mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-02-15 11:45:54 +00:00
369 lines
12 KiB
C++
369 lines
12 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2009 Dmitry Suzdalev <dimsuz@gmail.com>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "editactiondialog.h"
|
|
|
|
#include "klipper_debug.h"
|
|
#include <QComboBox>
|
|
#include <QDialogButtonBox>
|
|
#include <QIcon>
|
|
#include <QItemDelegate>
|
|
|
|
#include <KWindowConfig>
|
|
#include <kwindowconfig.h>
|
|
|
|
#include "ui_editactiondialog.h"
|
|
#include "urlgrabber.h"
|
|
|
|
namespace
|
|
{
|
|
static QString output2text(ClipCommand::Output output)
|
|
{
|
|
switch (output) {
|
|
case ClipCommand::IGNORE:
|
|
return QString(i18n("Ignore"));
|
|
case ClipCommand::REPLACE:
|
|
return QString(i18n("Replace Clipboard"));
|
|
case ClipCommand::ADD:
|
|
return QString(i18n("Add to Clipboard"));
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Show dropdown of editing Output part of commands
|
|
*/
|
|
class ActionOutputDelegate : public QItemDelegate
|
|
{
|
|
public:
|
|
ActionOutputDelegate(QObject *parent = nullptr)
|
|
: QItemDelegate(parent)
|
|
{
|
|
}
|
|
|
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/) const override
|
|
{
|
|
QComboBox *editor = new QComboBox(parent);
|
|
editor->setInsertPolicy(QComboBox::NoInsert);
|
|
editor->addItem(output2text(ClipCommand::IGNORE), QVariant::fromValue<ClipCommand::Output>(ClipCommand::IGNORE));
|
|
editor->addItem(output2text(ClipCommand::REPLACE), QVariant::fromValue<ClipCommand::Output>(ClipCommand::REPLACE));
|
|
editor->addItem(output2text(ClipCommand::ADD), QVariant::fromValue<ClipCommand::Output>(ClipCommand::ADD));
|
|
return editor;
|
|
}
|
|
|
|
void setEditorData(QWidget *editor, const QModelIndex &index) const override
|
|
{
|
|
QComboBox *ed = static_cast<QComboBox *>(editor);
|
|
QVariant data(index.model()->data(index, Qt::EditRole));
|
|
ed->setCurrentIndex(static_cast<int>(data.value<ClipCommand::Output>()));
|
|
}
|
|
|
|
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
|
|
{
|
|
QComboBox *ed = static_cast<QComboBox *>(editor);
|
|
model->setData(index, ed->itemData(ed->currentIndex()));
|
|
}
|
|
|
|
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & /*index*/) const override
|
|
{
|
|
editor->setGeometry(option.rect);
|
|
}
|
|
};
|
|
|
|
class ActionDetailModel : public QAbstractTableModel
|
|
{
|
|
public:
|
|
ActionDetailModel(ClipAction *action, QObject *parent = nullptr);
|
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
int columnCount(const QModelIndex &parent) const override;
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
const QList<ClipCommand> &commands() const
|
|
{
|
|
return m_commands;
|
|
}
|
|
void addCommand(const ClipCommand &command);
|
|
void removeCommand(const QModelIndex &index);
|
|
|
|
private:
|
|
enum column_t { COMMAND_COL = 0, OUTPUT_COL = 1, DESCRIPTION_COL = 2 };
|
|
QList<ClipCommand> m_commands;
|
|
QVariant displayData(ClipCommand *command, column_t column) const;
|
|
QVariant editData(ClipCommand *command, column_t column) const;
|
|
QVariant decorationData(ClipCommand *command, column_t column) const;
|
|
void setIconForCommand(ClipCommand &cmd);
|
|
};
|
|
|
|
ActionDetailModel::ActionDetailModel(ClipAction *action, QObject *parent)
|
|
: QAbstractTableModel(parent)
|
|
, m_commands(action->commands())
|
|
{
|
|
}
|
|
|
|
Qt::ItemFlags ActionDetailModel::flags(const QModelIndex & /*index*/) const
|
|
{
|
|
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
|
}
|
|
|
|
void ActionDetailModel::setIconForCommand(ClipCommand &cmd)
|
|
{
|
|
// let's try to update icon of the item according to command
|
|
QString command = cmd.command;
|
|
if (command.contains(QLatin1Char(' '))) {
|
|
// get first word
|
|
command = command.section(QLatin1Char(' '), 0, 0);
|
|
}
|
|
|
|
if (QIcon::hasThemeIcon(command)) {
|
|
cmd.icon = command;
|
|
} else {
|
|
cmd.icon.clear();
|
|
}
|
|
}
|
|
|
|
bool ActionDetailModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
{
|
|
if (role == Qt::EditRole) {
|
|
ClipCommand cmd = m_commands.at(index.row());
|
|
switch (static_cast<column_t>(index.column())) {
|
|
case COMMAND_COL:
|
|
cmd.command = value.toString();
|
|
setIconForCommand(cmd);
|
|
break;
|
|
case OUTPUT_COL:
|
|
cmd.output = value.value<ClipCommand::Output>();
|
|
break;
|
|
case DESCRIPTION_COL:
|
|
cmd.description = value.toString();
|
|
break;
|
|
}
|
|
m_commands.replace(index.row(), cmd);
|
|
Q_EMIT dataChanged(index, index);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int ActionDetailModel::columnCount(const QModelIndex & /*parent*/) const
|
|
{
|
|
return 3;
|
|
}
|
|
|
|
int ActionDetailModel::rowCount(const QModelIndex &) const
|
|
{
|
|
return m_commands.count();
|
|
}
|
|
|
|
QVariant ActionDetailModel::displayData(ClipCommand *command, ActionDetailModel::column_t column) const
|
|
{
|
|
switch (column) {
|
|
case COMMAND_COL:
|
|
return command->command;
|
|
case OUTPUT_COL:
|
|
return output2text(command->output);
|
|
case DESCRIPTION_COL:
|
|
return command->description;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
QVariant ActionDetailModel::decorationData(ClipCommand *command, ActionDetailModel::column_t column) const
|
|
{
|
|
switch (column) {
|
|
case COMMAND_COL:
|
|
return command->icon.isEmpty() ? QIcon::fromTheme(QStringLiteral("system-run")) : QIcon::fromTheme(command->icon);
|
|
case OUTPUT_COL:
|
|
case DESCRIPTION_COL:
|
|
break;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
QVariant ActionDetailModel::editData(ClipCommand *command, ActionDetailModel::column_t column) const
|
|
{
|
|
switch (column) {
|
|
case COMMAND_COL:
|
|
return command->command;
|
|
case OUTPUT_COL:
|
|
return QVariant::fromValue<ClipCommand::Output>(command->output);
|
|
case DESCRIPTION_COL:
|
|
return command->description;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
QVariant ActionDetailModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
|
switch (static_cast<column_t>(section)) {
|
|
case COMMAND_COL:
|
|
return i18n("Command");
|
|
case OUTPUT_COL:
|
|
return i18n("Output Handling");
|
|
case DESCRIPTION_COL:
|
|
return i18n("Description");
|
|
}
|
|
}
|
|
return QAbstractTableModel::headerData(section, orientation, role);
|
|
}
|
|
|
|
QVariant ActionDetailModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
const int column = index.column();
|
|
const int row = index.row();
|
|
ClipCommand cmd = m_commands.at(row);
|
|
switch (role) {
|
|
case Qt::DisplayRole:
|
|
return displayData(&cmd, static_cast<column_t>(column));
|
|
case Qt::DecorationRole:
|
|
return decorationData(&cmd, static_cast<column_t>(column));
|
|
case Qt::EditRole:
|
|
return editData(&cmd, static_cast<column_t>(column));
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
void ActionDetailModel::addCommand(const ClipCommand &command)
|
|
{
|
|
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
|
m_commands << command;
|
|
endInsertRows();
|
|
}
|
|
|
|
void ActionDetailModel::removeCommand(const QModelIndex &index)
|
|
{
|
|
int row = index.row();
|
|
beginRemoveRows(QModelIndex(), row, row);
|
|
m_commands.removeAt(row);
|
|
endRemoveRows();
|
|
}
|
|
|
|
EditActionDialog::EditActionDialog(QWidget *parent)
|
|
: QDialog(parent)
|
|
{
|
|
setWindowTitle(i18n("Action Properties"));
|
|
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
|
buttons->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return);
|
|
connect(buttons, &QDialogButtonBox::accepted, this, &EditActionDialog::slotAccepted);
|
|
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
|
|
|
QWidget *dlgWidget = new QWidget(this);
|
|
m_ui = new Ui::EditActionDialog;
|
|
m_ui->setupUi(dlgWidget);
|
|
|
|
m_ui->leRegExp->setClearButtonEnabled(true);
|
|
m_ui->leDescription->setClearButtonEnabled(true);
|
|
|
|
m_ui->pbAddCommand->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
|
|
m_ui->pbRemoveCommand->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
|
|
|
|
// For some reason, the default row height is 30 pixel. Set it to the minimum sectionSize instead,
|
|
// which is the font height+struts.
|
|
m_ui->twCommandList->verticalHeader()->setDefaultSectionSize(m_ui->twCommandList->verticalHeader()->minimumSectionSize());
|
|
m_ui->twCommandList->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
|
|
|
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
|
layout->addWidget(dlgWidget);
|
|
layout->addWidget(buttons);
|
|
|
|
connect(m_ui->pbAddCommand, &QPushButton::clicked, this, &EditActionDialog::onAddCommand);
|
|
connect(m_ui->pbRemoveCommand, &QPushButton::clicked, this, &EditActionDialog::onRemoveCommand);
|
|
|
|
const KConfigGroup grp = KSharedConfig::openConfig()->group("EditActionDialog");
|
|
KWindowConfig::restoreWindowSize(windowHandle(), grp);
|
|
QByteArray hdrState = grp.readEntry("ColumnState", QByteArray());
|
|
if (!hdrState.isEmpty()) {
|
|
qCDebug(KLIPPER_LOG) << "Restoring column state";
|
|
m_ui->twCommandList->horizontalHeader()->restoreState(QByteArray::fromBase64(hdrState));
|
|
}
|
|
// do this after restoreState()
|
|
m_ui->twCommandList->horizontalHeader()->setHighlightSections(false);
|
|
}
|
|
|
|
EditActionDialog::~EditActionDialog()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
void EditActionDialog::setAction(ClipAction *act, int commandIdxToSelect)
|
|
{
|
|
m_action = act;
|
|
m_model = new ActionDetailModel(act, this);
|
|
m_ui->twCommandList->setModel(m_model);
|
|
m_ui->twCommandList->setItemDelegateForColumn(1, new ActionOutputDelegate);
|
|
connect(m_ui->twCommandList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &EditActionDialog::onSelectionChanged);
|
|
|
|
updateWidgets(commandIdxToSelect);
|
|
}
|
|
|
|
void EditActionDialog::updateWidgets(int commandIdxToSelect)
|
|
{
|
|
if (!m_action) {
|
|
qCDebug(KLIPPER_LOG) << "no action to edit was set";
|
|
return;
|
|
}
|
|
|
|
m_ui->leRegExp->setText(m_action->actionRegexPattern());
|
|
m_ui->automatic->setChecked(m_action->automatic());
|
|
m_ui->leDescription->setText(m_action->description());
|
|
|
|
if (commandIdxToSelect != -1) {
|
|
m_ui->twCommandList->setCurrentIndex(m_model->index(commandIdxToSelect, 0));
|
|
}
|
|
|
|
// update Remove button
|
|
onSelectionChanged();
|
|
}
|
|
|
|
void EditActionDialog::saveAction()
|
|
{
|
|
if (!m_action) {
|
|
qCDebug(KLIPPER_LOG) << "no action to edit was set";
|
|
return;
|
|
}
|
|
|
|
m_action->setActionRegexPattern(m_ui->leRegExp->text());
|
|
m_action->setDescription(m_ui->leDescription->text());
|
|
m_action->setAutomatic(m_ui->automatic->isChecked());
|
|
|
|
m_action->clearCommands();
|
|
|
|
foreach (const ClipCommand &cmd, m_model->commands()) {
|
|
m_action->addCommand(cmd);
|
|
}
|
|
}
|
|
|
|
void EditActionDialog::slotAccepted()
|
|
{
|
|
saveAction();
|
|
|
|
qCDebug(KLIPPER_LOG) << "Saving dialogue state";
|
|
KConfigGroup grp = KSharedConfig::openConfig()->group("EditActionDialog");
|
|
KWindowConfig::saveWindowSize(windowHandle(), grp);
|
|
grp.writeEntry("ColumnState", m_ui->twCommandList->horizontalHeader()->saveState().toBase64());
|
|
accept();
|
|
}
|
|
|
|
void EditActionDialog::onAddCommand()
|
|
{
|
|
m_model->addCommand(ClipCommand(i18n("new command"), i18n("Command Description"), true, QLatin1String("")));
|
|
m_ui->twCommandList->edit(m_model->index(m_model->rowCount() - 1, 0));
|
|
}
|
|
|
|
void EditActionDialog::onRemoveCommand()
|
|
{
|
|
m_model->removeCommand(m_ui->twCommandList->selectionModel()->currentIndex());
|
|
}
|
|
|
|
void EditActionDialog::onSelectionChanged()
|
|
{
|
|
m_ui->pbRemoveCommand->setEnabled(m_ui->twCommandList->selectionModel() && m_ui->twCommandList->selectionModel()->hasSelection());
|
|
}
|