Another minor change, but this should almost get us to the point that we
[lyx.git] / src / Text.h
blobc8073eec711150df87764b08b10a8573ef9d6642
1 // -*- C++ -*-
2 /**
3 * \file Text.h
4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author unknown
8 * \author Lars Gullik Bjønnes
9 * \author John Levon
11 * Full author contact details are available in file CREDITS.
14 #ifndef TEXT_H
15 #define TEXT_H
17 #include "DocIterator.h"
18 #include "ParagraphList.h"
20 namespace lyx {
22 class Buffer;
23 class BufferParams;
24 class BufferView;
25 class CompletionList;
26 class Cursor;
27 class CursorSlice;
28 class DocIterator;
29 class ErrorList;
30 class Font;
31 class FontInfo;
32 class FuncRequest;
33 class FuncStatus;
34 class Inset;
35 class Lexer;
36 class PainterInfo;
37 class Spacing;
39 /// This class encapsulates the main text data and operations in LyX
40 class Text {
41 public:
42 /// constructor
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
49 // count as empty.
50 bool empty() const;
51 /// Access to owner InsetText.
52 InsetText const & inset() const;
54 ///
55 FontInfo layoutFont(pit_type pit) const;
56 ///
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
70 * in insetbase.h
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
86 enum DEPTH_CHANGE {
87 INC_DEPTH,
88 DEC_DEPTH
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);
109 /// ???
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);
154 /// select all text
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
160 enum ChangeOp {
161 ACCEPT,
162 REJECT
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,
257 Font const & font);
258 /// needed to insert the selection
259 void insertStringAsParagraphs(DocIterator const & dit, docstring const & str,
260 Font const & font);
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;
325 private:
326 /// The InsetText owner shall have access to everything.
327 friend class InsetText;
329 /// return past-the-last paragraph influenced by a layout
330 /// change on pit
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,
353 bool asParagraphs);
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);
363 /// Owner Inset.
364 InsetText * owner_;
366 ParagraphList pars_;
368 bool autoBreakRows_;
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,
379 pit_type par,
380 pos_type pos);
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);
392 } // namespace lyx
394 #endif // TEXT_H