-rw-r--r-- | core/launcher/desktop.cpp | 18 | ||||
-rw-r--r-- | core/launcher/desktop.h | 2 | ||||
-rw-r--r-- | core/launcher/startmenu.cpp | 252 | ||||
-rw-r--r-- | core/launcher/startmenu.h | 31 | ||||
-rw-r--r-- | core/launcher/systray.cpp | 2 | ||||
-rw-r--r-- | core/launcher/taskbar.cpp | 11 |
6 files changed, 288 insertions, 28 deletions
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp index 68949e6..1a33b36 100644 --- a/core/launcher/desktop.cpp +++ b/core/launcher/desktop.cpp @@ -335,96 +335,99 @@ void DesktopApplication::switchLCD ( bool on ) DesktopApplication::DesktopApplication( int& argc, char **argv, Type appType ) : QPEApplication( argc, argv, appType ) { QTimer * t = new QTimer( this ); connect( t, SIGNAL( timeout() ), this, SLOT( psTimeout() ) ); t->start( 10000 ); ps = new PowerStatus; pa = new DesktopPowerAlerter( 0 ); channel = new QCopChannel( "QPE/Desktop", this ); connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ), this, SLOT( desktopMessage( const QCString&, const QByteArray& ) ) ); channel = new QCopChannel( "QPE/System", this ); connect( channel, SIGNAL( received( const QCString&, const QByteArray& ) ), this, SLOT( systemMessage( const QCString&, const QByteArray& ) ) ); m_screensaver = new QPEScreenSaver; m_screensaver-> setInterval ( -1 ); QWSServer::setScreenSaver( m_screensaver ); } DesktopApplication::~DesktopApplication() { delete ps; delete pa; } void DesktopApplication::desktopMessage( const QCString &msg, const QByteArray &data ) { #ifdef Q_WS_QWS QDataStream stream( data, IO_ReadOnly ); if ( msg == "keyRegister(int key, QString channel, QString message)" ) { int k; QString c, m; stream >> k; stream >> c; stream >> m; qWarning( "KeyRegisterReceived: %i, %s, %s", k, ( const char* ) c, ( const char * ) m ); keyRegisterList.append( QCopKeyRegister( k, c, m ) ); } else if ( msg == "suspend()" ) { emit power(); } + else if ( msg == "home()" ) { + qpedesktop-> home ( ); + } #endif } void DesktopApplication::systemMessage( const QCString & msg, const QByteArray & data ) { #ifdef Q_WS_QWS QDataStream stream ( data, IO_ReadOnly ); if ( msg == "setScreenSaverInterval(int)" ) { int time; stream >> time; m_screensaver-> setInterval( time ); } else if ( msg == "setScreenSaverIntervals(int,int,int)" ) { int t1, t2, t3; stream >> t1 >> t2 >> t3; m_screensaver-> setIntervals( t1, t2, t3 ); } else if ( msg == "setBacklight(int)" ) { int bright; stream >> bright; m_screensaver-> setBacklight( bright ); } else if ( msg == "setScreenSaverMode(int)" ) { int mode; stream >> mode; m_screensaver-> setMode ( mode ); } #endif } enum MemState { Unknown, VeryLow, Low, Normal } memstate = Unknown; #ifdef Q_WS_QWS bool DesktopApplication::qwsEventFilter( QWSEvent *e ) { qpedesktop->checkMemory(); if ( e->type == QWSEvent::Key ) { QWSKeyEvent * ke = ( QWSKeyEvent * ) e; if ( !loggedin && ke->simpleData.keycode != Key_F34 ) return TRUE; bool press = ke->simpleData.is_press; bool autoRepeat = ke->simpleData.is_auto_repeat; /* app that registers key/message to be sent back to the app, when it doesn't have focus, @@ -672,107 +675,112 @@ void Desktop::checkMemory() memstate = Unknown; if ( ignoreNormal ) ignoreNormal = FALSE; else QMessageBox::information ( 0 , "Memory Status", "There is enough memory again." ); break; case VeryLow: memstate = Unknown; QMessageBox::critical( 0 , "Memory Status", "The memory is very low. \n" "Please end this application \n" "immediately." ); recoverMemory(); } existingMessage = FALSE; #endif } static bool isVisibleWindow( int wid ) { const QList<QWSWindow> &list = qwsServer->clientWindows(); QWSWindow* w; for ( QListIterator<QWSWindow> it( list ); ( w = it.current() ); ++it ) { if ( w->winId() == wid ) return !w->isFullyObscured(); } return FALSE; } static bool hasVisibleWindow( const QString& clientname ) { const QList<QWSWindow> &list = qwsServer->clientWindows(); QWSWindow* w; for ( QListIterator<QWSWindow> it( list ); ( w = it.current() ); ++it ) { if ( w->client() ->identity() == clientname && !w->isFullyObscured() ) return TRUE; } return FALSE; } void Desktop::raiseLauncher() { Config cfg( "qpe" ); //F12 'Home' cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "Middle", "Home" ); if ( tempItem == "Home" || tempItem.isEmpty() ) { - if ( isVisibleWindow( launcher->winId() ) ) - launcher->nextView(); - else - launcher->raise(); + home ( ); } else { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } } +void Desktop::home ( ) +{ + if ( isVisibleWindow( launcher->winId() ) ) + launcher->nextView(); + else + launcher->raise(); +} + void Desktop::executeOrModify( const QString& appLnkFile ) { AppLnk lnk( MimeType::appsFolderName() + "/" + appLnkFile ); if ( lnk.isValid() ) { QCString app = lnk.exec().utf8(); Global::terminateBuiltin( "calibrate" ); if ( QCopChannel::isRegistered( "QPE/Application/" + app ) ) { // MRUList::addTask( &lnk ); if ( hasVisibleWindow( app ) ) QCopChannel::send( "QPE/Application/" + app, "nextView()" ); else QCopChannel::send( "QPE/Application/" + app, "raise()" ); } else { lnk.execute(); } } } void Desktop::raiseDatebook() { Config cfg( "qpe" ); //F9 'Activity' cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "LeftEnd" , "Calendar" ); if ( tempItem == "Calendar" || tempItem.isEmpty() ) { tempItem = "datebook"; } QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } void Desktop::raiseContacts() { Config cfg( "qpe" ); //F10, 'Contacts' cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "Left2nd", "Address Book" ); if ( tempItem == "Address Book" || tempItem.isEmpty() ) { tempItem = "addressbook"; } QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } void Desktop::raiseMenu() { Config cfg( "qpe" ); //F11, 'Menu @@ -792,96 +800,98 @@ void Desktop::raiseMenu() void Desktop::raiseEmail() { Config cfg( "qpe" ); //F13, 'Mail' // only in zaurus, on ipaq mail key is F11 cfg.setGroup( "AppsKey" ); QString tempItem; tempItem = cfg.readEntry( "RightEnd", "Mail" ); if ( tempItem == "Mail" || tempItem == "qtmail" || tempItem.isEmpty() ) { tempItem = "mail"; } QCopEnvelope e( "QPE/System", "execute(QString)" ); e << tempItem; } // autoStarts apps on resume and start void Desktop::execAutoStart() { QString appName; int delay; QDateTime now = QDateTime::currentDateTime(); Config cfg( "autostart" ); cfg.setGroup( "AutoStart" ); appName = cfg.readEntry( "Apps", "" ); delay = ( cfg.readEntry( "Delay", "0" ) ).toInt(); // If the time between suspend and resume was longer then the // value saved as delay, start the app if ( suspendTime.secsTo( now ) >= ( delay * 60 ) && !appName.isEmpty() ) { QCopEnvelope e( "QPE/System", "execute(QString)" ); e << QString( appName ); } } #if defined(QPE_HAVE_TOGGLELIGHT) #include <qpe/config.h> #include <sys/ioctl.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <linux/ioctl.h> #include <time.h> #endif void Desktop::togglePower() { static bool excllock = false; + qDebug ( "togglePower (locked == %d)", excllock ? 1 : 0 ); + if ( excllock ) return ; excllock = true; bool wasloggedin = loggedin; loggedin = 0; suspendTime = QDateTime::currentDateTime(); ODevice::inst ( ) -> suspend ( ); QWSServer::screenSaverActivate ( false ); DesktopApplication::switchLCD ( true ); // force LCD on without slow qcop call { QCopEnvelope( "QPE/Card", "mtabChanged()" ); // might have changed while asleep } if ( wasloggedin ) login( TRUE ); execAutoStart(); //qcopBridge->closeOpenConnections(); excllock = false; } void Desktop::toggleLight() { QCopEnvelope e( "QPE/System", "setBacklight(int)" ); e << -2; // toggle } void Desktop::toggleSymbolInput() { tb->toggleSymbolInput(); } void Desktop::toggleNumLockState() { tb->toggleNumLockState(); } void Desktop::toggleCapsLockState() { tb->toggleCapsLockState(); } diff --git a/core/launcher/desktop.h b/core/launcher/desktop.h index f7c3e3f..09ffe1c 100644 --- a/core/launcher/desktop.h +++ b/core/launcher/desktop.h @@ -73,72 +73,74 @@ protected: public slots: virtual void desktopMessage ( const QCString &msg, const QByteArray &data ); virtual void systemMessage ( const QCString &msg, const QByteArray &data ); protected slots: void shutdown( ShutdownImpl::Type ); void psTimeout(); void sendCard(); private: DesktopPowerAlerter *pa; PowerStatus *ps; QTimer *cardSendTimer; QCopChannel *channel; QPEScreenSaver *m_screensaver; }; class Desktop : public QWidget { Q_OBJECT public: Desktop(); ~Desktop(); static bool screenLocked(); void show(); void checkMemory(); void keyClick(); void screenClick(); static void soundAlarm(); public slots: void raiseDatebook(); void raiseContacts(); void raiseMenu(); void raiseLauncher(); void raiseEmail(); void execAutoStart(); void togglePower(); void toggleLight(); void toggleNumLockState(); void toggleCapsLockState(); void toggleSymbolInput(); void terminateServers(); void rereadVolumes(); + void home ( ); + protected: void executeOrModify( const QString& appLnkFile ); void styleChange( QStyle & ); void timerEvent( QTimerEvent *e ); QWidget *bg; Launcher *launcher; TaskBar *tb; private: void startTransferServer(); bool recoverMemory(); QCopBridge *qcopBridge; TransferServer *transferServer; PackageSlave *packageSlave; QDateTime suspendTime; bool keyclick, touchclick, alarmsound; }; #endif // __DESKTOP_H__ diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp index b008a30..647d0f2 100644 --- a/core/launcher/startmenu.cpp +++ b/core/launcher/startmenu.cpp @@ -1,171 +1,385 @@ /********************************************************************** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** -** This file is part of Qtopia Environment. +** 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 <qdict.h> +#include <qintdict.h> +#include <qdir.h> #include <stdlib.h> // #define USE_CONFIG_FILE StartMenu::StartMenu(QWidget *parent) : QLabel( parent ) { loadOptions(); - setPixmap( Resource::loadPixmap( startButtonPixmap ) ); + int sz = AppLnk::smallIconSize()+3; + QPixmap pm; + pm.convertFromImage(Resource::loadImage(startButtonPixmap).smoothScale(sz,sz)); + setPixmap(pm); setFocusPolicy( NoFocus ); //setFlat( startButtonIsFlat ); - apps = new AppLnkSet( QPEApplication::qpeDir() + "apps" ); + apps = 0; + launchMenu = 0; + applets. setAutoDelete ( true ); + sepId = 0; - createMenu(); + reloadApps ( ); + reloadApplets ( ); } 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" ); + QString tmpBoolString3 = config.readEntry( "UseMRUList", "TRUE" ); popupMenuSidePixmap = config.readEntry( "PopupMenuSidePixmap", "launcher/sidebar" ); - startButtonPixmap = config.readEntry( "StartButtonPixmap", "go" ); + startButtonPixmap = config.readEntry( "StartButtonPixmap", "launcher/start_button" ); #else // Basically just #include the .qpe_menu.conf file settings useWidePopupMenu = FALSE; popupMenuSidePixmap = "launcher/sidebar"; startButtonIsFlat = TRUE; - startButtonPixmap = "launcher/start_button"; + startButtonPixmap = "launcher/start_button"; // No tr #endif } void StartMenu::createMenu() { + delete launchMenu; if ( useWidePopupMenu ) launchMenu = new PopupWithLaunchSideThing( this, &popupMenuSidePixmap ); else launchMenu = new StartPopupMenu( this ); loadMenu( apps, launchMenu ); + loadApplets ( ); + + connect( launchMenu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); +} +void StartMenu::reloadApps() +{ + Config cfg("StartMenu"); + 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 ( 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); + } else { + 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 ( ); + } } bool StartMenu::loadMenu( AppLnkSet *folder, QPopupMenu *menu ) { bool result = FALSE; - QStringList typs = folder->types(); + Config cfg("StartMenu"); + cfg.setGroup("Menu"); + + bool ltabs = cfg.readBoolEntry("LauncherTabs",TRUE); + bool lot = cfg.readBoolEntry("LauncherOther",TRUE); + + tabdict. clear ( ); + + if ( sepId ) + menu-> removeItem ( sepId ); + sepId = ( menu-> count ( )) ? menu-> insertSeparator ( 0 ) : 0; + + if ( ltabs || lot ) { QDict<QPopupMenu> typpop; - for (QStringList::Iterator tit=typs.begin(); tit!=typs.end(); ++tit) { + QStringList typs = folder->types(); + for (QStringList::Iterator tit=typs.fromLast(); ; --tit) { if ( !(*tit).isEmpty() ) { - QPopupMenu *new_menu = new StartPopupMenu( menu ); - typpop.insert(*tit, new_menu); + QPopupMenu *new_menu; + if ( ltabs ) { + new_menu = new StartPopupMenu( menu ); connect( new_menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); - menu->insertItem( folder->typePixmap(*tit), folder->typeName(*tit), new_menu ); + 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" ) { + 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; - pmenu->insertItem( app->pixmap(), app->name(), app->id() ); + else + pmenu = 0; + } + if ( pmenu ) { + QString t = app->name(); + t.replace(QRegExp("&"),"&&"); // escape shortcut character + pmenu->insertItem( app->pixmap(), t, app->id() ); + } result=TRUE; } } + } - if ( result ) - connect( menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) ); + 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 ( ); return result; } void StartMenu::launch() { int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height(); 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 = ab->iface->position() - aa->iface->position(); + if ( d ) return d; + return QString::compare(ab->library->library(),aa->library->library()); +} + +void StartMenu::clearApplets() +{ + launchMenu-> hide(); + + for ( QIntDictIterator<MenuApplet> it ( 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(); +} + + + +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 + + bool safe = false; //cfg.readBoolEntry("SafeMode",FALSE); + if ( safe && !safety_tid ) + return; + cfg.writeEntry("SafeMode",TRUE); + cfg.write(); + QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' ); + + 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; + } else { + exclude += *it; + delete lib; + } + } + cfg.writeEntry( "ExcludeApplets", exclude, ',' ); + qsort(xapplets,napplets,sizeof(applets[0]),compareAppletPositions); + + if ( sepId ) + launchMenu-> removeItem ( sepId ); + sepId = ( launchMenu-> count ( )) ? launchMenu-> insertSeparator ( ) : 0; + + while (napplets--) { + MenuApplet *applet = xapplets[napplets]; + QString lang = getenv( "LANG" ); + 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; + + 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 ( ) ); + applets.insert ( applet-> id, new MenuApplet(*applet)); + } + delete xapplets; + + if ( sepId && ( launchMenu-> idAt ( launchMenu-> count ( ) - 1 ) == sepId )) { // no applets + launchMenu-> removeItem ( sepId ); + sepId = 0; + } + if ( !launchMenu-> count ( )) // if we don't do this QPopupMenu will insert a dummy Separator, which won't go away later + sepId = launchMenu-> insertSeparator ( ); + + 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; + } +} + diff --git a/core/launcher/startmenu.h b/core/launcher/startmenu.h index a02f39e..0a91bb8 100644 --- a/core/launcher/startmenu.h +++ b/core/launcher/startmenu.h @@ -1,76 +1,103 @@ /********************************************************************** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** -** This file is part of Qtopia Environment. +** 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 <qstring.h> #include <qlist.h> +#include <qintdict.h> #include <qlabel.h> #include <qpopupmenu.h> +#include <qpe/menuappletinterface.h> class AppLnkSet; class AppLnk; class StartPopupMenu : public QPopupMenu { public: StartPopupMenu( QWidget *parent ) : QPopupMenu( parent ) {} protected: void keyPressEvent( QKeyEvent *e ); }; +class QLibrary; + +struct MenuApplet +{ +#ifndef QT_NO_COMPONENT + 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); public: StartPopupMenu *launchMenu; 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( ); 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; }; #endif // __START_MENU_H__ diff --git a/core/launcher/systray.cpp b/core/launcher/systray.cpp index 697971d..406c662 100644 --- a/core/launcher/systray.cpp +++ b/core/launcher/systray.cpp @@ -57,96 +57,96 @@ void SysTray::loadApplets() addApplets(); } void SysTray::clearApplets() { hide(); #ifndef SINGLE_APP QValueList<TaskbarApplet>::Iterator mit; for ( mit = appletList.begin(); mit != appletList.end(); ++mit ) { (*mit).iface->release(); (*mit).library->unload(); delete (*mit).library; } #endif appletList.clear(); if ( layout ) delete layout; layout = new QHBoxLayout( this, 0, 1 ); layout->setAutoAdd(TRUE); } void SysTray::addApplets() { #ifndef SINGLE_APP Config cfg( "Taskbar" ); 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 bool safe = false; //cfg.readBoolEntry("SafeMode",FALSE); if ( safe && !safety_tid ) return; cfg.writeEntry("SafeMode",TRUE); cfg.write(); QStringList exclude = cfg.readListEntry( "ExcludeApplets", ',' ); QString path = QPEApplication::qpeDir() + "/plugins/applets"; QDir dir( path, "lib*.so" ); QStringList list = dir.entryList(); QStringList::Iterator it; int napplets=0; TaskbarApplet* *applets = new TaskbarApplet*[list.count()]; for ( it = list.begin(); it != list.end(); ++it ) { if ( exclude.find( *it ) != exclude.end() ) continue; TaskbarAppletInterface *iface = 0; QLibrary *lib = new QLibrary( path + "/" + *it ); - if ( lib->queryInterface( IID_TaskbarApplet, (QUnknownInterface**)&iface ) == QS_OK ) { + if (( lib->queryInterface( IID_TaskbarApplet, (QUnknownInterface**)&iface ) == QS_OK ) && iface ) { TaskbarApplet *applet = new TaskbarApplet; applets[napplets++] = applet; applet->library = lib; applet->iface = iface; } else { exclude += *it; delete lib; } } cfg.writeEntry( "ExcludeApplets", exclude, ',' ); qsort(applets,napplets,sizeof(applets[0]),compareAppletPositions); while (napplets--) { TaskbarApplet *applet = applets[napplets]; applet->applet = applet->iface->applet( this ); appletList.append(*applet); QString lang = getenv( "LANG" ); 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; } delete applets; #else TaskbarApplet applet; applet.iface = new ClockAppletImpl(); applet.applet = applet.iface->applet( this ); appletList.append( a ); #endif show(); if ( !safety_tid ) safety_tid = startTimer(2000); // TT has 5000, but this is a PITA for a developer ;) (sandman) } void SysTray::timerEvent(QTimerEvent* e) { if ( e->timerId() == safety_tid ) { Config cfg( "Taskbar" ); cfg.setGroup( "Applets" ); cfg.writeEntry( "SafeMode", FALSE ); killTimer(safety_tid); safety_tid = 0; } } diff --git a/core/launcher/taskbar.cpp b/core/launcher/taskbar.cpp index 46bcdb3..7d1aaf1 100644 --- a/core/launcher/taskbar.cpp +++ b/core/launcher/taskbar.cpp @@ -146,181 +146,188 @@ TaskBar::TaskBar() : QHBox(0, 0, WStyle_Customize | WStyle_Tool | WStyle_StaysOn { Global::setBuiltinCommands(builtins); sm = new StartMenu( this ); inputMethods = new InputMethods( this ); connect( inputMethods, SIGNAL(inputToggled(bool)), this, SLOT(calcMaxWindowRect()) ); //new QuickLauncher( this ); stack = new QWidgetStack( this ); stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); label = new QLabel(stack); //mru = new MRUList( stack ); //stack->raiseWidget( mru ); runningAppBar = new RunningAppBar(stack); stack->raiseWidget(runningAppBar); waitIcon = new Wait( this ); (void) new AppIcons( this ); sysTray = new SysTray( this ); // ## make customizable in some way? #ifdef QT_QWS_CUSTOM lockState = new LockKeyState( this ); #else lockState = 0; #endif #if defined(Q_WS_QWS) #if !defined(QT_NO_COP) QCopChannel *channel = new QCopChannel( "QPE/TaskBar", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(receive(const QCString&, const QByteArray&)) ); #endif #endif waitTimer = new QTimer( this ); connect( waitTimer, SIGNAL( timeout() ), this, SLOT( stopWait() ) ); clearer = new QTimer( this ); QObject::connect(clearer, SIGNAL(timeout()), SLOT(clearStatusBar())); QObject::connect(clearer, SIGNAL(timeout()), sysTray, SLOT(show())); } void TaskBar::setStatusMessage( const QString &text ) { + if ( !text.isEmpty() ) { label->setText( text ); stack->raiseWidget( label ); if ( sysTray && ( label->fontMetrics().width( text ) > label->width() ) ) sysTray->hide(); - clearer->start( 3000 ); + clearer->start( 3000, TRUE ); + } else { + clearStatusBar(); + } } void TaskBar::clearStatusBar() { label->clear(); stack->raiseWidget(runningAppBar); // stack->raiseWidget( mru ); } void TaskBar::startWait() { waitIcon->setWaiting( true ); // a catchall stop after 10 seconds... waitTimer->start( 10 * 1000, true ); } -void TaskBar::stopWait(const QString& app) +void TaskBar::stopWait(const QString& /*app*/) { waitTimer->stop(); //mru->addTask(sm->execToLink(app)); waitIcon->setWaiting( false ); } void TaskBar::stopWait() { waitTimer->stop(); waitIcon->setWaiting( false ); } void TaskBar::resizeEvent( QResizeEvent *e ) { QHBox::resizeEvent( e ); calcMaxWindowRect(); } void TaskBar::styleChange( QStyle &s ) { QHBox::styleChange( s ); calcMaxWindowRect(); } void TaskBar::calcMaxWindowRect() { #ifdef Q_WS_QWS QRect wr; int displayWidth = qApp->desktop()->width(); QRect ir = inputMethods->inputRect(); if ( ir.isValid() ) { wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 ); } else { wr.setCoords( 0, 0, displayWidth-1, y()-1 ); } #if QT_VERSION < 300 QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr, QSize(qt_screen->width(),qt_screen->height())) ); #else QWSServer::setMaxWindowRect( wr ); #endif #endif } void TaskBar::receive( const QCString &msg, const QByteArray &data ) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "message(QString)" ) { QString text; stream >> text; setStatusMessage( text ); } else if ( msg == "hideInputMethod()" ) { inputMethods->hideInputMethod(); } else if ( msg == "showInputMethod()" ) { inputMethods->showInputMethod(); } else if ( msg == "reloadInputMethods()" ) { inputMethods->loadInputMethods(); + } else if ( msg == "reloadApps()" ) { + sm->reloadApps(); } else if ( msg == "reloadApplets()" ) { sysTray->clearApplets(); sysTray->addApplets(); + sm->reloadApplets(); } else if ( msg == "soundAlarm()" ) { Desktop::soundAlarm(); } else if ( msg == "setLed(int,bool)" ) { int led, status; stream >> led >> status; QValueList <OLed> ll = ODevice::inst ( )-> ledList ( ); if ( ll. count ( )) { OLed l = ll. contains ( Led_Mail ) ? Led_Mail : ll [0]; bool canblink = ODevice::inst ( )-> ledStateList ( l ). contains ( Led_BlinkSlow ); ODevice::inst ( )-> setLedState ( l, status ? ( canblink ? Led_BlinkSlow : Led_On ) : Led_Off ); } } } QWidget *TaskBar::calibrate(bool) { #ifdef Q_WS_QWS Calibrate *c = new Calibrate; c->show(); return c; #else return 0; #endif } void TaskBar::toggleNumLockState() { if ( lockState ) lockState->toggleNumLockState(); } void TaskBar::toggleCapsLockState() { if ( lockState ) lockState->toggleCapsLockState(); } void TaskBar::toggleSymbolInput() { if ( inputMethods->currentShown() == "Unicode" ) { inputMethods->hideInputMethod(); } else { inputMethods->showInputMethod("Unicode"); } } bool TaskBar::recoverMemory() |