mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support file change check
This commit is contained in:
parent
0a97b2480d
commit
141b404240
14
src/resources/icons/reading_modified.svg
Normal file
14
src/resources/icons/reading_modified.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<g>
|
||||
<path style="fill:#C9302C" d="M112,64v16v320h16V80h304v337.143c0,8.205-6.652,14.857-14.857,14.857H94.857C86.652,432,80,425.348,80,417.143V128h16v-16
|
||||
H64v305.143C64,434.157,77.843,448,94.857,448h322.285C434.157,448,448,434.157,448,417.143V64H112z"/>
|
||||
<rect style="fill:#C9302C" x="160" y="112" width="128" height="16"/>
|
||||
<rect style="fill:#C9302C" x="160" y="192" width="240" height="16"/>
|
||||
<rect style="fill:#C9302C" x="160" y="272" width="192" height="16"/>
|
||||
<rect style="fill:#C9302C" x="160" y="352" width="240" height="16"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1018 B |
@ -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
|
||||
|
@ -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()
|
||||
|
@ -372,6 +372,9 @@ public:
|
||||
// Read all available mdhl files in c_styleConfigFolder.
|
||||
QVector<QString> 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
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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<QPair<int, int> > 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.
|
||||
|
@ -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()
|
||||
|
@ -2,13 +2,20 @@
|
||||
#include <QApplication>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#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 <span style=\"%1\">%2</span> 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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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"
|
||||
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<VEditTab *> VEditWindow::getAllTabs() const
|
||||
{
|
||||
int nrTab = count();
|
||||
|
||||
QVector<VEditTab *> 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();
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ public:
|
||||
|
||||
QVector<VEditTabInfo> getAllTabsInfo() const;
|
||||
|
||||
QVector<VEditTab *> 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
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "vfile.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QTextEdit>
|
||||
#include <QFileInfo>
|
||||
#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();
|
||||
}
|
||||
|
26
src/vfile.h
26
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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1864,7 +1864,7 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info)
|
||||
title.append('#');
|
||||
}
|
||||
|
||||
if (m_curFile->isModified()) {
|
||||
if (m_curTab->isModified()) {
|
||||
title.append('*');
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -141,5 +141,6 @@
|
||||
<file>resources/icons/delete_snippet.svg</file>
|
||||
<file>resources/icons/snippet_info.svg</file>
|
||||
<file>resources/icons/apply_snippet.svg</file>
|
||||
<file>resources/icons/reading_modified.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user