mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09: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
|
; C:\users\vnote\vnote.md -> C:\\users\\vnote\\vnote.md
|
||||||
startup_pages=
|
startup_pages=
|
||||||
|
|
||||||
|
; Timer interval to check file modification or save file to tmp file in milliseconds
|
||||||
|
file_timer_interval=2000
|
||||||
|
|
||||||
[web]
|
[web]
|
||||||
; Location and configuration for Mathjax
|
; Location and configuration for Mathjax
|
||||||
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML
|
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();
|
"startup_pages").toStringList();
|
||||||
|
|
||||||
initFromSessionSettings();
|
initFromSessionSettings();
|
||||||
|
|
||||||
|
m_fileTimerInterval = getConfigFromSettings("global",
|
||||||
|
"file_timer_interval").toInt();
|
||||||
|
if (m_fileTimerInterval < 100) {
|
||||||
|
m_fileTimerInterval = 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VConfigManager::initSettings()
|
void VConfigManager::initSettings()
|
||||||
|
@ -372,6 +372,9 @@ public:
|
|||||||
// Read all available mdhl files in c_styleConfigFolder.
|
// Read all available mdhl files in c_styleConfigFolder.
|
||||||
QVector<QString> getEditorStyles() const;
|
QVector<QString> getEditorStyles() const;
|
||||||
|
|
||||||
|
// Return the timer interval for checking file.
|
||||||
|
int getFileTimerInterval() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Look up a config from user and default settings.
|
// Look up a config from user and default settings.
|
||||||
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
|
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
|
||||||
@ -703,6 +706,9 @@ private:
|
|||||||
// File paths to open on startup.
|
// File paths to open on startup.
|
||||||
QStringList m_startupPages;
|
QStringList m_startupPages;
|
||||||
|
|
||||||
|
// Timer interval to check file in milliseconds.
|
||||||
|
int m_fileTimerInterval;
|
||||||
|
|
||||||
// The name of the config file in each directory, obsolete.
|
// The name of the config file in each directory, obsolete.
|
||||||
// Use c_dirConfigFile instead.
|
// Use c_dirConfigFile instead.
|
||||||
static const QString c_obsoleteDirConfigFile;
|
static const QString c_obsoleteDirConfigFile;
|
||||||
@ -1779,4 +1785,9 @@ inline void VConfigManager::setStartupPages(const QStringList &p_pages)
|
|||||||
setConfigToSettings("global", "startup_pages", m_startupPages);
|
setConfigToSettings("global", "startup_pages", m_startupPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int VConfigManager::getFileTimerInterval() const
|
||||||
|
{
|
||||||
|
return m_fileTimerInterval;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
@ -48,9 +48,6 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
|||||||
connect(m_highlightTimer, &QTimer::timeout,
|
connect(m_highlightTimer, &QTimer::timeout,
|
||||||
this, &VEdit::doHighlightExtraSelections);
|
this, &VEdit::doHighlightExtraSelections);
|
||||||
|
|
||||||
connect(document(), &QTextDocument::modificationChanged,
|
|
||||||
(VFile *)m_file, &VFile::setModified);
|
|
||||||
|
|
||||||
m_extraSelections.resize((int)SelectionId::MaxSelection);
|
m_extraSelections.resize((int)SelectionId::MaxSelection);
|
||||||
|
|
||||||
updateFontAndPalette();
|
updateFontAndPalette();
|
||||||
@ -80,10 +77,6 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
|||||||
|
|
||||||
VEdit::~VEdit()
|
VEdit::~VEdit()
|
||||||
{
|
{
|
||||||
if (m_file) {
|
|
||||||
disconnect(document(), &QTextDocument::modificationChanged,
|
|
||||||
(VFile *)m_file, &VFile::setModified);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEdit::updateConfig()
|
void VEdit::updateConfig()
|
||||||
@ -146,16 +139,12 @@ bool VEdit::scrollToBlock(int p_blockNumber)
|
|||||||
|
|
||||||
bool VEdit::isModified() const
|
bool VEdit::isModified() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_file ? (m_file->isModified() == document()->isModified()) : true);
|
|
||||||
return document()->isModified();
|
return document()->isModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEdit::setModified(bool p_modified)
|
void VEdit::setModified(bool p_modified)
|
||||||
{
|
{
|
||||||
document()->setModified(p_modified);
|
document()->setModified(p_modified);
|
||||||
if (m_file) {
|
|
||||||
m_file->setModified(p_modified);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEdit::insertImage()
|
void VEdit::insertImage()
|
||||||
|
@ -53,6 +53,14 @@ VEditArea::VEditArea(QWidget *parent)
|
|||||||
win->focusNextTab(false);
|
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()
|
void VEditArea::setupUI()
|
||||||
@ -1016,3 +1024,16 @@ void VEditArea::recordClosedFile(const VFileSessionInfo &p_file)
|
|||||||
m_lastClosedFiles.push(p_file);
|
m_lastClosedFiles.push(p_file);
|
||||||
qDebug() << "pushed closed file" << p_file.m_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.
|
// Handle the vimStatusUpdated signal of VEditWindow.
|
||||||
void handleWindowVimStatusUpdated(const VVim *p_vim);
|
void handleWindowVimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
|
// Handle the timeout signal of file timer.
|
||||||
|
void handleFileTimerTimeout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
QVector<QPair<int, int> > findTabsByFile(const VFile *p_file);
|
QVector<QPair<int, int> > findTabsByFile(const VFile *p_file);
|
||||||
@ -167,6 +170,9 @@ private:
|
|||||||
// Init targets for Captain mode.
|
// Init targets for Captain mode.
|
||||||
void registerCaptainTargets();
|
void registerCaptainTargets();
|
||||||
|
|
||||||
|
// Check whether opened files have been changed outside.
|
||||||
|
void checkFileChangeOutside();
|
||||||
|
|
||||||
// Captain mode functions.
|
// Captain mode functions.
|
||||||
|
|
||||||
// Activate tab @p_idx.
|
// Activate tab @p_idx.
|
||||||
|
@ -27,10 +27,6 @@ VEditor::VEditor(VFile *p_file, QWidget *p_editor)
|
|||||||
|
|
||||||
VEditor::~VEditor()
|
VEditor::~VEditor()
|
||||||
{
|
{
|
||||||
if (m_file && m_document) {
|
|
||||||
QObject::disconnect(m_document, &QTextDocument::modificationChanged,
|
|
||||||
(VFile *)m_file, &VFile::setModified);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditor::init()
|
void VEditor::init()
|
||||||
@ -65,9 +61,6 @@ void VEditor::init()
|
|||||||
|
|
||||||
m_extraSelections.resize((int)SelectionId::MaxSelection);
|
m_extraSelections.resize((int)SelectionId::MaxSelection);
|
||||||
|
|
||||||
QObject::connect(m_document, &QTextDocument::modificationChanged,
|
|
||||||
(VFile *)m_file, &VFile::setModified);
|
|
||||||
|
|
||||||
updateFontAndPalette();
|
updateFontAndPalette();
|
||||||
|
|
||||||
m_config.init(QFontMetrics(m_editor->font()), false);
|
m_config.init(QFontMetrics(m_editor->font()), false);
|
||||||
@ -344,17 +337,12 @@ bool VEditor::wordInSearchedSelection(const QString &p_text)
|
|||||||
|
|
||||||
bool VEditor::isModified() const
|
bool VEditor::isModified() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_file ? (m_file->isModified() == m_document->isModified())
|
|
||||||
: true);
|
|
||||||
return m_document->isModified();
|
return m_document->isModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditor::setModified(bool p_modified)
|
void VEditor::setModified(bool p_modified)
|
||||||
{
|
{
|
||||||
m_document->setModified(p_modified);
|
m_document->setModified(p_modified);
|
||||||
if (m_file) {
|
|
||||||
m_file->setModified(p_modified);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditor::insertImage()
|
void VEditor::insertImage()
|
||||||
|
@ -2,13 +2,20 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
|
||||||
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
VEditTab::VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent)
|
VEditTab::VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent)
|
||||||
: QWidget(p_parent),
|
: QWidget(p_parent),
|
||||||
m_file(p_file),
|
m_file(p_file),
|
||||||
m_isEditMode(false),
|
m_isEditMode(false),
|
||||||
m_outline(p_file),
|
m_outline(p_file),
|
||||||
m_currentHeader(p_file, -1),
|
m_currentHeader(p_file, -1),
|
||||||
m_editArea(p_editArea)
|
m_editArea(p_editArea),
|
||||||
|
m_checkFileChange(true),
|
||||||
|
m_fileDiverged(false)
|
||||||
{
|
{
|
||||||
connect(qApp, &QApplication::focusChanged,
|
connect(qApp, &QApplication::focusChanged,
|
||||||
this, &VEditTab::handleFocusChanged);
|
this, &VEditTab::handleFocusChanged);
|
||||||
@ -35,7 +42,7 @@ bool VEditTab::isEditMode() const
|
|||||||
|
|
||||||
bool VEditTab::isModified() const
|
bool VEditTab::isModified() const
|
||||||
{
|
{
|
||||||
return m_file->isModified();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VFile *VEditTab::getFile() const
|
VFile *VEditTab::getFile() const
|
||||||
@ -133,3 +140,44 @@ void VEditTab::applySnippet(const VSnippet *p_snippet)
|
|||||||
void VEditTab::applySnippet()
|
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 isEditMode() const;
|
||||||
|
|
||||||
bool isModified() const;
|
virtual bool isModified() const;
|
||||||
|
|
||||||
void focusTab();
|
void focusTab();
|
||||||
|
|
||||||
@ -98,6 +98,15 @@ public:
|
|||||||
// Prompt for user to apply a snippet.
|
// Prompt for user to apply a snippet.
|
||||||
virtual void applySnippet();
|
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:
|
public slots:
|
||||||
// Enter edit mode
|
// Enter edit mode
|
||||||
virtual void editFile() = 0;
|
virtual void editFile() = 0;
|
||||||
@ -131,6 +140,12 @@ protected:
|
|||||||
// Tab info to restore from once ready.
|
// Tab info to restore from once ready.
|
||||||
VEditTabInfo m_infoToRestore;
|
VEditTabInfo m_infoToRestore;
|
||||||
|
|
||||||
|
// Whether check the file change outside.
|
||||||
|
bool m_checkFileChange;
|
||||||
|
|
||||||
|
// File has diverged from disk.
|
||||||
|
bool m_fileDiverged;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void getFocused();
|
void getFocused();
|
||||||
|
|
||||||
|
@ -158,6 +158,17 @@ void VEditWindow::initTabActions()
|
|||||||
QDesktopServices::openUrl(url);
|
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"),
|
m_recycleBinAct = new QAction(QIcon(":/resources/icons/recycle_bin.svg"),
|
||||||
tr("&Recycle Bin"), this);
|
tr("&Recycle Bin"), this);
|
||||||
m_recycleBinAct->setToolTip(tr("Open the recycle bin of this note"));
|
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();
|
const VFile *file = editor->getFile();
|
||||||
bool editMode = editor->isEditMode();
|
bool editMode = editor->isEditMode();
|
||||||
|
|
||||||
setTabText(p_index, generateTabText(p_index, file));
|
setTabText(p_index, generateTabText(p_index, editor));
|
||||||
setTabToolTip(p_index, generateTooltip(file));
|
setTabToolTip(p_index, generateTooltip(file));
|
||||||
|
|
||||||
QString iconUrl(":/resources/icons/reading.svg");
|
QString iconUrl;
|
||||||
if (editMode) {
|
if (editMode) {
|
||||||
iconUrl = file->isModified() ? ":/resources/icons/editing_modified.svg"
|
iconUrl = editor->isModified() ? ":/resources/icons/editing_modified.svg"
|
||||||
: ":/resources/icons/editing.svg";
|
: ":/resources/icons/editing.svg";
|
||||||
|
} else {
|
||||||
|
iconUrl = editor->isModified() ? ":/resources/icons/reading_modified.svg"
|
||||||
|
: ":/resources/icons/reading.svg";
|
||||||
}
|
}
|
||||||
|
|
||||||
setTabIcon(p_index, QIcon(iconUrl));
|
setTabIcon(p_index, QIcon(iconUrl));
|
||||||
@ -524,8 +538,7 @@ void VEditWindow::updateAllTabsSequence()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < count(); ++i) {
|
for (int i = 0; i < count(); ++i) {
|
||||||
VEditTab *editor = getTab(i);
|
VEditTab *editor = getTab(i);
|
||||||
const VFile *file = editor->getFile();
|
setTabText(i, generateTabText(i, editor));
|
||||||
setTabText(i, generateTabText(i, file));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,6 +640,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
|||||||
m_openLocationAct->setData(tab);
|
m_openLocationAct->setData(tab);
|
||||||
menu.addAction(m_openLocationAct);
|
menu.addAction(m_openLocationAct);
|
||||||
|
|
||||||
|
m_reloadAct->setData(tab);
|
||||||
|
menu.addAction(m_reloadAct);
|
||||||
|
|
||||||
m_noteInfoAct->setData(tab);
|
m_noteInfoAct->setData(tab);
|
||||||
menu.addAction(m_noteInfoAct);
|
menu.addAction(m_noteInfoAct);
|
||||||
} else if (file->getType() == FileType::Orphan
|
} else if (file->getType() == FileType::Orphan
|
||||||
@ -637,6 +653,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
|||||||
m_openLocationAct->setData(tab);
|
m_openLocationAct->setData(tab);
|
||||||
menu.addAction(m_openLocationAct);
|
menu.addAction(m_openLocationAct);
|
||||||
|
|
||||||
|
m_reloadAct->setData(tab);
|
||||||
|
menu.addAction(m_reloadAct);
|
||||||
|
|
||||||
m_noteInfoAct->setData(tab);
|
m_noteInfoAct->setData(tab);
|
||||||
menu.addAction(m_noteInfoAct);
|
menu.addAction(m_noteInfoAct);
|
||||||
}
|
}
|
||||||
@ -1054,3 +1073,24 @@ void VEditWindow::dropEvent(QDropEvent *p_event)
|
|||||||
|
|
||||||
QTabWidget::dropEvent(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<VEditTabInfo> getAllTabsInfo() const;
|
||||||
|
|
||||||
|
QVector<VEditTab *> getAllTabs() const;
|
||||||
|
|
||||||
// Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab.
|
// Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab.
|
||||||
bool addEditTab(QWidget *p_widget);
|
bool addEditTab(QWidget *p_widget);
|
||||||
// Set whether it is the current window.
|
// Set whether it is the current window.
|
||||||
@ -71,6 +73,9 @@ public:
|
|||||||
// If @p_index is -1, it is current tab.
|
// If @p_index is -1, it is current tab.
|
||||||
void updateTabStatus(int p_index = -1);
|
void updateTabStatus(int p_index = -1);
|
||||||
|
|
||||||
|
// Check whether opened files have been changed outside.
|
||||||
|
void checkFileChangeOutside();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -143,7 +148,7 @@ private:
|
|||||||
|
|
||||||
QString generateTooltip(const VFile *p_file) const;
|
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();
|
bool canRemoveSplit();
|
||||||
|
|
||||||
@ -196,6 +201,9 @@ private:
|
|||||||
// Open the location (the folder containing this file) of this note.
|
// Open the location (the folder containing this file) of this note.
|
||||||
QAction *m_openLocationAct;
|
QAction *m_openLocationAct;
|
||||||
|
|
||||||
|
// Reload the note from disk.
|
||||||
|
QAction *m_reloadAct;
|
||||||
|
|
||||||
// Open the recycle bin folder of this note.
|
// Open the recycle bin folder of this note.
|
||||||
QAction *m_recycleBinAct;
|
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 "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return QString("%1.%2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10))
|
return QString("%1.%2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10))
|
||||||
.arg(p_file->getName())
|
.arg(file->getName())
|
||||||
.arg(p_file->isModifiable() ? "" : "#")
|
.arg(file->isModifiable() ? "" : "#")
|
||||||
.arg(p_file->isModified() ? "*" : "");
|
.arg(p_tab->isModified() ? "*" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // VEDITWINDOW_H
|
#endif // VEDITWINDOW_H
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDebug>
|
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
@ -15,7 +14,6 @@ VFile::VFile(QObject *p_parent,
|
|||||||
: QObject(p_parent),
|
: QObject(p_parent),
|
||||||
m_name(p_name),
|
m_name(p_name),
|
||||||
m_opened(false),
|
m_opened(false),
|
||||||
m_modified(false),
|
|
||||||
m_docType(VUtils::docTypeFromName(p_name)),
|
m_docType(VUtils::docTypeFromName(p_name)),
|
||||||
m_type(p_type),
|
m_type(p_type),
|
||||||
m_modifiable(p_modifiable),
|
m_modifiable(p_modifiable),
|
||||||
@ -40,7 +38,7 @@ bool VFile::open()
|
|||||||
QString filePath = fetchPath();
|
QString filePath = fetchPath();
|
||||||
Q_ASSERT(QFileInfo::exists(filePath));
|
Q_ASSERT(QFileInfo::exists(filePath));
|
||||||
m_content = VUtils::readFileFromDisk(filePath);
|
m_content = VUtils::readFileFromDisk(filePath);
|
||||||
m_modified = false;
|
m_lastModified = QFileInfo(filePath).lastModified();
|
||||||
m_opened = true;
|
m_opened = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -52,7 +50,6 @@ void VFile::close()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_content.clear();
|
m_content.clear();
|
||||||
m_modified = false;
|
|
||||||
m_opened = false;
|
m_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +59,8 @@ bool VFile::save()
|
|||||||
Q_ASSERT(m_modifiable);
|
Q_ASSERT(m_modifiable);
|
||||||
bool ret = VUtils::writeFileToDisk(fetchPath(), m_content);
|
bool ret = VUtils::writeFileToDisk(fetchPath(), m_content);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
m_lastModified = QFileInfo(fetchPath()).lastModified();
|
||||||
m_modifiedTimeUtc = QDateTime::currentDateTimeUtc();
|
m_modifiedTimeUtc = QDateTime::currentDateTimeUtc();
|
||||||
m_modified = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -98,8 +95,18 @@ bool VFile::isInternalImageFolder(const QString &p_path) const
|
|||||||
|| VUtils::equalPath(p_path, fetchImageFolderPath());
|
|| 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();
|
virtual ~VFile();
|
||||||
|
|
||||||
// Open the file to load content into m_content.
|
// 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();
|
virtual bool open();
|
||||||
|
|
||||||
// Close the file.
|
// Close the file.
|
||||||
// Clear m_modified, m_content, m_opened.
|
// Clear m_content, m_opened.
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
|
||||||
// Save m_content to the file.
|
// Save m_content to the file.
|
||||||
virtual bool save();
|
virtual bool save();
|
||||||
|
|
||||||
|
// Reload content from disk.
|
||||||
|
virtual void reload();
|
||||||
|
|
||||||
const QString &getName() const;
|
const QString &getName() const;
|
||||||
|
|
||||||
DocType getDocType() const;
|
DocType getDocType() const;
|
||||||
|
|
||||||
bool isModified() const;
|
|
||||||
|
|
||||||
bool isModifiable() const;
|
bool isModifiable() const;
|
||||||
|
|
||||||
bool isOpened() const;
|
bool isOpened() const;
|
||||||
@ -75,8 +76,8 @@ public:
|
|||||||
|
|
||||||
QDateTime getModifiedTimeUtc() const;
|
QDateTime getModifiedTimeUtc() const;
|
||||||
|
|
||||||
public slots:
|
// Whether this file was changed outside VNote.
|
||||||
void setModified(bool p_modified);
|
bool isChangedOutside() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Name of this file.
|
// Name of this file.
|
||||||
@ -85,9 +86,6 @@ protected:
|
|||||||
// Whether this file has been opened (content loaded).
|
// Whether this file has been opened (content loaded).
|
||||||
bool m_opened;
|
bool m_opened;
|
||||||
|
|
||||||
// m_content is different from that in the disk.
|
|
||||||
bool m_modified;
|
|
||||||
|
|
||||||
// DocType of this file: Html, Markdown.
|
// DocType of this file: Html, Markdown.
|
||||||
DocType m_docType;
|
DocType m_docType;
|
||||||
|
|
||||||
@ -105,6 +103,10 @@ protected:
|
|||||||
|
|
||||||
// UTC time of last modification to this file in VNote.
|
// UTC time of last modification to this file in VNote.
|
||||||
QDateTime m_modifiedTimeUtc;
|
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
|
inline const QString &VFile::getName() const
|
||||||
@ -117,11 +119,6 @@ inline DocType VFile::getDocType() const
|
|||||||
return m_docType;
|
return m_docType;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool VFile::isModified() const
|
|
||||||
{
|
|
||||||
return m_modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool VFile::isModifiable() const
|
inline bool VFile::isModifiable() const
|
||||||
{
|
{
|
||||||
return m_modifiable;
|
return m_modifiable;
|
||||||
@ -146,7 +143,6 @@ inline const QString &VFile::getContent() const
|
|||||||
inline void VFile::setContent(const QString &p_content)
|
inline void VFile::setContent(const QString &p_content)
|
||||||
{
|
{
|
||||||
m_content = p_content;
|
m_content = p_content;
|
||||||
m_modified = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QDateTime VFile::getCreatedTimeUtc() const
|
inline QDateTime VFile::getCreatedTimeUtc() const
|
||||||
|
@ -101,7 +101,7 @@ void VHtmlTab::readFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_editor && m_editor->isModified()) {
|
if (m_editor && isModified()) {
|
||||||
// Prompt to save the changes.
|
// Prompt to save the changes.
|
||||||
bool modifiable = m_file->isModifiable();
|
bool modifiable = m_file->isModifiable();
|
||||||
int ret = VUtils::showMessage(QMessageBox::Information,
|
int ret = VUtils::showMessage(QMessageBox::Information,
|
||||||
@ -123,7 +123,7 @@ void VHtmlTab::readFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall through
|
V_FALLTHROUGH;
|
||||||
|
|
||||||
case QMessageBox::Discard:
|
case QMessageBox::Discard:
|
||||||
m_editor->reloadFile();
|
m_editor->reloadFile();
|
||||||
@ -148,7 +148,7 @@ void VHtmlTab::readFile()
|
|||||||
|
|
||||||
bool VHtmlTab::saveFile()
|
bool VHtmlTab::saveFile()
|
||||||
{
|
{
|
||||||
if (!m_isEditMode || !m_editor->isModified()) {
|
if (!m_isEditMode || !isModified()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +184,9 @@ bool VHtmlTab::saveFile()
|
|||||||
tr("Fail to write to disk when saving a note. Please try it again."),
|
tr("Fail to write to disk when saving a note. Please try it again."),
|
||||||
QMessageBox::Ok, QMessageBox::Ok, this);
|
QMessageBox::Ok, QMessageBox::Ok, this);
|
||||||
m_editor->setModified(true);
|
m_editor->setModified(true);
|
||||||
|
} else {
|
||||||
|
m_fileDiverged = false;
|
||||||
|
m_checkFileChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus();
|
updateStatus();
|
||||||
@ -191,6 +194,11 @@ bool VHtmlTab::saveFile()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VHtmlTab::isModified() const
|
||||||
|
{
|
||||||
|
return m_editor->isModified() || m_fileDiverged;
|
||||||
|
}
|
||||||
|
|
||||||
void VHtmlTab::saveAndRead()
|
void VHtmlTab::saveAndRead()
|
||||||
{
|
{
|
||||||
saveFile();
|
saveFile();
|
||||||
@ -265,3 +273,9 @@ bool VHtmlTab::restoreFromTabInfo(const VEditTabInfo &p_info)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VHtmlTab::reload()
|
||||||
|
{
|
||||||
|
m_editor->reloadFile();
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
// Save file.
|
// Save file.
|
||||||
bool saveFile() Q_DECL_OVERRIDE;
|
bool saveFile() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
bool isModified() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
void insertImage() Q_DECL_OVERRIDE;
|
void insertImage() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
// Search @p_text in current note.
|
// Search @p_text in current note.
|
||||||
@ -45,6 +47,8 @@ public:
|
|||||||
|
|
||||||
void requestUpdateVimStatus() Q_DECL_OVERRIDE;
|
void requestUpdateVimStatus() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void reload() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
|
@ -1864,7 +1864,7 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info)
|
|||||||
title.append('#');
|
title.append('#');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_curFile->isModified()) {
|
if (m_curTab->isModified()) {
|
||||||
title.append('*');
|
title.append('*');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ void VMdTab::readFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_editor && m_editor->isModified()) {
|
if (m_editor && isModified()) {
|
||||||
// Prompt to save the changes.
|
// Prompt to save the changes.
|
||||||
bool modifiable = m_file->isModifiable();
|
bool modifiable = m_file->isModifiable();
|
||||||
int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"),
|
int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"),
|
||||||
@ -262,7 +262,7 @@ void VMdTab::readFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall through
|
V_FALLTHROUGH;
|
||||||
|
|
||||||
case QMessageBox::Discard:
|
case QMessageBox::Discard:
|
||||||
m_editor->reloadFile();
|
m_editor->reloadFile();
|
||||||
@ -293,7 +293,7 @@ bool VMdTab::saveFile()
|
|||||||
|
|
||||||
Q_ASSERT(m_editor);
|
Q_ASSERT(m_editor);
|
||||||
|
|
||||||
if (!m_editor->isModified()) {
|
if (!isModified()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +329,9 @@ bool VMdTab::saveFile()
|
|||||||
tr("Fail to write to disk when saving a note. Please try it again."),
|
tr("Fail to write to disk when saving a note. Please try it again."),
|
||||||
QMessageBox::Ok, QMessageBox::Ok, this);
|
QMessageBox::Ok, QMessageBox::Ok, this);
|
||||||
m_editor->setModified(true);
|
m_editor->setModified(true);
|
||||||
|
} else {
|
||||||
|
m_fileDiverged = false;
|
||||||
|
m_checkFileChange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +340,11 @@ bool VMdTab::saveFile()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VMdTab::isModified() const
|
||||||
|
{
|
||||||
|
return (m_editor ? m_editor->isModified() : false) || m_fileDiverged;
|
||||||
|
}
|
||||||
|
|
||||||
void VMdTab::saveAndRead()
|
void VMdTab::saveAndRead()
|
||||||
{
|
{
|
||||||
saveFile();
|
saveFile();
|
||||||
@ -818,3 +826,19 @@ VInsertSelector *VMdTab::prepareSnippetSelector(QWidget *p_parent)
|
|||||||
VInsertSelector *sel = new VInsertSelector(7, items, p_parent);
|
VInsertSelector *sel = new VInsertSelector(7, items, p_parent);
|
||||||
return sel;
|
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.
|
// Save file.
|
||||||
bool saveFile() Q_DECL_OVERRIDE;
|
bool saveFile() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
bool isModified() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
// Scroll to @p_header.
|
// Scroll to @p_header.
|
||||||
void scrollToHeader(const VHeaderPointer &p_header) Q_DECL_OVERRIDE;
|
void scrollToHeader(const VHeaderPointer &p_header) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -80,6 +82,8 @@ public:
|
|||||||
|
|
||||||
void applySnippet() Q_DECL_OVERRIDE;
|
void applySnippet() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void reload() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
|
@ -141,5 +141,6 @@
|
|||||||
<file>resources/icons/delete_snippet.svg</file>
|
<file>resources/icons/delete_snippet.svg</file>
|
||||||
<file>resources/icons/snippet_info.svg</file>
|
<file>resources/icons/snippet_info.svg</file>
|
||||||
<file>resources/icons/apply_snippet.svg</file>
|
<file>resources/icons/apply_snippet.svg</file>
|
||||||
|
<file>resources/icons/reading_modified.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user