1 | /* |
2 | SPDX-FileCopyrightText: 2001-2014 Christoph Cullmann <cullmann@kde.org> |
3 | SPDX-FileCopyrightText: 2005-2014 Dominik Haumann <dhaumann@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef KTEXTEDITOR_DOCUMENT_H |
9 | #define KTEXTEDITOR_DOCUMENT_H |
10 | |
11 | #include <ktexteditor_export.h> |
12 | |
13 | #include <ktexteditor/cursor.h> |
14 | #include <ktexteditor/movingcursor.h> |
15 | #include <ktexteditor/movingrange.h> |
16 | #include <ktexteditor/range.h> |
17 | |
18 | // our main baseclass of the KTextEditor::Document |
19 | #include <KParts/ReadWritePart> |
20 | #include <KSyntaxHighlighting/Theme> |
21 | |
22 | // the list of views |
23 | #include <QList> |
24 | |
25 | class KConfigGroup; |
26 | |
27 | namespace KTextEditor |
28 | { |
29 | class DocumentPrivate; |
30 | class EditingTransactionPrivate; |
31 | class MainWindow; |
32 | class Message; |
33 | class View; |
34 | class AnnotationModel; |
35 | |
36 | /** |
37 | * \brief Search flags for use with searchText. |
38 | * |
39 | * Modifies the behavior of searchText. |
40 | * By default it is searched for a case-sensitive plaintext pattern, |
41 | * without processing of escape sequences, with "whole words" off, |
42 | * in forward direction, within a non-block-mode text range. |
43 | * |
44 | * \see SearchOptions |
45 | * \author Sebastian Pipping \<webmaster@hartwork.org\> |
46 | */ |
47 | enum SearchOption { |
48 | Default = 0, ///< Default settings |
49 | |
50 | // modes |
51 | Regex = 1 << 1, ///< Treats the pattern as a regular expression |
52 | |
53 | // options for all modes |
54 | CaseInsensitive = 1 << 4, ///< Ignores cases, e.g. "a" matches "A" |
55 | Backwards = 1 << 5, ///< Searches in backward direction |
56 | |
57 | // options for plaintext |
58 | EscapeSequences = 1 << 10, ///< Plaintext mode: Processes escape sequences |
59 | WholeWords = 1 << 11, ///< Plaintext mode: Whole words only, e.g. @em not "amp" in "example" |
60 | |
61 | MaxSearchOption = 1 << 31 ///< Placeholder for binary compatibility |
62 | }; |
63 | |
64 | /// Stores a combination of #SearchOption values. |
65 | Q_DECLARE_FLAGS(SearchOptions, SearchOption) |
66 | Q_DECLARE_OPERATORS_FOR_FLAGS(SearchOptions) |
67 | |
68 | /** |
69 | * \class Mark |
70 | * \see doc_marktext |
71 | */ |
72 | class Mark |
73 | { |
74 | public: |
75 | /** The line that contains the mark. */ |
76 | int line; |
77 | |
78 | /** The mark types in the line, combined with logical OR. */ |
79 | uint type; |
80 | }; |
81 | |
82 | /** |
83 | * \class Document document.h <KTextEditor/Document> |
84 | * |
85 | * \brief A KParts derived class representing a text document. |
86 | * |
87 | * Topics: |
88 | * - \ref doc_intro |
89 | * - \ref doc_manipulation |
90 | * - \ref doc_views |
91 | * - \ref doc_readwrite |
92 | * - \ref doc_notifications |
93 | * - \ref doc_recovery |
94 | * - \ref doc_movinginterface |
95 | * - \ref doc_config |
96 | * - \ref doc_modiface |
97 | * - \ref doc_marktext |
98 | * - \ref doc_annoiface |
99 | * |
100 | * \section doc_intro Introduction |
101 | * |
102 | * The Document class represents a pure text document providing methods to |
103 | * modify the content and create views. A document can have any number |
104 | * of views, each view representing the same content, i.e. all views are |
105 | * synchronized. Support for text selection is handled by a View and text |
106 | * format attributes by the Attribute class. |
107 | * |
108 | * To load a document call KParts::ReadOnlyPart::openUrl(). |
109 | * To reload a document from a file call documentReload(), to save the |
110 | * document call documentSave() or documentSaveAs(). Whenever the modified |
111 | * state of the document changes the signal modifiedChanged() is emitted. |
112 | * Check the modified state with KParts::ReadWritePart::isModified(). |
113 | * Further signals are documentUrlChanged(). The encoding can be specified |
114 | * with setEncoding(), however this will only take effect on file reload and |
115 | * file save. |
116 | * |
117 | * \section doc_manipulation Text Manipulation |
118 | * |
119 | * Get the whole content with text() and set new content with setText(). |
120 | * Call insertText() or insertLine() to insert new text or removeText() |
121 | * and removeLine() to remove content. Whenever the document's content |
122 | * changed the signal textChanged() is emitted. Additional signals are |
123 | * textInserted() and textRemoved(). Note, that the first line in the |
124 | * document is line 0. |
125 | * |
126 | * A Document provides full undo/redo history. |
127 | * Text manipulation actions can be grouped together to one undo/redo action by |
128 | * using an the class EditingTransaction. You can stack multiple EditingTransaction%s. |
129 | * Internally, the Document has a reference counter. If this reference counter |
130 | * is increased the first time (by creating an instance of EditingTransaction), |
131 | * the signal editingStarted() is emitted. Only when the internal reference counter |
132 | * reaches zero again, the signal editingFinished() and optionally the signal |
133 | * textChanged() are emitted. Whether an editing transaction is currently active |
134 | * can be checked by calling isEditingTransactionRunning(). |
135 | * |
136 | * @note The signal editingFinished() is always emitted when the last instance |
137 | * of EditingTransaction is destroyed. Contrary, the signal textChanged() |
138 | * is emitted only if text changed. Hence, textChanged() is more accurate |
139 | * with respect to changes in the Document. |
140 | * |
141 | * Every text editing transaction is also available through the signals |
142 | * lineWrapped(), lineUnwrapped(), textInserted() and textRemoved(). |
143 | * However, these signals should be used with care. Please be aware of the |
144 | * following warning: |
145 | * |
146 | * @warning Never change the Document's contents when edit actions are active, |
147 | * i.e. in between of (foreign) editing transactions. In case you |
148 | * violate this, the currently active edit action may perform edits |
149 | * that lead to undefined behavior. |
150 | * |
151 | * \section doc_views Document Views |
152 | * |
153 | * A View displays the document's content. As already mentioned, a document |
154 | * can have any number of views, all synchronized. Get a list of all views |
155 | * with views(). Create a new view with createView(). Every time a new view |
156 | * is created the signal viewCreated() is emitted. |
157 | * |
158 | * \section doc_readwrite Read-Only Mode |
159 | * |
160 | * A Document may be in read-only mode, for instance due to missing file |
161 | * permissions. The read-only mode can be checked with isReadWrite(). Further, |
162 | * the signal readWriteChanged() is emitted whenever the state changes either |
163 | * to read-only mode or to read/write mode. The read-only mode can be controlled |
164 | * with setReadWrite(). |
165 | * |
166 | * \section doc_notifications Notifications in Documents and Views |
167 | * |
168 | * A Document has the ability to show a Message to the user in a View. |
169 | * The Message then is shown either the specified View if Message::setView() |
170 | * was called, or in all View%s of the Document. |
171 | * |
172 | * To post a message just create a new Message and send it with postMessage(). |
173 | * Further information is available in the API documentation of Message. |
174 | * |
175 | * @see Message |
176 | * |
177 | * \section doc_recovery Crash Recovery for Documents |
178 | * |
179 | * When the system or the application using the editor component crashed |
180 | * with unsaved changes in the Document, the View notifies the user about |
181 | * the lost data and asks, whether the data should be recovered. |
182 | * |
183 | * This Document gives you control over the data recovery process. Use |
184 | * isDataRecoveryAvailable() to check for lost data. If you do not want the |
185 | * editor component to handle the data recovery process automatically, you can |
186 | * either trigger the data recovery by calling recoverData() or discard it |
187 | * through discardDataRecovery(). |
188 | * |
189 | * \section doc_movinginterface Document Moving Interface |
190 | * |
191 | * Document Moving Interface allows you to create MovingRange and MovingCursor. A |
192 | * Moving Range or Cursor is a special type of range/cursor because it automatically |
193 | * moves on text insertion or removal. Additionally, one can use the moving ranges to |
194 | * change the color of a particular word or give it a different attribute such as bold. |
195 | * Use newMovingCursor() to create a new moving cursor and newMovingRange() to create |
196 | * a new moving range. |
197 | * |
198 | * Upon destruction or reload, a document will remove all its moving ranges. You can |
199 | * connect to aboutToDeleteMovingInterfaceContent() and aboutToInvalidateMovingInterfaceContent() |
200 | * signals to know when that is going to happen and update the cached ranges accordingly. |
201 | * |
202 | * \section doc_config Document Config |
203 | * Config provides methods to access and modify the low level config information for a given |
204 | * Document. |
205 | * KTextEditor::Document has support for the following config keys: |
206 | * - backup-on-save-local [bool], enable/disable backup when saving local files |
207 | * - backup-on-save-remote [bool], enable/disable backup when saving remote files |
208 | * - backup-on-save-suffix [string], set the suffix for file backups, e.g. "~" |
209 | * - backup-on-save-prefix [string], set the prefix for file backups, e.g. "." |
210 | * - replace-tabs [bool], whether to replace tabs |
211 | * - indent-pasted-text [bool], whether to indent pasted text |
212 | * - tab-width [int], read/set the width for tabs |
213 | * - indent-width [int], read/set the indentation width |
214 | * - on-the-fly-spellcheck [bool], enable/disable on the fly spellcheck |
215 | * |
216 | * \section doc_modiface External modification extension interface for the Document. |
217 | * |
218 | * The class ModificationInterface provides methods to handle modifications |
219 | * of all opened files caused by external programs. Whenever the |
220 | * modified-on-disk state changes the signal modifiedOnDisk() is emitted |
221 | * along with a ModifiedOnDiskReason. Set the state by calling |
222 | * setModifiedOnDisk(). Whether the Editor should show warning dialogs to |
223 | * inform the user about external modified files can be controlled with |
224 | * setModifiedOnDiskWarning(). The slot modifiedOnDisk() is called to ask |
225 | * the user what to do whenever a file was modified. |
226 | * |
227 | * \section doc_marktext |
228 | * |
229 | * The Mark Interface provides methods to enable and disable marks in a |
230 | * Document, a marked line can be visualized for example with a shaded |
231 | * background color and/or a pixmap in the iconborder of the Document's View. |
232 | * There are a number of predefined mark types, specified in |
233 | * reservedMarkersCount(). Additionally it is possible to add custom marks |
234 | * and set custom pixmaps. |
235 | * |
236 | * Get all marks in the document by calling marks(). Use clearMarks() to |
237 | * remove all marks in the entire document. A single mark can be retrieved |
238 | * with mark(). To remove all marks from a line call clearMark(). To add |
239 | * and remove marks from a given line use addMark() and removeMark(). It is |
240 | * also possible to replace all marks with setMark(), i.e. setMark() is the |
241 | * same as a call of clearMark() followed by addMark(). The signals |
242 | * marksChanged() and markChanged() are emitted whenever a line's marks |
243 | * changed. |
244 | * |
245 | * \attention A mark type is represented as an \e uint. An \e uint can have |
246 | * several mark types combined (see above: logical OR). That means for |
247 | * all functions/signals with an \e uint parameter, e.g. setMark(), |
248 | * removeMark(), etc, the \e uint may contain \e multiple marks, i.e. |
249 | * you can add and remove multiple marks \e simultaneously. |
250 | * |
251 | * All marks that should be editable by the user can be specified with a mark |
252 | * mask via setEditableMarks(). To set a description and pixmap of a mark type |
253 | * call setMarkDescription() and setMarkPixmap(). |
254 | * |
255 | * \section doc_annoiface Annotation Interface |
256 | * |
257 | * The Annotation Interface is designed to provide line annotation information |
258 | * for a document. This interface provides means to associate a document with a |
259 | * annotation model, which provides some annotation information for each line |
260 | * in the document. |
261 | * |
262 | * Setting a model for a Document makes the model data available for all views. |
263 | * If you only want to provide annotations in exactly one view, you can use |
264 | * the AnnotationViewInterface directly. See the AnnotationViewInterface for |
265 | * further details. To summarize, the two use cases are |
266 | * - (1) show annotations in all views. This means you set an AnnotationModel |
267 | * with this interface, and then call setAnnotationBorderVisible() for |
268 | * each view. |
269 | * - (2) show annotations only in one view. This means to \e not use this |
270 | * interface. Instead, use the AnnotationViewInterface, which inherits |
271 | * this interface. This means you set a model for the specific View. |
272 | * |
273 | * If you set a model to the Document \e and the View, the View's model has |
274 | * higher priority. |
275 | * |
276 | * More information about interfaces for the document can be found in |
277 | * \ref kte_group_doc_extensions. |
278 | * |
279 | * \see KParts::ReadWritePart, KTextEditor::Editor, KTextEditor::View, |
280 | * KTextEditor::MarkInterface |
281 | * \author Christoph Cullmann \<cullmann@kde.org\> |
282 | */ |
283 | class KTEXTEDITOR_EXPORT Document : public KParts::ReadWritePart |
284 | { |
285 | Q_OBJECT |
286 | |
287 | protected: |
288 | /** |
289 | * Constructor. |
290 | * |
291 | * Create a new document with \p parent. |
292 | * |
293 | * Pass it the internal implementation to store a d-pointer. |
294 | * |
295 | * \param impl d-pointer to use |
296 | * \param parent parent object |
297 | * \see Editor::createDocument() |
298 | */ |
299 | Document(DocumentPrivate *impl, const KPluginMetaData &data, QObject *parent); |
300 | |
301 | public: |
302 | /** |
303 | * Virtual destructor. |
304 | */ |
305 | ~Document() override; |
306 | |
307 | /** |
308 | * \name Manage View%s of this Document |
309 | * |
310 | * \{ |
311 | */ |
312 | public: |
313 | /** |
314 | * Create a new view attached to @p parent. |
315 | * @param parent parent widget |
316 | * @param mainWindow the main window responsible for this view, if any |
317 | * @return the new view |
318 | */ |
319 | virtual View *createView(QWidget *parent, KTextEditor::MainWindow *mainWindow = nullptr) = 0; |
320 | |
321 | /** |
322 | * Returns the views pre-casted to KTextEditor::View%s |
323 | */ |
324 | virtual QList<View *> views() const = 0; |
325 | |
326 | Q_SIGNALS: |
327 | /** |
328 | * This signal is emitted whenever the \p document creates a new \p view. |
329 | * It should be called for every view to help applications / plugins to |
330 | * attach to the \p view. |
331 | * \attention This signal should be emitted after the view constructor is |
332 | * completed, e.g. in the createView() method. |
333 | * \param document the document for which a new view is created |
334 | * \param view the new view |
335 | * \see createView() |
336 | */ |
337 | void viewCreated(KTextEditor::Document *document, KTextEditor::View *view); |
338 | |
339 | //!\} |
340 | |
341 | /** |
342 | * \name General Information about this Document |
343 | * |
344 | * \{ |
345 | */ |
346 | public: |
347 | /** |
348 | * Get this document's name. |
349 | * The editor part should provide some meaningful name, like some unique |
350 | * "Untitled XYZ" for the document - \e without URL or basename for |
351 | * documents with url. |
352 | * \return readable document name |
353 | */ |
354 | virtual QString documentName() const = 0; |
355 | |
356 | /** |
357 | * Get this document's mimetype. |
358 | * \return mimetype |
359 | */ |
360 | virtual QString mimeType() = 0; |
361 | |
362 | /** |
363 | * Get the git hash of the Document's contents on disk. |
364 | * The returned hash equals the git hash of the file written to disk. |
365 | * If the document is a remote document, the checksum may not be |
366 | * available. In this case, QByteArray::isNull() returns \e true. |
367 | * |
368 | * git hash is defined as: |
369 | * |
370 | * sha1("blob " + filesize + "\0" + filecontent) |
371 | * |
372 | * \return the git hash of the document |
373 | */ |
374 | virtual QByteArray checksum() const = 0; |
375 | |
376 | /* |
377 | * SIGNALS |
378 | * following signals should be emitted by the editor document. |
379 | */ |
380 | Q_SIGNALS: |
381 | /** |
382 | * This signal is emitted whenever the \p document name changes. |
383 | * \param document document which changed its name |
384 | * \see documentName() |
385 | */ |
386 | void documentNameChanged(KTextEditor::Document *document); |
387 | |
388 | /** |
389 | * This signal is emitted whenever the \p document URL changes. |
390 | * \param document document which changed its URL |
391 | * \see KParts::ReadOnlyPart::url() |
392 | */ |
393 | void documentUrlChanged(KTextEditor::Document *document); |
394 | |
395 | /** |
396 | * This signal is emitted whenever the \p document's buffer changed from |
397 | * either state \e unmodified to \e modified or vice versa. |
398 | * |
399 | * \param document document which changed its modified state |
400 | * \see KParts::ReadWritePart::isModified(). |
401 | * \see KParts::ReadWritePart::setModified() |
402 | */ |
403 | void modifiedChanged(KTextEditor::Document *document); |
404 | |
405 | /** |
406 | * This signal is emitted whenever the readWrite state of a document |
407 | * changes. |
408 | * \param document the document whose read/write property changed |
409 | * \see KParts::ReadWritePart::setReadWrite() |
410 | */ |
411 | void readWriteChanged(KTextEditor::Document *document); |
412 | |
413 | /* |
414 | * VERY IMPORTANT: Methods to set and query the current encoding of the |
415 | * document |
416 | */ |
417 | public: |
418 | /** |
419 | * Set the encoding for this document. This encoding will be used |
420 | * while loading and saving files, it will \e not affect the already |
421 | * existing content of the document, e.g. if the file has already been |
422 | * opened without the correct encoding, this will \e not fix it, you |
423 | * would for example need to trigger a reload for this. |
424 | * \param encoding new encoding for the document, the name must be |
425 | * accepted by QStringDecoder/QStringEncoder, if an empty encoding name is given, the |
426 | * part should fallback to its own default encoding, e.g. the |
427 | * system encoding or the global user settings |
428 | * \return \e true on success, or \e false, if the encoding could not be set. |
429 | * \see encoding() |
430 | */ |
431 | virtual bool setEncoding(const QString &encoding) = 0; |
432 | |
433 | /** |
434 | * Get the current chosen encoding. The return value is an empty string, |
435 | * if the document uses the default encoding of the editor and no own |
436 | * special encoding. |
437 | * \return current encoding of the document |
438 | * \see setEncoding() |
439 | */ |
440 | virtual QString encoding() const = 0; |
441 | |
442 | //!\} |
443 | |
444 | /** |
445 | * \name File Loading and Saving |
446 | * |
447 | * All this actions cause user interaction in some cases. |
448 | * \{ |
449 | */ |
450 | public: |
451 | /** |
452 | * Reload the current file. |
453 | * The user will be prompted by the part on changes and more and can |
454 | * cancel this action if it can harm. |
455 | * \return \e true if the reload has been done, otherwise \e false. If |
456 | * the document has no url set, it will just return \e false. |
457 | */ |
458 | virtual bool documentReload() = 0; |
459 | |
460 | /** |
461 | * Save the current file. |
462 | * The user will be asked for a filename if needed and more. |
463 | * \return \e true on success, i.e. the save has been done, otherwise |
464 | * \e false |
465 | */ |
466 | virtual bool documentSave() = 0; |
467 | |
468 | /** |
469 | * Save the current file to another location. |
470 | * The user will be asked for a filename and more. |
471 | * \return \e true on success, i.e. the save has been done, otherwise |
472 | * \e false |
473 | */ |
474 | virtual bool documentSaveAs() = 0; |
475 | |
476 | /** |
477 | * True, eg if the file for opening could not be read |
478 | * This doesn't have to handle the KPart job canceled cases. |
479 | * @return was there some problem loading the file? |
480 | */ |
481 | bool openingError() const; |
482 | |
483 | /* |
484 | * SIGNALS |
485 | * Following signals should be emitted by the document if the text content |
486 | * is changed. |
487 | */ |
488 | Q_SIGNALS: |
489 | /** |
490 | * This signal should be emitted after a document has been saved to disk or for remote files uploaded. |
491 | * saveAs should be set to true, if the operation is a save as operation |
492 | */ |
493 | void documentSavedOrUploaded(KTextEditor::Document *document, bool saveAs); |
494 | |
495 | /** |
496 | * Warn anyone listening that the current document is about to close. |
497 | * At this point all of the information is still accessible, such as the text, |
498 | * cursors and ranges. |
499 | * |
500 | * Any modifications made to the document at this point will be lost. |
501 | * |
502 | * \param document the document being closed |
503 | */ |
504 | void aboutToClose(KTextEditor::Document *document); |
505 | |
506 | /** |
507 | * Warn anyone listening that the current document is about to reload. |
508 | * At this point all of the information is still accessible, such as the text, |
509 | * cursors and ranges. |
510 | * |
511 | * Any modifications made to the document at this point will be lost. |
512 | * |
513 | * \param document the document being reloaded |
514 | */ |
515 | void aboutToReload(KTextEditor::Document *document); |
516 | |
517 | /** |
518 | * Emitted after the current document was reloaded. |
519 | * At this point, some information might have been invalidated, like |
520 | * for example the editing history. |
521 | * |
522 | * \param document the document that was reloaded. |
523 | * |
524 | * @since 4.6 |
525 | */ |
526 | void reloaded(KTextEditor::Document *document); |
527 | |
528 | /** |
529 | * Emitted just before the document will be saved |
530 | * Any modifications made to the document at this point |
531 | * will get stored on disk. |
532 | * |
533 | * \param document the document that was reloaded. |
534 | * |
535 | * @since 5.91 |
536 | */ |
537 | void aboutToSave(KTextEditor::Document *document); |
538 | |
539 | //!\} |
540 | |
541 | /** |
542 | * \name Text Manipulation |
543 | * |
544 | * \{ |
545 | */ |
546 | public: |
547 | /** |
548 | * Editing transaction support. |
549 | * |
550 | * Edit commands during this sequence will be bunched together so that |
551 | * they represent a single undo command in the editor, and so that |
552 | * repaint events do not occur in between. |
553 | * |
554 | * Your application should \e not return control to the event loop while |
555 | * it has an unterminated (i.e. this object is not destructed) editing |
556 | * sequence (result undefined) - so do all of your work in one go! |
557 | * |
558 | * Using this class typically looks as follows: |
559 | * @code |
560 | * void foo() { |
561 | * KTextEditor::Document::EditingTransaction transaction(document); |
562 | * // now call editing functions |
563 | * document->removeText(...) |
564 | * document->insertText(...) |
565 | * } |
566 | * @endcode |
567 | * |
568 | * Although usually not required, the EditingTransaction additionally |
569 | * allows to manually call finish() and start() in between. |
570 | * |
571 | * @see editingStarted(), editingFinished() |
572 | */ |
573 | class KTEXTEDITOR_EXPORT EditingTransaction |
574 | { |
575 | public: |
576 | /** |
577 | * Constructs the object and starts an editing transaction by |
578 | * calling start(). |
579 | * |
580 | * @param document document for the transaction |
581 | * @see start() |
582 | */ |
583 | explicit EditingTransaction(Document *document); |
584 | |
585 | /** |
586 | * No copy constructor, don't allow this to be copied. |
587 | */ |
588 | EditingTransaction(const EditingTransaction &) = delete; |
589 | |
590 | /** |
591 | * No assignment operator, no copying around editing transations. |
592 | */ |
593 | EditingTransaction &operator=(const EditingTransaction &) = delete; |
594 | |
595 | /** |
596 | * Destructs the object and, if needed, finishes a running editing |
597 | * transaction by calling finish(). |
598 | * |
599 | * @see finish() |
600 | */ |
601 | ~EditingTransaction(); |
602 | |
603 | /** |
604 | * By calling start(), the editing transaction can be started again. |
605 | * This function only is of use in combination with finish(). |
606 | * |
607 | * @see finish() |
608 | */ |
609 | void start(); |
610 | |
611 | /** |
612 | * By calling finish(), the editing transaction can be finished |
613 | * already before destruction of this instance. |
614 | * |
615 | * @see start() |
616 | */ |
617 | void finish(); |
618 | |
619 | private: |
620 | /** |
621 | * private d-pointer |
622 | */ |
623 | EditingTransactionPrivate *const d; |
624 | }; |
625 | |
626 | /** |
627 | * Check whether an editing transaction is currently running. |
628 | * |
629 | * @see EditingTransaction |
630 | */ |
631 | virtual bool isEditingTransactionRunning() const = 0; |
632 | |
633 | /* |
634 | * General access to the document's text content. |
635 | */ |
636 | public: |
637 | /** |
638 | * Get the document content. |
639 | * \return the complete document content |
640 | * \see setText() |
641 | */ |
642 | virtual QString text() const = 0; |
643 | |
644 | /** |
645 | * Get the document content within the given \p range. |
646 | * \param range the range of text to retrieve |
647 | * \param block Set this to \e true to receive text in a visual block, |
648 | * rather than everything inside \p range. |
649 | * \return the requested text part, or QString() for invalid ranges. |
650 | * \see setText() |
651 | */ |
652 | virtual QString text(Range range, bool block = false) const = 0; |
653 | |
654 | /** |
655 | * Get the character at text position \p cursor. |
656 | * \param position the location of the character to retrieve |
657 | * \return the requested character, or QChar() for invalid cursors. |
658 | * \see setText() |
659 | */ |
660 | virtual QChar characterAt(KTextEditor::Cursor position) const = 0; |
661 | |
662 | /** |
663 | * Get the word at the text position \p cursor. |
664 | * The returned word is defined by the word boundaries to the left and |
665 | * right starting at \p cursor. The algorithm takes highlighting information |
666 | * into account, e.g. a dash ('-') in C++ is interpreted as word boundary, |
667 | * whereas e.g. CSS allows identifiers with dash ('-'). |
668 | * |
669 | * If \p cursor is not a valid text position or if there is no word |
670 | * under the requested position \p cursor, an empty string is returned. |
671 | * |
672 | * \param cursor requested cursor position for the word |
673 | * \return the word under the cursor or an empty string if there is no word. |
674 | * |
675 | * \see wordRangeAt(), characterAt() |
676 | */ |
677 | virtual QString wordAt(KTextEditor::Cursor cursor) const = 0; |
678 | |
679 | /** |
680 | * Get the text range for the word located under the text position \p cursor. |
681 | * The returned word is defined by the word boundaries to the left and |
682 | * right starting at \p cursor. The algorithm takes highlighting information |
683 | * into account, e.g. a dash ('-') in C++ is interpreted as word boundary, |
684 | * whereas e.g. CSS allows identifiers with dash ('-'). |
685 | * |
686 | * If \p cursor is not a valid text position or if there is no word |
687 | * under the requested position \p cursor, an invalid text range is returned. |
688 | * If the text range is valid, it is \e always on a single line. |
689 | * |
690 | * \param cursor requested cursor position for the word |
691 | * \return the Range spanning the word under the cursor or an invalid range if there is no word. |
692 | * |
693 | * \see wordAt(), characterAt(), KTextEditor::Range::isValid() |
694 | */ |
695 | virtual KTextEditor::Range wordRangeAt(KTextEditor::Cursor cursor) const = 0; |
696 | |
697 | /** |
698 | * Get whether \p cursor is a valid text position. |
699 | * A cursor position at (line, column) is valid, if |
700 | * - line >= 0 and line < lines() holds, and |
701 | * - column >= 0 and column <= lineLength(column). |
702 | * |
703 | * The text position \p cursor is also invalid if it is inside a Unicode surrogate. |
704 | * Therefore, use this function when iterating over the characters of a line. |
705 | * |
706 | * \param cursor cursor position to check for validity |
707 | * \return true, if \p cursor is a valid text position, otherwise \p false |
708 | * |
709 | * \since 5.0 |
710 | */ |
711 | virtual bool isValidTextPosition(KTextEditor::Cursor cursor) const = 0; |
712 | |
713 | /** |
714 | * Get the document content within the given \p range. |
715 | * \param range the range of text to retrieve |
716 | * \param block Set this to \e true to receive text in a visual block, |
717 | * rather than everything inside \p range. |
718 | * \return the requested text lines, or QStringList() for invalid ranges. |
719 | * no end of line termination is included. |
720 | * \see setText() |
721 | */ |
722 | virtual QStringList textLines(Range range, bool block = false) const = 0; |
723 | |
724 | /** |
725 | * Get a single text line. |
726 | * \param line the wanted line |
727 | * \return the requested line, or "" for invalid line numbers |
728 | * \see text(), lineLength() |
729 | */ |
730 | virtual QString line(int line) const = 0; |
731 | |
732 | /** |
733 | * Get the count of lines of the document. |
734 | * \return the current number of lines in the document |
735 | * \see length() |
736 | */ |
737 | virtual int lines() const = 0; |
738 | |
739 | /** |
740 | * Check whether \p line currently contains unsaved data. |
741 | * If \p line contains unsaved data, \e true is returned, otherwise \e false. |
742 | * When the user saves the file, a modified line turns into a \e saved line. |
743 | * In this case isLineModified() returns \e false and in its stead isLineSaved() |
744 | * returns \e true. |
745 | * \param line line to query |
746 | * \see isLineSaved(), isLineTouched() |
747 | * \since 5.0 |
748 | */ |
749 | virtual bool isLineModified(int line) const = 0; |
750 | |
751 | /** |
752 | * Check whether \p line currently contains only saved text. |
753 | * Saved text in this case implies that a line was touched at some point |
754 | * by the user and then then changes were either undone or the user saved |
755 | * the file. |
756 | * |
757 | * In case \p line was touched and currently contains only saved data, |
758 | * \e true is returned, otherwise \e false. |
759 | * \param line line to query |
760 | * \see isLineModified(), isLineTouched() |
761 | * \since 5.0 |
762 | */ |
763 | virtual bool isLineSaved(int line) const = 0; |
764 | |
765 | /** |
766 | * Check whether \p line was touched since the file was opened. |
767 | * This equals the statement isLineModified() || isLineSaved(). |
768 | * \param line line to query |
769 | * \see isLineModified(), isLineSaved() |
770 | * \since 5.0 |
771 | */ |
772 | virtual bool isLineTouched(int line) const = 0; |
773 | |
774 | /** |
775 | * End position of the document. |
776 | * \return The last column on the last line of the document |
777 | * \see all() |
778 | */ |
779 | virtual Cursor documentEnd() const = 0; |
780 | |
781 | /** |
782 | * A Range which encompasses the whole document. |
783 | * \return A range from the start to the end of the document |
784 | */ |
785 | inline Range documentRange() const |
786 | { |
787 | return Range(Cursor::start(), documentEnd()); |
788 | } |
789 | |
790 | /** |
791 | * Get the count of characters in the document. A TAB character counts as |
792 | * only one character. |
793 | * \return the number of characters in the document |
794 | * \see lines() |
795 | */ |
796 | virtual qsizetype totalCharacters() const = 0; |
797 | |
798 | /** |
799 | * Returns if the document is empty. |
800 | */ |
801 | virtual bool isEmpty() const; |
802 | |
803 | /** |
804 | * Get the length of a given line in characters. |
805 | * \param line line to get length from |
806 | * \return the number of characters in the line or -1 if the line was |
807 | * invalid |
808 | * \see line() |
809 | */ |
810 | virtual int lineLength(int line) const = 0; |
811 | |
812 | /** |
813 | * Get the end cursor position of line \p line. |
814 | * \param line line |
815 | * \see lineLength(), line() |
816 | */ |
817 | inline Cursor endOfLine(int line) const |
818 | { |
819 | return Cursor(line, lineLength(line)); |
820 | } |
821 | |
822 | /** |
823 | * Set the given text as new document content. |
824 | * \param text new content for the document |
825 | * \return \e true on success, otherwise \e false |
826 | * \see text() |
827 | */ |
828 | virtual bool setText(const QString &text) = 0; |
829 | |
830 | /** |
831 | * Set the given text as new document content. |
832 | * \param text new content for the document |
833 | * \return \e true on success, otherwise \e false |
834 | * \see text() |
835 | */ |
836 | virtual bool setText(const QStringList &text) = 0; |
837 | |
838 | /** |
839 | * Remove the whole content of the document. |
840 | * \return \e true on success, otherwise \e false |
841 | * \see removeText(), removeLine() |
842 | */ |
843 | virtual bool clear() = 0; |
844 | |
845 | /** |
846 | * Insert \p text at \p position. |
847 | * \param position position to insert the text |
848 | * \param text text to insert |
849 | * \param block insert this text as a visual block of text rather than a linear sequence |
850 | * \return \e true on success, otherwise \e false |
851 | * \see setText(), removeText() |
852 | */ |
853 | virtual bool insertText(KTextEditor::Cursor position, const QString &text, bool block = false) = 0; |
854 | |
855 | /** |
856 | * Insert \p text at \p position. |
857 | * \param position position to insert the text |
858 | * \param text text to insert |
859 | * \param block insert this text as a visual block of text rather than a linear sequence |
860 | * \return \e true on success, otherwise \e false |
861 | * \see setText(), removeText() |
862 | */ |
863 | virtual bool insertText(KTextEditor::Cursor position, const QStringList &text, bool block = false) = 0; |
864 | |
865 | /** |
866 | * Replace text from \p range with specified \p text. |
867 | * \param range range of text to replace |
868 | * \param text text to replace with |
869 | * \param block replace text as a visual block of text rather than a linear sequence |
870 | * \return \e true on success, otherwise \e false |
871 | * \see setText(), removeText(), insertText() |
872 | */ |
873 | virtual bool replaceText(Range range, const QString &text, bool block = false); |
874 | |
875 | /** |
876 | * Replace text from \p range with specified \p text. |
877 | * \param range range of text to replace |
878 | * \param text text to replace with |
879 | * \param block replace text as a visual block of text rather than a linear sequence |
880 | * \return \e true on success, otherwise \e false |
881 | * \see setText(), removeText(), insertText() |
882 | */ |
883 | virtual bool replaceText(Range range, const QStringList &text, bool block = false); |
884 | |
885 | /** |
886 | * Remove the text specified in \p range. |
887 | * \param range range of text to remove |
888 | * \param block set this to true to remove a text block on the basis of columns, rather than everything inside \p range |
889 | * \return \e true on success, otherwise \e false |
890 | * \see setText(), insertText() |
891 | */ |
892 | virtual bool removeText(Range range, bool block = false) = 0; |
893 | |
894 | /** |
895 | * Insert line(s) at the given line number. The newline character '\\n' |
896 | * is treated as line delimiter, so it is possible to insert multiple |
897 | * lines. To append lines at the end of the document, use |
898 | * \code |
899 | * insertLine( lines(), text ) |
900 | * \endcode |
901 | * \param line line where to insert the text |
902 | * \param text text which should be inserted |
903 | * \return \e true on success, otherwise \e false |
904 | * \see insertText() |
905 | */ |
906 | virtual bool insertLine(int line, const QString &text) = 0; |
907 | |
908 | /** |
909 | * Insert line(s) at the given line number. The newline character '\\n' |
910 | * is treated as line delimiter, so it is possible to insert multiple |
911 | * lines. To append lines at the end of the document, use |
912 | * \code |
913 | * insertLine( lines(), text ) |
914 | * \endcode |
915 | * \param line line where to insert the text |
916 | * \param text text which should be inserted |
917 | * \return \e true on success, otherwise \e false |
918 | * \see insertText() |
919 | */ |
920 | virtual bool insertLines(int line, const QStringList &text) = 0; |
921 | |
922 | /** |
923 | * Remove \p line from the document. |
924 | * \param line line to remove |
925 | * \return \e true on success, otherwise \e false |
926 | * \see removeText(), clear() |
927 | */ |
928 | virtual bool removeLine(int line) = 0; |
929 | |
930 | /** |
931 | * \brief Searches the given input range for a text pattern. |
932 | * |
933 | * Searches for a text pattern within the given input range. |
934 | * The kind of search performed depends on the \p options |
935 | * used. Use this function for plaintext searches as well as |
936 | * regular expression searches. If no match is found the first |
937 | * (and only) element in the vector return is the invalid range. |
938 | * When searching for regular expressions, the first element holds |
939 | * the range of the full match, the subsequent elements hold |
940 | * the ranges of the capturing parentheses. |
941 | * |
942 | * \param range Input range to search in |
943 | * \param pattern Text pattern to search for |
944 | * \param options Combination of search flags |
945 | * \return List of ranges (length >=1) |
946 | * |
947 | * \author Sebastian Pipping \<webmaster@hartwork.org\> |
948 | * |
949 | * \since 5.11 |
950 | */ |
951 | QList<KTextEditor::Range> searchText(KTextEditor::Range range, const QString &pattern, const SearchOptions options = Default) const; |
952 | |
953 | /** |
954 | * \brief Retrives the offset for the given cursor position |
955 | * NOTE: It will return -1 if the cursor was invalid or out of bounds. |
956 | * \since 6.0 |
957 | */ |
958 | virtual qsizetype cursorToOffset(KTextEditor::Cursor c) const = 0; |
959 | |
960 | /** |
961 | * \brief Retrives the cursor position for given offset |
962 | * NOTE: It will return an invalid cursor(-1, -1) if offset is invalid. |
963 | * \since 6.0 |
964 | */ |
965 | virtual KTextEditor::Cursor offsetToCursor(qsizetype offset) const = 0; |
966 | /* |
967 | * SIGNALS |
968 | * Following signals should be emitted by the document if the text content |
969 | * is changed. |
970 | */ |
971 | Q_SIGNALS: |
972 | /** |
973 | * Editing transaction has started. |
974 | * \param document document which emitted this signal |
975 | */ |
976 | void editingStarted(KTextEditor::Document *document); |
977 | |
978 | /** |
979 | * Editing transaction has finished. |
980 | * |
981 | * @note This signal is emitted also for editing actions that maybe do not |
982 | * modify the @p document contents (think of having an empty |
983 | * EditingTransaction). If you want to get notified only |
984 | * after text really changed, connect to the signal textChanged(). |
985 | * |
986 | * \param document document which emitted this signal |
987 | * @see textChanged() |
988 | */ |
989 | void editingFinished(KTextEditor::Document *document); |
990 | |
991 | /** |
992 | * A line got wrapped. |
993 | * \param document document which emitted this signal |
994 | * @param position position where the wrap occurred |
995 | */ |
996 | void lineWrapped(KTextEditor::Document *document, KTextEditor::Cursor position); |
997 | |
998 | /** |
999 | * A line got unwrapped. |
1000 | * \param document document which emitted this signal |
1001 | * @param line line where the unwrap occurred |
1002 | */ |
1003 | void lineUnwrapped(KTextEditor::Document *document, int line); |
1004 | |
1005 | /** |
1006 | * Text got inserted. |
1007 | * \param document document which emitted this signal |
1008 | * @param position position where the insertion occurred |
1009 | * @param text inserted text |
1010 | */ |
1011 | void textInserted(KTextEditor::Document *document, KTextEditor::Cursor position, const QString &text); |
1012 | |
1013 | /** |
1014 | * Text got removed. |
1015 | * \param document document which emitted this signal |
1016 | * @param range range where the removal occurred |
1017 | * @param text removed text |
1018 | */ |
1019 | void textRemoved(KTextEditor::Document *document, KTextEditor::Range range, const QString &text); |
1020 | |
1021 | /** |
1022 | * The \p document emits this signal whenever its text changes. |
1023 | * \param document document which emitted this signal |
1024 | * \see text(), textLine() |
1025 | */ |
1026 | void textChanged(KTextEditor::Document *document); |
1027 | |
1028 | //!\} |
1029 | |
1030 | /** |
1031 | * \name Highlighting and Related Information |
1032 | * |
1033 | * \{ |
1034 | */ |
1035 | public: |
1036 | /** |
1037 | * Get the default style of the character located at @p position. |
1038 | * If @p position is not a valid text position, the default style |
1039 | * KSyntaxHighlighting::Theme::TextStyle::Normal is returned. |
1040 | * |
1041 | * @note Further information about the colors of default styles depend on |
1042 | * the currently chosen schema. Since each View may have a different |
1043 | * color schema, the color information can be obtained through |
1044 | * View::defaultStyleAttribute() and View::lineAttributes(). |
1045 | * |
1046 | * @param position text position |
1047 | * @return default style, see enum KSyntaxHighlighting::Theme::TextStyle |
1048 | * @see View::defaultStyleAttribute(), View::lineAttributes() |
1049 | */ |
1050 | virtual KSyntaxHighlighting::Theme::TextStyle defaultStyleAt(KTextEditor::Cursor position) const = 0; |
1051 | |
1052 | /** |
1053 | * Return the name of the currently used mode |
1054 | * \return name of the used mode |
1055 | * \see modes(), setMode() |
1056 | */ |
1057 | virtual QString mode() const = 0; |
1058 | |
1059 | /** |
1060 | * Return the name of the currently used mode |
1061 | * \return name of the used mode |
1062 | * \see highlightingModes(), setHighlightingMode() |
1063 | */ |
1064 | virtual QString highlightingMode() const = 0; |
1065 | |
1066 | /** |
1067 | * \brief Get all available highlighting modes for the current document. |
1068 | * |
1069 | * Each document can be highlighted using an arbitrary number of highlighting |
1070 | * contexts. This method will return the names for each of the used modes. |
1071 | * |
1072 | * Example: The "PHP (HTML)" mode includes the highlighting for PHP, HTML, CSS and JavaScript. |
1073 | * |
1074 | * \return Returns a list of embedded highlighting modes for the current Document. |
1075 | * |
1076 | * \see KTextEditor::Document::highlightingMode() |
1077 | */ |
1078 | virtual QStringList embeddedHighlightingModes() const = 0; |
1079 | |
1080 | /** |
1081 | * \brief Get the highlight mode used at a given position in the document. |
1082 | * |
1083 | * Retrieve the name of the applied highlight mode at a given \p position |
1084 | * in the current document. |
1085 | * |
1086 | * Calling this might trigger re-highlighting up to the given line. |
1087 | * Therefore this is not const. |
1088 | * |
1089 | * \see highlightingModes() |
1090 | */ |
1091 | virtual QString highlightingModeAt(KTextEditor::Cursor position) = 0; |
1092 | |
1093 | /** |
1094 | * Return a list of the names of all possible modes |
1095 | * \return list of mode names |
1096 | * \see mode(), setMode() |
1097 | */ |
1098 | virtual QStringList modes() const = 0; |
1099 | |
1100 | /** |
1101 | * Return a list of the names of all possible modes |
1102 | * \return list of mode names |
1103 | * \see highlightingMode(), setHighlightingMode() |
1104 | */ |
1105 | virtual QStringList highlightingModes() const = 0; |
1106 | |
1107 | /** |
1108 | * Set the current mode of the document by giving its name |
1109 | * \param name name of the mode to use for this document |
1110 | * \return \e true on success, otherwise \e false |
1111 | * \see mode(), modes(), modeChanged() |
1112 | */ |
1113 | virtual bool setMode(const QString &name) = 0; |
1114 | |
1115 | /** |
1116 | * Set the current mode of the document by giving its name |
1117 | * \param name name of the mode to use for this document |
1118 | * \return \e true on success, otherwise \e false |
1119 | * \see highlightingMode(), highlightingModes(), highlightingModeChanged() |
1120 | */ |
1121 | virtual bool setHighlightingMode(const QString &name) = 0; |
1122 | |
1123 | /** |
1124 | * Returns the name of the section for a highlight given its index in the highlight |
1125 | * list (as returned by highlightModes()). |
1126 | * |
1127 | * You can use this function to build a tree of the highlight names, organized in sections. |
1128 | * |
1129 | * \param index the index of the highlight in the list returned by modes() |
1130 | */ |
1131 | virtual QString highlightingModeSection(int index) const = 0; |
1132 | |
1133 | /** |
1134 | * Returns the name of the section for a mode given its index in the highlight |
1135 | * list (as returned by modes()). |
1136 | * |
1137 | * You can use this function to build a tree of the mode names, organized in sections. |
1138 | * |
1139 | * \param index the index of the highlight in the list returned by modes() |
1140 | */ |
1141 | virtual QString modeSection(int index) const = 0; |
1142 | |
1143 | /* |
1144 | * SIGNALS |
1145 | * Following signals should be emitted by the document if the mode |
1146 | * of the document changes |
1147 | */ |
1148 | Q_SIGNALS: |
1149 | /** |
1150 | * Warn anyone listening that the current document's mode has |
1151 | * changed. |
1152 | * |
1153 | * \param document the document whose mode has changed |
1154 | * \see setMode() |
1155 | */ |
1156 | void modeChanged(KTextEditor::Document *document); |
1157 | |
1158 | /** |
1159 | * Warn anyone listening that the current document's highlighting mode has |
1160 | * changed. |
1161 | * |
1162 | * \param document the document which's mode has changed |
1163 | * \see setHighlightingMode() |
1164 | */ |
1165 | void highlightingModeChanged(KTextEditor::Document *document); |
1166 | |
1167 | //!\} |
1168 | |
1169 | /** |
1170 | * \name Printing |
1171 | * |
1172 | * \{ |
1173 | */ |
1174 | public: |
1175 | /** |
1176 | * Print the document. This should result in showing the print dialog. |
1177 | * |
1178 | * @returns true if document was printed |
1179 | */ |
1180 | virtual bool print() = 0; |
1181 | |
1182 | /** |
1183 | * Shows the print preview dialog/ |
1184 | */ |
1185 | virtual void printPreview() = 0; |
1186 | |
1187 | //!\} |
1188 | |
1189 | /** |
1190 | * \name Showing Interactive Notifications |
1191 | * |
1192 | * \{ |
1193 | */ |
1194 | public: |
1195 | /** |
1196 | * Post @p message to the Document and its View%s. |
1197 | * If multiple Message%s are posted, the one with the highest priority |
1198 | * is shown first. |
1199 | * |
1200 | * Usually, you can simply forget the pointer, as the Message is deleted |
1201 | * automatically, once it is processed or the document gets closed. |
1202 | * |
1203 | * If the Document does not have a View yet, the Message is queued and |
1204 | * shown, once a View for the Document is created. |
1205 | * |
1206 | * @param message the message to show |
1207 | * @return @e true, if @p message was posted. @e false, if message == 0. |
1208 | */ |
1209 | virtual bool postMessage(Message *message) = 0; |
1210 | |
1211 | //!\} |
1212 | |
1213 | /** |
1214 | * \name Session Configuration |
1215 | * |
1216 | * \{ |
1217 | */ |
1218 | public: |
1219 | /** |
1220 | * Read session settings from the given \p config. |
1221 | * |
1222 | * Known flags: |
1223 | * - \p SkipUrl => do not save/restore the file |
1224 | * - \p SkipMode => do not save/restore the mode |
1225 | * - \p SkipHighlighting => do not save/restore the highlighting |
1226 | * - \p SkipEncoding => do not save/restore the encoding |
1227 | * |
1228 | * \param config read the session settings from this KConfigGroup |
1229 | * \param flags additional flags |
1230 | * \see writeSessionConfig() |
1231 | */ |
1232 | virtual void readSessionConfig(const KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) = 0; |
1233 | |
1234 | /** |
1235 | * Write session settings to the \p config. |
1236 | * See readSessionConfig() for more details about available \p flags. |
1237 | * |
1238 | * \param config write the session settings to this KConfigGroup |
1239 | * \param flags additional flags |
1240 | * \see readSessionConfig() |
1241 | */ |
1242 | virtual void writeSessionConfig(KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) = 0; |
1243 | |
1244 | //!\} |
1245 | |
1246 | /** |
1247 | * \name Crash Recovery |
1248 | * |
1249 | * \{ |
1250 | */ |
1251 | public: |
1252 | /** |
1253 | * Returns whether a recovery is available for the current document. |
1254 | * |
1255 | * \see recoverData(), discardDataRecovery() |
1256 | */ |
1257 | virtual bool isDataRecoveryAvailable() const = 0; |
1258 | |
1259 | /** |
1260 | * If recover data is available, calling recoverData() will trigger the |
1261 | * recovery of the data. If isDataRecoveryAvailable() returns \e false, |
1262 | * calling this function does nothing. |
1263 | * |
1264 | * \see isDataRecoveryAvailable(), discardDataRecovery() |
1265 | */ |
1266 | virtual void recoverData() = 0; |
1267 | |
1268 | /** |
1269 | * If recover data is available, calling discardDataRecovery() will discard |
1270 | * the recover data and the recover data is lost. |
1271 | * If isDataRecoveryAvailable() returns \e false, calling this function |
1272 | * does nothing. |
1273 | * |
1274 | * \see isDataRecoveryAvailable(), recoverData() |
1275 | */ |
1276 | virtual void discardDataRecovery() = 0; |
1277 | |
1278 | //!\} |
1279 | |
1280 | Q_SIGNALS: |
1281 | /** |
1282 | * This signal is emitted whenever the current document configuration is changed. |
1283 | * |
1284 | * \param document the document which's config has changed |
1285 | * |
1286 | * \since 5.79 |
1287 | */ |
1288 | void configChanged(KTextEditor::Document *document); |
1289 | |
1290 | /** |
1291 | * \name Moving Interface |
1292 | * |
1293 | * \{ |
1294 | */ |
1295 | public: |
1296 | /** |
1297 | * Create a new moving cursor for this document. |
1298 | * @param position position of the moving cursor to create |
1299 | * @param insertBehavior insertion behavior |
1300 | * @return new moving cursor for the document |
1301 | */ |
1302 | virtual MovingCursor *newMovingCursor(KTextEditor::Cursor position, MovingCursor::InsertBehavior insertBehavior = MovingCursor::MoveOnInsert) = 0; |
1303 | |
1304 | /** |
1305 | * Create a new moving range for this document. |
1306 | * @param range range of the moving range to create |
1307 | * @param insertBehaviors insertion behaviors |
1308 | * @param emptyBehavior behavior on becoming empty |
1309 | * @return new moving range for the document |
1310 | */ |
1311 | virtual MovingRange *newMovingRange(Range range, |
1312 | MovingRange::InsertBehaviors insertBehaviors = MovingRange::DoNotExpand, |
1313 | MovingRange::EmptyBehavior emptyBehavior = MovingRange::AllowEmpty) = 0; |
1314 | |
1315 | /** |
1316 | * Current revision |
1317 | * @return current revision |
1318 | */ |
1319 | virtual qint64 revision() const = 0; |
1320 | |
1321 | /** |
1322 | * Last revision the buffer got successful saved |
1323 | * @return last revision buffer got saved, -1 if none |
1324 | */ |
1325 | virtual qint64 lastSavedRevision() const = 0; |
1326 | |
1327 | /** |
1328 | * Lock a revision, this will keep it around until released again. |
1329 | * But all revisions will always be cleared on buffer clear() (and therefor load()) |
1330 | * @param revision revision to lock |
1331 | */ |
1332 | virtual void lockRevision(qint64 revision) = 0; |
1333 | |
1334 | /** |
1335 | * Release a revision. |
1336 | * @param revision revision to release |
1337 | */ |
1338 | virtual void unlockRevision(qint64 revision) = 0; |
1339 | |
1340 | /** |
1341 | * Transform a cursor from one revision to an other. |
1342 | * @param cursor cursor to transform |
1343 | * @param insertBehavior behavior of this cursor on insert of text at its position |
1344 | * @param fromRevision from this revision we want to transform |
1345 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
1346 | */ |
1347 | virtual void |
1348 | transformCursor(KTextEditor::Cursor &cursor, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1) = 0; |
1349 | |
1350 | /** |
1351 | * Transform a cursor from one revision to an other. |
1352 | * @param line line number of the cursor to transform |
1353 | * @param column column number of the cursor to transform |
1354 | * @param insertBehavior behavior of this cursor on insert of text at its position |
1355 | * @param fromRevision from this revision we want to transform |
1356 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
1357 | */ |
1358 | virtual void |
1359 | transformCursor(int &line, int &column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1) = 0; |
1360 | |
1361 | /** |
1362 | * Transform a range from one revision to an other. |
1363 | * @param range range to transform |
1364 | * @param insertBehaviors behavior of this range on insert of text at its position |
1365 | * @param emptyBehavior behavior on becoming empty |
1366 | * @param fromRevision from this revision we want to transform |
1367 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
1368 | */ |
1369 | virtual void transformRange(KTextEditor::Range &range, |
1370 | KTextEditor::MovingRange::InsertBehaviors insertBehaviors, |
1371 | MovingRange::EmptyBehavior emptyBehavior, |
1372 | qint64 fromRevision, |
1373 | qint64 toRevision = -1) = 0; |
1374 | |
1375 | Q_SIGNALS: |
1376 | /** |
1377 | * This signal is emitted before the cursors/ranges/revisions of a document |
1378 | * are destroyed as the document is deleted. |
1379 | * @param document the document which the interface belongs to which is in the process of being deleted |
1380 | */ |
1381 | void aboutToDeleteMovingInterfaceContent(KTextEditor::Document *document); |
1382 | |
1383 | /** |
1384 | * This signal is emitted before the ranges of a document are invalidated |
1385 | * and the revisions are deleted as the document is cleared (for example on |
1386 | * load/reload). While this signal is emitted, the old document content is |
1387 | * still valid and accessible before the clear. |
1388 | * @param document the document which the interface belongs to which will invalidate its data |
1389 | */ |
1390 | void aboutToInvalidateMovingInterfaceContent(KTextEditor::Document *document); |
1391 | |
1392 | //!\} |
1393 | |
1394 | /** |
1395 | * \name Config |
1396 | * |
1397 | * \{ |
1398 | */ |
1399 | public: |
1400 | /** |
1401 | * \brief Get a list of all available keys. |
1402 | */ |
1403 | virtual QStringList configKeys() const = 0; |
1404 | /** |
1405 | * \brief Get a value for the \p key. |
1406 | */ |
1407 | virtual QVariant configValue(const QString &key) = 0; |
1408 | /** |
1409 | * \brief Set a the \p key's value to \p value. |
1410 | */ |
1411 | virtual void setConfigValue(const QString &key, const QVariant &value) = 0; |
1412 | //!\} |
1413 | |
1414 | /** |
1415 | * \name Modification Interface |
1416 | * |
1417 | * \{ |
1418 | */ |
1419 | public: |
1420 | /** |
1421 | * Reasons why a document is modified on disk. |
1422 | */ |
1423 | enum ModifiedOnDiskReason { |
1424 | OnDiskUnmodified = 0, ///< Not modified |
1425 | OnDiskModified = 1, ///< The file was modified on disk |
1426 | OnDiskCreated = 2, ///< The file was created on disk |
1427 | OnDiskDeleted = 3 ///< The file was deleted on disk |
1428 | }; |
1429 | |
1430 | /** |
1431 | * Set the document's modified-on-disk state to \p reason. |
1432 | * KTextEditor implementations should emit the signal modifiedOnDisk() |
1433 | * along with the reason. When the document is in a clean state again the |
1434 | * reason should be ModifiedOnDiskReason::OnDiskUnmodified. |
1435 | * |
1436 | * \param reason the modified-on-disk reason. |
1437 | * \see ModifiedOnDiskReason, modifiedOnDisk() |
1438 | */ |
1439 | virtual void setModifiedOnDisk(ModifiedOnDiskReason reason) = 0; |
1440 | |
1441 | /** |
1442 | * Control, whether the editor should show a warning dialog whenever a file |
1443 | * was modified on disk. If \p on is \e true the editor will show warning |
1444 | * dialogs. |
1445 | * \param on controls, whether the editor should show a warning dialog for |
1446 | * files modified on disk |
1447 | */ |
1448 | virtual void setModifiedOnDiskWarning(bool on) = 0; |
1449 | |
1450 | Q_SIGNALS: |
1451 | /** |
1452 | * This signal is emitted whenever the \p document changed its |
1453 | * modified-on-disk state. |
1454 | * \param document the Document object that represents the file on disk |
1455 | * \param isModified if \e true, the file was modified rather than created |
1456 | * or deleted |
1457 | * \param reason the reason why the signal was emitted |
1458 | * \see setModifiedOnDisk() |
1459 | */ |
1460 | void modifiedOnDisk(KTextEditor::Document *document, bool isModified, KTextEditor::Document::ModifiedOnDiskReason reason); |
1461 | //!\} |
1462 | |
1463 | /** |
1464 | * \name Mark Interface |
1465 | * |
1466 | * \{ |
1467 | */ |
1468 | public: |
1469 | /** |
1470 | * Get all marks set on the \p line. |
1471 | * \param line requested line |
1472 | * \return a \e uint representing of the marks set in \p line concatenated |
1473 | * by logical OR |
1474 | * \see addMark(), removeMark() |
1475 | */ |
1476 | virtual uint mark(int line) = 0; |
1477 | |
1478 | /** |
1479 | * Set the \p line's mark types to \p markType. |
1480 | * If \p line already contains a mark of the given type it has no effect. |
1481 | * All other marks are deleted before the mark is set. You can achieve |
1482 | * the same by calling |
1483 | * \code |
1484 | * clearMark(line); |
1485 | * addMark(line, markType); |
1486 | * \endcode |
1487 | * \param line line to set the mark |
1488 | * \param markType mark type |
1489 | * \see clearMark(), addMark(), mark() |
1490 | */ |
1491 | virtual void setMark(int line, uint markType) = 0; |
1492 | |
1493 | /** |
1494 | * Clear all marks set in the \p line. |
1495 | * \param line line to clear marks |
1496 | * \see clearMarks(), removeMark(), addMark() |
1497 | */ |
1498 | virtual void clearMark(int line) = 0; |
1499 | |
1500 | /** |
1501 | * Add marks of type \p markType to \p line. Existing marks on this line |
1502 | * are preserved. If the mark \p markType already is set, nothing |
1503 | * happens. |
1504 | * \param line line to set the mark |
1505 | * \param markType mark type |
1506 | * \see removeMark(), setMark() |
1507 | */ |
1508 | virtual void addMark(int line, uint markType) = 0; |
1509 | |
1510 | /** |
1511 | * Remove the mark mask of type \p markType from \p line. |
1512 | * \param line line to remove the mark |
1513 | * \param markType mark type to be removed |
1514 | * \see clearMark() |
1515 | */ |
1516 | virtual void removeMark(int line, uint markType) = 0; |
1517 | |
1518 | /** |
1519 | * Get a hash holding all marks in the document. |
1520 | * The hash key for a mark is its line. |
1521 | * \return a hash holding all marks in the document |
1522 | * |
1523 | * KF6 TODO: Change Mark* to Mark. No need for pointer here. |
1524 | */ |
1525 | virtual const QHash<int, KTextEditor::Mark *> &marks() = 0; |
1526 | |
1527 | /** |
1528 | * Clear all marks in the entire document. |
1529 | * \see clearMark(), removeMark() |
1530 | */ |
1531 | /// TODO: dominik: add argument unit mask = 0 |
1532 | virtual void clearMarks() = 0; |
1533 | |
1534 | /** |
1535 | * Get the number of predefined mark types we have so far. |
1536 | * \note FIXME: If you change this you have to make sure katepart |
1537 | * supports the new size! |
1538 | * \return number of reserved marker types |
1539 | */ |
1540 | static int reservedMarkersCount() |
1541 | { |
1542 | return 7; |
1543 | } |
1544 | |
1545 | /** |
1546 | * Predefined mark types. |
1547 | * |
1548 | * To add a new standard mark type, edit this interface and document |
1549 | * the type. |
1550 | */ |
1551 | enum MarkTypes { |
1552 | /** Bookmark */ |
1553 | markType01 = 0x1, |
1554 | /** Breakpoint active */ |
1555 | markType02 = 0x2, |
1556 | /** Breakpoint reached */ |
1557 | markType03 = 0x4, |
1558 | /** Breakpoint disabled */ |
1559 | markType04 = 0x8, |
1560 | /** Execution mark */ |
1561 | markType05 = 0x10, |
1562 | /** Warning */ |
1563 | markType06 = 0x20, |
1564 | /** Error */ |
1565 | markType07 = 0x40, |
1566 | |
1567 | markType08 = 0x80, |
1568 | markType09 = 0x100, |
1569 | markType10 = 0x200, |
1570 | markType11 = 0x400, |
1571 | markType12 = 0x800, |
1572 | markType13 = 0x1000, |
1573 | markType14 = 0x2000, |
1574 | markType15 = 0x4000, |
1575 | markType16 = 0x8000, |
1576 | markType17 = 0x10000, |
1577 | markType18 = 0x20000, |
1578 | markType19 = 0x40000, |
1579 | markType20 = 0x80000, |
1580 | markType21 = 0x100000, |
1581 | markType22 = 0x200000, |
1582 | markType23 = 0x400000, |
1583 | markType24 = 0x800000, |
1584 | markType25 = 0x1000000, |
1585 | markType26 = 0x2000000, |
1586 | markType27 = 0x4000000, |
1587 | markType28 = 0x8000000, |
1588 | markType29 = 0x10000000, |
1589 | markType30 = 0x20000000, |
1590 | markType31 = 0x40000000, |
1591 | markType32 = 0x80000000, |
1592 | /* reserved marks */ |
1593 | Bookmark = markType01, |
1594 | BreakpointActive = markType02, |
1595 | BreakpointReached = markType03, |
1596 | BreakpointDisabled = markType04, |
1597 | Execution = markType05, |
1598 | Warning = markType06, |
1599 | Error = markType07, |
1600 | SearchMatch = markType32, |
1601 | }; |
1602 | |
1603 | /* |
1604 | * Methods to modify mark properties. |
1605 | */ |
1606 | public: |
1607 | /** |
1608 | * Set the \p mark's description to \p text. |
1609 | * \param mark mark to set the description |
1610 | * \param text new descriptive text |
1611 | * \see markDescription(), setMarkPixmap() |
1612 | */ |
1613 | virtual void setMarkDescription(MarkTypes mark, const QString &text) = 0; |
1614 | |
1615 | /** |
1616 | * Get the \p mark's description to text. |
1617 | * \param mark mark to set the description |
1618 | * \return text of the given \p mark or QString(), if the entry does not |
1619 | * exist |
1620 | * \see setMarkDescription(), setMarkPixmap() |
1621 | */ |
1622 | virtual QString markDescription(MarkTypes mark) const = 0; |
1623 | |
1624 | /** |
1625 | * Set the mark mask the user is allowed to toggle to \p markMask. |
1626 | * I.e. concatenate all editable marks with a logical OR. If the user should |
1627 | * be able to add a bookmark and set a breakpoint with the context menu in |
1628 | * the icon pane, you have to call |
1629 | * \code |
1630 | * // iface is of Type KTextEditor::MarkInterface* |
1631 | * // only make bookmark and breakpoint editable |
1632 | * iface->setEditableMarks( MarkInterface::Bookmark | |
1633 | * MarkInterface::BreakpointActive ); |
1634 | * |
1635 | * // or preserve last settings, and add bookmark and breakpoint |
1636 | * iface->setEditableMarks( iface->editableMarks() | |
1637 | * MarkInterface::Bookmark | |
1638 | * MarkInterface::BreakpointActive ); |
1639 | * \endcode |
1640 | * \param markMask bitmap pattern |
1641 | * \see editableMarks(), setMarkPixmap(), setMarkDescription() |
1642 | */ |
1643 | virtual void setEditableMarks(uint markMask) = 0; |
1644 | |
1645 | /** |
1646 | * Get, which marks can be toggled by the user. |
1647 | * The returned value is a mark mask containing all editable marks combined |
1648 | * with a logical OR. |
1649 | * \return mark mask containing all editable marks |
1650 | * \see setEditableMarks() |
1651 | */ |
1652 | virtual uint editableMarks() const = 0; |
1653 | |
1654 | /** |
1655 | * Possible actions on a mark. |
1656 | * \see markChanged() |
1657 | */ |
1658 | enum MarkChangeAction { |
1659 | MarkAdded = 0, /**< action: a mark was added. */ |
1660 | MarkRemoved = 1 /**< action: a mark was removed. */ |
1661 | }; |
1662 | |
1663 | /** |
1664 | * Set the \p mark's icon to \p icon. |
1665 | * \param markType mark type to which the icon will be attached |
1666 | * \param icon new icon |
1667 | * \see setMarkDescription() |
1668 | */ |
1669 | virtual void setMarkIcon(MarkTypes markType, const QIcon &icon) = 0; |
1670 | |
1671 | /** |
1672 | * Get the \p mark's icon. |
1673 | * \param markType mark type. If the icon does not exist the resulting is null |
1674 | * (check with QIcon::isNull()). |
1675 | * \see setMarkDescription() |
1676 | */ |
1677 | virtual QIcon markIcon(MarkTypes markType) const = 0; |
1678 | |
1679 | Q_SIGNALS: |
1680 | /** |
1681 | * The \p document emits this signal whenever a mark mask changed. |
1682 | * \param document document which emitted this signal |
1683 | * \see markChanged() |
1684 | */ |
1685 | void marksChanged(KTextEditor::Document *document); |
1686 | |
1687 | /** |
1688 | * The \p document emits this signal whenever the \p mark changes. |
1689 | * \param document the document which emitted the signal |
1690 | * \param mark changed mark |
1691 | * \param action action, either removed or added |
1692 | * \see marksChanged() |
1693 | */ |
1694 | void markChanged(KTextEditor::Document *document, KTextEditor::Mark mark, KTextEditor::Document::MarkChangeAction action); |
1695 | |
1696 | /** |
1697 | * The \p document emits this signal whenever the \p mark is hovered using the mouse, |
1698 | * and the receiver may show a tooltip. |
1699 | * \param document the document which emitted the signal |
1700 | * \param mark mark that was hovered |
1701 | * \param position mouse position during the hovering |
1702 | * \param handled set this to 'true' if this event was handled externally |
1703 | */ |
1704 | void markToolTipRequested(KTextEditor::Document *document, KTextEditor::Mark mark, QPoint position, bool &handled); |
1705 | |
1706 | /** |
1707 | * The \p document emits this signal whenever the \p mark is right-clicked to show a context menu. |
1708 | * The receiver may show an own context menu instead of the kate internal one. |
1709 | * \param document the document which emitted the signal |
1710 | * \param mark mark that was right-clicked |
1711 | * \param pos position where the menu should be started |
1712 | * \param handled set this to 'true' if this event was handled externally, and kate should not create an own context menu. |
1713 | */ |
1714 | void (KTextEditor::Document *document, KTextEditor::Mark mark, QPoint pos, bool &handled); |
1715 | |
1716 | /** |
1717 | * The \p document emits this signal whenever the \p mark is left-clicked. |
1718 | * \param document the document which emitted the signal |
1719 | * \param mark mark that was right-clicked |
1720 | * \param handled set this to 'true' if this event was handled externally, and kate should not do own handling of the left click. |
1721 | */ |
1722 | void markClicked(KTextEditor::Document *document, KTextEditor::Mark mark, bool &handled); |
1723 | //!\} |
1724 | |
1725 | /** |
1726 | * \name Annotation Interface |
1727 | * |
1728 | * \{ |
1729 | */ |
1730 | public: |
1731 | /** |
1732 | * Sets a new \ref AnnotationModel for this document to provide |
1733 | * annotation information for each line. |
1734 | * |
1735 | * \param model the new AnnotationModel |
1736 | */ |
1737 | virtual void setAnnotationModel(AnnotationModel *model) = 0; |
1738 | |
1739 | /** |
1740 | * returns the currently set \ref AnnotationModel or 0 if there's none |
1741 | * set |
1742 | * @returns the current \ref AnnotationModel |
1743 | */ |
1744 | virtual AnnotationModel *annotationModel() const = 0; |
1745 | //!\} |
1746 | |
1747 | private: |
1748 | /** |
1749 | * private d-pointer, pointing to the internal implementation |
1750 | */ |
1751 | DocumentPrivate *const d; |
1752 | }; |
1753 | |
1754 | } |
1755 | |
1756 | #endif |
1757 | |