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 "lyxcursor.h"
21 #include "insets/inset.h"
23 #include "bufferview_funcs.h"
24 #include "textcursor.h"
42 This class used to hold the mapping between buffer paragraphs and
43 screen rows. Nowadays, the Paragraphs take care of their rows
44 themselves and this contains just most of the code for manipulating
45 them and interaction with the Cursor.
48 // The inheritance from TextCursor should go. It's just there to ease
50 class LyXText : public TextCursor {
53 LyXText(BufferView *, InsetText *, bool ininset,
54 ParagraphList & paragraphs);
56 void init(BufferView *);
61 /// the current font settings
64 LyXFont real_current_font;
65 /// our buffer's default layout font
68 /// offset of dran area to document start.
71 /// update all cached row positions
72 void updateRowPositions();
73 /// get the y coord. of the top of the screen (relative to doc start)
75 /// set the y coord. of the top of the screen (relative to doc start)
77 /// set the anchoring row. top_y will be computed relative to this
78 void anchor_row(RowList::iterator rit);
80 InsetText * inset_owner;
82 UpdatableInset * the_locking_inset;
85 int getRealCursorX() const;
87 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
89 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
91 LyXFont getLabelFont(ParagraphList::iterator pit) const;
93 void setCharFont(ParagraphList::iterator pit,
94 lyx::pos_type pos, LyXFont const & font);
95 void setCharFont(ParagraphList::iterator pit,
97 LyXFont const & font, bool toggleall);
99 /// what you expect when pressing <enter> at cursor position
100 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
102 /** set layout over selection and make a total rebreak of
105 ParagraphList::iterator
106 setLayout(LyXCursor & actual_cursor,
107 LyXCursor & selection_start,
108 LyXCursor & selection_end,
109 string const & layout);
111 void setLayout(string const & layout);
114 * Increase or decrease the nesting depth of the selected paragraph(s)
115 * if test_only, don't change any depths. Returns whether something
116 * (would have) changed
118 bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
120 /// get the depth at current cursor position
121 int getDepth() const;
123 /** set font over selection and make a total rebreak of those
125 toggleall defaults to false.
127 void setFont(LyXFont const &, bool toggleall = false);
129 /// rebreaks all paragaphs between the given pars.
130 int redoParagraphs(ParagraphList::iterator begin,
131 ParagraphList::iterator end);
132 /// rebreaks the given par
133 void redoParagraph(ParagraphList::iterator pit);
135 /// rebreaks the cursor par
136 void redoParagraph();
138 /// rebreaks the given par, return max row width
139 int redoParagraphInternal(ParagraphList::iterator pit);
143 void toggleFree(LyXFont const &, bool toggleall = false);
146 string getStringToIndex();
148 /** insert a character, moves all the following breaks in the
149 same Paragraph one to the right and make a little rebreak
151 void insertChar(char c);
153 void insertInset(InsetOld * inset);
155 /// a full rebreak of the whole text
157 /// compute text metrics
158 void metrics(MetricsInfo & mi, Dimension & dim);
161 InsetOld::RESULT dispatch(FuncRequest const & cmd);
165 BufferView * bv() const;
167 friend class LyXScreen;
170 /// only the top-level LyXText has this non-zero
171 BufferView * bv_owner;
174 /// returns a pointer to a specified row.
176 getRow(ParagraphList::iterator pit, lyx::pos_type pos) const;
178 /// returns a pointer cursor row
179 RowList::iterator getRow(LyXCursor const & cursor) const;
181 RowList::iterator cursorRow() const;
183 * Return the next row, when cursor is at the end of the
184 * previous row, for insets that take a full row.
186 * FIXME: explain why we need this ? especially for y...
188 RowList::iterator cursorIRow() const;
190 /** returns a pointer to the row near the specified y-coordinate
191 (relative to the whole text). y is set to the real beginning
194 RowList::iterator getRowNearY(int y,
195 ParagraphList::iterator & pit) const;
197 /** returns the column near the specified x-coordinate of the row
198 x is set to the real beginning of this column
200 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
201 RowList::iterator rit, int & x, bool & boundary) const;
203 /// need the selection cursor:
206 void clearSelection();
208 /// select the word we need depending on word_location
209 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
210 /// just selects the word the cursor is in
211 void selectWord(lyx::word_location loc);
212 /// returns the inset at cursor (if it exists), 0 otherwise
213 InsetOld * getInset() const;
215 /// accept selected change
218 /// reject selected change
221 /** 'selects" the next word, where the cursor is not in
222 and returns this word as string. THe cursor will be moved
223 to the beginning of this word.
224 With SelectSelectedWord can this be highlighted really
226 WordLangTuple const selectNextWordToSpellcheck(float & value);
228 void selectSelectedWord();
229 /// re-computes the cached coordinates in the cursor
231 /// returns true if par was empty and was removed
232 bool setCursor(ParagraphList::iterator pit,
235 bool boundary = false);
237 void setCursor(LyXCursor &, ParagraphList::iterator pit,
239 bool boundary = false);
241 void setCursorIntern(ParagraphList::iterator pit,
244 bool boundary = false);
246 void setCurrentFont();
249 bool isBoundary(Buffer const *, Paragraph const & par,
250 lyx::pos_type pos) const;
252 bool isBoundary(Buffer const *, Paragraph const & par,
254 LyXFont const & font) const;
257 void setCursorFromCoordinates(int x, int y);
259 void setCursorFromCoordinates(LyXCursor &,
262 void cursorUp(bool selecting = false);
264 void cursorDown(bool selecting = false);
266 void cursorLeft(bool internal = true);
268 void cursorRight(bool internal = true);
270 void cursorLeftOneWord();
272 void cursorRightOneWord();
274 void cursorUpParagraph();
276 void cursorDownParagraph();
282 void cursorPrevious();
294 bool selectWordWhenUnderCursor(lyx::word_location);
300 text_capitalization = 1,
304 /// Change the case of the word at cursor position.
305 void changeCase(TextCase action);
310 void cutSelection(bool doclear = true, bool realcut = true);
312 void copySelection();
314 void pasteSelection(size_t sel_index = 0);
316 /** the DTP switches for paragraphs. LyX will store the top settings
317 always in the first physical paragraph, the bottom settings in the
318 last. When a paragraph is broken, the top settings rest, the bottom
319 settings are given to the new one. So I can make shure, they do not
320 duplicate themself (and you cannnot make dirty things with them! )
322 void setParagraph(bool line_top, bool line_bottom,
323 bool pagebreak_top, bool pagebreak_bottom,
324 VSpace const & space_top,
325 VSpace const & space_bottom,
326 Spacing const & spacing,
328 string const & labelwidthstring,
331 /* these things are for search and replace */
334 * Sets the selection from the current cursor position to length
335 * characters to the right. No safety checks.
337 void setSelectionRange(lyx::pos_type length);
339 /** simple replacing. The font of the first selected character
342 void replaceSelectionWithString(string const & str);
344 /// needed to insert the selection
345 void insertStringAsLines(string const & str);
346 /// needed to insert the selection
347 void insertStringAsParagraphs(string const & str);
349 /// Find next inset of some specified type.
350 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
351 string const & contents = string());
353 void gotoInset(std::vector<InsetOld::Code> const & codes,
356 void gotoInset(InsetOld::Code code, bool same_content);
359 int workWidth() const;
362 void computeBidiTables(ParagraphList::iterator pit,
363 Buffer const *, RowList::iterator row) const;
364 /// Maps positions in the visual string to positions in logical string.
365 lyx::pos_type log2vis(lyx::pos_type pos) const;
366 /// Maps positions in the logical string to positions in visual string.
367 lyx::pos_type vis2log(lyx::pos_type pos) const;
369 lyx::pos_type bidi_level(lyx::pos_type pos) const;
371 bool bidi_InRange(lyx::pos_type pos) const;
374 float getCursorX(ParagraphList::iterator pit,
375 RowList::iterator rit, lyx::pos_type pos,
376 lyx::pos_type last, bool boundary) const;
377 /// used in setlayout
378 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
380 /// Calculate and set the height of the row
381 void setHeightOfRow(ParagraphList::iterator, RowList::iterator rit);
383 // fix the cursor `cur' after a characters has been deleted at `where'
384 // position. Called by deleteEmptyParagraphMechanism
385 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
387 /// delete double space (false) or empty paragraphs (true) around old_cursor
388 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
391 /** Updates all counters starting BEHIND the row. Changed paragraphs
392 * with a dynamic left margin will be rebroken. */
393 void updateCounters();
395 * Returns an inset if inset was hit, or 0 if not.
396 * If hit, the coordinates are changed relative to the inset.
398 InsetOld * checkInsetHit(int & x, int & y);
401 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
403 int singleWidth(ParagraphList::iterator pit,
404 lyx::pos_type pos, char c, LyXFont const & Font) const;
406 /// return the color of the canvas
407 LColor::color backgroundColor() const;
410 mutable bool bidi_same_direction;
412 unsigned char transformChar(unsigned char c, Paragraph const & par,
413 lyx::pos_type pos) const;
416 * Returns the left beginning of the text.
417 * This information cannot be taken from the layout object, because
418 * in LaTeX the beginning of the text fits in some cases
419 * (for example sections) exactly the label-width.
421 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
423 int rightMargin(ParagraphList::iterator pit, Buffer const &, Row const & row) const;
425 /** this calculates the specified parameters. needed when setting
426 * the cursor and when creating a visible row */
427 void prepareToPrint(ParagraphList::iterator pit,
428 RowList::iterator row) const;
432 void setCounter(Buffer const *, ParagraphList::iterator pit);
434 void deleteWordForward();
436 void deleteWordBackward();
438 void deleteLineForward();
441 * some low level functions
445 /// sets row.end to the pos value *after* which a row should break.
446 /// for example, the pos after which isNewLine(pos) == true
447 lyx::pos_type rowBreakPoint(ParagraphList::iterator pit,
448 Row const & row) const;
450 /// returns the minimum space a row needs on the screen in pixel
451 int fill(ParagraphList::iterator pit,
452 RowList::iterator row, int workwidth) const;
455 * returns the minimum space a manual label needs on the
458 int labelFill(ParagraphList::iterator pit, Row const & row) const;
461 int labelEnd(ParagraphList::iterator pit, Row const & row) const;
464 mutable std::vector<lyx::pos_type> log2vis_list;
466 mutable std::vector<lyx::pos_type> vis2log_list;
468 mutable std::vector<lyx::pos_type> bidi_levels;
470 mutable lyx::pos_type bidi_start;
472 mutable lyx::pos_type bidi_end;
475 const bool in_inset_;
477 ParagraphList & paragraphs_;
483 // special owner functions
485 ParagraphList & ownerParagraphs() const;
487 /// return true if this is owned by an inset.
488 bool isInInset() const;
490 /// return first row of text
491 RowList::iterator firstRow() const;
492 /// return last row of text
493 RowList::iterator lastRow() const;
494 /// return row "behind" last row of text
495 RowList::iterator endRow() const;
496 /// return next row crossing paragraph boundaries
497 void nextRow(ParagraphList::iterator & pit,
498 RowList::iterator & rit) const;
499 /// return previous row crossing paragraph boundaries
500 void previousRow(ParagraphList::iterator & pit,
501 RowList::iterator & rit) const;
507 /** Cursor related data.
508 Later this variable has to be removed. There should be now internal
511 ///TextCursor cursor_;
514 /// return the default height of a row in pixels, considering font zoom
515 extern int defaultRowHeight();