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"
45 This class used to hold the mapping between buffer paragraphs and
46 screen rows. Nowadays, the Paragraphs take care of their rows
47 themselves and this contains just most of the code for manipulating
48 them and interaction with the Cursor.
51 // The inheritance from TextCursor should go. It's just there to ease
53 class LyXText : public TextCursor {
57 LyXText(BufferView *, bool ininset);
59 void init(BufferView *);
62 /// update y coordinate cache of all paragraphs
63 void updateParPositions();
65 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
67 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
69 LyXFont getLabelFont(ParagraphList::iterator pit) const;
71 void setCharFont(ParagraphList::iterator pit,
72 lyx::pos_type pos, LyXFont const & font);
73 void setCharFont(ParagraphList::iterator pit,
75 LyXFont const & font, bool toggleall);
77 /// what you expect when pressing <enter> at cursor position
78 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
80 /** set layout over selection and make a total rebreak of
83 ParagraphList::iterator
84 setLayout(LyXCursor & actual_cursor,
85 LyXCursor & selection_start,
86 LyXCursor & selection_end,
87 std::string const & layout);
89 void setLayout(std::string const & layout);
91 /// Increase or decrease the nesting depth of the selected paragraph(s)
92 void changeDepth(bv_funcs::DEPTH_CHANGE type);
94 /// Returns whether something would be changed by changeDepth
95 bool changeDepthAllowed(bv_funcs::DEPTH_CHANGE type);
97 /// get the depth at current cursor position
100 /** set font over selection and make a total rebreak of those
102 toggleall defaults to false.
104 void setFont(LyXFont const &, bool toggleall = false);
106 /// rebreaks all paragaphs between the given pars.
107 void redoParagraphs(ParagraphList::iterator begin,
108 ParagraphList::iterator end);
109 /// rebreaks the given par
110 void redoParagraph(ParagraphList::iterator pit);
112 /// rebreaks the cursor par
113 void redoParagraph();
116 void toggleFree(LyXFont const &, bool toggleall = false);
119 std::string getStringToIndex();
121 /** insert a character, moves all the following breaks in the
122 same Paragraph one to the right and make a little rebreak
124 void insertChar(char c);
126 void insertInset(InsetOld * inset);
128 /// a full rebreak of the whole text
130 /// compute text metrics
131 void metrics(MetricsInfo & mi, Dimension & dim);
132 /// draw text (only used for insets)
133 void draw(PainterInfo & pi, int x, int y) const;
135 /// try to handle that request
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 an iterator pointing to the row near the specified
156 * y-coordinate (relative to the whole text). y is set to the
157 * real beginning of this row
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 Spacing const & spacing,
273 std::string const & labelwidthstring,
276 /* these things are for search and replace */
279 * Sets the selection from the current cursor position to length
280 * characters to the right. No safety checks.
282 void setSelectionRange(lyx::pos_type length);
284 /** simple replacing. The font of the first selected character
287 void replaceSelectionWithString(std::string const & str);
289 /// needed to insert the selection
290 void insertStringAsLines(std::string const & str);
291 /// needed to insert the selection
292 void insertStringAsParagraphs(std::string const & str);
294 /// Find next inset of some specified type.
295 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
296 std::string const & contents = std::string());
298 void gotoInset(std::vector<InsetOld::Code> const & codes,
301 void gotoInset(InsetOld::Code code, bool same_content);
303 /// current max text width
304 int textWidth() const;
306 /// updates all counters
307 void updateCounters();
308 /// Returns an inset if inset was hit, or 0 if not.
309 InsetOld * checkInsetHit(int x, int y);
312 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
314 int singleWidth(ParagraphList::iterator pit,
315 lyx::pos_type pos, char c, LyXFont const & Font) const;
317 /// return the color of the canvas
318 LColor_color backgroundColor() const;
321 * Returns the left beginning of the text.
322 * This information cannot be taken from the layout object, because
323 * in LaTeX the beginning of the text fits in some cases
324 * (for example sections) exactly the label-width.
326 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
327 int leftMargin(ParagraphList::iterator pit) const;
329 int rightMargin(Paragraph const & par) const;
331 /** this calculates the specified parameters. needed when setting
332 * the cursor and when creating a visible row */
333 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
336 // special owner functions
338 ParagraphList & paragraphs() const;
340 /// return true if this is owned by an inset.
341 bool isInInset() const;
344 ParagraphList::iterator firstPar() const;
346 ParagraphList::iterator lastPar() const;
348 ParagraphList::iterator endPar() const;
350 /// return first row of text
351 RowList::iterator firstRow() const;
352 /// return last row of text
353 RowList::iterator lastRow() const;
354 /// return row "behind" last row of text
355 RowList::iterator endRow() const;
356 /// return next row crossing paragraph boundaries
357 void nextRow(ParagraphList::iterator & pit,
358 RowList::iterator & rit) const;
359 /// return previous row crossing paragraph boundaries
360 void previousRow(ParagraphList::iterator & pit,
361 RowList::iterator & rit) const;
363 /// is this row the last in the text?
364 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
365 /// is this row the first in the text?
366 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
369 std::string selectionAsString(Buffer const & buffer, bool label) const;
371 double spacing(Paragraph const &) const;
373 void cursorLeftOneWord(LyXCursor &);
375 void cursorRightOneWord(LyXCursor &);
378 DispatchResult moveRight();
380 DispatchResult moveLeft();
382 DispatchResult moveRightIntern(bool front,
383 bool activate_inset, bool selecting);
385 DispatchResult moveLeftIntern(bool front,
386 bool activate_inset, bool selecting);
388 DispatchResult moveUp();
390 DispatchResult moveDown();
392 bool checkAndActivateInset(bool front);
395 void write(Buffer const & buf, std::ostream & os) const;
396 /// returns whether we've seen our usual 'end' marker
397 bool read(Buffer const & buf, LyXLex & lex);
406 /// the current font settings
407 LyXFont current_font;
409 LyXFont real_current_font;
410 /// our buffer's default layout font
411 LyXFont defaultfont_;
413 int background_color_;
415 /// only the top-level LyXText has this non-zero
416 BufferView * bv_owner;
423 ParagraphList paragraphs_;
425 /// 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) const;
477 /// set 'number' font property
479 /// is the cursor paragraph right-to-left?
483 /// return the default height of a row in pixels, considering font zoom
484 extern int defaultRowHeight();
487 std::string expandLabel(LyXTextClass const & textclass,
488 LyXLayout_ptr const & layout, bool appendix);