support custom external editors

Define [external_editors] section for custom external editors.
This commit is contained in:
Le Tan 2017-11-20 19:29:31 +08:00
parent 8ab8b3d83a
commit 32aa68dc78
5 changed files with 96 additions and 17 deletions

View File

@ -270,3 +270,10 @@ RemoveSplit=R
MagicWord=M MagicWord=M
; Prompt for user to apply a snippet ; Prompt for user to apply a snippet
ApplySnippet=S 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

View File

@ -1300,3 +1300,21 @@ QVector<VMagicWord> VConfigManager::getCustomMagicWords()
return words; return words;
} }
QVector<QPair<QString, QString>> VConfigManager::getExternalEditors() const
{
QVector<QPair<QString, QString>> ret;
userSettings->beginGroup("external_editors");
QStringList keys = userSettings->childKeys();
for (auto const & key : keys) {
if (key.isEmpty()) {
continue;
}
ret.push_back(QPair<QString, QString>(key, userSettings->value(key).toString()));
}
userSettings->endGroup();
return ret;
}

View File

@ -384,6 +384,9 @@ public:
// Whether backup file is enabled. // Whether backup file is enabled.
bool getEnableBackupFile() const; bool getEnableBackupFile() const;
// Get defined external editors.
QVector<QPair<QString, QString>> getExternalEditors() 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 &section, const QString &key) const; QVariant getConfigFromSettings(const QString &section, const QString &key) const;

View File

@ -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"), deleteFileAct = new QAction(QIcon(":/resources/icons/delete_note.svg"),
tr("&Delete"), this); tr("&Delete"), this);
deleteFileAct->setToolTip(tr("Delete selected note")); deleteFileAct->setToolTip(tr("Delete selected note"));
@ -175,6 +160,8 @@ void VFileList::initActions()
m_sortAct->setToolTip(tr("Sort notes in this folder manually")); m_sortAct->setToolTip(tr("Sort notes in this folder manually"));
connect(m_sortAct, &QAction::triggered, connect(m_sortAct, &QAction::triggered,
this, &VFileList::sortItems); this, &VFileList::sortItems);
initOpenWithMenu();
} }
void VFileList::setDirectory(VDirectory *p_directory) void VFileList::setDirectory(VDirectory *p_directory)
@ -540,7 +527,7 @@ void VFileList::contextMenuRequested(QPoint pos)
menu.addAction(m_openInEditAct); menu.addAction(m_openInEditAct);
} }
menu.addAction(m_openExternalAct); menu.addMenu(m_openWithMenu);
menu.addSeparator(); menu.addSeparator();
} }
} }
@ -977,3 +964,58 @@ void VFileList::sortItems()
updateFileList(); 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<QAction *>(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<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
process, &QProcess::deleteLater);
process->start(cmd);
qDebug() << "open with" << cmd << "process" << process->processId();
}
}
}

View File

@ -21,6 +21,7 @@ class QPushButton;
class VEditArea; class VEditArea;
class QFocusEvent; class QFocusEvent;
class QLabel; class QLabel;
class QMenu;
class VFileList : public QWidget, public VNavigationMode class VFileList : public QWidget, public VNavigationMode
{ {
@ -101,6 +102,9 @@ private slots:
// Sort files in this list. // Sort files in this list.
void sortItems(); void sortItems();
// Hanlde Open With action's triggered signal.
void handleOpenWithActionTriggered();
protected: protected:
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
@ -151,6 +155,9 @@ private:
// Check if there are files in clipboard available to paste. // Check if there are files in clipboard available to paste.
bool pasteAvailable() const; bool pasteAvailable() const;
// Init Open With menu.
void initOpenWithMenu();
VEditArea *editArea; VEditArea *editArea;
QListWidget *fileList; QListWidget *fileList;
QPointer<VDirectory> m_directory; QPointer<VDirectory> m_directory;
@ -161,7 +168,6 @@ private:
// Actions // Actions
QAction *m_openInReadAct; QAction *m_openInReadAct;
QAction *m_openInEditAct; QAction *m_openInEditAct;
QAction *m_openExternalAct;
QAction *newFileAct; QAction *newFileAct;
QAction *deleteFileAct; QAction *deleteFileAct;
QAction *fileInfoAct; QAction *fileInfoAct;
@ -171,6 +177,9 @@ private:
QAction *m_openLocationAct; QAction *m_openLocationAct;
QAction *m_sortAct; QAction *m_sortAct;
// Context sub-menu of Open With.
QMenu *m_openWithMenu;
static const QString c_infoShortcutSequence; static const QString c_infoShortcutSequence;
static const QString c_copyShortcutSequence; static const QString c_copyShortcutSequence;
static const QString c_cutShortcutSequence; static const QString c_cutShortcutSequence;