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"
20 #include "ParagraphList_fwd.h"
21 #include "RowList_fwd.h"
22 #include "textcursor.h"
24 #include "insets/inset.h"
43 This class used to hold the mapping between buffer paragraphs and
44 screen rows. Nowadays, the Paragraphs take care of their rows
45 themselves and this contains just most of the code for manipulating
46 them and interaction with the Cursor.
49 // The inheritance from TextCursor should go. It's just there to ease
51 class LyXText : public TextCursor {
54 LyXText(BufferView *, InsetText *, bool ininset,
55 ParagraphList & paragraphs);
57 void init(BufferView *);
62 /// the current font settings
65 LyXFont real_current_font;
66 /// our buffer's default layout font
69 /// offset of dran area to document start.
72 /// update all cached row positions
73 void updateRowPositions();
75 InsetText * inset_owner;
77 UpdatableInset * the_locking_inset;
80 int getRealCursorX() const;
82 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
84 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
86 LyXFont getLabelFont(ParagraphList::iterator pit) const;
88 void setCharFont(ParagraphList::iterator pit,
89 lyx::pos_type pos, LyXFont const & font);
90 void setCharFont(ParagraphList::iterator pit,
92 LyXFont const & font, bool toggleall);
94 /// what you expect when pressing <enter> at cursor position
95 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
97 /** set layout over selection and make a total rebreak of
100 ParagraphList::iterator
101 setLayout(LyXCursor & actual_cursor,
102 LyXCursor & selection_start,
103 LyXCursor & selection_end,
104 std::string const & layout);
106 void setLayout(std::string const & layout);
109 * Increase or decrease the nesting depth of the selected paragraph(s)
110 * if test_only, don't change any depths. Returns whether something
111 * (would have) changed
113 bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
115 /// get the depth at current cursor position
116 int getDepth() const;
118 /** set font over selection and make a total rebreak of those
120 toggleall defaults to false.
122 void setFont(LyXFont const &, bool toggleall = false);
124 /// rebreaks all paragaphs between the given pars.
125 int redoParagraphs(ParagraphList::iterator begin,
126 ParagraphList::iterator end);
127 /// rebreaks the given par
128 void redoParagraph(ParagraphList::iterator pit);
130 /// rebreaks the cursor par
131 void redoParagraph();
133 /// rebreaks the given par, return max row width
134 int redoParagraphInternal(ParagraphList::iterator pit);
138 void toggleFree(LyXFont const &, bool toggleall = false);
141 std::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 /// need the selection cursor:
201 void clearSelection();
203 /// select the word we need depending on word_location
204 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
205 /// just selects the word the cursor is in
206 void selectWord(lyx::word_location loc);
207 /// returns the inset at cursor (if it exists), 0 otherwise
208 InsetOld * getInset() const;
210 /// accept selected change
213 /// reject selected change
216 /** 'selects" the next word, where the cursor is not in
217 and returns this word as string. THe cursor will be moved
218 to the beginning of this word.
219 With SelectSelectedWord can this be highlighted really
221 WordLangTuple const selectNextWordToSpellcheck(float & value);
223 void selectSelectedWord();
224 /// re-computes the cached coordinates in the cursor
226 /// returns true if par was empty and was removed
227 bool setCursor(ParagraphList::iterator pit,
230 bool boundary = false);
232 void setCursor(LyXCursor &, ParagraphList::iterator pit,
234 bool boundary = false);
236 void setCursorIntern(ParagraphList::iterator pit,
239 bool boundary = false);
241 void setCurrentFont();
244 bool isBoundary(Buffer const &, Paragraph const & par,
245 lyx::pos_type pos) const;
247 bool isBoundary(Buffer const &, Paragraph const & par,
249 LyXFont const & font) const;
252 void setCursorFromCoordinates(int x, int y);
254 void setCursorFromCoordinates(LyXCursor &,
257 void cursorUp(bool selecting = false);
259 void cursorDown(bool selecting = false);
261 void cursorLeft(bool internal = true);
263 void cursorRight(bool internal = true);
265 void cursorLeftOneWord();
267 void cursorRightOneWord();
269 void cursorUpParagraph();
271 void cursorDownParagraph();
277 void cursorPrevious();
289 bool selectWordWhenUnderCursor(lyx::word_location);
295 text_capitalization = 1,
299 /// Change the case of the word at cursor position.
300 void changeCase(TextCase action);
305 void cutSelection(bool doclear = true, bool realcut = true);
307 void copySelection();
309 void pasteSelection(size_t sel_index = 0);
311 /** the DTP switches for paragraphs. LyX will store the top settings
312 always in the first physical paragraph, the bottom settings in the
313 last. When a paragraph is broken, the top settings rest, the bottom
314 settings are given to the new one. So I can make shure, they do not
315 duplicate themself (and you cannnot make dirty things with them! )
317 void setParagraph(bool line_top, bool line_bottom,
318 bool pagebreak_top, bool pagebreak_bottom,
319 VSpace const & space_top,
320 VSpace const & space_bottom,
321 Spacing const & spacing,
323 std::string const & labelwidthstring,
326 /* these things are for search and replace */
329 * Sets the selection from the current cursor position to length
330 * characters to the right. No safety checks.
332 void setSelectionRange(lyx::pos_type length);
334 /** simple replacing. The font of the first selected character
337 void replaceSelectionWithString(std::string const & str);
339 /// needed to insert the selection
340 void insertStringAsLines(std::string const & str);
341 /// needed to insert the selection
342 void insertStringAsParagraphs(std::string const & str);
344 /// Find next inset of some specified type.
345 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
346 std::string const & contents = std::string());
348 void gotoInset(std::vector<InsetOld::Code> const & codes,
351 void gotoInset(InsetOld::Code code, bool same_content);
354 int workWidth() const;
357 void computeBidiTables(ParagraphList::iterator pit,
358 Buffer const &, RowList::iterator row) const;
359 /// Maps positions in the visual string to positions in logical string.
360 lyx::pos_type log2vis(lyx::pos_type pos) const;
361 /// Maps positions in the logical string to positions in visual string.
362 lyx::pos_type vis2log(lyx::pos_type pos) const;
364 lyx::pos_type bidi_level(lyx::pos_type pos) const;
366 bool bidi_InRange(lyx::pos_type pos) const;
369 float getCursorX(ParagraphList::iterator pit,
370 RowList::iterator rit, lyx::pos_type pos,
371 lyx::pos_type last, bool boundary) const;
372 /// used in setlayout
373 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
375 /// Calculate and set the height of the row
376 void setHeightOfRow(ParagraphList::iterator, RowList::iterator rit);
378 // fix the cursor `cur' after a characters has been deleted at `where'
379 // position. Called by deleteEmptyParagraphMechanism
380 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
382 /// delete double space (false) or empty paragraphs (true) around old_cursor
383 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
386 /** Updates all counters starting BEHIND the row. Changed paragraphs
387 * with a dynamic left margin will be rebroken. */
388 void updateCounters();
390 * Returns an inset if inset was hit, or 0 if not.
391 * If hit, the coordinates are changed relative to the inset.
393 InsetOld * checkInsetHit(int & x, int & y);
396 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
398 int singleWidth(ParagraphList::iterator pit,
399 lyx::pos_type pos, char c, LyXFont const & Font) const;
401 /// return the color of the canvas
402 LColor_color backgroundColor() const;
405 mutable bool bidi_same_direction;
407 unsigned char transformChar(unsigned char c, Paragraph const & par,
408 lyx::pos_type pos) const;
411 * Returns the left beginning of the text.
412 * This information cannot be taken from the layout object, because
413 * in LaTeX the beginning of the text fits in some cases
414 * (for example sections) exactly the label-width.
416 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
418 int rightMargin(ParagraphList::iterator pit, Buffer const &, Row const & row) const;
420 /** this calculates the specified parameters. needed when setting
421 * the cursor and when creating a visible row */
422 void prepareToPrint(ParagraphList::iterator pit,
423 RowList::iterator row) const;
427 void setCounter(Buffer const &, ParagraphList::iterator pit);
429 void deleteWordForward();
431 void deleteWordBackward();
433 void deleteLineForward();
436 * some low level functions
440 /// sets row.end to the pos value *after* which a row should break.
441 /// for example, the pos after which isNewLine(pos) == true
442 lyx::pos_type rowBreakPoint(ParagraphList::iterator pit,
443 Row const & row) const;
445 /// returns the minimum space a row needs on the screen in pixel
446 int fill(ParagraphList::iterator pit,
447 RowList::iterator row, int workwidth) const;
450 * returns the minimum space a manual label needs on the
453 int labelFill(ParagraphList::iterator pit, Row const & row) const;
456 int labelEnd(ParagraphList::iterator pit, Row const & row) const;
459 mutable std::vector<lyx::pos_type> log2vis_list;
461 mutable std::vector<lyx::pos_type> vis2log_list;
463 mutable std::vector<lyx::pos_type> bidi_levels;
465 mutable lyx::pos_type bidi_start;
467 mutable lyx::pos_type bidi_end;
470 const bool in_inset_;
472 ParagraphList & paragraphs_;
478 // special owner functions
480 ParagraphList & ownerParagraphs() const;
482 /// return true if this is owned by an inset.
483 bool isInInset() const;
485 /// return first row of text
486 RowList::iterator firstRow() const;
487 /// return last row of text
488 RowList::iterator lastRow() const;
489 /// return row "behind" last row of text
490 RowList::iterator endRow() const;
491 /// return next row crossing paragraph boundaries
492 void nextRow(ParagraphList::iterator & pit,
493 RowList::iterator & rit) const;
494 /// return previous row crossing paragraph boundaries
495 void previousRow(ParagraphList::iterator & pit,
496 RowList::iterator & rit) const;
502 /** Cursor related data.
503 Later this variable has to be removed. There should be now internal
506 ///TextCursor cursor_;
509 /// return the default height of a row in pixels, considering font zoom
510 extern int defaultRowHeight();