mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
256 lines
7.8 KiB
C++
256 lines
7.8 KiB
C++
#include "snippetpanel.h"
|
|
|
|
#include <QVBoxLayout>
|
|
#include <QToolButton>
|
|
#include <QListWidgetItem>
|
|
|
|
#include <utils/widgetutils.h>
|
|
#include <snippet/snippetmgr.h>
|
|
#include <core/vnotex.h>
|
|
#include <core/exception.h>
|
|
#include <core/configmgr.h>
|
|
#include <core/widgetconfig.h>
|
|
|
|
#include "titlebar.h"
|
|
#include "listwidget.h"
|
|
#include "dialogs/newsnippetdialog.h"
|
|
#include "dialogs/snippetpropertiesdialog.h"
|
|
#include "dialogs/deleteconfirmdialog.h"
|
|
#include "mainwindow.h"
|
|
#include "messageboxhelper.h"
|
|
|
|
using namespace vnotex;
|
|
|
|
SnippetPanel::SnippetPanel(QWidget *p_parent)
|
|
: QFrame(p_parent)
|
|
{
|
|
m_builtInSnippetsVisible = ConfigMgr::getInst().getWidgetConfig().isSnippetPanelBuiltInSnippetsVisible();
|
|
setupUI();
|
|
}
|
|
|
|
void SnippetPanel::setupUI()
|
|
{
|
|
auto mainLayout = new QVBoxLayout(this);
|
|
WidgetUtils::setContentsMargins(mainLayout);
|
|
|
|
{
|
|
setupTitleBar(QString(), this);
|
|
mainLayout->addWidget(m_titleBar);
|
|
}
|
|
|
|
m_snippetList = new ListWidget(this);
|
|
m_snippetList->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
m_snippetList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
connect(m_snippetList, &QListWidget::customContextMenuRequested,
|
|
this, &SnippetPanel::handleContextMenuRequested);
|
|
connect(m_snippetList, &QListWidget::itemActivated,
|
|
this, &SnippetPanel::applySnippet);
|
|
mainLayout->addWidget(m_snippetList);
|
|
|
|
setFocusProxy(m_snippetList);
|
|
}
|
|
|
|
void SnippetPanel::initialize()
|
|
{
|
|
updateSnippetList();
|
|
}
|
|
|
|
void SnippetPanel::setupTitleBar(const QString &p_title, QWidget *p_parent)
|
|
{
|
|
m_titleBar = new TitleBar(p_title, true, TitleBar::Action::Menu, p_parent);
|
|
m_titleBar->setActionButtonsAlwaysShown(true);
|
|
|
|
{
|
|
auto newBtn = m_titleBar->addActionButton(QStringLiteral("add.svg"), tr("New Snippet"));
|
|
connect(newBtn, &QToolButton::triggered,
|
|
this, &SnippetPanel::newSnippet);
|
|
}
|
|
|
|
{
|
|
auto openFolderBtn = m_titleBar->addActionButton(QStringLiteral("open_folder.svg"), tr("Open Folder"));
|
|
connect(openFolderBtn, &QToolButton::triggered,
|
|
this, []() {
|
|
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(SnippetMgr::getInst().getSnippetFolder()));
|
|
});
|
|
}
|
|
|
|
auto showAct = m_titleBar->addMenuAction(tr("Show Built-In Snippets"),
|
|
m_titleBar,
|
|
[this](bool p_checked) {
|
|
ConfigMgr::getInst().getWidgetConfig().setSnippetPanelBuiltInSnippetsVisible(p_checked);
|
|
setBuiltInSnippetsVisible(p_checked);
|
|
});
|
|
showAct->setCheckable(true);
|
|
showAct->setChecked(m_builtInSnippetsVisible);
|
|
}
|
|
|
|
void SnippetPanel::newSnippet()
|
|
{
|
|
NewSnippetDialog dialog(VNoteX::getInst().getMainWindow());
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
updateSnippetList();
|
|
}
|
|
}
|
|
|
|
void SnippetPanel::updateItemsCountLabel()
|
|
{
|
|
const auto cnt = m_snippetList->count();
|
|
if (cnt == 0) {
|
|
m_titleBar->setInfoLabel("");
|
|
} else {
|
|
m_titleBar->setInfoLabel(tr("%n Item(s)", "", cnt));
|
|
}
|
|
}
|
|
|
|
void SnippetPanel::updateSnippetList()
|
|
{
|
|
m_snippetList->clear();
|
|
|
|
const auto &snippets = SnippetMgr::getInst().getSnippets();
|
|
for (const auto &snippet : snippets) {
|
|
if (snippet->isReadOnly() && !m_builtInSnippetsVisible) {
|
|
continue;
|
|
}
|
|
|
|
auto item = new QListWidgetItem(m_snippetList);
|
|
QString suffix;
|
|
if (snippet->isReadOnly()) {
|
|
suffix = QLatin1Char('*');
|
|
}
|
|
if (snippet->getShortcut() == Snippet::InvalidShortcut) {
|
|
item->setText(snippet->getName() + suffix);
|
|
} else {
|
|
item->setText(tr("%1%2 [%3]").arg(snippet->getName(), suffix, snippet->getShortcutString()));
|
|
}
|
|
|
|
item->setData(Qt::UserRole, snippet->getName());
|
|
item->setToolTip(snippet->getDescription());
|
|
}
|
|
|
|
updateItemsCountLabel();
|
|
}
|
|
|
|
void SnippetPanel::handleContextMenuRequested(const QPoint &p_pos)
|
|
{
|
|
auto item = m_snippetList->itemAt(p_pos);
|
|
if (!item) {
|
|
return;
|
|
}
|
|
|
|
QMenu menu(this);
|
|
|
|
const int selectedCount = m_snippetList->selectedItems().size();
|
|
if (selectedCount == 1) {
|
|
menu.addAction(tr("&Apply"),
|
|
&menu,
|
|
[this]() {
|
|
applySnippet(m_snippetList->currentItem());
|
|
});
|
|
}
|
|
|
|
menu.addAction(tr("&Delete"),
|
|
this,
|
|
&SnippetPanel::removeSelectedSnippets);
|
|
|
|
if (selectedCount == 1) {
|
|
menu.addAction(tr("&Properties (Rename)"),
|
|
&menu,
|
|
[this]() {
|
|
auto item = m_snippetList->currentItem();
|
|
if (!item) {
|
|
return;
|
|
}
|
|
|
|
auto snippet = SnippetMgr::getInst().find(getSnippetName(item));
|
|
if (!snippet) {
|
|
qWarning() << "failed to find snippet for properties" << getSnippetName(item);
|
|
return;
|
|
}
|
|
|
|
SnippetPropertiesDialog dialog(snippet.data(), VNoteX::getInst().getMainWindow());
|
|
if (dialog.exec()) {
|
|
updateSnippetList();
|
|
}
|
|
});
|
|
}
|
|
|
|
menu.exec(m_snippetList->mapToGlobal(p_pos));
|
|
}
|
|
|
|
QString SnippetPanel::getSnippetName(const QListWidgetItem *p_item)
|
|
{
|
|
return p_item->data(Qt::UserRole).toString();
|
|
}
|
|
|
|
void SnippetPanel::removeSelectedSnippets()
|
|
{
|
|
const auto selectedItems = m_snippetList->selectedItems();
|
|
if (selectedItems.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
QVector<ConfirmItemInfo> items;
|
|
for (const auto &selectedItem : selectedItems) {
|
|
const auto name = getSnippetName(selectedItem);
|
|
items.push_back(ConfirmItemInfo(name,
|
|
name,
|
|
QString(),
|
|
nullptr));
|
|
}
|
|
|
|
DeleteConfirmDialog dialog(tr("Confirm Deletion"),
|
|
tr("Delete these snippets permanently?"),
|
|
tr("Files will be deleted permanently and could not be found even "
|
|
"in operating system's recycle bin."),
|
|
items,
|
|
DeleteConfirmDialog::Flag::None,
|
|
false,
|
|
VNoteX::getInst().getMainWindow());
|
|
|
|
QStringList snippetsToDelete;
|
|
if (dialog.exec()) {
|
|
items = dialog.getConfirmedItems();
|
|
for (const auto &item : items) {
|
|
snippetsToDelete << item.m_name;
|
|
}
|
|
}
|
|
|
|
if (snippetsToDelete.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
for (const auto &snippetName : snippetsToDelete) {
|
|
try {
|
|
SnippetMgr::getInst().removeSnippet(snippetName);
|
|
} catch (Exception &p_e) {
|
|
QString msg = tr("Failed to remove snippet (%1) (%2).").arg(snippetName, p_e.what());
|
|
qCritical() << msg;
|
|
MessageBoxHelper::notify(MessageBoxHelper::Critical, msg, VNoteX::getInst().getMainWindow());
|
|
}
|
|
}
|
|
|
|
updateSnippetList();
|
|
}
|
|
|
|
void SnippetPanel::applySnippet(const QListWidgetItem *p_item)
|
|
{
|
|
if (!p_item) {
|
|
return;
|
|
}
|
|
const auto name = getSnippetName(p_item);
|
|
if (!name.isEmpty()) {
|
|
emit applySnippetRequested(name);
|
|
}
|
|
}
|
|
|
|
void SnippetPanel::setBuiltInSnippetsVisible(bool p_visible)
|
|
{
|
|
if (m_builtInSnippetsVisible == p_visible) {
|
|
return;
|
|
}
|
|
|
|
m_builtInSnippetsVisible = p_visible;
|
|
|
|
updateSnippetList();
|
|
}
|