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 /// select the word we need depending on word_location
182 void getWord(CursorSlice & from, CursorSlice & to, lyx::word_location const);
183 /// just selects the word the cursor is in
184 void selectWord(lyx::word_location loc);
185 /// returns the inset at cursor (if it exists), 0 otherwise
186 InsetOld * getInset() const;
188 /// accept selected change
191 /// reject selected change
195 void setCursor(ParagraphList::iterator pit, lyx::pos_type pos);
196 /// returns true if par was empty and was removed
197 bool setCursor(lyx::paroffset_type par, lyx::pos_type pos,
198 bool setfont = true, bool boundary = false);
200 void setCursor(CursorSlice &, lyx::paroffset_type par,
201 lyx::pos_type pos, bool boundary = false);
203 void setCursorIntern(lyx::paroffset_type par, lyx::pos_type pos,
204 bool setfont = true, bool boundary = false);
206 void setCurrentFont();
209 void recUndo(lyx::paroffset_type first, lyx::paroffset_type last) const;
211 void recUndo(lyx::paroffset_type first) const;
213 void setCursorFromCoordinates(int x, int y);
215 void setCursorFromCoordinates(CursorSlice &, int x, int y);
217 void cursorUp(bool selecting = false);
219 void cursorDown(bool selecting = false);
221 bool cursorLeft(bool internal = true);
223 bool cursorRight(bool internal = true);
225 void cursorLeftOneWord();
227 void cursorRightOneWord();
229 void cursorUpParagraph();
231 void cursorDownParagraph();
237 void cursorPrevious();
249 bool selectWordWhenUnderCursor(lyx::word_location);
255 text_capitalization = 1,
259 /// Change the case of the word at cursor position.
260 void changeCase(TextCase action);
265 void cutSelection(bool doclear = true, bool realcut = true);
267 void copySelection();
269 void pasteSelection(size_t sel_index = 0);
271 /** the DTP switches for paragraphs. LyX will store the top settings
272 always in the first physical paragraph, the bottom settings in the
273 last. When a paragraph is broken, the top settings rest, the bottom
274 settings are given to the new one.
277 Spacing const & spacing,
279 std::string const & labelwidthstring,
282 /* these things are for search and replace */
285 * Sets the selection from the current cursor position to length
286 * characters to the right. No safety checks.
288 void setSelectionRange(lyx::pos_type length);
290 /** simple replacing. The font of the first selected character
293 void replaceSelectionWithString(std::string const & str);
295 /// needed to insert the selection
296 void insertStringAsLines(std::string const & str);
297 /// needed to insert the selection
298 void insertStringAsParagraphs(std::string const & str);
300 /// Find next inset of some specified type.
301 bool gotoNextInset(std::vector<InsetOld::Code> const & codes,
302 std::string const & contents = std::string());
304 void gotoInset(std::vector<InsetOld::Code> const & codes,
307 void gotoInset(InsetOld::Code code, bool same_content);
309 /// current max text width
310 int textWidth() const;
312 /// updates all counters
313 void updateCounters();
314 /// Returns an inset if inset was hit, or 0 if not.
315 InsetOld * checkInsetHit(int x, int y);
318 int singleWidth(ParagraphList::iterator pit, lyx::pos_type pos) const;
320 int singleWidth(ParagraphList::iterator pit,
321 lyx::pos_type pos, char c, LyXFont const & Font) const;
323 /// return the color of the canvas
324 LColor_color backgroundColor() const;
327 * Returns the left beginning of the text.
328 * This information cannot be taken from the layout object, because
329 * in LaTeX the beginning of the text fits in some cases
330 * (for example sections) exactly the label-width.
332 int leftMargin(ParagraphList::iterator pit, lyx::pos_type pos) const;
333 int leftMargin(ParagraphList::iterator pit) const;
335 int rightMargin(Paragraph const & par) const;
337 /** this calculates the specified parameters. needed when setting
338 * the cursor and when creating a visible row */
339 void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
342 // special owner functions
344 ParagraphList & paragraphs() const;
346 /// return true if this is owned by an inset.
347 bool isInInset() const;
350 ParagraphList::iterator firstPar() const;
352 ParagraphList::iterator lastPar() const;
354 ParagraphList::iterator endPar() const;
356 /// return first row of text
357 RowList::iterator firstRow() const;
358 /// return last row of text
359 RowList::iterator lastRow() const;
360 /// return row "behind" last row of text
361 RowList::iterator endRow() const;
362 /// return next row crossing paragraph boundaries
363 void nextRow(ParagraphList::iterator & pit,
364 RowList::iterator & rit) const;
365 /// return previous row crossing paragraph boundaries
366 void previousRow(ParagraphList::iterator & pit,
367 RowList::iterator & rit) const;
369 /// is this row the last in the text?
370 bool isLastRow(ParagraphList::iterator pit, Row const & row) const;
371 /// is this row the first in the text?
372 bool isFirstRow(ParagraphList::iterator pit, Row const & row) const;
375 std::string selectionAsString(Buffer const & buffer, bool label) const;
377 double spacing(Paragraph const &) const;
379 void cursorLeftOneWord(CursorSlice &);
381 void cursorRightOneWord(CursorSlice &);
384 DispatchResult moveRight();
386 DispatchResult moveLeft();
388 DispatchResult moveRightIntern(bool front,
389 bool activate_inset, bool selecting);
391 DispatchResult moveLeftIntern(bool front,
392 bool activate_inset, bool selecting);
394 DispatchResult moveUp();
396 DispatchResult moveDown();
398 bool checkAndActivateInset(bool front);
401 void write(Buffer const & buf, std::ostream & os) const;
402 /// returns whether we've seen our usual 'end' marker
403 bool read(Buffer const & buf, LyXLex & lex);
414 int cursorX(CursorSlice const & cursor) const;
416 int cursorY(CursorSlice const & cursor) const;
418 /// the topmost cursor slice
419 CursorSlice & cursor();
420 /// the topmost cursor slice
421 CursorSlice const & cursor() const;
422 /// access to the selection anchor
423 CursorSlice & anchor();
424 /// access to the selection anchor
425 CursorSlice const & anchor() const;
430 void clearSelection();
432 CursorSlice const & selStart() const;
434 CursorSlice const & selEnd() const;
436 CursorSlice & selStart();
438 CursorSlice & selEnd();
443 Later this variable has to be removed. There should be no internal
444 cursor in a text (and thus not in a buffer). By keeping this it is
445 (I think) impossible to have several views with the same buffer, but
446 the cursor placed at different places.
448 Since the LyXText now has been moved from Buffer to BufferView
449 it should not be absolutely needed to move the cursor...
451 Nevertheless, it should still be moved, in order to keep classes
452 and interdependencies small.
454 // the other end of the selection
465 /// the current font settings
466 LyXFont current_font;
468 LyXFont real_current_font;
469 /// our buffer's default layout font
470 LyXFont defaultfont_;
472 int background_color_;
474 /// only the top-level LyXText has this non-zero
475 BufferView * bv_owner;
482 ParagraphList paragraphs_;
484 /// absolute document pixel coordinates of this LyXText
488 /// our 'outermost' Font
493 /// return past-the-last paragraph influenced by a layout
495 ParagraphList::iterator undoSpan(ParagraphList::iterator pit);
497 /// rebreaks the given par
498 void redoParagraphInternal(ParagraphList::iterator pit);
499 /// used in setlayout
500 void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
502 /// Calculate and set the height of the row
503 void setHeightOfRow(ParagraphList::iterator, Row & row);
505 // fix the cursor `cur' after a characters has been deleted at `where'
506 // position. Called by deleteEmptyParagraphMechanism
507 void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
509 /// delete double space (false) or empty paragraphs (true) around old_cursor
510 bool deleteEmptyParagraphMechanism(CursorSlice const & old_cursor);
513 void setCounter(Buffer const &, ParagraphList::iterator pit);
515 void deleteWordForward();
517 void deleteWordBackward();
519 void deleteLineForward();
521 /// sets row.end to the pos value *after* which a row should break.
522 /// for example, the pos after which isNewLine(pos) == true
523 void rowBreakPoint(ParagraphList::iterator pit, Row & row) const;
525 /// sets row.witdh to the minimum space a row needs on the screen in pixel
526 void fill(ParagraphList::iterator pit, Row & row, int workwidth) const;
529 * returns the minimum space a manual label needs on the
532 int labelFill(ParagraphList::iterator pit, Row const & row) const;
535 int labelEnd(ParagraphList::iterator pit) const;
539 /// set 'number' font property
541 /// is the cursor paragraph right-to-left?
545 /// return the default height of a row in pixels, considering font zoom
546 extern int defaultRowHeight();
549 std::string expandLabel(LyXTextClass const & textclass,
550 LyXLayout_ptr const & layout, bool appendix);