• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Applets

simpleapplet.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2007 Robert Knight <robertknight@gmail.com>
00003     Copyright 2008 Sebastian Sauer <mail@dipe.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 // Own
00022 #include "simpleapplet/simpleapplet.h"
00023 #include "simpleapplet/menuview.h"
00024 
00025 // Qt
00026 #include <QLabel>
00027 #include <QComboBox>
00028 #include <QGridLayout>
00029 #include <QGraphicsView>
00030 #include <QMetaObject>
00031 #include <QMetaEnum>
00032 #include <QPointer>
00033 #include <QGraphicsLinearLayout>
00034 
00035 // KDE
00036 #include <KIcon>
00037 #include <KConfigDialog>
00038 #include <KMenu>
00039 #include <KProcess>
00040 
00041 // Plasma
00042 #include <plasma/widgets/icon.h>
00043 #include <plasma/containment.h>
00044 
00045 // Local
00046 #include "core/itemhandlers.h"
00047 #include "core/models.h"
00048 #include "core/applicationmodel.h"
00049 #include "core/favoritesmodel.h"
00050 #include "core/systemmodel.h"
00051 #include "core/recentlyusedmodel.h"
00052 #include "core/leavemodel.h"
00053 #include "core/urlitemlauncher.h"
00054 
00056 class MenuLauncherApplet::Private
00057 {
00058 public:
00059         QPointer<Kickoff::MenuView> menuview;
00060         Plasma::Icon *icon;
00061         QPointer<Kickoff::UrlItemLauncher> launcher;
00062 
00063         MenuLauncherApplet::ViewType viewtype;
00064         MenuLauncherApplet::FormatType formattype;
00065 
00066         QComboBox *viewComboBox, *formatComboBox;
00067 
00068         QList<QAction*> actions;
00069         QAction* switcher;
00070 
00071         Private() : menuview(0), launcher(0), switcher(0) {}
00072         ~Private() { delete menuview; }
00073 
00074         void addItem(QComboBox* combo, const QString& caption, int index, const QString& icon = QString()) {
00075             if( icon.isNull() ) {
00076                 combo->addItem(caption, index);
00077             }
00078             else {
00079                 combo->addItem(KIcon(icon), caption, index);
00080             }
00081         }
00082 
00083         void setCurrentItem(QComboBox* combo, int currentIndex) {
00084             for(int i = combo->count() - 1; i >= 0; --i) {
00085                 if( combo->itemData(i).toInt() == currentIndex ) {
00086                     combo->setCurrentIndex(i);
00087                     return;
00088                 }
00089             }
00090             if( combo->count() > 0 ) {
00091                 combo->setCurrentIndex(0);
00092             }
00093         }
00094 
00095         Kickoff::MenuView *createMenuView(QAbstractItemModel *model = 0) {
00096             Kickoff::MenuView *view = new Kickoff::MenuView(menuview);
00097             view->setFormatType( (Kickoff::MenuView::FormatType) formattype );
00098             if( model ) {
00099                 view->setModel(model);
00100             }
00101             return view;
00102         }
00103 
00104         void addMenu(Kickoff::MenuView *view, bool mergeFirstLevel) {
00105             QList<QAction*> actions = view->actions();
00106             foreach(QAction *action, actions) {
00107                 if( action->menu() && mergeFirstLevel ) {
00108                     QMetaObject::invokeMethod(action->menu(),"aboutToShow"); //fetch the children
00109                     if( actions.count() > 1 && action->menu()->actions().count() > 0 ) {
00110                         menuview->addTitle(action->text());
00111                     }
00112                     foreach(QAction *a, action->menu()->actions()) {
00113                         a->setVisible(a->menu() || ! view->indexForAction(a).data(Kickoff::UrlRole).isNull());
00114                         menuview->addAction(a);
00115                     }
00116                 }
00117                 else {
00118                     action->setVisible(action->menu() || ! view->indexForAction(action).data(Kickoff::UrlRole).isNull());
00119                     menuview->addAction(action);
00120                 }
00121             }
00122 
00123             // if the model asks us for a reset we can't do much except to invalidate our
00124             // menuview to be able to rebuild it what is needed to prevent dealing with
00125             // invalid items.
00126             // the problem here is, that if the menu is currently displayed, it will just
00127             // close itself what is evil++ but still better then crashes. anyway, the
00128             // right(TM) solution would be to introduce logic to update the content of the
00129             // menu even on a reset.
00130             connect(view->model(), SIGNAL(modelReset()), menuview, SLOT(deleteLater()));
00131         }
00132 
00133         QString viewIcon() {
00134             switch( viewtype ) {
00135                 case Combined:
00136                     return "start-here-kde";
00137                 case Favorites:
00138                     return "bookmarks";
00139                 case Applications:
00140                     return "applications-other";
00141                 case Computer:
00142                     return "computer";
00143                 case RecentlyUsed:
00144                     return "document-open-recent";
00145                 case Leave:
00146                     return "application-exit";
00147             }
00148             return QString();
00149         }
00150 
00151 };
00152 
00153 MenuLauncherApplet::MenuLauncherApplet(QObject *parent, const QVariantList &args)
00154     : Plasma::Applet(parent,args),
00155       d(new Private)
00156 {
00157     KGlobal::locale()->insertCatalog("plasma_applet_launcher");
00158 
00159     setHasConfigurationInterface(true);
00160     setBackgroundHints(NoBackground);
00161 
00162     d->icon = new Plasma::Icon(QString(), this);
00163     d->icon->setFlag(ItemIsMovable, false);
00164     connect(d->icon, SIGNAL(pressed(bool)), this, SLOT(toggleMenu(bool)));
00165     connect(this, SIGNAL(activate()), this, SLOT(toggleMenu()));
00166 
00167     d->viewtype = Combined;
00168     d->formattype = NameDescription;
00169     
00170     resize(d->icon->sizeFromIconSize(IconSize(KIconLoader::Desktop)));
00171 }
00172 
00173 MenuLauncherApplet::~MenuLauncherApplet()
00174 {
00175     delete d;
00176 }
00177 
00178 void MenuLauncherApplet::init()
00179 {
00180     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
00181     layout->setContentsMargins(0, 0, 0, 0);
00182     layout->setSpacing(0);
00183 
00184     layout->addItem(d->icon);
00185 
00186     KConfigGroup cg = config();
00187 
00188     {
00189         QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("ViewType"));
00190         QByteArray ba = cg.readEntry("view", QByteArray(e.valueToKey(d->viewtype)));
00191         d->viewtype = (MenuLauncherApplet::ViewType) e.keyToValue(ba);
00192     }
00193     {
00194         QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("FormatType"));
00195         QByteArray ba = cg.readEntry("format", QByteArray(e.valueToKey(d->formattype)));
00196         d->formattype = (MenuLauncherApplet::FormatType) e.keyToValue(ba);
00197     }
00198 
00199     d->icon->setIcon(KIcon(d->viewIcon()));
00200     //d->icon->setIcon(KIcon(cg.readEntry("icon","start-here-kde")));
00201     //setMinimumContentSize(d->icon->iconSize()); //setSize(d->icon->iconSize())
00202 
00203     setAspectRatioMode(Plasma::ConstrainedSquare);
00204 
00205     Kickoff::UrlItemLauncher::addGlobalHandler(Kickoff::UrlItemLauncher::ExtensionHandler,"desktop",new Kickoff::ServiceItemHandler);
00206     Kickoff::UrlItemLauncher::addGlobalHandler(Kickoff::UrlItemLauncher::ProtocolHandler, "leave", new Kickoff::LeaveItemHandler);
00207 
00208     if (KService::serviceByStorageId("kde4-kmenuedit.desktop")) {
00209         QAction* menueditor = new QAction(i18n("Menu Editor"), this);
00210         d->actions.append(menueditor);
00211         connect(menueditor, SIGNAL(triggered(bool)), this, SLOT(startMenuEditor()));
00212     }
00213 
00214     Q_ASSERT( ! d->switcher );
00215     d->switcher = new QAction(i18n("Switch to Kickoff Menu Style"), this);
00216     d->actions.append(d->switcher);
00217     connect(d->switcher, SIGNAL(triggered(bool)), this, SLOT(switchMenuStyle()));
00218 
00219     constraintsEvent(Plasma::ImmutableConstraint);
00220 }
00221 
00222 void MenuLauncherApplet::constraintsEvent(Plasma::Constraints constraints)
00223 {
00224     setBackgroundHints(NoBackground);
00225     if (constraints & Plasma::FormFactorConstraint) {
00226         if (formFactor() == Plasma::Planar ||
00227             formFactor() == Plasma::MediaCenter) {
00228             //FIXME set correct minimum size
00229             //setMinimumContentSize(d->icon->sizeFromIconSize(IconSize(KIconLoader::Desktop)));
00230         } else {
00231             //setMinimumContentSize(d->icon->sizeFromIconSize(IconSize(KIconLoader::Small)));
00232         }
00233     }
00234 
00235     if (constraints & Plasma::ImmutableConstraint) {
00236         d->switcher->setVisible(immutability() == Plasma::Mutable);
00237     }
00238 }
00239 
00240 void MenuLauncherApplet::switchMenuStyle()
00241 {
00242     if (containment()) {
00243         containment()->addApplet("launcher", QVariantList(), geometry());
00244         destroy();
00245     }
00246 }
00247 
00248 void MenuLauncherApplet::startMenuEditor()
00249 {
00250     KProcess::execute("kmenuedit");
00251 }
00252 
00253 void MenuLauncherApplet::createConfigurationInterface(KConfigDialog *parent)
00254 {
00255     QWidget *p = new QWidget;
00256     QGridLayout *l = new QGridLayout(p);
00257     p->setLayout(l);
00258 
00259     QLabel *viewLabel = new QLabel(i18nc("@label:listbox Which category of items to view in a KMenu-like menu", "View:"), p);
00260     l->addWidget(viewLabel, 0, 0);
00261     d->viewComboBox = new QComboBox(p);
00262     viewLabel->setBuddy(d->viewComboBox);
00263     d->addItem(d->viewComboBox, i18nc("@item:inlistbox View:", "Standard"), MenuLauncherApplet::Combined, "start-here-kde");
00264     d->addItem(d->viewComboBox, i18nc("@item:inlistbox View:", "Favorites"), MenuLauncherApplet::Favorites, "bookmarks");
00265     d->addItem(d->viewComboBox, i18nc("@item:inlistbox View:", "Applications"), MenuLauncherApplet::Applications, "applications-other");
00266     d->addItem(d->viewComboBox, i18nc("@item:inlistbox View:", "Computer"), MenuLauncherApplet::Computer, "computer");
00267     d->addItem(d->viewComboBox, i18nc("@item:inlistbox View:", "Recently Used"), MenuLauncherApplet::RecentlyUsed, "document-open-recent");
00268     d->addItem(d->viewComboBox, i18nc("@item:inlistbox View:", "Leave"), MenuLauncherApplet::Leave, "application-exit");
00269     l->addWidget(d->viewComboBox, 0, 1);
00270 
00271     QLabel *formatLabel = new QLabel(i18nc("@label:listbox How to present applications in a KMenu-like menu", "Format:"), p);
00272     l->addWidget(formatLabel, 1, 0);
00273     d->formatComboBox = new QComboBox(p);
00274     formatLabel->setBuddy(d->formatComboBox);
00275     d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name Only"), MenuLauncherApplet::Name);
00276     d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Description Only"), MenuLauncherApplet::Description);
00277     d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name Description"), MenuLauncherApplet::NameDescription);
00278     d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Description (Name)"), MenuLauncherApplet::DescriptionName);
00279     l->addWidget(d->formatComboBox, 1, 1);
00280 
00281     l->setColumnStretch(1,1);
00282 
00283     d->setCurrentItem(d->viewComboBox, d->viewtype);
00284     d->setCurrentItem(d->formatComboBox, d->formattype);
00285 
00286     parent->setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Apply);
00287     connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
00288     connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
00289     parent->addPage(p, parent->windowTitle(), icon());
00290 }
00291 
00292 void MenuLauncherApplet::configAccepted()
00293 {
00294     bool needssaving = false;
00295     KConfigGroup cg = config();
00296 
00297     int vt = d->viewComboBox->itemData(d->viewComboBox->currentIndex()).toInt();
00298     if( vt != d->viewtype ) {
00299         d->viewtype = (MenuLauncherApplet::ViewType) vt;
00300         needssaving = true;
00301 
00302         QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("ViewType"));
00303         cg.writeEntry("view", QByteArray(e.valueToKey(d->viewtype)));
00304 
00305         d->icon->setIcon(KIcon(d->viewIcon()));
00306         d->icon->update();
00307     }
00308 
00309     int ft = d->formatComboBox->itemData(d->formatComboBox->currentIndex()).toInt();
00310     if( ft != d->formattype ) {
00311         d->formattype = (MenuLauncherApplet::FormatType) ft;
00312         needssaving = true;
00313 
00314         QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("FormatType"));
00315         cg.writeEntry("format", QByteArray(e.valueToKey(d->formattype)));
00316     }
00317 
00318     if( needssaving ) {
00319         emit configNeedsSaving();
00320 
00321         delete d->menuview;
00322         d->menuview = 0;
00323     }
00324 }
00325 
00326 void MenuLauncherApplet::toggleMenu(bool pressed)
00327 {
00328     if (pressed) {
00329         toggleMenu();
00330     }
00331 }
00332 
00333 void MenuLauncherApplet::toggleMenu()
00334 {
00335     if (!d->menuview) {
00336         d->menuview = new Kickoff::MenuView();
00337         connect(d->menuview, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*)));
00338         connect(d->menuview, SIGNAL(aboutToHide()), d->icon, SLOT(setUnpressed()));
00339         connect(d->menuview, SIGNAL(aboutToHide()), d->menuview, SLOT(deleteLater()));
00340 
00341         switch( d->viewtype ) {
00342             case Combined: {
00343                 Kickoff::ApplicationModel *appModel = new Kickoff::ApplicationModel(d->menuview);
00344                 appModel->setDuplicatePolicy(Kickoff::ApplicationModel::ShowLatestOnlyPolicy);
00345                 Kickoff::MenuView *appview = d->createMenuView(appModel);
00346                 d->addMenu(appview, false);
00347 
00348                 d->menuview->addSeparator();
00349                 Kickoff::MenuView *favview = d->createMenuView(new Kickoff::FavoritesModel(d->menuview));
00350                 d->addMenu(favview, false);
00351 
00352                 d->menuview->addSeparator();
00353                 QAction *switchaction = d->menuview->addAction(KIcon("system-switch-user"),i18n("Switch User"));
00354                 switchaction->setData(KUrl("leave:/switch"));
00355                 QAction *lockaction = d->menuview->addAction(KIcon("system-lock-screen"),i18n("Lock"));
00356                 lockaction->setData(KUrl("leave:/lock"));
00357                 QAction *logoutaction = d->menuview->addAction(KIcon("system-shutdown"),i18n("Leave"));
00358                 logoutaction->setData(KUrl("leave:/logout"));
00359             } break;
00360             case Favorites: {
00361                 Kickoff::MenuView *favview = d->createMenuView(new Kickoff::FavoritesModel(d->menuview));
00362                 d->addMenu(favview, true);
00363             } break;
00364             case Applications: {
00365                 Kickoff::ApplicationModel *appModel = new Kickoff::ApplicationModel(d->menuview);
00366                 appModel->setDuplicatePolicy(Kickoff::ApplicationModel::ShowLatestOnlyPolicy);
00367                 Kickoff::MenuView *appview = d->createMenuView(appModel);
00368                 d->addMenu(appview, false);
00369             } break;
00370             case Computer: {
00371                 Kickoff::MenuView *systemview = d->createMenuView(new Kickoff::SystemModel(d->menuview));
00372                 d->addMenu(systemview, true);
00373             } break;
00374             case RecentlyUsed: {
00375                 Kickoff::MenuView *recentlyview = d->createMenuView(new Kickoff::RecentlyUsedModel(d->menuview));
00376                 d->addMenu(recentlyview, true);
00377             } break;
00378             case Leave: {
00379                 Kickoff::MenuView *leaveview = d->createMenuView(new Kickoff::LeaveModel(d->menuview));
00380                 d->addMenu(leaveview, true);
00381             } break;
00382         }
00383     }
00384 
00385     d->menuview->setAttribute(Qt::WA_DeleteOnClose);
00386     d->menuview->popup(popupPosition(d->menuview->sizeHint()));
00387     d->icon->setPressed();
00388 }
00389 
00390 void MenuLauncherApplet::actionTriggered(QAction *action)
00391 {
00392     KUrl url = action->data().value<KUrl>();
00393     if (url.scheme() == "leave") {
00394         if ( ! d->launcher ) {
00395             d->launcher = new Kickoff::UrlItemLauncher(d->menuview);
00396         }
00397         d->launcher->openUrl(url.url());
00398         return;
00399     }
00400     for(QWidget* w = action->parentWidget(); w; w = w->parentWidget()) {
00401         if (Kickoff::MenuView *view = dynamic_cast<Kickoff::MenuView*>(w)) {
00402             view->actionTriggered(action);
00403             break;
00404         }
00405     }
00406 }
00407 
00408 QList<QAction*> MenuLauncherApplet::contextualActions()
00409 {
00410     return d->actions;
00411 }
00412 
00413 #include "simpleapplet.moc"

Applets

Skip menu "Applets"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal