/* * Copyright (C) 2006 by Aaron Seigo * Copyright (C) 2007-2009 Ryan P. Bitanga * Copyright (C) 2008 by Davide Bettio * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . */ #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include "toolbutton.h" #include "krunnerapp.h" #include "qs_dialog.h" #include "qs_matchview.h" #include "qs_querymatchitem.h" #include "qs_queryactionitem.h" QsDialog::QsDialog(Plasma::RunnerManager *runnerManager, QWidget *parent) : KRunnerDialog(runnerManager, parent) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); QHBoxLayout *hLayout = new QHBoxLayout(); hLayout->setMargin(0); hLayout->setSpacing(0); m_configButton = new ToolButton(this); m_configButton->setText(i18n("Settings")); m_configButton->setToolTip(i18n("Settings")); m_configButton->setIcon(m_iconSvg->pixmap(QLatin1String( "configure" ))); connect(m_configButton, SIGNAL(clicked()), SLOT(toggleConfigDialog())); m_activityButton = new ToolButton(this); KRunnerApp *krunnerApp = KRunnerApp::self(); QAction *showSystemActivityAction = krunnerApp->actionCollection()->action(QLatin1String( "Show System Activity" )); m_activityButton->setDefaultAction(showSystemActivityAction); m_activityButton->setIcon(m_iconSvg->pixmap(QLatin1String( "status" ))); updateSystemActivityToolTip(); connect(showSystemActivityAction, SIGNAL(globalShortcutChanged(QKeySequence)), this, SLOT(updateSystemActivityToolTip())); connect(showSystemActivityAction, SIGNAL(triggered(bool)), this, SLOT(close())); m_singleRunnerIcon = new QLabel(this); QLabel *label = new QLabel(this); label->setText(QLatin1String( "QuickSand" )); const QColor textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); QPalette titlePallete = label->palette(); titlePallete.setColor(QPalette::WindowText, textColor); label->setPalette(titlePallete); QToolButton *m_closeButton = new ToolButton(this); KGuiItem guiItem = KStandardGuiItem::close(); m_closeButton->setText(guiItem.text()); m_closeButton->setToolTip(guiItem.text().remove(QLatin1Char( '&' ))); m_closeButton->setIcon(m_iconSvg->pixmap(QLatin1String( "close" ))); connect(m_closeButton, SIGNAL(clicked(bool)), this, SLOT(close())); hLayout->addWidget(m_configButton); hLayout->addWidget(m_activityButton); hLayout->addWidget(m_singleRunnerIcon); hLayout->addStretch(); hLayout->addWidget(label); hLayout->addStretch(); hLayout->addWidget(m_closeButton); layout->addLayout(hLayout); m_matchView = new QuickSand::QsMatchView(this); layout->addWidget(m_matchView); connect(m_matchView, SIGNAL(textChanged(QString)), m_matchView, SLOT(setTitle(QString))); m_currentMatch = 0; m_actionView = new QuickSand::QsMatchView(this); layout->addWidget(m_actionView); m_actionView->setTitle(i18n("Actions")); m_actionView->setCountingActions(true); m_actionView->hide(); connect(m_runnerManager, SIGNAL(matchesChanged(QList)), this, SLOT(setMatches(QList))); connect(m_matchView, SIGNAL(textChanged(QString)), this, SLOT(launchQuery(QString))); connect(m_matchView, SIGNAL(selectionChanged(MatchItem*)), this, SLOT(loadActions(MatchItem*))); connect(m_matchView, SIGNAL(itemActivated(MatchItem*)), this, SLOT(run(MatchItem*))); connect(m_actionView, SIGNAL(selectionChanged(MatchItem*)), this, SLOT(setAction(MatchItem*))); connect(m_actionView, SIGNAL(itemActivated(MatchItem*)), this, SLOT(run(MatchItem*))); m_matchView->setFocus(); m_newQuery = true; new QShortcut(QKeySequence(Qt::Key_Escape), this, SLOT(close())); } QsDialog::~QsDialog() {} // FIXME: We still have no notion of history... Actually adaptive search should partly take care of this void QsDialog::clearHistory() {} void QsDialog::setConfigWidget(QWidget *w) { //Yet another code copy pasted from default interface, should we move this to a common place? const int screenId = qApp->desktop()->screenNumber(this); const int maxHeight = qApp->desktop()->availableGeometry(screenId).height(); int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); const int padding = top + bottom + m_activityButton->height(); resize(width(), qMin(maxHeight, qMax(w->sizeHint().height() + padding, size().height()))); QVBoxLayout *layout = static_cast(this->layout()); layout->addWidget(w); m_matchView->hide(); connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(configWidgetDestroyed())); } void QsDialog::configWidgetDestroyed() { QTimer::singleShot(0, this, SLOT(cleanupAfterConfigWidget())); } void QsDialog::cleanupAfterConfigWidget() { m_matchView->show(); m_matchView->setFocus(); adjustSize(); } void QsDialog::adjustInterface() { if (m_runnerManager->singleModeRunner()) { m_singleRunnerIcon->setPixmap(m_runnerManager->singleModeRunner()->icon().pixmap( QSize( 22, 22 )) ); m_singleRunnerIcon->show(); m_configButton->hide(); } else { m_singleRunnerIcon->hide(); m_configButton->show(); } } void QsDialog::display(const QString &term) { KWindowSystem::setOnDesktop(winId(), KWindowSystem::currentDesktop()); adjustInterface(); m_matchView->reset(); m_actionView->reset(); m_actionView->hide(); adjustSize(); m_matchView->setFocus(); //positionOnScreen will call QWidget::show anyways so we don't need to call it here positionOnScreen(); KWindowSystem::forceActiveWindow(winId()); if (term.isEmpty() && !m_runnerManager->singleMode()) { m_matchView->setTitle(QString()); } else { m_matchView->setTitle(term); launchQuery(term); } } void QsDialog::launchQuery(const QString &query) { if (query.isEmpty() && !m_runnerManager->singleMode()) { m_matchView->reset(); } else { m_matchView->showLoading(); } m_runnerManager->launchQuery(query); m_newQuery = true; } void QsDialog::run(MatchItem *item) { if (QuickSand::QueryMatchItem *match = qobject_cast(item)) { m_runnerManager->run(match->match()); close(); } else if (qobject_cast(item)) { m_runnerManager->run(m_currentMatch->match()); close(); } } void QsDialog::loadActions(MatchItem *item) { if (item == m_currentMatch) { return; } m_currentMatch = qobject_cast(item); QList actions; if (m_currentMatch) { QList queryActions = m_runnerManager->actionsForMatch(m_currentMatch->match()); foreach(QAction *action, queryActions) { MatchItem *m = new QuickSand::QueryActionItem(action); actions.append(m); } } if (actions.size()) { m_actionView->show(); } else if (m_actionView->isVisible()) { m_actionView->hide(); } adjustSize(); m_actionView->setItems(actions, false); } void QsDialog::setMatches(const QList &matches) { QList items; QMultiMap temp; QMultiMap::iterator end = m_matches.end(); foreach (const Plasma::QueryMatch &match, matches) { temp.insert(match.id(), match); // Do not create new MatchItems for existing matches when the query hasn't changed if (!m_newQuery && m_matches.find(match.id()) != end) { // kDebug() << "A match with id " << match.id() << " already exists."; QList duplicates = m_matches.values(match.id()); bool exists = false; foreach (const Plasma::QueryMatch &m, duplicates) { // FIXME: Matching the displayed text isn't always reliable // maybe adding an operator== to QueryMatch would help if (m.text() == match.text()) { exists = true; break; } } if (exists) { continue; } } MatchItem *m = new QuickSand::QueryMatchItem(match); //TODO: I'm leaving the switch because this feature has sence, but we have to find another way to implement it /* switch(match.type()) { case Plasma::QueryMatch::ExactMatch: m->setBackgroundColor(QColor(Qt::yellow)); break; case Plasma::QueryMatch::InformationalMatch: case Plasma::QueryMatch::HelperMatch: m->setBackgroundColor(QColor(Qt::blue)); break; default: m->setBackgroundColor(QColor(Qt::green)); break; }*/ items.append(m); } // kDebug() << "Add " << items.size() << " matches. Append?" << !m_newQuery; m_matchView->setItems(items, true, !m_newQuery); m_matches = temp; // If new matches are obtained for the same query, append them to the list m_newQuery = false; } void QsDialog::setAction(MatchItem *item) { if (QuickSand::QueryActionItem *action = qobject_cast(item)) { m_currentMatch->match().setSelectedAction(action->action()); } } void QsDialog::updateSystemActivityToolTip() { /* Set the tooltip for the Show System Activity button to include the global shortcut */ KRunnerApp *krunnerApp = KRunnerApp::self(); KAction *showSystemActivityAction = qobject_cast(krunnerApp->actionCollection()->action(QLatin1String( "Show System Activity" ))); if (showSystemActivityAction) { QString shortcut = showSystemActivityAction->globalShortcut().toString(); if (shortcut.isEmpty()) { m_activityButton->setToolTip( showSystemActivityAction->toolTip() ); } else { m_activityButton->setToolTip( i18nc("tooltip, shortcut", "%1 (%2)", showSystemActivityAction->toolTip(), shortcut)); } } } #include "moc_qs_dialog.cpp"