# # SVN commit 936481 by sebsauer: # # polishing # --- plasma/applets/kickoff/simpleapplet/menuview.cpp~ 2009-03-10 21:31:10.000000000 +0100 +++ plasma/applets/kickoff/simpleapplet/menuview.cpp 2009-03-10 22:11:34.000000000 +0100 @@ -23,10 +23,11 @@ // Qt #include <QtCore/QAbstractItemModel> +#include <QtCore/QPersistentModelIndex> #include <QtCore/QStack> #include <QtGui/QApplication> #include <QtGui/QMouseEvent> -#include <QtCore/QPersistentModelIndex> +#include <QtGui/QStandardItem> // KDE #include <KDebug> @@ -49,6 +50,7 @@ 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()); @@ -75,8 +77,9 @@ return action; } - void buildBranch(QMenu *menu, QAbstractItemModel *model, const QModelIndex& parent) { - int rowCount = model->rowCount(parent); + void buildBranch(KMenu *menu, QAbstractItemModel *model, const QModelIndex& parent) { + const int rowCount = model->rowCount(parent); + //if (rowCount > 0 && menu->actions().count() > 0) menu->addSeparator(); for (int i = 0; i < rowCount; i++) { QAction *action = createActionForIndex(model, model->index(i, column, parent), menu); menu->addAction(action); @@ -89,13 +92,19 @@ UrlItemLauncher *launcher; MenuView::FormatType formattype; QPoint mousePressPos; + QList<QStandardItem*> items; }; -MenuView::MenuView(QWidget *parent) +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); } @@ -119,20 +128,11 @@ } else { switch (d->formattype) { case Name: { - if (name.isEmpty()) { - action->setText(text); - } else { - action->setText(name); - } - } - break; + action->setText(name.isEmpty() ? text : name); + } break; case Description: { - if (name.contains(text, Qt::CaseInsensitive)) { - text = name; - } - action->setText(text); - } - break; + action->setText(name.contains(text, Qt::CaseInsensitive) ? name : text); + } break; case NameDescription: // fall through case NameDashDescription: // fall through case DescriptionName: { @@ -154,7 +154,7 @@ action->setText(text); } } - break; + } break; } } @@ -226,14 +226,18 @@ return KMenu::eventFilter(watched, event); } -void MenuView::addModel(QAbstractItemModel *model, bool mergeFirstLevel) +void MenuView::addModel(QAbstractItemModel *model, MenuView::ModelOptions options) { - if(mergeFirstLevel) { + 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<QString>(); + if (count > 1 && ! title.isEmpty()) + addTitle(title); + model->blockSignals(true); model->setData(index, qVariantFromValue(this->menuAction()), Private::ActionRole); model->blockSignals(false); @@ -250,6 +254,16 @@ 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; @@ -345,6 +359,9 @@ } */ #else + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); modelReset(); #endif } @@ -389,6 +406,9 @@ } */ #else + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); modelReset(); #endif } @@ -416,6 +436,8 @@ updateAction(model, actions[row], model->index(row, d->column, topLeft.parent())); } #else + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); modelReset(); #endif } @@ -449,9 +471,16 @@ void MenuView::actionTriggered(QAction *action) { - QModelIndex index = indexForAction(action); - Q_ASSERT(index.isValid()); - d->launcher->openItem(index); + KUrl url = action->data().value<KUrl>(); + 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="<<action->objectName()<<"text="<<action->text()<<"parent="<<(action->parent()?action->parent()->metaObject()->className():"NULL"); + } } #include "menuview.moc" --- plasma/applets/kickoff/simpleapplet/menuview.h~ 2009-03-10 22:14:18.000000000 +0100 +++ plasma/applets/kickoff/simpleapplet/menuview.h 2009-03-10 22:48:12.000000000 +0100 @@ -28,6 +28,7 @@ #include <KMenu> class QAbstractItemModel; +class QStandardItem; namespace Kickoff { @@ -54,12 +55,21 @@ public: /** Constructs a new menu with the specified @p parent */ - MenuView(QWidget *parent = 0); + MenuView(QWidget *parent = 0, const QString &title = QString(), const QIcon &icon = QIcon()); /** Destructor */ virtual ~MenuView(); - /** Sets the model displayed by this menu. */ - void addModel(QAbstractItemModel *model, bool mergeFirstLevel); + /// 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); + + /** 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; --- plasma/applets/kickoff/simpleapplet/simpleapplet.h~ 2009-03-10 22:14:18.000000000 +0100 +++ plasma/applets/kickoff/simpleapplet/simpleapplet.h 2009-03-10 23:03:06.000000000 +0100 @@ -34,7 +34,6 @@ { Q_OBJECT Q_ENUMS(ViewType) - Q_FLAGS(ViewTypes) Q_ENUMS(FormatType) public: @@ -54,10 +53,14 @@ SwitchUser, ///< Switch User Action SaveSession, ///< Save Session Action (only enabled if restoreSavedSession is enabled) LockScreen, ///< Lock Screen Action + Standby, ///< Standby Action + SuspendDisk, ///< Suspend to Disk Action + SuspendRAM, ///< Suspend to RAM Action + Restart, ///< Restart Action + Shutdown, ///< Shutdown Action Logout, ///< Logout Action Leave ///< Leave Menu }; - Q_DECLARE_FLAGS(ViewTypes, ViewType) /** * How the text of the menuitems got formatted. @@ -130,8 +133,6 @@ Private * const d; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(MenuLauncherApplet::ViewTypes) - K_EXPORT_PLASMA_APPLET(menulauncher, MenuLauncherApplet) #endif --- plasma/applets/kickoff/simpleapplet/menuview.cpp~ 2009-03-10 23:39:57.000000000 +0100 +++ plasma/applets/kickoff/simpleapplet/menuview.cpp 2009-03-10 23:59:54.000000000 +0100 @@ -153,7 +153,6 @@ } else { // if there is no name, let's just use the describing text action->setText(text); } - } } break; } } --- plasma/applets/kickoff/simpleapplet/simpleapplet.cpp.old 2009-04-01 22:59:08.000000000 +0200 +++ plasma/applets/kickoff/simpleapplet/simpleapplet.cpp 2009-04-01 23:22:34.000000000 +0200 @@ -54,6 +54,8 @@ #include <KCModuleInfo> #include <KToolInvocation> #include <KIconButton> +#include <kworkspace/kworkspace.h> +#include <solid/control/powermanager.h> // Plasma #include <Plasma/IconWidget> @@ -100,7 +102,7 @@ BookmarkOwner* bookmarkowner; KBookmarkMenu* bookmarkmenu; - QStringList viewtypes; + QStringList viewtypes;//QList<MenuLauncherApplet::ViewType> MenuLauncherApplet::FormatType formattype; int maxRecentApps; @@ -158,10 +160,15 @@ case RecentlyUsedApplications: return i18n("Recently Used Applications"); case RecentlyUsedDocuments: return i18n("Recently Used Documents"); case Settings: return i18n("System Settings"); - case RunCommand: return i18n("Run Command"); + case RunCommand: return i18n("Run Command..."); case SwitchUser: return i18n("Switch User"); case SaveSession: return i18n("Save Session"); - case LockScreen: return i18n("Lock Screen"); + case LockScreen: return i18n("Lock the screen"); + case Standby: return i18nc("Puts the system on standby", "Standby"); + case SuspendDisk: return i18n("Suspend to Disk"); + case SuspendRAM: return i18n("Suspend to RAM"); + case Restart: return i18n("Restart"); + case Shutdown: return i18n("Shutdown"); case Logout: return i18n("Logout"); case Leave: return i18n("Leave"); } @@ -181,25 +188,43 @@ case SwitchUser: return "system-switch-user"; case SaveSession: return "document-save"; case LockScreen: return "system-lock-screen"; + case Standby: return "system-suspend"; + case SuspendDisk: return "system-suspend-hibernate"; + case SuspendRAM: return "system-suspend-hibernate"; + case Restart: return "system-restart"; + case Shutdown: return "system-shutdown"; case Logout: return "system-log-out"; case Leave: return "system-shutdown"; } return QString(); } - /* - MenuLauncherApplet::ViewTypes viewTypes(const QByteArray& types) const { + MenuLauncherApplet::ViewType viewType(const QByteArray& type) const { QMetaEnum e = q->metaObject()->enumerator(q->metaObject()->indexOfEnumerator("ViewType")); - return (MenuLauncherApplet::ViewTypes) e.keyToValue(types); + return (MenuLauncherApplet::ViewType) e.keyToValue(type); } + /* QByteArray viewTypes(MenuLauncherApplet::ViewTypes types) const { QMetaEnum e = q->metaObject()->enumerator(q->metaObject()->indexOfEnumerator("ViewType")); - return e.valueToKeys(types); + return e.valueToKey(types); + } + QList<MenuLauncherApplet::ViewType> viewTypes(const QStringList &types) const { + QList<MenuLauncherApplet::ViewType> l; + foreach(QString t, types) l << viewType(t.toUtf()); + return l; + } + QStringList viewTypes(const QList<MenuLauncherApplet::ViewType> &types) const { + QStringList l; + foreach(MenuLauncherApplet::ViewType t, types) l << viewType(t); + return l; } */ void updateTooltip() { - Plasma::ToolTipContent data(i18n("Classic Application Launcher"), i18n("Traditional menu based application launcher"), icon->icon()); + QStringList names; + foreach(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); } }; @@ -221,7 +246,7 @@ connect(d->icon, SIGNAL(pressed(bool)), this, SLOT(toggleMenu(bool))); connect(this, SIGNAL(activate()), this, SLOT(toggleMenu())); - d->viewtypes << "RecentlyUsedApplications" << "Applications" << "Favorites" << "RunCommand" << "SwitchUser" << "SaveSession" << "LockScreen" << "Logout"; + d->viewtypes << "RecentlyUsedApplications" << "Applications" << "Favorites" << "RunCommand" << "Leave"; d->formattype = NameDescription; QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this); @@ -243,12 +268,10 @@ QStringList viewtypes = cg.readEntry("views", QStringList()); if(viewtypes.isEmpty()) { // backward-compatibility to <KDE4.3 QByteArray oldview = cg.readEntry("view", QByteArray()); - if(oldview == "Combined") { - d->viewtypes = QStringList() << "Applications" << "Favorites" << "RunCommand" << "SwitchUser" << "SaveSession" << "LockScreen" << "Logout"; - } else if(! oldview.isEmpty()) { + if (!oldview.isEmpty() && oldview != "Combined") { d->viewtypes = QStringList() << oldview; - iconname = d->viewIcon( (MenuLauncherApplet::ViewType) metaObject()->enumerator(metaObject()->indexOfEnumerator("ViewType")).keyToValue(oldview) ); - } + iconname = d->viewIcon(d->viewType(oldview)); + } // else we use the default d->viewtypes } else { d->viewtypes = viewtypes; } @@ -343,9 +366,10 @@ d->view = new QListWidget(viewpage); d->view->resize(300,500); l->addWidget(d->view); - foreach(ViewType vt, QList<ViewType>()<<RecentlyUsedApplications<<RecentlyUsedDocuments<<Applications<<Favorites<<Bookmarks<<Computer<<RecentlyUsed<<Settings<<RunCommand<<SwitchUser<<SaveSession<<LockScreen<<Logout<<Leave) { - QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("ViewType")); - QByteArray vtname = e.valueToKey(vt); + 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); @@ -411,6 +435,7 @@ d->viewtypes = viewtypes; d->updateTooltip(); cg.writeEntry("views", d->viewtypes); + } const QString iconname = d->iconButton->icon(); if (! iconname.isEmpty()) { @@ -461,15 +486,23 @@ void MenuLauncherApplet::toggleMenu(bool pressed) { - if (! pressed) { + if (!pressed || d->viewtypes.count()<=0) { + if (d->menuview) + d->menuview->deleteLater(); return; } + + d->icon->setPressed(); + if (!d->menuview) { d->menuview = new Kickoff::MenuView(); + d->menuview->setAttribute(Qt::WA_DeleteOnClose); d->menuview->setFormatType( (Kickoff::MenuView::FormatType) d->formattype ); connect(d->menuview, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); connect(d->menuview, SIGNAL(aboutToHide()), d->icon, SLOT(setUnpressed())); //connect(d->menuview, SIGNAL(afterBeingHidden()), d->menuview, SLOT(deleteLater())); + + Kickoff::MenuView::ModelOptions options = d->viewtypes.count() < 2 ? Kickoff::MenuView::MergeFirstLevel : Kickoff::MenuView::None; foreach(QString vtname, d->viewtypes) { if(vtname == "Applications") { if(d->menuview->actions().count() > 0) @@ -479,27 +512,27 @@ if (d->formattype == Name || d->formattype == NameDescription || d->formattype == NameDashDescription) appModel->setPrimaryNamePolicy(Kickoff::ApplicationModel::AppNamePrimary); appModel->setSystemApplicationPolicy(Kickoff::ApplicationModel::ShowApplicationAndSystemPolicy); - d->menuview->addModel(appModel, false); + d->menuview->addModel(appModel); } else if(vtname == "Favorites") { if(d->menuview->actions().count() > 0) d->menuview->addSeparator(); - d->menuview->addModel(new Kickoff::FavoritesModel(d->menuview), d->viewtypes.count() < 2); + d->menuview->addModel(new Kickoff::FavoritesModel(d->menuview), options); } else if(vtname == "Computer") { - d->menuview->addModel(new Kickoff::SystemModel(d->menuview), d->viewtypes.count() < 2); + d->menuview->addModel(new Kickoff::SystemModel(d->menuview), options); } else if(vtname == "RecentlyUsed") { - d->menuview->addModel(new Kickoff::RecentlyUsedModel(d->menuview), d->viewtypes.count() < 2); + d->menuview->addModel(new Kickoff::RecentlyUsedModel(d->menuview), options); } else if(vtname == "RecentlyUsedApplications") { if(d->menuview->actions().count() > 0) d->menuview->addSeparator(); if (d->maxRecentApps > 0) - d->menuview->addModel(new Kickoff::RecentlyUsedModel(d->menuview, Kickoff::RecentlyUsedModel::ApplicationsOnly, d->maxRecentApps), true); + d->menuview->addModel(new Kickoff::RecentlyUsedModel(d->menuview, Kickoff::RecentlyUsedModel::ApplicationsOnly, d->maxRecentApps), Kickoff::MenuView::MergeFirstLevel); } else if(vtname == "RecentlyUsedDocuments") { if(d->menuview->actions().count() > 0) d->menuview->addSeparator(); - d->menuview->addModel(new Kickoff::RecentlyUsedModel(d->menuview, Kickoff::RecentlyUsedModel::DocumentsOnly), true); + d->menuview->addModel(new Kickoff::RecentlyUsedModel(d->menuview, Kickoff::RecentlyUsedModel::DocumentsOnly), Kickoff::MenuView::MergeFirstLevel); } else if(vtname == "Bookmarks") { KMenu* menu = d->menuview; - if(d->viewtypes.count() >= 2) { + if(d->viewtypes.count() > 1) { menu = new KMenu(d->viewText(Bookmarks), d->menuview); menu->setIcon(KIcon(d->viewIcon(Bookmarks))); d->menuview->addMenu(menu); @@ -513,7 +546,7 @@ d->bookmarkmenu = new KBookmarkMenu(mgr, d->bookmarkowner, menu, d->bookmarkcollection); } else if(vtname == "Settings") { KMenu* parentmenu = d->menuview; - if(d->viewtypes.count() >= 2) { + if(d->viewtypes.count() > 1) { parentmenu = new KMenu(d->viewText(Settings), d->menuview); parentmenu->setIcon(KIcon(d->viewIcon(Settings))); d->menuview->addMenu(parentmenu); @@ -556,8 +589,7 @@ m->addTitle(subcategory->name().replace('&',"&&")); foreach(KService::Ptr entry, modules[category]) { KCModuleInfo module(entry->entryPath()); - QAction* a = m->addAction(KIcon(module.icon()), module.moduleName().replace('&',"&&")); - a->setData(KUrl("kcm:/" + entry->entryPath())); + m->addAction(KIcon(module.icon()), module.moduleName().replace('&',"&&"))->setData(KUrl("kcm:/" + entry->entryPath())); } } } else if(vtname == "RunCommand") { @@ -566,27 +598,48 @@ d->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") { + if (c.readEntry("loginMode") == "restoreSavedSession") d->menuview->addAction(KIcon(d->viewIcon(SaveSession)), d->viewText(SaveSession))->setData(KUrl("leave:/savesession")); - } } else if(vtname == "LockScreen") { d->menuview->addAction(KIcon(d->viewIcon(LockScreen)), d->viewText(LockScreen))->setData(KUrl("leave:/lock")); } else if(vtname == "Logout") { d->menuview->addAction(KIcon(d->viewIcon(Logout)), d->viewText(Logout))->setData(KUrl("leave:/logout")); } else if(vtname == "Leave") { - if(d->menuview->actions().count() > 0) - d->menuview->addSeparator(); - Kickoff::LeaveModel *leavemodel = new Kickoff::LeaveModel(d->menuview); + Kickoff::MenuView* parentmenu = d->menuview; + if(d->viewtypes.count() > 1) { + parentmenu = new Kickoff::MenuView(d->menuview, d->viewText(Leave), KIcon(d->viewIcon(Leave))); + parentmenu->setFormatType(Kickoff::MenuView::Description); + d->menuview->addMenu(parentmenu); + } + Kickoff::LeaveModel *leavemodel = new Kickoff::LeaveModel(parentmenu); leavemodel->updateModel(); - d->menuview->addModel(leavemodel, true); + parentmenu->addModel(leavemodel, Kickoff::MenuView::MergeFirstLevel); + } else { +#ifndef Q_WS_WIN + Solid::Control::PowerManager::SuspendMethods spdMethods = Solid::Control::PowerManager::supportedSuspendMethods(); + if(vtname == "Standby") { + if (spdMethods & Solid::Control::PowerManager::Standby) + d->menuview->addAction(KIcon(d->viewIcon(Standby)), d->viewText(Standby))->setData(KUrl("leave:/standby")); + } else if(vtname == "SuspendDisk") { + if (spdMethods & Solid::Control::PowerManager::ToDisk) + d->menuview->addAction(KIcon(d->viewIcon(SuspendDisk)), d->viewText(SuspendDisk))->setData(KUrl("leave:/suspenddisk")); + } else if(vtname == "SuspendRAM") { + if (spdMethods & Solid::Control::PowerManager::ToRam) + d->menuview->addAction(KIcon(d->viewIcon(SuspendRAM)), d->viewText(SuspendRAM))->setData(KUrl("leave:/suspendram")); + } else if(vtname == "Restart") { + if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot)) + d->menuview->addAction(KIcon(d->viewIcon(Restart)), d->viewText(Restart))->setData(KUrl("leave:/restart")); + } else if(vtname == "Shutdown") { + if (KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt)) + d->menuview->addAction(KIcon(d->viewIcon(Shutdown)), d->viewText(Shutdown))->setData(KUrl("leave:/shutdown")); + } +#endif } } } Plasma::ToolTipManager::self()->hide(this); - d->menuview->setAttribute(Qt::WA_DeleteOnClose); d->menuview->popup(popupPosition(d->menuview->sizeHint())); - d->icon->setPressed(); } void MenuLauncherApplet::actionTriggered(QAction *action)