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 "lyxtextclass.h"
22 #include "ParagraphList_fwd.h"
23 #include "RowList_fwd.h"
24 #include "textcursor.h"
26 #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 {
56 LyXText(BufferView *, InsetText *, bool ininset, ParagraphList & plist);
58 void init(BufferView *);
61 /// update y coordinate cache of all paragraphs
62 void updateParPositions();
64 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
66 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
68 LyXFont getLabelFont(ParagraphList::iterator pit) const;
70 void setCharFont(ParagraphList::iterator pit,
71 lyx::pos_type pos, LyXFont const & font);
72 void setCharFont(ParagraphList::iterator pit,
74 LyXFont const & font, bool toggleall);
76 /// what you expect when pressing <enter> at cursor position
77 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
79 /** set layout over selection and make a total rebreak of
82 ParagraphList::iterator
83 setLayout(LyXCursor & actual_cursor,
84 LyXCursor & selection_start,
85 LyXCursor & selection_end,
86 std::string const & layout);
88 void setLayout(std::string const & layout);
91 * Increase or decrease the nesting depth of the selected paragraph(s)
92 * if test_only, don't change any depths. Returns whether something
93 * (would have) changed
95 bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
97 /// get the depth at current cursor position
100 /** set font over selection and make a total rebreak of those
102 toggleall defaults to false.
104 void setFont(LyXFont const &, bool toggleall = false);
106 /// rebreaks all paragaphs between the given pars.
107 void redoParagraphs(ParagraphList::iterator begin,
108 ParagraphList::iterator end);
109 /// rebreaks the given par
110 void redoParagraph(ParagraphList::iterator pit);
112 /// rebreaks the cursor par
113 void redoParagraph();
116 void toggleFree(LyXFont const &, bool toggleall = false);
119 std::string getStringToIndex();
121 /** insert a character, moves all the following breaks in the
122 same Paragraph one to the right and make a little rebreak
124 void insertChar(char c);
126 void insertInset(InsetOld * inset);
128 /// a full rebreak of the whole text
130 /// compute text metrics
131 void metrics(MetricsInfo & mi, Dimension & dim);
134 DispatchResult dispatch(FuncRequest const & cmd);
138 BufferView * bv() const;
140 friend class LyXScreen;
142 /// returns an iterator pointing to a cursor paragraph
143 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
145 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
147 int parOffset(ParagraphList::iterator pit) const;
149 ParagraphList::iterator cursorPar() const;
151 RowList::iterator cursorRow() const;
153 /** returns an iterator pointing to the row near the specified
154 * y-coordinate (relative to the whole text). y is set to the
155 * real beginning of this row
157 RowList::iterator getRowNearY(int y,
158 ParagraphList::iterator & pit) const;
160 /** returns the column near the specified x-coordinate of the row
161 x is set to the real beginning of this column
163 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
164 Row const & row, int & x, bool & boundary) const;
166 /// need the selection cursor:
169 void clearSelection();
171 /// select the word we need depending on word_location
172 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
173 /// just selects the word the cursor is in
174 void selectWord(lyx::word_location loc);
175 /// returns the inset at cursor (if it exists), 0 otherwise
176 InsetOld * getInset() const;
178 /// accept selected change
181 /// reject selected change
184 /// re-computes the cached coordinates in the cursor
187 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
188 /// returns true if par was empty and was removed
189 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
190 bool setfont = true, bool boundary = false);
192 void setCursor(LyXCursor &, lyx::paroffset_type par,
193 lyx::pos_type pos, bool boundary = false);
195 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
196 bool setfont = true, bool boundary = false);
198 void setCurrentFont();
201 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
203 void recUndo(lyx::paroffset_type first) const;
205 void setCursorFromCoordinates(int x, int y);
207 void setCursorFromCoordinates(LyXCursor &, int x, int y);
209 void cursorUp(bool selecting = false);
211 void cursorDown(bool selecting = false);
213 bool cursorLeft(bool internal = true);
215 bool cursorRight(bool internal = true);
217 void cursorLeftOneWord();
219 void cursorRightOneWord();
221 void cursorUpParagraph();
223 void cursorDownParagraph();
229 void cursorPrevious();
241 bool selectWordWhenUnderCursor(lyx::word_location);
247 text_capitalization = 1,
251 /// Change the case of the word at cursor position.
252 void changeCase(TextCase action);
257 void cutSelection(bool doclear = true, bool realcut = true);
259 void copySelection();
261 void pasteSelection(size_t sel_index = 0);
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.
269 VSpace const & space_top,
270 VSpace const & space_bottom,
271 Spacing const & spacing,
273 std::string const & labelwidthstring,
276 /* these things are for search and replace */
279 * Sets the selection from the current cursor position to length
280 * characters to the right. No safety checks.
282 void setSelectionRange(lyx::pos_type length);
284 /** simple replacing. The font of the first selected character
287 void replaceSelectionWithString(std::string const & str);
289 /// needed to insert the selection
290 void insertStringAsLines(std::string const & str);
291 /// needed to insert the selection
292 void insertStringAsParagraphs(std::string const & str);
294 /// Find next inset of some specified type.
295 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
296 std::string const & contents = std::string());
298 void gotoInset(std::vector<InsetOld::Code> const & codes,
301 void gotoInset(InsetOld::Code code, bool same_content);
303 /// current max text width
304 int textWidth() const;
306 /// updates all counters
307 void updateCounters();
308 /// Returns an inset if inset was hit, or 0 if not.
309 InsetOld * checkInsetHit(int x, int y);
312 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
314 int singleWidth(ParagraphList::iterator pit,
315 lyx::pos_type pos, char c, LyXFont const & Font) const;
317 /// return the color of the canvas
318 LColor_color backgroundColor() const;
321 * Returns the left beginning of the text.
322 * This information cannot be taken from the layout object, because
323 * in LaTeX the beginning of the text fits in some cases
324 * (for example sections) exactly the label-width.
326 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
327 int leftMargin(ParagraphList::iterator pit) const;
329 int rightMargin(Paragraph const & par) const;
331 /** this calculates the specified parameters. needed when setting
332 * the cursor and when creating a visible row */
333 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
336 // special owner functions
338 ParagraphList & ownerParagraphs() const;
340 /// return true if this is owned by an inset.
341 bool isInInset() const;
344 ParagraphList::iterator firstPar() const;
346 ParagraphList::iterator lastPar() const;
348 ParagraphList::iterator endPar() const;
350 /// return first row of text
351 RowList::iterator firstRow() const;
352 /// return last row of text
353 RowList::iterator lastRow() const;
354 /// return row "behind" last row of text
355 RowList::iterator endRow() const;
356 /// return next row crossing paragraph boundaries
357 void nextRow(ParagraphList::iterator & pit,
358 RowList::iterator & rit) const;
359 /// return previous row crossing paragraph boundaries
360 void previousRow(ParagraphList::iterator & pit,
361 RowList::iterator & rit) const;
363 /// is this row the last in the text?
364 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
365 /// is this row the first in the text?
366 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
369 std::string selectionAsString(Buffer const & buffer, bool label) const;
371 double spacing(Paragraph const &) const;
373 void cursorLeftOneWord(LyXCursor &);
375 void cursorRightOneWord(LyXCursor &);
378 DispatchResult moveRight();
380 DispatchResult moveLeft();
382 DispatchResult moveRightIntern(bool front,
383 bool activate_inset, bool selecting);
385 DispatchResult moveLeftIntern(bool front,
386 bool activate_inset, bool selecting);
388 DispatchResult moveUp();
390 DispatchResult moveDown();
392 bool checkAndActivateInset(bool front);
402 /// the current font settings
403 LyXFont current_font;
405 LyXFont real_current_font;
406 /// our buffer's default layout font
407 LyXFont defaultfont_;
409 InsetText * inset_owner;
411 /// only the top-level LyXText has this non-zero
412 BufferView * bv_owner;
419 ParagraphList * paragraphs_;
421 /// absolute document pixel coordinates of this LyXText
427 /// rebreaks the given par
428 void redoParagraphInternal(ParagraphList::iterator pit);
431 float getCursorX(ParagraphList::iterator pit,
432 Row const & row, lyx::pos_type pos, bool boundary) const;
433 /// used in setlayout
434 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
436 /// Calculate and set the height of the row
437 void setHeightOfRow(ParagraphList::iterator, Row & row);
439 // fix the cursor `cur' after a characters has been deleted at `where'
440 // position. Called by deleteEmptyParagraphMechanism
441 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
443 /// delete double space (false) or empty paragraphs (true) around old_cursor
444 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
447 void setCounter(Buffer const &, ParagraphList::iterator pit);
449 void deleteWordForward();
451 void deleteWordBackward();
453 void deleteLineForward();
455 /// sets row.end to the pos value *after* which a row should break.
456 /// for example, the pos after which isNewLine(pos) == true
457 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
459 /// sets row.witdh to the minimum space a row needs on the screen in pixel
460 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
463 * returns the minimum space a manual label needs on the
466 int labelFill(ParagraphList::iterator pit, Row const & row) const;
469 int labelEnd(ParagraphList::iterator pit) const;
473 /// set 'number' font property
475 /// is the cursor paragraph right-to-left?
479 /// return the default height of a row in pixels, considering font zoom
480 extern int defaultRowHeight();
483 std::string expandLabel(LyXTextClass const & textclass,
484 LyXLayout_ptr const & layout, bool appendix);