KTextEditor

movingcursor.h
1 /*
2  SPDX-FileCopyrightText: 2010 Christoph Cullmann <[email protected]>
3 
4  Based on code of the SmartCursor/Range by:
5  SPDX-FileCopyrightText: 2003-2005 Hamish Rodda <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #ifndef KTEXTEDITOR_MOVINGCURSOR_H
11 #define KTEXTEDITOR_MOVINGCURSOR_H
12 
13 #include <ktexteditor/cursor.h>
14 #include <ktexteditor/document.h>
15 #include <ktexteditor_export.h>
16 
17 #include <QDebug>
18 
19 namespace KTextEditor
20 {
21 class MovingRange;
22 
23 /**
24  * \class MovingCursor movingcursor.h <KTextEditor/MovingCursor>
25  *
26  * \short A Cursor which is bound to a specific Document, and maintains its position.
27  *
28  * \ingroup kte_group_moving_classes
29  *
30  * A MovingCursor is an extension of the basic Cursor class. It maintains its
31  * position in the document. As a result of this, MovingCursor%s may not be copied, as they need
32  * to maintain a connection to the associated Document.
33  *
34  * Create a new MovingCursor like this:
35  * \code
36  * // Retrieve the MovingInterface
37  * KTextEditor::MovingInterface* moving =
38  * qobject_cast<KTextEditor::MovingInterface*>( yourDocument );
39  *
40  * if ( moving ) {
41  * KTextEditor::MovingCursor* cursor = moving->newMovingCursor();
42  * }
43  * \endcode
44  *
45  * When finished with a MovingCursor, simply delete it.
46  * If the document the cursor belong to is deleted, it will get deleted automatically.
47  *
48  * \sa Cursor, Range, MovingRange and MovingInterface.
49  *
50  * \author Christoph Cullmann <[email protected]>
51  *
52  * \since 4.5
53  */
54 class KTEXTEDITOR_EXPORT MovingCursor
55 {
56  //
57  // sub types
58  //
59 public:
60  /**
61  * Insert behavior of this cursor, should it stay if text is insert at its position
62  * or should it move.
63  */
65  StayOnInsert = 0x0, ///< stay on insert
66  MoveOnInsert = 0x1 ///< move on insert
67  };
68 
69  /**
70  * Wrap behavior for end of line treatement used in move().
71  */
72  enum WrapBehavior {
73  Wrap = 0x0, ///< wrap at end of line
74  NoWrap = 0x1 ///< do not wrap at end of line
75  };
76 
77  //
78  // stuff that needs to be implemented by editor part cursors
79  //
80 public:
81  /**
82  * Set insert behavior.
83  * @param insertBehavior new insert behavior
84  */
85  virtual void setInsertBehavior(InsertBehavior insertBehavior) = 0;
86 
87  /**
88  * Get current insert behavior.
89  * @return current insert behavior
90  */
91  virtual InsertBehavior insertBehavior() const = 0;
92 
93  /**
94  * Gets the document to which this cursor is bound.
95  * \return a pointer to the document
96  */
97  virtual Document *document() const = 0;
98 
99  /**
100  * Get range this cursor belongs to, if any
101  * @return range this pointer is part of, else 0
102  */
103  virtual MovingRange *range() const = 0;
104 
105  /**
106  * Set the current cursor position to \e position.
107  *
108  * \param position new cursor position
109  */
110  virtual void setPosition(const KTextEditor::Cursor &position) = 0;
111 
112  /**
113  * Retrieve the line on which this cursor is situated.
114  * \return line number, where 0 is the first line.
115  */
116  virtual int line() const = 0;
117 
118  /**
119  * Retrieve the column on which this cursor is situated.
120  * \return column number, where 0 is the first column.
121  */
122  virtual int column() const = 0;
123 
124  /**
125  * Destruct the moving cursor.
126  */
127  virtual ~MovingCursor();
128 
129  //
130  // forbidden stuff
131  //
132 protected:
133  /**
134  * For inherited class only.
135  */
136  MovingCursor();
137 
138 private:
139  /**
140  * no copy constructor, don't allow this to be copied.
141  */
142  MovingCursor(const MovingCursor &);
143 
144  /**
145  * no assignment operator, no copying around clever cursors.
146  */
147  MovingCursor &operator=(const MovingCursor &);
148 
149  //
150  // convenience API
151  //
152 public:
153  /**
154  * Returns whether the current position of this cursor is a valid position,
155  * i.e. whether line() >= 0 and column() >= 0.
156  *
157  * \return \e true , if the cursor position is valid, otherwise \e false
158  */
159  inline bool isValid() const
160  {
161  return line() >= 0 && column() >= 0;
162  }
163 
164  /**
165  * Check whether this MovingCursor is located at a valid text position.
166  * A cursor position at (line, column) is valid, if
167  * - line >= 0 and line < document()->lines() holds, and
168  * - column >= 0 and column <= lineLength(column).
169  *
170  * Further, the text position is also invalid if it is inside a Unicode
171  * surrogate (utf-32 character).
172  *
173  * \return \e true, if the cursor is a valid text position, otherwise \e false
174  *
175  * \see Document::isValidTextPosition()
176  */
177  inline bool isValidTextPosition() const
178  {
179  return document()->isValidTextPosition(toCursor());
180  }
181 
182  /**
183  * \overload
184  *
185  * Set the cursor position to \e line and \e column.
186  *
187  * \param line new cursor line
188  * \param column new cursor column
189  */
190  void setPosition(int line, int column);
191 
192  /**
193  * Set the cursor line to \e line.
194  * \param line new cursor line
195  */
196  void setLine(int line);
197 
198  /**
199  * Set the cursor column to \e column.
200  * \param column new cursor column
201  */
202  void setColumn(int column);
203 
204  /**
205  * Determine if this cursor is located at column 0 of a valid text line.
206  *
207  * \return \e true if cursor is a valid text position and column()=0, otherwise \e false.
208  */
209  bool atStartOfLine() const;
210 
211  /**
212  * Determine if this cursor is located at the end of the current line.
213  *
214  * \return \e true if the cursor is situated at the end of the line, otherwise \e false.
215  */
216  bool atEndOfLine() const;
217 
218  /**
219  * Determine if this cursor is located at line 0 and column 0.
220  *
221  * \return \e true if the cursor is at start of the document, otherwise \e false.
222  */
223  bool atStartOfDocument() const;
224 
225  /**
226  * Determine if this cursor is located at the end of the last line in the
227  * document.
228  *
229  * \return \e true if the cursor is at the end of the document, otherwise \e false.
230  */
231  bool atEndOfDocument() const;
232 
233  /**
234  * Moves the cursor to the next line and sets the column to 0. If the cursor
235  * position is already in the last line of the document, the cursor position
236  * remains unchanged and the return value is \e false.
237  *
238  * \return \e true on success, otherwise \e false
239  */
240  bool gotoNextLine();
241 
242  /**
243  * Moves the cursor to the previous line and sets the column to 0. If the
244  * cursor position is already in line 0, the cursor position remains
245  * unchanged and the return value is \e false.
246  *
247  * \return \e true on success, otherwise \e false
248  */
249  bool gotoPreviousLine();
250 
251  /**
252  * Moves the cursor \p chars character forward or backwards. If \e wrapBehavior
253  * equals WrapBehavior::Wrap, the cursor is automatically wrapped to the
254  * next line at the end of a line.
255  *
256  * When moving backwards, the WrapBehavior does not have any effect.
257  * \note If the cursor could not be moved the amount of chars requested,
258  * the cursor is not moved at all!
259  *
260  * \return \e true on success, otherwise \e false
261  */
262  bool move(int chars, WrapBehavior wrapBehavior = Wrap);
263 
264  /**
265  * Convert this clever cursor into a dumb one.
266  * Even if this cursor belongs to a range, the created one not.
267  * @return normal cursor
268  */
269  const Cursor toCursor() const
270  {
271  return Cursor(line(), column());
272  }
273 
274  /**
275  * Convert this clever cursor into a dumb one. Equal to toCursor, allowing to use implicit conversion.
276  * Even if this cursor belongs to a range, the created one not.
277  * @return normal cursor
278  */
279  operator Cursor() const
280  {
281  return Cursor(line(), column());
282  }
283 
284  //
285  // operators for: MovingCursor <-> MovingCursor
286  //
287  /**
288  * Equality operator.
289  *
290  * \note comparison between two invalid cursors is undefined.
291  * comparison between an invalid and a valid cursor will always be \e false.
292  *
293  * \param c1 first cursor to compare
294  * \param c2 second cursor to compare
295  * \return \e true, if c1's and c2's line and column are \e equal.
296  */
297  inline friend bool operator==(const MovingCursor &c1, const MovingCursor &c2)
298  {
299  return c1.line() == c2.line() && c1.column() == c2.column();
300  }
301 
302  /**
303  * Inequality operator.
304  * \param c1 first cursor to compare
305  * \param c2 second cursor to compare
306  * \return \e true, if c1's and c2's line and column are \e not equal.
307  */
308  inline friend bool operator!=(const MovingCursor &c1, const MovingCursor &c2)
309  {
310  return !(c1 == c2);
311  }
312 
313  /**
314  * Greater than operator.
315  * \param c1 first cursor to compare
316  * \param c2 second cursor to compare
317  * \return \e true, if c1's position is greater than c2's position,
318  * otherwise \e false.
319  */
320  inline friend bool operator>(const MovingCursor &c1, const MovingCursor &c2)
321  {
322  return c1.line() > c2.line() || (c1.line() == c2.line() && c1.column() > c2.column());
323  }
324 
325  /**
326  * Greater than or equal to operator.
327  * \param c1 first cursor to compare
328  * \param c2 second cursor to compare
329  * \return \e true, if c1's position is greater than or equal to c2's
330  * position, otherwise \e false.
331  */
332  inline friend bool operator>=(const MovingCursor &c1, const MovingCursor &c2)
333  {
334  return c1.line() > c2.line() || (c1.line() == c2.line() && c1.column() >= c2.column());
335  }
336 
337  /**
338  * Less than operator.
339  * \param c1 first cursor to compare
340  * \param c2 second cursor to compare
341  * \return \e true, if c1's position is greater than or equal to c2's
342  * position, otherwise \e false.
343  */
344  inline friend bool operator<(const MovingCursor &c1, const MovingCursor &c2)
345  {
346  return !(c1 >= c2);
347  }
348 
349  /**
350  * Less than or equal to operator.
351  * \param c1 first cursor to compare
352  * \param c2 second cursor to compare
353  * \return \e true, if c1's position is lesser than or equal to c2's
354  * position, otherwise \e false.
355  */
356  inline friend bool operator<=(const MovingCursor &c1, const MovingCursor &c2)
357  {
358  return !(c1 > c2);
359  }
360 
361  /**
362  * qDebug() stream operator. Writes this cursor to the debug output in a nicely formatted way.
363  * @param s debug stream
364  * @param cursor cursor to print
365  * @return debug stream
366  */
367  inline friend QDebug operator<<(QDebug s, const MovingCursor *cursor)
368  {
369  if (cursor) {
370  s.nospace() << "(" << cursor->line() << ", " << cursor->column() << ")";
371  } else {
372  s.nospace() << "(null cursor)";
373  }
374  return s.space();
375  }
376 
377  /**
378  * qDebug() stream operator. Writes this cursor to the debug output in a nicely formatted way.
379  * @param s debug stream
380  * @param cursor cursor to print
381  * @return debug stream
382  */
383  inline friend QDebug operator<<(QDebug s, const MovingCursor &cursor)
384  {
385  return s << &cursor;
386  }
387 };
388 
389 }
390 
391 #endif
friend bool operator<=(const MovingCursor &c1, const MovingCursor &c2)
Less than or equal to operator.
Definition: movingcursor.h:356
friend bool operator==(const MovingCursor &c1, const MovingCursor &c2)
Equality operator.
Definition: movingcursor.h:297
QDebug & nospace()
bool isValidTextPosition() const
Check whether this MovingCursor is located at a valid text position.
Definition: movingcursor.h:177
virtual int line() const =0
Retrieve the line on which this cursor is situated.
QDebug & space()
InsertBehavior
Insert behavior of this cursor, should it stay if text is insert at its position or should it move.
Definition: movingcursor.h:64
WrapBehavior
Wrap behavior for end of line treatement used in move().
Definition: movingcursor.h:72
The Cursor represents a position in a Document.
Definition: cursor.h:71
bool isValid() const
Returns whether the current position of this cursor is a valid position, i.e.
Definition: movingcursor.h:159
virtual int column() const =0
Retrieve the column on which this cursor is situated.
friend QDebug operator<<(QDebug s, const MovingCursor &cursor)
qDebug() stream operator.
Definition: movingcursor.h:383
friend bool operator!=(const MovingCursor &c1, const MovingCursor &c2)
Inequality operator.
Definition: movingcursor.h:308
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
Definition: katetextblock.h:22
const Cursor toCursor() const
Convert this clever cursor into a dumb one.
Definition: movingcursor.h:269
friend bool operator>=(const MovingCursor &c1, const MovingCursor &c2)
Greater than or equal to operator.
Definition: movingcursor.h:332
A range that is bound to a specific Document, and maintains its position.
Definition: movingrange.h:144
friend QDebug operator<<(QDebug s, const MovingCursor *cursor)
qDebug() stream operator.
Definition: movingcursor.h:367
friend bool operator<(const MovingCursor &c1, const MovingCursor &c2)
Less than operator.
Definition: movingcursor.h:344
friend bool operator>(const MovingCursor &c1, const MovingCursor &c2)
Greater than operator.
Definition: movingcursor.h:320
A Cursor which is bound to a specific Document, and maintains its position.
Definition: movingcursor.h:54
A KParts derived class representing a text document.
Definition: document.h:185
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Mar 26 2023 03:55:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.