support external programs

This commit is contained in:
Le Tan 2021-06-18 20:46:30 +08:00
parent b04b23d04b
commit ff79533fa0
21 changed files with 423 additions and 21 deletions

View File

@ -51,6 +51,7 @@ namespace vnotex
ActivateNextTab, ActivateNextTab,
ActivatePreviousTab, ActivatePreviousTab,
FocusContentArea, FocusContentArea,
OpenWithDefaultProgram,
MaxShortcut MaxShortcut
}; };
Q_ENUM(Shortcut) Q_ENUM(Shortcut)

View File

@ -37,6 +37,24 @@ QJsonObject SessionConfig::NotebookItem::toJson() const
return jobj; return jobj;
} }
void SessionConfig::ExternalProgram::fromJson(const QJsonObject &p_jobj)
{
m_name = p_jobj[QStringLiteral("name")].toString();
m_command = p_jobj[QStringLiteral("command")].toString();
m_shortcut = p_jobj[QStringLiteral("shortcut")].toString();
}
QJsonObject SessionConfig::ExternalProgram::toJson() const
{
QJsonObject jobj;
jobj[QStringLiteral("name")] = m_name;
jobj[QStringLiteral("command")] = m_command;
jobj[QStringLiteral("shortcut")] = m_shortcut;
return jobj;
}
SessionConfig::SessionConfig(ConfigMgr *p_mgr) SessionConfig::SessionConfig(ConfigMgr *p_mgr)
: IConfig(p_mgr, nullptr) : IConfig(p_mgr, nullptr)
{ {
@ -57,10 +75,6 @@ void SessionConfig::init()
loadStateAndGeometry(sessionJobj); loadStateAndGeometry(sessionJobj);
if (MainConfig::isVersionChanged()) {
doVersionSpecificOverride();
}
m_exportOption.fromJson(sessionJobj[QStringLiteral("export_option")].toObject()); m_exportOption.fromJson(sessionJobj[QStringLiteral("export_option")].toObject());
m_searchOption.fromJson(sessionJobj[QStringLiteral("search_option")].toObject()); m_searchOption.fromJson(sessionJobj[QStringLiteral("search_option")].toObject());
@ -68,6 +82,14 @@ void SessionConfig::init()
m_viewAreaSession = readByteArray(sessionJobj, QStringLiteral("viewarea_session")); m_viewAreaSession = readByteArray(sessionJobj, QStringLiteral("viewarea_session"));
m_notebookExplorerSession = readByteArray(sessionJobj, QStringLiteral("notebook_explorer_session")); m_notebookExplorerSession = readByteArray(sessionJobj, QStringLiteral("notebook_explorer_session"));
loadExternalPrograms(sessionJobj);
loadNotebooks(sessionJobj);
if (MainConfig::isVersionChanged()) {
doVersionSpecificOverride();
}
} }
void SessionConfig::loadCore(const QJsonObject &p_session) void SessionConfig::loadCore(const QJsonObject &p_session)
@ -128,14 +150,8 @@ void SessionConfig::setNewNotebookDefaultRootFolderPath(const QString &p_path)
this); this);
} }
const QVector<SessionConfig::NotebookItem> &SessionConfig::getNotebooks() const QVector<SessionConfig::NotebookItem> &SessionConfig::getNotebooks() const
{ {
if (m_notebooks.isEmpty()) {
auto mgr = getMgr();
auto sessionSettings = mgr->getSettings(ConfigMgr::Source::Session);
const auto &sessionJobj = sessionSettings->getJson();
loadNotebooks(sessionJobj);
}
return m_notebooks; return m_notebooks;
} }
@ -191,6 +207,7 @@ QJsonObject SessionConfig::toJson() const
obj[QStringLiteral("search_option")] = m_searchOption.toJson(); obj[QStringLiteral("search_option")] = m_searchOption.toJson();
writeByteArray(obj, QStringLiteral("viewarea_session"), m_viewAreaSession); writeByteArray(obj, QStringLiteral("viewarea_session"), m_viewAreaSession);
writeByteArray(obj, QStringLiteral("notebook_explorer_session"), m_notebookExplorerSession); writeByteArray(obj, QStringLiteral("notebook_explorer_session"), m_notebookExplorerSession);
obj[QStringLiteral("external_programs")] = saveExternalPrograms();
return obj; return obj;
} }
@ -365,3 +382,26 @@ void SessionConfig::setQuickAccessFiles(const QStringList &p_files)
{ {
updateConfig(m_quickAccessFiles, p_files, this); updateConfig(m_quickAccessFiles, p_files, this);
} }
void SessionConfig::loadExternalPrograms(const QJsonObject &p_session)
{
const auto arr = p_session.value(QStringLiteral("external_programs")).toArray();
m_externalPrograms.resize(arr.size());
for (int i = 0; i < arr.size(); ++i) {
m_externalPrograms[i].fromJson(arr[i].toObject());
}
}
QJsonArray SessionConfig::saveExternalPrograms() const
{
QJsonArray arr;
for (const auto &pro : m_externalPrograms) {
arr.append(pro.toJson());
}
return arr;
}
const QVector<SessionConfig::ExternalProgram> &SessionConfig::getExternalPrograms() const
{
return m_externalPrograms;
}

View File

@ -53,6 +53,20 @@ namespace vnotex
Software Software
}; };
struct ExternalProgram
{
void fromJson(const QJsonObject &p_jobj);
QJsonObject toJson() const;
QString m_name;
// %1: the file paths to open.
QString m_command;
QString m_shortcut;
};
explicit SessionConfig(ConfigMgr *p_mgr); explicit SessionConfig(ConfigMgr *p_mgr);
~SessionConfig(); ~SessionConfig();
@ -65,7 +79,7 @@ namespace vnotex
const QString &getCurrentNotebookRootFolderPath() const; const QString &getCurrentNotebookRootFolderPath() const;
void setCurrentNotebookRootFolderPath(const QString &p_path); void setCurrentNotebookRootFolderPath(const QString &p_path);
const QVector<SessionConfig::NotebookItem> &getNotebooks(); const QVector<SessionConfig::NotebookItem> &getNotebooks() const;
void setNotebooks(const QVector<SessionConfig::NotebookItem> &p_notebooks); void setNotebooks(const QVector<SessionConfig::NotebookItem> &p_notebooks);
void writeToSettings() const Q_DECL_OVERRIDE; void writeToSettings() const Q_DECL_OVERRIDE;
@ -107,6 +121,8 @@ namespace vnotex
const QStringList &getQuickAccessFiles() const; const QStringList &getQuickAccessFiles() const;
void setQuickAccessFiles(const QStringList &p_files); void setQuickAccessFiles(const QStringList &p_files);
const QVector<ExternalProgram> &getExternalPrograms() const;
private: private:
void loadCore(const QJsonObject &p_session); void loadCore(const QJsonObject &p_session);
@ -120,6 +136,10 @@ namespace vnotex
QJsonObject saveStateAndGeometry() const; QJsonObject saveStateAndGeometry() const;
void loadExternalPrograms(const QJsonObject &p_session);
QJsonArray saveExternalPrograms() const;
void doVersionSpecificOverride(); void doVersionSpecificOverride();
QString m_newNotebookDefaultRootFolderPath; QString m_newNotebookDefaultRootFolderPath;
@ -153,6 +173,8 @@ namespace vnotex
QString m_flashPage; QString m_flashPage;
QStringList m_quickAccessFiles; QStringList m_quickAccessFiles;
QVector<ExternalProgram> m_externalPrograms;
}; };
} // ns vnotex } // ns vnotex

View File

@ -44,7 +44,8 @@
"AlternateTab" : "Ctrl+G, 0", "AlternateTab" : "Ctrl+G, 0",
"ActivateNextTab" : "Ctrl+G, N", "ActivateNextTab" : "Ctrl+G, N",
"ActivatePreviousTab" : "Ctrl+G, P", "ActivatePreviousTab" : "Ctrl+G, P",
"FocusContentArea" : "Ctrl+G, Y" "FocusContentArea" : "Ctrl+G, Y",
"OpenWithDefaultProgram" : "F9"
}, },
"toolbar_icon_size" : 16, "toolbar_icon_size" : 16,
"note_management" : { "note_management" : {

View File

@ -0,0 +1,30 @@
# External Programs
VNote allows user to open notes with **external programs** via the `Open With` in the context menu of the node explorer.
To add custom external programs, user needs to edit the session configuration. A sample may look like this:
```json
{
"external_programs": [
{
"name" : "gvim",
"command" : "C:\\\"Program Files (x86)\"\\Vim\\vim80\\gvim.exe %1",
"shortcut" : "F4"
},
{
"name" : "notepad",
"command" : "notepad %1",
"shortcut" : ""
}
]
}
```
An external program could have 3 properties:
1. `name`: the name of the program in VNote;
2. `command`: the command to execute when opening notes with this external program;
1. Use `%1` as a placeholder which will be replaced by the real file paths (automatically wrapped by double quotes);
3. `shortcut`: the shortcut assigned to this external program;
Close VNote before editting the session configuration.

View File

@ -0,0 +1,30 @@
# 外部程序
VNote 支持通过在节点浏览器上下文菜单中的 `打开方式` 来调用 **外部程序** 打开笔记。
用户需要编辑会话配置来添加自定义外部程序。一个例子如下:
```json
{
"external_programs": [
{
"name" : "gvim",
"command" : "C:\\\"Program Files (x86)\"\\Vim\\vim80\\gvim.exe %1",
"shortcut" : "F4"
},
{
"name" : "notepad",
"command" : "notepad %1",
"shortcut" : ""
}
]
}
```
一个外部程序可以包含3个属性
1. `name`: 该程序在 VNote 中的名字;
2. `command`: 当使用该外部程序打开笔记时执行的命令;
1. 使用 `%1` 占位符,会被替换为真实的文件路径(自动加上双引号包裹)
3. `shortcut`: 分配给该外部程序的快捷键;
修改配置前请关闭 VNote。

View File

@ -4,10 +4,12 @@
<file>docs/en/about_vnotex.txt</file> <file>docs/en/about_vnotex.txt</file>
<file>docs/en/shortcuts.md</file> <file>docs/en/shortcuts.md</file>
<file>docs/en/markdown_guide.md</file> <file>docs/en/markdown_guide.md</file>
<file>docs/en/external_programs.md</file>
<file>docs/zh_CN/get_started.txt</file> <file>docs/zh_CN/get_started.txt</file>
<file>docs/zh_CN/about_vnotex.txt</file> <file>docs/zh_CN/about_vnotex.txt</file>
<file>docs/zh_CN/shortcuts.md</file> <file>docs/zh_CN/shortcuts.md</file>
<file>docs/zh_CN/markdown_guide.md</file> <file>docs/zh_CN/markdown_guide.md</file>
<file>docs/zh_CN/external_programs.md</file>
<file>web/markdown-viewer-template.html</file> <file>web/markdown-viewer-template.html</file>
<file>web/markdown-export-template.html</file> <file>web/markdown-export-template.html</file>
<file>web/css/globalstyles.css</file> <file>web/css/globalstyles.css</file>

View File

@ -333,7 +333,9 @@ void WebViewExporter::prepareWkhtmltopdfArguments(const ExportPdfOption &p_pdfOp
// Must be put after the global object options. // Must be put after the global object options.
if (p_pdfOption.m_addTableOfContents) { if (p_pdfOption.m_addTableOfContents) {
m_wkhtmltopdfArgs << "toc" << "--toc-text-size-shrink" << "1.0"; m_wkhtmltopdfArgs << "toc";
m_wkhtmltopdfArgs << "--toc-text-size-shrink" << "1.0";
m_wkhtmltopdfArgs << "--toc-header-text" << tr("Table of Contents");
} }
} }

View File

@ -156,3 +156,12 @@ ProcessUtils::State ProcessUtils::start(const QString &p_program,
return proc.exitStatus() == QProcess::NormalExit ? State::Succeeded : State::Crashed; return proc.exitStatus() == QProcess::NormalExit ? State::Succeeded : State::Crashed;
} }
void ProcessUtils::startDetached(const QString &p_command)
{
Q_ASSERT(!p_command.isEmpty());
auto process = new QProcess();
QObject::connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
process, &QProcess::deleteLater);
process->start(p_command);
}

View File

@ -35,6 +35,8 @@ namespace vnotex
const std::function<void(const QString &)> &p_logger, const std::function<void(const QString &)> &p_logger,
const bool &p_askedToStop); const bool &p_askedToStop);
static void startDetached(const QString &p_command);
// Copied from QProcess code. // Copied from QProcess code.
static QStringList parseCombinedArgString(const QString &p_args); static QStringList parseCombinedArgString(const QString &p_args);

View File

@ -175,6 +175,10 @@ void WidgetUtils::addActionShortcut(QAction *p_action,
void WidgetUtils::addActionShortcutText(QAction *p_action, void WidgetUtils::addActionShortcutText(QAction *p_action,
const QString &p_shortcut) const QString &p_shortcut)
{ {
if (p_shortcut.isEmpty()) {
return;
}
QKeySequence kseq(p_shortcut); QKeySequence kseq(p_shortcut);
if (kseq.isEmpty()) { if (kseq.isEmpty()) {
return; return;

View File

@ -612,7 +612,7 @@ QWidget *ExportDialog::getPdfAdvancedSettings()
} }
{ {
m_addTableOfContentsCheckBox = WidgetsFactory::createCheckBox(tr("Add Table-Of-Contents"), widget); m_addTableOfContentsCheckBox = WidgetsFactory::createCheckBox(tr("Add Table-of-Contents"), widget);
layout->addRow(m_addTableOfContentsCheckBox); layout->addRow(m_addTableOfContentsCheckBox);
} }

View File

@ -0,0 +1,36 @@
#include "miscpage.h"
#include <QFormLayout>
#include <widgets/widgetsfactory.h>
#include <core/coreconfig.h>
#include <core/sessionconfig.h>
#include <core/configmgr.h>
#include <utils/widgetutils.h>
using namespace vnotex;
MiscPage::MiscPage(QWidget *p_parent)
: SettingsPage(p_parent)
{
setupUI();
}
void MiscPage::setupUI()
{
}
void MiscPage::loadInternal()
{
}
void MiscPage::saveInternal()
{
}
QString MiscPage::title() const
{
return tr("Misc");
}

View File

@ -0,0 +1,26 @@
#ifndef MISCPAGE_H
#define MISCPAGE_H
#include "settingspage.h"
namespace vnotex
{
class MiscPage : public SettingsPage
{
Q_OBJECT
public:
explicit MiscPage(QWidget *p_parent = nullptr);
QString title() const Q_DECL_OVERRIDE;
protected:
void loadInternal() Q_DECL_OVERRIDE;
void saveInternal() Q_DECL_OVERRIDE;
private:
void setupUI();
};
}
#endif // MISCPAGE_H

View File

@ -10,6 +10,7 @@
#include <widgets/widgetsfactory.h> #include <widgets/widgetsfactory.h>
#include "generalpage.h" #include "generalpage.h"
#include "miscpage.h"
#include "editorpage.h" #include "editorpage.h"
#include "texteditorpage.h" #include "texteditorpage.h"
#include "markdowneditorpage.h" #include "markdowneditorpage.h"
@ -123,6 +124,14 @@ void SettingsDialog::setupPages()
} }
} }
// Misc.
{
/*
auto page = new MiscPage(this);
addPage(page);
*/
}
setChangesUnsaved(false); setChangesUnsaved(false);
m_pageExplorer->setCurrentItem(m_pageExplorer->topLevelItem(0), 0, QItemSelectionModel::ClearAndSelect); m_pageExplorer->setCurrentItem(m_pageExplorer->topLevelItem(0), 0, QItemSelectionModel::ClearAndSelect);
m_pageExplorer->expandAll(); m_pageExplorer->expandAll();

View File

@ -7,6 +7,7 @@
#include <QMenu> #include <QMenu>
#include <QAction> #include <QAction>
#include <QSet> #include <QSet>
#include <QShortcut>
#include <notebook/notebook.h> #include <notebook/notebook.h>
#include <notebook/node.h> #include <notebook/node.h>
@ -16,6 +17,8 @@
#include "vnotex.h" #include "vnotex.h"
#include "mainwindow.h" #include "mainwindow.h"
#include <utils/iconutils.h> #include <utils/iconutils.h>
#include <utils/docsutils.h>
#include <utils/processutils.h>
#include "treewidget.h" #include "treewidget.h"
#include "dialogs/notepropertiesdialog.h" #include "dialogs/notepropertiesdialog.h"
#include "dialogs/folderpropertiesdialog.h" #include "dialogs/folderpropertiesdialog.h"
@ -31,6 +34,8 @@
#include <core/fileopenparameters.h> #include <core/fileopenparameters.h>
#include <core/events.h> #include <core/events.h>
#include <core/configmgr.h> #include <core/configmgr.h>
#include <core/coreconfig.h>
#include <core/sessionconfig.h>
using namespace vnotex; using namespace vnotex;
@ -177,6 +182,8 @@ NotebookNodeExplorer::NotebookNodeExplorer(QWidget *p_parent)
initNodeIcons(); initNodeIcons();
setupUI(); setupUI();
setupShortcuts();
} }
void NotebookNodeExplorer::initNodeIcons() const void NotebookNodeExplorer::initNodeIcons() const
@ -793,6 +800,10 @@ void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_
act = createAction(Action::Open, p_menu); act = createAction(Action::Open, p_menu);
p_menu->addAction(act); p_menu->addAction(act);
addOpenWithMenu(p_menu);
p_menu->addSeparator();
if (selectedSize == 1 && p_node->isContainer()) { if (selectedSize == 1 && p_node->isContainer()) {
act = createAction(Action::ExpandAll, p_menu); act = createAction(Action::ExpandAll, p_menu);
p_menu->addAction(act); p_menu->addAction(act);
@ -827,6 +838,10 @@ void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_
act = createAction(Action::Open, p_menu); act = createAction(Action::Open, p_menu);
p_menu->addAction(act); p_menu->addAction(act);
addOpenWithMenu(p_menu);
p_menu->addSeparator();
if (selectedSize == 1 && p_node->isContainer()) { if (selectedSize == 1 && p_node->isContainer()) {
act = createAction(Action::ExpandAll, p_menu); act = createAction(Action::ExpandAll, p_menu);
p_menu->addAction(act); p_menu->addAction(act);
@ -902,6 +917,10 @@ void NotebookNodeExplorer::createContextMenuOnExternalNode(QMenu *p_menu, const
act = createAction(Action::Open, p_menu); act = createAction(Action::Open, p_menu);
p_menu->addAction(act); p_menu->addAction(act);
addOpenWithMenu(p_menu);
p_menu->addSeparator();
act = createAction(Action::ImportToConfig, p_menu); act = createAction(Action::ImportToConfig, p_menu);
p_menu->addAction(act); p_menu->addAction(act);
@ -1831,6 +1850,27 @@ void NotebookNodeExplorer::openSelectedNodes()
} }
} }
QStringList NotebookNodeExplorer::getSelectedNodesPath() const
{
QStringList files;
// Support nodes and external nodes.
auto selectedNodes = getSelectedNodes();
for (const auto &externalNode : selectedNodes.second) {
files << externalNode->fetchAbsolutePath();
}
for (const auto &node : selectedNodes.first) {
if (checkInvalidNode(node)) {
continue;
}
files << node->fetchAbsolutePath();
}
return files;
}
QSharedPointer<Node> NotebookNodeExplorer::importToIndex(const ExternalNode *p_node) QSharedPointer<Node> NotebookNodeExplorer::importToIndex(const ExternalNode *p_node)
{ {
auto node = m_notebook->addAsNode(p_node->getNode(), auto node = m_notebook->addAsNode(p_node->getNode(),
@ -1914,3 +1954,93 @@ void NotebookNodeExplorer::expandItemRecursively(QTreeWidgetItem *p_item)
expandItemRecursively(p_item->child(i)); expandItemRecursively(p_item->child(i));
} }
} }
void NotebookNodeExplorer::addOpenWithMenu(QMenu *p_menu)
{
auto subMenu = p_menu->addMenu(tr("Open &With"));
{
const auto &sessionConfig = ConfigMgr::getInst().getSessionConfig();
for (const auto &pro : sessionConfig.getExternalPrograms()) {
QAction *act = subMenu->addAction(pro.m_name);
connect(act, &QAction::triggered,
this, [this, act]() {
openSelectedNodesWithExternalProgram(act->data().toString());
});
act->setData(pro.m_command);
WidgetUtils::addActionShortcutText(act, pro.m_shortcut);
}
}
subMenu->addSeparator();
{
auto defaultAct = subMenu->addAction(tr("System Default Program"),
this,
&NotebookNodeExplorer::openSelectedNodesWithDefaultProgram);
const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
WidgetUtils::addActionShortcutText(defaultAct, coreConfig.getShortcut(CoreConfig::OpenWithDefaultProgram));
}
subMenu->addAction(tr("Add External Program"),
this,
[]() {
const auto file = DocsUtils::getDocFile(QStringLiteral("external_programs.md"));
if (!file.isEmpty()) {
auto paras = QSharedPointer<FileOpenParameters>::create();
paras->m_readOnly = true;
emit VNoteX::getInst().openFileRequested(file, paras);
}
});
}
void NotebookNodeExplorer::setupShortcuts()
{
const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
// OpenWithDefaultProgram.
{
auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::OpenWithDefaultProgram), this);
if (shortcut) {
connect(shortcut, &QShortcut::activated,
this, &NotebookNodeExplorer::openSelectedNodesWithDefaultProgram);
}
}
const auto &sessionConfig = ConfigMgr::getInst().getSessionConfig();
for (const auto &pro : sessionConfig.getExternalPrograms()) {
auto shortcut = WidgetUtils::createShortcut(pro.m_shortcut, this);
const auto &command = pro.m_command;
if (shortcut) {
connect(shortcut, &QShortcut::activated,
this, [this, command]() {
openSelectedNodesWithExternalProgram(command);
});
}
}
}
void NotebookNodeExplorer::openSelectedNodesWithDefaultProgram()
{
const auto files = getSelectedNodesPath();
for (const auto &file : files) {
if (file.isEmpty()) {
continue;
}
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(file));
}
}
void NotebookNodeExplorer::openSelectedNodesWithExternalProgram(const QString &p_command)
{
const auto files = getSelectedNodesPath();
for (const auto &file : files) {
if (file.isEmpty()) {
continue;
}
auto command = p_command;
command.replace(QStringLiteral("%1"), QString("\"%1\"").arg(file));
ProcessUtils::startDetached(command);
}
}

View File

@ -155,6 +155,8 @@ namespace vnotex
void setupUI(); void setupUI();
void setupShortcuts();
void setupMasterExplorer(QWidget *p_parent = nullptr); void setupMasterExplorer(QWidget *p_parent = nullptr);
void clearExplorer(); void clearExplorer();
@ -263,6 +265,14 @@ namespace vnotex
void expandItemRecursively(QTreeWidgetItem *p_item); void expandItemRecursively(QTreeWidgetItem *p_item);
void addOpenWithMenu(QMenu *p_menu);
QStringList getSelectedNodesPath() const;
void openSelectedNodesWithDefaultProgram();
void openSelectedNodesWithExternalProgram(const QString &p_command);
static NotebookNodeExplorer::NodeData getItemNodeData(const QTreeWidgetItem *p_item); static NotebookNodeExplorer::NodeData getItemNodeData(const QTreeWidgetItem *p_item);
static void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data); static void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data);

View File

@ -569,6 +569,25 @@ void ViewSplit::createContextMenuOnTabBar(QMenu *p_menu, int p_tabIdx) const
p_menu->addSeparator(); p_menu->addSeparator();
{
auto act = p_menu->addAction(tr("Auto Reload"));
act->setToolTip(tr("Reload file from disk automatically if it is changed outside"));
act->setCheckable(true);
auto win = getViewWindow(p_tabIdx);
Q_ASSERT(win);
act->setChecked(win->getWindowFlags() & ViewWindow::AutoReload);
connect(act, &QAction::triggered,
this, [win](bool p_checked) {
if (p_checked) {
win->setWindowFlags(win->getWindowFlags() | ViewWindow::AutoReload);
} else {
win->setWindowFlags(win->getWindowFlags() & ~ViewWindow::AutoReload);
}
});
}
p_menu->addSeparator();
// Copy Path. // Copy Path.
p_menu->addAction(tr("Copy Path"), p_menu->addAction(tr("Copy Path"),
[this, p_tabIdx]() { [this, p_tabIdx]() {

View File

@ -755,12 +755,15 @@ int ViewWindow::checkFileMissingOrChangedOutside()
return Failed; return Failed;
} }
} else if (m_buffer->checkFileChangedOutside()) { } else if (m_buffer->checkFileChangedOutside()) {
int ret = MessageBoxHelper::questionSaveDiscardCancel(MessageBoxHelper::Warning, int ret = QMessageBox::Discard;
tr("File is changed from outside (%1).").arg(m_buffer->getPath()), if (!(getWindowFlags() & WindowFlag::AutoReload)) {
tr("Do you want to save the buffer to the file to override, or discard the buffer?"), ret = MessageBoxHelper::questionSaveDiscardCancel(MessageBoxHelper::Warning,
tr("The file is changed from outside. Please choose to save the buffer to the file or " tr("File is changed from outside (%1).").arg(m_buffer->getPath()),
"just discard the buffer and reload the file."), tr("Do you want to save the buffer to the file to override, or discard the buffer?"),
this); tr("The file is changed from outside. Please choose to save the buffer to the file or "
"just discard the buffer and reload the file."),
this);
}
switch (ret) { switch (ret) {
case QMessageBox::Save: case QMessageBox::Save:
if (!save(true)) { if (!save(true)) {
@ -1095,3 +1098,13 @@ ViewWindowSession ViewWindow::saveSession() const
session.m_viewWindowMode = getMode(); session.m_viewWindowMode = getMode();
return session; return session;
} }
ViewWindow::WindowFlags ViewWindow::getWindowFlags() const
{
return m_flags;
}
void ViewWindow::setWindowFlags(WindowFlags p_flags)
{
m_flags = p_flags;
}

View File

@ -30,6 +30,13 @@ namespace vnotex
{ {
Q_OBJECT Q_OBJECT
public: public:
enum WindowFlag
{
None = 0,
AutoReload = 0x1
};
Q_DECLARE_FLAGS(WindowFlags, WindowFlag);
explicit ViewWindow(QWidget *p_parent = nullptr); explicit ViewWindow(QWidget *p_parent = nullptr);
virtual ~ViewWindow(); virtual ~ViewWindow();
@ -74,6 +81,9 @@ namespace vnotex
virtual ViewWindowSession saveSession() const; virtual ViewWindowSession saveSession() const;
WindowFlags getWindowFlags() const;
void setWindowFlags(WindowFlags p_flags);
public slots: public slots:
virtual void handleEditorConfigChange() = 0; virtual void handleEditorConfigChange() = 0;
@ -320,9 +330,13 @@ namespace vnotex
EditReadDiscardAction *m_editReadDiscardAct = nullptr; EditReadDiscardAction *m_editReadDiscardAct = nullptr;
WindowFlags m_flags = WindowFlag::None;
static QIcon s_savedIcon; static QIcon s_savedIcon;
static QIcon s_modifiedIcon; static QIcon s_modifiedIcon;
}; };
} // ns vnotex } // ns vnotex
Q_DECLARE_OPERATORS_FOR_FLAGS(vnotex::ViewWindow::WindowFlags)
#endif // VIEWWINDOW_H #endif // VIEWWINDOW_H

View File

@ -19,6 +19,7 @@ SOURCES += \
$$PWD/dialogs/settings/editorpage.cpp \ $$PWD/dialogs/settings/editorpage.cpp \
$$PWD/dialogs/settings/generalpage.cpp \ $$PWD/dialogs/settings/generalpage.cpp \
$$PWD/dialogs/settings/markdowneditorpage.cpp \ $$PWD/dialogs/settings/markdowneditorpage.cpp \
$$PWD/dialogs/settings/miscpage.cpp \
$$PWD/dialogs/settings/quickaccesspage.cpp \ $$PWD/dialogs/settings/quickaccesspage.cpp \
$$PWD/dialogs/settings/settingspage.cpp \ $$PWD/dialogs/settings/settingspage.cpp \
$$PWD/dialogs/settings/settingsdialog.cpp \ $$PWD/dialogs/settings/settingsdialog.cpp \
@ -117,6 +118,7 @@ HEADERS += \
$$PWD/dialogs/settings/editorpage.h \ $$PWD/dialogs/settings/editorpage.h \
$$PWD/dialogs/settings/generalpage.h \ $$PWD/dialogs/settings/generalpage.h \
$$PWD/dialogs/settings/markdowneditorpage.h \ $$PWD/dialogs/settings/markdowneditorpage.h \
$$PWD/dialogs/settings/miscpage.h \
$$PWD/dialogs/settings/quickaccesspage.h \ $$PWD/dialogs/settings/quickaccesspage.h \
$$PWD/dialogs/settings/settingspage.h \ $$PWD/dialogs/settings/settingspage.h \
$$PWD/dialogs/settings/settingsdialog.h \ $$PWD/dialogs/settings/settingsdialog.h \