1
// Copyright (c) 2000-2001 Charles Samuels <charles@kde.org>
2
// Copyright (c) 2000-2001 Neil Stevens <multivac@fcmail.com>
4
// Permission is hereby granted, free of charge, to any person obtaining a copy
5
// of this software and associated documentation files (the "Software"), to deal
6
// in the Software without restriction, including without limitation the rights
7
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
// copies of the Software, and to permit persons to whom the Software is
9
// furnished to do so, subject to the following conditions:
11
// The above copyright notice and this permission notice shall be included in
12
// all copies or substantial portions of the Software.
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIAB\ILITY, WHETHER IN
18
// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
#include <kiconloader.h>
29
#include "noatunlistview.h"
31
#include <qwhatsthis.h>
34
#include "noatunapp.h"
35
#include "pluginmodule.h"
37
PluginListItem::PluginListItem(const bool _exclusive, bool _checked, const NoatunLibraryInfo &_info, QListView *_parent)
38
: QCheckListItem(_parent, _info.name, CheckBox)
40
, silentStateChange(false)
41
, exclusive(_exclusive)
44
if(_checked) static_cast<PluginListView *>(listView())->count++;
48
void PluginListItem::setChecked(bool b)
50
silentStateChange = true;
52
silentStateChange = false;
55
void PluginListItem::stateChange(bool b)
57
if(!silentStateChange)
58
static_cast<PluginListView *>(listView())->stateChanged(this, b);
61
void PluginListItem::paintCell(QPainter *p, const QColorGroup &cg, int a, int b, int c)
63
if(exclusive) myType = RadioButton;
64
QCheckListItem::paintCell(p, cg, a, b, c);
65
if(exclusive) myType = CheckBox;
68
PluginListView::PluginListView(unsigned _min, unsigned _max, QWidget *_parent, const char *_name)
69
: KListView(_parent, _name)
72
, min(_min <= _max ? _min : _max)
77
PluginListView::PluginListView(unsigned _min, QWidget *_parent, const char *_name)
78
: KListView(_parent, _name)
85
PluginListView::PluginListView(QWidget *_parent, const char *_name)
86
: KListView(_parent, _name)
93
void PluginListView::clear()
99
void PluginListView::stateChanged(PluginListItem *item, bool b)
104
emit stateChange(item, b);
106
if(hasMaximum && count > max)
108
// Find a different one and turn it off
110
QListViewItem *cur = firstChild();
111
PluginListItem *curItem = dynamic_cast<PluginListItem *>(cur);
113
while(cur == item || !curItem || !curItem->isOn())
115
cur = cur->nextSibling();
116
curItem = dynamic_cast<PluginListItem *>(cur);
119
curItem->setOn(false);
126
item->setChecked(true);
131
emit stateChange(item, b);
136
Plugins::Plugins(QObject *_parent)
137
: CModule(i18n("Plugins"), i18n("Choose Your Plugins"), _parent)
139
(new QVBoxLayout(this))->setAutoAdd(true);
140
KTabCtl *tabControl = new KTabCtl(this);
142
QFrame *interfaceTab = new QFrame(tabControl);
143
(new QVBoxLayout(interfaceTab, KDialog::marginHint(), KDialog::spacingHint()))->setAutoAdd(true);
144
(void)new QLabel(i18n("<b>Choose one or more interfaces to use:</b>"), interfaceTab);
145
// At least one interface is required
146
interfaceList = new PluginListView(1, interfaceTab);
147
interfaceList->addColumn(i18n("Name"));
148
interfaceList->addColumn(i18n("Description"));
149
interfaceList->addColumn(i18n("Author"));
150
interfaceList->addColumn(i18n("License"));
151
connect(interfaceList, SIGNAL(stateChange(PluginListItem *, bool)), this, SLOT(stateChange(PluginListItem *, bool)));
152
tabControl->addTab(interfaceTab, i18n("Interfaces"));
154
QFrame *playlistTab = new QFrame(tabControl);
155
(new QVBoxLayout(playlistTab, KDialog::marginHint(), KDialog::spacingHint()))->setAutoAdd(true);
156
(void)new QLabel(i18n("<b>Choose one playlist to use:</b>"), playlistTab);
157
// Exactly one playlist is required
158
playlistList = new PluginListView(1, 1, playlistTab);
159
playlistList->addColumn(i18n("Name"));
160
playlistList->addColumn(i18n("Description"));
161
playlistList->addColumn(i18n("Author"));
162
playlistList->addColumn(i18n("License"));
163
connect(playlistList, SIGNAL(stateChange(PluginListItem *, bool)), this, SLOT(stateChange(PluginListItem *, bool)));
164
tabControl->addTab(playlistTab, i18n("Playlist"));
166
QFrame *otherTab = new QFrame(tabControl);
167
(new QVBoxLayout(otherTab, KDialog::marginHint(), KDialog::spacingHint()))->setAutoAdd(true);
168
(void)new QLabel(i18n("<b>Choose any other plugins to use:</b>"), otherTab);
169
// Other plugins are not restricted
170
otherList = new PluginListView(0, otherTab);
171
otherList->addColumn(i18n("Name"));
172
otherList->addColumn(i18n("Description"));
173
otherList->addColumn(i18n("Author"));
174
otherList->addColumn(i18n("License"));
175
connect(otherList, SIGNAL(stateChange(PluginListItem *, bool)), this, SLOT(stateChange(PluginListItem *, bool)));
176
tabControl->addTab(otherTab, i18n("Other Plugins"));
179
void Plugins::reopen()
181
playlistList->clear();
182
interfaceList->clear();
185
QValueList<NoatunLibraryInfo> available = napp->libraryLoader()->available();
186
QValueList<NoatunLibraryInfo> loaded = napp->libraryLoader()->loaded();
188
for(QValueList<NoatunLibraryInfo>::Iterator i = available.begin(); i != available.end(); ++i)
190
PluginListView *parent;
191
bool exclusive = false;
193
if((*i).type == "userinterface")
194
parent = interfaceList;
195
else if((*i).type == "playlist")
197
parent = playlistList;
200
else if((*i).type == "sm" || (*i).type=="hidden")
207
PluginListItem *item = new PluginListItem(exclusive, loaded.contains(*i), *i, parent);
208
item->setText(0, (*i).name);
209
item->setText(1, (*i).comment);
210
item->setText(2, (*i).author);
211
item->setText(3, (*i).license);
216
void Plugins::stateChange(PluginListItem *item, bool b)
219
addPlugin(item->info());
221
removePlugin(item->info());
224
void Plugins::addPlugin(const NoatunLibraryInfo &info)
226
// Load any that this one depends upon
227
for(QStringList::ConstIterator i = info.require.begin(); i != info.require.end(); ++i)
229
NoatunLibraryInfo requiredInfo = napp->libraryLoader()->getInfo(*i);
230
PluginListItem *item = findItem(requiredInfo);
231
if(item) item->setOn(true);
234
if(mDeleted.contains(info.specfile))
235
mDeleted.remove(info.specfile);
236
else if(!mAdded.contains(info.specfile))
237
mAdded.append(info.specfile);
240
void Plugins::removePlugin(const NoatunLibraryInfo &info)
242
LibraryLoader &loader = *(napp->libraryLoader());
244
// Here are the ones loaded
245
QValueList<NoatunLibraryInfo> loaded = napp->libraryLoader()->loaded();
247
// Add the ones marked for loading
248
for(QStringList::ConstIterator i = mAdded.begin(); i != mAdded.end(); ++i)
249
loaded.append(loader.getInfo(*i));
251
// Subtract the ones marked for removal
252
for(QStringList::ConstIterator i = mDeleted.begin(); i != mDeleted.end(); ++i)
253
loaded.remove(loader.getInfo(*i));
255
// If any depend on this plugin, mark them for removal (or remove them from mAdded)
256
for(QValueList<NoatunLibraryInfo>::Iterator i = loaded.begin(); i != loaded.end(); ++i)
258
for(QStringList::ConstIterator j = (*i).require.begin(); j != (*i).require.end(); ++j)
260
if(*j == info.specfile)
262
PluginListItem *item = findItem(*i);
263
if(item) item->setOn(false);
268
if (mAdded.contains(info.specfile))
269
mAdded.remove(info.specfile);
270
else if(!mDeleted.contains(info.specfile))
271
mDeleted.append(info.specfile);
274
PluginListItem *Plugins::findItem(const NoatunLibraryInfo &info) const
276
for(QListViewItem *cur = otherList->firstChild(); cur != 0; cur = cur->itemBelow())
278
PluginListItem *item = dynamic_cast<PluginListItem *>(cur);
279
if(item && item->info() == info)
283
// If our only interface has a dependency removed, that's a double dose of trouble
284
// We may as well have this here for completeness, though
285
for(QListViewItem *cur = interfaceList->firstChild(); cur != 0; cur = cur->itemBelow())
287
PluginListItem *item = dynamic_cast<PluginListItem *>(cur);
288
if(item && item->info() == info)
292
// If a playlist is added or removed due to a dependency, we're doom-diddly-oomed
293
// We may as well have this here for completeness, though
294
for(QListViewItem *cur = playlistList->firstChild(); cur != 0; cur = cur->itemBelow())
296
PluginListItem *item = dynamic_cast<PluginListItem *>(cur);
297
if(item && item->info() == info)
306
LibraryLoader &loader = *(napp->libraryLoader());
308
// Load the plugins the user added
309
for(QStringList::Iterator i = mAdded.begin(); i != mAdded.end(); ++i)
312
// Remove the plugins the user removed
313
for (QStringList::Iterator i = mDeleted.begin(); i != mDeleted.end(); ++i)
316
// Round up the ones that weren't loaded right now, for saving in the configuration
317
QStringList specList(mAdded);
319
QValueList<NoatunLibraryInfo> loaded = loader.loaded();
320
for(QValueList<NoatunLibraryInfo>::Iterator i = loaded.begin(); i != loaded.end(); ++i)
321
if(!specList.contains((*i).specfile) && loader.isLoaded((*i).specfile))
322
specList += (*i).specfile;
324
// Now we actually save
325
loader.setModules(specList);
331
#include "pluginmodule.moc"