Subversion Repositories Scribus

Rev

Rev 5291 | Rev 5464 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4777 avox 1
//FIXME: this include must go to sctextstruct.h !
2
#include <qvaluelist.h>
5105 mrdocs 3
#include <cassert>  //added to make Fedora-5 happy
4669 avox 4
#include "fpoint.h"
5
#include "sctextstruct.h"
6
#include "storytext.h"
7
#include "scribus.h"
8
#include "scfonts.h"
5184 avox 9
#include "util.h"
4669 avox 10
 
11
//FIXME: move to proper place
12
const QString CharStyle::NOCOLOR; // cf. sctextstruct.h
13
 
14
 
15
QChar SpecialChars::OBJECT     = QChar(25);
16
QChar SpecialChars::TAB        = QChar(9);
17
QChar SpecialChars::PARSEP     = QChar(13);
18
QChar SpecialChars::LINEBREAK  = QChar(28);
19
QChar SpecialChars::COLBREAK   = QChar(26);
20
QChar SpecialChars::FRAMEBREAK = QChar(27);
21
QChar SpecialChars::SHYPHEN;
22
QChar SpecialChars::NBHYPHEN   = QChar(24);
23
QChar SpecialChars::NBSPACE    = QChar(29);
24
QChar SpecialChars::ZWNBSPACE;
25
QChar SpecialChars::ZWSPACE;
26
//QChar SpecialChars::SPACE      = QChar(32);
27
 
28
 
29
 
30
StoryText::StoryText(ScribusDoc * doc_) : doc(doc_)
31
{
32
        clear();
33
}
34
 
4706 avox 35
StoryText::StoryText(const StoryText & other) : QPtrList<ScText>(other), doc(other.doc)
4669 avox 36
{
4706 avox 37
        selFirst = 0;
38
        selLast = -1;
39
 
40
        firstFrameItem = 0;
41
        lastFrameItem = -1;
42
 
4669 avox 43
        invalidateLayout();
44
}
45
 
46
StoryText::~StoryText()
47
{
48
}
49
 
50
StoryText& StoryText::operator= (const StoryText & other)
51
{
4706 avox 52
        selFirst = 0;
53
        selLast = -1;
54
 
55
        firstFrameItem = 0;
56
        lastFrameItem = -1;
57
 
4669 avox 58
        invalidateLayout();
59
        return *this;
60
}
61
 
62
 
63
void StoryText::clear()
64
{
65
        selFirst = 0;
66
        selLast = -1;
67
 
68
        firstFrameItem = 0;
69
        lastFrameItem = -1;
70
 
4749 avox 71
        for (ScText *it = first(); it != 0; it = next())
72
        {
73
                if ((it->ch == SpecialChars::OBJECT) && (it->cembedded != 0)) {
74
                        doc->FrameItems.remove(it->cembedded);
5184 avox 75
                        delete it->cembedded;
4749 avox 76
                        it->cembedded = 0;
77
                }
78
        }
79
 
4687 avox 80
        QPtrList<ScText>::clear();
4669 avox 81
        invalidateAll();
82
}
83
 
84
 
85
void StoryText::removeChars(int pos, uint len)
86
{
87
        if (pos < 0)
88
                pos += length();
89
 
90
        assert( len > 0 );
91
        assert( pos >= 0 );
92
        assert( pos + static_cast<int>(len) <= length() );
4749 avox 93
 
4752 avox 94
        for ( uint i=0; i < len; ++i )
4749 avox 95
        {
96
                ScText *it = take(i);
97
                if ((it->ch == SpecialChars::OBJECT) && (it->cembedded != 0)) {
98
                        doc->FrameItems.remove(it->cembedded);
99
                        it->cembedded = 0;
100
                }
101
                delete it;
102
        }
103
        invalidate(pos, -1);
4669 avox 104
}
105
 
4749 avox 106
void StoryText::insertChars(int pos, QString txt) //, const CharStyle&
4669 avox 107
{
108
        if (pos < 0)
109
                pos += length();
110
 
111
        assert(pos >= 0);
112
        assert(pos <= length());
4749 avox 113
 
5365 avox 114
        if (txt.length() == 0)
115
                return;
116
 
5184 avox 117
        const CharStyle style = pos == length() ? doc->docParagraphStyles[0].charStyle() : charStyle(pos);
5291 avox 118
        assert(style.cfont != NULL);
119
 
5184 avox 120
        const int paraStyle = pos == length() ? 0 : at(pos)->cab;
4749 avox 121
 
4752 avox 122
        for (uint i = 0; i < txt.length(); ++i) {
4749 avox 123
                ScText * item = new ScText();
124
                item->ch= txt.mid(i, 1);
125
                *static_cast<CharStyle *>(item) = style;
5184 avox 126
                item->cab = paraStyle;
127
                item->cselect = false;
128
                item->xp = 0;
129
                item->yp = 0;
130
                item->PtransX = 0;
131
                item->PtransY = 0;
132
                item->PRot = 0;
133
                item->cembedded = NULL;
4749 avox 134
                insert(pos + i, item);
135
        }
136
 
4669 avox 137
        invalidate(pos, pos + txt.length());
138
}
139
 
140
void StoryText::replaceChar(int pos, QChar ch)
141
{
142
        if (pos < 0)
143
                pos += length();
144
 
145
        assert(pos >= 0);
146
        assert(pos < length());
147
 
148
        at(pos)->ch = ch;
149
 
150
        invalidate(pos, pos + 1);
151
}
152
 
153
void StoryText::insertObject(int pos, PageItem* ob)
154
{
155
        if (pos < 0)
156
                pos += length();
157
 
158
        insertChars(pos, SpecialChars::OBJECT);
159
        //FIXME:NLS
160
}
161
 
162
 
163
int StoryText::length() const
164
{
165
        return count();
166
}
167
 
168
QChar StoryText::text(int pos) const
169
{
170
        if (pos < 0)
171
                pos += length();
172
 
173
        assert(pos >= 0);
174
        assert(pos < length());
175
 
176
        return const_cast<StoryText *>(this)->at(pos)->ch[0];
177
}
178
 
179
QString StoryText::text(int pos, uint len) const
180
{
181
        if (pos < 0)
182
                pos += length();
183
 
184
        assert(len > 0);
185
        assert(pos >= 0);
186
        assert(pos + signed(len) <= length());
187
 
188
        QString result;
4777 avox 189
        for (uint i = pos; i < pos+signed(len); ++i)
4669 avox 190
                result += const_cast<StoryText *>(this)->at(i)->ch;
191
 
192
        return result;
193
}
194
 
195
PageItem* StoryText::object(int pos) const
196
{
197
        if (pos < 0)
198
                pos += length();
199
 
200
        assert(pos >= 0);
201
        assert(pos < length());
202
 
203
        StoryText* that = const_cast<StoryText *>(this);       
204
        if (that->at(pos)->cembedded != NULL)
205
                return that->at(pos)->cembedded;
206
        else
207
                return NULL;
208
}
209
 
210
 
211
const CharStyle & StoryText::charStyle(int pos) const
212
{
213
        if (pos < 0)
214
                pos += length();
215
 
216
        assert(pos >= 0);
217
        assert(pos < length());
218
 
219
        StoryText* that = const_cast<StoryText *>(this);
220
        return dynamic_cast<const CharStyle &> (*that->at(pos));
221
}
222
 
223
const ParagraphStyle & StoryText::paragraphStyle(int pos) const
224
{
225
        if (pos < 0)
226
                pos += length();
227
 
228
        assert(pos >= 0);
229
        assert(pos < length());
230
 
5192 avox 231
        StoryText * that = const_cast<StoryText *> (this);
232
        assert( that->at(pos)->cab >= 0 );
233
        assert( that->at(pos)->cab < doc->docParagraphStyles.count() );
234
        return doc->docParagraphStyles[that->at(pos)->cab];
4669 avox 235
}
236
 
237
void StoryText::applyStyle(int pos, uint len, const CharStyle& style )
238
{
239
        if (pos < 0)
240
                pos += length();
241
 
242
        assert(pos >= 0);
243
        assert(pos + signed(len) <= length());
244
 
245
        if (len == 0)
246
                return;
247
 
4749 avox 248
        for (uint i=pos; i < pos+len; ++i)
249
                at(i)->applyStyle(style);
4669 avox 250
 
251
        invalidate(pos, pos + len);
252
}
253
 
254
void StoryText::applyStyle(int pos, const ParagraphStyle& style)
255
{
256
        if (pos < 0)
257
                pos += length();
258
 
259
        assert(pos >= 0);
260
        assert(pos < length());
261
 
5184 avox 262
        int paraStyle = QMAX(0, findParagraphStyle(doc, style)); //FIXME:NLS
263
        int i = pos - 1;
264
        // find start of para
265
        while (i >= 0 && text(i) != SpecialChars::PARSEP)
266
                --i;
267
        // set 'cab' field
268
        do {
269
                ++i;
270
                at(i)->cab = paraStyle;
271
        }
272
        while (i+1 < length() && text(i) != SpecialChars::PARSEP);             
4669 avox 273
}
274
 
275
uint StoryText::nrOfParagraphs() const
276
{
277
        uint result = 0;
278
        StoryText* that = const_cast<StoryText *>(this);
279
        for (int i=0; i < length(); ++i)
5184 avox 280
                if (that->text(i) == SpecialChars::PARSEP)
4669 avox 281
                        ++result;
282
        return result;
283
}
284
 
285
int StoryText::startOfParagraph(uint index) const
286
{
287
        if (index == 0)
288
                return 0;
289
 
5184 avox 290
        StoryText* that = const_cast<StoryText *>(this);
4669 avox 291
        for (int i=0; i < length(); ++i)
5184 avox 292
                if (that->text(i) == SpecialChars::PARSEP && ! --index)
4669 avox 293
                        return i + 1;
294
        return -1;
295
}
296
 
297
int StoryText::endOfParagraph(uint index) const
298
{
299
        ++index;
5184 avox 300
        StoryText* that = const_cast<StoryText *>(this);
4669 avox 301
        for (int i=0; i < length(); ++i)
5184 avox 302
                if (that->text(i) == SpecialChars::PARSEP && ! --index)
4669 avox 303
                        return i + 1;
304
        return length();
305
}
306
 
307
uint StoryText::nrOfRuns() const
308
{
309
        return 1;
310
}
311
 
312
int StoryText::startOfRun(uint index) const
313
{
314
        return 0;
315
}
316
 
317
int StoryText::endOfRun(uint index) const
318
{
319
        return length();
320
}
321
 
322
 
323
// selection
324
 
325
int StoryText::startOfSelection() const
326
{
327
        return selFirst <= selLast? selFirst : 0;
328
}
329
 
330
int StoryText::endOfSelection() const
331
{
332
        return selFirst <= selLast? selLast + 1 : -1;
333
}
334
 
335
int StoryText::lengthOfSelection() const
336
{
337
        return selFirst <= selLast? selLast - selFirst + 1 : 0;
338
}
339
 
340
 
341
bool StoryText::selected(int pos) const
342
{
4749 avox 343
        return (selFirst <= pos && pos <= selLast)
4752 avox 344
               || (pos >= 0 && pos < length() && const_cast<StoryText*>(this)->at(pos)->cselect);
4669 avox 345
}
346
 
347
void StoryText::select(int pos, uint len, bool on)
348
{
349
        if (pos < 0)
350
                pos += length();
351
 
352
        assert( pos >= 0 );
353
        assert( pos + signed(len) <= length() );
354
 
355
        StoryText* that = const_cast<StoryText *>(this);
356
        for (int i=pos; i < pos+signed(len); ++i)
357
                that->at(i)->cselect = on;
358
 
359
        if (on) {
360
                // extend if possible
361
                if (selected(pos - 1))
362
                        selLast = QMAX(selLast, pos + static_cast<int>(len) - 1);
363
                else if (selected(pos + len))
364
                        selFirst = QMIN(selFirst, pos);
365
                else {
366
                        selFirst = pos;
367
                        selLast = pos + len - 1;
368
                }
369
        }
370
        else {
371
                if (pos <= selFirst && selLast < pos + signed(len))
372
                        deselectAll();
373
                // shrink
374
                else if (!selected(pos - 1) && selected(pos + len - 1))
375
                        selFirst = pos + len;
376
                else if (selected(pos) && !selected(pos + len))
377
                        selLast = pos - 1;
378
                else if (selected(pos) || selected(pos + len - 1))
379
                        // Grr, deselection splits selection
380
                        selLast = pos - 1;
381
        }
382
}
383
 
384
void StoryText::selectAll()
385
{
386
        StoryText* that = const_cast<StoryText *>(this);
387
        for (int i=0; i < length(); ++i)
388
                that->at(i)->cselect = true;
389
 
390
        selFirst = 0;
391
        selLast = length() - 1;
392
}
393
 
394
void StoryText::deselectAll()
395
{
396
        StoryText* that = const_cast<StoryText *>(this);
397
        for (int i=0; i < length(); ++i)
398
                that->at(i)->cselect = false;
399
 
400
        selFirst = 0;
401
        selLast = -1;
402
}
403
 
404
void StoryText::removeSelection()
405
{
406
        if (selFirst > selLast)
407
                return;
408
 
409
        assert( selFirst >= 0 );
410
        assert( selLast < length() );
411
 
412
        removeChars(selFirst, selLast - selFirst+1);
413
        deselectAll();
414
}
415
 
416
 
417
 
418
void StoryText::invalidateObject(const PageItem * embedded)
419
{
420
}
421
 
422
void StoryText::invalidateLayout()
423
{
424
}
425
 
426
void StoryText::invalidateAll()
427
{
428
}
429
 
4749 avox 430
void StoryText::invalidate(int firstitem, int lastitem)
4669 avox 431
{
432
}
433
 
434
 
435
// physical view
436
 
437
/*
438
void StoryText::validate()
439
{
440
        static bool withinValidate = false;
441
 
442
        assert( !withinValidate );
443
        withinValidate = true;
444
 
445
        withinValidate = false;
446
}
447
*/
448
 
449
int StoryText::screenToPosition(FPoint coord) const
450
{
451
//FIXME:NLS     
452
        //FIXME: should be end of lastFrameItem
453
        return length();
454
}
455
 
456
 
457
FPoint StoryText::boundingBox(int pos, uint len) const
458
{
459
        return FPoint(); //FIXME
460
}
461
 
462
 
463
int StoryText::layout(int startItem)
464
{
465
        //FIXME:NLS
466
        return -1;
467
}
468
 
469
 
470
uint StoryText::nrOfItems() const
471
{
472
        return length();
473
}
474
 
475
 
476
ScText*  StoryText::item(uint itm)
477
{
478
        assert( static_cast<int>(itm) < length() );
479
        return const_cast<StoryText *>(this)->at(itm);
480
}
481
 
482
const QString StoryText::itemText(uint itm) const
483
{
484
 
485
        assert( static_cast<int>(itm) < length() );
486
 
487
        return text(itm, 1);
488
}
489
 
490
 
491
const CharStyle StoryText::itemStyle(uint itm) const
492
{
493
        assert( static_cast<int>(itm) < length() );
494
 
495
        return charStyle(itm);
496
}
497
 
498
 
499
int StoryText::startOfItem(uint itm) const
500
{
501
        assert( static_cast<int>(itm) < length() );
502
 
503
        return itm;
504
}
505
 
506
int StoryText::endOfItem(uint itm) const
507
{
508
        assert( static_cast<int>(itm) < length() );
509
 
510
        return itm + 1;
511
}
512