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 dispatch_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.
170 RowList::iterator getRow(Paragraph & par, lyx::pos_type pos) const;
172 /// returns an iterator pointing to a cursor row
173 RowList::iterator getRow(LyXCursor const & cursor) const;
175 RowList::iterator cursorRow() const;
176 /// returns an iterator pointing to a cursor paragraph
177 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
179 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
181 int parOffset(ParagraphList::iterator pit) const;
183 ParagraphList::iterator cursorPar() 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 Row const & row, 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
227 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
228 /// returns true if par was empty and was removed
229 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
230 bool setfont = true, bool boundary = false);
232 void setCursor(LyXCursor &, lyx::paroffset_type par,
233 lyx::pos_type pos, bool boundary = false);
235 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
236 bool setfont = true, bool boundary = false);
238 void setCurrentFont();
241 bool isBoundary(Buffer const &, Paragraph const & par,
242 lyx::pos_type pos) const;
244 bool isBoundary(Buffer const &, Paragraph const & par,
245 lyx::pos_type pos, LyXFont const & font) const;
248 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
250 void recUndo(lyx::paroffset_type first) const;
252 void setCursorFromCoordinates(int x, int y);
254 void setCursorFromCoordinates(LyXCursor &, int x, int y);
256 void cursorUp(bool selecting = false);
258 void cursorDown(bool selecting = false);
260 void cursorLeft(bool internal = true);
262 void cursorRight(bool internal = true);
264 void cursorLeftOneWord();
266 void cursorRightOneWord();
268 void cursorUpParagraph();
270 void cursorDownParagraph();
276 void cursorPrevious();
288 bool selectWordWhenUnderCursor(lyx::word_location);
294 text_capitalization = 1,
298 /// Change the case of the word at cursor position.
299 void changeCase(TextCase action);
304 void cutSelection(bool doclear = true, bool realcut = true);
306 void copySelection();
308 void pasteSelection(size_t sel_index = 0);
310 /** the DTP switches for paragraphs. LyX will store the top settings
311 always in the first physical paragraph, the bottom settings in the
312 last. When a paragraph is broken, the top settings rest, the bottom
313 settings are given to the new one. So I can make shure, they do not
314 duplicate themself (and you cannnot make dirty things with them! )
316 void setParagraph(bool line_top, bool line_bottom,
317 bool pagebreak_top, bool pagebreak_bottom,
318 VSpace const & space_top,
319 VSpace const & space_bottom,
320 Spacing const & spacing,
322 std::string const & labelwidthstring,
325 /* these things are for search and replace */
328 * Sets the selection from the current cursor position to length
329 * characters to the right. No safety checks.
331 void setSelectionRange(lyx::pos_type length);
333 /** simple replacing. The font of the first selected character
336 void replaceSelectionWithString(std::string const & str);
338 /// needed to insert the selection
339 void insertStringAsLines(std::string const & str);
340 /// needed to insert the selection
341 void insertStringAsParagraphs(std::string const & str);
343 /// Find next inset of some specified type.
344 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
345 std::string const & contents = std::string());
347 void gotoInset(std::vector<InsetOld::Code> const & codes,
350 void gotoInset(InsetOld::Code code, bool same_content);
353 int workWidth() const;
356 void computeBidiTables(Paragraph const & par,
357 Buffer const &, Row & row) const;
358 /// Maps positions in the visual string to positions in logical string.
359 lyx::pos_type log2vis(lyx::pos_type pos) const;
360 /// Maps positions in the logical string to positions in visual string.
361 lyx::pos_type vis2log(lyx::pos_type pos) const;
363 lyx::pos_type bidi_level(lyx::pos_type pos) const;
365 bool bidi_InRange(lyx::pos_type pos) const;
368 float getCursorX(ParagraphList::iterator pit,
369 Row const & row, lyx::pos_type pos,
370 lyx::pos_type last, bool boundary) const;
371 /// used in setlayout
372 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
374 /// Calculate and set the height of the row
375 void setHeightOfRow(ParagraphList::iterator, Row & row);
377 // fix the cursor `cur' after a characters has been deleted at `where'
378 // position. Called by deleteEmptyParagraphMechanism
379 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
381 /// delete double space (false) or empty paragraphs (true) around old_cursor
382 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
385 /** Updates all counters starting BEHIND the row. Changed paragraphs
386 * with a dynamic left margin will be rebroken. */
387 void updateCounters();
389 * Returns an inset if inset was hit, or 0 if not.
390 * If hit, the coordinates are changed relative to the inset.
392 InsetOld * checkInsetHit(int & x, int & y);
395 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
397 int singleWidth(ParagraphList::iterator pit,
398 lyx::pos_type pos, char c, LyXFont const & Font) const;
400 /// return the color of the canvas
401 LColor_color backgroundColor() const;
404 mutable bool bidi_same_direction;
406 unsigned char transformChar(unsigned char c, Paragraph const & par,
407 lyx::pos_type pos) const;
410 * Returns the left beginning of the text.
411 * This information cannot be taken from the layout object, because
412 * in LaTeX the beginning of the text fits in some cases
413 * (for example sections) exactly the label-width.
415 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
417 int rightMargin(Paragraph const & par, Buffer const &, Row const & row) const;
419 /** this calculates the specified parameters. needed when setting
420 * the cursor and when creating a visible row */
421 void prepareToPrint(ParagraphList::iterator pit,
422 RowList::iterator row) const;
426 void setCounter(Buffer const &, ParagraphList::iterator pit);
428 void deleteWordForward();
430 void deleteWordBackward();
432 void deleteLineForward();
434 /// sets row.end to the pos value *after* which a row should break.
435 /// for example, the pos after which isNewLine(pos) == true
436 lyx::pos_type rowBreakPoint(ParagraphList::iterator pit,
437 Row const & row) const;
439 /// returns the minimum space a row needs on the screen in pixel
440 int fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
443 * returns the minimum space a manual label needs on the
446 int labelFill(ParagraphList::iterator pit, Row const & row) const;
449 int labelEnd(ParagraphList::iterator pit, Row const & row) const;
452 mutable std::vector<lyx::pos_type> log2vis_list;
454 mutable std::vector<lyx::pos_type> vis2log_list;
456 mutable std::vector<lyx::pos_type> bidi_levels;
458 mutable lyx::pos_type bidi_start;
460 mutable lyx::pos_type bidi_end;
468 ParagraphList * paragraphs_;
470 // special owner functions
472 ParagraphList & ownerParagraphs() const;
474 /// return true if this is owned by an inset.
475 bool isInInset() const;
477 /// return first row of text
478 RowList::iterator firstRow() const;
479 /// return last row of text
480 RowList::iterator lastRow() const;
481 /// return row "behind" last row of text
482 RowList::iterator endRow() const;
483 /// return next row crossing paragraph boundaries
484 void nextRow(ParagraphList::iterator & pit,
485 RowList::iterator & rit) const;
486 /// return previous row crossing paragraph boundaries
487 void previousRow(ParagraphList::iterator & pit,
488 RowList::iterator & rit) const;
491 std::string selectionAsString(Buffer const & buffer, bool label) const;
493 /** Cursor related data.
494 Later this variable has to be removed. There should be now internal
497 ///TextCursor cursor_;
498 /// prohibit this as long as there are back pointers...
499 LyXText(LyXText const &);
502 /// return the default height of a row in pixels, considering font zoom
503 extern int defaultRowHeight();