6 files changed, 62 insertions, 29 deletions
diff --git a/core/multimedia/opieplayer/modplug/sndfile.cpp b/core/multimedia/opieplayer/modplug/sndfile.cpp index 1d0d610..799555c 100644 --- a/core/multimedia/opieplayer/modplug/sndfile.cpp +++ b/core/multimedia/opieplayer/modplug/sndfile.cpp | |||
@@ -1,1875 +1,1878 @@ | |||
1 | /* | 1 | /* |
2 | * This program is free software; you can redistribute it and modify it | 2 | * This program is free software; you can redistribute it and modify it |
3 | * under the terms of the GNU General Public License as published by the | 3 | * under the terms of the GNU General Public License as published by the |
4 | * Free Software Foundation; either version 2 of the license or (at your | 4 | * Free Software Foundation; either version 2 of the license or (at your |
5 | * option) any later version. | 5 | * option) any later version. |
6 | * | 6 | * |
7 | * Authors: Olivier Lapicque <olivierl@jps.net>, | 7 | * Authors: Olivier Lapicque <olivierl@jps.net>, |
8 | * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC) | 8 | * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC) |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <math.h> //for GCCFIX | 11 | #include <math.h> //for GCCFIX |
12 | #include "stdafx.h" | 12 | #include "stdafx.h" |
13 | #include "sndfile.h" | 13 | #include "sndfile.h" |
14 | 14 | ||
15 | #define MMCMP_SUPPORT | 15 | #define MMCMP_SUPPORT |
16 | 16 | ||
17 | #ifdef MMCMP_SUPPORT | 17 | #ifdef MMCMP_SUPPORT |
18 | extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); | 18 | extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | // External decompressors | 21 | // External decompressors |
22 | extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter); | 22 | extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter); |
23 | extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); | 23 | extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); |
24 | extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen); | 24 | extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen); |
25 | extern DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); | 25 | extern DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); |
26 | extern void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215); | 26 | extern void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215); |
27 | extern void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215); | 27 | extern void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215); |
28 | 28 | ||
29 | 29 | ||
30 | #define MAX_PACK_TABLES 3 | 30 | #define MAX_PACK_TABLES 3 |
31 | 31 | ||
32 | 32 | ||
33 | // Compression table | 33 | // Compression table |
34 | static const signed char UnpackTable[MAX_PACK_TABLES][16] = | 34 | static const signed char UnpackTable[MAX_PACK_TABLES][16] = |
35 | //-------------------------------------------- | 35 | //-------------------------------------------- |
36 | { | 36 | { |
37 | // CPU-generated dynamic table | 37 | // CPU-generated dynamic table |
38 | {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, | 38 | {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, |
39 | // u-Law table | 39 | // u-Law table |
40 | {0, 1, 2, 4, 8, 16, 32, 64, | 40 | {0, 1, 2, 4, 8, 16, 32, 64, |
41 | -1, -2, -4, -8, -16, -32, -48, -64}, | 41 | -1, -2, -4, -8, -16, -32, -48, -64}, |
42 | // Linear table | 42 | // Linear table |
43 | {0, 1, 2, 3, 5, 7, 12, 19, | 43 | {0, 1, 2, 3, 5, 7, 12, 19, |
44 | -1, -2, -3, -5, -7, -12, -19, -31} | 44 | -1, -2, -3, -5, -7, -12, -19, -31} |
45 | }; | 45 | }; |
46 | 46 | ||
47 | 47 | ||
48 | ////////////////////////////////////////////////////////// | 48 | ////////////////////////////////////////////////////////// |
49 | // CSoundFile | 49 | // CSoundFile |
50 | 50 | ||
51 | CSoundFile::CSoundFile() | 51 | CSoundFile::CSoundFile() |
52 | //---------------------- | 52 | //---------------------- |
53 | { | 53 | { |
54 | m_nType = MOD_TYPE_NONE; | 54 | m_nType = MOD_TYPE_NONE; |
55 | m_dwSongFlags = 0; | 55 | m_dwSongFlags = 0; |
56 | m_nChannels = 0; | 56 | m_nChannels = 0; |
57 | m_nMixChannels = 0; | 57 | m_nMixChannels = 0; |
58 | m_nSamples = 0; | 58 | m_nSamples = 0; |
59 | m_nInstruments = 0; | 59 | m_nInstruments = 0; |
60 | m_nPatternNames = 0; | 60 | m_nPatternNames = 0; |
61 | m_lpszPatternNames = NULL; | 61 | m_lpszPatternNames = NULL; |
62 | m_lpszSongComments = NULL; | 62 | m_lpszSongComments = NULL; |
63 | m_nFreqFactor = m_nTempoFactor = 128; | 63 | m_nFreqFactor = m_nTempoFactor = 128; |
64 | m_nMasterVolume = 128; | 64 | m_nMasterVolume = 128; |
65 | m_nMinPeriod = 0x20; | 65 | m_nMinPeriod = 0x20; |
66 | m_nMaxPeriod = 0x7FFF; | 66 | m_nMaxPeriod = 0x7FFF; |
67 | m_nRepeatCount = 0; | 67 | m_nRepeatCount = 0; |
68 | memset(Chn, 0, sizeof(Chn)); | 68 | memset(Chn, 0, sizeof(Chn)); |
69 | memset(ChnMix, 0, sizeof(ChnMix)); | 69 | memset(ChnMix, 0, sizeof(ChnMix)); |
70 | memset(Ins, 0, sizeof(Ins)); | 70 | memset(Ins, 0, sizeof(Ins)); |
71 | memset(ChnSettings, 0, sizeof(ChnSettings)); | 71 | memset(ChnSettings, 0, sizeof(ChnSettings)); |
72 | memset(Headers, 0, sizeof(Headers)); | 72 | memset(Headers, 0, sizeof(Headers)); |
73 | memset(Order, 0xFF, sizeof(Order)); | 73 | memset(Order, 0xFF, sizeof(Order)); |
74 | memset(Patterns, 0, sizeof(Patterns)); | 74 | memset(Patterns, 0, sizeof(Patterns)); |
75 | memset(m_szNames, 0, sizeof(m_szNames)); | 75 | memset(m_szNames, 0, sizeof(m_szNames)); |
76 | memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); | 76 | memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); |
77 | } | 77 | } |
78 | 78 | ||
79 | 79 | ||
80 | CSoundFile::~CSoundFile() | 80 | CSoundFile::~CSoundFile() |
81 | //----------------------- | 81 | //----------------------- |
82 | { | 82 | { |
83 | Destroy(); | 83 | Destroy(); |
84 | } | 84 | } |
85 | 85 | ||
86 | 86 | ||
87 | BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength) | 87 | BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength) |
88 | //---------------------------------------------------------- | 88 | //---------------------------------------------------------- |
89 | { | 89 | { |
90 | int i; | 90 | int i; |
91 | 91 | ||
92 | m_nType = MOD_TYPE_NONE; | 92 | m_nType = MOD_TYPE_NONE; |
93 | m_dwSongFlags = 0; | 93 | m_dwSongFlags = 0; |
94 | m_nChannels = 0; | 94 | m_nChannels = 0; |
95 | m_nMixChannels = 0; | 95 | m_nMixChannels = 0; |
96 | m_nSamples = 0; | 96 | m_nSamples = 0; |
97 | m_nInstruments = 0; | 97 | m_nInstruments = 0; |
98 | m_nFreqFactor = m_nTempoFactor = 128; | 98 | m_nFreqFactor = m_nTempoFactor = 128; |
99 | m_nMasterVolume = 128; | 99 | m_nMasterVolume = 128; |
100 | m_nDefaultGlobalVolume = 256; | 100 | m_nDefaultGlobalVolume = 256; |
101 | m_nGlobalVolume = 256; | 101 | m_nGlobalVolume = 256; |
102 | m_nOldGlbVolSlide = 0; | 102 | m_nOldGlbVolSlide = 0; |
103 | m_nDefaultSpeed = 6; | 103 | m_nDefaultSpeed = 6; |
104 | m_nDefaultTempo = 125; | 104 | m_nDefaultTempo = 125; |
105 | m_nPatternDelay = 0; | 105 | m_nPatternDelay = 0; |
106 | m_nFrameDelay = 0; | 106 | m_nFrameDelay = 0; |
107 | m_nNextRow = 0; | 107 | m_nNextRow = 0; |
108 | m_nRow = 0; | 108 | m_nRow = 0; |
109 | m_nPattern = 0; | 109 | m_nPattern = 0; |
110 | m_nCurrentPattern = 0; | 110 | m_nCurrentPattern = 0; |
111 | m_nNextPattern = 0; | 111 | m_nNextPattern = 0; |
112 | m_nRestartPos = 0; | 112 | m_nRestartPos = 0; |
113 | m_nMinPeriod = 16; | 113 | m_nMinPeriod = 16; |
114 | m_nMaxPeriod = 32767; | 114 | m_nMaxPeriod = 32767; |
115 | m_nSongPreAmp = 0x30; | 115 | m_nSongPreAmp = 0x30; |
116 | m_nPatternNames = 0; | 116 | m_nPatternNames = 0; |
117 | m_nMaxOrderPosition = 0; | 117 | m_nMaxOrderPosition = 0; |
118 | m_lpszPatternNames = NULL; | 118 | m_lpszPatternNames = NULL; |
119 | m_lpszSongComments = NULL; | 119 | m_lpszSongComments = NULL; |
120 | memset(Ins, 0, sizeof(Ins)); | 120 | memset(Ins, 0, sizeof(Ins)); |
121 | memset(ChnMix, 0, sizeof(ChnMix)); | 121 | memset(ChnMix, 0, sizeof(ChnMix)); |
122 | memset(Chn, 0, sizeof(Chn)); | 122 | memset(Chn, 0, sizeof(Chn)); |
123 | memset(Headers, 0, sizeof(Headers)); | 123 | memset(Headers, 0, sizeof(Headers)); |
124 | memset(Order, 0xFF, sizeof(Order)); | 124 | memset(Order, 0xFF, sizeof(Order)); |
125 | memset(Patterns, 0, sizeof(Patterns)); | 125 | memset(Patterns, 0, sizeof(Patterns)); |
126 | memset(m_szNames, 0, sizeof(m_szNames)); | 126 | memset(m_szNames, 0, sizeof(m_szNames)); |
127 | memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); | 127 | memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); |
128 | ResetMidiCfg(); | 128 | ResetMidiCfg(); |
129 | for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64; | 129 | for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64; |
130 | for (UINT nch=0; nch<MAX_BASECHANNELS; nch++) | 130 | for (UINT nch=0; nch<MAX_BASECHANNELS; nch++) |
131 | { | 131 | { |
132 | ChnSettings[nch].nPan = 128; | 132 | ChnSettings[nch].nPan = 128; |
133 | ChnSettings[nch].nVolume = 64; | 133 | ChnSettings[nch].nVolume = 64; |
134 | ChnSettings[nch].dwFlags = 0; | 134 | ChnSettings[nch].dwFlags = 0; |
135 | ChnSettings[nch].szName[0] = 0; | 135 | ChnSettings[nch].szName[0] = 0; |
136 | } | 136 | } |
137 | if (lpStream) | 137 | if (lpStream) |
138 | { | 138 | { |
139 | #ifdef MMCMP_SUPPORT | 139 | #ifdef MMCMP_SUPPORT |
140 | BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength); | 140 | BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength); |
141 | #endif | 141 | #endif |
142 | if ((!ReadXM(lpStream, dwMemLength)) | 142 | if ((!ReadXM(lpStream, dwMemLength)) |
143 | && (!ReadIT(lpStream, dwMemLength)) | 143 | && (!ReadIT(lpStream, dwMemLength)) |
144 | && (!ReadS3M(lpStream, dwMemLength)) | 144 | && (!ReadS3M(lpStream, dwMemLength)) |
145 | // && (!ReadWav(lpStream, dwMemLength)) | 145 | // && (!ReadWav(lpStream, dwMemLength)) |
146 | #ifndef MODPLUG_BASIC_SUPPORT | 146 | #ifndef MODPLUG_BASIC_SUPPORT |
147 | && (!ReadSTM(lpStream, dwMemLength)) | 147 | && (!ReadSTM(lpStream, dwMemLength)) |
148 | && (!ReadMed(lpStream, dwMemLength)) | 148 | && (!ReadMed(lpStream, dwMemLength)) |
149 | && (!ReadMTM(lpStream, dwMemLength)) | 149 | && (!ReadMTM(lpStream, dwMemLength)) |
150 | && (!ReadMDL(lpStream, dwMemLength)) | 150 | && (!ReadMDL(lpStream, dwMemLength)) |
151 | && (!ReadDBM(lpStream, dwMemLength)) | 151 | && (!ReadDBM(lpStream, dwMemLength)) |
152 | && (!Read669(lpStream, dwMemLength)) | 152 | && (!Read669(lpStream, dwMemLength)) |
153 | && (!ReadFAR(lpStream, dwMemLength)) | 153 | && (!ReadFAR(lpStream, dwMemLength)) |
154 | && (!ReadAMS(lpStream, dwMemLength)) | 154 | && (!ReadAMS(lpStream, dwMemLength)) |
155 | && (!ReadOKT(lpStream, dwMemLength)) | 155 | && (!ReadOKT(lpStream, dwMemLength)) |
156 | && (!ReadPTM(lpStream, dwMemLength)) | 156 | && (!ReadPTM(lpStream, dwMemLength)) |
157 | && (!ReadUlt(lpStream, dwMemLength)) | 157 | && (!ReadUlt(lpStream, dwMemLength)) |
158 | && (!ReadDMF(lpStream, dwMemLength)) | 158 | && (!ReadDMF(lpStream, dwMemLength)) |
159 | && (!ReadDSM(lpStream, dwMemLength)) | 159 | && (!ReadDSM(lpStream, dwMemLength)) |
160 | && (!ReadUMX(lpStream, dwMemLength)) | 160 | && (!ReadUMX(lpStream, dwMemLength)) |
161 | && (!ReadAMF(lpStream, dwMemLength)) | 161 | && (!ReadAMF(lpStream, dwMemLength)) |
162 | && (!ReadPSM(lpStream, dwMemLength)) | 162 | && (!ReadPSM(lpStream, dwMemLength)) |
163 | && (!ReadMT2(lpStream, dwMemLength)) | 163 | && (!ReadMT2(lpStream, dwMemLength)) |
164 | #endif // MODPLUG_BASIC_SUPPORT | 164 | #endif // MODPLUG_BASIC_SUPPORT |
165 | && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; | 165 | && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; |
166 | #ifdef MMCMP_SUPPORT | 166 | #ifdef MMCMP_SUPPORT |
167 | if (bMMCmp) | 167 | if (bMMCmp) |
168 | { | 168 | { |
169 | GlobalFreePtr(lpStream); | 169 | GlobalFreePtr(lpStream); |
170 | lpStream = NULL; | 170 | lpStream = NULL; |
171 | } | 171 | } |
172 | #endif | 172 | #endif |
173 | } | 173 | } |
174 | // Adjust song names | 174 | // Adjust song names |
175 | for (i=0; i<MAX_SAMPLES; i++) | 175 | for (i=0; i<MAX_SAMPLES; i++) |
176 | { | 176 | { |
177 | LPSTR p = m_szNames[i]; | 177 | LPSTR p = m_szNames[i]; |
178 | int j = 31; | 178 | int j = 31; |
179 | p[j] = 0; | 179 | p[j] = 0; |
180 | while ((j>=0) && (p[j]<=' ')) p[j--] = 0; | 180 | while ((j>=0) && (p[j]<=' ')) p[j--] = 0; |
181 | while (j>=0) | 181 | while (j>=0) |
182 | { | 182 | { |
183 | if (((BYTE)p[j]) < ' ') p[j] = ' '; | 183 | if (((BYTE)p[j]) < ' ') p[j] = ' '; |
184 | j--; | 184 | j--; |
185 | } | 185 | } |
186 | } | 186 | } |
187 | // Adjust channels | 187 | // Adjust channels |
188 | for (i=0; i<MAX_BASECHANNELS; i++) | 188 | for (i=0; i<MAX_BASECHANNELS; i++) |
189 | { | 189 | { |
190 | if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64; | 190 | if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64; |
191 | if (ChnSettings[i].nPan > 256) ChnSettings[i].nPan = 128; | 191 | if (ChnSettings[i].nPan > 256) ChnSettings[i].nPan = 128; |
192 | Chn[i].nPan = ChnSettings[i].nPan; | 192 | Chn[i].nPan = ChnSettings[i].nPan; |
193 | Chn[i].nGlobalVol = ChnSettings[i].nVolume; | 193 | Chn[i].nGlobalVol = ChnSettings[i].nVolume; |
194 | Chn[i].dwFlags = ChnSettings[i].dwFlags; | 194 | Chn[i].dwFlags = ChnSettings[i].dwFlags; |
195 | Chn[i].nVolume = 256; | 195 | Chn[i].nVolume = 256; |
196 | Chn[i].nCutOff = 0x7F; | 196 | Chn[i].nCutOff = 0x7F; |
197 | } | 197 | } |
198 | // Checking instruments | 198 | // Checking instruments |
199 | MODINSTRUMENT *pins = Ins; | 199 | MODINSTRUMENT *pins = Ins; |
200 | 200 | ||
201 | for (i=0; i<MAX_INSTRUMENTS; i++, pins++) | 201 | for (i=0; i<MAX_INSTRUMENTS; i++, pins++) |
202 | { | 202 | { |
203 | if (pins->pSample) | 203 | if (pins->pSample) |
204 | { | 204 | { |
205 | if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength; | 205 | if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength; |
206 | if (pins->nLoopStart + 3 >= pins->nLoopEnd) | 206 | if (pins->nLoopStart + 3 >= pins->nLoopEnd) |
207 | { | 207 | { |
208 | pins->nLoopStart = 0; | 208 | pins->nLoopStart = 0; |
209 | pins->nLoopEnd = 0; | 209 | pins->nLoopEnd = 0; |
210 | } | 210 | } |
211 | if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength; | 211 | if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength; |
212 | if (pins->nSustainStart + 3 >= pins->nSustainEnd) | 212 | if (pins->nSustainStart + 3 >= pins->nSustainEnd) |
213 | { | 213 | { |
214 | pins->nSustainStart = 0; | 214 | pins->nSustainStart = 0; |
215 | pins->nSustainEnd = 0; | 215 | pins->nSustainEnd = 0; |
216 | } | 216 | } |
217 | } else | 217 | } else |
218 | { | 218 | { |
219 | pins->nLength = 0; | 219 | pins->nLength = 0; |
220 | pins->nLoopStart = 0; | 220 | pins->nLoopStart = 0; |
221 | pins->nLoopEnd = 0; | 221 | pins->nLoopEnd = 0; |
222 | pins->nSustainStart = 0; | 222 | pins->nSustainStart = 0; |
223 | pins->nSustainEnd = 0; | 223 | pins->nSustainEnd = 0; |
224 | } | 224 | } |
225 | if (!pins->nLoopEnd) pins->uFlags &= ~CHN_LOOP; | 225 | if (!pins->nLoopEnd) pins->uFlags &= ~CHN_LOOP; |
226 | if (!pins->nSustainEnd) pins->uFlags &= ~CHN_SUSTAINLOOP; | 226 | if (!pins->nSustainEnd) pins->uFlags &= ~CHN_SUSTAINLOOP; |
227 | if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; | 227 | if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; |
228 | } | 228 | } |
229 | // Check invalid instruments | 229 | // Check invalid instruments |
230 | while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--; | 230 | while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--; |
231 | // Set default values | 231 | // Set default values |
232 | if (m_nSongPreAmp < 0x20) m_nSongPreAmp = 0x20; | 232 | if (m_nSongPreAmp < 0x20) m_nSongPreAmp = 0x20; |
233 | if (m_nDefaultTempo < 32) m_nDefaultTempo = 125; | 233 | if (m_nDefaultTempo < 32) m_nDefaultTempo = 125; |
234 | if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; | 234 | if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; |
235 | m_nMusicSpeed = m_nDefaultSpeed; | 235 | m_nMusicSpeed = m_nDefaultSpeed; |
236 | m_nMusicTempo = m_nDefaultTempo; | 236 | m_nMusicTempo = m_nDefaultTempo; |
237 | m_nGlobalVolume = m_nDefaultGlobalVolume; | 237 | m_nGlobalVolume = m_nDefaultGlobalVolume; |
238 | m_nNextPattern = 0; | 238 | m_nNextPattern = 0; |
239 | m_nCurrentPattern = 0; | 239 | m_nCurrentPattern = 0; |
240 | m_nPattern = 0; | 240 | m_nPattern = 0; |
241 | m_nBufferCount = 0; | 241 | m_nBufferCount = 0; |
242 | m_nTickCount = m_nMusicSpeed; | 242 | m_nTickCount = m_nMusicSpeed; |
243 | m_nNextRow = 0; | 243 | m_nNextRow = 0; |
244 | m_nRow = 0; | 244 | m_nRow = 0; |
245 | if ((m_nRestartPos >= MAX_ORDERS) || (Order[m_nRestartPos] >= MAX_PATTERNS)) m_nRestartPos = 0; | 245 | if ((m_nRestartPos >= MAX_ORDERS) || (Order[m_nRestartPos] >= MAX_PATTERNS)) m_nRestartPos = 0; |
246 | // Load plugins | 246 | // Load plugins |
247 | if (gpMixPluginCreateProc) | 247 | if (gpMixPluginCreateProc) |
248 | { | 248 | { |
249 | for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) | 249 | for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) |
250 | { | 250 | { |
251 | if ((m_MixPlugins[iPlug].Info.dwPluginId1) | 251 | if ((m_MixPlugins[iPlug].Info.dwPluginId1) |
252 | || (m_MixPlugins[iPlug].Info.dwPluginId2)) | 252 | || (m_MixPlugins[iPlug].Info.dwPluginId2)) |
253 | { | 253 | { |
254 | gpMixPluginCreateProc(&m_MixPlugins[iPlug]); | 254 | gpMixPluginCreateProc(&m_MixPlugins[iPlug]); |
255 | if (m_MixPlugins[iPlug].pMixPlugin) | 255 | if (m_MixPlugins[iPlug].pMixPlugin) |
256 | { | 256 | { |
257 | m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters(); | 257 | m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters(); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | } | 260 | } |
261 | } | 261 | } |
262 | if (m_nType) | 262 | if (m_nType) |
263 | { | 263 | { |
264 | UINT maxpreamp = 0x10+(m_nChannels*8); | 264 | UINT maxpreamp = 0x10+(m_nChannels*8); |
265 | if (maxpreamp > 100) maxpreamp = 100; | 265 | if (maxpreamp > 100) maxpreamp = 100; |
266 | if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp; | 266 | if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp; |
267 | return TRUE; | 267 | return TRUE; |
268 | } | 268 | } |
269 | return FALSE; | 269 | return FALSE; |
270 | } | 270 | } |
271 | 271 | ||
272 | 272 | ||
273 | BOOL CSoundFile::Destroy() | 273 | BOOL CSoundFile::Destroy() |
274 | 274 | ||
275 | //------------------------ | 275 | //------------------------ |
276 | { | 276 | { |
277 | int i; | 277 | int i; |
278 | for (i=0; i<MAX_PATTERNS; i++) if (Patterns[i]) | 278 | for (i=0; i<MAX_PATTERNS; i++) if (Patterns[i]) |
279 | { | 279 | { |
280 | FreePattern(Patterns[i]); | 280 | FreePattern(Patterns[i]); |
281 | Patterns[i] = NULL; | 281 | Patterns[i] = NULL; |
282 | } | 282 | } |
283 | m_nPatternNames = 0; | 283 | m_nPatternNames = 0; |
284 | if (m_lpszPatternNames) | 284 | if (m_lpszPatternNames) |
285 | { | 285 | { |
286 | delete m_lpszPatternNames; | 286 | delete m_lpszPatternNames; |
287 | m_lpszPatternNames = NULL; | 287 | m_lpszPatternNames = NULL; |
288 | } | 288 | } |
289 | if (m_lpszSongComments) | 289 | if (m_lpszSongComments) |
290 | { | 290 | { |
291 | delete m_lpszSongComments; | 291 | delete m_lpszSongComments; |
292 | m_lpszSongComments = NULL; | 292 | m_lpszSongComments = NULL; |
293 | } | 293 | } |
294 | for (i=1; i<MAX_SAMPLES; i++) | 294 | for (i=1; i<MAX_SAMPLES; i++) |
295 | { | 295 | { |
296 | MODINSTRUMENT *pins = &Ins[i]; | 296 | MODINSTRUMENT *pins = &Ins[i]; |
297 | if (pins->pSample) | 297 | if (pins->pSample) |
298 | { | 298 | { |
299 | FreeSample(pins->pSample); | 299 | FreeSample(pins->pSample); |
300 | pins->pSample = NULL; | 300 | pins->pSample = NULL; |
301 | } | 301 | } |
302 | } | 302 | } |
303 | for (i=0; i<MAX_INSTRUMENTS; i++) | 303 | for (i=0; i<MAX_INSTRUMENTS; i++) |
304 | { | 304 | { |
305 | if (Headers[i]) | 305 | if (Headers[i]) |
306 | { | 306 | { |
307 | delete Headers[i]; | 307 | delete Headers[i]; |
308 | Headers[i] = NULL; | 308 | Headers[i] = NULL; |
309 | } | 309 | } |
310 | } | 310 | } |
311 | for (i=0; i<MAX_MIXPLUGINS; i++) | 311 | for (i=0; i<MAX_MIXPLUGINS; i++) |
312 | { | 312 | { |
313 | if ((m_MixPlugins[i].nPluginDataSize) && (m_MixPlugins[i].pPluginData)) | 313 | if ((m_MixPlugins[i].nPluginDataSize) && (m_MixPlugins[i].pPluginData)) |
314 | { | 314 | { |
315 | m_MixPlugins[i].nPluginDataSize = 0; | 315 | m_MixPlugins[i].nPluginDataSize = 0; |
316 | delete [] (signed char*)m_MixPlugins[i].pPluginData; | 316 | delete [] (signed char*)m_MixPlugins[i].pPluginData; |
317 | m_MixPlugins[i].pPluginData = NULL; | 317 | m_MixPlugins[i].pPluginData = NULL; |
318 | } | 318 | } |
319 | m_MixPlugins[i].pMixState = NULL; | 319 | m_MixPlugins[i].pMixState = NULL; |
320 | if (m_MixPlugins[i].pMixPlugin) | 320 | if (m_MixPlugins[i].pMixPlugin) |
321 | { | 321 | { |
322 | m_MixPlugins[i].pMixPlugin->Release(); | 322 | m_MixPlugins[i].pMixPlugin->Release(); |
323 | m_MixPlugins[i].pMixPlugin = NULL; | 323 | m_MixPlugins[i].pMixPlugin = NULL; |
324 | } | 324 | } |
325 | } | 325 | } |
326 | m_nType = MOD_TYPE_NONE; | 326 | m_nType = MOD_TYPE_NONE; |
327 | m_nChannels = m_nSamples = m_nInstruments = 0; | 327 | m_nChannels = m_nSamples = m_nInstruments = 0; |
328 | return TRUE; | 328 | return TRUE; |
329 | } | 329 | } |
330 | 330 | ||
331 | 331 | ||
332 | ////////////////////////////////////////////////////////////////////////// | 332 | ////////////////////////////////////////////////////////////////////////// |
333 | // Memory Allocation | 333 | // Memory Allocation |
334 | 334 | ||
335 | MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) | 335 | MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) |
336 | //------------------------------------------------------------ | 336 | //------------------------------------------------------------ |
337 | { | 337 | { |
338 | MODCOMMAND *p = new MODCOMMAND[rows*nchns]; | 338 | MODCOMMAND *p = new MODCOMMAND[rows*nchns]; |
339 | if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND)); | 339 | if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND)); |
340 | return p; | 340 | return p; |
341 | } | 341 | } |
342 | 342 | ||
343 | 343 | ||
344 | void CSoundFile::FreePattern(LPVOID pat) | 344 | void CSoundFile::FreePattern(LPVOID pat) |
345 | //-------------------------------------- | 345 | //-------------------------------------- |
346 | { | 346 | { |
347 | if (pat) delete [] (signed char*)pat; | 347 | if (pat) delete [] (signed char*)pat; |
348 | } | 348 | } |
349 | 349 | ||
350 | 350 | ||
351 | signed char* CSoundFile::AllocateSample(UINT nbytes) | 351 | signed char* CSoundFile::AllocateSample(UINT nbytes) |
352 | //------------------------------------------- | 352 | //------------------------------------------- |
353 | { | 353 | { |
354 | signed char * p = (signed char *)GlobalAllocPtr(GHND, (nbytes+39) & ~7); | 354 | signed char * p = (signed char *)GlobalAllocPtr(GHND, (nbytes+39) & ~7); |
355 | if (p) p += 16; | 355 | if (p) p += 16; |
356 | return p; | 356 | return p; |
357 | } | 357 | } |
358 | 358 | ||
359 | 359 | ||
360 | void CSoundFile::FreeSample(LPVOID p) | 360 | void CSoundFile::FreeSample(LPVOID p) |
361 | //----------------------------------- | 361 | //----------------------------------- |
362 | { | 362 | { |
363 | if (p) | 363 | if (p) |
364 | { | 364 | { |
365 | GlobalFreePtr(((LPSTR)p)-16); | 365 | GlobalFreePtr(((LPSTR)p)-16); |
366 | } | 366 | } |
367 | } | 367 | } |
368 | 368 | ||
369 | 369 | ||
370 | ////////////////////////////////////////////////////////////////////////// | 370 | ////////////////////////////////////////////////////////////////////////// |
371 | // Misc functions | 371 | // Misc functions |
372 | 372 | ||
373 | void CSoundFile::ResetMidiCfg() | 373 | void CSoundFile::ResetMidiCfg() |
374 | //----------------------------- | 374 | //----------------------------- |
375 | { | 375 | { |
376 | memset(&m_MidiCfg, 0, sizeof(m_MidiCfg)); | 376 | memset(&m_MidiCfg, 0, sizeof(m_MidiCfg)); |
377 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_START*32], "FF"); | 377 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_START*32], "FF"); |
378 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_STOP*32], "FC"); | 378 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_STOP*32], "FC"); |
379 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEON*32], "9c n v"); | 379 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEON*32], "9c n v"); |
380 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEOFF*32], "9c n 0"); | 380 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEOFF*32], "9c n 0"); |
381 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p"); | 381 | lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p"); |
382 | lstrcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z"); | 382 | lstrcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z"); |
383 | for (int iz=0; iz<16; iz++) wsprintf(&m_MidiCfg.szMidiZXXExt[iz*32], "F0F001%02X", iz*8); | 383 | for (int iz=0; iz<16; iz++) wsprintf(&m_MidiCfg.szMidiZXXExt[iz*32], "F0F001%02X", iz*8); |
384 | } | 384 | } |
385 | 385 | ||
386 | 386 | ||
387 | UINT CSoundFile::GetNumChannels() const | 387 | UINT CSoundFile::GetNumChannels() const |
388 | //------------------------------------- | 388 | //------------------------------------- |
389 | { | 389 | { |
390 | UINT n = 0; | 390 | UINT n = 0; |
391 | for (UINT i=0; i<m_nChannels; i++) if (ChnSettings[i].nVolume) n++; | 391 | for (UINT i=0; i<m_nChannels; i++) if (ChnSettings[i].nVolume) n++; |
392 | return n; | 392 | return n; |
393 | } | 393 | } |
394 | 394 | ||
395 | 395 | ||
396 | UINT CSoundFile::GetSongComments(LPSTR s, UINT len, UINT linesize) | 396 | UINT CSoundFile::GetSongComments(LPSTR s, UINT len, UINT linesize) |
397 | //---------------------------------------------------------------- | 397 | //---------------------------------------------------------------- |
398 | { | 398 | { |
399 | LPCSTR p = m_lpszSongComments; | 399 | LPCSTR p = m_lpszSongComments; |
400 | if (!p) return 0; | 400 | if (!p) return 0; |
401 | UINT i = 2, ln=0; | 401 | UINT i = 2, ln=0; |
402 | if ((len) && (s)) s[0] = '\x0D'; | 402 | if ((len) && (s)) s[0] = '\x0D'; |
403 | if ((len > 1) && (s)) s[1] = '\x0A'; | 403 | if ((len > 1) && (s)) s[1] = '\x0A'; |
404 | while ((*p)&& (i+2 < len)) | 404 | while ((*p)&& (i+2 < len)) |
405 | { | 405 | { |
406 | BYTE c = (BYTE)*p++; | 406 | BYTE c = (BYTE)*p++; |
407 | if ((c == 0x0D) || ((c == ' ') && (ln >= linesize))) | 407 | if ((c == 0x0D) || ((c == ' ') && (ln >= linesize))) |
408 | { if (s) { s[i++] = '\x0D'; s[i++] = '\x0A'; } else i+= 2; ln=0; } | 408 | { if (s) { s[i++] = '\x0D'; s[i++] = '\x0A'; } else i+= 2; ln=0; } |
409 | else | 409 | else |
410 | if (c >= 0x20) { if (s) s[i++] = c; else i++; ln++; } | 410 | if (c >= 0x20) { if (s) s[i++] = c; else i++; ln++; } |
411 | } | 411 | } |
412 | if (s) s[i] = 0; | 412 | if (s) s[i] = 0; |
413 | return i; | 413 | return i; |
414 | } | 414 | } |
415 | 415 | ||
416 | 416 | ||
417 | UINT CSoundFile::GetRawSongComments(LPSTR s, UINT len, UINT linesize) | 417 | UINT CSoundFile::GetRawSongComments(LPSTR s, UINT len, UINT linesize) |
418 | //------------------------------------------------------------------- | 418 | //------------------------------------------------------------------- |
419 | { | 419 | { |
420 | LPCSTR p = m_lpszSongComments; | 420 | LPCSTR p = m_lpszSongComments; |
421 | if (!p) return 0; | 421 | if (!p) return 0; |
422 | UINT i = 0, ln=0; | 422 | UINT i = 0, ln=0; |
423 | while ((*p)&& (i < len-1)) | 423 | while ((*p)&& (i < len-1)) |
424 | { | 424 | { |
425 | BYTE c = (BYTE)*p++; | 425 | BYTE c = (BYTE)*p++; |
426 | if ((c == 0x0D)|| (c == 0x0A)) | 426 | if ((c == 0x0D)|| (c == 0x0A)) |
427 | { | 427 | { |
428 | if (ln) | 428 | if (ln) |
429 | { | 429 | { |
430 | while (ln < linesize) { if (s) s[i] = ' '; i++; ln++; } | 430 | while (ln < linesize) { if (s) s[i] = ' '; i++; ln++; } |
431 | ln = 0; | 431 | ln = 0; |
432 | } | 432 | } |
433 | } else | 433 | } else |
434 | if ((c == ' ') && (!ln)) | 434 | if ((c == ' ') && (!ln)) |
435 | { | 435 | { |
436 | UINT k=0; | 436 | UINT k=0; |
437 | while ((p[k]) && (p[k] >= ' '))k++; | 437 | while ((p[k]) && (p[k] >= ' '))k++; |
438 | if (k <= linesize) | 438 | if (k <= linesize) |
439 | { | 439 | { |
440 | if (s) s[i] = ' '; | 440 | if (s) s[i] = ' '; |
441 | i++; | 441 | i++; |
442 | ln++; | 442 | ln++; |
443 | } | 443 | } |
444 | } else | 444 | } else |
445 | { | 445 | { |
446 | if (s) s[i] = c; | 446 | if (s) s[i] = c; |
447 | i++; | 447 | i++; |
448 | ln++; | 448 | ln++; |
449 | if (ln == linesize) ln = 0; | 449 | if (ln == linesize) ln = 0; |
450 | } | 450 | } |
451 | } | 451 | } |
452 | if (ln) | 452 | if (ln) |
453 | { | 453 | { |
454 | while ((ln < linesize) && (i < len)) | 454 | while ((ln < linesize) && (i < len)) |
455 | { | 455 | { |
456 | if (s) s[i] = ' '; | 456 | if (s) s[i] = ' '; |
457 | i++; | 457 | i++; |
458 | ln++; | 458 | ln++; |
459 | } | 459 | } |
460 | } | 460 | } |
461 | if (s) s[i] = 0; | 461 | if (s) s[i] = 0; |
462 | return i; | 462 | return i; |
463 | } | 463 | } |
464 | 464 | ||
465 | 465 | ||
466 | BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX) | 466 | BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX) |
467 | //---------------------------------------------------------------------------- | 467 | //---------------------------------------------------------------------------- |
468 | { | 468 | { |
469 | BOOL bReset = FALSE; | 469 | BOOL bReset = FALSE; |
470 | DWORD d = gdwSoundSetup & ~SNDMIX_ENABLEMMX; | 470 | DWORD d = gdwSoundSetup & ~SNDMIX_ENABLEMMX; |
471 | if (bMMX) d |= SNDMIX_ENABLEMMX; | 471 | if (bMMX) d |= SNDMIX_ENABLEMMX; |
472 | if ((gdwMixingFreq != nRate) || (gnBitsPerSample != nBits) || (gnChannels != nChannels) || (d != gdwSoundSetup)) bReset = TRUE; | 472 | if ((gdwMixingFreq != nRate) || (gnBitsPerSample != nBits) || (gnChannels != nChannels) || (d != gdwSoundSetup)) bReset = TRUE; |
473 | gnChannels = nChannels; | 473 | gnChannels = nChannels; |
474 | gdwSoundSetup = d; | 474 | gdwSoundSetup = d; |
475 | gdwMixingFreq = nRate; | 475 | gdwMixingFreq = nRate; |
476 | gnBitsPerSample = nBits; | 476 | gnBitsPerSample = nBits; |
477 | InitPlayer(bReset); | 477 | InitPlayer(bReset); |
478 | return TRUE; | 478 | return TRUE; |
479 | } | 479 | } |
480 | 480 | ||
481 | 481 | ||
482 | BOOL CSoundFile::SetResamplingMode(UINT nMode) | 482 | BOOL CSoundFile::SetResamplingMode(UINT nMode) |
483 | //-------------------------------------------- | 483 | //-------------------------------------------- |
484 | { | 484 | { |
485 | DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); | 485 | DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); |
486 | switch(nMode) | 486 | switch(nMode) |
487 | { | 487 | { |
488 | case SRCMODE_NEAREST:d |= SNDMIX_NORESAMPLING; break; | 488 | case SRCMODE_NEAREST:d |= SNDMIX_NORESAMPLING; break; |
489 | case SRCMODE_LINEAR:break; | 489 | case SRCMODE_LINEAR:break; |
490 | case SRCMODE_SPLINE:d |= SNDMIX_HQRESAMPLER; break; | 490 | case SRCMODE_SPLINE:d |= SNDMIX_HQRESAMPLER; break; |
491 | case SRCMODE_POLYPHASE:d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break; | 491 | case SRCMODE_POLYPHASE:d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break; |
492 | default: | 492 | default: |
493 | return FALSE; | 493 | return FALSE; |
494 | } | 494 | } |
495 | gdwSoundSetup = d; | 495 | gdwSoundSetup = d; |
496 | return TRUE; | 496 | return TRUE; |
497 | } | 497 | } |
498 | 498 | ||
499 | 499 | ||
500 | BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC) | 500 | BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC) |
501 | //---------------------------------------------------------- | 501 | //---------------------------------------------------------- |
502 | { | 502 | { |
503 | if (nVol < 1) nVol = 1; | 503 | if (nVol < 1) nVol = 1; |
504 | if (nVol > 0x200) nVol = 0x200;// x4 maximum | 504 | if (nVol > 0x200) nVol = 0x200;// x4 maximum |
505 | if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC)) | 505 | if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC)) |
506 | { | 506 | { |
507 | gnAGC = gnAGC * m_nMasterVolume / nVol; | 507 | gnAGC = gnAGC * m_nMasterVolume / nVol; |
508 | if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY; | 508 | if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY; |
509 | } | 509 | } |
510 | m_nMasterVolume = nVol; | 510 | m_nMasterVolume = nVol; |
511 | return TRUE; | 511 | return TRUE; |
512 | } | 512 | } |
513 | 513 | ||
514 | 514 | ||
515 | void CSoundFile::SetAGC(BOOL b) | 515 | void CSoundFile::SetAGC(BOOL b) |
516 | //----------------------------- | 516 | //----------------------------- |
517 | { | 517 | { |
518 | if (b) | 518 | if (b) |
519 | { | 519 | { |
520 | if (!(gdwSoundSetup & SNDMIX_AGC)) | 520 | if (!(gdwSoundSetup & SNDMIX_AGC)) |
521 | { | 521 | { |
522 | gdwSoundSetup |= SNDMIX_AGC; | 522 | gdwSoundSetup |= SNDMIX_AGC; |
523 | gnAGC = AGC_UNITY; | 523 | gnAGC = AGC_UNITY; |
524 | } | 524 | } |
525 | } else gdwSoundSetup &= ~SNDMIX_AGC; | 525 | } else gdwSoundSetup &= ~SNDMIX_AGC; |
526 | } | 526 | } |
527 | 527 | ||
528 | 528 | ||
529 | UINT CSoundFile::GetNumPatterns() const | 529 | UINT CSoundFile::GetNumPatterns() const |
530 | //------------------------------------- | 530 | //------------------------------------- |
531 | { | 531 | { |
532 | UINT i = 0; | 532 | UINT i = 0; |
533 | while ((i < MAX_ORDERS) && (Order[i] < 0xFF)) i++; | 533 | while ((i < MAX_ORDERS) && (Order[i] < 0xFF)) i++; |
534 | return i; | 534 | return i; |
535 | } | 535 | } |
536 | 536 | ||
537 | 537 | ||
538 | UINT CSoundFile::GetNumInstruments() const | 538 | UINT CSoundFile::GetNumInstruments() const |
539 | //---------------------------------------- | 539 | //---------------------------------------- |
540 | { | 540 | { |
541 | UINT n=0; | 541 | UINT n=0; |
542 | for (UINT i=0; i<MAX_INSTRUMENTS; i++) if (Ins[i].pSample) n++; | 542 | for (UINT i=0; i<MAX_INSTRUMENTS; i++) if (Ins[i].pSample) n++; |
543 | return n; | 543 | return n; |
544 | } | 544 | } |
545 | 545 | ||
546 | 546 | ||
547 | UINT CSoundFile::GetMaxPosition() const | 547 | UINT CSoundFile::GetMaxPosition() const |
548 | //------------------------------------- | 548 | //------------------------------------- |
549 | { | 549 | { |
550 | UINT max = 0; | 550 | UINT max = 0; |
551 | UINT i = 0; | 551 | UINT i = 0; |
552 | 552 | ||
553 | while ((i < MAX_ORDERS) && (Order[i] != 0xFF)) | 553 | while ((i < MAX_ORDERS) && (Order[i] != 0xFF)) |
554 | { | 554 | { |
555 | if (Order[i] < MAX_PATTERNS) max += PatternSize[Order[i]]; | 555 | if (Order[i] < MAX_PATTERNS) max += PatternSize[Order[i]]; |
556 | i++; | 556 | i++; |
557 | } | 557 | } |
558 | return max; | 558 | return max; |
559 | } | 559 | } |
560 | 560 | ||
561 | 561 | ||
562 | UINT CSoundFile::GetCurrentPos() const | 562 | UINT CSoundFile::GetCurrentPos() const |
563 | //------------------------------------ | 563 | //------------------------------------ |
564 | { | 564 | { |
565 | UINT pos = 0; | 565 | UINT pos = 0; |
566 | 566 | ||
567 | for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < MAX_PATTERNS) | 567 | for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < MAX_PATTERNS) |
568 | pos += PatternSize[Order[i]]; | 568 | pos += PatternSize[Order[i]]; |
569 | return pos + m_nRow; | 569 | return pos + m_nRow; |
570 | } | 570 | } |
571 | 571 | ||
572 | 572 | ||
573 | void CSoundFile::SetCurrentPos(UINT nPos) | 573 | void CSoundFile::SetCurrentPos(UINT nPos) |
574 | //--------------------------------------- | 574 | //--------------------------------------- |
575 | { | 575 | { |
576 | UINT i, nPattern; | 576 | UINT i, nPattern; |
577 | 577 | ||
578 | for (i=0; i<MAX_CHANNELS; i++) | 578 | for (i=0; i<MAX_CHANNELS; i++) |
579 | { | 579 | { |
580 | Chn[i].nNote = Chn[i].nNewNote = Chn[i].nNewIns = 0; | 580 | Chn[i].nNote = Chn[i].nNewNote = Chn[i].nNewIns = 0; |
581 | Chn[i].pInstrument = NULL; | 581 | Chn[i].pInstrument = NULL; |
582 | Chn[i].pHeader = NULL; | 582 | Chn[i].pHeader = NULL; |
583 | Chn[i].nPortamentoDest = 0; | 583 | Chn[i].nPortamentoDest = 0; |
584 | Chn[i].nCommand = 0; | 584 | Chn[i].nCommand = 0; |
585 | Chn[i].nPatternLoopCount = 0; | 585 | Chn[i].nPatternLoopCount = 0; |
586 | Chn[i].nPatternLoop = 0; | 586 | Chn[i].nPatternLoop = 0; |
587 | Chn[i].nFadeOutVol = 0; | 587 | Chn[i].nFadeOutVol = 0; |
588 | Chn[i].dwFlags |= CHN_KEYOFF|CHN_NOTEFADE; | 588 | Chn[i].dwFlags |= CHN_KEYOFF|CHN_NOTEFADE; |
589 | Chn[i].nTremorCount = 0; | 589 | Chn[i].nTremorCount = 0; |
590 | } | 590 | } |
591 | if (!nPos) | 591 | if (!nPos) |
592 | { | 592 | { |
593 | for (i=0; i<MAX_CHANNELS; i++) | 593 | for (i=0; i<MAX_CHANNELS; i++) |
594 | { | 594 | { |
595 | Chn[i].nPeriod = 0; | 595 | Chn[i].nPeriod = 0; |
596 | Chn[i].nPos = Chn[i].nLength = 0; | 596 | Chn[i].nPos = Chn[i].nLength = 0; |
597 | Chn[i].nLoopStart = 0; | 597 | Chn[i].nLoopStart = 0; |
598 | Chn[i].nLoopEnd = 0; | 598 | Chn[i].nLoopEnd = 0; |
599 | Chn[i].nROfs = Chn[i].nLOfs = 0; | 599 | Chn[i].nROfs = Chn[i].nLOfs = 0; |
600 | Chn[i].pSample = NULL; | 600 | Chn[i].pSample = NULL; |
601 | Chn[i].pInstrument = NULL; | 601 | Chn[i].pInstrument = NULL; |
602 | Chn[i].pHeader = NULL; | 602 | Chn[i].pHeader = NULL; |
603 | Chn[i].nCutOff = 0x7F; | 603 | Chn[i].nCutOff = 0x7F; |
604 | Chn[i].nResonance = 0; | 604 | Chn[i].nResonance = 0; |
605 | Chn[i].nLeftVol = Chn[i].nRightVol = 0; | 605 | Chn[i].nLeftVol = Chn[i].nRightVol = 0; |
606 | Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0; | 606 | Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0; |
607 | Chn[i].nLeftRamp = Chn[i].nRightRamp = 0; | 607 | Chn[i].nLeftRamp = Chn[i].nRightRamp = 0; |
608 | Chn[i].nVolume = 256; | 608 | Chn[i].nVolume = 256; |
609 | if (i < MAX_BASECHANNELS) | 609 | if (i < MAX_BASECHANNELS) |
610 | { | 610 | { |
611 | Chn[i].dwFlags = ChnSettings[i].dwFlags; | 611 | Chn[i].dwFlags = ChnSettings[i].dwFlags; |
612 | Chn[i].nPan = ChnSettings[i].nPan; | 612 | Chn[i].nPan = ChnSettings[i].nPan; |
613 | Chn[i].nGlobalVol = ChnSettings[i].nVolume; | 613 | Chn[i].nGlobalVol = ChnSettings[i].nVolume; |
614 | } else | 614 | } else |
615 | { | 615 | { |
616 | Chn[i].dwFlags = 0; | 616 | Chn[i].dwFlags = 0; |
617 | Chn[i].nPan = 128; | 617 | Chn[i].nPan = 128; |
618 | Chn[i].nGlobalVol = 64; | 618 | Chn[i].nGlobalVol = 64; |
619 | } | 619 | } |
620 | } | 620 | } |
621 | m_nGlobalVolume = m_nDefaultGlobalVolume; | 621 | m_nGlobalVolume = m_nDefaultGlobalVolume; |
622 | m_nMusicSpeed = m_nDefaultSpeed; | 622 | m_nMusicSpeed = m_nDefaultSpeed; |
623 | m_nMusicTempo = m_nDefaultTempo; | 623 | m_nMusicTempo = m_nDefaultTempo; |
624 | } | 624 | } |
625 | m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); | 625 | m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); |
626 | for (nPattern = 0; nPattern < MAX_ORDERS; nPattern++) | 626 | for (nPattern = 0; nPattern < MAX_ORDERS; nPattern++) |
627 | { | 627 | { |
628 | UINT ord = Order[nPattern]; | 628 | UINT ord = Order[nPattern]; |
629 | if (ord == 0xFE) continue; | 629 | if (ord == 0xFE) continue; |
630 | if (ord == 0xFF) break; | 630 | if (ord == 0xFF) break; |
631 | if (ord < MAX_PATTERNS) | 631 | if (ord < MAX_PATTERNS) |
632 | { | 632 | { |
633 | if (nPos < (UINT)PatternSize[ord]) break; | 633 | if (nPos < (UINT)PatternSize[ord]) break; |
634 | nPos -= PatternSize[ord]; | 634 | nPos -= PatternSize[ord]; |
635 | } | 635 | } |
636 | } | 636 | } |
637 | // Buggy position ? | 637 | // Buggy position ? |
638 | if ((nPattern >= MAX_ORDERS) | 638 | if ((nPattern >= MAX_ORDERS) |
639 | || (Order[nPattern] >= MAX_PATTERNS) | 639 | || (Order[nPattern] >= MAX_PATTERNS) |
640 | || (nPos >= PatternSize[Order[nPattern]])) | 640 | || (nPos >= PatternSize[Order[nPattern]])) |
641 | { | 641 | { |
642 | nPos = 0; | 642 | nPos = 0; |
643 | nPattern = 0; | 643 | nPattern = 0; |
644 | } | 644 | } |
645 | UINT nRow = nPos; | 645 | UINT nRow = nPos; |
646 | if ((nRow) && (Order[nPattern] < MAX_PATTERNS)) | 646 | if ((nRow) && (Order[nPattern] < MAX_PATTERNS)) |
647 | { | 647 | { |
648 | MODCOMMAND *p = Patterns[Order[nPattern]]; | 648 | MODCOMMAND *p = Patterns[Order[nPattern]]; |
649 | if ((p) && (nRow < PatternSize[Order[nPattern]])) | 649 | if ((p) && (nRow < PatternSize[Order[nPattern]])) |
650 | { | 650 | { |
651 | BOOL bOk = FALSE; | 651 | BOOL bOk = FALSE; |
652 | while ((!bOk) && (nRow > 0)) | 652 | while ((!bOk) && (nRow > 0)) |
653 | { | 653 | { |
654 | UINT n = nRow * m_nChannels; | 654 | UINT n = nRow * m_nChannels; |
655 | for (UINT k=0; k<m_nChannels; k++, n++) | 655 | for (UINT k=0; k<m_nChannels; k++, n++) |
656 | { | 656 | { |
657 | if (p[n].note) | 657 | if (p[n].note) |
658 | { | 658 | { |
659 | bOk = TRUE; | 659 | bOk = TRUE; |
660 | break; | 660 | break; |
661 | } | 661 | } |
662 | } | 662 | } |
663 | if (!bOk) nRow--; | 663 | if (!bOk) nRow--; |
664 | } | 664 | } |
665 | } | 665 | } |
666 | } | 666 | } |
667 | m_nNextPattern = nPattern; | 667 | m_nNextPattern = nPattern; |
668 | m_nNextRow = nRow; | 668 | m_nNextRow = nRow; |
669 | m_nTickCount = m_nMusicSpeed; | 669 | m_nTickCount = m_nMusicSpeed; |
670 | m_nBufferCount = 0; | 670 | m_nBufferCount = 0; |
671 | m_nPatternDelay = 0; | 671 | m_nPatternDelay = 0; |
672 | m_nFrameDelay = 0; | 672 | m_nFrameDelay = 0; |
673 | } | 673 | } |
674 | 674 | ||
675 | 675 | ||
676 | void CSoundFile::SetCurrentOrder(UINT nPos) | 676 | void CSoundFile::SetCurrentOrder(UINT nPos) |
677 | //----------------------------------------- | 677 | //----------------------------------------- |
678 | { | 678 | { |
679 | while ((nPos < MAX_ORDERS) && (Order[nPos] == 0xFE)) nPos++; | 679 | while ((nPos < MAX_ORDERS) && (Order[nPos] == 0xFE)) nPos++; |
680 | if ((nPos >= MAX_ORDERS) || (Order[nPos] >= MAX_PATTERNS)) return; | 680 | if ((nPos >= MAX_ORDERS) || (Order[nPos] >= MAX_PATTERNS)) return; |
681 | for (UINT j=0; j<MAX_CHANNELS; j++) | 681 | for (UINT j=0; j<MAX_CHANNELS; j++) |
682 | { | 682 | { |
683 | Chn[j].nPeriod = 0; | 683 | Chn[j].nPeriod = 0; |
684 | Chn[j].nNote = 0; | 684 | Chn[j].nNote = 0; |
685 | Chn[j].nPortamentoDest = 0; | 685 | Chn[j].nPortamentoDest = 0; |
686 | Chn[j].nCommand = 0; | 686 | Chn[j].nCommand = 0; |
687 | Chn[j].nPatternLoopCount = 0; | 687 | Chn[j].nPatternLoopCount = 0; |
688 | Chn[j].nPatternLoop = 0; | 688 | Chn[j].nPatternLoop = 0; |
689 | Chn[j].nTremorCount = 0; | 689 | Chn[j].nTremorCount = 0; |
690 | } | 690 | } |
691 | if (!nPos) | 691 | if (!nPos) |
692 | { | 692 | { |
693 | SetCurrentPos(0); | 693 | SetCurrentPos(0); |
694 | } else | 694 | } else |
695 | { | 695 | { |
696 | m_nNextPattern = nPos; | 696 | m_nNextPattern = nPos; |
697 | m_nRow = m_nNextRow = 0; | 697 | m_nRow = m_nNextRow = 0; |
698 | m_nPattern = 0; | 698 | m_nPattern = 0; |
699 | m_nTickCount = m_nMusicSpeed; | 699 | m_nTickCount = m_nMusicSpeed; |
700 | m_nBufferCount = 0; | 700 | m_nBufferCount = 0; |
701 | m_nTotalCount = 0; | 701 | m_nTotalCount = 0; |
702 | m_nPatternDelay = 0; | 702 | m_nPatternDelay = 0; |
703 | m_nFrameDelay = 0; | 703 | m_nFrameDelay = 0; |
704 | } | 704 | } |
705 | m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); | 705 | m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); |
706 | } | 706 | } |
707 | 707 | ||
708 | 708 | ||
709 | void CSoundFile::ResetChannels() | 709 | void CSoundFile::ResetChannels() |
710 | //------------------------------ | 710 | //------------------------------ |
711 | { | 711 | { |
712 | m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); | 712 | m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); |
713 | m_nBufferCount = 0; | 713 | m_nBufferCount = 0; |
714 | for (UINT i=0; i<MAX_CHANNELS; i++) | 714 | for (UINT i=0; i<MAX_CHANNELS; i++) |
715 | { | 715 | { |
716 | Chn[i].nROfs = Chn[i].nLOfs = 0; | 716 | Chn[i].nROfs = Chn[i].nLOfs = 0; |
717 | } | 717 | } |
718 | } | 718 | } |
719 | 719 | ||
720 | 720 | ||
721 | void CSoundFile::LoopPattern(int nPat, int nRow) | 721 | void CSoundFile::LoopPattern(int nPat, int nRow) |
722 | //---------------------------------------------- | 722 | //---------------------------------------------- |
723 | { | 723 | { |
724 | if ((nPat < 0) || (nPat >= MAX_PATTERNS) || (!Patterns[nPat])) | 724 | if ((nPat < 0) || (nPat >= MAX_PATTERNS) || (!Patterns[nPat])) |
725 | { | 725 | { |
726 | m_dwSongFlags &= ~SONG_PATTERNLOOP; | 726 | m_dwSongFlags &= ~SONG_PATTERNLOOP; |
727 | } else | 727 | } else |
728 | { | 728 | { |
729 | if ((nRow < 0) || (nRow >= PatternSize[nPat])) nRow = 0; | 729 | if ((nRow < 0) || (nRow >= PatternSize[nPat])) nRow = 0; |
730 | m_nPattern = nPat; | 730 | m_nPattern = nPat; |
731 | m_nRow = m_nNextRow = nRow; | 731 | m_nRow = m_nNextRow = nRow; |
732 | m_nTickCount = m_nMusicSpeed; | 732 | m_nTickCount = m_nMusicSpeed; |
733 | m_nPatternDelay = 0; | 733 | m_nPatternDelay = 0; |
734 | m_nFrameDelay = 0; | 734 | m_nFrameDelay = 0; |
735 | m_nBufferCount = 0; | 735 | m_nBufferCount = 0; |
736 | m_dwSongFlags |= SONG_PATTERNLOOP; | 736 | m_dwSongFlags |= SONG_PATTERNLOOP; |
737 | } | 737 | } |
738 | } | 738 | } |
739 | 739 | ||
740 | 740 | ||
741 | UINT CSoundFile::GetBestSaveFormat() const | 741 | UINT CSoundFile::GetBestSaveFormat() const |
742 | //---------------------------------------- | 742 | //---------------------------------------- |
743 | { | 743 | { |
744 | if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE; | 744 | if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE; |
745 | if (!m_nType) return MOD_TYPE_NONE; | 745 | if (!m_nType) return MOD_TYPE_NONE; |
746 | if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_OKT)) | 746 | if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_OKT)) |
747 | return MOD_TYPE_MOD; | 747 | return MOD_TYPE_MOD; |
748 | if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM)) | 748 | if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM)) |
749 | return MOD_TYPE_S3M; | 749 | return MOD_TYPE_S3M; |
750 | if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MTM|MOD_TYPE_MT2)) | 750 | if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MTM|MOD_TYPE_MT2)) |
751 | return MOD_TYPE_XM; | 751 | return MOD_TYPE_XM; |
752 | return MOD_TYPE_IT; | 752 | return MOD_TYPE_IT; |
753 | } | 753 | } |
754 | 754 | ||
755 | 755 | ||
756 | UINT CSoundFile::GetSaveFormats() const | 756 | UINT CSoundFile::GetSaveFormats() const |
757 | //------------------------------------- | 757 | //------------------------------------- |
758 | { | 758 | { |
759 | UINT n = 0; | 759 | UINT n = 0; |
760 | if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0; | 760 | if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0; |
761 | switch(m_nType) | 761 | switch(m_nType) |
762 | { | 762 | { |
763 | case MOD_TYPE_MOD:n = MOD_TYPE_MOD; | 763 | case MOD_TYPE_MOD:n = MOD_TYPE_MOD; |
764 | case MOD_TYPE_S3M:n = MOD_TYPE_S3M; | 764 | case MOD_TYPE_S3M:n = MOD_TYPE_S3M; |
765 | } | 765 | } |
766 | n |= MOD_TYPE_XM | MOD_TYPE_IT; | 766 | n |= MOD_TYPE_XM | MOD_TYPE_IT; |
767 | if (!m_nInstruments) | 767 | if (!m_nInstruments) |
768 | { | 768 | { |
769 | if (m_nSamples < 32) n |= MOD_TYPE_MOD; | 769 | if (m_nSamples < 32) n |= MOD_TYPE_MOD; |
770 | n |= MOD_TYPE_S3M; | 770 | n |= MOD_TYPE_S3M; |
771 | } | 771 | } |
772 | return n; | 772 | return n; |
773 | } | 773 | } |
774 | 774 | ||
775 | 775 | ||
776 | UINT CSoundFile::GetSampleName(UINT nSample,LPSTR s) const | 776 | UINT CSoundFile::GetSampleName(UINT nSample,LPSTR s) const |
777 | //-------------------------------------------------------- | 777 | //-------------------------------------------------------- |
778 | { | 778 | { |
779 | char sztmp[40] = ""; // changed from CHAR | 779 | char sztmp[40] = ""; // changed from CHAR |
780 | memcpy(sztmp, m_szNames[nSample],32); | 780 | memcpy(sztmp, m_szNames[nSample],32); |
781 | sztmp[31] = 0; | 781 | sztmp[31] = 0; |
782 | if (s) strcpy(s, sztmp); | 782 | if (s) strcpy(s, sztmp); |
783 | return strlen(sztmp); | 783 | return strlen(sztmp); |
784 | } | 784 | } |
785 | 785 | ||
786 | 786 | ||
787 | UINT CSoundFile::GetInstrumentName(UINT nInstr,LPSTR s) const | 787 | UINT CSoundFile::GetInstrumentName(UINT nInstr,LPSTR s) const |
788 | //----------------------------------------------------------- | 788 | //----------------------------------------------------------- |
789 | { | 789 | { |
790 | char sztmp[40] = ""; // changed from CHAR | 790 | char sztmp[40] = ""; // changed from CHAR |
791 | if ((nInstr >= MAX_INSTRUMENTS) || (!Headers[nInstr])) | 791 | if ((nInstr >= MAX_INSTRUMENTS) || (!Headers[nInstr])) |
792 | { | 792 | { |
793 | if (s) *s = 0; | 793 | if (s) *s = 0; |
794 | return 0; | 794 | return 0; |
795 | } | 795 | } |
796 | INSTRUMENTHEADER *penv = Headers[nInstr]; | 796 | INSTRUMENTHEADER *penv = Headers[nInstr]; |
797 | memcpy(sztmp, penv->name, 32); | 797 | memcpy(sztmp, penv->name, 32); |
798 | sztmp[31] = 0; | 798 | sztmp[31] = 0; |
799 | if (s) strcpy(s, sztmp); | 799 | if (s) strcpy(s, sztmp); |
800 | return strlen(sztmp); | 800 | return strlen(sztmp); |
801 | } | 801 | } |
802 | 802 | ||
803 | 803 | ||
804 | #ifndef NO_PACKING | 804 | #ifndef NO_PACKING |
805 | UINT CSoundFile::PackSample(int &sample, int next) | 805 | UINT CSoundFile::PackSample(int &sample, int next) |
806 | //------------------------------------------------ | 806 | //------------------------------------------------ |
807 | { | 807 | { |
808 | UINT i = 0; | 808 | UINT i = 0; |
809 | int delta = next - sample; | 809 | int delta = next - sample; |
810 | if (delta >= 0) | 810 | if (delta >= 0) |
811 | { | 811 | { |
812 | for (i=0; i<7; i++) if (delta <= (int)CompressionTable[i+1]) break; | 812 | for (i=0; i<7; i++) if (delta <= (int)CompressionTable[i+1]) break; |
813 | } else | 813 | } else |
814 | { | 814 | { |
815 | for (i=8; i<15; i++) if (delta >= (int)CompressionTable[i+1]) break; | 815 | for (i=8; i<15; i++) if (delta >= (int)CompressionTable[i+1]) break; |
816 | } | 816 | } |
817 | sample += (int)CompressionTable[i]; | 817 | sample += (int)CompressionTable[i]; |
818 | return i; | 818 | return i; |
819 | } | 819 | } |
820 | 820 | ||
821 | 821 | ||
822 | BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) | 822 | BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) |
823 | //----------------------------------------------------------------------------------- | 823 | //----------------------------------------------------------------------------------- |
824 | { | 824 | { |
825 | int pos, old, oldpos, besttable = 0; | 825 | int pos, old, oldpos, besttable = 0; |
826 | DWORD dwErr, dwTotal, dwResult; | 826 | DWORD dwErr, dwTotal, dwResult; |
827 | int i,j; | 827 | int i,j; |
828 | 828 | ||
829 | if (result) *result = 0; | 829 | if (result) *result = 0; |
830 | if ((!pSample) || (nLen < 1024)) return FALSE; | 830 | if ((!pSample) || (nLen < 1024)) return FALSE; |
831 | // Try packing with different tables | 831 | // Try packing with different tables |
832 | dwResult = 0; | 832 | dwResult = 0; |
833 | for (j=1; j<MAX_PACK_TABLES; j++) | 833 | for (j=1; j<MAX_PACK_TABLES; j++) |
834 | { | 834 | { |
835 | memcpy(CompressionTable, UnpackTable[j], 16); | 835 | memcpy(CompressionTable, UnpackTable[j], 16); |
836 | dwErr = 0; | 836 | dwErr = 0; |
837 | dwTotal = 1; | 837 | dwTotal = 1; |
838 | old = pos = oldpos = 0; | 838 | old = pos = oldpos = 0; |
839 | for (i=0; i<(int)nLen; i++) | 839 | for (i=0; i<(int)nLen; i++) |
840 | { | 840 | { |
841 | int s = (int)pSample[i]; | 841 | int s = (int)pSample[i]; |
842 | PackSample(pos, s); | 842 | PackSample(pos, s); |
843 | dwErr += abs(pos - oldpos); | 843 | dwErr += abs(pos - oldpos); |
844 | dwTotal += abs(s - old); | 844 | dwTotal += abs(s - old); |
845 | old = s; | 845 | old = s; |
846 | oldpos = pos; | 846 | oldpos = pos; |
847 | } | 847 | } |
848 | dwErr = _muldiv(dwErr, 100, dwTotal); | 848 | dwErr = _muldiv(dwErr, 100, dwTotal); |
849 | if (dwErr >= dwResult) | 849 | if (dwErr >= dwResult) |
850 | { | 850 | { |
851 | dwResult = dwErr; | 851 | dwResult = dwErr; |
852 | besttable = j; | 852 | besttable = j; |
853 | } | 853 | } |
854 | } | 854 | } |
855 | memcpy(CompressionTable, UnpackTable[besttable], 16); | 855 | memcpy(CompressionTable, UnpackTable[besttable], 16); |
856 | if (result) | 856 | if (result) |
857 | { | 857 | { |
858 | if (dwResult > 100) *result= 100; else *result = (BYTE)dwResult; | 858 | if (dwResult > 100) *result= 100; else *result = (BYTE)dwResult; |
859 | } | 859 | } |
860 | return (dwResult >= nPacking) ? TRUE : FALSE; | 860 | return (dwResult >= nPacking) ? TRUE : FALSE; |
861 | } | 861 | } |
862 | #endif // NO_PACKING | 862 | #endif // NO_PACKING |
863 | 863 | ||
864 | #ifndef MODPLUG_NO_FILESAVE | 864 | #ifndef MODPLUG_NO_FILESAVE |
865 | 865 | ||
866 | UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen) | 866 | UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen) |
867 | //----------------------------------------------------------------------------------- | 867 | //----------------------------------------------------------------------------------- |
868 | { | 868 | { |
869 | UINT len = 0, bufcount; | 869 | UINT len = 0, bufcount; |
870 | signed char buffer[4096]; | 870 | signed char buffer[4096]; |
871 | signed char *pSample = (signed char *)pins->pSample; | 871 | signed char *pSample = (signed char *)pins->pSample; |
872 | UINT nLen = pins->nLength; | 872 | UINT nLen = pins->nLength; |
873 | 873 | ||
874 | if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen; | 874 | if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen; |
875 | if ((!pSample) || (f == NULL) || (!nLen)) return 0; | 875 | if ((!pSample) || (f == NULL) || (!nLen)) return 0; |
876 | switch(nFlags) | 876 | switch(nFlags) |
877 | { | 877 | { |
878 | #ifndef NO_PACKING | 878 | #ifndef NO_PACKING |
879 | // 3: 4-bit ADPCM data | 879 | // 3: 4-bit ADPCM data |
880 | case RS_ADPCM4: | 880 | case RS_ADPCM4: |
881 | { | 881 | { |
882 | int pos; | 882 | int pos; |
883 | len = (nLen + 1) / 2; | 883 | len = (nLen + 1) / 2; |
884 | fwrite(CompressionTable, 16, 1, f); | 884 | fwrite(CompressionTable, 16, 1, f); |
885 | bufcount = 0; | 885 | bufcount = 0; |
886 | pos = 0; | 886 | pos = 0; |
887 | for (UINT j=0; j<len; j++) | 887 | for (UINT j=0; j<len; j++) |
888 | { | 888 | { |
889 | BYTE b; | 889 | BYTE b; |
890 | // Sample #1 | 890 | // Sample #1 |
891 | b = PackSample(pos, (int)pSample[j*2]); | 891 | b = PackSample(pos, (int)pSample[j*2]); |
892 | // Sample #2 | 892 | // Sample #2 |
893 | b |= PackSample(pos, (int)pSample[j*2+1]) << 4; | 893 | b |= PackSample(pos, (int)pSample[j*2+1]) << 4; |
894 | buffer[bufcount++] = (signed char)b; | 894 | buffer[bufcount++] = (signed char)b; |
895 | if (bufcount >= sizeof(buffer)) | 895 | if (bufcount >= sizeof(buffer)) |
896 | { | 896 | { |
897 | fwrite(buffer, 1, bufcount, f); | 897 | fwrite(buffer, 1, bufcount, f); |
898 | bufcount = 0; | 898 | bufcount = 0; |
899 | } | 899 | } |
900 | } | 900 | } |
901 | if (bufcount) fwrite(buffer, 1, bufcount, f); | 901 | if (bufcount) fwrite(buffer, 1, bufcount, f); |
902 | len += 16; | 902 | len += 16; |
903 | } | 903 | } |
904 | break; | 904 | break; |
905 | #endif // NO_PACKING | 905 | #endif // NO_PACKING |
906 | 906 | ||
907 | // 16-bit samples | 907 | // 16-bit samples |
908 | case RS_PCM16U: | 908 | case RS_PCM16U: |
909 | case RS_PCM16D: | 909 | case RS_PCM16D: |
910 | case RS_PCM16S: | 910 | case RS_PCM16S: |
911 | { | 911 | { |
912 | short int *p = (short int *)pSample; | 912 | short int *p = (short int *)pSample; |
913 | int s_old = 0, s_ofs; | 913 | int s_old = 0, s_ofs; |
914 | len = nLen * 2; | 914 | len = nLen * 2; |
915 | bufcount = 0; | 915 | bufcount = 0; |
916 | s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0; | 916 | s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0; |
917 | for (UINT j=0; j<nLen; j++) | 917 | for (UINT j=0; j<nLen; j++) |
918 | { | 918 | { |
919 | int s_new = *p; | 919 | int s_new = *p; |
920 | p++; | 920 | p++; |
921 | if (pins->uFlags & CHN_STEREO) | 921 | if (pins->uFlags & CHN_STEREO) |
922 | { | 922 | { |
923 | s_new = (s_new + (*p) + 1) >> 1; | 923 | s_new = (s_new + (*p) + 1) >> 1; |
924 | p++; | 924 | p++; |
925 | } | 925 | } |
926 | if (nFlags == RS_PCM16D) | 926 | if (nFlags == RS_PCM16D) |
927 | { | 927 | { |
928 | *((short *)(&buffer[bufcount])) = (short)(s_new - s_old); | 928 | *((short *)(&buffer[bufcount])) = (short)(s_new - s_old); |
929 | s_old = s_new; | 929 | s_old = s_new; |
930 | } else | 930 | } else |
931 | { | 931 | { |
932 | *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs); | 932 | *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs); |
933 | } | 933 | } |
934 | bufcount += 2; | 934 | bufcount += 2; |
935 | if (bufcount >= sizeof(buffer) - 1) | 935 | if (bufcount >= sizeof(buffer) - 1) |
936 | { | 936 | { |
937 | fwrite(buffer, 1, bufcount, f); | 937 | fwrite(buffer, 1, bufcount, f); |
938 | bufcount = 0; | 938 | bufcount = 0; |
939 | } | 939 | } |
940 | } | 940 | } |
941 | if (bufcount) fwrite(buffer, 1, bufcount, f); | 941 | if (bufcount) fwrite(buffer, 1, bufcount, f); |
942 | } | 942 | } |
943 | break; | 943 | break; |
944 | 944 | ||
945 | 945 | ||
946 | // 8-bit Stereo samples (not interleaved) | 946 | // 8-bit Stereo samples (not interleaved) |
947 | case RS_STPCM8S: | 947 | case RS_STPCM8S: |
948 | case RS_STPCM8U: | 948 | case RS_STPCM8U: |
949 | case RS_STPCM8D: | 949 | case RS_STPCM8D: |
950 | { | 950 | { |
951 | int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0; | 951 | int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0; |
952 | for (UINT iCh=0; iCh<2; iCh++) | 952 | for (UINT iCh=0; iCh<2; iCh++) |
953 | { | 953 | { |
954 | signed char *p = pSample + iCh; | 954 | signed char *p = pSample + iCh; |
955 | int s_old = 0; | 955 | int s_old = 0; |
956 | 956 | ||
957 | bufcount = 0; | 957 | bufcount = 0; |
958 | for (UINT j=0; j<nLen; j++) | 958 | for (UINT j=0; j<nLen; j++) |
959 | { | 959 | { |
960 | int s_new = *p; | 960 | int s_new = *p; |
961 | p += 2; | 961 | p += 2; |
962 | if (nFlags == RS_STPCM8D) | 962 | if (nFlags == RS_STPCM8D) |
963 | { | 963 | { |
964 | buffer[bufcount++] = (signed char)(s_new - s_old); | 964 | buffer[bufcount++] = (signed char)(s_new - s_old); |
965 | s_old = s_new; | 965 | s_old = s_new; |
966 | } else | 966 | } else |
967 | { | 967 | { |
968 | buffer[bufcount++] = (signed char)(s_new + s_ofs); | 968 | buffer[bufcount++] = (signed char)(s_new + s_ofs); |
969 | } | 969 | } |
970 | if (bufcount >= sizeof(buffer)) | 970 | if (bufcount >= sizeof(buffer)) |
971 | { | 971 | { |
972 | fwrite(buffer, 1, bufcount, f); | 972 | fwrite(buffer, 1, bufcount, f); |
973 | bufcount = 0; | 973 | bufcount = 0; |
974 | } | 974 | } |
975 | } | 975 | } |
976 | if (bufcount) fwrite(buffer, 1, bufcount, f); | 976 | if (bufcount) fwrite(buffer, 1, bufcount, f); |
977 | } | 977 | } |
978 | } | 978 | } |
979 | len = nLen * 2; | 979 | len = nLen * 2; |
980 | break; | 980 | break; |
981 | 981 | ||
982 | // 16-bit Stereo samples (not interleaved) | 982 | // 16-bit Stereo samples (not interleaved) |
983 | case RS_STPCM16S: | 983 | case RS_STPCM16S: |
984 | case RS_STPCM16U: | 984 | case RS_STPCM16U: |
985 | case RS_STPCM16D: | 985 | case RS_STPCM16D: |
986 | { | 986 | { |
987 | int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0; | 987 | int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0; |
988 | for (UINT iCh=0; iCh<2; iCh++) | 988 | for (UINT iCh=0; iCh<2; iCh++) |
989 | { | 989 | { |
990 | signed short *p = ((signed short *)pSample) + iCh; | 990 | signed short *p = ((signed short *)pSample) + iCh; |
991 | int s_old = 0; | 991 | int s_old = 0; |
992 | 992 | ||
993 | bufcount = 0; | 993 | bufcount = 0; |
994 | for (UINT j=0; j<nLen; j++) | 994 | for (UINT j=0; j<nLen; j++) |
995 | { | 995 | { |
996 | int s_new = *p; | 996 | int s_new = *p; |
997 | p += 2; | 997 | p += 2; |
998 | if (nFlags == RS_STPCM16D) | 998 | if (nFlags == RS_STPCM16D) |
999 | { | 999 | { |
1000 | *((short *)(&buffer[bufcount])) = (short)(s_new - s_old); | 1000 | *((short *)(&buffer[bufcount])) = (short)(s_new - s_old); |
1001 | s_old = s_new; | 1001 | s_old = s_new; |
1002 | } else | 1002 | } else |
1003 | { | 1003 | { |
1004 | *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs); | 1004 | *((short *)(&buffer[bufcount])) = (short)(s_new + s_ofs); |
1005 | } | 1005 | } |
1006 | bufcount += 2; | 1006 | bufcount += 2; |
1007 | if (bufcount >= sizeof(buffer)) | 1007 | if (bufcount >= sizeof(buffer)) |
1008 | { | 1008 | { |
1009 | fwrite(buffer, 1, bufcount, f); | 1009 | fwrite(buffer, 1, bufcount, f); |
1010 | bufcount = 0; | 1010 | bufcount = 0; |
1011 | } | 1011 | } |
1012 | } | 1012 | } |
1013 | if (bufcount) fwrite(buffer, 1, bufcount, f); | 1013 | if (bufcount) fwrite(buffer, 1, bufcount, f); |
1014 | } | 1014 | } |
1015 | } | 1015 | } |
1016 | len = nLen*4; | 1016 | len = nLen*4; |
1017 | break; | 1017 | break; |
1018 | 1018 | ||
1019 | //Stereo signed interleaved | 1019 | //Stereo signed interleaved |
1020 | case RS_STIPCM8S: | 1020 | case RS_STIPCM8S: |
1021 | case RS_STIPCM16S: | 1021 | case RS_STIPCM16S: |
1022 | len = nLen * 2; | 1022 | len = nLen * 2; |
1023 | if (nFlags == RS_STIPCM16S) len *= 2; | 1023 | if (nFlags == RS_STIPCM16S) len *= 2; |
1024 | fwrite(pSample, 1, len, f); | 1024 | fwrite(pSample, 1, len, f); |
1025 | break; | 1025 | break; |
1026 | 1026 | ||
1027 | // Default: assume 8-bit PCM data | 1027 | // Default: assume 8-bit PCM data |
1028 | default: | 1028 | default: |
1029 | len = nLen; | 1029 | len = nLen; |
1030 | bufcount = 0; | 1030 | bufcount = 0; |
1031 | { | 1031 | { |
1032 | signed char *p = pSample; | 1032 | signed char *p = pSample; |
1033 | int sinc = (pins->uFlags & CHN_16BIT) ? 2 : 1; | 1033 | int sinc = (pins->uFlags & CHN_16BIT) ? 2 : 1; |
1034 | int s_old = 0, s_ofs = (nFlags == RS_PCM8U) ? 0x80 : 0; | 1034 | int s_old = 0, s_ofs = (nFlags == RS_PCM8U) ? 0x80 : 0; |
1035 | if (pins->uFlags & CHN_16BIT) p++; | 1035 | if (pins->uFlags & CHN_16BIT) p++; |
1036 | for (UINT j=0; j<len; j++) | 1036 | for (UINT j=0; j<len; j++) |
1037 | { | 1037 | { |
1038 | int s_new = (signed char)(*p); | 1038 | int s_new = (signed char)(*p); |
1039 | p += sinc; | 1039 | p += sinc; |
1040 | if (pins->uFlags & CHN_STEREO) | 1040 | if (pins->uFlags & CHN_STEREO) |
1041 | { | 1041 | { |
1042 | s_new = (s_new + ((int)*p) + 1) >> 1; | 1042 | s_new = (s_new + ((int)*p) + 1) >> 1; |
1043 | p += sinc; | 1043 | p += sinc; |
1044 | } | 1044 | } |
1045 | if (nFlags == RS_PCM8D) | 1045 | if (nFlags == RS_PCM8D) |
1046 | { | 1046 | { |
1047 | buffer[bufcount++] = (signed char)(s_new - s_old); | 1047 | buffer[bufcount++] = (signed char)(s_new - s_old); |
1048 | s_old = s_new; | 1048 | s_old = s_new; |
1049 | } else | 1049 | } else |
1050 | { | 1050 | { |
1051 | buffer[bufcount++] = (signed char)(s_new + s_ofs); | 1051 | buffer[bufcount++] = (signed char)(s_new + s_ofs); |
1052 | } | 1052 | } |
1053 | if (bufcount >= sizeof(buffer)) | 1053 | if (bufcount >= sizeof(buffer)) |
1054 | { | 1054 | { |
1055 | fwrite(buffer, 1, bufcount, f); | 1055 | fwrite(buffer, 1, bufcount, f); |
1056 | bufcount = 0; | 1056 | bufcount = 0; |
1057 | } | 1057 | } |
1058 | } | 1058 | } |
1059 | if (bufcount) fwrite(buffer, 1, bufcount, f); | 1059 | if (bufcount) fwrite(buffer, 1, bufcount, f); |
1060 | } | 1060 | } |
1061 | } | 1061 | } |
1062 | return len; | 1062 | return len; |
1063 | } | 1063 | } |
1064 | 1064 | ||
1065 | #endif // MODPLUG_NO_FILESAVE | 1065 | #endif // MODPLUG_NO_FILESAVE |
1066 | 1066 | ||
1067 | 1067 | ||
1068 | // Flags: | 1068 | // Flags: |
1069 | //0 = signed 8-bit PCM data (default) | 1069 | //0 = signed 8-bit PCM data (default) |
1070 | //1 = unsigned 8-bit PCM data | 1070 | //1 = unsigned 8-bit PCM data |
1071 | //2 = 8-bit ADPCM data with linear table | 1071 | //2 = 8-bit ADPCM data with linear table |
1072 | //3 = 4-bit ADPCM data | 1072 | //3 = 4-bit ADPCM data |
1073 | //4 = 16-bit ADPCM data with linear table | 1073 | //4 = 16-bit ADPCM data with linear table |
1074 | //5 = signed 16-bit PCM data | 1074 | //5 = signed 16-bit PCM data |
1075 | //6 = unsigned 16-bit PCM data | 1075 | //6 = unsigned 16-bit PCM data |
1076 | 1076 | ||
1077 | 1077 | ||
1078 | UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength) | 1078 | UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength) |
1079 | //------------------------------------------------------------------------------------------------ | 1079 | //------------------------------------------------------------------------------------------------ |
1080 | { | 1080 | { |
1081 | UINT len = 0, mem = pIns->nLength+6; | 1081 | UINT len = 0, mem = pIns->nLength+6; |
1082 | 1082 | ||
1083 | if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; | 1083 | if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; |
1084 | if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; | 1084 | if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; |
1085 | pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); | 1085 | pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); |
1086 | if (nFlags & RSF_16BIT) | 1086 | if (nFlags & RSF_16BIT) |
1087 | { | 1087 | { |
1088 | mem *= 2; | 1088 | mem *= 2; |
1089 | pIns->uFlags |= CHN_16BIT; | 1089 | pIns->uFlags |= CHN_16BIT; |
1090 | } | 1090 | } |
1091 | if (nFlags & RSF_STEREO) | 1091 | if (nFlags & RSF_STEREO) |
1092 | { | 1092 | { |
1093 | mem *= 2; | 1093 | mem *= 2; |
1094 | pIns->uFlags |= CHN_STEREO; | 1094 | pIns->uFlags |= CHN_STEREO; |
1095 | } | 1095 | } |
1096 | if ((pIns->pSample = AllocateSample(mem)) == NULL) | 1096 | if ((pIns->pSample = AllocateSample(mem)) == NULL) |
1097 | { | 1097 | { |
1098 | pIns->nLength = 0; | 1098 | pIns->nLength = 0; |
1099 | return 0; | 1099 | return 0; |
1100 | } | 1100 | } |
1101 | switch(nFlags) | 1101 | switch(nFlags) |
1102 | { | 1102 | { |
1103 | // 1: 8-bit unsigned PCM data | 1103 | // 1: 8-bit unsigned PCM data |
1104 | case RS_PCM8U: | 1104 | case RS_PCM8U: |
1105 | { | 1105 | { |
1106 | len = pIns->nLength; | 1106 | len = pIns->nLength; |
1107 | if (len > dwMemLength) len = pIns->nLength = dwMemLength; | 1107 | if (len > dwMemLength) len = pIns->nLength = dwMemLength; |
1108 | signed char *pSample = pIns->pSample; | 1108 | signed char *pSample = pIns->pSample; |
1109 | for (UINT j=0; j<len; j++) pSample[j] = (signed char)(lpMemFile[j] - 0x80); | 1109 | for (UINT j=0; j<len; j++) pSample[j] = (signed char)(lpMemFile[j] - 0x80); |
1110 | } | 1110 | } |
1111 | break; | 1111 | break; |
1112 | 1112 | ||
1113 | // 2: 8-bit ADPCM data with linear table | 1113 | // 2: 8-bit ADPCM data with linear table |
1114 | case RS_PCM8D: | 1114 | case RS_PCM8D: |
1115 | { | 1115 | { |
1116 | len = pIns->nLength; | 1116 | len = pIns->nLength; |
1117 | if (len > dwMemLength) break; | 1117 | if (len > dwMemLength) break; |
1118 | signed char *pSample = pIns->pSample; | 1118 | signed char *pSample = pIns->pSample; |
1119 | const signed char *p = (const signed char *)lpMemFile; | 1119 | const signed char *p = (const signed char *)lpMemFile; |
1120 | int delta = 0; | 1120 | int delta = 0; |
1121 | 1121 | ||
1122 | for (UINT j=0; j<len; j++) | 1122 | for (UINT j=0; j<len; j++) |
1123 | { | 1123 | { |
1124 | delta += p[j]; | 1124 | delta += p[j]; |
1125 | *pSample++ = (signed char)delta; | 1125 | *pSample++ = (signed char)delta; |
1126 | } | 1126 | } |
1127 | } | 1127 | } |
1128 | break; | 1128 | break; |
1129 | 1129 | ||
1130 | // 3: 4-bit ADPCM data | 1130 | // 3: 4-bit ADPCM data |
1131 | case RS_ADPCM4: | 1131 | case RS_ADPCM4: |
1132 | { | 1132 | { |
1133 | len = (pIns->nLength + 1) / 2; | 1133 | len = (pIns->nLength + 1) / 2; |
1134 | if (len > dwMemLength - 16) break; | 1134 | if (len > dwMemLength - 16) break; |
1135 | memcpy(CompressionTable, lpMemFile, 16); | 1135 | memcpy(CompressionTable, lpMemFile, 16); |
1136 | lpMemFile += 16; | 1136 | lpMemFile += 16; |
1137 | signed char *pSample = pIns->pSample; | 1137 | signed char *pSample = pIns->pSample; |
1138 | signed char delta = 0; | 1138 | signed char delta = 0; |
1139 | for (UINT j=0; j<len; j++) | 1139 | for (UINT j=0; j<len; j++) |
1140 | { | 1140 | { |
1141 | BYTE b0 = (BYTE)lpMemFile[j]; | 1141 | BYTE b0 = (BYTE)lpMemFile[j]; |
1142 | BYTE b1 = (BYTE)(lpMemFile[j] >> 4); | 1142 | BYTE b1 = (BYTE)(lpMemFile[j] >> 4); |
1143 | delta = (signed char)GetDeltaValue((int)delta, b0); | 1143 | delta = (signed char)GetDeltaValue((int)delta, b0); |
1144 | pSample[0] = delta; | 1144 | pSample[0] = delta; |
1145 | delta = (signed char)GetDeltaValue((int)delta, b1); | 1145 | delta = (signed char)GetDeltaValue((int)delta, b1); |
1146 | pSample[1] = delta; | 1146 | pSample[1] = delta; |
1147 | pSample += 2; | 1147 | pSample += 2; |
1148 | } | 1148 | } |
1149 | len += 16; | 1149 | len += 16; |
1150 | } | 1150 | } |
1151 | break; | 1151 | break; |
1152 | 1152 | ||
1153 | // 4: 16-bit ADPCM data with linear table | 1153 | // 4: 16-bit ADPCM data with linear table |
1154 | case RS_PCM16D: | 1154 | case RS_PCM16D: |
1155 | { | 1155 | { |
1156 | len = pIns->nLength * 2; | 1156 | len = pIns->nLength * 2; |
1157 | if (len > dwMemLength) break; | 1157 | if (len > dwMemLength) break; |
1158 | short int *pSample = (short int *)pIns->pSample; | 1158 | short int *pSample = (short int *)pIns->pSample; |
1159 | short int *p = (short int *)lpMemFile; | 1159 | short int *p = (short int *)lpMemFile; |
1160 | int delta16 = 0; | 1160 | int delta16 = 0; |
1161 | for (UINT j=0; j<len; j+=2) | 1161 | for (UINT j=0; j<len; j+=2) |
1162 | { | 1162 | { |
1163 | delta16 += bswapLE16(*p++); | 1163 | delta16 += bswapLE16(*p++); |
1164 | *pSample++ = (short int)delta16; | 1164 | *pSample++ = (short int)delta16; |
1165 | } | 1165 | } |
1166 | } | 1166 | } |
1167 | break; | 1167 | break; |
1168 | 1168 | ||
1169 | // 5: 16-bit signed PCM data | 1169 | // 5: 16-bit signed PCM data |
1170 | case RS_PCM16S: | 1170 | case RS_PCM16S: |
1171 | { | 1171 | { |
1172 | len = pIns->nLength * 2; | 1172 | len = pIns->nLength * 2; |
1173 | if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len); | 1173 | if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len); |
1174 | short int *pSample = (short int *)pIns->pSample; | 1174 | short int *pSample = (short int *)pIns->pSample; |
1175 | for (UINT j=0; j<len; j+=2) | 1175 | for (UINT j=0; j<len; j+=2) |
1176 | { | 1176 | { |
1177 | *pSample++ = bswapLE16(*pSample); | 1177 | *pSample++ = bswapLE16(*pSample); |
1178 | } | 1178 | } |
1179 | } | 1179 | } |
1180 | break; | 1180 | break; |
1181 | 1181 | ||
1182 | // 16-bit signed mono PCM motorola byte order | 1182 | // 16-bit signed mono PCM motorola byte order |
1183 | case RS_PCM16M: | 1183 | case RS_PCM16M: |
1184 | len = pIns->nLength * 2; | 1184 | len = pIns->nLength * 2; |
1185 | if (len > dwMemLength) len = dwMemLength & ~1; | 1185 | if (len > dwMemLength) len = dwMemLength & ~1; |
1186 | if (len > 1) | 1186 | if (len > 1) |
1187 | { | 1187 | { |
1188 | signed char *pSample = (signed char *)pIns->pSample; | 1188 | signed char *pSample = (signed char *)pIns->pSample; |
1189 | signed char *pSrc = (signed char *)lpMemFile; | 1189 | signed char *pSrc = (signed char *)lpMemFile; |
1190 | for (UINT j=0; j<len; j+=2) | 1190 | for (UINT j=0; j<len; j+=2) |
1191 | { | 1191 | { |
1192 | // pSample[j] = pSrc[j+1]; | 1192 | // pSample[j] = pSrc[j+1]; |
1193 | // pSample[j+1] = pSrc[j]; | 1193 | // pSample[j+1] = pSrc[j]; |
1194 | *((unsigned short *)(pSample+j)) = bswapBE16(*((unsigned short *)(pSrc+j))); | 1194 | *((unsigned short *)(pSample+j)) = bswapBE16(*((unsigned short *)(pSrc+j))); |
1195 | } | 1195 | } |
1196 | } | 1196 | } |
1197 | break; | 1197 | break; |
1198 | 1198 | ||
1199 | // 6: 16-bit unsigned PCM data | 1199 | // 6: 16-bit unsigned PCM data |
1200 | case RS_PCM16U: | 1200 | case RS_PCM16U: |
1201 | { | 1201 | { |
1202 | len = pIns->nLength * 2; | 1202 | len = pIns->nLength * 2; |
1203 | if (len > dwMemLength) break; | 1203 | if (len > dwMemLength) break; |
1204 | short int *pSample = (short int *)pIns->pSample; | 1204 | short int *pSample = (short int *)pIns->pSample; |
1205 | short int *pSrc = (short int *)lpMemFile; | 1205 | short int *pSrc = (short int *)lpMemFile; |
1206 | for (UINT j=0; j<len; j+=2) *pSample++ = bswapLE16(*(pSrc++)) - 0x8000; | 1206 | for (UINT j=0; j<len; j+=2) *pSample++ = bswapLE16(*(pSrc++)) - 0x8000; |
1207 | } | 1207 | } |
1208 | break; | 1208 | break; |
1209 | 1209 | ||
1210 | // 16-bit signed stereo big endian | 1210 | // 16-bit signed stereo big endian |
1211 | case RS_STPCM16M: | 1211 | case RS_STPCM16M: |
1212 | len = pIns->nLength * 2; | 1212 | len = pIns->nLength * 2; |
1213 | if (len*2 <= dwMemLength) | 1213 | if (len*2 <= dwMemLength) |
1214 | { | 1214 | { |
1215 | signed char *pSample = (signed char *)pIns->pSample; | 1215 | signed char *pSample = (signed char *)pIns->pSample; |
1216 | signed char *pSrc = (signed char *)lpMemFile; | 1216 | signed char *pSrc = (signed char *)lpMemFile; |
1217 | for (UINT j=0; j<len; j+=2) | 1217 | for (UINT j=0; j<len; j+=2) |
1218 | { | 1218 | { |
1219 | // pSample[j*2] = pSrc[j+1]; | 1219 | // pSample[j*2] = pSrc[j+1]; |
1220 | // pSample[j*2+1] = pSrc[j]; | 1220 | // pSample[j*2+1] = pSrc[j]; |
1221 | // pSample[j*2+2] = pSrc[j+1+len]; | 1221 | // pSample[j*2+2] = pSrc[j+1+len]; |
1222 | // pSample[j*2+3] = pSrc[j+len]; | 1222 | // pSample[j*2+3] = pSrc[j+len]; |
1223 | *((unsigned short *)(pSample+j*2)) = bswapBE16(*((unsigned short *)(pSrc+j))); | 1223 | *((unsigned short *)(pSample+j*2)) = bswapBE16(*((unsigned short *)(pSrc+j))); |
1224 | *((unsigned short *)(pSample+j*2+2)) = bswapBE16(*((unsigned short *)(pSrc+j+len))); | 1224 | *((unsigned short *)(pSample+j*2+2)) = bswapBE16(*((unsigned short *)(pSrc+j+len))); |
1225 | } | 1225 | } |
1226 | len *= 2; | 1226 | len *= 2; |
1227 | } | 1227 | } |
1228 | break; | 1228 | break; |
1229 | 1229 | ||
1230 | // 8-bit stereo samples | 1230 | // 8-bit stereo samples |
1231 | case RS_STPCM8S: | 1231 | case RS_STPCM8S: |
1232 | case RS_STPCM8U: | 1232 | case RS_STPCM8U: |
1233 | case RS_STPCM8D: | 1233 | case RS_STPCM8D: |
1234 | { | 1234 | { |
1235 | int iadd_l = 0, iadd_r = 0; | 1235 | int iadd_l = 0, iadd_r = 0; |
1236 | if (nFlags == RS_STPCM8U) { iadd_l = iadd_r = -128; } | 1236 | if (nFlags == RS_STPCM8U) { iadd_l = iadd_r = -128; } |
1237 | len = pIns->nLength; | 1237 | len = pIns->nLength; |
1238 | signed char *psrc = (signed char *)lpMemFile; | 1238 | signed char *psrc = (signed char *)lpMemFile; |
1239 | signed char *pSample = (signed char *)pIns->pSample; | 1239 | signed char *pSample = (signed char *)pIns->pSample; |
1240 | if (len*2 > dwMemLength) break; | 1240 | if (len*2 > dwMemLength) break; |
1241 | for (UINT j=0; j<len; j++) | 1241 | for (UINT j=0; j<len; j++) |
1242 | { | 1242 | { |
1243 | pSample[j*2] = (signed char)(psrc[0] + iadd_l); | 1243 | pSample[j*2] = (signed char)(psrc[0] + iadd_l); |
1244 | pSample[j*2+1] = (signed char)(psrc[len] + iadd_r); | 1244 | pSample[j*2+1] = (signed char)(psrc[len] + iadd_r); |
1245 | psrc++; | 1245 | psrc++; |
1246 | if (nFlags == RS_STPCM8D) | 1246 | if (nFlags == RS_STPCM8D) |
1247 | { | 1247 | { |
1248 | iadd_l = pSample[j*2]; | 1248 | iadd_l = pSample[j*2]; |
1249 | iadd_r = pSample[j*2+1]; | 1249 | iadd_r = pSample[j*2+1]; |
1250 | } | 1250 | } |
1251 | } | 1251 | } |
1252 | len *= 2; | 1252 | len *= 2; |
1253 | } | 1253 | } |
1254 | break; | 1254 | break; |
1255 | 1255 | ||
1256 | // 16-bit stereo samples | 1256 | // 16-bit stereo samples |
1257 | case RS_STPCM16S: | 1257 | case RS_STPCM16S: |
1258 | case RS_STPCM16U: | 1258 | case RS_STPCM16U: |
1259 | case RS_STPCM16D: | 1259 | case RS_STPCM16D: |
1260 | { | 1260 | { |
1261 | int iadd_l = 0, iadd_r = 0; | 1261 | int iadd_l = 0, iadd_r = 0; |
1262 | if (nFlags == RS_STPCM16U) { iadd_l = iadd_r = -0x8000; } | 1262 | if (nFlags == RS_STPCM16U) { iadd_l = iadd_r = -0x8000; } |
1263 | len = pIns->nLength; | 1263 | len = pIns->nLength; |
1264 | short int *psrc = (short int *)lpMemFile; | 1264 | short int *psrc = (short int *)lpMemFile; |
1265 | short int *pSample = (short int *)pIns->pSample; | 1265 | short int *pSample = (short int *)pIns->pSample; |
1266 | if (len*4 > dwMemLength) break; | 1266 | if (len*4 > dwMemLength) break; |
1267 | for (UINT j=0; j<len; j++) | 1267 | for (UINT j=0; j<len; j++) |
1268 | { | 1268 | { |
1269 | pSample[j*2] = (short int) (bswapLE16(psrc[0]) + iadd_l); | 1269 | pSample[j*2] = (short int) (bswapLE16(psrc[0]) + iadd_l); |
1270 | pSample[j*2+1] = (short int) (bswapLE16(psrc[len]) + iadd_r); | 1270 | pSample[j*2+1] = (short int) (bswapLE16(psrc[len]) + iadd_r); |
1271 | psrc++; | 1271 | psrc++; |
1272 | if (nFlags == RS_STPCM16D) | 1272 | if (nFlags == RS_STPCM16D) |
1273 | { | 1273 | { |
1274 | iadd_l = pSample[j*2]; | 1274 | iadd_l = pSample[j*2]; |
1275 | iadd_r = pSample[j*2+1]; | 1275 | iadd_r = pSample[j*2+1]; |
1276 | } | 1276 | } |
1277 | } | 1277 | } |
1278 | len *= 4; | 1278 | len *= 4; |
1279 | } | 1279 | } |
1280 | break; | 1280 | break; |
1281 | 1281 | ||
1282 | // IT 2.14 compressed samples | 1282 | // IT 2.14 compressed samples |
1283 | case RS_IT2148: | 1283 | case RS_IT2148: |
1284 | case RS_IT21416: | 1284 | case RS_IT21416: |
1285 | case RS_IT2158: | 1285 | case RS_IT2158: |
1286 | case RS_IT21516: | 1286 | case RS_IT21516: |
1287 | len = dwMemLength; | 1287 | len = dwMemLength; |
1288 | if (len < 4) break; | 1288 | if (len < 4) break; |
1289 | if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158)) | 1289 | if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158)) |
1290 | ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158)); | 1290 | ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158)); |
1291 | else | 1291 | else |
1292 | ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516)); | 1292 | ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516)); |
1293 | break; | 1293 | break; |
1294 | 1294 | ||
1295 | #ifndef MODPLUG_BASIC_SUPPORT | 1295 | #ifndef MODPLUG_BASIC_SUPPORT |
1296 | #ifndef FASTSOUNDLIB | 1296 | #ifndef FASTSOUNDLIB |
1297 | // 8-bit interleaved stereo samples | 1297 | // 8-bit interleaved stereo samples |
1298 | case RS_STIPCM8S: | 1298 | case RS_STIPCM8S: |
1299 | case RS_STIPCM8U: | 1299 | case RS_STIPCM8U: |
1300 | { | 1300 | { |
1301 | int iadd = 0; | 1301 | int iadd = 0; |
1302 | if (nFlags == RS_STIPCM8U) { iadd = -0x80; } | 1302 | if (nFlags == RS_STIPCM8U) { iadd = -0x80; } |
1303 | len = pIns->nLength; | 1303 | len = pIns->nLength; |
1304 | if (len*2 > dwMemLength) len = dwMemLength >> 1; | 1304 | if (len*2 > dwMemLength) len = dwMemLength >> 1; |
1305 | LPBYTE psrc = (LPBYTE)lpMemFile; | 1305 | LPBYTE psrc = (LPBYTE)lpMemFile; |
1306 | LPBYTE pSample = (LPBYTE)pIns->pSample; | 1306 | LPBYTE pSample = (LPBYTE)pIns->pSample; |
1307 | for (UINT j=0; j<len; j++) | 1307 | for (UINT j=0; j<len; j++) |
1308 | { | 1308 | { |
1309 | pSample[j*2] = (signed char)(psrc[0] + iadd); | 1309 | pSample[j*2] = (signed char)(psrc[0] + iadd); |
1310 | pSample[j*2+1] = (signed char)(psrc[1] + iadd); | 1310 | pSample[j*2+1] = (signed char)(psrc[1] + iadd); |
1311 | psrc+=2; | 1311 | psrc+=2; |
1312 | } | 1312 | } |
1313 | len *= 2; | 1313 | len *= 2; |
1314 | } | 1314 | } |
1315 | break; | 1315 | break; |
1316 | 1316 | ||
1317 | // 16-bit interleaved stereo samples | 1317 | // 16-bit interleaved stereo samples |
1318 | case RS_STIPCM16S: | 1318 | case RS_STIPCM16S: |
1319 | case RS_STIPCM16U: | 1319 | case RS_STIPCM16U: |
1320 | { | 1320 | { |
1321 | int iadd = 0; | 1321 | int iadd = 0; |
1322 | if (nFlags == RS_STIPCM16U) iadd = -32768; | 1322 | if (nFlags == RS_STIPCM16U) iadd = -32768; |
1323 | len = pIns->nLength; | 1323 | len = pIns->nLength; |
1324 | if (len*4 > dwMemLength) len = dwMemLength >> 2; | 1324 | if (len*4 > dwMemLength) len = dwMemLength >> 2; |
1325 | short int *psrc = (short int *)lpMemFile; | 1325 | short int *psrc = (short int *)lpMemFile; |
1326 | short int *pSample = (short int *)pIns->pSample; | 1326 | short int *pSample = (short int *)pIns->pSample; |
1327 | for (UINT j=0; j<len; j++) | 1327 | for (UINT j=0; j<len; j++) |
1328 | { | 1328 | { |
1329 | pSample[j*2] = (short int)(bswapLE16(psrc[0]) + iadd); | 1329 | pSample[j*2] = (short int)(bswapLE16(psrc[0]) + iadd); |
1330 | pSample[j*2+1] = (short int)(bswapLE16(psrc[1]) + iadd); | 1330 | pSample[j*2+1] = (short int)(bswapLE16(psrc[1]) + iadd); |
1331 | psrc += 2; | 1331 | psrc += 2; |
1332 | } | 1332 | } |
1333 | len *= 4; | 1333 | len *= 4; |
1334 | } | 1334 | } |
1335 | break; | 1335 | break; |
1336 | 1336 | ||
1337 | // AMS compressed samples | 1337 | // AMS compressed samples |
1338 | case RS_AMS8: | 1338 | case RS_AMS8: |
1339 | case RS_AMS16: | 1339 | case RS_AMS16: |
1340 | len = 9; | 1340 | len = 9; |
1341 | if (dwMemLength > 9) | 1341 | if (dwMemLength > 9) |
1342 | { | 1342 | { |
1343 | const char *psrc = lpMemFile; | 1343 | const char *psrc = lpMemFile; |
1344 | char packcharacter = lpMemFile[8], *pdest = (char *)pIns->pSample; | 1344 | char packcharacter = lpMemFile[8], *pdest = (char *)pIns->pSample; |
1345 | len += bswapLE32(*((LPDWORD)(lpMemFile+4))); | 1345 | len += bswapLE32(*((LPDWORD)(lpMemFile+4))); |
1346 | if (len > dwMemLength) len = dwMemLength; | 1346 | if (len > dwMemLength) len = dwMemLength; |
1347 | UINT dmax = pIns->nLength; | 1347 | UINT dmax = pIns->nLength; |
1348 | if (pIns->uFlags & CHN_16BIT) dmax <<= 1; | 1348 | if (pIns->uFlags & CHN_16BIT) dmax <<= 1; |
1349 | AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter); | 1349 | AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter); |
1350 | } | 1350 | } |
1351 | break; | 1351 | break; |
1352 | 1352 | ||
1353 | // PTM 8bit delta to 16-bit sample | 1353 | // PTM 8bit delta to 16-bit sample |
1354 | case RS_PTM8DTO16: | 1354 | case RS_PTM8DTO16: |
1355 | { | 1355 | { |
1356 | len = pIns->nLength * 2; | 1356 | len = pIns->nLength * 2; |
1357 | if (len > dwMemLength) break; | 1357 | if (len > dwMemLength) break; |
1358 | signed char *pSample = (signed char *)pIns->pSample; | 1358 | signed char *pSample = (signed char *)pIns->pSample; |
1359 | signed char delta8 = 0; | 1359 | signed char delta8 = 0; |
1360 | for (UINT j=0; j<len; j++) | 1360 | for (UINT j=0; j<len; j++) |
1361 | { | 1361 | { |
1362 | delta8 += lpMemFile[j]; | 1362 | delta8 += lpMemFile[j]; |
1363 | *pSample++ = delta8; | 1363 | *pSample++ = delta8; |
1364 | } | 1364 | } |
1365 | WORD *pSampleW = (WORD *)pIns->pSample; | 1365 | WORD *pSampleW = (WORD *)pIns->pSample; |
1366 | for (UINT j=0; j<len; j+=2) // swaparoni! | 1366 | for (UINT j=0; j<len; j+=2) // swaparoni! |
1367 | { | 1367 | { |
1368 | *pSampleW++ = bswapLE16(*pSampleW); | 1368 | *pSampleW++ = bswapLE16(*pSampleW); |
1369 | } | 1369 | } |
1370 | } | 1370 | } |
1371 | break; | 1371 | break; |
1372 | 1372 | ||
1373 | // Huffman MDL compressed samples | 1373 | // Huffman MDL compressed samples |
1374 | case RS_MDL8: | 1374 | case RS_MDL8: |
1375 | case RS_MDL16: | 1375 | case RS_MDL16: |
1376 | len = dwMemLength; | 1376 | len = dwMemLength; |
1377 | if (len >= 4) | 1377 | if (len >= 4) |
1378 | { | 1378 | { |
1379 | LPBYTE pSample = (LPBYTE)pIns->pSample; | 1379 | LPBYTE pSample = (LPBYTE)pIns->pSample; |
1380 | LPBYTE ibuf = (LPBYTE)lpMemFile; | 1380 | LPBYTE ibuf = (LPBYTE)lpMemFile; |
1381 | DWORD bitbuf = bswapLE32(*((DWORD *)ibuf)); | 1381 | DWORD bitbuf = bswapLE32(*((DWORD *)ibuf)); |
1382 | UINT bitnum = 32; | 1382 | UINT bitnum = 32; |
1383 | BYTE dlt = 0, lowbyte = 0; | 1383 | BYTE dlt = 0, lowbyte = 0; |
1384 | ibuf += 4; | 1384 | ibuf += 4; |
1385 | for (UINT j=0; j<pIns->nLength; j++) | 1385 | for (UINT j=0; j<pIns->nLength; j++) |
1386 | { | 1386 | { |
1387 | BYTE hibyte; | 1387 | BYTE hibyte; |
1388 | BYTE sign; | 1388 | BYTE sign; |
1389 | if (nFlags == RS_MDL16) lowbyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 8); | 1389 | if (nFlags == RS_MDL16) lowbyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 8); |
1390 | sign = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 1); | 1390 | sign = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 1); |
1391 | if (MDLReadBits(bitbuf, bitnum, ibuf, 1)) | 1391 | if (MDLReadBits(bitbuf, bitnum, ibuf, 1)) |
1392 | { | 1392 | { |
1393 | hibyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 3); | 1393 | hibyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 3); |
1394 | } else | 1394 | } else |
1395 | { | 1395 | { |
1396 | hibyte = 8; | 1396 | hibyte = 8; |
1397 | while (!MDLReadBits(bitbuf, bitnum, ibuf, 1)) hibyte += 0x10; | 1397 | while (!MDLReadBits(bitbuf, bitnum, ibuf, 1)) hibyte += 0x10; |
1398 | hibyte += MDLReadBits(bitbuf, bitnum, ibuf, 4); | 1398 | hibyte += MDLReadBits(bitbuf, bitnum, ibuf, 4); |
1399 | } | 1399 | } |
1400 | if (sign) hibyte = ~hibyte; | 1400 | if (sign) hibyte = ~hibyte; |
1401 | dlt += hibyte; | 1401 | dlt += hibyte; |
1402 | if (nFlags != RS_MDL16) | 1402 | if (nFlags != RS_MDL16) |
1403 | pSample[j] = dlt; | 1403 | pSample[j] = dlt; |
1404 | else | 1404 | else |
1405 | { | 1405 | { |
1406 | pSample[j<<1] = lowbyte; | 1406 | pSample[j<<1] = lowbyte; |
1407 | pSample[(j<<1)+1] = dlt; | 1407 | pSample[(j<<1)+1] = dlt; |
1408 | } | 1408 | } |
1409 | } | 1409 | } |
1410 | } | 1410 | } |
1411 | break; | 1411 | break; |
1412 | 1412 | ||
1413 | case RS_DMF8: | 1413 | case RS_DMF8: |
1414 | case RS_DMF16: | 1414 | case RS_DMF16: |
1415 | len = dwMemLength; | 1415 | len = dwMemLength; |
1416 | if (len >= 4) | 1416 | if (len >= 4) |
1417 | { | 1417 | { |
1418 | UINT maxlen = pIns->nLength; | 1418 | UINT maxlen = pIns->nLength; |
1419 | if (pIns->uFlags & CHN_16BIT) maxlen <<= 1; | 1419 | if (pIns->uFlags & CHN_16BIT) maxlen <<= 1; |
1420 | LPBYTE ibuf = (LPBYTE)lpMemFile, ibufmax = (LPBYTE)(lpMemFile+dwMemLength); | 1420 | LPBYTE ibuf = (LPBYTE)lpMemFile, ibufmax = (LPBYTE)(lpMemFile+dwMemLength); |
1421 | len = DMFUnpack((LPBYTE)pIns->pSample, ibuf, ibufmax, maxlen); | 1421 | len = DMFUnpack((LPBYTE)pIns->pSample, ibuf, ibufmax, maxlen); |
1422 | } | 1422 | } |
1423 | break; | 1423 | break; |
1424 | 1424 | ||
1425 | #ifdef MODPLUG_TRACKER | 1425 | #ifdef MODPLUG_TRACKER |
1426 | // PCM 24-bit signed -> load sample, and normalize it to 16-bit | 1426 | // PCM 24-bit signed -> load sample, and normalize it to 16-bit |
1427 | case RS_PCM24S: | 1427 | case RS_PCM24S: |
1428 | case RS_PCM32S: | 1428 | case RS_PCM32S: |
1429 | len = pIns->nLength * 3; | 1429 | len = pIns->nLength * 3; |
1430 | if (nFlags == RS_PCM32S) len += pIns->nLength; | 1430 | if (nFlags == RS_PCM32S) len += pIns->nLength; |
1431 | if (len > dwMemLength) break; | 1431 | if (len > dwMemLength) break; |
1432 | if (len > 4*8) | 1432 | if (len > 4*8) |
1433 | { | 1433 | { |
1434 | UINT slsize = (nFlags == RS_PCM32S) ? 4 : 3; | 1434 | UINT slsize = (nFlags == RS_PCM32S) ? 4 : 3; |
1435 | LPBYTE pSrc = (LPBYTE)lpMemFile; | 1435 | LPBYTE pSrc = (LPBYTE)lpMemFile; |
1436 | LONG max = 255; | 1436 | LONG max = 255; |
1437 | if (nFlags == RS_PCM32S) pSrc++; | 1437 | if (nFlags == RS_PCM32S) pSrc++; |
1438 | for (UINT j=0; j<len; j+=slsize) | 1438 | for (UINT j=0; j<len; j+=slsize) |
1439 | { | 1439 | { |
1440 | LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8; | 1440 | LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8; |
1441 | l /= 256; | 1441 | l /= 256; |
1442 | if (l > max) max = l; | 1442 | if (l > max) max = l; |
1443 | if (-l > max) max = -l; | 1443 | if (-l > max) max = -l; |
1444 | } | 1444 | } |
1445 | max = (max / 128) + 1; | 1445 | max = (max / 128) + 1; |
1446 | signed short *pDest = (signed short *)pIns->pSample; | 1446 | signed short *pDest = (signed short *)pIns->pSample; |
1447 | for (UINT k=0; k<len; k+=slsize) | 1447 | for (UINT k=0; k<len; k+=slsize) |
1448 | { | 1448 | { |
1449 | LONG l = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8; | 1449 | LONG l = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8; |
1450 | *pDest++ = (signed short)(l / max); | 1450 | *pDest++ = (signed short)(l / max); |
1451 | } | 1451 | } |
1452 | } | 1452 | } |
1453 | break; | 1453 | break; |
1454 | 1454 | ||
1455 | // Stereo PCM 24-bit signed -> load sample, and normalize it to 16-bit | 1455 | // Stereo PCM 24-bit signed -> load sample, and normalize it to 16-bit |
1456 | case RS_STIPCM24S: | 1456 | case RS_STIPCM24S: |
1457 | case RS_STIPCM32S: | 1457 | case RS_STIPCM32S: |
1458 | len = pIns->nLength * 6; | 1458 | len = pIns->nLength * 6; |
1459 | if (nFlags == RS_STIPCM32S) len += pIns->nLength * 2; | 1459 | if (nFlags == RS_STIPCM32S) len += pIns->nLength * 2; |
1460 | if (len > dwMemLength) break; | 1460 | if (len > dwMemLength) break; |
1461 | if (len > 8*8) | 1461 | if (len > 8*8) |
1462 | { | 1462 | { |
1463 | UINT slsize = (nFlags == RS_STIPCM32S) ? 4 : 3; | 1463 | UINT slsize = (nFlags == RS_STIPCM32S) ? 4 : 3; |
1464 | LPBYTE pSrc = (LPBYTE)lpMemFile; | 1464 | LPBYTE pSrc = (LPBYTE)lpMemFile; |
1465 | LONG max = 255; | 1465 | LONG max = 255; |
1466 | if (nFlags == RS_STIPCM32S) pSrc++; | 1466 | if (nFlags == RS_STIPCM32S) pSrc++; |
1467 | for (UINT j=0; j<len; j+=slsize) | 1467 | for (UINT j=0; j<len; j+=slsize) |
1468 | { | 1468 | { |
1469 | LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8; | 1469 | LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8; |
1470 | l /= 256; | 1470 | l /= 256; |
1471 | if (l > max) max = l; | 1471 | if (l > max) max = l; |
1472 | if (-l > max) max = -l; | 1472 | if (-l > max) max = -l; |
1473 | } | 1473 | } |
1474 | max = (max / 128) + 1; | 1474 | max = (max / 128) + 1; |
1475 | signed short *pDest = (signed short *)pIns->pSample; | 1475 | signed short *pDest = (signed short *)pIns->pSample; |
1476 | for (UINT k=0; k<len; k+=slsize) | 1476 | for (UINT k=0; k<len; k+=slsize) |
1477 | { | 1477 | { |
1478 | LONG lr = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8; | 1478 | LONG lr = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8; |
1479 | k += slsize; | 1479 | k += slsize; |
1480 | LONG ll = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8; | 1480 | LONG ll = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8; |
1481 | pDest[0] = (signed short)ll; | 1481 | pDest[0] = (signed short)ll; |
1482 | pDest[1] = (signed short)lr; | 1482 | pDest[1] = (signed short)lr; |
1483 | pDest += 2; | 1483 | pDest += 2; |
1484 | } | 1484 | } |
1485 | } | 1485 | } |
1486 | break; | 1486 | break; |
1487 | 1487 | ||
1488 | // 16-bit signed big endian interleaved stereo | 1488 | // 16-bit signed big endian interleaved stereo |
1489 | case RS_STIPCM16M: | 1489 | case RS_STIPCM16M: |
1490 | { | 1490 | { |
1491 | len = pIns->nLength; | 1491 | len = pIns->nLength; |
1492 | if (len*4 > dwMemLength) len = dwMemLength >> 2; | 1492 | if (len*4 > dwMemLength) len = dwMemLength >> 2; |
1493 | LPCBYTE psrc = (LPCBYTE)lpMemFile; | 1493 | LPCBYTE psrc = (LPCBYTE)lpMemFile; |
1494 | short int *pSample = (short int *)pIns->pSample; | 1494 | short int *pSample = (short int *)pIns->pSample; |
1495 | for (UINT j=0; j<len; j++) | 1495 | for (UINT j=0; j<len; j++) |
1496 | { | 1496 | { |
1497 | pSample[j*2] = (signed short)(((UINT)psrc[0] << 8) | (psrc[1])); | 1497 | pSample[j*2] = (signed short)(((UINT)psrc[0] << 8) | (psrc[1])); |
1498 | pSample[j*2+1] = (signed short)(((UINT)psrc[2] << 8) | (psrc[3])); | 1498 | pSample[j*2+1] = (signed short)(((UINT)psrc[2] << 8) | (psrc[3])); |
1499 | psrc += 4; | 1499 | psrc += 4; |
1500 | } | 1500 | } |
1501 | len *= 4; | 1501 | len *= 4; |
1502 | } | 1502 | } |
1503 | break; | 1503 | break; |
1504 | 1504 | ||
1505 | #endif // MODPLUG_TRACKER | 1505 | #endif // MODPLUG_TRACKER |
1506 | #endif // !FASTSOUNDLIB | 1506 | #endif // !FASTSOUNDLIB |
1507 | #endif // !MODPLUG_BASIC_SUPPORT | 1507 | #endif // !MODPLUG_BASIC_SUPPORT |
1508 | 1508 | ||
1509 | // Default: 8-bit signed PCM data | 1509 | // Default: 8-bit signed PCM data |
1510 | default: | 1510 | default: |
1511 | len = pIns->nLength; | 1511 | len = pIns->nLength; |
1512 | if (len > dwMemLength) len = pIns->nLength = dwMemLength; | 1512 | if (len > dwMemLength) len = pIns->nLength = dwMemLength; |
1513 | memcpy(pIns->pSample, lpMemFile, len); | 1513 | memcpy(pIns->pSample, lpMemFile, len); |
1514 | } | 1514 | } |
1515 | if (len > dwMemLength) | 1515 | if (len > dwMemLength) |
1516 | { | 1516 | { |
1517 | if (pIns->pSample) | 1517 | if (pIns->pSample) |
1518 | { | 1518 | { |
1519 | pIns->nLength = 0; | 1519 | pIns->nLength = 0; |
1520 | FreeSample(pIns->pSample); | 1520 | FreeSample(pIns->pSample); |
1521 | pIns->pSample = NULL; | 1521 | pIns->pSample = NULL; |
1522 | } | 1522 | } |
1523 | return 0; | 1523 | return 0; |
1524 | } | 1524 | } |
1525 | AdjustSampleLoop(pIns); | 1525 | AdjustSampleLoop(pIns); |
1526 | return len; | 1526 | return len; |
1527 | } | 1527 | } |
1528 | 1528 | ||
1529 | 1529 | ||
1530 | void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns) | 1530 | void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns) |
1531 | //---------------------------------------------------- | 1531 | //---------------------------------------------------- |
1532 | { | 1532 | { |
1533 | if (!pIns->pSample) return; | 1533 | if (!pIns->pSample) return; |
1534 | if (pIns->nLoopEnd > pIns->nLength) pIns->nLoopEnd = pIns->nLength; | 1534 | if (pIns->nLoopEnd > pIns->nLength) pIns->nLoopEnd = pIns->nLength; |
1535 | if (pIns->nLoopStart+2 >= pIns->nLoopEnd) | 1535 | if (pIns->nLoopStart+2 >= pIns->nLoopEnd) |
1536 | { | 1536 | { |
1537 | pIns->nLoopStart = pIns->nLoopEnd = 0; | 1537 | pIns->nLoopStart = pIns->nLoopEnd = 0; |
1538 | pIns->uFlags &= ~CHN_LOOP; | 1538 | pIns->uFlags &= ~CHN_LOOP; |
1539 | } | 1539 | } |
1540 | UINT len = pIns->nLength; | 1540 | UINT len = pIns->nLength; |
1541 | if (pIns->uFlags & CHN_16BIT) | 1541 | if (pIns->uFlags & CHN_16BIT) |
1542 | { | 1542 | { |
1543 | short int *pSample = (short int *)pIns->pSample; | 1543 | short int *pSample = (short int *)pIns->pSample; |
1544 | // Adjust end of sample | 1544 | // Adjust end of sample |
1545 | if (pIns->uFlags & CHN_STEREO) | 1545 | if (pIns->uFlags & CHN_STEREO) |
1546 | { | 1546 | { |
1547 | pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; | 1547 | pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; |
1548 | pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; | 1548 | pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; |
1549 | } else | 1549 | } else |
1550 | { | 1550 | { |
1551 | pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; | 1551 | pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; |
1552 | } | 1552 | } |
1553 | if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) | 1553 | if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) |
1554 | { | 1554 | { |
1555 | // Fix bad loops | 1555 | // Fix bad loops |
1556 | if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M)) | 1556 | if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M)) |
1557 | { | 1557 | { |
1558 | pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart]; | 1558 | pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart]; |
1559 | pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1]; | 1559 | pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1]; |
1560 | pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2]; | 1560 | pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2]; |
1561 | pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3]; | 1561 | pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3]; |
1562 | pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4]; | 1562 | pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4]; |
1563 | } | 1563 | } |
1564 | } | 1564 | } |
1565 | } else | 1565 | } else |
1566 | { | 1566 | { |
1567 | signed char *pSample = pIns->pSample; | 1567 | signed char *pSample = pIns->pSample; |
1568 | #ifndef FASTSOUNDLIB | 1568 | #ifndef FASTSOUNDLIB |
1569 | // Crappy samples (except chiptunes) ? | 1569 | // Crappy samples (except chiptunes) ? |
1570 | if ((pIns->nLength > 0x100) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)) | 1570 | if ((pIns->nLength > 0x100) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)) |
1571 | && (!(pIns->uFlags & CHN_STEREO))) | 1571 | && (!(pIns->uFlags & CHN_STEREO))) |
1572 | { | 1572 | { |
1573 | int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan; | 1573 | int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan; |
1574 | for (kscan=pIns->nLength-1; kscan>0; kscan--) | 1574 | for (kscan=pIns->nLength-1; kscan>0; kscan--) |
1575 | { | 1575 | { |
1576 | smpfix = pSample[kscan-1]; | 1576 | smpfix = pSample[kscan-1]; |
1577 | if (smpfix != smpend) break; | 1577 | if (smpfix != smpend) break; |
1578 | } | 1578 | } |
1579 | int delta = smpfix - smpend; | 1579 | int delta = smpfix - smpend; |
1580 | if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd)) | 1580 | if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd)) |
1581 | && ((delta < -8) || (delta > 8))) | 1581 | && ((delta < -8) || (delta > 8))) |
1582 | { | 1582 | { |
1583 | while (kscan<(int)pIns->nLength) | 1583 | while (kscan<(int)pIns->nLength) |
1584 | { | 1584 | { |
1585 | if (!(kscan & 7)) | 1585 | if (!(kscan & 7)) |
1586 | { | 1586 | { |
1587 | if (smpfix > 0) smpfix--; | 1587 | if (smpfix > 0) smpfix--; |
1588 | if (smpfix < 0) smpfix++; | 1588 | if (smpfix < 0) smpfix++; |
1589 | } | 1589 | } |
1590 | pSample[kscan] = (signed char)smpfix; | 1590 | pSample[kscan] = (signed char)smpfix; |
1591 | kscan++; | 1591 | kscan++; |
1592 | } | 1592 | } |
1593 | } | 1593 | } |
1594 | } | 1594 | } |
1595 | #endif | 1595 | #endif |
1596 | // Adjust end of sample | 1596 | // Adjust end of sample |
1597 | if (pIns->uFlags & CHN_STEREO) | 1597 | if (pIns->uFlags & CHN_STEREO) |
1598 | { | 1598 | { |
1599 | pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; | 1599 | pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; |
1600 | pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; | 1600 | pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; |
1601 | } else | 1601 | } else |
1602 | { | 1602 | { |
1603 | pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; | 1603 | pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; |
1604 | } | 1604 | } |
1605 | if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) | 1605 | if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) |
1606 | { | 1606 | { |
1607 | if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))) | 1607 | if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))) |
1608 | { | 1608 | { |
1609 | pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart]; | 1609 | pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart]; |
1610 | pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1]; | 1610 | pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1]; |
1611 | pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2]; | 1611 | pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2]; |
1612 | pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3]; | 1612 | pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3]; |
1613 | pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4]; | 1613 | pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4]; |
1614 | } | 1614 | } |
1615 | } | 1615 | } |
1616 | } | 1616 | } |
1617 | } | 1617 | } |
1618 | 1618 | ||
1619 | 1619 | ||
1620 | ///////////////////////////////////////////////////////////// | 1620 | ///////////////////////////////////////////////////////////// |
1621 | // Transpose <-> Frequency conversions | 1621 | // Transpose <-> Frequency conversions |
1622 | 1622 | ||
1623 | // returns 8363*2^((transp*128+ftune)/(12*128)) | 1623 | // returns 8363*2^((transp*128+ftune)/(12*128)) |
1624 | DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) | 1624 | DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) |
1625 | //----------------------------------------------------------- | 1625 | //----------------------------------------------------------- |
1626 | { | 1626 | { |
1627 | //---GCCFIX: Removed assembly. | 1627 | //---GCCFIX: Removed assembly. |
1628 | return (DWORD)(8363*pow(2, (transp*128+ftune)/(1536))); | 1628 | return (DWORD)(8363*pow(2, (transp*128+ftune)/(1536))); |
1629 | 1629 | ||
1630 | #ifdef WIN32 | 1630 | #ifdef WIN32 |
1631 | const float _fbase = 8363; | 1631 | const float _fbase = 8363; |
1632 | const float _factor = 1.0f/(12.0f*128.0f); | 1632 | const float _factor = 1.0f/(12.0f*128.0f); |
1633 | int result; | 1633 | int result; |
1634 | DWORD freq; | 1634 | DWORD freq; |
1635 | 1635 | ||
1636 | transp = (transp << 7) + ftune; | 1636 | transp = (transp << 7) + ftune; |
1637 | _asm { | 1637 | _asm { |
1638 | fild transp | 1638 | fild transp |
1639 | fld _factor | 1639 | fld _factor |
1640 | fmulp st(1), st(0) | 1640 | fmulp st(1), st(0) |
1641 | fist result | 1641 | fist result |
1642 | fisub result | 1642 | fisub result |
1643 | f2xm1 | 1643 | f2xm1 |
1644 | fild result | 1644 | fild result |
1645 | fld _fbase | 1645 | fld _fbase |
1646 | fscale | 1646 | fscale |
1647 | fstp st(1) | 1647 | fstp st(1) |
1648 | fmul st(1), st(0) | 1648 | fmul st(1), st(0) |
1649 | faddp st(1), st(0) | 1649 | faddp st(1), st(0) |
1650 | fistp freq | 1650 | fistp freq |
1651 | } | 1651 | } |
1652 | UINT derr = freq % 11025; | 1652 | UINT derr = freq % 11025; |
1653 | if (derr <= 8) freq -= derr; | 1653 | if (derr <= 8) freq -= derr; |
1654 | if (derr >= 11015) freq += 11025-derr; | 1654 | if (derr >= 11015) freq += 11025-derr; |
1655 | derr = freq % 1000; | 1655 | derr = freq % 1000; |
1656 | if (derr <= 5) freq -= derr; | 1656 | if (derr <= 5) freq -= derr; |
1657 | if (derr >= 995) freq += 1000-derr; | 1657 | if (derr >= 995) freq += 1000-derr; |
1658 | return freq; | 1658 | return freq; |
1659 | #endif | 1659 | #endif |
1660 | } | 1660 | } |
1661 | 1661 | ||
1662 | 1662 | ||
1663 | // returns 12*128*log2(freq/8363) | 1663 | // returns 12*128*log2(freq/8363) |
1664 | int CSoundFile::FrequencyToTranspose(DWORD freq) | 1664 | int CSoundFile::FrequencyToTranspose(DWORD freq) |
1665 | //---------------------------------------------- | 1665 | //---------------------------------------------- |
1666 | { | 1666 | { |
1667 | //---GCCFIX: Removed assembly. | 1667 | //---GCCFIX: Removed assembly. |
1668 | return int(1536*(log(freq/8363)/log(2))); | 1668 | return int(1536*(log(freq/8363)/log(2))); |
1669 | 1669 | ||
1670 | #ifdef WIN32 | 1670 | #ifdef WIN32 |
1671 | const float _f1_8363 = 1.0f / 8363.0f; | 1671 | const float _f1_8363 = 1.0f / 8363.0f; |
1672 | const float _factor = 128 * 12; | 1672 | const float _factor = 128 * 12; |
1673 | LONG result; | 1673 | LONG result; |
1674 | 1674 | ||
1675 | if (!freq) return 0; | 1675 | if (!freq) return 0; |
1676 | _asm { | 1676 | _asm { |
1677 | fld _factor | 1677 | fld _factor |
1678 | fild freq | 1678 | fild freq |
1679 | fld _f1_8363 | 1679 | fld _f1_8363 |
1680 | fmulp st(1), st(0) | 1680 | fmulp st(1), st(0) |
1681 | fyl2x | 1681 | fyl2x |
1682 | fistp result | 1682 | fistp result |
1683 | } | 1683 | } |
1684 | return result; | 1684 | return result; |
1685 | #endif | 1685 | #endif |
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | 1688 | ||
1689 | void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) | 1689 | void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) |
1690 | //-------------------------------------------------------- | 1690 | //-------------------------------------------------------- |
1691 | { | 1691 | { |
1692 | int f2t = FrequencyToTranspose(psmp->nC4Speed); | 1692 | int f2t = FrequencyToTranspose(psmp->nC4Speed); |
1693 | int transp = f2t >> 7; | 1693 | int transp = f2t >> 7; |
1694 | int ftune = f2t & 0x7F; | 1694 | int ftune = f2t & 0x7F; |
1695 | if (ftune > 80) | 1695 | if (ftune > 80) |
1696 | { | 1696 | { |
1697 | transp++; | 1697 | transp++; |
1698 | ftune -= 128; | 1698 | ftune -= 128; |
1699 | } | 1699 | } |
1700 | if (transp > 127) transp = 127; | 1700 | if (transp > 127) transp = 127; |
1701 | if (transp < -127) transp = -127; | 1701 | if (transp < -127) transp = -127; |
1702 | psmp->RelativeTone = transp; | 1702 | psmp->RelativeTone = transp; |
1703 | psmp->nFineTune = ftune; | 1703 | psmp->nFineTune = ftune; |
1704 | } | 1704 | } |
1705 | 1705 | ||
1706 | 1706 | ||
1707 | void CSoundFile::CheckCPUUsage(UINT nCPU) | 1707 | void CSoundFile::CheckCPUUsage(UINT nCPU) |
1708 | //--------------------------------------- | 1708 | //--------------------------------------- |
1709 | { | 1709 | { |
1710 | if (nCPU > 100) nCPU = 100; | 1710 | if (nCPU > 100) nCPU = 100; |
1711 | gnCPUUsage = nCPU; | 1711 | gnCPUUsage = nCPU; |
1712 | if (nCPU < 90) | 1712 | if (nCPU < 90) |
1713 | { | 1713 | { |
1714 | m_dwSongFlags &= ~SONG_CPUVERYHIGH; | 1714 | m_dwSongFlags &= ~SONG_CPUVERYHIGH; |
1715 | } else | 1715 | } else |
1716 | if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94)) | 1716 | if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94)) |
1717 | { | 1717 | { |
1718 | UINT i=MAX_CHANNELS; | 1718 | UINT i=MAX_CHANNELS; |
1719 | while (i >= 8) | 1719 | while (i >= 8) |
1720 | { | 1720 | { |
1721 | i--; | 1721 | i--; |
1722 | if (Chn[i].nLength) | 1722 | if (Chn[i].nLength) |
1723 | { | 1723 | { |
1724 | Chn[i].nLength = Chn[i].nPos = 0; | 1724 | Chn[i].nLength = Chn[i].nPos = 0; |
1725 | nCPU -= 2; | 1725 | nCPU -= 2; |
1726 | if (nCPU < 94) break; | 1726 | if (nCPU < 94) break; |
1727 | } | 1727 | } |
1728 | } | 1728 | } |
1729 | } else | 1729 | } else |
1730 | if (nCPU > 90) | 1730 | if (nCPU > 90) |
1731 | { | 1731 | { |
1732 | m_dwSongFlags |= SONG_CPUVERYHIGH; | 1732 | m_dwSongFlags |= SONG_CPUVERYHIGH; |
1733 | } | 1733 | } |
1734 | } | 1734 | } |
1735 | 1735 | ||
1736 | 1736 | ||
1737 | BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName) | 1737 | BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName) |
1738 | //--------------------------------------------------------- | 1738 | //--------------------------------------------------------- |
1739 | { | 1739 | { |
1740 | char szName[MAX_PATTERNNAME] = ""; // changed from CHAR | 1740 | char szName[MAX_PATTERNNAME] = ""; // changed from CHAR |
1741 | if (nPat >= MAX_PATTERNS) return FALSE; | 1741 | if (nPat >= MAX_PATTERNS) return FALSE; |
1742 | if (lpszName) lstrcpyn(szName, lpszName, MAX_PATTERNNAME); | 1742 | if (lpszName) |
1743 | lstrcpyn(szName, lpszName, MAX_PATTERNNAME); | ||
1744 | else | ||
1745 | return FALSE; | ||
1743 | szName[MAX_PATTERNNAME-1] = 0; | 1746 | szName[MAX_PATTERNNAME-1] = 0; |
1744 | if (!m_lpszPatternNames) m_nPatternNames = 0; | 1747 | if (!m_lpszPatternNames) m_nPatternNames = 0; |
1745 | if (nPat >= m_nPatternNames) | 1748 | if (nPat >= m_nPatternNames) |
1746 | { | 1749 | { |
1747 | if (!lpszName[0]) return TRUE; | 1750 | if (!lpszName[0]) return TRUE; |
1748 | UINT len = (nPat+1)*MAX_PATTERNNAME; | 1751 | UINT len = (nPat+1)*MAX_PATTERNNAME; |
1749 | char *p = new char[len]; // changed from CHAR | 1752 | char *p = new char[len]; // changed from CHAR |
1750 | if (!p) return FALSE; | 1753 | if (!p) return FALSE; |
1751 | memset(p, 0, len); | 1754 | memset(p, 0, len); |
1752 | if (m_lpszPatternNames) | 1755 | if (m_lpszPatternNames) |
1753 | { | 1756 | { |
1754 | memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME); | 1757 | memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME); |
1755 | delete m_lpszPatternNames; | 1758 | delete m_lpszPatternNames; |
1756 | m_lpszPatternNames = NULL; | 1759 | m_lpszPatternNames = NULL; |
1757 | } | 1760 | } |
1758 | m_lpszPatternNames = p; | 1761 | m_lpszPatternNames = p; |
1759 | m_nPatternNames = nPat + 1; | 1762 | m_nPatternNames = nPat + 1; |
1760 | } | 1763 | } |
1761 | memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME); | 1764 | memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME); |
1762 | return TRUE; | 1765 | return TRUE; |
1763 | } | 1766 | } |
1764 | 1767 | ||
1765 | 1768 | ||
1766 | BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const | 1769 | BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const |
1767 | //--------------------------------------------------------------------------- | 1770 | //--------------------------------------------------------------------------- |
1768 | { | 1771 | { |
1769 | if ((!lpszName) || (!cbSize)) return FALSE; | 1772 | if ((!lpszName) || (!cbSize)) return FALSE; |
1770 | lpszName[0] = 0; | 1773 | lpszName[0] = 0; |
1771 | if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME; | 1774 | if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME; |
1772 | if ((m_lpszPatternNames) && (nPat < m_nPatternNames)) | 1775 | if ((m_lpszPatternNames) && (nPat < m_nPatternNames)) |
1773 | { | 1776 | { |
1774 | memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize); | 1777 | memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize); |
1775 | lpszName[cbSize-1] = 0; | 1778 | lpszName[cbSize-1] = 0; |
1776 | return TRUE; | 1779 | return TRUE; |
1777 | } | 1780 | } |
1778 | return FALSE; | 1781 | return FALSE; |
1779 | } | 1782 | } |
1780 | 1783 | ||
1781 | 1784 | ||
1782 | #ifndef FASTSOUNDLIB | 1785 | #ifndef FASTSOUNDLIB |
1783 | 1786 | ||
1784 | UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns) | 1787 | UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns) |
1785 | //----------------------------------------------- | 1788 | //----------------------------------------------- |
1786 | { | 1789 | { |
1787 | UINT nExt = 0; | 1790 | UINT nExt = 0; |
1788 | 1791 | ||
1789 | if (!pbIns) return 0; | 1792 | if (!pbIns) return 0; |
1790 | if (m_nInstruments) | 1793 | if (m_nInstruments) |
1791 | { | 1794 | { |
1792 | memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL)); | 1795 | memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL)); |
1793 | for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) | 1796 | for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) |
1794 | { | 1797 | { |
1795 | MODCOMMAND *p = Patterns[ipat]; | 1798 | MODCOMMAND *p = Patterns[ipat]; |
1796 | if (p) | 1799 | if (p) |
1797 | { | 1800 | { |
1798 | UINT jmax = PatternSize[ipat] * m_nChannels; | 1801 | UINT jmax = PatternSize[ipat] * m_nChannels; |
1799 | for (UINT j=0; j<jmax; j++, p++) | 1802 | for (UINT j=0; j<jmax; j++, p++) |
1800 | { | 1803 | { |
1801 | if ((p->note) && (p->note <= 120)) | 1804 | if ((p->note) && (p->note <= 120)) |
1802 | { | 1805 | { |
1803 | if ((p->instr) && (p->instr < MAX_INSTRUMENTS)) | 1806 | if ((p->instr) && (p->instr < MAX_INSTRUMENTS)) |
1804 | { | 1807 | { |
1805 | INSTRUMENTHEADER *penv = Headers[p->instr]; | 1808 | INSTRUMENTHEADER *penv = Headers[p->instr]; |
1806 | if (penv) | 1809 | if (penv) |
1807 | { | 1810 | { |
1808 | UINT n = penv->Keyboard[p->note-1]; | 1811 | UINT n = penv->Keyboard[p->note-1]; |
1809 | if (n < MAX_SAMPLES) pbIns[n] = TRUE; | 1812 | if (n < MAX_SAMPLES) pbIns[n] = TRUE; |
1810 | } | 1813 | } |
1811 | } else | 1814 | } else |
1812 | { | 1815 | { |
1813 | for (UINT k=1; k<=m_nInstruments; k++) | 1816 | for (UINT k=1; k<=m_nInstruments; k++) |
1814 | { | 1817 | { |
1815 | INSTRUMENTHEADER *penv = Headers[k]; | 1818 | INSTRUMENTHEADER *penv = Headers[k]; |
1816 | if (penv) | 1819 | if (penv) |
1817 | { | 1820 | { |
1818 | UINT n = penv->Keyboard[p->note-1]; | 1821 | UINT n = penv->Keyboard[p->note-1]; |
1819 | if (n < MAX_SAMPLES) pbIns[n] = TRUE; | 1822 | if (n < MAX_SAMPLES) pbIns[n] = TRUE; |
1820 | } | 1823 | } |
1821 | } | 1824 | } |
1822 | } | 1825 | } |
1823 | } | 1826 | } |
1824 | } | 1827 | } |
1825 | } | 1828 | } |
1826 | } | 1829 | } |
1827 | for (UINT ichk=1; ichk<=m_nSamples; ichk++) | 1830 | for (UINT ichk=1; ichk<=m_nSamples; ichk++) |
1828 | { | 1831 | { |
1829 | if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++; | 1832 | if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++; |
1830 | } | 1833 | } |
1831 | } | 1834 | } |
1832 | return nExt; | 1835 | return nExt; |
1833 | } | 1836 | } |
1834 | 1837 | ||
1835 | 1838 | ||
1836 | BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns) | 1839 | BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns) |
1837 | //------------------------------------------------- | 1840 | //------------------------------------------------- |
1838 | { | 1841 | { |
1839 | if (!pbIns) return FALSE; | 1842 | if (!pbIns) return FALSE; |
1840 | for (UINT j=1; j<MAX_SAMPLES; j++) | 1843 | for (UINT j=1; j<MAX_SAMPLES; j++) |
1841 | { | 1844 | { |
1842 | if ((!pbIns[j]) && (Ins[j].pSample)) | 1845 | if ((!pbIns[j]) && (Ins[j].pSample)) |
1843 | { | 1846 | { |
1844 | DestroySample(j); | 1847 | DestroySample(j); |
1845 | if ((j == m_nSamples) && (j > 1)) m_nSamples--; | 1848 | if ((j == m_nSamples) && (j > 1)) m_nSamples--; |
1846 | } | 1849 | } |
1847 | } | 1850 | } |
1848 | return TRUE; | 1851 | return TRUE; |
1849 | } | 1852 | } |
1850 | 1853 | ||
1851 | 1854 | ||
1852 | BOOL CSoundFile::DestroySample(UINT nSample) | 1855 | BOOL CSoundFile::DestroySample(UINT nSample) |
1853 | //------------------------------------------ | 1856 | //------------------------------------------ |
1854 | { | 1857 | { |
1855 | if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE; | 1858 | if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE; |
1856 | if (!Ins[nSample].pSample) return TRUE; | 1859 | if (!Ins[nSample].pSample) return TRUE; |
1857 | MODINSTRUMENT *pins = &Ins[nSample]; | 1860 | MODINSTRUMENT *pins = &Ins[nSample]; |
1858 | signed char *pSample = pins->pSample; | 1861 | signed char *pSample = pins->pSample; |
1859 | pins->pSample = NULL; | 1862 | pins->pSample = NULL; |
1860 | pins->nLength = 0; | 1863 | pins->nLength = 0; |
1861 | pins->uFlags &= ~(CHN_16BIT); | 1864 | pins->uFlags &= ~(CHN_16BIT); |
1862 | for (UINT i=0; i<MAX_CHANNELS; i++) | 1865 | for (UINT i=0; i<MAX_CHANNELS; i++) |
1863 | { | 1866 | { |
1864 | if (Chn[i].pSample == pSample) | 1867 | if (Chn[i].pSample == pSample) |
1865 | { | 1868 | { |
1866 | Chn[i].nPos = Chn[i].nLength = 0; | 1869 | Chn[i].nPos = Chn[i].nLength = 0; |
1867 | Chn[i].pSample = Chn[i].pCurrentSample = NULL; | 1870 | Chn[i].pSample = Chn[i].pCurrentSample = NULL; |
1868 | } | 1871 | } |
1869 | } | 1872 | } |
1870 | FreeSample(pSample); | 1873 | FreeSample(pSample); |
1871 | return TRUE; | 1874 | return TRUE; |
1872 | } | 1875 | } |
1873 | 1876 | ||
1874 | #endif // FASTSOUNDLIB | 1877 | #endif // FASTSOUNDLIB |
1875 | 1878 | ||
diff --git a/core/multimedia/opieplayer/vorbis/tremor/block.c b/core/multimedia/opieplayer/vorbis/tremor/block.c index 8949253..7b5531b 100644 --- a/core/multimedia/opieplayer/vorbis/tremor/block.c +++ b/core/multimedia/opieplayer/vorbis/tremor/block.c | |||
@@ -1,453 +1,455 @@ | |||
1 | /******************************************************************** | 1 | /******************************************************************** |
2 | * * | 2 | * * |
3 | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * | 3 | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * |
4 | * * | 4 | * * |
5 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | 5 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
6 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | 6 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
7 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | 7 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
8 | * * | 8 | * * |
9 | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * | 9 | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
10 | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * | 10 | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * |
11 | * * | 11 | * * |
12 | ******************************************************************** | 12 | ******************************************************************** |
13 | 13 | ||
14 | function: PCM data vector blocking, windowing and dis/reassembly | 14 | function: PCM data vector blocking, windowing and dis/reassembly |
15 | 15 | ||
16 | ********************************************************************/ | 16 | ********************************************************************/ |
17 | 17 | ||
18 | #include <stdio.h> | 18 | #include <stdio.h> |
19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
20 | #include <string.h> | 20 | #include <string.h> |
21 | #include "ogg.h" | 21 | #include "ogg.h" |
22 | #include "ivorbiscodec.h" | 22 | #include "ivorbiscodec.h" |
23 | #include "codec_internal.h" | 23 | #include "codec_internal.h" |
24 | 24 | ||
25 | #include "window.h" | 25 | #include "window.h" |
26 | #include "registry.h" | 26 | #include "registry.h" |
27 | #include "misc.h" | 27 | #include "misc.h" |
28 | 28 | ||
29 | static int ilog(unsigned int v){ | 29 | static int ilog(unsigned int v){ |
30 | int ret=0; | 30 | int ret=0; |
31 | if(v)--v; | 31 | if(v)--v; |
32 | while(v){ | 32 | while(v){ |
33 | ret++; | 33 | ret++; |
34 | v>>=1; | 34 | v>>=1; |
35 | } | 35 | } |
36 | return(ret); | 36 | return(ret); |
37 | } | 37 | } |
38 | 38 | ||
39 | /* pcm accumulator examples (not exhaustive): | 39 | /* pcm accumulator examples (not exhaustive): |
40 | 40 | ||
41 | <-------------- lW ----------------> | 41 | <-------------- lW ----------------> |
42 | <--------------- W ----------------> | 42 | <--------------- W ----------------> |
43 | : .....|..... _______________ | | 43 | : .....|..... _______________ | |
44 | : .''' | '''_--- | |\ | | 44 | : .''' | '''_--- | |\ | |
45 | :.....''' |_____--- '''......| | \_______| | 45 | :.....''' |_____--- '''......| | \_______| |
46 | :.................|__________________|_______|__|______| | 46 | :.................|__________________|_______|__|______| |
47 | |<------ Sl ------>| > Sr < |endW | 47 | |<------ Sl ------>| > Sr < |endW |
48 | |beginSl |endSl | |endSr | 48 | |beginSl |endSl | |endSr |
49 | |beginW |endlW |beginSr | 49 | |beginW |endlW |beginSr |
50 | 50 | ||
51 | 51 | ||
52 | |< lW >| | 52 | |< lW >| |
53 | <--------------- W ----------------> | 53 | <--------------- W ----------------> |
54 | | | .. ______________ | | 54 | | | .. ______________ | |
55 | | | ' `/ | ---_ | | 55 | | | ' `/ | ---_ | |
56 | |___.'___/`. | ---_____| | 56 | |___.'___/`. | ---_____| |
57 | |_______|__|_______|_________________| | 57 | |_______|__|_______|_________________| |
58 | | >|Sl|< |<------ Sr ----->|endW | 58 | | >|Sl|< |<------ Sr ----->|endW |
59 | | | |endSl |beginSr |endSr | 59 | | | |endSl |beginSr |endSr |
60 | |beginW | |endlW | 60 | |beginW | |endlW |
61 | mult[0] |beginSl mult[n] | 61 | mult[0] |beginSl mult[n] |
62 | 62 | ||
63 | <-------------- lW -----------------> | 63 | <-------------- lW -----------------> |
64 | |<--W-->| | 64 | |<--W-->| |
65 | : .............. ___ | | | 65 | : .............. ___ | | |
66 | : .''' |`/ \ | | | 66 | : .''' |`/ \ | | |
67 | :.....''' |/`....\|...| | 67 | :.....''' |/`....\|...| |
68 | :.........................|___|___|___| | 68 | :.........................|___|___|___| |
69 | |Sl |Sr |endW | 69 | |Sl |Sr |endW |
70 | | | |endSr | 70 | | | |endSr |
71 | | |beginSr | 71 | | |beginSr |
72 | | |endSl | 72 | | |endSl |
73 | |beginSl | 73 | |beginSl |
74 | |beginW | 74 | |beginW |
75 | */ | 75 | */ |
76 | 76 | ||
77 | /* block abstraction setup *********************************************/ | 77 | /* block abstraction setup *********************************************/ |
78 | 78 | ||
79 | #ifndef WORD_ALIGN | 79 | #ifndef WORD_ALIGN |
80 | #define WORD_ALIGN 8 | 80 | #define WORD_ALIGN 8 |
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ | 83 | int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){ |
84 | memset(vb,0,sizeof(*vb)); | 84 | memset(vb,0,sizeof(*vb)); |
85 | vb->vd=v; | 85 | vb->vd=v; |
86 | vb->localalloc=0; | 86 | vb->localalloc=0; |
87 | vb->localstore=NULL; | 87 | vb->localstore=NULL; |
88 | 88 | ||
89 | return(0); | 89 | return(0); |
90 | } | 90 | } |
91 | 91 | ||
92 | void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ | 92 | void *_vorbis_block_alloc(vorbis_block *vb,long bytes){ |
93 | bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); | 93 | bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1); |
94 | if(bytes+vb->localtop>vb->localalloc){ | 94 | if(bytes+vb->localtop>vb->localalloc){ |
95 | /* can't just _ogg_realloc... there are outstanding pointers */ | 95 | /* can't just _ogg_realloc... there are outstanding pointers */ |
96 | if(vb->localstore){ | 96 | if(vb->localstore){ |
97 | struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link)); | 97 | struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link)); |
98 | vb->totaluse+=vb->localtop; | 98 | vb->totaluse+=vb->localtop; |
99 | link->next=vb->reap; | 99 | link->next=vb->reap; |
100 | link->ptr=vb->localstore; | 100 | link->ptr=vb->localstore; |
101 | vb->reap=link; | 101 | vb->reap=link; |
102 | } | 102 | } |
103 | /* highly conservative */ | 103 | /* highly conservative */ |
104 | vb->localalloc=bytes; | 104 | vb->localalloc=bytes; |
105 | vb->localstore=_ogg_malloc(vb->localalloc); | 105 | vb->localstore=_ogg_malloc(vb->localalloc); |
106 | vb->localtop=0; | 106 | vb->localtop=0; |
107 | } | 107 | } |
108 | { | 108 | { |
109 | void *ret=(void *)(((char *)vb->localstore)+vb->localtop); | 109 | void *ret=(void *)(((char *)vb->localstore)+vb->localtop); |
110 | vb->localtop+=bytes; | 110 | vb->localtop+=bytes; |
111 | return ret; | 111 | return ret; |
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | /* reap the chain, pull the ripcord */ | 115 | /* reap the chain, pull the ripcord */ |
116 | void _vorbis_block_ripcord(vorbis_block *vb){ | 116 | void _vorbis_block_ripcord(vorbis_block *vb){ |
117 | /* reap the chain */ | 117 | /* reap the chain */ |
118 | struct alloc_chain *reap=vb->reap; | 118 | struct alloc_chain *reap=vb->reap; |
119 | while(reap){ | 119 | while(reap){ |
120 | struct alloc_chain *next=reap->next; | 120 | struct alloc_chain *next=reap->next; |
121 | _ogg_free(reap->ptr); | 121 | _ogg_free(reap->ptr); |
122 | memset(reap,0,sizeof(*reap)); | 122 | memset(reap,0,sizeof(*reap)); |
123 | _ogg_free(reap); | 123 | _ogg_free(reap); |
124 | reap=next; | 124 | reap=next; |
125 | } | 125 | } |
126 | /* consolidate storage */ | 126 | /* consolidate storage */ |
127 | if(vb->totaluse){ | 127 | if(vb->totaluse){ |
128 | vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); | 128 | vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc); |
129 | vb->localalloc+=vb->totaluse; | 129 | vb->localalloc+=vb->totaluse; |
130 | vb->totaluse=0; | 130 | vb->totaluse=0; |
131 | } | 131 | } |
132 | 132 | ||
133 | /* pull the ripcord */ | 133 | /* pull the ripcord */ |
134 | vb->localtop=0; | 134 | vb->localtop=0; |
135 | vb->reap=NULL; | 135 | vb->reap=NULL; |
136 | } | 136 | } |
137 | 137 | ||
138 | int vorbis_block_clear(vorbis_block *vb){ | 138 | int vorbis_block_clear(vorbis_block *vb){ |
139 | _vorbis_block_ripcord(vb); | 139 | _vorbis_block_ripcord(vb); |
140 | if(vb->localstore)_ogg_free(vb->localstore); | 140 | if(vb->localstore)_ogg_free(vb->localstore); |
141 | 141 | ||
142 | memset(vb,0,sizeof(*vb)); | 142 | memset(vb,0,sizeof(*vb)); |
143 | return(0); | 143 | return(0); |
144 | } | 144 | } |
145 | 145 | ||
146 | static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ | 146 | static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){ |
147 | int i; | 147 | int i; |
148 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | 148 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; |
149 | private_state *b=NULL; | 149 | private_state *b=NULL; |
150 | 150 | ||
151 | memset(v,0,sizeof(*v)); | 151 | memset(v,0,sizeof(*v)); |
152 | b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b))); | 152 | b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b))); |
153 | 153 | ||
154 | v->vi=vi; | 154 | v->vi=vi; |
155 | b->modebits=ilog(ci->modes); | 155 | b->modebits=ilog(ci->modes); |
156 | 156 | ||
157 | /* Vorbis I uses only window type 0 */ | 157 | /* Vorbis I uses only window type 0 */ |
158 | b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2); | 158 | b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2); |
159 | b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2); | 159 | b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2); |
160 | 160 | ||
161 | /* finish the codebooks */ | 161 | /* finish the codebooks */ |
162 | if(!ci->fullbooks){ | 162 | if(!ci->fullbooks){ |
163 | ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); | 163 | ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); |
164 | for(i=0;i<ci->books;i++){ | 164 | for(i=0;i<ci->books;i++){ |
165 | vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); | 165 | vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); |
166 | /* decode codebooks are now standalone after init */ | 166 | /* decode codebooks are now standalone after init */ |
167 | vorbis_staticbook_destroy(ci->book_param[i]); | 167 | vorbis_staticbook_destroy(ci->book_param[i]); |
168 | ci->book_param[i]=NULL; | 168 | ci->book_param[i]=NULL; |
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | v->pcm_storage=ci->blocksizes[1]; | 172 | v->pcm_storage=ci->blocksizes[1]; |
173 | v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm)); | 173 | v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm)); |
174 | v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret)); | 174 | v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret)); |
175 | for(i=0;i<vi->channels;i++) | 175 | for(i=0;i<vi->channels;i++) |
176 | v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); | 176 | v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); |
177 | 177 | ||
178 | /* all 1 (large block) or 0 (small block) */ | 178 | /* all 1 (large block) or 0 (small block) */ |
179 | /* explicitly set for the sake of clarity */ | 179 | /* explicitly set for the sake of clarity */ |
180 | v->lW=0; /* previous window size */ | 180 | v->lW=0; /* previous window size */ |
181 | v->W=0; /* current window size */ | 181 | v->W=0; /* current window size */ |
182 | 182 | ||
183 | /* initialize all the mapping/backend lookups */ | 183 | /* initialize all the mapping/backend lookups */ |
184 | b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode)); | 184 | b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode)); |
185 | for(i=0;i<ci->modes;i++){ | 185 | for(i=0;i<ci->modes;i++){ |
186 | int mapnum=ci->mode_param[i]->mapping; | 186 | int mapnum=ci->mode_param[i]->mapping; |
187 | int maptype=ci->map_type[mapnum]; | 187 | int maptype=ci->map_type[mapnum]; |
188 | b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i], | 188 | b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i], |
189 | ci->map_param[mapnum]); | 189 | ci->map_param[mapnum]); |
190 | } | 190 | } |
191 | return(0); | 191 | return(0); |
192 | } | 192 | } |
193 | 193 | ||
194 | int vorbis_synthesis_restart(vorbis_dsp_state *v){ | 194 | int vorbis_synthesis_restart(vorbis_dsp_state *v){ |
195 | vorbis_info *vi=v->vi; | 195 | vorbis_info *vi=v->vi; |
196 | codec_setup_info *ci; | 196 | codec_setup_info *ci; |
197 | 197 | ||
198 | if(!v->backend_state)return -1; | 198 | if(!v->backend_state)return -1; |
199 | if(!vi)return -1; | 199 | if(!vi)return -1; |
200 | ci=vi->codec_setup; | 200 | ci=vi->codec_setup; |
201 | if(!ci)return -1; | 201 | if(!ci)return -1; |
202 | 202 | ||
203 | v->centerW=ci->blocksizes[1]/2; | 203 | v->centerW=ci->blocksizes[1]/2; |
204 | v->pcm_current=v->centerW; | 204 | v->pcm_current=v->centerW; |
205 | 205 | ||
206 | v->pcm_returned=-1; | 206 | v->pcm_returned=-1; |
207 | v->granulepos=-1; | 207 | v->granulepos=-1; |
208 | v->sequence=-1; | 208 | v->sequence=-1; |
209 | ((private_state *)(v->backend_state))->sample_count=-1; | 209 | ((private_state *)(v->backend_state))->sample_count=-1; |
210 | 210 | ||
211 | return(0); | 211 | return(0); |
212 | } | 212 | } |
213 | 213 | ||
214 | int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ | 214 | int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ |
215 | _vds_init(v,vi); | 215 | _vds_init(v,vi); |
216 | vorbis_synthesis_restart(v); | 216 | vorbis_synthesis_restart(v); |
217 | 217 | ||
218 | return(0); | 218 | return(0); |
219 | } | 219 | } |
220 | 220 | ||
221 | void vorbis_dsp_clear(vorbis_dsp_state *v){ | 221 | void vorbis_dsp_clear(vorbis_dsp_state *v){ |
222 | int i; | 222 | int i; |
223 | if(v){ | 223 | if(v){ |
224 | vorbis_info *vi=v->vi; | 224 | vorbis_info *vi=v->vi; |
225 | codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); | 225 | codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); |
226 | private_state *b=(private_state *)v->backend_state; | 226 | private_state *b=(private_state *)v->backend_state; |
227 | 227 | ||
228 | if(v->pcm){ | 228 | if(v->pcm){ |
229 | for(i=0;i<vi->channels;i++) | 229 | if (vi) { |
230 | if(v->pcm[i])_ogg_free(v->pcm[i]); | 230 | for(i=0;i<vi->channels;i++) |
231 | if(v->pcm[i])_ogg_free(v->pcm[i]); | ||
232 | } | ||
231 | _ogg_free(v->pcm); | 233 | _ogg_free(v->pcm); |
232 | if(v->pcmret)_ogg_free(v->pcmret); | 234 | if(v->pcmret)_ogg_free(v->pcmret); |
233 | } | 235 | } |
234 | 236 | ||
235 | /* free mode lookups; these are actually vorbis_look_mapping structs */ | 237 | /* free mode lookups; these are actually vorbis_look_mapping structs */ |
236 | if(ci){ | 238 | if(ci){ |
237 | for(i=0;i<ci->modes;i++){ | 239 | for(i=0;i<ci->modes;i++){ |
238 | int mapnum=ci->mode_param[i]->mapping; | 240 | int mapnum=ci->mode_param[i]->mapping; |
239 | int maptype=ci->map_type[mapnum]; | 241 | int maptype=ci->map_type[mapnum]; |
240 | if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]); | 242 | if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]); |
241 | } | 243 | } |
242 | } | 244 | } |
243 | 245 | ||
244 | if(b){ | 246 | if(b){ |
245 | if(b->mode)_ogg_free(b->mode); | 247 | if(b->mode)_ogg_free(b->mode); |
246 | _ogg_free(b); | 248 | _ogg_free(b); |
247 | } | 249 | } |
248 | 250 | ||
249 | memset(v,0,sizeof(*v)); | 251 | memset(v,0,sizeof(*v)); |
250 | } | 252 | } |
251 | } | 253 | } |
252 | 254 | ||
253 | /* Unlike in analysis, the window is only partially applied for each | 255 | /* Unlike in analysis, the window is only partially applied for each |
254 | block. The time domain envelope is not yet handled at the point of | 256 | block. The time domain envelope is not yet handled at the point of |
255 | calling (as it relies on the previous block). */ | 257 | calling (as it relies on the previous block). */ |
256 | 258 | ||
257 | int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ | 259 | int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){ |
258 | vorbis_info *vi=v->vi; | 260 | vorbis_info *vi=v->vi; |
259 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | 261 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; |
260 | private_state *b=v->backend_state; | 262 | private_state *b=v->backend_state; |
261 | int i,j; | 263 | int i,j; |
262 | 264 | ||
263 | if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); | 265 | if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); |
264 | 266 | ||
265 | v->lW=v->W; | 267 | v->lW=v->W; |
266 | v->W=vb->W; | 268 | v->W=vb->W; |
267 | v->nW=-1; | 269 | v->nW=-1; |
268 | 270 | ||
269 | if((v->sequence==-1)|| | 271 | if((v->sequence==-1)|| |
270 | (v->sequence+1 != vb->sequence)){ | 272 | (v->sequence+1 != vb->sequence)){ |
271 | v->granulepos=-1; /* out of sequence; lose count */ | 273 | v->granulepos=-1; /* out of sequence; lose count */ |
272 | b->sample_count=-1; | 274 | b->sample_count=-1; |
273 | } | 275 | } |
274 | 276 | ||
275 | v->sequence=vb->sequence; | 277 | v->sequence=vb->sequence; |
276 | 278 | ||
277 | if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly | 279 | if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly |
278 | was called on block */ | 280 | was called on block */ |
279 | int n=ci->blocksizes[v->W]/2; | 281 | int n=ci->blocksizes[v->W]/2; |
280 | int n0=ci->blocksizes[0]/2; | 282 | int n0=ci->blocksizes[0]/2; |
281 | int n1=ci->blocksizes[1]/2; | 283 | int n1=ci->blocksizes[1]/2; |
282 | 284 | ||
283 | int thisCenter; | 285 | int thisCenter; |
284 | int prevCenter; | 286 | int prevCenter; |
285 | 287 | ||
286 | if(v->centerW){ | 288 | if(v->centerW){ |
287 | thisCenter=n1; | 289 | thisCenter=n1; |
288 | prevCenter=0; | 290 | prevCenter=0; |
289 | }else{ | 291 | }else{ |
290 | thisCenter=0; | 292 | thisCenter=0; |
291 | prevCenter=n1; | 293 | prevCenter=n1; |
292 | } | 294 | } |
293 | 295 | ||
294 | /* v->pcm is now used like a two-stage double buffer. We don't want | 296 | /* v->pcm is now used like a two-stage double buffer. We don't want |
295 | to have to constantly shift *or* adjust memory usage. Don't | 297 | to have to constantly shift *or* adjust memory usage. Don't |
296 | accept a new block until the old is shifted out */ | 298 | accept a new block until the old is shifted out */ |
297 | 299 | ||
298 | /* overlap/add PCM */ | 300 | /* overlap/add PCM */ |
299 | 301 | ||
300 | for(j=0;j<vi->channels;j++){ | 302 | for(j=0;j<vi->channels;j++){ |
301 | /* the overlap/add section */ | 303 | /* the overlap/add section */ |
302 | if(v->lW){ | 304 | if(v->lW){ |
303 | if(v->W){ | 305 | if(v->W){ |
304 | /* large/large */ | 306 | /* large/large */ |
305 | ogg_int32_t *pcm=v->pcm[j]+prevCenter; | 307 | ogg_int32_t *pcm=v->pcm[j]+prevCenter; |
306 | ogg_int32_t *p=vb->pcm[j]; | 308 | ogg_int32_t *p=vb->pcm[j]; |
307 | for(i=0;i<n1;i++) | 309 | for(i=0;i<n1;i++) |
308 | pcm[i]+=p[i]; | 310 | pcm[i]+=p[i]; |
309 | }else{ | 311 | }else{ |
310 | /* large/small */ | 312 | /* large/small */ |
311 | ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; | 313 | ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2; |
312 | ogg_int32_t *p=vb->pcm[j]; | 314 | ogg_int32_t *p=vb->pcm[j]; |
313 | for(i=0;i<n0;i++) | 315 | for(i=0;i<n0;i++) |
314 | pcm[i]+=p[i]; | 316 | pcm[i]+=p[i]; |
315 | } | 317 | } |
316 | }else{ | 318 | }else{ |
317 | if(v->W){ | 319 | if(v->W){ |
318 | /* small/large */ | 320 | /* small/large */ |
319 | ogg_int32_t *pcm=v->pcm[j]+prevCenter; | 321 | ogg_int32_t *pcm=v->pcm[j]+prevCenter; |
320 | ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2; | 322 | ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2; |
321 | for(i=0;i<n0;i++) | 323 | for(i=0;i<n0;i++) |
322 | pcm[i]+=p[i]; | 324 | pcm[i]+=p[i]; |
323 | for(;i<n1/2+n0/2;i++) | 325 | for(;i<n1/2+n0/2;i++) |
324 | pcm[i]=p[i]; | 326 | pcm[i]=p[i]; |
325 | }else{ | 327 | }else{ |
326 | /* small/small */ | 328 | /* small/small */ |
327 | ogg_int32_t *pcm=v->pcm[j]+prevCenter; | 329 | ogg_int32_t *pcm=v->pcm[j]+prevCenter; |
328 | ogg_int32_t *p=vb->pcm[j]; | 330 | ogg_int32_t *p=vb->pcm[j]; |
329 | for(i=0;i<n0;i++) | 331 | for(i=0;i<n0;i++) |
330 | pcm[i]+=p[i]; | 332 | pcm[i]+=p[i]; |
331 | } | 333 | } |
332 | } | 334 | } |
333 | 335 | ||
334 | /* the copy section */ | 336 | /* the copy section */ |
335 | { | 337 | { |
336 | ogg_int32_t *pcm=v->pcm[j]+thisCenter; | 338 | ogg_int32_t *pcm=v->pcm[j]+thisCenter; |
337 | ogg_int32_t *p=vb->pcm[j]+n; | 339 | ogg_int32_t *p=vb->pcm[j]+n; |
338 | for(i=0;i<n;i++) | 340 | for(i=0;i<n;i++) |
339 | pcm[i]=p[i]; | 341 | pcm[i]=p[i]; |
340 | } | 342 | } |
341 | } | 343 | } |
342 | 344 | ||
343 | if(v->centerW) | 345 | if(v->centerW) |
344 | v->centerW=0; | 346 | v->centerW=0; |
345 | else | 347 | else |
346 | v->centerW=n1; | 348 | v->centerW=n1; |
347 | 349 | ||
348 | /* deal with initial packet state; we do this using the explicit | 350 | /* deal with initial packet state; we do this using the explicit |
349 | pcm_returned==-1 flag otherwise we're sensitive to first block | 351 | pcm_returned==-1 flag otherwise we're sensitive to first block |
350 | being short or long */ | 352 | being short or long */ |
351 | 353 | ||
352 | if(v->pcm_returned==-1){ | 354 | if(v->pcm_returned==-1){ |
353 | v->pcm_returned=thisCenter; | 355 | v->pcm_returned=thisCenter; |
354 | v->pcm_current=thisCenter; | 356 | v->pcm_current=thisCenter; |
355 | }else{ | 357 | }else{ |
356 | v->pcm_returned=prevCenter; | 358 | v->pcm_returned=prevCenter; |
357 | v->pcm_current=prevCenter+ | 359 | v->pcm_current=prevCenter+ |
358 | ci->blocksizes[v->lW]/4+ | 360 | ci->blocksizes[v->lW]/4+ |
359 | ci->blocksizes[v->W]/4; | 361 | ci->blocksizes[v->W]/4; |
360 | } | 362 | } |
361 | 363 | ||
362 | } | 364 | } |
363 | 365 | ||
364 | /* track the frame number... This is for convenience, but also | 366 | /* track the frame number... This is for convenience, but also |
365 | making sure our last packet doesn't end with added padding. If | 367 | making sure our last packet doesn't end with added padding. If |
366 | the last packet is partial, the number of samples we'll have to | 368 | the last packet is partial, the number of samples we'll have to |
367 | return will be past the vb->granulepos. | 369 | return will be past the vb->granulepos. |
368 | 370 | ||
369 | This is not foolproof! It will be confused if we begin | 371 | This is not foolproof! It will be confused if we begin |
370 | decoding at the last page after a seek or hole. In that case, | 372 | decoding at the last page after a seek or hole. In that case, |
371 | we don't have a starting point to judge where the last frame | 373 | we don't have a starting point to judge where the last frame |
372 | is. For this reason, vorbisfile will always try to make sure | 374 | is. For this reason, vorbisfile will always try to make sure |
373 | it reads the last two marked pages in proper sequence */ | 375 | it reads the last two marked pages in proper sequence */ |
374 | 376 | ||
375 | if(b->sample_count==-1){ | 377 | if(b->sample_count==-1){ |
376 | b->sample_count=0; | 378 | b->sample_count=0; |
377 | }else{ | 379 | }else{ |
378 | b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; | 380 | b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; |
379 | } | 381 | } |
380 | 382 | ||
381 | if(v->granulepos==-1){ | 383 | if(v->granulepos==-1){ |
382 | if(vb->granulepos!=-1){ /* only set if we have a position to set to */ | 384 | if(vb->granulepos!=-1){ /* only set if we have a position to set to */ |
383 | 385 | ||
384 | v->granulepos=vb->granulepos; | 386 | v->granulepos=vb->granulepos; |
385 | 387 | ||
386 | /* is this a short page? */ | 388 | /* is this a short page? */ |
387 | if(b->sample_count>v->granulepos){ | 389 | if(b->sample_count>v->granulepos){ |
388 | /* corner case; if this is both the first and last audio page, | 390 | /* corner case; if this is both the first and last audio page, |
389 | then spec says the end is cut, not beginning */ | 391 | then spec says the end is cut, not beginning */ |
390 | if(vb->eofflag){ | 392 | if(vb->eofflag){ |
391 | /* trim the end */ | 393 | /* trim the end */ |
392 | /* no preceeding granulepos; assume we started at zero (we'd | 394 | /* no preceeding granulepos; assume we started at zero (we'd |
393 | have to in a short single-page stream) */ | 395 | have to in a short single-page stream) */ |
394 | /* granulepos could be -1 due to a seek, but that would result | 396 | /* granulepos could be -1 due to a seek, but that would result |
395 | in a long coun`t, not short count */ | 397 | in a long coun`t, not short count */ |
396 | 398 | ||
397 | v->pcm_current-=(b->sample_count-v->granulepos); | 399 | v->pcm_current-=(b->sample_count-v->granulepos); |
398 | }else{ | 400 | }else{ |
399 | /* trim the beginning */ | 401 | /* trim the beginning */ |
400 | v->pcm_returned+=(b->sample_count-v->granulepos); | 402 | v->pcm_returned+=(b->sample_count-v->granulepos); |
401 | if(v->pcm_returned>v->pcm_current) | 403 | if(v->pcm_returned>v->pcm_current) |
402 | v->pcm_returned=v->pcm_current; | 404 | v->pcm_returned=v->pcm_current; |
403 | } | 405 | } |
404 | 406 | ||
405 | } | 407 | } |
406 | 408 | ||
407 | } | 409 | } |
408 | }else{ | 410 | }else{ |
409 | v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; | 411 | v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4; |
410 | if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ | 412 | if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){ |
411 | 413 | ||
412 | if(v->granulepos>vb->granulepos){ | 414 | if(v->granulepos>vb->granulepos){ |
413 | long extra=v->granulepos-vb->granulepos; | 415 | long extra=v->granulepos-vb->granulepos; |
414 | 416 | ||
415 | if(extra) | 417 | if(extra) |
416 | if(vb->eofflag){ | 418 | if(vb->eofflag){ |
417 | /* partial last frame. Strip the extra samples off */ | 419 | /* partial last frame. Strip the extra samples off */ |
418 | v->pcm_current-=extra; | 420 | v->pcm_current-=extra; |
419 | } /* else {Shouldn't happen *unless* the bitstream is out of | 421 | } /* else {Shouldn't happen *unless* the bitstream is out of |
420 | spec. Either way, believe the bitstream } */ | 422 | spec. Either way, believe the bitstream } */ |
421 | } /* else {Shouldn't happen *unless* the bitstream is out of | 423 | } /* else {Shouldn't happen *unless* the bitstream is out of |
422 | spec. Either way, believe the bitstream } */ | 424 | spec. Either way, believe the bitstream } */ |
423 | v->granulepos=vb->granulepos; | 425 | v->granulepos=vb->granulepos; |
424 | } | 426 | } |
425 | } | 427 | } |
426 | 428 | ||
427 | /* Update, cleanup */ | 429 | /* Update, cleanup */ |
428 | 430 | ||
429 | if(vb->eofflag)v->eofflag=1; | 431 | if(vb->eofflag)v->eofflag=1; |
430 | return(0); | 432 | return(0); |
431 | } | 433 | } |
432 | 434 | ||
433 | /* pcm==NULL indicates we just want the pending samples, no more */ | 435 | /* pcm==NULL indicates we just want the pending samples, no more */ |
434 | int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){ | 436 | int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){ |
435 | vorbis_info *vi=v->vi; | 437 | vorbis_info *vi=v->vi; |
436 | if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){ | 438 | if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){ |
437 | if(pcm){ | 439 | if(pcm){ |
438 | int i; | 440 | int i; |
439 | for(i=0;i<vi->channels;i++) | 441 | for(i=0;i<vi->channels;i++) |
440 | v->pcmret[i]=v->pcm[i]+v->pcm_returned; | 442 | v->pcmret[i]=v->pcm[i]+v->pcm_returned; |
441 | *pcm=v->pcmret; | 443 | *pcm=v->pcmret; |
442 | } | 444 | } |
443 | return(v->pcm_current-v->pcm_returned); | 445 | return(v->pcm_current-v->pcm_returned); |
444 | } | 446 | } |
445 | return(0); | 447 | return(0); |
446 | } | 448 | } |
447 | 449 | ||
448 | int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){ | 450 | int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){ |
449 | if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL); | 451 | if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL); |
450 | v->pcm_returned+=bytes; | 452 | v->pcm_returned+=bytes; |
451 | return(0); | 453 | return(0); |
452 | } | 454 | } |
453 | 455 | ||
diff --git a/core/multimedia/opieplayer/vorbis/tremor/info.c b/core/multimedia/opieplayer/vorbis/tremor/info.c index 941695e..3499ae4 100644 --- a/core/multimedia/opieplayer/vorbis/tremor/info.c +++ b/core/multimedia/opieplayer/vorbis/tremor/info.c | |||
@@ -1,354 +1,354 @@ | |||
1 | /******************************************************************** | 1 | /******************************************************************** |
2 | * * | 2 | * * |
3 | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * | 3 | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * |
4 | * * | 4 | * * |
5 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | 5 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
6 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | 6 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
7 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | 7 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
8 | * * | 8 | * * |
9 | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * | 9 | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 * |
10 | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * | 10 | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * |
11 | * * | 11 | * * |
12 | ******************************************************************** | 12 | ******************************************************************** |
13 | 13 | ||
14 | function: maintain the info structure, info <-> header packets | 14 | function: maintain the info structure, info <-> header packets |
15 | 15 | ||
16 | ********************************************************************/ | 16 | ********************************************************************/ |
17 | 17 | ||
18 | /* general handling of the header and the vorbis_info structure (and | 18 | /* general handling of the header and the vorbis_info structure (and |
19 | substructures) */ | 19 | substructures) */ |
20 | 20 | ||
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <ctype.h> | 23 | #include <ctype.h> |
24 | #include "ogg.h" | 24 | #include "ogg.h" |
25 | #include "ivorbiscodec.h" | 25 | #include "ivorbiscodec.h" |
26 | #include "codec_internal.h" | 26 | #include "codec_internal.h" |
27 | #include "codebook.h" | 27 | #include "codebook.h" |
28 | #include "registry.h" | 28 | #include "registry.h" |
29 | #include "window.h" | 29 | #include "window.h" |
30 | #include "misc.h" | 30 | #include "misc.h" |
31 | #include "os.h" | 31 | #include "os.h" |
32 | 32 | ||
33 | /* helpers */ | 33 | /* helpers */ |
34 | static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ | 34 | static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ |
35 | while(bytes--){ | 35 | while(bytes--){ |
36 | *buf++=oggpack_read(o,8); | 36 | *buf++=oggpack_read(o,8); |
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
40 | void vorbis_comment_init(vorbis_comment *vc){ | 40 | void vorbis_comment_init(vorbis_comment *vc){ |
41 | memset(vc,0,sizeof(*vc)); | 41 | memset(vc,0,sizeof(*vc)); |
42 | } | 42 | } |
43 | 43 | ||
44 | /* This is more or less the same as strncasecmp - but that doesn't exist | 44 | /* This is more or less the same as strncasecmp - but that doesn't exist |
45 | * everywhere, and this is a fairly trivial function, so we include it */ | 45 | * everywhere, and this is a fairly trivial function, so we include it */ |
46 | static int tagcompare(const char *s1, const char *s2, int n){ | 46 | static int tagcompare(const char *s1, const char *s2, int n){ |
47 | int c=0; | 47 | int c=0; |
48 | while(c < n){ | 48 | while(c < n){ |
49 | if(toupper(s1[c]) != toupper(s2[c])) | 49 | if(toupper(s1[c]) != toupper(s2[c])) |
50 | return !0; | 50 | return !0; |
51 | c++; | 51 | c++; |
52 | } | 52 | } |
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ | 56 | char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){ |
57 | long i; | 57 | long i; |
58 | int found = 0; | 58 | int found = 0; |
59 | int taglen = strlen(tag)+1; /* +1 for the = we append */ | 59 | int taglen = strlen(tag)+1; /* +1 for the = we append */ |
60 | char *fulltag = (char *)alloca(taglen+ 1); | 60 | char *fulltag = (char *)alloca(taglen+ 1); |
61 | 61 | ||
62 | strcpy(fulltag, tag); | 62 | strcpy(fulltag, tag); |
63 | strcat(fulltag, "="); | 63 | strcat(fulltag, "="); |
64 | 64 | ||
65 | for(i=0;i<vc->comments;i++){ | 65 | for(i=0;i<vc->comments;i++){ |
66 | if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ | 66 | if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ |
67 | if(count == found) | 67 | if(count == found) |
68 | /* We return a pointer to the data, not a copy */ | 68 | /* We return a pointer to the data, not a copy */ |
69 | return vc->user_comments[i] + taglen; | 69 | return vc->user_comments[i] + taglen; |
70 | else | 70 | else |
71 | found++; | 71 | found++; |
72 | } | 72 | } |
73 | } | 73 | } |
74 | return NULL; /* didn't find anything */ | 74 | return NULL; /* didn't find anything */ |
75 | } | 75 | } |
76 | 76 | ||
77 | int vorbis_comment_query_count(vorbis_comment *vc, char *tag){ | 77 | int vorbis_comment_query_count(vorbis_comment *vc, char *tag){ |
78 | int i,count=0; | 78 | int i,count=0; |
79 | int taglen = strlen(tag)+1; /* +1 for the = we append */ | 79 | int taglen = strlen(tag)+1; /* +1 for the = we append */ |
80 | char *fulltag = (char *)alloca(taglen+1); | 80 | char *fulltag = (char *)alloca(taglen+1); |
81 | strcpy(fulltag,tag); | 81 | strcpy(fulltag,tag); |
82 | strcat(fulltag, "="); | 82 | strcat(fulltag, "="); |
83 | 83 | ||
84 | for(i=0;i<vc->comments;i++){ | 84 | for(i=0;i<vc->comments;i++){ |
85 | if(!tagcompare(vc->user_comments[i], fulltag, taglen)) | 85 | if(!tagcompare(vc->user_comments[i], fulltag, taglen)) |
86 | count++; | 86 | count++; |
87 | } | 87 | } |
88 | 88 | ||
89 | return count; | 89 | return count; |
90 | } | 90 | } |
91 | 91 | ||
92 | void vorbis_comment_clear(vorbis_comment *vc){ | 92 | void vorbis_comment_clear(vorbis_comment *vc){ |
93 | if(vc){ | 93 | if(vc){ |
94 | long i; | 94 | long i; |
95 | for(i=0;i<vc->comments;i++) | 95 | for(i=0;i<vc->comments;i++) |
96 | if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); | 96 | if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); |
97 | if(vc->user_comments)_ogg_free(vc->user_comments); | 97 | if(vc->user_comments)_ogg_free(vc->user_comments); |
98 | if(vc->comment_lengths)_ogg_free(vc->comment_lengths); | 98 | if(vc->comment_lengths)_ogg_free(vc->comment_lengths); |
99 | if(vc->vendor)_ogg_free(vc->vendor); | 99 | if(vc->vendor)_ogg_free(vc->vendor); |
100 | memset(vc,0,sizeof(*vc)); | ||
100 | } | 101 | } |
101 | memset(vc,0,sizeof(*vc)); | ||
102 | } | 102 | } |
103 | 103 | ||
104 | /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. | 104 | /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. |
105 | They may be equal, but short will never ge greater than long */ | 105 | They may be equal, but short will never ge greater than long */ |
106 | int vorbis_info_blocksize(vorbis_info *vi,int zo){ | 106 | int vorbis_info_blocksize(vorbis_info *vi,int zo){ |
107 | codec_setup_info *ci = (codec_setup_info *)vi->codec_setup; | 107 | codec_setup_info *ci = (codec_setup_info *)vi->codec_setup; |
108 | return ci ? ci->blocksizes[zo] : -1; | 108 | return ci ? ci->blocksizes[zo] : -1; |
109 | } | 109 | } |
110 | 110 | ||
111 | /* used by synthesis, which has a full, alloced vi */ | 111 | /* used by synthesis, which has a full, alloced vi */ |
112 | void vorbis_info_init(vorbis_info *vi){ | 112 | void vorbis_info_init(vorbis_info *vi){ |
113 | memset(vi,0,sizeof(*vi)); | 113 | memset(vi,0,sizeof(*vi)); |
114 | vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info)); | 114 | vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info)); |
115 | } | 115 | } |
116 | 116 | ||
117 | void vorbis_info_clear(vorbis_info *vi){ | 117 | void vorbis_info_clear(vorbis_info *vi){ |
118 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | 118 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; |
119 | int i; | 119 | int i; |
120 | 120 | ||
121 | if(ci){ | 121 | if(ci){ |
122 | 122 | ||
123 | for(i=0;i<ci->modes;i++) | 123 | for(i=0;i<ci->modes;i++) |
124 | if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); | 124 | if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); |
125 | 125 | ||
126 | for(i=0;i<ci->maps;i++) /* unpack does the range checking */ | 126 | for(i=0;i<ci->maps;i++) /* unpack does the range checking */ |
127 | _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); | 127 | _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); |
128 | 128 | ||
129 | for(i=0;i<ci->floors;i++) /* unpack does the range checking */ | 129 | for(i=0;i<ci->floors;i++) /* unpack does the range checking */ |
130 | _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); | 130 | _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); |
131 | 131 | ||
132 | for(i=0;i<ci->residues;i++) /* unpack does the range checking */ | 132 | for(i=0;i<ci->residues;i++) /* unpack does the range checking */ |
133 | _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); | 133 | _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); |
134 | 134 | ||
135 | for(i=0;i<ci->books;i++){ | 135 | for(i=0;i<ci->books;i++){ |
136 | if(ci->book_param[i]){ | 136 | if(ci->book_param[i]){ |
137 | /* knows if the book was not alloced */ | 137 | /* knows if the book was not alloced */ |
138 | vorbis_staticbook_destroy(ci->book_param[i]); | 138 | vorbis_staticbook_destroy(ci->book_param[i]); |
139 | } | 139 | } |
140 | if(ci->fullbooks) | 140 | if(ci->fullbooks) |
141 | vorbis_book_clear(ci->fullbooks+i); | 141 | vorbis_book_clear(ci->fullbooks+i); |
142 | } | 142 | } |
143 | if(ci->fullbooks) | 143 | if(ci->fullbooks) |
144 | _ogg_free(ci->fullbooks); | 144 | _ogg_free(ci->fullbooks); |
145 | 145 | ||
146 | _ogg_free(ci); | 146 | _ogg_free(ci); |
147 | } | 147 | } |
148 | 148 | ||
149 | memset(vi,0,sizeof(*vi)); | 149 | memset(vi,0,sizeof(*vi)); |
150 | } | 150 | } |
151 | 151 | ||
152 | /* Header packing/unpacking ********************************************/ | 152 | /* Header packing/unpacking ********************************************/ |
153 | 153 | ||
154 | static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ | 154 | static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ |
155 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | 155 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; |
156 | if(!ci)return(OV_EFAULT); | 156 | if(!ci)return(OV_EFAULT); |
157 | 157 | ||
158 | vi->version=oggpack_read(opb,32); | 158 | vi->version=oggpack_read(opb,32); |
159 | if(vi->version!=0)return(OV_EVERSION); | 159 | if(vi->version!=0)return(OV_EVERSION); |
160 | 160 | ||
161 | vi->channels=oggpack_read(opb,8); | 161 | vi->channels=oggpack_read(opb,8); |
162 | vi->rate=oggpack_read(opb,32); | 162 | vi->rate=oggpack_read(opb,32); |
163 | 163 | ||
164 | vi->bitrate_upper=oggpack_read(opb,32); | 164 | vi->bitrate_upper=oggpack_read(opb,32); |
165 | vi->bitrate_nominal=oggpack_read(opb,32); | 165 | vi->bitrate_nominal=oggpack_read(opb,32); |
166 | vi->bitrate_lower=oggpack_read(opb,32); | 166 | vi->bitrate_lower=oggpack_read(opb,32); |
167 | 167 | ||
168 | ci->blocksizes[0]=1<<oggpack_read(opb,4); | 168 | ci->blocksizes[0]=1<<oggpack_read(opb,4); |
169 | ci->blocksizes[1]=1<<oggpack_read(opb,4); | 169 | ci->blocksizes[1]=1<<oggpack_read(opb,4); |
170 | 170 | ||
171 | if(vi->rate<1)goto err_out; | 171 | if(vi->rate<1)goto err_out; |
172 | if(vi->channels<1)goto err_out; | 172 | if(vi->channels<1)goto err_out; |
173 | if(ci->blocksizes[0]<64)goto err_out; | 173 | if(ci->blocksizes[0]<64)goto err_out; |
174 | if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out; | 174 | if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out; |
175 | if(ci->blocksizes[1]>8192)goto err_out; | 175 | if(ci->blocksizes[1]>8192)goto err_out; |
176 | 176 | ||
177 | if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ | 177 | if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ |
178 | 178 | ||
179 | return(0); | 179 | return(0); |
180 | err_out: | 180 | err_out: |
181 | vorbis_info_clear(vi); | 181 | vorbis_info_clear(vi); |
182 | return(OV_EBADHEADER); | 182 | return(OV_EBADHEADER); |
183 | } | 183 | } |
184 | 184 | ||
185 | static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ | 185 | static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ |
186 | int i; | 186 | int i; |
187 | int vendorlen=oggpack_read(opb,32); | 187 | int vendorlen=oggpack_read(opb,32); |
188 | if(vendorlen<0)goto err_out; | 188 | if(vendorlen<0)goto err_out; |
189 | vc->vendor=(char *)_ogg_calloc(vendorlen+1,1); | 189 | vc->vendor=(char *)_ogg_calloc(vendorlen+1,1); |
190 | _v_readstring(opb,vc->vendor,vendorlen); | 190 | _v_readstring(opb,vc->vendor,vendorlen); |
191 | vc->comments=oggpack_read(opb,32); | 191 | vc->comments=oggpack_read(opb,32); |
192 | if(vc->comments<0)goto err_out; | 192 | if(vc->comments<0)goto err_out; |
193 | vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); | 193 | vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); |
194 | vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); | 194 | vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); |
195 | 195 | ||
196 | for(i=0;i<vc->comments;i++){ | 196 | for(i=0;i<vc->comments;i++){ |
197 | int len=oggpack_read(opb,32); | 197 | int len=oggpack_read(opb,32); |
198 | if(len<0)goto err_out; | 198 | if(len<0)goto err_out; |
199 | vc->comment_lengths[i]=len; | 199 | vc->comment_lengths[i]=len; |
200 | vc->user_comments[i]=(char *)_ogg_calloc(len+1,1); | 200 | vc->user_comments[i]=(char *)_ogg_calloc(len+1,1); |
201 | _v_readstring(opb,vc->user_comments[i],len); | 201 | _v_readstring(opb,vc->user_comments[i],len); |
202 | } | 202 | } |
203 | if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ | 203 | if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ |
204 | 204 | ||
205 | return(0); | 205 | return(0); |
206 | err_out: | 206 | err_out: |
207 | vorbis_comment_clear(vc); | 207 | vorbis_comment_clear(vc); |
208 | return(OV_EBADHEADER); | 208 | return(OV_EBADHEADER); |
209 | } | 209 | } |
210 | 210 | ||
211 | /* all of the real encoding details are here. The modes, books, | 211 | /* all of the real encoding details are here. The modes, books, |
212 | everything */ | 212 | everything */ |
213 | static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ | 213 | static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ |
214 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | 214 | codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; |
215 | int i; | 215 | int i; |
216 | if(!ci)return(OV_EFAULT); | 216 | if(!ci)return(OV_EFAULT); |
217 | 217 | ||
218 | /* codebooks */ | 218 | /* codebooks */ |
219 | ci->books=oggpack_read(opb,8)+1; | 219 | ci->books=oggpack_read(opb,8)+1; |
220 | /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ | 220 | /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ |
221 | for(i=0;i<ci->books;i++){ | 221 | for(i=0;i<ci->books;i++){ |
222 | ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i])); | 222 | ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i])); |
223 | if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; | 223 | if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* time backend settings */ | 226 | /* time backend settings */ |
227 | ci->times=oggpack_read(opb,6)+1; | 227 | ci->times=oggpack_read(opb,6)+1; |
228 | /*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/ | 228 | /*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/ |
229 | /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/ | 229 | /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/ |
230 | for(i=0;i<ci->times;i++){ | 230 | for(i=0;i<ci->times;i++){ |
231 | ci->time_type[i]=oggpack_read(opb,16); | 231 | ci->time_type[i]=oggpack_read(opb,16); |
232 | if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out; | 232 | if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out; |
233 | /* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb); | 233 | /* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb); |
234 | Vorbis I has no time backend */ | 234 | Vorbis I has no time backend */ |
235 | /*if(!ci->time_param[i])goto err_out;*/ | 235 | /*if(!ci->time_param[i])goto err_out;*/ |
236 | } | 236 | } |
237 | 237 | ||
238 | /* floor backend settings */ | 238 | /* floor backend settings */ |
239 | ci->floors=oggpack_read(opb,6)+1; | 239 | ci->floors=oggpack_read(opb,6)+1; |
240 | /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ | 240 | /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ |
241 | /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ | 241 | /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ |
242 | for(i=0;i<ci->floors;i++){ | 242 | for(i=0;i<ci->floors;i++){ |
243 | ci->floor_type[i]=oggpack_read(opb,16); | 243 | ci->floor_type[i]=oggpack_read(opb,16); |
244 | if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; | 244 | if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; |
245 | ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); | 245 | ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); |
246 | if(!ci->floor_param[i])goto err_out; | 246 | if(!ci->floor_param[i])goto err_out; |
247 | } | 247 | } |
248 | 248 | ||
249 | /* residue backend settings */ | 249 | /* residue backend settings */ |
250 | ci->residues=oggpack_read(opb,6)+1; | 250 | ci->residues=oggpack_read(opb,6)+1; |
251 | /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ | 251 | /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ |
252 | /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ | 252 | /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ |
253 | for(i=0;i<ci->residues;i++){ | 253 | for(i=0;i<ci->residues;i++){ |
254 | ci->residue_type[i]=oggpack_read(opb,16); | 254 | ci->residue_type[i]=oggpack_read(opb,16); |
255 | if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; | 255 | if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; |
256 | ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); | 256 | ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); |
257 | if(!ci->residue_param[i])goto err_out; | 257 | if(!ci->residue_param[i])goto err_out; |
258 | } | 258 | } |
259 | 259 | ||
260 | /* map backend settings */ | 260 | /* map backend settings */ |
261 | ci->maps=oggpack_read(opb,6)+1; | 261 | ci->maps=oggpack_read(opb,6)+1; |
262 | /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ | 262 | /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ |
263 | /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ | 263 | /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ |
264 | for(i=0;i<ci->maps;i++){ | 264 | for(i=0;i<ci->maps;i++){ |
265 | ci->map_type[i]=oggpack_read(opb,16); | 265 | ci->map_type[i]=oggpack_read(opb,16); |
266 | if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; | 266 | if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; |
267 | ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); | 267 | ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); |
268 | if(!ci->map_param[i])goto err_out; | 268 | if(!ci->map_param[i])goto err_out; |
269 | } | 269 | } |
270 | 270 | ||
271 | /* mode settings */ | 271 | /* mode settings */ |
272 | ci->modes=oggpack_read(opb,6)+1; | 272 | ci->modes=oggpack_read(opb,6)+1; |
273 | /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ | 273 | /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ |
274 | for(i=0;i<ci->modes;i++){ | 274 | for(i=0;i<ci->modes;i++){ |
275 | ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i])); | 275 | ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i])); |
276 | ci->mode_param[i]->blockflag=oggpack_read(opb,1); | 276 | ci->mode_param[i]->blockflag=oggpack_read(opb,1); |
277 | ci->mode_param[i]->windowtype=oggpack_read(opb,16); | 277 | ci->mode_param[i]->windowtype=oggpack_read(opb,16); |
278 | ci->mode_param[i]->transformtype=oggpack_read(opb,16); | 278 | ci->mode_param[i]->transformtype=oggpack_read(opb,16); |
279 | ci->mode_param[i]->mapping=oggpack_read(opb,8); | 279 | ci->mode_param[i]->mapping=oggpack_read(opb,8); |
280 | 280 | ||
281 | if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; | 281 | if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; |
282 | if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; | 282 | if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; |
283 | if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; | 283 | if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; |
284 | } | 284 | } |
285 | 285 | ||
286 | if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ | 286 | if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ |
287 | 287 | ||
288 | return(0); | 288 | return(0); |
289 | err_out: | 289 | err_out: |
290 | vorbis_info_clear(vi); | 290 | vorbis_info_clear(vi); |
291 | return(OV_EBADHEADER); | 291 | return(OV_EBADHEADER); |
292 | } | 292 | } |
293 | 293 | ||
294 | /* The Vorbis header is in three packets; the initial small packet in | 294 | /* The Vorbis header is in three packets; the initial small packet in |
295 | the first page that identifies basic parameters, a second packet | 295 | the first page that identifies basic parameters, a second packet |
296 | with bitstream comments and a third packet that holds the | 296 | with bitstream comments and a third packet that holds the |
297 | codebook. */ | 297 | codebook. */ |
298 | 298 | ||
299 | int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ | 299 | int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ |
300 | oggpack_buffer opb; | 300 | oggpack_buffer opb; |
301 | 301 | ||
302 | if(op){ | 302 | if(op){ |
303 | oggpack_readinit(&opb,op->packet); | 303 | oggpack_readinit(&opb,op->packet); |
304 | 304 | ||
305 | /* Which of the three types of header is this? */ | 305 | /* Which of the three types of header is this? */ |
306 | /* Also verify header-ness, vorbis */ | 306 | /* Also verify header-ness, vorbis */ |
307 | { | 307 | { |
308 | char buffer[6]; | 308 | char buffer[6]; |
309 | int packtype=oggpack_read(&opb,8); | 309 | int packtype=oggpack_read(&opb,8); |
310 | memset(buffer,0,6); | 310 | memset(buffer,0,6); |
311 | _v_readstring(&opb,buffer,6); | 311 | _v_readstring(&opb,buffer,6); |
312 | if(memcmp(buffer,"vorbis",6)){ | 312 | if(memcmp(buffer,"vorbis",6)){ |
313 | /* not a vorbis header */ | 313 | /* not a vorbis header */ |
314 | return(OV_ENOTVORBIS); | 314 | return(OV_ENOTVORBIS); |
315 | } | 315 | } |
316 | switch(packtype){ | 316 | switch(packtype){ |
317 | case 0x01: /* least significant *bit* is read first */ | 317 | case 0x01: /* least significant *bit* is read first */ |
318 | if(!op->b_o_s){ | 318 | if(!op->b_o_s){ |
319 | /* Not the initial packet */ | 319 | /* Not the initial packet */ |
320 | return(OV_EBADHEADER); | 320 | return(OV_EBADHEADER); |
321 | } | 321 | } |
322 | if(vi->rate!=0){ | 322 | if(vi->rate!=0){ |
323 | /* previously initialized info header */ | 323 | /* previously initialized info header */ |
324 | return(OV_EBADHEADER); | 324 | return(OV_EBADHEADER); |
325 | } | 325 | } |
326 | 326 | ||
327 | return(_vorbis_unpack_info(vi,&opb)); | 327 | return(_vorbis_unpack_info(vi,&opb)); |
328 | 328 | ||
329 | case 0x03: /* least significant *bit* is read first */ | 329 | case 0x03: /* least significant *bit* is read first */ |
330 | if(vi->rate==0){ | 330 | if(vi->rate==0){ |
331 | /* um... we didn't get the initial header */ | 331 | /* um... we didn't get the initial header */ |
332 | return(OV_EBADHEADER); | 332 | return(OV_EBADHEADER); |
333 | } | 333 | } |
334 | 334 | ||
335 | return(_vorbis_unpack_comment(vc,&opb)); | 335 | return(_vorbis_unpack_comment(vc,&opb)); |
336 | 336 | ||
337 | case 0x05: /* least significant *bit* is read first */ | 337 | case 0x05: /* least significant *bit* is read first */ |
338 | if(vi->rate==0 || vc->vendor==NULL){ | 338 | if(vi->rate==0 || vc->vendor==NULL){ |
339 | /* um... we didn;t get the initial header or comments yet */ | 339 | /* um... we didn;t get the initial header or comments yet */ |
340 | return(OV_EBADHEADER); | 340 | return(OV_EBADHEADER); |
341 | } | 341 | } |
342 | 342 | ||
343 | return(_vorbis_unpack_books(vi,&opb)); | 343 | return(_vorbis_unpack_books(vi,&opb)); |
344 | 344 | ||
345 | default: | 345 | default: |
346 | /* Not a valid vorbis header type */ | 346 | /* Not a valid vorbis header type */ |
347 | return(OV_EBADHEADER); | 347 | return(OV_EBADHEADER); |
348 | break; | 348 | break; |
349 | } | 349 | } |
350 | } | 350 | } |
351 | } | 351 | } |
352 | return(OV_EBADHEADER); | 352 | return(OV_EBADHEADER); |
353 | } | 353 | } |
354 | 354 | ||
diff --git a/noncore/apps/opie-write/qrichtext.cpp b/noncore/apps/opie-write/qrichtext.cpp index f040f1e..768da44 100644 --- a/noncore/apps/opie-write/qrichtext.cpp +++ b/noncore/apps/opie-write/qrichtext.cpp | |||
@@ -1,7834 +1,7857 @@ | |||
1 | /**************************************************************************** | 1 | /**************************************************************************** |
2 | ** $Id$ | 2 | ** $Id$ |
3 | ** | 3 | ** |
4 | ** Implementation of the internal Qt classes dealing with rich text | 4 | ** Implementation of the internal Qt classes dealing with rich text |
5 | ** | 5 | ** |
6 | ** Created : 990101 | 6 | ** Created : 990101 |
7 | ** | 7 | ** |
8 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. | 8 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. |
9 | ** | 9 | ** |
10 | ** This file is part of the kernel module of the Qt GUI Toolkit. | 10 | ** This file is part of the kernel module of the Qt GUI Toolkit. |
11 | ** | 11 | ** |
12 | ** This file may be distributed under the terms of the Q Public License | 12 | ** This file may be distributed under the terms of the Q Public License |
13 | ** as defined by Trolltech AS of Norway and appearing in the file | 13 | ** as defined by Trolltech AS of Norway and appearing in the file |
14 | ** LICENSE.QPL included in the packaging of this file. | 14 | ** LICENSE.QPL included in the packaging of this file. |
15 | ** | 15 | ** |
16 | ** This file may be distributed and/or modified under the terms of the | 16 | ** This file may be distributed and/or modified under the terms of the |
17 | ** GNU General Public License version 2 as published by the Free Software | 17 | ** GNU General Public License version 2 as published by the Free Software |
18 | ** Foundation and appearing in the file LICENSE.GPL included in the | 18 | ** Foundation and appearing in the file LICENSE.GPL included in the |
19 | ** packaging of this file. | 19 | ** packaging of this file. |
20 | ** | 20 | ** |
21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition | 21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition |
22 | ** licenses may use this file in accordance with the Qt Commercial License | 22 | ** licenses may use this file in accordance with the Qt Commercial License |
23 | ** Agreement provided with the Software. | 23 | ** Agreement provided with the Software. |
24 | ** | 24 | ** |
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
27 | ** | 27 | ** |
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | 28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for |
29 | ** information about Qt Commercial License Agreements. | 29 | ** information about Qt Commercial License Agreements. |
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | 30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. |
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
32 | ** | 32 | ** |
33 | ** Contact info@trolltech.com if any conditions of this licensing are | 33 | ** Contact info@trolltech.com if any conditions of this licensing are |
34 | ** not clear to you. | 34 | ** not clear to you. |
35 | ** | 35 | ** |
36 | **********************************************************************/ | 36 | **********************************************************************/ |
37 | 37 | ||
38 | #include "qrichtext_p.h" | 38 | #include "qrichtext_p.h" |
39 | 39 | ||
40 | /* OPIE */ | 40 | /* OPIE */ |
41 | #include <opie2/odebug.h> | 41 | #include <opie2/odebug.h> |
42 | using namespace Opie::Core; | 42 | using namespace Opie::Core; |
43 | 43 | ||
44 | /* QT */ | 44 | /* QT */ |
45 | #include "qdragobject.h" | 45 | #include "qdragobject.h" |
46 | #include "qpaintdevicemetrics.h" | 46 | #include "qpaintdevicemetrics.h" |
47 | #include "qdrawutil.h" | 47 | #include "qdrawutil.h" |
48 | #include "qcleanuphandler.h" | 48 | #include "qcleanuphandler.h" |
49 | 49 | ||
50 | /* STD */ | 50 | /* STD */ |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> |
52 | 52 | ||
53 | using namespace Qt3; | 53 | using namespace Qt3; |
54 | 54 | ||
55 | static QTextCursor* richTextExportStart = 0; | 55 | static QTextCursor* richTextExportStart = 0; |
56 | static QTextCursor* richTextExportEnd = 0; | 56 | static QTextCursor* richTextExportEnd = 0; |
57 | 57 | ||
58 | static QTextFormatCollection *qFormatCollection = 0; | 58 | static QTextFormatCollection *qFormatCollection = 0; |
59 | 59 | ||
60 | const int border_tolerance = 2; | 60 | const int border_tolerance = 2; |
61 | 61 | ||
62 | #ifdef Q_WS_WIN | 62 | #ifdef Q_WS_WIN |
63 | #include "qt_windows.h" | 63 | #include "qt_windows.h" |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | #define QChar_linesep QChar(0x2028U) | 66 | #define QChar_linesep QChar(0x2028U) |
67 | 67 | ||
68 | static inline bool is_printer( QPainter *p ) | 68 | static inline bool is_printer( QPainter *p ) |
69 | { | 69 | { |
70 | if ( !p || !p->device() ) | 70 | if ( !p || !p->device() ) |
71 | return FALSE; | 71 | return FALSE; |
72 | return p->device()->devType() == QInternal::Printer; | 72 | return p->device()->devType() == QInternal::Printer; |
73 | } | 73 | } |
74 | 74 | ||
75 | static inline int scale( int value, QPainter *painter ) | 75 | static inline int scale( int value, QPainter *painter ) |
76 | { | 76 | { |
77 | if ( is_printer( painter ) ) { | 77 | if ( is_printer( painter ) ) { |
78 | QPaintDeviceMetrics metrics( painter->device() ); | 78 | QPaintDeviceMetrics metrics( painter->device() ); |
79 | #if defined(Q_WS_X11) | 79 | #if defined(Q_WS_X11) |
80 | value = value * metrics.logicalDpiY() / QPaintDevice::x11AppDpiY(); | 80 | value = value * metrics.logicalDpiY() / QPaintDevice::x11AppDpiY(); |
81 | #elif defined (Q_WS_WIN) | 81 | #elif defined (Q_WS_WIN) |
82 | HDC hdc = GetDC( 0 ); | 82 | HDC hdc = GetDC( 0 ); |
83 | int gdc = GetDeviceCaps( hdc, LOGPIXELSY ); | 83 | int gdc = GetDeviceCaps( hdc, LOGPIXELSY ); |
84 | if ( gdc ) | 84 | if ( gdc ) |
85 | value = value * metrics.logicalDpiY() / gdc; | 85 | value = value * metrics.logicalDpiY() / gdc; |
86 | ReleaseDC( 0, hdc ); | 86 | ReleaseDC( 0, hdc ); |
87 | #elif defined (Q_WS_MAC) | 87 | #elif defined (Q_WS_MAC) |
88 | value = value * metrics.logicalDpiY() / 75; // ##### FIXME | 88 | value = value * metrics.logicalDpiY() / 75; // ##### FIXME |
89 | #elif defined (Q_WS_QWS) | 89 | #elif defined (Q_WS_QWS) |
90 | value = value * metrics.logicalDpiY() / 75; | 90 | value = value * metrics.logicalDpiY() / 75; |
91 | #endif | 91 | #endif |
92 | } | 92 | } |
93 | return value; | 93 | return value; |
94 | } | 94 | } |
95 | 95 | ||
96 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 96 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
97 | 97 | ||
98 | void QTextCommandHistory::addCommand( QTextCommand *cmd ) | 98 | void QTextCommandHistory::addCommand( QTextCommand *cmd ) |
99 | { | 99 | { |
100 | if ( current < (int)history.count() - 1 ) { | 100 | if ( current < (int)history.count() - 1 ) { |
101 | QPtrList<QTextCommand> commands; | 101 | QPtrList<QTextCommand> commands; |
102 | commands.setAutoDelete( FALSE ); | 102 | commands.setAutoDelete( FALSE ); |
103 | 103 | ||
104 | for( int i = 0; i <= current; ++i ) { | 104 | for( int i = 0; i <= current; ++i ) { |
105 | commands.insert( i, history.at( 0 ) ); | 105 | commands.insert( i, history.at( 0 ) ); |
106 | history.take( 0 ); | 106 | history.take( 0 ); |
107 | } | 107 | } |
108 | 108 | ||
109 | commands.append( cmd ); | 109 | commands.append( cmd ); |
110 | history.clear(); | 110 | history.clear(); |
111 | history = commands; | 111 | history = commands; |
112 | history.setAutoDelete( TRUE ); | 112 | history.setAutoDelete( TRUE ); |
113 | } else { | 113 | } else { |
114 | history.append( cmd ); | 114 | history.append( cmd ); |
115 | } | 115 | } |
116 | 116 | ||
117 | if ( (int)history.count() > steps ) | 117 | if ( (int)history.count() > steps ) |
118 | history.removeFirst(); | 118 | history.removeFirst(); |
119 | else | 119 | else |
120 | ++current; | 120 | ++current; |
121 | } | 121 | } |
122 | 122 | ||
123 | QTextCursor *QTextCommandHistory::undo( QTextCursor *c ) | 123 | QTextCursor *QTextCommandHistory::undo( QTextCursor *c ) |
124 | { | 124 | { |
125 | if ( current > -1 ) { | 125 | if ( current > -1 ) { |
126 | QTextCursor *c2 = history.at( current )->unexecute( c ); | 126 | QTextCursor *c2 = history.at( current )->unexecute( c ); |
127 | --current; | 127 | --current; |
128 | return c2; | 128 | return c2; |
129 | } | 129 | } |
130 | return 0; | 130 | return 0; |
131 | } | 131 | } |
132 | 132 | ||
133 | QTextCursor *QTextCommandHistory::redo( QTextCursor *c ) | 133 | QTextCursor *QTextCommandHistory::redo( QTextCursor *c ) |
134 | { | 134 | { |
135 | if ( current > -1 ) { | 135 | if ( current > -1 ) { |
136 | if ( current < (int)history.count() - 1 ) { | 136 | if ( current < (int)history.count() - 1 ) { |
137 | ++current; | 137 | ++current; |
138 | return history.at( current )->execute( c ); | 138 | return history.at( current )->execute( c ); |
139 | } | 139 | } |
140 | } else { | 140 | } else { |
141 | if ( history.count() > 0 ) { | 141 | if ( history.count() > 0 ) { |
142 | ++current; | 142 | ++current; |
143 | return history.at( current )->execute( c ); | 143 | return history.at( current )->execute( c ); |
144 | } | 144 | } |
145 | } | 145 | } |
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | bool QTextCommandHistory::isUndoAvailable() | 149 | bool QTextCommandHistory::isUndoAvailable() |
150 | { | 150 | { |
151 | return current > -1; | 151 | return current > -1; |
152 | } | 152 | } |
153 | 153 | ||
154 | bool QTextCommandHistory::isRedoAvailable() | 154 | bool QTextCommandHistory::isRedoAvailable() |
155 | { | 155 | { |
156 | return current > -1 && current < (int)history.count() - 1 || current == -1 && history.count() > 0; | 156 | return current > -1 && current < (int)history.count() - 1 || current == -1 && history.count() > 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 159 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
160 | 160 | ||
161 | QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, | 161 | QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str, |
162 | const QByteArray& oldStyleInfo ) | 162 | const QByteArray& oldStyleInfo ) |
163 | : QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo ) | 163 | : QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo ) |
164 | { | 164 | { |
165 | for ( int j = 0; j < (int)text.size(); ++j ) { | 165 | for ( int j = 0; j < (int)text.size(); ++j ) { |
166 | if ( text[ j ].format() ) | 166 | if ( text[ j ].format() ) |
167 | text[ j ].format()->addRef(); | 167 | text[ j ].format()->addRef(); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str ) | 171 | QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str ) |
172 | : QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str ) | 172 | : QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str ) |
173 | { | 173 | { |
174 | for ( int i = 0; i < (int)text.size(); ++i ) { | 174 | for ( int i = 0; i < (int)text.size(); ++i ) { |
175 | if ( text[ i ].format() ) | 175 | if ( text[ i ].format() ) |
176 | text[ i ].format()->addRef(); | 176 | text[ i ].format()->addRef(); |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | QTextDeleteCommand::~QTextDeleteCommand() | 180 | QTextDeleteCommand::~QTextDeleteCommand() |
181 | { | 181 | { |
182 | for ( int i = 0; i < (int)text.size(); ++i ) { | 182 | for ( int i = 0; i < (int)text.size(); ++i ) { |
183 | if ( text[ i ].format() ) | 183 | if ( text[ i ].format() ) |
184 | text[ i ].format()->removeRef(); | 184 | text[ i ].format()->removeRef(); |
185 | } | 185 | } |
186 | text.resize( 0 ); | 186 | text.resize( 0 ); |
187 | } | 187 | } |
188 | 188 | ||
189 | QTextCursor *QTextDeleteCommand::execute( QTextCursor *c ) | 189 | QTextCursor *QTextDeleteCommand::execute( QTextCursor *c ) |
190 | { | 190 | { |
191 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; | 191 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; |
192 | if ( !s ) { | 192 | if ( !s && doc ) { |
193 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; | 193 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; |
194 | return 0; | 194 | return 0; |
195 | } else if ( !doc ) { | ||
196 | owarn << "No valid doc" << oendl; | ||
197 | return 0; | ||
195 | } | 198 | } |
196 | 199 | ||
197 | cursor.setParagraph( s ); | 200 | cursor.setParagraph( s ); |
198 | cursor.setIndex( index ); | 201 | cursor.setIndex( index ); |
199 | int len = text.size(); | 202 | int len = text.size(); |
200 | if ( c ) | 203 | if ( c ) |
201 | *c = cursor; | 204 | *c = cursor; |
202 | if ( doc ) { | 205 | if ( doc ) { |
203 | doc->setSelectionStart( QTextDocument::Temp, cursor ); | 206 | doc->setSelectionStart( QTextDocument::Temp, cursor ); |
204 | for ( int i = 0; i < len; ++i ) | 207 | for ( int i = 0; i < len; ++i ) |
205 | cursor.gotoNextLetter(); | 208 | cursor.gotoNextLetter(); |
206 | doc->setSelectionEnd( QTextDocument::Temp, cursor ); | 209 | doc->setSelectionEnd( QTextDocument::Temp, cursor ); |
207 | doc->removeSelectedText( QTextDocument::Temp, &cursor ); | 210 | doc->removeSelectedText( QTextDocument::Temp, &cursor ); |
208 | if ( c ) | 211 | if ( c ) |
209 | *c = cursor; | 212 | *c = cursor; |
210 | } else { | 213 | } else { |
211 | s->remove( index, len ); | 214 | s->remove( index, len ); |
212 | } | 215 | } |
213 | 216 | ||
214 | return c; | 217 | return c; |
215 | } | 218 | } |
216 | 219 | ||
217 | QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) | 220 | QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c ) |
218 | { | 221 | { |
219 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; | 222 | QTextParagraph *s = doc ? doc->paragAt( id ) : parag; |
220 | if ( !s ) { | 223 | if ( !s && doc ) { |
221 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; | 224 | owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl; |
222 | return 0; | 225 | return 0; |
226 | } else if ( !doc ) { | ||
227 | owarn << "No valid doc" << oendl; | ||
228 | return 0; | ||
223 | } | 229 | } |
224 | 230 | ||
225 | cursor.setParagraph( s ); | 231 | cursor.setParagraph( s ); |
226 | cursor.setIndex( index ); | 232 | cursor.setIndex( index ); |
227 | QString str = QTextString::toString( text ); | 233 | QString str = QTextString::toString( text ); |
228 | cursor.insert( str, TRUE, &text ); | 234 | cursor.insert( str, TRUE, &text ); |
229 | cursor.setParagraph( s ); | 235 | cursor.setParagraph( s ); |
230 | cursor.setIndex( index ); | 236 | cursor.setIndex( index ); |
231 | if ( c ) { | 237 | if ( c ) { |
232 | c->setParagraph( s ); | 238 | c->setParagraph( s ); |
233 | c->setIndex( index ); | 239 | c->setIndex( index ); |
234 | for ( int i = 0; i < (int)text.size(); ++i ) | 240 | for ( int i = 0; i < (int)text.size(); ++i ) |
235 | c->gotoNextLetter(); | 241 | c->gotoNextLetter(); |
242 | } else { | ||
243 | owarn << "No valid cursor" << oendl; | ||
244 | return 0; | ||
236 | } | 245 | } |
237 | 246 | ||
238 | if ( !styleInformation.isEmpty() ) { | 247 | if ( !styleInformation.isEmpty() ) { |
239 | QDataStream styleStream( styleInformation, IO_ReadOnly ); | 248 | QDataStream styleStream( styleInformation, IO_ReadOnly ); |
240 | int num; | 249 | int num; |
241 | styleStream >> num; | 250 | styleStream >> num; |
242 | QTextParagraph *p = s; | 251 | QTextParagraph *p = s; |
243 | while ( num-- && p ) { | 252 | while ( num-- && p ) { |
244 | p->readStyleInformation( styleStream ); | 253 | p->readStyleInformation( styleStream ); |
245 | p = p->next(); | 254 | p = p->next(); |
246 | } | 255 | } |
247 | } | 256 | } |
248 | s = cursor.paragraph(); | 257 | s = cursor.paragraph(); |
249 | while ( s ) { | 258 | while ( s ) { |
250 | s->format(); | 259 | s->format(); |
251 | s->setChanged( TRUE ); | 260 | s->setChanged( TRUE ); |
252 | if ( s == c->paragraph() ) | 261 | if ( s == c->paragraph() ) |
253 | break; | 262 | break; |
254 | s = s->next(); | 263 | s = s->next(); |
255 | } | 264 | } |
256 | 265 | ||
257 | return &cursor; | 266 | return &cursor; |
258 | } | 267 | } |
259 | 268 | ||
260 | QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, | 269 | QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx, |
261 | const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl ) | 270 | const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl ) |
262 | : QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl ) | 271 | : QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl ) |
263 | { | 272 | { |
264 | format = d->formatCollection()->format( f ); | 273 | format = d->formatCollection()->format( f ); |
265 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { | 274 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { |
266 | if ( oldFormats[ j ].format() ) | 275 | if ( oldFormats[ j ].format() ) |
267 | oldFormats[ j ].format()->addRef(); | 276 | oldFormats[ j ].format()->addRef(); |
268 | } | 277 | } |
269 | } | 278 | } |
270 | 279 | ||
271 | QTextFormatCommand::~QTextFormatCommand() | 280 | QTextFormatCommand::~QTextFormatCommand() |
272 | { | 281 | { |
273 | format->removeRef(); | 282 | format->removeRef(); |
274 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { | 283 | for ( int j = 0; j < (int)oldFormats.size(); ++j ) { |
275 | if ( oldFormats[ j ].format() ) | 284 | if ( oldFormats[ j ].format() ) |
276 | oldFormats[ j ].format()->removeRef(); | 285 | oldFormats[ j ].format()->removeRef(); |
277 | } | 286 | } |
278 | } | 287 | } |
279 | 288 | ||
280 | QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) | 289 | QTextCursor *QTextFormatCommand::execute( QTextCursor *c ) |
281 | { | 290 | { |
282 | QTextParagraph *sp = doc->paragAt( startId ); | 291 | QTextParagraph *sp = doc->paragAt( startId ); |
283 | QTextParagraph *ep = doc->paragAt( endId ); | 292 | QTextParagraph *ep = doc->paragAt( endId ); |
284 | if ( !sp || !ep ) | 293 | if ( !sp || !ep ) |
285 | return c; | 294 | return c; |
286 | 295 | ||
287 | QTextCursor start( doc ); | 296 | QTextCursor start( doc ); |
288 | start.setParagraph( sp ); | 297 | start.setParagraph( sp ); |
289 | start.setIndex( startIndex ); | 298 | start.setIndex( startIndex ); |
290 | QTextCursor end( doc ); | 299 | QTextCursor end( doc ); |
291 | end.setParagraph( ep ); | 300 | end.setParagraph( ep ); |
292 | end.setIndex( endIndex ); | 301 | end.setIndex( endIndex ); |
293 | 302 | ||
294 | doc->setSelectionStart( QTextDocument::Temp, start ); | 303 | doc->setSelectionStart( QTextDocument::Temp, start ); |
295 | doc->setSelectionEnd( QTextDocument::Temp, end ); | 304 | doc->setSelectionEnd( QTextDocument::Temp, end ); |
296 | doc->setFormat( QTextDocument::Temp, format, flags ); | 305 | doc->setFormat( QTextDocument::Temp, format, flags ); |
297 | doc->removeSelection( QTextDocument::Temp ); | 306 | doc->removeSelection( QTextDocument::Temp ); |
298 | if ( endIndex == ep->length() ) | 307 | if ( endIndex == ep->length() ) |
299 | end.gotoLeft(); | 308 | end.gotoLeft(); |
300 | *c = end; | 309 | *c = end; |
301 | return c; | 310 | return c; |
302 | } | 311 | } |
303 | 312 | ||
304 | QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) | 313 | QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c ) |
305 | { | 314 | { |
306 | QTextParagraph *sp = doc->paragAt( startId ); | 315 | QTextParagraph *sp = doc->paragAt( startId ); |
307 | QTextParagraph *ep = doc->paragAt( endId ); | 316 | QTextParagraph *ep = doc->paragAt( endId ); |
308 | if ( !sp || !ep ) | 317 | if ( !sp || !ep ) |
309 | return 0; | 318 | return 0; |
310 | 319 | ||
311 | int idx = startIndex; | 320 | int idx = startIndex; |
312 | int fIndex = 0; | 321 | int fIndex = 0; |
313 | for ( ;; ) { | 322 | for ( ;; ) { |
314 | if ( oldFormats.at( fIndex ).c == '\n' ) { | 323 | if ( oldFormats.at( fIndex ).c == '\n' ) { |
315 | if ( idx > 0 ) { | 324 | if ( idx > 0 ) { |
316 | if ( idx < sp->length() && fIndex > 0 ) | 325 | if ( idx < sp->length() && fIndex > 0 ) |
317 | sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() ); | 326 | sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() ); |
318 | if ( sp == ep ) | 327 | if ( sp == ep ) |
319 | break; | 328 | break; |
320 | sp = sp->next(); | 329 | sp = sp->next(); |
321 | idx = 0; | 330 | idx = 0; |
322 | } | 331 | } |
323 | fIndex++; | 332 | fIndex++; |
324 | } | 333 | } |
325 | if ( oldFormats.at( fIndex ).format() ) | 334 | if ( oldFormats.at( fIndex ).format() ) |
326 | sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() ); | 335 | sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() ); |
327 | idx++; | 336 | idx++; |
328 | fIndex++; | 337 | fIndex++; |
329 | if ( fIndex >= (int)oldFormats.size() ) | 338 | if ( fIndex >= (int)oldFormats.size() ) |
330 | break; | 339 | break; |
331 | if ( idx >= sp->length() ) { | 340 | if ( idx >= sp->length() ) { |
332 | if ( sp == ep ) | 341 | if ( sp == ep ) |
333 | break; | 342 | break; |
334 | sp = sp->next(); | 343 | sp = sp->next(); |
335 | idx = 0; | 344 | idx = 0; |
336 | } | 345 | } |
337 | } | 346 | } |
338 | 347 | ||
339 | QTextCursor end( doc ); | 348 | QTextCursor end( doc ); |
340 | end.setParagraph( ep ); | 349 | end.setParagraph( ep ); |
341 | end.setIndex( endIndex ); | 350 | end.setIndex( endIndex ); |
342 | if ( endIndex == ep->length() ) | 351 | if ( endIndex == ep->length() ) |
343 | end.gotoLeft(); | 352 | end.gotoLeft(); |
344 | *c = end; | 353 | *c = end; |
345 | return c; | 354 | return c; |
346 | } | 355 | } |
347 | 356 | ||
348 | QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange ) | 357 | QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange ) |
349 | : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange ) | 358 | : QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange ) |
350 | { | 359 | { |
351 | after = readStyleInformation( d, fParag, lParag ); | 360 | after = readStyleInformation( d, fParag, lParag ); |
352 | } | 361 | } |
353 | 362 | ||
354 | 363 | ||
355 | QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag ) | 364 | QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag ) |
356 | { | 365 | { |
357 | QByteArray style; | 366 | QByteArray style; |
358 | QTextParagraph *p = doc->paragAt( fParag ); | 367 | QTextParagraph *p = doc->paragAt( fParag ); |
359 | if ( !p ) | 368 | if ( !p ) |
360 | return style; | 369 | return style; |
361 | QDataStream styleStream( style, IO_WriteOnly ); | 370 | QDataStream styleStream( style, IO_WriteOnly ); |
362 | int num = lParag - fParag + 1; | 371 | int num = lParag - fParag + 1; |
363 | styleStream << num; | 372 | styleStream << num; |
364 | while ( num -- && p ) { | 373 | while ( num -- && p ) { |
365 | p->writeStyleInformation( styleStream ); | 374 | p->writeStyleInformation( styleStream ); |
366 | p = p->next(); | 375 | p = p->next(); |
367 | } | 376 | } |
368 | return style; | 377 | return style; |
369 | } | 378 | } |
370 | 379 | ||
371 | void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style ) | 380 | void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style ) |
372 | { | 381 | { |
373 | QTextParagraph *p = doc->paragAt( fParag ); | 382 | QTextParagraph *p = doc->paragAt( fParag ); |
374 | if ( !p ) | 383 | if ( !p ) |
375 | return; | 384 | return; |
376 | QDataStream styleStream( style, IO_ReadOnly ); | 385 | QDataStream styleStream( style, IO_ReadOnly ); |
377 | int num; | 386 | int num; |
378 | styleStream >> num; | 387 | styleStream >> num; |
379 | while ( num-- && p ) { | 388 | while ( num-- && p ) { |
380 | p->readStyleInformation( styleStream ); | 389 | p->readStyleInformation( styleStream ); |
381 | p = p->next(); | 390 | p = p->next(); |
382 | } | 391 | } |
383 | } | 392 | } |
384 | 393 | ||
385 | QTextCursor *QTextStyleCommand::execute( QTextCursor *c ) | 394 | QTextCursor *QTextStyleCommand::execute( QTextCursor *c ) |
386 | { | 395 | { |
387 | writeStyleInformation( doc, firstParag, after ); | 396 | writeStyleInformation( doc, firstParag, after ); |
388 | return c; | 397 | return c; |
389 | } | 398 | } |
390 | 399 | ||
391 | QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c ) | 400 | QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c ) |
392 | { | 401 | { |
393 | writeStyleInformation( doc, firstParag, before ); | 402 | writeStyleInformation( doc, firstParag, before ); |
394 | return c; | 403 | return c; |
395 | } | 404 | } |
396 | 405 | ||
397 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 406 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
398 | 407 | ||
399 | QTextCursor::QTextCursor( QTextDocument *d ) | 408 | QTextCursor::QTextCursor( QTextDocument *d ) |
400 | : idx( 0 ), tmpIndex( -1 ), ox( 0 ), oy( 0 ), | 409 | : idx( 0 ), tmpIndex( -1 ), ox( 0 ), oy( 0 ), |
401 | valid( TRUE ) | 410 | valid( TRUE ) |
402 | { | 411 | { |
403 | para = d ? d->firstParagraph() : 0; | 412 | para = d ? d->firstParagraph() : 0; |
404 | } | 413 | } |
405 | 414 | ||
406 | QTextCursor::QTextCursor( const QTextCursor &c ) | 415 | QTextCursor::QTextCursor( const QTextCursor &c ) |
407 | { | 416 | { |
408 | ox = c.ox; | 417 | ox = c.ox; |
409 | oy = c.oy; | 418 | oy = c.oy; |
410 | idx = c.idx; | 419 | idx = c.idx; |
411 | para = c.para; | 420 | para = c.para; |
412 | tmpIndex = c.tmpIndex; | 421 | tmpIndex = c.tmpIndex; |
413 | indices = c.indices; | 422 | indices = c.indices; |
414 | paras = c.paras; | 423 | paras = c.paras; |
415 | xOffsets = c.xOffsets; | 424 | xOffsets = c.xOffsets; |
416 | yOffsets = c.yOffsets; | 425 | yOffsets = c.yOffsets; |
417 | valid = c.valid; | 426 | valid = c.valid; |
418 | } | 427 | } |
419 | 428 | ||
420 | QTextCursor &QTextCursor::operator=( const QTextCursor &c ) | 429 | QTextCursor &QTextCursor::operator=( const QTextCursor &c ) |
421 | { | 430 | { |
422 | ox = c.ox; | 431 | ox = c.ox; |
423 | oy = c.oy; | 432 | oy = c.oy; |
424 | idx = c.idx; | 433 | idx = c.idx; |
425 | para = c.para; | 434 | para = c.para; |
426 | tmpIndex = c.tmpIndex; | 435 | tmpIndex = c.tmpIndex; |
427 | indices = c.indices; | 436 | indices = c.indices; |
428 | paras = c.paras; | 437 | paras = c.paras; |
429 | xOffsets = c.xOffsets; | 438 | xOffsets = c.xOffsets; |
430 | yOffsets = c.yOffsets; | 439 | yOffsets = c.yOffsets; |
431 | valid = c.valid; | 440 | valid = c.valid; |
432 | 441 | ||
433 | return *this; | 442 | return *this; |
434 | } | 443 | } |
435 | 444 | ||
436 | bool QTextCursor::operator==( const QTextCursor &c ) const | 445 | bool QTextCursor::operator==( const QTextCursor &c ) const |
437 | { | 446 | { |
438 | return para == c.para && idx == c.idx; | 447 | return para == c.para && idx == c.idx; |
439 | } | 448 | } |
440 | 449 | ||
441 | int QTextCursor::totalOffsetX() const | 450 | int QTextCursor::totalOffsetX() const |
442 | { | 451 | { |
443 | int xoff = ox; | 452 | int xoff = ox; |
444 | for ( QValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit ) | 453 | for ( QValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit ) |
445 | xoff += *xit; | 454 | xoff += *xit; |
446 | return xoff; | 455 | return xoff; |
447 | } | 456 | } |
448 | 457 | ||
449 | int QTextCursor::totalOffsetY() const | 458 | int QTextCursor::totalOffsetY() const |
450 | { | 459 | { |
451 | int yoff = oy; | 460 | int yoff = oy; |
452 | for ( QValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit ) | 461 | for ( QValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit ) |
453 | yoff += *yit; | 462 | yoff += *yit; |
454 | return yoff; | 463 | return yoff; |
455 | } | 464 | } |
456 | 465 | ||
457 | void QTextCursor::gotoIntoNested( const QPoint &globalPos ) | 466 | void QTextCursor::gotoIntoNested( const QPoint &globalPos ) |
458 | { | 467 | { |
459 | if ( !para ) | 468 | if ( !para ) |
460 | return; | 469 | return; |
461 | push(); | 470 | push(); |
462 | ox = 0; | 471 | ox = 0; |
463 | int bl, y; | 472 | int bl, y; |
464 | para->lineHeightOfChar( idx, &bl, &y ); | 473 | para->lineHeightOfChar( idx, &bl, &y ); |
465 | oy = y + para->rect().y(); | 474 | oy = y + para->rect().y(); |
466 | QPoint p( globalPos.x() - offsetX(), globalPos.y() - offsetY() ); | 475 | QPoint p( globalPos.x() - offsetX(), globalPos.y() - offsetY() ); |
467 | Q_ASSERT( para->at( idx )->isCustom() ); | 476 | Q_ASSERT( para->at( idx )->isCustom() ); |
468 | ox = para->at( idx )->x; | 477 | ox = para->at( idx )->x; |
469 | 478 | ||
470 | QTextDocument* doc = document(); | 479 | QTextDocument* doc = document(); |
471 | para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, p ); | 480 | para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, p ); |
472 | } | 481 | } |
473 | 482 | ||
474 | void QTextCursor::invalidateNested() | 483 | void QTextCursor::invalidateNested() |
475 | { | 484 | { |
476 | QValueStack<QTextParagraph*>::Iterator it = paras.begin(); | 485 | QValueStack<QTextParagraph*>::Iterator it = paras.begin(); |
477 | QValueStack<int>::Iterator it2 = indices.begin(); | 486 | QValueStack<int>::Iterator it2 = indices.begin(); |
478 | for ( ; it != paras.end(); ++it, ++it2 ) { | 487 | for ( ; it != paras.end(); ++it, ++it2 ) { |
479 | if ( *it == para ) | 488 | if ( *it == para ) |
480 | continue; | 489 | continue; |
481 | (*it)->invalidate( 0 ); | 490 | (*it)->invalidate( 0 ); |
482 | if ( (*it)->at( *it2 )->isCustom() ) | 491 | if ( (*it)->at( *it2 )->isCustom() ) |
483 | (*it)->at( *it2 )->customItem()->invalidate(); | 492 | (*it)->at( *it2 )->customItem()->invalidate(); |
484 | } | 493 | } |
485 | } | 494 | } |
486 | 495 | ||
487 | void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QTextStringChar> *formatting ) | 496 | void QTextCursor::insert( const QString &str, bool checkNewLine, QMemArray<QTextStringChar> *formatting ) |
488 | { | 497 | { |
489 | tmpIndex = -1; | 498 | tmpIndex = -1; |
490 | bool justInsert = TRUE; | 499 | bool justInsert = TRUE; |
491 | QString s( str ); | 500 | QString s( str ); |
492 | #if defined(Q_WS_WIN) | 501 | #if defined(Q_WS_WIN) |
493 | if ( checkNewLine ) { | 502 | if ( checkNewLine ) { |
494 | int i = 0; | 503 | int i = 0; |
495 | while ( ( i = s.find( '\r', i ) ) != -1 ) | 504 | while ( ( i = s.find( '\r', i ) ) != -1 ) |
496 | s.remove( i ,1 ); | 505 | s.remove( i ,1 ); |
497 | } | 506 | } |
498 | #endif | 507 | #endif |
499 | if ( checkNewLine ) | 508 | if ( checkNewLine ) |
500 | justInsert = s.find( '\n' ) == -1; | 509 | justInsert = s.find( '\n' ) == -1; |
501 | if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index | 510 | if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index |
502 | para->insert( idx, s.unicode(), s.length() ); | 511 | para->insert( idx, s.unicode(), s.length() ); |
503 | if ( formatting ) { | 512 | if ( formatting ) { |
504 | for ( int i = 0; i < (int)s.length(); ++i ) { | 513 | for ( int i = 0; i < (int)s.length(); ++i ) { |
505 | if ( formatting->at( i ).format() ) { | 514 | if ( formatting->at( i ).format() ) { |
506 | formatting->at( i ).format()->addRef(); | 515 | formatting->at( i ).format()->addRef(); |
507 | para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE ); | 516 | para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE ); |
508 | } | 517 | } |
509 | } | 518 | } |
510 | } | 519 | } |
511 | idx += s.length(); | 520 | idx += s.length(); |
512 | } else { // we split at new lines | 521 | } else { // we split at new lines |
513 | int start = -1; | 522 | int start = -1; |
514 | int end; | 523 | int end; |
515 | int y = para->rect().y() + para->rect().height(); | 524 | int y = para->rect().y() + para->rect().height(); |
516 | int lastIndex = 0; | 525 | int lastIndex = 0; |
517 | do { | 526 | do { |
518 | end = s.find( '\n', start + 1 ); // find line break | 527 | end = s.find( '\n', start + 1 ); // find line break |
519 | if ( end == -1 ) // didn't find one, so end of line is end of string | 528 | if ( end == -1 ) // didn't find one, so end of line is end of string |
520 | end = s.length(); | 529 | end = s.length(); |
521 | int len = (start == -1 ? end : end - start - 1); | 530 | int len = (start == -1 ? end : end - start - 1); |
522 | if ( len > 0 ) // insert the line | 531 | if ( len > 0 ) // insert the line |
523 | para->insert( idx, s.unicode() + start + 1, len ); | 532 | para->insert( idx, s.unicode() + start + 1, len ); |
524 | else | 533 | else |
525 | para->invalidate( 0 ); | 534 | para->invalidate( 0 ); |
526 | if ( formatting ) { // set formats to the chars of the line | 535 | if ( formatting ) { // set formats to the chars of the line |
527 | for ( int i = 0; i < len; ++i ) { | 536 | for ( int i = 0; i < len; ++i ) { |
528 | if ( formatting->at( i + lastIndex ).format() ) { | 537 | if ( formatting->at( i + lastIndex ).format() ) { |
529 | formatting->at( i + lastIndex ).format()->addRef(); | 538 | formatting->at( i + lastIndex ).format()->addRef(); |
530 | para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE ); | 539 | para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE ); |
531 | } | 540 | } |
532 | } | 541 | } |
533 | lastIndex += len; | 542 | lastIndex += len; |
534 | } | 543 | } |
535 | start = end; // next start is at the end of this line | 544 | start = end; // next start is at the end of this line |
536 | idx += len; // increase the index of the cursor to the end of the inserted text | 545 | idx += len; // increase the index of the cursor to the end of the inserted text |
537 | if ( s[end] == '\n' ) { // if at the end was a line break, break the line | 546 | if ( s[end] == '\n' ) { // if at the end was a line break, break the line |
538 | splitAndInsertEmptyParagraph( FALSE, TRUE ); | 547 | splitAndInsertEmptyParagraph( FALSE, TRUE ); |
539 | para->setEndState( -1 ); | 548 | para->setEndState( -1 ); |
540 | para->prev()->format( -1, FALSE ); | 549 | para->prev()->format( -1, FALSE ); |
541 | lastIndex++; | 550 | lastIndex++; |
542 | } | 551 | } |
543 | 552 | ||
544 | } while ( end < (int)s.length() ); | 553 | } while ( end < (int)s.length() ); |
545 | 554 | ||
546 | para->format( -1, FALSE ); | 555 | para->format( -1, FALSE ); |
547 | int dy = para->rect().y() + para->rect().height() - y; | 556 | int dy = para->rect().y() + para->rect().height() - y; |
548 | QTextParagraph *p = para; | 557 | QTextParagraph *p = para; |
549 | p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 ); | 558 | p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 ); |
550 | p = p->next(); | 559 | p = p->next(); |
551 | while ( p ) { | 560 | while ( p ) { |
552 | p->setParagId( p->prev()->paragId() + 1 ); | 561 | p->setParagId( p->prev()->paragId() + 1 ); |
553 | p->move( dy ); | 562 | p->move( dy ); |
554 | p->invalidate( 0 ); | 563 | p->invalidate( 0 ); |
555 | p->setEndState( -1 ); | 564 | p->setEndState( -1 ); |
556 | p = p->next(); | 565 | p = p->next(); |
557 | } | 566 | } |
558 | } | 567 | } |
559 | 568 | ||
560 | int h = para->rect().height(); | 569 | int h = para->rect().height(); |
561 | para->format( -1, TRUE ); | 570 | para->format( -1, TRUE ); |
562 | if ( h != para->rect().height() ) | 571 | if ( h != para->rect().height() ) |
563 | invalidateNested(); | 572 | invalidateNested(); |
564 | else if ( para->document() && para->document()->parent() ) | 573 | else if ( para->document() && para->document()->parent() ) |
565 | para->document()->nextDoubleBuffered = TRUE; | 574 | para->document()->nextDoubleBuffered = TRUE; |
566 | } | 575 | } |
567 | 576 | ||
568 | void QTextCursor::gotoLeft() | 577 | void QTextCursor::gotoLeft() |
569 | { | 578 | { |
570 | if ( para->string()->isRightToLeft() ) | 579 | if ( para->string()->isRightToLeft() ) |
571 | gotoNextLetter(); | 580 | gotoNextLetter(); |
572 | else | 581 | else |
573 | gotoPreviousLetter(); | 582 | gotoPreviousLetter(); |
574 | } | 583 | } |
575 | 584 | ||
576 | void QTextCursor::gotoPreviousLetter() | 585 | void QTextCursor::gotoPreviousLetter() |
577 | { | 586 | { |
578 | tmpIndex = -1; | 587 | tmpIndex = -1; |
579 | 588 | ||
580 | if ( idx > 0 ) { | 589 | if ( idx > 0 ) { |
581 | idx--; | 590 | idx--; |
582 | const QTextStringChar *tsc = para->at( idx ); | 591 | const QTextStringChar *tsc = para->at( idx ); |
583 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) | 592 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) |
584 | processNesting( EnterEnd ); | 593 | processNesting( EnterEnd ); |
585 | } else if ( para->prev() ) { | 594 | } else if ( para->prev() ) { |
586 | para = para->prev(); | 595 | para = para->prev(); |
587 | while ( !para->isVisible() && para->prev() ) | 596 | while ( !para->isVisible() && para->prev() ) |
588 | para = para->prev(); | 597 | para = para->prev(); |
589 | idx = para->length() - 1; | 598 | idx = para->length() - 1; |
590 | } else if ( nestedDepth() ) { | 599 | } else if ( nestedDepth() ) { |
591 | pop(); | 600 | pop(); |
592 | processNesting( Prev ); | 601 | processNesting( Prev ); |
593 | if ( idx == -1 ) { | 602 | if ( idx == -1 ) { |
594 | pop(); | 603 | pop(); |
595 | if ( idx > 0 ) { | 604 | if ( idx > 0 ) { |
596 | idx--; | 605 | idx--; |
597 | } else if ( para->prev() ) { | 606 | } else if ( para->prev() ) { |
598 | para = para->prev(); | 607 | para = para->prev(); |
599 | idx = para->length() - 1; | 608 | idx = para->length() - 1; |
600 | } | 609 | } |
601 | } | 610 | } |
602 | } | 611 | } |
603 | } | 612 | } |
604 | 613 | ||
605 | void QTextCursor::push() | 614 | void QTextCursor::push() |
606 | { | 615 | { |
607 | indices.push( idx ); | 616 | indices.push( idx ); |
608 | paras.push( para ); | 617 | paras.push( para ); |
609 | xOffsets.push( ox ); | 618 | xOffsets.push( ox ); |
610 | yOffsets.push( oy ); | 619 | yOffsets.push( oy ); |
611 | } | 620 | } |
612 | 621 | ||
613 | void QTextCursor::pop() | 622 | void QTextCursor::pop() |
614 | { | 623 | { |
615 | if ( indices.isEmpty() ) | 624 | if ( indices.isEmpty() ) |
616 | return; | 625 | return; |
617 | idx = indices.pop(); | 626 | idx = indices.pop(); |
618 | para = paras.pop(); | 627 | para = paras.pop(); |
619 | ox = xOffsets.pop(); | 628 | ox = xOffsets.pop(); |
620 | oy = yOffsets.pop(); | 629 | oy = yOffsets.pop(); |
621 | } | 630 | } |
622 | 631 | ||
623 | void QTextCursor::restoreState() | 632 | void QTextCursor::restoreState() |
624 | { | 633 | { |
625 | while ( !indices.isEmpty() ) | 634 | while ( !indices.isEmpty() ) |
626 | pop(); | 635 | pop(); |
627 | } | 636 | } |
628 | 637 | ||
629 | bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link ) | 638 | bool QTextCursor::place( const QPoint &p, QTextParagraph *s, bool link ) |
630 | { | 639 | { |
631 | QPoint pos( p ); | 640 | QPoint pos( p ); |
632 | QRect r; | 641 | QRect r; |
633 | QTextParagraph *str = s; | 642 | QTextParagraph *str = s; |
634 | if ( pos.y() < s->rect().y() ) | 643 | if ( pos.y() < s->rect().y() ) |
635 | pos.setY( s->rect().y() ); | 644 | pos.setY( s->rect().y() ); |
636 | while ( s ) { | 645 | while ( s ) { |
637 | r = s->rect(); | 646 | r = s->rect(); |
638 | r.setWidth( document() ? document()->width() : QWIDGETSIZE_MAX ); | 647 | r.setWidth( document() ? document()->width() : QWIDGETSIZE_MAX ); |
639 | if ( s->isVisible() ) | 648 | if ( s->isVisible() ) |
640 | str = s; | 649 | str = s; |
641 | if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() || !s->next() ) | 650 | if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() || !s->next() ) |
642 | break; | 651 | break; |
643 | s = s->next(); | 652 | s = s->next(); |
644 | } | 653 | } |
645 | 654 | ||
646 | if ( !s || !str ) | 655 | if ( !s || !str ) |
647 | return FALSE; | 656 | return FALSE; |
648 | 657 | ||
649 | s = str; | 658 | s = str; |
650 | 659 | ||
651 | setParagraph( s ); | 660 | setParagraph( s ); |
652 | int y = s->rect().y(); | 661 | int y = s->rect().y(); |
653 | int lines = s->lines(); | 662 | int lines = s->lines(); |
654 | QTextStringChar *chr = 0; | 663 | QTextStringChar *chr = 0; |
655 | int index = 0; | 664 | int index = 0; |
656 | int i = 0; | 665 | int i = 0; |
657 | int cy = 0; | 666 | int cy = 0; |
658 | int ch = 0; | 667 | int ch = 0; |
659 | for ( ; i < lines; ++i ) { | 668 | for ( ; i < lines; ++i ) { |
660 | chr = s->lineStartOfLine( i, &index ); | 669 | chr = s->lineStartOfLine( i, &index ); |
661 | cy = s->lineY( i ); | 670 | cy = s->lineY( i ); |
662 | ch = s->lineHeight( i ); | 671 | ch = s->lineHeight( i ); |
663 | if ( !chr ) | 672 | if ( !chr ) |
664 | return FALSE; | 673 | return FALSE; |
665 | if ( pos.y() <= y + cy + ch ) | 674 | if ( pos.y() <= y + cy + ch ) |
666 | break; | 675 | break; |
667 | } | 676 | } |
668 | int nextLine; | 677 | int nextLine; |
669 | if ( i < lines - 1 ) | 678 | if ( i < lines - 1 ) |
670 | s->lineStartOfLine( i+1, &nextLine ); | 679 | s->lineStartOfLine( i+1, &nextLine ); |
671 | else | 680 | else |
672 | nextLine = s->length(); | 681 | nextLine = s->length(); |
673 | i = index; | 682 | i = index; |
674 | int x = s->rect().x(); | 683 | int x = s->rect().x(); |
675 | if ( pos.x() < x ) | 684 | if ( pos.x() < x ) |
676 | pos.setX( x + 1 ); | 685 | pos.setX( x + 1 ); |
677 | int cw; | 686 | int cw; |
678 | int curpos = s->length()-1; | 687 | int curpos = s->length()-1; |
679 | int dist = 10000000; | 688 | int dist = 10000000; |
680 | bool inCustom = FALSE; | 689 | bool inCustom = FALSE; |
681 | while ( i < nextLine ) { | 690 | while ( i < nextLine ) { |
682 | chr = s->at(i); | 691 | chr = s->at(i); |
683 | int cpos = x + chr->x; | 692 | int cpos = x + chr->x; |
684 | cw = s->string()->width( i ); | 693 | cw = s->string()->width( i ); |
685 | if ( chr->isCustom() && chr->customItem()->isNested() ) { | 694 | if ( chr->isCustom() && chr->customItem()->isNested() ) { |
686 | if ( pos.x() >= cpos && pos.x() <= cpos + cw && | 695 | if ( pos.x() >= cpos && pos.x() <= cpos + cw && |
687 | pos.y() >= y + cy && pos.y() <= y + cy + chr->height() ) { | 696 | pos.y() >= y + cy && pos.y() <= y + cy + chr->height() ) { |
688 | inCustom = TRUE; | 697 | inCustom = TRUE; |
689 | curpos = i; | 698 | curpos = i; |
690 | break; | 699 | break; |
691 | } | 700 | } |
692 | } else { | 701 | } else { |
693 | if( chr->rightToLeft ) | 702 | if( chr->rightToLeft ) |
694 | cpos += cw; | 703 | cpos += cw; |
695 | int d = cpos - pos.x(); | 704 | int d = cpos - pos.x(); |
696 | bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft; | 705 | bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft; |
697 | if ( QABS( d ) < dist || (dist == d && dm == TRUE ) ) { | 706 | if ( QABS( d ) < dist || (dist == d && dm == TRUE ) ) { |
698 | dist = QABS( d ); | 707 | dist = QABS( d ); |
699 | if ( !link || pos.x() >= x + chr->x ) | 708 | if ( !link || pos.x() >= x + chr->x ) |
700 | curpos = i; | 709 | curpos = i; |
701 | } | 710 | } |
702 | } | 711 | } |
703 | i++; | 712 | i++; |
704 | } | 713 | } |
705 | setIndex( curpos ); | 714 | setIndex( curpos ); |
706 | 715 | ||
707 | if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) { | 716 | if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) { |
708 | QTextDocument *oldDoc = para->document(); | 717 | QTextDocument *oldDoc = para->document(); |
709 | gotoIntoNested( pos ); | 718 | gotoIntoNested( pos ); |
710 | if ( oldDoc == para->document() ) | 719 | if ( oldDoc == para->document() ) |
711 | return TRUE; | 720 | return TRUE; |
712 | QPoint p( pos.x() - offsetX(), pos.y() - offsetY() ); | 721 | QPoint p( pos.x() - offsetX(), pos.y() - offsetY() ); |
713 | if ( !place( p, document()->firstParagraph(), link ) ) | 722 | if ( !place( p, document()->firstParagraph(), link ) ) |
714 | pop(); | 723 | pop(); |
715 | } | 724 | } |
716 | return TRUE; | 725 | return TRUE; |
717 | } | 726 | } |
718 | 727 | ||
719 | void QTextCursor::processNesting( Operation op ) | 728 | void QTextCursor::processNesting( Operation op ) |
720 | { | 729 | { |
721 | if ( !para->document() ) | 730 | if ( !para->document() ) |
722 | return; | 731 | return; |
723 | QTextDocument* doc = para->document(); | 732 | QTextDocument* doc = para->document(); |
724 | push(); | 733 | push(); |
725 | ox = para->at( idx )->x; | 734 | ox = para->at( idx )->x; |
726 | int bl, y; | 735 | int bl, y; |
727 | para->lineHeightOfChar( idx, &bl, &y ); | 736 | para->lineHeightOfChar( idx, &bl, &y ); |
728 | oy = y + para->rect().y(); | 737 | oy = y + para->rect().y(); |
729 | bool ok = FALSE; | 738 | bool ok = FALSE; |
730 | 739 | ||
731 | switch ( op ) { | 740 | switch ( op ) { |
732 | case EnterBegin: | 741 | case EnterBegin: |
733 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy ); | 742 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy ); |
734 | break; | 743 | break; |
735 | case EnterEnd: | 744 | case EnterEnd: |
736 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE ); | 745 | ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE ); |
737 | break; | 746 | break; |
738 | case Next: | 747 | case Next: |
739 | ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy ); | 748 | ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy ); |
740 | break; | 749 | break; |
741 | case Prev: | 750 | case Prev: |
742 | ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy ); | 751 | ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy ); |
743 | break; | 752 | break; |
744 | case Down: | 753 | case Down: |
745 | ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy ); | 754 | ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy ); |
746 | break; | 755 | break; |
747 | case Up: | 756 | case Up: |
748 | ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy ); | 757 | ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy ); |
749 | break; | 758 | break; |
750 | } | 759 | } |
751 | if ( !ok ) | 760 | if ( !ok ) |
752 | pop(); | 761 | pop(); |
753 | } | 762 | } |
754 | 763 | ||
755 | void QTextCursor::gotoRight() | 764 | void QTextCursor::gotoRight() |
756 | { | 765 | { |
757 | if ( para->string()->isRightToLeft() ) | 766 | if ( para->string()->isRightToLeft() ) |
758 | gotoPreviousLetter(); | 767 | gotoPreviousLetter(); |
759 | else | 768 | else |
760 | gotoNextLetter(); | 769 | gotoNextLetter(); |
761 | } | 770 | } |
762 | 771 | ||
763 | void QTextCursor::gotoNextLetter() | 772 | void QTextCursor::gotoNextLetter() |
764 | { | 773 | { |
765 | tmpIndex = -1; | 774 | tmpIndex = -1; |
766 | 775 | ||
767 | const QTextStringChar *tsc = para->at( idx ); | 776 | const QTextStringChar *tsc = para->at( idx ); |
768 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) { | 777 | if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) { |
769 | processNesting( EnterBegin ); | 778 | processNesting( EnterBegin ); |
770 | return; | 779 | return; |
771 | } | 780 | } |
772 | 781 | ||
773 | if ( idx < para->length() - 1 ) { | 782 | if ( idx < para->length() - 1 ) { |
774 | idx++; | 783 | idx++; |
775 | } else if ( para->next() ) { | 784 | } else if ( para->next() ) { |
776 | para = para->next(); | 785 | para = para->next(); |
777 | while ( !para->isVisible() && para->next() ) | 786 | while ( !para->isVisible() && para->next() ) |
778 | para = para->next(); | 787 | para = para->next(); |
779 | idx = 0; | 788 | idx = 0; |
780 | } else if ( nestedDepth() ) { | 789 | } else if ( nestedDepth() ) { |
781 | pop(); | 790 | pop(); |
782 | processNesting( Next ); | 791 | processNesting( Next ); |
783 | if ( idx == -1 ) { | 792 | if ( idx == -1 ) { |
784 | pop(); | 793 | pop(); |
785 | if ( idx < para->length() - 1 ) { | 794 | if ( idx < para->length() - 1 ) { |
786 | idx++; | 795 | idx++; |
787 | } else if ( para->next() ) { | 796 | } else if ( para->next() ) { |
788 | para = para->next(); | 797 | para = para->next(); |
789 | idx = 0; | 798 | idx = 0; |
790 | } | 799 | } |
791 | } | 800 | } |
792 | } | 801 | } |
793 | } | 802 | } |
794 | 803 | ||
795 | void QTextCursor::gotoUp() | 804 | void QTextCursor::gotoUp() |
796 | { | 805 | { |
797 | int indexOfLineStart; | 806 | int indexOfLineStart; |
798 | int line; | 807 | int line; |
799 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 808 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
800 | if ( !c ) | 809 | if ( !c ) |
801 | return; | 810 | return; |
802 | 811 | ||
803 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); | 812 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); |
804 | if ( indexOfLineStart == 0 ) { | 813 | if ( indexOfLineStart == 0 ) { |
805 | if ( !para->prev() ) { | 814 | if ( !para->prev() ) { |
806 | if ( !nestedDepth() ) | 815 | if ( !nestedDepth() ) |
807 | return; | 816 | return; |
808 | pop(); | 817 | pop(); |
809 | processNesting( Up ); | 818 | processNesting( Up ); |
810 | if ( idx == -1 ) { | 819 | if ( idx == -1 ) { |
811 | pop(); | 820 | pop(); |
812 | if ( !para->prev() ) | 821 | if ( !para->prev() ) |
813 | return; | 822 | return; |
814 | idx = tmpIndex = 0; | 823 | idx = tmpIndex = 0; |
815 | } else { | 824 | } else { |
816 | tmpIndex = -1; | 825 | tmpIndex = -1; |
817 | return; | 826 | return; |
818 | } | 827 | } |
819 | } | 828 | } |
820 | QTextParagraph *p = para->prev(); | 829 | QTextParagraph *p = para->prev(); |
821 | while ( p && !p->isVisible() ) | 830 | while ( p && !p->isVisible() ) |
822 | p = p->prev(); | 831 | p = p->prev(); |
823 | if ( p ) | 832 | if ( p ) |
824 | para = p; | 833 | para = p; |
825 | int lastLine = para->lines() - 1; | 834 | int lastLine = para->lines() - 1; |
826 | if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) ) | 835 | if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) ) |
827 | return; | 836 | return; |
828 | if ( indexOfLineStart + tmpIndex < para->length() ) | 837 | if ( indexOfLineStart + tmpIndex < para->length() ) |
829 | idx = indexOfLineStart + tmpIndex; | 838 | idx = indexOfLineStart + tmpIndex; |
830 | else | 839 | else |
831 | idx = para->length() - 1; | 840 | idx = para->length() - 1; |
832 | } else { | 841 | } else { |
833 | --line; | 842 | --line; |
834 | int oldIndexOfLineStart = indexOfLineStart; | 843 | int oldIndexOfLineStart = indexOfLineStart; |
835 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) | 844 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) |
836 | return; | 845 | return; |
837 | if ( indexOfLineStart + tmpIndex < oldIndexOfLineStart ) | 846 | if ( indexOfLineStart + tmpIndex < oldIndexOfLineStart ) |
838 | idx = indexOfLineStart + tmpIndex; | 847 | idx = indexOfLineStart + tmpIndex; |
839 | else | 848 | else |
840 | idx = oldIndexOfLineStart - 1; | 849 | idx = oldIndexOfLineStart - 1; |
841 | } | 850 | } |
842 | } | 851 | } |
843 | 852 | ||
844 | void QTextCursor::gotoDown() | 853 | void QTextCursor::gotoDown() |
845 | { | 854 | { |
846 | int indexOfLineStart; | 855 | int indexOfLineStart; |
847 | int line; | 856 | int line; |
848 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 857 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
849 | if ( !c ) | 858 | if ( !c ) |
850 | return; | 859 | return; |
851 | 860 | ||
852 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); | 861 | tmpIndex = QMAX( tmpIndex, idx - indexOfLineStart ); |
853 | if ( line == para->lines() - 1 ) { | 862 | if ( line == para->lines() - 1 ) { |
854 | if ( !para->next() ) { | 863 | if ( !para->next() ) { |
855 | if ( !nestedDepth() ) | 864 | if ( !nestedDepth() ) |
856 | return; | 865 | return; |
857 | pop(); | 866 | pop(); |
858 | processNesting( Down ); | 867 | processNesting( Down ); |
859 | if ( idx == -1 ) { | 868 | if ( idx == -1 ) { |
860 | pop(); | 869 | pop(); |
861 | if ( !para->next() ) | 870 | if ( !para->next() ) |
862 | return; | 871 | return; |
863 | idx = tmpIndex = 0; | 872 | idx = tmpIndex = 0; |
864 | } else { | 873 | } else { |
865 | tmpIndex = -1; | 874 | tmpIndex = -1; |
866 | return; | 875 | return; |
867 | } | 876 | } |
868 | } | 877 | } |
869 | QTextParagraph *s = para->next(); | 878 | QTextParagraph *s = para->next(); |
870 | while ( s && !s->isVisible() ) | 879 | while ( s && !s->isVisible() ) |
871 | s = s->next(); | 880 | s = s->next(); |
872 | if ( s ) | 881 | if ( s ) |
873 | para = s; | 882 | para = s; |
874 | if ( !para->lineStartOfLine( 0, &indexOfLineStart ) ) | 883 | if ( !para->lineStartOfLine( 0, &indexOfLineStart ) ) |
875 | return; | 884 | return; |
876 | int end; | 885 | int end; |
877 | if ( para->lines() == 1 ) | 886 | if ( para->lines() == 1 ) |
878 | end = para->length(); | 887 | end = para->length(); |
879 | else | 888 | else |
880 | para->lineStartOfLine( 1, &end ); | 889 | para->lineStartOfLine( 1, &end ); |
881 | if ( indexOfLineStart + tmpIndex < end ) | 890 | if ( indexOfLineStart + tmpIndex < end ) |
882 | idx = indexOfLineStart + tmpIndex; | 891 | idx = indexOfLineStart + tmpIndex; |
883 | else | 892 | else |
884 | idx = end - 1; | 893 | idx = end - 1; |
885 | } else { | 894 | } else { |
886 | ++line; | 895 | ++line; |
887 | int end; | 896 | int end; |
888 | if ( line == para->lines() - 1 ) | 897 | if ( line == para->lines() - 1 ) |
889 | end = para->length(); | 898 | end = para->length(); |
890 | else | 899 | else |
891 | para->lineStartOfLine( line + 1, &end ); | 900 | para->lineStartOfLine( line + 1, &end ); |
892 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) | 901 | if ( !para->lineStartOfLine( line, &indexOfLineStart ) ) |
893 | return; | 902 | return; |
894 | if ( indexOfLineStart + tmpIndex < end ) | 903 | if ( indexOfLineStart + tmpIndex < end ) |
895 | idx = indexOfLineStart + tmpIndex; | 904 | idx = indexOfLineStart + tmpIndex; |
896 | else | 905 | else |
897 | idx = end - 1; | 906 | idx = end - 1; |
898 | } | 907 | } |
899 | } | 908 | } |
900 | 909 | ||
901 | void QTextCursor::gotoLineEnd() | 910 | void QTextCursor::gotoLineEnd() |
902 | { | 911 | { |
903 | tmpIndex = -1; | 912 | tmpIndex = -1; |
904 | int indexOfLineStart; | 913 | int indexOfLineStart; |
905 | int line; | 914 | int line; |
906 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 915 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
907 | if ( !c ) | 916 | if ( !c ) |
908 | return; | 917 | return; |
909 | 918 | ||
910 | if ( line == para->lines() - 1 ) { | 919 | if ( line == para->lines() - 1 ) { |
911 | idx = para->length() - 1; | 920 | idx = para->length() - 1; |
912 | } else { | 921 | } else { |
913 | c = para->lineStartOfLine( ++line, &indexOfLineStart ); | 922 | c = para->lineStartOfLine( ++line, &indexOfLineStart ); |
914 | indexOfLineStart--; | 923 | indexOfLineStart--; |
915 | idx = indexOfLineStart; | 924 | idx = indexOfLineStart; |
916 | } | 925 | } |
917 | } | 926 | } |
918 | 927 | ||
919 | void QTextCursor::gotoLineStart() | 928 | void QTextCursor::gotoLineStart() |
920 | { | 929 | { |
921 | tmpIndex = -1; | 930 | tmpIndex = -1; |
922 | int indexOfLineStart; | 931 | int indexOfLineStart; |
923 | int line; | 932 | int line; |
924 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); | 933 | QTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line ); |
925 | if ( !c ) | 934 | if ( !c ) |
926 | return; | 935 | return; |
927 | 936 | ||
928 | idx = indexOfLineStart; | 937 | idx = indexOfLineStart; |
929 | } | 938 | } |
930 | 939 | ||
931 | void QTextCursor::gotoHome() | 940 | void QTextCursor::gotoHome() |
932 | { | 941 | { |
933 | if ( topParagraph()->document() ) | 942 | if ( topParagraph()->document() ) |
934 | gotoPosition( topParagraph()->document()->firstParagraph() ); | 943 | gotoPosition( topParagraph()->document()->firstParagraph() ); |
935 | else | 944 | else |
936 | gotoLineStart(); | 945 | gotoLineStart(); |
937 | } | 946 | } |
938 | 947 | ||
939 | void QTextCursor::gotoEnd() | 948 | void QTextCursor::gotoEnd() |
940 | { | 949 | { |
941 | if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() ) | 950 | if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() ) |
942 | gotoPosition( topParagraph()->document()->lastParagraph(), | 951 | gotoPosition( topParagraph()->document()->lastParagraph(), |
943 | topParagraph()->document()->lastParagraph()->length() - 1); | 952 | topParagraph()->document()->lastParagraph()->length() - 1); |
944 | else | 953 | else |
945 | gotoLineEnd(); | 954 | gotoLineEnd(); |
946 | } | 955 | } |
947 | 956 | ||
948 | void QTextCursor::gotoPageUp( int visibleHeight ) | 957 | void QTextCursor::gotoPageUp( int visibleHeight ) |
949 | { | 958 | { |
950 | int targetY = globalY() - visibleHeight; | 959 | int targetY = globalY() - visibleHeight; |
951 | QTextParagraph* old; int index; | 960 | QTextParagraph* old; int index; |
952 | do { | 961 | do { |
953 | old = para; index = idx; | 962 | old = para; index = idx; |
954 | gotoUp(); | 963 | gotoUp(); |
955 | } while ( (old != para || index != idx) && globalY() > targetY ); | 964 | } while ( (old != para || index != idx) && globalY() > targetY ); |
956 | } | 965 | } |
957 | 966 | ||
958 | void QTextCursor::gotoPageDown( int visibleHeight ) | 967 | void QTextCursor::gotoPageDown( int visibleHeight ) |
959 | { | 968 | { |
960 | int targetY = globalY() + visibleHeight; | 969 | int targetY = globalY() + visibleHeight; |
961 | QTextParagraph* old; int index; | 970 | QTextParagraph* old; int index; |
962 | do { | 971 | do { |
963 | old = para; index = idx; | 972 | old = para; index = idx; |
964 | gotoDown(); | 973 | gotoDown(); |
965 | } while ( (old != para || index != idx) && globalY() < targetY ); | 974 | } while ( (old != para || index != idx) && globalY() < targetY ); |
966 | } | 975 | } |
967 | 976 | ||
968 | void QTextCursor::gotoWordRight() | 977 | void QTextCursor::gotoWordRight() |
969 | { | 978 | { |
970 | if ( para->string()->isRightToLeft() ) | 979 | if ( para->string()->isRightToLeft() ) |
971 | gotoPreviousWord(); | 980 | gotoPreviousWord(); |
972 | else | 981 | else |
973 | gotoNextWord(); | 982 | gotoNextWord(); |
974 | } | 983 | } |
975 | 984 | ||
976 | void QTextCursor::gotoWordLeft() | 985 | void QTextCursor::gotoWordLeft() |
977 | { | 986 | { |
978 | if ( para->string()->isRightToLeft() ) | 987 | if ( para->string()->isRightToLeft() ) |
979 | gotoNextWord(); | 988 | gotoNextWord(); |
980 | else | 989 | else |
981 | gotoPreviousWord(); | 990 | gotoPreviousWord(); |
982 | } | 991 | } |
983 | 992 | ||
984 | void QTextCursor::gotoPreviousWord() | 993 | void QTextCursor::gotoPreviousWord() |
985 | { | 994 | { |
986 | gotoPreviousLetter(); | 995 | gotoPreviousLetter(); |
987 | tmpIndex = -1; | 996 | tmpIndex = -1; |
988 | QTextString *s = para->string(); | 997 | QTextString *s = para->string(); |
989 | bool allowSame = FALSE; | 998 | bool allowSame = FALSE; |
990 | if ( idx == ((int)s->length()-1) ) | 999 | if ( idx == ((int)s->length()-1) ) |
991 | return; | 1000 | return; |
992 | for ( int i = idx; i >= 0; --i ) { | 1001 | for ( int i = idx; i >= 0; --i ) { |
993 | if ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1002 | if ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
994 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) { | 1003 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) { |
995 | if ( !allowSame ) | 1004 | if ( !allowSame ) |
996 | continue; | 1005 | continue; |
997 | idx = i + 1; | 1006 | idx = i + 1; |
998 | return; | 1007 | return; |
999 | } | 1008 | } |
1000 | if ( !allowSame && !( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1009 | if ( !allowSame && !( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1001 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) | 1010 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) |
1002 | allowSame = TRUE; | 1011 | allowSame = TRUE; |
1003 | } | 1012 | } |
1004 | idx = 0; | 1013 | idx = 0; |
1005 | } | 1014 | } |
1006 | 1015 | ||
1007 | void QTextCursor::gotoNextWord() | 1016 | void QTextCursor::gotoNextWord() |
1008 | { | 1017 | { |
1009 | tmpIndex = -1; | 1018 | tmpIndex = -1; |
1010 | QTextString *s = para->string(); | 1019 | QTextString *s = para->string(); |
1011 | bool allowSame = FALSE; | 1020 | bool allowSame = FALSE; |
1012 | for ( int i = idx; i < (int)s->length(); ++i ) { | 1021 | for ( int i = idx; i < (int)s->length(); ++i ) { |
1013 | if ( ! (s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1022 | if ( ! (s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1014 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';') ) { | 1023 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';') ) { |
1015 | if ( !allowSame ) | 1024 | if ( !allowSame ) |
1016 | continue; | 1025 | continue; |
1017 | idx = i; | 1026 | idx = i; |
1018 | return; | 1027 | return; |
1019 | } | 1028 | } |
1020 | if ( !allowSame && ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || | 1029 | if ( !allowSame && ( s->at( i ).c.isSpace() || s->at( i ).c == '\t' || s->at( i ).c == '.' || |
1021 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) | 1030 | s->at( i ).c == ',' || s->at( i ).c == ':' || s->at( i ).c == ';' ) ) |
1022 | allowSame = TRUE; | 1031 | allowSame = TRUE; |
1023 | 1032 | ||
1024 | } | 1033 | } |
1025 | 1034 | ||
1026 | if ( idx < ((int)s->length()-1) ) { | 1035 | if ( idx < ((int)s->length()-1) ) { |
1027 | gotoLineEnd(); | 1036 | gotoLineEnd(); |
1028 | } else if ( para->next() ) { | 1037 | } else if ( para->next() ) { |
1029 | QTextParagraph *p = para->next(); | 1038 | QTextParagraph *p = para->next(); |
1030 | while ( p && !p->isVisible() ) | 1039 | while ( p && !p->isVisible() ) |
1031 | p = p->next(); | 1040 | p = p->next(); |
1032 | if ( s ) { | 1041 | if ( s ) { |
1033 | para = p; | 1042 | para = p; |
1034 | idx = 0; | 1043 | idx = 0; |
1035 | } | 1044 | } |
1036 | } else { | 1045 | } else { |
1037 | gotoLineEnd(); | 1046 | gotoLineEnd(); |
1038 | } | 1047 | } |
1039 | } | 1048 | } |
1040 | 1049 | ||
1041 | bool QTextCursor::atParagStart() | 1050 | bool QTextCursor::atParagStart() |
1042 | { | 1051 | { |
1043 | return idx == 0; | 1052 | return idx == 0; |
1044 | } | 1053 | } |
1045 | 1054 | ||
1046 | bool QTextCursor::atParagEnd() | 1055 | bool QTextCursor::atParagEnd() |
1047 | { | 1056 | { |
1048 | return idx == para->length() - 1; | 1057 | return idx == para->length() - 1; |
1049 | } | 1058 | } |
1050 | 1059 | ||
1051 | void QTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds ) | 1060 | void QTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds ) |
1052 | { | 1061 | { |
1053 | if ( !para->document() ) | 1062 | if ( !para->document() ) |
1054 | return; | 1063 | return; |
1055 | tmpIndex = -1; | 1064 | tmpIndex = -1; |
1056 | QTextFormat *f = 0; | 1065 | QTextFormat *f = 0; |
1057 | if ( para->document()->useFormatCollection() ) { | 1066 | if ( para->document()->useFormatCollection() ) { |
1058 | f = para->at( idx )->format(); | 1067 | f = para->at( idx )->format(); |
1059 | if ( idx == para->length() - 1 && idx > 0 ) | 1068 | if ( idx == para->length() - 1 && idx > 0 ) |
1060 | f = para->at( idx - 1 )->format(); | 1069 | f = para->at( idx - 1 )->format(); |
1061 | if ( f->isMisspelled() ) { | 1070 | if ( f->isMisspelled() ) { |
1062 | f->removeRef(); | 1071 | f->removeRef(); |
1063 | f = para->document()->formatCollection()->format( f->font(), f->color() ); | 1072 | f = para->document()->formatCollection()->format( f->font(), f->color() ); |
1064 | } | 1073 | } |
1065 | } | 1074 | } |
1066 | 1075 | ||
1067 | if ( atParagEnd() ) { | 1076 | if ( atParagEnd() ) { |
1068 | QTextParagraph *n = para->next(); | 1077 | QTextParagraph *n = para->next(); |
1069 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); | 1078 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); |
1070 | if ( f ) | 1079 | if ( f ) |
1071 | s->setFormat( 0, 1, f, TRUE ); | 1080 | s->setFormat( 0, 1, f, TRUE ); |
1072 | s->copyParagData( para ); | 1081 | s->copyParagData( para ); |
1073 | if ( ind ) { | 1082 | if ( ind ) { |
1074 | int oi, ni; | 1083 | int oi, ni; |
1075 | s->indent( &oi, &ni ); | 1084 | s->indent( &oi, &ni ); |
1076 | para = s; | 1085 | para = s; |
1077 | idx = ni; | 1086 | idx = ni; |
1078 | } else { | 1087 | } else { |
1079 | para = s; | 1088 | para = s; |
1080 | idx = 0; | 1089 | idx = 0; |
1081 | } | 1090 | } |
1082 | } else if ( atParagStart() ) { | 1091 | } else if ( atParagStart() ) { |
1083 | QTextParagraph *p = para->prev(); | 1092 | QTextParagraph *p = para->prev(); |
1084 | QTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds ); | 1093 | QTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds ); |
1085 | if ( f ) | 1094 | if ( f ) |
1086 | s->setFormat( 0, 1, f, TRUE ); | 1095 | s->setFormat( 0, 1, f, TRUE ); |
1087 | s->copyParagData( para ); | 1096 | s->copyParagData( para ); |
1088 | if ( ind ) { | 1097 | if ( ind ) { |
1089 | s->indent(); | 1098 | s->indent(); |
1090 | s->format(); | 1099 | s->format(); |
1091 | indent(); | 1100 | indent(); |
1092 | para->format(); | 1101 | para->format(); |
1093 | } | 1102 | } |
1094 | } else { | 1103 | } else { |
1095 | QString str = para->string()->toString().mid( idx, 0xFFFFFF ); | 1104 | QString str = para->string()->toString().mid( idx, 0xFFFFFF ); |
1096 | QTextParagraph *n = para->next(); | 1105 | QTextParagraph *n = para->next(); |
1097 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); | 1106 | QTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds ); |
1098 | s->copyParagData( para ); | 1107 | s->copyParagData( para ); |
1099 | s->remove( 0, 1 ); | 1108 | s->remove( 0, 1 ); |
1100 | s->append( str, TRUE ); | 1109 | s->append( str, TRUE ); |
1101 | for ( uint i = 0; i < str.length(); ++i ) { | 1110 | for ( uint i = 0; i < str.length(); ++i ) { |
1102 | QTextStringChar* tsc = para->at( idx + i ); | 1111 | QTextStringChar* tsc = para->at( idx + i ); |
1103 | s->setFormat( i, 1, tsc->format(), TRUE ); | 1112 | s->setFormat( i, 1, tsc->format(), TRUE ); |
1104 | if ( tsc->isCustom() ) { | 1113 | if ( tsc->isCustom() ) { |
1105 | QTextCustomItem * item = tsc->customItem(); | 1114 | QTextCustomItem * item = tsc->customItem(); |
1106 | s->at( i )->setCustomItem( item ); | 1115 | s->at( i )->setCustomItem( item ); |
1107 | tsc->loseCustomItem(); | 1116 | tsc->loseCustomItem(); |
1108 | } | 1117 | } |
1109 | if ( tsc->isAnchor() ) | 1118 | if ( tsc->isAnchor() ) |
1110 | s->at( i )->setAnchor( tsc->anchorName(), | 1119 | s->at( i )->setAnchor( tsc->anchorName(), |
1111 | tsc->anchorHref() ); | 1120 | tsc->anchorHref() ); |
1112 | } | 1121 | } |
1113 | para->truncate( idx ); | 1122 | para->truncate( idx ); |
1114 | if ( ind ) { | 1123 | if ( ind ) { |
1115 | int oi, ni; | 1124 | int oi, ni; |
1116 | s->indent( &oi, &ni ); | 1125 | s->indent( &oi, &ni ); |
1117 | para = s; | 1126 | para = s; |
1118 | idx = ni; | 1127 | idx = ni; |
1119 | } else { | 1128 | } else { |
1120 | para = s; | 1129 | para = s; |
1121 | idx = 0; | 1130 | idx = 0; |
1122 | } | 1131 | } |
1123 | } | 1132 | } |
1124 | 1133 | ||
1125 | invalidateNested(); | 1134 | invalidateNested(); |
1126 | } | 1135 | } |
1127 | 1136 | ||
1128 | bool QTextCursor::remove() | 1137 | bool QTextCursor::remove() |
1129 | { | 1138 | { |
1130 | tmpIndex = -1; | 1139 | tmpIndex = -1; |
1131 | if ( !atParagEnd() ) { | 1140 | if ( !atParagEnd() ) { |
1132 | para->remove( idx, 1 ); | 1141 | para->remove( idx, 1 ); |
1133 | int h = para->rect().height(); | 1142 | int h = para->rect().height(); |
1134 | para->format( -1, TRUE ); | 1143 | para->format( -1, TRUE ); |
1135 | if ( h != para->rect().height() ) | 1144 | if ( h != para->rect().height() ) |
1136 | invalidateNested(); | 1145 | invalidateNested(); |
1137 | else if ( para->document() && para->document()->parent() ) | 1146 | else if ( para->document() && para->document()->parent() ) |
1138 | para->document()->nextDoubleBuffered = TRUE; | 1147 | para->document()->nextDoubleBuffered = TRUE; |
1139 | return FALSE; | 1148 | return FALSE; |
1140 | } else if ( para->next() ) { | 1149 | } else if ( para->next() ) { |
1141 | para->join( para->next() ); | 1150 | para->join( para->next() ); |
1142 | invalidateNested(); | 1151 | invalidateNested(); |
1143 | return TRUE; | 1152 | return TRUE; |
1144 | } | 1153 | } |
1145 | return FALSE; | 1154 | return FALSE; |
1146 | } | 1155 | } |
1147 | 1156 | ||
1148 | void QTextCursor::indent() | 1157 | void QTextCursor::indent() |
1149 | { | 1158 | { |
1150 | int oi = 0, ni = 0; | 1159 | int oi = 0, ni = 0; |
1151 | para->indent( &oi, &ni ); | 1160 | para->indent( &oi, &ni ); |
1152 | if ( oi == ni ) | 1161 | if ( oi == ni ) |
1153 | return; | 1162 | return; |
1154 | 1163 | ||
1155 | if ( idx >= oi ) | 1164 | if ( idx >= oi ) |
1156 | idx += ni - oi; | 1165 | idx += ni - oi; |
1157 | else | 1166 | else |
1158 | idx = ni; | 1167 | idx = ni; |
1159 | } | 1168 | } |
1160 | 1169 | ||
1161 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 1170 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1162 | 1171 | ||
1163 | QTextDocument::QTextDocument( QTextDocument *p ) | 1172 | QTextDocument::QTextDocument( QTextDocument *p ) |
1164 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) | 1173 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) |
1165 | { | 1174 | { |
1166 | fCollection = new QTextFormatCollection; | 1175 | fCollection = new QTextFormatCollection; |
1167 | init(); | 1176 | init(); |
1168 | } | 1177 | } |
1169 | 1178 | ||
1170 | QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f ) | 1179 | QTextDocument::QTextDocument( QTextDocument *p, QTextFormatCollection *f ) |
1171 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) | 1180 | : par( p ), parentPar( 0 ), tc( 0 ), tArray( 0 ), tStopWidth( 0 ) |
1172 | { | 1181 | { |
1173 | fCollection = f; | 1182 | fCollection = f; |
1174 | init(); | 1183 | init(); |
1175 | } | 1184 | } |
1176 | 1185 | ||
1177 | void QTextDocument::init() | 1186 | void QTextDocument::init() |
1178 | { | 1187 | { |
1179 | oTextValid = TRUE; | 1188 | oTextValid = TRUE; |
1180 | mightHaveCustomItems = FALSE; | 1189 | mightHaveCustomItems = FALSE; |
1181 | if ( par ) | 1190 | if ( par ) |
1182 | par->insertChild( this ); | 1191 | par->insertChild( this ); |
1183 | pProcessor = 0; | 1192 | pProcessor = 0; |
1184 | useFC = TRUE; | 1193 | useFC = TRUE; |
1185 | pFormatter = 0; | 1194 | pFormatter = 0; |
1186 | indenter = 0; | 1195 | indenter = 0; |
1187 | fParag = 0; | 1196 | fParag = 0; |
1188 | txtFormat = Qt::AutoText; | 1197 | txtFormat = Qt::AutoText; |
1189 | preferRichText = FALSE; | 1198 | preferRichText = FALSE; |
1190 | pages = FALSE; | 1199 | pages = FALSE; |
1191 | focusIndicator.parag = 0; | 1200 | focusIndicator.parag = 0; |
1192 | minw = 0; | 1201 | minw = 0; |
1193 | wused = 0; | 1202 | wused = 0; |
1194 | minwParag = curParag = 0; | 1203 | minwParag = curParag = 0; |
1195 | align = AlignAuto; | 1204 | align = AlignAuto; |
1196 | nSelections = 1; | 1205 | nSelections = 1; |
1197 | 1206 | ||
1198 | setStyleSheet( QStyleSheet::defaultSheet() ); | 1207 | setStyleSheet( QStyleSheet::defaultSheet() ); |
1199 | factory_ = QMimeSourceFactory::defaultFactory(); | 1208 | factory_ = QMimeSourceFactory::defaultFactory(); |
1200 | contxt = QString::null; | 1209 | contxt = QString::null; |
1201 | 1210 | ||
1202 | underlLinks = par ? par->underlLinks : TRUE; | 1211 | underlLinks = par ? par->underlLinks : TRUE; |
1203 | backBrush = 0; | 1212 | backBrush = 0; |
1204 | buf_pixmap = 0; | 1213 | buf_pixmap = 0; |
1205 | nextDoubleBuffered = FALSE; | 1214 | nextDoubleBuffered = FALSE; |
1206 | 1215 | ||
1207 | if ( par ) | 1216 | if ( par ) |
1208 | withoutDoubleBuffer = par->withoutDoubleBuffer; | 1217 | withoutDoubleBuffer = par->withoutDoubleBuffer; |
1209 | else | 1218 | else |
1210 | withoutDoubleBuffer = FALSE; | 1219 | withoutDoubleBuffer = FALSE; |
1211 | 1220 | ||
1212 | lParag = fParag = createParagraph( this, 0, 0 ); | 1221 | lParag = fParag = createParagraph( this, 0, 0 ); |
1213 | 1222 | ||
1214 | cx = 0; | 1223 | cx = 0; |
1215 | cy = 2; | 1224 | cy = 2; |
1216 | if ( par ) | 1225 | if ( par ) |
1217 | cx = cy = 0; | 1226 | cx = cy = 0; |
1218 | cw = 600; | 1227 | cw = 600; |
1219 | vw = 0; | 1228 | vw = 0; |
1220 | flow_ = new QTextFlow; | 1229 | flow_ = new QTextFlow; |
1221 | flow_->setWidth( cw ); | 1230 | flow_->setWidth( cw ); |
1222 | 1231 | ||
1223 | leftmargin = rightmargin = 4; | 1232 | leftmargin = rightmargin = 4; |
1224 | scaleFontsFactor = 1; | 1233 | scaleFontsFactor = 1; |
1225 | 1234 | ||
1226 | 1235 | ||
1227 | selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight ); | 1236 | selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight ); |
1228 | selectionText[ Standard ] = TRUE; | 1237 | selectionText[ Standard ] = TRUE; |
1229 | commandHistory = new QTextCommandHistory( 100 ); | 1238 | commandHistory = new QTextCommandHistory( 100 ); |
1230 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; | 1239 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; |
1231 | } | 1240 | } |
1232 | 1241 | ||
1233 | QTextDocument::~QTextDocument() | 1242 | QTextDocument::~QTextDocument() |
1234 | { | 1243 | { |
1235 | if ( par ) | 1244 | if ( par ) |
1236 | par->removeChild( this ); | 1245 | par->removeChild( this ); |
1237 | clear(); | 1246 | clear(); |
1238 | delete commandHistory; | 1247 | delete commandHistory; |
1239 | delete flow_; | 1248 | delete flow_; |
1240 | if ( !par ) | 1249 | if ( !par ) |
1241 | delete pFormatter; | 1250 | delete pFormatter; |
1242 | delete fCollection; | 1251 | delete fCollection; |
1243 | delete pProcessor; | 1252 | delete pProcessor; |
1244 | delete buf_pixmap; | 1253 | delete buf_pixmap; |
1245 | delete indenter; | 1254 | delete indenter; |
1246 | delete backBrush; | 1255 | delete backBrush; |
1247 | if ( tArray ) | 1256 | if ( tArray ) |
1248 | delete [] tArray; | 1257 | delete [] tArray; |
1249 | } | 1258 | } |
1250 | 1259 | ||
1251 | void QTextDocument::clear( bool createEmptyParag ) | 1260 | void QTextDocument::clear( bool createEmptyParag ) |
1252 | { | 1261 | { |
1253 | if ( flow_ ) | 1262 | if ( flow_ ) |
1254 | flow_->clear(); | 1263 | flow_->clear(); |
1255 | while ( fParag ) { | 1264 | while ( fParag ) { |
1256 | QTextParagraph *p = fParag->next(); | 1265 | QTextParagraph *p = fParag->next(); |
1257 | delete fParag; | 1266 | delete fParag; |
1258 | fParag = p; | 1267 | fParag = p; |
1259 | } | 1268 | } |
1260 | fParag = lParag = 0; | 1269 | fParag = lParag = 0; |
1261 | if ( createEmptyParag ) | 1270 | if ( createEmptyParag ) |
1262 | fParag = lParag = createParagraph( this ); | 1271 | fParag = lParag = createParagraph( this ); |
1263 | selections.clear(); | 1272 | selections.clear(); |
1264 | oText = QString::null; | 1273 | oText = QString::null; |
1265 | oTextValid = TRUE; | 1274 | oTextValid = TRUE; |
1266 | } | 1275 | } |
1267 | 1276 | ||
1268 | int QTextDocument::widthUsed() const | 1277 | int QTextDocument::widthUsed() const |
1269 | { | 1278 | { |
1270 | return wused + border_tolerance; | 1279 | return wused + border_tolerance; |
1271 | } | 1280 | } |
1272 | 1281 | ||
1273 | int QTextDocument::height() const | 1282 | int QTextDocument::height() const |
1274 | { | 1283 | { |
1275 | int h = 0; | 1284 | int h = 0; |
1276 | if ( lParag ) | 1285 | if ( lParag ) |
1277 | h = lParag->rect().top() + lParag->rect().height() + 1; | 1286 | h = lParag->rect().top() + lParag->rect().height() + 1; |
1278 | int fh = flow_->boundingRect().bottom(); | 1287 | int fh = flow_->boundingRect().bottom(); |
1279 | return QMAX( h, fh ); | 1288 | return QMAX( h, fh ); |
1280 | } | 1289 | } |
1281 | 1290 | ||
1282 | 1291 | ||
1283 | 1292 | ||
1284 | QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) | 1293 | QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) |
1285 | { | 1294 | { |
1286 | return new QTextParagraph( d, pr, nx, updateIds ); | 1295 | return new QTextParagraph( d, pr, nx, updateIds ); |
1287 | } | 1296 | } |
1288 | 1297 | ||
1289 | bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p ) | 1298 | bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p ) |
1290 | { | 1299 | { |
1291 | if ( needed == -1 ) { | 1300 | if ( needed == -1 ) { |
1292 | minw = 0; | 1301 | minw = 0; |
1293 | wused = 0; | 1302 | wused = 0; |
1294 | p = 0; | 1303 | p = 0; |
1295 | } | 1304 | } |
1296 | if ( p == minwParag ) { | 1305 | if ( p == minwParag ) { |
1297 | minw = needed; | 1306 | minw = needed; |
1298 | emit minimumWidthChanged( minw ); | 1307 | emit minimumWidthChanged( minw ); |
1299 | } else if ( needed > minw ) { | 1308 | } else if ( needed > minw ) { |
1300 | minw = needed; | 1309 | minw = needed; |
1301 | minwParag = p; | 1310 | minwParag = p; |
1302 | emit minimumWidthChanged( minw ); | 1311 | emit minimumWidthChanged( minw ); |
1303 | } | 1312 | } |
1304 | wused = QMAX( wused, used ); | 1313 | wused = QMAX( wused, used ); |
1305 | wused = QMAX( wused, minw ); | 1314 | wused = QMAX( wused, minw ); |
1306 | cw = QMAX( minw, cw ); | 1315 | cw = QMAX( minw, cw ); |
1307 | return TRUE; | 1316 | return TRUE; |
1308 | } | 1317 | } |
1309 | 1318 | ||
1310 | void QTextDocument::setPlainText( const QString &text ) | 1319 | void QTextDocument::setPlainText( const QString &text ) |
1311 | { | 1320 | { |
1312 | clear(); | 1321 | clear(); |
1313 | preferRichText = FALSE; | 1322 | preferRichText = FALSE; |
1314 | oTextValid = TRUE; | 1323 | oTextValid = TRUE; |
1315 | oText = text; | 1324 | oText = text; |
1316 | 1325 | ||
1317 | int lastNl = 0; | 1326 | int lastNl = 0; |
1318 | int nl = text.find( '\n' ); | 1327 | int nl = text.find( '\n' ); |
1319 | if ( nl == -1 ) { | 1328 | if ( nl == -1 ) { |
1320 | lParag = createParagraph( this, lParag, 0 ); | 1329 | lParag = createParagraph( this, lParag, 0 ); |
1321 | if ( !fParag ) | 1330 | if ( !fParag ) |
1322 | fParag = lParag; | 1331 | fParag = lParag; |
1323 | QString s = text; | 1332 | QString s = text; |
1324 | if ( !s.isEmpty() ) { | 1333 | if ( !s.isEmpty() ) { |
1325 | if ( s[ (int)s.length() - 1 ] == '\r' ) | 1334 | if ( s[ (int)s.length() - 1 ] == '\r' ) |
1326 | s.remove( s.length() - 1, 1 ); | 1335 | s.remove( s.length() - 1, 1 ); |
1327 | lParag->append( s ); | 1336 | lParag->append( s ); |
1328 | } | 1337 | } |
1329 | } else { | 1338 | } else { |
1330 | for (;;) { | 1339 | for (;;) { |
1331 | lParag = createParagraph( this, lParag, 0 ); | 1340 | lParag = createParagraph( this, lParag, 0 ); |
1332 | if ( !fParag ) | 1341 | if ( !fParag ) |
1333 | fParag = lParag; | 1342 | fParag = lParag; |
1334 | QString s = text.mid( lastNl, nl - lastNl ); | 1343 | QString s = text.mid( lastNl, nl - lastNl ); |
1335 | if ( !s.isEmpty() ) { | 1344 | if ( !s.isEmpty() ) { |
1336 | if ( s[ (int)s.length() - 1 ] == '\r' ) | 1345 | if ( s[ (int)s.length() - 1 ] == '\r' ) |
1337 | s.remove( s.length() - 1, 1 ); | 1346 | s.remove( s.length() - 1, 1 ); |
1338 | lParag->append( s ); | 1347 | lParag->append( s ); |
1339 | } | 1348 | } |
1340 | if ( nl == 0xffffff ) | 1349 | if ( nl == 0xffffff ) |
1341 | break; | 1350 | break; |
1342 | lastNl = nl + 1; | 1351 | lastNl = nl + 1; |
1343 | nl = text.find( '\n', nl + 1 ); | 1352 | nl = text.find( '\n', nl + 1 ); |
1344 | if ( nl == -1 ) | 1353 | if ( nl == -1 ) |
1345 | nl = 0xffffff; | 1354 | nl = 0xffffff; |
1346 | } | 1355 | } |
1347 | } | 1356 | } |
1348 | if ( !lParag ) | 1357 | if ( !lParag ) |
1349 | lParag = fParag = createParagraph( this, 0, 0 ); | 1358 | lParag = fParag = createParagraph( this, 0, 0 ); |
1350 | } | 1359 | } |
1351 | 1360 | ||
1352 | struct Q_EXPORT QTextDocumentTag { | 1361 | struct Q_EXPORT QTextDocumentTag { |
1353 | QTextDocumentTag(){} | 1362 | QTextDocumentTag(){} |
1354 | QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f ) | 1363 | QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f ) |
1355 | :name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) { | 1364 | :name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) { |
1356 | wsm = QStyleSheetItem::WhiteSpaceNormal; | 1365 | wsm = QStyleSheetItem::WhiteSpaceNormal; |
1357 | } | 1366 | } |
1358 | QString name; | 1367 | QString name; |
1359 | const QStyleSheetItem* style; | 1368 | const QStyleSheetItem* style; |
1360 | QString anchorHref; | 1369 | QString anchorHref; |
1361 | QStyleSheetItem::WhiteSpaceMode wsm; | 1370 | QStyleSheetItem::WhiteSpaceMode wsm; |
1362 | QTextFormat format; | 1371 | QTextFormat format; |
1363 | int alignment : 16; | 1372 | int alignment : 16; |
1364 | int direction : 5; | 1373 | int direction : 5; |
1365 | QStyleSheetItem::ListStyle liststyle; | 1374 | QStyleSheetItem::ListStyle liststyle; |
1366 | 1375 | ||
1367 | QTextDocumentTag( const QTextDocumentTag& t ) { | 1376 | QTextDocumentTag( const QTextDocumentTag& t ) { |
1368 | name = t.name; | 1377 | name = t.name; |
1369 | style = t.style; | 1378 | style = t.style; |
1370 | anchorHref = t.anchorHref; | 1379 | anchorHref = t.anchorHref; |
1371 | wsm = t.wsm; | 1380 | wsm = t.wsm; |
1372 | format = t.format; | 1381 | format = t.format; |
1373 | alignment = t.alignment; | 1382 | alignment = t.alignment; |
1374 | direction = t.direction; | 1383 | direction = t.direction; |
1375 | liststyle = t.liststyle; | 1384 | liststyle = t.liststyle; |
1376 | } | 1385 | } |
1377 | QTextDocumentTag& operator=(const QTextDocumentTag& t) { | 1386 | QTextDocumentTag& operator=(const QTextDocumentTag& t) { |
1378 | name = t.name; | 1387 | name = t.name; |
1379 | style = t.style; | 1388 | style = t.style; |
1380 | anchorHref = t.anchorHref; | 1389 | anchorHref = t.anchorHref; |
1381 | wsm = t.wsm; | 1390 | wsm = t.wsm; |
1382 | format = t.format; | 1391 | format = t.format; |
1383 | alignment = t.alignment; | 1392 | alignment = t.alignment; |
1384 | direction = t.direction; | 1393 | direction = t.direction; |
1385 | liststyle = t.liststyle; | 1394 | liststyle = t.liststyle; |
1386 | return *this; | 1395 | return *this; |
1387 | } | 1396 | } |
1388 | 1397 | ||
1389 | #if defined(Q_FULL_TEMPLATE_INSTANTIATION) | 1398 | #if defined(Q_FULL_TEMPLATE_INSTANTIATION) |
1390 | bool operator==( const QTextDocumentTag& ) const { return FALSE; } | 1399 | bool operator==( const QTextDocumentTag& ) const { return FALSE; } |
1391 | #endif | 1400 | #endif |
1392 | }; | 1401 | }; |
1393 | 1402 | ||
1394 | 1403 | ||
1395 | #define NEWPAR do{ if ( !hasNewPar) { \ | 1404 | #define NEWPAR do { \ |
1396 | if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \ | 1405 | if ( !hasNewPar) { \ |
1397 | curpar->remove( curpar->length()-2, 1 ); \ | 1406 | if ( !curpar ) { \ |
1398 | curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \ | 1407 | owarn << "no current paragraph" << oendl; \ |
1399 | hasNewPar = TRUE; \ | 1408 | return; \ |
1400 | curpar->rtext = TRUE; \ | 1409 | } \ |
1401 | curpar->align = curtag.alignment; \ | 1410 | if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \ |
1402 | curpar->lstyle = curtag.liststyle; \ | 1411 | curpar->remove( curpar->length()-2, 1 ); \ |
1403 | curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \ | 1412 | curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); \ |
1404 | curpar->str->setDirection( (QChar::Direction)curtag.direction ); \ | 1413 | if ( !curpar ) { \ |
1405 | space = TRUE; \ | 1414 | owarn << "failed in creating a new paragraph" << oendl; \ |
1406 | delete vec; vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \ | 1415 | return; \ |
1407 | int i = 0; \ | 1416 | } \ |
1408 | for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ | 1417 | vec = 0; \ |
1409 | vec->insert( i++, (*it).style ); \ | 1418 | } \ |
1410 | vec->insert( i, curtag.style ); \ | 1419 | hasNewPar = TRUE; \ |
1411 | }while(FALSE) | 1420 | curpar->rtext = TRUE; \ |
1412 | 1421 | curpar->align = curtag.alignment; \ | |
1422 | curpar->lstyle = curtag.liststyle; \ | ||
1423 | curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \ | ||
1424 | curpar->str->setDirection( (QChar::Direction)curtag.direction ); \ | ||
1425 | space = TRUE; \ | ||
1426 | delete vec; \ | ||
1427 | vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \ | ||
1428 | int i = 0; \ | ||
1429 | for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \ | ||
1430 | vec->insert( i++, (*it).style ); \ | ||
1431 | vec->insert( i, curtag.style ); \ | ||
1432 | } while ( FALSE ) | ||
1413 | 1433 | ||
1414 | void QTextDocument::setRichText( const QString &text, const QString &context ) | 1434 | void QTextDocument::setRichText( const QString &text, const QString &context ) |
1415 | { | 1435 | { |
1416 | if ( !context.isEmpty() ) | 1436 | if ( !context.isEmpty() ) |
1417 | setContext( context ); | 1437 | setContext( context ); |
1418 | clear(); | 1438 | clear(); |
1419 | fParag = lParag = createParagraph( this ); | 1439 | fParag = lParag = createParagraph( this ); |
1420 | oTextValid = TRUE; | 1440 | oTextValid = TRUE; |
1421 | oText = text; | 1441 | oText = text; |
1422 | setRichTextInternal( text ); | 1442 | setRichTextInternal( text ); |
1423 | fParag->rtext = TRUE; | 1443 | fParag->rtext = TRUE; |
1424 | } | 1444 | } |
1425 | 1445 | ||
1426 | void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor ) | 1446 | void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor ) |
1427 | { | 1447 | { |
1428 | QTextParagraph* curpar = lParag; | 1448 | QTextParagraph* curpar = lParag; |
1429 | int pos = 0; | 1449 | int pos = 0; |
1430 | QValueStack<QTextDocumentTag> tags; | 1450 | QValueStack<QTextDocumentTag> tags; |
1431 | QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() ); | 1451 | QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() ); |
1432 | QTextDocumentTag curtag = initag; | 1452 | QTextDocumentTag curtag = initag; |
1433 | bool space = TRUE; | 1453 | bool space = TRUE; |
1434 | bool canMergeLi = FALSE; | 1454 | bool canMergeLi = FALSE; |
1435 | 1455 | ||
1436 | bool textEditMode = FALSE; | 1456 | bool textEditMode = FALSE; |
1437 | 1457 | ||
1438 | const QChar* doc = text.unicode(); | 1458 | const QChar* doc = text.unicode(); |
1439 | int length = text.length(); | 1459 | int length = text.length(); |
1440 | bool hasNewPar = curpar->length() <= 1; | 1460 | bool hasNewPar = curpar->length() <= 1; |
1441 | QString anchorName; | 1461 | QString anchorName; |
1442 | 1462 | ||
1443 | // style sheet handling for margin and line spacing calculation below | 1463 | // style sheet handling for margin and line spacing calculation below |
1444 | QTextParagraph* stylesPar = curpar; | 1464 | QTextParagraph* stylesPar = curpar; |
1445 | QPtrVector<QStyleSheetItem>* vec = 0; | 1465 | QPtrVector<QStyleSheetItem>* vec = 0; |
1446 | QPtrList< QPtrVector<QStyleSheetItem> > styles; | 1466 | QPtrList< QPtrVector<QStyleSheetItem> > styles; |
1447 | styles.setAutoDelete( TRUE ); | 1467 | styles.setAutoDelete( TRUE ); |
1448 | 1468 | ||
1449 | if ( cursor ) { | 1469 | if ( cursor ) { |
1450 | cursor->splitAndInsertEmptyParagraph(); | 1470 | cursor->splitAndInsertEmptyParagraph(); |
1451 | QTextCursor tmp = *cursor; | 1471 | QTextCursor tmp = *cursor; |
1452 | tmp.gotoPreviousLetter(); | 1472 | tmp.gotoPreviousLetter(); |
1453 | stylesPar = curpar = tmp.paragraph(); | 1473 | stylesPar = curpar = tmp.paragraph(); |
1454 | hasNewPar = TRUE; | 1474 | hasNewPar = TRUE; |
1455 | textEditMode = TRUE; | 1475 | textEditMode = TRUE; |
1456 | } else { | 1476 | } else { |
1457 | NEWPAR; | 1477 | NEWPAR; |
1458 | } | 1478 | } |
1459 | 1479 | ||
1460 | // set rtext spacing to FALSE for the initial paragraph. | 1480 | // set rtext spacing to FALSE for the initial paragraph. |
1461 | curpar->rtext = FALSE; | 1481 | curpar->rtext = FALSE; |
1462 | 1482 | ||
1463 | QString wellKnownTags = "br hr wsp table qt body meta title"; | 1483 | QString wellKnownTags = "br hr wsp table qt body meta title"; |
1464 | 1484 | ||
1465 | while ( pos < length ) { | 1485 | while ( pos < length ) { |
1466 | if ( hasPrefix(doc, length, pos, '<' ) ){ | 1486 | if ( hasPrefix(doc, length, pos, '<' ) ){ |
1467 | if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) { | 1487 | if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) { |
1468 | // open tag | 1488 | // open tag |
1469 | QMap<QString, QString> attr; | 1489 | QMap<QString, QString> attr; |
1470 | bool emptyTag = FALSE; | 1490 | bool emptyTag = FALSE; |
1471 | QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag); | 1491 | QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag); |
1472 | if ( tagname.isEmpty() ) | 1492 | if ( tagname.isEmpty() ) |
1473 | continue; // nothing we could do with this, probably parse error | 1493 | continue; // nothing we could do with this, probably parse error |
1474 | 1494 | ||
1475 | const QStyleSheetItem* nstyle = sheet_->item(tagname); | 1495 | const QStyleSheetItem* nstyle = sheet_->item(tagname); |
1476 | 1496 | ||
1477 | if ( nstyle ) { | 1497 | if ( nstyle ) { |
1478 | // we might have to close some 'forgotten' tags | 1498 | // we might have to close some 'forgotten' tags |
1479 | while ( !nstyle->allowedInContext( curtag.style ) ) { | 1499 | while ( !nstyle->allowedInContext( curtag.style ) ) { |
1480 | QString msg; | 1500 | QString msg; |
1481 | msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)", | 1501 | msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)", |
1482 | tagname.ascii(), curtag.style->name().ascii(), pos); | 1502 | tagname.ascii(), curtag.style->name().ascii(), pos); |
1483 | sheet_->error( msg ); | 1503 | sheet_->error( msg ); |
1484 | if ( tags.isEmpty() ) | 1504 | if ( tags.isEmpty() ) |
1485 | break; | 1505 | break; |
1486 | curtag = tags.pop(); | 1506 | curtag = tags.pop(); |
1487 | } | 1507 | } |
1488 | 1508 | ||
1489 | /* special handling for p and li for HTML | 1509 | /* special handling for p and li for HTML |
1490 | compatibility. We do not want to embed blocks in | 1510 | compatibility. We do not want to embed blocks in |
1491 | p, and we do not want new blocks inside non-empty | 1511 | p, and we do not want new blocks inside non-empty |
1492 | lis. Plus we want to merge empty lis sometimes. */ | 1512 | lis. Plus we want to merge empty lis sometimes. */ |
1493 | if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1513 | if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1494 | canMergeLi = TRUE; | 1514 | canMergeLi = TRUE; |
1495 | } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { | 1515 | } else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) { |
1496 | while ( curtag.style->name() == "p" ) { | 1516 | while ( curtag.style->name() == "p" ) { |
1497 | if ( tags.isEmpty() ) | 1517 | if ( tags.isEmpty() ) |
1498 | break; | 1518 | break; |
1499 | curtag = tags.pop(); | 1519 | curtag = tags.pop(); |
1500 | } | 1520 | } |
1501 | 1521 | ||
1502 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1522 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1503 | // we are in a li and a new block comes along | 1523 | // we are in a li and a new block comes along |
1504 | if ( nstyle->name() == "ul" || nstyle->name() == "ol" ) | 1524 | if ( nstyle->name() == "ul" || nstyle->name() == "ol" ) |
1505 | hasNewPar = FALSE; // we want an empty li (like most browsers) | 1525 | hasNewPar = FALSE; // we want an empty li (like most browsers) |
1506 | if ( !hasNewPar ) { | 1526 | if ( !hasNewPar ) { |
1507 | /* do not add new blocks inside | 1527 | /* do not add new blocks inside |
1508 | non-empty lis */ | 1528 | non-empty lis */ |
1509 | while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1529 | while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1510 | if ( tags.isEmpty() ) | 1530 | if ( tags.isEmpty() ) |
1511 | break; | 1531 | break; |
1512 | curtag = tags.pop(); | 1532 | curtag = tags.pop(); |
1513 | } | 1533 | } |
1514 | } else if ( canMergeLi ) { | 1534 | } else if ( canMergeLi ) { |
1515 | /* we have an empty li and a block | 1535 | /* we have an empty li and a block |
1516 | comes along, merge them */ | 1536 | comes along, merge them */ |
1517 | nstyle = curtag.style; | 1537 | nstyle = curtag.style; |
1518 | } | 1538 | } |
1519 | canMergeLi = FALSE; | 1539 | canMergeLi = FALSE; |
1520 | } | 1540 | } |
1521 | } | 1541 | } |
1522 | } | 1542 | } |
1523 | 1543 | ||
1524 | QTextCustomItem* custom = 0; | 1544 | QTextCustomItem* custom = 0; |
1525 | 1545 | ||
1526 | // some well-known tags, some have a nstyle, some not | 1546 | // some well-known tags, some have a nstyle, some not |
1527 | if ( wellKnownTags.find( tagname ) != -1 ) { | 1547 | if ( wellKnownTags.find( tagname ) != -1 ) { |
1528 | if ( tagname == "br" ) { | 1548 | if ( tagname == "br" ) { |
1529 | emptyTag = space = TRUE; | 1549 | emptyTag = space = TRUE; |
1530 | int index = QMAX( curpar->length(),1) - 1; | 1550 | int index = QMAX( curpar->length(),1) - 1; |
1531 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1551 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1532 | curpar->append( QChar_linesep ); | 1552 | curpar->append( QChar_linesep ); |
1533 | curpar->setFormat( index, 1, &format ); | 1553 | curpar->setFormat( index, 1, &format ); |
1534 | } else if ( tagname == "hr" ) { | 1554 | } else if ( tagname == "hr" ) { |
1535 | emptyTag = space = TRUE; | 1555 | emptyTag = space = TRUE; |
1536 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); | 1556 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); |
1537 | NEWPAR; | 1557 | NEWPAR; |
1538 | } else if ( tagname == "table" ) { | 1558 | } else if ( tagname == "table" ) { |
1539 | emptyTag = space = TRUE; | 1559 | emptyTag = space = TRUE; |
1540 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1560 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1541 | curpar->setAlignment( curtag.alignment ); | 1561 | curpar->setAlignment( curtag.alignment ); |
1542 | custom = parseTable( attr, format, doc, length, pos, curpar ); | 1562 | custom = parseTable( attr, format, doc, length, pos, curpar ); |
1543 | } else if ( tagname == "qt" || tagname == "body" ) { | 1563 | } else if ( tagname == "qt" || tagname == "body" ) { |
1544 | if ( attr.contains( "bgcolor" ) ) { | 1564 | if ( attr.contains( "bgcolor" ) ) { |
1545 | QBrush *b = new QBrush( QColor( attr["bgcolor"] ) ); | 1565 | QBrush *b = new QBrush( QColor( attr["bgcolor"] ) ); |
1546 | setPaper( b ); | 1566 | setPaper( b ); |
1547 | } | 1567 | } |
1548 | if ( attr.contains( "background" ) ) { | 1568 | if ( attr.contains( "background" ) ) { |
1549 | QImage img; | 1569 | QImage img; |
1550 | QString bg = attr["background"]; | 1570 | QString bg = attr["background"]; |
1551 | const QMimeSource* m = factory_->data( bg, contxt ); | 1571 | const QMimeSource* m = factory_->data( bg, contxt ); |
1552 | if ( !m ) { | 1572 | if ( !m ) { |
1553 | owarn << "QRichText: no mimesource for " << bg.latin1() << "" << oendl; | 1573 | owarn << "QRichText: no mimesource for " << bg.latin1() << "" << oendl; |
1554 | } else { | 1574 | } else { |
1555 | if ( !QImageDrag::decode( m, img ) ) { | 1575 | if ( !QImageDrag::decode( m, img ) ) { |
1556 | owarn << "QTextImage: cannot decode " << bg.latin1() << "" << oendl; | 1576 | owarn << "QTextImage: cannot decode " << bg.latin1() << "" << oendl; |
1557 | } | 1577 | } |
1558 | } | 1578 | } |
1559 | if ( !img.isNull() ) { | 1579 | if ( !img.isNull() ) { |
1560 | QPixmap pm; | 1580 | QPixmap pm; |
1561 | pm.convertFromImage( img ); | 1581 | pm.convertFromImage( img ); |
1562 | QBrush *b = new QBrush( QColor(), pm ); | 1582 | QBrush *b = new QBrush( QColor(), pm ); |
1563 | setPaper( b ); | 1583 | setPaper( b ); |
1564 | } | 1584 | } |
1565 | } | 1585 | } |
1566 | if ( attr.contains( "text" ) ) { | 1586 | if ( attr.contains( "text" ) ) { |
1567 | QColor c( attr["text"] ); | 1587 | QColor c( attr["text"] ); |
1568 | if ( formatCollection()->defaultFormat()->color() != c ) { | 1588 | if ( formatCollection()->defaultFormat()->color() != c ) { |
1569 | QDict<QTextFormat> formats = formatCollection()->dict(); | 1589 | QDict<QTextFormat> formats = formatCollection()->dict(); |
1570 | QDictIterator<QTextFormat> it( formats ); | 1590 | QDictIterator<QTextFormat> it( formats ); |
1571 | while ( it.current() ) { | 1591 | while ( it.current() ) { |
1572 | if ( it.current() == formatCollection()->defaultFormat() ) { | 1592 | if ( it.current() == formatCollection()->defaultFormat() ) { |
1573 | ++it; | 1593 | ++it; |
1574 | continue; | 1594 | continue; |
1575 | } | 1595 | } |
1576 | it.current()->setColor( c ); | 1596 | it.current()->setColor( c ); |
1577 | ++it; | 1597 | ++it; |
1578 | } | 1598 | } |
1579 | formatCollection()->defaultFormat()->setColor( c ); | 1599 | formatCollection()->defaultFormat()->setColor( c ); |
1580 | curtag.format.setColor( c ); | 1600 | curtag.format.setColor( c ); |
1581 | } | 1601 | } |
1582 | } | 1602 | } |
1583 | if ( attr.contains( "link" ) ) | 1603 | if ( attr.contains( "link" ) ) |
1584 | linkColor = QColor( attr["link"] ); | 1604 | linkColor = QColor( attr["link"] ); |
1585 | if ( attr.contains( "title" ) ) | 1605 | if ( attr.contains( "title" ) ) |
1586 | attribs.replace( "title", attr["title"] ); | 1606 | attribs.replace( "title", attr["title"] ); |
1587 | 1607 | ||
1588 | if ( textEditMode ) { | 1608 | if ( textEditMode ) { |
1589 | if ( attr.contains("style" ) ) { | 1609 | if ( attr.contains("style" ) ) { |
1590 | QString a = attr["style"]; | 1610 | QString a = attr["style"]; |
1591 | for ( int s = 0; s < a.contains(';')+1; s++ ) { | 1611 | for ( int s = 0; s < a.contains(';')+1; s++ ) { |
1592 | QString style = QTextDocument::section( a, ";", s, s ); | 1612 | QString style = QTextDocument::section( a, ";", s, s ); |
1593 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { | 1613 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { |
1594 | scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) / | 1614 | scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) / |
1595 | style.mid( 10, style.length() - 12 ).toInt(); | 1615 | style.mid( 10, style.length() - 12 ).toInt(); |
1596 | } | 1616 | } |
1597 | } | 1617 | } |
1598 | } | 1618 | } |
1599 | nstyle = 0; // ignore body in textEditMode | 1619 | nstyle = 0; // ignore body in textEditMode |
1600 | } | 1620 | } |
1601 | // end qt- and body-tag handling | 1621 | // end qt- and body-tag handling |
1602 | } else if ( tagname == "meta" ) { | 1622 | } else if ( tagname == "meta" ) { |
1603 | if ( attr["name"] == "qrichtext" && attr["content"] == "1" ) | 1623 | if ( attr["name"] == "qrichtext" && attr["content"] == "1" ) |
1604 | textEditMode = TRUE; | 1624 | textEditMode = TRUE; |
1605 | } else if ( tagname == "title" ) { | 1625 | } else if ( tagname == "title" ) { |
1606 | QString title; | 1626 | QString title; |
1607 | while ( pos < length ) { | 1627 | while ( pos < length ) { |
1608 | if ( hasPrefix( doc, length, pos, QChar('<') ) && hasPrefix( doc, length, pos+1, QChar('/') ) && | 1628 | if ( hasPrefix( doc, length, pos, QChar('<') ) && hasPrefix( doc, length, pos+1, QChar('/') ) && |
1609 | parseCloseTag( doc, length, pos ) == "title" ) | 1629 | parseCloseTag( doc, length, pos ) == "title" ) |
1610 | break; | 1630 | break; |
1611 | title += doc[ pos ]; | 1631 | title += doc[ pos ]; |
1612 | ++pos; | 1632 | ++pos; |
1613 | } | 1633 | } |
1614 | attribs.replace( "title", title ); | 1634 | attribs.replace( "title", title ); |
1615 | } | 1635 | } |
1616 | } // end of well-known tag handling | 1636 | } // end of well-known tag handling |
1617 | 1637 | ||
1618 | if ( !custom ) // try generic custom item | 1638 | if ( !custom ) // try generic custom item |
1619 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); | 1639 | custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this ); |
1620 | 1640 | ||
1621 | if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it | 1641 | if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it |
1622 | continue; | 1642 | continue; |
1623 | 1643 | ||
1624 | if ( custom ) { | 1644 | if ( custom ) { |
1625 | int index = QMAX( curpar->length(),1) - 1; | 1645 | int index = QMAX( curpar->length(),1) - 1; |
1626 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1646 | QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1627 | curpar->append( QChar('*') ); | 1647 | curpar->append( QChar('*') ); |
1628 | curpar->setFormat( index, 1, &format ); | 1648 | curpar->setFormat( index, 1, &format ); |
1629 | curpar->at( index )->setCustomItem( custom ); | 1649 | curpar->at( index )->setCustomItem( custom ); |
1630 | if ( !curtag.anchorHref.isEmpty() ) | 1650 | if ( !curtag.anchorHref.isEmpty() ) |
1631 | curpar->at(index)->setAnchor( QString::null, curtag.anchorHref ); | 1651 | curpar->at(index)->setAnchor( QString::null, curtag.anchorHref ); |
1632 | if ( !anchorName.isEmpty() ) { | 1652 | if ( !anchorName.isEmpty() ) { |
1633 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); | 1653 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); |
1634 | anchorName = QString::null; | 1654 | anchorName = QString::null; |
1635 | } | 1655 | } |
1636 | registerCustomItem( custom, curpar ); | 1656 | registerCustomItem( custom, curpar ); |
1637 | hasNewPar = FALSE; | 1657 | hasNewPar = FALSE; |
1638 | } else if ( !emptyTag ) { | 1658 | } else if ( !emptyTag ) { |
1639 | /* if we do nesting, push curtag on the stack, | 1659 | /* if we do nesting, push curtag on the stack, |
1640 | otherwise reinint curag. */ | 1660 | otherwise reinint curag. */ |
1641 | if ( curtag.style->name() != tagname || nstyle->selfNesting() ) { | 1661 | if ( curtag.style->name() != tagname || nstyle->selfNesting() ) { |
1642 | tags.push( curtag ); | 1662 | tags.push( curtag ); |
1643 | } else { | 1663 | } else { |
1644 | if ( !tags.isEmpty() ) | 1664 | if ( !tags.isEmpty() ) |
1645 | curtag = tags.top(); | 1665 | curtag = tags.top(); |
1646 | else | 1666 | else |
1647 | curtag = initag; | 1667 | curtag = initag; |
1648 | } | 1668 | } |
1649 | 1669 | ||
1650 | curtag.name = tagname; | 1670 | curtag.name = tagname; |
1651 | curtag.style = nstyle; | 1671 | curtag.style = nstyle; |
1652 | curtag.name = tagname; | 1672 | curtag.name = tagname; |
1653 | curtag.style = nstyle; | 1673 | curtag.style = nstyle; |
1654 | if ( int(nstyle->whiteSpaceMode()) != QStyleSheetItem::Undefined ) | 1674 | if ( int(nstyle->whiteSpaceMode()) != QStyleSheetItem::Undefined ) |
1655 | curtag.wsm = nstyle->whiteSpaceMode(); | 1675 | curtag.wsm = nstyle->whiteSpaceMode(); |
1656 | 1676 | ||
1657 | /* ignore whitespace for inline elements if there | 1677 | /* ignore whitespace for inline elements if there |
1658 | was already one*/ | 1678 | was already one*/ |
1659 | if ( !textEditMode && curtag.wsm == QStyleSheetItem::WhiteSpaceNormal | 1679 | if ( !textEditMode && curtag.wsm == QStyleSheetItem::WhiteSpaceNormal |
1660 | && ( space || nstyle->displayMode() != QStyleSheetItem::DisplayInline ) ) | 1680 | && ( space || nstyle->displayMode() != QStyleSheetItem::DisplayInline ) ) |
1661 | eatSpace( doc, length, pos ); | 1681 | eatSpace( doc, length, pos ); |
1662 | 1682 | ||
1663 | curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); | 1683 | curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor ); |
1664 | if ( nstyle->isAnchor() ) { | 1684 | if ( nstyle->isAnchor() ) { |
1665 | if ( !anchorName.isEmpty() ) | 1685 | if ( !anchorName.isEmpty() ) |
1666 | anchorName += "#" + attr["name"]; | 1686 | anchorName += "#" + attr["name"]; |
1667 | else | 1687 | else |
1668 | anchorName = attr["name"]; | 1688 | anchorName = attr["name"]; |
1669 | curtag.anchorHref = attr["href"]; | 1689 | curtag.anchorHref = attr["href"]; |
1670 | } | 1690 | } |
1671 | 1691 | ||
1672 | if ( nstyle->alignment() != QStyleSheetItem::Undefined ) | 1692 | if ( nstyle->alignment() != QStyleSheetItem::Undefined ) |
1673 | curtag.alignment = nstyle->alignment(); | 1693 | curtag.alignment = nstyle->alignment(); |
1674 | 1694 | ||
1675 | if ( (int) nstyle->listStyle() != QStyleSheetItem::Undefined ) | 1695 | if ( (int) nstyle->listStyle() != QStyleSheetItem::Undefined ) |
1676 | curtag.liststyle = nstyle->listStyle(); | 1696 | curtag.liststyle = nstyle->listStyle(); |
1677 | 1697 | ||
1678 | if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock | 1698 | if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock |
1679 | || nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1699 | || nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1680 | 1700 | ||
1681 | if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") { | 1701 | if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") { |
1682 | QString type = attr["type"]; | 1702 | QString type = attr["type"]; |
1683 | if ( !type.isEmpty() ) { | 1703 | if ( !type.isEmpty() ) { |
1684 | if ( type == "1" ) { | 1704 | if ( type == "1" ) { |
1685 | curtag.liststyle = QStyleSheetItem::ListDecimal; | 1705 | curtag.liststyle = QStyleSheetItem::ListDecimal; |
1686 | } else if ( type == "a" ) { | 1706 | } else if ( type == "a" ) { |
1687 | curtag.liststyle = QStyleSheetItem::ListLowerAlpha; | 1707 | curtag.liststyle = QStyleSheetItem::ListLowerAlpha; |
1688 | } else if ( type == "A" ) { | 1708 | } else if ( type == "A" ) { |
1689 | curtag.liststyle = QStyleSheetItem::ListUpperAlpha; | 1709 | curtag.liststyle = QStyleSheetItem::ListUpperAlpha; |
1690 | } else { | 1710 | } else { |
1691 | type = type.lower(); | 1711 | type = type.lower(); |
1692 | if ( type == "square" ) | 1712 | if ( type == "square" ) |
1693 | curtag.liststyle = QStyleSheetItem::ListSquare; | 1713 | curtag.liststyle = QStyleSheetItem::ListSquare; |
1694 | else if ( type == "disc" ) | 1714 | else if ( type == "disc" ) |
1695 | curtag.liststyle = QStyleSheetItem::ListDisc; | 1715 | curtag.liststyle = QStyleSheetItem::ListDisc; |
1696 | else if ( type == "circle" ) | 1716 | else if ( type == "circle" ) |
1697 | curtag.liststyle = QStyleSheetItem::ListCircle; | 1717 | curtag.liststyle = QStyleSheetItem::ListCircle; |
1698 | } | 1718 | } |
1699 | } | 1719 | } |
1700 | } | 1720 | } |
1701 | 1721 | ||
1702 | 1722 | ||
1703 | /* Internally we treat ordered and bullet | 1723 | /* Internally we treat ordered and bullet |
1704 | lists the same for margin calculations. In | 1724 | lists the same for margin calculations. In |
1705 | order to have fast pointer compares in the | 1725 | order to have fast pointer compares in the |
1706 | xMargin() functions we restrict ourselves to | 1726 | xMargin() functions we restrict ourselves to |
1707 | <ol>. Once we calculate the margins in the | 1727 | <ol>. Once we calculate the margins in the |
1708 | parser rathern than later, the unelegance of | 1728 | parser rathern than later, the unelegance of |
1709 | this approach goes awy | 1729 | this approach goes awy |
1710 | */ | 1730 | */ |
1711 | if ( nstyle->name() == "ul" ) | 1731 | if ( nstyle->name() == "ul" ) |
1712 | curtag.style = sheet_->item( "ol" ); | 1732 | curtag.style = sheet_->item( "ol" ); |
1713 | 1733 | ||
1714 | if ( attr.contains( "align" ) ) { | 1734 | if ( attr.contains( "align" ) ) { |
1715 | QString align = attr["align"]; | 1735 | QString align = attr["align"]; |
1716 | if ( align == "center" ) | 1736 | if ( align == "center" ) |
1717 | curtag.alignment = Qt::AlignCenter; | 1737 | curtag.alignment = Qt::AlignCenter; |
1718 | else if ( align == "right" ) | 1738 | else if ( align == "right" ) |
1719 | curtag.alignment = Qt::AlignRight; | 1739 | curtag.alignment = Qt::AlignRight; |
1720 | else if ( align == "justify" ) | 1740 | else if ( align == "justify" ) |
1721 | curtag.alignment = Qt3::AlignJustify; | 1741 | curtag.alignment = Qt3::AlignJustify; |
1722 | } | 1742 | } |
1723 | if ( attr.contains( "dir" ) ) { | 1743 | if ( attr.contains( "dir" ) ) { |
1724 | QString dir = attr["dir"]; | 1744 | QString dir = attr["dir"]; |
1725 | if ( dir == "rtl" ) | 1745 | if ( dir == "rtl" ) |
1726 | curtag.direction = QChar::DirR; | 1746 | curtag.direction = QChar::DirR; |
1727 | else if ( dir == "ltr" ) | 1747 | else if ( dir == "ltr" ) |
1728 | curtag.direction = QChar::DirL; | 1748 | curtag.direction = QChar::DirL; |
1729 | } | 1749 | } |
1730 | 1750 | ||
1731 | NEWPAR; | 1751 | NEWPAR; |
1732 | 1752 | ||
1733 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { | 1753 | if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) { |
1734 | if ( attr.contains( "value " ) ) | 1754 | if ( attr.contains( "value " ) ) |
1735 | curpar->setListValue( attr["value"].toInt() ); | 1755 | curpar->setListValue( attr["value"].toInt() ); |
1736 | } | 1756 | } |
1737 | 1757 | ||
1738 | if ( attr.contains( "style" ) ) { | 1758 | if ( attr.contains( "style" ) ) { |
1739 | QString a = attr["style"]; | 1759 | QString a = attr["style"]; |
1740 | bool ok = TRUE; | 1760 | bool ok = TRUE; |
1741 | for ( int s = 0; ok && s < a.contains(';')+1; s++ ) { | 1761 | for ( int s = 0; ok && s < a.contains(';')+1; s++ ) { |
1742 | QString style = QTextDocument::section( a, ";", s, s ); | 1762 | QString style = QTextDocument::section( a, ";", s, s ); |
1743 | if ( style.startsWith("margin-top:" ) && QTextDocument::endsWith(style, "px") ) | 1763 | if ( style.startsWith("margin-top:" ) && QTextDocument::endsWith(style, "px") ) |
1744 | curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok); | 1764 | curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok); |
1745 | else if ( style.startsWith("margin-bottom:" ) && QTextDocument::endsWith(style, "px") ) | 1765 | else if ( style.startsWith("margin-bottom:" ) && QTextDocument::endsWith(style, "px") ) |
1746 | curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok); | 1766 | curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok); |
1747 | else if ( style.startsWith("margin-left:" ) && QTextDocument::endsWith(style, "px") ) | 1767 | else if ( style.startsWith("margin-left:" ) && QTextDocument::endsWith(style, "px") ) |
1748 | curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok); | 1768 | curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok); |
1749 | else if ( style.startsWith("margin-right:" ) && QTextDocument::endsWith(style, "px") ) | 1769 | else if ( style.startsWith("margin-right:" ) && QTextDocument::endsWith(style, "px") ) |
1750 | curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok); | 1770 | curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok); |
1751 | else if ( style.startsWith("text-indent:" ) && QTextDocument::endsWith(style, "px") ) | 1771 | else if ( style.startsWith("text-indent:" ) && QTextDocument::endsWith(style, "px") ) |
1752 | curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok); | 1772 | curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok); |
1753 | } | 1773 | } |
1754 | if ( !ok ) // be pressmistic | 1774 | if ( !ok ) // be pressmistic |
1755 | curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0; | 1775 | curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0; |
1756 | } | 1776 | } |
1757 | } | 1777 | } |
1758 | } | 1778 | } |
1759 | } else { | 1779 | } else { |
1760 | QString tagname = parseCloseTag( doc, length, pos ); | 1780 | QString tagname = parseCloseTag( doc, length, pos ); |
1761 | if ( tagname.isEmpty() ) | 1781 | if ( tagname.isEmpty() ) |
1762 | continue; // nothing we could do with this, probably parse error | 1782 | continue; // nothing we could do with this, probably parse error |
1763 | if ( !sheet_->item( tagname ) ) // ignore unknown tags | 1783 | if ( !sheet_->item( tagname ) ) // ignore unknown tags |
1764 | continue; | 1784 | continue; |
1765 | 1785 | ||
1766 | // we close a block item. Since the text may continue, we need to have a new paragraph | 1786 | // we close a block item. Since the text may continue, we need to have a new paragraph |
1767 | bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock | 1787 | bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock |
1768 | || curtag.style->displayMode() == QStyleSheetItem::DisplayListItem; | 1788 | || curtag.style->displayMode() == QStyleSheetItem::DisplayListItem; |
1769 | 1789 | ||
1770 | 1790 | ||
1771 | // html slopiness: handle unbalanched tag closing | 1791 | // html slopiness: handle unbalanched tag closing |
1772 | while ( curtag.name != tagname ) { | 1792 | while ( curtag.name != tagname ) { |
1773 | QString msg; | 1793 | QString msg; |
1774 | msg.sprintf( "QText Warning: Document not valid ( '%s' not closed before '%s' #%d)", | 1794 | msg.sprintf( "QText Warning: Document not valid ( '%s' not closed before '%s' #%d)", |
1775 | curtag.name.ascii(), tagname.ascii(), pos); | 1795 | curtag.name.ascii(), tagname.ascii(), pos); |
1776 | sheet_->error( msg ); | 1796 | sheet_->error( msg ); |
1777 | if ( tags.isEmpty() ) | 1797 | if ( tags.isEmpty() ) |
1778 | break; | 1798 | break; |
1779 | curtag = tags.pop(); | 1799 | curtag = tags.pop(); |
1780 | } | 1800 | } |
1781 | 1801 | ||
1782 | 1802 | ||
1783 | // close the tag | 1803 | // close the tag |
1784 | if ( !tags.isEmpty() ) | 1804 | if ( !tags.isEmpty() ) |
1785 | curtag = tags.pop(); | 1805 | curtag = tags.pop(); |
1786 | else | 1806 | else |
1787 | curtag = initag; | 1807 | curtag = initag; |
1788 | 1808 | ||
1789 | if ( needNewPar ) { | 1809 | if ( needNewPar ) { |
1790 | if ( textEditMode && tagname == "p" ) // preserve empty paragraphs | 1810 | if ( textEditMode && tagname == "p" ) // preserve empty paragraphs |
1791 | hasNewPar = FALSE; | 1811 | hasNewPar = FALSE; |
1792 | NEWPAR; | 1812 | NEWPAR; |
1793 | } | 1813 | } |
1794 | } | 1814 | } |
1795 | } else { | 1815 | } else { |
1796 | // normal contents | 1816 | // normal contents |
1797 | QString s; | 1817 | QString s; |
1798 | QChar c; | 1818 | QChar c; |
1799 | while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){ | 1819 | while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){ |
1800 | if ( textEditMode ) { | 1820 | if ( textEditMode ) { |
1801 | // text edit mode: we handle all white space but ignore newlines | 1821 | // text edit mode: we handle all white space but ignore newlines |
1802 | c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre ); | 1822 | c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre ); |
1803 | if ( c == QChar_linesep ) | 1823 | if ( c == QChar_linesep ) |
1804 | break; | 1824 | break; |
1805 | } else { | 1825 | } else { |
1806 | int l = pos; | 1826 | int l = pos; |
1807 | c = parseChar( doc, length, pos, curtag.wsm ); | 1827 | c = parseChar( doc, length, pos, curtag.wsm ); |
1808 | 1828 | ||
1809 | // in white space pre mode: treat any space as non breakable | 1829 | // in white space pre mode: treat any space as non breakable |
1810 | if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre ) | 1830 | if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre ) |
1811 | c = QChar::nbsp; | 1831 | c = QChar::nbsp; |
1812 | 1832 | ||
1813 | if ( c == ' ' || c == QChar_linesep ) { | 1833 | if ( c == ' ' || c == QChar_linesep ) { |
1814 | /* avoid overlong paragraphs by forcing a new | 1834 | /* avoid overlong paragraphs by forcing a new |
1815 | paragraph after 4096 characters. This case can | 1835 | paragraph after 4096 characters. This case can |
1816 | occur when loading undiscovered plain text | 1836 | occur when loading undiscovered plain text |
1817 | documents in rich text mode. Instead of hanging | 1837 | documents in rich text mode. Instead of hanging |
1818 | forever, we do the trick. | 1838 | forever, we do the trick. |
1819 | */ | 1839 | */ |
1820 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do { | 1840 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do { |
1821 | if ( doc[l] == '\n' ) { | 1841 | if ( doc[l] == '\n' ) { |
1822 | hasNewPar = FALSE; // for a new paragraph ... | 1842 | hasNewPar = FALSE; // for a new paragraph ... |
1823 | NEWPAR; | 1843 | NEWPAR; |
1824 | hasNewPar = FALSE; // ... and make it non-reusable | 1844 | hasNewPar = FALSE; // ... and make it non-reusable |
1825 | c = '\n'; // make sure we break below | 1845 | c = '\n'; // make sure we break below |
1826 | break; | 1846 | break; |
1827 | } | 1847 | } |
1828 | } while ( ++l < pos ); | 1848 | } while ( ++l < pos ); |
1829 | } | 1849 | } |
1830 | } | 1850 | } |
1831 | 1851 | ||
1832 | if ( c == '\n' ) | 1852 | if ( c == '\n' ) |
1833 | break; // break on newlines, pre delievers a QChar_linesep | 1853 | break; // break on newlines, pre delievers a QChar_linesep |
1834 | 1854 | ||
1835 | bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode; | 1855 | bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode; |
1836 | 1856 | ||
1837 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space ) | 1857 | if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space ) |
1838 | continue; | 1858 | continue; |
1839 | if ( c == '\r' ) | 1859 | if ( c == '\r' ) |
1840 | continue; | 1860 | continue; |
1841 | space = c_isSpace; | 1861 | space = c_isSpace; |
1842 | s += c; | 1862 | s += c; |
1843 | } | 1863 | } |
1844 | if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) { | 1864 | if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) { |
1845 | hasNewPar = FALSE; | 1865 | hasNewPar = FALSE; |
1846 | int index = QMAX( curpar->length(),1) - 1; | 1866 | int index = QMAX( curpar->length(),1) - 1; |
1847 | curpar->append( s ); | 1867 | curpar->append( s ); |
1848 | QTextFormat* f = formatCollection()->format( &curtag.format ); | 1868 | QTextFormat* f = formatCollection()->format( &curtag.format ); |
1849 | curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already | 1869 | curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already |
1850 | f->ref += s.length() -1; // that what friends are for... | 1870 | f->ref += s.length() -1; // that what friends are for... |
1851 | if ( !curtag.anchorHref.isEmpty() ) { | 1871 | if ( !curtag.anchorHref.isEmpty() ) { |
1852 | for ( int i = 0; i < int(s.length()); i++ ) | 1872 | for ( int i = 0; i < int(s.length()); i++ ) |
1853 | curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref ); | 1873 | curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref ); |
1854 | } | 1874 | } |
1855 | if ( !anchorName.isEmpty() ) { | 1875 | if ( !anchorName.isEmpty() ) { |
1856 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); | 1876 | curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() ); |
1857 | anchorName = QString::null; | 1877 | anchorName = QString::null; |
1858 | } | 1878 | } |
1859 | } | 1879 | } |
1860 | } | 1880 | } |
1861 | } | 1881 | } |
1862 | if ( hasNewPar && curpar != fParag && !cursor ) { | 1882 | if ( hasNewPar && curpar != fParag && !cursor ) { |
1863 | // cleanup unused last paragraphs | 1883 | // cleanup unused last paragraphs |
1864 | curpar = curpar->p; | 1884 | curpar = curpar->p; |
1865 | delete curpar->n; | 1885 | delete curpar->n; |
1866 | } | 1886 | } |
1867 | if ( !anchorName.isEmpty() ) { | 1887 | if ( !anchorName.isEmpty() ) { |
1868 | curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() ); | 1888 | curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() ); |
1869 | anchorName = QString::null; | 1889 | anchorName = QString::null; |
1870 | } | 1890 | } |
1871 | 1891 | ||
1872 | 1892 | ||
1873 | setRichTextMarginsInternal( styles, stylesPar ); | 1893 | setRichTextMarginsInternal( styles, stylesPar ); |
1874 | 1894 | ||
1875 | if ( cursor ) { | 1895 | if ( cursor ) { |
1876 | cursor->gotoPreviousLetter(); | 1896 | cursor->gotoPreviousLetter(); |
1877 | cursor->remove(); | 1897 | cursor->remove(); |
1878 | } | 1898 | } |
1879 | 1899 | ||
1880 | } | 1900 | } |
1881 | 1901 | ||
1882 | void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar ) | 1902 | void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar ) |
1883 | { | 1903 | { |
1884 | // margin and line spacing calculation | 1904 | // margin and line spacing calculation |
1885 | QPtrVector<QStyleSheetItem>* prevStyle = 0; | 1905 | QPtrVector<QStyleSheetItem>* prevStyle = 0; |
1886 | QPtrVector<QStyleSheetItem>* curStyle = styles.first(); | 1906 | QPtrVector<QStyleSheetItem>* curStyle = styles.first(); |
1887 | QPtrVector<QStyleSheetItem>* nextStyle = styles.next(); | 1907 | QPtrVector<QStyleSheetItem>* nextStyle = styles.next(); |
1888 | while ( stylesPar ) { | 1908 | while ( stylesPar ) { |
1889 | if ( !curStyle ) { | 1909 | if ( !curStyle ) { |
1890 | stylesPar = stylesPar->next(); | 1910 | stylesPar = stylesPar->next(); |
1891 | prevStyle = curStyle; | 1911 | prevStyle = curStyle; |
1892 | curStyle = nextStyle; | 1912 | curStyle = nextStyle; |
1893 | nextStyle = styles.next(); | 1913 | nextStyle = styles.next(); |
1894 | continue; | 1914 | continue; |
1895 | } | 1915 | } |
1896 | 1916 | ||
1897 | int i, mar; | 1917 | int i, mar; |
1898 | QStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0; | 1918 | QStyleSheetItem* mainStyle = (*curStyle)[curStyle->size()-1]; |
1899 | if ( mainStyle && mainStyle->displayMode() == QStyleSheetItem::DisplayListItem ) | 1919 | if ( !mainStyle ) |
1920 | return; | ||
1921 | |||
1922 | if ( mainStyle->displayMode() == QStyleSheetItem::DisplayListItem ) | ||
1900 | stylesPar->setListItem( TRUE ); | 1923 | stylesPar->setListItem( TRUE ); |
1901 | int numLists = 0; | 1924 | int numLists = 0; |
1902 | for ( i = 0; i < (int)curStyle->size(); ++i ) { | 1925 | for ( i = 0; i < (int)curStyle->size(); ++i ) { |
1903 | if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock | 1926 | if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock |
1904 | && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) | 1927 | && int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) |
1905 | numLists++; | 1928 | numLists++; |
1906 | } | 1929 | } |
1907 | stylesPar->ldepth = numLists; | 1930 | stylesPar->ldepth = numLists; |
1908 | if ( stylesPar->next() && nextStyle ) { | 1931 | if ( stylesPar->next() && nextStyle ) { |
1909 | // also set the depth of the next paragraph, required for the margin calculation | 1932 | // also set the depth of the next paragraph, required for the margin calculation |
1910 | numLists = 0; | 1933 | numLists = 0; |
1911 | for ( i = 0; i < (int)nextStyle->size(); ++i ) { | 1934 | for ( i = 0; i < (int)nextStyle->size(); ++i ) { |
1912 | if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock | 1935 | if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock |
1913 | && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) | 1936 | && int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined ) |
1914 | numLists++; | 1937 | numLists++; |
1915 | } | 1938 | } |
1916 | stylesPar->next()->ldepth = numLists; | 1939 | stylesPar->next()->ldepth = numLists; |
1917 | } | 1940 | } |
1918 | 1941 | ||
1919 | // do the top margin | 1942 | // do the top margin |
1920 | QStyleSheetItem* item = mainStyle; | 1943 | QStyleSheetItem* item = mainStyle; |
1921 | int m; | 1944 | int m; |
1922 | if (stylesPar->utm > 0 ) { | 1945 | if (stylesPar->utm > 0 ) { |
1923 | m = stylesPar->utm-1; | 1946 | m = stylesPar->utm-1; |
1924 | stylesPar->utm = 0; | 1947 | stylesPar->utm = 0; |
1925 | } else { | 1948 | } else { |
1926 | m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) ); | 1949 | m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) ); |
1927 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem | 1950 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem |
1928 | && stylesPar->ldepth ) | 1951 | && stylesPar->ldepth ) |
1929 | m /= stylesPar->ldepth; | 1952 | m /= stylesPar->ldepth; |
1930 | } | 1953 | } |
1931 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 1954 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
1932 | item = (*curStyle)[ i ]; | 1955 | item = (*curStyle)[ i ]; |
1933 | if ( prevStyle && i < (int) prevStyle->size() && | 1956 | if ( prevStyle && i < (int) prevStyle->size() && |
1934 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && | 1957 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && |
1935 | (*prevStyle)[ i ] == item ) ) | 1958 | (*prevStyle)[ i ] == item ) ) |
1936 | break; | 1959 | break; |
1937 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags | 1960 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags |
1938 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && | 1961 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && |
1939 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) | 1962 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) |
1940 | continue; | 1963 | continue; |
1941 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) ); | 1964 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) ); |
1942 | m = QMAX( m, mar ); | 1965 | m = QMAX( m, mar ); |
1943 | } | 1966 | } |
1944 | stylesPar->utm = m - stylesPar->topMargin(); | 1967 | stylesPar->utm = m - stylesPar->topMargin(); |
1945 | 1968 | ||
1946 | // do the bottom margin | 1969 | // do the bottom margin |
1947 | item = mainStyle; | 1970 | item = mainStyle; |
1948 | if (stylesPar->ubm > 0 ) { | 1971 | if (stylesPar->ubm > 0 ) { |
1949 | m = stylesPar->ubm-1; | 1972 | m = stylesPar->ubm-1; |
1950 | stylesPar->ubm = 0; | 1973 | stylesPar->ubm = 0; |
1951 | } else { | 1974 | } else { |
1952 | m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); | 1975 | m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); |
1953 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem | 1976 | if ( item->displayMode() == QStyleSheetItem::DisplayListItem |
1954 | && stylesPar->ldepth ) | 1977 | && stylesPar->ldepth ) |
1955 | m /= stylesPar->ldepth; | 1978 | m /= stylesPar->ldepth; |
1956 | } | 1979 | } |
1957 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 1980 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
1958 | item = (*curStyle)[ i ]; | 1981 | item = (*curStyle)[ i ]; |
1959 | if ( nextStyle && i < (int) nextStyle->size() && | 1982 | if ( nextStyle && i < (int) nextStyle->size() && |
1960 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && | 1983 | ( item->displayMode() == QStyleSheetItem::DisplayBlock && |
1961 | (*nextStyle)[ i ] == item ) ) | 1984 | (*nextStyle)[ i ] == item ) ) |
1962 | break; | 1985 | break; |
1963 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags | 1986 | // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags |
1964 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && | 1987 | if ( int(item->listStyle()) != QStyleSheetItem::Undefined && |
1965 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) | 1988 | ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) ) |
1966 | continue; | 1989 | continue; |
1967 | mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); | 1990 | mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); |
1968 | m = QMAX( m, mar ); | 1991 | m = QMAX( m, mar ); |
1969 | } | 1992 | } |
1970 | stylesPar->ubm = m - stylesPar->bottomMargin(); | 1993 | stylesPar->ubm = m - stylesPar->bottomMargin(); |
1971 | 1994 | ||
1972 | // do the left margin, simplyfied | 1995 | // do the left margin, simplyfied |
1973 | item = mainStyle; | 1996 | item = mainStyle; |
1974 | if (stylesPar->ulm > 0 ) { | 1997 | if (stylesPar->ulm > 0 ) { |
1975 | m = stylesPar->ulm-1; | 1998 | m = stylesPar->ulm-1; |
1976 | stylesPar->ulm = 0; | 1999 | stylesPar->ulm = 0; |
1977 | } else { | 2000 | } else { |
1978 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); | 2001 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); |
1979 | } | 2002 | } |
1980 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 2003 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
1981 | item = (*curStyle)[ i ]; | 2004 | item = (*curStyle)[ i ]; |
1982 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); | 2005 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); |
1983 | } | 2006 | } |
1984 | stylesPar->ulm = m - stylesPar->leftMargin(); | 2007 | stylesPar->ulm = m - stylesPar->leftMargin(); |
1985 | 2008 | ||
1986 | // do the right margin, simplyfied | 2009 | // do the right margin, simplyfied |
1987 | item = mainStyle; | 2010 | item = mainStyle; |
1988 | if (stylesPar->urm > 0 ) { | 2011 | if (stylesPar->urm > 0 ) { |
1989 | m = stylesPar->urm-1; | 2012 | m = stylesPar->urm-1; |
1990 | stylesPar->urm = 0; | 2013 | stylesPar->urm = 0; |
1991 | } else { | 2014 | } else { |
1992 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); | 2015 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); |
1993 | } | 2016 | } |
1994 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 2017 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
1995 | item = (*curStyle)[ i ]; | 2018 | item = (*curStyle)[ i ]; |
1996 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); | 2019 | m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); |
1997 | } | 2020 | } |
1998 | stylesPar->urm = m - stylesPar->rightMargin(); | 2021 | stylesPar->urm = m - stylesPar->rightMargin(); |
1999 | 2022 | ||
2000 | // do the first line margin, which really should be called text-indent | 2023 | // do the first line margin, which really should be called text-indent |
2001 | item = mainStyle; | 2024 | item = mainStyle; |
2002 | if (stylesPar->uflm > 0 ) { | 2025 | if (stylesPar->uflm > 0 ) { |
2003 | m = stylesPar->uflm-1; | 2026 | m = stylesPar->uflm-1; |
2004 | stylesPar->uflm = 0; | 2027 | stylesPar->uflm = 0; |
2005 | } else { | 2028 | } else { |
2006 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); | 2029 | m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); |
2007 | } | 2030 | } |
2008 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { | 2031 | for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { |
2009 | item = (*curStyle)[ i ]; | 2032 | item = (*curStyle)[ i ]; |
2010 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); | 2033 | mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); |
2011 | m = QMAX( m, mar ); | 2034 | m = QMAX( m, mar ); |
2012 | } | 2035 | } |
2013 | stylesPar->uflm =m - stylesPar->firstLineMargin(); | 2036 | stylesPar->uflm =m - stylesPar->firstLineMargin(); |
2014 | 2037 | ||
2015 | // do the bogus line "spacing", which really is just an extra margin | 2038 | // do the bogus line "spacing", which really is just an extra margin |
2016 | item = mainStyle; | 2039 | item = mainStyle; |
2017 | for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) { | 2040 | for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) { |
2018 | item = (*curStyle)[ i ]; | 2041 | item = (*curStyle)[ i ]; |
2019 | if ( item->lineSpacing() != QStyleSheetItem::Undefined ) { | 2042 | if ( item->lineSpacing() != QStyleSheetItem::Undefined ) { |
2020 | stylesPar->ulinespacing = item->lineSpacing(); | 2043 | stylesPar->ulinespacing = item->lineSpacing(); |
2021 | if ( formatCollection() && | 2044 | if ( formatCollection() && |
2022 | stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() ) | 2045 | stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() ) |
2023 | stylesPar->ulinespacing += formatCollection()->defaultFormat()->height(); | 2046 | stylesPar->ulinespacing += formatCollection()->defaultFormat()->height(); |
2024 | break; | 2047 | break; |
2025 | } | 2048 | } |
2026 | } | 2049 | } |
2027 | 2050 | ||
2028 | stylesPar = stylesPar->next(); | 2051 | stylesPar = stylesPar->next(); |
2029 | prevStyle = curStyle; | 2052 | prevStyle = curStyle; |
2030 | curStyle = nextStyle; | 2053 | curStyle = nextStyle; |
2031 | nextStyle = styles.next(); | 2054 | nextStyle = styles.next(); |
2032 | } | 2055 | } |
2033 | } | 2056 | } |
2034 | 2057 | ||
2035 | void QTextDocument::setText( const QString &text, const QString &context ) | 2058 | void QTextDocument::setText( const QString &text, const QString &context ) |
2036 | { | 2059 | { |
2037 | focusIndicator.parag = 0; | 2060 | focusIndicator.parag = 0; |
2038 | selections.clear(); | 2061 | selections.clear(); |
2039 | if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) || | 2062 | if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) || |
2040 | txtFormat == Qt::RichText ) | 2063 | txtFormat == Qt::RichText ) |
2041 | setRichText( text, context ); | 2064 | setRichText( text, context ); |
2042 | else | 2065 | else |
2043 | setPlainText( text ); | 2066 | setPlainText( text ); |
2044 | } | 2067 | } |
2045 | 2068 | ||
2046 | QString QTextDocument::plainText() const | 2069 | QString QTextDocument::plainText() const |
2047 | { | 2070 | { |
2048 | QString buffer; | 2071 | QString buffer; |
2049 | QString s; | 2072 | QString s; |
2050 | QTextParagraph *p = fParag; | 2073 | QTextParagraph *p = fParag; |
2051 | while ( p ) { | 2074 | while ( p ) { |
2052 | if ( !p->mightHaveCustomItems ) { | 2075 | if ( !p->mightHaveCustomItems ) { |
2053 | s = p->string()->toString(); | 2076 | s = p->string()->toString(); |
2054 | } else { | 2077 | } else { |
2055 | for ( int i = 0; i < p->length() - 1; ++i ) { | 2078 | for ( int i = 0; i < p->length() - 1; ++i ) { |
2056 | if ( p->at( i )->isCustom() ) { | 2079 | if ( p->at( i )->isCustom() ) { |
2057 | if ( p->at( i )->customItem()->isNested() ) { | 2080 | if ( p->at( i )->customItem()->isNested() ) { |
2058 | s += "\n"; | 2081 | s += "\n"; |
2059 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 2082 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
2060 | QPtrList<QTextTableCell> cells = t->tableCells(); | 2083 | QPtrList<QTextTableCell> cells = t->tableCells(); |
2061 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) | 2084 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) |
2062 | s += c->richText()->plainText() + "\n"; | 2085 | s += c->richText()->plainText() + "\n"; |
2063 | s += "\n"; | 2086 | s += "\n"; |
2064 | } | 2087 | } |
2065 | } else { | 2088 | } else { |
2066 | s += p->at( i )->c; | 2089 | s += p->at( i )->c; |
2067 | } | 2090 | } |
2068 | } | 2091 | } |
2069 | } | 2092 | } |
2070 | s.remove( s.length() - 1, 1 ); | 2093 | s.remove( s.length() - 1, 1 ); |
2071 | if ( p->next() ) | 2094 | if ( p->next() ) |
2072 | s += "\n"; | 2095 | s += "\n"; |
2073 | buffer += s; | 2096 | buffer += s; |
2074 | p = p->next(); | 2097 | p = p->next(); |
2075 | } | 2098 | } |
2076 | return buffer; | 2099 | return buffer; |
2077 | } | 2100 | } |
2078 | 2101 | ||
2079 | static QString align_to_string( int a ) | 2102 | static QString align_to_string( int a ) |
2080 | { | 2103 | { |
2081 | if ( a & Qt::AlignRight ) | 2104 | if ( a & Qt::AlignRight ) |
2082 | return " align=\"right\""; | 2105 | return " align=\"right\""; |
2083 | if ( a & Qt::AlignHCenter ) | 2106 | if ( a & Qt::AlignHCenter ) |
2084 | return " align=\"center\""; | 2107 | return " align=\"center\""; |
2085 | if ( a & Qt3::AlignJustify ) | 2108 | if ( a & Qt3::AlignJustify ) |
2086 | return " align=\"justify\""; | 2109 | return " align=\"justify\""; |
2087 | return QString::null; | 2110 | return QString::null; |
2088 | } | 2111 | } |
2089 | 2112 | ||
2090 | static QString direction_to_string( int d ) | 2113 | static QString direction_to_string( int d ) |
2091 | { | 2114 | { |
2092 | if ( d != QChar::DirON ) | 2115 | if ( d != QChar::DirON ) |
2093 | return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" ); | 2116 | return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" ); |
2094 | return QString::null; | 2117 | return QString::null; |
2095 | } | 2118 | } |
2096 | 2119 | ||
2097 | static QString list_value_to_string( int v ) | 2120 | static QString list_value_to_string( int v ) |
2098 | { | 2121 | { |
2099 | if ( v != -1 ) | 2122 | if ( v != -1 ) |
2100 | return " listvalue=\"" + QString::number( v ) + "\""; | 2123 | return " listvalue=\"" + QString::number( v ) + "\""; |
2101 | return QString::null; | 2124 | return QString::null; |
2102 | } | 2125 | } |
2103 | 2126 | ||
2104 | static QString list_style_to_string( int v ) | 2127 | static QString list_style_to_string( int v ) |
2105 | { | 2128 | { |
2106 | switch( v ) { | 2129 | switch( v ) { |
2107 | case QStyleSheetItem::ListDecimal: return "\"1\""; | 2130 | case QStyleSheetItem::ListDecimal: return "\"1\""; |
2108 | case QStyleSheetItem::ListLowerAlpha: return "\"a\""; | 2131 | case QStyleSheetItem::ListLowerAlpha: return "\"a\""; |
2109 | case QStyleSheetItem::ListUpperAlpha: return "\"A\""; | 2132 | case QStyleSheetItem::ListUpperAlpha: return "\"A\""; |
2110 | case QStyleSheetItem::ListDisc: return "\"disc\""; | 2133 | case QStyleSheetItem::ListDisc: return "\"disc\""; |
2111 | case QStyleSheetItem::ListSquare: return "\"square\""; | 2134 | case QStyleSheetItem::ListSquare: return "\"square\""; |
2112 | case QStyleSheetItem::ListCircle: return "\"circle\""; | 2135 | case QStyleSheetItem::ListCircle: return "\"circle\""; |
2113 | default: | 2136 | default: |
2114 | return QString::null; | 2137 | return QString::null; |
2115 | } | 2138 | } |
2116 | } | 2139 | } |
2117 | 2140 | ||
2118 | static inline bool list_is_ordered( int v ) | 2141 | static inline bool list_is_ordered( int v ) |
2119 | { | 2142 | { |
2120 | return v == QStyleSheetItem::ListDecimal || | 2143 | return v == QStyleSheetItem::ListDecimal || |
2121 | v == QStyleSheetItem::ListLowerAlpha || | 2144 | v == QStyleSheetItem::ListLowerAlpha || |
2122 | v == QStyleSheetItem::ListUpperAlpha; | 2145 | v == QStyleSheetItem::ListUpperAlpha; |
2123 | } | 2146 | } |
2124 | 2147 | ||
2125 | 2148 | ||
2126 | static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl ) | 2149 | static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl ) |
2127 | { | 2150 | { |
2128 | QString s; | 2151 | QString s; |
2129 | if ( l > 0 ) | 2152 | if ( l > 0 ) |
2130 | s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px"; | 2153 | s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px"; |
2131 | if ( r > 0 ) | 2154 | if ( r > 0 ) |
2132 | s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px"; | 2155 | s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px"; |
2133 | if ( t > 0 ) | 2156 | if ( t > 0 ) |
2134 | s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px"; | 2157 | s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px"; |
2135 | if ( b > 0 ) | 2158 | if ( b > 0 ) |
2136 | s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px"; | 2159 | s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px"; |
2137 | if ( fl > 0 ) | 2160 | if ( fl > 0 ) |
2138 | s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px"; | 2161 | s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px"; |
2139 | if ( !!s ) | 2162 | if ( !!s ) |
2140 | return " style=\"" + s + "\""; | 2163 | return " style=\"" + s + "\""; |
2141 | return QString::null; | 2164 | return QString::null; |
2142 | } | 2165 | } |
2143 | 2166 | ||
2144 | QString QTextDocument::richText() const | 2167 | QString QTextDocument::richText() const |
2145 | { | 2168 | { |
2146 | QString s = ""; | 2169 | QString s = ""; |
2147 | if ( !par ) { | 2170 | if ( !par ) { |
2148 | s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ; | 2171 | s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ; |
2149 | s += QString::number( formatCollection()->defaultFormat()->font().pointSize() ); | 2172 | s += QString::number( formatCollection()->defaultFormat()->font().pointSize() ); |
2150 | s += "pt;font-family:"; | 2173 | s += "pt;font-family:"; |
2151 | s += formatCollection()->defaultFormat()->font().family(); | 2174 | s += formatCollection()->defaultFormat()->font().family(); |
2152 | s +="\">"; | 2175 | s +="\">"; |
2153 | } | 2176 | } |
2154 | QTextParagraph* p = fParag; | 2177 | QTextParagraph* p = fParag; |
2155 | 2178 | ||
2156 | QStyleSheetItem* item_p = styleSheet()->item("p"); | 2179 | QStyleSheetItem* item_p = styleSheet()->item("p"); |
2157 | QStyleSheetItem* item_ul = styleSheet()->item("ul"); | 2180 | QStyleSheetItem* item_ul = styleSheet()->item("ul"); |
2158 | QStyleSheetItem* item_ol = styleSheet()->item("ol"); | 2181 | QStyleSheetItem* item_ol = styleSheet()->item("ol"); |
2159 | QStyleSheetItem* item_li = styleSheet()->item("li"); | 2182 | QStyleSheetItem* item_li = styleSheet()->item("li"); |
2160 | if ( !item_p || !item_ul || !item_ol || !item_li ) { | 2183 | if ( !item_p || !item_ul || !item_ol || !item_li ) { |
2161 | owarn << "QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, ul, ol, or li)" << oendl; | 2184 | owarn << "QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, ul, ol, or li)" << oendl; |
2162 | return QString::null; | 2185 | return QString::null; |
2163 | } | 2186 | } |
2164 | int pastListDepth = 0; | 2187 | int pastListDepth = 0; |
2165 | int listDepth = 0; | 2188 | int listDepth = 0; |
2166 | int futureListDepth = 0; | 2189 | int futureListDepth = 0; |
2167 | QMemArray<int> listStyles(10); | 2190 | QMemArray<int> listStyles(10); |
2168 | 2191 | ||
2169 | while ( p ) { | 2192 | while ( p ) { |
2170 | listDepth = p->listDepth(); | 2193 | listDepth = p->listDepth(); |
2171 | if ( listDepth < pastListDepth ) { | 2194 | if ( listDepth < pastListDepth ) { |
2172 | for ( int i = listDepth+1; i <= pastListDepth; i++ ) | 2195 | for ( int i = listDepth+1; i <= pastListDepth; i++ ) |
2173 | s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>"; | 2196 | s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>"; |
2174 | s += '\n'; | 2197 | s += '\n'; |
2175 | } else if ( listDepth > pastListDepth ) { | 2198 | } else if ( listDepth > pastListDepth ) { |
2176 | s += '\n'; | 2199 | s += '\n'; |
2177 | listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) ); | 2200 | listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) ); |
2178 | QString list_type; | 2201 | QString list_type; |
2179 | listStyles[listDepth] = p->listStyle(); | 2202 | listStyles[listDepth] = p->listStyle(); |
2180 | if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() ) | 2203 | if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() ) |
2181 | list_type = " type=" + list_style_to_string( p->listStyle() ); | 2204 | list_type = " type=" + list_style_to_string( p->listStyle() ); |
2182 | for ( int i = pastListDepth; i < listDepth; i++ ) { | 2205 | for ( int i = pastListDepth; i < listDepth; i++ ) { |
2183 | s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ; | 2206 | s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ; |
2184 | s += list_type + ">"; | 2207 | s += list_type + ">"; |
2185 | } | 2208 | } |
2186 | } else { | 2209 | } else { |
2187 | s += '\n'; | 2210 | s += '\n'; |
2188 | } | 2211 | } |
2189 | 2212 | ||
2190 | QString ps = p->richText(); | 2213 | QString ps = p->richText(); |
2191 | 2214 | ||
2192 | // for the bottom margin we need to know whether we are at the end of a list | 2215 | // for the bottom margin we need to know whether we are at the end of a list |
2193 | futureListDepth = 0; | 2216 | futureListDepth = 0; |
2194 | if ( listDepth > 0 && p->next() ) | 2217 | if ( listDepth > 0 && p->next() ) |
2195 | futureListDepth = p->next()->listDepth(); | 2218 | futureListDepth = p->next()->listDepth(); |
2196 | 2219 | ||
2197 | if ( richTextExportStart && richTextExportStart->paragraph() ==p && | 2220 | if ( richTextExportStart && richTextExportStart->paragraph() ==p && |
2198 | richTextExportStart->index() == 0 ) | 2221 | richTextExportStart->index() == 0 ) |
2199 | s += "<selstart/>"; | 2222 | s += "<selstart/>"; |
2200 | 2223 | ||
2201 | if ( p->isListItem() ) { | 2224 | if ( p->isListItem() ) { |
2202 | s += "<li"; | 2225 | s += "<li"; |
2203 | if ( p->listStyle() != listStyles[listDepth] ) | 2226 | if ( p->listStyle() != listStyles[listDepth] ) |
2204 | s += " type=" + list_style_to_string( p->listStyle() ); | 2227 | s += " type=" + list_style_to_string( p->listStyle() ); |
2205 | s +=align_to_string( p->alignment() ); | 2228 | s +=align_to_string( p->alignment() ); |
2206 | s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); | 2229 | s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); |
2207 | s += list_value_to_string( p->listValue() ); | 2230 | s += list_value_to_string( p->listValue() ); |
2208 | s += direction_to_string( p->direction() ); | 2231 | s += direction_to_string( p->direction() ); |
2209 | s +=">"; | 2232 | s +=">"; |
2210 | s += ps; | 2233 | s += ps; |
2211 | s += "</li>"; | 2234 | s += "</li>"; |
2212 | } else { | 2235 | } else { |
2213 | // normal paragraph item | 2236 | // normal paragraph item |
2214 | s += "<p"; | 2237 | s += "<p"; |
2215 | s += align_to_string( p->alignment() ); | 2238 | s += align_to_string( p->alignment() ); |
2216 | s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); | 2239 | s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); |
2217 | s +=direction_to_string( p->direction() ); | 2240 | s +=direction_to_string( p->direction() ); |
2218 | s += ">"; | 2241 | s += ">"; |
2219 | s += ps; | 2242 | s += ps; |
2220 | s += "</p>"; | 2243 | s += "</p>"; |
2221 | } | 2244 | } |
2222 | pastListDepth = listDepth; | 2245 | pastListDepth = listDepth; |
2223 | p = p->next(); | 2246 | p = p->next(); |
2224 | } | 2247 | } |
2225 | while ( listDepth > 0 ) { | 2248 | while ( listDepth > 0 ) { |
2226 | s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>"; | 2249 | s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>"; |
2227 | listDepth--; | 2250 | listDepth--; |
2228 | } | 2251 | } |
2229 | 2252 | ||
2230 | if ( !par ) | 2253 | if ( !par ) |
2231 | s += "\n</body></html>\n"; | 2254 | s += "\n</body></html>\n"; |
2232 | 2255 | ||
2233 | return s; | 2256 | return s; |
2234 | } | 2257 | } |
2235 | 2258 | ||
2236 | QString QTextDocument::text() const | 2259 | QString QTextDocument::text() const |
2237 | { | 2260 | { |
2238 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) | 2261 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) |
2239 | return richText(); | 2262 | return richText(); |
2240 | return plainText(); | 2263 | return plainText(); |
2241 | } | 2264 | } |
2242 | 2265 | ||
2243 | QString QTextDocument::text( int parag ) const | 2266 | QString QTextDocument::text( int parag ) const |
2244 | { | 2267 | { |
2245 | QTextParagraph *p = paragAt( parag ); | 2268 | QTextParagraph *p = paragAt( parag ); |
2246 | if ( !p ) | 2269 | if ( !p ) |
2247 | return QString::null; | 2270 | return QString::null; |
2248 | 2271 | ||
2249 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) | 2272 | if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) |
2250 | return p->richText(); | 2273 | return p->richText(); |
2251 | else | 2274 | else |
2252 | return p->string()->toString(); | 2275 | return p->string()->toString(); |
2253 | } | 2276 | } |
2254 | 2277 | ||
2255 | void QTextDocument::invalidate() | 2278 | void QTextDocument::invalidate() |
2256 | { | 2279 | { |
2257 | QTextParagraph *s = fParag; | 2280 | QTextParagraph *s = fParag; |
2258 | while ( s ) { | 2281 | while ( s ) { |
2259 | s->invalidate( 0 ); | 2282 | s->invalidate( 0 ); |
2260 | s = s->next(); | 2283 | s = s->next(); |
2261 | } | 2284 | } |
2262 | } | 2285 | } |
2263 | 2286 | ||
2264 | void QTextDocument::selectionStart( int id, int ¶gId, int &index ) | 2287 | void QTextDocument::selectionStart( int id, int ¶gId, int &index ) |
2265 | { | 2288 | { |
2266 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2289 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2267 | if ( it == selections.end() ) | 2290 | if ( it == selections.end() ) |
2268 | return; | 2291 | return; |
2269 | QTextDocumentSelection &sel = *it; | 2292 | QTextDocumentSelection &sel = *it; |
2270 | paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); | 2293 | paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); |
2271 | index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); | 2294 | index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); |
2272 | } | 2295 | } |
2273 | 2296 | ||
2274 | QTextCursor QTextDocument::selectionStartCursor( int id) | 2297 | QTextCursor QTextDocument::selectionStartCursor( int id) |
2275 | { | 2298 | { |
2276 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2299 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2277 | if ( it == selections.end() ) | 2300 | if ( it == selections.end() ) |
2278 | return QTextCursor( this ); | 2301 | return QTextCursor( this ); |
2279 | QTextDocumentSelection &sel = *it; | 2302 | QTextDocumentSelection &sel = *it; |
2280 | if ( sel.swapped ) | 2303 | if ( sel.swapped ) |
2281 | return sel.endCursor; | 2304 | return sel.endCursor; |
2282 | return sel.startCursor; | 2305 | return sel.startCursor; |
2283 | } | 2306 | } |
2284 | 2307 | ||
2285 | QTextCursor QTextDocument::selectionEndCursor( int id) | 2308 | QTextCursor QTextDocument::selectionEndCursor( int id) |
2286 | { | 2309 | { |
2287 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2310 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2288 | if ( it == selections.end() ) | 2311 | if ( it == selections.end() ) |
2289 | return QTextCursor( this ); | 2312 | return QTextCursor( this ); |
2290 | QTextDocumentSelection &sel = *it; | 2313 | QTextDocumentSelection &sel = *it; |
2291 | if ( !sel.swapped ) | 2314 | if ( !sel.swapped ) |
2292 | return sel.endCursor; | 2315 | return sel.endCursor; |
2293 | return sel.startCursor; | 2316 | return sel.startCursor; |
2294 | } | 2317 | } |
2295 | 2318 | ||
2296 | void QTextDocument::selectionEnd( int id, int ¶gId, int &index ) | 2319 | void QTextDocument::selectionEnd( int id, int ¶gId, int &index ) |
2297 | { | 2320 | { |
2298 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2321 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2299 | if ( it == selections.end() ) | 2322 | if ( it == selections.end() ) |
2300 | return; | 2323 | return; |
2301 | QTextDocumentSelection &sel = *it; | 2324 | QTextDocumentSelection &sel = *it; |
2302 | paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); | 2325 | paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); |
2303 | index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); | 2326 | index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); |
2304 | } | 2327 | } |
2305 | 2328 | ||
2306 | void QTextDocument::addSelection( int id ) | 2329 | void QTextDocument::addSelection( int id ) |
2307 | { | 2330 | { |
2308 | nSelections = QMAX( nSelections, id + 1 ); | 2331 | nSelections = QMAX( nSelections, id + 1 ); |
2309 | } | 2332 | } |
2310 | 2333 | ||
2311 | static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCursor &start, QTextCursor &end ) | 2334 | static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCursor &start, QTextCursor &end ) |
2312 | { | 2335 | { |
2313 | QTextCursor c1 = start; | 2336 | QTextCursor c1 = start; |
2314 | QTextCursor c2 = end; | 2337 | QTextCursor c2 = end; |
2315 | if ( sel.swapped ) { | 2338 | if ( sel.swapped ) { |
2316 | c1 = end; | 2339 | c1 = end; |
2317 | c2 = start; | 2340 | c2 = start; |
2318 | } | 2341 | } |
2319 | 2342 | ||
2320 | c1.paragraph()->removeSelection( id ); | 2343 | c1.paragraph()->removeSelection( id ); |
2321 | c2.paragraph()->removeSelection( id ); | 2344 | c2.paragraph()->removeSelection( id ); |
2322 | if ( c1.paragraph() != c2.paragraph() ) { | 2345 | if ( c1.paragraph() != c2.paragraph() ) { |
2323 | c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 ); | 2346 | c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 ); |
2324 | c2.paragraph()->setSelection( id, 0, c2.index() ); | 2347 | c2.paragraph()->setSelection( id, 0, c2.index() ); |
2325 | } else { | 2348 | } else { |
2326 | c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) ); | 2349 | c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) ); |
2327 | } | 2350 | } |
2328 | 2351 | ||
2329 | sel.startCursor = start; | 2352 | sel.startCursor = start; |
2330 | sel.endCursor = end; | 2353 | sel.endCursor = end; |
2331 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) | 2354 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) |
2332 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); | 2355 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); |
2333 | } | 2356 | } |
2334 | 2357 | ||
2335 | bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor ) | 2358 | bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor ) |
2336 | { | 2359 | { |
2337 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2360 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2338 | if ( it == selections.end() ) | 2361 | if ( it == selections.end() ) |
2339 | return FALSE; | 2362 | return FALSE; |
2340 | QTextDocumentSelection &sel = *it; | 2363 | QTextDocumentSelection &sel = *it; |
2341 | 2364 | ||
2342 | QTextCursor start = sel.startCursor; | 2365 | QTextCursor start = sel.startCursor; |
2343 | QTextCursor end = cursor; | 2366 | QTextCursor end = cursor; |
2344 | 2367 | ||
2345 | if ( start == end ) { | 2368 | if ( start == end ) { |
2346 | removeSelection( id ); | 2369 | removeSelection( id ); |
2347 | setSelectionStart( id, cursor ); | 2370 | setSelectionStart( id, cursor ); |
2348 | return TRUE; | 2371 | return TRUE; |
2349 | } | 2372 | } |
2350 | 2373 | ||
2351 | if ( sel.endCursor.paragraph() == end.paragraph() ) { | 2374 | if ( sel.endCursor.paragraph() == end.paragraph() ) { |
2352 | setSelectionEndHelper( id, sel, start, end ); | 2375 | setSelectionEndHelper( id, sel, start, end ); |
2353 | return TRUE; | 2376 | return TRUE; |
2354 | } | 2377 | } |
2355 | 2378 | ||
2356 | bool inSelection = FALSE; | 2379 | bool inSelection = FALSE; |
2357 | QTextCursor c( this ); | 2380 | QTextCursor c( this ); |
2358 | QTextCursor tmp = sel.startCursor; | 2381 | QTextCursor tmp = sel.startCursor; |
2359 | if ( sel.swapped ) | 2382 | if ( sel.swapped ) |
2360 | tmp = sel.endCursor; | 2383 | tmp = sel.endCursor; |
2361 | tmp.restoreState(); | 2384 | tmp.restoreState(); |
2362 | QTextCursor tmp2 = cursor; | 2385 | QTextCursor tmp2 = cursor; |
2363 | tmp2.restoreState(); | 2386 | tmp2.restoreState(); |
2364 | c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() ); | 2387 | c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() ); |
2365 | bool hadStart = FALSE; | 2388 | bool hadStart = FALSE; |
2366 | bool hadEnd = FALSE; | 2389 | bool hadEnd = FALSE; |
2367 | bool hadStartParag = FALSE; | 2390 | bool hadStartParag = FALSE; |
2368 | bool hadEndParag = FALSE; | 2391 | bool hadEndParag = FALSE; |
2369 | bool hadOldStart = FALSE; | 2392 | bool hadOldStart = FALSE; |
2370 | bool hadOldEnd = FALSE; | 2393 | bool hadOldEnd = FALSE; |
2371 | bool leftSelection = FALSE; | 2394 | bool leftSelection = FALSE; |
2372 | sel.swapped = FALSE; | 2395 | sel.swapped = FALSE; |
2373 | for ( ;; ) { | 2396 | for ( ;; ) { |
2374 | if ( c == start ) | 2397 | if ( c == start ) |
2375 | hadStart = TRUE; | 2398 | hadStart = TRUE; |
2376 | if ( c == end ) | 2399 | if ( c == end ) |
2377 | hadEnd = TRUE; | 2400 | hadEnd = TRUE; |
2378 | if ( c.paragraph() == start.paragraph() ) | 2401 | if ( c.paragraph() == start.paragraph() ) |
2379 | hadStartParag = TRUE; | 2402 | hadStartParag = TRUE; |
2380 | if ( c.paragraph() == end.paragraph() ) | 2403 | if ( c.paragraph() == end.paragraph() ) |
2381 | hadEndParag = TRUE; | 2404 | hadEndParag = TRUE; |
2382 | if ( c == sel.startCursor ) | 2405 | if ( c == sel.startCursor ) |
2383 | hadOldStart = TRUE; | 2406 | hadOldStart = TRUE; |
2384 | if ( c == sel.endCursor ) | 2407 | if ( c == sel.endCursor ) |
2385 | hadOldEnd = TRUE; | 2408 | hadOldEnd = TRUE; |
2386 | 2409 | ||
2387 | if ( !sel.swapped && | 2410 | if ( !sel.swapped && |
2388 | ( hadEnd && !hadStart || | 2411 | ( hadEnd && !hadStart || |
2389 | hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) ) | 2412 | hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) ) |
2390 | sel.swapped = TRUE; | 2413 | sel.swapped = TRUE; |
2391 | 2414 | ||
2392 | if ( c == end && hadStartParag || | 2415 | if ( c == end && hadStartParag || |
2393 | c == start && hadEndParag ) { | 2416 | c == start && hadEndParag ) { |
2394 | QTextCursor tmp = c; | 2417 | QTextCursor tmp = c; |
2395 | tmp.restoreState(); | 2418 | tmp.restoreState(); |
2396 | if ( tmp.paragraph() != c.paragraph() ) { | 2419 | if ( tmp.paragraph() != c.paragraph() ) { |
2397 | int sstart = tmp.paragraph()->selectionStart( id ); | 2420 | int sstart = tmp.paragraph()->selectionStart( id ); |
2398 | tmp.paragraph()->removeSelection( id ); | 2421 | tmp.paragraph()->removeSelection( id ); |
2399 | tmp.paragraph()->setSelection( id, sstart, tmp.index() ); | 2422 | tmp.paragraph()->setSelection( id, sstart, tmp.index() ); |
2400 | } | 2423 | } |
2401 | } | 2424 | } |
2402 | 2425 | ||
2403 | if ( inSelection && | 2426 | if ( inSelection && |
2404 | ( c == end && hadStart || c == start && hadEnd ) ) | 2427 | ( c == end && hadStart || c == start && hadEnd ) ) |
2405 | leftSelection = TRUE; | 2428 | leftSelection = TRUE; |
2406 | else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) ) | 2429 | else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) ) |
2407 | inSelection = TRUE; | 2430 | inSelection = TRUE; |
2408 | 2431 | ||
2409 | bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd(); | 2432 | bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd(); |
2410 | c.paragraph()->removeSelection( id ); | 2433 | c.paragraph()->removeSelection( id ); |
2411 | if ( inSelection ) { | 2434 | if ( inSelection ) { |
2412 | if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) { | 2435 | if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) { |
2413 | c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) ); | 2436 | c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) ); |
2414 | } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) { | 2437 | } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) { |
2415 | c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 ); | 2438 | c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 ); |
2416 | } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) { | 2439 | } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) { |
2417 | c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 ); | 2440 | c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 ); |
2418 | } else if ( c.paragraph() == end.paragraph() && hadEndParag ) { | 2441 | } else if ( c.paragraph() == end.paragraph() && hadEndParag ) { |
2419 | c.paragraph()->setSelection( id, 0, end.index() ); | 2442 | c.paragraph()->setSelection( id, 0, end.index() ); |
2420 | } else if ( c.paragraph() == start.paragraph() && hadStartParag ) { | 2443 | } else if ( c.paragraph() == start.paragraph() && hadStartParag ) { |
2421 | c.paragraph()->setSelection( id, 0, start.index() ); | 2444 | c.paragraph()->setSelection( id, 0, start.index() ); |
2422 | } else { | 2445 | } else { |
2423 | c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 ); | 2446 | c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 ); |
2424 | } | 2447 | } |
2425 | } | 2448 | } |
2426 | 2449 | ||
2427 | if ( leftSelection ) | 2450 | if ( leftSelection ) |
2428 | inSelection = FALSE; | 2451 | inSelection = FALSE; |
2429 | 2452 | ||
2430 | if ( noSelectionAnymore ) | 2453 | if ( noSelectionAnymore ) |
2431 | break; | 2454 | break; |
2432 | // *ugle*hack optimization | 2455 | // *ugle*hack optimization |
2433 | QTextParagraph *p = c.paragraph(); | 2456 | QTextParagraph *p = c.paragraph(); |
2434 | if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) { | 2457 | if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) { |
2435 | c.gotoNextLetter(); | 2458 | c.gotoNextLetter(); |
2436 | if ( p == lastParagraph() && c.atParagEnd() ) | 2459 | if ( p == lastParagraph() && c.atParagEnd() ) |
2437 | break; | 2460 | break; |
2438 | } else { | 2461 | } else { |
2439 | if ( p->document()->parent() ) | 2462 | if ( p->document()->parent() ) |
2440 | do { | 2463 | do { |
2441 | c.gotoNextLetter(); | 2464 | c.gotoNextLetter(); |
2442 | } while ( c.paragraph() == p ); | 2465 | } while ( c.paragraph() == p ); |
2443 | else | 2466 | else |
2444 | c.setParagraph( p->next() ); | 2467 | c.setParagraph( p->next() ); |
2445 | } | 2468 | } |
2446 | } | 2469 | } |
2447 | 2470 | ||
2448 | if ( !sel.swapped ) | 2471 | if ( !sel.swapped ) |
2449 | sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 ); | 2472 | sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 ); |
2450 | 2473 | ||
2451 | sel.startCursor = start; | 2474 | sel.startCursor = start; |
2452 | sel.endCursor = end; | 2475 | sel.endCursor = end; |
2453 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) | 2476 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) |
2454 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); | 2477 | sel.swapped = sel.startCursor.index() > sel.endCursor.index(); |
2455 | 2478 | ||
2456 | setSelectionEndHelper( id, sel, start, end ); | 2479 | setSelectionEndHelper( id, sel, start, end ); |
2457 | 2480 | ||
2458 | return TRUE; | 2481 | return TRUE; |
2459 | } | 2482 | } |
2460 | 2483 | ||
2461 | void QTextDocument::selectAll( int id ) | 2484 | void QTextDocument::selectAll( int id ) |
2462 | { | 2485 | { |
2463 | removeSelection( id ); | 2486 | removeSelection( id ); |
2464 | 2487 | ||
2465 | QTextDocumentSelection sel; | 2488 | QTextDocumentSelection sel; |
2466 | sel.swapped = FALSE; | 2489 | sel.swapped = FALSE; |
2467 | QTextCursor c( this ); | 2490 | QTextCursor c( this ); |
2468 | 2491 | ||
2469 | c.setParagraph( fParag ); | 2492 | c.setParagraph( fParag ); |
2470 | c.setIndex( 0 ); | 2493 | c.setIndex( 0 ); |
2471 | sel.startCursor = c; | 2494 | sel.startCursor = c; |
2472 | 2495 | ||
2473 | c.setParagraph( lParag ); | 2496 | c.setParagraph( lParag ); |
2474 | c.setIndex( lParag->length() - 1 ); | 2497 | c.setIndex( lParag->length() - 1 ); |
2475 | sel.endCursor = c; | 2498 | sel.endCursor = c; |
2476 | 2499 | ||
2477 | selections.insert( id, sel ); | 2500 | selections.insert( id, sel ); |
2478 | 2501 | ||
2479 | QTextParagraph *p = fParag; | 2502 | QTextParagraph *p = fParag; |
2480 | while ( p ) { | 2503 | while ( p ) { |
2481 | p->setSelection( id, 0, p->length() - 1 ); | 2504 | p->setSelection( id, 0, p->length() - 1 ); |
2482 | p = p->next(); | 2505 | p = p->next(); |
2483 | } | 2506 | } |
2484 | 2507 | ||
2485 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) | 2508 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) |
2486 | d->selectAll( id ); | 2509 | d->selectAll( id ); |
2487 | } | 2510 | } |
2488 | 2511 | ||
2489 | bool QTextDocument::removeSelection( int id ) | 2512 | bool QTextDocument::removeSelection( int id ) |
2490 | { | 2513 | { |
2491 | if ( !selections.contains( id ) ) | 2514 | if ( !selections.contains( id ) ) |
2492 | return FALSE; | 2515 | return FALSE; |
2493 | 2516 | ||
2494 | QTextDocumentSelection &sel = selections[ id ]; | 2517 | QTextDocumentSelection &sel = selections[ id ]; |
2495 | 2518 | ||
2496 | QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor; | 2519 | QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor; |
2497 | QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor; | 2520 | QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor; |
2498 | QTextParagraph* p = 0; | 2521 | QTextParagraph* p = 0; |
2499 | while ( start != end ) { | 2522 | while ( start != end ) { |
2500 | if ( p != start.paragraph() ) { | 2523 | if ( p != start.paragraph() ) { |
2501 | p = start.paragraph(); | 2524 | p = start.paragraph(); |
2502 | p->removeSelection( id ); | 2525 | p->removeSelection( id ); |
2503 | } | 2526 | } |
2504 | start.gotoNextLetter(); | 2527 | start.gotoNextLetter(); |
2505 | } | 2528 | } |
2506 | selections.remove( id ); | 2529 | selections.remove( id ); |
2507 | return TRUE; | 2530 | return TRUE; |
2508 | } | 2531 | } |
2509 | 2532 | ||
2510 | QString QTextDocument::selectedText( int id, bool asRichText ) const | 2533 | QString QTextDocument::selectedText( int id, bool asRichText ) const |
2511 | { | 2534 | { |
2512 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); | 2535 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); |
2513 | if ( it == selections.end() ) | 2536 | if ( it == selections.end() ) |
2514 | return QString::null; | 2537 | return QString::null; |
2515 | 2538 | ||
2516 | QTextDocumentSelection sel = *it; | 2539 | QTextDocumentSelection sel = *it; |
2517 | 2540 | ||
2518 | 2541 | ||
2519 | QTextCursor c1 = sel.startCursor; | 2542 | QTextCursor c1 = sel.startCursor; |
2520 | QTextCursor c2 = sel.endCursor; | 2543 | QTextCursor c2 = sel.endCursor; |
2521 | if ( sel.swapped ) { | 2544 | if ( sel.swapped ) { |
2522 | c2 = sel.startCursor; | 2545 | c2 = sel.startCursor; |
2523 | c1 = sel.endCursor; | 2546 | c1 = sel.endCursor; |
2524 | } | 2547 | } |
2525 | 2548 | ||
2526 | /* 3.0.3 improvement: Make it possible to get a reasonable | 2549 | /* 3.0.3 improvement: Make it possible to get a reasonable |
2527 | selection inside a table. This approach is very conservative: | 2550 | selection inside a table. This approach is very conservative: |
2528 | make sure that both cursors have the same depth level and point | 2551 | make sure that both cursors have the same depth level and point |
2529 | to paragraphs within the same text document. | 2552 | to paragraphs within the same text document. |
2530 | 2553 | ||
2531 | Meaning if you select text in two table cells, you will get the | 2554 | Meaning if you select text in two table cells, you will get the |
2532 | entire table. This is still far better than the 3.0.2, where | 2555 | entire table. This is still far better than the 3.0.2, where |
2533 | you always got the entire table. | 2556 | you always got the entire table. |
2534 | 2557 | ||
2535 | ### Fix this properly when refactoring | 2558 | ### Fix this properly when refactoring |
2536 | */ | 2559 | */ |
2537 | while ( c2.nestedDepth() > c1.nestedDepth() ) | 2560 | while ( c2.nestedDepth() > c1.nestedDepth() ) |
2538 | c2.oneUp(); | 2561 | c2.oneUp(); |
2539 | while ( c1.nestedDepth() > c2.nestedDepth() ) | 2562 | while ( c1.nestedDepth() > c2.nestedDepth() ) |
2540 | c1.oneUp(); | 2563 | c1.oneUp(); |
2541 | while ( c1.nestedDepth() && c2.nestedDepth() && | 2564 | while ( c1.nestedDepth() && c2.nestedDepth() && |
2542 | c1.paragraph()->document() != c2.paragraph()->document() ) { | 2565 | c1.paragraph()->document() != c2.paragraph()->document() ) { |
2543 | c1.oneUp(); | 2566 | c1.oneUp(); |
2544 | c2.oneUp(); | 2567 | c2.oneUp(); |
2545 | } | 2568 | } |
2546 | // do not trust sel_swapped with tables. Fix this properly when refactoring as well | 2569 | // do not trust sel_swapped with tables. Fix this properly when refactoring as well |
2547 | if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() || | 2570 | if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() || |
2548 | (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) { | 2571 | (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) { |
2549 | QTextCursor tmp = c1; | 2572 | QTextCursor tmp = c1; |
2550 | c2 = c1; | 2573 | c2 = c1; |
2551 | c1 = tmp; | 2574 | c1 = tmp; |
2552 | } | 2575 | } |
2553 | 2576 | ||
2554 | // end selection 3.0.3 improvement | 2577 | // end selection 3.0.3 improvement |
2555 | 2578 | ||
2556 | if ( asRichText && !parent() ) { | 2579 | if ( asRichText && !parent() ) { |
2557 | richTextExportStart = &c1; | 2580 | richTextExportStart = &c1; |
2558 | richTextExportEnd = &c2; | 2581 | richTextExportEnd = &c2; |
2559 | 2582 | ||
2560 | QString sel = richText(); | 2583 | QString sel = richText(); |
2561 | int from = sel.find( "<selstart/>" ); | 2584 | int from = sel.find( "<selstart/>" ); |
2562 | int to = sel.findRev( "<selend/>" ); | 2585 | int to = sel.findRev( "<selend/>" ); |
2563 | if ( from >= 0 && from <= to ) | 2586 | if ( from >= 0 && from <= to ) |
2564 | sel = sel.mid( from, to - from ); | 2587 | sel = sel.mid( from, to - from ); |
2565 | richTextExportStart = richTextExportEnd = 0; | 2588 | richTextExportStart = richTextExportEnd = 0; |
2566 | return sel; | 2589 | return sel; |
2567 | } | 2590 | } |
2568 | 2591 | ||
2569 | QString s; | 2592 | QString s; |
2570 | if ( c1.paragraph() == c2.paragraph() ) { | 2593 | if ( c1.paragraph() == c2.paragraph() ) { |
2571 | QTextParagraph *p = c1.paragraph(); | 2594 | QTextParagraph *p = c1.paragraph(); |
2572 | int end = c2.index(); | 2595 | int end = c2.index(); |
2573 | if ( p->at( QMAX( 0, end - 1 ) )->isCustom() ) | 2596 | if ( p->at( QMAX( 0, end - 1 ) )->isCustom() ) |
2574 | ++end; | 2597 | ++end; |
2575 | if ( !p->mightHaveCustomItems ) { | 2598 | if ( !p->mightHaveCustomItems ) { |
2576 | s += p->string()->toString().mid( c1.index(), end - c1.index() ); | 2599 | s += p->string()->toString().mid( c1.index(), end - c1.index() ); |
2577 | } else { | 2600 | } else { |
2578 | for ( int i = c1.index(); i < end; ++i ) { | 2601 | for ( int i = c1.index(); i < end; ++i ) { |
2579 | if ( p->at( i )->isCustom() ) { | 2602 | if ( p->at( i )->isCustom() ) { |
2580 | if ( p->at( i )->customItem()->isNested() ) { | 2603 | if ( p->at( i )->customItem()->isNested() ) { |
2581 | s += "\n"; | 2604 | s += "\n"; |
2582 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 2605 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
2583 | QPtrList<QTextTableCell> cells = t->tableCells(); | 2606 | QPtrList<QTextTableCell> cells = t->tableCells(); |
2584 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) | 2607 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) |
2585 | s += c->richText()->plainText() + "\n"; | 2608 | s += c->richText()->plainText() + "\n"; |
2586 | s += "\n"; | 2609 | s += "\n"; |
2587 | } | 2610 | } |
2588 | } else { | 2611 | } else { |
2589 | s += p->at( i )->c; | 2612 | s += p->at( i )->c; |
2590 | } | 2613 | } |
2591 | } | 2614 | } |
2592 | } | 2615 | } |
2593 | } else { | 2616 | } else { |
2594 | QTextParagraph *p = c1.paragraph(); | 2617 | QTextParagraph *p = c1.paragraph(); |
2595 | int start = c1.index(); | 2618 | int start = c1.index(); |
2596 | while ( p ) { | 2619 | while ( p ) { |
2597 | int end = p == c2.paragraph() ? c2.index() : p->length() - 1; | 2620 | int end = p == c2.paragraph() ? c2.index() : p->length() - 1; |
2598 | if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() ) | 2621 | if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() ) |
2599 | ++end; | 2622 | ++end; |
2600 | if ( !p->mightHaveCustomItems ) { | 2623 | if ( !p->mightHaveCustomItems ) { |
2601 | s += p->string()->toString().mid( start, end - start ); | 2624 | s += p->string()->toString().mid( start, end - start ); |
2602 | if ( p != c2.paragraph() ) | 2625 | if ( p != c2.paragraph() ) |
2603 | s += "\n"; | 2626 | s += "\n"; |
2604 | } else { | 2627 | } else { |
2605 | for ( int i = start; i < end; ++i ) { | 2628 | for ( int i = start; i < end; ++i ) { |
2606 | if ( p->at( i )->isCustom() ) { | 2629 | if ( p->at( i )->isCustom() ) { |
2607 | if ( p->at( i )->customItem()->isNested() ) { | 2630 | if ( p->at( i )->customItem()->isNested() ) { |
2608 | s += "\n"; | 2631 | s += "\n"; |
2609 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 2632 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
2610 | QPtrList<QTextTableCell> cells = t->tableCells(); | 2633 | QPtrList<QTextTableCell> cells = t->tableCells(); |
2611 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) | 2634 | for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) |
2612 | s += c->richText()->plainText() + "\n"; | 2635 | s += c->richText()->plainText() + "\n"; |
2613 | s += "\n"; | 2636 | s += "\n"; |
2614 | } | 2637 | } |
2615 | } else { | 2638 | } else { |
2616 | s += p->at( i )->c; | 2639 | s += p->at( i )->c; |
2617 | } | 2640 | } |
2618 | } | 2641 | } |
2619 | } | 2642 | } |
2620 | start = 0; | 2643 | start = 0; |
2621 | if ( p == c2.paragraph() ) | 2644 | if ( p == c2.paragraph() ) |
2622 | break; | 2645 | break; |
2623 | p = p->next(); | 2646 | p = p->next(); |
2624 | } | 2647 | } |
2625 | } | 2648 | } |
2626 | // ### workaround for plain text export until we get proper | 2649 | // ### workaround for plain text export until we get proper |
2627 | // mime types: turn unicode line seperators into the more | 2650 | // mime types: turn unicode line seperators into the more |
2628 | // widely understood \n. Makes copy and pasting code snipplets | 2651 | // widely understood \n. Makes copy and pasting code snipplets |
2629 | // from within Assistent possible | 2652 | // from within Assistent possible |
2630 | QChar* uc = (QChar*) s.unicode(); | 2653 | QChar* uc = (QChar*) s.unicode(); |
2631 | for ( uint ii = 0; ii < s.length(); ii++ ) | 2654 | for ( uint ii = 0; ii < s.length(); ii++ ) |
2632 | if ( uc[(int)ii] == QChar_linesep ) | 2655 | if ( uc[(int)ii] == QChar_linesep ) |
2633 | uc[(int)ii] = QChar('\n'); | 2656 | uc[(int)ii] = QChar('\n'); |
2634 | return s; | 2657 | return s; |
2635 | } | 2658 | } |
2636 | 2659 | ||
2637 | void QTextDocument::setFormat( int id, QTextFormat *f, int flags ) | 2660 | void QTextDocument::setFormat( int id, QTextFormat *f, int flags ) |
2638 | { | 2661 | { |
2639 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); | 2662 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); |
2640 | if ( it == selections.end() ) | 2663 | if ( it == selections.end() ) |
2641 | return; | 2664 | return; |
2642 | 2665 | ||
2643 | QTextDocumentSelection sel = *it; | 2666 | QTextDocumentSelection sel = *it; |
2644 | 2667 | ||
2645 | QTextCursor c1 = sel.startCursor; | 2668 | QTextCursor c1 = sel.startCursor; |
2646 | QTextCursor c2 = sel.endCursor; | 2669 | QTextCursor c2 = sel.endCursor; |
2647 | if ( sel.swapped ) { | 2670 | if ( sel.swapped ) { |
2648 | c2 = sel.startCursor; | 2671 | c2 = sel.startCursor; |
2649 | c1 = sel.endCursor; | 2672 | c1 = sel.endCursor; |
2650 | } | 2673 | } |
2651 | 2674 | ||
2652 | c2.restoreState(); | 2675 | c2.restoreState(); |
2653 | c1.restoreState(); | 2676 | c1.restoreState(); |
2654 | 2677 | ||
2655 | if ( c1.paragraph() == c2.paragraph() ) { | 2678 | if ( c1.paragraph() == c2.paragraph() ) { |
2656 | c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags ); | 2679 | c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags ); |
2657 | return; | 2680 | return; |
2658 | } | 2681 | } |
2659 | 2682 | ||
2660 | c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags ); | 2683 | c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags ); |
2661 | QTextParagraph *p = c1.paragraph()->next(); | 2684 | QTextParagraph *p = c1.paragraph()->next(); |
2662 | while ( p && p != c2.paragraph() ) { | 2685 | while ( p && p != c2.paragraph() ) { |
2663 | p->setFormat( 0, p->length(), f, TRUE, flags ); | 2686 | p->setFormat( 0, p->length(), f, TRUE, flags ); |
2664 | p = p->next(); | 2687 | p = p->next(); |
2665 | } | 2688 | } |
2666 | c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags ); | 2689 | c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags ); |
2667 | } | 2690 | } |
2668 | 2691 | ||
2669 | void QTextDocument::removeSelectedText( int id, QTextCursor *cursor ) | 2692 | void QTextDocument::removeSelectedText( int id, QTextCursor *cursor ) |
2670 | { | 2693 | { |
2671 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2694 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2672 | if ( it == selections.end() ) | 2695 | if ( it == selections.end() ) |
2673 | return; | 2696 | return; |
2674 | 2697 | ||
2675 | QTextDocumentSelection sel = *it; | 2698 | QTextDocumentSelection sel = *it; |
2676 | 2699 | ||
2677 | QTextCursor c1 = sel.startCursor; | 2700 | QTextCursor c1 = sel.startCursor; |
2678 | QTextCursor c2 = sel.endCursor; | 2701 | QTextCursor c2 = sel.endCursor; |
2679 | if ( sel.swapped ) { | 2702 | if ( sel.swapped ) { |
2680 | c2 = sel.startCursor; | 2703 | c2 = sel.startCursor; |
2681 | c1 = sel.endCursor; | 2704 | c1 = sel.endCursor; |
2682 | } | 2705 | } |
2683 | 2706 | ||
2684 | // ### no support for editing tables yet | 2707 | // ### no support for editing tables yet |
2685 | if ( c1.nestedDepth() || c2.nestedDepth() ) | 2708 | if ( c1.nestedDepth() || c2.nestedDepth() ) |
2686 | return; | 2709 | return; |
2687 | 2710 | ||
2688 | c2.restoreState(); | 2711 | c2.restoreState(); |
2689 | c1.restoreState(); | 2712 | c1.restoreState(); |
2690 | 2713 | ||
2691 | *cursor = c1; | 2714 | *cursor = c1; |
2692 | removeSelection( id ); | 2715 | removeSelection( id ); |
2693 | 2716 | ||
2694 | if ( c1.paragraph() == c2.paragraph() ) { | 2717 | if ( c1.paragraph() == c2.paragraph() ) { |
2695 | c1.paragraph()->remove( c1.index(), c2.index() - c1.index() ); | 2718 | c1.paragraph()->remove( c1.index(), c2.index() - c1.index() ); |
2696 | return; | 2719 | return; |
2697 | } | 2720 | } |
2698 | 2721 | ||
2699 | if ( c1.paragraph() == fParag && c1.index() == 0 && | 2722 | if ( c1.paragraph() == fParag && c1.index() == 0 && |
2700 | c2.paragraph() == lParag && c2.index() == lParag->length() - 1 ) | 2723 | c2.paragraph() == lParag && c2.index() == lParag->length() - 1 ) |
2701 | cursor->setValid( FALSE ); | 2724 | cursor->setValid( FALSE ); |
2702 | 2725 | ||
2703 | bool didGoLeft = FALSE; | 2726 | bool didGoLeft = FALSE; |
2704 | if ( c1.index() == 0 && c1.paragraph() != fParag ) { | 2727 | if ( c1.index() == 0 && c1.paragraph() != fParag ) { |
2705 | cursor->gotoPreviousLetter(); | 2728 | cursor->gotoPreviousLetter(); |
2706 | if ( cursor->isValid() ) | 2729 | if ( cursor->isValid() ) |
2707 | didGoLeft = TRUE; | 2730 | didGoLeft = TRUE; |
2708 | } | 2731 | } |
2709 | 2732 | ||
2710 | c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() ); | 2733 | c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() ); |
2711 | QTextParagraph *p = c1.paragraph()->next(); | 2734 | QTextParagraph *p = c1.paragraph()->next(); |
2712 | int dy = 0; | 2735 | int dy = 0; |
2713 | QTextParagraph *tmp; | 2736 | QTextParagraph *tmp; |
2714 | while ( p && p != c2.paragraph() ) { | 2737 | while ( p && p != c2.paragraph() ) { |
2715 | tmp = p->next(); | 2738 | tmp = p->next(); |
2716 | dy -= p->rect().height(); | 2739 | dy -= p->rect().height(); |
2717 | delete p; | 2740 | delete p; |
2718 | p = tmp; | 2741 | p = tmp; |
2719 | } | 2742 | } |
2720 | c2.paragraph()->remove( 0, c2.index() ); | 2743 | c2.paragraph()->remove( 0, c2.index() ); |
2721 | while ( p ) { | 2744 | while ( p ) { |
2722 | p->move( dy ); | 2745 | p->move( dy ); |
2723 | p->invalidate( 0 ); | 2746 | p->invalidate( 0 ); |
2724 | p->setEndState( -1 ); | 2747 | p->setEndState( -1 ); |
2725 | p = p->next(); | 2748 | p = p->next(); |
2726 | } | 2749 | } |
2727 | 2750 | ||
2728 | c1.paragraph()->join( c2.paragraph() ); | 2751 | c1.paragraph()->join( c2.paragraph() ); |
2729 | 2752 | ||
2730 | if ( didGoLeft ) | 2753 | if ( didGoLeft ) |
2731 | cursor->gotoNextLetter(); | 2754 | cursor->gotoNextLetter(); |
2732 | } | 2755 | } |
2733 | 2756 | ||
2734 | void QTextDocument::indentSelection( int id ) | 2757 | void QTextDocument::indentSelection( int id ) |
2735 | { | 2758 | { |
2736 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); | 2759 | QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); |
2737 | if ( it == selections.end() ) | 2760 | if ( it == selections.end() ) |
2738 | return; | 2761 | return; |
2739 | 2762 | ||
2740 | QTextDocumentSelection sel = *it; | 2763 | QTextDocumentSelection sel = *it; |
2741 | QTextParagraph *startParag = sel.startCursor.paragraph(); | 2764 | QTextParagraph *startParag = sel.startCursor.paragraph(); |
2742 | QTextParagraph *endParag = sel.endCursor.paragraph(); | 2765 | QTextParagraph *endParag = sel.endCursor.paragraph(); |
2743 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { | 2766 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { |
2744 | endParag = sel.startCursor.paragraph(); | 2767 | endParag = sel.startCursor.paragraph(); |
2745 | startParag = sel.endCursor.paragraph(); | 2768 | startParag = sel.endCursor.paragraph(); |
2746 | } | 2769 | } |
2747 | 2770 | ||
2748 | QTextParagraph *p = startParag; | 2771 | QTextParagraph *p = startParag; |
2749 | while ( p && p != endParag ) { | 2772 | while ( p && p != endParag ) { |
2750 | p->indent(); | 2773 | p->indent(); |
2751 | p = p->next(); | 2774 | p = p->next(); |
2752 | } | 2775 | } |
2753 | } | 2776 | } |
2754 | 2777 | ||
2755 | void QTextDocument::addCommand( QTextCommand *cmd ) | 2778 | void QTextDocument::addCommand( QTextCommand *cmd ) |
2756 | { | 2779 | { |
2757 | commandHistory->addCommand( cmd ); | 2780 | commandHistory->addCommand( cmd ); |
2758 | } | 2781 | } |
2759 | 2782 | ||
2760 | QTextCursor *QTextDocument::undo( QTextCursor *c ) | 2783 | QTextCursor *QTextDocument::undo( QTextCursor *c ) |
2761 | { | 2784 | { |
2762 | return commandHistory->undo( c ); | 2785 | return commandHistory->undo( c ); |
2763 | } | 2786 | } |
2764 | 2787 | ||
2765 | QTextCursor *QTextDocument::redo( QTextCursor *c ) | 2788 | QTextCursor *QTextDocument::redo( QTextCursor *c ) |
2766 | { | 2789 | { |
2767 | return commandHistory->redo( c ); | 2790 | return commandHistory->redo( c ); |
2768 | } | 2791 | } |
2769 | 2792 | ||
2770 | bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward ) | 2793 | bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward ) |
2771 | { | 2794 | { |
2772 | removeSelection( Standard ); | 2795 | removeSelection( Standard ); |
2773 | QTextParagraph *p = 0; | 2796 | QTextParagraph *p = 0; |
2774 | QString expr = e; | 2797 | QString expr = e; |
2775 | // if we search for 'word only' than we have to be sure that | 2798 | // if we search for 'word only' than we have to be sure that |
2776 | // the expression contains no space or punct character at the | 2799 | // the expression contains no space or punct character at the |
2777 | // beginning or in the end. Otherwise we would run into a | 2800 | // beginning or in the end. Otherwise we would run into a |
2778 | // endlessloop. | 2801 | // endlessloop. |
2779 | if ( wo ) { | 2802 | if ( wo ) { |
2780 | for ( ;; ) { | 2803 | for ( ;; ) { |
2781 | if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() ) | 2804 | if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() ) |
2782 | expr = expr.right( expr.length() - 1 ); | 2805 | expr = expr.right( expr.length() - 1 ); |
2783 | else | 2806 | else |
2784 | break; | 2807 | break; |
2785 | } | 2808 | } |
2786 | for ( ;; ) { | 2809 | for ( ;; ) { |
2787 | if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() ) | 2810 | if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() ) |
2788 | expr = expr.left( expr.length() - 1 ); | 2811 | expr = expr.left( expr.length() - 1 ); |
2789 | else | 2812 | else |
2790 | break; | 2813 | break; |
2791 | } | 2814 | } |
2792 | } | 2815 | } |
2793 | for (;;) { | 2816 | for (;;) { |
2794 | if ( p != cursor.paragraph() ) { | 2817 | if ( p != cursor.paragraph() ) { |
2795 | p = cursor.paragraph(); | 2818 | p = cursor.paragraph(); |
2796 | QString s = cursor.paragraph()->string()->toString(); | 2819 | QString s = cursor.paragraph()->string()->toString(); |
2797 | int start = cursor.index(); | 2820 | int start = cursor.index(); |
2798 | for ( ;; ) { | 2821 | for ( ;; ) { |
2799 | int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs ); | 2822 | int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs ); |
2800 | int end = res + expr.length(); | 2823 | int end = res + expr.length(); |
2801 | if ( res == -1 || ( !forward && start < end ) ) | 2824 | if ( res == -1 || ( !forward && start < end ) ) |
2802 | break; | 2825 | break; |
2803 | if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) && | 2826 | if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) && |
2804 | ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) { | 2827 | ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) { |
2805 | removeSelection( Standard ); | 2828 | removeSelection( Standard ); |
2806 | cursor.setIndex( forward ? end : res ); | 2829 | cursor.setIndex( forward ? end : res ); |
2807 | setSelectionStart( Standard, cursor ); | 2830 | setSelectionStart( Standard, cursor ); |
2808 | cursor.setIndex( forward ? res : end ); | 2831 | cursor.setIndex( forward ? res : end ); |
2809 | setSelectionEnd( Standard, cursor ); | 2832 | setSelectionEnd( Standard, cursor ); |
2810 | return TRUE; | 2833 | return TRUE; |
2811 | } | 2834 | } |
2812 | start = res + (forward ? 1 : -1); | 2835 | start = res + (forward ? 1 : -1); |
2813 | } | 2836 | } |
2814 | } | 2837 | } |
2815 | if ( forward ) { | 2838 | if ( forward ) { |
2816 | if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () ) | 2839 | if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () ) |
2817 | break; | 2840 | break; |
2818 | cursor.gotoNextLetter(); | 2841 | cursor.gotoNextLetter(); |
2819 | } else { | 2842 | } else { |
2820 | if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() ) | 2843 | if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() ) |
2821 | break; | 2844 | break; |
2822 | cursor.gotoPreviousLetter(); | 2845 | cursor.gotoPreviousLetter(); |
2823 | } | 2846 | } |
2824 | } | 2847 | } |
2825 | return FALSE; | 2848 | return FALSE; |
2826 | } | 2849 | } |
2827 | 2850 | ||
2828 | void QTextDocument::setTextFormat( Qt::TextFormat f ) | 2851 | void QTextDocument::setTextFormat( Qt::TextFormat f ) |
2829 | { | 2852 | { |
2830 | txtFormat = f; | 2853 | txtFormat = f; |
2831 | if ( fParag == lParag && fParag->length() <= 1 ) | 2854 | if ( fParag == lParag && fParag->length() <= 1 ) |
2832 | fParag->rtext = ( f == Qt::RichText ); | 2855 | fParag->rtext = ( f == Qt::RichText ); |
2833 | } | 2856 | } |
2834 | 2857 | ||
2835 | Qt::TextFormat QTextDocument::textFormat() const | 2858 | Qt::TextFormat QTextDocument::textFormat() const |
2836 | { | 2859 | { |
2837 | return txtFormat; | 2860 | return txtFormat; |
2838 | } | 2861 | } |
2839 | 2862 | ||
2840 | bool QTextDocument::inSelection( int selId, const QPoint &pos ) const | 2863 | bool QTextDocument::inSelection( int selId, const QPoint &pos ) const |
2841 | { | 2864 | { |
2842 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( selId ); | 2865 | QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( selId ); |
2843 | if ( it == selections.end() ) | 2866 | if ( it == selections.end() ) |
2844 | return FALSE; | 2867 | return FALSE; |
2845 | 2868 | ||
2846 | QTextDocumentSelection sel = *it; | 2869 | QTextDocumentSelection sel = *it; |
2847 | QTextParagraph *startParag = sel.startCursor.paragraph(); | 2870 | QTextParagraph *startParag = sel.startCursor.paragraph(); |
2848 | QTextParagraph *endParag = sel.endCursor.paragraph(); | 2871 | QTextParagraph *endParag = sel.endCursor.paragraph(); |
2849 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() && | 2872 | if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() && |
2850 | sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) ) | 2873 | sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) ) |
2851 | return FALSE; | 2874 | return FALSE; |
2852 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { | 2875 | if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { |
2853 | endParag = sel.startCursor.paragraph(); | 2876 | endParag = sel.startCursor.paragraph(); |
2854 | startParag = sel.endCursor.paragraph(); | 2877 | startParag = sel.endCursor.paragraph(); |
2855 | } | 2878 | } |
2856 | 2879 | ||
2857 | QTextParagraph *p = startParag; | 2880 | QTextParagraph *p = startParag; |
2858 | while ( p ) { | 2881 | while ( p ) { |
2859 | if ( p->rect().contains( pos ) ) { | 2882 | if ( p->rect().contains( pos ) ) { |
2860 | bool inSel = FALSE; | 2883 | bool inSel = FALSE; |
2861 | int selStart = p->selectionStart( selId ); | 2884 | int selStart = p->selectionStart( selId ); |
2862 | int selEnd = p->selectionEnd( selId ); | 2885 | int selEnd = p->selectionEnd( selId ); |
2863 | int y = 0; | 2886 | int y = 0; |
2864 | int h = 0; | 2887 | int h = 0; |
2865 | for ( int i = 0; i < p->length(); ++i ) { | 2888 | for ( int i = 0; i < p->length(); ++i ) { |
2866 | if ( i == selStart ) | 2889 | if ( i == selStart ) |
2867 | inSel = TRUE; | 2890 | inSel = TRUE; |
2868 | if ( i == selEnd ) | 2891 | if ( i == selEnd ) |
2869 | break; | 2892 | break; |
2870 | if ( p->at( i )->lineStart ) { | 2893 | if ( p->at( i )->lineStart ) { |
2871 | y = (*p->lineStarts.find( i ))->y; | 2894 | y = (*p->lineStarts.find( i ))->y; |
2872 | h = (*p->lineStarts.find( i ))->h; | 2895 | h = (*p->lineStarts.find( i ))->h; |
2873 | } | 2896 | } |
2874 | if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) { | 2897 | if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) { |
2875 | if ( inSel && pos.x() >= p->at( i )->x && | 2898 | if ( inSel && pos.x() >= p->at( i )->x && |
2876 | pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) ) | 2899 | pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) ) |
2877 | return TRUE; | 2900 | return TRUE; |
2878 | } | 2901 | } |
2879 | } | 2902 | } |
2880 | } | 2903 | } |
2881 | if ( pos.y() < p->rect().y() ) | 2904 | if ( pos.y() < p->rect().y() ) |
2882 | break; | 2905 | break; |
2883 | if ( p == endParag ) | 2906 | if ( p == endParag ) |
2884 | break; | 2907 | break; |
2885 | p = p->next(); | 2908 | p = p->next(); |
2886 | } | 2909 | } |
2887 | 2910 | ||
2888 | return FALSE; | 2911 | return FALSE; |
2889 | } | 2912 | } |
2890 | 2913 | ||
2891 | void QTextDocument::doLayout( QPainter *p, int w ) | 2914 | void QTextDocument::doLayout( QPainter *p, int w ) |
2892 | { | 2915 | { |
2893 | minw = wused = 0; | 2916 | minw = wused = 0; |
2894 | if ( !is_printer( p ) ) | 2917 | if ( !is_printer( p ) ) |
2895 | p = 0; | 2918 | p = 0; |
2896 | withoutDoubleBuffer = ( p != 0 ); | 2919 | withoutDoubleBuffer = ( p != 0 ); |
2897 | QPainter * oldPainter = QTextFormat::painter(); | 2920 | QPainter * oldPainter = QTextFormat::painter(); |
2898 | QTextFormat::setPainter( p ); | 2921 | QTextFormat::setPainter( p ); |
2899 | flow_->setWidth( w ); | 2922 | flow_->setWidth( w ); |
2900 | cw = w; | 2923 | cw = w; |
2901 | vw = w; | 2924 | vw = w; |
2902 | QTextParagraph *parag = fParag; | 2925 | QTextParagraph *parag = fParag; |
2903 | while ( parag ) { | 2926 | while ( parag ) { |
2904 | parag->invalidate( 0 ); | 2927 | parag->invalidate( 0 ); |
2905 | if ( p ) | 2928 | if ( p ) |
2906 | parag->adjustToPainter( p ); | 2929 | parag->adjustToPainter( p ); |
2907 | parag->format(); | 2930 | parag->format(); |
2908 | parag = parag->next(); | 2931 | parag = parag->next(); |
2909 | } | 2932 | } |
2910 | QTextFormat::setPainter( oldPainter ); | 2933 | QTextFormat::setPainter( oldPainter ); |
2911 | } | 2934 | } |
2912 | 2935 | ||
2913 | QPixmap *QTextDocument::bufferPixmap( const QSize &s ) | 2936 | QPixmap *QTextDocument::bufferPixmap( const QSize &s ) |
2914 | { | 2937 | { |
2915 | if ( !buf_pixmap ) | 2938 | if ( !buf_pixmap ) |
2916 | buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) ); | 2939 | buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) ); |
2917 | else if ( buf_pixmap->size() != s ) | 2940 | else if ( buf_pixmap->size() != s ) |
2918 | buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) ); | 2941 | buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) ); |
2919 | return buf_pixmap; | 2942 | return buf_pixmap; |
2920 | } | 2943 | } |
2921 | 2944 | ||
2922 | void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) | 2945 | void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) |
2923 | { | 2946 | { |
2924 | if ( !firstParagraph() ) | 2947 | if ( !firstParagraph() ) |
2925 | return; | 2948 | return; |
2926 | 2949 | ||
2927 | if ( paper ) { | 2950 | if ( paper ) { |
2928 | p->setBrushOrigin( 0, 0 ); | 2951 | p->setBrushOrigin( 0, 0 ); |
2929 | 2952 | ||
2930 | p->fillRect( rect, *paper ); | 2953 | p->fillRect( rect, *paper ); |
2931 | } | 2954 | } |
2932 | 2955 | ||
2933 | if ( formatCollection()->defaultFormat()->color() != cg.text() ) | 2956 | if ( formatCollection()->defaultFormat()->color() != cg.text() ) |
2934 | setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() ); | 2957 | setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() ); |
2935 | 2958 | ||
2936 | QTextParagraph *parag = firstParagraph(); | 2959 | QTextParagraph *parag = firstParagraph(); |
2937 | while ( parag ) { | 2960 | while ( parag ) { |
2938 | if ( !parag->isValid() ) | 2961 | if ( !parag->isValid() ) |
2939 | parag->format(); | 2962 | parag->format(); |
2940 | int y = parag->rect().y(); | 2963 | int y = parag->rect().y(); |
2941 | QRect pr( parag->rect() ); | 2964 | QRect pr( parag->rect() ); |
2942 | pr.setX( 0 ); | 2965 | pr.setX( 0 ); |
2943 | pr.setWidth( QWIDGETSIZE_MAX ); | 2966 | pr.setWidth( QWIDGETSIZE_MAX ); |
2944 | if ( !rect.isNull() && !rect.intersects( pr ) ) { | 2967 | if ( !rect.isNull() && !rect.intersects( pr ) ) { |
2945 | parag = parag->next(); | 2968 | parag = parag->next(); |
2946 | continue; | 2969 | continue; |
2947 | } | 2970 | } |
2948 | p->translate( 0, y ); | 2971 | p->translate( 0, y ); |
2949 | if ( rect.isValid() ) | 2972 | if ( rect.isValid() ) |
2950 | parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() ); | 2973 | parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() ); |
2951 | else | 2974 | else |
2952 | parag->paint( *p, cg, 0, FALSE ); | 2975 | parag->paint( *p, cg, 0, FALSE ); |
2953 | p->translate( 0, -y ); | 2976 | p->translate( 0, -y ); |
2954 | parag = parag->next(); | 2977 | parag = parag->next(); |
2955 | if ( !flow()->isEmpty() ) | 2978 | if ( !flow()->isEmpty() ) |
2956 | flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE ); | 2979 | flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE ); |
2957 | } | 2980 | } |
2958 | } | 2981 | } |
2959 | 2982 | ||
2960 | void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, | 2983 | void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, |
2961 | QPixmap *&doubleBuffer, const QColorGroup &cg, | 2984 | QPixmap *&doubleBuffer, const QColorGroup &cg, |
2962 | bool drawCursor, QTextCursor *cursor, bool resetChanged ) | 2985 | bool drawCursor, QTextCursor *cursor, bool resetChanged ) |
2963 | { | 2986 | { |
2964 | QPainter *painter = 0; | 2987 | QPainter *painter = 0; |
2965 | if ( resetChanged ) | 2988 | if ( resetChanged ) |
2966 | parag->setChanged( FALSE ); | 2989 | parag->setChanged( FALSE ); |
2967 | QRect ir( parag->rect() ); | 2990 | QRect ir( parag->rect() ); |
2968 | bool useDoubleBuffer = !parag->document()->parent(); | 2991 | bool useDoubleBuffer = !parag->document()->parent(); |
2969 | if ( !useDoubleBuffer && parag->document()->nextDoubleBuffered ) | 2992 | if ( !useDoubleBuffer && parag->document()->nextDoubleBuffered ) |
2970 | useDoubleBuffer = TRUE; | 2993 | useDoubleBuffer = TRUE; |
2971 | if ( is_printer( p ) ) | 2994 | if ( is_printer( p ) ) |
2972 | useDoubleBuffer = FALSE; | 2995 | useDoubleBuffer = FALSE; |
2973 | 2996 | ||
2974 | if ( useDoubleBuffer ) { | 2997 | if ( useDoubleBuffer ) { |
2975 | painter = new QPainter; | 2998 | painter = new QPainter; |
2976 | if ( cx >= 0 && cy >= 0 ) | 2999 | if ( cx >= 0 && cy >= 0 ) |
2977 | ir = ir.intersect( QRect( cx, cy, cw, ch ) ); | 3000 | ir = ir.intersect( QRect( cx, cy, cw, ch ) ); |
2978 | if ( !doubleBuffer || | 3001 | if ( !doubleBuffer || |
2979 | ir.width() > doubleBuffer->width() || | 3002 | ir.width() > doubleBuffer->width() || |
2980 | ir.height() > doubleBuffer->height() ) { | 3003 | ir.height() > doubleBuffer->height() ) { |
2981 | doubleBuffer = bufferPixmap( ir.size() ); | 3004 | doubleBuffer = bufferPixmap( ir.size() ); |
2982 | painter->begin( doubleBuffer ); | 3005 | painter->begin( doubleBuffer ); |
2983 | } else { | 3006 | } else { |
2984 | painter->begin( doubleBuffer ); | 3007 | painter->begin( doubleBuffer ); |
2985 | } | 3008 | } |
2986 | } else { | 3009 | } else { |
2987 | painter = p; | 3010 | painter = p; |
2988 | painter->translate( ir.x(), ir.y() ); | 3011 | painter->translate( ir.x(), ir.y() ); |
2989 | } | 3012 | } |
2990 | 3013 | ||
2991 | painter->setBrushOrigin( -ir.x(), -ir.y() ); | 3014 | painter->setBrushOrigin( -ir.x(), -ir.y() ); |
2992 | 3015 | ||
2993 | if ( useDoubleBuffer || is_printer( painter ) ) | 3016 | if ( useDoubleBuffer || is_printer( painter ) ) |
2994 | painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) ); | 3017 | painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) ); |
2995 | else if ( cursor && cursor->paragraph() == parag ) | 3018 | else if ( cursor && cursor->paragraph() == parag ) |
2996 | painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ), | 3019 | painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ), |
2997 | parag->backgroundBrush( cg ) ); | 3020 | parag->backgroundBrush( cg ) ); |
2998 | 3021 | ||
2999 | painter->translate( -( ir.x() - parag->rect().x() ), | 3022 | painter->translate( -( ir.x() - parag->rect().x() ), |
3000 | -( ir.y() - parag->rect().y() ) ); | 3023 | -( ir.y() - parag->rect().y() ) ); |
3001 | parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch ); | 3024 | parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch ); |
3002 | 3025 | ||
3003 | if ( useDoubleBuffer ) { | 3026 | if ( useDoubleBuffer ) { |
3004 | delete painter; | 3027 | delete painter; |
3005 | painter = 0; | 3028 | painter = 0; |
3006 | p->drawPixmap( ir.topLeft(), *doubleBuffer, QRect( QPoint( 0, 0 ), ir.size() ) ); | 3029 | p->drawPixmap( ir.topLeft(), *doubleBuffer, QRect( QPoint( 0, 0 ), ir.size() ) ); |
3007 | } else { | 3030 | } else { |
3008 | painter->translate( -ir.x(), -ir.y() ); | 3031 | painter->translate( -ir.x(), -ir.y() ); |
3009 | } | 3032 | } |
3010 | 3033 | ||
3011 | if ( useDoubleBuffer ) { | 3034 | if ( useDoubleBuffer ) { |
3012 | if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) { | 3035 | if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) { |
3013 | p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(), | 3036 | p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(), |
3014 | ( parag->document()->x() + parag->document()->width() ) - | 3037 | ( parag->document()->x() + parag->document()->width() ) - |
3015 | ( parag->rect().x() + parag->rect().width() ), | 3038 | ( parag->rect().x() + parag->rect().width() ), |
3016 | parag->rect().height(), cg.brush( QColorGroup::Base ) ); | 3039 | parag->rect().height(), cg.brush( QColorGroup::Base ) ); |
3017 | } | 3040 | } |
3018 | } | 3041 | } |
3019 | 3042 | ||
3020 | parag->document()->nextDoubleBuffered = FALSE; | 3043 | parag->document()->nextDoubleBuffered = FALSE; |
3021 | } | 3044 | } |
3022 | 3045 | ||
3023 | QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, | 3046 | QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, |
3024 | bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged ) | 3047 | bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged ) |
3025 | { | 3048 | { |
3026 | if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) { | 3049 | if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) { |
3027 | withoutDoubleBuffer = TRUE; | 3050 | withoutDoubleBuffer = TRUE; |
3028 | QRect r; | 3051 | QRect r; |
3029 | draw( p, r, cg ); | 3052 | draw( p, r, cg ); |
3030 | return 0; | 3053 | return 0; |
3031 | } | 3054 | } |
3032 | withoutDoubleBuffer = FALSE; | 3055 | withoutDoubleBuffer = FALSE; |
3033 | 3056 | ||
3034 | if ( !firstParagraph() ) | 3057 | if ( !firstParagraph() ) |
3035 | return 0; | 3058 | return 0; |
3036 | 3059 | ||
3037 | if ( cx < 0 && cy < 0 ) { | 3060 | if ( cx < 0 && cy < 0 ) { |
3038 | cx = 0; | 3061 | cx = 0; |
3039 | cy = 0; | 3062 | cy = 0; |
3040 | cw = width(); | 3063 | cw = width(); |
3041 | ch = height(); | 3064 | ch = height(); |
3042 | } | 3065 | } |
3043 | 3066 | ||
3044 | QTextParagraph *lastFormatted = 0; | 3067 | QTextParagraph *lastFormatted = 0; |
3045 | QTextParagraph *parag = firstParagraph(); | 3068 | QTextParagraph *parag = firstParagraph(); |
3046 | 3069 | ||
3047 | QPixmap *doubleBuffer = 0; | 3070 | QPixmap *doubleBuffer = 0; |
3048 | QPainter painter; | 3071 | QPainter painter; |
3049 | 3072 | ||
3050 | bool fullWidthSelection = FALSE; | 3073 | bool fullWidthSelection = FALSE; |
3051 | while ( parag ) { | 3074 | while ( parag ) { |
3052 | lastFormatted = parag; | 3075 | lastFormatted = parag; |
3053 | if ( !parag->isValid() ) | 3076 | if ( !parag->isValid() ) |
3054 | parag->format(); | 3077 | parag->format(); |
3055 | 3078 | ||
3056 | QRect pr = parag->rect(); | 3079 | QRect pr = parag->rect(); |
3057 | if ( fullWidthSelection ) | 3080 | if ( fullWidthSelection ) |
3058 | pr.setWidth( parag->document()->width() ); | 3081 | pr.setWidth( parag->document()->width() ); |
3059 | if ( pr.y() > cy + ch ) | 3082 | if ( pr.y() > cy + ch ) |
3060 | goto floating; | 3083 | goto floating; |
3061 | if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) { | 3084 | if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) { |
3062 | parag = parag->next(); | 3085 | parag = parag->next(); |
3063 | continue; | 3086 | continue; |
3064 | } | 3087 | } |
3065 | 3088 | ||
3066 | drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged ); | 3089 | drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged ); |
3067 | parag = parag->next(); | 3090 | parag = parag->next(); |
3068 | } | 3091 | } |
3069 | 3092 | ||
3070 | parag = lastParagraph(); | 3093 | parag = lastParagraph(); |
3071 | 3094 | ||
3072 | floating: | 3095 | floating: |
3073 | if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) { | 3096 | if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) { |
3074 | if ( !parag->document()->parent() ) { | 3097 | if ( !parag->document()->parent() ) { |
3075 | p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(), | 3098 | p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(), |
3076 | parag->document()->height() - ( parag->rect().y() + parag->rect().height() ), | 3099 | parag->document()->height() - ( parag->rect().y() + parag->rect().height() ), |
3077 | cg.brush( QColorGroup::Base ) ); | 3100 | cg.brush( QColorGroup::Base ) ); |
3078 | } | 3101 | } |
3079 | if ( !flow()->isEmpty() ) { | 3102 | if ( !flow()->isEmpty() ) { |
3080 | QRect cr( cx, cy, cw, ch ); | 3103 | QRect cr( cx, cy, cw, ch ); |
3081 | flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE ); | 3104 | flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE ); |
3082 | } | 3105 | } |
3083 | } | 3106 | } |
3084 | 3107 | ||
3085 | if ( buf_pixmap && buf_pixmap->height() > 300 ) { | 3108 | if ( buf_pixmap && buf_pixmap->height() > 300 ) { |
3086 | delete buf_pixmap; | 3109 | delete buf_pixmap; |
3087 | buf_pixmap = 0; | 3110 | buf_pixmap = 0; |
3088 | } | 3111 | } |
3089 | 3112 | ||
3090 | return lastFormatted; | 3113 | return lastFormatted; |
3091 | } | 3114 | } |
3092 | 3115 | ||
3093 | /* | 3116 | /* |
3094 | #### this function only sets the default font size in the format collection | 3117 | #### this function only sets the default font size in the format collection |
3095 | */ | 3118 | */ |
3096 | void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color ) | 3119 | void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color ) |
3097 | { | 3120 | { |
3098 | bool reformat = font != fCollection->defaultFormat()->font(); | 3121 | bool reformat = font != fCollection->defaultFormat()->font(); |
3099 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) | 3122 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) |
3100 | d->setDefaultFormat( font, color ); | 3123 | d->setDefaultFormat( font, color ); |
3101 | fCollection->updateDefaultFormat( font, color, sheet_ ); | 3124 | fCollection->updateDefaultFormat( font, color, sheet_ ); |
3102 | 3125 | ||
3103 | if ( !reformat ) | 3126 | if ( !reformat ) |
3104 | return; | 3127 | return; |
3105 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; | 3128 | tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; |
3106 | 3129 | ||
3107 | // invalidate paragraphs and custom items | 3130 | // invalidate paragraphs and custom items |
3108 | QTextParagraph *p = fParag; | 3131 | QTextParagraph *p = fParag; |
3109 | while ( p ) { | 3132 | while ( p ) { |
3110 | p->invalidate( 0 ); | 3133 | p->invalidate( 0 ); |
3111 | for ( int i = 0; i < p->length() - 1; ++i ) | 3134 | for ( int i = 0; i < p->length() - 1; ++i ) |
3112 | if ( p->at( i )->isCustom() ) | 3135 | if ( p->at( i )->isCustom() ) |
3113 | p->at( i )->customItem()->invalidate(); | 3136 | p->at( i )->customItem()->invalidate(); |
3114 | p = p->next(); | 3137 | p = p->next(); |
3115 | } | 3138 | } |
3116 | } | 3139 | } |
3117 | 3140 | ||
3118 | void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p ) | 3141 | void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p ) |
3119 | { | 3142 | { |
3120 | if ( i && i->placement() != QTextCustomItem::PlaceInline ) { | 3143 | if ( i && i->placement() != QTextCustomItem::PlaceInline ) { |
3121 | flow_->registerFloatingItem( i ); | 3144 | flow_->registerFloatingItem( i ); |
3122 | p->registerFloatingItem( i ); | 3145 | p->registerFloatingItem( i ); |
3123 | i->setParagraph( p ); | 3146 | i->setParagraph( p ); |
3124 | } | 3147 | } |
3125 | p->mightHaveCustomItems = mightHaveCustomItems = TRUE; | 3148 | p->mightHaveCustomItems = mightHaveCustomItems = TRUE; |
3126 | } | 3149 | } |
3127 | 3150 | ||
3128 | void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p ) | 3151 | void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p ) |
3129 | { | 3152 | { |
3130 | flow_->unregisterFloatingItem( i ); | 3153 | flow_->unregisterFloatingItem( i ); |
3131 | p->unregisterFloatingItem( i ); | 3154 | p->unregisterFloatingItem( i ); |
3132 | i->setParagraph( 0 ); | 3155 | i->setParagraph( 0 ); |
3133 | } | 3156 | } |
3134 | 3157 | ||
3135 | bool QTextDocument::hasFocusParagraph() const | 3158 | bool QTextDocument::hasFocusParagraph() const |
3136 | { | 3159 | { |
3137 | return !!focusIndicator.parag; | 3160 | return !!focusIndicator.parag; |
3138 | } | 3161 | } |
3139 | 3162 | ||
3140 | QString QTextDocument::focusHref() const | 3163 | QString QTextDocument::focusHref() const |
3141 | { | 3164 | { |
3142 | return focusIndicator.href; | 3165 | return focusIndicator.href; |
3143 | } | 3166 | } |
3144 | 3167 | ||
3145 | bool QTextDocument::focusNextPrevChild( bool next ) | 3168 | bool QTextDocument::focusNextPrevChild( bool next ) |
3146 | { | 3169 | { |
3147 | if ( !focusIndicator.parag ) { | 3170 | if ( !focusIndicator.parag ) { |
3148 | if ( next ) { | 3171 | if ( next ) { |
3149 | focusIndicator.parag = fParag; | 3172 | focusIndicator.parag = fParag; |
3150 | focusIndicator.start = 0; | 3173 | focusIndicator.start = 0; |
3151 | focusIndicator.len = 0; | 3174 | focusIndicator.len = 0; |
3152 | } else { | 3175 | } else { |
3153 | focusIndicator.parag = lParag; | 3176 | focusIndicator.parag = lParag; |
3154 | focusIndicator.start = lParag->length(); | 3177 | focusIndicator.start = lParag->length(); |
3155 | focusIndicator.len = 0; | 3178 | focusIndicator.len = 0; |
3156 | } | 3179 | } |
3157 | } else { | 3180 | } else { |
3158 | focusIndicator.parag->setChanged( TRUE ); | 3181 | focusIndicator.parag->setChanged( TRUE ); |
3159 | } | 3182 | } |
3160 | focusIndicator.href = QString::null; | 3183 | focusIndicator.href = QString::null; |
3161 | 3184 | ||
3162 | if ( next ) { | 3185 | if ( next ) { |
3163 | QTextParagraph *p = focusIndicator.parag; | 3186 | QTextParagraph *p = focusIndicator.parag; |
3164 | int index = focusIndicator.start + focusIndicator.len; | 3187 | int index = focusIndicator.start + focusIndicator.len; |
3165 | while ( p ) { | 3188 | while ( p ) { |
3166 | for ( int i = index; i < p->length(); ++i ) { | 3189 | for ( int i = index; i < p->length(); ++i ) { |
3167 | if ( p->at( i )->isAnchor() ) { | 3190 | if ( p->at( i )->isAnchor() ) { |
3168 | p->setChanged( TRUE ); | 3191 | p->setChanged( TRUE ); |
3169 | focusIndicator.parag = p; | 3192 | focusIndicator.parag = p; |
3170 | focusIndicator.start = i; | 3193 | focusIndicator.start = i; |
3171 | focusIndicator.len = 0; | 3194 | focusIndicator.len = 0; |
3172 | focusIndicator.href = p->at( i )->anchorHref(); | 3195 | focusIndicator.href = p->at( i )->anchorHref(); |
3173 | while ( i < p->length() ) { | 3196 | while ( i < p->length() ) { |
3174 | if ( !p->at( i )->isAnchor() ) | 3197 | if ( !p->at( i )->isAnchor() ) |
3175 | return TRUE; | 3198 | return TRUE; |
3176 | focusIndicator.len++; | 3199 | focusIndicator.len++; |
3177 | i++; | 3200 | i++; |
3178 | } | 3201 | } |
3179 | } else if ( p->at( i )->isCustom() ) { | 3202 | } else if ( p->at( i )->isCustom() ) { |
3180 | if ( p->at( i )->customItem()->isNested() ) { | 3203 | if ( p->at( i )->customItem()->isNested() ) { |
3181 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 3204 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
3182 | QPtrList<QTextTableCell> cells = t->tableCells(); | 3205 | QPtrList<QTextTableCell> cells = t->tableCells(); |
3183 | // first try to continue | 3206 | // first try to continue |
3184 | QTextTableCell *c; | 3207 | QTextTableCell *c; |
3185 | bool resetCells = TRUE; | 3208 | bool resetCells = TRUE; |
3186 | for ( c = cells.first(); c; c = cells.next() ) { | 3209 | for ( c = cells.first(); c; c = cells.next() ) { |
3187 | if ( c->richText()->hasFocusParagraph() ) { | 3210 | if ( c->richText()->hasFocusParagraph() ) { |
3188 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3211 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3189 | p->setChanged( TRUE ); | 3212 | p->setChanged( TRUE ); |
3190 | focusIndicator.parag = p; | 3213 | focusIndicator.parag = p; |
3191 | focusIndicator.start = i; | 3214 | focusIndicator.start = i; |
3192 | focusIndicator.len = 0; | 3215 | focusIndicator.len = 0; |
3193 | focusIndicator.href = c->richText()->focusHref(); | 3216 | focusIndicator.href = c->richText()->focusHref(); |
3194 | return TRUE; | 3217 | return TRUE; |
3195 | } else { | 3218 | } else { |
3196 | resetCells = FALSE; | 3219 | resetCells = FALSE; |
3197 | c = cells.next(); | 3220 | c = cells.next(); |
3198 | break; | 3221 | break; |
3199 | } | 3222 | } |
3200 | } | 3223 | } |
3201 | } | 3224 | } |
3202 | // now really try | 3225 | // now really try |
3203 | if ( resetCells ) | 3226 | if ( resetCells ) |
3204 | c = cells.first(); | 3227 | c = cells.first(); |
3205 | for ( ; c; c = cells.next() ) { | 3228 | for ( ; c; c = cells.next() ) { |
3206 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3229 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3207 | p->setChanged( TRUE ); | 3230 | p->setChanged( TRUE ); |
3208 | focusIndicator.parag = p; | 3231 | focusIndicator.parag = p; |
3209 | focusIndicator.start = i; | 3232 | focusIndicator.start = i; |
3210 | focusIndicator.len = 0; | 3233 | focusIndicator.len = 0; |
3211 | focusIndicator.href = c->richText()->focusHref(); | 3234 | focusIndicator.href = c->richText()->focusHref(); |
3212 | return TRUE; | 3235 | return TRUE; |
3213 | } | 3236 | } |
3214 | } | 3237 | } |
3215 | } | 3238 | } |
3216 | } | 3239 | } |
3217 | } | 3240 | } |
3218 | index = 0; | 3241 | index = 0; |
3219 | p = p->next(); | 3242 | p = p->next(); |
3220 | } | 3243 | } |
3221 | } else { | 3244 | } else { |
3222 | QTextParagraph *p = focusIndicator.parag; | 3245 | QTextParagraph *p = focusIndicator.parag; |
3223 | int index = focusIndicator.start - 1; | 3246 | int index = focusIndicator.start - 1; |
3224 | if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 ) | 3247 | if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 ) |
3225 | index++; | 3248 | index++; |
3226 | while ( p ) { | 3249 | while ( p ) { |
3227 | for ( int i = index; i >= 0; --i ) { | 3250 | for ( int i = index; i >= 0; --i ) { |
3228 | if ( p->at( i )->isAnchor() ) { | 3251 | if ( p->at( i )->isAnchor() ) { |
3229 | p->setChanged( TRUE ); | 3252 | p->setChanged( TRUE ); |
3230 | focusIndicator.parag = p; | 3253 | focusIndicator.parag = p; |
3231 | focusIndicator.start = i; | 3254 | focusIndicator.start = i; |
3232 | focusIndicator.len = 0; | 3255 | focusIndicator.len = 0; |
3233 | focusIndicator.href = p->at( i )->anchorHref(); | 3256 | focusIndicator.href = p->at( i )->anchorHref(); |
3234 | while ( i >= -1 ) { | 3257 | while ( i >= -1 ) { |
3235 | if ( i < 0 || !p->at( i )->isAnchor() ) { | 3258 | if ( i < 0 || !p->at( i )->isAnchor() ) { |
3236 | focusIndicator.start++; | 3259 | focusIndicator.start++; |
3237 | return TRUE; | 3260 | return TRUE; |
3238 | } | 3261 | } |
3239 | if ( i < 0 ) | 3262 | if ( i < 0 ) |
3240 | break; | 3263 | break; |
3241 | focusIndicator.len++; | 3264 | focusIndicator.len++; |
3242 | focusIndicator.start--; | 3265 | focusIndicator.start--; |
3243 | i--; | 3266 | i--; |
3244 | } | 3267 | } |
3245 | } else if ( p->at( i )->isCustom() ) { | 3268 | } else if ( p->at( i )->isCustom() ) { |
3246 | if ( p->at( i )->customItem()->isNested() ) { | 3269 | if ( p->at( i )->customItem()->isNested() ) { |
3247 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); | 3270 | QTextTable *t = (QTextTable*)p->at( i )->customItem(); |
3248 | QPtrList<QTextTableCell> cells = t->tableCells(); | 3271 | QPtrList<QTextTableCell> cells = t->tableCells(); |
3249 | // first try to continue | 3272 | // first try to continue |
3250 | QTextTableCell *c; | 3273 | QTextTableCell *c; |
3251 | bool resetCells = TRUE; | 3274 | bool resetCells = TRUE; |
3252 | for ( c = cells.last(); c; c = cells.prev() ) { | 3275 | for ( c = cells.last(); c; c = cells.prev() ) { |
3253 | if ( c->richText()->hasFocusParagraph() ) { | 3276 | if ( c->richText()->hasFocusParagraph() ) { |
3254 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3277 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3255 | p->setChanged( TRUE ); | 3278 | p->setChanged( TRUE ); |
3256 | focusIndicator.parag = p; | 3279 | focusIndicator.parag = p; |
3257 | focusIndicator.start = i; | 3280 | focusIndicator.start = i; |
3258 | focusIndicator.len = 0; | 3281 | focusIndicator.len = 0; |
3259 | focusIndicator.href = c->richText()->focusHref(); | 3282 | focusIndicator.href = c->richText()->focusHref(); |
3260 | return TRUE; | 3283 | return TRUE; |
3261 | } else { | 3284 | } else { |
3262 | resetCells = FALSE; | 3285 | resetCells = FALSE; |
3263 | c = cells.prev(); | 3286 | c = cells.prev(); |
3264 | break; | 3287 | break; |
3265 | } | 3288 | } |
3266 | } | 3289 | } |
3267 | if ( cells.at() == 0 ) | 3290 | if ( cells.at() == 0 ) |
3268 | break; | 3291 | break; |
3269 | } | 3292 | } |
3270 | // now really try | 3293 | // now really try |
3271 | if ( resetCells ) | 3294 | if ( resetCells ) |
3272 | c = cells.last(); | 3295 | c = cells.last(); |
3273 | for ( ; c; c = cells.prev() ) { | 3296 | for ( ; c; c = cells.prev() ) { |
3274 | if ( c->richText()->focusNextPrevChild( next ) ) { | 3297 | if ( c->richText()->focusNextPrevChild( next ) ) { |
3275 | p->setChanged( TRUE ); | 3298 | p->setChanged( TRUE ); |
3276 | focusIndicator.parag = p; | 3299 | focusIndicator.parag = p; |
3277 | focusIndicator.start = i; | 3300 | focusIndicator.start = i; |
3278 | focusIndicator.len = 0; | 3301 | focusIndicator.len = 0; |
3279 | focusIndicator.href = c->richText()->focusHref(); | 3302 | focusIndicator.href = c->richText()->focusHref(); |
3280 | return TRUE; | 3303 | return TRUE; |
3281 | } | 3304 | } |
3282 | if ( cells.at() == 0 ) | 3305 | if ( cells.at() == 0 ) |
3283 | break; | 3306 | break; |
3284 | } | 3307 | } |
3285 | } | 3308 | } |
3286 | } | 3309 | } |
3287 | } | 3310 | } |
3288 | p = p->prev(); | 3311 | p = p->prev(); |
3289 | if ( p ) | 3312 | if ( p ) |
3290 | index = p->length() - 1; | 3313 | index = p->length() - 1; |
3291 | } | 3314 | } |
3292 | } | 3315 | } |
3293 | 3316 | ||
3294 | focusIndicator.parag = 0; | 3317 | focusIndicator.parag = 0; |
3295 | 3318 | ||
3296 | return FALSE; | 3319 | return FALSE; |
3297 | } | 3320 | } |
3298 | 3321 | ||
3299 | int QTextDocument::length() const | 3322 | int QTextDocument::length() const |
3300 | { | 3323 | { |
3301 | int l = 0; | 3324 | int l = 0; |
3302 | QTextParagraph *p = fParag; | 3325 | QTextParagraph *p = fParag; |
3303 | while ( p ) { | 3326 | while ( p ) { |
3304 | l += p->length() - 1; // don't count trailing space | 3327 | l += p->length() - 1; // don't count trailing space |
3305 | p = p->next(); | 3328 | p = p->next(); |
3306 | } | 3329 | } |
3307 | return l; | 3330 | return l; |
3308 | } | 3331 | } |
3309 | 3332 | ||
3310 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 3333 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3311 | 3334 | ||
3312 | int QTextFormat::width( const QChar &c ) const | 3335 | int QTextFormat::width( const QChar &c ) const |
3313 | { | 3336 | { |
3314 | if ( c.unicode() == 0xad ) // soft hyphen | 3337 | if ( c.unicode() == 0xad ) // soft hyphen |
3315 | return 0; | 3338 | return 0; |
3316 | if ( !pntr || !pntr->isActive() ) { | 3339 | if ( !pntr || !pntr->isActive() ) { |
3317 | if ( c == '\t' ) | 3340 | if ( c == '\t' ) |
3318 | return fm.width( 'x' ) * 8; | 3341 | return fm.width( 'x' ) * 8; |
3319 | if ( ha == AlignNormal ) { | 3342 | if ( ha == AlignNormal ) { |
3320 | int w; | 3343 | int w; |
3321 | if ( c.row() ) | 3344 | if ( c.row() ) |
3322 | w = fm.width( c ); | 3345 | w = fm.width( c ); |
3323 | else | 3346 | else |
3324 | w = widths[ c.unicode() ]; | 3347 | w = widths[ c.unicode() ]; |
3325 | if ( w == 0 && !c.row() ) { | 3348 | if ( w == 0 && !c.row() ) { |
3326 | w = fm.width( c ); | 3349 | w = fm.width( c ); |
3327 | ( (QTextFormat*)this )->widths[ c.unicode() ] = w; | 3350 | ( (QTextFormat*)this )->widths[ c.unicode() ] = w; |
3328 | } | 3351 | } |
3329 | return w; | 3352 | return w; |
3330 | } else { | 3353 | } else { |
3331 | QFont f( fn ); | 3354 | QFont f( fn ); |
3332 | if ( usePixelSizes ) | 3355 | if ( usePixelSizes ) |
3333 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3356 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3334 | else | 3357 | else |
3335 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3358 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3336 | QFontMetrics fm_( f ); | 3359 | QFontMetrics fm_( f ); |
3337 | return fm_.width( c ); | 3360 | return fm_.width( c ); |
3338 | } | 3361 | } |
3339 | } | 3362 | } |
3340 | 3363 | ||
3341 | QFont f( fn ); | 3364 | QFont f( fn ); |
3342 | if ( ha != AlignNormal ) { | 3365 | if ( ha != AlignNormal ) { |
3343 | if ( usePixelSizes ) | 3366 | if ( usePixelSizes ) |
3344 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3367 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3345 | else | 3368 | else |
3346 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3369 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3347 | } | 3370 | } |
3348 | pntr->setFont( f ); | 3371 | pntr->setFont( f ); |
3349 | 3372 | ||
3350 | return pntr->fontMetrics().width( c ); | 3373 | return pntr->fontMetrics().width( c ); |
3351 | } | 3374 | } |
3352 | 3375 | ||
3353 | int QTextFormat::width( const QString &str, int pos ) const | 3376 | int QTextFormat::width( const QString &str, int pos ) const |
3354 | { | 3377 | { |
3355 | int w = 0; | 3378 | int w = 0; |
3356 | if ( str[ pos ].unicode() == 0xad ) | 3379 | if ( str[ pos ].unicode() == 0xad ) |
3357 | return w; | 3380 | return w; |
3358 | if ( !pntr || !pntr->isActive() ) { | 3381 | if ( !pntr || !pntr->isActive() ) { |
3359 | if ( ha == AlignNormal ) { | 3382 | if ( ha == AlignNormal ) { |
3360 | w = fm.width( str[ pos ] ); | 3383 | w = fm.width( str[ pos ] ); |
3361 | } else { | 3384 | } else { |
3362 | QFont f( fn ); | 3385 | QFont f( fn ); |
3363 | if ( usePixelSizes ) | 3386 | if ( usePixelSizes ) |
3364 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3387 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3365 | else | 3388 | else |
3366 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3389 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3367 | QFontMetrics fm_( f ); | 3390 | QFontMetrics fm_( f ); |
3368 | w = fm_.width( str[ pos ] ); | 3391 | w = fm_.width( str[ pos ] ); |
3369 | } | 3392 | } |
3370 | } else { | 3393 | } else { |
3371 | QFont f( fn ); | 3394 | QFont f( fn ); |
3372 | if ( ha != AlignNormal ) { | 3395 | if ( ha != AlignNormal ) { |
3373 | if ( usePixelSizes ) | 3396 | if ( usePixelSizes ) |
3374 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 3397 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
3375 | else | 3398 | else |
3376 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 3399 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
3377 | } | 3400 | } |
3378 | pntr->setFont( f ); | 3401 | pntr->setFont( f ); |
3379 | w = pntr->fontMetrics().width( str[ pos ] ); | 3402 | w = pntr->fontMetrics().width( str[ pos ] ); |
3380 | } | 3403 | } |
3381 | return w; | 3404 | return w; |
3382 | } | 3405 | } |
3383 | 3406 | ||
3384 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 3407 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3385 | 3408 | ||
3386 | QTextString::QTextString() | 3409 | QTextString::QTextString() |
3387 | { | 3410 | { |
3388 | bidiDirty = FALSE; | 3411 | bidiDirty = FALSE; |
3389 | bidi = FALSE; | 3412 | bidi = FALSE; |
3390 | rightToLeft = FALSE; | 3413 | rightToLeft = FALSE; |
3391 | dir = QChar::DirON; | 3414 | dir = QChar::DirON; |
3392 | } | 3415 | } |
3393 | 3416 | ||
3394 | QTextString::QTextString( const QTextString &s ) | 3417 | QTextString::QTextString( const QTextString &s ) |
3395 | { | 3418 | { |
3396 | bidiDirty = s.bidiDirty; | 3419 | bidiDirty = s.bidiDirty; |
3397 | bidi = s.bidi; | 3420 | bidi = s.bidi; |
3398 | rightToLeft = s.rightToLeft; | 3421 | rightToLeft = s.rightToLeft; |
3399 | dir = s.dir; | 3422 | dir = s.dir; |
3400 | data = s.subString(); | 3423 | data = s.subString(); |
3401 | } | 3424 | } |
3402 | 3425 | ||
3403 | void QTextString::insert( int index, const QString &s, QTextFormat *f ) | 3426 | void QTextString::insert( int index, const QString &s, QTextFormat *f ) |
3404 | { | 3427 | { |
3405 | insert( index, s.unicode(), s.length(), f ); | 3428 | insert( index, s.unicode(), s.length(), f ); |
3406 | } | 3429 | } |
3407 | 3430 | ||
3408 | void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f ) | 3431 | void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f ) |
3409 | { | 3432 | { |
3410 | int os = data.size(); | 3433 | int os = data.size(); |
3411 | data.resize( data.size() + len ); | 3434 | data.resize( data.size() + len ); |
3412 | if ( index < os ) { | 3435 | if ( index < os ) { |
3413 | memmove( data.data() + index + len, data.data() + index, | 3436 | memmove( data.data() + index + len, data.data() + index, |
3414 | sizeof( QTextStringChar ) * ( os - index ) ); | 3437 | sizeof( QTextStringChar ) * ( os - index ) ); |
3415 | } | 3438 | } |
3416 | for ( int i = 0; i < len; ++i ) { | 3439 | for ( int i = 0; i < len; ++i ) { |
3417 | data[ (int)index + i ].x = 0; | 3440 | data[ (int)index + i ].x = 0; |
3418 | data[ (int)index + i ].lineStart = 0; | 3441 | data[ (int)index + i ].lineStart = 0; |
3419 | data[ (int)index + i ].d.format = 0; | 3442 | data[ (int)index + i ].d.format = 0; |
3420 | data[ (int)index + i ].type = QTextStringChar::Regular; | 3443 | data[ (int)index + i ].type = QTextStringChar::Regular; |
3421 | data[ (int)index + i ].rightToLeft = 0; | 3444 | data[ (int)index + i ].rightToLeft = 0; |
3422 | data[ (int)index + i ].startOfRun = 0; | 3445 | data[ (int)index + i ].startOfRun = 0; |
3423 | data[ (int)index + i ].c = unicode[i]; | 3446 | data[ (int)index + i ].c = unicode[i]; |
3424 | data[ (int)index + i ].setFormat( f ); | 3447 | data[ (int)index + i ].setFormat( f ); |
3425 | } | 3448 | } |
3426 | bidiDirty = TRUE; | 3449 | bidiDirty = TRUE; |
3427 | } | 3450 | } |
3428 | 3451 | ||
3429 | QTextString::~QTextString() | 3452 | QTextString::~QTextString() |
3430 | { | 3453 | { |
3431 | clear(); | 3454 | clear(); |
3432 | } | 3455 | } |
3433 | 3456 | ||
3434 | void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat ) | 3457 | void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat ) |
3435 | { | 3458 | { |
3436 | int os = data.size(); | 3459 | int os = data.size(); |
3437 | data.resize( data.size() + 1 ); | 3460 | data.resize( data.size() + 1 ); |
3438 | if ( index < os ) { | 3461 | if ( index < os ) { |
3439 | memmove( data.data() + index + 1, data.data() + index, | 3462 | memmove( data.data() + index + 1, data.data() + index, |
3440 | sizeof( QTextStringChar ) * ( os - index ) ); | 3463 | sizeof( QTextStringChar ) * ( os - index ) ); |
3441 | } | 3464 | } |
3442 | data[ (int)index ].c = c->c; | 3465 | data[ (int)index ].c = c->c; |
3443 | data[ (int)index ].x = 0; | 3466 | data[ (int)index ].x = 0; |
3444 | data[ (int)index ].lineStart = 0; | 3467 | data[ (int)index ].lineStart = 0; |
3445 | data[ (int)index ].rightToLeft = 0; | 3468 | data[ (int)index ].rightToLeft = 0; |
3446 | data[ (int)index ].d.format = 0; | 3469 | data[ (int)index ].d.format = 0; |
3447 | data[ (int)index ].type = QTextStringChar::Regular; | 3470 | data[ (int)index ].type = QTextStringChar::Regular; |
3448 | if ( doAddRefFormat && c->format() ) | 3471 | if ( doAddRefFormat && c->format() ) |
3449 | c->format()->addRef(); | 3472 | c->format()->addRef(); |
3450 | data[ (int)index ].setFormat( c->format() ); | 3473 | data[ (int)index ].setFormat( c->format() ); |
3451 | bidiDirty = TRUE; | 3474 | bidiDirty = TRUE; |
3452 | } | 3475 | } |
3453 | 3476 | ||
3454 | void QTextString::truncate( int index ) | 3477 | void QTextString::truncate( int index ) |
3455 | { | 3478 | { |
3456 | index = QMAX( index, 0 ); | 3479 | index = QMAX( index, 0 ); |
3457 | index = QMIN( index, (int)data.size() - 1 ); | 3480 | index = QMIN( index, (int)data.size() - 1 ); |
3458 | if ( index < (int)data.size() ) { | 3481 | if ( index < (int)data.size() ) { |
3459 | for ( int i = index + 1; i < (int)data.size(); ++i ) { | 3482 | for ( int i = index + 1; i < (int)data.size(); ++i ) { |
3460 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { | 3483 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { |
3461 | delete data[ i ].customItem(); | 3484 | delete data[ i ].customItem(); |
3462 | if ( data[ i ].d.custom->format ) | 3485 | if ( data[ i ].d.custom->format ) |
3463 | data[ i ].d.custom->format->removeRef(); | 3486 | data[ i ].d.custom->format->removeRef(); |
3464 | delete data[ i ].d.custom; | 3487 | delete data[ i ].d.custom; |
3465 | data[ i ].d.custom = 0; | 3488 | data[ i ].d.custom = 0; |
3466 | } else if ( data[ i ].format() ) { | 3489 | } else if ( data[ i ].format() ) { |
3467 | data[ i ].format()->removeRef(); | 3490 | data[ i ].format()->removeRef(); |
3468 | } | 3491 | } |
3469 | } | 3492 | } |
3470 | } | 3493 | } |
3471 | data.truncate( index ); | 3494 | data.truncate( index ); |
3472 | bidiDirty = TRUE; | 3495 | bidiDirty = TRUE; |
3473 | } | 3496 | } |
3474 | 3497 | ||
3475 | void QTextString::remove( int index, int len ) | 3498 | void QTextString::remove( int index, int len ) |
3476 | { | 3499 | { |
3477 | for ( int i = index; i < (int)data.size() && i - index < len; ++i ) { | 3500 | for ( int i = index; i < (int)data.size() && i - index < len; ++i ) { |
3478 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { | 3501 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { |
3479 | delete data[ i ].customItem(); | 3502 | delete data[ i ].customItem(); |
3480 | if ( data[ i ].d.custom->format ) | 3503 | if ( data[ i ].d.custom->format ) |
3481 | data[ i ].d.custom->format->removeRef(); | 3504 | data[ i ].d.custom->format->removeRef(); |
3482 | delete data[ i ].d.custom; | 3505 | delete data[ i ].d.custom; |
3483 | data[ i ].d.custom = 0; | 3506 | data[ i ].d.custom = 0; |
3484 | } else if ( data[ i ].format() ) { | 3507 | } else if ( data[ i ].format() ) { |
3485 | data[ i ].format()->removeRef(); | 3508 | data[ i ].format()->removeRef(); |
3486 | } | 3509 | } |
3487 | } | 3510 | } |
3488 | memmove( data.data() + index, data.data() + index + len, | 3511 | memmove( data.data() + index, data.data() + index + len, |
3489 | sizeof( QTextStringChar ) * ( data.size() - index - len ) ); | 3512 | sizeof( QTextStringChar ) * ( data.size() - index - len ) ); |
3490 | data.resize( data.size() - len ); | 3513 | data.resize( data.size() - len ); |
3491 | bidiDirty = TRUE; | 3514 | bidiDirty = TRUE; |
3492 | } | 3515 | } |
3493 | 3516 | ||
3494 | void QTextString::clear() | 3517 | void QTextString::clear() |
3495 | { | 3518 | { |
3496 | for ( int i = 0; i < (int)data.count(); ++i ) { | 3519 | for ( int i = 0; i < (int)data.count(); ++i ) { |
3497 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { | 3520 | if ( !(data[ i ].type == QTextStringChar::Regular) ) { |
3498 | delete data[ i ].customItem(); | 3521 | delete data[ i ].customItem(); |
3499 | if ( data[ i ].d.custom->format ) | 3522 | if ( data[ i ].d.custom->format ) |
3500 | data[ i ].d.custom->format->removeRef(); | 3523 | data[ i ].d.custom->format->removeRef(); |
3501 | delete data[ i ].d.custom; | 3524 | delete data[ i ].d.custom; |
3502 | data[ i ].d.custom = 0; | 3525 | data[ i ].d.custom = 0; |
3503 | } else if ( data[ i ].format() ) { | 3526 | } else if ( data[ i ].format() ) { |
3504 | data[ i ].format()->removeRef(); | 3527 | data[ i ].format()->removeRef(); |
3505 | } | 3528 | } |
3506 | } | 3529 | } |
3507 | data.resize( 0 ); | 3530 | data.resize( 0 ); |
3508 | } | 3531 | } |
3509 | 3532 | ||
3510 | void QTextString::setFormat( int index, QTextFormat *f, bool useCollection ) | 3533 | void QTextString::setFormat( int index, QTextFormat *f, bool useCollection ) |
3511 | { | 3534 | { |
3512 | if ( useCollection && data[ index ].format() ) | 3535 | if ( useCollection && data[ index ].format() ) |
3513 | data[ index ].format()->removeRef(); | 3536 | data[ index ].format()->removeRef(); |
3514 | data[ index ].setFormat( f ); | 3537 | data[ index ].setFormat( f ); |
3515 | } | 3538 | } |
3516 | 3539 | ||
3517 | void QTextString::checkBidi() const | 3540 | void QTextString::checkBidi() const |
3518 | { | 3541 | { |
3519 | bool rtlKnown = FALSE; | 3542 | bool rtlKnown = FALSE; |
3520 | if ( dir == QChar::DirR ) { | 3543 | if ( dir == QChar::DirR ) { |
3521 | ((QTextString *)this)->bidi = TRUE; | 3544 | ((QTextString *)this)->bidi = TRUE; |
3522 | ((QTextString *)this)->rightToLeft = TRUE; | 3545 | ((QTextString *)this)->rightToLeft = TRUE; |
3523 | rtlKnown = TRUE; | 3546 | rtlKnown = TRUE; |
3524 | return; | 3547 | return; |
3525 | } else if ( dir == QChar::DirL ) { | 3548 | } else if ( dir == QChar::DirL ) { |
3526 | ((QTextString *)this)->rightToLeft = FALSE; | 3549 | ((QTextString *)this)->rightToLeft = FALSE; |
3527 | rtlKnown = TRUE; | 3550 | rtlKnown = TRUE; |
3528 | } else { | 3551 | } else { |
3529 | ((QTextString *)this)->rightToLeft = FALSE; | 3552 | ((QTextString *)this)->rightToLeft = FALSE; |
3530 | } | 3553 | } |
3531 | 3554 | ||
3532 | int len = data.size(); | 3555 | int len = data.size(); |
3533 | const QTextStringChar *c = data.data(); | 3556 | const QTextStringChar *c = data.data(); |
3534 | ((QTextString *)this)->bidi = FALSE; | 3557 | ((QTextString *)this)->bidi = FALSE; |
3535 | while( len ) { | 3558 | while( len ) { |
3536 | if ( !rtlKnown ) { | 3559 | if ( !rtlKnown ) { |
3537 | switch( c->c.direction() ) | 3560 | switch( c->c.direction() ) |
3538 | { | 3561 | { |
3539 | case QChar::DirL: | 3562 | case QChar::DirL: |
3540 | case QChar::DirLRO: | 3563 | case QChar::DirLRO: |
3541 | case QChar::DirLRE: | 3564 | case QChar::DirLRE: |
3542 | ((QTextString *)this)->rightToLeft = FALSE; | 3565 | ((QTextString *)this)->rightToLeft = FALSE; |
3543 | rtlKnown = TRUE; | 3566 | rtlKnown = TRUE; |
3544 | break; | 3567 | break; |
3545 | case QChar::DirR: | 3568 | case QChar::DirR: |
3546 | case QChar::DirAL: | 3569 | case QChar::DirAL: |
3547 | case QChar::DirRLO: | 3570 | case QChar::DirRLO: |
3548 | case QChar::DirRLE: | 3571 | case QChar::DirRLE: |
3549 | ((QTextString *)this)->rightToLeft = TRUE; | 3572 | ((QTextString *)this)->rightToLeft = TRUE; |
3550 | rtlKnown = TRUE; | 3573 | rtlKnown = TRUE; |
3551 | break; | 3574 | break; |
3552 | default: | 3575 | default: |
3553 | break; | 3576 | break; |
3554 | } | 3577 | } |
3555 | } | 3578 | } |
3556 | uchar row = c->c.row(); | 3579 | uchar row = c->c.row(); |
3557 | if( (row > 0x04 && row < 0x09) || (row > 0xfa && row < 0xff) ) { | 3580 | if( (row > 0x04 && row < 0x09) || (row > 0xfa && row < 0xff) ) { |
3558 | ((QTextString *)this)->bidi = TRUE; | 3581 | ((QTextString *)this)->bidi = TRUE; |
3559 | if ( rtlKnown ) | 3582 | if ( rtlKnown ) |
3560 | return; | 3583 | return; |
3561 | } | 3584 | } |
3562 | len--; | 3585 | len--; |
3563 | ++c; | 3586 | ++c; |
3564 | } | 3587 | } |
3565 | } | 3588 | } |
3566 | 3589 | ||
3567 | void QTextDocument::setStyleSheet( QStyleSheet *s ) | 3590 | void QTextDocument::setStyleSheet( QStyleSheet *s ) |
3568 | { | 3591 | { |
3569 | if ( !s ) | 3592 | if ( !s ) |
3570 | return; | 3593 | return; |
3571 | sheet_ = s; | 3594 | sheet_ = s; |
3572 | list_tm = list_bm = par_tm = par_bm = 12; | 3595 | list_tm = list_bm = par_tm = par_bm = 12; |
3573 | list_lm = 40; | 3596 | list_lm = 40; |
3574 | li_tm = li_bm = 0; | 3597 | li_tm = li_bm = 0; |
3575 | QStyleSheetItem* item = s->item( "ol" ); | 3598 | QStyleSheetItem* item = s->item( "ol" ); |
3576 | if ( item ) { | 3599 | if ( item ) { |
3577 | list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); | 3600 | list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); |
3578 | list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); | 3601 | list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); |
3579 | list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft )); | 3602 | list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft )); |
3580 | } | 3603 | } |
3581 | if ( (item = s->item( "li" ) ) ) { | 3604 | if ( (item = s->item( "li" ) ) ) { |
3582 | li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); | 3605 | li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); |
3583 | li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); | 3606 | li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); |
3584 | } | 3607 | } |
3585 | if ( (item = s->item( "p" ) ) ) { | 3608 | if ( (item = s->item( "p" ) ) ) { |
3586 | par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); | 3609 | par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); |
3587 | par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); | 3610 | par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); |
3588 | } | 3611 | } |
3589 | } | 3612 | } |
3590 | 3613 | ||
3591 | void QTextDocument::setUnderlineLinks( bool b ) { | 3614 | void QTextDocument::setUnderlineLinks( bool b ) { |
3592 | underlLinks = b; | 3615 | underlLinks = b; |
3593 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) | 3616 | for ( QTextDocument *d = childList.first(); d; d = childList.next() ) |
3594 | d->setUnderlineLinks( b ); | 3617 | d->setUnderlineLinks( b ); |
3595 | } | 3618 | } |
3596 | 3619 | ||
3597 | void QTextStringChar::setFormat( QTextFormat *f ) | 3620 | void QTextStringChar::setFormat( QTextFormat *f ) |
3598 | { | 3621 | { |
3599 | if ( type == Regular ) { | 3622 | if ( type == Regular ) { |
3600 | d.format = f; | 3623 | d.format = f; |
3601 | } else { | 3624 | } else { |
3602 | if ( !d.custom ) { | 3625 | if ( !d.custom ) { |
3603 | d.custom = new CustomData; | 3626 | d.custom = new CustomData; |
3604 | d.custom->custom = 0; | 3627 | d.custom->custom = 0; |
3605 | } | 3628 | } |
3606 | d.custom->format = f; | 3629 | d.custom->format = f; |
3607 | } | 3630 | } |
3608 | } | 3631 | } |
3609 | 3632 | ||
3610 | void QTextStringChar::setCustomItem( QTextCustomItem *i ) | 3633 | void QTextStringChar::setCustomItem( QTextCustomItem *i ) |
3611 | { | 3634 | { |
3612 | if ( type == Regular ) { | 3635 | if ( type == Regular ) { |
3613 | QTextFormat *f = format(); | 3636 | QTextFormat *f = format(); |
3614 | d.custom = new CustomData; | 3637 | d.custom = new CustomData; |
3615 | d.custom->format = f; | 3638 | d.custom->format = f; |
3616 | } else { | 3639 | } else { |
3617 | delete d.custom->custom; | 3640 | delete d.custom->custom; |
3618 | } | 3641 | } |
3619 | d.custom->custom = i; | 3642 | d.custom->custom = i; |
3620 | type = (type == Anchor ? CustomAnchor : Custom); | 3643 | type = (type == Anchor ? CustomAnchor : Custom); |
3621 | } | 3644 | } |
3622 | 3645 | ||
3623 | void QTextStringChar::loseCustomItem() | 3646 | void QTextStringChar::loseCustomItem() |
3624 | { | 3647 | { |
3625 | if ( type == Custom ) { | 3648 | if ( type == Custom ) { |
3626 | QTextFormat *f = d.custom->format; | 3649 | QTextFormat *f = d.custom->format; |
3627 | d.custom->custom = 0; | 3650 | d.custom->custom = 0; |
3628 | delete d.custom; | 3651 | delete d.custom; |
3629 | type = Regular; | 3652 | type = Regular; |
3630 | d.format = f; | 3653 | d.format = f; |
3631 | } else if ( type == CustomAnchor ) { | 3654 | } else if ( type == CustomAnchor ) { |
3632 | d.custom->custom = 0; | 3655 | d.custom->custom = 0; |
3633 | type = Anchor; | 3656 | type = Anchor; |
3634 | } | 3657 | } |
3635 | } | 3658 | } |
3636 | 3659 | ||
3637 | QString QTextStringChar::anchorName() const | 3660 | QString QTextStringChar::anchorName() const |
3638 | { | 3661 | { |
3639 | if ( type == Regular ) | 3662 | if ( type == Regular ) |
3640 | return QString::null; | 3663 | return QString::null; |
3641 | else | 3664 | else |
3642 | return d.custom->anchorName; | 3665 | return d.custom->anchorName; |
3643 | } | 3666 | } |
3644 | 3667 | ||
3645 | QString QTextStringChar::anchorHref() const | 3668 | QString QTextStringChar::anchorHref() const |
3646 | { | 3669 | { |
3647 | if ( type == Regular ) | 3670 | if ( type == Regular ) |
3648 | return QString::null; | 3671 | return QString::null; |
3649 | else | 3672 | else |
3650 | return d.custom->anchorHref; | 3673 | return d.custom->anchorHref; |
3651 | } | 3674 | } |
3652 | 3675 | ||
3653 | void QTextStringChar::setAnchor( const QString& name, const QString& href ) | 3676 | void QTextStringChar::setAnchor( const QString& name, const QString& href ) |
3654 | { | 3677 | { |
3655 | if ( type == Regular ) { | 3678 | if ( type == Regular ) { |
3656 | QTextFormat *f = format(); | 3679 | QTextFormat *f = format(); |
3657 | d.custom = new CustomData; | 3680 | d.custom = new CustomData; |
3658 | d.custom->custom = 0; | 3681 | d.custom->custom = 0; |
3659 | d.custom->format = f; | 3682 | d.custom->format = f; |
3660 | type = Anchor; | 3683 | type = Anchor; |
3661 | } else if ( type == Custom ) { | 3684 | } else if ( type == Custom ) { |
3662 | type = CustomAnchor; | 3685 | type = CustomAnchor; |
3663 | } | 3686 | } |
3664 | d.custom->anchorName = name; | 3687 | d.custom->anchorName = name; |
3665 | d.custom->anchorHref = href; | 3688 | d.custom->anchorHref = href; |
3666 | } | 3689 | } |
3667 | 3690 | ||
3668 | 3691 | ||
3669 | int QTextString::width( int idx ) const | 3692 | int QTextString::width( int idx ) const |
3670 | { | 3693 | { |
3671 | int w = 0; | 3694 | int w = 0; |
3672 | QTextStringChar *c = &at( idx ); | 3695 | QTextStringChar *c = &at( idx ); |
3673 | if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 ) | 3696 | if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 ) |
3674 | return 0; | 3697 | return 0; |
3675 | if( c->isCustom() ) { | 3698 | if( c->isCustom() ) { |
3676 | if( c->customItem()->placement() == QTextCustomItem::PlaceInline ) | 3699 | if( c->customItem()->placement() == QTextCustomItem::PlaceInline ) |
3677 | w = c->customItem()->width; | 3700 | w = c->customItem()->width; |
3678 | } else { | 3701 | } else { |
3679 | int r = c->c.row(); | 3702 | int r = c->c.row(); |
3680 | if( r < 0x06 || r > 0x1f ) | 3703 | if( r < 0x06 || r > 0x1f ) |
3681 | w = c->format()->width( c->c ); | 3704 | w = c->format()->width( c->c ); |
3682 | else { | 3705 | else { |
3683 | // complex text. We need some hacks to get the right metric here | 3706 | // complex text. We need some hacks to get the right metric here |
3684 | QString str; | 3707 | QString str; |
3685 | int pos = 0; | 3708 | int pos = 0; |
3686 | if( idx > 4 ) | 3709 | if( idx > 4 ) |
3687 | pos = idx - 4; | 3710 | pos = idx - 4; |
3688 | int off = idx - pos; | 3711 | int off = idx - pos; |
3689 | int end = QMIN( length(), idx + 4 ); | 3712 | int end = QMIN( length(), idx + 4 ); |
3690 | while ( pos < end ) { | 3713 | while ( pos < end ) { |
3691 | str += at(pos).c; | 3714 | str += at(pos).c; |
3692 | pos++; | 3715 | pos++; |
3693 | } | 3716 | } |
3694 | w = c->format()->width( str, off ); | 3717 | w = c->format()->width( str, off ); |
3695 | } | 3718 | } |
3696 | } | 3719 | } |
3697 | return w; | 3720 | return w; |
3698 | } | 3721 | } |
3699 | 3722 | ||
3700 | QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const | 3723 | QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const |
3701 | { | 3724 | { |
3702 | if ( len == 0xFFFFFF ) | 3725 | if ( len == 0xFFFFFF ) |
3703 | len = data.size(); | 3726 | len = data.size(); |
3704 | QMemArray<QTextStringChar> a; | 3727 | QMemArray<QTextStringChar> a; |
3705 | a.resize( len ); | 3728 | a.resize( len ); |
3706 | for ( int i = 0; i < len; ++i ) { | 3729 | for ( int i = 0; i < len; ++i ) { |
3707 | QTextStringChar *c = &data[ i + start ]; | 3730 | QTextStringChar *c = &data[ i + start ]; |
3708 | a[ i ].c = c->c; | 3731 | a[ i ].c = c->c; |
3709 | a[ i ].x = 0; | 3732 | a[ i ].x = 0; |
3710 | a[ i ].lineStart = 0; | 3733 | a[ i ].lineStart = 0; |
3711 | a[ i ].rightToLeft = 0; | 3734 | a[ i ].rightToLeft = 0; |
3712 | a[ i ].d.format = 0; | 3735 | a[ i ].d.format = 0; |
3713 | a[ i ].type = QTextStringChar::Regular; | 3736 | a[ i ].type = QTextStringChar::Regular; |
3714 | a[ i ].setFormat( c->format() ); | 3737 | a[ i ].setFormat( c->format() ); |
3715 | if ( c->format() ) | 3738 | if ( c->format() ) |
3716 | c->format()->addRef(); | 3739 | c->format()->addRef(); |
3717 | } | 3740 | } |
3718 | return a; | 3741 | return a; |
3719 | } | 3742 | } |
3720 | 3743 | ||
3721 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 3744 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3722 | 3745 | ||
3723 | QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) | 3746 | QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) |
3724 | : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ), | 3747 | : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ), |
3725 | changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE), | 3748 | changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE), |
3726 | lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE), | 3749 | lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE), |
3727 | mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE), | 3750 | mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE), |
3728 | align( 0 ),mSelections( 0 ), | 3751 | align( 0 ),mSelections( 0 ), |
3729 | mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ), | 3752 | mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ), |
3730 | utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ), | 3753 | utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ), |
3731 | tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 ) | 3754 | tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 ) |
3732 | { | 3755 | { |
3733 | lstyle = QStyleSheetItem::ListDisc; | 3756 | lstyle = QStyleSheetItem::ListDisc; |
3734 | if ( !hasdoc ) | 3757 | if ( !hasdoc ) |
3735 | docOrPseudo = new QTextParagraphPseudoDocument; | 3758 | docOrPseudo = new QTextParagraphPseudoDocument; |
3736 | bgcol = 0; | 3759 | bgcol = 0; |
3737 | list_val = -1; | 3760 | list_val = -1; |
3738 | QTextFormat* defFormat = formatCollection()->defaultFormat(); | 3761 | QTextFormat* defFormat = formatCollection()->defaultFormat(); |
3739 | if ( !hasdoc ) { | 3762 | if ( !hasdoc ) { |
3740 | tabStopWidth = defFormat->width( 'x' ) * 8; | 3763 | tabStopWidth = defFormat->width( 'x' ) * 8; |
3741 | pseudoDocument()->commandHistory = new QTextCommandHistory( 100 ); | 3764 | pseudoDocument()->commandHistory = new QTextCommandHistory( 100 ); |
3742 | } | 3765 | } |
3743 | 3766 | ||
3744 | if ( p ) | 3767 | if ( p ) |
3745 | p->n = this; | 3768 | p->n = this; |
3746 | if ( n ) | 3769 | if ( n ) |
3747 | n->p = this; | 3770 | n->p = this; |
3748 | 3771 | ||
3749 | 3772 | ||
3750 | if ( !p && hasdoc ) | 3773 | if ( !p && hasdoc ) |
3751 | document()->setFirstParagraph( this ); | 3774 | document()->setFirstParagraph( this ); |
3752 | if ( !n && hasdoc ) | 3775 | if ( !n && hasdoc ) |
3753 | document()->setLastParagraph( this ); | 3776 | document()->setLastParagraph( this ); |
3754 | 3777 | ||
3755 | state = -1; | 3778 | state = -1; |
3756 | 3779 | ||
3757 | if ( p ) | 3780 | if ( p ) |
3758 | id = p->id + 1; | 3781 | id = p->id + 1; |
3759 | else | 3782 | else |
3760 | id = 0; | 3783 | id = 0; |
3761 | if ( n && updateIds ) { | 3784 | if ( n && updateIds ) { |
3762 | QTextParagraph *s = n; | 3785 | QTextParagraph *s = n; |
3763 | while ( s ) { | 3786 | while ( s ) { |
3764 | s->id = s->p->id + 1; | 3787 | s->id = s->p->id + 1; |
3765 | s->invalidateStyleCache(); | 3788 | s->invalidateStyleCache(); |
3766 | s = s->n; | 3789 | s = s->n; |
3767 | } | 3790 | } |
3768 | } | 3791 | } |
3769 | 3792 | ||
3770 | str = new QTextString(); | 3793 | str = new QTextString(); |
3771 | str->insert( 0, " ", formatCollection()->defaultFormat() ); | 3794 | str->insert( 0, " ", formatCollection()->defaultFormat() ); |
3772 | } | 3795 | } |
3773 | 3796 | ||
3774 | QTextParagraph::~QTextParagraph() | 3797 | QTextParagraph::~QTextParagraph() |
3775 | { | 3798 | { |
3776 | delete str; | 3799 | delete str; |
3777 | if ( hasdoc ) { | 3800 | if ( hasdoc ) { |
3778 | register QTextDocument *doc = document(); | 3801 | register QTextDocument *doc = document(); |
3779 | if ( this == doc->minwParag ) { | 3802 | if ( this == doc->minwParag ) { |
3780 | doc->minwParag = 0; | 3803 | doc->minwParag = 0; |
3781 | doc->minw = 0; | 3804 | doc->minw = 0; |
3782 | } | 3805 | } |
3783 | if ( this == doc->curParag ) | 3806 | if ( this == doc->curParag ) |
3784 | doc->curParag = 0; | 3807 | doc->curParag = 0; |
3785 | } else { | 3808 | } else { |
3786 | delete pseudoDocument(); | 3809 | delete pseudoDocument(); |
3787 | } | 3810 | } |
3788 | if ( tArray ) | 3811 | if ( tArray ) |
3789 | delete [] tArray; | 3812 | delete [] tArray; |
3790 | delete eData; | 3813 | delete eData; |
3791 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); | 3814 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); |
3792 | for ( ; it != lineStarts.end(); ++it ) | 3815 | for ( ; it != lineStarts.end(); ++it ) |
3793 | delete *it; | 3816 | delete *it; |
3794 | if ( mSelections ) | 3817 | if ( mSelections ) |
3795 | delete mSelections; | 3818 | delete mSelections; |
3796 | if ( mFloatingItems ) | 3819 | if ( mFloatingItems ) |
3797 | delete mFloatingItems; | 3820 | delete mFloatingItems; |
3798 | if ( p ) | 3821 | if ( p ) |
3799 | p->setNext( n ); | 3822 | p->setNext( n ); |
3800 | if ( n ) | 3823 | if ( n ) |
3801 | n->setPrev( p ); | 3824 | n->setPrev( p ); |
3802 | } | 3825 | } |
3803 | 3826 | ||
3804 | void QTextParagraph::setNext( QTextParagraph *s ) | 3827 | void QTextParagraph::setNext( QTextParagraph *s ) |
3805 | { | 3828 | { |
3806 | n = s; | 3829 | n = s; |
3807 | if ( !n && hasdoc ) | 3830 | if ( !n && hasdoc ) |
3808 | document()->setLastParagraph( this ); | 3831 | document()->setLastParagraph( this ); |
3809 | } | 3832 | } |
3810 | 3833 | ||
3811 | void QTextParagraph::setPrev( QTextParagraph *s ) | 3834 | void QTextParagraph::setPrev( QTextParagraph *s ) |
3812 | { | 3835 | { |
3813 | p = s; | 3836 | p = s; |
3814 | if ( !p && hasdoc ) | 3837 | if ( !p && hasdoc ) |
3815 | document()->setFirstParagraph( this ); | 3838 | document()->setFirstParagraph( this ); |
3816 | } | 3839 | } |
3817 | 3840 | ||
3818 | void QTextParagraph::invalidate( int chr ) | 3841 | void QTextParagraph::invalidate( int chr ) |
3819 | { | 3842 | { |
3820 | if ( invalid < 0 ) | 3843 | if ( invalid < 0 ) |
3821 | invalid = chr; | 3844 | invalid = chr; |
3822 | else | 3845 | else |
3823 | invalid = QMIN( invalid, chr ); | 3846 | invalid = QMIN( invalid, chr ); |
3824 | if ( mFloatingItems ) { | 3847 | if ( mFloatingItems ) { |
3825 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) | 3848 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) |
3826 | i->ypos = -1; | 3849 | i->ypos = -1; |
3827 | } | 3850 | } |
3828 | invalidateStyleCache(); | 3851 | invalidateStyleCache(); |
3829 | } | 3852 | } |
3830 | 3853 | ||
3831 | void QTextParagraph::invalidateStyleCache() | 3854 | void QTextParagraph::invalidateStyleCache() |
3832 | { | 3855 | { |
3833 | if ( list_val < 0 ) | 3856 | if ( list_val < 0 ) |
3834 | list_val = -1; | 3857 | list_val = -1; |
3835 | } | 3858 | } |
3836 | 3859 | ||
3837 | 3860 | ||
3838 | void QTextParagraph::insert( int index, const QString &s ) | 3861 | void QTextParagraph::insert( int index, const QString &s ) |
3839 | { | 3862 | { |
3840 | insert( index, s.unicode(), s.length() ); | 3863 | insert( index, s.unicode(), s.length() ); |
3841 | } | 3864 | } |
3842 | 3865 | ||
3843 | void QTextParagraph::insert( int index, const QChar *unicode, int len ) | 3866 | void QTextParagraph::insert( int index, const QChar *unicode, int len ) |
3844 | { | 3867 | { |
3845 | if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() ) | 3868 | if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() ) |
3846 | str->insert( index, unicode, len, | 3869 | str->insert( index, unicode, len, |
3847 | document()->preProcessor()->format( QTextPreProcessor::Standard ) ); | 3870 | document()->preProcessor()->format( QTextPreProcessor::Standard ) ); |
3848 | else | 3871 | else |
3849 | str->insert( index, unicode, len, formatCollection()->defaultFormat() ); | 3872 | str->insert( index, unicode, len, formatCollection()->defaultFormat() ); |
3850 | invalidate( index ); | 3873 | invalidate( index ); |
3851 | needPreProcess = TRUE; | 3874 | needPreProcess = TRUE; |
3852 | } | 3875 | } |
3853 | 3876 | ||
3854 | void QTextParagraph::truncate( int index ) | 3877 | void QTextParagraph::truncate( int index ) |
3855 | { | 3878 | { |
3856 | str->truncate( index ); | 3879 | str->truncate( index ); |
3857 | insert( length(), " " ); | 3880 | insert( length(), " " ); |
3858 | needPreProcess = TRUE; | 3881 | needPreProcess = TRUE; |
3859 | } | 3882 | } |
3860 | 3883 | ||
3861 | void QTextParagraph::remove( int index, int len ) | 3884 | void QTextParagraph::remove( int index, int len ) |
3862 | { | 3885 | { |
3863 | if ( index + len - str->length() > 0 ) | 3886 | if ( index + len - str->length() > 0 ) |
3864 | return; | 3887 | return; |
3865 | for ( int i = index; i < index + len; ++i ) { | 3888 | for ( int i = index; i < index + len; ++i ) { |
3866 | QTextStringChar *c = at( i ); | 3889 | QTextStringChar *c = at( i ); |
3867 | if ( hasdoc && c->isCustom() ) { | 3890 | if ( hasdoc && c->isCustom() ) { |
3868 | document()->unregisterCustomItem( c->customItem(), this ); | 3891 | document()->unregisterCustomItem( c->customItem(), this ); |
3869 | } | 3892 | } |
3870 | } | 3893 | } |
3871 | str->remove( index, len ); | 3894 | str->remove( index, len ); |
3872 | invalidate( 0 ); | 3895 | invalidate( 0 ); |
3873 | needPreProcess = TRUE; | 3896 | needPreProcess = TRUE; |
3874 | } | 3897 | } |
3875 | 3898 | ||
3876 | void QTextParagraph::join( QTextParagraph *s ) | 3899 | void QTextParagraph::join( QTextParagraph *s ) |
3877 | { | 3900 | { |
3878 | int oh = r.height() + s->r.height(); | 3901 | int oh = r.height() + s->r.height(); |
3879 | n = s->n; | 3902 | n = s->n; |
3880 | if ( n ) | 3903 | if ( n ) |
3881 | n->p = this; | 3904 | n->p = this; |
3882 | else if ( hasdoc ) | 3905 | else if ( hasdoc ) |
3883 | document()->setLastParagraph( this ); | 3906 | document()->setLastParagraph( this ); |
3884 | 3907 | ||
3885 | int start = str->length(); | 3908 | int start = str->length(); |
3886 | if ( length() > 0 && at( length() - 1 )->c == ' ' ) { | 3909 | if ( length() > 0 && at( length() - 1 )->c == ' ' ) { |
3887 | remove( length() - 1, 1 ); | 3910 | remove( length() - 1, 1 ); |
3888 | --start; | 3911 | --start; |
3889 | } | 3912 | } |
3890 | append( s->str->toString(), TRUE ); | 3913 | append( s->str->toString(), TRUE ); |
3891 | 3914 | ||
3892 | for ( int i = 0; i < s->length(); ++i ) { | 3915 | for ( int i = 0; i < s->length(); ++i ) { |
3893 | if ( !hasdoc || document()->useFormatCollection() ) { | 3916 | if ( !hasdoc || document()->useFormatCollection() ) { |
3894 | s->str->at( i ).format()->addRef(); | 3917 | s->str->at( i ).format()->addRef(); |
3895 | str->setFormat( i + start, s->str->at( i ).format(), TRUE ); | 3918 | str->setFormat( i + start, s->str->at( i ).format(), TRUE ); |
3896 | } | 3919 | } |
3897 | if ( s->str->at( i ).isCustom() ) { | 3920 | if ( s->str->at( i ).isCustom() ) { |
3898 | QTextCustomItem * item = s->str->at( i ).customItem(); | 3921 | QTextCustomItem * item = s->str->at( i ).customItem(); |
3899 | str->at( i + start ).setCustomItem( item ); | 3922 | str->at( i + start ).setCustomItem( item ); |
3900 | s->str->at( i ).loseCustomItem(); | 3923 | s->str->at( i ).loseCustomItem(); |
3901 | if ( hasdoc ) { | 3924 | if ( hasdoc ) { |
3902 | document()->unregisterCustomItem( item, s ); | 3925 | document()->unregisterCustomItem( item, s ); |
3903 | document()->registerCustomItem( item, this ); | 3926 | document()->registerCustomItem( item, this ); |
3904 | } | 3927 | } |
3905 | } | 3928 | } |
3906 | if ( s->str->at( i ).isAnchor() ) { | 3929 | if ( s->str->at( i ).isAnchor() ) { |
3907 | str->at( i + start ).setAnchor( s->str->at( i ).anchorName(), | 3930 | str->at( i + start ).setAnchor( s->str->at( i ).anchorName(), |
3908 | s->str->at( i ).anchorHref() ); | 3931 | s->str->at( i ).anchorHref() ); |
3909 | } | 3932 | } |
3910 | } | 3933 | } |
3911 | 3934 | ||
3912 | if ( !extraData() && s->extraData() ) { | 3935 | if ( !extraData() && s->extraData() ) { |
3913 | setExtraData( s->extraData() ); | 3936 | setExtraData( s->extraData() ); |
3914 | s->setExtraData( 0 ); | 3937 | s->setExtraData( 0 ); |
3915 | } else if ( extraData() && s->extraData() ) { | 3938 | } else if ( extraData() && s->extraData() ) { |
3916 | extraData()->join( s->extraData() ); | 3939 | extraData()->join( s->extraData() ); |
3917 | } | 3940 | } |
3918 | delete s; | 3941 | delete s; |
3919 | invalidate( 0 ); | 3942 | invalidate( 0 ); |
3920 | r.setHeight( oh ); | 3943 | r.setHeight( oh ); |
3921 | needPreProcess = TRUE; | 3944 | needPreProcess = TRUE; |
3922 | if ( n ) { | 3945 | if ( n ) { |
3923 | QTextParagraph *s = n; | 3946 | QTextParagraph *s = n; |
3924 | s->invalidate( 0 ); | 3947 | s->invalidate( 0 ); |
3925 | while ( s ) { | 3948 | while ( s ) { |
3926 | s->id = s->p->id + 1; | 3949 | s->id = s->p->id + 1; |
3927 | s->state = -1; | 3950 | s->state = -1; |
3928 | s->needPreProcess = TRUE; | 3951 | s->needPreProcess = TRUE; |
3929 | s->changed = TRUE; | 3952 | s->changed = TRUE; |
3930 | s->invalidateStyleCache(); | 3953 | s->invalidateStyleCache(); |
3931 | s = s->n; | 3954 | s = s->n; |
3932 | } | 3955 | } |
3933 | } | 3956 | } |
3934 | format(); | 3957 | format(); |
3935 | state = -1; | 3958 | state = -1; |
3936 | } | 3959 | } |
3937 | 3960 | ||
3938 | void QTextParagraph::move( int &dy ) | 3961 | void QTextParagraph::move( int &dy ) |
3939 | { | 3962 | { |
3940 | if ( dy == 0 ) | 3963 | if ( dy == 0 ) |
3941 | return; | 3964 | return; |
3942 | changed = TRUE; | 3965 | changed = TRUE; |
3943 | r.moveBy( 0, dy ); | 3966 | r.moveBy( 0, dy ); |
3944 | if ( mFloatingItems ) { | 3967 | if ( mFloatingItems ) { |
3945 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) | 3968 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) |
3946 | i->ypos += dy; | 3969 | i->ypos += dy; |
3947 | } | 3970 | } |
3948 | if ( p ) | 3971 | if ( p ) |
3949 | p->lastInFrame = TRUE; | 3972 | p->lastInFrame = TRUE; |
3950 | 3973 | ||
3951 | // do page breaks if required | 3974 | // do page breaks if required |
3952 | if ( hasdoc && document()->isPageBreakEnabled() ) { | 3975 | if ( hasdoc && document()->isPageBreakEnabled() ) { |
3953 | int shift; | 3976 | int shift; |
3954 | if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) { | 3977 | if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) { |
3955 | if ( p ) | 3978 | if ( p ) |
3956 | p->setChanged( TRUE ); | 3979 | p->setChanged( TRUE ); |
3957 | dy += shift; | 3980 | dy += shift; |
3958 | } | 3981 | } |
3959 | } | 3982 | } |
3960 | } | 3983 | } |
3961 | 3984 | ||
3962 | void QTextParagraph::format( int start, bool doMove ) | 3985 | void QTextParagraph::format( int start, bool doMove ) |
3963 | { | 3986 | { |
3964 | if ( !str || str->length() == 0 || !formatter() ) | 3987 | if ( !str || str->length() == 0 || !formatter() ) |
3965 | return; | 3988 | return; |
3966 | 3989 | ||
3967 | if ( hasdoc && | 3990 | if ( hasdoc && |
3968 | document()->preProcessor() && | 3991 | document()->preProcessor() && |
3969 | ( needPreProcess || state == -1 ) ) | 3992 | ( needPreProcess || state == -1 ) ) |
3970 | document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid ); | 3993 | document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid ); |
3971 | needPreProcess = FALSE; | 3994 | needPreProcess = FALSE; |
3972 | 3995 | ||
3973 | if ( invalid == -1 ) | 3996 | if ( invalid == -1 ) |
3974 | return; | 3997 | return; |
3975 | 3998 | ||
3976 | r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) ); | 3999 | r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) ); |
3977 | if ( p ) | 4000 | if ( p ) |
3978 | p->lastInFrame = FALSE; | 4001 | p->lastInFrame = FALSE; |
3979 | 4002 | ||
3980 | movedDown = FALSE; | 4003 | movedDown = FALSE; |
3981 | bool formattedAgain = FALSE; | 4004 | bool formattedAgain = FALSE; |
3982 | 4005 | ||
3983 | formatAgain: | 4006 | formatAgain: |
3984 | 4007 | ||
3985 | r.setWidth( documentWidth() ); | 4008 | r.setWidth( documentWidth() ); |
3986 | if ( hasdoc && mFloatingItems ) { | 4009 | if ( hasdoc && mFloatingItems ) { |
3987 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) { | 4010 | for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) { |
3988 | i->ypos = r.y(); | 4011 | i->ypos = r.y(); |
3989 | if ( i->placement() == QTextCustomItem::PlaceRight ) { | 4012 | if ( i->placement() == QTextCustomItem::PlaceRight ) { |
3990 | i->xpos = r.x() + r.width() - i->width; | 4013 | i->xpos = r.x() + r.width() - i->width; |
3991 | } | 4014 | } |
3992 | } | 4015 | } |
3993 | } | 4016 | } |
3994 | QMap<int, QTextLineStart*> oldLineStarts = lineStarts; | 4017 | QMap<int, QTextLineStart*> oldLineStarts = lineStarts; |
3995 | lineStarts.clear(); | 4018 | lineStarts.clear(); |
3996 | int y = formatter()->format( document(), this, start, oldLineStarts ); | 4019 | int y = formatter()->format( document(), this, start, oldLineStarts ); |
3997 | 4020 | ||
3998 | 4021 | ||
3999 | r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) ); | 4022 | r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) ); |
4000 | 4023 | ||
4001 | 4024 | ||
4002 | QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin(); | 4025 | QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin(); |
4003 | 4026 | ||
4004 | for ( ; it != oldLineStarts.end(); ++it ) | 4027 | for ( ; it != oldLineStarts.end(); ++it ) |
4005 | delete *it; | 4028 | delete *it; |
4006 | 4029 | ||
4007 | QTextStringChar *c = 0; | 4030 | QTextStringChar *c = 0; |
4008 | // do not do this on mac, as the paragraph | 4031 | // do not do this on mac, as the paragraph |
4009 | // with has to be the full document width on mac as the selections | 4032 | // with has to be the full document width on mac as the selections |
4010 | // always extend completely to the right. This is a bit unefficient, | 4033 | // always extend completely to the right. This is a bit unefficient, |
4011 | // as this results in a bigger double buffer than needed but ok for | 4034 | // as this results in a bigger double buffer than needed but ok for |
4012 | // now. | 4035 | // now. |
4013 | if ( lineStarts.count() == 1 ) { | 4036 | if ( lineStarts.count() == 1 ) { |
4014 | if ( !string()->isBidi() ) { | 4037 | if ( !string()->isBidi() ) { |
4015 | c = &str->at( str->length() - 1 ); | 4038 | c = &str->at( str->length() - 1 ); |
4016 | r.setWidth( c->x + str->width( str->length() - 1 ) ); | 4039 | r.setWidth( c->x + str->width( str->length() - 1 ) ); |
4017 | } else { | 4040 | } else { |
4018 | r.setWidth( lineStarts[0]->w ); | 4041 | r.setWidth( lineStarts[0]->w ); |
4019 | } | 4042 | } |
4020 | } | 4043 | } |
4021 | 4044 | ||
4022 | if ( !hasdoc ) { // qt_format_text bounding rect handling | 4045 | if ( !hasdoc ) { // qt_format_text bounding rect handling |
4023 | it = lineStarts.begin(); | 4046 | it = lineStarts.begin(); |
4024 | int usedw = 0; | 4047 | int usedw = 0; |
4025 | for ( ; it != lineStarts.end(); ++it ) | 4048 | for ( ; it != lineStarts.end(); ++it ) |
4026 | usedw = QMAX( usedw, (*it)->w ); | 4049 | usedw = QMAX( usedw, (*it)->w ); |
4027 | if ( r.width() <= 0 ) { | 4050 | if ( r.width() <= 0 ) { |
4028 | // if the user specifies an invalid rect, this means that the | 4051 | // if the user specifies an invalid rect, this means that the |
4029 | // bounding box should grow to the width that the text actually | 4052 | // bounding box should grow to the width that the text actually |
4030 | // needs | 4053 | // needs |
4031 | r.setWidth( usedw ); | 4054 | r.setWidth( usedw ); |
4032 | } else { | 4055 | } else { |
4033 | r.setWidth( QMIN( usedw, r.width() ) ); | 4056 | r.setWidth( QMIN( usedw, r.width() ) ); |
4034 | } | 4057 | } |
4035 | } | 4058 | } |
4036 | 4059 | ||
4037 | if ( y != r.height() ) | 4060 | if ( y != r.height() ) |
4038 | r.setHeight( y ); | 4061 | r.setHeight( y ); |
4039 | 4062 | ||
4040 | if ( !visible ) { | 4063 | if ( !visible ) { |
4041 | r.setHeight( 0 ); | 4064 | r.setHeight( 0 ); |
4042 | } else { | 4065 | } else { |
4043 | int minw = formatter()->minimumWidth(); | 4066 | int minw = formatter()->minimumWidth(); |
4044 | int wused = formatter()->widthUsed(); | 4067 | int wused = formatter()->widthUsed(); |
4045 | wused = QMAX( minw, wused ); | 4068 | wused = QMAX( minw, wused ); |
4046 | if ( hasdoc ) { | 4069 | if ( hasdoc ) { |
4047 | document()->setMinimumWidth( minw, wused, this ); | 4070 | document()->setMinimumWidth( minw, wused, this ); |
4048 | } else { | 4071 | } else { |
4049 | pseudoDocument()->minw = QMAX( pseudoDocument()->minw, minw ); | 4072 | pseudoDocument()->minw = QMAX( pseudoDocument()->minw, minw ); |
4050 | pseudoDocument()->wused = QMAX( pseudoDocument()->wused, wused ); | 4073 | pseudoDocument()->wused = QMAX( pseudoDocument()->wused, wused ); |
4051 | } | 4074 | } |
4052 | } | 4075 | } |
4053 | 4076 | ||
4054 | // do page breaks if required | 4077 | // do page breaks if required |
4055 | if ( hasdoc && document()->isPageBreakEnabled() ) { | 4078 | if ( hasdoc && document()->isPageBreakEnabled() ) { |
4056 | int shift = document()->formatter()->formatVertically( document(), this ); | 4079 | int shift = document()->formatter()->formatVertically( document(), this ); |
4057 | if ( shift && !formattedAgain ) { | 4080 | if ( shift && !formattedAgain ) { |
4058 | formattedAgain = TRUE; | 4081 | formattedAgain = TRUE; |
4059 | goto formatAgain; | 4082 | goto formatAgain; |
4060 | } | 4083 | } |
4061 | } | 4084 | } |
4062 | 4085 | ||
4063 | if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) { | 4086 | if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) { |
4064 | int dy = ( r.y() + r.height() ) - n->r.y(); | 4087 | int dy = ( r.y() + r.height() ) - n->r.y(); |
4065 | QTextParagraph *s = n; | 4088 | QTextParagraph *s = n; |
4066 | bool makeInvalid = p && p->lastInFrame; | 4089 | bool makeInvalid = p && p->lastInFrame; |
4067 | while ( s && dy ) { | 4090 | while ( s && dy ) { |
4068 | if ( !s->isFullWidth() ) | 4091 | if ( !s->isFullWidth() ) |
4069 | makeInvalid = TRUE; | 4092 | makeInvalid = TRUE; |
4070 | if ( makeInvalid ) | 4093 | if ( makeInvalid ) |
4071 | s->invalidate( 0 ); | 4094 | s->invalidate( 0 ); |
4072 | s->move( dy ); | 4095 | s->move( dy ); |
4073 | if ( s->lastInFrame ) | 4096 | if ( s->lastInFrame ) |
4074 | makeInvalid = TRUE; | 4097 | makeInvalid = TRUE; |
4075 | s = s->n; | 4098 | s = s->n; |
4076 | } | 4099 | } |
4077 | } | 4100 | } |
4078 | 4101 | ||
4079 | firstFormat = FALSE; | 4102 | firstFormat = FALSE; |
4080 | changed = TRUE; | 4103 | changed = TRUE; |
4081 | invalid = -1; | 4104 | invalid = -1; |
4082 | //##### string()->setTextChanged( FALSE ); | 4105 | //##### string()->setTextChanged( FALSE ); |
4083 | } | 4106 | } |
4084 | 4107 | ||
4085 | int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const | 4108 | int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const |
4086 | { | 4109 | { |
4087 | if ( !isValid() ) | 4110 | if ( !isValid() ) |
4088 | ( (QTextParagraph*)this )->format(); | 4111 | ( (QTextParagraph*)this )->format(); |
4089 | 4112 | ||
4090 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); | 4113 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); |
4091 | --it; | 4114 | --it; |
4092 | for ( ;; ) { | 4115 | for ( ;; ) { |
4093 | if ( i >= it.key() ) { | 4116 | if ( i >= it.key() ) { |
4094 | if ( bl ) | 4117 | if ( bl ) |
4095 | *bl = ( *it )->baseLine; | 4118 | *bl = ( *it )->baseLine; |
4096 | if ( y ) | 4119 | if ( y ) |
4097 | *y = ( *it )->y; | 4120 | *y = ( *it )->y; |
4098 | return ( *it )->h; | 4121 | return ( *it )->h; |
4099 | } | 4122 | } |
4100 | if ( it == lineStarts.begin() ) | 4123 | if ( it == lineStarts.begin() ) |
4101 | break; | 4124 | break; |
4102 | --it; | 4125 | --it; |
4103 | } | 4126 | } |
4104 | 4127 | ||
4105 | owarn << "QTextParagraph::lineHeightOfChar: couldn't find lh for " << i << "" << oendl; | 4128 | owarn << "QTextParagraph::lineHeightOfChar: couldn't find lh for " << i << "" << oendl; |
4106 | return 15; | 4129 | return 15; |
4107 | } | 4130 | } |
4108 | 4131 | ||
4109 | QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const | 4132 | QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const |
4110 | { | 4133 | { |
4111 | if ( !isValid() ) | 4134 | if ( !isValid() ) |
4112 | ( (QTextParagraph*)this )->format(); | 4135 | ( (QTextParagraph*)this )->format(); |
4113 | 4136 | ||
4114 | int l = (int)lineStarts.count() - 1; | 4137 | int l = (int)lineStarts.count() - 1; |
4115 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); | 4138 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); |
4116 | --it; | 4139 | --it; |
4117 | for ( ;; ) { | 4140 | for ( ;; ) { |
4118 | if ( i >= it.key() ) { | 4141 | if ( i >= it.key() ) { |
4119 | if ( index ) | 4142 | if ( index ) |
4120 | *index = it.key(); | 4143 | *index = it.key(); |
4121 | if ( line ) | 4144 | if ( line ) |
4122 | *line = l; | 4145 | *line = l; |
4123 | return &str->at( it.key() ); | 4146 | return &str->at( it.key() ); |
4124 | } | 4147 | } |
4125 | if ( it == lineStarts.begin() ) | 4148 | if ( it == lineStarts.begin() ) |
4126 | break; | 4149 | break; |
4127 | --it; | 4150 | --it; |
4128 | --l; | 4151 | --l; |
4129 | } | 4152 | } |
4130 | 4153 | ||
4131 | owarn << "QTextParagraph::lineStartOfChar: couldn't find " << i << "" << oendl; | 4154 | owarn << "QTextParagraph::lineStartOfChar: couldn't find " << i << "" << oendl; |
4132 | return 0; | 4155 | return 0; |
4133 | } | 4156 | } |
4134 | 4157 | ||
4135 | int QTextParagraph::lines() const | 4158 | int QTextParagraph::lines() const |
4136 | { | 4159 | { |
4137 | if ( !isValid() ) | 4160 | if ( !isValid() ) |
4138 | ( (QTextParagraph*)this )->format(); | 4161 | ( (QTextParagraph*)this )->format(); |
4139 | 4162 | ||
4140 | return (int)lineStarts.count(); | 4163 | return (int)lineStarts.count(); |
4141 | } | 4164 | } |
4142 | 4165 | ||
4143 | QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const | 4166 | QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const |
4144 | { | 4167 | { |
4145 | if ( !isValid() ) | 4168 | if ( !isValid() ) |
4146 | ( (QTextParagraph*)this )->format(); | 4169 | ( (QTextParagraph*)this )->format(); |
4147 | 4170 | ||
4148 | if ( line >= 0 && line < (int)lineStarts.count() ) { | 4171 | if ( line >= 0 && line < (int)lineStarts.count() ) { |
4149 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); | 4172 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); |
4150 | while ( line-- > 0 ) | 4173 | while ( line-- > 0 ) |
4151 | ++it; | 4174 | ++it; |
4152 | int i = it.key(); | 4175 | int i = it.key(); |
4153 | if ( index ) | 4176 | if ( index ) |
4154 | *index = i; | 4177 | *index = i; |
4155 | return &str->at( i ); | 4178 | return &str->at( i ); |
4156 | } | 4179 | } |
4157 | 4180 | ||
4158 | owarn << "QTextParagraph::lineStartOfLine: couldn't find " << line << "" << oendl; | 4181 | owarn << "QTextParagraph::lineStartOfLine: couldn't find " << line << "" << oendl; |
4159 | return 0; | 4182 | return 0; |
4160 | } | 4183 | } |
4161 | 4184 | ||
4162 | int QTextParagraph::leftGap() const | 4185 | int QTextParagraph::leftGap() const |
4163 | { | 4186 | { |
4164 | if ( !isValid() ) | 4187 | if ( !isValid() ) |
4165 | ( (QTextParagraph*)this )->format(); | 4188 | ( (QTextParagraph*)this )->format(); |
4166 | 4189 | ||
4167 | int line = 0; | 4190 | int line = 0; |
4168 | int x = str->at(0).x; /* set x to x of first char */ | 4191 | int x = str->at(0).x; /* set x to x of first char */ |
4169 | if ( str->isBidi() ) { | 4192 | if ( str->isBidi() ) { |
4170 | for ( int i = 1; i < str->length()-1; ++i ) | 4193 | for ( int i = 1; i < str->length()-1; ++i ) |
4171 | x = QMIN(x, str->at(i).x); | 4194 | x = QMIN(x, str->at(i).x); |
4172 | return x; | 4195 | return x; |
4173 | } | 4196 | } |
4174 | 4197 | ||
4175 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); | 4198 | QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); |
4176 | while (line < (int)lineStarts.count()) { | 4199 | while (line < (int)lineStarts.count()) { |
4177 | int i = it.key(); /* char index */ | 4200 | int i = it.key(); /* char index */ |
4178 | x = QMIN(x, str->at(i).x); | 4201 | x = QMIN(x, str->at(i).x); |
4179 | ++it; | 4202 | ++it; |
4180 | ++line; | 4203 | ++line; |
4181 | } | 4204 | } |
4182 | return x; | 4205 | return x; |
4183 | } | 4206 | } |
4184 | 4207 | ||
4185 | void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags ) | 4208 | void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags ) |
4186 | { | 4209 | { |
4187 | if ( !f ) | 4210 | if ( !f ) |
4188 | return; | 4211 | return; |
4189 | if ( index < 0 ) | 4212 | if ( index < 0 ) |
4190 | index = 0; | 4213 | index = 0; |
4191 | if ( index > str->length() - 1 ) | 4214 | if ( index > str->length() - 1 ) |
4192 | index = str->length() - 1; | 4215 | index = str->length() - 1; |
4193 | if ( index + len >= str->length() ) | 4216 | if ( index + len >= str->length() ) |
4194 | len = str->length() - index; | 4217 | len = str->length() - index; |
4195 | 4218 | ||
4196 | QTextFormatCollection *fc = 0; | 4219 | QTextFormatCollection *fc = 0; |
4197 | if ( useCollection ) | 4220 | if ( useCollection ) |
4198 | fc = formatCollection(); | 4221 | fc = formatCollection(); |
4199 | QTextFormat *of; | 4222 | QTextFormat *of; |
4200 | for ( int i = 0; i < len; ++i ) { | 4223 | for ( int i = 0; i < len; ++i ) { |
4201 | of = str->at( i + index ).format(); | 4224 | of = str->at( i + index ).format(); |
4202 | if ( !changed && f->key() != of->key() ) | 4225 | if ( !changed && f->key() != of->key() ) |
4203 | changed = TRUE; | 4226 | changed = TRUE; |
4204 | if ( invalid == -1 && | 4227 | if ( invalid == -1 && |
4205 | ( f->font().family() != of->font().family() || | 4228 | ( f->font().family() != of->font().family() || |
4206 | f->font().pointSize() != of->font().pointSize() || | 4229 | f->font().pointSize() != of->font().pointSize() || |
4207 | f->font().weight() != of->font().weight() || | 4230 | f->font().weight() != of->font().weight() || |
4208 | f->font().italic() != of->font().italic() || | 4231 | f->font().italic() != of->font().italic() || |
4209 | f->vAlign() != of->vAlign() ) ) { | 4232 | f->vAlign() != of->vAlign() ) ) { |
4210 | invalidate( 0 ); | 4233 | invalidate( 0 ); |
4211 | } | 4234 | } |
4212 | if ( flags == -1 || flags == QTextFormat::Format || !fc ) { | 4235 | if ( flags == -1 || flags == QTextFormat::Format || !fc ) { |
4213 | if ( fc ) | 4236 | if ( fc ) |
4214 | f = fc->format( f ); | 4237 | f = fc->format( f ); |
4215 | str->setFormat( i + index, f, useCollection ); | 4238 | str->setFormat( i + index, f, useCollection ); |
4216 | } else { | 4239 | } else { |
4217 | QTextFormat *fm = fc->format( of, f, flags ); | 4240 | QTextFormat *fm = fc->format( of, f, flags ); |
4218 | str->setFormat( i + index, fm, useCollection ); | 4241 | str->setFormat( i + index, fm, useCollection ); |
4219 | } | 4242 | } |
4220 | } | 4243 | } |
4221 | } | 4244 | } |
4222 | 4245 | ||
4223 | void QTextParagraph::indent( int *oldIndent, int *newIndent ) | 4246 | void QTextParagraph::indent( int *oldIndent, int *newIndent ) |
4224 | { | 4247 | { |
4225 | if ( !hasdoc || !document()->indent() || isListItem() ) { | 4248 | if ( !hasdoc || !document()->indent() || isListItem() ) { |
4226 | if ( oldIndent ) | 4249 | if ( oldIndent ) |
4227 | *oldIndent = 0; | 4250 | *oldIndent = 0; |
4228 | if ( newIndent ) | 4251 | if ( newIndent ) |
4229 | *newIndent = 0; | 4252 | *newIndent = 0; |
4230 | if ( oldIndent && newIndent ) | 4253 | if ( oldIndent && newIndent ) |
4231 | *newIndent = *oldIndent; | 4254 | *newIndent = *oldIndent; |
4232 | return; | 4255 | return; |
4233 | } | 4256 | } |
4234 | document()->indent()->indent( document(), this, oldIndent, newIndent ); | 4257 | document()->indent()->indent( document(), this, oldIndent, newIndent ); |
4235 | } | 4258 | } |
4236 | 4259 | ||
4237 | void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections, | 4260 | void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections, |
4238 | int clipx, int clipy, int clipw, int cliph ) | 4261 | int clipx, int clipy, int clipw, int cliph ) |
4239 | { | 4262 | { |
4240 | if ( !visible ) | 4263 | if ( !visible ) |
4241 | return; | 4264 | return; |
4242 | QTextStringChar *chr = 0; | 4265 | QTextStringChar *chr = 0; |
4243 | int i, y, h, baseLine, xstart, xend; | 4266 | int i, y, h, baseLine, xstart, xend; |
4244 | i = y =h = baseLine = 0; | 4267 | i = y =h = baseLine = 0; |
4245 | QRect cursorRect; | 4268 | QRect cursorRect; |
4246 | drawSelections &= ( mSelections != 0 ); | 4269 | drawSelections &= ( mSelections != 0 ); |
4247 | // macintosh full-width selection style | 4270 | // macintosh full-width selection style |
4248 | bool fullWidthStyle = FALSE; | 4271 | bool fullWidthStyle = FALSE; |
4249 | int fullSelectionWidth = 0; | 4272 | int fullSelectionWidth = 0; |
4250 | if ( drawSelections && fullWidthStyle ) | 4273 | if ( drawSelections && fullWidthStyle ) |
4251 | fullSelectionWidth = (hasdoc ? document()->width() : r.width()); | 4274 | fullSelectionWidth = (hasdoc ? document()->width() : r.width()); |
4252 | 4275 | ||
4253 | QString qstr = str->toString(); | 4276 | QString qstr = str->toString(); |
4254 | // ### workaround so that \n are not drawn, actually this should | 4277 | // ### workaround so that \n are not drawn, actually this should |
4255 | // be fixed in QFont somewhere (under Windows you get ugly boxes | 4278 | // be fixed in QFont somewhere (under Windows you get ugly boxes |
4256 | // otherwise) | 4279 | // otherwise) |
4257 | QChar* uc = (QChar*) qstr.unicode(); | 4280 | QChar* uc = (QChar*) qstr.unicode(); |
4258 | for ( uint ii = 0; ii < qstr.length(); ii++ ) | 4281 | for ( uint ii = 0; ii < qstr.length(); ii++ ) |
4259 | if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' ) | 4282 | if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' ) |
4260 | uc[(int)ii] = 0x20; | 4283 | uc[(int)ii] = 0x20; |
4261 | 4284 | ||
4262 | int line = -1; | 4285 | int line = -1; |
4263 | int paintStart = 0; | 4286 | int paintStart = 0; |
4264 | int selection = -1; | 4287 | int selection = -1; |
4265 | for ( i = 0; i < length(); i++ ) { | 4288 | for ( i = 0; i < length(); i++ ) { |
4266 | chr = at( i ); | 4289 | chr = at( i ); |
4267 | 4290 | ||
4268 | // we flush at end of document | 4291 | // we flush at end of document |
4269 | bool flush = i== length()-1; | 4292 | bool flush = i== length()-1; |
4270 | bool selectionStateChanged = FALSE; | 4293 | bool selectionStateChanged = FALSE; |
4271 | if ( !flush ) { | 4294 | if ( !flush ) { |
4272 | QTextStringChar *nextchr = at( i+1 ); | 4295 | QTextStringChar *nextchr = at( i+1 ); |
4273 | // we flush at end of line | 4296 | // we flush at end of line |
4274 | flush |= nextchr->lineStart; | 4297 | flush |= nextchr->lineStart; |
4275 | // we flush on format changes | 4298 | // we flush on format changes |
4276 | flush |= ( nextchr->format() != chr->format() ); | 4299 | flush |= ( nextchr->format() != chr->format() ); |
4277 | // we flush on anchor changes | 4300 | // we flush on anchor changes |
4278 | flush |= ( nextchr->isAnchor() != chr->isAnchor() ); | 4301 | flush |= ( nextchr->isAnchor() != chr->isAnchor() ); |
4279 | // we flush on start of run | 4302 | // we flush on start of run |
4280 | flush |= nextchr->startOfRun; | 4303 | flush |= nextchr->startOfRun; |
4281 | // we flush on bidi changes | 4304 | // we flush on bidi changes |
4282 | flush |= ( nextchr->rightToLeft != chr->rightToLeft ); | 4305 | flush |= ( nextchr->rightToLeft != chr->rightToLeft ); |
4283 | // we flush on tab | 4306 | // we flush on tab |
4284 | flush |= ( chr->c == '\t' ); | 4307 | flush |= ( chr->c == '\t' ); |
4285 | // we flush on soft hypens | 4308 | // we flush on soft hypens |
4286 | flush |= ( chr->c.unicode() == 0xad ); | 4309 | flush |= ( chr->c.unicode() == 0xad ); |
4287 | // we flush on custom items | 4310 | // we flush on custom items |
4288 | flush |= chr->isCustom(); | 4311 | flush |= chr->isCustom(); |
4289 | // we flush before custom items | 4312 | // we flush before custom items |
4290 | flush |= nextchr->isCustom(); | 4313 | flush |= nextchr->isCustom(); |
4291 | // when painting justified, we flush on spaces | 4314 | // when painting justified, we flush on spaces |
4292 | if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify ) | 4315 | if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify ) |
4293 | flush |= QTextFormatter::isBreakable( str, i ); | 4316 | flush |= QTextFormatter::isBreakable( str, i ); |
4294 | // we flush when the string is getting too long | 4317 | // we flush when the string is getting too long |
4295 | flush |= ( i - paintStart >= 256 ); | 4318 | flush |= ( i - paintStart >= 256 ); |
4296 | // we flush when the selection state changes | 4319 | // we flush when the selection state changes |
4297 | if ( drawSelections ) { | 4320 | if ( drawSelections ) { |
4298 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); | 4321 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); |
4299 | it != mSelections->end(); ++it ) | 4322 | it != mSelections->end(); ++it ) |
4300 | selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 ); | 4323 | selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 ); |
4301 | flush |= selectionStateChanged; | 4324 | flush |= selectionStateChanged; |
4302 | } | 4325 | } |
4303 | } | 4326 | } |
4304 | 4327 | ||
4305 | // init a new line | 4328 | // init a new line |
4306 | if ( chr->lineStart ) { | 4329 | if ( chr->lineStart ) { |
4307 | if (fullWidthStyle && drawSelections && selection >= 0) | 4330 | if (fullWidthStyle && drawSelections && selection >= 0) |
4308 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, | 4331 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, |
4309 | (selection == QTextDocument::Standard || !hasdoc) ? | 4332 | (selection == QTextDocument::Standard || !hasdoc) ? |
4310 | cg.color( QColorGroup::Highlight ) : | 4333 | cg.color( QColorGroup::Highlight ) : |
4311 | document()->selectionColor( selection ) ); | 4334 | document()->selectionColor( selection ) ); |
4312 | ++line; | 4335 | ++line; |
4313 | paintStart = i; | 4336 | paintStart = i; |
4314 | lineInfo( line, y, h, baseLine ); | 4337 | lineInfo( line, y, h, baseLine ); |
4315 | if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave | 4338 | if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave |
4316 | break; | 4339 | break; |
4317 | } | 4340 | } |
4318 | 4341 | ||
4319 | // if this is the first line and we are a list item, draw the the bullet label | 4342 | // if this is the first line and we are a list item, draw the the bullet label |
4320 | if ( line == 0 && isListItem() ) | 4343 | if ( line == 0 && isListItem() ) |
4321 | drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg ); | 4344 | drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg ); |
4322 | } | 4345 | } |
4323 | 4346 | ||
4324 | // check for cursor mark | 4347 | // check for cursor mark |
4325 | if ( cursor && this == cursor->paragraph() && i == cursor->index() ) { | 4348 | if ( cursor && this == cursor->paragraph() && i == cursor->index() ) { |
4326 | QTextStringChar *c = i == 0 ? chr : chr - 1; | 4349 | QTextStringChar *c = i == 0 ? chr : chr - 1; |
4327 | cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(), | 4350 | cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(), |
4328 | 1, c->format()->height() ); | 4351 | 1, c->format()->height() ); |
4329 | } | 4352 | } |
4330 | 4353 | ||
4331 | // check if we are in a selection and store which one it is | 4354 | // check if we are in a selection and store which one it is |
4332 | selection = -1; | 4355 | selection = -1; |
4333 | if ( drawSelections ) { | 4356 | if ( drawSelections ) { |
4334 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); | 4357 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); |
4335 | it != mSelections->end(); ++it ) | 4358 | it != mSelections->end(); ++it ) |
4336 | if ( (*it).start <= i && i < (*it).end + ( (*it).end == length()-1 && n && n->hasSelection(it.key()) ) ? 1:0 | 4359 | if ( (*it).start <= i && i < (*it).end + ( (*it).end == length()-1 && n && n->hasSelection(it.key()) ) ? 1:0 |
4337 | // exclude the standard selection from printing | 4360 | // exclude the standard selection from printing |
4338 | && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) { | 4361 | && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) { |
4339 | selection = it.key(); | 4362 | selection = it.key(); |
4340 | break; | 4363 | break; |
4341 | } | 4364 | } |
4342 | } | 4365 | } |
4343 | 4366 | ||
4344 | if ( flush ) { // something changed, draw what we have so far | 4367 | if ( flush ) { // something changed, draw what we have so far |
4345 | if ( chr->rightToLeft ) { | 4368 | if ( chr->rightToLeft ) { |
4346 | xstart = chr->x; | 4369 | xstart = chr->x; |
4347 | xend = at( paintStart )->x + str->width( paintStart ); | 4370 | xend = at( paintStart )->x + str->width( paintStart ); |
4348 | } else { | 4371 | } else { |
4349 | xstart = at( paintStart )->x; | 4372 | xstart = at( paintStart )->x; |
4350 | if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart ) | 4373 | if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart ) |
4351 | xend = str->at( i + 1 ).x; | 4374 | xend = str->at( i + 1 ).x; |
4352 | else | 4375 | else |
4353 | xend = chr->x + str->width( i ); | 4376 | xend = chr->x + str->width( i ); |
4354 | } | 4377 | } |
4355 | 4378 | ||
4356 | if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) { | 4379 | if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) { |
4357 | if ( !chr->isCustom() ) | 4380 | if ( !chr->isCustom() ) |
4358 | drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y, | 4381 | drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y, |
4359 | baseLine, xend-xstart, h, selection, | 4382 | baseLine, xend-xstart, h, selection, |
4360 | chr, cg, chr->rightToLeft ); | 4383 | chr, cg, chr->rightToLeft ); |
4361 | else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline ) | 4384 | else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline ) |
4362 | chr->customItem()->draw( &painter, chr->x, y, | 4385 | chr->customItem()->draw( &painter, chr->x, y, |
4363 | clipx == -1 ? clipx : (clipx - r.x()), | 4386 | clipx == -1 ? clipx : (clipx - r.x()), |
4364 | clipy == -1 ? clipy : (clipy - r.y()), | 4387 | clipy == -1 ? clipy : (clipy - r.y()), |
4365 | clipw, cliph, cg, selection >= 0 ); | 4388 | clipw, cliph, cg, selection >= 0 ); |
4366 | } | 4389 | } |
4367 | paintStart = i+1; | 4390 | paintStart = i+1; |
4368 | } | 4391 | } |
4369 | 4392 | ||
4370 | } | 4393 | } |
4371 | 4394 | ||
4372 | if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections) | 4395 | if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections) |
4373 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin(); | 4396 | for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin(); |
4374 | it != next()->mSelections->end(); ++it ) | 4397 | it != next()->mSelections->end(); ++it ) |
4375 | if (((*it).start) == 0) { | 4398 | if (((*it).start) == 0) { |
4376 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, | 4399 | painter.fillRect( xend, y, fullSelectionWidth - xend, h, |
4377 | (selection == QTextDocument::Standard || !hasdoc) ? | 4400 | (selection == QTextDocument::Standard || !hasdoc) ? |
4378 | cg.color( QColorGroup::Highlight ) : | 4401 | cg.color( QColorGroup::Highlight ) : |
4379 | document()->selectionColor( selection ) ); | 4402 | document()->selectionColor( selection ) ); |
4380 | break; | 4403 | break; |
4381 | } | 4404 | } |
4382 | 4405 | ||
4383 | // time to draw the cursor | 4406 | // time to draw the cursor |
4384 | const int cursor_extent = 4; | 4407 | const int cursor_extent = 4; |
4385 | if ( !cursorRect.isNull() && cursor && | 4408 | if ( !cursorRect.isNull() && cursor && |
4386 | ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) { | 4409 | ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) { |
4387 | painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) ); | 4410 | painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) ); |
4388 | painter.save(); | 4411 | painter.save(); |
4389 | if ( string()->isBidi() ) { | 4412 | if ( string()->isBidi() ) { |
4390 | if ( at( cursor->index() )->rightToLeft ) { | 4413 | if ( at( cursor->index() )->rightToLeft ) { |
4391 | painter.setPen( Qt::black ); | 4414 | painter.setPen( Qt::black ); |
4392 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4415 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4393 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4416 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4394 | } else { | 4417 | } else { |
4395 | painter.setPen( Qt::black ); | 4418 | painter.setPen( Qt::black ); |
4396 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4419 | painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4397 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); | 4420 | painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); |
4398 | } | 4421 | } |
4399 | } | 4422 | } |
4400 | painter.restore(); | 4423 | painter.restore(); |
4401 | } | 4424 | } |
4402 | } | 4425 | } |
4403 | 4426 | ||
4404 | //#define BIDI_DEBUG | 4427 | //#define BIDI_DEBUG |
4405 | 4428 | ||
4406 | void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart, | 4429 | void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart, |
4407 | int y, int baseLine, int w, int h, int selection, | 4430 | int y, int baseLine, int w, int h, int selection, |
4408 | QTextStringChar *formatChar, const QColorGroup& cg, | 4431 | QTextStringChar *formatChar, const QColorGroup& cg, |
4409 | bool rightToLeft ) | 4432 | bool rightToLeft ) |
4410 | { | 4433 | { |
4411 | int i = start + len - 1; | 4434 | int i = start + len - 1; |
4412 | bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE; | 4435 | bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE; |
4413 | QTextFormat* format = formatChar->format(); | 4436 | QTextFormat* format = formatChar->format(); |
4414 | QString str( s ); | 4437 | QString str( s ); |
4415 | if ( str[ (int)str.length() - 1 ].unicode() == 0xad ) | 4438 | if ( str[ (int)str.length() - 1 ].unicode() == 0xad ) |
4416 | str.remove( str.length() - 1, 1 ); | 4439 | str.remove( str.length() - 1, 1 ); |
4417 | if ( !plainText || hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color() ) | 4440 | if ( !plainText || hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color() ) |
4418 | painter.setPen( QPen( format->color() ) ); | 4441 | painter.setPen( QPen( format->color() ) ); |
4419 | else | 4442 | else |
4420 | painter.setPen( cg.text() ); | 4443 | painter.setPen( cg.text() ); |
4421 | painter.setFont( format->font() ); | 4444 | painter.setFont( format->font() ); |
4422 | 4445 | ||
4423 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) { | 4446 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) { |
4424 | if ( format->useLinkColor() ) { | 4447 | if ( format->useLinkColor() ) { |
4425 | if ( document()->linkColor.isValid() ) | 4448 | if ( document()->linkColor.isValid() ) |
4426 | painter.setPen( document()->linkColor ); | 4449 | painter.setPen( document()->linkColor ); |
4427 | else | 4450 | else |
4428 | painter.setPen( QPen( Qt::blue ) ); | 4451 | painter.setPen( QPen( Qt::blue ) ); |
4429 | } | 4452 | } |
4430 | if ( document()->underlineLinks() ) { | 4453 | if ( document()->underlineLinks() ) { |
4431 | QFont fn = format->font(); | 4454 | QFont fn = format->font(); |
4432 | fn.setUnderline( TRUE ); | 4455 | fn.setUnderline( TRUE ); |
4433 | painter.setFont( fn ); | 4456 | painter.setFont( fn ); |
4434 | } | 4457 | } |
4435 | } | 4458 | } |
4436 | 4459 | ||
4437 | if ( selection >= 0 ) { | 4460 | if ( selection >= 0 ) { |
4438 | if ( !hasdoc || document()->invertSelectionText( selection ) ) | 4461 | if ( !hasdoc || document()->invertSelectionText( selection ) ) |
4439 | painter.setPen( cg.color( QColorGroup::HighlightedText ) ); | 4462 | painter.setPen( cg.color( QColorGroup::HighlightedText ) ); |
4440 | painter.fillRect( xstart, y, w, h, | 4463 | painter.fillRect( xstart, y, w, h, |
4441 | (selection == QTextDocument::Standard || !hasdoc) ? | 4464 | (selection == QTextDocument::Standard || !hasdoc) ? |
4442 | cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) ); | 4465 | cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) ); |
4443 | } | 4466 | } |
4444 | 4467 | ||
4445 | if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) { | 4468 | if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) { |
4446 | if ( format->vAlign() == QTextFormat::AlignNormal ) { | 4469 | if ( format->vAlign() == QTextFormat::AlignNormal ) { |
4447 | painter.drawText( xstart, y + baseLine, str.mid( start ), len ); | 4470 | painter.drawText( xstart, y + baseLine, str.mid( start ), len ); |
4448 | #ifdef BIDI_DEBUG | 4471 | #ifdef BIDI_DEBUG |
4449 | painter.save(); | 4472 | painter.save(); |
4450 | painter.setPen ( Qt::red ); | 4473 | painter.setPen ( Qt::red ); |
4451 | painter.drawLine( xstart, y, xstart, y + baseLine ); | 4474 | painter.drawLine( xstart, y, xstart, y + baseLine ); |
4452 | painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 ); | 4475 | painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 ); |
4453 | int w = 0; | 4476 | int w = 0; |
4454 | int i = 0; | 4477 | int i = 0; |
4455 | while( i < len ) | 4478 | while( i < len ) |
4456 | w += painter.fontMetrics().charWidth( str, start + i++ ); | 4479 | w += painter.fontMetrics().charWidth( str, start + i++ ); |
4457 | painter.setPen ( Qt::blue ); | 4480 | painter.setPen ( Qt::blue ); |
4458 | painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine ); | 4481 | painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine ); |
4459 | painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 ); | 4482 | painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 ); |
4460 | painter.restore(); | 4483 | painter.restore(); |
4461 | #endif | 4484 | #endif |
4462 | } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) { | 4485 | } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) { |
4463 | QFont f( painter.font() ); | 4486 | QFont f( painter.font() ); |
4464 | if ( format->fontSizesInPixels() ) | 4487 | if ( format->fontSizesInPixels() ) |
4465 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 4488 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
4466 | else | 4489 | else |
4467 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 4490 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
4468 | painter.setFont( f ); | 4491 | painter.setFont( f ); |
4469 | painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ), | 4492 | painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ), |
4470 | str.mid( start ), len ); | 4493 | str.mid( start ), len ); |
4471 | } else if ( format->vAlign() == QTextFormat::AlignSubScript ) { | 4494 | } else if ( format->vAlign() == QTextFormat::AlignSubScript ) { |
4472 | QFont f( painter.font() ); | 4495 | QFont f( painter.font() ); |
4473 | if ( format->fontSizesInPixels() ) | 4496 | if ( format->fontSizesInPixels() ) |
4474 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); | 4497 | f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); |
4475 | else | 4498 | else |
4476 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); | 4499 | f.setPointSize( ( f.pointSize() * 2 ) / 3 ); |
4477 | painter.setFont( f ); | 4500 | painter.setFont( f ); |
4478 | painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len ); | 4501 | painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len ); |
4479 | } | 4502 | } |
4480 | } | 4503 | } |
4481 | if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) { | 4504 | if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) { |
4482 | painter.drawText( xstart + w, y + baseLine, "\xad" ); | 4505 | painter.drawText( xstart + w, y + baseLine, "\xad" ); |
4483 | } | 4506 | } |
4484 | if ( format->isMisspelled() ) { | 4507 | if ( format->isMisspelled() ) { |
4485 | painter.save(); | 4508 | painter.save(); |
4486 | painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) ); | 4509 | painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) ); |
4487 | painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 ); | 4510 | painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 ); |
4488 | painter.restore(); | 4511 | painter.restore(); |
4489 | } | 4512 | } |
4490 | 4513 | ||
4491 | i -= len; | 4514 | i -= len; |
4492 | 4515 | ||
4493 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() && | 4516 | if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() && |
4494 | document()->focusIndicator.parag == this && | 4517 | document()->focusIndicator.parag == this && |
4495 | ( document()->focusIndicator.start >= i && | 4518 | ( document()->focusIndicator.start >= i && |
4496 | document()->focusIndicator.start + document()->focusIndicator.len <= i + len || | 4519 | document()->focusIndicator.start + document()->focusIndicator.len <= i + len || |
4497 | document()->focusIndicator.start <= i && | 4520 | document()->focusIndicator.start <= i && |
4498 | document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) { | 4521 | document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) { |
4499 | painter.drawWinFocusRect( QRect( xstart, y, w, h ) ); | 4522 | painter.drawWinFocusRect( QRect( xstart, y, w, h ) ); |
4500 | } | 4523 | } |
4501 | 4524 | ||
4502 | } | 4525 | } |
4503 | 4526 | ||
4504 | void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ) | 4527 | void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ) |
4505 | { | 4528 | { |
4506 | QRect r ( x, y, w, h ); | 4529 | QRect r ( x, y, w, h ); |
4507 | QStyleSheetItem::ListStyle s = listStyle(); | 4530 | QStyleSheetItem::ListStyle s = listStyle(); |
4508 | 4531 | ||
4509 | p->save(); | 4532 | p->save(); |
4510 | QTextFormat *format = at( 0 )->format(); | 4533 | QTextFormat *format = at( 0 )->format(); |
4511 | if ( format ) { | 4534 | if ( format ) { |
4512 | p->setPen( format->color() ); | 4535 | p->setPen( format->color() ); |
4513 | p->setFont( format->font() ); | 4536 | p->setFont( format->font() ); |
4514 | } | 4537 | } |
4515 | QFontMetrics fm( p->fontMetrics() ); | 4538 | QFontMetrics fm( p->fontMetrics() ); |
4516 | int size = fm.lineSpacing() / 3; | 4539 | int size = fm.lineSpacing() / 3; |
4517 | 4540 | ||
4518 | switch ( s ) { | 4541 | switch ( s ) { |
4519 | case QStyleSheetItem::ListDecimal: | 4542 | case QStyleSheetItem::ListDecimal: |
4520 | case QStyleSheetItem::ListLowerAlpha: | 4543 | case QStyleSheetItem::ListLowerAlpha: |
4521 | case QStyleSheetItem::ListUpperAlpha: | 4544 | case QStyleSheetItem::ListUpperAlpha: |
4522 | { | 4545 | { |
4523 | if ( list_val == -1 ) { // uninitialised list value, calcluate the right one | 4546 | if ( list_val == -1 ) { // uninitialised list value, calcluate the right one |
4524 | int depth = listDepth(); | 4547 | int depth = listDepth(); |
4525 | list_val--; | 4548 | list_val--; |
4526 | // ### evil, square and expensive. This needs to be done when formatting, not when painting | 4549 | // ### evil, square and expensive. This needs to be done when formatting, not when painting |
4527 | QTextParagraph* s = prev(); | 4550 | QTextParagraph* s = prev(); |
4528 | int depth_s; | 4551 | int depth_s; |
4529 | while ( s && (depth_s = s->listDepth()) >= depth ) { | 4552 | while ( s && (depth_s = s->listDepth()) >= depth ) { |
4530 | if ( depth_s == depth && s->isListItem() ) | 4553 | if ( depth_s == depth && s->isListItem() ) |
4531 | list_val--; | 4554 | list_val--; |
4532 | s = s->prev(); | 4555 | s = s->prev(); |
4533 | } | 4556 | } |
4534 | } | 4557 | } |
4535 | 4558 | ||
4536 | int n = list_val; | 4559 | int n = list_val; |
4537 | if ( n < -1 ) | 4560 | if ( n < -1 ) |
4538 | n = -n - 1; | 4561 | n = -n - 1; |
4539 | QString l; | 4562 | QString l; |
4540 | switch ( s ) { | 4563 | switch ( s ) { |
4541 | case QStyleSheetItem::ListLowerAlpha: | 4564 | case QStyleSheetItem::ListLowerAlpha: |
4542 | if ( n < 27 ) { | 4565 | if ( n < 27 ) { |
4543 | l = QChar( ('a' + (char) (n-1))); | 4566 | l = QChar( ('a' + (char) (n-1))); |
4544 | break; | 4567 | break; |
4545 | } | 4568 | } |
4546 | case QStyleSheetItem::ListUpperAlpha: | 4569 | case QStyleSheetItem::ListUpperAlpha: |
4547 | if ( n < 27 ) { | 4570 | if ( n < 27 ) { |
4548 | l = QChar( ('A' + (char) (n-1))); | 4571 | l = QChar( ('A' + (char) (n-1))); |
4549 | break; | 4572 | break; |
4550 | } | 4573 | } |
4551 | break; | 4574 | break; |
4552 | default: //QStyleSheetItem::ListDecimal: | 4575 | default: //QStyleSheetItem::ListDecimal: |
4553 | l.setNum( n ); | 4576 | l.setNum( n ); |
4554 | break; | 4577 | break; |
4555 | } | 4578 | } |
4556 | l += QString::fromLatin1(". "); | 4579 | l += QString::fromLatin1(". "); |
4557 | p->drawText( r.right() - fm.width( l ), r.top() + base, l ); | 4580 | p->drawText( r.right() - fm.width( l ), r.top() + base, l ); |
4558 | } | 4581 | } |
4559 | break; | 4582 | break; |
4560 | case QStyleSheetItem::ListSquare: | 4583 | case QStyleSheetItem::ListSquare: |
4561 | { | 4584 | { |
4562 | QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size ); | 4585 | QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size ); |
4563 | p->fillRect( er , cg.brush( QColorGroup::Text ) ); | 4586 | p->fillRect( er , cg.brush( QColorGroup::Text ) ); |
4564 | } | 4587 | } |
4565 | break; | 4588 | break; |
4566 | case QStyleSheetItem::ListCircle: | 4589 | case QStyleSheetItem::ListCircle: |
4567 | { | 4590 | { |
4568 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); | 4591 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); |
4569 | p->drawEllipse( er ); | 4592 | p->drawEllipse( er ); |
4570 | } | 4593 | } |
4571 | break; | 4594 | break; |
4572 | case QStyleSheetItem::ListDisc: | 4595 | case QStyleSheetItem::ListDisc: |
4573 | default: | 4596 | default: |
4574 | { | 4597 | { |
4575 | p->setBrush( cg.brush( QColorGroup::Text )); | 4598 | p->setBrush( cg.brush( QColorGroup::Text )); |
4576 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); | 4599 | QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); |
4577 | p->drawEllipse( er ); | 4600 | p->drawEllipse( er ); |
4578 | p->setBrush( Qt::NoBrush ); | 4601 | p->setBrush( Qt::NoBrush ); |
4579 | } | 4602 | } |
4580 | break; | 4603 | break; |
4581 | } | 4604 | } |
4582 | 4605 | ||
4583 | p->restore(); | 4606 | p->restore(); |
4584 | } | 4607 | } |
4585 | 4608 | ||
4586 | void QTextParagraph::readStyleInformation( QDataStream& stream ) | 4609 | void QTextParagraph::readStyleInformation( QDataStream& stream ) |
4587 | { | 4610 | { |
4588 | int int_align, int_lstyle; | 4611 | int int_align, int_lstyle; |
4589 | uchar uchar_litem, uchar_rtext, uchar_dir; | 4612 | uchar uchar_litem, uchar_rtext, uchar_dir; |
4590 | stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm | 4613 | stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm |
4591 | >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir; | 4614 | >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir; |
4592 | align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle; | 4615 | align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle; |
4593 | litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir ); | 4616 | litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir ); |
4594 | QTextParagraph* s = prev() ? prev() : this; | 4617 | QTextParagraph* s = prev() ? prev() : this; |
4595 | while ( s ) { | 4618 | while ( s ) { |
4596 | s->invalidate( 0 ); | 4619 | s->invalidate( 0 ); |
4597 | s = s->next(); | 4620 | s = s->next(); |
4598 | } | 4621 | } |
4599 | } | 4622 | } |
4600 | 4623 | ||
4601 | void QTextParagraph::writeStyleInformation( QDataStream& stream ) const | 4624 | void QTextParagraph::writeStyleInformation( QDataStream& stream ) const |
4602 | { | 4625 | { |
4603 | stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction(); | 4626 | stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction(); |
4604 | } | 4627 | } |
4605 | 4628 | ||
4606 | 4629 | ||
4607 | 4630 | ||
4608 | void QTextParagraph::setListDepth( int depth ) { | 4631 | void QTextParagraph::setListDepth( int depth ) { |
4609 | if ( !hasdoc || depth == ldepth ) | 4632 | if ( !hasdoc || depth == ldepth ) |
4610 | return; | 4633 | return; |
4611 | ldepth = depth; | 4634 | ldepth = depth; |
4612 | QTextParagraph* s = prev() ? prev() : this; | 4635 | QTextParagraph* s = prev() ? prev() : this; |
4613 | while ( s ) { | 4636 | while ( s ) { |
4614 | s->invalidate( 0 ); | 4637 | s->invalidate( 0 ); |
4615 | s = s->next(); | 4638 | s = s->next(); |
4616 | } | 4639 | } |
4617 | } | 4640 | } |
4618 | 4641 | ||
4619 | int *QTextParagraph::tabArray() const | 4642 | int *QTextParagraph::tabArray() const |
4620 | { | 4643 | { |
4621 | int *ta = tArray; | 4644 | int *ta = tArray; |
4622 | if ( !ta && hasdoc ) | 4645 | if ( !ta && hasdoc ) |
4623 | ta = document()->tabArray(); | 4646 | ta = document()->tabArray(); |
4624 | return ta; | 4647 | return ta; |
4625 | } | 4648 | } |
4626 | 4649 | ||
4627 | int QTextParagraph::nextTab( int, int x ) | 4650 | int QTextParagraph::nextTab( int, int x ) |
4628 | { | 4651 | { |
4629 | int *ta = tArray; | 4652 | int *ta = tArray; |
4630 | if ( hasdoc ) { | 4653 | if ( hasdoc ) { |
4631 | if ( !ta ) | 4654 | if ( !ta ) |
4632 | ta = document()->tabArray(); | 4655 | ta = document()->tabArray(); |
4633 | tabStopWidth = document()->tabStopWidth(); | 4656 | tabStopWidth = document()->tabStopWidth(); |
4634 | } | 4657 | } |
4635 | if ( ta ) { | 4658 | if ( ta ) { |
4636 | int i = 0; | 4659 | int i = 0; |
4637 | while ( ta[ i ] ) { | 4660 | while ( ta[ i ] ) { |
4638 | if ( ta[ i ] >= x ) | 4661 | if ( ta[ i ] >= x ) |
4639 | return tArray[ i ]; | 4662 | return tArray[ i ]; |
4640 | ++i; | 4663 | ++i; |
4641 | } | 4664 | } |
4642 | return tArray[ 0 ]; | 4665 | return tArray[ 0 ]; |
4643 | } else { | 4666 | } else { |
4644 | int d; | 4667 | int d; |
4645 | if ( tabStopWidth != 0 ) | 4668 | if ( tabStopWidth != 0 ) |
4646 | d = x / tabStopWidth; | 4669 | d = x / tabStopWidth; |
4647 | else | 4670 | else |
4648 | return x; | 4671 | return x; |
4649 | return tabStopWidth * ( d + 1 ); | 4672 | return tabStopWidth * ( d + 1 ); |
4650 | } | 4673 | } |
4651 | } | 4674 | } |
4652 | 4675 | ||
4653 | void QTextParagraph::adjustToPainter( QPainter *p ) | 4676 | void QTextParagraph::adjustToPainter( QPainter *p ) |
4654 | { | 4677 | { |
4655 | for ( int i = 0; i < length(); ++i ) { | 4678 | for ( int i = 0; i < length(); ++i ) { |
4656 | if ( at( i )->isCustom() ) | 4679 | if ( at( i )->isCustom() ) |
4657 | at( i )->customItem()->adjustToPainter( p ); | 4680 | at( i )->customItem()->adjustToPainter( p ); |
4658 | } | 4681 | } |
4659 | } | 4682 | } |
4660 | 4683 | ||
4661 | QTextFormatCollection *QTextParagraph::formatCollection() const | 4684 | QTextFormatCollection *QTextParagraph::formatCollection() const |
4662 | { | 4685 | { |
4663 | if ( hasdoc ) | 4686 | if ( hasdoc ) |
4664 | return document()->formatCollection(); | 4687 | return document()->formatCollection(); |
4665 | if ( !qFormatCollection ) { | 4688 | if ( !qFormatCollection ) { |
4666 | qFormatCollection = new QTextFormatCollection; | 4689 | qFormatCollection = new QTextFormatCollection; |
4667 | static QSingleCleanupHandler<QTextFormatCollection> qtfCleanup; | 4690 | static QSingleCleanupHandler<QTextFormatCollection> qtfCleanup; |
4668 | qtfCleanup.set( &qFormatCollection ); | 4691 | qtfCleanup.set( &qFormatCollection ); |
4669 | } | 4692 | } |
4670 | return qFormatCollection; | 4693 | return qFormatCollection; |
4671 | } | 4694 | } |
4672 | 4695 | ||
4673 | QString QTextParagraph::richText() const | 4696 | QString QTextParagraph::richText() const |
4674 | { | 4697 | { |
4675 | QString s; | 4698 | QString s; |
4676 | QTextStringChar *formatChar = 0; | 4699 | QTextStringChar *formatChar = 0; |
4677 | QString spaces; | 4700 | QString spaces; |
4678 | bool doStart = richTextExportStart && richTextExportStart->paragraph() == this; | 4701 | bool doStart = richTextExportStart && richTextExportStart->paragraph() == this; |
4679 | bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this; | 4702 | bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this; |
4680 | int i; | 4703 | int i; |
4681 | for ( i = 0; i < length()-1; ++i ) { | 4704 | for ( i = 0; i < length()-1; ++i ) { |
4682 | if ( doStart && i && richTextExportStart->index() == i ) | 4705 | if ( doStart && i && richTextExportStart->index() == i ) |
4683 | s += "<selstart/>"; | 4706 | s += "<selstart/>"; |
4684 | if ( doEnd && richTextExportEnd->index() == i ) | 4707 | if ( doEnd && richTextExportEnd->index() == i ) |
4685 | s += "<selend/>"; | 4708 | s += "<selend/>"; |
4686 | QTextStringChar *c = &str->at( i ); | 4709 | QTextStringChar *c = &str->at( i ); |
4687 | if ( c->isAnchor() && !c->anchorName().isEmpty() ) { | 4710 | if ( c->isAnchor() && !c->anchorName().isEmpty() ) { |
4688 | if ( c->anchorName().contains( '#' ) ) { | 4711 | if ( c->anchorName().contains( '#' ) ) { |
4689 | QStringList l = QStringList::split( '#', c->anchorName() ); | 4712 | QStringList l = QStringList::split( '#', c->anchorName() ); |
4690 | for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) | 4713 | for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) |
4691 | s += "<a name=\"" + *it + "\"></a>"; | 4714 | s += "<a name=\"" + *it + "\"></a>"; |
4692 | } else { | 4715 | } else { |
4693 | s += "<a name=\"" + c->anchorName() + "\"></a>"; | 4716 | s += "<a name=\"" + c->anchorName() + "\"></a>"; |
4694 | } | 4717 | } |
4695 | } | 4718 | } |
4696 | if ( !formatChar ) { | 4719 | if ( !formatChar ) { |
4697 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), | 4720 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), |
4698 | 0, QString::null, c->anchorHref() ); | 4721 | 0, QString::null, c->anchorHref() ); |
4699 | formatChar = c; | 4722 | formatChar = c; |
4700 | } else if ( ( formatChar->format()->key() != c->format()->key() ) || | 4723 | } else if ( ( formatChar->format()->key() != c->format()->key() ) || |
4701 | (c->anchorHref() != formatChar->anchorHref() ) ) { | 4724 | (c->anchorHref() != formatChar->anchorHref() ) ) { |
4702 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), | 4725 | s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), |
4703 | formatChar->format() , formatChar->anchorHref(), c->anchorHref() ); | 4726 | formatChar->format() , formatChar->anchorHref(), c->anchorHref() ); |
4704 | formatChar = c; | 4727 | formatChar = c; |
4705 | } | 4728 | } |
4706 | if ( c->c == '<' ) | 4729 | if ( c->c == '<' ) |
4707 | s += "<"; | 4730 | s += "<"; |
4708 | else if ( c->c == '>' ) | 4731 | else if ( c->c == '>' ) |
4709 | s += ">"; | 4732 | s += ">"; |
4710 | else if ( c->isCustom() ) | 4733 | else if ( c->isCustom() ) |
4711 | s += c->customItem()->richText(); | 4734 | s += c->customItem()->richText(); |
4712 | else if ( c->c == '\n' || c->c == QChar_linesep ) | 4735 | else if ( c->c == '\n' || c->c == QChar_linesep ) |
4713 | s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co. | 4736 | s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co. |
4714 | else | 4737 | else |
4715 | s += c->c; | 4738 | s += c->c; |
4716 | } | 4739 | } |
4717 | if ( doEnd && richTextExportEnd->index() == i ) | 4740 | if ( doEnd && richTextExportEnd->index() == i ) |
4718 | s += "<selend/>"; | 4741 | s += "<selend/>"; |
4719 | if ( formatChar ) | 4742 | if ( formatChar ) |
4720 | s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() ); | 4743 | s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() ); |
4721 | return s; | 4744 | return s; |
4722 | } | 4745 | } |
4723 | 4746 | ||
4724 | void QTextParagraph::addCommand( QTextCommand *cmd ) | 4747 | void QTextParagraph::addCommand( QTextCommand *cmd ) |
4725 | { | 4748 | { |
4726 | if ( !hasdoc ) | 4749 | if ( !hasdoc ) |
4727 | pseudoDocument()->commandHistory->addCommand( cmd ); | 4750 | pseudoDocument()->commandHistory->addCommand( cmd ); |
4728 | else | 4751 | else |
4729 | document()->commands()->addCommand( cmd ); | 4752 | document()->commands()->addCommand( cmd ); |
4730 | } | 4753 | } |
4731 | 4754 | ||
4732 | QTextCursor *QTextParagraph::undo( QTextCursor *c ) | 4755 | QTextCursor *QTextParagraph::undo( QTextCursor *c ) |
4733 | { | 4756 | { |
4734 | if ( !hasdoc ) | 4757 | if ( !hasdoc ) |
4735 | return pseudoDocument()->commandHistory->undo( c ); | 4758 | return pseudoDocument()->commandHistory->undo( c ); |
4736 | return document()->commands()->undo( c ); | 4759 | return document()->commands()->undo( c ); |
4737 | } | 4760 | } |
4738 | 4761 | ||
4739 | QTextCursor *QTextParagraph::redo( QTextCursor *c ) | 4762 | QTextCursor *QTextParagraph::redo( QTextCursor *c ) |
4740 | { | 4763 | { |
4741 | if ( !hasdoc ) | 4764 | if ( !hasdoc ) |
4742 | return pseudoDocument()->commandHistory->redo( c ); | 4765 | return pseudoDocument()->commandHistory->redo( c ); |
4743 | return document()->commands()->redo( c ); | 4766 | return document()->commands()->redo( c ); |
4744 | } | 4767 | } |
4745 | 4768 | ||
4746 | int QTextParagraph::topMargin() const | 4769 | int QTextParagraph::topMargin() const |
4747 | { | 4770 | { |
4748 | int m = 0; | 4771 | int m = 0; |
4749 | if ( rtext ) { | 4772 | if ( rtext ) { |
4750 | m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm; | 4773 | m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm; |
4751 | if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) ) | 4774 | if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) ) |
4752 | m = QMAX( m, document()->list_tm ); | 4775 | m = QMAX( m, document()->list_tm ); |
4753 | } | 4776 | } |
4754 | m += utm; | 4777 | m += utm; |
4755 | return scale( m, QTextFormat::painter() ); | 4778 | return scale( m, QTextFormat::painter() ); |
4756 | } | 4779 | } |
4757 | 4780 | ||
4758 | int QTextParagraph::bottomMargin() const | 4781 | int QTextParagraph::bottomMargin() const |
4759 | { | 4782 | { |
4760 | int m = 0; | 4783 | int m = 0; |
4761 | if ( rtext ) { | 4784 | if ( rtext ) { |
4762 | m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm; | 4785 | m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm; |
4763 | if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) ) | 4786 | if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) ) |
4764 | m = QMAX( m, document()->list_bm ); | 4787 | m = QMAX( m, document()->list_bm ); |
4765 | } | 4788 | } |
4766 | m += ubm; | 4789 | m += ubm; |
4767 | return scale( m, QTextFormat::painter() ); | 4790 | return scale( m, QTextFormat::painter() ); |
4768 | } | 4791 | } |
4769 | 4792 | ||
4770 | int QTextParagraph::leftMargin() const | 4793 | int QTextParagraph::leftMargin() const |
4771 | { | 4794 | { |
4772 | int m = ulm; | 4795 | int m = ulm; |
4773 | if ( listDepth() ) | 4796 | if ( listDepth() ) |
4774 | m += listDepth() * document()->list_lm; | 4797 | m += listDepth() * document()->list_lm; |
4775 | return scale( m, QTextFormat::painter() ); | 4798 | return scale( m, QTextFormat::painter() ); |
4776 | } | 4799 | } |
4777 | 4800 | ||
4778 | int QTextParagraph::firstLineMargin() const | 4801 | int QTextParagraph::firstLineMargin() const |
4779 | { | 4802 | { |
4780 | int m = uflm; | 4803 | int m = uflm; |
4781 | return scale( m, QTextFormat::painter() ); | 4804 | return scale( m, QTextFormat::painter() ); |
4782 | } | 4805 | } |
4783 | 4806 | ||
4784 | int QTextParagraph::rightMargin() const | 4807 | int QTextParagraph::rightMargin() const |
4785 | { | 4808 | { |
4786 | int m = urm; | 4809 | int m = urm; |
4787 | return scale( m, QTextFormat::painter() ); | 4810 | return scale( m, QTextFormat::painter() ); |
4788 | } | 4811 | } |
4789 | 4812 | ||
4790 | int QTextParagraph::lineSpacing() const | 4813 | int QTextParagraph::lineSpacing() const |
4791 | { | 4814 | { |
4792 | int l = ulinespacing; | 4815 | int l = ulinespacing; |
4793 | l = scale( l, QTextFormat::painter() ); | 4816 | l = scale( l, QTextFormat::painter() ); |
4794 | return l; | 4817 | return l; |
4795 | } | 4818 | } |
4796 | 4819 | ||
4797 | void QTextParagraph::copyParagData( QTextParagraph *parag ) | 4820 | void QTextParagraph::copyParagData( QTextParagraph *parag ) |
4798 | { | 4821 | { |
4799 | rtext = parag->rtext; | 4822 | rtext = parag->rtext; |
4800 | lstyle = parag->lstyle; | 4823 | lstyle = parag->lstyle; |
4801 | ldepth = parag->ldepth; | 4824 | ldepth = parag->ldepth; |
4802 | litem = parag->litem; | 4825 | litem = parag->litem; |
4803 | align = parag->align; | 4826 | align = parag->align; |
4804 | utm = parag->utm; | 4827 | utm = parag->utm; |
4805 | ubm = parag->ubm; | 4828 | ubm = parag->ubm; |
4806 | urm = parag->urm; | 4829 | urm = parag->urm; |
4807 | ulm = parag->ulm; | 4830 | ulm = parag->ulm; |
4808 | uflm = parag->uflm; | 4831 | uflm = parag->uflm; |
4809 | ulinespacing = parag->ulinespacing; | 4832 | ulinespacing = parag->ulinespacing; |
4810 | QColor *c = parag->backgroundColor(); | 4833 | QColor *c = parag->backgroundColor(); |
4811 | if ( c ) | 4834 | if ( c ) |
4812 | setBackgroundColor( *c ); | 4835 | setBackgroundColor( *c ); |
4813 | str->setDirection( parag->str->direction() ); | 4836 | str->setDirection( parag->str->direction() ); |
4814 | } | 4837 | } |
4815 | 4838 | ||
4816 | void QTextParagraph::show() | 4839 | void QTextParagraph::show() |
4817 | { | 4840 | { |
4818 | if ( visible || !hasdoc ) | 4841 | if ( visible || !hasdoc ) |
4819 | return; | 4842 | return; |
4820 | visible = TRUE; | 4843 | visible = TRUE; |
4821 | } | 4844 | } |
4822 | 4845 | ||
4823 | void QTextParagraph::hide() | 4846 | void QTextParagraph::hide() |
4824 | { | 4847 | { |
4825 | if ( !visible || !hasdoc ) | 4848 | if ( !visible || !hasdoc ) |
4826 | return; | 4849 | return; |
4827 | visible = FALSE; | 4850 | visible = FALSE; |
4828 | } | 4851 | } |
4829 | 4852 | ||
4830 | void QTextParagraph::setDirection( QChar::Direction d ) | 4853 | void QTextParagraph::setDirection( QChar::Direction d ) |
4831 | { | 4854 | { |
4832 | if ( str && str->direction() != d ) { | 4855 | if ( str && str->direction() != d ) { |
4833 | str->setDirection( d ); | 4856 | str->setDirection( d ); |
4834 | invalidate( 0 ); | 4857 | invalidate( 0 ); |
4835 | } | 4858 | } |
4836 | } | 4859 | } |
4837 | 4860 | ||
4838 | QChar::Direction QTextParagraph::direction() const | 4861 | QChar::Direction QTextParagraph::direction() const |
4839 | { | 4862 | { |
4840 | return (str ? str->direction() : QChar::DirON ); | 4863 | return (str ? str->direction() : QChar::DirON ); |
4841 | } | 4864 | } |
4842 | 4865 | ||
4843 | void QTextParagraph::setChanged( bool b, bool recursive ) | 4866 | void QTextParagraph::setChanged( bool b, bool recursive ) |
4844 | { | 4867 | { |
4845 | changed = b; | 4868 | changed = b; |
4846 | if ( recursive ) { | 4869 | if ( recursive ) { |
4847 | if ( document() && document()->parentParagraph() ) | 4870 | if ( document() && document()->parentParagraph() ) |
4848 | document()->parentParagraph()->setChanged( b, recursive ); | 4871 | document()->parentParagraph()->setChanged( b, recursive ); |
4849 | } | 4872 | } |
4850 | } | 4873 | } |
4851 | 4874 | ||
4852 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 4875 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4853 | 4876 | ||
4854 | 4877 | ||
4855 | QTextPreProcessor::QTextPreProcessor() | 4878 | QTextPreProcessor::QTextPreProcessor() |
4856 | { | 4879 | { |
4857 | } | 4880 | } |
4858 | 4881 | ||
4859 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 4882 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4860 | 4883 | ||
4861 | QTextFormatter::QTextFormatter() | 4884 | QTextFormatter::QTextFormatter() |
4862 | : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE ) | 4885 | : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE ) |
4863 | { | 4886 | { |
4864 | } | 4887 | } |
4865 | 4888 | ||
4866 | QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, | 4889 | QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, |
4867 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) | 4890 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) |
4868 | { | 4891 | { |
4869 | #ifndef QT_NO_COMPLEXTEXT | 4892 | #ifndef QT_NO_COMPLEXTEXT |
4870 | if( string->isBidi() ) | 4893 | if( string->isBidi() ) |
4871 | return bidiReorderLine( parag, string, line, startChar, lastChar, align, space ); | 4894 | return bidiReorderLine( parag, string, line, startChar, lastChar, align, space ); |
4872 | #endif | 4895 | #endif |
4873 | int start = (startChar - &string->at(0)); | 4896 | int start = (startChar - &string->at(0)); |
4874 | int last = (lastChar - &string->at(0) ); | 4897 | int last = (lastChar - &string->at(0) ); |
4875 | // do alignment Auto == Left in this case | 4898 | // do alignment Auto == Left in this case |
4876 | if ( align & Qt::AlignHCenter || align & Qt::AlignRight ) { | 4899 | if ( align & Qt::AlignHCenter || align & Qt::AlignRight ) { |
4877 | if ( align & Qt::AlignHCenter ) | 4900 | if ( align & Qt::AlignHCenter ) |
4878 | space /= 2; | 4901 | space /= 2; |
4879 | for ( int j = start; j <= last; ++j ) | 4902 | for ( int j = start; j <= last; ++j ) |
4880 | string->at( j ).x += space; | 4903 | string->at( j ).x += space; |
4881 | } else if ( align & Qt3::AlignJustify ) { | 4904 | } else if ( align & Qt3::AlignJustify ) { |
4882 | int numSpaces = 0; | 4905 | int numSpaces = 0; |
4883 | // End at "last-1", the last space ends up with a width of 0 | 4906 | // End at "last-1", the last space ends up with a width of 0 |
4884 | for ( int j = last-1; j >= start; --j ) { | 4907 | for ( int j = last-1; j >= start; --j ) { |
4885 | // Start at last tab, if any. | 4908 | // Start at last tab, if any. |
4886 | if ( string->at( j ).c == '\t' ) { | 4909 | if ( string->at( j ).c == '\t' ) { |
4887 | start = j+1; | 4910 | start = j+1; |
4888 | break; | 4911 | break; |
4889 | } | 4912 | } |
4890 | if( isBreakable( string, j ) ) { | 4913 | if( isBreakable( string, j ) ) { |
4891 | numSpaces++; | 4914 | numSpaces++; |
4892 | } | 4915 | } |
4893 | } | 4916 | } |
4894 | int toAdd = 0; | 4917 | int toAdd = 0; |
4895 | for ( int k = start + 1; k <= last; ++k ) { | 4918 | for ( int k = start + 1; k <= last; ++k ) { |
4896 | if( isBreakable( string, k ) && numSpaces ) { | 4919 | if( isBreakable( string, k ) && numSpaces ) { |
4897 | int s = space / numSpaces; | 4920 | int s = space / numSpaces; |
4898 | toAdd += s; | 4921 | toAdd += s; |
4899 | space -= s; | 4922 | space -= s; |
4900 | numSpaces--; | 4923 | numSpaces--; |
4901 | } | 4924 | } |
4902 | string->at( k ).x += toAdd; | 4925 | string->at( k ).x += toAdd; |
4903 | } | 4926 | } |
4904 | } | 4927 | } |
4905 | 4928 | ||
4906 | if ( last >= 0 && last < string->length() ) | 4929 | if ( last >= 0 && last < string->length() ) |
4907 | line->w = string->at( last ).x + string->width( last ); | 4930 | line->w = string->at( last ).x + string->width( last ); |
4908 | else | 4931 | else |
4909 | line->w = 0; | 4932 | line->w = 0; |
4910 | 4933 | ||
4911 | return new QTextLineStart(); | 4934 | return new QTextLineStart(); |
4912 | } | 4935 | } |
4913 | 4936 | ||
4914 | #ifndef QT_NO_COMPLEXTEXT | 4937 | #ifndef QT_NO_COMPLEXTEXT |
4915 | 4938 | ||
4916 | #ifdef BIDI_DEBUG | 4939 | #ifdef BIDI_DEBUG |
4917 | #include <iostream> | 4940 | #include <iostream> |
4918 | #endif | 4941 | #endif |
4919 | 4942 | ||
4920 | // collects one line of the paragraph and transforms it to visual order | 4943 | // collects one line of the paragraph and transforms it to visual order |
4921 | QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line, | 4944 | QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line, |
4922 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) | 4945 | QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) |
4923 | { | 4946 | { |
4924 | int start = (startChar - &text->at(0)); | 4947 | int start = (startChar - &text->at(0)); |
4925 | int last = (lastChar - &text->at(0) ); | 4948 | int last = (lastChar - &text->at(0) ); |
4926 | 4949 | ||
4927 | QBidiControl *control = new QBidiControl( line->context(), line->status ); | 4950 | QBidiControl *control = new QBidiControl( line->context(), line->status ); |
4928 | QString str; | 4951 | QString str; |
4929 | str.setUnicode( 0, last - start + 1 ); | 4952 | str.setUnicode( 0, last - start + 1 ); |
4930 | // fill string with logically ordered chars. | 4953 | // fill string with logically ordered chars. |
4931 | QTextStringChar *ch = startChar; | 4954 | QTextStringChar *ch = startChar; |
4932 | QChar *qch = (QChar *)str.unicode(); | 4955 | QChar *qch = (QChar *)str.unicode(); |
4933 | while ( ch <= lastChar ) { | 4956 | while ( ch <= lastChar ) { |
4934 | *qch = ch->c; | 4957 | *qch = ch->c; |
4935 | qch++; | 4958 | qch++; |
4936 | ch++; | 4959 | ch++; |
4937 | } | 4960 | } |
4938 | int x = startChar->x; | 4961 | int x = startChar->x; |
4939 | 4962 | ||
4940 | QPtrList<QTextRun> *runs; | 4963 | QPtrList<QTextRun> *runs; |
4941 | runs = QComplexText::bidiReorderLine(control, str, 0, last - start + 1, | 4964 | runs = QComplexText::bidiReorderLine(control, str, 0, last - start + 1, |
4942 | (text->isRightToLeft() ? QChar::DirR : QChar::DirL) ); | 4965 | (text->isRightToLeft() ? QChar::DirR : QChar::DirL) ); |
4943 | 4966 | ||
4944 | // now construct the reordered string out of the runs... | 4967 | // now construct the reordered string out of the runs... |
4945 | 4968 | ||
4946 | int numSpaces = 0; | 4969 | int numSpaces = 0; |
4947 | // set the correct alignment. This is a bit messy.... | 4970 | // set the correct alignment. This is a bit messy.... |
4948 | if( align == Qt3::AlignAuto ) { | 4971 | if( align == Qt3::AlignAuto ) { |
4949 | // align according to directionality of the paragraph... | 4972 | // align according to directionality of the paragraph... |
4950 | if ( text->isRightToLeft() ) | 4973 | if ( text->isRightToLeft() ) |
4951 | align = Qt::AlignRight; | 4974 | align = Qt::AlignRight; |
4952 | } | 4975 | } |
4953 | 4976 | ||
4954 | if ( align & Qt::AlignHCenter ) | 4977 | if ( align & Qt::AlignHCenter ) |
4955 | x += space/2; | 4978 | x += space/2; |
4956 | else if ( align & Qt::AlignRight ) | 4979 | else if ( align & Qt::AlignRight ) |
4957 | x += space; | 4980 | x += space; |
4958 | else if ( align & Qt3::AlignJustify ) { | 4981 | else if ( align & Qt3::AlignJustify ) { |
4959 | // End at "last-1", the last space ends up with a width of 0 | 4982 | // End at "last-1", the last space ends up with a width of 0 |
4960 | for ( int j = last-1; j >= start; --j ) { | 4983 | for ( int j = last-1; j >= start; --j ) { |
4961 | // Start at last tab, if any. | 4984 | // Start at last tab, if any. |
4962 | if ( text->at( j ).c == '\t' ) { | 4985 | if ( text->at( j ).c == '\t' ) { |
4963 | start = j+1; | 4986 | start = j+1; |
4964 | break; | 4987 | break; |
4965 | } | 4988 | } |
4966 | if( isBreakable( text, j ) ) { | 4989 | if( isBreakable( text, j ) ) { |
4967 | numSpaces++; | 4990 | numSpaces++; |
4968 | } | 4991 | } |
4969 | } | 4992 | } |
4970 | } | 4993 | } |
4971 | int toAdd = 0; | 4994 | int toAdd = 0; |
4972 | bool first = TRUE; | 4995 | bool first = TRUE; |
4973 | QTextRun *r = runs->first(); | 4996 | QTextRun *r = runs->first(); |
4974 | int xmax = -0xffffff; | 4997 | int xmax = -0xffffff; |
4975 | while ( r ) { | 4998 | while ( r ) { |
4976 | if(r->level %2) { | 4999 | if(r->level %2) { |
4977 | // odd level, need to reverse the string | 5000 | // odd level, need to reverse the string |
4978 | int pos = r->stop + start; | 5001 | int pos = r->stop + start; |
4979 | while(pos >= r->start + start) { | 5002 | while(pos >= r->start + start) { |
4980 | QTextStringChar *c = &text->at(pos); | 5003 | QTextStringChar *c = &text->at(pos); |
4981 | if( numSpaces && !first && isBreakable( text, pos ) ) { | 5004 | if( numSpaces && !first && isBreakable( text, pos ) ) { |
4982 | int s = space / numSpaces; | 5005 | int s = space / numSpaces; |
4983 | toAdd += s; | 5006 | toAdd += s; |
4984 | space -= s; | 5007 | space -= s; |
4985 | numSpaces--; | 5008 | numSpaces--; |
4986 | } else if ( first ) { | 5009 | } else if ( first ) { |
4987 | first = FALSE; | 5010 | first = FALSE; |
4988 | if ( c->c == ' ' ) | 5011 | if ( c->c == ' ' ) |
4989 | x -= c->format()->width( ' ' ); | 5012 | x -= c->format()->width( ' ' ); |
4990 | } | 5013 | } |
4991 | c->x = x + toAdd; | 5014 | c->x = x + toAdd; |
4992 | c->rightToLeft = TRUE; | 5015 | c->rightToLeft = TRUE; |
4993 | c->startOfRun = FALSE; | 5016 | c->startOfRun = FALSE; |
4994 | int ww = 0; | 5017 | int ww = 0; |
4995 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->c == '\n' || c->isCustom() ) { | 5018 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->c == '\n' || c->isCustom() ) { |
4996 | ww = text->width( pos ); | 5019 | ww = text->width( pos ); |
4997 | } else { | 5020 | } else { |
4998 | ww = c->format()->width( ' ' ); | 5021 | ww = c->format()->width( ' ' ); |
4999 | } | 5022 | } |
5000 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; | 5023 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; |
5001 | x += ww; | 5024 | x += ww; |
5002 | pos--; | 5025 | pos--; |
5003 | } | 5026 | } |
5004 | } else { | 5027 | } else { |
5005 | int pos = r->start + start; | 5028 | int pos = r->start + start; |
5006 | while(pos <= r->stop + start) { | 5029 | while(pos <= r->stop + start) { |
5007 | QTextStringChar* c = &text->at(pos); | 5030 | QTextStringChar* c = &text->at(pos); |
5008 | if( numSpaces && !first && isBreakable( text, pos ) ) { | 5031 | if( numSpaces && !first && isBreakable( text, pos ) ) { |
5009 | int s = space / numSpaces; | 5032 | int s = space / numSpaces; |
5010 | toAdd += s; | 5033 | toAdd += s; |
5011 | space -= s; | 5034 | space -= s; |
5012 | numSpaces--; | 5035 | numSpaces--; |
5013 | } else if ( first ) { | 5036 | } else if ( first ) { |
5014 | first = FALSE; | 5037 | first = FALSE; |
5015 | if ( c->c == ' ' ) | 5038 | if ( c->c == ' ' ) |
5016 | x -= c->format()->width( ' ' ); | 5039 | x -= c->format()->width( ' ' ); |
5017 | } | 5040 | } |
5018 | c->x = x + toAdd; | 5041 | c->x = x + toAdd; |
5019 | c->rightToLeft = FALSE; | 5042 | c->rightToLeft = FALSE; |
5020 | c->startOfRun = FALSE; | 5043 | c->startOfRun = FALSE; |
5021 | int ww = 0; | 5044 | int ww = 0; |
5022 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->isCustom() ) { | 5045 | if ( c->c.unicode() >= 32 || c->c == '\t' || c->isCustom() ) { |
5023 | ww = text->width( pos ); | 5046 | ww = text->width( pos ); |
5024 | } else { | 5047 | } else { |
5025 | ww = c->format()->width( ' ' ); | 5048 | ww = c->format()->width( ' ' ); |
5026 | } | 5049 | } |
5027 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; | 5050 | if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; |
5028 | x += ww; | 5051 | x += ww; |
5029 | pos++; | 5052 | pos++; |
5030 | } | 5053 | } |
5031 | } | 5054 | } |
5032 | text->at( r->start + start ).startOfRun = TRUE; | 5055 | text->at( r->start + start ).startOfRun = TRUE; |
5033 | r = runs->next(); | 5056 | r = runs->next(); |
5034 | } | 5057 | } |
5035 | 5058 | ||
5036 | line->w = xmax + 10; | 5059 | line->w = xmax + 10; |
5037 | QTextLineStart *ls = new QTextLineStart( control->context, control->status ); | 5060 | QTextLineStart *ls = new QTextLineStart( control->context, control->status ); |
5038 | delete control; | 5061 | delete control; |
5039 | delete runs; | 5062 | delete runs; |
5040 | return ls; | 5063 | return ls; |
5041 | } | 5064 | } |
5042 | #endif | 5065 | #endif |
5043 | 5066 | ||
5044 | bool QTextFormatter::isBreakable( QTextString *string, int pos ) | 5067 | bool QTextFormatter::isBreakable( QTextString *string, int pos ) |
5045 | { | 5068 | { |
5046 | const QChar &c = string->at( pos ).c; | 5069 | const QChar &c = string->at( pos ).c; |
5047 | char ch = c.latin1(); | 5070 | char ch = c.latin1(); |
5048 | if ( c == QChar_linesep ) | 5071 | if ( c == QChar_linesep ) |
5049 | return TRUE; | 5072 | return TRUE; |
5050 | if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U ) | 5073 | if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U ) |
5051 | return TRUE; | 5074 | return TRUE; |
5052 | if ( c.unicode() == 0xad ) // soft hyphen | 5075 | if ( c.unicode() == 0xad ) // soft hyphen |
5053 | return TRUE; | 5076 | return TRUE; |
5054 | if ( !ch ) { | 5077 | if ( !ch ) { |
5055 | // not latin1, need to do more sophisticated checks for other scripts | 5078 | // not latin1, need to do more sophisticated checks for other scripts |
5056 | uchar row = c.row(); | 5079 | uchar row = c.row(); |
5057 | if ( row == 0x0e ) { | 5080 | if ( row == 0x0e ) { |
5058 | // 0e00 - 0e7f == Thai | 5081 | // 0e00 - 0e7f == Thai |
5059 | if ( c.cell() < 0x80 ) { | 5082 | if ( c.cell() < 0x80 ) { |
5060 | #ifdef HAVE_THAI_BREAKS | 5083 | #ifdef HAVE_THAI_BREAKS |
5061 | // check for thai | 5084 | // check for thai |
5062 | if( string != cachedString ) { | 5085 | if( string != cachedString ) { |
5063 | // build up string of thai chars | 5086 | // build up string of thai chars |
5064 | QTextCodec *thaiCodec = QTextCodec::codecForMib(2259); | 5087 | QTextCodec *thaiCodec = QTextCodec::codecForMib(2259); |
5065 | if ( !thaiCache ) | 5088 | if ( !thaiCache ) |
5066 | thaiCache = new QCString; | 5089 | thaiCache = new QCString; |
5067 | if ( !thaiIt ) | 5090 | if ( !thaiIt ) |
5068 | thaiIt = ThBreakIterator::createWordInstance(); | 5091 | thaiIt = ThBreakIterator::createWordInstance(); |
5069 | *thaiCache = thaiCodec->fromUnicode( s->string() ); | 5092 | *thaiCache = thaiCodec->fromUnicode( s->string() ); |
5070 | } | 5093 | } |
5071 | thaiIt->setText(thaiCache->data()); | 5094 | thaiIt->setText(thaiCache->data()); |
5072 | for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) { | 5095 | for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) { |
5073 | if( i == pos ) | 5096 | if( i == pos ) |
5074 | return TRUE; | 5097 | return TRUE; |
5075 | if( i > pos ) | 5098 | if( i > pos ) |
5076 | return FALSE; | 5099 | return FALSE; |
5077 | } | 5100 | } |
5078 | return FALSE; | 5101 | return FALSE; |
5079 | #else | 5102 | #else |
5080 | // if we don't have a thai line breaking lib, allow | 5103 | // if we don't have a thai line breaking lib, allow |
5081 | // breaks everywhere except directly before punctuation. | 5104 | // breaks everywhere except directly before punctuation. |
5082 | return TRUE; | 5105 | return TRUE; |
5083 | #endif | 5106 | #endif |
5084 | } else | 5107 | } else |
5085 | return FALSE; | 5108 | return FALSE; |
5086 | } | 5109 | } |
5087 | if ( row < 0x11 ) // no asian font | 5110 | if ( row < 0x11 ) // no asian font |
5088 | return FALSE; | 5111 | return FALSE; |
5089 | if ( row > 0x2d && row < 0xfb || row == 0x11 ) | 5112 | if ( row > 0x2d && row < 0xfb || row == 0x11 ) |
5090 | // asian line breaking. Everywhere allowed except directly | 5113 | // asian line breaking. Everywhere allowed except directly |
5091 | // in front of a punctuation character. | 5114 | // in front of a punctuation character. |
5092 | return TRUE; | 5115 | return TRUE; |
5093 | } | 5116 | } |
5094 | return FALSE; | 5117 | return FALSE; |
5095 | } | 5118 | } |
5096 | 5119 | ||
5097 | void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls ) | 5120 | void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls ) |
5098 | { | 5121 | { |
5099 | if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times | 5122 | if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times |
5100 | parag->lineStartList().insert( index, ls ); | 5123 | parag->lineStartList().insert( index, ls ); |
5101 | return; | 5124 | return; |
5102 | } | 5125 | } |
5103 | QMap<int, QTextLineStart*>::Iterator it; | 5126 | QMap<int, QTextLineStart*>::Iterator it; |
5104 | if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) { | 5127 | if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) { |
5105 | parag->lineStartList().insert( index, ls ); | 5128 | parag->lineStartList().insert( index, ls ); |
5106 | } else { | 5129 | } else { |
5107 | delete *it; | 5130 | delete *it; |
5108 | parag->lineStartList().remove( it ); | 5131 | parag->lineStartList().remove( it ); |
5109 | parag->lineStartList().insert( index, ls ); | 5132 | parag->lineStartList().insert( index, ls ); |
5110 | } | 5133 | } |
5111 | } | 5134 | } |
5112 | 5135 | ||
5113 | 5136 | ||
5114 | /* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns | 5137 | /* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns |
5115 | the shift of the paragraphs bottom line. | 5138 | the shift of the paragraphs bottom line. |
5116 | */ | 5139 | */ |
5117 | int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag ) | 5140 | int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag ) |
5118 | { | 5141 | { |
5119 | int oldHeight = parag->rect().height(); | 5142 | int oldHeight = parag->rect().height(); |
5120 | QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList(); | 5143 | QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList(); |
5121 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); | 5144 | QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); |
5122 | int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0; | 5145 | int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0; |
5123 | for ( ; it != lineStarts.end() ; ++it ) { | 5146 | for ( ; it != lineStarts.end() ; ++it ) { |
5124 | QTextLineStart * ls = it.data(); | 5147 | QTextLineStart * ls = it.data(); |
5125 | ls->y = h; | 5148 | ls->y = h; |
5126 | QTextStringChar *c = ¶g->string()->at(it.key()); | 5149 | QTextStringChar *c = ¶g->string()->at(it.key()); |
5127 | if ( c && c->customItem() && c->customItem()->ownLine() ) { | 5150 | if ( c && c->customItem() && c->customItem()->ownLine() ) { |
5128 | int h = c->customItem()->height; | 5151 | int h = c->customItem()->height; |
5129 | c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() ); | 5152 | c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() ); |
5130 | int delta = c->customItem()->height - h; | 5153 | int delta = c->customItem()->height - h; |
5131 | ls->h += delta; | 5154 | ls->h += delta; |
5132 | if ( delta ) | 5155 | if ( delta ) |
5133 | parag->setMovedDown( TRUE ); | 5156 | parag->setMovedDown( TRUE ); |
5134 | } else { | 5157 | } else { |
5135 | int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h ); | 5158 | int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h ); |
5136 | ls->y += shift; | 5159 | ls->y += shift; |
5137 | if ( shift ) | 5160 | if ( shift ) |
5138 | parag->setMovedDown( TRUE ); | 5161 | parag->setMovedDown( TRUE ); |
5139 | } | 5162 | } |
5140 | h = ls->y + ls->h; | 5163 | h = ls->y + ls->h; |
5141 | } | 5164 | } |
5142 | int m = parag->bottomMargin(); | 5165 | int m = parag->bottomMargin(); |
5143 | if ( !parag->next() ) | 5166 | if ( !parag->next() ) |
5144 | m = 0; | 5167 | m = 0; |
5145 | else | 5168 | else |
5146 | m = QMAX(m, parag->next()->topMargin() ) / 2; | 5169 | m = QMAX(m, parag->next()->topMargin() ) / 2; |
5147 | h += m; | 5170 | h += m; |
5148 | parag->setHeight( h ); | 5171 | parag->setHeight( h ); |
5149 | return h - oldHeight; | 5172 | return h - oldHeight; |
5150 | } | 5173 | } |
5151 | 5174 | ||
5152 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5175 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5153 | 5176 | ||
5154 | QTextFormatterBreakInWords::QTextFormatterBreakInWords() | 5177 | QTextFormatterBreakInWords::QTextFormatterBreakInWords() |
5155 | { | 5178 | { |
5156 | } | 5179 | } |
5157 | 5180 | ||
5158 | #define SPACE(s) doc?(s>0?s:0):s | 5181 | #define SPACE(s) doc?(s>0?s:0):s |
5159 | 5182 | ||
5160 | int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag, | 5183 | int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag, |
5161 | int start, const QMap<int, QTextLineStart*> & ) | 5184 | int start, const QMap<int, QTextLineStart*> & ) |
5162 | { | 5185 | { |
5163 | QTextStringChar *c = 0; | 5186 | QTextStringChar *c = 0; |
5164 | QTextStringChar *firstChar = 0; | 5187 | QTextStringChar *firstChar = 0; |
5165 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; | 5188 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; |
5166 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); | 5189 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); |
5167 | int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 ); | 5190 | int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 ); |
5168 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; | 5191 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; |
5169 | int h = y; | 5192 | int h = y; |
5170 | int len = parag->length(); | 5193 | int len = parag->length(); |
5171 | if ( doc ) | 5194 | if ( doc ) |
5172 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 ); | 5195 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 ); |
5173 | int rm = parag->rightMargin(); | 5196 | int rm = parag->rightMargin(); |
5174 | int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5197 | int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5175 | bool fullWidth = TRUE; | 5198 | bool fullWidth = TRUE; |
5176 | int minw = 0; | 5199 | int minw = 0; |
5177 | int wused = 0; | 5200 | int wused = 0; |
5178 | bool wrapEnabled = isWrapEnabled( parag ); | 5201 | bool wrapEnabled = isWrapEnabled( parag ); |
5179 | 5202 | ||
5180 | start = 0; //######### what is the point with start?! (Matthias) | 5203 | start = 0; //######### what is the point with start?! (Matthias) |
5181 | if ( start == 0 ) | 5204 | if ( start == 0 ) |
5182 | c = ¶g->string()->at( 0 ); | 5205 | c = ¶g->string()->at( 0 ); |
5183 | 5206 | ||
5184 | int i = start; | 5207 | int i = start; |
5185 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); | 5208 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); |
5186 | insertLineStart( parag, 0, lineStart ); | 5209 | insertLineStart( parag, 0, lineStart ); |
5187 | 5210 | ||
5188 | QPainter *painter = QTextFormat::painter(); | 5211 | QPainter *painter = QTextFormat::painter(); |
5189 | 5212 | ||
5190 | int col = 0; | 5213 | int col = 0; |
5191 | int ww = 0; | 5214 | int ww = 0; |
5192 | QChar lastChr; | 5215 | QChar lastChr; |
5193 | for ( ; i < len; ++i, ++col ) { | 5216 | for ( ; i < len; ++i, ++col ) { |
5194 | if ( c ) | 5217 | if ( c ) |
5195 | lastChr = c->c; | 5218 | lastChr = c->c; |
5196 | c = ¶g->string()->at( i ); | 5219 | c = ¶g->string()->at( i ); |
5197 | c->rightToLeft = FALSE; | 5220 | c->rightToLeft = FALSE; |
5198 | // ### the lines below should not be needed | 5221 | // ### the lines below should not be needed |
5199 | if ( painter ) | 5222 | if ( painter ) |
5200 | c->format()->setPainter( painter ); | 5223 | c->format()->setPainter( painter ); |
5201 | if ( i > 0 ) { | 5224 | if ( i > 0 ) { |
5202 | c->lineStart = 0; | 5225 | c->lineStart = 0; |
5203 | } else { | 5226 | } else { |
5204 | c->lineStart = 1; | 5227 | c->lineStart = 1; |
5205 | firstChar = c; | 5228 | firstChar = c; |
5206 | } | 5229 | } |
5207 | if ( c->c.unicode() >= 32 || c->isCustom() ) { | 5230 | if ( c->c.unicode() >= 32 || c->isCustom() ) { |
5208 | ww = parag->string()->width( i ); | 5231 | ww = parag->string()->width( i ); |
5209 | } else if ( c->c == '\t' ) { | 5232 | } else if ( c->c == '\t' ) { |
5210 | int nx = parag->nextTab( i, x - left ) + left; | 5233 | int nx = parag->nextTab( i, x - left ) + left; |
5211 | if ( nx < x ) | 5234 | if ( nx < x ) |
5212 | ww = w - x; | 5235 | ww = w - x; |
5213 | else | 5236 | else |
5214 | ww = nx - x; | 5237 | ww = nx - x; |
5215 | } else { | 5238 | } else { |
5216 | ww = c->format()->width( ' ' ); | 5239 | ww = c->format()->width( ' ' ); |
5217 | } | 5240 | } |
5218 | 5241 | ||
5219 | if ( c->isCustom() && c->customItem()->ownLine() ) { | 5242 | if ( c->isCustom() && c->customItem()->ownLine() ) { |
5220 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5243 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5221 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5244 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5222 | c->customItem()->resize( w - x ); | 5245 | c->customItem()->resize( w - x ); |
5223 | w = dw; | 5246 | w = dw; |
5224 | y += h; | 5247 | y += h; |
5225 | h = c->height(); | 5248 | h = c->height(); |
5226 | lineStart = new QTextLineStart( y, h, h ); | 5249 | lineStart = new QTextLineStart( y, h, h ); |
5227 | insertLineStart( parag, i, lineStart ); | 5250 | insertLineStart( parag, i, lineStart ); |
5228 | c->lineStart = 1; | 5251 | c->lineStart = 1; |
5229 | firstChar = c; | 5252 | firstChar = c; |
5230 | x = 0xffffff; | 5253 | x = 0xffffff; |
5231 | continue; | 5254 | continue; |
5232 | } | 5255 | } |
5233 | 5256 | ||
5234 | if ( wrapEnabled && | 5257 | if ( wrapEnabled && |
5235 | ( wrapAtColumn() == -1 && x + ww > w || | 5258 | ( wrapAtColumn() == -1 && x + ww > w || |
5236 | wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) { | 5259 | wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) { |
5237 | x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5260 | x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5238 | w = dw; | 5261 | w = dw; |
5239 | y += h; | 5262 | y += h; |
5240 | h = c->height(); | 5263 | h = c->height(); |
5241 | lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) ); | 5264 | lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) ); |
5242 | lineStart->y = y; | 5265 | lineStart->y = y; |
5243 | insertLineStart( parag, i, lineStart ); | 5266 | insertLineStart( parag, i, lineStart ); |
5244 | lineStart->baseLine = c->ascent(); | 5267 | lineStart->baseLine = c->ascent(); |
5245 | lineStart->h = c->height(); | 5268 | lineStart->h = c->height(); |
5246 | c->lineStart = 1; | 5269 | c->lineStart = 1; |
5247 | firstChar = c; | 5270 | firstChar = c; |
5248 | col = 0; | 5271 | col = 0; |
5249 | if ( wrapAtColumn() != -1 ) | 5272 | if ( wrapAtColumn() != -1 ) |
5250 | minw = QMAX( minw, w ); | 5273 | minw = QMAX( minw, w ); |
5251 | } else if ( lineStart ) { | 5274 | } else if ( lineStart ) { |
5252 | lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() ); | 5275 | lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() ); |
5253 | h = QMAX( h, c->height() ); | 5276 | h = QMAX( h, c->height() ); |
5254 | lineStart->h = h; | 5277 | lineStart->h = h; |
5255 | } | 5278 | } |
5256 | 5279 | ||
5257 | c->x = x; | 5280 | c->x = x; |
5258 | x += ww; | 5281 | x += ww; |
5259 | wused = QMAX( wused, x ); | 5282 | wused = QMAX( wused, x ); |
5260 | } | 5283 | } |
5261 | 5284 | ||
5262 | int m = parag->bottomMargin(); | 5285 | int m = parag->bottomMargin(); |
5263 | if ( !parag->next() ) | 5286 | if ( !parag->next() ) |
5264 | m = 0; | 5287 | m = 0; |
5265 | else | 5288 | else |
5266 | m = QMAX(m, parag->next()->topMargin() ) / 2; | 5289 | m = QMAX(m, parag->next()->topMargin() ) / 2; |
5267 | parag->setFullWidth( fullWidth ); | 5290 | parag->setFullWidth( fullWidth ); |
5268 | y += h + m; | 5291 | y += h + m; |
5269 | if ( doc ) | 5292 | if ( doc ) |
5270 | minw += doc->rightMargin(); | 5293 | minw += doc->rightMargin(); |
5271 | if ( !wrapEnabled ) | 5294 | if ( !wrapEnabled ) |
5272 | minw = QMAX(minw, wused); | 5295 | minw = QMAX(minw, wused); |
5273 | 5296 | ||
5274 | thisminw = minw; | 5297 | thisminw = minw; |
5275 | thiswused = wused; | 5298 | thiswused = wused; |
5276 | return y; | 5299 | return y; |
5277 | } | 5300 | } |
5278 | 5301 | ||
5279 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5302 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5280 | 5303 | ||
5281 | QTextFormatterBreakWords::QTextFormatterBreakWords() | 5304 | QTextFormatterBreakWords::QTextFormatterBreakWords() |
5282 | { | 5305 | { |
5283 | } | 5306 | } |
5284 | 5307 | ||
5285 | #define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \ | 5308 | #define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \ |
5286 | int yflow = lineStart->y + parag->rect().y();\ | 5309 | int yflow = lineStart->y + parag->rect().y();\ |
5287 | int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \ | 5310 | int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \ |
5288 | lineStart->y += shift;\ | 5311 | lineStart->y += shift;\ |
5289 | y += shift;\ | 5312 | y += shift;\ |
5290 | }}while(FALSE) | 5313 | }}while(FALSE) |
5291 | 5314 | ||
5292 | int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, | 5315 | int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, |
5293 | int start, const QMap<int, QTextLineStart*> & ) | 5316 | int start, const QMap<int, QTextLineStart*> & ) |
5294 | { | 5317 | { |
5295 | QTextStringChar *c = 0; | 5318 | QTextStringChar *c = 0; |
5296 | QTextStringChar *firstChar = 0; | 5319 | QTextStringChar *firstChar = 0; |
5297 | QTextString *string = parag->string(); | 5320 | QTextString *string = parag->string(); |
5298 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; | 5321 | int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; |
5299 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); | 5322 | int x = left + ( doc ? parag->firstLineMargin() : 0 ); |
5300 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; | 5323 | int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; |
5301 | int h = y; | 5324 | int h = y; |
5302 | int len = parag->length(); | 5325 | int len = parag->length(); |
5303 | if ( doc ) | 5326 | if ( doc ) |
5304 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 ); | 5327 | x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 ); |
5305 | int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 ); | 5328 | int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 ); |
5306 | 5329 | ||
5307 | int curLeft = x; | 5330 | int curLeft = x; |
5308 | int rm = parag->rightMargin(); | 5331 | int rm = parag->rightMargin(); |
5309 | int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0; | 5332 | int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0; |
5310 | int w = dw - rdiff; | 5333 | int w = dw - rdiff; |
5311 | bool fullWidth = TRUE; | 5334 | bool fullWidth = TRUE; |
5312 | int marg = left + rdiff; | 5335 | int marg = left + rdiff; |
5313 | int minw = 0; | 5336 | int minw = 0; |
5314 | int wused = 0; | 5337 | int wused = 0; |
5315 | int tminw = marg; | 5338 | int tminw = marg; |
5316 | int linespacing = doc ? parag->lineSpacing() : 0; | 5339 | int linespacing = doc ? parag->lineSpacing() : 0; |
5317 | bool wrapEnabled = isWrapEnabled( parag ); | 5340 | bool wrapEnabled = isWrapEnabled( parag ); |
5318 | 5341 | ||
5319 | start = 0; | 5342 | start = 0; |
5320 | if ( start == 0 ) | 5343 | if ( start == 0 ) |
5321 | c = ¶g->string()->at( 0 ); | 5344 | c = ¶g->string()->at( 0 ); |
5322 | 5345 | ||
5323 | int i = start; | 5346 | int i = start; |
5324 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); | 5347 | QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); |
5325 | insertLineStart( parag, 0, lineStart ); | 5348 | insertLineStart( parag, 0, lineStart ); |
5326 | int lastBreak = -1; | 5349 | int lastBreak = -1; |
5327 | int tmpBaseLine = 0, tmph = 0; | 5350 | int tmpBaseLine = 0, tmph = 0; |
5328 | bool lastWasNonInlineCustom = FALSE; | 5351 | bool lastWasNonInlineCustom = FALSE; |
5329 | 5352 | ||
5330 | int align = parag->alignment(); | 5353 | int align = parag->alignment(); |
5331 | if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto ) | 5354 | if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto ) |
5332 | align = doc->alignment(); | 5355 | align = doc->alignment(); |
5333 | 5356 | ||
5334 | align &= Qt3::AlignHorizontal_Mask; | 5357 | align &= Qt3::AlignHorizontal_Mask; |
5335 | 5358 | ||
5336 | QPainter *painter = QTextFormat::painter(); | 5359 | QPainter *painter = QTextFormat::painter(); |
5337 | int col = 0; | 5360 | int col = 0; |
5338 | int ww = 0; | 5361 | int ww = 0; |
5339 | QChar lastChr; | 5362 | QChar lastChr; |
5340 | for ( ; i < len; ++i, ++col ) { | 5363 | for ( ; i < len; ++i, ++col ) { |
5341 | if ( c ) | 5364 | if ( c ) |
5342 | lastChr = c->c; | 5365 | lastChr = c->c; |
5343 | // ### next line should not be needed | 5366 | // ### next line should not be needed |
5344 | if ( painter ) | 5367 | if ( c && painter ) |
5345 | c->format()->setPainter( painter ); | 5368 | c->format()->setPainter( painter ); |
5346 | c = &string->at( i ); | 5369 | c = &string->at( i ); |
5347 | c->rightToLeft = FALSE; | 5370 | c->rightToLeft = FALSE; |
5348 | if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) { | 5371 | if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) { |
5349 | c->lineStart = 0; | 5372 | c->lineStart = 0; |
5350 | } else { | 5373 | } else { |
5351 | c->lineStart = 1; | 5374 | c->lineStart = 1; |
5352 | firstChar = c; | 5375 | firstChar = c; |
5353 | } | 5376 | } |
5354 | 5377 | ||
5355 | if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline ) | 5378 | if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline ) |
5356 | lastWasNonInlineCustom = TRUE; | 5379 | lastWasNonInlineCustom = TRUE; |
5357 | else | 5380 | else |
5358 | lastWasNonInlineCustom = FALSE; | 5381 | lastWasNonInlineCustom = FALSE; |
5359 | 5382 | ||
5360 | if ( c->c.unicode() >= 32 || c->isCustom() ) { | 5383 | if ( c->c.unicode() >= 32 || c->isCustom() ) { |
5361 | ww = string->width( i ); | 5384 | ww = string->width( i ); |
5362 | } else if ( c->c == '\t' ) { | 5385 | } else if ( c->c == '\t' ) { |
5363 | int nx = parag->nextTab( i, x - left ) + left; | 5386 | int nx = parag->nextTab( i, x - left ) + left; |
5364 | if ( nx < x ) | 5387 | if ( nx < x ) |
5365 | ww = w - x; | 5388 | ww = w - x; |
5366 | else | 5389 | else |
5367 | ww = nx - x; | 5390 | ww = nx - x; |
5368 | } else { | 5391 | } else { |
5369 | ww = c->format()->width( ' ' ); | 5392 | ww = c->format()->width( ' ' ); |
5370 | } | 5393 | } |
5371 | 5394 | ||
5372 | // last character ("invisible" space) has no width | 5395 | // last character ("invisible" space) has no width |
5373 | if ( i == len - 1 ) | 5396 | if ( i == len - 1 ) |
5374 | ww = 0; | 5397 | ww = 0; |
5375 | 5398 | ||
5376 | QTextCustomItem* ci = c->customItem(); | 5399 | QTextCustomItem* ci = c->customItem(); |
5377 | if ( c->isCustom() && ci->ownLine() ) { | 5400 | if ( c->isCustom() && ci->ownLine() ) { |
5378 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5401 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5379 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5402 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5380 | QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); | 5403 | QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); |
5381 | ci->resize( w - x); | 5404 | ci->resize( w - x); |
5382 | if ( ci->width < w - x ) { | 5405 | if ( ci->width < w - x ) { |
5383 | if ( align & Qt::AlignHCenter ) | 5406 | if ( align & Qt::AlignHCenter ) |
5384 | x = ( w - ci->width ) / 2; | 5407 | x = ( w - ci->width ) / 2; |
5385 | else if ( align & Qt::AlignRight ) { | 5408 | else if ( align & Qt::AlignRight ) { |
5386 | x = w - ci->width; | 5409 | x = w - ci->width; |
5387 | } | 5410 | } |
5388 | } | 5411 | } |
5389 | c->x = x; | 5412 | c->x = x; |
5390 | curLeft = x; | 5413 | curLeft = x; |
5391 | if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { | 5414 | if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { |
5392 | y += QMAX( h, QMAX( tmph, linespacing ) ); | 5415 | y += QMAX( h, QMAX( tmph, linespacing ) ); |
5393 | tmph = c->height(); | 5416 | tmph = c->height(); |
5394 | h = tmph; | 5417 | h = tmph; |
5395 | lineStart = lineStart2; | 5418 | lineStart = lineStart2; |
5396 | lineStart->y = y; | 5419 | lineStart->y = y; |
5397 | insertLineStart( parag, i, lineStart ); | 5420 | insertLineStart( parag, i, lineStart ); |
5398 | c->lineStart = 1; | 5421 | c->lineStart = 1; |
5399 | firstChar = c; | 5422 | firstChar = c; |
5400 | } else { | 5423 | } else { |
5401 | tmph = c->height(); | 5424 | tmph = c->height(); |
5402 | h = tmph; | 5425 | h = tmph; |
5403 | delete lineStart2; | 5426 | delete lineStart2; |
5404 | } | 5427 | } |
5405 | lineStart->h = h; | 5428 | lineStart->h = h; |
5406 | lineStart->baseLine = h; | 5429 | lineStart->baseLine = h; |
5407 | tmpBaseLine = lineStart->baseLine; | 5430 | tmpBaseLine = lineStart->baseLine; |
5408 | lastBreak = -2; | 5431 | lastBreak = -2; |
5409 | x = 0xffffff; | 5432 | x = 0xffffff; |
5410 | minw = QMAX( minw, tminw ); | 5433 | minw = QMAX( minw, tminw ); |
5411 | 5434 | ||
5412 | int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 ); | 5435 | int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 ); |
5413 | if ( tw < QWIDGETSIZE_MAX ) | 5436 | if ( tw < QWIDGETSIZE_MAX ) |
5414 | tminw = tw; | 5437 | tminw = tw; |
5415 | else | 5438 | else |
5416 | tminw = marg; | 5439 | tminw = marg; |
5417 | wused = QMAX( wused, ci->width ); | 5440 | wused = QMAX( wused, ci->width ); |
5418 | continue; | 5441 | continue; |
5419 | } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) { | 5442 | } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) { |
5420 | int tw = ci->minimumWidth(); | 5443 | int tw = ci->minimumWidth(); |
5421 | if ( tw < QWIDGETSIZE_MAX ) | 5444 | if ( tw < QWIDGETSIZE_MAX ) |
5422 | minw = QMAX( minw, tw ); | 5445 | minw = QMAX( minw, tw ); |
5423 | } | 5446 | } |
5424 | 5447 | ||
5425 | bool lastWasOwnLineCustomItem = lastBreak == -2; | 5448 | bool lastWasOwnLineCustomItem = lastBreak == -2; |
5426 | bool hadBreakableChar = lastBreak != -1; | 5449 | bool hadBreakableChar = lastBreak != -1; |
5427 | bool lastWasHardBreak = lastChr == QChar_linesep; | 5450 | bool lastWasHardBreak = lastChr == QChar_linesep; |
5428 | 5451 | ||
5429 | // we break if | 5452 | // we break if |
5430 | // 1. the last character was a hard break (QChar_linesep) or | 5453 | // 1. the last character was a hard break (QChar_linesep) or |
5431 | // 2. the last charater was a own-line custom item (eg. table or ruler) or | 5454 | // 2. the last charater was a own-line custom item (eg. table or ruler) or |
5432 | // 3. wrapping was enabled, it was not a space and following | 5455 | // 3. wrapping was enabled, it was not a space and following |
5433 | // condition is true: We either had a breakable character | 5456 | // condition is true: We either had a breakable character |
5434 | // previously or we ar allowed to break in words and - either | 5457 | // previously or we ar allowed to break in words and - either |
5435 | // we break at w pixels and the current char would exceed that | 5458 | // we break at w pixels and the current char would exceed that |
5436 | // or - we break at a column and the current character would | 5459 | // or - we break at a column and the current character would |
5437 | // exceed that. | 5460 | // exceed that. |
5438 | if ( lastWasHardBreak || lastWasOwnLineCustomItem || | 5461 | if ( lastWasHardBreak || lastWasOwnLineCustomItem || |
5439 | ( wrapEnabled && | 5462 | ( wrapEnabled && |
5440 | ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) && | 5463 | ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) && |
5441 | ( (wrapAtColumn() == -1 && x + ww > w) || | 5464 | ( (wrapAtColumn() == -1 && x + ww > w) || |
5442 | (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) ) | 5465 | (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) ) |
5443 | ) | 5466 | ) |
5444 | ) { | 5467 | ) { |
5445 | if ( wrapAtColumn() != -1 ) | 5468 | if ( wrapAtColumn() != -1 ) |
5446 | minw = QMAX( minw, x + ww ); | 5469 | minw = QMAX( minw, x + ww ); |
5447 | // if a break was forced (no breakable char, hard break or own line custom item), break immediately.... | 5470 | // if a break was forced (no breakable char, hard break or own line custom item), break immediately.... |
5448 | if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) { | 5471 | if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) { |
5449 | if ( lineStart ) { | 5472 | if ( lineStart ) { |
5450 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); | 5473 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); |
5451 | h = QMAX( h, tmph ); | 5474 | h = QMAX( h, tmph ); |
5452 | lineStart->h = h; | 5475 | lineStart->h = h; |
5453 | DO_FLOW( lineStart ); | 5476 | DO_FLOW( lineStart ); |
5454 | } | 5477 | } |
5455 | lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); | 5478 | lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); |
5456 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5479 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5457 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5480 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5458 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling | 5481 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling |
5459 | int nx = parag->nextTab( i, x - left ) + left; | 5482 | int nx = parag->nextTab( i, x - left ) + left; |
5460 | if ( nx < x ) | 5483 | if ( nx < x ) |
5461 | ww = w - x; | 5484 | ww = w - x; |
5462 | else | 5485 | else |
5463 | ww = nx - x; | 5486 | ww = nx - x; |
5464 | } | 5487 | } |
5465 | curLeft = x; | 5488 | curLeft = x; |
5466 | y += QMAX( h, linespacing ); | 5489 | y += QMAX( h, linespacing ); |
5467 | tmph = c->height(); | 5490 | tmph = c->height(); |
5468 | h = 0; | 5491 | h = 0; |
5469 | lineStart->y = y; | 5492 | lineStart->y = y; |
5470 | insertLineStart( parag, i, lineStart ); | 5493 | insertLineStart( parag, i, lineStart ); |
5471 | lineStart->baseLine = c->ascent(); | 5494 | lineStart->baseLine = c->ascent(); |
5472 | lineStart->h = c->height(); | 5495 | lineStart->h = c->height(); |
5473 | c->lineStart = 1; | 5496 | c->lineStart = 1; |
5474 | firstChar = c; | 5497 | firstChar = c; |
5475 | tmpBaseLine = lineStart->baseLine; | 5498 | tmpBaseLine = lineStart->baseLine; |
5476 | lastBreak = -1; | 5499 | lastBreak = -1; |
5477 | col = 0; | 5500 | col = 0; |
5478 | } else { // ... otherwise if we had a breakable char, break there | 5501 | } else { // ... otherwise if we had a breakable char, break there |
5479 | DO_FLOW( lineStart ); | 5502 | DO_FLOW( lineStart ); |
5480 | i = lastBreak; | 5503 | i = lastBreak; |
5481 | lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) ); | 5504 | lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) ); |
5482 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; | 5505 | x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; |
5483 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); | 5506 | w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); |
5484 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling | 5507 | if ( !doc && c->c == '\t' ) { // qt_format_text tab handling |
5485 | int nx = parag->nextTab( i, x - left ) + left; | 5508 | int nx = parag->nextTab( i, x - left ) + left; |
5486 | if ( nx < x ) | 5509 | if ( nx < x ) |
5487 | ww = w - x; | 5510 | ww = w - x; |
5488 | else | 5511 | else |
5489 | ww = nx - x; | 5512 | ww = nx - x; |
5490 | } | 5513 | } |
5491 | curLeft = x; | 5514 | curLeft = x; |
5492 | y += QMAX( h, linespacing ); | 5515 | y += QMAX( h, linespacing ); |
5493 | tmph = c->height(); | 5516 | tmph = c->height(); |
5494 | h = tmph; | 5517 | h = tmph; |
5495 | lineStart->y = y; | 5518 | lineStart->y = y; |
5496 | insertLineStart( parag, i + 1, lineStart ); | 5519 | insertLineStart( parag, i + 1, lineStart ); |
5497 | lineStart->baseLine = c->ascent(); | 5520 | lineStart->baseLine = c->ascent(); |
5498 | lineStart->h = c->height(); | 5521 | lineStart->h = c->height(); |
5499 | c->lineStart = 1; | 5522 | c->lineStart = 1; |
5500 | firstChar = c; | 5523 | firstChar = c; |
5501 | tmpBaseLine = lineStart->baseLine; | 5524 | tmpBaseLine = lineStart->baseLine; |
5502 | lastBreak = -1; | 5525 | lastBreak = -1; |
5503 | col = 0; | 5526 | col = 0; |
5504 | tminw = marg; | 5527 | tminw = marg; |
5505 | continue; | 5528 | continue; |
5506 | } | 5529 | } |
5507 | } else if ( lineStart && isBreakable( string, i ) ) { | 5530 | } else if ( lineStart && isBreakable( string, i ) ) { |
5508 | if ( len <= 2 || i < len - 1 ) { | 5531 | if ( len <= 2 || i < len - 1 ) { |
5509 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); | 5532 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); |
5510 | tmph = QMAX( tmph, c->height() ); | 5533 | tmph = QMAX( tmph, c->height() ); |
5511 | } | 5534 | } |
5512 | minw = QMAX( minw, tminw ); | 5535 | minw = QMAX( minw, tminw ); |
5513 | tminw = marg + ww; | 5536 | tminw = marg + ww; |
5514 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); | 5537 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); |
5515 | h = QMAX( h, tmph ); | 5538 | h = QMAX( h, tmph ); |
5516 | lineStart->h = h; | 5539 | lineStart->h = h; |
5517 | if ( i < len - 2 || c->c != ' ' ) | 5540 | if ( i < len - 2 || c->c != ' ' ) |
5518 | lastBreak = i; | 5541 | lastBreak = i; |
5519 | } else { | 5542 | } else { |
5520 | tminw += ww; | 5543 | tminw += ww; |
5521 | int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() ); | 5544 | int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() ); |
5522 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); | 5545 | tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); |
5523 | tmph = tmpBaseLine + belowBaseLine; | 5546 | tmph = tmpBaseLine + belowBaseLine; |
5524 | } | 5547 | } |
5525 | 5548 | ||
5526 | c->x = x; | 5549 | c->x = x; |
5527 | x += ww; | 5550 | x += ww; |
5528 | wused = QMAX( wused, x ); | 5551 | wused = QMAX( wused, x ); |
5529 | } | 5552 | } |
5530 | 5553 | ||
5531 | // ### hack. The last char in the paragraph is always invisible, | 5554 | // ### hack. The last char in the paragraph is always invisible, |
5532 | // ### and somehow sometimes has a wrong format. It changes | 5555 | // ### and somehow sometimes has a wrong format. It changes |
5533 | // ### between // layouting and printing. This corrects some | 5556 | // ### between // layouting and printing. This corrects some |
5534 | // ### layouting errors in BiDi mode due to this. | 5557 | // ### layouting errors in BiDi mode due to this. |
5535 | if ( len > 1 && !c->isAnchor() ) { | 5558 | if ( len > 1 && !c->isAnchor() ) { |
5536 | c->format()->removeRef(); | 5559 | c->format()->removeRef(); |
5537 | c->setFormat( string->at( len - 2 ).format() ); | 5560 | c->setFormat( string->at( len - 2 ).format() ); |
5538 | c->format()->addRef(); | 5561 | c->format()->addRef(); |
5539 | } | 5562 | } |
5540 | 5563 | ||
5541 | if ( lineStart ) { | 5564 | if ( lineStart ) { |
5542 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); | 5565 | lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); |
5543 | h = QMAX( h, tmph ); | 5566 | h = QMAX( h, tmph ); |
5544 | lineStart->h = h; | 5567 | lineStart->h = h; |
5545 | // last line in a paragraph is not justified | 5568 | // last line in a paragraph is not justified |
5546 | if ( align == Qt3::AlignJustify || lastChr == QChar_linesep ) | 5569 | if ( align == Qt3::AlignJustify || lastChr == QChar_linesep ) |
5547 | align = Qt3::AlignAuto; | 5570 | align = Qt3::AlignAuto; |
5548 | DO_FLOW( lineStart ); | 5571 | DO_FLOW( lineStart ); |
5549 | lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) ); | 5572 | lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) ); |
5550 | delete lineStart; | 5573 | delete lineStart; |
5551 | } | 5574 | } |
5552 | 5575 | ||
5553 | minw = QMAX( minw, tminw ); | 5576 | minw = QMAX( minw, tminw ); |
5554 | if ( doc ) | 5577 | if ( doc ) |
5555 | minw += doc->rightMargin(); | 5578 | minw += doc->rightMargin(); |
5556 | 5579 | ||
5557 | int m = parag->bottomMargin(); | 5580 | int m = parag->bottomMargin(); |
5558 | if ( !parag->next() ) | 5581 | if ( !parag->next() ) |
5559 | m = 0; | 5582 | m = 0; |
5560 | else | 5583 | else |
5561 | m = QMAX(m, parag->next()->topMargin() ) / 2; | 5584 | m = QMAX(m, parag->next()->topMargin() ) / 2; |
5562 | parag->setFullWidth( fullWidth ); | 5585 | parag->setFullWidth( fullWidth ); |
5563 | y += QMAX( h, linespacing ) + m; | 5586 | y += QMAX( h, linespacing ) + m; |
5564 | 5587 | ||
5565 | wused += rm; | 5588 | wused += rm; |
5566 | if ( !wrapEnabled || wrapAtColumn() != -1 ) | 5589 | if ( !wrapEnabled || wrapAtColumn() != -1 ) |
5567 | minw = QMAX(minw, wused); | 5590 | minw = QMAX(minw, wused); |
5568 | 5591 | ||
5569 | // This is the case where we are breaking wherever we darn well please | 5592 | // This is the case where we are breaking wherever we darn well please |
5570 | // in cases like that, the minw should not be the length of the entire | 5593 | // in cases like that, the minw should not be the length of the entire |
5571 | // word, because we necessarily want to show the word on the whole line. | 5594 | // word, because we necessarily want to show the word on the whole line. |
5572 | // example: word wrap in iconview | 5595 | // example: word wrap in iconview |
5573 | if ( allowBreakInWords() && minw > wused ) | 5596 | if ( allowBreakInWords() && minw > wused ) |
5574 | minw = wused; | 5597 | minw = wused; |
5575 | 5598 | ||
5576 | thisminw = minw; | 5599 | thisminw = minw; |
5577 | thiswused = wused; | 5600 | thiswused = wused; |
5578 | return y; | 5601 | return y; |
5579 | } | 5602 | } |
5580 | 5603 | ||
5581 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5604 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5582 | 5605 | ||
5583 | QTextIndent::QTextIndent() | 5606 | QTextIndent::QTextIndent() |
5584 | { | 5607 | { |
5585 | } | 5608 | } |
5586 | 5609 | ||
5587 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5610 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5588 | 5611 | ||
5589 | QTextFormatCollection::QTextFormatCollection() | 5612 | QTextFormatCollection::QTextFormatCollection() |
5590 | : cKey( 307 ) | 5613 | : cKey( 307 ) |
5591 | { | 5614 | { |
5592 | defFormat = new QTextFormat( QApplication::font(), | 5615 | defFormat = new QTextFormat( QApplication::font(), |
5593 | QApplication::palette().color( QPalette::Active, QColorGroup::Text ) ); | 5616 | QApplication::palette().color( QPalette::Active, QColorGroup::Text ) ); |
5594 | lastFormat = cres = 0; | 5617 | lastFormat = cres = 0; |
5595 | cflags = -1; | 5618 | cflags = -1; |
5596 | cKey.setAutoDelete( TRUE ); | 5619 | cKey.setAutoDelete( TRUE ); |
5597 | cachedFormat = 0; | 5620 | cachedFormat = 0; |
5598 | } | 5621 | } |
5599 | 5622 | ||
5600 | QTextFormatCollection::~QTextFormatCollection() | 5623 | QTextFormatCollection::~QTextFormatCollection() |
5601 | { | 5624 | { |
5602 | delete defFormat; | 5625 | delete defFormat; |
5603 | } | 5626 | } |
5604 | 5627 | ||
5605 | QTextFormat *QTextFormatCollection::format( QTextFormat *f ) | 5628 | QTextFormat *QTextFormatCollection::format( QTextFormat *f ) |
5606 | { | 5629 | { |
5607 | if ( f->parent() == this || f == defFormat ) { | 5630 | if ( f->parent() == this || f == defFormat ) { |
5608 | lastFormat = f; | 5631 | lastFormat = f; |
5609 | lastFormat->addRef(); | 5632 | lastFormat->addRef(); |
5610 | return lastFormat; | 5633 | return lastFormat; |
5611 | } | 5634 | } |
5612 | 5635 | ||
5613 | if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) { | 5636 | if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) { |
5614 | lastFormat->addRef(); | 5637 | lastFormat->addRef(); |
5615 | return lastFormat; | 5638 | return lastFormat; |
5616 | } | 5639 | } |
5617 | 5640 | ||
5618 | QTextFormat *fm = cKey.find( f->key() ); | 5641 | QTextFormat *fm = cKey.find( f->key() ); |
5619 | if ( fm ) { | 5642 | if ( fm ) { |
5620 | lastFormat = fm; | 5643 | lastFormat = fm; |
5621 | lastFormat->addRef(); | 5644 | lastFormat->addRef(); |
5622 | return lastFormat; | 5645 | return lastFormat; |
5623 | } | 5646 | } |
5624 | 5647 | ||
5625 | if ( f->key() == defFormat->key() ) | 5648 | if ( f->key() == defFormat->key() ) |
5626 | return defFormat; | 5649 | return defFormat; |
5627 | 5650 | ||
5628 | lastFormat = createFormat( *f ); | 5651 | lastFormat = createFormat( *f ); |
5629 | lastFormat->collection = this; | 5652 | lastFormat->collection = this; |
5630 | cKey.insert( lastFormat->key(), lastFormat ); | 5653 | cKey.insert( lastFormat->key(), lastFormat ); |
5631 | return lastFormat; | 5654 | return lastFormat; |
5632 | } | 5655 | } |
5633 | 5656 | ||
5634 | QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags ) | 5657 | QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags ) |
5635 | { | 5658 | { |
5636 | if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) { | 5659 | if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) { |
5637 | cres->addRef(); | 5660 | cres->addRef(); |
5638 | return cres; | 5661 | return cres; |
5639 | } | 5662 | } |
5640 | 5663 | ||
5641 | cres = createFormat( *of ); | 5664 | cres = createFormat( *of ); |
5642 | kof = of->key(); | 5665 | kof = of->key(); |
5643 | knf = nf->key(); | 5666 | knf = nf->key(); |
5644 | cflags = flags; | 5667 | cflags = flags; |
5645 | if ( flags & QTextFormat::Bold ) | 5668 | if ( flags & QTextFormat::Bold ) |
5646 | cres->fn.setBold( nf->fn.bold() ); | 5669 | cres->fn.setBold( nf->fn.bold() ); |
5647 | if ( flags & QTextFormat::Italic ) | 5670 | if ( flags & QTextFormat::Italic ) |
5648 | cres->fn.setItalic( nf->fn.italic() ); | 5671 | cres->fn.setItalic( nf->fn.italic() ); |
5649 | if ( flags & QTextFormat::Underline ) | 5672 | if ( flags & QTextFormat::Underline ) |
5650 | cres->fn.setUnderline( nf->fn.underline() ); | 5673 | cres->fn.setUnderline( nf->fn.underline() ); |
5651 | if ( flags & QTextFormat::StrikeOut ) | 5674 | if ( flags & QTextFormat::StrikeOut ) |
5652 | cres->fn.setStrikeOut( nf->fn.strikeOut() ); | 5675 | cres->fn.setStrikeOut( nf->fn.strikeOut() ); |
5653 | if ( flags & QTextFormat::Family ) | 5676 | if ( flags & QTextFormat::Family ) |
5654 | cres->fn.setFamily( nf->fn.family() ); | 5677 | cres->fn.setFamily( nf->fn.family() ); |
5655 | if ( flags & QTextFormat::Size ) { | 5678 | if ( flags & QTextFormat::Size ) { |
5656 | if ( of->usePixelSizes ) | 5679 | if ( of->usePixelSizes ) |
5657 | cres->fn.setPixelSize( nf->fn.pixelSize() ); | 5680 | cres->fn.setPixelSize( nf->fn.pixelSize() ); |
5658 | else | 5681 | else |
5659 | cres->fn.setPointSize( nf->fn.pointSize() ); | 5682 | cres->fn.setPointSize( nf->fn.pointSize() ); |
5660 | } | 5683 | } |
5661 | if ( flags & QTextFormat::Color ) | 5684 | if ( flags & QTextFormat::Color ) |
5662 | cres->col = nf->col; | 5685 | cres->col = nf->col; |
5663 | if ( flags & QTextFormat::Misspelled ) | 5686 | if ( flags & QTextFormat::Misspelled ) |
5664 | cres->missp = nf->missp; | 5687 | cres->missp = nf->missp; |
5665 | if ( flags & QTextFormat::VAlign ) | 5688 | if ( flags & QTextFormat::VAlign ) |
5666 | cres->ha = nf->ha; | 5689 | cres->ha = nf->ha; |
5667 | cres->update(); | 5690 | cres->update(); |
5668 | 5691 | ||
5669 | QTextFormat *fm = cKey.find( cres->key() ); | 5692 | QTextFormat *fm = cKey.find( cres->key() ); |
5670 | if ( !fm ) { | 5693 | if ( !fm ) { |
5671 | cres->collection = this; | 5694 | cres->collection = this; |
5672 | cKey.insert( cres->key(), cres ); | 5695 | cKey.insert( cres->key(), cres ); |
5673 | } else { | 5696 | } else { |
5674 | delete cres; | 5697 | delete cres; |
5675 | cres = fm; | 5698 | cres = fm; |
5676 | cres->addRef(); | 5699 | cres->addRef(); |
5677 | } | 5700 | } |
5678 | 5701 | ||
5679 | return cres; | 5702 | return cres; |
5680 | } | 5703 | } |
5681 | 5704 | ||
5682 | QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c ) | 5705 | QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c ) |
5683 | { | 5706 | { |
5684 | if ( cachedFormat && cfont == f && ccol == c ) { | 5707 | if ( cachedFormat && cfont == f && ccol == c ) { |
5685 | cachedFormat->addRef(); | 5708 | cachedFormat->addRef(); |
5686 | return cachedFormat; | 5709 | return cachedFormat; |
5687 | } | 5710 | } |
5688 | 5711 | ||
5689 | QString key = QTextFormat::getKey( f, c, FALSE, QTextFormat::AlignNormal ); | 5712 | QString key = QTextFormat::getKey( f, c, FALSE, QTextFormat::AlignNormal ); |
5690 | cachedFormat = cKey.find( key ); | 5713 | cachedFormat = cKey.find( key ); |
5691 | cfont = f; | 5714 | cfont = f; |
5692 | ccol = c; | 5715 | ccol = c; |
5693 | 5716 | ||
5694 | if ( cachedFormat ) { | 5717 | if ( cachedFormat ) { |
5695 | cachedFormat->addRef(); | 5718 | cachedFormat->addRef(); |
5696 | return cachedFormat; | 5719 | return cachedFormat; |
5697 | } | 5720 | } |
5698 | 5721 | ||
5699 | if ( key == defFormat->key() ) | 5722 | if ( key == defFormat->key() ) |
5700 | return defFormat; | 5723 | return defFormat; |
5701 | 5724 | ||
5702 | cachedFormat = createFormat( f, c ); | 5725 | cachedFormat = createFormat( f, c ); |
5703 | cachedFormat->collection = this; | 5726 | cachedFormat->collection = this; |
5704 | cKey.insert( cachedFormat->key(), cachedFormat ); | 5727 | cKey.insert( cachedFormat->key(), cachedFormat ); |
5705 | if ( cachedFormat->key() != key ) | 5728 | if ( cachedFormat->key() != key ) |
5706 | owarn << "ASSERT: keys for format not identical: '" << cachedFormat->key().latin1() << " '" << key.latin1() << "'" << oendl; | 5729 | owarn << "ASSERT: keys for format not identical: '" << cachedFormat->key().latin1() << " '" << key.latin1() << "'" << oendl; |
5707 | return cachedFormat; | 5730 | return cachedFormat; |
5708 | } | 5731 | } |
5709 | 5732 | ||
5710 | void QTextFormatCollection::remove( QTextFormat *f ) | 5733 | void QTextFormatCollection::remove( QTextFormat *f ) |
5711 | { | 5734 | { |
5712 | if ( lastFormat == f ) | 5735 | if ( lastFormat == f ) |
5713 | lastFormat = 0; | 5736 | lastFormat = 0; |
5714 | if ( cres == f ) | 5737 | if ( cres == f ) |
5715 | cres = 0; | 5738 | cres = 0; |
5716 | if ( cachedFormat == f ) | 5739 | if ( cachedFormat == f ) |
5717 | cachedFormat = 0; | 5740 | cachedFormat = 0; |
5718 | cKey.remove( f->key() ); | 5741 | cKey.remove( f->key() ); |
5719 | } | 5742 | } |
5720 | 5743 | ||
5721 | #define UPDATE( up, lo, rest ) \ | 5744 | #define UPDATE( up, lo, rest ) \ |
5722 | if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \ | 5745 | if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \ |
5723 | fm->fn.set##up##rest( font.lo##rest() ) | 5746 | fm->fn.set##up##rest( font.lo##rest() ) |
5724 | 5747 | ||
5725 | void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet ) | 5748 | void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet ) |
5726 | { | 5749 | { |
5727 | QDictIterator<QTextFormat> it( cKey ); | 5750 | QDictIterator<QTextFormat> it( cKey ); |
5728 | QTextFormat *fm; | 5751 | QTextFormat *fm; |
5729 | bool usePixels = font.pointSize() == -1; | 5752 | bool usePixels = font.pointSize() == -1; |
5730 | bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() : | 5753 | bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() : |
5731 | font.pointSize() != defFormat->fn.pointSize(); | 5754 | font.pointSize() != defFormat->fn.pointSize(); |
5732 | int base = usePixels ? font.pixelSize() : font.pointSize(); | 5755 | int base = usePixels ? font.pixelSize() : font.pointSize(); |
5733 | while ( ( fm = it.current() ) ) { | 5756 | while ( ( fm = it.current() ) ) { |
5734 | ++it; | 5757 | ++it; |
5735 | UPDATE( F, f, amily ); | 5758 | UPDATE( F, f, amily ); |
5736 | UPDATE( W, w, eight ); | 5759 | UPDATE( W, w, eight ); |
5737 | UPDATE( B, b, old ); | 5760 | UPDATE( B, b, old ); |
5738 | UPDATE( I, i, talic ); | 5761 | UPDATE( I, i, talic ); |
5739 | UPDATE( U, u, nderline ); | 5762 | UPDATE( U, u, nderline ); |
5740 | if ( changeSize ) { | 5763 | if ( changeSize ) { |
5741 | fm->stdSize = base; | 5764 | fm->stdSize = base; |
5742 | fm->usePixelSizes = usePixels; | 5765 | fm->usePixelSizes = usePixels; |
5743 | if ( usePixels ) | 5766 | if ( usePixels ) |
5744 | fm->fn.setPixelSize( fm->stdSize ); | 5767 | fm->fn.setPixelSize( fm->stdSize ); |
5745 | else | 5768 | else |
5746 | fm->fn.setPointSize( fm->stdSize ); | 5769 | fm->fn.setPointSize( fm->stdSize ); |
5747 | sheet->scaleFont( fm->fn, fm->logicalFontSize ); | 5770 | sheet->scaleFont( fm->fn, fm->logicalFontSize ); |
5748 | } | 5771 | } |
5749 | if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col ) | 5772 | if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col ) |
5750 | fm->col = color; | 5773 | fm->col = color; |
5751 | fm->update(); | 5774 | fm->update(); |
5752 | } | 5775 | } |
5753 | 5776 | ||
5754 | defFormat->fn = font; | 5777 | defFormat->fn = font; |
5755 | defFormat->col = color; | 5778 | defFormat->col = color; |
5756 | defFormat->update(); | 5779 | defFormat->update(); |
5757 | defFormat->stdSize = base; | 5780 | defFormat->stdSize = base; |
5758 | defFormat->usePixelSizes = usePixels; | 5781 | defFormat->usePixelSizes = usePixels; |
5759 | 5782 | ||
5760 | updateKeys(); | 5783 | updateKeys(); |
5761 | } | 5784 | } |
5762 | 5785 | ||
5763 | // the keys in cKey have changed, rebuild the hashtable | 5786 | // the keys in cKey have changed, rebuild the hashtable |
5764 | void QTextFormatCollection::updateKeys() | 5787 | void QTextFormatCollection::updateKeys() |
5765 | { | 5788 | { |
5766 | if ( cKey.isEmpty() ) | 5789 | if ( cKey.isEmpty() ) |
5767 | return; | 5790 | return; |
5768 | cKey.setAutoDelete( FALSE ); | 5791 | cKey.setAutoDelete( FALSE ); |
5769 | QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ]; | 5792 | QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ]; |
5770 | QTextFormat **f = formats; | 5793 | QTextFormat **f = formats; |
5771 | QDictIterator<QTextFormat> it( cKey ); | 5794 | QDictIterator<QTextFormat> it( cKey ); |
5772 | while ( ( *f = it.current() ) ) { | 5795 | while ( ( *f = it.current() ) ) { |
5773 | ++it; | 5796 | ++it; |
5774 | ++f; | 5797 | ++f; |
5775 | } | 5798 | } |
5776 | cKey.clear(); | 5799 | cKey.clear(); |
5777 | for ( f = formats; *f; f++ ) | 5800 | for ( f = formats; *f; f++ ) |
5778 | cKey.insert( (*f)->key(), *f ); | 5801 | cKey.insert( (*f)->key(), *f ); |
5779 | cKey.setAutoDelete( TRUE ); | 5802 | cKey.setAutoDelete( TRUE ); |
5780 | delete [] formats; | 5803 | delete [] formats; |
5781 | } | 5804 | } |
5782 | 5805 | ||
5783 | 5806 | ||
5784 | 5807 | ||
5785 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 5808 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5786 | 5809 | ||
5787 | void QTextFormat::setBold( bool b ) | 5810 | void QTextFormat::setBold( bool b ) |
5788 | { | 5811 | { |
5789 | if ( b == fn.bold() ) | 5812 | if ( b == fn.bold() ) |
5790 | return; | 5813 | return; |
5791 | fn.setBold( b ); | 5814 | fn.setBold( b ); |
5792 | update(); | 5815 | update(); |
5793 | } | 5816 | } |
5794 | 5817 | ||
5795 | void QTextFormat::setMisspelled( bool b ) | 5818 | void QTextFormat::setMisspelled( bool b ) |
5796 | { | 5819 | { |
5797 | if ( b == (bool)missp ) | 5820 | if ( b == (bool)missp ) |
5798 | return; | 5821 | return; |
5799 | missp = b; | 5822 | missp = b; |
5800 | update(); | 5823 | update(); |
5801 | } | 5824 | } |
5802 | 5825 | ||
5803 | void QTextFormat::setVAlign( VerticalAlignment a ) | 5826 | void QTextFormat::setVAlign( VerticalAlignment a ) |
5804 | { | 5827 | { |
5805 | if ( a == ha ) | 5828 | if ( a == ha ) |
5806 | return; | 5829 | return; |
5807 | ha = a; | 5830 | ha = a; |
5808 | update(); | 5831 | update(); |
5809 | } | 5832 | } |
5810 | 5833 | ||
5811 | void QTextFormat::setItalic( bool b ) | 5834 | void QTextFormat::setItalic( bool b ) |
5812 | { | 5835 | { |
5813 | if ( b == fn.italic() ) | 5836 | if ( b == fn.italic() ) |
5814 | return; | 5837 | return; |
5815 | fn.setItalic( b ); | 5838 | fn.setItalic( b ); |
5816 | update(); | 5839 | update(); |
5817 | } | 5840 | } |
5818 | 5841 | ||
5819 | void QTextFormat::setUnderline( bool b ) | 5842 | void QTextFormat::setUnderline( bool b ) |
5820 | { | 5843 | { |
5821 | if ( b == fn.underline() ) | 5844 | if ( b == fn.underline() ) |
5822 | return; | 5845 | return; |
5823 | fn.setUnderline( b ); | 5846 | fn.setUnderline( b ); |
5824 | update(); | 5847 | update(); |
5825 | } | 5848 | } |
5826 | 5849 | ||
5827 | void QTextFormat::setStrikeOut( bool b ) | 5850 | void QTextFormat::setStrikeOut( bool b ) |
5828 | { | 5851 | { |
5829 | if ( b == fn.strikeOut() ) | 5852 | if ( b == fn.strikeOut() ) |
5830 | return; | 5853 | return; |
5831 | fn.setStrikeOut( b ); | 5854 | fn.setStrikeOut( b ); |
5832 | update(); | 5855 | update(); |
5833 | } | 5856 | } |
5834 | 5857 | ||
5835 | void QTextFormat::setFamily( const QString &f ) | 5858 | void QTextFormat::setFamily( const QString &f ) |
5836 | { | 5859 | { |
5837 | if ( f == fn.family() ) | 5860 | if ( f == fn.family() ) |
5838 | return; | 5861 | return; |
5839 | fn.setFamily( f ); | 5862 | fn.setFamily( f ); |
5840 | update(); | 5863 | update(); |
5841 | } | 5864 | } |
5842 | 5865 | ||
5843 | void QTextFormat::setPointSize( int s ) | 5866 | void QTextFormat::setPointSize( int s ) |
5844 | { | 5867 | { |
5845 | if ( s == fn.pointSize() ) | 5868 | if ( s == fn.pointSize() ) |
5846 | return; | 5869 | return; |
5847 | fn.setPointSize( s ); | 5870 | fn.setPointSize( s ); |
5848 | usePixelSizes = FALSE; | 5871 | usePixelSizes = FALSE; |
5849 | update(); | 5872 | update(); |
5850 | } | 5873 | } |
5851 | 5874 | ||
5852 | void QTextFormat::setFont( const QFont &f ) | 5875 | void QTextFormat::setFont( const QFont &f ) |
5853 | { | 5876 | { |
5854 | if ( f == fn && !k.isEmpty() ) | 5877 | if ( f == fn && !k.isEmpty() ) |
5855 | return; | 5878 | return; |
5856 | fn = f; | 5879 | fn = f; |
5857 | update(); | 5880 | update(); |
5858 | } | 5881 | } |
5859 | 5882 | ||
5860 | void QTextFormat::setColor( const QColor &c ) | 5883 | void QTextFormat::setColor( const QColor &c ) |
5861 | { | 5884 | { |
5862 | if ( c == col ) | 5885 | if ( c == col ) |
5863 | return; | 5886 | return; |
5864 | col = c; | 5887 | col = c; |
5865 | update(); | 5888 | update(); |
5866 | } | 5889 | } |
5867 | 5890 | ||
5868 | QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, | 5891 | QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, |
5869 | const QString& oldAnchorHref, const QString& anchorHref ) const | 5892 | const QString& oldAnchorHref, const QString& anchorHref ) const |
5870 | { | 5893 | { |
5871 | QString tag; | 5894 | QString tag; |
5872 | if ( f ) | 5895 | if ( f ) |
5873 | tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref ); | 5896 | tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref ); |
5874 | 5897 | ||
5875 | if ( !anchorHref.isEmpty() ) | 5898 | if ( !anchorHref.isEmpty() ) |
5876 | tag += "<a href=\"" + anchorHref + "\">"; | 5899 | tag += "<a href=\"" + anchorHref + "\">"; |
5877 | 5900 | ||
5878 | if ( font() != defaultFormat->font() | 5901 | if ( font() != defaultFormat->font() |
5879 | || vAlign() != defaultFormat->vAlign() | 5902 | || vAlign() != defaultFormat->vAlign() |
5880 | || color().rgb() != defaultFormat->color().rgb() ) { | 5903 | || color().rgb() != defaultFormat->color().rgb() ) { |
5881 | QString s; | 5904 | QString s; |
5882 | if ( font().family() != defaultFormat->font().family() ) | 5905 | if ( font().family() != defaultFormat->font().family() ) |
5883 | s += QString(!!s?";":"") + "font-family:" + fn.family(); | 5906 | s += QString(!!s?";":"") + "font-family:" + fn.family(); |
5884 | if ( font().italic() && font().italic() != defaultFormat->font().italic() ) | 5907 | if ( font().italic() && font().italic() != defaultFormat->font().italic() ) |
5885 | s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal"); | 5908 | s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal"); |
5886 | if ( font().pointSize() != defaultFormat->font().pointSize() ) | 5909 | if ( font().pointSize() != defaultFormat->font().pointSize() ) |
5887 | s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt"; | 5910 | s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt"; |
5888 | if ( font().weight() != defaultFormat->font().weight() ) | 5911 | if ( font().weight() != defaultFormat->font().weight() ) |
5889 | s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 ); | 5912 | s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 ); |
5890 | if ( font().underline() != defaultFormat->font().underline() ) | 5913 | if ( font().underline() != defaultFormat->font().underline() ) |
5891 | s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none"); | 5914 | s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none"); |
5892 | if ( vAlign() != defaultFormat->vAlign() ) { | 5915 | if ( vAlign() != defaultFormat->vAlign() ) { |
5893 | s += QString(!!s?";":"") + "vertical-align:"; | 5916 | s += QString(!!s?";":"") + "vertical-align:"; |
5894 | if ( vAlign() == QTextFormat::AlignSuperScript ) | 5917 | if ( vAlign() == QTextFormat::AlignSuperScript ) |
5895 | s += "super"; | 5918 | s += "super"; |
5896 | else if ( vAlign() == QTextFormat::AlignSubScript ) | 5919 | else if ( vAlign() == QTextFormat::AlignSubScript ) |
5897 | s += "sub"; | 5920 | s += "sub"; |
5898 | else | 5921 | else |
5899 | s += "normal"; | 5922 | s += "normal"; |
5900 | } | 5923 | } |
5901 | if ( color().rgb() != defaultFormat->color().rgb() ) | 5924 | if ( color().rgb() != defaultFormat->color().rgb() ) |
5902 | s += QString(!!s?";":"") + "color:" + col.name(); | 5925 | s += QString(!!s?";":"") + "color:" + col.name(); |
5903 | if ( !s.isEmpty() ) | 5926 | if ( !s.isEmpty() ) |
5904 | tag += "<span style=\"" + s + "\">"; | 5927 | tag += "<span style=\"" + s + "\">"; |
5905 | } | 5928 | } |
5906 | 5929 | ||
5907 | return tag; | 5930 | return tag; |
5908 | } | 5931 | } |
5909 | 5932 | ||
5910 | QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const | 5933 | QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const |
5911 | { | 5934 | { |
5912 | QString tag; | 5935 | QString tag; |
5913 | if ( font().family() != defaultFormat->font().family() | 5936 | if ( font().family() != defaultFormat->font().family() |
5914 | || font().pointSize() != defaultFormat->font().pointSize() | 5937 | || font().pointSize() != defaultFormat->font().pointSize() |
5915 | || font().weight() != defaultFormat->font().weight() | 5938 | || font().weight() != defaultFormat->font().weight() |
5916 | || font().italic() != defaultFormat->font().italic() | 5939 | || font().italic() != defaultFormat->font().italic() |
5917 | || font().underline() != defaultFormat->font().underline() | 5940 | || font().underline() != defaultFormat->font().underline() |
5918 | || font().strikeOut() != defaultFormat->font().strikeOut() | 5941 | || font().strikeOut() != defaultFormat->font().strikeOut() |
5919 | || vAlign() != defaultFormat->vAlign() | 5942 | || vAlign() != defaultFormat->vAlign() |
5920 | || color().rgb() != defaultFormat->color().rgb() ) | 5943 | || color().rgb() != defaultFormat->color().rgb() ) |
5921 | tag += "</span>"; | 5944 | tag += "</span>"; |
5922 | if ( !anchorHref.isEmpty() ) | 5945 | if ( !anchorHref.isEmpty() ) |
5923 | tag += "</a>"; | 5946 | tag += "</a>"; |
5924 | return tag; | 5947 | return tag; |
5925 | } | 5948 | } |
5926 | 5949 | ||
5927 | QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const | 5950 | QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const |
5928 | { | 5951 | { |
5929 | QTextFormat format(*this); | 5952 | QTextFormat format(*this); |
5930 | if (!style ) | 5953 | if (!style ) |
5931 | return format; | 5954 | return format; |
5932 | 5955 | ||
5933 | if ( !style->isAnchor() && style->color().isValid() ) { | 5956 | if ( !style->isAnchor() && style->color().isValid() ) { |
5934 | // the style is not an anchor and defines a color. | 5957 | // the style is not an anchor and defines a color. |
5935 | // It might be used inside an anchor and it should | 5958 | // It might be used inside an anchor and it should |
5936 | // override the link color. | 5959 | // override the link color. |
5937 | format.linkColor = FALSE; | 5960 | format.linkColor = FALSE; |
5938 | } | 5961 | } |
5939 | switch ( style->verticalAlignment() ) { | 5962 | switch ( style->verticalAlignment() ) { |
5940 | case QStyleSheetItem::VAlignBaseline: | 5963 | case QStyleSheetItem::VAlignBaseline: |
5941 | format.setVAlign( QTextFormat::AlignNormal ); | 5964 | format.setVAlign( QTextFormat::AlignNormal ); |
5942 | break; | 5965 | break; |
5943 | case QStyleSheetItem::VAlignSuper: | 5966 | case QStyleSheetItem::VAlignSuper: |
5944 | format.setVAlign( QTextFormat::AlignSuperScript ); | 5967 | format.setVAlign( QTextFormat::AlignSuperScript ); |
5945 | break; | 5968 | break; |
5946 | case QStyleSheetItem::VAlignSub: | 5969 | case QStyleSheetItem::VAlignSub: |
5947 | format.setVAlign( QTextFormat::AlignSubScript ); | 5970 | format.setVAlign( QTextFormat::AlignSubScript ); |
5948 | break; | 5971 | break; |
5949 | } | 5972 | } |
5950 | 5973 | ||
5951 | if ( style->fontWeight() != QStyleSheetItem::Undefined ) | 5974 | if ( style->fontWeight() != QStyleSheetItem::Undefined ) |
5952 | format.fn.setWeight( style->fontWeight() ); | 5975 | format.fn.setWeight( style->fontWeight() ); |
5953 | if ( style->fontSize() != QStyleSheetItem::Undefined ) { | 5976 | if ( style->fontSize() != QStyleSheetItem::Undefined ) { |
5954 | format.fn.setPointSize( style->fontSize() ); | 5977 | format.fn.setPointSize( style->fontSize() ); |
5955 | } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) { | 5978 | } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) { |
5956 | format.logicalFontSize = style->logicalFontSize(); | 5979 | format.logicalFontSize = style->logicalFontSize(); |
5957 | if ( format.usePixelSizes ) | 5980 | if ( format.usePixelSizes ) |
5958 | format.fn.setPixelSize( format.stdSize ); | 5981 | format.fn.setPixelSize( format.stdSize ); |
5959 | else | 5982 | else |
5960 | format.fn.setPointSize( format.stdSize ); | 5983 | format.fn.setPointSize( format.stdSize ); |
5961 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); | 5984 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); |
5962 | } else if ( style->logicalFontSizeStep() ) { | 5985 | } else if ( style->logicalFontSizeStep() ) { |
5963 | format.logicalFontSize += style->logicalFontSizeStep(); | 5986 | format.logicalFontSize += style->logicalFontSizeStep(); |
5964 | if ( format.usePixelSizes ) | 5987 | if ( format.usePixelSizes ) |
5965 | format.fn.setPixelSize( format.stdSize ); | 5988 | format.fn.setPixelSize( format.stdSize ); |
5966 | else | 5989 | else |
5967 | format.fn.setPointSize( format.stdSize ); | 5990 | format.fn.setPointSize( format.stdSize ); |
5968 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); | 5991 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); |
5969 | } | 5992 | } |
5970 | if ( !style->fontFamily().isEmpty() ) | 5993 | if ( !style->fontFamily().isEmpty() ) |
5971 | format.fn.setFamily( style->fontFamily() ); | 5994 | format.fn.setFamily( style->fontFamily() ); |
5972 | if ( style->color().isValid() ) | 5995 | if ( style->color().isValid() ) |
5973 | format.col = style->color(); | 5996 | format.col = style->color(); |
5974 | if ( style->definesFontItalic() ) | 5997 | if ( style->definesFontItalic() ) |
5975 | format.fn.setItalic( style->fontItalic() ); | 5998 | format.fn.setItalic( style->fontItalic() ); |
5976 | if ( style->definesFontUnderline() ) | 5999 | if ( style->definesFontUnderline() ) |
5977 | format.fn.setUnderline( style->fontUnderline() ); | 6000 | format.fn.setUnderline( style->fontUnderline() ); |
5978 | if ( style->definesFontStrikeOut() ) | 6001 | if ( style->definesFontStrikeOut() ) |
5979 | format.fn.setStrikeOut( style->fontStrikeOut() ); | 6002 | format.fn.setStrikeOut( style->fontStrikeOut() ); |
5980 | 6003 | ||
5981 | 6004 | ||
5982 | if ( style->name() == "font") { | 6005 | if ( style->name() == "font") { |
5983 | if ( attr.contains("color") ) { | 6006 | if ( attr.contains("color") ) { |
5984 | QString s = attr["color"]; | 6007 | QString s = attr["color"]; |
5985 | if ( !s.isEmpty() ) { | 6008 | if ( !s.isEmpty() ) { |
5986 | format.col.setNamedColor( s ); | 6009 | format.col.setNamedColor( s ); |
5987 | format.linkColor = FALSE; | 6010 | format.linkColor = FALSE; |
5988 | } | 6011 | } |
5989 | } | 6012 | } |
5990 | if ( attr.contains("face") ) { | 6013 | if ( attr.contains("face") ) { |
5991 | QString a = attr["face"]; | 6014 | QString a = attr["face"]; |
5992 | QString family = QTextDocument::section( a, ",", 0, 0 ); | 6015 | QString family = QTextDocument::section( a, ",", 0, 0 ); |
5993 | if ( !!family ) | 6016 | if ( !!family ) |
5994 | format.fn.setFamily( family ); | 6017 | format.fn.setFamily( family ); |
5995 | } | 6018 | } |
5996 | if ( attr.contains("size") ) { | 6019 | if ( attr.contains("size") ) { |
5997 | QString a = attr["size"]; | 6020 | QString a = attr["size"]; |
5998 | int n = a.toInt(); | 6021 | int n = a.toInt(); |
5999 | if ( a[0] == '+' || a[0] == '-' ) | 6022 | if ( a[0] == '+' || a[0] == '-' ) |
6000 | n += format.logicalFontSize; | 6023 | n += format.logicalFontSize; |
6001 | format.logicalFontSize = n; | 6024 | format.logicalFontSize = n; |
6002 | if ( format.usePixelSizes ) | 6025 | if ( format.usePixelSizes ) |
6003 | format.fn.setPixelSize( format.stdSize ); | 6026 | format.fn.setPixelSize( format.stdSize ); |
6004 | else | 6027 | else |
6005 | format.fn.setPointSize( format.stdSize ); | 6028 | format.fn.setPointSize( format.stdSize ); |
6006 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); | 6029 | style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); |
6007 | } | 6030 | } |
6008 | } | 6031 | } |
6009 | if ( attr.contains("style" ) ) { | 6032 | if ( attr.contains("style" ) ) { |
6010 | QString a = attr["style"]; | 6033 | QString a = attr["style"]; |
6011 | for ( int s = 0; s < a.contains(';')+1; s++ ) { | 6034 | for ( int s = 0; s < a.contains(';')+1; s++ ) { |
6012 | QString style = QTextDocument::section( a, ";", s, s ); | 6035 | QString style = QTextDocument::section( a, ";", s, s ); |
6013 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { | 6036 | if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { |
6014 | format.logicalFontSize = 0; | 6037 | format.logicalFontSize = 0; |
6015 | format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) ); | 6038 | format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) ); |
6016 | } if ( style.startsWith("font-style:" ) ) { | 6039 | } if ( style.startsWith("font-style:" ) ) { |
6017 | QString s = style.mid( 11 ).stripWhiteSpace(); | 6040 | QString s = style.mid( 11 ).stripWhiteSpace(); |
6018 | if ( s == "normal" ) | 6041 | if ( s == "normal" ) |
6019 | format.fn.setItalic( FALSE ); | 6042 | format.fn.setItalic( FALSE ); |
6020 | else if ( s == "italic" || s == "oblique" ) | 6043 | else if ( s == "italic" || s == "oblique" ) |
6021 | format.fn.setItalic( TRUE ); | 6044 | format.fn.setItalic( TRUE ); |
6022 | } else if ( style.startsWith("font-weight:" ) ) { | 6045 | } else if ( style.startsWith("font-weight:" ) ) { |
6023 | QString s = style.mid( 12 ); | 6046 | QString s = style.mid( 12 ); |
6024 | bool ok = TRUE; | 6047 | bool ok = TRUE; |
6025 | int n = s.toInt( &ok ); | 6048 | int n = s.toInt( &ok ); |
6026 | if ( ok ) | 6049 | if ( ok ) |
6027 | format.fn.setWeight( n/8 ); | 6050 | format.fn.setWeight( n/8 ); |
6028 | } else if ( style.startsWith("font-family:" ) ) { | 6051 | } else if ( style.startsWith("font-family:" ) ) { |
6029 | format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() ); | 6052 | format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() ); |
6030 | } else if ( style.startsWith("text-decoration:" ) ) { | 6053 | } else if ( style.startsWith("text-decoration:" ) ) { |
6031 | QString s = style.mid( 16 ).stripWhiteSpace(); | 6054 | QString s = style.mid( 16 ).stripWhiteSpace(); |
6032 | format.fn.setUnderline( s == "underline" ); | 6055 | format.fn.setUnderline( s == "underline" ); |
6033 | } else if ( style.startsWith("vertical-align:" ) ) { | 6056 | } else if ( style.startsWith("vertical-align:" ) ) { |
6034 | QString s = style.mid( 15 ).stripWhiteSpace(); | 6057 | QString s = style.mid( 15 ).stripWhiteSpace(); |
6035 | if ( s == "sub" ) | 6058 | if ( s == "sub" ) |
6036 | format.setVAlign( QTextFormat::AlignSubScript ); | 6059 | format.setVAlign( QTextFormat::AlignSubScript ); |
6037 | else if ( s == "super" ) | 6060 | else if ( s == "super" ) |
6038 | format.setVAlign( QTextFormat::AlignSuperScript ); | 6061 | format.setVAlign( QTextFormat::AlignSuperScript ); |
6039 | else | 6062 | else |
6040 | format.setVAlign( QTextFormat::AlignNormal ); | 6063 | format.setVAlign( QTextFormat::AlignNormal ); |
6041 | } else if ( style.startsWith("color:" ) ) { | 6064 | } else if ( style.startsWith("color:" ) ) { |
6042 | format.col.setNamedColor( style.mid(6) ); | 6065 | format.col.setNamedColor( style.mid(6) ); |
6043 | format.linkColor = FALSE; | 6066 | format.linkColor = FALSE; |
6044 | } | 6067 | } |
6045 | } | 6068 | } |
6046 | } | 6069 | } |
6047 | 6070 | ||
6048 | format.update(); | 6071 | format.update(); |
6049 | return format; | 6072 | return format; |
6050 | } | 6073 | } |
6051 | 6074 | ||
6052 | struct QPixmapInt | 6075 | struct QPixmapInt |
6053 | { | 6076 | { |
6054 | QPixmapInt() : ref( 0 ) {} | 6077 | QPixmapInt() : ref( 0 ) {} |
6055 | QPixmap pm; | 6078 | QPixmap pm; |
6056 | int ref; | 6079 | int ref; |
6057 | }; | 6080 | }; |
6058 | 6081 | ||
6059 | static QMap<QString, QPixmapInt> *pixmap_map = 0; | 6082 | static QMap<QString, QPixmapInt> *pixmap_map = 0; |
6060 | 6083 | ||
6061 | QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context, | 6084 | QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context, |
6062 | QMimeSourceFactory &factory ) | 6085 | QMimeSourceFactory &factory ) |
6063 | : QTextCustomItem( p ), reg( 0 ) | 6086 | : QTextCustomItem( p ), reg( 0 ) |
6064 | { | 6087 | { |
6065 | width = height = 0; | 6088 | width = height = 0; |
6066 | if ( attr.contains("width") ) | 6089 | if ( attr.contains("width") ) |
6067 | width = attr["width"].toInt(); | 6090 | width = attr["width"].toInt(); |
6068 | if ( attr.contains("height") ) | 6091 | if ( attr.contains("height") ) |
6069 | height = attr["height"].toInt(); | 6092 | height = attr["height"].toInt(); |
6070 | 6093 | ||
6071 | QString imageName = attr["src"]; | 6094 | QString imageName = attr["src"]; |
6072 | 6095 | ||
6073 | if (!imageName) | 6096 | if (!imageName) |
6074 | imageName = attr["source"]; | 6097 | imageName = attr["source"]; |
6075 | 6098 | ||
6076 | if ( !imageName.isEmpty() ) { | 6099 | if ( !imageName.isEmpty() ) { |
6077 | imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory ); | 6100 | imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory ); |
6078 | if ( !pixmap_map ) | 6101 | if ( !pixmap_map ) |
6079 | pixmap_map = new QMap<QString, QPixmapInt>; | 6102 | pixmap_map = new QMap<QString, QPixmapInt>; |
6080 | if ( pixmap_map->contains( imgId ) ) { | 6103 | if ( pixmap_map->contains( imgId ) ) { |
6081 | QPixmapInt& pmi = pixmap_map->operator[](imgId); | 6104 | QPixmapInt& pmi = pixmap_map->operator[](imgId); |
6082 | pm = pmi.pm; | 6105 | pm = pmi.pm; |
6083 | pmi.ref++; | 6106 | pmi.ref++; |
6084 | width = pm.width(); | 6107 | width = pm.width(); |
6085 | height = pm.height(); | 6108 | height = pm.height(); |
6086 | } else { | 6109 | } else { |
6087 | QImage img; | 6110 | QImage img; |
6088 | const QMimeSource* m = | 6111 | const QMimeSource* m = |
6089 | factory.data( imageName, context ); | 6112 | factory.data( imageName, context ); |
6090 | if ( !m ) { | 6113 | if ( !m ) { |
6091 | owarn << "QTextImage: no mimesource for " << imageName.latin1() << "" << oendl; | 6114 | owarn << "QTextImage: no mimesource for " << imageName.latin1() << "" << oendl; |
6092 | } | 6115 | } |
6093 | else { | 6116 | else { |
6094 | if ( !QImageDrag::decode( m, img ) ) { | 6117 | if ( !QImageDrag::decode( m, img ) ) { |
6095 | owarn << "QTextImage: cannot decode " << imageName.latin1() << "" << oendl; | 6118 | owarn << "QTextImage: cannot decode " << imageName.latin1() << "" << oendl; |
6096 | } | 6119 | } |
6097 | } | 6120 | } |
6098 | 6121 | ||
6099 | if ( !img.isNull() ) { | 6122 | if ( !img.isNull() ) { |
6100 | if ( width == 0 ) { | 6123 | if ( width == 0 ) { |
6101 | width = img.width(); | 6124 | width = img.width(); |
6102 | if ( height != 0 ) { | 6125 | if ( height != 0 ) { |
6103 | width = img.width() * height / img.height(); | 6126 | width = img.width() * height / img.height(); |
6104 | } | 6127 | } |
6105 | } | 6128 | } |
6106 | if ( height == 0 ) { | 6129 | if ( height == 0 ) { |
6107 | height = img.height(); | 6130 | height = img.height(); |
6108 | if ( width != img.width() ) { | 6131 | if ( width != img.width() ) { |
6109 | height = img.height() * width / img.width(); | 6132 | height = img.height() * width / img.width(); |
6110 | } | 6133 | } |
6111 | } | 6134 | } |
6112 | if ( img.width() != width || img.height() != height ){ | 6135 | if ( img.width() != width || img.height() != height ){ |
6113 | #ifndef QT_NO_IMAGE_SMOOTHSCALE | 6136 | #ifndef QT_NO_IMAGE_SMOOTHSCALE |
6114 | img = img.smoothScale(width, height); | 6137 | img = img.smoothScale(width, height); |
6115 | #endif | 6138 | #endif |
6116 | width = img.width(); | 6139 | width = img.width(); |
6117 | height = img.height(); | 6140 | height = img.height(); |
6118 | } | 6141 | } |
6119 | pm.convertFromImage( img ); | 6142 | pm.convertFromImage( img ); |
6120 | } | 6143 | } |
6121 | if ( !pm.isNull() ) { | 6144 | if ( !pm.isNull() ) { |
6122 | QPixmapInt& pmi = pixmap_map->operator[](imgId); | 6145 | QPixmapInt& pmi = pixmap_map->operator[](imgId); |
6123 | pmi.pm = pm; | 6146 | pmi.pm = pm; |
6124 | pmi.ref++; | 6147 | pmi.ref++; |
6125 | } | 6148 | } |
6126 | } | 6149 | } |
6127 | if ( pm.mask() ) { | 6150 | if ( pm.mask() ) { |
6128 | QRegion mask( *pm.mask() ); | 6151 | QRegion mask( *pm.mask() ); |
6129 | QRegion all( 0, 0, pm.width(), pm.height() ); | 6152 | QRegion all( 0, 0, pm.width(), pm.height() ); |
6130 | reg = new QRegion( all.subtract( mask ) ); | 6153 | reg = new QRegion( all.subtract( mask ) ); |
6131 | } | 6154 | } |
6132 | } | 6155 | } |
6133 | 6156 | ||
6134 | if ( pm.isNull() && (width*height)==0 ) | 6157 | if ( pm.isNull() && (width*height)==0 ) |
6135 | width = height = 50; | 6158 | width = height = 50; |
6136 | 6159 | ||
6137 | place = PlaceInline; | 6160 | place = PlaceInline; |
6138 | if ( attr["align"] == "left" ) | 6161 | if ( attr["align"] == "left" ) |
6139 | place = PlaceLeft; | 6162 | place = PlaceLeft; |
6140 | else if ( attr["align"] == "right" ) | 6163 | else if ( attr["align"] == "right" ) |
6141 | place = PlaceRight; | 6164 | place = PlaceRight; |
6142 | 6165 | ||
6143 | tmpwidth = width; | 6166 | tmpwidth = width; |
6144 | tmpheight = height; | 6167 | tmpheight = height; |
6145 | 6168 | ||
6146 | attributes = attr; | 6169 | attributes = attr; |
6147 | } | 6170 | } |
6148 | 6171 | ||
6149 | QTextImage::~QTextImage() | 6172 | QTextImage::~QTextImage() |
6150 | { | 6173 | { |
6151 | delete reg; | 6174 | delete reg; |
6152 | if ( pixmap_map && pixmap_map->contains( imgId ) ) { | 6175 | if ( pixmap_map && pixmap_map->contains( imgId ) ) { |
6153 | QPixmapInt& pmi = pixmap_map->operator[](imgId); | 6176 | QPixmapInt& pmi = pixmap_map->operator[](imgId); |
6154 | pmi.ref--; | 6177 | pmi.ref--; |
6155 | if ( !pmi.ref ) { | 6178 | if ( !pmi.ref ) { |
6156 | pixmap_map->remove( imgId ); | 6179 | pixmap_map->remove( imgId ); |
6157 | if ( pixmap_map->isEmpty() ) { | 6180 | if ( pixmap_map->isEmpty() ) { |
6158 | delete pixmap_map; | 6181 | delete pixmap_map; |
6159 | pixmap_map = 0; | 6182 | pixmap_map = 0; |
6160 | } | 6183 | } |
6161 | } | 6184 | } |
6162 | } | 6185 | } |
6163 | } | 6186 | } |
6164 | 6187 | ||
6165 | QString QTextImage::richText() const | 6188 | QString QTextImage::richText() const |
6166 | { | 6189 | { |
6167 | QString s; | 6190 | QString s; |
6168 | s += "<img "; | 6191 | s += "<img "; |
6169 | QMap<QString, QString>::ConstIterator it = attributes.begin(); | 6192 | QMap<QString, QString>::ConstIterator it = attributes.begin(); |
6170 | for ( ; it != attributes.end(); ++it ) | 6193 | for ( ; it != attributes.end(); ++it ) |
6171 | s += it.key() + "=" + *it + " "; | 6194 | s += it.key() + "=" + *it + " "; |
6172 | s += ">"; | 6195 | s += ">"; |
6173 | return s; | 6196 | return s; |
6174 | } | 6197 | } |
6175 | 6198 | ||
6176 | void QTextImage::adjustToPainter( QPainter* p ) | 6199 | void QTextImage::adjustToPainter( QPainter* p ) |
6177 | { | 6200 | { |
6178 | width = scale( tmpwidth, p ); | 6201 | width = scale( tmpwidth, p ); |
6179 | height = scale( tmpheight, p ); | 6202 | height = scale( tmpheight, p ); |
6180 | } | 6203 | } |
6181 | 6204 | ||
6182 | #if !defined(Q_WS_X11) | 6205 | #if !defined(Q_WS_X11) |
6183 | #include <qbitmap.h> | 6206 | #include <qbitmap.h> |
6184 | #include "qcleanuphandler.h" | 6207 | #include "qcleanuphandler.h" |
6185 | static QPixmap *qrt_selection = 0; | 6208 | static QPixmap *qrt_selection = 0; |
6186 | static QSingleCleanupHandler<QPixmap> qrt_cleanup_pixmap; | 6209 | static QSingleCleanupHandler<QPixmap> qrt_cleanup_pixmap; |
6187 | static void qrt_createSelectionPixmap( const QColorGroup &cg ) | 6210 | static void qrt_createSelectionPixmap( const QColorGroup &cg ) |
6188 | { | 6211 | { |
6189 | qrt_selection = new QPixmap( 2, 2 ); | 6212 | qrt_selection = new QPixmap( 2, 2 ); |
6190 | qrt_cleanup_pixmap.set( &qrt_selection ); | 6213 | qrt_cleanup_pixmap.set( &qrt_selection ); |
6191 | qrt_selection->fill( Qt::color0 ); | 6214 | qrt_selection->fill( Qt::color0 ); |
6192 | QBitmap m( 2, 2 ); | 6215 | QBitmap m( 2, 2 ); |
6193 | m.fill( Qt::color1 ); | 6216 | m.fill( Qt::color1 ); |
6194 | QPainter p( &m ); | 6217 | QPainter p( &m ); |
6195 | p.setPen( Qt::color0 ); | 6218 | p.setPen( Qt::color0 ); |
6196 | for ( int j = 0; j < 2; ++j ) { | 6219 | for ( int j = 0; j < 2; ++j ) { |
6197 | p.drawPoint( j % 2, j ); | 6220 | p.drawPoint( j % 2, j ); |
6198 | } | 6221 | } |
6199 | p.end(); | 6222 | p.end(); |
6200 | qrt_selection->setMask( m ); | 6223 | qrt_selection->setMask( m ); |
6201 | qrt_selection->fill( cg.highlight() ); | 6224 | qrt_selection->fill( cg.highlight() ); |
6202 | } | 6225 | } |
6203 | #endif | 6226 | #endif |
6204 | 6227 | ||
6205 | void QTextImage::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) | 6228 | void QTextImage::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) |
6206 | { | 6229 | { |
6207 | if ( placement() != PlaceInline ) { | 6230 | if ( placement() != PlaceInline ) { |
6208 | x = xpos; | 6231 | x = xpos; |
6209 | y = ypos; | 6232 | y = ypos; |
6210 | } | 6233 | } |
6211 | 6234 | ||
6212 | if ( pm.isNull() ) { | 6235 | if ( pm.isNull() ) { |
6213 | p->fillRect( x , y, width, height, cg.dark() ); | 6236 | p->fillRect( x , y, width, height, cg.dark() ); |
6214 | return; | 6237 | return; |
6215 | } | 6238 | } |
6216 | 6239 | ||
6217 | if ( is_printer( p ) ) { | 6240 | if ( is_printer( p ) ) { |
6218 | p->drawPixmap( x, y, pm ); | 6241 | p->drawPixmap( x, y, pm ); |
6219 | return; | 6242 | return; |
6220 | } | 6243 | } |
6221 | 6244 | ||
6222 | if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) ) | 6245 | if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) ) |
6223 | return; | 6246 | return; |
6224 | 6247 | ||
6225 | if ( placement() == PlaceInline ) | 6248 | if ( placement() == PlaceInline ) |
6226 | p->drawPixmap( x , y, pm ); | 6249 | p->drawPixmap( x , y, pm ); |
6227 | else | 6250 | else |
6228 | p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch ); | 6251 | p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch ); |
6229 | 6252 | ||
6230 | if ( selected && placement() == PlaceInline && is_printer( p ) ) { | 6253 | if ( selected && placement() == PlaceInline && is_printer( p ) ) { |
6231 | #if defined(Q_WS_X11) | 6254 | #if defined(Q_WS_X11) |
6232 | p->fillRect( QRect( QPoint( x, y ), pm.size() ), QBrush( cg.highlight(), QBrush::Dense4Pattern) ); | 6255 | p->fillRect( QRect( QPoint( x, y ), pm.size() ), QBrush( cg.highlight(), QBrush::Dense4Pattern) ); |
6233 | #else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it | 6256 | #else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it |
6234 | if ( !qrt_selection ) | 6257 | if ( !qrt_selection ) |
6235 | qrt_createSelectionPixmap( cg ); | 6258 | qrt_createSelectionPixmap( cg ); |
6236 | p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection ); | 6259 | p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection ); |
6237 | #endif | 6260 | #endif |
6238 | } | 6261 | } |
6239 | } | 6262 | } |
6240 | 6263 | ||
6241 | void QTextHorizontalLine::adjustToPainter( QPainter* p ) | 6264 | void QTextHorizontalLine::adjustToPainter( QPainter* p ) |
6242 | { | 6265 | { |
6243 | height = scale( tmpheight, p ); | 6266 | height = scale( tmpheight, p ); |
6244 | } | 6267 | } |
6245 | 6268 | ||
6246 | 6269 | ||
6247 | QTextHorizontalLine::QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr, | 6270 | QTextHorizontalLine::QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr, |
6248 | const QString &, | 6271 | const QString &, |
6249 | QMimeSourceFactory & ) | 6272 | QMimeSourceFactory & ) |
6250 | : QTextCustomItem( p ) | 6273 | : QTextCustomItem( p ) |
6251 | { | 6274 | { |
6252 | height = tmpheight = 8; | 6275 | height = tmpheight = 8; |
6253 | if ( attr.find( "color" ) != attr.end() ) | 6276 | if ( attr.find( "color" ) != attr.end() ) |
6254 | color = QColor( *attr.find( "color" ) ); | 6277 | color = QColor( *attr.find( "color" ) ); |
6255 | } | 6278 | } |
6256 | 6279 | ||
6257 | QTextHorizontalLine::~QTextHorizontalLine() | 6280 | QTextHorizontalLine::~QTextHorizontalLine() |
6258 | { | 6281 | { |
6259 | } | 6282 | } |
6260 | 6283 | ||
6261 | QString QTextHorizontalLine::richText() const | 6284 | QString QTextHorizontalLine::richText() const |
6262 | { | 6285 | { |
6263 | return "<hr>"; | 6286 | return "<hr>"; |
6264 | } | 6287 | } |
6265 | 6288 | ||
6266 | void QTextHorizontalLine::draw( QPainter* p, int x, int y, int , int , int , int , const QColorGroup& cg, bool selected ) | 6289 | void QTextHorizontalLine::draw( QPainter* p, int x, int y, int , int , int , int , const QColorGroup& cg, bool selected ) |
6267 | { | 6290 | { |
6268 | QRect r( x, y, width, height); | 6291 | QRect r( x, y, width, height); |
6269 | if ( is_printer( p ) ) { | 6292 | if ( is_printer( p ) ) { |
6270 | QPen oldPen = p->pen(); | 6293 | QPen oldPen = p->pen(); |
6271 | if ( !color.isValid() ) | 6294 | if ( !color.isValid() ) |
6272 | p->setPen( QPen( cg.text(), height/8 ) ); | 6295 | p->setPen( QPen( cg.text(), height/8 ) ); |
6273 | else | 6296 | else |
6274 | p->setPen( QPen( color, height/8 ) ); | 6297 | p->setPen( QPen( color, height/8 ) ); |
6275 | p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 ); | 6298 | p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 ); |
6276 | p->setPen( oldPen ); | 6299 | p->setPen( oldPen ); |
6277 | } else { | 6300 | } else { |
6278 | QColorGroup g( cg ); | 6301 | QColorGroup g( cg ); |
6279 | if ( color.isValid() ) | 6302 | if ( color.isValid() ) |
6280 | g.setColor( QColorGroup::Dark, color ); | 6303 | g.setColor( QColorGroup::Dark, color ); |
6281 | if ( selected ) | 6304 | if ( selected ) |
6282 | p->fillRect( r.left(), y, r.right(), y + height, g.highlight() ); | 6305 | p->fillRect( r.left(), y, r.right(), y + height, g.highlight() ); |
6283 | qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 ); | 6306 | qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 ); |
6284 | } | 6307 | } |
6285 | } | 6308 | } |
6286 | 6309 | ||
6287 | 6310 | ||
6288 | /*****************************************************************/ | 6311 | /*****************************************************************/ |
6289 | // Small set of utility functions to make the parser a bit simpler | 6312 | // Small set of utility functions to make the parser a bit simpler |
6290 | // | 6313 | // |
6291 | 6314 | ||
6292 | bool QTextDocument::hasPrefix(const QChar* doc, int length, int pos, QChar c) | 6315 | bool QTextDocument::hasPrefix(const QChar* doc, int length, int pos, QChar c) |
6293 | { | 6316 | { |
6294 | if ( pos >= length ) | 6317 | if ( pos >= length ) |
6295 | return FALSE; | 6318 | return FALSE; |
6296 | return doc[ pos ].lower() == c.lower(); | 6319 | return doc[ pos ].lower() == c.lower(); |
6297 | } | 6320 | } |
6298 | 6321 | ||
6299 | bool QTextDocument::hasPrefix( const QChar* doc, int length, int pos, const QString& s ) | 6322 | bool QTextDocument::hasPrefix( const QChar* doc, int length, int pos, const QString& s ) |
6300 | { | 6323 | { |
6301 | if ( pos + (int) s.length() >= length ) | 6324 | if ( pos + (int) s.length() >= length ) |
6302 | return FALSE; | 6325 | return FALSE; |
6303 | for ( int i = 0; i < (int)s.length(); i++ ) { | 6326 | for ( int i = 0; i < (int)s.length(); i++ ) { |
6304 | if ( doc[ pos + i ].lower() != s[ i ].lower() ) | 6327 | if ( doc[ pos + i ].lower() != s[ i ].lower() ) |
6305 | return FALSE; | 6328 | return FALSE; |
6306 | } | 6329 | } |
6307 | return TRUE; | 6330 | return TRUE; |
6308 | } | 6331 | } |
6309 | 6332 | ||
6310 | static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col ) | 6333 | static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col ) |
6311 | { | 6334 | { |
6312 | for ( QTextTableCell* c = cells.first(); c; c = cells.next() ) { | 6335 | for ( QTextTableCell* c = cells.first(); c; c = cells.next() ) { |
6313 | if ( row >= c->row() && row < c->row() + c->rowspan() | 6336 | if ( row >= c->row() && row < c->row() + c->rowspan() |
6314 | && col >= c->column() && col < c->column() + c->colspan() ) | 6337 | && col >= c->column() && col < c->column() + c->colspan() ) |
6315 | return TRUE; | 6338 | return TRUE; |
6316 | } | 6339 | } |
6317 | return FALSE; | 6340 | return FALSE; |
6318 | } | 6341 | } |
6319 | 6342 | ||
6320 | QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, | 6343 | QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, |
6321 | const QChar* doc, int length, int& pos, QTextParagraph *curpar ) | 6344 | const QChar* doc, int length, int& pos, QTextParagraph *curpar ) |
6322 | { | 6345 | { |
6323 | 6346 | ||
6324 | QTextTable* table = new QTextTable( this, attr ); | 6347 | QTextTable* table = new QTextTable( this, attr ); |
6325 | int row = -1; | 6348 | int row = -1; |
6326 | int col = -1; | 6349 | int col = -1; |
6327 | 6350 | ||
6328 | QString rowbgcolor; | 6351 | QString rowbgcolor; |
6329 | QString rowalign; | 6352 | QString rowalign; |
6330 | QString tablebgcolor = attr["bgcolor"]; | 6353 | QString tablebgcolor = attr["bgcolor"]; |
6331 | 6354 | ||
6332 | QPtrList<QTextTableCell> multicells; | 6355 | QPtrList<QTextTableCell> multicells; |
6333 | 6356 | ||
6334 | QString tagname; | 6357 | QString tagname; |
6335 | (void) eatSpace(doc, length, pos); | 6358 | (void) eatSpace(doc, length, pos); |
6336 | while ( pos < length) { | 6359 | while ( pos < length) { |
6337 | if (hasPrefix(doc, length, pos, QChar('<')) ){ | 6360 | if (hasPrefix(doc, length, pos, QChar('<')) ){ |
6338 | if (hasPrefix(doc, length, pos+1, QChar('/'))) { | 6361 | if (hasPrefix(doc, length, pos+1, QChar('/'))) { |
6339 | tagname = parseCloseTag( doc, length, pos ); | 6362 | tagname = parseCloseTag( doc, length, pos ); |
6340 | if ( tagname == "table" ) { | 6363 | if ( tagname == "table" ) { |
6341 | return table; | 6364 | return table; |
6342 | } | 6365 | } |
6343 | } else { | 6366 | } else { |
6344 | QMap<QString, QString> attr2; | 6367 | QMap<QString, QString> attr2; |
6345 | bool emptyTag = FALSE; | 6368 | bool emptyTag = FALSE; |
6346 | tagname = parseOpenTag( doc, length, pos, attr2, emptyTag ); | 6369 | tagname = parseOpenTag( doc, length, pos, attr2, emptyTag ); |
6347 | if ( tagname == "tr" ) { | 6370 | if ( tagname == "tr" ) { |
6348 | rowbgcolor = attr2["bgcolor"]; | 6371 | rowbgcolor = attr2["bgcolor"]; |
6349 | rowalign = attr2["align"]; | 6372 | rowalign = attr2["align"]; |
6350 | row++; | 6373 | row++; |
6351 | col = -1; | 6374 | col = -1; |
6352 | } | 6375 | } |
6353 | else if ( tagname == "td" || tagname == "th" ) { | 6376 | else if ( tagname == "td" || tagname == "th" ) { |
6354 | col++; | 6377 | col++; |
6355 | while ( qt_is_cell_in_use( multicells, row, col ) ) { | 6378 | while ( qt_is_cell_in_use( multicells, row, col ) ) { |
6356 | col++; | 6379 | col++; |
6357 | } | 6380 | } |
6358 | 6381 | ||
6359 | if ( row >= 0 && col >= 0 ) { | 6382 | if ( row >= 0 && col >= 0 ) { |
6360 | const QStyleSheetItem* s = sheet_->item(tagname); | 6383 | const QStyleSheetItem* s = sheet_->item(tagname); |
6361 | if ( !attr2.contains("bgcolor") ) { | 6384 | if ( !attr2.contains("bgcolor") ) { |
6362 | if (!rowbgcolor.isEmpty() ) | 6385 | if (!rowbgcolor.isEmpty() ) |
6363 | attr2["bgcolor"] = rowbgcolor; | 6386 | attr2["bgcolor"] = rowbgcolor; |
6364 | else if (!tablebgcolor.isEmpty() ) | 6387 | else if (!tablebgcolor.isEmpty() ) |
6365 | attr2["bgcolor"] = tablebgcolor; | 6388 | attr2["bgcolor"] = tablebgcolor; |
6366 | } | 6389 | } |
6367 | if ( !attr2.contains("align") ) { | 6390 | if ( !attr2.contains("align") ) { |
6368 | if (!rowalign.isEmpty() ) | 6391 | if (!rowalign.isEmpty() ) |
6369 | attr2["align"] = rowalign; | 6392 | attr2["align"] = rowalign; |
6370 | } | 6393 | } |
6371 | 6394 | ||
6372 | // extract the cell contents | 6395 | // extract the cell contents |
6373 | int end = pos; | 6396 | int end = pos; |
6374 | while ( end < length | 6397 | while ( end < length |
6375 | && !hasPrefix( doc, length, end, "</td") | 6398 | && !hasPrefix( doc, length, end, "</td") |
6376 | && !hasPrefix( doc, length, end, "<td") | 6399 | && !hasPrefix( doc, length, end, "<td") |
6377 | && !hasPrefix( doc, length, end, "</th") | 6400 | && !hasPrefix( doc, length, end, "</th") |
6378 | && !hasPrefix( doc, length, end, "<th") | 6401 | && !hasPrefix( doc, length, end, "<th") |
6379 | && !hasPrefix( doc, length, end, "<td") | 6402 | && !hasPrefix( doc, length, end, "<td") |
6380 | && !hasPrefix( doc, length, end, "</tr") | 6403 | && !hasPrefix( doc, length, end, "</tr") |
6381 | && !hasPrefix( doc, length, end, "<tr") | 6404 | && !hasPrefix( doc, length, end, "<tr") |
6382 | && !hasPrefix( doc, length, end, "</table") ) { | 6405 | && !hasPrefix( doc, length, end, "</table") ) { |
6383 | if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table | 6406 | if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table |
6384 | int nested = 1; | 6407 | int nested = 1; |
6385 | ++end; | 6408 | ++end; |
6386 | while ( end < length && nested != 0 ) { | 6409 | while ( end < length && nested != 0 ) { |
6387 | if ( hasPrefix( doc, length, end, "</table" ) ) | 6410 | if ( hasPrefix( doc, length, end, "</table" ) ) |
6388 | nested--; | 6411 | nested--; |
6389 | if ( hasPrefix( doc, length, end, "<table" ) ) | 6412 | if ( hasPrefix( doc, length, end, "<table" ) ) |
6390 | nested++; | 6413 | nested++; |
6391 | end++; | 6414 | end++; |
6392 | } | 6415 | } |
6393 | } | 6416 | } |
6394 | end++; | 6417 | end++; |
6395 | } | 6418 | } |
6396 | QTextTableCell* cell = new QTextTableCell( table, row, col, | 6419 | QTextTableCell* cell = new QTextTableCell( table, row, col, |
6397 | attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ), | 6420 | attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ), |
6398 | contxt, *factory_, sheet_, | 6421 | contxt, *factory_, sheet_, |
6399 | QString( doc, length).mid( pos, end - pos ) ); | 6422 | QString( doc, length).mid( pos, end - pos ) ); |
6400 | cell->richText()->parentPar = curpar; | 6423 | cell->richText()->parentPar = curpar; |
6401 | if ( cell->colspan() > 1 || cell->rowspan() > 1 ) | 6424 | if ( cell->colspan() > 1 || cell->rowspan() > 1 ) |
6402 | multicells.append( cell ); | 6425 | multicells.append( cell ); |
6403 | col += cell->colspan()-1; | 6426 | col += cell->colspan()-1; |
6404 | pos = end; | 6427 | pos = end; |
6405 | } | 6428 | } |
6406 | } | 6429 | } |
6407 | } | 6430 | } |
6408 | 6431 | ||
6409 | } else { | 6432 | } else { |
6410 | ++pos; | 6433 | ++pos; |
6411 | } | 6434 | } |
6412 | } | 6435 | } |
6413 | return table; | 6436 | return table; |
6414 | } | 6437 | } |
6415 | 6438 | ||
6416 | bool QTextDocument::eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp ) | 6439 | bool QTextDocument::eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp ) |
6417 | { | 6440 | { |
6418 | int old_pos = pos; | 6441 | int old_pos = pos; |
6419 | while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != QChar::nbsp ) ) ) | 6442 | while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != QChar::nbsp ) ) ) |
6420 | pos++; | 6443 | pos++; |
6421 | return old_pos < pos; | 6444 | return old_pos < pos; |
6422 | } | 6445 | } |
6423 | 6446 | ||
6424 | bool QTextDocument::eat(const QChar* doc, int length, int& pos, QChar c) | 6447 | bool QTextDocument::eat(const QChar* doc, int length, int& pos, QChar c) |
6425 | { | 6448 | { |
6426 | bool ok = pos < length && doc[pos] == c; | 6449 | bool ok = pos < length && doc[pos] == c; |
6427 | if ( ok ) | 6450 | if ( ok ) |
6428 | pos++; | 6451 | pos++; |
6429 | return ok; | 6452 | return ok; |
6430 | } | 6453 | } |
6431 | /*****************************************************************/ | 6454 | /*****************************************************************/ |
6432 | 6455 | ||
6433 | struct Entity { | 6456 | struct Entity { |
6434 | const char * name; | 6457 | const char * name; |
6435 | Q_UINT16 code; | 6458 | Q_UINT16 code; |
6436 | }; | 6459 | }; |
6437 | 6460 | ||
6438 | static const Entity entitylist [] = { | 6461 | static const Entity entitylist [] = { |
6439 | { "AElig", 0x00c6 }, | 6462 | { "AElig", 0x00c6 }, |
6440 | { "Aacute", 0x00c1 }, | 6463 | { "Aacute", 0x00c1 }, |
6441 | { "Acirc", 0x00c2 }, | 6464 | { "Acirc", 0x00c2 }, |
6442 | { "Agrave", 0x00c0 }, | 6465 | { "Agrave", 0x00c0 }, |
6443 | { "Alpha", 0x0391 }, | 6466 | { "Alpha", 0x0391 }, |
6444 | { "AMP", 38 }, | 6467 | { "AMP", 38 }, |
6445 | { "Aring", 0x00c5 }, | 6468 | { "Aring", 0x00c5 }, |
6446 | { "Atilde", 0x00c3 }, | 6469 | { "Atilde", 0x00c3 }, |
6447 | { "Auml", 0x00c4 }, | 6470 | { "Auml", 0x00c4 }, |
6448 | { "Beta", 0x0392 }, | 6471 | { "Beta", 0x0392 }, |
6449 | { "Ccedil", 0x00c7 }, | 6472 | { "Ccedil", 0x00c7 }, |
6450 | { "Chi", 0x03a7 }, | 6473 | { "Chi", 0x03a7 }, |
6451 | { "Dagger", 0x2021 }, | 6474 | { "Dagger", 0x2021 }, |
6452 | { "Delta", 0x0394 }, | 6475 | { "Delta", 0x0394 }, |
6453 | { "ETH", 0x00d0 }, | 6476 | { "ETH", 0x00d0 }, |
6454 | { "Eacute", 0x00c9 }, | 6477 | { "Eacute", 0x00c9 }, |
6455 | { "Ecirc", 0x00ca }, | 6478 | { "Ecirc", 0x00ca }, |
6456 | { "Egrave", 0x00c8 }, | 6479 | { "Egrave", 0x00c8 }, |
6457 | { "Epsilon", 0x0395 }, | 6480 | { "Epsilon", 0x0395 }, |
6458 | { "Eta", 0x0397 }, | 6481 | { "Eta", 0x0397 }, |
6459 | { "Euml", 0x00cb }, | 6482 | { "Euml", 0x00cb }, |
6460 | { "Gamma", 0x0393 }, | 6483 | { "Gamma", 0x0393 }, |
6461 | { "GT", 62 }, | 6484 | { "GT", 62 }, |
6462 | { "Iacute", 0x00cd }, | 6485 | { "Iacute", 0x00cd }, |
6463 | { "Icirc", 0x00ce }, | 6486 | { "Icirc", 0x00ce }, |
6464 | { "Igrave", 0x00cc }, | 6487 | { "Igrave", 0x00cc }, |
6465 | { "Iota", 0x0399 }, | 6488 | { "Iota", 0x0399 }, |
6466 | { "Iuml", 0x00cf }, | 6489 | { "Iuml", 0x00cf }, |
6467 | { "Kappa", 0x039a }, | 6490 | { "Kappa", 0x039a }, |
6468 | { "Lambda", 0x039b }, | 6491 | { "Lambda", 0x039b }, |
6469 | { "LT", 60 }, | 6492 | { "LT", 60 }, |
6470 | { "Mu", 0x039c }, | 6493 | { "Mu", 0x039c }, |
6471 | { "Ntilde", 0x00d1 }, | 6494 | { "Ntilde", 0x00d1 }, |
6472 | { "Nu", 0x039d }, | 6495 | { "Nu", 0x039d }, |
6473 | { "OElig", 0x0152 }, | 6496 | { "OElig", 0x0152 }, |
6474 | { "Oacute", 0x00d3 }, | 6497 | { "Oacute", 0x00d3 }, |
6475 | { "Ocirc", 0x00d4 }, | 6498 | { "Ocirc", 0x00d4 }, |
6476 | { "Ograve", 0x00d2 }, | 6499 | { "Ograve", 0x00d2 }, |
6477 | { "Omega", 0x03a9 }, | 6500 | { "Omega", 0x03a9 }, |
6478 | { "Omicron", 0x039f }, | 6501 | { "Omicron", 0x039f }, |
6479 | { "Oslash", 0x00d8 }, | 6502 | { "Oslash", 0x00d8 }, |
6480 | { "Otilde", 0x00d5 }, | 6503 | { "Otilde", 0x00d5 }, |
6481 | { "Ouml", 0x00d6 }, | 6504 | { "Ouml", 0x00d6 }, |
6482 | { "Phi", 0x03a6 }, | 6505 | { "Phi", 0x03a6 }, |
6483 | { "Pi", 0x03a0 }, | 6506 | { "Pi", 0x03a0 }, |
6484 | { "Prime", 0x2033 }, | 6507 | { "Prime", 0x2033 }, |
6485 | { "Psi", 0x03a8 }, | 6508 | { "Psi", 0x03a8 }, |
6486 | { "QUOT", 34 }, | 6509 | { "QUOT", 34 }, |
6487 | { "Rho", 0x03a1 }, | 6510 | { "Rho", 0x03a1 }, |
6488 | { "Scaron", 0x0160 }, | 6511 | { "Scaron", 0x0160 }, |
6489 | { "Sigma", 0x03a3 }, | 6512 | { "Sigma", 0x03a3 }, |
6490 | { "THORN", 0x00de }, | 6513 | { "THORN", 0x00de }, |
6491 | { "Tau", 0x03a4 }, | 6514 | { "Tau", 0x03a4 }, |
6492 | { "Theta", 0x0398 }, | 6515 | { "Theta", 0x0398 }, |
6493 | { "Uacute", 0x00da }, | 6516 | { "Uacute", 0x00da }, |
6494 | { "Ucirc", 0x00db }, | 6517 | { "Ucirc", 0x00db }, |
6495 | { "Ugrave", 0x00d9 }, | 6518 | { "Ugrave", 0x00d9 }, |
6496 | { "Upsilon", 0x03a5 }, | 6519 | { "Upsilon", 0x03a5 }, |
6497 | { "Uuml", 0x00dc }, | 6520 | { "Uuml", 0x00dc }, |
6498 | { "Xi", 0x039e }, | 6521 | { "Xi", 0x039e }, |
6499 | { "Yacute", 0x00dd }, | 6522 | { "Yacute", 0x00dd }, |
6500 | { "Yuml", 0x0178 }, | 6523 | { "Yuml", 0x0178 }, |
6501 | { "Zeta", 0x0396 }, | 6524 | { "Zeta", 0x0396 }, |
6502 | { "aacute", 0x00e1 }, | 6525 | { "aacute", 0x00e1 }, |
6503 | { "acirc", 0x00e2 }, | 6526 | { "acirc", 0x00e2 }, |
6504 | { "acute", 0x00b4 }, | 6527 | { "acute", 0x00b4 }, |
6505 | { "aelig", 0x00e6 }, | 6528 | { "aelig", 0x00e6 }, |
6506 | { "agrave", 0x00e0 }, | 6529 | { "agrave", 0x00e0 }, |
6507 | { "alefsym", 0x2135 }, | 6530 | { "alefsym", 0x2135 }, |
6508 | { "alpha", 0x03b1 }, | 6531 | { "alpha", 0x03b1 }, |
6509 | { "amp", 38 }, | 6532 | { "amp", 38 }, |
6510 | { "and", 0x22a5 }, | 6533 | { "and", 0x22a5 }, |
6511 | { "ang", 0x2220 }, | 6534 | { "ang", 0x2220 }, |
6512 | { "apos", 0x0027 }, | 6535 | { "apos", 0x0027 }, |
6513 | { "aring", 0x00e5 }, | 6536 | { "aring", 0x00e5 }, |
6514 | { "asymp", 0x2248 }, | 6537 | { "asymp", 0x2248 }, |
6515 | { "atilde", 0x00e3 }, | 6538 | { "atilde", 0x00e3 }, |
6516 | { "auml", 0x00e4 }, | 6539 | { "auml", 0x00e4 }, |
6517 | { "bdquo", 0x201e }, | 6540 | { "bdquo", 0x201e }, |
6518 | { "beta", 0x03b2 }, | 6541 | { "beta", 0x03b2 }, |
6519 | { "brvbar", 0x00a6 }, | 6542 | { "brvbar", 0x00a6 }, |
6520 | { "bull", 0x2022 }, | 6543 | { "bull", 0x2022 }, |
6521 | { "cap", 0x2229 }, | 6544 | { "cap", 0x2229 }, |
6522 | { "ccedil", 0x00e7 }, | 6545 | { "ccedil", 0x00e7 }, |
6523 | { "cedil", 0x00b8 }, | 6546 | { "cedil", 0x00b8 }, |
6524 | { "cent", 0x00a2 }, | 6547 | { "cent", 0x00a2 }, |
6525 | { "chi", 0x03c7 }, | 6548 | { "chi", 0x03c7 }, |
6526 | { "circ", 0x02c6 }, | 6549 | { "circ", 0x02c6 }, |
6527 | { "clubs", 0x2663 }, | 6550 | { "clubs", 0x2663 }, |
6528 | { "cong", 0x2245 }, | 6551 | { "cong", 0x2245 }, |
6529 | { "copy", 0x00a9 }, | 6552 | { "copy", 0x00a9 }, |
6530 | { "crarr", 0x21b5 }, | 6553 | { "crarr", 0x21b5 }, |
6531 | { "cup", 0x222a }, | 6554 | { "cup", 0x222a }, |
6532 | { "curren", 0x00a4 }, | 6555 | { "curren", 0x00a4 }, |
6533 | { "dArr", 0x21d3 }, | 6556 | { "dArr", 0x21d3 }, |
6534 | { "dagger", 0x2020 }, | 6557 | { "dagger", 0x2020 }, |
6535 | { "darr", 0x2193 }, | 6558 | { "darr", 0x2193 }, |
6536 | { "deg", 0x00b0 }, | 6559 | { "deg", 0x00b0 }, |
6537 | { "delta", 0x03b4 }, | 6560 | { "delta", 0x03b4 }, |
6538 | { "diams", 0x2666 }, | 6561 | { "diams", 0x2666 }, |
6539 | { "divide", 0x00f7 }, | 6562 | { "divide", 0x00f7 }, |
6540 | { "eacute", 0x00e9 }, | 6563 | { "eacute", 0x00e9 }, |
6541 | { "ecirc", 0x00ea }, | 6564 | { "ecirc", 0x00ea }, |
6542 | { "egrave", 0x00e8 }, | 6565 | { "egrave", 0x00e8 }, |
6543 | { "empty", 0x2205 }, | 6566 | { "empty", 0x2205 }, |
6544 | { "emsp", 0x2003 }, | 6567 | { "emsp", 0x2003 }, |
6545 | { "ensp", 0x2002 }, | 6568 | { "ensp", 0x2002 }, |
6546 | { "epsilon", 0x03b5 }, | 6569 | { "epsilon", 0x03b5 }, |
6547 | { "equiv", 0x2261 }, | 6570 | { "equiv", 0x2261 }, |
6548 | { "eta", 0x03b7 }, | 6571 | { "eta", 0x03b7 }, |
6549 | { "eth", 0x00f0 }, | 6572 | { "eth", 0x00f0 }, |
6550 | { "euml", 0x00eb }, | 6573 | { "euml", 0x00eb }, |
6551 | { "euro", 0x20ac }, | 6574 | { "euro", 0x20ac }, |
6552 | { "exist", 0x2203 }, | 6575 | { "exist", 0x2203 }, |
6553 | { "fnof", 0x0192 }, | 6576 | { "fnof", 0x0192 }, |
6554 | { "forall", 0x2200 }, | 6577 | { "forall", 0x2200 }, |
6555 | { "frac12", 0x00bd }, | 6578 | { "frac12", 0x00bd }, |
6556 | { "frac14", 0x00bc }, | 6579 | { "frac14", 0x00bc }, |
6557 | { "frac34", 0x00be }, | 6580 | { "frac34", 0x00be }, |
6558 | { "frasl", 0x2044 }, | 6581 | { "frasl", 0x2044 }, |
6559 | { "gamma", 0x03b3 }, | 6582 | { "gamma", 0x03b3 }, |
6560 | { "ge", 0x2265 }, | 6583 | { "ge", 0x2265 }, |
6561 | { "gt", 62 }, | 6584 | { "gt", 62 }, |
6562 | { "hArr", 0x21d4 }, | 6585 | { "hArr", 0x21d4 }, |
6563 | { "harr", 0x2194 }, | 6586 | { "harr", 0x2194 }, |
6564 | { "hearts", 0x2665 }, | 6587 | { "hearts", 0x2665 }, |
6565 | { "hellip", 0x2026 }, | 6588 | { "hellip", 0x2026 }, |
6566 | { "iacute", 0x00ed }, | 6589 | { "iacute", 0x00ed }, |
6567 | { "icirc", 0x00ee }, | 6590 | { "icirc", 0x00ee }, |
6568 | { "iexcl", 0x00a1 }, | 6591 | { "iexcl", 0x00a1 }, |
6569 | { "igrave", 0x00ec }, | 6592 | { "igrave", 0x00ec }, |
6570 | { "image", 0x2111 }, | 6593 | { "image", 0x2111 }, |
6571 | { "infin", 0x221e }, | 6594 | { "infin", 0x221e }, |
6572 | { "int", 0x222b }, | 6595 | { "int", 0x222b }, |
6573 | { "iota", 0x03b9 }, | 6596 | { "iota", 0x03b9 }, |
6574 | { "iquest", 0x00bf }, | 6597 | { "iquest", 0x00bf }, |
6575 | { "isin", 0x2208 }, | 6598 | { "isin", 0x2208 }, |
6576 | { "iuml", 0x00ef }, | 6599 | { "iuml", 0x00ef }, |
6577 | { "kappa", 0x03ba }, | 6600 | { "kappa", 0x03ba }, |
6578 | { "lArr", 0x21d0 }, | 6601 | { "lArr", 0x21d0 }, |
6579 | { "lambda", 0x03bb }, | 6602 | { "lambda", 0x03bb }, |
6580 | { "lang", 0x2329 }, | 6603 | { "lang", 0x2329 }, |
6581 | { "laquo", 0x00ab }, | 6604 | { "laquo", 0x00ab }, |
6582 | { "larr", 0x2190 }, | 6605 | { "larr", 0x2190 }, |
6583 | { "lceil", 0x2308 }, | 6606 | { "lceil", 0x2308 }, |
6584 | { "ldquo", 0x201c }, | 6607 | { "ldquo", 0x201c }, |
6585 | { "le", 0x2264 }, | 6608 | { "le", 0x2264 }, |
6586 | { "lfloor", 0x230a }, | 6609 | { "lfloor", 0x230a }, |
6587 | { "lowast", 0x2217 }, | 6610 | { "lowast", 0x2217 }, |
6588 | { "loz", 0x25ca }, | 6611 | { "loz", 0x25ca }, |
6589 | { "lrm", 0x200e }, | 6612 | { "lrm", 0x200e }, |
6590 | { "lsaquo", 0x2039 }, | 6613 | { "lsaquo", 0x2039 }, |
6591 | { "lsquo", 0x2018 }, | 6614 | { "lsquo", 0x2018 }, |
6592 | { "lt", 60 }, | 6615 | { "lt", 60 }, |
6593 | { "macr", 0x00af }, | 6616 | { "macr", 0x00af }, |
6594 | { "mdash", 0x2014 }, | 6617 | { "mdash", 0x2014 }, |
6595 | { "micro", 0x00b5 }, | 6618 | { "micro", 0x00b5 }, |
6596 | { "middot", 0x00b7 }, | 6619 | { "middot", 0x00b7 }, |
6597 | { "minus", 0x2212 }, | 6620 | { "minus", 0x2212 }, |
6598 | { "mu", 0x03bc }, | 6621 | { "mu", 0x03bc }, |
6599 | { "nabla", 0x2207 }, | 6622 | { "nabla", 0x2207 }, |
6600 | { "nbsp", 0x00a0 }, | 6623 | { "nbsp", 0x00a0 }, |
6601 | { "ndash", 0x2013 }, | 6624 | { "ndash", 0x2013 }, |
6602 | { "ne", 0x2260 }, | 6625 | { "ne", 0x2260 }, |
6603 | { "ni", 0x220b }, | 6626 | { "ni", 0x220b }, |
6604 | { "not", 0x00ac }, | 6627 | { "not", 0x00ac }, |
6605 | { "notin", 0x2209 }, | 6628 | { "notin", 0x2209 }, |
6606 | { "nsub", 0x2284 }, | 6629 | { "nsub", 0x2284 }, |
6607 | { "ntilde", 0x00f1 }, | 6630 | { "ntilde", 0x00f1 }, |
6608 | { "nu", 0x03bd }, | 6631 | { "nu", 0x03bd }, |
6609 | { "oacute", 0x00f3 }, | 6632 | { "oacute", 0x00f3 }, |
6610 | { "ocirc", 0x00f4 }, | 6633 | { "ocirc", 0x00f4 }, |
6611 | { "oelig", 0x0153 }, | 6634 | { "oelig", 0x0153 }, |
6612 | { "ograve", 0x00f2 }, | 6635 | { "ograve", 0x00f2 }, |
6613 | { "oline", 0x203e }, | 6636 | { "oline", 0x203e }, |
6614 | { "omega", 0x03c9 }, | 6637 | { "omega", 0x03c9 }, |
6615 | { "omicron", 0x03bf }, | 6638 | { "omicron", 0x03bf }, |
6616 | { "oplus", 0x2295 }, | 6639 | { "oplus", 0x2295 }, |
6617 | { "or", 0x22a6 }, | 6640 | { "or", 0x22a6 }, |
6618 | { "ordf", 0x00aa }, | 6641 | { "ordf", 0x00aa }, |
6619 | { "ordm", 0x00ba }, | 6642 | { "ordm", 0x00ba }, |
6620 | { "oslash", 0x00f8 }, | 6643 | { "oslash", 0x00f8 }, |
6621 | { "otilde", 0x00f5 }, | 6644 | { "otilde", 0x00f5 }, |
6622 | { "otimes", 0x2297 }, | 6645 | { "otimes", 0x2297 }, |
6623 | { "ouml", 0x00f6 }, | 6646 | { "ouml", 0x00f6 }, |
6624 | { "para", 0x00b6 }, | 6647 | { "para", 0x00b6 }, |
6625 | { "part", 0x2202 }, | 6648 | { "part", 0x2202 }, |
6626 | { "percnt", 0x0025 }, | 6649 | { "percnt", 0x0025 }, |
6627 | { "permil", 0x2030 }, | 6650 | { "permil", 0x2030 }, |
6628 | { "perp", 0x22a5 }, | 6651 | { "perp", 0x22a5 }, |
6629 | { "phi", 0x03c6 }, | 6652 | { "phi", 0x03c6 }, |
6630 | { "pi", 0x03c0 }, | 6653 | { "pi", 0x03c0 }, |
6631 | { "piv", 0x03d6 }, | 6654 | { "piv", 0x03d6 }, |
6632 | { "plusmn", 0x00b1 }, | 6655 | { "plusmn", 0x00b1 }, |
6633 | { "pound", 0x00a3 }, | 6656 | { "pound", 0x00a3 }, |
6634 | { "prime", 0x2032 }, | 6657 | { "prime", 0x2032 }, |
6635 | { "prod", 0x220f }, | 6658 | { "prod", 0x220f }, |
6636 | { "prop", 0x221d }, | 6659 | { "prop", 0x221d }, |
6637 | { "psi", 0x03c8 }, | 6660 | { "psi", 0x03c8 }, |
6638 | { "quot", 34 }, | 6661 | { "quot", 34 }, |
6639 | { "rArr", 0x21d2 }, | 6662 | { "rArr", 0x21d2 }, |
6640 | { "radic", 0x221a }, | 6663 | { "radic", 0x221a }, |
6641 | { "rang", 0x232a }, | 6664 | { "rang", 0x232a }, |
6642 | { "raquo", 0x00bb }, | 6665 | { "raquo", 0x00bb }, |
6643 | { "rarr", 0x2192 }, | 6666 | { "rarr", 0x2192 }, |
6644 | { "rceil", 0x2309 }, | 6667 | { "rceil", 0x2309 }, |
6645 | { "rdquo", 0x201d }, | 6668 | { "rdquo", 0x201d }, |
6646 | { "real", 0x211c }, | 6669 | { "real", 0x211c }, |
6647 | { "reg", 0x00ae }, | 6670 | { "reg", 0x00ae }, |
6648 | { "rfloor", 0x230b }, | 6671 | { "rfloor", 0x230b }, |
6649 | { "rho", 0x03c1 }, | 6672 | { "rho", 0x03c1 }, |
6650 | { "rlm", 0x200f }, | 6673 | { "rlm", 0x200f }, |
6651 | { "rsaquo", 0x203a }, | 6674 | { "rsaquo", 0x203a }, |
6652 | { "rsquo", 0x2019 }, | 6675 | { "rsquo", 0x2019 }, |
6653 | { "sbquo", 0x201a }, | 6676 | { "sbquo", 0x201a }, |
6654 | { "scaron", 0x0161 }, | 6677 | { "scaron", 0x0161 }, |
6655 | { "sdot", 0x22c5 }, | 6678 | { "sdot", 0x22c5 }, |
6656 | { "sect", 0x00a7 }, | 6679 | { "sect", 0x00a7 }, |
6657 | { "shy", 0x00ad }, | 6680 | { "shy", 0x00ad }, |
6658 | { "sigma", 0x03c3 }, | 6681 | { "sigma", 0x03c3 }, |
6659 | { "sigmaf", 0x03c2 }, | 6682 | { "sigmaf", 0x03c2 }, |
6660 | { "sim", 0x223c }, | 6683 | { "sim", 0x223c }, |
6661 | { "spades", 0x2660 }, | 6684 | { "spades", 0x2660 }, |
6662 | { "sub", 0x2282 }, | 6685 | { "sub", 0x2282 }, |
6663 | { "sube", 0x2286 }, | 6686 | { "sube", 0x2286 }, |
6664 | { "sum", 0x2211 }, | 6687 | { "sum", 0x2211 }, |
6665 | { "sup1", 0x00b9 }, | 6688 | { "sup1", 0x00b9 }, |
6666 | { "sup2", 0x00b2 }, | 6689 | { "sup2", 0x00b2 }, |
6667 | { "sup3", 0x00b3 }, | 6690 | { "sup3", 0x00b3 }, |
6668 | { "sup", 0x2283 }, | 6691 | { "sup", 0x2283 }, |
6669 | { "supe", 0x2287 }, | 6692 | { "supe", 0x2287 }, |
6670 | { "szlig", 0x00df }, | 6693 | { "szlig", 0x00df }, |
6671 | { "tau", 0x03c4 }, | 6694 | { "tau", 0x03c4 }, |
6672 | { "there4", 0x2234 }, | 6695 | { "there4", 0x2234 }, |
6673 | { "theta", 0x03b8 }, | 6696 | { "theta", 0x03b8 }, |
6674 | { "thetasym", 0x03d1 }, | 6697 | { "thetasym", 0x03d1 }, |
6675 | { "thinsp", 0x2009 }, | 6698 | { "thinsp", 0x2009 }, |
6676 | { "thorn", 0x00fe }, | 6699 | { "thorn", 0x00fe }, |
6677 | { "tilde", 0x02dc }, | 6700 | { "tilde", 0x02dc }, |
6678 | { "times", 0x00d7 }, | 6701 | { "times", 0x00d7 }, |
6679 | { "trade", 0x2122 }, | 6702 | { "trade", 0x2122 }, |
6680 | { "uArr", 0x21d1 }, | 6703 | { "uArr", 0x21d1 }, |
6681 | { "uacute", 0x00fa }, | 6704 | { "uacute", 0x00fa }, |
6682 | { "uarr", 0x2191 }, | 6705 | { "uarr", 0x2191 }, |
6683 | { "ucirc", 0x00fb }, | 6706 | { "ucirc", 0x00fb }, |
6684 | { "ugrave", 0x00f9 }, | 6707 | { "ugrave", 0x00f9 }, |
6685 | { "uml", 0x00a8 }, | 6708 | { "uml", 0x00a8 }, |
6686 | { "upsih", 0x03d2 }, | 6709 | { "upsih", 0x03d2 }, |
6687 | { "upsilon", 0x03c5 }, | 6710 | { "upsilon", 0x03c5 }, |
6688 | { "uuml", 0x00fc }, | 6711 | { "uuml", 0x00fc }, |
6689 | { "weierp", 0x2118 }, | 6712 | { "weierp", 0x2118 }, |
6690 | { "xi", 0x03be }, | 6713 | { "xi", 0x03be }, |
6691 | { "yacute", 0x00fd }, | 6714 | { "yacute", 0x00fd }, |
6692 | { "yen", 0x00a5 }, | 6715 | { "yen", 0x00a5 }, |
6693 | { "yuml", 0x00ff }, | 6716 | { "yuml", 0x00ff }, |
6694 | { "zeta", 0x03b6 }, | 6717 | { "zeta", 0x03b6 }, |
6695 | { "zwj", 0x200d }, | 6718 | { "zwj", 0x200d }, |
6696 | { "zwnj", 0x200c }, | 6719 | { "zwnj", 0x200c }, |
6697 | { "", 0x0000 } | 6720 | { "", 0x0000 } |
6698 | }; | 6721 | }; |
6699 | 6722 | ||
6700 | 6723 | ||
6701 | 6724 | ||
6702 | 6725 | ||
6703 | 6726 | ||
6704 | static QMap<QCString, QChar> *html_map = 0; | 6727 | static QMap<QCString, QChar> *html_map = 0; |
6705 | static void qt_cleanup_html_map() | 6728 | static void qt_cleanup_html_map() |
6706 | { | 6729 | { |
6707 | delete html_map; | 6730 | delete html_map; |
6708 | html_map = 0; | 6731 | html_map = 0; |
6709 | } | 6732 | } |
6710 | 6733 | ||
6711 | static QMap<QCString, QChar> *htmlMap() | 6734 | static QMap<QCString, QChar> *htmlMap() |
6712 | { | 6735 | { |
6713 | if ( !html_map ) { | 6736 | if ( !html_map ) { |
6714 | html_map = new QMap<QCString, QChar>; | 6737 | html_map = new QMap<QCString, QChar>; |
6715 | qAddPostRoutine( qt_cleanup_html_map ); | 6738 | qAddPostRoutine( qt_cleanup_html_map ); |
6716 | 6739 | ||
6717 | const Entity *ent = entitylist; | 6740 | const Entity *ent = entitylist; |
6718 | while( ent->code ) { | 6741 | while( ent->code ) { |
6719 | html_map->insert( ent->name, QChar(ent->code) ); | 6742 | html_map->insert( ent->name, QChar(ent->code) ); |
6720 | ent++; | 6743 | ent++; |
6721 | } | 6744 | } |
6722 | } | 6745 | } |
6723 | return html_map; | 6746 | return html_map; |
6724 | } | 6747 | } |
6725 | 6748 | ||
6726 | QChar QTextDocument::parseHTMLSpecialChar(const QChar* doc, int length, int& pos) | 6749 | QChar QTextDocument::parseHTMLSpecialChar(const QChar* doc, int length, int& pos) |
6727 | { | 6750 | { |
6728 | QCString s; | 6751 | QCString s; |
6729 | pos++; | 6752 | pos++; |
6730 | int recoverpos = pos; | 6753 | int recoverpos = pos; |
6731 | while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 6) { | 6754 | while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 6) { |
6732 | s += doc[pos]; | 6755 | s += doc[pos]; |
6733 | pos++; | 6756 | pos++; |
6734 | } | 6757 | } |
6735 | if (doc[pos] != ';' && !doc[pos].isSpace() ) { | 6758 | if (doc[pos] != ';' && !doc[pos].isSpace() ) { |
6736 | pos = recoverpos; | 6759 | pos = recoverpos; |
6737 | return '&'; | 6760 | return '&'; |
6738 | } | 6761 | } |
6739 | pos++; | 6762 | pos++; |
6740 | 6763 | ||
6741 | if ( s.length() > 1 && s[0] == '#') { | 6764 | if ( s.length() > 1 && s[0] == '#') { |
6742 | int num = s.mid(1).toInt(); | 6765 | int num = s.mid(1).toInt(); |
6743 | if ( num == 151 ) // ### hack for designer manual | 6766 | if ( num == 151 ) // ### hack for designer manual |
6744 | return '-'; | 6767 | return '-'; |
6745 | return num; | 6768 | return num; |
6746 | } | 6769 | } |
6747 | 6770 | ||
6748 | QMap<QCString, QChar>::Iterator it = htmlMap()->find(s); | 6771 | QMap<QCString, QChar>::Iterator it = htmlMap()->find(s); |
6749 | if ( it != htmlMap()->end() ) { | 6772 | if ( it != htmlMap()->end() ) { |
6750 | return *it; | 6773 | return *it; |
6751 | } | 6774 | } |
6752 | 6775 | ||
6753 | pos = recoverpos; | 6776 | pos = recoverpos; |
6754 | return '&'; | 6777 | return '&'; |
6755 | } | 6778 | } |
6756 | 6779 | ||
6757 | QString QTextDocument::parseWord(const QChar* doc, int length, int& pos, bool lower) | 6780 | QString QTextDocument::parseWord(const QChar* doc, int length, int& pos, bool lower) |
6758 | { | 6781 | { |
6759 | QString s; | 6782 | QString s; |
6760 | 6783 | ||
6761 | if (doc[pos] == '"') { | 6784 | if (doc[pos] == '"') { |
6762 | pos++; | 6785 | pos++; |
6763 | while ( pos < length && doc[pos] != '"' ) { | 6786 | while ( pos < length && doc[pos] != '"' ) { |
6764 | s += doc[pos]; | 6787 | s += doc[pos]; |
6765 | pos++; | 6788 | pos++; |
6766 | } | 6789 | } |
6767 | eat(doc, length, pos, '"'); | 6790 | eat(doc, length, pos, '"'); |
6768 | } else { | 6791 | } else { |
6769 | static QString term = QString::fromLatin1("/>"); | 6792 | static QString term = QString::fromLatin1("/>"); |
6770 | while( pos < length && | 6793 | while( pos < length && |
6771 | (doc[pos] != '>' && !hasPrefix( doc, length, pos, term)) | 6794 | (doc[pos] != '>' && !hasPrefix( doc, length, pos, term)) |
6772 | && doc[pos] != '<' | 6795 | && doc[pos] != '<' |
6773 | && doc[pos] != '=' | 6796 | && doc[pos] != '=' |
6774 | && !doc[pos].isSpace()) | 6797 | && !doc[pos].isSpace()) |
6775 | { | 6798 | { |
6776 | if ( doc[pos] == '&') | 6799 | if ( doc[pos] == '&') |
6777 | s += parseHTMLSpecialChar( doc, length, pos ); | 6800 | s += parseHTMLSpecialChar( doc, length, pos ); |
6778 | else { | 6801 | else { |
6779 | s += doc[pos]; | 6802 | s += doc[pos]; |
6780 | pos++; | 6803 | pos++; |
6781 | } | 6804 | } |
6782 | } | 6805 | } |
6783 | if (lower) | 6806 | if (lower) |
6784 | s = s.lower(); | 6807 | s = s.lower(); |
6785 | } | 6808 | } |
6786 | return s; | 6809 | return s; |
6787 | } | 6810 | } |
6788 | 6811 | ||
6789 | QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm ) | 6812 | QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm ) |
6790 | { | 6813 | { |
6791 | if ( pos >= length ) | 6814 | if ( pos >= length ) |
6792 | return QChar::null; | 6815 | return QChar::null; |
6793 | 6816 | ||
6794 | QChar c = doc[pos++]; | 6817 | QChar c = doc[pos++]; |
6795 | 6818 | ||
6796 | if (c == '<' ) | 6819 | if (c == '<' ) |
6797 | return QChar::null; | 6820 | return QChar::null; |
6798 | 6821 | ||
6799 | if ( c.isSpace() && c != QChar::nbsp ) { | 6822 | if ( c.isSpace() && c != QChar::nbsp ) { |
6800 | if ( wsm == QStyleSheetItem::WhiteSpacePre ) { | 6823 | if ( wsm == QStyleSheetItem::WhiteSpacePre ) { |
6801 | if ( c == '\n' ) | 6824 | if ( c == '\n' ) |
6802 | return QChar_linesep; | 6825 | return QChar_linesep; |
6803 | else | 6826 | else |
6804 | return c; | 6827 | return c; |
6805 | } else { // non-pre mode: collapse whitespace except nbsp | 6828 | } else { // non-pre mode: collapse whitespace except nbsp |
6806 | while ( pos< length && | 6829 | while ( pos< length && |
6807 | doc[pos].isSpace() && doc[pos] != QChar::nbsp ) | 6830 | doc[pos].isSpace() && doc[pos] != QChar::nbsp ) |
6808 | pos++; | 6831 | pos++; |
6809 | if ( wsm == QStyleSheetItem::WhiteSpaceNoWrap ) | 6832 | if ( wsm == QStyleSheetItem::WhiteSpaceNoWrap ) |
6810 | return QChar::nbsp; | 6833 | return QChar::nbsp; |
6811 | else | 6834 | else |
6812 | return ' '; | 6835 | return ' '; |
6813 | } | 6836 | } |
6814 | } | 6837 | } |
6815 | else if ( c == '&' ) | 6838 | else if ( c == '&' ) |
6816 | return parseHTMLSpecialChar( doc, length, --pos ); | 6839 | return parseHTMLSpecialChar( doc, length, --pos ); |
6817 | else | 6840 | else |
6818 | return c; | 6841 | return c; |
6819 | } | 6842 | } |
6820 | 6843 | ||
6821 | QString QTextDocument::parseOpenTag(const QChar* doc, int length, int& pos, | 6844 | QString QTextDocument::parseOpenTag(const QChar* doc, int length, int& pos, |
6822 | QMap<QString, QString> &attr, bool& emptyTag) | 6845 | QMap<QString, QString> &attr, bool& emptyTag) |
6823 | { | 6846 | { |
6824 | emptyTag = FALSE; | 6847 | emptyTag = FALSE; |
6825 | pos++; | 6848 | pos++; |
6826 | if ( hasPrefix(doc, length, pos, '!') ) { | 6849 | if ( hasPrefix(doc, length, pos, '!') ) { |
6827 | if ( hasPrefix( doc, length, pos+1, "--")) { | 6850 | if ( hasPrefix( doc, length, pos+1, "--")) { |
6828 | pos += 3; | 6851 | pos += 3; |
6829 | // eat comments | 6852 | // eat comments |
6830 | QString pref = QString::fromLatin1("-->"); | 6853 | QString pref = QString::fromLatin1("-->"); |
6831 | while ( !hasPrefix(doc, length, pos, pref ) && pos < length ) | 6854 | while ( !hasPrefix(doc, length, pos, pref ) && pos < length ) |
6832 | pos++; | 6855 | pos++; |
6833 | if ( hasPrefix(doc, length, pos, pref ) ) { | 6856 | if ( hasPrefix(doc, length, pos, pref ) ) { |
6834 | pos += 3; | 6857 | pos += 3; |
6835 | eatSpace(doc, length, pos, TRUE); | 6858 | eatSpace(doc, length, pos, TRUE); |
6836 | } | 6859 | } |
6837 | emptyTag = TRUE; | 6860 | emptyTag = TRUE; |
6838 | return QString::null; | 6861 | return QString::null; |
6839 | } | 6862 | } |
6840 | else { | 6863 | else { |
6841 | // eat strange internal tags | 6864 | // eat strange internal tags |
6842 | while ( !hasPrefix(doc, length, pos, '>') && pos < length ) | 6865 | while ( !hasPrefix(doc, length, pos, '>') && pos < length ) |
6843 | pos++; | 6866 | pos++; |
6844 | if ( hasPrefix(doc, length, pos, '>') ) { | 6867 | if ( hasPrefix(doc, length, pos, '>') ) { |
6845 | pos++; | 6868 | pos++; |
6846 | eatSpace(doc, length, pos, TRUE); | 6869 | eatSpace(doc, length, pos, TRUE); |
6847 | } | 6870 | } |
6848 | return QString::null; | 6871 | return QString::null; |
6849 | } | 6872 | } |
6850 | } | 6873 | } |
6851 | 6874 | ||
6852 | QString tag = parseWord(doc, length, pos ); | 6875 | QString tag = parseWord(doc, length, pos ); |
6853 | eatSpace(doc, length, pos, TRUE); | 6876 | eatSpace(doc, length, pos, TRUE); |
6854 | static QString term = QString::fromLatin1("/>"); | 6877 | static QString term = QString::fromLatin1("/>"); |
6855 | static QString s_TRUE = QString::fromLatin1("TRUE"); | 6878 | static QString s_TRUE = QString::fromLatin1("TRUE"); |
6856 | 6879 | ||
6857 | while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) { | 6880 | while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) { |
6858 | QString key = parseWord(doc, length, pos ); | 6881 | QString key = parseWord(doc, length, pos ); |
6859 | eatSpace(doc, length, pos, TRUE); | 6882 | eatSpace(doc, length, pos, TRUE); |
6860 | if ( key.isEmpty()) { | 6883 | if ( key.isEmpty()) { |
6861 | // error recovery | 6884 | // error recovery |
6862 | while ( pos < length && doc[pos] != '>' ) | 6885 | while ( pos < length && doc[pos] != '>' ) |
6863 | pos++; | 6886 | pos++; |
6864 | break; | 6887 | break; |
6865 | } | 6888 | } |
6866 | QString value; | 6889 | QString value; |
6867 | if (hasPrefix(doc, length, pos, '=') ){ | 6890 | if (hasPrefix(doc, length, pos, '=') ){ |
6868 | pos++; | 6891 | pos++; |
6869 | eatSpace(doc, length, pos); | 6892 | eatSpace(doc, length, pos); |
6870 | value = parseWord(doc, length, pos, FALSE); | 6893 | value = parseWord(doc, length, pos, FALSE); |
6871 | } | 6894 | } |
6872 | else | 6895 | else |
6873 | value = s_TRUE; | 6896 | value = s_TRUE; |
6874 | attr.insert(key.lower(), value ); | 6897 | attr.insert(key.lower(), value ); |
6875 | eatSpace(doc, length, pos, TRUE); | 6898 | eatSpace(doc, length, pos, TRUE); |
6876 | } | 6899 | } |
6877 | 6900 | ||
6878 | if (emptyTag) { | 6901 | if (emptyTag) { |
6879 | eat(doc, length, pos, '/'); | 6902 | eat(doc, length, pos, '/'); |
6880 | eat(doc, length, pos, '>'); | 6903 | eat(doc, length, pos, '>'); |
6881 | } | 6904 | } |
6882 | else | 6905 | else |
6883 | eat(doc, length, pos, '>'); | 6906 | eat(doc, length, pos, '>'); |
6884 | 6907 | ||
6885 | return tag; | 6908 | return tag; |
6886 | } | 6909 | } |
6887 | 6910 | ||
6888 | QString QTextDocument::parseCloseTag( const QChar* doc, int length, int& pos ) | 6911 | QString QTextDocument::parseCloseTag( const QChar* doc, int length, int& pos ) |
6889 | { | 6912 | { |
6890 | pos++; | 6913 | pos++; |
6891 | pos++; | 6914 | pos++; |
6892 | QString tag = parseWord(doc, length, pos ); | 6915 | QString tag = parseWord(doc, length, pos ); |
6893 | eatSpace(doc, length, pos, TRUE); | 6916 | eatSpace(doc, length, pos, TRUE); |
6894 | eat(doc, length, pos, '>'); | 6917 | eat(doc, length, pos, '>'); |
6895 | return tag; | 6918 | return tag; |
6896 | } | 6919 | } |
6897 | 6920 | ||
6898 | QTextFlow::QTextFlow() | 6921 | QTextFlow::QTextFlow() |
6899 | { | 6922 | { |
6900 | w = pagesize = 0; | 6923 | w = pagesize = 0; |
6901 | leftItems.setAutoDelete( FALSE ); | 6924 | leftItems.setAutoDelete( FALSE ); |
6902 | rightItems.setAutoDelete( FALSE ); | 6925 | rightItems.setAutoDelete( FALSE ); |
6903 | } | 6926 | } |
6904 | 6927 | ||
6905 | QTextFlow::~QTextFlow() | 6928 | QTextFlow::~QTextFlow() |
6906 | { | 6929 | { |
6907 | } | 6930 | } |
6908 | 6931 | ||
6909 | void QTextFlow::clear() | 6932 | void QTextFlow::clear() |
6910 | { | 6933 | { |
6911 | leftItems.clear(); | 6934 | leftItems.clear(); |
6912 | rightItems.clear(); | 6935 | rightItems.clear(); |
6913 | } | 6936 | } |
6914 | 6937 | ||
6915 | void QTextFlow::setWidth( int width ) | 6938 | void QTextFlow::setWidth( int width ) |
6916 | { | 6939 | { |
6917 | w = width; | 6940 | w = width; |
6918 | } | 6941 | } |
6919 | 6942 | ||
6920 | int QTextFlow::adjustLMargin( int yp, int, int margin, int space ) | 6943 | int QTextFlow::adjustLMargin( int yp, int, int margin, int space ) |
6921 | { | 6944 | { |
6922 | for ( QTextCustomItem* item = leftItems.first(); item; item = leftItems.next() ) { | 6945 | for ( QTextCustomItem* item = leftItems.first(); item; item = leftItems.next() ) { |
6923 | if ( item->ypos == -1 ) | 6946 | if ( item->ypos == -1 ) |
6924 | continue; | 6947 | continue; |
6925 | if ( yp >= item->ypos && yp < item->ypos + item->height ) | 6948 | if ( yp >= item->ypos && yp < item->ypos + item->height ) |
6926 | margin = QMAX( margin, item->xpos + item->width + space ); | 6949 | margin = QMAX( margin, item->xpos + item->width + space ); |
6927 | } | 6950 | } |
6928 | return margin; | 6951 | return margin; |
6929 | } | 6952 | } |
6930 | 6953 | ||
6931 | int QTextFlow::adjustRMargin( int yp, int, int margin, int space ) | 6954 | int QTextFlow::adjustRMargin( int yp, int, int margin, int space ) |
6932 | { | 6955 | { |
6933 | for ( QTextCustomItem* item = rightItems.first(); item; item = rightItems.next() ) { | 6956 | for ( QTextCustomItem* item = rightItems.first(); item; item = rightItems.next() ) { |
6934 | if ( item->ypos == -1 ) | 6957 | if ( item->ypos == -1 ) |
6935 | continue; | 6958 | continue; |
6936 | if ( yp >= item->ypos && yp < item->ypos + item->height ) | 6959 | if ( yp >= item->ypos && yp < item->ypos + item->height ) |
6937 | margin = QMAX( margin, w - item->xpos - space ); | 6960 | margin = QMAX( margin, w - item->xpos - space ); |
6938 | } | 6961 | } |
6939 | return margin; | 6962 | return margin; |
6940 | } | 6963 | } |
6941 | 6964 | ||
6942 | 6965 | ||
6943 | int QTextFlow::adjustFlow( int y, int /*w*/, int h ) | 6966 | int QTextFlow::adjustFlow( int y, int /*w*/, int h ) |
6944 | { | 6967 | { |
6945 | if ( pagesize > 0 ) { // check pages | 6968 | if ( pagesize > 0 ) { // check pages |
6946 | int yinpage = y % pagesize; | 6969 | int yinpage = y % pagesize; |
6947 | if ( yinpage <= border_tolerance ) | 6970 | if ( yinpage <= border_tolerance ) |
6948 | return border_tolerance - yinpage; | 6971 | return border_tolerance - yinpage; |
6949 | else | 6972 | else |
6950 | if ( yinpage + h > pagesize - border_tolerance ) | 6973 | if ( yinpage + h > pagesize - border_tolerance ) |
6951 | return ( pagesize - yinpage ) + border_tolerance; | 6974 | return ( pagesize - yinpage ) + border_tolerance; |
6952 | } | 6975 | } |
6953 | return 0; | 6976 | return 0; |
6954 | } | 6977 | } |
6955 | 6978 | ||
6956 | void QTextFlow::unregisterFloatingItem( QTextCustomItem* item ) | 6979 | void QTextFlow::unregisterFloatingItem( QTextCustomItem* item ) |
6957 | { | 6980 | { |
6958 | leftItems.removeRef( item ); | 6981 | leftItems.removeRef( item ); |
6959 | rightItems.removeRef( item ); | 6982 | rightItems.removeRef( item ); |
6960 | } | 6983 | } |
6961 | 6984 | ||
6962 | void QTextFlow::registerFloatingItem( QTextCustomItem* item ) | 6985 | void QTextFlow::registerFloatingItem( QTextCustomItem* item ) |
6963 | { | 6986 | { |
6964 | if ( item->placement() == QTextCustomItem::PlaceRight ) { | 6987 | if ( item->placement() == QTextCustomItem::PlaceRight ) { |
6965 | if ( !rightItems.contains( item ) ) | 6988 | if ( !rightItems.contains( item ) ) |
6966 | rightItems.append( item ); | 6989 | rightItems.append( item ); |
6967 | } else if ( item->placement() == QTextCustomItem::PlaceLeft && | 6990 | } else if ( item->placement() == QTextCustomItem::PlaceLeft && |
6968 | !leftItems.contains( item ) ) { | 6991 | !leftItems.contains( item ) ) { |
6969 | leftItems.append( item ); | 6992 | leftItems.append( item ); |
6970 | } | 6993 | } |
6971 | } | 6994 | } |
6972 | 6995 | ||
6973 | QRect QTextFlow::boundingRect() const | 6996 | QRect QTextFlow::boundingRect() const |
6974 | { | 6997 | { |
6975 | QRect br; | 6998 | QRect br; |
6976 | QPtrListIterator<QTextCustomItem> l( leftItems ); | 6999 | QPtrListIterator<QTextCustomItem> l( leftItems ); |
6977 | while( l.current() ) { | 7000 | while( l.current() ) { |
6978 | br = br.unite( l.current()->geometry() ); | 7001 | br = br.unite( l.current()->geometry() ); |
6979 | ++l; | 7002 | ++l; |
6980 | } | 7003 | } |
6981 | QPtrListIterator<QTextCustomItem> r( rightItems ); | 7004 | QPtrListIterator<QTextCustomItem> r( rightItems ); |
6982 | while( r.current() ) { | 7005 | while( r.current() ) { |
6983 | br = br.unite( r.current()->geometry() ); | 7006 | br = br.unite( r.current()->geometry() ); |
6984 | ++r; | 7007 | ++r; |
6985 | } | 7008 | } |
6986 | return br; | 7009 | return br; |
6987 | } | 7010 | } |
6988 | 7011 | ||
6989 | 7012 | ||
6990 | void QTextFlow::drawFloatingItems( QPainter* p, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) | 7013 | void QTextFlow::drawFloatingItems( QPainter* p, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) |
6991 | { | 7014 | { |
6992 | QTextCustomItem *item; | 7015 | QTextCustomItem *item; |
6993 | for ( item = leftItems.first(); item; item = leftItems.next() ) { | 7016 | for ( item = leftItems.first(); item; item = leftItems.next() ) { |
6994 | if ( item->xpos == -1 || item->ypos == -1 ) | 7017 | if ( item->xpos == -1 || item->ypos == -1 ) |
6995 | continue; | 7018 | continue; |
6996 | item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected ); | 7019 | item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected ); |
6997 | } | 7020 | } |
6998 | 7021 | ||
6999 | for ( item = rightItems.first(); item; item = rightItems.next() ) { | 7022 | for ( item = rightItems.first(); item; item = rightItems.next() ) { |
7000 | if ( item->xpos == -1 || item->ypos == -1 ) | 7023 | if ( item->xpos == -1 || item->ypos == -1 ) |
7001 | continue; | 7024 | continue; |
7002 | item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected ); | 7025 | item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected ); |
7003 | } | 7026 | } |
7004 | } | 7027 | } |
7005 | 7028 | ||
7006 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 7029 | // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7007 | 7030 | ||
7008 | void QTextCustomItem::pageBreak( int /*y*/ , QTextFlow* /*flow*/ ) | 7031 | void QTextCustomItem::pageBreak( int /*y*/ , QTextFlow* /*flow*/ ) |
7009 | { | 7032 | { |
7010 | } | 7033 | } |
7011 | 7034 | ||
7012 | QTextTable::QTextTable( QTextDocument *p, const QMap<QString, QString> & attr ) | 7035 | QTextTable::QTextTable( QTextDocument *p, const QMap<QString, QString> & attr ) |
7013 | : QTextCustomItem( p ) | 7036 | : QTextCustomItem( p ) |
7014 | { | 7037 | { |
7015 | cells.setAutoDelete( FALSE ); | 7038 | cells.setAutoDelete( FALSE ); |
7016 | cellspacing = 2; | 7039 | cellspacing = 2; |
7017 | if ( attr.contains("cellspacing") ) | 7040 | if ( attr.contains("cellspacing") ) |
7018 | cellspacing = attr["cellspacing"].toInt(); | 7041 | cellspacing = attr["cellspacing"].toInt(); |
7019 | cellpadding = 1; | 7042 | cellpadding = 1; |
7020 | if ( attr.contains("cellpadding") ) | 7043 | if ( attr.contains("cellpadding") ) |
7021 | cellpadding = attr["cellpadding"].toInt(); | 7044 | cellpadding = attr["cellpadding"].toInt(); |
7022 | border = innerborder = 0; | 7045 | border = innerborder = 0; |
7023 | if ( attr.contains("border" ) ) { | 7046 | if ( attr.contains("border" ) ) { |
7024 | QString s( attr["border"] ); | 7047 | QString s( attr["border"] ); |
7025 | if ( s == "TRUE" ) | 7048 | if ( s == "TRUE" ) |
7026 | border = 1; | 7049 | border = 1; |
7027 | else | 7050 | else |
7028 | border = attr["border"].toInt(); | 7051 | border = attr["border"].toInt(); |
7029 | } | 7052 | } |
7030 | us_b = border; | 7053 | us_b = border; |
7031 | 7054 | ||
7032 | innerborder = us_ib = border ? 1 : 0; | 7055 | innerborder = us_ib = border ? 1 : 0; |
7033 | 7056 | ||
7034 | if ( border ) | 7057 | if ( border ) |
7035 | cellspacing += 2; | 7058 | cellspacing += 2; |
7036 | 7059 | ||
7037 | us_ib = innerborder; | 7060 | us_ib = innerborder; |
7038 | us_cs = cellspacing; | 7061 | us_cs = cellspacing; |
7039 | us_cp = cellpadding; | 7062 | us_cp = cellpadding; |
7040 | outerborder = cellspacing + border; | 7063 | outerborder = cellspacing + border; |
7041 | us_ob = outerborder; | 7064 | us_ob = outerborder; |
7042 | layout = new QGridLayout( 1, 1, cellspacing ); | 7065 | layout = new QGridLayout( 1, 1, cellspacing ); |
7043 | 7066 | ||
7044 | fixwidth = 0; | 7067 | fixwidth = 0; |
7045 | stretch = 0; | 7068 | stretch = 0; |
7046 | if ( attr.contains("width") ) { | 7069 | if ( attr.contains("width") ) { |
7047 | bool b; | 7070 | bool b; |
7048 | QString s( attr["width"] ); | 7071 | QString s( attr["width"] ); |
7049 | int w = s.toInt( &b ); | 7072 | int w = s.toInt( &b ); |
7050 | if ( b ) { | 7073 | if ( b ) { |
7051 | fixwidth = w; | 7074 | fixwidth = w; |
7052 | } else { | 7075 | } else { |
7053 | s = s.stripWhiteSpace(); | 7076 | s = s.stripWhiteSpace(); |
7054 | if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' ) | 7077 | if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' ) |
7055 | stretch = s.left( s.length()-1).toInt(); | 7078 | stretch = s.left( s.length()-1).toInt(); |
7056 | } | 7079 | } |
7057 | } | 7080 | } |
7058 | 7081 | ||
7059 | place = PlaceInline; | 7082 | place = PlaceInline; |
7060 | if ( attr["align"] == "left" ) | 7083 | if ( attr["align"] == "left" ) |
7061 | place = PlaceLeft; | 7084 | place = PlaceLeft; |
7062 | else if ( attr["align"] == "right" ) | 7085 | else if ( attr["align"] == "right" ) |
7063 | place = PlaceRight; | 7086 | place = PlaceRight; |
7064 | cachewidth = 0; | 7087 | cachewidth = 0; |
7065 | attributes = attr; | 7088 | attributes = attr; |
7066 | pageBreakFor = -1; | 7089 | pageBreakFor = -1; |
7067 | } | 7090 | } |
7068 | 7091 | ||
7069 | QTextTable::~QTextTable() | 7092 | QTextTable::~QTextTable() |
7070 | { | 7093 | { |
7071 | delete layout; | 7094 | delete layout; |
7072 | } | 7095 | } |
7073 | 7096 | ||
7074 | QString QTextTable::richText() const | 7097 | QString QTextTable::richText() const |
7075 | { | 7098 | { |
7076 | QString s; | 7099 | QString s; |
7077 | s = "<table "; | 7100 | s = "<table "; |
7078 | QMap<QString, QString>::ConstIterator it = attributes.begin(); | 7101 | QMap<QString, QString>::ConstIterator it = attributes.begin(); |
7079 | for ( ; it != attributes.end(); ++it ) | 7102 | for ( ; it != attributes.end(); ++it ) |
7080 | s += it.key() + "=" + *it + " "; | 7103 | s += it.key() + "=" + *it + " "; |
7081 | s += ">\n"; | 7104 | s += ">\n"; |
7082 | 7105 | ||
7083 | int lastRow = -1; | 7106 | int lastRow = -1; |
7084 | bool needEnd = FALSE; | 7107 | bool needEnd = FALSE; |
7085 | QPtrListIterator<QTextTableCell> it2( cells ); | 7108 | QPtrListIterator<QTextTableCell> it2( cells ); |
7086 | while ( it2.current() ) { | 7109 | while ( it2.current() ) { |
7087 | QTextTableCell *cell = it2.current(); | 7110 | QTextTableCell *cell = it2.current(); |
7088 | ++it2; | 7111 | ++it2; |
7089 | if ( lastRow != cell->row() ) { | 7112 | if ( lastRow != cell->row() ) { |
7090 | if ( lastRow != -1 ) | 7113 | if ( lastRow != -1 ) |
7091 | s += "</tr>\n"; | 7114 | s += "</tr>\n"; |
7092 | s += "<tr>"; | 7115 | s += "<tr>"; |
7093 | lastRow = cell->row(); | 7116 | lastRow = cell->row(); |
7094 | needEnd = TRUE; | 7117 | needEnd = TRUE; |
7095 | } | 7118 | } |
7096 | s += "<td"; | 7119 | s += "<td"; |
7097 | it = cell->attributes.begin(); | 7120 | it = cell->attributes.begin(); |
7098 | for ( ; it != cell->attributes.end(); ++it ) | 7121 | for ( ; it != cell->attributes.end(); ++it ) |
7099 | s += " " + it.key() + "=" + *it; | 7122 | s += " " + it.key() + "=" + *it; |
7100 | s += ">"; | 7123 | s += ">"; |
7101 | s += cell->richText()->richText(); | 7124 | s += cell->richText()->richText(); |
7102 | s += "</td>"; | 7125 | s += "</td>"; |
7103 | } | 7126 | } |
7104 | if ( needEnd ) | 7127 | if ( needEnd ) |
7105 | s += "</tr>\n"; | 7128 | s += "</tr>\n"; |
7106 | s += "</table>\n"; | 7129 | s += "</table>\n"; |
7107 | return s; | 7130 | return s; |
7108 | } | 7131 | } |
7109 | 7132 | ||
7110 | void QTextTable::adjustToPainter( QPainter* p ) | 7133 | void QTextTable::adjustToPainter( QPainter* p ) |
7111 | { | 7134 | { |
7112 | cellspacing = scale( us_cs, p ); | 7135 | cellspacing = scale( us_cs, p ); |
7113 | cellpadding = scale( us_cp, p ); | 7136 | cellpadding = scale( us_cp, p ); |
7114 | border = scale( us_b , p ); | 7137 | border = scale( us_b , p ); |
7115 | innerborder = scale( us_ib, p ); | 7138 | innerborder = scale( us_ib, p ); |
7116 | outerborder = scale( us_ob ,p ); | 7139 | outerborder = scale( us_ob ,p ); |
7117 | width = 0; | 7140 | width = 0; |
7118 | cachewidth = 0; | 7141 | cachewidth = 0; |
7119 | for ( QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) | 7142 | for ( QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) |
7120 | cell->adjustToPainter( p ); | 7143 | cell->adjustToPainter( p ); |
7121 | } | 7144 | } |
7122 | 7145 | ||
7123 | void QTextTable::adjustCells( int y , int shift ) | 7146 | void QTextTable::adjustCells( int y , int shift ) |
7124 | { | 7147 | { |
7125 | QPtrListIterator<QTextTableCell> it( cells ); | 7148 | QPtrListIterator<QTextTableCell> it( cells ); |
7126 | QTextTableCell* cell; | 7149 | QTextTableCell* cell; |
7127 | bool enlarge = FALSE; | 7150 | bool enlarge = FALSE; |
7128 | while ( ( cell = it.current() ) ) { | 7151 | while ( ( cell = it.current() ) ) { |
7129 | ++it; | 7152 | ++it; |
7130 | QRect r = cell->geometry(); | 7153 | QRect r = cell->geometry(); |
7131 | if ( y <= r.top() ) { | 7154 | if ( y <= r.top() ) { |
7132 | r.moveBy(0, shift ); | 7155 | r.moveBy(0, shift ); |
7133 | cell->setGeometry( r ); | 7156 | cell->setGeometry( r ); |
7134 | enlarge = TRUE; | 7157 | enlarge = TRUE; |
7135 | } else if ( y <= r.bottom() ) { | 7158 | } else if ( y <= r.bottom() ) { |
7136 | r.rBottom() += shift; | 7159 | r.rBottom() += shift; |
7137 | cell->setGeometry( r ); | 7160 | cell->setGeometry( r ); |
7138 | enlarge = TRUE; | 7161 | enlarge = TRUE; |
7139 | } | 7162 | } |
7140 | } | 7163 | } |
7141 | if ( enlarge ) | 7164 | if ( enlarge ) |
7142 | height += shift; | 7165 | height += shift; |
7143 | } | 7166 | } |
7144 | 7167 | ||
7145 | void QTextTable::pageBreak( int yt, QTextFlow* flow ) | 7168 | void QTextTable::pageBreak( int yt, QTextFlow* flow ) |
7146 | { | 7169 | { |
7147 | if ( flow->pageSize() <= 0 ) | 7170 | if ( flow->pageSize() <= 0 ) |
7148 | return; | 7171 | return; |
7149 | if ( layout && pageBreakFor > 0 && pageBreakFor != yt ) { | 7172 | if ( layout && pageBreakFor > 0 && pageBreakFor != yt ) { |
7150 | layout->invalidate(); | 7173 | layout->invalidate(); |
7151 | int h = layout->heightForWidth( width-2*outerborder ); | 7174 | int h = layout->heightForWidth( width-2*outerborder ); |
7152 | layout->setGeometry( QRect(0, 0, width-2*outerborder, h) ); | 7175 | layout->setGeometry( QRect(0, 0, width-2*outerborder, h) ); |
7153 | height = layout->geometry().height()+2*outerborder; | 7176 | height = layout->geometry().height()+2*outerborder; |
7154 | } | 7177 | } |
7155 | pageBreakFor = yt; | 7178 | pageBreakFor = yt; |
7156 | QPtrListIterator<QTextTableCell> it( cells ); | 7179 | QPtrListIterator<QTextTableCell> it( cells ); |
7157 | QTextTableCell* cell; | 7180 | QTextTableCell* cell; |
7158 | while ( ( cell = it.current() ) ) { | 7181 | while ( ( cell = it.current() ) ) { |
7159 | ++it; | 7182 | ++it; |
7160 | int y = yt + outerborder + cell->geometry().y(); | 7183 | int y = yt + outerborder + cell->geometry().y(); |
7161 | int shift = flow->adjustFlow( y - cellspacing, width, cell->richText()->height() + 2*cellspacing ); | 7184 | int shift = flow->adjustFlow( y - cellspacing, width, cell->richText()->height() + 2*cellspacing ); |
7162 | adjustCells( y - outerborder - yt, shift ); | 7185 | adjustCells( y - outerborder - yt, shift ); |
7163 | } | 7186 | } |
7164 | } | 7187 | } |
7165 | 7188 | ||
7166 | 7189 | ||
7167 | void QTextTable::draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) | 7190 | void QTextTable::draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) |
7168 | { | 7191 | { |
7169 | if ( placement() != PlaceInline ) { | 7192 | if ( placement() != PlaceInline ) { |
7170 | x = xpos; | 7193 | x = xpos; |
7171 | y = ypos; | 7194 | y = ypos; |
7172 | } | 7195 | } |
7173 | 7196 | ||
7174 | for (QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) { | 7197 | for (QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) { |
7175 | if ( cx < 0 && cy < 0 || | 7198 | if ( cx < 0 && cy < 0 || |
7176 | QRect( cx, cy, cw, ch ).intersects( QRect( x + outerborder + cell->geometry().x(), | 7199 | QRect( cx, cy, cw, ch ).intersects( QRect( x + outerborder + cell->geometry().x(), |
7177 | y + outerborder + cell->geometry().y(), | 7200 | y + outerborder + cell->geometry().y(), |
7178 | cell->geometry().width(), cell->geometry().height() ) ) ) { | 7201 | cell->geometry().width(), cell->geometry().height() ) ) ) { |
7179 | cell->draw( p, x+outerborder, y+outerborder, cx, cy, cw, ch, cg, selected ); | 7202 | cell->draw( p, x+outerborder, y+outerborder, cx, cy, cw, ch, cg, selected ); |
7180 | if ( border ) { | 7203 | if ( border ) { |
7181 | QRect r( x+outerborder+cell->geometry().x() - innerborder, | 7204 | QRect r( x+outerborder+cell->geometry().x() - innerborder, |
7182 | y+outerborder+cell->geometry().y() - innerborder, | 7205 | y+outerborder+cell->geometry().y() - innerborder, |
7183 | cell->geometry().width() + 2 * innerborder, | 7206 | cell->geometry().width() + 2 * innerborder, |
7184 | cell->geometry().height() + 2 * innerborder ); | 7207 | cell->geometry().height() + 2 * innerborder ); |
7185 | if ( is_printer( p ) ) { | 7208 | if ( is_printer( p ) ) { |
7186 | QPen oldPen = p->pen(); | 7209 | QPen oldPen = p->pen(); |
7187 | QRect r2 = r; | 7210 | QRect r2 = r; |
7188 | r2.setLeft( r2.left() + innerborder/2 ); | 7211 | r2.setLeft( r2.left() + innerborder/2 ); |
7189 | r2.setTop( r2.top() + innerborder/2 ); | 7212 | r2.setTop( r2.top() + innerborder/2 ); |
7190 | r2.setRight( r2.right() - innerborder/2 ); | 7213 | r2.setRight( r2.right() - innerborder/2 ); |
7191 | r2.setBottom( r2.bottom() - innerborder/2 ); | 7214 | r2.setBottom( r2.bottom() - innerborder/2 ); |
7192 | p->setPen( QPen( cg.text(), innerborder ) ); | 7215 | p->setPen( QPen( cg.text(), innerborder ) ); |
7193 | p->drawRect( r2 ); | 7216 | p->drawRect( r2 ); |
7194 | p->setPen( oldPen ); | 7217 | p->setPen( oldPen ); |
7195 | } else { | 7218 | } else { |
7196 | int s = QMAX( cellspacing-2*innerborder, 0); | 7219 | int s = QMAX( cellspacing-2*innerborder, 0); |
7197 | if ( s ) { | 7220 | if ( s ) { |
7198 | p->fillRect( r.left()-s, r.top(), s+1, r.height(), cg.button() ); | 7221 | p->fillRect( r.left()-s, r.top(), s+1, r.height(), cg.button() ); |
7199 | p->fillRect( r.right(), r.top(), s+1, r.height(), cg.button() ); | 7222 | p->fillRect( r.right(), r.top(), s+1, r.height(), cg.button() ); |
7200 | p->fillRect( r.left()-s, r.top()-s, r.width()+2*s, s, cg.button() ); | 7223 | p->fillRect( r.left()-s, r.top()-s, r.width()+2*s, s, cg.button() ); |
7201 | p->fillRect( r.left()-s, r.bottom(), r.width()+2*s, s, cg.button() ); | 7224 | p->fillRect( r.left()-s, r.bottom(), r.width()+2*s, s, cg.button() ); |
7202 | } | 7225 | } |
7203 | qDrawShadePanel( p, r, cg, TRUE, innerborder ); | 7226 | qDrawShadePanel( p, r, cg, TRUE, innerborder ); |
7204 | } | 7227 | } |
7205 | } | 7228 | } |
7206 | } | 7229 | } |
7207 | } | 7230 | } |
7208 | if ( border ) { | 7231 | if ( border ) { |
7209 | QRect r ( x, y, width, height ); | 7232 | QRect r ( x, y, width, height ); |
7210 | if ( is_printer( p ) ) { | 7233 | if ( is_printer( p ) ) { |
7211 | QRect r2 = r; | 7234 | QRect r2 = r; |
7212 | r2.setLeft( r2.left() + border/2 ); | 7235 | r2.setLeft( r2.left() + border/2 ); |
7213 | r2.setTop( r2.top() + border/2 ); | 7236 | r2.setTop( r2.top() + border/2 ); |
7214 | r2.setRight( r2.right() - border/2 ); | 7237 | r2.setRight( r2.right() - border/2 ); |
7215 | r2.setBottom( r2.bottom() - border/2 ); | 7238 | r2.setBottom( r2.bottom() - border/2 ); |
7216 | QPen oldPen = p->pen(); | 7239 | QPen oldPen = p->pen(); |
7217 | p->setPen( QPen( cg.text(), border ) ); | 7240 | p->setPen( QPen( cg.text(), border ) ); |
7218 | p->drawRect( r2 ); | 7241 | p->drawRect( r2 ); |
7219 | p->setPen( oldPen ); | 7242 | p->setPen( oldPen ); |
7220 | } else { | 7243 | } else { |
7221 | int s = border+QMAX( cellspacing-2*innerborder, 0); | 7244 | int s = border+QMAX( cellspacing-2*innerborder, 0); |
7222 | if ( s ) { | 7245 | if ( s ) { |
7223 | p->fillRect( r.left(), r.top(), s, r.height(), cg.button() ); | 7246 | p->fillRect( r.left(), r.top(), s, r.height(), cg.button() ); |
7224 | p->fillRect( r.right()-s, r.top(), s, r.height(), cg.button() ); | 7247 | p->fillRect( r.right()-s, r.top(), s, r.height(), cg.button() ); |
7225 | p->fillRect( r.left(), r.top(), r.width(), s, cg.button() ); | 7248 | p->fillRect( r.left(), r.top(), r.width(), s, cg.button() ); |
7226 | p->fillRect( r.left(), r.bottom()-s, r.width(), s, cg.button() ); | 7249 | p->fillRect( r.left(), r.bottom()-s, r.width(), s, cg.button() ); |
7227 | } | 7250 | } |
7228 | qDrawShadePanel( p, r, cg, FALSE, border ); | 7251 | qDrawShadePanel( p, r, cg, FALSE, border ); |
7229 | } | 7252 | } |
7230 | } | 7253 | } |
7231 | 7254 | ||
7232 | } | 7255 | } |
7233 | 7256 | ||
7234 | int QTextTable::minimumWidth() const | 7257 | int QTextTable::minimumWidth() const |
7235 | { | 7258 | { |
7236 | return (layout ? layout->minimumSize().width() : 0) + 2 * outerborder; | 7259 | return (layout ? layout->minimumSize().width() : 0) + 2 * outerborder; |
7237 | } | 7260 | } |
7238 | 7261 | ||
7239 | void QTextTable::resize( int nwidth ) | 7262 | void QTextTable::resize( int nwidth ) |
7240 | { | 7263 | { |
7241 | if ( fixwidth && cachewidth != 0 ) | 7264 | if ( fixwidth && cachewidth != 0 ) |
7242 | return; | 7265 | return; |
7243 | if ( nwidth == cachewidth ) | 7266 | if ( nwidth == cachewidth ) |
7244 | return; | 7267 | return; |
7245 | 7268 | ||
7246 | 7269 | ||
7247 | cachewidth = nwidth; | 7270 | cachewidth = nwidth; |
7248 | int w = nwidth; | 7271 | int w = nwidth; |
7249 | 7272 | ||
7250 | format( w ); | 7273 | format( w ); |
7251 | 7274 | ||
7252 | if ( stretch ) | 7275 | if ( stretch ) |
7253 | nwidth = nwidth * stretch / 100; | 7276 | nwidth = nwidth * stretch / 100; |
7254 | 7277 | ||
7255 | width = nwidth; | 7278 | width = nwidth; |
7256 | layout->invalidate(); | 7279 | layout->invalidate(); |
7257 | int shw = layout->sizeHint().width() + 2*outerborder; | 7280 | int shw = layout->sizeHint().width() + 2*outerborder; |
7258 | int mw = layout->minimumSize().width() + 2*outerborder; | 7281 | int mw = layout->minimumSize().width() + 2*outerborder; |
7259 | if ( stretch ) | 7282 | if ( stretch ) |
7260 | width = QMAX( mw, nwidth ); | 7283 | width = QMAX( mw, nwidth ); |
7261 | else | 7284 | else |
7262 | width = QMAX( mw, QMIN( nwidth, shw ) ); | 7285 | width = QMAX( mw, QMIN( nwidth, shw ) ); |
7263 | 7286 | ||
7264 | if ( fixwidth ) | 7287 | if ( fixwidth ) |
7265 | width = fixwidth; | 7288 | width = fixwidth; |
7266 | 7289 | ||
7267 | layout->invalidate(); | 7290 | layout->invalidate(); |
7268 | mw = layout->minimumSize().width() + 2*outerborder; | 7291 | mw = layout->minimumSize().width() + 2*outerborder; |
7269 | width = QMAX( width, mw ); | 7292 | width = QMAX( width, mw ); |
7270 | 7293 | ||
7271 | int h = layout->heightForWidth( width-2*outerborder ); | 7294 | int h = layout->heightForWidth( width-2*outerborder ); |
7272 | layout->setGeometry( QRect(0, 0, width-2*outerborder, h) ); | 7295 | layout->setGeometry( QRect(0, 0, width-2*outerborder, h) ); |
7273 | height = layout->geometry().height()+2*outerborder; | 7296 | height = layout->geometry().height()+2*outerborder; |
7274 | } | 7297 | } |
7275 | 7298 | ||
7276 | void QTextTable::format( int w ) | 7299 | void QTextTable::format( int w ) |
7277 | { | 7300 | { |
7278 | for ( int i = 0; i < (int)cells.count(); ++i ) { | 7301 | for ( int i = 0; i < (int)cells.count(); ++i ) { |
7279 | QTextTableCell *cell = cells.at( i ); | 7302 | QTextTableCell *cell = cells.at( i ); |
7280 | QRect r = cell->geometry(); | 7303 | QRect r = cell->geometry(); |
7281 | r.setWidth( w - 2*outerborder ); | 7304 | r.setWidth( w - 2*outerborder ); |
7282 | cell->setGeometry( r ); | 7305 | cell->setGeometry( r ); |
7283 | } | 7306 | } |
7284 | } | 7307 | } |
7285 | 7308 | ||
7286 | void QTextTable::addCell( QTextTableCell* cell ) | 7309 | void QTextTable::addCell( QTextTableCell* cell ) |
7287 | { | 7310 | { |
7288 | cells.append( cell ); | 7311 | cells.append( cell ); |
7289 | layout->addMultiCell( cell, cell->row(), cell->row() + cell->rowspan()-1, | 7312 | layout->addMultiCell( cell, cell->row(), cell->row() + cell->rowspan()-1, |
7290 | cell->column(), cell->column() + cell->colspan()-1 ); | 7313 | cell->column(), cell->column() + cell->colspan()-1 ); |
7291 | } | 7314 | } |
7292 | 7315 | ||
7293 | bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy, bool atEnd ) | 7316 | bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy, bool atEnd ) |
7294 | { | 7317 | { |
7295 | currCell.remove( c ); | 7318 | currCell.remove( c ); |
7296 | if ( !atEnd ) | 7319 | if ( !atEnd ) |
7297 | return next( c, doc, parag, idx, ox, oy ); | 7320 | return next( c, doc, parag, idx, ox, oy ); |
7298 | currCell.insert( c, cells.count() ); | 7321 | currCell.insert( c, cells.count() ); |
7299 | return prev( c, doc, parag, idx, ox, oy ); | 7322 | return prev( c, doc, parag, idx, ox, oy ); |
7300 | } | 7323 | } |
7301 | 7324 | ||
7302 | bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy, const QPoint &pos ) | 7325 | bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy, const QPoint &pos ) |
7303 | { | 7326 | { |
7304 | currCell.remove( c ); | 7327 | currCell.remove( c ); |
7305 | int lastCell = -1; | 7328 | int lastCell = -1; |
7306 | int lastY = -1; | 7329 | int lastY = -1; |
7307 | int i; | 7330 | int i; |
7308 | for ( i = 0; i < (int)cells.count(); ++i ) { | 7331 | for ( i = 0; i < (int)cells.count(); ++i ) { |
7309 | QTextTableCell *cell = cells.at( i ); | 7332 | QTextTableCell *cell = cells.at( i ); |
7310 | if ( !cell ) | 7333 | if ( !cell ) |
7311 | continue; | 7334 | continue; |
7312 | QRect r( cell->geometry().x(), | 7335 | QRect r( cell->geometry().x(), |
7313 | cell->geometry().y(), | 7336 | cell->geometry().y(), |
7314 | cell->geometry().width() + 2 * innerborder + 2 * outerborder, | 7337 | cell->geometry().width() + 2 * innerborder + 2 * outerborder, |
7315 | cell->geometry().height() + 2 * innerborder + 2 * outerborder ); | 7338 | cell->geometry().height() + 2 * innerborder + 2 * outerborder ); |
7316 | 7339 | ||
7317 | if ( r.left() <= pos.x() && r.right() >= pos.x() ) { | 7340 | if ( r.left() <= pos.x() && r.right() >= pos.x() ) { |
7318 | if ( cell->geometry().y() > lastY ) { | 7341 | if ( cell->geometry().y() > lastY ) { |
7319 | lastCell = i; | 7342 | lastCell = i; |
7320 | lastY = cell->geometry().y(); | 7343 | lastY = cell->geometry().y(); |
7321 | } | 7344 | } |
7322 | if ( r.top() <= pos.y() && r.bottom() >= pos.y() ) { | 7345 | if ( r.top() <= pos.y() && r.bottom() >= pos.y() ) { |
7323 | currCell.insert( c, i ); | 7346 | currCell.insert( c, i ); |
7324 | break; | 7347 | break; |
7325 | } | 7348 | } |
7326 | } | 7349 | } |
7327 | } | 7350 | } |
7328 | if ( i == (int) cells.count() ) | 7351 | if ( i == (int) cells.count() ) |
7329 | return FALSE; // no cell found | 7352 | return FALSE; // no cell found |
7330 | 7353 | ||
7331 | if ( currCell.find( c ) == currCell.end() ) { | 7354 | if ( currCell.find( c ) == currCell.end() ) { |
7332 | if ( lastY != -1 ) | 7355 | if ( lastY != -1 ) |
7333 | currCell.insert( c, lastCell ); | 7356 | currCell.insert( c, lastCell ); |
7334 | else | 7357 | else |
7335 | return FALSE; | 7358 | return FALSE; |
7336 | } | 7359 | } |
7337 | 7360 | ||
7338 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); | 7361 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); |
7339 | if ( !cell ) | 7362 | if ( !cell ) |
7340 | return FALSE; | 7363 | return FALSE; |
7341 | doc = cell->richText(); | 7364 | doc = cell->richText(); |
7342 | parag = doc->firstParagraph(); | 7365 | parag = doc->firstParagraph(); |
7343 | idx = 0; | 7366 | idx = 0; |
7344 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); | 7367 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); |
7345 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; | 7368 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; |
7346 | return TRUE; | 7369 | return TRUE; |
7347 | } | 7370 | } |
7348 | 7371 | ||
7349 | bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) | 7372 | bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) |
7350 | { | 7373 | { |
7351 | int cc = -1; | 7374 | int cc = -1; |
7352 | if ( currCell.find( c ) != currCell.end() ) | 7375 | if ( currCell.find( c ) != currCell.end() ) |
7353 | cc = *currCell.find( c ); | 7376 | cc = *currCell.find( c ); |
7354 | if ( cc > (int)cells.count() - 1 || cc < 0 ) | 7377 | if ( cc > (int)cells.count() - 1 || cc < 0 ) |
7355 | cc = -1; | 7378 | cc = -1; |
7356 | currCell.remove( c ); | 7379 | currCell.remove( c ); |
7357 | currCell.insert( c, ++cc ); | 7380 | currCell.insert( c, ++cc ); |
7358 | if ( cc >= (int)cells.count() ) { | 7381 | if ( cc >= (int)cells.count() ) { |
7359 | currCell.insert( c, 0 ); | 7382 | currCell.insert( c, 0 ); |
7360 | QTextCustomItem::next( c, doc, parag, idx, ox, oy ); | 7383 | QTextCustomItem::next( c, doc, parag, idx, ox, oy ); |
7361 | QTextTableCell *cell = cells.first(); | 7384 | QTextTableCell *cell = cells.first(); |
7362 | if ( !cell ) | 7385 | if ( !cell ) |
7363 | return FALSE; | 7386 | return FALSE; |
7364 | doc = cell->richText(); | 7387 | doc = cell->richText(); |
7365 | idx = -1; | 7388 | idx = -1; |
7366 | return TRUE; | 7389 | return TRUE; |
7367 | } | 7390 | } |
7368 | 7391 | ||
7369 | if ( currCell.find( c ) == currCell.end() ) | 7392 | if ( currCell.find( c ) == currCell.end() ) |
7370 | return FALSE; | 7393 | return FALSE; |
7371 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); | 7394 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); |
7372 | if ( !cell ) | 7395 | if ( !cell ) |
7373 | return FALSE; | 7396 | return FALSE; |
7374 | doc = cell->richText(); | 7397 | doc = cell->richText(); |
7375 | parag = doc->firstParagraph(); | 7398 | parag = doc->firstParagraph(); |
7376 | idx = 0; | 7399 | idx = 0; |
7377 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); | 7400 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); |
7378 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; | 7401 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; |
7379 | return TRUE; | 7402 | return TRUE; |
7380 | } | 7403 | } |
7381 | 7404 | ||
7382 | bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) | 7405 | bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) |
7383 | { | 7406 | { |
7384 | int cc = -1; | 7407 | int cc = -1; |
7385 | if ( currCell.find( c ) != currCell.end() ) | 7408 | if ( currCell.find( c ) != currCell.end() ) |
7386 | cc = *currCell.find( c ); | 7409 | cc = *currCell.find( c ); |
7387 | if ( cc > (int)cells.count() - 1 || cc < 0 ) | 7410 | if ( cc > (int)cells.count() - 1 || cc < 0 ) |
7388 | cc = cells.count(); | 7411 | cc = cells.count(); |
7389 | currCell.remove( c ); | 7412 | currCell.remove( c ); |
7390 | currCell.insert( c, --cc ); | 7413 | currCell.insert( c, --cc ); |
7391 | if ( cc < 0 ) { | 7414 | if ( cc < 0 ) { |
7392 | currCell.insert( c, 0 ); | 7415 | currCell.insert( c, 0 ); |
7393 | QTextCustomItem::prev( c, doc, parag, idx, ox, oy ); | 7416 | QTextCustomItem::prev( c, doc, parag, idx, ox, oy ); |
7394 | QTextTableCell *cell = cells.first(); | 7417 | QTextTableCell *cell = cells.first(); |
7395 | if ( !cell ) | 7418 | if ( !cell ) |
7396 | return FALSE; | 7419 | return FALSE; |
7397 | doc = cell->richText(); | 7420 | doc = cell->richText(); |
7398 | idx = -1; | 7421 | idx = -1; |
7399 | return TRUE; | 7422 | return TRUE; |
7400 | } | 7423 | } |
7401 | 7424 | ||
7402 | if ( currCell.find( c ) == currCell.end() ) | 7425 | if ( currCell.find( c ) == currCell.end() ) |
7403 | return FALSE; | 7426 | return FALSE; |
7404 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); | 7427 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); |
7405 | if ( !cell ) | 7428 | if ( !cell ) |
7406 | return FALSE; | 7429 | return FALSE; |
7407 | doc = cell->richText(); | 7430 | doc = cell->richText(); |
7408 | parag = doc->lastParagraph(); | 7431 | parag = doc->lastParagraph(); |
7409 | idx = parag->length() - 1; | 7432 | idx = parag->length() - 1; |
7410 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); | 7433 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); |
7411 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; | 7434 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; |
7412 | return TRUE; | 7435 | return TRUE; |
7413 | } | 7436 | } |
7414 | 7437 | ||
7415 | bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) | 7438 | bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) |
7416 | { | 7439 | { |
7417 | if ( currCell.find( c ) == currCell.end() ) | 7440 | if ( currCell.find( c ) == currCell.end() ) |
7418 | return FALSE; | 7441 | return FALSE; |
7419 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); | 7442 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); |
7420 | if ( cell->row_ == layout->numRows() - 1 ) { | 7443 | if ( cell->row_ == layout->numRows() - 1 ) { |
7421 | currCell.insert( c, 0 ); | 7444 | currCell.insert( c, 0 ); |
7422 | QTextCustomItem::down( c, doc, parag, idx, ox, oy ); | 7445 | QTextCustomItem::down( c, doc, parag, idx, ox, oy ); |
7423 | QTextTableCell *cell = cells.first(); | 7446 | QTextTableCell *cell = cells.first(); |
7424 | if ( !cell ) | 7447 | if ( !cell ) |
7425 | return FALSE; | 7448 | return FALSE; |
7426 | doc = cell->richText(); | 7449 | doc = cell->richText(); |
7427 | idx = -1; | 7450 | idx = -1; |
7428 | return TRUE; | 7451 | return TRUE; |
7429 | } | 7452 | } |
7430 | 7453 | ||
7431 | int oldRow = cell->row_; | 7454 | int oldRow = cell->row_; |
7432 | int oldCol = cell->col_; | 7455 | int oldCol = cell->col_; |
7433 | if ( currCell.find( c ) == currCell.end() ) | 7456 | if ( currCell.find( c ) == currCell.end() ) |
7434 | return FALSE; | 7457 | return FALSE; |
7435 | int cc = *currCell.find( c ); | 7458 | int cc = *currCell.find( c ); |
7436 | for ( int i = cc; i < (int)cells.count(); ++i ) { | 7459 | for ( int i = cc; i < (int)cells.count(); ++i ) { |
7437 | cell = cells.at( i ); | 7460 | cell = cells.at( i ); |
7438 | if ( cell->row_ > oldRow && cell->col_ == oldCol ) { | 7461 | if ( cell->row_ > oldRow && cell->col_ == oldCol ) { |
7439 | currCell.insert( c, i ); | 7462 | currCell.insert( c, i ); |
7440 | break; | 7463 | break; |
7441 | } | 7464 | } |
7442 | } | 7465 | } |
7443 | doc = cell->richText(); | 7466 | doc = cell->richText(); |
7444 | if ( !cell ) | 7467 | if ( !cell ) |
7445 | return FALSE; | 7468 | return FALSE; |
7446 | parag = doc->firstParagraph(); | 7469 | parag = doc->firstParagraph(); |
7447 | idx = 0; | 7470 | idx = 0; |
7448 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); | 7471 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); |
7449 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; | 7472 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; |
7450 | return TRUE; | 7473 | return TRUE; |
7451 | } | 7474 | } |
7452 | 7475 | ||
7453 | bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) | 7476 | bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *¶g, int &idx, int &ox, int &oy ) |
7454 | { | 7477 | { |
7455 | if ( currCell.find( c ) == currCell.end() ) | 7478 | if ( currCell.find( c ) == currCell.end() ) |
7456 | return FALSE; | 7479 | return FALSE; |
7457 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); | 7480 | QTextTableCell *cell = cells.at( *currCell.find( c ) ); |
7458 | if ( cell->row_ == 0 ) { | 7481 | if ( cell->row_ == 0 ) { |
7459 | currCell.insert( c, 0 ); | 7482 | currCell.insert( c, 0 ); |
7460 | QTextCustomItem::up( c, doc, parag, idx, ox, oy ); | 7483 | QTextCustomItem::up( c, doc, parag, idx, ox, oy ); |
7461 | QTextTableCell *cell = cells.first(); | 7484 | QTextTableCell *cell = cells.first(); |
7462 | if ( !cell ) | 7485 | if ( !cell ) |
7463 | return FALSE; | 7486 | return FALSE; |
7464 | doc = cell->richText(); | 7487 | doc = cell->richText(); |
7465 | idx = -1; | 7488 | idx = -1; |
7466 | return TRUE; | 7489 | return TRUE; |
7467 | } | 7490 | } |
7468 | 7491 | ||
7469 | int oldRow = cell->row_; | 7492 | int oldRow = cell->row_; |
7470 | int oldCol = cell->col_; | 7493 | int oldCol = cell->col_; |
7471 | if ( currCell.find( c ) == currCell.end() ) | 7494 | if ( currCell.find( c ) == currCell.end() ) |
7472 | return FALSE; | 7495 | return FALSE; |
7473 | int cc = *currCell.find( c ); | 7496 | int cc = *currCell.find( c ); |
7474 | for ( int i = cc; i >= 0; --i ) { | 7497 | for ( int i = cc; i >= 0; --i ) { |
7475 | cell = cells.at( i ); | 7498 | cell = cells.at( i ); |
7476 | if ( cell->row_ < oldRow && cell->col_ == oldCol ) { | 7499 | if ( cell->row_ < oldRow && cell->col_ == oldCol ) { |
7477 | currCell.insert( c, i ); | 7500 | currCell.insert( c, i ); |
7478 | break; | 7501 | break; |
7479 | } | 7502 | } |
7480 | } | 7503 | } |
7481 | doc = cell->richText(); | 7504 | doc = cell->richText(); |
7482 | if ( !cell ) | 7505 | if ( !cell ) |
7483 | return FALSE; | 7506 | return FALSE; |
7484 | parag = doc->lastParagraph(); | 7507 | parag = doc->lastParagraph(); |
7485 | idx = parag->length() - 1; | 7508 | idx = parag->length() - 1; |
7486 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); | 7509 | ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); |
7487 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; | 7510 | oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; |
7488 | return TRUE; | 7511 | return TRUE; |
7489 | } | 7512 | } |
7490 | 7513 | ||
7491 | QTextTableCell::QTextTableCell( QTextTable* table, | 7514 | QTextTableCell::QTextTableCell( QTextTable* table, |
7492 | int row, int column, | 7515 | int row, int column, |
7493 | const QMap<QString, QString> &attr, | 7516 | const QMap<QString, QString> &attr, |
7494 | const QStyleSheetItem* /*style*/, // ### use them | 7517 | const QStyleSheetItem* /*style*/, // ### use them |
7495 | const QTextFormat& /*fmt*/, const QString& context, | 7518 | const QTextFormat& /*fmt*/, const QString& context, |
7496 | QMimeSourceFactory &factory, QStyleSheet *sheet, | 7519 | QMimeSourceFactory &factory, QStyleSheet *sheet, |
7497 | const QString& doc) | 7520 | const QString& doc) |
7498 | { | 7521 | { |
7499 | cached_width = -1; | 7522 | cached_width = -1; |
7500 | cached_sizehint = -1; | 7523 | cached_sizehint = -1; |
7501 | 7524 | ||
7502 | maxw = QWIDGETSIZE_MAX; | 7525 | maxw = QWIDGETSIZE_MAX; |
7503 | minw = 0; | 7526 | minw = 0; |
7504 | 7527 | ||
7505 | parent = table; | 7528 | parent = table; |
7506 | row_ = row; | 7529 | row_ = row; |
7507 | col_ = column; | 7530 | col_ = column; |
7508 | stretch_ = 0; | 7531 | stretch_ = 0; |
7509 | richtext = new QTextDocument( table->parent ); | 7532 | richtext = new QTextDocument( table->parent ); |
7510 | richtext->setTableCell( this ); | 7533 | richtext->setTableCell( this ); |
7511 | QString a = *attr.find( "align" ); | 7534 | QString a = *attr.find( "align" ); |
7512 | if ( !a.isEmpty() ) { | 7535 | if ( !a.isEmpty() ) { |
7513 | a = a.lower(); | 7536 | a = a.lower(); |
7514 | if ( a == "left" ) | 7537 | if ( a == "left" ) |
7515 | richtext->setAlignment( Qt::AlignLeft ); | 7538 | richtext->setAlignment( Qt::AlignLeft ); |
7516 | else if ( a == "center" ) | 7539 | else if ( a == "center" ) |
7517 | richtext->setAlignment( Qt::AlignHCenter ); | 7540 | richtext->setAlignment( Qt::AlignHCenter ); |
7518 | else if ( a == "right" ) | 7541 | else if ( a == "right" ) |
7519 | richtext->setAlignment( Qt::AlignRight ); | 7542 | richtext->setAlignment( Qt::AlignRight ); |
7520 | } | 7543 | } |
7521 | align = 0; | 7544 | align = 0; |
7522 | QString va = *attr.find( "valign" ); | 7545 | QString va = *attr.find( "valign" ); |
7523 | if ( !va.isEmpty() ) { | 7546 | if ( !va.isEmpty() ) { |
7524 | va = va.lower(); | 7547 | va = va.lower(); |
7525 | if ( va == "center" ) | 7548 | if ( va == "center" ) |
7526 | align |= Qt::AlignVCenter; | 7549 | align |= Qt::AlignVCenter; |
7527 | else if ( va == "bottom" ) | 7550 | else if ( va == "bottom" ) |
7528 | align |= Qt::AlignBottom; | 7551 | align |= Qt::AlignBottom; |
7529 | } | 7552 | } |
7530 | richtext->setFormatter( table->parent->formatter() ); | 7553 | richtext->setFormatter( table->parent->formatter() ); |
7531 | richtext->setUseFormatCollection( table->parent->useFormatCollection() ); | 7554 | richtext->setUseFormatCollection( table->parent->useFormatCollection() ); |
7532 | richtext->setMimeSourceFactory( &factory ); | 7555 | richtext->setMimeSourceFactory( &factory ); |
7533 | richtext->setStyleSheet( sheet ); | 7556 | richtext->setStyleSheet( sheet ); |
7534 | richtext->setDefaultFormat( table->parent->formatCollection()->defaultFormat()->font(), | 7557 | richtext->setDefaultFormat( table->parent->formatCollection()->defaultFormat()->font(), |
7535 | table->parent->formatCollection()->defaultFormat()->color() ); | 7558 | table->parent->formatCollection()->defaultFormat()->color() ); |
7536 | richtext->setRichText( doc, context ); | 7559 | richtext->setRichText( doc, context ); |
7537 | rowspan_ = 1; | 7560 | rowspan_ = 1; |
7538 | colspan_ = 1; | 7561 | colspan_ = 1; |
7539 | if ( attr.contains("colspan") ) | 7562 | if ( attr.contains("colspan") ) |
7540 | colspan_ = attr["colspan"].toInt(); | 7563 | colspan_ = attr["colspan"].toInt(); |
7541 | if ( attr.contains("rowspan") ) | 7564 | if ( attr.contains("rowspan") ) |
7542 | rowspan_ = attr["rowspan"].toInt(); | 7565 | rowspan_ = attr["rowspan"].toInt(); |
7543 | 7566 | ||
7544 | background = 0; | 7567 | background = 0; |
7545 | if ( attr.contains("bgcolor") ) { | 7568 | if ( attr.contains("bgcolor") ) { |
7546 | background = new QBrush(QColor( attr["bgcolor"] )); | 7569 | background = new QBrush(QColor( attr["bgcolor"] )); |
7547 | } | 7570 | } |
7548 | 7571 | ||
7549 | 7572 | ||
7550 | hasFixedWidth = FALSE; | 7573 | hasFixedWidth = FALSE; |
7551 | if ( attr.contains("width") ) { | 7574 | if ( attr.contains("width") ) { |
7552 | bool b; | 7575 | bool b; |
7553 | QString s( attr["width"] ); | 7576 | QString s( attr["width"] ); |
7554 | int w = s.toInt( &b ); | 7577 | int w = s.toInt( &b ); |
7555 | if ( b ) { | 7578 | if ( b ) { |
7556 | maxw = w; | 7579 | maxw = w; |
7557 | minw = maxw; | 7580 | minw = maxw; |
7558 | hasFixedWidth = TRUE; | 7581 | hasFixedWidth = TRUE; |
7559 | } else { | 7582 | } else { |
7560 | s = s.stripWhiteSpace(); | 7583 | s = s.stripWhiteSpace(); |
7561 | if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' ) | 7584 | if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' ) |
7562 | stretch_ = s.left( s.length()-1).toInt(); | 7585 | stretch_ = s.left( s.length()-1).toInt(); |
7563 | } | 7586 | } |
7564 | } | 7587 | } |
7565 | 7588 | ||
7566 | attributes = attr; | 7589 | attributes = attr; |
7567 | 7590 | ||
7568 | parent->addCell( this ); | 7591 | parent->addCell( this ); |
7569 | } | 7592 | } |
7570 | 7593 | ||
7571 | QTextTableCell::~QTextTableCell() | 7594 | QTextTableCell::~QTextTableCell() |
7572 | { | 7595 | { |
7573 | delete background; | 7596 | delete background; |
7574 | background = 0; | 7597 | background = 0; |
7575 | delete richtext; | 7598 | delete richtext; |
7576 | richtext = 0; | 7599 | richtext = 0; |
7577 | } | 7600 | } |
7578 | 7601 | ||
7579 | QSize QTextTableCell::sizeHint() const | 7602 | QSize QTextTableCell::sizeHint() const |
7580 | { | 7603 | { |
7581 | int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance); | 7604 | int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance); |
7582 | int used = richtext->widthUsed() + extra; | 7605 | int used = richtext->widthUsed() + extra; |
7583 | 7606 | ||
7584 | if (stretch_ ) { | 7607 | if (stretch_ ) { |
7585 | int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding; | 7608 | int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding; |
7586 | return QSize( QMIN( w, maxw ), 0 ).expandedTo( minimumSize() ); | 7609 | return QSize( QMIN( w, maxw ), 0 ).expandedTo( minimumSize() ); |
7587 | } | 7610 | } |
7588 | 7611 | ||
7589 | return QSize( used, 0 ).expandedTo( minimumSize() ); | 7612 | return QSize( used, 0 ).expandedTo( minimumSize() ); |
7590 | } | 7613 | } |
7591 | 7614 | ||
7592 | QSize QTextTableCell::minimumSize() const | 7615 | QSize QTextTableCell::minimumSize() const |
7593 | { | 7616 | { |
7594 | int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance); | 7617 | int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance); |
7595 | return QSize( QMAX( richtext->minimumWidth() + extra, minw), 0 ); | 7618 | return QSize( QMAX( richtext->minimumWidth() + extra, minw), 0 ); |
7596 | } | 7619 | } |
7597 | 7620 | ||
7598 | QSize QTextTableCell::maximumSize() const | 7621 | QSize QTextTableCell::maximumSize() const |
7599 | { | 7622 | { |
7600 | return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ); | 7623 | return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ); |
7601 | } | 7624 | } |
7602 | 7625 | ||
7603 | QSizePolicy::ExpandData QTextTableCell::expanding() const | 7626 | QSizePolicy::ExpandData QTextTableCell::expanding() const |
7604 | { | 7627 | { |
7605 | return QSizePolicy::BothDirections; | 7628 | return QSizePolicy::BothDirections; |
7606 | } | 7629 | } |
7607 | 7630 | ||
7608 | bool QTextTableCell::isEmpty() const | 7631 | bool QTextTableCell::isEmpty() const |
7609 | { | 7632 | { |
7610 | return FALSE; | 7633 | return FALSE; |
7611 | } | 7634 | } |
7612 | void QTextTableCell::setGeometry( const QRect& r ) | 7635 | void QTextTableCell::setGeometry( const QRect& r ) |
7613 | { | 7636 | { |
7614 | int extra = 2 * ( parent->innerborder + parent->cellpadding ); | 7637 | int extra = 2 * ( parent->innerborder + parent->cellpadding ); |
7615 | if ( r.width() != cached_width ) | 7638 | if ( r.width() != cached_width ) |
7616 | richtext->doLayout( QTextFormat::painter(), r.width() - extra ); | 7639 | richtext->doLayout( QTextFormat::painter(), r.width() - extra ); |
7617 | cached_width = r.width(); | 7640 | cached_width = r.width(); |
7618 | geom = r; | 7641 | geom = r; |
7619 | } | 7642 | } |
7620 | 7643 | ||
7621 | QRect QTextTableCell::geometry() const | 7644 | QRect QTextTableCell::geometry() const |
7622 | { | 7645 | { |
7623 | return geom; | 7646 | return geom; |
7624 | } | 7647 | } |
7625 | 7648 | ||
7626 | bool QTextTableCell::hasHeightForWidth() const | 7649 | bool QTextTableCell::hasHeightForWidth() const |
7627 | { | 7650 | { |
7628 | return TRUE; | 7651 | return TRUE; |
7629 | } | 7652 | } |
7630 | 7653 | ||
7631 | int QTextTableCell::heightForWidth( int w ) const | 7654 | int QTextTableCell::heightForWidth( int w ) const |
7632 | { | 7655 | { |
7633 | int extra = 2 * ( parent->innerborder + parent->cellpadding ); | 7656 | int extra = 2 * ( parent->innerborder + parent->cellpadding ); |
7634 | w = QMAX( minw, w ); | 7657 | w = QMAX( minw, w ); |
7635 | 7658 | ||
7636 | if ( cached_width != w ) { | 7659 | if ( cached_width != w ) { |
7637 | QTextTableCell* that = (QTextTableCell*) this; | 7660 | QTextTableCell* that = (QTextTableCell*) this; |
7638 | that->richtext->doLayout( QTextFormat::painter(), w - extra ); | 7661 | that->richtext->doLayout( QTextFormat::painter(), w - extra ); |
7639 | that->cached_width = w; | 7662 | that->cached_width = w; |
7640 | } | 7663 | } |
7641 | return richtext->height() + extra; | 7664 | return richtext->height() + extra; |
7642 | } | 7665 | } |
7643 | 7666 | ||
7644 | void QTextTableCell::adjustToPainter( QPainter* p ) | 7667 | void QTextTableCell::adjustToPainter( QPainter* p ) |
7645 | { | 7668 | { |
7646 | QTextParagraph *parag = richtext->firstParagraph(); | 7669 | QTextParagraph *parag = richtext->firstParagraph(); |
7647 | while ( parag ) { | 7670 | while ( parag ) { |
7648 | parag->adjustToPainter( p ); | 7671 | parag->adjustToPainter( p ); |
7649 | parag = parag->next(); | 7672 | parag = parag->next(); |
7650 | } | 7673 | } |
7651 | } | 7674 | } |
7652 | 7675 | ||
7653 | int QTextTableCell::horizontalAlignmentOffset() const | 7676 | int QTextTableCell::horizontalAlignmentOffset() const |
7654 | { | 7677 | { |
7655 | return parent->cellpadding; | 7678 | return parent->cellpadding; |
7656 | } | 7679 | } |
7657 | 7680 | ||
7658 | int QTextTableCell::verticalAlignmentOffset() const | 7681 | int QTextTableCell::verticalAlignmentOffset() const |
7659 | { | 7682 | { |
7660 | if ( (align & Qt::AlignVCenter ) == Qt::AlignVCenter ) | 7683 | if ( (align & Qt::AlignVCenter ) == Qt::AlignVCenter ) |
7661 | return ( geom.height() - richtext->height() ) / 2; | 7684 | return ( geom.height() - richtext->height() ) / 2; |
7662 | else if ( ( align & Qt::AlignBottom ) == Qt::AlignBottom ) | 7685 | else if ( ( align & Qt::AlignBottom ) == Qt::AlignBottom ) |
7663 | return geom.height() - parent->cellpadding - richtext->height() ; | 7686 | return geom.height() - parent->cellpadding - richtext->height() ; |
7664 | return parent->cellpadding; | 7687 | return parent->cellpadding; |
7665 | } | 7688 | } |
7666 | 7689 | ||
7667 | void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool ) | 7690 | void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool ) |
7668 | { | 7691 | { |
7669 | if ( cached_width != geom.width() ) { | 7692 | if ( cached_width != geom.width() ) { |
7670 | int extra = 2 * ( parent->innerborder + parent->cellpadding ); | 7693 | int extra = 2 * ( parent->innerborder + parent->cellpadding ); |
7671 | richtext->doLayout( p, geom.width() - extra ); | 7694 | richtext->doLayout( p, geom.width() - extra ); |
7672 | cached_width = geom.width(); | 7695 | cached_width = geom.width(); |
7673 | } | 7696 | } |
7674 | QColorGroup g( cg ); | 7697 | QColorGroup g( cg ); |
7675 | if ( background ) | 7698 | if ( background ) |
7676 | g.setBrush( QColorGroup::Base, *background ); | 7699 | g.setBrush( QColorGroup::Base, *background ); |
7677 | else if ( richtext->paper() ) | 7700 | else if ( richtext->paper() ) |
7678 | g.setBrush( QColorGroup::Base, *richtext->paper() ); | 7701 | g.setBrush( QColorGroup::Base, *richtext->paper() ); |
7679 | 7702 | ||
7680 | p->save(); | 7703 | p->save(); |
7681 | p->translate( x + geom.x(), y + geom.y() ); | 7704 | p->translate( x + geom.x(), y + geom.y() ); |
7682 | if ( background ) | 7705 | if ( background ) |
7683 | p->fillRect( 0, 0, geom.width(), geom.height(), *background ); | 7706 | p->fillRect( 0, 0, geom.width(), geom.height(), *background ); |
7684 | else if ( richtext->paper() ) | 7707 | else if ( richtext->paper() ) |
7685 | p->fillRect( 0, 0, geom.width(), geom.height(), *richtext->paper() ); | 7708 | p->fillRect( 0, 0, geom.width(), geom.height(), *richtext->paper() ); |
7686 | 7709 | ||
7687 | p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() ); | 7710 | p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() ); |
7688 | 7711 | ||
7689 | QRegion r; | 7712 | QRegion r; |
7690 | if ( cx >= 0 && cy >= 0 ) | 7713 | if ( cx >= 0 && cy >= 0 ) |
7691 | richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ), | 7714 | richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ), |
7692 | cy - ( y + geom.y() + verticalAlignmentOffset() ), | 7715 | cy - ( y + geom.y() + verticalAlignmentOffset() ), |
7693 | cw, ch, g, FALSE, FALSE, 0 ); | 7716 | cw, ch, g, FALSE, FALSE, 0 ); |
7694 | else | 7717 | else |
7695 | richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 ); | 7718 | richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 ); |
7696 | 7719 | ||
7697 | p->restore(); | 7720 | p->restore(); |
7698 | } | 7721 | } |
7699 | 7722 | ||
7700 | QString QTextDocument::section( QString str, const QString &sep, int start, int end ) | 7723 | QString QTextDocument::section( QString str, const QString &sep, int start, int end ) |
7701 | { | 7724 | { |
7702 | const QChar *uc = str.unicode(); | 7725 | const QChar *uc = str.unicode(); |
7703 | if ( !uc ) | 7726 | if ( !uc ) |
7704 | return QString(); | 7727 | return QString(); |
7705 | QString _sep = sep; | 7728 | QString _sep = sep; |
7706 | const QChar *uc_sep = _sep.unicode(); | 7729 | const QChar *uc_sep = _sep.unicode(); |
7707 | if(!uc_sep) | 7730 | if(!uc_sep) |
7708 | return QString(); | 7731 | return QString(); |
7709 | bool match = FALSE, last_match = TRUE; | 7732 | bool match = FALSE, last_match = TRUE; |
7710 | 7733 | ||
7711 | //find start | 7734 | //find start |
7712 | int n = str.length(), sep_len = _sep.length(); | 7735 | int n = str.length(), sep_len = _sep.length(); |
7713 | const QChar *begin = start < 0 ? uc + n : uc; | 7736 | const QChar *begin = start < 0 ? uc + n : uc; |
7714 | while(start) { | 7737 | while(start) { |
7715 | match = FALSE; | 7738 | match = FALSE; |
7716 | int c = 0; | 7739 | int c = 0; |
7717 | for(const QChar *tmp = start < 0 ? begin - sep_len : begin; | 7740 | for(const QChar *tmp = start < 0 ? begin - sep_len : begin; |
7718 | c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { | 7741 | c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { |
7719 | if( *tmp != *(uc_sep + c) ) | 7742 | if( *tmp != *(uc_sep + c) ) |
7720 | break; | 7743 | break; |
7721 | if(c == sep_len - 1) { | 7744 | if(c == sep_len - 1) { |
7722 | match = TRUE; | 7745 | match = TRUE; |
7723 | break; | 7746 | break; |
7724 | } | 7747 | } |
7725 | } | 7748 | } |
7726 | last_match = match; | 7749 | last_match = match; |
7727 | 7750 | ||
7728 | if(start < 0) { | 7751 | if(start < 0) { |
7729 | if(match) { | 7752 | if(match) { |
7730 | begin -= sep_len; | 7753 | begin -= sep_len; |
7731 | if(!++start) | 7754 | if(!++start) |
7732 | break; | 7755 | break; |
7733 | } else { | 7756 | } else { |
7734 | if(start == -1 && begin == uc) | 7757 | if(start == -1 && begin == uc) |
7735 | break; | 7758 | break; |
7736 | begin--; | 7759 | begin--; |
7737 | } | 7760 | } |
7738 | } else { | 7761 | } else { |
7739 | if(match) { | 7762 | if(match) { |
7740 | if(!--start) | 7763 | if(!--start) |
7741 | break; | 7764 | break; |
7742 | begin += sep_len; | 7765 | begin += sep_len; |
7743 | } else { | 7766 | } else { |
7744 | if(start == 1 && begin == uc + n) | 7767 | if(start == 1 && begin == uc + n) |
7745 | break; | 7768 | break; |
7746 | begin++; | 7769 | begin++; |
7747 | } | 7770 | } |
7748 | } | 7771 | } |
7749 | if(begin > uc + n || begin < uc) | 7772 | if(begin > uc + n || begin < uc) |
7750 | return QString(); | 7773 | return QString(); |
7751 | } | 7774 | } |
7752 | if(match) | 7775 | if(match) |
7753 | begin+=sep_len; | 7776 | begin+=sep_len; |
7754 | if(begin > uc + n || begin < uc) | 7777 | if(begin > uc + n || begin < uc) |
7755 | return QString(); | 7778 | return QString(); |
7756 | 7779 | ||
7757 | //now find last | 7780 | //now find last |
7758 | match = FALSE; | 7781 | match = FALSE; |
7759 | const QChar *last = end < 0 ? uc + n : uc; | 7782 | const QChar *last = end < 0 ? uc + n : uc; |
7760 | if(end == -1) { | 7783 | if(end == -1) { |
7761 | int c = 0; | 7784 | int c = 0; |
7762 | for(const QChar *tmp = end < 0 ? last - sep_len : last; | 7785 | for(const QChar *tmp = end < 0 ? last - sep_len : last; |
7763 | c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { | 7786 | c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { |
7764 | if( *tmp != *(uc_sep + c) ) | 7787 | if( *tmp != *(uc_sep + c) ) |
7765 | break; | 7788 | break; |
7766 | if(c == sep_len - 1) { | 7789 | if(c == sep_len - 1) { |
7767 | match = TRUE; | 7790 | match = TRUE; |
7768 | break; | 7791 | break; |
7769 | } | 7792 | } |
7770 | } | 7793 | } |
7771 | } else { | 7794 | } else { |
7772 | end++; | 7795 | end++; |
7773 | last_match = TRUE; | 7796 | last_match = TRUE; |
7774 | while(end) { | 7797 | while(end) { |
7775 | match = FALSE; | 7798 | match = FALSE; |
7776 | int c = 0; | 7799 | int c = 0; |
7777 | for(const QChar *tmp = end < 0 ? last - sep_len : last; | 7800 | for(const QChar *tmp = end < 0 ? last - sep_len : last; |
7778 | c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { | 7801 | c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { |
7779 | if( *tmp != *(uc_sep + c) ) | 7802 | if( *tmp != *(uc_sep + c) ) |
7780 | break; | 7803 | break; |
7781 | if(c == sep_len - 1) { | 7804 | if(c == sep_len - 1) { |
7782 | match = TRUE; | 7805 | match = TRUE; |
7783 | break; | 7806 | break; |
7784 | } | 7807 | } |
7785 | } | 7808 | } |
7786 | last_match = match; | 7809 | last_match = match; |
7787 | 7810 | ||
7788 | if(end < 0) { | 7811 | if(end < 0) { |
7789 | if(match) { | 7812 | if(match) { |
7790 | if(!++end) | 7813 | if(!++end) |
7791 | break; | 7814 | break; |
7792 | last -= sep_len; | 7815 | last -= sep_len; |
7793 | } else { | 7816 | } else { |
7794 | last--; | 7817 | last--; |
7795 | } | 7818 | } |
7796 | } else { | 7819 | } else { |
7797 | if(match) { | 7820 | if(match) { |
7798 | last += sep_len; | 7821 | last += sep_len; |
7799 | if(!--end) | 7822 | if(!--end) |
7800 | break; | 7823 | break; |
7801 | } else { | 7824 | } else { |
7802 | last++; | 7825 | last++; |
7803 | } | 7826 | } |
7804 | } | 7827 | } |
7805 | if(last >= uc + n) { | 7828 | if(last >= uc + n) { |
7806 | last = uc + n; | 7829 | last = uc + n; |
7807 | break; | 7830 | break; |
7808 | } else if(last < uc) { | 7831 | } else if(last < uc) { |
7809 | return QString(); | 7832 | return QString(); |
7810 | } | 7833 | } |
7811 | } | 7834 | } |
7812 | } | 7835 | } |
7813 | if(match) | 7836 | if(match) |
7814 | last -= sep_len; | 7837 | last -= sep_len; |
7815 | if(last < uc || last > uc + n || begin >= last) | 7838 | if(last < uc || last > uc + n || begin >= last) |
7816 | return QString(); | 7839 | return QString(); |
7817 | 7840 | ||
7818 | //done | 7841 | //done |
7819 | return QString(begin, last - begin); | 7842 | return QString(begin, last - begin); |
7820 | } | 7843 | } |
7821 | 7844 | ||
7822 | bool QTextDocument::endsWith( QString str, const QString &s) | 7845 | bool QTextDocument::endsWith( QString str, const QString &s) |
7823 | { | 7846 | { |
7824 | if ( str.isNull() ) | 7847 | if ( str.isNull() ) |
7825 | return s.isNull(); | 7848 | return s.isNull(); |
7826 | int pos = str.length() - s.length(); | 7849 | int pos = str.length() - s.length(); |
7827 | if ( pos < 0 ) | 7850 | if ( pos < 0 ) |
7828 | return FALSE; | 7851 | return FALSE; |
7829 | for ( uint i = 0; i < s.length(); i++ ) { | 7852 | for ( uint i = 0; i < s.length(); i++ ) { |
7830 | if ( str.unicode()[pos+i] != s[(int)i] ) | 7853 | if ( str.unicode()[pos+i] != s[(int)i] ) |
7831 | return FALSE; | 7854 | return FALSE; |
7832 | } | 7855 | } |
7833 | return TRUE; | 7856 | return TRUE; |
7834 | } | 7857 | } |
diff --git a/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp index 9069c09..3fd877f 100644 --- a/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp +++ b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp | |||
@@ -1,329 +1,332 @@ | |||
1 | //-*-c++-*- | 1 | //-*-c++-*- |
2 | /*************************************************************************** | 2 | /*************************************************************************** |
3 | * Copyright (C) 2003 by Fred Schaettgen * | 3 | * Copyright (C) 2003 by Fred Schaettgen * |
4 | * kdebluetooth@schaettgen.de * | 4 | * kdebluetooth@schaettgen.de * |
5 | * * | 5 | * * |
6 | * This program is free software; you can redistribute it and/or modify * | 6 | * This program is free software; you can redistribute it and/or modify * |
7 | * it under the terms of the GNU General Public License as published by * | 7 | * it under the terms of the GNU General Public License as published by * |
8 | * the Free Software Foundation; either version 2 of the License, or * | 8 | * the Free Software Foundation; either version 2 of the License, or * |
9 | * (at your option) any later version. * | 9 | * (at your option) any later version. * |
10 | ***************************************************************************/ | 10 | ***************************************************************************/ |
11 | 11 | ||
12 | #include <assert.h> | 12 | #include <assert.h> |
13 | #include <qregexp.h> | 13 | #include <qregexp.h> |
14 | #include <opie2/odebug.h> | 14 | #include <opie2/odebug.h> |
15 | 15 | ||
16 | #include <OTUUID.h> | 16 | #include <OTUUID.h> |
17 | #include <OTSDPAttribute.h> | 17 | #include <OTSDPAttribute.h> |
18 | 18 | ||
19 | using namespace Opietooth2; | 19 | using namespace Opietooth2; |
20 | 20 | ||
21 | OTSDPAttribute::OTSDPAttribute() { | 21 | OTSDPAttribute::OTSDPAttribute() { |
22 | type = INVALID; | 22 | type = INVALID; |
23 | memset( &Value, 0, sizeof( Value ) ); | 23 | memset( &Value, 0, sizeof( Value ) ); |
24 | } | 24 | } |
25 | 25 | ||
26 | OTSDPAttribute::~OTSDPAttribute() { | 26 | OTSDPAttribute::~OTSDPAttribute() { |
27 | if( type == INT ) { | 27 | if( type == INT ) { |
28 | delete Value.intVal; | 28 | delete Value.intVal; |
29 | } else if( type == UUID ) { | 29 | } else if( type == UUID ) { |
30 | delete Value.uuidVal; | 30 | delete Value.uuidVal; |
31 | } else if( type == UINT ) { | 31 | } else if( type == UINT ) { |
32 | delete Value.uintVal; | 32 | delete Value.uintVal; |
33 | } else if( type == STRING || | 33 | } else if( type == STRING || |
34 | type == URL | 34 | type == URL |
35 | ) { | 35 | ) { |
36 | delete Value.stringVal; | 36 | delete Value.stringVal; |
37 | } else if( type == ALTERNATIVE || | 37 | } else if( type == ALTERNATIVE || |
38 | type == SEQUENCE | 38 | type == SEQUENCE |
39 | ) { | 39 | ) { |
40 | delete Value.sequenceVal; | 40 | delete Value.sequenceVal; |
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | OTSDPAttribute::OTSDPAttribute( sdp_data_t * attrib ) { | 44 | OTSDPAttribute::OTSDPAttribute( sdp_data_t * attrib ) { |
45 | setNil(); | 45 | setNil(); |
46 | switch( attrib->dtd ) { | 46 | switch( attrib->dtd ) { |
47 | case SDP_DATA_NIL: // Nil type | 47 | case SDP_DATA_NIL: // Nil type |
48 | { setNil(); | 48 | { setNil(); |
49 | break; | 49 | break; |
50 | } | 50 | } |
51 | case SDP_UINT8: // Unsigned integer | 51 | case SDP_UINT8: // Unsigned integer |
52 | setUInt(attrib->val.uint8); | 52 | setUInt(attrib->val.uint8); |
53 | break; | 53 | break; |
54 | case SDP_UINT16: // Unsigned integer | 54 | case SDP_UINT16: // Unsigned integer |
55 | setUInt(attrib->val.uint16); | 55 | setUInt(attrib->val.uint16); |
56 | break; | 56 | break; |
57 | case SDP_UINT32: // Unsigned integer | 57 | case SDP_UINT32: // Unsigned integer |
58 | setUInt(attrib->val.uint32); | 58 | setUInt(attrib->val.uint32); |
59 | break; | 59 | break; |
60 | case SDP_UINT64: // Unsigned integer | 60 | case SDP_UINT64: // Unsigned integer |
61 | setUInt(attrib->val.uint64); | 61 | setUInt(attrib->val.uint64); |
62 | break; | 62 | break; |
63 | case SDP_UINT128: // Unsigned integer | 63 | case SDP_UINT128: // Unsigned integer |
64 | // setUInt(attrib->val.uint16); | 64 | // setUInt(attrib->val.uint16); |
65 | assert(false); // BUG/TODO: uint128 integers not supported | 65 | assert(false); // BUG/TODO: uint128 integers not supported |
66 | break; | 66 | break; |
67 | case SDP_INT8: // Unsigned integer | 67 | case SDP_INT8: // Unsigned integer |
68 | setInt(attrib->val.int8); | 68 | setInt(attrib->val.int8); |
69 | break; | 69 | break; |
70 | case SDP_INT16: // Unsigned integer | 70 | case SDP_INT16: // Unsigned integer |
71 | setInt(attrib->val.int16); | 71 | setInt(attrib->val.int16); |
72 | break; | 72 | break; |
73 | case SDP_INT32: // Unsigned integer | 73 | case SDP_INT32: // Unsigned integer |
74 | setInt(attrib->val.int32); | 74 | setInt(attrib->val.int32); |
75 | break; | 75 | break; |
76 | case SDP_INT64: // Unsigned integer | 76 | case SDP_INT64: // Unsigned integer |
77 | setInt(attrib->val.int64); | 77 | setInt(attrib->val.int64); |
78 | break; | 78 | break; |
79 | case SDP_INT128: // Unsigned integer | 79 | case SDP_INT128: // Unsigned integer |
80 | // newAttr.setInt(attrib->val.uint16); | 80 | // newAttr.setInt(attrib->val.uint16); |
81 | assert(false); // BUG/TODO: uint128 integers not supported | 81 | assert(false); // BUG/TODO: uint128 integers not supported |
82 | break; | 82 | break; |
83 | case SDP_UUID16: | 83 | case SDP_UUID16: |
84 | { OTUUID id; | 84 | { OTUUID id; |
85 | ::uuid_t uuidVal = attrib->val.uuid; | 85 | ::uuid_t uuidVal = attrib->val.uuid; |
86 | id.setUUID32(uuidVal.value.uuid16); | 86 | id.setUUID32(uuidVal.value.uuid16); |
87 | setUUID(id ); | 87 | setUUID(id ); |
88 | } | 88 | } |
89 | break; | 89 | break; |
90 | case SDP_UUID32: | 90 | case SDP_UUID32: |
91 | { OTUUID id; | 91 | { OTUUID id; |
92 | ::uuid_t uuidVal = attrib->val.uuid; | 92 | ::uuid_t uuidVal = attrib->val.uuid; |
93 | id.setUUID32(uuidVal.value.uuid32); | 93 | id.setUUID32(uuidVal.value.uuid32); |
94 | setUUID(id ); | 94 | setUUID(id ); |
95 | } | 95 | } |
96 | break; | 96 | break; |
97 | case SDP_UUID128: | 97 | case SDP_UUID128: |
98 | { OTUUID id; | 98 | { OTUUID id; |
99 | ::uuid_t uuidVal = attrib->val.uuid; | 99 | ::uuid_t uuidVal = attrib->val.uuid; |
100 | uint64_t* v128; | 100 | uint64_t* v128; |
101 | v128 = reinterpret_cast<uint64_t*>(&(uuidVal.value.uuid128)); | 101 | v128 = reinterpret_cast<uint64_t*>(&(uuidVal.value.uuid128)); |
102 | id.setUUID128(v128[0], v128[1]); | 102 | id.setUUID128(v128[0], v128[1]); |
103 | setUUID(id ); | 103 | setUUID(id ); |
104 | } | 104 | } |
105 | break; | 105 | break; |
106 | case SDP_TEXT_STR_UNSPEC : | 106 | case SDP_TEXT_STR_UNSPEC : |
107 | case SDP_TEXT_STR8 : | 107 | case SDP_TEXT_STR8 : |
108 | case SDP_TEXT_STR16 : | 108 | case SDP_TEXT_STR16 : |
109 | case SDP_TEXT_STR32 : | 109 | case SDP_TEXT_STR32 : |
110 | setString( QString(attrib->val.str) ); | 110 | setString( QString(attrib->val.str) ); |
111 | break; | 111 | break; |
112 | case SDP_URL_STR_UNSPEC : | 112 | case SDP_URL_STR_UNSPEC : |
113 | case SDP_URL_STR8 : | 113 | case SDP_URL_STR8 : |
114 | case SDP_URL_STR16 : | 114 | case SDP_URL_STR16 : |
115 | case SDP_URL_STR32 : | 115 | case SDP_URL_STR32 : |
116 | setURL( QString(attrib->val.str) ); | 116 | setURL( QString(attrib->val.str) ); |
117 | break; | 117 | break; |
118 | case SDP_BOOL: | 118 | case SDP_BOOL: |
119 | setBool( attrib->val.int8 != 0); | 119 | setBool( attrib->val.int8 != 0); |
120 | break; | 120 | break; |
121 | case SDP_SEQ_UNSPEC : | 121 | case SDP_SEQ_UNSPEC : |
122 | case SDP_SEQ8 : | 122 | case SDP_SEQ8 : |
123 | case SDP_SEQ16 : | 123 | case SDP_SEQ16 : |
124 | case SDP_SEQ32 : | 124 | case SDP_SEQ32 : |
125 | case SDP_ALT_UNSPEC : | 125 | case SDP_ALT_UNSPEC : |
126 | case SDP_ALT8 : | 126 | case SDP_ALT8 : |
127 | case SDP_ALT16 : | 127 | case SDP_ALT16 : |
128 | case SDP_ALT32 : | 128 | case SDP_ALT32 : |
129 | { AttributeVector subAttribs; | 129 | { AttributeVector subAttribs; |
130 | OTSDPAttribute * Attr; | 130 | OTSDPAttribute * Attr; |
131 | sdp_data_t* subAttrib = attrib->val.dataseq; | 131 | sdp_data_t* subAttrib = attrib->val.dataseq; |
132 | 132 | ||
133 | for (; subAttrib; subAttrib = subAttrib->next) { | 133 | for (; subAttrib; subAttrib = subAttrib->next) { |
134 | 134 | ||
135 | Attr = new OTSDPAttribute(subAttrib); | 135 | Attr = new OTSDPAttribute(subAttrib); |
136 | subAttribs.resize( subAttribs.size() + 1 ); | 136 | subAttribs.resize( subAttribs.size() + 1 ); |
137 | subAttribs.insert( subAttribs.size() - 1, Attr ); | 137 | subAttribs.insert( subAttribs.size() - 1, Attr ); |
138 | } | 138 | } |
139 | 139 | ||
140 | if( attrib->dtd == SDP_ALT_UNSPEC || | 140 | if( attrib->dtd == SDP_ALT_UNSPEC || |
141 | attrib->dtd == SDP_ALT8 || | 141 | attrib->dtd == SDP_ALT8 || |
142 | attrib->dtd == SDP_ALT16 || | 142 | attrib->dtd == SDP_ALT16 || |
143 | attrib->dtd == SDP_ALT32 ) { | 143 | attrib->dtd == SDP_ALT32 ) { |
144 | setAlternative(subAttribs); | 144 | setAlternative(subAttribs); |
145 | } else { | 145 | } else { |
146 | setSequence(subAttribs); | 146 | setSequence(subAttribs); |
147 | } | 147 | } |
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | } // end case | 150 | } // end case |
151 | } | 151 | } |
152 | 152 | ||
153 | QString OTSDPAttribute::toString( void ) { | 153 | QString OTSDPAttribute::toString( void ) { |
154 | QString S; | 154 | QString S; |
155 | switch( type ) { | 155 | switch( type ) { |
156 | case INVALID : | 156 | case INVALID : |
157 | S = "invalid"; | 157 | S = "invalid"; |
158 | break; | 158 | break; |
159 | case NIL : | 159 | case NIL : |
160 | S = "NIL"; | 160 | S = "NIL"; |
161 | break; | 161 | break; |
162 | case UINT : | 162 | case UINT : |
163 | S = Value.uintVal->toString(); | 163 | S = Value.uintVal->toString(); |
164 | break; | 164 | break; |
165 | case INT : | 165 | case INT : |
166 | S = Value.intVal->toString(); | 166 | S = Value.intVal->toString(); |
167 | break; | 167 | break; |
168 | case UUID : | 168 | case UUID : |
169 | S = Value.uuidVal->toString(); | 169 | S = Value.uuidVal->toString(); |
170 | break; | 170 | break; |
171 | case BOOLEAN : | 171 | case BOOLEAN : |
172 | S = (Value.boolVal) ? "true" : "false"; | 172 | S = (Value.boolVal) ? "true" : "false"; |
173 | break; | 173 | break; |
174 | case STRING : | 174 | case STRING : |
175 | S = *(Value.stringVal); | 175 | S = *(Value.stringVal); |
176 | break; | 176 | break; |
177 | case URL : | 177 | case URL : |
178 | S = *(Value.stringVal); | 178 | S = *(Value.stringVal); |
179 | break; | 179 | break; |
180 | case SEQUENCE : | 180 | case SEQUENCE : |
181 | S.sprintf( "Sequence(%d)", Value.sequenceVal->count() ); | 181 | S.sprintf( "Sequence(%d)", Value.sequenceVal->count() ); |
182 | break; | 182 | break; |
183 | case ALTERNATIVE : | 183 | case ALTERNATIVE : |
184 | S.sprintf( "Alternative(%d)", Value.sequenceVal->count() ); | 184 | S.sprintf( "Alternative(%d)", Value.sequenceVal->count() ); |
185 | break; | 185 | break; |
186 | case UNKNOWN : | 186 | case UNKNOWN : |
187 | S = "unknown"; | 187 | S = "unknown"; |
188 | break; | 188 | break; |
189 | } | 189 | } |
190 | return S; | 190 | return S; |
191 | } | 191 | } |
192 | 192 | ||
193 | void OTSDPAttribute::setNil() { | 193 | void OTSDPAttribute::setNil() { |
194 | type = NIL; | 194 | type = NIL; |
195 | } | 195 | } |
196 | 196 | ||
197 | void OTSDPAttribute::setInt(const OTSDPAttribute::int128_t & val) { | 197 | void OTSDPAttribute::setInt(const OTSDPAttribute::int128_t & val) { |
198 | type = INT; | 198 | type = INT; |
199 | Value.intVal = new int128_t( val ); | 199 | Value.intVal = new int128_t( val ); |
200 | } | 200 | } |
201 | 201 | ||
202 | void OTSDPAttribute::setUInt(const uint128_t & val) { | 202 | void OTSDPAttribute::setUInt(const uint128_t & val) { |
203 | type = UINT; | 203 | type = UINT; |
204 | Value.uintVal = new uint128_t(val); | 204 | Value.uintVal = new uint128_t(val); |
205 | } | 205 | } |
206 | 206 | ||
207 | void OTSDPAttribute::setUUID(const OTUUID & val) { | 207 | void OTSDPAttribute::setUUID(const OTUUID & val) { |
208 | type = UUID; | 208 | type = UUID; |
209 | Value.uuidVal = new OTUUID( val ); | 209 | Value.uuidVal = new OTUUID( val ); |
210 | } | 210 | } |
211 | 211 | ||
212 | void OTSDPAttribute::setBool(bool val) { | 212 | void OTSDPAttribute::setBool(bool val) { |
213 | type = BOOLEAN; | 213 | type = BOOLEAN; |
214 | Value.boolVal = val; | 214 | Value.boolVal = val; |
215 | } | 215 | } |
216 | 216 | ||
217 | void OTSDPAttribute::setString( const QString & val) { | 217 | void OTSDPAttribute::setString( const QString & val) { |
218 | type = STRING; | 218 | type = STRING; |
219 | Value.stringVal = new QString( val ); | 219 | Value.stringVal = new QString( val ); |
220 | } | 220 | } |
221 | 221 | ||
222 | void OTSDPAttribute::setURL( const QString & val) { | 222 | void OTSDPAttribute::setURL( const QString & val) { |
223 | type = URL; | 223 | type = URL; |
224 | Value.stringVal = new QString(val); | 224 | Value.stringVal = new QString(val); |
225 | } | 225 | } |
226 | 226 | ||
227 | void OTSDPAttribute::setSequence(const AttributeVector& val) { | 227 | void OTSDPAttribute::setSequence(const AttributeVector& val) { |
228 | type = SEQUENCE; | 228 | type = SEQUENCE; |
229 | Value.sequenceVal = new AttributeVector(); | 229 | Value.sequenceVal = new AttributeVector(); |
230 | Value.sequenceVal->setAutoDelete( TRUE ); | 230 | Value.sequenceVal->setAutoDelete( TRUE ); |
231 | *Value.sequenceVal = val; | 231 | *Value.sequenceVal = val; |
232 | } | 232 | } |
233 | 233 | ||
234 | void OTSDPAttribute::setAlternative(const AttributeVector& val) { | 234 | void OTSDPAttribute::setAlternative(const AttributeVector& val) { |
235 | type = ALTERNATIVE; | 235 | type = ALTERNATIVE; |
236 | Value.sequenceVal = new AttributeVector(); | 236 | Value.sequenceVal = new AttributeVector(); |
237 | Value.sequenceVal->setAutoDelete( TRUE ); | 237 | Value.sequenceVal->setAutoDelete( TRUE ); |
238 | *Value.sequenceVal = val; | 238 | *Value.sequenceVal = val; |
239 | } | 239 | } |
240 | 240 | ||
241 | QString OTSDPAttribute::getString() { | 241 | QString OTSDPAttribute::getString() { |
242 | assert(type == STRING); | 242 | assert(type == STRING); |
243 | return *Value.stringVal; | 243 | return *Value.stringVal; |
244 | } | 244 | } |
245 | 245 | ||
246 | QString OTSDPAttribute::getURL() { | 246 | QString OTSDPAttribute::getURL() { |
247 | assert(type == URL); | 247 | assert(type == URL); |
248 | return *Value.stringVal; | 248 | return *Value.stringVal; |
249 | } | 249 | } |
250 | 250 | ||
251 | const OTSDPAttribute::int128_t & OTSDPAttribute::getInt() { | 251 | const OTSDPAttribute::int128_t & OTSDPAttribute::getInt() { |
252 | assert(type == INT); | 252 | assert(type == INT); |
253 | return *Value.intVal; | 253 | return *Value.intVal; |
254 | } | 254 | } |
255 | 255 | ||
256 | 256 | ||
257 | const OTSDPAttribute::uint128_t & OTSDPAttribute::getUInt() { | 257 | const OTSDPAttribute::uint128_t & OTSDPAttribute::getUInt() { |
258 | assert(type == UINT); | 258 | assert(type == UINT); |
259 | return *Value.uintVal; | 259 | return *Value.uintVal; |
260 | } | 260 | } |
261 | 261 | ||
262 | const OTUUID & OTSDPAttribute::getUUID() { | 262 | const OTUUID & OTSDPAttribute::getUUID() { |
263 | assert(type == UUID); | 263 | assert(type == UUID); |
264 | return *Value.uuidVal; | 264 | return *Value.uuidVal; |
265 | } | 265 | } |
266 | 266 | ||
267 | bool OTSDPAttribute::getBool() { | 267 | bool OTSDPAttribute::getBool() { |
268 | assert(type == BOOLEAN); | 268 | assert(type == BOOLEAN); |
269 | return Value.boolVal; | 269 | return Value.boolVal; |
270 | } | 270 | } |
271 | 271 | ||
272 | AttributeVector * OTSDPAttribute::getSequence() { | 272 | AttributeVector * OTSDPAttribute::getSequence() { |
273 | assert(type == SEQUENCE); | 273 | assert(type == SEQUENCE); |
274 | return Value.sequenceVal; | 274 | return Value.sequenceVal; |
275 | } | 275 | } |
276 | 276 | ||
277 | AttributeVector * OTSDPAttribute::getAlternative() { | 277 | AttributeVector * OTSDPAttribute::getAlternative() { |
278 | assert(type == ALTERNATIVE); | 278 | assert(type == ALTERNATIVE); |
279 | return Value.sequenceVal; | 279 | return Value.sequenceVal; |
280 | } | 280 | } |
281 | 281 | ||
282 | UUIDVector OTSDPAttribute::getAllUUIDs() { | 282 | UUIDVector OTSDPAttribute::getAllUUIDs() { |
283 | 283 | ||
284 | UUIDVector uuids; | 284 | UUIDVector uuids; |
285 | 285 | ||
286 | if (getType() == UUID) { | 286 | if (getType() == UUID) { |
287 | uuids.resize( uuids.size()+1 ); | 287 | uuids.resize( uuids.size()+1 ); |
288 | uuids[uuids.size()-1] = getUUID(); | 288 | uuids[uuids.size()-1] = getUUID(); |
289 | } else { | 289 | } else { |
290 | AttributeVector * subAttributes = 0 ; | 290 | AttributeVector * subAttributes = 0 ; |
291 | 291 | ||
292 | if (getType() == SEQUENCE) { | 292 | if (getType() == SEQUENCE) { |
293 | subAttributes = getSequence(); | 293 | subAttributes = getSequence(); |
294 | } else if (getType() == ALTERNATIVE) { | 294 | } else if (getType() == ALTERNATIVE) { |
295 | subAttributes = getAlternative(); | 295 | subAttributes = getAlternative(); |
296 | } | 296 | } |
297 | 297 | ||
298 | if (!subAttributes) | ||
299 | return 0; | ||
300 | |||
298 | int os; | 301 | int os; |
299 | for( unsigned int i = 0; i < subAttributes->count(); i++ ) { | 302 | for( unsigned int i = 0; i < subAttributes->count(); i++ ) { |
300 | UUIDVector subUUIDs = (*subAttributes)[i]->getAllUUIDs(); | 303 | UUIDVector subUUIDs = (*subAttributes)[i]->getAllUUIDs(); |
301 | 304 | ||
302 | os = uuids.size(); | 305 | os = uuids.size(); |
303 | uuids.resize( uuids.size()+subUUIDs.count() ); | 306 | uuids.resize( uuids.size()+subUUIDs.count() ); |
304 | 307 | ||
305 | for( unsigned int k = 0; k < subUUIDs.count(); k++ ) { | 308 | for( unsigned int k = 0; k < subUUIDs.count(); k++ ) { |
306 | uuids[os + k] = subUUIDs[k]; | 309 | uuids[os + k] = subUUIDs[k]; |
307 | } | 310 | } |
308 | } | 311 | } |
309 | } | 312 | } |
310 | return uuids; | 313 | return uuids; |
311 | } | 314 | } |
312 | 315 | ||
313 | static char * Attr2String[] = { | 316 | static char * Attr2String[] = { |
314 | "Invalid", | 317 | "Invalid", |
315 | "Nil", | 318 | "Nil", |
316 | "UInt", | 319 | "UInt", |
317 | "int", | 320 | "int", |
318 | "UUID", | 321 | "UUID", |
319 | "Boolean", | 322 | "Boolean", |
320 | "String", | 323 | "String", |
321 | "Sequence", | 324 | "Sequence", |
322 | "Alternative", | 325 | "Alternative", |
323 | "URL", | 326 | "URL", |
324 | "Unknown" | 327 | "Unknown" |
325 | }; | 328 | }; |
326 | 329 | ||
327 | const char * OTSDPAttribute::getTypeString() { | 330 | const char * OTSDPAttribute::getTypeString() { |
328 | return Attr2String[type]; | 331 | return Attr2String[type]; |
329 | } | 332 | } |
diff --git a/noncore/settings/packagemanager/oipkgconfigdlg.cpp b/noncore/settings/packagemanager/oipkgconfigdlg.cpp index d014378..78a18f7 100644 --- a/noncore/settings/packagemanager/oipkgconfigdlg.cpp +++ b/noncore/settings/packagemanager/oipkgconfigdlg.cpp | |||
@@ -1,716 +1,718 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | 3 | ||
4 | Copyright (C)2004, 2005 Dan Williams <drw@handhelds.org> | 4 | Copyright (C)2004, 2005 Dan Williams <drw@handhelds.org> |
5 | =. | 5 | =. |
6 | .=l. | 6 | .=l. |
7 | .>+-= | 7 | .>+-= |
8 | _;:, .> :=|. This program is free software; you can | 8 | _;:, .> :=|. This program is free software; you can |
9 | .> <`_, > . <= redistribute it and/or modify it under | 9 | .> <`_, > . <= redistribute it and/or modify it under |
10 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | 10 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public |
11 | .="- .-=="i, .._ License as published by the Free Software | 11 | .="- .-=="i, .._ License as published by the Free Software |
12 | - . .-<_> .<> Foundation; either version 2 of the License, | 12 | - . .-<_> .<> Foundation; either version 2 of the License, |
13 | ._= =} : or (at your option) any later version. | 13 | ._= =} : or (at your option) any later version. |
14 | .%`+i> _;_. | 14 | .%`+i> _;_. |
15 | .i_,=:_. -<s. This program is distributed in the hope that | 15 | .i_,=:_. -<s. This program is distributed in the hope that |
16 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | 16 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; |
17 | : .. .:, . . . without even the implied warranty of | 17 | : .. .:, . . . without even the implied warranty of |
18 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | 18 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A |
19 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | 19 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU |
20 | ..}^=.= = ; Library General Public License for more | 20 | ..}^=.= = ; Library General Public License for more |
21 | ++= -. .` .: details. | 21 | ++= -. .` .: details. |
22 | : = ...= . :.=- | 22 | : = ...= . :.=- |
23 | -. .:....=;==+<; You should have received a copy of the GNU | 23 | -. .:....=;==+<; You should have received a copy of the GNU |
24 | -_. . . )=. = Library General Public License along with | 24 | -_. . . )=. = Library General Public License along with |
25 | -- :-=` this library; see the file COPYING.LIB. | 25 | -- :-=` this library; see the file COPYING.LIB. |
26 | If not, write to the Free Software Foundation, | 26 | If not, write to the Free Software Foundation, |
27 | Inc., 59 Temple Place - Suite 330, | 27 | Inc., 59 Temple Place - Suite 330, |
28 | Boston, MA 02111-1307, USA. | 28 | Boston, MA 02111-1307, USA. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "oipkgconfigdlg.h" | 31 | #include "oipkgconfigdlg.h" |
32 | 32 | ||
33 | #include <opie2/ofiledialog.h> | 33 | #include <opie2/ofiledialog.h> |
34 | #include <opie2/oresource.h> | 34 | #include <opie2/oresource.h> |
35 | 35 | ||
36 | #include <qpe/qpeapplication.h> | 36 | #include <qpe/qpeapplication.h> |
37 | 37 | ||
38 | #include <qcheckbox.h> | 38 | #include <qcheckbox.h> |
39 | #include <qcombobox.h> | 39 | #include <qcombobox.h> |
40 | #include <qgroupbox.h> | 40 | #include <qgroupbox.h> |
41 | #include <qlabel.h> | 41 | #include <qlabel.h> |
42 | #include <qlineedit.h> | 42 | #include <qlineedit.h> |
43 | #include <qlistbox.h> | 43 | #include <qlistbox.h> |
44 | #include <qpushbutton.h> | 44 | #include <qpushbutton.h> |
45 | #include <qscrollview.h> | 45 | #include <qscrollview.h> |
46 | #include <qwhatsthis.h> | 46 | #include <qwhatsthis.h> |
47 | 47 | ||
48 | OIpkgConfigDlg::OIpkgConfigDlg( OIpkg *ipkg, bool installOptions, QWidget *parent ) | 48 | OIpkgConfigDlg::OIpkgConfigDlg( OIpkg *ipkg, bool installOptions, QWidget *parent ) |
49 | : QDialog( parent, QString::null, true, WStyle_ContextHelp ) | 49 | : QDialog( parent, QString::null, true, WStyle_ContextHelp ) |
50 | , m_ipkg( ipkg ) | 50 | , m_ipkg( ipkg ) |
51 | , m_configs( 0l ) | 51 | , m_configs( 0l ) |
52 | , m_installOptions( installOptions ) | 52 | , m_installOptions( installOptions ) |
53 | , m_serverCurrent( -1 ) | 53 | , m_serverCurrent( -1 ) |
54 | , m_destCurrent( -1 ) | 54 | , m_destCurrent( -1 ) |
55 | , m_layout( this, 2, 4 ) | 55 | , m_layout( this, 2, 4 ) |
56 | , m_tabWidget( this ) | 56 | , m_tabWidget( this ) |
57 | { | 57 | { |
58 | setCaption( tr( "Configuration" ) ); | 58 | setCaption( tr( "Configuration" ) ); |
59 | 59 | ||
60 | // Initialize configuration widgets | 60 | // Initialize configuration widgets |
61 | if ( !installOptions ) | 61 | if ( !installOptions ) |
62 | { | 62 | { |
63 | initServerWidget(); | 63 | initServerWidget(); |
64 | initDestinationWidget(); | 64 | initDestinationWidget(); |
65 | initProxyWidget(); | 65 | initProxyWidget(); |
66 | } | 66 | } |
67 | initOptionsWidget(); | 67 | initOptionsWidget(); |
68 | 68 | ||
69 | // Load configuration information | 69 | // Load configuration information |
70 | initData(); | 70 | initData(); |
71 | 71 | ||
72 | // Setup tabs for all info | 72 | // Setup tabs for all info |
73 | m_layout.addWidget( &m_tabWidget ); | 73 | m_layout.addWidget( &m_tabWidget ); |
74 | if ( !m_installOptions ) | 74 | if ( !m_installOptions ) |
75 | { | 75 | { |
76 | m_tabWidget.addTab( m_serverWidget, "packagemanager/servertab", tr( "Servers" ) ); | 76 | m_tabWidget.addTab( m_serverWidget, "packagemanager/servertab", tr( "Servers" ) ); |
77 | m_tabWidget.addTab( m_destWidget, "packagemanager/desttab", tr( "Destinations" ) ); | 77 | m_tabWidget.addTab( m_destWidget, "packagemanager/desttab", tr( "Destinations" ) ); |
78 | m_tabWidget.addTab( m_proxyWidget, "packagemanager/proxytab", tr( "Proxies" ) ); | 78 | m_tabWidget.addTab( m_proxyWidget, "packagemanager/proxytab", tr( "Proxies" ) ); |
79 | m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); | 79 | m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); |
80 | m_tabWidget.setCurrentTab( tr( "Servers" ) ); | 80 | m_tabWidget.setCurrentTab( tr( "Servers" ) ); |
81 | } | 81 | } |
82 | else | 82 | else |
83 | { | 83 | { |
84 | m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); | 84 | m_tabWidget.addTab( m_optionsWidget, "exec", tr( "Options" ) ); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | void OIpkgConfigDlg::accept() | 88 | void OIpkgConfigDlg::accept() |
89 | { | 89 | { |
90 | // Save server, destination and proxy configuration | 90 | // Save server, destination and proxy configuration |
91 | if ( !m_installOptions ) | 91 | if ( !m_installOptions ) |
92 | { | 92 | { |
93 | // Update proxy information before saving settings | 93 | // Update proxy information before saving settings |
94 | OConfItem *confItem = m_ipkg->findConfItem( OConfItem::Option, "http_proxy" ); | 94 | OConfItem *confItem = m_ipkg->findConfItem( OConfItem::Option, "http_proxy" ); |
95 | if ( confItem ) | 95 | if ( confItem ) |
96 | { | 96 | { |
97 | confItem->setValue( m_proxyHttpServer->text() ); | 97 | confItem->setValue( m_proxyHttpServer->text() ); |
98 | confItem->setActive( m_proxyHttpActive->isChecked() ); | 98 | confItem->setActive( m_proxyHttpActive->isChecked() ); |
99 | } | 99 | } |
100 | else | 100 | else |
101 | m_configs->append( new OConfItem( OConfItem::Option, "http_proxy", | 101 | m_configs->append( new OConfItem( OConfItem::Option, "http_proxy", |
102 | m_proxyHttpServer->text(), QString::null, | 102 | m_proxyHttpServer->text(), QString::null, |
103 | m_proxyHttpActive->isChecked() ) ); | 103 | m_proxyHttpActive->isChecked() ) ); |
104 | 104 | ||
105 | confItem = m_ipkg->findConfItem( OConfItem::Option, "ftp_proxy" ); | 105 | confItem = m_ipkg->findConfItem( OConfItem::Option, "ftp_proxy" ); |
106 | if ( confItem ) | 106 | if ( confItem ) |
107 | { | 107 | { |
108 | confItem->setValue( m_proxyFtpServer->text() ); | 108 | confItem->setValue( m_proxyFtpServer->text() ); |
109 | confItem->setActive( m_proxyFtpActive->isChecked() ); | 109 | confItem->setActive( m_proxyFtpActive->isChecked() ); |
110 | } | 110 | } |
111 | else | 111 | else |
112 | m_configs->append( new OConfItem( OConfItem::Option, "ftp_proxy", | 112 | m_configs->append( new OConfItem( OConfItem::Option, "ftp_proxy", |
113 | m_proxyFtpServer->text(), QString::null, | 113 | m_proxyFtpServer->text(), QString::null, |
114 | m_proxyFtpActive->isChecked() ) ); | 114 | m_proxyFtpActive->isChecked() ) ); |
115 | 115 | ||
116 | confItem = m_ipkg->findConfItem( OConfItem::Option, "proxy_username" ); | 116 | confItem = m_ipkg->findConfItem( OConfItem::Option, "proxy_username" ); |
117 | if ( confItem ) | 117 | if ( confItem ) |
118 | confItem->setValue( m_proxyUsername->text() ); | 118 | confItem->setValue( m_proxyUsername->text() ); |
119 | else | 119 | else |
120 | m_configs->append( new OConfItem( OConfItem::Option, "proxy_username", | 120 | m_configs->append( new OConfItem( OConfItem::Option, "proxy_username", |
121 | m_proxyUsername->text() ) ); | 121 | m_proxyUsername->text() ) ); |
122 | 122 | ||
123 | confItem = m_ipkg->findConfItem( OConfItem::Option, "proxy_password" ); | 123 | confItem = m_ipkg->findConfItem( OConfItem::Option, "proxy_password" ); |
124 | if ( confItem ) | 124 | if ( confItem ) |
125 | confItem->setValue( m_proxyPassword->text() ); | 125 | confItem->setValue( m_proxyPassword->text() ); |
126 | else | 126 | else |
127 | m_configs->append( new OConfItem( OConfItem::Option, "proxy_password", | 127 | m_configs->append( new OConfItem( OConfItem::Option, "proxy_password", |
128 | m_proxyPassword->text() ) ); | 128 | m_proxyPassword->text() ) ); |
129 | 129 | ||
130 | QString listsDir = m_optSourceLists->text(); | 130 | QString listsDir = m_optSourceLists->text(); |
131 | if ( listsDir == QString::null || listsDir == "" ) | 131 | if ( listsDir == QString::null || listsDir == "" ) |
132 | listsDir = "/usr/lib/ipkg/lists"; // TODO - use proper libipkg define | 132 | listsDir = "/usr/lib/ipkg/lists"; // TODO - use proper libipkg define |
133 | confItem = m_ipkg->findConfItem( OConfItem::Other, "lists_dir" ); | 133 | confItem = m_ipkg->findConfItem( OConfItem::Other, "lists_dir" ); |
134 | if ( confItem ) | 134 | if ( confItem ) |
135 | confItem->setValue( listsDir ); | 135 | confItem->setValue( listsDir ); |
136 | else | 136 | else |
137 | m_configs->append( new OConfItem( OConfItem::Other, "lists_dir", | 137 | m_configs->append( new OConfItem( OConfItem::Other, "lists_dir", |
138 | listsDir, "name" ) ); | 138 | listsDir, "name" ) ); |
139 | 139 | ||
140 | m_ipkg->setConfigItems( m_configs ); | 140 | m_ipkg->setConfigItems( m_configs ); |
141 | } | 141 | } |
142 | 142 | ||
143 | // Save options configuration | 143 | // Save options configuration |
144 | int options = 0; | 144 | int options = 0; |
145 | if ( m_optForceDepends->isChecked() ) | 145 | if ( m_optForceDepends->isChecked() ) |
146 | options |= FORCE_DEPENDS; | 146 | options |= FORCE_DEPENDS; |
147 | if ( m_optForceReinstall->isChecked() ) | 147 | if ( m_optForceReinstall->isChecked() ) |
148 | options |= FORCE_REINSTALL; | 148 | options |= FORCE_REINSTALL; |
149 | if ( m_optForceRemove->isChecked() ) | 149 | if ( m_optForceRemove->isChecked() ) |
150 | options |= FORCE_REMOVE; | 150 | options |= FORCE_REMOVE; |
151 | if ( m_optForceOverwrite->isChecked() ) | 151 | if ( m_optForceOverwrite->isChecked() ) |
152 | options |= FORCE_OVERWRITE; | 152 | options |= FORCE_OVERWRITE; |
153 | if ( m_optForceRecursive->isChecked() ) | 153 | if ( m_optForceRecursive->isChecked() ) |
154 | options |= FORCE_RECURSIVE; | 154 | options |= FORCE_RECURSIVE; |
155 | if ( m_optVerboseWget->isChecked() ) | 155 | if ( m_optVerboseWget->isChecked() ) |
156 | options |= FORCE_VERBOSE_WGET; | 156 | options |= FORCE_VERBOSE_WGET; |
157 | m_ipkg->setIpkgExecOptions( options ); | 157 | m_ipkg->setIpkgExecOptions( options ); |
158 | m_ipkg->setIpkgExecVerbosity( m_optVerboseIpkg->currentItem() ); | 158 | m_ipkg->setIpkgExecVerbosity( m_optVerboseIpkg->currentItem() ); |
159 | 159 | ||
160 | QDialog::accept(); | 160 | QDialog::accept(); |
161 | } | 161 | } |
162 | 162 | ||
163 | void OIpkgConfigDlg::reject() | 163 | void OIpkgConfigDlg::reject() |
164 | { | 164 | { |
165 | if ( m_configs ) | 165 | if ( m_configs ) |
166 | delete m_configs; | 166 | delete m_configs; |
167 | } | 167 | } |
168 | 168 | ||
169 | void OIpkgConfigDlg::initServerWidget() | 169 | void OIpkgConfigDlg::initServerWidget() |
170 | { | 170 | { |
171 | m_serverWidget = new QWidget( this ); | 171 | m_serverWidget = new QWidget( this ); |
172 | 172 | ||
173 | // Initialize UI | 173 | // Initialize UI |
174 | QVBoxLayout *vb = new QVBoxLayout( m_serverWidget ); | 174 | QVBoxLayout *vb = new QVBoxLayout( m_serverWidget ); |
175 | QScrollView *sv = new QScrollView( m_serverWidget ); | 175 | QScrollView *sv = new QScrollView( m_serverWidget ); |
176 | vb->addWidget( sv, 0, 0 ); | 176 | vb->addWidget( sv, 0, 0 ); |
177 | sv->setResizePolicy( QScrollView::AutoOneFit ); | 177 | sv->setResizePolicy( QScrollView::AutoOneFit ); |
178 | sv->setFrameStyle( QFrame::NoFrame ); | 178 | sv->setFrameStyle( QFrame::NoFrame ); |
179 | QWidget *container = new QWidget( sv->viewport() ); | 179 | QWidget *container = new QWidget( sv->viewport() ); |
180 | sv->addChild( container ); | 180 | sv->addChild( container ); |
181 | QGridLayout *layout = new QGridLayout( container, 2, 3, 2, 4 ); | 181 | QGridLayout *layout = new QGridLayout( container, 2, 3, 2, 4 ); |
182 | 182 | ||
183 | m_serverList = new QListBox( container ); | 183 | m_serverList = new QListBox( container ); |
184 | QWhatsThis::add( m_serverList, tr( "This is a list of all servers configured. Select one here to edit or delete, or add a new one below." ) ); | 184 | QWhatsThis::add( m_serverList, tr( "This is a list of all servers configured. Select one here to edit or delete, or add a new one below." ) ); |
185 | m_serverList->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); | 185 | m_serverList->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); |
186 | connect( m_serverList, SIGNAL(highlighted(int)), this, SLOT(slotServerSelected(int)) ); | 186 | connect( m_serverList, SIGNAL(highlighted(int)), this, SLOT(slotServerSelected(int)) ); |
187 | layout->addMultiCellWidget( m_serverList, 0, 0, 0, 2 ); | 187 | layout->addMultiCellWidget( m_serverList, 0, 0, 0, 2 ); |
188 | 188 | ||
189 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ), | 189 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ), |
190 | tr( "New" ), container ); | 190 | tr( "New" ), container ); |
191 | btn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 191 | btn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
192 | QWhatsThis::add( btn, tr( "Tap here to create a new entry. Fill in the fields below and then tap on Update." ) ); | 192 | QWhatsThis::add( btn, tr( "Tap here to create a new entry. Fill in the fields below and then tap on Update." ) ); |
193 | connect( btn, SIGNAL(clicked()), this, SLOT(slotServerNew()) ); | 193 | connect( btn, SIGNAL(clicked()), this, SLOT(slotServerNew()) ); |
194 | layout->addWidget( btn, 1, 0 ); | 194 | layout->addWidget( btn, 1, 0 ); |
195 | 195 | ||
196 | m_serverEditBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ), | 196 | m_serverEditBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ), |
197 | tr( "Edit" ), container ); | 197 | tr( "Edit" ), container ); |
198 | m_serverEditBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 198 | m_serverEditBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
199 | m_serverEditBtn->setEnabled( false ); | 199 | m_serverEditBtn->setEnabled( false ); |
200 | QWhatsThis::add( m_serverEditBtn, tr( "Tap here to edit the entry selected above." ) ); | 200 | QWhatsThis::add( m_serverEditBtn, tr( "Tap here to edit the entry selected above." ) ); |
201 | connect( m_serverEditBtn, SIGNAL(clicked()), this, SLOT(slotServerEdit()) ); | 201 | connect( m_serverEditBtn, SIGNAL(clicked()), this, SLOT(slotServerEdit()) ); |
202 | layout->addWidget( m_serverEditBtn, 1, 1 ); | 202 | layout->addWidget( m_serverEditBtn, 1, 1 ); |
203 | 203 | ||
204 | m_serverDeleteBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ), | 204 | m_serverDeleteBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ), |
205 | tr( "Delete" ), container ); | 205 | tr( "Delete" ), container ); |
206 | m_serverDeleteBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 206 | m_serverDeleteBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
207 | m_serverDeleteBtn->setEnabled( false ); | 207 | m_serverDeleteBtn->setEnabled( false ); |
208 | QWhatsThis::add( m_serverDeleteBtn, tr( "Tap here to delete the entry selected above." ) ); | 208 | QWhatsThis::add( m_serverDeleteBtn, tr( "Tap here to delete the entry selected above." ) ); |
209 | connect( m_serverDeleteBtn, SIGNAL(clicked()), this, SLOT(slotServerDelete()) ); | 209 | connect( m_serverDeleteBtn, SIGNAL(clicked()), this, SLOT(slotServerDelete()) ); |
210 | layout->addWidget( m_serverDeleteBtn, 1, 2 ); | 210 | layout->addWidget( m_serverDeleteBtn, 1, 2 ); |
211 | } | 211 | } |
212 | 212 | ||
213 | void OIpkgConfigDlg::initDestinationWidget() | 213 | void OIpkgConfigDlg::initDestinationWidget() |
214 | { | 214 | { |
215 | m_destWidget = new QWidget( this ); | 215 | m_destWidget = new QWidget( this ); |
216 | 216 | ||
217 | // Initialize UI | 217 | // Initialize UI |
218 | QVBoxLayout *vb = new QVBoxLayout( m_destWidget ); | 218 | QVBoxLayout *vb = new QVBoxLayout( m_destWidget ); |
219 | QScrollView *sv = new QScrollView( m_destWidget ); | 219 | QScrollView *sv = new QScrollView( m_destWidget ); |
220 | vb->addWidget( sv, 0, 0 ); | 220 | vb->addWidget( sv, 0, 0 ); |
221 | sv->setResizePolicy( QScrollView::AutoOneFit ); | 221 | sv->setResizePolicy( QScrollView::AutoOneFit ); |
222 | sv->setFrameStyle( QFrame::NoFrame ); | 222 | sv->setFrameStyle( QFrame::NoFrame ); |
223 | QWidget *container = new QWidget( sv->viewport() ); | 223 | QWidget *container = new QWidget( sv->viewport() ); |
224 | sv->addChild( container ); | 224 | sv->addChild( container ); |
225 | QGridLayout *layout = new QGridLayout( container, 2, 3, 2, 4 ); | 225 | QGridLayout *layout = new QGridLayout( container, 2, 3, 2, 4 ); |
226 | 226 | ||
227 | m_destList = new QListBox( container ); | 227 | m_destList = new QListBox( container ); |
228 | QWhatsThis::add( m_destList, tr( "This is a list of all destinations configured for this device. Select one here to edit or delete, or add a new one below." ) ); | 228 | QWhatsThis::add( m_destList, tr( "This is a list of all destinations configured for this device. Select one here to edit or delete, or add a new one below." ) ); |
229 | m_destList->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); | 229 | m_destList->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); |
230 | connect( m_destList, SIGNAL(highlighted(int)), this, SLOT(slotDestSelected(int)) ); | 230 | connect( m_destList, SIGNAL(highlighted(int)), this, SLOT(slotDestSelected(int)) ); |
231 | layout->addMultiCellWidget( m_destList, 0, 0, 0, 2 ); | 231 | layout->addMultiCellWidget( m_destList, 0, 0, 0, 2 ); |
232 | 232 | ||
233 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ), | 233 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ), |
234 | tr( "New" ), container ); | 234 | tr( "New" ), container ); |
235 | btn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 235 | btn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
236 | QWhatsThis::add( btn, tr( "Tap here to create a new entry. Fill in the fields below and then tap on Update." ) ); | 236 | QWhatsThis::add( btn, tr( "Tap here to create a new entry. Fill in the fields below and then tap on Update." ) ); |
237 | connect( btn, SIGNAL(clicked()), this, SLOT(slotDestNew()) ); | 237 | connect( btn, SIGNAL(clicked()), this, SLOT(slotDestNew()) ); |
238 | layout->addWidget( btn, 1, 0 ); | 238 | layout->addWidget( btn, 1, 0 ); |
239 | 239 | ||
240 | m_destEditBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ), | 240 | m_destEditBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ), |
241 | tr( "Edit" ), container ); | 241 | tr( "Edit" ), container ); |
242 | m_destEditBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 242 | m_destEditBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
243 | m_destEditBtn->setEnabled( false ); | 243 | m_destEditBtn->setEnabled( false ); |
244 | QWhatsThis::add( m_destEditBtn, tr( "Tap here to edit the entry selected above." ) ); | 244 | QWhatsThis::add( m_destEditBtn, tr( "Tap here to edit the entry selected above." ) ); |
245 | connect( m_destEditBtn, SIGNAL(clicked()), this, SLOT(slotDestEdit()) ); | 245 | connect( m_destEditBtn, SIGNAL(clicked()), this, SLOT(slotDestEdit()) ); |
246 | layout->addWidget( m_destEditBtn, 1, 1 ); | 246 | layout->addWidget( m_destEditBtn, 1, 1 ); |
247 | 247 | ||
248 | m_destDeleteBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ), | 248 | m_destDeleteBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ), |
249 | tr( "Delete" ), container ); | 249 | tr( "Delete" ), container ); |
250 | m_destDeleteBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 250 | m_destDeleteBtn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
251 | m_destDeleteBtn->setEnabled( false ); | 251 | m_destDeleteBtn->setEnabled( false ); |
252 | QWhatsThis::add( m_destDeleteBtn, tr( "Tap here to delete the entry selected above." ) ); | 252 | QWhatsThis::add( m_destDeleteBtn, tr( "Tap here to delete the entry selected above." ) ); |
253 | connect( m_destDeleteBtn, SIGNAL(clicked()), this, SLOT(slotDestDelete()) ); | 253 | connect( m_destDeleteBtn, SIGNAL(clicked()), this, SLOT(slotDestDelete()) ); |
254 | layout->addWidget( m_destDeleteBtn, 1, 2 ); | 254 | layout->addWidget( m_destDeleteBtn, 1, 2 ); |
255 | } | 255 | } |
256 | 256 | ||
257 | void OIpkgConfigDlg::initProxyWidget() | 257 | void OIpkgConfigDlg::initProxyWidget() |
258 | { | 258 | { |
259 | m_proxyWidget = new QWidget( this ); | 259 | m_proxyWidget = new QWidget( this ); |
260 | 260 | ||
261 | // Initialize UI | 261 | // Initialize UI |
262 | QVBoxLayout *vb = new QVBoxLayout( m_proxyWidget ); | 262 | QVBoxLayout *vb = new QVBoxLayout( m_proxyWidget ); |
263 | QScrollView *sv = new QScrollView( m_proxyWidget ); | 263 | QScrollView *sv = new QScrollView( m_proxyWidget ); |
264 | vb->addWidget( sv, 0, 0 ); | 264 | vb->addWidget( sv, 0, 0 ); |
265 | sv->setResizePolicy( QScrollView::AutoOneFit ); | 265 | sv->setResizePolicy( QScrollView::AutoOneFit ); |
266 | sv->setFrameStyle( QFrame::NoFrame ); | 266 | sv->setFrameStyle( QFrame::NoFrame ); |
267 | QWidget *container = new QWidget( sv->viewport() ); | 267 | QWidget *container = new QWidget( sv->viewport() ); |
268 | sv->addChild( container ); | 268 | sv->addChild( container ); |
269 | QGridLayout *layout = new QGridLayout( container, 4, 2, 2, 4 ); | 269 | QGridLayout *layout = new QGridLayout( container, 4, 2, 2, 4 ); |
270 | 270 | ||
271 | // HTTP proxy server configuration | 271 | // HTTP proxy server configuration |
272 | QGroupBox *grpbox = new QGroupBox( 0, Qt::Vertical, tr( "HTTP Proxy" ), container ); | 272 | QGroupBox *grpbox = new QGroupBox( 0, Qt::Vertical, tr( "HTTP Proxy" ), container ); |
273 | grpbox->layout()->setSpacing( 2 ); | 273 | grpbox->layout()->setSpacing( 2 ); |
274 | grpbox->layout()->setMargin( 4 ); | 274 | grpbox->layout()->setMargin( 4 ); |
275 | layout->addMultiCellWidget( grpbox, 0, 0, 0, 1 ); | 275 | layout->addMultiCellWidget( grpbox, 0, 0, 0, 1 ); |
276 | QVBoxLayout *grplayout = new QVBoxLayout( grpbox->layout() ); | 276 | QVBoxLayout *grplayout = new QVBoxLayout( grpbox->layout() ); |
277 | m_proxyHttpServer = new QLineEdit( grpbox ); | 277 | m_proxyHttpServer = new QLineEdit( grpbox ); |
278 | QWhatsThis::add( m_proxyHttpServer, tr( "Enter the URL address of the HTTP proxy server here." ) ); | 278 | QWhatsThis::add( m_proxyHttpServer, tr( "Enter the URL address of the HTTP proxy server here." ) ); |
279 | grplayout->addWidget( m_proxyHttpServer ); | 279 | grplayout->addWidget( m_proxyHttpServer ); |
280 | m_proxyHttpActive = new QCheckBox( tr( "Enabled" ), grpbox ); | 280 | m_proxyHttpActive = new QCheckBox( tr( "Enabled" ), grpbox ); |
281 | QWhatsThis::add( m_proxyHttpActive, tr( "Tap here to enable or disable the HTTP proxy server." ) ); | 281 | QWhatsThis::add( m_proxyHttpActive, tr( "Tap here to enable or disable the HTTP proxy server." ) ); |
282 | grplayout->addWidget( m_proxyHttpActive ); | 282 | grplayout->addWidget( m_proxyHttpActive ); |
283 | 283 | ||
284 | // FTP proxy server configuration | 284 | // FTP proxy server configuration |
285 | grpbox = new QGroupBox( 0, Qt::Vertical, tr( "FTP Proxy" ), container ); | 285 | grpbox = new QGroupBox( 0, Qt::Vertical, tr( "FTP Proxy" ), container ); |
286 | grpbox->layout()->setSpacing( 2 ); | 286 | grpbox->layout()->setSpacing( 2 ); |
287 | grpbox->layout()->setMargin( 4 ); | 287 | grpbox->layout()->setMargin( 4 ); |
288 | layout->addMultiCellWidget( grpbox, 1, 1, 0, 1 ); | 288 | layout->addMultiCellWidget( grpbox, 1, 1, 0, 1 ); |
289 | grplayout = new QVBoxLayout( grpbox->layout() ); | 289 | grplayout = new QVBoxLayout( grpbox->layout() ); |
290 | m_proxyFtpServer = new QLineEdit( grpbox ); | 290 | m_proxyFtpServer = new QLineEdit( grpbox ); |
291 | QWhatsThis::add( m_proxyFtpServer, tr( "Enter the URL address of the FTP proxy server here." ) ); | 291 | QWhatsThis::add( m_proxyFtpServer, tr( "Enter the URL address of the FTP proxy server here." ) ); |
292 | grplayout->addWidget( m_proxyFtpServer ); | 292 | grplayout->addWidget( m_proxyFtpServer ); |
293 | m_proxyFtpActive = new QCheckBox( tr( "Enabled" ), grpbox ); | 293 | m_proxyFtpActive = new QCheckBox( tr( "Enabled" ), grpbox ); |
294 | QWhatsThis::add( m_proxyFtpActive, tr( "Tap here to enable or disable the FTP proxy server." ) ); | 294 | QWhatsThis::add( m_proxyFtpActive, tr( "Tap here to enable or disable the FTP proxy server." ) ); |
295 | grplayout->addWidget( m_proxyFtpActive ); | 295 | grplayout->addWidget( m_proxyFtpActive ); |
296 | 296 | ||
297 | // Proxy server username and password configuration | 297 | // Proxy server username and password configuration |
298 | QLabel *label = new QLabel( tr( "Username:" ), container ); | 298 | QLabel *label = new QLabel( tr( "Username:" ), container ); |
299 | QWhatsThis::add( label, tr( "Enter the username for the proxy servers here." ) ); | 299 | QWhatsThis::add( label, tr( "Enter the username for the proxy servers here." ) ); |
300 | layout->addWidget( label, 2, 0 ); | 300 | layout->addWidget( label, 2, 0 ); |
301 | m_proxyUsername = new QLineEdit( container ); | 301 | m_proxyUsername = new QLineEdit( container ); |
302 | QWhatsThis::add( m_proxyUsername, tr( "Enter the username for the proxy servers here." ) ); | 302 | QWhatsThis::add( m_proxyUsername, tr( "Enter the username for the proxy servers here." ) ); |
303 | layout->addWidget( m_proxyUsername, 2, 1 ); | 303 | layout->addWidget( m_proxyUsername, 2, 1 ); |
304 | 304 | ||
305 | label = new QLabel( tr( "Password:" ), container ); | 305 | label = new QLabel( tr( "Password:" ), container ); |
306 | QWhatsThis::add( label, tr( "Enter the password for the proxy servers here." ) ); | 306 | QWhatsThis::add( label, tr( "Enter the password for the proxy servers here." ) ); |
307 | layout->addWidget( label, 3, 0 ); | 307 | layout->addWidget( label, 3, 0 ); |
308 | m_proxyPassword = new QLineEdit( container ); | 308 | m_proxyPassword = new QLineEdit( container ); |
309 | QWhatsThis::add( m_proxyPassword, tr( "Enter the password for the proxy servers here." ) ); | 309 | QWhatsThis::add( m_proxyPassword, tr( "Enter the password for the proxy servers here." ) ); |
310 | layout->addWidget( m_proxyPassword, 3, 1 ); | 310 | layout->addWidget( m_proxyPassword, 3, 1 ); |
311 | } | 311 | } |
312 | 312 | ||
313 | void OIpkgConfigDlg::initOptionsWidget() | 313 | void OIpkgConfigDlg::initOptionsWidget() |
314 | { | 314 | { |
315 | m_optionsWidget = new QWidget( this ); | 315 | m_optionsWidget = new QWidget( this ); |
316 | 316 | ||
317 | // Initialize UI | 317 | // Initialize UI |
318 | QVBoxLayout *vb = new QVBoxLayout( m_optionsWidget ); | 318 | QVBoxLayout *vb = new QVBoxLayout( m_optionsWidget ); |
319 | QScrollView *sv = new QScrollView( m_optionsWidget ); | 319 | QScrollView *sv = new QScrollView( m_optionsWidget ); |
320 | vb->addWidget( sv, 0, 0 ); | 320 | vb->addWidget( sv, 0, 0 ); |
321 | sv->setResizePolicy( QScrollView::AutoOneFit ); | 321 | sv->setResizePolicy( QScrollView::AutoOneFit ); |
322 | sv->setFrameStyle( QFrame::NoFrame ); | 322 | sv->setFrameStyle( QFrame::NoFrame ); |
323 | QWidget *container = new QWidget( sv->viewport() ); | 323 | QWidget *container = new QWidget( sv->viewport() ); |
324 | sv->addChild( container ); | 324 | sv->addChild( container ); |
325 | QGridLayout *layout = new QGridLayout( container, 8, 2, 2, 4 ); | 325 | QGridLayout *layout = new QGridLayout( container, 8, 2, 2, 4 ); |
326 | 326 | ||
327 | m_optForceDepends = new QCheckBox( tr( "Force Depends" ), container ); | 327 | m_optForceDepends = new QCheckBox( tr( "Force Depends" ), container ); |
328 | QWhatsThis::add( m_optForceDepends, tr( "Tap here to enable or disable the '-force-depends' option for Ipkg." ) ); | 328 | QWhatsThis::add( m_optForceDepends, tr( "Tap here to enable or disable the '-force-depends' option for Ipkg." ) ); |
329 | layout->addMultiCellWidget( m_optForceDepends, 0, 0, 0, 1 ); | 329 | layout->addMultiCellWidget( m_optForceDepends, 0, 0, 0, 1 ); |
330 | 330 | ||
331 | m_optForceReinstall = new QCheckBox( tr( "Force Reinstall" ), container ); | 331 | m_optForceReinstall = new QCheckBox( tr( "Force Reinstall" ), container ); |
332 | QWhatsThis::add( m_optForceReinstall, tr( "Tap here to enable or disable the '-force-reinstall' option for Ipkg." ) ); | 332 | QWhatsThis::add( m_optForceReinstall, tr( "Tap here to enable or disable the '-force-reinstall' option for Ipkg." ) ); |
333 | layout->addMultiCellWidget( m_optForceReinstall, 1, 1, 0, 1 ); | 333 | layout->addMultiCellWidget( m_optForceReinstall, 1, 1, 0, 1 ); |
334 | 334 | ||
335 | m_optForceRemove = new QCheckBox( tr( "Force Remove" ), container ); | 335 | m_optForceRemove = new QCheckBox( tr( "Force Remove" ), container ); |
336 | QWhatsThis::add( m_optForceRemove, tr( "Tap here to enable or disable the '-force-removal-of-dependent-packages' option for Ipkg." ) ); | 336 | QWhatsThis::add( m_optForceRemove, tr( "Tap here to enable or disable the '-force-removal-of-dependent-packages' option for Ipkg." ) ); |
337 | layout->addMultiCellWidget( m_optForceRemove, 2, 2, 0, 1 ); | 337 | layout->addMultiCellWidget( m_optForceRemove, 2, 2, 0, 1 ); |
338 | 338 | ||
339 | m_optForceOverwrite = new QCheckBox( tr( "Force Overwrite" ), container ); | 339 | m_optForceOverwrite = new QCheckBox( tr( "Force Overwrite" ), container ); |
340 | QWhatsThis::add( m_optForceOverwrite, tr( "Tap here to enable or disable the '-force-overwrite' option for Ipkg." ) ); | 340 | QWhatsThis::add( m_optForceOverwrite, tr( "Tap here to enable or disable the '-force-overwrite' option for Ipkg." ) ); |
341 | layout->addMultiCellWidget( m_optForceOverwrite, 3, 3, 0, 1 ); | 341 | layout->addMultiCellWidget( m_optForceOverwrite, 3, 3, 0, 1 ); |
342 | 342 | ||
343 | m_optForceRecursive = new QCheckBox( tr( "Force Recursive" ), container ); | 343 | m_optForceRecursive = new QCheckBox( tr( "Force Recursive" ), container ); |
344 | QWhatsThis::add( m_optForceRecursive, tr( "Tap here to enable or disable the '-recursive' option for Ipkg." ) ); | 344 | QWhatsThis::add( m_optForceRecursive, tr( "Tap here to enable or disable the '-recursive' option for Ipkg." ) ); |
345 | layout->addMultiCellWidget( m_optForceRecursive, 4, 4, 0, 1 ); | 345 | layout->addMultiCellWidget( m_optForceRecursive, 4, 4, 0, 1 ); |
346 | 346 | ||
347 | m_optVerboseWget = new QCheckBox( tr( "Verbose fetch" ), container ); | 347 | m_optVerboseWget = new QCheckBox( tr( "Verbose fetch" ), container ); |
348 | QWhatsThis::add( m_optVerboseWget, tr( "Tap here to enable or disable the '-verbose_wget' option for Ipkg." ) ); | 348 | QWhatsThis::add( m_optVerboseWget, tr( "Tap here to enable or disable the '-verbose_wget' option for Ipkg." ) ); |
349 | layout->addMultiCellWidget( m_optVerboseWget, 5, 5, 0, 1 ); | 349 | layout->addMultiCellWidget( m_optVerboseWget, 5, 5, 0, 1 ); |
350 | 350 | ||
351 | QLabel *l = new QLabel( tr( "Information level:" ), container ); | 351 | QLabel *l = new QLabel( tr( "Information level:" ), container ); |
352 | QWhatsThis::add( l, tr( "Select information level for Ipkg." ) ); | 352 | QWhatsThis::add( l, tr( "Select information level for Ipkg." ) ); |
353 | layout->addMultiCellWidget( l, 6, 6, 0, 1 ); | 353 | layout->addMultiCellWidget( l, 6, 6, 0, 1 ); |
354 | 354 | ||
355 | m_optVerboseIpkg = new QComboBox( container ); | 355 | m_optVerboseIpkg = new QComboBox( container ); |
356 | QWhatsThis::add( m_optVerboseIpkg, tr( "Select information level for Ipkg." ) ); | 356 | QWhatsThis::add( m_optVerboseIpkg, tr( "Select information level for Ipkg." ) ); |
357 | m_optVerboseIpkg->insertItem( tr( "Errors only" ) ); | 357 | m_optVerboseIpkg->insertItem( tr( "Errors only" ) ); |
358 | m_optVerboseIpkg->insertItem( tr( "Normal messages" ) ); | 358 | m_optVerboseIpkg->insertItem( tr( "Normal messages" ) ); |
359 | m_optVerboseIpkg->insertItem( tr( "Informative messages" ) ); | 359 | m_optVerboseIpkg->insertItem( tr( "Informative messages" ) ); |
360 | m_optVerboseIpkg->insertItem( tr( "Troubleshooting output" ) ); | 360 | m_optVerboseIpkg->insertItem( tr( "Troubleshooting output" ) ); |
361 | layout->addMultiCellWidget( m_optVerboseIpkg, 7, 7, 0, 1 ); | 361 | layout->addMultiCellWidget( m_optVerboseIpkg, 7, 7, 0, 1 ); |
362 | 362 | ||
363 | l = new QLabel( tr( "Package source lists directory:" ), container ); | 363 | l = new QLabel( tr( "Package source lists directory:" ), container ); |
364 | QWhatsThis::add( l, tr( "Enter the directory where package source feed information is stored." ) ); | 364 | QWhatsThis::add( l, tr( "Enter the directory where package source feed information is stored." ) ); |
365 | layout->addMultiCellWidget( l, 8, 8, 0, 1 ); | 365 | layout->addMultiCellWidget( l, 8, 8, 0, 1 ); |
366 | 366 | ||
367 | m_optSourceLists = new QLineEdit( container ); | 367 | m_optSourceLists = new QLineEdit( container ); |
368 | QWhatsThis::add( m_optSourceLists, tr( "Enter the directory where package source feed information is stored." ) ); | 368 | QWhatsThis::add( m_optSourceLists, tr( "Enter the directory where package source feed information is stored." ) ); |
369 | layout->addWidget( m_optSourceLists, 9, 0 ); | 369 | layout->addWidget( m_optSourceLists, 9, 0 ); |
370 | 370 | ||
371 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "folder", Opie::Core::OResource::SmallIcon ), | 371 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "folder", Opie::Core::OResource::SmallIcon ), |
372 | QString::null, container ); | 372 | QString::null, container ); |
373 | btn->setMinimumHeight( AppLnk::smallIconSize()+4 ); | 373 | btn->setMinimumHeight( AppLnk::smallIconSize()+4 ); |
374 | btn->setMaximumWidth( btn->height() ); | 374 | btn->setMaximumWidth( btn->height() ); |
375 | QWhatsThis::add( btn, tr( "Tap here to select the directory where package source feed information is stored." ) ); | 375 | QWhatsThis::add( btn, tr( "Tap here to select the directory where package source feed information is stored." ) ); |
376 | connect( btn, SIGNAL(clicked()), this, SLOT(slotOptSelectSourceListsPath()) ); | 376 | connect( btn, SIGNAL(clicked()), this, SLOT(slotOptSelectSourceListsPath()) ); |
377 | layout->addWidget( btn, 9, 1 ); | 377 | layout->addWidget( btn, 9, 1 ); |
378 | 378 | ||
379 | layout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); | 379 | layout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); |
380 | } | 380 | } |
381 | 381 | ||
382 | void OIpkgConfigDlg::initData() | 382 | void OIpkgConfigDlg::initData() |
383 | { | 383 | { |
384 | // Read ipkg configuration (server/destination/proxy) information | 384 | // Read ipkg configuration (server/destination/proxy) information |
385 | if ( m_ipkg && !m_installOptions ) | 385 | if ( m_ipkg && !m_installOptions ) |
386 | { | 386 | { |
387 | m_configs = m_ipkg->configItems(); | 387 | m_configs = m_ipkg->configItems(); |
388 | if ( m_configs ) | 388 | if ( m_configs ) |
389 | { | 389 | { |
390 | for ( OConfItemListIterator configIt( *m_configs ); configIt.current(); ++configIt ) | 390 | for ( OConfItemListIterator configIt( *m_configs ); configIt.current(); ++configIt ) |
391 | { | 391 | { |
392 | OConfItem *config = configIt.current(); | 392 | OConfItem *config = configIt.current(); |
393 | 393 | ||
394 | // Add configuration item to the appropriate dialog controls | 394 | // Add configuration item to the appropriate dialog controls |
395 | if ( config ) | 395 | if ( config ) |
396 | { | 396 | { |
397 | switch ( config->type() ) | 397 | switch ( config->type() ) |
398 | { | 398 | { |
399 | case OConfItem::Source : m_serverList->insertItem( config->name() ); break; | 399 | case OConfItem::Source : m_serverList->insertItem( config->name() ); break; |
400 | case OConfItem::Destination : m_destList->insertItem( config->name() ); break; | 400 | case OConfItem::Destination : m_destList->insertItem( config->name() ); break; |
401 | case OConfItem::Option : | 401 | case OConfItem::Option : |
402 | { | 402 | { |
403 | if ( config->name() == "http_proxy" ) | 403 | if ( config->name() == "http_proxy" ) |
404 | { | 404 | { |
405 | m_proxyHttpServer->setText( config->value() ); | 405 | m_proxyHttpServer->setText( config->value() ); |
406 | m_proxyHttpActive->setChecked( config->active() ); | 406 | m_proxyHttpActive->setChecked( config->active() ); |
407 | } | 407 | } |
408 | else if ( config->name() == "ftp_proxy" ) | 408 | else if ( config->name() == "ftp_proxy" ) |
409 | { | 409 | { |
410 | m_proxyFtpServer->setText( config->value() ); | 410 | m_proxyFtpServer->setText( config->value() ); |
411 | m_proxyFtpActive->setChecked( config->active() ); | 411 | m_proxyFtpActive->setChecked( config->active() ); |
412 | } | 412 | } |
413 | else if ( config->name() == "proxy_username" ) | 413 | else if ( config->name() == "proxy_username" ) |
414 | { | 414 | { |
415 | m_proxyUsername->setText( config->value() ); | 415 | m_proxyUsername->setText( config->value() ); |
416 | } | 416 | } |
417 | else if ( config->name() == "proxy_password" ) | 417 | else if ( config->name() == "proxy_password" ) |
418 | { | 418 | { |
419 | m_proxyPassword->setText( config->value() ); | 419 | m_proxyPassword->setText( config->value() ); |
420 | } | 420 | } |
421 | } | 421 | } |
422 | break; | 422 | break; |
423 | case OConfItem::Other : | 423 | case OConfItem::Other : |
424 | { | 424 | { |
425 | if ( config->name() == "lists_dir" ) | 425 | if ( config->name() == "lists_dir" ) |
426 | m_optSourceLists->setText( config->value() ); | 426 | m_optSourceLists->setText( config->value() ); |
427 | else // TODO - use proper libipkg define | 427 | else // TODO - use proper libipkg define |
428 | m_optSourceLists->setText( "/usr/lib/ipkg/lists" ); | 428 | m_optSourceLists->setText( "/usr/lib/ipkg/lists" ); |
429 | } | 429 | } |
430 | break; | 430 | break; |
431 | default : break; | 431 | default : break; |
432 | }; | 432 | }; |
433 | } | 433 | } |
434 | } | 434 | } |
435 | } | 435 | } |
436 | } | 436 | } |
437 | 437 | ||
438 | // Get Ipkg execution options | 438 | // Get Ipkg execution options |
439 | int options = m_ipkg->ipkgExecOptions(); | 439 | int options = 0; |
440 | if ( m_ipkg ) | ||
441 | options = m_ipkg->ipkgExecOptions(); | ||
440 | if ( options & FORCE_DEPENDS ) | 442 | if ( options & FORCE_DEPENDS ) |
441 | m_optForceDepends->setChecked( true ); | 443 | m_optForceDepends->setChecked( true ); |
442 | if ( options & FORCE_REINSTALL ) | 444 | if ( options & FORCE_REINSTALL ) |
443 | m_optForceReinstall->setChecked( true ); | 445 | m_optForceReinstall->setChecked( true ); |
444 | if ( options & FORCE_REMOVE ) | 446 | if ( options & FORCE_REMOVE ) |
445 | m_optForceRemove->setChecked( true ); | 447 | m_optForceRemove->setChecked( true ); |
446 | if ( options & FORCE_OVERWRITE ) | 448 | if ( options & FORCE_OVERWRITE ) |
447 | m_optForceOverwrite->setChecked( true ); | 449 | m_optForceOverwrite->setChecked( true ); |
448 | if ( options & FORCE_RECURSIVE ) | 450 | if ( options & FORCE_RECURSIVE ) |
449 | m_optForceRecursive->setChecked( true ); | 451 | m_optForceRecursive->setChecked( true ); |
450 | if ( options & FORCE_VERBOSE_WGET ) | 452 | if ( options & FORCE_VERBOSE_WGET ) |
451 | m_optVerboseWget->setChecked( true ); | 453 | m_optVerboseWget->setChecked( true ); |
452 | 454 | ||
453 | m_optVerboseIpkg->setCurrentItem( m_ipkg->ipkgExecVerbosity() ); | 455 | m_optVerboseIpkg->setCurrentItem( ( m_ipkg ? m_ipkg->ipkgExecVerbosity() : 0 ) ); |
454 | } | 456 | } |
455 | 457 | ||
456 | void OIpkgConfigDlg::slotServerSelected( int index ) | 458 | void OIpkgConfigDlg::slotServerSelected( int index ) |
457 | { | 459 | { |
458 | m_serverCurrent = index; | 460 | m_serverCurrent = index; |
459 | 461 | ||
460 | // Enable Edit and Delete buttons | 462 | // Enable Edit and Delete buttons |
461 | m_serverEditBtn->setEnabled( true ); | 463 | m_serverEditBtn->setEnabled( true ); |
462 | m_serverDeleteBtn->setEnabled( true ); | 464 | m_serverDeleteBtn->setEnabled( true ); |
463 | } | 465 | } |
464 | 466 | ||
465 | void OIpkgConfigDlg::slotServerNew() | 467 | void OIpkgConfigDlg::slotServerNew() |
466 | { | 468 | { |
467 | OConfItem *server = new OConfItem( OConfItem::Source ); | 469 | OConfItem *server = new OConfItem( OConfItem::Source ); |
468 | 470 | ||
469 | OIpkgServerDlg dlg( server, this ); | 471 | OIpkgServerDlg dlg( server, this ); |
470 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) | 472 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) |
471 | { | 473 | { |
472 | // Add to configuration option list | 474 | // Add to configuration option list |
473 | m_configs->append( server ); | 475 | m_configs->append( server ); |
474 | m_configs->sort(); | 476 | m_configs->sort(); |
475 | 477 | ||
476 | // Add to server list | 478 | // Add to server list |
477 | m_serverList->insertItem( server->name() ); | 479 | m_serverList->insertItem( server->name() ); |
478 | m_serverList->setCurrentItem( m_serverList->count() ); | 480 | m_serverList->setCurrentItem( m_serverList->count() ); |
479 | } | 481 | } |
480 | else | 482 | else |
481 | delete server; | 483 | delete server; |
482 | } | 484 | } |
483 | 485 | ||
484 | void OIpkgConfigDlg::slotServerEdit() | 486 | void OIpkgConfigDlg::slotServerEdit() |
485 | { | 487 | { |
486 | // Find selected server in list | 488 | // Find selected server in list |
487 | OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() ); | 489 | OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() ); |
488 | 490 | ||
489 | // Edit server | 491 | // Edit server |
490 | if ( server ) | 492 | if ( server ) |
491 | { | 493 | { |
492 | QString origName = server->name(); | 494 | QString origName = server->name(); |
493 | OIpkgServerDlg dlg( server, this ); | 495 | OIpkgServerDlg dlg( server, this ); |
494 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) | 496 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) |
495 | { | 497 | { |
496 | // Check to see if name has changed, if so update the server list | 498 | // Check to see if name has changed, if so update the server list |
497 | if ( server->name() != origName ) | 499 | if ( server->name() != origName ) |
498 | m_serverList->changeItem( server->name(), m_serverCurrent ); | 500 | m_serverList->changeItem( server->name(), m_serverCurrent ); |
499 | } | 501 | } |
500 | } | 502 | } |
501 | } | 503 | } |
502 | 504 | ||
503 | void OIpkgConfigDlg::slotServerDelete() | 505 | void OIpkgConfigDlg::slotServerDelete() |
504 | { | 506 | { |
505 | // Find selected server in list | 507 | // Find selected server in list |
506 | OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() ); | 508 | OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() ); |
507 | 509 | ||
508 | // Delete server | 510 | // Delete server |
509 | if ( server ) | 511 | if ( server ) |
510 | { | 512 | { |
511 | m_configs->removeRef( server ); | 513 | m_configs->removeRef( server ); |
512 | m_serverList->removeItem( m_serverCurrent ); | 514 | m_serverList->removeItem( m_serverCurrent ); |
513 | } | 515 | } |
514 | } | 516 | } |
515 | 517 | ||
516 | void OIpkgConfigDlg::slotDestSelected( int index ) | 518 | void OIpkgConfigDlg::slotDestSelected( int index ) |
517 | { | 519 | { |
518 | m_destCurrent = index; | 520 | m_destCurrent = index; |
519 | 521 | ||
520 | // Enable Edit and Delete buttons | 522 | // Enable Edit and Delete buttons |
521 | m_destEditBtn->setEnabled( true ); | 523 | m_destEditBtn->setEnabled( true ); |
522 | m_destDeleteBtn->setEnabled( true ); | 524 | m_destDeleteBtn->setEnabled( true ); |
523 | } | 525 | } |
524 | 526 | ||
525 | void OIpkgConfigDlg::slotDestNew() | 527 | void OIpkgConfigDlg::slotDestNew() |
526 | { | 528 | { |
527 | OConfItem *dest = new OConfItem( OConfItem::Destination ); | 529 | OConfItem *dest = new OConfItem( OConfItem::Destination ); |
528 | 530 | ||
529 | OIpkgDestDlg dlg( dest, this ); | 531 | OIpkgDestDlg dlg( dest, this ); |
530 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) | 532 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) |
531 | { | 533 | { |
532 | // Add to configuration option list | 534 | // Add to configuration option list |
533 | m_configs->append( dest ); | 535 | m_configs->append( dest ); |
534 | m_configs->sort(); | 536 | m_configs->sort(); |
535 | 537 | ||
536 | // Add to destination list | 538 | // Add to destination list |
537 | m_destList->insertItem( dest->name() ); | 539 | m_destList->insertItem( dest->name() ); |
538 | m_destList->setCurrentItem( m_destList->count() ); | 540 | m_destList->setCurrentItem( m_destList->count() ); |
539 | } | 541 | } |
540 | else | 542 | else |
541 | delete dest; | 543 | delete dest; |
542 | } | 544 | } |
543 | 545 | ||
544 | void OIpkgConfigDlg::slotDestEdit() | 546 | void OIpkgConfigDlg::slotDestEdit() |
545 | { | 547 | { |
546 | // Find selected destination in list | 548 | // Find selected destination in list |
547 | OConfItem *dest = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() ); | 549 | OConfItem *dest = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() ); |
548 | 550 | ||
549 | // Edit destination | 551 | // Edit destination |
550 | if ( dest ) | 552 | if ( dest ) |
551 | { | 553 | { |
552 | QString origName = dest->name(); | 554 | QString origName = dest->name(); |
553 | OIpkgDestDlg dlg( dest, this ); | 555 | OIpkgDestDlg dlg( dest, this ); |
554 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) | 556 | if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted ) |
555 | { | 557 | { |
556 | // Check to see if name has changed, if so update the dest list | 558 | // Check to see if name has changed, if so update the dest list |
557 | if ( dest->name() != origName ) | 559 | if ( dest->name() != origName ) |
558 | m_destList->changeItem( dest->name(), m_destCurrent ); | 560 | m_destList->changeItem( dest->name(), m_destCurrent ); |
559 | } | 561 | } |
560 | } | 562 | } |
561 | } | 563 | } |
562 | 564 | ||
563 | void OIpkgConfigDlg::slotDestDelete() | 565 | void OIpkgConfigDlg::slotDestDelete() |
564 | { | 566 | { |
565 | // Find selected destination in list | 567 | // Find selected destination in list |
566 | OConfItem *destination = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() ); | 568 | OConfItem *destination = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() ); |
567 | 569 | ||
568 | // Delete destination | 570 | // Delete destination |
569 | if ( destination ) | 571 | if ( destination ) |
570 | { | 572 | { |
571 | m_configs->removeRef( destination ); | 573 | m_configs->removeRef( destination ); |
572 | m_destList->removeItem( m_destCurrent ); | 574 | m_destList->removeItem( m_destCurrent ); |
573 | } | 575 | } |
574 | } | 576 | } |
575 | 577 | ||
576 | void OIpkgConfigDlg::slotOptSelectSourceListsPath() | 578 | void OIpkgConfigDlg::slotOptSelectSourceListsPath() |
577 | { | 579 | { |
578 | QString path = Opie::Ui::OFileDialog::getDirectory( 0, m_optSourceLists->text() ); | 580 | QString path = Opie::Ui::OFileDialog::getDirectory( 0, m_optSourceLists->text() ); |
579 | if ( path.at( path.length() - 1 ) == '/' ) | 581 | if ( path.at( path.length() - 1 ) == '/' ) |
580 | path.truncate( path.length() - 1 ); | 582 | path.truncate( path.length() - 1 ); |
581 | if ( !path.isNull() ) | 583 | if ( !path.isNull() ) |
582 | m_optSourceLists->setText( path ); | 584 | m_optSourceLists->setText( path ); |
583 | } | 585 | } |
584 | 586 | ||
585 | OIpkgServerDlg::OIpkgServerDlg( OConfItem *server, QWidget *parent ) | 587 | OIpkgServerDlg::OIpkgServerDlg( OConfItem *server, QWidget *parent ) |
586 | : QDialog( parent, QString::null, true, WStyle_ContextHelp ) | 588 | : QDialog( parent, QString::null, true, WStyle_ContextHelp ) |
587 | , m_server( server ) | 589 | , m_server( server ) |
588 | { | 590 | { |
589 | setCaption( tr( "Edit Server" ) ); | 591 | setCaption( tr( "Edit Server" ) ); |
590 | 592 | ||
591 | // Initialize UI | 593 | // Initialize UI |
592 | QVBoxLayout *layout = new QVBoxLayout( this, 2, 4 ); | 594 | QVBoxLayout *layout = new QVBoxLayout( this, 2, 4 ); |
593 | 595 | ||
594 | m_active = new QCheckBox( tr( "Active" ), this ); | 596 | m_active = new QCheckBox( tr( "Active" ), this ); |
595 | QWhatsThis::add( m_active, tr( "Tap here to indicate whether this entry is active or not." ) ); | 597 | QWhatsThis::add( m_active, tr( "Tap here to indicate whether this entry is active or not." ) ); |
596 | layout->addWidget( m_active ); | 598 | layout->addWidget( m_active ); |
597 | 599 | ||
598 | layout->addStretch(); | 600 | layout->addStretch(); |
599 | 601 | ||
600 | QLabel *label = new QLabel( tr( "Name:" ), this ); | 602 | QLabel *label = new QLabel( tr( "Name:" ), this ); |
601 | QWhatsThis::add( label, tr( "Enter the name of this entry here." ) ); | 603 | QWhatsThis::add( label, tr( "Enter the name of this entry here." ) ); |
602 | layout->addWidget( label ); | 604 | layout->addWidget( label ); |
603 | m_name = new QLineEdit( this ); | 605 | m_name = new QLineEdit( this ); |
604 | QWhatsThis::add( m_name, tr( "Enter the name of this entry here." ) ); | 606 | QWhatsThis::add( m_name, tr( "Enter the name of this entry here." ) ); |
605 | layout->addWidget( m_name ); | 607 | layout->addWidget( m_name ); |
606 | 608 | ||
607 | layout->addStretch(); | 609 | layout->addStretch(); |
608 | 610 | ||
609 | label = new QLabel( tr( "Address:" ), this ); | 611 | label = new QLabel( tr( "Address:" ), this ); |
610 | QWhatsThis::add( label, tr( "Enter the URL address of this entry here." ) ); | 612 | QWhatsThis::add( label, tr( "Enter the URL address of this entry here." ) ); |
611 | layout->addWidget( label ); | 613 | layout->addWidget( label ); |
612 | m_location = new QLineEdit( this ); | 614 | m_location = new QLineEdit( this ); |
613 | QWhatsThis::add( m_location, tr( "Enter the URL address of this entry here." ) ); | 615 | QWhatsThis::add( m_location, tr( "Enter the URL address of this entry here." ) ); |
614 | layout->addWidget( m_location ); | 616 | layout->addWidget( m_location ); |
615 | 617 | ||
616 | layout->addStretch(); | 618 | layout->addStretch(); |
617 | 619 | ||
618 | m_compressed = new QCheckBox( tr( "Compressed server feed" ), this ); | 620 | m_compressed = new QCheckBox( tr( "Compressed server feed" ), this ); |
619 | QWhatsThis::add( m_compressed, tr( "Tap here to indicate whether the server support compressed archives or not." ) ); | 621 | QWhatsThis::add( m_compressed, tr( "Tap here to indicate whether the server support compressed archives or not." ) ); |
620 | layout->addWidget( m_compressed ); | 622 | layout->addWidget( m_compressed ); |
621 | 623 | ||
622 | // Populate initial information | 624 | // Populate initial information |
623 | if ( m_server ) | 625 | if ( m_server ) |
624 | { | 626 | { |
625 | m_name->setText( m_server->name() ); | 627 | m_name->setText( m_server->name() ); |
626 | m_location->setText( m_server->value() ); | 628 | m_location->setText( m_server->value() ); |
627 | m_compressed->setChecked( m_server->features().contains( "Compressed" ) ); | 629 | m_compressed->setChecked( m_server->features().contains( "Compressed" ) ); |
628 | m_active->setChecked( m_server->active() ); | 630 | m_active->setChecked( m_server->active() ); |
629 | } | 631 | } |
630 | } | 632 | } |
631 | 633 | ||
632 | void OIpkgServerDlg::accept() | 634 | void OIpkgServerDlg::accept() |
633 | { | 635 | { |
634 | // Save information entered | 636 | // Save information entered |
635 | QString name = m_name->text(); | 637 | QString name = m_name->text(); |
636 | name.replace( QRegExp( " " ), "_" ); | 638 | name.replace( QRegExp( " " ), "_" ); |
637 | m_server->setName( name ); | 639 | m_server->setName( name ); |
638 | m_server->setValue( m_location->text() ); | 640 | m_server->setValue( m_location->text() ); |
639 | m_compressed->isChecked() ? m_server->setFeatures( "Compressed" ) | 641 | m_compressed->isChecked() ? m_server->setFeatures( "Compressed" ) |
640 | : m_server->setFeatures( QString::null ); | 642 | : m_server->setFeatures( QString::null ); |
641 | m_server->setActive( m_active->isChecked() ); | 643 | m_server->setActive( m_active->isChecked() ); |
642 | 644 | ||
643 | QDialog::accept(); | 645 | QDialog::accept(); |
644 | } | 646 | } |
645 | 647 | ||
646 | OIpkgDestDlg::OIpkgDestDlg( OConfItem *dest, QWidget *parent ) | 648 | OIpkgDestDlg::OIpkgDestDlg( OConfItem *dest, QWidget *parent ) |
647 | : QDialog( parent, QString::null, true, WStyle_ContextHelp ) | 649 | : QDialog( parent, QString::null, true, WStyle_ContextHelp ) |
648 | , m_dest( dest ) | 650 | , m_dest( dest ) |
649 | { | 651 | { |
650 | setCaption( tr( "Edit Destination" ) ); | 652 | setCaption( tr( "Edit Destination" ) ); |
651 | 653 | ||
652 | // Initialize UI | 654 | // Initialize UI |
653 | QVBoxLayout *layout = new QVBoxLayout( this, 2, 4 ); | 655 | QVBoxLayout *layout = new QVBoxLayout( this, 2, 4 ); |
654 | 656 | ||
655 | m_active = new QCheckBox( tr( "Active" ), this ); | 657 | m_active = new QCheckBox( tr( "Active" ), this ); |
656 | QWhatsThis::add( m_active, tr( "Tap here to indicate whether this entry is active or not." ) ); | 658 | QWhatsThis::add( m_active, tr( "Tap here to indicate whether this entry is active or not." ) ); |
657 | layout->addWidget( m_active ); | 659 | layout->addWidget( m_active ); |
658 | 660 | ||
659 | layout->addStretch(); | 661 | layout->addStretch(); |
660 | 662 | ||
661 | QLabel *label = new QLabel( tr( "Name:" ), this ); | 663 | QLabel *label = new QLabel( tr( "Name:" ), this ); |
662 | QWhatsThis::add( label, tr( "Enter the name of this entry here." ) ); | 664 | QWhatsThis::add( label, tr( "Enter the name of this entry here." ) ); |
663 | layout->addWidget( label ); | 665 | layout->addWidget( label ); |
664 | m_name = new QLineEdit( this ); | 666 | m_name = new QLineEdit( this ); |
665 | QWhatsThis::add( m_name, tr( "Enter the name of this entry here." ) ); | 667 | QWhatsThis::add( m_name, tr( "Enter the name of this entry here." ) ); |
666 | layout->addWidget( m_name ); | 668 | layout->addWidget( m_name ); |
667 | 669 | ||
668 | layout->addStretch(); | 670 | layout->addStretch(); |
669 | 671 | ||
670 | label = new QLabel( tr( "Location:" ), this ); | 672 | label = new QLabel( tr( "Location:" ), this ); |
671 | QWhatsThis::add( label, tr( "Enter the absolute directory path of this entry here." ) ); | 673 | QWhatsThis::add( label, tr( "Enter the absolute directory path of this entry here." ) ); |
672 | layout->addWidget( label ); | 674 | layout->addWidget( label ); |
673 | 675 | ||
674 | QHBoxLayout *layout2 = new QHBoxLayout( this, 2, 4 ); | 676 | QHBoxLayout *layout2 = new QHBoxLayout( this, 2, 4 ); |
675 | layout->addLayout( layout2 ); | 677 | layout->addLayout( layout2 ); |
676 | 678 | ||
677 | m_location = new QLineEdit( this ); | 679 | m_location = new QLineEdit( this ); |
678 | QWhatsThis::add( m_location, tr( "Enter the absolute directory path of this entry here." ) ); | 680 | QWhatsThis::add( m_location, tr( "Enter the absolute directory path of this entry here." ) ); |
679 | layout2->addWidget( m_location ); | 681 | layout2->addWidget( m_location ); |
680 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "folder", Opie::Core::OResource::SmallIcon ), | 682 | QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "folder", Opie::Core::OResource::SmallIcon ), |
681 | QString::null, this ); | 683 | QString::null, this ); |
682 | btn->setMaximumWidth( btn->height() ); | 684 | btn->setMaximumWidth( btn->height() ); |
683 | QWhatsThis::add( btn, tr( "Tap here to select the desired location." ) ); | 685 | QWhatsThis::add( btn, tr( "Tap here to select the desired location." ) ); |
684 | connect( btn, SIGNAL(clicked()), this, SLOT(slotSelectPath()) ); | 686 | connect( btn, SIGNAL(clicked()), this, SLOT(slotSelectPath()) ); |
685 | layout2->addWidget( btn ); | 687 | layout2->addWidget( btn ); |
686 | 688 | ||
687 | // Populate initial information | 689 | // Populate initial information |
688 | if ( m_dest ) | 690 | if ( m_dest ) |
689 | { | 691 | { |
690 | m_name->setText( m_dest->name() ); | 692 | m_name->setText( m_dest->name() ); |
691 | m_location->setText( m_dest->value() ); | 693 | m_location->setText( m_dest->value() ); |
692 | m_active->setChecked( m_dest->active() ); | 694 | m_active->setChecked( m_dest->active() ); |
693 | } | 695 | } |
694 | } | 696 | } |
695 | 697 | ||
696 | void OIpkgDestDlg::accept() | 698 | void OIpkgDestDlg::accept() |
697 | { | 699 | { |
698 | // Save information entered | 700 | // Save information entered |
699 | QString name = m_name->text(); | 701 | QString name = m_name->text(); |
700 | name.replace( QRegExp( " " ), "_" ); | 702 | name.replace( QRegExp( " " ), "_" ); |
701 | m_dest->setName( name ); | 703 | m_dest->setName( name ); |
702 | m_dest->setValue( m_location->text() ); | 704 | m_dest->setValue( m_location->text() ); |
703 | m_dest->setActive( m_active->isChecked() ); | 705 | m_dest->setActive( m_active->isChecked() ); |
704 | 706 | ||
705 | QDialog::accept(); | 707 | QDialog::accept(); |
706 | } | 708 | } |
707 | 709 | ||
708 | void OIpkgDestDlg::slotSelectPath() | 710 | void OIpkgDestDlg::slotSelectPath() |
709 | { | 711 | { |
710 | QString path = Opie::Ui::OFileDialog::getDirectory( 0, m_location->text() ); | 712 | QString path = Opie::Ui::OFileDialog::getDirectory( 0, m_location->text() ); |
711 | if ( path.at( path.length() - 1 ) == '/' ) | 713 | if ( path.at( path.length() - 1 ) == '/' ) |
712 | path.truncate( path.length() - 1 ); | 714 | path.truncate( path.length() - 1 ); |
713 | if ( !path.isNull() ) | 715 | if ( !path.isNull() ) |
714 | m_location->setText( path ); | 716 | m_location->setText( path ); |
715 | } | 717 | } |
716 | 718 | ||