Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
8175 avox 1
/*
2
 For general Scribus (>=1.3.2) copyright and licensing information please refer
3
 to the COPYING file provided with the program. Following this notice may exist
4
 a copyright and/or license notice that predates the release of Scribus 1.3.2
5
 for which a new license (GPL+exception) is in place.
6
 */
7
/***************************************************************************
8
pageitem.cpp  -  description
9
-------------------
10
    begin                : Sat Apr 7 2001
11
    copyright            : (C) 2001 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
        ***************************************************************************/
14
 
15
/***************************************************************************
16
*                                                                         *
17
*   This program is free software; you can redistribute it and/or modify  *
18
*   it under the terms of the GNU General Public License as published by  *
19
*   the Free Software Foundation; either version 2 of the License, or     *
20
*   (at your option) any later version.                                   *
21
*                                                                         *
22
***************************************************************************/
23
 
24
 
4669 avox 25
#ifndef STORYTEXT_H_
26
#define STORYTEXT_H_
27
 
10223 cbradney 28
#include <QObject>
29
#include <QString>
10366 jghali 30
#include <QList>
7523 cbradney 31
#include <cassert>
4669 avox 32
 
33
//#include "text/paragraphlayout.h"
6144 avox 34
#include "text/frect.h"
8175 avox 35
#include "text/specialchars.h"
7970 cbradney 36
#include "sctextstruct.h"
37
#include "style.h"
8337 avox 38
#include "styles/charstyle.h"
39
#include "styles/paragraphstyle.h"
8194 avox 40
#include "desaxe/saxio.h"
4669 avox 41
 
42
#ifdef NLS_CONFORMANCE
43
#define NLS_PRIVATE private
44
#else
45
#define NLS_PRIVATE public
46
#endif
47
 
7970 cbradney 48
class CharStyle;
49
class ParagraphStyle;
50
class PageItem;
51
//class ScTextEngine;
52
//class ScScriptItem;
53
class ScribusDoc;
54
class ScText_Shared;
8455 avox 55
class ResourceCollection;
7970 cbradney 56
 
4669 avox 57
 
6144 avox 58
struct LineSpec
59
{
13161 malex 60
        qreal x;
61
        qreal y;
62
        qreal width;
63
        qreal ascent;
64
        qreal descent;
13211 jghali 65
        qreal colLeft;
6144 avox 66
 
67
        int firstItem;
68
        int lastItem;
13161 malex 69
        qreal naturalWidth;
6144 avox 70
};
71
 
4669 avox 72
/**
73
 * This class holds the text of a Scribus textframe and pointers to its
74
 * styles and embedded objects.
75
 *
76
 * The logical view of the text consists of a sequence of Unicode chars.
77
 * Partition objects keep track of the positions of style changes,
78
 * paragraph ends and embedded objects.
79
 *
80
 * The physical view consists of a sequence of ScriptItems. Each ScriptItem
81
 * corresponds to a subsequence of Unicode chars in the original sequence
82
 * and associates this with an array of glyph indices. Metrics information
83
 * give the physical position of the ScriptItem in the textframe and its
84
 * bounding box. For each glyph there's also its advance and the relative
85
 * offsets to its basepoint. Other information in the ScriptItem is only
86
 * used by the layouter.
87
 */
8194 avox 88
class SCRIBUS_API StoryText : public QObject, public SaxIO
7953 cbradney 89
{
7942 avox 90
        Q_OBJECT
91
 
4669 avox 92
 public:
17408 fschmid 93
        StoryText(ScribusDoc *doc);
6144 avox 94
        StoryText();
4669 avox 95
        StoryText(const StoryText & other);
96
        StoryText& operator= (const StoryText & other);
97
        virtual ~StoryText();
17408 fschmid 98
        void setDoc(ScribusDoc *docin);
8266 avox 99
 
100
        static const Xml_string saxxDefaultElem;
8834 cbradney 101
        static void  desaxeRules(const Xml_string& prefixPattern, desaxe::Digester& ruleset, Xml_string elemtag = saxxDefaultElem);
8266 avox 102
 
8800 jghali 103
        virtual void saxx(SaxHandler& handler, const Xml_string& elemtag) const;
8266 avox 104
        virtual void saxx(SaxHandler& handler)                     const { saxx(handler, saxxDefaultElem); }
105
 
16639 jghali 106
        int  cursorPosition() const;
107
        void setCursorPosition(int pos, bool relative = false);
108
        void normalizeCursorPosition();
109
        int  normalizedCursorPosition();
110
 
4669 avox 111
        void clear();
6144 avox 112
        StoryText copy() const;
17501 craig 113
 
114
        // Add, change, replace
16639 jghali 115
        // Insert chars from another StoryText object at current cursor position
16626 jghali 116
        void insert(const StoryText& other, bool onlySelection = false);
16639 jghali 117
        // Insert chars from another StoryText object at specific position
6887 avox 118
        void insert(int pos, const StoryText& other, bool onlySelection = false);
16639 jghali 119
        // Append chars from another StoryText object
6887 avox 120
        void append(const StoryText& other) { insert(length(), other, false); }
16639 jghali 121
        // Remove len chars at specific position
4669 avox 122
        void removeChars(int pos, uint len);
16639 jghali 123
        // Insert chars at current cursor position
16626 jghali 124
        void insertChars(QString txt, bool applyNeighbourStyle = false);
16639 jghali 125
        // Insert chars ar specific position
9645 avox 126
        void insertChars(int pos, QString txt, bool applyNeighbourStyle = false);
16639 jghali 127
        // Insert inline object at current cursor position
17407 fschmid 128
        void insertObject(int obj);
16639 jghali 129
        // Insert object at specific position
17407 fschmid 130
        void insertObject(int pos, int obj);
4669 avox 131
        void replaceChar(int pos, QChar ch);
17501 craig 132
        // Replaced a word, and return the difference in length between old and new
133
        int replaceWord(int pos, QString newWord);
17407 fschmid 134
        void replaceObject(int pos, int obj);
4669 avox 135
 
5559 avox 136
        void hyphenateWord(int pos, uint len, char* hyphens);
137
 
4669 avox 138
        int length() const;
16639 jghali 139
        // Get char at current cursor position
16626 jghali 140
        QChar   text() const;
16639 jghali 141
        // Get char at specific position
16626 jghali 142
        QChar   text(int pos) const;
16639 jghali 143
        // Get text with len chars at specific position
4669 avox 144
        QString text(int pos, uint len) const;
17501 craig 145
        //Get sentence at any position within it
146
        QString sentence(int pos, int &posn);
16639 jghali 147
        // Get word at specific position
15805 craig 148
        QString wordAt(int pos) const;
16600 jghali 149
 
150
        bool hasObject(int pos) const;
4669 avox 151
        PageItem* object(int pos) const;
5559 avox 152
 
153
        int nextCharPos(int c);
154
        int prevCharPos(int c);
155
        int nextWordPos(int c);
156
        int prevWordPos(int c);
13161 malex 157
        int nextLinePos(int c, qreal oldX);
158
        int prevLinePos(int c, qreal oldX);
5559 avox 159
        int nextFramePos(int c);
160
        int prevFramePos(int c);
161
 
16639 jghali 162
        // Get charstyle at current cursor position
16626 jghali 163
        const CharStyle& charStyle() const;
16639 jghali 164
        // Get charstyle at specific position
4669 avox 165
        const CharStyle& charStyle(int pos) const;
16639 jghali 166
        // Get paragraph style at current cursor position
167
        const ParagraphStyle& paragraphStyle() const;
168
        // Get paragraph style at specific position
5346 mrdocs 169
        const ParagraphStyle& paragraphStyle(int pos) const;
5559 avox 170
        const ParagraphStyle& defaultStyle() const;
171
        void setDefaultStyle(const ParagraphStyle& style);
6733 avox 172
        void setCharStyle(int pos, uint len, const CharStyle& style);
173
        void setStyle(int pos, const ParagraphStyle& style);
5721 avox 174
        void applyCharStyle(int pos, uint len, const CharStyle& style);
13290 jghali 175
        void applyStyle(int pos, const ParagraphStyle& style, bool rmDirectFormatting = false);
5773 avox 176
        void eraseCharStyle(int pos, uint len, const CharStyle& style);
177
        void eraseStyle(int pos, const ParagraphStyle& style);
7442 avox 178
        void replaceStyles(QMap<QString,QString> newNameForOld);
179
        void replaceCharStyles(QMap<QString,QString> newNameForOld);
16681 jghali 180
 
181
        // Cleanup legacy formatting for whole story, ie remove direct
182
        // formatting for parameters already set at paragraph level
183
        void fixLegacyFormatting();
7442 avox 184
 
16681 jghali 185
        // Cleanup legacy formatting for paragraph at position pos
186
        void fixLegacyFormatting(int pos);
187
 
8455 avox 188
        void getNamedResources(ResourceCollection& lists) const;
189
        void replaceNamedResources(ResourceCollection& newNames);
190
 
4669 avox 191
        uint nrOfParagraphs() const;
16626 jghali 192
        int startOfParagraph() const;
4669 avox 193
        int startOfParagraph(uint index) const;
16626 jghali 194
        int endOfParagraph() const;
4669 avox 195
        int endOfParagraph(uint index) const;
16626 jghali 196
        uint nrOfParagraph() const;
16069 craig 197
        uint nrOfParagraph(int pos) const;
4669 avox 198
 
199
        uint nrOfRuns() const;
200
        int startOfRun(uint index) const;
201
        int endOfRun(uint index) const;
202
 
5184 avox 203
// positioning
204
        int nextChar(int pos);
205
        int prevChar(int pos);
206
        int nextWord(int pos);
207
        int prevWord(int pos);
17501 craig 208
        int endOfWord(int pos) const;
5184 avox 209
        int nextSentence(int pos);
210
        int prevSentence(int pos);
211
        int nextParagraph(int pos);
212
        int prevParagraph(int pos);
213
 
214
// these need valid layout:
215
 
216
        int startOfLine(int pos);
217
        int endOfLine(int pos);
7501 avox 218
        int prevLine(int pos);
219
        int nextLine(int pos);
5184 avox 220
        int startOfFrame(int pos);
221
        int endOfFrame(int pos);
222
 
4669 avox 223
// selection
224
 
225
        void selectAll();
226
        void deselectAll();
227
        void removeSelection();
13054 pierre 228
        void extendSelection(int oldPos, int newPos);
229
        int selectWord(int pos);
230
        void select(int pos, uint len, bool on = true);
4669 avox 231
        bool selected(int pos) const;
232
        int startOfSelection() const;
233
        int endOfSelection() const;
234
        int lengthOfSelection() const;
235
 
236
 
237
//  when physical view doesn't match logical view any more:
238
 
239
        /// call this if the shape of an embedded object changes (redos layout)
240
        void invalidateObject(const PageItem* embedded);
241
        /// call this if the shape of the paragraph changes (redos layout)
242
        void invalidateLayout();
7942 avox 243
 
244
public slots:
245
        /// call this if some logical style changes (redos shaping and layout)
4669 avox 246
        void invalidateAll();
247
 
13148 pierre 248
        signals:
249
                void changed();
4669 avox 250
 
7942 avox 251
public:
4669 avox 252
// physical view
253
 
5184 avox 254
        bool overflows() const;
4669 avox 255
        /// layouts the text -- FIXME: better interface for this
256
        int layout(int startItem);
257
        uint nrOfItems() const;
7442 avox 258
//private:
4669 avox 259
        ScText * item(uint index);
6144 avox 260
        const ScText * item(uint index) const;
7442 avox 261
public:
262
        ScText * item_p(uint index) { return item(index); }
4669 avox 263
//      void bidiReorder(uint firstItem, uint lastItem, uint indices[]) const;
264
        /** returns the Unicode string which belongs to this ScScriptItem */
265
        const QString itemText(uint index) const;
266
        /** returns the CharStyle which belongs to this ScScriptItem */
267
        const CharStyle itemStyle(uint index) const;
268
        /// returns the character postion at the start of this item
269
        int startOfItem(uint index) const;
270
        /// returns the character position after this item
271
        int endOfItem(uint index) const;
272
//      const ScTextEngine * engineForRun(uint index) const;
273
//      const ScTextEngine * engineForItem(uint index) const;
274
 
275
//      ParagraphLayout layouter;
276
 
277
        int screenToPosition(FPoint coord) const;
6144 avox 278
        FRect  boundingBox(int pos, uint len = 1) const;
4669 avox 279
 
8452 jghali 280
        uint lines() const { return (uint) m_lines.count(); }
7501 avox 281
 
6144 avox 282
        LineSpec line(uint i) const { return m_lines[i]; }
283
 
7501 avox 284
        void appendLine(const LineSpec& ls)
285
        {
7521 avox 286
                assert( ls.firstItem >= 0 );
287
                assert( ls.firstItem < length() );
288
                assert( ls.lastItem >= 0 && ls.firstItem - ls.lastItem < 1 );
289
                assert( ls.lastItem < length() );
7501 avox 290
                m_lines.append(ls);
291
                if (lastFrameItem < firstFrameItem) {
292
                        firstFrameItem = ls.firstItem;
293
                        lastFrameItem = ls.lastItem;
294
                }
295
                else {
8562 jghali 296
                        firstFrameItem = qMin(firstFrameItem, ls.firstItem);
297
                        lastFrameItem = qMax(lastFrameItem, ls.lastItem);
7501 avox 298
                }
299
        }
16840 jghali 300
 
301
        // Remove the last line from the list. Used when we need to backtrack on the layouting.
302
        void removeLastLine ()
303
        {
304
                if (m_lines.isEmpty()) return;
305
                LineSpec last = m_lines.takeLast ();
306
                if (m_lines.isEmpty()) {
307
                        clearLines();
308
                        return;
309
                }
310
                // fix lastFrameItem
311
                if (lastFrameItem != last.lastItem) return;
312
                lastFrameItem = m_lines.last().lastItem;
313
        }
314
 
7501 avox 315
        void clearLines()
316
        {
317
                m_lines.clear();
318
                firstFrameItem = 0;
319
                lastFrameItem = -1;
320
        }
321
 
322
        int firstInFrame() { return firstFrameItem; }
323
        int lastInFrame() { return lastFrameItem; }
324
 
325
private:
4669 avox 326
        ScribusDoc * doc;
327
        int selFirst, selLast;
328
        int firstFrameItem, lastFrameItem;
10366 jghali 329
        QList<LineSpec> m_lines;
6144 avox 330
        bool m_validLayout;
13161 malex 331
        qreal m_magicX;
7501 avox 332
        int m_lastMagicPos;
12093 jghali 333
 
15009 jghali 334
        QString textWithSoftHyphens (int pos, uint len) const;
335
        void    insertCharsWithSoftHyphens(int pos, QString txt, bool applyNeighbourStyle = false);
6144 avox 336
 
4669 avox 337
        /// mark these runs as invalid, ie. need itemize and shaping
338
        void invalidate(int firstRun, int lastRun);
8175 avox 339
        void removeParSep(int pos);
340
        void insertParSep(int pos);
341
 
342
        //      int splitRun(int pos);
4669 avox 343
 
344
        /** bring physical view in sync with logical one.
345
         *  This gets called automatically from all physical view methods
346
         */
347
//      void validate();
348
        /// private data structure
5721 avox 349
        ScText_Shared * d;
4669 avox 350
        /// gives the physical view which was last given to the layouter
351
//      uint layouterVersion;
352
        /// is true after layout() has been exercised
353
//      bool layouterValid;
354
 };
7970 cbradney 355
 
356
 
4669 avox 357
#endif /*STORYTEXT_H_*/