1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 2001-2004 Christoph Cullmann <cullmann@kde.org> |
3 | Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org> |
4 | Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> |
5 | Copyright (C) 2006 Hamish Rodda <rodda@kde.org> |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License version 2 as published by the Free Software Foundation. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #ifndef _KATE_DOCUMENT_H_ |
23 | #define _KATE_DOCUMENT_H_ |
24 | |
25 | #include <QPointer> |
26 | #include <QStack> |
27 | #include <QTimer> |
28 | |
29 | #include <KJob> |
30 | |
31 | #include <ktexteditor/document.h> |
32 | #include <ktexteditor/markinterface.h> |
33 | #include <ktexteditor/modificationinterface.h> |
34 | #include <ktexteditor/configinterface.h> |
35 | #include <ktexteditor/annotationinterface.h> |
36 | #include <ktexteditor/movinginterface.h> |
37 | #include <ktexteditor/message.h> |
38 | #include <ktexteditor/mainwindow.h> |
39 | #include <ktexteditor/inlinenoteinterface.h> |
40 | |
41 | #include <ktexteditor_export.h> |
42 | #include "katetextline.h" |
43 | |
44 | class KateTemplateHandler; |
45 | namespace KTextEditor |
46 | { |
47 | class Plugin; |
48 | class Attribute; |
49 | class TemplateScript; |
50 | } |
51 | |
52 | namespace KIO |
53 | { |
54 | class TransferJob; |
55 | } |
56 | |
57 | namespace Kate |
58 | { |
59 | class SwapFile; |
60 | } |
61 | |
62 | class KateBuffer; |
63 | namespace KTextEditor { class ViewPrivate; } |
64 | class KateDocumentConfig; |
65 | class KateHighlighting; |
66 | class KateUndoManager; |
67 | class KateOnTheFlyChecker; |
68 | class KateDocumentTest; |
69 | |
70 | class KateAutoIndent; |
71 | class KateModOnHdPrompt; |
72 | class KToggleAction; |
73 | |
74 | /** |
75 | * @brief Backend of KTextEditor::Document related public KTextEditor interfaces. |
76 | * |
77 | * @warning This file is @e private API and not part of the public |
78 | * KTextEditor interfaces. |
79 | */ |
80 | class KTEXTEDITOR_EXPORT KTextEditor::DocumentPrivate : public KTextEditor::Document, |
81 | public KTextEditor::MarkInterface, |
82 | public KTextEditor::ModificationInterface, |
83 | public KTextEditor::ConfigInterface, |
84 | public KTextEditor::AnnotationInterface, |
85 | public KTextEditor::MovingInterface, |
86 | private KTextEditor::MovingRangeFeedback |
87 | { |
88 | Q_OBJECT |
89 | Q_INTERFACES(KTextEditor::MarkInterface) |
90 | Q_INTERFACES(KTextEditor::ModificationInterface) |
91 | Q_INTERFACES(KTextEditor::AnnotationInterface) |
92 | Q_INTERFACES(KTextEditor::ConfigInterface) |
93 | Q_INTERFACES(KTextEditor::MovingInterface) |
94 | |
95 | friend class KTextEditor::Document; |
96 | friend class ::KateDocumentTest; |
97 | friend class ::KateBuffer; |
98 | |
99 | public: |
100 | explicit DocumentPrivate(bool bSingleViewMode = false, bool bReadOnly = false, |
101 | QWidget *parentWidget = nullptr, QObject * = nullptr); |
102 | ~DocumentPrivate() override; |
103 | |
104 | using ReadWritePart::closeUrl; |
105 | bool closeUrl() override; |
106 | |
107 | bool openUrl(const QUrl &url) override; |
108 | |
109 | KTextEditor::Range rangeOnLine(KTextEditor::Range range, int line) const; |
110 | |
111 | private: |
112 | void showAndSetOpeningErrorAccess(); |
113 | /* |
114 | * Overload this to have on-demand view creation |
115 | */ |
116 | public: |
117 | /** |
118 | * @return The widget defined by this part, set by setWidget(). |
119 | */ |
120 | QWidget *widget() override; |
121 | |
122 | public: |
123 | bool readOnly() const |
124 | { |
125 | return m_bReadOnly; |
126 | } |
127 | bool singleViewMode() const |
128 | { |
129 | return m_bSingleViewMode; |
130 | } |
131 | |
132 | private: |
133 | // only to make part work, don't change it ! |
134 | const bool m_bSingleViewMode; |
135 | const bool m_bReadOnly; |
136 | |
137 | // |
138 | // KTextEditor::Document stuff |
139 | // |
140 | public: |
141 | KTextEditor::View *createView(QWidget *parent, KTextEditor::MainWindow *mainWindow = nullptr) override; |
142 | |
143 | QList<KTextEditor::View *> views() const override |
144 | { |
145 | return m_viewsCache; |
146 | } |
147 | |
148 | virtual KTextEditor::View *activeView() const |
149 | { |
150 | return m_activeView; |
151 | } |
152 | |
153 | private: |
154 | QHash<KTextEditor::View *, KTextEditor::ViewPrivate *> m_views; |
155 | KTextEditor::View *m_activeView = nullptr; |
156 | |
157 | // |
158 | // KTextEditor::EditInterface stuff |
159 | // |
160 | public Q_SLOTS: |
161 | bool setText(const QString &) override; |
162 | bool setText(const QStringList &text) override; |
163 | bool clear() override; |
164 | |
165 | bool insertText(const KTextEditor::Cursor &position, const QString &s, bool block = false) override; |
166 | bool insertText(const KTextEditor::Cursor &position, const QStringList &text, bool block = false) override; |
167 | |
168 | bool insertLine(int line, const QString &s) override; |
169 | bool insertLines(int line, const QStringList &s) override; |
170 | |
171 | bool removeText(const KTextEditor::Range &range, bool block = false) override; |
172 | bool removeLine(int line) override; |
173 | |
174 | bool replaceText(const KTextEditor::Range &range, const QString &s, bool block = false) override; |
175 | |
176 | // unhide method... |
177 | bool replaceText(const KTextEditor::Range &r, const QStringList &l, bool b) override |
178 | { |
179 | return KTextEditor::Document::replaceText(r, l, b); |
180 | } |
181 | |
182 | public: |
183 | bool isEditingTransactionRunning() const override; |
184 | QString text(const KTextEditor::Range &range, bool blockwise = false) const override; |
185 | QStringList textLines(const KTextEditor::Range &range, bool block = false) const override; |
186 | QString text() const override; |
187 | QString line(int line) const override; |
188 | QChar characterAt(const KTextEditor::Cursor &position) const override; |
189 | QString wordAt(const KTextEditor::Cursor &cursor) const override; |
190 | KTextEditor::Range wordRangeAt(const KTextEditor::Cursor &cursor) const override; |
191 | bool isValidTextPosition(const KTextEditor::Cursor& cursor) const override; |
192 | int lines() const override; |
193 | bool isLineModified(int line) const override; |
194 | bool isLineSaved(int line) const override; |
195 | bool isLineTouched(int line) const override; |
196 | KTextEditor::Cursor documentEnd() const override; |
197 | int totalCharacters() const override; |
198 | int lineLength(int line) const override; |
199 | |
200 | Q_SIGNALS: |
201 | void (const KTextEditor::Cursor &position, const QString &text); |
202 | |
203 | /** |
204 | * The \p document emits this signal whenever text was inserted. The |
205 | * insertion occurred at range.start(), and new text now occupies up to |
206 | * range.end(). |
207 | * \param document document which emitted this signal |
208 | * \param range range that the newly inserted text occupies |
209 | * \see insertText(), insertLine() |
210 | */ |
211 | void textInserted(KTextEditor::Document *document, const KTextEditor::Range &range); |
212 | |
213 | /** |
214 | * The \p document emits this signal whenever \p range was removed, i.e. |
215 | * text was removed. |
216 | * \param document document which emitted this signal |
217 | * \param range range that the removed text previously occupied |
218 | * \param oldText the text that has been removed |
219 | * \see removeText(), removeLine(), clear() |
220 | */ |
221 | void textRemoved(KTextEditor::Document *document, const KTextEditor::Range &range, const QString &oldText); |
222 | |
223 | public: |
224 | //BEGIN editStart/editEnd (start, end, undo, cursor update, view update) |
225 | /** |
226 | * Enclose editor actions with @p editStart() and @p editEnd() to group |
227 | * them. |
228 | */ |
229 | bool editStart(); |
230 | |
231 | /** |
232 | * Alias for @p editStart() |
233 | */ |
234 | void editBegin() |
235 | { |
236 | editStart(); |
237 | } |
238 | |
239 | /** |
240 | * End a editor operation. |
241 | * @see editStart() |
242 | */ |
243 | bool editEnd(); |
244 | |
245 | void pushEditState(); |
246 | void popEditState(); |
247 | |
248 | virtual bool startEditing() |
249 | { |
250 | return editStart(); |
251 | } |
252 | virtual bool finishEditing() |
253 | { |
254 | return editEnd(); |
255 | } |
256 | |
257 | //END editStart/editEnd |
258 | |
259 | void inputMethodStart(); |
260 | void inputMethodEnd(); |
261 | |
262 | //BEGIN LINE BASED INSERT/REMOVE STUFF (editStart() and editEnd() included) |
263 | /** |
264 | * Add a string in the given line/column |
265 | * @param line line number |
266 | * @param col column |
267 | * @param s string to be inserted |
268 | * @return true on success |
269 | */ |
270 | bool editInsertText(int line, int col, const QString &s); |
271 | |
272 | /** |
273 | * Remove a string in the given line/column |
274 | * @param line line number |
275 | * @param col column |
276 | * @param len length of text to be removed |
277 | * @return true on success |
278 | */ |
279 | bool editRemoveText(int line, int col, int len); |
280 | |
281 | /** |
282 | * Mark @p line as @p autowrapped. This is necessary if static word warp is |
283 | * enabled, because we have to know whether to insert a new line or add the |
284 | * wrapped words to the following line. |
285 | * @param line line number |
286 | * @param autowrapped autowrapped? |
287 | * @return true on success |
288 | */ |
289 | bool editMarkLineAutoWrapped(int line, bool autowrapped); |
290 | |
291 | /** |
292 | * Wrap @p line. If @p newLine is true, ignore the textline's flag |
293 | * KateTextLine::flagAutoWrapped and force a new line. Whether a new line |
294 | * was needed/added you can grab with @p newLineAdded. |
295 | * @param line line number |
296 | * @param col column |
297 | * @param newLine if true, force a new line |
298 | * @param newLineAdded return value is true, if new line was added (may be 0) |
299 | * @return true on success |
300 | */ |
301 | bool editWrapLine(int line, int col, bool newLine = true, bool *newLineAdded = nullptr); |
302 | |
303 | /** |
304 | * Unwrap @p line. If @p removeLine is true, we force to join the lines. If |
305 | * @p removeLine is true, @p length is ignored (eg not needed). |
306 | * @param line line number |
307 | * @param removeLine if true, force to remove the next line |
308 | * @return true on success |
309 | */ |
310 | bool editUnWrapLine(int line, bool removeLine = true, int length = 0); |
311 | |
312 | /** |
313 | * Insert a string at the given line. |
314 | * @param line line number |
315 | * @param s string to insert |
316 | * @return true on success |
317 | */ |
318 | bool editInsertLine(int line, const QString &s); |
319 | |
320 | /** |
321 | * Remove a line |
322 | * @param line line number |
323 | * @return true on success |
324 | */ |
325 | bool editRemoveLine(int line); |
326 | |
327 | bool editRemoveLines(int from, int to); |
328 | |
329 | /** |
330 | * Warp a line |
331 | * @param startLine line to begin wrapping |
332 | * @param endLine line to stop wrapping |
333 | * @return true on success |
334 | */ |
335 | bool wrapText(int startLine, int endLine); |
336 | |
337 | /** |
338 | * Wrap lines touched by the selection with respect of existing paragraphs. |
339 | * To do so will the paragraph prior to the wrap joined as one single line |
340 | * which cause an almost perfect wrapped paragraph as long as there are no |
341 | * unneeded spaces exist or some formatting like this comment block. |
342 | * Without any selection the current line is wrapped. |
343 | * Empty lines around each paragraph are untouched. |
344 | * @param first line to begin wrapping |
345 | * @param last line to stop wrapping |
346 | * @return true on success |
347 | */ |
348 | bool wrapParagraph(int first, int last); |
349 | //END LINE BASED INSERT/REMOVE STUFF |
350 | |
351 | Q_SIGNALS: |
352 | /** |
353 | * Emitted when text from @p line was wrapped at position pos onto line @p nextLine. |
354 | */ |
355 | void editLineWrapped(int line, int col, int len); |
356 | |
357 | /** |
358 | * Emitted each time text from @p nextLine was upwrapped onto @p line. |
359 | */ |
360 | void editLineUnWrapped(int line, int col); |
361 | |
362 | public: |
363 | bool isEditRunning() const; |
364 | |
365 | void setUndoMergeAllEdits(bool merge); |
366 | |
367 | enum EditingPositionKind { Previous, Next }; |
368 | |
369 | /** |
370 | *Returns the next or previous position cursor in this document from the stack depending on the argument passed. |
371 | *@return cursor invalid if m_editingStack empty |
372 | */ |
373 | KTextEditor::Cursor lastEditingPosition(EditingPositionKind nextOrPrevious, KTextEditor::Cursor); |
374 | |
375 | private: |
376 | int editSessionNumber = 0; |
377 | QStack<int> editStateStack; |
378 | bool editIsRunning = false; |
379 | bool m_undoMergeAllEdits = false; |
380 | KTextEditor::Cursor m_editLastChangeStartCursor = KTextEditor::Cursor::invalid(); |
381 | QStack<QSharedPointer<KTextEditor::MovingCursor>> m_editingStack; |
382 | int m_editingStackPosition = -1; |
383 | |
384 | // |
385 | // KTextEditor::UndoInterface stuff |
386 | // |
387 | public Q_SLOTS: |
388 | void undo(); |
389 | void redo(); |
390 | |
391 | /** |
392 | * Removes all the elements in m_editingStack of the respective document. |
393 | */ |
394 | void clearEditingPosStack(); |
395 | |
396 | /** |
397 | * Saves the editing positions into the stack. |
398 | * If the consecutive editings happens in the same line, then remove |
399 | * the previous and add the new one with updated column no. |
400 | */ |
401 | void saveEditingPositions(const KTextEditor::Cursor &cursor); |
402 | |
403 | public: |
404 | uint undoCount() const; |
405 | uint redoCount() const; |
406 | |
407 | KateUndoManager *undoManager() |
408 | { |
409 | return m_undoManager; |
410 | } |
411 | |
412 | protected: |
413 | KateUndoManager *const m_undoManager; |
414 | |
415 | Q_SIGNALS: |
416 | void undoChanged(); |
417 | |
418 | public: |
419 | QVector<KTextEditor::Range> searchText( |
420 | const KTextEditor::Range &range, |
421 | const QString &pattern, |
422 | const KTextEditor::SearchOptions options) const; |
423 | |
424 | private: |
425 | /** |
426 | * Return a widget suitable to be used as a dialog parent. |
427 | */ |
428 | QWidget *dialogParent(); |
429 | |
430 | /* |
431 | * Access to the mode/highlighting subsystem |
432 | */ |
433 | public: |
434 | /** |
435 | * @copydoc KTextEditor::Document::defaultStyleAt() |
436 | */ |
437 | KTextEditor::DefaultStyle defaultStyleAt(const KTextEditor::Cursor &position) const override; |
438 | |
439 | /** |
440 | * Return the name of the currently used mode |
441 | * \return name of the used mode |
442 | */ |
443 | QString mode() const override; |
444 | |
445 | /** |
446 | * Return the name of the currently used mode |
447 | * \return name of the used mode |
448 | */ |
449 | QString highlightingMode() const override; |
450 | |
451 | /** |
452 | * Return a list of the names of all possible modes |
453 | * \return list of mode names |
454 | */ |
455 | QStringList modes() const override; |
456 | |
457 | /** |
458 | * Return a list of the names of all possible modes |
459 | * \return list of mode names |
460 | */ |
461 | QStringList highlightingModes() const override; |
462 | |
463 | /** |
464 | * Set the current mode of the document by giving its name |
465 | * \param name name of the mode to use for this document |
466 | * \return \e true on success, otherwise \e false |
467 | */ |
468 | bool setMode(const QString &name) override; |
469 | |
470 | /** |
471 | * Set the current mode of the document by giving its name |
472 | * \param name name of the mode to use for this document |
473 | * \return \e true on success, otherwise \e false |
474 | */ |
475 | bool setHighlightingMode(const QString &name) override; |
476 | /** |
477 | * Returns the name of the section for a highlight given its @p index in the highlight |
478 | * list (as returned by highlightModes()). |
479 | * You can use this function to build a tree of the highlight names, organized in sections. |
480 | * \param index in the highlight list for which to find the section name. |
481 | */ |
482 | QString highlightingModeSection(int index) const override; |
483 | |
484 | /** |
485 | * Returns the name of the section for a mode given its @p index in the highlight |
486 | * list (as returned by modes()). |
487 | * You can use this function to build a tree of the mode names, organized in sections. |
488 | * \param index index in the highlight list for which to find the section name. |
489 | */ |
490 | QString modeSection(int index) const override; |
491 | |
492 | /* |
493 | * Helpers.... |
494 | */ |
495 | public: |
496 | void bufferHlChanged(); |
497 | |
498 | /** |
499 | * allow to mark, that we changed hl on user wish and should not reset it |
500 | * atm used for the user visible menu to select highlightings |
501 | */ |
502 | void setDontChangeHlOnSave(); |
503 | |
504 | /** |
505 | * Set that the BOM marker is forced via the tool menu |
506 | */ |
507 | void bomSetByUser(); |
508 | |
509 | public: |
510 | /** |
511 | * Read session settings from the given \p config. |
512 | * |
513 | * Known flags: |
514 | * "SkipUrl" => don't save/restore the file |
515 | * "SkipMode" => don't save/restore the mode |
516 | * "SkipHighlighting" => don't save/restore the highlighting |
517 | * "SkipEncoding" => don't save/restore the encoding |
518 | * |
519 | * \param config read the session settings from this KConfigGroup |
520 | * \param flags additional flags |
521 | * \see writeSessionConfig() |
522 | */ |
523 | void readSessionConfig(const KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) override; |
524 | |
525 | /** |
526 | * Write session settings to the \p config. |
527 | * See readSessionConfig() for more details. |
528 | * |
529 | * \param config write the session settings to this KConfigGroup |
530 | * \param flags additional flags |
531 | * \see readSessionConfig() |
532 | */ |
533 | void writeSessionConfig(KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) override; |
534 | |
535 | Q_SIGNALS: |
536 | void configChanged(); |
537 | |
538 | // |
539 | // KTextEditor::MarkInterface |
540 | // |
541 | public Q_SLOTS: |
542 | void setMark(int line, uint markType) override; |
543 | void clearMark(int line) override; |
544 | |
545 | void addMark(int line, uint markType) override; |
546 | void removeMark(int line, uint markType) override; |
547 | |
548 | void clearMarks() override; |
549 | |
550 | void requestMarkTooltip(int line, QPoint position); |
551 | |
552 | ///Returns true if the click on the mark should not be further processed |
553 | bool handleMarkClick(int line); |
554 | |
555 | ///Returns true if the context-menu event should not further be processed |
556 | bool handleMarkContextMenu(int line, QPoint position); |
557 | |
558 | void setMarkPixmap(MarkInterface::MarkTypes, const QPixmap &) override; |
559 | |
560 | void setMarkDescription(MarkInterface::MarkTypes, const QString &) override; |
561 | |
562 | void setEditableMarks(uint markMask) override; |
563 | |
564 | public: |
565 | uint mark(int line) override; |
566 | const QHash<int, KTextEditor::Mark *> &marks() override; |
567 | QPixmap markPixmap(MarkInterface::MarkTypes) const override; |
568 | QString markDescription(MarkInterface::MarkTypes) const override; |
569 | virtual QColor markColor(MarkInterface::MarkTypes) const; |
570 | uint editableMarks() const override; |
571 | |
572 | Q_SIGNALS: |
573 | void markToolTipRequested(KTextEditor::Document *document, KTextEditor::Mark mark, QPoint position, bool &handled); |
574 | |
575 | void (KTextEditor::Document *document, KTextEditor::Mark mark, QPoint pos, bool &handled); |
576 | |
577 | void markClicked(KTextEditor::Document *document, KTextEditor::Mark mark, bool &handled); |
578 | |
579 | void marksChanged(KTextEditor::Document *) override; |
580 | void markChanged(KTextEditor::Document *, KTextEditor::Mark, KTextEditor::MarkInterface::MarkChangeAction) override; |
581 | |
582 | private: |
583 | QHash<int, KTextEditor::Mark *> m_marks; |
584 | QHash<int, QPixmap> m_markPixmaps; |
585 | QHash<int, QString> m_markDescriptions; |
586 | uint m_editableMarks = markType01; |
587 | |
588 | // KTextEditor::PrintInterface |
589 | // |
590 | public Q_SLOTS: |
591 | bool print() override; |
592 | void printPreview() override; |
593 | |
594 | // |
595 | // KTextEditor::DocumentInfoInterface ( ### unfinished ) |
596 | // |
597 | public: |
598 | /** |
599 | * Tries to detect mime-type based on file name and content of buffer. |
600 | * |
601 | * @return the name of the mimetype for the document. |
602 | */ |
603 | QString mimeType() override; |
604 | |
605 | // |
606 | // once was KTextEditor::VariableInterface |
607 | // |
608 | public: |
609 | /** |
610 | * Returns the value for the variable @p name. |
611 | * If the Document does not have a variable called @p name, |
612 | * an empty QString() is returned. |
613 | * |
614 | * @param name variable to query |
615 | * @return value of the variable @p name |
616 | * @see setVariable() |
617 | */ |
618 | virtual QString variable(const QString &name) const; |
619 | |
620 | /** |
621 | * Set the variable @p name to @p value. Setting and changing a variable |
622 | * has immediate effect on the Document. For instance, setting the variable |
623 | * @e indent-mode to @e cstyle will immediately cause the Document to load |
624 | * the C Style indenter. |
625 | * |
626 | * @param name the variable name |
627 | * @param value the value to be set |
628 | * @see variable() |
629 | */ |
630 | virtual void setVariable(const QString &name, const QString &value); |
631 | |
632 | private: |
633 | QMap<QString, QString> m_storedVariables; |
634 | |
635 | // |
636 | // MovingInterface API |
637 | // |
638 | public: |
639 | /** |
640 | * Create a new moving cursor for this document. |
641 | * @param position position of the moving cursor to create |
642 | * @param insertBehavior insertion behavior |
643 | * @return new moving cursor for the document |
644 | */ |
645 | KTextEditor::MovingCursor *newMovingCursor(const KTextEditor::Cursor &position, KTextEditor::MovingCursor::InsertBehavior insertBehavior = KTextEditor::MovingCursor::MoveOnInsert) override; |
646 | |
647 | /** |
648 | * Create a new moving range for this document. |
649 | * @param range range of the moving range to create |
650 | * @param insertBehaviors insertion behaviors |
651 | * @param emptyBehavior behavior on becoming empty |
652 | * @return new moving range for the document |
653 | */ |
654 | KTextEditor::MovingRange *newMovingRange(const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors = KTextEditor::MovingRange::DoNotExpand |
655 | , KTextEditor::MovingRange::EmptyBehavior emptyBehavior = KTextEditor::MovingRange::AllowEmpty) override; |
656 | |
657 | /** |
658 | * Current revision |
659 | * @return current revision |
660 | */ |
661 | qint64 revision() const override; |
662 | |
663 | /** |
664 | * Last revision the buffer got successful saved |
665 | * @return last revision buffer got saved, -1 if none |
666 | */ |
667 | qint64 lastSavedRevision() const override; |
668 | |
669 | /** |
670 | * Lock a revision, this will keep it around until released again. |
671 | * But all revisions will always be cleared on buffer clear() (and therefor load()) |
672 | * @param revision revision to lock |
673 | */ |
674 | void lockRevision(qint64 revision) override; |
675 | |
676 | /** |
677 | * Release a revision. |
678 | * @param revision revision to release |
679 | */ |
680 | void unlockRevision(qint64 revision) override; |
681 | |
682 | /** |
683 | * Transform a cursor from one revision to an other. |
684 | * @param cursor cursor to transform |
685 | * @param insertBehavior behavior of this cursor on insert of text at its position |
686 | * @param fromRevision from this revision we want to transform |
687 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
688 | */ |
689 | void transformCursor(KTextEditor::Cursor &cursor, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1) override; |
690 | |
691 | /** |
692 | * Transform a cursor from one revision to an other. |
693 | * @param line line number of the cursor to transform |
694 | * @param column column number of the cursor to transform |
695 | * @param insertBehavior behavior of this cursor on insert of text at its position |
696 | * @param fromRevision from this revision we want to transform |
697 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
698 | */ |
699 | void transformCursor(int &line, int &column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1) override; |
700 | |
701 | /** |
702 | * Transform a range from one revision to an other. |
703 | * @param range range to transform |
704 | * @param insertBehaviors behavior of this range on insert of text at its position |
705 | * @param emptyBehavior behavior on becoming empty |
706 | * @param fromRevision from this revision we want to transform |
707 | * @param toRevision to this revision we want to transform, default of -1 is current revision |
708 | */ |
709 | void transformRange(KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors, KTextEditor::MovingRange::EmptyBehavior emptyBehavior, qint64 fromRevision, qint64 toRevision = -1) override; |
710 | |
711 | // |
712 | // MovingInterface Signals |
713 | // |
714 | Q_SIGNALS: |
715 | /** |
716 | * This signal is emitted before the cursors/ranges/revisions of a document are destroyed as the document is deleted. |
717 | * @param document the document which the interface belongs too which is in the process of being deleted |
718 | */ |
719 | void aboutToDeleteMovingInterfaceContent(KTextEditor::Document *document); |
720 | |
721 | /** |
722 | * This signal is emitted before the ranges of a document are invalidated and the revisions are deleted as the document is cleared (for example on load/reload). |
723 | * While this signal is emitted, still the old document content is around before the clear. |
724 | * @param document the document which the interface belongs too which will invalidate its data |
725 | */ |
726 | void aboutToInvalidateMovingInterfaceContent(KTextEditor::Document *document); |
727 | |
728 | // |
729 | // Annotation Interface |
730 | // |
731 | public: |
732 | |
733 | void setAnnotationModel(KTextEditor::AnnotationModel *model) override; |
734 | KTextEditor::AnnotationModel *annotationModel() const override; |
735 | |
736 | Q_SIGNALS: |
737 | void annotationModelChanged(KTextEditor::AnnotationModel *, KTextEditor::AnnotationModel *); |
738 | |
739 | private: |
740 | KTextEditor::AnnotationModel *m_annotationModel = nullptr; |
741 | |
742 | // |
743 | // KParts::ReadWrite stuff |
744 | // |
745 | public: |
746 | /** |
747 | * open the file obtained by the kparts framework |
748 | * the framework abstracts the loading of remote files |
749 | * @return success |
750 | */ |
751 | bool openFile() override; |
752 | |
753 | /** |
754 | * save the file obtained by the kparts framework |
755 | * the framework abstracts the uploading of remote files |
756 | * @return success |
757 | */ |
758 | bool saveFile() override; |
759 | |
760 | void setReadWrite(bool rw = true) override; |
761 | |
762 | void setModified(bool m) override; |
763 | |
764 | bool isAutoReload(); |
765 | KToggleAction* autoReloadToggleAction() { return m_autoReloadMode; }; |
766 | void delayAutoReload(); |
767 | |
768 | private Q_SLOTS: |
769 | void autoReloadToggled(bool b); |
770 | |
771 | private: |
772 | void activateDirWatch(const QString &useFileName = QString()); |
773 | void deactivateDirWatch(); |
774 | |
775 | QString m_dirWatchFile; |
776 | |
777 | /** |
778 | * Make backup copy during saveFile, if configured that way. |
779 | * @return success? else saveFile should return false and not write the file |
780 | */ |
781 | bool createBackupFile(); |
782 | |
783 | public: |
784 | /** |
785 | * Type chars in a view. |
786 | * Will filter out non-printable chars from the realChars array before inserting. |
787 | */ |
788 | bool typeChars(KTextEditor::ViewPrivate *type, const QString &realChars); |
789 | |
790 | /** |
791 | * gets the last line number (lines() - 1) |
792 | */ |
793 | inline int lastLine() const |
794 | { |
795 | return lines() - 1; |
796 | } |
797 | |
798 | // Repaint all of all of the views |
799 | void repaintViews(bool paintOnlyDirty = true); |
800 | |
801 | KateHighlighting *highlight() const; |
802 | |
803 | public Q_SLOTS: |
804 | void tagLines(int start, int end); |
805 | |
806 | private Q_SLOTS: |
807 | void internalHlChanged(); |
808 | |
809 | public: |
810 | void addView(KTextEditor::View *); |
811 | /** removes the view from the list of views. The view is *not* deleted. |
812 | * That's your job. Or, easier, just delete the view in the first place. |
813 | * It will remove itself. TODO: this could be converted to a private slot |
814 | * connected to the view's destroyed() signal. It is not currently called |
815 | * anywhere except from the KTextEditor::ViewPrivate destructor. |
816 | */ |
817 | void removeView(KTextEditor::View *); |
818 | void setActiveView(KTextEditor::View *); |
819 | |
820 | bool ownedView(KTextEditor::ViewPrivate *); |
821 | |
822 | int toVirtualColumn(int line, int column) const; |
823 | int toVirtualColumn(const KTextEditor::Cursor &) const; |
824 | int fromVirtualColumn(int line, int column) const; |
825 | int fromVirtualColumn(const KTextEditor::Cursor &) const; |
826 | |
827 | enum NewLineIndent { Indent, NoIndent }; |
828 | |
829 | void newLine(KTextEditor::ViewPrivate *view, NewLineIndent indent = NewLineIndent::Indent); // Changes input |
830 | void backspace(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor &); |
831 | void del(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor &); |
832 | void transpose(const KTextEditor::Cursor &); |
833 | void paste(KTextEditor::ViewPrivate *view, const QString &text); |
834 | |
835 | public: |
836 | void indent(KTextEditor::Range range, int change); |
837 | void (KTextEditor::ViewPrivate *view, uint line, uint column, int change); |
838 | void align(KTextEditor::ViewPrivate *view, const KTextEditor::Range &range); |
839 | void insertTab(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor &); |
840 | |
841 | enum TextTransform { Uppercase, Lowercase, Capitalize }; |
842 | |
843 | /** |
844 | Handling uppercase, lowercase and capitalize for the view. |
845 | |
846 | If there is a selection, that is transformed, otherwise for uppercase or |
847 | lowercase the character right of the cursor is transformed, for capitalize |
848 | the word under the cursor is transformed. |
849 | */ |
850 | void transform(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor &, TextTransform); |
851 | /** |
852 | Unwrap a range of lines. |
853 | */ |
854 | void joinLines(uint first, uint last); |
855 | |
856 | private: |
857 | bool removeStringFromBeginning(int line, const QString &str); |
858 | bool removeStringFromEnd(int line, const QString &str); |
859 | |
860 | /** |
861 | Expand tabs to spaces in typed text, if enabled. |
862 | @param cursorPos The current cursor position for the inserted characters. |
863 | @param str The typed characters to expand. |
864 | */ |
865 | QString eventuallyReplaceTabs(const KTextEditor::Cursor &cursorPos, const QString &str) const; |
866 | |
867 | /** |
868 | Find the position (line and col) of the next char |
869 | that is not a space. If found line and col point to the found character. |
870 | Otherwise they have both the value -1. |
871 | @param line Line of the character which is examined first. |
872 | @param col Column of the character which is examined first. |
873 | @return True if the specified or a following character is not a space |
874 | Otherwise false. |
875 | */ |
876 | bool nextNonSpaceCharPos(int &line, int &col); |
877 | |
878 | /** |
879 | Find the position (line and col) of the previous char |
880 | that is not a space. If found line and col point to the found character. |
881 | Otherwise they have both the value -1. |
882 | @return True if the specified or a preceding character is not a space. |
883 | Otherwise false. |
884 | */ |
885 | bool previousNonSpaceCharPos(int &line, int &col); |
886 | |
887 | /** |
888 | * Sets a comment marker as defined by the language providing the attribute |
889 | * @p attrib on the line @p line |
890 | */ |
891 | void (int line, int attrib = 0); |
892 | /** |
893 | * Removes a comment marker as defined by the language providing the attribute |
894 | * @p attrib on the line @p line |
895 | */ |
896 | bool (int line, int attrib = 0); |
897 | |
898 | /** |
899 | * @see addStartLineCommentToSingleLine. |
900 | */ |
901 | void (int line, int attrib = 0); |
902 | /** |
903 | *@see removeStartLineCommentFromSingleLine. |
904 | */ |
905 | bool (int line, int attrib = 0); |
906 | /** |
907 | *@see removeStartLineCommentFromSingleLine. |
908 | */ |
909 | bool (const KTextEditor::Cursor &start, const KTextEditor::Cursor &end, int attrib = 0); |
910 | |
911 | /** |
912 | * Add a comment marker as defined by the language providing the attribute |
913 | * @p attrib to each line in the selection. |
914 | */ |
915 | void (KTextEditor::ViewPrivate *view, int attrib = 0); |
916 | /** |
917 | * @see addStartStopCommentToSelection. |
918 | */ |
919 | void (KTextEditor::ViewPrivate *view, int attrib = 0); |
920 | |
921 | /** |
922 | * Removes comment markers relevant to the language providing |
923 | * the attribuge @p attrib from each line in the selection. |
924 | * |
925 | * @return whether the operation succeeded. |
926 | */ |
927 | bool (KTextEditor::ViewPrivate *view, int attrib = 0); |
928 | /** |
929 | * @see removeStartStopCommentFromSelection. |
930 | */ |
931 | bool (KTextEditor::ViewPrivate *view, int attrib = 0); |
932 | |
933 | public: |
934 | KTextEditor::Range findMatchingBracket(const KTextEditor::Cursor & start, int maxLines); |
935 | |
936 | public: |
937 | QString documentName() const override |
938 | { |
939 | return m_docName; |
940 | } |
941 | |
942 | private: |
943 | void updateDocName(); |
944 | |
945 | public: |
946 | /** |
947 | * @return whether the document is modified on disk since last saved |
948 | */ |
949 | bool isModifiedOnDisc() |
950 | { |
951 | return m_modOnHd; |
952 | } |
953 | |
954 | void setModifiedOnDisk(ModifiedOnDiskReason reason) override; |
955 | |
956 | void setModifiedOnDiskWarning(bool on) override; |
957 | |
958 | public Q_SLOTS: |
959 | /** |
960 | * Ask the user what to do, if the file has been modified on disk. |
961 | * Reimplemented from KTextEditor::Document. |
962 | */ |
963 | virtual void slotModifiedOnDisk(KTextEditor::View *v = nullptr); |
964 | |
965 | /** |
966 | * Reloads the current document from disk if possible |
967 | */ |
968 | bool documentReload() override; |
969 | |
970 | bool documentSave() override; |
971 | bool documentSaveAs() override; |
972 | bool documentSaveAsWithEncoding(const QString &encoding); |
973 | bool documentSaveCopyAs(); |
974 | |
975 | bool save() override; |
976 | public: |
977 | bool saveAs(const QUrl &url) override; |
978 | |
979 | Q_SIGNALS: |
980 | /** |
981 | * Indicate this file is modified on disk |
982 | * @param doc the KTextEditor::Document object that represents the file on disk |
983 | * @param isModified indicates the file was modified rather than created or deleted |
984 | * @param reason the reason we are emitting the signal. |
985 | */ |
986 | void modifiedOnDisk(KTextEditor::Document *doc, bool isModified, KTextEditor::ModificationInterface::ModifiedOnDiskReason reason) override; |
987 | |
988 | private: |
989 | // helper to handle the embedded notification for externally modified files |
990 | QPointer<KateModOnHdPrompt> m_modOnHdHandler; |
991 | |
992 | private Q_SLOTS: |
993 | void onModOnHdSaveAs(); |
994 | void onModOnHdClose(); |
995 | void onModOnHdReload(); |
996 | void onModOnHdAutoReload(); |
997 | void onModOnHdIgnore(); |
998 | |
999 | public: |
1000 | bool setEncoding(const QString &e) override; |
1001 | QString encoding() const override; |
1002 | |
1003 | public Q_SLOTS: |
1004 | void setWordWrap(bool on); |
1005 | void setWordWrapAt(uint col); |
1006 | |
1007 | public: |
1008 | bool wordWrap() const; |
1009 | uint wordWrapAt() const; |
1010 | |
1011 | public Q_SLOTS: |
1012 | void setPageUpDownMovesCursor(bool on); |
1013 | |
1014 | public: |
1015 | bool pageUpDownMovesCursor() const; |
1016 | |
1017 | // code folding |
1018 | public: |
1019 | /** |
1020 | * Same as plainKateTextLine(), except that it is made sure |
1021 | * the line is highlighted. |
1022 | */ |
1023 | Kate::TextLine kateTextLine(int i); |
1024 | |
1025 | //! @copydoc KateBuffer::plainLine() |
1026 | Kate::TextLine plainKateTextLine(int i); |
1027 | |
1028 | Q_SIGNALS: |
1029 | void aboutToRemoveText(const KTextEditor::Range &); |
1030 | |
1031 | private Q_SLOTS: |
1032 | void slotModOnHdDirty(const QString &path); |
1033 | void slotModOnHdCreated(const QString &path); |
1034 | void slotModOnHdDeleted(const QString &path); |
1035 | void slotDelayedHandleModOnHd(); |
1036 | |
1037 | private: |
1038 | /** |
1039 | * Create a git compatible sha1 checksum of the file, if it is a local file. |
1040 | * The result can be accessed through KateBuffer::digest(). |
1041 | * |
1042 | * @return whether the operation was attempted and succeeded. |
1043 | */ |
1044 | bool createDigest(); |
1045 | |
1046 | /** |
1047 | * create a string for the modonhd warnings, giving the reason. |
1048 | */ |
1049 | QString reasonedMOHString() const; |
1050 | |
1051 | /** |
1052 | * Removes all trailing whitespace in the document. |
1053 | */ |
1054 | void removeTrailingSpaces(); |
1055 | |
1056 | public: |
1057 | /** |
1058 | * Returns a git compatible sha1 checksum of this document on disk. |
1059 | * @return checksum for this document on disk |
1060 | */ |
1061 | QByteArray checksum() const override; |
1062 | |
1063 | void updateFileType(const QString &newType, bool user = false); |
1064 | |
1065 | QString fileType() const |
1066 | { |
1067 | return m_fileType; |
1068 | } |
1069 | |
1070 | /** |
1071 | * Get access to buffer of this document. |
1072 | * Is needed to create cursors and ranges for example. |
1073 | * @return document buffer |
1074 | */ |
1075 | KateBuffer &buffer() |
1076 | { |
1077 | return *m_buffer; |
1078 | } |
1079 | |
1080 | /** |
1081 | * set indentation mode by user |
1082 | * this will remember that a user did set it and will avoid reset on save |
1083 | */ |
1084 | void rememberUserDidSetIndentationMode() |
1085 | { |
1086 | m_indenterSetByUser = true; |
1087 | } |
1088 | |
1089 | /** |
1090 | * User did set encoding for next reload => enforce it! |
1091 | */ |
1092 | void userSetEncodingForNextReload() |
1093 | { |
1094 | m_userSetEncodingForNextReload = true; |
1095 | } |
1096 | |
1097 | // |
1098 | // REALLY internal data ;) |
1099 | // |
1100 | private: |
1101 | // text buffer |
1102 | KateBuffer *const m_buffer; |
1103 | |
1104 | // indenter |
1105 | KateAutoIndent *const m_indenter; |
1106 | |
1107 | bool m_hlSetByUser = false; |
1108 | bool m_bomSetByUser = false; |
1109 | bool m_indenterSetByUser = false; |
1110 | bool m_userSetEncodingForNextReload = false; |
1111 | |
1112 | bool m_modOnHd = false; |
1113 | KToggleAction* m_autoReloadMode; |
1114 | QTimer m_autoReloadThrottle; |
1115 | ModifiedOnDiskReason m_modOnHdReason = OnDiskUnmodified; |
1116 | ModifiedOnDiskReason m_prevModOnHdReason = OnDiskUnmodified; |
1117 | |
1118 | QString m_docName; |
1119 | int = 0; |
1120 | |
1121 | // file type !!! |
1122 | QString m_fileType; |
1123 | bool m_fileTypeSetByUser = false; |
1124 | |
1125 | /** |
1126 | * document is still reloading a file |
1127 | */ |
1128 | bool m_reloading = false; |
1129 | |
1130 | public Q_SLOTS: |
1131 | void slotQueryClose_save(bool *handled, bool *abortClosing); |
1132 | |
1133 | public: |
1134 | bool queryClose() override; |
1135 | |
1136 | /** |
1137 | * Configuration |
1138 | */ |
1139 | public: |
1140 | KateDocumentConfig *config() |
1141 | { |
1142 | return m_config; |
1143 | } |
1144 | KateDocumentConfig *config() const |
1145 | { |
1146 | return m_config; |
1147 | } |
1148 | |
1149 | void updateConfig(); |
1150 | |
1151 | private: |
1152 | void makeAttribs(bool needInvalidate = true); |
1153 | |
1154 | KateDocumentConfig *const m_config; |
1155 | |
1156 | /** |
1157 | * Variable Reader |
1158 | * TODO add register functionality/ktexteditor interface |
1159 | */ |
1160 | private: |
1161 | /** |
1162 | * read dir config file |
1163 | */ |
1164 | void readDirConfig(); |
1165 | |
1166 | /** |
1167 | Reads all the variables in the document. |
1168 | Called when opening/saving a document |
1169 | */ |
1170 | void readVariables(bool onlyViewAndRenderer = false); |
1171 | |
1172 | /** |
1173 | Reads and applies the variables in a single line |
1174 | TODO registered variables gets saved in a [map] |
1175 | */ |
1176 | void readVariableLine(QString t, bool onlyViewAndRenderer = false); |
1177 | /** |
1178 | Sets a view variable in all the views. |
1179 | */ |
1180 | void setViewVariable(QString var, QString val); |
1181 | /** |
1182 | @return weather a string value could be converted |
1183 | to a bool value as supported. |
1184 | The value is put in *result. |
1185 | */ |
1186 | static bool checkBoolValue(QString value, bool *result); |
1187 | /** |
1188 | @return weather a string value could be converted |
1189 | to a integer value. |
1190 | The value is put in *result. |
1191 | */ |
1192 | static bool checkIntValue(QString value, int *result); |
1193 | /** |
1194 | Feeds value into @p col using QColor::setNamedColor() and returns |
1195 | whether the color is valid |
1196 | */ |
1197 | static bool checkColorValue(QString value, QColor &col); |
1198 | |
1199 | bool m_fileChangedDialogsActivated = false; |
1200 | |
1201 | // |
1202 | // KTextEditor::ConfigInterface |
1203 | // |
1204 | public: |
1205 | QStringList configKeys() const override; |
1206 | QVariant configValue(const QString &key) override; |
1207 | void setConfigValue(const QString &key, const QVariant &value) override; |
1208 | |
1209 | // |
1210 | // KTextEditor::RecoveryInterface |
1211 | // |
1212 | public: |
1213 | bool isDataRecoveryAvailable() const override; |
1214 | void recoverData() override; |
1215 | void discardDataRecovery() override; |
1216 | |
1217 | // |
1218 | // Highlighting information |
1219 | // |
1220 | public: |
1221 | QStringList embeddedHighlightingModes() const override; |
1222 | QString highlightingModeAt(const KTextEditor::Cursor &position) override; |
1223 | // TODO KDE5: move to View |
1224 | virtual KTextEditor::Attribute::Ptr attributeAt(const KTextEditor::Cursor &position); |
1225 | |
1226 | // |
1227 | //BEGIN: KTextEditor::MessageInterface |
1228 | // |
1229 | public: |
1230 | bool postMessage(KTextEditor::Message *message) override; |
1231 | |
1232 | public Q_SLOTS: |
1233 | void messageDestroyed(KTextEditor::Message *message); |
1234 | |
1235 | private: |
1236 | QHash<KTextEditor::Message *, QList<QSharedPointer<QAction> > > m_messageHash; |
1237 | //END KTextEditor::MessageInterface |
1238 | |
1239 | public: |
1240 | QString defaultDictionary() const; |
1241 | QList<QPair<KTextEditor::MovingRange *, QString> > dictionaryRanges() const; |
1242 | bool isOnTheFlySpellCheckingEnabled() const; |
1243 | |
1244 | QString dictionaryForMisspelledRange(const KTextEditor::Range &range) const; |
1245 | void clearMisspellingForWord(const QString &word); |
1246 | |
1247 | public Q_SLOTS: |
1248 | void clearDictionaryRanges(); |
1249 | void setDictionary(const QString &dict, const KTextEditor::Range &range, bool blockmode); |
1250 | void setDictionary(const QString &dict, const KTextEditor::Range &range); |
1251 | void setDefaultDictionary(const QString &dict); |
1252 | void onTheFlySpellCheckingEnabled(bool enable); |
1253 | void refreshOnTheFlyCheck(const KTextEditor::Range &range = KTextEditor::Range::invalid()); |
1254 | |
1255 | Q_SIGNALS: |
1256 | void dictionaryRangesPresent(bool yesNo); |
1257 | void defaultDictionaryChanged(KTextEditor::DocumentPrivate *document); |
1258 | |
1259 | public: |
1260 | bool containsCharacterEncoding(const KTextEditor::Range &range); |
1261 | |
1262 | typedef QList<QPair<int, int> > OffsetList; |
1263 | |
1264 | int computePositionWrtOffsets(const OffsetList &offsetList, int pos); |
1265 | |
1266 | /** |
1267 | * The first OffsetList is from decoded to encoded, and the second OffsetList from |
1268 | * encoded to decoded. |
1269 | **/ |
1270 | QString decodeCharacters(const KTextEditor::Range &range, |
1271 | KTextEditor::DocumentPrivate::OffsetList &decToEncOffsetList, |
1272 | KTextEditor::DocumentPrivate::OffsetList &encToDecOffsetList); |
1273 | void replaceCharactersByEncoding(const KTextEditor::Range &range); |
1274 | |
1275 | protected: |
1276 | KateOnTheFlyChecker *m_onTheFlyChecker = nullptr; |
1277 | QString m_defaultDictionary; |
1278 | QList<QPair<KTextEditor::MovingRange *, QString> > m_dictionaryRanges; |
1279 | |
1280 | // from KTextEditor::MovingRangeFeedback |
1281 | void rangeInvalid(KTextEditor::MovingRange *movingRange) override; |
1282 | void rangeEmpty(KTextEditor::MovingRange *movingRange) override; |
1283 | |
1284 | void deleteDictionaryRange(KTextEditor::MovingRange *movingRange); |
1285 | |
1286 | private: |
1287 | Kate::SwapFile *m_swapfile; |
1288 | |
1289 | public: |
1290 | Kate::SwapFile *swapFile(); |
1291 | |
1292 | //helpers for scripting and codefolding |
1293 | int defStyleNum(int line, int column); |
1294 | bool (int line, int column); |
1295 | |
1296 | public: |
1297 | /** |
1298 | * Find the next modified/saved line, starting at @p startLine. If @p down |
1299 | * is \e true, the search is performed downwards, otherwise upwards. |
1300 | * @return the touched line in the requested search direction, or -1 if not found |
1301 | */ |
1302 | int findTouchedLine(int startLine, bool down); |
1303 | |
1304 | private Q_SLOTS: |
1305 | /** |
1306 | * watch for all started io jobs to remember if file is perhaps loading atm |
1307 | * @param job started job |
1308 | */ |
1309 | void slotStarted(KIO::Job *job); |
1310 | void slotCompleted(); |
1311 | void slotCanceled(); |
1312 | |
1313 | /** |
1314 | * trigger display of loading message, after 1000 ms |
1315 | */ |
1316 | void slotTriggerLoadingMessage(); |
1317 | |
1318 | /** |
1319 | * Abort loading |
1320 | */ |
1321 | void slotAbortLoading(); |
1322 | |
1323 | void slotUrlChanged(const QUrl &url); |
1324 | |
1325 | private: |
1326 | /** |
1327 | * different possible states |
1328 | */ |
1329 | enum DocumentStates { |
1330 | /** |
1331 | * Idle |
1332 | */ |
1333 | DocumentIdle, |
1334 | |
1335 | /** |
1336 | * Loading |
1337 | */ |
1338 | DocumentLoading, |
1339 | |
1340 | /** |
1341 | * Saving |
1342 | */ |
1343 | DocumentSaving, |
1344 | |
1345 | /** |
1346 | * Pre Saving As, this is between ::saveAs is called and ::save |
1347 | */ |
1348 | DocumentPreSavingAs, |
1349 | |
1350 | /** |
1351 | * Saving As |
1352 | */ |
1353 | DocumentSavingAs |
1354 | }; |
1355 | |
1356 | /** |
1357 | * current state |
1358 | */ |
1359 | DocumentStates m_documentState = DocumentIdle; |
1360 | |
1361 | /** |
1362 | * read-write state before loading started |
1363 | */ |
1364 | bool m_readWriteStateBeforeLoading = false; |
1365 | |
1366 | /** |
1367 | * if the document is untitled |
1368 | */ |
1369 | bool m_isUntitled = true; |
1370 | /** |
1371 | * loading job, we want to cancel with cancel in the loading message |
1372 | */ |
1373 | QPointer<KJob> m_loadingJob; |
1374 | |
1375 | /** |
1376 | * message to show during loading |
1377 | */ |
1378 | QPointer<KTextEditor::Message> m_loadingMessage; |
1379 | |
1380 | /** |
1381 | * Was there any open error on last file loading? |
1382 | */ |
1383 | bool m_openingError = false; |
1384 | |
1385 | /** |
1386 | * Last open file error message |
1387 | */ |
1388 | QString m_openingErrorMessage; |
1389 | |
1390 | public: |
1391 | /** |
1392 | * reads the line length limit from config, if it is not overridden |
1393 | */ |
1394 | int lineLengthLimit() const; |
1395 | |
1396 | public Q_SLOTS: |
1397 | void openWithLineLengthLimitOverride(); |
1398 | |
1399 | private: |
1400 | /** |
1401 | * timer for delayed handling of mod on hd |
1402 | */ |
1403 | QTimer m_modOnHdTimer; |
1404 | |
1405 | private: |
1406 | /** |
1407 | * currently active template handler; there can be only one |
1408 | */ |
1409 | QPointer<KateTemplateHandler> m_activeTemplateHandler; |
1410 | |
1411 | private: |
1412 | /** |
1413 | * current autobrace range |
1414 | */ |
1415 | QSharedPointer<KTextEditor::MovingRange> m_currentAutobraceRange; |
1416 | /** |
1417 | * current autobrace closing character (e.g. ']') |
1418 | */ |
1419 | QChar m_currentAutobraceClosingChar; |
1420 | |
1421 | private Q_SLOTS: |
1422 | void checkCursorForAutobrace(KTextEditor::View* view, const KTextEditor::Cursor& newPos); |
1423 | |
1424 | public: |
1425 | void setActiveTemplateHandler(KateTemplateHandler* handler); |
1426 | |
1427 | Q_SIGNALS: |
1428 | void loaded(KTextEditor::DocumentPrivate *document); |
1429 | |
1430 | private Q_SLOTS: |
1431 | /** |
1432 | * trigger a close of this document in the application |
1433 | */ |
1434 | void closeDocumentInApplication(); |
1435 | private: |
1436 | // To calculate a QHash.keys() is quite expensive, |
1437 | // better keep a copy of that list updated when a view is added or removed. |
1438 | QList<KTextEditor::View *> m_viewsCache; |
1439 | }; |
1440 | |
1441 | #endif |
1442 | |