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;
if (!(getWindowFlags() & WindowFlag::AutoReload)) {
ret = MessageBoxHelper::questionSaveDiscardCancel(MessageBoxHelper::Warning,
tr("File is changed from outside (%1).").arg(m_buffer->getPath()), tr("File is changed from outside (%1).").arg(m_buffer->getPath()),
tr("Do you want to save the buffer to the file to override, or discard the buffer?"), tr("Do you want to save the buffer to the file to override, or discard the buffer?"),
tr("The file is changed from outside. Please choose to save the buffer to the file or " 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."), "just discard the buffer and reload the file."),
this); 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 \