File indexing completed on 2024-04-21 03:57:28
0001 /* 0002 SPDX-FileCopyrightText: 2001-2004 Christoph Cullmann <cullmann@kde.org> 0003 SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org> 0004 SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> 0005 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef _KATE_DOCUMENT_H_ 0011 #define _KATE_DOCUMENT_H_ 0012 0013 #include <QPointer> 0014 #include <QStack> 0015 #include <QTimer> 0016 0017 #include <ktexteditor/document.h> 0018 #include <ktexteditor/mainwindow.h> 0019 #include <ktexteditor/movingrangefeedback.h> 0020 0021 #include "katetextline.h" 0022 #include <ktexteditor_export.h> 0023 0024 class KJob; 0025 class KateTemplateHandler; 0026 namespace KTextEditor 0027 { 0028 class Plugin; 0029 class Attribute; 0030 class TemplateScript; 0031 } 0032 0033 namespace KIO 0034 { 0035 class TransferJob; 0036 } 0037 0038 namespace Kate 0039 { 0040 class SwapFile; 0041 } 0042 0043 class KateBuffer; 0044 namespace KTextEditor 0045 { 0046 class Message; 0047 class ViewPrivate; 0048 } 0049 class KateDocumentConfig; 0050 class KateHighlighting; 0051 class KateUndoManager; 0052 class KateOnTheFlyChecker; 0053 class KateDocumentTest; 0054 0055 class KateAutoIndent; 0056 class KateModOnHdPrompt; 0057 class KToggleAction; 0058 0059 /** 0060 * @brief Backend of KTextEditor::Document related public KTextEditor interfaces. 0061 * 0062 * @warning This file is @e private API and not part of the public 0063 * KTextEditor interfaces. 0064 */ 0065 class KTEXTEDITOR_EXPORT KTextEditor::DocumentPrivate final : public KTextEditor::Document, private KTextEditor::MovingRangeFeedback 0066 { 0067 Q_OBJECT 0068 0069 friend class KTextEditor::Document; 0070 friend class ::KateDocumentTest; 0071 friend class ::KateBuffer; 0072 0073 public: 0074 explicit DocumentPrivate(const KPluginMetaData &data, 0075 bool bSingleViewMode = false, 0076 bool bReadOnly = false, 0077 QWidget *parentWidget = nullptr, 0078 QObject * = nullptr); 0079 explicit DocumentPrivate(bool bSingleViewMode = false, bool bReadOnly = false, QWidget *parentWidget = nullptr, QObject * = nullptr) 0080 : DocumentPrivate(KPluginMetaData(), bSingleViewMode, bReadOnly, parentWidget) 0081 { 0082 } 0083 ~DocumentPrivate() override; 0084 0085 using ReadWritePart::closeUrl; 0086 bool closeUrl() override; 0087 0088 bool openUrl(const QUrl &url) override; 0089 0090 KTextEditor::Range rangeOnLine(KTextEditor::Range range, int line) const; 0091 0092 private: 0093 KTEXTEDITOR_NO_EXPORT 0094 void showAndSetOpeningErrorAccess(); 0095 /* 0096 * Overload this to have on-demand view creation 0097 */ 0098 public: 0099 /** 0100 * @return The widget defined by this part, set by setWidget(). 0101 */ 0102 QWidget *widget() override; 0103 0104 public: 0105 bool readOnly() const 0106 { 0107 return m_bReadOnly; 0108 } 0109 bool singleViewMode() const 0110 { 0111 return m_bSingleViewMode; 0112 } 0113 0114 private: 0115 // only to make part work, don't change it ! 0116 const bool m_bSingleViewMode; 0117 const bool m_bReadOnly; 0118 0119 // 0120 // KTextEditor::Document stuff 0121 // 0122 public: 0123 KTextEditor::View *createView(QWidget *parent, KTextEditor::MainWindow *mainWindow = nullptr) override; 0124 0125 QList<KTextEditor::View *> views() const override 0126 { 0127 return m_views; 0128 } 0129 0130 KTextEditor::View *activeView() const 0131 { 0132 return m_activeView; 0133 } 0134 0135 private: 0136 KTextEditor::View *m_activeView = nullptr; 0137 0138 // 0139 // KTextEditor::EditInterface stuff 0140 // 0141 public Q_SLOTS: 0142 bool setText(const QString &) override; 0143 bool setText(const QStringList &text) override; 0144 bool clear() override; 0145 0146 bool insertText(KTextEditor::Cursor position, const QString &s, bool block = false) override; 0147 bool insertText(KTextEditor::Cursor position, const QStringList &text, bool block = false) override; 0148 0149 bool insertLine(int line, const QString &s) override; 0150 bool insertLines(int line, const QStringList &s) override; 0151 0152 bool removeText(KTextEditor::Range range, bool block = false) override; 0153 bool removeLine(int line) override; 0154 0155 bool replaceText(KTextEditor::Range range, const QString &s, bool block = false) override; 0156 0157 // unhide method... 0158 bool replaceText(KTextEditor::Range r, const QStringList &l, bool b) override 0159 { 0160 return KTextEditor::Document::replaceText(r, l, b); 0161 } 0162 0163 public: 0164 bool isEditingTransactionRunning() const override; 0165 QString text(KTextEditor::Range range, bool blockwise = false) const override; 0166 QStringList textLines(KTextEditor::Range range, bool block = false) const override; 0167 QString text() const override; 0168 QString line(int line) const override; 0169 QChar characterAt(KTextEditor::Cursor position) const override; 0170 QString wordAt(KTextEditor::Cursor cursor) const override; 0171 KTextEditor::Range wordRangeAt(KTextEditor::Cursor cursor) const override; 0172 bool isValidTextPosition(KTextEditor::Cursor cursor) const override; 0173 int lines() const override; 0174 bool isLineModified(int line) const override; 0175 bool isLineSaved(int line) const override; 0176 bool isLineTouched(int line) const override; 0177 KTextEditor::Cursor documentEnd() const override; 0178 qsizetype totalCharacters() const override; 0179 int lineLength(int line) const override; 0180 qsizetype cursorToOffset(KTextEditor::Cursor c) const override; 0181 KTextEditor::Cursor offsetToCursor(qsizetype offset) const override; 0182 0183 Q_SIGNALS: 0184 void charactersSemiInteractivelyInserted(KTextEditor::Cursor position, const QString &text); 0185 0186 /** 0187 * The \p document emits this signal whenever text was inserted. The 0188 * insertion occurred at range.start(), and new text now occupies up to 0189 * range.end(). 0190 * \param document document which emitted this signal 0191 * \param range range that the newly inserted text occupies 0192 * \see insertText(), insertLine() 0193 */ 0194 void textInsertedRange(KTextEditor::Document *document, KTextEditor::Range range); 0195 0196 /** 0197 * The \p document emits this signal whenever \p range was removed, i.e. 0198 * text was removed. 0199 * \param document document which emitted this signal 0200 * \param range range that the removed text previously occupied 0201 * \param oldText the text that has been removed 0202 * \see removeText(), removeLine(), clear() 0203 */ 0204 void textRemoved(KTextEditor::Document *document, KTextEditor::Range range, const QString &oldText); 0205 0206 public: 0207 // BEGIN editStart/editEnd (start, end, undo, cursor update, view update) 0208 /** 0209 * Enclose editor actions with @p editStart() and @p editEnd() to group 0210 * them. 0211 */ 0212 bool editStart(); 0213 0214 /** 0215 * End a editor operation. 0216 * @see editStart() 0217 */ 0218 bool editEnd(); 0219 0220 void pushEditState(); 0221 void popEditState(); 0222 0223 // END editStart/editEnd 0224 0225 void inputMethodStart(); 0226 void inputMethodEnd(); 0227 0228 // BEGIN LINE BASED INSERT/REMOVE STUFF (editStart() and editEnd() included) 0229 /** 0230 * Add a string in the given line/column 0231 * @param line line number 0232 * @param col column 0233 * @param s string to be inserted 0234 * @return true on success 0235 */ 0236 bool editInsertText(int line, int col, const QString &s, bool notify = true); 0237 0238 /** 0239 * Remove a string in the given line/column 0240 * @param line line number 0241 * @param col column 0242 * @param len length of text to be removed 0243 * @return true on success 0244 */ 0245 bool editRemoveText(int line, int col, int len); 0246 0247 /** 0248 * Mark @p line as @p autowrapped. This is necessary if static word warp is 0249 * enabled, because we have to know whether to insert a new line or add the 0250 * wrapped words to the following line. 0251 * @param line line number 0252 * @param autowrapped autowrapped? 0253 * @return true on success 0254 */ 0255 bool editMarkLineAutoWrapped(int line, bool autowrapped); 0256 0257 /** 0258 * Wrap @p line. If @p newLine is true, ignore the textline's flag 0259 * KateTextLine::flagAutoWrapped and force a new line. Whether a new line 0260 * was needed/added you can grab with @p newLineAdded. 0261 * @param line line number 0262 * @param col column 0263 * @param newLine if true, force a new line 0264 * @param newLineAdded return value is true, if new line was added (may be 0) 0265 * @return true on success 0266 */ 0267 bool editWrapLine(int line, int col, bool newLine = true, bool *newLineAdded = nullptr, bool notify = true); 0268 0269 /** 0270 * Unwrap @p line. If @p removeLine is true, we force to join the lines. If 0271 * @p removeLine is true, @p length is ignored (eg not needed). 0272 * @param line line number 0273 * @param removeLine if true, force to remove the next line 0274 * @return true on success 0275 */ 0276 bool editUnWrapLine(int line, bool removeLine = true, int length = 0); 0277 0278 /** 0279 * Insert a string at the given line. 0280 * @param line line number 0281 * @param s string to insert 0282 * @return true on success 0283 */ 0284 bool editInsertLine(int line, const QString &s, bool notify = true); 0285 0286 /** 0287 * Remove a line 0288 * @param line line number 0289 * @return true on success 0290 */ 0291 bool editRemoveLine(int line); 0292 0293 bool editRemoveLines(int from, int to); 0294 0295 /** 0296 * Warp a line 0297 * @param startLine line to begin wrapping 0298 * @param endLine line to stop wrapping 0299 * @return true on success 0300 */ 0301 bool wrapText(int startLine, int endLine); 0302 0303 /** 0304 * Wrap lines touched by the selection with respect of existing paragraphs. 0305 * To do so will the paragraph prior to the wrap joined as one single line 0306 * which cause an almost perfect wrapped paragraph as long as there are no 0307 * unneeded spaces exist or some formatting like this comment block. 0308 * Without any selection the current line is wrapped. 0309 * Empty lines around each paragraph are untouched. 0310 * @param first line to begin wrapping 0311 * @param last line to stop wrapping 0312 * @return true on success 0313 */ 0314 bool wrapParagraph(int first, int last); 0315 // END LINE BASED INSERT/REMOVE STUFF 0316 0317 Q_SIGNALS: 0318 /** 0319 * Emitted when text from @p line was wrapped at position pos onto line @p nextLine. 0320 */ 0321 void editLineWrapped(int line, int col, int len); 0322 0323 /** 0324 * Emitted each time text from @p nextLine was upwrapped onto @p line. 0325 */ 0326 void editLineUnWrapped(int line, int col); 0327 0328 public: 0329 bool isEditRunning() const; 0330 0331 void setUndoMergeAllEdits(bool merge); 0332 0333 enum EditingPositionKind { Previous, Next }; 0334 0335 /** 0336 *Returns the next or previous position cursor in this document from the stack depending on the argument passed. 0337 *@return cursor invalid if m_editingStack empty 0338 */ 0339 KTextEditor::Cursor lastEditingPosition(EditingPositionKind nextOrPrevious, KTextEditor::Cursor); 0340 0341 private: 0342 int editSessionNumber = 0; 0343 QStack<int> editStateStack; 0344 bool editIsRunning = false; 0345 bool m_undoMergeAllEdits = false; 0346 KTextEditor::Cursor m_editLastChangeStartCursor = KTextEditor::Cursor::invalid(); 0347 QStack<std::shared_ptr<KTextEditor::MovingCursor>> m_editingStack; 0348 int m_editingStackPosition = -1; 0349 0350 // 0351 // KTextEditor::UndoInterface stuff 0352 // 0353 public Q_SLOTS: 0354 void undo(); 0355 void redo(); 0356 0357 /** 0358 * Removes all the elements in m_editingStack of the respective document. 0359 */ 0360 void clearEditingPosStack(); 0361 0362 /** 0363 * Saves the editing positions into the stack. 0364 * If the consecutive editings happens in the same line, then remove 0365 * the previous and add the new one with updated column no. 0366 */ 0367 void saveEditingPositions(const KTextEditor::Cursor cursor); 0368 0369 public: 0370 uint undoCount() const; 0371 uint redoCount() const; 0372 0373 KateUndoManager *undoManager() 0374 { 0375 return m_undoManager; 0376 } 0377 0378 protected: 0379 KateUndoManager *const m_undoManager; 0380 0381 Q_SIGNALS: 0382 void undoChanged(); 0383 0384 public: 0385 QList<KTextEditor::Range> searchText(KTextEditor::Range range, const QString &pattern, const KTextEditor::SearchOptions options) const; 0386 0387 private: 0388 /** 0389 * Return a widget suitable to be used as a dialog parent. 0390 */ 0391 KTEXTEDITOR_NO_EXPORT 0392 QWidget *dialogParent(); 0393 0394 /** 0395 * Wrapper around QFileDialog::getSaveFileUrl, will use proper dialogParent 0396 * and try it's best to find a good directory as start 0397 * @param dialogTitle dialog title string 0398 * @return url to save to or empty url if aborted 0399 */ 0400 KTEXTEDITOR_NO_EXPORT 0401 QUrl getSaveFileUrl(const QString &dialogTitle); 0402 0403 /* 0404 * Access to the mode/highlighting subsystem 0405 */ 0406 public: 0407 /** 0408 * @copydoc KTextEditor::Document::defaultStyleAt() 0409 */ 0410 KSyntaxHighlighting::Theme::TextStyle defaultStyleAt(KTextEditor::Cursor position) const override; 0411 0412 /** 0413 * Return the name of the currently used mode 0414 * \return name of the used mode 0415 */ 0416 QString mode() const override; 0417 0418 /** 0419 * Return the name of the currently used mode 0420 * \return name of the used mode 0421 */ 0422 QString highlightingMode() const override; 0423 0424 /** 0425 * Return a list of the names of all possible modes 0426 * \return list of mode names 0427 */ 0428 QStringList modes() const override; 0429 0430 /** 0431 * Return a list of the names of all possible modes 0432 * \return list of mode names 0433 */ 0434 QStringList highlightingModes() const override; 0435 0436 /** 0437 * Set the current mode of the document by giving its name 0438 * \param name name of the mode to use for this document 0439 * \return \e true on success, otherwise \e false 0440 */ 0441 bool setMode(const QString &name) override; 0442 0443 /** 0444 * Set the current mode of the document by giving its name 0445 * \param name name of the mode to use for this document 0446 * \return \e true on success, otherwise \e false 0447 */ 0448 bool setHighlightingMode(const QString &name) override; 0449 /** 0450 * Returns the name of the section for a highlight given its @p index in the highlight 0451 * list (as returned by highlightModes()). 0452 * You can use this function to build a tree of the highlight names, organized in sections. 0453 * \param index in the highlight list for which to find the section name. 0454 */ 0455 QString highlightingModeSection(int index) const override; 0456 0457 /** 0458 * Returns the name of the section for a mode given its @p index in the highlight 0459 * list (as returned by modes()). 0460 * You can use this function to build a tree of the mode names, organized in sections. 0461 * \param index index in the highlight list for which to find the section name. 0462 */ 0463 QString modeSection(int index) const override; 0464 0465 /* 0466 * Helpers.... 0467 */ 0468 public: 0469 void bufferHlChanged(); 0470 0471 /** 0472 * allow to mark, that we changed hl on user wish and should not reset it 0473 * atm used for the user visible menu to select highlightings 0474 */ 0475 void setDontChangeHlOnSave(); 0476 0477 /** 0478 * Set that the BOM marker is forced via the tool menu 0479 */ 0480 void bomSetByUser(); 0481 0482 public: 0483 /** 0484 * Read session settings from the given \p config. 0485 * 0486 * Known flags: 0487 * "SkipUrl" => don't save/restore the file 0488 * "SkipMode" => don't save/restore the mode 0489 * "SkipHighlighting" => don't save/restore the highlighting 0490 * "SkipEncoding" => don't save/restore the encoding 0491 * 0492 * \param config read the session settings from this KConfigGroup 0493 * \param flags additional flags 0494 * \see writeSessionConfig() 0495 */ 0496 void readSessionConfig(const KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) override; 0497 0498 /** 0499 * Write session settings to the \p config. 0500 * See readSessionConfig() for more details. 0501 * 0502 * \param config write the session settings to this KConfigGroup 0503 * \param flags additional flags 0504 * \see readSessionConfig() 0505 */ 0506 void writeSessionConfig(KConfigGroup &config, const QSet<QString> &flags = QSet<QString>()) override; 0507 0508 // 0509 // KTextEditor::MarkInterface 0510 // 0511 public Q_SLOTS: 0512 void setMark(int line, uint markType) override; 0513 void clearMark(int line) override; 0514 0515 void addMark(int line, uint markType) override; 0516 void removeMark(int line, uint markType) override; 0517 0518 void clearMarks() override; 0519 0520 void requestMarkTooltip(int line, QPoint position); 0521 0522 /// Returns true if the click on the mark should not be further processed 0523 bool handleMarkClick(int line); 0524 0525 /// Returns true if the context-menu event should not further be processed 0526 bool handleMarkContextMenu(int line, QPoint position); 0527 0528 void setMarkDescription(Document::MarkTypes, const QString &) override; 0529 0530 void setEditableMarks(uint markMask) override; 0531 void setMarkIcon(Document::MarkTypes markType, const QIcon &icon) override; 0532 0533 public: 0534 uint mark(int line) override; 0535 const QHash<int, KTextEditor::Mark *> &marks() override; 0536 QString markDescription(Document::MarkTypes) const override; 0537 virtual QColor markColor(Document::MarkTypes) const; 0538 uint editableMarks() const override; 0539 QIcon markIcon(Document::MarkTypes markType) const override; 0540 0541 private: 0542 QHash<int, KTextEditor::Mark *> m_marks; 0543 QHash<int, QIcon> m_markIcons; // QPixmap or QIcon, KF6: remove QPixmap support 0544 QHash<int, QString> m_markDescriptions; 0545 uint m_editableMarks = markType01; 0546 0547 // 0548 // KTextEditor::PrintInterface 0549 // 0550 public Q_SLOTS: 0551 bool print() override; 0552 void printPreview() override; 0553 0554 // 0555 // KTextEditor::DocumentInfoInterface ( ### unfinished ) 0556 // 0557 public: 0558 /** 0559 * Tries to detect mime-type based on file name and content of buffer. 0560 * 0561 * @return the name of the mimetype for the document. 0562 */ 0563 QString mimeType() override; 0564 0565 // 0566 // once was KTextEditor::VariableInterface 0567 // 0568 public: 0569 /** 0570 * Returns the value for the variable @p name. 0571 * If the Document does not have a variable called @p name, 0572 * an empty QString() is returned. 0573 * 0574 * // TODO KF6: expose in KTextEditor::Document? 0575 * 0576 * @param name variable to query 0577 * @return value of the variable @p name 0578 * @see setVariable() 0579 */ 0580 virtual QString variable(const QString &name) const; 0581 0582 /** 0583 * Set the variable @p name to @p value. Setting and changing a variable 0584 * has immediate effect on the Document. For instance, setting the variable 0585 * @e indent-mode to @e cstyle will immediately cause the Document to load 0586 * the C Style indenter. 0587 * 0588 * // TODO KF6: expose in KTextEditor::Document? 0589 * 0590 * @param name the variable name 0591 * @param value the value to be set 0592 * @see variable() 0593 */ 0594 virtual void setVariable(const QString &name, const QString &value); 0595 0596 private: 0597 std::map<QString, QString> m_storedVariables; 0598 0599 // 0600 // MovingInterface API 0601 // 0602 public: 0603 /** 0604 * Create a new moving cursor for this document. 0605 * @param position position of the moving cursor to create 0606 * @param insertBehavior insertion behavior 0607 * @return new moving cursor for the document 0608 */ 0609 KTextEditor::MovingCursor *newMovingCursor(KTextEditor::Cursor position, 0610 KTextEditor::MovingCursor::InsertBehavior insertBehavior = KTextEditor::MovingCursor::MoveOnInsert) override; 0611 0612 /** 0613 * Create a new moving range for this document. 0614 * @param range range of the moving range to create 0615 * @param insertBehaviors insertion behaviors 0616 * @param emptyBehavior behavior on becoming empty 0617 * @return new moving range for the document 0618 */ 0619 KTextEditor::MovingRange *newMovingRange(KTextEditor::Range range, 0620 KTextEditor::MovingRange::InsertBehaviors insertBehaviors = KTextEditor::MovingRange::DoNotExpand, 0621 KTextEditor::MovingRange::EmptyBehavior emptyBehavior = KTextEditor::MovingRange::AllowEmpty) override; 0622 0623 /** 0624 * Current revision 0625 * @return current revision 0626 */ 0627 qint64 revision() const override; 0628 0629 /** 0630 * Last revision the buffer got successful saved 0631 * @return last revision buffer got saved, -1 if none 0632 */ 0633 qint64 lastSavedRevision() const override; 0634 0635 /** 0636 * Lock a revision, this will keep it around until released again. 0637 * But all revisions will always be cleared on buffer clear() (and therefor load()) 0638 * @param revision revision to lock 0639 */ 0640 void lockRevision(qint64 revision) override; 0641 0642 /** 0643 * Release a revision. 0644 * @param revision revision to release 0645 */ 0646 void unlockRevision(qint64 revision) override; 0647 0648 /** 0649 * Transform a cursor from one revision to an other. 0650 * @param cursor cursor to transform 0651 * @param insertBehavior behavior of this cursor on insert of text at its position 0652 * @param fromRevision from this revision we want to transform 0653 * @param toRevision to this revision we want to transform, default of -1 is current revision 0654 */ 0655 void transformCursor(KTextEditor::Cursor &cursor, 0656 KTextEditor::MovingCursor::InsertBehavior insertBehavior, 0657 qint64 fromRevision, 0658 qint64 toRevision = -1) override; 0659 0660 /** 0661 * Transform a cursor from one revision to an other. 0662 * @param line line number of the cursor to transform 0663 * @param column column number of the cursor to transform 0664 * @param insertBehavior behavior of this cursor on insert of text at its position 0665 * @param fromRevision from this revision we want to transform 0666 * @param toRevision to this revision we want to transform, default of -1 is current revision 0667 */ 0668 void 0669 transformCursor(int &line, int &column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision = -1) override; 0670 0671 /** 0672 * Transform a range from one revision to an other. 0673 * @param range range to transform 0674 * @param insertBehaviors behavior of this range on insert of text at its position 0675 * @param emptyBehavior behavior on becoming empty 0676 * @param fromRevision from this revision we want to transform 0677 * @param toRevision to this revision we want to transform, default of -1 is current revision 0678 */ 0679 void transformRange(KTextEditor::Range &range, 0680 KTextEditor::MovingRange::InsertBehaviors insertBehaviors, 0681 KTextEditor::MovingRange::EmptyBehavior emptyBehavior, 0682 qint64 fromRevision, 0683 qint64 toRevision = -1) override; 0684 0685 // 0686 // Annotation Interface 0687 // 0688 public: 0689 void setAnnotationModel(KTextEditor::AnnotationModel *model) override; 0690 KTextEditor::AnnotationModel *annotationModel() const override; 0691 0692 Q_SIGNALS: 0693 void annotationModelChanged(KTextEditor::AnnotationModel *, KTextEditor::AnnotationModel *); 0694 0695 private: 0696 KTextEditor::AnnotationModel *m_annotationModel = nullptr; 0697 0698 // 0699 // KParts::ReadWrite stuff 0700 // 0701 public: 0702 /** 0703 * open the file obtained by the kparts framework 0704 * the framework abstracts the loading of remote files 0705 * @return success 0706 */ 0707 bool openFile() override; 0708 0709 /** 0710 * save the file obtained by the kparts framework 0711 * the framework abstracts the uploading of remote files 0712 * @return success 0713 */ 0714 bool saveFile() override; 0715 0716 void setReadWrite(bool rw = true) override; 0717 0718 void setModified(bool m) override; 0719 0720 bool isAutoReload(); 0721 KToggleAction *autoReloadToggleAction() 0722 { 0723 return m_autoReloadMode; 0724 }; 0725 void delayAutoReload(); 0726 0727 private Q_SLOTS: 0728 void autoReloadToggled(bool b); 0729 0730 private: 0731 KTEXTEDITOR_NO_EXPORT 0732 void activateDirWatch(const QString &useFileName = QString()); 0733 KTEXTEDITOR_NO_EXPORT 0734 void deactivateDirWatch(); 0735 0736 QString m_dirWatchFile; 0737 0738 /** 0739 * Make backup copy during saveFile, if configured that way. 0740 * @return success? else saveFile should return false and not write the file 0741 */ 0742 KTEXTEDITOR_NO_EXPORT 0743 bool createBackupFile(); 0744 0745 public: 0746 /** 0747 * Type chars in a view. 0748 * Characters are filtered in KateViewInternal::isAcceptableInput() before calling typeChars. 0749 * 0750 * @param view view that received the input 0751 * @param chars characters to type 0752 */ 0753 void typeChars(KTextEditor::ViewPrivate *view, QString chars); 0754 0755 /** 0756 * gets the last line number (lines() - 1) 0757 */ 0758 inline int lastLine() const 0759 { 0760 return lines() - 1; 0761 } 0762 0763 // Repaint all of all of the views 0764 void repaintViews(bool paintOnlyDirty = true); 0765 0766 KateHighlighting *highlight() const; 0767 0768 public Q_SLOTS: 0769 void tagLines(KTextEditor::LineRange lineRange); 0770 void tagLine(int line); 0771 0772 private Q_SLOTS: 0773 void internalHlChanged(); 0774 0775 public: 0776 void addView(KTextEditor::View *); 0777 /** removes the view from the list of views. The view is *not* deleted. 0778 * That's your job. Or, easier, just delete the view in the first place. 0779 * It will remove itself. TODO: this could be converted to a private slot 0780 * connected to the view's destroyed() signal. It is not currently called 0781 * anywhere except from the KTextEditor::ViewPrivate destructor. 0782 */ 0783 void removeView(KTextEditor::View *); 0784 void setActiveView(KTextEditor::View *); 0785 0786 bool ownedView(KTextEditor::ViewPrivate *); 0787 0788 int toVirtualColumn(int line, int column) const; 0789 int toVirtualColumn(const KTextEditor::Cursor) const; 0790 int fromVirtualColumn(int line, int column) const; 0791 int fromVirtualColumn(const KTextEditor::Cursor) const; 0792 0793 enum NewLineIndent { Indent, NoIndent }; 0794 enum NewLinePos { Normal, Above, Below }; 0795 0796 void newLine(KTextEditor::ViewPrivate *view, NewLineIndent indent = NewLineIndent::Indent, NewLinePos newLinePos = Normal); // Changes input 0797 void backspace(KTextEditor::ViewPrivate *view); 0798 void del(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor); 0799 void transpose(const KTextEditor::Cursor); 0800 void swapTextRanges(KTextEditor::Range firstWord, KTextEditor::Range secondWord); 0801 bool multiPaste(KTextEditor::ViewPrivate *view, const QStringList &texts); 0802 void paste(KTextEditor::ViewPrivate *view, const QString &text); 0803 0804 public: 0805 enum CommentType { 0806 UnComment = -1, 0807 ToggleComment = 0, 0808 Comment = 1, 0809 }; 0810 0811 private: 0812 // Helper function for use with multiple cursors 0813 KTEXTEDITOR_NO_EXPORT 0814 KTextEditor::Cursor backspaceAtCursor(KTextEditor::ViewPrivate *v, KTextEditor::Cursor c); 0815 void commentSelection(KTextEditor::Range selection, KTextEditor::Cursor c, bool blockSelect, CommentType changeType); 0816 // exported for katedocument_test 0817 KTEXTEDITOR_NO_EXPORT 0818 bool skipAutoBrace(QChar closingBracket, KTextEditor::Cursor pos); 0819 0820 public: 0821 void indent(KTextEditor::Range range, int change); 0822 void comment(KTextEditor::ViewPrivate *view, uint line, uint column, CommentType change); 0823 void align(KTextEditor::ViewPrivate *view, KTextEditor::Range range); 0824 void alignOn(KTextEditor::Range range, const QString &pattern, bool blockwise); 0825 void insertTab(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor); 0826 0827 enum TextTransform { Uppercase, Lowercase, Capitalize }; 0828 0829 /** 0830 Handling uppercase, lowercase and capitalize for the view. 0831 0832 If there is a selection, that is transformed, otherwise for uppercase or 0833 lowercase the character right of the cursor is transformed, for capitalize 0834 the word under the cursor is transformed. 0835 */ 0836 void transform(KTextEditor::ViewPrivate *view, KTextEditor::Cursor, TextTransform); 0837 /** 0838 Unwrap a range of lines. 0839 */ 0840 void joinLines(uint first, uint last); 0841 0842 private: 0843 KTEXTEDITOR_NO_EXPORT 0844 void transformCursorOrRange(KTextEditor::ViewPrivate *view, const KTextEditor::Cursor, KTextEditor::Range selection, TextTransform); 0845 0846 KTEXTEDITOR_NO_EXPORT 0847 bool removeStringFromBeginning(int line, const QString &str); 0848 KTEXTEDITOR_NO_EXPORT 0849 bool removeStringFromEnd(int line, const QString &str); 0850 0851 /** 0852 Expand tabs to spaces in typed text, if enabled. 0853 @param cursorPos The current cursor position for the inserted characters. 0854 @param str The typed characters to expand. 0855 */ 0856 KTEXTEDITOR_NO_EXPORT 0857 QString eventuallyReplaceTabs(const KTextEditor::Cursor cursorPos, const QString &str) const; 0858 0859 /** 0860 Find the position (line and col) of the next char 0861 that is not a space. If found line and col point to the found character. 0862 Otherwise they have both the value -1. 0863 @param line Line of the character which is examined first. 0864 @param col Column of the character which is examined first. 0865 @return True if the specified or a following character is not a space 0866 Otherwise false. 0867 */ 0868 KTEXTEDITOR_NO_EXPORT 0869 bool nextNonSpaceCharPos(int &line, int &col); 0870 0871 /** 0872 Find the position (line and col) of the previous char 0873 that is not a space. If found line and col point to the found character. 0874 Otherwise they have both the value -1. 0875 @return True if the specified or a preceding character is not a space. 0876 Otherwise false. 0877 */ 0878 KTEXTEDITOR_NO_EXPORT 0879 bool previousNonSpaceCharPos(int &line, int &col); 0880 0881 /** 0882 * Sets a comment marker as defined by the language providing the attribute 0883 * @p attrib on the line @p line 0884 */ 0885 KTEXTEDITOR_NO_EXPORT 0886 void addStartLineCommentToSingleLine(int line, int attrib = 0); 0887 /** 0888 * Removes a comment marker as defined by the language providing the attribute 0889 * @p attrib on the line @p line 0890 */ 0891 KTEXTEDITOR_NO_EXPORT 0892 bool removeStartLineCommentFromSingleLine(int line, int attrib = 0); 0893 0894 /** 0895 * @see addStartLineCommentToSingleLine. 0896 */ 0897 KTEXTEDITOR_NO_EXPORT 0898 void addStartStopCommentToSingleLine(int line, int attrib = 0); 0899 /** 0900 *@see removeStartLineCommentFromSingleLine. 0901 */ 0902 KTEXTEDITOR_NO_EXPORT 0903 bool removeStartStopCommentFromSingleLine(int line, int attrib = 0); 0904 /** 0905 *@see removeStartLineCommentFromSingleLine. 0906 */ 0907 KTEXTEDITOR_NO_EXPORT 0908 bool removeStartStopCommentFromRegion(const KTextEditor::Cursor start, const KTextEditor::Cursor end, int attrib = 0); 0909 0910 /** 0911 * Add a comment marker as defined by the language providing the attribute 0912 * @p attrib to each line in the selection. 0913 */ 0914 KTEXTEDITOR_NO_EXPORT 0915 void addStartStopCommentToSelection(KTextEditor::Range, bool blockSelection, int attrib = 0); 0916 /** 0917 * @see addStartStopCommentToSelection. 0918 */ 0919 KTEXTEDITOR_NO_EXPORT 0920 void addStartLineCommentToSelection(KTextEditor::Range, int attrib = 0); 0921 0922 /** 0923 * Removes comment markers relevant to the language providing 0924 * the attribute @p attrib from each line in the selection. 0925 * 0926 * @return whether the operation succeeded. 0927 */ 0928 KTEXTEDITOR_NO_EXPORT 0929 bool removeStartStopCommentFromSelection(KTextEditor::Range, int attrib = 0); 0930 /** 0931 * @see removeStartStopCommentFromSelection. 0932 */ 0933 KTEXTEDITOR_NO_EXPORT 0934 bool removeStartLineCommentFromSelection(KTextEditor::Range, int attrib, bool toggleComment); 0935 0936 public: 0937 KTextEditor::Range findMatchingBracket(const KTextEditor::Cursor start, int maxLines); 0938 0939 public: 0940 QString documentName() const override 0941 { 0942 return m_docName; 0943 } 0944 0945 private: 0946 KTEXTEDITOR_NO_EXPORT 0947 void updateDocName(); 0948 KTEXTEDITOR_NO_EXPORT 0949 static void uniquifyDocNames(const std::vector<KTextEditor::DocumentPrivate *> &docs); 0950 0951 public: 0952 /** 0953 * @return whether the document is modified on disk since last saved 0954 */ 0955 bool isModifiedOnDisc() 0956 { 0957 return m_modOnHd; 0958 } 0959 0960 void setModifiedOnDisk(ModifiedOnDiskReason reason) override; 0961 0962 void setModifiedOnDiskWarning(bool on) override; 0963 0964 public Q_SLOTS: 0965 /** 0966 * Ask the user what to do, if the file has been modified on disk. 0967 * Reimplemented from KTextEditor::Document. 0968 */ 0969 virtual void slotModifiedOnDisk(KTextEditor::View *v = nullptr); 0970 0971 /** 0972 * Reloads the current document from disk if possible 0973 */ 0974 bool documentReload() override; 0975 0976 bool documentSave() override; 0977 bool documentSaveAs() override; 0978 bool documentSaveAsWithEncoding(const QString &encoding); 0979 void documentSaveCopyAs(); 0980 0981 bool save() override; 0982 0983 public: 0984 bool saveAs(const QUrl &url) override; 0985 0986 private: 0987 // helper to handle the embedded notification for externally modified files 0988 QPointer<KateModOnHdPrompt> m_modOnHdHandler; 0989 0990 private Q_SLOTS: 0991 void onModOnHdSaveAs(); 0992 void onModOnHdClose(); 0993 void onModOnHdReload(); 0994 void onModOnHdAutoReload(); 0995 void onModOnHdIgnore(); 0996 0997 public: 0998 bool setEncoding(const QString &e) override; 0999 QString encoding() const override; 1000 1001 public Q_SLOTS: 1002 void setWordWrap(bool on); 1003 void setWordWrapAt(uint col); 1004 1005 public: 1006 bool wordWrap() const; 1007 uint wordWrapAt() const; 1008 1009 public Q_SLOTS: 1010 void setPageUpDownMovesCursor(bool on); 1011 1012 public: 1013 bool pageUpDownMovesCursor() const; 1014 1015 // code folding 1016 public: 1017 /** 1018 * Same as plainKateTextLine(), except that it is made sure 1019 * the line is highlighted. 1020 */ 1021 Kate::TextLine kateTextLine(int i); 1022 1023 //! @copydoc KateBuffer::plainLine() 1024 Kate::TextLine plainKateTextLine(int i); 1025 1026 Q_SIGNALS: 1027 void aboutToRemoveText(KTextEditor::Range); 1028 1029 private Q_SLOTS: 1030 void slotModOnHdDirty(const QString &path); 1031 void slotModOnHdCreated(const QString &path); 1032 void slotModOnHdDeleted(const QString &path); 1033 void slotDelayedHandleModOnHd(); 1034 1035 private: 1036 /** 1037 * Create a git compatible sha1 checksum of the file, if it is a local file. 1038 * The result can be accessed through KateBuffer::digest(). 1039 * 1040 * @return whether the operation was attempted and succeeded. 1041 */ 1042 bool createDigest(); 1043 // exported for katedocument_test 1044 1045 /** 1046 * create a string for the modonhd warnings, giving the reason. 1047 */ 1048 KTEXTEDITOR_NO_EXPORT 1049 QString reasonedMOHString() const; 1050 1051 /** 1052 * Removes all trailing whitespace in the document and add new line at eof 1053 * if configured that way. 1054 */ 1055 KTEXTEDITOR_NO_EXPORT 1056 void removeTrailingSpacesAndAddNewLineAtEof(); 1057 1058 public: 1059 /** 1060 * This function doesn't check for config and is 1061 * available for use all the time via an action 1062 */ 1063 void removeAllTrailingSpaces(); 1064 1065 /** 1066 * Returns a git compatible sha1 checksum of this document on disk. 1067 * @return checksum for this document on disk 1068 */ 1069 QByteArray checksum() const override; 1070 1071 /** 1072 * @return false if @p newType is an invalid mode. 1073 */ 1074 bool updateFileType(const QString &newType, bool user = false); 1075 1076 QString fileType() const 1077 { 1078 return m_fileType; 1079 } 1080 1081 /** 1082 * Get access to buffer of this document. 1083 * Is needed to create cursors and ranges for example. 1084 * @return document buffer 1085 */ 1086 KateBuffer &buffer() 1087 { 1088 return *m_buffer; 1089 } 1090 1091 /** 1092 * set indentation mode by user 1093 * this will remember that a user did set it and will avoid reset on save 1094 */ 1095 void rememberUserDidSetIndentationMode() 1096 { 1097 m_indenterSetByUser = true; 1098 } 1099 1100 /** 1101 * User did set encoding for next reload => enforce it! 1102 */ 1103 void userSetEncodingForNextReload() 1104 { 1105 m_userSetEncodingForNextReload = true; 1106 } 1107 1108 // 1109 // REALLY internal data ;) 1110 // 1111 private: 1112 // text buffer 1113 KateBuffer *const m_buffer; 1114 1115 // indenter 1116 KateAutoIndent *const m_indenter; 1117 1118 bool m_hlSetByUser = false; 1119 bool m_bomSetByUser = false; 1120 bool m_indenterSetByUser = false; 1121 bool m_userSetEncodingForNextReload = false; 1122 1123 bool m_modOnHd = false; 1124 KToggleAction *m_autoReloadMode; 1125 QTimer m_autoReloadThrottle; 1126 ModifiedOnDiskReason m_modOnHdReason = OnDiskUnmodified; 1127 ModifiedOnDiskReason m_prevModOnHdReason = OnDiskUnmodified; 1128 1129 QString m_docName; 1130 int m_docNameNumber = 0; 1131 1132 // file type !!! 1133 QString m_fileType; 1134 bool m_fileTypeSetByUser = false; 1135 1136 /** 1137 * document is still reloading a file 1138 */ 1139 bool m_reloading = false; 1140 1141 public Q_SLOTS: 1142 void slotQueryClose_save(bool *handled, bool *abortClosing); 1143 1144 public: 1145 bool queryClose() override; 1146 1147 /** 1148 * Configuration 1149 */ 1150 public: 1151 KateDocumentConfig *config() 1152 { 1153 return m_config.get(); 1154 } 1155 KateDocumentConfig *config() const 1156 { 1157 return m_config.get(); 1158 } 1159 1160 void updateConfig(); 1161 1162 private: 1163 KTEXTEDITOR_NO_EXPORT 1164 void makeAttribs(bool needInvalidate = true); 1165 1166 std::unique_ptr<KateDocumentConfig> const m_config; 1167 1168 /** 1169 * Variable Reader 1170 * TODO add register functionality/ktexteditor interface 1171 */ 1172 private: 1173 /** 1174 * read dir config file 1175 */ 1176 KTEXTEDITOR_NO_EXPORT 1177 void readDirConfig(); 1178 1179 /** 1180 Reads all the variables in the document. 1181 Called when opening/saving a document 1182 Returns true if variables were read 1183 */ 1184 bool readVariables(bool onlyViewAndRenderer = false); 1185 // exported for katedocument_test 1186 1187 /** 1188 Reads and applies the variables in a single line 1189 TODO registered variables gets saved in a [map] 1190 */ 1191 void readVariableLine(const QString &t, bool onlyViewAndRenderer = false); 1192 // exported for katedocument_test 1193 /** 1194 Sets a view variable in all the views. 1195 */ 1196 KTEXTEDITOR_NO_EXPORT 1197 void setViewVariable(const QString &var, const QString &val); 1198 /** 1199 @return weather a string value could be converted 1200 to a bool value as supported. 1201 The value is put in *result. 1202 */ 1203 KTEXTEDITOR_NO_EXPORT 1204 static bool checkBoolValue(QString value, bool *result); 1205 /** 1206 @return weather a string value could be converted 1207 to a integer value. 1208 The value is put in *result. 1209 */ 1210 KTEXTEDITOR_NO_EXPORT 1211 static bool checkIntValue(const QString &value, int *result); 1212 /** 1213 Feeds value into @p col using QColor::fromString() and returns 1214 whether the color is valid 1215 */ 1216 KTEXTEDITOR_NO_EXPORT 1217 static bool checkColorValue(const QString &value, QColor &col); 1218 1219 bool m_fileChangedDialogsActivated = false; 1220 1221 // 1222 // KTextEditor::ConfigInterface 1223 // 1224 public: 1225 QStringList configKeys() const override; 1226 QVariant configValue(const QString &key) override; 1227 void setConfigValue(const QString &key, const QVariant &value) override; 1228 1229 // 1230 // KTextEditor::RecoveryInterface 1231 // 1232 public: 1233 bool isDataRecoveryAvailable() const override; 1234 void recoverData() override; 1235 void discardDataRecovery() override; 1236 1237 // 1238 // Highlighting information 1239 // 1240 public: 1241 QStringList embeddedHighlightingModes() const override; 1242 QString highlightingModeAt(KTextEditor::Cursor position) override; 1243 1244 // 1245 // BEGIN: KTextEditor::MessageInterface 1246 // 1247 public: 1248 bool postMessage(KTextEditor::Message *message) override; 1249 1250 public Q_SLOTS: 1251 void messageDestroyed(KTextEditor::Message *message); 1252 1253 private: 1254 QHash<KTextEditor::Message *, QList<std::shared_ptr<QAction>>> m_messageHash; 1255 // END KTextEditor::MessageInterface 1256 1257 public: 1258 QString defaultDictionary() const; 1259 QList<QPair<KTextEditor::MovingRange *, QString>> dictionaryRanges() const; 1260 bool isOnTheFlySpellCheckingEnabled() const; 1261 KateOnTheFlyChecker *onTheFlySpellChecker() const 1262 { 1263 return m_onTheFlyChecker; 1264 } 1265 1266 QString dictionaryForMisspelledRange(KTextEditor::Range range) const; 1267 void clearMisspellingForWord(const QString &word); 1268 1269 public Q_SLOTS: 1270 void clearDictionaryRanges(); 1271 void setDictionary(const QString &dict, KTextEditor::Range range, bool blockmode); 1272 void setDictionary(const QString &dict, KTextEditor::Range range); 1273 void setDefaultDictionary(const QString &dict); 1274 void onTheFlySpellCheckingEnabled(bool enable); 1275 void refreshOnTheFlyCheck(KTextEditor::Range range = KTextEditor::Range::invalid()); 1276 1277 Q_SIGNALS: 1278 void dictionaryRangesPresent(bool yesNo); 1279 void defaultDictionaryChanged(KTextEditor::DocumentPrivate *document); 1280 1281 public: 1282 bool containsCharacterEncoding(KTextEditor::Range range); 1283 1284 typedef QList<QPair<int, int>> OffsetList; 1285 1286 static int computePositionWrtOffsets(const OffsetList &offsetList, int pos); 1287 1288 /** 1289 * The first OffsetList is from decoded to encoded, and the second OffsetList from 1290 * encoded to decoded. 1291 **/ 1292 QString decodeCharacters(KTextEditor::Range range, 1293 KTextEditor::DocumentPrivate::OffsetList &decToEncOffsetList, 1294 KTextEditor::DocumentPrivate::OffsetList &encToDecOffsetList); 1295 void replaceCharactersByEncoding(KTextEditor::Range range); 1296 1297 protected: 1298 KateOnTheFlyChecker *m_onTheFlyChecker = nullptr; 1299 QString m_defaultDictionary; 1300 QList<QPair<KTextEditor::MovingRange *, QString>> m_dictionaryRanges; 1301 1302 // from KTextEditor::MovingRangeFeedback 1303 void rangeInvalid(KTextEditor::MovingRange *movingRange) override; 1304 void rangeEmpty(KTextEditor::MovingRange *movingRange) override; 1305 1306 void deleteDictionaryRange(KTextEditor::MovingRange *movingRange); 1307 1308 private: 1309 Kate::SwapFile *m_swapfile; 1310 1311 public: 1312 Kate::SwapFile *swapFile(); 1313 1314 // helpers for scripting and codefolding 1315 KSyntaxHighlighting::Theme::TextStyle defStyleNum(int line, int column); 1316 bool isComment(int line, int column); 1317 1318 public: 1319 /** 1320 * Find the next modified/saved line, starting at @p startLine. If @p down 1321 * is \e true, the search is performed downwards, otherwise upwards. 1322 * @return the touched line in the requested search direction, or -1 if not found 1323 */ 1324 int findTouchedLine(int startLine, bool down); 1325 1326 private Q_SLOTS: 1327 /** 1328 * watch for all started io jobs to remember if file is perhaps loading atm 1329 * @param job started job 1330 */ 1331 void slotStarted(KIO::Job *job); 1332 void slotCompleted(); 1333 void slotCanceled(); 1334 1335 /** 1336 * trigger display of loading message, after 1000 ms 1337 */ 1338 void slotTriggerLoadingMessage(); 1339 1340 /** 1341 * Abort loading 1342 */ 1343 void slotAbortLoading(); 1344 1345 void slotUrlChanged(const QUrl &url); 1346 1347 private: 1348 /** 1349 * different possible states 1350 */ 1351 enum DocumentStates { 1352 /** 1353 * Idle 1354 */ 1355 DocumentIdle, 1356 1357 /** 1358 * Loading 1359 */ 1360 DocumentLoading, 1361 1362 /** 1363 * Saving 1364 */ 1365 DocumentSaving, 1366 1367 /** 1368 * Pre Saving As, this is between ::saveAs is called and ::save 1369 */ 1370 DocumentPreSavingAs, 1371 1372 /** 1373 * Saving As 1374 */ 1375 DocumentSavingAs 1376 }; 1377 1378 /** 1379 * current state 1380 */ 1381 DocumentStates m_documentState = DocumentIdle; 1382 1383 /** 1384 * read-write state before loading started 1385 */ 1386 bool m_readWriteStateBeforeLoading = false; 1387 1388 /** 1389 * if the document is untitled 1390 */ 1391 bool m_isUntitled = true; 1392 /** 1393 * loading job, we want to cancel with cancel in the loading message 1394 */ 1395 QPointer<KJob> m_loadingJob; 1396 1397 /** 1398 * message to show during loading 1399 */ 1400 QPointer<KTextEditor::Message> m_loadingMessage; 1401 1402 /** 1403 * Was there any open error on last file loading? 1404 */ 1405 bool m_openingError = false; 1406 1407 public: 1408 /** 1409 * reads the line length limit from config, if it is not overridden 1410 */ 1411 int lineLengthLimit() const; 1412 1413 public Q_SLOTS: 1414 void openWithLineLengthLimitOverride(); 1415 1416 private: 1417 /** 1418 * timer for delayed handling of mod on hd 1419 */ 1420 QTimer m_modOnHdTimer; 1421 1422 private: 1423 /** 1424 * currently active template handler; there can be only one 1425 */ 1426 QPointer<KateTemplateHandler> m_activeTemplateHandler; 1427 1428 private: 1429 /** 1430 * current autobrace range 1431 */ 1432 std::unique_ptr<KTextEditor::MovingRange> m_currentAutobraceRange; 1433 /** 1434 * current autobrace closing character (e.g. ']') 1435 */ 1436 QChar m_currentAutobraceClosingChar; 1437 1438 private Q_SLOTS: 1439 void checkCursorForAutobrace(KTextEditor::View *view, const KTextEditor::Cursor newPos); 1440 1441 public: 1442 void setActiveTemplateHandler(KateTemplateHandler *handler); 1443 1444 Q_SIGNALS: 1445 void loaded(KTextEditor::DocumentPrivate *document); 1446 1447 private: 1448 QList<KTextEditor::View *> m_views; 1449 QTimer m_autoSaveTimer; 1450 }; 1451 1452 #endif