Rev 24265 | 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 | |||
22463 | jghali | 28 | #include <cassert> |
10223 | cbradney | 29 | #include <QObject> |
30 | #include <QString> |
||
10366 | jghali | 31 | #include <QList> |
23660 | craig | 32 | #include <unicode/uversion.h> |
22463 | jghali | 33 | |
21563 | jghali | 34 | #include "itextsource.h" |
17826 | craig | 35 | #include "marks.h" |
6144 | avox | 36 | #include "text/frect.h" |
8175 | avox | 37 | #include "text/specialchars.h" |
7970 | cbradney | 38 | #include "sctextstruct.h" |
39 | #include "style.h" |
||
8337 | avox | 40 | #include "styles/charstyle.h" |
41 | #include "styles/paragraphstyle.h" |
||
8194 | avox | 42 | #include "desaxe/saxio.h" |
4669 | avox | 43 | |
7970 | cbradney | 44 | class CharStyle; |
45 | class ParagraphStyle; |
||
46 | class PageItem; |
||
24684 | jghali | 47 | class ResourceCollection; |
7970 | cbradney | 48 | class ScribusDoc; |
49 | class ScText_Shared; |
||
21563 | jghali | 50 | class ShapedTextCache; |
24684 | jghali | 51 | class TextNote; |
4669 | avox | 52 | |
23660 | craig | 53 | U_NAMESPACE_BEGIN |
54 | class BreakIterator; |
||
55 | U_NAMESPACE_END |
||
6144 | avox | 56 | |
4669 | avox | 57 | /** |
58 | * This class holds the text of a Scribus textframe and pointers to its |
||
59 | * styles and embedded objects. |
||
60 | * |
||
61 | * The logical view of the text consists of a sequence of Unicode chars. |
||
62 | * Partition objects keep track of the positions of style changes, |
||
63 | * paragraph ends and embedded objects. |
||
64 | * |
||
65 | * The physical view consists of a sequence of ScriptItems. Each ScriptItem |
||
66 | * corresponds to a subsequence of Unicode chars in the original sequence |
||
67 | * and associates this with an array of glyph indices. Metrics information |
||
68 | * give the physical position of the ScriptItem in the textframe and its |
||
69 | * bounding box. For each glyph there's also its advance and the relative |
||
70 | * offsets to its basepoint. Other information in the ScriptItem is only |
||
71 | * used by the layouter. |
||
72 | */ |
||
21563 | jghali | 73 | class SCRIBUS_API StoryText : public QObject, public SaxIO, public ITextSource |
7953 | cbradney | 74 | { |
7942 | avox | 75 | Q_OBJECT |
76 | |||
22993 | jghali | 77 | public: |
17408 | fschmid | 78 | StoryText(ScribusDoc *doc); |
22993 | jghali | 79 | StoryText(); |
80 | StoryText(const StoryText & other); |
||
81 | StoryText& operator= (const StoryText & other); |
||
82 | virtual ~StoryText(); |
||
23456 | jghali | 83 | |
84 | bool hasBulletOrNum() const; |
||
85 | bool hasTextMarks() const; |
||
86 | bool marksCountChanged() const; |
||
87 | void resetMarksCountChanged(); |
||
22993 | jghali | 88 | |
17408 | fschmid | 89 | void setDoc(ScribusDoc *docin); |
24265 | jghali | 90 | ScribusDoc* doc() const { return m_doc; } |
8266 | avox | 91 | |
92 | static const Xml_string saxxDefaultElem; |
||
8834 | cbradney | 93 | static void desaxeRules(const Xml_string& prefixPattern, desaxe::Digester& ruleset, Xml_string elemtag = saxxDefaultElem); |
8266 | avox | 94 | |
8800 | jghali | 95 | virtual void saxx(SaxHandler& handler, const Xml_string& elemtag) const; |
8266 | avox | 96 | virtual void saxx(SaxHandler& handler) const { saxx(handler, saxxDefaultElem); } |
97 | |||
16639 | jghali | 98 | int cursorPosition() const; |
99 | void setCursorPosition(int pos, bool relative = false); |
||
100 | void normalizeCursorPosition(); |
||
101 | int normalizedCursorPosition(); |
||
102 | |||
21563 | jghali | 103 | void moveCursorForward(); |
104 | void moveCursorBackward(); |
||
105 | void moveCursorLeft(); |
||
106 | void moveCursorRight(); |
||
107 | |||
108 | void moveCursorWordLeft(); |
||
109 | void moveCursorWordRight(); |
||
110 | |||
22993 | jghali | 111 | void clear(); |
6144 | avox | 112 | StoryText copy() const; |
17541 | jghali | 113 | |
114 | // Find text in story |
||
22127 | jghali | 115 | int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive, int* pLen = 0) const; |
17541 | jghali | 116 | int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; |
17501 | craig | 117 | |
118 | // Add, change, replace |
||
16639 | jghali | 119 | // Insert chars from another StoryText object at current cursor position |
16626 | jghali | 120 | void insert(const StoryText& other, bool onlySelection = false); |
16639 | jghali | 121 | // Insert chars from another StoryText object at specific position |
6887 | avox | 122 | void insert(int pos, const StoryText& other, bool onlySelection = false); |
16639 | jghali | 123 | // Append chars from another StoryText object |
6887 | avox | 124 | void append(const StoryText& other) { insert(length(), other, false); } |
16639 | jghali | 125 | // Remove len chars at specific position |
4669 | avox | 126 | void removeChars(int pos, uint len); |
18843 | fschmid | 127 | // Removes trailing empty paragraphs |
128 | void trim(); |
||
16639 | jghali | 129 | // Insert chars at current cursor position |
22635 | craig | 130 | void insertChars(const QString& txt, bool applyNeighbourStyle = false); |
16639 | jghali | 131 | // Insert chars ar specific position |
22295 | craig | 132 | void insertChars(int pos, const QString& txt, bool applyNeighbourStyle = false); |
16639 | jghali | 133 | // Insert inline object at current cursor position |
17407 | fschmid | 134 | void insertObject(int obj); |
16639 | jghali | 135 | // Insert object at specific position |
17407 | fschmid | 136 | void insertObject(int pos, int obj); |
17826 | craig | 137 | // Insert mark at cursor or specific position |
23456 | jghali | 138 | void insertMark(Mark* mark, int pos = -1); |
23396 | jghali | 139 | // Replace a character |
4669 | avox | 140 | void replaceChar(int pos, QChar ch); |
23396 | jghali | 141 | // Replace current selection with specified text |
142 | void replaceSelection(const QString& newText); |
||
17501 | craig | 143 | // Replaced a word, and return the difference in length between old and new |
144 | int replaceWord(int pos, QString newWord); |
||
17407 | fschmid | 145 | void replaceObject(int pos, int obj); |
4669 | avox | 146 | |
22639 | craig | 147 | void hyphenateWord(int pos, uint len, const char* hyphens); |
5559 | avox | 148 | |
17674 | jghali | 149 | // Retrieve length of story text |
4669 | avox | 150 | int length() const; |
17674 | jghali | 151 | |
152 | // Get content at specific position as plain text |
||
153 | // Internal paragraph separator are converted to |
||
154 | // unix new lines for better compatibility with |
||
155 | // text editors |
||
156 | QString plainText() const; |
||
157 | |||
21563 | jghali | 158 | // TextSource methods |
159 | |||
160 | virtual bool isBlockStart(int pos) const; |
||
161 | virtual int nextBlockStart(int pos) const; |
||
162 | virtual InlineFrame object(int pos) const; |
||
163 | virtual bool hasExpansionPoint(int pos) const; |
||
164 | virtual ExpansionPoint expansionPoint(int pos) const; |
||
165 | |||
16639 | jghali | 166 | // Get char at current cursor position |
21563 | jghali | 167 | // QChar text() const; |
16639 | jghali | 168 | // Get char at specific position |
16626 | jghali | 169 | QChar text(int pos) const; |
16639 | jghali | 170 | // Get text with len chars at specific position |
22295 | craig | 171 | QString text(int pos, uint len) const; |
24041 | jghali | 172 | // Get sentence at any position within it |
17501 | craig | 173 | QString sentence(int pos, int &posn); |
24041 | jghali | 174 | // Get word starting at position |
175 | QString word(int pos); |
||
16600 | jghali | 176 | |
177 | bool hasObject(int pos) const; |
||
22993 | jghali | 178 | PageItem* getItem(int pos) const; // deprecated |
24684 | jghali | 179 | |
23625 | jghali | 180 | int findMark(const Mark* mrk, int startPos = 0) const; |
23440 | jghali | 181 | bool hasMark(int pos, const Mark* mrk = nullptr) const; |
24684 | jghali | 182 | bool hasMark(int pos, MarkType markType) const; |
17826 | craig | 183 | Mark *mark(int pos) const; |
22993 | jghali | 184 | void replaceMark(int pos, Mark* mrk); |
21563 | jghali | 185 | void applyMarkCharstyle(Mark* mrk, CharStyle& currStyle) const; |
18524 | avox | 186 | |
24684 | jghali | 187 | int findNote(const TextNote* textNote) const; |
188 | |||
21563 | jghali | 189 | bool isHighSurrogate(int pos) const; |
190 | bool isLowSurrogate(int pos) const; |
||
191 | |||
16639 | jghali | 192 | // Get charstyle at current cursor position |
16626 | jghali | 193 | const CharStyle& charStyle() const; |
16639 | jghali | 194 | // Get charstyle at specific position |
4669 | avox | 195 | const CharStyle& charStyle(int pos) const; |
16639 | jghali | 196 | // Get paragraph style at current cursor position |
197 | const ParagraphStyle& paragraphStyle() const; |
||
198 | // Get paragraph style at specific position |
||
22993 | jghali | 199 | const ParagraphStyle& paragraphStyle(int pos) const; |
200 | const ParagraphStyle& defaultStyle() const; |
||
201 | void setDefaultStyle(const ParagraphStyle& style); |
||
202 | void setCharStyle(int pos, uint len, const CharStyle& style); |
||
203 | void setStyle(int pos, const ParagraphStyle& style); |
||
204 | void applyCharStyle(int pos, uint len, const CharStyle& style); |
||
205 | void applyStyle(int pos, const ParagraphStyle& style, bool rmDirectFormatting = false); |
||
206 | void eraseCharStyle(int pos, uint len, const CharStyle& style); |
||
207 | void eraseStyle(int pos, const ParagraphStyle& style); |
||
22631 | craig | 208 | void replaceStyles(const QMap<QString,QString>& newNameForOld); |
7442 | avox | 209 | void replaceCharStyles(QMap<QString,QString> newNameForOld); |
16681 | jghali | 210 | |
211 | // Cleanup legacy formatting for whole story, ie remove direct |
||
212 | // formatting for parameters already set at paragraph level |
||
213 | void fixLegacyFormatting(); |
||
7442 | avox | 214 | |
16681 | jghali | 215 | // Cleanup legacy formatting for paragraph at position pos |
216 | void fixLegacyFormatting(int pos); |
||
217 | |||
8455 | avox | 218 | void getNamedResources(ResourceCollection& lists) const; |
219 | void replaceNamedResources(ResourceCollection& newNames); |
||
220 | |||
22993 | jghali | 221 | uint nrOfParagraphs() const; |
16626 | jghali | 222 | int startOfParagraph() const; |
22993 | jghali | 223 | int startOfParagraph(uint index) const; |
16626 | jghali | 224 | int endOfParagraph() const; |
22993 | jghali | 225 | int endOfParagraph(uint index) const; |
16626 | jghali | 226 | uint nrOfParagraph() const; |
16069 | craig | 227 | uint nrOfParagraph(int pos) const; |
4669 | avox | 228 | |
22993 | jghali | 229 | uint nrOfRuns() const; |
230 | int startOfRun(uint index) const; |
||
231 | int endOfRun(uint index) const; |
||
4669 | avox | 232 | |
5184 | avox | 233 | // positioning |
234 | int nextChar(int pos); |
||
235 | int prevChar(int pos); |
||
17878 | jghali | 236 | int firstWord(); |
5184 | avox | 237 | int nextWord(int pos); |
238 | int prevWord(int pos); |
||
17501 | craig | 239 | int endOfWord(int pos) const; |
5184 | avox | 240 | int nextSentence(int pos); |
241 | int prevSentence(int pos); |
||
20558 | craig | 242 | int endOfSentence(int pos) const; |
5184 | avox | 243 | int nextParagraph(int pos); |
244 | int prevParagraph(int pos); |
||
245 | |||
246 | // these need valid layout: |
||
247 | |||
18987 | avox | 248 | // int startOfLine(int pos); |
249 | // int endOfLine(int pos); |
||
250 | // int prevLine(int pos); |
||
251 | // int nextLine(int pos); |
||
252 | // int startOfFrame(int pos); |
||
253 | // int endOfFrame(int pos); |
||
5184 | avox | 254 | |
4669 | avox | 255 | // selection |
256 | |||
22993 | jghali | 257 | void selectAll(); |
258 | void deselectAll(); |
||
259 | void removeSelection(); |
||
260 | void extendSelection(int oldPos, int newPos); |
||
13054 | pierre | 261 | int selectWord(int pos); |
22271 | craig | 262 | void select(int pos, int len, bool on = true); |
23396 | jghali | 263 | QString selectedText() const; |
22993 | jghali | 264 | bool selected(int pos) const; |
4669 | avox | 265 | int startOfSelection() const; |
266 | int endOfSelection() const; |
||
22832 | craig | 267 | int selectionLength() const; |
23940 | jghali | 268 | bool hasSelection() const; |
23396 | jghali | 269 | |
21563 | jghali | 270 | // break iterators |
23660 | craig | 271 | static icu::BreakIterator* getGraphemeIterator(); |
272 | static icu::BreakIterator* getWordIterator(); |
||
273 | static icu::BreakIterator* getSentenceIterator(); |
||
274 | static icu::BreakIterator* getLineIterator(); |
||
24234 | jghali | 275 | |
18524 | avox | 276 | // layout helpers |
277 | |||
21563 | jghali | 278 | ShapedTextCache* shapedTextCache() { return m_shapedTextCache; } |
279 | |||
18524 | avox | 280 | LayoutFlags flags(int pos) const; |
281 | bool hasFlag(int pos, LayoutFlags flag) const; |
||
282 | void setFlag(int pos, LayoutFlags flag); |
||
283 | void clearFlag(int pos, LayoutFlags flag); |
||
284 | |||
4669 | avox | 285 | // when physical view doesn't match logical view any more: |
286 | |||
287 | /// call this if the shape of an embedded object changes (redos layout) |
||
22993 | jghali | 288 | void invalidateObject(const PageItem* embedded); |
289 | /// call this if the shape of the paragraph changes (redos layout) |
||
290 | void invalidateLayout(); |
||
7942 | avox | 291 | |
292 | public slots: |
||
293 | /// call this if some logical style changes (redos shaping and layout) |
||
22993 | jghali | 294 | void invalidateAll(); |
4669 | avox | 295 | |
18987 | avox | 296 | signals: |
21515 | jghali | 297 | void changed(int firstItem, int endItem); |
4669 | avox | 298 | |
18524 | avox | 299 | private: |
23534 | jghali | 300 | ScText * item(int index); |
301 | const ScText * item(int index) const; |
||
21563 | jghali | 302 | void fixSurrogateSelection(); |
7501 | avox | 303 | |
304 | private: |
||
23626 | jghali | 305 | ScribusDoc * m_doc; |
21563 | jghali | 306 | ShapedTextCache* m_shapedTextCache; |
23660 | craig | 307 | static icu::BreakIterator* m_graphemeIterator; |
308 | static icu::BreakIterator* m_wordIterator; |
||
309 | static icu::BreakIterator* m_sentenceIterator; |
||
310 | static icu::BreakIterator* m_lineIterator; |
||
12093 | jghali | 311 | |
15009 | jghali | 312 | QString textWithSoftHyphens (int pos, uint len) const; |
22635 | craig | 313 | void insertCharsWithSoftHyphens(int pos, const QString& txt, bool applyNeighbourStyle = false); |
6144 | avox | 314 | |
22993 | jghali | 315 | /// mark these runs as invalid, ie. need itemize and shaping |
316 | void invalidate(int firstRun, int lastRun); |
||
317 | void removeParSep(int pos); |
||
318 | void insertParSep(int pos); |
||
8175 | avox | 319 | |
320 | // int splitRun(int pos); |
||
22993 | jghali | 321 | |
322 | /** bring physical view in sync with logical one. |
||
323 | * This gets called automatically from all physical view methods |
||
4669 | avox | 324 | */ |
325 | // void validate(); |
||
22993 | jghali | 326 | /// private data structure |
327 | ScText_Shared * d; |
||
328 | /// gives the physical view which was last given to the layouter |
||
4669 | avox | 329 | // uint layouterVersion; |
330 | /// is true after layout() has been exercised |
||
331 | // bool layouterValid; |
||
332 | }; |
||
7970 | cbradney | 333 | |
334 | |||
4669 | avox | 335 | #endif /*STORYTEXT_H_*/ |