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"
45 /// This class encapsulates the main text data and operations in LyX
51 /// \return true if there's no content at all.
52 /// \warning a non standard layout on an empty paragraph doesn't
57 Font getFont(Buffer const & buffer, Paragraph const & par,
60 void applyOuterFont(Buffer const & buffer, Font &) const;
62 Font getLayoutFont(Buffer const & buffer, pit_type pit) const;
64 Font getLabelFont(Buffer const & buffer,
65 Paragraph const & par) const;
66 /** Set font of character at position \p pos in paragraph \p pit.
67 * Must not be called if \p pos denotes an inset with text contents,
68 * and the inset is not allowed inside a font change (see below).
70 void setCharFont(Buffer const & buffer, pit_type pit, pos_type pos,
73 /** Needed to propagate font changes to all text cells of insets
74 * that are not allowed inside a font change (bug 1973).
75 * Must not be called if \p pos denotes an ordinary character or an
76 * inset that is alowed inside a font change.
77 * FIXME: This should be removed, see documentation of noFontChange
80 void setInsetFont(Buffer const & buffer, pit_type pit, pos_type pos,
81 Font const & font, bool toggleall = false);
83 /// what you expect when pressing \<enter\> at cursor position
84 void breakParagraph(Cursor & cur, bool keep_layout = false);
86 /// set layout over selection
87 void setLayout(Buffer const & buffer, pit_type start, pit_type end,
88 docstring const & layout);
89 /// Set given layout to current cursor position.
90 /// FIXME: replace Cursor with DocIterator.
91 void setLayout(Cursor & cur, docstring const & layout);
93 /// what type of depth change to make
98 /// Increase or decrease the nesting depth of the selected paragraph(s)
99 /// FIXME: replace Cursor with DocIterator.
100 void changeDepth(Cursor & cur, DEPTH_CHANGE type);
102 /// Returns whether something would be changed by changeDepth
103 /// FIXME: replace Cursor with DocIterator.
104 bool changeDepthAllowed(Cursor & cur, DEPTH_CHANGE type) const;
106 /// Set font over selection paragraphs and rebreak.
107 /// FIXME: replace Cursor with DocIterator.
108 void setFont(Cursor & cur, Font const &, bool toggleall = false);
109 /// Set font from \p begin to \p end and rebreak.
110 void setFont(Buffer const & buffer, CursorSlice const & begin,
111 CursorSlice const & end, Font const &,
112 bool toggleall = false);
115 void toggleFree(Cursor & cur, Font const &, bool toggleall = false);
118 /// FIXME: replace Cursor with DocIterator.
119 docstring getStringToIndex(Cursor const & cur);
121 /// insert a character at cursor position
122 /// FIXME: replace Cursor with DocIterator.
123 void insertChar(Cursor & cur, char_type c);
124 /// insert an inset at cursor position
125 /// FIXME: replace Cursor with DocIterator.
126 void insertInset(Cursor & cur, Inset * inset);
128 /// draw text (only used for insets)
129 void draw(PainterInfo & pi, int x, int y) const;
130 /// draw textselection
131 void drawSelection(PainterInfo & pi, int x, int y) const;
133 /// try to handle that request
134 /// FIXME: replace Cursor with DocIterator.
135 void dispatch(Cursor & cur, FuncRequest & cmd);
136 /// do we want to handle this event?
137 bool getStatus(Cursor & cur, FuncRequest const & cmd,
138 FuncStatus & status) const;
140 /// read-only access to individual paragraph
141 Paragraph const & getPar(pit_type pit) const { return pars_[pit]; }
142 /// read-write access to individual paragraph
143 Paragraph & getPar(pit_type pit) { return pars_[pit]; }
144 // Returns the current font and depth as a message.
145 /// FIXME: replace Cursor with DocIterator.
146 docstring currentState(Cursor & cur);
148 /** returns row near the specified
149 * y-coordinate in given paragraph (relative to the screen).
151 /// FIXME: move to TextMetrics.
152 Row const & getRowNearY(BufferView const & bv, int y,
155 /// returns the paragraph number closest to screen y-coordinate.
156 /// This method uses the BufferView CoordCache to locate the
157 /// paragraph. The y-coodinate is allowed to be off-screen and
158 /// the CoordCache will be automatically updated if needed. This is
159 /// the reason why we need a non const BufferView.
160 /// FIXME: move to TextMetrics.
161 pit_type getPitNearY(BufferView & bv, int y) const;
163 /** Find the word under \c from in the relative location
164 * defined by \c word_location.
165 * @param from return here the start of the word
166 * @param to return here the end of the word
168 void getWord(CursorSlice & from, CursorSlice & to, word_location const);
169 /// just selects the word the cursor is in
170 void selectWord(Cursor & cur, word_location loc);
172 /// what type of change operation to make
177 /// accept or reject the selected change
178 void acceptOrRejectChanges(Cursor & cur, ChangeOp op);
179 /// accept the changes within the complete Text
180 void acceptChanges(BufferParams const & bparams);
181 /// reject the changes within the complete Text
182 void rejectChanges(BufferParams const & bparams);
184 /// returns true if par was empty and was removed
185 bool setCursor(Cursor & cur, pit_type par, pos_type pos,
186 bool setfont = true, bool boundary = false);
188 void setCursor(CursorSlice &, pit_type par, pos_type pos);
190 void setCursorIntern(Cursor & cur, pit_type par,
191 pos_type pos, bool setfont = true, bool boundary = false);
193 void setCurrentFont(Cursor & cur);
196 void recUndo(Cursor & cur, pit_type first, pit_type last) const;
198 void recUndo(Cursor & cur, pit_type first) const;
200 /// sets cursor only within this Text.
201 /// x,y are screen coordinates
202 void setCursorFromCoordinates(Cursor & cur, int x, int y);
204 /// sets cursor recursively descending into nested editable insets
206 \return the inset pointer if x,y is covering that inset
207 \param x,y are absolute screen coordinates.
208 \retval inset is non-null if the cursor is positionned inside
210 /// FIXME: move to TextMetrics.
211 /// FIXME: cleanup to use BufferView::getCoveringInset() and
212 /// setCursorFromCoordinates() instead of checkInsetHit().
213 Inset * editXY(Cursor & cur, int x, int y);
215 /// Move cursor one position left
217 * Returns true if an update is needed after the move.
219 bool cursorLeft(Cursor & cur);
220 /// Move cursor one position right
222 * Returns true if an update is needed after the move.
224 bool cursorRight(Cursor & cur);
226 bool cursorLeftOneWord(Cursor & cur);
228 bool cursorRightOneWord(Cursor & cur);
230 bool cursorUpParagraph(Cursor & cur);
232 bool cursorDownParagraph(Cursor & cur);
234 /// FIXME: move to TextMetrics.
235 bool cursorHome(Cursor & cur);
237 /// FIXME: move to TextMetrics.
238 bool cursorEnd(Cursor & cur);
240 void cursorPrevious(Cursor & cur);
242 void cursorNext(Cursor & cur);
244 bool cursorTop(Cursor & cur);
246 bool cursorBottom(Cursor & cur);
247 /// Erase character at cursor. Honour change tracking
248 /// FIXME: replace Cursor with DocIterator.
249 bool erase(Cursor & cur);
250 /// Delete character before cursor. Honour CT
251 /// FIXME: replace Cursor with DocIterator.
252 bool backspace(Cursor & cur);
253 // Dissolve the inset under cursor
254 /// FIXME: replace Cursor with DocIterator.
255 bool dissolveInset(Cursor & cur);
257 bool selectWordWhenUnderCursor(Cursor & cur, word_location);
263 text_capitalization = 1,
267 /// Change the case of the word at cursor position.
268 void changeCase(Cursor & cur, TextCase action);
269 /// Transposes the character at the cursor with the one before it
270 void charsTranspose(Cursor & cur);
272 /** the DTP switches for paragraphs. LyX will store the top settings
273 always in the first physical paragraph, the bottom settings in the
274 last. When a paragraph is broken, the top settings rest, the bottom
275 settings are given to the new one.
276 This function will handle a multi-paragraph selection.
278 void setParagraphs(Cursor & cur, docstring arg, bool modify = false);
279 /// Sets parameters for current or selected paragraphs
280 void setParagraphs(Cursor & cur, ParagraphParameters const & p);
282 /* these things are for search and replace */
284 /// needed to insert the selection
285 /// FIXME: replace Cursor with DocIterator.
286 void insertStringAsLines(Cursor & cur, docstring const & str);
287 /// needed to insert the selection
288 /// FIXME: replace Cursor with DocIterator.
289 void insertStringAsParagraphs(Cursor & cur, docstring const & str);
291 /// Returns an inset if inset was hit, or 0 if not.
292 /// \warning This method is not recursive! It will return the
293 /// outermost inset within this Text.
294 /// \sa BufferView::getCoveringInset() to get the innermost inset.
295 Inset * checkInsetHit(BufferView &, int x, int y);
297 /// return the color of the canvas
298 Color_color backgroundColor() const;
301 * Returns the left beginning of the text.
302 * This information cannot be taken from the layout object, because
303 * in LaTeX the beginning of the text fits in some cases
304 * (for example sections) exactly the label-width.
306 /// FIXME: move to TextMetrics.
307 int leftMargin(Buffer const &, int max_width, pit_type pit, pos_type pos) const;
308 int leftMargin(Buffer const &, int max_width, pit_type pit) const;
310 /// access to our paragraphs
311 ParagraphList const & paragraphs() const { return pars_; }
312 ParagraphList & paragraphs() { return pars_; }
313 /// return true if this is the main text
314 bool isMainText(Buffer const &) const;
316 /// is this row the last in the text?
317 /// FIXME: move to TextMetrics.
318 bool isLastRow(pit_type pit, Row const & row) const;
319 /// is this row the first in the text?
320 /// FIXME: move to TextMetrics.
321 bool isFirstRow(pit_type pit, Row const & row) const;
324 double spacing(Buffer const & buffer, Paragraph const & par) const;
325 /// make a suggestion for a label
326 /// FIXME: replace Cursor with DocIterator.
327 docstring getPossibleLabel(Cursor & cur) const;
328 /// is this paragraph right-to-left?
329 bool isRTL(Buffer const &, Paragraph const & par) const;
330 /// is this position in the paragraph right-to-left?
331 bool isRTL(Buffer const & buffer, CursorSlice const & sl, bool boundary) const;
332 /// is between pos-1 and pos an RTL<->LTR boundary?
333 bool isRTLBoundary(Buffer const & buffer, Paragraph const & par,
335 /// would be a RTL<->LTR boundary between pos and the given font?
336 bool isRTLBoundary(Buffer const & buffer, Paragraph const & par,
337 pos_type pos, Font const & font) const;
340 bool checkAndActivateInset(Cursor & cur, bool front);
343 void write(Buffer const & buf, std::ostream & os) const;
344 /// returns whether we've seen our usual 'end' marker
345 bool read(Buffer const & buf, Lexer & lex, ErrorList & errorList);
348 /// FIXME: move to TextMetrics.
349 int cursorX(BufferView const &, CursorSlice const & cursor,
350 bool boundary) const;
352 /// FIXME: move to TextMetrics.
353 int cursorY(BufferView const & bv, CursorSlice const & cursor,
354 bool boundary) const;
356 /// delete double spaces, leading spaces, and empty paragraphs around old cursor.
357 /// \retval true if a change has happened and we need a redraw.
358 /// FIXME: replace Cursor with DocIterator. This is not possible right
359 /// now because recordUndo() is called which needs a Cursor.
360 static bool deleteEmptyParagraphMechanism(Cursor & cur,
361 Cursor & old, bool & need_anchor_change);
363 /// delete double spaces, leading spaces, and empty paragraphs
364 /// from \first to \last paragraph
365 void deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool trackChanges);
368 /// the current font settings
371 Font real_current_font;
373 int background_color_;
378 /// our 'outermost' font. This is handed down from the surrounding
379 // inset through the pi/mi parameter (pi.base.font)
385 /// return past-the-last paragraph influenced by a layout
387 pit_type undoSpan(pit_type pit);
389 // fix the cursor `cur' after a characters has been deleted at `where'
390 // position. Called by deleteEmptyParagraphMechanism
391 static void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
393 // At cursor position 0, try to merge the paragraph with the one before it.
394 // Ignore change tracking, i.e., physically remove the end-of-par character
395 bool backspacePos0(Cursor & cur);
396 /// handle the case where bibitems were deleted
397 bool handleBibitems(Cursor & cur);
400 void deleteWordForward(Cursor & cur);
402 void deleteWordBackward(Cursor & cur);
404 void deleteLineForward(Cursor & cur);
407 /// set 'number' font property
408 void number(Cursor & cur);
409 /// draw selection for a single row
410 void drawRowSelection(PainterInfo & pi, int x, Row const & row,
411 DocIterator const & beg, DocIterator const & end,
412 bool drawOnBegMargin, bool drawOnEndMargin) const;
414 /// paste plain text at current cursor.
415 /// \param str string to paste
416 /// \param asParagraphs whether to paste as paragraphs or as lines
417 void pasteString(Cursor & cur, docstring const & str,