/*************************************************************************** * applet.cpp * * * * Copyright (C) 2008 Jason Stubbs * * Copyright (C) 2008 Sebastian Sauer * * Copyright (C) 2010 Marco Martin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "applet.h" #include "widgetitem.h" #include "mouseredirectarea.h" #include "../protocols/dbussystemtray/dbussystemtraytask.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../core/manager.h" static const bool DEFAULT_SHOW_APPS = true; static const bool DEFAULT_SHOW_COMMUNICATION = true; static const bool DEFAULT_SHOW_SERVICES = true; static const bool DEFAULT_SHOW_HARDWARE = true; static const bool DEFAULT_SHOW_UNKNOWN = true; static const char KlipperName[] = "Klipper"; namespace SystemTray { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace { static void _RegisterEnums(QDeclarativeContext *context, const QMetaObject &meta) { for (int i = 0, s = meta.enumeratorCount(); i < s; ++i) { QMetaEnum e = meta.enumerator(i); for (int i = 0, s = e.keyCount(); i < s; ++i) { context->setContextProperty(e.key(i), e.value(i)); } } } } // namespace K_EXPORT_PLASMA_APPLET(systemtray, Applet) Manager *Applet::s_manager = 0; int Applet::s_managerUsage = 0; Applet::Applet(QObject *parent, const QVariantList &arguments) : Plasma::Applet(parent, arguments), m_widget(0), m_firstRun(true) { if (!s_manager) { s_manager = new SystemTray::Manager(); } ++s_managerUsage; setAspectRatioMode(Plasma::IgnoreAspectRatio); setHasConfigurationInterface(true); } Applet::~Applet() { // stop listening to the manager disconnect(s_manager, 0, this, 0); foreach (Task *task, s_manager->tasks()) { // we don't care about the task updates anymore disconnect(task, 0, this, 0); // delete our widget (if any); some widgets (such as the extender info one) // may rely on the applet being around, so we need to delete them here and now // while we're still kicking if (task->isWidget()) delete task->widget(this, false); } delete m_widget; --s_managerUsage; if (s_managerUsage < 1) { delete s_manager; s_manager = 0; s_managerUsage = 0; } } void Applet::init() { // First of all, we have to register new QML types because they won't be registered later qmlRegisterType("Private", 0, 1, "WidgetItem"); qmlRegisterType("Private", 0, 1, "MouseRedirectArea"); // Find data directory KStandardDirs std_dirs; QStringList dirs = std_dirs.findDirs("data", SYSTEMTRAY_DATA_INSTALL_DIR); QString data_path; if (!dirs.isEmpty()) { data_path = dirs.at(0); } else { setFailedToLaunch(true, "Data directory for applet isn't found"); return; } // Create declarative engine, etc m_widget = new Plasma::DeclarativeWidget(this); m_widget->setInitializationDelayed(true); connect(m_widget, SIGNAL(finished()), this, SLOT(_onWidgetCreationFinished())); m_widget->setQmlPath(data_path + QString::fromLatin1("contents/ui/main.qml")); if (!m_widget->engine() || !m_widget->engine()->rootContext() || !m_widget->engine()->rootContext()->isValid() || m_widget->mainComponent()->isError()) { QString reason; foreach (QDeclarativeError error, m_widget->mainComponent()->errors()) { reason += error.toString(); } setFailedToLaunch(true, reason); return; } // setup context add global object "plasmoid" QDeclarativeContext *root_context = m_widget->engine()->rootContext(); root_context->setContextProperty("plasmoid", this); // add enumerations manually to global context _RegisterEnums(root_context, Task::staticMetaObject); _RegisterEnums(root_context, SystemTray::Applet::staticMetaObject); // add declarative widget to our applet QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); layout->addItem(m_widget); } void Applet::_onAddedTask(Task *task) { if (task->isWidget()) { // If task is presented as a widget then we should check that widget if (!task->isEmbeddable(this)) { //was a widget created previously? kill it QGraphicsWidget *widget = task->widget(this, false); if (widget) { task->abandon(this); } return; } QGraphicsWidget *widget = task->widget(this); if (!widget) { return; } //If the applet doesn't want to show FDO tasks, remove (not just hide) any of them //if the dbus icon has a category that the applet doesn't want to show remove it if (!m_shownCategories.contains(task->category()) && !qobject_cast(widget)) { task->abandon(this); return; } } else if (!m_shownCategories.contains(task->category())) { return; } // provide task to qml code emit newTask(task); DBusSystemTrayTask *dbus_task = qobject_cast(task); if (dbus_task && !dbus_task->objectName().isEmpty() && dbus_task->shortcut().isEmpty()) { // try to set shortcut bool is_klipper = false; QString default_shortcut; if (dbus_task->name() == KlipperName) { // for klipper we have to read its default hotkey from its config is_klipper = true; QString file = KStandardDirs::locateLocal("config", "kglobalshortcutsrc"); KConfig config(file); KConfigGroup cg(&config, "klipper"); QStringList shortcutTextList = cg.readEntry("show_klipper_popup", QStringList()); if (shortcutTextList.size() >= 2) { default_shortcut = shortcutTextList.first(); if (default_shortcut.isEmpty()) { default_shortcut = shortcutTextList[1]; } } if (default_shortcut.isEmpty()) { default_shortcut = "Ctrl+Alt+V"; } } QString action_name = _getActionName(task); KConfigGroup cg = config(); KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts"); QString shortcut = shortcutsConfig.readEntryUntranslated(action_name, default_shortcut); dbus_task->setShortcut(shortcut); if (is_klipper && shortcut == default_shortcut) { // we have to write klipper's hotkey to config if (shortcut.isEmpty()) shortcutsConfig.deleteEntry(action_name); else shortcutsConfig.writeEntry(action_name, shortcut); } } } void Applet::_onRemovedTask(Task *task) { //remove task from QML code emit deletedTask(task); } void Applet::_onStatusChangedTask() { foreach (Task *task, s_manager->tasks()) { if (task->status() == Task::NeedsAttention) { setStatus(Plasma::NeedsAttentionStatus); return; } } setStatus(Plasma::PassiveStatus); } void Applet::_onWidgetCreationFinished() { // add already existing tasks QList tasks = s_manager->tasks(); foreach (Task *t, tasks) { _onAddedTask(t); } connect(s_manager, SIGNAL(taskAdded(SystemTray::Task*)), this, SLOT(_onAddedTask(SystemTray::Task*))); connect(s_manager, SIGNAL(taskRemoved(SystemTray::Task*)), this, SLOT(_onRemovedTask(SystemTray::Task*))); connect(s_manager, SIGNAL(taskStatusChanged()), this, SLOT(_onStatusChangedTask())); } bool Applet::isFirstRun() { return m_firstRun; } void Applet::configChanged() { KConfigGroup gcg = globalConfig(); KConfigGroup cg = config(); m_hiddenTypes = QSet::fromList(cg.readEntry("hidden", QStringList())); m_alwaysShownTypes = QSet::fromList(cg.readEntry("alwaysShown", QStringList())); m_shownCategories.clear(); if (cg.readEntry("ShowApplicationStatus", gcg.readEntry("ShowApplicationStatus", DEFAULT_SHOW_APPS))) { m_shownCategories.insert(Task::ApplicationStatus); } if (cg.readEntry("ShowCommunications", gcg.readEntry("ShowCommunications", DEFAULT_SHOW_COMMUNICATION))) { m_shownCategories.insert(Task::Communications); } if (cg.readEntry("ShowSystemServices", gcg.readEntry("ShowSystemServices", DEFAULT_SHOW_SERVICES))) { m_shownCategories.insert(Task::SystemServices); } if (cg.readEntry("ShowHardware", gcg.readEntry("ShowHardware", DEFAULT_SHOW_HARDWARE))) { m_shownCategories.insert(Task::Hardware); } if (cg.readEntry("ShowUnknown", gcg.readEntry("ShowUnknown", DEFAULT_SHOW_UNKNOWN))) { m_shownCategories.insert(Task::UnknownCategory); } s_manager->loadApplets(this); // notify QML code about new user's preferences emit visibilityPreferenceChanged(); } QString Applet::_getActionName(Task *task) const { if (task->objectName().isEmpty()) return QString(""); return task->objectName() + QString("-") + QString::number(this->id()); } void Applet::constraintsEvent(Plasma::Constraints constraints) { if (constraints & Plasma::FormFactorConstraint) { emit formFactorChanged(); } if (constraints & Plasma::LocationConstraint) { emit locationChanged(); } if (constraints & Plasma::ImmutableConstraint) { if (m_visibleItemsInterface) { bool visible = (immutability() == Plasma::UserImmutable); m_visibleItemsUi.visibleItemsView->setEnabled(immutability() == Plasma::Mutable); m_visibleItemsUi.unlockLabel->setVisible(visible); m_visibleItemsUi.unlockButton->setVisible(visible); } } if (constraints & Plasma::StartupCompletedConstraint) { QTimer::singleShot(0, this, SLOT(checkDefaultApplets())); configChanged(); } s_manager->forwardConstraintsEvent(constraints, this); } SystemTray::Manager *Applet::manager() const { return s_manager; } QSet Applet::shownCategories() const { return m_shownCategories; } void Applet::propogateSizeHintChange(Qt::SizeHint which) { emit sizeHintChanged(which); } void Applet::createConfigurationInterface(KConfigDialog *parent) { if (!m_autoHideInterface) { m_autoHideInterface = new QWidget(); m_visibleItemsInterface = new QWidget(); m_autoHideUi.setupUi(m_autoHideInterface.data()); m_autoHideUi.icons->header()->setResizeMode(QHeaderView::ResizeToContents); m_visibleItemsUi.setupUi(m_visibleItemsInterface.data()); QAction *unlockAction = 0; if (containment() && containment()->corona()) { unlockAction = containment()->corona()->action("lock widgets"); } if (unlockAction) { disconnect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), this, SLOT(unlockContainment())); connect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), unlockAction, SLOT(trigger()), Qt::UniqueConnection); } else { disconnect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), unlockAction, SLOT(trigger())); connect(m_visibleItemsUi.unlockButton, SIGNAL(clicked()), this, SLOT(unlockContainment()), Qt::UniqueConnection); } connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); parent->addPage(m_visibleItemsInterface.data(), i18n("Display"), "preferences-desktop-notification", i18n("Choose which information to show")); parent->addPage(m_autoHideInterface.data(), i18n("Entries"), "configure-toolbars"); bool visible = (immutability() == Plasma::UserImmutable); //FIXME: always showing the scrollbar is due to a bug somewhere in QAbstractScrollArea, //QListView and/or KCategorizedView; without it, under certain circumstances it will //go into an infinite loop. too many people are running into this problem, so we are //working around the problem rather than waiting for an upstream fix, which is against //our usual policy. //to determine if this line is no longer needed in the future, comment it out, lock //widgets, then call up the configuration dialog for a system tray applet and click //on the "unlock widgets" button. m_visibleItemsUi.unlockLabel->setVisible(visible); m_visibleItemsUi.unlockButton->setVisible(visible); m_visibleItemsUi.visibleItemsView->setEnabled(immutability() == Plasma::Mutable); m_visibleItemsUi.visibleItemsView->setCategoryDrawer(new KCategoryDrawer(m_visibleItemsUi.visibleItemsView)); m_visibleItemsUi.visibleItemsView->setMouseTracking(true); m_visibleItemsUi.visibleItemsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_visibleItemsUi.visibleItemsView->setVerticalScrollMode(QListView::ScrollPerPixel); KCategorizedSortFilterProxyModel *visibleItemsModel = new KCategorizedSortFilterProxyModel(m_visibleItemsUi.visibleItemsView); visibleItemsModel->setCategorizedModel(true); m_visibleItemsSourceModel = new QStandardItemModel(m_visibleItemsUi.visibleItemsView); visibleItemsModel->setSourceModel(m_visibleItemsSourceModel.data()); m_visibleItemsUi.visibleItemsView->setModel(visibleItemsModel); } QStandardItemModel *visibleItemsSourceModel = m_visibleItemsSourceModel.data(); // the lifespan of m_visibleItemsSourceModel is tied to the config UI, so it // should always exist at this point Q_ASSERT(visibleItemsSourceModel); visibleItemsSourceModel->clear(); m_autoHideUi.icons->clear(); QMultiMap sortedTasks; foreach (Task *task, s_manager->tasks()) { if (!m_shownCategories.contains(task->category())) { continue; } if (task->isWidget() && !task->widget(this, false)) { // it is not being used by this widget continue; } sortedTasks.insert(task->name(), task); } KConfigGroup gcg = globalConfig(); KConfigGroup cg = config(); KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts"); foreach (Task *task, sortedTasks) { QTreeWidgetItem *listItem = new QTreeWidgetItem(m_autoHideUi.icons); KComboBox *itemCombo = new KComboBox(m_autoHideUi.icons); listItem->setText(0, task->name()); listItem->setIcon(0, task->icon()); listItem->setFlags(Qt::ItemIsEnabled); listItem->setData(0, Qt::UserRole, task->taskId()); itemCombo->addItem(i18nc("Item will be automatically shown or hidden from the systray", "Auto")); itemCombo->addItem(i18nc("Item is never visible in the systray", "Hidden")); itemCombo->addItem(i18nc("Item is always visible in the systray", "Always Visible")); if (m_hiddenTypes.contains(task->taskId())) { itemCombo->setCurrentIndex(1); } else if (m_alwaysShownTypes.contains(task->taskId())) { itemCombo->setCurrentIndex(2); } else { itemCombo->setCurrentIndex(0); } m_autoHideUi.icons->setItemWidget(listItem, 1, itemCombo); KKeySequenceWidget *button = new KKeySequenceWidget(m_autoHideUi.icons); DBusSystemTrayTask *dbus_task = qobject_cast(task); Plasma::Applet *applet = qobject_cast(task->widget(this)); if (task && dbus_task && !dbus_task->objectName().isEmpty()) { QString action_name = _getActionName(task); QString shortcutText = shortcutsConfig.readEntryUntranslated(action_name, QString()); button->setKeySequence(shortcutText); } else if (task && applet) { button->setKeySequence(applet->globalShortcut().primary()); //no way to have a shortcut for the fdo protocol } else { button->setEnabled(false); } m_autoHideUi.icons->setItemWidget(listItem, 2, button); m_autoHideUi.icons->addTopLevelItem(listItem); // try to make sure we have enough width! int totalWidth = 0; for (int i = 0; i < m_autoHideUi.icons->header()->count(); ++i) { totalWidth += m_autoHideUi.icons->columnWidth(i); } m_autoHideUi.icons->setMinimumWidth(totalWidth + style()->pixelMetric(QStyle::PM_ScrollBarExtent)); connect(itemCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified())); connect(button, SIGNAL(keySequenceChanged(QKeySequence)), parent, SLOT(settingsModified())); } const QString itemCategories = i18nc("Categories of items in the systemtray that will be shown or hidden", "Shown Item Categories"); QStandardItem *applicationStatusItem = new QStandardItem(); applicationStatusItem->setText(i18nc("Systemtray items that describe the status of a generic application", "Application status")); applicationStatusItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); bool checked = cg.readEntry("ShowApplicationStatus", gcg.readEntry("ShowApplicationStatus", DEFAULT_SHOW_APPS)); applicationStatusItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); applicationStatusItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); applicationStatusItem->setData("ShowApplicationStatus", Qt::UserRole+1); visibleItemsSourceModel->appendRow(applicationStatusItem); QStandardItem *communicationsItem = new QStandardItem(); communicationsItem->setText(i18nc("Items communication related, such as chat or email clients", "Communications")); communicationsItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); checked = cg.readEntry("ShowCommunications", gcg.readEntry("ShowCommunications", DEFAULT_SHOW_COMMUNICATION)); communicationsItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); communicationsItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); communicationsItem->setData("ShowCommunications", Qt::UserRole+1); visibleItemsSourceModel->appendRow(communicationsItem); QStandardItem *systemServicesItem = new QStandardItem(); systemServicesItem->setText(i18nc("Items about the status of the system, such as a filesystem indexer", "System services")); systemServicesItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); checked = cg.readEntry("ShowSystemServices", gcg.readEntry("ShowSystemServices", DEFAULT_SHOW_SERVICES)); systemServicesItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); systemServicesItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); systemServicesItem->setData("ShowSystemServices", Qt::UserRole+1); visibleItemsSourceModel->appendRow(systemServicesItem); QStandardItem *hardwareControlItem = new QStandardItem(); hardwareControlItem->setText(i18nc("Items about hardware, such as battery or volume control", "Hardware control")); hardwareControlItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); checked = cg.readEntry("ShowHardware", gcg.readEntry("ShowHardware", DEFAULT_SHOW_HARDWARE)); hardwareControlItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); hardwareControlItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); hardwareControlItem->setData("ShowHardware", Qt::UserRole+1); visibleItemsSourceModel->appendRow(hardwareControlItem); QStandardItem *unknownItem = new QStandardItem(); unknownItem->setText(i18nc("Other uncategorized systemtray items", "Miscellaneous")); unknownItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); checked = cg.readEntry("ShowUnknown", gcg.readEntry("ShowUnknown", DEFAULT_SHOW_UNKNOWN)); unknownItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); unknownItem->setData(itemCategories, KCategorizedSortFilterProxyModel::CategoryDisplayRole); unknownItem->setData("ShowUnknown", Qt::UserRole+1); visibleItemsSourceModel->appendRow(unknownItem); QStringList ownApplets = s_manager->applets(this); QMap sortedApplets; foreach (const KPluginInfo &info, Plasma::Applet::listAppletInfo()) { KService::Ptr service = info.service(); if (service->property("X-Plasma-NotificationArea", QVariant::Bool).toBool()) { // if we already have a plugin with this exact name in it, then check if it is the // same plugin and skip it if it is indeed already listed if (sortedApplets.contains(info.name())) { bool dupe = false; // it is possible (though poor form) to have multiple applets // with the same visible name but different plugins, so we hve to check all values foreach (const KPluginInfo &existingInfo, sortedApplets.values(info.name())) { if (existingInfo.pluginName() == info.pluginName()) { dupe = true; break; } } if (dupe) { continue; } } // insertMulti becase it is possible (though poor form) to have multiple applets // with the same visible name but different plugins sortedApplets.insertMulti(info.name(), info); } } foreach (const KPluginInfo &info, sortedApplets) { QStandardItem *item = new QStandardItem(); item->setText(info.name()); item->setIcon(KIcon(info.icon())); item->setCheckable(true); item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); item->setCheckState(ownApplets.contains(info.pluginName()) ? Qt::Checked : Qt::Unchecked); item->setData(i18nc("Extra items to be manually added in the systray, such as little Plasma widgets", "Extra Items"), KCategorizedSortFilterProxyModel::CategoryDisplayRole); item->setData(info.pluginName(), Qt::UserRole+2); visibleItemsSourceModel->appendRow(item); } connect(visibleItemsSourceModel, SIGNAL(itemChanged(QStandardItem*)), parent, SLOT(settingsModified())); } //not always the corona lock action is available: netbook locks per-containment void Applet::unlockContainment() { if (containment() && containment()->immutability() == Plasma::UserImmutable) { containment()->setImmutability(Plasma::Mutable); } } void Applet::configAccepted() { KConfigGroup cg = config(); KConfigGroup shortcutsConfig = KConfigGroup(&cg, "Shortcuts"); QStringList hiddenTypes; QStringList alwaysShownTypes; QTreeWidget *hiddenList = m_autoHideUi.icons; for (int i = 0; i < hiddenList->topLevelItemCount(); ++i) { QTreeWidgetItem *item = hiddenList->topLevelItem(i); KComboBox *itemCombo = static_cast(hiddenList->itemWidget(item, 1)); //kDebug() << (item->checkState() == Qt::Checked) << item->data(Qt::UserRole).toString(); const QString taskTypeId = item->data(0, Qt::UserRole).toString(); if (itemCombo->currentIndex() == 1) { //Always hidden hiddenTypes << taskTypeId; } else if (itemCombo->currentIndex() == 2) { //Always visible alwaysShownTypes << taskTypeId; } KKeySequenceWidget *keySeq = static_cast(hiddenList->itemWidget(item, 2)); QKeySequence seq = keySeq->keySequence(); Task *task = 0; //FIXME: terribly inefficient foreach (Task *candidateTask, s_manager->tasks()) { if (candidateTask->taskId() == taskTypeId) { task = candidateTask; break; } } if (task) { if (!task->isWidget()) { DBusSystemTrayTask *dbus_task = qobject_cast(task); if (dbus_task) { QString shortcut = seq.toString(); dbus_task->setShortcut(shortcut); QString action_name = _getActionName(task); if (seq.isEmpty()) shortcutsConfig.deleteEntry(action_name); else shortcutsConfig.writeEntry(action_name, shortcut); dbus_task->setShortcut(shortcut); } } else { Plasma::Applet *applet = qobject_cast( task->widget(this) ); if (applet) { applet->setGlobalShortcut(KShortcut(seq)); } } } } cg.writeEntry("hidden", hiddenTypes); cg.writeEntry("alwaysShown", alwaysShownTypes); QStringList applets = s_manager->applets(this); for (int i = 0; i <= m_visibleItemsSourceModel.data()->rowCount() - 1; i++) { QModelIndex index = m_visibleItemsSourceModel.data()->index(i, 0); QString itemCategory = index.data(Qt::UserRole+1).toString(); QString appletName = index.data(Qt::UserRole+2).toString(); if (!itemCategory.isEmpty()) { QStandardItem *item = m_visibleItemsSourceModel.data()->itemFromIndex(index); cg.writeEntry(itemCategory, (item->checkState() == Qt::Checked)); } else if (!appletName.isEmpty()){ QStandardItem *item = m_visibleItemsSourceModel.data()->itemFromIndex(index); if (item->checkState() != Qt::Unchecked && !applets.contains(appletName)) { s_manager->addApplet(appletName, this); } if (item->checkState() == Qt::Checked) { applets.removeAll(appletName); } } } foreach (const QString &appletName, applets) { s_manager->removeApplet(appletName, this); } emit configNeedsSaving(); } void Applet::checkDefaultApplets() { if (config().readEntry("DefaultAppletsAdded", false)) { m_firstRun = false; return; } QStringList applets = s_manager->applets(this); if (!applets.contains("org.kde.networkmanagement")) { s_manager->addApplet("org.kde.networkmanagement", this); } if (!applets.contains("notifier")) { s_manager->addApplet("notifier", this); } if (!applets.contains("org.kde.notifications")) { s_manager->addApplet("org.kde.notifications", this); } if (!applets.contains("battery")) { Plasma::DataEngineManager *engines = Plasma::DataEngineManager::self(); Plasma::DataEngine *power = engines->loadEngine("powermanagement"); if (power) { const QStringList &batteries = power->query("Battery")["Sources"].toStringList(); if (!batteries.isEmpty()) { s_manager->addApplet("battery", this); } } engines->unloadEngine("powermanagement"); } config().writeEntry("DefaultAppletsAdded", true); } int Applet::getVisibilityPreference(QObject *task) const { Task *t = qobject_cast(task); if (!t) return AutoVisibility; if ( m_hiddenTypes.contains(t->taskId()) ) { return AlwaysHidden; } else if ( m_alwaysShownTypes.contains(t->taskId()) ) { return AlwaysShown; } return AutoVisibility; } QAction *Applet::createShortcutAction(QString action_id) const { KAction *action = new KAction(parent()); action->setObjectName(action_id); return action; } void Applet::updateShortcutAction(QAction *action, QString shortcut) const { KAction *act = qobject_cast(action); if (!act) { return; } act->forgetGlobalShortcut(); if (!shortcut.isEmpty()) { act->setGlobalShortcut(KShortcut(QKeySequence(shortcut)), KAction::ShortcutTypes(KAction::ActiveShortcut | KAction::DefaultShortcut), KAction::NoAutoloading); } } void Applet::destroyShortcutAction(QAction *action) const { KAction *act = qobject_cast(action); if (act) { delete act; } } void Applet::showMenu(QObject *menu_var, int x, int y, QObject *item_var) const { QGraphicsItem *item = qobject_cast(item_var); QMenu *menu = qobject_cast(menu_var); if (menu) { QPoint pos(x, y); menu->adjustSize(); if (item && containment() && containment()->corona()) { pos = containment()->corona()->popupPosition(item, menu->size()); } else { pos = Plasma::Applet::popupPosition(menu->size()); } menu->popup(pos); } } void Applet::hideFromTaskbar(qulonglong win_id) const { if (win_id > 0) { KWindowSystem::setState(win_id, NET::SkipTaskbar | NET::SkipPager); } } QString Applet::getUniqueId(QObject *obj) const { return QString::number(reinterpret_cast(obj)); } QPoint Applet::popupPosition(QObject *item_var, QSize size, int align) const { QGraphicsItem *item = qobject_cast(item_var); if ( item && containment() && containment()->corona() ) { return containment()->corona()->popupPosition(item, size, (Qt::AlignmentFlag)align); } return Plasma::Applet::popupPosition(size, (Qt::AlignmentFlag)align); } } #include "moc_applet.cpp"