mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
snippet: support Ctrl+E S to insert snippets
This commit is contained in:
parent
9b730c2889
commit
0a97b2480d
@ -218,6 +218,8 @@ Jump to the first split window on the right.
|
|||||||
Move current tab one split window left.
|
Move current tab one split window left.
|
||||||
- `Shift+L`
|
- `Shift+L`
|
||||||
Move current tab one split window right.
|
Move current tab one split window right.
|
||||||
|
- `S`
|
||||||
|
Apply a snippet in edit mode.
|
||||||
- `?`
|
- `?`
|
||||||
Display shortcuts documentation.
|
Display shortcuts documentation.
|
||||||
|
|
||||||
|
@ -219,6 +219,8 @@ RemoveSplit=R
|
|||||||
将当前标签页左移一个分割窗口。
|
将当前标签页左移一个分割窗口。
|
||||||
- `Shift+L`
|
- `Shift+L`
|
||||||
将当前标签页右移一个分割窗口。
|
将当前标签页右移一个分割窗口。
|
||||||
|
- `S`
|
||||||
|
在编辑模式中应用片段。
|
||||||
- `?`
|
- `?`
|
||||||
显示本快捷键说明。
|
显示本快捷键说明。
|
||||||
|
|
||||||
|
@ -255,3 +255,5 @@ VerticalSplit=V
|
|||||||
RemoveSplit=R
|
RemoveSplit=R
|
||||||
; Evaluate selected text or cursor word as magic words
|
; Evaluate selected text or cursor word as magic words
|
||||||
MagicWord=M
|
MagicWord=M
|
||||||
|
; Prompt for user to apply a snippet
|
||||||
|
ApplySnippet=S
|
||||||
|
@ -268,6 +268,15 @@ QLabel[ColorTealLabel="true"] {
|
|||||||
background-color: @Teal7;
|
background-color: @Teal7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VSelectorItemWidget QLabel[SelectorItemShortcutLabel="true"] {
|
||||||
|
font: bold;
|
||||||
|
border: 2px solid @logo-min;
|
||||||
|
padding: 3px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: @logo-base;
|
||||||
|
color: @logo-max;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget[NotebookPanel="true"] {
|
QWidget[NotebookPanel="true"] {
|
||||||
padding-left: 3px;
|
padding-left: 3px;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,8 @@ SOURCES += main.cpp\
|
|||||||
vsnippet.cpp \
|
vsnippet.cpp \
|
||||||
dialog/veditsnippetdialog.cpp \
|
dialog/veditsnippetdialog.cpp \
|
||||||
utils/vimnavigationforwidget.cpp \
|
utils/vimnavigationforwidget.cpp \
|
||||||
vtoolbox.cpp
|
vtoolbox.cpp \
|
||||||
|
vinsertselector.cpp
|
||||||
|
|
||||||
HEADERS += vmainwindow.h \
|
HEADERS += vmainwindow.h \
|
||||||
vdirectorytree.h \
|
vdirectorytree.h \
|
||||||
@ -181,7 +182,8 @@ HEADERS += vmainwindow.h \
|
|||||||
vsnippet.h \
|
vsnippet.h \
|
||||||
dialog/veditsnippetdialog.h \
|
dialog/veditsnippetdialog.h \
|
||||||
utils/vimnavigationforwidget.h \
|
utils/vimnavigationforwidget.h \
|
||||||
vtoolbox.h
|
vtoolbox.h \
|
||||||
|
vinsertselector.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
vnote.qrc \
|
vnote.qrc \
|
||||||
|
@ -516,6 +516,7 @@ QChar VUtils::keyToChar(int p_key)
|
|||||||
if (p_key >= Qt::Key_A && p_key <= Qt::Key_Z) {
|
if (p_key >= Qt::Key_A && p_key <= Qt::Key_Z) {
|
||||||
return QChar('a' + p_key - Qt::Key_A);
|
return QChar('a' + p_key - Qt::Key_A);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QChar();
|
return QChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ void VButtonWithWidget::init()
|
|||||||
m_bubbleBg = QColor("#15AE67");
|
m_bubbleBg = QColor("#15AE67");
|
||||||
|
|
||||||
QMenu *menu = new QMenu(this);
|
QMenu *menu = new QMenu(this);
|
||||||
VButtonWidgetAction *act = new VButtonWidgetAction(m_popupWidget, menu);
|
QWidgetAction *act = new QWidgetAction(menu);
|
||||||
|
act->setDefaultWidget(m_popupWidget);
|
||||||
menu->addAction(act);
|
menu->addAction(act);
|
||||||
connect(menu, &QMenu::aboutToShow,
|
connect(menu, &QMenu::aboutToShow,
|
||||||
this, [this]() {
|
this, [this]() {
|
||||||
|
@ -39,25 +39,6 @@ private:
|
|||||||
VButtonWithWidget *m_btn;
|
VButtonWithWidget *m_btn;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VButtonWidgetAction : public QWidgetAction
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
VButtonWidgetAction(QWidget *p_widget, QWidget *p_parent)
|
|
||||||
: QWidgetAction(p_parent), m_widget(p_widget)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *createWidget(QWidget *p_parent)
|
|
||||||
{
|
|
||||||
m_widget->setParent(p_parent);
|
|
||||||
return m_widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QWidget *m_widget;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A QPushButton with popup widget.
|
// A QPushButton with popup widget.
|
||||||
class VButtonWithWidget : public QPushButton
|
class VButtonWithWidget : public QPushButton
|
||||||
{
|
{
|
||||||
|
@ -885,6 +885,10 @@ void VEditArea::registerCaptainTargets()
|
|||||||
g_config->getCaptainShortcutKeySequence("MagicWord"),
|
g_config->getCaptainShortcutKeySequence("MagicWord"),
|
||||||
this,
|
this,
|
||||||
evaluateMagicWordsByCaptain);
|
evaluateMagicWordsByCaptain);
|
||||||
|
captain->registerCaptainTarget(tr("ApplySnippet"),
|
||||||
|
g_config->getCaptainShortcutKeySequence("ApplySnippet"),
|
||||||
|
this,
|
||||||
|
applySnippetByCaptain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditArea::activateTabByCaptain(void *p_target, void *p_data, int p_idx)
|
void VEditArea::activateTabByCaptain(void *p_target, void *p_data, int p_idx)
|
||||||
@ -989,6 +993,16 @@ void VEditArea::evaluateMagicWordsByCaptain(void *p_target, void *p_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditArea::applySnippetByCaptain(void *p_target, void *p_data)
|
||||||
|
{
|
||||||
|
Q_UNUSED(p_data);
|
||||||
|
VEditArea *obj = static_cast<VEditArea *>(p_target);
|
||||||
|
VEditTab *tab = obj->getCurrentTab();
|
||||||
|
if (tab && tab->tabHasFocus()) {
|
||||||
|
tab->applySnippet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VEditArea::recordClosedFile(const VFileSessionInfo &p_file)
|
void VEditArea::recordClosedFile(const VFileSessionInfo &p_file)
|
||||||
{
|
{
|
||||||
for (auto it = m_lastClosedFiles.begin(); it != m_lastClosedFiles.end(); ++it) {
|
for (auto it = m_lastClosedFiles.begin(); it != m_lastClosedFiles.end(); ++it) {
|
||||||
|
@ -195,6 +195,9 @@ private:
|
|||||||
// Evaluate selected text or the word on cursor as magic words.
|
// Evaluate selected text or the word on cursor as magic words.
|
||||||
static void evaluateMagicWordsByCaptain(void *p_target, void *p_data);
|
static void evaluateMagicWordsByCaptain(void *p_target, void *p_data);
|
||||||
|
|
||||||
|
// Prompt for user to apply a snippet.
|
||||||
|
static void applySnippetByCaptain(void *p_target, void *p_data);
|
||||||
|
|
||||||
// End Captain mode functions.
|
// End Captain mode functions.
|
||||||
|
|
||||||
int curWindowIndex;
|
int curWindowIndex;
|
||||||
|
@ -129,3 +129,7 @@ void VEditTab::applySnippet(const VSnippet *p_snippet)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(p_snippet);
|
Q_UNUSED(p_snippet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditTab::applySnippet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -95,6 +95,9 @@ public:
|
|||||||
// Insert snippet @p_snippet.
|
// Insert snippet @p_snippet.
|
||||||
virtual void applySnippet(const VSnippet *p_snippet);
|
virtual void applySnippet(const VSnippet *p_snippet);
|
||||||
|
|
||||||
|
// Prompt for user to apply a snippet.
|
||||||
|
virtual void applySnippet();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode
|
// Enter edit mode
|
||||||
virtual void editFile() = 0;
|
virtual void editFile() = 0;
|
||||||
|
113
src/vinsertselector.cpp
Normal file
113
src/vinsertselector.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "vinsertselector.h"
|
||||||
|
|
||||||
|
#include <QtWidgets>
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
|
||||||
|
VSelectorItemWidget::VSelectorItemWidget(QWidget *p_parent)
|
||||||
|
: QWidget(p_parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VSelectorItemWidget::VSelectorItemWidget(const VInsertSelectorItem &p_item, QWidget *p_parent)
|
||||||
|
: QWidget(p_parent), m_name(p_item.m_name)
|
||||||
|
{
|
||||||
|
QLabel *shortcutLabel = new QLabel(p_item.m_shortcut);
|
||||||
|
shortcutLabel->setProperty("SelectorItemShortcutLabel", true);
|
||||||
|
|
||||||
|
m_btn = new QPushButton(p_item.m_name);
|
||||||
|
m_btn->setToolTip(p_item.m_toolTip);
|
||||||
|
m_btn->setProperty("SelectionBtn", true);
|
||||||
|
connect(m_btn, &QPushButton::clicked,
|
||||||
|
this, [this]() {
|
||||||
|
emit clicked(m_name);
|
||||||
|
});
|
||||||
|
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout();
|
||||||
|
layout->addWidget(shortcutLabel);
|
||||||
|
layout->addWidget(m_btn, 1);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
VInsertSelector::VInsertSelector(int p_nrRows,
|
||||||
|
const QVector<VInsertSelectorItem> &p_items,
|
||||||
|
QWidget *p_parent)
|
||||||
|
: QWidget(p_parent),
|
||||||
|
m_items(p_items)
|
||||||
|
{
|
||||||
|
setupUI(p_nrRows < 1 ? 1 : p_nrRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VInsertSelector::setupUI(int p_nrRows)
|
||||||
|
{
|
||||||
|
QGridLayout *layout = new QGridLayout();
|
||||||
|
|
||||||
|
int row = 0, col = 0;
|
||||||
|
for (auto const & it : m_items) {
|
||||||
|
QWidget *wid = createItemWidget(it);
|
||||||
|
layout->addWidget(wid, row, col);
|
||||||
|
if (++row == p_nrRows) {
|
||||||
|
row = 0;
|
||||||
|
++col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *VInsertSelector::createItemWidget(const VInsertSelectorItem &p_item)
|
||||||
|
{
|
||||||
|
VSelectorItemWidget *widget = new VSelectorItemWidget(p_item);
|
||||||
|
connect(widget, &VSelectorItemWidget::clicked,
|
||||||
|
this, &VInsertSelector::itemClicked);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VInsertSelector::itemClicked(const QString &p_name)
|
||||||
|
{
|
||||||
|
m_clickedItemName = p_name;
|
||||||
|
emit accepted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VInsertSelector::keyPressEvent(QKeyEvent *p_event)
|
||||||
|
{
|
||||||
|
QWidget::keyPressEvent(p_event);
|
||||||
|
|
||||||
|
if (p_event->key() == Qt::Key_BracketLeft
|
||||||
|
&& VUtils::isControlModifierForVim(p_event->modifiers())) {
|
||||||
|
m_clickedItemName.clear();
|
||||||
|
emit accepted(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar ch = VUtils::keyToChar(p_event->key());
|
||||||
|
if (!ch.isNull()) {
|
||||||
|
// Activate corresponding item.
|
||||||
|
const VInsertSelectorItem *item = findItemByShortcut(ch);
|
||||||
|
if (item) {
|
||||||
|
itemClicked(item->m_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const VInsertSelectorItem *VInsertSelector::findItemByShortcut(QChar p_shortcut) const
|
||||||
|
{
|
||||||
|
for (auto const & it : m_items) {
|
||||||
|
if (it.m_shortcut == p_shortcut) {
|
||||||
|
return ⁢
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VInsertSelector::showEvent(QShowEvent *p_event)
|
||||||
|
{
|
||||||
|
QWidget::showEvent(p_event);
|
||||||
|
|
||||||
|
if (!hasFocus()) {
|
||||||
|
setFocus();
|
||||||
|
}
|
||||||
|
}
|
87
src/vinsertselector.h
Normal file
87
src/vinsertselector.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef VINSERTSELECTOR_H
|
||||||
|
#define VINSERTSELECTOR_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
class QKeyEvent;
|
||||||
|
class QShowEvent;
|
||||||
|
|
||||||
|
struct VInsertSelectorItem
|
||||||
|
{
|
||||||
|
VInsertSelectorItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VInsertSelectorItem(const QString &p_name,
|
||||||
|
const QString &p_toolTip,
|
||||||
|
QChar p_shortcut = QChar())
|
||||||
|
: m_name(p_name), m_toolTip(p_toolTip), m_shortcut(p_shortcut)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString m_name;
|
||||||
|
|
||||||
|
QString m_toolTip;
|
||||||
|
|
||||||
|
QChar m_shortcut;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VSelectorItemWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VSelectorItemWidget(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
VSelectorItemWidget(const VInsertSelectorItem &p_item, QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// This item widget is clicked.
|
||||||
|
void clicked(const QString &p_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_name;
|
||||||
|
|
||||||
|
QPushButton *m_btn;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VInsertSelector : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VInsertSelector(int p_nrRows,
|
||||||
|
const QVector<VInsertSelectorItem> &p_items,
|
||||||
|
QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
const QString &getClickedItem() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void accepted(bool p_accepted = true);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void itemClicked(const QString &p_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupUI(int p_nrRows);
|
||||||
|
|
||||||
|
QWidget *createItemWidget(const VInsertSelectorItem &p_item);
|
||||||
|
|
||||||
|
const VInsertSelectorItem *findItemByShortcut(QChar p_shortcut) const;
|
||||||
|
|
||||||
|
QVector<VInsertSelectorItem> m_items;
|
||||||
|
|
||||||
|
QString m_clickedItemName;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const QString &VInsertSelector::getClickedItem() const
|
||||||
|
{
|
||||||
|
return m_clickedItemName;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VINSERTSELECTOR_H
|
@ -64,6 +64,8 @@ public:
|
|||||||
|
|
||||||
VEditArea *getEditArea() const;
|
VEditArea *getEditArea() const;
|
||||||
|
|
||||||
|
VSnippetList *getSnippetList() const;
|
||||||
|
|
||||||
// View and edit the information of @p_file, which is an orphan file.
|
// View and edit the information of @p_file, which is an orphan file.
|
||||||
void editOrphanFileInfo(VFile *p_file);
|
void editOrphanFileInfo(VFile *p_file);
|
||||||
|
|
||||||
@ -411,4 +413,9 @@ inline VEditTab *VMainWindow::getCurrentTab() const
|
|||||||
return m_curTab;
|
return m_curTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline VSnippetList *VMainWindow::getSnippetList() const
|
||||||
|
{
|
||||||
|
return m_snippetList;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VMAINWINDOW_H
|
#endif // VMAINWINDOW_H
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <QWebChannel>
|
#include <QWebChannel>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QXmlStreamReader>
|
#include <QCoreApplication>
|
||||||
#include "vmdtab.h"
|
#include "vmdtab.h"
|
||||||
#include "vdocument.h"
|
#include "vdocument.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
@ -19,6 +19,8 @@
|
|||||||
#include "vmdeditor.h"
|
#include "vmdeditor.h"
|
||||||
#include "vmainwindow.h"
|
#include "vmainwindow.h"
|
||||||
#include "vsnippet.h"
|
#include "vsnippet.h"
|
||||||
|
#include "vinsertselector.h"
|
||||||
|
#include "vsnippetlist.h"
|
||||||
|
|
||||||
extern VMainWindow *g_mainWin;
|
extern VMainWindow *g_mainWin;
|
||||||
|
|
||||||
@ -728,6 +730,8 @@ void VMdTab::evaluateMagicWords()
|
|||||||
|
|
||||||
void VMdTab::applySnippet(const VSnippet *p_snippet)
|
void VMdTab::applySnippet(const VSnippet *p_snippet)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(p_snippet);
|
||||||
|
|
||||||
if (isEditMode()
|
if (isEditMode()
|
||||||
&& m_file->isModifiable()
|
&& m_file->isModifiable()
|
||||||
&& p_snippet->getType() == VSnippet::Type::PlainText) {
|
&& p_snippet->getType() == VSnippet::Type::PlainText) {
|
||||||
@ -738,6 +742,79 @@ void VMdTab::applySnippet(const VSnippet *p_snippet)
|
|||||||
m_editor->setTextCursor(cursor);
|
m_editor->setTextCursor(cursor);
|
||||||
|
|
||||||
m_editor->setVimMode(VimMode::Insert);
|
m_editor->setVimMode(VimMode::Insert);
|
||||||
|
|
||||||
|
g_mainWin->showStatusMessage(tr("Snippet applied"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_mainWin->showStatusMessage(tr("Snippet %1 is not applicable").arg(p_snippet->getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdTab::applySnippet()
|
||||||
|
{
|
||||||
|
if (!isEditMode() || !m_file->isModifiable()) {
|
||||||
|
g_mainWin->showStatusMessage(tr("Snippets are not applicable"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint pos(m_editor->cursorRect().bottomRight());
|
||||||
|
QMenu menu(this);
|
||||||
|
VInsertSelector *sel = prepareSnippetSelector(&menu);
|
||||||
|
if (!sel) {
|
||||||
|
g_mainWin->showStatusMessage(tr("No available snippets defined with shortcuts"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidgetAction *act = new QWidgetAction(&menu);
|
||||||
|
act->setDefaultWidget(sel);
|
||||||
|
connect(sel, &VInsertSelector::accepted,
|
||||||
|
this, [this, &menu]() {
|
||||||
|
QKeyEvent *escEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape,
|
||||||
|
Qt::NoModifier);
|
||||||
|
QCoreApplication::postEvent(&menu, escEvent);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addAction(act);
|
||||||
|
|
||||||
|
menu.exec(m_editor->mapToGlobal(pos));
|
||||||
|
|
||||||
|
QString chosenItem = sel->getClickedItem();
|
||||||
|
if (!chosenItem.isEmpty()) {
|
||||||
|
const VSnippet *snip = g_mainWin->getSnippetList()->getSnippet(chosenItem);
|
||||||
|
if (snip) {
|
||||||
|
applySnippet(snip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool selectorItemCmp(const VInsertSelectorItem &p_a, const VInsertSelectorItem &p_b)
|
||||||
|
{
|
||||||
|
if (p_a.m_shortcut < p_b.m_shortcut) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VInsertSelector *VMdTab::prepareSnippetSelector(QWidget *p_parent)
|
||||||
|
{
|
||||||
|
auto snippets = g_mainWin->getSnippetList()->getSnippets();
|
||||||
|
QVector<VInsertSelectorItem> items;
|
||||||
|
for (auto const & snip : snippets) {
|
||||||
|
if (!snip.getShortcut().isNull()) {
|
||||||
|
items.push_back(VInsertSelectorItem(snip.getName(),
|
||||||
|
snip.getName(),
|
||||||
|
snip.getShortcut()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort items by shortcut.
|
||||||
|
std::sort(items.begin(), items.end(), selectorItemCmp);
|
||||||
|
|
||||||
|
VInsertSelector *sel = new VInsertSelector(7, items, p_parent);
|
||||||
|
return sel;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ class VWebView;
|
|||||||
class QStackedLayout;
|
class QStackedLayout;
|
||||||
class VDocument;
|
class VDocument;
|
||||||
class VMdEditor;
|
class VMdEditor;
|
||||||
|
class VInsertSelector;
|
||||||
|
|
||||||
class VMdTab : public VEditTab
|
class VMdTab : public VEditTab
|
||||||
{
|
{
|
||||||
@ -77,6 +78,8 @@ public:
|
|||||||
|
|
||||||
void applySnippet(const VSnippet *p_snippet) Q_DECL_OVERRIDE;
|
void applySnippet(const VSnippet *p_snippet) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void applySnippet() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
@ -156,6 +159,9 @@ private:
|
|||||||
// Return true if succeed.
|
// Return true if succeed.
|
||||||
bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE;
|
bool restoreFromTabInfo(const VEditTabInfo &p_info) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
// Prepare insert selector with snippets.
|
||||||
|
VInsertSelector *prepareSnippetSelector(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
VMdEditor *m_editor;
|
VMdEditor *m_editor;
|
||||||
VWebView *m_webViewer;
|
VWebView *m_webViewer;
|
||||||
VDocument *m_document;
|
VDocument *m_document;
|
||||||
|
@ -162,11 +162,16 @@ bool VSnippet::apply(QTextCursor &p_cursor) const
|
|||||||
// Evaluate the content.
|
// Evaluate the content.
|
||||||
QString content = g_mwMgr->evaluate(m_content);
|
QString content = g_mwMgr->evaluate(m_content);
|
||||||
|
|
||||||
|
if (content.isEmpty()) {
|
||||||
|
p_cursor.endEditBlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Find the cursor mark and break the content.
|
// Find the cursor mark and break the content.
|
||||||
QString secondPart;
|
QString secondPart;
|
||||||
if (!m_cursorMark.isEmpty()) {
|
if (!m_cursorMark.isEmpty()) {
|
||||||
QStringList parts = content.split(m_cursorMark, QString::SkipEmptyParts);
|
QStringList parts = content.split(m_cursorMark);
|
||||||
Q_ASSERT(parts.size() < 3);
|
Q_ASSERT(parts.size() < 3 && parts.size() > 0);
|
||||||
|
|
||||||
content = parts[0];
|
content = parts[0];
|
||||||
if (parts.size() == 2) {
|
if (parts.size() == 2) {
|
||||||
@ -175,13 +180,14 @@ bool VSnippet::apply(QTextCursor &p_cursor) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace the selection mark.
|
// Replace the selection mark.
|
||||||
if (!m_selectionMark.isEmpty()) {
|
// Content may be empty.
|
||||||
|
if (!m_selectionMark.isEmpty() && !content.isEmpty()) {
|
||||||
content.replace(m_selectionMark, selection);
|
content.replace(m_selectionMark, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pos = p_cursor.position() + content.size();
|
int pos = p_cursor.position() + content.size();
|
||||||
|
|
||||||
if (!secondPart.isEmpty()) {
|
if (!m_selectionMark.isEmpty() && !secondPart.isEmpty()) {
|
||||||
secondPart.replace(m_selectionMark, selection);
|
secondPart.replace(m_selectionMark, selection);
|
||||||
content += secondPart;
|
content += secondPart;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,8 @@ void VSnippetList::newSnippet()
|
|||||||
dialog.getTypeInput(),
|
dialog.getTypeInput(),
|
||||||
dialog.getContentInput(),
|
dialog.getContentInput(),
|
||||||
dialog.getCursorMarkInput(),
|
dialog.getCursorMarkInput(),
|
||||||
dialog.getSelectionMarkInput());
|
dialog.getSelectionMarkInput(),
|
||||||
|
dialog.getShortcutInput());
|
||||||
|
|
||||||
QString errMsg;
|
QString errMsg;
|
||||||
if (!addSnippet(snippet, &errMsg)) {
|
if (!addSnippet(snippet, &errMsg)) {
|
||||||
@ -215,8 +216,9 @@ void VSnippetList::deleteSelectedItems()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto const & item : selectedItems) {
|
for (auto const & item : selectedItems) {
|
||||||
items.push_back(ConfirmItemInfo(item->text(),
|
QString name = item->data(Qt::UserRole).toString();
|
||||||
item->text(),
|
items.push_back(ConfirmItemInfo(name,
|
||||||
|
name,
|
||||||
"",
|
"",
|
||||||
NULL));
|
NULL));
|
||||||
}
|
}
|
||||||
@ -377,7 +379,10 @@ void VSnippetList::updateContent()
|
|||||||
|
|
||||||
for (int i = 0; i < m_snippets.size(); ++i) {
|
for (int i = 0; i < m_snippets.size(); ++i) {
|
||||||
const VSnippet &snip = m_snippets[i];
|
const VSnippet &snip = m_snippets[i];
|
||||||
QListWidgetItem *item = new QListWidgetItem(snip.getName());
|
QString text = QString("%1%2").arg(snip.getName())
|
||||||
|
.arg(snip.getShortcut().isNull()
|
||||||
|
? "" : QString(" [%1]").arg(snip.getShortcut()));
|
||||||
|
QListWidgetItem *item = new QListWidgetItem(text);
|
||||||
item->setToolTip(snip.getName());
|
item->setToolTip(snip.getName());
|
||||||
item->setData(Qt::UserRole, snip.getName());
|
item->setData(Qt::UserRole, snip.getName());
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@ class VSnippetList : public QWidget, public VNavigationMode
|
|||||||
public:
|
public:
|
||||||
explicit VSnippetList(QWidget *p_parent = nullptr);
|
explicit VSnippetList(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
const QVector<VSnippet> &getSnippets() const;
|
||||||
|
|
||||||
|
const VSnippet *getSnippet(const QString &p_name) const;
|
||||||
|
|
||||||
// Implementations for VNavigationMode.
|
// Implementations for VNavigationMode.
|
||||||
void showNavigation() Q_DECL_OVERRIDE;
|
void showNavigation() Q_DECL_OVERRIDE;
|
||||||
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
||||||
@ -98,4 +102,19 @@ private:
|
|||||||
static const QString c_infoShortcutSequence;
|
static const QString c_infoShortcutSequence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline const QVector<VSnippet> &VSnippetList::getSnippets() const
|
||||||
|
{
|
||||||
|
return m_snippets;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const VSnippet *VSnippetList::getSnippet(const QString &p_name) const
|
||||||
|
{
|
||||||
|
for (auto const & snip : m_snippets) {
|
||||||
|
if (snip.getName() == p_name) {
|
||||||
|
return &snip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif // VSNIPPETLIST_H
|
#endif // VSNIPPETLIST_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user