2
* Copyright (c) 2009 Chani Armitage <chani@kde.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU Library General Public License as
6
* published by the Free Software Foundation; either version 2, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details
14
* You should have received a copy of the GNU Library General Public
15
* License along with this program; if not, write to the
16
* Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
#include "mousepluginwidget.h"
22
#include <Plasma/Containment>
25
#include <KAboutApplicationDialog>
28
#include <QApplication>
31
#include <QDialogButtonBox>
32
#include <QGridLayout>
34
Q_DECLARE_METATYPE(KPluginInfo)
36
MousePluginWidget::MousePluginWidget(const QString &pluginName, const QString &trigger, QGridLayout *layoutHack, QWidget *parent)
40
m_lastConfigLocation(trigger),
41
m_tempConfigParent(QString(), KConfig::SimpleConfig)
43
KPluginInfo::List plugins = Plasma::ContainmentActions::listContainmentActionsInfo();
44
if (plugins.isEmpty()) {
46
QLabel *fail = new QLabel(i18n("No plugins found, check your installation."), parent);
47
layoutHack->addWidget(fail, 0, 0);
51
//make us some widgets
52
m_pluginList = new QComboBox(parent);
53
m_aboutButton = new QToolButton(parent);
54
m_clearButton = new QToolButton(parent);
55
m_triggerButton = new MouseInputButton(parent);
56
m_configButton = new QToolButton(parent);
57
//m_ui.description->setText(plugin.comment());
60
//FIXME is there some way to share this across all the entries?
61
foreach (const KPluginInfo& plugin, plugins) {
62
if (plugin.property("NoDisplay").toBool()) {
66
m_pluginList->addItem(KIcon(plugin.icon()), plugin.name(), QVariant::fromValue(plugin));
67
if (plugin.pluginName() == pluginName) {
68
m_pluginList->setCurrentIndex(m_pluginList->count() - 1);
73
if (! m_plugin.isValid()) {
74
//probably an empty string; pick the first one
75
m_pluginList->setCurrentIndex(0);
76
m_plugin = plugins.first();
80
m_tempConfig = KConfigGroup(&m_tempConfigParent, "test");
81
if (!m_plugin.property("X-Plasma-HasConfigurationInterface").toBool()) {
82
m_configButton->setVisible(false);
87
//pretty icons for the buttons
88
m_aboutButton->setIcon(KIcon("dialog-information"));
89
m_triggerButton->setIcon(KIcon("input-mouse"));
90
m_configButton->setIcon(KIcon("configure"));
91
m_clearButton->setIcon(KIcon("list-remove"));
94
//FIXME what's the Right Way to do this?
95
int row = layoutHack->rowCount();
96
layoutHack->addWidget(m_triggerButton, row, 0);
97
layoutHack->addWidget(m_pluginList, row, 1);
98
layoutHack->addWidget(m_configButton, row, 2);
99
layoutHack->addWidget(m_aboutButton, row, 3);
100
layoutHack->addWidget(m_clearButton, row, 4);
103
connect(m_pluginList, SIGNAL(currentIndexChanged(int)), this, SLOT(setPlugin(int)));
104
connect(m_triggerButton, SIGNAL(triggerChanged(QString,QString)), this, SLOT(changeTrigger(QString,QString)));
105
connect(m_configButton, SIGNAL(clicked()), this, SLOT(configure()));
106
connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearTrigger()));
107
connect(m_aboutButton, SIGNAL(clicked()), this, SLOT(showAbout()));
110
MousePluginWidget::~MousePluginWidget()
112
delete m_pluginInstance.data();
115
void MousePluginWidget::setPlugin(int index)
117
m_plugin = m_pluginList->itemData(index).value<KPluginInfo>();
118
//clear all the old plugin's stuff
120
kDebug() << "can't happen";
121
m_configDlg->deleteLater();
124
if (m_pluginInstance) {
125
delete m_pluginInstance.data();
126
kDebug() << "tried to delete instance";
128
//reset config button
129
bool hasConfig = m_plugin.property("X-Plasma-HasConfigurationInterface").toBool();
130
m_configButton->setVisible(hasConfig);
131
m_tempConfig.deleteGroup();
132
m_lastConfigLocation.clear();
133
//FIXME a stray mousewheel deleting your config would be no fun.
134
//perhaps we could mark it for deletion, and then... um.. not delete it if the user goes back to
135
//that plugin? but then we'd have to record which plugin the config is *for*...
136
emit configChanged(m_triggerButton->trigger());
139
void MousePluginWidget::setContainment(Plasma::Containment *ctmt)
141
//note: since the old plugin's parent is the old containment,
142
//we let that containment take care of deleting it
143
m_containment = ctmt;
146
void MousePluginWidget::setTrigger(const QString &trigger)
148
m_triggerButton->setTrigger(trigger);
149
updateConfig(trigger);
152
void MousePluginWidget::clearTrigger()
154
QString oldTrigger = m_triggerButton->trigger();
155
setTrigger(QString());
156
emit triggerChanged(oldTrigger, QString());
159
m_pluginList->deleteLater();
160
m_aboutButton->deleteLater();
161
m_clearButton->deleteLater();
162
m_triggerButton->deleteLater();
163
m_configButton->deleteLater();
168
void MousePluginWidget::changeTrigger(const QString &oldTrigger, const QString& newTrigger)
170
updateConfig(newTrigger);
171
emit triggerChanged(oldTrigger, newTrigger);
174
void MousePluginWidget::updateConfig(const QString &trigger)
176
m_configButton->setEnabled(!trigger.isEmpty());
177
m_pluginList->setEnabled(!trigger.isEmpty());
180
void MousePluginWidget::configure()
182
if (!m_pluginInstance) {
183
Plasma::ContainmentActions *pluginInstance = Plasma::ContainmentActions::load(m_containment, m_plugin.pluginName());
184
if (!pluginInstance) {
186
kDebug() << "failed to load plugin!";
190
m_pluginInstance = pluginInstance;
192
if (m_lastConfigLocation.isEmpty()) {
193
pluginInstance->restore(m_tempConfig);
195
KConfigGroup cfg = m_containment->containmentActionsConfig();
196
cfg = KConfigGroup(&cfg, m_lastConfigLocation);
197
pluginInstance->restore(cfg);
202
m_configDlg = new QDialog(qobject_cast<QWidget*>(parent()));
203
QLayout *lay = new QVBoxLayout(m_configDlg);
204
m_configDlg->setLayout(lay);
205
m_configDlg->setWindowModality(Qt::WindowModal);
207
//put the config in the dialog
208
QWidget *w = m_pluginInstance.data()->createConfigurationInterface(m_configDlg);
212
const QString title = w->windowTitle();
214
m_configDlg->setWindowTitle(title.isEmpty() ? i18n("Configure Plugin") :title);
216
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
217
Qt::Horizontal, m_configDlg);
218
lay->addWidget(buttons);
220
//TODO other signals?
221
connect(buttons, SIGNAL(accepted()), this, SLOT(acceptConfig()));
222
connect(buttons, SIGNAL(rejected()), this, SLOT(rejectConfig()));
228
void MousePluginWidget::acceptConfig()
230
kDebug() << "accept";
231
if (m_pluginInstance) {
232
m_pluginInstance.data()->configurationAccepted();
235
m_configDlg->deleteLater();
237
emit configChanged(m_triggerButton->trigger());
240
void MousePluginWidget::rejectConfig()
242
kDebug() << "reject";
243
m_configDlg->deleteLater();
247
void MousePluginWidget::prepareForSave()
249
if (!m_configButton->isVisible() || m_pluginInstance || m_lastConfigLocation.isEmpty()) {
253
//back up our config because it'll be erased for saving
254
KConfigGroup cfg = m_containment->containmentActionsConfig();
255
cfg = KConfigGroup(&cfg, m_lastConfigLocation);
256
cfg.copyTo(&m_tempConfig);
257
//kDebug() << "copied to temp";
260
void MousePluginWidget::save()
262
QString trigger = m_triggerButton->trigger();
263
if (trigger.isEmpty()) {
264
m_lastConfigLocation.clear();
268
if (m_pluginInstance || !m_lastConfigLocation.isEmpty()) {
269
KConfigGroup cfg = m_containment->containmentActionsConfig();
270
cfg = KConfigGroup(&cfg, trigger);
271
if (m_pluginInstance) {
272
m_pluginInstance.data()->save(cfg);
274
m_tempConfig.copyTo(&cfg);
275
//kDebug() << "copied from temp";
277
m_lastConfigLocation = trigger;
279
m_containment->setContainmentActions(trigger, m_plugin.pluginName());
282
//copied from appletbrowser.cpp
283
//FIXME add a feature to KAboutApplicationDialog to delete the object
284
/* This is just a wrapper around KAboutApplicationDialog that deletes
285
the KAboutData object that it is associated with, when it is deleted.
286
This is required to free memory correctly when KAboutApplicationDialog
287
is called with a temporary KAboutData that is allocated on the heap.
288
(see the code below, in AppletBrowserWidget::infoAboutApplet())
290
class KAboutApplicationDialog2 : public KAboutApplicationDialog
293
KAboutApplicationDialog2(KAboutData *ab, QWidget *parent = 0)
294
: KAboutApplicationDialog(ab, parent), m_ab(ab) {}
296
~KAboutApplicationDialog2()
305
void MousePluginWidget::showAbout()
307
KAboutData *aboutData = new KAboutData(m_plugin.name().toUtf8(),
308
m_plugin.name().toUtf8(),
309
ki18n(m_plugin.name().toUtf8()),
310
m_plugin.version().toUtf8(), ki18n(m_plugin.comment().toUtf8()),
311
m_plugin.fullLicense().key(), ki18n(QByteArray()), ki18n(QByteArray()), m_plugin.website().toLatin1(),
312
m_plugin.email().toLatin1());
314
aboutData->setProgramIconName(m_plugin.icon());
316
aboutData->addAuthor(ki18n(m_plugin.author().toUtf8()), ki18n(QByteArray()), m_plugin.email().toLatin1());
318
KAboutApplicationDialog *aboutDialog = new KAboutApplicationDialog2(aboutData, qobject_cast<QWidget*>(parent()));
322
// vim: sw=4 sts=4 et tw=100