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 // The structure that keeps track of the selections set.
47 : set_(false), mark_(false)
62 bool set_; // former selection
63 bool mark_; // former mark_set
67 /// This class encapsulates the main text data and operations in LyX
71 LyXText(BufferView *, bool ininset);
73 void init(BufferView *);
76 /// update y coordinate cache of all paragraphs
77 void updateParPositions();
79 LyXFont getFont(ParagraphList::iterator pit, lyx::pos_type pos) const;
81 LyXFont getLayoutFont(ParagraphList::iterator pit) const;
83 LyXFont getLabelFont(ParagraphList::iterator pit) const;
85 void setCharFont(ParagraphList::iterator pit,
86 lyx::pos_type pos, LyXFont const & font);
87 void setCharFont(ParagraphList::iterator pit,
89 LyXFont const & font, bool toggleall);
91 /// what you expect when pressing <enter> at cursor position
92 void breakParagraph(ParagraphList & paragraphs, char keep_layout = 0);
94 /** set layout over selection and make a total rebreak of
97 ParagraphList::iterator
98 setLayout(ParagraphList::iterator start,
99 ParagraphList::iterator end,
100 std::string const & layout);
102 void setLayout(std::string const & layout);
104 /// Increase or decrease the nesting depth of the selected paragraph(s)
105 void changeDepth(bv_funcs::DEPTH_CHANGE type);
107 /// Returns whether something would be changed by changeDepth
108 bool changeDepthAllowed(bv_funcs::DEPTH_CHANGE type);
110 /// get the depth at current cursor position
111 int getDepth() const;
113 /** set font over selection and make a total rebreak of those
115 toggleall defaults to false.
117 void setFont(LyXFont const &, bool toggleall = false);
119 /// rebreaks all paragaphs between the given pars.
120 void redoParagraphs(ParagraphList::iterator begin,
121 ParagraphList::iterator end);
122 /// rebreaks the given par
123 void redoParagraph(ParagraphList::iterator pit);
125 /// rebreaks the cursor par
126 void redoParagraph();
129 void toggleFree(LyXFont const &, bool toggleall = false);
132 std::string getStringToIndex();
134 /** insert a character, moves all the following breaks in the
135 same Paragraph one to the right and make a little rebreak
137 void insertChar(char c);
139 void insertInset(InsetOld * inset);
141 /// a full rebreak of the whole text
143 /// compute text metrics
144 void metrics(MetricsInfo & mi, Dimension & dim);
145 /// draw text (only used for insets)
146 void draw(PainterInfo & pi, int x, int y) const;
148 /// try to handle that request
149 DispatchResult dispatch(FuncRequest const & cmd);
153 BufferView * bv() const;
155 friend class LyXScreen;
157 /// returns an iterator pointing to a cursor paragraph
158 ParagraphList::iterator getPar(CursorSlice const & cursor) const;
160 ParagraphList::iterator getPar(lyx::paroffset_type par) const;
162 int parOffset(ParagraphList::iterator pit) const;
164 ParagraphList::iterator cursorPar() const;
166 RowList::iterator cursorRow() const;
168 /** returns an iterator pointing to the row near the specified
169 * y-coordinate (relative to the whole text). y is set to the
170 * real beginning of this row
172 RowList::iterator getRowNearY(int y,
173 ParagraphList::iterator & pit) const;
175 /** returns the column near the specified x-coordinate of the row
176 x is set to the real beginning of this column
178 lyx::pos_type getColumnNearX(ParagraphList::iterator pit,
179 Row const & row, int & x, bool & boundary) const;
181 /** Find the word under \c from in the relative location
182 * defined by \c word_location.
183 * @param from return here the start of the word
184 * @param to return here the end of the word
186 void getWord(CursorSlice & from, CursorSlice & to, lyx::word_location const);
187 /// just selects the word the cursor is in
188 void selectWord(lyx::word_location loc);
189 /// returns the inset at cursor (if it exists), 0 otherwise
190 InsetOld * getInset() const;
192 /// accept selected change
195 /// reject selected change
199 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
200 /// returns true if par was empty and was removed
201 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
202 bool setfont = true, bool boundary = false);
204 void setCursor(CursorSlice &, lyx::paroffset_type par,
205 lyx::pos_type pos, bool boundary = false);
207 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
208 bool setfont = true, bool boundary = false);
210 void setCurrentFont();
213 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
215 void recUndo(lyx::paroffset_type first) const;
217 void setCursorFromCoordinates(int x, int y);
219 void setCursorFromCoordinates(CursorSlice &, int x, int y);
221 void cursorUp(bool selecting = false);
223 void cursorDown(bool selecting = false);
225 bool cursorLeft(bool internal = true);
227 bool cursorRight(bool internal = true);
229 void cursorLeftOneWord();
231 void cursorRightOneWord();
233 void cursorUpParagraph();
235 void cursorDownParagraph();
241 void cursorPrevious();
253 bool selectWordWhenUnderCursor(lyx::word_location);
259 text_capitalization = 1,
263 /// Change the case of the word at cursor position.
264 void changeCase(TextCase action);
269 void cutSelection(bool doclear = true, bool realcut = true);
271 void copySelection();
273 void pasteSelection(size_t sel_index = 0);
275 /** the DTP switches for paragraphs. LyX will store the top settings
276 always in the first physical paragraph, the bottom settings in the
277 last. When a paragraph is broken, the top settings rest, the bottom
278 settings are given to the new one.
281 Spacing const & spacing,
283 std::string const & labelwidthstring,
286 /* these things are for search and replace */
289 * Sets the selection from the current cursor position to length
290 * characters to the right. No safety checks.
292 void setSelectionRange(lyx::pos_type length);
294 /** simple replacing. The font of the first selected character
297 void replaceSelectionWithString(std::string const & str);
299 /// needed to insert the selection
300 void insertStringAsLines(std::string const & str);
301 /// needed to insert the selection
302 void insertStringAsParagraphs(std::string const & str);
304 /// Find next inset of some specified type.
305 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
306 std::string const & contents = std::string());
308 void gotoInset(std::vector<InsetOld::Code> const & codes,
311 void gotoInset(InsetOld::Code code, bool same_content);
313 /// current max text width
314 int textWidth() const;
316 /// updates all counters
317 void updateCounters();
318 /// Returns an inset if inset was hit, or 0 if not.
319 InsetOld * checkInsetHit(int x, int y);
322 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
324 int singleWidth(ParagraphList::iterator pit,
325 lyx::pos_type pos, char c, LyXFont const & Font) const;
327 /// return the color of the canvas
328 LColor_color backgroundColor() const;
331 * Returns the left beginning of the text.
332 * This information cannot be taken from the layout object, because
333 * in LaTeX the beginning of the text fits in some cases
334 * (for example sections) exactly the label-width.
336 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
337 int leftMargin(ParagraphList::iterator pit) const;
339 int rightMargin(Paragraph const & par) const;
341 /** this calculates the specified parameters. needed when setting
342 * the cursor and when creating a visible row */
343 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
346 // special owner functions
348 ParagraphList & paragraphs() const;
350 /// return true if this is owned by an inset.
351 bool isInInset() const;
354 ParagraphList::iterator firstPar() const;
356 ParagraphList::iterator lastPar() const;
358 ParagraphList::iterator endPar() const;
360 /// return first row of text
361 RowList::iterator firstRow() const;
362 /// return last row of text
363 RowList::iterator lastRow() const;
364 /// return row "behind" last row of text
365 RowList::iterator endRow() const;
366 /// return next row crossing paragraph boundaries
367 void nextRow(ParagraphList::iterator & pit,
368 RowList::iterator & rit) const;
369 /// return previous row crossing paragraph boundaries
370 void previousRow(ParagraphList::iterator & pit,
371 RowList::iterator & rit) const;
373 /// is this row the last in the text?
374 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
375 /// is this row the first in the text?
376 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
379 std::string selectionAsString(Buffer const & buffer, bool label) const;
381 double spacing(Paragraph const &) const;
383 void cursorLeftOneWord(CursorSlice &);
385 void cursorRightOneWord(CursorSlice &);
388 DispatchResult moveRight();
390 DispatchResult moveLeft();
392 DispatchResult moveRightIntern(bool front,
393 bool activate_inset, bool selecting);
395 DispatchResult moveLeftIntern(bool front,
396 bool activate_inset, bool selecting);
398 DispatchResult moveUp();
400 DispatchResult moveDown();
402 bool checkAndActivateInset(bool front);
405 void write(Buffer const & buf, std::ostream & os) const;
406 /// returns whether we've seen our usual 'end' marker
407 bool read(Buffer const & buf, LyXLex & lex);
418 int cursorX(CursorSlice const & cursor) const;
420 int cursorY(CursorSlice const & cursor) const;
422 /// the topmost cursor slice
423 CursorSlice & cursor();
424 /// the topmost cursor slice
425 CursorSlice const & cursor() const;
426 /// access to the selection anchor
427 CursorSlice & anchor();
428 /// access to the selection anchor
429 CursorSlice const & anchor() const;
434 void clearSelection();
436 CursorSlice const & selStart() const;
438 CursorSlice const & selEnd() const;
440 CursorSlice & selStart();
442 CursorSlice & selEnd();
447 Later this variable has to be removed. There should be no internal
448 cursor in a text (and thus not in a buffer). By keeping this it is
449 (I think) impossible to have several views with the same buffer, but
450 the cursor placed at different places.
452 Since the LyXText now has been moved from Buffer to BufferView
453 it should not be absolutely needed to move the cursor...
455 Nevertheless, it should still be moved, in order to keep classes
456 and interdependencies small.
458 // the other end of the selection
469 /// the current font settings
470 LyXFont current_font;
472 LyXFont real_current_font;
473 /// our buffer's default layout font
474 LyXFont defaultfont_;
476 int background_color_;
478 /// only the top-level LyXText has this non-zero
479 BufferView * bv_owner;
486 ParagraphList paragraphs_;
488 /// absolute document pixel coordinates of this LyXText
492 /// our 'outermost' Font
497 /// return past-the-last paragraph influenced by a layout
499 ParagraphList::iterator undoSpan(ParagraphList::iterator pit);
501 /// rebreaks the given par
502 void redoParagraphInternal(ParagraphList::iterator pit);
503 /// used in setlayout
504 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
506 /// Calculate and set the height of the row
507 void setHeightOfRow(ParagraphList::iterator, Row & row);
509 // fix the cursor `cur' after a characters has been deleted at `where'
510 // position. Called by deleteEmptyParagraphMechanism
511 void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
513 /// delete double space (false) or empty paragraphs (true) around old_cursor
514 bool deleteEmptyParagraphMechanism(CursorSlice const & old_cursor);
517 void setCounter(Buffer const &, ParagraphList::iterator pit);
519 void deleteWordForward();
521 void deleteWordBackward();
523 void deleteLineForward();
525 /// sets row.end to the pos value *after* which a row should break.
526 /// for example, the pos after which isNewLine(pos) == true
527 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
529 /// sets row.witdh to the minimum space a row needs on the screen in pixel
530 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
533 * returns the minimum space a manual label needs on the
536 int labelFill(ParagraphList::iterator pit, Row const & row) const;
539 int labelEnd(ParagraphList::iterator pit) const;
543 /// set 'number' font property
545 /// is the cursor paragraph right-to-left?
549 /// return the default height of a row in pixels, considering font zoom
550 extern int defaultRowHeight();
553 std::string expandLabel(LyXTextClass const & textclass,
554 LyXLayout_ptr const & layout, bool appendix);