00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ui/launcher.h"
00022
00023
00024 #include <unistd.h>
00025
00026
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
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
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
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
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
00132 setupFavoritesView();
00133
00134
00135 setupAllProgramsView();
00136
00137
00138 setupSystemView();
00139
00140
00141 setupRecentView();
00142
00143
00144 setupLeaveView();
00145
00146
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
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
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
00372
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
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
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
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
00519
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
00643
00644 if ((object == d->contentSwitcher || object == d->searchBar) && event->type() == QEvent::KeyPress) {
00645
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
00667
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
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
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