1
/***************************************************************************
4
* Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> *
5
* Copyright (C) 2008 Sebastian Sauer *
6
* Copyright (C) 2010 Marco Martin <notmart@gmail.com> *
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. *
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 *
16
* GNU General Public License for more details. *
18
* You should have received a copy of the GNU General Public License *
19
* along with this program; if not, write to the *
20
* Free Software Foundation, Inc., *
21
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
22
***************************************************************************/
26
#include <QtCore/QProcess>
27
#include <QtCore/QTimer>
28
#include <QtGui/QApplication>
29
#include <QtGui/QGraphicsLayout>
30
#include <QtGui/QGraphicsLinearLayout>
31
#include <QtGui/QVBoxLayout>
32
#include <QtGui/QIcon>
33
#include <QtGui/QLabel>
34
#include <QtGui/QListWidget>
35
#include <QtGui/QTreeWidget>
36
#include <QtGui/QCheckBox>
37
#include <QtGui/QPainter>
38
#include <QtGui/QX11Info>
39
#include <QStandardItemModel>
40
#include <QStyledItemDelegate>
44
#include <KConfigDialog>
46
#include <KWindowSystem>
47
#include <KCategorizedView>
48
#include <KCategorizedSortFilterProxyModel>
49
#include <KCategoryDrawer>
50
#include <KKeySequenceWidget>
52
#include <Solid/Device>
54
#include <plasma/extender.h>
55
#include <plasma/extenderitem.h>
56
#include <plasma/extendergroup.h>
57
#include <plasma/framesvg.h>
58
#include <plasma/widgets/label.h>
59
#include <plasma/theme.h>
60
#include <plasma/dataenginemanager.h>
61
#include <plasma/dataengine.h>
62
#include <Plasma/TabBar>
63
#include <Plasma/Containment>
64
#include <Plasma/Corona>
65
#include <Plasma/IconWidget>
66
#include <Plasma/Dialog>
67
#include <Plasma/WindowEffects>
71
#include "../core/manager.h"
74
static const bool DEFAULT_SHOW_APPS = true;
75
static const bool DEFAULT_SHOW_COMMUNICATION = true;
76
static const bool DEFAULT_SHOW_SERVICES = true;
77
static const bool DEFAULT_SHOW_HARDWARE = true;
78
static const bool DEFAULT_SHOW_UNKNOWN = true;
84
K_EXPORT_PLASMA_APPLET(systemtray, Applet)
87
Manager *Applet::s_manager = 0;
88
int Applet::s_managerUsage = 0;
90
Applet::Applet(QObject *parent, const QVariantList &arguments)
91
: Plasma::PopupApplet(parent, arguments),
98
s_manager = new SystemTray::Manager();
103
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout(this);
104
lay->setContentsMargins(0, 0, 0, 0);
105
m_background = new Plasma::FrameSvg(this);
106
m_background->setImagePath("widgets/systemtray");
107
m_background->setCacheAllRenderedFrames(true);
108
m_separator = new Plasma::FrameSvg(this);
109
m_separator->setImagePath("widgets/line");
110
m_separator->setCacheAllRenderedFrames(true);
111
m_taskArea = new TaskArea(this);
112
lay->addItem(m_taskArea);
113
connect(m_taskArea, SIGNAL(toggleHiddenItems()), this, SLOT(togglePopup()));
115
m_icons = new Plasma::Svg(this);
116
m_icons->setImagePath("widgets/configuration-icons");
118
setPopupIcon(QIcon());
119
setPassivePopup(false);
120
setPopupAlignment(Qt::AlignRight);
121
setAspectRatioMode(Plasma::IgnoreAspectRatio);
122
setHasConfigurationInterface(true);
124
connect(s_manager, SIGNAL(taskAdded(SystemTray::Task*)),
125
m_taskArea, SLOT(addTask(SystemTray::Task*)));
126
//TODO: we re-add the task when it changed: slightly silly!
127
connect(s_manager, SIGNAL(taskChanged(SystemTray::Task*)),
128
m_taskArea, SLOT(addTask(SystemTray::Task*)));
129
connect(s_manager, SIGNAL(taskRemoved(SystemTray::Task*)),
130
m_taskArea, SLOT(removeTask(SystemTray::Task*)));
132
connect(m_taskArea, SIGNAL(sizeHintChanged(Qt::SizeHint)),
133
this, SLOT(propogateSizeHintChange(Qt::SizeHint)));
135
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
136
this, SLOT(themeChanged()));
141
// stop listening to the manager
142
disconnect(s_manager, 0, this, 0);
144
// remove the taskArea so we can delete the widgets without it going nuts on us
147
foreach (Task *task, s_manager->tasks()) {
148
// we don't care about the task updates anymore
149
disconnect(task, 0, this, 0);
151
// delete our widget (if any); some widgets (such as the extender info one)
152
// may rely on the applet being around, so we need to delete them here and now
153
// while we're still kicking
154
delete task->widget(this, false);
158
if (s_managerUsage < 1) {
169
bool Applet::isFirstRun()
174
QGraphicsWidget *Applet::graphicsWidget()
176
return m_taskArea->hiddenTasksWidget();
179
void Applet::configChanged()
181
KConfigGroup gcg = globalConfig();
182
KConfigGroup cg = config();
184
const QStringList hiddenTypes = cg.readEntry("hidden", QStringList());
185
const QStringList alwaysShownTypes = cg.readEntry("alwaysShown", QStringList());
186
m_taskArea->setHiddenTypes(hiddenTypes);
187
m_taskArea->setAlwaysShownTypes(alwaysShownTypes);
189
m_shownCategories.clear();
191
if (cg.readEntry("ShowApplicationStatus", gcg.readEntry("ShowApplicationStatus", DEFAULT_SHOW_APPS))) {
192
m_shownCategories.insert(Task::ApplicationStatus);
195
if (cg.readEntry("ShowCommunications", gcg.readEntry("ShowCommunications", DEFAULT_SHOW_COMMUNICATION))) {
196
m_shownCategories.insert(Task::Communications);
199
if (cg.readEntry("ShowSystemServices", gcg.readEntry("ShowSystemServices", DEFAULT_SHOW_SERVICES))) {
200
m_shownCategories.insert(Task::SystemServices);
203
if (cg.readEntry("ShowHardware", gcg.readEntry("ShowHardware", DEFAULT_SHOW_HARDWARE))) {
204
m_shownCategories.insert(Task::Hardware);
207
if (cg.readEntry("ShowUnknown", gcg.readEntry("ShowUnknown", DEFAULT_SHOW_UNKNOWN))) {
208
m_shownCategories.insert(Task::UnknownCategory);
211
s_manager->loadApplets(this);
212
m_taskArea->syncTasks(s_manager->tasks());
216
void Applet::popupEvent(bool)
218
m_taskArea->updateUnhideToolIcon();
221
bool Applet::isPopupShowing() const
223
if (PopupApplet::isPopupShowing()) {
227
foreach (Task *task, s_manager->tasks()) {
228
Plasma::Applet *applet = qobject_cast<Plasma::Applet*>(task->widget(const_cast<Applet *>(this), false));
230
if (applet->isPopupShowing()) {
239
void Applet::constraintsEvent(Plasma::Constraints constraints)
241
if (constraints & Plasma::FormFactorConstraint) {
242
QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Preferred);
243
policy.setHeightForWidth(true);
244
bool vertical = formFactor() == Plasma::Vertical;
247
policy.setVerticalPolicy(QSizePolicy::Expanding);
249
policy.setHorizontalPolicy(QSizePolicy::Expanding);
252
setSizePolicy(policy);
253
m_taskArea->setSizePolicy(policy);
254
m_taskArea->setOrientation(vertical ? Qt::Vertical : Qt::Horizontal);
257
if (constraints & Plasma::LocationConstraint) {
258
m_taskArea->setLocation(location());
261
if (constraints & Plasma::SizeConstraint) {
265
if (constraints & Plasma::ImmutableConstraint) {
266
if (m_visibleItemsInterface) {
267
bool visible = (immutability() == Plasma::UserImmutable);
268
m_visibleItemsUi.visibleItemsView->setEnabled(immutability() == Plasma::Mutable);
269
m_visibleItemsUi.unlockLabel->setVisible(visible);
270
m_visibleItemsUi.unlockButton->setVisible(visible);
274
if (constraints & Plasma::StartupCompletedConstraint) {
275
QTimer::singleShot(0, this, SLOT(checkDefaultApplets()));
279
s_manager->forwardConstraintsEvent(constraints, this);
282
SystemTray::Manager *Applet::manager() const
287
QSet<Task::Category> Applet::shownCategories() const
289
return m_shownCategories;
292
void Applet::themeChanged()
298
void Applet::checkSizes()
300
Plasma::FormFactor f = formFactor();
301
qreal leftMargin, topMargin, rightMargin, bottomMargin;
302
m_background->setElementPrefix(QString());
303
m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders);
304
m_background->getMargins(leftMargin, topMargin, rightMargin, bottomMargin);
306
QSizeF minSize = m_taskArea->effectiveSizeHint(Qt::MinimumSize);
307
if (f == Plasma::Horizontal && minSize.height() > size().height() - topMargin - bottomMargin) {
308
m_background->setEnabledBorders(Plasma::FrameSvg::LeftBorder | Plasma::FrameSvg::RightBorder);
309
layout()->setContentsMargins(leftMargin, 0, rightMargin, 0);
310
} else if (f == Plasma::Vertical && minSize.width() > size().width() - leftMargin - rightMargin) {
311
m_background->setEnabledBorders(Plasma::FrameSvg::TopBorder | Plasma::FrameSvg::BottomBorder);
312
layout()->setContentsMargins(0, topMargin, 0, bottomMargin);
314
layout()->setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin);
317
static_cast<QGraphicsLayoutItem*>(m_taskArea)->updateGeometry();
319
QSizeF preferredSize = m_taskArea->effectiveSizeHint(Qt::PreferredSize);
321
preferredSize.setWidth(preferredSize.width() + leftMargin + rightMargin);
322
preferredSize.setHeight(preferredSize.height() + topMargin + bottomMargin);
323
setPreferredSize(preferredSize);
325
QSizeF actualSize = size();
327
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
328
if (f == Plasma::Horizontal) {
329
setMinimumSize(preferredSize.width(), 0);
330
setMaximumSize(preferredSize.width(), QWIDGETSIZE_MAX);
331
} else if (f == Plasma::Vertical) {
332
setMinimumSize(0, preferredSize.height());
333
setMaximumSize(QWIDGETSIZE_MAX, preferredSize.height());
334
} else if (f == Plasma::Planar) {
335
setMinimumSize(preferredSize);
340
void Applet::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
344
QRect normalRect = contentsRect;
345
m_background->setElementPrefix(QString());
347
const int leftEasement = m_taskArea->leftEasement();
350
QRect firstRect(normalRect);
352
if (formFactor() == Plasma::Vertical) {
353
int margin = m_background->marginSize(Plasma::TopMargin);
354
firstRect.setHeight(leftEasement + margin);
355
normalRect.setY(firstRect.bottom() + 1);
356
} else if (QApplication::layoutDirection() == Qt::RightToLeft) {
357
int margin = m_background->marginSize(Plasma::RightMargin);
358
normalRect.setWidth(normalRect.width() - leftEasement - margin);
359
firstRect.setX(normalRect.right() + 1);
361
int margin = m_background->marginSize(Plasma::LeftMargin);
362
firstRect.setWidth(leftEasement + margin);
363
normalRect.setX(firstRect.right() + 1);
366
if (m_background->hasElementPrefix("firstelements")) {
367
m_background->setElementPrefix("firstelements");
369
m_background->setElementPrefix("lastelements");
371
m_background->resizeFrame(contentsRect.size());
374
painter->setClipRect(firstRect, Qt::IntersectClip);
375
m_background->paintFrame(painter, contentsRect, QRectF(QPointF(0, 0), contentsRect.size()));
379
const int rightEasement = m_taskArea->rightEasement();
380
if(rightEasement > 0)
382
QRect lastRect(normalRect);
384
if (formFactor() == Plasma::Vertical) {
385
int margin = m_background->marginSize(Plasma::BottomMargin);
386
normalRect.setHeight(normalRect.height() - rightEasement - margin);
387
lastRect.setY(normalRect.bottom() + 1);
388
} else if (QApplication::layoutDirection() == Qt::RightToLeft) {
389
int margin = m_background->marginSize(Plasma::LeftMargin);
390
lastRect.setWidth(rightEasement + margin);
391
normalRect.setX(lastRect.right() + 1);
393
int margin = m_background->marginSize(Plasma::RightMargin);
394
normalRect.setWidth(normalRect.width() - rightEasement - margin);
395
lastRect.setX(normalRect.right() + 1);
398
m_background->setElementPrefix("lastelements");
399
m_background->resizeFrame(contentsRect.size());
402
painter->setClipRect(lastRect, Qt::IntersectClip);
403
m_background->paintFrame(painter, contentsRect, QRectF(QPointF(0, 0), contentsRect.size()));
407
m_background->setElementPrefix(QString());
408
m_background->resizeFrame(contentsRect.size());
411
painter->setClipRect(normalRect, Qt::IntersectClip);
412
m_background->paintFrame(painter, contentsRect, QRectF(QPointF(0, 0), contentsRect.size()));
415
if (leftEasement > 0) {
416
if (formFactor() == Plasma::Vertical) {
417
if (m_separator->hasElement("horizontal-line")) {
418
QSize s = m_separator->elementRect("horizontal-line").size().toSize();
419
m_separator->paint(painter, QRect(normalRect.topLeft() - QPoint(0, s.height() / 2),
420
QSize(normalRect.width(), s.height())), "horizontal-line");
422
} else if (m_separator->hasElement("vertical-line")) {
423
QSize s = m_separator->elementRect("vertical-line").size().toSize();
424
if (QApplication::layoutDirection() == Qt::RightToLeft) {
425
m_separator->paint(painter, QRect(normalRect.topRight() - QPoint(s.width() / 2, 0),
426
QSize(s.width(), normalRect.height())), "vertical-line");
428
m_separator->paint(painter, QRect(normalRect.topLeft() - QPoint(s.width() / 2, 0),
429
QSize(s.width(), normalRect.height())), "vertical-line");
436
void Applet::propogateSizeHintChange(Qt::SizeHint which)
439
emit sizeHintChanged(which);
442
void Applet::createConfigurationInterface(KConfigDialog *parent)
444
if (!m_autoHideInterface) {
445
m_autoHideInterface = new QWidget();
446
m_visibleItemsInterface = new QWidget();
448
m_autoHideUi.setupUi(m_autoHideInterface.data());
450
m_visibleItemsUi.setupUi(m_visibleItemsInterface.data());
452
QAction *unlockAction = 0;
453
if (containment() && containment()->corona()) {
454
unlockAction = containment()->corona()->action("lock widgets");
458
disconnect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), this, SLOT(unlockContainment()));
459
connect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), unlockAction, SLOT(trigger()), Qt::UniqueConnection);
461
disconnect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), unlockAction, SLOT(trigger()));
462
connect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), this, SLOT(unlockContainment()), Qt::UniqueConnection);
466
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
467
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
469
parent->addPage(m_visibleItemsInterface.data(), i18n("Display"),
470
"preferences-desktop-notification",
471
i18n("Choose which information to show"));
472
parent->addPage(m_autoHideInterface.data(), i18n("Entries"), "configure-toolbars");
474
bool visible = (immutability() == Plasma::UserImmutable);
475
//FIXME: always showing the scrollbar is due to a bug somewhere in QAbstractScrollArea,
476
//QListView and/or KCategorizedView; without it, under certain circumstances it will
477
//go into an infinite loop. too many people are running into this problem, so we are
478
//working around the problem rather than waiting for an upstream fix, which is against
480
//to determine if this line is no longer needed in the future, comment it out, lock
481
//widgets, then call up the configuration dialog for a system tray applet and click
482
//on the "unlock widgets" button.
483
m_visibleItemsUi.visibleItemsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
484
m_visibleItemsUi.visibleItemsView->setEnabled(immutability() == Plasma::Mutable);
485
m_visibleItemsUi.unlockLabel->setVisible(visible);
486
m_visibleItemsUi.unlockButton->setVisible(visible);
488
m_visibleItemsUi.visibleItemsView->setCategoryDrawer(new KCategoryDrawerV3(m_visibleItemsUi.visibleItemsView));
489
m_visibleItemsUi.visibleItemsView->setMouseTracking(true);
490
m_visibleItemsUi.visibleItemsView->setVerticalScrollMode(QListView::ScrollPerPixel);
492
KCategorizedSortFilterProxyModel *visibleItemsModel = new KCategorizedSortFilterProxyModel(m_visibleItemsUi.visibleItemsView);
493
visibleItemsModel->setCategorizedModel(true);
495
m_visibleItemsSourceModel = new QStandardItemModel(m_visibleItemsUi.visibleItemsView);
496
visibleItemsModel->setSourceModel(m_visibleItemsSourceModel.data());
498
m_visibleItemsUi.visibleItemsView->setModel(visibleItemsModel);
501
m_autoHideUi.icons->clear();
502
if (m_visibleItemsSourceModel) {
503
m_visibleItemsSourceModel.data()->clear();
506
QMultiMap<QString, Task *> sortedTasks;
507
foreach (Task *task, s_manager->tasks()) {
508
if (!m_shownCategories.contains(task->category())) {
512
if (!task->widget(this, false)) {
513
// it is not being used by this widget
517
sortedTasks.insert(task->name(), task);
520
KConfigGroup gcg = globalConfig();
521
KConfigGroup cg = config();
522
KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts");
524
foreach (Task *task, sortedTasks) {
525
QTreeWidgetItem *listItem = new QTreeWidgetItem(m_autoHideUi.icons);
526
KComboBox *itemCombo = new KComboBox(m_autoHideUi.icons);
527
listItem->setText(0, task->name());
528
listItem->setIcon(0, task->icon());
529
listItem->setFlags(Qt::ItemIsEnabled);
530
listItem->setData(0, Qt::UserRole, task->typeId());
532
itemCombo->addItem(i18nc("Item will be automatically shown or hidden from the systray", "Auto"));
533
itemCombo->addItem(i18nc("Item is never visible in the systray", "Hidden"));
534
itemCombo->addItem(i18nc("Item is always visible in the systray", "Always Visible"));
536
if (task->hidden() & Task::UserHidden) {
537
itemCombo->setCurrentIndex(1);
538
} else if (m_taskArea->alwaysShownTypes().contains(task->typeId())) {
539
itemCombo->setCurrentIndex(2);
541
itemCombo->setCurrentIndex(0);
543
m_autoHideUi.icons->setItemWidget(listItem, 1, itemCombo);
545
KKeySequenceWidget *button = new KKeySequenceWidget(m_autoHideUi.icons);
547
Plasma::IconWidget *icon = qobject_cast<Plasma::IconWidget *>(task->widget(this));
548
Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(task->widget(this));
551
QString shortcutText = shortcutsConfig.readEntryUntranslated(icon->action()->objectName(), QString());
552
button->setKeySequence(shortcutText);
553
} else if (task && applet) {
554
button->setKeySequence(applet->globalShortcut().primary());
555
//no way to have a shortcut for the fdo protocol
557
button->setEnabled(false);
559
m_autoHideUi.icons->setItemWidget(listItem, 2, button);
560
m_autoHideUi.icons->addTopLevelItem(listItem);
562
// try to make sure we have enough width!
564
for (int i = 0; i < m_autoHideUi.icons->header()->count(); ++i) {
565
totalWidth += m_autoHideUi.icons->columnWidth(i);
567
m_autoHideUi.icons->setMinimumWidth(totalWidth + style()->pixelMetric(QStyle::PM_ScrollBarExtent));
569
connect(itemCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
570
connect(button, SIGNAL(keySequenceChanged(QKeySequence)), parent, SLOT(settingsModified()));
574
const QString itemCategories = i18nc("Categories of items in the systemtray that will be shown or hidden", "Shown Item Categories");
576
QStandardItem *applicationStatusItem = new QStandardItem();
577
applicationStatusItem->setText(i18nc("Systemtray items that describe the status of a generic application", "Application status"));
578
applicationStatusItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
579
bool checked = cg.readEntry("ShowApplicationStatus",
580
gcg.readEntry("ShowApplicationStatus", DEFAULT_SHOW_APPS));
581
applicationStatusItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
582
applicationStatusItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
583
applicationStatusItem->setData("ShowApplicationStatus", Qt::UserRole+1);
584
m_visibleItemsSourceModel.data()->appendRow(applicationStatusItem);
586
QStandardItem *communicationsItem = new QStandardItem();
587
communicationsItem->setText(i18nc("Items communication related, such as chat or email clients", "Communications"));
588
communicationsItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
589
checked = cg.readEntry("ShowCommunications",
590
gcg.readEntry("ShowCommunications", DEFAULT_SHOW_COMMUNICATION));
591
communicationsItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
592
communicationsItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
593
communicationsItem->setData("ShowCommunications", Qt::UserRole+1);
594
m_visibleItemsSourceModel.data()->appendRow(communicationsItem);
596
QStandardItem *systemServicesItem = new QStandardItem();
597
systemServicesItem->setText(i18nc("Items about the status of the system, such as a filesystem indexer", "System services"));
598
systemServicesItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
599
checked = cg.readEntry("ShowSystemServices",
600
gcg.readEntry("ShowSystemServices", DEFAULT_SHOW_SERVICES));
601
systemServicesItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
602
systemServicesItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
603
systemServicesItem->setData("ShowSystemServices", Qt::UserRole+1);
604
m_visibleItemsSourceModel.data()->appendRow(systemServicesItem);
606
QStandardItem *hardwareControlItem = new QStandardItem();
607
hardwareControlItem->setText(i18nc("Items about hardware, such as battery or volume control", "Hardware control"));
608
hardwareControlItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
609
checked = cg.readEntry("ShowHardware",
610
gcg.readEntry("ShowHardware", DEFAULT_SHOW_HARDWARE));
611
hardwareControlItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
612
hardwareControlItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
613
hardwareControlItem->setData("ShowHardware", Qt::UserRole+1);
614
m_visibleItemsSourceModel.data()->appendRow(hardwareControlItem);
616
QStandardItem *unknownItem = new QStandardItem();
617
unknownItem->setText(i18nc("Other uncategorized systemtray items", "Miscellaneous"));
618
unknownItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
619
checked = cg.readEntry("ShowUnknown",
620
gcg.readEntry("ShowUnknown", DEFAULT_SHOW_UNKNOWN));
621
unknownItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
622
unknownItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
623
unknownItem->setData("ShowUnknown", Qt::UserRole+1);
624
m_visibleItemsSourceModel.data()->appendRow(unknownItem);
626
QStringList ownApplets = s_manager->applets(this);
628
foreach (const KPluginInfo &info, Plasma::Applet::listAppletInfo()) {
629
KService::Ptr service = info.service();
630
if (service->property("X-Plasma-NotificationArea", QVariant::Bool).toBool()) {
631
QStandardItem *item = new QStandardItem();
632
item->setText(service->name());
633
item->setIcon(KIcon(service->icon()));
634
item->setCheckable(true);
635
item->setCheckState(ownApplets.contains(info.pluginName()) ? Qt::Checked : Qt::Unchecked);
636
item->setData(i18nc("Extra items to be manually added in the systray, such as little Plasma widgets", "Extra Items"), KCategorizedSortFilterProxyModel::CategoryDisplayRole);
637
item->setData(info.pluginName(), Qt::UserRole+2);
638
m_visibleItemsSourceModel.data()->appendRow(item);
642
connect(m_visibleItemsSourceModel.data(), SIGNAL(itemChanged(QStandardItem*)), parent, SLOT(settingsModified()));
645
//not always the corona lock action is available: netbook locks per-containment
646
void Applet::unlockContainment()
648
if (containment() && containment()->immutability() == Plasma::UserImmutable) {
649
containment()->setImmutability(Plasma::Mutable);
653
void Applet::configAccepted()
655
KConfigGroup cg = config();
656
KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts");
658
QStringList hiddenTypes;
659
QStringList alwaysShownTypes;
660
QTreeWidget *hiddenList = m_autoHideUi.icons;
661
for (int i = 0; i < hiddenList->topLevelItemCount(); ++i) {
662
QTreeWidgetItem *item = hiddenList->topLevelItem(i);
663
KComboBox *itemCombo = static_cast<KComboBox *>(hiddenList->itemWidget(item, 1));
664
//kDebug() << (item->checkState() == Qt::Checked) << item->data(Qt::UserRole).toString();
665
const QString taskTypeId = item->data(0, Qt::UserRole).toString();
666
if (itemCombo->currentIndex() == 1) {
668
hiddenTypes << taskTypeId;
669
} else if (itemCombo->currentIndex() == 2) {
671
alwaysShownTypes << taskTypeId;
674
KKeySequenceWidget *keySeq = static_cast<KKeySequenceWidget *>(hiddenList->itemWidget(item, 2));
675
QKeySequence seq = keySeq->keySequence();
677
//FIXME: terribly inefficient
678
foreach (Task *candidateTask, s_manager->tasks()) {
679
if (candidateTask->typeId() == taskTypeId) {
680
task = candidateTask;
686
QGraphicsWidget *widget = task->widget(this);
689
Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(widget);
690
Plasma::IconWidget *icon = qobject_cast<Plasma::IconWidget *>(widget);
692
applet->setGlobalShortcut(KShortcut(seq));
694
KAction *action = qobject_cast<KAction *>(icon->action());
695
if (action && !seq.isEmpty()) {
696
action->setGlobalShortcut(KShortcut(seq),
697
KAction::ShortcutTypes(KAction::ActiveShortcut | KAction::DefaultShortcut),
698
KAction::NoAutoloading);
699
shortcutsConfig.writeEntry(action->objectName(), seq.toString());
700
} else if (seq.isEmpty()) {
701
action->forgetGlobalShortcut();
702
shortcutsConfig.deleteEntry(action->objectName());
709
cg.writeEntry("hidden", hiddenTypes);
710
cg.writeEntry("alwaysShown", alwaysShownTypes);
712
QStringList applets = s_manager->applets(this);
714
for (int i = 0; i <= m_visibleItemsSourceModel.data()->rowCount() - 1; i++) {
715
QModelIndex index = m_visibleItemsSourceModel.data()->index(i, 0);
716
QString itemCategory = index.data(Qt::UserRole+1).toString();
717
QString appletName = index.data(Qt::UserRole+2).toString();
718
if (!itemCategory.isEmpty()) {
719
QStandardItem *item = m_visibleItemsSourceModel.data()->itemFromIndex(index);
720
cg.writeEntry(itemCategory, (item->checkState() == Qt::Checked));
721
} else if (!appletName.isEmpty()){
722
QStandardItem *item = m_visibleItemsSourceModel.data()->itemFromIndex(index);
724
if (item->checkState() != Qt::Unchecked && !applets.contains(appletName)) {
725
s_manager->addApplet(appletName, this);
728
if (item->checkState() == Qt::Checked) {
729
applets.removeAll(appletName);
734
foreach (const QString &appletName, applets) {
735
s_manager->removeApplet(appletName, this);
738
emit configNeedsSaving();
741
void Applet::checkDefaultApplets()
743
if (config().readEntry("DefaultAppletsAdded", false)) {
749
QStringList applets = s_manager->applets(this);
750
if (!applets.contains("org.kde.networkmanagement")) {
751
s_manager->addApplet("org.kde.networkmanagement", this);
754
if (!applets.contains("notifier")) {
755
s_manager->addApplet("notifier", this);
758
if (!applets.contains("notifications")) {
759
s_manager->addApplet("notifications", this);
762
if (!applets.contains("battery")) {
763
Plasma::DataEngineManager *engines = Plasma::DataEngineManager::self();
764
Plasma::DataEngine *power = engines->loadEngine("powermanagement");
766
const QStringList &batteries = power->query("Battery")["Sources"].toStringList();
767
if (!batteries.isEmpty()) {
768
s_manager->addApplet("battery", this);
771
engines->unloadEngine("powermanagement");
774
config().writeEntry("DefaultAppletsAdded", true);
779
#include "applet.moc"