mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
support external programs
This commit is contained in:
parent
b04b23d04b
commit
ff79533fa0
@ -51,6 +51,7 @@ namespace vnotex
|
||||
ActivateNextTab,
|
||||
ActivatePreviousTab,
|
||||
FocusContentArea,
|
||||
OpenWithDefaultProgram,
|
||||
MaxShortcut
|
||||
};
|
||||
Q_ENUM(Shortcut)
|
||||
|
@ -37,6 +37,24 @@ QJsonObject SessionConfig::NotebookItem::toJson() const
|
||||
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)
|
||||
: IConfig(p_mgr, nullptr)
|
||||
{
|
||||
@ -57,10 +75,6 @@ void SessionConfig::init()
|
||||
|
||||
loadStateAndGeometry(sessionJobj);
|
||||
|
||||
if (MainConfig::isVersionChanged()) {
|
||||
doVersionSpecificOverride();
|
||||
}
|
||||
|
||||
m_exportOption.fromJson(sessionJobj[QStringLiteral("export_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_notebookExplorerSession = readByteArray(sessionJobj, QStringLiteral("notebook_explorer_session"));
|
||||
|
||||
loadExternalPrograms(sessionJobj);
|
||||
|
||||
loadNotebooks(sessionJobj);
|
||||
|
||||
if (MainConfig::isVersionChanged()) {
|
||||
doVersionSpecificOverride();
|
||||
}
|
||||
}
|
||||
|
||||
void SessionConfig::loadCore(const QJsonObject &p_session)
|
||||
@ -128,14 +150,8 @@ void SessionConfig::setNewNotebookDefaultRootFolderPath(const QString &p_path)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -191,6 +207,7 @@ QJsonObject SessionConfig::toJson() const
|
||||
obj[QStringLiteral("search_option")] = m_searchOption.toJson();
|
||||
writeByteArray(obj, QStringLiteral("viewarea_session"), m_viewAreaSession);
|
||||
writeByteArray(obj, QStringLiteral("notebook_explorer_session"), m_notebookExplorerSession);
|
||||
obj[QStringLiteral("external_programs")] = saveExternalPrograms();
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -365,3 +382,26 @@ void SessionConfig::setQuickAccessFiles(const QStringList &p_files)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -53,6 +53,20 @@ namespace vnotex
|
||||
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);
|
||||
|
||||
~SessionConfig();
|
||||
@ -65,7 +79,7 @@ namespace vnotex
|
||||
const QString &getCurrentNotebookRootFolderPath() const;
|
||||
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 writeToSettings() const Q_DECL_OVERRIDE;
|
||||
@ -107,6 +121,8 @@ namespace vnotex
|
||||
const QStringList &getQuickAccessFiles() const;
|
||||
void setQuickAccessFiles(const QStringList &p_files);
|
||||
|
||||
const QVector<ExternalProgram> &getExternalPrograms() const;
|
||||
|
||||
private:
|
||||
void loadCore(const QJsonObject &p_session);
|
||||
|
||||
@ -120,6 +136,10 @@ namespace vnotex
|
||||
|
||||
QJsonObject saveStateAndGeometry() const;
|
||||
|
||||
void loadExternalPrograms(const QJsonObject &p_session);
|
||||
|
||||
QJsonArray saveExternalPrograms() const;
|
||||
|
||||
void doVersionSpecificOverride();
|
||||
|
||||
QString m_newNotebookDefaultRootFolderPath;
|
||||
@ -153,6 +173,8 @@ namespace vnotex
|
||||
QString m_flashPage;
|
||||
|
||||
QStringList m_quickAccessFiles;
|
||||
|
||||
QVector<ExternalProgram> m_externalPrograms;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -44,7 +44,8 @@
|
||||
"AlternateTab" : "Ctrl+G, 0",
|
||||
"ActivateNextTab" : "Ctrl+G, N",
|
||||
"ActivatePreviousTab" : "Ctrl+G, P",
|
||||
"FocusContentArea" : "Ctrl+G, Y"
|
||||
"FocusContentArea" : "Ctrl+G, Y",
|
||||
"OpenWithDefaultProgram" : "F9"
|
||||
},
|
||||
"toolbar_icon_size" : 16,
|
||||
"note_management" : {
|
||||
|
30
src/data/extra/docs/en/external_programs.md
Normal file
30
src/data/extra/docs/en/external_programs.md
Normal 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.
|
30
src/data/extra/docs/zh_CN/external_programs.md
Normal file
30
src/data/extra/docs/zh_CN/external_programs.md
Normal 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。
|
@ -4,10 +4,12 @@
|
||||
<file>docs/en/about_vnotex.txt</file>
|
||||
<file>docs/en/shortcuts.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/about_vnotex.txt</file>
|
||||
<file>docs/zh_CN/shortcuts.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-export-template.html</file>
|
||||
<file>web/css/globalstyles.css</file>
|
||||
|
@ -333,7 +333,9 @@ void WebViewExporter::prepareWkhtmltopdfArguments(const ExportPdfOption &p_pdfOp
|
||||
|
||||
// Must be put after the global object options.
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,3 +156,12 @@ ProcessUtils::State ProcessUtils::start(const QString &p_program,
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ namespace vnotex
|
||||
const std::function<void(const QString &)> &p_logger,
|
||||
const bool &p_askedToStop);
|
||||
|
||||
static void startDetached(const QString &p_command);
|
||||
|
||||
// Copied from QProcess code.
|
||||
static QStringList parseCombinedArgString(const QString &p_args);
|
||||
|
||||
|
@ -175,6 +175,10 @@ void WidgetUtils::addActionShortcut(QAction *p_action,
|
||||
void WidgetUtils::addActionShortcutText(QAction *p_action,
|
||||
const QString &p_shortcut)
|
||||
{
|
||||
if (p_shortcut.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QKeySequence kseq(p_shortcut);
|
||||
if (kseq.isEmpty()) {
|
||||
return;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
36
src/widgets/dialogs/settings/miscpage.cpp
Normal file
36
src/widgets/dialogs/settings/miscpage.cpp
Normal 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");
|
||||
}
|
26
src/widgets/dialogs/settings/miscpage.h
Normal file
26
src/widgets/dialogs/settings/miscpage.h
Normal 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
|
@ -10,6 +10,7 @@
|
||||
#include <widgets/widgetsfactory.h>
|
||||
|
||||
#include "generalpage.h"
|
||||
#include "miscpage.h"
|
||||
#include "editorpage.h"
|
||||
#include "texteditorpage.h"
|
||||
#include "markdowneditorpage.h"
|
||||
@ -123,6 +124,14 @@ void SettingsDialog::setupPages()
|
||||
}
|
||||
}
|
||||
|
||||
// Misc.
|
||||
{
|
||||
/*
|
||||
auto page = new MiscPage(this);
|
||||
addPage(page);
|
||||
*/
|
||||
}
|
||||
|
||||
setChangesUnsaved(false);
|
||||
m_pageExplorer->setCurrentItem(m_pageExplorer->topLevelItem(0), 0, QItemSelectionModel::ClearAndSelect);
|
||||
m_pageExplorer->expandAll();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QSet>
|
||||
#include <QShortcut>
|
||||
|
||||
#include <notebook/notebook.h>
|
||||
#include <notebook/node.h>
|
||||
@ -16,6 +17,8 @@
|
||||
#include "vnotex.h"
|
||||
#include "mainwindow.h"
|
||||
#include <utils/iconutils.h>
|
||||
#include <utils/docsutils.h>
|
||||
#include <utils/processutils.h>
|
||||
#include "treewidget.h"
|
||||
#include "dialogs/notepropertiesdialog.h"
|
||||
#include "dialogs/folderpropertiesdialog.h"
|
||||
@ -31,6 +34,8 @@
|
||||
#include <core/fileopenparameters.h>
|
||||
#include <core/events.h>
|
||||
#include <core/configmgr.h>
|
||||
#include <core/coreconfig.h>
|
||||
#include <core/sessionconfig.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -177,6 +182,8 @@ NotebookNodeExplorer::NotebookNodeExplorer(QWidget *p_parent)
|
||||
initNodeIcons();
|
||||
|
||||
setupUI();
|
||||
|
||||
setupShortcuts();
|
||||
}
|
||||
|
||||
void NotebookNodeExplorer::initNodeIcons() const
|
||||
@ -793,6 +800,10 @@ void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_
|
||||
act = createAction(Action::Open, p_menu);
|
||||
p_menu->addAction(act);
|
||||
|
||||
addOpenWithMenu(p_menu);
|
||||
|
||||
p_menu->addSeparator();
|
||||
|
||||
if (selectedSize == 1 && p_node->isContainer()) {
|
||||
act = createAction(Action::ExpandAll, p_menu);
|
||||
p_menu->addAction(act);
|
||||
@ -827,6 +838,10 @@ void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_
|
||||
act = createAction(Action::Open, p_menu);
|
||||
p_menu->addAction(act);
|
||||
|
||||
addOpenWithMenu(p_menu);
|
||||
|
||||
p_menu->addSeparator();
|
||||
|
||||
if (selectedSize == 1 && p_node->isContainer()) {
|
||||
act = createAction(Action::ExpandAll, p_menu);
|
||||
p_menu->addAction(act);
|
||||
@ -902,6 +917,10 @@ void NotebookNodeExplorer::createContextMenuOnExternalNode(QMenu *p_menu, const
|
||||
act = createAction(Action::Open, p_menu);
|
||||
p_menu->addAction(act);
|
||||
|
||||
addOpenWithMenu(p_menu);
|
||||
|
||||
p_menu->addSeparator();
|
||||
|
||||
act = createAction(Action::ImportToConfig, p_menu);
|
||||
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)
|
||||
{
|
||||
auto node = m_notebook->addAsNode(p_node->getNode(),
|
||||
@ -1914,3 +1954,93 @@ void NotebookNodeExplorer::expandItemRecursively(QTreeWidgetItem *p_item)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -155,6 +155,8 @@ namespace vnotex
|
||||
|
||||
void setupUI();
|
||||
|
||||
void setupShortcuts();
|
||||
|
||||
void setupMasterExplorer(QWidget *p_parent = nullptr);
|
||||
|
||||
void clearExplorer();
|
||||
@ -263,6 +265,14 @@ namespace vnotex
|
||||
|
||||
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 void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data);
|
||||
|
@ -569,6 +569,25 @@ void ViewSplit::createContextMenuOnTabBar(QMenu *p_menu, int p_tabIdx) const
|
||||
|
||||
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.
|
||||
p_menu->addAction(tr("Copy Path"),
|
||||
[this, p_tabIdx]() {
|
||||
|
@ -755,12 +755,15 @@ int ViewWindow::checkFileMissingOrChangedOutside()
|
||||
return Failed;
|
||||
}
|
||||
} else if (m_buffer->checkFileChangedOutside()) {
|
||||
int ret = MessageBoxHelper::questionSaveDiscardCancel(MessageBoxHelper::Warning,
|
||||
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("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);
|
||||
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("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 "
|
||||
"just discard the buffer and reload the file."),
|
||||
this);
|
||||
}
|
||||
switch (ret) {
|
||||
case QMessageBox::Save:
|
||||
if (!save(true)) {
|
||||
@ -1095,3 +1098,13 @@ ViewWindowSession ViewWindow::saveSession() const
|
||||
session.m_viewWindowMode = getMode();
|
||||
return session;
|
||||
}
|
||||
|
||||
ViewWindow::WindowFlags ViewWindow::getWindowFlags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
|
||||
void ViewWindow::setWindowFlags(WindowFlags p_flags)
|
||||
{
|
||||
m_flags = p_flags;
|
||||
}
|
||||
|
@ -30,6 +30,13 @@ namespace vnotex
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum WindowFlag
|
||||
{
|
||||
None = 0,
|
||||
AutoReload = 0x1
|
||||
};
|
||||
Q_DECLARE_FLAGS(WindowFlags, WindowFlag);
|
||||
|
||||
explicit ViewWindow(QWidget *p_parent = nullptr);
|
||||
|
||||
virtual ~ViewWindow();
|
||||
@ -74,6 +81,9 @@ namespace vnotex
|
||||
|
||||
virtual ViewWindowSession saveSession() const;
|
||||
|
||||
WindowFlags getWindowFlags() const;
|
||||
void setWindowFlags(WindowFlags p_flags);
|
||||
|
||||
public slots:
|
||||
virtual void handleEditorConfigChange() = 0;
|
||||
|
||||
@ -320,9 +330,13 @@ namespace vnotex
|
||||
|
||||
EditReadDiscardAction *m_editReadDiscardAct = nullptr;
|
||||
|
||||
WindowFlags m_flags = WindowFlag::None;
|
||||
|
||||
static QIcon s_savedIcon;
|
||||
static QIcon s_modifiedIcon;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(vnotex::ViewWindow::WindowFlags)
|
||||
|
||||
#endif // VIEWWINDOW_H
|
||||
|
@ -19,6 +19,7 @@ SOURCES += \
|
||||
$$PWD/dialogs/settings/editorpage.cpp \
|
||||
$$PWD/dialogs/settings/generalpage.cpp \
|
||||
$$PWD/dialogs/settings/markdowneditorpage.cpp \
|
||||
$$PWD/dialogs/settings/miscpage.cpp \
|
||||
$$PWD/dialogs/settings/quickaccesspage.cpp \
|
||||
$$PWD/dialogs/settings/settingspage.cpp \
|
||||
$$PWD/dialogs/settings/settingsdialog.cpp \
|
||||
@ -117,6 +118,7 @@ HEADERS += \
|
||||
$$PWD/dialogs/settings/editorpage.h \
|
||||
$$PWD/dialogs/settings/generalpage.h \
|
||||
$$PWD/dialogs/settings/markdowneditorpage.h \
|
||||
$$PWD/dialogs/settings/miscpage.h \
|
||||
$$PWD/dialogs/settings/quickaccesspage.h \
|
||||
$$PWD/dialogs/settings/settingspage.h \
|
||||
$$PWD/dialogs/settings/settingsdialog.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user