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 InsetText * inset_owner;
72 UpdatableInset * the_locking_inset;
74 /// update all cached row positions
75 void updateRowPositions();
77 int getRealCursorX() const;
79 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
81 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
83 LyXFont getLabelFont(ParagraphList::iterator pit) const;
85 void setCharFont(ParagraphList::iterator pit,
86 lyx::pos_type pos, LyXFont const & font);
87 void setCharFont(ParagraphList::iterator pit,
89 LyXFont const & font, bool toggleall);
91 /// what you expect when pressing <enter> at cursor position
92 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
94 /** set layout over selection and make a total rebreak of
97 ParagraphList::iterator
98 setLayout(LyXCursor & actual_cursor,
99 LyXCursor & selection_start,
100 LyXCursor & selection_end,
101 std::string const & layout);
103 void setLayout(std::string const & layout);
106 * Increase or decrease the nesting depth of the selected paragraph(s)
107 * if test_only, don't change any depths. Returns whether something
108 * (would have) changed
110 bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
112 /// get the depth at current cursor position
113 int getDepth() const;
115 /** set font over selection and make a total rebreak of those
117 toggleall defaults to false.
119 void setFont(LyXFont const &, bool toggleall = false);
121 /// rebreaks all paragaphs between the given pars.
122 void redoParagraphs(ParagraphList::iterator begin,
123 ParagraphList::iterator end);
124 /// rebreaks the given par
125 void redoParagraph(ParagraphList::iterator pit);
127 /// rebreaks the cursor par
128 void redoParagraph();
130 /// rebreaks the given par
131 void redoParagraphInternal(ParagraphList::iterator pit);
135 void toggleFree(LyXFont const &, bool toggleall = false);
138 std::string getStringToIndex();
140 /** insert a character, moves all the following breaks in the
141 same Paragraph one to the right and make a little rebreak
143 void insertChar(char c);
145 void insertInset(InsetOld * inset);
147 /// a full rebreak of the whole text
149 /// compute text metrics
150 void metrics(MetricsInfo & mi, Dimension & dim);
153 DispatchResult dispatch(FuncRequest const & cmd);
157 BufferView * bv() const;
159 friend class LyXScreen;
162 /// only the top-level LyXText has this non-zero
163 BufferView * bv_owner;
165 /// returns an iterator pointing to a cursor paragraph
166 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
168 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
170 int parOffset(ParagraphList::iterator pit) const;
172 ParagraphList::iterator cursorPar() const;
174 RowList::iterator cursorRow() const;
176 /** returns a pointer to the row near the specified y-coordinate
177 (relative to the whole text). y is set to the real beginning
180 RowList::iterator getRowNearY(int y,
181 ParagraphList::iterator & pit) const;
183 /** returns the column near the specified x-coordinate of the row
184 x is set to the real beginning of this column
186 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
187 Row const & row, int & x, bool & boundary) const;
189 /// need the selection cursor:
192 void clearSelection();
194 /// select the word we need depending on word_location
195 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
196 /// just selects the word the cursor is in
197 void selectWord(lyx::word_location loc);
198 /// returns the inset at cursor (if it exists), 0 otherwise
199 InsetOld * getInset() const;
201 /// accept selected change
204 /// reject selected change
207 /** 'selects" the next word, where the cursor is not in
208 and returns this word as string. THe cursor will be moved
209 to the beginning of this word.
210 With SelectSelectedWord can this be highlighted really
212 WordLangTuple const selectNextWordToSpellcheck(float & value);
214 void selectSelectedWord();
215 /// re-computes the cached coordinates in the cursor
218 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
219 /// returns true if par was empty and was removed
220 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
221 bool setfont = true, bool boundary = false);
223 void setCursor(LyXCursor &, lyx::paroffset_type par,
224 lyx::pos_type pos, bool boundary = false);
226 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
227 bool setfont = true, bool boundary = false);
229 void setCurrentFont();
232 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
234 void recUndo(lyx::paroffset_type first) const;
236 void setCursorFromCoordinates(int x, int y);
238 void setCursorFromCoordinates(LyXCursor &, int x, int y);
240 void cursorUp(bool selecting = false);
242 void cursorDown(bool selecting = false);
244 void cursorLeft(bool internal = true);
246 void cursorRight(bool internal = true);
248 void cursorLeftOneWord();
250 void cursorRightOneWord();
252 void cursorUpParagraph();
254 void cursorDownParagraph();
260 void cursorPrevious();
272 bool selectWordWhenUnderCursor(lyx::word_location);
278 text_capitalization = 1,
282 /// Change the case of the word at cursor position.
283 void changeCase(TextCase action);
288 void cutSelection(bool doclear = true, bool realcut = true);
290 void copySelection();
292 void pasteSelection(size_t sel_index = 0);
294 /** the DTP switches for paragraphs. LyX will store the top settings
295 always in the first physical paragraph, the bottom settings in the
296 last. When a paragraph is broken, the top settings rest, the bottom
297 settings are given to the new one.
300 VSpace const & space_top,
301 VSpace const & space_bottom,
302 Spacing const & spacing,
304 std::string const & labelwidthstring,
307 /* these things are for search and replace */
310 * Sets the selection from the current cursor position to length
311 * characters to the right. No safety checks.
313 void setSelectionRange(lyx::pos_type length);
315 /** simple replacing. The font of the first selected character
318 void replaceSelectionWithString(std::string const & str);
320 /// needed to insert the selection
321 void insertStringAsLines(std::string const & str);
322 /// needed to insert the selection
323 void insertStringAsParagraphs(std::string const & str);
325 /// Find next inset of some specified type.
326 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
327 std::string const & contents = std::string());
329 void gotoInset(std::vector<InsetOld::Code> const & codes,
332 void gotoInset(InsetOld::Code code, bool same_content);
335 int workWidth() const;
339 float getCursorX(ParagraphList::iterator pit,
340 Row const & row, lyx::pos_type pos, bool boundary) const;
341 /// used in setlayout
342 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
344 /// Calculate and set the height of the row
345 void setHeightOfRow(ParagraphList::iterator, Row & row);
347 // fix the cursor `cur' after a characters has been deleted at `where'
348 // position. Called by deleteEmptyParagraphMechanism
349 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
351 /// delete double space (false) or empty paragraphs (true) around old_cursor
352 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
355 /** Updates all counters starting BEHIND the row. Changed paragraphs
356 * with a dynamic left margin will be rebroken. */
357 void updateCounters();
359 * Returns an inset if inset was hit, or 0 if not.
360 * If hit, the coordinates are changed relative to the inset.
362 InsetOld * checkInsetHit(int & x, int & y);
365 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
367 int singleWidth(ParagraphList::iterator pit,
368 lyx::pos_type pos, char c, LyXFont const & Font) const;
370 /// return the color of the canvas
371 LColor_color backgroundColor() const;
374 * Returns the left beginning of the text.
375 * This information cannot be taken from the layout object, because
376 * in LaTeX the beginning of the text fits in some cases
377 * (for example sections) exactly the label-width.
379 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
381 int rightMargin(Paragraph const & par, Buffer const &) const;
383 /** this calculates the specified parameters. needed when setting
384 * the cursor and when creating a visible row */
385 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
389 void setCounter(Buffer const &, ParagraphList::iterator pit);
391 void deleteWordForward();
393 void deleteWordBackward();
395 void deleteLineForward();
397 /// sets row.end to the pos value *after* which a row should break.
398 /// for example, the pos after which isNewLine(pos) == true
399 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
401 /// sets row.witdh to the minimum space a row needs on the screen in pixel
402 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
405 * returns the minimum space a manual label needs on the
408 int labelFill(ParagraphList::iterator pit, Row const & row) const;
411 int labelEnd(ParagraphList::iterator pit, Row const & row) const;
422 ParagraphList * paragraphs_;
424 // special owner functions
426 ParagraphList & ownerParagraphs() const;
428 /// return true if this is owned by an inset.
429 bool isInInset() const;
431 /// return first row of text
432 RowList::iterator firstRow() const;
433 /// return last row of text
434 RowList::iterator lastRow() const;
435 /// return row "behind" last row of text
436 RowList::iterator endRow() const;
437 /// return next row crossing paragraph boundaries
438 void nextRow(ParagraphList::iterator & pit,
439 RowList::iterator & rit) const;
440 /// return previous row crossing paragraph boundaries
441 void previousRow(ParagraphList::iterator & pit,
442 RowList::iterator & rit) const;
444 /// is this row the last in the text?
445 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
446 /// is this row the first in the text?
447 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
450 std::string selectionAsString(Buffer const & buffer, bool label) const;
452 double spacing(Paragraph const &) const;
454 /** Cursor related data.
455 Later this variable has to be removed. There should be now internal
458 ///TextCursor cursor_;
459 /// prohibit this as long as there are back pointers...
460 LyXText(LyXText const &);
462 // cache for cursorPar()
463 mutable ParagraphList::iterator cache_par_;
464 mutable int cache_pos_;
467 /// return the default height of a row in pixels, considering font zoom
468 extern int defaultRowHeight();