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.
18 #include "DispatchResult.h"
21 #include "lyxlayout_ptr_fwd.h"
22 #include "ParagraphList.h"
46 /// This class encapsulates the main text data and operations in LyX
53 Font getFont(Buffer const & buffer, Paragraph const & par,
56 void applyOuterFont(Buffer const & buffer, Font &) const;
58 Font getLayoutFont(Buffer const & buffer, pit_type pit) const;
60 Font getLabelFont(Buffer const & buffer,
61 Paragraph const & par) const;
62 /** Set font of character at position \p pos in paragraph \p pit.
63 * Must not be called if \p pos denotes an inset with text contents,
64 * and the inset is not allowed inside a font change (see below).
66 void setCharFont(Buffer const & buffer, pit_type pit, pos_type pos,
69 /** Needed to propagate font changes to all text cells of insets
70 * that are not allowed inside a font change (bug 1973).
71 * Must not be called if \p pos denotes an ordinary character or an
72 * inset that is alowed inside a font change.
73 * FIXME: This should be removed, see documentation of noFontChange
76 void setInsetFont(Buffer const & buffer, pit_type pit, pos_type pos,
77 Font const & font, bool toggleall = false);
79 /// what you expect when pressing \<enter\> at cursor position
80 void breakParagraph(Cursor & cur, bool keep_layout = false);
82 /// set layout over selection
83 void setLayout(Buffer const & buffer, pit_type start, pit_type end,
84 std::string const & layout);
85 /// Set given layout to current cursor position.
86 /// FIXME: replace Cursor with DocIterator.
87 void setLayout(Cursor & cur, std::string const & layout);
89 /// what type of depth change to make
94 /// Increase or decrease the nesting depth of the selected paragraph(s)
95 /// FIXME: replace Cursor with DocIterator.
96 void changeDepth(Cursor & cur, DEPTH_CHANGE type);
98 /// Returns whether something would be changed by changeDepth
99 /// FIXME: replace Cursor with DocIterator.
100 bool changeDepthAllowed(Cursor & cur, DEPTH_CHANGE type) const;
102 /// Set font over selection paragraphs and rebreak.
103 /// FIXME: replace Cursor with DocIterator.
104 void setFont(Cursor & cur, Font const &, bool toggleall = false);
105 /// Set font from \p begin to \p end and rebreak.
106 void setFont(Buffer const & buffer, DocIterator const & begin,
107 DocIterator const & end, Font const &,
108 bool toggleall = false);
111 void toggleFree(Cursor & cur, Font const &, bool toggleall = false);
114 /// FIXME: replace Cursor with DocIterator.
115 docstring getStringToIndex(Cursor const & cur);
117 /// insert a character at cursor position
118 /// FIXME: replace Cursor with DocIterator.
119 void insertChar(Cursor & cur, char_type c);
120 /// insert an inset at cursor position
121 /// FIXME: replace Cursor with DocIterator.
122 void insertInset(Cursor & cur, Inset * inset);
124 /// draw text (only used for insets)
125 void draw(PainterInfo & pi, int x, int y) const;
126 /// draw textselection
127 void drawSelection(PainterInfo & pi, int x, int y) const;
129 /// try to handle that request
130 /// FIXME: replace Cursor with DocIterator.
131 void dispatch(Cursor & cur, FuncRequest & cmd);
132 /// do we want to handle this event?
133 bool getStatus(Cursor & cur, FuncRequest const & cmd,
134 FuncStatus & status) const;
136 /// read-only access to individual paragraph
137 Paragraph const & getPar(pit_type pit) const { return pars_[pit]; }
138 /// read-write access to individual paragraph
139 Paragraph & getPar(pit_type pit) { return pars_[pit]; }
140 // Returns the current font and depth as a message.
141 /// FIXME: replace Cursor with DocIterator.
142 docstring currentState(Cursor & cur);
144 /** returns row near the specified
145 * y-coordinate in given paragraph (relative to the screen).
147 /// FIXME: move to TextMetrics.
148 Row const & getRowNearY(BufferView const & bv, int y,
151 /// returns the paragraph number closest to screen y-coordinate.
152 /// This method uses the BufferView CoordCache to locate the
153 /// paragraph. The y-coodinate is allowed to be off-screen and
154 /// the CoordCache will be automatically updated if needed. This is
155 /// the reason why we need a non const BufferView.
156 /// FIXME: move to TextMetrics.
157 pit_type getPitNearY(BufferView & bv, int y) const;
159 /** Find the word under \c from in the relative location
160 * defined by \c word_location.
161 * @param from return here the start of the word
162 * @param to return here the end of the word
164 void getWord(CursorSlice & from, CursorSlice & to, word_location const);
165 /// just selects the word the cursor is in
166 void selectWord(Cursor & cur, word_location loc);
168 /// what type of change operation to make
173 /// accept or reject the selected change
174 void acceptOrRejectChanges(Cursor & cur, ChangeOp op);
175 /// accept the changes within the complete Text
176 void acceptChanges(BufferParams const & bparams);
177 /// reject the changes within the complete Text
178 void rejectChanges(BufferParams const & bparams);
180 /// returns true if par was empty and was removed
181 bool setCursor(Cursor & cur, pit_type par, pos_type pos,
182 bool setfont = true, bool boundary = false);
184 void setCursor(CursorSlice &, pit_type par, pos_type pos);
186 void setCursorIntern(Cursor & cur, pit_type par,
187 pos_type pos, bool setfont = true, bool boundary = false);
189 void setCurrentFont(Cursor & cur);
192 void recUndo(Cursor & cur, pit_type first, pit_type last) const;
194 void recUndo(Cursor & cur, pit_type first) const;
196 /// sets cursor only within this Text.
197 /// x,y are screen coordinates
198 void setCursorFromCoordinates(Cursor & cur, int x, int y);
200 /// sets cursor recursively descending into nested editable insets
202 \return the inset pointer if x,y is covering that inset
203 \param x,y are absolute screen coordinates.
204 \retval inset is non-null if the cursor is positionned inside
206 /// FIXME: move to TextMetrics.
207 /// FIXME: cleanup to use BufferView::getCoveringInset() and
208 /// setCursorFromCoordinates() instead of checkInsetHit().
209 Inset * editXY(Cursor & cur, int x, int y);
211 /// Move cursor one position left
213 * Returns true if an update is needed after the move.
215 bool cursorLeft(Cursor & cur);
216 /// Move cursor one position right
218 * Returns true if an update is needed after the move.
220 bool cursorRight(Cursor & cur);
222 bool cursorLeftOneWord(Cursor & cur);
224 bool cursorRightOneWord(Cursor & cur);
226 bool cursorUpParagraph(Cursor & cur);
228 bool cursorDownParagraph(Cursor & cur);
230 /// FIXME: move to TextMetrics.
231 bool cursorHome(Cursor & cur);
233 /// FIXME: move to TextMetrics.
234 bool cursorEnd(Cursor & cur);
236 void cursorPrevious(Cursor & cur);
238 void cursorNext(Cursor & cur);
240 bool cursorTop(Cursor & cur);
242 bool cursorBottom(Cursor & cur);
243 /// Erase character at cursor. Honour change tracking
244 /// FIXME: replace Cursor with DocIterator.
245 bool erase(Cursor & cur);
246 /// Delete character before cursor. Honour CT
247 /// FIXME: replace Cursor with DocIterator.
248 bool backspace(Cursor & cur);
249 // Dissolve the inset under cursor
250 /// FIXME: replace Cursor with DocIterator.
251 bool dissolveInset(Cursor & cur);
253 bool selectWordWhenUnderCursor(Cursor & cur, word_location);
259 text_capitalization = 1,
263 /// Change the case of the word at cursor position.
264 void changeCase(Cursor & cur, TextCase action);
265 /// Transposes the character at the cursor with the one before it
266 void charsTranspose(Cursor & cur);
268 /** the DTP switches for paragraphs. LyX will store the top settings
269 always in the first physical paragraph, the bottom settings in the
270 last. When a paragraph is broken, the top settings rest, the bottom
271 settings are given to the new one.
273 void setParagraph(Cursor & cur,
274 Spacing const & spacing,
276 docstring const & labelwidthstring,
279 /* these things are for search and replace */
281 /// needed to insert the selection
282 /// FIXME: replace Cursor with DocIterator.
283 void insertStringAsLines(Cursor & cur, docstring const & str);
284 /// needed to insert the selection
285 /// FIXME: replace Cursor with DocIterator.
286 void insertStringAsParagraphs(Cursor & cur, docstring const & str);
288 /// Returns an inset if inset was hit, or 0 if not.
289 /// \warning This method is not recursive! It will return the
290 /// outermost inset within this Text.
291 /// \sa BufferView::getCoveringInset() to get the innermost inset.
292 Inset * checkInsetHit(BufferView &, int x, int y);
295 /// FIXME: move to TextMetrics.
296 int singleWidth(Buffer const &, Paragraph const & par,
299 /// FIXME: move to TextMetrics.
300 int singleWidth(Paragraph const & par, pos_type pos, char_type c,
301 Font const & Font) const;
303 /// return the color of the canvas
304 Color_color backgroundColor() const;
307 * Returns the left beginning of the text.
308 * This information cannot be taken from the layout object, because
309 * in LaTeX the beginning of the text fits in some cases
310 * (for example sections) exactly the label-width.
312 /// FIXME: move to TextMetrics.
313 int leftMargin(Buffer const &, int max_width, pit_type pit, pos_type pos) const;
314 int leftMargin(Buffer const &, int max_width, pit_type pit) const;
316 /// access to our paragraphs
317 ParagraphList const & paragraphs() const { return pars_; }
318 ParagraphList & paragraphs() { return pars_; }
319 /// return true if this is the main text
320 bool isMainText(Buffer const &) const;
322 /// is this row the last in the text?
323 /// FIXME: move to TextMetrics.
324 bool isLastRow(pit_type pit, Row const & row) const;
325 /// is this row the first in the text?
326 /// FIXME: move to TextMetrics.
327 bool isFirstRow(pit_type pit, Row const & row) const;
330 double spacing(Buffer const & buffer, Paragraph const & par) const;
331 /// make a suggestion for a label
332 /// FIXME: replace Cursor with DocIterator.
333 docstring getPossibleLabel(Cursor & cur) const;
334 /// is this paragraph right-to-left?
335 bool isRTL(Buffer const &, Paragraph const & par) const;
337 bool checkAndActivateInset(Cursor & cur, bool front);
340 void write(Buffer const & buf, std::ostream & os) const;
341 /// returns whether we've seen our usual 'end' marker
342 bool read(Buffer const & buf, Lexer & lex, ErrorList & errorList);
345 /// FIXME: move to TextMetrics.
346 int cursorX(BufferView const &, CursorSlice const & cursor,
347 bool boundary) const;
349 /// FIXME: move to TextMetrics.
350 int cursorY(BufferView const & bv, CursorSlice const & cursor,
351 bool boundary) const;
353 /// delete double spaces, leading spaces, and empty paragraphs around old cursor.
354 /// \retval true if a change has happened and we need a redraw.
355 /// FIXME: replace Cursor with DocIterator. This is not possible right
356 /// now because recordUndo() is called which needs a Cursor.
357 static bool deleteEmptyParagraphMechanism(Cursor & cur,
358 Cursor & old, bool & need_anchor_change);
360 /// delete double spaces, leading spaces, and empty paragraphs
361 /// from \first to \last paragraph
362 void deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool trackChanges);
365 /// the current font settings
368 Font real_current_font;
370 int background_color_;
377 /// our 'outermost' font. This is handed down from the surrounding
378 // inset through the pi/mi parameter (pi.base.font)
384 /// return past-the-last paragraph influenced by a layout
386 pit_type undoSpan(pit_type pit);
388 // fix the cursor `cur' after a characters has been deleted at `where'
389 // position. Called by deleteEmptyParagraphMechanism
390 static void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
392 // At cursor position 0, try to merge the paragraph with the one before it.
393 // Ignore change tracking, i.e., physically remove the end-of-par character
394 bool backspacePos0(Cursor & cur);
395 /// handle the case where bibitems were deleted
396 bool handleBibitems(Cursor & cur);
399 void deleteWordForward(Cursor & cur);
401 void deleteWordBackward(Cursor & cur);
403 void deleteLineForward(Cursor & cur);
406 /// set 'number' font property
407 void number(Cursor & cur);
409 /// paste plain text at current cursor.
410 /// \param str string to paste
411 /// \param asParagraphs whether to paste as paragraphs or as lines
412 void pasteString(Cursor & cur, docstring const & str,