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;
63 void setCharFont(Buffer const & buffer, pit_type pit, pos_type pos,
66 /// what you expect when pressing \<enter\> at cursor position
67 void breakParagraph(Cursor & cur, bool keep_layout = false);
69 /// set layout over selection
70 void setLayout(Buffer const & buffer, pit_type start, pit_type end,
71 std::string const & layout);
72 /// Set given layout to current cursor position.
73 /// FIXME: replace Cursor with DocIterator.
74 void setLayout(Cursor & cur, std::string const & layout);
76 /// what type of depth change to make
81 /// Increase or decrease the nesting depth of the selected paragraph(s)
82 /// FIXME: replace Cursor with DocIterator.
83 void changeDepth(Cursor & cur, DEPTH_CHANGE type);
85 /// Returns whether something would be changed by changeDepth
86 /// FIXME: replace Cursor with DocIterator.
87 bool changeDepthAllowed(Cursor & cur, DEPTH_CHANGE type) const;
89 /// Set font over selection paragraphs and rebreak.
90 /// FIXME: replace Cursor with DocIterator.
91 void setFont(Cursor & cur, Font const &, bool toggleall = false);
94 void toggleFree(Cursor & cur, Font const &, bool toggleall = false);
97 /// FIXME: replace Cursor with DocIterator.
98 docstring getStringToIndex(Cursor const & cur);
100 /// insert a character at cursor position
101 /// FIXME: replace Cursor with DocIterator.
102 void insertChar(Cursor & cur, char_type c);
103 /// insert an inset at cursor position
104 /// FIXME: replace Cursor with DocIterator.
105 void insertInset(Cursor & cur, Inset * inset);
107 /// draw text (only used for insets)
108 void draw(PainterInfo & pi, int x, int y) const;
109 /// draw textselection
110 void drawSelection(PainterInfo & pi, int x, int y) const;
112 /// try to handle that request
113 /// FIXME: replace Cursor with DocIterator.
114 void dispatch(Cursor & cur, FuncRequest & cmd);
115 /// do we want to handle this event?
116 bool getStatus(Cursor & cur, FuncRequest const & cmd,
117 FuncStatus & status) const;
119 /// read-only access to individual paragraph
120 Paragraph const & getPar(pit_type pit) const { return pars_[pit]; }
121 /// read-write access to individual paragraph
122 Paragraph & getPar(pit_type pit) { return pars_[pit]; }
123 // Returns the current font and depth as a message.
124 /// FIXME: replace Cursor with DocIterator.
125 docstring currentState(Cursor & cur);
127 /** returns row near the specified
128 * y-coordinate in given paragraph (relative to the screen).
130 /// FIXME: move to TextMetrics.
131 Row const & getRowNearY(BufferView const & bv, int y,
134 /// returns the paragraph number closest to screen y-coordinate.
135 /// This method uses the BufferView CoordCache to locate the
136 /// paragraph. The y-coodinate is allowed to be off-screen and
137 /// the CoordCache will be automatically updated if needed. This is
138 /// the reason why we need a non const BufferView.
139 /// FIXME: move to TextMetrics.
140 pit_type getPitNearY(BufferView & bv, int y) const;
142 /** Find the word under \c from in the relative location
143 * defined by \c word_location.
144 * @param from return here the start of the word
145 * @param to return here the end of the word
147 void getWord(CursorSlice & from, CursorSlice & to, word_location const);
148 /// just selects the word the cursor is in
149 void selectWord(Cursor & cur, word_location loc);
151 /// what type of change operation to make
156 /// accept or reject the selected change
157 void acceptOrRejectChanges(Cursor & cur, ChangeOp op);
158 /// accept the changes within the complete Text
159 void acceptChanges(BufferParams const & bparams);
160 /// reject the changes within the complete Text
161 void rejectChanges(BufferParams const & bparams);
163 /// returns true if par was empty and was removed
164 bool setCursor(Cursor & cur, pit_type par, pos_type pos,
165 bool setfont = true, bool boundary = false);
167 void setCursor(CursorSlice &, pit_type par, pos_type pos);
169 void setCursorIntern(Cursor & cur, pit_type par,
170 pos_type pos, bool setfont = true, bool boundary = false);
172 void setCurrentFont(Cursor & cur);
175 void recUndo(Cursor & cur, pit_type first, pit_type last) const;
177 void recUndo(Cursor & cur, pit_type first) const;
179 /// sets cursor only within this Text.
180 /// x,y are screen coordinates
181 void setCursorFromCoordinates(Cursor & cur, int x, int y);
183 /// sets cursor recursively descending into nested editable insets
185 \return the inset pointer if x,y is covering that inset
186 \param x,y are absolute screen coordinates.
187 \retval inset is non-null if the cursor is positionned inside
189 /// FIXME: move to TextMetrics.
190 /// FIXME: cleanup to use BufferView::getCoveringInset() and
191 /// setCursorFromCoordinates() instead of checkInsetHit().
192 Inset * editXY(Cursor & cur, int x, int y);
194 /// Move cursor one line up.
196 * Returns true if an update is needed after the move.
198 /// FIXME: move to TextMetrics.
199 bool cursorUp(Cursor & cur);
200 /// Move cursor one line down.
202 * Returns true if an update is needed after the move.
204 /// FIXME: move to TextMetrics.
205 bool cursorDown(Cursor & cur);
206 /// Move cursor one position left
208 * Returns true if an update is needed after the move.
210 bool cursorLeft(Cursor & cur);
211 /// Move cursor one position right
213 * Returns true if an update is needed after the move.
215 bool cursorRight(Cursor & cur);
217 bool cursorLeftOneWord(Cursor & cur);
219 bool cursorRightOneWord(Cursor & cur);
221 bool cursorUpParagraph(Cursor & cur);
223 bool cursorDownParagraph(Cursor & cur);
225 /// FIXME: move to TextMetrics.
226 bool cursorHome(Cursor & cur);
228 /// FIXME: move to TextMetrics.
229 bool cursorEnd(Cursor & cur);
231 void cursorPrevious(Cursor & cur);
233 void cursorNext(Cursor & cur);
235 bool cursorTop(Cursor & cur);
237 bool cursorBottom(Cursor & cur);
238 /// Erase character at cursor. Honour change tracking
239 /// FIXME: replace Cursor with DocIterator.
240 bool erase(Cursor & cur);
241 /// Delete character before cursor. Honour CT
242 /// FIXME: replace Cursor with DocIterator.
243 bool backspace(Cursor & cur);
244 // Dissolve the inset under cursor
245 /// FIXME: replace Cursor with DocIterator.
246 bool dissolveInset(Cursor & cur);
248 bool selectWordWhenUnderCursor(Cursor & cur, word_location);
254 text_capitalization = 1,
258 /// Change the case of the word at cursor position.
259 void changeCase(Cursor & cur, TextCase action);
260 /// Transposes the character at the cursor with the one before it
261 void charsTranspose(Cursor & cur);
263 /** the DTP switches for paragraphs. LyX will store the top settings
264 always in the first physical paragraph, the bottom settings in the
265 last. When a paragraph is broken, the top settings rest, the bottom
266 settings are given to the new one.
268 void setParagraph(Cursor & cur,
269 Spacing const & spacing,
271 docstring const & labelwidthstring,
274 /* these things are for search and replace */
276 /// needed to insert the selection
277 /// FIXME: replace Cursor with DocIterator.
278 void insertStringAsLines(Cursor & cur, docstring const & str);
279 /// needed to insert the selection
280 /// FIXME: replace Cursor with DocIterator.
281 void insertStringAsParagraphs(Cursor & cur, docstring const & str);
283 /// Returns an inset if inset was hit, or 0 if not.
284 /// \warning This method is not recursive! It will return the
285 /// outermost inset within this Text.
286 /// \sa BufferView::getCoveringInset() to get the innermost inset.
287 Inset * checkInsetHit(BufferView &, int x, int y);
290 /// FIXME: move to TextMetrics.
291 int singleWidth(Buffer const &, Paragraph const & par,
294 /// FIXME: move to TextMetrics.
295 int singleWidth(Paragraph const & par, pos_type pos, char_type c,
296 Font const & Font) const;
298 /// return the color of the canvas
299 Color_color backgroundColor() const;
302 * Returns the left beginning of the text.
303 * This information cannot be taken from the layout object, because
304 * in LaTeX the beginning of the text fits in some cases
305 * (for example sections) exactly the label-width.
307 /// FIXME: move to TextMetrics.
308 int leftMargin(Buffer const &, int max_width, pit_type pit, pos_type pos) const;
309 int leftMargin(Buffer const &, int max_width, pit_type pit) const;
311 /// access to our paragraphs
312 ParagraphList const & paragraphs() const { return pars_; }
313 ParagraphList & paragraphs() { return pars_; }
314 /// return true if this is the main text
315 bool isMainText(Buffer const &) const;
317 /// is this row the last in the text?
318 /// FIXME: move to TextMetrics.
319 bool isLastRow(pit_type pit, Row const & row) const;
320 /// is this row the first in the text?
321 /// FIXME: move to TextMetrics.
322 bool isFirstRow(pit_type pit, Row const & row) const;
325 double spacing(Buffer const & buffer, Paragraph const & par) const;
326 /// make a suggestion for a label
327 /// FIXME: replace Cursor with DocIterator.
328 docstring getPossibleLabel(Cursor & cur) const;
329 /// is this paragraph right-to-left?
330 bool isRTL(Buffer const &, Paragraph const & par) const;
332 bool checkAndActivateInset(Cursor & cur, bool front);
335 void write(Buffer const & buf, std::ostream & os) const;
336 /// returns whether we've seen our usual 'end' marker
337 bool read(Buffer const & buf, Lexer & lex, ErrorList & errorList);
340 /// FIXME: move to TextMetrics.
341 int cursorX(BufferView const &, CursorSlice const & cursor,
342 bool boundary) const;
344 /// FIXME: move to TextMetrics.
345 int cursorY(BufferView const & bv, CursorSlice const & cursor,
346 bool boundary) const;
348 /// delete double spaces, leading spaces, and empty paragraphs around old cursor.
349 /// \retval true if a change has happened and we need a redraw.
350 /// FIXME: replace Cursor with DocIterator. This is not possible right
351 /// now because recordUndo() is called which needs a Cursor.
352 static bool deleteEmptyParagraphMechanism(Cursor & cur,
353 Cursor & old, bool & need_anchor_change);
355 /// delete double spaces, leading spaces, and empty paragraphs
356 /// from \first to \last paragraph
357 void deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool trackChanges);
360 /// the current font settings
363 Font real_current_font;
365 int background_color_;
372 /// our 'outermost' font. This is handed down from the surrounding
373 // inset through the pi/mi parameter (pi.base.font)
379 /// return past-the-last paragraph influenced by a layout
381 pit_type undoSpan(pit_type pit);
383 // fix the cursor `cur' after a characters has been deleted at `where'
384 // position. Called by deleteEmptyParagraphMechanism
385 static void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
387 // At cursor position 0, try to merge the paragraph with the one before it.
388 // Ignore change tracking, i.e., physically remove the end-of-par character
389 bool backspacePos0(Cursor & cur);
392 void deleteWordForward(Cursor & cur);
394 void deleteWordBackward(Cursor & cur);
396 void deleteLineForward(Cursor & cur);
399 /// set 'number' font property
400 void number(Cursor & cur);
402 /// paste plain text at current cursor.
403 /// \param str string to paste
404 /// \param asParagraphs whether to paste as paragraphs or as lines
405 void pasteString(Cursor & cur, docstring const & str,