summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp32
-rw-r--r--inputmethods/dasher/PPMLanguageModel.cpp3
-rw-r--r--noncore/apps/opie-reader/Bkmks.cpp18
-rw-r--r--noncore/apps/opie-reader/Bkmks.h7
-rw-r--r--noncore/apps/opie-reader/StyleConsts.cpp7
-rw-r--r--noncore/apps/opie-reader/StyleConsts.h8
-rw-r--r--noncore/apps/opie-write/qrichtext.cpp5
-rw-r--r--noncore/apps/tinykate/libkate/document/katehighlight.cpp7
-rw-r--r--noncore/apps/tinykate/libkate/document/katehighlight.h2
9 files changed, 57 insertions, 32 deletions
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
index 1db34d2..30ff49d 100644
--- a/core/apps/embeddedkonsole/TEScreen.cpp
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -1,1236 +1,1238 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [TEScreen.C] Screen Data Type */ 3/* [TEScreen.C] Screen Data Type */
4/* */ 4/* */
5/* -------------------------------------------------------------------------- */ 5/* -------------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14/* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16/* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18// enhancements added by L.J. Potter <ljp@llornkcor.com> 18// enhancements added by L.J. Potter <ljp@llornkcor.com>
19 19
20/*! \file 20/*! \file
21*/ 21*/
22 22
23/*! \class TEScreen 23/*! \class TEScreen
24 24
25 \brief The image manipulated by the emulation. 25 \brief The image manipulated by the emulation.
26 26
27 This class implements the operations of the terminal emulation framework. 27 This class implements the operations of the terminal emulation framework.
28 It is a complete passive device, driven by the emulation decoder 28 It is a complete passive device, driven by the emulation decoder
29 (TEmuVT102). By this it forms in fact an ADT, that defines operations 29 (TEmuVT102). By this it forms in fact an ADT, that defines operations
30 on a rectangular image. 30 on a rectangular image.
31 31
32 It does neither know how to display its image nor about escape sequences. 32 It does neither know how to display its image nor about escape sequences.
33 It is further independent of the underlying toolkit. By this, one can even 33 It is further independent of the underlying toolkit. By this, one can even
34 use this module for an ordinary text surface. 34 use this module for an ordinary text surface.
35 35
36 Since the operations are called by a specific emulation decoder, one may 36 Since the operations are called by a specific emulation decoder, one may
37 collect their different operations here. 37 collect their different operations here.
38 38
39 The state manipulated by the operations is mainly kept in `image', though 39 The state manipulated by the operations is mainly kept in `image', though
40 it is a little more complex bejond this. See the header file of the class. 40 it is a little more complex bejond this. See the header file of the class.
41 41
42 \sa TEWidget \sa VT102Emulation 42 \sa TEWidget \sa VT102Emulation
43*/ 43*/
44 44
45#include <stdio.h> 45#include <stdio.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <unistd.h> 47#include <unistd.h>
48// #include <kdebug.h> 48// #include <kdebug.h>
49 49
50#include <assert.h> 50#include <assert.h>
51#include <string.h> 51#include <string.h>
52#include <ctype.h> 52#include <ctype.h>
53 53
54#include <qpe/config.h> 54#include <qpe/config.h>
55#include "TEScreen.h" 55#include "TEScreen.h"
56 56
57#define HERE printf("%s(%d): here\n",__FILE__,__LINE__) 57#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
58 58
59//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI. 59//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
60//FIXME: see if we can get this from terminfo. 60//FIXME: see if we can get this from terminfo.
61#define BS_CLEARS FALSE 61#define BS_CLEARS FALSE
62 62
63#define loc(X,Y) ((Y) * columns + (X)) 63#define loc(X,Y) ((Y) * columns + (X))
64 64
65/*! creates a `TEScreen' of `lines' lines and `columns' columns. 65/*! creates a `TEScreen' of `lines' lines and `columns' columns.
66*/ 66*/
67 67
68TEScreen::TEScreen(int lines, int columns) 68TEScreen::TEScreen(int _lines, int _columns) :
69 lines(_lines),
70 columns(_columns),
71 tabstops(0),
72 histCursor(0),
73 horzCursor(0)
69{ 74{
70 this->lines = lines;
71 this->columns = columns;
72// odebug << "Columns " << columns << "" << oendl; 75// odebug << "Columns " << columns << "" << oendl;
73 76
74 image = (ca*) malloc(lines*columns*sizeof(ca)); 77 image = new ca[lines*columns];
75 tabstops = NULL; initTabStops(); 78 initTabStops();
76
77 histCursor = 0;
78 horzCursor = 0;
79 79
80 clearSelection(); 80 clearSelection();
81 reset(); 81 reset();
82} 82}
83 83
84/*! Destructor 84/*! Destructor
85*/ 85*/
86 86
87TEScreen::~TEScreen() 87TEScreen::~TEScreen()
88{ 88{
89 free(image); 89 delete [] image;
90 if (tabstops) free(tabstops); 90 delete [] tabstops;
91} 91}
92 92
93/* ------------------------------------------------------------------------- */ 93/* ------------------------------------------------------------------------- */
94/* */ 94/* */
95/* Normalized Screen Operations */ 95/* Normalized Screen Operations */
96/* */ 96/* */
97/* ------------------------------------------------------------------------- */ 97/* ------------------------------------------------------------------------- */
98 98
99// Cursor Setting -------------------------------------------------------------- 99// Cursor Setting --------------------------------------------------------------
100 100
101/*! \section Cursor 101/*! \section Cursor
102 102
103 The `cursor' is a location within the screen that is implicitely used in 103 The `cursor' is a location within the screen that is implicitely used in
104 many operations. The operations within this section allow to manipulate 104 many operations. The operations within this section allow to manipulate
105 the cursor explicitly and to obtain it's value. 105 the cursor explicitly and to obtain it's value.
106 106
107 The position of the cursor is guarantied to be between (including) 0 and 107 The position of the cursor is guarantied to be between (including) 0 and
108 `columns-1' and `lines-1'. 108 `columns-1' and `lines-1'.
109*/ 109*/
110 110
111/*! 111/*!
112 Move the cursor up. 112 Move the cursor up.
113 113
114 The cursor will not be moved beyond the top margin. 114 The cursor will not be moved beyond the top margin.
115*/ 115*/
116 116
117void TEScreen::cursorUp(int n) 117void TEScreen::cursorUp(int n)
118//=CUU 118//=CUU
119{ 119{
120 if (n == 0) n = 1; // Default 120 if (n == 0) n = 1; // Default
121 int stop = cuY < tmargin ? 0 : tmargin; 121 int stop = cuY < tmargin ? 0 : tmargin;
122 cuX = QMIN(columns-1,cuX); // nowrap! 122 cuX = QMIN(columns-1,cuX); // nowrap!
123 cuY = QMAX(stop,cuY-n); 123 cuY = QMAX(stop,cuY-n);
124} 124}
125 125
126/*! 126/*!
127 Move the cursor down. 127 Move the cursor down.
128 128
129 The cursor will not be moved beyond the bottom margin. 129 The cursor will not be moved beyond the bottom margin.
130*/ 130*/
131 131
132void TEScreen::cursorDown(int n) 132void TEScreen::cursorDown(int n)
133//=CUD 133//=CUD
134{ 134{
135 if (n == 0) n = 1; // Default 135 if (n == 0) n = 1; // Default
136 int stop = cuY > bmargin ? lines-1 : bmargin; 136 int stop = cuY > bmargin ? lines-1 : bmargin;
137 cuX = QMIN(columns-1,cuX); // nowrap! 137 cuX = QMIN(columns-1,cuX); // nowrap!
138 cuY = QMIN(stop,cuY+n); 138 cuY = QMIN(stop,cuY+n);
139} 139}
140 140
141/*! 141/*!
142 Move the cursor left. 142 Move the cursor left.
143 143
144 The cursor will not move beyond the first column. 144 The cursor will not move beyond the first column.
145*/ 145*/
146 146
147void TEScreen::cursorLeft(int n) 147void TEScreen::cursorLeft(int n)
148//=CUB 148//=CUB
149{ 149{
150 if (n == 0) n = 1; // Default 150 if (n == 0) n = 1; // Default
151 cuX = QMIN(columns-1,cuX); // nowrap! 151 cuX = QMIN(columns-1,cuX); // nowrap!
152 cuX = QMAX(0,cuX-n); 152 cuX = QMAX(0,cuX-n);
153} 153}
154 154
155/*! 155/*!
156 Move the cursor left. 156 Move the cursor left.
157 157
158 The cursor will not move beyond the rightmost column. 158 The cursor will not move beyond the rightmost column.
159*/ 159*/
160 160
161void TEScreen::cursorRight(int n) 161void TEScreen::cursorRight(int n)
162//=CUF 162//=CUF
163{ 163{
164 if (n == 0) n = 1; // Default 164 if (n == 0) n = 1; // Default
165 cuX = QMIN(columns-1,cuX+n); 165 cuX = QMIN(columns-1,cuX+n);
166} 166}
167 167
168/*! 168/*!
169 Set top and bottom margin. 169 Set top and bottom margin.
170*/ 170*/
171 171
172void TEScreen::setMargins(int top, int bot) 172void TEScreen::setMargins(int top, int bot)
173//=STBM 173//=STBM
174{ 174{
175 if (top == 0) top = 1; // Default 175 if (top == 0) top = 1; // Default
176 if (bot == 0) bot = lines; // Default 176 if (bot == 0) bot = lines; // Default
177 top = top - 1; // Adjust to internal lineno 177 top = top - 1; // Adjust to internal lineno
178 bot = bot - 1; // Adjust to internal lineno 178 bot = bot - 1; // Adjust to internal lineno
179 if ( !( 0 <= top && top < bot && bot < lines ) ) 179 if ( !( 0 <= top && top < bot && bot < lines ) )
180 { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n", 180 { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
181 __FILE__,__LINE__,top,bot); 181 __FILE__,__LINE__,top,bot);
182 return; // Default error action: ignore 182 return; // Default error action: ignore
183 } 183 }
184 tmargin = top; 184 tmargin = top;
185 bmargin = bot; 185 bmargin = bot;
186 cuX = 0; 186 cuX = 0;
187 cuY = getMode(MODE_Origin) ? top : 0; 187 cuY = getMode(MODE_Origin) ? top : 0;
188} 188}
189 189
190/*! 190/*!
191 Move the cursor down one line. 191 Move the cursor down one line.
192 192
193 If cursor is on bottom margin, the region between the 193 If cursor is on bottom margin, the region between the
194 actual top and bottom margin is scrolled up instead. 194 actual top and bottom margin is scrolled up instead.
195*/ 195*/
196 196
197void TEScreen::index() 197void TEScreen::index()
198//=IND 198//=IND
199{ 199{
200 if (cuY == bmargin) 200 if (cuY == bmargin)
201 { 201 {
202 if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history 202 if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
203 scrollUp(tmargin,1); 203 scrollUp(tmargin,1);
204 } 204 }
205 else if (cuY < lines-1) 205 else if (cuY < lines-1)
206 cuY += 1; 206 cuY += 1;
207} 207}
208 208
209/*! 209/*!
210 Move the cursor up one line. 210 Move the cursor up one line.
211 211
212 If cursor is on the top margin, the region between the 212 If cursor is on the top margin, the region between the
213 actual top and bottom margin is scrolled down instead. 213 actual top and bottom margin is scrolled down instead.
214*/ 214*/
215 215
216void TEScreen::reverseIndex() 216void TEScreen::reverseIndex()
217//=RI 217//=RI
218{ 218{
219 if (cuY == tmargin) 219 if (cuY == tmargin)
220 scrollDown(tmargin,1); 220 scrollDown(tmargin,1);
221 else if (cuY > 0) 221 else if (cuY > 0)
222 cuY -= 1; 222 cuY -= 1;
223} 223}
224 224
225/*! 225/*!
226 Move the cursor to the begin of the next line. 226 Move the cursor to the begin of the next line.
227 227
228 If cursor is on bottom margin, the region between the 228 If cursor is on bottom margin, the region between the
229 actual top and bottom margin is scrolled up. 229 actual top and bottom margin is scrolled up.
230*/ 230*/
231 231
232void TEScreen::NextLine() 232void TEScreen::NextLine()
233//=NEL 233//=NEL
234{ 234{
235 Return(); index(); 235 Return(); index();
236} 236}
237 237
238// Line Editing ---------------------------------------------------------------- 238// Line Editing ----------------------------------------------------------------
239 239
240/*! \section inserting / deleting characters 240/*! \section inserting / deleting characters
241*/ 241*/
242 242
243/*! erase `n' characters starting from (including) the cursor position. 243/*! erase `n' characters starting from (including) the cursor position.
244 244
245 The line is filled in from the right with spaces. 245 The line is filled in from the right with spaces.
246*/ 246*/
247 247
248void TEScreen::eraseChars(int n) 248void TEScreen::eraseChars(int n)
249{ 249{
250 if (n == 0) n = 1; // Default 250 if (n == 0) n = 1; // Default
251 int p = QMAX(0,QMIN(cuX+n-1,columns-1)); 251 int p = QMAX(0,QMIN(cuX+n-1,columns-1));
252 clearImage(loc(cuX,cuY),loc(p,cuY),' '); 252 clearImage(loc(cuX,cuY),loc(p,cuY),' ');
253} 253}
254 254
255/*! delete `n' characters starting from (including) the cursor position. 255/*! delete `n' characters starting from (including) the cursor position.
256 256
257 The line is filled in from the right with spaces. 257 The line is filled in from the right with spaces.
258*/ 258*/
259 259
260void TEScreen::deleteChars(int n) 260void TEScreen::deleteChars(int n)
261{ 261{
262 if (n == 0) n = 1; // Default 262 if (n == 0) n = 1; // Default
263 int p = QMAX(0,QMIN(cuX+n,columns-1)); 263 int p = QMAX(0,QMIN(cuX+n,columns-1));
264 moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY)); 264 moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
265 clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' '); 265 clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
266} 266}
267 267
268/*! insert `n' spaces at the cursor position. 268/*! insert `n' spaces at the cursor position.
269 269
270 The cursor is not moved by the operation. 270 The cursor is not moved by the operation.
271*/ 271*/
272 272
273void TEScreen::insertChars(int n) 273void TEScreen::insertChars(int n)
274{ 274{
275 if (n == 0) n = 1; // Default 275 if (n == 0) n = 1; // Default
276 int p = QMAX(0,QMIN(columns-1-n,columns-1)); 276 int p = QMAX(0,QMIN(columns-1-n,columns-1));
277 int q = QMAX(0,QMIN(cuX+n,columns-1)); 277 int q = QMAX(0,QMIN(cuX+n,columns-1));
278 moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY)); 278 moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
279 clearImage(loc(cuX,cuY),loc(q-1,cuY),' '); 279 clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
280} 280}
281 281
282/*! delete `n' lines starting from (including) the cursor position. 282/*! delete `n' lines starting from (including) the cursor position.
283 283
284 The cursor is not moved by the operation. 284 The cursor is not moved by the operation.
285*/ 285*/
286 286
287void TEScreen::deleteLines(int n) 287void TEScreen::deleteLines(int n)
288{ 288{
289 if (n == 0) n = 1; // Default 289 if (n == 0) n = 1; // Default
290 scrollUp(cuY,n); 290 scrollUp(cuY,n);
291} 291}
292 292
293/*! insert `n' lines at the cursor position. 293/*! insert `n' lines at the cursor position.
294 294
295 The cursor is not moved by the operation. 295 The cursor is not moved by the operation.
296*/ 296*/
297 297
298void TEScreen::insertLines(int n) 298void TEScreen::insertLines(int n)
299{ 299{
300 if (n == 0) n = 1; // Default 300 if (n == 0) n = 1; // Default
301 scrollDown(cuY,n); 301 scrollDown(cuY,n);
302} 302}
303 303
304// Mode Operations ----------------------------------------------------------- 304// Mode Operations -----------------------------------------------------------
305 305
306/*! Set a specific mode. */ 306/*! Set a specific mode. */
307 307
308void TEScreen::setMode(int m) 308void TEScreen::setMode(int m)
309{ 309{
310 currParm.mode[m] = TRUE; 310 currParm.mode[m] = TRUE;
311 switch(m) 311 switch(m)
312 { 312 {
313 case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home 313 case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
314 } 314 }
315} 315}
316 316
317/*! Reset a specific mode. */ 317/*! Reset a specific mode. */
318 318
319void TEScreen::resetMode(int m) 319void TEScreen::resetMode(int m)
320{ 320{
321 currParm.mode[m] = FALSE; 321 currParm.mode[m] = FALSE;
322 switch(m) 322 switch(m)
323 { 323 {
324 case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home 324 case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
325 } 325 }
326} 326}
327 327
328/*! Save a specific mode. */ 328/*! Save a specific mode. */
329 329
330void TEScreen::saveMode(int m) 330void TEScreen::saveMode(int m)
331{ 331{
332 saveParm.mode[m] = currParm.mode[m]; 332 saveParm.mode[m] = currParm.mode[m];
333} 333}
334 334
335/*! Restore a specific mode. */ 335/*! Restore a specific mode. */
336 336
337void TEScreen::restoreMode(int m) 337void TEScreen::restoreMode(int m)
338{ 338{
339 currParm.mode[m] = saveParm.mode[m]; 339 currParm.mode[m] = saveParm.mode[m];
340} 340}
341 341
342//NOTE: this is a helper function 342//NOTE: this is a helper function
343/*! Return the setting a specific mode. */ 343/*! Return the setting a specific mode. */
344BOOL TEScreen::getMode(int m) 344BOOL TEScreen::getMode(int m)
345{ 345{
346 return currParm.mode[m]; 346 return currParm.mode[m];
347} 347}
348 348
349/*! Save the cursor position and the rendition attribute settings. */ 349/*! Save the cursor position and the rendition attribute settings. */
350 350
351void TEScreen::saveCursor() 351void TEScreen::saveCursor()
352{ 352{
353 sa_cuX = cuX; 353 sa_cuX = cuX;
354 sa_cuY = cuY; 354 sa_cuY = cuY;
355 sa_cu_re = cu_re; 355 sa_cu_re = cu_re;
356 sa_cu_fg = cu_fg; 356 sa_cu_fg = cu_fg;
357 sa_cu_bg = cu_bg; 357 sa_cu_bg = cu_bg;
358} 358}
359 359
360/*! Restore the cursor position and the rendition attribute settings. */ 360/*! Restore the cursor position and the rendition attribute settings. */
361 361
362void TEScreen::restoreCursor() 362void TEScreen::restoreCursor()
363{ 363{
364 cuX = QMIN(sa_cuX,columns-1); 364 cuX = QMIN(sa_cuX,columns-1);
365 cuY = QMIN(sa_cuY,lines-1); 365 cuY = QMIN(sa_cuY,lines-1);
366 cu_re = sa_cu_re; 366 cu_re = sa_cu_re;
367 cu_fg = sa_cu_fg; 367 cu_fg = sa_cu_fg;
368 cu_bg = sa_cu_bg; 368 cu_bg = sa_cu_bg;
369 effectiveRendition(); 369 effectiveRendition();
370} 370}
371 371
372/* ------------------------------------------------------------------------- */ 372/* ------------------------------------------------------------------------- */
373/* */ 373/* */
374/* Screen Operations */ 374/* Screen Operations */
375/* */ 375/* */
376/* ------------------------------------------------------------------------- */ 376/* ------------------------------------------------------------------------- */
377 377
378/*! Assing a new size to the screen. 378/*! Assing a new size to the screen.
379 379
380 The topmost left position is maintained, while lower lines 380 The topmost left position is maintained, while lower lines
381 or right hand side columns might be removed or filled with 381 or right hand side columns might be removed or filled with
382 spaces to fit the new size. 382 spaces to fit the new size.
383 383
384 The region setting is reset to the whole screen and the 384 The region setting is reset to the whole screen and the
385 tab positions reinitialized. 385 tab positions reinitialized.
386*/ 386*/
387 387
388void TEScreen::resizeImage(int new_lines, int new_columns) 388void TEScreen::resizeImage(int new_lines, int new_columns)
389{ 389{
390 if (cuY > new_lines-1) { 390 if (cuY > new_lines-1) {
391// attempt to preserve focus and lines 391// attempt to preserve focus and lines
392 bmargin = lines-1; //FIXME: margin lost 392 bmargin = lines-1; //FIXME: margin lost
393 for (int i = 0; i < cuY-(new_lines-1); i++) { 393 for (int i = 0; i < cuY-(new_lines-1); i++) {
394 addHistLine(); scrollUp(horzCursor,1); 394 addHistLine(); scrollUp(horzCursor,1);
395 } 395 }
396 } 396 }
397 397
398 // make new image 398 // make new image
399 ca* newimg = (ca*)malloc( new_lines * new_columns * sizeof( ca)); 399 ca* newimg = new ca[new_lines * new_columns];
400 400
401 clearSelection(); 401 clearSelection();
402 402
403 // clear new image 403 // clear new image
404 for (int y = 0; y < new_lines; y++) 404 for (int y = 0; y < new_lines; y++)
405 for (int x = 0; x < new_columns; x++) { 405 for (int x = 0; x < new_columns; x++) {
406 newimg[y*new_columns+x].c = ' '; 406 newimg[y*new_columns+x].c = ' ';
407 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR; 407 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
408 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR; 408 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
409 newimg[y*new_columns+x].r = DEFAULT_RENDITION; 409 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
410 } 410 }
411 int cpy_lines = QMIN(new_lines, lines); 411 int cpy_lines = QMIN(new_lines, lines);
412 int cpy_columns = QMIN(new_columns,columns); 412 int cpy_columns = QMIN(new_columns,columns);
413 // copy to new image 413 // copy to new image
414 for (int y = 0; y < cpy_lines; y++) 414 for (int y = 0; y < cpy_lines; y++)
415 for (int x = 0; x < cpy_columns; x++) { 415 for (int x = 0; x < cpy_columns; x++) {
416 newimg[y*new_columns+x].c = image[loc(x,y)].c; 416 newimg[y*new_columns+x].c = image[loc(x,y)].c;
417 newimg[y*new_columns+x].f = image[loc(x,y)].f; 417 newimg[y*new_columns+x].f = image[loc(x,y)].f;
418 newimg[y*new_columns+x].b = image[loc(x,y)].b; 418 newimg[y*new_columns+x].b = image[loc(x,y)].b;
419 newimg[y*new_columns+x].r = image[loc(x,y)].r; 419 newimg[y*new_columns+x].r = image[loc(x,y)].r;
420 } 420 }
421 free(image); 421 delete [] image;
422 image = newimg; 422 image = newimg;
423 lines = new_lines; 423 lines = new_lines;
424 columns = new_columns; 424 columns = new_columns;
425 cuX = QMIN(cuX,columns-1); 425 cuX = QMIN(cuX,columns-1);
426 cuY = QMIN(cuY,lines-1); 426 cuY = QMIN(cuY,lines-1);
427 427
428 // FIXME: try to keep values, evtl. 428 // FIXME: try to keep values, evtl.
429 tmargin=0; 429 tmargin=0;
430 bmargin=lines-1; 430 bmargin=lines-1;
431 initTabStops(); 431 initTabStops();
432 clearSelection(); 432 clearSelection();
433} 433}
434 434
435/* 435/*
436 Clarifying rendition here and in TEWidget. 436 Clarifying rendition here and in TEWidget.
437 437
438 currently, TEWidget's color table is 438 currently, TEWidget's color table is
439 0 1 2 .. 9 10 .. 17 439 0 1 2 .. 9 10 .. 17
440 dft_fg, dft_bg, dim 0..7, intensive 0..7 440 dft_fg, dft_bg, dim 0..7, intensive 0..7
441 441
442 cu_fg, cu_bg contain values 0..8; 442 cu_fg, cu_bg contain values 0..8;
443 - 0 = default color 443 - 0 = default color
444 - 1..8 = ansi specified color 444 - 1..8 = ansi specified color
445 445
446 re_fg, re_bg contain values 0..17 446 re_fg, re_bg contain values 0..17
447 due to the TEWidget's color table 447 due to the TEWidget's color table
448 448
449 rendition attributes are 449 rendition attributes are
450 450
451 attr widget screen 451 attr widget screen
452 -------------- ------ ------ 452 -------------- ------ ------
453 RE_UNDERLINE XX XX affects foreground only 453 RE_UNDERLINE XX XX affects foreground only
454 RE_BLINK XX XX affects foreground only 454 RE_BLINK XX XX affects foreground only
455 RE_BOLD XX XX affects foreground only 455 RE_BOLD XX XX affects foreground only
456 RE_REVERSE -- XX 456 RE_REVERSE -- XX
457 RE_TRANSPARENT XX -- affects background only 457 RE_TRANSPARENT XX -- affects background only
458 RE_INTENSIVE XX -- affects foreground only 458 RE_INTENSIVE XX -- affects foreground only
459 459
460 Note that RE_BOLD is used in both widget 460 Note that RE_BOLD is used in both widget
461 and screen rendition. Since xterm/vt102 461 and screen rendition. Since xterm/vt102
462 is to poor to distinguish between bold 462 is to poor to distinguish between bold
463 (which is a font attribute) and intensive 463 (which is a font attribute) and intensive
464 (which is a color attribute), we translate 464 (which is a color attribute), we translate
465 this and RE_BOLD in falls eventually appart 465 this and RE_BOLD in falls eventually appart
466 into RE_BOLD and RE_INTENSIVE. 466 into RE_BOLD and RE_INTENSIVE.
467*/ 467*/
468 468
469void TEScreen::reverseRendition(ca* p) 469void TEScreen::reverseRendition(ca* p)
470{ UINT8 f = p->f; UINT8 b = p->b; 470{ UINT8 f = p->f; UINT8 b = p->b;
471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT; 471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
472} 472}
473 473
474void TEScreen::effectiveRendition() 474void TEScreen::effectiveRendition()
475// calculate rendition 475// calculate rendition
476{ 476{
477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK); 477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
478 if (cu_re & RE_REVERSE) 478 if (cu_re & RE_REVERSE)
479 { 479 {
480 ef_fg = cu_bg; 480 ef_fg = cu_bg;
481 ef_bg = cu_fg; 481 ef_bg = cu_fg;
482 } 482 }
483 else 483 else
484 { 484 {
485 ef_fg = cu_fg; 485 ef_fg = cu_fg;
486 ef_bg = cu_bg; 486 ef_bg = cu_bg;
487 } 487 }
488 if (cu_re & RE_BOLD) 488 if (cu_re & RE_BOLD)
489 { 489 {
490 if (ef_fg < BASE_COLORS) 490 if (ef_fg < BASE_COLORS)
491 ef_fg += BASE_COLORS; 491 ef_fg += BASE_COLORS;
492 else 492 else
493 ef_fg -= BASE_COLORS; 493 ef_fg -= BASE_COLORS;
494 } 494 }
495} 495}
496 496
497/*! 497/*!
498 returns the image. 498 returns the image.
499 499
500 Get the size of the image by \sa getLines and \sa getColumns. 500 Get the size of the image by \sa getLines and \sa getColumns.
501 501
502 NOTE that the image returned by this function must later be 502 NOTE that the image returned by this function must later be
503 freed. 503 freed.
504 504
505*/ 505*/
506 506
507ca* TEScreen::getCookedImage() 507ca* TEScreen::getCookedImage()
508{ 508{
509 int x,y; 509 int x,y;
510 ca* merged = (ca*)malloc(lines*columns*sizeof(ca)); 510 ca* merged = new ca[lines*columns];
511 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION); 511 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
512 512
513 if (histCursor > hist.getLines()) { 513 if (histCursor > hist.getLines()) {
514 histCursor = hist.getLines(); 514 histCursor = hist.getLines();
515 } 515 }
516 516
517 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++) 517 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
518 { 518 {
519 int len = QMIN(columns,hist.getLineLen(y+histCursor)); 519 int len = QMIN(columns,hist.getLineLen(y+histCursor));
520 int yp = y*columns; 520 int yp = y*columns;
521 int yq = (y+histCursor)*columns; 521 int yq = (y+histCursor)*columns;
522 522
523 hist.getCells(y+histCursor,0,len,merged+yp); 523 hist.getCells(y+histCursor,0,len,merged+yp);
524 for (x = len; x < columns; x++) merged[yp+x] = dft; 524 for (x = len; x < columns; x++) merged[yp+x] = dft;
525 for (x = 0; x < columns; x++) 525 for (x = 0; x < columns; x++)
526 { int p=x + yp; int q=x + yq; 526 { int p=x + yp; int q=x + yq;
527 if ( ( q >= sel_TL ) && ( q <= sel_BR ) ) 527 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
528 reverseRendition(&merged[p]); // for selection 528 reverseRendition(&merged[p]); // for selection
529 } 529 }
530 } 530 }
531 if (lines >= hist.getLines()-histCursor) 531 if (lines >= hist.getLines()-histCursor)
532 { 532 {
533 for (y = (hist.getLines()-histCursor); y < lines ; y++) 533 for (y = (hist.getLines()-histCursor); y < lines ; y++)
534 { 534 {
535 int yp = y*columns; 535 int yp = y*columns;
536 int yq = (y+histCursor)*columns; 536 int yq = (y+histCursor)*columns;
537 int yr = (y-hist.getLines()+histCursor)*columns; 537 int yr = (y-hist.getLines()+histCursor)*columns;
538 for (x = 0; x < columns; x++) 538 for (x = 0; x < columns; x++)
539 { int p = x + yp; int q = x + yq; int r = x + yr; 539 { int p = x + yp; int q = x + yq; int r = x + yr;
540 merged[p] = image[r]; 540 merged[p] = image[r];
541 if ( q >= sel_TL && q <= sel_BR ) 541 if ( q >= sel_TL && q <= sel_BR )
542 reverseRendition(&merged[p]); // for selection 542 reverseRendition(&merged[p]); // for selection
543 } 543 }
544 544
545 } 545 }
546 } 546 }
547 // evtl. inverse display 547 // evtl. inverse display
548 if (getMode(MODE_Screen)) 548 if (getMode(MODE_Screen))
549 { int i,n = lines*columns; 549 { int i,n = lines*columns;
550 for (i = 0; i < n; i++) 550 for (i = 0; i < n; i++)
551 reverseRendition(&merged[i]); // for reverse display 551 reverseRendition(&merged[i]); // for reverse display
552 } 552 }
553 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible 553 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
554 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]); 554 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
555 return merged; 555 return merged;
556 556
557} 557}
558 558
559 559
560/*! 560/*!
561*/ 561*/
562 562
563void TEScreen::reset() 563void TEScreen::reset()
564{ 564{
565 Config cfg( "Konsole" ); 565 Config cfg( "Konsole" );
566 cfg.setGroup("ScrollBar"); 566 cfg.setGroup("ScrollBar");
567 if( !cfg.readBoolEntry("HorzScroll",0) ) 567 if( !cfg.readBoolEntry("HorzScroll",0) )
568 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin 568 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
569 569
570 570
571 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1] 571 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
572 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke 572 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
573 setMode(MODE_Cursor); // cursor visible 573 setMode(MODE_Cursor); // cursor visible
574 resetMode(MODE_Screen); // screen not inverse 574 resetMode(MODE_Screen); // screen not inverse
575 resetMode(MODE_NewLine); 575 resetMode(MODE_NewLine);
576 576
577 tmargin=0; 577 tmargin=0;
578 bmargin=lines-1; 578 bmargin=lines-1;
579 579
580 setDefaultRendition(); 580 setDefaultRendition();
581 saveCursor(); 581 saveCursor();
582 582
583 clear(); 583 clear();
584} 584}
585 585
586/*! Clear the entire screen and home the cursor. 586/*! Clear the entire screen and home the cursor.
587*/ 587*/
588 588
589void TEScreen::clear() 589void TEScreen::clear()
590{ 590{
591 clearEntireScreen(); 591 clearEntireScreen();
592 home(); 592 home();
593} 593}
594 594
595/*! Moves the cursor left one column. 595/*! Moves the cursor left one column.
596*/ 596*/
597 597
598void TEScreen::BackSpace() 598void TEScreen::BackSpace()
599{ 599{
600 cuX = QMAX(0,cuX-1); 600 cuX = QMAX(0,cuX-1);
601 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' '; 601 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
602} 602}
603 603
604/*! 604/*!
605*/ 605*/
606 606
607void TEScreen::Tabulate() 607void TEScreen::Tabulate()
608{ 608{
609 // note that TAB is a format effector (does not write ' '); 609 // note that TAB is a format effector (does not write ' ');
610 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1); 610 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
611} 611}
612 612
613void TEScreen::clearTabStops() 613void TEScreen::clearTabStops()
614{ 614{
615 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE; 615 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
616} 616}
617 617
618void TEScreen::changeTabStop(bool set) 618void TEScreen::changeTabStop(bool set)
619{ 619{
620 if (cuX >= columns) return; 620 if (cuX >= columns) return;
621 tabstops[cuX] = set; 621 tabstops[cuX] = set;
622} 622}
623 623
624void TEScreen::initTabStops() 624void TEScreen::initTabStops()
625{ 625{
626 if (tabstops) free(tabstops); 626 if (tabstops)
627 tabstops = (bool*)malloc(columns*sizeof(bool)); 627 delete [] tabstops;
628
629 tabstops = new bool[columns];
628 // Arrg! The 1st tabstop has to be one longer than the other. 630 // Arrg! The 1st tabstop has to be one longer than the other.
629 // i.e. the kids start counting from 0 instead of 1. 631 // i.e. the kids start counting from 0 instead of 1.
630 // Other programs might behave correctly. Be aware. 632 // Other programs might behave correctly. Be aware.
631 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0); 633 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
632} 634}
633 635
634/*! 636/*!
635 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine) 637 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
636 depending on the NewLine Mode (LNM). This mode also 638 depending on the NewLine Mode (LNM). This mode also
637 affects the key sequence returned for newline ([CR]LF). 639 affects the key sequence returned for newline ([CR]LF).
638*/ 640*/
639 641
640void TEScreen::NewLine() 642void TEScreen::NewLine()
641{ 643{
642 if (getMode(MODE_NewLine)) Return(); 644 if (getMode(MODE_NewLine)) Return();
643 index(); 645 index();
644} 646}
645 647
646/*! put `c' literally onto the screen at the current cursor position. 648/*! put `c' literally onto the screen at the current cursor position.
647 649
648 VT100 uses the convention to produce an automatic newline (am) 650 VT100 uses the convention to produce an automatic newline (am)
649 with the *first* character that would fall onto the next line (xenl). 651 with the *first* character that would fall onto the next line (xenl).
650*/ 652*/
651 653
652void TEScreen::checkSelection(int from, int to) 654void TEScreen::checkSelection(int from, int to)
653{ 655{
654 if (sel_begin == -1) return; 656 if (sel_begin == -1) return;
655 int scr_TL = loc(0, hist.getLines()); 657 int scr_TL = loc(0, hist.getLines());
656 //Clear entire selection if it overlaps region [from, to] 658 //Clear entire selection if it overlaps region [from, to]
657 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) ) 659 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
658 { 660 {
659 clearSelection(); 661 clearSelection();
660 } 662 }
661} 663}
662 664
663void TEScreen::ShowCharacter(unsigned short c) 665void TEScreen::ShowCharacter(unsigned short c)
664{ 666{
665 // Note that VT100 does wrapping BEFORE putting the character. 667 // Note that VT100 does wrapping BEFORE putting the character.
666 // This has impact on the assumption of valid cursor positions. 668 // This has impact on the assumption of valid cursor positions.
667 // We indicate the fact that a newline has to be triggered by 669 // We indicate the fact that a newline has to be triggered by
668 // putting the cursor one right to the last column of the screen. 670 // putting the cursor one right to the last column of the screen.
669 671
670 if (cuX >= columns) 672 if (cuX >= columns)
671 { 673 {
672 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1; 674 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1;
673 // comment out for no wrap 675 // comment out for no wrap
674 } 676 }
675 677
676 if (getMode(MODE_Insert)) insertChars(1); 678 if (getMode(MODE_Insert)) insertChars(1);
677 679
678 int i = loc( cuX, cuY); 680 int i = loc( cuX, cuY);
679 681
680 checkSelection(i, i); // check if selection is still valid. 682 checkSelection(i, i); // check if selection is still valid.
681 683
682 image[i].c = c; 684 image[i].c = c;
683 image[i].f = ef_fg; 685 image[i].f = ef_fg;
684 image[i].b = ef_bg; 686 image[i].b = ef_bg;
685 image[i].r = ef_re; 687 image[i].r = ef_re;
686 688
687 cuX += 1; 689 cuX += 1;
688} 690}
689 691
690// Region commands ------------------------------------------------------------- 692// Region commands -------------------------------------------------------------
691 693
692 694
693/*! scroll up `n' lines within current region. 695/*! scroll up `n' lines within current region.
694 The `n' new lines are cleared. 696 The `n' new lines are cleared.
695 \sa setRegion \sa scrollDown 697 \sa setRegion \sa scrollDown
696*/ 698*/
697 699
698void TEScreen::scrollUp(int from, int n) 700void TEScreen::scrollUp(int from, int n)
699{ 701{
700 if (n <= 0 || from + n > bmargin) return; 702 if (n <= 0 || from + n > bmargin) return;
701 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 703 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
702 704
703 moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin)); 705 moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin));
704 clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' '); 706 clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' ');
705} 707}
706 708
707/*! scroll down `n' lines within current region. 709/*! scroll down `n' lines within current region.
708 The `n' new lines are cleared. 710 The `n' new lines are cleared.
709 \sa setRegion \sa scrollUp 711 \sa setRegion \sa scrollUp
710*/ 712*/
711 713
712void TEScreen::scrollDown(int from, int n) 714void TEScreen::scrollDown(int from, int n)
713{ 715{
714 716
715//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 717//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
716 if (n <= 0) return; 718 if (n <= 0) return;
717 if (from > bmargin) return; 719 if (from > bmargin) return;
718 if (from + n > bmargin) n = bmargin - from; 720 if (from + n > bmargin) n = bmargin - from;
719 721
720 moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n)); 722 moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n));
721 clearImage(loc(0,from),loc(columns-1,from+n-1),' '); 723 clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
722} 724}
723 725
724 726
725 727
726/*! position the cursor to a specific line and column. */ 728/*! position the cursor to a specific line and column. */
727void TEScreen::setCursorYX(int y, int x) 729void TEScreen::setCursorYX(int y, int x)
728{ 730{
729 setCursorY(y); setCursorX(x); 731 setCursorY(y); setCursorX(x);
730} 732}
731 733
732/*! Set the cursor to x-th line. */ 734/*! Set the cursor to x-th line. */
733 735
734void TEScreen::setCursorX(int x) 736void TEScreen::setCursorX(int x)
735{ 737{
736 if (x == 0) x = 1; // Default 738 if (x == 0) x = 1; // Default
737 x -= 1; // Adjust 739 x -= 1; // Adjust
738 cuX = QMAX(0,QMIN(columns-1, x)); 740 cuX = QMAX(0,QMIN(columns-1, x));
739} 741}
740 742
741/*! Set the cursor to y-th line. */ 743/*! Set the cursor to y-th line. */
742 744
743void TEScreen::setCursorY(int y) 745void TEScreen::setCursorY(int y)
744{ 746{
745 if (y == 0) y = 1; // Default 747 if (y == 0) y = 1; // Default
746 y -= 1; // Adjust 748 y -= 1; // Adjust
747 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) )); 749 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
748} 750}
749 751
750/*! set cursor to the `left upper' corner of the screen (1,1). 752/*! set cursor to the `left upper' corner of the screen (1,1).
751*/ 753*/
752 754
753void TEScreen::home() 755void TEScreen::home()
754{ 756{
755 cuX = 0; 757 cuX = 0;
756 cuY = 0; 758 cuY = 0;
757} 759}
758 760
759/*! set cursor to the begin of the current line. 761/*! set cursor to the begin of the current line.
760*/ 762*/
761 763
762void TEScreen::Return() 764void TEScreen::Return()
763{ 765{
764 cuX = 0; 766 cuX = 0;
765} 767}
766 768
767/*! returns the current cursor columns. 769/*! returns the current cursor columns.
768*/ 770*/
769 771
770int TEScreen::getCursorX() 772int TEScreen::getCursorX()
771{ 773{
772 return cuX; 774 return cuX;
773} 775}
774 776
775/*! returns the current cursor line. 777/*! returns the current cursor line.
776*/ 778*/
777 779
778int TEScreen::getCursorY() 780int TEScreen::getCursorY()
779{ 781{
780 return cuY; 782 return cuY;
781} 783}
782 784
783// Erasing --------------------------------------------------------------------- 785// Erasing ---------------------------------------------------------------------
784 786
785/*! \section Erasing 787/*! \section Erasing
786 788
787 This group of operations erase parts of the screen contents by filling 789 This group of operations erase parts of the screen contents by filling
788 it with spaces colored due to the current rendition settings. 790 it with spaces colored due to the current rendition settings.
789 791
790 Althought the cursor position is involved in most of these operations, 792 Althought the cursor position is involved in most of these operations,
791 it is never modified by them. 793 it is never modified by them.
792*/ 794*/
793 795
794/*! fill screen between (including) `loca' and `loce' with spaces. 796/*! fill screen between (including) `loca' and `loce' with spaces.
795 797
796 This is an internal helper functions. The parameter types are internal 798 This is an internal helper functions. The parameter types are internal
797 addresses of within the screen image and make use of the way how the 799 addresses of within the screen image and make use of the way how the
798 screen matrix is mapped to the image vector. 800 screen matrix is mapped to the image vector.
799*/ 801*/
800 802
801void TEScreen::clearImage(int loca, int loce, char c) 803void TEScreen::clearImage(int loca, int loce, char c)
802{ int i; 804{ int i;
803 int scr_TL=loc(0,hist.getLines()); 805 int scr_TL=loc(0,hist.getLines());
804 //FIXME: check positions 806 //FIXME: check positions
805 807
806 //Clear entire selection if it overlaps region to be moved... 808 //Clear entire selection if it overlaps region to be moved...
807 if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) ) 809 if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
808 { 810 {
809 clearSelection(); 811 clearSelection();
810 } 812 }
811 for (i = loca; i <= loce; i++) 813 for (i = loca; i <= loce; i++)
812 { 814 {
813 image[i].c = c; 815 image[i].c = c;
814 image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi 816 image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
815 image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different 817 image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
816 image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here. 818 image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
817 } 819 }
818} 820}
819 821
820/*! move image between (including) `loca' and `loce' to 'dst'. 822/*! move image between (including) `loca' and `loce' to 'dst'.
821 823
822 This is an internal helper functions. The parameter types are internal 824 This is an internal helper functions. The parameter types are internal
823 addresses of within the screen image and make use of the way how the 825 addresses of within the screen image and make use of the way how the
824 screen matrix is mapped to the image vector. 826 screen matrix is mapped to the image vector.
825*/ 827*/
826 828
827void TEScreen::moveImage(int dst, int loca, int loce) 829void TEScreen::moveImage(int dst, int loca, int loce)
828{ 830{
829//FIXME: check positions 831//FIXME: check positions
830 if (loce < loca) { 832 if (loce < loca) {
831 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl; 833 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
832 return; 834 return;
833 } 835 }
834 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca)); 836 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
835} 837}
836 838
837/*! clear from (including) current cursor position to end of screen. 839/*! clear from (including) current cursor position to end of screen.
838*/ 840*/
839 841
840void TEScreen::clearToEndOfScreen() 842void TEScreen::clearToEndOfScreen()
841{ 843{
842 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' '); 844 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
843} 845}
844 846
845/*! clear from begin of screen to (including) current cursor position. 847/*! clear from begin of screen to (including) current cursor position.
846*/ 848*/
847 849
848void TEScreen::clearToBeginOfScreen() 850void TEScreen::clearToBeginOfScreen()
849{ 851{
850 clearImage(loc(0,0),loc(cuX,cuY),' '); 852 clearImage(loc(0,0),loc(cuX,cuY),' ');
851} 853}
852 854
853/*! clear the entire screen. 855/*! clear the entire screen.
854*/ 856*/
855 857
856void TEScreen::clearEntireScreen() 858void TEScreen::clearEntireScreen()
857{ 859{
858 clearImage(loc(0,0),loc(columns-1,lines-1),' '); 860 clearImage(loc(0,0),loc(columns-1,lines-1),' ');
859} 861}
860 862
861/*! fill screen with 'E' 863/*! fill screen with 'E'
862 This is to aid screen alignment 864 This is to aid screen alignment
863*/ 865*/
864 866
865void TEScreen::helpAlign() 867void TEScreen::helpAlign()
866{ 868{
867 clearImage(loc(0,0),loc(columns-1,lines-1),'E'); 869 clearImage(loc(0,0),loc(columns-1,lines-1),'E');
868} 870}
869 871
870/*! clear from (including) current cursor position to end of current cursor line. 872/*! clear from (including) current cursor position to end of current cursor line.
871*/ 873*/
872 874
873void TEScreen::clearToEndOfLine() 875void TEScreen::clearToEndOfLine()
874{ 876{
875 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' '); 877 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
876} 878}
877 879
878/*! clear from begin of current cursor line to (including) current cursor position. 880/*! clear from begin of current cursor line to (including) current cursor position.
879*/ 881*/
880 882
881void TEScreen::clearToBeginOfLine() 883void TEScreen::clearToBeginOfLine()
882{ 884{
883 clearImage(loc(0,cuY),loc(cuX,cuY),' '); 885 clearImage(loc(0,cuY),loc(cuX,cuY),' ');
884} 886}
885 887
886/*! clears entire current cursor line 888/*! clears entire current cursor line
887*/ 889*/
888 890
889void TEScreen::clearEntireLine() 891void TEScreen::clearEntireLine()
890{ 892{
891 clearImage( loc( 0, cuY),loc( columns - 1, cuY),' '); 893 clearImage( loc( 0, cuY),loc( columns - 1, cuY),' ');
892} 894}
893 895
894// Rendition ------------------------------------------------------------------ 896// Rendition ------------------------------------------------------------------
895 897
896/*! 898/*!
897 set rendition mode 899 set rendition mode
898*/ 900*/
899 901
900void TEScreen::setRendition(int re) 902void TEScreen::setRendition(int re)
901{ 903{
902 cu_re |= re; 904 cu_re |= re;
903 effectiveRendition(); 905 effectiveRendition();
904} 906}
905 907
906/*! 908/*!
907 reset rendition mode 909 reset rendition mode
908*/ 910*/
909 911
910void TEScreen::resetRendition(int re) 912void TEScreen::resetRendition(int re)
911{ 913{
912 cu_re &= ~re; 914 cu_re &= ~re;
913 effectiveRendition(); 915 effectiveRendition();
914} 916}
915 917
916/*! 918/*!
917*/ 919*/
918 920
919void TEScreen::setDefaultRendition() 921void TEScreen::setDefaultRendition()
920{ 922{
921 setForeColorToDefault(); 923 setForeColorToDefault();
922 setBackColorToDefault(); 924 setBackColorToDefault();
923 cu_re = DEFAULT_RENDITION; 925 cu_re = DEFAULT_RENDITION;
924 effectiveRendition(); 926 effectiveRendition();
925} 927}
926 928
927/*! 929/*!
928*/ 930*/
929 931
930void TEScreen::setForeColor(int fgcolor) 932void TEScreen::setForeColor(int fgcolor)
931{ 933{
932 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2); 934 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
933 effectiveRendition(); 935 effectiveRendition();
934} 936}
935 937
936/*! 938/*!
937*/ 939*/
938 940
939void TEScreen::setBackColor(int bgcolor) 941void TEScreen::setBackColor(int bgcolor)
940{ 942{
941 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2); 943 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
942 effectiveRendition(); 944 effectiveRendition();
943} 945}
944 946
945/*! 947/*!
946*/ 948*/
947 949
948void TEScreen::setBackColorToDefault() 950void TEScreen::setBackColorToDefault()
949{ 951{
950 cu_bg = DEFAULT_BACK_COLOR; 952 cu_bg = DEFAULT_BACK_COLOR;
951 effectiveRendition(); 953 effectiveRendition();
952} 954}
953 955
954/*! 956/*!
955*/ 957*/
956 958
957void TEScreen::setForeColorToDefault() 959void TEScreen::setForeColorToDefault()
958{ 960{
959 cu_fg = DEFAULT_FORE_COLOR; 961 cu_fg = DEFAULT_FORE_COLOR;
960 effectiveRendition(); 962 effectiveRendition();
961} 963}
962 964
963/* ------------------------------------------------------------------------- */ 965/* ------------------------------------------------------------------------- */
964/* */ 966/* */
965/* Marking & Selection */ 967/* Marking & Selection */
966/* */ 968/* */
967/* ------------------------------------------------------------------------- */ 969/* ------------------------------------------------------------------------- */
968 970
969void TEScreen::clearSelection() 971void TEScreen::clearSelection()
970{ 972{
971 sel_BR = -1; 973 sel_BR = -1;
972 sel_TL = -1; 974 sel_TL = -1;
973 sel_begin = -1; 975 sel_begin = -1;
974} 976}
975 977
976void TEScreen::setSelBeginXY(const int x, const int y) 978void TEScreen::setSelBeginXY(const int x, const int y)
977{ 979{
978 if (histCursor > hist.getLines()) { 980 if (histCursor > hist.getLines()) {
979 histCursor = hist.getLines(); 981 histCursor = hist.getLines();
980 } 982 }
981 sel_begin = loc(x,y+histCursor) ; 983 sel_begin = loc(x,y+histCursor) ;
982 sel_BR = sel_begin; 984 sel_BR = sel_begin;
983 sel_TL = sel_begin; 985 sel_TL = sel_begin;
984} 986}
985 987
986void TEScreen::setSelExtentXY(const int x, const int y) 988void TEScreen::setSelExtentXY(const int x, const int y)
987{ 989{
988 if (sel_begin == -1) return; 990 if (sel_begin == -1) return;
989 if (histCursor > hist.getLines()) { 991 if (histCursor > hist.getLines()) {
990 histCursor = hist.getLines(); 992 histCursor = hist.getLines();
991 } 993 }
992 int l = loc(x,y + histCursor); 994 int l = loc(x,y + histCursor);
993 995
994 if (l < sel_begin) 996 if (l < sel_begin)
995 { 997 {
996 sel_TL = l; 998 sel_TL = l;
997 sel_BR = sel_begin; 999 sel_BR = sel_begin;
998 } 1000 }
999 else 1001 else
1000 { 1002 {
1001 /* FIXME, HACK to correct for x too far to the right... */ 1003 /* FIXME, HACK to correct for x too far to the right... */
1002 if (( x == columns )|| (x == 0)) l--; 1004 if (( x == columns )|| (x == 0)) l--;
1003 1005
1004 sel_TL = sel_begin; 1006 sel_TL = sel_begin;
1005 sel_BR = l; 1007 sel_BR = l;
1006 } 1008 }
1007} 1009}
1008 1010
1009QString TEScreen::getSelText(const BOOL preserve_line_breaks) 1011QString TEScreen::getSelText(const BOOL preserve_line_breaks)
1010{ 1012{
1011 if (sel_begin == -1) 1013 if (sel_begin == -1)
1012 return QString::null; // Selection got clear while selecting. 1014 return QString::null; // Selection got clear while selecting.
1013 1015
1014 int *m; // buffer to fill. 1016 int *m; // buffer to fill.
1015 int s, d; // source index, dest. index. 1017 int s, d; // source index, dest. index.
1016 int hist_BR = loc(0, hist.getLines()); 1018 int hist_BR = loc(0, hist.getLines());
1017 int hY = sel_TL / columns; 1019 int hY = sel_TL / columns;
1018 int hX = sel_TL % columns; 1020 int hX = sel_TL % columns;
1019 int eol; // end of line 1021 int eol; // end of line
1020 1022
1021 s = sel_TL; // tracks copy in source. 1023 s = sel_TL; // tracks copy in source.
1022 1024
1023 // allocate buffer for maximum 1025 // allocate buffer for maximum
1024 // possible size... 1026 // possible size...
1025 d = (sel_BR - sel_TL) / columns + 1; 1027 d = (sel_BR - sel_TL) / columns + 1;
1026 m = new int[d * (columns + 1) + 2]; 1028 m = new int[d * (columns + 1) + 2];
1027 d = 0; 1029 d = 0;
1028 1030
1029 while (s <= sel_BR) 1031 while (s <= sel_BR)
1030 { 1032 {
1031 if (s < hist_BR) 1033 if (s < hist_BR)
1032 { // get lines from hist.history 1034 { // get lines from hist.history
1033 // buffer. 1035 // buffer.
1034 eol = hist.getLineLen(hY); 1036 eol = hist.getLineLen(hY);
1035 1037
1036 if ((hY == (sel_BR / columns)) && 1038 if ((hY == (sel_BR / columns)) &&
1037 (eol >= (sel_BR % columns))) 1039 (eol >= (sel_BR % columns)))
1038 { 1040 {
1039 eol = sel_BR % columns + 1; 1041 eol = sel_BR % columns + 1;
1040 } 1042 }
1041 1043
1042 while (hX < eol) 1044 while (hX < eol)
1043 { 1045 {
1044 m[d++] = hist.getCell(hY, hX++).c; 1046 m[d++] = hist.getCell(hY, hX++).c;
1045 s++; 1047 s++;
1046 } 1048 }
1047 1049
1048 if (s <= sel_BR) 1050 if (s <= sel_BR)
1049 { 1051 {
1050 // The line break handling 1052 // The line break handling
1051 // It's different from the screen 1053 // It's different from the screen
1052 // image case! 1054 // image case!
1053 if (eol % columns == 0) 1055 if (eol % columns == 0)
1054 { 1056 {
1055 // That's either a completely filled 1057 // That's either a completely filled
1056 // line or an empty line 1058 // line or an empty line
1057 if (eol == 0) 1059 if (eol == 0)
1058 { 1060 {
1059 m[d++] = '\n'; 1061 m[d++] = '\n';
1060 } 1062 }
1061 else 1063 else
1062 { 1064 {
1063 // We have a full line. 1065 // We have a full line.
1064 // FIXME: How can we handle newlines 1066 // FIXME: How can we handle newlines
1065 // at this position?! 1067 // at this position?!
1066 } 1068 }
1067 } 1069 }
1068 else if ((eol + 1) % columns == 0) 1070 else if ((eol + 1) % columns == 0)
1069 { 1071 {
1070 // FIXME: We don't know if this was a 1072 // FIXME: We don't know if this was a
1071 // space at the last position or a 1073 // space at the last position or a
1072 // short line!! 1074 // short line!!
1073 m[d++] = ' '; 1075 m[d++] = ' ';
1074 } 1076 }
1075 else 1077 else
1076 { 1078 {
1077 // We have a short line here. Put a 1079 // We have a short line here. Put a
1078 // newline or a space into the 1080 // newline or a space into the
1079 // buffer. 1081 // buffer.
1080 m[d++] = preserve_line_breaks ? '\n' : ' '; 1082 m[d++] = preserve_line_breaks ? '\n' : ' ';
1081 } 1083 }
1082 } 1084 }
1083 1085
1084 hY++; 1086 hY++;
1085 hX = 0; 1087 hX = 0;
1086 s = hY * columns; 1088 s = hY * columns;
1087 } 1089 }
1088 else 1090 else
1089 { // or from screen image. 1091 { // or from screen image.
1090 eol = (s / columns + 1) * columns - 1; 1092 eol = (s / columns + 1) * columns - 1;
1091 1093
1092 if (eol < sel_BR) 1094 if (eol < sel_BR)
1093 { 1095 {
1094 while ((eol > s) && 1096 while ((eol > s) &&
1095 isspace(image[eol - hist_BR].c)) 1097 isspace(image[eol - hist_BR].c))
1096 { 1098 {
1097 eol--; 1099 eol--;
1098 } 1100 }
1099 } 1101 }
1100 else 1102 else
1101 { 1103 {
1102 eol = sel_BR; 1104 eol = sel_BR;
1103 } 1105 }
1104 1106
1105 while (s <= eol) 1107 while (s <= eol)
1106 { 1108 {
1107 m[d++] = image[s++ - hist_BR].c; 1109 m[d++] = image[s++ - hist_BR].c;
1108 } 1110 }
1109 1111
1110 if (eol < sel_BR) 1112 if (eol < sel_BR)
1111 { 1113 {
1112 // eol processing see below ... 1114 // eol processing see below ...
1113 if ((eol + 1) % columns == 0) 1115 if ((eol + 1) % columns == 0)
1114 { 1116 {
1115 if (image[eol - hist_BR].c == ' ') 1117 if (image[eol - hist_BR].c == ' ')
1116 { 1118 {
1117 m[d++] = ' '; 1119 m[d++] = ' ';
1118 } 1120 }
1119 } 1121 }
1120 else 1122 else
1121 { 1123 {
1122 m[d++] = ((preserve_line_breaks || 1124 m[d++] = ((preserve_line_breaks ||
1123 ((eol % columns) == 0)) ? 1125 ((eol % columns) == 0)) ?
1124 '\n' : ' '); 1126 '\n' : ' ');
1125 } 1127 }
1126 } 1128 }
1127 1129
1128 s = (eol / columns + 1) * columns; 1130 s = (eol / columns + 1) * columns;
1129 } 1131 }
1130 } 1132 }
1131 1133
1132 QChar* qc = new QChar[d]; 1134 QChar* qc = new QChar[d];
1133 1135
1134 for (int i = 0; i < d; i++) 1136 for (int i = 0; i < d; i++)
1135 { 1137 {
1136 qc[i] = m[i]; 1138 qc[i] = m[i];
1137 } 1139 }
1138 1140
1139 QString res(qc, d); 1141 QString res(qc, d);
1140 1142
1141 delete [] m; 1143 delete [] m;
1142 delete [] qc; 1144 delete [] qc;
1143 1145
1144 return res; 1146 return res;
1145} 1147}
1146/* above ... end of line processing for selection -- psilva 1148/* above ... end of line processing for selection -- psilva
1147cases: 1149cases:
1148 1150
11491) (eol+1)%columns == 0 --> the whole line is filled. 11511) (eol+1)%columns == 0 --> the whole line is filled.
1150 If the last char is a space, insert (preserve) space. otherwise 1152 If the last char is a space, insert (preserve) space. otherwise
1151 leave the text alone, so that words that are broken by linewrap 1153 leave the text alone, so that words that are broken by linewrap
1152 are preserved. 1154 are preserved.
1153 1155
1154FIXME: 1156FIXME:
1155 * this suppresses \n for command output that is 1157 * this suppresses \n for command output that is
1156 sized to the exact column width of the screen. 1158 sized to the exact column width of the screen.
1157 1159
11582) eol%columns == 0 --> blank line. 11602) eol%columns == 0 --> blank line.
1159 insert a \n unconditionally. 1161 insert a \n unconditionally.
1160 Do it either you would because you are in preserve_line_break mode, 1162 Do it either you would because you are in preserve_line_break mode,
1161 or because it's an ASCII paragraph delimiter, so even when 1163 or because it's an ASCII paragraph delimiter, so even when
1162 not preserving line_breaks, you want to preserve paragraph breaks. 1164 not preserving line_breaks, you want to preserve paragraph breaks.
1163 1165
11643) else --> partially filled line 11663) else --> partially filled line
1165 insert a \n in preserve line break mode, else a space 1167 insert a \n in preserve line break mode, else a space
1166 The space prevents concatenation of the last word of one 1168 The space prevents concatenation of the last word of one
1167 line with the first of the next. 1169 line with the first of the next.
1168 1170
1169*/ 1171*/
1170 1172
1171void TEScreen::addHistLine() 1173void TEScreen::addHistLine()
1172{ 1174{
1173 assert(hasScroll() || histCursor == 0); 1175 assert(hasScroll() || histCursor == 0);
1174 1176
1175 // add to hist buffer 1177 // add to hist buffer
1176 // we have to take care about scrolling, too... 1178 // we have to take care about scrolling, too...
1177 1179
1178 if (hasScroll()){ 1180 if (hasScroll()){
1179 ca dft; 1181 ca dft;
1180 1182
1181 int end = columns - 1; 1183 int end = columns - 1;
1182 while (end >= 0 && image[end] == dft) 1184 while (end >= 0 && image[end] == dft)
1183 end -= 1; 1185 end -= 1;
1184 1186
1185 hist.addCells( image, end + 1); 1187 hist.addCells( image, end + 1);
1186 hist.addLine(); 1188 hist.addLine();
1187 1189
1188 // adjust history cursor 1190 // adjust history cursor
1189 histCursor += ( hist.getLines() - 1 == histCursor); 1191 histCursor += ( hist.getLines() - 1 == histCursor);
1190 } 1192 }
1191 1193
1192 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround 1194 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
1193} 1195}
1194 1196
1195void TEScreen::setHistCursor(int cursor) 1197void TEScreen::setHistCursor(int cursor)
1196{ 1198{
1197 histCursor = cursor; //FIXME:rangecheck 1199 histCursor = cursor; //FIXME:rangecheck
1198 if (histCursor > hist.getLines()) { 1200 if (histCursor > hist.getLines()) {
1199 histCursor = hist.getLines(); 1201 histCursor = hist.getLines();
1200 } 1202 }
1201 if (histCursor < 0) { 1203 if (histCursor < 0) {
1202 histCursor = 0; 1204 histCursor = 0;
1203 } 1205 }
1204} 1206}
1205 1207
1206void TEScreen::setHorzCursor(int cursor) 1208void TEScreen::setHorzCursor(int cursor)
1207{ 1209{
1208 horzCursor = cursor; 1210 horzCursor = cursor;
1209} 1211}
1210 1212
1211int TEScreen::getHistCursor() 1213int TEScreen::getHistCursor()
1212{ 1214{
1213 return histCursor; 1215 return histCursor;
1214} 1216}
1215 1217
1216int TEScreen::getHorzCursor() 1218int TEScreen::getHorzCursor()
1217{ 1219{
1218 return horzCursor; 1220 return horzCursor;
1219} 1221}
1220 1222
1221int TEScreen::getHistLines() 1223int TEScreen::getHistLines()
1222{ 1224{
1223 return hist.getLines(); 1225 return hist.getLines();
1224} 1226}
1225 1227
1226void TEScreen::setScroll(bool on) 1228void TEScreen::setScroll(bool on)
1227{ 1229{
1228 histCursor = 0; 1230 histCursor = 0;
1229 clearSelection(); 1231 clearSelection();
1230 hist.setScroll(on); 1232 hist.setScroll(on);
1231} 1233}
1232 1234
1233bool TEScreen::hasScroll() 1235bool TEScreen::hasScroll()
1234{ 1236{
1235 return hist.hasScroll(); 1237 return hist.hasScroll();
1236} 1238}
diff --git a/inputmethods/dasher/PPMLanguageModel.cpp b/inputmethods/dasher/PPMLanguageModel.cpp
index 137b07f..d767d16 100644
--- a/inputmethods/dasher/PPMLanguageModel.cpp
+++ b/inputmethods/dasher/PPMLanguageModel.cpp
@@ -1,309 +1,310 @@
1// PPMLanguageModel.h 1// PPMLanguageModel.h
2// 2//
3///////////////////////////////////////////////////////////////////////////// 3/////////////////////////////////////////////////////////////////////////////
4// 4//
5// Copyright (c) 1999-2002 David Ward 5// Copyright (c) 1999-2002 David Ward
6// 6//
7///////////////////////////////////////////////////////////////////////////// 7/////////////////////////////////////////////////////////////////////////////
8 8
9#include <math.h> 9#include <math.h>
10#include "PPMLanguageModel.h" 10#include "PPMLanguageModel.h"
11 11
12using namespace Dasher; 12using namespace Dasher;
13using namespace std; 13using namespace std;
14 14
15// static TCHAR debug[256]; 15// static TCHAR debug[256];
16typedef unsigned long ulong; 16typedef unsigned long ulong;
17 17
18//////////////////////////////////////////////////////////////////////// 18////////////////////////////////////////////////////////////////////////
19/// PPMnode definitions 19/// PPMnode definitions
20//////////////////////////////////////////////////////////////////////// 20////////////////////////////////////////////////////////////////////////
21 21
22CPPMLanguageModel::CPPMnode *CPPMLanguageModel::CPPMnode::find_symbol(int sym) 22CPPMLanguageModel::CPPMnode *CPPMLanguageModel::CPPMnode::find_symbol(int sym)
23// see if symbol is a child of node 23// see if symbol is a child of node
24{ 24{
25 // printf("finding symbol %d at node %d\n",sym,node->id); 25 // printf("finding symbol %d at node %d\n",sym,node->id);
26 CPPMnode *found=child; 26 CPPMnode *found=child;
27 while (found) { 27 while (found) {
28 if (found->symbol==sym) 28 if (found->symbol==sym)
29 return found; 29 return found;
30 found=found->next; 30 found=found->next;
31 } 31 }
32 return 0; 32 return 0;
33} 33}
34 34
35 35
36CPPMLanguageModel::CPPMnode * CPPMLanguageModel::CPPMnode::add_symbol_to_node(int sym,int *update) 36CPPMLanguageModel::CPPMnode * CPPMLanguageModel::CPPMnode::add_symbol_to_node(int sym,int *update)
37{ 37{
38 CPPMnode *born,*search; 38 CPPMnode *born,*search;
39 search=find_symbol(sym); 39 search=find_symbol(sym);
40 if (!search) { 40 if (!search) {
41 born = new CPPMnode(sym); 41 born = new CPPMnode(sym);
42 born->next=child; 42 born->next=child;
43 child=born; 43 child=born;
44 // node->count=1; 44 // node->count=1;
45 return born; 45 return born;
46 } else { 46 } else {
47 if (*update) { // perform update exclusions 47 if (*update) { // perform update exclusions
48 search->count++; 48 search->count++;
49 *update=0; 49 *update=0;
50 } 50 }
51 return search; 51 return search;
52 } 52 }
53 53
54} 54}
55 55
56 56
57///////////////////////////////////////////////////////////////////// 57/////////////////////////////////////////////////////////////////////
58// CPPMLanguageModel defs 58// CPPMLanguageModel defs
59///////////////////////////////////////////////////////////////////// 59/////////////////////////////////////////////////////////////////////
60 60
61CPPMLanguageModel::CPPMLanguageModel(CAlphabet *_alphabet,int _normalization) 61CPPMLanguageModel::CPPMLanguageModel(CAlphabet *_alphabet,int _normalization)
62 : CLanguageModel(_alphabet,_normalization) 62 : CLanguageModel(_alphabet,_normalization), root(0), m_rootcontext(0)
63{ 63{
64 root=new CPPMnode(-1); 64 root=new CPPMnode(-1);
65 m_rootcontext=new CPPMContext(root,0); 65 m_rootcontext=new CPPMContext(root,0);
66} 66}
67 67
68 68
69CPPMLanguageModel::~CPPMLanguageModel() 69CPPMLanguageModel::~CPPMLanguageModel()
70{ 70{
71 delete m_rootcontext;
71 delete root; 72 delete root;
72} 73}
73 74
74 75
75bool CPPMLanguageModel::GetProbs(CContext *context,vector<unsigned int> &probs,double ) 76bool CPPMLanguageModel::GetProbs(CContext *context,vector<unsigned int> &probs,double )
76 // get the probability distribution at the context 77 // get the probability distribution at the context
77{ 78{
78 // seems like we have to have this hack for VC++ 79 // seems like we have to have this hack for VC++
79 CPPMContext *ppmcontext=static_cast<CPPMContext *> (context); 80 CPPMContext *ppmcontext=static_cast<CPPMContext *> (context);
80 81
81 82
82 int modelchars=GetNumberModelChars(); 83 int modelchars=GetNumberModelChars();
83 int norm=CLanguageModel::normalization(); 84 int norm=CLanguageModel::normalization();
84 probs.resize(modelchars); 85 probs.resize(modelchars);
85 CPPMnode *temp,*s; 86 CPPMnode *temp,*s;
86 int loop,total; 87 int loop,total;
87 int sym; 88 int sym;
88 // ulong spent=0; 89 // ulong spent=0;
89 ulong size_of_slice; 90 ulong size_of_slice;
90 bool *exclusions=new bool [modelchars]; 91 bool *exclusions=new bool [modelchars];
91 ulong uniform=modelchars; 92 ulong uniform=modelchars;
92 ulong tospend=norm-uniform; 93 ulong tospend=norm-uniform;
93 temp=ppmcontext->head; 94 temp=ppmcontext->head;
94 for (loop=0; loop <modelchars; loop++) { /* set up the exclusions array */ 95 for (loop=0; loop <modelchars; loop++) { /* set up the exclusions array */
95 probs[loop]=0; 96 probs[loop]=0;
96 exclusions[loop]=0; 97 exclusions[loop]=0;
97 } 98 }
98 while (temp!=0) { 99 while (temp!=0) {
99 //Usprintf(debug,TEXT("tospend %u\n"),tospend); 100 //Usprintf(debug,TEXT("tospend %u\n"),tospend);
100 //DebugOutput(TEXT("round\n")); 101 //DebugOutput(TEXT("round\n"));
101 total=0; 102 total=0;
102 s=temp->child; 103 s=temp->child;
103 while (s) { 104 while (s) {
104 sym=s->symbol; 105 sym=s->symbol;
105 if (!exclusions[s->symbol]) 106 if (!exclusions[s->symbol])
106 total=total+s->count; 107 total=total+s->count;
107 s=s->next; 108 s=s->next;
108 } 109 }
109 if (total) { 110 if (total) {
110 //Usprintf(debug,TEXT"escape %u\n"),tospend* 111 //Usprintf(debug,TEXT"escape %u\n"),tospend*
111 size_of_slice=tospend; 112 size_of_slice=tospend;
112 s=temp->child; 113 s=temp->child;
113 while (s) { 114 while (s) {
114 if (!exclusions[s->symbol]) { 115 if (!exclusions[s->symbol]) {
115 exclusions[s->symbol]=1; 116 exclusions[s->symbol]=1;
116 ulong p=size_of_slice*(2*s->count-1)/2/ulong(total); 117 ulong p=size_of_slice*(2*s->count-1)/2/ulong(total);
117 probs[s->symbol]+=p; 118 probs[s->symbol]+=p;
118 tospend-=p; 119 tospend-=p;
119 } 120 }
120 // Usprintf(debug,TEXT("sym %u counts %d p %u tospend %u \n"),sym,s->count,p,tospend); 121 // Usprintf(debug,TEXT("sym %u counts %d p %u tospend %u \n"),sym,s->count,p,tospend);
121 // DebugOutput(debug); 122 // DebugOutput(debug);
122 s=s->next; 123 s=s->next;
123 } 124 }
124 } 125 }
125 temp = temp->vine; 126 temp = temp->vine;
126 } 127 }
127 //Usprintf(debug,TEXT("Norm %u tospend %u\n"),Norm,tospend); 128 //Usprintf(debug,TEXT("Norm %u tospend %u\n"),Norm,tospend);
128 //DebugOutput(debug); 129 //DebugOutput(debug);
129 130
130 size_of_slice=tospend; 131 size_of_slice=tospend;
131 int symbolsleft=0; 132 int symbolsleft=0;
132 for (sym=1;sym<modelchars;sym++) 133 for (sym=1;sym<modelchars;sym++)
133 if (!probs[sym]) 134 if (!probs[sym])
134 symbolsleft++; 135 symbolsleft++;
135 for (sym=1;sym<modelchars;sym++) 136 for (sym=1;sym<modelchars;sym++)
136 if (!probs[sym]) { 137 if (!probs[sym]) {
137 ulong p=size_of_slice/symbolsleft; 138 ulong p=size_of_slice/symbolsleft;
138 probs[sym]+=p; 139 probs[sym]+=p;
139 tospend-=p; 140 tospend-=p;
140 } 141 }
141 142
142 // distribute what's left evenly 143 // distribute what's left evenly
143 tospend+=uniform; 144 tospend+=uniform;
144 for (sym=1;sym<modelchars;sym++) { 145 for (sym=1;sym<modelchars;sym++) {
145 ulong p=tospend/(modelchars-sym); 146 ulong p=tospend/(modelchars-sym);
146 probs[sym]+=p; 147 probs[sym]+=p;
147 tospend-=p; 148 tospend-=p;
148 } 149 }
149 //Usprintf(debug,TEXT("finaltospend %u\n"),tospend); 150 //Usprintf(debug,TEXT("finaltospend %u\n"),tospend);
150 //DebugOutput(debug); 151 //DebugOutput(debug);
151 152
152 // free(exclusions); // !!! 153 // free(exclusions); // !!!
153 // !!! NB by IAM: p577 Stroustrup 3rd Edition: "Allocating an object using new and deleting it using free() is asking for trouble" 154 // !!! NB by IAM: p577 Stroustrup 3rd Edition: "Allocating an object using new and deleting it using free() is asking for trouble"
154 delete[] exclusions; 155 delete[] exclusions;
155 return true; 156 return true;
156} 157}
157 158
158 159
159void CPPMLanguageModel::AddSymbol(CPPMLanguageModel::CPPMContext &context,int symbol) 160void CPPMLanguageModel::AddSymbol(CPPMLanguageModel::CPPMContext &context,int symbol)
160 // add symbol to the context 161 // add symbol to the context
161 // creates new nodes, updates counts 162 // creates new nodes, updates counts
162 // and leaves 'context' at the new context 163 // and leaves 'context' at the new context
163{ 164{
164 // sanity check 165 // sanity check
165 if (symbol==0 || symbol>=GetNumberModelChars()) 166 if (symbol==0 || symbol>=GetNumberModelChars())
166 return; 167 return;
167 168
168 CPPMnode *vineptr,*temp; 169 CPPMnode *vineptr,*temp;
169 int updatecnt=1; 170 int updatecnt=1;
170 171
171 temp=context.head->vine; 172 temp=context.head->vine;
172 context.head=context.head->add_symbol_to_node(symbol,&updatecnt); 173 context.head=context.head->add_symbol_to_node(symbol,&updatecnt);
173 vineptr=context.head; 174 vineptr=context.head;
174 context.order++; 175 context.order++;
175 176
176 while (temp!=0) { 177 while (temp!=0) {
177 vineptr->vine=temp->add_symbol_to_node(symbol,&updatecnt); 178 vineptr->vine=temp->add_symbol_to_node(symbol,&updatecnt);
178 vineptr=vineptr->vine; 179 vineptr=vineptr->vine;
179 temp=temp->vine; 180 temp=temp->vine;
180 } 181 }
181 vineptr->vine=root; 182 vineptr->vine=root;
182 if (context.order>MAX_ORDER){ 183 if (context.order>MAX_ORDER){
183 context.head=context.head->vine; 184 context.head=context.head->vine;
184 context.order--; 185 context.order--;
185 } 186 }
186} 187}
187 188
188 189
189// update context with symbol 'Symbol' 190// update context with symbol 'Symbol'
190void CPPMLanguageModel::EnterSymbol(CContext* Context, modelchar Symbol) 191void CPPMLanguageModel::EnterSymbol(CContext* Context, modelchar Symbol)
191{ 192{
192 CPPMLanguageModel::CPPMContext& context = * static_cast<CPPMContext *> (Context); 193 CPPMLanguageModel::CPPMContext& context = * static_cast<CPPMContext *> (Context);
193 194
194 CPPMnode *find; 195 CPPMnode *find;
195 // CPPMnode *temp=context.head; 196 // CPPMnode *temp=context.head;
196 197
197 while (context.head) { 198 while (context.head) {
198 find =context.head->find_symbol(Symbol); 199 find =context.head->find_symbol(Symbol);
199 if (find) { 200 if (find) {
200 context.order++; 201 context.order++;
201 context.head=find; 202 context.head=find;
202 //Usprintf(debug,TEXT("found context %x order %d\n"),head,order); 203 //Usprintf(debug,TEXT("found context %x order %d\n"),head,order);
203 //DebugOutput(debug); 204 //DebugOutput(debug);
204 return; 205 return;
205 } 206 }
206 context.order--; 207 context.order--;
207 context.head=context.head->vine; 208 context.head=context.head->vine;
208 } 209 }
209 210
210 if (context.head==0) { 211 if (context.head==0) {
211 context.head=root; 212 context.head=root;
212 context.order=0; 213 context.order=0;
213 } 214 }
214 215
215} 216}
216 217
217 218
218void CPPMLanguageModel::LearnSymbol(CContext* Context, modelchar Symbol) 219void CPPMLanguageModel::LearnSymbol(CContext* Context, modelchar Symbol)
219{ 220{
220 CPPMLanguageModel::CPPMContext& context = * static_cast<CPPMContext *> (Context); 221 CPPMLanguageModel::CPPMContext& context = * static_cast<CPPMContext *> (Context);
221 AddSymbol(context, Symbol); 222 AddSymbol(context, Symbol);
222} 223}
223 224
224 225
225void CPPMLanguageModel::dumpSymbol(int symbol) 226void CPPMLanguageModel::dumpSymbol(int symbol)
226{ 227{
227 if ((symbol <= 32) || (symbol >= 127)) 228 if ((symbol <= 32) || (symbol >= 127))
228 printf( "<%d>", symbol ); 229 printf( "<%d>", symbol );
229 else 230 else
230 printf( "%c", symbol ); 231 printf( "%c", symbol );
231} 232}
232 233
233 234
234void CPPMLanguageModel::dumpString( char *str, int pos, int len ) 235void CPPMLanguageModel::dumpString( char *str, int pos, int len )
235 // Dump the string STR starting at position POS 236 // Dump the string STR starting at position POS
236{ 237{
237 char cc; 238 char cc;
238 int p; 239 int p;
239 for (p = pos; p<pos+len; p++) { 240 for (p = pos; p<pos+len; p++) {
240 cc = str [p]; 241 cc = str [p];
241 if ((cc <= 31) || (cc >= 127)) 242 if ((cc <= 31) || (cc >= 127))
242 printf( "<%d>", cc ); 243 printf( "<%d>", cc );
243 else 244 else
244 printf( "%c", cc ); 245 printf( "%c", cc );
245 } 246 }
246} 247}
247 248
248 249
249void CPPMLanguageModel::dumpTrie( CPPMLanguageModel::CPPMnode *, int ) 250void CPPMLanguageModel::dumpTrie( CPPMLanguageModel::CPPMnode *, int )
250 // diagnostic display of the PPM trie from node t and deeper 251 // diagnostic display of the PPM trie from node t and deeper
251{ 252{
252//TODO 253//TODO
253/* 254/*
254 dchar debug[256]; 255 dchar debug[256];
255 int sym; 256 int sym;
256 CPPMnode *s; 257 CPPMnode *s;
257 Usprintf( debug,TEXT("%5d %7x "), d, t ); 258 Usprintf( debug,TEXT("%5d %7x "), d, t );
258 //TODO: Uncomment this when headers sort out 259 //TODO: Uncomment this when headers sort out
259 //DebugOutput(debug); 260 //DebugOutput(debug);
260 if (t < 0) // pointer to input 261 if (t < 0) // pointer to input
261 printf( " <" ); 262 printf( " <" );
262 else { 263 else {
263 Usprintf(debug,TEXT( " %3d %5d %7x %7x %7x <"), t->symbol,t->count, t->vine, t->child, t->next ); 264 Usprintf(debug,TEXT( " %3d %5d %7x %7x %7x <"), t->symbol,t->count, t->vine, t->child, t->next );
264 //TODO: Uncomment this when headers sort out 265 //TODO: Uncomment this when headers sort out
265 //DebugOutput(debug); 266 //DebugOutput(debug);
266 } 267 }
267 268
268 dumpString( dumpTrieStr, 0, d ); 269 dumpString( dumpTrieStr, 0, d );
269 Usprintf( debug,TEXT(">\n") ); 270 Usprintf( debug,TEXT(">\n") );
270 //TODO: Uncomment this when headers sort out 271 //TODO: Uncomment this when headers sort out
271 //DebugOutput(debug); 272 //DebugOutput(debug);
272 if (t != 0) { 273 if (t != 0) {
273 s = t->child; 274 s = t->child;
274 while (s != 0) { 275 while (s != 0) {
275 sym =s->symbol; 276 sym =s->symbol;
276 277
277 dumpTrieStr [d] = sym; 278 dumpTrieStr [d] = sym;
278 dumpTrie( s, d+1 ); 279 dumpTrie( s, d+1 );
279 s = s->next; 280 s = s->next;
280 } 281 }
281 } 282 }
282*/ 283*/
283} 284}
284 285
285 286
286void CPPMLanguageModel::dump() 287void CPPMLanguageModel::dump()
287 // diagnostic display of the whole PPM trie 288 // diagnostic display of the whole PPM trie
288{ 289{
289// TODO: 290// TODO:
290/* 291/*
291 dchar debug[256]; 292 dchar debug[256];
292 Usprintf(debug,TEXT( "Dump of Trie : \n" )); 293 Usprintf(debug,TEXT( "Dump of Trie : \n" ));
293 //TODO: Uncomment this when headers sort out 294 //TODO: Uncomment this when headers sort out
294 //DebugOutput(debug); 295 //DebugOutput(debug);
295 Usprintf(debug,TEXT( "---------------\n" )); 296 Usprintf(debug,TEXT( "---------------\n" ));
296 //TODO: Uncomment this when headers sort out 297 //TODO: Uncomment this when headers sort out
297 //DebugOutput(debug); 298 //DebugOutput(debug);
298 Usprintf( debug,TEXT( "depth node symbol count vine child next context\n") ); 299 Usprintf( debug,TEXT( "depth node symbol count vine child next context\n") );
299 //TODO: Uncomment this when headers sort out 300 //TODO: Uncomment this when headers sort out
300 //DebugOutput(debug); 301 //DebugOutput(debug);
301 dumpTrie( root, 0 ); 302 dumpTrie( root, 0 );
302 Usprintf( debug,TEXT( "---------------\n" )); 303 Usprintf( debug,TEXT( "---------------\n" ));
303 //TODO: Uncomment this when headers sort out 304 //TODO: Uncomment this when headers sort out
304 //DebugOutput(debug); 305 //DebugOutput(debug);
305 Usprintf(debug,TEXT( "\n" )); 306 Usprintf(debug,TEXT( "\n" ));
306 //TODO: Uncomment this when headers sort out 307 //TODO: Uncomment this when headers sort out
307 //DebugOutput(debug); 308 //DebugOutput(debug);
308*/ 309*/
309} 310}
diff --git a/noncore/apps/opie-reader/Bkmks.cpp b/noncore/apps/opie-reader/Bkmks.cpp
index 440d8be..28f6318 100644
--- a/noncore/apps/opie-reader/Bkmks.cpp
+++ b/noncore/apps/opie-reader/Bkmks.cpp
@@ -1,399 +1,415 @@
1#include <qmessagebox.h> 1#include <qmessagebox.h>
2 2
3#include "Bkmks.h" 3#include "Bkmks.h"
4 4
5#include "StyleConsts.h" 5#include "StyleConsts.h"
6#include "Markups.h" 6#include "Markups.h"
7#include "my_list.h" 7#include "my_list.h"
8#include "version.h" 8#include "version.h"
9#include "names.h" 9#include "names.h"
10 10
11const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE); 11const unsigned long BkmkFile::magic = ((unsigned long)'q' << 24) | ((unsigned long)'t' << 16) | ((unsigned long)'r' << 8) | ((unsigned long)BKMKTYPE);
12 12
13Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) 13Bkmk::Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p) :
14 m_name(0),
15 m_namelen(0),
16 m_anno(0),
17 m_annolen(0),
18 m_position(0)
14{ 19{
15 init(_nm, _nmlen, _anno, _annolen, _p); 20 init(_nm, _nmlen, _anno, _annolen, _p);
16} 21}
17 22
18Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p) 23Bkmk::Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short annolen, unsigned int _p) : m_position(_p)
19{ 24{
20 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p); 25 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, annolen, _p);
21} 26}
22 27
28Bkmk::Bkmk(const Bkmk& rhs) :
29 m_name(0),
30 m_namelen(0),
31 m_anno(0),
32 m_annolen(0),
33 m_position(0)
34{
35 init(rhs.name(), sizeof(tchar)*(ustrlen(rhs.name())+1), rhs.anno(),
36 sizeof(tchar)*(ustrlen(rhs.anno())+1), rhs.value());
37}
38
23Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p) 39Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p) : m_position(_p)
24{ 40{
25 if (_anno == NULL) 41 if (_anno == NULL)
26 { 42 {
27 tchar t = 0; 43 tchar t = 0;
28 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); 44 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p);
29 } 45 }
30 else 46 else
31 { 47 {
32 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); 48 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p);
33 } 49 }
34} 50}
35 51
36Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p) 52Bkmk::Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2) : m_position(_p)
37{ 53{
38 if (_anno == NULL) 54 if (_anno == NULL)
39 { 55 {
40 tchar t = 0; 56 tchar t = 0;
41 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p); 57 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), &t, sizeof(t), _p);
42 } 58 }
43 else 59 else
44 { 60 {
45 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p); 61 init(_nm, sizeof(tchar)*(ustrlen(_nm)+1), _anno, sizeof(tchar)*(ustrlen(_anno)+1), _p);
46 } 62 }
47 m_position2 = _p2; 63 m_position2 = _p2;
48 m_red = m_green = m_blue = 127; 64 m_red = m_green = m_blue = 127;
49} 65}
50 66
51void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p) 67void Bkmk::init(const void* _nm, unsigned short _nmlen, const void* _anno, unsigned short _annolen, unsigned int _p)
52{ 68{
53 m_namelen = _nmlen; 69 m_namelen = _nmlen;
54 if (m_namelen > 0) 70 if (m_namelen > 0)
55 { 71 {
56 m_name = new unsigned char[m_namelen]; 72 m_name = new unsigned char[m_namelen];
57 memcpy(m_name, _nm, m_namelen); 73 memcpy(m_name, _nm, m_namelen);
58 } 74 }
59 else 75 else
60 { 76 {
61 m_name = NULL; 77 m_name = NULL;
62 } 78 }
63 79
64 m_annolen = _annolen; 80 m_annolen = _annolen;
65 if (m_annolen > 0) 81 if (m_annolen > 0)
66 { 82 {
67 m_anno = new unsigned char[m_annolen]; 83 m_anno = new unsigned char[m_annolen];
68 memcpy(m_anno, _anno, m_annolen); 84 memcpy(m_anno, _anno, m_annolen);
69 } 85 }
70 else 86 else
71 { 87 {
72 m_anno = NULL; 88 m_anno = NULL;
73 } 89 }
74 m_position = _p; 90 m_position = _p;
75 m_position2 = _p; 91 m_position2 = _p;
76 m_red = m_green = m_blue = 255; 92 m_red = m_green = m_blue = 255;
77 m_level = 0; 93 m_level = 0;
78} 94}
79 95
80Bkmk::~Bkmk() 96Bkmk::~Bkmk()
81{ 97{
82 if (m_name != NULL) delete [] m_name; 98 if (m_name != NULL) delete [] m_name;
83 m_name = NULL; 99 m_name = NULL;
84 if (m_anno != NULL) delete [] m_anno; 100 if (m_anno != NULL) delete [] m_anno;
85 m_anno = NULL; 101 m_anno = NULL;
86} 102}
87 103
88Bkmk& Bkmk::operator=(const Bkmk& rhs) 104Bkmk& Bkmk::operator=(const Bkmk& rhs)
89{ 105{
90 if (m_name != NULL) 106 if (m_name != NULL)
91 { 107 {
92 delete [] m_name; 108 delete [] m_name;
93 m_name = NULL; 109 m_name = NULL;
94 } 110 }
95 if (m_anno != NULL) 111 if (m_anno != NULL)
96 { 112 {
97 delete [] m_anno; 113 delete [] m_anno;
98 m_anno = NULL; 114 m_anno = NULL;
99 } 115 }
100 if (rhs.m_name != NULL) 116 if (rhs.m_name != NULL)
101 { 117 {
102 m_namelen = rhs.m_namelen; 118 m_namelen = rhs.m_namelen;
103 m_name = new unsigned char[m_namelen]; 119 m_name = new unsigned char[m_namelen];
104 memcpy(m_name, rhs.m_name, m_namelen); 120 memcpy(m_name, rhs.m_name, m_namelen);
105 } 121 }
106 else 122 else
107 m_name = NULL; 123 m_name = NULL;
108 if (rhs.m_anno != NULL) 124 if (rhs.m_anno != NULL)
109 { 125 {
110 m_annolen = rhs.m_annolen; 126 m_annolen = rhs.m_annolen;
111 m_anno = new unsigned char[m_annolen]; 127 m_anno = new unsigned char[m_annolen];
112 memcpy(m_anno, rhs.m_anno, m_annolen); 128 memcpy(m_anno, rhs.m_anno, m_annolen);
113 } 129 }
114 else 130 else
115 m_anno = NULL; 131 m_anno = NULL;
116 m_position = rhs.m_position; 132 m_position = rhs.m_position;
117 m_position2 = rhs.m_position2; 133 m_position2 = rhs.m_position2;
118 m_red = rhs.m_red; 134 m_red = rhs.m_red;
119 m_green = rhs.m_green; 135 m_green = rhs.m_green;
120 m_blue = rhs.m_blue; 136 m_blue = rhs.m_blue;
121 m_level = rhs.m_level; 137 m_level = rhs.m_level;
122 return *this; 138 return *this;
123} 139}
124 140
125bool Bkmk::operator==(const Bkmk& rhs) 141bool Bkmk::operator==(const Bkmk& rhs)
126{ 142{
127 return ((m_position == rhs.m_position) && (m_position2 == rhs.m_position2) && (rhs.m_namelen == m_namelen) && memcmp(m_name,rhs.m_name,m_namelen) == 0); 143 return ((m_position == rhs.m_position) && (m_position2 == rhs.m_position2) && (rhs.m_namelen == m_namelen) && memcmp(m_name,rhs.m_name,m_namelen) == 0);
128} 144}
129 145
130void Bkmk::setAnno(unsigned char* t, unsigned short len) 146void Bkmk::setAnno(unsigned char* t, unsigned short len)
131{ 147{
132 if (m_anno != NULL) 148 if (m_anno != NULL)
133 { 149 {
134 delete [] m_anno; 150 delete [] m_anno;
135 m_anno = NULL; 151 m_anno = NULL;
136 } 152 }
137 if (t != NULL) 153 if (t != NULL)
138 { 154 {
139 m_annolen = len; 155 m_annolen = len;
140 m_anno = new unsigned char[m_annolen]; 156 m_anno = new unsigned char[m_annolen];
141 memcpy(m_anno, t, m_annolen); 157 memcpy(m_anno, t, m_annolen);
142 } 158 }
143 else 159 else
144 { 160 {
145 m_annolen = sizeof(tchar); 161 m_annolen = sizeof(tchar);
146 m_anno = new unsigned char[m_annolen]; 162 m_anno = new unsigned char[m_annolen];
147 *((tchar*)m_anno) = 0; 163 *((tchar*)m_anno) = 0;
148 } 164 }
149} 165}
150 166
151void Bkmk::setAnno(tchar* t) 167void Bkmk::setAnno(tchar* t)
152{ 168{
153 if (m_anno != NULL) 169 if (m_anno != NULL)
154 { 170 {
155 delete [] m_anno; 171 delete [] m_anno;
156 m_anno = NULL; 172 m_anno = NULL;
157 } 173 }
158 if (t != NULL) 174 if (t != NULL)
159 { 175 {
160 unsigned short len = ustrlen(t)+1; 176 unsigned short len = ustrlen(t)+1;
161 m_annolen = sizeof(tchar)*len; 177 m_annolen = sizeof(tchar)*len;
162 m_anno = new unsigned char[m_annolen]; 178 m_anno = new unsigned char[m_annolen];
163 memcpy(m_anno, t, m_annolen); 179 memcpy(m_anno, t, m_annolen);
164 } 180 }
165 else 181 else
166 { 182 {
167 m_annolen = sizeof(tchar); 183 m_annolen = sizeof(tchar);
168 m_anno = new unsigned char[m_annolen]; 184 m_anno = new unsigned char[m_annolen];
169 *((tchar*)m_anno) = 0; 185 *((tchar*)m_anno) = 0;
170 } 186 }
171} 187}
172 188
173BkmkFile::BkmkFile(const char *fnm, bool w, bool _x) 189BkmkFile::BkmkFile(const char *fnm, bool w, bool _x)
174 : 190 :
175 wt(w), isUpgraded(false), m_extras(_x) 191 wt(w), isUpgraded(false), m_extras(_x)
176{ 192{
177 if (w) 193 if (w)
178 { 194 {
179 f = fopen(fnm, "wb"); 195 f = fopen(fnm, "wb");
180 } 196 }
181 else 197 else
182 { 198 {
183 f = fopen(fnm, "rb"); 199 f = fopen(fnm, "rb");
184 } 200 }
185} 201}
186 202
187BkmkFile::~BkmkFile() 203BkmkFile::~BkmkFile()
188{ 204{
189 if (f != NULL) fclose(f); 205 if (f != NULL) fclose(f);
190} 206}
191 207
192void BkmkFile::write(const Bkmk& b) 208void BkmkFile::write(const Bkmk& b)
193{ 209{
194 if (f != NULL) 210 if (f != NULL)
195 { 211 {
196 fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f); 212 fwrite(&b.m_namelen, sizeof(b.m_namelen),1,f);
197 fwrite(b.m_name,1,b.m_namelen,f); 213 fwrite(b.m_name,1,b.m_namelen,f);
198 fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f); 214 fwrite(&b.m_annolen, sizeof(b.m_annolen),1,f);
199 fwrite(b.m_anno,1,b.m_annolen,f); 215 fwrite(b.m_anno,1,b.m_annolen,f);
200 fwrite(&b.m_position,sizeof(b.m_position),1,f); 216 fwrite(&b.m_position,sizeof(b.m_position),1,f);
201 if (m_extras) 217 if (m_extras)
202 { 218 {
203 fwrite(&b.m_position2,sizeof(b.m_position2),1,f); 219 fwrite(&b.m_position2,sizeof(b.m_position2),1,f);
204 fwrite(&b.m_red,sizeof(b.m_red),1,f); 220 fwrite(&b.m_red,sizeof(b.m_red),1,f);
205 fwrite(&b.m_green,sizeof(b.m_green),1,f); 221 fwrite(&b.m_green,sizeof(b.m_green),1,f);
206 fwrite(&b.m_blue,sizeof(b.m_blue),1,f); 222 fwrite(&b.m_blue,sizeof(b.m_blue),1,f);
207 fwrite(&b.m_level,sizeof(b.m_level),1,f); 223 fwrite(&b.m_level,sizeof(b.m_level),1,f);
208 } 224 }
209 } 225 }
210} 226}
211 227
212void BkmkFile::write(CList<Bkmk>& bl) 228void BkmkFile::write(CList<Bkmk>& bl)
213{ 229{
214 if (f != NULL) 230 if (f != NULL)
215 { 231 {
216 fwrite(&magic, sizeof(magic), 1, f); 232 fwrite(&magic, sizeof(magic), 1, f);
217 for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++) 233 for (CList<Bkmk>::iterator i = bl.begin(); i != bl.end(); i++)
218 { 234 {
219 write(*i); 235 write(*i);
220 } 236 }
221 } 237 }
222} 238}
223 239
224CList<Bkmk>* BkmkFile::readall() 240CList<Bkmk>* BkmkFile::readall()
225{ 241{
226 CList<Bkmk>* bl = NULL; 242 CList<Bkmk>* bl = NULL;
227 if (f != NULL) 243 if (f != NULL)
228 { 244 {
229 unsigned long newmagic; 245 unsigned long newmagic;
230 fread(&newmagic, sizeof(newmagic), 1, f); 246 fread(&newmagic, sizeof(newmagic), 1, f);
231 if ((newmagic & 0xffffff00) != (magic & 0xffffff00)) 247 if ((newmagic & 0xffffff00) != (magic & 0xffffff00))
232 { 248 {
233 if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0) 249 if (QMessageBox::warning(NULL, "Old bookmark file!", "Which version of " PROGNAME "\ndid you upgrade from?", "0_4*", "Any other version") == 0)
234 { 250 {
235 fseek(f,0,SEEK_SET); 251 fseek(f,0,SEEK_SET);
236 bl = readall00(&read05); 252 bl = readall00(&read05);
237 } 253 }
238 else 254 else
239 { 255 {
240 fseek(f,0,SEEK_SET); 256 fseek(f,0,SEEK_SET);
241 bl = readall00(&read03); 257 bl = readall00(&read03);
242 } 258 }
243 isUpgraded = true; 259 isUpgraded = true;
244 } 260 }
245 else 261 else
246 { 262 {
247 switch(newmagic & 0xff) 263 switch(newmagic & 0xff)
248 { 264 {
249 case 7: 265 case 7:
250 isUpgraded = false; 266 isUpgraded = false;
251 bl = readall00(read07); 267 bl = readall00(read07);
252 // qDebug("Correct version!"); 268 // qDebug("Correct version!");
253 break; 269 break;
254 case 6: 270 case 6:
255 isUpgraded = true; 271 isUpgraded = true;
256 bl = readall00(read06); 272 bl = readall00(read06);
257 // qDebug("Correct version!"); 273 // qDebug("Correct version!");
258 break; 274 break;
259 case 5: 275 case 5:
260 isUpgraded = true; 276 isUpgraded = true;
261 bl = readall00(read05); 277 bl = readall00(read05);
262 // qDebug("Known version!"); 278 // qDebug("Known version!");
263 break; 279 break;
264 default: 280 default:
265 // qDebug("Unknown version!"); 281 // qDebug("Unknown version!");
266 isUpgraded = true; 282 isUpgraded = true;
267 bl = readall00(read05); 283 bl = readall00(read05);
268 } 284 }
269 } 285 }
270 } 286 }
271 return bl; 287 return bl;
272} 288}
273 289
274CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*)) 290CList<Bkmk>* BkmkFile::readall00(Bkmk* (*readfn)(BkmkFile*, FILE*))
275{ 291{
276 CList<Bkmk>* bl = new CList<Bkmk>; 292 CList<Bkmk>* bl = new CList<Bkmk>;
277 while (1) 293 while (1)
278 { 294 {
279 Bkmk* b = (*readfn)(this, f); 295 Bkmk* b = (*readfn)(this, f);
280 if (b == NULL) break; 296 if (b == NULL) break;
281 bl->push_back(*b); 297 bl->push_back(*b);
282 delete b; 298 delete b;
283 } 299 }
284 return bl; 300 return bl;
285} 301}
286 302
287Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f) 303Bkmk* BkmkFile::read03(BkmkFile* /*_this*/, FILE* f)
288{ 304{
289 Bkmk* b = NULL; 305 Bkmk* b = NULL;
290 if (f != NULL) 306 if (f != NULL)
291 { 307 {
292 unsigned short ln; 308 unsigned short ln;
293 if (fread(&ln,sizeof(ln),1,f) == 1) 309 if (fread(&ln,sizeof(ln),1,f) == 1)
294 { 310 {
295 tchar* name = new tchar[ln+1]; 311 tchar* name = new tchar[ln+1];
296 fread(name,sizeof(tchar),ln,f); 312 fread(name,sizeof(tchar),ln,f);
297 name[ln] = 0; 313 name[ln] = 0;
298 314
299 ln = 0; 315 ln = 0;
300 tchar* anno = new tchar[ln+1]; 316 tchar* anno = new tchar[ln+1];
301 anno[ln] = 0; 317 anno[ln] = 0;
302 318
303 unsigned int pos; 319 unsigned int pos;
304 fread(&pos,sizeof(pos),1,f); 320 fread(&pos,sizeof(pos),1,f);
305 b = new Bkmk(name,anno,pos); 321 b = new Bkmk(name,anno,pos);
306 } 322 }
307 } 323 }
308 return b; 324 return b;
309} 325}
310 326
311Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f) 327Bkmk* BkmkFile::read05(BkmkFile* /*_this*/, FILE* f)
312{ 328{
313 Bkmk* b = NULL; 329 Bkmk* b = NULL;
314 if (f != NULL) 330 if (f != NULL)
315 { 331 {
316 unsigned short ln; 332 unsigned short ln;
317 if (fread(&ln,sizeof(ln),1,f) == 1) 333 if (fread(&ln,sizeof(ln),1,f) == 1)
318 { 334 {
319 tchar* nm = new tchar[ln+1]; 335 tchar* nm = new tchar[ln+1];
320 fread(nm,sizeof(tchar),ln,f); 336 fread(nm,sizeof(tchar),ln,f);
321 nm[ln] = 0; 337 nm[ln] = 0;
322 fread(&ln,sizeof(ln),1,f); 338 fread(&ln,sizeof(ln),1,f);
323 tchar* anno = new tchar[ln+1]; 339 tchar* anno = new tchar[ln+1];
324 if (ln > 0) fread(anno,sizeof(tchar),ln,f); 340 if (ln > 0) fread(anno,sizeof(tchar),ln,f);
325 anno[ln] = 0; 341 anno[ln] = 0;
326 unsigned int pos; 342 unsigned int pos;
327 fread(&pos,sizeof(pos),1,f); 343 fread(&pos,sizeof(pos),1,f);
328 b = new Bkmk(nm,anno,pos); 344 b = new Bkmk(nm,anno,pos);
329 } 345 }
330 } 346 }
331 return b; 347 return b;
332} 348}
333 349
334Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f) 350Bkmk* BkmkFile::read06(BkmkFile* /*_this*/, FILE* f)
335{ 351{
336 Bkmk* b = NULL; 352 Bkmk* b = NULL;
337 if (f != NULL) 353 if (f != NULL)
338 { 354 {
339 unsigned short ln; 355 unsigned short ln;
340 if (fread(&ln,sizeof(ln),1,f) == 1) 356 if (fread(&ln,sizeof(ln),1,f) == 1)
341 { 357 {
342 b = new Bkmk; 358 b = new Bkmk;
343 b->m_namelen = ln; 359 b->m_namelen = ln;
344 b->m_name = new unsigned char[b->m_namelen]; 360 b->m_name = new unsigned char[b->m_namelen];
345 fread(b->m_name,1,b->m_namelen,f); 361 fread(b->m_name,1,b->m_namelen,f);
346 362
347 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); 363 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f);
348 if (b->m_annolen > 0) 364 if (b->m_annolen > 0)
349 { 365 {
350 b->m_anno = new unsigned char[b->m_annolen]; 366 b->m_anno = new unsigned char[b->m_annolen];
351 fread(b->m_anno,1,b->m_annolen,f); 367 fread(b->m_anno,1,b->m_annolen,f);
352 } 368 }
353 fread(&(b->m_position),sizeof(b->m_position),1,f); 369 fread(&(b->m_position),sizeof(b->m_position),1,f);
354 b->m_position2 = b->m_position+b->m_namelen-1; 370 b->m_position2 = b->m_position+b->m_namelen-1;
355 b->m_red = b->m_green = b->m_blue = 127; 371 b->m_red = b->m_green = b->m_blue = 127;
356 b->m_level = 0; 372 b->m_level = 0;
357 } 373 }
358 } 374 }
359 return b; 375 return b;
360} 376}
361 377
362Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f) 378Bkmk* BkmkFile::read07(BkmkFile* _this, FILE* f)
363{ 379{
364 Bkmk* b = NULL; 380 Bkmk* b = NULL;
365 if (f != NULL) 381 if (f != NULL)
366 { 382 {
367 unsigned short ln; 383 unsigned short ln;
368 if (fread(&ln,sizeof(ln),1,f) == 1) 384 if (fread(&ln,sizeof(ln),1,f) == 1)
369 { 385 {
370 b = new Bkmk; 386 b = new Bkmk;
371 b->m_namelen = ln; 387 b->m_namelen = ln;
372 b->m_name = new unsigned char[b->m_namelen]; 388 b->m_name = new unsigned char[b->m_namelen];
373 fread(b->m_name,1,b->m_namelen,f); 389 fread(b->m_name,1,b->m_namelen,f);
374 390
375 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f); 391 fread(&(b->m_annolen),sizeof(b->m_annolen),1,f);
376 if (b->m_annolen > 0) 392 if (b->m_annolen > 0)
377 { 393 {
378 b->m_anno = new unsigned char[b->m_annolen]; 394 b->m_anno = new unsigned char[b->m_annolen];
379 fread(b->m_anno,1,b->m_annolen,f); 395 fread(b->m_anno,1,b->m_annolen,f);
380 } 396 }
381 fread(&(b->m_position),sizeof(b->m_position),1,f); 397 fread(&(b->m_position),sizeof(b->m_position),1,f);
382 if (_this->m_extras) 398 if (_this->m_extras)
383 { 399 {
384 fread(&(b->m_position2),sizeof(b->m_position2),1,f); 400 fread(&(b->m_position2),sizeof(b->m_position2),1,f);
385 fread(&(b->m_red),sizeof(b->m_red),1,f); 401 fread(&(b->m_red),sizeof(b->m_red),1,f);
386 fread(&(b->m_green),sizeof(b->m_green),1,f); 402 fread(&(b->m_green),sizeof(b->m_green),1,f);
387 fread(&(b->m_blue),sizeof(b->m_blue),1,f); 403 fread(&(b->m_blue),sizeof(b->m_blue),1,f);
388 fread(&(b->m_level),sizeof(b->m_level),1,f); 404 fread(&(b->m_level),sizeof(b->m_level),1,f);
389 } 405 }
390 else 406 else
391 { 407 {
392 b->m_position2 = b->m_position; 408 b->m_position2 = b->m_position;
393 b->m_red = b->m_green = b->m_blue = 255; 409 b->m_red = b->m_green = b->m_blue = 255;
394 b->m_level = 0; 410 b->m_level = 0;
395 } 411 }
396 } 412 }
397 } 413 }
398 return b; 414 return b;
399} 415}
diff --git a/noncore/apps/opie-reader/Bkmks.h b/noncore/apps/opie-reader/Bkmks.h
index c2275e2..985e158 100644
--- a/noncore/apps/opie-reader/Bkmks.h
+++ b/noncore/apps/opie-reader/Bkmks.h
@@ -1,84 +1,81 @@
1#ifndef __Bkmks_h 1#ifndef __Bkmks_h
2#define __Bkmks_h 2#define __Bkmks_h
3 3
4#include "config.h" 4#include "config.h"
5#include "Filedata.h" 5#include "Filedata.h"
6#include <stdio.h> 6#include <stdio.h>
7 7
8template<class T> 8template<class T>
9class CList; 9class CList;
10 10
11class Bkmk 11class Bkmk
12{ 12{
13 friend class BkmkFile; 13 friend class BkmkFile;
14 unsigned char* m_name; 14 unsigned char* m_name;
15 unsigned short m_namelen; 15 unsigned short m_namelen;
16 unsigned char* m_anno; 16 unsigned char* m_anno;
17 unsigned short m_annolen; 17 unsigned short m_annolen;
18 unsigned int m_position; 18 unsigned int m_position;
19 unsigned int m_position2; 19 unsigned int m_position2;
20 unsigned char m_red,m_green,m_blue, m_level; 20 unsigned char m_red,m_green,m_blue, m_level;
21 void init(const void*, unsigned short, const void*, unsigned short, unsigned int); 21 void init(const void*, unsigned short, const void*, unsigned short, unsigned int);
22 public: 22 public:
23 Bkmk() : m_name(NULL), m_namelen(0), m_anno(NULL), m_annolen(0), m_position(0) {}; 23 Bkmk() : m_name(0), m_namelen(0), m_anno(0), m_annolen(0), m_position(0) {};
24 Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p); 24 Bkmk(const unsigned char* _nm, unsigned short _nmlen, const unsigned char* _anno, unsigned short _annolen, unsigned int _p);
25 Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short _annolen, unsigned int _p); 25 Bkmk(const tchar* _nm, const unsigned char* _anno, unsigned short _annolen, unsigned int _p);
26 Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p); 26 Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p);
27 Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2); 27 Bkmk(const tchar* _nm, const tchar* _anno, unsigned int _p, unsigned int _p2);
28 Bkmk(const Bkmk& rhs) : m_name(NULL), m_anno(NULL) 28 Bkmk(const Bkmk& rhs);
29 {
30 *this = rhs;
31 }
32 ~Bkmk(); 29 ~Bkmk();
33 unsigned int value() const { return m_position; } 30 unsigned int value() const { return m_position; }
34 void value(unsigned int _v) { m_position = _v; } 31 void value(unsigned int _v) { m_position = _v; }
35 unsigned int value2() const { return m_position2; } 32 unsigned int value2() const { return m_position2; }
36 void value2(unsigned int _v) { m_position2 = _v; } 33 void value2(unsigned int _v) { m_position2 = _v; }
37 unsigned char red() { return m_red; } 34 unsigned char red() { return m_red; }
38 unsigned char green() { return m_green; } 35 unsigned char green() { return m_green; }
39 unsigned char blue() { return m_blue; } 36 unsigned char blue() { return m_blue; }
40 void red(unsigned char _v) { m_red = _v; } 37 void red(unsigned char _v) { m_red = _v; }
41 void green(unsigned char _v) { m_green = _v; } 38 void green(unsigned char _v) { m_green = _v; }
42 void blue(unsigned char _v) { m_blue = _v; } 39 void blue(unsigned char _v) { m_blue = _v; }
43 unsigned char level() { return m_level; } 40 unsigned char level() { return m_level; }
44 void level(unsigned char _v) { m_level = _v; } 41 void level(unsigned char _v) { m_level = _v; }
45 tchar *name() const { return (tchar*)m_name; } 42 tchar *name() const { return (tchar*)m_name; }
46 tchar *anno() const { return (tchar*)m_anno; } 43 tchar *anno() const { return (tchar*)m_anno; }
47 bool operator<(const Bkmk& rhs) { return (m_position < rhs.m_position); } 44 bool operator<(const Bkmk& rhs) { return (m_position < rhs.m_position); }
48 Bkmk& operator=(const Bkmk& rhs); 45 Bkmk& operator=(const Bkmk& rhs);
49 bool operator==(const Bkmk& rhs); 46 bool operator==(const Bkmk& rhs);
50 void setAnno(tchar* t); 47 void setAnno(tchar* t);
51 void setAnno(unsigned char* t, unsigned short len); 48 void setAnno(unsigned char* t, unsigned short len);
52 unsigned char* filedata() 49 unsigned char* filedata()
53 { 50 {
54 CFiledata fd(anno()); 51 CFiledata fd(anno());
55 return m_anno+fd.length(); 52 return m_anno+fd.length();
56 } 53 }
57 unsigned short filedatalen() 54 unsigned short filedatalen()
58 { 55 {
59 CFiledata fd(anno()); 56 CFiledata fd(anno());
60 return m_annolen - fd.length(); 57 return m_annolen - fd.length();
61 } 58 }
62}; 59};
63 60
64class BkmkFile 61class BkmkFile
65{ 62{
66 FILE* f; 63 FILE* f;
67 bool wt; 64 bool wt;
68 bool isUpgraded, m_extras; 65 bool isUpgraded, m_extras;
69 static const unsigned long magic; 66 static const unsigned long magic;
70 private: 67 private:
71 static Bkmk* read07(BkmkFile*, FILE*); 68 static Bkmk* read07(BkmkFile*, FILE*);
72 static Bkmk* read06(BkmkFile*, FILE*); 69 static Bkmk* read06(BkmkFile*, FILE*);
73 static Bkmk* read05(BkmkFile*, FILE*); 70 static Bkmk* read05(BkmkFile*, FILE*);
74 static Bkmk* read03(BkmkFile*, FILE*); 71 static Bkmk* read03(BkmkFile*, FILE*);
75 CList<Bkmk>* readall00(Bkmk*(*fn)(BkmkFile*, FILE*)); 72 CList<Bkmk>* readall00(Bkmk*(*fn)(BkmkFile*, FILE*));
76 void write(const Bkmk& b); 73 void write(const Bkmk& b);
77 public: 74 public:
78 bool upgraded() { return isUpgraded; } 75 bool upgraded() { return isUpgraded; }
79 BkmkFile(const char *fnm, bool w, bool _x); 76 BkmkFile(const char *fnm, bool w, bool _x);
80 ~BkmkFile(); 77 ~BkmkFile();
81 void write(CList<Bkmk>& bl); 78 void write(CList<Bkmk>& bl);
82 CList<Bkmk>* readall(); 79 CList<Bkmk>* readall();
83}; 80};
84#endif 81#endif
diff --git a/noncore/apps/opie-reader/StyleConsts.cpp b/noncore/apps/opie-reader/StyleConsts.cpp
index 77c9d3b..c19fa3d 100644
--- a/noncore/apps/opie-reader/StyleConsts.cpp
+++ b/noncore/apps/opie-reader/StyleConsts.cpp
@@ -1,108 +1,115 @@
1 1
2#include <qimage.h> 2#include <qimage.h>
3#include "StyleConsts.h" 3#include "StyleConsts.h"
4 4
5GraphicLink::~GraphicLink() { delete graphic; } 5GraphicLink::~GraphicLink() { delete graphic; }
6 6
7pmstore::pmstore(bool _canScale, QImage* p, bool isLnk, unsigned long tgt) :
8 count(1),
9 m_isScaleable(_canScale)
10{
11 graphic = new GraphicLink(p, isLnk, tgt);
12}
13
7pmstore::~pmstore() 14pmstore::~pmstore()
8{ 15{
9//// qDebug("Deleting image"); 16//// qDebug("Deleting image");
10 delete graphic; 17 delete graphic;
11} 18}
12 19
13CStyle::~CStyle() 20CStyle::~CStyle()
14{ 21{
15 if (graphic != NULL) 22 if (graphic != NULL)
16 { 23 {
17 if (--(graphic->count) == 0) 24 if (--(graphic->count) == 0)
18 { 25 {
19 delete graphic; 26 delete graphic;
20 } 27 }
21 } 28 }
22} 29}
23 30
24CStyle::CStyle(const CStyle& rhs) : graphic(NULL) 31CStyle::CStyle(const CStyle& rhs) : graphic(NULL)
25{ 32{
26 *this = rhs; 33 *this = rhs;
27} 34}
28 35
29CStyle& CStyle::operator=(const CStyle& rhs) 36CStyle& CStyle::operator=(const CStyle& rhs)
30{ 37{
31 if (rhs.graphic != NULL) 38 if (rhs.graphic != NULL)
32 { 39 {
33 (rhs.graphic->count)++; 40 (rhs.graphic->count)++;
34 if (graphic != NULL) 41 if (graphic != NULL)
35 { 42 {
36 if (--(graphic->count) == 0) 43 if (--(graphic->count) == 0)
37 { 44 {
38 delete graphic; 45 delete graphic;
39 } 46 }
40 } 47 }
41 graphic = rhs.graphic; 48 graphic = rhs.graphic;
42 } 49 }
43 else 50 else
44 { 51 {
45 if (graphic != NULL) 52 if (graphic != NULL)
46 { 53 {
47 if (--(graphic->count) == 0) 54 if (--(graphic->count) == 0)
48 { 55 {
49 delete graphic; 56 delete graphic;
50 } 57 }
51 graphic = NULL; 58 graphic = NULL;
52 } 59 }
53 } 60 }
54 sty = rhs.sty; 61 sty = rhs.sty;
55 return *this; 62 return *this;
56} 63}
57 64
58void CStyle::clearPicture() 65void CStyle::clearPicture()
59{ 66{
60 if (graphic != NULL) 67 if (graphic != NULL)
61 { 68 {
62 if (--(graphic->count) == 0) 69 if (--(graphic->count) == 0)
63 { 70 {
64 delete graphic; 71 delete graphic;
65 } 72 }
66 graphic = NULL; 73 graphic = NULL;
67 } 74 }
68} 75}
69 76
70void CStyle::unset() 77void CStyle::unset()
71{ 78{
72 sty.unset(); 79 sty.unset();
73 if (graphic != NULL) 80 if (graphic != NULL)
74 { 81 {
75 if (--(graphic->count) == 0) 82 if (--(graphic->count) == 0)
76 { 83 {
77 delete graphic; 84 delete graphic;
78 } 85 }
79 graphic = NULL; 86 graphic = NULL;
80 } 87 }
81} 88}
82 89
83void CStyle::setPicture(bool canScale, QImage* _g, bool il, unsigned long tgt) 90void CStyle::setPicture(bool canScale, QImage* _g, bool il, unsigned long tgt)
84{ 91{
85 if (graphic != NULL) 92 if (graphic != NULL)
86 { 93 {
87 if (--(graphic->count) == 0) 94 if (--(graphic->count) == 0)
88 { 95 {
89 delete graphic; 96 delete graphic;
90 } 97 }
91 graphic = NULL; 98 graphic = NULL;
92 } 99 }
93 if (_g != NULL) graphic = new pmstore(canScale, _g, il, tgt); 100 if (_g != NULL) graphic = new pmstore(canScale, _g, il, tgt);
94} 101}
95 102
96void CStyle::invert() 103void CStyle::invert()
97{ 104{
98 qDebug("Before:<%02x%02x%02x>", sty.bred, sty.bgreen, sty.bblue); 105 qDebug("Before:<%02x%02x%02x>", sty.bred, sty.bgreen, sty.bblue);
99 qDebug("Before:<%02x%02x%02x>", sty.red, sty.green, sty.blue); 106 qDebug("Before:<%02x%02x%02x>", sty.red, sty.green, sty.blue);
100 sty.bred = 255-sty.bred; 107 sty.bred = 255-sty.bred;
101 sty.bgreen = 255-sty.bgreen; 108 sty.bgreen = 255-sty.bgreen;
102 sty.bblue = 255-sty.bblue; 109 sty.bblue = 255-sty.bblue;
103 sty.red = 255-sty.red; 110 sty.red = 255-sty.red;
104 sty.green = 255-sty.green; 111 sty.green = 255-sty.green;
105 sty.blue = 255-sty.blue; 112 sty.blue = 255-sty.blue;
106 qDebug("After:<%02x%02x%02x>", sty.bred, sty.bgreen, sty.bblue); 113 qDebug("After:<%02x%02x%02x>", sty.bred, sty.bgreen, sty.bblue);
107 qDebug("After:<%02x%02x%02x>", sty.red, sty.green, sty.blue); 114 qDebug("After:<%02x%02x%02x>", sty.red, sty.green, sty.blue);
108} 115}
diff --git a/noncore/apps/opie-reader/StyleConsts.h b/noncore/apps/opie-reader/StyleConsts.h
index 4b7ff4b..5fd9669 100644
--- a/noncore/apps/opie-reader/StyleConsts.h
+++ b/noncore/apps/opie-reader/StyleConsts.h
@@ -1,232 +1,230 @@
1#ifndef __STYLECONSTS_H 1#ifndef __STYLECONSTS_H
2#define __STYLECONSTS_H 2#define __STYLECONSTS_H
3 3
4typedef unsigned short StyleType; 4typedef unsigned short StyleType;
5 5
6#ifdef _WINDOWS 6#ifdef _WINDOWS
7#include <string.h> 7#include <string.h>
8#endif 8#endif
9#include <string.h> 9#include <string.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <qglobal.h> 11#include <qglobal.h>
12class QImage; 12class QImage;
13 13
14struct GraphicLink 14struct GraphicLink
15{ 15{
16 QImage* graphic; 16 QImage* graphic;
17 bool isLink; 17 bool isLink;
18 unsigned long link; 18 unsigned long link;
19 GraphicLink(QImage* p, bool isLnk, unsigned long tgt) : 19 GraphicLink(QImage* p, bool isLnk, unsigned long tgt) :
20 graphic(p), isLink(isLnk), link(tgt) {} 20 graphic(p), isLink(isLnk), link(tgt) {}
21 ~GraphicLink(); 21 ~GraphicLink();
22}; 22};
23 23
24struct pmstore 24class pmstore
25{ 25{
26 public:
26 unsigned int count; 27 unsigned int count;
27 bool m_isScaleable; 28 bool m_isScaleable;
28 GraphicLink* graphic; 29 GraphicLink* graphic;
29 pmstore(bool _canScale, QImage* p, bool isLnk, unsigned long tgt) : count(1), m_isScaleable(_canScale) 30 pmstore(bool _canScale, QImage* p, bool isLnk, unsigned long tgt);
30 {
31 graphic = new GraphicLink(p, isLnk, tgt);
32 }
33 ~pmstore(); 31 ~pmstore();
34}; 32};
35 33
36enum EalignmentType 34enum EalignmentType
37{ 35{
38 m_AlignLeft, 36 m_AlignLeft,
39 m_AlignRight, 37 m_AlignRight,
40 m_AlignCentre, 38 m_AlignCentre,
41 m_AlignJustify, 39 m_AlignJustify,
42 m_AlignNone 40 m_AlignNone
43}; 41};
44 42
45class CBasicStyle 43class CBasicStyle
46{ 44{
47 friend class CStyle; 45 friend class CStyle;
48 bool m_bold, 46 bool m_bold,
49 m_italic; 47 m_italic;
50 unsigned long m_table; 48 unsigned long m_table;
51 int m_fontsize; 49 int m_fontsize;
52 EalignmentType m_align; 50 EalignmentType m_align;
53 unsigned char red, green, blue; 51 unsigned char red, green, blue;
54 unsigned char bred, bgreen, bblue; 52 unsigned char bred, bgreen, bblue;
55 unsigned char pred, pgreen, pblue; 53 unsigned char pred, pgreen, pblue;
56 unsigned long data; 54 unsigned long data;
57 unsigned long offset; 55 unsigned long offset;
58 bool isLink; 56 bool isLink;
59 // bool isVisited; 57 // bool isVisited;
60 bool m_underline; 58 bool m_underline;
61 bool m_strikethru; 59 bool m_strikethru;
62 bool m_monospaced; 60 bool m_monospaced;
63 unsigned char m_leftmargin, m_rightmargin; 61 unsigned char m_leftmargin, m_rightmargin;
64 signed char m_extraspace; 62 signed char m_extraspace;
65 signed char m_voffset; 63 signed char m_voffset;
66 CBasicStyle() 64 CBasicStyle()
67 { 65 {
68 unset(); 66 unset();
69 m_table = 0xffffffff; 67 m_table = 0xffffffff;
70 } 68 }
71 bool operator!=(const CBasicStyle& rhs) 69 bool operator!=(const CBasicStyle& rhs)
72 { 70 {
73 return (memcmp(this, &rhs, sizeof(CBasicStyle)) != 0); 71 return (memcmp(this, &rhs, sizeof(CBasicStyle)) != 0);
74 } 72 }
75 void unset() 73 void unset()
76 { 74 {
77 m_bold = false; 75 m_bold = false;
78 m_italic = false; 76 m_italic = false;
79 m_fontsize = 0; 77 m_fontsize = 0;
80 m_align = m_AlignLeft; 78 m_align = m_AlignLeft;
81 red = green = blue = 0; 79 red = green = blue = 0;
82 bred = bgreen = bblue = 255; 80 bred = bgreen = bblue = 255;
83 pred = pgreen = pblue = 255; 81 pred = pgreen = pblue = 255;
84 data = 0; 82 data = 0;
85 offset = 0; 83 offset = 0;
86 isLink = false; 84 isLink = false;
87 // isVisited = false; 85 // isVisited = false;
88 m_underline = false; 86 m_underline = false;
89 m_strikethru = false; 87 m_strikethru = false;
90 m_leftmargin = 0; 88 m_leftmargin = 0;
91 m_rightmargin = 0; 89 m_rightmargin = 0;
92 m_monospaced = false; 90 m_monospaced = false;
93 m_extraspace = 0; 91 m_extraspace = 0;
94 m_voffset = 0; 92 m_voffset = 0;
95 } 93 }
96}; 94};
97 95
98class CStyle 96class CStyle
99{ 97{
100 CBasicStyle sty; 98 CBasicStyle sty;
101 pmstore* graphic; 99 pmstore* graphic;
102 public: 100 public:
103 signed char getVOffset() { return sty.m_voffset; } 101 signed char getVOffset() { return sty.m_voffset; }
104 void setVOffset(signed char sp) { sty.m_voffset = sp; } 102 void setVOffset(signed char sp) { sty.m_voffset = sp; }
105 signed char getExtraSpace() { return sty.m_extraspace; } 103 signed char getExtraSpace() { return sty.m_extraspace; }
106 void setExtraSpace(signed char sp) { sty.m_extraspace = sp; } 104 void setExtraSpace(signed char sp) { sty.m_extraspace = sp; }
107 bool getPictureLink() 105 bool getPictureLink()
108 { 106 {
109 return (graphic != NULL && graphic->graphic->isLink); 107 return (graphic != NULL && graphic->graphic->isLink);
110 } 108 }
111 unsigned long getPictureLinkData() 109 unsigned long getPictureLinkData()
112 { 110 {
113 return graphic->graphic->link; 111 return graphic->graphic->link;
114 } 112 }
115 void setLeftMargin(unsigned char m) { sty.m_leftmargin = m; } 113 void setLeftMargin(unsigned char m) { sty.m_leftmargin = m; }
116 unsigned char getLeftMargin() { return sty.m_leftmargin; } 114 unsigned char getLeftMargin() { return sty.m_leftmargin; }
117 void setRightMargin(unsigned char m) { sty.m_rightmargin = m; } 115 void setRightMargin(unsigned char m) { sty.m_rightmargin = m; }
118 unsigned char getRightMargin() { return sty.m_rightmargin; } 116 unsigned char getRightMargin() { return sty.m_rightmargin; }
119 unsigned char Red() { return sty.red; } 117 unsigned char Red() { return sty.red; }
120 unsigned char Green() { return sty.green; } 118 unsigned char Green() { return sty.green; }
121 unsigned char Blue() { return sty.blue; } 119 unsigned char Blue() { return sty.blue; }
122 void setColour(unsigned char r, unsigned char g, unsigned char b) 120 void setColour(unsigned char r, unsigned char g, unsigned char b)
123 { 121 {
124 sty.red = r; 122 sty.red = r;
125 sty.green = g; 123 sty.green = g;
126 sty.blue = b; 124 sty.blue = b;
127 } 125 }
128 unsigned char bRed() { return sty.bred; } 126 unsigned char bRed() { return sty.bred; }
129 unsigned char bGreen() { return sty.bgreen; } 127 unsigned char bGreen() { return sty.bgreen; }
130 unsigned char bBlue() { return sty.bblue; } 128 unsigned char bBlue() { return sty.bblue; }
131 unsigned char pRed() { return sty.pred; } 129 unsigned char pRed() { return sty.pred; }
132 unsigned char pGreen() { return sty.pgreen; } 130 unsigned char pGreen() { return sty.pgreen; }
133 unsigned char pBlue() { return sty.pblue; } 131 unsigned char pBlue() { return sty.pblue; }
134 void setPaper(unsigned char r, unsigned char g, unsigned char b) 132 void setPaper(unsigned char r, unsigned char g, unsigned char b)
135 { 133 {
136 sty.pred = r; 134 sty.pred = r;
137 sty.pgreen = g; 135 sty.pgreen = g;
138 sty.pblue = b; 136 sty.pblue = b;
139 } 137 }
140 void setBackground(unsigned char r, unsigned char g, unsigned char b) 138 void setBackground(unsigned char r, unsigned char g, unsigned char b)
141 { 139 {
142 sty.bred = r; 140 sty.bred = r;
143 sty.bgreen = g; 141 sty.bgreen = g;
144 sty.bblue = b; 142 sty.bblue = b;
145 } 143 }
146 CStyle() : graphic(NULL) {} 144 CStyle() : graphic(NULL) {}
147 ~CStyle(); 145 ~CStyle();
148// CStyle(CStyle&); 146// CStyle(CStyle&);
149 CStyle(const CStyle&); 147 CStyle(const CStyle&);
150 CStyle& operator=(const CStyle&); 148 CStyle& operator=(const CStyle&);
151 void unset(); 149 void unset();
152 bool isTable() const { return (sty.m_table != 0xffffffff); } 150 bool isTable() const { return (sty.m_table != 0xffffffff); }
153 void setTable(unsigned long _b) { sty.m_table = _b; } 151 void setTable(unsigned long _b) { sty.m_table = _b; }
154 unsigned long getTable() { return sty.m_table; } 152 unsigned long getTable() { return sty.m_table; }
155 bool isPicture() const { return (graphic != NULL); } 153 bool isPicture() const { return (graphic != NULL); }
156 bool canScale() const { return graphic->m_isScaleable; } 154 bool canScale() const { return graphic->m_isScaleable; }
157 void clearPicture(); 155 void clearPicture();
158 void setPicture(bool canScale, QImage* _g, bool il=false, unsigned long tgt=0); 156 void setPicture(bool canScale, QImage* _g, bool il=false, unsigned long tgt=0);
159 QImage* getPicture() 157 QImage* getPicture()
160 { 158 {
161 QImage* pm = ((graphic != NULL) ? graphic->graphic->graphic : NULL); 159 QImage* pm = ((graphic != NULL) ? graphic->graphic->graphic : NULL);
162 return pm; 160 return pm;
163 } 161 }
164 void setUnderline() { sty.m_underline = true; } 162 void setUnderline() { sty.m_underline = true; }
165 void unsetUnderline() { sty.m_underline = false; } 163 void unsetUnderline() { sty.m_underline = false; }
166 bool isUnderline() { return sty.m_underline; } 164 bool isUnderline() { return sty.m_underline; }
167 void setStrikethru() { sty.m_strikethru = true; } 165 void setStrikethru() { sty.m_strikethru = true; }
168 void unsetStrikethru() { sty.m_strikethru = false; } 166 void unsetStrikethru() { sty.m_strikethru = false; }
169 bool isStrikethru() { return sty.m_strikethru; } 167 bool isStrikethru() { return sty.m_strikethru; }
170 void setBold() { sty.m_bold = true; } 168 void setBold() { sty.m_bold = true; }
171 void unsetBold() { sty.m_bold = false; } 169 void unsetBold() { sty.m_bold = false; }
172 bool isBold() { return sty.m_bold; } 170 bool isBold() { return sty.m_bold; }
173 void setItalic() { sty.m_italic = true; } 171 void setItalic() { sty.m_italic = true; }
174 void unsetItalic() { sty.m_italic = false; } 172 void unsetItalic() { sty.m_italic = false; }
175 bool isItalic() { return sty.m_italic; } 173 bool isItalic() { return sty.m_italic; }
176 void setMono() { sty.m_monospaced = true; } 174 void setMono() { sty.m_monospaced = true; }
177 void unsetMono() { sty.m_monospaced = false; } 175 void unsetMono() { sty.m_monospaced = false; }
178 bool isMono() { return sty.m_monospaced; } 176 bool isMono() { return sty.m_monospaced; }
179 177
180 void setLeftJustify() 178 void setLeftJustify()
181 { 179 {
182 sty.m_align = m_AlignLeft; 180 sty.m_align = m_AlignLeft;
183 } 181 }
184 void setRightJustify() 182 void setRightJustify()
185 { 183 {
186 sty.m_align = m_AlignRight; 184 sty.m_align = m_AlignRight;
187 } 185 }
188 void setCentreJustify() 186 void setCentreJustify()
189 { 187 {
190 sty.m_align = m_AlignCentre; 188 sty.m_align = m_AlignCentre;
191 } 189 }
192 void setFullJustify() 190 void setFullJustify()
193 { 191 {
194 sty.m_align = m_AlignJustify; 192 sty.m_align = m_AlignJustify;
195 } 193 }
196 void setNoJustify() 194 void setNoJustify()
197 { 195 {
198 sty.m_align = m_AlignNone; 196 sty.m_align = m_AlignNone;
199 } 197 }
200 StyleType getJustify() 198 StyleType getJustify()
201 { 199 {
202 return sty.m_align; 200 return sty.m_align;
203 } 201 }
204 202
205 void setFontSize(int _fs) 203 void setFontSize(int _fs)
206 { 204 {
207 sty.m_fontsize = _fs; 205 sty.m_fontsize = _fs;
208 } 206 }
209 int getFontSize() const 207 int getFontSize() const
210 { 208 {
211 return sty.m_fontsize; 209 return sty.m_fontsize;
212 } 210 }
213 bool operator!=(const CStyle& rhs) 211 bool operator!=(const CStyle& rhs)
214 { 212 {
215 return 213 return
216 ( 214 (
217 (sty != rhs.sty) || 215 (sty != rhs.sty) ||
218 (graphic != rhs.graphic) 216 (graphic != rhs.graphic)
219 ); 217 );
220 } 218 }
221 void setLink(bool _l) { sty.isLink = _l; } 219 void setLink(bool _l) { sty.isLink = _l; }
222 bool getLink() { return sty.isLink; } 220 bool getLink() { return sty.isLink; }
223 // void setVisited(bool _l) { sty.isVisited = _l; } 221 // void setVisited(bool _l) { sty.isVisited = _l; }
224 // bool getVisited() { return sty.isVisited; } 222 // bool getVisited() { return sty.isVisited; }
225 void setData(unsigned long _d) { sty.data = _d; } 223 void setData(unsigned long _d) { sty.data = _d; }
226 unsigned long getData() { return sty.data; } 224 unsigned long getData() { return sty.data; }
227 void setOffset(unsigned long _d) { sty.offset = _d; } 225 void setOffset(unsigned long _d) { sty.offset = _d; }
228 unsigned long getOffset() { return sty.offset; } 226 unsigned long getOffset() { return sty.offset; }
229 void invert(); 227 void invert();
230}; 228};
231 229
232#endif 230#endif
diff --git a/noncore/apps/opie-write/qrichtext.cpp b/noncore/apps/opie-write/qrichtext.cpp
index c27eb1e..f040f1e 100644
--- a/noncore/apps/opie-write/qrichtext.cpp
+++ b/noncore/apps/opie-write/qrichtext.cpp
@@ -1967,5869 +1967,5868 @@ void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheet
1967 mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) ); 1967 mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
1968 m = QMAX( m, mar ); 1968 m = QMAX( m, mar );
1969 } 1969 }
1970 stylesPar->ubm = m - stylesPar->bottomMargin(); 1970 stylesPar->ubm = m - stylesPar->bottomMargin();
1971 1971
1972 // do the left margin, simplyfied 1972 // do the left margin, simplyfied
1973 item = mainStyle; 1973 item = mainStyle;
1974 if (stylesPar->ulm > 0 ) { 1974 if (stylesPar->ulm > 0 ) {
1975 m = stylesPar->ulm-1; 1975 m = stylesPar->ulm-1;
1976 stylesPar->ulm = 0; 1976 stylesPar->ulm = 0;
1977 } else { 1977 } else {
1978 m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); 1978 m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
1979 } 1979 }
1980 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 1980 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1981 item = (*curStyle)[ i ]; 1981 item = (*curStyle)[ i ];
1982 m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) ); 1982 m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
1983 } 1983 }
1984 stylesPar->ulm = m - stylesPar->leftMargin(); 1984 stylesPar->ulm = m - stylesPar->leftMargin();
1985 1985
1986 // do the right margin, simplyfied 1986 // do the right margin, simplyfied
1987 item = mainStyle; 1987 item = mainStyle;
1988 if (stylesPar->urm > 0 ) { 1988 if (stylesPar->urm > 0 ) {
1989 m = stylesPar->urm-1; 1989 m = stylesPar->urm-1;
1990 stylesPar->urm = 0; 1990 stylesPar->urm = 0;
1991 } else { 1991 } else {
1992 m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); 1992 m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
1993 } 1993 }
1994 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 1994 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
1995 item = (*curStyle)[ i ]; 1995 item = (*curStyle)[ i ];
1996 m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) ); 1996 m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
1997 } 1997 }
1998 stylesPar->urm = m - stylesPar->rightMargin(); 1998 stylesPar->urm = m - stylesPar->rightMargin();
1999 1999
2000 // do the first line margin, which really should be called text-indent 2000 // do the first line margin, which really should be called text-indent
2001 item = mainStyle; 2001 item = mainStyle;
2002 if (stylesPar->uflm > 0 ) { 2002 if (stylesPar->uflm > 0 ) {
2003 m = stylesPar->uflm-1; 2003 m = stylesPar->uflm-1;
2004 stylesPar->uflm = 0; 2004 stylesPar->uflm = 0;
2005 } else { 2005 } else {
2006 m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); 2006 m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) );
2007 } 2007 }
2008 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) { 2008 for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
2009 item = (*curStyle)[ i ]; 2009 item = (*curStyle)[ i ];
2010 mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) ); 2010 mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) );
2011 m = QMAX( m, mar ); 2011 m = QMAX( m, mar );
2012 } 2012 }
2013 stylesPar->uflm =m - stylesPar->firstLineMargin(); 2013 stylesPar->uflm =m - stylesPar->firstLineMargin();
2014 2014
2015 // do the bogus line "spacing", which really is just an extra margin 2015 // do the bogus line "spacing", which really is just an extra margin
2016 item = mainStyle; 2016 item = mainStyle;
2017 for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) { 2017 for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) {
2018 item = (*curStyle)[ i ]; 2018 item = (*curStyle)[ i ];
2019 if ( item->lineSpacing() != QStyleSheetItem::Undefined ) { 2019 if ( item->lineSpacing() != QStyleSheetItem::Undefined ) {
2020 stylesPar->ulinespacing = item->lineSpacing(); 2020 stylesPar->ulinespacing = item->lineSpacing();
2021 if ( formatCollection() && 2021 if ( formatCollection() &&
2022 stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() ) 2022 stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() )
2023 stylesPar->ulinespacing += formatCollection()->defaultFormat()->height(); 2023 stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
2024 break; 2024 break;
2025 } 2025 }
2026 } 2026 }
2027 2027
2028 stylesPar = stylesPar->next(); 2028 stylesPar = stylesPar->next();
2029 prevStyle = curStyle; 2029 prevStyle = curStyle;
2030 curStyle = nextStyle; 2030 curStyle = nextStyle;
2031 nextStyle = styles.next(); 2031 nextStyle = styles.next();
2032 } 2032 }
2033} 2033}
2034 2034
2035void QTextDocument::setText( const QString &text, const QString &context ) 2035void QTextDocument::setText( const QString &text, const QString &context )
2036{ 2036{
2037 focusIndicator.parag = 0; 2037 focusIndicator.parag = 0;
2038 selections.clear(); 2038 selections.clear();
2039 if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) || 2039 if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) ||
2040 txtFormat == Qt::RichText ) 2040 txtFormat == Qt::RichText )
2041 setRichText( text, context ); 2041 setRichText( text, context );
2042 else 2042 else
2043 setPlainText( text ); 2043 setPlainText( text );
2044} 2044}
2045 2045
2046QString QTextDocument::plainText() const 2046QString QTextDocument::plainText() const
2047{ 2047{
2048 QString buffer; 2048 QString buffer;
2049 QString s; 2049 QString s;
2050 QTextParagraph *p = fParag; 2050 QTextParagraph *p = fParag;
2051 while ( p ) { 2051 while ( p ) {
2052 if ( !p->mightHaveCustomItems ) { 2052 if ( !p->mightHaveCustomItems ) {
2053 s = p->string()->toString(); 2053 s = p->string()->toString();
2054 } else { 2054 } else {
2055 for ( int i = 0; i < p->length() - 1; ++i ) { 2055 for ( int i = 0; i < p->length() - 1; ++i ) {
2056 if ( p->at( i )->isCustom() ) { 2056 if ( p->at( i )->isCustom() ) {
2057 if ( p->at( i )->customItem()->isNested() ) { 2057 if ( p->at( i )->customItem()->isNested() ) {
2058 s += "\n"; 2058 s += "\n";
2059 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 2059 QTextTable *t = (QTextTable*)p->at( i )->customItem();
2060 QPtrList<QTextTableCell> cells = t->tableCells(); 2060 QPtrList<QTextTableCell> cells = t->tableCells();
2061 for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) 2061 for ( QTextTableCell *c = cells.first(); c; c = cells.next() )
2062 s += c->richText()->plainText() + "\n"; 2062 s += c->richText()->plainText() + "\n";
2063 s += "\n"; 2063 s += "\n";
2064 } 2064 }
2065 } else { 2065 } else {
2066 s += p->at( i )->c; 2066 s += p->at( i )->c;
2067 } 2067 }
2068 } 2068 }
2069 } 2069 }
2070 s.remove( s.length() - 1, 1 ); 2070 s.remove( s.length() - 1, 1 );
2071 if ( p->next() ) 2071 if ( p->next() )
2072 s += "\n"; 2072 s += "\n";
2073 buffer += s; 2073 buffer += s;
2074 p = p->next(); 2074 p = p->next();
2075 } 2075 }
2076 return buffer; 2076 return buffer;
2077} 2077}
2078 2078
2079static QString align_to_string( int a ) 2079static QString align_to_string( int a )
2080{ 2080{
2081 if ( a & Qt::AlignRight ) 2081 if ( a & Qt::AlignRight )
2082 return " align=\"right\""; 2082 return " align=\"right\"";
2083 if ( a & Qt::AlignHCenter ) 2083 if ( a & Qt::AlignHCenter )
2084 return " align=\"center\""; 2084 return " align=\"center\"";
2085 if ( a & Qt3::AlignJustify ) 2085 if ( a & Qt3::AlignJustify )
2086 return " align=\"justify\""; 2086 return " align=\"justify\"";
2087 return QString::null; 2087 return QString::null;
2088} 2088}
2089 2089
2090static QString direction_to_string( int d ) 2090static QString direction_to_string( int d )
2091{ 2091{
2092 if ( d != QChar::DirON ) 2092 if ( d != QChar::DirON )
2093 return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" ); 2093 return ( d == QChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" );
2094 return QString::null; 2094 return QString::null;
2095} 2095}
2096 2096
2097static QString list_value_to_string( int v ) 2097static QString list_value_to_string( int v )
2098{ 2098{
2099 if ( v != -1 ) 2099 if ( v != -1 )
2100 return " listvalue=\"" + QString::number( v ) + "\""; 2100 return " listvalue=\"" + QString::number( v ) + "\"";
2101 return QString::null; 2101 return QString::null;
2102} 2102}
2103 2103
2104static QString list_style_to_string( int v ) 2104static QString list_style_to_string( int v )
2105{ 2105{
2106 switch( v ) { 2106 switch( v ) {
2107 case QStyleSheetItem::ListDecimal: return "\"1\""; 2107 case QStyleSheetItem::ListDecimal: return "\"1\"";
2108 case QStyleSheetItem::ListLowerAlpha: return "\"a\""; 2108 case QStyleSheetItem::ListLowerAlpha: return "\"a\"";
2109 case QStyleSheetItem::ListUpperAlpha: return "\"A\""; 2109 case QStyleSheetItem::ListUpperAlpha: return "\"A\"";
2110 case QStyleSheetItem::ListDisc: return "\"disc\""; 2110 case QStyleSheetItem::ListDisc: return "\"disc\"";
2111 case QStyleSheetItem::ListSquare: return "\"square\""; 2111 case QStyleSheetItem::ListSquare: return "\"square\"";
2112 case QStyleSheetItem::ListCircle: return "\"circle\""; 2112 case QStyleSheetItem::ListCircle: return "\"circle\"";
2113 default: 2113 default:
2114 return QString::null; 2114 return QString::null;
2115 } 2115 }
2116} 2116}
2117 2117
2118static inline bool list_is_ordered( int v ) 2118static inline bool list_is_ordered( int v )
2119{ 2119{
2120 return v == QStyleSheetItem::ListDecimal || 2120 return v == QStyleSheetItem::ListDecimal ||
2121 v == QStyleSheetItem::ListLowerAlpha || 2121 v == QStyleSheetItem::ListLowerAlpha ||
2122 v == QStyleSheetItem::ListUpperAlpha; 2122 v == QStyleSheetItem::ListUpperAlpha;
2123} 2123}
2124 2124
2125 2125
2126static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl ) 2126static QString margin_to_string( QStyleSheetItem* style, int t, int b, int l, int r, int fl )
2127{ 2127{
2128 QString s; 2128 QString s;
2129 if ( l > 0 ) 2129 if ( l > 0 )
2130 s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px"; 2130 s += QString(!!s?";":"") + "margin-left:" + QString::number(l+QMAX(0,style->margin(QStyleSheetItem::MarginLeft))) + "px";
2131 if ( r > 0 ) 2131 if ( r > 0 )
2132 s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px"; 2132 s += QString(!!s?";":"") + "margin-right:" + QString::number(r+QMAX(0,style->margin(QStyleSheetItem::MarginRight))) + "px";
2133 if ( t > 0 ) 2133 if ( t > 0 )
2134 s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px"; 2134 s += QString(!!s?";":"") + "margin-top:" + QString::number(t+QMAX(0,style->margin(QStyleSheetItem::MarginTop))) + "px";
2135 if ( b > 0 ) 2135 if ( b > 0 )
2136 s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px"; 2136 s += QString(!!s?";":"") + "margin-bottom:" + QString::number(b+QMAX(0,style->margin(QStyleSheetItem::MarginBottom))) + "px";
2137 if ( fl > 0 ) 2137 if ( fl > 0 )
2138 s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px"; 2138 s += QString(!!s?";":"") + "text-indent:" + QString::number(fl+QMAX(0,style->margin(QStyleSheetItem::MarginFirstLine))) + "px";
2139 if ( !!s ) 2139 if ( !!s )
2140 return " style=\"" + s + "\""; 2140 return " style=\"" + s + "\"";
2141 return QString::null; 2141 return QString::null;
2142} 2142}
2143 2143
2144QString QTextDocument::richText() const 2144QString QTextDocument::richText() const
2145{ 2145{
2146 QString s = ""; 2146 QString s = "";
2147 if ( !par ) { 2147 if ( !par ) {
2148 s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ; 2148 s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ;
2149 s += QString::number( formatCollection()->defaultFormat()->font().pointSize() ); 2149 s += QString::number( formatCollection()->defaultFormat()->font().pointSize() );
2150 s += "pt;font-family:"; 2150 s += "pt;font-family:";
2151 s += formatCollection()->defaultFormat()->font().family(); 2151 s += formatCollection()->defaultFormat()->font().family();
2152 s +="\">"; 2152 s +="\">";
2153 } 2153 }
2154 QTextParagraph* p = fParag; 2154 QTextParagraph* p = fParag;
2155 2155
2156 QStyleSheetItem* item_p = styleSheet()->item("p"); 2156 QStyleSheetItem* item_p = styleSheet()->item("p");
2157 QStyleSheetItem* item_ul = styleSheet()->item("ul"); 2157 QStyleSheetItem* item_ul = styleSheet()->item("ul");
2158 QStyleSheetItem* item_ol = styleSheet()->item("ol"); 2158 QStyleSheetItem* item_ol = styleSheet()->item("ol");
2159 QStyleSheetItem* item_li = styleSheet()->item("li"); 2159 QStyleSheetItem* item_li = styleSheet()->item("li");
2160 if ( !item_p || !item_ul || !item_ol || !item_li ) { 2160 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; 2161 owarn << "QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, ul, ol, or li)" << oendl;
2162 return QString::null; 2162 return QString::null;
2163 } 2163 }
2164 int pastListDepth = 0; 2164 int pastListDepth = 0;
2165 int listDepth = 0; 2165 int listDepth = 0;
2166 int futureListDepth = 0; 2166 int futureListDepth = 0;
2167 QMemArray<int> listStyles(10); 2167 QMemArray<int> listStyles(10);
2168 2168
2169 while ( p ) { 2169 while ( p ) {
2170 listDepth = p->listDepth(); 2170 listDepth = p->listDepth();
2171 if ( listDepth < pastListDepth ) { 2171 if ( listDepth < pastListDepth ) {
2172 for ( int i = listDepth+1; i <= pastListDepth; i++ ) 2172 for ( int i = listDepth+1; i <= pastListDepth; i++ )
2173 s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>"; 2173 s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>";
2174 s += '\n'; 2174 s += '\n';
2175 } else if ( listDepth > pastListDepth ) { 2175 } else if ( listDepth > pastListDepth ) {
2176 s += '\n'; 2176 s += '\n';
2177 listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) ); 2177 listStyles.resize( QMAX( (int)listStyles.size(), listDepth+1 ) );
2178 QString list_type; 2178 QString list_type;
2179 listStyles[listDepth] = p->listStyle(); 2179 listStyles[listDepth] = p->listStyle();
2180 if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() ) 2180 if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() )
2181 list_type = " type=" + list_style_to_string( p->listStyle() ); 2181 list_type = " type=" + list_style_to_string( p->listStyle() );
2182 for ( int i = pastListDepth; i < listDepth; i++ ) { 2182 for ( int i = pastListDepth; i < listDepth; i++ ) {
2183 s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ; 2183 s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ;
2184 s += list_type + ">"; 2184 s += list_type + ">";
2185 } 2185 }
2186 } else { 2186 } else {
2187 s += '\n'; 2187 s += '\n';
2188 } 2188 }
2189 2189
2190 QString ps = p->richText(); 2190 QString ps = p->richText();
2191 2191
2192 // for the bottom margin we need to know whether we are at the end of a list 2192 // for the bottom margin we need to know whether we are at the end of a list
2193 futureListDepth = 0; 2193 futureListDepth = 0;
2194 if ( listDepth > 0 && p->next() ) 2194 if ( listDepth > 0 && p->next() )
2195 futureListDepth = p->next()->listDepth(); 2195 futureListDepth = p->next()->listDepth();
2196 2196
2197 if ( richTextExportStart && richTextExportStart->paragraph() ==p && 2197 if ( richTextExportStart && richTextExportStart->paragraph() ==p &&
2198 richTextExportStart->index() == 0 ) 2198 richTextExportStart->index() == 0 )
2199 s += "<selstart/>"; 2199 s += "<selstart/>";
2200 2200
2201 if ( p->isListItem() ) { 2201 if ( p->isListItem() ) {
2202 s += "<li"; 2202 s += "<li";
2203 if ( p->listStyle() != listStyles[listDepth] ) 2203 if ( p->listStyle() != listStyles[listDepth] )
2204 s += " type=" + list_style_to_string( p->listStyle() ); 2204 s += " type=" + list_style_to_string( p->listStyle() );
2205 s +=align_to_string( p->alignment() ); 2205 s +=align_to_string( p->alignment() );
2206 s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); 2206 s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
2207 s += list_value_to_string( p->listValue() ); 2207 s += list_value_to_string( p->listValue() );
2208 s += direction_to_string( p->direction() ); 2208 s += direction_to_string( p->direction() );
2209 s +=">"; 2209 s +=">";
2210 s += ps; 2210 s += ps;
2211 s += "</li>"; 2211 s += "</li>";
2212 } else { 2212 } else {
2213 // normal paragraph item 2213 // normal paragraph item
2214 s += "<p"; 2214 s += "<p";
2215 s += align_to_string( p->alignment() ); 2215 s += align_to_string( p->alignment() );
2216 s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm ); 2216 s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
2217 s +=direction_to_string( p->direction() ); 2217 s +=direction_to_string( p->direction() );
2218 s += ">"; 2218 s += ">";
2219 s += ps; 2219 s += ps;
2220 s += "</p>"; 2220 s += "</p>";
2221 } 2221 }
2222 pastListDepth = listDepth; 2222 pastListDepth = listDepth;
2223 p = p->next(); 2223 p = p->next();
2224 } 2224 }
2225 while ( listDepth > 0 ) { 2225 while ( listDepth > 0 ) {
2226 s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>"; 2226 s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>";
2227 listDepth--; 2227 listDepth--;
2228 } 2228 }
2229 2229
2230 if ( !par ) 2230 if ( !par )
2231 s += "\n</body></html>\n"; 2231 s += "\n</body></html>\n";
2232 2232
2233 return s; 2233 return s;
2234} 2234}
2235 2235
2236QString QTextDocument::text() const 2236QString QTextDocument::text() const
2237{ 2237{
2238 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) 2238 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText )
2239 return richText(); 2239 return richText();
2240 return plainText(); 2240 return plainText();
2241} 2241}
2242 2242
2243QString QTextDocument::text( int parag ) const 2243QString QTextDocument::text( int parag ) const
2244{ 2244{
2245 QTextParagraph *p = paragAt( parag ); 2245 QTextParagraph *p = paragAt( parag );
2246 if ( !p ) 2246 if ( !p )
2247 return QString::null; 2247 return QString::null;
2248 2248
2249 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText ) 2249 if ( txtFormat == Qt::AutoText && preferRichText || txtFormat == Qt::RichText )
2250 return p->richText(); 2250 return p->richText();
2251 else 2251 else
2252 return p->string()->toString(); 2252 return p->string()->toString();
2253} 2253}
2254 2254
2255void QTextDocument::invalidate() 2255void QTextDocument::invalidate()
2256{ 2256{
2257 QTextParagraph *s = fParag; 2257 QTextParagraph *s = fParag;
2258 while ( s ) { 2258 while ( s ) {
2259 s->invalidate( 0 ); 2259 s->invalidate( 0 );
2260 s = s->next(); 2260 s = s->next();
2261 } 2261 }
2262} 2262}
2263 2263
2264void QTextDocument::selectionStart( int id, int &paragId, int &index ) 2264void QTextDocument::selectionStart( int id, int &paragId, int &index )
2265{ 2265{
2266 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2266 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2267 if ( it == selections.end() ) 2267 if ( it == selections.end() )
2268 return; 2268 return;
2269 QTextDocumentSelection &sel = *it; 2269 QTextDocumentSelection &sel = *it;
2270 paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); 2270 paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
2271 index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); 2271 index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
2272} 2272}
2273 2273
2274QTextCursor QTextDocument::selectionStartCursor( int id) 2274QTextCursor QTextDocument::selectionStartCursor( int id)
2275{ 2275{
2276 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2276 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2277 if ( it == selections.end() ) 2277 if ( it == selections.end() )
2278 return QTextCursor( this ); 2278 return QTextCursor( this );
2279 QTextDocumentSelection &sel = *it; 2279 QTextDocumentSelection &sel = *it;
2280 if ( sel.swapped ) 2280 if ( sel.swapped )
2281 return sel.endCursor; 2281 return sel.endCursor;
2282 return sel.startCursor; 2282 return sel.startCursor;
2283} 2283}
2284 2284
2285QTextCursor QTextDocument::selectionEndCursor( int id) 2285QTextCursor QTextDocument::selectionEndCursor( int id)
2286{ 2286{
2287 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2287 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2288 if ( it == selections.end() ) 2288 if ( it == selections.end() )
2289 return QTextCursor( this ); 2289 return QTextCursor( this );
2290 QTextDocumentSelection &sel = *it; 2290 QTextDocumentSelection &sel = *it;
2291 if ( !sel.swapped ) 2291 if ( !sel.swapped )
2292 return sel.endCursor; 2292 return sel.endCursor;
2293 return sel.startCursor; 2293 return sel.startCursor;
2294} 2294}
2295 2295
2296void QTextDocument::selectionEnd( int id, int &paragId, int &index ) 2296void QTextDocument::selectionEnd( int id, int &paragId, int &index )
2297{ 2297{
2298 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2298 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2299 if ( it == selections.end() ) 2299 if ( it == selections.end() )
2300 return; 2300 return;
2301 QTextDocumentSelection &sel = *it; 2301 QTextDocumentSelection &sel = *it;
2302 paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId(); 2302 paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
2303 index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index(); 2303 index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
2304} 2304}
2305 2305
2306void QTextDocument::addSelection( int id ) 2306void QTextDocument::addSelection( int id )
2307{ 2307{
2308 nSelections = QMAX( nSelections, id + 1 ); 2308 nSelections = QMAX( nSelections, id + 1 );
2309} 2309}
2310 2310
2311static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCursor &start, QTextCursor &end ) 2311static void setSelectionEndHelper( int id, QTextDocumentSelection &sel, QTextCursor &start, QTextCursor &end )
2312{ 2312{
2313 QTextCursor c1 = start; 2313 QTextCursor c1 = start;
2314 QTextCursor c2 = end; 2314 QTextCursor c2 = end;
2315 if ( sel.swapped ) { 2315 if ( sel.swapped ) {
2316 c1 = end; 2316 c1 = end;
2317 c2 = start; 2317 c2 = start;
2318 } 2318 }
2319 2319
2320 c1.paragraph()->removeSelection( id ); 2320 c1.paragraph()->removeSelection( id );
2321 c2.paragraph()->removeSelection( id ); 2321 c2.paragraph()->removeSelection( id );
2322 if ( c1.paragraph() != c2.paragraph() ) { 2322 if ( c1.paragraph() != c2.paragraph() ) {
2323 c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 ); 2323 c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 );
2324 c2.paragraph()->setSelection( id, 0, c2.index() ); 2324 c2.paragraph()->setSelection( id, 0, c2.index() );
2325 } else { 2325 } else {
2326 c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) ); 2326 c1.paragraph()->setSelection( id, QMIN( c1.index(), c2.index() ), QMAX( c1.index(), c2.index() ) );
2327 } 2327 }
2328 2328
2329 sel.startCursor = start; 2329 sel.startCursor = start;
2330 sel.endCursor = end; 2330 sel.endCursor = end;
2331 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) 2331 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
2332 sel.swapped = sel.startCursor.index() > sel.endCursor.index(); 2332 sel.swapped = sel.startCursor.index() > sel.endCursor.index();
2333} 2333}
2334 2334
2335bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor ) 2335bool QTextDocument::setSelectionEnd( int id, const QTextCursor &cursor )
2336{ 2336{
2337 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2337 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2338 if ( it == selections.end() ) 2338 if ( it == selections.end() )
2339 return FALSE; 2339 return FALSE;
2340 QTextDocumentSelection &sel = *it; 2340 QTextDocumentSelection &sel = *it;
2341 2341
2342 QTextCursor start = sel.startCursor; 2342 QTextCursor start = sel.startCursor;
2343 QTextCursor end = cursor; 2343 QTextCursor end = cursor;
2344 2344
2345 if ( start == end ) { 2345 if ( start == end ) {
2346 removeSelection( id ); 2346 removeSelection( id );
2347 setSelectionStart( id, cursor ); 2347 setSelectionStart( id, cursor );
2348 return TRUE; 2348 return TRUE;
2349 } 2349 }
2350 2350
2351 if ( sel.endCursor.paragraph() == end.paragraph() ) { 2351 if ( sel.endCursor.paragraph() == end.paragraph() ) {
2352 setSelectionEndHelper( id, sel, start, end ); 2352 setSelectionEndHelper( id, sel, start, end );
2353 return TRUE; 2353 return TRUE;
2354 } 2354 }
2355 2355
2356 bool inSelection = FALSE; 2356 bool inSelection = FALSE;
2357 QTextCursor c( this ); 2357 QTextCursor c( this );
2358 QTextCursor tmp = sel.startCursor; 2358 QTextCursor tmp = sel.startCursor;
2359 if ( sel.swapped ) 2359 if ( sel.swapped )
2360 tmp = sel.endCursor; 2360 tmp = sel.endCursor;
2361 tmp.restoreState(); 2361 tmp.restoreState();
2362 QTextCursor tmp2 = cursor; 2362 QTextCursor tmp2 = cursor;
2363 tmp2.restoreState(); 2363 tmp2.restoreState();
2364 c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() ); 2364 c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() );
2365 bool hadStart = FALSE; 2365 bool hadStart = FALSE;
2366 bool hadEnd = FALSE; 2366 bool hadEnd = FALSE;
2367 bool hadStartParag = FALSE; 2367 bool hadStartParag = FALSE;
2368 bool hadEndParag = FALSE; 2368 bool hadEndParag = FALSE;
2369 bool hadOldStart = FALSE; 2369 bool hadOldStart = FALSE;
2370 bool hadOldEnd = FALSE; 2370 bool hadOldEnd = FALSE;
2371 bool leftSelection = FALSE; 2371 bool leftSelection = FALSE;
2372 sel.swapped = FALSE; 2372 sel.swapped = FALSE;
2373 for ( ;; ) { 2373 for ( ;; ) {
2374 if ( c == start ) 2374 if ( c == start )
2375 hadStart = TRUE; 2375 hadStart = TRUE;
2376 if ( c == end ) 2376 if ( c == end )
2377 hadEnd = TRUE; 2377 hadEnd = TRUE;
2378 if ( c.paragraph() == start.paragraph() ) 2378 if ( c.paragraph() == start.paragraph() )
2379 hadStartParag = TRUE; 2379 hadStartParag = TRUE;
2380 if ( c.paragraph() == end.paragraph() ) 2380 if ( c.paragraph() == end.paragraph() )
2381 hadEndParag = TRUE; 2381 hadEndParag = TRUE;
2382 if ( c == sel.startCursor ) 2382 if ( c == sel.startCursor )
2383 hadOldStart = TRUE; 2383 hadOldStart = TRUE;
2384 if ( c == sel.endCursor ) 2384 if ( c == sel.endCursor )
2385 hadOldEnd = TRUE; 2385 hadOldEnd = TRUE;
2386 2386
2387 if ( !sel.swapped && 2387 if ( !sel.swapped &&
2388 ( hadEnd && !hadStart || 2388 ( hadEnd && !hadStart ||
2389 hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) ) 2389 hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index() ) )
2390 sel.swapped = TRUE; 2390 sel.swapped = TRUE;
2391 2391
2392 if ( c == end && hadStartParag || 2392 if ( c == end && hadStartParag ||
2393 c == start && hadEndParag ) { 2393 c == start && hadEndParag ) {
2394 QTextCursor tmp = c; 2394 QTextCursor tmp = c;
2395 tmp.restoreState(); 2395 tmp.restoreState();
2396 if ( tmp.paragraph() != c.paragraph() ) { 2396 if ( tmp.paragraph() != c.paragraph() ) {
2397 int sstart = tmp.paragraph()->selectionStart( id ); 2397 int sstart = tmp.paragraph()->selectionStart( id );
2398 tmp.paragraph()->removeSelection( id ); 2398 tmp.paragraph()->removeSelection( id );
2399 tmp.paragraph()->setSelection( id, sstart, tmp.index() ); 2399 tmp.paragraph()->setSelection( id, sstart, tmp.index() );
2400 } 2400 }
2401 } 2401 }
2402 2402
2403 if ( inSelection && 2403 if ( inSelection &&
2404 ( c == end && hadStart || c == start && hadEnd ) ) 2404 ( c == end && hadStart || c == start && hadEnd ) )
2405 leftSelection = TRUE; 2405 leftSelection = TRUE;
2406 else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) ) 2406 else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) )
2407 inSelection = TRUE; 2407 inSelection = TRUE;
2408 2408
2409 bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd(); 2409 bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd();
2410 c.paragraph()->removeSelection( id ); 2410 c.paragraph()->removeSelection( id );
2411 if ( inSelection ) { 2411 if ( inSelection ) {
2412 if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) { 2412 if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) {
2413 c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) ); 2413 c.paragraph()->setSelection( id, QMIN( start.index(), end.index() ), QMAX( start.index(), end.index() ) );
2414 } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) { 2414 } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) {
2415 c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 ); 2415 c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 );
2416 } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) { 2416 } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) {
2417 c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 ); 2417 c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 );
2418 } else if ( c.paragraph() == end.paragraph() && hadEndParag ) { 2418 } else if ( c.paragraph() == end.paragraph() && hadEndParag ) {
2419 c.paragraph()->setSelection( id, 0, end.index() ); 2419 c.paragraph()->setSelection( id, 0, end.index() );
2420 } else if ( c.paragraph() == start.paragraph() && hadStartParag ) { 2420 } else if ( c.paragraph() == start.paragraph() && hadStartParag ) {
2421 c.paragraph()->setSelection( id, 0, start.index() ); 2421 c.paragraph()->setSelection( id, 0, start.index() );
2422 } else { 2422 } else {
2423 c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 ); 2423 c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 );
2424 } 2424 }
2425 } 2425 }
2426 2426
2427 if ( leftSelection ) 2427 if ( leftSelection )
2428 inSelection = FALSE; 2428 inSelection = FALSE;
2429 2429
2430 if ( noSelectionAnymore ) 2430 if ( noSelectionAnymore )
2431 break; 2431 break;
2432 // *ugle*hack optimization 2432 // *ugle*hack optimization
2433 QTextParagraph *p = c.paragraph(); 2433 QTextParagraph *p = c.paragraph();
2434 if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) { 2434 if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) {
2435 c.gotoNextLetter(); 2435 c.gotoNextLetter();
2436 if ( p == lastParagraph() && c.atParagEnd() ) 2436 if ( p == lastParagraph() && c.atParagEnd() )
2437 break; 2437 break;
2438 } else { 2438 } else {
2439 if ( p->document()->parent() ) 2439 if ( p->document()->parent() )
2440 do { 2440 do {
2441 c.gotoNextLetter(); 2441 c.gotoNextLetter();
2442 } while ( c.paragraph() == p ); 2442 } while ( c.paragraph() == p );
2443 else 2443 else
2444 c.setParagraph( p->next() ); 2444 c.setParagraph( p->next() );
2445 } 2445 }
2446 } 2446 }
2447 2447
2448 if ( !sel.swapped ) 2448 if ( !sel.swapped )
2449 sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 ); 2449 sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 );
2450 2450
2451 sel.startCursor = start; 2451 sel.startCursor = start;
2452 sel.endCursor = end; 2452 sel.endCursor = end;
2453 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() ) 2453 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
2454 sel.swapped = sel.startCursor.index() > sel.endCursor.index(); 2454 sel.swapped = sel.startCursor.index() > sel.endCursor.index();
2455 2455
2456 setSelectionEndHelper( id, sel, start, end ); 2456 setSelectionEndHelper( id, sel, start, end );
2457 2457
2458 return TRUE; 2458 return TRUE;
2459} 2459}
2460 2460
2461void QTextDocument::selectAll( int id ) 2461void QTextDocument::selectAll( int id )
2462{ 2462{
2463 removeSelection( id ); 2463 removeSelection( id );
2464 2464
2465 QTextDocumentSelection sel; 2465 QTextDocumentSelection sel;
2466 sel.swapped = FALSE; 2466 sel.swapped = FALSE;
2467 QTextCursor c( this ); 2467 QTextCursor c( this );
2468 2468
2469 c.setParagraph( fParag ); 2469 c.setParagraph( fParag );
2470 c.setIndex( 0 ); 2470 c.setIndex( 0 );
2471 sel.startCursor = c; 2471 sel.startCursor = c;
2472 2472
2473 c.setParagraph( lParag ); 2473 c.setParagraph( lParag );
2474 c.setIndex( lParag->length() - 1 ); 2474 c.setIndex( lParag->length() - 1 );
2475 sel.endCursor = c; 2475 sel.endCursor = c;
2476 2476
2477 selections.insert( id, sel ); 2477 selections.insert( id, sel );
2478 2478
2479 QTextParagraph *p = fParag; 2479 QTextParagraph *p = fParag;
2480 while ( p ) { 2480 while ( p ) {
2481 p->setSelection( id, 0, p->length() - 1 ); 2481 p->setSelection( id, 0, p->length() - 1 );
2482 p = p->next(); 2482 p = p->next();
2483 } 2483 }
2484 2484
2485 for ( QTextDocument *d = childList.first(); d; d = childList.next() ) 2485 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
2486 d->selectAll( id ); 2486 d->selectAll( id );
2487} 2487}
2488 2488
2489bool QTextDocument::removeSelection( int id ) 2489bool QTextDocument::removeSelection( int id )
2490{ 2490{
2491 if ( !selections.contains( id ) ) 2491 if ( !selections.contains( id ) )
2492 return FALSE; 2492 return FALSE;
2493 2493
2494 QTextDocumentSelection &sel = selections[ id ]; 2494 QTextDocumentSelection &sel = selections[ id ];
2495 2495
2496 QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor; 2496 QTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor;
2497 QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor; 2497 QTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor;
2498 QTextParagraph* p = 0; 2498 QTextParagraph* p = 0;
2499 while ( start != end ) { 2499 while ( start != end ) {
2500 if ( p != start.paragraph() ) { 2500 if ( p != start.paragraph() ) {
2501 p = start.paragraph(); 2501 p = start.paragraph();
2502 p->removeSelection( id ); 2502 p->removeSelection( id );
2503 } 2503 }
2504 start.gotoNextLetter(); 2504 start.gotoNextLetter();
2505 } 2505 }
2506 selections.remove( id ); 2506 selections.remove( id );
2507 return TRUE; 2507 return TRUE;
2508} 2508}
2509 2509
2510QString QTextDocument::selectedText( int id, bool asRichText ) const 2510QString QTextDocument::selectedText( int id, bool asRichText ) const
2511{ 2511{
2512 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); 2512 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id );
2513 if ( it == selections.end() ) 2513 if ( it == selections.end() )
2514 return QString::null; 2514 return QString::null;
2515 2515
2516 QTextDocumentSelection sel = *it; 2516 QTextDocumentSelection sel = *it;
2517 2517
2518 2518
2519 QTextCursor c1 = sel.startCursor; 2519 QTextCursor c1 = sel.startCursor;
2520 QTextCursor c2 = sel.endCursor; 2520 QTextCursor c2 = sel.endCursor;
2521 if ( sel.swapped ) { 2521 if ( sel.swapped ) {
2522 c2 = sel.startCursor; 2522 c2 = sel.startCursor;
2523 c1 = sel.endCursor; 2523 c1 = sel.endCursor;
2524 } 2524 }
2525 2525
2526 /* 3.0.3 improvement: Make it possible to get a reasonable 2526 /* 3.0.3 improvement: Make it possible to get a reasonable
2527 selection inside a table. This approach is very conservative: 2527 selection inside a table. This approach is very conservative:
2528 make sure that both cursors have the same depth level and point 2528 make sure that both cursors have the same depth level and point
2529 to paragraphs within the same text document. 2529 to paragraphs within the same text document.
2530 2530
2531 Meaning if you select text in two table cells, you will get the 2531 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 2532 entire table. This is still far better than the 3.0.2, where
2533 you always got the entire table. 2533 you always got the entire table.
2534 2534
2535 ### Fix this properly when refactoring 2535 ### Fix this properly when refactoring
2536 */ 2536 */
2537 while ( c2.nestedDepth() > c1.nestedDepth() ) 2537 while ( c2.nestedDepth() > c1.nestedDepth() )
2538 c2.oneUp(); 2538 c2.oneUp();
2539 while ( c1.nestedDepth() > c2.nestedDepth() ) 2539 while ( c1.nestedDepth() > c2.nestedDepth() )
2540 c1.oneUp(); 2540 c1.oneUp();
2541 while ( c1.nestedDepth() && c2.nestedDepth() && 2541 while ( c1.nestedDepth() && c2.nestedDepth() &&
2542 c1.paragraph()->document() != c2.paragraph()->document() ) { 2542 c1.paragraph()->document() != c2.paragraph()->document() ) {
2543 c1.oneUp(); 2543 c1.oneUp();
2544 c2.oneUp(); 2544 c2.oneUp();
2545 } 2545 }
2546 // do not trust sel_swapped with tables. Fix this properly when refactoring as well 2546 // do not trust sel_swapped with tables. Fix this properly when refactoring as well
2547 if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() || 2547 if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() ||
2548 (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) { 2548 (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) {
2549 QTextCursor tmp = c1; 2549 QTextCursor tmp = c1;
2550 c2 = c1; 2550 c2 = c1;
2551 c1 = tmp; 2551 c1 = tmp;
2552 } 2552 }
2553 2553
2554 // end selection 3.0.3 improvement 2554 // end selection 3.0.3 improvement
2555 2555
2556 if ( asRichText && !parent() ) { 2556 if ( asRichText && !parent() ) {
2557 richTextExportStart = &c1; 2557 richTextExportStart = &c1;
2558 richTextExportEnd = &c2; 2558 richTextExportEnd = &c2;
2559 2559
2560 QString sel = richText(); 2560 QString sel = richText();
2561 int from = sel.find( "<selstart/>" ); 2561 int from = sel.find( "<selstart/>" );
2562 int to = sel.findRev( "<selend/>" ); 2562 int to = sel.findRev( "<selend/>" );
2563 if ( from >= 0 && from <= to ) 2563 if ( from >= 0 && from <= to )
2564 sel = sel.mid( from, to - from ); 2564 sel = sel.mid( from, to - from );
2565 richTextExportStart = richTextExportEnd = 0; 2565 richTextExportStart = richTextExportEnd = 0;
2566 return sel; 2566 return sel;
2567 } 2567 }
2568 2568
2569 QString s; 2569 QString s;
2570 if ( c1.paragraph() == c2.paragraph() ) { 2570 if ( c1.paragraph() == c2.paragraph() ) {
2571 QTextParagraph *p = c1.paragraph(); 2571 QTextParagraph *p = c1.paragraph();
2572 int end = c2.index(); 2572 int end = c2.index();
2573 if ( p->at( QMAX( 0, end - 1 ) )->isCustom() ) 2573 if ( p->at( QMAX( 0, end - 1 ) )->isCustom() )
2574 ++end; 2574 ++end;
2575 if ( !p->mightHaveCustomItems ) { 2575 if ( !p->mightHaveCustomItems ) {
2576 s += p->string()->toString().mid( c1.index(), end - c1.index() ); 2576 s += p->string()->toString().mid( c1.index(), end - c1.index() );
2577 } else { 2577 } else {
2578 for ( int i = c1.index(); i < end; ++i ) { 2578 for ( int i = c1.index(); i < end; ++i ) {
2579 if ( p->at( i )->isCustom() ) { 2579 if ( p->at( i )->isCustom() ) {
2580 if ( p->at( i )->customItem()->isNested() ) { 2580 if ( p->at( i )->customItem()->isNested() ) {
2581 s += "\n"; 2581 s += "\n";
2582 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 2582 QTextTable *t = (QTextTable*)p->at( i )->customItem();
2583 QPtrList<QTextTableCell> cells = t->tableCells(); 2583 QPtrList<QTextTableCell> cells = t->tableCells();
2584 for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) 2584 for ( QTextTableCell *c = cells.first(); c; c = cells.next() )
2585 s += c->richText()->plainText() + "\n"; 2585 s += c->richText()->plainText() + "\n";
2586 s += "\n"; 2586 s += "\n";
2587 } 2587 }
2588 } else { 2588 } else {
2589 s += p->at( i )->c; 2589 s += p->at( i )->c;
2590 } 2590 }
2591 } 2591 }
2592 } 2592 }
2593 } else { 2593 } else {
2594 QTextParagraph *p = c1.paragraph(); 2594 QTextParagraph *p = c1.paragraph();
2595 int start = c1.index(); 2595 int start = c1.index();
2596 while ( p ) { 2596 while ( p ) {
2597 int end = p == c2.paragraph() ? c2.index() : p->length() - 1; 2597 int end = p == c2.paragraph() ? c2.index() : p->length() - 1;
2598 if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() ) 2598 if ( p == c2.paragraph() && p->at( QMAX( 0, end - 1 ) )->isCustom() )
2599 ++end; 2599 ++end;
2600 if ( !p->mightHaveCustomItems ) { 2600 if ( !p->mightHaveCustomItems ) {
2601 s += p->string()->toString().mid( start, end - start ); 2601 s += p->string()->toString().mid( start, end - start );
2602 if ( p != c2.paragraph() ) 2602 if ( p != c2.paragraph() )
2603 s += "\n"; 2603 s += "\n";
2604 } else { 2604 } else {
2605 for ( int i = start; i < end; ++i ) { 2605 for ( int i = start; i < end; ++i ) {
2606 if ( p->at( i )->isCustom() ) { 2606 if ( p->at( i )->isCustom() ) {
2607 if ( p->at( i )->customItem()->isNested() ) { 2607 if ( p->at( i )->customItem()->isNested() ) {
2608 s += "\n"; 2608 s += "\n";
2609 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 2609 QTextTable *t = (QTextTable*)p->at( i )->customItem();
2610 QPtrList<QTextTableCell> cells = t->tableCells(); 2610 QPtrList<QTextTableCell> cells = t->tableCells();
2611 for ( QTextTableCell *c = cells.first(); c; c = cells.next() ) 2611 for ( QTextTableCell *c = cells.first(); c; c = cells.next() )
2612 s += c->richText()->plainText() + "\n"; 2612 s += c->richText()->plainText() + "\n";
2613 s += "\n"; 2613 s += "\n";
2614 } 2614 }
2615 } else { 2615 } else {
2616 s += p->at( i )->c; 2616 s += p->at( i )->c;
2617 } 2617 }
2618 } 2618 }
2619 } 2619 }
2620 start = 0; 2620 start = 0;
2621 if ( p == c2.paragraph() ) 2621 if ( p == c2.paragraph() )
2622 break; 2622 break;
2623 p = p->next(); 2623 p = p->next();
2624 } 2624 }
2625 } 2625 }
2626 // ### workaround for plain text export until we get proper 2626 // ### workaround for plain text export until we get proper
2627 // mime types: turn unicode line seperators into the more 2627 // mime types: turn unicode line seperators into the more
2628 // widely understood \n. Makes copy and pasting code snipplets 2628 // widely understood \n. Makes copy and pasting code snipplets
2629 // from within Assistent possible 2629 // from within Assistent possible
2630 QChar* uc = (QChar*) s.unicode(); 2630 QChar* uc = (QChar*) s.unicode();
2631 for ( uint ii = 0; ii < s.length(); ii++ ) 2631 for ( uint ii = 0; ii < s.length(); ii++ )
2632 if ( uc[(int)ii] == QChar_linesep ) 2632 if ( uc[(int)ii] == QChar_linesep )
2633 uc[(int)ii] = QChar('\n'); 2633 uc[(int)ii] = QChar('\n');
2634 return s; 2634 return s;
2635} 2635}
2636 2636
2637void QTextDocument::setFormat( int id, QTextFormat *f, int flags ) 2637void QTextDocument::setFormat( int id, QTextFormat *f, int flags )
2638{ 2638{
2639 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id ); 2639 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( id );
2640 if ( it == selections.end() ) 2640 if ( it == selections.end() )
2641 return; 2641 return;
2642 2642
2643 QTextDocumentSelection sel = *it; 2643 QTextDocumentSelection sel = *it;
2644 2644
2645 QTextCursor c1 = sel.startCursor; 2645 QTextCursor c1 = sel.startCursor;
2646 QTextCursor c2 = sel.endCursor; 2646 QTextCursor c2 = sel.endCursor;
2647 if ( sel.swapped ) { 2647 if ( sel.swapped ) {
2648 c2 = sel.startCursor; 2648 c2 = sel.startCursor;
2649 c1 = sel.endCursor; 2649 c1 = sel.endCursor;
2650 } 2650 }
2651 2651
2652 c2.restoreState(); 2652 c2.restoreState();
2653 c1.restoreState(); 2653 c1.restoreState();
2654 2654
2655 if ( c1.paragraph() == c2.paragraph() ) { 2655 if ( c1.paragraph() == c2.paragraph() ) {
2656 c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags ); 2656 c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags );
2657 return; 2657 return;
2658 } 2658 }
2659 2659
2660 c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags ); 2660 c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags );
2661 QTextParagraph *p = c1.paragraph()->next(); 2661 QTextParagraph *p = c1.paragraph()->next();
2662 while ( p && p != c2.paragraph() ) { 2662 while ( p && p != c2.paragraph() ) {
2663 p->setFormat( 0, p->length(), f, TRUE, flags ); 2663 p->setFormat( 0, p->length(), f, TRUE, flags );
2664 p = p->next(); 2664 p = p->next();
2665 } 2665 }
2666 c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags ); 2666 c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags );
2667} 2667}
2668 2668
2669void QTextDocument::removeSelectedText( int id, QTextCursor *cursor ) 2669void QTextDocument::removeSelectedText( int id, QTextCursor *cursor )
2670{ 2670{
2671 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2671 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2672 if ( it == selections.end() ) 2672 if ( it == selections.end() )
2673 return; 2673 return;
2674 2674
2675 QTextDocumentSelection sel = *it; 2675 QTextDocumentSelection sel = *it;
2676 2676
2677 QTextCursor c1 = sel.startCursor; 2677 QTextCursor c1 = sel.startCursor;
2678 QTextCursor c2 = sel.endCursor; 2678 QTextCursor c2 = sel.endCursor;
2679 if ( sel.swapped ) { 2679 if ( sel.swapped ) {
2680 c2 = sel.startCursor; 2680 c2 = sel.startCursor;
2681 c1 = sel.endCursor; 2681 c1 = sel.endCursor;
2682 } 2682 }
2683 2683
2684 // ### no support for editing tables yet 2684 // ### no support for editing tables yet
2685 if ( c1.nestedDepth() || c2.nestedDepth() ) 2685 if ( c1.nestedDepth() || c2.nestedDepth() )
2686 return; 2686 return;
2687 2687
2688 c2.restoreState(); 2688 c2.restoreState();
2689 c1.restoreState(); 2689 c1.restoreState();
2690 2690
2691 *cursor = c1; 2691 *cursor = c1;
2692 removeSelection( id ); 2692 removeSelection( id );
2693 2693
2694 if ( c1.paragraph() == c2.paragraph() ) { 2694 if ( c1.paragraph() == c2.paragraph() ) {
2695 c1.paragraph()->remove( c1.index(), c2.index() - c1.index() ); 2695 c1.paragraph()->remove( c1.index(), c2.index() - c1.index() );
2696 return; 2696 return;
2697 } 2697 }
2698 2698
2699 if ( c1.paragraph() == fParag && c1.index() == 0 && 2699 if ( c1.paragraph() == fParag && c1.index() == 0 &&
2700 c2.paragraph() == lParag && c2.index() == lParag->length() - 1 ) 2700 c2.paragraph() == lParag && c2.index() == lParag->length() - 1 )
2701 cursor->setValid( FALSE ); 2701 cursor->setValid( FALSE );
2702 2702
2703 bool didGoLeft = FALSE; 2703 bool didGoLeft = FALSE;
2704 if ( c1.index() == 0 && c1.paragraph() != fParag ) { 2704 if ( c1.index() == 0 && c1.paragraph() != fParag ) {
2705 cursor->gotoPreviousLetter(); 2705 cursor->gotoPreviousLetter();
2706 if ( cursor->isValid() ) 2706 if ( cursor->isValid() )
2707 didGoLeft = TRUE; 2707 didGoLeft = TRUE;
2708 } 2708 }
2709 2709
2710 c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() ); 2710 c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() );
2711 QTextParagraph *p = c1.paragraph()->next(); 2711 QTextParagraph *p = c1.paragraph()->next();
2712 int dy = 0; 2712 int dy = 0;
2713 QTextParagraph *tmp; 2713 QTextParagraph *tmp;
2714 while ( p && p != c2.paragraph() ) { 2714 while ( p && p != c2.paragraph() ) {
2715 tmp = p->next(); 2715 tmp = p->next();
2716 dy -= p->rect().height(); 2716 dy -= p->rect().height();
2717 delete p; 2717 delete p;
2718 p = tmp; 2718 p = tmp;
2719 } 2719 }
2720 c2.paragraph()->remove( 0, c2.index() ); 2720 c2.paragraph()->remove( 0, c2.index() );
2721 while ( p ) { 2721 while ( p ) {
2722 p->move( dy ); 2722 p->move( dy );
2723 p->invalidate( 0 ); 2723 p->invalidate( 0 );
2724 p->setEndState( -1 ); 2724 p->setEndState( -1 );
2725 p = p->next(); 2725 p = p->next();
2726 } 2726 }
2727 2727
2728 c1.paragraph()->join( c2.paragraph() ); 2728 c1.paragraph()->join( c2.paragraph() );
2729 2729
2730 if ( didGoLeft ) 2730 if ( didGoLeft )
2731 cursor->gotoNextLetter(); 2731 cursor->gotoNextLetter();
2732} 2732}
2733 2733
2734void QTextDocument::indentSelection( int id ) 2734void QTextDocument::indentSelection( int id )
2735{ 2735{
2736 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id ); 2736 QMap<int, QTextDocumentSelection>::Iterator it = selections.find( id );
2737 if ( it == selections.end() ) 2737 if ( it == selections.end() )
2738 return; 2738 return;
2739 2739
2740 QTextDocumentSelection sel = *it; 2740 QTextDocumentSelection sel = *it;
2741 QTextParagraph *startParag = sel.startCursor.paragraph(); 2741 QTextParagraph *startParag = sel.startCursor.paragraph();
2742 QTextParagraph *endParag = sel.endCursor.paragraph(); 2742 QTextParagraph *endParag = sel.endCursor.paragraph();
2743 if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { 2743 if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
2744 endParag = sel.startCursor.paragraph(); 2744 endParag = sel.startCursor.paragraph();
2745 startParag = sel.endCursor.paragraph(); 2745 startParag = sel.endCursor.paragraph();
2746 } 2746 }
2747 2747
2748 QTextParagraph *p = startParag; 2748 QTextParagraph *p = startParag;
2749 while ( p && p != endParag ) { 2749 while ( p && p != endParag ) {
2750 p->indent(); 2750 p->indent();
2751 p = p->next(); 2751 p = p->next();
2752 } 2752 }
2753} 2753}
2754 2754
2755void QTextDocument::addCommand( QTextCommand *cmd ) 2755void QTextDocument::addCommand( QTextCommand *cmd )
2756{ 2756{
2757 commandHistory->addCommand( cmd ); 2757 commandHistory->addCommand( cmd );
2758} 2758}
2759 2759
2760QTextCursor *QTextDocument::undo( QTextCursor *c ) 2760QTextCursor *QTextDocument::undo( QTextCursor *c )
2761{ 2761{
2762 return commandHistory->undo( c ); 2762 return commandHistory->undo( c );
2763} 2763}
2764 2764
2765QTextCursor *QTextDocument::redo( QTextCursor *c ) 2765QTextCursor *QTextDocument::redo( QTextCursor *c )
2766{ 2766{
2767 return commandHistory->redo( c ); 2767 return commandHistory->redo( c );
2768} 2768}
2769 2769
2770bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward ) 2770bool QTextDocument::find( QTextCursor& cursor, const QString &e, bool cs, bool wo, bool forward )
2771{ 2771{
2772 removeSelection( Standard ); 2772 removeSelection( Standard );
2773 QTextParagraph *p = 0; 2773 QTextParagraph *p = 0;
2774 QString expr = e; 2774 QString expr = e;
2775 // if we search for 'word only' than we have to be sure that 2775 // if we search for 'word only' than we have to be sure that
2776 // the expression contains no space or punct character at the 2776 // the expression contains no space or punct character at the
2777 // beginning or in the end. Otherwise we would run into a 2777 // beginning or in the end. Otherwise we would run into a
2778 // endlessloop. 2778 // endlessloop.
2779 if ( wo ) { 2779 if ( wo ) {
2780 for ( ;; ) { 2780 for ( ;; ) {
2781 if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() ) 2781 if ( expr[ 0 ].isSpace() || expr[ 0 ].isPunct() )
2782 expr = expr.right( expr.length() - 1 ); 2782 expr = expr.right( expr.length() - 1 );
2783 else 2783 else
2784 break; 2784 break;
2785 } 2785 }
2786 for ( ;; ) { 2786 for ( ;; ) {
2787 if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() ) 2787 if ( expr.at( expr.length() - 1 ).isSpace() || expr.at( expr.length() - 1 ).isPunct() )
2788 expr = expr.left( expr.length() - 1 ); 2788 expr = expr.left( expr.length() - 1 );
2789 else 2789 else
2790 break; 2790 break;
2791 } 2791 }
2792 } 2792 }
2793 for (;;) { 2793 for (;;) {
2794 if ( p != cursor.paragraph() ) { 2794 if ( p != cursor.paragraph() ) {
2795 p = cursor.paragraph(); 2795 p = cursor.paragraph();
2796 QString s = cursor.paragraph()->string()->toString(); 2796 QString s = cursor.paragraph()->string()->toString();
2797 int start = cursor.index(); 2797 int start = cursor.index();
2798 for ( ;; ) { 2798 for ( ;; ) {
2799 int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs ); 2799 int res = forward ? s.find( expr, start, cs ) : s.findRev( expr, start, cs );
2800 int end = res + expr.length(); 2800 int end = res + expr.length();
2801 if ( res == -1 || ( !forward && start < end ) ) 2801 if ( res == -1 || ( !forward && start < end ) )
2802 break; 2802 break;
2803 if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) && 2803 if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) &&
2804 ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) { 2804 ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) {
2805 removeSelection( Standard ); 2805 removeSelection( Standard );
2806 cursor.setIndex( forward ? end : res ); 2806 cursor.setIndex( forward ? end : res );
2807 setSelectionStart( Standard, cursor ); 2807 setSelectionStart( Standard, cursor );
2808 cursor.setIndex( forward ? res : end ); 2808 cursor.setIndex( forward ? res : end );
2809 setSelectionEnd( Standard, cursor ); 2809 setSelectionEnd( Standard, cursor );
2810 return TRUE; 2810 return TRUE;
2811 } 2811 }
2812 start = res + (forward ? 1 : -1); 2812 start = res + (forward ? 1 : -1);
2813 } 2813 }
2814 } 2814 }
2815 if ( forward ) { 2815 if ( forward ) {
2816 if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () ) 2816 if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd () )
2817 break; 2817 break;
2818 cursor.gotoNextLetter(); 2818 cursor.gotoNextLetter();
2819 } else { 2819 } else {
2820 if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() ) 2820 if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() )
2821 break; 2821 break;
2822 cursor.gotoPreviousLetter(); 2822 cursor.gotoPreviousLetter();
2823 } 2823 }
2824 } 2824 }
2825 return FALSE; 2825 return FALSE;
2826} 2826}
2827 2827
2828void QTextDocument::setTextFormat( Qt::TextFormat f ) 2828void QTextDocument::setTextFormat( Qt::TextFormat f )
2829{ 2829{
2830 txtFormat = f; 2830 txtFormat = f;
2831 if ( fParag == lParag && fParag->length() <= 1 ) 2831 if ( fParag == lParag && fParag->length() <= 1 )
2832 fParag->rtext = ( f == Qt::RichText ); 2832 fParag->rtext = ( f == Qt::RichText );
2833} 2833}
2834 2834
2835Qt::TextFormat QTextDocument::textFormat() const 2835Qt::TextFormat QTextDocument::textFormat() const
2836{ 2836{
2837 return txtFormat; 2837 return txtFormat;
2838} 2838}
2839 2839
2840bool QTextDocument::inSelection( int selId, const QPoint &pos ) const 2840bool QTextDocument::inSelection( int selId, const QPoint &pos ) const
2841{ 2841{
2842 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( selId ); 2842 QMap<int, QTextDocumentSelection>::ConstIterator it = selections.find( selId );
2843 if ( it == selections.end() ) 2843 if ( it == selections.end() )
2844 return FALSE; 2844 return FALSE;
2845 2845
2846 QTextDocumentSelection sel = *it; 2846 QTextDocumentSelection sel = *it;
2847 QTextParagraph *startParag = sel.startCursor.paragraph(); 2847 QTextParagraph *startParag = sel.startCursor.paragraph();
2848 QTextParagraph *endParag = sel.endCursor.paragraph(); 2848 QTextParagraph *endParag = sel.endCursor.paragraph();
2849 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() && 2849 if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() &&
2850 sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) ) 2850 sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) )
2851 return FALSE; 2851 return FALSE;
2852 if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) { 2852 if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
2853 endParag = sel.startCursor.paragraph(); 2853 endParag = sel.startCursor.paragraph();
2854 startParag = sel.endCursor.paragraph(); 2854 startParag = sel.endCursor.paragraph();
2855 } 2855 }
2856 2856
2857 QTextParagraph *p = startParag; 2857 QTextParagraph *p = startParag;
2858 while ( p ) { 2858 while ( p ) {
2859 if ( p->rect().contains( pos ) ) { 2859 if ( p->rect().contains( pos ) ) {
2860 bool inSel = FALSE; 2860 bool inSel = FALSE;
2861 int selStart = p->selectionStart( selId ); 2861 int selStart = p->selectionStart( selId );
2862 int selEnd = p->selectionEnd( selId ); 2862 int selEnd = p->selectionEnd( selId );
2863 int y = 0; 2863 int y = 0;
2864 int h = 0; 2864 int h = 0;
2865 for ( int i = 0; i < p->length(); ++i ) { 2865 for ( int i = 0; i < p->length(); ++i ) {
2866 if ( i == selStart ) 2866 if ( i == selStart )
2867 inSel = TRUE; 2867 inSel = TRUE;
2868 if ( i == selEnd ) 2868 if ( i == selEnd )
2869 break; 2869 break;
2870 if ( p->at( i )->lineStart ) { 2870 if ( p->at( i )->lineStart ) {
2871 y = (*p->lineStarts.find( i ))->y; 2871 y = (*p->lineStarts.find( i ))->y;
2872 h = (*p->lineStarts.find( i ))->h; 2872 h = (*p->lineStarts.find( i ))->h;
2873 } 2873 }
2874 if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) { 2874 if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) {
2875 if ( inSel && pos.x() >= p->at( i )->x && 2875 if ( inSel && pos.x() >= p->at( i )->x &&
2876 pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) ) 2876 pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) )
2877 return TRUE; 2877 return TRUE;
2878 } 2878 }
2879 } 2879 }
2880 } 2880 }
2881 if ( pos.y() < p->rect().y() ) 2881 if ( pos.y() < p->rect().y() )
2882 break; 2882 break;
2883 if ( p == endParag ) 2883 if ( p == endParag )
2884 break; 2884 break;
2885 p = p->next(); 2885 p = p->next();
2886 } 2886 }
2887 2887
2888 return FALSE; 2888 return FALSE;
2889} 2889}
2890 2890
2891void QTextDocument::doLayout( QPainter *p, int w ) 2891void QTextDocument::doLayout( QPainter *p, int w )
2892{ 2892{
2893 minw = wused = 0; 2893 minw = wused = 0;
2894 if ( !is_printer( p ) ) 2894 if ( !is_printer( p ) )
2895 p = 0; 2895 p = 0;
2896 withoutDoubleBuffer = ( p != 0 ); 2896 withoutDoubleBuffer = ( p != 0 );
2897 QPainter * oldPainter = QTextFormat::painter(); 2897 QPainter * oldPainter = QTextFormat::painter();
2898 QTextFormat::setPainter( p ); 2898 QTextFormat::setPainter( p );
2899 flow_->setWidth( w ); 2899 flow_->setWidth( w );
2900 cw = w; 2900 cw = w;
2901 vw = w; 2901 vw = w;
2902 QTextParagraph *parag = fParag; 2902 QTextParagraph *parag = fParag;
2903 while ( parag ) { 2903 while ( parag ) {
2904 parag->invalidate( 0 ); 2904 parag->invalidate( 0 );
2905 if ( p ) 2905 if ( p )
2906 parag->adjustToPainter( p ); 2906 parag->adjustToPainter( p );
2907 parag->format(); 2907 parag->format();
2908 parag = parag->next(); 2908 parag = parag->next();
2909 } 2909 }
2910 QTextFormat::setPainter( oldPainter ); 2910 QTextFormat::setPainter( oldPainter );
2911} 2911}
2912 2912
2913QPixmap *QTextDocument::bufferPixmap( const QSize &s ) 2913QPixmap *QTextDocument::bufferPixmap( const QSize &s )
2914{ 2914{
2915 if ( !buf_pixmap ) 2915 if ( !buf_pixmap )
2916 buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) ); 2916 buf_pixmap = new QPixmap( s.expandedTo( QSize(1,1) ) );
2917 else if ( buf_pixmap->size() != s ) 2917 else if ( buf_pixmap->size() != s )
2918 buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) ); 2918 buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) );
2919 return buf_pixmap; 2919 return buf_pixmap;
2920} 2920}
2921 2921
2922void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper ) 2922void QTextDocument::draw( QPainter *p, const QRect &rect, const QColorGroup &cg, const QBrush *paper )
2923{ 2923{
2924 if ( !firstParagraph() ) 2924 if ( !firstParagraph() )
2925 return; 2925 return;
2926 2926
2927 if ( paper ) { 2927 if ( paper ) {
2928 p->setBrushOrigin( 0, 0 ); 2928 p->setBrushOrigin( 0, 0 );
2929 2929
2930 p->fillRect( rect, *paper ); 2930 p->fillRect( rect, *paper );
2931 } 2931 }
2932 2932
2933 if ( formatCollection()->defaultFormat()->color() != cg.text() ) 2933 if ( formatCollection()->defaultFormat()->color() != cg.text() )
2934 setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() ); 2934 setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() );
2935 2935
2936 QTextParagraph *parag = firstParagraph(); 2936 QTextParagraph *parag = firstParagraph();
2937 while ( parag ) { 2937 while ( parag ) {
2938 if ( !parag->isValid() ) 2938 if ( !parag->isValid() )
2939 parag->format(); 2939 parag->format();
2940 int y = parag->rect().y(); 2940 int y = parag->rect().y();
2941 QRect pr( parag->rect() ); 2941 QRect pr( parag->rect() );
2942 pr.setX( 0 ); 2942 pr.setX( 0 );
2943 pr.setWidth( QWIDGETSIZE_MAX ); 2943 pr.setWidth( QWIDGETSIZE_MAX );
2944 if ( !rect.isNull() && !rect.intersects( pr ) ) { 2944 if ( !rect.isNull() && !rect.intersects( pr ) ) {
2945 parag = parag->next(); 2945 parag = parag->next();
2946 continue; 2946 continue;
2947 } 2947 }
2948 p->translate( 0, y ); 2948 p->translate( 0, y );
2949 if ( rect.isValid() ) 2949 if ( rect.isValid() )
2950 parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() ); 2950 parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() );
2951 else 2951 else
2952 parag->paint( *p, cg, 0, FALSE ); 2952 parag->paint( *p, cg, 0, FALSE );
2953 p->translate( 0, -y ); 2953 p->translate( 0, -y );
2954 parag = parag->next(); 2954 parag = parag->next();
2955 if ( !flow()->isEmpty() ) 2955 if ( !flow()->isEmpty() )
2956 flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE ); 2956 flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE );
2957 } 2957 }
2958} 2958}
2959 2959
2960void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch, 2960void QTextDocument::drawParagraph( QPainter *p, QTextParagraph *parag, int cx, int cy, int cw, int ch,
2961 QPixmap *&doubleBuffer, const QColorGroup &cg, 2961 QPixmap *&doubleBuffer, const QColorGroup &cg,
2962 bool drawCursor, QTextCursor *cursor, bool resetChanged ) 2962 bool drawCursor, QTextCursor *cursor, bool resetChanged )
2963{ 2963{
2964 QPainter *painter = 0; 2964 QPainter *painter = 0;
2965 if ( resetChanged ) 2965 if ( resetChanged )
2966 parag->setChanged( FALSE ); 2966 parag->setChanged( FALSE );
2967 QRect ir( parag->rect() ); 2967 QRect ir( parag->rect() );
2968 bool useDoubleBuffer = !parag->document()->parent(); 2968 bool useDoubleBuffer = !parag->document()->parent();
2969 if ( !useDoubleBuffer && parag->document()->nextDoubleBuffered ) 2969 if ( !useDoubleBuffer && parag->document()->nextDoubleBuffered )
2970 useDoubleBuffer = TRUE; 2970 useDoubleBuffer = TRUE;
2971 if ( is_printer( p ) ) 2971 if ( is_printer( p ) )
2972 useDoubleBuffer = FALSE; 2972 useDoubleBuffer = FALSE;
2973 2973
2974 if ( useDoubleBuffer ) { 2974 if ( useDoubleBuffer ) {
2975 painter = new QPainter; 2975 painter = new QPainter;
2976 if ( cx >= 0 && cy >= 0 ) 2976 if ( cx >= 0 && cy >= 0 )
2977 ir = ir.intersect( QRect( cx, cy, cw, ch ) ); 2977 ir = ir.intersect( QRect( cx, cy, cw, ch ) );
2978 if ( !doubleBuffer || 2978 if ( !doubleBuffer ||
2979 ir.width() > doubleBuffer->width() || 2979 ir.width() > doubleBuffer->width() ||
2980 ir.height() > doubleBuffer->height() ) { 2980 ir.height() > doubleBuffer->height() ) {
2981 doubleBuffer = bufferPixmap( ir.size() ); 2981 doubleBuffer = bufferPixmap( ir.size() );
2982 painter->begin( doubleBuffer ); 2982 painter->begin( doubleBuffer );
2983 } else { 2983 } else {
2984 painter->begin( doubleBuffer ); 2984 painter->begin( doubleBuffer );
2985 } 2985 }
2986 } else { 2986 } else {
2987 painter = p; 2987 painter = p;
2988 painter->translate( ir.x(), ir.y() ); 2988 painter->translate( ir.x(), ir.y() );
2989 } 2989 }
2990 2990
2991 painter->setBrushOrigin( -ir.x(), -ir.y() ); 2991 painter->setBrushOrigin( -ir.x(), -ir.y() );
2992 2992
2993 if ( useDoubleBuffer || is_printer( painter ) ) 2993 if ( useDoubleBuffer || is_printer( painter ) )
2994 painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) ); 2994 painter->fillRect( QRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) );
2995 else if ( cursor && cursor->paragraph() == parag ) 2995 else if ( cursor && cursor->paragraph() == parag )
2996 painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ), 2996 painter->fillRect( QRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ),
2997 parag->backgroundBrush( cg ) ); 2997 parag->backgroundBrush( cg ) );
2998 2998
2999 painter->translate( -( ir.x() - parag->rect().x() ), 2999 painter->translate( -( ir.x() - parag->rect().x() ),
3000 -( ir.y() - parag->rect().y() ) ); 3000 -( ir.y() - parag->rect().y() ) );
3001 parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch ); 3001 parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch );
3002 3002
3003 if ( useDoubleBuffer ) { 3003 if ( useDoubleBuffer ) {
3004 delete painter; 3004 delete painter;
3005 painter = 0; 3005 painter = 0;
3006 p->drawPixmap( ir.topLeft(), *doubleBuffer, QRect( QPoint( 0, 0 ), ir.size() ) ); 3006 p->drawPixmap( ir.topLeft(), *doubleBuffer, QRect( QPoint( 0, 0 ), ir.size() ) );
3007 } else { 3007 } else {
3008 painter->translate( -ir.x(), -ir.y() ); 3008 painter->translate( -ir.x(), -ir.y() );
3009 } 3009 }
3010 3010
3011 if ( useDoubleBuffer ) { 3011 if ( useDoubleBuffer ) {
3012 if ( parag->rect().x() + parag->rect().width() < parag->document()->x() + parag->document()->width() ) { 3012 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(), 3013 p->fillRect( parag->rect().x() + parag->rect().width(), parag->rect().y(),
3014 ( parag->document()->x() + parag->document()->width() ) - 3014 ( parag->document()->x() + parag->document()->width() ) -
3015 ( parag->rect().x() + parag->rect().width() ), 3015 ( parag->rect().x() + parag->rect().width() ),
3016 parag->rect().height(), cg.brush( QColorGroup::Base ) ); 3016 parag->rect().height(), cg.brush( QColorGroup::Base ) );
3017 } 3017 }
3018 } 3018 }
3019 3019
3020 parag->document()->nextDoubleBuffered = FALSE; 3020 parag->document()->nextDoubleBuffered = FALSE;
3021} 3021}
3022 3022
3023QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg, 3023QTextParagraph *QTextDocument::draw( QPainter *p, int cx, int cy, int cw, int ch, const QColorGroup &cg,
3024 bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged ) 3024 bool onlyChanged, bool drawCursor, QTextCursor *cursor, bool resetChanged )
3025{ 3025{
3026 if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) { 3026 if ( withoutDoubleBuffer || par && par->withoutDoubleBuffer ) {
3027 withoutDoubleBuffer = TRUE; 3027 withoutDoubleBuffer = TRUE;
3028 QRect r; 3028 QRect r;
3029 draw( p, r, cg ); 3029 draw( p, r, cg );
3030 return 0; 3030 return 0;
3031 } 3031 }
3032 withoutDoubleBuffer = FALSE; 3032 withoutDoubleBuffer = FALSE;
3033 3033
3034 if ( !firstParagraph() ) 3034 if ( !firstParagraph() )
3035 return 0; 3035 return 0;
3036 3036
3037 if ( cx < 0 && cy < 0 ) { 3037 if ( cx < 0 && cy < 0 ) {
3038 cx = 0; 3038 cx = 0;
3039 cy = 0; 3039 cy = 0;
3040 cw = width(); 3040 cw = width();
3041 ch = height(); 3041 ch = height();
3042 } 3042 }
3043 3043
3044 QTextParagraph *lastFormatted = 0; 3044 QTextParagraph *lastFormatted = 0;
3045 QTextParagraph *parag = firstParagraph(); 3045 QTextParagraph *parag = firstParagraph();
3046 3046
3047 QPixmap *doubleBuffer = 0; 3047 QPixmap *doubleBuffer = 0;
3048 QPainter painter; 3048 QPainter painter;
3049 3049
3050 bool fullWidthSelection = FALSE; 3050 bool fullWidthSelection = FALSE;
3051 while ( parag ) { 3051 while ( parag ) {
3052 lastFormatted = parag; 3052 lastFormatted = parag;
3053 if ( !parag->isValid() ) 3053 if ( !parag->isValid() )
3054 parag->format(); 3054 parag->format();
3055 3055
3056 QRect pr = parag->rect(); 3056 QRect pr = parag->rect();
3057 if ( fullWidthSelection ) 3057 if ( fullWidthSelection )
3058 pr.setWidth( parag->document()->width() ); 3058 pr.setWidth( parag->document()->width() );
3059 if ( pr.y() > cy + ch ) 3059 if ( pr.y() > cy + ch )
3060 goto floating; 3060 goto floating;
3061 if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) { 3061 if ( !pr.intersects( QRect( cx, cy, cw, ch ) ) || ( onlyChanged && !parag->hasChanged() ) ) {
3062 parag = parag->next(); 3062 parag = parag->next();
3063 continue; 3063 continue;
3064 } 3064 }
3065 3065
3066 drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged ); 3066 drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged );
3067 parag = parag->next(); 3067 parag = parag->next();
3068 } 3068 }
3069 3069
3070 parag = lastParagraph(); 3070 parag = lastParagraph();
3071 3071
3072 floating: 3072 floating:
3073 if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) { 3073 if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) {
3074 if ( !parag->document()->parent() ) { 3074 if ( !parag->document()->parent() ) {
3075 p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(), 3075 p->fillRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
3076 parag->document()->height() - ( parag->rect().y() + parag->rect().height() ), 3076 parag->document()->height() - ( parag->rect().y() + parag->rect().height() ),
3077 cg.brush( QColorGroup::Base ) ); 3077 cg.brush( QColorGroup::Base ) );
3078 } 3078 }
3079 if ( !flow()->isEmpty() ) { 3079 if ( !flow()->isEmpty() ) {
3080 QRect cr( cx, cy, cw, ch ); 3080 QRect cr( cx, cy, cw, ch );
3081 flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE ); 3081 flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE );
3082 } 3082 }
3083 } 3083 }
3084 3084
3085 if ( buf_pixmap && buf_pixmap->height() > 300 ) { 3085 if ( buf_pixmap && buf_pixmap->height() > 300 ) {
3086 delete buf_pixmap; 3086 delete buf_pixmap;
3087 buf_pixmap = 0; 3087 buf_pixmap = 0;
3088 } 3088 }
3089 3089
3090 return lastFormatted; 3090 return lastFormatted;
3091} 3091}
3092 3092
3093/* 3093/*
3094 #### this function only sets the default font size in the format collection 3094 #### this function only sets the default font size in the format collection
3095 */ 3095 */
3096void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color ) 3096void QTextDocument::setDefaultFormat( const QFont &font, const QColor &color )
3097{ 3097{
3098 bool reformat = font != fCollection->defaultFormat()->font(); 3098 bool reformat = font != fCollection->defaultFormat()->font();
3099 for ( QTextDocument *d = childList.first(); d; d = childList.next() ) 3099 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
3100 d->setDefaultFormat( font, color ); 3100 d->setDefaultFormat( font, color );
3101 fCollection->updateDefaultFormat( font, color, sheet_ ); 3101 fCollection->updateDefaultFormat( font, color, sheet_ );
3102 3102
3103 if ( !reformat ) 3103 if ( !reformat )
3104 return; 3104 return;
3105 tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8; 3105 tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
3106 3106
3107 // invalidate paragraphs and custom items 3107 // invalidate paragraphs and custom items
3108 QTextParagraph *p = fParag; 3108 QTextParagraph *p = fParag;
3109 while ( p ) { 3109 while ( p ) {
3110 p->invalidate( 0 ); 3110 p->invalidate( 0 );
3111 for ( int i = 0; i < p->length() - 1; ++i ) 3111 for ( int i = 0; i < p->length() - 1; ++i )
3112 if ( p->at( i )->isCustom() ) 3112 if ( p->at( i )->isCustom() )
3113 p->at( i )->customItem()->invalidate(); 3113 p->at( i )->customItem()->invalidate();
3114 p = p->next(); 3114 p = p->next();
3115 } 3115 }
3116} 3116}
3117 3117
3118void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p ) 3118void QTextDocument::registerCustomItem( QTextCustomItem *i, QTextParagraph *p )
3119{ 3119{
3120 if ( i && i->placement() != QTextCustomItem::PlaceInline ) { 3120 if ( i && i->placement() != QTextCustomItem::PlaceInline ) {
3121 flow_->registerFloatingItem( i ); 3121 flow_->registerFloatingItem( i );
3122 p->registerFloatingItem( i ); 3122 p->registerFloatingItem( i );
3123 i->setParagraph( p ); 3123 i->setParagraph( p );
3124 } 3124 }
3125 p->mightHaveCustomItems = mightHaveCustomItems = TRUE; 3125 p->mightHaveCustomItems = mightHaveCustomItems = TRUE;
3126} 3126}
3127 3127
3128void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p ) 3128void QTextDocument::unregisterCustomItem( QTextCustomItem *i, QTextParagraph *p )
3129{ 3129{
3130 flow_->unregisterFloatingItem( i ); 3130 flow_->unregisterFloatingItem( i );
3131 p->unregisterFloatingItem( i ); 3131 p->unregisterFloatingItem( i );
3132 i->setParagraph( 0 ); 3132 i->setParagraph( 0 );
3133} 3133}
3134 3134
3135bool QTextDocument::hasFocusParagraph() const 3135bool QTextDocument::hasFocusParagraph() const
3136{ 3136{
3137 return !!focusIndicator.parag; 3137 return !!focusIndicator.parag;
3138} 3138}
3139 3139
3140QString QTextDocument::focusHref() const 3140QString QTextDocument::focusHref() const
3141{ 3141{
3142 return focusIndicator.href; 3142 return focusIndicator.href;
3143} 3143}
3144 3144
3145bool QTextDocument::focusNextPrevChild( bool next ) 3145bool QTextDocument::focusNextPrevChild( bool next )
3146{ 3146{
3147 if ( !focusIndicator.parag ) { 3147 if ( !focusIndicator.parag ) {
3148 if ( next ) { 3148 if ( next ) {
3149 focusIndicator.parag = fParag; 3149 focusIndicator.parag = fParag;
3150 focusIndicator.start = 0; 3150 focusIndicator.start = 0;
3151 focusIndicator.len = 0; 3151 focusIndicator.len = 0;
3152 } else { 3152 } else {
3153 focusIndicator.parag = lParag; 3153 focusIndicator.parag = lParag;
3154 focusIndicator.start = lParag->length(); 3154 focusIndicator.start = lParag->length();
3155 focusIndicator.len = 0; 3155 focusIndicator.len = 0;
3156 } 3156 }
3157 } else { 3157 } else {
3158 focusIndicator.parag->setChanged( TRUE ); 3158 focusIndicator.parag->setChanged( TRUE );
3159 } 3159 }
3160 focusIndicator.href = QString::null; 3160 focusIndicator.href = QString::null;
3161 3161
3162 if ( next ) { 3162 if ( next ) {
3163 QTextParagraph *p = focusIndicator.parag; 3163 QTextParagraph *p = focusIndicator.parag;
3164 int index = focusIndicator.start + focusIndicator.len; 3164 int index = focusIndicator.start + focusIndicator.len;
3165 while ( p ) { 3165 while ( p ) {
3166 for ( int i = index; i < p->length(); ++i ) { 3166 for ( int i = index; i < p->length(); ++i ) {
3167 if ( p->at( i )->isAnchor() ) { 3167 if ( p->at( i )->isAnchor() ) {
3168 p->setChanged( TRUE ); 3168 p->setChanged( TRUE );
3169 focusIndicator.parag = p; 3169 focusIndicator.parag = p;
3170 focusIndicator.start = i; 3170 focusIndicator.start = i;
3171 focusIndicator.len = 0; 3171 focusIndicator.len = 0;
3172 focusIndicator.href = p->at( i )->anchorHref(); 3172 focusIndicator.href = p->at( i )->anchorHref();
3173 while ( i < p->length() ) { 3173 while ( i < p->length() ) {
3174 if ( !p->at( i )->isAnchor() ) 3174 if ( !p->at( i )->isAnchor() )
3175 return TRUE; 3175 return TRUE;
3176 focusIndicator.len++; 3176 focusIndicator.len++;
3177 i++; 3177 i++;
3178 } 3178 }
3179 } else if ( p->at( i )->isCustom() ) { 3179 } else if ( p->at( i )->isCustom() ) {
3180 if ( p->at( i )->customItem()->isNested() ) { 3180 if ( p->at( i )->customItem()->isNested() ) {
3181 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 3181 QTextTable *t = (QTextTable*)p->at( i )->customItem();
3182 QPtrList<QTextTableCell> cells = t->tableCells(); 3182 QPtrList<QTextTableCell> cells = t->tableCells();
3183 // first try to continue 3183 // first try to continue
3184 QTextTableCell *c; 3184 QTextTableCell *c;
3185 bool resetCells = TRUE; 3185 bool resetCells = TRUE;
3186 for ( c = cells.first(); c; c = cells.next() ) { 3186 for ( c = cells.first(); c; c = cells.next() ) {
3187 if ( c->richText()->hasFocusParagraph() ) { 3187 if ( c->richText()->hasFocusParagraph() ) {
3188 if ( c->richText()->focusNextPrevChild( next ) ) { 3188 if ( c->richText()->focusNextPrevChild( next ) ) {
3189 p->setChanged( TRUE ); 3189 p->setChanged( TRUE );
3190 focusIndicator.parag = p; 3190 focusIndicator.parag = p;
3191 focusIndicator.start = i; 3191 focusIndicator.start = i;
3192 focusIndicator.len = 0; 3192 focusIndicator.len = 0;
3193 focusIndicator.href = c->richText()->focusHref(); 3193 focusIndicator.href = c->richText()->focusHref();
3194 return TRUE; 3194 return TRUE;
3195 } else { 3195 } else {
3196 resetCells = FALSE; 3196 resetCells = FALSE;
3197 c = cells.next(); 3197 c = cells.next();
3198 break; 3198 break;
3199 } 3199 }
3200 } 3200 }
3201 } 3201 }
3202 // now really try 3202 // now really try
3203 if ( resetCells ) 3203 if ( resetCells )
3204 c = cells.first(); 3204 c = cells.first();
3205 for ( ; c; c = cells.next() ) { 3205 for ( ; c; c = cells.next() ) {
3206 if ( c->richText()->focusNextPrevChild( next ) ) { 3206 if ( c->richText()->focusNextPrevChild( next ) ) {
3207 p->setChanged( TRUE ); 3207 p->setChanged( TRUE );
3208 focusIndicator.parag = p; 3208 focusIndicator.parag = p;
3209 focusIndicator.start = i; 3209 focusIndicator.start = i;
3210 focusIndicator.len = 0; 3210 focusIndicator.len = 0;
3211 focusIndicator.href = c->richText()->focusHref(); 3211 focusIndicator.href = c->richText()->focusHref();
3212 return TRUE; 3212 return TRUE;
3213 } 3213 }
3214 } 3214 }
3215 } 3215 }
3216 } 3216 }
3217 } 3217 }
3218 index = 0; 3218 index = 0;
3219 p = p->next(); 3219 p = p->next();
3220 } 3220 }
3221 } else { 3221 } else {
3222 QTextParagraph *p = focusIndicator.parag; 3222 QTextParagraph *p = focusIndicator.parag;
3223 int index = focusIndicator.start - 1; 3223 int index = focusIndicator.start - 1;
3224 if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 ) 3224 if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 )
3225 index++; 3225 index++;
3226 while ( p ) { 3226 while ( p ) {
3227 for ( int i = index; i >= 0; --i ) { 3227 for ( int i = index; i >= 0; --i ) {
3228 if ( p->at( i )->isAnchor() ) { 3228 if ( p->at( i )->isAnchor() ) {
3229 p->setChanged( TRUE ); 3229 p->setChanged( TRUE );
3230 focusIndicator.parag = p; 3230 focusIndicator.parag = p;
3231 focusIndicator.start = i; 3231 focusIndicator.start = i;
3232 focusIndicator.len = 0; 3232 focusIndicator.len = 0;
3233 focusIndicator.href = p->at( i )->anchorHref(); 3233 focusIndicator.href = p->at( i )->anchorHref();
3234 while ( i >= -1 ) { 3234 while ( i >= -1 ) {
3235 if ( i < 0 || !p->at( i )->isAnchor() ) { 3235 if ( i < 0 || !p->at( i )->isAnchor() ) {
3236 focusIndicator.start++; 3236 focusIndicator.start++;
3237 return TRUE; 3237 return TRUE;
3238 } 3238 }
3239 if ( i < 0 ) 3239 if ( i < 0 )
3240 break; 3240 break;
3241 focusIndicator.len++; 3241 focusIndicator.len++;
3242 focusIndicator.start--; 3242 focusIndicator.start--;
3243 i--; 3243 i--;
3244 } 3244 }
3245 } else if ( p->at( i )->isCustom() ) { 3245 } else if ( p->at( i )->isCustom() ) {
3246 if ( p->at( i )->customItem()->isNested() ) { 3246 if ( p->at( i )->customItem()->isNested() ) {
3247 QTextTable *t = (QTextTable*)p->at( i )->customItem(); 3247 QTextTable *t = (QTextTable*)p->at( i )->customItem();
3248 QPtrList<QTextTableCell> cells = t->tableCells(); 3248 QPtrList<QTextTableCell> cells = t->tableCells();
3249 // first try to continue 3249 // first try to continue
3250 QTextTableCell *c; 3250 QTextTableCell *c;
3251 bool resetCells = TRUE; 3251 bool resetCells = TRUE;
3252 for ( c = cells.last(); c; c = cells.prev() ) { 3252 for ( c = cells.last(); c; c = cells.prev() ) {
3253 if ( c->richText()->hasFocusParagraph() ) { 3253 if ( c->richText()->hasFocusParagraph() ) {
3254 if ( c->richText()->focusNextPrevChild( next ) ) { 3254 if ( c->richText()->focusNextPrevChild( next ) ) {
3255 p->setChanged( TRUE ); 3255 p->setChanged( TRUE );
3256 focusIndicator.parag = p; 3256 focusIndicator.parag = p;
3257 focusIndicator.start = i; 3257 focusIndicator.start = i;
3258 focusIndicator.len = 0; 3258 focusIndicator.len = 0;
3259 focusIndicator.href = c->richText()->focusHref(); 3259 focusIndicator.href = c->richText()->focusHref();
3260 return TRUE; 3260 return TRUE;
3261 } else { 3261 } else {
3262 resetCells = FALSE; 3262 resetCells = FALSE;
3263 c = cells.prev(); 3263 c = cells.prev();
3264 break; 3264 break;
3265 } 3265 }
3266 } 3266 }
3267 if ( cells.at() == 0 ) 3267 if ( cells.at() == 0 )
3268 break; 3268 break;
3269 } 3269 }
3270 // now really try 3270 // now really try
3271 if ( resetCells ) 3271 if ( resetCells )
3272 c = cells.last(); 3272 c = cells.last();
3273 for ( ; c; c = cells.prev() ) { 3273 for ( ; c; c = cells.prev() ) {
3274 if ( c->richText()->focusNextPrevChild( next ) ) { 3274 if ( c->richText()->focusNextPrevChild( next ) ) {
3275 p->setChanged( TRUE ); 3275 p->setChanged( TRUE );
3276 focusIndicator.parag = p; 3276 focusIndicator.parag = p;
3277 focusIndicator.start = i; 3277 focusIndicator.start = i;
3278 focusIndicator.len = 0; 3278 focusIndicator.len = 0;
3279 focusIndicator.href = c->richText()->focusHref(); 3279 focusIndicator.href = c->richText()->focusHref();
3280 return TRUE; 3280 return TRUE;
3281 } 3281 }
3282 if ( cells.at() == 0 ) 3282 if ( cells.at() == 0 )
3283 break; 3283 break;
3284 } 3284 }
3285 } 3285 }
3286 } 3286 }
3287 } 3287 }
3288 p = p->prev(); 3288 p = p->prev();
3289 if ( p ) 3289 if ( p )
3290 index = p->length() - 1; 3290 index = p->length() - 1;
3291 } 3291 }
3292 } 3292 }
3293 3293
3294 focusIndicator.parag = 0; 3294 focusIndicator.parag = 0;
3295 3295
3296 return FALSE; 3296 return FALSE;
3297} 3297}
3298 3298
3299int QTextDocument::length() const 3299int QTextDocument::length() const
3300{ 3300{
3301 int l = 0; 3301 int l = 0;
3302 QTextParagraph *p = fParag; 3302 QTextParagraph *p = fParag;
3303 while ( p ) { 3303 while ( p ) {
3304 l += p->length() - 1; // don't count trailing space 3304 l += p->length() - 1; // don't count trailing space
3305 p = p->next(); 3305 p = p->next();
3306 } 3306 }
3307 return l; 3307 return l;
3308} 3308}
3309 3309
3310// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3310// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3311 3311
3312int QTextFormat::width( const QChar &c ) const 3312int QTextFormat::width( const QChar &c ) const
3313{ 3313{
3314 if ( c.unicode() == 0xad ) // soft hyphen 3314 if ( c.unicode() == 0xad ) // soft hyphen
3315 return 0; 3315 return 0;
3316 if ( !pntr || !pntr->isActive() ) { 3316 if ( !pntr || !pntr->isActive() ) {
3317 if ( c == '\t' ) 3317 if ( c == '\t' )
3318 return fm.width( 'x' ) * 8; 3318 return fm.width( 'x' ) * 8;
3319 if ( ha == AlignNormal ) { 3319 if ( ha == AlignNormal ) {
3320 int w; 3320 int w;
3321 if ( c.row() ) 3321 if ( c.row() )
3322 w = fm.width( c ); 3322 w = fm.width( c );
3323 else 3323 else
3324 w = widths[ c.unicode() ]; 3324 w = widths[ c.unicode() ];
3325 if ( w == 0 && !c.row() ) { 3325 if ( w == 0 && !c.row() ) {
3326 w = fm.width( c ); 3326 w = fm.width( c );
3327 ( (QTextFormat*)this )->widths[ c.unicode() ] = w; 3327 ( (QTextFormat*)this )->widths[ c.unicode() ] = w;
3328 } 3328 }
3329 return w; 3329 return w;
3330 } else { 3330 } else {
3331 QFont f( fn ); 3331 QFont f( fn );
3332 if ( usePixelSizes ) 3332 if ( usePixelSizes )
3333 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); 3333 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
3334 else 3334 else
3335 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 3335 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
3336 QFontMetrics fm_( f ); 3336 QFontMetrics fm_( f );
3337 return fm_.width( c ); 3337 return fm_.width( c );
3338 } 3338 }
3339 } 3339 }
3340 3340
3341 QFont f( fn ); 3341 QFont f( fn );
3342 if ( ha != AlignNormal ) { 3342 if ( ha != AlignNormal ) {
3343 if ( usePixelSizes ) 3343 if ( usePixelSizes )
3344 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); 3344 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
3345 else 3345 else
3346 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 3346 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
3347 } 3347 }
3348 pntr->setFont( f ); 3348 pntr->setFont( f );
3349 3349
3350 return pntr->fontMetrics().width( c ); 3350 return pntr->fontMetrics().width( c );
3351} 3351}
3352 3352
3353int QTextFormat::width( const QString &str, int pos ) const 3353int QTextFormat::width( const QString &str, int pos ) const
3354{ 3354{
3355 int w = 0; 3355 int w = 0;
3356 if ( str[ pos ].unicode() == 0xad ) 3356 if ( str[ pos ].unicode() == 0xad )
3357 return w; 3357 return w;
3358 if ( !pntr || !pntr->isActive() ) { 3358 if ( !pntr || !pntr->isActive() ) {
3359 if ( ha == AlignNormal ) { 3359 if ( ha == AlignNormal ) {
3360 w = fm.width( str[ pos ] ); 3360 w = fm.width( str[ pos ] );
3361 } else { 3361 } else {
3362 QFont f( fn ); 3362 QFont f( fn );
3363 if ( usePixelSizes ) 3363 if ( usePixelSizes )
3364 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); 3364 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
3365 else 3365 else
3366 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 3366 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
3367 QFontMetrics fm_( f ); 3367 QFontMetrics fm_( f );
3368 w = fm_.width( str[ pos ] ); 3368 w = fm_.width( str[ pos ] );
3369 } 3369 }
3370 } else { 3370 } else {
3371 QFont f( fn ); 3371 QFont f( fn );
3372 if ( ha != AlignNormal ) { 3372 if ( ha != AlignNormal ) {
3373 if ( usePixelSizes ) 3373 if ( usePixelSizes )
3374 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); 3374 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
3375 else 3375 else
3376 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 3376 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
3377 } 3377 }
3378 pntr->setFont( f ); 3378 pntr->setFont( f );
3379 w = pntr->fontMetrics().width( str[ pos ] ); 3379 w = pntr->fontMetrics().width( str[ pos ] );
3380 } 3380 }
3381 return w; 3381 return w;
3382} 3382}
3383 3383
3384// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3384// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3385 3385
3386QTextString::QTextString() 3386QTextString::QTextString()
3387{ 3387{
3388 bidiDirty = FALSE; 3388 bidiDirty = FALSE;
3389 bidi = FALSE; 3389 bidi = FALSE;
3390 rightToLeft = FALSE; 3390 rightToLeft = FALSE;
3391 dir = QChar::DirON; 3391 dir = QChar::DirON;
3392} 3392}
3393 3393
3394QTextString::QTextString( const QTextString &s ) 3394QTextString::QTextString( const QTextString &s )
3395{ 3395{
3396 bidiDirty = s.bidiDirty; 3396 bidiDirty = s.bidiDirty;
3397 bidi = s.bidi; 3397 bidi = s.bidi;
3398 rightToLeft = s.rightToLeft; 3398 rightToLeft = s.rightToLeft;
3399 dir = s.dir; 3399 dir = s.dir;
3400 data = s.subString(); 3400 data = s.subString();
3401} 3401}
3402 3402
3403void QTextString::insert( int index, const QString &s, QTextFormat *f ) 3403void QTextString::insert( int index, const QString &s, QTextFormat *f )
3404{ 3404{
3405 insert( index, s.unicode(), s.length(), f ); 3405 insert( index, s.unicode(), s.length(), f );
3406} 3406}
3407 3407
3408void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f ) 3408void QTextString::insert( int index, const QChar *unicode, int len, QTextFormat *f )
3409{ 3409{
3410 int os = data.size(); 3410 int os = data.size();
3411 data.resize( data.size() + len ); 3411 data.resize( data.size() + len );
3412 if ( index < os ) { 3412 if ( index < os ) {
3413 memmove( data.data() + index + len, data.data() + index, 3413 memmove( data.data() + index + len, data.data() + index,
3414 sizeof( QTextStringChar ) * ( os - index ) ); 3414 sizeof( QTextStringChar ) * ( os - index ) );
3415 } 3415 }
3416 for ( int i = 0; i < len; ++i ) { 3416 for ( int i = 0; i < len; ++i ) {
3417 data[ (int)index + i ].x = 0; 3417 data[ (int)index + i ].x = 0;
3418 data[ (int)index + i ].lineStart = 0; 3418 data[ (int)index + i ].lineStart = 0;
3419 data[ (int)index + i ].d.format = 0; 3419 data[ (int)index + i ].d.format = 0;
3420 data[ (int)index + i ].type = QTextStringChar::Regular; 3420 data[ (int)index + i ].type = QTextStringChar::Regular;
3421 data[ (int)index + i ].rightToLeft = 0; 3421 data[ (int)index + i ].rightToLeft = 0;
3422 data[ (int)index + i ].startOfRun = 0; 3422 data[ (int)index + i ].startOfRun = 0;
3423 data[ (int)index + i ].c = unicode[i]; 3423 data[ (int)index + i ].c = unicode[i];
3424 data[ (int)index + i ].setFormat( f ); 3424 data[ (int)index + i ].setFormat( f );
3425 } 3425 }
3426 bidiDirty = TRUE; 3426 bidiDirty = TRUE;
3427} 3427}
3428 3428
3429QTextString::~QTextString() 3429QTextString::~QTextString()
3430{ 3430{
3431 clear(); 3431 clear();
3432} 3432}
3433 3433
3434void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat ) 3434void QTextString::insert( int index, QTextStringChar *c, bool doAddRefFormat )
3435{ 3435{
3436 int os = data.size(); 3436 int os = data.size();
3437 data.resize( data.size() + 1 ); 3437 data.resize( data.size() + 1 );
3438 if ( index < os ) { 3438 if ( index < os ) {
3439 memmove( data.data() + index + 1, data.data() + index, 3439 memmove( data.data() + index + 1, data.data() + index,
3440 sizeof( QTextStringChar ) * ( os - index ) ); 3440 sizeof( QTextStringChar ) * ( os - index ) );
3441 } 3441 }
3442 data[ (int)index ].c = c->c; 3442 data[ (int)index ].c = c->c;
3443 data[ (int)index ].x = 0; 3443 data[ (int)index ].x = 0;
3444 data[ (int)index ].lineStart = 0; 3444 data[ (int)index ].lineStart = 0;
3445 data[ (int)index ].rightToLeft = 0; 3445 data[ (int)index ].rightToLeft = 0;
3446 data[ (int)index ].d.format = 0; 3446 data[ (int)index ].d.format = 0;
3447 data[ (int)index ].type = QTextStringChar::Regular; 3447 data[ (int)index ].type = QTextStringChar::Regular;
3448 if ( doAddRefFormat && c->format() ) 3448 if ( doAddRefFormat && c->format() )
3449 c->format()->addRef(); 3449 c->format()->addRef();
3450 data[ (int)index ].setFormat( c->format() ); 3450 data[ (int)index ].setFormat( c->format() );
3451 bidiDirty = TRUE; 3451 bidiDirty = TRUE;
3452} 3452}
3453 3453
3454void QTextString::truncate( int index ) 3454void QTextString::truncate( int index )
3455{ 3455{
3456 index = QMAX( index, 0 ); 3456 index = QMAX( index, 0 );
3457 index = QMIN( index, (int)data.size() - 1 ); 3457 index = QMIN( index, (int)data.size() - 1 );
3458 if ( index < (int)data.size() ) { 3458 if ( index < (int)data.size() ) {
3459 for ( int i = index + 1; i < (int)data.size(); ++i ) { 3459 for ( int i = index + 1; i < (int)data.size(); ++i ) {
3460 if ( !(data[ i ].type == QTextStringChar::Regular) ) { 3460 if ( !(data[ i ].type == QTextStringChar::Regular) ) {
3461 delete data[ i ].customItem(); 3461 delete data[ i ].customItem();
3462 if ( data[ i ].d.custom->format ) 3462 if ( data[ i ].d.custom->format )
3463 data[ i ].d.custom->format->removeRef(); 3463 data[ i ].d.custom->format->removeRef();
3464 delete data[ i ].d.custom; 3464 delete data[ i ].d.custom;
3465 data[ i ].d.custom = 0; 3465 data[ i ].d.custom = 0;
3466 } else if ( data[ i ].format() ) { 3466 } else if ( data[ i ].format() ) {
3467 data[ i ].format()->removeRef(); 3467 data[ i ].format()->removeRef();
3468 } 3468 }
3469 } 3469 }
3470 } 3470 }
3471 data.truncate( index ); 3471 data.truncate( index );
3472 bidiDirty = TRUE; 3472 bidiDirty = TRUE;
3473} 3473}
3474 3474
3475void QTextString::remove( int index, int len ) 3475void QTextString::remove( int index, int len )
3476{ 3476{
3477 for ( int i = index; i < (int)data.size() && i - index < len; ++i ) { 3477 for ( int i = index; i < (int)data.size() && i - index < len; ++i ) {
3478 if ( !(data[ i ].type == QTextStringChar::Regular) ) { 3478 if ( !(data[ i ].type == QTextStringChar::Regular) ) {
3479 delete data[ i ].customItem(); 3479 delete data[ i ].customItem();
3480 if ( data[ i ].d.custom->format ) 3480 if ( data[ i ].d.custom->format )
3481 data[ i ].d.custom->format->removeRef(); 3481 data[ i ].d.custom->format->removeRef();
3482 delete data[ i ].d.custom; 3482 delete data[ i ].d.custom;
3483 data[ i ].d.custom = 0; 3483 data[ i ].d.custom = 0;
3484 } else if ( data[ i ].format() ) { 3484 } else if ( data[ i ].format() ) {
3485 data[ i ].format()->removeRef(); 3485 data[ i ].format()->removeRef();
3486 } 3486 }
3487 } 3487 }
3488 memmove( data.data() + index, data.data() + index + len, 3488 memmove( data.data() + index, data.data() + index + len,
3489 sizeof( QTextStringChar ) * ( data.size() - index - len ) ); 3489 sizeof( QTextStringChar ) * ( data.size() - index - len ) );
3490 data.resize( data.size() - len ); 3490 data.resize( data.size() - len );
3491 bidiDirty = TRUE; 3491 bidiDirty = TRUE;
3492} 3492}
3493 3493
3494void QTextString::clear() 3494void QTextString::clear()
3495{ 3495{
3496 for ( int i = 0; i < (int)data.count(); ++i ) { 3496 for ( int i = 0; i < (int)data.count(); ++i ) {
3497 if ( !(data[ i ].type == QTextStringChar::Regular) ) { 3497 if ( !(data[ i ].type == QTextStringChar::Regular) ) {
3498 delete data[ i ].customItem(); 3498 delete data[ i ].customItem();
3499 if ( data[ i ].d.custom->format ) 3499 if ( data[ i ].d.custom->format )
3500 data[ i ].d.custom->format->removeRef(); 3500 data[ i ].d.custom->format->removeRef();
3501 delete data[ i ].d.custom; 3501 delete data[ i ].d.custom;
3502 data[ i ].d.custom = 0; 3502 data[ i ].d.custom = 0;
3503 } else if ( data[ i ].format() ) { 3503 } else if ( data[ i ].format() ) {
3504 data[ i ].format()->removeRef(); 3504 data[ i ].format()->removeRef();
3505 } 3505 }
3506 } 3506 }
3507 data.resize( 0 ); 3507 data.resize( 0 );
3508} 3508}
3509 3509
3510void QTextString::setFormat( int index, QTextFormat *f, bool useCollection ) 3510void QTextString::setFormat( int index, QTextFormat *f, bool useCollection )
3511{ 3511{
3512 if ( useCollection && data[ index ].format() ) 3512 if ( useCollection && data[ index ].format() )
3513 data[ index ].format()->removeRef(); 3513 data[ index ].format()->removeRef();
3514 data[ index ].setFormat( f ); 3514 data[ index ].setFormat( f );
3515} 3515}
3516 3516
3517void QTextString::checkBidi() const 3517void QTextString::checkBidi() const
3518{ 3518{
3519 bool rtlKnown = FALSE; 3519 bool rtlKnown = FALSE;
3520 if ( dir == QChar::DirR ) { 3520 if ( dir == QChar::DirR ) {
3521 ((QTextString *)this)->bidi = TRUE; 3521 ((QTextString *)this)->bidi = TRUE;
3522 ((QTextString *)this)->rightToLeft = TRUE; 3522 ((QTextString *)this)->rightToLeft = TRUE;
3523 rtlKnown = TRUE; 3523 rtlKnown = TRUE;
3524 return; 3524 return;
3525 } else if ( dir == QChar::DirL ) { 3525 } else if ( dir == QChar::DirL ) {
3526 ((QTextString *)this)->rightToLeft = FALSE; 3526 ((QTextString *)this)->rightToLeft = FALSE;
3527 rtlKnown = TRUE; 3527 rtlKnown = TRUE;
3528 } else { 3528 } else {
3529 ((QTextString *)this)->rightToLeft = FALSE; 3529 ((QTextString *)this)->rightToLeft = FALSE;
3530 } 3530 }
3531 3531
3532 int len = data.size(); 3532 int len = data.size();
3533 const QTextStringChar *c = data.data(); 3533 const QTextStringChar *c = data.data();
3534 ((QTextString *)this)->bidi = FALSE; 3534 ((QTextString *)this)->bidi = FALSE;
3535 while( len ) { 3535 while( len ) {
3536 if ( !rtlKnown ) { 3536 if ( !rtlKnown ) {
3537 switch( c->c.direction() ) 3537 switch( c->c.direction() )
3538 { 3538 {
3539 case QChar::DirL: 3539 case QChar::DirL:
3540 case QChar::DirLRO: 3540 case QChar::DirLRO:
3541 case QChar::DirLRE: 3541 case QChar::DirLRE:
3542 ((QTextString *)this)->rightToLeft = FALSE; 3542 ((QTextString *)this)->rightToLeft = FALSE;
3543 rtlKnown = TRUE; 3543 rtlKnown = TRUE;
3544 break; 3544 break;
3545 case QChar::DirR: 3545 case QChar::DirR:
3546 case QChar::DirAL: 3546 case QChar::DirAL:
3547 case QChar::DirRLO: 3547 case QChar::DirRLO:
3548 case QChar::DirRLE: 3548 case QChar::DirRLE:
3549 ((QTextString *)this)->rightToLeft = TRUE; 3549 ((QTextString *)this)->rightToLeft = TRUE;
3550 rtlKnown = TRUE; 3550 rtlKnown = TRUE;
3551 break; 3551 break;
3552 default: 3552 default:
3553 break; 3553 break;
3554 } 3554 }
3555 } 3555 }
3556 uchar row = c->c.row(); 3556 uchar row = c->c.row();
3557 if( (row > 0x04 && row < 0x09) || (row > 0xfa && row < 0xff) ) { 3557 if( (row > 0x04 && row < 0x09) || (row > 0xfa && row < 0xff) ) {
3558 ((QTextString *)this)->bidi = TRUE; 3558 ((QTextString *)this)->bidi = TRUE;
3559 if ( rtlKnown ) 3559 if ( rtlKnown )
3560 return; 3560 return;
3561 } 3561 }
3562 len--; 3562 len--;
3563 ++c; 3563 ++c;
3564 } 3564 }
3565} 3565}
3566 3566
3567void QTextDocument::setStyleSheet( QStyleSheet *s ) 3567void QTextDocument::setStyleSheet( QStyleSheet *s )
3568{ 3568{
3569 if ( !s ) 3569 if ( !s )
3570 return; 3570 return;
3571 sheet_ = s; 3571 sheet_ = s;
3572 list_tm = list_bm = par_tm = par_bm = 12; 3572 list_tm = list_bm = par_tm = par_bm = 12;
3573 list_lm = 40; 3573 list_lm = 40;
3574 li_tm = li_bm = 0; 3574 li_tm = li_bm = 0;
3575 QStyleSheetItem* item = s->item( "ol" ); 3575 QStyleSheetItem* item = s->item( "ol" );
3576 if ( item ) { 3576 if ( item ) {
3577 list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); 3577 list_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop ));
3578 list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); 3578 list_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom ));
3579 list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft )); 3579 list_lm = QMAX(0,item->margin( QStyleSheetItem::MarginLeft ));
3580 } 3580 }
3581 if ( (item = s->item( "li" ) ) ) { 3581 if ( (item = s->item( "li" ) ) ) {
3582 li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); 3582 li_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop ));
3583 li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); 3583 li_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom ));
3584 } 3584 }
3585 if ( (item = s->item( "p" ) ) ) { 3585 if ( (item = s->item( "p" ) ) ) {
3586 par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop )); 3586 par_tm = QMAX(0,item->margin( QStyleSheetItem::MarginTop ));
3587 par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom )); 3587 par_bm = QMAX(0,item->margin( QStyleSheetItem::MarginBottom ));
3588 } 3588 }
3589} 3589}
3590 3590
3591void QTextDocument::setUnderlineLinks( bool b ) { 3591void QTextDocument::setUnderlineLinks( bool b ) {
3592 underlLinks = b; 3592 underlLinks = b;
3593 for ( QTextDocument *d = childList.first(); d; d = childList.next() ) 3593 for ( QTextDocument *d = childList.first(); d; d = childList.next() )
3594 d->setUnderlineLinks( b ); 3594 d->setUnderlineLinks( b );
3595} 3595}
3596 3596
3597void QTextStringChar::setFormat( QTextFormat *f ) 3597void QTextStringChar::setFormat( QTextFormat *f )
3598{ 3598{
3599 if ( type == Regular ) { 3599 if ( type == Regular ) {
3600 d.format = f; 3600 d.format = f;
3601 } else { 3601 } else {
3602 if ( !d.custom ) { 3602 if ( !d.custom ) {
3603 d.custom = new CustomData; 3603 d.custom = new CustomData;
3604 d.custom->custom = 0; 3604 d.custom->custom = 0;
3605 } 3605 }
3606 d.custom->format = f; 3606 d.custom->format = f;
3607 } 3607 }
3608} 3608}
3609 3609
3610void QTextStringChar::setCustomItem( QTextCustomItem *i ) 3610void QTextStringChar::setCustomItem( QTextCustomItem *i )
3611{ 3611{
3612 if ( type == Regular ) { 3612 if ( type == Regular ) {
3613 QTextFormat *f = format(); 3613 QTextFormat *f = format();
3614 d.custom = new CustomData; 3614 d.custom = new CustomData;
3615 d.custom->format = f; 3615 d.custom->format = f;
3616 } else { 3616 } else {
3617 delete d.custom->custom; 3617 delete d.custom->custom;
3618 } 3618 }
3619 d.custom->custom = i; 3619 d.custom->custom = i;
3620 type = (type == Anchor ? CustomAnchor : Custom); 3620 type = (type == Anchor ? CustomAnchor : Custom);
3621} 3621}
3622 3622
3623void QTextStringChar::loseCustomItem() 3623void QTextStringChar::loseCustomItem()
3624{ 3624{
3625 if ( type == Custom ) { 3625 if ( type == Custom ) {
3626 QTextFormat *f = d.custom->format; 3626 QTextFormat *f = d.custom->format;
3627 d.custom->custom = 0; 3627 d.custom->custom = 0;
3628 delete d.custom; 3628 delete d.custom;
3629 type = Regular; 3629 type = Regular;
3630 d.format = f; 3630 d.format = f;
3631 } else if ( type == CustomAnchor ) { 3631 } else if ( type == CustomAnchor ) {
3632 d.custom->custom = 0; 3632 d.custom->custom = 0;
3633 type = Anchor; 3633 type = Anchor;
3634 } 3634 }
3635} 3635}
3636 3636
3637QString QTextStringChar::anchorName() const 3637QString QTextStringChar::anchorName() const
3638{ 3638{
3639 if ( type == Regular ) 3639 if ( type == Regular )
3640 return QString::null; 3640 return QString::null;
3641 else 3641 else
3642 return d.custom->anchorName; 3642 return d.custom->anchorName;
3643} 3643}
3644 3644
3645QString QTextStringChar::anchorHref() const 3645QString QTextStringChar::anchorHref() const
3646{ 3646{
3647 if ( type == Regular ) 3647 if ( type == Regular )
3648 return QString::null; 3648 return QString::null;
3649 else 3649 else
3650 return d.custom->anchorHref; 3650 return d.custom->anchorHref;
3651} 3651}
3652 3652
3653void QTextStringChar::setAnchor( const QString& name, const QString& href ) 3653void QTextStringChar::setAnchor( const QString& name, const QString& href )
3654{ 3654{
3655 if ( type == Regular ) { 3655 if ( type == Regular ) {
3656 QTextFormat *f = format(); 3656 QTextFormat *f = format();
3657 d.custom = new CustomData; 3657 d.custom = new CustomData;
3658 d.custom->custom = 0; 3658 d.custom->custom = 0;
3659 d.custom->format = f; 3659 d.custom->format = f;
3660 type = Anchor; 3660 type = Anchor;
3661 } else if ( type == Custom ) { 3661 } else if ( type == Custom ) {
3662 type = CustomAnchor; 3662 type = CustomAnchor;
3663 } 3663 }
3664 d.custom->anchorName = name; 3664 d.custom->anchorName = name;
3665 d.custom->anchorHref = href; 3665 d.custom->anchorHref = href;
3666} 3666}
3667 3667
3668 3668
3669int QTextString::width( int idx ) const 3669int QTextString::width( int idx ) const
3670{ 3670{
3671 int w = 0; 3671 int w = 0;
3672 QTextStringChar *c = &at( idx ); 3672 QTextStringChar *c = &at( idx );
3673 if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 ) 3673 if ( c->c.unicode() == 0xad || c->c.unicode() == 0x2028 )
3674 return 0; 3674 return 0;
3675 if( c->isCustom() ) { 3675 if( c->isCustom() ) {
3676 if( c->customItem()->placement() == QTextCustomItem::PlaceInline ) 3676 if( c->customItem()->placement() == QTextCustomItem::PlaceInline )
3677 w = c->customItem()->width; 3677 w = c->customItem()->width;
3678 } else { 3678 } else {
3679 int r = c->c.row(); 3679 int r = c->c.row();
3680 if( r < 0x06 || r > 0x1f ) 3680 if( r < 0x06 || r > 0x1f )
3681 w = c->format()->width( c->c ); 3681 w = c->format()->width( c->c );
3682 else { 3682 else {
3683 // complex text. We need some hacks to get the right metric here 3683 // complex text. We need some hacks to get the right metric here
3684 QString str; 3684 QString str;
3685 int pos = 0; 3685 int pos = 0;
3686 if( idx > 4 ) 3686 if( idx > 4 )
3687 pos = idx - 4; 3687 pos = idx - 4;
3688 int off = idx - pos; 3688 int off = idx - pos;
3689 int end = QMIN( length(), idx + 4 ); 3689 int end = QMIN( length(), idx + 4 );
3690 while ( pos < end ) { 3690 while ( pos < end ) {
3691 str += at(pos).c; 3691 str += at(pos).c;
3692 pos++; 3692 pos++;
3693 } 3693 }
3694 w = c->format()->width( str, off ); 3694 w = c->format()->width( str, off );
3695 } 3695 }
3696 } 3696 }
3697 return w; 3697 return w;
3698} 3698}
3699 3699
3700QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const 3700QMemArray<QTextStringChar> QTextString::subString( int start, int len ) const
3701{ 3701{
3702 if ( len == 0xFFFFFF ) 3702 if ( len == 0xFFFFFF )
3703 len = data.size(); 3703 len = data.size();
3704 QMemArray<QTextStringChar> a; 3704 QMemArray<QTextStringChar> a;
3705 a.resize( len ); 3705 a.resize( len );
3706 for ( int i = 0; i < len; ++i ) { 3706 for ( int i = 0; i < len; ++i ) {
3707 QTextStringChar *c = &data[ i + start ]; 3707 QTextStringChar *c = &data[ i + start ];
3708 a[ i ].c = c->c; 3708 a[ i ].c = c->c;
3709 a[ i ].x = 0; 3709 a[ i ].x = 0;
3710 a[ i ].lineStart = 0; 3710 a[ i ].lineStart = 0;
3711 a[ i ].rightToLeft = 0; 3711 a[ i ].rightToLeft = 0;
3712 a[ i ].d.format = 0; 3712 a[ i ].d.format = 0;
3713 a[ i ].type = QTextStringChar::Regular; 3713 a[ i ].type = QTextStringChar::Regular;
3714 a[ i ].setFormat( c->format() ); 3714 a[ i ].setFormat( c->format() );
3715 if ( c->format() ) 3715 if ( c->format() )
3716 c->format()->addRef(); 3716 c->format()->addRef();
3717 } 3717 }
3718 return a; 3718 return a;
3719} 3719}
3720 3720
3721// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3721// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3722 3722
3723QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds ) 3723QTextParagraph::QTextParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds )
3724 : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ), 3724 : invalid( 0 ), p( pr ), n( nx ), docOrPseudo( d ),
3725 changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE), 3725 changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE),
3726 lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE), 3726 lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE),
3727 mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE), 3727 mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE),
3728 align( 0 ),mSelections( 0 ), 3728 align( 0 ),mSelections( 0 ),
3729 mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ), 3729 mFloatingItems( 0 ), lstyle( QStyleSheetItem::ListDisc ),
3730 utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ), 3730 utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ),
3731 tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 ) 3731 tArray(0), tabStopWidth(0), eData( 0 ), ldepth( 0 )
3732{ 3732{
3733 lstyle = QStyleSheetItem::ListDisc; 3733 lstyle = QStyleSheetItem::ListDisc;
3734 if ( !hasdoc ) 3734 if ( !hasdoc )
3735 docOrPseudo = new QTextParagraphPseudoDocument; 3735 docOrPseudo = new QTextParagraphPseudoDocument;
3736 bgcol = 0; 3736 bgcol = 0;
3737 list_val = -1; 3737 list_val = -1;
3738 QTextFormat* defFormat = formatCollection()->defaultFormat(); 3738 QTextFormat* defFormat = formatCollection()->defaultFormat();
3739 if ( !hasdoc ) { 3739 if ( !hasdoc ) {
3740 tabStopWidth = defFormat->width( 'x' ) * 8; 3740 tabStopWidth = defFormat->width( 'x' ) * 8;
3741 pseudoDocument()->commandHistory = new QTextCommandHistory( 100 ); 3741 pseudoDocument()->commandHistory = new QTextCommandHistory( 100 );
3742 } 3742 }
3743 3743
3744 if ( p ) 3744 if ( p )
3745 p->n = this; 3745 p->n = this;
3746 if ( n ) 3746 if ( n )
3747 n->p = this; 3747 n->p = this;
3748 3748
3749 3749
3750 if ( !p && hasdoc ) 3750 if ( !p && hasdoc )
3751 document()->setFirstParagraph( this ); 3751 document()->setFirstParagraph( this );
3752 if ( !n && hasdoc ) 3752 if ( !n && hasdoc )
3753 document()->setLastParagraph( this ); 3753 document()->setLastParagraph( this );
3754 3754
3755 state = -1; 3755 state = -1;
3756 3756
3757 if ( p ) 3757 if ( p )
3758 id = p->id + 1; 3758 id = p->id + 1;
3759 else 3759 else
3760 id = 0; 3760 id = 0;
3761 if ( n && updateIds ) { 3761 if ( n && updateIds ) {
3762 QTextParagraph *s = n; 3762 QTextParagraph *s = n;
3763 while ( s ) { 3763 while ( s ) {
3764 s->id = s->p->id + 1; 3764 s->id = s->p->id + 1;
3765 s->invalidateStyleCache(); 3765 s->invalidateStyleCache();
3766 s = s->n; 3766 s = s->n;
3767 } 3767 }
3768 } 3768 }
3769 3769
3770 str = new QTextString(); 3770 str = new QTextString();
3771 str->insert( 0, " ", formatCollection()->defaultFormat() ); 3771 str->insert( 0, " ", formatCollection()->defaultFormat() );
3772} 3772}
3773 3773
3774QTextParagraph::~QTextParagraph() 3774QTextParagraph::~QTextParagraph()
3775{ 3775{
3776 delete str; 3776 delete str;
3777 if ( hasdoc ) { 3777 if ( hasdoc ) {
3778 register QTextDocument *doc = document(); 3778 register QTextDocument *doc = document();
3779 if ( this == doc->minwParag ) { 3779 if ( this == doc->minwParag ) {
3780 doc->minwParag = 0; 3780 doc->minwParag = 0;
3781 doc->minw = 0; 3781 doc->minw = 0;
3782 } 3782 }
3783 if ( this == doc->curParag ) 3783 if ( this == doc->curParag )
3784 doc->curParag = 0; 3784 doc->curParag = 0;
3785 } else { 3785 } else {
3786 delete pseudoDocument(); 3786 delete pseudoDocument();
3787 } 3787 }
3788 if ( tArray ) 3788 if ( tArray )
3789 delete [] tArray; 3789 delete [] tArray;
3790 delete eData; 3790 delete eData;
3791 QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); 3791 QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
3792 for ( ; it != lineStarts.end(); ++it ) 3792 for ( ; it != lineStarts.end(); ++it )
3793 delete *it; 3793 delete *it;
3794 if ( mSelections ) 3794 if ( mSelections )
3795 delete mSelections; 3795 delete mSelections;
3796 if ( mFloatingItems ) 3796 if ( mFloatingItems )
3797 delete mFloatingItems; 3797 delete mFloatingItems;
3798 if ( p ) 3798 if ( p )
3799 p->setNext( n ); 3799 p->setNext( n );
3800 if ( n ) 3800 if ( n )
3801 n->setPrev( p ); 3801 n->setPrev( p );
3802} 3802}
3803 3803
3804void QTextParagraph::setNext( QTextParagraph *s ) 3804void QTextParagraph::setNext( QTextParagraph *s )
3805{ 3805{
3806 n = s; 3806 n = s;
3807 if ( !n && hasdoc ) 3807 if ( !n && hasdoc )
3808 document()->setLastParagraph( this ); 3808 document()->setLastParagraph( this );
3809} 3809}
3810 3810
3811void QTextParagraph::setPrev( QTextParagraph *s ) 3811void QTextParagraph::setPrev( QTextParagraph *s )
3812{ 3812{
3813 p = s; 3813 p = s;
3814 if ( !p && hasdoc ) 3814 if ( !p && hasdoc )
3815 document()->setFirstParagraph( this ); 3815 document()->setFirstParagraph( this );
3816} 3816}
3817 3817
3818void QTextParagraph::invalidate( int chr ) 3818void QTextParagraph::invalidate( int chr )
3819{ 3819{
3820 if ( invalid < 0 ) 3820 if ( invalid < 0 )
3821 invalid = chr; 3821 invalid = chr;
3822 else 3822 else
3823 invalid = QMIN( invalid, chr ); 3823 invalid = QMIN( invalid, chr );
3824 if ( mFloatingItems ) { 3824 if ( mFloatingItems ) {
3825 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) 3825 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
3826 i->ypos = -1; 3826 i->ypos = -1;
3827 } 3827 }
3828 invalidateStyleCache(); 3828 invalidateStyleCache();
3829} 3829}
3830 3830
3831void QTextParagraph::invalidateStyleCache() 3831void QTextParagraph::invalidateStyleCache()
3832{ 3832{
3833 if ( list_val < 0 ) 3833 if ( list_val < 0 )
3834 list_val = -1; 3834 list_val = -1;
3835} 3835}
3836 3836
3837 3837
3838void QTextParagraph::insert( int index, const QString &s ) 3838void QTextParagraph::insert( int index, const QString &s )
3839{ 3839{
3840 insert( index, s.unicode(), s.length() ); 3840 insert( index, s.unicode(), s.length() );
3841} 3841}
3842 3842
3843void QTextParagraph::insert( int index, const QChar *unicode, int len ) 3843void QTextParagraph::insert( int index, const QChar *unicode, int len )
3844{ 3844{
3845 if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() ) 3845 if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() )
3846 str->insert( index, unicode, len, 3846 str->insert( index, unicode, len,
3847 document()->preProcessor()->format( QTextPreProcessor::Standard ) ); 3847 document()->preProcessor()->format( QTextPreProcessor::Standard ) );
3848 else 3848 else
3849 str->insert( index, unicode, len, formatCollection()->defaultFormat() ); 3849 str->insert( index, unicode, len, formatCollection()->defaultFormat() );
3850 invalidate( index ); 3850 invalidate( index );
3851 needPreProcess = TRUE; 3851 needPreProcess = TRUE;
3852} 3852}
3853 3853
3854void QTextParagraph::truncate( int index ) 3854void QTextParagraph::truncate( int index )
3855{ 3855{
3856 str->truncate( index ); 3856 str->truncate( index );
3857 insert( length(), " " ); 3857 insert( length(), " " );
3858 needPreProcess = TRUE; 3858 needPreProcess = TRUE;
3859} 3859}
3860 3860
3861void QTextParagraph::remove( int index, int len ) 3861void QTextParagraph::remove( int index, int len )
3862{ 3862{
3863 if ( index + len - str->length() > 0 ) 3863 if ( index + len - str->length() > 0 )
3864 return; 3864 return;
3865 for ( int i = index; i < index + len; ++i ) { 3865 for ( int i = index; i < index + len; ++i ) {
3866 QTextStringChar *c = at( i ); 3866 QTextStringChar *c = at( i );
3867 if ( hasdoc && c->isCustom() ) { 3867 if ( hasdoc && c->isCustom() ) {
3868 document()->unregisterCustomItem( c->customItem(), this ); 3868 document()->unregisterCustomItem( c->customItem(), this );
3869 } 3869 }
3870 } 3870 }
3871 str->remove( index, len ); 3871 str->remove( index, len );
3872 invalidate( 0 ); 3872 invalidate( 0 );
3873 needPreProcess = TRUE; 3873 needPreProcess = TRUE;
3874} 3874}
3875 3875
3876void QTextParagraph::join( QTextParagraph *s ) 3876void QTextParagraph::join( QTextParagraph *s )
3877{ 3877{
3878 int oh = r.height() + s->r.height(); 3878 int oh = r.height() + s->r.height();
3879 n = s->n; 3879 n = s->n;
3880 if ( n ) 3880 if ( n )
3881 n->p = this; 3881 n->p = this;
3882 else if ( hasdoc ) 3882 else if ( hasdoc )
3883 document()->setLastParagraph( this ); 3883 document()->setLastParagraph( this );
3884 3884
3885 int start = str->length(); 3885 int start = str->length();
3886 if ( length() > 0 && at( length() - 1 )->c == ' ' ) { 3886 if ( length() > 0 && at( length() - 1 )->c == ' ' ) {
3887 remove( length() - 1, 1 ); 3887 remove( length() - 1, 1 );
3888 --start; 3888 --start;
3889 } 3889 }
3890 append( s->str->toString(), TRUE ); 3890 append( s->str->toString(), TRUE );
3891 3891
3892 for ( int i = 0; i < s->length(); ++i ) { 3892 for ( int i = 0; i < s->length(); ++i ) {
3893 if ( !hasdoc || document()->useFormatCollection() ) { 3893 if ( !hasdoc || document()->useFormatCollection() ) {
3894 s->str->at( i ).format()->addRef(); 3894 s->str->at( i ).format()->addRef();
3895 str->setFormat( i + start, s->str->at( i ).format(), TRUE ); 3895 str->setFormat( i + start, s->str->at( i ).format(), TRUE );
3896 } 3896 }
3897 if ( s->str->at( i ).isCustom() ) { 3897 if ( s->str->at( i ).isCustom() ) {
3898 QTextCustomItem * item = s->str->at( i ).customItem(); 3898 QTextCustomItem * item = s->str->at( i ).customItem();
3899 str->at( i + start ).setCustomItem( item ); 3899 str->at( i + start ).setCustomItem( item );
3900 s->str->at( i ).loseCustomItem(); 3900 s->str->at( i ).loseCustomItem();
3901 if ( hasdoc ) { 3901 if ( hasdoc ) {
3902 document()->unregisterCustomItem( item, s ); 3902 document()->unregisterCustomItem( item, s );
3903 document()->registerCustomItem( item, this ); 3903 document()->registerCustomItem( item, this );
3904 } 3904 }
3905 } 3905 }
3906 if ( s->str->at( i ).isAnchor() ) { 3906 if ( s->str->at( i ).isAnchor() ) {
3907 str->at( i + start ).setAnchor( s->str->at( i ).anchorName(), 3907 str->at( i + start ).setAnchor( s->str->at( i ).anchorName(),
3908 s->str->at( i ).anchorHref() ); 3908 s->str->at( i ).anchorHref() );
3909 } 3909 }
3910 } 3910 }
3911 3911
3912 if ( !extraData() && s->extraData() ) { 3912 if ( !extraData() && s->extraData() ) {
3913 setExtraData( s->extraData() ); 3913 setExtraData( s->extraData() );
3914 s->setExtraData( 0 ); 3914 s->setExtraData( 0 );
3915 } else if ( extraData() && s->extraData() ) { 3915 } else if ( extraData() && s->extraData() ) {
3916 extraData()->join( s->extraData() ); 3916 extraData()->join( s->extraData() );
3917 } 3917 }
3918 delete s; 3918 delete s;
3919 invalidate( 0 ); 3919 invalidate( 0 );
3920 r.setHeight( oh ); 3920 r.setHeight( oh );
3921 needPreProcess = TRUE; 3921 needPreProcess = TRUE;
3922 if ( n ) { 3922 if ( n ) {
3923 QTextParagraph *s = n; 3923 QTextParagraph *s = n;
3924 s->invalidate( 0 ); 3924 s->invalidate( 0 );
3925 while ( s ) { 3925 while ( s ) {
3926 s->id = s->p->id + 1; 3926 s->id = s->p->id + 1;
3927 s->state = -1; 3927 s->state = -1;
3928 s->needPreProcess = TRUE; 3928 s->needPreProcess = TRUE;
3929 s->changed = TRUE; 3929 s->changed = TRUE;
3930 s->invalidateStyleCache(); 3930 s->invalidateStyleCache();
3931 s = s->n; 3931 s = s->n;
3932 } 3932 }
3933 } 3933 }
3934 format(); 3934 format();
3935 state = -1; 3935 state = -1;
3936} 3936}
3937 3937
3938void QTextParagraph::move( int &dy ) 3938void QTextParagraph::move( int &dy )
3939{ 3939{
3940 if ( dy == 0 ) 3940 if ( dy == 0 )
3941 return; 3941 return;
3942 changed = TRUE; 3942 changed = TRUE;
3943 r.moveBy( 0, dy ); 3943 r.moveBy( 0, dy );
3944 if ( mFloatingItems ) { 3944 if ( mFloatingItems ) {
3945 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) 3945 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
3946 i->ypos += dy; 3946 i->ypos += dy;
3947 } 3947 }
3948 if ( p ) 3948 if ( p )
3949 p->lastInFrame = TRUE; 3949 p->lastInFrame = TRUE;
3950 3950
3951 // do page breaks if required 3951 // do page breaks if required
3952 if ( hasdoc && document()->isPageBreakEnabled() ) { 3952 if ( hasdoc && document()->isPageBreakEnabled() ) {
3953 int shift; 3953 int shift;
3954 if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) { 3954 if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) {
3955 if ( p ) 3955 if ( p )
3956 p->setChanged( TRUE ); 3956 p->setChanged( TRUE );
3957 dy += shift; 3957 dy += shift;
3958 } 3958 }
3959 } 3959 }
3960} 3960}
3961 3961
3962void QTextParagraph::format( int start, bool doMove ) 3962void QTextParagraph::format( int start, bool doMove )
3963{ 3963{
3964 if ( !str || str->length() == 0 || !formatter() ) 3964 if ( !str || str->length() == 0 || !formatter() )
3965 return; 3965 return;
3966 3966
3967 if ( hasdoc && 3967 if ( hasdoc &&
3968 document()->preProcessor() && 3968 document()->preProcessor() &&
3969 ( needPreProcess || state == -1 ) ) 3969 ( needPreProcess || state == -1 ) )
3970 document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid ); 3970 document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid );
3971 needPreProcess = FALSE; 3971 needPreProcess = FALSE;
3972 3972
3973 if ( invalid == -1 ) 3973 if ( invalid == -1 )
3974 return; 3974 return;
3975 3975
3976 r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) ); 3976 r.moveTopLeft( QPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) );
3977 if ( p ) 3977 if ( p )
3978 p->lastInFrame = FALSE; 3978 p->lastInFrame = FALSE;
3979 3979
3980 movedDown = FALSE; 3980 movedDown = FALSE;
3981 bool formattedAgain = FALSE; 3981 bool formattedAgain = FALSE;
3982 3982
3983 formatAgain: 3983 formatAgain:
3984 3984
3985 r.setWidth( documentWidth() ); 3985 r.setWidth( documentWidth() );
3986 if ( hasdoc && mFloatingItems ) { 3986 if ( hasdoc && mFloatingItems ) {
3987 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) { 3987 for ( QTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) {
3988 i->ypos = r.y(); 3988 i->ypos = r.y();
3989 if ( i->placement() == QTextCustomItem::PlaceRight ) { 3989 if ( i->placement() == QTextCustomItem::PlaceRight ) {
3990 i->xpos = r.x() + r.width() - i->width; 3990 i->xpos = r.x() + r.width() - i->width;
3991 } 3991 }
3992 } 3992 }
3993 } 3993 }
3994 QMap<int, QTextLineStart*> oldLineStarts = lineStarts; 3994 QMap<int, QTextLineStart*> oldLineStarts = lineStarts;
3995 lineStarts.clear(); 3995 lineStarts.clear();
3996 int y = formatter()->format( document(), this, start, oldLineStarts ); 3996 int y = formatter()->format( document(), this, start, oldLineStarts );
3997 3997
3998 3998
3999 r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) ); 3999 r.setWidth( QMAX( r.width(), formatter()->minimumWidth() ) );
4000 4000
4001 4001
4002 QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin(); 4002 QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin();
4003 4003
4004 for ( ; it != oldLineStarts.end(); ++it ) 4004 for ( ; it != oldLineStarts.end(); ++it )
4005 delete *it; 4005 delete *it;
4006 4006
4007 QTextStringChar *c = 0; 4007 QTextStringChar *c = 0;
4008 // do not do this on mac, as the paragraph 4008 // do not do this on mac, as the paragraph
4009 // with has to be the full document width on mac as the selections 4009 // 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, 4010 // 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 4011 // as this results in a bigger double buffer than needed but ok for
4012 // now. 4012 // now.
4013 if ( lineStarts.count() == 1 ) { 4013 if ( lineStarts.count() == 1 ) {
4014 if ( !string()->isBidi() ) { 4014 if ( !string()->isBidi() ) {
4015 c = &str->at( str->length() - 1 ); 4015 c = &str->at( str->length() - 1 );
4016 r.setWidth( c->x + str->width( str->length() - 1 ) ); 4016 r.setWidth( c->x + str->width( str->length() - 1 ) );
4017 } else { 4017 } else {
4018 r.setWidth( lineStarts[0]->w ); 4018 r.setWidth( lineStarts[0]->w );
4019 } 4019 }
4020 } 4020 }
4021 4021
4022 if ( !hasdoc ) { // qt_format_text bounding rect handling 4022 if ( !hasdoc ) { // qt_format_text bounding rect handling
4023 it = lineStarts.begin(); 4023 it = lineStarts.begin();
4024 int usedw = 0; 4024 int usedw = 0;
4025 for ( ; it != lineStarts.end(); ++it ) 4025 for ( ; it != lineStarts.end(); ++it )
4026 usedw = QMAX( usedw, (*it)->w ); 4026 usedw = QMAX( usedw, (*it)->w );
4027 if ( r.width() <= 0 ) { 4027 if ( r.width() <= 0 ) {
4028 // if the user specifies an invalid rect, this means that the 4028 // if the user specifies an invalid rect, this means that the
4029 // bounding box should grow to the width that the text actually 4029 // bounding box should grow to the width that the text actually
4030 // needs 4030 // needs
4031 r.setWidth( usedw ); 4031 r.setWidth( usedw );
4032 } else { 4032 } else {
4033 r.setWidth( QMIN( usedw, r.width() ) ); 4033 r.setWidth( QMIN( usedw, r.width() ) );
4034 } 4034 }
4035 } 4035 }
4036 4036
4037 if ( y != r.height() ) 4037 if ( y != r.height() )
4038 r.setHeight( y ); 4038 r.setHeight( y );
4039 4039
4040 if ( !visible ) { 4040 if ( !visible ) {
4041 r.setHeight( 0 ); 4041 r.setHeight( 0 );
4042 } else { 4042 } else {
4043 int minw = formatter()->minimumWidth(); 4043 int minw = formatter()->minimumWidth();
4044 int wused = formatter()->widthUsed(); 4044 int wused = formatter()->widthUsed();
4045 wused = QMAX( minw, wused ); 4045 wused = QMAX( minw, wused );
4046 if ( hasdoc ) { 4046 if ( hasdoc ) {
4047 document()->setMinimumWidth( minw, wused, this ); 4047 document()->setMinimumWidth( minw, wused, this );
4048 } else { 4048 } else {
4049 pseudoDocument()->minw = QMAX( pseudoDocument()->minw, minw ); 4049 pseudoDocument()->minw = QMAX( pseudoDocument()->minw, minw );
4050 pseudoDocument()->wused = QMAX( pseudoDocument()->wused, wused ); 4050 pseudoDocument()->wused = QMAX( pseudoDocument()->wused, wused );
4051 } 4051 }
4052 } 4052 }
4053 4053
4054 // do page breaks if required 4054 // do page breaks if required
4055 if ( hasdoc && document()->isPageBreakEnabled() ) { 4055 if ( hasdoc && document()->isPageBreakEnabled() ) {
4056 int shift = document()->formatter()->formatVertically( document(), this ); 4056 int shift = document()->formatter()->formatVertically( document(), this );
4057 if ( shift && !formattedAgain ) { 4057 if ( shift && !formattedAgain ) {
4058 formattedAgain = TRUE; 4058 formattedAgain = TRUE;
4059 goto formatAgain; 4059 goto formatAgain;
4060 } 4060 }
4061 } 4061 }
4062 4062
4063 if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) { 4063 if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) {
4064 int dy = ( r.y() + r.height() ) - n->r.y(); 4064 int dy = ( r.y() + r.height() ) - n->r.y();
4065 QTextParagraph *s = n; 4065 QTextParagraph *s = n;
4066 bool makeInvalid = p && p->lastInFrame; 4066 bool makeInvalid = p && p->lastInFrame;
4067 while ( s && dy ) { 4067 while ( s && dy ) {
4068 if ( !s->isFullWidth() ) 4068 if ( !s->isFullWidth() )
4069 makeInvalid = TRUE; 4069 makeInvalid = TRUE;
4070 if ( makeInvalid ) 4070 if ( makeInvalid )
4071 s->invalidate( 0 ); 4071 s->invalidate( 0 );
4072 s->move( dy ); 4072 s->move( dy );
4073 if ( s->lastInFrame ) 4073 if ( s->lastInFrame )
4074 makeInvalid = TRUE; 4074 makeInvalid = TRUE;
4075 s = s->n; 4075 s = s->n;
4076 } 4076 }
4077 } 4077 }
4078 4078
4079 firstFormat = FALSE; 4079 firstFormat = FALSE;
4080 changed = TRUE; 4080 changed = TRUE;
4081 invalid = -1; 4081 invalid = -1;
4082 //##### string()->setTextChanged( FALSE ); 4082 //##### string()->setTextChanged( FALSE );
4083} 4083}
4084 4084
4085int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const 4085int QTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const
4086{ 4086{
4087 if ( !isValid() ) 4087 if ( !isValid() )
4088 ( (QTextParagraph*)this )->format(); 4088 ( (QTextParagraph*)this )->format();
4089 4089
4090 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); 4090 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
4091 --it; 4091 --it;
4092 for ( ;; ) { 4092 for ( ;; ) {
4093 if ( i >= it.key() ) { 4093 if ( i >= it.key() ) {
4094 if ( bl ) 4094 if ( bl )
4095 *bl = ( *it )->baseLine; 4095 *bl = ( *it )->baseLine;
4096 if ( y ) 4096 if ( y )
4097 *y = ( *it )->y; 4097 *y = ( *it )->y;
4098 return ( *it )->h; 4098 return ( *it )->h;
4099 } 4099 }
4100 if ( it == lineStarts.begin() ) 4100 if ( it == lineStarts.begin() )
4101 break; 4101 break;
4102 --it; 4102 --it;
4103 } 4103 }
4104 4104
4105 owarn << "QTextParagraph::lineHeightOfChar: couldn't find lh for " << i << "" << oendl; 4105 owarn << "QTextParagraph::lineHeightOfChar: couldn't find lh for " << i << "" << oendl;
4106 return 15; 4106 return 15;
4107} 4107}
4108 4108
4109QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const 4109QTextStringChar *QTextParagraph::lineStartOfChar( int i, int *index, int *line ) const
4110{ 4110{
4111 if ( !isValid() ) 4111 if ( !isValid() )
4112 ( (QTextParagraph*)this )->format(); 4112 ( (QTextParagraph*)this )->format();
4113 4113
4114 int l = (int)lineStarts.count() - 1; 4114 int l = (int)lineStarts.count() - 1;
4115 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end(); 4115 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
4116 --it; 4116 --it;
4117 for ( ;; ) { 4117 for ( ;; ) {
4118 if ( i >= it.key() ) { 4118 if ( i >= it.key() ) {
4119 if ( index ) 4119 if ( index )
4120 *index = it.key(); 4120 *index = it.key();
4121 if ( line ) 4121 if ( line )
4122 *line = l; 4122 *line = l;
4123 return &str->at( it.key() ); 4123 return &str->at( it.key() );
4124 } 4124 }
4125 if ( it == lineStarts.begin() ) 4125 if ( it == lineStarts.begin() )
4126 break; 4126 break;
4127 --it; 4127 --it;
4128 --l; 4128 --l;
4129 } 4129 }
4130 4130
4131 owarn << "QTextParagraph::lineStartOfChar: couldn't find " << i << "" << oendl; 4131 owarn << "QTextParagraph::lineStartOfChar: couldn't find " << i << "" << oendl;
4132 return 0; 4132 return 0;
4133} 4133}
4134 4134
4135int QTextParagraph::lines() const 4135int QTextParagraph::lines() const
4136{ 4136{
4137 if ( !isValid() ) 4137 if ( !isValid() )
4138 ( (QTextParagraph*)this )->format(); 4138 ( (QTextParagraph*)this )->format();
4139 4139
4140 return (int)lineStarts.count(); 4140 return (int)lineStarts.count();
4141} 4141}
4142 4142
4143QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const 4143QTextStringChar *QTextParagraph::lineStartOfLine( int line, int *index ) const
4144{ 4144{
4145 if ( !isValid() ) 4145 if ( !isValid() )
4146 ( (QTextParagraph*)this )->format(); 4146 ( (QTextParagraph*)this )->format();
4147 4147
4148 if ( line >= 0 && line < (int)lineStarts.count() ) { 4148 if ( line >= 0 && line < (int)lineStarts.count() ) {
4149 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); 4149 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
4150 while ( line-- > 0 ) 4150 while ( line-- > 0 )
4151 ++it; 4151 ++it;
4152 int i = it.key(); 4152 int i = it.key();
4153 if ( index ) 4153 if ( index )
4154 *index = i; 4154 *index = i;
4155 return &str->at( i ); 4155 return &str->at( i );
4156 } 4156 }
4157 4157
4158 owarn << "QTextParagraph::lineStartOfLine: couldn't find " << line << "" << oendl; 4158 owarn << "QTextParagraph::lineStartOfLine: couldn't find " << line << "" << oendl;
4159 return 0; 4159 return 0;
4160} 4160}
4161 4161
4162int QTextParagraph::leftGap() const 4162int QTextParagraph::leftGap() const
4163{ 4163{
4164 if ( !isValid() ) 4164 if ( !isValid() )
4165 ( (QTextParagraph*)this )->format(); 4165 ( (QTextParagraph*)this )->format();
4166 4166
4167 int line = 0; 4167 int line = 0;
4168 int x = str->at(0).x; /* set x to x of first char */ 4168 int x = str->at(0).x; /* set x to x of first char */
4169 if ( str->isBidi() ) { 4169 if ( str->isBidi() ) {
4170 for ( int i = 1; i < str->length()-1; ++i ) 4170 for ( int i = 1; i < str->length()-1; ++i )
4171 x = QMIN(x, str->at(i).x); 4171 x = QMIN(x, str->at(i).x);
4172 return x; 4172 return x;
4173 } 4173 }
4174 4174
4175 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin(); 4175 QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
4176 while (line < (int)lineStarts.count()) { 4176 while (line < (int)lineStarts.count()) {
4177 int i = it.key(); /* char index */ 4177 int i = it.key(); /* char index */
4178 x = QMIN(x, str->at(i).x); 4178 x = QMIN(x, str->at(i).x);
4179 ++it; 4179 ++it;
4180 ++line; 4180 ++line;
4181 } 4181 }
4182 return x; 4182 return x;
4183} 4183}
4184 4184
4185void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags ) 4185void QTextParagraph::setFormat( int index, int len, QTextFormat *f, bool useCollection, int flags )
4186{ 4186{
4187 if ( !f ) 4187 if ( !f )
4188 return; 4188 return;
4189 if ( index < 0 ) 4189 if ( index < 0 )
4190 index = 0; 4190 index = 0;
4191 if ( index > str->length() - 1 ) 4191 if ( index > str->length() - 1 )
4192 index = str->length() - 1; 4192 index = str->length() - 1;
4193 if ( index + len >= str->length() ) 4193 if ( index + len >= str->length() )
4194 len = str->length() - index; 4194 len = str->length() - index;
4195 4195
4196 QTextFormatCollection *fc = 0; 4196 QTextFormatCollection *fc = 0;
4197 if ( useCollection ) 4197 if ( useCollection )
4198 fc = formatCollection(); 4198 fc = formatCollection();
4199 QTextFormat *of; 4199 QTextFormat *of;
4200 for ( int i = 0; i < len; ++i ) { 4200 for ( int i = 0; i < len; ++i ) {
4201 of = str->at( i + index ).format(); 4201 of = str->at( i + index ).format();
4202 if ( !changed && f->key() != of->key() ) 4202 if ( !changed && f->key() != of->key() )
4203 changed = TRUE; 4203 changed = TRUE;
4204 if ( invalid == -1 && 4204 if ( invalid == -1 &&
4205 ( f->font().family() != of->font().family() || 4205 ( f->font().family() != of->font().family() ||
4206 f->font().pointSize() != of->font().pointSize() || 4206 f->font().pointSize() != of->font().pointSize() ||
4207 f->font().weight() != of->font().weight() || 4207 f->font().weight() != of->font().weight() ||
4208 f->font().italic() != of->font().italic() || 4208 f->font().italic() != of->font().italic() ||
4209 f->vAlign() != of->vAlign() ) ) { 4209 f->vAlign() != of->vAlign() ) ) {
4210 invalidate( 0 ); 4210 invalidate( 0 );
4211 } 4211 }
4212 if ( flags == -1 || flags == QTextFormat::Format || !fc ) { 4212 if ( flags == -1 || flags == QTextFormat::Format || !fc ) {
4213 if ( fc ) 4213 if ( fc )
4214 f = fc->format( f ); 4214 f = fc->format( f );
4215 str->setFormat( i + index, f, useCollection ); 4215 str->setFormat( i + index, f, useCollection );
4216 } else { 4216 } else {
4217 QTextFormat *fm = fc->format( of, f, flags ); 4217 QTextFormat *fm = fc->format( of, f, flags );
4218 str->setFormat( i + index, fm, useCollection ); 4218 str->setFormat( i + index, fm, useCollection );
4219 } 4219 }
4220 } 4220 }
4221} 4221}
4222 4222
4223void QTextParagraph::indent( int *oldIndent, int *newIndent ) 4223void QTextParagraph::indent( int *oldIndent, int *newIndent )
4224{ 4224{
4225 if ( !hasdoc || !document()->indent() || isListItem() ) { 4225 if ( !hasdoc || !document()->indent() || isListItem() ) {
4226 if ( oldIndent ) 4226 if ( oldIndent )
4227 *oldIndent = 0; 4227 *oldIndent = 0;
4228 if ( newIndent ) 4228 if ( newIndent )
4229 *newIndent = 0; 4229 *newIndent = 0;
4230 if ( oldIndent && newIndent ) 4230 if ( oldIndent && newIndent )
4231 *newIndent = *oldIndent; 4231 *newIndent = *oldIndent;
4232 return; 4232 return;
4233 } 4233 }
4234 document()->indent()->indent( document(), this, oldIndent, newIndent ); 4234 document()->indent()->indent( document(), this, oldIndent, newIndent );
4235} 4235}
4236 4236
4237void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections, 4237void QTextParagraph::paint( QPainter &painter, const QColorGroup &cg, QTextCursor *cursor, bool drawSelections,
4238 int clipx, int clipy, int clipw, int cliph ) 4238 int clipx, int clipy, int clipw, int cliph )
4239{ 4239{
4240 if ( !visible ) 4240 if ( !visible )
4241 return; 4241 return;
4242 QTextStringChar *chr = 0; 4242 QTextStringChar *chr = 0;
4243 int i, y, h, baseLine, xstart, xend; 4243 int i, y, h, baseLine, xstart, xend;
4244 i = y =h = baseLine = 0; 4244 i = y =h = baseLine = 0;
4245 QRect cursorRect; 4245 QRect cursorRect;
4246 drawSelections &= ( mSelections != 0 ); 4246 drawSelections &= ( mSelections != 0 );
4247 // macintosh full-width selection style 4247 // macintosh full-width selection style
4248 bool fullWidthStyle = FALSE; 4248 bool fullWidthStyle = FALSE;
4249 int fullSelectionWidth = 0; 4249 int fullSelectionWidth = 0;
4250 if ( drawSelections && fullWidthStyle ) 4250 if ( drawSelections && fullWidthStyle )
4251 fullSelectionWidth = (hasdoc ? document()->width() : r.width()); 4251 fullSelectionWidth = (hasdoc ? document()->width() : r.width());
4252 4252
4253 QString qstr = str->toString(); 4253 QString qstr = str->toString();
4254 // ### workaround so that \n are not drawn, actually this should 4254 // ### workaround so that \n are not drawn, actually this should
4255 // be fixed in QFont somewhere (under Windows you get ugly boxes 4255 // be fixed in QFont somewhere (under Windows you get ugly boxes
4256 // otherwise) 4256 // otherwise)
4257 QChar* uc = (QChar*) qstr.unicode(); 4257 QChar* uc = (QChar*) qstr.unicode();
4258 for ( uint ii = 0; ii < qstr.length(); ii++ ) 4258 for ( uint ii = 0; ii < qstr.length(); ii++ )
4259 if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' ) 4259 if ( uc[(int)ii]== '\n' || uc[(int)ii] == QChar_linesep || uc[(int)ii] == '\t' )
4260 uc[(int)ii] = 0x20; 4260 uc[(int)ii] = 0x20;
4261 4261
4262 int line = -1; 4262 int line = -1;
4263 int paintStart = 0; 4263 int paintStart = 0;
4264 int selection = -1; 4264 int selection = -1;
4265 for ( i = 0; i < length(); i++ ) { 4265 for ( i = 0; i < length(); i++ ) {
4266 chr = at( i ); 4266 chr = at( i );
4267 4267
4268 // we flush at end of document 4268 // we flush at end of document
4269 bool flush = i== length()-1; 4269 bool flush = i== length()-1;
4270 bool selectionStateChanged = FALSE; 4270 bool selectionStateChanged = FALSE;
4271 if ( !flush ) { 4271 if ( !flush ) {
4272 QTextStringChar *nextchr = at( i+1 ); 4272 QTextStringChar *nextchr = at( i+1 );
4273 // we flush at end of line 4273 // we flush at end of line
4274 flush |= nextchr->lineStart; 4274 flush |= nextchr->lineStart;
4275 // we flush on format changes 4275 // we flush on format changes
4276 flush |= ( nextchr->format() != chr->format() ); 4276 flush |= ( nextchr->format() != chr->format() );
4277 // we flush on anchor changes 4277 // we flush on anchor changes
4278 flush |= ( nextchr->isAnchor() != chr->isAnchor() ); 4278 flush |= ( nextchr->isAnchor() != chr->isAnchor() );
4279 // we flush on start of run 4279 // we flush on start of run
4280 flush |= nextchr->startOfRun; 4280 flush |= nextchr->startOfRun;
4281 // we flush on bidi changes 4281 // we flush on bidi changes
4282 flush |= ( nextchr->rightToLeft != chr->rightToLeft ); 4282 flush |= ( nextchr->rightToLeft != chr->rightToLeft );
4283 // we flush on tab 4283 // we flush on tab
4284 flush |= ( chr->c == '\t' ); 4284 flush |= ( chr->c == '\t' );
4285 // we flush on soft hypens 4285 // we flush on soft hypens
4286 flush |= ( chr->c.unicode() == 0xad ); 4286 flush |= ( chr->c.unicode() == 0xad );
4287 // we flush on custom items 4287 // we flush on custom items
4288 flush |= chr->isCustom(); 4288 flush |= chr->isCustom();
4289 // we flush before custom items 4289 // we flush before custom items
4290 flush |= nextchr->isCustom(); 4290 flush |= nextchr->isCustom();
4291 // when painting justified, we flush on spaces 4291 // when painting justified, we flush on spaces
4292 if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify ) 4292 if ((alignment() & Qt3::AlignJustify) == Qt3::AlignJustify )
4293 flush |= QTextFormatter::isBreakable( str, i ); 4293 flush |= QTextFormatter::isBreakable( str, i );
4294 // we flush when the string is getting too long 4294 // we flush when the string is getting too long
4295 flush |= ( i - paintStart >= 256 ); 4295 flush |= ( i - paintStart >= 256 );
4296 // we flush when the selection state changes 4296 // we flush when the selection state changes
4297 if ( drawSelections ) { 4297 if ( drawSelections ) {
4298 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); 4298 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin();
4299 it != mSelections->end(); ++it ) 4299 it != mSelections->end(); ++it )
4300 selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 ); 4300 selectionStateChanged |=( (*it).start == i || (*it).start == i+1 || (*it).end == i+1 );
4301 flush |= selectionStateChanged; 4301 flush |= selectionStateChanged;
4302 } 4302 }
4303 } 4303 }
4304 4304
4305 // init a new line 4305 // init a new line
4306 if ( chr->lineStart ) { 4306 if ( chr->lineStart ) {
4307 if (fullWidthStyle && drawSelections && selection >= 0) 4307 if (fullWidthStyle && drawSelections && selection >= 0)
4308 painter.fillRect( xend, y, fullSelectionWidth - xend, h, 4308 painter.fillRect( xend, y, fullSelectionWidth - xend, h,
4309 (selection == QTextDocument::Standard || !hasdoc) ? 4309 (selection == QTextDocument::Standard || !hasdoc) ?
4310 cg.color( QColorGroup::Highlight ) : 4310 cg.color( QColorGroup::Highlight ) :
4311 document()->selectionColor( selection ) ); 4311 document()->selectionColor( selection ) );
4312 ++line; 4312 ++line;
4313 paintStart = i; 4313 paintStart = i;
4314 lineInfo( line, y, h, baseLine ); 4314 lineInfo( line, y, h, baseLine );
4315 if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave 4315 if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave
4316 break; 4316 break;
4317 } 4317 }
4318 4318
4319 // if this is the first line and we are a list item, draw the the bullet label 4319 // if this is the first line and we are a list item, draw the the bullet label
4320 if ( line == 0 && isListItem() ) 4320 if ( line == 0 && isListItem() )
4321 drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg ); 4321 drawLabel( &painter, chr->x, y, 0, 0, baseLine, cg );
4322 } 4322 }
4323 4323
4324 // check for cursor mark 4324 // check for cursor mark
4325 if ( cursor && this == cursor->paragraph() && i == cursor->index() ) { 4325 if ( cursor && this == cursor->paragraph() && i == cursor->index() ) {
4326 QTextStringChar *c = i == 0 ? chr : chr - 1; 4326 QTextStringChar *c = i == 0 ? chr : chr - 1;
4327 cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(), 4327 cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(),
4328 1, c->format()->height() ); 4328 1, c->format()->height() );
4329 } 4329 }
4330 4330
4331 // check if we are in a selection and store which one it is 4331 // check if we are in a selection and store which one it is
4332 selection = -1; 4332 selection = -1;
4333 if ( drawSelections ) { 4333 if ( drawSelections ) {
4334 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin(); 4334 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = mSelections->begin();
4335 it != mSelections->end(); ++it ) 4335 it != mSelections->end(); ++it )
4336 if ( (*it).start <= i && i < (*it).end + ( (*it).end == length()-1 && n && n->hasSelection(it.key()) ) ? 1:0 4336 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 4337 // exclude the standard selection from printing
4338 && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) { 4338 && (it.key() != QTextDocument::Standard || !is_printer( &painter) ) ) {
4339 selection = it.key(); 4339 selection = it.key();
4340 break; 4340 break;
4341 } 4341 }
4342 } 4342 }
4343 4343
4344 if ( flush ) { // something changed, draw what we have so far 4344 if ( flush ) { // something changed, draw what we have so far
4345 if ( chr->rightToLeft ) { 4345 if ( chr->rightToLeft ) {
4346 xstart = chr->x; 4346 xstart = chr->x;
4347 xend = at( paintStart )->x + str->width( paintStart ); 4347 xend = at( paintStart )->x + str->width( paintStart );
4348 } else { 4348 } else {
4349 xstart = at( paintStart )->x; 4349 xstart = at( paintStart )->x;
4350 if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart ) 4350 if ( !selectionStateChanged && i < length() - 1 && !str->at( i + 1 ).lineStart )
4351 xend = str->at( i + 1 ).x; 4351 xend = str->at( i + 1 ).x;
4352 else 4352 else
4353 xend = chr->x + str->width( i ); 4353 xend = chr->x + str->width( i );
4354 } 4354 }
4355 4355
4356 if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) { 4356 if ( (clipx == -1 || clipw == -1) || (xend >= clipx && xstart <= clipx + clipw) ) {
4357 if ( !chr->isCustom() ) 4357 if ( !chr->isCustom() )
4358 drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y, 4358 drawString( painter, qstr, paintStart, i - paintStart + 1, xstart, y,
4359 baseLine, xend-xstart, h, selection, 4359 baseLine, xend-xstart, h, selection,
4360 chr, cg, chr->rightToLeft ); 4360 chr, cg, chr->rightToLeft );
4361 else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline ) 4361 else if ( chr->customItem()->placement() == QTextCustomItem::PlaceInline )
4362 chr->customItem()->draw( &painter, chr->x, y, 4362 chr->customItem()->draw( &painter, chr->x, y,
4363 clipx == -1 ? clipx : (clipx - r.x()), 4363 clipx == -1 ? clipx : (clipx - r.x()),
4364 clipy == -1 ? clipy : (clipy - r.y()), 4364 clipy == -1 ? clipy : (clipy - r.y()),
4365 clipw, cliph, cg, selection >= 0 ); 4365 clipw, cliph, cg, selection >= 0 );
4366 } 4366 }
4367 paintStart = i+1; 4367 paintStart = i+1;
4368 } 4368 }
4369 4369
4370 } 4370 }
4371 4371
4372 if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections) 4372 if (fullWidthStyle && drawSelections && selection >= 0 && next() && next()->mSelections)
4373 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin(); 4373 for ( QMap<int, QTextParagraphSelection>::ConstIterator it = next()->mSelections->begin();
4374 it != next()->mSelections->end(); ++it ) 4374 it != next()->mSelections->end(); ++it )
4375 if (((*it).start) == 0) { 4375 if (((*it).start) == 0) {
4376 painter.fillRect( xend, y, fullSelectionWidth - xend, h, 4376 painter.fillRect( xend, y, fullSelectionWidth - xend, h,
4377 (selection == QTextDocument::Standard || !hasdoc) ? 4377 (selection == QTextDocument::Standard || !hasdoc) ?
4378 cg.color( QColorGroup::Highlight ) : 4378 cg.color( QColorGroup::Highlight ) :
4379 document()->selectionColor( selection ) ); 4379 document()->selectionColor( selection ) );
4380 break; 4380 break;
4381 } 4381 }
4382 4382
4383 // time to draw the cursor 4383 // time to draw the cursor
4384 const int cursor_extent = 4; 4384 const int cursor_extent = 4;
4385 if ( !cursorRect.isNull() && cursor && 4385 if ( !cursorRect.isNull() && cursor &&
4386 ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) { 4386 ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) {
4387 painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) ); 4387 painter.fillRect( cursorRect, cg.color( QColorGroup::Text ) );
4388 painter.save(); 4388 painter.save();
4389 if ( string()->isBidi() ) { 4389 if ( string()->isBidi() ) {
4390 if ( at( cursor->index() )->rightToLeft ) { 4390 if ( at( cursor->index() )->rightToLeft ) {
4391 painter.setPen( Qt::black ); 4391 painter.setPen( Qt::black );
4392 painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); 4392 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 ); 4393 painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
4394 } else { 4394 } else {
4395 painter.setPen( Qt::black ); 4395 painter.setPen( Qt::black );
4396 painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 ); 4396 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 ); 4397 painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
4398 } 4398 }
4399 } 4399 }
4400 painter.restore(); 4400 painter.restore();
4401 } 4401 }
4402} 4402}
4403 4403
4404//#define BIDI_DEBUG 4404//#define BIDI_DEBUG
4405 4405
4406void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart, 4406void QTextParagraph::drawString( QPainter &painter, const QString &s, int start, int len, int xstart,
4407 int y, int baseLine, int w, int h, int selection, 4407 int y, int baseLine, int w, int h, int selection,
4408 QTextStringChar *formatChar, const QColorGroup& cg, 4408 QTextStringChar *formatChar, const QColorGroup& cg,
4409 bool rightToLeft ) 4409 bool rightToLeft )
4410{ 4410{
4411 int i = start + len - 1; 4411 int i = start + len - 1;
4412 bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE; 4412 bool plainText = hasdoc ? document()->textFormat() == Qt::PlainText : FALSE;
4413 QTextFormat* format = formatChar->format(); 4413 QTextFormat* format = formatChar->format();
4414 QString str( s ); 4414 QString str( s );
4415 if ( str[ (int)str.length() - 1 ].unicode() == 0xad ) 4415 if ( str[ (int)str.length() - 1 ].unicode() == 0xad )
4416 str.remove( str.length() - 1, 1 ); 4416 str.remove( str.length() - 1, 1 );
4417 if ( !plainText || hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color() ) 4417 if ( !plainText || hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color() )
4418 painter.setPen( QPen( format->color() ) ); 4418 painter.setPen( QPen( format->color() ) );
4419 else 4419 else
4420 painter.setPen( cg.text() ); 4420 painter.setPen( cg.text() );
4421 painter.setFont( format->font() ); 4421 painter.setFont( format->font() );
4422 4422
4423 if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) { 4423 if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) {
4424 if ( format->useLinkColor() ) { 4424 if ( format->useLinkColor() ) {
4425 if ( document()->linkColor.isValid() ) 4425 if ( document()->linkColor.isValid() )
4426 painter.setPen( document()->linkColor ); 4426 painter.setPen( document()->linkColor );
4427 else 4427 else
4428 painter.setPen( QPen( Qt::blue ) ); 4428 painter.setPen( QPen( Qt::blue ) );
4429 } 4429 }
4430 if ( document()->underlineLinks() ) { 4430 if ( document()->underlineLinks() ) {
4431 QFont fn = format->font(); 4431 QFont fn = format->font();
4432 fn.setUnderline( TRUE ); 4432 fn.setUnderline( TRUE );
4433 painter.setFont( fn ); 4433 painter.setFont( fn );
4434 } 4434 }
4435 } 4435 }
4436 4436
4437 if ( selection >= 0 ) { 4437 if ( selection >= 0 ) {
4438 if ( !hasdoc || document()->invertSelectionText( selection ) ) 4438 if ( !hasdoc || document()->invertSelectionText( selection ) )
4439 painter.setPen( cg.color( QColorGroup::HighlightedText ) ); 4439 painter.setPen( cg.color( QColorGroup::HighlightedText ) );
4440 painter.fillRect( xstart, y, w, h, 4440 painter.fillRect( xstart, y, w, h,
4441 (selection == QTextDocument::Standard || !hasdoc) ? 4441 (selection == QTextDocument::Standard || !hasdoc) ?
4442 cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) ); 4442 cg.color( QColorGroup::Highlight ) : document()->selectionColor( selection ) );
4443 } 4443 }
4444 4444
4445 if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) { 4445 if ( str[ start ] != '\t' && str[ start ].unicode() != 0xad ) {
4446 if ( format->vAlign() == QTextFormat::AlignNormal ) { 4446 if ( format->vAlign() == QTextFormat::AlignNormal ) {
4447 painter.drawText( xstart, y + baseLine, str.mid( start ), len ); 4447 painter.drawText( xstart, y + baseLine, str.mid( start ), len );
4448#ifdef BIDI_DEBUG 4448#ifdef BIDI_DEBUG
4449 painter.save(); 4449 painter.save();
4450 painter.setPen ( Qt::red ); 4450 painter.setPen ( Qt::red );
4451 painter.drawLine( xstart, y, xstart, y + baseLine ); 4451 painter.drawLine( xstart, y, xstart, y + baseLine );
4452 painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 ); 4452 painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 );
4453 int w = 0; 4453 int w = 0;
4454 int i = 0; 4454 int i = 0;
4455 while( i < len ) 4455 while( i < len )
4456 w += painter.fontMetrics().charWidth( str, start + i++ ); 4456 w += painter.fontMetrics().charWidth( str, start + i++ );
4457 painter.setPen ( Qt::blue ); 4457 painter.setPen ( Qt::blue );
4458 painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine ); 4458 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 ); 4459 painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 );
4460 painter.restore(); 4460 painter.restore();
4461#endif 4461#endif
4462 } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) { 4462 } else if ( format->vAlign() == QTextFormat::AlignSuperScript ) {
4463 QFont f( painter.font() ); 4463 QFont f( painter.font() );
4464 if ( format->fontSizesInPixels() ) 4464 if ( format->fontSizesInPixels() )
4465 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); 4465 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
4466 else 4466 else
4467 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 4467 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
4468 painter.setFont( f ); 4468 painter.setFont( f );
4469 painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ), 4469 painter.drawText( xstart, y + baseLine - ( painter.fontMetrics().height() / 2 ),
4470 str.mid( start ), len ); 4470 str.mid( start ), len );
4471 } else if ( format->vAlign() == QTextFormat::AlignSubScript ) { 4471 } else if ( format->vAlign() == QTextFormat::AlignSubScript ) {
4472 QFont f( painter.font() ); 4472 QFont f( painter.font() );
4473 if ( format->fontSizesInPixels() ) 4473 if ( format->fontSizesInPixels() )
4474 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 ); 4474 f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
4475 else 4475 else
4476 f.setPointSize( ( f.pointSize() * 2 ) / 3 ); 4476 f.setPointSize( ( f.pointSize() * 2 ) / 3 );
4477 painter.setFont( f ); 4477 painter.setFont( f );
4478 painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len ); 4478 painter.drawText( xstart, y + baseLine + painter.fontMetrics().height() / 6, str.mid( start ), len );
4479 } 4479 }
4480 } 4480 }
4481 if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) { 4481 if ( i + 1 < length() && at( i + 1 )->lineStart && at( i )->c.unicode() == 0xad ) {
4482 painter.drawText( xstart + w, y + baseLine, "\xad" ); 4482 painter.drawText( xstart + w, y + baseLine, "\xad" );
4483 } 4483 }
4484 if ( format->isMisspelled() ) { 4484 if ( format->isMisspelled() ) {
4485 painter.save(); 4485 painter.save();
4486 painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) ); 4486 painter.setPen( QPen( Qt::red, 1, Qt::DotLine ) );
4487 painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 ); 4487 painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 );
4488 painter.restore(); 4488 painter.restore();
4489 } 4489 }
4490 4490
4491 i -= len; 4491 i -= len;
4492 4492
4493 if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() && 4493 if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() &&
4494 document()->focusIndicator.parag == this && 4494 document()->focusIndicator.parag == this &&
4495 ( document()->focusIndicator.start >= i && 4495 ( document()->focusIndicator.start >= i &&
4496 document()->focusIndicator.start + document()->focusIndicator.len <= i + len || 4496 document()->focusIndicator.start + document()->focusIndicator.len <= i + len ||
4497 document()->focusIndicator.start <= i && 4497 document()->focusIndicator.start <= i &&
4498 document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) { 4498 document()->focusIndicator.start + document()->focusIndicator.len >= i + len ) ) {
4499 painter.drawWinFocusRect( QRect( xstart, y, w, h ) ); 4499 painter.drawWinFocusRect( QRect( xstart, y, w, h ) );
4500 } 4500 }
4501 4501
4502} 4502}
4503 4503
4504void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg ) 4504void QTextParagraph::drawLabel( QPainter* p, int x, int y, int w, int h, int base, const QColorGroup& cg )
4505{ 4505{
4506 QRect r ( x, y, w, h ); 4506 QRect r ( x, y, w, h );
4507 QStyleSheetItem::ListStyle s = listStyle(); 4507 QStyleSheetItem::ListStyle s = listStyle();
4508 4508
4509 p->save(); 4509 p->save();
4510 QTextFormat *format = at( 0 )->format(); 4510 QTextFormat *format = at( 0 )->format();
4511 if ( format ) { 4511 if ( format ) {
4512 p->setPen( format->color() ); 4512 p->setPen( format->color() );
4513 p->setFont( format->font() ); 4513 p->setFont( format->font() );
4514 } 4514 }
4515 QFontMetrics fm( p->fontMetrics() ); 4515 QFontMetrics fm( p->fontMetrics() );
4516 int size = fm.lineSpacing() / 3; 4516 int size = fm.lineSpacing() / 3;
4517 4517
4518 switch ( s ) { 4518 switch ( s ) {
4519 case QStyleSheetItem::ListDecimal: 4519 case QStyleSheetItem::ListDecimal:
4520 case QStyleSheetItem::ListLowerAlpha: 4520 case QStyleSheetItem::ListLowerAlpha:
4521 case QStyleSheetItem::ListUpperAlpha: 4521 case QStyleSheetItem::ListUpperAlpha:
4522 { 4522 {
4523 if ( list_val == -1 ) { // uninitialised list value, calcluate the right one 4523 if ( list_val == -1 ) { // uninitialised list value, calcluate the right one
4524 int depth = listDepth(); 4524 int depth = listDepth();
4525 list_val--; 4525 list_val--;
4526 // ### evil, square and expensive. This needs to be done when formatting, not when painting 4526 // ### evil, square and expensive. This needs to be done when formatting, not when painting
4527 QTextParagraph* s = prev(); 4527 QTextParagraph* s = prev();
4528 int depth_s; 4528 int depth_s;
4529 while ( s && (depth_s = s->listDepth()) >= depth ) { 4529 while ( s && (depth_s = s->listDepth()) >= depth ) {
4530 if ( depth_s == depth && s->isListItem() ) 4530 if ( depth_s == depth && s->isListItem() )
4531 list_val--; 4531 list_val--;
4532 s = s->prev(); 4532 s = s->prev();
4533 } 4533 }
4534 } 4534 }
4535 4535
4536 int n = list_val; 4536 int n = list_val;
4537 if ( n < -1 ) 4537 if ( n < -1 )
4538 n = -n - 1; 4538 n = -n - 1;
4539 QString l; 4539 QString l;
4540 switch ( s ) { 4540 switch ( s ) {
4541 case QStyleSheetItem::ListLowerAlpha: 4541 case QStyleSheetItem::ListLowerAlpha:
4542 if ( n < 27 ) { 4542 if ( n < 27 ) {
4543 l = QChar( ('a' + (char) (n-1))); 4543 l = QChar( ('a' + (char) (n-1)));
4544 break; 4544 break;
4545 } 4545 }
4546 case QStyleSheetItem::ListUpperAlpha: 4546 case QStyleSheetItem::ListUpperAlpha:
4547 if ( n < 27 ) { 4547 if ( n < 27 ) {
4548 l = QChar( ('A' + (char) (n-1))); 4548 l = QChar( ('A' + (char) (n-1)));
4549 break; 4549 break;
4550 } 4550 }
4551 break; 4551 break;
4552 default: //QStyleSheetItem::ListDecimal: 4552 default: //QStyleSheetItem::ListDecimal:
4553 l.setNum( n ); 4553 l.setNum( n );
4554 break; 4554 break;
4555 } 4555 }
4556 l += QString::fromLatin1(". "); 4556 l += QString::fromLatin1(". ");
4557 p->drawText( r.right() - fm.width( l ), r.top() + base, l ); 4557 p->drawText( r.right() - fm.width( l ), r.top() + base, l );
4558 } 4558 }
4559 break; 4559 break;
4560 case QStyleSheetItem::ListSquare: 4560 case QStyleSheetItem::ListSquare:
4561 { 4561 {
4562 QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size ); 4562 QRect er( r.right() - size * 2, r.top() + fm.height() / 2 - size / 2, size, size );
4563 p->fillRect( er , cg.brush( QColorGroup::Text ) ); 4563 p->fillRect( er , cg.brush( QColorGroup::Text ) );
4564 } 4564 }
4565 break; 4565 break;
4566 case QStyleSheetItem::ListCircle: 4566 case QStyleSheetItem::ListCircle:
4567 { 4567 {
4568 QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); 4568 QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size);
4569 p->drawEllipse( er ); 4569 p->drawEllipse( er );
4570 } 4570 }
4571 break; 4571 break;
4572 case QStyleSheetItem::ListDisc: 4572 case QStyleSheetItem::ListDisc:
4573 default: 4573 default:
4574 { 4574 {
4575 p->setBrush( cg.brush( QColorGroup::Text )); 4575 p->setBrush( cg.brush( QColorGroup::Text ));
4576 QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size); 4576 QRect er( r.right()-size*2, r.top() + fm.height() / 2 - size / 2, size, size);
4577 p->drawEllipse( er ); 4577 p->drawEllipse( er );
4578 p->setBrush( Qt::NoBrush ); 4578 p->setBrush( Qt::NoBrush );
4579 } 4579 }
4580 break; 4580 break;
4581 } 4581 }
4582 4582
4583 p->restore(); 4583 p->restore();
4584} 4584}
4585 4585
4586void QTextParagraph::readStyleInformation( QDataStream& stream ) 4586void QTextParagraph::readStyleInformation( QDataStream& stream )
4587{ 4587{
4588 int int_align, int_lstyle; 4588 int int_align, int_lstyle;
4589 uchar uchar_litem, uchar_rtext, uchar_dir; 4589 uchar uchar_litem, uchar_rtext, uchar_dir;
4590 stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm 4590 stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm
4591 >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir; 4591 >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir;
4592 align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle; 4592 align = int_align; lstyle = (QStyleSheetItem::ListStyle) int_lstyle;
4593 litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir ); 4593 litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (QChar::Direction)uchar_dir );
4594 QTextParagraph* s = prev() ? prev() : this; 4594 QTextParagraph* s = prev() ? prev() : this;
4595 while ( s ) { 4595 while ( s ) {
4596 s->invalidate( 0 ); 4596 s->invalidate( 0 );
4597 s = s->next(); 4597 s = s->next();
4598 } 4598 }
4599} 4599}
4600 4600
4601void QTextParagraph::writeStyleInformation( QDataStream& stream ) const 4601void QTextParagraph::writeStyleInformation( QDataStream& stream ) const
4602{ 4602{
4603 stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction(); 4603 stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction();
4604} 4604}
4605 4605
4606 4606
4607 4607
4608void QTextParagraph::setListDepth( int depth ) { 4608void QTextParagraph::setListDepth( int depth ) {
4609 if ( !hasdoc || depth == ldepth ) 4609 if ( !hasdoc || depth == ldepth )
4610 return; 4610 return;
4611 ldepth = depth; 4611 ldepth = depth;
4612 QTextParagraph* s = prev() ? prev() : this; 4612 QTextParagraph* s = prev() ? prev() : this;
4613 while ( s ) { 4613 while ( s ) {
4614 s->invalidate( 0 ); 4614 s->invalidate( 0 );
4615 s = s->next(); 4615 s = s->next();
4616 } 4616 }
4617} 4617}
4618 4618
4619int *QTextParagraph::tabArray() const 4619int *QTextParagraph::tabArray() const
4620{ 4620{
4621 int *ta = tArray; 4621 int *ta = tArray;
4622 if ( !ta && hasdoc ) 4622 if ( !ta && hasdoc )
4623 ta = document()->tabArray(); 4623 ta = document()->tabArray();
4624 return ta; 4624 return ta;
4625} 4625}
4626 4626
4627int QTextParagraph::nextTab( int, int x ) 4627int QTextParagraph::nextTab( int, int x )
4628{ 4628{
4629 int *ta = tArray; 4629 int *ta = tArray;
4630 if ( hasdoc ) { 4630 if ( hasdoc ) {
4631 if ( !ta ) 4631 if ( !ta )
4632 ta = document()->tabArray(); 4632 ta = document()->tabArray();
4633 tabStopWidth = document()->tabStopWidth(); 4633 tabStopWidth = document()->tabStopWidth();
4634 } 4634 }
4635 if ( ta ) { 4635 if ( ta ) {
4636 int i = 0; 4636 int i = 0;
4637 while ( ta[ i ] ) { 4637 while ( ta[ i ] ) {
4638 if ( ta[ i ] >= x ) 4638 if ( ta[ i ] >= x )
4639 return tArray[ i ]; 4639 return tArray[ i ];
4640 ++i; 4640 ++i;
4641 } 4641 }
4642 return tArray[ 0 ]; 4642 return tArray[ 0 ];
4643 } else { 4643 } else {
4644 int d; 4644 int d;
4645 if ( tabStopWidth != 0 ) 4645 if ( tabStopWidth != 0 )
4646 d = x / tabStopWidth; 4646 d = x / tabStopWidth;
4647 else 4647 else
4648 return x; 4648 return x;
4649 return tabStopWidth * ( d + 1 ); 4649 return tabStopWidth * ( d + 1 );
4650 } 4650 }
4651} 4651}
4652 4652
4653void QTextParagraph::adjustToPainter( QPainter *p ) 4653void QTextParagraph::adjustToPainter( QPainter *p )
4654{ 4654{
4655 for ( int i = 0; i < length(); ++i ) { 4655 for ( int i = 0; i < length(); ++i ) {
4656 if ( at( i )->isCustom() ) 4656 if ( at( i )->isCustom() )
4657 at( i )->customItem()->adjustToPainter( p ); 4657 at( i )->customItem()->adjustToPainter( p );
4658 } 4658 }
4659} 4659}
4660 4660
4661QTextFormatCollection *QTextParagraph::formatCollection() const 4661QTextFormatCollection *QTextParagraph::formatCollection() const
4662{ 4662{
4663 if ( hasdoc ) 4663 if ( hasdoc )
4664 return document()->formatCollection(); 4664 return document()->formatCollection();
4665 if ( !qFormatCollection ) { 4665 if ( !qFormatCollection ) {
4666 qFormatCollection = new QTextFormatCollection; 4666 qFormatCollection = new QTextFormatCollection;
4667 static QSingleCleanupHandler<QTextFormatCollection> qtfCleanup; 4667 static QSingleCleanupHandler<QTextFormatCollection> qtfCleanup;
4668 qtfCleanup.set( &qFormatCollection ); 4668 qtfCleanup.set( &qFormatCollection );
4669 } 4669 }
4670 return qFormatCollection; 4670 return qFormatCollection;
4671} 4671}
4672 4672
4673QString QTextParagraph::richText() const 4673QString QTextParagraph::richText() const
4674{ 4674{
4675 QString s; 4675 QString s;
4676 QTextStringChar *formatChar = 0; 4676 QTextStringChar *formatChar = 0;
4677 QString spaces; 4677 QString spaces;
4678 bool doStart = richTextExportStart && richTextExportStart->paragraph() == this; 4678 bool doStart = richTextExportStart && richTextExportStart->paragraph() == this;
4679 bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this; 4679 bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this;
4680 int i; 4680 int i;
4681 for ( i = 0; i < length()-1; ++i ) { 4681 for ( i = 0; i < length()-1; ++i ) {
4682 if ( doStart && i && richTextExportStart->index() == i ) 4682 if ( doStart && i && richTextExportStart->index() == i )
4683 s += "<selstart/>"; 4683 s += "<selstart/>";
4684 if ( doEnd && richTextExportEnd->index() == i ) 4684 if ( doEnd && richTextExportEnd->index() == i )
4685 s += "<selend/>"; 4685 s += "<selend/>";
4686 QTextStringChar *c = &str->at( i ); 4686 QTextStringChar *c = &str->at( i );
4687 if ( c->isAnchor() && !c->anchorName().isEmpty() ) { 4687 if ( c->isAnchor() && !c->anchorName().isEmpty() ) {
4688 if ( c->anchorName().contains( '#' ) ) { 4688 if ( c->anchorName().contains( '#' ) ) {
4689 QStringList l = QStringList::split( '#', c->anchorName() ); 4689 QStringList l = QStringList::split( '#', c->anchorName() );
4690 for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) 4690 for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it )
4691 s += "<a name=\"" + *it + "\"></a>"; 4691 s += "<a name=\"" + *it + "\"></a>";
4692 } else { 4692 } else {
4693 s += "<a name=\"" + c->anchorName() + "\"></a>"; 4693 s += "<a name=\"" + c->anchorName() + "\"></a>";
4694 } 4694 }
4695 } 4695 }
4696 if ( !formatChar ) { 4696 if ( !formatChar ) {
4697 s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), 4697 s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
4698 0, QString::null, c->anchorHref() ); 4698 0, QString::null, c->anchorHref() );
4699 formatChar = c; 4699 formatChar = c;
4700 } else if ( ( formatChar->format()->key() != c->format()->key() ) || 4700 } else if ( ( formatChar->format()->key() != c->format()->key() ) ||
4701 (c->anchorHref() != formatChar->anchorHref() ) ) { 4701 (c->anchorHref() != formatChar->anchorHref() ) ) {
4702 s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(), 4702 s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
4703 formatChar->format() , formatChar->anchorHref(), c->anchorHref() ); 4703 formatChar->format() , formatChar->anchorHref(), c->anchorHref() );
4704 formatChar = c; 4704 formatChar = c;
4705 } 4705 }
4706 if ( c->c == '<' ) 4706 if ( c->c == '<' )
4707 s += "&lt;"; 4707 s += "&lt;";
4708 else if ( c->c == '>' ) 4708 else if ( c->c == '>' )
4709 s += "&gt;"; 4709 s += "&gt;";
4710 else if ( c->isCustom() ) 4710 else if ( c->isCustom() )
4711 s += c->customItem()->richText(); 4711 s += c->customItem()->richText();
4712 else if ( c->c == '\n' || c->c == QChar_linesep ) 4712 else if ( c->c == '\n' || c->c == QChar_linesep )
4713 s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co. 4713 s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co.
4714 else 4714 else
4715 s += c->c; 4715 s += c->c;
4716 } 4716 }
4717 if ( doEnd && richTextExportEnd->index() == i ) 4717 if ( doEnd && richTextExportEnd->index() == i )
4718 s += "<selend/>"; 4718 s += "<selend/>";
4719 if ( formatChar ) 4719 if ( formatChar )
4720 s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() ); 4720 s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() );
4721 return s; 4721 return s;
4722} 4722}
4723 4723
4724void QTextParagraph::addCommand( QTextCommand *cmd ) 4724void QTextParagraph::addCommand( QTextCommand *cmd )
4725{ 4725{
4726 if ( !hasdoc ) 4726 if ( !hasdoc )
4727 pseudoDocument()->commandHistory->addCommand( cmd ); 4727 pseudoDocument()->commandHistory->addCommand( cmd );
4728 else 4728 else
4729 document()->commands()->addCommand( cmd ); 4729 document()->commands()->addCommand( cmd );
4730} 4730}
4731 4731
4732QTextCursor *QTextParagraph::undo( QTextCursor *c ) 4732QTextCursor *QTextParagraph::undo( QTextCursor *c )
4733{ 4733{
4734 if ( !hasdoc ) 4734 if ( !hasdoc )
4735 return pseudoDocument()->commandHistory->undo( c ); 4735 return pseudoDocument()->commandHistory->undo( c );
4736 return document()->commands()->undo( c ); 4736 return document()->commands()->undo( c );
4737} 4737}
4738 4738
4739QTextCursor *QTextParagraph::redo( QTextCursor *c ) 4739QTextCursor *QTextParagraph::redo( QTextCursor *c )
4740{ 4740{
4741 if ( !hasdoc ) 4741 if ( !hasdoc )
4742 return pseudoDocument()->commandHistory->redo( c ); 4742 return pseudoDocument()->commandHistory->redo( c );
4743 return document()->commands()->redo( c ); 4743 return document()->commands()->redo( c );
4744} 4744}
4745 4745
4746int QTextParagraph::topMargin() const 4746int QTextParagraph::topMargin() const
4747{ 4747{
4748 int m = 0; 4748 int m = 0;
4749 if ( rtext ) { 4749 if ( rtext ) {
4750 m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm; 4750 m = isListItem() ? (document()->li_tm/QMAX(1,listDepth())) : document()->par_tm;
4751 if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) ) 4751 if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) )
4752 m = QMAX( m, document()->list_tm ); 4752 m = QMAX( m, document()->list_tm );
4753 } 4753 }
4754 m += utm; 4754 m += utm;
4755 return scale( m, QTextFormat::painter() ); 4755 return scale( m, QTextFormat::painter() );
4756} 4756}
4757 4757
4758int QTextParagraph::bottomMargin() const 4758int QTextParagraph::bottomMargin() const
4759{ 4759{
4760 int m = 0; 4760 int m = 0;
4761 if ( rtext ) { 4761 if ( rtext ) {
4762 m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm; 4762 m = isListItem() ? (document()->li_bm/QMAX(1,listDepth())) : document()->par_bm;
4763 if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) ) 4763 if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) )
4764 m = QMAX( m, document()->list_bm ); 4764 m = QMAX( m, document()->list_bm );
4765 } 4765 }
4766 m += ubm; 4766 m += ubm;
4767 return scale( m, QTextFormat::painter() ); 4767 return scale( m, QTextFormat::painter() );
4768} 4768}
4769 4769
4770int QTextParagraph::leftMargin() const 4770int QTextParagraph::leftMargin() const
4771{ 4771{
4772 int m = ulm; 4772 int m = ulm;
4773 if ( listDepth() ) 4773 if ( listDepth() )
4774 m += listDepth() * document()->list_lm; 4774 m += listDepth() * document()->list_lm;
4775 return scale( m, QTextFormat::painter() ); 4775 return scale( m, QTextFormat::painter() );
4776} 4776}
4777 4777
4778int QTextParagraph::firstLineMargin() const 4778int QTextParagraph::firstLineMargin() const
4779{ 4779{
4780 int m = uflm; 4780 int m = uflm;
4781 return scale( m, QTextFormat::painter() ); 4781 return scale( m, QTextFormat::painter() );
4782} 4782}
4783 4783
4784int QTextParagraph::rightMargin() const 4784int QTextParagraph::rightMargin() const
4785{ 4785{
4786 int m = urm; 4786 int m = urm;
4787 return scale( m, QTextFormat::painter() ); 4787 return scale( m, QTextFormat::painter() );
4788} 4788}
4789 4789
4790int QTextParagraph::lineSpacing() const 4790int QTextParagraph::lineSpacing() const
4791{ 4791{
4792 int l = ulinespacing; 4792 int l = ulinespacing;
4793 l = scale( l, QTextFormat::painter() ); 4793 l = scale( l, QTextFormat::painter() );
4794 return l; 4794 return l;
4795} 4795}
4796 4796
4797void QTextParagraph::copyParagData( QTextParagraph *parag ) 4797void QTextParagraph::copyParagData( QTextParagraph *parag )
4798{ 4798{
4799 rtext = parag->rtext; 4799 rtext = parag->rtext;
4800 lstyle = parag->lstyle; 4800 lstyle = parag->lstyle;
4801 ldepth = parag->ldepth; 4801 ldepth = parag->ldepth;
4802 litem = parag->litem; 4802 litem = parag->litem;
4803 align = parag->align; 4803 align = parag->align;
4804 utm = parag->utm; 4804 utm = parag->utm;
4805 ubm = parag->ubm; 4805 ubm = parag->ubm;
4806 urm = parag->urm; 4806 urm = parag->urm;
4807 ulm = parag->ulm; 4807 ulm = parag->ulm;
4808 uflm = parag->uflm; 4808 uflm = parag->uflm;
4809 ulinespacing = parag->ulinespacing; 4809 ulinespacing = parag->ulinespacing;
4810 QColor *c = parag->backgroundColor(); 4810 QColor *c = parag->backgroundColor();
4811 if ( c ) 4811 if ( c )
4812 setBackgroundColor( *c ); 4812 setBackgroundColor( *c );
4813 str->setDirection( parag->str->direction() ); 4813 str->setDirection( parag->str->direction() );
4814} 4814}
4815 4815
4816void QTextParagraph::show() 4816void QTextParagraph::show()
4817{ 4817{
4818 if ( visible || !hasdoc ) 4818 if ( visible || !hasdoc )
4819 return; 4819 return;
4820 visible = TRUE; 4820 visible = TRUE;
4821} 4821}
4822 4822
4823void QTextParagraph::hide() 4823void QTextParagraph::hide()
4824{ 4824{
4825 if ( !visible || !hasdoc ) 4825 if ( !visible || !hasdoc )
4826 return; 4826 return;
4827 visible = FALSE; 4827 visible = FALSE;
4828} 4828}
4829 4829
4830void QTextParagraph::setDirection( QChar::Direction d ) 4830void QTextParagraph::setDirection( QChar::Direction d )
4831{ 4831{
4832 if ( str && str->direction() != d ) { 4832 if ( str && str->direction() != d ) {
4833 str->setDirection( d ); 4833 str->setDirection( d );
4834 invalidate( 0 ); 4834 invalidate( 0 );
4835 } 4835 }
4836} 4836}
4837 4837
4838QChar::Direction QTextParagraph::direction() const 4838QChar::Direction QTextParagraph::direction() const
4839{ 4839{
4840 return (str ? str->direction() : QChar::DirON ); 4840 return (str ? str->direction() : QChar::DirON );
4841} 4841}
4842 4842
4843void QTextParagraph::setChanged( bool b, bool recursive ) 4843void QTextParagraph::setChanged( bool b, bool recursive )
4844{ 4844{
4845 changed = b; 4845 changed = b;
4846 if ( recursive ) { 4846 if ( recursive ) {
4847 if ( document() && document()->parentParagraph() ) 4847 if ( document() && document()->parentParagraph() )
4848 document()->parentParagraph()->setChanged( b, recursive ); 4848 document()->parentParagraph()->setChanged( b, recursive );
4849 } 4849 }
4850} 4850}
4851 4851
4852// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4852// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4853 4853
4854 4854
4855QTextPreProcessor::QTextPreProcessor() 4855QTextPreProcessor::QTextPreProcessor()
4856{ 4856{
4857} 4857}
4858 4858
4859// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4859// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4860 4860
4861QTextFormatter::QTextFormatter() 4861QTextFormatter::QTextFormatter()
4862 : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE ) 4862 : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE )
4863{ 4863{
4864} 4864}
4865 4865
4866QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line, 4866QTextLineStart *QTextFormatter::formatLine( QTextParagraph *parag, QTextString *string, QTextLineStart *line,
4867 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) 4867 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space )
4868{ 4868{
4869#ifndef QT_NO_COMPLEXTEXT 4869#ifndef QT_NO_COMPLEXTEXT
4870 if( string->isBidi() ) 4870 if( string->isBidi() )
4871 return bidiReorderLine( parag, string, line, startChar, lastChar, align, space ); 4871 return bidiReorderLine( parag, string, line, startChar, lastChar, align, space );
4872#endif 4872#endif
4873 int start = (startChar - &string->at(0)); 4873 int start = (startChar - &string->at(0));
4874 int last = (lastChar - &string->at(0) ); 4874 int last = (lastChar - &string->at(0) );
4875 // do alignment Auto == Left in this case 4875 // do alignment Auto == Left in this case
4876 if ( align & Qt::AlignHCenter || align & Qt::AlignRight ) { 4876 if ( align & Qt::AlignHCenter || align & Qt::AlignRight ) {
4877 if ( align & Qt::AlignHCenter ) 4877 if ( align & Qt::AlignHCenter )
4878 space /= 2; 4878 space /= 2;
4879 for ( int j = start; j <= last; ++j ) 4879 for ( int j = start; j <= last; ++j )
4880 string->at( j ).x += space; 4880 string->at( j ).x += space;
4881 } else if ( align & Qt3::AlignJustify ) { 4881 } else if ( align & Qt3::AlignJustify ) {
4882 int numSpaces = 0; 4882 int numSpaces = 0;
4883 // End at "last-1", the last space ends up with a width of 0 4883 // End at "last-1", the last space ends up with a width of 0
4884 for ( int j = last-1; j >= start; --j ) { 4884 for ( int j = last-1; j >= start; --j ) {
4885 // Start at last tab, if any. 4885 // Start at last tab, if any.
4886 if ( string->at( j ).c == '\t' ) { 4886 if ( string->at( j ).c == '\t' ) {
4887 start = j+1; 4887 start = j+1;
4888 break; 4888 break;
4889 } 4889 }
4890 if( isBreakable( string, j ) ) { 4890 if( isBreakable( string, j ) ) {
4891 numSpaces++; 4891 numSpaces++;
4892 } 4892 }
4893 } 4893 }
4894 int toAdd = 0; 4894 int toAdd = 0;
4895 for ( int k = start + 1; k <= last; ++k ) { 4895 for ( int k = start + 1; k <= last; ++k ) {
4896 if( isBreakable( string, k ) && numSpaces ) { 4896 if( isBreakable( string, k ) && numSpaces ) {
4897 int s = space / numSpaces; 4897 int s = space / numSpaces;
4898 toAdd += s; 4898 toAdd += s;
4899 space -= s; 4899 space -= s;
4900 numSpaces--; 4900 numSpaces--;
4901 } 4901 }
4902 string->at( k ).x += toAdd; 4902 string->at( k ).x += toAdd;
4903 } 4903 }
4904 } 4904 }
4905 4905
4906 if ( last >= 0 && last < string->length() ) 4906 if ( last >= 0 && last < string->length() )
4907 line->w = string->at( last ).x + string->width( last ); 4907 line->w = string->at( last ).x + string->width( last );
4908 else 4908 else
4909 line->w = 0; 4909 line->w = 0;
4910 4910
4911 return new QTextLineStart(); 4911 return new QTextLineStart();
4912} 4912}
4913 4913
4914#ifndef QT_NO_COMPLEXTEXT 4914#ifndef QT_NO_COMPLEXTEXT
4915 4915
4916#ifdef BIDI_DEBUG 4916#ifdef BIDI_DEBUG
4917#include <iostream> 4917#include <iostream>
4918#endif 4918#endif
4919 4919
4920// collects one line of the paragraph and transforms it to visual order 4920// collects one line of the paragraph and transforms it to visual order
4921QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line, 4921QTextLineStart *QTextFormatter::bidiReorderLine( QTextParagraph * /*parag*/, QTextString *text, QTextLineStart *line,
4922 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space ) 4922 QTextStringChar *startChar, QTextStringChar *lastChar, int align, int space )
4923{ 4923{
4924 int start = (startChar - &text->at(0)); 4924 int start = (startChar - &text->at(0));
4925 int last = (lastChar - &text->at(0) ); 4925 int last = (lastChar - &text->at(0) );
4926 4926
4927 QBidiControl *control = new QBidiControl( line->context(), line->status ); 4927 QBidiControl *control = new QBidiControl( line->context(), line->status );
4928 QString str; 4928 QString str;
4929 str.setUnicode( 0, last - start + 1 ); 4929 str.setUnicode( 0, last - start + 1 );
4930 // fill string with logically ordered chars. 4930 // fill string with logically ordered chars.
4931 QTextStringChar *ch = startChar; 4931 QTextStringChar *ch = startChar;
4932 QChar *qch = (QChar *)str.unicode(); 4932 QChar *qch = (QChar *)str.unicode();
4933 while ( ch <= lastChar ) { 4933 while ( ch <= lastChar ) {
4934 *qch = ch->c; 4934 *qch = ch->c;
4935 qch++; 4935 qch++;
4936 ch++; 4936 ch++;
4937 } 4937 }
4938 int x = startChar->x; 4938 int x = startChar->x;
4939 4939
4940 QPtrList<QTextRun> *runs; 4940 QPtrList<QTextRun> *runs;
4941 runs = QComplexText::bidiReorderLine(control, str, 0, last - start + 1, 4941 runs = QComplexText::bidiReorderLine(control, str, 0, last - start + 1,
4942 (text->isRightToLeft() ? QChar::DirR : QChar::DirL) ); 4942 (text->isRightToLeft() ? QChar::DirR : QChar::DirL) );
4943 4943
4944 // now construct the reordered string out of the runs... 4944 // now construct the reordered string out of the runs...
4945 4945
4946 int numSpaces = 0; 4946 int numSpaces = 0;
4947 // set the correct alignment. This is a bit messy.... 4947 // set the correct alignment. This is a bit messy....
4948 if( align == Qt3::AlignAuto ) { 4948 if( align == Qt3::AlignAuto ) {
4949 // align according to directionality of the paragraph... 4949 // align according to directionality of the paragraph...
4950 if ( text->isRightToLeft() ) 4950 if ( text->isRightToLeft() )
4951 align = Qt::AlignRight; 4951 align = Qt::AlignRight;
4952 } 4952 }
4953 4953
4954 if ( align & Qt::AlignHCenter ) 4954 if ( align & Qt::AlignHCenter )
4955 x += space/2; 4955 x += space/2;
4956 else if ( align & Qt::AlignRight ) 4956 else if ( align & Qt::AlignRight )
4957 x += space; 4957 x += space;
4958 else if ( align & Qt3::AlignJustify ) { 4958 else if ( align & Qt3::AlignJustify ) {
4959 // End at "last-1", the last space ends up with a width of 0 4959 // End at "last-1", the last space ends up with a width of 0
4960 for ( int j = last-1; j >= start; --j ) { 4960 for ( int j = last-1; j >= start; --j ) {
4961 // Start at last tab, if any. 4961 // Start at last tab, if any.
4962 if ( text->at( j ).c == '\t' ) { 4962 if ( text->at( j ).c == '\t' ) {
4963 start = j+1; 4963 start = j+1;
4964 break; 4964 break;
4965 } 4965 }
4966 if( isBreakable( text, j ) ) { 4966 if( isBreakable( text, j ) ) {
4967 numSpaces++; 4967 numSpaces++;
4968 } 4968 }
4969 } 4969 }
4970 } 4970 }
4971 int toAdd = 0; 4971 int toAdd = 0;
4972 bool first = TRUE; 4972 bool first = TRUE;
4973 QTextRun *r = runs->first(); 4973 QTextRun *r = runs->first();
4974 int xmax = -0xffffff; 4974 int xmax = -0xffffff;
4975 while ( r ) { 4975 while ( r ) {
4976 if(r->level %2) { 4976 if(r->level %2) {
4977 // odd level, need to reverse the string 4977 // odd level, need to reverse the string
4978 int pos = r->stop + start; 4978 int pos = r->stop + start;
4979 while(pos >= r->start + start) { 4979 while(pos >= r->start + start) {
4980 QTextStringChar *c = &text->at(pos); 4980 QTextStringChar *c = &text->at(pos);
4981 if( numSpaces && !first && isBreakable( text, pos ) ) { 4981 if( numSpaces && !first && isBreakable( text, pos ) ) {
4982 int s = space / numSpaces; 4982 int s = space / numSpaces;
4983 toAdd += s; 4983 toAdd += s;
4984 space -= s; 4984 space -= s;
4985 numSpaces--; 4985 numSpaces--;
4986 } else if ( first ) { 4986 } else if ( first ) {
4987 first = FALSE; 4987 first = FALSE;
4988 if ( c->c == ' ' ) 4988 if ( c->c == ' ' )
4989 x -= c->format()->width( ' ' ); 4989 x -= c->format()->width( ' ' );
4990 } 4990 }
4991 c->x = x + toAdd; 4991 c->x = x + toAdd;
4992 c->rightToLeft = TRUE; 4992 c->rightToLeft = TRUE;
4993 c->startOfRun = FALSE; 4993 c->startOfRun = FALSE;
4994 int ww = 0; 4994 int ww = 0;
4995 if ( c->c.unicode() >= 32 || c->c == '\t' || c->c == '\n' || c->isCustom() ) { 4995 if ( c->c.unicode() >= 32 || c->c == '\t' || c->c == '\n' || c->isCustom() ) {
4996 ww = text->width( pos ); 4996 ww = text->width( pos );
4997 } else { 4997 } else {
4998 ww = c->format()->width( ' ' ); 4998 ww = c->format()->width( ' ' );
4999 } 4999 }
5000 if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; 5000 if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww;
5001 x += ww; 5001 x += ww;
5002 pos--; 5002 pos--;
5003 } 5003 }
5004 } else { 5004 } else {
5005 int pos = r->start + start; 5005 int pos = r->start + start;
5006 while(pos <= r->stop + start) { 5006 while(pos <= r->stop + start) {
5007 QTextStringChar* c = &text->at(pos); 5007 QTextStringChar* c = &text->at(pos);
5008 if( numSpaces && !first && isBreakable( text, pos ) ) { 5008 if( numSpaces && !first && isBreakable( text, pos ) ) {
5009 int s = space / numSpaces; 5009 int s = space / numSpaces;
5010 toAdd += s; 5010 toAdd += s;
5011 space -= s; 5011 space -= s;
5012 numSpaces--; 5012 numSpaces--;
5013 } else if ( first ) { 5013 } else if ( first ) {
5014 first = FALSE; 5014 first = FALSE;
5015 if ( c->c == ' ' ) 5015 if ( c->c == ' ' )
5016 x -= c->format()->width( ' ' ); 5016 x -= c->format()->width( ' ' );
5017 } 5017 }
5018 c->x = x + toAdd; 5018 c->x = x + toAdd;
5019 c->rightToLeft = FALSE; 5019 c->rightToLeft = FALSE;
5020 c->startOfRun = FALSE; 5020 c->startOfRun = FALSE;
5021 int ww = 0; 5021 int ww = 0;
5022 if ( c->c.unicode() >= 32 || c->c == '\t' || c->isCustom() ) { 5022 if ( c->c.unicode() >= 32 || c->c == '\t' || c->isCustom() ) {
5023 ww = text->width( pos ); 5023 ww = text->width( pos );
5024 } else { 5024 } else {
5025 ww = c->format()->width( ' ' ); 5025 ww = c->format()->width( ' ' );
5026 } 5026 }
5027 if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww; 5027 if ( xmax < x + toAdd + ww ) xmax = x + toAdd + ww;
5028 x += ww; 5028 x += ww;
5029 pos++; 5029 pos++;
5030 } 5030 }
5031 } 5031 }
5032 text->at( r->start + start ).startOfRun = TRUE; 5032 text->at( r->start + start ).startOfRun = TRUE;
5033 r = runs->next(); 5033 r = runs->next();
5034 } 5034 }
5035 5035
5036 line->w = xmax + 10; 5036 line->w = xmax + 10;
5037 QTextLineStart *ls = new QTextLineStart( control->context, control->status ); 5037 QTextLineStart *ls = new QTextLineStart( control->context, control->status );
5038 delete control; 5038 delete control;
5039 delete runs; 5039 delete runs;
5040 return ls; 5040 return ls;
5041} 5041}
5042#endif 5042#endif
5043 5043
5044bool QTextFormatter::isBreakable( QTextString *string, int pos ) 5044bool QTextFormatter::isBreakable( QTextString *string, int pos )
5045{ 5045{
5046 const QChar &c = string->at( pos ).c; 5046 const QChar &c = string->at( pos ).c;
5047 char ch = c.latin1(); 5047 char ch = c.latin1();
5048 if ( c == QChar_linesep ) 5048 if ( c == QChar_linesep )
5049 return TRUE; 5049 return TRUE;
5050 if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U ) 5050 if ( c.isSpace() && ch != '\n' && c.unicode() != 0x00a0U )
5051 return TRUE; 5051 return TRUE;
5052 if ( c.unicode() == 0xad ) // soft hyphen 5052 if ( c.unicode() == 0xad ) // soft hyphen
5053 return TRUE; 5053 return TRUE;
5054 if ( !ch ) { 5054 if ( !ch ) {
5055 // not latin1, need to do more sophisticated checks for other scripts 5055 // not latin1, need to do more sophisticated checks for other scripts
5056 uchar row = c.row(); 5056 uchar row = c.row();
5057 if ( row == 0x0e ) { 5057 if ( row == 0x0e ) {
5058 // 0e00 - 0e7f == Thai 5058 // 0e00 - 0e7f == Thai
5059 if ( c.cell() < 0x80 ) { 5059 if ( c.cell() < 0x80 ) {
5060#ifdef HAVE_THAI_BREAKS 5060#ifdef HAVE_THAI_BREAKS
5061 // check for thai 5061 // check for thai
5062 if( string != cachedString ) { 5062 if( string != cachedString ) {
5063 // build up string of thai chars 5063 // build up string of thai chars
5064 QTextCodec *thaiCodec = QTextCodec::codecForMib(2259); 5064 QTextCodec *thaiCodec = QTextCodec::codecForMib(2259);
5065 if ( !thaiCache ) 5065 if ( !thaiCache )
5066 thaiCache = new QCString; 5066 thaiCache = new QCString;
5067 if ( !thaiIt ) 5067 if ( !thaiIt )
5068 thaiIt = ThBreakIterator::createWordInstance(); 5068 thaiIt = ThBreakIterator::createWordInstance();
5069 *thaiCache = thaiCodec->fromUnicode( s->string() ); 5069 *thaiCache = thaiCodec->fromUnicode( s->string() );
5070 } 5070 }
5071 thaiIt->setText(thaiCache->data()); 5071 thaiIt->setText(thaiCache->data());
5072 for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) { 5072 for(int i = thaiIt->first(); i != thaiIt->DONE; i = thaiIt->next() ) {
5073 if( i == pos ) 5073 if( i == pos )
5074 return TRUE; 5074 return TRUE;
5075 if( i > pos ) 5075 if( i > pos )
5076 return FALSE; 5076 return FALSE;
5077 } 5077 }
5078 return FALSE; 5078 return FALSE;
5079#else 5079#else
5080 // if we don't have a thai line breaking lib, allow 5080 // if we don't have a thai line breaking lib, allow
5081 // breaks everywhere except directly before punctuation. 5081 // breaks everywhere except directly before punctuation.
5082 return TRUE; 5082 return TRUE;
5083#endif 5083#endif
5084 } else 5084 } else
5085 return FALSE; 5085 return FALSE;
5086 } 5086 }
5087 if ( row < 0x11 ) // no asian font 5087 if ( row < 0x11 ) // no asian font
5088 return FALSE; 5088 return FALSE;
5089 if ( row > 0x2d && row < 0xfb || row == 0x11 ) 5089 if ( row > 0x2d && row < 0xfb || row == 0x11 )
5090 // asian line breaking. Everywhere allowed except directly 5090 // asian line breaking. Everywhere allowed except directly
5091 // in front of a punctuation character. 5091 // in front of a punctuation character.
5092 return TRUE; 5092 return TRUE;
5093 } 5093 }
5094 return FALSE; 5094 return FALSE;
5095} 5095}
5096 5096
5097void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls ) 5097void QTextFormatter::insertLineStart( QTextParagraph *parag, int index, QTextLineStart *ls )
5098{ 5098{
5099 if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times 5099 if ( index > 0 ) { // we can assume that only first line starts are insrted multiple times
5100 parag->lineStartList().insert( index, ls ); 5100 parag->lineStartList().insert( index, ls );
5101 return; 5101 return;
5102 } 5102 }
5103 QMap<int, QTextLineStart*>::Iterator it; 5103 QMap<int, QTextLineStart*>::Iterator it;
5104 if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) { 5104 if ( ( it = parag->lineStartList().find( index ) ) == parag->lineStartList().end() ) {
5105 parag->lineStartList().insert( index, ls ); 5105 parag->lineStartList().insert( index, ls );
5106 } else { 5106 } else {
5107 delete *it; 5107 delete *it;
5108 parag->lineStartList().remove( it ); 5108 parag->lineStartList().remove( it );
5109 parag->lineStartList().insert( index, ls ); 5109 parag->lineStartList().insert( index, ls );
5110 } 5110 }
5111} 5111}
5112 5112
5113 5113
5114/* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns 5114/* Standard pagebreak algorithm using QTextFlow::adjustFlow. Returns
5115 the shift of the paragraphs bottom line. 5115 the shift of the paragraphs bottom line.
5116 */ 5116 */
5117int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag ) 5117int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag )
5118{ 5118{
5119 int oldHeight = parag->rect().height(); 5119 int oldHeight = parag->rect().height();
5120 QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList(); 5120 QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList();
5121 QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin(); 5121 QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
5122 int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0; 5122 int h = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0;
5123 for ( ; it != lineStarts.end() ; ++it ) { 5123 for ( ; it != lineStarts.end() ; ++it ) {
5124 QTextLineStart * ls = it.data(); 5124 QTextLineStart * ls = it.data();
5125 ls->y = h; 5125 ls->y = h;
5126 QTextStringChar *c = &parag->string()->at(it.key()); 5126 QTextStringChar *c = &parag->string()->at(it.key());
5127 if ( c && c->customItem() && c->customItem()->ownLine() ) { 5127 if ( c && c->customItem() && c->customItem()->ownLine() ) {
5128 int h = c->customItem()->height; 5128 int h = c->customItem()->height;
5129 c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() ); 5129 c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() );
5130 int delta = c->customItem()->height - h; 5130 int delta = c->customItem()->height - h;
5131 ls->h += delta; 5131 ls->h += delta;
5132 if ( delta ) 5132 if ( delta )
5133 parag->setMovedDown( TRUE ); 5133 parag->setMovedDown( TRUE );
5134 } else { 5134 } else {
5135 int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h ); 5135 int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h );
5136 ls->y += shift; 5136 ls->y += shift;
5137 if ( shift ) 5137 if ( shift )
5138 parag->setMovedDown( TRUE ); 5138 parag->setMovedDown( TRUE );
5139 } 5139 }
5140 h = ls->y + ls->h; 5140 h = ls->y + ls->h;
5141 } 5141 }
5142 int m = parag->bottomMargin(); 5142 int m = parag->bottomMargin();
5143 if ( !parag->next() ) 5143 if ( !parag->next() )
5144 m = 0; 5144 m = 0;
5145 else 5145 else
5146 m = QMAX(m, parag->next()->topMargin() ) / 2; 5146 m = QMAX(m, parag->next()->topMargin() ) / 2;
5147 h += m; 5147 h += m;
5148 parag->setHeight( h ); 5148 parag->setHeight( h );
5149 return h - oldHeight; 5149 return h - oldHeight;
5150} 5150}
5151 5151
5152// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5152// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5153 5153
5154QTextFormatterBreakInWords::QTextFormatterBreakInWords() 5154QTextFormatterBreakInWords::QTextFormatterBreakInWords()
5155{ 5155{
5156} 5156}
5157 5157
5158#define SPACE(s) doc?(s>0?s:0):s 5158#define SPACE(s) doc?(s>0?s:0):s
5159 5159
5160int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag, 5160int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag,
5161 int start, const QMap<int, QTextLineStart*> & ) 5161 int start, const QMap<int, QTextLineStart*> & )
5162{ 5162{
5163 QTextStringChar *c = 0; 5163 QTextStringChar *c = 0;
5164 QTextStringChar *firstChar = 0; 5164 QTextStringChar *firstChar = 0;
5165 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; 5165 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
5166 int x = left + ( doc ? parag->firstLineMargin() : 0 ); 5166 int x = left + ( doc ? parag->firstLineMargin() : 0 );
5167 int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 ); 5167 int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 );
5168 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; 5168 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
5169 int h = y; 5169 int h = y;
5170 int len = parag->length(); 5170 int len = parag->length();
5171 if ( doc ) 5171 if ( doc )
5172 x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 ); 5172 x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 );
5173 int rm = parag->rightMargin(); 5173 int rm = parag->rightMargin();
5174 int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 ); 5174 int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
5175 bool fullWidth = TRUE; 5175 bool fullWidth = TRUE;
5176 int minw = 0; 5176 int minw = 0;
5177 int wused = 0; 5177 int wused = 0;
5178 bool wrapEnabled = isWrapEnabled( parag ); 5178 bool wrapEnabled = isWrapEnabled( parag );
5179 5179
5180 start = 0; //######### what is the point with start?! (Matthias) 5180 start = 0; //######### what is the point with start?! (Matthias)
5181 if ( start == 0 ) 5181 if ( start == 0 )
5182 c = &parag->string()->at( 0 ); 5182 c = &parag->string()->at( 0 );
5183 5183
5184 int i = start; 5184 int i = start;
5185 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); 5185 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
5186 insertLineStart( parag, 0, lineStart ); 5186 insertLineStart( parag, 0, lineStart );
5187 5187
5188 QPainter *painter = QTextFormat::painter(); 5188 QPainter *painter = QTextFormat::painter();
5189 5189
5190 int col = 0; 5190 int col = 0;
5191 int ww = 0; 5191 int ww = 0;
5192 QChar lastChr; 5192 QChar lastChr;
5193 for ( ; i < len; ++i, ++col ) { 5193 for ( ; i < len; ++i, ++col ) {
5194 if ( c ) 5194 if ( c )
5195 lastChr = c->c; 5195 lastChr = c->c;
5196 c = &parag->string()->at( i ); 5196 c = &parag->string()->at( i );
5197 c->rightToLeft = FALSE; 5197 c->rightToLeft = FALSE;
5198 // ### the lines below should not be needed 5198 // ### the lines below should not be needed
5199 if ( painter ) 5199 if ( painter )
5200 c->format()->setPainter( painter ); 5200 c->format()->setPainter( painter );
5201 if ( i > 0 ) { 5201 if ( i > 0 ) {
5202 c->lineStart = 0; 5202 c->lineStart = 0;
5203 } else { 5203 } else {
5204 c->lineStart = 1; 5204 c->lineStart = 1;
5205 firstChar = c; 5205 firstChar = c;
5206 } 5206 }
5207 if ( c->c.unicode() >= 32 || c->isCustom() ) { 5207 if ( c->c.unicode() >= 32 || c->isCustom() ) {
5208 ww = parag->string()->width( i ); 5208 ww = parag->string()->width( i );
5209 } else if ( c->c == '\t' ) { 5209 } else if ( c->c == '\t' ) {
5210 int nx = parag->nextTab( i, x - left ) + left; 5210 int nx = parag->nextTab( i, x - left ) + left;
5211 if ( nx < x ) 5211 if ( nx < x )
5212 ww = w - x; 5212 ww = w - x;
5213 else 5213 else
5214 ww = nx - x; 5214 ww = nx - x;
5215 } else { 5215 } else {
5216 ww = c->format()->width( ' ' ); 5216 ww = c->format()->width( ' ' );
5217 } 5217 }
5218 5218
5219 if ( c->isCustom() && c->customItem()->ownLine() ) { 5219 if ( c->isCustom() && c->customItem()->ownLine() ) {
5220 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5220 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 ); 5221 w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
5222 c->customItem()->resize( w - x ); 5222 c->customItem()->resize( w - x );
5223 w = dw; 5223 w = dw;
5224 y += h; 5224 y += h;
5225 h = c->height(); 5225 h = c->height();
5226 lineStart = new QTextLineStart( y, h, h ); 5226 lineStart = new QTextLineStart( y, h, h );
5227 insertLineStart( parag, i, lineStart ); 5227 insertLineStart( parag, i, lineStart );
5228 c->lineStart = 1; 5228 c->lineStart = 1;
5229 firstChar = c; 5229 firstChar = c;
5230 x = 0xffffff; 5230 x = 0xffffff;
5231 continue; 5231 continue;
5232 } 5232 }
5233 5233
5234 if ( wrapEnabled && 5234 if ( wrapEnabled &&
5235 ( wrapAtColumn() == -1 && x + ww > w || 5235 ( wrapAtColumn() == -1 && x + ww > w ||
5236 wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) { 5236 wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) {
5237 x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5237 x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
5238 w = dw; 5238 w = dw;
5239 y += h; 5239 y += h;
5240 h = c->height(); 5240 h = c->height();
5241 lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) ); 5241 lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) );
5242 lineStart->y = y; 5242 lineStart->y = y;
5243 insertLineStart( parag, i, lineStart ); 5243 insertLineStart( parag, i, lineStart );
5244 lineStart->baseLine = c->ascent(); 5244 lineStart->baseLine = c->ascent();
5245 lineStart->h = c->height(); 5245 lineStart->h = c->height();
5246 c->lineStart = 1; 5246 c->lineStart = 1;
5247 firstChar = c; 5247 firstChar = c;
5248 col = 0; 5248 col = 0;
5249 if ( wrapAtColumn() != -1 ) 5249 if ( wrapAtColumn() != -1 )
5250 minw = QMAX( minw, w ); 5250 minw = QMAX( minw, w );
5251 } else if ( lineStart ) { 5251 } else if ( lineStart ) {
5252 lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() ); 5252 lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() );
5253 h = QMAX( h, c->height() ); 5253 h = QMAX( h, c->height() );
5254 lineStart->h = h; 5254 lineStart->h = h;
5255 } 5255 }
5256 5256
5257 c->x = x; 5257 c->x = x;
5258 x += ww; 5258 x += ww;
5259 wused = QMAX( wused, x ); 5259 wused = QMAX( wused, x );
5260 } 5260 }
5261 5261
5262 int m = parag->bottomMargin(); 5262 int m = parag->bottomMargin();
5263 if ( !parag->next() ) 5263 if ( !parag->next() )
5264 m = 0; 5264 m = 0;
5265 else 5265 else
5266 m = QMAX(m, parag->next()->topMargin() ) / 2; 5266 m = QMAX(m, parag->next()->topMargin() ) / 2;
5267 parag->setFullWidth( fullWidth ); 5267 parag->setFullWidth( fullWidth );
5268 y += h + m; 5268 y += h + m;
5269 if ( doc ) 5269 if ( doc )
5270 minw += doc->rightMargin(); 5270 minw += doc->rightMargin();
5271 if ( !wrapEnabled ) 5271 if ( !wrapEnabled )
5272 minw = QMAX(minw, wused); 5272 minw = QMAX(minw, wused);
5273 5273
5274 thisminw = minw; 5274 thisminw = minw;
5275 thiswused = wused; 5275 thiswused = wused;
5276 return y; 5276 return y;
5277} 5277}
5278 5278
5279// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5279// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5280 5280
5281QTextFormatterBreakWords::QTextFormatterBreakWords() 5281QTextFormatterBreakWords::QTextFormatterBreakWords()
5282{ 5282{
5283} 5283}
5284 5284
5285#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \ 5285#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \
5286 int yflow = lineStart->y + parag->rect().y();\ 5286 int yflow = lineStart->y + parag->rect().y();\
5287 int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \ 5287 int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \
5288 lineStart->y += shift;\ 5288 lineStart->y += shift;\
5289 y += shift;\ 5289 y += shift;\
5290 }}while(FALSE) 5290 }}while(FALSE)
5291 5291
5292int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag, 5292int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag,
5293 int start, const QMap<int, QTextLineStart*> & ) 5293 int start, const QMap<int, QTextLineStart*> & )
5294{ 5294{
5295 QTextStringChar *c = 0; 5295 QTextStringChar *c = 0;
5296 QTextStringChar *firstChar = 0; 5296 QTextStringChar *firstChar = 0;
5297 QTextString *string = parag->string(); 5297 QTextString *string = parag->string();
5298 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0; 5298 int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
5299 int x = left + ( doc ? parag->firstLineMargin() : 0 ); 5299 int x = left + ( doc ? parag->firstLineMargin() : 0 );
5300 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0; 5300 int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
5301 int h = y; 5301 int h = y;
5302 int len = parag->length(); 5302 int len = parag->length();
5303 if ( doc ) 5303 if ( doc )
5304 x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 ); 5304 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 ); 5305 int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 );
5306 5306
5307 int curLeft = x; 5307 int curLeft = x;
5308 int rm = parag->rightMargin(); 5308 int rm = parag->rightMargin();
5309 int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0; 5309 int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0;
5310 int w = dw - rdiff; 5310 int w = dw - rdiff;
5311 bool fullWidth = TRUE; 5311 bool fullWidth = TRUE;
5312 int marg = left + rdiff; 5312 int marg = left + rdiff;
5313 int minw = 0; 5313 int minw = 0;
5314 int wused = 0; 5314 int wused = 0;
5315 int tminw = marg; 5315 int tminw = marg;
5316 int linespacing = doc ? parag->lineSpacing() : 0; 5316 int linespacing = doc ? parag->lineSpacing() : 0;
5317 bool wrapEnabled = isWrapEnabled( parag ); 5317 bool wrapEnabled = isWrapEnabled( parag );
5318 5318
5319 start = 0; 5319 start = 0;
5320 if ( start == 0 ) 5320 if ( start == 0 )
5321 c = &parag->string()->at( 0 ); 5321 c = &parag->string()->at( 0 );
5322 5322
5323 int i = start; 5323 int i = start;
5324 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 ); 5324 QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
5325 insertLineStart( parag, 0, lineStart ); 5325 insertLineStart( parag, 0, lineStart );
5326 int lastBreak = -1; 5326 int lastBreak = -1;
5327 int tmpBaseLine = 0, tmph = 0; 5327 int tmpBaseLine = 0, tmph = 0;
5328 bool lastWasNonInlineCustom = FALSE; 5328 bool lastWasNonInlineCustom = FALSE;
5329 5329
5330 int align = parag->alignment(); 5330 int align = parag->alignment();
5331 if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto ) 5331 if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto )
5332 align = doc->alignment(); 5332 align = doc->alignment();
5333 5333
5334 align &= Qt3::AlignHorizontal_Mask; 5334 align &= Qt3::AlignHorizontal_Mask;
5335 5335
5336 QPainter *painter = QTextFormat::painter(); 5336 QPainter *painter = QTextFormat::painter();
5337 int col = 0; 5337 int col = 0;
5338 int ww = 0; 5338 int ww = 0;
5339 QChar lastChr; 5339 QChar lastChr;
5340 for ( ; i < len; ++i, ++col ) { 5340 for ( ; i < len; ++i, ++col ) {
5341 if ( c ) 5341 if ( c )
5342 lastChr = c->c; 5342 lastChr = c->c;
5343 // ### next line should not be needed 5343 // ### next line should not be needed
5344 if ( painter ) 5344 if ( painter )
5345 c->format()->setPainter( painter ); 5345 c->format()->setPainter( painter );
5346 c = &string->at( i ); 5346 c = &string->at( i );
5347 c->rightToLeft = FALSE; 5347 c->rightToLeft = FALSE;
5348 if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) { 5348 if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) {
5349 c->lineStart = 0; 5349 c->lineStart = 0;
5350 } else { 5350 } else {
5351 c->lineStart = 1; 5351 c->lineStart = 1;
5352 firstChar = c; 5352 firstChar = c;
5353 } 5353 }
5354 5354
5355 if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline ) 5355 if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline )
5356 lastWasNonInlineCustom = TRUE; 5356 lastWasNonInlineCustom = TRUE;
5357 else 5357 else
5358 lastWasNonInlineCustom = FALSE; 5358 lastWasNonInlineCustom = FALSE;
5359 5359
5360 if ( c->c.unicode() >= 32 || c->isCustom() ) { 5360 if ( c->c.unicode() >= 32 || c->isCustom() ) {
5361 ww = string->width( i ); 5361 ww = string->width( i );
5362 } else if ( c->c == '\t' ) { 5362 } else if ( c->c == '\t' ) {
5363 int nx = parag->nextTab( i, x - left ) + left; 5363 int nx = parag->nextTab( i, x - left ) + left;
5364 if ( nx < x ) 5364 if ( nx < x )
5365 ww = w - x; 5365 ww = w - x;
5366 else 5366 else
5367 ww = nx - x; 5367 ww = nx - x;
5368 } else { 5368 } else {
5369 ww = c->format()->width( ' ' ); 5369 ww = c->format()->width( ' ' );
5370 } 5370 }
5371 5371
5372 // last character ("invisible" space) has no width 5372 // last character ("invisible" space) has no width
5373 if ( i == len - 1 ) 5373 if ( i == len - 1 )
5374 ww = 0; 5374 ww = 0;
5375 5375
5376 QTextCustomItem* ci = c->customItem(); 5376 QTextCustomItem* ci = c->customItem();
5377 if ( c->isCustom() && ci->ownLine() ) { 5377 if ( c->isCustom() && ci->ownLine() ) {
5378 x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left; 5378 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 ); 5379 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) ); 5380 QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
5381 ci->resize( w - x); 5381 ci->resize( w - x);
5382 if ( ci->width < w - x ) { 5382 if ( ci->width < w - x ) {
5383 if ( align & Qt::AlignHCenter ) 5383 if ( align & Qt::AlignHCenter )
5384 x = ( w - ci->width ) / 2; 5384 x = ( w - ci->width ) / 2;
5385 else if ( align & Qt::AlignRight ) { 5385 else if ( align & Qt::AlignRight ) {
5386 x = w - ci->width; 5386 x = w - ci->width;
5387 } 5387 }
5388 } 5388 }
5389 c->x = x; 5389 c->x = x;
5390 curLeft = x; 5390 curLeft = x;
5391 if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) { 5391 if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) {
5392 y += QMAX( h, QMAX( tmph, linespacing ) ); 5392 y += QMAX( h, QMAX( tmph, linespacing ) );
5393 tmph = c->height(); 5393 tmph = c->height();
5394 h = tmph; 5394 h = tmph;
5395 lineStart = lineStart2; 5395 lineStart = lineStart2;
5396 lineStart->y = y; 5396 lineStart->y = y;
5397 insertLineStart( parag, i, lineStart ); 5397 insertLineStart( parag, i, lineStart );
5398 c->lineStart = 1; 5398 c->lineStart = 1;
5399 firstChar = c; 5399 firstChar = c;
5400 } else { 5400 } else {
5401 tmph = c->height(); 5401 tmph = c->height();
5402 h = tmph; 5402 h = tmph;
5403 delete lineStart2; 5403 delete lineStart2;
5404 } 5404 }
5405 lineStart->h = h; 5405 lineStart->h = h;
5406 lineStart->baseLine = h; 5406 lineStart->baseLine = h;
5407 tmpBaseLine = lineStart->baseLine; 5407 tmpBaseLine = lineStart->baseLine;
5408 lastBreak = -2; 5408 lastBreak = -2;
5409 x = 0xffffff; 5409 x = 0xffffff;
5410 minw = QMAX( minw, tminw ); 5410 minw = QMAX( minw, tminw );
5411 5411
5412 int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 ); 5412 int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 );
5413 if ( tw < QWIDGETSIZE_MAX ) 5413 if ( tw < QWIDGETSIZE_MAX )
5414 tminw = tw; 5414 tminw = tw;
5415 else 5415 else
5416 tminw = marg; 5416 tminw = marg;
5417 wused = QMAX( wused, ci->width ); 5417 wused = QMAX( wused, ci->width );
5418 continue; 5418 continue;
5419 } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) { 5419 } else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) {
5420 int tw = ci->minimumWidth(); 5420 int tw = ci->minimumWidth();
5421 if ( tw < QWIDGETSIZE_MAX ) 5421 if ( tw < QWIDGETSIZE_MAX )
5422 minw = QMAX( minw, tw ); 5422 minw = QMAX( minw, tw );
5423 } 5423 }
5424 5424
5425 bool lastWasOwnLineCustomItem = lastBreak == -2; 5425 bool lastWasOwnLineCustomItem = lastBreak == -2;
5426 bool hadBreakableChar = lastBreak != -1; 5426 bool hadBreakableChar = lastBreak != -1;
5427 bool lastWasHardBreak = lastChr == QChar_linesep; 5427 bool lastWasHardBreak = lastChr == QChar_linesep;
5428 5428
5429 // we break if 5429 // we break if
5430 // 1. the last character was a hard break (QChar_linesep) or 5430 // 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 5431 // 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 5432 // 3. wrapping was enabled, it was not a space and following
5433 // condition is true: We either had a breakable character 5433 // condition is true: We either had a breakable character
5434 // previously or we ar allowed to break in words and - either 5434 // previously or we ar allowed to break in words and - either
5435 // we break at w pixels and the current char would exceed that 5435 // we break at w pixels and the current char would exceed that
5436 // or - we break at a column and the current character would 5436 // or - we break at a column and the current character would
5437 // exceed that. 5437 // exceed that.
5438 if ( lastWasHardBreak || lastWasOwnLineCustomItem || 5438 if ( lastWasHardBreak || lastWasOwnLineCustomItem ||
5439 ( wrapEnabled && 5439 ( wrapEnabled &&
5440 ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) && 5440 ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
5441 ( (wrapAtColumn() == -1 && x + ww > w) || 5441 ( (wrapAtColumn() == -1 && x + ww > w) ||
5442 (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) ) 5442 (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) )
5443 ) 5443 )
5444 ) { 5444 ) {
5445 if ( wrapAtColumn() != -1 ) 5445 if ( wrapAtColumn() != -1 )
5446 minw = QMAX( minw, x + ww ); 5446 minw = QMAX( minw, x + ww );
5447 // if a break was forced (no breakable char, hard break or own line custom item), break immediately.... 5447 // if a break was forced (no breakable char, hard break or own line custom item), break immediately....
5448 if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) { 5448 if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) {
5449 if ( lineStart ) { 5449 if ( lineStart ) {
5450 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); 5450 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine );
5451 h = QMAX( h, tmph ); 5451 h = QMAX( h, tmph );
5452 lineStart->h = h; 5452 lineStart->h = h;
5453 DO_FLOW( lineStart ); 5453 DO_FLOW( lineStart );
5454 } 5454 }
5455 lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) ); 5455 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; 5456 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 ); 5457 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 5458 if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
5459 int nx = parag->nextTab( i, x - left ) + left; 5459 int nx = parag->nextTab( i, x - left ) + left;
5460 if ( nx < x ) 5460 if ( nx < x )
5461 ww = w - x; 5461 ww = w - x;
5462 else 5462 else
5463 ww = nx - x; 5463 ww = nx - x;
5464 } 5464 }
5465 curLeft = x; 5465 curLeft = x;
5466 y += QMAX( h, linespacing ); 5466 y += QMAX( h, linespacing );
5467 tmph = c->height(); 5467 tmph = c->height();
5468 h = 0; 5468 h = 0;
5469 lineStart->y = y; 5469 lineStart->y = y;
5470 insertLineStart( parag, i, lineStart ); 5470 insertLineStart( parag, i, lineStart );
5471 lineStart->baseLine = c->ascent(); 5471 lineStart->baseLine = c->ascent();
5472 lineStart->h = c->height(); 5472 lineStart->h = c->height();
5473 c->lineStart = 1; 5473 c->lineStart = 1;
5474 firstChar = c; 5474 firstChar = c;
5475 tmpBaseLine = lineStart->baseLine; 5475 tmpBaseLine = lineStart->baseLine;
5476 lastBreak = -1; 5476 lastBreak = -1;
5477 col = 0; 5477 col = 0;
5478 } else { // ... otherwise if we had a breakable char, break there 5478 } else { // ... otherwise if we had a breakable char, break there
5479 DO_FLOW( lineStart ); 5479 DO_FLOW( lineStart );
5480 i = lastBreak; 5480 i = lastBreak;
5481 lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) ); 5481 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; 5482 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 ); 5483 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 5484 if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
5485 int nx = parag->nextTab( i, x - left ) + left; 5485 int nx = parag->nextTab( i, x - left ) + left;
5486 if ( nx < x ) 5486 if ( nx < x )
5487 ww = w - x; 5487 ww = w - x;
5488 else 5488 else
5489 ww = nx - x; 5489 ww = nx - x;
5490 } 5490 }
5491 curLeft = x; 5491 curLeft = x;
5492 y += QMAX( h, linespacing ); 5492 y += QMAX( h, linespacing );
5493 tmph = c->height(); 5493 tmph = c->height();
5494 h = tmph; 5494 h = tmph;
5495 lineStart->y = y; 5495 lineStart->y = y;
5496 insertLineStart( parag, i + 1, lineStart ); 5496 insertLineStart( parag, i + 1, lineStart );
5497 lineStart->baseLine = c->ascent(); 5497 lineStart->baseLine = c->ascent();
5498 lineStart->h = c->height(); 5498 lineStart->h = c->height();
5499 c->lineStart = 1; 5499 c->lineStart = 1;
5500 firstChar = c; 5500 firstChar = c;
5501 tmpBaseLine = lineStart->baseLine; 5501 tmpBaseLine = lineStart->baseLine;
5502 lastBreak = -1; 5502 lastBreak = -1;
5503 col = 0; 5503 col = 0;
5504 tminw = marg; 5504 tminw = marg;
5505 continue; 5505 continue;
5506 } 5506 }
5507 } else if ( lineStart && isBreakable( string, i ) ) { 5507 } else if ( lineStart && isBreakable( string, i ) ) {
5508 if ( len <= 2 || i < len - 1 ) { 5508 if ( len <= 2 || i < len - 1 ) {
5509 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); 5509 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() );
5510 tmph = QMAX( tmph, c->height() ); 5510 tmph = QMAX( tmph, c->height() );
5511 } 5511 }
5512 minw = QMAX( minw, tminw ); 5512 minw = QMAX( minw, tminw );
5513 tminw = marg + ww; 5513 tminw = marg + ww;
5514 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); 5514 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine );
5515 h = QMAX( h, tmph ); 5515 h = QMAX( h, tmph );
5516 lineStart->h = h; 5516 lineStart->h = h;
5517 if ( i < len - 2 || c->c != ' ' ) 5517 if ( i < len - 2 || c->c != ' ' )
5518 lastBreak = i; 5518 lastBreak = i;
5519 } else { 5519 } else {
5520 tminw += ww; 5520 tminw += ww;
5521 int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() ); 5521 int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() );
5522 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() ); 5522 tmpBaseLine = QMAX( tmpBaseLine, c->ascent() );
5523 tmph = tmpBaseLine + belowBaseLine; 5523 tmph = tmpBaseLine + belowBaseLine;
5524 } 5524 }
5525 5525
5526 c->x = x; 5526 c->x = x;
5527 x += ww; 5527 x += ww;
5528 wused = QMAX( wused, x ); 5528 wused = QMAX( wused, x );
5529 } 5529 }
5530 5530
5531 // ### hack. The last char in the paragraph is always invisible, 5531 // ### hack. The last char in the paragraph is always invisible,
5532 // ### and somehow sometimes has a wrong format. It changes 5532 // ### and somehow sometimes has a wrong format. It changes
5533 // ### between // layouting and printing. This corrects some 5533 // ### between // layouting and printing. This corrects some
5534 // ### layouting errors in BiDi mode due to this. 5534 // ### layouting errors in BiDi mode due to this.
5535 if ( len > 1 && !c->isAnchor() ) { 5535 if ( len > 1 && !c->isAnchor() ) {
5536 c->format()->removeRef(); 5536 c->format()->removeRef();
5537 c->setFormat( string->at( len - 2 ).format() ); 5537 c->setFormat( string->at( len - 2 ).format() );
5538 c->format()->addRef(); 5538 c->format()->addRef();
5539 } 5539 }
5540 5540
5541 if ( lineStart ) { 5541 if ( lineStart ) {
5542 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine ); 5542 lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine );
5543 h = QMAX( h, tmph ); 5543 h = QMAX( h, tmph );
5544 lineStart->h = h; 5544 lineStart->h = h;
5545 // last line in a paragraph is not justified 5545 // last line in a paragraph is not justified
5546 if ( align == Qt3::AlignJustify || lastChr == QChar_linesep ) 5546 if ( align == Qt3::AlignJustify || lastChr == QChar_linesep )
5547 align = Qt3::AlignAuto; 5547 align = Qt3::AlignAuto;
5548 DO_FLOW( lineStart ); 5548 DO_FLOW( lineStart );
5549 lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) ); 5549 lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) );
5550 delete lineStart; 5550 delete lineStart;
5551 } 5551 }
5552 5552
5553 minw = QMAX( minw, tminw ); 5553 minw = QMAX( minw, tminw );
5554 if ( doc ) 5554 if ( doc )
5555 minw += doc->rightMargin(); 5555 minw += doc->rightMargin();
5556 5556
5557 int m = parag->bottomMargin(); 5557 int m = parag->bottomMargin();
5558 if ( !parag->next() ) 5558 if ( !parag->next() )
5559 m = 0; 5559 m = 0;
5560 else 5560 else
5561 m = QMAX(m, parag->next()->topMargin() ) / 2; 5561 m = QMAX(m, parag->next()->topMargin() ) / 2;
5562 parag->setFullWidth( fullWidth ); 5562 parag->setFullWidth( fullWidth );
5563 y += QMAX( h, linespacing ) + m; 5563 y += QMAX( h, linespacing ) + m;
5564 5564
5565 wused += rm; 5565 wused += rm;
5566 if ( !wrapEnabled || wrapAtColumn() != -1 ) 5566 if ( !wrapEnabled || wrapAtColumn() != -1 )
5567 minw = QMAX(minw, wused); 5567 minw = QMAX(minw, wused);
5568 5568
5569 // This is the case where we are breaking wherever we darn well please 5569 // 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 5570 // 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. 5571 // word, because we necessarily want to show the word on the whole line.
5572 // example: word wrap in iconview 5572 // example: word wrap in iconview
5573 if ( allowBreakInWords() && minw > wused ) 5573 if ( allowBreakInWords() && minw > wused )
5574 minw = wused; 5574 minw = wused;
5575 5575
5576 thisminw = minw; 5576 thisminw = minw;
5577 thiswused = wused; 5577 thiswused = wused;
5578 return y; 5578 return y;
5579} 5579}
5580 5580
5581// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5581// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5582 5582
5583QTextIndent::QTextIndent() 5583QTextIndent::QTextIndent()
5584{ 5584{
5585} 5585}
5586 5586
5587// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5587// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5588 5588
5589QTextFormatCollection::QTextFormatCollection() 5589QTextFormatCollection::QTextFormatCollection()
5590 : cKey( 307 ) 5590 : cKey( 307 )
5591{ 5591{
5592 defFormat = new QTextFormat( QApplication::font(), 5592 defFormat = new QTextFormat( QApplication::font(),
5593 QApplication::palette().color( QPalette::Active, QColorGroup::Text ) ); 5593 QApplication::palette().color( QPalette::Active, QColorGroup::Text ) );
5594 lastFormat = cres = 0; 5594 lastFormat = cres = 0;
5595 cflags = -1; 5595 cflags = -1;
5596 cKey.setAutoDelete( TRUE ); 5596 cKey.setAutoDelete( TRUE );
5597 cachedFormat = 0; 5597 cachedFormat = 0;
5598} 5598}
5599 5599
5600QTextFormatCollection::~QTextFormatCollection() 5600QTextFormatCollection::~QTextFormatCollection()
5601{ 5601{
5602 delete defFormat; 5602 delete defFormat;
5603} 5603}
5604 5604
5605QTextFormat *QTextFormatCollection::format( QTextFormat *f ) 5605QTextFormat *QTextFormatCollection::format( QTextFormat *f )
5606{ 5606{
5607 if ( f->parent() == this || f == defFormat ) { 5607 if ( f->parent() == this || f == defFormat ) {
5608 lastFormat = f; 5608 lastFormat = f;
5609 lastFormat->addRef(); 5609 lastFormat->addRef();
5610 return lastFormat; 5610 return lastFormat;
5611 } 5611 }
5612 5612
5613 if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) { 5613 if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) {
5614 lastFormat->addRef(); 5614 lastFormat->addRef();
5615 return lastFormat; 5615 return lastFormat;
5616 } 5616 }
5617 5617
5618 QTextFormat *fm = cKey.find( f->key() ); 5618 QTextFormat *fm = cKey.find( f->key() );
5619 if ( fm ) { 5619 if ( fm ) {
5620 lastFormat = fm; 5620 lastFormat = fm;
5621 lastFormat->addRef(); 5621 lastFormat->addRef();
5622 return lastFormat; 5622 return lastFormat;
5623 } 5623 }
5624 5624
5625 if ( f->key() == defFormat->key() ) 5625 if ( f->key() == defFormat->key() )
5626 return defFormat; 5626 return defFormat;
5627 5627
5628 lastFormat = createFormat( *f ); 5628 lastFormat = createFormat( *f );
5629 lastFormat->collection = this; 5629 lastFormat->collection = this;
5630 cKey.insert( lastFormat->key(), lastFormat ); 5630 cKey.insert( lastFormat->key(), lastFormat );
5631 return lastFormat; 5631 return lastFormat;
5632} 5632}
5633 5633
5634QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags ) 5634QTextFormat *QTextFormatCollection::format( QTextFormat *of, QTextFormat *nf, int flags )
5635{ 5635{
5636 if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) { 5636 if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) {
5637 cres->addRef(); 5637 cres->addRef();
5638 return cres; 5638 return cres;
5639 } 5639 }
5640 5640
5641 cres = createFormat( *of ); 5641 cres = createFormat( *of );
5642 kof = of->key(); 5642 kof = of->key();
5643 knf = nf->key(); 5643 knf = nf->key();
5644 cflags = flags; 5644 cflags = flags;
5645 if ( flags & QTextFormat::Bold ) 5645 if ( flags & QTextFormat::Bold )
5646 cres->fn.setBold( nf->fn.bold() ); 5646 cres->fn.setBold( nf->fn.bold() );
5647 if ( flags & QTextFormat::Italic ) 5647 if ( flags & QTextFormat::Italic )
5648 cres->fn.setItalic( nf->fn.italic() ); 5648 cres->fn.setItalic( nf->fn.italic() );
5649 if ( flags & QTextFormat::Underline ) 5649 if ( flags & QTextFormat::Underline )
5650 cres->fn.setUnderline( nf->fn.underline() ); 5650 cres->fn.setUnderline( nf->fn.underline() );
5651 if ( flags & QTextFormat::StrikeOut ) 5651 if ( flags & QTextFormat::StrikeOut )
5652 cres->fn.setStrikeOut( nf->fn.strikeOut() ); 5652 cres->fn.setStrikeOut( nf->fn.strikeOut() );
5653 if ( flags & QTextFormat::Family ) 5653 if ( flags & QTextFormat::Family )
5654 cres->fn.setFamily( nf->fn.family() ); 5654 cres->fn.setFamily( nf->fn.family() );
5655 if ( flags & QTextFormat::Size ) { 5655 if ( flags & QTextFormat::Size ) {
5656 if ( of->usePixelSizes ) 5656 if ( of->usePixelSizes )
5657 cres->fn.setPixelSize( nf->fn.pixelSize() ); 5657 cres->fn.setPixelSize( nf->fn.pixelSize() );
5658 else 5658 else
5659 cres->fn.setPointSize( nf->fn.pointSize() ); 5659 cres->fn.setPointSize( nf->fn.pointSize() );
5660 } 5660 }
5661 if ( flags & QTextFormat::Color ) 5661 if ( flags & QTextFormat::Color )
5662 cres->col = nf->col; 5662 cres->col = nf->col;
5663 if ( flags & QTextFormat::Misspelled ) 5663 if ( flags & QTextFormat::Misspelled )
5664 cres->missp = nf->missp; 5664 cres->missp = nf->missp;
5665 if ( flags & QTextFormat::VAlign ) 5665 if ( flags & QTextFormat::VAlign )
5666 cres->ha = nf->ha; 5666 cres->ha = nf->ha;
5667 cres->update(); 5667 cres->update();
5668 5668
5669 QTextFormat *fm = cKey.find( cres->key() ); 5669 QTextFormat *fm = cKey.find( cres->key() );
5670 if ( !fm ) { 5670 if ( !fm ) {
5671 cres->collection = this; 5671 cres->collection = this;
5672 cKey.insert( cres->key(), cres ); 5672 cKey.insert( cres->key(), cres );
5673 } else { 5673 } else {
5674 delete cres; 5674 delete cres;
5675 cres = fm; 5675 cres = fm;
5676 cres->addRef(); 5676 cres->addRef();
5677 } 5677 }
5678 5678
5679 return cres; 5679 return cres;
5680} 5680}
5681 5681
5682QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c ) 5682QTextFormat *QTextFormatCollection::format( const QFont &f, const QColor &c )
5683{ 5683{
5684 if ( cachedFormat && cfont == f && ccol == c ) { 5684 if ( cachedFormat && cfont == f && ccol == c ) {
5685 cachedFormat->addRef(); 5685 cachedFormat->addRef();
5686 return cachedFormat; 5686 return cachedFormat;
5687 } 5687 }
5688 5688
5689 QString key = QTextFormat::getKey( f, c, FALSE, QTextFormat::AlignNormal ); 5689 QString key = QTextFormat::getKey( f, c, FALSE, QTextFormat::AlignNormal );
5690 cachedFormat = cKey.find( key ); 5690 cachedFormat = cKey.find( key );
5691 cfont = f; 5691 cfont = f;
5692 ccol = c; 5692 ccol = c;
5693 5693
5694 if ( cachedFormat ) { 5694 if ( cachedFormat ) {
5695 cachedFormat->addRef(); 5695 cachedFormat->addRef();
5696 return cachedFormat; 5696 return cachedFormat;
5697 } 5697 }
5698 5698
5699 if ( key == defFormat->key() ) 5699 if ( key == defFormat->key() )
5700 return defFormat; 5700 return defFormat;
5701 5701
5702 cachedFormat = createFormat( f, c ); 5702 cachedFormat = createFormat( f, c );
5703 cachedFormat->collection = this; 5703 cachedFormat->collection = this;
5704 cKey.insert( cachedFormat->key(), cachedFormat ); 5704 cKey.insert( cachedFormat->key(), cachedFormat );
5705 if ( cachedFormat->key() != key ) 5705 if ( cachedFormat->key() != key )
5706 owarn << "ASSERT: keys for format not identical: '" << cachedFormat->key().latin1() << " '" << key.latin1() << "'" << oendl; 5706 owarn << "ASSERT: keys for format not identical: '" << cachedFormat->key().latin1() << " '" << key.latin1() << "'" << oendl;
5707 return cachedFormat; 5707 return cachedFormat;
5708} 5708}
5709 5709
5710void QTextFormatCollection::remove( QTextFormat *f ) 5710void QTextFormatCollection::remove( QTextFormat *f )
5711{ 5711{
5712 if ( lastFormat == f ) 5712 if ( lastFormat == f )
5713 lastFormat = 0; 5713 lastFormat = 0;
5714 if ( cres == f ) 5714 if ( cres == f )
5715 cres = 0; 5715 cres = 0;
5716 if ( cachedFormat == f ) 5716 if ( cachedFormat == f )
5717 cachedFormat = 0; 5717 cachedFormat = 0;
5718 cKey.remove( f->key() ); 5718 cKey.remove( f->key() );
5719} 5719}
5720 5720
5721#define UPDATE( up, lo, rest ) \ 5721#define UPDATE( up, lo, rest ) \
5722 if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \ 5722 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() ) 5723 fm->fn.set##up##rest( font.lo##rest() )
5724 5724
5725void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet ) 5725void QTextFormatCollection::updateDefaultFormat( const QFont &font, const QColor &color, QStyleSheet *sheet )
5726{ 5726{
5727 QDictIterator<QTextFormat> it( cKey ); 5727 QDictIterator<QTextFormat> it( cKey );
5728 QTextFormat *fm; 5728 QTextFormat *fm;
5729 bool usePixels = font.pointSize() == -1; 5729 bool usePixels = font.pointSize() == -1;
5730 bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() : 5730 bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() :
5731 font.pointSize() != defFormat->fn.pointSize(); 5731 font.pointSize() != defFormat->fn.pointSize();
5732 int base = usePixels ? font.pixelSize() : font.pointSize(); 5732 int base = usePixels ? font.pixelSize() : font.pointSize();
5733 while ( ( fm = it.current() ) ) { 5733 while ( ( fm = it.current() ) ) {
5734 ++it; 5734 ++it;
5735 UPDATE( F, f, amily ); 5735 UPDATE( F, f, amily );
5736 UPDATE( W, w, eight ); 5736 UPDATE( W, w, eight );
5737 UPDATE( B, b, old ); 5737 UPDATE( B, b, old );
5738 UPDATE( I, i, talic ); 5738 UPDATE( I, i, talic );
5739 UPDATE( U, u, nderline ); 5739 UPDATE( U, u, nderline );
5740 if ( changeSize ) { 5740 if ( changeSize ) {
5741 fm->stdSize = base; 5741 fm->stdSize = base;
5742 fm->usePixelSizes = usePixels; 5742 fm->usePixelSizes = usePixels;
5743 if ( usePixels ) 5743 if ( usePixels )
5744 fm->fn.setPixelSize( fm->stdSize ); 5744 fm->fn.setPixelSize( fm->stdSize );
5745 else 5745 else
5746 fm->fn.setPointSize( fm->stdSize ); 5746 fm->fn.setPointSize( fm->stdSize );
5747 sheet->scaleFont( fm->fn, fm->logicalFontSize ); 5747 sheet->scaleFont( fm->fn, fm->logicalFontSize );
5748 } 5748 }
5749 if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col ) 5749 if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col )
5750 fm->col = color; 5750 fm->col = color;
5751 fm->update(); 5751 fm->update();
5752 } 5752 }
5753 5753
5754 defFormat->fn = font; 5754 defFormat->fn = font;
5755 defFormat->col = color; 5755 defFormat->col = color;
5756 defFormat->update(); 5756 defFormat->update();
5757 defFormat->stdSize = base; 5757 defFormat->stdSize = base;
5758 defFormat->usePixelSizes = usePixels; 5758 defFormat->usePixelSizes = usePixels;
5759 5759
5760 updateKeys(); 5760 updateKeys();
5761} 5761}
5762 5762
5763// the keys in cKey have changed, rebuild the hashtable 5763// the keys in cKey have changed, rebuild the hashtable
5764void QTextFormatCollection::updateKeys() 5764void QTextFormatCollection::updateKeys()
5765{ 5765{
5766 if ( cKey.isEmpty() ) 5766 if ( cKey.isEmpty() )
5767 return; 5767 return;
5768 cKey.setAutoDelete( FALSE ); 5768 cKey.setAutoDelete( FALSE );
5769 QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ]; 5769 QTextFormat** formats = new QTextFormat*[ cKey.count() + 1 ];
5770 QTextFormat **f = formats; 5770 QTextFormat **f = formats;
5771 QDictIterator<QTextFormat> it( cKey ); 5771 QDictIterator<QTextFormat> it( cKey );
5772 while ( ( *f = it.current() ) ) { 5772 while ( ( *f = it.current() ) ) {
5773 ++it; 5773 ++it;
5774 ++f; 5774 ++f;
5775 } 5775 }
5776 cKey.clear(); 5776 cKey.clear();
5777 for ( f = formats; *f; f++ ) 5777 for ( f = formats; *f; f++ )
5778 cKey.insert( (*f)->key(), *f ); 5778 cKey.insert( (*f)->key(), *f );
5779 cKey.setAutoDelete( TRUE ); 5779 cKey.setAutoDelete( TRUE );
5780 delete [] formats; 5780 delete [] formats;
5781} 5781}
5782 5782
5783 5783
5784 5784
5785// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5785// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5786 5786
5787void QTextFormat::setBold( bool b ) 5787void QTextFormat::setBold( bool b )
5788{ 5788{
5789 if ( b == fn.bold() ) 5789 if ( b == fn.bold() )
5790 return; 5790 return;
5791 fn.setBold( b ); 5791 fn.setBold( b );
5792 update(); 5792 update();
5793} 5793}
5794 5794
5795void QTextFormat::setMisspelled( bool b ) 5795void QTextFormat::setMisspelled( bool b )
5796{ 5796{
5797 if ( b == (bool)missp ) 5797 if ( b == (bool)missp )
5798 return; 5798 return;
5799 missp = b; 5799 missp = b;
5800 update(); 5800 update();
5801} 5801}
5802 5802
5803void QTextFormat::setVAlign( VerticalAlignment a ) 5803void QTextFormat::setVAlign( VerticalAlignment a )
5804{ 5804{
5805 if ( a == ha ) 5805 if ( a == ha )
5806 return; 5806 return;
5807 ha = a; 5807 ha = a;
5808 update(); 5808 update();
5809} 5809}
5810 5810
5811void QTextFormat::setItalic( bool b ) 5811void QTextFormat::setItalic( bool b )
5812{ 5812{
5813 if ( b == fn.italic() ) 5813 if ( b == fn.italic() )
5814 return; 5814 return;
5815 fn.setItalic( b ); 5815 fn.setItalic( b );
5816 update(); 5816 update();
5817} 5817}
5818 5818
5819void QTextFormat::setUnderline( bool b ) 5819void QTextFormat::setUnderline( bool b )
5820{ 5820{
5821 if ( b == fn.underline() ) 5821 if ( b == fn.underline() )
5822 return; 5822 return;
5823 fn.setUnderline( b ); 5823 fn.setUnderline( b );
5824 update(); 5824 update();
5825} 5825}
5826 5826
5827void QTextFormat::setStrikeOut( bool b ) 5827void QTextFormat::setStrikeOut( bool b )
5828{ 5828{
5829 if ( b == fn.strikeOut() ) 5829 if ( b == fn.strikeOut() )
5830 return; 5830 return;
5831 fn.setStrikeOut( b ); 5831 fn.setStrikeOut( b );
5832 update(); 5832 update();
5833} 5833}
5834 5834
5835void QTextFormat::setFamily( const QString &f ) 5835void QTextFormat::setFamily( const QString &f )
5836{ 5836{
5837 if ( f == fn.family() ) 5837 if ( f == fn.family() )
5838 return; 5838 return;
5839 fn.setFamily( f ); 5839 fn.setFamily( f );
5840 update(); 5840 update();
5841} 5841}
5842 5842
5843void QTextFormat::setPointSize( int s ) 5843void QTextFormat::setPointSize( int s )
5844{ 5844{
5845 if ( s == fn.pointSize() ) 5845 if ( s == fn.pointSize() )
5846 return; 5846 return;
5847 fn.setPointSize( s ); 5847 fn.setPointSize( s );
5848 usePixelSizes = FALSE; 5848 usePixelSizes = FALSE;
5849 update(); 5849 update();
5850} 5850}
5851 5851
5852void QTextFormat::setFont( const QFont &f ) 5852void QTextFormat::setFont( const QFont &f )
5853{ 5853{
5854 if ( f == fn && !k.isEmpty() ) 5854 if ( f == fn && !k.isEmpty() )
5855 return; 5855 return;
5856 fn = f; 5856 fn = f;
5857 update(); 5857 update();
5858} 5858}
5859 5859
5860void QTextFormat::setColor( const QColor &c ) 5860void QTextFormat::setColor( const QColor &c )
5861{ 5861{
5862 if ( c == col ) 5862 if ( c == col )
5863 return; 5863 return;
5864 col = c; 5864 col = c;
5865 update(); 5865 update();
5866} 5866}
5867 5867
5868QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f, 5868QString QTextFormat::makeFormatChangeTags( QTextFormat* defaultFormat, QTextFormat *f,
5869 const QString& oldAnchorHref, const QString& anchorHref ) const 5869 const QString& oldAnchorHref, const QString& anchorHref ) const
5870{ 5870{
5871 QString tag; 5871 QString tag;
5872 if ( f ) 5872 if ( f )
5873 tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref ); 5873 tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref );
5874 5874
5875 if ( !anchorHref.isEmpty() ) 5875 if ( !anchorHref.isEmpty() )
5876 tag += "<a href=\"" + anchorHref + "\">"; 5876 tag += "<a href=\"" + anchorHref + "\">";
5877 5877
5878 if ( font() != defaultFormat->font() 5878 if ( font() != defaultFormat->font()
5879 || vAlign() != defaultFormat->vAlign() 5879 || vAlign() != defaultFormat->vAlign()
5880 || color().rgb() != defaultFormat->color().rgb() ) { 5880 || color().rgb() != defaultFormat->color().rgb() ) {
5881 QString s; 5881 QString s;
5882 if ( font().family() != defaultFormat->font().family() ) 5882 if ( font().family() != defaultFormat->font().family() )
5883 s += QString(!!s?";":"") + "font-family:" + fn.family(); 5883 s += QString(!!s?";":"") + "font-family:" + fn.family();
5884 if ( font().italic() && font().italic() != defaultFormat->font().italic() ) 5884 if ( font().italic() && font().italic() != defaultFormat->font().italic() )
5885 s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal"); 5885 s += QString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal");
5886 if ( font().pointSize() != defaultFormat->font().pointSize() ) 5886 if ( font().pointSize() != defaultFormat->font().pointSize() )
5887 s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt"; 5887 s += QString(!!s?";":"") + "font-size:" + QString::number( fn.pointSize() ) + "pt";
5888 if ( font().weight() != defaultFormat->font().weight() ) 5888 if ( font().weight() != defaultFormat->font().weight() )
5889 s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 ); 5889 s += QString(!!s?";":"") + "font-weight:" + QString::number( fn.weight() * 8 );
5890 if ( font().underline() != defaultFormat->font().underline() ) 5890 if ( font().underline() != defaultFormat->font().underline() )
5891 s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none"); 5891 s += QString(!!s?";":"") + "text-decoration:" + ( font().underline() ? "underline" : "none");
5892 if ( vAlign() != defaultFormat->vAlign() ) { 5892 if ( vAlign() != defaultFormat->vAlign() ) {
5893 s += QString(!!s?";":"") + "vertical-align:"; 5893 s += QString(!!s?";":"") + "vertical-align:";
5894 if ( vAlign() == QTextFormat::AlignSuperScript ) 5894 if ( vAlign() == QTextFormat::AlignSuperScript )
5895 s += "super"; 5895 s += "super";
5896 else if ( vAlign() == QTextFormat::AlignSubScript ) 5896 else if ( vAlign() == QTextFormat::AlignSubScript )
5897 s += "sub"; 5897 s += "sub";
5898 else 5898 else
5899 s += "normal"; 5899 s += "normal";
5900 } 5900 }
5901 if ( color().rgb() != defaultFormat->color().rgb() ) 5901 if ( color().rgb() != defaultFormat->color().rgb() )
5902 s += QString(!!s?";":"") + "color:" + col.name(); 5902 s += QString(!!s?";":"") + "color:" + col.name();
5903 if ( !s.isEmpty() ) 5903 if ( !s.isEmpty() )
5904 tag += "<span style=\"" + s + "\">"; 5904 tag += "<span style=\"" + s + "\">";
5905 } 5905 }
5906 5906
5907 return tag; 5907 return tag;
5908} 5908}
5909 5909
5910QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const 5910QString QTextFormat::makeFormatEndTags( QTextFormat* defaultFormat, const QString& anchorHref ) const
5911{ 5911{
5912 QString tag; 5912 QString tag;
5913 if ( font().family() != defaultFormat->font().family() 5913 if ( font().family() != defaultFormat->font().family()
5914 || font().pointSize() != defaultFormat->font().pointSize() 5914 || font().pointSize() != defaultFormat->font().pointSize()
5915 || font().weight() != defaultFormat->font().weight() 5915 || font().weight() != defaultFormat->font().weight()
5916 || font().italic() != defaultFormat->font().italic() 5916 || font().italic() != defaultFormat->font().italic()
5917 || font().underline() != defaultFormat->font().underline() 5917 || font().underline() != defaultFormat->font().underline()
5918 || font().strikeOut() != defaultFormat->font().strikeOut() 5918 || font().strikeOut() != defaultFormat->font().strikeOut()
5919 || vAlign() != defaultFormat->vAlign() 5919 || vAlign() != defaultFormat->vAlign()
5920 || color().rgb() != defaultFormat->color().rgb() ) 5920 || color().rgb() != defaultFormat->color().rgb() )
5921 tag += "</span>"; 5921 tag += "</span>";
5922 if ( !anchorHref.isEmpty() ) 5922 if ( !anchorHref.isEmpty() )
5923 tag += "</a>"; 5923 tag += "</a>";
5924 return tag; 5924 return tag;
5925} 5925}
5926 5926
5927QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const 5927QTextFormat QTextFormat::makeTextFormat( const QStyleSheetItem *style, const QMap<QString,QString>& attr, double scaleFontsFactor ) const
5928{ 5928{
5929 QTextFormat format(*this); 5929 QTextFormat format(*this);
5930 if (!style ) 5930 if (!style )
5931 return format; 5931 return format;
5932 5932
5933 if ( !style->isAnchor() && style->color().isValid() ) { 5933 if ( !style->isAnchor() && style->color().isValid() ) {
5934 // the style is not an anchor and defines a color. 5934 // the style is not an anchor and defines a color.
5935 // It might be used inside an anchor and it should 5935 // It might be used inside an anchor and it should
5936 // override the link color. 5936 // override the link color.
5937 format.linkColor = FALSE; 5937 format.linkColor = FALSE;
5938 } 5938 }
5939 switch ( style->verticalAlignment() ) { 5939 switch ( style->verticalAlignment() ) {
5940 case QStyleSheetItem::VAlignBaseline: 5940 case QStyleSheetItem::VAlignBaseline:
5941 format.setVAlign( QTextFormat::AlignNormal ); 5941 format.setVAlign( QTextFormat::AlignNormal );
5942 break; 5942 break;
5943 case QStyleSheetItem::VAlignSuper: 5943 case QStyleSheetItem::VAlignSuper:
5944 format.setVAlign( QTextFormat::AlignSuperScript ); 5944 format.setVAlign( QTextFormat::AlignSuperScript );
5945 break; 5945 break;
5946 case QStyleSheetItem::VAlignSub: 5946 case QStyleSheetItem::VAlignSub:
5947 format.setVAlign( QTextFormat::AlignSubScript ); 5947 format.setVAlign( QTextFormat::AlignSubScript );
5948 break; 5948 break;
5949 } 5949 }
5950 5950
5951 if ( style->fontWeight() != QStyleSheetItem::Undefined ) 5951 if ( style->fontWeight() != QStyleSheetItem::Undefined )
5952 format.fn.setWeight( style->fontWeight() ); 5952 format.fn.setWeight( style->fontWeight() );
5953 if ( style->fontSize() != QStyleSheetItem::Undefined ) { 5953 if ( style->fontSize() != QStyleSheetItem::Undefined ) {
5954 format.fn.setPointSize( style->fontSize() ); 5954 format.fn.setPointSize( style->fontSize() );
5955 } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) { 5955 } else if ( style->logicalFontSize() != QStyleSheetItem::Undefined ) {
5956 format.logicalFontSize = style->logicalFontSize(); 5956 format.logicalFontSize = style->logicalFontSize();
5957 if ( format.usePixelSizes ) 5957 if ( format.usePixelSizes )
5958 format.fn.setPixelSize( format.stdSize ); 5958 format.fn.setPixelSize( format.stdSize );
5959 else 5959 else
5960 format.fn.setPointSize( format.stdSize ); 5960 format.fn.setPointSize( format.stdSize );
5961 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); 5961 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
5962 } else if ( style->logicalFontSizeStep() ) { 5962 } else if ( style->logicalFontSizeStep() ) {
5963 format.logicalFontSize += style->logicalFontSizeStep(); 5963 format.logicalFontSize += style->logicalFontSizeStep();
5964 if ( format.usePixelSizes ) 5964 if ( format.usePixelSizes )
5965 format.fn.setPixelSize( format.stdSize ); 5965 format.fn.setPixelSize( format.stdSize );
5966 else 5966 else
5967 format.fn.setPointSize( format.stdSize ); 5967 format.fn.setPointSize( format.stdSize );
5968 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); 5968 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
5969 } 5969 }
5970 if ( !style->fontFamily().isEmpty() ) 5970 if ( !style->fontFamily().isEmpty() )
5971 format.fn.setFamily( style->fontFamily() ); 5971 format.fn.setFamily( style->fontFamily() );
5972 if ( style->color().isValid() ) 5972 if ( style->color().isValid() )
5973 format.col = style->color(); 5973 format.col = style->color();
5974 if ( style->definesFontItalic() ) 5974 if ( style->definesFontItalic() )
5975 format.fn.setItalic( style->fontItalic() ); 5975 format.fn.setItalic( style->fontItalic() );
5976 if ( style->definesFontUnderline() ) 5976 if ( style->definesFontUnderline() )
5977 format.fn.setUnderline( style->fontUnderline() ); 5977 format.fn.setUnderline( style->fontUnderline() );
5978 if ( style->definesFontStrikeOut() ) 5978 if ( style->definesFontStrikeOut() )
5979 format.fn.setStrikeOut( style->fontStrikeOut() ); 5979 format.fn.setStrikeOut( style->fontStrikeOut() );
5980 5980
5981 5981
5982 if ( style->name() == "font") { 5982 if ( style->name() == "font") {
5983 if ( attr.contains("color") ) { 5983 if ( attr.contains("color") ) {
5984 QString s = attr["color"]; 5984 QString s = attr["color"];
5985 if ( !s.isEmpty() ) { 5985 if ( !s.isEmpty() ) {
5986 format.col.setNamedColor( s ); 5986 format.col.setNamedColor( s );
5987 format.linkColor = FALSE; 5987 format.linkColor = FALSE;
5988 } 5988 }
5989 } 5989 }
5990 if ( attr.contains("face") ) { 5990 if ( attr.contains("face") ) {
5991 QString a = attr["face"]; 5991 QString a = attr["face"];
5992 QString family = QTextDocument::section( a, ",", 0, 0 ); 5992 QString family = QTextDocument::section( a, ",", 0, 0 );
5993 if ( !!family ) 5993 if ( !!family )
5994 format.fn.setFamily( family ); 5994 format.fn.setFamily( family );
5995 } 5995 }
5996 if ( attr.contains("size") ) { 5996 if ( attr.contains("size") ) {
5997 QString a = attr["size"]; 5997 QString a = attr["size"];
5998 int n = a.toInt(); 5998 int n = a.toInt();
5999 if ( a[0] == '+' || a[0] == '-' ) 5999 if ( a[0] == '+' || a[0] == '-' )
6000 n += format.logicalFontSize; 6000 n += format.logicalFontSize;
6001 format.logicalFontSize = n; 6001 format.logicalFontSize = n;
6002 if ( format.usePixelSizes ) 6002 if ( format.usePixelSizes )
6003 format.fn.setPixelSize( format.stdSize ); 6003 format.fn.setPixelSize( format.stdSize );
6004 else 6004 else
6005 format.fn.setPointSize( format.stdSize ); 6005 format.fn.setPointSize( format.stdSize );
6006 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize ); 6006 style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
6007 } 6007 }
6008 } 6008 }
6009 if ( attr.contains("style" ) ) { 6009 if ( attr.contains("style" ) ) {
6010 QString a = attr["style"]; 6010 QString a = attr["style"];
6011 for ( int s = 0; s < a.contains(';')+1; s++ ) { 6011 for ( int s = 0; s < a.contains(';')+1; s++ ) {
6012 QString style = QTextDocument::section( a, ";", s, s ); 6012 QString style = QTextDocument::section( a, ";", s, s );
6013 if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) { 6013 if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) {
6014 format.logicalFontSize = 0; 6014 format.logicalFontSize = 0;
6015 format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) ); 6015 format.setPointSize( int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toInt() ) );
6016 } if ( style.startsWith("font-style:" ) ) { 6016 } if ( style.startsWith("font-style:" ) ) {
6017 QString s = style.mid( 11 ).stripWhiteSpace(); 6017 QString s = style.mid( 11 ).stripWhiteSpace();
6018 if ( s == "normal" ) 6018 if ( s == "normal" )
6019 format.fn.setItalic( FALSE ); 6019 format.fn.setItalic( FALSE );
6020 else if ( s == "italic" || s == "oblique" ) 6020 else if ( s == "italic" || s == "oblique" )
6021 format.fn.setItalic( TRUE ); 6021 format.fn.setItalic( TRUE );
6022 } else if ( style.startsWith("font-weight:" ) ) { 6022 } else if ( style.startsWith("font-weight:" ) ) {
6023 QString s = style.mid( 12 ); 6023 QString s = style.mid( 12 );
6024 bool ok = TRUE; 6024 bool ok = TRUE;
6025 int n = s.toInt( &ok ); 6025 int n = s.toInt( &ok );
6026 if ( ok ) 6026 if ( ok )
6027 format.fn.setWeight( n/8 ); 6027 format.fn.setWeight( n/8 );
6028 } else if ( style.startsWith("font-family:" ) ) { 6028 } else if ( style.startsWith("font-family:" ) ) {
6029 format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() ); 6029 format.fn.setFamily( QTextDocument::section(style.mid(12),",",0,0).stripWhiteSpace() );
6030 } else if ( style.startsWith("text-decoration:" ) ) { 6030 } else if ( style.startsWith("text-decoration:" ) ) {
6031 QString s = style.mid( 16 ).stripWhiteSpace(); 6031 QString s = style.mid( 16 ).stripWhiteSpace();
6032 format.fn.setUnderline( s == "underline" ); 6032 format.fn.setUnderline( s == "underline" );
6033 } else if ( style.startsWith("vertical-align:" ) ) { 6033 } else if ( style.startsWith("vertical-align:" ) ) {
6034 QString s = style.mid( 15 ).stripWhiteSpace(); 6034 QString s = style.mid( 15 ).stripWhiteSpace();
6035 if ( s == "sub" ) 6035 if ( s == "sub" )
6036 format.setVAlign( QTextFormat::AlignSubScript ); 6036 format.setVAlign( QTextFormat::AlignSubScript );
6037 else if ( s == "super" ) 6037 else if ( s == "super" )
6038 format.setVAlign( QTextFormat::AlignSuperScript ); 6038 format.setVAlign( QTextFormat::AlignSuperScript );
6039 else 6039 else
6040 format.setVAlign( QTextFormat::AlignNormal ); 6040 format.setVAlign( QTextFormat::AlignNormal );
6041 } else if ( style.startsWith("color:" ) ) { 6041 } else if ( style.startsWith("color:" ) ) {
6042 format.col.setNamedColor( style.mid(6) ); 6042 format.col.setNamedColor( style.mid(6) );
6043 format.linkColor = FALSE; 6043 format.linkColor = FALSE;
6044 } 6044 }
6045 } 6045 }
6046 } 6046 }
6047 6047
6048 format.update(); 6048 format.update();
6049 return format; 6049 return format;
6050} 6050}
6051 6051
6052struct QPixmapInt 6052struct QPixmapInt
6053{ 6053{
6054 QPixmapInt() : ref( 0 ) {} 6054 QPixmapInt() : ref( 0 ) {}
6055 QPixmap pm; 6055 QPixmap pm;
6056 int ref; 6056 int ref;
6057}; 6057};
6058 6058
6059static QMap<QString, QPixmapInt> *pixmap_map = 0; 6059static QMap<QString, QPixmapInt> *pixmap_map = 0;
6060 6060
6061QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context, 6061QTextImage::QTextImage( QTextDocument *p, const QMap<QString, QString> &attr, const QString& context,
6062 QMimeSourceFactory &factory ) 6062 QMimeSourceFactory &factory )
6063 : QTextCustomItem( p ) 6063 : QTextCustomItem( p ), reg( 0 )
6064{ 6064{
6065 width = height = 0; 6065 width = height = 0;
6066 if ( attr.contains("width") ) 6066 if ( attr.contains("width") )
6067 width = attr["width"].toInt(); 6067 width = attr["width"].toInt();
6068 if ( attr.contains("height") ) 6068 if ( attr.contains("height") )
6069 height = attr["height"].toInt(); 6069 height = attr["height"].toInt();
6070 6070
6071 reg = 0;
6072 QString imageName = attr["src"]; 6071 QString imageName = attr["src"];
6073 6072
6074 if (!imageName) 6073 if (!imageName)
6075 imageName = attr["source"]; 6074 imageName = attr["source"];
6076 6075
6077 if ( !imageName.isEmpty() ) { 6076 if ( !imageName.isEmpty() ) {
6078 imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory ); 6077 imgId = QString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory );
6079 if ( !pixmap_map ) 6078 if ( !pixmap_map )
6080 pixmap_map = new QMap<QString, QPixmapInt>; 6079 pixmap_map = new QMap<QString, QPixmapInt>;
6081 if ( pixmap_map->contains( imgId ) ) { 6080 if ( pixmap_map->contains( imgId ) ) {
6082 QPixmapInt& pmi = pixmap_map->operator[](imgId); 6081 QPixmapInt& pmi = pixmap_map->operator[](imgId);
6083 pm = pmi.pm; 6082 pm = pmi.pm;
6084 pmi.ref++; 6083 pmi.ref++;
6085 width = pm.width(); 6084 width = pm.width();
6086 height = pm.height(); 6085 height = pm.height();
6087 } else { 6086 } else {
6088 QImage img; 6087 QImage img;
6089 const QMimeSource* m = 6088 const QMimeSource* m =
6090 factory.data( imageName, context ); 6089 factory.data( imageName, context );
6091 if ( !m ) { 6090 if ( !m ) {
6092 owarn << "QTextImage: no mimesource for " << imageName.latin1() << "" << oendl; 6091 owarn << "QTextImage: no mimesource for " << imageName.latin1() << "" << oendl;
6093 } 6092 }
6094 else { 6093 else {
6095 if ( !QImageDrag::decode( m, img ) ) { 6094 if ( !QImageDrag::decode( m, img ) ) {
6096 owarn << "QTextImage: cannot decode " << imageName.latin1() << "" << oendl; 6095 owarn << "QTextImage: cannot decode " << imageName.latin1() << "" << oendl;
6097 } 6096 }
6098 } 6097 }
6099 6098
6100 if ( !img.isNull() ) { 6099 if ( !img.isNull() ) {
6101 if ( width == 0 ) { 6100 if ( width == 0 ) {
6102 width = img.width(); 6101 width = img.width();
6103 if ( height != 0 ) { 6102 if ( height != 0 ) {
6104 width = img.width() * height / img.height(); 6103 width = img.width() * height / img.height();
6105 } 6104 }
6106 } 6105 }
6107 if ( height == 0 ) { 6106 if ( height == 0 ) {
6108 height = img.height(); 6107 height = img.height();
6109 if ( width != img.width() ) { 6108 if ( width != img.width() ) {
6110 height = img.height() * width / img.width(); 6109 height = img.height() * width / img.width();
6111 } 6110 }
6112 } 6111 }
6113 if ( img.width() != width || img.height() != height ){ 6112 if ( img.width() != width || img.height() != height ){
6114#ifndef QT_NO_IMAGE_SMOOTHSCALE 6113#ifndef QT_NO_IMAGE_SMOOTHSCALE
6115 img = img.smoothScale(width, height); 6114 img = img.smoothScale(width, height);
6116#endif 6115#endif
6117 width = img.width(); 6116 width = img.width();
6118 height = img.height(); 6117 height = img.height();
6119 } 6118 }
6120 pm.convertFromImage( img ); 6119 pm.convertFromImage( img );
6121 } 6120 }
6122 if ( !pm.isNull() ) { 6121 if ( !pm.isNull() ) {
6123 QPixmapInt& pmi = pixmap_map->operator[](imgId); 6122 QPixmapInt& pmi = pixmap_map->operator[](imgId);
6124 pmi.pm = pm; 6123 pmi.pm = pm;
6125 pmi.ref++; 6124 pmi.ref++;
6126 } 6125 }
6127 } 6126 }
6128 if ( pm.mask() ) { 6127 if ( pm.mask() ) {
6129 QRegion mask( *pm.mask() ); 6128 QRegion mask( *pm.mask() );
6130 QRegion all( 0, 0, pm.width(), pm.height() ); 6129 QRegion all( 0, 0, pm.width(), pm.height() );
6131 reg = new QRegion( all.subtract( mask ) ); 6130 reg = new QRegion( all.subtract( mask ) );
6132 } 6131 }
6133 } 6132 }
6134 6133
6135 if ( pm.isNull() && (width*height)==0 ) 6134 if ( pm.isNull() && (width*height)==0 )
6136 width = height = 50; 6135 width = height = 50;
6137 6136
6138 place = PlaceInline; 6137 place = PlaceInline;
6139 if ( attr["align"] == "left" ) 6138 if ( attr["align"] == "left" )
6140 place = PlaceLeft; 6139 place = PlaceLeft;
6141 else if ( attr["align"] == "right" ) 6140 else if ( attr["align"] == "right" )
6142 place = PlaceRight; 6141 place = PlaceRight;
6143 6142
6144 tmpwidth = width; 6143 tmpwidth = width;
6145 tmpheight = height; 6144 tmpheight = height;
6146 6145
6147 attributes = attr; 6146 attributes = attr;
6148} 6147}
6149 6148
6150QTextImage::~QTextImage() 6149QTextImage::~QTextImage()
6151{ 6150{
6151 delete reg;
6152 if ( pixmap_map && pixmap_map->contains( imgId ) ) { 6152 if ( pixmap_map && pixmap_map->contains( imgId ) ) {
6153 QPixmapInt& pmi = pixmap_map->operator[](imgId); 6153 QPixmapInt& pmi = pixmap_map->operator[](imgId);
6154 pmi.ref--; 6154 pmi.ref--;
6155 if ( !pmi.ref ) { 6155 if ( !pmi.ref ) {
6156 pixmap_map->remove( imgId ); 6156 pixmap_map->remove( imgId );
6157 if ( pixmap_map->isEmpty() ) { 6157 if ( pixmap_map->isEmpty() ) {
6158 delete pixmap_map; 6158 delete pixmap_map;
6159 pixmap_map = 0; 6159 pixmap_map = 0;
6160 } 6160 }
6161 } 6161 }
6162 } 6162 }
6163 delete reg;
6164} 6163}
6165 6164
6166QString QTextImage::richText() const 6165QString QTextImage::richText() const
6167{ 6166{
6168 QString s; 6167 QString s;
6169 s += "<img "; 6168 s += "<img ";
6170 QMap<QString, QString>::ConstIterator it = attributes.begin(); 6169 QMap<QString, QString>::ConstIterator it = attributes.begin();
6171 for ( ; it != attributes.end(); ++it ) 6170 for ( ; it != attributes.end(); ++it )
6172 s += it.key() + "=" + *it + " "; 6171 s += it.key() + "=" + *it + " ";
6173 s += ">"; 6172 s += ">";
6174 return s; 6173 return s;
6175} 6174}
6176 6175
6177void QTextImage::adjustToPainter( QPainter* p ) 6176void QTextImage::adjustToPainter( QPainter* p )
6178{ 6177{
6179 width = scale( tmpwidth, p ); 6178 width = scale( tmpwidth, p );
6180 height = scale( tmpheight, p ); 6179 height = scale( tmpheight, p );
6181} 6180}
6182 6181
6183#if !defined(Q_WS_X11) 6182#if !defined(Q_WS_X11)
6184#include <qbitmap.h> 6183#include <qbitmap.h>
6185#include "qcleanuphandler.h" 6184#include "qcleanuphandler.h"
6186static QPixmap *qrt_selection = 0; 6185static QPixmap *qrt_selection = 0;
6187static QSingleCleanupHandler<QPixmap> qrt_cleanup_pixmap; 6186static QSingleCleanupHandler<QPixmap> qrt_cleanup_pixmap;
6188static void qrt_createSelectionPixmap( const QColorGroup &cg ) 6187static void qrt_createSelectionPixmap( const QColorGroup &cg )
6189{ 6188{
6190 qrt_selection = new QPixmap( 2, 2 ); 6189 qrt_selection = new QPixmap( 2, 2 );
6191 qrt_cleanup_pixmap.set( &qrt_selection ); 6190 qrt_cleanup_pixmap.set( &qrt_selection );
6192 qrt_selection->fill( Qt::color0 ); 6191 qrt_selection->fill( Qt::color0 );
6193 QBitmap m( 2, 2 ); 6192 QBitmap m( 2, 2 );
6194 m.fill( Qt::color1 ); 6193 m.fill( Qt::color1 );
6195 QPainter p( &m ); 6194 QPainter p( &m );
6196 p.setPen( Qt::color0 ); 6195 p.setPen( Qt::color0 );
6197 for ( int j = 0; j < 2; ++j ) { 6196 for ( int j = 0; j < 2; ++j ) {
6198 p.drawPoint( j % 2, j ); 6197 p.drawPoint( j % 2, j );
6199 } 6198 }
6200 p.end(); 6199 p.end();
6201 qrt_selection->setMask( m ); 6200 qrt_selection->setMask( m );
6202 qrt_selection->fill( cg.highlight() ); 6201 qrt_selection->fill( cg.highlight() );
6203} 6202}
6204#endif 6203#endif
6205 6204
6206void QTextImage::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) 6205void QTextImage::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected )
6207{ 6206{
6208 if ( placement() != PlaceInline ) { 6207 if ( placement() != PlaceInline ) {
6209 x = xpos; 6208 x = xpos;
6210 y = ypos; 6209 y = ypos;
6211 } 6210 }
6212 6211
6213 if ( pm.isNull() ) { 6212 if ( pm.isNull() ) {
6214 p->fillRect( x , y, width, height, cg.dark() ); 6213 p->fillRect( x , y, width, height, cg.dark() );
6215 return; 6214 return;
6216 } 6215 }
6217 6216
6218 if ( is_printer( p ) ) { 6217 if ( is_printer( p ) ) {
6219 p->drawPixmap( x, y, pm ); 6218 p->drawPixmap( x, y, pm );
6220 return; 6219 return;
6221 } 6220 }
6222 6221
6223 if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) ) 6222 if ( placement() != PlaceInline && !QRect( xpos, ypos, width, height ).intersects( QRect( cx, cy, cw, ch ) ) )
6224 return; 6223 return;
6225 6224
6226 if ( placement() == PlaceInline ) 6225 if ( placement() == PlaceInline )
6227 p->drawPixmap( x , y, pm ); 6226 p->drawPixmap( x , y, pm );
6228 else 6227 else
6229 p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch ); 6228 p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch );
6230 6229
6231 if ( selected && placement() == PlaceInline && is_printer( p ) ) { 6230 if ( selected && placement() == PlaceInline && is_printer( p ) ) {
6232#if defined(Q_WS_X11) 6231#if defined(Q_WS_X11)
6233 p->fillRect( QRect( QPoint( x, y ), pm.size() ), QBrush( cg.highlight(), QBrush::Dense4Pattern) ); 6232 p->fillRect( QRect( QPoint( x, y ), pm.size() ), QBrush( cg.highlight(), QBrush::Dense4Pattern) );
6234#else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it 6233#else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it
6235 if ( !qrt_selection ) 6234 if ( !qrt_selection )
6236 qrt_createSelectionPixmap( cg ); 6235 qrt_createSelectionPixmap( cg );
6237 p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection ); 6236 p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection );
6238#endif 6237#endif
6239 } 6238 }
6240} 6239}
6241 6240
6242void QTextHorizontalLine::adjustToPainter( QPainter* p ) 6241void QTextHorizontalLine::adjustToPainter( QPainter* p )
6243{ 6242{
6244 height = scale( tmpheight, p ); 6243 height = scale( tmpheight, p );
6245} 6244}
6246 6245
6247 6246
6248QTextHorizontalLine::QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr, 6247QTextHorizontalLine::QTextHorizontalLine( QTextDocument *p, const QMap<QString, QString> &attr,
6249 const QString &, 6248 const QString &,
6250 QMimeSourceFactory & ) 6249 QMimeSourceFactory & )
6251 : QTextCustomItem( p ) 6250 : QTextCustomItem( p )
6252{ 6251{
6253 height = tmpheight = 8; 6252 height = tmpheight = 8;
6254 if ( attr.find( "color" ) != attr.end() ) 6253 if ( attr.find( "color" ) != attr.end() )
6255 color = QColor( *attr.find( "color" ) ); 6254 color = QColor( *attr.find( "color" ) );
6256} 6255}
6257 6256
6258QTextHorizontalLine::~QTextHorizontalLine() 6257QTextHorizontalLine::~QTextHorizontalLine()
6259{ 6258{
6260} 6259}
6261 6260
6262QString QTextHorizontalLine::richText() const 6261QString QTextHorizontalLine::richText() const
6263{ 6262{
6264 return "<hr>"; 6263 return "<hr>";
6265} 6264}
6266 6265
6267void QTextHorizontalLine::draw( QPainter* p, int x, int y, int , int , int , int , const QColorGroup& cg, bool selected ) 6266void QTextHorizontalLine::draw( QPainter* p, int x, int y, int , int , int , int , const QColorGroup& cg, bool selected )
6268{ 6267{
6269 QRect r( x, y, width, height); 6268 QRect r( x, y, width, height);
6270 if ( is_printer( p ) ) { 6269 if ( is_printer( p ) ) {
6271 QPen oldPen = p->pen(); 6270 QPen oldPen = p->pen();
6272 if ( !color.isValid() ) 6271 if ( !color.isValid() )
6273 p->setPen( QPen( cg.text(), height/8 ) ); 6272 p->setPen( QPen( cg.text(), height/8 ) );
6274 else 6273 else
6275 p->setPen( QPen( color, height/8 ) ); 6274 p->setPen( QPen( color, height/8 ) );
6276 p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 ); 6275 p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 );
6277 p->setPen( oldPen ); 6276 p->setPen( oldPen );
6278 } else { 6277 } else {
6279 QColorGroup g( cg ); 6278 QColorGroup g( cg );
6280 if ( color.isValid() ) 6279 if ( color.isValid() )
6281 g.setColor( QColorGroup::Dark, color ); 6280 g.setColor( QColorGroup::Dark, color );
6282 if ( selected ) 6281 if ( selected )
6283 p->fillRect( r.left(), y, r.right(), y + height, g.highlight() ); 6282 p->fillRect( r.left(), y, r.right(), y + height, g.highlight() );
6284 qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 ); 6283 qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 );
6285 } 6284 }
6286} 6285}
6287 6286
6288 6287
6289/*****************************************************************/ 6288/*****************************************************************/
6290// Small set of utility functions to make the parser a bit simpler 6289// Small set of utility functions to make the parser a bit simpler
6291// 6290//
6292 6291
6293bool QTextDocument::hasPrefix(const QChar* doc, int length, int pos, QChar c) 6292bool QTextDocument::hasPrefix(const QChar* doc, int length, int pos, QChar c)
6294{ 6293{
6295 if ( pos >= length ) 6294 if ( pos >= length )
6296 return FALSE; 6295 return FALSE;
6297 return doc[ pos ].lower() == c.lower(); 6296 return doc[ pos ].lower() == c.lower();
6298} 6297}
6299 6298
6300bool QTextDocument::hasPrefix( const QChar* doc, int length, int pos, const QString& s ) 6299bool QTextDocument::hasPrefix( const QChar* doc, int length, int pos, const QString& s )
6301{ 6300{
6302 if ( pos + (int) s.length() >= length ) 6301 if ( pos + (int) s.length() >= length )
6303 return FALSE; 6302 return FALSE;
6304 for ( int i = 0; i < (int)s.length(); i++ ) { 6303 for ( int i = 0; i < (int)s.length(); i++ ) {
6305 if ( doc[ pos + i ].lower() != s[ i ].lower() ) 6304 if ( doc[ pos + i ].lower() != s[ i ].lower() )
6306 return FALSE; 6305 return FALSE;
6307 } 6306 }
6308 return TRUE; 6307 return TRUE;
6309} 6308}
6310 6309
6311static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col ) 6310static bool qt_is_cell_in_use( QPtrList<QTextTableCell>& cells, int row, int col )
6312{ 6311{
6313 for ( QTextTableCell* c = cells.first(); c; c = cells.next() ) { 6312 for ( QTextTableCell* c = cells.first(); c; c = cells.next() ) {
6314 if ( row >= c->row() && row < c->row() + c->rowspan() 6313 if ( row >= c->row() && row < c->row() + c->rowspan()
6315 && col >= c->column() && col < c->column() + c->colspan() ) 6314 && col >= c->column() && col < c->column() + c->colspan() )
6316 return TRUE; 6315 return TRUE;
6317 } 6316 }
6318 return FALSE; 6317 return FALSE;
6319} 6318}
6320 6319
6321QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt, 6320QTextCustomItem* QTextDocument::parseTable( const QMap<QString, QString> &attr, const QTextFormat &fmt,
6322 const QChar* doc, int length, int& pos, QTextParagraph *curpar ) 6321 const QChar* doc, int length, int& pos, QTextParagraph *curpar )
6323{ 6322{
6324 6323
6325 QTextTable* table = new QTextTable( this, attr ); 6324 QTextTable* table = new QTextTable( this, attr );
6326 int row = -1; 6325 int row = -1;
6327 int col = -1; 6326 int col = -1;
6328 6327
6329 QString rowbgcolor; 6328 QString rowbgcolor;
6330 QString rowalign; 6329 QString rowalign;
6331 QString tablebgcolor = attr["bgcolor"]; 6330 QString tablebgcolor = attr["bgcolor"];
6332 6331
6333 QPtrList<QTextTableCell> multicells; 6332 QPtrList<QTextTableCell> multicells;
6334 6333
6335 QString tagname; 6334 QString tagname;
6336 (void) eatSpace(doc, length, pos); 6335 (void) eatSpace(doc, length, pos);
6337 while ( pos < length) { 6336 while ( pos < length) {
6338 if (hasPrefix(doc, length, pos, QChar('<')) ){ 6337 if (hasPrefix(doc, length, pos, QChar('<')) ){
6339 if (hasPrefix(doc, length, pos+1, QChar('/'))) { 6338 if (hasPrefix(doc, length, pos+1, QChar('/'))) {
6340 tagname = parseCloseTag( doc, length, pos ); 6339 tagname = parseCloseTag( doc, length, pos );
6341 if ( tagname == "table" ) { 6340 if ( tagname == "table" ) {
6342 return table; 6341 return table;
6343 } 6342 }
6344 } else { 6343 } else {
6345 QMap<QString, QString> attr2; 6344 QMap<QString, QString> attr2;
6346 bool emptyTag = FALSE; 6345 bool emptyTag = FALSE;
6347 tagname = parseOpenTag( doc, length, pos, attr2, emptyTag ); 6346 tagname = parseOpenTag( doc, length, pos, attr2, emptyTag );
6348 if ( tagname == "tr" ) { 6347 if ( tagname == "tr" ) {
6349 rowbgcolor = attr2["bgcolor"]; 6348 rowbgcolor = attr2["bgcolor"];
6350 rowalign = attr2["align"]; 6349 rowalign = attr2["align"];
6351 row++; 6350 row++;
6352 col = -1; 6351 col = -1;
6353 } 6352 }
6354 else if ( tagname == "td" || tagname == "th" ) { 6353 else if ( tagname == "td" || tagname == "th" ) {
6355 col++; 6354 col++;
6356 while ( qt_is_cell_in_use( multicells, row, col ) ) { 6355 while ( qt_is_cell_in_use( multicells, row, col ) ) {
6357 col++; 6356 col++;
6358 } 6357 }
6359 6358
6360 if ( row >= 0 && col >= 0 ) { 6359 if ( row >= 0 && col >= 0 ) {
6361 const QStyleSheetItem* s = sheet_->item(tagname); 6360 const QStyleSheetItem* s = sheet_->item(tagname);
6362 if ( !attr2.contains("bgcolor") ) { 6361 if ( !attr2.contains("bgcolor") ) {
6363 if (!rowbgcolor.isEmpty() ) 6362 if (!rowbgcolor.isEmpty() )
6364 attr2["bgcolor"] = rowbgcolor; 6363 attr2["bgcolor"] = rowbgcolor;
6365 else if (!tablebgcolor.isEmpty() ) 6364 else if (!tablebgcolor.isEmpty() )
6366 attr2["bgcolor"] = tablebgcolor; 6365 attr2["bgcolor"] = tablebgcolor;
6367 } 6366 }
6368 if ( !attr2.contains("align") ) { 6367 if ( !attr2.contains("align") ) {
6369 if (!rowalign.isEmpty() ) 6368 if (!rowalign.isEmpty() )
6370 attr2["align"] = rowalign; 6369 attr2["align"] = rowalign;
6371 } 6370 }
6372 6371
6373 // extract the cell contents 6372 // extract the cell contents
6374 int end = pos; 6373 int end = pos;
6375 while ( end < length 6374 while ( end < length
6376 && !hasPrefix( doc, length, end, "</td") 6375 && !hasPrefix( doc, length, end, "</td")
6377 && !hasPrefix( doc, length, end, "<td") 6376 && !hasPrefix( doc, length, end, "<td")
6378 && !hasPrefix( doc, length, end, "</th") 6377 && !hasPrefix( doc, length, end, "</th")
6379 && !hasPrefix( doc, length, end, "<th") 6378 && !hasPrefix( doc, length, end, "<th")
6380 && !hasPrefix( doc, length, end, "<td") 6379 && !hasPrefix( doc, length, end, "<td")
6381 && !hasPrefix( doc, length, end, "</tr") 6380 && !hasPrefix( doc, length, end, "</tr")
6382 && !hasPrefix( doc, length, end, "<tr") 6381 && !hasPrefix( doc, length, end, "<tr")
6383 && !hasPrefix( doc, length, end, "</table") ) { 6382 && !hasPrefix( doc, length, end, "</table") ) {
6384 if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table 6383 if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table
6385 int nested = 1; 6384 int nested = 1;
6386 ++end; 6385 ++end;
6387 while ( end < length && nested != 0 ) { 6386 while ( end < length && nested != 0 ) {
6388 if ( hasPrefix( doc, length, end, "</table" ) ) 6387 if ( hasPrefix( doc, length, end, "</table" ) )
6389 nested--; 6388 nested--;
6390 if ( hasPrefix( doc, length, end, "<table" ) ) 6389 if ( hasPrefix( doc, length, end, "<table" ) )
6391 nested++; 6390 nested++;
6392 end++; 6391 end++;
6393 } 6392 }
6394 } 6393 }
6395 end++; 6394 end++;
6396 } 6395 }
6397 QTextTableCell* cell = new QTextTableCell( table, row, col, 6396 QTextTableCell* cell = new QTextTableCell( table, row, col,
6398 attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ), 6397 attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ),
6399 contxt, *factory_, sheet_, 6398 contxt, *factory_, sheet_,
6400 QString( doc, length).mid( pos, end - pos ) ); 6399 QString( doc, length).mid( pos, end - pos ) );
6401 cell->richText()->parentPar = curpar; 6400 cell->richText()->parentPar = curpar;
6402 if ( cell->colspan() > 1 || cell->rowspan() > 1 ) 6401 if ( cell->colspan() > 1 || cell->rowspan() > 1 )
6403 multicells.append( cell ); 6402 multicells.append( cell );
6404 col += cell->colspan()-1; 6403 col += cell->colspan()-1;
6405 pos = end; 6404 pos = end;
6406 } 6405 }
6407 } 6406 }
6408 } 6407 }
6409 6408
6410 } else { 6409 } else {
6411 ++pos; 6410 ++pos;
6412 } 6411 }
6413 } 6412 }
6414 return table; 6413 return table;
6415} 6414}
6416 6415
6417bool QTextDocument::eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp ) 6416bool QTextDocument::eatSpace(const QChar* doc, int length, int& pos, bool includeNbsp )
6418{ 6417{
6419 int old_pos = pos; 6418 int old_pos = pos;
6420 while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != QChar::nbsp ) ) ) 6419 while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != QChar::nbsp ) ) )
6421 pos++; 6420 pos++;
6422 return old_pos < pos; 6421 return old_pos < pos;
6423} 6422}
6424 6423
6425bool QTextDocument::eat(const QChar* doc, int length, int& pos, QChar c) 6424bool QTextDocument::eat(const QChar* doc, int length, int& pos, QChar c)
6426{ 6425{
6427 bool ok = pos < length && doc[pos] == c; 6426 bool ok = pos < length && doc[pos] == c;
6428 if ( ok ) 6427 if ( ok )
6429 pos++; 6428 pos++;
6430 return ok; 6429 return ok;
6431} 6430}
6432/*****************************************************************/ 6431/*****************************************************************/
6433 6432
6434struct Entity { 6433struct Entity {
6435 const char * name; 6434 const char * name;
6436 Q_UINT16 code; 6435 Q_UINT16 code;
6437}; 6436};
6438 6437
6439static const Entity entitylist [] = { 6438static const Entity entitylist [] = {
6440 { "AElig", 0x00c6 }, 6439 { "AElig", 0x00c6 },
6441 { "Aacute", 0x00c1 }, 6440 { "Aacute", 0x00c1 },
6442 { "Acirc", 0x00c2 }, 6441 { "Acirc", 0x00c2 },
6443 { "Agrave", 0x00c0 }, 6442 { "Agrave", 0x00c0 },
6444 { "Alpha", 0x0391 }, 6443 { "Alpha", 0x0391 },
6445 { "AMP", 38 }, 6444 { "AMP", 38 },
6446 { "Aring", 0x00c5 }, 6445 { "Aring", 0x00c5 },
6447 { "Atilde", 0x00c3 }, 6446 { "Atilde", 0x00c3 },
6448 { "Auml", 0x00c4 }, 6447 { "Auml", 0x00c4 },
6449 { "Beta", 0x0392 }, 6448 { "Beta", 0x0392 },
6450 { "Ccedil", 0x00c7 }, 6449 { "Ccedil", 0x00c7 },
6451 { "Chi", 0x03a7 }, 6450 { "Chi", 0x03a7 },
6452 { "Dagger", 0x2021 }, 6451 { "Dagger", 0x2021 },
6453 { "Delta", 0x0394 }, 6452 { "Delta", 0x0394 },
6454 { "ETH", 0x00d0 }, 6453 { "ETH", 0x00d0 },
6455 { "Eacute", 0x00c9 }, 6454 { "Eacute", 0x00c9 },
6456 { "Ecirc", 0x00ca }, 6455 { "Ecirc", 0x00ca },
6457 { "Egrave", 0x00c8 }, 6456 { "Egrave", 0x00c8 },
6458 { "Epsilon", 0x0395 }, 6457 { "Epsilon", 0x0395 },
6459 { "Eta", 0x0397 }, 6458 { "Eta", 0x0397 },
6460 { "Euml", 0x00cb }, 6459 { "Euml", 0x00cb },
6461 { "Gamma", 0x0393 }, 6460 { "Gamma", 0x0393 },
6462 { "GT", 62 }, 6461 { "GT", 62 },
6463 { "Iacute", 0x00cd }, 6462 { "Iacute", 0x00cd },
6464 { "Icirc", 0x00ce }, 6463 { "Icirc", 0x00ce },
6465 { "Igrave", 0x00cc }, 6464 { "Igrave", 0x00cc },
6466 { "Iota", 0x0399 }, 6465 { "Iota", 0x0399 },
6467 { "Iuml", 0x00cf }, 6466 { "Iuml", 0x00cf },
6468 { "Kappa", 0x039a }, 6467 { "Kappa", 0x039a },
6469 { "Lambda", 0x039b }, 6468 { "Lambda", 0x039b },
6470 { "LT", 60 }, 6469 { "LT", 60 },
6471 { "Mu", 0x039c }, 6470 { "Mu", 0x039c },
6472 { "Ntilde", 0x00d1 }, 6471 { "Ntilde", 0x00d1 },
6473 { "Nu", 0x039d }, 6472 { "Nu", 0x039d },
6474 { "OElig", 0x0152 }, 6473 { "OElig", 0x0152 },
6475 { "Oacute", 0x00d3 }, 6474 { "Oacute", 0x00d3 },
6476 { "Ocirc", 0x00d4 }, 6475 { "Ocirc", 0x00d4 },
6477 { "Ograve", 0x00d2 }, 6476 { "Ograve", 0x00d2 },
6478 { "Omega", 0x03a9 }, 6477 { "Omega", 0x03a9 },
6479 { "Omicron", 0x039f }, 6478 { "Omicron", 0x039f },
6480 { "Oslash", 0x00d8 }, 6479 { "Oslash", 0x00d8 },
6481 { "Otilde", 0x00d5 }, 6480 { "Otilde", 0x00d5 },
6482 { "Ouml", 0x00d6 }, 6481 { "Ouml", 0x00d6 },
6483 { "Phi", 0x03a6 }, 6482 { "Phi", 0x03a6 },
6484 { "Pi", 0x03a0 }, 6483 { "Pi", 0x03a0 },
6485 { "Prime", 0x2033 }, 6484 { "Prime", 0x2033 },
6486 { "Psi", 0x03a8 }, 6485 { "Psi", 0x03a8 },
6487 { "QUOT", 34 }, 6486 { "QUOT", 34 },
6488 { "Rho", 0x03a1 }, 6487 { "Rho", 0x03a1 },
6489 { "Scaron", 0x0160 }, 6488 { "Scaron", 0x0160 },
6490 { "Sigma", 0x03a3 }, 6489 { "Sigma", 0x03a3 },
6491 { "THORN", 0x00de }, 6490 { "THORN", 0x00de },
6492 { "Tau", 0x03a4 }, 6491 { "Tau", 0x03a4 },
6493 { "Theta", 0x0398 }, 6492 { "Theta", 0x0398 },
6494 { "Uacute", 0x00da }, 6493 { "Uacute", 0x00da },
6495 { "Ucirc", 0x00db }, 6494 { "Ucirc", 0x00db },
6496 { "Ugrave", 0x00d9 }, 6495 { "Ugrave", 0x00d9 },
6497 { "Upsilon", 0x03a5 }, 6496 { "Upsilon", 0x03a5 },
6498 { "Uuml", 0x00dc }, 6497 { "Uuml", 0x00dc },
6499 { "Xi", 0x039e }, 6498 { "Xi", 0x039e },
6500 { "Yacute", 0x00dd }, 6499 { "Yacute", 0x00dd },
6501 { "Yuml", 0x0178 }, 6500 { "Yuml", 0x0178 },
6502 { "Zeta", 0x0396 }, 6501 { "Zeta", 0x0396 },
6503 { "aacute", 0x00e1 }, 6502 { "aacute", 0x00e1 },
6504 { "acirc", 0x00e2 }, 6503 { "acirc", 0x00e2 },
6505 { "acute", 0x00b4 }, 6504 { "acute", 0x00b4 },
6506 { "aelig", 0x00e6 }, 6505 { "aelig", 0x00e6 },
6507 { "agrave", 0x00e0 }, 6506 { "agrave", 0x00e0 },
6508 { "alefsym", 0x2135 }, 6507 { "alefsym", 0x2135 },
6509 { "alpha", 0x03b1 }, 6508 { "alpha", 0x03b1 },
6510 { "amp", 38 }, 6509 { "amp", 38 },
6511 { "and", 0x22a5 }, 6510 { "and", 0x22a5 },
6512 { "ang", 0x2220 }, 6511 { "ang", 0x2220 },
6513 { "apos", 0x0027 }, 6512 { "apos", 0x0027 },
6514 { "aring", 0x00e5 }, 6513 { "aring", 0x00e5 },
6515 { "asymp", 0x2248 }, 6514 { "asymp", 0x2248 },
6516 { "atilde", 0x00e3 }, 6515 { "atilde", 0x00e3 },
6517 { "auml", 0x00e4 }, 6516 { "auml", 0x00e4 },
6518 { "bdquo", 0x201e }, 6517 { "bdquo", 0x201e },
6519 { "beta", 0x03b2 }, 6518 { "beta", 0x03b2 },
6520 { "brvbar", 0x00a6 }, 6519 { "brvbar", 0x00a6 },
6521 { "bull", 0x2022 }, 6520 { "bull", 0x2022 },
6522 { "cap", 0x2229 }, 6521 { "cap", 0x2229 },
6523 { "ccedil", 0x00e7 }, 6522 { "ccedil", 0x00e7 },
6524 { "cedil", 0x00b8 }, 6523 { "cedil", 0x00b8 },
6525 { "cent", 0x00a2 }, 6524 { "cent", 0x00a2 },
6526 { "chi", 0x03c7 }, 6525 { "chi", 0x03c7 },
6527 { "circ", 0x02c6 }, 6526 { "circ", 0x02c6 },
6528 { "clubs", 0x2663 }, 6527 { "clubs", 0x2663 },
6529 { "cong", 0x2245 }, 6528 { "cong", 0x2245 },
6530 { "copy", 0x00a9 }, 6529 { "copy", 0x00a9 },
6531 { "crarr", 0x21b5 }, 6530 { "crarr", 0x21b5 },
6532 { "cup", 0x222a }, 6531 { "cup", 0x222a },
6533 { "curren", 0x00a4 }, 6532 { "curren", 0x00a4 },
6534 { "dArr", 0x21d3 }, 6533 { "dArr", 0x21d3 },
6535 { "dagger", 0x2020 }, 6534 { "dagger", 0x2020 },
6536 { "darr", 0x2193 }, 6535 { "darr", 0x2193 },
6537 { "deg", 0x00b0 }, 6536 { "deg", 0x00b0 },
6538 { "delta", 0x03b4 }, 6537 { "delta", 0x03b4 },
6539 { "diams", 0x2666 }, 6538 { "diams", 0x2666 },
6540 { "divide", 0x00f7 }, 6539 { "divide", 0x00f7 },
6541 { "eacute", 0x00e9 }, 6540 { "eacute", 0x00e9 },
6542 { "ecirc", 0x00ea }, 6541 { "ecirc", 0x00ea },
6543 { "egrave", 0x00e8 }, 6542 { "egrave", 0x00e8 },
6544 { "empty", 0x2205 }, 6543 { "empty", 0x2205 },
6545 { "emsp", 0x2003 }, 6544 { "emsp", 0x2003 },
6546 { "ensp", 0x2002 }, 6545 { "ensp", 0x2002 },
6547 { "epsilon", 0x03b5 }, 6546 { "epsilon", 0x03b5 },
6548 { "equiv", 0x2261 }, 6547 { "equiv", 0x2261 },
6549 { "eta", 0x03b7 }, 6548 { "eta", 0x03b7 },
6550 { "eth", 0x00f0 }, 6549 { "eth", 0x00f0 },
6551 { "euml", 0x00eb }, 6550 { "euml", 0x00eb },
6552 { "euro", 0x20ac }, 6551 { "euro", 0x20ac },
6553 { "exist", 0x2203 }, 6552 { "exist", 0x2203 },
6554 { "fnof", 0x0192 }, 6553 { "fnof", 0x0192 },
6555 { "forall", 0x2200 }, 6554 { "forall", 0x2200 },
6556 { "frac12", 0x00bd }, 6555 { "frac12", 0x00bd },
6557 { "frac14", 0x00bc }, 6556 { "frac14", 0x00bc },
6558 { "frac34", 0x00be }, 6557 { "frac34", 0x00be },
6559 { "frasl", 0x2044 }, 6558 { "frasl", 0x2044 },
6560 { "gamma", 0x03b3 }, 6559 { "gamma", 0x03b3 },
6561 { "ge", 0x2265 }, 6560 { "ge", 0x2265 },
6562 { "gt", 62 }, 6561 { "gt", 62 },
6563 { "hArr", 0x21d4 }, 6562 { "hArr", 0x21d4 },
6564 { "harr", 0x2194 }, 6563 { "harr", 0x2194 },
6565 { "hearts", 0x2665 }, 6564 { "hearts", 0x2665 },
6566 { "hellip", 0x2026 }, 6565 { "hellip", 0x2026 },
6567 { "iacute", 0x00ed }, 6566 { "iacute", 0x00ed },
6568 { "icirc", 0x00ee }, 6567 { "icirc", 0x00ee },
6569 { "iexcl", 0x00a1 }, 6568 { "iexcl", 0x00a1 },
6570 { "igrave", 0x00ec }, 6569 { "igrave", 0x00ec },
6571 { "image", 0x2111 }, 6570 { "image", 0x2111 },
6572 { "infin", 0x221e }, 6571 { "infin", 0x221e },
6573 { "int", 0x222b }, 6572 { "int", 0x222b },
6574 { "iota", 0x03b9 }, 6573 { "iota", 0x03b9 },
6575 { "iquest", 0x00bf }, 6574 { "iquest", 0x00bf },
6576 { "isin", 0x2208 }, 6575 { "isin", 0x2208 },
6577 { "iuml", 0x00ef }, 6576 { "iuml", 0x00ef },
6578 { "kappa", 0x03ba }, 6577 { "kappa", 0x03ba },
6579 { "lArr", 0x21d0 }, 6578 { "lArr", 0x21d0 },
6580 { "lambda", 0x03bb }, 6579 { "lambda", 0x03bb },
6581 { "lang", 0x2329 }, 6580 { "lang", 0x2329 },
6582 { "laquo", 0x00ab }, 6581 { "laquo", 0x00ab },
6583 { "larr", 0x2190 }, 6582 { "larr", 0x2190 },
6584 { "lceil", 0x2308 }, 6583 { "lceil", 0x2308 },
6585 { "ldquo", 0x201c }, 6584 { "ldquo", 0x201c },
6586 { "le", 0x2264 }, 6585 { "le", 0x2264 },
6587 { "lfloor", 0x230a }, 6586 { "lfloor", 0x230a },
6588 { "lowast", 0x2217 }, 6587 { "lowast", 0x2217 },
6589 { "loz", 0x25ca }, 6588 { "loz", 0x25ca },
6590 { "lrm", 0x200e }, 6589 { "lrm", 0x200e },
6591 { "lsaquo", 0x2039 }, 6590 { "lsaquo", 0x2039 },
6592 { "lsquo", 0x2018 }, 6591 { "lsquo", 0x2018 },
6593 { "lt", 60 }, 6592 { "lt", 60 },
6594 { "macr", 0x00af }, 6593 { "macr", 0x00af },
6595 { "mdash", 0x2014 }, 6594 { "mdash", 0x2014 },
6596 { "micro", 0x00b5 }, 6595 { "micro", 0x00b5 },
6597 { "middot", 0x00b7 }, 6596 { "middot", 0x00b7 },
6598 { "minus", 0x2212 }, 6597 { "minus", 0x2212 },
6599 { "mu", 0x03bc }, 6598 { "mu", 0x03bc },
6600 { "nabla", 0x2207 }, 6599 { "nabla", 0x2207 },
6601 { "nbsp", 0x00a0 }, 6600 { "nbsp", 0x00a0 },
6602 { "ndash", 0x2013 }, 6601 { "ndash", 0x2013 },
6603 { "ne", 0x2260 }, 6602 { "ne", 0x2260 },
6604 { "ni", 0x220b }, 6603 { "ni", 0x220b },
6605 { "not", 0x00ac }, 6604 { "not", 0x00ac },
6606 { "notin", 0x2209 }, 6605 { "notin", 0x2209 },
6607 { "nsub", 0x2284 }, 6606 { "nsub", 0x2284 },
6608 { "ntilde", 0x00f1 }, 6607 { "ntilde", 0x00f1 },
6609 { "nu", 0x03bd }, 6608 { "nu", 0x03bd },
6610 { "oacute", 0x00f3 }, 6609 { "oacute", 0x00f3 },
6611 { "ocirc", 0x00f4 }, 6610 { "ocirc", 0x00f4 },
6612 { "oelig", 0x0153 }, 6611 { "oelig", 0x0153 },
6613 { "ograve", 0x00f2 }, 6612 { "ograve", 0x00f2 },
6614 { "oline", 0x203e }, 6613 { "oline", 0x203e },
6615 { "omega", 0x03c9 }, 6614 { "omega", 0x03c9 },
6616 { "omicron", 0x03bf }, 6615 { "omicron", 0x03bf },
6617 { "oplus", 0x2295 }, 6616 { "oplus", 0x2295 },
6618 { "or", 0x22a6 }, 6617 { "or", 0x22a6 },
6619 { "ordf", 0x00aa }, 6618 { "ordf", 0x00aa },
6620 { "ordm", 0x00ba }, 6619 { "ordm", 0x00ba },
6621 { "oslash", 0x00f8 }, 6620 { "oslash", 0x00f8 },
6622 { "otilde", 0x00f5 }, 6621 { "otilde", 0x00f5 },
6623 { "otimes", 0x2297 }, 6622 { "otimes", 0x2297 },
6624 { "ouml", 0x00f6 }, 6623 { "ouml", 0x00f6 },
6625 { "para", 0x00b6 }, 6624 { "para", 0x00b6 },
6626 { "part", 0x2202 }, 6625 { "part", 0x2202 },
6627 { "percnt", 0x0025 }, 6626 { "percnt", 0x0025 },
6628 { "permil", 0x2030 }, 6627 { "permil", 0x2030 },
6629 { "perp", 0x22a5 }, 6628 { "perp", 0x22a5 },
6630 { "phi", 0x03c6 }, 6629 { "phi", 0x03c6 },
6631 { "pi", 0x03c0 }, 6630 { "pi", 0x03c0 },
6632 { "piv", 0x03d6 }, 6631 { "piv", 0x03d6 },
6633 { "plusmn", 0x00b1 }, 6632 { "plusmn", 0x00b1 },
6634 { "pound", 0x00a3 }, 6633 { "pound", 0x00a3 },
6635 { "prime", 0x2032 }, 6634 { "prime", 0x2032 },
6636 { "prod", 0x220f }, 6635 { "prod", 0x220f },
6637 { "prop", 0x221d }, 6636 { "prop", 0x221d },
6638 { "psi", 0x03c8 }, 6637 { "psi", 0x03c8 },
6639 { "quot", 34 }, 6638 { "quot", 34 },
6640 { "rArr", 0x21d2 }, 6639 { "rArr", 0x21d2 },
6641 { "radic", 0x221a }, 6640 { "radic", 0x221a },
6642 { "rang", 0x232a }, 6641 { "rang", 0x232a },
6643 { "raquo", 0x00bb }, 6642 { "raquo", 0x00bb },
6644 { "rarr", 0x2192 }, 6643 { "rarr", 0x2192 },
6645 { "rceil", 0x2309 }, 6644 { "rceil", 0x2309 },
6646 { "rdquo", 0x201d }, 6645 { "rdquo", 0x201d },
6647 { "real", 0x211c }, 6646 { "real", 0x211c },
6648 { "reg", 0x00ae }, 6647 { "reg", 0x00ae },
6649 { "rfloor", 0x230b }, 6648 { "rfloor", 0x230b },
6650 { "rho", 0x03c1 }, 6649 { "rho", 0x03c1 },
6651 { "rlm", 0x200f }, 6650 { "rlm", 0x200f },
6652 { "rsaquo", 0x203a }, 6651 { "rsaquo", 0x203a },
6653 { "rsquo", 0x2019 }, 6652 { "rsquo", 0x2019 },
6654 { "sbquo", 0x201a }, 6653 { "sbquo", 0x201a },
6655 { "scaron", 0x0161 }, 6654 { "scaron", 0x0161 },
6656 { "sdot", 0x22c5 }, 6655 { "sdot", 0x22c5 },
6657 { "sect", 0x00a7 }, 6656 { "sect", 0x00a7 },
6658 { "shy", 0x00ad }, 6657 { "shy", 0x00ad },
6659 { "sigma", 0x03c3 }, 6658 { "sigma", 0x03c3 },
6660 { "sigmaf", 0x03c2 }, 6659 { "sigmaf", 0x03c2 },
6661 { "sim", 0x223c }, 6660 { "sim", 0x223c },
6662 { "spades", 0x2660 }, 6661 { "spades", 0x2660 },
6663 { "sub", 0x2282 }, 6662 { "sub", 0x2282 },
6664 { "sube", 0x2286 }, 6663 { "sube", 0x2286 },
6665 { "sum", 0x2211 }, 6664 { "sum", 0x2211 },
6666 { "sup1", 0x00b9 }, 6665 { "sup1", 0x00b9 },
6667 { "sup2", 0x00b2 }, 6666 { "sup2", 0x00b2 },
6668 { "sup3", 0x00b3 }, 6667 { "sup3", 0x00b3 },
6669 { "sup", 0x2283 }, 6668 { "sup", 0x2283 },
6670 { "supe", 0x2287 }, 6669 { "supe", 0x2287 },
6671 { "szlig", 0x00df }, 6670 { "szlig", 0x00df },
6672 { "tau", 0x03c4 }, 6671 { "tau", 0x03c4 },
6673 { "there4", 0x2234 }, 6672 { "there4", 0x2234 },
6674 { "theta", 0x03b8 }, 6673 { "theta", 0x03b8 },
6675 { "thetasym", 0x03d1 }, 6674 { "thetasym", 0x03d1 },
6676 { "thinsp", 0x2009 }, 6675 { "thinsp", 0x2009 },
6677 { "thorn", 0x00fe }, 6676 { "thorn", 0x00fe },
6678 { "tilde", 0x02dc }, 6677 { "tilde", 0x02dc },
6679 { "times", 0x00d7 }, 6678 { "times", 0x00d7 },
6680 { "trade", 0x2122 }, 6679 { "trade", 0x2122 },
6681 { "uArr", 0x21d1 }, 6680 { "uArr", 0x21d1 },
6682 { "uacute", 0x00fa }, 6681 { "uacute", 0x00fa },
6683 { "uarr", 0x2191 }, 6682 { "uarr", 0x2191 },
6684 { "ucirc", 0x00fb }, 6683 { "ucirc", 0x00fb },
6685 { "ugrave", 0x00f9 }, 6684 { "ugrave", 0x00f9 },
6686 { "uml", 0x00a8 }, 6685 { "uml", 0x00a8 },
6687 { "upsih", 0x03d2 }, 6686 { "upsih", 0x03d2 },
6688 { "upsilon", 0x03c5 }, 6687 { "upsilon", 0x03c5 },
6689 { "uuml", 0x00fc }, 6688 { "uuml", 0x00fc },
6690 { "weierp", 0x2118 }, 6689 { "weierp", 0x2118 },
6691 { "xi", 0x03be }, 6690 { "xi", 0x03be },
6692 { "yacute", 0x00fd }, 6691 { "yacute", 0x00fd },
6693 { "yen", 0x00a5 }, 6692 { "yen", 0x00a5 },
6694 { "yuml", 0x00ff }, 6693 { "yuml", 0x00ff },
6695 { "zeta", 0x03b6 }, 6694 { "zeta", 0x03b6 },
6696 { "zwj", 0x200d }, 6695 { "zwj", 0x200d },
6697 { "zwnj", 0x200c }, 6696 { "zwnj", 0x200c },
6698 { "", 0x0000 } 6697 { "", 0x0000 }
6699}; 6698};
6700 6699
6701 6700
6702 6701
6703 6702
6704 6703
6705static QMap<QCString, QChar> *html_map = 0; 6704static QMap<QCString, QChar> *html_map = 0;
6706static void qt_cleanup_html_map() 6705static void qt_cleanup_html_map()
6707{ 6706{
6708 delete html_map; 6707 delete html_map;
6709 html_map = 0; 6708 html_map = 0;
6710} 6709}
6711 6710
6712static QMap<QCString, QChar> *htmlMap() 6711static QMap<QCString, QChar> *htmlMap()
6713{ 6712{
6714 if ( !html_map ) { 6713 if ( !html_map ) {
6715 html_map = new QMap<QCString, QChar>; 6714 html_map = new QMap<QCString, QChar>;
6716 qAddPostRoutine( qt_cleanup_html_map ); 6715 qAddPostRoutine( qt_cleanup_html_map );
6717 6716
6718 const Entity *ent = entitylist; 6717 const Entity *ent = entitylist;
6719 while( ent->code ) { 6718 while( ent->code ) {
6720 html_map->insert( ent->name, QChar(ent->code) ); 6719 html_map->insert( ent->name, QChar(ent->code) );
6721 ent++; 6720 ent++;
6722 } 6721 }
6723 } 6722 }
6724 return html_map; 6723 return html_map;
6725} 6724}
6726 6725
6727QChar QTextDocument::parseHTMLSpecialChar(const QChar* doc, int length, int& pos) 6726QChar QTextDocument::parseHTMLSpecialChar(const QChar* doc, int length, int& pos)
6728{ 6727{
6729 QCString s; 6728 QCString s;
6730 pos++; 6729 pos++;
6731 int recoverpos = pos; 6730 int recoverpos = pos;
6732 while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 6) { 6731 while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 6) {
6733 s += doc[pos]; 6732 s += doc[pos];
6734 pos++; 6733 pos++;
6735 } 6734 }
6736 if (doc[pos] != ';' && !doc[pos].isSpace() ) { 6735 if (doc[pos] != ';' && !doc[pos].isSpace() ) {
6737 pos = recoverpos; 6736 pos = recoverpos;
6738 return '&'; 6737 return '&';
6739 } 6738 }
6740 pos++; 6739 pos++;
6741 6740
6742 if ( s.length() > 1 && s[0] == '#') { 6741 if ( s.length() > 1 && s[0] == '#') {
6743 int num = s.mid(1).toInt(); 6742 int num = s.mid(1).toInt();
6744 if ( num == 151 ) // ### hack for designer manual 6743 if ( num == 151 ) // ### hack for designer manual
6745 return '-'; 6744 return '-';
6746 return num; 6745 return num;
6747 } 6746 }
6748 6747
6749 QMap<QCString, QChar>::Iterator it = htmlMap()->find(s); 6748 QMap<QCString, QChar>::Iterator it = htmlMap()->find(s);
6750 if ( it != htmlMap()->end() ) { 6749 if ( it != htmlMap()->end() ) {
6751 return *it; 6750 return *it;
6752 } 6751 }
6753 6752
6754 pos = recoverpos; 6753 pos = recoverpos;
6755 return '&'; 6754 return '&';
6756} 6755}
6757 6756
6758QString QTextDocument::parseWord(const QChar* doc, int length, int& pos, bool lower) 6757QString QTextDocument::parseWord(const QChar* doc, int length, int& pos, bool lower)
6759{ 6758{
6760 QString s; 6759 QString s;
6761 6760
6762 if (doc[pos] == '"') { 6761 if (doc[pos] == '"') {
6763 pos++; 6762 pos++;
6764 while ( pos < length && doc[pos] != '"' ) { 6763 while ( pos < length && doc[pos] != '"' ) {
6765 s += doc[pos]; 6764 s += doc[pos];
6766 pos++; 6765 pos++;
6767 } 6766 }
6768 eat(doc, length, pos, '"'); 6767 eat(doc, length, pos, '"');
6769 } else { 6768 } else {
6770 static QString term = QString::fromLatin1("/>"); 6769 static QString term = QString::fromLatin1("/>");
6771 while( pos < length && 6770 while( pos < length &&
6772 (doc[pos] != '>' && !hasPrefix( doc, length, pos, term)) 6771 (doc[pos] != '>' && !hasPrefix( doc, length, pos, term))
6773 && doc[pos] != '<' 6772 && doc[pos] != '<'
6774 && doc[pos] != '=' 6773 && doc[pos] != '='
6775 && !doc[pos].isSpace()) 6774 && !doc[pos].isSpace())
6776 { 6775 {
6777 if ( doc[pos] == '&') 6776 if ( doc[pos] == '&')
6778 s += parseHTMLSpecialChar( doc, length, pos ); 6777 s += parseHTMLSpecialChar( doc, length, pos );
6779 else { 6778 else {
6780 s += doc[pos]; 6779 s += doc[pos];
6781 pos++; 6780 pos++;
6782 } 6781 }
6783 } 6782 }
6784 if (lower) 6783 if (lower)
6785 s = s.lower(); 6784 s = s.lower();
6786 } 6785 }
6787 return s; 6786 return s;
6788} 6787}
6789 6788
6790QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm ) 6789QChar QTextDocument::parseChar(const QChar* doc, int length, int& pos, QStyleSheetItem::WhiteSpaceMode wsm )
6791{ 6790{
6792 if ( pos >= length ) 6791 if ( pos >= length )
6793 return QChar::null; 6792 return QChar::null;
6794 6793
6795 QChar c = doc[pos++]; 6794 QChar c = doc[pos++];
6796 6795
6797 if (c == '<' ) 6796 if (c == '<' )
6798 return QChar::null; 6797 return QChar::null;
6799 6798
6800 if ( c.isSpace() && c != QChar::nbsp ) { 6799 if ( c.isSpace() && c != QChar::nbsp ) {
6801 if ( wsm == QStyleSheetItem::WhiteSpacePre ) { 6800 if ( wsm == QStyleSheetItem::WhiteSpacePre ) {
6802 if ( c == '\n' ) 6801 if ( c == '\n' )
6803 return QChar_linesep; 6802 return QChar_linesep;
6804 else 6803 else
6805 return c; 6804 return c;
6806 } else { // non-pre mode: collapse whitespace except nbsp 6805 } else { // non-pre mode: collapse whitespace except nbsp
6807 while ( pos< length && 6806 while ( pos< length &&
6808 doc[pos].isSpace() && doc[pos] != QChar::nbsp ) 6807 doc[pos].isSpace() && doc[pos] != QChar::nbsp )
6809 pos++; 6808 pos++;
6810 if ( wsm == QStyleSheetItem::WhiteSpaceNoWrap ) 6809 if ( wsm == QStyleSheetItem::WhiteSpaceNoWrap )
6811 return QChar::nbsp; 6810 return QChar::nbsp;
6812 else 6811 else
6813 return ' '; 6812 return ' ';
6814 } 6813 }
6815 } 6814 }
6816 else if ( c == '&' ) 6815 else if ( c == '&' )
6817 return parseHTMLSpecialChar( doc, length, --pos ); 6816 return parseHTMLSpecialChar( doc, length, --pos );
6818 else 6817 else
6819 return c; 6818 return c;
6820} 6819}
6821 6820
6822QString QTextDocument::parseOpenTag(const QChar* doc, int length, int& pos, 6821QString QTextDocument::parseOpenTag(const QChar* doc, int length, int& pos,
6823 QMap<QString, QString> &attr, bool& emptyTag) 6822 QMap<QString, QString> &attr, bool& emptyTag)
6824{ 6823{
6825 emptyTag = FALSE; 6824 emptyTag = FALSE;
6826 pos++; 6825 pos++;
6827 if ( hasPrefix(doc, length, pos, '!') ) { 6826 if ( hasPrefix(doc, length, pos, '!') ) {
6828 if ( hasPrefix( doc, length, pos+1, "--")) { 6827 if ( hasPrefix( doc, length, pos+1, "--")) {
6829 pos += 3; 6828 pos += 3;
6830 // eat comments 6829 // eat comments
6831 QString pref = QString::fromLatin1("-->"); 6830 QString pref = QString::fromLatin1("-->");
6832 while ( !hasPrefix(doc, length, pos, pref ) && pos < length ) 6831 while ( !hasPrefix(doc, length, pos, pref ) && pos < length )
6833 pos++; 6832 pos++;
6834 if ( hasPrefix(doc, length, pos, pref ) ) { 6833 if ( hasPrefix(doc, length, pos, pref ) ) {
6835 pos += 3; 6834 pos += 3;
6836 eatSpace(doc, length, pos, TRUE); 6835 eatSpace(doc, length, pos, TRUE);
6837 } 6836 }
6838 emptyTag = TRUE; 6837 emptyTag = TRUE;
6839 return QString::null; 6838 return QString::null;
6840 } 6839 }
6841 else { 6840 else {
6842 // eat strange internal tags 6841 // eat strange internal tags
6843 while ( !hasPrefix(doc, length, pos, '>') && pos < length ) 6842 while ( !hasPrefix(doc, length, pos, '>') && pos < length )
6844 pos++; 6843 pos++;
6845 if ( hasPrefix(doc, length, pos, '>') ) { 6844 if ( hasPrefix(doc, length, pos, '>') ) {
6846 pos++; 6845 pos++;
6847 eatSpace(doc, length, pos, TRUE); 6846 eatSpace(doc, length, pos, TRUE);
6848 } 6847 }
6849 return QString::null; 6848 return QString::null;
6850 } 6849 }
6851 } 6850 }
6852 6851
6853 QString tag = parseWord(doc, length, pos ); 6852 QString tag = parseWord(doc, length, pos );
6854 eatSpace(doc, length, pos, TRUE); 6853 eatSpace(doc, length, pos, TRUE);
6855 static QString term = QString::fromLatin1("/>"); 6854 static QString term = QString::fromLatin1("/>");
6856 static QString s_TRUE = QString::fromLatin1("TRUE"); 6855 static QString s_TRUE = QString::fromLatin1("TRUE");
6857 6856
6858 while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) { 6857 while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) {
6859 QString key = parseWord(doc, length, pos ); 6858 QString key = parseWord(doc, length, pos );
6860 eatSpace(doc, length, pos, TRUE); 6859 eatSpace(doc, length, pos, TRUE);
6861 if ( key.isEmpty()) { 6860 if ( key.isEmpty()) {
6862 // error recovery 6861 // error recovery
6863 while ( pos < length && doc[pos] != '>' ) 6862 while ( pos < length && doc[pos] != '>' )
6864 pos++; 6863 pos++;
6865 break; 6864 break;
6866 } 6865 }
6867 QString value; 6866 QString value;
6868 if (hasPrefix(doc, length, pos, '=') ){ 6867 if (hasPrefix(doc, length, pos, '=') ){
6869 pos++; 6868 pos++;
6870 eatSpace(doc, length, pos); 6869 eatSpace(doc, length, pos);
6871 value = parseWord(doc, length, pos, FALSE); 6870 value = parseWord(doc, length, pos, FALSE);
6872 } 6871 }
6873 else 6872 else
6874 value = s_TRUE; 6873 value = s_TRUE;
6875 attr.insert(key.lower(), value ); 6874 attr.insert(key.lower(), value );
6876 eatSpace(doc, length, pos, TRUE); 6875 eatSpace(doc, length, pos, TRUE);
6877 } 6876 }
6878 6877
6879 if (emptyTag) { 6878 if (emptyTag) {
6880 eat(doc, length, pos, '/'); 6879 eat(doc, length, pos, '/');
6881 eat(doc, length, pos, '>'); 6880 eat(doc, length, pos, '>');
6882 } 6881 }
6883 else 6882 else
6884 eat(doc, length, pos, '>'); 6883 eat(doc, length, pos, '>');
6885 6884
6886 return tag; 6885 return tag;
6887} 6886}
6888 6887
6889QString QTextDocument::parseCloseTag( const QChar* doc, int length, int& pos ) 6888QString QTextDocument::parseCloseTag( const QChar* doc, int length, int& pos )
6890{ 6889{
6891 pos++; 6890 pos++;
6892 pos++; 6891 pos++;
6893 QString tag = parseWord(doc, length, pos ); 6892 QString tag = parseWord(doc, length, pos );
6894 eatSpace(doc, length, pos, TRUE); 6893 eatSpace(doc, length, pos, TRUE);
6895 eat(doc, length, pos, '>'); 6894 eat(doc, length, pos, '>');
6896 return tag; 6895 return tag;
6897} 6896}
6898 6897
6899QTextFlow::QTextFlow() 6898QTextFlow::QTextFlow()
6900{ 6899{
6901 w = pagesize = 0; 6900 w = pagesize = 0;
6902 leftItems.setAutoDelete( FALSE ); 6901 leftItems.setAutoDelete( FALSE );
6903 rightItems.setAutoDelete( FALSE ); 6902 rightItems.setAutoDelete( FALSE );
6904} 6903}
6905 6904
6906QTextFlow::~QTextFlow() 6905QTextFlow::~QTextFlow()
6907{ 6906{
6908} 6907}
6909 6908
6910void QTextFlow::clear() 6909void QTextFlow::clear()
6911{ 6910{
6912 leftItems.clear(); 6911 leftItems.clear();
6913 rightItems.clear(); 6912 rightItems.clear();
6914} 6913}
6915 6914
6916void QTextFlow::setWidth( int width ) 6915void QTextFlow::setWidth( int width )
6917{ 6916{
6918 w = width; 6917 w = width;
6919} 6918}
6920 6919
6921int QTextFlow::adjustLMargin( int yp, int, int margin, int space ) 6920int QTextFlow::adjustLMargin( int yp, int, int margin, int space )
6922{ 6921{
6923 for ( QTextCustomItem* item = leftItems.first(); item; item = leftItems.next() ) { 6922 for ( QTextCustomItem* item = leftItems.first(); item; item = leftItems.next() ) {
6924 if ( item->ypos == -1 ) 6923 if ( item->ypos == -1 )
6925 continue; 6924 continue;
6926 if ( yp >= item->ypos && yp < item->ypos + item->height ) 6925 if ( yp >= item->ypos && yp < item->ypos + item->height )
6927 margin = QMAX( margin, item->xpos + item->width + space ); 6926 margin = QMAX( margin, item->xpos + item->width + space );
6928 } 6927 }
6929 return margin; 6928 return margin;
6930} 6929}
6931 6930
6932int QTextFlow::adjustRMargin( int yp, int, int margin, int space ) 6931int QTextFlow::adjustRMargin( int yp, int, int margin, int space )
6933{ 6932{
6934 for ( QTextCustomItem* item = rightItems.first(); item; item = rightItems.next() ) { 6933 for ( QTextCustomItem* item = rightItems.first(); item; item = rightItems.next() ) {
6935 if ( item->ypos == -1 ) 6934 if ( item->ypos == -1 )
6936 continue; 6935 continue;
6937 if ( yp >= item->ypos && yp < item->ypos + item->height ) 6936 if ( yp >= item->ypos && yp < item->ypos + item->height )
6938 margin = QMAX( margin, w - item->xpos - space ); 6937 margin = QMAX( margin, w - item->xpos - space );
6939 } 6938 }
6940 return margin; 6939 return margin;
6941} 6940}
6942 6941
6943 6942
6944int QTextFlow::adjustFlow( int y, int /*w*/, int h ) 6943int QTextFlow::adjustFlow( int y, int /*w*/, int h )
6945{ 6944{
6946 if ( pagesize > 0 ) { // check pages 6945 if ( pagesize > 0 ) { // check pages
6947 int yinpage = y % pagesize; 6946 int yinpage = y % pagesize;
6948 if ( yinpage <= border_tolerance ) 6947 if ( yinpage <= border_tolerance )
6949 return border_tolerance - yinpage; 6948 return border_tolerance - yinpage;
6950 else 6949 else
6951 if ( yinpage + h > pagesize - border_tolerance ) 6950 if ( yinpage + h > pagesize - border_tolerance )
6952 return ( pagesize - yinpage ) + border_tolerance; 6951 return ( pagesize - yinpage ) + border_tolerance;
6953 } 6952 }
6954 return 0; 6953 return 0;
6955} 6954}
6956 6955
6957void QTextFlow::unregisterFloatingItem( QTextCustomItem* item ) 6956void QTextFlow::unregisterFloatingItem( QTextCustomItem* item )
6958{ 6957{
6959 leftItems.removeRef( item ); 6958 leftItems.removeRef( item );
6960 rightItems.removeRef( item ); 6959 rightItems.removeRef( item );
6961} 6960}
6962 6961
6963void QTextFlow::registerFloatingItem( QTextCustomItem* item ) 6962void QTextFlow::registerFloatingItem( QTextCustomItem* item )
6964{ 6963{
6965 if ( item->placement() == QTextCustomItem::PlaceRight ) { 6964 if ( item->placement() == QTextCustomItem::PlaceRight ) {
6966 if ( !rightItems.contains( item ) ) 6965 if ( !rightItems.contains( item ) )
6967 rightItems.append( item ); 6966 rightItems.append( item );
6968 } else if ( item->placement() == QTextCustomItem::PlaceLeft && 6967 } else if ( item->placement() == QTextCustomItem::PlaceLeft &&
6969 !leftItems.contains( item ) ) { 6968 !leftItems.contains( item ) ) {
6970 leftItems.append( item ); 6969 leftItems.append( item );
6971 } 6970 }
6972} 6971}
6973 6972
6974QRect QTextFlow::boundingRect() const 6973QRect QTextFlow::boundingRect() const
6975{ 6974{
6976 QRect br; 6975 QRect br;
6977 QPtrListIterator<QTextCustomItem> l( leftItems ); 6976 QPtrListIterator<QTextCustomItem> l( leftItems );
6978 while( l.current() ) { 6977 while( l.current() ) {
6979 br = br.unite( l.current()->geometry() ); 6978 br = br.unite( l.current()->geometry() );
6980 ++l; 6979 ++l;
6981 } 6980 }
6982 QPtrListIterator<QTextCustomItem> r( rightItems ); 6981 QPtrListIterator<QTextCustomItem> r( rightItems );
6983 while( r.current() ) { 6982 while( r.current() ) {
6984 br = br.unite( r.current()->geometry() ); 6983 br = br.unite( r.current()->geometry() );
6985 ++r; 6984 ++r;
6986 } 6985 }
6987 return br; 6986 return br;
6988} 6987}
6989 6988
6990 6989
6991void QTextFlow::drawFloatingItems( QPainter* p, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) 6990void QTextFlow::drawFloatingItems( QPainter* p, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected )
6992{ 6991{
6993 QTextCustomItem *item; 6992 QTextCustomItem *item;
6994 for ( item = leftItems.first(); item; item = leftItems.next() ) { 6993 for ( item = leftItems.first(); item; item = leftItems.next() ) {
6995 if ( item->xpos == -1 || item->ypos == -1 ) 6994 if ( item->xpos == -1 || item->ypos == -1 )
6996 continue; 6995 continue;
6997 item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected ); 6996 item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected );
6998 } 6997 }
6999 6998
7000 for ( item = rightItems.first(); item; item = rightItems.next() ) { 6999 for ( item = rightItems.first(); item; item = rightItems.next() ) {
7001 if ( item->xpos == -1 || item->ypos == -1 ) 7000 if ( item->xpos == -1 || item->ypos == -1 )
7002 continue; 7001 continue;
7003 item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected ); 7002 item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected );
7004 } 7003 }
7005} 7004}
7006 7005
7007// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7006// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7008 7007
7009void QTextCustomItem::pageBreak( int /*y*/ , QTextFlow* /*flow*/ ) 7008void QTextCustomItem::pageBreak( int /*y*/ , QTextFlow* /*flow*/ )
7010{ 7009{
7011} 7010}
7012 7011
7013QTextTable::QTextTable( QTextDocument *p, const QMap<QString, QString> & attr ) 7012QTextTable::QTextTable( QTextDocument *p, const QMap<QString, QString> & attr )
7014 : QTextCustomItem( p ) 7013 : QTextCustomItem( p )
7015{ 7014{
7016 cells.setAutoDelete( FALSE ); 7015 cells.setAutoDelete( FALSE );
7017 cellspacing = 2; 7016 cellspacing = 2;
7018 if ( attr.contains("cellspacing") ) 7017 if ( attr.contains("cellspacing") )
7019 cellspacing = attr["cellspacing"].toInt(); 7018 cellspacing = attr["cellspacing"].toInt();
7020 cellpadding = 1; 7019 cellpadding = 1;
7021 if ( attr.contains("cellpadding") ) 7020 if ( attr.contains("cellpadding") )
7022 cellpadding = attr["cellpadding"].toInt(); 7021 cellpadding = attr["cellpadding"].toInt();
7023 border = innerborder = 0; 7022 border = innerborder = 0;
7024 if ( attr.contains("border" ) ) { 7023 if ( attr.contains("border" ) ) {
7025 QString s( attr["border"] ); 7024 QString s( attr["border"] );
7026 if ( s == "TRUE" ) 7025 if ( s == "TRUE" )
7027 border = 1; 7026 border = 1;
7028 else 7027 else
7029 border = attr["border"].toInt(); 7028 border = attr["border"].toInt();
7030 } 7029 }
7031 us_b = border; 7030 us_b = border;
7032 7031
7033 innerborder = us_ib = border ? 1 : 0; 7032 innerborder = us_ib = border ? 1 : 0;
7034 7033
7035 if ( border ) 7034 if ( border )
7036 cellspacing += 2; 7035 cellspacing += 2;
7037 7036
7038 us_ib = innerborder; 7037 us_ib = innerborder;
7039 us_cs = cellspacing; 7038 us_cs = cellspacing;
7040 us_cp = cellpadding; 7039 us_cp = cellpadding;
7041 outerborder = cellspacing + border; 7040 outerborder = cellspacing + border;
7042 us_ob = outerborder; 7041 us_ob = outerborder;
7043 layout = new QGridLayout( 1, 1, cellspacing ); 7042 layout = new QGridLayout( 1, 1, cellspacing );
7044 7043
7045 fixwidth = 0; 7044 fixwidth = 0;
7046 stretch = 0; 7045 stretch = 0;
7047 if ( attr.contains("width") ) { 7046 if ( attr.contains("width") ) {
7048 bool b; 7047 bool b;
7049 QString s( attr["width"] ); 7048 QString s( attr["width"] );
7050 int w = s.toInt( &b ); 7049 int w = s.toInt( &b );
7051 if ( b ) { 7050 if ( b ) {
7052 fixwidth = w; 7051 fixwidth = w;
7053 } else { 7052 } else {
7054 s = s.stripWhiteSpace(); 7053 s = s.stripWhiteSpace();
7055 if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' ) 7054 if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' )
7056 stretch = s.left( s.length()-1).toInt(); 7055 stretch = s.left( s.length()-1).toInt();
7057 } 7056 }
7058 } 7057 }
7059 7058
7060 place = PlaceInline; 7059 place = PlaceInline;
7061 if ( attr["align"] == "left" ) 7060 if ( attr["align"] == "left" )
7062 place = PlaceLeft; 7061 place = PlaceLeft;
7063 else if ( attr["align"] == "right" ) 7062 else if ( attr["align"] == "right" )
7064 place = PlaceRight; 7063 place = PlaceRight;
7065 cachewidth = 0; 7064 cachewidth = 0;
7066 attributes = attr; 7065 attributes = attr;
7067 pageBreakFor = -1; 7066 pageBreakFor = -1;
7068} 7067}
7069 7068
7070QTextTable::~QTextTable() 7069QTextTable::~QTextTable()
7071{ 7070{
7072 delete layout; 7071 delete layout;
7073} 7072}
7074 7073
7075QString QTextTable::richText() const 7074QString QTextTable::richText() const
7076{ 7075{
7077 QString s; 7076 QString s;
7078 s = "<table "; 7077 s = "<table ";
7079 QMap<QString, QString>::ConstIterator it = attributes.begin(); 7078 QMap<QString, QString>::ConstIterator it = attributes.begin();
7080 for ( ; it != attributes.end(); ++it ) 7079 for ( ; it != attributes.end(); ++it )
7081 s += it.key() + "=" + *it + " "; 7080 s += it.key() + "=" + *it + " ";
7082 s += ">\n"; 7081 s += ">\n";
7083 7082
7084 int lastRow = -1; 7083 int lastRow = -1;
7085 bool needEnd = FALSE; 7084 bool needEnd = FALSE;
7086 QPtrListIterator<QTextTableCell> it2( cells ); 7085 QPtrListIterator<QTextTableCell> it2( cells );
7087 while ( it2.current() ) { 7086 while ( it2.current() ) {
7088 QTextTableCell *cell = it2.current(); 7087 QTextTableCell *cell = it2.current();
7089 ++it2; 7088 ++it2;
7090 if ( lastRow != cell->row() ) { 7089 if ( lastRow != cell->row() ) {
7091 if ( lastRow != -1 ) 7090 if ( lastRow != -1 )
7092 s += "</tr>\n"; 7091 s += "</tr>\n";
7093 s += "<tr>"; 7092 s += "<tr>";
7094 lastRow = cell->row(); 7093 lastRow = cell->row();
7095 needEnd = TRUE; 7094 needEnd = TRUE;
7096 } 7095 }
7097 s += "<td"; 7096 s += "<td";
7098 it = cell->attributes.begin(); 7097 it = cell->attributes.begin();
7099 for ( ; it != cell->attributes.end(); ++it ) 7098 for ( ; it != cell->attributes.end(); ++it )
7100 s += " " + it.key() + "=" + *it; 7099 s += " " + it.key() + "=" + *it;
7101 s += ">"; 7100 s += ">";
7102 s += cell->richText()->richText(); 7101 s += cell->richText()->richText();
7103 s += "</td>"; 7102 s += "</td>";
7104 } 7103 }
7105 if ( needEnd ) 7104 if ( needEnd )
7106 s += "</tr>\n"; 7105 s += "</tr>\n";
7107 s += "</table>\n"; 7106 s += "</table>\n";
7108 return s; 7107 return s;
7109} 7108}
7110 7109
7111void QTextTable::adjustToPainter( QPainter* p ) 7110void QTextTable::adjustToPainter( QPainter* p )
7112{ 7111{
7113 cellspacing = scale( us_cs, p ); 7112 cellspacing = scale( us_cs, p );
7114 cellpadding = scale( us_cp, p ); 7113 cellpadding = scale( us_cp, p );
7115 border = scale( us_b , p ); 7114 border = scale( us_b , p );
7116 innerborder = scale( us_ib, p ); 7115 innerborder = scale( us_ib, p );
7117 outerborder = scale( us_ob ,p ); 7116 outerborder = scale( us_ob ,p );
7118 width = 0; 7117 width = 0;
7119 cachewidth = 0; 7118 cachewidth = 0;
7120 for ( QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) 7119 for ( QTextTableCell* cell = cells.first(); cell; cell = cells.next() )
7121 cell->adjustToPainter( p ); 7120 cell->adjustToPainter( p );
7122} 7121}
7123 7122
7124void QTextTable::adjustCells( int y , int shift ) 7123void QTextTable::adjustCells( int y , int shift )
7125{ 7124{
7126 QPtrListIterator<QTextTableCell> it( cells ); 7125 QPtrListIterator<QTextTableCell> it( cells );
7127 QTextTableCell* cell; 7126 QTextTableCell* cell;
7128 bool enlarge = FALSE; 7127 bool enlarge = FALSE;
7129 while ( ( cell = it.current() ) ) { 7128 while ( ( cell = it.current() ) ) {
7130 ++it; 7129 ++it;
7131 QRect r = cell->geometry(); 7130 QRect r = cell->geometry();
7132 if ( y <= r.top() ) { 7131 if ( y <= r.top() ) {
7133 r.moveBy(0, shift ); 7132 r.moveBy(0, shift );
7134 cell->setGeometry( r ); 7133 cell->setGeometry( r );
7135 enlarge = TRUE; 7134 enlarge = TRUE;
7136 } else if ( y <= r.bottom() ) { 7135 } else if ( y <= r.bottom() ) {
7137 r.rBottom() += shift; 7136 r.rBottom() += shift;
7138 cell->setGeometry( r ); 7137 cell->setGeometry( r );
7139 enlarge = TRUE; 7138 enlarge = TRUE;
7140 } 7139 }
7141 } 7140 }
7142 if ( enlarge ) 7141 if ( enlarge )
7143 height += shift; 7142 height += shift;
7144} 7143}
7145 7144
7146void QTextTable::pageBreak( int yt, QTextFlow* flow ) 7145void QTextTable::pageBreak( int yt, QTextFlow* flow )
7147{ 7146{
7148 if ( flow->pageSize() <= 0 ) 7147 if ( flow->pageSize() <= 0 )
7149 return; 7148 return;
7150 if ( layout && pageBreakFor > 0 && pageBreakFor != yt ) { 7149 if ( layout && pageBreakFor > 0 && pageBreakFor != yt ) {
7151 layout->invalidate(); 7150 layout->invalidate();
7152 int h = layout->heightForWidth( width-2*outerborder ); 7151 int h = layout->heightForWidth( width-2*outerborder );
7153 layout->setGeometry( QRect(0, 0, width-2*outerborder, h) ); 7152 layout->setGeometry( QRect(0, 0, width-2*outerborder, h) );
7154 height = layout->geometry().height()+2*outerborder; 7153 height = layout->geometry().height()+2*outerborder;
7155 } 7154 }
7156 pageBreakFor = yt; 7155 pageBreakFor = yt;
7157 QPtrListIterator<QTextTableCell> it( cells ); 7156 QPtrListIterator<QTextTableCell> it( cells );
7158 QTextTableCell* cell; 7157 QTextTableCell* cell;
7159 while ( ( cell = it.current() ) ) { 7158 while ( ( cell = it.current() ) ) {
7160 ++it; 7159 ++it;
7161 int y = yt + outerborder + cell->geometry().y(); 7160 int y = yt + outerborder + cell->geometry().y();
7162 int shift = flow->adjustFlow( y - cellspacing, width, cell->richText()->height() + 2*cellspacing ); 7161 int shift = flow->adjustFlow( y - cellspacing, width, cell->richText()->height() + 2*cellspacing );
7163 adjustCells( y - outerborder - yt, shift ); 7162 adjustCells( y - outerborder - yt, shift );
7164 } 7163 }
7165} 7164}
7166 7165
7167 7166
7168void QTextTable::draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected ) 7167void QTextTable::draw(QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected )
7169{ 7168{
7170 if ( placement() != PlaceInline ) { 7169 if ( placement() != PlaceInline ) {
7171 x = xpos; 7170 x = xpos;
7172 y = ypos; 7171 y = ypos;
7173 } 7172 }
7174 7173
7175 for (QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) { 7174 for (QTextTableCell* cell = cells.first(); cell; cell = cells.next() ) {
7176 if ( cx < 0 && cy < 0 || 7175 if ( cx < 0 && cy < 0 ||
7177 QRect( cx, cy, cw, ch ).intersects( QRect( x + outerborder + cell->geometry().x(), 7176 QRect( cx, cy, cw, ch ).intersects( QRect( x + outerborder + cell->geometry().x(),
7178 y + outerborder + cell->geometry().y(), 7177 y + outerborder + cell->geometry().y(),
7179 cell->geometry().width(), cell->geometry().height() ) ) ) { 7178 cell->geometry().width(), cell->geometry().height() ) ) ) {
7180 cell->draw( p, x+outerborder, y+outerborder, cx, cy, cw, ch, cg, selected ); 7179 cell->draw( p, x+outerborder, y+outerborder, cx, cy, cw, ch, cg, selected );
7181 if ( border ) { 7180 if ( border ) {
7182 QRect r( x+outerborder+cell->geometry().x() - innerborder, 7181 QRect r( x+outerborder+cell->geometry().x() - innerborder,
7183 y+outerborder+cell->geometry().y() - innerborder, 7182 y+outerborder+cell->geometry().y() - innerborder,
7184 cell->geometry().width() + 2 * innerborder, 7183 cell->geometry().width() + 2 * innerborder,
7185 cell->geometry().height() + 2 * innerborder ); 7184 cell->geometry().height() + 2 * innerborder );
7186 if ( is_printer( p ) ) { 7185 if ( is_printer( p ) ) {
7187 QPen oldPen = p->pen(); 7186 QPen oldPen = p->pen();
7188 QRect r2 = r; 7187 QRect r2 = r;
7189 r2.setLeft( r2.left() + innerborder/2 ); 7188 r2.setLeft( r2.left() + innerborder/2 );
7190 r2.setTop( r2.top() + innerborder/2 ); 7189 r2.setTop( r2.top() + innerborder/2 );
7191 r2.setRight( r2.right() - innerborder/2 ); 7190 r2.setRight( r2.right() - innerborder/2 );
7192 r2.setBottom( r2.bottom() - innerborder/2 ); 7191 r2.setBottom( r2.bottom() - innerborder/2 );
7193 p->setPen( QPen( cg.text(), innerborder ) ); 7192 p->setPen( QPen( cg.text(), innerborder ) );
7194 p->drawRect( r2 ); 7193 p->drawRect( r2 );
7195 p->setPen( oldPen ); 7194 p->setPen( oldPen );
7196 } else { 7195 } else {
7197 int s = QMAX( cellspacing-2*innerborder, 0); 7196 int s = QMAX( cellspacing-2*innerborder, 0);
7198 if ( s ) { 7197 if ( s ) {
7199 p->fillRect( r.left()-s, r.top(), s+1, r.height(), cg.button() ); 7198 p->fillRect( r.left()-s, r.top(), s+1, r.height(), cg.button() );
7200 p->fillRect( r.right(), r.top(), s+1, r.height(), cg.button() ); 7199 p->fillRect( r.right(), r.top(), s+1, r.height(), cg.button() );
7201 p->fillRect( r.left()-s, r.top()-s, r.width()+2*s, s, cg.button() ); 7200 p->fillRect( r.left()-s, r.top()-s, r.width()+2*s, s, cg.button() );
7202 p->fillRect( r.left()-s, r.bottom(), r.width()+2*s, s, cg.button() ); 7201 p->fillRect( r.left()-s, r.bottom(), r.width()+2*s, s, cg.button() );
7203 } 7202 }
7204 qDrawShadePanel( p, r, cg, TRUE, innerborder ); 7203 qDrawShadePanel( p, r, cg, TRUE, innerborder );
7205 } 7204 }
7206 } 7205 }
7207 } 7206 }
7208 } 7207 }
7209 if ( border ) { 7208 if ( border ) {
7210 QRect r ( x, y, width, height ); 7209 QRect r ( x, y, width, height );
7211 if ( is_printer( p ) ) { 7210 if ( is_printer( p ) ) {
7212 QRect r2 = r; 7211 QRect r2 = r;
7213 r2.setLeft( r2.left() + border/2 ); 7212 r2.setLeft( r2.left() + border/2 );
7214 r2.setTop( r2.top() + border/2 ); 7213 r2.setTop( r2.top() + border/2 );
7215 r2.setRight( r2.right() - border/2 ); 7214 r2.setRight( r2.right() - border/2 );
7216 r2.setBottom( r2.bottom() - border/2 ); 7215 r2.setBottom( r2.bottom() - border/2 );
7217 QPen oldPen = p->pen(); 7216 QPen oldPen = p->pen();
7218 p->setPen( QPen( cg.text(), border ) ); 7217 p->setPen( QPen( cg.text(), border ) );
7219 p->drawRect( r2 ); 7218 p->drawRect( r2 );
7220 p->setPen( oldPen ); 7219 p->setPen( oldPen );
7221 } else { 7220 } else {
7222 int s = border+QMAX( cellspacing-2*innerborder, 0); 7221 int s = border+QMAX( cellspacing-2*innerborder, 0);
7223 if ( s ) { 7222 if ( s ) {
7224 p->fillRect( r.left(), r.top(), s, r.height(), cg.button() ); 7223 p->fillRect( r.left(), r.top(), s, r.height(), cg.button() );
7225 p->fillRect( r.right()-s, r.top(), s, r.height(), cg.button() ); 7224 p->fillRect( r.right()-s, r.top(), s, r.height(), cg.button() );
7226 p->fillRect( r.left(), r.top(), r.width(), s, cg.button() ); 7225 p->fillRect( r.left(), r.top(), r.width(), s, cg.button() );
7227 p->fillRect( r.left(), r.bottom()-s, r.width(), s, cg.button() ); 7226 p->fillRect( r.left(), r.bottom()-s, r.width(), s, cg.button() );
7228 } 7227 }
7229 qDrawShadePanel( p, r, cg, FALSE, border ); 7228 qDrawShadePanel( p, r, cg, FALSE, border );
7230 } 7229 }
7231 } 7230 }
7232 7231
7233} 7232}
7234 7233
7235int QTextTable::minimumWidth() const 7234int QTextTable::minimumWidth() const
7236{ 7235{
7237 return (layout ? layout->minimumSize().width() : 0) + 2 * outerborder; 7236 return (layout ? layout->minimumSize().width() : 0) + 2 * outerborder;
7238} 7237}
7239 7238
7240void QTextTable::resize( int nwidth ) 7239void QTextTable::resize( int nwidth )
7241{ 7240{
7242 if ( fixwidth && cachewidth != 0 ) 7241 if ( fixwidth && cachewidth != 0 )
7243 return; 7242 return;
7244 if ( nwidth == cachewidth ) 7243 if ( nwidth == cachewidth )
7245 return; 7244 return;
7246 7245
7247 7246
7248 cachewidth = nwidth; 7247 cachewidth = nwidth;
7249 int w = nwidth; 7248 int w = nwidth;
7250 7249
7251 format( w ); 7250 format( w );
7252 7251
7253 if ( stretch ) 7252 if ( stretch )
7254 nwidth = nwidth * stretch / 100; 7253 nwidth = nwidth * stretch / 100;
7255 7254
7256 width = nwidth; 7255 width = nwidth;
7257 layout->invalidate(); 7256 layout->invalidate();
7258 int shw = layout->sizeHint().width() + 2*outerborder; 7257 int shw = layout->sizeHint().width() + 2*outerborder;
7259 int mw = layout->minimumSize().width() + 2*outerborder; 7258 int mw = layout->minimumSize().width() + 2*outerborder;
7260 if ( stretch ) 7259 if ( stretch )
7261 width = QMAX( mw, nwidth ); 7260 width = QMAX( mw, nwidth );
7262 else 7261 else
7263 width = QMAX( mw, QMIN( nwidth, shw ) ); 7262 width = QMAX( mw, QMIN( nwidth, shw ) );
7264 7263
7265 if ( fixwidth ) 7264 if ( fixwidth )
7266 width = fixwidth; 7265 width = fixwidth;
7267 7266
7268 layout->invalidate(); 7267 layout->invalidate();
7269 mw = layout->minimumSize().width() + 2*outerborder; 7268 mw = layout->minimumSize().width() + 2*outerborder;
7270 width = QMAX( width, mw ); 7269 width = QMAX( width, mw );
7271 7270
7272 int h = layout->heightForWidth( width-2*outerborder ); 7271 int h = layout->heightForWidth( width-2*outerborder );
7273 layout->setGeometry( QRect(0, 0, width-2*outerborder, h) ); 7272 layout->setGeometry( QRect(0, 0, width-2*outerborder, h) );
7274 height = layout->geometry().height()+2*outerborder; 7273 height = layout->geometry().height()+2*outerborder;
7275} 7274}
7276 7275
7277void QTextTable::format( int w ) 7276void QTextTable::format( int w )
7278{ 7277{
7279 for ( int i = 0; i < (int)cells.count(); ++i ) { 7278 for ( int i = 0; i < (int)cells.count(); ++i ) {
7280 QTextTableCell *cell = cells.at( i ); 7279 QTextTableCell *cell = cells.at( i );
7281 QRect r = cell->geometry(); 7280 QRect r = cell->geometry();
7282 r.setWidth( w - 2*outerborder ); 7281 r.setWidth( w - 2*outerborder );
7283 cell->setGeometry( r ); 7282 cell->setGeometry( r );
7284 } 7283 }
7285} 7284}
7286 7285
7287void QTextTable::addCell( QTextTableCell* cell ) 7286void QTextTable::addCell( QTextTableCell* cell )
7288{ 7287{
7289 cells.append( cell ); 7288 cells.append( cell );
7290 layout->addMultiCell( cell, cell->row(), cell->row() + cell->rowspan()-1, 7289 layout->addMultiCell( cell, cell->row(), cell->row() + cell->rowspan()-1,
7291 cell->column(), cell->column() + cell->colspan()-1 ); 7290 cell->column(), cell->column() + cell->colspan()-1 );
7292} 7291}
7293 7292
7294bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd ) 7293bool QTextTable::enter( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd )
7295{ 7294{
7296 currCell.remove( c ); 7295 currCell.remove( c );
7297 if ( !atEnd ) 7296 if ( !atEnd )
7298 return next( c, doc, parag, idx, ox, oy ); 7297 return next( c, doc, parag, idx, ox, oy );
7299 currCell.insert( c, cells.count() ); 7298 currCell.insert( c, cells.count() );
7300 return prev( c, doc, parag, idx, ox, oy ); 7299 return prev( c, doc, parag, idx, ox, oy );
7301} 7300}
7302 7301
7303bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos ) 7302bool QTextTable::enterAt( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos )
7304{ 7303{
7305 currCell.remove( c ); 7304 currCell.remove( c );
7306 int lastCell = -1; 7305 int lastCell = -1;
7307 int lastY = -1; 7306 int lastY = -1;
7308 int i; 7307 int i;
7309 for ( i = 0; i < (int)cells.count(); ++i ) { 7308 for ( i = 0; i < (int)cells.count(); ++i ) {
7310 QTextTableCell *cell = cells.at( i ); 7309 QTextTableCell *cell = cells.at( i );
7311 if ( !cell ) 7310 if ( !cell )
7312 continue; 7311 continue;
7313 QRect r( cell->geometry().x(), 7312 QRect r( cell->geometry().x(),
7314 cell->geometry().y(), 7313 cell->geometry().y(),
7315 cell->geometry().width() + 2 * innerborder + 2 * outerborder, 7314 cell->geometry().width() + 2 * innerborder + 2 * outerborder,
7316 cell->geometry().height() + 2 * innerborder + 2 * outerborder ); 7315 cell->geometry().height() + 2 * innerborder + 2 * outerborder );
7317 7316
7318 if ( r.left() <= pos.x() && r.right() >= pos.x() ) { 7317 if ( r.left() <= pos.x() && r.right() >= pos.x() ) {
7319 if ( cell->geometry().y() > lastY ) { 7318 if ( cell->geometry().y() > lastY ) {
7320 lastCell = i; 7319 lastCell = i;
7321 lastY = cell->geometry().y(); 7320 lastY = cell->geometry().y();
7322 } 7321 }
7323 if ( r.top() <= pos.y() && r.bottom() >= pos.y() ) { 7322 if ( r.top() <= pos.y() && r.bottom() >= pos.y() ) {
7324 currCell.insert( c, i ); 7323 currCell.insert( c, i );
7325 break; 7324 break;
7326 } 7325 }
7327 } 7326 }
7328 } 7327 }
7329 if ( i == (int) cells.count() ) 7328 if ( i == (int) cells.count() )
7330 return FALSE; // no cell found 7329 return FALSE; // no cell found
7331 7330
7332 if ( currCell.find( c ) == currCell.end() ) { 7331 if ( currCell.find( c ) == currCell.end() ) {
7333 if ( lastY != -1 ) 7332 if ( lastY != -1 )
7334 currCell.insert( c, lastCell ); 7333 currCell.insert( c, lastCell );
7335 else 7334 else
7336 return FALSE; 7335 return FALSE;
7337 } 7336 }
7338 7337
7339 QTextTableCell *cell = cells.at( *currCell.find( c ) ); 7338 QTextTableCell *cell = cells.at( *currCell.find( c ) );
7340 if ( !cell ) 7339 if ( !cell )
7341 return FALSE; 7340 return FALSE;
7342 doc = cell->richText(); 7341 doc = cell->richText();
7343 parag = doc->firstParagraph(); 7342 parag = doc->firstParagraph();
7344 idx = 0; 7343 idx = 0;
7345 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7344 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7346 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7345 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7347 return TRUE; 7346 return TRUE;
7348} 7347}
7349 7348
7350bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy ) 7349bool QTextTable::next( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7351{ 7350{
7352 int cc = -1; 7351 int cc = -1;
7353 if ( currCell.find( c ) != currCell.end() ) 7352 if ( currCell.find( c ) != currCell.end() )
7354 cc = *currCell.find( c ); 7353 cc = *currCell.find( c );
7355 if ( cc > (int)cells.count() - 1 || cc < 0 ) 7354 if ( cc > (int)cells.count() - 1 || cc < 0 )
7356 cc = -1; 7355 cc = -1;
7357 currCell.remove( c ); 7356 currCell.remove( c );
7358 currCell.insert( c, ++cc ); 7357 currCell.insert( c, ++cc );
7359 if ( cc >= (int)cells.count() ) { 7358 if ( cc >= (int)cells.count() ) {
7360 currCell.insert( c, 0 ); 7359 currCell.insert( c, 0 );
7361 QTextCustomItem::next( c, doc, parag, idx, ox, oy ); 7360 QTextCustomItem::next( c, doc, parag, idx, ox, oy );
7362 QTextTableCell *cell = cells.first(); 7361 QTextTableCell *cell = cells.first();
7363 if ( !cell ) 7362 if ( !cell )
7364 return FALSE; 7363 return FALSE;
7365 doc = cell->richText(); 7364 doc = cell->richText();
7366 idx = -1; 7365 idx = -1;
7367 return TRUE; 7366 return TRUE;
7368 } 7367 }
7369 7368
7370 if ( currCell.find( c ) == currCell.end() ) 7369 if ( currCell.find( c ) == currCell.end() )
7371 return FALSE; 7370 return FALSE;
7372 QTextTableCell *cell = cells.at( *currCell.find( c ) ); 7371 QTextTableCell *cell = cells.at( *currCell.find( c ) );
7373 if ( !cell ) 7372 if ( !cell )
7374 return FALSE; 7373 return FALSE;
7375 doc = cell->richText(); 7374 doc = cell->richText();
7376 parag = doc->firstParagraph(); 7375 parag = doc->firstParagraph();
7377 idx = 0; 7376 idx = 0;
7378 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7377 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7379 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7378 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7380 return TRUE; 7379 return TRUE;
7381} 7380}
7382 7381
7383bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy ) 7382bool QTextTable::prev( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7384{ 7383{
7385 int cc = -1; 7384 int cc = -1;
7386 if ( currCell.find( c ) != currCell.end() ) 7385 if ( currCell.find( c ) != currCell.end() )
7387 cc = *currCell.find( c ); 7386 cc = *currCell.find( c );
7388 if ( cc > (int)cells.count() - 1 || cc < 0 ) 7387 if ( cc > (int)cells.count() - 1 || cc < 0 )
7389 cc = cells.count(); 7388 cc = cells.count();
7390 currCell.remove( c ); 7389 currCell.remove( c );
7391 currCell.insert( c, --cc ); 7390 currCell.insert( c, --cc );
7392 if ( cc < 0 ) { 7391 if ( cc < 0 ) {
7393 currCell.insert( c, 0 ); 7392 currCell.insert( c, 0 );
7394 QTextCustomItem::prev( c, doc, parag, idx, ox, oy ); 7393 QTextCustomItem::prev( c, doc, parag, idx, ox, oy );
7395 QTextTableCell *cell = cells.first(); 7394 QTextTableCell *cell = cells.first();
7396 if ( !cell ) 7395 if ( !cell )
7397 return FALSE; 7396 return FALSE;
7398 doc = cell->richText(); 7397 doc = cell->richText();
7399 idx = -1; 7398 idx = -1;
7400 return TRUE; 7399 return TRUE;
7401 } 7400 }
7402 7401
7403 if ( currCell.find( c ) == currCell.end() ) 7402 if ( currCell.find( c ) == currCell.end() )
7404 return FALSE; 7403 return FALSE;
7405 QTextTableCell *cell = cells.at( *currCell.find( c ) ); 7404 QTextTableCell *cell = cells.at( *currCell.find( c ) );
7406 if ( !cell ) 7405 if ( !cell )
7407 return FALSE; 7406 return FALSE;
7408 doc = cell->richText(); 7407 doc = cell->richText();
7409 parag = doc->lastParagraph(); 7408 parag = doc->lastParagraph();
7410 idx = parag->length() - 1; 7409 idx = parag->length() - 1;
7411 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7410 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7412 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7411 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7413 return TRUE; 7412 return TRUE;
7414} 7413}
7415 7414
7416bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy ) 7415bool QTextTable::down( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7417{ 7416{
7418 if ( currCell.find( c ) == currCell.end() ) 7417 if ( currCell.find( c ) == currCell.end() )
7419 return FALSE; 7418 return FALSE;
7420 QTextTableCell *cell = cells.at( *currCell.find( c ) ); 7419 QTextTableCell *cell = cells.at( *currCell.find( c ) );
7421 if ( cell->row_ == layout->numRows() - 1 ) { 7420 if ( cell->row_ == layout->numRows() - 1 ) {
7422 currCell.insert( c, 0 ); 7421 currCell.insert( c, 0 );
7423 QTextCustomItem::down( c, doc, parag, idx, ox, oy ); 7422 QTextCustomItem::down( c, doc, parag, idx, ox, oy );
7424 QTextTableCell *cell = cells.first(); 7423 QTextTableCell *cell = cells.first();
7425 if ( !cell ) 7424 if ( !cell )
7426 return FALSE; 7425 return FALSE;
7427 doc = cell->richText(); 7426 doc = cell->richText();
7428 idx = -1; 7427 idx = -1;
7429 return TRUE; 7428 return TRUE;
7430 } 7429 }
7431 7430
7432 int oldRow = cell->row_; 7431 int oldRow = cell->row_;
7433 int oldCol = cell->col_; 7432 int oldCol = cell->col_;
7434 if ( currCell.find( c ) == currCell.end() ) 7433 if ( currCell.find( c ) == currCell.end() )
7435 return FALSE; 7434 return FALSE;
7436 int cc = *currCell.find( c ); 7435 int cc = *currCell.find( c );
7437 for ( int i = cc; i < (int)cells.count(); ++i ) { 7436 for ( int i = cc; i < (int)cells.count(); ++i ) {
7438 cell = cells.at( i ); 7437 cell = cells.at( i );
7439 if ( cell->row_ > oldRow && cell->col_ == oldCol ) { 7438 if ( cell->row_ > oldRow && cell->col_ == oldCol ) {
7440 currCell.insert( c, i ); 7439 currCell.insert( c, i );
7441 break; 7440 break;
7442 } 7441 }
7443 } 7442 }
7444 doc = cell->richText(); 7443 doc = cell->richText();
7445 if ( !cell ) 7444 if ( !cell )
7446 return FALSE; 7445 return FALSE;
7447 parag = doc->firstParagraph(); 7446 parag = doc->firstParagraph();
7448 idx = 0; 7447 idx = 0;
7449 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7448 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7450 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7449 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7451 return TRUE; 7450 return TRUE;
7452} 7451}
7453 7452
7454bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy ) 7453bool QTextTable::up( QTextCursor *c, QTextDocument *&doc, QTextParagraph *&parag, int &idx, int &ox, int &oy )
7455{ 7454{
7456 if ( currCell.find( c ) == currCell.end() ) 7455 if ( currCell.find( c ) == currCell.end() )
7457 return FALSE; 7456 return FALSE;
7458 QTextTableCell *cell = cells.at( *currCell.find( c ) ); 7457 QTextTableCell *cell = cells.at( *currCell.find( c ) );
7459 if ( cell->row_ == 0 ) { 7458 if ( cell->row_ == 0 ) {
7460 currCell.insert( c, 0 ); 7459 currCell.insert( c, 0 );
7461 QTextCustomItem::up( c, doc, parag, idx, ox, oy ); 7460 QTextCustomItem::up( c, doc, parag, idx, ox, oy );
7462 QTextTableCell *cell = cells.first(); 7461 QTextTableCell *cell = cells.first();
7463 if ( !cell ) 7462 if ( !cell )
7464 return FALSE; 7463 return FALSE;
7465 doc = cell->richText(); 7464 doc = cell->richText();
7466 idx = -1; 7465 idx = -1;
7467 return TRUE; 7466 return TRUE;
7468 } 7467 }
7469 7468
7470 int oldRow = cell->row_; 7469 int oldRow = cell->row_;
7471 int oldCol = cell->col_; 7470 int oldCol = cell->col_;
7472 if ( currCell.find( c ) == currCell.end() ) 7471 if ( currCell.find( c ) == currCell.end() )
7473 return FALSE; 7472 return FALSE;
7474 int cc = *currCell.find( c ); 7473 int cc = *currCell.find( c );
7475 for ( int i = cc; i >= 0; --i ) { 7474 for ( int i = cc; i >= 0; --i ) {
7476 cell = cells.at( i ); 7475 cell = cells.at( i );
7477 if ( cell->row_ < oldRow && cell->col_ == oldCol ) { 7476 if ( cell->row_ < oldRow && cell->col_ == oldCol ) {
7478 currCell.insert( c, i ); 7477 currCell.insert( c, i );
7479 break; 7478 break;
7480 } 7479 }
7481 } 7480 }
7482 doc = cell->richText(); 7481 doc = cell->richText();
7483 if ( !cell ) 7482 if ( !cell )
7484 return FALSE; 7483 return FALSE;
7485 parag = doc->lastParagraph(); 7484 parag = doc->lastParagraph();
7486 idx = parag->length() - 1; 7485 idx = parag->length() - 1;
7487 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x(); 7486 ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
7488 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder; 7487 oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
7489 return TRUE; 7488 return TRUE;
7490} 7489}
7491 7490
7492QTextTableCell::QTextTableCell( QTextTable* table, 7491QTextTableCell::QTextTableCell( QTextTable* table,
7493 int row, int column, 7492 int row, int column,
7494 const QMap<QString, QString> &attr, 7493 const QMap<QString, QString> &attr,
7495 const QStyleSheetItem* /*style*/, // ### use them 7494 const QStyleSheetItem* /*style*/, // ### use them
7496 const QTextFormat& /*fmt*/, const QString& context, 7495 const QTextFormat& /*fmt*/, const QString& context,
7497 QMimeSourceFactory &factory, QStyleSheet *sheet, 7496 QMimeSourceFactory &factory, QStyleSheet *sheet,
7498 const QString& doc) 7497 const QString& doc)
7499{ 7498{
7500 cached_width = -1; 7499 cached_width = -1;
7501 cached_sizehint = -1; 7500 cached_sizehint = -1;
7502 7501
7503 maxw = QWIDGETSIZE_MAX; 7502 maxw = QWIDGETSIZE_MAX;
7504 minw = 0; 7503 minw = 0;
7505 7504
7506 parent = table; 7505 parent = table;
7507 row_ = row; 7506 row_ = row;
7508 col_ = column; 7507 col_ = column;
7509 stretch_ = 0; 7508 stretch_ = 0;
7510 richtext = new QTextDocument( table->parent ); 7509 richtext = new QTextDocument( table->parent );
7511 richtext->setTableCell( this ); 7510 richtext->setTableCell( this );
7512 QString a = *attr.find( "align" ); 7511 QString a = *attr.find( "align" );
7513 if ( !a.isEmpty() ) { 7512 if ( !a.isEmpty() ) {
7514 a = a.lower(); 7513 a = a.lower();
7515 if ( a == "left" ) 7514 if ( a == "left" )
7516 richtext->setAlignment( Qt::AlignLeft ); 7515 richtext->setAlignment( Qt::AlignLeft );
7517 else if ( a == "center" ) 7516 else if ( a == "center" )
7518 richtext->setAlignment( Qt::AlignHCenter ); 7517 richtext->setAlignment( Qt::AlignHCenter );
7519 else if ( a == "right" ) 7518 else if ( a == "right" )
7520 richtext->setAlignment( Qt::AlignRight ); 7519 richtext->setAlignment( Qt::AlignRight );
7521 } 7520 }
7522 align = 0; 7521 align = 0;
7523 QString va = *attr.find( "valign" ); 7522 QString va = *attr.find( "valign" );
7524 if ( !va.isEmpty() ) { 7523 if ( !va.isEmpty() ) {
7525 va = va.lower(); 7524 va = va.lower();
7526 if ( va == "center" ) 7525 if ( va == "center" )
7527 align |= Qt::AlignVCenter; 7526 align |= Qt::AlignVCenter;
7528 else if ( va == "bottom" ) 7527 else if ( va == "bottom" )
7529 align |= Qt::AlignBottom; 7528 align |= Qt::AlignBottom;
7530 } 7529 }
7531 richtext->setFormatter( table->parent->formatter() ); 7530 richtext->setFormatter( table->parent->formatter() );
7532 richtext->setUseFormatCollection( table->parent->useFormatCollection() ); 7531 richtext->setUseFormatCollection( table->parent->useFormatCollection() );
7533 richtext->setMimeSourceFactory( &factory ); 7532 richtext->setMimeSourceFactory( &factory );
7534 richtext->setStyleSheet( sheet ); 7533 richtext->setStyleSheet( sheet );
7535 richtext->setDefaultFormat( table->parent->formatCollection()->defaultFormat()->font(), 7534 richtext->setDefaultFormat( table->parent->formatCollection()->defaultFormat()->font(),
7536 table->parent->formatCollection()->defaultFormat()->color() ); 7535 table->parent->formatCollection()->defaultFormat()->color() );
7537 richtext->setRichText( doc, context ); 7536 richtext->setRichText( doc, context );
7538 rowspan_ = 1; 7537 rowspan_ = 1;
7539 colspan_ = 1; 7538 colspan_ = 1;
7540 if ( attr.contains("colspan") ) 7539 if ( attr.contains("colspan") )
7541 colspan_ = attr["colspan"].toInt(); 7540 colspan_ = attr["colspan"].toInt();
7542 if ( attr.contains("rowspan") ) 7541 if ( attr.contains("rowspan") )
7543 rowspan_ = attr["rowspan"].toInt(); 7542 rowspan_ = attr["rowspan"].toInt();
7544 7543
7545 background = 0; 7544 background = 0;
7546 if ( attr.contains("bgcolor") ) { 7545 if ( attr.contains("bgcolor") ) {
7547 background = new QBrush(QColor( attr["bgcolor"] )); 7546 background = new QBrush(QColor( attr["bgcolor"] ));
7548 } 7547 }
7549 7548
7550 7549
7551 hasFixedWidth = FALSE; 7550 hasFixedWidth = FALSE;
7552 if ( attr.contains("width") ) { 7551 if ( attr.contains("width") ) {
7553 bool b; 7552 bool b;
7554 QString s( attr["width"] ); 7553 QString s( attr["width"] );
7555 int w = s.toInt( &b ); 7554 int w = s.toInt( &b );
7556 if ( b ) { 7555 if ( b ) {
7557 maxw = w; 7556 maxw = w;
7558 minw = maxw; 7557 minw = maxw;
7559 hasFixedWidth = TRUE; 7558 hasFixedWidth = TRUE;
7560 } else { 7559 } else {
7561 s = s.stripWhiteSpace(); 7560 s = s.stripWhiteSpace();
7562 if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' ) 7561 if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' )
7563 stretch_ = s.left( s.length()-1).toInt(); 7562 stretch_ = s.left( s.length()-1).toInt();
7564 } 7563 }
7565 } 7564 }
7566 7565
7567 attributes = attr; 7566 attributes = attr;
7568 7567
7569 parent->addCell( this ); 7568 parent->addCell( this );
7570} 7569}
7571 7570
7572QTextTableCell::~QTextTableCell() 7571QTextTableCell::~QTextTableCell()
7573{ 7572{
7574 delete background; 7573 delete background;
7575 background = 0; 7574 background = 0;
7576 delete richtext; 7575 delete richtext;
7577 richtext = 0; 7576 richtext = 0;
7578} 7577}
7579 7578
7580QSize QTextTableCell::sizeHint() const 7579QSize QTextTableCell::sizeHint() const
7581{ 7580{
7582 int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance); 7581 int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance);
7583 int used = richtext->widthUsed() + extra; 7582 int used = richtext->widthUsed() + extra;
7584 7583
7585 if (stretch_ ) { 7584 if (stretch_ ) {
7586 int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding; 7585 int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding;
7587 return QSize( QMIN( w, maxw ), 0 ).expandedTo( minimumSize() ); 7586 return QSize( QMIN( w, maxw ), 0 ).expandedTo( minimumSize() );
7588 } 7587 }
7589 7588
7590 return QSize( used, 0 ).expandedTo( minimumSize() ); 7589 return QSize( used, 0 ).expandedTo( minimumSize() );
7591} 7590}
7592 7591
7593QSize QTextTableCell::minimumSize() const 7592QSize QTextTableCell::minimumSize() const
7594{ 7593{
7595 int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance); 7594 int extra = 2 * ( parent->innerborder + parent->cellpadding + border_tolerance);
7596 return QSize( QMAX( richtext->minimumWidth() + extra, minw), 0 ); 7595 return QSize( QMAX( richtext->minimumWidth() + extra, minw), 0 );
7597} 7596}
7598 7597
7599QSize QTextTableCell::maximumSize() const 7598QSize QTextTableCell::maximumSize() const
7600{ 7599{
7601 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ); 7600 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
7602} 7601}
7603 7602
7604QSizePolicy::ExpandData QTextTableCell::expanding() const 7603QSizePolicy::ExpandData QTextTableCell::expanding() const
7605{ 7604{
7606 return QSizePolicy::BothDirections; 7605 return QSizePolicy::BothDirections;
7607} 7606}
7608 7607
7609bool QTextTableCell::isEmpty() const 7608bool QTextTableCell::isEmpty() const
7610{ 7609{
7611 return FALSE; 7610 return FALSE;
7612} 7611}
7613void QTextTableCell::setGeometry( const QRect& r ) 7612void QTextTableCell::setGeometry( const QRect& r )
7614{ 7613{
7615 int extra = 2 * ( parent->innerborder + parent->cellpadding ); 7614 int extra = 2 * ( parent->innerborder + parent->cellpadding );
7616 if ( r.width() != cached_width ) 7615 if ( r.width() != cached_width )
7617 richtext->doLayout( QTextFormat::painter(), r.width() - extra ); 7616 richtext->doLayout( QTextFormat::painter(), r.width() - extra );
7618 cached_width = r.width(); 7617 cached_width = r.width();
7619 geom = r; 7618 geom = r;
7620} 7619}
7621 7620
7622QRect QTextTableCell::geometry() const 7621QRect QTextTableCell::geometry() const
7623{ 7622{
7624 return geom; 7623 return geom;
7625} 7624}
7626 7625
7627bool QTextTableCell::hasHeightForWidth() const 7626bool QTextTableCell::hasHeightForWidth() const
7628{ 7627{
7629 return TRUE; 7628 return TRUE;
7630} 7629}
7631 7630
7632int QTextTableCell::heightForWidth( int w ) const 7631int QTextTableCell::heightForWidth( int w ) const
7633{ 7632{
7634 int extra = 2 * ( parent->innerborder + parent->cellpadding ); 7633 int extra = 2 * ( parent->innerborder + parent->cellpadding );
7635 w = QMAX( minw, w ); 7634 w = QMAX( minw, w );
7636 7635
7637 if ( cached_width != w ) { 7636 if ( cached_width != w ) {
7638 QTextTableCell* that = (QTextTableCell*) this; 7637 QTextTableCell* that = (QTextTableCell*) this;
7639 that->richtext->doLayout( QTextFormat::painter(), w - extra ); 7638 that->richtext->doLayout( QTextFormat::painter(), w - extra );
7640 that->cached_width = w; 7639 that->cached_width = w;
7641 } 7640 }
7642 return richtext->height() + extra; 7641 return richtext->height() + extra;
7643} 7642}
7644 7643
7645void QTextTableCell::adjustToPainter( QPainter* p ) 7644void QTextTableCell::adjustToPainter( QPainter* p )
7646{ 7645{
7647 QTextParagraph *parag = richtext->firstParagraph(); 7646 QTextParagraph *parag = richtext->firstParagraph();
7648 while ( parag ) { 7647 while ( parag ) {
7649 parag->adjustToPainter( p ); 7648 parag->adjustToPainter( p );
7650 parag = parag->next(); 7649 parag = parag->next();
7651 } 7650 }
7652} 7651}
7653 7652
7654int QTextTableCell::horizontalAlignmentOffset() const 7653int QTextTableCell::horizontalAlignmentOffset() const
7655{ 7654{
7656 return parent->cellpadding; 7655 return parent->cellpadding;
7657} 7656}
7658 7657
7659int QTextTableCell::verticalAlignmentOffset() const 7658int QTextTableCell::verticalAlignmentOffset() const
7660{ 7659{
7661 if ( (align & Qt::AlignVCenter ) == Qt::AlignVCenter ) 7660 if ( (align & Qt::AlignVCenter ) == Qt::AlignVCenter )
7662 return ( geom.height() - richtext->height() ) / 2; 7661 return ( geom.height() - richtext->height() ) / 2;
7663 else if ( ( align & Qt::AlignBottom ) == Qt::AlignBottom ) 7662 else if ( ( align & Qt::AlignBottom ) == Qt::AlignBottom )
7664 return geom.height() - parent->cellpadding - richtext->height() ; 7663 return geom.height() - parent->cellpadding - richtext->height() ;
7665 return parent->cellpadding; 7664 return parent->cellpadding;
7666} 7665}
7667 7666
7668void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool ) 7667void QTextTableCell::draw( QPainter* p, int x, int y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool )
7669{ 7668{
7670 if ( cached_width != geom.width() ) { 7669 if ( cached_width != geom.width() ) {
7671 int extra = 2 * ( parent->innerborder + parent->cellpadding ); 7670 int extra = 2 * ( parent->innerborder + parent->cellpadding );
7672 richtext->doLayout( p, geom.width() - extra ); 7671 richtext->doLayout( p, geom.width() - extra );
7673 cached_width = geom.width(); 7672 cached_width = geom.width();
7674 } 7673 }
7675 QColorGroup g( cg ); 7674 QColorGroup g( cg );
7676 if ( background ) 7675 if ( background )
7677 g.setBrush( QColorGroup::Base, *background ); 7676 g.setBrush( QColorGroup::Base, *background );
7678 else if ( richtext->paper() ) 7677 else if ( richtext->paper() )
7679 g.setBrush( QColorGroup::Base, *richtext->paper() ); 7678 g.setBrush( QColorGroup::Base, *richtext->paper() );
7680 7679
7681 p->save(); 7680 p->save();
7682 p->translate( x + geom.x(), y + geom.y() ); 7681 p->translate( x + geom.x(), y + geom.y() );
7683 if ( background ) 7682 if ( background )
7684 p->fillRect( 0, 0, geom.width(), geom.height(), *background ); 7683 p->fillRect( 0, 0, geom.width(), geom.height(), *background );
7685 else if ( richtext->paper() ) 7684 else if ( richtext->paper() )
7686 p->fillRect( 0, 0, geom.width(), geom.height(), *richtext->paper() ); 7685 p->fillRect( 0, 0, geom.width(), geom.height(), *richtext->paper() );
7687 7686
7688 p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() ); 7687 p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() );
7689 7688
7690 QRegion r; 7689 QRegion r;
7691 if ( cx >= 0 && cy >= 0 ) 7690 if ( cx >= 0 && cy >= 0 )
7692 richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ), 7691 richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ),
7693 cy - ( y + geom.y() + verticalAlignmentOffset() ), 7692 cy - ( y + geom.y() + verticalAlignmentOffset() ),
7694 cw, ch, g, FALSE, FALSE, 0 ); 7693 cw, ch, g, FALSE, FALSE, 0 );
7695 else 7694 else
7696 richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 ); 7695 richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 );
7697 7696
7698 p->restore(); 7697 p->restore();
7699} 7698}
7700 7699
7701QString QTextDocument::section( QString str, const QString &sep, int start, int end ) 7700QString QTextDocument::section( QString str, const QString &sep, int start, int end )
7702{ 7701{
7703 const QChar *uc = str.unicode(); 7702 const QChar *uc = str.unicode();
7704 if ( !uc ) 7703 if ( !uc )
7705 return QString(); 7704 return QString();
7706 QString _sep = sep; 7705 QString _sep = sep;
7707 const QChar *uc_sep = _sep.unicode(); 7706 const QChar *uc_sep = _sep.unicode();
7708 if(!uc_sep) 7707 if(!uc_sep)
7709 return QString(); 7708 return QString();
7710 bool match = FALSE, last_match = TRUE; 7709 bool match = FALSE, last_match = TRUE;
7711 7710
7712 //find start 7711 //find start
7713 int n = str.length(), sep_len = _sep.length(); 7712 int n = str.length(), sep_len = _sep.length();
7714 const QChar *begin = start < 0 ? uc + n : uc; 7713 const QChar *begin = start < 0 ? uc + n : uc;
7715 while(start) { 7714 while(start) {
7716 match = FALSE; 7715 match = FALSE;
7717 int c = 0; 7716 int c = 0;
7718 for(const QChar *tmp = start < 0 ? begin - sep_len : begin; 7717 for(const QChar *tmp = start < 0 ? begin - sep_len : begin;
7719 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { 7718 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
7720 if( *tmp != *(uc_sep + c) ) 7719 if( *tmp != *(uc_sep + c) )
7721 break; 7720 break;
7722 if(c == sep_len - 1) { 7721 if(c == sep_len - 1) {
7723 match = TRUE; 7722 match = TRUE;
7724 break; 7723 break;
7725 } 7724 }
7726 } 7725 }
7727 last_match = match; 7726 last_match = match;
7728 7727
7729 if(start < 0) { 7728 if(start < 0) {
7730 if(match) { 7729 if(match) {
7731 begin -= sep_len; 7730 begin -= sep_len;
7732 if(!++start) 7731 if(!++start)
7733 break; 7732 break;
7734 } else { 7733 } else {
7735 if(start == -1 && begin == uc) 7734 if(start == -1 && begin == uc)
7736 break; 7735 break;
7737 begin--; 7736 begin--;
7738 } 7737 }
7739 } else { 7738 } else {
7740 if(match) { 7739 if(match) {
7741 if(!--start) 7740 if(!--start)
7742 break; 7741 break;
7743 begin += sep_len; 7742 begin += sep_len;
7744 } else { 7743 } else {
7745 if(start == 1 && begin == uc + n) 7744 if(start == 1 && begin == uc + n)
7746 break; 7745 break;
7747 begin++; 7746 begin++;
7748 } 7747 }
7749 } 7748 }
7750 if(begin > uc + n || begin < uc) 7749 if(begin > uc + n || begin < uc)
7751 return QString(); 7750 return QString();
7752 } 7751 }
7753 if(match) 7752 if(match)
7754 begin+=sep_len; 7753 begin+=sep_len;
7755 if(begin > uc + n || begin < uc) 7754 if(begin > uc + n || begin < uc)
7756 return QString(); 7755 return QString();
7757 7756
7758 //now find last 7757 //now find last
7759 match = FALSE; 7758 match = FALSE;
7760 const QChar *last = end < 0 ? uc + n : uc; 7759 const QChar *last = end < 0 ? uc + n : uc;
7761 if(end == -1) { 7760 if(end == -1) {
7762 int c = 0; 7761 int c = 0;
7763 for(const QChar *tmp = end < 0 ? last - sep_len : last; 7762 for(const QChar *tmp = end < 0 ? last - sep_len : last;
7764 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { 7763 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
7765 if( *tmp != *(uc_sep + c) ) 7764 if( *tmp != *(uc_sep + c) )
7766 break; 7765 break;
7767 if(c == sep_len - 1) { 7766 if(c == sep_len - 1) {
7768 match = TRUE; 7767 match = TRUE;
7769 break; 7768 break;
7770 } 7769 }
7771 } 7770 }
7772 } else { 7771 } else {
7773 end++; 7772 end++;
7774 last_match = TRUE; 7773 last_match = TRUE;
7775 while(end) { 7774 while(end) {
7776 match = FALSE; 7775 match = FALSE;
7777 int c = 0; 7776 int c = 0;
7778 for(const QChar *tmp = end < 0 ? last - sep_len : last; 7777 for(const QChar *tmp = end < 0 ? last - sep_len : last;
7779 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) { 7778 c < sep_len && tmp < uc + n && tmp >= uc; tmp++, c++) {
7780 if( *tmp != *(uc_sep + c) ) 7779 if( *tmp != *(uc_sep + c) )
7781 break; 7780 break;
7782 if(c == sep_len - 1) { 7781 if(c == sep_len - 1) {
7783 match = TRUE; 7782 match = TRUE;
7784 break; 7783 break;
7785 } 7784 }
7786 } 7785 }
7787 last_match = match; 7786 last_match = match;
7788 7787
7789 if(end < 0) { 7788 if(end < 0) {
7790 if(match) { 7789 if(match) {
7791 if(!++end) 7790 if(!++end)
7792 break; 7791 break;
7793 last -= sep_len; 7792 last -= sep_len;
7794 } else { 7793 } else {
7795 last--; 7794 last--;
7796 } 7795 }
7797 } else { 7796 } else {
7798 if(match) { 7797 if(match) {
7799 last += sep_len; 7798 last += sep_len;
7800 if(!--end) 7799 if(!--end)
7801 break; 7800 break;
7802 } else { 7801 } else {
7803 last++; 7802 last++;
7804 } 7803 }
7805 } 7804 }
7806 if(last >= uc + n) { 7805 if(last >= uc + n) {
7807 last = uc + n; 7806 last = uc + n;
7808 break; 7807 break;
7809 } else if(last < uc) { 7808 } else if(last < uc) {
7810 return QString(); 7809 return QString();
7811 } 7810 }
7812 } 7811 }
7813 } 7812 }
7814 if(match) 7813 if(match)
7815 last -= sep_len; 7814 last -= sep_len;
7816 if(last < uc || last > uc + n || begin >= last) 7815 if(last < uc || last > uc + n || begin >= last)
7817 return QString(); 7816 return QString();
7818 7817
7819 //done 7818 //done
7820 return QString(begin, last - begin); 7819 return QString(begin, last - begin);
7821} 7820}
7822 7821
7823bool QTextDocument::endsWith( QString str, const QString &s) 7822bool QTextDocument::endsWith( QString str, const QString &s)
7824{ 7823{
7825 if ( str.isNull() ) 7824 if ( str.isNull() )
7826 return s.isNull(); 7825 return s.isNull();
7827 int pos = str.length() - s.length(); 7826 int pos = str.length() - s.length();
7828 if ( pos < 0 ) 7827 if ( pos < 0 )
7829 return FALSE; 7828 return FALSE;
7830 for ( uint i = 0; i < s.length(); i++ ) { 7829 for ( uint i = 0; i < s.length(); i++ ) {
7831 if ( str.unicode()[pos+i] != s[(int)i] ) 7830 if ( str.unicode()[pos+i] != s[(int)i] )
7832 return FALSE; 7831 return FALSE;
7833 } 7832 }
7834 return TRUE; 7833 return TRUE;
7835} 7834}
diff --git a/noncore/apps/tinykate/libkate/document/katehighlight.cpp b/noncore/apps/tinykate/libkate/document/katehighlight.cpp
index 539d356..89024f7 100644
--- a/noncore/apps/tinykate/libkate/document/katehighlight.cpp
+++ b/noncore/apps/tinykate/libkate/document/katehighlight.cpp
@@ -1,1463 +1,1468 @@
1/* 1/*
2 Copyright (C) 1998, 1999 Jochen Wilhelmy 2 Copyright (C) 1998, 1999 Jochen Wilhelmy
3 digisnap@cs.tu-berlin.de 3 digisnap@cs.tu-berlin.de
4 (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org> 4 (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org>
5 (C) 2002 Joseph Wenninger <jowenn@kde.org> 5 (C) 2002 Joseph Wenninger <jowenn@kde.org>
6 This library is free software; you can redistribute it and/or 6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either 8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version. 9 version 2 of the License, or (at your option) any later version.
10 10
11 This library is distributed in the hope that it will be useful, 11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details. 14 Library General Public License for more details.
15 15
16 You should have received a copy of the GNU Library General Public License 16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to 17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20*/ 20*/
21 21
22#include "katehighlight.h" 22#include "katehighlight.h"
23#include "katetextline.h" 23#include "katetextline.h"
24#include "katedocument.h" 24#include "katedocument.h"
25#include "katesyntaxdocument.h" 25#include "katesyntaxdocument.h"
26 26
27#include "kglobal.h" 27#include "kglobal.h"
28//#include "kinstance.h" 28//#include "kinstance.h"
29//#include "kmimemagic.h" 29//#include "kmimemagic.h"
30#include "klocale.h" 30#include "klocale.h"
31//#include "kregexp.h" 31//#include "kregexp.h"
32#include "kglobalsettings.h" 32#include "kglobalsettings.h"
33#include "kdebug.h" 33#include "kdebug.h"
34#include "kstddirs.h" 34#include "kstddirs.h"
35 35
36/* OPIE */ 36/* OPIE */
37#include <opie2/odebug.h> 37#include <opie2/odebug.h>
38#include <qpe/config.h> 38#include <qpe/config.h>
39 39
40/* QT */ 40/* QT */
41#include <qtextstream.h> 41#include <qtextstream.h>
42 42
43/* STD */ 43/* STD */
44#include <string.h> 44#include <string.h>
45 45
46 46
47HlManager *HlManager::s_pSelf = 0; 47HlManager *HlManager::s_pSelf = 0;
48 48
49enum Item_styles { dsNormal,dsKeyword,dsDataType,dsDecVal,dsBaseN,dsFloat,dsChar,dsString,dsComment,dsOthers}; 49enum Item_styles { dsNormal,dsKeyword,dsDataType,dsDecVal,dsBaseN,dsFloat,dsChar,dsString,dsComment,dsOthers};
50 50
51static bool trueBool = true; 51static bool trueBool = true;
52static QString stdDeliminator = QString ("!%&()*+,-./:;<=>?[]^{|}~ \t\\"); 52static QString stdDeliminator = QString ("!%&()*+,-./:;<=>?[]^{|}~ \t\\");
53 53
54int getDefStyleNum(QString name) 54int getDefStyleNum(QString name)
55{ 55{
56 if (name=="dsNormal") return dsNormal; 56 if (name=="dsNormal") return dsNormal;
57 if (name=="dsKeyword") return dsKeyword; 57 if (name=="dsKeyword") return dsKeyword;
58 if (name=="dsDataType") return dsDataType; 58 if (name=="dsDataType") return dsDataType;
59 if (name=="dsDecVal") return dsDecVal; 59 if (name=="dsDecVal") return dsDecVal;
60 if (name=="dsBaseN") return dsBaseN; 60 if (name=="dsBaseN") return dsBaseN;
61 if (name=="dsFloat") return dsFloat; 61 if (name=="dsFloat") return dsFloat;
62 if (name=="dsChar") return dsChar; 62 if (name=="dsChar") return dsChar;
63 if (name=="dsString") return dsString; 63 if (name=="dsString") return dsString;
64 if (name=="dsComment") return dsComment; 64 if (name=="dsComment") return dsComment;
65 if (name=="dsOthers") return dsOthers; 65 if (name=="dsOthers") return dsOthers;
66 66
67 return dsNormal; 67 return dsNormal;
68} 68}
69 69
70bool ustrchr(const QChar *s, uint len, QChar c) 70bool ustrchr(const QChar *s, uint len, QChar c)
71{ 71{
72 for (int z=0; z < len; z++) 72 for (int z=0; z < len; z++)
73 { 73 {
74 if (*s == c) return true; 74 if (*s == c) return true;
75 s++; 75 s++;
76 } 76 }
77 77
78 return false; 78 return false;
79} 79}
80 80
81HlItem::HlItem(int attribute, int context) 81HlItem::HlItem(int attribute, int context)
82 : attr(attribute), ctx(context) {subItems=0; 82 : attr(attribute), ctx(context) {subItems=0;
83} 83}
84 84
85HlItem::~HlItem() 85HlItem::~HlItem()
86{ 86{
87 //kdDebug(13010)<<"In hlItem::~HlItem()"<<endl; 87 //kdDebug(13010)<<"In hlItem::~HlItem()"<<endl;
88 if (subItems!=0) {subItems->setAutoDelete(true); subItems->clear(); delete subItems;} 88 if (subItems!=0) {subItems->setAutoDelete(true); subItems->clear(); delete subItems;}
89} 89}
90 90
91bool HlItem::startEnable(QChar c) 91bool HlItem::startEnable(QChar c)
92{ 92{
93 return true; 93 return true;
94} 94}
95 95
96HlCharDetect::HlCharDetect(int attribute, int context, QChar c) 96HlCharDetect::HlCharDetect(int attribute, int context, QChar c)
97 : HlItem(attribute,context), sChar(c) { 97 : HlItem(attribute,context), sChar(c) {
98} 98}
99 99
100const QChar *HlCharDetect::checkHgl(const QChar *str, int len, bool) { 100const QChar *HlCharDetect::checkHgl(const QChar *str, int len, bool) {
101 if (*str == sChar) return str + 1; 101 if (*str == sChar) return str + 1;
102 return 0L; 102 return 0L;
103} 103}
104 104
105Hl2CharDetect::Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2) 105Hl2CharDetect::Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2)
106 : HlItem(attribute,context) { 106 : HlItem(attribute,context) {
107 sChar1 = ch1; 107 sChar1 = ch1;
108 sChar2 = ch2; 108 sChar2 = ch2;
109} 109}
110 110
111const QChar *Hl2CharDetect::checkHgl(const QChar *str, int len, bool) { 111const QChar *Hl2CharDetect::checkHgl(const QChar *str, int len, bool) {
112 if (str[0] == sChar1 && str[1] == sChar2) return str + 2; 112 if (str[0] == sChar1 && str[1] == sChar2) return str + 2;
113 return 0L; 113 return 0L;
114} 114}
115 115
116HlStringDetect::HlStringDetect(int attribute, int context, const QString &s, bool inSensitive) 116HlStringDetect::HlStringDetect(int attribute, int context, const QString &s, bool inSensitive)
117 : HlItem(attribute, context), str(inSensitive ? s.upper():s), _inSensitive(inSensitive) { 117 : HlItem(attribute, context), str(inSensitive ? s.upper():s), _inSensitive(inSensitive) {
118} 118}
119 119
120HlStringDetect::~HlStringDetect() { 120HlStringDetect::~HlStringDetect() {
121} 121}
122 122
123const QChar *HlStringDetect::checkHgl(const QChar *s, int len, bool) { 123const QChar *HlStringDetect::checkHgl(const QChar *s, int len, bool) {
124 if (!_inSensitive) {if (memcmp(s, str.unicode(), str.length()*sizeof(QChar)) == 0) return s + str.length();} 124 if (!_inSensitive) {if (memcmp(s, str.unicode(), str.length()*sizeof(QChar)) == 0) return s + str.length();}
125 else 125 else
126 { 126 {
127 QString tmp=QString(s,str.length()).upper(); 127 QString tmp=QString(s,str.length()).upper();
128 if (tmp==str) return s+str.length(); 128 if (tmp==str) return s+str.length();
129 } 129 }
130 return 0L; 130 return 0L;
131} 131}
132 132
133 133
134HlRangeDetect::HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2) 134HlRangeDetect::HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2)
135 : HlItem(attribute,context) { 135 : HlItem(attribute,context) {
136 sChar1 = ch1; 136 sChar1 = ch1;
137 sChar2 = ch2; 137 sChar2 = ch2;
138} 138}
139 139
140const QChar *HlRangeDetect::checkHgl(const QChar *s, int len, bool) { 140const QChar *HlRangeDetect::checkHgl(const QChar *s, int len, bool) {
141 if (*s == sChar1) 141 if (*s == sChar1)
142 { 142 {
143 do 143 do
144 { 144 {
145 s++; 145 s++;
146 len--; 146 len--;
147 if (len == 0) return 0L; 147 if (len == 0) return 0L;
148 } 148 }
149 while (*s != sChar2); 149 while (*s != sChar2);
150 150
151 return s + 1; 151 return s + 1;
152 } 152 }
153 return 0L; 153 return 0L;
154} 154}
155 155
156HlKeyword::HlKeyword (int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen) 156HlKeyword::HlKeyword (int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen)
157 : HlItem(attribute,context), dict (113, casesensitive) 157 : HlItem(attribute,context), dict (113, casesensitive)
158{ 158{
159 deliminatorChars = deliminator; 159 deliminatorChars = deliminator;
160 deliminatorLen = deliLen; 160 deliminatorLen = deliLen;
161 _caseSensitive=casesensitive; 161 _caseSensitive=casesensitive;
162} 162}
163 163
164HlKeyword::~HlKeyword() { 164HlKeyword::~HlKeyword() {
165} 165}
166 166
167bool HlKeyword::startEnable(QChar c) 167bool HlKeyword::startEnable(QChar c)
168{ 168{
169 return ustrchr(deliminatorChars, deliminatorLen, c); 169 return ustrchr(deliminatorChars, deliminatorLen, c);
170} 170}
171 171
172// If we use a dictionary for lookup we don't really need 172// If we use a dictionary for lookup we don't really need
173// an item as such we are using the key to lookup 173// an item as such we are using the key to lookup
174void HlKeyword::addWord(const QString &word) 174void HlKeyword::addWord(const QString &word)
175{ 175{
176 words.append(word); 176 words.append(word);
177 dict.insert(word,&trueBool); 177 dict.insert(word,&trueBool);
178} 178}
179 179
180void HlKeyword::addList(const QStringList& list) 180void HlKeyword::addList(const QStringList& list)
181{ 181{
182 182
183 words+=list; 183 words+=list;
184 for(uint i=0;i<list.count();i++) dict.insert(list[i], &trueBool); 184 for(uint i=0;i<list.count();i++) dict.insert(list[i], &trueBool);
185} 185}
186 186
187const QChar *HlKeyword::checkHgl(const QChar *s, int len, bool b) 187const QChar *HlKeyword::checkHgl(const QChar *s, int len, bool b)
188{ 188{
189 if (len == 0) return 0L; 189 if (len == 0) return 0L;
190 190
191 const QChar *s2 = s; 191 const QChar *s2 = s;
192 192
193 while ( (len > 0) && (!ustrchr(deliminatorChars, deliminatorLen, *s2)) ) 193 while ( (len > 0) && (!ustrchr(deliminatorChars, deliminatorLen, *s2)) )
194 { 194 {
195 s2++; 195 s2++;
196 len--; 196 len--;
197 } 197 }
198 198
199 if (s2 == s) return 0L; 199 if (s2 == s) return 0L;
200 200
201 QString lookup = QString(s,s2-s); 201 QString lookup = QString(s,s2-s);
202 202
203 if ( dict.find(lookup) ) return s2; 203 if ( dict.find(lookup) ) return s2;
204 return 0L; 204 return 0L;
205} 205}
206 206
207HlInt::HlInt(int attribute, int context) 207HlInt::HlInt(int attribute, int context)
208 : HlItem(attribute,context) { 208 : HlItem(attribute,context) {
209} 209}
210 210
211const QChar *HlInt::checkHgl(const QChar *str, int len, bool) { 211const QChar *HlInt::checkHgl(const QChar *str, int len, bool) {
212 const QChar *s,*s1; 212 const QChar *s,*s1;
213 213
214 s = str; 214 s = str;
215 while (s->isDigit()) s++; 215 while (s->isDigit()) s++;
216 if (s > str) 216 if (s > str)
217 { 217 {
218 if (subItems) 218 if (subItems)
219 { 219 {
220 for (HlItem *it=subItems->first();it;it=subItems->next()) 220 for (HlItem *it=subItems->first();it;it=subItems->next())
221 { 221 {
222 s1=it->checkHgl(s, len, false); 222 s1=it->checkHgl(s, len, false);
223 if (s1) return s1; 223 if (s1) return s1;
224 } 224 }
225 } 225 }
226 return s; 226 return s;
227 } 227 }
228 return 0L; 228 return 0L;
229} 229}
230 230
231HlFloat::HlFloat(int attribute, int context) 231HlFloat::HlFloat(int attribute, int context)
232 : HlItem(attribute,context) { 232 : HlItem(attribute,context) {
233} 233}
234 234
235const QChar *HlFloat::checkHgl(const QChar *s, int len, bool) { 235const QChar *HlFloat::checkHgl(const QChar *s, int len, bool) {
236 bool b, p; 236 bool b, p;
237 const QChar *s1; 237 const QChar *s1;
238 238
239 b = false; 239 b = false;
240 while (s->isDigit()){ 240 while (s->isDigit()){
241 s++; 241 s++;
242 b = true; 242 b = true;
243 } 243 }
244 if (p = (*s == '.')) { 244 if (p = (*s == '.')) {
245 s++; 245 s++;
246 while (s->isDigit()) { 246 while (s->isDigit()) {
247 s++; 247 s++;
248 b = true; 248 b = true;
249 } 249 }
250 } 250 }
251 if (!b) return 0L; 251 if (!b) return 0L;
252 if ((*s&0xdf) == 'E') s++; 252 if ((*s&0xdf) == 'E') s++;
253 else 253 else
254 if (!p) return 0L; 254 if (!p) return 0L;
255 else 255 else
256 { 256 {
257 if (subItems) 257 if (subItems)
258 { 258 {
259 for (HlItem *it=subItems->first();it;it=subItems->next()) 259 for (HlItem *it=subItems->first();it;it=subItems->next())
260 { 260 {
261 s1=it->checkHgl(s, len, false); 261 s1=it->checkHgl(s, len, false);
262 if (s1) return s1; 262 if (s1) return s1;
263 } 263 }
264 } 264 }
265 return s; 265 return s;
266 } 266 }
267 if ((*s == '-')||(*s =='+')) s++; 267 if ((*s == '-')||(*s =='+')) s++;
268 b = false; 268 b = false;
269 while (s->isDigit()) { 269 while (s->isDigit()) {
270 s++; 270 s++;
271 b = true; 271 b = true;
272 } 272 }
273 if (b) 273 if (b)
274 { 274 {
275 if (subItems) 275 if (subItems)
276 { 276 {
277 for (HlItem *it=subItems->first();it;it=subItems->next()) 277 for (HlItem *it=subItems->first();it;it=subItems->next())
278 { 278 {
279 s1=it->checkHgl(s, len, false); 279 s1=it->checkHgl(s, len, false);
280 if (s1) return s1; 280 if (s1) return s1;
281 } 281 }
282 } 282 }
283 return s; 283 return s;
284 } 284 }
285 else return 0L; 285 else return 0L;
286} 286}
287 287
288 288
289HlCInt::HlCInt(int attribute, int context) 289HlCInt::HlCInt(int attribute, int context)
290 : HlInt(attribute,context) { 290 : HlInt(attribute,context) {
291} 291}
292 292
293const QChar *HlCInt::checkHgl(const QChar *s, int len, bool lineStart) { 293const QChar *HlCInt::checkHgl(const QChar *s, int len, bool lineStart) {
294 294
295// if (*s == '0') s++; else s = HlInt::checkHgl(s); 295// if (*s == '0') s++; else s = HlInt::checkHgl(s);
296 s = HlInt::checkHgl(s, len, lineStart); 296 s = HlInt::checkHgl(s, len, lineStart);
297 if (s != 0L) { 297 if (s != 0L) {
298 int l = 0; 298 int l = 0;
299 int u = 0; 299 int u = 0;
300 const QChar *str; 300 const QChar *str;
301 301
302 do { 302 do {
303 str = s; 303 str = s;
304 if ((*s&0xdf) == 'L' ) { 304 if ((*s&0xdf) == 'L' ) {
305 l++; 305 l++;
306 if (l > 2) return 0L; 306 if (l > 2) return 0L;
307 s++; 307 s++;
308 } 308 }
309 if ((*s&0xdf) == 'U' ){ 309 if ((*s&0xdf) == 'U' ){
310 u++; 310 u++;
311 if (u > 1) return 0L; 311 if (u > 1) return 0L;
312 s++; 312 s++;
313 } 313 }
314 } while (s != str); 314 } while (s != str);
315 } 315 }
316 return s; 316 return s;
317} 317}
318 318
319HlCOct::HlCOct(int attribute, int context) 319HlCOct::HlCOct(int attribute, int context)
320 : HlItem(attribute,context) { 320 : HlItem(attribute,context) {
321} 321}
322 322
323const QChar *HlCOct::checkHgl(const QChar *str, int len, bool) { 323const QChar *HlCOct::checkHgl(const QChar *str, int len, bool) {
324 const QChar *s; 324 const QChar *s;
325 325
326 if (*str == '0') { 326 if (*str == '0') {
327 str++; 327 str++;
328 s = str; 328 s = str;
329 while (*s >= '0' && *s <= '7') s++; 329 while (*s >= '0' && *s <= '7') s++;
330 if (s > str) { 330 if (s > str) {
331 if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++; 331 if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++;
332 return s; 332 return s;
333 } 333 }
334 } 334 }
335 return 0L; 335 return 0L;
336} 336}
337 337
338HlCHex::HlCHex(int attribute, int context) 338HlCHex::HlCHex(int attribute, int context)
339 : HlItem(attribute,context) { 339 : HlItem(attribute,context) {
340} 340}
341 341
342const QChar *HlCHex::checkHgl(const QChar *str, int len, bool) { 342const QChar *HlCHex::checkHgl(const QChar *str, int len, bool) {
343 const QChar *s=str; 343 const QChar *s=str;
344#if 0 344#if 0
345 int i; 345 int i;
346 for (i=0;(*s)!='\0';s++,i++); 346 for (i=0;(*s)!='\0';s++,i++);
347 QString line(str,i); 347 QString line(str,i);
348 QRegExp3 rx("0[xX][a-fA-F\\d]+[UuLl]?"); // this matches but is also matching parenthesis 348 QRegExp3 rx("0[xX][a-fA-F\\d]+[UuLl]?"); // this matches but is also matching parenthesis
349 int pos=rx.search(line,0); 349 int pos=rx.search(line,0);
350 if(pos > -1) return str+rx.matchedLength(); 350 if(pos > -1) return str+rx.matchedLength();
351 else 351 else
352 return 0L; 352 return 0L;
353 353
354#else 354#else
355 if (str[0] == '0' && ((str[1]&0xdf) == 'X' )) { 355 if (str[0] == '0' && ((str[1]&0xdf) == 'X' )) {
356 str += 2; 356 str += 2;
357 s = str; 357 s = str;
358 while (s->isDigit() || ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') /*|| (*s >= 'a' && *s <= 'f')*/) s++; 358 while (s->isDigit() || ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') /*|| (*s >= 'a' && *s <= 'f')*/) s++;
359 if (s > str) { 359 if (s > str) {
360 if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++; 360 if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++;
361 return s; 361 return s;
362 } 362 }
363 } 363 }
364 return 0L; 364 return 0L;
365#endif 365#endif
366} 366}
367 367
368HlCFloat::HlCFloat(int attribute, int context) 368HlCFloat::HlCFloat(int attribute, int context)
369 : HlFloat(attribute,context) { 369 : HlFloat(attribute,context) {
370} 370}
371 371
372const QChar *HlCFloat::checkHgl(const QChar *s, int len, bool lineStart) { 372const QChar *HlCFloat::checkHgl(const QChar *s, int len, bool lineStart) {
373 373
374 s = HlFloat::checkHgl(s, len, lineStart); 374 s = HlFloat::checkHgl(s, len, lineStart);
375 if (s && ((*s&0xdf) == 'F' )) s++; 375 if (s && ((*s&0xdf) == 'F' )) s++;
376 return s; 376 return s;
377} 377}
378 378
379HlAnyChar::HlAnyChar(int attribute, int context, const QChar* charList, uint len) 379HlAnyChar::HlAnyChar(int attribute, int context, const QChar* charList, uint len)
380 : HlItem(attribute, context) { 380 : HlItem(attribute, context) {
381 _charList=charList; 381 _charList=charList;
382 _charListLen=len; 382 _charListLen=len;
383} 383}
384 384
385const QChar *HlAnyChar::checkHgl(const QChar *s, int len, bool) 385const QChar *HlAnyChar::checkHgl(const QChar *s, int len, bool)
386{ 386{
387 if (ustrchr(_charList, _charListLen, *s)) return s +1; 387 if (ustrchr(_charList, _charListLen, *s)) return s +1;
388 return 0L; 388 return 0L;
389} 389}
390 390
391HlRegExpr::HlRegExpr(int attribute, int context,QString regexp) 391HlRegExpr::HlRegExpr(int attribute, int context,QString regexp)
392 : HlItem(attribute, context) { 392 : HlItem(attribute, context), Expr(0) {
393 393
394 handlesLinestart=regexp.startsWith("^"); 394 handlesLinestart=regexp.startsWith("^");
395 if(!handlesLinestart) regexp.prepend("^"); 395 if(!handlesLinestart) regexp.prepend("^");
396 Expr=new QRegExp3(regexp); 396 Expr=new QRegExp3(regexp);
397} 397}
398 398
399HlRegExpr::~HlRegExpr()
400{
401 delete Expr;
402}
403
399const QChar *HlRegExpr::checkHgl(const QChar *s, int len, bool lineStart) 404const QChar *HlRegExpr::checkHgl(const QChar *s, int len, bool lineStart)
400{ 405{
401 if ((!lineStart) && handlesLinestart) return 0; 406 if ((!lineStart) && handlesLinestart) return 0;
402 407
403 QString line(s,len); 408 QString line(s,len);
404 int pos = Expr->search( line, 0 ); 409 int pos = Expr->search( line, 0 );
405 if (pos==-1) return 0L; 410 if (pos==-1) return 0L;
406 else 411 else
407 return (s+Expr->matchedLength()); 412 return (s+Expr->matchedLength());
408}; 413};
409 414
410 415
411HlLineContinue::HlLineContinue(int attribute, int context) 416HlLineContinue::HlLineContinue(int attribute, int context)
412 : HlItem(attribute,context) { 417 : HlItem(attribute,context) {
413} 418}
414 419
415const QChar *HlLineContinue::checkHgl(const QChar *s, int len, bool) { 420const QChar *HlLineContinue::checkHgl(const QChar *s, int len, bool) {
416 421
417 if ((s[0].latin1() == '\\') && (len == 1)) 422 if ((s[0].latin1() == '\\') && (len == 1))
418 { 423 {
419 return s + 1; 424 return s + 1;
420 } 425 }
421 return 0L; 426 return 0L;
422} 427}
423 428
424 429
425HlCStringChar::HlCStringChar(int attribute, int context) 430HlCStringChar::HlCStringChar(int attribute, int context)
426 : HlItem(attribute,context) { 431 : HlItem(attribute,context) {
427} 432}
428 433
429//checks for hex and oct (for example \x1b or \033) 434//checks for hex and oct (for example \x1b or \033)
430const QChar *checkCharHexOct(const QChar *str) { 435const QChar *checkCharHexOct(const QChar *str) {
431 const QChar *s; 436 const QChar *s;
432 s=str; 437 s=str;
433 int n; 438 int n;
434 if (*s == 'x') { 439 if (*s == 'x') {
435 n = 0; 440 n = 0;
436 do { 441 do {
437 s++; 442 s++;
438 n *= 16; 443 n *= 16;
439 if (s->isDigit()) n += *s - '0'; 444 if (s->isDigit()) n += *s - '0';
440 else if ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') n += (*s&0xdf) - 'A' + 10; 445 else if ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') n += (*s&0xdf) - 'A' + 10;
441// else if (*s >= 'a' && *s <= 'f') n += *s - 'a' + 10; 446// else if (*s >= 'a' && *s <= 'f') n += *s - 'a' + 10;
442 else break; 447 else break;
443 if (n >= 256) return 0L; 448 if (n >= 256) return 0L;
444 } while (true); 449 } while (true);
445 if (s - str == 1) return 0L; 450 if (s - str == 1) return 0L;
446 } else { 451 } else {
447 if (!(*s >= '0' && *s <= '7')) return 0L; 452 if (!(*s >= '0' && *s <= '7')) return 0L;
448 n = *s - '0'; 453 n = *s - '0';
449 do { 454 do {
450 s++; 455 s++;
451 n *= 8; 456 n *= 8;
452 if (*s >= '0' && *s <= '7') n += *s - '0'; else break; 457 if (*s >= '0' && *s <= '7') n += *s - '0'; else break;
453 if (n >= 256) return s; 458 if (n >= 256) return s;
454 } while (s - str < 3); 459 } while (s - str < 3);
455 } 460 }
456 return s; 461 return s;
457} 462}
458// checks for C escaped chars \n and escaped hex/octal chars 463// checks for C escaped chars \n and escaped hex/octal chars
459const QChar *checkEscapedChar(const QChar *s, int len) { 464const QChar *checkEscapedChar(const QChar *s, int len) {
460 int i; 465 int i;
461 if (s[0] == '\\' && (len > 1) ) { 466 if (s[0] == '\\' && (len > 1) ) {
462 s++; 467 s++;
463 switch(*s){ 468 switch(*s){
464 case 'a': // checks for control chars 469 case 'a': // checks for control chars
465 case 'b': // we want to fall through 470 case 'b': // we want to fall through
466 case 'e': 471 case 'e':
467 case 'f': 472 case 'f':
468 473
469 case 'n': 474 case 'n':
470 case 'r': 475 case 'r':
471 case 't': 476 case 't':
472 case 'v': 477 case 'v':
473 case '\'': 478 case '\'':
474 case '\"': 479 case '\"':
475 case '?' : // added ? ANSI C classifies this as an escaped char 480 case '?' : // added ? ANSI C classifies this as an escaped char
476 case '\\': s++; 481 case '\\': s++;
477 break; 482 break;
478 case 'x': // if it's like \xff 483 case 'x': // if it's like \xff
479 s++; // eat the x 484 s++; // eat the x
480 // these for loops can probably be 485 // these for loops can probably be
481 // replaced with something else but 486 // replaced with something else but
482 // for right now they work 487 // for right now they work
483 // check for hexdigits 488 // check for hexdigits
484 for(i=0;i<2 &&(*s >= '0' && *s <= '9' || (*s&0xdf) >= 'A' && (*s&0xdf) <= 'F');i++,s++); 489 for(i=0;i<2 &&(*s >= '0' && *s <= '9' || (*s&0xdf) >= 'A' && (*s&0xdf) <= 'F');i++,s++);
485 if(i==0) return 0L; // takes care of case '\x' 490 if(i==0) return 0L; // takes care of case '\x'
486 break; 491 break;
487 492
488 case '0': case '1': case '2': case '3' : 493 case '0': case '1': case '2': case '3' :
489 case '4': case '5': case '6': case '7' : 494 case '4': case '5': case '6': case '7' :
490 for(i=0;i < 3 &&(*s >='0'&& *s<='7');i++,s++); 495 for(i=0;i < 3 &&(*s >='0'&& *s<='7');i++,s++);
491 break; 496 break;
492 default: return 0L; 497 default: return 0L;
493 } 498 }
494 return s; 499 return s;
495 } 500 }
496 return 0L; 501 return 0L;
497} 502}
498 503
499const QChar *HlCStringChar::checkHgl(const QChar *str, int len, bool) { 504const QChar *HlCStringChar::checkHgl(const QChar *str, int len, bool) {
500 return checkEscapedChar(str, len); 505 return checkEscapedChar(str, len);
501} 506}
502 507
503 508
504HlCChar::HlCChar(int attribute, int context) 509HlCChar::HlCChar(int attribute, int context)
505 : HlItem(attribute,context) { 510 : HlItem(attribute,context) {
506} 511}
507 512
508const QChar *HlCChar::checkHgl(const QChar *str, int len, bool) { 513const QChar *HlCChar::checkHgl(const QChar *str, int len, bool) {
509 const QChar *s; 514 const QChar *s;
510 515
511 if ((len > 1) && (str[0] == '\'') && (str[1] != '\'')) 516 if ((len > 1) && (str[0] == '\'') && (str[1] != '\''))
512 { 517 {
513 s = checkEscapedChar(&str[1], len); //try to match escaped char 518 s = checkEscapedChar(&str[1], len); //try to match escaped char
514 if (!s) s = &str[2]; //match single non-escaped char 519 if (!s) s = &str[2]; //match single non-escaped char
515 if (*s == '\'') return s + 1; 520 if (*s == '\'') return s + 1;
516 } 521 }
517 return 0L; 522 return 0L;
518} 523}
519 524
520 525
521//-------- 526//--------
522ItemStyle::ItemStyle() : selCol(Qt::white), bold(false), italic(false) { 527ItemStyle::ItemStyle() : selCol(Qt::white), bold(false), italic(false) {
523} 528}
524 529
525ItemStyle::ItemStyle(const QColor &col, const QColor &selCol, 530ItemStyle::ItemStyle(const QColor &col, const QColor &selCol,
526 bool bold, bool italic) 531 bool bold, bool italic)
527 : col(col), selCol(selCol), bold(bold), italic(italic) { 532 : col(col), selCol(selCol), bold(bold), italic(italic) {
528} 533}
529 534
530ItemData::ItemData(const QString name, int defStyleNum) 535ItemData::ItemData(const QString name, int defStyleNum)
531 : name(name), defStyleNum(defStyleNum), defStyle(true) { 536 : name(name), defStyleNum(defStyleNum), defStyle(true) {
532} 537}
533 538
534ItemData::ItemData(const QString name, int defStyleNum, 539ItemData::ItemData(const QString name, int defStyleNum,
535 const QColor &col, const QColor &selCol, bool bold, bool italic) 540 const QColor &col, const QColor &selCol, bool bold, bool italic)
536 : ItemStyle(col,selCol,bold,italic), name(name), defStyleNum(defStyleNum), 541 : ItemStyle(col,selCol,bold,italic), name(name), defStyleNum(defStyleNum),
537 defStyle(false) { 542 defStyle(false) {
538} 543}
539 544
540HlData::HlData(const QString &wildcards, const QString &mimetypes, const QString &identifier) 545HlData::HlData(const QString &wildcards, const QString &mimetypes, const QString &identifier)
541 : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier) { 546 : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier) {
542 547
543//JW itemDataList.setAutoDelete(true); 548//JW itemDataList.setAutoDelete(true);
544} 549}
545 550
546HlContext::HlContext(int attribute, int lineEndContext, int _lineBeginContext) 551HlContext::HlContext(int attribute, int lineEndContext, int _lineBeginContext)
547 : attr(attribute), ctx(lineEndContext),lineBeginContext(_lineBeginContext) { 552 : attr(attribute), ctx(lineEndContext),lineBeginContext(_lineBeginContext) {
548 items.setAutoDelete(true); 553 items.setAutoDelete(true);
549} 554}
550 555
551Hl2CharDetect::Hl2CharDetect(int attribute, int context, const QChar *s) 556Hl2CharDetect::Hl2CharDetect(int attribute, int context, const QChar *s)
552 : HlItem(attribute,context) { 557 : HlItem(attribute,context) {
553 sChar1 = s[0]; 558 sChar1 = s[0];
554 sChar2 = s[1]; 559 sChar2 = s[1];
555} 560}
556 561
557Highlight::Highlight(syntaxModeListItem *def) : refCount(0) 562Highlight::Highlight(syntaxModeListItem *def) : refCount(0)
558{ 563{
559 noHl = false; 564 noHl = false;
560 565
561 if (def == 0) 566 if (def == 0)
562 { 567 {
563 noHl = true; 568 noHl = true;
564 iName = I18N_NOOP("Normal"); 569 iName = I18N_NOOP("Normal");
565 iSection = ""; 570 iSection = "";
566 } 571 }
567 else 572 else
568 { 573 {
569 iName = def->name; 574 iName = def->name;
570 iSection = def->section; 575 iSection = def->section;
571 iWildcards = def->extension; 576 iWildcards = def->extension;
572 iMimetypes = def->mimetype; 577 iMimetypes = def->mimetype;
573 identifier = def->identifier; 578 identifier = def->identifier;
574 } 579 }
575 deliminator = stdDeliminator; 580 deliminator = stdDeliminator;
576 deliminatorChars = deliminator.unicode(); 581 deliminatorChars = deliminator.unicode();
577 deliminatorLen = deliminator.length(); 582 deliminatorLen = deliminator.length();
578} 583}
579 584
580Highlight::~Highlight() 585Highlight::~Highlight()
581{ 586{
582} 587}
583 588
584int Highlight::doHighlight(int ctxNum, TextLine *textLine) 589int Highlight::doHighlight(int ctxNum, TextLine *textLine)
585{ 590{
586 if (noHl) 591 if (noHl)
587 { 592 {
588 textLine->setAttribs(0,0,textLine->length()); 593 textLine->setAttribs(0,0,textLine->length());
589 textLine->setAttr(0); 594 textLine->setAttr(0);
590 return 0; 595 return 0;
591 } 596 }
592 597
593 HlContext *context; 598 HlContext *context;
594 const QChar *s2; 599 const QChar *s2;
595 HlItem *item; 600 HlItem *item;
596 601
597 context = contextList[ctxNum]; 602 context = contextList[ctxNum];
598 if (context->lineBeginContext!=-1) 603 if (context->lineBeginContext!=-1)
599 { 604 {
600 ctxNum=context->lineBeginContext; 605 ctxNum=context->lineBeginContext;
601 context=contextList[ctxNum]; 606 context=contextList[ctxNum];
602 } 607 }
603 608
604 QChar lastChar = ' '; 609 QChar lastChar = ' ';
605 610
606 // first char 611 // first char
607 const QChar *str = textLine->getText(); 612 const QChar *str = textLine->getText();
608 613
609 // non space char - index of that char 614 // non space char - index of that char
610 const QChar *s1 = textLine->firstNonSpace(); 615 const QChar *s1 = textLine->firstNonSpace();
611 uint z = textLine->firstChar(); 616 uint z = textLine->firstChar();
612 617
613 // length of textline 618 // length of textline
614 uint len = textLine->length(); 619 uint len = textLine->length();
615 620
616 bool found = false; 621 bool found = false;
617 while (z < len) 622 while (z < len)
618 { 623 {
619 found = false; 624 found = false;
620 625
621 for (item = context->items.first(); item != 0L; item = context->items.next()) 626 for (item = context->items.first(); item != 0L; item = context->items.next())
622 { 627 {
623 if (item->startEnable(lastChar)) 628 if (item->startEnable(lastChar))
624 { 629 {
625 s2 = item->checkHgl(s1, len-z, z==0); 630 s2 = item->checkHgl(s1, len-z, z==0);
626 if (s2 > s1) 631 if (s2 > s1)
627 { 632 {
628 odebug << "An item has been detected" << oendl; 633 odebug << "An item has been detected" << oendl;
629 textLine->setAttribs(item->attr,s1 - str,s2 - str); 634 textLine->setAttribs(item->attr,s1 - str,s2 - str);
630 ctxNum = item->ctx; 635 ctxNum = item->ctx;
631 context = contextList[ctxNum]; 636 context = contextList[ctxNum];
632 z = z + s2 - s1 - 1; 637 z = z + s2 - s1 - 1;
633 s1 = s2 - 1; 638 s1 = s2 - 1;
634 found = true; 639 found = true;
635 break; 640 break;
636 } 641 }
637 } 642 }
638 } 643 }
639 644
640 // nothing found: set attribute of one char 645 // nothing found: set attribute of one char
641 if (!found) 646 if (!found)
642 textLine->setAttribs(context->attr,s1 - str,s1 - str + 1); 647 textLine->setAttribs(context->attr,s1 - str,s1 - str + 1);
643 648
644 lastChar = *s1; 649 lastChar = *s1;
645 s1++; 650 s1++;
646 z++; 651 z++;
647 } 652 }
648 653
649 //set "end of line"-properties 654 //set "end of line"-properties
650 textLine->setAttr(context->attr); 655 textLine->setAttr(context->attr);
651 656
652 //return new context 657 //return new context
653 return context->ctx; 658 return context->ctx;
654} 659}
655 660
656KateConfig *Highlight::getKateConfig() { 661KateConfig *Highlight::getKateConfig() {
657 KateConfig *config; 662 KateConfig *config;
658 config=KGlobal::config(); 663 config=KGlobal::config();
659 config->setGroup(iName + QString(" Highlight")); 664 config->setGroup(iName + QString(" Highlight"));
660 return config; 665 return config;
661} 666}
662 667
663QString Highlight::getWildcards() { 668QString Highlight::getWildcards() {
664 KateConfig *config; 669 KateConfig *config;
665 670
666 config = getKateConfig(); 671 config = getKateConfig();
667 672
668 //if wildcards not yet in config, then use iWildCards as default 673 //if wildcards not yet in config, then use iWildCards as default
669 return config->readEntry("Wildcards", iWildcards); 674 return config->readEntry("Wildcards", iWildcards);
670} 675}
671 676
672 677
673QString Highlight::getMimetypes() { 678QString Highlight::getMimetypes() {
674 KateConfig *config; 679 KateConfig *config;
675 680
676 config = getKateConfig(); 681 config = getKateConfig();
677 682
678 return config->readEntry("Mimetypes", iMimetypes); 683 return config->readEntry("Mimetypes", iMimetypes);
679} 684}
680 685
681 686
682HlData *Highlight::getData() { 687HlData *Highlight::getData() {
683 KateConfig *config; 688 KateConfig *config;
684 HlData *hlData; 689 HlData *hlData;
685 690
686 config = getKateConfig(); 691 config = getKateConfig();
687 692
688// iWildcards = config->readEntry("Wildcards"); 693// iWildcards = config->readEntry("Wildcards");
689// iMimetypes = config->readEntry("Mimetypes"); 694// iMimetypes = config->readEntry("Mimetypes");
690// hlData = new HlData(iWildcards,iMimetypes); 695// hlData = new HlData(iWildcards,iMimetypes);
691 hlData = new HlData( 696 hlData = new HlData(
692 config->readEntry("Wildcards", iWildcards), 697 config->readEntry("Wildcards", iWildcards),
693 config->readEntry("Mimetypes", iMimetypes), 698 config->readEntry("Mimetypes", iMimetypes),
694 config->readEntry("Identifier", identifier)); 699 config->readEntry("Identifier", identifier));
695 getItemDataList(hlData->itemDataList, config); 700 getItemDataList(hlData->itemDataList, config);
696 return hlData; 701 return hlData;
697} 702}
698 703
699void Highlight::setData(HlData *hlData) { 704void Highlight::setData(HlData *hlData) {
700 KateConfig *config; 705 KateConfig *config;
701 706
702 config = getKateConfig(); 707 config = getKateConfig();
703 708
704// iWildcards = hlData->wildcards; 709// iWildcards = hlData->wildcards;
705// iMimetypes = hlData->mimetypes; 710// iMimetypes = hlData->mimetypes;
706 711
707 config->writeEntry("Wildcards",hlData->wildcards); 712 config->writeEntry("Wildcards",hlData->wildcards);
708 config->writeEntry("Mimetypes",hlData->mimetypes); 713 config->writeEntry("Mimetypes",hlData->mimetypes);
709 714
710 setItemDataList(hlData->itemDataList,config); 715 setItemDataList(hlData->itemDataList,config);
711} 716}
712 717
713void Highlight::getItemDataList(ItemDataList &list) { 718void Highlight::getItemDataList(ItemDataList &list) {
714 KateConfig *config; 719 KateConfig *config;
715 720
716 config = getKateConfig(); 721 config = getKateConfig();
717 getItemDataList(list, config); 722 getItemDataList(list, config);
718} 723}
719 724
720void Highlight::getItemDataList(ItemDataList &list, KateConfig *config) { 725void Highlight::getItemDataList(ItemDataList &list, KateConfig *config) {
721 ItemData *p; 726 ItemData *p;
722 QString s; 727 QString s;
723 QRgb col, selCol; 728 QRgb col, selCol;
724 729
725 list.clear(); 730 list.clear();
726//JW list.setAutoDelete(true); 731//JW list.setAutoDelete(true);
727 createItemData(list); 732 createItemData(list);
728 733
729 for (p = list.first(); p != 0L; p = list.next()) { 734 for (p = list.first(); p != 0L; p = list.next()) {
730 s = config->readEntry(p->name); 735 s = config->readEntry(p->name);
731 if (!s.isEmpty()) { 736 if (!s.isEmpty()) {
732 sscanf(s.latin1(),"%d,%X,%X,%d,%d", &p->defStyle,&col,&selCol,&p->bold,&p->italic); 737 sscanf(s.latin1(),"%d,%X,%X,%d,%d", &p->defStyle,&col,&selCol,&p->bold,&p->italic);
733 p->col.setRgb(col); 738 p->col.setRgb(col);
734 p->selCol.setRgb(selCol); 739 p->selCol.setRgb(selCol);
735 } 740 }
736 } 741 }
737} 742}
738 743
739/******************************************************************************************* 744/*******************************************************************************************
740 Highlight - setItemDataList 745 Highlight - setItemDataList
741 saves the ItemData / attribute / style definitions to the apps configfile. 746 saves the ItemData / attribute / style definitions to the apps configfile.
742 Especially needed for user overridden values. 747 Especially needed for user overridden values.
743 748
744 * input: ItemDataList &list :reference to the list, whose 749 * input: ItemDataList &list :reference to the list, whose
745 * items should be saved 750 * items should be saved
746 * KateConfig *config :Pointer KDE configuration 751 * KateConfig *config :Pointer KDE configuration
747 * class, which should be used 752 * class, which should be used
748 * as storage 753 * as storage
749 ************* 754 *************
750 * output: none 755 * output: none
751 ************* 756 *************
752 * return value: none 757 * return value: none
753*******************************************************************************************/ 758*******************************************************************************************/
754 759
755void Highlight::setItemDataList(ItemDataList &list, KateConfig *config) { 760void Highlight::setItemDataList(ItemDataList &list, KateConfig *config) {
756 ItemData *p; 761 ItemData *p;
757 QString s; 762 QString s;
758 763
759 for (p = list.first(); p != 0L; p = list.next()) { 764 for (p = list.first(); p != 0L; p = list.next()) {
760 s.sprintf("%d,%X,%X,%d,%d", 765 s.sprintf("%d,%X,%X,%d,%d",
761 p->defStyle,p->col.rgb(),p->selCol.rgb(),p->bold,p->italic); 766 p->defStyle,p->col.rgb(),p->selCol.rgb(),p->bold,p->italic);
762 config->writeEntry(p->name,s); 767 config->writeEntry(p->name,s);
763 } 768 }
764} 769}
765 770
766 771
767/******************************************************************************************* 772/*******************************************************************************************
768 Highlight - use 773 Highlight - use
769 Increase the usage count and trigger initialization if needed 774 Increase the usage count and trigger initialization if needed
770 775
771 * input: none 776 * input: none
772 ************* 777 *************
773 * output: none 778 * output: none
774 ************* 779 *************
775 * return value: none 780 * return value: none
776*******************************************************************************************/ 781*******************************************************************************************/
777 782
778void Highlight::use() 783void Highlight::use()
779{ 784{
780 if (refCount == 0) init(); 785 if (refCount == 0) init();
781 refCount++; 786 refCount++;
782} 787}
783 788
784 789
785/******************************************************************************************* 790/*******************************************************************************************
786 Highlight - release 791 Highlight - release
787 Decrease the usage count and trigger a cleanup if needed 792 Decrease the usage count and trigger a cleanup if needed
788 793
789 * input: none 794 * input: none
790 ************* 795 *************
791 * output: none 796 * output: none
792 ************* 797 *************
793 * return value: none 798 * return value: none
794*******************************************************************************************/ 799*******************************************************************************************/
795 800
796void Highlight::release() 801void Highlight::release()
797{ 802{
798 refCount--; 803 refCount--;
799 if (refCount == 0) done(); 804 if (refCount == 0) done();
800} 805}
801 806
802/******************************************************************************************* 807/*******************************************************************************************
803 Highlight - init 808 Highlight - init
804 If it's the first time a particular highlighting is used create the needed contextlist 809 If it's the first time a particular highlighting is used create the needed contextlist
805 810
806 * input: none 811 * input: none
807 ************* 812 *************
808 * output: none 813 * output: none
809 ************* 814 *************
810 * return value: none 815 * return value: none
811*******************************************************************************************/ 816*******************************************************************************************/
812 817
813void Highlight::init() 818void Highlight::init()
814{ 819{
815 if (noHl) 820 if (noHl)
816 return; 821 return;
817 822
818 for (int z = 0; z < nContexts; z++) contextList[z] = 0L; 823 for (int z = 0; z < nContexts; z++) contextList[z] = 0L;
819 makeContextList(); 824 makeContextList();
820} 825}
821 826
822 827
823/******************************************************************************************* 828/*******************************************************************************************
824 Highlight - done 829 Highlight - done
825 If the there is no document using the highlighting style free the complete context 830 If the there is no document using the highlighting style free the complete context
826 structure. 831 structure.
827 832
828 * input: none 833 * input: none
829 ************* 834 *************
830 * output: none 835 * output: none
831 ************* 836 *************
832 * return value: none 837 * return value: none
833*******************************************************************************************/ 838*******************************************************************************************/
834 839
835void Highlight::done() 840void Highlight::done()
836{ 841{
837 if (noHl) 842 if (noHl)
838 return; 843 return;
839 844
840 for (int z = 0; z < nContexts; z++) delete contextList[z]; 845 for (int z = 0; z < nContexts; z++) delete contextList[z];
841} 846}
842 847
843 848
844/******************************************************************************************* 849/*******************************************************************************************
845 Highlight - createItemData 850 Highlight - createItemData
846 This function reads the itemData entries from the config file, which specifies the 851 This function reads the itemData entries from the config file, which specifies the
847 default attribute styles for matched items/contexts. 852 default attribute styles for matched items/contexts.
848 853
849 * input: none 854 * input: none
850 ************* 855 *************
851 * output: ItemDataList &list :A reference to the internal 856 * output: ItemDataList &list :A reference to the internal
852 list containing the parsed 857 list containing the parsed
853 default config 858 default config
854 ************* 859 *************
855 * return value: none 860 * return value: none
856*******************************************************************************************/ 861*******************************************************************************************/
857 862
858void Highlight::createItemData(ItemDataList &list) 863void Highlight::createItemData(ItemDataList &list)
859{ 864{
860 odebug << "Highlight::createItemData" << oendl; 865 odebug << "Highlight::createItemData" << oendl;
861 866
862 // If no highlighting is selected we need only one default. 867 // If no highlighting is selected we need only one default.
863 if (noHl) 868 if (noHl)
864 { 869 {
865 list.append(new ItemData(I18N_NOOP("Normal Text"), dsNormal)); 870 list.append(new ItemData(I18N_NOOP("Normal Text"), dsNormal));
866 return; 871 return;
867 } 872 }
868 873
869 QString color; 874 QString color;
870 QString selColor; 875 QString selColor;
871 QString bold; 876 QString bold;
872 QString italic; 877 QString italic;
873 878
874 // If the internal list isn't already available read the config file 879 // If the internal list isn't already available read the config file
875 if (internalIDList.count()==0) 880 if (internalIDList.count()==0)
876 { 881 {
877 //if all references to the list are destried the contents will also be deleted 882 //if all references to the list are destried the contents will also be deleted
878 internalIDList.setAutoDelete(true); 883 internalIDList.setAutoDelete(true);
879 syntaxContextData *data; 884 syntaxContextData *data;
880 885
881 odebug << "Trying to read itemData section" << oendl; 886 odebug << "Trying to read itemData section" << oendl;
882 887
883 //Tell the syntax document class which file we want to parse and which data group 888 //Tell the syntax document class which file we want to parse and which data group
884 HlManager::self()->syntax->setIdentifier(identifier); 889 HlManager::self()->syntax->setIdentifier(identifier);
885 data=HlManager::self()->syntax->getGroupInfo("highlighting","itemData"); 890 data=HlManager::self()->syntax->getGroupInfo("highlighting","itemData");
886 //begin with the real parsing 891 //begin with the real parsing
887 while (HlManager::self()->syntax->nextGroup(data)) 892 while (HlManager::self()->syntax->nextGroup(data))
888 { 893 {
889 odebug << "Setting up one itemData element" << oendl; 894 odebug << "Setting up one itemData element" << oendl;
890 // read all attributes 895 // read all attributes
891 color=HlManager::self()->syntax->groupData(data,QString("color")); 896 color=HlManager::self()->syntax->groupData(data,QString("color"));
892 selColor=HlManager::self()->syntax->groupData(data,QString("selColor")); 897 selColor=HlManager::self()->syntax->groupData(data,QString("selColor"));
893 bold=HlManager::self()->syntax->groupData(data,QString("bold")); 898 bold=HlManager::self()->syntax->groupData(data,QString("bold"));
894 italic=HlManager::self()->syntax->groupData(data,QString("italic")); 899 italic=HlManager::self()->syntax->groupData(data,QString("italic"));
895 //check if the user overrides something 900 //check if the user overrides something
896 if ( (!color.isEmpty()) && (!selColor.isEmpty()) && (!bold.isEmpty()) && (!italic.isEmpty())) 901 if ( (!color.isEmpty()) && (!selColor.isEmpty()) && (!bold.isEmpty()) && (!italic.isEmpty()))
897 { 902 {
898 //create a user defined style 903 //create a user defined style
899 internalIDList.append(new ItemData( 904 internalIDList.append(new ItemData(
900 HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(), 905 HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
901 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum"))), 906 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum"))),
902 QColor(color),QColor(selColor),(bold=="true") || (bold=="1"), (italic=="true") || (italic=="1") 907 QColor(color),QColor(selColor),(bold=="true") || (bold=="1"), (italic=="true") || (italic=="1")
903 )); 908 ));
904 } 909 }
905 else 910 else
906 { 911 {
907 //assign a default style 912 //assign a default style
908 internalIDList.append(new ItemData( 913 internalIDList.append(new ItemData(
909 HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(), 914 HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
910 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum"))))); 915 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum")))));
911 916
912 } 917 }
913 } 918 }
914 //clean up 919 //clean up
915 if (data) HlManager::self()->syntax->freeGroupInfo(data); 920 if (data) HlManager::self()->syntax->freeGroupInfo(data);
916 } 921 }
917 922
918 //set the ouput reference 923 //set the ouput reference
919 list=internalIDList; 924 list=internalIDList;
920} 925}
921 926
922 927
923/******************************************************************************************* 928/*******************************************************************************************
924 Highlight - lookupAttrName 929 Highlight - lookupAttrName
925 This function is a helper for makeContextList and createHlItem. It looks the given 930 This function is a helper for makeContextList and createHlItem. It looks the given
926 attribute name in the itemData list up and returns it's index 931 attribute name in the itemData list up and returns it's index
927 932
928 * input: QString &name :the attribute name to lookup 933 * input: QString &name :the attribute name to lookup
929 * ItemDataList &iDl :the list containing all 934 * ItemDataList &iDl :the list containing all
930 * available attributes 935 * available attributes
931 ************* 936 *************
932 * output: none 937 * output: none
933 ************* 938 *************
934 * return value: int :The index of the attribute 939 * return value: int :The index of the attribute
935 * or 0 940 * or 0
936*******************************************************************************************/ 941*******************************************************************************************/
937 942
938int Highlight::lookupAttrName(const QString& name, ItemDataList &iDl) 943int Highlight::lookupAttrName(const QString& name, ItemDataList &iDl)
939{ 944{
940 for (int i=0;i<iDl.count();i++) 945 for (int i=0;i<iDl.count();i++)
941 { 946 {
942 if (iDl.at(i)->name==name) return i; 947 if (iDl.at(i)->name==name) return i;
943 } 948 }
944 kdDebug(13010)<<"Couldn't resolve itemDataName"<<endl; 949 kdDebug(13010)<<"Couldn't resolve itemDataName"<<endl;
945 return 0; 950 return 0;
946} 951}
947 952
948 953
949/******************************************************************************************* 954/*******************************************************************************************
950 Highlight - createHlItem 955 Highlight - createHlItem
951 This function is a helper for makeContextList. It parses the xml file for 956 This function is a helper for makeContextList. It parses the xml file for
952 information, how single or multi line comments are marked 957 information, how single or multi line comments are marked
953 958
954 * input: syntaxContextData *data : Data about the item read from 959 * input: syntaxContextData *data : Data about the item read from
955 * the xml file 960 * the xml file
956 * ItemDataList &iDl : List of all available itemData 961 * ItemDataList &iDl : List of all available itemData
957 * entries. Needed for attribute 962 * entries. Needed for attribute
958 * name->index translation 963 * name->index translation
959 ************* 964 *************
960 * output: none 965 * output: none
961 ************* 966 *************
962 * return value: HlItem * : Pointer to the newly created item 967 * return value: HlItem * : Pointer to the newly created item
963 * object 968 * object
964*******************************************************************************************/ 969*******************************************************************************************/
965 970
966HlItem *Highlight::createHlItem(syntaxContextData *data, ItemDataList &iDl) 971HlItem *Highlight::createHlItem(syntaxContextData *data, ItemDataList &iDl)
967{ 972{
968 // No highlighting -> exit 973 // No highlighting -> exit
969 if (noHl) 974 if (noHl)
970 return 0; 975 return 0;
971 976
972 // get the (tagname) itemd type 977 // get the (tagname) itemd type
973 QString dataname=HlManager::self()->syntax->groupItemData(data,QString("")); 978 QString dataname=HlManager::self()->syntax->groupItemData(data,QString(""));
974 979
975 // BEGIN - Translation of the attribute parameter 980 // BEGIN - Translation of the attribute parameter
976 QString tmpAttr=HlManager::self()->syntax->groupItemData(data,QString("attribute")).simplifyWhiteSpace(); 981 QString tmpAttr=HlManager::self()->syntax->groupItemData(data,QString("attribute")).simplifyWhiteSpace();
977 int attr; 982 int attr;
978 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr) 983 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
979 attr=tmpAttr.toInt(); 984 attr=tmpAttr.toInt();
980 else 985 else
981 attr=lookupAttrName(tmpAttr,iDl); 986 attr=lookupAttrName(tmpAttr,iDl);
982 // END - Translation of the attribute parameter 987 // END - Translation of the attribute parameter
983 988
984 // Info about context switch 989 // Info about context switch
985 int context=((HlManager::self()->syntax->groupItemData(data,QString("context"))).toInt()); 990 int context=((HlManager::self()->syntax->groupItemData(data,QString("context"))).toInt());
986 991
987 // Get the char parameter (eg DetectChar) 992 // Get the char parameter (eg DetectChar)
988 char chr; 993 char chr;
989 if (! HlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty()) 994 if (! HlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty())
990 chr= (HlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0]; 995 chr= (HlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0];
991 else 996 else
992 chr=0; 997 chr=0;
993 998
994 // Get the String parameter (eg. StringDetect) 999 // Get the String parameter (eg. StringDetect)
995 QString stringdata=HlManager::self()->syntax->groupItemData(data,QString("String")); 1000 QString stringdata=HlManager::self()->syntax->groupItemData(data,QString("String"));
996 1001
997 // Get a second char parameter (char1) (eg Detect2Chars) 1002 // Get a second char parameter (char1) (eg Detect2Chars)
998 char chr1; 1003 char chr1;
999 if (! HlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty()) 1004 if (! HlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty())
1000 chr1= (HlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0]; 1005 chr1= (HlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0];
1001 else 1006 else
1002 chr1=0; 1007 chr1=0;
1003 1008
1004 // Will be removed eventuall. Atm used for StringDetect 1009 // Will be removed eventuall. Atm used for StringDetect
1005 bool insensitive=(HlManager::self()->syntax->groupItemData(data,QString("insensitive"))==QString("TRUE")); 1010 bool insensitive=(HlManager::self()->syntax->groupItemData(data,QString("insensitive"))==QString("TRUE"));
1006 1011
1007 1012
1008 //Create the item corresponding to it's type and set it's parameters 1013 //Create the item corresponding to it's type and set it's parameters
1009 if (dataname=="keyword") 1014 if (dataname=="keyword")
1010 { 1015 {
1011 HlKeyword *keyword=new HlKeyword(attr,context,casesensitive, 1016 HlKeyword *keyword=new HlKeyword(attr,context,casesensitive,
1012 deliminatorChars, deliminatorLen); 1017 deliminatorChars, deliminatorLen);
1013 1018
1014 //Get the entries for the keyword lookup list 1019 //Get the entries for the keyword lookup list
1015 keyword->addList(HlManager::self()->syntax->finddata("highlighting",stringdata)); 1020 keyword->addList(HlManager::self()->syntax->finddata("highlighting",stringdata));
1016 return keyword; 1021 return keyword;
1017 } else 1022 } else
1018 if (dataname=="Float") return (new HlFloat(attr,context)); else 1023 if (dataname=="Float") return (new HlFloat(attr,context)); else
1019 if (dataname=="Int") return(new HlInt(attr,context)); else 1024 if (dataname=="Int") return(new HlInt(attr,context)); else
1020 if (dataname=="DetectChar") return(new HlCharDetect(attr,context,chr)); else 1025 if (dataname=="DetectChar") return(new HlCharDetect(attr,context,chr)); else
1021 if (dataname=="Detect2Chars") return(new Hl2CharDetect(attr,context,chr,chr1)); else 1026 if (dataname=="Detect2Chars") return(new Hl2CharDetect(attr,context,chr,chr1)); else
1022 if (dataname=="RangeDetect") return(new HlRangeDetect(attr,context, chr, chr1)); else 1027 if (dataname=="RangeDetect") return(new HlRangeDetect(attr,context, chr, chr1)); else
1023 if (dataname=="LineContinue") return(new HlLineContinue(attr,context)); else 1028 if (dataname=="LineContinue") return(new HlLineContinue(attr,context)); else
1024 if (dataname=="StringDetect") return(new HlStringDetect(attr,context,stringdata,insensitive)); else 1029 if (dataname=="StringDetect") return(new HlStringDetect(attr,context,stringdata,insensitive)); else
1025 if (dataname=="AnyChar") return(new HlAnyChar(attr,context,stringdata.unicode(), stringdata.length())); else 1030 if (dataname=="AnyChar") return(new HlAnyChar(attr,context,stringdata.unicode(), stringdata.length())); else
1026 if (dataname=="RegExpr") return(new HlRegExpr(attr,context,stringdata)); else 1031 if (dataname=="RegExpr") return(new HlRegExpr(attr,context,stringdata)); else
1027 if(dataname=="HlCChar") return ( new HlCChar(attr,context));else 1032 if(dataname=="HlCChar") return ( new HlCChar(attr,context));else
1028 if(dataname=="HlCHex") return (new HlCHex(attr,context));else 1033 if(dataname=="HlCHex") return (new HlCHex(attr,context));else
1029 if(dataname=="HlCOct") return (new HlCOct(attr,context)); else 1034 if(dataname=="HlCOct") return (new HlCOct(attr,context)); else
1030 if(dataname=="HlCStringChar") return (new HlCStringChar(attr,context)); else 1035 if(dataname=="HlCStringChar") return (new HlCStringChar(attr,context)); else
1031 1036
1032 { 1037 {
1033 // oops, unknown type. Perhaps a spelling error in the xml file 1038 // oops, unknown type. Perhaps a spelling error in the xml file
1034 return 0; 1039 return 0;
1035 } 1040 }
1036 1041
1037 1042
1038} 1043}
1039 1044
1040 1045
1041/******************************************************************************************* 1046/*******************************************************************************************
1042 Highlight - isInWord 1047 Highlight - isInWord
1043 1048
1044 * input: Qchar c Character to investigate 1049 * input: Qchar c Character to investigate
1045 ************* 1050 *************
1046 * output: none 1051 * output: none
1047 ************* 1052 *************
1048 * return value: returns true, if c is no deliminator 1053 * return value: returns true, if c is no deliminator
1049*******************************************************************************************/ 1054*******************************************************************************************/
1050 1055
1051bool Highlight::isInWord(QChar c) 1056bool Highlight::isInWord(QChar c)
1052{ 1057{
1053 return !ustrchr(deliminatorChars, deliminatorLen, c); 1058 return !ustrchr(deliminatorChars, deliminatorLen, c);
1054} 1059}
1055 1060
1056 1061
1057 1062
1058/******************************************************************************************* 1063/*******************************************************************************************
1059 Highlight - readCommentConfig 1064 Highlight - readCommentConfig
1060 This function is a helper for makeContextList. It parses the xml file for 1065 This function is a helper for makeContextList. It parses the xml file for
1061 information, how single or multi line comments are marked 1066 information, how single or multi line comments are marked
1062 1067
1063 * input: none 1068 * input: none
1064 ************* 1069 *************
1065 * output: none 1070 * output: none
1066 ************* 1071 *************
1067 * return value: none 1072 * return value: none
1068*******************************************************************************************/ 1073*******************************************************************************************/
1069 1074
1070void Highlight::readCommentConfig() 1075void Highlight::readCommentConfig()
1071{ 1076{
1072 1077
1073 cslStart = ""; 1078 cslStart = "";
1074 HlManager::self()->syntax->setIdentifier(identifier); 1079 HlManager::self()->syntax->setIdentifier(identifier);
1075 1080
1076 syntaxContextData *data=HlManager::self()->syntax->getGroupInfo("general","comment"); 1081 syntaxContextData *data=HlManager::self()->syntax->getGroupInfo("general","comment");
1077 if (data) 1082 if (data)
1078 { 1083 {
1079// kdDebug(13010)<<"COMMENT DATA FOUND"<<endl; 1084// kdDebug(13010)<<"COMMENT DATA FOUND"<<endl;
1080 while (HlManager::self()->syntax->nextGroup(data)) 1085 while (HlManager::self()->syntax->nextGroup(data))
1081 { 1086 {
1082 1087
1083 if (HlManager::self()->syntax->groupData(data,"name")=="singleLine") 1088 if (HlManager::self()->syntax->groupData(data,"name")=="singleLine")
1084 cslStart=HlManager::self()->syntax->groupData(data,"start"); 1089 cslStart=HlManager::self()->syntax->groupData(data,"start");
1085 if (HlManager::self()->syntax->groupData(data,"name")=="multiLine") 1090 if (HlManager::self()->syntax->groupData(data,"name")=="multiLine")
1086 { 1091 {
1087 cmlStart=HlManager::self()->syntax->groupData(data,"start"); 1092 cmlStart=HlManager::self()->syntax->groupData(data,"start");
1088 cmlEnd=HlManager::self()->syntax->groupData(data,"end"); 1093 cmlEnd=HlManager::self()->syntax->groupData(data,"end");
1089 } 1094 }
1090 } 1095 }
1091 HlManager::self()->syntax->freeGroupInfo(data); 1096 HlManager::self()->syntax->freeGroupInfo(data);
1092 } 1097 }
1093 1098
1094} 1099}
1095 1100
1096/******************************************************************************************* 1101/*******************************************************************************************
1097 Highlight - readGlobalKeyWordConfig 1102 Highlight - readGlobalKeyWordConfig
1098 This function is a helper for makeContextList. It parses the xml file for 1103 This function is a helper for makeContextList. It parses the xml file for
1099 information, if keywords should be treated case(in)sensitive and creates the keyword 1104 information, if keywords should be treated case(in)sensitive and creates the keyword
1100 delimiter list. Which is the default list, without any given weak deliminiators 1105 delimiter list. Which is the default list, without any given weak deliminiators
1101 1106
1102 * input: none 1107 * input: none
1103 ************* 1108 *************
1104 * output: none 1109 * output: none
1105 ************* 1110 *************
1106 * return value: none 1111 * return value: none
1107*******************************************************************************************/ 1112*******************************************************************************************/
1108 1113
1109 1114
1110void Highlight::readGlobalKeywordConfig() 1115void Highlight::readGlobalKeywordConfig()
1111{ 1116{
1112 // Tell the syntax document class which file we want to parse 1117 // Tell the syntax document class which file we want to parse
1113 HlManager::self()->syntax->setIdentifier(identifier); 1118 HlManager::self()->syntax->setIdentifier(identifier);
1114 1119
1115 // Get the keywords config entry 1120 // Get the keywords config entry
1116 syntaxContextData * data=HlManager::self()->syntax->getConfig("general","keywords"); 1121 syntaxContextData * data=HlManager::self()->syntax->getConfig("general","keywords");
1117 if (data) 1122 if (data)
1118 { 1123 {
1119 kdDebug(13010)<<"Found global keyword config"<<endl; 1124 kdDebug(13010)<<"Found global keyword config"<<endl;
1120 1125
1121 if (HlManager::self()->syntax->groupItemData(data,QString("casesensitive"))!="0") 1126 if (HlManager::self()->syntax->groupItemData(data,QString("casesensitive"))!="0")
1122 casesensitive=true; else {casesensitive=false; kdDebug(13010)<<"Turning on case insensitiveness"<<endl;} 1127 casesensitive=true; else {casesensitive=false; kdDebug(13010)<<"Turning on case insensitiveness"<<endl;}
1123 //get the weak deliminators 1128 //get the weak deliminators
1124 weakDeliminator=(!HlManager::self()->syntax->groupItemData(data,QString("weakDeliminator"))); 1129 weakDeliminator=(!HlManager::self()->syntax->groupItemData(data,QString("weakDeliminator")));
1125 1130
1126 // remove any weakDelimitars (if any) from the default list and store this list. 1131 // remove any weakDelimitars (if any) from the default list and store this list.
1127 int f; 1132 int f;
1128 for (int s=0; s < weakDeliminator.length(); s++) 1133 for (int s=0; s < weakDeliminator.length(); s++)
1129 { 1134 {
1130 f = 0; 1135 f = 0;
1131 f = deliminator.find (weakDeliminator[s]); 1136 f = deliminator.find (weakDeliminator[s]);
1132 1137
1133 if (f > -1) 1138 if (f > -1)
1134 deliminator.remove (f, 1); 1139 deliminator.remove (f, 1);
1135 } 1140 }
1136 1141
1137 deliminatorChars = deliminator.unicode(); 1142 deliminatorChars = deliminator.unicode();
1138 deliminatorLen = deliminator.length(); 1143 deliminatorLen = deliminator.length();
1139 1144
1140 HlManager::self()->syntax->freeGroupInfo(data); 1145 HlManager::self()->syntax->freeGroupInfo(data);
1141 } 1146 }
1142 else 1147 else
1143 { 1148 {
1144 //Default values 1149 //Default values
1145 casesensitive=true; 1150 casesensitive=true;
1146 weakDeliminator=QString(""); 1151 weakDeliminator=QString("");
1147 } 1152 }
1148 1153
1149} 1154}
1150 1155
1151/******************************************************************************************* 1156/*******************************************************************************************
1152 Highlight - makeContextList 1157 Highlight - makeContextList
1153 That's the most important initialization function for each highlighting. It's called 1158 That's the most important initialization function for each highlighting. It's called
1154 each time a document gets a highlighting style assigned. parses the xml file and 1159 each time a document gets a highlighting style assigned. parses the xml file and
1155 creates a corresponding internal structure 1160 creates a corresponding internal structure
1156 1161
1157 * input: none 1162 * input: none
1158 ************* 1163 *************
1159 * output: none 1164 * output: none
1160 ************* 1165 *************
1161 * return value: none 1166 * return value: none
1162*******************************************************************************************/ 1167*******************************************************************************************/
1163 1168
1164 1169
1165void Highlight::makeContextList() 1170void Highlight::makeContextList()
1166{ 1171{
1167 if (noHl) 1172 if (noHl)
1168 return; 1173 return;
1169 1174
1170 HlKeyword *keyword=0, *dataType=0; 1175 HlKeyword *keyword=0, *dataType=0;
1171 syntaxContextData *data, *datasub; 1176 syntaxContextData *data, *datasub;
1172 HlItem *c; 1177 HlItem *c;
1173 1178
1174 readCommentConfig(); 1179 readCommentConfig();
1175 readGlobalKeywordConfig(); 1180 readGlobalKeywordConfig();
1176 1181
1177 // Let the syntax document class know, which file we'd like to parse 1182 // Let the syntax document class know, which file we'd like to parse
1178 HlManager::self()->syntax->setIdentifier(identifier); 1183 HlManager::self()->syntax->setIdentifier(identifier);
1179 1184
1180 // This list is needed for the translation of the attribute parameter, if the itemData name is given instead of the index 1185 // This list is needed for the translation of the attribute parameter, if the itemData name is given instead of the index
1181 ItemDataList iDl; 1186 ItemDataList iDl;
1182 createItemData(iDl); 1187 createItemData(iDl);
1183 1188
1184 //start the real work 1189 //start the real work
1185 data=HlManager::self()->syntax->getGroupInfo("highlighting","context"); 1190 data=HlManager::self()->syntax->getGroupInfo("highlighting","context");
1186 int i=0; 1191 int i=0;
1187 if (data) 1192 if (data)
1188 { 1193 {
1189 while (HlManager::self()->syntax->nextGroup(data)) 1194 while (HlManager::self()->syntax->nextGroup(data))
1190 { 1195 {
1191 1196
1192 // BEGIN - Translation of the attribute parameter 1197 // BEGIN - Translation of the attribute parameter
1193 QString tmpAttr=HlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace(); 1198 QString tmpAttr=HlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace();
1194 int attr; 1199 int attr;
1195 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr) 1200 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
1196 attr=tmpAttr.toInt(); 1201 attr=tmpAttr.toInt();
1197 else 1202 else
1198 attr=lookupAttrName(tmpAttr,iDl); 1203 attr=lookupAttrName(tmpAttr,iDl);
1199 // END - Translation of the attribute parameter 1204 // END - Translation of the attribute parameter
1200 1205
1201 contextList[i]=new HlContext( 1206 contextList[i]=new HlContext(
1202 attr, 1207 attr,
1203 (HlManager::self()->syntax->groupData(data,QString("lineEndContext"))).toInt(), 1208 (HlManager::self()->syntax->groupData(data,QString("lineEndContext"))).toInt(),
1204 (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1: 1209 (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1:
1205 (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt()); 1210 (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt());
1206 1211
1207 1212
1208 //Let's create all items for the context 1213 //Let's create all items for the context
1209 while (HlManager::self()->syntax->nextItem(data)) 1214 while (HlManager::self()->syntax->nextItem(data))
1210 { 1215 {
1211// kdDebug(13010)<< "In make Contextlist: Item:"<<endl; 1216// kdDebug(13010)<< "In make Contextlist: Item:"<<endl;
1212 c=createHlItem(data,iDl); 1217 c=createHlItem(data,iDl);
1213 if (c) 1218 if (c)
1214 { 1219 {
1215 contextList[i]->items.append(c); 1220 contextList[i]->items.append(c);
1216 1221
1217 // Not supported completely atm and only one level. Subitems.(all have to be matched to at once) 1222 // Not supported completely atm and only one level. Subitems.(all have to be matched to at once)
1218 datasub=HlManager::self()->syntax->getSubItems(data); 1223 datasub=HlManager::self()->syntax->getSubItems(data);
1219 bool tmpbool; 1224 bool tmpbool;
1220 if (tmpbool=HlManager::self()->syntax->nextItem(datasub)) 1225 if (tmpbool=HlManager::self()->syntax->nextItem(datasub))
1221 { 1226 {
1222 c->subItems=new QList<HlItem>; 1227 c->subItems=new QList<HlItem>;
1223 for (;tmpbool;tmpbool=HlManager::self()->syntax->nextItem(datasub)) 1228 for (;tmpbool;tmpbool=HlManager::self()->syntax->nextItem(datasub))
1224 c->subItems->append(createHlItem(datasub,iDl)); 1229 c->subItems->append(createHlItem(datasub,iDl));
1225 } 1230 }
1226 HlManager::self()->syntax->freeGroupInfo(datasub); 1231 HlManager::self()->syntax->freeGroupInfo(datasub);
1227 // end of sublevel 1232 // end of sublevel
1228 } 1233 }
1229// kdDebug(13010)<<"Last line in loop"<<endl; 1234// kdDebug(13010)<<"Last line in loop"<<endl;
1230 } 1235 }
1231 i++; 1236 i++;
1232 } 1237 }
1233 } 1238 }
1234 1239
1235 HlManager::self()->syntax->freeGroupInfo(data); 1240 HlManager::self()->syntax->freeGroupInfo(data);
1236 1241
1237 1242
1238} 1243}
1239 1244
1240HlManager::HlManager() : QObject(0L) 1245HlManager::HlManager() : QObject(0L)
1241{ 1246{
1242 syntax = new SyntaxDocument(); 1247 syntax = new SyntaxDocument();
1243 SyntaxModeList modeList = syntax->modeList(); 1248 SyntaxModeList modeList = syntax->modeList();
1244 1249
1245 hlList.setAutoDelete(true); 1250 hlList.setAutoDelete(true);
1246 hlList.append(new Highlight(0)); 1251 hlList.append(new Highlight(0));
1247 1252
1248 uint i=0; 1253 uint i=0;
1249 while (i < modeList.count()) 1254 while (i < modeList.count())
1250 { 1255 {
1251 hlList.append(new Highlight(modeList.at(i))); 1256 hlList.append(new Highlight(modeList.at(i)));
1252 i++; 1257 i++;
1253 } 1258 }
1254} 1259}
1255 1260
1256HlManager::~HlManager() { 1261HlManager::~HlManager() {
1257 if(syntax) delete syntax; 1262 if(syntax) delete syntax;
1258} 1263}
1259 1264
1260HlManager *HlManager::self() 1265HlManager *HlManager::self()
1261{ 1266{
1262 if ( !s_pSelf ) 1267 if ( !s_pSelf )
1263 s_pSelf = new HlManager; 1268 s_pSelf = new HlManager;
1264 return s_pSelf; 1269 return s_pSelf;
1265} 1270}
1266 1271
1267Highlight *HlManager::getHl(int n) { 1272Highlight *HlManager::getHl(int n) {
1268 if (n < 0 || n >= (int) hlList.count()) n = 0; 1273 if (n < 0 || n >= (int) hlList.count()) n = 0;
1269 return hlList.at(n); 1274 return hlList.at(n);
1270} 1275}
1271 1276
1272int HlManager::defaultHl() { 1277int HlManager::defaultHl() {
1273 KateConfig *config; 1278 KateConfig *config;
1274 config = KGlobal::config(); 1279 config = KGlobal::config();
1275 config->setGroup("General Options"); 1280 config->setGroup("General Options");
1276 1281
1277#warning fixme return nameFind(config->readEntry("Highlight")); 1282#warning fixme return nameFind(config->readEntry("Highlight"));
1278 1283
1279} 1284}
1280 1285
1281 1286
1282int HlManager::nameFind(const QString &name) { 1287int HlManager::nameFind(const QString &name) {
1283 int z; 1288 int z;
1284 1289
1285 for (z = hlList.count() - 1; z > 0; z--) { 1290 for (z = hlList.count() - 1; z > 0; z--) {
1286 if (hlList.at(z)->iName == name) break; 1291 if (hlList.at(z)->iName == name) break;
1287 } 1292 }
1288 return z; 1293 return z;
1289} 1294}
1290 1295
1291int HlManager::wildcardFind(const QString &fileName) { 1296int HlManager::wildcardFind(const QString &fileName) {
1292 Highlight *highlight; 1297 Highlight *highlight;
1293 int p1, p2; 1298 int p1, p2;
1294 QString w; 1299 QString w;
1295 for (highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) { 1300 for (highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
1296 p1 = 0; 1301 p1 = 0;
1297 w = highlight->getWildcards(); 1302 w = highlight->getWildcards();
1298 while (p1 < (int) w.length()) { 1303 while (p1 < (int) w.length()) {
1299 p2 = w.find(';',p1); 1304 p2 = w.find(';',p1);
1300 if (p2 == -1) p2 = w.length(); 1305 if (p2 == -1) p2 = w.length();
1301 if (p1 < p2) { 1306 if (p1 < p2) {
1302 QRegExp regExp(w.mid(p1,p2 - p1),true,true); 1307 QRegExp regExp(w.mid(p1,p2 - p1),true,true);
1303 if (regExp.match(fileName) == 0) return hlList.at(); 1308 if (regExp.match(fileName) == 0) return hlList.at();
1304 } 1309 }
1305 p1 = p2 + 1; 1310 p1 = p2 + 1;
1306 } 1311 }
1307 } 1312 }
1308 return -1; 1313 return -1;
1309} 1314}
1310 1315
1311 1316
1312int HlManager::makeAttribs(Highlight *highlight, Attribute *a, int maxAttribs) { 1317int HlManager::makeAttribs(Highlight *highlight, Attribute *a, int maxAttribs) {
1313 ItemStyleList defaultStyleList; 1318 ItemStyleList defaultStyleList;
1314 ItemStyle *defaultStyle; 1319 ItemStyle *defaultStyle;
1315 ItemDataList itemDataList; 1320 ItemDataList itemDataList;
1316 ItemData *itemData; 1321 ItemData *itemData;
1317 int nAttribs, z; 1322 int nAttribs, z;
1318 1323
1319 odebug << "HlManager::makeAttribs" << oendl; 1324 odebug << "HlManager::makeAttribs" << oendl;
1320 1325
1321 defaultStyleList.setAutoDelete(true); 1326 defaultStyleList.setAutoDelete(true);
1322 getDefaults(defaultStyleList); 1327 getDefaults(defaultStyleList);
1323 1328
1324// itemDataList.setAutoDelete(true); 1329// itemDataList.setAutoDelete(true);
1325 highlight->getItemDataList(itemDataList); 1330 highlight->getItemDataList(itemDataList);
1326 nAttribs = itemDataList.count(); 1331 nAttribs = itemDataList.count();
1327 for (z = 0; z < nAttribs; z++) { 1332 for (z = 0; z < nAttribs; z++) {
1328 odebug << "HlManager::makeAttribs: createing one attribute definition" << oendl; 1333 odebug << "HlManager::makeAttribs: createing one attribute definition" << oendl;
1329 itemData = itemDataList.at(z); 1334 itemData = itemDataList.at(z);
1330 if (itemData->defStyle) { 1335 if (itemData->defStyle) {
1331 // default style 1336 // default style
1332 defaultStyle = defaultStyleList.at(itemData->defStyleNum); 1337 defaultStyle = defaultStyleList.at(itemData->defStyleNum);
1333 a[z].col = defaultStyle->col; 1338 a[z].col = defaultStyle->col;
1334 a[z].selCol = defaultStyle->selCol; 1339 a[z].selCol = defaultStyle->selCol;
1335 a[z].bold = defaultStyle->bold; 1340 a[z].bold = defaultStyle->bold;
1336 a[z].italic = defaultStyle->italic; 1341 a[z].italic = defaultStyle->italic;
1337 } else { 1342 } else {
1338 // custom style 1343 // custom style
1339 a[z].col = itemData->col; 1344 a[z].col = itemData->col;
1340 a[z].selCol = itemData->selCol; 1345 a[z].selCol = itemData->selCol;
1341 a[z].bold = itemData->bold; 1346 a[z].bold = itemData->bold;
1342 a[z].italic = itemData->italic; 1347 a[z].italic = itemData->italic;
1343 } 1348 }
1344 } 1349 }
1345 1350
1346 for (; z < maxAttribs; z++) { 1351 for (; z < maxAttribs; z++) {
1347 a[z].col = black; 1352 a[z].col = black;
1348 a[z].selCol = black; 1353 a[z].selCol = black;
1349 a[z].bold = defaultStyle->bold; 1354 a[z].bold = defaultStyle->bold;
1350 a[z].italic = defaultStyle->italic; 1355 a[z].italic = defaultStyle->italic;
1351 } 1356 }
1352 return nAttribs; 1357 return nAttribs;
1353} 1358}
1354 1359
1355int HlManager::defaultStyles() { 1360int HlManager::defaultStyles() {
1356 return 10; 1361 return 10;
1357} 1362}
1358 1363
1359QString HlManager::defaultStyleName(int n) 1364QString HlManager::defaultStyleName(int n)
1360{ 1365{
1361 static QStringList names; 1366 static QStringList names;
1362 1367
1363 if (names.isEmpty()) 1368 if (names.isEmpty())
1364 { 1369 {
1365 names << i18n("Normal"); 1370 names << i18n("Normal");
1366 names << i18n("Keyword"); 1371 names << i18n("Keyword");
1367 names << i18n("Data Type"); 1372 names << i18n("Data Type");
1368 names << i18n("Decimal/Value"); 1373 names << i18n("Decimal/Value");
1369 names << i18n("Base-N Integer"); 1374 names << i18n("Base-N Integer");
1370 names << i18n("Floating Point"); 1375 names << i18n("Floating Point");
1371 names << i18n("Character"); 1376 names << i18n("Character");
1372 names << i18n("String"); 1377 names << i18n("String");
1373 names << i18n("Comment"); 1378 names << i18n("Comment");
1374 names << i18n("Others"); 1379 names << i18n("Others");
1375 } 1380 }
1376 1381
1377 return names[n]; 1382 return names[n];
1378} 1383}
1379 1384
1380void HlManager::getDefaults(ItemStyleList &list) { 1385void HlManager::getDefaults(ItemStyleList &list) {
1381 KateConfig *config; 1386 KateConfig *config;
1382 int z; 1387 int z;
1383 ItemStyle *i; 1388 ItemStyle *i;
1384 QString s; 1389 QString s;
1385 QRgb col, selCol; 1390 QRgb col, selCol;
1386 1391
1387 list.setAutoDelete(true); 1392 list.setAutoDelete(true);
1388 //ItemStyle(color, selected color, bold, italic) 1393 //ItemStyle(color, selected color, bold, italic)
1389 list.append(new ItemStyle(black,white,false,false)); //normal 1394 list.append(new ItemStyle(black,white,false,false)); //normal
1390 list.append(new ItemStyle(black,white,true,false)); //keyword 1395 list.append(new ItemStyle(black,white,true,false)); //keyword
1391 list.append(new ItemStyle(darkRed,white,false,false)); //datatype 1396 list.append(new ItemStyle(darkRed,white,false,false)); //datatype
1392 list.append(new ItemStyle(blue,cyan,false,false)); //decimal/value 1397 list.append(new ItemStyle(blue,cyan,false,false)); //decimal/value
1393 list.append(new ItemStyle(darkCyan,cyan,false,false)); //base n 1398 list.append(new ItemStyle(darkCyan,cyan,false,false)); //base n
1394 list.append(new ItemStyle(darkMagenta,cyan,false,false));//float 1399 list.append(new ItemStyle(darkMagenta,cyan,false,false));//float
1395 list.append(new ItemStyle(magenta,magenta,false,false)); //char 1400 list.append(new ItemStyle(magenta,magenta,false,false)); //char
1396 list.append(new ItemStyle(red,red,false,false)); //string 1401 list.append(new ItemStyle(red,red,false,false)); //string
1397 list.append(new ItemStyle(darkGray,gray,false,true)); //comment 1402 list.append(new ItemStyle(darkGray,gray,false,true)); //comment
1398 list.append(new ItemStyle(darkGreen,green,false,false)); //others 1403 list.append(new ItemStyle(darkGreen,green,false,false)); //others
1399 1404
1400#warning fixme 1405#warning fixme
1401/* 1406/*
1402 config = KateFactory::instance()->config(); 1407 config = KateFactory::instance()->config();
1403 config->setGroup("Default Item Styles"); 1408 config->setGroup("Default Item Styles");
1404 for (z = 0; z < defaultStyles(); z++) { 1409 for (z = 0; z < defaultStyles(); z++) {
1405 i = list.at(z); 1410 i = list.at(z);
1406 s = config->readEntry(defaultStyleName(z)); 1411 s = config->readEntry(defaultStyleName(z));
1407 if (!s.isEmpty()) { 1412 if (!s.isEmpty()) {
1408 sscanf(s.latin1(),"%X,%X,%d,%d",&col,&selCol,&i->bold,&i->italic); 1413 sscanf(s.latin1(),"%X,%X,%d,%d",&col,&selCol,&i->bold,&i->italic);
1409 i->col.setRgb(col); 1414 i->col.setRgb(col);
1410 i->selCol.setRgb(selCol); 1415 i->selCol.setRgb(selCol);
1411 } 1416 }
1412 } 1417 }
1413*/ 1418*/
1414} 1419}
1415 1420
1416void HlManager::setDefaults(ItemStyleList &list) { 1421void HlManager::setDefaults(ItemStyleList &list) {
1417 KateConfig *config; 1422 KateConfig *config;
1418 int z; 1423 int z;
1419 ItemStyle *i; 1424 ItemStyle *i;
1420 char s[64]; 1425 char s[64];
1421#warning fixme 1426#warning fixme
1422/* 1427/*
1423 config = KateFactory::instance()->config(); 1428 config = KateFactory::instance()->config();
1424 config->setGroup("Default Item Styles"); 1429 config->setGroup("Default Item Styles");
1425 for (z = 0; z < defaultStyles(); z++) { 1430 for (z = 0; z < defaultStyles(); z++) {
1426 i = list.at(z); 1431 i = list.at(z);
1427 sprintf(s,"%X,%X,%d,%d",i->col.rgb(),i->selCol.rgb(),i->bold, i->italic); 1432 sprintf(s,"%X,%X,%d,%d",i->col.rgb(),i->selCol.rgb(),i->bold, i->italic);
1428 config->writeEntry(defaultStyleName(z),s); 1433 config->writeEntry(defaultStyleName(z),s);
1429 } 1434 }
1430*/ 1435*/
1431 emit changed(); 1436 emit changed();
1432} 1437}
1433 1438
1434 1439
1435int HlManager::highlights() { 1440int HlManager::highlights() {
1436 return (int) hlList.count(); 1441 return (int) hlList.count();
1437} 1442}
1438 1443
1439QString HlManager::hlName(int n) { 1444QString HlManager::hlName(int n) {
1440 return hlList.at(n)->iName; 1445 return hlList.at(n)->iName;
1441} 1446}
1442 1447
1443QString HlManager::hlSection(int n) { 1448QString HlManager::hlSection(int n) {
1444 return hlList.at(n)->iSection; 1449 return hlList.at(n)->iSection;
1445} 1450}
1446 1451
1447void HlManager::getHlDataList(HlDataList &list) { 1452void HlManager::getHlDataList(HlDataList &list) {
1448 int z; 1453 int z;
1449 1454
1450 for (z = 0; z < (int) hlList.count(); z++) { 1455 for (z = 0; z < (int) hlList.count(); z++) {
1451 list.append(hlList.at(z)->getData()); 1456 list.append(hlList.at(z)->getData());
1452 } 1457 }
1453} 1458}
1454 1459
1455void HlManager::setHlDataList(HlDataList &list) { 1460void HlManager::setHlDataList(HlDataList &list) {
1456 int z; 1461 int z;
1457 1462
1458 for (z = 0; z < (int) hlList.count(); z++) { 1463 for (z = 0; z < (int) hlList.count(); z++) {
1459 hlList.at(z)->setData(list.at(z)); 1464 hlList.at(z)->setData(list.at(z));
1460 } 1465 }
1461 //notify documents about changes in highlight configuration 1466 //notify documents about changes in highlight configuration
1462 emit changed(); 1467 emit changed();
1463} 1468}
diff --git a/noncore/apps/tinykate/libkate/document/katehighlight.h b/noncore/apps/tinykate/libkate/document/katehighlight.h
index fddf585..f0be27b 100644
--- a/noncore/apps/tinykate/libkate/document/katehighlight.h
+++ b/noncore/apps/tinykate/libkate/document/katehighlight.h
@@ -1,349 +1,349 @@
1/* 1/*
2 Copyright (C) 1998, 1999 Jochen Wilhelmy 2 Copyright (C) 1998, 1999 Jochen Wilhelmy
3 digisnap@cs.tu-berlin.de 3 digisnap@cs.tu-berlin.de
4 (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org> 4 (C) 2002, 2001 The Kate Team <kwrite-devel@kde.org>
5 (C) 2002 Joseph Wenninger <jowenn@kde.org> 5 (C) 2002 Joseph Wenninger <jowenn@kde.org>
6 6
7 This library is free software; you can redistribute it and/or 7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public 8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This library is distributed in the hope that it will be useful, 12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details. 15 Library General Public License for more details.
16 16
17 You should have received a copy of the GNU Library General Public License 17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to 18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#ifndef _HIGHLIGHT_H_ 23#ifndef _HIGHLIGHT_H_
24#define _HIGHLIGHT_H_ 24#define _HIGHLIGHT_H_
25 25
26#include <qlist.h> 26#include <qlist.h>
27#include <qdialog.h> 27#include <qdialog.h>
28 28
29#include <kcolorbtn.h> 29#include <kcolorbtn.h>
30#include <qstrvec.h> 30#include <qstrvec.h>
31#include <qdict.h> 31#include <qdict.h>
32#include <qregexp.h> 32#include <qregexp.h>
33#include "../qt3back/qregexp3.h" 33#include "../qt3back/qregexp3.h"
34#include <kdebug.h> 34#include <kdebug.h>
35 35
36class SyntaxDocument; 36class SyntaxDocument;
37struct syntaxModeListItem; 37struct syntaxModeListItem;
38struct syntaxContextData; 38struct syntaxContextData;
39 39
40class QCheckBox; 40class QCheckBox;
41class QComboBox; 41class QComboBox;
42class QLineEdit; 42class QLineEdit;
43 43
44class TextLine; 44class TextLine;
45class Attribute; 45class Attribute;
46 46
47class HlItem { 47class HlItem {
48 public: 48 public:
49 HlItem(int attribute, int context); 49 HlItem(int attribute, int context);
50 virtual ~HlItem(); 50 virtual ~HlItem();
51 virtual bool startEnable(QChar); 51 virtual bool startEnable(QChar);
52 virtual const QChar *checkHgl(const QChar *, int len, bool) = 0; 52 virtual const QChar *checkHgl(const QChar *, int len, bool) = 0;
53 QList<HlItem> *subItems; 53 QList<HlItem> *subItems;
54 int attr; 54 int attr;
55 int ctx; 55 int ctx;
56}; 56};
57 57
58class HlCharDetect : public HlItem { 58class HlCharDetect : public HlItem {
59 public: 59 public:
60 HlCharDetect(int attribute, int context, QChar); 60 HlCharDetect(int attribute, int context, QChar);
61 virtual const QChar *checkHgl(const QChar *, int len, bool); 61 virtual const QChar *checkHgl(const QChar *, int len, bool);
62 protected: 62 protected:
63 QChar sChar; 63 QChar sChar;
64}; 64};
65 65
66class Hl2CharDetect : public HlItem { 66class Hl2CharDetect : public HlItem {
67 public: 67 public:
68 Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2); 68 Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2);
69 Hl2CharDetect(int attribute, int context, const QChar *ch); 69 Hl2CharDetect(int attribute, int context, const QChar *ch);
70 70
71 virtual const QChar *checkHgl(const QChar *, int len, bool); 71 virtual const QChar *checkHgl(const QChar *, int len, bool);
72 protected: 72 protected:
73 QChar sChar1; 73 QChar sChar1;
74 QChar sChar2; 74 QChar sChar2;
75}; 75};
76 76
77class HlStringDetect : public HlItem { 77class HlStringDetect : public HlItem {
78 public: 78 public:
79 HlStringDetect(int attribute, int context, const QString &, bool inSensitive=false); 79 HlStringDetect(int attribute, int context, const QString &, bool inSensitive=false);
80 virtual ~HlStringDetect(); 80 virtual ~HlStringDetect();
81 virtual const QChar *checkHgl(const QChar *, int len, bool); 81 virtual const QChar *checkHgl(const QChar *, int len, bool);
82 protected: 82 protected:
83 const QString str; 83 const QString str;
84 bool _inSensitive; 84 bool _inSensitive;
85}; 85};
86 86
87class HlRangeDetect : public HlItem { 87class HlRangeDetect : public HlItem {
88 public: 88 public:
89 HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2); 89 HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2);
90 virtual const QChar *checkHgl(const QChar *, int len, bool); 90 virtual const QChar *checkHgl(const QChar *, int len, bool);
91 protected: 91 protected:
92 QChar sChar1; 92 QChar sChar1;
93 QChar sChar2; 93 QChar sChar2;
94}; 94};
95 95
96class HlKeyword : public HlItem 96class HlKeyword : public HlItem
97{ 97{
98 public: 98 public:
99 HlKeyword(int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen); 99 HlKeyword(int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen);
100 virtual ~HlKeyword(); 100 virtual ~HlKeyword();
101 101
102 virtual void addWord(const QString &); 102 virtual void addWord(const QString &);
103 virtual void addList(const QStringList &); 103 virtual void addList(const QStringList &);
104 virtual const QChar *checkHgl(const QChar *, int len, bool); 104 virtual const QChar *checkHgl(const QChar *, int len, bool);
105 QStringList getList() { return words;}; 105 QStringList getList() { return words;};
106 virtual bool startEnable(QChar c); 106 virtual bool startEnable(QChar c);
107 107
108 protected: 108 protected:
109 QStringList words; 109 QStringList words;
110 QDict<bool> dict; 110 QDict<bool> dict;
111 bool _caseSensitive; 111 bool _caseSensitive;
112 const QChar *deliminatorChars; 112 const QChar *deliminatorChars;
113 uint deliminatorLen; 113 uint deliminatorLen;
114}; 114};
115 115
116class HlPHex : public HlItem { 116class HlPHex : public HlItem {
117 public: 117 public:
118 HlPHex(int attribute,int context); 118 HlPHex(int attribute,int context);
119 virtual const QChar *checkHgl(const QChar *, int len, bool); 119 virtual const QChar *checkHgl(const QChar *, int len, bool);
120}; 120};
121class HlInt : public HlItem { 121class HlInt : public HlItem {
122 public: 122 public:
123 HlInt(int attribute, int context); 123 HlInt(int attribute, int context);
124 virtual const QChar *checkHgl(const QChar *, int len, bool); 124 virtual const QChar *checkHgl(const QChar *, int len, bool);
125}; 125};
126 126
127class HlFloat : public HlItem { 127class HlFloat : public HlItem {
128 public: 128 public:
129 HlFloat(int attribute, int context); 129 HlFloat(int attribute, int context);
130 virtual const QChar *checkHgl(const QChar *, int len, bool); 130 virtual const QChar *checkHgl(const QChar *, int len, bool);
131}; 131};
132 132
133class HlCInt : public HlInt { 133class HlCInt : public HlInt {
134 public: 134 public:
135 HlCInt(int attribute, int context); 135 HlCInt(int attribute, int context);
136 virtual const QChar *checkHgl(const QChar *, int len, bool); 136 virtual const QChar *checkHgl(const QChar *, int len, bool);
137}; 137};
138 138
139class HlCOct : public HlItem { 139class HlCOct : public HlItem {
140 public: 140 public:
141 HlCOct(int attribute, int context); 141 HlCOct(int attribute, int context);
142 virtual const QChar *checkHgl(const QChar *, int len, bool); 142 virtual const QChar *checkHgl(const QChar *, int len, bool);
143}; 143};
144 144
145class HlCHex : public HlItem { 145class HlCHex : public HlItem {
146 public: 146 public:
147 HlCHex(int attribute, int context); 147 HlCHex(int attribute, int context);
148 virtual const QChar *checkHgl(const QChar *, int len, bool); 148 virtual const QChar *checkHgl(const QChar *, int len, bool);
149}; 149};
150 150
151class HlCFloat : public HlFloat { 151class HlCFloat : public HlFloat {
152 public: 152 public:
153 HlCFloat(int attribute, int context); 153 HlCFloat(int attribute, int context);
154 virtual const QChar *checkHgl(const QChar *, int len, bool); 154 virtual const QChar *checkHgl(const QChar *, int len, bool);
155}; 155};
156 156
157class HlLineContinue : public HlItem { 157class HlLineContinue : public HlItem {
158 public: 158 public:
159 HlLineContinue(int attribute, int context); 159 HlLineContinue(int attribute, int context);
160 virtual bool endEnable(QChar c) {return c == '\0';} 160 virtual bool endEnable(QChar c) {return c == '\0';}
161 virtual const QChar *checkHgl(const QChar *, int len, bool); 161 virtual const QChar *checkHgl(const QChar *, int len, bool);
162}; 162};
163 163
164class HlCStringChar : public HlItem { 164class HlCStringChar : public HlItem {
165 public: 165 public:
166 HlCStringChar(int attribute, int context); 166 HlCStringChar(int attribute, int context);
167 virtual const QChar *checkHgl(const QChar *, int len, bool); 167 virtual const QChar *checkHgl(const QChar *, int len, bool);
168}; 168};
169 169
170class HlCChar : public HlItem { 170class HlCChar : public HlItem {
171 public: 171 public:
172 HlCChar(int attribute, int context); 172 HlCChar(int attribute, int context);
173 virtual const QChar *checkHgl(const QChar *, int len, bool); 173 virtual const QChar *checkHgl(const QChar *, int len, bool);
174}; 174};
175 175
176class HlAnyChar : public HlItem { 176class HlAnyChar : public HlItem {
177 public: 177 public:
178 HlAnyChar(int attribute, int context, const QChar* charList, uint len); 178 HlAnyChar(int attribute, int context, const QChar* charList, uint len);
179 virtual const QChar *checkHgl(const QChar *, int len, bool); 179 virtual const QChar *checkHgl(const QChar *, int len, bool);
180 const QChar* _charList; 180 const QChar* _charList;
181 uint _charListLen; 181 uint _charListLen;
182}; 182};
183 183
184class HlRegExpr : public HlItem { 184class HlRegExpr : public HlItem {
185 public: 185 public:
186 HlRegExpr(int attribute, int context,QString expr); 186 HlRegExpr(int attribute, int context,QString expr);
187 ~HlRegExpr(){delete Expr;}; 187 ~HlRegExpr();
188 virtual const QChar *checkHgl(const QChar *, int len, bool); 188 virtual const QChar *checkHgl(const QChar *, int len, bool);
189 QRegExp3 *Expr; 189 QRegExp3 *Expr;
190 bool handlesLinestart; 190 bool handlesLinestart;
191}; 191};
192 192
193//-------- 193//--------
194 194
195 195
196//Item Style: color, selected color, bold, italic 196//Item Style: color, selected color, bold, italic
197class ItemStyle { 197class ItemStyle {
198 public: 198 public:
199 ItemStyle(); 199 ItemStyle();
200// ItemStyle(const ItemStyle &); 200// ItemStyle(const ItemStyle &);
201 ItemStyle(const QColor &, const QColor &, bool bold, bool italic); 201 ItemStyle(const QColor &, const QColor &, bool bold, bool italic);
202 ItemStyle(ItemStyle *its){col=its->col;selCol=its->selCol; bold=its->bold; italic=its->italic;} 202 ItemStyle(ItemStyle *its){col=its->col;selCol=its->selCol; bold=its->bold; italic=its->italic;}
203// void setData(const ItemStyle &); 203// void setData(const ItemStyle &);
204 QColor col; 204 QColor col;
205 QColor selCol; 205 QColor selCol;
206 int bold; //boolean value 206 int bold; //boolean value
207 int italic; //boolean value 207 int italic; //boolean value
208}; 208};
209 209
210typedef QList<ItemStyle> ItemStyleList; 210typedef QList<ItemStyle> ItemStyleList;
211 211
212//Item Properties: name, Item Style, Item Font 212//Item Properties: name, Item Style, Item Font
213class ItemData : public ItemStyle { 213class ItemData : public ItemStyle {
214 public: 214 public:
215 ItemData(const QString name, int defStyleNum); 215 ItemData(const QString name, int defStyleNum);
216 ItemData(const QString name, int defStyleNum, 216 ItemData(const QString name, int defStyleNum,
217 const QColor&, const QColor&, bool bold, bool italic); 217 const QColor&, const QColor&, bool bold, bool italic);
218 ItemData(ItemData 218 ItemData(ItemData
219*itd):ItemStyle((ItemStyle*)itd),name(itd->name),defStyleNum(itd->defStyleNum),defStyle(itd->defStyle){;} 219*itd):ItemStyle((ItemStyle*)itd),name(itd->name),defStyleNum(itd->defStyleNum),defStyle(itd->defStyle){;}
220 const QString name; 220 const QString name;
221 int defStyleNum; 221 int defStyleNum;
222 int defStyle; //boolean value 222 int defStyle; //boolean value
223}; 223};
224 224
225typedef QList<ItemData> ItemDataList; 225typedef QList<ItemData> ItemDataList;
226 226
227class HlData { 227class HlData {
228 public: 228 public:
229 HlData(const QString &wildcards, const QString &mimetypes,const QString &identifier); 229 HlData(const QString &wildcards, const QString &mimetypes,const QString &identifier);
230 ItemDataList itemDataList; 230 ItemDataList itemDataList;
231 QString wildcards; 231 QString wildcards;
232 QString mimetypes; 232 QString mimetypes;
233 QString identifier; 233 QString identifier;
234}; 234};
235 235
236typedef QList<HlData> HlDataList; 236typedef QList<HlData> HlDataList;
237 237
238class HlManager; 238class HlManager;
239class KateConfig; 239class KateConfig;
240 240
241//context 241//context
242class HlContext { 242class HlContext {
243 public: 243 public:
244 HlContext(int attribute, int lineEndContext,int _lineBeginContext); 244 HlContext(int attribute, int lineEndContext,int _lineBeginContext);
245 QList<HlItem> items; 245 QList<HlItem> items;
246 int attr; 246 int attr;
247 int ctx; 247 int ctx;
248 int lineBeginContext; 248 int lineBeginContext;
249}; 249};
250 250
251class Highlight 251class Highlight
252{ 252{
253 friend class HlManager; 253 friend class HlManager;
254 254
255 public: 255 public:
256 Highlight(syntaxModeListItem *def); 256 Highlight(syntaxModeListItem *def);
257 ~Highlight(); 257 ~Highlight();
258 258
259 int doHighlight(int ctxNum, TextLine *); 259 int doHighlight(int ctxNum, TextLine *);
260 260
261 KateConfig *getKateConfig(); 261 KateConfig *getKateConfig();
262 QString getWildcards(); 262 QString getWildcards();
263 QString getMimetypes(); 263 QString getMimetypes();
264 HlData *getData(); 264 HlData *getData();
265 void setData(HlData *); 265 void setData(HlData *);
266 void getItemDataList(ItemDataList &); 266 void getItemDataList(ItemDataList &);
267 void getItemDataList(ItemDataList &, KateConfig *); 267 void getItemDataList(ItemDataList &, KateConfig *);
268 void setItemDataList(ItemDataList &, KateConfig *); 268 void setItemDataList(ItemDataList &, KateConfig *);
269 QString name() {return iName;} 269 QString name() {return iName;}
270 QString section() {return iSection;} 270 QString section() {return iSection;}
271 void use(); 271 void use();
272 void release(); 272 void release();
273 bool isInWord(QChar c); 273 bool isInWord(QChar c);
274 274
275 QString getCommentStart() {return cmlStart;}; 275 QString getCommentStart() {return cmlStart;};
276 QString getCommentEnd() {return cmlEnd;}; 276 QString getCommentEnd() {return cmlEnd;};
277 QString getCommentSingleLineStart() { return cslStart;}; 277 QString getCommentSingleLineStart() { return cslStart;};
278 278
279 protected: 279 protected:
280 void init(); 280 void init();
281 void done(); 281 void done();
282 void makeContextList (); 282 void makeContextList ();
283 void createItemData (ItemDataList &list); 283 void createItemData (ItemDataList &list);
284 void readGlobalKeywordConfig(); 284 void readGlobalKeywordConfig();
285 void readCommentConfig(); 285 void readCommentConfig();
286 HlItem *createHlItem(struct syntaxContextData *data, ItemDataList &iDl); 286 HlItem *createHlItem(struct syntaxContextData *data, ItemDataList &iDl);
287 int lookupAttrName(const QString& name, ItemDataList &iDl); 287 int lookupAttrName(const QString& name, ItemDataList &iDl);
288 ItemDataList internalIDList; 288 ItemDataList internalIDList;
289 static const int nContexts = 32; 289 static const int nContexts = 32;
290 HlContext *contextList[nContexts]; 290 HlContext *contextList[nContexts];
291 291
292 bool noHl; 292 bool noHl;
293 bool casesensitive; 293 bool casesensitive;
294 QString weakDeliminator; 294 QString weakDeliminator;
295 QString deliminator; 295 QString deliminator;
296 const QChar *deliminatorChars; 296 const QChar *deliminatorChars;
297 uint deliminatorLen; 297 uint deliminatorLen;
298 QString cmlStart; 298 QString cmlStart;
299 QString cmlEnd; 299 QString cmlEnd;
300 QString cslStart; 300 QString cslStart;
301 QString iName; 301 QString iName;
302 QString iSection; 302 QString iSection;
303 QString iWildcards; 303 QString iWildcards;
304 QString iMimetypes; 304 QString iMimetypes;
305 QString identifier; 305 QString identifier;
306 int refCount; 306 int refCount;
307}; 307};
308 308
309class HlManager : public QObject { 309class HlManager : public QObject {
310 Q_OBJECT 310 Q_OBJECT
311 public: 311 public:
312 HlManager(); 312 HlManager();
313 ~HlManager(); 313 ~HlManager();
314 314
315 static HlManager *self(); 315 static HlManager *self();
316 316
317 Highlight *getHl(int n); 317 Highlight *getHl(int n);
318 int defaultHl(); 318 int defaultHl();
319 int nameFind(const QString &name); 319 int nameFind(const QString &name);
320 320
321 int wildcardFind(const QString &fileName); 321 int wildcardFind(const QString &fileName);
322 int findHl(Highlight *h) {return hlList.find(h);} 322 int findHl(Highlight *h) {return hlList.find(h);}
323 323
324 int makeAttribs(Highlight *, Attribute *, int maxAttribs); 324 int makeAttribs(Highlight *, Attribute *, int maxAttribs);
325 325
326 int defaultStyles(); 326 int defaultStyles();
327 QString defaultStyleName(int n); 327 QString defaultStyleName(int n);
328 void getDefaults(ItemStyleList &); 328 void getDefaults(ItemStyleList &);
329 void setDefaults(ItemStyleList &); 329 void setDefaults(ItemStyleList &);
330 330
331 int highlights(); 331 int highlights();
332 QString hlName(int n); 332 QString hlName(int n);
333 QString hlSection(int n); 333 QString hlSection(int n);
334 void getHlDataList(HlDataList &); 334 void getHlDataList(HlDataList &);
335 void setHlDataList(HlDataList &); 335 void setHlDataList(HlDataList &);
336 336
337 SyntaxDocument *syntax; 337 SyntaxDocument *syntax;
338 338
339 signals: 339 signals:
340 void changed(); 340 void changed();
341 protected: 341 protected:
342 QList<Highlight> hlList; 342 QList<Highlight> hlList;
343 static HlManager *s_pSelf; 343 static HlManager *s_pSelf;
344}; 344};
345 345
346 346
347 347
348 348
349#endif //_HIGHLIGHT_H_ 349#endif //_HIGHLIGHT_H_