/*************************************************************************** * Copyright (c) 2005 Dominik Seichter * * * * 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ***************************************************************************/ #include "find_mnu.h" #include "k_mnu.h" #include "kickerSettings.h" #include "menuinfo.h" #include "menumanager.h" #include "popupmenutitle.h" #include #include #include #include #include #include PanelFindMenu::PanelFindMenu(QWidget *parent, const char *name ) : KPanelMenu(parent, name) { } void PanelFindMenu::initialize() { KPanelMenu::slotClear(); QHBox* hbox = new QHBox( this ); hbox->setSpacing( 3 ); new QLabel( i18n("Name:"), hbox ); m_searchLine = new KLineEdit( i18n("Application Name"), hbox ); connect( m_searchLine, SIGNAL( textChanged( const QString & ) ), this, SLOT( updateSearch( const QString & ) ) ); setItemEnabled( insertItem(new PopupMenuTitle(i18n("Find an Application"), font()) ), false ); insertItem( hbox ); insertSeparator(); } void PanelFindMenu::slotExec(int id) { if (!m_entryMap.contains(id)) return; KSycocaEntry* e = m_entryMap[id]; kapp->propagateSessionManager(); KService::Ptr service = static_cast(e); KApplication::startServiceByDesktopPath(service->desktopEntryPath(), QStringList(), 0, 0, 0, "", true); MenuManager::the()->kmenu()->updateRecentMenuItems(service); } void PanelFindMenu::updateSearch( const QString & str ) { QStringList menu_ext = KickerSettings::menuExtensions(); QValueList::ConstIterator it; // first step is to clear the old search results for ( it=m_ids.begin(); it!=m_ids.end(); ++it ) removeItem( *it ); m_ids.clear(); m_entryMap.clear(); // do not allow empty search strings if ( !str.isEmpty() ) parseServices( str, QString::null ); } void PanelFindMenu::parseServices( const QString & str, const QString & relPath ) { KServiceGroup::List::ConstIterator it; // We ask KSycoca to give us all services (sorted). KServiceGroup::Ptr root = KServiceGroup::group( relPath ); if (!root || !root->isValid()) return; KServiceGroup::List m_list = root->entries(true, true, true, KickerSettings::detailedMenuEntries() && !KickerSettings::detailedEntriesNamesFirst()); QStringList suppressGenericNames = root->suppressGenericNames(); if (m_list.isEmpty()) return; for (it = m_list.begin(); it != m_list.end(); ++it) { KSycocaEntry* e = *it; if (e->isType(KST_KServiceGroup)) { KServiceGroup::Ptr g(static_cast(e)); // Ignore dotfiles. if ((g->name().at(0) == '.')) continue; // Avoid adding empty groups. KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath()); if (subMenuRoot->childCount() == 0) continue; parseServices( str, g->relPath() ); } else if (e->isType(KST_KService)) { KService::Ptr s(static_cast(e)); insertMenuItem(s, str, suppressGenericNames); } } } void PanelFindMenu::insertMenuItem( KService::Ptr & s, const QString & str, const QStringList & suppressGenericNames ) { int id; // check wether this KService matches the users // search string. We search case insensitive in: // - Name // - Generic Name (e.g. "Mail Client") // - Comment // - Executable (e.g. "kmail") if ( !(s->name().contains( str, false ) || s->genericName().contains( str, false ) || s->comment().contains( str, false ) || s->exec().contains( str, false )) ) return; QString serviceName = s->name(); // add comment if (KickerSettings::detailedMenuEntries()) { QString comment = s->genericName(); if ( !comment.isEmpty() ) { if (KickerSettings::detailedEntriesNamesFirst()) { if (!(suppressGenericNames.contains(s->untranslatedGenericName()))) serviceName = QString( "%1 (%2)" ).arg( serviceName ).arg( comment ); } else serviceName = QString( "%1 (%2)" ).arg( comment ).arg( serviceName ); } } // restrict menu entries to a sane length if ( serviceName.length() > 60 ) { serviceName.truncate( 57 ); serviceName += "..."; } // check for NoDisplay if (s->noDisplay()) return; // ignore dotfiles. if ((serviceName.at(0) == '.')) return; // item names may contain ampersands. To avoid them being converted // to accelerators, replace them with two ampersands. serviceName.replace("&", "&&"); QIconSet iconset; if (KickerSettings::menuEntryHeight() > 0) { iconset = KGlobal::instance()->iconLoader()->loadIconSet( s->icon(), KIcon::NoGroup, KickerSettings::menuEntryHeight()); } else if (KickerSettings::menuEntryHeight() == 0) { QPixmap normal = KGlobal::instance()->iconLoader()->loadIcon( s->icon(), KIcon::Small, 0, KIcon::DefaultState, 0L, true); QPixmap active = KGlobal::instance()->iconLoader()->loadIcon( s->icon(), KIcon::Small, 0, KIcon::ActiveState, 0L, true); // make sure they are not larger than 20x20 if (normal.width() > 20 || normal.height() > 20) { normal.convertFromImage(normal.convertToImage() .smoothScale(20,20)); } if (active.width() > 20 || active.height() > 20) { active.convertFromImage(active.convertToImage() .smoothScale(20,20)); } iconset.setPixmap(normal, QIconSet::Small, QIconSet::Normal); iconset.setPixmap(active, QIconSet::Small, QIconSet::Active); } id = insertItem(iconset, serviceName ); m_ids.append( id ); m_entryMap.insert(id, static_cast(s)); }