2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright 1995 Matthias Ettrich
8 * Copyright 1995-1999 The LyX Team.
10 * ====================================================== */
22 #include "lyxcursor.h"
23 #include "lyxparagraph.h"
30 This class holds the mapping between buffer paragraphs and screen rows.
43 NEED_VERY_LITTLE_REFRESH
46 /// points to Buffer.params
47 BufferParams * parameters;
51 mutable int number_of_rows;
54 /// the current font settings
55 mutable LyXFont current_font;
57 mutable LyXFont real_current_font;
60 LyXText(int paperwidth, Buffer *);
66 LyXFont GetFont(LyXParagraph * par,
67 LyXParagraph::size_type pos) const;
69 void SetCharFont(LyXParagraph * par,
70 LyXParagraph::size_type pos,
71 LyXFont const & font);
72 /// returns a pointer to the very first LyXParagraph
73 LyXParagraph * FirstParagraph() const;
75 /// what you expect when pressing <enter> at cursor position
76 void BreakParagraph(char keep_layout = 0);
78 /** set layout over selection and make a total rebreak of
81 void SetLayout(char layout);
84 void MakeFontEntriesLayoutSpecific(LyXParagraph * par);
86 /** increment depth over selection and make a total rebreak of those
91 /** decrement depth over selection and make a total rebreak of those
95 /** Get the depth at current cursor position
97 int GetDepth() const { return cursor.par->GetDepth(); }
99 /** set font over selection and make a total rebreak of those
101 toggleall defaults to false.
103 void SetFont(LyXFont const & font, bool toggleall = false);
105 /** deletes and inserts again all paragaphs between the cursor
106 and the specified par. The Cursor is needed to set the refreshing
108 This function is needed after SetLayout and SetFont etc.
110 void RedoParagraphs(LyXCursor const & cursor,
111 LyXParagraph const * end_par) const;
113 void RedoParagraph() const;
116 void ToggleFree(LyXFont const & font, bool toggleall = false);
118 /** recalculates the heights of all previous rows of the
119 specified paragraph. needed, if the last characters font
122 void RedoHeightOfParagraph(LyXCursor const & cursor);
124 /** forces the redrawing of a paragraph. Needed when manipulating a
127 void RedoDrawingOfParagraph(LyXCursor const & cursor);
129 /** insert a character, moves all the following breaks in the
130 same Paragraph one to the right and make a little rebreak
132 void InsertChar(char c);
134 void InsertInset(Inset * inset);
136 /// completes the insertion with a full rebreak
140 LyXParagraph::footnote_flag GetFootnoteFlag(int row);
142 Row * need_break_row;
144 mutable long refresh_y;
152 mutable Row * refresh_row;
156 /** wether the screen needs a refresh,
157 starting with refresh_y
159 mutable text_status status;
161 /** returns a pointer to the row near the specified y-coordinate
162 (relative to the whole text). y is set to the real beginning
165 Row * GetRowNearY(long & y) const;
167 /** returns the column near the specified x-coordinate of the row
168 x is set to the real beginning of this column
170 int GetColumnNearX(Row * row, int & x) const;
172 /** returns a pointer to a specified row. y is set to the beginning
175 Row * GetRow(LyXParagraph * par,
176 LyXParagraph::size_type pos, long & y) const;
177 /** returns the height of a default row, needed for scrollbar
179 int DefaultHeight() const;
182 Later this variable has to be removed. There should be now internal
183 cursor in a text (and thus not in a buffer). By keeping this it is
184 (I think) impossible to have several views with the same buffer, but
185 the cursor placed at different places.
187 Since the LyXText now has been moved from Buffer to BufferView
188 it should not be absolutely needed to move the cursor...
190 mutable LyXCursor cursor;
192 /* the selection cursor */
194 mutable bool selection;
196 mutable bool mark_set;
199 mutable LyXCursor sel_cursor;
201 LyXCursor sel_start_cursor;
203 mutable LyXCursor sel_end_cursor;
204 /// needed for the toggling
205 LyXCursor last_sel_cursor;
207 LyXCursor toggle_cursor;
209 LyXCursor toggle_end_cursor;
211 /// need the selection cursor:
214 void ClearSelection() const;
216 /// just selects the word the cursor is in
219 /** 'selects" the next word, where the cursor is not in
220 and returns this word as string. THe cursor will be moved
221 to the beginning of this word.
222 With SelectSelectedWord can this be highlighted really
224 char * SelectNextWord(float & value);
226 void SelectSelectedWord();
228 void SetCursor(LyXParagraph * par,
229 LyXParagraph::size_type pos) const;
231 void SetCursorIntern(LyXParagraph * par,
232 LyXParagraph::size_type pos) const;
234 void SetCursorFromCoordinates(int x, long y) const;
236 void CursorUp() const;
238 void CursorDown() const;
240 void CursorLeft() const;
242 void CursorRight() const;
244 void CursorLeftOneWord() const;
246 void CursorRightOneWord() const;
248 void CursorUpParagraph() const;
250 void CursorDownParagraph() const;
252 void CursorHome() const;
254 void CursorEnd() const;
256 void CursorTab() const;
258 void CursorTop() const;
260 void CursorBottom() const;
266 void DeleteWordForward();
268 void DeleteWordBackward();
270 void DeleteLineForward();
272 int SelectWordWhenUnderCursor();
276 text_capitalization = 1,
279 /// Change the case of the word at cursor position.
280 void ChangeWordCase(TextCase action);
282 /** returns a printed row in a pixmap. The y value is needed to
283 decide, wether it is selected text or not. This is a strange
286 void GetVisibleRow(LyXScreen & scr, int offset,
287 Row * row_ptr, long y);
291 void ToggleFootnote();
295 void OpenFootnotes();
299 void CloseFootnotes();
301 void CloseFootnote();
303 /** turn the selection into a new environment. If there is no
304 selection, create an empty environment
306 void InsertFootnoteEnvironment(LyXParagraph::footnote_kind kind);
308 void MeltFootnoteEnvironment();
310 void CutSelection(bool = true);
312 void CopySelection();
314 void PasteSelection();
316 void copyEnvironmentType();
318 void pasteEnvironmentType();
320 void InsertFootnote();
322 void InsertMarginpar();
326 void InsertTabular();
328 /** the DTP switches for paragraphs. LyX will store the top settings
329 always in the first physical paragraph, the bottom settings in the
330 last. When a paragraph is broken, the top settings rest, the bottom
331 settings are given to the new one. So I can make shure, they do not
332 duplicate themself (and you cannnot make dirty things with them! )
334 void SetParagraph(bool line_top, bool line_bottom,
335 bool pagebreak_top, bool pagebreak_bottom,
336 VSpace const & space_top,
337 VSpace const & space_bottom,
339 string labelwidthstring,
341 void SetParagraphExtraOpt(int type,
344 int alignment, bool hfill,
345 bool start_minipage);
347 /* these things are for search and replace */
349 /** returns true if the specified string is at the specified
352 bool IsStringInText(LyXParagraph * par,
353 LyXParagraph::size_type pos,
354 char const * str) const;
355 /** sets the selection over the number of characters of string,
358 void SetSelectionOverString(char const * str);
360 /** simple replacing. The font of the first selected character
363 void ReplaceSelectionWithString(char const * str);
365 /** if the string can be found: return true and set the cursor to
367 bool SearchForward(char const * str) const;
368 bool SearchBackward(char const * str) const;
370 /// needed to insert the selection
371 void InsertStringA(LyXParagraph::TextContainer const & text);
372 /// needed to insert the selection
373 void InsertStringB(LyXParagraph::TextContainer const & text);
374 /// needed to insert the selection
375 void InsertStringA(char const * str);
376 /// needed to insert the selection
377 void InsertStringB(char const * str);
379 /// usefull when texing from within LyX
380 bool GotoNextError() const;
382 /// just another feature :)
383 bool GotoNextNote() const;
385 /** needed to switch between different classes this works
386 for a list of paragraphs beginning with the specified par
387 return value is the number of wrong conversions
389 int SwitchLayoutsBetweenClasses(char class1, char class2,
392 /* for the greater insets */
394 /// returns 0 if inset wasn't found
395 int UpdateInset(Inset * inset);
397 void CheckParagraph(LyXParagraph * par,
398 LyXParagraph::size_type pos);
400 int NumberOfCell(LyXParagraph * par,
401 LyXParagraph::size_type pos) const;
402 /* table stuff -- begin*/
404 /** all table features of the text-class are put together in
405 this function. Possible values of feature are defined in table.h
407 void TableFeatures(int feature, string const & val) const;
409 void TableFeatures(int feature) const;
411 /** pos points at the beginning of the next cell (if there is one)
413 int WidthOfCell(LyXParagraph * par,
414 LyXParagraph::size_type & pos) const;
416 void CheckParagraphInTable(LyXParagraph * par,
417 LyXParagraph::size_type pos);
419 void InsertCharInTable(char c);
421 void BackspaceInTable();
423 bool HitInTable(Row * row, int x) const;
425 bool MouseHitInTable(int x, long y) const;
426 /* table stuff -- end*/
428 LyXParagraph * GetParFromID(int id);
431 /// returns false if no undo possible
433 /// returns false if no redo possible
435 /// used by TextUndo/TextRedo
436 bool TextHandleUndo(Undo * undo);
437 /// makes sure the next operation will be stored
439 /// this is dangerous and for internal use only
441 /// this is dangerous and for internal use only
443 /// the flag used by FinishUndo();
444 mutable bool undo_finished;
448 void SetUndo(Undo::undo_kind kind,
449 LyXParagraph const * before,
450 LyXParagraph const * end) const;
452 void SetRedo(Undo::undo_kind kind,
453 LyXParagraph const * before,
454 LyXParagraph const * end);
456 Undo * CreateUndo(Undo::undo_kind kind,
457 LyXParagraph const * before,
458 LyXParagraph const * end) const;
459 /// for external use in lyx_cb.C
460 void SetCursorParUndo();
462 void CursorLeftIntern() const;
464 void CursorRightIntern() const;
466 void RemoveTableRow(LyXCursor * cursor) const;
469 bool IsEmptyTableRow(LyXCursor const & cursor) const;
472 bool IsEmptyTableCell() const;
474 void toggleAppendix();
476 unsigned short paperWidth() const { return paperwidth; }
478 /// width of the paper
479 unsigned short paperwidth;
482 mutable Row * firstrow;
484 mutable Row * lastrow;
486 /** Copybuffer for copy environment type
487 Asger has learned that this should be a buffer-property instead
488 Lgb has learned that 'char' is a lousy type for non-characters
492 /// the currentrow is needed to access rows faster*/
493 mutable Row * currentrow; // pointer to the current row
494 /// position in the text
495 mutable long currentrow_y;
497 /** inserts a new row behind the specified row, increments
498 * the touched counters */
499 void InsertRow(Row * row, LyXParagraph * par,
500 LyXParagraph::size_type pos) const;
501 /** removes the row and reset the touched counters */
502 void RemoveRow(Row * row) const;
504 /** remove all following rows of the paragraph of the specified row. */
505 void RemoveParagraph(Row * row) const;
507 /** insert the specified paragraph behind the specified row */
508 void InsertParagraph(LyXParagraph * par, Row * row) const;
510 /** appends the implizit specified paragraph behind the specified row,
511 * start at the implizit given position */
512 void AppendParagraph(Row * row) const;
515 void BreakAgain(Row * row) const;
517 void BreakAgainOneRow(Row * row);
518 /// Calculate and set the height of the row
519 void SetHeightOfRow(Row * row_ptr) const;
521 /** this calculates the specified parameters. needed when setting
522 * the cursor and when creating a visible row */
523 void PrepareToPrint(Row * row, float & x,
524 float & fill_separator,
526 float & fill_label_hfill) const;
528 void DeleteEmptyParagraphMechanism(LyXCursor const & old_cursor) const;
530 /** Updates all counters starting BEHIND the row. Changed paragraphs
531 * with a dynamic left margin will be rebroken. */
532 void UpdateCounters(Row * row) const;
534 void SetCounter(LyXParagraph * par) const;
537 * some low level functions
541 int SingleWidth(LyXParagraph * par,
542 LyXParagraph::size_type pos) const;
544 int SingleWidth(LyXParagraph * par,
545 LyXParagraph::size_type pos, char c) const;
547 void Draw(Row const * row, LyXParagraph::size_type & pos,
549 int offset, float & x);
550 /// get the next breakpoint in a given paragraph
551 LyXParagraph::size_type NextBreakPoint(Row const * row,
553 /// returns the minimum space a row needs on the screen in pixel
554 int Fill(Row const * row, int paperwidth) const;
556 /** returns the minimum space a manual label needs on the
558 int LabelFill(Row const * row) const;
561 LyXParagraph::size_type BeginningOfMainBody(LyXParagraph * par) const;
562 /** Returns the left beginning of the text.
563 This information cannot be taken from the layouts-objekt, because
564 in LaTeX the beginning of the text fits in some cases
565 (for example sections) exactly the label-width.
567 int LeftMargin(Row const * row) const;
569 int RightMargin(Row const * row) const;
571 int LabelEnd (Row const * row) const;
573 /** returns the number of separators in the specified row.
574 The separator on the very last column doesnt count
576 int NumberOfSeparators(Row const * row) const;
578 /** returns the number of hfills in the specified row. The
579 LyX-Hfill is a LaTeX \hfill so that the hfills at the
580 beginning and at the end were ignored. This is {\em MUCH}
581 more usefull than not to ignore!
583 int NumberOfHfills(Row const * row) const;
585 /// like NumberOfHfills, but only those in the manual label!
586 int NumberOfLabelHfills(Row const * row) const;
588 /** returns true, if a expansion is needed. Rules are given by
591 bool HfillExpansion(Row const * row_ptr,
592 LyXParagraph::size_type pos) const;
593 /** returns the paragraph position of the last character in the
596 LyXParagraph::size_type RowLast(Row const * row) const;