From 97f73b26082f251a89a7b6ab3a7915526b0a746a Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Fri, 12 Apr 2024 03:33:58 +0300 Subject: [PATCH] plasma: reimplement launcher applet very much WIP but functional Signed-off-by: Ivailo Monev --- plasma/applets/CMakeLists.txt | 2 +- plasma/applets/kickoff/CMakeLists.txt | 125 -- plasma/applets/kickoff/DESIGN-GOALS | 69 -- plasma/applets/kickoff/applet/applet.cpp | 334 ------ plasma/applets/kickoff/applet/applet.h | 82 -- .../applets/kickoff/applet/kickoffConfig.ui | 126 -- .../applets/kickoff/core/applicationmodel.cpp | 708 ----------- .../applets/kickoff/core/applicationmodel.h | 145 --- .../applets/kickoff/core/favoritesmodel.cpp | 351 ------ plasma/applets/kickoff/core/favoritesmodel.h | 72 -- plasma/applets/kickoff/core/itemhandlers.cpp | 174 --- plasma/applets/kickoff/core/itemhandlers.h | 58 - .../kickoff/core/kickoffabstractmodel.cpp | 92 -- .../kickoff/core/kickoffabstractmodel.h | 55 - plasma/applets/kickoff/core/kickoffmodel.cpp | 92 -- plasma/applets/kickoff/core/kickoffmodel.h | 57 - .../kickoff/core/kickoffproxymodel.cpp | 92 -- .../applets/kickoff/core/kickoffproxymodel.h | 55 - plasma/applets/kickoff/core/krunnermodel.cpp | 229 ---- plasma/applets/kickoff/core/krunnermodel.h | 75 -- plasma/applets/kickoff/core/leavemodel.cpp | 181 --- plasma/applets/kickoff/core/leavemodel.h | 45 - plasma/applets/kickoff/core/models.cpp | 216 ---- plasma/applets/kickoff/core/models.h | 139 --- .../kickoff/core/org.kde.kickoff.recent.xml | 7 - .../applets/kickoff/core/org.kde.kickoff.xml | 7 - .../kickoff/core/recentapplications.cpp | 191 --- .../applets/kickoff/core/recentapplications.h | 93 -- .../kickoff/core/recentlyusedmodel.cpp | 286 ----- .../applets/kickoff/core/recentlyusedmodel.h | 76 -- plasma/applets/kickoff/core/systemmodel.cpp | 464 ------- plasma/applets/kickoff/core/systemmodel.h | 103 -- .../applets/kickoff/core/urlitemlauncher.cpp | 154 --- plasma/applets/kickoff/core/urlitemlauncher.h | 90 -- plasma/applets/kickoff/main.cpp | 48 - .../applets/kickoff/simpleapplet/menuview.cpp | 563 --------- .../applets/kickoff/simpleapplet/menuview.h | 179 --- .../plasma-applet-simplelauncher.desktop | 164 --- .../kickoff/simpleapplet/simpleapplet.cpp | 892 -------------- .../kickoff/simpleapplet/simpleapplet.h | 163 --- plasma/applets/kickoff/ui/contentareacap.cpp | 58 - .../applets/kickoff/ui/contextmenufactory.cpp | 311 ----- .../applets/kickoff/ui/contextmenufactory.h | 58 - plasma/applets/kickoff/ui/flipscrollview.cpp | 567 --------- plasma/applets/kickoff/ui/flipscrollview.h | 101 -- plasma/applets/kickoff/ui/itemdelegate.cpp | 114 -- plasma/applets/kickoff/ui/itemdelegate.h | 65 - plasma/applets/kickoff/ui/launcher.cpp | 1063 ----------------- plasma/applets/kickoff/ui/launcher.h | 115 -- plasma/applets/kickoff/ui/searchbar.cpp | 150 --- plasma/applets/kickoff/ui/searchbar.h | 58 - plasma/applets/kickoff/ui/tabbar.cpp | 440 ------- plasma/applets/kickoff/ui/tabbar.h | 99 -- plasma/applets/kickoff/ui/urlitemview.cpp | 715 ----------- plasma/applets/kickoff/ui/urlitemview.h | 87 -- plasma/applets/launcher/CMakeLists.txt | 25 + .../applets/{kickoff => launcher}/Messages.sh | 1 - plasma/applets/launcher/launcher.cpp | 976 +++++++++++++++ .../contentareacap.h => launcher/launcher.h} | 32 +- .../plasma-applet-launcher.desktop | 6 +- 60 files changed, 1025 insertions(+), 11070 deletions(-) delete mode 100644 plasma/applets/kickoff/CMakeLists.txt delete mode 100644 plasma/applets/kickoff/DESIGN-GOALS delete mode 100644 plasma/applets/kickoff/applet/applet.cpp delete mode 100644 plasma/applets/kickoff/applet/applet.h delete mode 100644 plasma/applets/kickoff/applet/kickoffConfig.ui delete mode 100644 plasma/applets/kickoff/core/applicationmodel.cpp delete mode 100644 plasma/applets/kickoff/core/applicationmodel.h delete mode 100644 plasma/applets/kickoff/core/favoritesmodel.cpp delete mode 100644 plasma/applets/kickoff/core/favoritesmodel.h delete mode 100644 plasma/applets/kickoff/core/itemhandlers.cpp delete mode 100644 plasma/applets/kickoff/core/itemhandlers.h delete mode 100644 plasma/applets/kickoff/core/kickoffabstractmodel.cpp delete mode 100644 plasma/applets/kickoff/core/kickoffabstractmodel.h delete mode 100644 plasma/applets/kickoff/core/kickoffmodel.cpp delete mode 100644 plasma/applets/kickoff/core/kickoffmodel.h delete mode 100644 plasma/applets/kickoff/core/kickoffproxymodel.cpp delete mode 100644 plasma/applets/kickoff/core/kickoffproxymodel.h delete mode 100644 plasma/applets/kickoff/core/krunnermodel.cpp delete mode 100644 plasma/applets/kickoff/core/krunnermodel.h delete mode 100644 plasma/applets/kickoff/core/leavemodel.cpp delete mode 100644 plasma/applets/kickoff/core/leavemodel.h delete mode 100644 plasma/applets/kickoff/core/models.cpp delete mode 100644 plasma/applets/kickoff/core/models.h delete mode 100644 plasma/applets/kickoff/core/org.kde.kickoff.recent.xml delete mode 100644 plasma/applets/kickoff/core/org.kde.kickoff.xml delete mode 100644 plasma/applets/kickoff/core/recentapplications.cpp delete mode 100644 plasma/applets/kickoff/core/recentapplications.h delete mode 100644 plasma/applets/kickoff/core/recentlyusedmodel.cpp delete mode 100644 plasma/applets/kickoff/core/recentlyusedmodel.h delete mode 100644 plasma/applets/kickoff/core/systemmodel.cpp delete mode 100644 plasma/applets/kickoff/core/systemmodel.h delete mode 100644 plasma/applets/kickoff/core/urlitemlauncher.cpp delete mode 100644 plasma/applets/kickoff/core/urlitemlauncher.h delete mode 100644 plasma/applets/kickoff/main.cpp delete mode 100644 plasma/applets/kickoff/simpleapplet/menuview.cpp delete mode 100644 plasma/applets/kickoff/simpleapplet/menuview.h delete mode 100644 plasma/applets/kickoff/simpleapplet/plasma-applet-simplelauncher.desktop delete mode 100644 plasma/applets/kickoff/simpleapplet/simpleapplet.cpp delete mode 100644 plasma/applets/kickoff/simpleapplet/simpleapplet.h delete mode 100644 plasma/applets/kickoff/ui/contentareacap.cpp delete mode 100644 plasma/applets/kickoff/ui/contextmenufactory.cpp delete mode 100644 plasma/applets/kickoff/ui/contextmenufactory.h delete mode 100644 plasma/applets/kickoff/ui/flipscrollview.cpp delete mode 100644 plasma/applets/kickoff/ui/flipscrollview.h delete mode 100644 plasma/applets/kickoff/ui/itemdelegate.cpp delete mode 100644 plasma/applets/kickoff/ui/itemdelegate.h delete mode 100644 plasma/applets/kickoff/ui/launcher.cpp delete mode 100644 plasma/applets/kickoff/ui/launcher.h delete mode 100644 plasma/applets/kickoff/ui/searchbar.cpp delete mode 100644 plasma/applets/kickoff/ui/searchbar.h delete mode 100644 plasma/applets/kickoff/ui/tabbar.cpp delete mode 100644 plasma/applets/kickoff/ui/tabbar.h delete mode 100644 plasma/applets/kickoff/ui/urlitemview.cpp delete mode 100644 plasma/applets/kickoff/ui/urlitemview.h create mode 100644 plasma/applets/launcher/CMakeLists.txt rename plasma/applets/{kickoff => launcher}/Messages.sh (65%) create mode 100644 plasma/applets/launcher/launcher.cpp rename plasma/applets/{kickoff/ui/contentareacap.h => launcher/launcher.h} (51%) rename plasma/applets/{kickoff/applet => launcher}/plasma-applet-launcher.desktop (98%) diff --git a/plasma/applets/CMakeLists.txt b/plasma/applets/CMakeLists.txt index 030c7d5a..4823f94a 100644 --- a/plasma/applets/CMakeLists.txt +++ b/plasma/applets/CMakeLists.txt @@ -11,7 +11,7 @@ add_subdirectory(system-monitor) add_subdirectory(notifications) add_subdirectory(systemtray) add_subdirectory(keyboard) -add_subdirectory(kickoff) +add_subdirectory(launcher) add_subdirectory(trash) add_subdirectory(folderview) add_subdirectory(weather) diff --git a/plasma/applets/kickoff/CMakeLists.txt b/plasma/applets/kickoff/CMakeLists.txt deleted file mode 100644 index fc6e9ea8..00000000 --- a/plasma/applets/kickoff/CMakeLists.txt +++ /dev/null @@ -1,125 +0,0 @@ -####################################################################################### -# Kickoff Library - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} -) - -set(libkickoff_SRCS - core/kickoffmodel.cpp - core/kickoffabstractmodel.cpp - core/kickoffproxymodel.cpp - core/applicationmodel.cpp - core/favoritesmodel.cpp - core/leavemodel.cpp - core/models.cpp - core/recentapplications.cpp - core/recentlyusedmodel.cpp - core/krunnermodel.cpp - core/systemmodel.cpp - core/urlitemlauncher.cpp - core/itemhandlers.cpp -) - -qt4_add_dbus_adaptor(libkickoff_SRCS core/org.kde.kickoff.xml core/applicationmodel.h Kickoff::ApplicationModel) -qt4_add_dbus_adaptor(libkickoff_SRCS core/org.kde.kickoff.recent.xml core/recentlyusedmodel.h Kickoff::RecentlyUsedModel) - -set(screensaver_xml ${CMAKE_SOURCE_DIR}/kscreensaver/org.freedesktop.ScreenSaver.xml) -QT4_ADD_DBUS_INTERFACE(libkickoff_SRCS ${screensaver_xml} screensaver_interface) -set(ksmserver_xml ${CMAKE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) -QT4_ADD_DBUS_INTERFACE(libkickoff_SRCS ${ksmserver_xml} ksmserver_interface) - -set(Kickoff_LIBS KDE4::kio KDE4::solid kworkspace) - -add_library(kickoff SHARED ${libkickoff_SRCS}) -target_link_libraries(kickoff KDE4::plasma ${Kickoff_LIBS}) - -generate_export_header(kickoff) - -install( - TARGETS kickoff - DESTINATION ${KDE4_LIB_INSTALL_DIR} -) - -####################################################################################### -# Kickoff Plasma Applet - -set(Applet_SRCS - ui/contextmenufactory.cpp - ui/flipscrollview.cpp - ui/itemdelegate.cpp - ui/contentareacap.cpp - ui/launcher.cpp - ui/searchbar.cpp - ui/tabbar.cpp - ui/urlitemview.cpp - applet/applet.cpp - applet/kickoffConfig.ui -) - -set_source_files_properties( - ${CMAKE_CURRENT_SOURCE_DIR}/ui/contextmenufactory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ui/launcher.cpp - PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE -) - -kde4_add_plugin(plasma_applet_launcher ${Applet_SRCS}) - -target_link_libraries(plasma_applet_launcher - KDE4::kcmutils - KDE4::plasma - ${QT_QTNETWORK_LIBRARY} - ${Kickoff_LIBS} - kickoff -) - -install( - TARGETS plasma_applet_launcher - DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} -) - -install( - FILES applet/plasma-applet-launcher.desktop - DESTINATION ${KDE4_SERVICES_INSTALL_DIR} -) - -####################################################################################### -# Kickoff Simple KMenu Plasma Applet - -set(SimpleApplet_SRCS - ui/contextmenufactory.cpp - simpleapplet/menuview.cpp - simpleapplet/simpleapplet.cpp -) - -set_source_files_properties( - ${CMAKE_CURRENT_SOURCE_DIR}/ui/contextmenufactory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/simpleapplet/menuview.cpp - PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE -) - -kde4_add_plugin(plasma_applet_simplelauncher ${SimpleApplet_SRCS}) -target_link_libraries(plasma_applet_simplelauncher - KDE4::kcmutils - KDE4::plasma - ${Kickoff_LIBS} - kickoff -) - -install( - TARGETS plasma_applet_simplelauncher - DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} -) - -install( - FILES simpleapplet/plasma-applet-simplelauncher.desktop - DESTINATION ${KDE4_SERVICES_INSTALL_DIR} -) - -# Kickoff Standalone Test Application -#IF (CMAKE_BUILD_TYPE MATCHES Debug) -# set(Application_SRCS ${Kickoff_SRCS} main.cpp) -# add_executable(kickoff ${Application_SRCS}) -# target_link_libraries(kickoff KDE4::plasma ${Kickoff_LIBS}) -# install(TARGETS kickoff DESTINATION ${KDE4_BIN_INSTALL_DIR}) -#ENDIF (CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/plasma/applets/kickoff/DESIGN-GOALS b/plasma/applets/kickoff/DESIGN-GOALS deleted file mode 100644 index 7d5956a6..00000000 --- a/plasma/applets/kickoff/DESIGN-GOALS +++ /dev/null @@ -1,69 +0,0 @@ - -Project Proposal: Kickoff KDE 4 Rewrite - -This is a re-implementation of the Kickoff menu for KDE 3 originally created -by the OpenSuSE team. - -Overall goals: - -1. Implement the Kickoff user interface using Qt/KDE 4 technology - -2. Make it easy for distributions to modify the menu contents - -3. Make it easy for distributions to add their own branding - -Detailed goals: - -1. Implement the Kickoff user interface using Qt/KDE 4 technology - - -> Clean separation of core and user interface - -> eg. Make good use of Qt 4's model/view classes - -> Use Strigi for search and analysis (or possibly just Xesam interface?) - -> Use Solid for getting data for removable device list - -> Attractive, original, but not overbearing graphical effects - using Qt 4's new painting and animation features. - - To decide on: - - -> Consult the Kickoff/KDE 3 developers and OpenSuSE users about - any desired changes to the user interface. - -> Whether to use Plasma applets and widgets or Qt's widgets and - QAbstractItemView as the base for the view classes. - -> Provision of Plasma data engines for applets to use to query - applications, recent documents, favorites etc. - -> Should facilities be provided for distributions to replace - Strigi with their choice of search engine? - - Ideas to explore in future: - - -> Use Sonnet for spell-checking the user's search query - -> Light KWin integration for interesting effects for revealing, - hiding or rendering the Kickoff launcher on composited '3D' - desktops. - -Goals 2 and 3 are derived from looking at the KDE 3 implementation -of Kickoff and also the way in which distributions customise KDE. -Consulting distribution representatives is important to clarify -these particular goals. - -2. Make it easy for distributions to modify the menu contents - - -> Different distributions may have different tools for system - configuration ( eg. System Settings , YaST , Mandriva's tools ) - -> The available options on the leave page and the way in which - those tools work varies depending on the distribution - -3. Make it easy for distributions to add their own branding - - -> The launcher menu is a highly visible part of the desktop, - distributions are therefore likely to want to brand it with - their own logos, colors, icons etc. - This does not mean infinite theme-ability, but rather a good - out-of-the-box look which distros can easily tweak so that - it is obvious which distribution is being used from looking - at a screenshot, and also to allow distros to make some - obvious cosmetic changes between versions. - - (See the Ubuntu art specs for example which state that each - new version is supposed to have a visual look which is - distinct from the previous version) diff --git a/plasma/applets/kickoff/applet/applet.cpp b/plasma/applets/kickoff/applet/applet.cpp deleted file mode 100644 index 9f82c47f..00000000 --- a/plasma/applets/kickoff/applet/applet.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "applet/applet.h" - -// Katie -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Local -#include "ui_kickoffConfig.h" -#include "ui/launcher.h" -#include "core/recentapplications.h" -#include "core/models.h" -#include "core/krunnermodel.h" - -// NOTE: keep in sync with: -// kdelibs/kutils/kpluginselector_p.h -static const int s_pluginnamerole = 0x0CBBBB00; - -static QString kMakeToolTip(const QString &pluginname) -{ - QString result; - Plasma::AbstractRunner* runner = Kickoff::KRunnerModel::runnerManager()->runner(pluginname); - if (!runner) { - return result; - } - const QList syntaxes = runner->syntaxes(); - if (syntaxes.isEmpty()) { - return result; - } - QStringList uniqueexamples; - foreach (const Plasma::RunnerSyntax &syntax, syntaxes) { - foreach (const QString &example, syntax.exampleQueriesWithTermDescription()) { - uniqueexamples.append(example); - } - } - uniqueexamples.removeDuplicates(); - if (uniqueexamples.isEmpty()) { - return result; - } - result.append(i18n("Examples:
")); - foreach (const QString &example, uniqueexamples) { - result.append(QString::fromLatin1("%1
").arg(Qt::escape(example))); - } - // qDebug() << Q_FUNC_INFO << result; - return result; -} - -class LauncherApplet::Private -{ -public: - Private(LauncherApplet *lApplet) : launcher(0), switcher(0), q(lApplet) { } - ~Private() { - delete launcher; - } - void createLauncher(); - void initToolTip(); - - Kickoff::Launcher *launcher; - - QList actions; - QAction* switcher; - LauncherApplet *q; - Ui::kickoffConfig ui; - KPluginSelector* selector; -}; - -void LauncherApplet::Private::createLauncher() -{ - if (launcher) { - return; - } - - launcher = new Kickoff::Launcher(q); - launcher->setAttribute(Qt::WA_NoSystemBackground); - launcher->setAutoHide(true); - QObject::connect(launcher, SIGNAL(aboutToHide()), q, SLOT(hidePopup())); - QObject::connect(launcher, SIGNAL(configNeedsSaving()), q, SIGNAL(configNeedsSaving())); - //launcher->resize(launcher->sizeHint()); - //QObject::connect(launcher, SIGNAL(aboutToHide()), icon, SLOT(setUnpressed())); -} - -void LauncherApplet::Private::initToolTip() -{ - Plasma::ToolTipContent data(i18n("Kickoff Application Launcher"), - i18n("Favorites, applications, computer places, " - "recently used items and desktop sessions"), - q->popupIcon().pixmap(IconSize(KIconLoader::Desktop))); - Plasma::ToolTipManager::self()->setContent(q, data); -} - -LauncherApplet::LauncherApplet(QObject *parent, const QVariantList &args) - : Plasma::PopupApplet(parent, args), - d(new Private(this)) -{ - KGlobal::locale()->insertCatalog("plasma_applet_launcher"); - setAspectRatioMode(Plasma::IgnoreAspectRatio); - setHasConfigurationInterface(true); -} - -LauncherApplet::~LauncherApplet() -{ - delete d; -} - -void LauncherApplet::init() -{ - if (KService::serviceByStorageId("kmenuedit.desktop")) { - QAction* menueditor = new QAction(i18n("Edit Applications..."), this); - d->actions.append(menueditor); - connect(menueditor, SIGNAL(triggered(bool)), this, SLOT(startMenuEditor())); - } - - Q_ASSERT(! d->switcher); - d->switcher = new QAction(i18n("Switch to Classic Menu Style"), this); - d->actions.append(d->switcher); - connect(d->switcher, SIGNAL(triggered(bool)), this, SLOT(switchMenuStyle())); - - setGlobalShortcut(KShortcut(Qt::ALT+Qt::Key_F2)); - - configChanged(); - Plasma::ToolTipManager::self()->registerWidget(this); -} - -void LauncherApplet::constraintsEvent(Plasma::Constraints constraints) -{ - if ((constraints & Plasma::ImmutableConstraint) && d->switcher) { - d->switcher->setVisible(immutability() == Plasma::Mutable); - } -} - -void LauncherApplet::switchMenuStyle() -{ - if (containment()) { - Plasma::Applet * simpleLauncher = - containment()->addApplet("simplelauncher", QVariantList() << true, geometry()); - - //Copy all the config items to the simple launcher - QMetaObject::invokeMethod(simpleLauncher, "saveConfigurationFromKickoff", - Qt::DirectConnection, Q_ARG(KConfigGroup, config()), - Q_ARG(KConfigGroup, globalConfig())); - - //Switch shortcuts with the new launcher to avoid losing it - KShortcut currentShortcut = globalShortcut(); - setGlobalShortcut(KShortcut()); - simpleLauncher->setGlobalShortcut(currentShortcut); - - //Destroy this widget - destroy(); - } -} - -void LauncherApplet::startMenuEditor() -{ - KToolInvocation::kdeinitExec("kmenuedit"); -} - -void LauncherApplet::createConfigurationInterface(KConfigDialog *parent) -{ - QWidget *widget = new QWidget(); - d->ui.setupUi(widget); - parent->addPage(widget, i18nc("General configuration page", "General"), icon()); - - const QList plugins = Plasma::RunnerManager::listRunnerInfo(); - d->selector = new KPluginSelector(widget); - d->selector->addPlugins( - plugins, - KPluginSelector::ReadConfigFile, - i18n("Available Plugins"), QString(), - Kickoff::componentData().config() - ); - connect(d->selector, SIGNAL(changed(bool)), parent, SLOT(settingsModified())); - parent->addPage(d->selector, i18n("Runners"), "preferences-plugin"); - - foreach (const KPluginInfo& plugin, plugins) { - Kickoff::KRunnerModel::runnerManager()->loadRunner(plugin.service()); - } - // HACK: setup tooltips for the plugins - KCategorizedView* selectorview = d->selector->findChild(); - if (selectorview) { - QAbstractItemModel* selectormodel = selectorview->model(); - if (selectormodel) { - for (int i = 0; i < selectormodel->rowCount(); i++) { - QModelIndex selectorindex = selectormodel->index(i, 0); - const QString pluginname = selectormodel->data(selectorindex, s_pluginnamerole).toString(); - selectormodel->setData(selectorindex, kMakeToolTip(pluginname), Qt::ToolTipRole); - } - } - } - // forces unload of the disabled plugins that have been loaded for the tooltip - Kickoff::KRunnerModel::runnerManager()->reloadConfiguration(); - - connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); - connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); - - d->createLauncher(); - d->ui.iconButton->setIcon(popupIcon()); - d->ui.switchOnHoverCheckBox->setChecked(d->launcher->switchTabsOnHover()); - d->ui.appsByNameCheckBox->setChecked(d->launcher->showAppsByName()); - d->ui.showRecentlyInstalledCheckBox->setChecked(d->launcher->showRecentlyInstalled()); - connect(d->ui.iconButton, SIGNAL(iconChanged(QString)), parent, SLOT(settingsModified())); - connect(d->ui.switchOnHoverCheckBox, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); - connect(d->ui.appsByNameCheckBox, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); - connect(d->ui.showRecentlyInstalledCheckBox, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); -} - -void LauncherApplet::popupEvent(bool show) -{ - if (show) { - Plasma::ToolTipManager::self()->clearContent(this); - d->createLauncher(); - d->launcher->setLauncherOrigin(popupPlacement(), location()); - } -} - -void LauncherApplet::toolTipAboutToShow() -{ - if (d->launcher->isVisible()) { - Plasma::ToolTipManager::self()->clearContent(this); - } else { - d->initToolTip(); - } -} - -void LauncherApplet::configChanged() -{ - KConfigGroup cg = config(); - setPopupIcon(cg.readEntry("icon", "start-here-kde")); - constraintsEvent(Plasma::ImmutableConstraint); - - if (d->launcher) { - d->launcher->setApplet(this); - } -} - -void LauncherApplet::configAccepted() -{ - d->selector->save(); - KConfigGroup pcg = Kickoff::componentData().config()->group("Plugins"); - QStringList allowed; - foreach (KPluginInfo plugin, Plasma::RunnerManager::listRunnerInfo()) { - plugin.load(pcg); - if (plugin.isPluginEnabled()) { - allowed.append(plugin.pluginName()); - } - } - Kickoff::KRunnerModel::runnerManager()->setAllowedRunners(allowed); - - bool switchTabsOnHover = d->ui.switchOnHoverCheckBox->isChecked(); - bool showAppsByName = d->ui.appsByNameCheckBox->isChecked(); - bool showRecentlyInstalled = d->ui.showRecentlyInstalledCheckBox->isChecked(); - - const QString iconname = d->ui.iconButton->icon(); - - // TODO: should this be moved into Launcher as well? perhaps even the config itself? - d->createLauncher(); - - KConfigGroup cg = config(); - const QString oldIcon = cg.readEntry("icon", "start-here-kde"); - if (!iconname.isEmpty() && iconname != oldIcon) { - cg.writeEntry("icon", iconname); - - if (!iconname.isEmpty()) { - setPopupIcon(iconname); - } - - emit configNeedsSaving(); - } - - d->launcher->setSwitchTabsOnHover(switchTabsOnHover); - d->launcher->setShowAppsByName(showAppsByName); - d->launcher->setShowRecentlyInstalled(showRecentlyInstalled); -} - -QList LauncherApplet::contextualActions() -{ - return d->actions; -} - -QWidget *LauncherApplet::widget() -{ - d->createLauncher(); - return d->launcher; -} - -void LauncherApplet::saveConfigurationFromSimpleLauncher(const KConfigGroup & configGroup, const KConfigGroup & globalConfigGroup) -{ - //Copy configuration values - KConfigGroup cg = config(); - configGroup.copyTo(&cg); - - KConfigGroup gcg = globalConfig(); - globalConfigGroup.copyTo(&gcg); - - configChanged(); - emit configNeedsSaving(); -} - -#include "moc_applet.cpp" diff --git a/plasma/applets/kickoff/applet/applet.h b/plasma/applets/kickoff/applet/applet.h deleted file mode 100644 index f3afe734..00000000 --- a/plasma/applets/kickoff/applet/applet.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef APPLET_H -#define APPLET_H - -// KDE - -// Plasma -#include - -namespace Kickoff -{ -class Launcher; -} -namespace Plasma -{ -} - -class LauncherApplet : public Plasma::PopupApplet -{ - Q_OBJECT - -public: - LauncherApplet(QObject *parent, const QVariantList &args); - virtual ~LauncherApplet(); - - void init(); - - void constraintsEvent(Plasma::Constraints constraints); - - virtual QList contextualActions(); - - QWidget *widget(); - -public slots: - void switchMenuStyle(); - void startMenuEditor(); - void toolTipAboutToShow(); - void configChanged(); - - /** - * Save config values stored on SimpleLauncher after a menu switch - */ - void saveConfigurationFromSimpleLauncher(const KConfigGroup & configGroup, - const KConfigGroup & globalConfigGroup); - -protected slots: - void configAccepted(); - //void toggleMenu(); - //void toggleMenu(bool pressed); - -protected: - - void createConfigurationInterface(KConfigDialog *parent); - void popupEvent(bool show); - -private: - friend class Kickoff::Launcher; - class Private; - Private * const d; -}; - -K_EXPORT_PLASMA_APPLET(launcher, LauncherApplet) - -#endif diff --git a/plasma/applets/kickoff/applet/kickoffConfig.ui b/plasma/applets/kickoff/applet/kickoffConfig.ui deleted file mode 100644 index bd90d9a0..00000000 --- a/plasma/applets/kickoff/applet/kickoffConfig.ui +++ /dev/null @@ -1,126 +0,0 @@ - - - kickoffConfig - - - - 0 - 0 - 400 - 300 - - - - - - - - - - - - - - - - - Show applications by &name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - appsByNameCheckBox - - - - - - - - - - - - - - Qt::Horizontal - - - - 131 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 204 - - - - - - - - &Icon: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - iconButton - - - - - - - Switch &tabs on hover: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - switchOnHoverCheckBox - - - - - - - - - - - - - - Show 'Recently Installed': - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - showRecentlyInstalledCheckBox - - - - - - - - KIconButton - QPushButton -
kicondialog.h
-
-
- -
diff --git a/plasma/applets/kickoff/core/applicationmodel.cpp b/plasma/applets/kickoff/core/applicationmodel.cpp deleted file mode 100644 index 137e09f4..00000000 --- a/plasma/applets/kickoff/core/applicationmodel.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/* - Copyright 2007 Pino Toscano - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "applicationmodel.h" - -// Qt -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "kickoffadaptor.h" -// Local -#include "core/models.h" - -#include - -template <> inline -void KConfigGroup::writeEntry(const char *pKey, - const KGlobalSettings::Completion& aValue, - KConfigBase::WriteConfigFlags flags) -{ - writeEntry(pKey, int(aValue), flags); -} - -namespace Kickoff -{ - -class AppNode -{ -public: - AppNode() - : parent(0), - fetched(false), - isDir(false), - isSeparator(false), - subTitleMandatory(false) - { - } - - ~AppNode() - { - qDeleteAll(children); - } - - QList children; - - QIcon icon; - QString iconName; - QString genericName; - QString appName; - QString relPath; - QString desktopEntry; - - AppNode *parent; - DisplayOrder displayOrder; - bool fetched : 1; - bool isDir : 1; - bool isSeparator : 1; - bool subTitleMandatory : 1; -}; - -class ApplicationModelPrivate -{ -public: - ApplicationModelPrivate(ApplicationModel *qq, bool _allowSeparators) - : q(qq), - root(new AppNode()), - duplicatePolicy(ApplicationModel::ShowDuplicatesPolicy), - systemApplicationPolicy(ApplicationModel::ShowApplicationAndSystemPolicy), - primaryNamePolicy(ApplicationModel::GenericNamePrimary), - displayOrder(NameAfterDescription), - allowSeparators(_allowSeparators), - showRecentlyInstalled(true) - { - systemApplications = Kickoff::systemApplicationList(); - reloadTimer = new QTimer(qq); - reloadTimer->setSingleShot(true); - QObject::connect(reloadTimer, SIGNAL(timeout()), qq, SLOT(delayedReloadMenu())); - } - - ~ApplicationModelPrivate() - { - delete root; - } - - void fillNode(const QString &relPath, AppNode *node); - static QHash iconNameMap(); - - ApplicationModel *q; - QWeakPointer applet; - AppNode *root; - ApplicationModel::DuplicatePolicy duplicatePolicy; - ApplicationModel::SystemApplicationPolicy systemApplicationPolicy; - ApplicationModel::PrimaryNamePolicy primaryNamePolicy; - QStringList systemApplications; - DisplayOrder displayOrder; - bool allowSeparators; - bool showRecentlyInstalled; - QTimer *reloadTimer; - - QStringList newInstalledPrograms; - QHash seenPrograms; -}; - -void ApplicationModelPrivate::fillNode(const QString &_relPath, AppNode *node) -{ - if (_relPath=="new/") { - Q_FOREACH (const QString &it, newInstalledPrograms) { - KService::Ptr p = KService::serviceByStorageId(it); - - if (p->noDisplay()) { - continue; - } - - AppNode *newnode = new AppNode(); - newnode->icon = KIcon(p->icon()); - newnode->appName = p->name(); - newnode->genericName = p->genericName(); - newnode->desktopEntry = p->entryPath(); - newnode->parent = node; - node->children.append(newnode); - } - return; - } - - KServiceGroup::Ptr root = KServiceGroup::group(_relPath); - - if (!root || !root->isValid()) { - return; - } - - const KServiceGroup::List list = root->entries(true /* sorted */, - true /* exclude no display entries */, - allowSeparators /* allow separators */, - primaryNamePolicy == ApplicationModel::GenericNamePrimary /* sort by generic name */); - - // application name <-> service map for detecting duplicate entries - QHash existingServices; - - // generic name <-> node mapping to determinate duplicate generic names - QHash > genericNames; - - for (KServiceGroup::List::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) { - QString icon; - QString appName; - QString genericName; - QString relPath = _relPath; - QString desktopEntry; - bool isDir = false; - bool isSeparator = false; - const KSycocaEntry::Ptr p = (*it); - - if (p->isType(KST_KService)) { - const KService::Ptr service = KService::Ptr::staticCast(p); - - if (service->noDisplay()) { - continue; - } - - icon = service->icon(); - appName = service->name(); - genericName = service->genericName(); - desktopEntry = service->entryPath(); - - // check for duplicates (eg. KDE 3 and KDE 4 versions of application - // both present) - if (duplicatePolicy == ApplicationModel::ShowLatestOnlyPolicy && - existingServices.contains(appName)) { - if (Kickoff::isLaterVersion(existingServices[appName], service)) { - continue; - } else { - // find and remove the existing entry with the same name - for (int i = node->children.count() - 1; i >= 0; --i) { - AppNode *app = node->children.at(i); - if (app->appName == appName && - app->genericName == genericName && - app->iconName == icon) { - app = node->children.takeAt(i); - const QString s = app->genericName.toLower(); - if (genericNames.contains(s)) { - QList list = genericNames[s]; - for (int j = list.count() - 1; j >= 0; --j) { - if(list.at(j) == app) { - list.takeAt(j); - } - } - genericNames[s] = list; - } - delete app; - } - } - } - } - - if (systemApplicationPolicy == ApplicationModel::ShowSystemOnlyPolicy && - systemApplications.contains(service->desktopEntryName())) { - // don't duplicate applications that are configured to appear in the System tab - // in the Applications tab - continue; - } - - existingServices[appName] = service; - } else if (p->isType(KST_KServiceGroup)) { - const KServiceGroup::Ptr serviceGroup = KServiceGroup::Ptr::staticCast(p); - - if (serviceGroup->noDisplay() || serviceGroup->childCount() == 0) { - continue; - } - - kDebug() << "Service group" << serviceGroup->entryPath() << serviceGroup->icon() - << serviceGroup->relPath() << serviceGroup->directoryEntryPath(); - - icon = serviceGroup->icon(); - if (iconNameMap().contains(icon)) { - icon = iconNameMap().value(icon); - } - - desktopEntry = serviceGroup->entryPath(); - genericName = serviceGroup->caption(); - relPath = serviceGroup->relPath(); - appName = serviceGroup->comment(); - isDir = true; - } else if (p->isType(KST_KServiceSeparator)) { - isSeparator = true; - } else { - kWarning() << "KServiceGroup: Unexpected object in list!"; - continue; - } - - AppNode *newnode = new AppNode(); - newnode->iconName = icon; - newnode->icon = KIcon(icon); - newnode->appName = appName; - newnode->genericName = genericName; - newnode->relPath = relPath; - newnode->desktopEntry = desktopEntry; - newnode->isDir = isDir; - newnode->isSeparator = isSeparator; - newnode->parent = node; - node->children.append(newnode); - - if (p->isType(KST_KService)) { - const QString s = genericName.toLower(); - QList list = genericNames.value(s); - list.append(newnode); - genericNames[s] = list; - } - } - - if (showRecentlyInstalled && _relPath.isEmpty() && !newInstalledPrograms.isEmpty()) { - AppNode *newnode = new AppNode(); - newnode->icon = KIcon("chronometer"); - newnode->appName = i18n("Recently Installed"); - newnode->relPath = "new/"; - newnode->isDir = true; - newnode->parent = node; - node->children.prepend(newnode); - } - - // set the subTitleMandatory field for nodes that do not provide a unique generic - // name what may help us on display to show in such cases also the subtitle to - // provide a hint to the user what the duplicate entries are about. - foreach (const QList &list, genericNames) { - if (list.count() > 1) { - foreach (AppNode* n, list) { - n->subTitleMandatory = true; - } - } - } -} - -ApplicationModel::ApplicationModel(QObject *parent, bool allowSeparators) - : KickoffAbstractModel(parent), - d(new ApplicationModelPrivate(this, allowSeparators)) -{ - QDBusConnection dbus = QDBusConnection::sessionBus(); - (void)new KickoffAdaptor(this); - QDBusConnection::sessionBus().registerObject("/kickoff", this); - dbus.connect(QString(), "/kickoff", "org.kde.plasma", "reloadMenu", this, SLOT(reloadMenu())); - connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(checkSycocaChange(QStringList))); -} - -ApplicationModel::~ApplicationModel() -{ - delete d; -} - -bool ApplicationModel::canFetchMore(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return false; - - AppNode *node = static_cast(parent.internalPointer()); - return node->isDir && !node->fetched; -} - -void ApplicationModel::setNameDisplayOrder(DisplayOrder displayOrder) -{ - d->displayOrder = displayOrder; -} - -DisplayOrder ApplicationModel::nameDisplayOrder() const -{ - return d->displayOrder; -} - -void ApplicationModel::setShowRecentlyInstalled(bool showRecentlyInstalled) -{ - if (d->showRecentlyInstalled != showRecentlyInstalled) { - d->showRecentlyInstalled = showRecentlyInstalled; - reloadMenu(); - } -} - -bool ApplicationModel::showRecentlyInstalled() const -{ - return d->showRecentlyInstalled; -} - -int ApplicationModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return 1; -} - -bool ApplicationModel::nameAfterDescription(const QModelIndex &index) const -{ - AppNode *node = static_cast(index.internalPointer()); - if (node->isDir) { - return true; - } - - QModelIndex parent = index.parent(); - while (parent.parent().isValid()) { - parent = parent.parent(); - } - - if (parent.isValid()) { - // nasty little hack to always makes games show their unique name - // there is no such thing as a "generic name" for a game in practice - // though this is apparently quite true for all other kinds of apps - AppNode *node = static_cast(parent.internalPointer()); - if (node->isDir && node->genericName == i18n("Games")) { - return false; - } - } - - return d->displayOrder == NameAfterDescription; -} - -QVariant ApplicationModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - AppNode *node = static_cast(index.internalPointer()); - - switch (role) { - case Qt::DisplayRole: - if (nameAfterDescription(index) && !node->genericName.isEmpty()) { - return node->genericName; - } - return node->appName; - case Kickoff::SubTitleRole: - if (!nameAfterDescription(index) && !node->genericName.isEmpty()) { - return node->genericName; - } - return node->appName; - case Kickoff::UrlRole: - if (node->isDir) { - return QString(); - } - return node->desktopEntry; - case Kickoff::SubTitleMandatoryRole: - return nameAfterDescription(index) && node->subTitleMandatory; - case Kickoff::SeparatorRole: - return node->isSeparator; - case Qt::DecorationRole: - return node->icon; - case Kickoff::RelPathRole: - return node->relPath; - case Kickoff::IconNameRole: - return node->iconName; - default: - ; - } - return QVariant(); -} - -void ApplicationModel::fetchMore(const QModelIndex &parent) -{ - if (!parent.isValid()) { - return; - } - - AppNode *node = static_cast(parent.internalPointer()); - if (!node->isDir) { - return; - } - - emit layoutAboutToBeChanged(); - d->fillNode(node->relPath, node); - node->fetched = true; - emit layoutChanged(); -} - -bool ApplicationModel::hasChildren(const QModelIndex &parent) const -{ - if (!parent.isValid()) { - return true; - } - - AppNode *node = static_cast(parent.internalPointer()); - return node->isDir; -} - -QVariant ApplicationModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != Qt::Horizontal || section != 0) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - return i18n("All Applications"); - break; - default: - return QVariant(); - } -} - -QModelIndex ApplicationModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || column != 0) - return QModelIndex(); - - AppNode *node = d->root; - if (parent.isValid()) - node = static_cast(parent.internalPointer()); - - if (row >= node->children.count()) - return QModelIndex(); - else - return createIndex(row, 0, node->children.at(row)); -} - -QModelIndex ApplicationModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) { - return QModelIndex(); - } - - AppNode *node = static_cast(index.internalPointer()); - if (node->parent->parent) { - int id = node->parent->parent->children.indexOf(node->parent); - - if (id >= 0 && id < node->parent->parent->children.count()) { - return createIndex(id, 0, node->parent); - } - } - - return QModelIndex(); -} - -int ApplicationModel::rowCount(const QModelIndex &parent) const -{ - if (!parent.isValid()) { - return d->root->children.count(); - } - - AppNode *node = static_cast(parent.internalPointer()); - return node->children.count(); -} - -void ApplicationModel::setDuplicatePolicy(DuplicatePolicy policy) -{ - if (d->duplicatePolicy != policy) { - d->duplicatePolicy = policy; - reloadMenu(); - } -} - -void ApplicationModel::setSystemApplicationPolicy(SystemApplicationPolicy policy) -{ - if (d->systemApplicationPolicy != policy) { - d->systemApplicationPolicy = policy; - reloadMenu(); - } -} - -void ApplicationModel::setPrimaryNamePolicy(PrimaryNamePolicy policy) -{ - if (policy != d->primaryNamePolicy) { - d->primaryNamePolicy = policy; - reloadMenu(); - } -} - -ApplicationModel::PrimaryNamePolicy ApplicationModel::primaryNamePolicy() const -{ - return d->primaryNamePolicy; -} - -void ApplicationModel::delayedReloadMenu() -{ - if (!d->reloadTimer->isActive()) { - d->reloadTimer->start(200); - } -} - -void ApplicationModel::reloadMenu() -{ - delete d->root; - d->root = new AppNode(); - createNewProgramList(); - d->fillNode(QString(), d->root); - reset(); -} - -void ApplicationModel::checkSycocaChange(const QStringList &changes) -{ - if (changes.contains("services") || changes.contains("apps") || changes.contains("xdgdata-apps")) { - reloadMenu(); - } -} - -ApplicationModel::DuplicatePolicy ApplicationModel::duplicatePolicy() const -{ - return d->duplicatePolicy; -} - -ApplicationModel::SystemApplicationPolicy ApplicationModel::systemApplicationPolicy() const -{ - return d->systemApplicationPolicy; -} - -void ApplicationModel::setApplet(Plasma::Applet *applet) -{ - if (d->applet.data() != applet) { - d->applet = applet; - createNewProgramList(); - } -} - -void ApplicationModel::createNewProgramList() -{ - if (!d->applet) { - return; - } - - d->newInstalledPrograms.clear(); - if (!d->showRecentlyInstalled) { - return; - } - - KConfigGroup kickoffrc = d->applet.data()->globalConfig(); - foreach (const QString &it, kickoffrc.keyList()) { - d->seenPrograms.insert(it, QDate::fromString(kickoffrc.readEntry(it), Qt::ISODate)); - } - - bool initialize = (d->seenPrograms.isEmpty()); - - bool seenProgramsChanged = createNewProgramListForPath(QString()); - - if (initialize) { - // on first start, set all entries' dates to empty (means: they are not new) - for (QHash::Iterator it = d->seenPrograms.begin(); it != d->seenPrograms.end(); ++it) - *it = QDate(); - - d->newInstalledPrograms.clear(); - } - - if (seenProgramsChanged) { - for (QHash::Iterator it = d->seenPrograms.begin(); it != d->seenPrograms.end(); ++it) { - kickoffrc.writeEntry(it.key(), it.value().toString(Qt::ISODate)); - } - kickoffrc.sync(); - } -} - -bool ApplicationModel::createNewProgramListForPath(const QString &relPath) -{ - bool seenProgramsChanged = false; - - KServiceGroup::Ptr group = KServiceGroup::group(relPath); - if (!group || !group->isValid()) { - return false; - } - - const KServiceGroup::List list = group->entries(); - - KServiceGroup::List::ConstIterator it = list.begin(); - for (; it != list.end(); ++it) { - KSycocaEntry::Ptr e = (*it); - - if (e->isType(KST_KServiceGroup)) { - KServiceGroup::Ptr g(KServiceGroup::Ptr::staticCast(e)); - if (!g->noDisplay()) { - if (createNewProgramListForPath(g->relPath())) - seenProgramsChanged = true; - } - } else if (e->isType(KST_KService)) { - KService::Ptr s(KService::Ptr::staticCast(e)); - if (s->isApplication() && !s->noDisplay()) { - QString shortStorageId = s->storageId().remove(".desktop"); - QHash::Iterator it_find = d->seenPrograms.find(shortStorageId); - if (it_find == d->seenPrograms.end()) { - seenProgramsChanged = true; - d->seenPrograms.insert(shortStorageId, QDate::currentDate()); - if (!d->newInstalledPrograms.contains(s->storageId())) { - d->newInstalledPrograms += s->storageId(); - } - } - else { - QDate date = it_find.value(); - if (date.isValid()) { - if (date.daysTo(QDate::currentDate()) < 3) { - if (!d->newInstalledPrograms.contains(s->storageId())) { - d->newInstalledPrograms += s->storageId(); - } - } - else { - seenProgramsChanged = true; - (*it_find) = QDate(); // this entry is not new anymore - } - } - } - } - } - } - return seenProgramsChanged; -} - -/** - * FIXME This is a temporary workaround to map the icon names found - * in the desktop directory files (from /usr/share/desktop-directories) - * into the Oxygen icon names. (Only applies if the Gnome menu files - * are also installed) - * - * This list was compiled from Kubuntu 7.04 with the gnome-menus - * package present. - * - * This needs to be discussed on kde-core-devel and fixed - */ -QHash ApplicationModelPrivate::iconNameMap() -{ - static QHash map; - if (map.isEmpty()) { - map.insert("gnome-util", "applications-accessories"); - // accessibility Oxygen icon was missing when this list was compiled - map.insert("accessibility-directory", "applications-other"); - map.insert("gnome-devel", "applications-development"); - map.insert("package_edutainment", "applications-education"); - map.insert("gnome-joystick", "applications-games"); - map.insert("gnome-graphics", "applications-graphics"); - map.insert("gnome-globe", "applications-internet"); - map.insert("gnome-multimedia", "applications-multimedia"); - map.insert("gnome-applications", "applications-office"); - map.insert("gnome-system", "applications-system"); - } - return map; -} - -} // namespace Kickoff - - -#include "moc_applicationmodel.cpp" diff --git a/plasma/applets/kickoff/core/applicationmodel.h b/plasma/applets/kickoff/core/applicationmodel.h deleted file mode 100644 index 51c5b1a8..00000000 --- a/plasma/applets/kickoff/core/applicationmodel.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - Copyright 2007 Pino Toscano - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef APPLICATIONMODEL_H -#define APPLICATIONMODEL_H - -#include "kickoff_export.h" -#include "core/kickoffabstractmodel.h" -#include "core/models.h" - -namespace Plasma -{ - class Applet; -} // namespace Plasma - -namespace Kickoff -{ - -class ApplicationModelPrivate; - -/** - * ApplicationModel provides a tree model containing all of the user's installed graphical programs. - * The applications are arranged into categories, based on the information in their .desktop files. - */ -class KICKOFF_EXPORT ApplicationModel : public KickoffAbstractModel -{ - Q_OBJECT - -public: - ApplicationModel(QObject *parent = 0, bool allowSeparators = false); - virtual ~ApplicationModel(); - - /** - * This enum describes the policy for - * handling duplicate applications (that is, - * two applications with the same name in the same group) - */ - enum DuplicatePolicy { - /** Display duplicate entries. */ - ShowDuplicatesPolicy, - /** - * Show only the entry for the most recent - * version of the application. - * - * Currently only a crude heuristic to determine whether the - * application is from KDE 3 or KDE 4 is used to determine - * recent-ness. - * - * eg. If MyGame/KDE 3 and MyGame/KDE 4 are found - * show only MyGame/KDE 4 - */ - ShowLatestOnlyPolicy - }; - - /** - * This enum describes the policy for - * handling applications that are configured to appear - * in the System tab. - */ - enum SystemApplicationPolicy { - /** Display entries in Applications tab and System tab. */ - ShowApplicationAndSystemPolicy, - /** Display entry only in System tab. */ - ShowSystemOnlyPolicy - }; - - enum PrimaryNamePolicy { - AppNamePrimary, - GenericNamePrimary - }; - - void setNameDisplayOrder(DisplayOrder displayOrder); - DisplayOrder nameDisplayOrder() const; - //DisplayOrder m_displayOrder; - /** - * Sets the policy for handling duplicate applications. - * See DuplicatePolicy - */ - void setDuplicatePolicy(DuplicatePolicy policy); - /** See setDuplicatePolicy() */ - DuplicatePolicy duplicatePolicy() const; - - /** - * Sets the policy for handling System applications. - * See SystemApplicationPolicy - */ - void setSystemApplicationPolicy(SystemApplicationPolicy policy); - /** See setSystemApplicationPolicy() */ - SystemApplicationPolicy systemApplicationPolicy() const; - - void setPrimaryNamePolicy(PrimaryNamePolicy policy); - PrimaryNamePolicy primaryNamePolicy() const; - - // reimplemented from QAbstractItemModel - virtual bool canFetchMore(const QModelIndex &parent) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual void fetchMore(const QModelIndex &parent); - virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &index) const; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - - void setApplet(Plasma::Applet *applet); - void setShowRecentlyInstalled(bool showRecentlyInstalled); - bool showRecentlyInstalled() const; - -public slots: - void reloadMenu(); - void delayedReloadMenu(); - void checkSycocaChange(const QStringList &changes); - -private: - bool nameAfterDescription(const QModelIndex &index) const; - - friend class ApplicationModelPrivate; - ApplicationModelPrivate *const d; - - void createNewProgramList(); - bool createNewProgramListForPath(const QString &relPath); - - Q_DISABLE_COPY(ApplicationModel) -}; - -} - -#endif diff --git a/plasma/applets/kickoff/core/favoritesmodel.cpp b/plasma/applets/kickoff/core/favoritesmodel.cpp deleted file mode 100644 index 4e0cafb2..00000000 --- a/plasma/applets/kickoff/core/favoritesmodel.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -//Own -#include "core/favoritesmodel.h" - -// Qt -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include - -using namespace Kickoff; - -class FavoritesModel::Private -{ -public: - Private(FavoritesModel *parent) - : q(parent), - displayOrder(NameAfterDescription) - { - init(); - } - - void init() - { - headerItem = new QStandardItem(i18n("Favorites")); - q->appendRow(headerItem); - } - - void addFavoriteItem(const QString& url) - { - QStandardItem *item = StandardItemFactory::createItemForUrl(url, displayOrder); - headerItem->appendRow(item); - } - - void moveFavoriteItem(int startRow, int destRow) - { - if (destRow == startRow) { - return; - } - - QStandardItem *item = headerItem->takeChild(startRow); - - headerItem->removeRow(startRow); - headerItem->insertRow(destRow, item); - } - - void removeFavoriteItem(const QString& url) - { - QModelIndexList matches = q->match(q->index(0, 0), UrlRole, - url, -1, - Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap | Qt::MatchRecursive)); - - kDebug() << "Removing item matches" << matches; - - foreach (const QModelIndex& index, matches) { - QStandardItem *item = q->itemFromIndex(index); - if (item->parent()) { - item->parent()->removeRow(item->row()); - } else { - qDeleteAll(q->takeRow(item->row())); - } - } - } - - static void loadFavorites() - { - globalFavoriteList.clear(); - globalFavoriteSet.clear(); - - KConfigGroup favoritesGroup = componentData().config()->group("Favorites"); - QList favoriteList = favoritesGroup.readEntry("FavoriteURLs", QList()); - if (favoriteList.isEmpty()) { - favoriteList = defaultFavorites(); - } - - foreach (const QString &favorite, favoriteList) { - FavoritesModel::add(favorite); - } - } - - static QList defaultFavorites() - { - QList applications; - applications << "konsole" << "dolphin" << "systemsettings"; - - QList desktopFiles; - - foreach (const QString& application, applications) { - KService::Ptr service = KService::serviceByStorageId(application + ".desktop"); - if (service) { - desktopFiles << service->entryPath(); - } - } - - return desktopFiles; - } - - static void saveFavorites() - { - KConfigGroup favoritesGroup = componentData().config()->group("Favorites"); - favoritesGroup.writeEntry("FavoriteURLs", globalFavoriteList); - favoritesGroup.config()->sync(); - } - - static QList globalFavoriteList; - static QSet globalFavoriteSet; - static QSet models; - - FavoritesModel * const q; - QStandardItem *headerItem; - DisplayOrder displayOrder; -}; - -QList FavoritesModel::Private::globalFavoriteList; -QSet FavoritesModel::Private::globalFavoriteSet; -QSet FavoritesModel::Private::models; - -FavoritesModel::FavoritesModel(QObject *parent) - : KickoffModel(parent) - , d(new Private(this)) -{ - Private::models << this; - if (Private::models.count() == 1 && Private::globalFavoriteList.isEmpty()) { - Private::loadFavorites(); - } else { - foreach (const QString &url, Private::globalFavoriteList) { - d->addFavoriteItem(url); - } - } - -} - -FavoritesModel::~FavoritesModel() -{ - Private::models.remove(this); - - if (Private::models.isEmpty()) { - Private::saveFavorites(); - } - - delete d; -} - -void FavoritesModel::add(const QString& url) -{ - Private::globalFavoriteList << url; - Private::globalFavoriteSet << url; - - foreach (FavoritesModel* model, Private::models) { - model->d->addFavoriteItem(url); - } - - // save after each add in case we crash - Private::saveFavorites(); -} - -void FavoritesModel::move(int startRow, int destRow) -{ - // just move the item - Private::globalFavoriteList.move(startRow, destRow); - - foreach (FavoritesModel* model, Private::models) { - model->d->moveFavoriteItem(startRow, destRow); - } - - // save after each add in case we crash - Private::saveFavorites(); -} - -void FavoritesModel::remove(const QString& url) -{ - Private::globalFavoriteList.removeAll(url); - Private::globalFavoriteSet.remove(url); - - foreach (FavoritesModel* model, Private::models) { - model->d->removeFavoriteItem(url); - } - - // save after each remove in case of crash or other mishaps - Private::saveFavorites(); -} - -bool FavoritesModel::isFavorite(const QString& url) -{ - return Private::globalFavoriteSet.contains(url); -} - -int FavoritesModel::numberOfFavorites() -{ - foreach (FavoritesModel* model, Private::models) { - return model->d->headerItem->rowCount() - 1; - } - - return 0; -} - -void FavoritesModel::sortFavorites(Qt::SortOrder order) -{ - if(Private::models.isEmpty()) { - return; - } - - foreach (FavoritesModel *model, Private::models) { - model->d->headerItem->sortChildren(0, order); - } - - Private::globalFavoriteList.clear(); - - FavoritesModel *model = *Private::models.begin(); - QStandardItem *childData; - for (int i = 0; i <= numberOfFavorites(); i++) { - childData = model->d->headerItem->child(i, 0); - Private::globalFavoriteList.append(childData->data(Kickoff::UrlRole).toString()); - } - - Private::saveFavorites(); -} - -void FavoritesModel::sortFavoritesAscending() -{ - sortFavorites(Qt::AscendingOrder); -} - -void FavoritesModel::sortFavoritesDescending() -{ - sortFavorites(Qt::DescendingOrder); -} - -bool FavoritesModel::dropMimeData(const QMimeData *data, Qt::DropAction action, - int row, int column, const QModelIndex & parent) -{ - Q_UNUSED(parent); - - if (action == Qt::IgnoreAction) { - return true; - } - - if (column > 0) { - return false; - } - - if (action == Qt::MoveAction) { - QModelIndex modelIndex; - QStandardItem *startItem; - int startRow = -1; - - int destRow = row; - - // look for the favorite that was dragged - for (int i = 0; i < d->headerItem->rowCount(); i++) { - startItem = d->headerItem->child(i, 0); - if (QFileInfo(startItem->data(Kickoff::UrlRole).toString()).completeBaseName() - == QFileInfo(data->text()).completeBaseName()) { - startRow = i; - break; - } - } - - if (startRow < 0) { - bool dropped = false; - foreach (const QUrl &url, data->urls()) { - if (!url.isValid()) { - continue; - } - const QString path = url.toLocalFile(); - if (!KDesktopFile::isDesktopFile(path)) { - continue; - } - KDesktopFile dFile(path); - if (dFile.hasApplicationType() && !dFile.noDisplay()) { - FavoritesModel::add(path); - dropped = true; - } - } - return dropped; - } - - if (destRow < 0) - return false; - - // now move the item to it's new location - FavoritesModel::move(startRow, destRow); - - return true; - } - - return true; -} - -QVariant FavoritesModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != Qt::Horizontal || section != 0) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - return i18nc("@title:column", "Favorites"); - break; - default: - return QVariant(); - } -} - -void FavoritesModel::setNameDisplayOrder(DisplayOrder displayOrder) -{ - if (d->displayOrder == displayOrder) { - return; - } - - d->displayOrder = displayOrder; - - foreach (FavoritesModel* model, Private::models) { - model->clear(); - model->d->init(); - } - - Private::loadFavorites(); -} - -DisplayOrder FavoritesModel::nameDisplayOrder() const -{ - return d->displayOrder; -} - -#include "moc_favoritesmodel.cpp" diff --git a/plasma/applets/kickoff/core/favoritesmodel.h b/plasma/applets/kickoff/core/favoritesmodel.h deleted file mode 100644 index d6044931..00000000 --- a/plasma/applets/kickoff/core/favoritesmodel.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef FAVORITESMODEL_H -#define FAVORITESMODEL_H - -#include "kickoff_export.h" -#include "core/kickoffmodel.h" -#include "core/models.h" - -namespace Kickoff -{ - -/** - * A model which provides an ordered list of 'favorite' items chosen by the user. - * The items may represent documents, folders, applications, devices or anything else - * identified by a URL. - * - * The information persists between sessions. - */ -class KICKOFF_EXPORT FavoritesModel : public KickoffModel -{ - Q_OBJECT - -public: - FavoritesModel(QObject *parent); - virtual ~FavoritesModel(); - - /** Add a new item for @p url to the user's favorites list. */ - static void add(const QString& url); - /** Remove the item associated with @p url from the user's favorites list. */ - static void remove(const QString& url); - /** Returns true if @p url is in the list of the user's favorite URLs. */ - static void move(int startRow, int destRow); - static int numberOfFavorites(); - static void sortFavorites(Qt::SortOrder order); - static bool isFavorite(const QString& url); - - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, - int row, int column, const QModelIndex & parent); - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - void setNameDisplayOrder(DisplayOrder displayOrder); - DisplayOrder nameDisplayOrder() const; - -public Q_SLOTS: - void sortFavoritesAscending(); - void sortFavoritesDescending(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // FAVORITESMODEL_H diff --git a/plasma/applets/kickoff/core/itemhandlers.cpp b/plasma/applets/kickoff/core/itemhandlers.cpp deleted file mode 100644 index 9d5911c1..00000000 --- a/plasma/applets/kickoff/core/itemhandlers.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/itemhandlers.h" - -// Qt -#include - -// KDE -#include -#include -#include -#include -#include -#include - -// KDE Base -#include "kworkspace/kworkspace.h" -#include "kworkspace/kdisplaymanager.h" - -// Local -#include "core/recentapplications.h" - -// DBus -#include "screensaver_interface.h" -#include "ksmserver_interface.h" -#include -#include - -using namespace Kickoff; - -bool ServiceItemHandler::openUrl(const KUrl& url) -{ - KService::Ptr service = KService::serviceByDesktopPath(url.pathOrUrl()); - - if (!service.isNull()) { - RecentApplications::self()->add(service); - } else { - qWarning() << "Failed to find service for" << url; - return false; - } - - new KRun(url, 0); - return true; -} - -bool LeaveItemHandler::openUrl(const KUrl& url) -{ - m_logoutAction = url.path().remove('/'); - - if (m_logoutAction == "sleep") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(suspendRAM())); - return true; - } else if (m_logoutAction == "hibernate") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(suspendDisk())); - return true; - } else if (m_logoutAction == "hybrid") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(suspendHybrid())); - return true; - } else if (m_logoutAction == "lock") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(lock())); - return true; - } else if (m_logoutAction == "switch") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(switchUser())); - return true; - } else if (m_logoutAction == "logout" || m_logoutAction == "logoutonly" || - m_logoutAction == "restart" || m_logoutAction == "shutdown") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(logout())); - return true; - } else if (m_logoutAction == "savesession") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(saveSession())); - return true; - } else if (m_logoutAction == "suspendram") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(suspendRAM())); - return true; - } else if (m_logoutAction == "suspenddisk") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(suspendDisk())); - return true; - } else if (m_logoutAction == "suspendhybrid") { - // decouple dbus call, otherwise we'll run into a dead-lock - QTimer::singleShot(0, this, SLOT(suspendHybrid())); - return true; - } - - return false; -} - -void LeaveItemHandler::logout() -{ - KWorkSpace::ShutdownConfirm confirm = KWorkSpace::ShutdownConfirmDefault; - KWorkSpace::ShutdownType type = KWorkSpace::ShutdownTypeNone; - - if (m_logoutAction == "logout" || m_logoutAction == "logoutonly") { - type = KWorkSpace::ShutdownTypeNone; - } else if (m_logoutAction == "lock") { - kDebug() << "Locking screen"; - } else if (m_logoutAction == "switch") { - kDebug() << "Switching user"; - } else if (m_logoutAction == "restart") { - type = KWorkSpace::ShutdownTypeReboot; - } else if (m_logoutAction == "shutdown") { - type = KWorkSpace::ShutdownTypeHalt; - } - - KWorkSpace::requestShutDown(confirm, type); -} - -void LeaveItemHandler::lock() -{ - QString interface("org.freedesktop.ScreenSaver"); - org::freedesktop::ScreenSaver screensaver(interface, "/ScreenSaver", QDBusConnection::sessionBus()); - screensaver.Lock(); -} - -void LeaveItemHandler::switchUser() -{ - QDBusInterface saveriface( - "org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver" - ); - saveriface.call("Lock"); - KDisplayManager dm; - dm.newSession(); -} - -void LeaveItemHandler::saveSession() -{ - QString interface("org.kde.ksmserver"); - - org::kde::KSMServerInterface ksmserver(interface, "/KSMServer", QDBusConnection::sessionBus()); - if (ksmserver.isValid()) { - ksmserver.saveCurrentSession(); - } -} - -void LeaveItemHandler::suspendRAM() -{ - Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState); -} - -void LeaveItemHandler::suspendDisk() -{ - Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState); -} - -void LeaveItemHandler::suspendHybrid() -{ - Solid::PowerManagement::requestSleep(Solid::PowerManagement::HybridSuspendState); -} diff --git a/plasma/applets/kickoff/core/itemhandlers.h b/plasma/applets/kickoff/core/itemhandlers.h deleted file mode 100644 index 83277935..00000000 --- a/plasma/applets/kickoff/core/itemhandlers.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef ITEMHANDLERS_H -#define ITEMHANDLERS_H - -#include - -#include "kickoff_export.h" -#include "core/urlitemlauncher.h" - -namespace Kickoff -{ - -class KICKOFF_EXPORT ServiceItemHandler : public UrlItemHandler -{ -public: - virtual bool openUrl(const KUrl& url); -}; -class KICKOFF_EXPORT LeaveItemHandler : public QObject, public UrlItemHandler -{ - Q_OBJECT -public: - virtual bool openUrl(const KUrl& url); - -private Q_SLOTS: - void logout(); - void lock(); - void switchUser(); - void saveSession(); - void suspendRAM(); - void suspendDisk(); - void suspendHybrid(); - -private: - QString m_logoutAction; -}; - -} - -#endif // ITEMHANDLERS_H - diff --git a/plasma/applets/kickoff/core/kickoffabstractmodel.cpp b/plasma/applets/kickoff/core/kickoffabstractmodel.cpp deleted file mode 100644 index ea51c050..00000000 --- a/plasma/applets/kickoff/core/kickoffabstractmodel.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright 2008 Marco Martin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/kickoffabstractmodel.h" - -// Qt -#include - -// KDE -#include -#include - -// Local -#include "core/models.h" - -using namespace Kickoff; - -KickoffAbstractModel::KickoffAbstractModel(QObject *parent) - : QAbstractItemModel(parent) -{} - -KickoffAbstractModel::~KickoffAbstractModel() -{} - -Qt::ItemFlags KickoffAbstractModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); - - if (index.isValid()) { - return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; - } else { - return 0; - } -} - -QMimeData *KickoffAbstractModel::mimeData(const QModelIndexList &indexes) const -{ - KUrl::List urls; - QByteArray itemData; - - foreach(const QModelIndex &index, indexes) { - KUrl itemUrl = KUrl(data(index, UrlRole).toString()); - if (itemUrl.isValid()) { - urls << itemUrl; - } - } - - QMimeData *mimeData = new QMimeData(); - - if (!urls.isEmpty()) { - urls.populateMimeData(mimeData); - } - - return mimeData; -} - -QStringList KickoffAbstractModel::mimeTypes() const -{ - QStringList types; - types << QLatin1String("text/uri-list"); - return types; -} - -Qt::DropActions KickoffAbstractModel::supportedDropActions() const -{ - return 0; -} - -Qt::DropActions KickoffAbstractModel::supportedDragActions() const -{ - return Qt::CopyAction; -} - -#include "moc_kickoffabstractmodel.cpp" - diff --git a/plasma/applets/kickoff/core/kickoffabstractmodel.h b/plasma/applets/kickoff/core/kickoffabstractmodel.h deleted file mode 100644 index 699a57e5..00000000 --- a/plasma/applets/kickoff/core/kickoffabstractmodel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright 2008 Marco Martin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KICKOFFABSTRACTMODEL_H -#define KICKOFFABSTRACTMODEL_H - -#include "kickoff_export.h" - -// Qt -#include - -// KDE - -namespace Kickoff -{ - -/** - * Base model for Kickoff models based on QAbstractItemModel, enables drag and drop support - */ -class KICKOFF_EXPORT KickoffAbstractModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - /** Construct a new KickoffModel with the specified parent. */ - KickoffAbstractModel(QObject *parent = 0); - virtual ~KickoffAbstractModel(); - - //Reimplementations - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; - virtual QStringList mimeTypes() const; - virtual Qt::DropActions supportedDropActions() const; - virtual Qt::DropActions supportedDragActions() const; -}; - -} - -#endif // KICKOFFABSTRACTMODEL_H diff --git a/plasma/applets/kickoff/core/kickoffmodel.cpp b/plasma/applets/kickoff/core/kickoffmodel.cpp deleted file mode 100644 index d51b1874..00000000 --- a/plasma/applets/kickoff/core/kickoffmodel.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright 2008 Marco Martin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/kickoffmodel.h" - -// Qt -#include - -// KDE -#include -#include - -// Local -#include "core/models.h" - -using namespace Kickoff; - -KickoffModel::KickoffModel(QObject *parent) - : QStandardItemModel(parent) -{ -} - -KickoffModel::~KickoffModel() -{} - -Qt::ItemFlags KickoffModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index); - - if (index.isValid()) { - return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; - } else { - return 0; - } -} - -QMimeData *KickoffModel::mimeData(const QModelIndexList &indexes) const -{ - KUrl::List urls; - - foreach (const QModelIndex &index, indexes) { - KUrl itemUrl = KUrl(data(index, UrlRole).toString()); - if (itemUrl.isValid()) { - urls << itemUrl; - } - } - - QMimeData *mimeData = new QMimeData(); - - if (!urls.isEmpty()) { - urls.populateMimeData(mimeData); - } - - return mimeData; -} - -QStringList KickoffModel::mimeTypes() const -{ - QStringList types; - types << QLatin1String("text/uri-list"); - return types; -} - -Qt::DropActions KickoffModel::supportedDropActions() const -{ - return Qt::MoveAction; -} - -Qt::DropActions KickoffModel::supportedDragActions() const -{ - return Qt::CopyAction; -} - -#include "moc_kickoffmodel.cpp" - diff --git a/plasma/applets/kickoff/core/kickoffmodel.h b/plasma/applets/kickoff/core/kickoffmodel.h deleted file mode 100644 index c6647377..00000000 --- a/plasma/applets/kickoff/core/kickoffmodel.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright 2008 Marco Martin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KICKOFFMODEL_H -#define KICKOFFMODEL_H - -#include "kickoff_export.h" - -// Qt -#include - -// KDE - -namespace Kickoff -{ - -/** - * Base model for Kickoff models based on QStandardItemModel, enables drag and drop support - */ -class KICKOFF_EXPORT KickoffModel : public QStandardItemModel -{ - Q_OBJECT - -public: - /** Construct a new KickoffModel with the specified parent. */ - KickoffModel(QObject *parent = 0); - virtual ~KickoffModel(); - - //Reimplementations - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; - virtual QStringList mimeTypes() const; - virtual Qt::DropActions supportedDropActions() const; - virtual Qt::DropActions supportedDragActions() const; - -private: -}; - -} - -#endif // KICKOFFMODEL_H diff --git a/plasma/applets/kickoff/core/kickoffproxymodel.cpp b/plasma/applets/kickoff/core/kickoffproxymodel.cpp deleted file mode 100644 index dd661067..00000000 --- a/plasma/applets/kickoff/core/kickoffproxymodel.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright 2008 Marco Martin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/kickoffproxymodel.h" - -// Qt -#include - -// KDE -#include -#include - -// Local -#include "core/models.h" - -using namespace Kickoff; - -KickoffProxyModel::KickoffProxyModel(QObject *parent) - : QAbstractProxyModel(parent) -{} - -KickoffProxyModel::~KickoffProxyModel() -{} - -Qt::ItemFlags KickoffProxyModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags defaultFlags = QAbstractProxyModel::flags(index); - - if (index.isValid()) { - return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; - } else { - return 0; - } -} - -QMimeData *KickoffProxyModel::mimeData(const QModelIndexList &indexes) const -{ - KUrl::List urls; - QByteArray itemData; - - foreach(const QModelIndex &index, indexes) { - KUrl itemUrl = KUrl(data(index, UrlRole).toString()); - if (itemUrl.isValid()) { - urls << itemUrl; - } - } - - QMimeData *mimeData = new QMimeData(); - - if (!urls.isEmpty()) { - urls.populateMimeData(mimeData); - } - - return mimeData; -} - -QStringList KickoffProxyModel::mimeTypes() const -{ - QStringList types; - types << QLatin1String("text/uri-list"); - return types; -} - -Qt::DropActions KickoffProxyModel::supportedDropActions() const -{ - return 0; -} - -Qt::DropActions KickoffProxyModel::supportedDragActions() const -{ - return Qt::CopyAction; -} - -#include "moc_kickoffproxymodel.cpp" - diff --git a/plasma/applets/kickoff/core/kickoffproxymodel.h b/plasma/applets/kickoff/core/kickoffproxymodel.h deleted file mode 100644 index 577ddd01..00000000 --- a/plasma/applets/kickoff/core/kickoffproxymodel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright 2008 Marco Martin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KICKOFFPROXYMODEL_H -#define KICKOFFPROXYMODEL_H - -#include "kickoff_export.h" - -// Qt -#include - -// KDE - -namespace Kickoff -{ - -/** - * Base model for Kickoff models based on QAbstractProxyModel, enables drag and drop support - */ -class KICKOFF_EXPORT KickoffProxyModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - /** Construct a new KickoffModel with the specified parent. */ - KickoffProxyModel(QObject *parent = 0); - virtual ~KickoffProxyModel(); - - //Reimplementations - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; - virtual QStringList mimeTypes() const; - virtual Qt::DropActions supportedDropActions() const; - virtual Qt::DropActions supportedDragActions() const; -}; - -} - -#endif // KICKOFFPROXYMODEL_H diff --git a/plasma/applets/kickoff/core/krunnermodel.cpp b/plasma/applets/kickoff/core/krunnermodel.cpp deleted file mode 100644 index 6c7ebbb6..00000000 --- a/plasma/applets/kickoff/core/krunnermodel.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright 2009 Ivan Cukic - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/krunnermodel.h" - -// Qt -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include - -// Local -#include "core/recentapplications.h" - -#define DELAY_TIME 50 - -using namespace Kickoff; - -Plasma::RunnerManager* _runnerManager = nullptr; - -static KService::Ptr serviceForUrl(const KUrl &url) -{ - QString runner = url.host(); - QString id = url.path(); - - if (id.startsWith(QLatin1Char('/'))) { - id = id.remove(0, 1); - } - - if (runner != QLatin1String("services")) { - return KService::Ptr(nullptr); - } - - // URL path example: services_kde4-kate.desktop - // or: services_firefox.desktop - id.remove("services_"); - - return KService::serviceByStorageId(id); -} - -bool KRunnerItemHandler::openUrl(const KUrl& url) -{ - QString runner = url.host(); - QString id = url.path(); - if (id.startsWith(QLatin1Char('/'))) { - id = id.remove(0, 1); - } - - // Since krunner:// urls can't be added to recent applications, - // we find the local .desktop entry. - - KService::Ptr service = serviceForUrl(url); - if (service) { - RecentApplications::self()->add(service); - } else { - qWarning() << "Failed to find service for" << url; - } - - KRunnerModel::runnerManager()->run(id); - return true; -} - -class KRunnerModel::Private { -public: - QBasicTimer searchDelay; - QString searchQuery; - DisplayOrder displayOrder; -}; - -KRunnerModel::KRunnerModel(QObject *parent) - : KickoffModel(parent) - , d(new Private()) -{ - connect( - runnerManager(), SIGNAL(matchesChanged(QList)), - this, SLOT(matchesChanged(QList)) - ); -} - -KRunnerModel::~KRunnerModel() -{ - delete d; -} - -void KRunnerModel::setQuery(const QString& query) -{ - runnerManager()->reset(); - clear(); - - d->searchQuery = query.trimmed(); - - if (d->searchQuery.isEmpty()) { - return; - } - - d->searchDelay.start(DELAY_TIME, this); -} - -void KRunnerModel::timerEvent(QTimerEvent * event) -{ - KickoffModel::timerEvent(event); - - if (event->timerId() == d->searchDelay.timerId()) { - d->searchDelay.stop(); - runnerManager()->launchQuery(d->searchQuery); - }; -} - -void KRunnerModel::setNameDisplayOrder(DisplayOrder displayOrder) -{ - d->displayOrder = displayOrder; -} - -DisplayOrder KRunnerModel::nameDisplayOrder() const -{ - return d->displayOrder; -} - -void KRunnerModel::matchesChanged(const QList< Plasma::QueryMatch > & m) -{ - QList< Plasma::QueryMatch > matches = m; - - qSort(matches.begin(), matches.end()); - - clear(); - - while (matches.size()) { - Plasma::QueryMatch match = matches.takeLast(); - - appendRow( - StandardItemFactory::createItem( - match.icon(), - match.text(), - match.subtext(), - QString("krunner://") + match.runner()->id() + "/" + match.id() - ) - ); - } -} - -Qt::ItemFlags KRunnerModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags flags = KickoffModel::flags(index); - - if (index.isValid()) { - KUrl url = data(index, UrlRole).toString(); - QString host = url.host(); - if (host != "services") { - flags &= ~ (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); - } - } else { - flags = 0; - } - - return flags; -} - -QMimeData * KRunnerModel::mimeData(const QModelIndexList &indexes) const -{ - KUrl::List urls; - - foreach (const QModelIndex &index, indexes) { - KUrl url = data(index, UrlRole).toString(); - - KService::Ptr service = serviceForUrl(url); - - if (service) { - urls << KUrl(service->entryPath()); - } - } - - QMimeData *mimeData = new QMimeData(); - - if (!urls.isEmpty()) { - urls.populateMimeData(mimeData); - } - - return mimeData; - -} - -Plasma::RunnerManager* KRunnerModel::runnerManager() -{ - if (!_runnerManager) { - KConfigGroup conf = componentData().config()->group("Plugins"); - QStringList allowed; - foreach (KPluginInfo plugin, Plasma::RunnerManager::listRunnerInfo()) { - plugin.load(conf); - if (plugin.isPluginEnabled()) { - allowed.append(plugin.pluginName()); - } - } - // NOTE: Plasma::RunnerManager uses sub-group named PlasmaRunnerManager - conf = componentData().config()->group("KRunner"); - conf.writeEntry("loadAll", false); - conf.sync(); - _runnerManager = new Plasma::RunnerManager(conf); - _runnerManager->setAllowedRunners(allowed); - } - return _runnerManager; -} - - -#include "moc_krunnermodel.cpp" diff --git a/plasma/applets/kickoff/core/krunnermodel.h b/plasma/applets/kickoff/core/krunnermodel.h deleted file mode 100644 index 0f9450bf..00000000 --- a/plasma/applets/kickoff/core/krunnermodel.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright 2009 Ivan Cukic - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KRUNNERMODEL_H -#define KRUNNERMODEL_H - -#include "kickoff_export.h" -#include "core/models.h" -#include "core/kickoffmodel.h" -#include "core/urlitemlauncher.h" - -#include -#include - -namespace Kickoff { - -class KICKOFF_EXPORT KRunnerItemHandler : public UrlItemHandler { -public: - virtual bool openUrl(const KUrl& url); -}; - -class KICKOFF_EXPORT KRunnerModel : public KickoffModel -{ - Q_OBJECT - -public: - KRunnerModel(QObject *parent); - virtual ~KRunnerModel(); - void setNameDisplayOrder(DisplayOrder displayOrder); - DisplayOrder nameDisplayOrder() const; - - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; - // virtual QStringList mimeTypes() const; - // virtual Qt::DropActions supportedDropActions() const; - // virtual Qt::DropActions supportedDragActions() const; - - static Plasma::RunnerManager* runnerManager(); -private: - void timerEvent(QTimerEvent * event); - -public Q_SLOTS: - void setQuery(const QString& query); - -private Q_SLOTS: - void matchesChanged(const QList< Plasma::QueryMatch > & matches); - -Q_SIGNALS: - void resultsAvailable(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // KRUNNERMODEL_H - diff --git a/plasma/applets/kickoff/core/leavemodel.cpp b/plasma/applets/kickoff/core/leavemodel.cpp deleted file mode 100644 index e8e9f743..00000000 --- a/plasma/applets/kickoff/core/leavemodel.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/leavemodel.h" - -// Qt -#include - -// KDE -#include -#include -#include -#include -#include -#include - -// Local -#include "core/models.h" - -using namespace Kickoff; - -QStandardItem* LeaveModel::createStandardItem(const QString& url) -{ - //Q_ASSERT(KUrl(url).scheme() == "leave"); - QStandardItem *item = new QStandardItem(); - const QString basename = QFileInfo(url).baseName(); - if (basename == "logoutonly") { - item->setText(i18n("Log out")); - item->setIcon(KIcon("system-log-out")); - item->setData(i18n("End session"), Kickoff::SubTitleRole); - } else if (basename == "lock") { - item->setText(i18n("Lock")); - item->setIcon(KIcon("system-lock-screen")); - item->setData(i18n("Lock screen"), Kickoff::SubTitleRole); - } else if (basename == "switch") { - item->setText(i18n("Switch user")); - item->setIcon(KIcon("system-switch-user")); - item->setData(i18n("Start a parallel session as a different user"), Kickoff::SubTitleRole); - } else if (basename == "shutdown") { - item->setText(i18n("Shut down")); - item->setIcon(KIcon("system-shutdown")); - item->setData(i18n("Turn off computer"), Kickoff::SubTitleRole); - } else if (basename == "restart") { - item->setText(i18nc("Restart computer", "Restart")); - item->setIcon(KIcon("system-reboot")); - item->setData(i18n("Restart computer"), Kickoff::SubTitleRole); - } else if (basename == "savesession") { - item->setText(i18n("Save Session")); - item->setIcon(KIcon("document-save")); - item->setData(i18n("Save current session for next login"), Kickoff::SubTitleRole); - } else if (basename == "suspenddisk") { - item->setText(i18n("Hibernate")); - item->setIcon(KIcon("system-suspend-hibernate")); - item->setData(i18n("Suspend to disk"), Kickoff::SubTitleRole); - } else if (basename == "suspendram") { - item->setText(i18n("Sleep")); - item->setIcon(KIcon("system-suspend")); - item->setData(i18n("Suspend to RAM"), Kickoff::SubTitleRole); - } else if (basename == "suspendhybrid") { - item->setText(i18n("Hybrid Suspend")); - item->setIcon(KIcon("system-suspend")); - item->setData(i18n("Hybrid Suspend"), Kickoff::SubTitleRole); - } else { - item->setText(basename); - item->setData(url, Kickoff::SubTitleRole); - } - item->setData(url, Kickoff::UrlRole); - return item; -} - -LeaveModel::LeaveModel(QObject *parent) - : QStandardItemModel(parent) -{ -} - -QVariant LeaveModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != Qt::Horizontal || section != 0) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - return i18n("Leave"); - break; - default: - return QVariant(); - } -} - -void LeaveModel::updateModel() -{ - clear(); - - // Session Options - QStandardItem *sessionOptions = new QStandardItem(i18n("Session")); - - // Logout - QStandardItem *logoutOption = createStandardItem("leave:/logoutonly"); - sessionOptions->appendRow(logoutOption); - - // Lock - QStandardItem *lockOption = createStandardItem("leave:/lock"); - sessionOptions->appendRow(lockOption); - - // Save Session - KConfigGroup c(KSharedConfig::openConfig("ksmserverrc", KConfig::NoGlobals), "General"); - if (c.readEntry("loginMode") == "restoreSavedSession") { - QStandardItem *saveSessionOption = createStandardItem("leave:/savesession"); - sessionOptions->appendRow(saveSessionOption); - } - - // Switch User - if (KDisplayManager().isSwitchable()) { - QStandardItem *switchUserOption = createStandardItem("leave:/switch"); - sessionOptions->appendRow(switchUserOption); - } - - // System Options - QStandardItem *systemOptions = new QStandardItem(i18n("System")); - bool addSystemSession = false; - - QSet< Solid::PowerManagement::SleepState > spdMethods = Solid::PowerManagement::supportedSleepStates(); - if (spdMethods.contains(Solid::PowerManagement::SuspendState)) { - QStandardItem *suspendramOption = createStandardItem("leave:/suspendram"); - systemOptions->appendRow(suspendramOption); - addSystemSession = true; - } - - if (spdMethods.contains(Solid::PowerManagement::HibernateState)) { - QStandardItem *suspenddiskOption = createStandardItem("leave:/suspenddisk"); - systemOptions->appendRow(suspenddiskOption); - addSystemSession = true; - } - - if (spdMethods.contains(Solid::PowerManagement::HybridSuspendState)) { - QStandardItem *suspendhybridOption = createStandardItem("leave:/suspendhybrid"); - systemOptions->appendRow(suspendhybridOption); - addSystemSession = true; - } - - if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot)) { - // Restart - QStandardItem *restartOption = createStandardItem("leave:/restart"); - systemOptions->appendRow(restartOption); - addSystemSession = true; - } - - if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt)) { - // Shutdown - QStandardItem *shutDownOption = createStandardItem("leave:/shutdown"); - systemOptions->appendRow(shutDownOption); - addSystemSession = true; - } - - appendRow(sessionOptions); - if (addSystemSession) { - appendRow(systemOptions); - } else { - delete systemOptions; - } -} - -#include "moc_leavemodel.cpp" diff --git a/plasma/applets/kickoff/core/leavemodel.h b/plasma/applets/kickoff/core/leavemodel.h deleted file mode 100644 index 9f583c80..00000000 --- a/plasma/applets/kickoff/core/leavemodel.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef LEAVEMODEL_H -#define LEAVEMODEL_H - -#include "kickoff_export.h" - -#include - -namespace Kickoff -{ - -class KICKOFF_EXPORT LeaveModel : public QStandardItemModel -{ - Q_OBJECT - -public: - LeaveModel(QObject *parent); - - static QStandardItem* createStandardItem(const QString& url); - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - void updateModel(); -}; - -} - -#endif // LEAVEMODEL_H diff --git a/plasma/applets/kickoff/core/models.cpp b/plasma/applets/kickoff/core/models.cpp deleted file mode 100644 index 817c64fb..00000000 --- a/plasma/applets/kickoff/core/models.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/models.h" -#include "core/leavemodel.h" - -// Qt -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Kickoff; - -namespace Kickoff -{ - -Q_GLOBAL_STATIC_WITH_ARGS(KUrl, homeUrl, (QDir::homePath())) -Q_GLOBAL_STATIC_WITH_ARGS(KUrl, remoteUrl, ("remote:/")) -K_GLOBAL_STATIC(StandardItemFactoryData, factoryData) - -StandardItemFactoryData* deviceFactoryData() -{ - return factoryData; -} -} // namespace Kickoff - -QStandardItem *StandardItemFactory::createItemForUrl(const QString& urlString, DisplayOrder displayOrder) -{ - KUrl url(urlString); - - QStandardItem *item = 0; - - // Match files ending with ".desktop" and being local or having a relative - // path. For instance applications that still installs .desktop files at - // /usr/share/applnk, like KVirc 3 - const bool isDesktopFile = urlString.endsWith(QLatin1String(".desktop")); - if (isDesktopFile && (url.isLocalFile() || url.isRelative())) { - // .desktop files may be services (type field == 'Application' or 'Service') - // or they may be other types such as links. - // - // first look in the KDE service database to see if this file is a service, - // otherwise represent it as a generic .desktop file - KService::Ptr service = KService::serviceByDesktopPath(url.toLocalFile()); - if (service) { - return createItemForService(service, displayOrder); - } - - item = new QStandardItem(); - KDesktopFile desktopFile(url.toLocalFile()); - QString urlFileName = QFileInfo(urlString).fileName(); - if (isDesktopFile) { - urlFileName = urlFileName.mid(0, urlFileName.size() - 8); - } - item->setText(urlFileName); - item->setIcon(KIcon(desktopFile.readIcon())); - - //FIXME: desktopUrl is a hack around borkage in KRecentDocuments which - // stores a path in the URL field! - KUrl desktopUrl(desktopFile.desktopGroup().readPathEntry("URL", QString())); - if (!desktopUrl.url().isEmpty()) { - item->setData(desktopUrl.url(), Kickoff::UrlRole); - } else { - // desktopUrl.url() is empty if the file doesn't exist so set the - // url role to that which was passed so that the item can still be - // manually removed - item->setData(urlString, Kickoff::UrlRole); - } - - QString subTitle = desktopUrl.isLocalFile() ? desktopUrl.toLocalFile() : desktopUrl.prettyUrl(); - item->setData(subTitle, Kickoff::SubTitleRole); - - setSpecialUrlProperties(desktopUrl, item); - } else if (url.scheme() == "leave") { - item = LeaveModel::createStandardItem(urlString); - } else { - item = new QStandardItem(); - const QString subTitle = url.isLocalFile() ? url.toLocalFile() : url.prettyUrl(); - QString basename = QFileInfo(url.prettyUrl()).fileName(); - if (basename.isNull()) { - basename = subTitle; - } - - item->setText(basename); - item->setIcon(KIcon(KMimeType::iconNameForUrl(url))); - item->setData(url.url(), Kickoff::UrlRole); - item->setData(subTitle, Kickoff::SubTitleRole); - - setSpecialUrlProperties(url, item); - } - - return item; -} - -void StandardItemFactory::setSpecialUrlProperties(const KUrl& url, QStandardItem *item) -{ - // specially handled URLs - if (homeUrl() && url == *homeUrl()) { - item->setText(i18n("Home Folder")); - item->setIcon(KIcon("user-home")); - } else if (remoteUrl() && url == *remoteUrl()) { - item->setText(i18n("Network Folders")); - } -} - -QStandardItem *StandardItemFactory::createItem(const QIcon & icon, const QString & title, - const QString & description, const QString & url) -{ - QStandardItem *appItem = new QStandardItem; - - appItem->setText(title); - appItem->setIcon(icon); - appItem->setData(description, Kickoff::SubTitleRole); - appItem->setData(url, Kickoff::UrlRole); - - return appItem; -} - -QStandardItem *StandardItemFactory::createItemForService(KService::Ptr service, DisplayOrder displayOrder) -{ - QStandardItem *appItem = new QStandardItem; - - QString genericName = service->genericName(); - QString appName = service->name(); - bool nameFirst = displayOrder == NameBeforeDescription; - appItem->setText(nameFirst || genericName.isEmpty() ? appName : genericName); - appItem->setIcon(KIcon(service->icon())); - appItem->setData(service->entryPath(), Kickoff::UrlRole); - - if (nameFirst) { - if (!genericName.isEmpty()) { - appItem->setData(genericName, Kickoff::SubTitleRole); - } - } else if (!genericName.isEmpty()) { - // we only set the subtitle to appname if the generic name is empty because if - // the generic name IS empty, then the app name is used as the title role - // and we don't want it repeated twice. - appItem->setData(appName, Kickoff::SubTitleRole); - } - - return appItem; -} - -bool Kickoff::isLaterVersion(KService::Ptr first , KService::Ptr second) -{ - // a very crude heuristic using the .desktop path names - // which only understands kde3 vs kde4 - bool firstIsKde4 = first->entryPath().contains("kde4"); - bool secondIsKde4 = second->entryPath().contains("kde4"); - - return firstIsKde4 && !secondIsKde4; -} - -QStringList Kickoff::systemApplicationList() -{ - KConfigGroup appsGroup = componentData().config()->group("SystemApplications"); - QStringList apps; - apps << "systemsettings"; - apps = appsGroup.readEntry("DesktopFiles", apps); - return apps; -} - -#if 0 -void Kickoff::swapModelIndexes(QModelIndex& first, QModelIndex& second) -{ - Q_ASSERT(first.isValid()); - Q_ASSERT(second.isValid()); - - QAbstractItemModel *firstModel = const_cast(first.model()); - QAbstractItemModel *secondModel = const_cast(second.model()); - - Q_ASSERT(firstModel && secondModel); - - QMap firstIndexData = firstModel->itemData(first); - QMap secondIndexData = secondModel->itemData(second); - - firstModel->setItemData(first, secondIndexData); - secondModel->setItemData(second, firstIndexData); -} -#endif - -K_GLOBAL_STATIC_WITH_ARGS(KComponentData, kickoffComponent, ("kickoff", QByteArray(), KComponentData::SkipMainComponentRegistration)) -KComponentData Kickoff::componentData() -{ - return *kickoffComponent; -} - - - diff --git a/plasma/applets/kickoff/core/models.h b/plasma/applets/kickoff/core/models.h deleted file mode 100644 index 1be57490..00000000 --- a/plasma/applets/kickoff/core/models.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef MODELS_H -#define MODELS_H - -#include "kickoff_export.h" - -// Katie -#include -#include - -// KDE -#include -#include - -namespace Solid -{ -class Device; -} - -namespace Kickoff -{ -class StandardItemFactoryData -{ -public: - QHash deviceByUrl; -}; - -StandardItemFactoryData* deviceFactoryData(); - -/** - * List of applications contained in the DesktopFiles key in the - * SystemApplications group, used to populate the System model - * @return list of desktop entry names - */ -QStringList systemApplicationList(); - -/** - * Additional data roles for data which the Kickoff models supply with their items - * for use when rendering the items and launching them. - */ -enum DataRole { - /** A sub title to be displayed below the text from the item's Qt::DisplayRole data */ - SubTitleRole = Qt::UserRole + 1, - FirstDataRole = SubTitleRole, - /** The URL to be opened when executing the item. */ - UrlRole = Qt::UserRole + 2, - /** The Solid device identifier for items which represent devices. */ - DeviceUdiRole = Qt::UserRole + 3, - /** The amount of space (in Kilobytes) used for items which represent storage. */ - DiskUsedSpaceRole = Qt::UserRole + 4, - /** The amount of free space (in Kilobytes) for items which represent storage. */ - DiskFreeSpaceRole = Qt::UserRole + 5, - SubTitleMandatoryRole = Qt::UserRole + 6, - /** Is item a separator. **/ - SeparatorRole = Qt::UserRole + 7, - /** relative path of the item */ - RelPathRole = Qt::UserRole + 8, - IconNameRole = Qt::UserRole + 9, - LastDataRole = IconNameRole -}; - -/** - * This enum describes the policy for displaying - * Name of Application - Description - * Description - Name of Application - */ -enum DisplayOrder { - NameAfterDescription, - NameBeforeDescription -}; - -/** - * Factory for creating QStandardItems with appropriate text, icons, URL - * and other Kickoff-specific information for a given URL or Service. - */ -class StandardItemFactory -{ -public: - static QStandardItem *createItemForUrl(const QString& url, DisplayOrder displayOrder); - static QStandardItem *createItemForService(KService::Ptr service, - DisplayOrder displayOrder); - static QStandardItem *createItem(const QIcon & icon, const QString & title, - const QString & description, const QString & url); - -private: - static void setSpecialUrlProperties(const KUrl& url, QStandardItem *item); -}; - -/** - * Abstract base class for delegates which provide information about a model - * item's state in a particular view. - */ -class ItemStateProvider -{ -public: - virtual ~ItemStateProvider() {} - - /** - * Returns true if a @p index should be drawn in the view or - * false if it should be hidden. - */ - virtual bool isVisible(const QModelIndex& index) const = 0; -}; - -// returns true if 'first' represents a more recent version of -// an application than 'second' -// -// eg. isLaterVersion(myapp_kde4,myapp_kde3) returns true -bool isLaterVersion(KService::Ptr first , KService::Ptr second); - -#if 0 -/** Swaps the data for two indexes in a QAbstractItemModel */ -void swapModelIndexes(QModelIndex& first, QModelIndex& second); -#endif - -// returns the Kickoff component data, this is mainly used -// to access the Kickoff shared config data -KICKOFF_EXPORT KComponentData componentData(); -} - -#endif //MODELS_H diff --git a/plasma/applets/kickoff/core/org.kde.kickoff.recent.xml b/plasma/applets/kickoff/core/org.kde.kickoff.recent.xml deleted file mode 100644 index d013f622..00000000 --- a/plasma/applets/kickoff/core/org.kde.kickoff.recent.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/plasma/applets/kickoff/core/org.kde.kickoff.xml b/plasma/applets/kickoff/core/org.kde.kickoff.xml deleted file mode 100644 index b0f5d097..00000000 --- a/plasma/applets/kickoff/core/org.kde.kickoff.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/plasma/applets/kickoff/core/recentapplications.cpp b/plasma/applets/kickoff/core/recentapplications.cpp deleted file mode 100644 index a443a1a0..00000000 --- a/plasma/applets/kickoff/core/recentapplications.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/recentapplications.h" - -// Qt -#include -#include - -// KDE -#include -#include - -// Local -#include "core/models.h" - -using namespace Kickoff; - -class RecentApplications::Private -{ -public: - class ServiceInfo; - - Private() : defaultMaxServices(DEFAULT_MAX_SERVICES) { - KConfigGroup recentGroup = componentData().config()->group("RecentlyUsed"); - QList recentApplications = recentGroup.readEntry("Applications", QList()); - defaultMaxServices = maxServices = qMax(0, recentGroup.readEntry("MaxApplications", defaultMaxServices)); - - // TESTING - // the actual last date/time is not currently recorded, instead we just use - // the current date/time and adjust it by one second after each item is added - // to preserve the order of the applications in the list loaded from the KConfig - // source - QDateTime dateTime = QDateTime::currentDateTime(); - foreach(const QString& application, recentApplications) { - ServiceInfo info; - info.storageId = application; - info.startCount = 1; - info.lastStartedTime = dateTime; - addEntry(info.storageId, info); - dateTime = dateTime.addSecs(1); - } - }; - ~Private() { - KConfigGroup recentGroup = componentData().config()->group("RecentlyUsed"); - - QList services = serviceInfo.values(); - qSort(services.begin(), services.end()); - - // TESTING - // only the desktop file used is currently recorded, information such - // as start count and date/time of last used is lost - QList recentApplications; - foreach(const ServiceInfo& info, services) { - recentApplications << info.storageId; - } - - recentGroup.writeEntry("Applications", recentApplications); - recentGroup.config()->sync(); - } - void addEntry(const QString& id, ServiceInfo& info) { - // if this service is already in the list then remove the existing - // queue entry (so that there are no duplicates in the queue) - if (serviceInfo.contains(id)) { - kDebug() << "Duplicate entry added. Removing existing entry from queue."; - serviceQueue.removeAll(id); - } - - serviceQueue.append(id); - serviceInfo.insert(id, info); - } - - void removeExpiredEntries() { - // if more than the maximum number of services have been added - // remove the least recently used service - while (serviceQueue.count() > maxServices) { - QString removeId = serviceQueue.takeFirst(); - kDebug() << "More than the maximal " << maxServices << " services added. Removing" << removeId << "from queue."; - serviceInfo.remove(removeId); - emit instance.applicationRemoved(KService::serviceByStorageId(removeId)); - } - } - - class ServiceInfo - { - public: - ServiceInfo() : startCount(0) {} - - QString storageId; - int startCount; - QDateTime lastStartedTime; - - bool operator<(const ServiceInfo& rhs) const { - return this->lastStartedTime < rhs.lastStartedTime; - } - }; - - static const int DEFAULT_MAX_SERVICES = 5; - int defaultMaxServices, maxServices; - // queue to keep track of the order in which services have been used - // (most recently used at the back) - QList serviceQueue; - QHash serviceInfo; - RecentApplications instance; -}; -K_GLOBAL_STATIC(RecentApplications::Private, privateSelf) - -RecentApplications *RecentApplications::self() -{ - return &privateSelf->instance; -} - -RecentApplications::RecentApplications() -{ -} - -QList RecentApplications::recentApplications() const -{ - QList services = privateSelf->serviceInfo.values(); - qSort(services.begin(), services.end(), qGreater()); - - QList servicePtrs; - foreach(const Private::ServiceInfo& info, services) { - KService::Ptr s = KService::serviceByStorageId(info.storageId); - - if (s) { - servicePtrs << s; - } - } - return servicePtrs; -} -int RecentApplications::startCount(KService::Ptr service) const -{ - return privateSelf->serviceInfo[service->storageId()].startCount; -} -QDateTime RecentApplications::lastStartedTime(KService::Ptr service) const -{ - return privateSelf->serviceInfo[service->storageId()].lastStartedTime; -} -void RecentApplications::setMaximum(int maximum) -{ - Q_ASSERT(maximum >= 0); - privateSelf->maxServices = maximum; - privateSelf->removeExpiredEntries(); -} -int RecentApplications::maximum() const -{ - return privateSelf->maxServices; -} -int RecentApplications::defaultMaximum() const -{ - return privateSelf->defaultMaxServices; -} -void RecentApplications::add(KService::Ptr service) -{ - Private::ServiceInfo info = privateSelf->serviceInfo.value(service->storageId()); - info.storageId = service->storageId(); - info.startCount++; - info.lastStartedTime = QDateTime::currentDateTime(); - - privateSelf->addEntry(info.storageId, info); - - kDebug() << "Recent app added" << info.storageId << info.startCount; - emit applicationAdded(service, info.startCount); - - privateSelf->removeExpiredEntries(); -} -void RecentApplications::clear() -{ - privateSelf->serviceInfo.clear(); - emit cleared(); -} - -#include "moc_recentapplications.cpp" diff --git a/plasma/applets/kickoff/core/recentapplications.h b/plasma/applets/kickoff/core/recentapplications.h deleted file mode 100644 index 7d37f8c9..00000000 --- a/plasma/applets/kickoff/core/recentapplications.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef RECENTAPPLICATIONS_H -#define RECENTAPPLICATIONS_H - -#include "kickoff_export.h" - -// Qt -#include -#include - -// KDE -#include - -namespace Kickoff -{ - -/** - * Singleton class which can be used to keep track of recently started applications - * in the Kickoff launcher. - * - * RecentApplications information persists between sessions. - */ -class KICKOFF_EXPORT RecentApplications : public QObject -{ - Q_OBJECT -public: - class Private; - friend class Private; - - static RecentApplications *self(); - - /** - * List of service pointers for recently started applications in the order in which - * they were started, with the most recently used application first. - */ - QList recentApplications() const; - /** Returns the number of times an application represented by @p service has been started. */ - int startCount(KService::Ptr service) const; - /** Returns the last time and date with the application represented by @p service was started. */ - QDateTime lastStartedTime(KService::Ptr service) const; - - /** Sets the maximum number of recently used applications to remember. */ - void setMaximum(int max); - /** Returns the maximum number of recently used applications that are remembered. */ - int maximum() const; - /** Returns the default maximum number of recently used applications that are remembered as defined - either in the configfile as "MaxApplications" or via the DEFAULT_MAX_SERVICES macro. */ - int defaultMaximum() const; - -public Q_SLOTS: - /** - * Registers the startup of an application. This should be called whenever a new application - * or service is started. - */ - void add(KService::Ptr service); - /** Clear the list of recent applications. */ - void clear(); - -Q_SIGNALS: - /** Emitted after add() has been called. */ - void applicationAdded(KService::Ptr service, int startCount); - /** Emitted after remove() has been called. */ - void applicationRemoved(KService::Ptr service); - /** Emitted after clear() has been called. */ - void cleared(); - -private: - RecentApplications(); -}; - -} - -#endif // RECENTAPPLICATIONS_H - - diff --git a/plasma/applets/kickoff/core/recentlyusedmodel.cpp b/plasma/applets/kickoff/core/recentlyusedmodel.cpp deleted file mode 100644 index 61b999de..00000000 --- a/plasma/applets/kickoff/core/recentlyusedmodel.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "core/recentlyusedmodel.h" - -// Qt - -// KDE -#include -#include -#include -#include -#include - -// Local -#include "core/recentapplications.h" -#include "recentadaptor.h" - -using namespace Kickoff; - -class RecentlyUsedModel::Private -{ -public: - Private(RecentlyUsedModel *parent, RecentType recenttype, int maxRecentApps) - : q(parent), - recenttype(recenttype), - maxRecentApps(maxRecentApps >= 0 ? maxRecentApps : Kickoff::RecentApplications::self()->defaultMaximum()), - recentDocumentItem(0), - recentAppItem(0), - displayOrder(NameAfterDescription) - { - } - - void removeExistingItem(const QString& path) { - if (!itemsByPath.contains(path)) { - return; - } - - QStandardItem *existingItem = itemsByPath[path]; - kDebug() << "Removing existing item" << existingItem; - Q_ASSERT(existingItem->parent()); - existingItem->parent()->removeRow(existingItem->row()); - itemsByPath.remove(path); - } - - void addRecentApplication(KService::Ptr service, bool append) { - // remove existing item if any - removeExistingItem(service->entryPath()); - - QStandardItem *appItem = StandardItemFactory::createItemForService(service, displayOrder); - itemsByPath.insert(service->entryPath(), appItem); - - if (append) { - recentAppItem->appendRow(appItem); - } else { - recentAppItem->insertRow(0, appItem); - } - - while (recentAppItem->rowCount() > maxRecentApps) { - QList row = recentAppItem->takeRow(recentAppItem->rowCount() - 1); - - //don't leave pending stuff in itemsByPath - if (!row.isEmpty()) { - itemsByPath.remove(row.first()->data(UrlRole).toString()); - qDeleteAll(row.begin(), row.end()); - } - } - } - - void addRecentDocument(const QString& desktopPath, bool append) { - // remove existing item if any - KDesktopFile desktopFile(desktopPath); - KUrl documentUrl = desktopFile.readUrl(); - - removeExistingItem(documentUrl.url()); - - QStandardItem *documentItem = StandardItemFactory::createItemForUrl(desktopPath, displayOrder); - documentItem->setData(true, Kickoff::SubTitleMandatoryRole); - itemsByPath.insert(desktopPath, documentItem); - - //kDebug() << "Document item" << documentItem << "text" << documentItem->text() << "url" << documentUrl.url(); - if (append) { - recentDocumentItem->appendRow(documentItem); - } else { - recentDocumentItem->insertRow(0, documentItem); - } - } - - void loadRecentDocuments() - { - // create branch for documents and add existing items - recentDocumentItem = new QStandardItem(i18n("Documents")); - const QStringList documents = KRecentDocument::recentDocuments(); - foreach(const QString& document, documents) { - addRecentDocument(document, true); - } - - q->appendRow(recentDocumentItem); - } - - void loadRecentApplications() - { - recentAppItem = new QStandardItem(i18n("Applications")); - - const QList services = RecentApplications::self()->recentApplications(); - for(int i = 0; i < maxRecentApps && i < services.count(); ++i) { - addRecentApplication(services[i], true); - } - - q->appendRow(recentAppItem); - } - - RecentlyUsedModel * const q; - RecentType recenttype; - int maxRecentApps; - - QStandardItem *recentDocumentItem; - QStandardItem *recentAppItem; - QHash itemsByPath; - DisplayOrder displayOrder; -}; - -RecentlyUsedModel::RecentlyUsedModel(QObject *parent, RecentType recenttype, int maxRecentApps) - : KickoffModel(parent), - d(new Private(this, recenttype, maxRecentApps)) -{ - QDBusConnection dbus = QDBusConnection::sessionBus(); - (void)new RecentAdaptor(this); - QDBusConnection::sessionBus().registerObject("/kickoff/RecentAppDoc", this); - dbus.connect(QString(), "/kickoff/RecentAppDoc", "org.kde.plasma", "clearRecentDocumentsAndApplications", this, SLOT(clearRecentDocumentsAndApplications())); - - if (recenttype != DocumentsOnly) { - d->loadRecentApplications(); - - // listen for changes to the list of recent applications - connect(RecentApplications::self(), SIGNAL(applicationAdded(KService::Ptr,int)), - this, SLOT(recentApplicationAdded(KService::Ptr,int))); - connect(RecentApplications::self(), SIGNAL(applicationRemoved(KService::Ptr)), - this, SLOT(recentApplicationRemoved(KService::Ptr))); - connect(RecentApplications::self(), SIGNAL(cleared()), - this, SLOT(recentApplicationsCleared())); - } - - if (recenttype != ApplicationsOnly) { - d->loadRecentDocuments(); - - // listen for changes to the list of recent documents - KDirWatch *recentDocWatch = new KDirWatch(this); - recentDocWatch->addDir(KRecentDocument::recentDocumentDirectory()); - connect(recentDocWatch, SIGNAL(dirty(QString)), this, SLOT(recentDocumentDirty(QString))); - } -} - -RecentlyUsedModel::~RecentlyUsedModel() -{ - delete d; -} - -QVariant RecentlyUsedModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != Qt::Horizontal || section != 0) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - if (d->recenttype == DocumentsAndApplications) { - return i18n("Recently Used"); - } else if (d->recenttype == DocumentsOnly) { - return i18n("Recently Used Documents"); - } else if (d->recenttype == ApplicationsOnly) { - return i18n("Recently Used Applications"); - } - default: - return QVariant(); - } -} - -void RecentlyUsedModel::setNameDisplayOrder(DisplayOrder displayOrder) -{ - if (d->displayOrder == displayOrder) { - return; - } - - d->displayOrder = displayOrder; - - d->itemsByPath.clear(); - clear(); - - if (d->recenttype != DocumentsOnly) { - d->loadRecentApplications(); - } - - if (d->recenttype != ApplicationsOnly) { - d->loadRecentDocuments(); - } -} - -DisplayOrder RecentlyUsedModel::nameDisplayOrder() const -{ - return d->displayOrder; -} - -void RecentlyUsedModel::recentDocumentDirty(const QString& path) -{ - kDebug() << "Recent document dirty" << path; - - d->itemsByPath.clear(); - clear(); - - if (d->recenttype != DocumentsOnly) { - d->loadRecentApplications(); - } - - if (d->recenttype != ApplicationsOnly) { - d->loadRecentDocuments(); - } -} - -void RecentlyUsedModel::recentApplicationAdded(KService::Ptr service, int) -{ - if (service) { - d->addRecentApplication(service, false); - } -} - -void RecentlyUsedModel::recentApplicationRemoved(KService::Ptr service) -{ - if (service) { - d->removeExistingItem(service->entryPath()); - } -} - -void RecentlyUsedModel::recentApplicationsCleared() -{ - QSet appItems; - const int rows = d->recentAppItem->rowCount(); - for (int i = 0;i < rows;i++) { - appItems << d->recentAppItem->child(i); - } - QMutableHashIterator iter(d->itemsByPath); - while (iter.hasNext()) { - iter.next(); - if (appItems.contains(iter.value())) { - iter.remove(); - } - } - - d->recentAppItem->removeRows(0, d->recentAppItem->rowCount()); -} - -void RecentlyUsedModel::clearRecentApplications() -{ - RecentApplications::self()->clear(); -} -void RecentlyUsedModel::clearRecentDocuments() -{ - KRecentDocument::clear(); -} - -void RecentlyUsedModel::clearRecentDocumentsAndApplications() -{ - clearRecentDocuments(); - clearRecentApplications(); -} - - -#include "moc_recentlyusedmodel.cpp" - diff --git a/plasma/applets/kickoff/core/recentlyusedmodel.h b/plasma/applets/kickoff/core/recentlyusedmodel.h deleted file mode 100644 index 226294f6..00000000 --- a/plasma/applets/kickoff/core/recentlyusedmodel.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef RECENTLYUSEDMODEL_H -#define RECENTLYUSEDMODEL_H - -#include "kickoff_export.h" -#include "core/kickoffmodel.h" -#include "core/models.h" - -// KDE -#include - -namespace Kickoff -{ - -/** - * Model for the Recently Used view which provides a tree of recently used - * applications and documents. - */ -class KICKOFF_EXPORT RecentlyUsedModel : public KickoffModel -{ - Q_OBJECT - -public: - - /** Defines what the model should display. */ - enum RecentType { - DocumentsAndApplications, ///< display recently used documents and applications. - DocumentsOnly, ///< documents only. recently used applications will not be displayed. - ApplicationsOnly ///< applications only, recently used documents will not be displayed. - }; - - /** Construct a new RecentlyUsedModel with the specified parent. */ - explicit RecentlyUsedModel(QObject *parent = 0, RecentType recenttype = DocumentsAndApplications, int maxRecentApps = -1); - virtual ~RecentlyUsedModel(); - - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - void setNameDisplayOrder(DisplayOrder displayOrder); - DisplayOrder nameDisplayOrder() const; - -public Q_SLOTS: - void clearRecentApplications(); - void clearRecentDocuments(); - void clearRecentDocumentsAndApplications(); - -private Q_SLOTS: - void recentDocumentDirty(const QString& path); - void recentApplicationAdded(KService::Ptr, int startCount); - void recentApplicationRemoved(KService::Ptr); - void recentApplicationsCleared(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // RECENTLYUSEDMODEL_H diff --git a/plasma/applets/kickoff/core/systemmodel.cpp b/plasma/applets/kickoff/core/systemmodel.cpp deleted file mode 100644 index d2f68420..00000000 --- a/plasma/applets/kickoff/core/systemmodel.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "systemmodel.h" - -// Qt -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Local -#include "core/models.h" -#include "core/systemmodel.h" - -using namespace Kickoff; - -static const int APPLICATIONS_ROW = 0; -static const int BOOKMARKS_ROW = 1; -static const int REMOVABLE_ROW = 2; -static const int FIXED_ROW = 3; -static const int LAST_ROW = FIXED_ROW; - -class SystemModel::Private -{ -public: - Private(SystemModel *parent) - : q(parent), - placesModel(new KFilePlacesModel(parent)), - refreshRequested(false) - { - q->setSourceModel(placesModel); - - connect(placesModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - q, SLOT(sourceDataChanged(QModelIndex,QModelIndex))); - connect(placesModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - q, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int))); - connect(placesModel, SIGNAL(rowsInserted(QModelIndex,int,int)), - q, SLOT(sourceRowsInserted(QModelIndex,int,int))); - connect(placesModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - q, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int))); - connect(placesModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), - q, SLOT(sourceRowsRemoved(QModelIndex,int,int))); - - topLevelSections << i18n("Applications") - << i18n("Places") - << i18n("Removable Storage") - << i18n("Storage"); - connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), q, SLOT(reloadApplications())); - } - - SystemModel * const q; - KFilePlacesModel *placesModel; - QStringList topLevelSections; - KService::List appsList; - QMap usageByMountpoint; - QWeakPointer usageFinder; - bool refreshRequested; -}; - -SystemModel::SystemModel(QObject *parent) - : KickoffProxyModel(parent) - , d(new Private(this)) -{ - qRegisterMetaType("UsageInfo"); - reloadApplications(); -} - -SystemModel::~SystemModel() -{ - delete d; -} - -QModelIndex SystemModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - if (!sourceIndex.isValid()) { - return QModelIndex(); - } - - QModelIndex parent; - - if (!d->placesModel->isDevice(sourceIndex)) { - parent = index(BOOKMARKS_ROW, 0); - } else { - bool isFixedDevice = d->placesModel->data(sourceIndex, KFilePlacesModel::FixedDeviceRole).toBool(); - - if (!isFixedDevice) { - parent = index(REMOVABLE_ROW, 0); - } else { - parent = index(FIXED_ROW, 0); - } - } - - return index(sourceIndex.row(), 0, parent); -} - -QModelIndex SystemModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!proxyIndex.isValid() || !proxyIndex.parent().isValid()) { - return QModelIndex(); - } - - return d->placesModel->index(proxyIndex.row(), proxyIndex.column()); -} - -QModelIndex SystemModel::index(int row, int column, const QModelIndex &parent) const -{ - if (!parent.isValid()) { - return createIndex(row, column, 0); - } - - // We use the row+1 of the parent as internal Id. - return createIndex(row, column, parent.row() + 1); -} - -QModelIndex SystemModel::parent(const QModelIndex &item) const -{ - if (item.internalId() > 0) { - return index(item.internalId() - 1, 0); - } else { - return QModelIndex(); - } -} - -int SystemModel::rowCount(const QModelIndex &parent) const -{ - if (!parent.isValid()) { - return LAST_ROW + 1; - } else if (!parent.parent().isValid()) { - switch (parent.row()) { - case APPLICATIONS_ROW: - return d->appsList.size() + 1; - case BOOKMARKS_ROW: - return d->placesModel->rowCount(); - case REMOVABLE_ROW: - return d->placesModel->rowCount(); - default: - return 0; - } - } - - return 0; -} - -int SystemModel::columnCount(const QModelIndex &/*parent*/) const -{ - return 1; -} - -QVariant SystemModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - if (index.internalId() == 0) { - if (role == Qt::DisplayRole) { - return d->topLevelSections[index.row()]; - } else { - return QVariant(); - } - } - - if (index.internalId() - 1 == APPLICATIONS_ROW) { - if (d->appsList.count() < index.row()) { - return QVariant(); - } else if (d->appsList.count() == index.row()) { - // used to be "Run Command" - return QVariant(); - } - - KService::Ptr service = d->appsList[index.row()]; - - switch (role) { - case Qt::DisplayRole: - return service->name(); - case Qt::DecorationRole: - return KIcon(service->icon()); - case SubTitleRole: - return service->genericName(); - case UrlRole: - return service->entryPath(); - default: - return QVariant(); - } - } - - if (role == UrlRole && !d->placesModel->isHidden(mapToSource(index))) { - QModelIndex parent = index.parent(); - QModelIndex sourceIndex = mapToSource(index); - - bool isDevice = d->placesModel->isDevice(sourceIndex); - bool wellPlaced = false; - - if (!isDevice && parent.row() == BOOKMARKS_ROW) { - wellPlaced = true; - } else if (isDevice) { - bool fixed = d->placesModel->data(sourceIndex, KFilePlacesModel::FixedDeviceRole).toBool(); - - if (!fixed && parent.row() == REMOVABLE_ROW) { - wellPlaced = true; - } else if (fixed && parent.row() == FIXED_ROW) { - wellPlaced = true; - } - } - - if (wellPlaced) { - return d->placesModel->url(sourceIndex).url(); - } else { - return QVariant(); - } - } else if (role == DeviceUdiRole) { - QModelIndex sourceIndex = mapToSource(index); - - if (d->placesModel->isDevice(sourceIndex)) { - Solid::Device dev = d->placesModel->deviceForIndex(sourceIndex); - return dev.udi(); - } else { - return QVariant(); - } - } else if (role == SubTitleRole) { - QModelIndex sourceIndex = mapToSource(index); - - if (d->placesModel->isDevice(sourceIndex)) { - Solid::Device dev = d->placesModel->deviceForIndex(sourceIndex); - Solid::StorageAccess *access = dev.as(); - - if (access) { - return access->filePath(); - } - } else if (index.parent().row() != APPLICATIONS_ROW) { - KUrl url = d->placesModel->url(sourceIndex); - return url.isLocalFile() ? url.toLocalFile() : url.prettyUrl(); - } - - return QVariant(); - } else if (role == DiskUsedSpaceRole || role == DiskFreeSpaceRole) { - QModelIndex sourceIndex = mapToSource(index); - QString mp; - - if (d->placesModel->isDevice(sourceIndex)) { - Solid::Device dev = d->placesModel->deviceForIndex(sourceIndex); - Solid::StorageAccess *access = dev.as(); - - if (access) { - mp = access->filePath(); - } - } - - if (!mp.isEmpty() && d->usageByMountpoint.contains(mp)) { - UsageInfo info = d->usageByMountpoint[mp]; - - if (role == DiskUsedSpaceRole) { - return info.used; - } else { - return info.available; - } - } - } - - return d->placesModel->data(mapToSource(index), role); -} - -QVariant SystemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != Qt::Horizontal || section != 0) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - return i18n("Computer"); - break; - default: - return QVariant(); - } -} - -UsageFinder::UsageFinder(QObject *parent) - : QThread(parent) -{ - -} - -void UsageFinder::add(int index, const QString &mountPoint) -{ - //NOTE: this is not particularly perfect for a threaded object ;) - // but the assumption here is that add is called before run() - m_toCheck.append(qMakePair(index, mountPoint)); -} - -void UsageFinder::run() -{ - typedef QPair CheckPair; - foreach (CheckPair check, m_toCheck) { - KDiskFreeSpaceInfo freeSpace = KDiskFreeSpaceInfo::freeSpaceInfo(check.second); - if (freeSpace.isValid()) { - UsageInfo info; - info.used = freeSpace.used() / 1024; - info.available = freeSpace.available() / 1024; - emit usageInfo(check.first, check.second, info); - } - } -} - -void SystemModel::refreshUsageInfo() -{ - if (d->usageFinder) { - d->refreshRequested = true; - } else { - QTimer::singleShot(100, this, SLOT(startUsageInfoFetch())); - } -} - -void SystemModel::setUsageInfo(int index, const QString &mountPoint, const UsageInfo &usageInfo) -{ - QModelIndex sourceIndex = d->placesModel->index(index, 0); - if (sourceIndex.isValid()) { - d->usageByMountpoint[mountPoint] = usageInfo; - QModelIndex index = mapFromSource(sourceIndex); - emit dataChanged(index, index); - } -} - -void SystemModel::stopRefreshingUsageInfo() -{ - d->refreshRequested = false; -} - -void SystemModel::usageFinderFinished() -{ - if (d->refreshRequested) { - d->refreshRequested = false; - QTimer::singleShot(100, this, SLOT(startUsageInfoFetch())); - } -} - -void SystemModel::startUsageInfoFetch() -{ - if (d->usageFinder) { - return; - } - - UsageFinder *usageFinder = new UsageFinder(this); - d->usageFinder = usageFinder; - connect(usageFinder, SIGNAL(finished()), - this, SLOT(usageFinderFinished())); - connect(usageFinder, SIGNAL(finished()), - usageFinder, SLOT(deleteLater())); - connect(usageFinder, SIGNAL(usageInfo(int,QString,UsageInfo)), - this, SLOT(setUsageInfo(int,QString,UsageInfo))); - - bool hasDevices = false; - - for (int i = 0; i < d->placesModel->rowCount(); ++i) { - QModelIndex sourceIndex = d->placesModel->index(i, 0); - if (d->placesModel->isDevice(sourceIndex)) { - Solid::Device dev = d->placesModel->deviceForIndex(sourceIndex); - Solid::StorageAccess *access = dev.as(); - - if (access && !access->filePath().isEmpty()) { - usageFinder->add(i, access->filePath()); - hasDevices = true; - } - } - } - - if (hasDevices) { - usageFinder->start(); - } else { - delete usageFinder; - } -} - -void SystemModel::reloadApplications() -{ - const QStringList apps = Kickoff::systemApplicationList(); - d->appsList.clear(); - - foreach (const QString &app, apps) { - KService::Ptr service = KService::serviceByStorageId(app); - - if (service) { - d->appsList << service; - } - } -} - -void Kickoff::SystemModel::sourceDataChanged(const QModelIndex &start, const QModelIndex &end) -{ - if (start.parent().isValid()) return; - - for (int row = BOOKMARKS_ROW; row <= LAST_ROW; ++row) { - QModelIndex section = index(row, 0); - - QModelIndex new_start = index(start.row(), start.column(), section); - QModelIndex new_end = index(end.row(), end.column(), section); - emit dataChanged(new_start, new_end); - } -} - -void Kickoff::SystemModel::sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end) -{ - if (parent.isValid()) return; - - for (int row = BOOKMARKS_ROW; row <= LAST_ROW; ++row) { - QModelIndex section = index(row, 0); - beginInsertRows(section, start, end); - } -} - -void Kickoff::SystemModel::sourceRowsInserted(const QModelIndex &parent, int /*start*/, int /*end*/) -{ - if (parent.isValid()) return; - - endInsertRows(); -} - -void Kickoff::SystemModel::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) -{ - if (parent.isValid()) return; - - for (int row = BOOKMARKS_ROW; row <= LAST_ROW; ++row) { - QModelIndex section = index(row, 0); - beginRemoveRows(section, start, end); - } -} - -void Kickoff::SystemModel::sourceRowsRemoved(const QModelIndex &parent, int /*start*/, int /*end*/) -{ - if (parent.isValid()) return; - - endRemoveRows(); -} - -#include "moc_systemmodel.cpp" diff --git a/plasma/applets/kickoff/core/systemmodel.h b/plasma/applets/kickoff/core/systemmodel.h deleted file mode 100644 index cde6edf1..00000000 --- a/plasma/applets/kickoff/core/systemmodel.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SYSTEMMODEL_H -#define SYSTEMMODEL_H - -#include "kickoff_export.h" -#include "core/kickoffproxymodel.h" - -#include - -namespace Kickoff -{ - -struct UsageInfo { - UsageInfo() - : used(0), - available(0) - {} - - quint64 used; - quint64 available; -}; - -class UsageFinder : public QThread -{ - Q_OBJECT - -public: - UsageFinder(QObject *parent); - void add(int index, const QString &mountPoint); - -Q_SIGNALS: - void usageInfo(int index, const QString &mountPoint, const UsageInfo &usageInfo); - -protected: - void run(); - -private: - QList > m_toCheck; -}; - -/** - * Model which provides a tree of items for important system setup tools (eg. System Settings) , - * folders (eg. the user's home folder and the local network) and fixed and removable storage. - */ -class KICKOFF_EXPORT SystemModel : public KickoffProxyModel -{ - Q_OBJECT - -public: - /** Constructs a new SystemModel with the specified parent. */ - SystemModel(QObject *parent = 0); - virtual ~SystemModel(); - - virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &item) const; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - void refreshUsageInfo(); - void stopRefreshingUsageInfo(); - -private Q_SLOTS: - void startUsageInfoFetch(); - void reloadApplications(); - void sourceDataChanged(const QModelIndex &start, const QModelIndex &end); - void sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); - void sourceRowsInserted(const QModelIndex &parent, int start, int end); - void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - void sourceRowsRemoved(const QModelIndex &parent, int start, int end); - void setUsageInfo(int index, const QString &mountPoint, const UsageInfo &usageInfo); - void usageFinderFinished(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // SYSTEMMODEL_H - diff --git a/plasma/applets/kickoff/core/urlitemlauncher.cpp b/plasma/applets/kickoff/core/urlitemlauncher.cpp deleted file mode 100644 index 8dbf6b9c..00000000 --- a/plasma/applets/kickoff/core/urlitemlauncher.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "urlitemlauncher.h" - -// Qt -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include - -// Local -#include "core/models.h" -#include "core/urlitemlauncher.h" - -using namespace Kickoff; - -class HandlerInfo -{ -public: - HandlerInfo() : type(UrlItemLauncher::ProtocolHandler) , handler(0) {} - UrlItemLauncher::HandlerType type; - UrlItemHandler *handler; -}; - -class GenericItemHandler : public UrlItemHandler -{ -public: - virtual bool openUrl(const KUrl& url) { - new KRun(url, nullptr); - return true; - } -}; - -class UrlItemLauncher::Private -{ -public: - static QHash globalHandlers; - static GenericItemHandler genericHandler; - - static bool openUrl(const QString &urlString) { - kDebug() << "Opening item with URL" << urlString; - - KUrl url(urlString); - HandlerInfo protocolHandler = globalHandlers[url.scheme()]; - if (protocolHandler.type == ProtocolHandler && protocolHandler.handler != 0) { - return protocolHandler.handler->openUrl(url); - } - - QString extension = QFileInfo(url.path()).suffix(); - HandlerInfo extensionHandler = globalHandlers[extension]; - if (extensionHandler.type == ExtensionHandler && extensionHandler.handler != 0) { - return extensionHandler.handler->openUrl(url); - } - - return genericHandler.openUrl(url); - } -}; - -QHash UrlItemLauncher::Private::globalHandlers; -GenericItemHandler UrlItemLauncher::Private::genericHandler; - -UrlItemLauncher::UrlItemLauncher(QObject *parent) - : QObject(parent) - , d(new Private) -{ -} - -UrlItemLauncher::~UrlItemLauncher() -{ - delete d; -} - -bool UrlItemLauncher::openItem(const QModelIndex& index) -{ - QString urlString = index.data(UrlRole).value(); - if (urlString.isEmpty()) { - QString udi = index.data(DeviceUdiRole).toString(); - if (!udi.isEmpty()) { - Solid::Device device(udi); - Solid::StorageAccess *access = device.as(); - - if (access && !access->isAccessible()) { - connect(access, SIGNAL(setupDone(Solid::ErrorType,QString,QString)), - this, SLOT(onSetupDone(Solid::ErrorType,QString,QString))); - access->setup(); - return true; - } - } - - kDebug() << "Item" << index.data(Qt::DisplayRole) << "has no URL to open."; - return false; - } - - return Private::openUrl(urlString); -} - -bool UrlItemLauncher::openUrl(const QString& url) -{ - return Private::openUrl(url); -} - -void UrlItemLauncher::onSetupDone(Solid::ErrorType error, const QString &errorData, const QString &udi) -{ - Q_UNUSED(errorData); - - if (error != Solid::NoError) { - return; - } - - Solid::Device device(udi); - Solid::StorageAccess *access = device.as(); - - Q_ASSERT(access); - - QString urlString = "file://" + access->filePath(); - Private::openUrl(urlString); -} - -// FIXME: the handlers are leaked, as they are added with each new Kickoff instance, -// but never deleted. -void UrlItemLauncher::addGlobalHandler(HandlerType type, const QString& name, UrlItemHandler *handler) -{ - HandlerInfo info; - info.type = type; - info.handler = handler; - Private::globalHandlers.insert(name, info); -} - - -#include "moc_urlitemlauncher.cpp" diff --git a/plasma/applets/kickoff/core/urlitemlauncher.h b/plasma/applets/kickoff/core/urlitemlauncher.h deleted file mode 100644 index cdd23626..00000000 --- a/plasma/applets/kickoff/core/urlitemlauncher.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef URLITEMLAUNCHER_H -#define URLITEMLAUNCHER_H - -#include "kickoff_export.h" - -#include -#include -#include - - -class KUrl; - -namespace Kickoff -{ - -/** - * UrlItemHandler is an abstract base class for handlers which can open particular - * types of URL. - * - * @see UrlItemLauncher - */ -class UrlItemHandler -{ -public: - virtual ~UrlItemHandler() {} - virtual bool openUrl(const KUrl& url) = 0; -}; - -/** - * UrlItemLauncher provides facilities to open a item from a Kickoff model based on its UrlRole - * data. - * - * By default, a UrlItemLauncher opens all URLs using the KRun class. Additional handlers can be created - * to handle URLs with particular protocols or extensions differently. Handlers can be - * registered using the static addGlobalHandler() method. - */ -class KICKOFF_EXPORT UrlItemLauncher : public QObject -{ - Q_OBJECT - -public: - UrlItemLauncher(QObject *parent = 0); - virtual ~UrlItemLauncher(); - - enum HandlerType { - ProtocolHandler, - ExtensionHandler - }; - static void addGlobalHandler(HandlerType type, - const QString& name, - UrlItemHandler *handler); - -public Q_SLOTS: - /** Open the specified @p index from a Kickoff model. */ - bool openItem(const QModelIndex& index); - /** Open the specified @p url */ - bool openUrl(const QString& url); - -private Q_SLOTS: - void onSetupDone(Solid::ErrorType error, const QString &errorData, const QString &udi); - -private: - class Private; - Private * const d; -}; - -} - -#endif // URLITEMLAUNCHER_H - diff --git a/plasma/applets/kickoff/main.cpp b/plasma/applets/kickoff/main.cpp deleted file mode 100644 index 199e32c3..00000000 --- a/plasma/applets/kickoff/main.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// KDE -#include -#include -#include - -// Local -#include "ui/launcher.h" - -#define KICKOFF_VERSION "1.9.3" - -int main(int argc, char** argv) -{ - KAboutData about("kickoff", 0, ki18n("Kickoff"), KICKOFF_VERSION, - ki18n("Application Launcher"), - KAboutData::License_GPL_V2); - KCmdLineArgs::init(argc, argv, &about); - - KApplication app; - - Kickoff::Launcher *launcher = new Kickoff::Launcher((QWidget*)0); - launcher->setWindowTitle("Kickoff KDE 4 Test Application"); - // ensure launcher gets deleted when the app closes so that favorites, - // recent applications etc. are saved - launcher->setAttribute(Qt::WA_DeleteOnClose); - launcher->show(); - - return app.exec(); -} - diff --git a/plasma/applets/kickoff/simpleapplet/menuview.cpp b/plasma/applets/kickoff/simpleapplet/menuview.cpp deleted file mode 100644 index ca9a1d3e..00000000 --- a/plasma/applets/kickoff/simpleapplet/menuview.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2008-2009 Sebastian Sauer - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "menuview.h" - -// Qt -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include - -// Local -#include "core/models.h" -#include "core/itemhandlers.h" - -#define MAX_NAME_SIZE 50 - -Q_DECLARE_METATYPE(QPersistentModelIndex) -Q_DECLARE_METATYPE(QAction*) - -using namespace Kickoff; - -/// @internal d-pointer class -class MenuView::Private -{ -public: - enum { ActionRole = Qt::UserRole + 52 }; - - Private(MenuView *q) : q(q), column(0), launcher(new UrlItemLauncher(q)), formattype(MenuView::DescriptionName) {} - ~Private() - { - qDeleteAll(items); - } - - QAction *createActionForIndex(QAbstractItemModel *model, const QModelIndex& index, QMenu *parent) - { - Q_ASSERT(index.isValid()); - QAction *action = 0; - if (model->hasChildren(index)) { - KMenu *childMenu = new KMenu(parent); - childMenu->installEventFilter(q); - childMenu->setContextMenuPolicy(Qt::CustomContextMenu); - connect(childMenu, SIGNAL(customContextMenuRequested(QPoint)), - q, SLOT(contextMenuRequested(QPoint))); - action = childMenu->menuAction(); - buildBranch(childMenu, model, index); - } else { - action = q->createLeafAction(index, parent); - } - - q->updateAction(model, action, index); - return action; - } - - QString trunctuateName(QString name, int maxSize) - { - if (name.length() <= maxSize) { - return name; - } - - maxSize -= 2; // remove the 3 placeholder points - const int start = maxSize / 3; //use one third of the chars for the start of the name - const int end = maxSize - start; - return name.left(start) + ".." + name.right(end); - } - - void buildBranch(KMenu *menu, QAbstractItemModel *model, const QModelIndex& parent) - { - if (model->canFetchMore(parent)) { - model->fetchMore(parent); - } - const int rowCount = model->rowCount(parent); - for (int i = 0; i < rowCount; i++) { - QAction *action = createActionForIndex(model, model->index(i, column, parent), menu); - action->setText(trunctuateName(action->text(), MAX_NAME_SIZE)); - menu->addAction(action); - } - } - - QModelIndex findByRelPath(QAbstractItemModel * model, const QModelIndex & parent, const QString & relPath) - { - QModelIndex newRoot; - if (model->canFetchMore(parent)) { - model->fetchMore(parent); - } - const int rowCount = model->rowCount(parent); - for (int row = 0; row < rowCount; row++) { - QModelIndex index = model->index(row, 0, parent); - Q_ASSERT(index.isValid()); - if (index.data(Kickoff::RelPathRole).isValid()) { - QString indexRelPath = index.data(Kickoff::RelPathRole).toString(); - if (relPath == indexRelPath) { - newRoot = index; - break; - } - if (!indexRelPath.isEmpty() && relPath.startsWith(indexRelPath)) { - newRoot = findByRelPath(model, index, relPath); - break; - } - } - } - return newRoot; - } - - - MenuView * const q; - int column; - UrlItemLauncher *launcher; - MenuView::FormatType formattype; - QPoint mousePressPos; - QList items; - QHash modelsHeader; - QList > models; -}; - -MenuView::MenuView(QWidget *parent, const QString &title, const QIcon &icon) - : KMenu(parent) - , d(new Private(this)) -{ - if (! title.isNull()) - setTitle(title); - if (! icon.isNull()) - setIcon(icon); - - installEventFilter(this); - - connect(this, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(contextMenuRequested(QPoint))); -} - -MenuView::~MenuView() -{ - QListIterator > it(d->models); - while (it.hasNext()) { - QAbstractItemModel *model = it.next().data(); - if (model) { - model->disconnect(this); - } - } - - delete d; -} - -QAction *MenuView::createLeafAction(const QModelIndex &index, QObject *parent) -{ - Q_UNUSED(index); - return new QAction(parent); -} - -void MenuView::updateAction(QAbstractItemModel *model, QAction *action, const QModelIndex& index) -{ - bool isSeparator = index.data(Kickoff::SeparatorRole).value(); - - // if Description or DescriptionName -> displayOrder = Kickoff::NameAfterDescription - // Qt::DisplayRole returns genericName, the generic name e.g. "Advanced Text Editor" or "Spreadsheet" or just "" (right, it's a mess too) - // Kickoff::SubTitleRole returns appName, the name e.g. "Kate" or "OpenOffice.org Calc" (right, sometimes the text is also used for the generic app-name) - // - // if Name or NameDescription or NameDashDescription -> displayOrder = Kickoff::NameBeforeDescription - // Qt::DisplayRole returns appName, - // Kickoff::SubTitleRole returns genericName. - - QString mainText = index.data(Qt::DisplayRole).value().replace('&', "&&"); - QString altText = index.data(Kickoff::SubTitleRole).value().replace('&', "&&"); - if (action->menu() != 0) { // if it is an item with sub-menuitems, we probably like to thread them another way... - action->setText(mainText); - } else { - switch (d->formattype) { - case Name: - case Description: { - action->setText(mainText); - action->setToolTip(altText); - } break; - case NameDescription: // fall through - case NameDashDescription: // fall through - case DescriptionName: { - if (!mainText.isEmpty()) { // seems we have a program, but some of them don't define a name at all - if (mainText.contains(altText, Qt::CaseInsensitive)) { // sometimes the description contains also the name - action->setText(mainText); - } else if (altText.contains(mainText, Qt::CaseInsensitive)) { // and sometimes the name also contains the description - action->setText(altText); - } else { // seems we have a perfect desktop-file (likely a KDE one, heh) and name+description are clear separated - if (d->formattype == NameDashDescription) { - action->setText(QString("%1 - %2").arg(mainText).arg(altText)); - } else { - action->setText(QString("%1 (%2)").arg(mainText).arg(altText)); - } - } - } else { // if there is no name, let's just use the describing text - action->setText(altText); - } - } break; - } - } - - action->setSeparator(isSeparator); - if (!isSeparator) { - action->setIcon(index.data(Qt::DecorationRole).value()); - } - - // we map modelindex and action together - action->setData(qVariantFromValue(QPersistentModelIndex(index))); - - // don't emit the dataChanged-signal cause else we may end in a infinite loop - model->blockSignals(true); - model->setData(index, qVariantFromValue(action), Private::ActionRole); - model->blockSignals(false); -} - -bool MenuView::eventFilter(QObject *watched, QEvent *event) -{ - switch(event->type()) { - case QEvent::MouseMove: { - QMouseEvent *mouseEvent = static_cast(event); - QMenu *watchedMenu = qobject_cast(watched); - const int mousePressDistance = !d->mousePressPos.isNull() ? (mouseEvent->pos() - d->mousePressPos).manhattanLength() : 0; - - if (watchedMenu && mouseEvent->buttons() & Qt::LeftButton - && mousePressDistance >= QApplication::startDragDistance()) { - QAction *action = watchedMenu->actionAt(mouseEvent->pos()); - if (!action) { - return KMenu::eventFilter(watched, event); - } - - QPersistentModelIndex index = action->data().value(); - if (!index.isValid()) { - return KMenu::eventFilter(watched, event); - } - - QUrl url = index.data(UrlRole).toUrl(); - if (url.isEmpty()) { - return KMenu::eventFilter(watched, event); - } - - QMimeData *mimeData = new QMimeData(); - mimeData->setUrls(QList() << url); - mimeData->setText(url.toString()); - QDrag *drag = new QDrag(this); - drag->setMimeData(mimeData); - - QIcon icon = action->icon(); - drag->setPixmap(icon.pixmap(IconSize(KIconLoader::Desktop))); - - d->mousePressPos = QPoint(); - - Qt::DropAction dropAction = drag->exec(); - Q_UNUSED(dropAction); - - return true; - } - - break; - } - - case QEvent::MouseButtonPress: { - QMouseEvent *mouseEvent = static_cast(event); - QMenu *watchedMenu = qobject_cast(watched); - if (watchedMenu) { - d->mousePressPos = mouseEvent->pos(); - } - - break; - } - - case QEvent::MouseButtonRelease: { - QMenu *watchedMenu = qobject_cast(watched); - if (watchedMenu) { - d->mousePressPos = QPoint(); - } - - break; - } - - case QEvent::Hide: { - emit afterBeingHidden(); - break; - } - - case QEvent::ToolTip: { - bool hide = true; - - if ((d->formattype == Name) || (d->formattype == Description)) { - QHelpEvent *helpEvent = static_cast(event); - QMenu *watchedMenu = qobject_cast(watched); - - if (watchedMenu && watchedMenu->activeAction()) { - QString toolTip = watchedMenu->activeAction()->toolTip(); - - if ((toolTip != watchedMenu->activeAction()->text()) && (watchedMenu->activeAction()->menu() == 0)) { - QToolTip::showText(helpEvent->globalPos(), toolTip); - hide = false ; - } - } - } - - if (hide) { - QToolTip::hideText(); - event->ignore(); - } - - break; - } - - default: - break; - } - - return KMenu::eventFilter(watched, event); -} - -void MenuView::addModel(QAbstractItemModel *model, MenuView::ModelOptions options, const QString & relativePath) -{ - QString title = model->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(); - - QAction *header = addTitle(title); - header->setVisible(false); - - d->modelsHeader.insert(model, header); - d->models.append(model); - - if (options & MergeFirstLevel) { - const int count = model->rowCount(); - for (int row = 0; row < count; ++row) { - QModelIndex index = model->index(row, 0, QModelIndex()); - Q_ASSERT(index.isValid()); - - const QString title = index.data(Qt::DisplayRole).value(); - if (count > 1 && ! title.isEmpty() && model->rowCount(index) > 0) { - addTitle(title); - } - - model->blockSignals(true); - model->setData(index, qVariantFromValue(this->menuAction()), Private::ActionRole); - model->blockSignals(false); - - d->buildBranch(this, model, index); - } - } else { - QModelIndex root; - if (!relativePath.isEmpty()) { - root = d->findByRelPath(model, root, relativePath); - } - d->buildBranch(this, model, root); - } - - connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int))); - connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); - connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(dataChanged(QModelIndex,QModelIndex))); - connect(model, SIGNAL(modelReset()), this, SLOT(modelReset())); -} - -void MenuView::addItem(QStandardItem *item) -{ - QAction *action = new QAction(item->icon(), item->text(), this); - KUrl url(item->data(Kickoff::UrlRole).toString()); - Q_ASSERT(url.isValid()); - action->setData(url); - addAction(action); - d->items << item; -} - -UrlItemLauncher *MenuView::launcher() const -{ - return d->launcher; -} - -QModelIndex MenuView::indexForAction(QAction *action) const -{ - Q_ASSERT(action != 0); - QPersistentModelIndex index = action->data().value(); - return index; -} - -QAction *MenuView::actionForIndex(const QModelIndex& index) const -{ - if (!index.isValid()) { - return this->menuAction(); - } - - const QAbstractItemModel *model = index.model(); - Q_ASSERT(model); - QVariant v = model->data(index, Private::ActionRole); - Q_ASSERT(v.isValid()); - QAction* a = v.value(); - Q_ASSERT(a); - return a; -} - -bool MenuView::isValidIndex(const QModelIndex& index) const -{ - QVariant v = (index.isValid() && index.model()) ? index.model()->data(index, Private::ActionRole) : QVariant(); - return v.isValid() && v.value(); -} - -void MenuView::rowsInserted(const QModelIndex& parent, int start, int end) -{ - kDebug() << start << end; - - Q_ASSERT(parent.isValid()); - Q_ASSERT(parent.model()); - - //Q_ASSERT( ! isValidIndex(parent) ); - QMenu *menu = isValidIndex(parent) ? actionForIndex(parent)->menu() : this; - - QAbstractItemModel *model = const_cast(parent.model()); - if (!model) { - return; - } - - QList newActions; - for (int row = start; row <= end; row++) { - QModelIndex index = model->index(row, d->column, parent); - QAction *newAction = d->createActionForIndex(model, index, menu); - kDebug()<<"new action="<text(); - newActions << newAction; - } - - int lastidx = -1, offset = -1; - for (int i = 0; i < menu->actions().count(); ++i) { - QAction *action = menu->actions()[i]; - Q_ASSERT(action); - QModelIndex index = indexForAction(action); - if (index.isValid() && index.model() == model) { - lastidx = i; - if(++offset == start) - break; - } - } - - if (lastidx < 0 && d->modelsHeader.contains(model)) { - QAction *header = d->modelsHeader[model]; - lastidx = menu->actions().indexOf(header); - } - - if (lastidx >= 0) { - if (offset < start) { - lastidx++; // insert action the item right after the last valid index - } - - if (lastidx < menu->actions().count()) { - menu->insertActions(menu->actions()[lastidx], newActions); - } else { - lastidx = -1; - } - } - - if (lastidx < 0) { - // just append the action - menu->addActions(newActions); - } -} - -void MenuView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) -{ - kDebug() << start << end; - Q_UNUSED(parent); - Q_UNUSED(start); - Q_UNUSED(end); - modelReset(); -} - -void MenuView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) -{ - QAbstractItemModel *model = const_cast(topLeft.model()); - Q_ASSERT(model); - - //Q_ASSERT( ! isValidIndex(topLeft) ); - QMenu *menu = isValidIndex(topLeft) ? actionForIndex(topLeft)->menu() : this; - - QList actions = menu->actions(); - Q_ASSERT(bottomRight.row() < actions.count()); - - for (int row = topLeft.row(); row <= bottomRight.row() && row < actions.count(); ++row) { - QModelIndex index = model->index(row, d->column, topLeft.parent()); - kDebug()<(); - updateAction(model, actions[row], index); - } -} - -void MenuView::modelReset() -{ - kDebug(); - deleteLater(); // we need to force clearance of the menu and rebuild from scratch -} - -void MenuView::setColumn(int column) -{ - d->column = column; - modelReset(); -} - -int MenuView::column() const -{ - return d->column; -} - -MenuView::FormatType MenuView::formatType() const -{ - return d->formattype; -} - -void MenuView::setFormatType(MenuView::FormatType formattype) -{ - d->formattype = formattype; -} - -void MenuView::setModelTitleVisible(QAbstractItemModel *model, bool visible) -{ - if (d->modelsHeader.contains(model)) { - QAction *header = d->modelsHeader[model]; - header->setVisible(visible); - } -} - -void MenuView::actionTriggered(QAction *action) -{ - KUrl url = action->data().value(); - if (url.isValid()) { - d->launcher->openUrl(url.url()); - } else { - QModelIndex index = indexForAction(action); - if (index.isValid()) { - d->launcher->openItem(index); - } else { - kWarning()<<"Invalid action objectName="<objectName()<<"text="<text()<<"parent="<<(action->parent()?action->parent()->metaObject()->className():"NULL"); - } - } -} - -void MenuView::contextMenuRequested(const QPoint &pos) -{ - KMenu *menu = qobject_cast(sender()); - emit customContextMenuRequested(menu, pos); -} - -#include "moc_menuview.cpp" diff --git a/plasma/applets/kickoff/simpleapplet/menuview.h b/plasma/applets/kickoff/simpleapplet/menuview.h deleted file mode 100644 index 39a78776..00000000 --- a/plasma/applets/kickoff/simpleapplet/menuview.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2008-2009 Sebastian Sauer - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef MENUVIEW_H -#define MENUVIEW_H - -// Qt -#include - -// KDE -#include - -#include -#include - -namespace Kickoff -{ - -class UrlItemLauncher; - -/** - * A view for a QAbstractItemModel which displays the model (set with setModel()) - * as a hierarchical menu. - * - * When the menu is executed and an item is triggered, the model index associated with the - * chosen item can be found by calling indexForAction() with the triggered action. The action - * associated with a particular model index can be found using actionForIndex(). - * - * MenuView creates actions for parts of the model on demand as the user explores the menu. - * The type of action created for leaf items in the tree can be changed by re-implementing - * createLeafAction(). When a new action is created or if the corresponding model - * index's data changes, updateAction() is called to set the action's properties. This - * can be reimplemented in sub-classes to change the appearance of the actions. - */ -class MenuView : public KMenu -{ - Q_OBJECT -public: - - /** Constructs a new menu with the specified @p parent */ - MenuView(QWidget *parent = 0, const QString &title = QString(), const QIcon &icon = QIcon()); - /** Destructor */ - virtual ~MenuView(); - - /// Options for a model. - enum ModelOptions { - None, ///< no options. - MergeFirstLevel ///< merge the first both levels of items within the model into one hirachy in the menuview. - }; - - /** Adds a model to display within this menu. */ - void addModel(QAbstractItemModel *model, ModelOptions options = None, const QString & relativePath = QString()); - - /** Adds a QStandardItem to display within this menu. This menu will take over the ownership of the item. */ - void addItem(QStandardItem *item); - - /** Returns the UrlItemLauncher used to handle launching of urls. */ - UrlItemLauncher *launcher() const; - - /** Maps an action in the menu to its corresponding index in model() */ - QModelIndex indexForAction(QAction *action) const; - - /** - * Maps an index in the model to its corresponding action in the menu. - * If @p index is invalid then menuAction() will be returned. If @p index - * is in a part of the tree which the user has not yet explored then 0 will - * be returned because the menu hierarchy is constructed on-demand as the user - * explores the menu. - */ - QAction *actionForIndex(const QModelIndex& index) const; - - /** - * Returns true if the passed \p index is a valid QModelIndex and does - * represent a QAction. This method is equal to the actionForIndex() method - * above except allowing to explicit ask if the QModelIndex is valid and - * to indicate that way, that it may the case that the QModelIndex went - * out of scope already. - */ - bool isValidIndex(const QModelIndex& index) const; - - /** Sets the column from the model which is used to construct the actions in the menu. */ - void setColumn(int column); - /** Returns the column from the model which is used to construct the actions in the menu. */ - int column() const; - - /** The format type enumeration. */ - enum FormatType { - Name = 0, ///< Name only - Description, ///< Description only - NameDescription, ///< Name (Description) - DescriptionName, ///< Description (Name) - NameDashDescription ///< Name - Description - }; - /** \return the format type. */ - FormatType formatType() const; - /** Set the format type. */ - void setFormatType(FormatType formattype); - /** Set visibility of model title on menu. */ - void setModelTitleVisible(QAbstractItemModel *model, bool visible); - -protected: - - /** - * Creates a new action to represent a leaf index in the tree. A leaf index - * is one which does not have children. The default implementation creates a new - * QAction with no properties set. updateAction() is immediately called on the - * return action to set its text and icon. - * - * @param index The index in the model for which an action should be created - * @param parent The object which should be set as the parent of the new action - */ - virtual QAction *createLeafAction(const QModelIndex& index, QObject *parent); - - /** - * Sets the text, icon and other properties of @p action using the data - * associated with @p index in the model(). This is called whenever the data for - * a range of indexes in the tree is altered. - * - * The default implementation sets the action's text to the index's Qt::DisplayRole data - * and the action's icon to the index's Qt::DecorationRole data. - */ - virtual void updateAction(QAbstractItemModel *model, QAction *action, const QModelIndex& index); - - // reimplemented - virtual bool eventFilter(QObject *watched, QEvent *event); - -public Q_SLOTS: - /** - * An item in the menu got triggered. - */ - void actionTriggered(QAction* action); - - void contextMenuRequested(const QPoint& pos); - -Q_SIGNALS: - /** - * Compared to the aboutToShow() this signal will be emitted after the menu - * got hidden. - */ - void afterBeingHidden(); - - void customContextMenuRequested(QMenu* menu, const QPoint& pos); - -private Q_SLOTS: - /// new items have been inserted into the model - void rowsInserted(const QModelIndex& parent, int start, int end); - /// existing items are about to be removed from the model - void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - /// data within an item of the model change - void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - /// the model did reset itself and all items are invalid - void modelReset(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // MENUVIEW_H - diff --git a/plasma/applets/kickoff/simpleapplet/plasma-applet-simplelauncher.desktop b/plasma/applets/kickoff/simpleapplet/plasma-applet-simplelauncher.desktop deleted file mode 100644 index d711bc3b..00000000 --- a/plasma/applets/kickoff/simpleapplet/plasma-applet-simplelauncher.desktop +++ /dev/null @@ -1,164 +0,0 @@ -[Desktop Entry] -Name=Application Launcher Menu -Name[af]=Programlanseerder-kieslys -Name[ar]=قائمة مطلق التطبيقات -Name[ast]=Menú del llanzador d'aplicaciones -Name[be@latin]=Menu dla ŭklučeńnia aplikacyjaŭ -Name[bg]=Стартиране на програми с меню -Name[bn]=অ্যাপলিকেশন লঞ্চার মেনু -Name[bs]=meni za pokretanje programa -Name[ca]=Menú del llançador d'aplicacions -Name[ca@valencia]=Menú del llançador d'aplicacions -Name[cs]=Nabídka spouštěče aplikací -Name[csb]=Menu zrëszôcza programów -Name[da]=Startmenu -Name[de]=K-Menü (traditionell) -Name[el]=Μενού εκτέλεσης εφαρμογών -Name[en_GB]=Application Launcher Menu -Name[eo]=Aplikaĵolanĉila menuo -Name[es]=Menú del lanzador de aplicaciones -Name[et]=Rakenduste käivitaja menüü -Name[eu]=Aplikazio-abiarazlearen menua -Name[fi]=Sovellusten käynnistysvalikko -Name[fr]=Menu de lancement des applications -Name[fy]=Applikaasje úteinsetter menu -Name[ga]=Roghchlár Tosaitheora Feidhmchlár -Name[gl]=Menú iniciador de programas -Name[gu]=કાર્યક્રમ ચલાવનાર મેનુ -Name[he]=תפריט משגר יישומים -Name[hi]=अनुप्रयोग चलाने वाला मेन्यू -Name[hne]=अनुपरयोग चालू करइया मेनु -Name[hr]=Izbornik pokretača aplikacija -Name[hsb]=Meni startowarja aplikacijow -Name[hu]=Programindító menü -Name[ia]=Menu de Lanceator de application -Name[id]=Menu Peluncur Aplikasi -Name[is]=Valmynd forritaræsingar -Name[ja]=アプリケーション起動メニュー -Name[kk]=Қолданбаны жегу мәзірі -Name[km]=ម៉ឺនុយ​កម្មវិធី​ចាប់ផ្ដើម​កម្មវិធី -Name[kn]=ಅನ್ವಯ ಪ್ರಕ್ಷೇಪಕ (ಲಾಚರ್) ಪರಿವಿಡಿ -Name[ko]=프로그램 실행기 메뉴 -Name[lt]=Programų paleidiklio meniu -Name[lv]=Programmu palaidēja izvēlne -Name[ml]=പ്രയോഗവിക്ഷേപിണി മെനു -Name[mr]=अनुप्रयोग प्रक्षेपक मेन्यू -Name[nb]=Meny for programstarter -Name[nds]=Programmoproopmenü -Name[nl]=Programmastartermenu -Name[nn]=Programstartmeny -Name[or]=ପ୍ରୟୋଗ ଆରମ୍ଭକର୍ତ୍ତା ତାଲିକା -Name[pa]=ਐਪਲੀਕੇਸ਼ਨ ਲਾਂਚਰ ਮੇਨੂ -Name[pl]=Menu aktywatora programów -Name[pt]=Menu do Lançador de Aplicações -Name[pt_BR]=Menu do lançador de aplicativos -Name[ro]=Meniu pentru lansatorul de aplicații -Name[ru]=Классическое меню запуска приложений -Name[se]=Prográmmaálggahanfállu -Name[si]=යෙදුම් ඇරඹුම් මෙනුව -Name[sk]=Spúšťač aplikácií (menu) -Name[sl]=Meni zaganjalnika programov -Name[sr]=мени за покретање програма -Name[sr@ijekavian]=мени за покретање програма -Name[sr@ijekavianlatin]=meni za pokretanje programa -Name[sr@latin]=meni za pokretanje programa -Name[sv]=Programstartmeny -Name[ta]=பயன்பாடு ஏவல் தளம் -Name[te]=అనువర్తనముల లాంచర్ మెనూ -Name[tg]=Менюи оғози барномаҳо -Name[th]=เมนูเรียกใช้งานโปรแกรม -Name[tr]=Uygulama Başlatma Menüsü -Name[ug]=پروگرامما ئىجرا قىلغۇچ تىزىملىكى -Name[uk]=Інструмент запуску програм з меню -Name[vi]=Trình đơn chạy ứng dụng -Name[wa]=Dressêye d' enondeu di programe -Name[x-test]=xxApplication Launcher Menuxx -Name[zh_CN]=应用程序启动菜单 -Name[zh_TW]=應用程式啟動器選單 -Comment=Traditional menu based application launcher -Comment[af]=Tradisionele kieslys as programlanseerder -Comment[ar]=مطلق تطبيقات تقليدي على شكل قائمة -Comment[ast]=Llanzador d'aplicaciones tradicional basáu en menú -Comment[be@latin]=Tradycyjnaje menu dla ŭklučeńnia aplikacyjaŭ -Comment[bg]=Традиционно стартиране на програми с меню -Comment[bs]=Tradicionalno pokretanje programa pomoću menija -Comment[ca]=Llançador d'aplicacions basat en el menú tradicional -Comment[ca@valencia]=Llançador d'aplicacions basat en el menú tradicional -Comment[cs]=Tradiční spouštěč aplikací založený na nabídce -Comment[da]=Traditionel menubaseret startmenu -Comment[de]=Programmstarter mit traditionellen Menüs -Comment[el]=Παραδοσιακό μενού εκτέλεσης εφαρμογών -Comment[en_GB]=Traditional menu based application launcher -Comment[eo]=La kutima menua bazita aplikaĵolanĉilo -Comment[es]=Lanzador de aplicaciones tradicional basado en menú -Comment[et]=Rakenduste käivitajale tuginev traditsiooniline menüü -Comment[eu]=Menuetan oinarritutako aplikazio-abiarazle tradizionala -Comment[fi]=Perinteinen valikkopohjainen sovellusten käynnistin -Comment[fr]=Lanceur d'applications utilisant un menu traditionnel -Comment[fy]=Tradisjoneel menu bassearre applikaasje úteinsetter -Comment[ga]=Tosaitheoir traidisiúnta feidhmchlár bunaithe ar roghchlár -Comment[gl]=Un iniciador de programas baseado no menú tradicional -Comment[gu]=પરંપરાગત મેનુ આધારિત કાર્યક્રમમ ચલાવનાર -Comment[he]=משגר יישומים מסורתי מבוסס תפריטים -Comment[hi]=पारंपरिक मेन्यू आधारित अनुप्रयोग चलाने वाला -Comment[hne]=परंपरा वाले मेनु आधारित अनुपरयोग चालू करइया -Comment[hr]=Tradicionalni pokretač baziran na izbornicima -Comment[hsb]=Tradicionalny, na meniju bazowacy startowar aplikacijow -Comment[hu]=Hagyományos programindító menü -Comment[ia]=Lanceator de application basate sur menu traditional -Comment[id]=Menu tradisional berbasis peluncur aplikasi -Comment[is]=Venjuleg valmyndabyggð forritaræsing -Comment[ja]=Kickoff ランチャーに基づく従来のアプリケーション起動メニュー -Comment[kk]=Қолданба жеккішті негіздейтін дәстүрлі мәзір -Comment[km]=ម៉ឺនុយ​បន្ថែម​មាន​មូលដ្ឋាន​លើ​កម្មវិធី​ចាប់ផ្ដើម​កម្មវិធី -Comment[kn]=ಸಾಂಪ್ರದಾಯಿಕ ಪರಿವಿಡಿ ಆಧಾರಿತ ಅನ್ವಯ ಪ್ರಕ್ಷೇಪಕ (ಲಾಂಚರ್) -Comment[ko]=전통적인 메뉴 기반 프로그램 실행기 -Comment[lt]=Tradicinio meniu programų paleidiklis -Comment[lv]=Tradicionālais uz izvēlnēm bāzētais programmu palaidējs -Comment[mk]=Традиционален стартувач на апликации базиран на мени -Comment[ml]=പരമ്പരാഗതമായ മെനുഅടിസ്ഥാനമാക്കിയുള്ള പ്രയോഗവിക്ഷേപിണി -Comment[mr]=पारंपारिक मेन्यू आधारित अनुप्रयोग प्रक्षेपक -Comment[nb]=Tradisjonell menybasert programstarter -Comment[nds]=Begäng Programmoproper mit Menüs -Comment[nl]=Traditioneel menu voor het starten van programma's -Comment[nn]=Tradisjonell menybasert programstartar -Comment[or]=ପ୍ରଥାଗତ ତାଲିକା ଆଧାରିତ ପ୍ରୟୋଗ ଆରମ୍ଭକର୍ତ୍ତା -Comment[pa]=ਆਮ ਮੇਨੂ ਅਧਾਰਿਤ ਐਪਲੀਕੇਸ਼ਨ ਲਾਂਚਰ -Comment[pl]=Tradycyjny, oparty o menu, aktywator programów -Comment[pt]=Lançador de aplicações baseado num menu tradicional -Comment[pt_BR]=Lançador de aplicativos baseado no menu tradicional -Comment[ro]=Lansator de aplicații bazat pe meniu tradițional -Comment[ru]=Традиционное меню запуска приложений -Comment[se]=Árbevirolaš fállovuođđoduvvun prográmmaálggaheaddji -Comment[si]=සාම්ප්‍රදායික මෙනු පාදක කරගන් යෙදුම් අරඹනය -Comment[sk]=Tradičný spúšťač aplikácií založený na menu -Comment[sl]=Zaganjalnik programov, ki temelji na tradicionalnem meniju -Comment[sr]=Традиционално покретање програма помоћу менија -Comment[sr@ijekavian]=Традиционално покретање програма помоћу менија -Comment[sr@ijekavianlatin]=Tradicionalno pokretanje programa pomoću menija -Comment[sr@latin]=Tradicionalno pokretanje programa pomoću menija -Comment[sv]=Traditionell menybaserad programstart -Comment[ta]=Traditional menu based application launcher -Comment[te]=సాంప్రదాయ మెనూ ఆధారిత అనువర్తనం లాంచర్ -Comment[tg]=Традиционное средство запуска приложений на основе меню -Comment[th]=เมนูแบบดั้งเดิมสำหรับเรียกใช้งานโปรแกรม -Comment[tr]=Geleneksel menü temelli uygulama başlatıcı -Comment[ug]=تىزىملىك ئاساسىدىكى ئەنئەنىۋى پروگرامما ئىجرا قىلغۇچ -Comment[uk]=Інструмент запуску програм з традиційним меню -Comment[wa]=Enondeu d' programe båzé sol tradicionele dressêye -Comment[x-test]=xxTraditional menu based application launcherxx -Comment[zh_CN]=基于菜单的传统程序启动器 -Comment[zh_TW]=傳統選單式的應用程式啟動器 -Icon=start-here-kde -Type=Service -X-KDE-ServiceTypes=Plasma/Applet -X-KDE-Library=plasma_applet_simplelauncher -X-KDE-PluginInfo-Author=Robert Knight -X-KDE-PluginInfo-Email=robertknight@gmail.com -X-KDE-PluginInfo-Name=simplelauncher -X-KDE-PluginInfo-Version=1.0 -X-KDE-PluginInfo-Website= -X-KDE-PluginInfo-Category=Application Launchers -X-KDE-PluginInfo-Depends= -X-KDE-PluginInfo-License=GPL -X-KDE-PluginInfo-EnabledByDefault=false diff --git a/plasma/applets/kickoff/simpleapplet/simpleapplet.cpp b/plasma/applets/kickoff/simpleapplet/simpleapplet.cpp deleted file mode 100644 index 70ee1323..00000000 --- a/plasma/applets/kickoff/simpleapplet/simpleapplet.cpp +++ /dev/null @@ -1,892 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2008-2009 Sebastian Sauer - Copyright 2009 Christian Loose - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "simpleapplet/simpleapplet.h" -#include "simpleapplet/menuview.h" - -// Katie -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// KDE Libs -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// KDE Base -#include - -// Plasma -#include -#include -#include - -// Local -#include "core/itemhandlers.h" -#include "core/models.h" -#include "core/applicationmodel.h" -#include "core/favoritesmodel.h" -#include "core/systemmodel.h" -#include "core/recentlyusedmodel.h" -#include "core/recentapplications.h" -#include "core/leavemodel.h" -#include "core/urlitemlauncher.h" -#include "ui/contextmenufactory.h" - -Q_DECLARE_METATYPE(QPersistentModelIndex) - -/// @internal KBookmarkOwner specialization -class BookmarkOwner : public KBookmarkOwner -{ -public: - BookmarkOwner() : KBookmarkOwner() {} - virtual bool enableOption(BookmarkOption) const { - return false; - } - virtual bool supportsTabs() const { - return false; - } - virtual void openBookmark(const KBookmark& b, Qt::MouseButtons, Qt::KeyboardModifiers) { - new KRun(b.url(), (QWidget*)0); - } -}; - -/// @internal d-pointer class -class MenuLauncherApplet::Private -{ -public: - MenuLauncherApplet *q; - - QWeakPointer menuview; - Plasma::IconWidget *icon; - QString iconname; - QWeakPointer launcher; - - KActionCollection* bookmarkcollection; - BookmarkOwner* bookmarkowner; - KBookmarkMenu* bookmarkmenu; - - QStringList viewtypes;//QList - QString relativePath; - MenuLauncherApplet::FormatType formattype; - int maxRecentApps; - bool showMenuTitles; - bool showRecentlyInstalled; - - QListWidget *view; - KIconButton *iconButton; - KComboBox *formatComboBox; - QSpinBox *recentApplicationsSpinBox; - QCheckBox *showMenuTitlesCheckBox; - QCheckBox *showRecentlyInstalledCheckBox; - - QList actions; - QAction* switcher; - Kickoff::ContextMenuFactory *contextMenuFactory; - - bool delayedConfigLoad; - - explicit Private(MenuLauncherApplet *q) - : q(q), - icon(0), - bookmarkcollection(0), - bookmarkowner(0), - bookmarkmenu(0), - view(0), - iconButton(0), - formatComboBox(0), - showMenuTitlesCheckBox(0), - showRecentlyInstalledCheckBox(0), - switcher(0), - contextMenuFactory(0) - {} - - ~Private() - { - delete bookmarkmenu; - delete bookmarkowner; - delete menuview.data(); - } - - void setMaxRecentApps(int num) { - maxRecentApps = qMax(0, num); - if (maxRecentApps > Kickoff::RecentApplications::self()->maximum()) { - Kickoff::RecentApplications::self()->setMaximum(maxRecentApps); - } - } - - void addItem(KComboBox* combo, const QString& caption, int index, const QString& icon = QString()) - { - if (icon.isEmpty()) { - combo->addItem(caption, index); - } else { - combo->addItem(KIcon(icon), caption, index); - } - } - - void setCurrentItem(KComboBox* combo, int currentIndex) - { - for (int i = combo->count() - 1; i >= 0; --i) { - if (combo->itemData(i).toInt() == currentIndex) { - combo->setCurrentIndex(i); - return; - } - } - if (combo->count() > 0) - combo->setCurrentIndex(0); - } - - void addModel(QAbstractItemModel *model, ViewType viewtype, Kickoff::MenuView::ModelOptions options = Kickoff::MenuView::MergeFirstLevel, int formattype = -1) - { - Kickoff::MenuView* mainView = menuview.data(); - Kickoff::MenuView* m = mainView; - if (viewtypes.count() > 1 || !m) { - m = new Kickoff::MenuView(mainView, viewText(viewtype), KIcon(viewIcon(viewtype))); - m->setFormatType((formattype >= 0 || !mainView) ? (Kickoff::MenuView::FormatType)formattype : mainView->formatType()); - mainView->addMenu(m); - } - m->addModel(model, options); - } - - QString viewText(MenuLauncherApplet::ViewType vt) const { - switch (vt) { - case Favorites: return i18n("Favorites"); - case Bookmarks: return i18n("Bookmarks"); - case Applications: return i18n("Applications"); - case Computer: return i18n("Computer"); - case RecentlyUsed: return i18n("Recently Used"); - case RecentlyUsedApplications: return i18n("Recently Used Applications"); - case RecentlyUsedDocuments: return i18n("Recently Used Documents"); - case Settings: return i18n("System Settings"); - case SwitchUser: return i18n("Switch User"); - case SaveSession: return i18n("Save Session"); - case LockScreen: return i18n("Lock Screen"); - case SuspendDisk: return i18n("Hibernate"); - case SuspendRAM: return i18n("Sleep"); - case HybridSuspend: return i18n("Hybrid Suspend"); - case Restart: return i18nc("Restart Computer", "Restart"); - case Shutdown: return i18n("Shut down"); - case Logout: return i18n("Log out"); - case Leave: return i18n("Leave"); - } - return QString(); - } - - QString viewIcon(MenuLauncherApplet::ViewType vt) const { - switch (vt) { - case Favorites: return "bookmarks"; - case Bookmarks: return "folder-bookmarks"; - case Applications: return "applications-other"; - case Computer: return "computer"; - case RecentlyUsed: return "document-open-recent"; - case RecentlyUsedApplications: return "document-open-recent"; - case RecentlyUsedDocuments: return "document-open-recent"; - case Settings: return "preferences-system"; - case SwitchUser: return "system-switch-user"; - case SaveSession: return "document-save"; - case LockScreen: return "system-lock-screen"; - case SuspendDisk: return "system-suspend-hibernate"; - case SuspendRAM: return "system-suspend-hibernate"; - case HybridSuspend: return "system-suspend"; - case Restart: return "system-reboot"; - case Shutdown: return "system-shutdown"; - case Logout: return "system-log-out"; - case Leave: return "system-shutdown"; - } - return QString(); - } - - MenuLauncherApplet::ViewType viewType(const QByteArray& type) const { - QMetaEnum e = q->metaObject()->enumerator(q->metaObject()->indexOfEnumerator("ViewType")); - return (MenuLauncherApplet::ViewType) e.keyToValue(type); - } - - /* - QByteArray viewType(MenuLauncherApplet::ViewType type) const { - QMetaEnum e = q->metaObject()->enumerator(q->metaObject()->indexOfEnumerator("ViewType")); - return e.valueToKey(types); - } - QList viewTypes(const QStringList &types) const { - QList l; - foreach(QString t, types) l << viewType(t.toUtf()); - return l; - } - QStringList viewTypes(const QList &types) const { - QStringList l; - foreach(MenuLauncherApplet::ViewType t, types) l << viewType(t); - return l; - } - */ - - void updateTooltip() { - QStringList names; - foreach(const QString &vtname, viewtypes) - names << viewText(viewType(vtname.toUtf8())); - Plasma::ToolTipContent data(i18n("Application Launcher Menu"), names.join(", "), icon->icon()); - Plasma::ToolTipManager::self()->setContent(q, data); - } -}; - -MenuLauncherApplet::MenuLauncherApplet(QObject *parent, const QVariantList &args) - : Plasma::Applet(parent, args), - d(new Private(this)) -{ - KGlobal::locale()->insertCatalog("plasma_applet_launcher"); - - setAspectRatioMode(Plasma::ConstrainedSquare); - setHasConfigurationInterface(true); - setBackgroundHints(NoBackground); - - resize(IconSize(KIconLoader::Desktop) * 2, IconSize(KIconLoader::Desktop) * 2); - - d->icon = new Plasma::IconWidget(QString(), this); - d->icon->setFlag(ItemIsMovable, false); - connect(d->icon, SIGNAL(pressed(bool)), this, SLOT(showMenu(bool))); - connect(this, SIGNAL(activate()), this, SLOT(toggleMenu())); - - d->delayedConfigLoad = false; - switch(args.count()) { - case 2: { //Use submenu paths - d->viewtypes << "Applications"; - d->relativePath = args.value(0).toString(); - d->iconname = args.value(1).toString(); - break; - } - case 1: { //Check for delayed config (switch from Kickoff) - d->delayedConfigLoad = true; - //Do not "break;", as we may need the default views configuration - //(if SimpleLauncher was never used before) - } - default: { //Default configuration - d->viewtypes << "RecentlyUsedApplications" << "Applications" << "Favorites"; - d->viewtypes << "Leave"; - d->iconname = "start-here-kde"; - } - } - d->formattype = NameDescription; - - QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - layout->addItem(d->icon); - - d->contextMenuFactory = new Kickoff::ContextMenuFactory(this); - d->contextMenuFactory->setApplet(this); -} - -MenuLauncherApplet::~MenuLauncherApplet() -{ - delete d; -} - -void MenuLauncherApplet::init() -{ - bool receivedArgs = false; - if (!d->relativePath.isEmpty()) { - receivedArgs = true; - } - - configChanged(); - - Kickoff::UrlItemLauncher::addGlobalHandler(Kickoff::UrlItemLauncher::ExtensionHandler, "desktop", new Kickoff::ServiceItemHandler); - Kickoff::UrlItemLauncher::addGlobalHandler(Kickoff::UrlItemLauncher::ProtocolHandler, "leave", new Kickoff::LeaveItemHandler); - - if (KService::serviceByStorageId("kmenuedit.desktop")) { - QAction* menueditor = new QAction(i18n("Edit Applications..."), this); - d->actions.append(menueditor); - connect(menueditor, SIGNAL(triggered(bool)), this, SLOT(startMenuEditor())); - } - - Q_ASSERT(! d->switcher); - d->switcher = new QAction(i18n("Switch to Application Launcher Style"), this); - d->actions.append(d->switcher); - connect(d->switcher, SIGNAL(triggered(bool)), this, SLOT(switchMenuStyle())); - - if (receivedArgs) { - KConfigGroup cg = config(); - cg.writeEntry("relativePath", d->relativePath); - cg.writeEntry("icon", d->iconname); - emit configNeedsSaving(); - } - - connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)), - this, SLOT(iconSizeChanged(int))); -} - -void MenuLauncherApplet::constraintsEvent(Plasma::Constraints constraints) -{ - setBackgroundHints(NoBackground); - if (constraints & Plasma::FormFactorConstraint) { - if (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter) { - //FIXME set correct minimum size - //setMinimumContentSize(d->icon->sizeFromIconSize(IconSize(KIconLoader::Desktop))); - } else { - //setMinimumContentSize(d->icon->sizeFromIconSize(IconSize(KIconLoader::Small))); - } - } - - if ((constraints & Plasma::ImmutableConstraint) && d->switcher) { - d->switcher->setVisible(immutability() == Plasma::Mutable); - } -} - -void MenuLauncherApplet::switchMenuStyle() -{ - if (containment()) { - Plasma::Applet *launcher = containment()->addApplet("launcher", QVariantList(), geometry()); - //Copy all the config items to the simple launcher - QMetaObject::invokeMethod(launcher, "saveConfigurationFromSimpleLauncher", - Qt::DirectConnection, Q_ARG(KConfigGroup, config()), - Q_ARG(KConfigGroup, globalConfig())); - - //Switch shortcuts with the new launcher to avoid losing it - KShortcut currentShortcut = globalShortcut(); - setGlobalShortcut(KShortcut()); - launcher->setGlobalShortcut(currentShortcut); - destroy(); - } -} - -void MenuLauncherApplet::startMenuEditor() -{ - KToolInvocation::kdeinitExec("kmenuedit"); -} - -void MenuLauncherApplet::customContextMenuRequested(QMenu* menu, const QPoint& pos) -{ - if (!menu) { - return; - } - - // there are 2 possible cases - // 1) An an actual action is active - menu is the menu containing the action wanted - // 2) either a submenu is active, but none of its actions are active. menu is the submenu, - // not the menu containing the submenu - QAction* menuAction = menu->activeAction(); - if (menuAction) { // case 1) - const QPersistentModelIndex index = menuAction->data().value(); - d->contextMenuFactory->showContextMenu(0, index, pos); - } else { // case 2) - menuAction = menu->menuAction(); - if (menuAction) { - const QPersistentModelIndex index = menuAction->data().value(); - d->contextMenuFactory->showContextMenu(0, index, pos); - } - } -} - -void MenuLauncherApplet::createConfigurationInterface(KConfigDialog *parent) -{ - d->view = 0; - d->recentApplicationsSpinBox = 0; - if (d->relativePath.isEmpty()) { - QWidget *viewpage = new QWidget(parent); - QVBoxLayout *l = new QVBoxLayout(viewpage); - l->setMargin(0); - viewpage->setLayout(l); - d->view = new QListWidget(viewpage); - d->view->resize(300,500); - l->addWidget(d->view); - - QMetaEnum vte = metaObject()->enumerator(metaObject()->indexOfEnumerator("ViewType")); - for(int i = 0; i < vte.keyCount(); ++i) { - ViewType vt = (ViewType) vte.value(i); - const QByteArray vtname = vte.key(i); - QListWidgetItem *item = new QListWidgetItem(KIcon(d->viewIcon(vt)), d->viewText(vt), d->view); - item->setCheckState(d->viewtypes.contains(vtname) ? Qt::Checked : Qt::Unchecked); - item->setData(Qt::UserRole, vtname); - d->view->addItem(item); - } - parent->addPage(viewpage, i18n("View"), "view-list-details"); - } - - QWidget *p = new QWidget(parent); - QGridLayout *grid = new QGridLayout(p); - grid->setMargin(0); - - QLabel *iconLabel = new QLabel(i18n("Icon:"), p); - grid->addWidget(iconLabel, 0, 0, Qt::AlignRight); - d->iconButton = new KIconButton(p); - d->iconButton->setIcon(d->icon->icon()); - iconLabel->setBuddy(d->iconButton); - grid->addWidget(d->iconButton, 0, 1); - - QLabel *formatLabel = new QLabel(i18nc("@label:listbox How to present applications in a KMenu-like menu", "Format:"), p); - grid->addWidget(formatLabel, 1, 0, Qt::AlignRight); - d->formatComboBox = new KComboBox(p); - formatLabel->setBuddy(d->formatComboBox); - d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name Only"), MenuLauncherApplet::Name); - d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Description Only"), MenuLauncherApplet::Description); - d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name (Description)"), MenuLauncherApplet::NameDescription); - d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Description (Name)"), MenuLauncherApplet::DescriptionName); - d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name - Description"), MenuLauncherApplet::NameDashDescription); - d->setCurrentItem(d->formatComboBox, d->formattype); - grid->addWidget(d->formatComboBox, 1, 1); - - if (d->relativePath.isEmpty()) { - QLabel *recentLabel = new QLabel(i18n("Recently used applications:"), p); - grid->addWidget(recentLabel, 2, 0, Qt::AlignRight); - d->recentApplicationsSpinBox = new QSpinBox(p); - d->recentApplicationsSpinBox->setMaximum(10); - d->recentApplicationsSpinBox->setMinimum(0); - d->recentApplicationsSpinBox->setValue(d->maxRecentApps); - recentLabel->setBuddy(d->recentApplicationsSpinBox); - grid->addWidget(d->recentApplicationsSpinBox, 2, 1); - } - - QLabel *showMenuTitlesLabel = new QLabel(i18n("Show menu titles:"), p); - grid->addWidget(showMenuTitlesLabel, 3, 0, Qt::AlignRight); - d->showMenuTitlesCheckBox = new QCheckBox(p); - d->showMenuTitlesCheckBox->setChecked(d->showMenuTitles); - grid->addWidget(d->showMenuTitlesCheckBox, 3, 1); - - QLabel *showMenuRecentlyInstalledLabel = new QLabel(i18n("Show 'Recently Installed':"), p); - grid->addWidget(showMenuRecentlyInstalledLabel, 4, 0, Qt::AlignRight); - d->showRecentlyInstalledCheckBox = new QCheckBox(p); - d->showRecentlyInstalledCheckBox->setChecked(d->showRecentlyInstalled); - grid->addWidget(d->showRecentlyInstalledCheckBox, 4, 1); - - grid->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 5, 0, 1, 3); - parent->addPage(p, i18n("Options"), "configure"); - - connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); - connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); - connect(d->iconButton, SIGNAL(iconChanged(QString)), parent, SLOT(settingsModified())); - connect(d->formatComboBox, SIGNAL(currentIndexChanged(QString)), parent, SLOT(settingsModified())); - connect(d->recentApplicationsSpinBox, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified())); - connect(d->showMenuTitlesCheckBox, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); - connect(d->showRecentlyInstalledCheckBox, SIGNAL(toggled(bool)), parent, SLOT(settingsModified())); - connect(d->view, SIGNAL(currentTextChanged(QString)), parent, SLOT(settingsModified())); -} - -void MenuLauncherApplet::configAccepted() -{ - bool needssaving = false; - KConfigGroup cg = config(); - - if (d->view) { - QStringList viewtypes; - for(int i = 0; i < d->view->count(); ++i) { - QListWidgetItem *item = d->view->item(i); - QByteArray vtname = item->data(Qt::UserRole).toByteArray(); - if(item->checkState() == Qt::Checked) - viewtypes << vtname; - if( !needssaving && ((item->checkState() == Qt::Checked && ! d->viewtypes.contains(vtname)) || (item->checkState() == Qt::Unchecked && d->viewtypes.contains(vtname))) ) - needssaving = true; - } - if(needssaving) { - d->viewtypes = viewtypes; - d->updateTooltip(); - cg.writeEntry("views", d->viewtypes); - cg.deleteEntry("view"); // "view" was from iconButton->icon(); - if (! iconname.isEmpty()) { - needssaving = true; - d->icon->setIcon(KIcon(iconname)); - d->updateTooltip(); - cg.writeEntry("icon", iconname); - } - - const int ft = d->formatComboBox->itemData(d->formatComboBox->currentIndex()).toInt(); - if (ft != d->formattype) { - needssaving = true; - d->formattype = (MenuLauncherApplet::FormatType) ft; - QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("FormatType")); - cg.writeEntry("format", QByteArray(e.valueToKey(d->formattype))); - } - - if (d->recentApplicationsSpinBox) { - const int maxRecentApps = d->recentApplicationsSpinBox->value(); - if (maxRecentApps != d->maxRecentApps) { - needssaving = true; - d->setMaxRecentApps(maxRecentApps); - cg.writeEntry("maxRecentApps", maxRecentApps); - } - } - - const bool showMenuTitles = d->showMenuTitlesCheckBox->isChecked(); - if (showMenuTitles != d->showMenuTitles) { - needssaving = true; - d->showMenuTitles = showMenuTitles; - cg.writeEntry("showMenuTitles", showMenuTitles); - } - - const bool showRecentlyInstalled = d->showRecentlyInstalledCheckBox->isChecked(); - if (showRecentlyInstalled != d->showRecentlyInstalled) { - needssaving = true; - d->showRecentlyInstalled = showRecentlyInstalled; - cg.writeEntry("showRecentlyInstalled", showRecentlyInstalled); - } - - if (needssaving) { - d->updateTooltip(); - emit configNeedsSaving(); - if (d->menuview) { - d->menuview.data()->deleteLater(); - } - } -} - -inline int weightOfService( const KService::Ptr service ) -{ - QVariant tmp = service->property("X-KDE-Weight", QVariant::Int); - return (tmp.isValid() ? tmp.toInt() : 100); -} -inline bool sortServiceItemsByWeight(const KService::Ptr left, const KService::Ptr right) -{ - return weightOfService(left) < weightOfService(right); -} -KService::List sortServices(KService::List list) -{ - qSort(list.begin(), list.end(), sortServiceItemsByWeight); - return list; -} - -void MenuLauncherApplet::toggleMenu() -{ - showMenu(!d->menuview || !d->menuview.data()->isVisible()); -} - -void MenuLauncherApplet::showMenu(bool pressed) -{ - if (!pressed || d->viewtypes.count()<=0) { - if (d->menuview) { - d->menuview.data()->deleteLater(); - d->menuview.clear(); - } - - return; - } - - d->icon->setPressed(); - - if (!d->menuview) { - Kickoff::MenuView *menuview = new Kickoff::MenuView(); - d->menuview = menuview; - menuview->setAttribute(Qt::WA_DeleteOnClose); - menuview->setFormatType( (Kickoff::MenuView::FormatType) d->formattype ); - menuview->setContextMenuPolicy(Qt::CustomContextMenu); - connect(menuview, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); - connect(menuview, SIGNAL(aboutToHide()), this, SLOT(menuHiding())); - connect(menuview, SIGNAL(customContextMenuRequested(QMenu*,QPoint)), - this, SLOT(customContextMenuRequested(QMenu*,QPoint))); - //connect(menuview, SIGNAL(afterBeingHidden()), menuview, SLOT(deleteLater())); - - //Kickoff::MenuView::ModelOptions options = d->viewtypes.count() < 2 ? Kickoff::MenuView::MergeFirstLevel : Kickoff::MenuView::None; - foreach(const QString &vtname, d->viewtypes) { - if(vtname == "Applications") { - Kickoff::ApplicationModel *appModel = new Kickoff::ApplicationModel(menuview, true /*allow separators*/); - appModel->setApplet(this); - appModel->setDuplicatePolicy(Kickoff::ApplicationModel::ShowLatestOnlyPolicy); - if (d->formattype == Name || d->formattype == NameDescription || d->formattype == NameDashDescription) { - appModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - appModel->setPrimaryNamePolicy(Kickoff::ApplicationModel::AppNamePrimary); - } - appModel->setSystemApplicationPolicy(Kickoff::ApplicationModel::ShowApplicationAndSystemPolicy); - appModel->setShowRecentlyInstalled(d->showRecentlyInstalled); - - menuview->addModel(appModel, Kickoff::MenuView::None, d->relativePath); - - if (d->relativePath.isEmpty()) { - if (d->showMenuTitles) { - menuview->setModelTitleVisible(appModel, true); - menuview->addTitle(i18n("Actions")); - } else { - menuview->addSeparator(); - } - } - } else if(vtname == "Favorites") { - Kickoff::FavoritesModel *favoritesModel = new Kickoff::FavoritesModel(menuview); - if (d->formattype == Name || d->formattype == NameDescription || d->formattype == NameDashDescription) { - favoritesModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - } - d->addModel(favoritesModel, Favorites); - } else if(vtname == "Computer") { - d->addModel(new Kickoff::SystemModel(menuview), Computer); - } else if(vtname == "RecentlyUsed") { - Kickoff::RecentlyUsedModel *recentModel = new Kickoff::RecentlyUsedModel(menuview); - if (d->formattype == Name || d->formattype == NameDescription || d->formattype == NameDashDescription) { - recentModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - } - d->addModel(recentModel, RecentlyUsed); - } else if(vtname == "RecentlyUsedApplications") { - if (d->maxRecentApps > 0) { - Kickoff::RecentlyUsedModel *recentModel = new Kickoff::RecentlyUsedModel(menuview, Kickoff::RecentlyUsedModel::ApplicationsOnly, d->maxRecentApps); - if (d->formattype == Name || d->formattype == NameDescription || d->formattype == NameDashDescription) { - recentModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - } - menuview->addModel(recentModel, Kickoff::MenuView::MergeFirstLevel); - - if (d->showMenuTitles) { - menuview->setModelTitleVisible(recentModel, true); - } else { - menuview->addSeparator(); - } - } - } else if(vtname == "RecentlyUsedDocuments") { - Kickoff::RecentlyUsedModel *recentModel = new Kickoff::RecentlyUsedModel(menuview, Kickoff::RecentlyUsedModel::DocumentsOnly); - menuview->addModel(recentModel, Kickoff::MenuView::MergeFirstLevel); - - if (d->showMenuTitles) { - menuview->setModelTitleVisible(recentModel, true); - } else { - menuview->addSeparator(); - } - } else if(vtname == "Bookmarks") { - KMenu* menu = menuview; - if(d->viewtypes.count() > 1) { - menu = new KMenu(d->viewText(Bookmarks), menuview); - menu->setIcon(KIcon(d->viewIcon(Bookmarks))); - menuview->addMenu(menu); - } - KBookmarkManager* mgr = KBookmarkManager::userBookmarksManager(); - if (! d->bookmarkcollection) { - d->bookmarkcollection = new KActionCollection(this); - d->bookmarkowner = new BookmarkOwner(); - } - delete d->bookmarkmenu; - d->bookmarkmenu = new KBookmarkMenu(mgr, d->bookmarkowner, menu, d->bookmarkcollection); - } else if(vtname == "Settings") { - KMenu* parentmenu = menuview; - if(d->viewtypes.count() > 1) { - parentmenu = new KMenu(d->viewText(Settings), menuview); - parentmenu->setIcon(KIcon(d->viewIcon(Settings))); - menuview->addMenu(parentmenu); - } - QMap menus; - foreach(const KService::Ptr &rootentry, sortServices(KServiceTypeTrader::self()->query("SystemSettingsCategory", "(not exist [X-KDE-System-Settings-Parent-Category]) or [X-KDE-System-Settings-Parent-Category]==''"))) { - parentmenu->addTitle(rootentry->name().replace('&',"&&")); - const QString rootcategory = rootentry->property("X-KDE-System-Settings-Category").toString(); - foreach(const KService::Ptr &entry, sortServices(KServiceTypeTrader::self()->query("SystemSettingsCategory", QString("[X-KDE-System-Settings-Parent-Category]=='%1'").arg(rootcategory)))) { - KMenu* menu = new KMenu(entry->name().replace('&',"&&"), parentmenu); - menu->setIcon(KIcon(entry->icon())); - parentmenu->addMenu(menu); - const QString category = entry->property("X-KDE-System-Settings-Category").toString(); - menus[category] = menu; - } - } - QMap > modules; - foreach(const KService::Ptr &entry, sortServices(KServiceTypeTrader::self()->query("KCModule"))) { - const QString category = entry->property("X-KDE-System-Settings-Parent-Category").toString(); - if(! category.isEmpty() && ! entry->noDisplay()) - modules[category] << entry; - } - foreach(const QString& category, modules.keys()) { - QString menucategory = category; - KService::Ptr subcategory = KService::Ptr(); - while(! menucategory.isEmpty() && ! menus.contains(menucategory)) { - KService::List services = KServiceTypeTrader::self()->query("SystemSettingsCategory", QString("[X-KDE-System-Settings-Category]=='%1'").arg(menucategory)); - //Q_ASSERT(services.count() > 0); //if that happens then we miss the desktop-file defining the category - //Q_ASSERT(services.count() < 2); //if that happens then we have more then one desktop-file defining the same category - if(services.count() < 1) { - menucategory.clear(); - } else { - subcategory = services[0]; - menucategory = subcategory->property("X-KDE-System-Settings-Parent-Category").toString(); - } - } - if(menucategory.isEmpty()) continue; //skip the category - KMenu* m = menus[menucategory]; - if(! subcategory.isNull()) - m->addTitle(subcategory->name().replace('&',"&&")); - foreach(const KService::Ptr &entry, modules[category]) { - KCModuleInfo module(entry->entryPath()); - m->addAction(KIcon(module.icon()), module.moduleName().replace('&',"&&"))->setData(KUrl("kcm:/" + entry->entryPath())); - } - } - } else if(vtname == "SwitchUser") { - menuview->addAction(KIcon(d->viewIcon(SwitchUser)), d->viewText(SwitchUser))->setData(KUrl("leave:/switch")); - } else if(vtname == "SaveSession") { - KConfigGroup c(KSharedConfig::openConfig("ksmserverrc", KConfig::NoGlobals), "General"); - if (c.readEntry("loginMode") == "restoreSavedSession") - menuview->addAction(KIcon(d->viewIcon(SaveSession)), d->viewText(SaveSession))->setData(KUrl("leave:/savesession")); - } else if(vtname == "LockScreen") { - menuview->addAction(KIcon(d->viewIcon(LockScreen)), d->viewText(LockScreen))->setData(KUrl("leave:/lock")); - } else if(vtname == "Logout") { - menuview->addAction(KIcon(d->viewIcon(Logout)), d->viewText(Logout))->setData(KUrl("leave:/logout")); - } else if(vtname == "Leave") { - Kickoff::LeaveModel *leavemodel = new Kickoff::LeaveModel(menuview); - leavemodel->updateModel(); - d->addModel(leavemodel, Leave, Kickoff::MenuView::MergeFirstLevel, Kickoff::MenuView::Name); - } else { - QSet< Solid::PowerManagement::SleepState > spdMethods = Solid::PowerManagement::supportedSleepStates(); - if(vtname == "SuspendDisk") { - if (spdMethods.contains(Solid::PowerManagement::HibernateState)) - menuview->addAction(KIcon(d->viewIcon(SuspendDisk)), d->viewText(SuspendDisk))->setData(KUrl("leave:/suspenddisk")); - } else if(vtname == "SuspendRAM") { - if (spdMethods.contains(Solid::PowerManagement::SuspendState)) - menuview->addAction(KIcon(d->viewIcon(SuspendRAM)), d->viewText(SuspendRAM))->setData(KUrl("leave:/suspendram")); - } else if (vtname == "HybridSuspend") { - if (spdMethods.contains(Solid::PowerManagement::HybridSuspendState)) - menuview->addAction(KIcon(d->viewIcon(HybridSuspend)), d->viewText(HybridSuspend))->setData(KUrl("leave:/suspendhybrid")); - } else if(vtname == "Restart") { - if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot)) - menuview->addAction(KIcon(d->viewIcon(Restart)), d->viewText(Restart))->setData(KUrl("leave:/restart")); - } else if(vtname == "Shutdown") { - if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt)) - menuview->addAction(KIcon(d->viewIcon(Shutdown)), d->viewText(Shutdown))->setData(KUrl("leave:/shutdown")); - } - } - } - } - - Plasma::ToolTipManager::self()->hide(this); - setStatus(Plasma::NeedsAttentionStatus); - d->menuview.data()->popup(popupPosition(d->menuview.data()->sizeHint())); -} - -void MenuLauncherApplet::menuHiding() -{ - d->icon->setUnpressed(); - setStatus(Plasma::PassiveStatus); -} - -void MenuLauncherApplet::actionTriggered(QAction *action) -{ - const KUrl url = action->data().value(); - if (url.scheme() == "leave") { - if (!d->launcher) { - d->launcher = new Kickoff::UrlItemLauncher(d->menuview.data()); - } - - d->launcher.data()->openUrl(url.url()); - return; - } - if (url.scheme() == "kcm") { - KToolInvocation::kdeinitExec("kcmshell4", QStringList() << url.fileName()); - return; - } - for (QWidget* w = action->parentWidget(); w; w = w->parentWidget()) { - if (Kickoff::MenuView *view = qobject_cast(w)) { - view->actionTriggered(action); - break; - } - } -} - -QList MenuLauncherApplet::contextualActions() -{ - return d->actions; -} - -void MenuLauncherApplet::iconSizeChanged(int group) -{ - if (group == KIconLoader::Desktop || group == KIconLoader::Panel) { - updateGeometry(); - } -} - -QSizeF MenuLauncherApplet::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const -{ - if (which == Qt::PreferredSize) { - int iconSize = -1; - - switch (formFactor()) { - case Plasma::Planar: - case Plasma::MediaCenter: - iconSize = IconSize(KIconLoader::Desktop); - break; - - case Plasma::Horizontal: - case Plasma::Vertical: - iconSize = IconSize(KIconLoader::Panel); - break; - } - - return QSizeF(iconSize, iconSize); - } - - return Plasma::Applet::sizeHint(which, constraint); -} - - -void MenuLauncherApplet::saveConfigurationFromKickoff(const KConfigGroup & configGroup, const KConfigGroup & globalConfigGroup) -{ - //Copy configuration values - KConfigGroup cg = config(); - configGroup.copyTo(&cg); - - KConfigGroup gcg = globalConfig(); - globalConfigGroup.copyTo(&gcg); - - configChanged(); - emit configNeedsSaving(); -} - -void MenuLauncherApplet::configChanged() -{ - KConfigGroup cg = config(); - - const QStringList viewtypes = cg.readEntry("views", QStringList()); - if(viewtypes.isEmpty()) { // backward-compatibility to viewtypes = QStringList() << oldview; - d->iconname = d->viewIcon(d->viewType(oldview)); - } // else we use the default d->viewtypes - } else { - d->viewtypes = viewtypes; - } - - QMetaEnum fte = metaObject()->enumerator(metaObject()->indexOfEnumerator("FormatType")); - QByteArray ftb = cg.readEntry("format", QByteArray(fte.valueToKey(d->formattype))); - d->formattype = (MenuLauncherApplet::FormatType) fte.keyToValue(ftb); - - d->setMaxRecentApps(cg.readEntry("maxRecentApps", qMin(5, Kickoff::RecentApplications::self()->maximum()))); - d->showMenuTitles = cg.readEntry("showMenuTitles", false); - d->showRecentlyInstalled = cg.readEntry("showRecentlyInstalled", true); - - d->icon->setIcon(KIcon(cg.readEntry("icon", d->iconname))); - - d->relativePath = cg.readEntry("relativePath", d->relativePath); - if (!d->relativePath.isEmpty()) { - d->viewtypes.clear(); - d->viewtypes << "Applications"; - } - - d->updateTooltip(); - - constraintsEvent(Plasma::ImmutableConstraint); -} - -#include "moc_simpleapplet.cpp" diff --git a/plasma/applets/kickoff/simpleapplet/simpleapplet.h b/plasma/applets/kickoff/simpleapplet/simpleapplet.h deleted file mode 100644 index a79f3d8f..00000000 --- a/plasma/applets/kickoff/simpleapplet/simpleapplet.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2008-2009 Sebastian Sauer - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SIMPLEAPPLET_H -#define SIMPLEAPPLET_H - -// Plasma -#include - -#include - -/** -* The MenuLauncherApplet class implements an applet that provides the traditional -* aka classic KDE3 like KMenu application launcher using the Kickoff functionality. -*/ -class MenuLauncherApplet : public Plasma::Applet -{ - Q_OBJECT - Q_ENUMS(ViewType) - Q_ENUMS(FormatType) -public: - - /** - * The content we like to display within the menu. - */ - enum ViewType { - RecentlyUsedApplications, ///< Recently Used Applications Menu - RecentlyUsedDocuments, ///< Recently Used Documents Menu - Applications, ///< Applications Menu - Favorites, ///< Favorites Menu - Bookmarks, ///< Bookmarks Menu - Computer, ///< Computer Menu - RecentlyUsed, ///< Recently Used Menu - Settings, ///< Settings Menu - SwitchUser, ///< Switch User Action - SaveSession, ///< Save Session Action (only enabled if restoreSavedSession is enabled) - LockScreen, ///< Lock Screen Action - SuspendDisk, ///< Suspend to Disk Action - SuspendRAM, ///< Suspend to RAM Action - HybridSuspend, ///< Hybrid Suspend Action - Restart, ///< Restart Action - Shutdown, ///< Shutdown Action - Logout, ///< Logout Action - Leave ///< Leave Menu - }; - - /** - * How the text of the menuitems got formatted. - */ - enum FormatType { - Name = 0, ///< Name only - Description, ///< Description only - NameDescription, ///< Name Description - DescriptionName, ///< Description (Name) - NameDashDescription ///< Name - Description - }; - - /** - * Constructor. - * - * \param parent The parent QObject. - * \param args The optional list of arguments. - */ - MenuLauncherApplet(QObject *parent, const QVariantList &args); - - /** - * Destructor. - */ - virtual ~MenuLauncherApplet(); - - /** - * This method is called once the applet is loaded and added to a Corona. - **/ - void init(); - - /** - * Called when any of the geometry constraints have been updated. - * - * @param constraints the type of constraints that were updated - */ - void constraintsEvent(Plasma::Constraints constraints); - - /** - * Returns a list of context-related QAction instances. - */ - virtual QList contextualActions(); - -public Q_SLOTS: - /** - * Switch the menu style from the traditional aka classic KDE3 like - * KMenu to the new Kickoff menu. - */ - void switchMenuStyle(); - - /** - * Start the menu editor by launching kmenuedit. - */ - void startMenuEditor(); - - /** - * Show a custom context menu for the selected action. - */ - void customContextMenuRequested(QMenu* menu, const QPoint& pos); - - /** - * Save config values stored on Kickoff after a menu switch - */ - void saveConfigurationFromKickoff(const KConfigGroup & configGroup, - const KConfigGroup & globalConfigGroup); - - /** - * Reload configuration values - * Useful to load previously stored configurations after a menu switch - */ - void configChanged(); - -protected: - /** - * Create a configuration dialog. - */ - void createConfigurationInterface(KConfigDialog *parent); - - QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF()) const; - -private Q_SLOTS: - /// Configuration-dialog accepted. - void configAccepted(); - /// The menu got toggled or activated. - void toggleMenu(); - /// Shows the menu due to being toggled / activated. - void showMenu(bool pressed); - /// An action within the menu got triggered. - void actionTriggered(QAction *action); - /// Icon size setting changed - void iconSizeChanged(int group); - /// Menu is hidden, reset the UI - void menuHiding(); - -private: - class Private; - Private * const d; -}; - -K_EXPORT_PLASMA_APPLET(menulauncher, MenuLauncherApplet) - -#endif diff --git a/plasma/applets/kickoff/ui/contentareacap.cpp b/plasma/applets/kickoff/ui/contentareacap.cpp deleted file mode 100644 index 312c984e..00000000 --- a/plasma/applets/kickoff/ui/contentareacap.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright 2008 Andrew Lake - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "contentareacap.h" -#include -#include - -ContentAreaCap::ContentAreaCap(QWidget *parent, bool flip) - :QWidget(parent) -{ - setMaximumHeight(3); - setMinimumHeight(3); - sizePolicy().setVerticalPolicy(QSizePolicy::Fixed); - flipCap = flip; - - parent->setCursor(Qt::ArrowCursor); -} - -void ContentAreaCap::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - - QPainter painter(this); - QPainterPath path; - QRect r = rect(); - if (!flipCap) { - path.moveTo(r.topLeft() + QPoint(0,3)); - path.quadTo(r.topLeft(), r.topLeft() + QPoint(3,0)); - path.lineTo(r.topRight() + QPoint(-2,0)); - path.quadTo(r.topRight() + QPoint(1,0), r.topRight() + QPoint(1,3)); - } else { - path.moveTo(r.topLeft()); - path.quadTo(r.topLeft() + QPoint(0,3), r.topLeft() + QPoint(3,3)); - path.lineTo(r.topRight() + QPoint(-2,3)); - path.quadTo(r.topRight() + QPoint(1,3), r.topRight() + QPoint(1,0)); - } - painter.setPen(QPen(palette().base(), 1)); - painter.setRenderHint(QPainter::Antialiasing); - painter.fillPath(path, palette().base()); - painter.end(); -} - diff --git a/plasma/applets/kickoff/ui/contextmenufactory.cpp b/plasma/applets/kickoff/ui/contextmenufactory.cpp deleted file mode 100644 index 04e06d51..00000000 --- a/plasma/applets/kickoff/ui/contextmenufactory.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "ui/contextmenufactory.h" - -// Qt -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Plasma -#include -#include - -// Local -#include "core/favoritesmodel.h" -#include "core/models.h" - -Q_DECLARE_METATYPE(QPersistentModelIndex) - -using namespace Kickoff; - -class ContextMenuFactory::Private -{ -public: - Private() - : applet(0) { - } - - QMap > viewActions; - Plasma::Applet *applet; -}; - -ContextMenuFactory::ContextMenuFactory(QObject *parent) - : QObject(parent) - , d(new Private) -{ -} - -ContextMenuFactory::~ContextMenuFactory() -{ - delete d; -} - -void ContextMenuFactory::showContextMenu(QAbstractItemView *view, - const QPersistentModelIndex& index, const QPoint& pos) -{ - Q_UNUSED(pos); - - if (!index.isValid()) { - return; - } - - QString url = index.data(UrlRole).value(); - qDebug() << "ContextMenuFactory::showContextMenu: " << url; - - if (url.isEmpty()) { - return; - } - - // ivan: The url handling is dirty - instead of handling it in - // the source data models (that define them), we are handling - // them here. So, we need to make urls from KRunner model - // to behave properly - if (url.startsWith(QLatin1String("krunner://"))) { - url = url.remove("krunner://"); - qDebug() << "ContextMenuFactory::showContextMenu: 1 " << url; - if (url.startsWith(QLatin1String("services/services_"))) { - url = url.remove("services/services_"); - } else { - return; - } - - KService::Ptr service = KService::serviceByStorageId(url); - if(!service) { - return; - } - - url = service->entryPath(); - - qDebug() << "ContextMenuFactory::showContextMenu: " << "KRunner service runner: " << url; - } - - - const bool isFavorite = FavoritesModel::isFavorite(url); - - QList actions; - - QAction *favoriteAction = 0; - - if (url.endsWith(QLatin1String(".desktop"))) { - // add to / remove from favorites - favoriteAction = new QAction(this); - if (isFavorite) { - favoriteAction->setText(i18n("Remove From Favorites")); - favoriteAction->setIcon(KIcon("list-remove")); - actions << favoriteAction; - //exclude stuff in the leave tab - } else if (KUrl(url).protocol() != "leave") { - favoriteAction->setText(i18n("Add to Favorites")); - favoriteAction->setIcon(KIcon("bookmark-new")); - actions << favoriteAction; - } - } - - // add to desktop - QAction *addToDesktopAction = new QAction(this); - - // add to main panel - QAction *addToPanelAction = new QAction(this); - - //### FIXME : icons in leave-view are not properly based on a .desktop file - //so you cant put them in desktop or panel - //### TODO : do not forget to remove (kurl.scheme() != "leave") and kurl declaration - //when proper action for such case will be provided - KUrl kurl(url); - if ((d->applet) && (kurl.scheme() != "leave")) { - Plasma::Containment *containment = d->applet->containment(); - - // There might be relative paths for .desktop installed in - // /usr/shar/applnk, we need to locate them - bool urlFound = true; - if (kurl.isRelative() && kurl.url().endsWith(QLatin1String(".desktop"))) { - kurl = KStandardDirs::locate("apps", url); - urlFound = !kurl.isEmpty(); - } - - if (urlFound && containment && containment->corona()) { - Plasma::Containment *desktop = containment->corona()->containmentForScreen(containment->screen()); - - if (desktop && desktop->immutability() == Plasma::Mutable) { - addToDesktopAction->setText(i18n("Add to Desktop")); - actions << addToDesktopAction; - } - } - - if (urlFound && containment && containment->immutability() == Plasma::Mutable && - (containment->containmentType() == Plasma::Containment::PanelContainment || - containment->containmentType() == Plasma::Containment::CustomPanelContainment)) { - addToPanelAction->setText(i18n("Add to Panel")); - actions << addToPanelAction; - } - } - - QAction *advancedSeparator = new QAction(this); - if (actions.count() > 0) { - // advanced item actions - advancedSeparator->setSeparator(true); - actions << advancedSeparator; - } - - // device actions - const QString udi = index.data(DeviceUdiRole).toString(); - Solid::Device device(udi); - Solid::StorageAccess *access = device.as(); - QAction *ejectAction = 0; - if (device.isValid() && access) { - ejectAction = new QAction(this); - if (device.is()) { - ejectAction->setText(i18n("Eject")); - } else { - ejectAction->setText(i18n("Safely Remove")); - } - actions << ejectAction; - } - - // add view specific actions - QAction *viewSeparator = new QAction(this); - if (view) { - if (actions.count() > 0) { - viewSeparator->setSeparator(true); - actions << viewSeparator; - } - actions << viewActions(view); - } - - //return if we added just a separator so far - if (actions.count() < 2) { - return; - } - - - // display menu - KMenu menu; - menu.addTitle(index.data(Qt::DisplayRole).value()); - foreach(QAction* action, actions) { - menu.addAction(action); - } - - QAction *result = menu.exec(QCursor::pos()); - - if (favoriteAction && result == favoriteAction) { - if (isFavorite) { - FavoritesModel::remove(url); - } else { - FavoritesModel::add(url); - } - } else if (ejectAction && result == ejectAction) { - if (device.is()) { - Solid::OpticalDrive *drive = device.as(); - drive->eject(); - } else { - access->teardown(); - } - } else if (addToDesktopAction && result == addToDesktopAction) { - if (d->applet) { - Plasma::Containment *containment = d->applet->containment(); - if (containment) { - Plasma::Corona *corona = containment->corona(); - if (corona) { - int vdesk = KWindowSystem::currentDesktop() - 1; - Plasma::Containment *desktop = corona->containmentForScreen(containment->screen(), vdesk); - //PVDA disabled? - if (!desktop) { - desktop = corona->containmentForScreen(containment->screen(), -1); - } - if (desktop) { - QVariantList args; - args << kurl.url() << index.data(Kickoff::IconNameRole); - if (kurl.scheme() == "applications") { // it's a service group - desktop->addApplet("simplelauncher", args); - } else if (desktop->metaObject()->indexOfSlot("addUrls(KUrl::List)") != -1) { - QMetaObject::invokeMethod(desktop, "addUrls", - Qt::DirectConnection, Q_ARG(KUrl::List, KUrl::List(kurl))); - } else { - desktop->addApplet("icon", args); - } - } - } - } - } - }else if (addToPanelAction && result == addToPanelAction) { - if (d->applet) { - // we assume that the panel is the same containment where the kickoff is located - Plasma::Containment *panel = d->applet->containment(); - if (panel) { - QVariantList args; - args << kurl.url() << index.data(Kickoff::IconNameRole); - - // move it to the middle of the panel - QRectF rect(panel->geometry().width() / 2, 0, 150, panel->boundingRect().height()); - if (kurl.scheme() == "applications") { // it's a service group - panel->addApplet("simplelauncher", args); - } else { - panel->addApplet("icon", args, rect); - } - } - } - } - - delete favoriteAction; - delete addToDesktopAction; - delete addToPanelAction; - delete advancedSeparator; - delete viewSeparator; - delete ejectAction; -} - -void ContextMenuFactory::setViewActions(QAbstractItemView *view, const QList& actions) -{ - if (actions.isEmpty()) { - d->viewActions.remove(view); - } else { - d->viewActions.insert(view, actions); - } -} -QList ContextMenuFactory::viewActions(QAbstractItemView *view) const -{ - return d->viewActions[view]; -} - -void ContextMenuFactory::setApplet(Plasma::Applet *applet) -{ - d->applet = applet; -} - -#include "moc_contextmenufactory.cpp" diff --git a/plasma/applets/kickoff/ui/contextmenufactory.h b/plasma/applets/kickoff/ui/contextmenufactory.h deleted file mode 100644 index ce001195..00000000 --- a/plasma/applets/kickoff/ui/contextmenufactory.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef CONTEXTMENUFACTORY_H -#define CONTEXTMENUFACTORY_H - -// Qt -#include -#include - -// Plasma -#include - -#include - -namespace Kickoff -{ - -class ContextMenuFactory : public QObject -{ - Q_OBJECT - -public: - ContextMenuFactory(QObject *parent = 0); - ~ContextMenuFactory(); - - void setViewActions(QAbstractItemView *view, const QList& actions); - QList viewActions(QAbstractItemView *view) const; - - void setApplet(Plasma::Applet *applet); - -public Q_SLOTS: - void showContextMenu(QAbstractItemView *view, - const QPersistentModelIndex& index, const QPoint& pos); - -private: - class Private; - Private * const d; -}; - -} - -#endif // CONTEXTMENUFACTORY_H diff --git a/plasma/applets/kickoff/ui/flipscrollview.cpp b/plasma/applets/kickoff/ui/flipscrollview.cpp deleted file mode 100644 index f17c1aaa..00000000 --- a/plasma/applets/kickoff/ui/flipscrollview.cpp +++ /dev/null @@ -1,567 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "ui/flipscrollview.h" - -// Qt -#include -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include - -#include "ui/itemdelegate.h" - -using namespace Kickoff; - -class FlipScrollView::Private -{ -public: - Private(FlipScrollView *view) - : q(view) - , flipAnimTimeLine(new QTimeLine()) - , animLeftToRight(true) - , itemHeight(-1) { - } - - ~Private() - { - delete flipAnimTimeLine; - } - - QModelIndex currentRoot() const - { - if (currentRootIndex.isValid()) { - return currentRootIndex; - } else { - return q->rootIndex(); - } - } - - QModelIndex previousRoot() const - { - if (previousRootIndices.isEmpty()) { - return QModelIndex(); - } - return previousRootIndices.top(); - } - - void setCurrentRoot(const QModelIndex& index) - { - if (previousRootIndices.isEmpty() || previousRootIndices.top() != index) { - // we're entering into a submenu - //kDebug() << "pushing" << currentRootIndex.data(Qt::DisplayRole).value(); - animLeftToRight = true; - hoveredIndex = QModelIndex(); - previousRootIndices.push(currentRootIndex); - currentRootIndex = index; - previousVerticalOffsets.append(q->verticalOffset()); - updateScrollBarRange(); - q->verticalScrollBar()->setValue(0); - } else { - // we're exiting to the parent menu - //kDebug() << "popping" << previousRootIndices.top().data(Qt::DisplayRole).value(); - animLeftToRight = false; - hoveredIndex = currentRootIndex; - previousRootIndices.pop(); - //if (!previousRootIndices.isEmpty()) { - // kDebug() << "now the previos root is" << previousRootIndices.top().data(Qt::DisplayRole).value(); - //} - currentRootIndex = index; - updateScrollBarRange(); - q->verticalScrollBar()->setValue(previousVerticalOffsets.pop()); - } - - emit q->currentRootChanged(index); - - if (q->viewOptions().direction == Qt::RightToLeft) { - animLeftToRight = !animLeftToRight; - } - - flipAnimTimeLine->setCurrentTime(0); - q->update(); - } - - int previousVerticalOffset() - { - return previousVerticalOffsets.isEmpty() ? 0 : previousVerticalOffsets.top(); - } - - int treeDepth(const QModelIndex& headerIndex) const - { - int depth = 0; - QModelIndex index = headerIndex; - while (index.isValid()) { - index = index.parent(); - depth++; - } - return depth; - } - - QPainterPath trianglePath(qreal width = 5, qreal height = 10) { - QPainterPath path(QPointF(-width / 2, 0.0)); - path.lineTo(width, -height / 2); - path.lineTo(width, height / 2); - path.lineTo(-width / 2, 0.0); - - return path; - } - - void updateScrollBarRange() - { - int childCount = q->model()->rowCount(currentRootIndex); - int pageSize = q->height(); - int itemH = q->sizeHintForIndex(q->model()->index(0, 0)).height(); - q->verticalScrollBar()->setRange(0, (childCount * itemH) - pageSize); - q->verticalScrollBar()->setPageStep(pageSize); - q->verticalScrollBar()->setSingleStep(itemH); - } - - FlipScrollView * const q; - QPersistentModelIndex hoveredIndex; - QPersistentModelIndex watchedIndexForDrag; - - QTimeLine *flipAnimTimeLine; - bool animLeftToRight; - - int itemHeight; - static const int FLIP_ANIM_DURATION = 200; - -private: - QPersistentModelIndex currentRootIndex; - QStack previousRootIndices; - QStack previousVerticalOffsets; -}; - -FlipScrollView::FlipScrollView(QWidget *parent) - : QAbstractItemView(parent) - , d(new Private(this)) -{ - connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(openItem(QModelIndex))); - connect(d->flipAnimTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(updateFlipAnimation(qreal))); - d->flipAnimTimeLine->setDuration(Private::FLIP_ANIM_DURATION); - d->flipAnimTimeLine->setCurrentTime(Private::FLIP_ANIM_DURATION); - setIconSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium)); - setMouseTracking(true); - setAutoScroll(true); - QPalette viewPalette(palette()); - viewPalette.setColor(QPalette::Window, palette().color(QPalette::Active, QPalette::Base)); - setPalette(viewPalette); - setAutoFillBackground(true); -} -FlipScrollView::~FlipScrollView() -{ - delete d; -} - -void FlipScrollView::setCurrentRoot(const QModelIndex &index) -{ - d->setCurrentRoot(index); -} - -void FlipScrollView::viewRoot() -{ - QModelIndex index; - while (d->currentRoot().isValid()) { - index = d->currentRoot(); - d->setCurrentRoot(d->currentRoot().parent()); - setCurrentIndex(index); - } - update(d->hoveredIndex); - d->hoveredIndex = index; -} - -QModelIndex FlipScrollView::indexAt(const QPoint& point) const -{ - const int items = model()->rowCount(d->currentRoot()); - const int rowIndex = (point.y() + verticalOffset()) / itemHeight(); - - if (rowIndex < items) { - return model()->index(rowIndex, 0, d->currentRoot()); - } else { - return QModelIndex(); - } -} - -int FlipScrollView::itemHeight() const -{ - //TODO: reset on font change - if (d->itemHeight < 1) { - QModelIndex index = model()->index(0, 0, d->currentRoot()); - d->itemHeight = sizeHintForIndex(index).height(); - } - - return d->itemHeight; -} - -void FlipScrollView::scrollTo(const QModelIndex& index, ScrollHint hint) -{ - if (!index.isValid()) { - return; - } - - const QRect itemRect = visualRect(index); - if (itemRect.isValid() && hint == EnsureVisible) { - if (itemRect.top() < 0) { - verticalScrollBar()->setValue(verticalScrollBar()->value() + - itemRect.top()); - } else if (itemRect.bottom() > height()) { - verticalScrollBar()->setValue(verticalScrollBar()->value() + - (itemRect.bottom() - height())); - } - update(itemRect); - } -} - -bool FlipScrollView::isIndexHidden(const QModelIndex&) const -{ - return false; -} - -QRect FlipScrollView::visualRect(const QModelIndex& index) const -{ - const int leftOffset = ItemDelegate::ITEM_LEFT_MARGIN; - - if (index.parent() != d->currentRoot() && - index.parent() != d->previousRoot() && - index.parent() != (QModelIndex)d->hoveredIndex) { - return QRect(); - } - - const bool parentIsPreviousRoot = d->previousRoot().isValid() && index.parent() == d->previousRoot(); - if (parentIsPreviousRoot && d->flipAnimTimeLine->state() == QTimeLine::NotRunning) { - return QRect(); - } - - const int scrollBarWidth = verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0; - QRect itemRect(leftOffset, index.row() * itemHeight() - verticalOffset() , - width() - leftOffset - scrollBarWidth, itemHeight()); - - const qreal timeValue = d->flipAnimTimeLine->currentValue(); - if (index.parent() == d->currentRoot()) { - if (d->animLeftToRight) { - itemRect.translate(itemRect.width() * (1 - timeValue), 0); - } else { - itemRect.translate(-itemRect.width() * (1 - timeValue), 0); - } - } else { - if (d->animLeftToRight) { - itemRect.translate((-timeValue*itemRect.width()), 0); - } else { - itemRect.translate((timeValue*itemRect.width()), 0); - } - } - - return itemRect; -} - -int FlipScrollView::horizontalOffset() const -{ - return 0; -} - -int FlipScrollView::verticalOffset() const -{ - return verticalScrollBar()->value(); -} - -QRegion FlipScrollView::visualRegionForSelection(const QItemSelection& selection) const -{ - QRegion region; - foreach(const QModelIndex& index , selection.indexes()) { - region |= visualRect(index); - } - return region; -} -QModelIndex FlipScrollView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers) -{ - QModelIndex index = currentIndex(); - // kDebug() << "Moving cursor with current index" << index.data(Qt::DisplayRole); - switch (cursorAction) { - case MoveUp: - if (!currentIndex().isValid()) { - index = model()->index(model()->rowCount(d->currentRoot()) - 1, 0, d->currentRoot()); - } else if (currentIndex().row() > 0) { - index = currentIndex().sibling(currentIndex().row() - 1, - currentIndex().column()); - } - break; - case MoveDown: - if (!currentIndex().isValid()) { - index = model()->index(0, 0, d->currentRoot()); - } else if (currentIndex().row() < - model()->rowCount(currentIndex().parent()) - 1) { - index = currentIndex().sibling(currentIndex().row() + 1, - currentIndex().column()); - } - break; - case MoveLeft: - if (d->currentRoot().isValid()) { - index = d->currentRoot(); - d->setCurrentRoot(d->currentRoot().parent()); - setCurrentIndex(index); - } - break; - case MoveRight: - if (model()->hasChildren(currentIndex())) { - openItem(currentIndex()); - // return the new current index set by openItem() - index = currentIndex(); - } - break; - default: - // Do nothing - break; - } - - // clear the hovered index - update(d->hoveredIndex); - d->hoveredIndex = index; - - //kDebug() << "New index after move" << index.data(Qt::DisplayRole); - return index; -} - -void FlipScrollView::setSelection(const QRect& rect , QItemSelectionModel::SelectionFlags flags) -{ - QItemSelection selection; - selection.select(indexAt(rect.topLeft()), indexAt(rect.bottomRight())); - selectionModel()->select(selection, flags); -} - -void FlipScrollView::openItem(const QModelIndex& index) -{ - if (model()->canFetchMore(index)) { - model()->fetchMore(index); - } - - const bool hasChildren = model()->hasChildren(index); - - if (hasChildren) { - d->setCurrentRoot(index); - setCurrentIndex(model()->index(0, 0, index)); - } else { - //TODO Emit a signal to open/execute the item - } -} - -void FlipScrollView::resizeEvent(QResizeEvent*) -{ - d->updateScrollBarRange(); -} - -void FlipScrollView::mousePressEvent(QMouseEvent *event) -{ - d->watchedIndexForDrag = indexAt(event->pos()); - QAbstractItemView::mousePressEvent(event); -} - -void FlipScrollView::mouseReleaseEvent(QMouseEvent *event) -{ - d->watchedIndexForDrag = QModelIndex(); - QAbstractItemView::mouseReleaseEvent(event); -} - -void FlipScrollView::mouseMoveEvent(QMouseEvent *event) -{ - const QModelIndex itemUnderMouse = indexAt(event->pos()); - if (itemUnderMouse != d->hoveredIndex) { - update(itemUnderMouse); - update(d->hoveredIndex); - - d->hoveredIndex = itemUnderMouse; - setCurrentIndex(d->hoveredIndex); - } - - QAbstractItemView::mouseMoveEvent(event); -} - -void FlipScrollView::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Enter || - event->key() == Qt::Key_Return || - event->key() == Qt::Key_Right) { - moveCursor(MoveRight, event->modifiers()); - event->accept(); - return; - } - - if (event->key() == Qt::Key_Escape || event->key() == Qt::Key_Left) { - if (d->currentRoot().isValid()) { - moveCursor(MoveLeft, event->modifiers()); - event->accept(); - return; - } else { - // we are already in the leftmost column. - kDebug() << "we are in Left-Most column, processing Key_Left"; - event->accept(); - emit focusNextViewLeft(); - return; - } - } - QAbstractItemView::keyPressEvent(event); -} - -void FlipScrollView::leaveEvent(QEvent *event) -{ - Q_UNUSED(event); - d->hoveredIndex = QModelIndex(); - setCurrentIndex(QModelIndex()); -} - -void FlipScrollView::paintItems(QPainter &painter, QPaintEvent *event, QModelIndex &root) -{ - const int rows = model()->rowCount(root); - //kDebug() << "painting" << rows << "items"; - - for (int i = 0; i < rows; ++i) { - QModelIndex index = model()->index(i, 0, root); - - QStyleOptionViewItem option = viewOptions(); - option.rect = visualRect(index); - - // only draw items intersecting the region of the widget - // being updated - if (!event->rect().intersects(option.rect)) { - continue; - } - - if (selectionModel()->isSelected(index)) { - option.state |= QStyle::State_Selected; - } - - if (index == d->hoveredIndex) { - option.state |= QStyle::State_MouseOver; - } - - if (index == currentIndex()) { - option.state |= QStyle::State_HasFocus; - } - - itemDelegate(index)->paint(&painter, option, index); - - if (model()->hasChildren(index)) { - painter.save(); - painter.setPen(Qt::NoPen); - // there is an assumption made here that the delegate will fill the background - // with the selected color or some similar color which contrasts well with the - // highlighted text color - if (option.state & QStyle::State_MouseOver) { - painter.setBrush(palette().highlight()); - } else { - painter.setBrush(palette().text()); - } - - QRect triRect = option.rect; - QPainterPath tPath = d->trianglePath(); - if (option.direction == Qt::LeftToRight) { - triRect.setLeft(triRect.right() - ItemDelegate::ITEM_RIGHT_MARGIN); - painter.translate(triRect.center().x() - 6, triRect.y() + (option.rect.height() / 2)); - - } else { - triRect.setRight(triRect.left() + ItemDelegate::ITEM_RIGHT_MARGIN); - painter.translate(triRect.center().x() + 6, triRect.y() + (option.rect.height() / 2)); - } - - - if (option.direction == Qt::LeftToRight) { - painter.rotate(180); - } - - painter.drawPath(tPath); - painter.resetTransform(); - painter.restore(); - } - } -} - -void FlipScrollView::paintEvent(QPaintEvent * event) -{ - QPalette viewPalette(palette()); - viewPalette.setColor(QPalette::Window, palette().color(QPalette::Active, QPalette::Base)); - setPalette(viewPalette); - setAutoFillBackground(true); - - QPainter painter(viewport()); - painter.setRenderHint(QPainter::Antialiasing); - - // draw items - QModelIndex currentRoot = d->currentRoot(); - QModelIndex previousRoot = d->animLeftToRight ? d->previousRoot() : (QModelIndex)d->hoveredIndex; - //kDebug() << "current root is" << currentRoot.data(Qt::DisplayRole).value(); - - paintItems(painter, event, currentRoot); - - const qreal timerValue = d->flipAnimTimeLine->currentValue(); - - if (timerValue < 1.0) { - //kDebug() << "previous root is" << previousRoot.data(Qt::DisplayRole).value(); - paintItems(painter, event, previousRoot); - - if (d->flipAnimTimeLine->state() != QTimeLine::Running) { - d->flipAnimTimeLine->start(); - } - } - - // draw navigation - QStyle::State state = 0; - if (currentRoot.isValid()) { - state |= QStyle::State_Enabled; - } -} - -void FlipScrollView::startDrag(Qt::DropActions supportedActions) -{ - kDebug() << "Starting UrlItemView drag with actions" << supportedActions; - - if (!d->watchedIndexForDrag.isValid()) { - return; - } - - QDrag *drag = new QDrag(this); - QMimeData *mimeData = model()->mimeData(selectionModel()->selectedIndexes()); - - if (mimeData->text().isNull()) { - return; - } - - drag->setMimeData(mimeData); - - QModelIndex idx = selectionModel()->selectedIndexes().first(); - QIcon icon = idx.data(Qt::DecorationRole).value(); - drag->setPixmap(icon.pixmap(IconSize(KIconLoader::Desktop))); - - drag->exec(); -} - -void FlipScrollView::updateFlipAnimation(qreal) -{ - setDirtyRegion(rect()); -} - -#include "moc_flipscrollview.cpp" diff --git a/plasma/applets/kickoff/ui/flipscrollview.h b/plasma/applets/kickoff/ui/flipscrollview.h deleted file mode 100644 index e7eba093..00000000 --- a/plasma/applets/kickoff/ui/flipscrollview.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef FLIPSCROLLVIEW_H -#define FLIPSCROLLVIEW_H - -// Qt -#include - -namespace Kickoff -{ - -/** - * An "iPod-style" item view for single-column tree and list data models which - * displays items in pages (one per tree branch). - * - * Clicking on an item which has children (eg. a folder in a directory model) - * scrolls the whole contents of the view to show the items children. A large back - * arrow is displayed on the left of the display if the current item has a valid parent, - * when clicked on this scrolls the whole contents of the view to show the parent item's - * children. - * - * The view assumes that the item delegate will fill the background with the current palette's - * highlight color when the user hovers over items with the mouse. Item delegates should check - * for the QStyle::State_MouseOver or QStyle::State_Selected flags in the state - * field of the QStyleOptionViewItem passed to the QAbstractItemDelegate::paint() method. - */ -class FlipScrollView : public QAbstractItemView -{ - Q_OBJECT - -public: - /** Construct a new FlipScrollView with the specified parent. */ - FlipScrollView(QWidget *parent = 0); - virtual ~FlipScrollView(); - - void setCurrentRoot(const QModelIndex &index); - - /** Go to the root item. */ - void viewRoot(); - - // reimplemented from QAbstractItemView - virtual QModelIndex indexAt(const QPoint& point) const; - virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible); - virtual QRect visualRect(const QModelIndex& index) const; - - int itemHeight() const; - -Q_SIGNALS: - void currentRootChanged(const QModelIndex &index); - void focusNextViewLeft(); - -protected: - // reimplemented from QWidget - virtual void paintEvent(QPaintEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void resizeEvent(QResizeEvent *event); - virtual void keyPressEvent(QKeyEvent *event); - virtual void leaveEvent(QEvent *event); - - // reimplemented from QAbstractItemView - virtual bool isIndexHidden(const QModelIndex& index) const; - virtual int horizontalOffset() const; - virtual int verticalOffset() const; - virtual QRegion visualRegionForSelection(const QItemSelection& selection) const; - virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers); - virtual void setSelection(const QRect& rect , QItemSelectionModel::SelectionFlags flags); - virtual void startDrag(Qt::DropActions supportedActions); - -private Q_SLOTS: - void openItem(const QModelIndex& index); - void updateFlipAnimation(qreal value); - -private: - void paintItems(QPainter &painter, QPaintEvent *event, QModelIndex &index); - - class Private; - Private * const d; -}; - -} - -#endif // FLIPSCROLLVIEW_H diff --git a/plasma/applets/kickoff/ui/itemdelegate.cpp b/plasma/applets/kickoff/ui/itemdelegate.cpp deleted file mode 100644 index 7c60a210..00000000 --- a/plasma/applets/kickoff/ui/itemdelegate.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "ui/itemdelegate.h" - -// Qt -#include -#include -#include -#include - -// KDE -#include -#include -#include - -// plasma -#include - -using namespace Kickoff; - -ItemDelegate::ItemDelegate(QObject *parent) - : Plasma::Delegate(parent) -{ -} - -void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const -{ - Plasma::Delegate::paint(painter, option, index); - - qreal freeSpace = -1; - qreal usedSpace = -1; - if (!index.data(DiskFreeSpaceRole).isNull()) { - freeSpace = index.data(DiskFreeSpaceRole).value() / 1024.0 / 1024.0; - usedSpace = index.data(DiskUsedSpaceRole).value() / 1024.0 / 1024.0; - } - - - // draw free space information (for drive icons) - if (usedSpace >= 0) { - painter->save(); - - QRect emptyRect = rectAfterTitle(option, index); - - QSize barSize = QSize(qMin(emptyRect.width(), option.rect.width() / 3), emptyRect.height()); - - if (barSize.width() > 0) { - // if the item view is gradually resized smaller or larger, make the bar fade out/in - // as enough space for it becomes available - if (barSize.width() < 20.0) { - painter->setOpacity(barSize.width() / 20.0); - } - - QRect spaceRect = QStyle::alignedRect(option.direction, - Qt::AlignRight, barSize, emptyRect); - - if (!(option.state & (QStyle::State_Selected | QStyle::State_MouseOver | QStyle::State_HasFocus))) { - painter->setOpacity(painter->opacity() / 2.5); - } else { - } - - KCapacityBar capacityBar(KCapacityBar::DrawTextInline); - capacityBar.setValue((usedSpace / (freeSpace + usedSpace))*100); - capacityBar.drawCapacityBar(painter, spaceRect); - - // -- Removed the free space text because it added too much 'visual noise' to the item - // - // some precision is lost here, but it is acceptible given that the disk-free bar - // is only shown as a guide - // QString freeSpaceString = KGlobal::locale()->formatByteSize(freeSpace*1024*1024*1024); - // painter->drawText(spaceRect,Qt::AlignCenter,i18n("%1 free",freeSpaceString)); - } - - painter->restore(); - } - -} - -bool ItemDelegate::isVisible(const QModelIndex& index) const -{ - if (!index.isValid()) return false; - - if (index.model()->hasChildren(index)) { - const int childCount = index.model()->rowCount(index); - for (int i = 0; i < childCount; ++i) { - QModelIndex child = index.model()->index(i, 0, index); - if (!child.data(UrlRole).isNull()) { - return true; - } - } - return false; - } - - return !index.data(UrlRole).isNull(); -} - diff --git a/plasma/applets/kickoff/ui/itemdelegate.h b/plasma/applets/kickoff/ui/itemdelegate.h deleted file mode 100644 index bf79e2cc..00000000 --- a/plasma/applets/kickoff/ui/itemdelegate.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef ITEMDELEGATE_H -#define ITEMDELEGATE_H - -// Qt -#include - -//Plasma -#include - -// Local -#include "core/models.h" - -namespace Kickoff -{ - -/** - * Item delegate for rendering items in the Kickoff launcher's views. - * - * The delegate makes use of the various additional Kickoff item data roles - * to draw the item. For example, if the DiskFreeSpaceRole and DiskUsedSpaceRole item - * data is valid then a bar chart showing the amount of free space available on the disk - * will be drawn. - */ -class ItemDelegate : public Plasma::Delegate , public ItemStateProvider -{ -public: - ItemDelegate(QObject *parent = 0); - virtual void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; - - // reimplemented from ItemStateProvider - virtual bool isVisible(const QModelIndex& index) const; - - static const int HEADER_LEFT_MARGIN = 5; - static const int HEADER_TOP_MARGIN = 15; - static const int HEADER_BOTTOM_MARGIN = 4; - static const int HEADER_HEIGHT = 35; - static const int FIRST_HEADER_HEIGHT = 20; - - static const int ITEM_LEFT_MARGIN = 12; - static const int ITEM_RIGHT_MARGIN = 7; - static const int TOP_OFFSET = 5; -}; - -} - -#endif // ITEMDELEGATE_H diff --git a/plasma/applets/kickoff/ui/launcher.cpp b/plasma/applets/kickoff/ui/launcher.cpp deleted file mode 100644 index ab26d183..00000000 --- a/plasma/applets/kickoff/ui/launcher.cpp +++ /dev/null @@ -1,1063 +0,0 @@ -/* - Copyright 2007 Robert Knight - Copyright 2007 Kevin Ottens - Copyright 2009 Ivan Cukic - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "ui/launcher.h" - -// Qt -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Local -#include "core/favoritesmodel.h" -#include "core/recentlyusedmodel.h" -#include "core/applicationmodel.h" -#include "core/leavemodel.h" -#include "core/itemhandlers.h" -//#include "core/searchmodel.h" -#include "core/krunnermodel.h" -#include "core/systemmodel.h" - -#include "ui/itemdelegate.h" -#include "ui/contextmenufactory.h" -#include "ui/urlitemview.h" -#include "ui/flipscrollview.h" -#include "ui/searchbar.h" -#include "ui/tabbar.h" -#include "ui/contentareacap.h" - -Q_DECLARE_METATYPE(QPersistentModelIndex) - -using namespace Kickoff; - -class Launcher::Private -{ -public: - Private(Launcher *launcher) - : q(launcher) - , applet(0) - , urlLauncher(new UrlItemLauncher(launcher)) - , searchModel(0) - , leaveModel(0) - , searchBar(0) - , footer(0) - , contentAreaHeader(0) - , contentArea(0) - , contentAreaFooter(0) - , contentSwitcher(0) - , applicationView(0) - , searchView(0) - , favoritesView(0) - , contextMenuFactory(0) - , autoHide(false) - , appViewIsReceivingKeyEvents(false) - , visibleItemCount(10) - , placement(Plasma::TopPosedLeftAlignedPopup) - , panelEdge(Plasma::BottomEdge) - { - } - - ~Private() - { - } - - enum TabOrder { NormalTabOrder, ReverseTabOrder }; - - void setupEventHandler(QAbstractItemView *view) - { - view->viewport()->installEventFilter(q); - view->installEventFilter(q); - } - - void addView(const QString& name, const QIcon& icon, - QAbstractItemModel *model = 0, QAbstractItemView *view = 0, - QWidget *headerWidget = 0) - { - view->setFrameStyle(QFrame::NoFrame); - // prevent the view from stealing focus from the search bar - view->setFocusPolicy(Qt::NoFocus); - view->setContextMenuPolicy(Qt::CustomContextMenu); - view->setSelectionMode(QAbstractItemView::SingleSelection); - view->setDragEnabled(true); - view->setAcceptDrops(true); - view->setDropIndicatorShown(true); - if (name == i18n("Favorites")) { - view->setDragDropMode(QAbstractItemView::DragDrop); - } else if(name == i18n("Applications") || name == i18n("Computer") || - name == i18n("Recently Used")) { - view->setDragDropMode(QAbstractItemView::DragOnly); - } - view->setModel(model); - //view->setCurrentIndex(QModelIndex()); - setupEventHandler(view); - - connect(view, SIGNAL(customContextMenuRequested(QPoint)), q, SLOT(showViewContextMenu(QPoint))); - - contentSwitcher->addTab(icon, name); - - if (!headerWidget) { - contentArea->addWidget(view); - } else { - QWidget *parent = new QWidget; - parent->setLayout(new QVBoxLayout); - parent->layout()->setSpacing(0); - parent->layout()->setContentsMargins(0, 0, 0, 0); - parent->layout()->addWidget(headerWidget); - parent->layout()->addWidget(view); - contentArea->addWidget(parent); - } - } - - void initTabs() - { - // Favorites view - setupFavoritesView(); - - // All Programs view - setupAllProgramsView(); - - // System view - setupSystemView(); - - // Recently Used view - setupRecentView(); - - // Leave view - setupLeaveView(); - - // Search Bar - setupSearchView(); - } - - void setupLeaveView() - { - leaveModel = new LeaveModel(q); - leaveModel->updateModel(); - UrlItemView *view = new UrlItemView(); - ItemDelegate *delegate = new ItemDelegate(q); - delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); - delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); - view->setItemDelegate(delegate); - view->setItemStateProvider(delegate); - addView(i18n("Leave"), KIcon("system-shutdown"), leaveModel, view); - } - - void setupFavoritesView() - { - favoritesModel = new FavoritesModel(q); - UrlItemView *view = new UrlItemView(); - ItemDelegate *delegate = new ItemDelegate(q); - delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); - delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); - view->setItemDelegate(delegate); - view->setItemStateProvider(delegate); - addView(i18n("Favorites"), KIcon("bookmarks"), favoritesModel, view); - - QAction *sortAscendingAction = new QAction(KIcon("view-sort-ascending"), - i18n("Sort Alphabetically (A to Z)"), q); - - QAction *sortDescendingAction = new QAction(KIcon("view-sort-descending"), - i18n("Sort Alphabetically (Z to A)"), q); - - connect(favoritesModel, SIGNAL(rowsInserted(QModelIndex,int,int)), q, SLOT(focusFavoritesView())); - connect(sortAscendingAction, SIGNAL(triggered()), favoritesModel, SLOT(sortFavoritesAscending())); - connect(sortDescendingAction, SIGNAL(triggered()), favoritesModel, SLOT(sortFavoritesDescending())); - - favoritesView = view; - QList actions; - actions << sortAscendingAction << sortDescendingAction; - contextMenuFactory->setViewActions(view, actions); - } - - void setupAllProgramsView() - { - applicationModel = new ApplicationModel(q); - applicationModel->setDuplicatePolicy(ApplicationModel::ShowLatestOnlyPolicy); - - FlipScrollView *view = new FlipScrollView(); - applicationView = view; - ItemDelegate *delegate = new ItemDelegate(q); - delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); - delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); - applicationView->setItemDelegate(delegate); - - applicationBreadcrumbs = new QWidget; - applicationBreadcrumbs->setMinimumHeight(ItemDelegate::HEADER_HEIGHT); - applicationBreadcrumbs->setLayout(new QHBoxLayout); - applicationBreadcrumbs->layout()->setContentsMargins(0, 0, 0, 0); - applicationBreadcrumbs->layout()->setSpacing(0); - - QPalette palette = applicationBreadcrumbs->palette(); - palette.setColor(QPalette::Window, palette.color(QPalette::Active, QPalette::Base)); - applicationBreadcrumbs->setPalette(palette); - applicationBreadcrumbs->setAutoFillBackground(true); - - connect(applicationView, SIGNAL(currentRootChanged(QModelIndex)), - q, SLOT(fillBreadcrumbs(QModelIndex))); - connect(applicationView, SIGNAL(focusNextViewLeft()), - q, SLOT(moveViewToLeft())); - - q->fillBreadcrumbs(QModelIndex()); - - addView(i18n("Applications"), KIcon("applications-other"), - applicationModel, applicationView, applicationBreadcrumbs); - } - - void setupRecentView() - { - recentlyUsedModel = new RecentlyUsedModel(q); - UrlItemView *view = new UrlItemView(); - ItemDelegate *delegate = new ItemDelegate(q); - delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); - delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); - view->setItemDelegate(delegate); - view->setItemStateProvider(delegate); - addView(i18n("Recently Used"), KIcon("document-open-recent"), recentlyUsedModel, view); - - QAction *clearApplications = new QAction(KIcon("edit-clear-history"), i18n("Clear Recent Applications"), q); - QAction *clearDocuments = new QAction(KIcon("edit-clear-history"), i18n("Clear Recent Documents"), q); - - connect(clearApplications, SIGNAL(triggered()), recentlyUsedModel, SLOT(clearRecentApplications())); - connect(clearDocuments, SIGNAL(triggered()), recentlyUsedModel, SLOT(clearRecentDocuments())); - - contextMenuFactory->setViewActions(view, QList() << clearApplications << clearDocuments); - } - - void setupSystemView() - { - systemModel = new SystemModel(q); - UrlItemView *view = new UrlItemView(); - ItemDelegate *delegate = new ItemDelegate(q); - delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); - delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); - view->setItemDelegate(delegate); - view->setItemStateProvider(delegate); - - addView(i18n("Computer"), systemIcon(), systemModel, view); - } - - void setupSearchView() - { - searchModel = new KRunnerModel(q); - UrlItemView *view = new UrlItemView(); - ItemDelegate *delegate = new ItemDelegate(q); - delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); - delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); - view->setItemDelegate(delegate); - view->setItemStateProvider(delegate); - - view->setModel(searchModel); - view->setFrameStyle(QFrame::NoFrame); - view->setSelectionMode(QAbstractItemView::SingleSelection); - // prevent view from stealing focus from the search bar - view->setFocusPolicy(Qt::StrongFocus); - view->setDragEnabled(true); - - setupEventHandler(view); - - connect(searchModel, SIGNAL(resultsAvailable()), q, SLOT(resultsAvailable())); - - connect(searchBar, SIGNAL(queryChanged(QString)), searchModel, SLOT(setQuery(QString))); - connect(searchBar, SIGNAL(queryChanged(QString)), q, SLOT(focusSearchView(QString))); - - view->setContextMenuPolicy(Qt::CustomContextMenu); - connect(view, SIGNAL(customContextMenuRequested(QPoint)), q, SLOT(showViewContextMenu(QPoint))); - - contentArea->addWidget(view); - searchView = view; - } - - void registerUrlHandlers() - { - UrlItemLauncher::addGlobalHandler(UrlItemLauncher::ExtensionHandler, "desktop", new ServiceItemHandler); - UrlItemLauncher::addGlobalHandler(UrlItemLauncher::ProtocolHandler, "leave", new LeaveItemHandler); - UrlItemLauncher::addGlobalHandler(UrlItemLauncher::ProtocolHandler, "krunner", new KRunnerItemHandler); - } - - QIcon systemIcon() - { - QList batteryList = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString()); - - if (batteryList.isEmpty()) { - return KIcon("computer"); - } else { - return KIcon("computer-laptop"); - } - } - - void setNorthLayout(TabOrder tabOrder) - { - contentSwitcher->setShape(QTabBar::RoundedNorth); - QLayout * layout = q->layout(); - delete layout; - layout = new QVBoxLayout(); - layout->addWidget(contentSwitcher); - layout->addWidget(contentAreaHeader); - layout->addWidget(contentArea); - layout->addWidget(contentAreaFooter); - layout->addWidget(searchBar); - layout->addWidget(footer); - layout->setSpacing(0); - layout->setMargin(0); - q->setLayout(layout); - setTabOrder(tabOrder); - } - - void setSouthLayout(TabOrder tabOrder) - { - contentSwitcher->setShape(QTabBar::RoundedSouth); - QLayout * layout = q->layout(); - delete layout; - layout = new QVBoxLayout(); - layout->addWidget(footer); - layout->addWidget(searchBar); - layout->addWidget(contentAreaHeader); - layout->addWidget(contentArea); - layout->addWidget(contentAreaFooter); - layout->addWidget(contentSwitcher); - layout->setSpacing(0); - layout->setMargin(0); - q->setLayout(layout); - setTabOrder(tabOrder); - } - - void setWestLayout(TabOrder tabOrder) - { - contentSwitcher->setShape(QTabBar::RoundedWest); - QLayout * layout = q->layout(); - delete layout; - layout = new QHBoxLayout(); - layout->addWidget(contentSwitcher); - - QBoxLayout * contentLayout = new QVBoxLayout(); - contentLayout->addWidget(contentAreaHeader); - contentLayout->addWidget(contentArea); - contentLayout->addWidget(contentAreaFooter); - - layout->addItem(contentLayout); - - QBoxLayout * layout2 = new QVBoxLayout(); - if (tabOrder == NormalTabOrder) { - layout2->addLayout(layout); - layout2->addWidget(searchBar); - layout2->addWidget(footer); - } else { - layout2->addWidget(footer); - layout2->addWidget(searchBar); - layout2->addLayout(layout); - } - layout->setSpacing(0); - layout->setMargin(0); - layout2->setSpacing(0); - layout2->setMargin(0); - q->setLayout(layout2); - setTabOrder(tabOrder); - } - - void setEastLayout(TabOrder tabOrder) - { - contentSwitcher->setShape(QTabBar::RoundedEast); - QLayout * layout = q->layout(); - delete layout; - layout = new QHBoxLayout(); - - QBoxLayout * contentLayout = new QVBoxLayout(); - contentLayout->addWidget(contentAreaHeader); - contentLayout->addWidget(contentArea); - contentLayout->addWidget(contentAreaFooter); - - layout->addItem(contentLayout); - - layout->addWidget(contentSwitcher); - QBoxLayout * layout2 = new QVBoxLayout(); - if (tabOrder == NormalTabOrder) { - layout2->addLayout(layout); - layout2->addWidget(searchBar); - layout2->addWidget(footer); - } else { - layout2->addWidget(footer); - layout2->addWidget(searchBar); - layout2->addLayout(layout); - } - layout->setSpacing(0); - layout->setMargin(0); - layout2->setSpacing(0); - layout2->setMargin(0); - q->setLayout(layout2); - setTabOrder(tabOrder); - } - - void setTabOrder(TabOrder newOrder) - { - // identify current TabOrder, assumes favoritesView is first in normal order - TabOrder oldOrder; - if (contentArea->widget(0) == favoritesView) { - oldOrder = NormalTabOrder; - } else { - oldOrder = ReverseTabOrder; - } - if (newOrder == oldOrder) { - return; - } - // remove the and widgets and store their data in a separate structure - // remove this first so we can cleanly remove the widgets controlled by contentSwitcher - contentArea->removeWidget(searchView); - Q_ASSERT(contentArea->count() == contentSwitcher->count()); - - QList removedTabs; - for (int i = contentSwitcher->count() - 1; i >= 0 ; i--) { - WidgetTabData wtd; - wtd.tabText = contentSwitcher->tabText(i); - wtd.tabToolTip = contentSwitcher->tabToolTip(i); - wtd.tabWhatsThis = contentSwitcher->tabWhatsThis(i); - wtd.tabIcon = contentSwitcher->tabIcon(i); - wtd.widget = contentArea->widget(i); - removedTabs.append(wtd); - - contentSwitcher->removeTab(i); - contentArea->removeWidget(contentArea->widget(i)); - } - // then reinsert them in reversed order - int i = 0; - foreach(const WidgetTabData &wtd, removedTabs) { - contentSwitcher->addTab(wtd.tabIcon, wtd.tabText); - contentSwitcher->setTabToolTip(i, wtd.tabToolTip); - contentSwitcher->setTabWhatsThis(i, wtd.tabWhatsThis); - contentArea->addWidget(wtd.widget); - ++i; - } - //finally replace the searchView - contentArea->addWidget(searchView); - } - - struct WidgetTabData { - QString tabText; - QString tabToolTip; - QString tabWhatsThis; - QIcon tabIcon; - QWidget *widget; - }; - - Launcher * const q; - Plasma::Applet *applet; - UrlItemLauncher *urlLauncher; - FavoritesModel *favoritesModel; - ApplicationModel *applicationModel; - RecentlyUsedModel *recentlyUsedModel; - KRunnerModel *searchModel; - SystemModel *systemModel; - LeaveModel *leaveModel; - SearchBar *searchBar; - QWidget *footer; - QLabel *userinfo; - ContentAreaCap *contentAreaHeader; - QStackedWidget *contentArea; - ContentAreaCap *contentAreaFooter; - TabBar *contentSwitcher; - FlipScrollView *applicationView; - QWidget *applicationBreadcrumbs; - UrlItemView *searchView; - QAbstractItemView *favoritesView; - ContextMenuFactory *contextMenuFactory; - bool autoHide; - bool appViewIsReceivingKeyEvents; - int visibleItemCount; - Plasma::PopupPlacement placement; - Plasma::Location panelEdge; -}; - -Launcher::Launcher(QWidget *parent) - : QWidget(parent, Qt::Window) - , d(new Private(this)) -{ - init(); -} - -Launcher::Launcher(Plasma::Applet *applet) - : QWidget(0, Qt::Window) - , d(new Private(this)) -{ - init(); - setApplet(applet); -} - -void Launcher::init() -{ - QVBoxLayout *layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setMargin(0); - - const int rightHeaderMargin = style()->pixelMetric(QStyle::PM_ScrollBarExtent); - - d->searchBar = new SearchBar(this); - if (layoutDirection() == Qt::LeftToRight) { - d->searchBar->setContentsMargins(0, 0, rightHeaderMargin, 0); - } else { - d->searchBar->setContentsMargins(rightHeaderMargin, 0, 0, 0); - } - d->searchBar->installEventFilter(this); - d->contentAreaHeader = new ContentAreaCap(this); - d->contentArea = new QStackedWidget(this); - bool flipCap = true; - d->contentAreaFooter = new ContentAreaCap(this, flipCap); - d->contentSwitcher = new TabBar(this); - d->contentSwitcher->installEventFilter(this); - d->contentSwitcher->setIconSize(QSize(48, 48)); - d->contentSwitcher->setShape(QTabBar::RoundedSouth); - connect(d->contentSwitcher, SIGNAL(currentChanged(int)), - d->contentArea, SLOT(setCurrentIndex(int))); - d->contextMenuFactory = new ContextMenuFactory(this); - - d->initTabs(); - d->registerUrlHandlers(); - - // Add status information footer - d->footer = new QWidget; - - const QString hostname = QHostInfo::localHostName(); - KUser user; - QString fullName = user.property(KUser::FullName); - QString labelText; - if (fullName.isEmpty()) { - labelText = i18nc("login name, hostname", "User %1 on %2", user.loginName(), hostname); - } else { - labelText = i18nc("full name, login name, hostname", "%1 (%2) on %3", fullName, user.loginName(), hostname); - } - - d->userinfo = new QLabel(labelText); - - QHBoxLayout *brandingLayout = new QHBoxLayout; - brandingLayout->setMargin(3); - brandingLayout->addSpacing(ItemDelegate::ITEM_LEFT_MARGIN - 3); - brandingLayout->addWidget(d->userinfo); - brandingLayout->addStretch(2); - brandingLayout->addSpacing(rightHeaderMargin); - d->footer->setLayout(brandingLayout); - - layout->addWidget(d->footer); - layout->addWidget(d->searchBar); - layout->addWidget(d->contentAreaHeader); - layout->addWidget(d->contentArea); - layout->addWidget(d->contentAreaFooter); - layout->addWidget(d->contentSwitcher); - - setLayout(layout); - setAttribute(Qt::WA_TranslucentBackground); - //setBackgroundRole(QPalette::AlternateBase); - //setAutoFillBackground(true); - - updateThemedPalette(); - connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), - this, SLOT(updateThemedPalette())); - - setAppViewIsReceivingKeyEvents(false); // Left/Right arrow keys are delivered elsewhere (for now) -} - -void Launcher::updateThemedPalette() -{ - QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); - QPalette p = d->userinfo->palette(); - p.setColor(QPalette::Normal, QPalette::WindowText, color); - p.setColor(QPalette::Inactive, QPalette::WindowText, color); - d->userinfo->setPalette(p); -} - -QSize Launcher::minimumSizeHint() const -{ - QSize size; - - switch (d->panelEdge) { - case Plasma::LeftEdge: - case Plasma::RightEdge: - size.rheight() = d->searchBar->sizeHint().height() + - d->footer->sizeHint().height() + - qMax(d->favoritesView->sizeHintForRow(0) * 3 + ItemDelegate::HEADER_HEIGHT, d->contentSwitcher->sizeHint().height()); - size.rwidth() = d->contentSwitcher->sizeHint().width() + d->favoritesView->sizeHint().width(); - break; - case Plasma::TopEdge: - case Plasma::BottomEdge: - default: - size.rheight() = d->searchBar->sizeHint().height() + - d->contentSwitcher->sizeHint().height() + d->footer->sizeHint().height() + - d->favoritesView->sizeHintForRow(0) * 3 + ItemDelegate::HEADER_HEIGHT; - size.rwidth() = d->contentSwitcher->sizeHint().width(); - break; - } - - return size; -} - -QSize Launcher::sizeHint() const -{ - return QSize(minimumSizeHint().width(), 500); -} - -void Launcher::setAutoHide(bool hide) -{ - d->autoHide = hide; -} - -bool Launcher::autoHide() const -{ - return d->autoHide; -} - -void Launcher::setSwitchTabsOnHover(bool switchOnHover) -{ - if (d->applet && switchOnHover != d->contentSwitcher->switchTabsOnHover()) { - KConfigGroup cg = d->applet->globalConfig(); - cg.writeEntry("SwitchTabsOnHover", switchOnHover); - emit configNeedsSaving(); - } - - d->contentSwitcher->setSwitchTabsOnHover(switchOnHover); -} - -void Launcher::setShowAppsByName(bool showAppsByName) -{ - //ApplicationModel *m_applicationModel = applicationModel; - const bool wasByName = d->applicationModel->nameDisplayOrder() == Kickoff::NameBeforeDescription; - if (d->applet && showAppsByName != wasByName) { - KConfigGroup cg = d->applet->config(); - cg.writeEntry("ShowAppsByName", showAppsByName); - emit configNeedsSaving(); - } - - if (showAppsByName) { - d->applicationModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - d->applicationModel->setPrimaryNamePolicy(Kickoff::ApplicationModel::AppNamePrimary); - d->recentlyUsedModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - d->favoritesModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - d->searchModel->setNameDisplayOrder(Kickoff::NameBeforeDescription); - } else { - d->applicationModel->setNameDisplayOrder(Kickoff::NameAfterDescription); - d->applicationModel->setPrimaryNamePolicy(Kickoff::ApplicationModel::GenericNamePrimary); - d->recentlyUsedModel->setNameDisplayOrder(Kickoff::NameAfterDescription); - d->favoritesModel->setNameDisplayOrder(Kickoff::NameAfterDescription); - d->searchModel->setNameDisplayOrder(Kickoff::NameAfterDescription); - } -} - -void Launcher::setShowRecentlyInstalled(bool showRecentlyInstalled) -{ - const bool wasShowRecentlyInstalled = d->applicationModel->showRecentlyInstalled(); - if (d->applet && showRecentlyInstalled != wasShowRecentlyInstalled) { - KConfigGroup cg = d->applet->config(); - cg.writeEntry("ShowRecentlyInstalled", showRecentlyInstalled); - emit configNeedsSaving(); - } - - d->applicationModel->setShowRecentlyInstalled(showRecentlyInstalled); -} - -bool Launcher::switchTabsOnHover() const -{ - return d->contentSwitcher->switchTabsOnHover(); -} - -bool Launcher::showAppsByName() const -{ - return d->applicationModel->nameDisplayOrder() == Kickoff::NameBeforeDescription; -} - -bool Launcher::showRecentlyInstalled() const -{ - return d->applicationModel->showRecentlyInstalled(); -} - -void Launcher::setVisibleItemCount(int count) -{ - d->visibleItemCount = count; -} - -int Launcher::visibleItemCount() const -{ - return d->visibleItemCount; -} - -void Launcher::setAppViewIsReceivingKeyEvents(bool isReceiving) -{ - d->appViewIsReceivingKeyEvents = isReceiving; -} - -bool Launcher::appViewIsReceivingKeyEvents() const -{ - return d->appViewIsReceivingKeyEvents; -} - -void Launcher::setApplet(Plasma::Applet *applet) -{ - KConfigGroup cg = applet->globalConfig(); - setSwitchTabsOnHover(cg.readEntry("SwitchTabsOnHover", switchTabsOnHover())); - - cg = applet->config(); - setShowAppsByName(cg.readEntry("ShowAppsByName", showAppsByName())); - setVisibleItemCount(cg.readEntry("VisibleItemsCount", visibleItemCount())); - setShowRecentlyInstalled(cg.readEntry("ShowRecentlyInstalled", showRecentlyInstalled())); - - d->applet = applet; - d->contextMenuFactory->setApplet(applet); - d->applicationModel->setApplet(applet); -} - -void Launcher::reset() -{ - d->contentSwitcher->setCurrentIndexWithoutAnimation(d->contentArea->indexOf(d->favoritesView)); - d->contentArea->setCurrentWidget(d->favoritesView); - d->searchBar->clear(); - d->applicationView->viewRoot(); - d->leaveModel->updateModel(); -} - -Launcher::~Launcher() -{ - delete d; -} - -void Launcher::focusSearchView(const QString& query) -{ - bool queryEmpty = query.isEmpty(); - - d->contentSwitcher->setVisible(queryEmpty); - - if (!queryEmpty) { - d->contentArea->setCurrentWidget(d->searchView); - } else { - focusFavoritesView(); - } -} - -void Launcher::focusFavoritesView() -{ - d->contentSwitcher->setCurrentIndex(d->contentArea->indexOf(d->favoritesView)); - d->contentArea->setCurrentWidget(d->favoritesView); - d->contentSwitcher->setVisible(true); - d->searchBar->clear(); - setAppViewIsReceivingKeyEvents(false); -} - -void Launcher::moveViewToLeft() -{ - d->contentSwitcher->setCurrentIndex(d->contentArea->indexOf(d->favoritesView)); - d->contentArea->setCurrentWidget(d->favoritesView); - d->contentSwitcher->setVisible(true); - d->searchBar->clear(); - setAppViewIsReceivingKeyEvents(false); - -} - -bool Launcher::eventFilter(QObject *object, QEvent *event) -{ - // deliver unhandled key presses from the search bar - // (mainly arrow keys, enter) to the active view - - if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - - if ((object == d->contentSwitcher || object == d->searchBar)) { - - // left/right should Nav the tabbar, unless ApplicationView is receiving them. - if (keyEvent->modifiers() == Qt::NoModifier && - (keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right)) { - kDebug() << "launcher, at filter #2"; - if (d->applicationView->isVisible() && appViewIsReceivingKeyEvents()) { - QCoreApplication::sendEvent(d->applicationView, event); - return true; - } - if (object == d->contentSwitcher) { - return false; - } else { - QCoreApplication::sendEvent(d->contentSwitcher, event); - return true; - } - } - - // Next: Up/Down should ALWAYS go into the ApplicationView, if it is visible. - if (keyEvent->modifiers() == Qt::NoModifier && - (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)) { - kDebug() << "launcher, at filter #3A"; - if (d->applicationView->isVisible()) { - kDebug() << "launcher, at filter #3B"; - setAppViewIsReceivingKeyEvents(true); - QCoreApplication::sendEvent(d->applicationView, event); - return true; - } - } - - // Third: Up/Down, Key_Enter, and Key_Return must be explicitly sent into the ApplicationView., if it is receiving Keys - if (keyEvent->key() == Qt::Key_Up || - keyEvent->key() == Qt::Key_Down || - keyEvent->key() == Qt::Key_Enter || - keyEvent->key() == Qt::Key_Return) { - kDebug() << "launcher, at filter #3"; - if (d->applicationView->isVisible()) { - if (appViewIsReceivingKeyEvents()) { - QCoreApplication::sendEvent(d->applicationView, event); - return true; - } - } - } - - // if the search view is visible, we are passing the events to it - if (d->searchView->isVisible()) { - if (!d->searchView->initializeSelection() - || keyEvent->key() == Qt::Key_Return - || keyEvent->key() == Qt::Key_Enter) { - kDebug() << "Passing the event to the search view" << event; - QCoreApplication::sendEvent(d->searchView, event); - } - return true; - } - - // getting for the active view, and passing the events to it - QAbstractItemView *activeView = qobject_cast(d->contentArea->currentWidget()); - - if (activeView) { - QCoreApplication::sendEvent(activeView, event); - return true; - } - } - } - - // the mouse events we are interested in are delivered to the viewport, - // other events are delivered to the view itself. - QAbstractItemView *view = qobject_cast(object); - if (!view) { - view = qobject_cast(object->parent()); - } - - if (view) { - QModelIndex openIndex; - if (event->type() == QEvent::MouseButtonRelease) { - QMouseEvent *mouseEvent = (QMouseEvent*)event; - const QModelIndex index = view->indexAt(mouseEvent->pos()); - if (index.isValid() && - index.model()->hasChildren(index) == false && - mouseEvent->button() == Qt::LeftButton) { - openIndex = index; - } - } else if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = (QKeyEvent*)event; - const QModelIndex index = view->currentIndex(); - if (index.isValid() && index.model()->hasChildren(index) == false && - (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return)) { - openIndex = index; - } - } - if (openIndex.isValid()) { - d->urlLauncher->openItem(openIndex); - // Clear the search bar when enter was pressed - if (event->type() == QEvent::KeyPress) { - d->searchBar->clear(); - } - if (d->autoHide) { - emit aboutToHide(); - } - return true; - } - } - return QWidget::eventFilter(object, event); -} - -void Launcher::showViewContextMenu(const QPoint& pos) -{ - QAbstractItemView *view = qobject_cast(sender()); - if (view) { - const QModelIndex index = view->indexAt(pos); - d->contextMenuFactory->showContextMenu(view, index, pos); - } -} - -void Launcher::hideEvent(QHideEvent *event) -{ - Q_UNUSED(event) - reset(); - d->systemModel->stopRefreshingUsageInfo(); -} - -void Launcher::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Escape) { - emit aboutToHide(); - } -#if 0 - // allow tab switching by pressing the left or right arrow keys - if (event->key() == Qt::Key_Left && d->contentSwitcher->currentIndex() > 0) { - d->contentSwitcher->setCurrentIndex(d->contentSwitcher->currentIndex() - 1); - } else if (event->key() == Qt::Key_Right && - d->contentSwitcher->currentIndex() < d->contentSwitcher->count() - 1) { - d->contentSwitcher->setCurrentIndex(d->contentSwitcher->currentIndex() + 1); - } -#endif -} - -void Launcher::showEvent(QShowEvent *e) -{ - d->searchBar->setFocus(); - d->systemModel->refreshUsageInfo(); - - QWidget::showEvent(e); -} - -void Launcher::resultsAvailable() -{ - const QModelIndex root = d->searchModel->index(0, 0); - d->searchView->setCurrentIndex(d->searchModel->index(0, 0, root)); -} - -void Launcher::setLauncherOrigin(const Plasma::PopupPlacement placement, Plasma::Location location) -{ - if (d->placement != placement) { - d->placement = placement; - - Private::TabOrder normalOrder; - Private::TabOrder reverseOrder; - - //QTabBar attempts to be smart and flips what we say in rtl mode so say the opposite when the tabbar is horizontal - if (QApplication::layoutDirection() == Qt::RightToLeft) { - normalOrder = Private::ReverseTabOrder; - reverseOrder = Private::NormalTabOrder; - } else { - normalOrder = Private::NormalTabOrder; - reverseOrder = Private::ReverseTabOrder; - } - - switch (placement) { - case Plasma::TopPosedRightAlignedPopup: - d->setSouthLayout(reverseOrder); - break; - case Plasma::LeftPosedTopAlignedPopup: - //when the tabbar is vertical it's fine - d->setEastLayout(Private::NormalTabOrder); - break; - case Plasma::LeftPosedBottomAlignedPopup: - d->setEastLayout(Private::ReverseTabOrder); - break; - case Plasma::BottomPosedLeftAlignedPopup: - d->setNorthLayout(normalOrder); - break; - case Plasma::BottomPosedRightAlignedPopup: - d->setNorthLayout(reverseOrder); - break; - case Plasma::RightPosedTopAlignedPopup: - d->setWestLayout(Private::NormalTabOrder); - break; - case Plasma::RightPosedBottomAlignedPopup: - d->setWestLayout(Private::ReverseTabOrder); - break; - case Plasma::TopPosedLeftAlignedPopup: - default: - d->setSouthLayout(normalOrder); - break; - } - } - - d->panelEdge = location; - reset(); -} - -void Launcher::fillBreadcrumbs(const QModelIndex &index) -{ - QList children = d->applicationBreadcrumbs->findChildren(); - foreach (QWidget *child, children) { - child->setParent(0); - child->hide(); - child->deleteLater(); - } - - QHBoxLayout *layout = static_cast(d->applicationBreadcrumbs->layout()); - while (layout->count() > 0) { - delete layout->takeAt(0); - } - - layout->addStretch(10); - - QModelIndex current = index; - while (current.isValid()) { - addBreadcrumb(current, current == index); - current = current.parent(); - } - - // show a '>' only if the index is valid, and therefore All Applications is not alone up there - addBreadcrumb(QModelIndex(), !index.isValid()); -} - -void Launcher::addBreadcrumb(const QModelIndex &index, bool isLeaf) -{ - QPushButton *button = new QPushButton(d->applicationBreadcrumbs); - button->setFont(KGlobalSettings::smallestReadableFont()); - button->setFlat(true); - button->setStyleSheet("* { padding: 4 }"); - button->setCursor(Qt::PointingHandCursor); - - QPalette palette = button->palette(); - palette.setColor(QPalette::ButtonText, palette.color(QPalette::Disabled, QPalette::ButtonText)); - button->setPalette(palette); - - QString suffix; - if (isLeaf) { - button->setEnabled(false); - } else { - suffix = " >"; - } - - if (index.isValid()) { - button->setText(index.data().toString()+suffix); - } else { - button->setText(i18n("All Applications")+suffix); - } - - QVariant data = QVariant::fromValue(QPersistentModelIndex(index)); - button->setProperty("applicationIndex", data); - connect(button, SIGNAL(clicked()), - this, SLOT(breadcrumbActivated())); - - QHBoxLayout *layout = static_cast(d->applicationBreadcrumbs->layout()); - layout->insertWidget(1, button); -} - -void Launcher::breadcrumbActivated() -{ - QPushButton *button = static_cast(sender()); - QModelIndex index = button->property("applicationIndex").value(); - d->applicationView->setCurrentRoot(index); -} - -#include "moc_launcher.cpp" - diff --git a/plasma/applets/kickoff/ui/launcher.h b/plasma/applets/kickoff/ui/launcher.h deleted file mode 100644 index 7fd8b45f..00000000 --- a/plasma/applets/kickoff/ui/launcher.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef LAUNCHER_H -#define LAUNCHER_H - -// Qt -#include -#include - -// Plasma -#include - -namespace Kickoff -{ - -/** - * The main window class for the Kickoff launcher. This class is responsible - * for creating the various tabs, views and models which make up the launcher's - * user interface. - */ -class Launcher : public QWidget -{ - Q_OBJECT - -public: - /** Construct a new Launcher with the specified parent. */ - explicit Launcher(QWidget *parent = 0); - /** Construct a new Launcher associated with the specified Plasma::Applet. */ - explicit Launcher(Plasma::Applet *applet = 0); - ~Launcher(); - - /** Specifies whether the launcher should hide itself when an item is activated. */ - void setAutoHide(bool autoHide); - bool autoHide() const; - - /** Specifies whether the application names in the launcher should be displayed * - before or after the description */ - void setShowAppsByName(bool showAppByName); - bool showAppsByName() const; - - /** Specifies whether hovering switches between tabs or if a click is required to switch the tabs. */ - void setSwitchTabsOnHover(bool switchOnHover); - bool switchTabsOnHover() const; - - /** Specifies the number of visible items used to determinate the visible height. */ - void setVisibleItemCount(int count); - int visibleItemCount() const; - - /** Specifies the plasma applet the launcher is working on. */ - void setApplet(Plasma::Applet *applet); - - /** Specifies the direction the launcher is popping up in relative to its icon */ - void setLauncherOrigin(const Plasma::PopupPlacement placement, Plasma::Location location); - void setAppViewIsReceivingKeyEvents(bool isReceiving); - bool appViewIsReceivingKeyEvents() const; - // reimplemented - virtual bool eventFilter(QObject *object, QEvent *event); - virtual QSize minimumSizeHint() const; - virtual QSize sizeHint() const; - - /** Reset the launcher. This is called e.g. by the Kickoff-applet before shown to be sure - we don't display old searches and switch back to the favorite-view. */ - void reset(); - - /** Specifies whether 'Recently Installed' hierarchy shall be shown in application view */ - void setShowRecentlyInstalled(bool showRecentlyInstalled); - bool showRecentlyInstalled() const; - -signals: - void aboutToHide(); - void configNeedsSaving(); - -protected: - virtual void keyPressEvent(QKeyEvent *event); - virtual void showEvent(QShowEvent *event); - virtual void hideEvent(QHideEvent *event); - -private Q_SLOTS: - void focusSearchView(const QString& query); - void showViewContextMenu(const QPoint& pos); - void focusFavoritesView(); - void resultsAvailable(); - void updateThemedPalette(); - void fillBreadcrumbs(const QModelIndex &index); - void breadcrumbActivated(); - void moveViewToLeft(); - -private: - void addBreadcrumb(const QModelIndex &index, bool isLeaf); - void init(); - - class Private; - Private * const d; -}; - -} - -#endif // LAUNCHER_H diff --git a/plasma/applets/kickoff/ui/searchbar.cpp b/plasma/applets/kickoff/ui/searchbar.cpp deleted file mode 100644 index 4ca62150..00000000 --- a/plasma/applets/kickoff/ui/searchbar.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "ui/searchbar.h" -#include "ui/itemdelegate.h" - -// Katie -#include -#include -#include -#include -#include -#include -#include - -// KDE -#include -#include -#include - -//Plasma -#include - -using namespace Kickoff; - -class SearchBar::Private -{ -public: - Private() : editWidget(0), timer(0) {} - - KLineEdit *editWidget; - QLabel *searchLabel; - QTimer *timer; -}; - -SearchBar::SearchBar(QWidget *parent) - : QWidget(parent) - , d(new Private) -{ - // timer for buffered updates - d->timer = new QTimer(this); - d->timer->setInterval(300); - d->timer->setSingleShot(true); - connect(d->timer, SIGNAL(timeout()), this, SLOT(updateTimerExpired())); - connect(this, SIGNAL(startUpdateTimer()), d->timer, SLOT(start())); - - // setup UI - QHBoxLayout *layout = new QHBoxLayout; - layout->setMargin(3); - layout->setSpacing(0); // we do the spacing manually to line up with the views below - - d->searchLabel = new QLabel(i18nc("Label of the search bar textedit", "Search:"), this); - QLabel *searchIcon = new QLabel(this); - - const QFileInfo fi(QDir(QDir::homePath()), ".face.icon"); - if (fi.exists()) { - searchIcon->setPixmap(QPixmap(fi.absoluteFilePath()).scaled(KIconLoader::SizeMedium, KIconLoader::SizeMedium, Qt::KeepAspectRatio)); - } else { - searchIcon->setPixmap(KIcon("system-search").pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium)); - } - - d->editWidget = new KLineEdit(this); - d->editWidget->installEventFilter(this); - d->editWidget->setClearButtonShown(true); - connect(d->editWidget, SIGNAL(textChanged(QString)), this, SIGNAL(startUpdateTimer())); - - //add arbitrary spacing - layout->addSpacing(2); - layout->addWidget(searchIcon); - layout->addSpacing(5); - layout->addWidget(d->searchLabel); - layout->addSpacing(5); - layout->addWidget(d->editWidget); - setLayout(layout); - - setFocusProxy(d->editWidget); - - updateThemedPalette(); - connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), - this, SLOT(updateThemedPalette())); -} - -void SearchBar::updateThemedPalette() -{ - QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); - QPalette p = d->searchLabel->palette(); - p.setColor(QPalette::Normal, QPalette::WindowText, color); - p.setColor(QPalette::Inactive, QPalette::WindowText, color); - d->searchLabel->setPalette(p); -} - -void SearchBar::updateTimerExpired() -{ - emit queryChanged(d->editWidget->text()); -} - -SearchBar::~SearchBar() -{ - delete d; -} - -bool SearchBar::eventFilter(QObject *watched, QEvent *event) -{ - if (watched == d->editWidget && event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - - // Left and right arrow key presses in the search edit when the - // edit is empty are propagated up to the 'launcher'. This allows - // the launcher to navigate among views (switch among the Tabs) - //while the search bar still has the focus. - if ((keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right) && - d->editWidget->text().isEmpty()) { - QCoreApplication::sendEvent(this, event); - return true; - } - // Up and Down arrows, as well as Tab, propagate up to 'launcher'. - // It will recognize them as a request to enter the currently-visible Tab View. - if (keyEvent->key() == Qt::Key_Down || - keyEvent->key() == Qt::Key_Up || - keyEvent->key() == Qt::Key_Tab) { - QCoreApplication::sendEvent(this, event); - return true; - } - } - return false; -} - -void SearchBar::clear() -{ - d->editWidget->clear(); -} - -#include "moc_searchbar.cpp" diff --git a/plasma/applets/kickoff/ui/searchbar.h b/plasma/applets/kickoff/ui/searchbar.h deleted file mode 100644 index 60aa9b4b..00000000 --- a/plasma/applets/kickoff/ui/searchbar.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SEARCHBAR_H -#define SEARCHBAR_H - -// Qt -#include - -namespace Kickoff -{ - -class SearchBar : public QWidget -{ - Q_OBJECT - -public: - SearchBar(QWidget *parent); - virtual ~SearchBar(); - - bool eventFilter(QObject *watched, QEvent *event); - void clear(); - -Q_SIGNALS: - void queryChanged(const QString& newQuery); - - // internal - void startUpdateTimer(); - -private Q_SLOTS: - void updateTimerExpired(); - void updateThemedPalette(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // SEARCHBAR_H - diff --git a/plasma/applets/kickoff/ui/tabbar.cpp b/plasma/applets/kickoff/ui/tabbar.cpp deleted file mode 100644 index ae0aa7f4..00000000 --- a/plasma/applets/kickoff/ui/tabbar.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "ui/tabbar.h" - -// KDE -#include -#include - -// Qt -#include -#include -#include -#include -#include - -#include -#include -#include - - -using namespace Kickoff; - -TabBar::TabBar(QWidget *parent) - : KTabBar(parent), - m_hoveredTabIndex(-1), - m_switchOnHover(true), - m_animateSwitch(true), - m_animProgress(1.0) -{ - m_lastIndex[0] = -1; - connect(this, SIGNAL(currentChanged(int)), this, SLOT(startAnimation())); - - m_tabSwitchTimer.setSingleShot(true); - connect(&m_tabSwitchTimer, SIGNAL(timeout()), this, SLOT(switchToHoveredTab())); - setAcceptDrops(true); - setMouseTracking(true); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - setUsesScrollButtons(false); - - background = new Plasma::FrameSvg(this); - background->setImagePath("dialogs/kickoff"); - background->setEnabledBorders( - Plasma::FrameSvg::BottomBorder | - Plasma::FrameSvg::LeftBorder | - Plasma::FrameSvg::RightBorder - ); - background->resizeFrame(size()); - background->setElementPrefix("plain"); - - connect(background, SIGNAL(repaintNeeded()), this, SLOT(update())); -} - -void TabBar::setShape(Shape shape) -{ - resize(0, 0); // This is required, so that the custom implementation of tabSizeHint, - // which expands the tabs to the full width of the widget does not pick up - // the previous width, e.g. if the panel is moved from the bottom to the left - KTabBar::setShape(shape); - resize(sizeHint()); -} - -void TabBar::setCurrentIndexWithoutAnimation(int index) -{ - disconnect(this, SIGNAL(currentChanged(int)), this, SLOT(startAnimation())); - setCurrentIndex(index); - storeLastIndex(); - connect(this, SIGNAL(currentChanged(int)), this, SLOT(startAnimation())); - animationFinished(); -} - -void TabBar::setSwitchTabsOnHover(bool switchOnHover) -{ - m_switchOnHover = switchOnHover; -} - -bool TabBar::switchTabsOnHover() const -{ - return m_switchOnHover; -} - -void TabBar::setAnimateSwitch(bool animateSwitch) -{ - m_animateSwitch = animateSwitch; -} - -bool TabBar::animateSwitch() const -{ - return m_animateSwitch; -} - -QSize TabBar::tabSize(int index) const -{ - QSize hint; - const QFontMetrics metrics(KGlobalSettings::smallestReadableFont()); - const QSize textSize = metrics.size(Qt::TextHideMnemonic, tabText(index)); - hint.rwidth() = qMax(iconSize().width(), textSize.width()); - hint.rheight() = iconSize().height() + textSize.height(); - hint.rwidth() += 4 * TAB_CONTENTS_MARGIN; - hint.rheight() += 2 * TAB_CONTENTS_MARGIN; - return hint; -} - -void TabBar::storeLastIndex() -{ - // if first run - if (m_lastIndex[0] == -1) { - m_lastIndex[1] = currentIndex(); - } - m_lastIndex[0] = m_lastIndex[1]; - m_lastIndex[1] = currentIndex(); -} - -int TabBar::lastIndex() const -{ - return m_lastIndex[0]; -} - -QSize TabBar::tabSizeHint(int index) const -{ - QSize hint = tabSize(index); - int minwidth = 0; - int minheight = 0; - - Shape s = shape(); - switch (s) { - case RoundedSouth: - case TriangularSouth: - case RoundedNorth: - case TriangularNorth: - if (count() > 0) { - for (int i = count() - 1; i >= 0; i--) { - minwidth += tabSize(i).width(); - } - if (minwidth < width()) { - hint.rwidth() += (width() - minwidth) / count(); - } - } - break; - case RoundedWest: - case TriangularWest: - case RoundedEast: - case TriangularEast: - if (count() > 0) { - for (int i = count() - 1; i >= 0; i--) { - minheight += tabSize(i).height(); - } - if (minheight < height()) { - hint.rheight() += (height() - minheight) / count(); - } - } - hint.rwidth() = qMax(hint.width(), width()); - break; - } - return hint; -} - -QSize TabBar::sizeHint() const -{ - int width = 0; - int height = 0; - - if (isVertical()) { - for (int i = count() - 1; i >= 0; i--) { - height += tabSize(i).height(); - } - - width = tabSize(0).width(); - } else { - for (int i = count() - 1; i >= 0; i--) { - width += tabSize(i).width(); - } - - height = tabSize(0).height(); - } - return QSize(width, height); -} - -QPainterPath TabBar::tabPath(const QRectF &_r) -{ - const qreal radius = 6; - Shape s = shape(); - QPainterPath path; - QRectF r = _r; - - switch (s) { - case RoundedSouth: - case TriangularSouth: - r.adjust(0, 0, 0, -3); - path.moveTo(r.topLeft()); - // Top left corner - path.quadTo(r.topLeft() + QPointF(radius, 0), r.topLeft() + QPointF(radius, radius)); - path.lineTo(r.bottomLeft() + QPointF(radius, -radius)); - // Bottom left corner - path.quadTo(r.bottomLeft() + QPointF(radius, 0), r.bottomLeft() + QPointF(radius * 2, 0)); - path.lineTo(r.bottomRight() + QPoint(-radius * 2, 0)); - // Bottom right corner - path.quadTo(r.bottomRight() + QPointF(-radius, 0), r.bottomRight() + QPointF(-radius, -radius)); - path.lineTo(r.topRight() + QPointF(-radius, radius)); - // Top right corner - path.quadTo(r.topRight() + QPointF(-radius, 0), r.topRight()); - break; - case RoundedNorth: - case TriangularNorth: - - r.adjust(0, 3, 0, 1); - path.moveTo(r.bottomLeft()); - // Bottom left corner - path.quadTo(r.bottomLeft() + QPointF(radius, 0), r.bottomLeft() + QPointF(radius, -radius)); - // Top left corner - path.lineTo(r.topLeft() + QPointF(radius, radius)); - path.quadTo(r.topLeft() + QPoint(radius, 0), r.topLeft() + QPointF(radius * 2, 0)); - // Top right corner - path.lineTo(r.topRight() + QPointF(-radius * 2, 0)); - path.quadTo(r.topRight() + QPointF(-radius, 0), r.topRight() + QPointF(-radius, radius)); - // Bottom right corner - path.lineTo(r.bottomRight() + QPointF(-radius, -radius)); - path.quadTo(r.bottomRight() + QPointF(-radius, 0), r.bottomRight()); - break; - case RoundedWest: - case TriangularWest: - r.adjust(3, 0, 1, 0); - path.moveTo(r.topRight()); - // Top right corner - path.lineTo(r.topRight()); - path.quadTo(r.topRight() + QPointF(0, radius), r.topRight() + QPointF(-radius, radius)); - // Top left corner - path.lineTo(r.topLeft() + QPointF(radius, radius)); - path.quadTo(r.topLeft() + QPointF(0, radius), r.topLeft() + QPointF(0, radius * 2)); - // Bottom left corner - path.lineTo(r.bottomLeft() + QPointF(0, -radius * 2)); - path.quadTo(r.bottomLeft() + QPointF(0, -radius), r.bottomLeft() + QPointF(radius, -radius)); - // Bottom right corner - path.lineTo(r.bottomRight() + QPointF(-radius, -radius)); - path.quadTo(r.bottomRight() + QPointF(0, -radius), r.bottomRight()); - break; - case RoundedEast: - case TriangularEast: - r.adjust(0, 0, -3, 0); - path.moveTo(r.topLeft()); - // Top left corner - path.quadTo(r.topLeft() + QPointF(0, radius), r.topLeft() + QPointF(radius, radius)); - // Top right corner - path.lineTo(r.topRight() + QPointF(-radius, radius)); - path.quadTo(r.topRight() + QPointF(0, radius), r.topRight() + QPointF(0, radius * 2)); - // Bottom right corner - path.lineTo(r.bottomRight() + QPointF(0, -radius * 2)); - path.quadTo(r.bottomRight() + QPointF(0, -radius), r.bottomRight() + QPointF(-radius, -radius)); - // Bottom left corner - path.lineTo(r.bottomLeft() + QPointF(radius, -radius)); - path.quadTo(r.bottomLeft() + QPointF(0, -radius), r.bottomLeft()); - break; - } - - return path; -} - -void TabBar::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event) - QPainter painter(this); - //int numTabs = count(); - int currentTab = currentIndex(); - - background->paintFrame(&painter); - - //bool ltr = painter.layoutDirection() == Qt::LeftToRight; // Not yet used - painter.setFont(KGlobalSettings::smallestReadableFont()); - - // Drawing Tabborders - QRectF movingRect; - - if (m_currentAnimRect.isNull()) { - movingRect = tabRect(currentIndex()); - } else { - movingRect = m_currentAnimRect; - } - QPainterPath path = tabPath(movingRect); - - painter.save(); - painter.setPen(QPen(palette().base(), 1)); - - painter.setRenderHint(QPainter::Antialiasing); - - painter.fillPath(path, palette().base()); - - painter.restore(); - - QFontMetrics metrics(painter.font()); - int textHeight = metrics.height(); - - for (int i = 0; i < count(); i++) { - QRect rect = tabRect(i).adjusted(TAB_CONTENTS_MARGIN, TAB_CONTENTS_MARGIN, - -TAB_CONTENTS_MARGIN, -TAB_CONTENTS_MARGIN); - // draw tab icon - QRectF iconRect = rect; - iconRect.setBottom(iconRect.bottom() - textHeight); - iconRect.adjust(0, (isVertical() ? 1 : 0) * TAB_CONTENTS_MARGIN + 3, 0, 0); - - tabIcon(i).paint(&painter, iconRect.toRect()); - - // draw tab text - if (i != currentTab || m_animProgress < 0.9) { - //painter.setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText), 0)); - painter.setPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor)); - } else { - painter.setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::NormalText), 0)); - } - QRect textRect = rect; - textRect.setTop(textRect.bottom() - textHeight); - painter.drawText(textRect, Qt::AlignCenter | Qt::TextHideMnemonic, tabText(i)); - } -} - -void TabBar::leaveEvent(QEvent *event) -{ - Q_UNUSED(event) - m_hoveredTabIndex = -1; -} - -void TabBar::mouseMoveEvent(QMouseEvent *event) -{ - m_hoveredTabIndex = tabAt(event->pos()); - if (m_switchOnHover && m_hoveredTabIndex > -1 && m_hoveredTabIndex != currentIndex()) { - m_tabSwitchTimer.stop(); - m_tabSwitchTimer.start(50); - } -} - -void TabBar::resizeEvent(QResizeEvent* event) -{ - KTabBar::resizeEvent(event); - m_currentAnimRect = tabRect(currentIndex()); - - background->resizeFrame(event->size()); - - update(); -} - -void TabBar::dragEnterEvent(QDragEnterEvent *event) -{ - m_hoveredTabIndex = tabAt(event->pos()); - m_tabSwitchTimer.stop(); - m_tabSwitchTimer.start(50); - event->ignore(); -} - -void TabBar::switchToHoveredTab() -{ - if (m_hoveredTabIndex < 0 || m_hoveredTabIndex == currentIndex()) { - return; - } - - if (m_animateSwitch) { - setCurrentIndex(m_hoveredTabIndex); - } else { - setCurrentIndexWithoutAnimation(m_hoveredTabIndex); - } -} - -void TabBar::startAnimation() -{ - storeLastIndex(); - - QPropertyAnimation *animation = m_animation.data(); - if (animation) { - animation->pause(); - } else { - animation = new QPropertyAnimation(this, "animValue"); - animation->setEasingCurve(QEasingCurve::OutQuad); - animation->setDuration(150); - animation->setStartValue(0.0); - animation->setEndValue(1.0); - } - - animation->start(QAbstractAnimation::DeleteWhenStopped); -} - -qreal TabBar::animValue() const -{ - return m_animProgress; -} - -void TabBar::setAnimValue(qreal value) -{ - if ((m_animProgress = value) == 1.0) { - animationFinished(); - return; - } - // animation rect - QRect rect = tabRect(currentIndex()); - QRect lastRect = tabRect(lastIndex()); - int x = isHorizontal() ? (int)(lastRect.x() - value * (lastRect.x() - rect.x())) : rect.x(); - int y = isHorizontal() ? rect.y() : (int)(lastRect.y() - value * (lastRect.y() - rect.y())); - QSizeF sz = lastRect.size() - value * (lastRect.size() - rect.size()); - m_currentAnimRect = QRect(x, y, (int)(sz.width()), (int)(sz.height())); - update(); -} - -void TabBar::animationFinished() -{ - m_currentAnimRect = QRect(); - update(); -} - -bool TabBar::isVertical() const -{ - Shape s = shape(); - if (s == RoundedWest || - s == RoundedEast || - s == TriangularWest || - s == TriangularEast) { - return true; - } - return false; -} - -bool TabBar::isHorizontal() const -{ - return !isVertical(); -} - -#include "moc_tabbar.cpp" diff --git a/plasma/applets/kickoff/ui/tabbar.h b/plasma/applets/kickoff/ui/tabbar.h deleted file mode 100644 index 3910cd54..00000000 --- a/plasma/applets/kickoff/ui/tabbar.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef TABBAR_H -#define TABBAR_H - -#include -#include -#include - -#include - -namespace Plasma -{ -class FrameSvg; -} - -namespace Kickoff -{ - -class TabBar : public KTabBar -{ - Q_OBJECT - Q_PROPERTY(qreal animValue READ animValue WRITE setAnimValue) - -public: - TabBar(QWidget *parent); - - QSize sizeHint() const; - /** Like the setCurrentIndex() method but switches the tab without using any - animation. This is used e.g. within Launcher::reset() to switch back to the - favorite tab before Kickoff got shown. */ - void setCurrentIndexWithoutAnimation(int index); - - /** Specifies whether hovering switches between tabs or if a click is required to switch the tabs. */ - void setSwitchTabsOnHover(bool switchOnHover); - bool switchTabsOnHover() const; - void setAnimateSwitch(bool animateSwitch); - bool animateSwitch() const ; - void setShape(Shape shape); - qreal animValue() const; - -protected: - int lastIndex() const; - - // reimplemented from KTabBar - virtual QSize tabSizeHint(int index) const; - virtual void paintEvent(QPaintEvent *event); - virtual void leaveEvent(QEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void resizeEvent(QResizeEvent* event); - virtual void dragEnterEvent(QDragEnterEvent *event); - - bool isHorizontal() const; - bool isVertical() const; - -protected slots: - void switchToHoveredTab(); - void animationFinished(); - void startAnimation(); - void setAnimValue(qreal value); - -private: - QPainterPath tabPath(const QRectF &r); - - static const int TAB_CONTENTS_MARGIN = 6; - int m_hoveredTabIndex; - QTimer m_tabSwitchTimer; - bool m_switchOnHover; - bool m_animateSwitch; - QRectF m_currentAnimRect; - int m_lastIndex[2]; - QWeakPointer m_animation; - qreal m_animProgress; - Plasma::FrameSvg *background; - - QSize tabSize(int index) const; - void storeLastIndex(); -}; - -} - -#endif // TABBAR_H diff --git a/plasma/applets/kickoff/ui/urlitemview.cpp b/plasma/applets/kickoff/ui/urlitemview.cpp deleted file mode 100644 index 6c367796..00000000 --- a/plasma/applets/kickoff/ui/urlitemview.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Own -#include "ui/urlitemview.h" - -// Qt -#include -#include -#include -#include -#include -#include -#include -#include - - -// KDE -#include -#include -#include -#include - -// Local -#include "core/models.h" -#include "core/kickoffmodel.h" -#include "ui/itemdelegate.h" - -using namespace Kickoff; - -class UrlItemView::Private -{ -public: - Private(UrlItemView *parent) - : q(parent) - , contentsHeight(0) - , itemStateProvider(0) { - } - - void doLayout() { - // clear existing layout information - itemRects.clear(); - visualOrder.clear(); - - if (!q->model()) { - return; - } - - int verticalOffset = ItemDelegate::TOP_OFFSET; - int horizontalOffset = 0; - int row = 0; - int visualColumn = 0; - - QModelIndex branch = currentRootIndex; - - while (true) { - if (itemChildOffsets[branch] + row >= q->model()->rowCount(branch) || - (branch != currentRootIndex && row > MAX_CHILD_ROWS)) { - - if (branch.isValid()) { - row = branch.row() + 1; - branch = branch.parent(); - continue; - } else { - break; - } - } - - QModelIndex child = q->model()->index(row + itemChildOffsets[branch], 0, branch); - - if (q->model()->hasChildren(child)) { - QSize childSize = calculateHeaderSize(child); - QRect rect(QPoint(ItemDelegate::HEADER_LEFT_MARGIN, verticalOffset), childSize); - //kDebug() << "header rect for" << child.data(Qt::DisplayRole) << "is" << rect; - itemRects.insert(child, rect); - - if (childSize.isValid()) { - // don't subtract 1 - verticalOffset += childSize.height(); - } - horizontalOffset = 0; - branch = child; - row = 0; - visualColumn = 0; - } else { - QSize childSize = calculateItemSize(child); - //kDebug() << "item rect for" << child.data(Qt::DisplayRole) << "is" << QRect(QPoint(horizontalOffset,verticalOffset), childSize); - - itemRects.insert(child, QRect(QPoint(horizontalOffset, verticalOffset), - childSize)); - - if (childSize.isValid()) { - visualOrder << child; - } - - horizontalOffset += contentWidth() / MAX_COLUMNS; - - visualColumn++; - row++; - - bool wasLastRow = row + itemChildOffsets[branch] >= q->model()->rowCount(branch); - bool nextItemIsBranch = false; - if (!wasLastRow) { - QModelIndex nextIndex = q->model()->index(row + itemChildOffsets[branch], 0, branch); - nextItemIsBranch = q->model()->hasChildren(nextIndex); - } - - if (visualColumn >= MAX_COLUMNS || wasLastRow || nextItemIsBranch) { - horizontalOffset = 0; - visualColumn = 0; - } - - if (childSize.isValid()) { - // don't subtract 1 - verticalOffset += childSize.height(); - } - } - } - contentsHeight = verticalOffset; - - updateScrollBarRange(); - } - - void drawHeader(QPainter *painter, - const QModelIndex& index, - const QStyleOptionViewItem& option) { - const bool first = isFirstHeader(index); - const int rightMargin = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 6; - const int dy = (first ? 4 : ItemDelegate::HEADER_TOP_MARGIN); - - painter->save(); - painter->setRenderHint(QPainter::Antialiasing, false); - - if (!first) { - QLinearGradient gradient(option.rect.topLeft(), option.rect.topRight()); - gradient.setColorAt(0.0, Qt::transparent); - gradient.setColorAt(0.1, option.palette.midlight().color()); - gradient.setColorAt(0.5, option.palette.mid().color()); - gradient.setColorAt(0.9, option.palette.midlight().color()); - gradient.setColorAt(1.0, Qt::transparent); - painter->setPen(QPen(gradient, 1)); - - painter->drawLine(option.rect.x() + 6, option.rect.y() + dy + 2, - option.rect.right() - rightMargin , option.rect.y() + dy + 2); - } - - painter->setFont(KGlobalSettings::smallestReadableFont()); - painter->setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText), 0)); - QString text = index.data(Qt::DisplayRole).value(); - painter->drawText(option.rect.adjusted(0, dy, -rightMargin, 0), - Qt::AlignVCenter | Qt::AlignRight, text); - painter->restore(); - } - - void updateScrollBarRange() { - const int pageSize = q->height(); - q->verticalScrollBar()->setRange(0, contentsHeight - pageSize); - q->verticalScrollBar()->setPageStep(pageSize); - q->verticalScrollBar()->setSingleStep(q->sizeHintForRow(0)); - } - - int contentWidth() const { - return q->width() - q->style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 2; - } - - QSize calculateItemSize(const QModelIndex& index) const { - if (itemStateProvider && !itemStateProvider->isVisible(index)) { - return QSize(); - } else { - return QSize(contentWidth() / MAX_COLUMNS, q->sizeHintForIndex(index).height()); - } - } - - bool isFirstHeader(const QModelIndex &index) const { - if (index.row() == 0) { - return q->model()->hasChildren(index); - } - - QModelIndex prevHeader = index.sibling(index.row() - 1, index.column()); - while (prevHeader.isValid()) { - //kDebug() << "checking" << prevHeader.data(Qt::DisplayRole).value(); - if (q->model()->hasChildren(prevHeader)) { - //kDebug() << "it has children"; - return false; - } - - prevHeader = prevHeader.sibling(prevHeader.row() - 1, prevHeader.column()); - } - - return true; - } - - bool insertAbove(const QRect &itemRect, const QPoint &pos) const { - return pos.y() < itemRect.top() + (itemRect.height() / 2); - } - - bool insertBelow(const QRect &itemRect, const QPoint &pos) const { - return pos.y() >= itemRect.top() + (itemRect.height() / 2); - } - - QSize calculateHeaderSize(const QModelIndex& index) const { - const QFontMetrics fm(KGlobalSettings::smallestReadableFont()); - int minHeight = ItemDelegate::HEADER_HEIGHT; - const bool isFirst = isFirstHeader(index); - - if (itemStateProvider && !itemStateProvider->isVisible(index)) { - return QSize(); - } else if (isFirst) { - minHeight = ItemDelegate::FIRST_HEADER_HEIGHT; - } - - return QSize(q->width() - ItemDelegate::HEADER_LEFT_MARGIN, - qMax(fm.height() + (isFirst ? 4 : ItemDelegate::HEADER_TOP_MARGIN), minHeight) - + ItemDelegate::HEADER_BOTTOM_MARGIN) ; - } - - QPoint mapFromViewport(const QPoint& point) const { - return point + QPoint(0, q->verticalOffset()); - } - - QPoint mapToViewport(const QPoint& point) const { - return point - QPoint(0, q->verticalOffset()); - } - - UrlItemView * const q; - QPersistentModelIndex currentRootIndex; - QPersistentModelIndex hoveredIndex; - QPersistentModelIndex watchedIndexForDrag; - - QHash itemChildOffsets; - QHash itemRects; - QList visualOrder; - - QRect dropRect; - int draggedRow; - bool dragging; - - int contentsHeight; - ItemStateProvider *itemStateProvider; - - static const int MAX_COLUMNS = 1; - - // TODO Eventually it will be possible to restrict each branch to only showing - // a given number of children, with Next/Previous arrows to view more children - // - // eg. - // - // Recent Documents [1-10 of 100] Next - // Recent Applications [10-20 of 30] Previous|Next - // - static const int MAX_CHILD_ROWS = 1000; -}; - -UrlItemView::UrlItemView(QWidget *parent) - : QAbstractItemView(parent) - , d(new Private(this)) -{ - d->dragging = false; - setIconSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium)); - setMouseTracking(true); - QPalette viewPalette(palette()); - viewPalette.setColor(QPalette::Window, palette().color(QPalette::Active, QPalette::Base)); - setPalette(viewPalette); - setAutoFillBackground(true); -} - -UrlItemView::~UrlItemView() -{ - delete d; -} - -QModelIndex UrlItemView::indexAt(const QPoint& point) const -{ - // simple linear search through the item rects, this will - // be inefficient when the viewport is large - QHashIterator iter(d->itemRects); - while (iter.hasNext()) { - iter.next(); - if (iter.value().contains(d->mapFromViewport(point))) { - return iter.key(); - } - } - return QModelIndex(); -} - -bool UrlItemView::initializeSelection() -{ - if (!selectionModel() - || selectionModel()->hasSelection() - || d->itemRects.size() == 0 - ) { - return false; - } - - // searching for the first item - the item whose rectangle is the - // top one - - QHashIterator iter(d->itemRects); - - // There is at least one item - iter.next(); - - int y = iter.value().top(); - QModelIndex index = iter.key(); - - while (iter.hasNext()) { - iter.next(); - - if (y > iter.value().top()) { - y = iter.value().top(); - index = iter.key(); - } - } - - setCurrentIndex(index); - - return selectionModel()->hasSelection(); -} - -void UrlItemView::setModel(QAbstractItemModel *model) -{ - QAbstractItemView::setModel(model); - - if (model) { - connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(updateLayout())); - connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(updateLayout())); - connect(model, SIGNAL(modelReset()), this, SLOT(updateLayout())); - } - - d->currentRootIndex = QModelIndex(); - d->itemChildOffsets.clear(); - updateLayout(); -} - -void UrlItemView::updateLayout() -{ - d->doLayout(); - - if (viewport()->isVisible()) { - viewport()->update(); - } -} - -void UrlItemView::scrollTo(const QModelIndex& index, ScrollHint hint) -{ - QRect itemRect = d->itemRects[index]; - QRect viewedRect = QRect(d->mapFromViewport(QPoint(0, 0)), - size()); - int topDifference = viewedRect.top() - itemRect.top(); - int bottomDifference = viewedRect.bottom() - itemRect.bottom(); - QScrollBar *scrollBar = verticalScrollBar(); - - if (!itemRect.isValid()) - return; - - switch (hint) { - case EnsureVisible: { - if (!viewedRect.contains(itemRect)) { - - if (topDifference < 0) { - // scroll view down - scrollBar->setValue(scrollBar->value() - bottomDifference); - } else { - // scroll view up - scrollBar->setValue(scrollBar->value() - topDifference); - } - } - } - break; - case PositionAtTop: { - //d->viewportOffset = itemRect.top(); - } - default: - Q_ASSERT(false); // Not implemented - } -} - -QRect UrlItemView::visualRect(const QModelIndex& index) const -{ - QRect itemRect = d->itemRects[index]; - if (!itemRect.isValid()) { - return itemRect; - } - - itemRect.moveTopLeft(d->mapToViewport(itemRect.topLeft())); - return itemRect; -} - -int UrlItemView::horizontalOffset() const -{ - return 0; -} - -bool UrlItemView::isIndexHidden(const QModelIndex&) const -{ - return false; -} - -QModelIndex UrlItemView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers) -{ - QModelIndex index = currentIndex(); - - int visualIndex = d->visualOrder.indexOf(index); - - switch (cursorAction) { - case MoveUp: - if (!currentIndex().isValid()) { - const QModelIndex root = model()->index(0, 0); - index = model()->index(model()->rowCount(root) - 1, 0, root); - } else { - visualIndex = qMax(0, visualIndex - 1); - } - break; - case MoveDown: - if (!currentIndex().isValid()) { - const QModelIndex root = model()->index(0, 0); - index = model()->index(0, 0, root); - } else { - visualIndex = qMin(d->visualOrder.count() - 1, visualIndex + 1); - } - break; - default: - // Do nothing - break; - } - - d->hoveredIndex = QModelIndex(); - - return currentIndex().isValid() ? d->visualOrder.value(visualIndex, QModelIndex()) - : index; -} - -void UrlItemView::setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags) -{ - QItemSelection selection; - selection.select(indexAt(rect.topLeft()), indexAt(rect.bottomRight())); - selectionModel()->select(selection, flags); -} - -int UrlItemView::verticalOffset() const -{ - return verticalScrollBar()->value(); -} - -QRegion UrlItemView::visualRegionForSelection(const QItemSelection& selection) const -{ - QRegion region; - foreach(const QModelIndex& index, selection.indexes()) { - region |= visualRect(index); - } - return region; -} - -void UrlItemView::paintEvent(QPaintEvent *event) -{ - if (!model()) { - return; - } - - QPalette viewPalette(palette()); - viewPalette.setColor(QPalette::Window, palette().color(QPalette::Active, QPalette::Base)); - setPalette(viewPalette); - setAutoFillBackground(true); - - QPainter painter(viewport()); - painter.setRenderHint(QPainter::Antialiasing); - - if (d->dragging && dragDropMode() == QAbstractItemView::DragDrop) { - const int y = (d->dropRect.top() + d->dropRect.bottom()) / 2; - - painter.save(); - QLinearGradient gr(d->dropRect.left(), y, d->dropRect.right(), y); - gr.setColorAt(0, palette().base().color()); - gr.setColorAt(.35, palette().windowText().color()); - gr.setColorAt(.65, palette().windowText().color()); - gr.setColorAt(1, palette().base().color()); - painter.setPen(QPen(gr, 1)); - painter.drawLine(d->dropRect.left(), y, d->dropRect.right(), y); - painter.restore(); - } - - QHashIterator indexIter(d->itemRects); - while (indexIter.hasNext()) { - indexIter.next(); - const QRect itemRect = visualRect(indexIter.key()); - const QModelIndex index = indexIter.key(); - - if (event->region().contains(itemRect)) { - QStyleOptionViewItem option = viewOptions(); - option.rect = itemRect; - - if (selectionModel()->isSelected(index)) { - option.state |= QStyle::State_Selected; - } - if (index == d->hoveredIndex) { - option.state |= QStyle::State_MouseOver; - } - if (index == currentIndex()) { - option.state |= QStyle::State_HasFocus; - } - - if (model()->hasChildren(index)) { - d->drawHeader(&painter, index, option); - } else { - if (option.rect.left() == 0) { - option.rect.setLeft(option.rect.left() + ItemDelegate::ITEM_LEFT_MARGIN); - option.rect.setRight(option.rect.right() - ItemDelegate::ITEM_RIGHT_MARGIN); - } - itemDelegate(index)->paint(&painter, option, index); - } - } - } -} - -void UrlItemView::resizeEvent(QResizeEvent *) -{ - updateLayout(); -} - - -void UrlItemView::mouseMoveEvent(QMouseEvent *event) -{ - const QModelIndex itemUnderMouse = indexAt(event->pos()); - if (itemUnderMouse != d->hoveredIndex && state() == NoState) { - update(itemUnderMouse); - update(d->hoveredIndex); - - d->hoveredIndex = itemUnderMouse; - setCurrentIndex(d->hoveredIndex); - } - - Plasma::Delegate *hoveredItemDelegate = - static_cast(itemDelegate(d->hoveredIndex)); - if (hoveredItemDelegate->showToolTip()) { - QModelIndex index = d->hoveredIndex; - QString titleText = index.data(Qt::DisplayRole).toString(); - QString subTitleText = index.data(Plasma::Delegate::SubTitleRole).toString(); - setToolTip(titleText + '\n' + subTitleText); - } else { - setToolTip(QString()); - } - - QAbstractItemView::mouseMoveEvent(event); -} - -void UrlItemView::mousePressEvent(QMouseEvent *event) -{ - d->watchedIndexForDrag = indexAt(event->pos()); - QAbstractItemView::mousePressEvent(event); -} - -void UrlItemView::mouseReleaseEvent(QMouseEvent *event) -{ - Q_UNUSED(event) - - d->watchedIndexForDrag = QModelIndex(); -} - -void UrlItemView::setItemStateProvider(ItemStateProvider *provider) -{ - d->itemStateProvider = provider; -} - -void UrlItemView::dragEnterEvent(QDragEnterEvent *event) -{ - if (dragDropMode() != QAbstractItemView::DragDrop) { - return; - } - - d->dragging = true; - setDirtyRegion(d->dropRect); - - event->accept(); -} - -void UrlItemView::dragLeaveEvent(QDragLeaveEvent *event) -{ - if (dragDropMode() != QAbstractItemView::DragDrop) { - return; - } - - d->dragging = false; - setDirtyRegion(d->dropRect); - - event->accept(); -} - -void UrlItemView::dragMoveEvent(QDragMoveEvent *event) -{ - QAbstractItemView::dragMoveEvent(event); - - const QPoint pos = event->pos(); - const QModelIndex index = indexAt(pos); - setDirtyRegion(d->dropRect); - - // check to see if it's the header - if (d->isFirstHeader(index) && index.row() == 0) { - event->ignore(); - return; - } - - if (index.isValid()) { - const QRect rect = visualRect(index); - const int gap = d->contentsHeight; - - if (d->insertAbove(rect, pos)) { - d->dropRect = QRect(rect.left(), rect.top() - gap / 2, - rect.width(), gap); - } else if (d->insertBelow(rect, pos)) { - d->dropRect = QRect(rect.left(), rect.bottom() + 1 - gap / 2, - rect.width(), gap); - } else { - d->dropRect = rect; - } - } - - setDirtyRegion(d->dropRect); -} - - -void UrlItemView::startDrag(Qt::DropActions supportedActions) -{ - Q_UNUSED(supportedActions) - //kDebug() << "Starting UrlItemView drag with actions" << supportedActions; - - if (!d->watchedIndexForDrag.isValid()) { - return; - } - - QMimeData *mimeData = model()->mimeData(selectionModel()->selectedIndexes()); - - if (!mimeData || mimeData->text().isNull()) { - return; - } - - QDrag *drag = new QDrag(this); - drag->setMimeData(mimeData); - - QModelIndex idx = selectionModel()->selectedIndexes().first(); - QIcon icon = idx.data(Qt::DecorationRole).value(); - d->draggedRow = idx.row(); - drag->setPixmap(icon.pixmap(IconSize(KIconLoader::Desktop))); - - d->dropRect = QRect(); - drag->exec(Qt::CopyAction|Qt::MoveAction|Qt::LinkAction); -} - -void UrlItemView::dropEvent(QDropEvent *event) -{ - if (!d->dragging) { - return; - } - - // This special code is necessary in order to be able to - // inidcate to the model WHERE the item should be dropped, - // Since the model cannot tell where the user dropped the - // item. The model itself handles the actual moving of the - // item. - if (dragDropMode() == QAbstractItemView::DragDrop) { - int row; - QPoint pos = event->pos(); - QModelIndex parent = indexAt(pos); - - if (!parent.isValid()) { - return; - } - const QRect rect = visualRect(parent); - - row = parent.row(); - - if(d->insertBelow(rect, pos) && d->draggedRow > row) { - row++; - } else if(d->insertAbove(rect, pos) && d->draggedRow < row) { - row--; - } - - model()->dropMimeData(event->mimeData(), event->dropAction(), - row, 0, parent); - - d->dragging = false; - - event->accept(); - } -} -void UrlItemView::leaveEvent(QEvent *event) -{ - Q_UNUSED(event) - - //kDebug() << "UrlItemView leave event"; - - d->hoveredIndex = QModelIndex(); - setCurrentIndex(QModelIndex()); -} - -ItemStateProvider *UrlItemView::itemStateProvider() const -{ - return d->itemStateProvider; -} -#include "moc_urlitemview.cpp" diff --git a/plasma/applets/kickoff/ui/urlitemview.h b/plasma/applets/kickoff/ui/urlitemview.h deleted file mode 100644 index 285227a4..00000000 --- a/plasma/applets/kickoff/ui/urlitemview.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright 2007 Robert Knight - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef URLITEMVIEW_H -#define URLITEMVIEW_H - -// Qt -#include - -namespace Kickoff -{ - -class ItemStateProvider; -class UrlItemView : public QAbstractItemView -{ - Q_OBJECT - -public: - UrlItemView(QWidget *parent = 0); - virtual ~UrlItemView(); - - void setItemStateProvider(ItemStateProvider *provider); - ItemStateProvider *itemStateProvider() const; - - // reimplemented from QAbstractItemView - virtual QModelIndex indexAt(const QPoint& point) const; - virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible); - virtual QRect visualRect(const QModelIndex& index) const; - virtual void setModel(QAbstractItemModel *model); - - /* if nothing is selected, the first item is - * @returns whether the selection has changed - */ - bool initializeSelection(); - -protected: - // reimplemented from QAbstractItemView - virtual int horizontalOffset() const; - virtual bool isIndexHidden(const QModelIndex& index) const; - virtual QModelIndex moveCursor(CursorAction action, Qt::KeyboardModifiers modifiers); - virtual void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags); - virtual int verticalOffset() const; - virtual QRegion visualRegionForSelection(const QItemSelection& selection) const; - virtual void startDrag(Qt::DropActions supportedActions); - virtual void dragEnterEvent(QDragEnterEvent *event); - virtual void dragLeaveEvent(QDragLeaveEvent *event); - virtual void dragMoveEvent(QDragMoveEvent *event); - - // reimplemented from QWidget - virtual void paintEvent(QPaintEvent *event); - virtual void resizeEvent(QResizeEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void dropEvent(QDropEvent *event); - virtual void leaveEvent(QEvent *event); - - -private Q_SLOTS: - // lays out all items in the view and sets the current index to the first - // selectable item - void updateLayout(); - -private: - class Private; - Private * const d; -}; - -} - -#endif // URLITEMVIEW_H diff --git a/plasma/applets/launcher/CMakeLists.txt b/plasma/applets/launcher/CMakeLists.txt new file mode 100644 index 00000000..45925208 --- /dev/null +++ b/plasma/applets/launcher/CMakeLists.txt @@ -0,0 +1,25 @@ +project(plasma-applet-launcher) + +set(launcher_SRCS + launcher.cpp +) + +kde4_add_plugin(plasma_applet_launcher ${launcher_SRCS}) +target_link_libraries(plasma_applet_launcher + KDE4::plasma + KDE4::kio + KDE4::solid + KDE4::kcmutils + ${QT_QTNETWORK_LIBRARY} + kworkspace +) + +install( + TARGETS plasma_applet_launcher + DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} +) + +install( + FILES plasma-applet-launcher.desktop + DESTINATION ${KDE4_SERVICES_INSTALL_DIR} +) diff --git a/plasma/applets/kickoff/Messages.sh b/plasma/applets/launcher/Messages.sh similarity index 65% rename from plasma/applets/kickoff/Messages.sh rename to plasma/applets/launcher/Messages.sh index 8ef58d3d..f5263755 100644 --- a/plasma/applets/kickoff/Messages.sh +++ b/plasma/applets/launcher/Messages.sh @@ -1,3 +1,2 @@ #!/bin/bash -$EXTRACTRC `find . -name \*.ui` >> rc.cpp $XGETTEXT `find . -name \*.cpp` -o $podir/plasma_applet_launcher.pot diff --git a/plasma/applets/launcher/launcher.cpp b/plasma/applets/launcher/launcher.cpp new file mode 100644 index 00000000..c2434542 --- /dev/null +++ b/plasma/applets/launcher/launcher.cpp @@ -0,0 +1,976 @@ +/* + This file is part of the KDE project + Copyright (C) 2024 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "launcher.h" +#include "kworkspace/kworkspace.h" +#include "kworkspace/kdisplaymanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const QString s_defaultpopupicon = QString::fromLatin1("start-here-kde"); +static const QSizeF s_minimumsize = QSizeF(450, 350); +static const QString s_firsttimeaddress = QString::fromLatin1("_k_firsttime"); +static const QStringList s_firsttimeservices = QStringList() + << QString::fromLatin1("konsole") + << QString::fromLatin1("dolphin") + << QString::fromLatin1("systemsettings"); + +static QSizeF kIconSize() +{ + const int iconsize = KIconLoader::global()->currentSize(KIconLoader::Desktop); + return QSizeF(iconsize, iconsize); +} + +// TODO: custom widget to catch hover events from anywhere in the widget rect? +static Plasma::IconWidget* kMakeIconWidget(QGraphicsWidget *parent, + const QSizeF &iconsize, + const QString &text, + const QString &infotext, + const QString &icon, + const QString &url) +{ + Plasma::IconWidget* iconwidget = new Plasma::IconWidget(parent); + iconwidget->setOrientation(Qt::Horizontal); + iconwidget->setMinimumIconSize(iconsize); + iconwidget->setMaximumIconSize(iconsize); + iconwidget->setText(text); + iconwidget->setInfoText(infotext); + iconwidget->setIcon(icon); + iconwidget->setProperty("_k_url", url); + return iconwidget; +} + +static bool kCanLockScreen() +{ + return KDBusConnectionPool::isServiceRegistered("org.freedesktop.ScreenSaver", QDBusConnection::sessionBus()); +} + +static void kLockScreen() +{ + QDBusInterface screensaver( + "org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", + QDBusConnection::sessionBus() + ); + screensaver.call("Lock"); +} + +class LauncherSearch : public QGraphicsWidget +{ + Q_OBJECT +public: + LauncherSearch(QGraphicsWidget *parent); + + void prepare(); + void query(const QString &text); + void finish(); + +private Q_SLOTS: + void slotUpdateLayout(const QList &matches); + void slotActivated(); + void slotTriggered(); + +private: + QMutex m_mutex; + QGraphicsLinearLayout* m_layout; + QList m_iconwidgets; + Plasma::Label* m_label; + Plasma::RunnerManager* m_runnermanager; +}; + +LauncherSearch::LauncherSearch(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + m_layout(nullptr), + m_label(nullptr), + m_runnermanager(nullptr) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout = new QGraphicsLinearLayout(Qt::Vertical, this); + setLayout(m_layout); + + m_label = new Plasma::Label(this); + m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_label->setAlignment(Qt::AlignCenter); + m_label->setText(i18n("No matches found")); + m_layout->addItem(m_label); + + m_runnermanager = new Plasma::RunnerManager(this); + connect( + m_runnermanager, SIGNAL(matchesChanged(QList)), + this, SLOT(slotUpdateLayout(QList)) + ); + // TODO: option to disable and enable runners + // m_runnermanager->setAllowedRunners(s_allowedrunners); +} + +void LauncherSearch::prepare() +{ + // qDebug() << Q_FUNC_INFO; + QMutexLocker locker(&m_mutex); + foreach (Plasma::IconWidget* iconwidget, m_iconwidgets) { + m_layout->removeItem(iconwidget); + } + qDeleteAll(m_iconwidgets); + m_iconwidgets.clear(); + + m_label->setVisible(true); + adjustSize(); + + m_runnermanager->reset(); +} + +void LauncherSearch::query(const QString &text) +{ + // qDebug() << Q_FUNC_INFO << text; + m_runnermanager->launchQuery(text); +} + +void LauncherSearch::finish() +{ + // qDebug() << Q_FUNC_INFO; + m_runnermanager->matchSessionComplete(); +} + +void LauncherSearch::slotUpdateLayout(const QList &matches) +{ + // qDebug() << Q_FUNC_INFO; + QMutexLocker locker(&m_mutex); + m_label->setVisible(false); + adjustSize(); + + const QSizeF iconsize = kIconSize(); + foreach (const Plasma::QueryMatch &match, matches) { + // qDebug() << Q_FUNC_INFO << match.text() << match.subtext(); + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, match.text(), match.subtext(), QString(), match.id() + ); + iconwidget->setIcon(match.icon()); + if (match.type() == Plasma::QueryMatch::InformationalMatch) { + iconwidget->setAcceptHoverEvents(false); + iconwidget->setAcceptedMouseButtons(Qt::NoButton); + } + int counter = 1; + if (match.hasConfigurationInterface()) { + // TODO: action is set but where is it? + QAction* matchconfigaction = new QAction(iconwidget); + matchconfigaction->setText(i18n("Configure")); + matchconfigaction->setIcon(KIcon("system-preferences")); + matchconfigaction->setProperty("_k_id", match.id()); + connect( + matchconfigaction, SIGNAL(triggered()), + this, SLOT(slotTriggered()) + ); + iconwidget->addIconAction(matchconfigaction); + counter++; + qDebug() << Q_FUNC_INFO << match.id(); + } + foreach (QAction* action, m_runnermanager->actionsForMatch(match)) { + iconwidget->addIconAction(action); + if (counter >= 4) { + // the limit of Plasma::IconWidget + break; + } + counter++; + } + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } +} + +void LauncherSearch::slotActivated() +{ + Plasma::IconWidget* iconwidget = qobject_cast(sender()); + const QString iconwidgeturl = iconwidget->property("_k_url").toString(); + m_runnermanager->run(iconwidgeturl); +} + +void LauncherSearch::slotTriggered() +{ + QAction* matchconfigaction = qobject_cast(sender()); + const QString matchconfigid = matchconfigaction->property("_k_id").toString(); + Plasma::AbstractRunner* runner = m_runnermanager->runner(m_runnermanager->runnerName(matchconfigid)); + if (!runner) { + kWarning() << "no runner for" << matchconfigid; + return; + } + // TODO: implement + qDebug() << Q_FUNC_INFO << matchconfigid; +} + +class LauncherFavorites : public QGraphicsWidget +{ + Q_OBJECT +public: + LauncherFavorites(QGraphicsWidget *parent); + +private Q_SLOTS: + void slotUpdateLayout(); + void slotActivated(); + +private: + QMutex m_mutex; + QGraphicsLinearLayout* m_layout; + QList m_iconwidgets; + KBookmarkManager* m_bookmarkmanager; +}; + +// TODO: context menu to remove +LauncherFavorites::LauncherFavorites(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + m_layout(nullptr), + m_bookmarkmanager(nullptr) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout = new QGraphicsLinearLayout(Qt::Vertical, this); + setLayout(m_layout); + + const QString bookmarfile = KStandardDirs::locateLocal("data", "plasma/bookmarks.xml"); + m_bookmarkmanager = KBookmarkManager::managerForFile(bookmarfile, "launcher"); + // m_bookmarkmanager->slotEditBookmarks(); + slotUpdateLayout(); + connect( + m_bookmarkmanager, SIGNAL(changed(QString,QString)), + this, SLOT(slotUpdateLayout()) + ); + connect( + KSycoca::self(), SIGNAL(databaseChanged(QStringList)), + this, SLOT(slotUpdateLayout()) + ); +} + +void LauncherFavorites::slotUpdateLayout() +{ + QMutexLocker locker(&m_mutex); + foreach (Plasma::IconWidget* iconwidget, m_iconwidgets) { + m_layout->removeItem(iconwidget); + } + qDeleteAll(m_iconwidgets); + m_iconwidgets.clear(); + + adjustSize(); + + bool isfirsttime = true; + KBookmarkGroup bookmarkgroup = m_bookmarkmanager->root(); + // first time gets a special treatment + KBookmark bookmark = bookmarkgroup.first(); + while (!bookmark.isNull()) { + if (bookmark.url().url() == s_firsttimeaddress) { + isfirsttime = false; + break; + } + bookmark = bookmarkgroup.next(bookmark); + } + if (isfirsttime) { + bookmark = bookmarkgroup.createNewSeparator(); + bookmark.setUrl(s_firsttimeaddress); + bookmark.setDescription("internal bookmark"); + foreach (const QString &name, s_firsttimeservices) { + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service.isNull()) { + bookmarkgroup.addBookmark(service->desktopEntryName(), KUrl(service->entryPath()), service->icon()); + } else { + kWarning() << "invalid first-time serivce" << name; + } + } + m_bookmarkmanager->emitChanged(bookmarkgroup); + } + + const QSizeF iconsize = kIconSize(); + bookmark = bookmarkgroup.first(); + while (!bookmark.isNull()) { + // qDebug() << Q_FUNC_INFO << bookmark.text() << bookmark.description() << bookmark.icon() << bookmark.url(); + if (bookmark.isSeparator()) { + bookmark = bookmarkgroup.next(bookmark); + continue; + } + const QString serviceentrypath = bookmark.url().url(); + KService::Ptr service = KService::serviceByDesktopPath(serviceentrypath); + if (service.isNull()) { + service = KService::serviceByDesktopName(bookmark.text()); + } + if (service.isNull()) { + kWarning() << "could not find service for" << serviceentrypath; + bookmark = bookmarkgroup.next(bookmark); + continue; + } + // qDebug() << Q_FUNC_INFO << service->entryPath() << service->name() << service->comment(); + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, service->name(), service->genericName(), service->icon(), service->entryPath() + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + bookmark = bookmarkgroup.next(bookmark); + } +} + +void LauncherFavorites::slotActivated() +{ + Plasma::IconWidget* iconwidget = qobject_cast(sender()); + const QString iconwidgeturl = iconwidget->property("_k_url").toString(); + (void)new KRun(KUrl(iconwidgeturl), nullptr); +} + + +class LauncherServiceWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + LauncherServiceWidget(QGraphicsWidget *parent, Plasma::TabBar *tabbar, const int tabindex); + + void appendGroup(Plasma::IconWidget* iconwidget, LauncherServiceWidget* servicewidget); + void appendApp(Plasma::IconWidget* iconwidget); + int serviceCount() const; + int tabIndex() const; + +public Q_SLOTS: + void slotGroupActivated(); + void slotAppActivated(); + +private: + Plasma::TabBar* m_tabbar; + int m_tabindex; + QGraphicsLinearLayout* m_layout; + QList m_iconwidgets; +}; + +LauncherServiceWidget::LauncherServiceWidget(QGraphicsWidget *parent, Plasma::TabBar *tabbar, const int tabindex) + : QGraphicsWidget(parent), + m_tabbar(tabbar), + m_tabindex(tabindex), + m_layout(nullptr) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout = new QGraphicsLinearLayout(Qt::Vertical, this); + setLayout(m_layout); +} + +int LauncherServiceWidget::serviceCount() const +{ + return m_iconwidgets.size(); +} + +int LauncherServiceWidget::tabIndex() const +{ + return m_tabindex; +} + +void LauncherServiceWidget::appendGroup(Plasma::IconWidget* iconwidget, LauncherServiceWidget* servicewidget) +{ + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + servicewidget, SLOT(slotGroupActivated()) + ); +} + +void LauncherServiceWidget::appendApp(Plasma::IconWidget* iconwidget) +{ + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotAppActivated()) + ); +} + +void LauncherServiceWidget::slotGroupActivated() +{ + m_tabbar->setCurrentIndex(m_tabindex); +} + +void LauncherServiceWidget::slotAppActivated() +{ + Plasma::IconWidget* iconwidget = qobject_cast(sender()); + const QString iconwidgeturl = iconwidget->property("_k_url").toString(); + (void)new KRun(KUrl(iconwidgeturl), nullptr); +} + +class LauncherApplications : public Plasma::TabBar +{ + Q_OBJECT +public: + LauncherApplications(QGraphicsWidget *parent); + +private Q_SLOTS: + void slotUpdateLayout(); + +private: + void addGroup(LauncherServiceWidget *servicewidget, KServiceGroup::Ptr group); + + QMutex m_mutex; + Plasma::ScrollWidget* m_rootscrollwidget; + LauncherServiceWidget* m_root; + QList m_tabscrollwidgets; + QList m_tabwidgets; +}; + +LauncherApplications::LauncherApplications(QGraphicsWidget *parent) + : Plasma::TabBar(parent), + m_rootscrollwidget(nullptr), + m_root(nullptr) +{ + // TODO: navigation bar instead + // setTabBarShown(false); + + slotUpdateLayout(); + + connect( + KSycoca::self(), SIGNAL(databaseChanged(QStringList)), + this, SLOT(slotUpdateLayout()) + ); +} + +void LauncherApplications::slotUpdateLayout() +{ + QMutexLocker locker(&m_mutex); + qDeleteAll(m_tabwidgets); + m_tabwidgets.clear(); + delete m_root; + m_root = nullptr; + delete m_rootscrollwidget; + m_rootscrollwidget = nullptr; + + m_rootscrollwidget = new Plasma::ScrollWidget(this); + m_rootscrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_root = new LauncherServiceWidget(m_rootscrollwidget, this, 0); + m_rootscrollwidget->setWidget(m_root); + addTab(KIcon("applications-other"), "root", m_rootscrollwidget); + + KServiceGroup::Ptr group = KServiceGroup::root(); + if (group && group->isValid()) { + addGroup(m_root, group); + } +} + +void LauncherApplications::addGroup(LauncherServiceWidget *servicewidget, KServiceGroup::Ptr group) +{ + const QString name = group->name(); + if (name.isEmpty() || group->noDisplay()) { + kDebug() << "hidden or invalid group" << name; + return; + } + + const QSizeF iconsize = kIconSize(); + foreach (const KServiceGroup::Ptr subgroup, group->groupEntries(KServiceGroup::NoOptions)) { + Plasma::ScrollWidget* scrollwidget = new Plasma::ScrollWidget(this); + scrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + LauncherServiceWidget* subgroupwidget = new LauncherServiceWidget(scrollwidget, this, servicewidget->tabIndex() + 1); + addGroup(subgroupwidget, subgroup); + if (subgroupwidget->serviceCount() < 1) { + delete subgroupwidget; + delete scrollwidget; + } else { + scrollwidget->setWidget(subgroupwidget); + m_tabscrollwidgets.append(scrollwidget); + Plasma::IconWidget* subgroupiconwidget = kMakeIconWidget( + servicewidget, + iconsize, subgroup->caption(), subgroup->comment(), subgroup->icon(), QString() + ); + servicewidget->appendGroup(subgroupiconwidget, subgroupwidget); + addTab(KIcon("applications-other"), subgroup->caption(), scrollwidget); + } + } + + foreach (const KService::Ptr app, group->serviceEntries(KServiceGroup::NoOptions)) { + if (app->noDisplay()) { + kDebug() << "hidden entry" << app->name(); + continue; + } + Plasma::IconWidget* appiconwidget = kMakeIconWidget( + servicewidget, + iconsize, app->name(), app->comment(), app->icon(), app->entryPath() + ); + servicewidget->appendApp(appiconwidget); + } +} + + +class LauncherRecent : public QGraphicsWidget +{ + Q_OBJECT +public: + LauncherRecent(QGraphicsWidget *parent); + +private Q_SLOTS: + void slotUpdateLayout(); + void slotActivated(); + +private: + QMutex m_mutex; + QGraphicsLinearLayout* m_layout; + QList m_iconwidgets; + KDirWatch* m_dirwatch; +}; + +LauncherRecent::LauncherRecent(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + m_layout(nullptr), + m_dirwatch(nullptr) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout = new QGraphicsLinearLayout(Qt::Vertical, this); + setLayout(m_layout); + + m_dirwatch = new KDirWatch(this); + m_dirwatch->addDir(KRecentDocument::recentDocumentDirectory()); + slotUpdateLayout(); + connect( + m_dirwatch, SIGNAL(dirty(QString)), + this, SLOT(slotUpdateLayout()) + ); +} + +void LauncherRecent::slotUpdateLayout() +{ + QMutexLocker locker(&m_mutex); + foreach (Plasma::IconWidget* iconwidget, m_iconwidgets) { + m_layout->removeItem(iconwidget); + } + qDeleteAll(m_iconwidgets); + m_iconwidgets.clear(); + + adjustSize(); + + const QSizeF iconsize = kIconSize(); + foreach (const QString &recent, KRecentDocument::recentDocuments()) { + KDesktopFile recentfile(recent); + // qDebug() << Q_FUNC_INFO << recentfile.readName() << recentfile.readComment(); + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, recentfile.readName(), recentfile.readComment(), recentfile.readIcon(), recentfile.readUrl() + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } +} + +void LauncherRecent::slotActivated() +{ + Plasma::IconWidget* iconwidget = qobject_cast(sender()); + const QString iconwidgeturl = iconwidget->property("_k_url").toString(); + (void)new KRun(KUrl(iconwidgeturl), nullptr); +} + + +class LauncherLeave : public QGraphicsWidget +{ + Q_OBJECT +public: + LauncherLeave(QGraphicsWidget *parent); + +private Q_SLOTS: + void slotUpdateLayout(); + void slotActivated(); + +private: + QMutex m_mutex; + QGraphicsLinearLayout* m_layout; + QList m_iconwidgets; + Plasma::Separator* m_systemseparator; +}; + +// TODO: check for lock and switchable state changes +LauncherLeave::LauncherLeave(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + m_systemseparator(nullptr) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout = new QGraphicsLinearLayout(Qt::Vertical, this); + setLayout(m_layout); + + slotUpdateLayout(); + connect( + Solid::PowerManagement::notifier(), SIGNAL(supportedSleepStatesChanged()), + this, SLOT(slotUpdateLayout()) + ); +} + +void LauncherLeave::slotUpdateLayout() +{ + QMutexLocker locker(&m_mutex); + foreach (Plasma::IconWidget* iconwidget, m_iconwidgets) { + m_layout->removeItem(iconwidget); + } + qDeleteAll(m_iconwidgets); + m_iconwidgets.clear(); + + if (m_systemseparator) { + m_layout->removeItem(m_systemseparator); + delete m_systemseparator; + m_systemseparator = nullptr; + } + + adjustSize(); + + const QSizeF iconsize = kIconSize(); + bool hassessionicon = false; + if (kCanLockScreen()) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Lock"), i18n("Lock screen"), "system-lock-screen", "lock" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + hassessionicon = true; + } + if (KDisplayManager().isSwitchable()) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Switch user"), i18n("Start a parallel session as a different user"), "system-switch-user", "switch" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + hassessionicon = true; + } + if (hassessionicon) { + m_systemseparator = new Plasma::Separator(this); + m_systemseparator->setOrientation(Qt::Horizontal); + m_layout->addItem(m_systemseparator); + } + + const QSet sleepsates = Solid::PowerManagement::supportedSleepStates(); + if (sleepsates.contains(Solid::PowerManagement::SuspendState)) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Sleep"), i18n("Suspend to RAM"), "system-suspend", "suspendram" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } + if (sleepsates.contains(Solid::PowerManagement::HibernateState)) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Hibernate"), i18n("Suspend to disk"), "system-suspend-hibernate", "suspenddisk" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } + if (sleepsates.contains(Solid::PowerManagement::HybridSuspendState)) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Hybrid Suspend"), i18n("Hybrid Suspend"), "system-suspend", "suspendhybrid" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } + + if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot)) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18nc("Restart computer", "Restart"), i18n("Restart computer"), "system-reboot", "restart" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } + if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt)) { + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Shut down"), i18n("Turn off computer"), "system-shutdown", "shutdown" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); + } + Plasma::IconWidget* iconwidget = kMakeIconWidget( + this, + iconsize, i18n("Log out"), i18n("End session"), "system-log-out", "logout" + ); + m_iconwidgets.append(iconwidget); + m_layout->addItem(iconwidget); + connect( + iconwidget, SIGNAL(activated()), + this, SLOT(slotActivated()) + ); +} + +void LauncherLeave::slotActivated() +{ + Plasma::IconWidget* iconwidget = qobject_cast(sender()); + const QString iconwidgeturl = iconwidget->property("_k_url").toString(); + if (iconwidgeturl == QLatin1String("lock")) { + kLockScreen(); + } else if (iconwidgeturl == QLatin1String("switch")) { + kLockScreen(); + KDisplayManager().newSession(); + } else if (iconwidgeturl == QLatin1String("suspendram")) { + Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState); + } else if (iconwidgeturl == QLatin1String("suspenddisk")) { + Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState); + } else if (iconwidgeturl == QLatin1String("suspendhybrid")) { + Solid::PowerManagement::requestSleep(Solid::PowerManagement::HybridSuspendState); + } else if (iconwidgeturl == QLatin1String("restart")) { + KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot); + } else if (iconwidgeturl == QLatin1String("shutdown")) { + KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt); + } else if (iconwidgeturl == QLatin1String("logout")) { + KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeNone); + } else { + Q_ASSERT(false); + kWarning() << "invalid url" << iconwidgeturl; + } +} + + +class LauncherAppletWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + LauncherAppletWidget(LauncherApplet* auncherapplet); + +private Q_SLOTS: + void slotSearch(const QString &text); + void slotTimeout(); + +private: + LauncherApplet* m_launcherapplet; + QGraphicsGridLayout* m_layout; + Plasma::IconWidget* m_iconwidget; + Plasma::Label* m_label; + Plasma::LineEdit* m_lineedit; + Plasma::TabBar* m_tabbar; + Plasma::ScrollWidget* m_favoritesscrollwidget; + LauncherFavorites* m_favoriteswidget; + LauncherApplications* m_applicationswidget; + Plasma::ScrollWidget* m_recentscrollwidget; + LauncherRecent* m_recentwidget; + Plasma::ScrollWidget* m_leavecrollwidget; + LauncherLeave* m_leavewidget; + Plasma::ScrollWidget* m_searchscrollwidget; + LauncherSearch* m_searchwidget; + QTimer* m_timer; +}; + +LauncherAppletWidget::LauncherAppletWidget(LauncherApplet* auncherapplet) + : QGraphicsWidget(auncherapplet), + m_launcherapplet(auncherapplet), + m_layout(nullptr), + m_iconwidget(nullptr), + m_label(nullptr), + m_lineedit(nullptr), + m_tabbar(nullptr), + m_favoritesscrollwidget(nullptr), + m_favoriteswidget(nullptr), + m_applicationswidget(nullptr), + m_recentscrollwidget(nullptr), + m_recentwidget(nullptr), + m_leavecrollwidget(nullptr), + m_leavewidget(nullptr), + m_searchscrollwidget(nullptr), + m_searchwidget(nullptr), + m_timer(nullptr) +{ + m_layout = new QGraphicsGridLayout(this); + + const QString hostname = QHostInfo::localHostName(); + KUser user(KUser::UseEffectiveUID); + QString usericon = user.faceIconPath(); + if (usericon.isEmpty()) { + usericon = QLatin1String("system-search"); + } + m_iconwidget = new Plasma::IconWidget(this); + const int iconsize = KIconLoader::global()->currentSize(KIconLoader::Toolbar); + const QSizeF iconsizef = QSizeF(iconsize, iconsize); + m_iconwidget->setMinimumIconSize(iconsizef); + m_iconwidget->setMaximumIconSize(iconsizef); + m_iconwidget->setAcceptHoverEvents(false); + m_iconwidget->setAcceptedMouseButtons(Qt::NoButton); + m_iconwidget->setIcon(usericon); + m_layout->addItem(m_iconwidget, 0, 0); + + QString usertext; + QString fullusername = user.property(KUser::FullName); + if (fullusername.isEmpty()) { + usertext = i18nc("login name, hostname", "User %1 on %2", user.loginName(), hostname); + } else { + usertext = i18nc("full name, login name, hostname", "%1 (%2) on %3", fullusername, user.loginName(), hostname); + } + m_label = new Plasma::Label(this); + m_label->setWordWrap(false); + m_label->setText(usertext); + m_layout->addItem(m_label, 0, 1); + + m_lineedit = new Plasma::LineEdit(this); + m_lineedit->setClickMessage(i18n("Search")); + m_layout->addItem(m_lineedit, 0, 2); + setFocusProxy(m_lineedit); + + m_tabbar = new Plasma::TabBar(this); + // has not effect.. + // m_tabbar->nativeWidget()->setShape(QTabBar::RoundedSouth); + m_favoritesscrollwidget = new Plasma::ScrollWidget(m_tabbar); + m_favoritesscrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_favoritesscrollwidget->setMinimumSize(s_minimumsize); + m_favoriteswidget = new LauncherFavorites(m_favoritesscrollwidget); + m_favoritesscrollwidget->setWidget(m_favoriteswidget); + m_tabbar->addTab(KIcon("bookmarks"), i18n("Favorites"), m_favoritesscrollwidget); + m_applicationswidget = new LauncherApplications(m_tabbar); + m_applicationswidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_applicationswidget->setMinimumSize(s_minimumsize); + m_tabbar->addTab(KIcon("applications-other"), i18n("Applications"), m_applicationswidget); + m_recentscrollwidget = new Plasma::ScrollWidget(m_tabbar); + m_recentscrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_recentscrollwidget->setMinimumSize(s_minimumsize); + m_recentwidget = new LauncherRecent(m_recentscrollwidget); + m_recentscrollwidget->setWidget(m_recentwidget); + m_tabbar->addTab(KIcon("document-open-recent"), i18n("Recently User"), m_recentscrollwidget); + m_leavecrollwidget = new Plasma::ScrollWidget(m_tabbar); + m_leavecrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_leavecrollwidget->setMinimumSize(s_minimumsize); + m_leavewidget = new LauncherLeave(m_leavecrollwidget); + m_leavecrollwidget->setWidget(m_leavewidget); + m_tabbar->addTab(KIcon("system-shutdown"), i18n("Leave"), m_leavecrollwidget); + m_layout->addItem(m_tabbar, 1, 0, 1, 3); + + m_searchscrollwidget = new Plasma::ScrollWidget(this); + m_searchscrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_searchscrollwidget->setMinimumSize(s_minimumsize); + m_searchscrollwidget->setVisible(false); + m_searchwidget = new LauncherSearch(m_searchscrollwidget); + m_searchscrollwidget->setWidget(m_searchwidget); + m_layout->addItem(m_searchscrollwidget, 2, 0, 1, 3); + connect( + m_lineedit, SIGNAL(textChanged(QString)), + this, SLOT(slotSearch(QString)) + ); + + m_timer = new QTimer(this); + m_timer->setSingleShot(true); + m_timer->setInterval(500); + connect( + m_timer, SIGNAL(timeout()), + this, SLOT(slotTimeout()) + ); + + setLayout(m_layout); + m_layout->setColumnStretchFactor(2, 100); +} + +void LauncherAppletWidget::slotSearch(const QString &text) +{ + const QString query = text.trimmed(); + if (query.isEmpty()) { + m_timer->stop(); + m_searchwidget->finish(); + m_searchscrollwidget->setVisible(false); + m_tabbar->setVisible(true); + return; + } + m_searchwidget->prepare(); + m_timer->start(); +} + +void LauncherAppletWidget::slotTimeout() +{ + m_searchwidget->query(m_lineedit->text()); + m_tabbar->setVisible(false); + m_searchscrollwidget->setVisible(true); +} + + +LauncherApplet::LauncherApplet(QObject *parent, const QVariantList &args) + : Plasma::PopupApplet(parent, args), + m_launcherwidget(nullptr) +{ + KGlobal::locale()->insertCatalog("plasma_applet_launcher"); + setPopupIcon(s_defaultpopupicon); + setAspectRatioMode(Plasma::IgnoreAspectRatio); + + m_launcherwidget = new LauncherAppletWidget(this); +} + +QGraphicsWidget *LauncherApplet::graphicsWidget() +{ + return m_launcherwidget; +} + +void LauncherApplet::popupEvent(bool show) +{ + if (show) { + m_launcherwidget->setFocus(); + } +} + +#include "launcher.moc" +#include "moc_launcher.cpp" diff --git a/plasma/applets/kickoff/ui/contentareacap.h b/plasma/applets/launcher/launcher.h similarity index 51% rename from plasma/applets/kickoff/ui/contentareacap.h rename to plasma/applets/launcher/launcher.h index 58b37ec7..64d2faa9 100644 --- a/plasma/applets/kickoff/ui/contentareacap.h +++ b/plasma/applets/launcher/launcher.h @@ -1,10 +1,10 @@ /* - Copyright 2008 Andrew Lake + This file is part of the KDE project + Copyright (C) 2024 Ivailo Monev This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + License version 2, as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,22 +17,30 @@ Boston, MA 02110-1301, USA. */ -#ifndef CONTENTAREACAP_H -#define CONTENTAREACAP_H +#ifndef LAUNCHER_H +#define LAUNCHER_H -#include +#include -class ContentAreaCap: public QWidget +class LauncherAppletWidget; + +class LauncherApplet : public Plasma::PopupApplet { Q_OBJECT - public: - ContentAreaCap(QWidget *parent, bool flip = false); + LauncherApplet(QObject *parent, const QVariantList &args); + + // Plasma::PopupApplet reimplementation + QGraphicsWidget* graphicsWidget() final; protected: - virtual void paintEvent(QPaintEvent *event); - bool flipCap; + void popupEvent(bool show) final; +private: + friend LauncherAppletWidget; + LauncherAppletWidget *m_launcherwidget; }; -#endif +K_EXPORT_PLASMA_APPLET(launcher, LauncherApplet) + +#endif // LAUNCHER_H diff --git a/plasma/applets/kickoff/applet/plasma-applet-launcher.desktop b/plasma/applets/launcher/plasma-applet-launcher.desktop similarity index 98% rename from plasma/applets/kickoff/applet/plasma-applet-launcher.desktop rename to plasma/applets/launcher/plasma-applet-launcher.desktop index e4e9a5e8..55de2b27 100644 --- a/plasma/applets/kickoff/applet/plasma-applet-launcher.desktop +++ b/plasma/applets/launcher/plasma-applet-launcher.desktop @@ -169,10 +169,10 @@ Type=Service X-KDE-ServiceTypes=Plasma/Applet X-KDE-Library=plasma_applet_launcher -X-KDE-PluginInfo-Author=Robert Knight -X-KDE-PluginInfo-Email=robertknight@gmail.com +X-KDE-PluginInfo-Author=Ivailo Monev +X-KDE-PluginInfo-Email=xakepa10@gmail.com X-KDE-PluginInfo-Name=launcher -X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Version=2.0 X-KDE-PluginInfo-Website= X-KDE-PluginInfo-Category=Application Launchers X-KDE-PluginInfo-Depends=