1 /*
2 * Cantata
3 *
4 * Copyright (c) 2011-2020 Craig Drummond <craig.p.drummond@gmail.com>
5 *
6 * ----
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #include "customactionssettings.h"
25 #include "customactions.h"
26 #include "support/messagebox.h"
27 #include "widgets/basicitemdelegate.h"
28 #include "widgets/icons.h"
29 #include "widgets/notelabel.h"
30 #include <QGridLayout>
31 #include <QFormLayout>
32 #include <QLabel>
33 #include <QSpacerItem>
34 #include <QPushButton>
35 #include <QHeaderView>
36
CustomActionDialog(QWidget * p)37 CustomActionDialog::CustomActionDialog(QWidget *p)
38 : Dialog(p)
39 {
40 QWidget *widget=new QWidget(this);
41 QFormLayout *layout=new QFormLayout(widget);
42 nameEntry=new LineEdit(widget);
43 commandEntry=new LineEdit(widget);
44 nameEntry->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
45 commandEntry->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
46 layout->addRow(new QLabel(tr("Name:"), widget), nameEntry);
47 layout->addRow(new QLabel(tr("Command:"), widget), commandEntry);
48 layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
49 NoteLabel *note=new NoteLabel(widget);
50 note->setText(tr("In the command line above, %f will be replaced with the file list and %d with the folder list. If neither are supplied, the the list of files will be appended to the command."));
51 layout->setWidget(2, QFormLayout::SpanningRole, note);
52 layout->setMargin(0);
53 setButtons(Dialog::Ok|Dialog::Cancel);
54 setMainWidget(widget);
55 setMinimumWidth(400);
56 ensurePolished();
57 adjustSize();
58 }
59
create()60 bool CustomActionDialog::create()
61 {
62 setCaption(tr("Add New Command"));
63 nameEntry->setText(QString());
64 commandEntry->setText(QString());
65 return QDialog::Accepted==exec();
66 }
67
edit(const QString & name,const QString & cmd)68 bool CustomActionDialog::edit(const QString &name, const QString &cmd)
69 {
70 setCaption(tr("Edit Command"));
71 nameEntry->setText(name);
72 commandEntry->setText(cmd);
73 return QDialog::Accepted==exec();
74 }
75
setResizeMode(QHeaderView * hdr,int idx,QHeaderView::ResizeMode mode)76 static inline void setResizeMode(QHeaderView *hdr, int idx, QHeaderView::ResizeMode mode)
77 {
78 hdr->setSectionResizeMode(idx, mode);
79 }
80
CustomActionsSettings(QWidget * parent)81 CustomActionsSettings::CustomActionsSettings(QWidget *parent)
82 : QWidget(parent)
83 , dlg(nullptr)
84 {
85 QGridLayout *layout=new QGridLayout(this);
86 layout->setMargin(0);
87 QLabel *label=new QLabel(tr("To have Cantata call external commands (e.g. to edit tags with another application), add an entry for the command below. When at least one command "
88 "command is defined, a 'Custom Actions' entry will be added to the context menus in the Library, Folders, and Playlists views."), this);
89 QFont f(Utils::smallFont(label->font()));
90 f.setItalic(true);
91 label->setFont(f);
92 label->setWordWrap(true);
93 layout->addWidget(label, 0, 0, 1, 2);
94 tree=new QTreeWidget(this);
95 add=new QPushButton(this);
96 edit=new QPushButton(this);
97 del=new QPushButton(this);
98 layout->addWidget(tree, 1, 0, 4, 1);
99 layout->addWidget(add, 1, 1, 1, 1);
100 layout->addWidget(edit, 2, 1, 1, 1);
101 layout->addWidget(del, 3, 1, 1, 1);
102 layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding), 4, 1);
103
104 add->setText(tr("Add"));
105 edit->setText(tr("Edit"));
106 del->setText(tr("Remove"));
107 edit->setEnabled(false);
108 del->setEnabled(false);
109
110 tree->setHeaderLabels(QStringList() << tr("Name") << tr("Command"));
111 tree->setAllColumnsShowFocus(true);
112 tree->setSelectionMode(QAbstractItemView::ExtendedSelection);
113 tree->setRootIsDecorated(false);
114 tree->setSortingEnabled(true);
115 setResizeMode(tree->header(), 0, QHeaderView::ResizeToContents);
116 tree->header()->setStretchLastSection(true);
117 tree->setAlternatingRowColors(false);
118 tree->setItemDelegate(new BasicItemDelegate(this));
119 connect(tree, SIGNAL(itemSelectionChanged()), this, SLOT(controlButtons()));
120 connect(add, SIGNAL(clicked()), SLOT(addCommand()));
121 connect(edit, SIGNAL(clicked()), SLOT(editCommand()));
122 connect(del, SIGNAL(clicked()), SLOT(delCommand()));
123 }
124
~CustomActionsSettings()125 CustomActionsSettings::~CustomActionsSettings()
126 {
127 }
128
controlButtons()129 void CustomActionsSettings::controlButtons()
130 {
131 int selCount=tree->selectedItems().count();
132 edit->setEnabled(1==selCount);
133 del->setEnabled(selCount>0);
134 }
135
load()136 void CustomActionsSettings::load()
137 {
138 for (const CustomActions::Command &cmd: CustomActions::self()->commandList()) {
139 new QTreeWidgetItem(tree, QStringList() << cmd.name << cmd.cmd);
140 }
141 }
142
save()143 void CustomActionsSettings::save()
144 {
145 QList<CustomActions::Command> commands;
146
147 for (int i=0; i<tree->topLevelItemCount(); ++i) {
148 commands.append((CustomActions::Command(tree->topLevelItem(i)->text(0), tree->topLevelItem(i)->text(1))));
149 }
150 CustomActions::self()->set(commands);
151 }
152
addCommand()153 void CustomActionsSettings::addCommand()
154 {
155 if (!dlg) {
156 dlg=new CustomActionDialog(this);
157 }
158 if (dlg->create() && !dlg->nameText().isEmpty() && !dlg->commandText().isEmpty()) {
159 new QTreeWidgetItem(tree, QStringList() << dlg->nameText() << dlg->commandText());
160 }
161 }
162
editCommand()163 void CustomActionsSettings::editCommand()
164 {
165 QList<QTreeWidgetItem *> items=tree->selectedItems();
166
167 if (1!=items.count()) {
168 return;
169 }
170 if (!dlg) {
171 dlg=new CustomActionDialog(this);
172 }
173 QTreeWidgetItem *item=items.at(0);
174 if (dlg->edit(item->text(0), item->text(1)) && !dlg->nameText().isEmpty() && !dlg->commandText().isEmpty()) {
175 item->setText(0, dlg->nameText());
176 item->setText(1, dlg->commandText());
177 }
178 }
179
delCommand()180 void CustomActionsSettings::delCommand()
181 {
182 if (MessageBox::Yes==MessageBox::warningYesNo(this, tr("Remove the selected commands?"), QString(), GuiItem(tr("Remove")), StdGuiItem::cancel())) {
183 for (QTreeWidgetItem *i: tree->selectedItems()) {
184 delete i;
185 }
186 }
187 }
188
189 #include "moc_customactionssettings.cpp"
190