00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #define INCLUDE_MENUITEM_DEF
00034
00035 #include "startmenu.h"
00036
00037
00038 #include <opie2/oresource.h>
00039 using namespace Opie::Core;
00040 #include <qtopia/qpeapplication.h>
00041 #include <qtopia/config.h>
00042 #include <qtopia/mimetype.h>
00043 #include <qtopia/qlibrary.h>
00044
00045 #define APPLNK_ID_OFFSET 250
00046 #define NO_ID -1
00047
00048
00049 void StartPopupMenu::keyPressEvent( QKeyEvent *e )
00050 {
00051 if ( e->key() == Key_F33 || e->key() == Key_Space ) {
00052
00053 QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0);
00054 QPopupMenu::keyPressEvent( &ke );
00055 } else {
00056 QPopupMenu::keyPressEvent( e );
00057 }
00058 }
00059
00060
00061
00062 StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
00063 {
00064 startButtonPixmap = "go";
00065
00066 int sz = AppLnk::smallIconSize()+3;
00067 QPixmap pm;
00068 pm.convertFromImage(OResource::loadImage( startButtonPixmap, OResource::NoScale ).smoothScale( sz,sz) );
00069 setPixmap(pm);
00070 setFocusPolicy( NoFocus );
00071
00072 useWidePopupMenu = true;
00073 launchMenu = 0;
00074 currentItem = 0;
00075 refreshMenu();
00076 }
00077
00078
00079 void StartMenu::mousePressEvent( QMouseEvent * )
00080 {
00081 launch();
00082 }
00083
00084
00085 StartMenu::~StartMenu()
00086 {
00087 clearApplets();
00088 }
00089
00090 void StartMenu::createMenu()
00091 {
00092 clearApplets();
00093 delete launchMenu;
00094
00095 launchMenu = new StartPopupMenu( this );
00096 loadMenu( launchMenu );
00097 loadApplets();
00098
00099 bool result = currentItem || menuApplets.count();
00100 if ( result )
00101 connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
00102 }
00103
00104 void StartMenu::refreshMenu()
00105 {
00106 Config cfg( "StartMenu" );
00107 cfg.setGroup( "Menu" );
00108 bool ltabs = cfg.readBoolEntry( "LauncherTabs", TRUE );
00109 bool lot = cfg.readBoolEntry( "LauncherOther", TRUE );
00110 useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
00111
00112 if ( launchMenu && !(ltabs || lot) ) return;
00113
00114 createMenu();
00115 }
00116
00117 void StartMenu::itemSelected( int id )
00118 {
00119 if ( id == NO_ID ) return;
00120
00121 if ( id < 0 ) {
00122 MenuApplet *applet = menuApplets.find( id );
00123 if ( applet ) {
00124 applet->iface->activated();
00125 }
00126 } else if ( id >= APPLNK_ID_OFFSET ) {
00127 AppLnk * appLnk = appLnks.find( id );
00128 if ( appLnk ) {
00129 appLnk->execute();
00130 }
00131 } else {
00132 QString *tabName = tabNames.find( id );
00133 if ( tabName ) {
00134 emit tabSelected( *tabName );
00135 }
00136 }
00137 }
00138
00139 void StartMenu::createAppEntry( QPopupMenu *menu, QDir dir, QString file )
00140 {
00141 if ( file.right(8) == ".desktop" ) {
00142 AppLnk* applnk = new AppLnk( dir.path() + "/" + file );
00143 if ( !applnk->isValid() ) {
00144 delete applnk;
00145 return;
00146 }
00147
00148 if ( applnk->type() == "Separator" ) {
00149 menu->insertSeparator();
00150 delete applnk;
00151 } else {
00152 QPixmap pixmap = OResource::loadPixmap( applnk->icon(), OResource::SmallIcon );
00153
00154 int current, left = 0, right = currentItem;
00155 while( left != right ) {
00156 current = ( left + right ) / 2;
00157 if ( menu->text(menu->idAt( ( current ) ) ) < applnk->name() )
00158 left = ++current;
00159 else
00160 right = current;
00161 }
00162
00163 menu->insertItem( pixmap, applnk->name(),
00164 currentItem + APPLNK_ID_OFFSET, current );
00165 appLnks.insert( currentItem + APPLNK_ID_OFFSET, applnk );
00166 currentItem++;
00167 }
00168 }
00169
00170 }
00171
00172 void StartMenu::createDirEntry( QPopupMenu *menu, QDir dir, QString file, bool lot )
00173 {
00174
00175
00176 if ( file == "." || file == ".." ) return;
00177
00178 Config cfg( dir.path() + "/" + file + "/.directory", Config::File );
00179 if ( !cfg.isValid() ) return;
00180
00181 QString name = cfg.readEntry( "Name" );
00182 QString icon = cfg.readEntry( "Icon" );
00183 if ( !name || !icon ) return;
00184
00185 QDir subdir = QDir( dir );
00186 subdir.cd( file );
00187 subdir.setFilter( QDir::Files );
00188 subdir.setNameFilter( "*.desktop" );
00189
00190
00191 if ( subdir.entryList().isEmpty() ) return;
00192
00193
00194
00195 QPixmap pixmap = OResource::loadPixmap( icon, OResource::SmallIcon );
00196 if ( useWidePopupMenu ) {
00197
00198 QPopupMenu *submenu = new QPopupMenu( menu );
00199 connect( submenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
00200 menu->insertItem( pixmap, name, submenu, NO_ID );
00201
00202
00203 createMenuEntries( submenu, subdir, true, lot );
00204 } else {
00205
00206 menu->insertItem( pixmap, name, currentItem );
00207 tabNames.insert( currentItem, new QString( file ) );
00208 currentItem++;
00209 }
00210 }
00211
00212 void StartMenu::createMenuEntries( QPopupMenu *menu, QDir dir, bool ltabs, bool lot )
00213 {
00214 if ( lot ) {
00215 dir.setFilter( QDir::Files );
00216 dir.setNameFilter( "*.desktop" );
00217 QStringList files = dir.entryList();
00218 files.sort();
00219
00220 for ( QStringList::Iterator it = files.begin(); it != files.end(); it++ ) {
00221 createAppEntry( menu, dir, *it );
00222 }
00223 }
00224 if ( ltabs ) {
00225 dir.setNameFilter( "*" );
00226 dir.setFilter( QDir::Dirs );
00227 QStringList dirs = dir.entryList();
00228 dirs.sort();
00229
00230 for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); it++ ) {
00231 createDirEntry( menu, dir, *it, lot );
00232 }
00233 }
00234 }
00235
00236 bool StartMenu::loadMenu( QPopupMenu *menu )
00237 {
00238 Config cfg("StartMenu");
00239 cfg.setGroup("Menu");
00240
00241 bool ltabs = cfg.readBoolEntry("LauncherTabs", TRUE);
00242 bool lot = cfg.readBoolEntry("LauncherOther", TRUE);
00243 useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
00244 bool sepfirst = !ltabs && !lot;
00245
00246 currentItem = 0;
00247 launchMenu->clear();
00248
00249 appLnks.setAutoDelete( true );
00250 tabNames.setAutoDelete( true );
00251 appLnks.clear();
00252 tabNames.clear();
00253 appLnks.setAutoDelete( false );
00254 tabNames.setAutoDelete( false );
00255
00256 QDir dir( MimeType::appsFolderName(), QString::null, QDir::Name );
00257 createMenuEntries( menu, dir, ltabs, lot );
00258
00259 if ( !menu->count() ) sepfirst = TRUE;
00260
00261 launchMenu->setName( sepfirst ? "accessories" : "accessories_need_sep" );
00262
00263 return currentItem;
00264 }
00265
00266
00267 void StartMenu::launch()
00268 {
00269 int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
00270
00271 if ( launchMenu->isVisible() )
00272 launchMenu->hide();
00273 else
00274 launchMenu->popup( QPoint( 1, y ) );
00275 }
00276
00277
00278
00279
00280 static int compareAppletPositions(const void *b, const void *a)
00281 {
00282 const MenuApplet* aa = *(const MenuApplet**)a;
00283 const MenuApplet* ab = *(const MenuApplet**)b;
00284 int d = aa->iface->position() - ab->iface->position();
00285 if ( d ) return d;
00286 return QString::compare(aa->library->library(),ab->library->library());
00287 }
00288
00289 void StartMenu::clearApplets()
00290 {
00291 if ( launchMenu )
00292 launchMenu-> hide();
00293
00294 for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) {
00295 MenuApplet *applet = it.current();
00296 if ( launchMenu ) {
00297 launchMenu->removeItem( applet-> id );
00298 delete applet->popup;
00299 }
00300
00301 applet->iface->release();
00302 applet->library->unload();
00303 delete applet-> library;
00304 }
00305 menuApplets.clear();
00306 }
00307
00308
00309
00310
00311 void StartMenu::loadApplets()
00312 {
00313 Config cfg( "StartMenu" );
00314 cfg.setGroup( "Applets" );
00315
00316
00317
00318
00319
00320
00321 QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' );
00322
00323 QString lang = getenv( "LANG" );
00324 QString path = QPEApplication::qpeDir() + "plugins/applets";
00325 QDir dir( path, "lib*.so" );
00326 QStringList list = dir.entryList();
00327 QStringList::Iterator it;
00328 int napplets = 0;
00329 MenuApplet* *xapplets = new MenuApplet*[list.count()];
00330 for ( it = list.begin(); it != list.end(); ++it ) {
00331 if ( exclude.find( *it ) != exclude.end() )
00332 continue;
00333 MenuAppletInterface *iface = 0;
00334 QLibrary *lib = new QLibrary( path + "/" + *it );
00335 if (( lib->queryInterface( IID_MenuApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) {
00336 MenuApplet *applet = new MenuApplet;
00337 xapplets[napplets++] = applet;
00338 applet->library = lib;
00339 applet->iface = iface;
00340
00341 QTranslator *trans = new QTranslator(qApp);
00342 QString type = (*it).left( (*it).find(".") );
00343 QString tfn = QPEApplication::qpeDir()+"i18n/"+lang+"/"+type+".qm";
00344 if ( trans->load( tfn ))
00345 qApp->installTranslator( trans );
00346 else
00347 delete trans;
00348 } else {
00349 exclude += *it;
00350 delete lib;
00351 }
00352 }
00353 cfg.writeEntry( "ExcludeApplets", exclude, ',' );
00354 qsort(xapplets, napplets, sizeof(menuApplets[0]), compareAppletPositions);
00355
00356
00357 while ( napplets-- ) {
00358 MenuApplet *applet = xapplets[napplets];
00359 applet->popup = applet->iface->popup( this );
00360
00361
00362 menuApplets.insert( -( currentItem + 2 ), new MenuApplet( *applet ) );
00363 currentItem++;
00364 }
00365 delete [] xapplets;
00366
00367 addApplets( launchMenu );
00368 }
00369
00370
00371
00372
00373
00374 void StartMenu::addApplets(QPopupMenu* pop) {
00375 QIntDict<MenuApplet> dict;
00376 if( pop-> count ( ))
00377 pop-> insertSeparator ( );
00378
00379 for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) {
00380 MenuApplet *applet = it.current();
00381 if ( applet->popup )
00382 applet->id = pop->insertItem( applet->iface->icon(),
00383 applet->iface->text(), applet->popup );
00384 else
00385 applet->id = pop->insertItem( applet->iface->icon(),
00386 applet->iface->text() );
00387
00388
00389 dict.insert( applet->id, new MenuApplet( *applet ) );
00390 }
00391
00392 menuApplets.setAutoDelete( true );
00393 menuApplets.clear();
00394 menuApplets.setAutoDelete( false );
00395 menuApplets = dict;
00396 }