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"
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 *, bool ininset);
57 void init(BufferView *);
60 /// update y coordinate cache of all paragraphs
61 void updateParPositions();
63 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
65 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
67 LyXFont getLabelFont(ParagraphList::iterator pit) const;
69 void setCharFont(ParagraphList::iterator pit,
70 lyx::pos_type pos, LyXFont const & font);
71 void setCharFont(ParagraphList::iterator pit,
73 LyXFont const & font, bool toggleall);
75 /// what you expect when pressing <enter> at cursor position
76 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
78 /** set layout over selection and make a total rebreak of
81 ParagraphList::iterator
82 setLayout(LyXCursor & actual_cursor,
83 LyXCursor & selection_start,
84 LyXCursor & selection_end,
85 std::string const & layout);
87 void setLayout(std::string const & layout);
89 /// Increase or decrease the nesting depth of the selected paragraph(s)
90 void changeDepth(bv_funcs::DEPTH_CHANGE type);
92 /// Returns whether something would be changed by changeDepth
93 bool changeDepthAllowed(bv_funcs::DEPTH_CHANGE type);
95 /// get the depth at current cursor position
98 /** set font over selection and make a total rebreak of those
100 toggleall defaults to false.
102 void setFont(LyXFont const &, bool toggleall = false);
104 /// rebreaks all paragaphs between the given pars.
105 void redoParagraphs(ParagraphList::iterator begin,
106 ParagraphList::iterator end);
107 /// rebreaks the given par
108 void redoParagraph(ParagraphList::iterator pit);
110 /// rebreaks the cursor par
111 void redoParagraph();
114 void toggleFree(LyXFont const &, bool toggleall = false);
117 std::string getStringToIndex();
119 /** insert a character, moves all the following breaks in the
120 same Paragraph one to the right and make a little rebreak
122 void insertChar(char c);
124 void insertInset(InsetOld * inset);
126 /// a full rebreak of the whole text
128 /// compute text metrics
129 void metrics(MetricsInfo & mi, Dimension & dim);
130 /// draw text (only used for insets)
131 void draw(PainterInfo & pi, int x, int y) const;
133 /// try to handle that request
134 DispatchResult dispatch(FuncRequest const & cmd);
138 BufferView * bv() const;
140 friend class LyXScreen;
142 /// returns an iterator pointing to a cursor paragraph
143 ParagraphList::iterator getPar(LyXCursor const & cursor) const;
145 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
147 int parOffset(ParagraphList::iterator pit) const;
149 ParagraphList::iterator cursorPar() const;
151 RowList::iterator cursorRow() const;
153 /** returns an iterator pointing to the row near the specified
154 * y-coordinate (relative to the whole text). y is set to the
155 * real beginning of this row
157 RowList::iterator getRowNearY(int y,
158 ParagraphList::iterator & pit) const;
160 /** returns the column near the specified x-coordinate of the row
161 x is set to the real beginning of this column
163 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
164 Row const & row, int & x, bool & boundary) const;
166 /// need the selection cursor:
169 void clearSelection();
171 /// select the word we need depending on word_location
172 void getWord(LyXCursor & from, LyXCursor & to, lyx::word_location const);
173 /// just selects the word the cursor is in
174 void selectWord(lyx::word_location loc);
175 /// returns the inset at cursor (if it exists), 0 otherwise
176 InsetOld * getInset() const;
178 /// accept selected change
181 /// reject selected change
184 /// re-computes the cached coordinates in the cursor
187 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
188 /// returns true if par was empty and was removed
189 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
190 bool setfont = true, bool boundary = false);
192 void setCursor(LyXCursor &, lyx::paroffset_type par,
193 lyx::pos_type pos, bool boundary = false);
195 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
196 bool setfont = true, bool boundary = false);
198 void setCurrentFont();
201 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
203 void recUndo(lyx::paroffset_type first) const;
205 void setCursorFromCoordinates(int x, int y);
207 void setCursorFromCoordinates(LyXCursor &, int x, int y);
209 void cursorUp(bool selecting = false);
211 void cursorDown(bool selecting = false);
213 bool cursorLeft(bool internal = true);
215 bool cursorRight(bool internal = true);
217 void cursorLeftOneWord();
219 void cursorRightOneWord();
221 void cursorUpParagraph();
223 void cursorDownParagraph();
229 void cursorPrevious();
241 bool selectWordWhenUnderCursor(lyx::word_location);
247 text_capitalization = 1,
251 /// Change the case of the word at cursor position.
252 void changeCase(TextCase action);
257 void cutSelection(bool doclear = true, bool realcut = true);
259 void copySelection();
261 void pasteSelection(size_t sel_index = 0);
263 /** the DTP switches for paragraphs. LyX will store the top settings
264 always in the first physical paragraph, the bottom settings in the
265 last. When a paragraph is broken, the top settings rest, the bottom
266 settings are given to the new one.
269 Spacing const & spacing,
271 std::string const & labelwidthstring,
274 /* these things are for search and replace */
277 * Sets the selection from the current cursor position to length
278 * characters to the right. No safety checks.
280 void setSelectionRange(lyx::pos_type length);
282 /** simple replacing. The font of the first selected character
285 void replaceSelectionWithString(std::string const & str);
287 /// needed to insert the selection
288 void insertStringAsLines(std::string const & str);
289 /// needed to insert the selection
290 void insertStringAsParagraphs(std::string const & str);
292 /// Find next inset of some specified type.
293 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
294 std::string const & contents = std::string());
296 void gotoInset(std::vector<InsetOld::Code> const & codes,
299 void gotoInset(InsetOld::Code code, bool same_content);
301 /// current max text width
302 int textWidth() const;
304 /// updates all counters
305 void updateCounters();
306 /// Returns an inset if inset was hit, or 0 if not.
307 InsetOld * checkInsetHit(int x, int y);
310 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
312 int singleWidth(ParagraphList::iterator pit,
313 lyx::pos_type pos, char c, LyXFont const & Font) const;
315 /// return the color of the canvas
316 LColor_color backgroundColor() const;
319 * Returns the left beginning of the text.
320 * This information cannot be taken from the layout object, because
321 * in LaTeX the beginning of the text fits in some cases
322 * (for example sections) exactly the label-width.
324 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
325 int leftMargin(ParagraphList::iterator pit) const;
327 int rightMargin(Paragraph const & par) const;
329 /** this calculates the specified parameters. needed when setting
330 * the cursor and when creating a visible row */
331 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
334 // special owner functions
336 ParagraphList & paragraphs() const;
338 /// return true if this is owned by an inset.
339 bool isInInset() const;
342 ParagraphList::iterator firstPar() const;
344 ParagraphList::iterator lastPar() const;
346 ParagraphList::iterator endPar() const;
348 /// return first row of text
349 RowList::iterator firstRow() const;
350 /// return last row of text
351 RowList::iterator lastRow() const;
352 /// return row "behind" last row of text
353 RowList::iterator endRow() const;
354 /// return next row crossing paragraph boundaries
355 void nextRow(ParagraphList::iterator & pit,
356 RowList::iterator & rit) const;
357 /// return previous row crossing paragraph boundaries
358 void previousRow(ParagraphList::iterator & pit,
359 RowList::iterator & rit) const;
361 /// is this row the last in the text?
362 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
363 /// is this row the first in the text?
364 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
367 std::string selectionAsString(Buffer const & buffer, bool label) const;
369 double spacing(Paragraph const &) const;
371 void cursorLeftOneWord(LyXCursor &);
373 void cursorRightOneWord(LyXCursor &);
376 DispatchResult moveRight();
378 DispatchResult moveLeft();
380 DispatchResult moveRightIntern(bool front,
381 bool activate_inset, bool selecting);
383 DispatchResult moveLeftIntern(bool front,
384 bool activate_inset, bool selecting);
386 DispatchResult moveUp();
388 DispatchResult moveDown();
390 bool checkAndActivateInset(bool front);
400 /// the current font settings
401 LyXFont current_font;
403 LyXFont real_current_font;
404 /// our buffer's default layout font
405 LyXFont defaultfont_;
407 int background_color_;
409 /// only the top-level LyXText has this non-zero
410 BufferView * bv_owner;
417 ParagraphList paragraphs_;
419 /// absolute document pixel coordinates of this LyXText
425 /// rebreaks the given par
426 void redoParagraphInternal(ParagraphList::iterator pit);
429 float getCursorX(ParagraphList::iterator pit,
430 Row const & row, lyx::pos_type pos, bool boundary) const;
431 /// used in setlayout
432 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
434 /// Calculate and set the height of the row
435 void setHeightOfRow(ParagraphList::iterator, Row & row);
437 // fix the cursor `cur' after a characters has been deleted at `where'
438 // position. Called by deleteEmptyParagraphMechanism
439 void fixCursorAfterDelete(LyXCursor & cur, LyXCursor const & where);
441 /// delete double space (false) or empty paragraphs (true) around old_cursor
442 bool deleteEmptyParagraphMechanism(LyXCursor const & old_cursor);
445 void setCounter(Buffer const &, ParagraphList::iterator pit);
447 void deleteWordForward();
449 void deleteWordBackward();
451 void deleteLineForward();
453 /// sets row.end to the pos value *after* which a row should break.
454 /// for example, the pos after which isNewLine(pos) == true
455 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
457 /// sets row.witdh to the minimum space a row needs on the screen in pixel
458 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
461 * returns the minimum space a manual label needs on the
464 int labelFill(ParagraphList::iterator pit, Row const & row) const;
467 int labelEnd(ParagraphList::iterator pit) const;
471 /// set 'number' font property
473 /// is the cursor paragraph right-to-left?
477 /// return the default height of a row in pixels, considering font zoom
478 extern int defaultRowHeight();
481 std::string expandLabel(LyXTextClass const & textclass,
482 LyXLayout_ptr const & layout, bool appendix);