2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 1995 Matthias Ettrich
8 * Copyright 1995-2001 The LyX Team.
10 * ====================================================== */
21 #include "lyxcursor.h"
22 #include "lyxparagraph.h"
33 This class holds the mapping between buffer paragraphs and screen rows.
44 NEED_VERY_LITTLE_REFRESH,
50 LyXText(BufferView *);
57 void init(BufferView *);
59 mutable int number_of_rows;
63 mutable unsigned int width;
64 /// the current font settings
65 mutable LyXFont current_font;
67 mutable LyXFont real_current_font;
68 /// first visible pixel-row is set from LyXScreen!!!
69 // unsigned is wrong here for text-insets!
72 BufferView * bv_owner;
74 InsetText * inset_owner;
76 UpdatableInset * the_locking_inset;
79 int GetRealCursorX(BufferView *) const;
81 LyXFont const GetFont(Buffer const *, LyXParagraph * par,
82 LyXParagraph::size_type pos) const;
84 void SetCharFont(Buffer const *, LyXParagraph * par,
85 LyXParagraph::size_type pos, LyXFont const & font);
86 void SetCharFont(BufferView *, LyXParagraph * par,
87 LyXParagraph::size_type pos,
88 LyXFont const & font, bool toggleall);
89 /// returns a pointer to the very first LyXParagraph
90 LyXParagraph * FirstParagraph() const;
92 /// what you expect when pressing <enter> at cursor position
93 void BreakParagraph(BufferView *, char keep_layout = 0);
95 /** set layout over selection and make a total rebreak of
98 LyXParagraph * SetLayout(BufferView *, LyXCursor & actual_cursor,
99 LyXCursor & selection_start,
100 LyXCursor & selection_end,
101 LyXTextClass::size_type layout);
102 void SetLayout(BufferView *, LyXTextClass::size_type layout);
104 /// used in setlayout
105 void MakeFontEntriesLayoutSpecific(Buffer const *, LyXParagraph * par);
107 /** increment depth over selection and make a total rebreak of those
110 void IncDepth(BufferView *);
112 /** decrement depth over selection and make a total rebreak of those
114 void DecDepth(BufferView *);
116 /** Get the depth at current cursor position
118 int GetDepth() const { return cursor.par()->GetDepth(); }
120 /** set font over selection and make a total rebreak of those
122 toggleall defaults to false.
124 void SetFont(BufferView *, LyXFont const &, bool toggleall = false);
126 /** deletes and inserts again all paragaphs between the cursor
127 and the specified par. The Cursor is needed to set the refreshing
129 This function is needed after SetLayout and SetFont etc.
131 void RedoParagraphs(BufferView *, LyXCursor const & cursor,
132 LyXParagraph const * end_par) const;
134 void RedoParagraph(BufferView *) const;
137 void ToggleFree(BufferView *, LyXFont const &, bool toggleall = false);
139 /** recalculates the heights of all previous rows of the
140 specified paragraph. needed, if the last characters font
143 void RedoHeightOfParagraph(BufferView *, LyXCursor const & cursor);
145 /** forces the redrawing of a paragraph. Needed when manipulating a
148 void RedoDrawingOfParagraph(BufferView *, LyXCursor const & cursor);
150 /** insert a character, moves all the following breaks in the
151 same Paragraph one to the right and make a little rebreak
153 void InsertChar(BufferView *, char c);
155 void InsertInset(BufferView *, Inset * inset);
157 /** Completes the insertion with a full rebreak.
158 Returns true if something was broken. */
159 bool FullRebreak(BufferView *);
162 Row * need_break_row;
164 mutable int refresh_y;
172 mutable Row * refresh_row;
176 /** wether the screen needs a refresh,
177 starting with refresh_y
179 mutable text_status status;
181 /** returns a pointer to the row near the specified y-coordinate
182 (relative to the whole text). y is set to the real beginning
185 Row * GetRowNearY(int & y) const;
187 /** returns the column near the specified x-coordinate of the row
188 x is set to the real beginning of this column
190 int GetColumnNearX(BufferView *, Row * row,
191 int & x, bool & boundary) const;
193 /** returns a pointer to a specified row. y is set to the beginning
196 Row * GetRow(LyXParagraph * par,
197 LyXParagraph::size_type pos, int & y) const;
199 /** returns the height of a default row, needed for scrollbar
201 int DefaultHeight() const;
204 Later this variable has to be removed. There should be now internal
205 cursor in a text (and thus not in a buffer). By keeping this it is
206 (I think) impossible to have several views with the same buffer, but
207 the cursor placed at different places.
209 Since the LyXText now has been moved from Buffer to BufferView
210 it should not be absolutely needed to move the cursor...
212 mutable LyXCursor cursor;
214 /* the selection cursor */
216 mutable bool selection;
218 mutable bool mark_set;
221 mutable LyXCursor sel_cursor;
223 mutable LyXCursor sel_start_cursor;
225 mutable LyXCursor sel_end_cursor;
226 /// needed for the toggling
227 LyXCursor last_sel_cursor;
229 LyXCursor toggle_cursor;
231 LyXCursor toggle_end_cursor;
233 /// need the selection cursor:
234 void SetSelection(BufferView *);
236 void ClearSelection(BufferView *) const;
238 string const selectionAsString(Buffer const *) const;
240 /// just selects the word the cursor is in
241 void SelectWord(BufferView *);
243 /** 'selects" the next word, where the cursor is not in
244 and returns this word as string. THe cursor will be moved
245 to the beginning of this word.
246 With SelectSelectedWord can this be highlighted really
248 string const SelectNextWord(BufferView *, float & value) const;
250 void SelectSelectedWord(BufferView *);
252 void SetCursor(BufferView *, LyXParagraph * par,
253 LyXParagraph::size_type pos,
255 bool boundary = false) const;
257 void SetCursor(BufferView *, LyXCursor &, LyXParagraph * par,
258 LyXParagraph::size_type pos,
259 bool boundary = false) const;
261 void SetCursorIntern(BufferView *, LyXParagraph * par,
262 LyXParagraph::size_type pos,
264 bool boundary = false) const;
266 void SetCurrentFont(BufferView *) const;
269 bool IsBoundary(Buffer const *, LyXParagraph * par,
270 LyXParagraph::size_type pos) const;
272 bool IsBoundary(Buffer const *, LyXParagraph * par,
273 LyXParagraph::size_type pos,
274 LyXFont const & font) const;
277 void SetCursorFromCoordinates(BufferView *, int x, int y) const;
279 void SetCursorFromCoordinates(BufferView *, LyXCursor &,
282 void CursorUp(BufferView *) const;
284 void CursorDown(BufferView *) const;
286 void CursorLeft(BufferView *, bool internal = true) const;
288 void CursorRight(BufferView *, bool internal = true) const;
290 void CursorLeftOneWord(BufferView *) const;
292 void CursorRightOneWord(BufferView *) const;
294 void CursorUpParagraph(BufferView *) const;
296 void CursorDownParagraph(BufferView *) const;
298 void CursorHome(BufferView *) const;
300 void CursorEnd(BufferView *) const;
302 void CursorTab(BufferView *) const;
304 void CursorTop(BufferView *) const;
306 void CursorBottom(BufferView *) const;
308 void Delete(BufferView *);
310 void Backspace(BufferView *);
312 void DeleteWordForward(BufferView *);
314 void DeleteWordBackward(BufferView *);
316 void DeleteLineForward(BufferView *);
318 bool SelectWordWhenUnderCursor(BufferView *);
324 text_capitalization = 1,
328 /// Change the case of the word at cursor position.
329 void ChangeWordCase(BufferView *, TextCase action);
330 void TransposeChars(BufferView const &);
332 /** returns a printed row in a pixmap. The y value is needed to
333 decide, wether it is selected text or not. This is a strange
336 void GetVisibleRow(BufferView *, int y_offset, int x_offset,
337 Row * row_ptr, int y, bool cleared=false);
340 void CutSelection(BufferView *, bool = true);
342 void CopySelection(BufferView *);
344 void PasteSelection(BufferView *);
346 void copyEnvironmentType();
348 void pasteEnvironmentType(BufferView *);
350 void InsertFootnote();
352 void InsertMarginpar();
356 void InsertTabular();
358 /** the DTP switches for paragraphs. LyX will store the top settings
359 always in the first physical paragraph, the bottom settings in the
360 last. When a paragraph is broken, the top settings rest, the bottom
361 settings are given to the new one. So I can make shure, they do not
362 duplicate themself (and you cannnot make dirty things with them! )
364 void SetParagraph(BufferView *,
365 bool line_top, bool line_bottom,
366 bool pagebreak_top, bool pagebreak_bottom,
367 VSpace const & space_top,
368 VSpace const & space_bottom,
370 string labelwidthstring,
373 /* these things are for search and replace */
375 /** sets the selection over the number of characters of string,
378 void SetSelectionOverString(BufferView *, string const & str);
380 /** simple replacing. The font of the first selected character
383 void ReplaceSelectionWithString(BufferView *, string const & str);
385 /// needed to insert the selection
386 void InsertStringA(BufferView *, string const & str);
387 /// needed to insert the selection
388 void InsertStringB(BufferView *, string const & str);
390 /// Find next inset of some specified type.
391 bool GotoNextInset(BufferView *, std::vector<Inset::Code> const & codes,
392 string const & contents = string()) const;
395 /* for the greater insets */
397 /// returns false if inset wasn't found
398 bool UpdateInset(BufferView *, Inset *);
400 void CheckParagraph(BufferView *, LyXParagraph * par,
401 LyXParagraph::size_type pos);
403 int NumberOfCell(LyXParagraph * par,
404 LyXParagraph::size_type pos) const;
406 LyXParagraph * GetParFromID(int id);
409 /// returns false if no undo possible
410 bool TextUndo(BufferView *);
411 /// returns false if no redo possible
412 bool TextRedo(BufferView *);
413 /// used by TextUndo/TextRedo
414 bool TextHandleUndo(BufferView *, Undo * undo);
415 /// makes sure the next operation will be stored
417 /// this is dangerous and for internal use only
419 /// this is dangerous and for internal use only
421 /// the flag used by FinishUndo();
422 mutable bool undo_finished;
426 void SetUndo(Buffer *, Undo::undo_kind kind,
427 LyXParagraph const * before,
428 LyXParagraph const * end) const;
430 void SetRedo(Buffer *, Undo::undo_kind kind,
431 LyXParagraph const * before,
432 LyXParagraph const * end);
434 Undo * CreateUndo(Buffer *, Undo::undo_kind kind,
435 LyXParagraph const * before,
436 LyXParagraph const * end) const;
437 /// for external use in lyx_cb.C
438 void SetCursorParUndo(Buffer *);
440 void RemoveTableRow(LyXCursor & cursor) const;
442 bool IsEmptyTableCell() const;
444 void toggleAppendix(BufferView *);
446 int workWidth(BufferView *) const;
448 void ComputeBidiTables(Buffer const *, Row * row) const;
450 /// Maps positions in the visual string to positions in logical string.
452 LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
453 if (bidi_start == -1)
456 return log2vis_list[pos-bidi_start];
459 /// Maps positions in the logical string to positions in visual string.
461 LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
462 if (bidi_start == -1)
465 return vis2log_list[pos-bidi_start];
469 LyXParagraph::size_type bidi_level(LyXParagraph::size_type pos) const {
470 if (bidi_start == -1)
473 return bidi_levels[pos-bidi_start];
477 bool bidi_InRange(LyXParagraph::size_type pos) const {
478 return bidi_start == -1 ||
479 (bidi_start <= pos && pos <= bidi_end);
485 mutable Row * firstrow;
487 mutable Row * lastrow;
489 /** Copybuffer for copy environment type.
490 Asger has learned that this should be a buffer-property instead
491 Lgb has learned that 'char' is a lousy type for non-characters
493 LyXTextClass::size_type copylayouttype;
495 /** inserts a new row behind the specified row, increments
496 the touched counters */
497 void InsertRow(Row * row, LyXParagraph * par,
498 LyXParagraph::size_type pos) const;
499 /** removes the row and reset the touched counters */
500 void RemoveRow(Row * row) const;
502 /** remove all following rows of the paragraph of the specified row. */
503 void RemoveParagraph(Row * row) const;
505 /** insert the specified paragraph behind the specified row */
506 void InsertParagraph(BufferView *,
507 LyXParagraph * par, Row * row) const;
509 /** appends the implizit specified paragraph behind the specified row,
510 * start at the implizit given position */
511 void AppendParagraph(BufferView *, Row * row) const;
514 void BreakAgain(BufferView *, Row * row) const;
516 void BreakAgainOneRow(BufferView *, Row * row);
517 /// Calculate and set the height of the row
518 void SetHeightOfRow(BufferView *, Row * row_ptr) const;
520 /** this calculates the specified parameters. needed when setting
521 * the cursor and when creating a visible row */
522 void PrepareToPrint(BufferView *, Row * row, float & x,
523 float & fill_separator,
525 float & fill_label_hfill,
526 bool bidi = true) const;
529 void DeleteEmptyParagraphMechanism(BufferView *,
530 LyXCursor const & old_cursor) const;
532 /** Updates all counters starting BEHIND the row. Changed paragraphs
533 * with a dynamic left margin will be rebroken. */
534 void UpdateCounters(BufferView *, Row * row) const;
536 void SetCounter(Buffer const *, LyXParagraph * par) const;
539 * some low level functions
543 int SingleWidth(BufferView *, LyXParagraph * par,
544 LyXParagraph::size_type pos) const;
546 int SingleWidth(BufferView *, LyXParagraph * par,
547 LyXParagraph::size_type pos, char c) const;
549 void draw(BufferView *, Row const * row,
550 LyXParagraph::size_type & pos,
551 int offset, float & x, bool cleared);
553 /// get the next breakpoint in a given paragraph
554 LyXParagraph::size_type NextBreakPoint(BufferView *, Row const * row,
556 /// returns the minimum space a row needs on the screen in pixel
557 int Fill(BufferView *, Row * row, int workwidth) const;
559 /** returns the minimum space a manual label needs on the
561 int LabelFill(BufferView *, Row const * row) const;
564 LyXParagraph::size_type
565 BeginningOfMainBody(Buffer const *, LyXParagraph const * par) const;
567 /** Returns the left beginning of the text.
568 This information cannot be taken from the layouts-objekt, because
569 in LaTeX the beginning of the text fits in some cases
570 (for example sections) exactly the label-width.
572 int LeftMargin(BufferView *, Row const * row) const;
574 int RightMargin(Buffer const *, Row const * row) const;
576 int LabelEnd (BufferView *, Row const * row) const;
578 /** returns the number of separators in the specified row.
579 The separator on the very last column doesnt count
581 int NumberOfSeparators(Buffer const *, Row const * row) const;
583 /** returns the number of hfills in the specified row. The
584 LyX-Hfill is a LaTeX \hfill so that the hfills at the
585 beginning and at the end were ignored. This is {\em MUCH}
586 more usefull than not to ignore!
588 int NumberOfHfills(Buffer const *, Row const * row) const;
590 /// like NumberOfHfills, but only those in the manual label!
591 int NumberOfLabelHfills(Buffer const *, Row const * row) const;
592 /** returns true, if a expansion is needed. Rules are given by
595 bool HfillExpansion(Buffer const *, Row const * row_ptr,
596 LyXParagraph::size_type pos) const;
600 mutable std::vector<LyXParagraph::size_type> log2vis_list;
603 mutable std::vector<LyXParagraph::size_type> vis2log_list;
606 mutable std::vector<LyXParagraph::size_type> bidi_levels;
609 mutable LyXParagraph::size_type bidi_start;
612 mutable LyXParagraph::size_type bidi_end;
615 mutable bool bidi_same_direction;
618 unsigned char TransformChar(unsigned char c, LyXParagraph * par,
619 LyXParagraph::size_type pos) const;
621 /** returns the paragraph position of the last character in the
624 LyXParagraph::size_type RowLast(Row const * row) const;
626 LyXParagraph::size_type RowLastPrintable(Row const * row) const;
631 // special owner functions
633 LyXParagraph * OwnerParagraph() const;
635 LyXParagraph * OwnerParagraph(LyXParagraph *) const;
639 /* returns a pointer to the row near the specified y-coordinate
640 * (relative to the whole text). y is set to the real beginning
643 Row * LyXText::GetRowNearY(int & y) const
645 // If possible we should optimize this method. (Lgb)
646 Row * tmprow = firstrow;
649 while (tmprow->next() && tmpy + tmprow->height() <= y) {
650 tmpy += tmprow->height();
651 tmprow = tmprow->next();
654 y = tmpy; // return the real y