Index: src/data/katepart5ui.rc =================================================================== --- src/data/katepart5ui.rc +++ src/data/katepart5ui.rc @@ -1,5 +1,5 @@ - + &File @@ -60,6 +60,11 @@ + Auto Reload + + + + Word Wrap Index: src/dialogs/katedialogs.h =================================================================== --- src/dialogs/katedialogs.h +++ src/dialogs/katedialogs.h @@ -318,7 +318,7 @@ * This dialog will prompt the user for what do with a file that is * modified on disk. * If the file wasn't deleted, it has a 'diff' button, which will create - * a diff file (uing diff(1)) and launch that using KRun. + * a diff file (using diff(1)) and launch that using KRun. */ class KateModOnHdPrompt : public QObject { @@ -340,6 +340,7 @@ void saveAsTriggered(); void ignoreTriggered(); void reloadTriggered(); + void autoReloadTriggered(); private Q_SLOTS: /** Index: src/dialogs/katedialogs.cpp =================================================================== --- src/dialogs/katedialogs.cpp +++ src/dialogs/katedialogs.cpp @@ -1273,6 +1273,12 @@ // If the file isn't deleted, present a diff button const bool onDiskDeleted = modtype == KTextEditor::ModificationInterface::OnDiskDeleted; if (!onDiskDeleted) { + QAction * aAutoReload = new QAction(i18n("Enable Auto Reload"), this); + aAutoReload->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); + aAutoReload->setToolTip(i18n("Will never again warn about on disk changes but always reload.")); + m_message->addAction(aAutoReload, false); + connect(aAutoReload, &QAction::triggered, this, &KateModOnHdPrompt::autoReloadTriggered); + if (!QStandardPaths::findExecutable(QStringLiteral("diff")).isEmpty()) { m_diffAction = new QAction(i18n("View &Difference"), this); m_diffAction->setToolTip(i18n("Shows a diff of the changes")); Index: src/document/katedocument.h =================================================================== --- src/document/katedocument.h +++ src/document/katedocument.h @@ -69,6 +69,7 @@ class KateAutoIndent; class KateModOnHdPrompt; +class KToggleAction; /** * @brief Backend of KTextEditor::Document related public KTextEditor interfaces. @@ -760,6 +761,12 @@ void setModified(bool m) override; + bool isAutoReload(); + KToggleAction* autoReloadToggleAction() { return m_autoReloadMode; }; + +private Q_SLOTS: + void autoReloadToggled(bool b); + private: void activateDirWatch(const QString &useFileName = QString()); void deactivateDirWatch(); @@ -982,6 +989,7 @@ private Q_SLOTS: void onModOnHdSaveAs(); void onModOnHdReload(); + void onModOnHdAutoReload(); void onModOnHdIgnore(); public: @@ -1098,6 +1106,8 @@ bool m_userSetEncodingForNextReload = false; bool m_modOnHd = false; + KToggleAction* m_autoReloadMode; + QTimer m_autoReloadThrottle; ModifiedOnDiskReason m_modOnHdReason = OnDiskUnmodified; ModifiedOnDiskReason m_prevModOnHdReason = OnDiskUnmodified; Index: src/document/katedocument.cpp =================================================================== --- src/document/katedocument.cpp +++ src/document/katedocument.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #include @@ -263,6 +264,15 @@ m_modOnHdTimer.setInterval(200); connect(&m_modOnHdTimer, SIGNAL(timeout()), this, SLOT(slotDelayedHandleModOnHd())); + // Setup auto reload stuff + m_autoReloadMode = new KToggleAction(i18n("Auto Reload Document"), this); + m_autoReloadMode->setWhatsThis(i18n("Automatic reload the docuemnt when it was changed on disk")); + connect(m_autoReloadMode, &KToggleAction::triggered, this, &DocumentPrivate::autoReloadToggled); + // Prepare some reload amok protector + m_autoReloadThrottle.setSingleShot(true); + m_autoReloadThrottle.setInterval(3000); + connect(&m_autoReloadThrottle, &QTimer::timeout, this, &DocumentPrivate::onModOnHdAutoReload); + /** * load handling * this is needed to ensure we signal the user if a file ist still loading @@ -4226,6 +4236,11 @@ return; } + if (!isModified() && isAutoReload()) { + onModOnHdAutoReload(); + return; + } + if (!m_fileChangedDialogsActivated || m_modOnHdHandler) { return; } @@ -4239,6 +4254,7 @@ m_modOnHdHandler = new KateModOnHdPrompt(this, m_modOnHdReason, reasonedMOHString()); connect(m_modOnHdHandler.data(), &KateModOnHdPrompt::saveAsTriggered, this, &DocumentPrivate::onModOnHdSaveAs); connect(m_modOnHdHandler.data(), &KateModOnHdPrompt::reloadTriggered, this, &DocumentPrivate::onModOnHdReload); + connect(m_modOnHdHandler.data(), &KateModOnHdPrompt::autoReloadTriggered, this, &DocumentPrivate::onModOnHdAutoReload); connect(m_modOnHdHandler.data(), &KateModOnHdPrompt::ignoreTriggered, this, &DocumentPrivate::onModOnHdIgnore); } @@ -4271,6 +4287,41 @@ delete m_modOnHdHandler; } +void KTextEditor::DocumentPrivate::autoReloadToggled(bool b) +{ + m_autoReloadMode->setChecked(b); + if (b) { + connect(&m_modOnHdTimer, &QTimer::timeout, this, &DocumentPrivate::onModOnHdAutoReload); + } else { + disconnect(&m_modOnHdTimer, &QTimer::timeout, this, &DocumentPrivate::onModOnHdAutoReload); + } +} + +bool KTextEditor::DocumentPrivate::isAutoReload() +{ + return m_autoReloadMode->isChecked(); +} + +void KTextEditor::DocumentPrivate::onModOnHdAutoReload() +{ + if (m_modOnHdHandler) { + delete m_modOnHdHandler; + m_autoReloadMode->setChecked(true); + } + + if (!isAutoReload()) { + return; + } + + if (m_modOnHd && !m_reloading && !m_autoReloadThrottle.isActive()) { + m_modOnHd = false; + m_prevModOnHdReason = OnDiskUnmodified; + emit modifiedOnDisk(this, false, OnDiskUnmodified); + documentReload(); + m_autoReloadThrottle.start(); + } +} + void KTextEditor::DocumentPrivate::onModOnHdIgnore() { // ignore as long as m_prevModOnHdReason == m_modOnHdReason Index: src/view/kateview.h =================================================================== --- src/view/kateview.h +++ src/view/kateview.h @@ -683,12 +683,14 @@ void exportHtmlToFile(const QString &file); private Q_SLOTS: + void slotDocumentReloaded(); + void slotDocumentAboutToReload(); void slotGotFocus(); void slotLostFocus(); void slotSaveCanceled(const QString &error); void slotConfigDialog(); - void exportHtmlToClipboard (); - void exportHtmlToFile (); + void exportHtmlToClipboard(); + void exportHtmlToFile(); public Q_SLOTS: void slotFoldToplevelNodes(); @@ -703,10 +705,11 @@ void setupEditActions(); void setupCodeFolding(); - QList m_editActions; + QList m_editActions; QAction *m_editUndo; QAction *m_editRedo; QAction *m_pasteMenu; + bool m_gotoBottomAfterReload; KToggleAction *m_toggleFoldingMarkers; KToggleAction *m_toggleIconBar; KToggleAction *m_toggleLineNumbers; Index: src/view/kateview.cpp =================================================================== --- src/view/kateview.cpp +++ src/view/kateview.cpp @@ -235,6 +235,9 @@ connect(m_doc, SIGNAL(aboutToReload(KTextEditor::Document*)), SLOT(saveFoldingState())); connect(m_doc, SIGNAL(reloaded(KTextEditor::Document*)), SLOT(applyFoldingState())); + connect(m_doc, &KTextEditor::DocumentPrivate::reloaded, this, &KTextEditor::ViewPrivate::slotDocumentReloaded); + connect(m_doc, &KTextEditor::DocumentPrivate::aboutToReload, this, &KTextEditor::ViewPrivate::slotDocumentAboutToReload); + // update highlights on scrolling and co connect(this, SIGNAL(displayRangeChanged(KTextEditor::ViewPrivate*)), this, SLOT(createHighlights())); @@ -748,6 +751,9 @@ a->setWhatsThis(i18n("Show/hide the mini-map on the vertical scrollbar.

The mini-map shows an overview of the whole document.")); connect(a, SIGNAL(triggered(bool)), SLOT(toggleScrollBarMiniMap())); + a = m_doc->autoReloadToggleAction(); + ac->addAction(QStringLiteral("view_auto_reload"), a); + // a = m_toggleScrollBarMiniMapAll = toggleAction = new KToggleAction(i18n("Show the whole document in the Mini-Map"), this); // ac->addAction(QLatin1String("view_scrollbar_minimap_all"), a); // a->setWhatsThis(i18n("Display the whole document in the mini-map.

With this option set the whole document will be visible in the mini-map.")); @@ -1316,6 +1322,19 @@ emit viewModeChanged(this, viewMode()); } +void KTextEditor::ViewPrivate::slotDocumentAboutToReload() +{ + m_gotoBottomAfterReload = doc()->isAutoReload(); + m_gotoBottomAfterReload &= m_viewInternal->endPos().line() == doc()->lastLine(); +} + +void KTextEditor::ViewPrivate::slotDocumentReloaded() +{ + if (m_gotoBottomAfterReload) { + bottom(); + } +} + void KTextEditor::ViewPrivate::slotGotFocus() { //qCDebug(LOG_KTE) << "KTextEditor::ViewPrivate::slotGotFocus";