-rw-r--r-- | core/launcher/startmenu.cpp | 374 | ||||
-rw-r--r-- | core/launcher/startmenu.h | 46 |
2 files changed, 172 insertions, 248 deletions
diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp index d75e8be..014418d 100644 --- a/core/launcher/startmenu.cpp +++ b/core/launcher/startmenu.cpp @@ -1,401 +1,333 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #define INCLUDE_MENUITEM_DEF #include "startmenu.h" -#include "sidething.h" -//#include "mrulist.h" -#include "info.h" - -#include <qpe/qpeapplication.h> -#include <qpe/config.h> -#include <qpe/applnk.h> -#include <qpe/global.h> -#include <qpe/resource.h> -#include <qpe/qlibrary.h> - -#include <qintdict.h> + +#include <qtopia/qpeapplication.h> +#include <qtopia/config.h> +#include <qtopia/applnk.h> +#include <qtopia/global.h> +#include <qtopia/resource.h> +#include <qtopia/mimetype.h> +#include <qtopia/qlibrary.h> + +#include <qdict.h> #include <qdir.h> +#include <qpainter.h> #include <stdlib.h> -// #define USE_CONFIG_FILE +void StartPopupMenu::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_F33 || e->key() == Key_Space ) { + // "OK" button, little hacky + QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0); + QPopupMenu::keyPressEvent( &ke ); + } else { + QPopupMenu::keyPressEvent( e ); + } +} +//--------------------------------------------------------------------------- StartMenu::StartMenu(QWidget *parent) : QLabel( parent ) { - loadOptions(); - safety_tid = 1; // disable the timer... valgrind said it.. we don't use that option either -zecke + startButtonPixmap = "go"; // No tr int sz = AppLnk::smallIconSize()+3; QPixmap pm; pm.convertFromImage(Resource::loadImage(startButtonPixmap).smoothScale(sz,sz)); setPixmap(pm); setFocusPolicy( NoFocus ); - //setFlat( startButtonIsFlat ); - apps = 0; launchMenu = 0; - applets. setAutoDelete ( true ); - sepId = 0; - - reloadApps ( ); - reloadApplets ( ); + refreshMenu(); } void StartMenu::mousePressEvent( QMouseEvent * ) { launch(); - if (desktopInfo) - desktopInfo->menuClicked(); } StartMenu::~StartMenu() { - delete apps; -} - - -void StartMenu::loadOptions() -{ -#ifdef USE_CONFIG_FILE - // Read configuration file - Config config("StartMenu"); - config.setGroup( "StartMenu" ); - QString tmpBoolString1 = config.readEntry( "UseWidePopupMenu", "FALSE" ); - useWidePopupMenu = ( tmpBoolString1 == "TRUE" ) ? TRUE : FALSE; - QString tmpBoolString2 = config.readEntry( "StartButtonIsFlat", "TRUE" ); - startButtonIsFlat = ( tmpBoolString2 == "TRUE" ) ? TRUE : FALSE; - QString tmpBoolString3 = config.readEntry( "UseMRUList", "TRUE" ); - popupMenuSidePixmap = config.readEntry( "PopupMenuSidePixmap", "launcher/sidebar" ); - startButtonPixmap = config.readEntry( "StartButtonPixmap", "go" ); -#else - // Basically just #include the .qpe_menu.conf file settings - useWidePopupMenu = FALSE; - popupMenuSidePixmap = "launcher/sidebar"; - startButtonIsFlat = TRUE; - startButtonPixmap = "go"; // No tr -#endif + clearApplets(); } - void StartMenu::createMenu() { + clearApplets(); delete launchMenu; - if ( useWidePopupMenu ) - launchMenu = new PopupWithLaunchSideThing( this, &popupMenuSidePixmap ); - else - launchMenu = new StartPopupMenu( this ); - loadMenu ( apps, launchMenu ); - loadApplets ( ); + launchMenu = new StartPopupMenu( this ); + loadMenu( launchMenu ); + loadApplets(); + bool result = nother || ntabs || m_applets.count(); + if ( result ) connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); + } -void StartMenu::reloadApps() +void StartMenu::refreshMenu() { - Config cfg("StartMenu"); + Config cfg("Taskbar"); cfg.setGroup("Menu"); bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE); bool lot = cfg.readBoolEntry("LauncherOther",TRUE); bool lt = ltabs || lot; - if ( launchMenu && apps && !lt ) - return; // nothing to do + if ( launchMenu && !lt ) + return; // nothing to do - if ( lt ) { - delete apps; - apps = new AppLnkSet( QPEApplication::qpeDir() + "apps" ); - } if ( launchMenu ) { - launchMenu-> hide ( ); - - for ( QIntDictIterator<QPopupMenu> it ( tabdict ); it. current ( ); ++it ) { - launchMenu-> removeItem ( it. currentKey ( )); - delete it.current ( ); - } - tabdict. clear ( ); - loadMenu(apps,launchMenu); + int i; + /* find the first entry we want to remove */ + for (i=0; i<(int)launchMenu->count(); i++) { + QMenuItem* item = launchMenu->findItem(launchMenu->idAt(i)); + if ( item && item->id() >= 0 && item->id() < ntabs ) { + break; + } + if ( item && item->isSeparator() ) { + i++; + break; + } + } + /* remove them */ + while (i<(int)launchMenu->count()) + launchMenu->removeItemAt(i); + loadMenu(launchMenu); + addApplets(launchMenu); } else { - createMenu(); + createMenu(); } } -void StartMenu::reloadApplets() -{ - if ( launchMenu ) { - clearApplets ( ); - loadApplets ( ); - } - else - createMenu ( ); -} - void StartMenu::itemSelected( int id ) { - const AppLnk *app = apps->find( id ); - if ( app ) - app->execute(); - else { - MenuApplet *applet = applets. find ( id ); - - if ( applet ) - applet-> iface-> activated ( ); - } + if ( id >= 0 && id < ntabs ) { + emit tabSelected(tabs[id]); + } else if ( id >= 20 && id < 20+nother ) { + other.at(id-20)->execute(); + }else { + MenuApplet *applet = m_applets.find ( id ); + if ( applet ) { + qWarning("activated"); + applet-> iface-> activated(); + } + } } -bool StartMenu::loadMenu( AppLnkSet *folder, QPopupMenu *menu ) +bool StartMenu::loadMenu( QPopupMenu *menu ) { - bool result = FALSE; - - Config cfg("StartMenu"); + Config cfg("Taskbar"); cfg.setGroup("Menu"); bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE); bool lot = cfg.readBoolEntry("LauncherOther",TRUE); + bool sepfirst = !ltabs && !lot; - tabdict. clear ( ); - - if ( sepId ) - menu-> removeItem ( sepId ); - sepId = ( menu-> count ( )) ? menu-> insertSeparator ( 0 ) : 0; + tabs.clear(); + other.setAutoDelete(TRUE); + other.clear(); + ntabs = 0; + nother = 0; + bool f=TRUE; if ( ltabs || lot ) { - QDict<QPopupMenu> typpop; - QStringList typs = folder->types(); - for (QStringList::Iterator tit=typs.fromLast(); ; --tit) { - if ( !(*tit).isEmpty() ) { - QPopupMenu *new_menu; - if ( ltabs ) { - new_menu = new StartPopupMenu( menu ); - connect( new_menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); - int id = menu->insertItem( folder->typePixmap(*tit), folder->typeName(*tit), new_menu, -1, 0 ); - tabdict. insert ( id, new_menu ); - } else { - new_menu = (QPopupMenu*)1; - } - typpop.insert(*tit, new_menu); - } - if ( tit == typs. begin ( )) - break; - } - QListIterator<AppLnk> it( folder->children() ); - bool f=TRUE; - for ( ; it.current(); ++it ) { - AppLnk *app = it.current(); - if ( app->type() == "Separator" ) { // No tr - if ( lot ) { - menu->insertSeparator(); - } - } else { - f = FALSE; - QString t = app->type(); - QPopupMenu* pmenu = typpop.find(t); - if ( ltabs ) { - if ( !pmenu && lot ) - pmenu = menu; - } else { - if ( !pmenu ) - pmenu = menu; - else - pmenu = 0; - } - if ( pmenu ) { - QString t = app->name(); - t.replace(QRegExp("&"),"&&"); // escape shortcut character - - int index = -1; - - for ( index = 0; index < pmenu-> count ( ); index++ ) { - if ( pmenu-> text ( pmenu-> idAt ( index )). compare ( t ) > 0 ) - break; - } - - pmenu->insertItem( app->pixmap(), t, app->id(), index ); - } - result=TRUE; - } - } + QDir dir( MimeType::appsFolderName(), QString::null, QDir::Name ); + for (int i=0; i<(int)dir.count(); i++) { + QString d = dir[i]; + Config cfg(dir.path()+"/"+d+"/.directory",Config::File); + if ( cfg.isValid() ) { + QString nm = cfg.readEntry("Name"); + QString ic = cfg.readEntry("Icon"); + if ( !!nm && !!ic ) { + tabs.append(d); + menu->insertItem( Resource::loadIconSet(ic), nm, ntabs++ ); + } + } else if ( lot && d.right(8)==".desktop") { + AppLnk* applnk = new AppLnk(dir.path()+"/"+d); + if ( applnk->isValid() ) { + if ( applnk->type() == "Separator" ) { // No tr + if ( lot ) { + menu->insertSeparator(); + sepfirst = f && !ltabs; + } + delete applnk; + } else { + f = FALSE; + other.append(applnk); + menu->insertItem( Resource::loadIconSet(applnk->icon()), + applnk->name(), 20+nother++ ); + } + } else { + delete applnk; + } + } + } + + if ( !menu->count() ) + sepfirst = TRUE; } - if ( sepId && ( menu-> idAt ( 0 ) == sepId )) { // no tabs entries - menu-> removeItem ( sepId ); - sepId = 0; - } - if ( !menu-> count ( )) // if we don't do this QPopupMenu will insert a dummy Separator, which won't go away later - sepId = menu-> insertSeparator ( ); + launchMenu->setName(sepfirst ? "accessories" : "accessories_need_sep"); // No tr - return result; + return (nother || ntabs ); } -void StartMenu::launch ( ) +void StartMenu::launch() { - int y = mapToGlobal ( QPoint ( )). y ( ) - launchMenu-> sizeHint ( ). height ( ); + int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height(); - if ( launchMenu-> isVisible ( )) { - launchMenu-> hide ( ); - } - else { - QWidget *active = qApp-> activeWindow ( ); - if ( active && active-> isPopup ( )) - active-> close ( ); - - launchMenu-> popup ( QPoint ( 1, y )); - } + if ( launchMenu->isVisible() ) + launchMenu->hide(); + else + launchMenu->popup( QPoint( 1, y ) ); } -const AppLnk* StartMenu::execToLink(const QString& appname) -{ - const AppLnk* a = apps->findExec( appname ); - return a; -} -void StartPopupMenu::keyPressEvent( QKeyEvent *e ) -{ - if ( e->key() == Key_F33 || e->key() == Key_Space ) { - // "OK" button, little hacky - QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0); - QPopupMenu::keyPressEvent( &ke ); - } else { - QPopupMenu::keyPressEvent( e ); - } -} + static int compareAppletPositions(const void *a, const void *b) { const MenuApplet* aa = *(const MenuApplet**)a; const MenuApplet* ab = *(const MenuApplet**)b; int d = aa->iface->position() - ab->iface->position(); if ( d ) return d; return QString::compare(aa->library->library(),ab->library->library()); } void StartMenu::clearApplets() { - launchMenu-> hide(); + if (launchMenu ) + launchMenu-> hide(); - for ( QIntDictIterator<MenuApplet> it ( applets ); it. current ( ); ++it ) { + for ( QIntDictIterator<MenuApplet> it ( m_applets ); it. current ( ); ++it ) { MenuApplet *applet = it. current ( ); if ( launchMenu ) { launchMenu-> removeItem ( applet-> id ); delete applet-> popup; } applet-> iface-> release(); applet-> library-> unload(); delete applet-> library; } - applets.clear(); + m_applets.clear(); } + void StartMenu::loadApplets() { Config cfg( "StartMenu" ); cfg.setGroup( "Applets" ); // SafeMode causes too much problems, so we disable it for now -- // maybe we should reenable it for OPIE 1.0 - sandman 26.09.02 + // removed in the remerge PluginManager could handle it + // we don't currently use it -zecke - bool safe = false; //cfg.readBoolEntry("SafeMode",FALSE); - if ( safe && !safety_tid ) - return; - cfg.writeEntry("SafeMode",TRUE); - cfg.write(); QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' ); QString lang = getenv( "LANG" ); QString path = QPEApplication::qpeDir() + "/plugins/applets"; QDir dir( path, "lib*.so" ); QStringList list = dir.entryList(); QStringList::Iterator it; int napplets=0; MenuApplet* *xapplets = new MenuApplet*[list.count()]; for ( it = list.begin(); it != list.end(); ++it ) { if ( exclude.find( *it ) != exclude.end() ) continue; MenuAppletInterface *iface = 0; QLibrary *lib = new QLibrary( path + "/" + *it ); if (( lib->queryInterface( IID_MenuApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) { MenuApplet *applet = new MenuApplet; xapplets[napplets++] = applet; applet->library = lib; applet->iface = iface; QTranslator *trans = new QTranslator(qApp); QString type = (*it).left( (*it).find(".") ); QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm"; if ( trans->load( tfn )) qApp->installTranslator( trans ); else delete trans; } else { exclude += *it; delete lib; } } cfg.writeEntry( "ExcludeApplets", exclude, ',' ); - qsort(xapplets,napplets,sizeof(applets[0]),compareAppletPositions); + qsort(xapplets,napplets,sizeof(m_applets[0]),compareAppletPositions); + - if ( sepId ) - launchMenu-> removeItem ( sepId ); - sepId = ( launchMenu-> count ( )) ? launchMenu-> insertSeparator ( ) : 0; + int foo = ( launchMenu-> count ( )) ? launchMenu-> insertSeparator ( ) : 0; while (napplets--) { MenuApplet *applet = xapplets[napplets]; applet-> popup = applet-> iface-> popup ( this ); if ( applet-> popup ) applet-> id = launchMenu-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ), applet-> popup ); - else + else applet-> id = launchMenu-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ) ); - applets.insert ( applet-> id, new MenuApplet(*applet)); - } - delete [] xapplets; - if ( sepId && ( launchMenu-> idAt ( launchMenu-> count ( ) - 1 ) == sepId )) { // no applets - launchMenu-> removeItem ( sepId ); - sepId = 0; + + m_applets.insert ( applet-> id, new MenuApplet(*applet)); } - if ( !launchMenu-> count ( )) // if we don't do this QPopupMenu will insert a dummy Separator, which won't go away later - sepId = launchMenu-> insertSeparator ( ); + delete [] xapplets; - if ( !safety_tid ) - safety_tid = startTimer(2000); // TT has 5000, but this is a PITA for a developer ;) (sandman) } -void StartMenu::timerEvent(QTimerEvent* e) -{ - if ( e->timerId() == safety_tid ) { - Config cfg( "StartMenu" ); - cfg.setGroup( "Applets" ); - cfg.writeEntry( "SafeMode", FALSE ); - killTimer(safety_tid); - safety_tid = 0; + +/* + * Launcher calls loadMenu too often fix that + */ +void StartMenu::addApplets(QPopupMenu* pop) { + QIntDict<MenuApplet> dict; + if( pop-> count ( )) + pop-> insertSeparator ( ); + + for ( QIntDictIterator<MenuApplet> it ( m_applets ); it. current ( ); ++it ) { + MenuApplet *applet = it. current ( ); + if ( applet-> popup ) + applet-> id = pop-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ), applet-> popup ); + else + applet-> id = pop-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ) ); + + dict.insert( applet->id, new MenuApplet(*applet) ); } + /* need to update the key */ + m_applets.setAutoDelete( true ); + m_applets.clear(); + m_applets.setAutoDelete( false ); + m_applets = dict; } - diff --git a/core/launcher/startmenu.h b/core/launcher/startmenu.h index 0a91bb8..99df0f0 100644 --- a/core/launcher/startmenu.h +++ b/core/launcher/startmenu.h @@ -1,103 +1,95 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef __START_MENU_H__ #define __START_MENU_H__ +#include <qtopia/applnk.h> +#include <qintdict.h> #include <qstring.h> #include <qlist.h> -#include <qintdict.h> #include <qlabel.h> #include <qpopupmenu.h> -#include <qpe/menuappletinterface.h> - -class AppLnkSet; -class AppLnk; +#include <qtopia/menuappletinterface.h> class StartPopupMenu : public QPopupMenu { public: StartPopupMenu( QWidget *parent ) : QPopupMenu( parent ) {} protected: void keyPressEvent( QKeyEvent *e ); }; class QLibrary; -struct MenuApplet -{ -#ifndef QT_NO_COMPONENT + +struct MenuApplet { QLibrary *library; -#endif MenuAppletInterface *iface; int id; QPopupMenu *popup; }; - class StartMenu : public QLabel { Q_OBJECT public: StartMenu( QWidget * ); ~StartMenu(); - const AppLnk* execToLink(const QString& appname); + void refreshMenu(); public: StartPopupMenu *launchMenu; +signals: + void tabSelected(const QString&); + public slots: void launch( ); - void loadOptions( ); void createMenu( ); - void reloadApps( ); - void reloadApplets( ); protected slots: void itemSelected( int id ); protected: virtual void mousePressEvent( QMouseEvent * ); - virtual void timerEvent ( QTimerEvent * ); - + private: - bool loadMenu( AppLnkSet *folder, QPopupMenu *menu ); - void loadApplets( ); - void clearApplets( ); + void loadApplets(); + void clearApplets(); + void addApplets( QPopupMenu* menu ); + bool loadMenu( QPopupMenu *menu ); private: bool useWidePopupMenu; QString popupMenuSidePixmap; bool startButtonIsFlat; QString startButtonPixmap; - AppLnkSet *apps; - - QIntDict<MenuApplet> applets; - QIntDict<QPopupMenu> tabdict; - -// QValueList<MenuApplet> appletList; - int safety_tid; - int sepId; + QStringList tabs; + QList<AppLnk> other; + QIntDict<MenuApplet> m_applets; + int ntabs; + int nother; }; #endif // __START_MENU_H__ |