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"
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 {
55 LyXText(BufferView *, InsetText *, bool ininset, ParagraphList & plist);
58 LyXText & operator=(LyXText const &);
60 void init(BufferView *);
63 /// update all cached row positions
64 void updateRowPositions();
66 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
68 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
70 LyXFont getLabelFont(ParagraphList::iterator pit) const;
72 void setCharFont(ParagraphList::iterator pit,
73 lyx::pos_type pos, LyXFont const & font);
74 void setCharFont(ParagraphList::iterator pit,
76 LyXFont const & font, bool toggleall);
78 /// what you expect when pressing <enter> at cursor position
79 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
81 /** set layout over selection and make a total rebreak of
84 ParagraphList::iterator
85 setLayout(LyXCursor & actual_cursor,
86 LyXCursor & selection_start,
87 LyXCursor & selection_end,
88 std::string const & layout);
90 void setLayout(std::string const & layout);
93 * Increase or decrease the nesting depth of the selected paragraph(s)
94 * if test_only, don't change any depths. Returns whether something
95 * (would have) changed
97 bool changeDepth(bv_funcs::DEPTH_CHANGE type, bool test_only);
99 /// get the depth at current cursor position
100 int getDepth() const;
102 /** set font over selection and make a total rebreak of those
104 toggleall defaults to false.
106 void setFont(LyXFont const &, bool toggleall = false);
108 /// rebreaks all paragaphs between the given pars.
109 void redoParagraphs(ParagraphList::iterator begin,
110 ParagraphList::iterator end);
111 /// rebreaks the given par
112 void redoParagraph(ParagraphList::iterator pit);
114 /// rebreaks the cursor par
115 void redoParagraph();
118 void toggleFree(LyXFont const &, bool toggleall = false);
121 std::string getStringToIndex();
123 /** insert a character, moves all the following breaks in the
124 same Paragraph one to the right and make a little rebreak
126 void insertChar(char c);
128 void insertInset(InsetOld * inset);
130 /// a full rebreak of the whole text
132 /// compute text metrics
133 void metrics(MetricsInfo & mi, Dimension & dim);
136 DispatchResult dispatch(FuncRequest const & cmd);
140 BufferView * bv() const;
142 friend class LyXScreen;
144 /// returns an iterator pointing to a cursor paragraph
145 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
147 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
149 int parOffset(ParagraphList::iterator pit) const;
151 ParagraphList::iterator cursorPar() const;
153 RowList::iterator cursorRow() const;
155 /** returns a pointer to the row near the specified y-coordinate
156 (relative to the whole text). y is set to the real beginning
159 RowList::iterator getRowNearY(int y,
160 ParagraphList::iterator & pit) const;
162 /** returns the column near the specified x-coordinate of the row
163 x is set to the real beginning of this column
165 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
166 Row const & row, int & x, bool & boundary) const;
168 /// need the selection cursor:
171 void clearSelection();
173 /// select the word we need depending on word_location
174 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
175 /// just selects the word the cursor is in
176 void selectWord(lyx::word_location loc);
177 /// returns the inset at cursor (if it exists), 0 otherwise
178 InsetOld * getInset() const;
180 /// accept selected change
183 /// reject selected change
186 /// re-computes the cached coordinates in the cursor
189 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
190 /// returns true if par was empty and was removed
191 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
192 bool setfont = true, bool boundary = false);
194 void setCursor(LyXCursor &, lyx::paroffset_type par,
195 lyx::pos_type pos, bool boundary = false);
197 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
198 bool setfont = true, bool boundary = false);
200 void setCurrentFont();
203 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
205 void recUndo(lyx::paroffset_type first) const;
207 void setCursorFromCoordinates(int x, int y);
209 void setCursorFromCoordinates(LyXCursor &, int x, int y);
211 void cursorUp(bool selecting = false);
213 void cursorDown(bool selecting = false);
215 bool cursorLeft(bool internal = true);
217 bool cursorRight(bool internal = true);
219 void cursorLeftOneWord();
221 void cursorRightOneWord();
223 void cursorUpParagraph();
225 void cursorDownParagraph();
231 void cursorPrevious();
243 bool selectWordWhenUnderCursor(lyx::word_location);
249 text_capitalization = 1,
253 /// Change the case of the word at cursor position.
254 void changeCase(TextCase action);
259 void cutSelection(bool doclear = true, bool realcut = true);
261 void copySelection();
263 void pasteSelection(size_t sel_index = 0);
265 /** the DTP switches for paragraphs. LyX will store the top settings
266 always in the first physical paragraph, the bottom settings in the
267 last. When a paragraph is broken, the top settings rest, the bottom
268 settings are given to the new one.
271 VSpace const & space_top,
272 VSpace const & space_bottom,
273 Spacing const & spacing,
275 std::string const & labelwidthstring,
278 /* these things are for search and replace */
281 * Sets the selection from the current cursor position to length
282 * characters to the right. No safety checks.
284 void setSelectionRange(lyx::pos_type length);
286 /** simple replacing. The font of the first selected character
289 void replaceSelectionWithString(std::string const & str);
291 /// needed to insert the selection
292 void insertStringAsLines(std::string const & str);
293 /// needed to insert the selection
294 void insertStringAsParagraphs(std::string const & str);
296 /// Find next inset of some specified type.
297 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
298 std::string const & contents = std::string());
300 void gotoInset(std::vector<InsetOld::Code> const & codes,
303 void gotoInset(InsetOld::Code code, bool same_content);
306 int workWidth() const;
308 /** Updates all counters starting BEHIND the row. Changed paragraphs
309 * with a dynamic left margin will be rebroken. */
310 void updateCounters();
312 * Returns an inset if inset was hit, or 0 if not.
314 InsetOld * checkInsetHit(int x, int y);
317 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
319 int singleWidth(ParagraphList::iterator pit,
320 lyx::pos_type pos, char c, LyXFont const & Font) const;
322 /// return the color of the canvas
323 LColor_color backgroundColor() const;
326 * Returns the left beginning of the text.
327 * This information cannot be taken from the layout object, because
328 * in LaTeX the beginning of the text fits in some cases
329 * (for example sections) exactly the label-width.
331 int leftMargin(ParagraphList::iterator pit, Row const & row) const;
333 int rightMargin(Paragraph const & par, Buffer const &) const;
335 /** this calculates the specified parameters. needed when setting
336 * the cursor and when creating a visible row */
337 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
340 // special owner functions
342 ParagraphList & ownerParagraphs() const;
344 /// return true if this is owned by an inset.
345 bool isInInset() const;
348 ParagraphList::iterator firstPar() const;
350 ParagraphList::iterator lastPar() const;
352 ParagraphList::iterator endPar() const;
354 /// return first row of text
355 RowList::iterator firstRow() const;
356 /// return last row of text
357 RowList::iterator lastRow() const;
358 /// return row "behind" last row of text
359 RowList::iterator endRow() const;
360 /// return next row crossing paragraph boundaries
361 void nextRow(ParagraphList::iterator & pit,
362 RowList::iterator & rit) const;
363 /// return previous row crossing paragraph boundaries
364 void previousRow(ParagraphList::iterator & pit,
365 RowList::iterator & rit) const;
367 /// is this row the last in the text?
368 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
369 /// is this row the first in the text?
370 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
373 std::string selectionAsString(Buffer const & buffer, bool label) const;
375 double spacing(Paragraph const &) const;
377 void cursorLeftOneWord(LyXCursor &);
379 void cursorRightOneWord(LyXCursor &);
382 DispatchResult moveRight();
384 DispatchResult moveLeft();
386 DispatchResult moveRightIntern(bool front,
387 bool activate_inset, bool selecting);
389 DispatchResult moveLeftIntern(bool front,
390 bool activate_inset, bool selecting);
392 DispatchResult moveUp();
394 DispatchResult moveDown();
396 bool checkAndActivateInset(bool front);
405 /// the current font settings
406 LyXFont current_font;
408 LyXFont real_current_font;
409 /// our buffer's default layout font
410 LyXFont defaultfont_;
412 InsetText * inset_owner;
414 /// only the top-level LyXText has this non-zero
415 BufferView * bv_owner;
422 ParagraphList * paragraphs_;
424 /// absolute document pixel coordinates of this LyXText
431 /// rebreaks the given par
432 void redoParagraphInternal(ParagraphList::iterator pit);
435 float getCursorX(ParagraphList::iterator pit,
436 Row const & row, lyx::pos_type pos, bool boundary) const;
437 /// used in setlayout
438 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
440 /// Calculate and set the height of the row
441 void setHeightOfRow(ParagraphList::iterator, Row & row);
443 // fix the cursor `cur' after a characters has been deleted at `where'
444 // position. Called by deleteEmptyParagraphMechanism
445 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
447 /// delete double space (false) or empty paragraphs (true) around old_cursor
448 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
451 void setCounter(Buffer const &, ParagraphList::iterator pit);
453 void deleteWordForward();
455 void deleteWordBackward();
457 void deleteLineForward();
459 /// sets row.end to the pos value *after* which a row should break.
460 /// for example, the pos after which isNewLine(pos) == true
461 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
463 /// sets row.witdh to the minimum space a row needs on the screen in pixel
464 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
467 * returns the minimum space a manual label needs on the
470 int labelFill(ParagraphList::iterator pit, Row const & row) const;
473 int labelEnd(ParagraphList::iterator pit, Row const & row) const;
477 /// set 'number' font property
479 /// is the cursor paragraph right-to-left?
485 /// prohibit this as long as there are back pointers...
486 LyXText(LyXText const &);
488 // cache for cursorPar()
489 mutable ParagraphList::iterator cache_par_;
490 mutable int cache_pos_;
493 /// return the default height of a row in pixels, considering font zoom
494 extern int defaultRowHeight();