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 "bufferview_funcs.h"
21 #include "ParagraphList_fwd.h"
22 #include "RowList_fwd.h"
23 #include "textcursor.h"
25 #include "insets/inset.h"
44 This class used to hold the mapping between buffer paragraphs and
45 screen rows. Nowadays, the Paragraphs take care of their rows
46 themselves and this contains just most of the code for manipulating
47 them and interaction with the Cursor.
50 // The inheritance from TextCursor should go. It's just there to ease
52 class LyXText : public TextCursor {
55 LyXText(BufferView *, InsetText *, bool ininset,
56 ParagraphList & paragraphs);
58 void init(BufferView *);
63 /// the current font settings
66 LyXFont real_current_font;
67 /// our buffer's default layout font
70 /// offset of drawn area to document start.
73 /// update all cached row positions
74 void updateRowPositions();
76 InsetText * inset_owner;
78 UpdatableInset * the_locking_inset;
81 int getRealCursorX() const;
83 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
85 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
87 LyXFont getLabelFont(ParagraphList::iterator pit) const;
89 void setCharFont(ParagraphList::iterator pit,
90 lyx::pos_type pos, LyXFont const & font);
91 void setCharFont(ParagraphList::iterator pit,
93 LyXFont const & font, bool toggleall);
95 /// what you expect when pressing <enter> at cursor position
96 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
98 /** set layout over selection and make a total rebreak of
101 ParagraphList::iterator
102 setLayout(LyXCursor & actual_cursor,
103 LyXCursor & selection_start,
104 LyXCursor & selection_end,
105 std::string const & layout);
107 void setLayout(std::string const & layout);
110 * Increase or decrease the nesting depth of the selected paragraph(s)
111 * if test_only, don't change any depths. Returns whether something
112 * (would have) changed
114 bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
116 /// get the depth at current cursor position
117 int getDepth() const;
119 /** set font over selection and make a total rebreak of those
121 toggleall defaults to false.
123 void setFont(LyXFont const &, bool toggleall = false);
125 /// rebreaks all paragaphs between the given pars.
126 void redoParagraphs(ParagraphList::iterator begin,
127 ParagraphList::iterator end);
128 /// rebreaks the given par
129 void redoParagraph(ParagraphList::iterator pit);
131 /// rebreaks the cursor par
132 void redoParagraph();
134 /// rebreaks the given par
135 void redoParagraphInternal(ParagraphList::iterator pit);
139 void toggleFree(LyXFont const &, bool toggleall = false);
142 std::string getStringToIndex();
144 /** insert a character, moves all the following breaks in the
145 same Paragraph one to the right and make a little rebreak
147 void insertChar(char c);
149 void insertInset(InsetOld * inset);
151 /// a full rebreak of the whole text
153 /// compute text metrics
154 void metrics(MetricsInfo & mi, Dimension & dim);
157 dispatch_result dispatch(FuncRequest const & cmd);
161 BufferView * bv() const;
163 friend class LyXScreen;
166 /// only the top-level LyXText has this non-zero
167 BufferView * bv_owner;
170 /// returns a pointer to a specified row.
171 RowList::iterator getRow(Paragraph & par, lyx::pos_type pos) const;
173 /// returns an iterator pointing to a cursor row
174 RowList::iterator getRow(LyXCursor const & cursor) const;
176 RowList::iterator cursorRow() const;
177 /// returns an iterator pointing to a cursor paragraph
178 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
180 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
182 int parOffset(ParagraphList::iterator pit) const;
184 ParagraphList::iterator cursorPar() const;
186 /** returns a pointer to the row near the specified y-coordinate
187 (relative to the whole text). y is set to the real beginning
190 RowList::iterator getRowNearY(int y,
191 ParagraphList::iterator & pit) const;
193 /** returns the column near the specified x-coordinate of the row
194 x is set to the real beginning of this column
196 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
197 Row const & row, int & x, bool & boundary) const;
199 /// need the selection cursor:
202 void clearSelection();
204 /// select the word we need depending on word_location
205 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
206 /// just selects the word the cursor is in
207 void selectWord(lyx::word_location loc);
208 /// returns the inset at cursor (if it exists), 0 otherwise
209 InsetOld * getInset() const;
211 /// accept selected change
214 /// reject selected change
217 /** 'selects" the next word, where the cursor is not in
218 and returns this word as string. THe cursor will be moved
219 to the beginning of this word.
220 With SelectSelectedWord can this be highlighted really
222 WordLangTuple const selectNextWordToSpellcheck(float & value);
224 void selectSelectedWord();
225 /// re-computes the cached coordinates in the cursor
228 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
229 /// returns true if par was empty and was removed
230 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
231 bool setfont = true, bool boundary = false);
233 void setCursor(LyXCursor &, lyx::paroffset_type par,
234 lyx::pos_type pos, bool boundary = false);
236 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
237 bool setfont = true, bool boundary = false);
239 void setCurrentFont();
242 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
244 void recUndo(lyx::paroffset_type first) const;
246 void setCursorFromCoordinates(int x, int y);
248 void setCursorFromCoordinates(LyXCursor &, int x, int y);
250 void cursorUp(bool selecting = false);
252 void cursorDown(bool selecting = false);
254 void cursorLeft(bool internal = true);
256 void cursorRight(bool internal = true);
258 void cursorLeftOneWord();
260 void cursorRightOneWord();
262 void cursorUpParagraph();
264 void cursorDownParagraph();
270 void cursorPrevious();
282 bool selectWordWhenUnderCursor(lyx::word_location);
288 text_capitalization = 1,
292 /// Change the case of the word at cursor position.
293 void changeCase(TextCase action);
298 void cutSelection(bool doclear = true, bool realcut = true);
300 void copySelection();
302 void pasteSelection(size_t sel_index = 0);
304 /** the DTP switches for paragraphs. LyX will store the top settings
305 always in the first physical paragraph, the bottom settings in the
306 last. When a paragraph is broken, the top settings rest, the bottom
307 settings are given to the new one. So I can make shure, they do not
308 duplicate themself (and you cannnot make dirty things with them! )
310 void setParagraph(bool line_top, bool line_bottom,
311 bool pagebreak_top, bool pagebreak_bottom,
312 VSpace const & space_top,
313 VSpace const & space_bottom,
314 Spacing const & spacing,
316 std::string const & labelwidthstring,
319 /* these things are for search and replace */
322 * Sets the selection from the current cursor position to length
323 * characters to the right. No safety checks.
325 void setSelectionRange(lyx::pos_type length);
327 /** simple replacing. The font of the first selected character
330 void replaceSelectionWithString(std::string const & str);
332 /// needed to insert the selection
333 void insertStringAsLines(std::string const & str);
334 /// needed to insert the selection
335 void insertStringAsParagraphs(std::string const & str);
337 /// Find next inset of some specified type.
338 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
339 std::string const & contents = std::string());
341 void gotoInset(std::vector<InsetOld::Code> const & codes,
344 void gotoInset(InsetOld::Code code, bool same_content);
347 int workWidth() const;
351 float getCursorX(ParagraphList::iterator pit,
352 Row const & row, lyx::pos_type pos,
353 lyx::pos_type last, bool boundary) const;
354 /// used in setlayout
355 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
357 /// Calculate and set the height of the row
358 void setHeightOfRow(ParagraphList::iterator, Row & row);
360 // fix the cursor `cur' after a characters has been deleted at `where'
361 // position. Called by deleteEmptyParagraphMechanism
362 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
364 /// delete double space (false) or empty paragraphs (true) around old_cursor
365 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
368 /** Updates all counters starting BEHIND the row. Changed paragraphs
369 * with a dynamic left margin will be rebroken. */
370 void updateCounters();
372 * Returns an inset if inset was hit, or 0 if not.
373 * If hit, the coordinates are changed relative to the inset.
375 InsetOld * checkInsetHit(int & x, int & y);
378 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
380 int singleWidth(ParagraphList::iterator pit,
381 lyx::pos_type pos, char c, LyXFont const & Font) const;
383 /// return the color of the canvas
384 LColor_color backgroundColor() const;
387 unsigned char transformChar(unsigned char c, Paragraph const & par,
388 lyx::pos_type pos) const;
391 * Returns the left beginning of the text.
392 * This information cannot be taken from the layout object, because
393 * in LaTeX the beginning of the text fits in some cases
394 * (for example sections) exactly the label-width.
396 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
398 int rightMargin(Paragraph const & par, Buffer const &, Row const & row) const;
400 /** this calculates the specified parameters. needed when setting
401 * the cursor and when creating a visible row */
402 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
406 void setCounter(Buffer const &, ParagraphList::iterator pit);
408 void deleteWordForward();
410 void deleteWordBackward();
412 void deleteLineForward();
414 /// sets row.end to the pos value *after* which a row should break.
415 /// for example, the pos after which isNewLine(pos) == true
416 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
418 /// returns the minimum space a row needs on the screen in pixel
419 int fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
422 * returns the minimum space a manual label needs on the
425 int labelFill(ParagraphList::iterator pit, Row const & row) const;
428 int labelEnd(ParagraphList::iterator pit, Row const & row) const;
439 ParagraphList * paragraphs_;
441 // special owner functions
443 ParagraphList & ownerParagraphs() const;
445 /// return true if this is owned by an inset.
446 bool isInInset() const;
448 /// return first row of text
449 RowList::iterator firstRow() const;
450 /// return last row of text
451 RowList::iterator lastRow() const;
452 /// return row "behind" last row of text
453 RowList::iterator endRow() const;
454 /// return next row crossing paragraph boundaries
455 void nextRow(ParagraphList::iterator & pit,
456 RowList::iterator & rit) const;
457 /// return previous row crossing paragraph boundaries
458 void previousRow(ParagraphList::iterator & pit,
459 RowList::iterator & rit) const;
461 /// is this row the last in the text?
462 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
463 /// is this row the first in the text?
464 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
467 std::string selectionAsString(Buffer const & buffer, bool label) const;
469 /** Cursor related data.
470 Later this variable has to be removed. There should be now internal
473 ///TextCursor cursor_;
474 /// prohibit this as long as there are back pointers...
475 LyXText(LyXText const &);
478 /// return the default height of a row in pixels, considering font zoom
479 extern int defaultRowHeight();