Added search function to Kicker

Closes bug 221


git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1165317 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
v3.5.13-sru
tpearson 14 years ago
parent a5edd20f0d
commit c851eb7595

@ -13,7 +13,7 @@ libkicker_ui_la_SOURCES = addbutton_mnu.cpp appletitem.ui appletview.ui addapple
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,8 @@ noinst_HEADERS = addapplet.h appletwidget.h addbutton_mnu.h addapplet_mnu.h appl
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

@ -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(TQWidget *parent, const TQString &msg, const char* name) :
KLineEdit(parent, name)
{
mDrawClickMsg = true;
setClickMessage( msg );
}
ClickLineEdit::~ClickLineEdit() {}
void ClickLineEdit::setClickMessage( const TQString &msg )
{
mClickMessage = msg;
repaint();
}
void ClickLineEdit::setText( const TQString &txt )
{
mDrawClickMsg = txt.isEmpty();
repaint();
KLineEdit::setText( txt );
}
void ClickLineEdit::drawContents( TQPainter *p )
{
KLineEdit::drawContents( p );
if ( mDrawClickMsg == true && !hasFocus() ) {
TQPen tmp = p->pen();
p->setPen( gray );
TQRect cr = contentsRect();
p->drawText( cr, AlignAuto|AlignVCenter, mClickMessage );
p->setPen( tmp );
}
}
void ClickLineEdit::focusInEvent( TQFocusEvent *ev )
{
if ( mDrawClickMsg == true )
{
mDrawClickMsg = false;
repaint();
}
TQLineEdit::focusInEvent( ev );
}
void ClickLineEdit::focusOutEvent( TQFocusEvent *ev )
{
if ( text().isEmpty() )
{
mDrawClickMsg = true;
repaint();
}
TQLineEdit::focusOutEvent( ev );
}
#include "clicklineedit.moc"

@ -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( TQWidget *parent, const TQString &msg = TQString::null, const char* name = 0 );
~ClickLineEdit();
void setClickMessage( const TQString &msg );
TQString clickMessage() const { return mClickMessage; }
virtual void setText( const TQString& txt );
protected:
virtual void drawContents( TQPainter *p );
virtual void focusInEvent( TQFocusEvent *ev );
virtual void focusOutEvent( TQFocusEvent *ev );
private:
TQString mClickMessage;
bool mDrawClickMsg;
};
}
#endif // CLICKLINEEDIT_H

@ -26,9 +26,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <unistd.h>
#include <dmctl.h>
#include <tqhbox.h>
#include <tqimage.h>
#include <tqlabel.h>
#include <tqpainter.h>
#include <tqstyle.h>
#include <tqtimer.h>
#include <tqtooltip.h>
#include <dcopclient.h>
#include <kapplication.h>
@ -40,9 +44,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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"
@ -57,10 +63,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "popupmenutitle.h"
#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(TQString::null, TQString::null, 0, "KMenu")
, bookmarkMenu(0)
@ -165,6 +174,25 @@ void PanelKMenu::paletteChanged()
}
}
/* 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 TQHBox {
public:
MenuHBox(PanelKMenu* parent) : TQHBox(parent)
{
}
virtual void keyPressEvent(TQKeyEvent *e)
{
}
private:
PanelKMenu *parent;
};
void PanelKMenu::initialize()
{
// kdDebug(1210) << "PanelKMenu::initialize()" << endl;
@ -191,6 +219,22 @@ void PanelKMenu::initialize()
// add services
PanelServiceMenu::initialize();
// Insert search field
TQHBox* hbox = new TQHBox( this );
KToolBarButton *clearButton = new KToolBarButton( "locationbar_erase", 0, hbox );
searchEdit = new KPIM::ClickLineEdit(hbox, " "+i18n("Press '/' to search..."));
hbox->setFocusPolicy(TQWidget::StrongFocus);
hbox->setFocusProxy(searchEdit);
hbox->setSpacing( 3 );
connect(clearButton, TQT_SIGNAL(clicked()), searchEdit, TQT_SLOT(clear()));
connect(this, TQT_SIGNAL(aboutToHide()), this, TQT_SLOT(slotClearSearch()));
connect(searchEdit, TQT_SIGNAL(textChanged(const TQString&)),
this, TQT_SLOT( slotUpdateSearch( const TQString&)));
insertItem(hbox, searchLineID, 0);
//TQToolTip::add(clearButton, i18n("Clear Search"));
//TQToolTip::add(searchEdit, i18n("Enter the name of an application"));
if (KickerSettings::showMenuTitles())
{
int id;
@ -581,6 +625,47 @@ void PanelKMenu::mouseMoveEvent(TQMouseEvent *e)
PanelServiceMenu::mouseMoveEvent( &newEvent );
}
void PanelKMenu::slotUpdateSearch(const TQString& searchString)
{
kdDebug() << "Searching for " << searchString << endl;
setSearchString(searchString);
}
void PanelKMenu::slotClearSearch()
{
if (searchEdit && searchEdit->text().isEmpty() == false) {
TQTimer::singleShot(0, searchEdit, TQT_SLOT(clear()));
}
}
void PanelKMenu::keyPressEvent(TQKeyEvent* 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() == TQt::Key_Slash && !searchEdit->hasFocus()) {
if (indexOf(searchLineID) >=0 ) {
setActiveItem(indexOf(searchLineID));
}
}
else if (e->key() == TQt::Key_Escape && searchEdit->text().isEmpty() == false) {
searchEdit->clear();
}
else if (e->key() == TQt::Key_Delete && !searchEdit->hasFocus() &&
searchEdit->text().isEmpty() == false)
{
searchEdit->clear();
}
else {
KPanelMenu::keyPressEvent(e);
}
}
void PanelKMenu::configChanged()
{
RecentlyLaunchedApps::the().m_bNeedToUpdate = false;

@ -30,6 +30,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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 +79,8 @@ protected slots:
void slotSaveSession();
void slotRunCommand();
void slotEditUserContact();
void slotUpdateSearch(const TQString &searchtext);
void slotClearSearch();
void paletteChanged();
virtual void configChanged();
void updateRecent();
@ -87,6 +95,8 @@ protected:
void mouseMoveEvent(TQMouseEvent *);
bool loadSidePixmap();
void doNewSession(bool lock);
void filterMenu(PanelServiceMenu* menu, const TQString &searchString);
void keyPressEvent(TQKeyEvent* e);
void createRecentMenuItems();
virtual void clearSubmenus();
@ -101,6 +111,8 @@ private:
KActionCollection *actionCollection;
KBookmarkOwner *bookmarkOwner;
PopupMenuList dynamicSubMenus;
KPIM::ClickLineEdit *searchEdit;
static const int searchLineID;
};
#endif

@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <tqbitmap.h>
#include <tqpixmap.h>
#include <tqimage.h>
#include <tqmap.h>
#include <dcopclient.h>
#include <kapplication.h>
@ -100,6 +101,8 @@ void PanelServiceMenu::initialize()
clear();
clearSubmenus();
searchSubMenuIDs.clear();
searchMenuItems.clear();
doInitialize();
}
@ -202,6 +205,10 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
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 @@ void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
}
KService::Ptr s(static_cast<KService *>(e));
searchMenuItems.insert(id);
insertMenuItem(s, id++, -1, &suppressGenericNames);
}
else if (e->isType(KST_KServiceSeparator))
@ -797,6 +805,8 @@ void PanelServiceMenu::slotClear()
delete *it;
}
subMenus.clear();
searchSubMenuIDs.clear();
searchMenuItems.clear();
}
void PanelServiceMenu::selectFirstItem()
@ -804,6 +814,76 @@ void PanelServiceMenu::selectFirstItem()
setActiveItem(indexOf(serviceMenuStartId()));
}
void PanelServiceMenu::setSearchString(const TQString &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 ]));
TQString 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);
TQString 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(TQString());
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_;
}
// updates "recent" section of KMenu
void PanelServiceMenu::updateRecentlyUsedApps(KService::Ptr &service)
{

@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SERVICE_MENU_H
#include <tqmap.h>
#include <set>
#include <tqvaluevector.h>
#include <ksycocaentry.h>
@ -41,8 +42,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @author Rik Hemsley <rik@kde.org>
*/
class KLineEdit;
typedef TQMap<int, KSycocaEntry::Ptr> EntryMap;
typedef TQValueVector<TQPopupMenu*> PopupMenuList;
class PanelServiceMenu;
typedef TQMap<PanelServiceMenu*,int> PanelServiceMenuMap;
class KDE_EXPORT PanelServiceMenu : public KPanelMenu
{
@ -63,6 +67,8 @@ public:
virtual void showMenu();
bool highlightMenuItem( const TQString &menuId );
void selectFirstItem();
void setSearchString(const TQString& searchString);
bool hasSearchResults();
private:
void fillMenu( KServiceGroup::Ptr &_root, KServiceGroup::List &_list,
@ -114,6 +120,9 @@ protected:
bool addmenumode_;
TQPoint startPos_;
PopupMenuList subMenus;
PanelServiceMenuMap searchSubMenuIDs;
bool hasSearchResults_;
std::set<int> searchMenuItems;
private slots:
void slotContextMenu(int);

Loading…
Cancel
Save