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, SIGNAL(triggered()), this, SIGNAL(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 @@ -744,6 +744,9 @@ void setModified(bool m) override; + void setAutoReload(bool b) { m_autoReloadMode = b; }; + bool isAutoReload() { return m_autoReloadMode; }; + private: void activateDirWatch(const QString &useFileName = QString()); void deactivateDirWatch(); @@ -966,6 +969,7 @@ private Q_SLOTS: void onModOnHdSaveAs(); void onModOnHdReload(); + void onModOnHdAutoReload(); void onModOnHdIgnore(); public: @@ -1082,6 +1086,8 @@ bool m_userSetEncodingForNextReload = false; bool m_modOnHd = false; + bool m_autoReloadMode = false; + QTimer m_autoReloadThrottle; ModifiedOnDiskReason m_modOnHdReason = OnDiskUnmodified; ModifiedOnDiskReason m_prevModOnHdReason = OnDiskUnmodified; Index: src/document/katedocument.cpp =================================================================== --- src/document/katedocument.cpp +++ src/document/katedocument.cpp @@ -263,6 +263,10 @@ m_modOnHdTimer.setInterval(200); connect(&m_modOnHdTimer, SIGNAL(timeout()), this, SLOT(slotDelayedHandleModOnHd())); + // Prepare some reload amok protector, no connect + m_autoReloadThrottle.setSingleShot(true); + m_autoReloadThrottle.setInterval(1000); + /** * load handling * this is needed to ensure we signal the user if a file ist still loading @@ -2830,6 +2834,7 @@ m_undoManager->setModified(m); } + //END //BEGIN Kate specific stuff ;) @@ -4165,6 +4170,11 @@ return; } + if (!isModified() && m_autoReloadMode) { + onModOnHdAutoReload(); + return; + } + if (!m_fileChangedDialogsActivated || m_modOnHdHandler) { return; } @@ -4178,6 +4188,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); } @@ -4210,6 +4221,25 @@ delete m_modOnHdHandler; } +void KTextEditor::DocumentPrivate::onModOnHdAutoReload() +{ + if (m_modOnHdHandler) { + delete m_modOnHdHandler; + m_autoReloadMode = true; + } + + if (!m_reloading && !m_autoReloadThrottle.isActive()) { + m_modOnHd = false; + m_prevModOnHdReason = OnDiskUnmodified; + emit modifiedOnDisk(this, false, OnDiskUnmodified); + documentReload(); + m_autoReloadThrottle.start(); + } else { + // Don't drop some triggered hint completely + QTimer::singleShot(m_autoReloadThrottle.remainingTime(), this, &DocumentPrivate::onModOnHdAutoReload); + } +} + 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 @@ -682,12 +682,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(); @@ -702,10 +704,13 @@ void setupEditActions(); void setupCodeFolding(); - QList m_editActions; + QList m_editActions; QAction *m_editUndo; QAction *m_editRedo; QAction *m_pasteMenu; + KToggleAction *m_toggleAutoReload; + KToggleAction *m_toggleFollowAfterReload; + 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, SIGNAL(reloaded(KTextEditor::Document*)), SLOT(slotDocumentReloaded())); + connect(m_doc, SIGNAL(aboutToReload(KTextEditor::Document*)), SLOT(slotDocumentAboutToReload())); + // update highlights on scrolling and co connect(this, SIGNAL(displayRangeChanged(KTextEditor::ViewPrivate*)), this, SLOT(createHighlights())); @@ -747,6 +750,19 @@ 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_toggleAutoReload = new KToggleAction(i18n("Auto Reload Document"), this); + ac->addAction(QStringLiteral("view_auto_reload"), a); +// ac->setDefaultShortcut(a, QKeySequence(Qt::Key_F10)); + a->setWhatsThis(i18n("Automatic reload the docuemnt when it was changed on disk")); + connect(a, &KToggleAction::triggered, [=] { if (m_doc) { m_doc->setAutoReload(m_toggleAutoReload->isChecked()); }}); + + a = m_toggleFollowAfterReload = new KToggleAction(i18n("Follow"), this); + ac->addAction(QStringLiteral("view_auto_follow"), a); +// ac->setDefaultShortcut(a, QKeySequence(Qt::Key_F10)); + a->setWhatsThis(i18n("Keep the view in a smart way at the end of the document after reload")); +// connect(a, &KToggleAction::triggered, [=] { }); + + // 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.")); @@ -1315,6 +1331,21 @@ emit viewModeChanged(this, viewMode()); } +void KTextEditor::ViewPrivate::slotDocumentAboutToReload() +{ + m_gotoBottomAfterReload = doc()->isAutoReload() && m_toggleFollowAfterReload->isChecked(); + m_gotoBottomAfterReload &= m_viewInternal->endPos().line() == doc()->lastLine(); +} + +void KTextEditor::ViewPrivate::slotDocumentReloaded() +{ + m_toggleAutoReload->setChecked(doc()->isAutoReload()); + m_toggleFollowAfterReload->setEnabled(doc()->isAutoReload()); + if (m_gotoBottomAfterReload) { + bottom(); + } +} + void KTextEditor::ViewPrivate::slotGotFocus() { //qCDebug(LOG_KTE) << "KTextEditor::ViewPrivate::slotGotFocus";