~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to noatun/noatun/library/pluginmodule.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2000-2001 Charles Samuels <charles@kde.org>
 
2
// Copyright (c) 2000-2001 Neil Stevens <multivac@fcmail.com>
 
3
// 
 
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:
 
10
// 
 
11
// The above copyright notice and this permission notice shall be included in
 
12
// all copies or substantial portions of the Software.
 
13
// 
 
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.
 
20
 
 
21
#include <kdialog.h>
 
22
#include <kiconloader.h>
 
23
#include <klocale.h>
 
24
#include <ktabctl.h>
 
25
#include <qheader.h>
 
26
#include <qlabel.h>
 
27
#include <qlayout.h>
 
28
 
 
29
#include "noatunlistview.h"
 
30
 
 
31
#include <qwhatsthis.h>
 
32
 
 
33
#include "common.h"
 
34
#include "noatunapp.h"
 
35
#include "pluginmodule.h"
 
36
 
 
37
PluginListItem::PluginListItem(const bool _exclusive, bool _checked, const NoatunLibraryInfo &_info, QListView *_parent)
 
38
        : QCheckListItem(_parent, _info.name, CheckBox)
 
39
        , mInfo(_info)
 
40
        , silentStateChange(false)
 
41
        , exclusive(_exclusive)
 
42
{
 
43
        setChecked(_checked);
 
44
        if(_checked) static_cast<PluginListView *>(listView())->count++;
 
45
}
 
46
 
 
47
 
 
48
void PluginListItem::setChecked(bool b)
 
49
{
 
50
        silentStateChange = true;
 
51
        setOn(b);
 
52
        silentStateChange = false;
 
53
}
 
54
 
 
55
void PluginListItem::stateChange(bool b)
 
56
{
 
57
        if(!silentStateChange)
 
58
                static_cast<PluginListView *>(listView())->stateChanged(this, b);
 
59
}
 
60
 
 
61
void PluginListItem::paintCell(QPainter *p, const QColorGroup &cg, int a, int b, int c)
 
62
{
 
63
        if(exclusive) myType = RadioButton;
 
64
        QCheckListItem::paintCell(p, cg, a, b, c);
 
65
        if(exclusive) myType = CheckBox;
 
66
}
 
67
 
 
68
PluginListView::PluginListView(unsigned _min, unsigned _max, QWidget *_parent, const char *_name)
 
69
        : KListView(_parent, _name)
 
70
        , hasMaximum(true)
 
71
        , max(_max)
 
72
        , min(_min <= _max ? _min : _max)
 
73
        , count(0)
 
74
{
 
75
}
 
76
 
 
77
PluginListView::PluginListView(unsigned _min, QWidget *_parent, const char *_name)
 
78
        : KListView(_parent, _name)
 
79
        , hasMaximum(false)
 
80
        , min(_min)
 
81
        , count(0)
 
82
{
 
83
}
 
84
 
 
85
PluginListView::PluginListView(QWidget *_parent, const char *_name)
 
86
        : KListView(_parent, _name)
 
87
        , hasMaximum(false)
 
88
        , min(0)
 
89
        , count(0)
 
90
{
 
91
}
 
92
 
 
93
void PluginListView::clear()
 
94
{
 
95
        count = 0;
 
96
        KListView::clear();
 
97
}
 
98
 
 
99
void PluginListView::stateChanged(PluginListItem *item, bool b)
 
100
{
 
101
        if(b)
 
102
        {
 
103
                count++;
 
104
                emit stateChange(item, b);
 
105
                
 
106
                if(hasMaximum && count > max)
 
107
                {
 
108
                        // Find a different one and turn it off
 
109
 
 
110
                        QListViewItem *cur = firstChild();
 
111
                        PluginListItem *curItem = dynamic_cast<PluginListItem *>(cur);
 
112
 
 
113
                        while(cur == item || !curItem || !curItem->isOn())
 
114
                        {
 
115
                                cur = cur->nextSibling();
 
116
                                curItem = dynamic_cast<PluginListItem *>(cur);
 
117
                        }
 
118
 
 
119
                        curItem->setOn(false);
 
120
                }
 
121
        }
 
122
        else
 
123
        {
 
124
                if(count == min)
 
125
                {
 
126
                        item->setChecked(true);
 
127
                }
 
128
                else
 
129
                {
 
130
                        count--;
 
131
                        emit stateChange(item, b);
 
132
                }
 
133
        }
 
134
}
 
135
 
 
136
Plugins::Plugins(QObject *_parent)
 
137
        : CModule(i18n("Plugins"), i18n("Choose Your Plugins"), _parent)
 
138
{
 
139
        (new QVBoxLayout(this))->setAutoAdd(true); 
 
140
        KTabCtl *tabControl = new KTabCtl(this);
 
141
 
 
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"));
 
153
        
 
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"));
 
165
 
 
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"));
 
177
}
 
178
 
 
179
void Plugins::reopen()
 
180
{
 
181
        playlistList->clear();
 
182
        interfaceList->clear();
 
183
        otherList->clear();
 
184
 
 
185
        QValueList<NoatunLibraryInfo> available = napp->libraryLoader()->available();
 
186
        QValueList<NoatunLibraryInfo> loaded = napp->libraryLoader()->loaded();
 
187
 
 
188
        for(QValueList<NoatunLibraryInfo>::Iterator i = available.begin(); i != available.end(); ++i)
 
189
        {
 
190
                PluginListView *parent;
 
191
                bool exclusive = false;
 
192
 
 
193
                if((*i).type == "userinterface")
 
194
                        parent = interfaceList;
 
195
                else if((*i).type == "playlist")
 
196
                {
 
197
                        parent = playlistList;
 
198
                        exclusive = true;
 
199
                }
 
200
                else if((*i).type == "sm" || (*i).type=="hidden")
 
201
                        parent = 0;
 
202
                else
 
203
                        parent = otherList;
 
204
 
 
205
                if(parent)
 
206
                {
 
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);
 
212
                }
 
213
        }
 
214
}
 
215
 
 
216
void Plugins::stateChange(PluginListItem *item, bool b)
 
217
{
 
218
        if(b)
 
219
                addPlugin(item->info());
 
220
        else
 
221
                removePlugin(item->info());
 
222
}
 
223
 
 
224
void Plugins::addPlugin(const NoatunLibraryInfo &info)
 
225
{
 
226
        // Load any that this one depends upon
 
227
        for(QStringList::ConstIterator i = info.require.begin(); i != info.require.end(); ++i)
 
228
        {
 
229
                NoatunLibraryInfo requiredInfo = napp->libraryLoader()->getInfo(*i);
 
230
                PluginListItem *item = findItem(requiredInfo);
 
231
                if(item) item->setOn(true);
 
232
        }
 
233
 
 
234
        if(mDeleted.contains(info.specfile))
 
235
                mDeleted.remove(info.specfile);
 
236
        else if(!mAdded.contains(info.specfile))
 
237
                mAdded.append(info.specfile);
 
238
}
 
239
 
 
240
void Plugins::removePlugin(const NoatunLibraryInfo &info)
 
241
{
 
242
        LibraryLoader &loader = *(napp->libraryLoader());
 
243
 
 
244
        // Here are the ones loaded
 
245
        QValueList<NoatunLibraryInfo> loaded = napp->libraryLoader()->loaded();
 
246
        
 
247
        // Add the ones marked for loading
 
248
        for(QStringList::ConstIterator i = mAdded.begin(); i != mAdded.end(); ++i)
 
249
                loaded.append(loader.getInfo(*i));
 
250
 
 
251
        // Subtract the ones marked for removal
 
252
        for(QStringList::ConstIterator i = mDeleted.begin(); i != mDeleted.end(); ++i)
 
253
                loaded.remove(loader.getInfo(*i));
 
254
 
 
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)
 
257
        {
 
258
                for(QStringList::ConstIterator j = (*i).require.begin(); j != (*i).require.end(); ++j)
 
259
                {
 
260
                        if(*j == info.specfile)
 
261
                        {
 
262
                                PluginListItem *item = findItem(*i);
 
263
                                if(item) item->setOn(false);
 
264
                        }
 
265
                }
 
266
        }
 
267
 
 
268
        if (mAdded.contains(info.specfile))
 
269
                mAdded.remove(info.specfile);
 
270
        else if(!mDeleted.contains(info.specfile))
 
271
                mDeleted.append(info.specfile);
 
272
}
 
273
 
 
274
PluginListItem *Plugins::findItem(const NoatunLibraryInfo &info) const
 
275
{
 
276
        for(QListViewItem *cur = otherList->firstChild(); cur != 0; cur = cur->itemBelow())
 
277
        {
 
278
                PluginListItem *item = dynamic_cast<PluginListItem *>(cur);
 
279
                if(item && item->info() == info)
 
280
                        return item;
 
281
        }
 
282
 
 
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())
 
286
        {
 
287
                PluginListItem *item = dynamic_cast<PluginListItem *>(cur);
 
288
                if(item && item->info() == info)
 
289
                        return item;
 
290
        }
 
291
 
 
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())
 
295
        {
 
296
                PluginListItem *item = dynamic_cast<PluginListItem *>(cur);
 
297
                if(item && item->info() == info)
 
298
                        return item;
 
299
        }
 
300
 
 
301
        return 0;
 
302
}
 
303
 
 
304
void Plugins::save()
 
305
{
 
306
        LibraryLoader &loader = *(napp->libraryLoader());
 
307
 
 
308
        // Load the plugins the user added
 
309
        for(QStringList::Iterator i = mAdded.begin(); i != mAdded.end(); ++i)
 
310
                loader.add(*i);
 
311
 
 
312
        // Remove the plugins the user removed
 
313
        for (QStringList::Iterator i = mDeleted.begin(); i != mDeleted.end(); ++i)
 
314
                loader.remove(*i);
 
315
 
 
316
        // Round up the ones that weren't loaded right now, for saving in the configuration
 
317
        QStringList specList(mAdded);
 
318
 
 
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;
 
323
 
 
324
        // Now we actually save
 
325
        loader.setModules(specList);
 
326
 
 
327
        mDeleted.clear();
 
328
        mAdded.clear();
 
329
}
 
330
 
 
331
#include "pluginmodule.moc"