WingTool/dialog/centerwindow.cpp

1278 lines
40 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "centerwindow.h"
#include "rundialog.h"
#include "shortcuteditdialog.h"
#include "tooleditdialog.h"
#include "toolswapdialog.h"
#include <DButtonBox>
#include <DFileDialog>
#include <DLabel>
#include <DMessageBox>
#include <DMessageManager>
#include <DNotifySender>
#include <DTextBrowser>
#include <DTitlebar>
#include <DWidgetUtil>
#include <QButtonGroup>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QMimeDatabase>
#include <QProcess>
#include <QScrollArea>
#include <QTableWidgetItem>
#include <QVBoxLayout>
#include <QVector>
DWIDGET_USE_NAMESPACE
CenterWindow::CenterWindow(DMainWindow *parent) : DMainWindow(parent) {
QIcon picon = ProgramIcon;
setWindowTitle(tr("CenterWindow"));
setMinimumSize(700, 500);
setWindowIcon(picon);
auto title = titlebar();
title->setTitle(tr("CenterWindow"));
title->setIcon(picon);
tabs = new DTabWidget(this);
setCentralWidget(tabs);
// General
auto w = new QWidget(this);
auto scview = new QScrollArea;
scview->setWidgetResizable(true);
scview->setWidget(w);
auto vlayout = new QVBoxLayout(w);
vlayout->setMargin(20);
auto l = new DLabel(tr("Common"), this);
auto font = this->font();
font.setUnderline(true);
font.setBold(true);
font.setItalic(true);
l->setFont(font);
vlayout->addWidget(l);
vlayout->addSpacing(5);
auto gw = new QWidget(w);
vlayout->addWidget(gw);
auto hlayout = new QHBoxLayout(gw);
vlayout->addLayout(hlayout);
cbToolWin = new DCheckBox(tr("EnabledToolWin"), this);
hlayout->addWidget(cbToolWin);
cbWinTool = new DCheckBox(tr("EnabledWinTool"), this);
hlayout->addWidget(cbWinTool);
gw = new QWidget(w);
vlayout->addWidget(gw);
hlayout = new QHBoxLayout(gw);
hlayout->addWidget(new DLabel(tr("ToolWinGridSize"), this));
hlayout->addSpacing(5);
sbGridsize = new DSpinBox(w);
sbGridsize->setRange(30, 60);
sbGridsize->setValue(40); // 默认 40 先
hlayout->addWidget(sbGridsize, 1);
vlayout->addSpacing(10);
l = new DLabel(tr("Shortcut"), this);
l->setFont(font);
vlayout->addWidget(l);
vlayout->addSpacing(5);
gw = new QWidget(w);
vlayout->addWidget(gw);
auto flayout = new QFormLayout(gw);
kseqRun = new DKeySequenceEdit(gw);
flayout->addRow(tr("RunWin:"), kseqRun);
kseqTool = new DKeySequenceEdit(gw);
flayout->addRow(tr("ToolBox:"), kseqTool);
hlayout = new QHBoxLayout(gw);
cbMod = new DComboBox(gw);
cbMod->addItems({"Ctrl", "Shift", "Alt", "Super"});
cbMod->setCurrentIndex(0);
hlayout->addWidget(cbMod);
cbMouseBtn = new DComboBox(gw);
cbMouseBtn->addItems(
{tr("Left"), tr("Right"), tr("Middle"), tr("XButton1"), tr("XButton2")});
cbMouseBtn->setCurrentIndex(2);
hlayout->addWidget(cbMouseBtn);
flayout->addRow(tr("ToolWin:"), hlayout);
vlayout->addSpacing(10);
l = new DLabel(tr("Config"), this);
l->setFont(font);
vlayout->addWidget(l);
vlayout->addSpacing(5);
auto group = new DButtonBox(this);
QList<DButtonBoxButton *> blist;
auto b = new DButtonBoxButton(tr("Export"), this);
connect(b, &DButtonBoxButton::clicked, this,
[=] { this->on_exportSettings(); });
blist.append(b);
b = new DButtonBoxButton(tr("Import"), this);
connect(b, &DButtonBoxButton::clicked, this,
[=] { this->on_importSettings(); });
blist.append(b);
b = new DButtonBoxButton(tr("Save"), this);
connect(b, &DButtonBoxButton::clicked, this, [=] { sm->saveSettings(); });
blist.append(b);
b = new DButtonBoxButton(tr("Reset"), this);
connect(b, &DButtonBoxButton::clicked, this,
[=] { this->on_resetSettings(); });
blist.append(b);
group->setButtonList(blist, false);
vlayout->addWidget(group);
vlayout->addSpacing(10);
l = new DLabel(tr("Log"), this);
l->setFont(font);
vlayout->addWidget(l);
vlayout->addSpacing(5);
auto btnlog = new DPushButton(tr("OpenLog"), w);
connect(btnlog, &DPushButton::clicked, this, [=] {
QDesktopServices::openUrl(QUrl(DLogManager::getlogFilePath()));
});
vlayout->addWidget(btnlog);
vlayout->addSpacing(10);
l = new DLabel(tr("Software"), this);
l->setFont(font);
vlayout->addWidget(l);
vlayout->addSpacing(5);
vlayout->addWidget(new DLabel(QString(tr("%1 , Ver %2 , by WingSummer."))
.arg(qApp->applicationName())
.arg(qApp->applicationVersion()),
this));
vlayout->addStretch();
tabs->addTab(scview, tr("General"));
// Hotkeys
w = new QWidget(this);
vlayout = new QVBoxLayout(w);
group = new DButtonBox(this);
vlayout->setMargin(20);
blist.clear(); // 征用
b = new DButtonBoxButton(tr("Add"), this);
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_addHotkey);
blist.append(b);
b = new DButtonBoxButton(tr("Remove"), this);
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_removeHotkey);
blist.append(b);
b = new DButtonBoxButton(tr("Edit"), this);
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_editHotkey);
blist.append(b);
b = new DButtonBoxButton(tr("Clear"), this);
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_clearHotkey);
blist.append(b);
group->setButtonList(blist, false);
vlayout->addWidget(group, Qt::AlignTop);
vlayout->addSpacing(10);
tbhotkeys = new DTableWidget(this);
tbhotkeys->setEditTriggers(DTableWidget::EditTrigger::NoEditTriggers);
tbhotkeys->setSelectionBehavior(QAbstractItemView::SelectRows);
tbhotkeys->setSelectionMode(QAbstractItemView::ExtendedSelection);
tbhotkeys->setColumnCount(4);
tbhotkeys->setHorizontalHeaderLabels(
{tr("Enable"), tr("HotKey"), tr("Exec"), tr("Params")});
tbhotkeys->setCornerButtonEnabled(true);
tbhotkeys->horizontalHeader()->setStretchLastSection(true);
tbhotkeys->setFocusPolicy(Qt::StrongFocus);
auto *menu = new DMenu(tbhotkeys);
QAction *a;
#define AddMenuAction(title, slot) \
a = new QAction(title, menu); \
connect(a, &QAction::triggered, this, slot); \
menu->addAction(a);
AddMenuAction(tr("Enable"), [=] { this->enableSelectedHotkeys(true); });
hkcmenu.append(a);
AddMenuAction(tr("Disable"), [=] { this->enableSelectedHotkeys(false); });
hkcmenu.append(a);
menu->addSeparator();
AddMenuAction(tr("Add"), &CenterWindow::on_addHotkey);
AddMenuAction(tr("Edit"), &CenterWindow::on_editHotkey);
hkcmenu.append(a);
AddMenuAction(tr("Remove"), &CenterWindow::on_removeHotkey);
hkcmenu.append(a);
AddMenuAction(tr("Clear"), &CenterWindow::on_clearHotkey);
tbhotkeys->setContextMenuPolicy(Qt::CustomContextMenu);
connect(tbhotkeys, &DTabWidget::customContextMenuRequested, this, [=] {
auto flag = tbhotkeys->selectedItems().count() > 0;
for (auto item : hkcmenu) {
item->setEnabled(flag);
}
menu->popup(QCursor::pos());
});
connect(tbhotkeys, &DTableWidget::cellClicked, this, [=](int row, int col) {
if (col)
return;
if (row < 0 || row >= scinfos.count())
return;
auto b = tbhotkeys->item(row, 0)->checkState() == Qt::Checked;
auto hk = hotkeys[row];
scinfos[hk].enabled = b;
manager->enableHotKey(hk, b);
});
connect(tbhotkeys, &DTableWidget::cellDoubleClicked, this,
[=](int row, int) { this->editTask(row); });
vlayout->addWidget(tbhotkeys);
tabs->addTab(w, tr("Hotkeys"));
// ToolBox
w = new QWidget(this);
// 左侧
auto tlayout = new QHBoxLayout(w);
auto tvlayout = new QVBoxLayout;
auto gridsize = 40; // 默认 40 先
gw = new QWidget(w);
delete gw->layout();
auto mlayout = new QGridLayout;
gw->setLayout(mlayout);
mlayout->setSpacing(1);
auto btngs = new QButtonGroup(w);
btngs->setExclusive(true); // 设置按钮选中互斥
for (int i = 0; i < 9; i++) {
auto lbl = new DIconButton(this);
lbl->setFixedSize(gridsize - 2, gridsize - 2);
lbl->setIconSize(QSize(gridsize / 2, gridsize / 2));
lbl->setCheckable(true);
auto in = std::div(i, 3);
mlayout->addWidget(lbl, in.quot, in.rem, Qt::AlignCenter);
lbls[i] = lbl;
btngs->addButton(lbl);
connect(lbl, &DIconButton::toggled, this, [=](bool v) {
if (v) {
auto info = toolinfos[i];
sellbl = i;
if (info.isPlugin) {
// 这里的含义是是否为 null
if (info.enabled) {
auto pi = info.pluginIndex;
auto plg = plgsys->plugin(pi);
auto e = QMetaEnum::fromType<IWingToolPlg::Catagorys>();
tbtoolinfo->setText(tr("[Plugin]"));
tbtoolinfo->append(QObject::tr("PluginName:") + plg->pluginName());
tbtoolinfo->append(tr("FakeName:") + info.fakename);
tbtoolinfo->append(tr("Service:") + plgsys->pluginServicetrNames(
plg)[info.serviceID]);
tbtoolinfo->append(tr("Params:") + info.params);
auto fw = tbtoolinfo->fontMetrics().horizontalAdvance('=');
tbtoolinfo->append(QString(tbtoolinfo->width() / fw, '='));
tbtoolinfo->append(
QObject::tr("Catagory:") +
QObject::tr(e.valueToKey(int(plg->pluginCatagory()))));
tbtoolinfo->append(QObject::tr("Version:") +
QString::number(plg->pluginVersion()));
tbtoolinfo->append(QObject::tr("Author:") + plg->pluginAuthor());
tbplginfo->append("");
auto fm = tbplginfo->currentCharFormat();
tbplginfo->insertHtml(
QString("<p>%1<a href=\"%2\" title=\"%2\">%2</a></p>")
.arg(QObject::tr("Web:"))
.arg(plg->pluginWebsite()));
tbplginfo->setCurrentCharFormat(fm);
tbtoolinfo->append(QObject::tr("Comment:") + plg->pluginComment());
tbtoolinfo->append(QObject::tr("Provider:") +
plgsys->pluginProvider(plg));
} else {
tbtoolinfo->setText(tr("NoTool"));
}
} else {
if (info.enabled) {
tbtoolinfo->setText(tr("[File]"));
tbtoolinfo->append(tr("FakeName:") + info.fakename);
tbtoolinfo->append(tr("FileName:") + info.process);
tbtoolinfo->append(tr("Params:") + info.params);
} else {
tbtoolinfo->setText(tr("NoTool"));
}
}
}
});
}
auto lbl4 = lbls[4];
lbl4->setIcon(ICONRES("close"));
tvlayout->addWidget(gw, 0, Qt::AlignCenter);
tbtoolinfo = new DTextBrowser(w);
tbtoolinfo->setUndoRedoEnabled(false);
tbtoolinfo->setOpenExternalLinks(true);
tvlayout->addWidget(tbtoolinfo);
group = new DButtonBox(this);
blist.clear(); // 重新征用
b = new DButtonBoxButton(ICONRES2("edit"));
b->setParent(this);
b->setIconSize(QSize(20, 20));
b->setToolTip(tr("Edit"));
connect(b, &DButtonBoxButton::clicked, this, [=] {
ToolEditDialog d(toolinfos[sellbl]);
if (d.exec()) {
auto res = d.getResult();
this->setToolWinInfo(sellbl, res);
sm->setModified();
emit lbls[sellbl]->toggled(true);
}
});
blist.append(b);
b = new DButtonBoxButton(ICONRES2("swap"));
b->setParent(this);
b->setIconSize(QSize(20, 20));
b->setToolTip(tr("Swap"));
connect(b, &DButtonBoxButton::clicked, this, [=] {
QVector<QIcon> icons;
for (auto i = 0; i < 9; i++) {
icons.append(lbls[i]->icon());
}
ToolSwapDialog d(icons, this->sellbl);
auto res = d.exec();
if (res >= 0) {
auto tmp = toolinfos[sellbl];
toolinfos[sellbl] = toolinfos[res];
toolinfos[res] = tmp;
auto icon1 = lbls[sellbl]->icon();
auto icon2 = lbls[res]->icon();
lbls[sellbl]->setIcon(icon2);
lbls[res]->setIcon(icon1);
manager->setToolIcon(sellbl, icon2, toolinfos[sellbl].fakename);
manager->setToolIcon(res, icon1, toolinfos[res].fakename);
lbls[res]->setChecked(true);
sm->setModified();
}
});
blist.append(b);
b = new DButtonBoxButton(ICONRES2("del"));
b->setParent(this);
b->setIconSize(QSize(20, 20));
b->setToolTip(tr("Delete"));
connect(b, &DButtonBoxButton::clicked, this, [=] {
toolinfos[sellbl] = ToolStructInfo();
auto ilbl = lbls[sellbl];
ilbl->setIcon(QIcon());
manager->setToolIcon(sellbl, QIcon(), "");
sm->setModified();
emit ilbl->toggled(true);
});
blist.append(b);
group->setButtonList(blist, false);
tvlayout->addWidget(group);
tlayout->addLayout(tvlayout);
// 右侧
tvlayout = new QVBoxLayout;
group = new DButtonBox(this);
// 再来征用一次
blist.clear();
b = new DButtonBoxButton(ICONRES2("add"));
b->setIconSize(QSize(20, 20));
b->setParent(this);
b->setToolTip(tr("Add"));
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_addWinTool);
blist.append(b);
b = new DButtonBoxButton(ICONRES2("del"));
b->setIconSize(QSize(20, 20));
b->setParent(this);
b->setToolTip(tr("Remove"));
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_removeWinTool);
blist.append(b);
b = new DButtonBoxButton(ICONRES2("edit"));
b->setIconSize(QSize(20, 20));
b->setParent(this);
b->setToolTip(tr("Edit"));
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_editWinTool);
blist.append(b);
b = new DButtonBoxButton(ICONRES2("up"));
b->setIconSize(QSize(20, 20));
b->setParent(this);
b->setToolTip(tr("Up"));
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_upWinTool);
blist.append(b);
b = new DButtonBoxButton(ICONRES2("down"));
b->setIconSize(QSize(20, 20));
b->setParent(this);
b->setToolTip(tr("Down"));
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_downWinTool);
blist.append(b);
b = new DButtonBoxButton(ICONRES2("clear"));
b->setIconSize(QSize(20, 20));
b->setParent(this);
b->setToolTip(tr("Clear"));
connect(b, &DButtonBoxButton::clicked, this, &CenterWindow::on_clearWinTool);
blist.append(b);
group->setButtonList(blist, false);
tvlayout->addWidget(group);
lstoolwin = new DListWidget(w);
menu = new DMenu(lstoolwin);
AddMenuAction(tr("Add"), &CenterWindow::on_addWinTool);
AddMenuAction(tr("Edit"), &CenterWindow::on_editWinTool);
lscmenu.append(a);
AddMenuAction(tr("Remove"), &CenterWindow::on_removeWinTool);
lscmenu.append(a);
AddMenuAction(tr("Clear"), &CenterWindow::on_clearWinTool);
menu->addSeparator();
AddMenuAction(tr("Up"), &CenterWindow::on_upWinTool);
lscmenu.append(a);
AddMenuAction(tr("Down"), &CenterWindow::on_downWinTool);
lscmenu.append(a);
AddMenuAction(tr("TopMost"), [=] {
if (lstoolwin->count() == 1)
return;
auto sels = lstoolwin->selectionModel()->selectedRows();
if (sels.isEmpty())
return;
QVector<int> nums;
for (auto &item : sels) {
nums.append(item.row());
}
std::sort(nums.begin(), nums.end());
// 过滤掉不需移动的选项
int i = 0;
auto len = nums.count();
for (; i < len; i++) {
if (nums[i] != i)
break;
}
// 下面就开始乾坤大挪移
for (auto p = nums.rbegin(); p != nums.rend() - i; p++) {
auto pi = *p;
wintoolinfos.move(pi, i);
auto item = lstoolwin->takeItem(pi);
lstoolwin->insertItem(i, item);
wintool.mvItem(pi, i);
}
sm->setModified();
});
lscmenu.append(a);
AddMenuAction(tr("DownMost"), [=] {
if (lstoolwin->count() == 1)
return;
auto sels = lstoolwin->selectionModel()->selectedRows();
if (sels.isEmpty())
return;
QVector<int> nums;
for (auto &item : sels) {
nums.append(item.row());
}
std::sort(nums.begin(), nums.end(), std::greater<int>());
// 过滤掉不需移动的选项
int i = 0;
auto len = nums.count();
if (nums.first() == lstoolwin->count() - 1) {
i++;
int pi = nums.first();
for (; i < len; i++) {
pi--;
if (nums[i] != pi)
break;
}
}
// 下面就开始乾坤大挪移
for (auto p = nums.rbegin(); p != nums.rend() - i; p++) {
auto pi = *p;
wintoolinfos.move(pi, i);
auto item = lstoolwin->takeItem(pi);
lstoolwin->insertItem(i, item);
wintool.mvItem(pi, i);
}
sm->setModified();
});
lscmenu.append(a);
lstoolwin->setContextMenuPolicy(Qt::CustomContextMenu);
lstoolwin->setSelectionMode(QListWidget::SelectionMode::ExtendedSelection);
lstoolwin->setDragDropMode(QListWidget::DragDropMode::NoDragDrop);
connect(lstoolwin, &DListWidget::customContextMenuRequested, this, [=] {
auto flag = lstoolwin->selectedItems().count() > 0;
for (auto item : lscmenu) {
item->setEnabled(flag);
}
menu->popup(QCursor::pos());
});
tvlayout->addWidget(lstoolwin);
tlayout->addLayout(tvlayout);
tabs->addTab(w, tr("ToolBox"));
// Plugins
w = new QWidget(this);
auto playout = new QHBoxLayout(w);
auto pvlayout = new QVBoxLayout;
lwplgs = new DListWidget(w);
playout->addWidget(lwplgs);
playout->addLayout(pvlayout);
tbplginfo = new DTextBrowser(w);
tbplginfo->setUndoRedoEnabled(false);
tbplginfo->setText(tr("No selected plugin."));
tbplginfo->setLineWrapMode(DTextBrowser::LineWrapMode::NoWrap);
tbplginfo->setOpenExternalLinks(true);
pvlayout->addWidget(tbplginfo);
auto btnplgset = new DPushButton(tr("PluginCenter"), w);
connect(btnplgset, &DPushButton::clicked, this, [=] {
auto plg = plgsys->plugin(lwplgs->currentRow());
plg->onPluginCenter();
});
btnplgset->setEnabled(false);
pvlayout->addWidget(btnplgset);
connect(lwplgs, &DListWidget::itemSelectionChanged, this, [=] {
if (lwplgs->currentRow() < 0) {
tbplginfo->setText(tr("No selected plugin."));
btnplgset->setEnabled(false);
return;
}
tbplginfo->clear();
btnplgset->setEnabled(true);
auto plg = plgsys->plugin(lwplgs->currentRow());
tbplginfo->append(tr("Name:") + plg->pluginName());
auto e = QMetaEnum::fromType<IWingToolPlg::Catagorys>();
tbplginfo->append(QObject::tr("Catagory:") +
QObject::tr(e.valueToKey(int(plg->pluginCatagory()))));
tbplginfo->append(QObject::tr("Version:") +
QString::number(plg->pluginVersion()));
tbplginfo->append(QObject::tr("Author:") + plg->pluginAuthor());
tbplginfo->append("");
auto fm = tbplginfo->currentCharFormat();
tbplginfo->insertHtml(QString("<p>%1<a href=\"%2\" title=\"%2\">%2</a></p>")
.arg(QObject::tr("Web:"))
.arg(plg->pluginWebsite()));
tbplginfo->setCurrentCharFormat(fm);
tbplginfo->append(QObject::tr("Comment:") + plg->pluginComment());
tbplginfo->append(QObject::tr("Provider:") + plgsys->pluginProvider(plg));
tbplginfo->append(QObject::tr("Services:"));
auto &srvtr = plgsys->pluginServicetrNames(plg);
auto &srv = plgsys->pluginServiceNames(plg);
auto len = srv.count();
for (auto i = 0; i < len; i++) {
tbplginfo->append(
QString("\t%1 : %2 ( %3 )").arg(i + 1).arg(srvtr[i]).arg(srv[i]));
}
tbplginfo->append(tr("RegisteredHotkey:"));
for (auto &item : plgsys->pluginRegisteredHotkey(plg)) {
tbplginfo->append(QString("\t%1").arg(item.toString()));
}
});
tabs->addTab(w, tr("Plugins"));
// AboutAuthor
w = new QWidget(this);
auto alayout = new QVBoxLayout(w);
l = new DLabel(this);
l->setFixedSize(100, 100);
l->setScaledContents(true);
l->setPixmap(QPixmap(":/images/author.jpg"));
alayout->addWidget(l);
alayout->addSpacing(10);
alayout->addWidget(l, 0, Qt::AlignCenter);
auto tb = new DTextBrowser(this);
tb->setSearchPaths(QStringList({":/", ":/images"}));
tb->setSource(QUrl("README.md"), QTextDocument::MarkdownResource);
tb->setOpenExternalLinks(true);
alayout->addWidget(tb);
tabs->addTab(w, tr("About"));
// Sponsor
w = new QWidget(this);
auto slayout = new QVBoxLayout(w);
slayout->addWidget(new DLabel(tr("ThanksForSponsor"), this), 0,
Qt::AlignCenter);
slayout->addSpacing(5);
l = new DLabel(this);
l->setPixmap(QPixmap(":/sponsor.png"));
slayout->addWidget(l, 0, Qt::AlignCenter);
tabs->addTab(w, tr("Sponsor"));
}
void CenterWindow::show(CenterWindow::TabPage index) {
auto i = int(index);
if (i >= 0)
tabs->setCurrentIndex(i);
DMainWindow::show();
}
bool CenterWindow::runTask(ToolStructInfo record) {
if (!record.enabled)
return true;
if (record.isPlugin) {
auto params = Utilities::parseCmdParams(record.params);
QVector<QVariant> ps;
for (auto &item : params) {
ps.append(item);
}
plgsys->pluginCall(record.provider, record.serviceID + 1, ps);
return true;
}
QFileInfo info(record.process);
auto absp = info.absoluteFilePath();
if (info.isExecutable()) {
if (!pstart.startDetached(absp, Utilities::parseCmdParams(record.params))) {
DMessageBox::critical(this, tr("runErr"), pstart.errorString());
return false;
}
} else {
if (record.params.count()) {
auto params = Utilities::parseCmdParams(record.params);
params.prepend("-c");
QString inter;
if (QFile::exists("/usr/bin/bash")) {
inter = "/usr/bin/bash";
} else {
if (QFile::exists("/bin/sh")) {
inter = "/bin/sh";
}
}
if (inter.isEmpty() || !pstart.startDetached(inter, params)) {
DMessageBox::critical(this, tr("runErr"), pstart.errorString());
return false;
}
} else {
if (!QDesktopServices::openUrl(QUrl("file://" + absp))) {
DMessageBox::critical(this, tr("err"), tr("openErr"));
return false;
}
}
}
return true;
}
void CenterWindow::editTask(int index) {
if (index < 0 || index >= scinfos.count())
return;
auto hk = hotkeys[index];
auto &task = scinfos[hk];
ShortCutEditDialog d(task);
if (d.exec()) {
auto res = d.getResult();
auto wt = new QTableWidgetItem;
wt->setCheckState(res.enabled ? Qt::Checked : Qt::Unchecked);
tbhotkeys->setItem(index, 0, wt);
tbhotkeys->setItem(index, 1, new QTableWidgetItem(res.seq.toString()));
auto plg = plgsys->plugin(res.pluginIndex);
auto &srvs = plgsys->pluginServicetrNames(plg);
wt = new QTableWidgetItem(Utilities::getProgramName(srvs, res));
wt->setToolTip(Utilities::getToolTipContent(srvs, res));
tbhotkeys->setItem(index, 2, wt);
wt = new QTableWidgetItem(res.params);
wt->setToolTip(res.params);
tbhotkeys->setItem(index, 3, wt);
task = res;
manager->editHotkey(hk, res.seq);
sm->setModified();
}
}
void CenterWindow::on_editHotkey() { this->editTask(tbhotkeys->currentRow()); }
void CenterWindow::on_removeHotkey() {
auto selrows = tbhotkeys->selectionModel()->selectedRows();
if (!selrows.length())
return;
if (selrows.length() > 1) {
QVector<int> nums;
for (auto &item : selrows)
nums.append(item.row());
std::sort(nums.begin(), nums.end(), std::greater<int>());
for (auto item : nums) {
auto hk = hotkeys.takeAt(item);
scinfos.remove(hk);
manager->unregisterHotkey(hk);
tbhotkeys->removeRow(item);
}
} else {
auto row = tbhotkeys->currentRow();
auto hk = hotkeys.takeAt(row);
scinfos.remove(hk);
manager->unregisterHotkey(hk);
tbhotkeys->removeRow(row);
}
sm->setModified();
}
void CenterWindow::on_clearHotkey() {
scinfos.clear();
hotkeys.clear();
manager->clearHotkey();
tbhotkeys->setRowCount(0);
sm->setModified();
DMessageManager::instance()->sendMessage(this, ProgramIcon,
tr("ClearSuccess"));
}
void CenterWindow::on_addHotkey() {
ShortCutEditDialog d;
if (d.exec()) {
auto res = d.getResult();
auto hk = manager->registerHotkey(res.seq, true);
if (hk == nullptr) {
DMessageManager::instance()->sendMessage(this, ProgramIcon,
tr("HotkeyRegisterFail"));
return;
}
scinfos.insert(hk, res);
hotkeys.append(hk);
auto index = tbhotkeys->rowCount();
tbhotkeys->setRowCount(index + 1);
auto wt = new QTableWidgetItem;
wt->setCheckState(res.enabled ? Qt::Checked : Qt::Unchecked);
tbhotkeys->setItem(index, 0, wt);
tbhotkeys->setItem(index, 1, new QTableWidgetItem(res.seq.toString()));
auto plg = plgsys->plugin(res.pluginIndex);
auto &srvs = plgsys->pluginServicetrNames(plg);
wt = new QTableWidgetItem(Utilities::getProgramName(srvs, res));
wt->setToolTip(Utilities::getToolTipContent(srvs, res));
tbhotkeys->setItem(index, 2, wt);
wt = new QTableWidgetItem(res.params);
wt->setToolTip(res.params);
tbhotkeys->setItem(index, 3, wt);
sm->setModified();
}
}
void CenterWindow::enableSelectedHotkeys(bool enable) {
auto selrows = tbhotkeys->selectionModel()->selectedRows();
for (auto &item : selrows) {
manager->enableHotKey(hotkeys[item.row()], enable);
sm->setModified();
}
}
void CenterWindow::on_editWinTool() {
auto sels = lstoolwin->selectedItems().count();
if (sels != 1) {
DMessageManager::instance()->sendMessage(this, ProgramIcon,
tr("PleaseSelectOne"));
return;
}
auto index = lstoolwin->currentRow();
ToolEditDialog d(wintoolinfos[index]);
if (d.exec()) {
auto res = d.getResult();
wintoolinfos[index] = res;
auto item = lstoolwin->item(index);
auto plg = plgsys->plugin(res.pluginIndex);
item->setIcon(Utilities::trimIconFromInfo(plg, res));
auto &srvs = plgsys->pluginServicetrNames(plg);
item->setText(Utilities::getProgramName(srvs, res));
item->setToolTip(Utilities::getToolTipContent(srvs, res));
sm->setModified();
}
}
void CenterWindow::on_removeWinTool() {
auto sels = lstoolwin->selectionModel()->selectedRows();
if (sels.isEmpty())
return;
QVector<int> nums;
for (auto &item : sels) {
nums.append(item.row());
}
std::sort(nums.begin(), nums.end(), std::greater<int>());
for (auto index : nums) {
wintoolinfos.removeAt(index);
auto item = lstoolwin->takeItem(index);
delete item;
wintool.rmItem(index);
}
sm->setModified();
}
void CenterWindow::on_clearWinTool() {
lstoolwin->clear();
wintoolinfos.clear();
wintool.rmItem(-1); // 清空数据
sm->setModified();
DMessageManager::instance()->sendMessage(this, ProgramIcon,
tr("ClearSuccess"));
}
void CenterWindow::on_addWinTool() {
ToolEditDialog d;
if (d.exec()) {
auto res = d.getResult();
auto index = lstoolwin->currentRow();
if (index < 0) {
wintoolinfos.append(res);
auto plg = plgsys->plugin(res.pluginIndex);
auto &srvs = plgsys->pluginServicetrNames(plg);
auto item = new QListWidgetItem(Utilities::trimIconFromInfo(plg, res),
Utilities::getProgramName(srvs, res));
item->setToolTip(Utilities::getToolTipContent(srvs, res));
lstoolwin->addItem(item);
wintool.addItem(res, res.isPlugin ? srvs[res.serviceID] : QString());
} else {
wintoolinfos.insert(index + 1, res);
auto plg = plgsys->plugin(res.pluginIndex);
auto &srvs = plgsys->pluginServiceNames(plg);
auto item = new QListWidgetItem(Utilities::trimIconFromInfo(plg, res),
Utilities::getProgramName(srvs, res));
item->setToolTip(Utilities::getToolTipContent(srvs, res));
lstoolwin->insertItem(index + 1, item);
wintool.addItem(res, res.isPlugin ? srvs[res.serviceID] : QString(),
index + 1);
}
sm->setModified();
}
}
void CenterWindow::on_upWinTool() {
if (lstoolwin->count() == 1)
return;
auto sels = lstoolwin->selectionModel()->selectedRows();
if (sels.isEmpty())
return;
QVector<int> nums;
for (auto &item : sels) {
nums.append(item.row());
}
std::sort(nums.begin(), nums.end());
// 过滤掉不需移动的选项
int i = 0;
auto len = nums.count();
for (; i < len; i++) {
if (nums[i] != i)
break;
}
// 下面就开始乾坤大挪移
for (; i < len; i++) {
auto p = nums[i];
wintoolinfos.move(p, p - 1);
auto item = lstoolwin->takeItem(p);
lstoolwin->insertItem(p - 1, item);
wintool.mvItem(p, p - 1);
}
sm->setModified();
}
void CenterWindow::on_downWinTool() {
if (lstoolwin->count() == 1)
return;
auto sels = lstoolwin->selectionModel()->selectedRows();
if (sels.isEmpty())
return;
QVector<int> nums;
for (auto &item : sels) {
nums.append(item.row());
}
std::sort(nums.begin(), nums.end(), std::greater<int>());
// 过滤掉不需移动的选项
int i = 0;
auto len = nums.count();
if (nums.first() == lstoolwin->count() - 1) {
i++;
int pi = nums.first();
for (; i < len; i++) {
pi--;
if (nums[i] != pi)
break;
}
}
// 下面就开始乾坤大挪移
for (; i < len; i++) {
auto p = nums[i];
wintoolinfos.move(p, p + 1);
auto item = lstoolwin->takeItem(p);
lstoolwin->insertItem(p + 1, item);
wintool.mvItem(p, p + 1);
}
sm->setModified();
}
void CenterWindow::on_exportSettings() {
auto path = DFileDialog::getSaveFileName(this, tr(""), QString(),
tr("Config (*.wtcfg)"));
if (path.isEmpty())
return;
if (sm->exportSettings(path)) {
DMessageManager::instance()->sendMessage(this, ProgramIcon,
tr("ExportSuccess"));
}
}
void CenterWindow::on_importSettings() {
auto path = DFileDialog::getOpenFileName(this, tr(""), QString(),
tr("Config (*.wtcfg)"));
if (path.isEmpty())
return;
if (sm->loadSettings(path)) {
DMessageManager::instance()->sendMessage(this, ProgramIcon,
tr("ImportSuccess"));
}
}
void CenterWindow::on_resetSettings() {
if (DMessageBox::question(this, tr("Warn"), tr("ResetSettings")) ==
DMessageBox::No)
return;
sm->resetSettings();
sm->saveSettings();
}
void CenterWindow::on_runplg() {
RunDialog d;
if (!d.exec()) {
DUtil::DNotifySender(tr("[%1] RunErr").arg(qApp->applicationName()))
.appIcon("dialog-error")
.appName(qApp->applicationName())
.call();
}
}
void CenterWindow::addHotKeyInfo(ToolStructInfo &info) {
// 添加 UI 项目
auto index = tbhotkeys->rowCount();
tbhotkeys->setRowCount(index + 1);
auto wt = new QTableWidgetItem;
wt->setCheckState(info.enabled ? Qt::Checked : Qt::Unchecked);
tbhotkeys->setItem(index, 0, wt);
tbhotkeys->setItem(index, 1, new QTableWidgetItem(info.seq.toString()));
auto plg = plgsys->plugin(info.pluginIndex);
auto &srvs = plgsys->pluginServicetrNames(plg);
wt = new QTableWidgetItem(Utilities::getProgramName(srvs, info));
wt->setToolTip(Utilities::getToolTipContent(srvs, info));
tbhotkeys->setItem(index, 2, wt);
wt = new QTableWidgetItem(info.params);
wt->setToolTip(info.params);
tbhotkeys->setItem(index, 3, wt);
// 注册热键
auto hk = manager->registerHotkey(info.seq, true);
hotkeys << hk;
scinfos.insert(hk, info);
// 修正热键状态
manager->enableHotKey(hk, info.enabled);
}
void CenterWindow::setToolWinInfo(int index, ToolStructInfo &info) {
toolinfos[index] = info;
auto icon =
Utilities::trimIconFromInfo(plgsys->plugin(info.pluginIndex), info);
auto ilbl = lbls[index];
ilbl->setIcon(icon);
manager->setToolIcon(index, icon, info.fakename);
}
void CenterWindow::setToolFinished() { lbls[0]->setChecked(true); }
void CenterWindow::addWinToolInfo(ToolStructInfo &info) {
wintoolinfos.append(info);
auto plg = plgsys->plugin(info.pluginIndex);
auto &srvs = plgsys->pluginServicetrNames(plg);
auto item = new QListWidgetItem(Utilities::trimIconFromInfo(plg, info),
Utilities::getProgramName(srvs, info));
item->setToolTip(Utilities::getToolTipContent(srvs, info));
lstoolwin->addItem(item);
wintool.addItem(info, info.isPlugin ? srvs[info.serviceID] : QString());
}
void CenterWindow::initGeneralSettings() {
sm = SettingManager::instance();
// 注册有关设置更改相关信号
cbWinTool->setChecked(sm->wintoolEnabled());
cbToolWin->setChecked(sm->toolwinEnabled());
connect(cbToolWin, &DCheckBox::toggled, this,
[=](bool v) { sm->setToolwinEnabled(v); });
connect(cbWinTool, &DCheckBox::toggled, this, [=](bool v) {
sm->setWintoolEnabled(v);
hkwintool->setRegistered(v);
});
connect(sm, &SettingManager::sigToolGridSizeChanged, this, [=](int v) {
for (auto i = 0; i < 9; i++) {
lbls[i]->setFixedSize(QSize(v, v));
}
});
sm->sigToolGridSizeChanged(sm->toolGridSize());
connect(sbGridsize, QOverload<int>::of(&DSpinBox::valueChanged), sm,
&SettingManager::setToolGridSize);
connect(tabs, &DTabWidget::currentChanged, this, [=] {
sm->saveSettings();
if (tabs->currentIndex() == 2)
lbls[sellbl]->toggled(true);
});
// WinTool 相关
wintool.setModal(true);
connect(&wintool, &ToolBoxWindow::sigRun, this,
[=](int index) { this->runTask(wintoolinfos[index]); });
auto seq = sm->toolBoxHotkey();
kseqTool->setKeySequence(seq);
hkwintool = manager->registerHotkey(seq, false);
hkwintool->disconnect(); // 断开所有自带连接,不能让它走默认处理
connect(hkwintool, &Hotkey::activated, this, [&] {
Dtk::Widget::moveToCenter(&wintool);
wintool.show();
wintool.activateWindow();
wintool.raise();
});
seq = sm->runWinHotkey();
kseqRun->setKeySequence(seq);
hkrunwin = manager->registerHotkey(seq, false);
hkrunwin->disconnect();
connect(hkrunwin, &Hotkey::activated, this, &CenterWindow::on_runplg);
connect(kseqTool, &DKeySequenceEdit::editingFinished, this,
[=](const QKeySequence &keySequence) {
sm->setToolBoxHotkey(keySequence);
});
connect(sm, &SettingManager::sigToolBoxHotkeyChanged, this,
[=](const QKeySequence seq) { hkwintool->setShortcut(seq, true); });
connect(kseqRun, &DKeySequenceEdit::editingFinished, this,
[=](const QKeySequence &keySequence) {
sm->setRunWinHotkey(keySequence);
});
connect(sm, &SettingManager::sigRunWinHotkeyChanged, this,
[=](const QKeySequence seq) { hkrunwin->setShortcut(seq, true); });
connect(sm, &SettingManager::sigToolwinEnabledChanged, this,
[=](bool b) { cbToolWin->setChecked(b); });
connect(sm, &SettingManager::sigWintoolEnabledChanged, this,
[=](bool b) { cbWinTool->setChecked(b); });
connect(sm, &SettingManager::sigToolwinModChanged, this,
[=](const Qt::KeyboardModifier mod) {
switch (mod) {
case Qt::KeyboardModifier::AltModifier:
cbMod->setCurrentIndex(2);
break;
case Qt::KeyboardModifier::MetaModifier:
cbMod->setCurrentIndex(3);
break;
case Qt::KeyboardModifier::ShiftModifier:
cbMod->setCurrentIndex(1);
break;
default:
cbMod->setCurrentIndex(0);
break;
}
});
sm->sigToolwinModChanged(sm->toolwinMod());
connect(sm, &SettingManager::sigToolwinMouseBtnChanged, this,
[=](const Qt::MouseButton btn) {
switch (btn) {
case Qt::MouseButton::RightButton:
cbMouseBtn->setCurrentIndex(1);
break;
case Qt::MouseButton::MidButton:
cbMouseBtn->setCurrentIndex(2);
break;
case Qt::MouseButton::XButton1:
cbMouseBtn->setCurrentIndex(3);
break;
case Qt::MouseButton::XButton2:
cbMouseBtn->setCurrentIndex(4);
break;
default:
cbMouseBtn->setCurrentIndex(0);
break;
}
});
sm->sigToolwinMouseBtnChanged(sm->toolwinMouseBtn());
connect(cbMod, QOverload<int>::of(&DComboBox::currentIndexChanged), this,
[=](int index) {
Qt::KeyboardModifier mod = Qt::KeyboardModifier::NoModifier;
switch (index) {
case 0:
mod = Qt::KeyboardModifier::ControlModifier;
break;
case 1:
mod = Qt::KeyboardModifier::ShiftModifier;
break;
case 2:
mod = Qt::KeyboardModifier::AltModifier;
break;
case 3:
mod = Qt::KeyboardModifier::MetaModifier;
break;
}
sm->setToolwinMod(mod);
});
connect(cbMouseBtn, QOverload<int>::of(&DComboBox::currentIndexChanged), this,
[=](int index) {
Qt::MouseButton btn = Qt::MouseButton::NoButton;
switch (index) {
case 0:
btn = Qt::MouseButton::LeftButton;
break;
case 1:
btn = Qt::MouseButton::RightButton;
break;
case 2:
btn = Qt::MouseButton::MidButton;
break;
case 3:
btn = Qt::MouseButton::XButton1;
break;
case 4:
btn = Qt::MouseButton::XButton2;
break;
}
sm->setToolMouseBtn(btn);
});
}
void CenterWindow::initPluginSys() {
plgsys = PluginSystem::instance();
for (auto item : plgsys->plugins()) {
lwplgs->addItem(new QListWidgetItem(Utilities::processPluginIcon(item),
item->pluginName()));
}
}
void CenterWindow::initAppManger() {
manager = AppManager::instance();
//初始化热键事件处理函数
connect(manager, &AppManager::hotkeyTirggered, this,
[=](const Hotkey *hotkey) {
if (hotkey->isHostHotkey()) {
auto &task = scinfos[const_cast<Hotkey *>(hotkey)];
this->runTask(task);
}
});
connect(manager, &AppManager::hotkeyReleased, this, [=](const Hotkey *) {});
connect(manager, &AppManager::hotkeyEnableChanged, this,
[=](bool value, const Hotkey *hotkey) {
if (hotkey->isHostHotkey()) {
tbhotkeys->item(hotkeys.indexOf(const_cast<Hotkey *>(hotkey)), 0)
->setCheckState(value ? Qt::Checked : Qt::Unchecked);
}
});
connect(manager, &AppManager::toolSelTriggered, this,
[=](int index) { this->runTask(toolinfos[index]); });
}
void CenterWindow::getConfig(QDataStream &f) {
QVector<int> plgindices;
// 先保存 Hotkey 的相关信息
f << hotkeys.count(); // 先存一下有几个
for (auto &p : scinfos) {
f << p.enabled << p.isPlugin << p.seq;
if (p.isPlugin) {
f << p.serviceName.toUtf8() << p.provider.toUtf8() << p.params.toUtf8()
<< p.fakename.toUtf8();
} else {
f << p.process.toUtf8() << p.params.toUtf8()
<< p.fakename.toUtf8(); // 如果是打开文件就没这么多事情了
}
}
// 下面继续存储 ToolWin 相关信息
for (auto i = 0; i < 9; i++) {
auto &p = toolinfos[i];
// 对于 ToolWin 来说enabled 是决定性的
// 只有这个标志位有效,这个工具才有意义
// 只存有意义的即可
f << p.enabled;
if (p.enabled) {
f << p.isPlugin;
if (p.isPlugin) {
f << p.serviceName.toUtf8() << p.iconpath.toUtf8()
<< p.provider.toUtf8() << p.params.toUtf8() << p.fakename.toUtf8();
} else {
f << p.process.toUtf8() << p.params.toUtf8() << p.fakename.toUtf8()
<< p.iconpath.toUtf8(); // 如果是打开文件就没这么多事情了
}
}
}
// 下面存取 WinTool 相关信息
f << wintoolinfos.count(); // 先存一下有几个
for (auto &p : wintoolinfos) {
// 对于 WinTool 来说, enabled 就没用了
// 只存储相关基础信息就可以了
f << p.isPlugin;
if (p.isPlugin) {
f << p.serviceName.toUtf8() << p.iconpath.toUtf8() << p.provider.toUtf8()
<< p.params.toUtf8() << p.fakename.toUtf8();
} else {
f << p.process.toUtf8() << p.params.toUtf8() << p.fakename.toUtf8()
<< p.iconpath.toUtf8(); // 如果是打开文件就没这么多事情了
}
}
// 保存完毕,可以返回了
}
void CenterWindow::resetConfig() {
ToolStructInfo toolinfo;
for (auto i = 0; i < 9; i++) {
toolinfos[i] = toolinfo;
QIcon icon;
auto ilbl = lbls[i];
ilbl->setIcon(icon);
manager->setToolIcon(i, icon, toolinfo.fakename);
}
lstoolwin->clear();
wintoolinfos.clear();
wintool.rmItem(-1);
}
void CenterWindow::closeEvent(QCloseEvent *event) {
event->ignore();
hide();
}
void CenterWindow::showEvent(QShowEvent *event) {
Q_UNUSED(event);
sm->saveSettings();
}