2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 1995 Matthias Ettrich
8 * Copyright 1995-2000 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,
86 LyXFont const & font);
87 /// returns a pointer to the very first LyXParagraph
88 LyXParagraph * FirstParagraph() const;
90 /// what you expect when pressing <enter> at cursor position
91 void BreakParagraph(BufferView *, char keep_layout = 0);
93 /** set layout over selection and make a total rebreak of
96 LyXParagraph * SetLayout(BufferView *, LyXCursor & actual_cursor,
97 LyXCursor & selection_start,
98 LyXCursor & selection_end,
99 LyXTextClass::size_type layout);
100 void SetLayout(BufferView *, LyXTextClass::size_type layout);
102 /// used in setlayout
103 void MakeFontEntriesLayoutSpecific(Buffer const *, LyXParagraph * par);
105 /** increment depth over selection and make a total rebreak of those
108 void IncDepth(BufferView *);
110 /** decrement depth over selection and make a total rebreak of those
112 void DecDepth(BufferView *);
114 /** Get the depth at current cursor position
116 int GetDepth() const { return cursor.par()->GetDepth(); }
118 /** set font over selection and make a total rebreak of those
120 toggleall defaults to false.
122 void SetFont(BufferView *, LyXFont const &, bool toggleall = false);
124 /** deletes and inserts again all paragaphs between the cursor
125 and the specified par. The Cursor is needed to set the refreshing
127 This function is needed after SetLayout and SetFont etc.
129 void RedoParagraphs(BufferView *, LyXCursor const & cursor,
130 LyXParagraph const * end_par) const;
132 void RedoParagraph(BufferView *) const;
135 void ToggleFree(BufferView *, LyXFont const &, bool toggleall = false);
137 /** recalculates the heights of all previous rows of the
138 specified paragraph. needed, if the last characters font
141 void RedoHeightOfParagraph(BufferView *, LyXCursor const & cursor);
143 /** forces the redrawing of a paragraph. Needed when manipulating a
146 void RedoDrawingOfParagraph(BufferView *, LyXCursor const & cursor);
148 /** insert a character, moves all the following breaks in the
149 same Paragraph one to the right and make a little rebreak
151 void InsertChar(BufferView *, char c);
153 void InsertInset(BufferView *, Inset * inset);
155 /** Completes the insertion with a full rebreak.
156 Returns true if something was broken. */
157 bool FullRebreak(BufferView *);
161 LyXParagraph::footnote_flag GetFootnoteFlag(int row);
164 Row * need_break_row;
166 mutable int refresh_y;
174 mutable Row * refresh_row;
178 /** wether the screen needs a refresh,
179 starting with refresh_y
181 mutable text_status status;
183 /** returns a pointer to the row near the specified y-coordinate
184 (relative to the whole text). y is set to the real beginning
187 Row * GetRowNearY(int & y) const;
189 /** returns the column near the specified x-coordinate of the row
190 x is set to the real beginning of this column
192 int GetColumnNearX(BufferView *, Row * row,
193 int & x, bool & boundary) const;
195 /** returns a pointer to a specified row. y is set to the beginning
198 Row * GetRow(LyXParagraph * par,
199 LyXParagraph::size_type pos, int & y) const;
201 /** returns the height of a default row, needed for scrollbar
203 int DefaultHeight() const;
206 Later this variable has to be removed. There should be now internal
207 cursor in a text (and thus not in a buffer). By keeping this it is
208 (I think) impossible to have several views with the same buffer, but
209 the cursor placed at different places.
211 Since the LyXText now has been moved from Buffer to BufferView
212 it should not be absolutely needed to move the cursor...
214 mutable LyXCursor cursor;
216 /* the selection cursor */
218 mutable bool selection;
220 mutable bool mark_set;
223 mutable LyXCursor sel_cursor;
225 LyXCursor sel_start_cursor;
227 mutable LyXCursor sel_end_cursor;
228 /// needed for the toggling
229 LyXCursor last_sel_cursor;
231 LyXCursor toggle_cursor;
233 LyXCursor toggle_end_cursor;
235 /// need the selection cursor:
236 void SetSelection(BufferView *);
238 void ClearSelection(BufferView *) const;
240 string const selectionAsString(Buffer const *) const;
242 /// just selects the word the cursor is in
243 void SelectWord(BufferView *);
245 /** 'selects" the next word, where the cursor is not in
246 and returns this word as string. THe cursor will be moved
247 to the beginning of this word.
248 With SelectSelectedWord can this be highlighted really
250 string const SelectNextWord(BufferView *, float & value) const;
252 void SelectSelectedWord(BufferView *);
254 void SetCursor(BufferView *, LyXParagraph * par,
255 LyXParagraph::size_type pos,
257 bool boundary = false) const;
259 void SetCursor(BufferView *, LyXCursor &, LyXParagraph * par,
260 LyXParagraph::size_type pos,
261 bool boundary = false) const;
263 void SetCursorIntern(BufferView *, LyXParagraph * par,
264 LyXParagraph::size_type pos,
266 bool boundary = false) const;
268 void SetCurrentFont(BufferView *) const;
271 bool IsBoundary(Buffer const *, LyXParagraph * par,
272 LyXParagraph::size_type pos) const;
274 bool IsBoundary(Buffer const *, LyXParagraph * par,
275 LyXParagraph::size_type pos,
276 LyXFont const & font) const;
279 void SetCursorFromCoordinates(BufferView *, int x, int y) const;
281 void SetCursorFromCoordinates(BufferView *, LyXCursor &,
284 void CursorUp(BufferView *) const;
286 void CursorDown(BufferView *) const;
288 void CursorLeft(BufferView *, bool internal = true) const;
290 void CursorRight(BufferView *, bool internal = true) const;
292 void CursorLeftOneWord(BufferView *) const;
294 void CursorRightOneWord(BufferView *) const;
296 void CursorUpParagraph(BufferView *) const;
298 void CursorDownParagraph(BufferView *) const;
300 void CursorHome(BufferView *) const;
302 void CursorEnd(BufferView *) const;
304 void CursorTab(BufferView *) const;
306 void CursorTop(BufferView *) const;
308 void CursorBottom(BufferView *) const;
310 void Delete(BufferView *);
312 void Backspace(BufferView *);
314 void DeleteWordForward(BufferView *);
316 void DeleteWordBackward(BufferView *);
318 void DeleteLineForward(BufferView *);
320 bool SelectWordWhenUnderCursor(BufferView *);
326 text_capitalization = 1,
330 /// Change the case of the word at cursor position.
331 void ChangeWordCase(BufferView *, TextCase action);
333 /** returns a printed row in a pixmap. The y value is needed to
334 decide, wether it is selected text or not. This is a strange
337 void GetVisibleRow(BufferView *, int y_offset, int x_offset,
338 Row * row_ptr, int y, bool cleared=false);
343 void ToggleFootnote(BufferView *);
345 void OpenStuff(BufferView *);
347 void OpenFootnotes();
349 void OpenFootnote(BufferView *);
351 void CloseFootnotes();
353 void CloseFootnote(BufferView *);
355 /** turn the selection into a new environment. If there is no
356 selection, create an empty environment
358 void InsertFootnoteEnvironment(BufferView *,
359 LyXParagraph::footnote_kind kind);
361 void MeltFootnoteEnvironment(BufferView *);
364 void CutSelection(BufferView *, bool = true);
366 void CopySelection(BufferView *);
368 void PasteSelection(BufferView *);
370 void copyEnvironmentType();
372 void pasteEnvironmentType(BufferView *);
374 void InsertFootnote();
376 void InsertMarginpar();
380 void InsertTabular();
382 /** the DTP switches for paragraphs. LyX will store the top settings
383 always in the first physical paragraph, the bottom settings in the
384 last. When a paragraph is broken, the top settings rest, the bottom
385 settings are given to the new one. So I can make shure, they do not
386 duplicate themself (and you cannnot make dirty things with them! )
388 void SetParagraph(BufferView *,
389 bool line_top, bool line_bottom,
390 bool pagebreak_top, bool pagebreak_bottom,
391 VSpace const & space_top,
392 VSpace const & space_bottom,
394 string labelwidthstring,
398 void SetParagraphExtraOpt(BufferView *, int type,
399 string const & width,
400 string const & widthp,
401 int alignment, bool hfill,
402 bool start_minipage);
404 /* these things are for search and replace */
406 /** sets the selection over the number of characters of string,
409 void SetSelectionOverString(BufferView *, string const & str);
411 /** simple replacing. The font of the first selected character
414 void ReplaceSelectionWithString(BufferView *, string const & str);
416 /// needed to insert the selection
417 void InsertStringA(BufferView *, string const & str);
418 /// needed to insert the selection
419 void InsertStringB(BufferView *, string const & str);
421 /// Find next inset of some specified type.
422 bool GotoNextInset(BufferView *, std::vector<Inset::Code> const & codes,
423 string const & contents = string()) const;
426 /* for the greater insets */
428 /// returns false if inset wasn't found
429 bool UpdateInset(BufferView *, Inset *);
431 void CheckParagraph(BufferView *, LyXParagraph * par,
432 LyXParagraph::size_type pos);
434 int NumberOfCell(LyXParagraph * par,
435 LyXParagraph::size_type pos) const;
437 LyXParagraph * GetParFromID(int id);
440 /// returns false if no undo possible
441 bool TextUndo(BufferView *);
442 /// returns false if no redo possible
443 bool TextRedo(BufferView *);
444 /// used by TextUndo/TextRedo
445 bool TextHandleUndo(BufferView *, Undo * undo);
446 /// makes sure the next operation will be stored
448 /// this is dangerous and for internal use only
450 /// this is dangerous and for internal use only
452 /// the flag used by FinishUndo();
453 mutable bool undo_finished;
457 void SetUndo(Buffer *, Undo::undo_kind kind,
458 LyXParagraph const * before,
459 LyXParagraph const * end) const;
461 void SetRedo(Buffer *, Undo::undo_kind kind,
462 LyXParagraph const * before,
463 LyXParagraph const * end);
465 Undo * CreateUndo(Buffer *, Undo::undo_kind kind,
466 LyXParagraph const * before,
467 LyXParagraph const * end) const;
468 /// for external use in lyx_cb.C
469 void SetCursorParUndo(Buffer *);
471 void RemoveTableRow(LyXCursor & cursor) const;
473 bool IsEmptyTableCell() const;
475 void toggleAppendix(BufferView *);
477 int workWidth(BufferView *) const;
479 void ComputeBidiTables(Buffer const *, Row * row) const;
481 /// Maps positions in the visual string to positions in logical string.
483 LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
484 if (bidi_start == -1)
487 return log2vis_list[pos-bidi_start];
490 /// Maps positions in the logical string to positions in visual string.
492 LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
493 if (bidi_start == -1)
496 return vis2log_list[pos-bidi_start];
500 LyXParagraph::size_type bidi_level(LyXParagraph::size_type pos) const {
501 if (bidi_start == -1)
504 return bidi_levels[pos-bidi_start];
508 bool bidi_InRange(LyXParagraph::size_type pos) const {
509 return bidi_start == -1 ||
510 (bidi_start <= pos && pos <= bidi_end);
516 mutable Row * firstrow;
518 mutable Row * lastrow;
520 /** Copybuffer for copy environment type.
521 Asger has learned that this should be a buffer-property instead
522 Lgb has learned that 'char' is a lousy type for non-characters
524 LyXTextClass::size_type copylayouttype;
526 /** inserts a new row behind the specified row, increments
527 the touched counters */
528 void InsertRow(Row * row, LyXParagraph * par,
529 LyXParagraph::size_type pos) const;
530 /** removes the row and reset the touched counters */
531 void RemoveRow(Row * row) const;
533 /** remove all following rows of the paragraph of the specified row. */
534 void RemoveParagraph(Row * row) const;
536 /** insert the specified paragraph behind the specified row */
537 void InsertParagraph(BufferView *,
538 LyXParagraph * par, Row * row) const;
540 /** appends the implizit specified paragraph behind the specified row,
541 * start at the implizit given position */
542 void AppendParagraph(BufferView *, Row * row) const;
545 void BreakAgain(BufferView *, Row * row) const;
547 void BreakAgainOneRow(BufferView *, Row * row);
548 /// Calculate and set the height of the row
549 void SetHeightOfRow(BufferView *, Row * row_ptr) const;
551 /** this calculates the specified parameters. needed when setting
552 * the cursor and when creating a visible row */
553 void PrepareToPrint(BufferView *, Row * row, float & x,
554 float & fill_separator,
556 float & fill_label_hfill,
557 bool bidi = true) const;
560 void DeleteEmptyParagraphMechanism(BufferView *,
561 LyXCursor const & old_cursor) const;
563 /** Updates all counters starting BEHIND the row. Changed paragraphs
564 * with a dynamic left margin will be rebroken. */
565 void UpdateCounters(BufferView *, Row * row) const;
567 void SetCounter(Buffer const *, LyXParagraph * par) const;
570 * some low level functions
574 int SingleWidth(BufferView *, LyXParagraph * par,
575 LyXParagraph::size_type pos) const;
577 int SingleWidth(BufferView *, LyXParagraph * par,
578 LyXParagraph::size_type pos, char c) const;
580 void draw(BufferView *, Row const * row,
581 LyXParagraph::size_type & pos,
582 int offset, float & x, bool cleared);
584 /// get the next breakpoint in a given paragraph
585 LyXParagraph::size_type NextBreakPoint(BufferView *, Row const * row,
587 /// returns the minimum space a row needs on the screen in pixel
588 int Fill(BufferView *, Row * row, int workwidth) const;
590 /** returns the minimum space a manual label needs on the
592 int LabelFill(BufferView *, Row const * row) const;
595 LyXParagraph::size_type
596 BeginningOfMainBody(Buffer const *, LyXParagraph const * par) const;
598 /** Returns the left beginning of the text.
599 This information cannot be taken from the layouts-objekt, because
600 in LaTeX the beginning of the text fits in some cases
601 (for example sections) exactly the label-width.
603 int LeftMargin(BufferView *, Row const * row) const;
605 int RightMargin(Buffer const *, Row const * row) const;
607 int LabelEnd (BufferView *, Row const * row) const;
609 /** returns the number of separators in the specified row.
610 The separator on the very last column doesnt count
612 int NumberOfSeparators(Buffer const *, Row const * row) const;
614 /** returns the number of hfills in the specified row. The
615 LyX-Hfill is a LaTeX \hfill so that the hfills at the
616 beginning and at the end were ignored. This is {\em MUCH}
617 more usefull than not to ignore!
619 int NumberOfHfills(Buffer const *, Row const * row) const;
621 /// like NumberOfHfills, but only those in the manual label!
622 int NumberOfLabelHfills(Buffer const *, Row const * row) const;
623 /** returns true, if a expansion is needed. Rules are given by
626 bool HfillExpansion(Buffer const *, Row const * row_ptr,
627 LyXParagraph::size_type pos) const;
631 mutable std::vector<LyXParagraph::size_type> log2vis_list;
634 mutable std::vector<LyXParagraph::size_type> vis2log_list;
637 mutable std::vector<LyXParagraph::size_type> bidi_levels;
640 mutable LyXParagraph::size_type bidi_start;
643 mutable LyXParagraph::size_type bidi_end;
646 mutable bool bidi_same_direction;
649 unsigned char TransformChar(unsigned char c, LyXParagraph * par,
650 LyXParagraph::size_type pos) const;
652 /** returns the paragraph position of the last character in the
655 LyXParagraph::size_type RowLast(Row const * row) const;
657 LyXParagraph::size_type RowLastPrintable(Row const * row) const;
662 // special owner functions
664 LyXParagraph * OwnerParagraph() const;
666 LyXParagraph * OwnerParagraph(LyXParagraph *) const;