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 "lyxtextclass.h"
22 #include "ParagraphList_fwd.h"
23 #include "RowList_fwd.h"
24 #include "textcursor.h"
26 #include "insets/inset.h"
44 This class used to hold the mapping between buffer paragraphs and
45 screen rows. Nowadays, the Paragraphs take care of their rows
46 themselves and this contains just most of the code for manipulating
47 them and interaction with the Cursor.
50 // The inheritance from TextCursor should go. It's just there to ease
52 class LyXText : public TextCursor {
56 LyXText(BufferView *, InsetText *, bool ininset, ParagraphList & plist);
58 void init(BufferView *);
61 /// update y coordinate cache of all paragraphs
62 void updateParPositions();
64 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
66 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
68 LyXFont getLabelFont(ParagraphList::iterator pit) const;
70 void setCharFont(ParagraphList::iterator pit,
71 lyx::pos_type pos, LyXFont const & font);
72 void setCharFont(ParagraphList::iterator pit,
74 LyXFont const & font, bool toggleall);
76 /// what you expect when pressing <enter> at cursor position
77 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
79 /** set layout over selection and make a total rebreak of
82 ParagraphList::iterator
83 setLayout(LyXCursor & actual_cursor,
84 LyXCursor & selection_start,
85 LyXCursor & selection_end,
86 std::string const & layout);
88 void setLayout(std::string const & layout);
90 /// Increase or decrease the nesting depth of the selected paragraph(s)
91 void changeDepth(bv_funcs::DEPTH_CHANGE type);
93 /// Returns whether something would be changed by changeDepth
94 bool changeDepthAllowed(bv_funcs::DEPTH_CHANGE type);
96 /// get the depth at current cursor position
99 /** set font over selection and make a total rebreak of those
101 toggleall defaults to false.
103 void setFont(LyXFont const &, bool toggleall = false);
105 /// rebreaks all paragaphs between the given pars.
106 void redoParagraphs(ParagraphList::iterator begin,
107 ParagraphList::iterator end);
108 /// rebreaks the given par
109 void redoParagraph(ParagraphList::iterator pit);
111 /// rebreaks the cursor par
112 void redoParagraph();
115 void toggleFree(LyXFont const &, bool toggleall = false);
118 std::string getStringToIndex();
120 /** insert a character, moves all the following breaks in the
121 same Paragraph one to the right and make a little rebreak
123 void insertChar(char c);
125 void insertInset(InsetOld * inset);
127 /// a full rebreak of the whole text
129 /// compute text metrics
130 void metrics(MetricsInfo & mi, Dimension & dim);
131 /// draw text (only used for insets)
132 void draw(PainterInfo & pi, int x, int y) const;
135 DispatchResult dispatch(FuncRequest const & cmd);
139 BufferView * bv() const;
141 friend class LyXScreen;
143 /// returns an iterator pointing to a cursor paragraph
144 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
146 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
148 int parOffset(ParagraphList::iterator pit) const;
150 ParagraphList::iterator cursorPar() const;
152 RowList::iterator cursorRow() const;
154 /** returns an iterator pointing to the row near the specified
155 * y-coordinate (relative to the whole text). y is set to the
156 * real beginning of this row
158 RowList::iterator getRowNearY(int y,
159 ParagraphList::iterator & pit) const;
161 /** returns the column near the specified x-coordinate of the row
162 x is set to the real beginning of this column
164 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
165 Row const & row, int & x, bool & boundary) const;
167 /// need the selection cursor:
170 void clearSelection();
172 /// select the word we need depending on word_location
173 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
174 /// just selects the word the cursor is in
175 void selectWord(lyx::word_location loc);
176 /// returns the inset at cursor (if it exists), 0 otherwise
177 InsetOld * getInset() const;
179 /// accept selected change
182 /// reject selected change
185 /// re-computes the cached coordinates in the cursor
188 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
189 /// returns true if par was empty and was removed
190 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
191 bool setfont = true, bool boundary = false);
193 void setCursor(LyXCursor &, lyx::paroffset_type par,
194 lyx::pos_type pos, bool boundary = false);
196 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
197 bool setfont = true, bool boundary = false);
199 void setCurrentFont();
202 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
204 void recUndo(lyx::paroffset_type first) const;
206 void setCursorFromCoordinates(int x, int y);
208 void setCursorFromCoordinates(LyXCursor &, int x, int y);
210 void cursorUp(bool selecting = false);
212 void cursorDown(bool selecting = false);
214 bool cursorLeft(bool internal = true);
216 bool cursorRight(bool internal = true);
218 void cursorLeftOneWord();
220 void cursorRightOneWord();
222 void cursorUpParagraph();
224 void cursorDownParagraph();
230 void cursorPrevious();
242 bool selectWordWhenUnderCursor(lyx::word_location);
248 text_capitalization = 1,
252 /// Change the case of the word at cursor position.
253 void changeCase(TextCase action);
258 void cutSelection(bool doclear = true, bool realcut = true);
260 void copySelection();
262 void pasteSelection(size_t sel_index = 0);
264 /** the DTP switches for paragraphs. LyX will store the top settings
265 always in the first physical paragraph, the bottom settings in the
266 last. When a paragraph is broken, the top settings rest, the bottom
267 settings are given to the new one.
270 VSpace const & space_top,
271 VSpace const & space_bottom,
272 Spacing const & spacing,
274 std::string const & labelwidthstring,
277 /* these things are for search and replace */
280 * Sets the selection from the current cursor position to length
281 * characters to the right. No safety checks.
283 void setSelectionRange(lyx::pos_type length);
285 /** simple replacing. The font of the first selected character
288 void replaceSelectionWithString(std::string const & str);
290 /// needed to insert the selection
291 void insertStringAsLines(std::string const & str);
292 /// needed to insert the selection
293 void insertStringAsParagraphs(std::string const & str);
295 /// Find next inset of some specified type.
296 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
297 std::string const & contents = std::string());
299 void gotoInset(std::vector<InsetOld::Code> const & codes,
302 void gotoInset(InsetOld::Code code, bool same_content);
304 /// current max text width
305 int textWidth() const;
307 /// updates all counters
308 void updateCounters();
309 /// Returns an inset if inset was hit, or 0 if not.
310 InsetOld * checkInsetHit(int x, int y);
313 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
315 int singleWidth(ParagraphList::iterator pit,
316 lyx::pos_type pos, char c, LyXFont const & Font) const;
318 /// return the color of the canvas
319 LColor_color backgroundColor() const;
322 * Returns the left beginning of the text.
323 * This information cannot be taken from the layout object, because
324 * in LaTeX the beginning of the text fits in some cases
325 * (for example sections) exactly the label-width.
327 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
328 int leftMargin(ParagraphList::iterator pit) const;
330 int rightMargin(Paragraph const & par) const;
332 /** this calculates the specified parameters. needed when setting
333 * the cursor and when creating a visible row */
334 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
337 // special owner functions
339 ParagraphList & ownerParagraphs() const;
341 /// return true if this is owned by an inset.
342 bool isInInset() const;
345 ParagraphList::iterator firstPar() const;
347 ParagraphList::iterator lastPar() const;
349 ParagraphList::iterator endPar() const;
351 /// return first row of text
352 RowList::iterator firstRow() const;
353 /// return last row of text
354 RowList::iterator lastRow() const;
355 /// return row "behind" last row of text
356 RowList::iterator endRow() const;
357 /// return next row crossing paragraph boundaries
358 void nextRow(ParagraphList::iterator & pit,
359 RowList::iterator & rit) const;
360 /// return previous row crossing paragraph boundaries
361 void previousRow(ParagraphList::iterator & pit,
362 RowList::iterator & rit) const;
364 /// is this row the last in the text?
365 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
366 /// is this row the first in the text?
367 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
370 std::string selectionAsString(Buffer const & buffer, bool label) const;
372 double spacing(Paragraph const &) const;
374 void cursorLeftOneWord(LyXCursor &);
376 void cursorRightOneWord(LyXCursor &);
379 DispatchResult moveRight();
381 DispatchResult moveLeft();
383 DispatchResult moveRightIntern(bool front,
384 bool activate_inset, bool selecting);
386 DispatchResult moveLeftIntern(bool front,
387 bool activate_inset, bool selecting);
389 DispatchResult moveUp();
391 DispatchResult moveDown();
393 bool checkAndActivateInset(bool front);
403 /// the current font settings
404 LyXFont current_font;
406 LyXFont real_current_font;
407 /// our buffer's default layout font
408 LyXFont defaultfont_;
410 InsetText * inset_owner;
412 /// only the top-level LyXText has this non-zero
413 BufferView * bv_owner;
420 ParagraphList * paragraphs_;
422 /// absolute document pixel coordinates of this LyXText
428 /// rebreaks the given par
429 void redoParagraphInternal(ParagraphList::iterator pit);
432 float getCursorX(ParagraphList::iterator pit,
433 Row const & row, lyx::pos_type pos, bool boundary) const;
434 /// used in setlayout
435 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
437 /// Calculate and set the height of the row
438 void setHeightOfRow(ParagraphList::iterator, Row & row);
440 // fix the cursor `cur' after a characters has been deleted at `where'
441 // position. Called by deleteEmptyParagraphMechanism
442 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
444 /// delete double space (false) or empty paragraphs (true) around old_cursor
445 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
448 void setCounter(Buffer const &, ParagraphList::iterator pit);
450 void deleteWordForward();
452 void deleteWordBackward();
454 void deleteLineForward();
456 /// sets row.end to the pos value *after* which a row should break.
457 /// for example, the pos after which isNewLine(pos) == true
458 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
460 /// sets row.witdh to the minimum space a row needs on the screen in pixel
461 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
464 * returns the minimum space a manual label needs on the
467 int labelFill(ParagraphList::iterator pit, Row const & row) const;
470 int labelEnd(ParagraphList::iterator pit) const;
474 /// set 'number' font property
476 /// is the cursor paragraph right-to-left?
480 /// return the default height of a row in pixels, considering font zoom
481 extern int defaultRowHeight();
484 std::string expandLabel(LyXTextClass const & textclass,
485 LyXLayout_ptr const & layout, bool appendix);