2 * Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library/Lesser General Public License
6 * version 2, or (at your option) any later version, as published by the
7 * Free Software Foundation
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/Lesser 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 "plasma/appletbrowser.h"
22 #include <QVBoxLayout>
27 #include <KConfigGroup>
29 #include <KPageWidgetItem>
30 #include <KPushButton>
31 #include <KServiceTypeTrader>
32 #include <KStandardAction>
34 #include "plasma/applet.h"
35 #include "plasma/corona.h"
36 #include "plasma/containment.h"
37 #include "plasma/appletbrowser/kcategorizeditemsview_p.h"
38 #include "plasma/appletbrowser/plasmaappletitemmodel_p.h"
39 #include "plasma/appletbrowser/openwidgetassistant_p.h"
44 class AppletBrowserWidget::Private
47 Private(Containment
* cont
, AppletBrowserWidget
* w
)
51 configGroup(&config
, "Applet Browser"),
52 itemModel(configGroup
, w
),
60 Plasma::Containment
*containment
;
61 KCategorizedItemsView
*appletList
;
62 QHash
<QString
, int> runningApplets
; // applet name => count
63 //extra hash so we can look up the names of deleted applets
64 QHash
<Plasma::Applet
*, QString
> appletNames
;
67 KConfigGroup configGroup
;
69 PlasmaAppletItemModel itemModel
;
70 KCategorizedItemsViewModels::DefaultFilterModel filterModel
;
73 void AppletBrowserWidget::Private::initFilters()
77 filterModel
.addFilter(i18n("All Widgets"),
78 KCategorizedItemsViewModels::Filter(), new KIcon("plasma"));
80 // Recommended emblems and filters
81 QRegExp
rx("recommended[.]([0-9A-Za-z]+)[.]caption");
82 QMapIterator
<QString
, QString
> i(configGroup
.entryMap());
85 if (!rx
.exactMatch(i
.key())) {
88 //kDebug() << "These are the key/vals in rc file " << rx.cap(1) << "\n";
90 QString id
= rx
.cap(1);
91 QString caption
= configGroup
.readEntry("recommended." + id
+ ".caption");
92 QString icon
= configGroup
.readEntry("recommended." + id
+ ".icon");
93 QString plugins
= configGroup
.readEntry("recommended." + id
+ ".plugins");
95 appletList
->addEmblem(i18n("Recommended by %1", caption
), new KIcon(icon
),
96 KCategorizedItemsViewModels::Filter("recommended." + id
, true));
97 filterModel
.addFilter(i18n("Recommended by %1", caption
),
98 KCategorizedItemsViewModels::Filter("recommended." + id
, true), new KIcon(icon
));
102 filterModel
.addFilter(i18n("My Favorite Widgets"),
103 KCategorizedItemsViewModels::Filter("favorite", true),
104 new KIcon("bookmarks"));
105 filterModel
.addFilter(i18n("Widgets I Have Used Before"),
106 KCategorizedItemsViewModels::Filter("used", true),
107 new KIcon("view-history"));
108 filterModel
.addFilter(i18n("Currently Running Widgets"),
109 KCategorizedItemsViewModels::Filter("running", true),
110 new KIcon("view-history"));
112 filterModel
.addSeparator(i18n("Categories:"));
114 foreach (const QString
& category
, Plasma::Applet::knownCategories(application
)) {
115 filterModel
.addFilter(category
,
116 KCategorizedItemsViewModels::Filter("category", category
));
120 AppletBrowserWidget::AppletBrowserWidget(Plasma::Containment
* containment
, QWidget
* parent
, Qt::WindowFlags f
)
121 : QWidget(parent
, f
),
122 d(new Private(containment
, this))
127 AppletBrowserWidget::~AppletBrowserWidget()
132 void AppletBrowserWidget::init()
134 QVBoxLayout
*layout
= new QVBoxLayout(this);
136 d
->appletList
= new KCategorizedItemsView(this);
137 connect(d
->appletList
, SIGNAL(activated(const QModelIndex
&)), this, SLOT(addApplet()));
138 layout
->addWidget( d
->appletList
);
141 d
->appletList
->addEmblem(i18n("Widgets I Have Used Before"), new KIcon("view-history"),
142 KCategorizedItemsViewModels::Filter("used", true));
145 d
->appletList
->setFilterModel(&d
->filterModel
);
148 d
->appletList
->setItemModel(&d
->itemModel
);
149 initRunningApplets();
154 void AppletBrowserWidget::initRunningApplets()
156 //get applets from corona, count them, send results to model
157 if (!d
->containment
) {
161 kDebug() << d
->runningApplets
.count();
162 Plasma::Corona
*c
= d
->containment
->corona();
164 //we've tried our best to get a corona
165 //we don't want just one containment, we want them all
167 kDebug() << "can't happen";
171 d
->appletNames
.clear();
172 d
->runningApplets
.clear();
173 QList
<Containment
*> containments
= c
->containments();
174 foreach (Containment
* containment
,containments
) {
175 connect(containment
, SIGNAL(appletAdded(Plasma::Applet
*)), this, SLOT(appletAdded(Plasma::Applet
*)));
176 //TODO track containments too?
177 QList
<Applet
*>applets
=containment
->applets();
178 foreach (Applet
*applet
,applets
) {
179 d
->runningApplets
[applet
->name()]++;
180 d
->appletNames
.insert(applet
, applet
->name());
181 connect(applet
, SIGNAL(destroyed(QObject
*)), this, SLOT(appletDestroyed(QObject
*)));
185 kDebug() << d
->runningApplets
;
186 d
->itemModel
.setRunningApplets(d
->runningApplets
);
189 void AppletBrowserWidget::setApplication(const QString
& app
)
191 d
->application
= app
;
193 d
->itemModel
.setApplication(app
);
195 //FIXME: AFAIK this shouldn't be necessary ... but here it is. need to find out what in that
196 // maze of models and views is screwing up
197 d
->appletList
->setItemModel(&d
->itemModel
);
199 kDebug() << d
->runningApplets
;
200 d
->itemModel
.setRunningApplets(d
->runningApplets
);
203 QString
AppletBrowserWidget::application()
205 return d
->application
;
208 void AppletBrowserWidget::setContainment(Plasma::Containment
*containment
)
210 d
->containment
= containment
;
213 Containment
*AppletBrowserWidget::containment() const
215 return d
->containment
;
218 void AppletBrowserWidget::addApplet()
220 kDebug() << "Button ADD clicked";
221 if (!d
->containment
) {
225 foreach (AbstractItem
*item
, d
->appletList
->selectedItems()) {
226 PlasmaAppletItem
*selectedItem
= (PlasmaAppletItem
*) item
;
227 kDebug() << "Adding applet " << selectedItem
->name() << "to containment";
228 d
->containment
->addApplet(selectedItem
->pluginName(), selectedItem
->arguments());
232 void AppletBrowserWidget::appletAdded(Plasma::Applet
* applet
)
234 QString name
= applet
->name();
237 d
->runningApplets
[name
]++;
238 d
->appletNames
.insert(applet
, name
);
239 connect(applet
, SIGNAL(destroyed(QObject
*)), this, SLOT(appletDestroyed(QObject
*)));
240 d
->itemModel
.setRunningApplets(name
, d
->runningApplets
[name
]);
243 void AppletBrowserWidget::appletDestroyed(QObject
* applet
)
246 Plasma::Applet
* a
= (Plasma::Applet
*)applet
; //don't care if it's valid, just need the address
248 QString name
= d
->appletNames
.take(a
);
251 if (d
->runningApplets
.contains(name
)) {
252 count
= d
->runningApplets
[name
] - 1;
255 d
->runningApplets
.remove(name
);
257 d
->runningApplets
[name
] = count
;
261 d
->itemModel
.setRunningApplets(name
, count
);
264 void AppletBrowserWidget::destroyApplets(const QString
&name
)
266 if (!d
->containment
) {
270 Plasma::Corona
*c
= d
->containment
->corona();
272 //we've tried our best to get a corona
273 //we don't want just one containment, we want them all
275 kDebug() << "can't happen";
279 foreach (Containment
*containment
, c
->containments()) {
280 QList
<Applet
*> applets
= containment
->applets();
281 foreach (Applet
*applet
,applets
) {
282 d
->appletNames
.remove(applet
);
283 if (applet
->name() == name
) {
284 applet
->disconnect(this);
290 d
->runningApplets
.remove(name
);
291 d
->itemModel
.setRunningApplets(name
, 0);
294 void AppletBrowserWidget::downloadWidgets()
297 kDebug() << "GHNS button clicked";
300 void AppletBrowserWidget::openWidgetFile()
302 // TODO: if we already have one of these showing and the user clicks to add it again, show the same window?
303 OpenWidgetAssistant
*assistant
= new OpenWidgetAssistant(topLevelWidget());
304 assistant
->setAttribute(Qt::WA_DeleteOnClose
, true);
308 class AppletBrowser::Private
311 void init(AppletBrowser
*, Plasma::Containment
*);
312 AppletBrowserWidget
*widget
;
315 AppletBrowser::AppletBrowser(Plasma::Containment
* containment
, QWidget
* parent
, Qt::WindowFlags f
)
316 : KDialog(parent
, f
),
319 d
->init(this, containment
);
322 void AppletBrowser::Private::init(AppletBrowser
*q
, Plasma::Containment
*containment
)
324 widget
= new AppletBrowserWidget(containment
, q
);
326 q
->setMainWidget(widget
);
327 q
->setWindowTitle(i18n("Widgets"));
329 q
->setButtons(KDialog::Apply
| KDialog::Close
| KDialog::User1
);
330 q
->setButtonText(KDialog::Apply
, i18n("Add Widget"));
331 q
->setButtonText(KDialog::User1
, i18n("Install New Widgets"));
333 KMenu
*widgetsMenu
= new KMenu(i18n("Get New Widgets"), q
);
334 QAction
*action
= new QAction(KIcon("applications-internet"),
335 i18n("Download from the Internet"), q
);
336 connect(action
, SIGNAL(triggered(bool)), widget
, SLOT(downloadWidgets()));
337 widgetsMenu
->addAction(action
);
339 action
= new QAction(KIcon("applications-internet"),
340 i18n("Install from file"), q
);
341 connect(action
, SIGNAL(triggered(bool)), widget
, SLOT(openWidgetFile()));
342 widgetsMenu
->addAction(action
);
343 q
->button(KDialog::User1
)->setMenu(widgetsMenu
);
345 q
->setButtonToolTip(KDialog::Close
, i18n("Close the dialog"));
346 q
->setButtonWhatsThis(KDialog::Close
, i18n("<qt>When clicking <b>Close</b>, this dialog will be closed with no further action taken.</qt>"));
347 q
->setButtonToolTip(KDialog::Apply
, i18n("Add selected widgets"));
348 q
->setButtonWhatsThis(KDialog::Apply
, i18n("<qt>When clicking <b>Add Widget</b>, the selected widgets will be added to your desktop.</qt>"));
349 q
->setButtonToolTip(KDialog::User1
, i18n("Download new widgets"));
350 q
->setButtonWhatsThis(KDialog::User1
, i18n("<qt>When clicking <b>Get New Widgets</b>, a dialog will open to allow you to download new widgets. You need to be connected to the Internet.</qt>"));
352 connect(q
, SIGNAL(applyClicked()), widget
, SLOT(addApplet()));
354 q
->setInitialSize(QSize(400, 600));
355 KConfigGroup
cg(KGlobal::config(), "PlasmaAppletBrowserDialog");
356 q
->restoreDialogSize(cg
);
359 AppletBrowser::~AppletBrowser()
361 KConfigGroup
cg(KGlobal::config(), "PlasmaAppletBrowserDialog");
365 void AppletBrowser::setApplication(const QString
& app
)
367 d
->widget
->setApplication( app
);
370 QString
AppletBrowser::application()
372 return d
->widget
->application();
375 void AppletBrowser::setContainment(Plasma::Containment
*containment
)
377 d
->widget
->setContainment(containment
);
380 Containment
* AppletBrowser::containment() const
382 return d
->widget
->containment();
385 } // namespace Plasma
387 #include "appletbrowser.moc"