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"
18 #include "cursor_slice.h"
22 #include "lyxtextclass.h"
23 #include "ParagraphList_fwd.h"
24 #include "RowList_fwd.h"
26 #include "insets/inset.h"
44 /// This class encapsulates the main text data and operations in LyX
48 LyXText(BufferView *, bool ininset);
50 void init(BufferView *);
53 /// update y coordinate cache of all paragraphs
54 void updateParPositions();
56 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
58 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
60 LyXFont getLabelFont(ParagraphList::iterator pit) const;
62 void setCharFont(ParagraphList::iterator pit,
63 lyx::pos_type pos, LyXFont const & font);
64 void setCharFont(ParagraphList::iterator pit,
66 LyXFont const & font, bool toggleall);
68 /// what you expect when pressing <enter> at cursor position
69 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
71 /** set layout over selection and make a total rebreak of
74 ParagraphList::iterator
75 setLayout(ParagraphList::iterator start,
76 ParagraphList::iterator end,
77 std::string const & layout);
79 void setLayout(std::string const & layout);
81 /// Increase or decrease the nesting depth of the selected paragraph(s)
82 void changeDepth(bv_funcs::DEPTH_CHANGE type);
84 /// Returns whether something would be changed by changeDepth
85 bool changeDepthAllowed(bv_funcs::DEPTH_CHANGE type);
87 /// get the depth at current cursor position
90 /** set font over selection and make a total rebreak of those
92 toggleall defaults to false.
94 void setFont(LyXFont const &, bool toggleall = false);
96 /// rebreaks all paragaphs between the given pars.
97 void redoParagraphs(ParagraphList::iterator begin,
98 ParagraphList::iterator end);
99 /// rebreaks the given par
100 void redoParagraph(ParagraphList::iterator pit);
102 /// rebreaks the cursor par
103 void redoParagraph();
106 void toggleFree(LyXFont const &, bool toggleall = false);
109 std::string getStringToIndex();
111 /** insert a character, moves all the following breaks in the
112 same Paragraph one to the right and make a little rebreak
114 void insertChar(char c);
116 void insertInset(InsetOld * inset);
118 /// a full rebreak of the whole text
120 /// compute text metrics
121 void metrics(MetricsInfo & mi, Dimension & dim);
122 /// draw text (only used for insets)
123 void draw(PainterInfo & pi, int x, int y) const;
125 /// try to handle that request
126 DispatchResult dispatch(FuncRequest const & cmd);
130 BufferView * bv() const;
132 friend class LyXScreen;
134 /// returns an iterator pointing to a cursor paragraph
135 ParagraphList::iterator getPar(CursorSlice const & cursor) const;
137 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
139 int parOffset(ParagraphList::iterator pit) const;
141 ParagraphList::iterator cursorPar() const;
143 RowList::iterator cursorRow() const;
145 /** returns an iterator pointing to the row near the specified
146 * y-coordinate (relative to the whole text). y is set to the
147 * real beginning of this row
149 RowList::iterator getRowNearY(int y,
150 ParagraphList::iterator & pit) const;
152 /** returns the column near the specified x-coordinate of the row
153 x is set to the real beginning of this column
155 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
156 Row const & row, int & x, bool & boundary) const;
158 /** Find the word under \c from in the relative location
159 * defined by \c word_location.
160 * @param from return here the start of the word
161 * @param to return here the end of the word
163 void getWord(CursorSlice & from, CursorSlice & to, lyx::word_location const);
164 /// just selects the word the cursor is in
165 void selectWord(lyx::word_location loc);
166 /// returns the inset at cursor (if it exists), 0 otherwise
167 InsetOld * getInset() const;
169 /// accept selected change
172 /// reject selected change
176 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
177 /// returns true if par was empty and was removed
178 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
179 bool setfont = true, bool boundary = false);
181 void setCursor(CursorSlice &, lyx::paroffset_type par,
182 lyx::pos_type pos, bool boundary = false);
184 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
185 bool setfont = true, bool boundary = false);
187 void setCurrentFont();
190 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
192 void recUndo(lyx::paroffset_type first) const;
194 void setCursorFromCoordinates(int x, int y);
196 void setCursorFromCoordinates(CursorSlice &, int x, int y);
198 void cursorUp(bool selecting = false);
200 void cursorDown(bool selecting = false);
202 bool cursorLeft(bool internal = true);
204 bool cursorRight(bool internal = true);
206 void cursorLeftOneWord();
208 void cursorRightOneWord();
210 void cursorUpParagraph();
212 void cursorDownParagraph();
218 void cursorPrevious();
230 bool selectWordWhenUnderCursor(lyx::word_location);
236 text_capitalization = 1,
240 /// Change the case of the word at cursor position.
241 void changeCase(TextCase action);
246 void cutSelection(bool doclear = true, bool realcut = true);
248 void copySelection();
250 void pasteSelection(size_t sel_index = 0);
252 /** the DTP switches for paragraphs. LyX will store the top settings
253 always in the first physical paragraph, the bottom settings in the
254 last. When a paragraph is broken, the top settings rest, the bottom
255 settings are given to the new one.
258 Spacing const & spacing,
260 std::string const & labelwidthstring,
263 /* these things are for search and replace */
266 * Sets the selection from the current cursor position to length
267 * characters to the right. No safety checks.
269 void setSelectionRange(lyx::pos_type length);
271 /** simple replacing. The font of the first selected character
274 void replaceSelectionWithString(std::string const & str);
276 /// needed to insert the selection
277 void insertStringAsLines(std::string const & str);
278 /// needed to insert the selection
279 void insertStringAsParagraphs(std::string const & str);
281 /// Find next inset of some specified type.
282 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
283 std::string const & contents = std::string());
285 void gotoInset(std::vector<InsetOld::Code> const & codes,
288 void gotoInset(InsetOld::Code code, bool same_content);
290 /// current max text width
291 int textWidth() const;
293 /// updates all counters
294 void updateCounters();
295 /// Returns an inset if inset was hit, or 0 if not.
296 InsetOld * checkInsetHit(int x, int y);
299 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
301 int singleWidth(ParagraphList::iterator pit,
302 lyx::pos_type pos, char c, LyXFont const & Font) const;
304 /// return the color of the canvas
305 LColor_color backgroundColor() const;
308 * Returns the left beginning of the text.
309 * This information cannot be taken from the layout object, because
310 * in LaTeX the beginning of the text fits in some cases
311 * (for example sections) exactly the label-width.
313 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
314 int leftMargin(ParagraphList::iterator pit) const;
316 int rightMargin(Paragraph const & par) const;
318 /** this calculates the specified parameters. needed when setting
319 * the cursor and when creating a visible row */
320 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
323 // special owner functions
325 ParagraphList & paragraphs() const;
327 /// return true if this is owned by an inset.
328 bool isInInset() const;
331 ParagraphList::iterator firstPar() const;
333 ParagraphList::iterator lastPar() const;
335 ParagraphList::iterator endPar() const;
337 /// return first row of text
338 RowList::iterator firstRow() const;
339 /// return last row of text
340 RowList::iterator lastRow() const;
341 /// return row "behind" last row of text
342 RowList::iterator endRow() const;
343 /// return next row crossing paragraph boundaries
344 void nextRow(ParagraphList::iterator & pit,
345 RowList::iterator & rit) const;
346 /// return previous row crossing paragraph boundaries
347 void previousRow(ParagraphList::iterator & pit,
348 RowList::iterator & rit) const;
350 /// is this row the last in the text?
351 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
352 /// is this row the first in the text?
353 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
356 std::string selectionAsString(Buffer const & buffer, bool label) const;
358 double spacing(Paragraph const &) const;
360 void cursorLeftOneWord(CursorSlice &);
362 void cursorRightOneWord(CursorSlice &);
365 DispatchResult moveRight();
367 DispatchResult moveLeft();
369 DispatchResult moveRightIntern(bool front,
370 bool activate_inset, bool selecting);
372 DispatchResult moveLeftIntern(bool front,
373 bool activate_inset, bool selecting);
375 DispatchResult moveUp();
377 DispatchResult moveDown();
379 bool checkAndActivateInset(bool front);
382 void write(Buffer const & buf, std::ostream & os) const;
383 /// returns whether we've seen our usual 'end' marker
384 bool read(Buffer const & buf, LyXLex & lex);
395 int cursorX(CursorSlice const & cursor) const;
397 int cursorY(CursorSlice const & cursor) const;
399 /// the topmost cursor slice
400 CursorSlice & cursor();
401 /// the topmost cursor slice
402 CursorSlice const & cursor() const;
403 /// access to the selection anchor
404 CursorSlice & anchor();
405 /// access to the selection anchor
406 CursorSlice const & anchor() const;
411 void clearSelection();
420 /// the current font settings
421 LyXFont current_font;
423 LyXFont real_current_font;
424 /// our buffer's default layout font
425 LyXFont defaultfont_;
427 int background_color_;
429 /// only the top-level LyXText has this non-zero
430 BufferView * bv_owner;
437 ParagraphList paragraphs_;
439 /// absolute document pixel coordinates of this LyXText
443 /// our 'outermost' Font
448 /// return past-the-last paragraph influenced by a layout
450 ParagraphList::iterator undoSpan(ParagraphList::iterator pit);
452 /// rebreaks the given par
453 void redoParagraphInternal(ParagraphList::iterator pit);
454 /// used in setlayout
455 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
457 /// Calculate and set the height of the row
458 void setHeightOfRow(ParagraphList::iterator, Row & row);
460 // fix the cursor `cur' after a characters has been deleted at `where'
461 // position. Called by deleteEmptyParagraphMechanism
462 void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
464 /// delete double space (false) or empty paragraphs (true) around old_cursor
465 bool deleteEmptyParagraphMechanism(CursorSlice const & old_cursor);
468 void setCounter(Buffer const &, ParagraphList::iterator pit);
470 void deleteWordForward();
472 void deleteWordBackward();
474 void deleteLineForward();
476 /// sets row.end to the pos value *after* which a row should break.
477 /// for example, the pos after which isNewLine(pos) == true
478 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
480 /// sets row.witdh to the minimum space a row needs on the screen in pixel
481 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
484 * returns the minimum space a manual label needs on the
487 int labelFill(ParagraphList::iterator pit, Row const & row) const;
490 int labelEnd(ParagraphList::iterator pit) const;
494 /// set 'number' font property
496 /// is the cursor paragraph right-to-left?
500 /// return the default height of a row in pixels, considering font zoom
501 extern int defaultRowHeight();
504 std::string expandLabel(LyXTextClass const & textclass,
505 LyXLayout_ptr const & layout, bool appendix);