From 32aa68dc7823f72362313147cc8f891b57cf6195 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Mon, 20 Nov 2017 19:29:31 +0800 Subject: [PATCH] support custom external editors Define [external_editors] section for custom external editors. --- src/resources/vnote.ini | 7 ++++ src/vconfigmanager.cpp | 18 ++++++++++ src/vconfigmanager.h | 3 ++ src/vfilelist.cpp | 74 ++++++++++++++++++++++++++++++++--------- src/vfilelist.h | 11 +++++- 5 files changed, 96 insertions(+), 17 deletions(-) diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 133f6939..c45b4f8c 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -270,3 +270,10 @@ RemoveSplit=R MagicWord=M ; Prompt for user to apply a snippet ApplySnippet=S + +[external_editors] +; Define external editors which could be called to edit notes +; One program per line with the format name="program %0 arg1 arg2" +; in which %0 will be replaced with the note file path +; Need to escape \ and ", use double quotes to quote paths/arguments with spaces +; SHOULD defined in user config file, not here diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 60775b35..e93bdb8f 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -1300,3 +1300,21 @@ QVector VConfigManager::getCustomMagicWords() return words; } + +QVector> VConfigManager::getExternalEditors() const +{ + QVector> ret; + userSettings->beginGroup("external_editors"); + QStringList keys = userSettings->childKeys(); + for (auto const & key : keys) { + if (key.isEmpty()) { + continue; + } + + ret.push_back(QPair(key, userSettings->value(key).toString())); + } + + userSettings->endGroup(); + + return ret; +} diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index b48294da..6a411325 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -384,6 +384,9 @@ public: // Whether backup file is enabled. bool getEnableBackupFile() const; + // Get defined external editors. + QVector> getExternalEditors() const; + private: // Look up a config from user and default settings. QVariant getConfigFromSettings(const QString §ion, const QString &key) const; diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp index d1a1a078..b2ac6b3b 100644 --- a/src/vfilelist.cpp +++ b/src/vfilelist.cpp @@ -119,21 +119,6 @@ void VFileList::initActions() } }); - m_openExternalAct = new QAction(tr("Open Via External Program"), this); - m_openExternalAct->setToolTip(tr("Open current note via external program")); - connect(m_openExternalAct, &QAction::triggered, - this, [this]() { - QListWidgetItem *item = fileList->currentItem(); - if (item) { - VNoteFile *file = getVFile(item); - if (file - && (!editArea->isFileOpened(file) || editArea->closeFile(file, false))) { - QUrl url = QUrl::fromLocalFile(file->fetchPath()); - QDesktopServices::openUrl(url); - } - } - }); - deleteFileAct = new QAction(QIcon(":/resources/icons/delete_note.svg"), tr("&Delete"), this); deleteFileAct->setToolTip(tr("Delete selected note")); @@ -175,6 +160,8 @@ void VFileList::initActions() m_sortAct->setToolTip(tr("Sort notes in this folder manually")); connect(m_sortAct, &QAction::triggered, this, &VFileList::sortItems); + + initOpenWithMenu(); } void VFileList::setDirectory(VDirectory *p_directory) @@ -540,7 +527,7 @@ void VFileList::contextMenuRequested(QPoint pos) menu.addAction(m_openInEditAct); } - menu.addAction(m_openExternalAct); + menu.addMenu(m_openWithMenu); menu.addSeparator(); } } @@ -977,3 +964,58 @@ void VFileList::sortItems() updateFileList(); } } + +void VFileList::initOpenWithMenu() +{ + m_openWithMenu = new QMenu(tr("Open With"), this); + m_openWithMenu->setToolTipsVisible(true); + + auto programs = g_config->getExternalEditors(); + for (auto const & pa : programs) { + QAction *act = new QAction(pa.first, this); + act->setToolTip(tr("Open current note with %1").arg(pa.first)); + act->setStatusTip(pa.second); + act->setData(pa.second); + connect(act, &QAction::triggered, + this, &VFileList::handleOpenWithActionTriggered); + + m_openWithMenu->addAction(act); + } + + QAction *defaultAct = new QAction(tr("System's Default Program"), this); + defaultAct->setToolTip(tr("Open current note with system's default program")); + connect(defaultAct, &QAction::triggered, + this, [this]() { + QListWidgetItem *item = fileList->currentItem(); + if (item) { + VNoteFile *file = getVFile(item); + if (file + && (!editArea->isFileOpened(file) || editArea->closeFile(file, false))) { + QUrl url = QUrl::fromLocalFile(file->fetchPath()); + QDesktopServices::openUrl(url); + } + } + }); + + m_openWithMenu->addAction(defaultAct); +} + +void VFileList::handleOpenWithActionTriggered() +{ + QAction *act = static_cast(sender()); + QString cmd = act->data().toString(); + + QListWidgetItem *item = fileList->currentItem(); + if (item) { + VNoteFile *file = getVFile(item); + if (file + && (!editArea->isFileOpened(file) || editArea->closeFile(file, false))) { + cmd.replace("%0", file->fetchPath()); + QProcess *process = new QProcess(this); + connect(process, static_cast(&QProcess::finished), + process, &QProcess::deleteLater); + process->start(cmd); + qDebug() << "open with" << cmd << "process" << process->processId(); + } + } +} diff --git a/src/vfilelist.h b/src/vfilelist.h index 56b43bc8..8a24baf1 100644 --- a/src/vfilelist.h +++ b/src/vfilelist.h @@ -21,6 +21,7 @@ class QPushButton; class VEditArea; class QFocusEvent; class QLabel; +class QMenu; class VFileList : public QWidget, public VNavigationMode { @@ -101,6 +102,9 @@ private slots: // Sort files in this list. void sortItems(); + // Hanlde Open With action's triggered signal. + void handleOpenWithActionTriggered(); + protected: void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; @@ -151,6 +155,9 @@ private: // Check if there are files in clipboard available to paste. bool pasteAvailable() const; + // Init Open With menu. + void initOpenWithMenu(); + VEditArea *editArea; QListWidget *fileList; QPointer m_directory; @@ -161,7 +168,6 @@ private: // Actions QAction *m_openInReadAct; QAction *m_openInEditAct; - QAction *m_openExternalAct; QAction *newFileAct; QAction *deleteFileAct; QAction *fileInfoAct; @@ -171,6 +177,9 @@ private: QAction *m_openLocationAct; QAction *m_sortAct; + // Context sub-menu of Open With. + QMenu *m_openWithMenu; + static const QString c_infoShortcutSequence; static const QString c_copyShortcutSequence; static const QString c_cutShortcutSequence;