Subversion Repositories Scribus

Rev

Rev 5776 | Rev 5778 | 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
 
12
QChar SpecialChars::OBJECT     = QChar(25);
13
QChar SpecialChars::TAB        = QChar(9);
14
QChar SpecialChars::PARSEP     = QChar(13);
15
QChar SpecialChars::LINEBREAK  = QChar(28);
16
QChar SpecialChars::COLBREAK   = QChar(26);
17
QChar SpecialChars::FRAMEBREAK = QChar(27);
18
QChar SpecialChars::SHYPHEN;
19
QChar SpecialChars::NBHYPHEN   = QChar(24);
20
QChar SpecialChars::NBSPACE    = QChar(29);
21
QChar SpecialChars::ZWNBSPACE;
22
QChar SpecialChars::ZWSPACE;
23
//QChar SpecialChars::SPACE      = QChar(32);
24
 
5753 jghali 25
class ScText_Shared : public QPtrList<ScText>
26
{
27
public:
5721 avox 28
        ParagraphStyle defaultStyle;
29
        uint refs;
5722 avox 30
        uint len;
31
        ScText_Shared() : QPtrList<ScText>(), defaultStyle(), refs(1), len(0)
5721 avox 32
        {
33
                setAutoDelete(true);
34
        }
35
};
4669 avox 36
 
37
 
38
StoryText::StoryText(ScribusDoc * doc_) : doc(doc_)
39
{
5721 avox 40
        d = new ScText_Shared();
4669 avox 41
        clear();
42
}
43
 
5721 avox 44
StoryText::StoryText(const StoryText & other) : doc(other.doc)
4669 avox 45
{
5721 avox 46
        d = other.d;
47
        d->refs++;
48
 
4706 avox 49
        selFirst = 0;
50
        selLast = -1;
51
 
52
        firstFrameItem = 0;
53
        lastFrameItem = -1;
5721 avox 54
 
4669 avox 55
        invalidateLayout();
56
}
57
 
58
StoryText::~StoryText()
59
{
5721 avox 60
        d->refs--;
61
        if (d->refs == 0) {
5773 avox 62
                for (ScText *it = d->first(); it != 0; it = d->next())
63
                {
64
                        if ((it->ch[0] == SpecialChars::OBJECT) && (it->cembedded != 0)) {
65
                                doc->FrameItems.remove(it->cembedded);
66
                                delete it->cembedded;
67
                                it->cembedded = 0;
68
                        }
69
                        else if ((it->ch[0] == SpecialChars::PARSEP)) {
70
                                delete it->parstyle;
71
                                it->parstyle = 0;
72
                        }
73
                }
74
 
75
                d->clear();
76
                d->len = 0;
5721 avox 77
                delete d;
78
        }      
4669 avox 79
}
80
 
81
StoryText& StoryText::operator= (const StoryText & other)
82
{
5721 avox 83
        d->refs--;
84
        if (d->refs == 0) {
85
                clear();
86
                delete d;
87
        }
88
 
89
        doc = other.doc;
90
        d = other.d;
91
        d->refs++;
92
 
4706 avox 93
        selFirst = 0;
94
        selLast = -1;
95
 
96
        firstFrameItem = 0;
97
        lastFrameItem = -1;
98
 
4669 avox 99
        invalidateLayout();
100
        return *this;
101
}
102
 
103
 
104
void StoryText::clear()
105
{
106
        selFirst = 0;
107
        selLast = -1;
108
 
109
        firstFrameItem = 0;
110
        lastFrameItem = -1;
111
 
5721 avox 112
        d->defaultStyle = ParagraphStyle();
113
        d->defaultStyle.setParent( & doc->docParagraphStyles[0]);
5777 avox 114
        d->defaultStyle.charStyle().setParent( & doc->docParagraphStyles[0].charStyle());
5569 avox 115
 
5721 avox 116
        for (ScText *it = d->first(); it != 0; it = d->next())
4749 avox 117
        {
5721 avox 118
                if ((it->ch[0] == SpecialChars::OBJECT) && (it->cembedded != 0)) {
4749 avox 119
                        doc->FrameItems.remove(it->cembedded);
5184 avox 120
                        delete it->cembedded;
4749 avox 121
                        it->cembedded = 0;
122
                }
5721 avox 123
                else if ((it->ch[0] == SpecialChars::PARSEP)) {
124
                        delete it->parstyle;
125
                        it->parstyle = 0;
126
                }
4749 avox 127
        }
128
 
5721 avox 129
        d->clear();
5722 avox 130
        d->len = 0;
4669 avox 131
        invalidateAll();
132
}
133
 
134
 
5732 avox 135
void StoryText::append(const StoryText& other)
136
{
137
        CharStyle cstyle(charStyle(length()));
138
        ParagraphStyle pstyle(paragraphStyle(length()));
139
        int cstyleStart = length();
140
        for (int i=0; i < other.length(); ++i) {
141
                if (other.charStyle(i) == cstyle)
142
                        continue;
143
                int pos = length();
144
                int len = i - cstyleStart;
145
                if (len > 0) {
146
                        insertChars(length(), other.text(cstyleStart, len));
147
                        applyCharStyle(pos, len, cstyle);
148
                }
149
                if (other.text(i) == SpecialChars::PARSEP) {
150
                        insertChars(pos+len, SpecialChars::PARSEP);
151
                        applyStyle(pos+len, other.paragraphStyle(i));
152
                        cstyleStart = i+1;
153
                }
154
                else {
155
                        cstyle = other.charStyle(i);
156
                        cstyleStart = i;
157
                }
158
        }
159
        int pos = length();
160
        int len = other.length() - cstyleStart;
161
        if (len > 0) {
162
                insertChars(length(), other.text(cstyleStart, len));
163
                applyCharStyle(pos, len, cstyle);
164
        }
165
        setDefaultStyle(other.defaultStyle());
166
}
167
 
168
 
169
 
5721 avox 170
/**
171
     A CharStyle's parent is usually the default paragraphstyle, unless explicitly
172
     changed. This routines makes sure that all parent pointers to the default
173
     paragraphStyle are up-to-date
174
 */
5776 avox 175
static void replaceParentStyle(StoryText* that, int pos, const CharStyle* oldP, const CharStyle* newP)
5721 avox 176
{
177
        for(int i = pos-1; i >= 0; ++i) {
178
                ScText* it = that->item(i);
179
                if (it->ch[0] == SpecialChars::PARSEP)
180
                        break;
181
                else if (it->parent() == NULL || it->parent() == oldP)
182
                        it->setParent(newP);
183
        }      
184
}
185
 
186
 
187
/**
188
    Make sure that the paragraph CharStyle's point to the new ParagraphStyle
189
 */
190
static void insertParSep(StoryText* that, int pos)
191
{
192
        ScText* it = that->item(pos);
5776 avox 193
        const ParagraphStyle& pstyle(that->paragraphStyle(pos));
194
        it->parstyle = new ParagraphStyle(pstyle);
195
        const CharStyle* oldP = & pstyle.charStyle();
196
        const CharStyle* newP = & it->parstyle->charStyle();
5721 avox 197
        replaceParentStyle(that, pos, oldP, newP);
198
}
199
/**
200
     need to remove the ParagraphStyle structure and replace all pointers
201
     to it...
202
 */
203
static void removeParSep(StoryText* that, int pos)
204
{
205
        ScText* it = that->item(pos);
206
        if (it->parstyle) {
5776 avox 207
                const CharStyle* oldP = & it->parstyle->charStyle();
208
                const CharStyle* newP = & that->paragraphStyle(pos+1).charStyle();
5721 avox 209
                replaceParentStyle(that, pos, oldP, newP);
210
                delete oldP;
211
        }
212
}
213
 
4669 avox 214
void StoryText::removeChars(int pos, uint len)
215
{
216
        if (pos < 0)
217
                pos += length();
218
 
219
        assert( len > 0 );
220
        assert( pos >= 0 );
221
        assert( pos + static_cast<int>(len) <= length() );
4749 avox 222
 
5751 avox 223
        for ( int i=pos + static_cast<int>(len) - 1; i >= pos; --i )
4749 avox 224
        {
5721 avox 225
                ScText *it = d->at(i);
226
                if ((it->ch[0] == SpecialChars::OBJECT) && (it->cembedded != 0)) {
4749 avox 227
                        doc->FrameItems.remove(it->cembedded);
228
                        it->cembedded = 0;
229
                }
5721 avox 230
                else if ((it->ch[0] == SpecialChars::PARSEP)) {
231
                        removeParSep(this, i);
232
                }
5751 avox 233
//              qDebug("remove char %d at %d", it->ch[0].unicode(), i);
5721 avox 234
                d->take(i);
5722 avox 235
                d->len--;
4749 avox 236
                delete it;
237
        }
5722 avox 238
 
239
        d->len = d->count();
4749 avox 240
        invalidate(pos, -1);
4669 avox 241
}
242
 
4749 avox 243
void StoryText::insertChars(int pos, QString txt) //, const CharStyle&
4669 avox 244
{
245
        if (pos < 0)
246
                pos += length();
247
 
248
        assert(pos >= 0);
249
        assert(pos <= length());
4749 avox 250
 
5365 avox 251
        if (txt.length() == 0)
252
                return;
253
 
5569 avox 254
        const CharStyle style = pos == 0 ? defaultStyle().charStyle() : charStyle(pos - 1);
5691 avox 255
        assert(style.font() != NULL);
5291 avox 256
 
5721 avox 257
//      const int paraStyle = pos == 0 ? 0 : at(pos - 1)->cab;
4749 avox 258
 
4752 avox 259
        for (uint i = 0; i < txt.length(); ++i) {
4749 avox 260
                ScText * item = new ScText();
261
                item->ch= txt.mid(i, 1);
262
                *static_cast<CharStyle *>(item) = style;
5721 avox 263
                d->insert(pos + i, item);
5722 avox 264
                d->len++;
5721 avox 265
                if (item->ch[0] == SpecialChars::PARSEP) {
266
//                      qDebug(QString("new PARSEP %2 at %1").arg(pos).arg(paragraphStyle(pos).name()));
267
                        insertParSep(this, pos + i);
268
                }
4749 avox 269
        }
270
 
5722 avox 271
        d->len = d->count();
4669 avox 272
        invalidate(pos, pos + txt.length());
273
}
274
 
275
void StoryText::replaceChar(int pos, QChar ch)
276
{
277
        if (pos < 0)
278
                pos += length();
279
 
280
        assert(pos >= 0);
281
        assert(pos < length());
282
 
5721 avox 283
        ScText* item = d->at(pos);
284
        if (item->ch[0] == ch)
285
                return;
286
 
287
        if (d->at(pos)->ch[0] == SpecialChars::PARSEP) {
288
                removeParSep(this, pos);
289
        }
290
        item->ch = ch;
291
        if (d->at(pos)->ch[0] == SpecialChars::PARSEP) {
292
                insertParSep(this, pos);
293
        }
294
 
4669 avox 295
        invalidate(pos, pos + 1);
296
}
297
 
5559 avox 298
void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
299
{
300
        assert(pos >= 0);
5691 avox 301
        assert(pos + signed(len) <= length());
5559 avox 302
 
5691 avox 303
        for (int i=pos; i < pos+signed(len); ++i)
5569 avox 304
                if(hyphens && hyphens[i] & 1)
5721 avox 305
                        d->at(i)->setEffects(d->at(i)->effects() | ScStyle_HyphenationPossible);
5559 avox 306
                else
5721 avox 307
                        d->at(i)->setEffects(d->at(i)->effects() & ~ScStyle_HyphenationPossible);
5559 avox 308
 
309
        invalidate(pos, pos + len);
310
}
311
 
4669 avox 312
void StoryText::insertObject(int pos, PageItem* ob)
313
{
314
        if (pos < 0)
315
                pos += length();
316
 
317
        insertChars(pos, SpecialChars::OBJECT);
5721 avox 318
        const_cast<StoryText *>(this)->d->at(pos)->cembedded = ob;
4669 avox 319
}
320
 
321
 
322
int StoryText::length() const
323
{
5722 avox 324
        return d->len;
4669 avox 325
}
326
 
327
QChar StoryText::text(int pos) const
328
{
329
        if (pos < 0)
330
                pos += length();
331
 
332
        assert(pos >= 0);
333
        assert(pos < length());
334
 
5721 avox 335
        return const_cast<StoryText *>(this)->d->at(pos)->ch[0];
4669 avox 336
}
337
 
338
QString StoryText::text(int pos, uint len) const
339
{
340
        if (pos < 0)
341
                pos += length();
342
 
343
        assert(len > 0);
344
        assert(pos >= 0);
345
        assert(pos + signed(len) <= length());
346
 
347
        QString result;
5721 avox 348
        StoryText* that(const_cast<StoryText*>(this));
349
        that->d->at(pos);
350
        for (int i = pos; i < pos+signed(len); ++i) {
351
                result += that->d->current()->ch;
352
                that->d->next();
353
        }
4669 avox 354
 
355
        return result;
356
}
357
 
358
PageItem* StoryText::object(int pos) const
359
{
360
        if (pos < 0)
361
                pos += length();
362
 
363
        assert(pos >= 0);
364
        assert(pos < length());
365
 
366
        StoryText* that = const_cast<StoryText *>(this);       
5721 avox 367
        if (that->d->at(pos)->cembedded != NULL)
368
                return that->d->at(pos)->cembedded;
4669 avox 369
        else
370
                return NULL;
371
}
372
 
373
 
374
const CharStyle & StoryText::charStyle(int pos) const
375
{
376
        if (pos < 0)
377
                pos += length();
378
 
379
        assert(pos >= 0);
5732 avox 380
        assert(pos <= length());
4669 avox 381
 
5732 avox 382
        if (length() == 0)
383
                return defaultStyle().charStyle();
384
        else if (pos == length())
385
                --pos;
386
 
4669 avox 387
        StoryText* that = const_cast<StoryText *>(this);
5721 avox 388
        return dynamic_cast<const CharStyle &> (*that->d->at(pos));
4669 avox 389
}
390
 
391
const ParagraphStyle & StoryText::paragraphStyle(int pos) const
392
{
393
        if (pos < 0)
394
                pos += length();
395
 
396
        assert(pos >= 0);
5721 avox 397
        assert(pos <= length());
4669 avox 398
 
5192 avox 399
        StoryText * that = const_cast<StoryText *> (this);
5721 avox 400
//      assert( that->at(pos)->cab >= 0 );
401
//      assert( that->at(pos)->cab < doc->docParagraphStyles.count() );
402
//      return doc->docParagraphStyles[that->at(pos)->cab];
403
 
404
        that->d->at(pos);
405
        while (pos < length() && that->d->current()->ch[0] != SpecialChars::PARSEP) {
406
                ++pos;
407
                that->d->next();
408
        }
409
        if (pos == length())
410
                return defaultStyle();
411
        else if ( !that->d->current()->parstyle ) {
5751 avox 412
                qDebug(QString("using default parstyle at %1").arg(pos));
5721 avox 413
                that->d->current()->parstyle = new ParagraphStyle(defaultStyle());
414
        }
415
        return *that->d->current()->parstyle;
4669 avox 416
}
417
 
5559 avox 418
const ParagraphStyle& StoryText::defaultStyle() const
419
{
5721 avox 420
        return d->defaultStyle;
5559 avox 421
}
422
 
5569 avox 423
 
424
void StoryText::setDefaultStyle(const ParagraphStyle& style)
425
{
5721 avox 426
        d->defaultStyle = style;
427
        if (!d->defaultStyle.parent())
428
                d->defaultStyle.setParent( & doc->docParagraphStyles[0] );
5777 avox 429
        if (!d->defaultStyle.charStyle().parent())
430
                d->defaultStyle.charStyle().setParent( & doc->docParagraphStyles[0].charStyle() );
5569 avox 431
}
432
 
433
 
434
 
5721 avox 435
void StoryText::applyCharStyle(int pos, uint len, const CharStyle& style )
4669 avox 436
{
437
        if (pos < 0)
438
                pos += length();
439
 
440
        assert(pos >= 0);
441
        assert(pos + signed(len) <= length());
442
 
443
        if (len == 0)
444
                return;
445
 
5721 avox 446
        d->at(pos);
447
        for (uint i=pos; i < pos+len; ++i) {
448
                d->current()->applyCharStyle(style);
449
                d->next();
450
        }
4669 avox 451
 
452
        invalidate(pos, pos + len);
453
}
454
 
5773 avox 455
 
456
 
457
void StoryText::eraseCharStyle(int pos, uint len, const CharStyle& style )
458
{
459
        if (pos < 0)
460
                pos += length();
461
 
462
        assert(pos >= 0);
463
        assert(pos + signed(len) <= length());
464
 
465
        if (len == 0)
466
                return;
467
 
468
        d->at(pos);
469
        for (uint i=pos; i < pos+len; ++i) {
470
                d->current()->eraseCharStyle(style);
471
                d->next();
472
        }
473
 
474
        invalidate(pos, pos + len);
475
}
476
 
477
 
4669 avox 478
void StoryText::applyStyle(int pos, const ParagraphStyle& style)
479
{
480
        if (pos < 0)
481
                pos += length();
482
 
483
        assert(pos >= 0);
5721 avox 484
        assert(pos <= length());
4669 avox 485
 
5721 avox 486
/*      int paraStyle = QMAX(0, findParagraphStyle(doc, style)); //FIXME:NLS
5184 avox 487
        int i = pos - 1;
5721 avox 488
        if (length() > 0) {
489
                // find start of para
490
                while (i >= 0 && at(i)->ch[0] != SpecialChars::PARSEP) {
491
                        --i;
492
                }
493
                // set 'cab' field
494
                do {
495
                        ++i;
496
                        at(i)->cab = paraStyle;
497
                }
498
                while (i+1 < length() && d->at(i)->ch[0] != SpecialChars::PARSEP);
499
        }
500
        ++i; */
501
 
502
        int i = pos;
503
        while (i < length() && d->at(i)->ch[0] != SpecialChars::PARSEP) {
5184 avox 504
                ++i;
505
        }
5721 avox 506
        if (i < length()) {
507
                if (!d->at(i)->parstyle) {
508
                        qDebug(QString("PARSEP without style at pos %1").arg(i));
509
                        d->at(i)->parstyle = new ParagraphStyle(defaultStyle());
510
                }
511
//              qDebug(QString("applying parstyle %2 at %1 for %3").arg(i).arg(paragraphStyle(pos).name()).arg(pos));
512
                d->at(i)->parstyle->applyStyle(style);
513
                if (!d->at(i)->parstyle->parent()) {
514
                        d->at(i)->parstyle->setParent( & d->defaultStyle );
515
                }
5777 avox 516
                if (!d->at(i)->parstyle->charStyle().parent()) {
517
                        d->at(i)->parstyle->charStyle().setParent( & d->defaultStyle.charStyle() );
518
                }
5721 avox 519
        }
520
        else {
521
                // not happy about this but inserting a new PARSEP makes more trouble
522
//              qDebug(QString("applying parstyle %1 as defaultstyle for %2").arg(paragraphStyle(pos).name()).arg(pos));
523
                d->defaultStyle.applyStyle(style);
524
        }
4669 avox 525
}
526
 
5773 avox 527
void StoryText::eraseStyle(int pos, const ParagraphStyle& style)
528
{
529
        if (pos < 0)
530
                pos += length();
531
 
532
        assert(pos >= 0);
533
        assert(pos <= length());
534
 
535
        int i = pos;
536
        while (i < length() && d->at(i)->ch[0] != SpecialChars::PARSEP) {
537
                ++i;
538
        }
539
        if (i < length()) {
540
                if (!d->at(i)->parstyle) {
541
                        qDebug(QString("PARSEP without style at pos %1").arg(i));
542
                        d->at(i)->parstyle = new ParagraphStyle(defaultStyle());
543
                }
544
                //              qDebug(QString("applying parstyle %2 at %1 for %3").arg(i).arg(paragraphStyle(pos).name()).arg(pos));
545
                d->at(i)->parstyle->eraseStyle(style);
546
                if (!d->at(i)->parstyle->parent()) {
547
                        d->at(i)->parstyle->setParent( & d->defaultStyle );
548
                }
5777 avox 549
                if (!d->at(i)->parstyle->charStyle().parent()) {
550
                        d->at(i)->parstyle->charStyle().setParent( & d->defaultStyle.charStyle() );
551
                }
5773 avox 552
        }
553
        else {
554
                // not happy about this but inserting a new PARSEP makes more trouble
555
                //              qDebug(QString("applying parstyle %1 as defaultstyle for %2").arg(paragraphStyle(pos).name()).arg(pos));
556
                d->defaultStyle.eraseStyle(style);
557
        }
558
}
559
 
560
 
4669 avox 561
uint StoryText::nrOfParagraphs() const
562
{
563
        uint result = 0;
5721 avox 564
        StoryText* that = const_cast<StoryText *>(this);
565
        that->d->at(0);
566
        for (int i=0; i < length(); ++i) {
567
                if (that->d->current()->ch[0] == SpecialChars::PARSEP)
4669 avox 568
                        ++result;
5721 avox 569
                that->d->next();
570
        }
4669 avox 571
        return result;
572
}
573
 
574
int StoryText::startOfParagraph(uint index) const
575
{
576
        if (index == 0)
577
                return 0;
578
 
5184 avox 579
        StoryText* that = const_cast<StoryText *>(this);
5721 avox 580
        that->d->at(0);
581
        for (int i=0; i < length(); ++i) {
582
                if (that->d->current()->ch[0] == SpecialChars::PARSEP && ! --index)
4669 avox 583
                        return i + 1;
5721 avox 584
                that->d->next();
585
        }
4669 avox 586
        return -1;
587
}
588
 
589
int StoryText::endOfParagraph(uint index) const
590
{
591
        ++index;
5184 avox 592
        StoryText* that = const_cast<StoryText *>(this);
5721 avox 593
        that->d->at(0);
594
        for (int i=0; i < length(); ++i) {
595
                if (that->d->current()->ch[0] == SpecialChars::PARSEP && ! --index)
596
                        return i;
597
                that->d->next();
598
        }
4669 avox 599
        return length();
600
}
601
 
602
uint StoryText::nrOfRuns() const
603
{
5464 avox 604
        return length();
4669 avox 605
}
606
 
607
int StoryText::startOfRun(uint index) const
608
{
5464 avox 609
        return index;
4669 avox 610
}
611
 
612
int StoryText::endOfRun(uint index) const
613
{
5464 avox 614
        return index + 1;
4669 avox 615
}
616
 
617
 
618
// selection
619
 
620
int StoryText::startOfSelection() const
621
{
622
        return selFirst <= selLast? selFirst : 0;
623
}
624
 
625
int StoryText::endOfSelection() const
626
{
627
        return selFirst <= selLast? selLast + 1 : -1;
628
}
629
 
630
int StoryText::lengthOfSelection() const
631
{
632
        return selFirst <= selLast? selLast - selFirst + 1 : 0;
633
}
634
 
635
 
636
bool StoryText::selected(int pos) const
637
{
4749 avox 638
        return (selFirst <= pos && pos <= selLast)
5721 avox 639
//             || (pos >= 0 && pos < length() && const_cast<StoryText*>(this)->d->at(pos)->cselect)
640
        ;
4669 avox 641
}
642
 
643
void StoryText::select(int pos, uint len, bool on)
644
{
645
        if (pos < 0)
646
                pos += length();
647
 
648
        assert( pos >= 0 );
649
        assert( pos + signed(len) <= length() );
650
 
5751 avox 651
//      qDebug("old selection: %d - %d", selFirst, selLast);
652
 
5721 avox 653
//      StoryText* that = const_cast<StoryText *>(this);
654
//      for (int i=pos; i < pos+signed(len); ++i)
655
//              that->at(i)->cselect = on;
4669 avox 656
 
657
        if (on) {
658
                // extend if possible
659
                if (selected(pos - 1))
660
                        selLast = QMAX(selLast, pos + static_cast<int>(len) - 1);
661
                else if (selected(pos + len))
662
                        selFirst = QMIN(selFirst, pos);
663
                else {
664
                        selFirst = pos;
665
                        selLast = pos + len - 1;
666
                }
667
        }
668
        else {
669
                if (pos <= selFirst && selLast < pos + signed(len))
670
                        deselectAll();
671
                // shrink
672
                else if (!selected(pos - 1) && selected(pos + len - 1))
673
                        selFirst = pos + len;
674
                else if (selected(pos) && !selected(pos + len))
675
                        selLast = pos - 1;
676
                else if (selected(pos) || selected(pos + len - 1))
677
                        // Grr, deselection splits selection
678
                        selLast = pos - 1;
679
        }
5751 avox 680
 
681
//      qDebug("new selection: %d - %d", selFirst, selLast);
4669 avox 682
}
683
 
684
void StoryText::selectAll()
685
{
5721 avox 686
/*      StoryText* that = const_cast<StoryText *>(this);
687
        that->at(0);
688
        for (int i=0; i < length(); ++i) {
689
                that->current()->cselect = true;
690
                that->next();
691
        }
692
*/
4669 avox 693
        selFirst = 0;
694
        selLast = length() - 1;
695
}
696
 
697
void StoryText::deselectAll()
698
{
5721 avox 699
/*      StoryText* that = const_cast<StoryText *>(this);
700
        that->at(0);
701
        for (int i=0; i < length(); ++i) {
702
                that->current()->cselect = false;
703
                that->next();
704
        }
705
*/     
4669 avox 706
        selFirst = 0;
707
        selLast = -1;
708
}
709
 
710
void StoryText::removeSelection()
711
{
5751 avox 712
//      qDebug("removeSelection: %d - %d", selFirst, selLast);
4669 avox 713
        if (selFirst > selLast)
714
                return;
715
 
716
        assert( selFirst >= 0 );
717
        assert( selLast < length() );
718
 
719
        removeChars(selFirst, selLast - selFirst+1);
720
        deselectAll();
721
}
722
 
723
 
724
 
725
void StoryText::invalidateObject(const PageItem * embedded)
726
{
727
}
728
 
729
void StoryText::invalidateLayout()
730
{
731
}
732
 
733
void StoryText::invalidateAll()
734
{
735
}
736
 
4749 avox 737
void StoryText::invalidate(int firstitem, int lastitem)
4669 avox 738
{
739
}
740
 
741
 
742
// physical view
743
 
744
/*
745
void StoryText::validate()
746
{
747
        static bool withinValidate = false;
748
 
749
        assert( !withinValidate );
750
        withinValidate = true;
751
 
752
        withinValidate = false;
753
}
754
*/
755
 
756
int StoryText::screenToPosition(FPoint coord) const
757
{
758
//FIXME:NLS     
759
        //FIXME: should be end of lastFrameItem
760
        return length();
761
}
762
 
763
 
764
FPoint StoryText::boundingBox(int pos, uint len) const
765
{
766
        return FPoint(); //FIXME
767
}
768
 
769
 
770
int StoryText::layout(int startItem)
771
{
772
        //FIXME:NLS
773
        return -1;
774
}
775
 
776
 
777
uint StoryText::nrOfItems() const
778
{
779
        return length();
780
}
781
 
782
 
783
ScText*  StoryText::item(uint itm)
784
{
785
        assert( static_cast<int>(itm) < length() );
5721 avox 786
        return const_cast<StoryText *>(this)->d->at(itm);
4669 avox 787
}
788
 
789
const QString StoryText::itemText(uint itm) const
790
{
791
 
792
        assert( static_cast<int>(itm) < length() );
793
 
794
        return text(itm, 1);
795
}
796
 
797
 
798
const CharStyle StoryText::itemStyle(uint itm) const
799
{
800
        assert( static_cast<int>(itm) < length() );
801
 
802
        return charStyle(itm);
803
}
804
 
805
 
806
int StoryText::startOfItem(uint itm) const
807
{
808
        assert( static_cast<int>(itm) < length() );
809
 
810
        return itm;
811
}
812
 
813
int StoryText::endOfItem(uint itm) const
814
{
815
        assert( static_cast<int>(itm) < length() );
816
 
817
        return itm + 1;
818
}
819