4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
8 * \author Lars Gullik Bjønnes
11 * Full author contact details are available in file CREDITS.
17 #include "DocIterator.h"
18 #include "ParagraphList.h"
39 /// This class encapsulates the main text data and operations in LyX
43 explicit Text(InsetText
* owner
)
44 : owner_(owner
), autoBreakRows_(false), undo_counter_(0)
47 /// \return true if there's no content at all.
48 /// \warning a non standard layout on an empty paragraph doesn't
51 /// Access to owner InsetText.
52 InsetText
const & inset() const;
55 FontInfo
layoutFont(pit_type pit
) const;
57 FontInfo
labelFont(Paragraph
const & par
) const;
58 /** Set font of character at position \p pos in paragraph \p pit.
59 * Must not be called if \p pos denotes an inset with text contents,
60 * and the inset is not allowed inside a font change (see below).
62 void setCharFont(pit_type pit
, pos_type pos
,
63 Font
const & font
, Font
const & display_font
);
65 /** Needed to propagate font changes to all text cells of insets
66 * that are not allowed inside a font change (bug 1973).
67 * Must not be called if \p pos denotes an ordinary character or an
68 * inset that is alowed inside a font change.
69 * FIXME: This should be removed, see documentation of noFontChange
72 void setInsetFont(BufferView
const & bv
, pit_type pit
, pos_type pos
,
73 Font
const & font
, bool toggleall
= false);
75 /// what you expect when pressing \<enter\> at cursor position
76 void breakParagraph(Cursor
& cur
, bool inverse_logic
= false);
78 /// set layout over selection
79 void setLayout(pit_type start
, pit_type end
,
80 docstring
const & layout
);
81 /// Set given layout to current cursor position.
82 /// FIXME: replace Cursor with DocIterator.
83 void setLayout(Cursor
& cur
, docstring
const & layout
);
85 /// what type of depth change to make
90 /// Increase or decrease the nesting depth of the selected paragraph(s)
91 /// FIXME: replace Cursor with DocIterator.
92 void changeDepth(Cursor
& cur
, DEPTH_CHANGE type
);
94 /// Returns whether something would be changed by changeDepth
95 /// FIXME: replace Cursor with DocIterator.
96 bool changeDepthAllowed(Cursor
& cur
, DEPTH_CHANGE type
) const;
98 /// Set font over selection paragraphs and rebreak.
99 /// FIXME: replace Cursor with DocIterator.
100 void setFont(Cursor
& cur
, Font
const &, bool toggleall
= false);
101 /// Set font from \p begin to \p end and rebreak.
102 void setFont(BufferView
const & bv
, CursorSlice
const & begin
,
103 CursorSlice
const & end
, Font
const &,
104 bool toggleall
= false);
107 void toggleFree(Cursor
& cur
, Font
const &, bool toggleall
= false);
110 /// FIXME: replace Cursor with DocIterator.
111 docstring
getStringToIndex(Cursor
const & cur
);
113 /// Convert the paragraphs to a string.
114 /// \param AsStringParameter options. This can contain any combination of
115 /// asStringParameter values. Valid examples:
116 /// asString(AS_STR_LABEL)
117 /// asString(AS_STR_LABEL | AS_STR_INSETS)
118 /// asString(AS_STR_INSETS)
119 docstring
asString(int options
= AS_STR_NONE
) const;
121 docstring
asString(pit_type beg
, pit_type end
,
122 int options
= AS_STR_NONE
) const;
124 /// insert a character at cursor position
125 /// FIXME: replace Cursor with DocIterator.
126 void insertChar(Cursor
& cur
, char_type c
);
127 /// insert an inset at cursor position
128 /// FIXME: replace Cursor with DocIterator.
129 void insertInset(Cursor
& cur
, Inset
* inset
);
131 /// try to handle that request
132 /// FIXME: replace Cursor with DocIterator.
133 void dispatch(Cursor
& cur
, FuncRequest
& cmd
);
134 /// do we want to handle this event?
135 bool getStatus(Cursor
& cur
, FuncRequest
const & cmd
,
136 FuncStatus
& status
) const;
138 /// read-only access to individual paragraph
139 Paragraph
const & getPar(pit_type pit
) const { return pars_
[pit
]; }
140 /// read-write access to individual paragraph
141 Paragraph
& getPar(pit_type pit
) { return pars_
[pit
]; }
142 // Returns the current font and depth as a message.
143 /// FIXME: replace Cursor with DocIterator.
144 docstring
currentState(Cursor
const & cur
) const;
146 /** Find the word under \c from in the relative location
147 * defined by \c word_location.
148 * @param from return here the start of the word
149 * @param to return here the end of the word
151 void getWord(CursorSlice
& from
, CursorSlice
& to
, word_location
const) const;
152 /// just selects the word the cursor is in
153 void selectWord(Cursor
& cur
, word_location loc
);
155 void selectAll(Cursor
& cur
);
156 /// convenience function get the previous word or an empty string
157 docstring
previousWord(CursorSlice
const & sl
) const;
159 /// what type of change operation to make
164 /// accept or reject the selected change
165 void acceptOrRejectChanges(Cursor
& cur
, ChangeOp op
);
166 /// accept the changes within the complete Text
167 void acceptChanges();
168 /// reject the changes within the complete Text
169 void rejectChanges();
171 /// returns true if par was empty and was removed
172 bool setCursor(Cursor
& cur
, pit_type par
, pos_type pos
,
173 bool setfont
= true, bool boundary
= false);
175 void setCursor(CursorSlice
&, pit_type par
, pos_type pos
);
177 void setCursorIntern(Cursor
& cur
, pit_type par
,
178 pos_type pos
, bool setfont
= true, bool boundary
= false);
181 void recUndo(Cursor
& cur
, pit_type first
, pit_type last
) const;
183 void recUndo(Cursor
& cur
, pit_type first
) const;
185 /// Move cursor one position backwards
187 * Returns true if an update is needed after the move.
189 bool cursorBackward(Cursor
& cur
);
190 /// Move cursor visually one position to the left
192 * \param skip_inset if true, don't enter insets
193 * Returns true if an update is needed after the move.
195 bool cursorVisLeft(Cursor
& cur
, bool skip_inset
= false);
196 /// Move cursor one position forward
198 * Returns true if an update is needed after the move.
200 bool cursorForward(Cursor
& cur
);
201 /// Move cursor visually one position to the right
203 * \param skip_inset if true, don't enter insets
204 * Returns true if an update is needed after the move.
206 bool cursorVisRight(Cursor
& cur
, bool skip_inset
= false);
208 bool cursorBackwardOneWord(Cursor
& cur
);
210 bool cursorForwardOneWord(Cursor
& cur
);
212 bool cursorVisLeftOneWord(Cursor
& cur
);
214 bool cursorVisRightOneWord(Cursor
& cur
);
215 /// Delete from cursor up to the end of the current or next word.
216 void deleteWordForward(Cursor
& cur
);
217 /// Delete from cursor to start of current or prior word.
218 void deleteWordBackward(Cursor
& cur
);
220 bool cursorUpParagraph(Cursor
& cur
);
222 bool cursorDownParagraph(Cursor
& cur
);
224 bool cursorTop(Cursor
& cur
);
226 bool cursorBottom(Cursor
& cur
);
227 /// Erase character at cursor. Honour change tracking
228 /// FIXME: replace Cursor with DocIterator.
229 bool erase(Cursor
& cur
);
230 /// Delete character before cursor. Honour CT
231 /// FIXME: replace Cursor with DocIterator.
232 bool backspace(Cursor
& cur
);
233 // Dissolve the inset under cursor
234 /// FIXME: replace Cursor with DocIterator.
235 bool dissolveInset(Cursor
& cur
);
237 bool selectWordWhenUnderCursor(Cursor
& cur
, word_location
);
238 /// Change the case of the word at cursor position.
239 void changeCase(Cursor
& cur
, TextCase action
);
240 /// Transposes the character at the cursor with the one before it
241 void charsTranspose(Cursor
& cur
);
243 /** the DTP switches for paragraphs. LyX will store the top settings
244 always in the first physical paragraph, the bottom settings in the
245 last. When a paragraph is broken, the top settings rest, the bottom
246 settings are given to the new one.
247 This function will handle a multi-paragraph selection.
249 void setParagraphs(Cursor
& cur
, docstring arg
, bool modify
= false);
250 /// Sets parameters for current or selected paragraphs
251 void setParagraphs(Cursor
& cur
, ParagraphParameters
const & p
);
253 /* these things are for search and replace */
255 /// needed to insert the selection
256 void insertStringAsLines(DocIterator
const & dit
, docstring
const & str
,
258 /// needed to insert the selection
259 void insertStringAsParagraphs(DocIterator
const & dit
, docstring
const & str
,
262 /// access to our paragraphs
263 ParagraphList
const & paragraphs() const { return pars_
; }
264 ParagraphList
& paragraphs() { return pars_
; }
265 /// return true if this is the main text
266 bool isMainText() const;
269 double spacing(Paragraph
const & par
) const;
270 /// make a suggestion for a label
271 /// FIXME: replace Cursor with DocIterator.
272 docstring
getPossibleLabel(Cursor
const & cur
) const;
273 /// is this paragraph right-to-left?
274 bool isRTL(Paragraph
const & par
) const;
277 bool checkAndActivateInset(Cursor
& cur
, bool front
);
279 bool checkAndActivateInsetVisual(Cursor
& cur
, bool movingForward
, bool movingLeft
);
282 void write(std::ostream
& os
) const;
283 /// returns true if \end_document has not been read
284 /// insetPtr is the containing Inset
285 bool read(Lexer
& lex
, ErrorList
& errorList
,
286 InsetText
* insetPtr
);
288 /// delete double spaces, leading spaces, and empty paragraphs around old cursor.
289 /// \retval true if a change has happened and we need a redraw.
290 /// FIXME: replace Cursor with DocIterator. This is not possible right
291 /// now because recordUndo() is called which needs a Cursor.
292 static bool deleteEmptyParagraphMechanism(Cursor
& cur
,
293 Cursor
& old
, bool & need_anchor_change
);
295 /// delete double spaces, leading spaces, and empty paragraphs
296 /// from \first to \last paragraph
297 void deleteEmptyParagraphMechanism(pit_type first
, pit_type last
, bool trackChanges
);
299 /// To resolve macros properly the texts get their DocIterator.
300 /// Every macro definition is stored with its DocIterator
301 /// as well. Only those macros with a smaller iterator become
302 /// visible in a paragraph.
303 DocIterator
macrocontextPosition() const;
305 void setMacrocontextPosition(DocIterator
const & pos
);
308 bool completionSupported(Cursor
const & cur
) const;
310 CompletionList
const * createCompletionList(Cursor
const & cur
) const;
312 bool insertCompletion(Cursor
& cur
, docstring
const & s
, bool /*finished*/);
314 docstring
completionPrefix(Cursor
const & cur
) const;
315 /// for the environments
316 pit_type
depthHook(pit_type par
, depth_type depth
) const;
318 pit_type
outerHook(pit_type par
) const;
319 /// Is it the first par with same depth and layout?
320 bool isFirstInSequence(pit_type par
) const;
321 /// Get the font of the "environment" of paragraph \p par_offset in \p pars.
322 /// All font changes of the paragraph are relative to this font.
323 Font
const outerFont(pit_type par_offset
) const;
326 /// The InsetText owner shall have access to everything.
327 friend class InsetText
;
329 /// return past-the-last paragraph influenced by a layout
331 pit_type
undoSpan(pit_type pit
);
333 // fix the cursor `cur' after a characters has been deleted at `where'
334 // position. Called by deleteEmptyParagraphMechanism
335 static void fixCursorAfterDelete(CursorSlice
& cur
, CursorSlice
const & where
);
337 // At cursor position 0, try to merge the paragraph with the one before it.
338 // Ignore change tracking, i.e., physically remove the end-of-par character
339 bool backspacePos0(Cursor
& cur
);
340 /// handle the case where bibitems were deleted
341 bool handleBibitems(Cursor
& cur
);
342 /// are we in a list item (description etc.)?
343 bool inDescriptionItem(Cursor
& cur
) const;
345 void charInserted(Cursor
& cur
);
346 /// set 'number' font property
347 void number(Cursor
& cur
);
349 /// paste plain text at current cursor.
350 /// \param str string to paste
351 /// \param asParagraphs whether to paste as paragraphs or as lines
352 void pasteString(Cursor
& cur
, docstring
const & str
,
355 void readParToken(Paragraph
& par
, Lexer
& lex
, std::string
const & token
,
356 Font
& font
, Change
& change
, ErrorList
& errorList
);
358 void readParagraph(Paragraph
& par
, Lexer
& lex
, ErrorList
& errorList
);
359 /// Set Label Width string to all paragraphs of the same layout
360 /// and depth in a sequence.
361 void setLabelWidthStringToSequence(pit_type
const par_offset
, docstring
const & s
);
369 /// position of the text in the buffer.
370 DocIterator macrocontext_position_
;
372 unsigned int undo_counter_
;
377 void breakParagraphConservative(BufferParams
const & bparams
,
378 ParagraphList
& paragraphs
,
383 * Append the next paragraph onto the tail of this one.
384 * Be careful, this doesent make any check at all.
386 void mergeParagraph(BufferParams
const & bparams
,
387 ParagraphList
& paragraphs
, pit_type par
);
389 /// accept the changes within the complete ParagraphList
390 void acceptChanges(ParagraphList
& pars
, BufferParams
const & bparams
);