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