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 void redoParagraphs(ParagraphList::iterator begin,
131 ParagraphList::iterator end);
132 /// rebreaks the given par
133 void redoParagraph(ParagraphList::iterator pit);
134 /// rebreaks the cursor par
135 void redoParagraph();
138 void toggleFree(LyXFont const &, bool toggleall = false);
141 string getStringToIndex();
143 /** insert a character, moves all the following breaks in the
144 same Paragraph one to the right and make a little rebreak
146 void insertChar(char c);
148 void insertInset(InsetOld * inset);
150 /// a full rebreak of the whole text
152 /// compute text metrics
153 void metrics(MetricsInfo & mi, Dimension & dim);
156 InsetOld::RESULT dispatch(FuncRequest const & cmd);
160 BufferView * bv() const;
162 friend class LyXScreen;
165 /// only the top-level LyXText has this non-zero
166 BufferView * bv_owner;
169 /// returns a pointer to a specified row.
171 getRow(ParagraphList::iterator pit, lyx::pos_type pos) const;
173 /// returns a pointer cursor row
174 RowList::iterator getRow(LyXCursor const & cursor) const;
176 RowList::iterator cursorRow() const;
178 * Return the next row, when cursor is at the end of the
179 * previous row, for insets that take a full row.
181 * FIXME: explain why we need this ? especially for y...
183 RowList::iterator cursorIRow() const;
185 /** returns a pointer to the row near the specified y-coordinate
186 (relative to the whole text). y is set to the real beginning
189 RowList::iterator getRowNearY(int & y,
190 ParagraphList::iterator & pit) const;
192 /** returns the column near the specified x-coordinate of the row
193 x is set to the real beginning of this column
195 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
196 RowList::iterator rit, int & x, bool & boundary) const;
198 /** returns a pointer to a specified row. y is set to the beginning
202 getRow(ParagraphList::iterator pit, lyx::pos_type pos, int & y) const;
204 /// need the selection cursor:
207 void clearSelection();
209 /// select the word we need depending on word_location
210 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
211 /// just selects the word the cursor is in
212 void selectWord(lyx::word_location loc);
213 /// returns the inset at cursor (if it exists), 0 otherwise
214 InsetOld * getInset() const;
216 /// accept selected change
219 /// reject selected change
222 /** 'selects" the next word, where the cursor is not in
223 and returns this word as string. THe cursor will be moved
224 to the beginning of this word.
225 With SelectSelectedWord can this be highlighted really
227 WordLangTuple const selectNextWordToSpellcheck(float & value);
229 void selectSelectedWord();
230 /// re-computes the cached coordinates in the cursor
232 /// returns true if par was empty and was removed
233 bool setCursor(ParagraphList::iterator pit,
236 bool boundary = false);
238 void setCursor(LyXCursor &, ParagraphList::iterator pit,
240 bool boundary = false);
242 void setCursorIntern(ParagraphList::iterator pit,
245 bool boundary = false);
247 void setCurrentFont();
250 bool isBoundary(Buffer const *, Paragraph const & par,
251 lyx::pos_type pos) const;
253 bool isBoundary(Buffer const *, Paragraph const & par,
255 LyXFont const & font) const;
258 void setCursorFromCoordinates(int x, int y);
260 void setCursorFromCoordinates(LyXCursor &,
263 void cursorUp(bool selecting = false);
265 void cursorDown(bool selecting = false);
267 void cursorLeft(bool internal = true);
269 void cursorRight(bool internal = true);
271 void cursorLeftOneWord();
273 void cursorRightOneWord();
275 void cursorUpParagraph();
277 void cursorDownParagraph();
283 void cursorPrevious();
295 bool selectWordWhenUnderCursor(lyx::word_location);
301 text_capitalization = 1,
305 /// Change the case of the word at cursor position.
306 void changeCase(TextCase action);
311 void cutSelection(bool doclear = true, bool realcut = true);
313 void copySelection();
315 void pasteSelection(size_t sel_index = 0);
317 /** the DTP switches for paragraphs. LyX will store the top settings
318 always in the first physical paragraph, the bottom settings in the
319 last. When a paragraph is broken, the top settings rest, the bottom
320 settings are given to the new one. So I can make shure, they do not
321 duplicate themself (and you cannnot make dirty things with them! )
323 void setParagraph(bool line_top, bool line_bottom,
324 bool pagebreak_top, bool pagebreak_bottom,
325 VSpace const & space_top,
326 VSpace const & space_bottom,
327 Spacing const & spacing,
329 string const & labelwidthstring,
332 /* these things are for search and replace */
335 * Sets the selection from the current cursor position to length
336 * characters to the right. No safety checks.
338 void setSelectionRange(lyx::pos_type length);
340 /** simple replacing. The font of the first selected character
343 void replaceSelectionWithString(string const & str);
345 /// needed to insert the selection
346 void insertStringAsLines(string const & str);
347 /// needed to insert the selection
348 void insertStringAsParagraphs(string const & str);
350 /// Find next inset of some specified type.
351 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
352 string const & contents = string());
354 void gotoInset(std::vector<InsetOld::Code> const & codes,
357 void gotoInset(InsetOld::Code code, bool same_content);
360 int workWidth() const;
363 void computeBidiTables(ParagraphList::iterator pit,
364 Buffer const *, RowList::iterator row) const;
365 /// Maps positions in the visual string to positions in logical string.
366 lyx::pos_type log2vis(lyx::pos_type pos) const;
367 /// Maps positions in the logical string to positions in visual string.
368 lyx::pos_type vis2log(lyx::pos_type pos) const;
370 lyx::pos_type bidi_level(lyx::pos_type pos) const;
372 bool bidi_InRange(lyx::pos_type pos) const;
375 float getCursorX(ParagraphList::iterator pit,
376 RowList::iterator rit, lyx::pos_type pos,
377 lyx::pos_type last, bool boundary) const;
378 /// used in setlayout
379 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
381 /// Calculate and set the height of the row
382 void setHeightOfRow(ParagraphList::iterator, RowList::iterator rit);
384 // fix the cursor `cur' after a characters has been deleted at `where'
385 // position. Called by deleteEmptyParagraphMechanism
386 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
388 /// delete double space (false) or empty paragraphs (true) around old_cursor
389 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
392 /** Updates all counters starting BEHIND the row. Changed paragraphs
393 * with a dynamic left margin will be rebroken. */
394 void updateCounters();
396 * Returns an inset if inset was hit, or 0 if not.
397 * If hit, the coordinates are changed relative to the inset.
399 InsetOld * checkInsetHit(int & x, int & y);
402 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
404 int singleWidth(ParagraphList::iterator pit,
405 lyx::pos_type pos, char c) const;
406 /// rebuild row cache
407 void rebuildRows(ParagraphList::iterator pit);
409 /// return the color of the canvas
410 LColor::color backgroundColor() const;
413 mutable bool bidi_same_direction;
415 unsigned char transformChar(unsigned char c, Paragraph const & par,
416 lyx::pos_type pos) const;
419 * Returns the left beginning of the text.
420 * This information cannot be taken from the layout object, because
421 * in LaTeX the beginning of the text fits in some cases
422 * (for example sections) exactly the label-width.
424 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
426 int rightMargin(ParagraphList::iterator pit, Buffer const &, Row const & row) const;
428 /** this calculates the specified parameters. needed when setting
429 * the cursor and when creating a visible row */
431 ParagraphList::iterator pit,
432 RowList::iterator row, double & x,
433 double & fill_separator,
435 double & fill_label_hfill,
436 bool bidi = true) const;
440 void setCounter(Buffer const *, ParagraphList::iterator pit);
442 void deleteWordForward();
444 void deleteWordBackward();
446 void deleteLineForward();
449 * some low level functions
453 /// return the pos value *before* which a row should break.
454 /// for example, the pos at which IsNewLine(pos) == true
455 lyx::pos_type rowBreakPoint(ParagraphList::iterator pit,
456 Row const & row) const;
458 /// returns the minimum space a row needs on the screen in pixel
459 int fill(ParagraphList::iterator pit,
460 RowList::iterator 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, Row const & row) const;
472 mutable std::vector<lyx::pos_type> log2vis_list;
474 mutable std::vector<lyx::pos_type> vis2log_list;
476 mutable std::vector<lyx::pos_type> bidi_levels;
478 mutable lyx::pos_type bidi_start;
480 mutable lyx::pos_type bidi_end;
483 const bool in_inset_;
485 ParagraphList & paragraphs_;
491 // special owner functions
493 ParagraphList & ownerParagraphs() const;
495 /// return true if this is owned by an inset.
496 bool isInInset() const;
498 /// return first row of text
499 RowList::iterator firstRow() const;
500 /// return last row of text
501 RowList::iterator lastRow() const;
502 /// return row "behind" last row of text
503 RowList::iterator endRow() const;
504 /// return next row crossing paragraph boundaries
505 void nextRow(ParagraphList::iterator & pit,
506 RowList::iterator & rit) const;
507 /// return previous row crossing paragraph boundaries
508 void previousRow(ParagraphList::iterator & pit,
509 RowList::iterator & rit) const;
515 /** Cursor related data.
516 Later this variable has to be removed. There should be now internal
519 ///TextCursor cursor_;
522 /// return the default height of a row in pixels, considering font zoom
523 extern int defaultRowHeight();