summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/launcher/startmenu.cpp253
-rw-r--r--core/launcher/startmenu.h21
2 files changed, 170 insertions, 104 deletions
diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp
index 08ae885..f17c7f8 100644
--- a/core/launcher/startmenu.cpp
+++ b/core/launcher/startmenu.cpp
@@ -9,41 +9,50 @@
** 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.
**
**********************************************************************/
+// TODO. During startup
+// Launcher::typeAdded
+// is called for each new tab and calls then each time the refresh of startmenu
+// suboptimal
+
#define INCLUDE_MENUITEM_DEF
#include "startmenu.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 <qpainter.h>
+
+//#include <stdlib.h>
+
-#include <stdlib.h>
+#define APPLNK_ID_OFFSET 250
+#define NO_ID -1
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 );
}
}
@@ -51,24 +60,25 @@ void StartPopupMenu::keyPressEvent( QKeyEvent *e )
//---------------------------------------------------------------------------
StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
{
startButtonPixmap = "go"; // No tr
int sz = AppLnk::smallIconSize()+3;
QPixmap pm;
pm.convertFromImage(Resource::loadImage(startButtonPixmap).smoothScale(sz,sz));
setPixmap(pm);
setFocusPolicy( NoFocus );
+ useWidePopupMenu = true;
launchMenu = 0;
refreshMenu();
}
void StartMenu::mousePressEvent( QMouseEvent * )
{
launch();
}
StartMenu::~StartMenu()
@@ -76,200 +86,248 @@ StartMenu::~StartMenu()
clearApplets();
}
void StartMenu::createMenu()
{
clearApplets();
delete launchMenu;
launchMenu = new StartPopupMenu( this );
loadMenu( launchMenu );
loadApplets();
- bool result = nother || ntabs || m_applets.count();
+ bool result = currentItem || menuApplets.count();
if ( result )
connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
-
}
void StartMenu::refreshMenu()
{
- Config cfg("Taskbar");
+ Config cfg( "StartMenu" );
cfg.setGroup("Menu");
bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE);
bool lot = cfg.readBoolEntry("LauncherOther",TRUE);
- bool lt = ltabs || lot;
- if ( launchMenu && !lt )
- return; // nothing to do
+ useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
+
+ if ( launchMenu && !(ltabs || lot) ) return; // nothing to do
- if ( 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();
}
-}
void StartMenu::itemSelected( int id )
{
- 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 ( id == NO_ID ) return;
+
+ if ( id < 0 ) {
+ MenuApplet *applet = menuApplets.find( id );
if ( applet ) {
- qWarning("activated");
applet-> iface-> activated();
}
+ } else if ( id >= APPLNK_ID_OFFSET ) {
+ AppLnk * appLnk = appLnks.find( id );
+ if ( appLnk ) {
+ appLnk->execute();
+ }
+ } else {
+ QString *tabName = tabNames.find( id );
+ if ( tabName ) {
+ emit tabSelected( *tabName );
+ }
}
}
-bool StartMenu::loadMenu( QPopupMenu *menu )
+void StartMenu::createAppEntry( QPopupMenu *menu, QDir dir, QString file )
{
- Config cfg("Taskbar");
- cfg.setGroup("Menu");
-
- bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE);
- bool lot = cfg.readBoolEntry("LauncherOther",TRUE);
- bool sepfirst = !ltabs && !lot;
-
- tabs.clear();
- other.setAutoDelete(TRUE);
- other.clear();
- ntabs = 0;
- nother = 0;
+ if ( file.right(8) == ".desktop" ) {
+ AppLnk* applnk = new AppLnk( dir.path() + "/" + file );
+ if ( !applnk->isValid() ) {
+ delete applnk;
+ return;
+ }
- bool f=TRUE;
- if ( ltabs || lot ) {
- 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++ );
+ QPixmap test;
+ test.convertFromImage(
+ Resource::loadImage( applnk->icon() ).smoothScale(
+ AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 );
+
+ menu->insertItem( test, applnk->name(),
+ currentItem + APPLNK_ID_OFFSET );
+ appLnks.insert( currentItem + APPLNK_ID_OFFSET, applnk );
+ currentItem++;
+ }
}
+
+}
+
+void StartMenu::createDirEntry( QPopupMenu *menu, QDir dir, QString file, bool lot )
+{
+ // do some sanity checks and collect information
+
+ if ( file == "." || file == ".." ) return;
+
+ Config cfg( dir.path() + "/" + file + "/.directory", Config::File );
+ if ( !cfg.isValid() ) return;
+
+ QString name = cfg.readEntry( "Name" );
+ QString icon = cfg.readEntry( "Icon" );
+ if ( !name || !icon ) return;
+
+ QDir subdir = QDir( dir );
+ subdir.cd( file );
+ subdir.setFilter( QDir::Files );
+ subdir.setNameFilter( "*.desktop" );
+ // we don' t show the menu if there are no entries
+ // perhaps one should check if there exist subsubdirs with entries...
+ if ( subdir.entryList().isEmpty() ) return;
+
+ // checks were ok
+
+ QPixmap test;
+ test.convertFromImage( Resource::loadImage( icon ).smoothScale(
+ AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 );
+
+ if ( useWidePopupMenu ) {
+ // generate submenu
+ QPopupMenu *submenu = new QPopupMenu( menu );
+ connect( submenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
+ menu->insertItem( test, name, submenu, NO_ID );
+
+ // ltabs is true cause else we wouldn't stuck around..
+ createMenuEntries( submenu, subdir, true, lot );
} else {
- delete applnk;
+ // no submenus - just bring corresponding tab to front
+ menu->insertItem( test, name, currentItem );
+ tabNames.insert( currentItem, new QString( file ) );
+ currentItem++;
}
}
+
+void StartMenu::createMenuEntries( QPopupMenu *menu, QDir dir, bool ltabs, bool lot )
+{
+ if ( lot ) {
+ dir.setFilter( QDir::Files );
+ dir.setNameFilter( "*.desktop" );
+ QStringList files = dir.entryList();
+ files.sort();
+
+ for ( QStringList::Iterator it = files.begin(); it != files.end(); it++ ) {
+ createAppEntry( menu, dir, *it );
+ }
}
+ if ( ltabs ) {
+ dir.setNameFilter( "*" );
+ dir.setFilter( QDir::Dirs );
+ QStringList dirs = dir.entryList();
+ dirs.sort();
- if ( !menu->count() )
- sepfirst = TRUE;
+ for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); it++ ) {
+ createDirEntry( menu, dir, *it, lot );
}
+ }
+}
+
+bool StartMenu::loadMenu( QPopupMenu *menu )
+{
+ Config cfg("StartMenu");
+ cfg.setGroup("Menu");
+
+ bool ltabs = cfg.readBoolEntry("LauncherTabs", TRUE);
+ bool lot = cfg.readBoolEntry("LauncherOther", TRUE);
+ useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
+ bool sepfirst = !ltabs && !lot;
+
+ currentItem = 0;
+ launchMenu->clear();
+
+ appLnks.setAutoDelete( true );
+ tabNames.setAutoDelete( true );
+ appLnks.clear();
+ tabNames.clear();
+ appLnks.setAutoDelete( false );
+ tabNames.setAutoDelete( false );
+
+ QDir dir( MimeType::appsFolderName(), QString::null, QDir::Name );
+ createMenuEntries( menu, dir, ltabs, lot );
+
+ if ( !menu->count() ) sepfirst = TRUE;
launchMenu->setName(sepfirst ? "accessories" : "accessories_need_sep"); // No tr
- return (nother || ntabs );
+ return currentItem;
}
void StartMenu::launch()
{
int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
if ( launchMenu->isVisible() )
launchMenu->hide();
else
launchMenu->popup( QPoint( 1, y ) );
}
-static int compareAppletPositions(const void *a, const void *b)
+static int compareAppletPositions(const void *b, const void *a)
{
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()
{
if (launchMenu )
launchMenu-> hide();
- for ( QIntDictIterator<MenuApplet> it ( m_applets ); it. current ( ); ++it ) {
+ for ( QIntDictIterator<MenuApplet> it( menuApplets ); 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;
}
- m_applets.clear();
+ menuApplets.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
QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' );
QString lang = getenv( "LANG" );
QString path = QPEApplication::qpeDir() + "/plugins/applets";
-#ifdef Q_OS_MACX
- QDir dir( path, "lib*.dylib" );
-#else
QDir dir( path, "lib*.so" );
-#endif /* Q_OS_MACX */
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;
@@ -280,58 +338,55 @@ void StartMenu::loadApplets()
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(m_applets[0]),compareAppletPositions);
+ qsort(xapplets, napplets, sizeof(menuApplets[0]), compareAppletPositions);
- 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
- applet-> id = launchMenu-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ) );
-
-
- m_applets.insert ( applet-> id, new MenuApplet(*applet));
+ // menuApplets got an id < -1
+ menuApplets.insert( -( currentItem + 2 ), new MenuApplet( *applet ) );
+ currentItem++;
}
delete [] xapplets;
+ addApplets( launchMenu );
}
/*
* 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 ) {
+ for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) {
MenuApplet *applet = it. current ( );
if ( applet-> popup )
- applet-> id = pop-> insertItem ( applet-> iface-> icon ( ), applet-> iface-> text ( ), 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 ( ) );
+ 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;
+ menuApplets.setAutoDelete( true );
+ menuApplets.clear();
+ menuApplets.setAutoDelete( false );
+ menuApplets = dict;
}
diff --git a/core/launcher/startmenu.h b/core/launcher/startmenu.h
index 99df0f0..7218035 100644
--- a/core/launcher/startmenu.h
+++ b/core/launcher/startmenu.h
@@ -16,49 +16,56 @@
** 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 <qmap.h>
+#include <qdir.h>
#include <qlabel.h>
#include <qpopupmenu.h>
#include <qtopia/menuappletinterface.h>
class StartPopupMenu : public QPopupMenu
{
+
public:
StartPopupMenu( QWidget *parent ) : QPopupMenu( parent ) {}
+
protected:
void keyPressEvent( QKeyEvent *e );
+
};
class QLibrary;
struct MenuApplet {
QLibrary *library;
MenuAppletInterface *iface;
int id;
QPopupMenu *popup;
};
class StartMenu : public QLabel {
+
Q_OBJECT
+
public:
StartMenu( QWidget * );
~StartMenu();
void refreshMenu();
public:
StartPopupMenu *launchMenu;
signals:
void tabSelected(const QString&);
@@ -68,28 +75,32 @@ public slots:
protected slots:
void itemSelected( int id );
protected:
virtual void mousePressEvent( QMouseEvent * );
private:
void loadApplets();
void clearApplets();
void addApplets( QPopupMenu* menu );
bool loadMenu( QPopupMenu *menu );
+ void createMenuEntries( QPopupMenu *menu, QDir dir, bool ltabs, bool lot );
+ void createDirEntry( QPopupMenu *menu, QDir dir, QString file, bool lot );
+ void createAppEntry( QPopupMenu *menu, QDir dir, QString file );
private:
bool useWidePopupMenu;
QString popupMenuSidePixmap;
bool startButtonIsFlat;
QString startButtonPixmap;
- QStringList tabs;
- QList<AppLnk> other;
- QIntDict<MenuApplet> m_applets;
- int ntabs;
- int nother;
+ int currentItem;
+
+ QIntDict<AppLnk> appLnks;
+ QIntDict<QString> tabNames;
+ QIntDict<MenuApplet> menuApplets;
+
};
#endif // __START_MENU_H__