summaryrefslogtreecommitdiffstats
path: root/src/menuhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/menuhandler.cpp')
-rw-r--r--src/menuhandler.cpp1712
1 files changed, 1712 insertions, 0 deletions
diff --git a/src/menuhandler.cpp b/src/menuhandler.cpp
new file mode 100644
index 0000000..06ca863
--- /dev/null
+++ b/src/menuhandler.cpp
@@ -0,0 +1,1712 @@
+
+/***************************************************************************
+ * Copyright (C) 2006-2007 by Marco Martin *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the Lesser 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 <klocale.h>
+#include <kmessagebox.h>
+#include <kuser.h>
+#include <kstandarddirs.h>
+#include <kmimetype.h>
+#include <qfocusdata.h>
+#include <qstyle.h>
+#include <qfile.h>
+#include <qcursor.h>
+#include <kpopupmenu.h>
+#include <kdebug.h>
+
+
+#include "menuhandler.h"
+#include "buttons.h"
+
+MenuHandler::MenuHandler( QWidget *parent, Prefs *prefs, char *name, WFlags fl)
+ :QFrame(parent, name, fl ), searchMode(false)
+{
+
+ prefSkel = prefs;
+
+ //make a KServiceGroup to iterate the menu entries
+ KServiceGroup::Ptr service = KServiceGroup::root();
+
+ //Kicker config
+ QString kickerConfPath = locate("config", "kickerrc");
+ kickerConf = new KConfig(kickerConfPath);
+
+ kickerConfWatch = new KDirWatch( this );
+ kickerConfWatch->addFile(kickerConfPath);
+ connect( kickerConfWatch, SIGNAL(dirty(const QString&)), this,
+ SLOT(slotModKickerConf()) );
+ connect( kickerConfWatch, SIGNAL(dirty(const QString&)), this,
+ SIGNAL(kickerConfChanged()) );
+
+ if( _newAppsNotification = prefSkel->newAppsNotification() )
+ {
+ //init the old and new installed list
+ oldInstalledList = prefSkel->oldInstalledApps();
+ loadNewInstalledApps();
+ initOldInstalledApps(service);
+ //save the creation time
+ prefSkel->setOldInstalledAppsAge(time(0));
+ initNewInstalledApps(service);
+ if( newInstalledList.count() > 0 )
+ emit(newApplications(newInstalledList.count()));
+ prefSkel->setOldInstalledApps(oldInstalledList);
+ prefSkel->setNewInstalledApps( newInstalledList );
+ prefSkel->setNewInstalledAppsTimeStamps( newInstalledTimeStamps );
+ }
+
+
+ //Main widget initialization
+ menu = new Menu(this, "tastyMenu");
+
+ MenuHandlerLayout = new QVBoxLayout( this, 0, 0, "MenuHandlerLayout");
+ MenuHandlerLayout->addWidget(menu);
+
+ readConfig();
+ setupColumns();
+
+ //Searchline...
+ iconLoader = KGlobal::iconLoader();
+ QPixmap icon;
+ if( QApplication::reverseLayout() )
+ icon = iconLoader->loadIcon("locationbar_erase", KIcon::Small);
+ else
+ icon = iconLoader->loadIcon("clear_left", KIcon::Small);
+ menu->clearButton->setIconSet(icon);
+
+ connect(menu->clearButton, SIGNAL(clicked()), menu->searchLine, SLOT (clear()) );
+
+ menu->detachButton->setIconSet(QPixmap(uic_findImage("detach.png")));
+ connect(menu->detachButton, SIGNAL(clicked()), this, SLOT (switchWindowMode()) );
+
+ menu->searchLine->setContextMenuEnabled(false);
+
+ //event filters for keyboard navigation
+ menu->clearButton->installEventFilter(this);
+ menu->searchLine->installEventFilter(this);
+ menu->menuModes->installEventFilter(this);
+ menu->runButton->installEventFilter(this);
+ menu->switchButton->installEventFilter(this);
+ menu->lockButton->installEventFilter(this);
+ menu->logoutButton->installEventFilter(this);
+
+ //action buttons
+ icon = iconLoader->loadIcon("exit", KIcon::Toolbar);
+ menu->logoutButton->setIconSet(icon);
+
+ icon = iconLoader->loadIcon("lock", KIcon::Toolbar);
+ menu->lockButton->setIconSet(icon);
+
+ icon = iconLoader->loadIcon("run", KIcon::Toolbar);
+ menu->runButton->setIconSet(icon);
+
+ icon = iconLoader->loadIcon("locationbar_erase", KIcon::Toolbar);
+ menu->clearRecentButton->setIconSet(icon);
+
+ setCaption("Tasty Menu");
+ setIcon(iconLoader->loadIcon("kmenu", KIcon::Panel));
+
+ //user icon and login
+ KUser *user = new KUser ();
+ QString loginName (user->loginName ());
+ QImage
+ userImage (locate
+ ("data", "/home/" + loginName + "/.face.icon"));
+ if( !userImage.isNull() )
+ {
+ userImage = userImage.smoothScale (KIcon::SizeSmallMedium, KIcon::SizeSmallMedium);
+ menu->switchButton->setIconSet(QPixmap(userImage));
+ }
+ menu->switchButton->setText(loginName);
+ sessionsMenu = new QPopupMenu();
+ menu->switchButton->setPopup(sessionsMenu);
+
+
+ initializeRecentlyUsed( );
+
+ populateList( service, menu->rootList, NULL, false );
+
+ //left/middle mouse button
+ connect (menu->dynamicList,
+ SIGNAL (activated(QListViewItem *, const QPoint & , int )), this,
+ SLOT (dynListClicked(QListViewItem *, const QPoint &, int)));
+ connect (menu->rootList,
+ SIGNAL (activated(QListViewItem *, const QPoint & , int )), this,
+ SLOT (rootListClicked(QListViewItem *, const QPoint &, int)));
+ connect (menu->childList,
+ SIGNAL (activated(QListViewItem *, const QPoint & , int )), this,
+ SLOT (childListClicked(QListViewItem *, const QPoint &, int)));
+
+ //right mouse button
+ connect (menu->dynamicList,
+ SIGNAL (contextMenuRequested(QListViewItem *, const QPoint & , int )), this,
+ SLOT (slotContextMenu(QListViewItem *, const QPoint &, int)));
+ connect (menu->rootList,
+ SIGNAL (contextMenuRequested(QListViewItem *, const QPoint & , int )), this,
+ SLOT (slotContextMenu(QListViewItem *, const QPoint &, int)));
+ connect (menu->childList,
+ SIGNAL (contextMenuRequested(QListViewItem *, const QPoint & , int )), this,
+ SLOT (slotContextMenu(QListViewItem *, const QPoint &, int)));
+
+ //don't open categories on mouseover on childlist
+ //menu->childList->setEasyOpen( true );
+
+ connect (menu->clearRecentButton, SIGNAL (clicked()), this, SLOT (clearDynList()));
+ connect (menu->logoutButton, SIGNAL (clicked()), this, SLOT (doLogout()));
+ connect (menu->lockButton, SIGNAL (clicked()), this, SLOT (doLock()));
+ connect (menu->runButton, SIGNAL (clicked()), this, SLOT (runDialog()));
+
+ connect( sessionsMenu, SIGNAL(aboutToShow()), SLOT(slotPopulateSessions()) );
+ connect( sessionsMenu, SIGNAL(activated(int)), SLOT(slotSessionActivated(int)) );
+
+
+ connect( menu->menuModes, SIGNAL(activated(int)), SLOT(menuModeChanged(int)) );
+ menuModeChanged(_menuMode);
+}
+
+
+MenuHandler::~MenuHandler()
+{
+}
+
+void MenuHandler::loadNewInstalledApps()
+{
+ //Notification for newly installed apps
+ xdgMenuLister = new KDirLister( );
+ KStandardDirs *standardDir=new KStandardDirs();
+ QStringList appDirs = standardDir->findDirs("xdgdata-apps", ".");
+ firstListing = 0;
+ for(QStringList::Iterator it = appDirs.begin(); it != appDirs.end(); ++it)
+ {
+ xdgMenuLister->openURL(*it, true);
+ /*HACK: links to kde programs are often installed in a kde subdirectory
+ of one of these, so i duplicate all the entries with entry+"kde/"*/
+ QString appDirWithKde = (*it)+"kde/";
+ if( QFile::exists(appDirWithKde) )
+ {
+ xdgMenuLister->openURL(appDirWithKde, true);
+ firstListing++;
+ }
+ }
+
+ firstListing += appDirs.count();
+ connect( xdgMenuLister, SIGNAL(newItems(const KFileItemList &)), this,
+ SLOT(slotApplicationsAdded(const KFileItemList &)) );
+ connect( xdgMenuLister, SIGNAL(deleteItem( KFileItem *)), this,
+ SLOT(slotApplicationRemoved()) );
+
+ xdgMenuWatch = new KDirWatch(this);
+ xdgMenuWatch->addFile(locateLocal("xdgconf-menu", "applications-kmenuedit.menu"));
+ //connect with slotApplicationRemoved() because we need to wait a while...
+ connect( xdgMenuWatch, SIGNAL(dirty(const QString&)), this,
+ SLOT(slotApplicationRemoved()) );
+
+ newInstalledList = prefSkel->newInstalledApps();
+ newInstalledTimeStamps = prefSkel->newInstalledAppsTimeStamps();
+
+ //expire old apps
+ for(uint i=0; i<newInstalledTimeStamps.count(); i++)
+ {
+ //127800 seconds = two days
+ if(time(0) - (uint)newInstalledTimeStamps[i] > 127800 )
+ {
+ newInstalledTimeStamps.remove(newInstalledTimeStamps.at(i));
+ newInstalledList.remove(newInstalledList.at(i));
+ }
+ }
+}
+
+void MenuHandler::setupColumns()
+{
+ menu->dynamicList->header()->hide();
+ menu->dynamicList->setResizeMode(QListView::AllColumns);
+ menu->dynamicList->addColumn("name");
+ menu->dynamicList->setShowToolTips(true);
+ menu->dynamicList->setSortColumn(-1);
+ menu->dynamicList->header()->setResizeEnabled(false);
+ menu->dynamicList->setHScrollBarMode(QScrollView::AlwaysOff);
+ menu->dynamicList->setActionIconSize( _actionIconSize );
+ menu->dynamicList->setRootIsDecorated( _showExpander );
+ //manage drag'n drop
+ menu->dynamicList->setAcceptDrops(true);
+ menu->dynamicList->setDragEnabled(true);
+ connect( menu->dynamicList, SIGNAL(moved()),
+ this, SLOT(dynListElemMoved()) );
+
+ menu->rootList->header()->hide();
+ menu->rootList->setResizeMode(QListView::AllColumns);
+ menu->rootList->addColumn("name");
+ menu->rootList->setSortColumn(-1);
+ menu->rootList->header()->setResizeEnabled(false);
+ menu->rootList->setHScrollBarMode(QScrollView::AlwaysOff);
+ menu->rootList->setHighLightGroups( false );
+ menu->rootList->setActionIconSize( _actionIconSize );
+ menu->rootList->setDragEnabled(true);
+
+ menu->childList->header()->hide();
+ menu->childList->setResizeMode(QListView::AllColumns);
+ menu->childList->addColumn("name");
+ menu->childList->setSortColumn(_alphabetical?0:-1);
+ menu->childList->header()->setResizeEnabled(false);
+ menu->childList->setHScrollBarMode(QScrollView::AlwaysOff);
+ menu->childList->setActionIconSize( _actionIconSize );
+ menu->childList->setRootIsDecorated( _showExpander );
+ menu->childList->setDragEnabled(true);
+}
+
+
+void MenuHandler::dynListElemMoved( )
+{
+ //very stupid: iterate the entire list and rewrite the favouriteList
+ favouriteList.clear();
+ QListViewItemIterator it( menu->dynamicList );
+
+ while ( it.current() )
+ {
+ TastyListViewItem *li = dynamic_cast<TastyListViewItem *>(it.current());
+
+ if( !li )
+ return;
+
+ favouriteList.append( li->getDeskopEntryPath() );
+ it++;
+ }
+
+ prefSkel->setFavouriteApps(favouriteList);
+ prefSkel->writeConfig();
+}
+
+
+bool MenuHandler::eventFilter( QObject *o, QEvent * e )
+{
+ if ( e->type() == QEvent::KeyPress )
+ {
+ QKeyEvent *keyEvent = (QKeyEvent *)e;
+ QFocusData *fData = focusData();
+ fData->home();
+
+ switch( keyEvent->key() )
+ {
+
+ case Qt::Key_Up:
+ if( dynamic_cast<QComboBox *>(o) )
+ return false;
+ fData->prev()->setFocus();
+ break;
+
+ case Qt::Key_Down:
+ {
+ if( dynamic_cast<QComboBox *>(o) )
+ return false;
+
+ //this is a workaround in order to set the focus on the
+ //right widget when the combobox is disabled
+ QWidget *nextWidget = fData->next();
+ if( nextWidget->isEnabled() )
+ nextWidget->setFocus();
+ else
+ fData->next()->setFocus();
+ }
+ break;
+
+ case Qt::Key_Right:
+ if( dynamic_cast<KListViewSearchLine *>(o) )
+ return false;
+ fData->next()->setFocus();
+ break;
+
+ case Qt::Key_Left:
+ if( dynamic_cast<KListViewSearchLine *>(o) )
+ return false;
+ fData->prev()->setFocus();
+ break;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ {
+ //only filter enter on search line
+ if( o != menu->searchLine )
+ return false;
+
+ QListViewItem *listItem = NULL;
+ //execute the only list item when there is exactly one
+ QListViewItemIterator it( menu->dynamicList,
+ QListViewItemIterator::Visible);
+ //listItem = it.current();
+ int count = 0;
+ //ensure the first level have only one result
+ while ( it.current() )
+ {
+ if( it.current()->childCount() == 0 )
+ {
+ count++;
+ listItem = it.current();
+ }
+ kdDebug() << "current: " << count << " " << it.current()->text(0);
+ if( count > 1 )
+ return false;
+ it++;
+ }
+
+ if( listItem )
+ {
+ dynListClicked(listItem, QPoint(0,0), 0);
+ menu->searchLine->clear();
+ }
+
+ break;
+ }
+
+ default:
+ return false;
+ break;
+ }
+ return true;
+ }
+ //for some reasons clicking with the right mouse button on the searchline everything crashes...
+/* else if( e->type() == QEvent::MouseButtonPress && o == menu->searchLine )
+ {return true;
+ QMouseEvent *mouseEvent = (QMouseEvent *)e;
+
+ if( mouseEvent->button() != QMouseEvent::RightButton )
+ return true;
+
+ if( menu->searchLine->text().length() < 4 )
+ return true;
+ else
+ return false;
+ }*/
+ else
+ return false;
+}
+
+
+void MenuHandler::readConfig()
+{
+ _menuMode = prefSkel->menuMode();
+ if( _menuMode < 0 )
+ _menuMode = 0;
+ menu->menuModes->setCurrentItem(_menuMode);
+
+ _currentCategory = prefSkel->currentCategory();
+
+ kickerConf->setGroup("menus");
+ _numRecentEntries = kickerConf->readNumEntry("NumVisibleEntries", 5);
+
+ _hideOneChild = prefSkel->hideOneChild();
+ _alphabetical = prefSkel->alphabetical();
+
+ favouriteList = prefSkel->favouriteApps();
+ if( favouriteList.isEmpty() )
+ {
+ favouriteList.append(locate("xdgdata-apps","kde/konqbrowser.desktop"));
+ favouriteList.append(locate("xdgdata-apps","kde/KMail.desktop"));
+ favouriteList.append(locate("xdgdata-apps","kde/Help.desktop"));
+ }
+
+ _showExpander = prefSkel->showExpander();
+ _alwaysCollapsed = prefSkel->alwaysCollapsed();
+
+ _displaySubText = prefSkel->displaySubText();
+
+ _iconSize1 = prefSkel->iconSize1();
+ if( _iconSize1 < 16 || _iconSize1 > 64 )
+ _iconSize1 = 22;
+ _iconSize2 = prefSkel->iconSize2();
+ if( _iconSize2 < 16 || _iconSize2 > 64 )
+ _iconSize2 = 22;
+ _iconSize3 = prefSkel->iconSize3();
+ if( _iconSize3 < 16 || _iconSize3 > 64 )
+ _iconSize3 = 22;
+
+ _actionIconSize = prefSkel->actionIconSize();
+ if( _actionIconSize > _iconSize1 )
+ _actionIconSize = _iconSize1;
+
+ //menu size
+ _menuWidth = 100.0/prefSkel->menuWidth();
+ _menuHeight = 100.0/prefSkel->menuHeight();
+ QRect r = QDesktopWidget().screenGeometry(this);
+ int w = (int)(r.width()/_menuWidth);
+ int h = (int)(r.height()/_menuHeight);
+ resize(w,h);
+
+ _kerryIntegration = prefSkel->kerryIntegration();
+ _strigiIntegration = prefSkel->strigiIntegration();
+
+ _isNormalWindow = prefSkel->isNormalWindow();
+ if( _isNormalWindow )
+ {
+ menu->detachButton->setIconSet(QPixmap(uic_findImage("attach.png")));
+ QToolTip::add( menu->detachButton, tr2i18n( "Make this window a popup menu" ) );
+ }
+ else
+ {
+ menu->detachButton->setIconSet(QPixmap(uic_findImage("detach.png")));
+ QToolTip::add( menu->detachButton, tr2i18n( "Make this menu a normal window" ) );
+ }
+
+ // disconnect(menu->searchLine, 0, 0, 0);
+ if( !_kerryIntegration && !_strigiIntegration )
+ {
+ //menu->searchLine->setListView((KListView *)(menu->dynamicList));
+ disconnect(menu->searchLine, SIGNAL(returnPressed( const QString &)),
+ this, SLOT (kerrySearch( const QString &)) );
+ disconnect(menu->searchLine, SIGNAL(returnPressed( const QString &)),
+ this, SLOT (strigiSearch( const QString &)) );
+ connect(menu->searchLine, SIGNAL(textChanged( const QString &)),
+ this, SLOT (initializeSearch( const QString &)) );
+ }
+ else if( _kerryIntegration )
+ {
+ menu->searchLine->setListView(NULL);
+ menu->searchLine->setEnabled(true);
+ disconnect(menu->searchLine, SIGNAL(textChanged( const QString &)),
+ this, SLOT (initializeSearch( const QString &)) );
+ disconnect(menu->searchLine, SIGNAL(returnPressed( const QString &)),
+ this, SLOT (strigiSearch( const QString &)) );
+ connect(menu->searchLine, SIGNAL(returnPressed( const QString &)),
+ this, SLOT (kerrySearch( const QString &)) );
+ menu->searchLine->setContextMenuEnabled(false);
+ }
+ else //strigi
+ {
+ menu->searchLine->setListView(NULL);
+ menu->searchLine->setEnabled(true);
+ disconnect(menu->searchLine, SIGNAL(textChanged( const QString &)),
+ this, SLOT (initializeSearch( const QString &)) );
+ disconnect(menu->searchLine, SIGNAL(returnPressed( const QString &)),
+ this, SLOT (kerrySearch( const QString &)) );
+ connect(menu->searchLine, SIGNAL(returnPressed( const QString &)),
+ this, SLOT (strigiSearch( const QString &)) );
+ menu->searchLine->setContextMenuEnabled(false);
+ }
+}
+
+void MenuHandler::updateConfig()
+{
+ readConfig();
+
+ menu->dynamicList->setActionIconSize( _actionIconSize );
+ menu->rootList->setActionIconSize( _actionIconSize );
+ menu->childList->setActionIconSize( _actionIconSize );
+
+ menu->dynamicList->setRootIsDecorated( _showExpander );
+ menu->childList->setRootIsDecorated( _showExpander );
+
+ menuModeChanged( _menuMode );
+ KServiceGroup::Ptr service = KServiceGroup::root();
+ menu->rootList->clear();
+ populateList( service, menu->rootList, NULL, false );
+}
+
+
+void MenuHandler::mousePressEvent( QMouseEvent *e)
+{
+ if(static_cast<QWidget *>(parent())->hasMouse())
+ {
+ close();
+ }
+ else if(!_isNormalWindow && !(rect().contains(e->pos())) )
+ {
+ hide();
+ QTimer::singleShot(200, this,SLOT(close()));
+ }
+}
+
+void MenuHandler::closeEvent ( QCloseEvent *e)
+{
+ e=e;
+
+ if( _isNormalWindow )
+ {
+ prefSkel->setNormalWindowWidth(width());
+ prefSkel->setNormalWindowHeight(height());
+ prefSkel->setNormalWindowX(x());
+ prefSkel->setNormalWindowY(y());
+ prefSkel->writeConfig();
+ }
+
+ //HACK: I wait a little bit to permit closing the menu
+ // when user clicks on the menu button again
+ QTimer::singleShot(50, this, SLOT(hide()));
+ emit(hidden());
+}
+
+void MenuHandler::popup(QPoint pos)
+{
+ if(isVisible())
+ {
+ close();
+ return;
+ }
+
+ menu->searchLine->setFocus();
+
+ int w;
+ int h;
+ if( !_isNormalWindow )
+ {
+ QRect r = QDesktopWidget().screenGeometry(this);
+ w = (int)(r.width()/_menuWidth);
+ h = (int)(r.height()/_menuHeight);
+ }
+ else
+ {
+ w = prefSkel->normalWindowWidth();
+ h = prefSkel->normalWindowHeight();
+ }
+
+ //the only way to make things proportioned
+ menu->leftFrame->setMaximumWidth( (int)((w-24)/3) );
+ menu->allAppsFrame->setMaximumHeight(menu->clearButton->height());
+
+ if( !_isNormalWindow )
+ move(pos);
+ else
+ move(prefSkel->normalWindowX(), prefSkel->normalWindowY());
+
+ resize(w,h);
+
+ show();
+}
+
+void MenuHandler::initOldInstalledApps(KServiceGroup::Ptr group)
+{
+ if( !group || !group->isValid() )
+ return;
+
+ //expires at 639000 seconds = 10 days
+ if( !prefSkel->oldInstalledApps().empty() ||
+ (time(0) - (uint)prefSkel->oldInstalledAppsAge() < 639000 )
+ )
+ return;
+
+ KServiceGroup::List list = group->entries(true, true, true, false);
+ for (KServiceGroup::List::ConstIterator it = list.begin ();
+ it != list.end (); it++)
+ {
+ KSycocaEntry *p = (*it);
+ if( p->isType( KST_KServiceGroup ) )
+ {
+ KServiceGroup *g = static_cast < KServiceGroup * > ( p );
+ if( g ->childCount() > 0 )
+ initOldInstalledApps(g);
+ }
+ else
+ {
+ KService *s = static_cast < KService * >(p);
+
+ oldInstalledList.append(s->desktopEntryPath());
+ }
+ }
+}
+
+void MenuHandler::initNewInstalledApps(KServiceGroup::Ptr group)
+{
+ if( !group || !group->isValid() )
+ return;
+ if( oldInstalledList.empty() )
+ return;
+
+ KServiceGroup::List list = group->entries(true, true, true, false);
+ for (KServiceGroup::List::ConstIterator it = list.begin ();
+ it != list.end (); it++)
+ {
+ KSycocaEntry *p = (*it);
+ if( p->isType( KST_KServiceGroup ) )
+ {
+ KServiceGroup *g = static_cast < KServiceGroup * > ( p );
+ if( g ->childCount()>0 )
+ initNewInstalledApps(g);
+ }
+ else
+ {
+ KService *s = static_cast < KService * > ( p );
+
+
+ QString path(s->desktopEntryPath());
+ if( oldInstalledList.findIndex(path) == -1 &&
+ newInstalledList.findIndex(path) == -1 )
+ {
+ newInstalledList.append(path);
+ newInstalledTimeStamps.append(time(0));
+ oldInstalledList.append(path);
+ }
+ }
+ }
+}
+
+
+bool MenuHandler::searchNewItems(KServiceGroup::Ptr group)
+{
+ if( !group || !group->isValid() )
+ return false;
+
+ if( newInstalledList.count() <= 0 )
+ return false;
+
+ KServiceGroup::List list = group->entries(true, true, true, false);
+ for (KServiceGroup::List::ConstIterator it = list.begin ();
+ it != list.end (); it++)
+ {
+ KSycocaEntry *p = (*it);
+ if( p->isType( KST_KServiceGroup ) )
+ {
+ KServiceGroup *g = static_cast < KServiceGroup * > ( p );
+ if( g ->childCount()<=0 )
+ continue;
+
+ if(searchNewItems(g))
+ return true;
+ }
+ else
+ {
+ KService *s = static_cast < KService * >(p);
+
+
+ /*kdDebug() << group->relPath() << ": "<< s->desktopEntryPath()
+ <<(( newInstalledList.findIndex(s->desktopEntryPath()) != -1 )
+ ?" present":" not present")<< endl;*/
+ if( newInstalledList.findIndex(s->desktopEntryPath()) != -1 )
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*KServiceGroup::List MenuHandler::getServiceGroupList( KServiceGroup *serviceGroup )
+{
+ QString key(serviceGroup->directoryEntryPath());
+
+ if( sListMap.contains(key) )
+ return sListMap[key];
+ else
+ {
+ KServiceGroup::List list = serviceGroup->entries(true, true, true, false);
+ sListMap[key] = list;
+ return list;
+ }
+}*/
+
+void MenuHandler::populateList( KServiceGroup *serviceGroup, TastyListView *listView,
+ TastyListViewItem *listItemFather,
+ bool recursive, const QString & query )
+{
+ if( !serviceGroup || !serviceGroup->isValid() )
+ return;
+ serviceGroup->setShowEmptyMenu(false);
+ //KServiceGroup::List list = serviceGroup->entries(true, true, true, false);
+
+ KServiceGroup::List list = serviceGroup->entries(true, true, true, false);
+
+ TastyListViewItem *prevListItem = NULL;
+
+ for (KServiceGroup::List::ConstIterator it = list.begin ();
+ it != list.end (); it++)
+ {
+ KSycocaEntry *p = (*it);
+
+ int iconSize;
+ if( listView && listView == menu->rootList
+ || listItemFather && listItemFather->listView() == menu->rootList )
+ iconSize = _iconSize2;
+ else if( listView && listView == menu->childList
+ || listItemFather && listItemFather->listView() == menu->childList)
+ iconSize = _iconSize3;
+ else
+ iconSize = _iconSize1;
+
+ if( p->isType( KST_KServiceGroup ) )
+ {
+ //KServiceGroup::Ptr g (static_cast < KServiceGroup * >(p));
+ KServiceGroup *g = static_cast < KServiceGroup * > ( p );
+ if( g ->childCount()<=0 || (g->name().at(0) == '.') )
+ continue;
+
+ g->setShowEmptyMenu(false);
+
+ int numChilds = g->childCount();
+ //FIXME: useless?
+ if(numChilds == 0)
+ continue;
+
+ QPixmap iconPix = iconLoader->loadIcon(g->icon(), KIcon::Toolbar,iconSize);
+
+ if ( iconPix.height () != iconSize)
+ {
+ QImage img = iconPix.convertToImage();
+ if( !img.isNull() )
+ {
+ img = img.smoothScale ( iconSize, iconSize);
+ iconPix = QPixmap (img);
+ }
+ }
+
+ TastyListViewItem *listItem;
+ if( listView )
+ listItem = new TastyListViewItem( listView, prevListItem,
+ !g->caption().isEmpty()?g->caption()
+ :g->name().section('/', -2));
+ else
+ listItem = new TastyListViewItem( listItemFather, prevListItem,
+ !g->caption().isEmpty()?g->caption()
+ :g->name().section('/', -2));
+
+ listItem->setPath( g->relPath() );
+ listItem->setType( TastyListViewItem::ServiceGroup );
+ //OpenGrup only on menu->rootList
+ if( listView == menu->rootList )
+ listItem->setActionType( TastyListViewItem::OpenGroup );
+ else
+ listItem->setActionType( TastyListViewItem::Collapse );
+
+ prevListItem = listItem;
+
+ listItem->setPixmap(0, iconPix);
+
+ //avoiding to display empty categories or with only one child (very common in SUSE)
+ if( (!_hideOneChild && numChilds > 0) || numChilds > 1 )
+ {
+ if( listView )
+ {
+ listView->insertItem( listItem );
+ if( _currentCategory == listItem->text(0) && listView == menu->rootList )
+ {
+ listView->setCurrentItem(listItem);
+ listView->setOpenItem(static_cast<QListViewItem *>(listItem));
+ rootListClicked(listItem, QPoint(0,0), 0);
+ }
+ if(searchNewItems(g))
+ listItem->setHighLight(true);
+ }
+ else if(listItemFather)
+ listItemFather->insertItem( listItem );
+
+ if( recursive )
+ populateList( g, NULL, listItem, true, query);
+
+ //the left column is always open
+ if( listView == menu->dynamicList ||
+ (listItemFather && listItemFather->listView()==menu->dynamicList))
+ listItem->setOpen( true );
+ else
+ listItem->setOpen( !_alwaysCollapsed );
+
+ if( listItem->getActionType() == TastyListViewItem::Expand &&
+ listItem->isOpen() )
+ listItem->setActionType( TastyListViewItem::Collapse );
+ else if( listItem->getActionType() == TastyListViewItem::Collapse &&
+ !listItem->isOpen() )
+ listItem->setActionType( TastyListViewItem::Expand );
+ }
+ else if( recursive )
+ {
+ if( listView )
+ populateList( g, listView, NULL, true, query);
+
+ else if(listItemFather)
+ populateList( g, NULL, listItemFather, true, query);
+
+ delete listItem;
+ }
+
+ }
+ else //The entry is a Service
+ {
+ KService *s = static_cast < KService * >(p);
+
+ if( s->name().at(0) == '.' )
+ continue;
+
+ const bool isSeparator = s->name() == "separator";
+
+
+ //Name and comment
+ QString itemName = s->name();
+ QString subText= QString();
+ if( !isSeparator )
+ {
+ if( s->comment() != NULL && !s->comment().isEmpty() )
+ subText = s->comment();
+ else if( s->genericName() && !s->genericName().isEmpty() )
+ subText = s->genericName();
+ }
+
+ //Have we done a query? (this improves query speed)
+ if( query != NULL
+ && !itemName.contains(query, false)
+ && !subText.contains(query, false) )
+ continue;
+
+ TastyListViewItem *listItem;
+
+ if( isSeparator )
+ {
+ if( _alphabetical )
+ continue;
+
+ if(listView)
+ {
+ listItem = new TastyListViewItem( listView, prevListItem, "separator" );
+ listView->insertItem( listItem );
+ }
+ else if(listItemFather)
+ {
+ listItem = new TastyListViewItem( listItemFather, prevListItem, "separator" );
+ listItemFather->insertItem( listItem );
+ }
+ else
+ return;
+
+ prevListItem = listItem;
+ listItem->setSelectable(false);
+ continue;
+ }
+
+ if( listView )
+ listItem = new TastyListViewItem( listView, prevListItem, itemName );
+ else
+ listItem = new TastyListViewItem( listItemFather, prevListItem, itemName );
+
+ listItem->setDisplaySubText(_displaySubText);
+ listItem->setPath( serviceGroup->relPath() );
+ listItem->setDeskopEntryPath( s->desktopEntryPath() );
+ listItem->setMenuId( s->menuId() );
+ listItem->setType( TastyListViewItem::Service );
+ listItem->setActionType( TastyListViewItem::AddBookMark );
+
+ listItem->setText(0,itemName);
+ listItem->setSubText(subText);
+
+ prevListItem = listItem;
+
+ QPixmap iconPix = s->pixmap( KIcon::Toolbar, iconSize );
+ if ( iconPix.height () != iconSize)
+ {
+ QImage img = iconPix.convertToImage();
+ if( !img.isNull() )
+ {
+ img = img.smoothScale ( iconSize, iconSize);
+ iconPix = QPixmap (img);
+ }
+ }
+ listItem->setPixmap(0, iconPix);
+
+ if( listView )
+ {
+ listView->insertItem( listItem );
+ }
+ else if(listItemFather)
+ {
+ listItemFather->insertItem( listItem );
+ }
+ if( newInstalledList.findIndex(s->desktopEntryPath()) != -1 )
+ listItem->setHighLight(true);
+ }
+
+ }
+
+}
+
+
+void MenuHandler::initializeRecentlyUsed( )
+{
+
+ recentlyUsedMap.clear();
+ moreUsedList.clear();
+
+ kickerConf->reparseConfiguration();
+ kickerConf->setGroup("menus");
+ QStringList recentUsedList = QStringList::split(',',kickerConf->readEntry("RecentAppsStat"));
+
+ for (QStringList::ConstIterator it = recentUsedList.begin();
+ it != recentUsedList.end(); ++it )
+ {
+ QString item = (*it);
+
+ QString desktopPath = item.section(' ',2,2);
+ if(desktopPath.isEmpty() || !QFile::exists(desktopPath))
+ continue;
+
+ recentlyUsedMap[-item.section(' ',1,1).toULong()] = desktopPath;
+ moreUsedList.append(desktopPath);
+
+ }
+
+}
+
+void MenuHandler::setupDynList( MenuMode mode )
+{
+ /*( mode == RecentDocuments
+ || mode == MoreUsed
+ || mode == RecentlyUsed )*/
+ if( mode != Favourites )
+ menu->clearRecentButton->show();
+ else
+ menu->clearRecentButton->hide();
+
+ currentMenuMode = mode;
+ menu->dynamicList->setAcceptDrops( mode == Favourites );
+}
+
+void MenuHandler::fillRecentDocuments( )
+{
+ menu->dynamicList->clear();
+ setupDynList( RecentDocuments );
+
+ QStringList recentDocsList = KRecentDocument::recentDocuments();
+
+ TastyListViewItem *listItem = NULL;
+
+ if( recentDocsList.isEmpty() )
+ return;
+
+ for (QStringList::Iterator it = recentDocsList.begin();
+ it != recentDocsList.end(); ++it )
+ {
+ KDesktopFile *f= new KDesktopFile(*it, true /* read only */);
+
+ if( !f )
+ continue;
+
+ listItem = new TastyListViewItem( menu->dynamicList, listItem, f->readName() );
+ listItem->setMultiLinesEnabled(false);
+
+ listItem->setDeskopEntryPath(*it);
+ listItem->setType( TastyListViewItem::DesktopFile );
+
+ QPixmap iconPix = iconLoader->loadIcon(f->readIcon(), KIcon::Panel, _iconSize1);
+ if ( iconPix.height () > _iconSize1)
+ {
+ QImage img = iconPix.convertToImage();
+ if( !img.isNull() )
+ {
+ img = img.smoothScale ( _iconSize1, _iconSize1);
+ iconPix = QPixmap (img);
+ }
+ }
+ listItem->setPixmap(0, iconPix);
+
+ menu->dynamicList->insertItem( listItem );
+ }
+
+}
+
+
+void MenuHandler::fillMoreUsed( )
+{
+ menu->dynamicList->clear();
+ setupDynList( MoreUsed );
+
+ int iteration = 0;
+
+ TastyListViewItem *listItem = NULL;
+
+ for (QStringList::Iterator it = moreUsedList.begin();
+ it != moreUsedList.end(); ++it )
+ {
+ //FIXME: yeah, I know, this is U G L Y :-)
+ if( iteration++ >= _numRecentEntries )
+ break;
+
+ KService::Ptr s = KService::serviceByDesktopPath(*it);
+ if( !s )
+ continue;
+
+ listItem = new TastyListViewItem( menu->dynamicList, listItem, s->name());
+ listItem->setSubText(!(s->comment().isEmpty())?s->comment():s->genericName() );
+
+ listItem->setDeskopEntryPath( s->desktopEntryPath() );
+ listItem->setType( TastyListViewItem::Service );
+ listItem->setActionType( TastyListViewItem::AddBookMark );
+ listItem->setDisplaySubText(_displaySubText);
+
+
+ QPixmap iconPix = s->pixmap( KIcon::Toolbar, _iconSize1 );
+ if( !iconPix.isNull() )
+ {
+ if ( iconPix.height () != _iconSize1)
+ {
+ QImage img = iconPix.convertToImage();
+ if( !img.isNull() )
+ {
+ img = img.smoothScale ( _iconSize1, _iconSize1);
+ iconPix = QPixmap (img);
+ }
+ }
+ listItem->setPixmap(0, iconPix);
+ }
+
+ menu->dynamicList->insertItem( listItem );
+ }
+
+}
+
+//FIXME: avoid the ugly code duplication
+void MenuHandler::fillRecentlyUsed( )
+{
+ menu->dynamicList->clear();
+ setupDynList( RecentlyUsed );
+
+ int iteration = 0;
+ TastyListViewItem *listItem = NULL;
+
+ for (RecentlyUsedMap::Iterator it = recentlyUsedMap.begin();
+ it != recentlyUsedMap.end(); ++it )
+ {
+ //FIXME: yeah, I know, this is U G L Y :-)
+ if( iteration++ >= _numRecentEntries )
+ break;
+
+ KService::Ptr s = KService::serviceByDesktopPath(it.data());
+ if( !s )
+ continue;
+
+ listItem = new TastyListViewItem( menu->dynamicList, listItem, s->name());
+ listItem->setSubText(!(s->comment().isEmpty())?s->comment():s->genericName() );
+
+ listItem->setDeskopEntryPath( s->desktopEntryPath() );
+ listItem->setType( TastyListViewItem::Service );
+ listItem->setActionType( TastyListViewItem::AddBookMark );
+ listItem->setDisplaySubText(_displaySubText);
+
+
+ QPixmap iconPix = s->pixmap( KIcon::Toolbar, _iconSize1 );
+ if( !iconPix.isNull() )
+ {
+ if ( iconPix.height () != _iconSize1)
+ {
+ QImage img = iconPix.convertToImage();
+ if( !img.isNull() )
+ {
+ img = img.smoothScale ( _iconSize1, _iconSize1);
+ iconPix = QPixmap (img);
+ }
+ }
+ listItem->setPixmap(0, iconPix);
+ }
+
+ menu->dynamicList->insertItem( listItem );
+ }
+
+}
+
+
+//FIXME: avoid the ugly code duplication
+void MenuHandler::fillFavourites( )
+{
+ menu->dynamicList->clear();
+ setupDynList( Favourites );
+
+ TastyListViewItem *listItem = NULL;
+
+ for (QStringList::Iterator it = favouriteList.begin();
+ it != favouriteList.end(); ++it )
+ {
+
+ KService::Ptr s = KService::serviceByDesktopPath(*it);
+ if( !s )
+ continue;
+ listItem = new TastyListViewItem( menu->dynamicList, listItem, s->name());
+ listItem->setSubText(!(s->comment().isEmpty())?s->comment():s->genericName() );
+
+ listItem->setDeskopEntryPath( s->desktopEntryPath() );
+ listItem->setType( TastyListViewItem::Service );
+ listItem->setActionType( TastyListViewItem::RemoveBookMark );
+ listItem->setDisplaySubText(_displaySubText);
+
+
+ QPixmap iconPix = s->pixmap( KIcon::Toolbar, _iconSize1 );
+ if ( iconPix.height () > _iconSize1)
+ {
+ QImage img = iconPix.convertToImage();
+ if( !img.isNull() )
+ {
+ img = img.smoothScale ( _iconSize1, _iconSize1);
+ iconPix = QPixmap (img);
+ }
+ }
+ listItem->setPixmap(0, iconPix);
+
+ menu->dynamicList->insertItem( listItem );
+ }
+
+}
+
+
+
+void MenuHandler::slotModKickerConf()
+{
+ kickerConf->reparseConfiguration();
+ initializeRecentlyUsed( );
+ if( currentMenuMode == MoreUsed )
+ fillMoreUsed();
+ else if( currentMenuMode == RecentlyUsed )
+ fillRecentlyUsed();
+}
+
+
+void MenuHandler::slotApplicationsAdded(const KFileItemList & newItems)
+{
+
+ if( firstListing > 0 )
+ {
+ firstListing--;
+ return;
+ }
+
+ //avoiding to build a mammoth list...
+ if( newItems.count() > 15 )
+ return;
+
+ for(KFileItemListIterator it(newItems); it.current(); ++it)
+ {
+ KFileItem *item = (*it);
+ QString path(item->url().path());
+
+ kdDebug() << "new item: " << item->name() << endl;
+ //ignore items already here
+ if( oldInstalledList.findIndex(path) == -1 )
+ {
+ newInstalledList.append(path);
+ newInstalledTimeStamps.append( time(0) );
+ oldInstalledList.append(path);
+ }
+ }
+
+ prefSkel->setNewInstalledApps( newInstalledList );
+ prefSkel->setNewInstalledAppsTimeStamps( newInstalledTimeStamps );
+ prefSkel->setOldInstalledApps( oldInstalledList );
+
+ emit(newApplications(newInstalledList.count()));
+
+ //It's necessary to wait some seconds, otherwise apps won't be listed
+ //I do it two times for being sure, because I still haven't the clear idea
+ //where the right files to watch are...
+ QTimer::singleShot(15000, this, SLOT(slotUpdateApplications()));
+}
+
+
+void MenuHandler::slotApplicationRemoved()
+{
+ QTimer::singleShot(15000, this, SLOT(slotUpdateApplications()));
+ slotUpdateApplications();
+}
+
+void MenuHandler::slotUpdateApplications()
+{
+ KRun::runCommand ("kbuildsycoca");
+ prefSkel->writeConfig();
+ menu->rootList->clear();
+ KServiceGroup::Ptr service = KServiceGroup::root();
+
+ populateList( service, menu->rootList, NULL, false );
+}
+
+void MenuHandler::listClicked( TastyListViewItem * listItem, const QPoint & coord )
+{
+ if( !listItem )
+ return;
+
+ //exit if the user clicked on an empty area
+ if( coord.y() != 0 &&
+ (listItem->itemPos( )+ listItem->height()) < coord.y() )
+ return;
+
+ int x = coord.x();
+
+ QString servicePath = listItem->getDeskopEntryPath();
+
+ switch( listItem->getType() )
+ {
+ case TastyListViewItem::Service:
+ {
+ //These paranoid checks seems to be needed
+ if( !listItem->listView() )
+ return;
+ TastyListView *lv = dynamic_cast<TastyListView *>(listItem->listView());
+ if( !lv )
+ return;
+ if( x >= (lv->visibleWidth() - lv->getActionIconSpace()) )
+ {
+ switch( listItem->getActionType() )
+ {
+ case TastyListViewItem::AddBookMark:
+ favouriteList.remove(servicePath);
+ favouriteList.append(servicePath);
+ prefSkel->setFavouriteApps(favouriteList);
+ prefSkel->writeConfig();
+ if( menu->menuModes->currentItem() == 0 )
+ fillFavourites( );
+ return;
+
+ case TastyListViewItem::RemoveBookMark:
+ favouriteList.remove(servicePath);
+ prefSkel->setFavouriteApps(favouriteList);
+ prefSkel->writeConfig();
+ if( menu->menuModes->currentItem() == 0 )
+ fillFavourites( );
+ return;
+
+ default:
+ break;
+ }
+ }
+
+ //if the item was highlighted get it back to normal and remove it from recently installed
+ listItem->setHighLight(false);
+ int index=newInstalledList.findIndex(servicePath);
+ if( index != -1 )
+ {
+ newInstalledList.remove(newInstalledList.at(index));
+ newInstalledTimeStamps.remove(newInstalledTimeStamps.at(index));
+ prefSkel->setNewInstalledApps( newInstalledList );
+ prefSkel->setNewInstalledAppsTimeStamps( newInstalledTimeStamps );
+ emit(newApplications(newInstalledList.count()));
+ //remove the highlight from the rootList, at the moment very costly
+ slotUpdateApplications();
+ }
+
+ int started = KApplication::startServiceByDesktopPath( servicePath );
+ if( !started )
+ {
+ DCOPRef kickerKMenuIface ("kicker", "KMenu");
+
+ kickerKMenuIface.call("slotServiceStartedByStorageId(QString,QString)", "tastymenu", servicePath);
+ if( (currentMenuMode == MoreUsed
+ || currentMenuMode == RecentlyUsed)
+ && !searchMode)
+ slotModKickerConf();
+ if( !_isNormalWindow )
+ close();
+ }
+ break;
+ }
+
+ case TastyListViewItem::ServiceGroup:
+ {
+ //open, collapse or expand?
+ switch( listItem->getActionType() )
+ {
+ case TastyListViewItem::Expand:
+ //avoiding setOpen when the user clicks on the three handle
+ if( !listItem->xOnDecoration(x) )
+ listItem->setOpen(true);
+ if(listItem->isOpen())
+ listItem->setActionType( TastyListViewItem::Collapse );
+ break;
+ case TastyListViewItem::Collapse:
+ if( !listItem->xOnDecoration(x) )
+ listItem->setOpen(false);
+ if(!listItem->isOpen())
+ listItem->setActionType( TastyListViewItem::Expand );
+ break;
+ case TastyListViewItem::OpenGroup:
+ default:
+ {
+ KServiceGroup::Ptr serviceGroup = KServiceGroup::group( listItem->getPath() );
+ if( serviceGroup )
+ {
+ menu->childList->clear();
+ populateList( serviceGroup, menu->childList, NULL, true );
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case TastyListViewItem::DesktopFile:
+ {
+ KDEDesktopMimeType::run(servicePath, true);
+ if( !_isNormalWindow )
+ close();
+ break;
+ }
+
+ default:
+ return;
+ }
+
+}
+
+void MenuHandler::dynListClicked( QListViewItem * listItem, const QPoint & coord, int c )
+{
+ c=c;
+ if( !listItem )
+ return;
+
+ TastyListViewItem *tastyListItem = dynamic_cast<TastyListViewItem *>(listItem);
+ if( !tastyListItem )
+ return;
+
+ listClicked( static_cast<TastyListViewItem *>(listItem), coord );
+}
+
+void MenuHandler::childListClicked( QListViewItem * listItem, const QPoint & coord, int c )
+{
+ c=c;
+ if( !listItem )
+ return;
+
+ TastyListViewItem *tastyListItem = dynamic_cast<TastyListViewItem *>(listItem);
+ if( !tastyListItem )
+ return;
+
+ /*if( _showExpander && (tastyListItem->getType() == TastyListViewItem::ServiceGroup) )
+ {
+ //FIXME: get the REAL size of the expander
+ if( coord.x() > 16 )
+ listItem->setOpen( !listItem->isOpen() );
+ }
+ else*/
+ listClicked( static_cast<TastyListViewItem *>(listItem), coord );
+}
+
+void MenuHandler::rootListClicked( QListViewItem * listItem, const QPoint & coord, int c )
+{
+ c=c;
+ if( !listItem )
+ return;
+
+ TastyListViewItem *tastyListItem = dynamic_cast<TastyListViewItem *>(listItem);
+ if( !tastyListItem )
+ return;
+
+ //don't reload when the current category is clicked (except for the first run)
+ if( menu->childList->childCount() > 0 &&
+ prefSkel->currentCategory( ) == tastyListItem->text(0) )
+ return;
+
+ if( tastyListItem->getType() == TastyListViewItem::ServiceGroup )
+ {
+ prefSkel->setCurrentCategory( tastyListItem->text(0) );
+ prefSkel->writeConfig();
+ }
+
+ listClicked( tastyListItem, coord );
+ if( _alphabetical )
+ menu->childList->setSorting(0);
+}
+
+void MenuHandler::slotContextMenu(QListViewItem *listItem, const QPoint &coord, int c)
+{
+
+ if( !listItem )
+ return;
+ TastyListViewItem *tastyListItem = dynamic_cast<TastyListViewItem *>(listItem);
+ if( !tastyListItem )
+ return;
+
+ KPopupMenu menu(this);
+
+ menu.insertTitle(tastyListItem->text(c));
+ if( tastyListItem->getPath() != "" )
+ {
+ if( tastyListItem->getType() == TastyListViewItem::ServiceGroup )
+ menu.insertItem(SmallIcon("kmenuedit"), i18n("&Edit submenu..."), 1);
+ else if( tastyListItem->getType() == TastyListViewItem::Service )
+ {
+ menu.insertItem(SmallIcon("kmenuedit"), i18n("&Edit item..."), 1);
+ menu.insertItem(SmallIcon("desktop"), i18n("&Add to desktop"), 3);
+ }
+ }
+
+ if( tastyListItem->getActionType() == TastyListViewItem::AddBookMark )
+ menu.insertItem(SmallIcon("bookmark_add"), i18n("&Add to favourite applications"), 2);
+ else if( tastyListItem->getActionType() == TastyListViewItem::RemoveBookMark )
+ menu.insertItem(SmallIcon("remove"), i18n("&Remove from favourite applications"), 2);
+
+ int choice;
+ if( menu.count() > 1 )
+ choice = menu.exec(coord);
+ else
+ return;
+
+ switch( choice )
+ {
+ case 1:
+ KRun::runCommand ("kmenuedit /" +
+ tastyListItem->getPath() +
+ " " +
+ tastyListItem->getMenuId());
+ if( !_isNormalWindow )
+ close();
+ break;
+
+ case 2:
+ listClicked( tastyListItem, QPoint(tastyListItem->listView()->width(), 0) );
+ break;
+
+ case 3:
+ KRun::runCommand( "cp " + tastyListItem->getDeskopEntryPath() + " ~/Desktop" );
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+void MenuHandler::doLogout()
+{
+ close();
+ DCOPRef kdesktopKDesktopIface ("kdesktop", "KDesktopIface");
+ kdesktopKDesktopIface.call ("logout()");
+}
+
+void MenuHandler::doLock()
+{
+ hide();
+ DCOPRef kdesktopKScreensaverIface ("kdesktop", "KScreensaverIface");
+ kdesktopKScreensaverIface.call ("lock()");
+ close();
+}
+
+void MenuHandler::runDialog()
+{
+ close();
+ DCOPRef kdesktopKDesktopIface ("kdesktop", "KDesktopIface");
+ kdesktopKDesktopIface.call ("popupExecuteCommand()");
+}
+
+/*Following functions are from official KDE Kmenu, Copyright 1996-2006 the kicker authors*/
+
+void MenuHandler::slotPopulateSessions()
+{
+ int p = 0;
+ DM dm;
+
+ sessionsMenu->clear();
+
+ sessionsMenu->insertItem(SmallIconSet("personal"), i18n("Edit user profile..."), 100 );
+ sessionsMenu->insertSeparator();
+
+ //optional save/restore session entries
+ if(prefSkel->showSaveSession())
+ {
+ sessionsMenu->insertItem( i18n("Save current session"), 101 );
+ }
+
+ if (kapp->authorize("start_new_session") && (p = dm.numReserve()) >= 0)
+ {
+ if( kapp->authorize("lock_screen") )
+ sessionsMenu->insertItem( i18n("Lock session and start a new one"), 102 );
+ sessionsMenu->insertItem(SmallIconSet("fork"), i18n("Start New Session"), 103 );
+ if (!p) {
+ sessionsMenu->setItemEnabled( 101, false );
+ sessionsMenu->setItemEnabled( 102, false );
+ }
+ sessionsMenu->insertSeparator();
+ }
+
+ SessList sess;
+ if (dm.localSessions( sess ))
+ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
+ int id = sessionsMenu->insertItem( DM::sess2Str( *it ), (*it).vt );
+ if (!(*it).vt)
+ sessionsMenu->setItemEnabled( id, false );
+ if ((*it).self)
+ sessionsMenu->setItemChecked( id, true );
+ }
+}
+
+void MenuHandler::slotSessionActivated( int ent )
+{
+ close();
+
+ switch(ent)
+ {
+ case 100:
+ close();
+ KRun::runCommand ("kcmshell kcm_useraccount");
+ break;
+ case 101:
+ {
+ close();
+ DCOPRef ksmserverKsmserver ("ksmserver", "ksmserver");
+ ksmserverKsmserver.call ("saveCurrentSession()");
+ break;
+ }
+ case 102:
+ doNewSession( true );
+ break;
+ case 103:
+ doNewSession( false );
+ break;
+ }
+
+ //switch on an other session
+ if (!sessionsMenu->isItemChecked( ent ))
+ DM().lockSwitchVT( ent );
+}
+
+void MenuHandler::doNewSession( bool lock )
+{
+ int result = KMessageBox::warningContinueCancel(
+ kapp->desktop()->screen(kapp->desktop()->screenNumber(menu)),
+ i18n("<p>You have chosen to open another desktop session.<br>"
+ "The current session will be hidden "
+ "and a new login screen will be displayed.<br>"
+ "An F-key is assigned to each session; "
+ "F%1 is usually assigned to the first session, "
+ "F%2 to the second session and so on. "
+ "You can switch between sessions by pressing "
+ "Ctrl, Alt and the appropriate F-key at the same time. "
+ "Additionally, the KDE Panel and Desktop menus have "
+ "actions for switching between sessions.</p>")
+ .arg(7).arg(8),
+ i18n("Warning - New Session"),
+ KGuiItem(i18n("&Start New Session"), "fork"),
+ ":confirmNewSession",
+ KMessageBox::PlainCaption | KMessageBox::Notify);
+
+ if (result==KMessageBox::Cancel)
+ return;
+
+ if (lock)
+ doLock();
+
+ DM().startReserve();
+}
+
+
+void MenuHandler::initializeSearch( const QString & query )
+{
+ if( !searchMode && query.length() > 2 )
+ {
+ if( !menu->searchLine->listView() )
+ menu->searchLine->setListView((KListView *)(menu->dynamicList));
+ searchMode = true;
+ menu->menuModes->setEnabled(false);
+ KServiceGroup::Ptr service = KServiceGroup::root();
+ menu->dynamicList->clear();
+ setCursor(QCursor(Qt::BusyCursor));
+ populateList( service, menu->dynamicList, NULL, true, query );
+ setCursor(QCursor(Qt::ArrowCursor));
+ }
+ else if( query.length() < 3 )
+ {
+ if( menu->searchLine->listView() )
+ {
+ menu->searchLine->setListView(NULL);
+ menu->searchLine->setEnabled(true);
+ menu->searchLine->setFocus();
+ menu->searchLine->setContextMenuEnabled(false);
+ }
+ searchMode = false;
+ menu->menuModes->setEnabled(true);
+ menu->dynamicList->clear();
+ menuModeChanged(_menuMode);
+ }
+}
+
+void MenuHandler::kerrySearch( const QString & query )
+{
+ close();
+ DCOPRef kdesktopKScreensaverIface ("kerry", "search");
+ kdesktopKScreensaverIface.call ("search(QString)", query);
+}
+
+void MenuHandler::strigiSearch( const QString & query )
+{
+ close();
+ KRun::runCommand ("konqueror strigi:/?q="+query);
+}
+
+void MenuHandler::clearDynList( )
+{
+ menu->dynamicList->clear();
+ switch( currentMenuMode )
+ {
+ case MoreUsed:
+ case RecentlyUsed:
+ {
+ DCOPRef kickerKMenuIface ("kicker", "kicker");
+ kickerKMenuIface.call("clearQuickStartMenu()");
+ slotModKickerConf();
+ break;
+ }
+ case RecentDocuments:
+ KRecentDocument::clear();
+ break;
+ default:
+ break;
+ }
+}
+
+void MenuHandler::menuModeChanged( int index )
+{
+ _menuMode = index;
+ prefSkel->setMenuMode(_menuMode);
+
+ switch(index)
+ {
+ case Favourites:
+ fillFavourites();
+ break;
+
+ case MoreUsed:
+ fillMoreUsed();
+ break;
+
+ case RecentlyUsed:
+ fillRecentlyUsed();
+ break;
+
+ case RecentDocuments:
+ fillRecentDocuments();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void MenuHandler::switchWindowMode()
+{
+ if( !_isNormalWindow /*testWFlags(Qt::WType_Popup)*/ )
+ {
+ _isNormalWindow = true;
+ hide();
+ reparent(static_cast<QWidget *>(parent()),Qt::WType_Dialog, pos(), true);
+
+ menu->detachButton->setIconSet(QPixmap(uic_findImage("attach.png")));
+ prefSkel->setIsNormalWindow(true);
+ }
+ else
+ {
+ hide();
+ reparent(static_cast<QWidget *>(parent()),
+ Qt::WType_Popup|Qt::WNoAutoErase,
+ pos(), true);
+
+ menu->detachButton->setIconSet(QPixmap(uic_findImage("detach.png")));
+ prefSkel->setIsNormalWindow(false);
+ _isNormalWindow = false;
+ }
+
+ prefSkel->writeConfig();
+}
+
+//EOF