From 141b404240ccece2316f1728e7a307c2746d6c1d Mon Sep 17 00:00:00 2001 From: Le Tan Date: Wed, 15 Nov 2017 19:45:33 +0800 Subject: [PATCH] support file change check --- src/resources/icons/reading_modified.svg | 14 +++++++ src/resources/vnote.ini | 3 ++ src/vconfigmanager.cpp | 6 +++ src/vconfigmanager.h | 11 +++++ src/vedit.cpp | 11 ----- src/veditarea.cpp | 21 ++++++++++ src/veditarea.h | 6 +++ src/veditor.cpp | 12 ------ src/vedittab.cpp | 52 +++++++++++++++++++++++- src/vedittab.h | 17 +++++++- src/veditwindow.cpp | 52 +++++++++++++++++++++--- src/veditwindow.h | 21 +++++++--- src/vfile.cpp | 21 ++++++---- src/vfile.h | 26 +++++------- src/vhtmltab.cpp | 20 +++++++-- src/vhtmltab.h | 4 ++ src/vmainwindow.cpp | 2 +- src/vmdtab.cpp | 30 ++++++++++++-- src/vmdtab.h | 4 ++ src/vnote.qrc | 1 + 20 files changed, 267 insertions(+), 67 deletions(-) create mode 100644 src/resources/icons/reading_modified.svg diff --git a/src/resources/icons/reading_modified.svg b/src/resources/icons/reading_modified.svg new file mode 100644 index 00000000..217b2c30 --- /dev/null +++ b/src/resources/icons/reading_modified.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 364616ce..f5234460 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -152,6 +152,9 @@ startup_page_type=0 ; C:\users\vnote\vnote.md -> C:\\users\\vnote\\vnote.md startup_pages= +; Timer interval to check file modification or save file to tmp file in milliseconds +file_timer_interval=2000 + [web] ; Location and configuration for Mathjax mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 44d817c6..944a7bee 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -262,6 +262,12 @@ void VConfigManager::initialize() "startup_pages").toStringList(); initFromSessionSettings(); + + m_fileTimerInterval = getConfigFromSettings("global", + "file_timer_interval").toInt(); + if (m_fileTimerInterval < 100) { + m_fileTimerInterval = 100; + } } void VConfigManager::initSettings() diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index faf1bee5..97b5a8e2 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -372,6 +372,9 @@ public: // Read all available mdhl files in c_styleConfigFolder. QVector getEditorStyles() const; + // Return the timer interval for checking file. + int getFileTimerInterval() const; + private: // Look up a config from user and default settings. QVariant getConfigFromSettings(const QString §ion, const QString &key) const; @@ -703,6 +706,9 @@ private: // File paths to open on startup. QStringList m_startupPages; + // Timer interval to check file in milliseconds. + int m_fileTimerInterval; + // The name of the config file in each directory, obsolete. // Use c_dirConfigFile instead. static const QString c_obsoleteDirConfigFile; @@ -1779,4 +1785,9 @@ inline void VConfigManager::setStartupPages(const QStringList &p_pages) setConfigToSettings("global", "startup_pages", m_startupPages); } +inline int VConfigManager::getFileTimerInterval() const +{ + return m_fileTimerInterval; +} + #endif // VCONFIGMANAGER_H diff --git a/src/vedit.cpp b/src/vedit.cpp index ffe6debc..fb89ceb8 100644 --- a/src/vedit.cpp +++ b/src/vedit.cpp @@ -48,9 +48,6 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent) connect(m_highlightTimer, &QTimer::timeout, this, &VEdit::doHighlightExtraSelections); - connect(document(), &QTextDocument::modificationChanged, - (VFile *)m_file, &VFile::setModified); - m_extraSelections.resize((int)SelectionId::MaxSelection); updateFontAndPalette(); @@ -80,10 +77,6 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent) VEdit::~VEdit() { - if (m_file) { - disconnect(document(), &QTextDocument::modificationChanged, - (VFile *)m_file, &VFile::setModified); - } } void VEdit::updateConfig() @@ -146,16 +139,12 @@ bool VEdit::scrollToBlock(int p_blockNumber) bool VEdit::isModified() const { - Q_ASSERT(m_file ? (m_file->isModified() == document()->isModified()) : true); return document()->isModified(); } void VEdit::setModified(bool p_modified) { document()->setModified(p_modified); - if (m_file) { - m_file->setModified(p_modified); - } } void VEdit::insertImage() diff --git a/src/veditarea.cpp b/src/veditarea.cpp index 3010f851..87f1cfb8 100644 --- a/src/veditarea.cpp +++ b/src/veditarea.cpp @@ -53,6 +53,14 @@ VEditArea::VEditArea(QWidget *parent) win->focusNextTab(false); } }); + + QTimer *timer = new QTimer(this); + timer->setSingleShot(false); + timer->setInterval(g_config->getFileTimerInterval()); + connect(timer, &QTimer::timeout, + this, &VEditArea::handleFileTimerTimeout); + + timer->start(); } void VEditArea::setupUI() @@ -1016,3 +1024,16 @@ void VEditArea::recordClosedFile(const VFileSessionInfo &p_file) m_lastClosedFiles.push(p_file); qDebug() << "pushed closed file" << p_file.m_file; } + +void VEditArea::handleFileTimerTimeout() +{ + checkFileChangeOutside(); +} + +void VEditArea::checkFileChangeOutside() +{ + int nrWin = splitter->count(); + for (int i = 0; i < nrWin; ++i) { + getWindow(i)->checkFileChangeOutside(); + } +} diff --git a/src/veditarea.h b/src/veditarea.h index d95a63be..ccbc48a9 100644 --- a/src/veditarea.h +++ b/src/veditarea.h @@ -149,6 +149,9 @@ private slots: // Handle the vimStatusUpdated signal of VEditWindow. void handleWindowVimStatusUpdated(const VVim *p_vim); + // Handle the timeout signal of file timer. + void handleFileTimerTimeout(); + private: void setupUI(); QVector > findTabsByFile(const VFile *p_file); @@ -167,6 +170,9 @@ private: // Init targets for Captain mode. void registerCaptainTargets(); + // Check whether opened files have been changed outside. + void checkFileChangeOutside(); + // Captain mode functions. // Activate tab @p_idx. diff --git a/src/veditor.cpp b/src/veditor.cpp index c3a73da4..509b9289 100644 --- a/src/veditor.cpp +++ b/src/veditor.cpp @@ -27,10 +27,6 @@ VEditor::VEditor(VFile *p_file, QWidget *p_editor) VEditor::~VEditor() { - if (m_file && m_document) { - QObject::disconnect(m_document, &QTextDocument::modificationChanged, - (VFile *)m_file, &VFile::setModified); - } } void VEditor::init() @@ -65,9 +61,6 @@ void VEditor::init() m_extraSelections.resize((int)SelectionId::MaxSelection); - QObject::connect(m_document, &QTextDocument::modificationChanged, - (VFile *)m_file, &VFile::setModified); - updateFontAndPalette(); m_config.init(QFontMetrics(m_editor->font()), false); @@ -344,17 +337,12 @@ bool VEditor::wordInSearchedSelection(const QString &p_text) bool VEditor::isModified() const { - Q_ASSERT(m_file ? (m_file->isModified() == m_document->isModified()) - : true); return m_document->isModified(); } void VEditor::setModified(bool p_modified) { m_document->setModified(p_modified); - if (m_file) { - m_file->setModified(p_modified); - } } void VEditor::insertImage() diff --git a/src/vedittab.cpp b/src/vedittab.cpp index 6796830e..7f0d2f2d 100644 --- a/src/vedittab.cpp +++ b/src/vedittab.cpp @@ -2,13 +2,20 @@ #include #include +#include "utils/vutils.h" +#include "vconfigmanager.h" + +extern VConfigManager *g_config; + VEditTab::VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent) : QWidget(p_parent), m_file(p_file), m_isEditMode(false), m_outline(p_file), m_currentHeader(p_file, -1), - m_editArea(p_editArea) + m_editArea(p_editArea), + m_checkFileChange(true), + m_fileDiverged(false) { connect(qApp, &QApplication::focusChanged, this, &VEditTab::handleFocusChanged); @@ -35,7 +42,7 @@ bool VEditTab::isEditMode() const bool VEditTab::isModified() const { - return m_file->isModified(); + return false; } VFile *VEditTab::getFile() const @@ -133,3 +140,44 @@ void VEditTab::applySnippet(const VSnippet *p_snippet) void VEditTab::applySnippet() { } + +void VEditTab::checkFileChangeOutside() +{ + if (!m_checkFileChange) { + return; + } + + if (m_file->isChangedOutside()) { + int ret = VUtils::showMessage(QMessageBox::Information, + tr("Information"), + tr("Note %2 has been modified by another program.") + .arg(g_config->c_dataTextStyle).arg(m_file->fetchPath()), + tr("Do you want to reload it?"), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes, + this); + switch (ret) { + case QMessageBox::Yes: + reloadFromDisk(); + break; + + case QMessageBox::No: + m_checkFileChange = false; + m_fileDiverged = true; + updateStatus(); + break; + + default: + Q_ASSERT(false); + break; + } + } +} + +void VEditTab::reloadFromDisk() +{ + m_file->reload(); + m_fileDiverged = false; + m_checkFileChange = true; + reload(); +} diff --git a/src/vedittab.h b/src/vedittab.h index 44885eb4..8be6fcd0 100644 --- a/src/vedittab.h +++ b/src/vedittab.h @@ -34,7 +34,7 @@ public: bool isEditMode() const; - bool isModified() const; + virtual bool isModified() const; void focusTab(); @@ -98,6 +98,15 @@ public: // Prompt for user to apply a snippet. virtual void applySnippet(); + // Check whether this file has been changed outside. + void checkFileChangeOutside(); + + // Reload the editor from file. + virtual void reload() = 0; + + // Reload file from disk and reload the editor. + void reloadFromDisk(); + public slots: // Enter edit mode virtual void editFile() = 0; @@ -131,6 +140,12 @@ protected: // Tab info to restore from once ready. VEditTabInfo m_infoToRestore; + // Whether check the file change outside. + bool m_checkFileChange; + + // File has diverged from disk. + bool m_fileDiverged; + signals: void getFocused(); diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp index 7955d350..6367fea4 100644 --- a/src/veditwindow.cpp +++ b/src/veditwindow.cpp @@ -158,6 +158,17 @@ void VEditWindow::initTabActions() QDesktopServices::openUrl(url); }); + m_reloadAct = new QAction(tr("Reload From Disk"), this); + m_reloadAct->setToolTip(tr("Reload the content of this note from disk")); + connect(m_reloadAct, &QAction::triggered, + this, [this](){ + int tab = this->m_closeTabAct->data().toInt(); + Q_ASSERT(tab != -1); + + VEditTab *editor = getTab(tab); + editor->reloadFromDisk(); + }); + m_recycleBinAct = new QAction(QIcon(":/resources/icons/recycle_bin.svg"), tr("&Recycle Bin"), this); m_recycleBinAct->setToolTip(tr("Open the recycle bin of this note")); @@ -508,13 +519,16 @@ void VEditWindow::updateTabInfo(int p_index) const VFile *file = editor->getFile(); bool editMode = editor->isEditMode(); - setTabText(p_index, generateTabText(p_index, file)); + setTabText(p_index, generateTabText(p_index, editor)); setTabToolTip(p_index, generateTooltip(file)); - QString iconUrl(":/resources/icons/reading.svg"); + QString iconUrl; if (editMode) { - iconUrl = file->isModified() ? ":/resources/icons/editing_modified.svg" - : ":/resources/icons/editing.svg"; + iconUrl = editor->isModified() ? ":/resources/icons/editing_modified.svg" + : ":/resources/icons/editing.svg"; + } else { + iconUrl = editor->isModified() ? ":/resources/icons/reading_modified.svg" + : ":/resources/icons/reading.svg"; } setTabIcon(p_index, QIcon(iconUrl)); @@ -524,8 +538,7 @@ void VEditWindow::updateAllTabsSequence() { for (int i = 0; i < count(); ++i) { VEditTab *editor = getTab(i); - const VFile *file = editor->getFile(); - setTabText(i, generateTabText(i, file)); + setTabText(i, generateTabText(i, editor)); } } @@ -627,6 +640,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) m_openLocationAct->setData(tab); menu.addAction(m_openLocationAct); + m_reloadAct->setData(tab); + menu.addAction(m_reloadAct); + m_noteInfoAct->setData(tab); menu.addAction(m_noteInfoAct); } else if (file->getType() == FileType::Orphan @@ -637,6 +653,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) m_openLocationAct->setData(tab); menu.addAction(m_openLocationAct); + m_reloadAct->setData(tab); + menu.addAction(m_reloadAct); + m_noteInfoAct->setData(tab); menu.addAction(m_noteInfoAct); } @@ -1054,3 +1073,24 @@ void VEditWindow::dropEvent(QDropEvent *p_event) QTabWidget::dropEvent(p_event); } + +QVector VEditWindow::getAllTabs() const +{ + int nrTab = count(); + + QVector tabs; + tabs.reserve(nrTab); + for (int i = 0; i < nrTab; ++i) { + tabs.push_back(getTab(i)); + } + + return tabs; +} + +void VEditWindow::checkFileChangeOutside() +{ + int nrTab = count(); + for (int i = 0; i < nrTab; ++i) { + getTab(i)->checkFileChangeOutside(); + } +} diff --git a/src/veditwindow.h b/src/veditwindow.h index 39c95eda..5e3bfb15 100644 --- a/src/veditwindow.h +++ b/src/veditwindow.h @@ -53,6 +53,8 @@ public: QVector getAllTabsInfo() const; + QVector getAllTabs() const; + // Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab. bool addEditTab(QWidget *p_widget); // Set whether it is the current window. @@ -71,6 +73,9 @@ public: // If @p_index is -1, it is current tab. void updateTabStatus(int p_index = -1); + // Check whether opened files have been changed outside. + void checkFileChangeOutside(); + protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; @@ -143,7 +148,7 @@ private: QString generateTooltip(const VFile *p_file) const; - QString generateTabText(int p_index, const VFile *p_file) const; + QString generateTabText(int p_index, const VEditTab *p_tab) const; bool canRemoveSplit(); @@ -196,6 +201,9 @@ private: // Open the location (the folder containing this file) of this note. QAction *m_openLocationAct; + // Reload the note from disk. + QAction *m_reloadAct; + // Open the recycle bin folder of this note. QAction *m_recycleBinAct; }; @@ -215,16 +223,17 @@ inline QString VEditWindow::generateTooltip(const VFile *p_file) const } } -inline QString VEditWindow::generateTabText(int p_index, const VFile *p_file) const +inline QString VEditWindow::generateTabText(int p_index, const VEditTab *p_tab) const { - if (!p_file) { + const VFile *file = p_tab->getFile(); + if (!file) { return ""; } return QString("%1.%2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10)) - .arg(p_file->getName()) - .arg(p_file->isModifiable() ? "" : "#") - .arg(p_file->isModified() ? "*" : ""); + .arg(file->getName()) + .arg(file->isModifiable() ? "" : "#") + .arg(p_tab->isModified() ? "*" : ""); } #endif // VEDITWINDOW_H diff --git a/src/vfile.cpp b/src/vfile.cpp index 198470c5..10cfa379 100644 --- a/src/vfile.cpp +++ b/src/vfile.cpp @@ -1,7 +1,6 @@ #include "vfile.h" #include -#include #include #include #include "utils/vutils.h" @@ -15,7 +14,6 @@ VFile::VFile(QObject *p_parent, : QObject(p_parent), m_name(p_name), m_opened(false), - m_modified(false), m_docType(VUtils::docTypeFromName(p_name)), m_type(p_type), m_modifiable(p_modifiable), @@ -40,7 +38,7 @@ bool VFile::open() QString filePath = fetchPath(); Q_ASSERT(QFileInfo::exists(filePath)); m_content = VUtils::readFileFromDisk(filePath); - m_modified = false; + m_lastModified = QFileInfo(filePath).lastModified(); m_opened = true; return true; } @@ -52,7 +50,6 @@ void VFile::close() } m_content.clear(); - m_modified = false; m_opened = false; } @@ -62,8 +59,8 @@ bool VFile::save() Q_ASSERT(m_modifiable); bool ret = VUtils::writeFileToDisk(fetchPath(), m_content); if (ret) { + m_lastModified = QFileInfo(fetchPath()).lastModified(); m_modifiedTimeUtc = QDateTime::currentDateTimeUtc(); - m_modified = false; } return ret; @@ -98,8 +95,18 @@ bool VFile::isInternalImageFolder(const QString &p_path) const || VUtils::equalPath(p_path, fetchImageFolderPath()); } -void VFile::setModified(bool p_modified) +bool VFile::isChangedOutside() const { - m_modified = p_modified; + QDateTime lm = QFileInfo(fetchPath()).lastModified(); + return lm != m_lastModified; } +void VFile::reload() +{ + Q_ASSERT(m_opened); + + QString filePath = fetchPath(); + Q_ASSERT(QFileInfo::exists(filePath)); + m_content = VUtils::readFileFromDisk(filePath); + m_lastModified = QFileInfo(filePath).lastModified(); +} diff --git a/src/vfile.h b/src/vfile.h index 6c3ca101..5f4e5694 100644 --- a/src/vfile.h +++ b/src/vfile.h @@ -22,22 +22,23 @@ public: virtual ~VFile(); // Open the file to load content into m_content. - // Init m_opened, m_modified, and m_content. + // Init m_opened, and m_content. virtual bool open(); // Close the file. - // Clear m_modified, m_content, m_opened. + // Clear m_content, m_opened. virtual void close(); // Save m_content to the file. virtual bool save(); + // Reload content from disk. + virtual void reload(); + const QString &getName() const; DocType getDocType() const; - bool isModified() const; - bool isModifiable() const; bool isOpened() const; @@ -75,8 +76,8 @@ public: QDateTime getModifiedTimeUtc() const; -public slots: - void setModified(bool p_modified); + // Whether this file was changed outside VNote. + bool isChangedOutside() const; protected: // Name of this file. @@ -85,9 +86,6 @@ protected: // Whether this file has been opened (content loaded). bool m_opened; - // m_content is different from that in the disk. - bool m_modified; - // DocType of this file: Html, Markdown. DocType m_docType; @@ -105,6 +103,10 @@ protected: // UTC time of last modification to this file in VNote. QDateTime m_modifiedTimeUtc; + + // Last modified date and local time when the file is last modified + // corresponding to m_content. + QDateTime m_lastModified; }; inline const QString &VFile::getName() const @@ -117,11 +119,6 @@ inline DocType VFile::getDocType() const return m_docType; } -inline bool VFile::isModified() const -{ - return m_modified; -} - inline bool VFile::isModifiable() const { return m_modifiable; @@ -146,7 +143,6 @@ inline const QString &VFile::getContent() const inline void VFile::setContent(const QString &p_content) { m_content = p_content; - m_modified = true; } inline QDateTime VFile::getCreatedTimeUtc() const diff --git a/src/vhtmltab.cpp b/src/vhtmltab.cpp index c751b2ef..0d0aad61 100644 --- a/src/vhtmltab.cpp +++ b/src/vhtmltab.cpp @@ -101,7 +101,7 @@ void VHtmlTab::readFile() return; } - if (m_editor && m_editor->isModified()) { + if (m_editor && isModified()) { // Prompt to save the changes. bool modifiable = m_file->isModifiable(); int ret = VUtils::showMessage(QMessageBox::Information, @@ -123,7 +123,7 @@ void VHtmlTab::readFile() return; } - // Fall through + V_FALLTHROUGH; case QMessageBox::Discard: m_editor->reloadFile(); @@ -148,7 +148,7 @@ void VHtmlTab::readFile() bool VHtmlTab::saveFile() { - if (!m_isEditMode || !m_editor->isModified()) { + if (!m_isEditMode || !isModified()) { return true; } @@ -184,6 +184,9 @@ bool VHtmlTab::saveFile() tr("Fail to write to disk when saving a note. Please try it again."), QMessageBox::Ok, QMessageBox::Ok, this); m_editor->setModified(true); + } else { + m_fileDiverged = false; + m_checkFileChange = true; } updateStatus(); @@ -191,6 +194,11 @@ bool VHtmlTab::saveFile() return ret; } +bool VHtmlTab::isModified() const +{ + return m_editor->isModified() || m_fileDiverged; +} + void VHtmlTab::saveAndRead() { saveFile(); @@ -265,3 +273,9 @@ bool VHtmlTab::restoreFromTabInfo(const VEditTabInfo &p_info) return true; } + +void VHtmlTab::reload() +{ + m_editor->reloadFile(); + updateStatus(); +} diff --git a/src/vhtmltab.h b/src/vhtmltab.h index 80471fa5..e28fe673 100644 --- a/src/vhtmltab.h +++ b/src/vhtmltab.h @@ -26,6 +26,8 @@ public: // Save file. bool saveFile() Q_DECL_OVERRIDE; + bool isModified() const Q_DECL_OVERRIDE; + void insertImage() Q_DECL_OVERRIDE; // Search @p_text in current note. @@ -45,6 +47,8 @@ public: void requestUpdateVimStatus() Q_DECL_OVERRIDE; + void reload() Q_DECL_OVERRIDE; + public slots: // Enter edit mode. void editFile() Q_DECL_OVERRIDE; diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 9878c036..e246b76f 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -1864,7 +1864,7 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info) title.append('#'); } - if (m_curFile->isModified()) { + if (m_curTab->isModified()) { title.append('*'); } } diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp index 611a0e14..8f83fcc9 100644 --- a/src/vmdtab.cpp +++ b/src/vmdtab.cpp @@ -241,7 +241,7 @@ void VMdTab::readFile() return; } - if (m_editor && m_editor->isModified()) { + if (m_editor && isModified()) { // Prompt to save the changes. bool modifiable = m_file->isModifiable(); int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), @@ -262,7 +262,7 @@ void VMdTab::readFile() return; } - // Fall through + V_FALLTHROUGH; case QMessageBox::Discard: m_editor->reloadFile(); @@ -293,7 +293,7 @@ bool VMdTab::saveFile() Q_ASSERT(m_editor); - if (!m_editor->isModified()) { + if (!isModified()) { return true; } @@ -329,6 +329,9 @@ bool VMdTab::saveFile() tr("Fail to write to disk when saving a note. Please try it again."), QMessageBox::Ok, QMessageBox::Ok, this); m_editor->setModified(true); + } else { + m_fileDiverged = false; + m_checkFileChange = true; } } @@ -337,6 +340,11 @@ bool VMdTab::saveFile() return ret; } +bool VMdTab::isModified() const +{ + return (m_editor ? m_editor->isModified() : false) || m_fileDiverged; +} + void VMdTab::saveAndRead() { saveFile(); @@ -818,3 +826,19 @@ VInsertSelector *VMdTab::prepareSnippetSelector(QWidget *p_parent) VInsertSelector *sel = new VInsertSelector(7, items, p_parent); return sel; } + +void VMdTab::reload() +{ + if (m_isEditMode) { + m_editor->reloadFile(); + m_editor->endEdit(); + m_editor->beginEdit(); + updateStatus(); + } else { + if (m_editor) { + m_editor->reloadFile(); + } + + showFileReadMode(); + } +} diff --git a/src/vmdtab.h b/src/vmdtab.h index c4372292..6f10bee3 100644 --- a/src/vmdtab.h +++ b/src/vmdtab.h @@ -32,6 +32,8 @@ public: // Save file. bool saveFile() Q_DECL_OVERRIDE; + bool isModified() const Q_DECL_OVERRIDE; + // Scroll to @p_header. void scrollToHeader(const VHeaderPointer &p_header) Q_DECL_OVERRIDE; @@ -80,6 +82,8 @@ public: void applySnippet() Q_DECL_OVERRIDE; + void reload() Q_DECL_OVERRIDE; + public slots: // Enter edit mode. void editFile() Q_DECL_OVERRIDE; diff --git a/src/vnote.qrc b/src/vnote.qrc index c582a282..d6f7d938 100644 --- a/src/vnote.qrc +++ b/src/vnote.qrc @@ -141,5 +141,6 @@ resources/icons/delete_snippet.svg resources/icons/snippet_info.svg resources/icons/apply_snippet.svg + resources/icons/reading_modified.svg