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

Applets

launcher.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2007 Robert Knight <robertknight@gmail.com>
00003     Copyright 2007 Kevin Ottens <ervin@kde.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 #include "ui/launcher.h"
00022 
00023 // System
00024 #include <unistd.h>
00025 
00026 // Qt
00027 #include <QApplication>
00028 #include <QKeyEvent>
00029 #include <QLabel>
00030 #include <QMouseEvent>
00031 #include <QPainter>
00032 #include <QStackedWidget>
00033 #include <QTabBar>
00034 #include <QToolButton>
00035 #include <QVBoxLayout>
00036 #include <QStyleOptionSizeGrip>
00037 
00038 // KDE
00039 #include <KDebug>
00040 #include <KLocalizedString>
00041 #include <KIcon>
00042 #include <KStandardDirs>
00043 #include <kuser.h>
00044 #include <Plasma/Theme>
00045 #include <Plasma/Delegate>
00046 #include <solid/device.h>
00047 #include <solid/deviceinterface.h>
00048 #include <KColorScheme>
00049 
00050 // Local
00051 #include "core/favoritesmodel.h"
00052 #include "core/recentlyusedmodel.h"
00053 #include "core/applicationmodel.h"
00054 #include "core/leavemodel.h"
00055 #include "core/itemhandlers.h"
00056 #include "core/searchmodel.h"
00057 #include "core/systemmodel.h"
00058 
00059 #include "ui/itemdelegate.h"
00060 #include "ui/brandingbutton.h"
00061 #include "ui/contextmenufactory.h"
00062 #include "ui/urlitemview.h"
00063 #include "ui/flipscrollview.h"
00064 #include "ui/searchbar.h"
00065 #include "ui/tabbar.h"
00066 #include "ui/contentareacap.h"
00067 
00068 using namespace Kickoff;
00069 
00070 class Launcher::Private
00071 {
00072 public:
00073     Private(Launcher *launcher)
00074             : q(launcher)
00075             , applet(0)
00076             , urlLauncher(new UrlItemLauncher(launcher))
00077             , searchModel(0)
00078             , leaveModel(0)
00079             , searchBar(0)
00080             , footer(0)
00081             , contentAreaHeader(0)
00082             , contentArea(0)
00083             , contentAreaFooter(0)
00084             , contentSwitcher(0)
00085             , searchView(0)
00086             , favoritesView(0)
00087             , contextMenuFactory(0)
00088             , autoHide(false)
00089             , visibleItemCount(10)
00090             , placement(Plasma::TopPosedLeftAlignedPopup)
00091             , panelEdge(Plasma::BottomEdge) {
00092     }
00093 
00094     ~Private() {
00095     }
00096 
00097     enum TabOrder { NormalTabOrder, ReverseTabOrder };
00098 
00099     void setupEventHandler(QAbstractItemView *view) {
00100         view->viewport()->installEventFilter(q);
00101         view->installEventFilter(q);
00102     }
00103 
00104     void addView(const QString& name, const QIcon& icon,
00105                  QAbstractItemModel *model = 0, QAbstractItemView *view = 0) {
00106         view->setFrameStyle(QFrame::NoFrame);
00107         // prevent the view from stealing focus from the search bar
00108         view->setFocusPolicy(Qt::NoFocus);
00109         view->setContextMenuPolicy(Qt::CustomContextMenu);
00110         view->setSelectionMode(QAbstractItemView::SingleSelection);
00111         view->setDragEnabled(true);
00112         view->setAcceptDrops(true);
00113         view->setDropIndicatorShown(true);
00114         if (name == "Favorites") {
00115             view->setDragDropMode(QAbstractItemView::DragDrop);
00116         } else if(name == "Applications" || name == "Computer" ||
00117                   name == "Recently Used") {
00118             view->setDragDropMode(QAbstractItemView::DragOnly);
00119         }
00120         view->setModel(model);
00121         //view->setCurrentIndex(QModelIndex());
00122         setupEventHandler(view);
00123 
00124         connect(view, SIGNAL(customContextMenuRequested(QPoint)), q, SLOT(showViewContextMenu(QPoint)));
00125 
00126         contentSwitcher->addTab(icon, name);
00127         contentArea->addWidget(view);
00128     }
00129 
00130     void initTabs() {
00131         // Favorites view
00132         setupFavoritesView();
00133 
00134         // All Programs view
00135         setupAllProgramsView();
00136 
00137         // System view
00138         setupSystemView();
00139 
00140         // Recently Used view
00141         setupRecentView();
00142 
00143         // Leave view
00144         setupLeaveView();
00145 
00146         // Search Bar
00147         setupSearchView();
00148     }
00149 
00150     void setupLeaveView() {
00151         leaveModel = new LeaveModel(q);
00152         leaveModel->updateModel();
00153         UrlItemView *view = new UrlItemView();
00154         ItemDelegate *delegate = new ItemDelegate(q);
00155         delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole);
00156         delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00157         view->setItemDelegate(delegate);
00158         view->setItemStateProvider(delegate);
00159         addView(i18n("Leave"), KIcon("system-shutdown"), leaveModel, view);
00160     }
00161 
00162     void setupFavoritesView() {
00163         FavoritesModel *model = new FavoritesModel(q);
00164         UrlItemView *view = new UrlItemView();
00165         ItemDelegate *delegate = new ItemDelegate(q);
00166         delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole);
00167         delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00168         view->setItemDelegate(delegate);
00169         view->setItemStateProvider(delegate);
00170         addView(i18n("Favorites"), KIcon("bookmarks"), model, view);
00171 
00172         QAction *sortAscendingAction = new QAction(KIcon("view-sort-ascending"), 
00173                                                    i18n("Sort Alphabetically (A to Z)"), q);
00174 
00175         QAction *sortDescendingAction = new QAction(KIcon("view-sort-descending"), 
00176                                                     i18n("Sort Alphabetically (Z to A)"), q);  
00177 
00178 
00179         connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), q, SLOT(focusFavoritesView()));
00180         connect(sortAscendingAction, SIGNAL(triggered()), model, SLOT(sortFavoritesAscending()));
00181         connect(sortDescendingAction, SIGNAL(triggered()), model, SLOT(sortFavoritesDescending()));
00182 
00183         favoritesView = view;
00184         QList<QAction*> actions;
00185         actions << sortAscendingAction << sortDescendingAction;
00186         contextMenuFactory->setViewActions(view, actions);
00187     }
00188 
00189     void setupAllProgramsView() {
00190         ApplicationModel *applicationModel = new ApplicationModel(q);
00191         applicationModel->setDuplicatePolicy(ApplicationModel::ShowLatestOnlyPolicy);
00192 
00193         applicationView = new FlipScrollView();
00194         ItemDelegate *delegate = new ItemDelegate(q);
00195         delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole);
00196         delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00197         applicationView->setItemDelegate(delegate);
00198 
00199         addView(i18n("Applications"), KIcon("applications-other"),
00200                 applicationModel, applicationView);
00201     }
00202 
00203     void setupRecentView() {
00204         RecentlyUsedModel *model = new RecentlyUsedModel(q);
00205         UrlItemView *view = new UrlItemView();
00206         ItemDelegate *delegate = new ItemDelegate(q);
00207         delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole);
00208         delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00209         view->setItemDelegate(delegate);
00210         view->setItemStateProvider(delegate);
00211         addView(i18n("Recently Used"), KIcon("document-open-recent"), model, view);
00212 
00213         QAction *clearApplications = new QAction(KIcon("edit-clear-history"), i18n("Clear Recent Applications"), q);
00214         QAction *clearDocuments = new QAction(KIcon("edit-clear-history"), i18n("Clear Recent Documents"), q);
00215 
00216         connect(clearApplications, SIGNAL(triggered()), model, SLOT(clearRecentApplications()));
00217         connect(clearDocuments, SIGNAL(triggered()), model, SLOT(clearRecentDocuments()));
00218 
00219         contextMenuFactory->setViewActions(view, QList<QAction*>() << clearApplications << clearDocuments);
00220     }
00221 
00222     void setupSystemView() {
00223         SystemModel *model = new SystemModel(q);
00224         UrlItemView *view = new UrlItemView();
00225         ItemDelegate *delegate = new ItemDelegate(q);
00226         delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole);
00227         delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00228         view->setItemDelegate(delegate);
00229         view->setItemStateProvider(delegate);
00230 
00231         addView(i18n("Computer"), systemIcon(), model, view);
00232     }
00233 
00234     void setupSearchView() {
00235         searchModel = new SearchModel(q);
00236         UrlItemView *view = new UrlItemView();
00237         ItemDelegate *delegate = new ItemDelegate(q);
00238         delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole);
00239         delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00240         view->setItemDelegate(delegate);
00241         view->setItemStateProvider(delegate);
00242         view->setModel(searchModel);
00243         view->setFrameStyle(QFrame::NoFrame);
00244         // prevent view from stealing focus from the search bar
00245         view->setFocusPolicy(Qt::NoFocus);
00246         view->setDragEnabled(true);
00247         setupEventHandler(view);
00248 
00249         connect(searchModel, SIGNAL(resultsAvailable()), q, SLOT(resultsAvailable()));
00250 
00251         connect(searchBar, SIGNAL(queryChanged(QString)), searchModel, SLOT(setQuery(QString)));
00252         connect(searchBar, SIGNAL(queryChanged(QString)), q, SLOT(focusSearchView(QString)));
00253 
00254         view->setContextMenuPolicy(Qt::CustomContextMenu);
00255         connect(view, SIGNAL(customContextMenuRequested(QPoint)), q, SLOT(showViewContextMenu(QPoint)));
00256 
00257         contentArea->addWidget(view);
00258         searchView = view;
00259     }
00260 
00261     void registerUrlHandlers() {
00262         UrlItemLauncher::addGlobalHandler(UrlItemLauncher::ExtensionHandler, "desktop", new ServiceItemHandler);
00263         UrlItemLauncher::addGlobalHandler(UrlItemLauncher::ProtocolHandler, "leave", new LeaveItemHandler);
00264     }
00265 
00266     QIcon systemIcon() {
00267         QList<Solid::Device> batteryList = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString());
00268 
00269         if (batteryList.isEmpty()) {
00270             return KIcon("computer");
00271         } else {
00272             return KIcon("computer-laptop");
00273         }
00274     }
00275 
00276     void setNorthLayout(TabOrder tabOrder) {
00277         contentSwitcher->setShape(QTabBar::RoundedNorth);
00278         QLayout * layout = q->layout();
00279         delete layout;
00280         layout = new QVBoxLayout();
00281         layout->addWidget(contentSwitcher);
00282         layout->addWidget(contentAreaHeader);
00283         layout->addWidget(contentArea);
00284         layout->addWidget(contentAreaFooter);
00285         layout->addWidget(searchBar);
00286         layout->addWidget(footer);
00287         layout->setSpacing(0);
00288         layout->setMargin(0);
00289         q->setLayout(layout);
00290         setTabOrder(tabOrder);
00291     }
00292 
00293     void setSouthLayout(TabOrder tabOrder) {
00294         contentSwitcher->setShape(QTabBar::RoundedSouth);
00295         QLayout * layout = q->layout();
00296         delete layout;
00297         layout = new QVBoxLayout();
00298         layout->addWidget(footer);
00299         layout->addWidget(searchBar);
00300         layout->addWidget(contentAreaHeader);
00301         layout->addWidget(contentArea);
00302         layout->addWidget(contentAreaFooter);
00303         layout->addWidget(contentSwitcher);
00304         layout->setSpacing(0);
00305         layout->setMargin(0);
00306         q->setLayout(layout);
00307         setTabOrder(tabOrder);
00308     }
00309 
00310     void setWestLayout(TabOrder tabOrder) {
00311         contentSwitcher->setShape(QTabBar::RoundedWest);
00312         QLayout * layout = q->layout();
00313         delete layout;
00314         layout = new QHBoxLayout();
00315         layout->addWidget(contentSwitcher);
00316         layout->addWidget(contentArea);
00317         QBoxLayout * layout2 = new QVBoxLayout();
00318         if (tabOrder == NormalTabOrder) {
00319             layout2->addLayout(layout);
00320             layout2->addWidget(searchBar);
00321             layout2->addWidget(footer);
00322         } else {
00323             layout2->addWidget(footer);
00324             layout2->addWidget(searchBar);
00325             layout2->addLayout(layout);
00326         }
00327         layout->setSpacing(0);
00328         layout->setMargin(0);
00329         layout2->setSpacing(0);
00330         layout2->setMargin(0);
00331         q->setLayout(layout2);
00332         setTabOrder(tabOrder);
00333     }
00334 
00335     void setEastLayout(TabOrder tabOrder) {
00336         contentSwitcher->setShape(QTabBar::RoundedEast);
00337         QLayout * layout = q->layout();
00338         delete layout;
00339         layout = new QHBoxLayout();
00340         layout->addWidget(contentArea);
00341         layout->addWidget(contentSwitcher);
00342         QBoxLayout * layout2 = new QVBoxLayout();
00343         if (tabOrder == NormalTabOrder) {
00344             layout2->addLayout(layout);
00345             layout2->addWidget(searchBar);
00346             layout2->addWidget(footer);
00347         } else {
00348             layout2->addWidget(footer);
00349             layout2->addWidget(searchBar);
00350             layout2->addLayout(layout);
00351         }
00352         layout->setSpacing(0);
00353         layout->setMargin(0);
00354         layout2->setSpacing(0);
00355         layout2->setMargin(0);
00356         q->setLayout(layout2);
00357         setTabOrder(tabOrder);
00358     }
00359 
00360     void setTabOrder(TabOrder newOrder) {
00361         // identify current TabOrder, assumes favoritesView is first in normal order
00362         TabOrder oldOrder;
00363         if (contentArea->widget(0) == favoritesView) {
00364             oldOrder = NormalTabOrder;
00365         } else {
00366             oldOrder = ReverseTabOrder;
00367         }
00368         if (newOrder == oldOrder) {
00369             return;
00370         }
00371         // remove the and widgets and store their data in a separate structure
00372         // remove this first so we can cleanly remove the widgets controlled by contentSwitcher
00373         contentArea->removeWidget(searchView);
00374         Q_ASSERT(contentArea->count() == contentSwitcher->count());
00375 
00376         QList<WidgetTabData> removedTabs;
00377         for (int i = contentSwitcher->count() - 1; i >= 0 ; i--) {
00378             WidgetTabData wtd;
00379             wtd.tabText = contentSwitcher->tabText(i);
00380             wtd.tabToolTip = contentSwitcher->tabToolTip(i);
00381             wtd.tabWhatsThis = contentSwitcher->tabWhatsThis(i);
00382             wtd.tabIcon = contentSwitcher->tabIcon(i);
00383             wtd.widget = contentArea->widget(i);
00384             removedTabs.append(wtd);
00385 
00386             contentSwitcher->removeTab(i);
00387             contentArea->removeWidget(contentArea->widget(i));
00388         }
00389         // then reinsert them in reversed order
00390         int i = 0;
00391         foreach(const WidgetTabData &wtd, removedTabs) {
00392             contentSwitcher->addTab(wtd.tabIcon, wtd.tabText);
00393             contentSwitcher->setTabToolTip(i, wtd.tabToolTip);
00394             contentSwitcher->setTabWhatsThis(i, wtd.tabWhatsThis);
00395             contentArea->addWidget(wtd.widget);
00396             ++i;
00397         }
00398         //finally replace the searchView
00399         contentArea->addWidget(searchView);
00400     }
00401 
00402     struct WidgetTabData {
00403         QString tabText;
00404         QString tabToolTip;
00405         QString tabWhatsThis;
00406         QIcon tabIcon;
00407         QWidget * widget;
00408     };
00409 
00410     Launcher * const q;
00411     Plasma::Applet *applet;
00412     UrlItemLauncher *urlLauncher;
00413     SearchModel *searchModel;
00414     LeaveModel *leaveModel;
00415     SearchBar *searchBar;
00416     QWidget *footer;
00417     QLabel *userinfo;
00418     ContentAreaCap *contentAreaHeader;
00419     QStackedWidget *contentArea;
00420     ContentAreaCap *contentAreaFooter;
00421     TabBar *contentSwitcher;
00422     FlipScrollView *applicationView;
00423     QAbstractItemView *searchView;
00424     QAbstractItemView *favoritesView;
00425     ContextMenuFactory *contextMenuFactory;
00426     bool autoHide;
00427     int visibleItemCount;
00428     Plasma::PopupPlacement placement;
00429     Plasma::Location panelEdge;
00430 };
00431 
00432 Launcher::Launcher(QWidget *parent)
00433         : QWidget(parent, Qt::Window)
00434         , d(new Private(this))
00435 {
00436     init();
00437 }
00438 
00439 Launcher::Launcher(Plasma::Applet *applet)
00440         : QWidget(0, Qt::Window)
00441         , d(new Private(this))
00442 {
00443     init();
00444     setApplet(applet);
00445 }
00446 
00447 void Launcher::init()
00448 {
00449     QVBoxLayout *layout = new QVBoxLayout;
00450     layout->setSpacing(0);
00451     layout->setMargin(0);
00452 
00453     const int rightHeaderMargin = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
00454 
00455     d->searchBar = new SearchBar(this);
00456     if (layoutDirection() == Qt::LeftToRight) {
00457         d->searchBar->setContentsMargins(0, 0, rightHeaderMargin, 0);
00458     } else {
00459         d->searchBar->setContentsMargins(rightHeaderMargin, 0, 0, 0);
00460     }
00461     d->searchBar->installEventFilter(this);
00462     d->contentAreaHeader = new ContentAreaCap(this);
00463     d->contentArea = new QStackedWidget(this);
00464     bool flipCap = true;
00465     d->contentAreaFooter = new ContentAreaCap(this, flipCap);
00466     d->contentSwitcher = new TabBar(this);
00467     d->contentSwitcher->installEventFilter(this);
00468     d->contentSwitcher->setIconSize(QSize(48, 48));
00469     d->contentSwitcher->setShape(QTabBar::RoundedSouth);
00470     connect(d->contentSwitcher, SIGNAL(currentChanged(int)),
00471             d->contentArea, SLOT(setCurrentIndex(int)));
00472     d->contextMenuFactory = new ContextMenuFactory(this);
00473 
00474     d->initTabs();
00475     d->registerUrlHandlers();
00476 
00477     // Add status information footer
00478     d->footer = new QWidget;
00479 
00480     char hostname[256];
00481     hostname[0] = '\0';
00482     if (!gethostname(hostname, sizeof(hostname))) {
00483         hostname[sizeof(hostname)-1] = '\0';
00484     }
00485     KUser user;
00486     QString fullName = user.property(KUser::FullName).toString();
00487     QString labelText;
00488     if (fullName.isEmpty()) {
00489         labelText = i18nc("login name, hostname", "User <b>%1</b> on <b>%2</b>", user.loginName(), hostname);
00490     } else {
00491         labelText = i18nc("full name, login name, hostname", "<b>%1 (%2)</b> on <b>%3</b>", fullName, user.loginName(), hostname);
00492     }
00493 
00494     d->userinfo = new QLabel(labelText);
00495 
00496     QToolButton *branding = new BrandingButton(this);
00497     branding->setAutoRaise(false);
00498     branding->setToolButtonStyle(Qt::ToolButtonIconOnly);
00499     connect(branding, SIGNAL(clicked()), this, SIGNAL(aboutToHide()));
00500 
00501     QHBoxLayout *brandingLayout = new QHBoxLayout;
00502     brandingLayout->setMargin(3);
00503     brandingLayout->addSpacing(ItemDelegate::ITEM_LEFT_MARGIN - 3);
00504     brandingLayout->addWidget(d->userinfo);
00505     brandingLayout->addStretch(2);
00506     brandingLayout->addWidget(branding);
00507     brandingLayout->addSpacing(rightHeaderMargin);
00508     d->footer->setLayout(brandingLayout);
00509 
00510     layout->addWidget(d->footer);
00511     layout->addWidget(d->searchBar);
00512     layout->addWidget(d->contentAreaHeader);
00513     layout->addWidget(d->contentArea);
00514     layout->addWidget(d->contentAreaFooter);
00515     layout->addWidget(d->contentSwitcher);
00516 
00517     setLayout(layout);
00518     //setBackgroundRole(QPalette::AlternateBase);
00519     //setAutoFillBackground(true);
00520 
00521     updateThemedPalette();
00522     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
00523             this, SLOT(updateThemedPalette()));
00524 }
00525 
00526 void Launcher::updateThemedPalette()
00527 {
00528     QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
00529     QPalette p = d->userinfo->palette();
00530     p.setColor(QPalette::Normal, QPalette::WindowText, color);
00531     p.setColor(QPalette::Inactive, QPalette::WindowText, color);
00532     d->userinfo->setPalette(p);
00533 }
00534 
00535 QSize Launcher::minimumSizeHint() const
00536 {
00537     QSize size;
00538 
00539     switch (d->panelEdge) {
00540     case Plasma::LeftEdge:
00541     case Plasma::RightEdge:
00542         size.rheight() = d->searchBar->sizeHint().height() +
00543                          d->footer->sizeHint().height() +
00544                          qMax(d->favoritesView->sizeHintForRow(0) * 3 + ItemDelegate::HEADER_HEIGHT, d->contentSwitcher->sizeHint().height());
00545         size.rwidth() = d->contentSwitcher->sizeHint().width() + d->favoritesView->sizeHint().width();
00546         break;
00547     case Plasma::TopEdge:
00548     case Plasma::BottomEdge:
00549     default:
00550         size.rheight() = d->searchBar->sizeHint().height() +
00551                          d->contentSwitcher->sizeHint().height() + d->footer->sizeHint().height() +
00552                          d->favoritesView->sizeHintForRow(0) * 3 + ItemDelegate::HEADER_HEIGHT;
00553         size.rwidth() = d->contentSwitcher->sizeHint().width();
00554         break;
00555     }
00556 
00557     return size;
00558 }
00559 
00560 QSize Launcher::sizeHint() const
00561 {
00562     return QSize(minimumSizeHint().width(), 500);
00563 }
00564 
00565 void Launcher::setAutoHide(bool hide)
00566 {
00567     d->autoHide = hide;
00568 }
00569 
00570 bool Launcher::autoHide() const
00571 {
00572     return d->autoHide;
00573 }
00574 
00575 void Launcher::setSwitchTabsOnHover(bool switchOnHover)
00576 {
00577     d->contentSwitcher->setSwitchTabsOnHover(switchOnHover);
00578 }
00579 
00580 bool Launcher::switchTabsOnHover() const
00581 {
00582     return d->contentSwitcher->switchTabsOnHover();
00583 }
00584 
00585 void Launcher::setVisibleItemCount(int count)
00586 {
00587     d->visibleItemCount = count;
00588 }
00589 
00590 int Launcher::visibleItemCount() const
00591 {
00592     return d->visibleItemCount;
00593 }
00594 
00595 void Launcher::setApplet(Plasma::Applet *applet)
00596 {
00597     d->applet = applet;
00598     d->contextMenuFactory->setApplet(applet);
00599 
00600     KConfigGroup cg = applet->globalConfig();
00601     setSwitchTabsOnHover(cg.readEntry("SwitchTabsOnHover", switchTabsOnHover()));
00602 
00603     cg = applet->config();
00604     setVisibleItemCount(cg.readEntry("VisibleItemsCount", visibleItemCount()));
00605 }
00606 
00607 void Launcher::reset()
00608 {
00609     d->contentSwitcher->setCurrentIndexWithoutAnimation(d->contentArea->indexOf(d->favoritesView));
00610     d->contentArea->setCurrentWidget(d->favoritesView);
00611     d->searchBar->clear();
00612     d->applicationView->viewRoot();
00613     d->leaveModel->updateModel();
00614 }
00615 
00616 Launcher::~Launcher()
00617 {
00618     delete d;
00619 }
00620 
00621 void Launcher::focusSearchView(const QString& query)
00622 {
00623     bool queryEmpty = query.isEmpty();
00624 
00625     d->contentSwitcher->setVisible(queryEmpty);
00626 
00627     if (!queryEmpty) {
00628         d->contentArea->setCurrentWidget(d->searchView);
00629     } else {
00630         focusFavoritesView();
00631     }
00632 }
00633 
00634 void Launcher::focusFavoritesView()
00635 {
00636     d->contentSwitcher->setCurrentIndex(d->contentArea->indexOf(d->favoritesView));
00637     d->contentArea->setCurrentWidget(d->favoritesView);
00638 }
00639 
00640 bool Launcher::eventFilter(QObject *object, QEvent *event)
00641 {
00642     // deliver unhandled key presses from the search bar
00643     // (mainly arrow keys, enter) to the active view
00644     if ((object == d->contentSwitcher || object == d->searchBar) && event->type() == QEvent::KeyPress) {
00645         // we want left/right to still nav the tabbar
00646         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
00647         if (keyEvent->modifiers() == Qt::NoModifier &&
00648                 (keyEvent->key() == Qt::Key_Left ||
00649                  keyEvent->key() == Qt::Key_Right)) {
00650             if (object == d->contentSwitcher) {
00651                 return false;
00652             } else {
00653                 QCoreApplication::sendEvent(d->contentSwitcher, event);
00654                 return true;
00655             }
00656         }
00657 
00658         QAbstractItemView *activeView = qobject_cast<QAbstractItemView*>(d->contentArea->currentWidget());
00659         if (activeView) {
00660             QCoreApplication::sendEvent(activeView, event);
00661             return true;
00662         }
00663     }
00664 
00665 
00666     // the mouse events we are interested in are delivered to the viewport,
00667     // other events are delivered to the view itself.
00668     QAbstractItemView *view = qobject_cast<QAbstractItemView*>(object);
00669     if (!view) {
00670         view = qobject_cast<QAbstractItemView*>(object->parent());
00671     }
00672 
00673     if (view) {
00674         QModelIndex openIndex;
00675         if (event->type() == QEvent::MouseButtonRelease) {
00676             QMouseEvent *mouseEvent = (QMouseEvent*)event;
00677             const QModelIndex index = view->indexAt(mouseEvent->pos());
00678             if (index.isValid() &&
00679                     index.model()->hasChildren(index) == false &&
00680                     mouseEvent->button() == Qt::LeftButton) {
00681                 openIndex = index;
00682             }
00683         } else if (event->type() == QEvent::KeyPress) {
00684             QKeyEvent *keyEvent = (QKeyEvent*)event;
00685             const QModelIndex index = view->currentIndex();
00686             if (index.isValid() && index.model()->hasChildren(index) == false &&
00687                     (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return)) {
00688                 openIndex = index;
00689             }
00690         }
00691         if (openIndex.isValid()) {
00692             d->urlLauncher->openItem(openIndex);
00693             // Clear the search bar when enter was pressed
00694             if (event->type() == QEvent::KeyPress) {
00695                 d->searchBar->clear();
00696             }
00697             if (d->autoHide) {
00698                 emit aboutToHide();
00699             }
00700             return true;
00701         }
00702     }
00703     return QWidget::eventFilter(object, event);
00704 }
00705 
00706 void Launcher::showViewContextMenu(const QPoint& pos)
00707 {
00708     QAbstractItemView *view = qobject_cast<QAbstractItemView*>(sender());
00709     if (view) {
00710         d->contextMenuFactory->showContextMenu(view, pos);
00711     }
00712 }
00713 
00714 void Launcher::hideEvent(QHideEvent *event)
00715 {
00716     Q_UNUSED(event)
00717     reset();
00718 }
00719 
00720 void Launcher::keyPressEvent(QKeyEvent *event)
00721 {
00722     if (event->key() == Qt::Key_Escape) {
00723         emit aboutToHide();
00724     }
00725 #if 0
00726     // allow tab switching by pressing the left or right arrow keys
00727     if (event->key() == Qt::Key_Left && d->contentSwitcher->currentIndex() > 0) {
00728         d->contentSwitcher->setCurrentIndex(d->contentSwitcher->currentIndex() - 1);
00729     } else if (event->key() == Qt::Key_Right &&
00730                d->contentSwitcher->currentIndex() < d->contentSwitcher->count() - 1) {
00731         d->contentSwitcher->setCurrentIndex(d->contentSwitcher->currentIndex() + 1);
00732     }
00733 #endif
00734 }
00735 
00736 void Launcher::showEvent(QShowEvent *e)
00737 {
00738     d->searchBar->setFocus();
00739 
00740     QWidget::showEvent(e);
00741 }
00742 
00743 void Launcher::resultsAvailable()
00744 {
00745     const QModelIndex root = d->searchModel->index(0, 0);
00746     d->searchView->setCurrentIndex(d->searchModel->index(0, 0, root));
00747 }
00748 
00749 void Launcher::setLauncherOrigin(const Plasma::PopupPlacement placement, Plasma::Location location)
00750 {
00751     if (d->placement != placement) {
00752         d->placement = placement;
00753 
00754         switch (placement) {
00755         case Plasma::TopPosedRightAlignedPopup:
00756             d->setSouthLayout(Private::ReverseTabOrder);
00757             break;
00758         case Plasma::LeftPosedTopAlignedPopup:
00759             d->setEastLayout(Private::NormalTabOrder);
00760             break;
00761         case Plasma::LeftPosedBottomAlignedPopup:
00762             d->setEastLayout(Private::ReverseTabOrder);
00763             break;
00764         case Plasma::BottomPosedLeftAlignedPopup:
00765             d->setNorthLayout(Private::NormalTabOrder);
00766             break;
00767         case Plasma::BottomPosedRightAlignedPopup:
00768             d->setNorthLayout(Private::ReverseTabOrder);
00769             break;
00770         case Plasma::RightPosedTopAlignedPopup:
00771             d->setWestLayout(Private::NormalTabOrder);
00772             break;
00773         case Plasma::RightPosedBottomAlignedPopup:
00774             d->setWestLayout(Private::ReverseTabOrder);
00775             break;
00776         case Plasma::TopPosedLeftAlignedPopup:
00777         default:
00778             d->setSouthLayout(Private::NormalTabOrder);
00779             break;
00780         }
00781     }
00782     d->panelEdge = location;
00783 }
00784 
00785 #include "launcher.moc"
00786 

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
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
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