Репозитории ALT
5.1: | 3.5.10-alt20.M51.2 |
4.1: | 3.5.10-alt16.M41.1 |
4.0: | 3.5.9-alt1.M40.1 |
3.0: | 3.4.1-alt12 |
+updates: | 3.4.1-alt12.1.M30 |
+backports: | 3.5.6-alt7.0.M30 |
Группа :: Графические оболочки/KDE
Пакет: kdebase
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: kmenu-search-fs20060627-fixed.diff
Скачать
Скачать
--- kicker/kicker/ui/Makefile.am
+++ kicker/kicker/ui/Makefile.am
@@ -13,7 +13,7 @@
recentapps.cpp browser_dlg.cpp \
removeapplet_mnu.cpp removeextension_mnu.cpp removecontainer_mnu.cpp \
removebutton_mnu.cpp popupmenutitle.cpp hidebutton.cpp \
- addappletvisualfeedback.cpp
+ addappletvisualfeedback.cpp clicklineedit.cpp
libkicker_ui_la_LIBADD = $(top_builddir)/libkonq/libkonq.la $(top_builddir)/kdmlib/libdmctl.la
@@ -25,7 +25,7 @@
addextension_mnu.h extensionop_mnu.h \
recentapps.h browser_dlg.h \
removeapplet_mnu.h removeextension_mnu.h removecontainer_mnu.h \
- removebutton_mnu.h popupmenutitle.h hidebutton.h addappletvisualfeedback.h
+ removebutton_mnu.h popupmenutitle.h hidebutton.h addappletvisualfeedback.h clicklineedit.h
removecontainer_mnu.lo: ../../libkicker/kickerSettings.h
removeextension_mnu.lo: ../../libkicker/kickerSettings.h
--- kicker/kicker/ui/clicklineedit.cpp
+++ kicker/kicker/ui/clicklineedit.cpp
@@ -0,0 +1,85 @@
+/*
+ This file is part of libkdepim.
+ Copyright (c) 2004 Daniel Molkentin <molkentin@kde.org>
+ based on code by Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+#include "clicklineedit.h"
+
+#include "qpainter.h"
+
+using namespace KPIM;
+
+ClickLineEdit::ClickLineEdit(QWidget *parent, const QString &msg, const char* name) :
+ KLineEdit(parent, name)
+{
+ mDrawClickMsg = true;
+ setClickMessage( msg );
+}
+
+ClickLineEdit::~ClickLineEdit() {}
+
+
+void ClickLineEdit::setClickMessage( const QString &msg )
+{
+ mClickMessage = msg;
+ repaint();
+}
+
+void ClickLineEdit::setText( const QString &txt )
+{
+ mDrawClickMsg = txt.isEmpty();
+ repaint();
+ KLineEdit::setText( txt );
+}
+
+void ClickLineEdit::drawContents( QPainter *p )
+{
+ KLineEdit::drawContents( p );
+
+ if ( mDrawClickMsg == true && !hasFocus() ) {
+ QPen tmp = p->pen();
+ p->setPen( gray );
+ QRect cr = contentsRect();
+ p->drawText( cr, AlignAuto|AlignVCenter, mClickMessage );
+ p->setPen( tmp );
+ }
+}
+
+void ClickLineEdit::focusInEvent( QFocusEvent *ev )
+{
+ if ( mDrawClickMsg == true )
+ {
+ mDrawClickMsg = false;
+ repaint();
+ }
+ QLineEdit::focusInEvent( ev );
+}
+
+void ClickLineEdit::focusOutEvent( QFocusEvent *ev )
+{
+ if ( text().isEmpty() )
+ {
+ mDrawClickMsg = true;
+ repaint();
+ }
+ QLineEdit::focusOutEvent( ev );
+}
+
+#include "clicklineedit.moc"
--- kicker/kicker/ui/clicklineedit.h
+++ kicker/kicker/ui/clicklineedit.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of libkdepim.
+ Copyright (c) 2004 Daniel Molkentin <molkentin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef CLICKLINEEDIT_H
+#define CLICKLINEEDIT_H
+
+#include <klineedit.h>
+
+
+namespace KPIM {
+
+/**
+ This class provides a KLineEdit which contains a greyed-out hinting
+ text as long as the user didn't enter any text
+
+ @short LineEdit with customizable "Click here" text
+ @author Daniel Molkentin
+*/
+class KDE_EXPORT ClickLineEdit : public KLineEdit
+{
+ Q_OBJECT
+ public:
+ ClickLineEdit( QWidget *parent, const QString &msg = QString::null, const char* name = 0 );
+ ~ClickLineEdit();
+
+ void setClickMessage( const QString &msg );
+ QString clickMessage() const { return mClickMessage; }
+
+ virtual void setText( const QString& txt );
+
+ protected:
+ virtual void drawContents( QPainter *p );
+ virtual void focusInEvent( QFocusEvent *ev );
+ virtual void focusOutEvent( QFocusEvent *ev );
+
+ private:
+ QString mClickMessage;
+ bool mDrawClickMsg;
+
+};
+
+}
+
+#endif // CLICKLINEEDIT_H
+
+
--- kicker/kicker/ui/k_mnu.cpp
+++ kicker/kicker/ui/k_mnu.cpp
@@ -26,9 +26,13 @@
#include <unistd.h>
#include <dmctl.h>
+#include <qhbox.h>
#include <qimage.h>
+#include <qlabel.h>
#include <qpainter.h>
#include <qstyle.h>
+#include <qtimer.h>
+#include <qtooltip.h>
#include <dcopclient.h>
#include <kapplication.h>
@@ -40,9 +44,11 @@
#include <kglobal.h>
#include <kglobalsettings.h>
#include <kiconloader.h>
+#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
+#include <ktoolbarbutton.h>
#include <kwin.h>
#include "client_mnu.h"
@@ -58,9 +64,12 @@
#include "quickbrowser_mnu.h"
#include "recentapps.h"
+#include "clicklineedit.h"
#include "k_mnu.h"
#include "k_mnu.moc"
+const int PanelKMenu::searchLineID(23140 /*whatever*/);
+
PanelKMenu::PanelKMenu()
: PanelServiceMenu(QString::null, QString::null, 0, "KMenu")
, bookmarkMenu(0)
@@ -165,6 +174,26 @@
}
}
+
+/* A MenuHBox is supposed to be inserted into a menu.
+ * You can set a special widget in the hbox which will
+ * get the focus if the user moves up or down with the
+ * cursor keys
+ */
+class MenuHBox : public QHBox {
+public:
+ MenuHBox(PanelKMenu* parent) : QHBox(parent)
+ {
+ }
+
+ virtual void keyPressEvent(QKeyEvent *e)
+ {
+
+ }
+private:
+ PanelKMenu *parent;
+};
+
void PanelKMenu::initialize()
{
// kdDebug(1210) << "PanelKMenu::initialize()" << endl;
@@ -191,13 +220,29 @@
// add services
PanelServiceMenu::initialize();
+ // Insert search field
+ QHBox* hbox = new QHBox( this );
+ KToolBarButton *clearButton = new KToolBarButton( "locationbar_erase", 0, hbox );
+ searchEdit = new KPIM::ClickLineEdit(hbox, " "+i18n("Press '/' to search..."));
+ hbox->setFocusPolicy(QWidget::StrongFocus);
+ hbox->setFocusProxy(searchEdit);
+ hbox->setSpacing( 3 );
+ connect(clearButton, SIGNAL(clicked()), searchEdit, SLOT(clear()));
+ connect(this, SIGNAL(aboutToHide()), this, SLOT(slotClearSearch()));
+ connect(searchEdit, SIGNAL(textChanged(const QString&)),
+ this, SLOT( slotUpdateSearch( const QString&)));
+ insertItem(hbox, searchLineID, 0);
+
+ //QToolTip::add(clearButton, i18n("Clear Search"));
+ //QToolTip::add(searchEdit, i18n("Enter the name of an application"));
+
if (KickerSettings::showMenuTitles())
{
int id;
id = insertItem(new PopupMenuTitle(i18n("All Applications"), font()), -1 /* id */, 0);
- setItemEnabled( id, false );
+ setItemEnabled(id, false);
id = insertItem(new PopupMenuTitle(i18n("Actions"), font()), -1 /* id */, -1);
- setItemEnabled( id, false );
+ setItemEnabled(id, false);
}
// create recent menu section
@@ -741,3 +786,43 @@
}
+void PanelKMenu::slotUpdateSearch(const QString& searchString)
+{
+ kdDebug() << "Searching for " << searchString << endl;
+ setSearchString(searchString);
+}
+
+void PanelKMenu::slotClearSearch()
+{
+ if (searchEdit && searchEdit->text().isEmpty() == false) {
+ QTimer::singleShot(0, searchEdit, SLOT(clear()));
+ }
+}
+
+void PanelKMenu::keyPressEvent(QKeyEvent* e)
+{
+ // We move the focus to the search field if the
+ // user presses '/'. This is the same shortcut as
+ // konqueror is using, and afaik it's hardcoded both
+ // here and there. This sucks badly for many non-us
+ // keyboard layouts, but for the sake of consistency
+ // we follow konqueror.
+ if (!searchEdit) return KPanelMenu::keyPressEvent(e);
+
+ if (e->key() == Qt::Key_Slash && !searchEdit->hasFocus()) {
+ if (indexOf(searchLineID) >=0 ) {
+ setActiveItem(indexOf(searchLineID));
+ }
+ }
+ else if (e->key() == Qt::Key_Escape && searchEdit->text().isEmpty() == false) {
+ searchEdit->clear();
+ }
+ else if (e->key() == Qt::Key_Delete && !searchEdit->hasFocus() &&
+ searchEdit->text().isEmpty() == false)
+ {
+ searchEdit->clear();
+ }
+ else {
+ KPanelMenu::keyPressEvent(e);
+ }
+}
--- kicker/kicker/ui/k_mnu.h
+++ kicker/kicker/ui/k_mnu.h
@@ -30,6 +30,11 @@
#include "service_mnu.h"
+namespace KPIM {
+ // Yes, ClickLineEdit was copied from libkdepim.
+ // Can we have it in kdelibs please?
+ class ClickLineEdit;
+}
class KickerClientMenu;
class KBookmarkMenu;
class KActionCollection;
@@ -73,6 +78,8 @@
void slotSaveSession();
void slotRunCommand();
void slotEditUserContact();
+ void slotUpdateSearch(const QString &searchtext);
+ void slotClearSearch();
void paletteChanged();
virtual void configChanged();
void updateRecent();
@@ -89,6 +96,8 @@
void doNewSession(bool lock);
void createRecentMenuItems();
virtual void clearSubmenus();
+ void filterMenu(PanelServiceMenu* menu, const QString &searchString);
+ void keyPressEvent(QKeyEvent* e);
private:
QPopupMenu *sessionsMenu;
@@ -101,6 +110,8 @@
KActionCollection *actionCollection;
KBookmarkOwner *bookmarkOwner;
PopupMenuList dynamicSubMenus;
+ KPIM::ClickLineEdit *searchEdit;
+ static const int searchLineID;
};
#endif
--- kicker/kicker/ui/service_mnu.cpp.orig 2006-05-23 01:12:40 +0700
+++ kicker/kicker/ui/service_mnu.cpp 2006-06-27 11:04:41 +0700
@@ -26,6 +26,7 @@
#include <qbitmap.h>
#include <qpixmap.h>
#include <qimage.h>
+#include <qmap.h>
#include <dcopclient.h>
#include <kapplication.h>
@@ -100,6 +101,8 @@
clear();
clearSubmenus();
+ searchSubMenuIDs.clear();
+ searchMenuItems.clear();
doInitialize();
}
@@ -202,6 +205,10 @@
int newId = insertItem(iconset, groupCaption, m, id++);
entryMap_.insert(newId, static_cast<KSycocaEntry*>(g));
+ // This submenu will be searched when applying a search string
+ searchSubMenuIDs[m] = newId;
+ // Also search the submenu name itself
+ searchMenuItems.insert(newId);
// We have to delete the sub menu our selves! (See Qt docs.)
subMenus.append(m);
}
@@ -214,6 +221,7 @@
}
KService::Ptr s(static_cast<KService *>(e));
+ searchMenuItems.insert(id);
insertMenuItem(s, id++, -1, &suppressGenericNames);
}
else if (e->isType(KST_KServiceSeparator))
@@ -772,6 +780,8 @@
delete *it;
}
subMenus.clear();
+ searchSubMenuIDs.clear();
+ searchMenuItems.clear();
}
void PanelServiceMenu::selectFirstItem()
@@ -796,3 +806,72 @@
RecentlyLaunchedApps::the().m_bNeedToUpdate = true;
}
+void PanelServiceMenu::setSearchString(const QString &searchString)
+{
+ // We must initialize the menu, because it might have not been opened before
+ initialize();
+
+ bool foundSomething = false;
+ std::set<int> nonemptyMenus;
+ std::set<int>::const_iterator menuItemIt(searchMenuItems.begin());
+ // Apply the filter on this menu
+ for (; menuItemIt != searchMenuItems.end(); ++menuItemIt) {
+ int id = *menuItemIt;
+ KService* s = dynamic_cast< KService* >( static_cast< KSycocaEntry* >( entryMap_[ id ]));
+ QString menuText = text(id);
+ if (menuText.contains(searchString, false) > 0
+ || ( s != NULL && ( s->name().contains(searchString, false) > 0
+ || s->exec().contains(searchString, false) > 0
+ || s->comment().contains(searchString, false) > 0
+ || s->genericName().contains(searchString, false) > 0
+ || s->exec().contains(searchString, false) > 0 )
+ )) {
+ setItemEnabled(id, true);
+ foundSomething = true;
+ nonemptyMenus.insert(id);
+ }
+ else {
+ setItemEnabled(id, false);
+ }
+ }
+ // Apply the filter on this menu
+ /*for (int i=count()-1; i>=0; --i) {
+ int id = idAt(i);
+ QString menuText = text(id);
+ if (menuText.contains(searchString, false) > 0) {
+ setItemEnabled(id, true);
+ foundSomething = true;
+ nonemptyMenus.insert(id);
+ }
+ else {
+ setItemEnabled(id, false);
+ }
+ }*/
+
+ PanelServiceMenuMap::iterator it(searchSubMenuIDs.begin());
+ // Apply the search filter on submenus
+ for (; it != searchSubMenuIDs.end(); ++it) {
+ it.key()->setSearchString(searchString);
+ if (nonemptyMenus.find(it.data()) != nonemptyMenus.end()) {
+ // if the current menu is a match already, we don't
+ // block access to the contained items
+ setItemEnabled(it.data(), true);
+ it.key()->setSearchString(QString());
+ foundSomething = true;
+ }
+ else if (it.key()->hasSearchResults()) {
+ setItemEnabled(it.data(), true);
+ foundSomething = true;
+ }
+ else {
+ setItemEnabled(it.data(), false);
+ }
+ }
+
+ hasSearchResults_ = foundSomething;
+}
+
+bool PanelServiceMenu::hasSearchResults()
+{
+ return hasSearchResults_;
+}
--- kicker/kicker/ui/service_mnu.h
+++ kicker/kicker/ui/service_mnu.h
@@ -26,6 +26,7 @@
#include <qmap.h>
#include <qvaluevector.h>
+#include <set>
#include <ksycocaentry.h>
#include <kservice.h>
@@ -41,8 +42,11 @@
* @author Rik Hemsley <rik@kde.org>
*/
+class KLineEdit;
typedef QMap<int, KSycocaEntry::Ptr> EntryMap;
typedef QValueVector<QPopupMenu*> PopupMenuList;
+class PanelServiceMenu;
+typedef QMap<PanelServiceMenu*,int> PanelServiceMenuMap;
class KDE_EXPORT PanelServiceMenu : public KPanelMenu
{
@@ -63,6 +67,8 @@
virtual void showMenu();
bool highlightMenuItem( const QString &menuId );
void selectFirstItem();
+ void setSearchString(const QString& searchString);
+ bool hasSearchResults();
private:
void fillMenu( KServiceGroup::Ptr &_root, KServiceGroup::List &_list,
@@ -116,6 +122,9 @@
bool addmenumode_;
QPoint startPos_;
PopupMenuList subMenus;
+ PanelServiceMenuMap searchSubMenuIDs;
+ bool hasSearchResults_;
+ std::set<int> searchMenuItems;
private slots:
void slotContextMenu(int);