summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/startmenu.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp
index 66f665f..ce7840e 100644
--- a/core/launcher/startmenu.cpp
+++ b/core/launcher/startmenu.cpp
@@ -1,349 +1,360 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21// TODO. During startup 21// TODO. During startup
22// Launcher::typeAdded 22// Launcher::typeAdded
23// is called for each new tab and calls then each time the refresh of startmenu 23// is called for each new tab and calls then each time the refresh of startmenu
24// suboptimal 24// suboptimal
25 25
26#define INCLUDE_MENUITEM_DEF 26#define INCLUDE_MENUITEM_DEF
27 27
28#include "startmenu.h" 28#include "startmenu.h"
29 29
30#include <qtopia/qpeapplication.h> 30#include <qtopia/qpeapplication.h>
31#include <qtopia/config.h> 31#include <qtopia/config.h>
32#include <qtopia/resource.h> 32#include <qtopia/resource.h>
33#include <qtopia/mimetype.h> 33#include <qtopia/mimetype.h>
34#include <qtopia/qlibrary.h> 34#include <qtopia/qlibrary.h>
35 35
36//#include <qpainter.h> 36//#include <qpainter.h>
37 37
38//#include <stdlib.h> 38//#include <stdlib.h>
39 39
40 40
41#define APPLNK_ID_OFFSET 250 41#define APPLNK_ID_OFFSET 250
42#define NO_ID -1 42#define NO_ID -1
43 43
44 44
45void StartPopupMenu::keyPressEvent( QKeyEvent *e ) 45void StartPopupMenu::keyPressEvent( QKeyEvent *e )
46{ 46{
47 if ( e->key() == Key_F33 || e->key() == Key_Space ) { 47 if ( e->key() == Key_F33 || e->key() == Key_Space ) {
48 // "OK" button, little hacky 48 // "OK" button, little hacky
49 QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0); 49 QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0);
50 QPopupMenu::keyPressEvent( &ke ); 50 QPopupMenu::keyPressEvent( &ke );
51 } else { 51 } else {
52 QPopupMenu::keyPressEvent( e ); 52 QPopupMenu::keyPressEvent( e );
53 } 53 }
54} 54}
55 55
56//--------------------------------------------------------------------------- 56//---------------------------------------------------------------------------
57 57
58StartMenu::StartMenu(QWidget *parent) : QLabel( parent ) 58StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
59{ 59{
60 startButtonPixmap = "go"; // No tr 60 startButtonPixmap = "go"; // No tr
61 61
62 int sz = AppLnk::smallIconSize()+3; 62 int sz = AppLnk::smallIconSize()+3;
63 QPixmap pm; 63 QPixmap pm;
64 pm.convertFromImage(Resource::loadImage( startButtonPixmap).smoothScale( sz,sz) ); 64 pm.convertFromImage(Resource::loadImage( startButtonPixmap).smoothScale( sz,sz) );
65 setPixmap(pm); 65 setPixmap(pm);
66 setFocusPolicy( NoFocus ); 66 setFocusPolicy( NoFocus );
67 67
68 useWidePopupMenu = true; 68 useWidePopupMenu = true;
69 launchMenu = 0; 69 launchMenu = 0;
70 currentItem = 0;
70 refreshMenu(); 71 refreshMenu();
71} 72}
72 73
73 74
74void StartMenu::mousePressEvent( QMouseEvent * ) 75void StartMenu::mousePressEvent( QMouseEvent * )
75{ 76{
76 launch(); 77 launch();
77} 78}
78 79
79 80
80StartMenu::~StartMenu() 81StartMenu::~StartMenu()
81{ 82{
82 clearApplets(); 83 clearApplets();
83} 84}
84 85
85void StartMenu::createMenu() 86void StartMenu::createMenu()
86{ 87{
87 clearApplets(); 88 clearApplets();
88 delete launchMenu; 89 delete launchMenu;
89 90
90 launchMenu = new StartPopupMenu( this ); 91 launchMenu = new StartPopupMenu( this );
91 loadMenu( launchMenu ); 92 loadMenu( launchMenu );
92 loadApplets(); 93 loadApplets();
93 94
94 bool result = currentItem || menuApplets.count(); 95 bool result = currentItem || menuApplets.count();
95 if ( result ) 96 if ( result )
96 connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); 97 connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
97} 98}
98 99
99void StartMenu::refreshMenu() 100void StartMenu::refreshMenu()
100{ 101{
101 Config cfg( "StartMenu" ); 102 Config cfg( "StartMenu" );
102 cfg.setGroup( "Menu" ); 103 cfg.setGroup( "Menu" );
103 bool ltabs = cfg.readBoolEntry( "LauncherTabs", TRUE ); 104 bool ltabs = cfg.readBoolEntry( "LauncherTabs", TRUE );
104 bool lot = cfg.readBoolEntry( "LauncherOther", TRUE ); 105 bool lot = cfg.readBoolEntry( "LauncherOther", TRUE );
105 useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE ); 106 useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
106 107
107 if ( launchMenu && !(ltabs || lot) ) return; // nothing to do 108 if ( launchMenu && !(ltabs || lot) ) return; // nothing to do
108 109
109 createMenu(); 110 createMenu();
110} 111}
111 112
112void StartMenu::itemSelected( int id ) 113void StartMenu::itemSelected( int id )
113{ 114{
114 if ( id == NO_ID ) return; 115 if ( id == NO_ID ) return;
115 116
116 if ( id < 0 ) { 117 if ( id < 0 ) {
117 MenuApplet *applet = menuApplets.find( id ); 118 MenuApplet *applet = menuApplets.find( id );
118 if ( applet ) { 119 if ( applet ) {
119 applet->iface->activated(); 120 applet->iface->activated();
120 } 121 }
121 } else if ( id >= APPLNK_ID_OFFSET ) { 122 } else if ( id >= APPLNK_ID_OFFSET ) {
122 AppLnk * appLnk = appLnks.find( id ); 123 AppLnk * appLnk = appLnks.find( id );
123 if ( appLnk ) { 124 if ( appLnk ) {
124 appLnk->execute(); 125 appLnk->execute();
125 } 126 }
126 } else { 127 } else {
127 QString *tabName = tabNames.find( id ); 128 QString *tabName = tabNames.find( id );
128 if ( tabName ) { 129 if ( tabName ) {
129 emit tabSelected( *tabName ); 130 emit tabSelected( *tabName );
130 } 131 }
131 } 132 }
132} 133}
133 134
134void StartMenu::createAppEntry( QPopupMenu *menu, QDir dir, QString file ) 135void StartMenu::createAppEntry( QPopupMenu *menu, QDir dir, QString file )
135{ 136{
136 if ( file.right(8) == ".desktop" ) { 137 if ( file.right(8) == ".desktop" ) {
137 AppLnk* applnk = new AppLnk( dir.path() + "/" + file ); 138 AppLnk* applnk = new AppLnk( dir.path() + "/" + file );
138 if ( !applnk->isValid() ) { 139 if ( !applnk->isValid() ) {
139 delete applnk; 140 delete applnk;
140 return; 141 return;
141 } 142 }
142 143
143 if ( applnk->type() == "Separator" ) { // No tr 144 if ( applnk->type() == "Separator" ) { // No tr
144 menu->insertSeparator(); 145 menu->insertSeparator();
145 delete applnk; 146 delete applnk;
146 } else { 147 } else {
147 QPixmap test; 148 QPixmap test;
148 QImage img = Resource::loadImage( applnk->icon() ); 149 QImage img = Resource::loadImage( applnk->icon() );
149 if(!img.isNull() ) 150 if(!img.isNull() )
150 test.convertFromImage( 151 test.convertFromImage(
151 img.smoothScale( 152 img.smoothScale(
152 AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 ); 153 AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 );
153 154
155 // Insert items ordered lexically
156 int current, left = 0, right = currentItem;
157 while( left != right ) {
158 current = ( left + right ) / 2;
159 if ( menu->text(menu->idAt( ( current ) ) ) < applnk->name() )
160 left = ++current;
161 else
162 right = current;
163 }
164
154 menu->insertItem( test, applnk->name(), 165 menu->insertItem( test, applnk->name(),
155 currentItem + APPLNK_ID_OFFSET ); 166 currentItem + APPLNK_ID_OFFSET, current );
156 appLnks.insert( currentItem + APPLNK_ID_OFFSET, applnk ); 167 appLnks.insert( currentItem + APPLNK_ID_OFFSET, applnk );
157 currentItem++; 168 currentItem++;
158 } 169 }
159 } 170 }
160 171
161} 172}
162 173
163void StartMenu::createDirEntry( QPopupMenu *menu, QDir dir, QString file, bool lot ) 174void StartMenu::createDirEntry( QPopupMenu *menu, QDir dir, QString file, bool lot )
164{ 175{
165 // do some sanity checks and collect information 176 // do some sanity checks and collect information
166 177
167 if ( file == "." || file == ".." ) return; 178 if ( file == "." || file == ".." ) return;
168 179
169 Config cfg( dir.path() + "/" + file + "/.directory", Config::File ); 180 Config cfg( dir.path() + "/" + file + "/.directory", Config::File );
170 if ( !cfg.isValid() ) return; 181 if ( !cfg.isValid() ) return;
171 182
172 QString name = cfg.readEntry( "Name" ); 183 QString name = cfg.readEntry( "Name" );
173 QString icon = cfg.readEntry( "Icon" ); 184 QString icon = cfg.readEntry( "Icon" );
174 if ( !name || !icon ) return; 185 if ( !name || !icon ) return;
175 186
176 QDir subdir = QDir( dir ); 187 QDir subdir = QDir( dir );
177 subdir.cd( file ); 188 subdir.cd( file );
178 subdir.setFilter( QDir::Files ); 189 subdir.setFilter( QDir::Files );
179 subdir.setNameFilter( "*.desktop" ); 190 subdir.setNameFilter( "*.desktop" );
180 // we don' t show the menu if there are no entries 191 // we don' t show the menu if there are no entries
181 // perhaps one should check if there exist subsubdirs with entries... 192 // perhaps one should check if there exist subsubdirs with entries...
182 if ( subdir.entryList().isEmpty() ) return; 193 if ( subdir.entryList().isEmpty() ) return;
183 194
184 // checks were ok 195 // checks were ok
185 196
186 QPixmap test; 197 QPixmap test;
187 test.convertFromImage( Resource::loadImage( icon ).smoothScale( 198 test.convertFromImage( Resource::loadImage( icon ).smoothScale(
188 AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 ); 199 AppLnk::smallIconSize(), AppLnk::smallIconSize() ), 0 );
189 200
190 if ( useWidePopupMenu ) { 201 if ( useWidePopupMenu ) {
191 // generate submenu 202 // generate submenu
192 QPopupMenu *submenu = new QPopupMenu( menu ); 203 QPopupMenu *submenu = new QPopupMenu( menu );
193 connect( submenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); 204 connect( submenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
194 menu->insertItem( test, name, submenu, NO_ID ); 205 menu->insertItem( test, name, submenu, NO_ID );
195 206
196 // ltabs is true cause else we wouldn't stuck around.. 207 // ltabs is true cause else we wouldn't stuck around..
197 createMenuEntries( submenu, subdir, true, lot ); 208 createMenuEntries( submenu, subdir, true, lot );
198 } else { 209 } else {
199 // no submenus - just bring corresponding tab to front 210 // no submenus - just bring corresponding tab to front
200 menu->insertItem( test, name, currentItem ); 211 menu->insertItem( test, name, currentItem );
201 tabNames.insert( currentItem, new QString( file ) ); 212 tabNames.insert( currentItem, new QString( file ) );
202 currentItem++; 213 currentItem++;
203 } 214 }
204} 215}
205 216
206void StartMenu::createMenuEntries( QPopupMenu *menu, QDir dir, bool ltabs, bool lot ) 217void StartMenu::createMenuEntries( QPopupMenu *menu, QDir dir, bool ltabs, bool lot )
207{ 218{
208 if ( lot ) { 219 if ( lot ) {
209 dir.setFilter( QDir::Files ); 220 dir.setFilter( QDir::Files );
210 dir.setNameFilter( "*.desktop" ); 221 dir.setNameFilter( "*.desktop" );
211 QStringList files = dir.entryList(); 222 QStringList files = dir.entryList();
212 files.sort(); 223 files.sort();
213 224
214 for ( QStringList::Iterator it = files.begin(); it != files.end(); it++ ) { 225 for ( QStringList::Iterator it = files.begin(); it != files.end(); it++ ) {
215 createAppEntry( menu, dir, *it ); 226 createAppEntry( menu, dir, *it );
216 } 227 }
217 } 228 }
218 if ( ltabs ) { 229 if ( ltabs ) {
219 dir.setNameFilter( "*" ); 230 dir.setNameFilter( "*" );
220 dir.setFilter( QDir::Dirs ); 231 dir.setFilter( QDir::Dirs );
221 QStringList dirs = dir.entryList(); 232 QStringList dirs = dir.entryList();
222 dirs.sort(); 233 dirs.sort();
223 234
224 for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); it++ ) { 235 for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); it++ ) {
225 createDirEntry( menu, dir, *it, lot ); 236 createDirEntry( menu, dir, *it, lot );
226 } 237 }
227 } 238 }
228} 239}
229 240
230bool StartMenu::loadMenu( QPopupMenu *menu ) 241bool StartMenu::loadMenu( QPopupMenu *menu )
231{ 242{
232 Config cfg("StartMenu"); 243 Config cfg("StartMenu");
233 cfg.setGroup("Menu"); 244 cfg.setGroup("Menu");
234 245
235 bool ltabs = cfg.readBoolEntry("LauncherTabs", TRUE); 246 bool ltabs = cfg.readBoolEntry("LauncherTabs", TRUE);
236 bool lot = cfg.readBoolEntry("LauncherOther", TRUE); 247 bool lot = cfg.readBoolEntry("LauncherOther", TRUE);
237 useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE ); 248 useWidePopupMenu = cfg.readBoolEntry( "LauncherSubPopup", TRUE );
238 bool sepfirst = !ltabs && !lot; 249 bool sepfirst = !ltabs && !lot;
239 250
240 currentItem = 0; 251 currentItem = 0;
241 launchMenu->clear(); 252 launchMenu->clear();
242 253
243 appLnks.setAutoDelete( true ); 254 appLnks.setAutoDelete( true );
244 tabNames.setAutoDelete( true ); 255 tabNames.setAutoDelete( true );
245 appLnks.clear(); 256 appLnks.clear();
246 tabNames.clear(); 257 tabNames.clear();
247 appLnks.setAutoDelete( false ); 258 appLnks.setAutoDelete( false );
248 tabNames.setAutoDelete( false ); 259 tabNames.setAutoDelete( false );
249 260
250 QDir dir( MimeType::appsFolderName(), QString::null, QDir::Name ); 261 QDir dir( MimeType::appsFolderName(), QString::null, QDir::Name );
251 createMenuEntries( menu, dir, ltabs, lot ); 262 createMenuEntries( menu, dir, ltabs, lot );
252 263
253 if ( !menu->count() ) sepfirst = TRUE; 264 if ( !menu->count() ) sepfirst = TRUE;
254 265
255 launchMenu->setName( sepfirst ? "accessories" : "accessories_need_sep" ); // No tr 266 launchMenu->setName( sepfirst ? "accessories" : "accessories_need_sep" ); // No tr
256 267
257 return currentItem; 268 return currentItem;
258} 269}
259 270
260 271
261void StartMenu::launch() 272void StartMenu::launch()
262{ 273{
263 int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height(); 274 int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
264 275
265 if ( launchMenu->isVisible() ) 276 if ( launchMenu->isVisible() )
266 launchMenu->hide(); 277 launchMenu->hide();
267 else 278 else
268 launchMenu->popup( QPoint( 1, y ) ); 279 launchMenu->popup( QPoint( 1, y ) );
269} 280}
270 281
271 282
272 283
273 284
274static int compareAppletPositions(const void *b, const void *a) 285static int compareAppletPositions(const void *b, const void *a)
275{ 286{
276 const MenuApplet* aa = *(const MenuApplet**)a; 287 const MenuApplet* aa = *(const MenuApplet**)a;
277 const MenuApplet* ab = *(const MenuApplet**)b; 288 const MenuApplet* ab = *(const MenuApplet**)b;
278 int d = aa->iface->position() - ab->iface->position(); 289 int d = aa->iface->position() - ab->iface->position();
279 if ( d ) return d; 290 if ( d ) return d;
280 return QString::compare(aa->library->library(),ab->library->library()); 291 return QString::compare(aa->library->library(),ab->library->library());
281} 292}
282 293
283void StartMenu::clearApplets() 294void StartMenu::clearApplets()
284{ 295{
285 if ( launchMenu ) 296 if ( launchMenu )
286 launchMenu-> hide(); 297 launchMenu-> hide();
287 298
288 for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) { 299 for ( QIntDictIterator<MenuApplet> it( menuApplets ); it.current(); ++it ) {
289 MenuApplet *applet = it.current(); 300 MenuApplet *applet = it.current();
290 if ( launchMenu ) { 301 if ( launchMenu ) {
291 launchMenu->removeItem( applet-> id ); 302 launchMenu->removeItem( applet-> id );
292 delete applet->popup; 303 delete applet->popup;
293 } 304 }
294 305
295 applet->iface->release(); 306 applet->iface->release();
296 applet->library->unload(); 307 applet->library->unload();
297 delete applet-> library; 308 delete applet-> library;
298 } 309 }
299 menuApplets.clear(); 310 menuApplets.clear();
300} 311}
301 312
302 313
303 314
304 315
305void StartMenu::loadApplets() 316void StartMenu::loadApplets()
306{ 317{
307 Config cfg( "StartMenu" ); 318 Config cfg( "StartMenu" );
308 cfg.setGroup( "Applets" ); 319 cfg.setGroup( "Applets" );
309 320
310 // SafeMode causes too much problems, so we disable it for now -- 321 // SafeMode causes too much problems, so we disable it for now --
311 // maybe we should reenable it for OPIE 1.0 - sandman 26.09.02 322 // maybe we should reenable it for OPIE 1.0 - sandman 26.09.02
312 // removed in the remerge PluginManager could handle it 323 // removed in the remerge PluginManager could handle it
313 // we don't currently use it -zecke 324 // we don't currently use it -zecke
314 325
315 QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' ); 326 QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' );
316 327
317 QString lang = getenv( "LANG" ); 328 QString lang = getenv( "LANG" );
318 QString path = QPEApplication::qpeDir() + "plugins/applets"; 329 QString path = QPEApplication::qpeDir() + "plugins/applets";
319 QDir dir( path, "lib*.so" ); 330 QDir dir( path, "lib*.so" );
320 QStringList list = dir.entryList(); 331 QStringList list = dir.entryList();
321 QStringList::Iterator it; 332 QStringList::Iterator it;
322 int napplets = 0; 333 int napplets = 0;
323 MenuApplet* *xapplets = new MenuApplet*[list.count()]; 334 MenuApplet* *xapplets = new MenuApplet*[list.count()];
324 for ( it = list.begin(); it != list.end(); ++it ) { 335 for ( it = list.begin(); it != list.end(); ++it ) {
325 if ( exclude.find( *it ) != exclude.end() ) 336 if ( exclude.find( *it ) != exclude.end() )
326 continue; 337 continue;
327 MenuAppletInterface *iface = 0; 338 MenuAppletInterface *iface = 0;
328 QLibrary *lib = new QLibrary( path + "/" + *it ); 339 QLibrary *lib = new QLibrary( path + "/" + *it );
329 if (( lib->queryInterface( IID_MenuApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) { 340 if (( lib->queryInterface( IID_MenuApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) {
330 MenuApplet *applet = new MenuApplet; 341 MenuApplet *applet = new MenuApplet;
331 xapplets[napplets++] = applet; 342 xapplets[napplets++] = applet;
332 applet->library = lib; 343 applet->library = lib;
333 applet->iface = iface; 344 applet->iface = iface;
334 345
335 QTranslator *trans = new QTranslator(qApp); 346 QTranslator *trans = new QTranslator(qApp);
336 QString type = (*it).left( (*it).find(".") ); 347 QString type = (*it).left( (*it).find(".") );
337 QString tfn = QPEApplication::qpeDir()+"i18n/"+lang+"/"+type+".qm"; 348 QString tfn = QPEApplication::qpeDir()+"i18n/"+lang+"/"+type+".qm";
338 if ( trans->load( tfn )) 349 if ( trans->load( tfn ))
339 qApp->installTranslator( trans ); 350 qApp->installTranslator( trans );
340 else 351 else
341 delete trans; 352 delete trans;
342 } else { 353 } else {
343 exclude += *it; 354 exclude += *it;
344 delete lib; 355 delete lib;
345 } 356 }
346 } 357 }
347 cfg.writeEntry( "ExcludeApplets", exclude, ',' ); 358 cfg.writeEntry( "ExcludeApplets", exclude, ',' );
348 qsort(xapplets, napplets, sizeof(menuApplets[0]), compareAppletPositions); 359 qsort(xapplets, napplets, sizeof(menuApplets[0]), compareAppletPositions);
349 360