Qtopia library API Documentation

qpeapplication.cpp

00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 */
00020 #define QTOPIA_INTERNAL_LANGLIST
00021 #include <stdlib.h>
00022 #include <unistd.h>
00023 #ifndef Q_OS_MACX
00024 #include <linux/limits.h> // needed for some toolchains (PATH_MAX)
00025 #endif
00026 #include <qfile.h>
00027 #include <qqueue.h>
00028 #ifdef Q_WS_QWS
00029 #ifndef QT_NO_COP
00030 #if QT_VERSION <= 231
00031 #define private public
00032 #define sendLocally processEvent
00033 #include "qcopenvelope_qws.h"
00034 #undef private
00035 #else
00036 #include "qcopenvelope_qws.h"
00037 #endif
00038 #endif
00039 #include <qwindowsystem_qws.h>
00040 #endif
00041 #include <qtextstream.h>
00042 #include <qpalette.h>
00043 #include <qbuffer.h>
00044 #include <qptrdict.h>
00045 #include <qregexp.h>
00046 #include <qdir.h>
00047 #include <qlabel.h>
00048 #include <qdialog.h>
00049 #include <qdragobject.h>
00050 #include <qtextcodec.h>
00051 #include <qevent.h>
00052 #include <qtooltip.h>
00053 #include <qsignal.h>
00054 #include <qmainwindow.h>
00055 #include <qwidgetlist.h>
00056 #include <qpixmapcache.h>
00057 
00058 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
00059 #define QTOPIA_INTERNAL_INITAPP
00060 #include "qpeapplication.h"
00061 #include "qpestyle.h"
00062 #include "styleinterface.h"
00063 #if QT_VERSION >= 300
00064 #include <qstylefactory.h>
00065 #else
00066 #include <qplatinumstyle.h>
00067 #include <qwindowsstyle.h>
00068 #include <qmotifstyle.h>
00069 #include <qmotifplusstyle.h>
00070 #include "lightstyle.h"
00071 
00072 #include <qpe/qlibrary.h>
00073 #endif
00074 #include "global.h"
00075 #include "resource.h"
00076 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00077 #include "qutfcodec.h"
00078 #endif
00079 #include "config.h"
00080 #include "network.h"
00081 #ifdef QWS
00082 #include "fontmanager.h"
00083 #endif
00084 
00085 #include "alarmserver.h"
00086 #include "applnk.h"
00087 #include "qpemenubar.h"
00088 #include "textcodecinterface.h"
00089 #include "imagecodecinterface.h"
00090 
00091 #include <unistd.h>
00092 #include <sys/file.h>
00093 #include <sys/ioctl.h>
00094 #ifndef QT_NO_SOUND
00095 #include <sys/soundcard.h>
00096 #endif
00097 #include "qt_override_p.h"
00098 
00099 
00100 class QPEApplicationData
00101 {
00102 public:
00103     QPEApplicationData ( )
00104         : presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ),
00105           notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ),
00106           keep_running( true ), qcopQok( false ), qpe_main_widget( 0 )
00107 
00108     {}
00109 
00110     int presstimer;
00111     QWidget* presswidget;
00112     QPoint presspos;
00113 
00114     bool rightpressed : 1;
00115     bool kbgrabbed    : 1;
00116     bool notbusysent  : 1;
00117     bool preloaded    : 1;
00118     bool forceshow    : 1;
00119     bool nomaximize   : 1;
00120     bool keep_running : 1;
00121         bool qcopQok      : 1;
00122 
00123 
00124         QStringList langs;
00125     QString appName;
00126     struct QCopRec
00127     {
00128         QCopRec( const QCString &ch, const QCString &msg,
00129                  const QByteArray &d ) :
00130                 channel( ch ), message( msg ), data( d )
00131         { }
00132 
00133         QCString channel;
00134         QCString message;
00135         QByteArray data;
00136     };
00137     QWidget* qpe_main_widget;
00138         QGuardedPtr<QWidget> lastraised;
00139     QQueue<QCopRec> qcopq;
00140         QString styleName;
00141     QString decorationName;
00142 
00143     void enqueueQCop( const QCString &ch, const QCString &msg,
00144                       const QByteArray &data )
00145     {
00146         qcopq.enqueue( new QCopRec( ch, msg, data ) );
00147     }
00148     void sendQCopQ()
00149     {
00150             if (!qcopQok )
00151                 return;
00152 
00153         QCopRec * r;
00154 
00155            while((r=qcopq.dequeue())) {
00156                // remove from queue before sending...
00157                // event loop can come around again before getting
00158                // back from sendLocally
00159 #ifndef QT_NO_COP
00160                QCopChannel::sendLocally( r->channel, r->message, r->data );
00161 #endif
00162 
00163            delete r;
00164            }
00165     }
00166     static void show_mx(QWidget* mw, bool nomaximize,  const QString & = QString::null )
00167     {
00168 
00169             // ugly hack, remove that later after finding a sane solution
00170             // Addendum: Only Sharp currently has models with high resolution but (physically) small displays,
00171             // so this is only useful if QT_QWS_SIMPAD is NOT defined. E.g. SIMpad has 800x600 but has
00172             // a (physically) large enough display to use the small icons
00173 #if defined(OPIE_HIGH_RES_SMALL_PHY)
00174             if ( QPEApplication::desktop() ->width() >= 600 && ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") ) )  {
00175                 ( (  QMainWindow* ) mw )->setUsesBigPixmaps( true );
00176             }
00177 #endif
00178 
00179         if ( mw->layout() && mw->inherits("QDialog") ) {
00180             QPEApplication::showDialog((QDialog*)mw, nomaximize);
00181         }
00182         else {
00183 #ifdef Q_WS_QWS
00184             if ( !nomaximize )
00185                 mw->showMaximized();
00186             else
00187 #endif
00188 
00189                 mw->show();
00190         }
00191     }
00192     static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
00193     {
00194         /*
00195         // This works but disable it for now until it is safe to apply
00196         // What is does is scan the .desktop files of all the apps for
00197         // the applnk that has the corresponding argv[0] as this program
00198         // then it uses the name stored in the .desktop file as the caption
00199         // for the main widget. This saves duplicating translations for
00200         // the app name in the program and in the .desktop files.
00201 
00202         AppLnkSet apps( appsPath );
00203 
00204         QList<AppLnk> appsList = apps.children();
00205         for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
00206           if ( (*it)->exec() == appName ) {
00207         mw->setCaption( (*it)->name() );
00208         return TRUE;
00209           }
00210         }
00211         */
00212         return FALSE;
00213     }
00214 
00215 
00216     void show(QWidget* mw, bool nomax)
00217     {
00218         setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" );
00219         nomaximize = nomax;
00220         qpe_main_widget = mw;
00221                 qcopQok = TRUE;
00222 #ifndef QT_NO_COP
00223 
00224         sendQCopQ();
00225 #endif
00226 
00227         if ( preloaded ) {
00228             if (forceshow)
00229                 show_mx(mw, nomax);
00230         }
00231         else if ( keep_running ) {
00232             show_mx(mw, nomax);
00233         }
00234     }
00235 
00236     void loadTextCodecs()
00237     {
00238         QString path = QPEApplication::qpeDir() + "/plugins/textcodecs";
00239 #ifdef Q_OS_MACX
00240         QDir dir( path, "lib*.dylib" );
00241 #else
00242         QDir dir( path, "lib*.so" );
00243 #endif
00244         QStringList list;
00245         if ( dir. exists ( ))
00246             list = dir.entryList();
00247         QStringList::Iterator it;
00248         for ( it = list.begin(); it != list.end(); ++it ) {
00249             TextCodecInterface *iface = 0;
00250             QLibrary *lib = new QLibrary( path + "/" + *it );
00251             if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
00252                 QValueList<int> mibs = iface->mibEnums();
00253                 for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) {
00254                     (void)iface->createForMib(*i);
00255                     // ### it exists now; need to remember if we can delete it
00256                 }
00257             }
00258             else {
00259                 lib->unload();
00260                 delete lib;
00261             }
00262         }
00263     }
00264 
00265     void loadImageCodecs()
00266     {
00267         QString path = QPEApplication::qpeDir() + "/plugins/imagecodecs";
00268 #ifdef Q_OS_MACX
00269         QDir dir( path, "lib*.dylib" );
00270 #else
00271         QDir dir( path, "lib*.so" );
00272 #endif
00273         QStringList list;
00274         if ( dir. exists ( ))
00275             list = dir.entryList();
00276         QStringList::Iterator it;
00277         for ( it = list.begin(); it != list.end(); ++it ) {
00278             ImageCodecInterface *iface = 0;
00279             QLibrary *lib = new QLibrary( path + "/" + *it );
00280             if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
00281                 QStringList formats = iface->keys();
00282                 for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) {
00283                     (void)iface->installIOHandler(*i);
00284                     // ### it exists now; need to remember if we can delete it
00285                 }
00286             }
00287             else {
00288                 lib->unload();
00289                 delete lib;
00290             }
00291         }
00292     }
00293 };
00294 
00295 class ResourceMimeFactory : public QMimeSourceFactory
00296 {
00297 public:
00298         ResourceMimeFactory() : resImage( 0 )
00299     {
00300         setFilePath( Global::helpPath() );
00301         setExtensionType( "html", "text/html;charset=UTF-8" );
00302     }
00303         ~ResourceMimeFactory() {
00304             delete resImage;
00305         }
00306 
00307     const QMimeSource* data( const QString& abs_name ) const
00308     {
00309         const QMimeSource * r = QMimeSourceFactory::data( abs_name );
00310         if ( !r ) {
00311             int sl = abs_name.length();
00312             do {
00313                 sl = abs_name.findRev( '/', sl - 1 );
00314                 QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name;
00315                 int dot = name.findRev( '.' );
00316                 if ( dot >= 0 )
00317                     name = name.left( dot );
00318                 QImage img = Resource::loadImage( name );
00319                 if ( !img.isNull() ) {
00320                                     delete resImage;
00321                                     resImage = new QImageDrag( img );
00322                                     r = resImage;
00323                                 }
00324             }
00325             while ( !r && sl > 0 );
00326         }
00327         return r;
00328     }
00329 private:
00330     mutable QImageDrag *resImage;
00331 };
00332 
00333 static int& hack(int& i)
00334 {
00335 #if QT_VERSION <= 230 && defined(QT_NO_CODECS)
00336     // These should be created, but aren't in Qt 2.3.0
00337     (void)new QUtf8Codec;
00338     (void)new QUtf16Codec;
00339 #endif
00340     return i;
00341 }
00342 
00343 static int muted = 0;
00344 static int micMuted = 0;
00345 
00346 static void setVolume( int t = 0, int percent = -1 )
00347 {
00348     switch ( t ) {
00349         case 0: {
00350                 Config cfg( "qpe" );
00351                 cfg.setGroup( "Volume" );
00352                 if ( percent < 0 )
00353                     percent = cfg.readNumEntry( "VolumePercent", 50 );
00354 #ifndef QT_NO_SOUND
00355                 int fd = 0;
00356                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00357                     int vol = muted ? 0 : percent;
00358                     // set both channels to same volume
00359                     vol |= vol << 8;
00360                     ioctl( fd, MIXER_WRITE( 0 ), &vol );
00361                     ::close( fd );
00362                 }
00363 #endif
00364             }
00365             break;
00366     }
00367 }
00368 
00369 static void setMic( int t = 0, int percent = -1 )
00370 {
00371     switch ( t ) {
00372         case 0: {
00373                 Config cfg( "qpe" );
00374                 cfg.setGroup( "Volume" );
00375                 if ( percent < 0 )
00376                     percent = cfg.readNumEntry( "Mic", 50 );
00377 
00378 #ifndef QT_NO_SOUND
00379                 int fd = 0;
00380                 int mic = micMuted ? 0 : percent;
00381                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00382                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic );
00383                     ::close( fd );
00384                 }
00385 #endif
00386             }
00387             break;
00388     }
00389 }
00390 
00391 
00392 static void setBass( int t = 0, int percent = -1 )
00393 {
00394     switch ( t ) {
00395         case 0: {
00396                 Config cfg( "qpe" );
00397                 cfg.setGroup( "Volume" );
00398                 if ( percent < 0 )
00399                     percent = cfg.readNumEntry( "BassPercent", 50 );
00400 
00401 #ifndef QT_NO_SOUND
00402                 int fd = 0;
00403                 int bass = percent;
00404                                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00405                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass );
00406                     ::close( fd );
00407                 }
00408 #endif
00409             }
00410             break;
00411     }
00412 }
00413 
00414 
00415 static void setTreble( int t = 0, int percent = -1 )
00416 {
00417     switch ( t ) {
00418         case 0: {
00419                 Config cfg( "qpe" );
00420                 cfg.setGroup( "Volume" );
00421                 if ( percent < 0 )
00422                     percent = cfg.readNumEntry( "TreblePercent", 50 );
00423 
00424 #ifndef QT_NO_SOUND
00425                 int fd = 0;
00426                 int treble = percent;
00427                 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
00428                     ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble );
00429                     ::close( fd );
00430                 }
00431 #endif
00432             }
00433             break;
00434     }
00435 }
00436 
00437 
00534 void QPEApplication::processQCopFile()
00535 {
00536     QString qcopfn("/tmp/qcop-msg-");
00537     qcopfn += d->appName; // append command name
00538 
00539     QFile f(qcopfn);
00540     if ( f.open(IO_ReadWrite) ) {
00541 #ifndef Q_OS_WIN32
00542     flock(f.handle(), LOCK_EX);
00543 #endif
00544     QDataStream ds(&f);
00545     QCString channel, message;
00546     QByteArray data;
00547     while(!ds.atEnd()) {
00548         ds >> channel >> message >> data;
00549         d->enqueueQCop(channel,message,data);
00550     }
00551     ::ftruncate(f.handle(), 0);
00552 #ifndef Q_OS_WIN32
00553     f.flush();
00554     flock(f.handle(), LOCK_UN);
00555 #endif
00556     }
00557 #endif
00558 }
00559 
00560 
00597 QPEApplication::QPEApplication( int & argc, char **argv, Type t )
00598         : QApplication( hack(argc), argv, t ), pidChannel( 0 )
00599 {
00600         QPixmapCache::setCacheLimit(256); // sensible default for smaller devices.
00601 
00602     d = new QPEApplicationData;
00603     d->loadTextCodecs();
00604     d->loadImageCodecs();
00605         int dw = desktop() ->width();
00606 
00607     if ( dw < 200 ) {
00608         setFont( QFont( "vera", 8 ) );
00609         AppLnk::setSmallIconSize( 10 );
00610         AppLnk::setBigIconSize( 28 );
00611     }
00612 #if defined(OPIE_HIGH_RES_SMALL_PHY)
00613     else if ( dw > 600 ) {
00614                 setFont( QFont( "vera", 16 ) );
00615                 AppLnk::setSmallIconSize( 24 );
00616         AppLnk::setBigIconSize( 48 );
00617     }
00618 #endif
00619     else if ( dw > 200 ) {
00620         setFont( QFont( "vera", 10 ) );
00621         AppLnk::setSmallIconSize( 14 );
00622         AppLnk::setBigIconSize( 32 );
00623     }
00624 
00625     QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory );
00626 
00627     connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) );
00628 
00629 
00630     sysChannel = new QCopChannel( "QPE/System", this );
00631     connect( sysChannel, SIGNAL( received( const QCString &, const QByteArray & ) ),
00632              this, SLOT( systemMessage( const QCString &, const QByteArray & ) ) );
00633 
00634 /* COde now in initapp */
00635 #if 0
00636 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
00637 
00638     QString qcopfn( "/tmp/qcop-msg-" );
00639     qcopfn += QString( argv[ 0 ] ); // append command name
00640 
00641     QFile f( qcopfn );
00642     if ( f.open( IO_ReadOnly ) ) {
00643         flock( f.handle(), LOCK_EX );
00644     }
00645 
00646 
00647 
00648     QCString channel = QCString( argv[ 0 ] );
00649     channel.replace( QRegExp( ".*/" ), "" );
00650     d->appName = channel;
00651     channel = "QPE/Application/" + channel;
00652     pidChannel = new QCopChannel( channel, this );
00653     connect( pidChannel, SIGNAL( received( const QCString &, const QByteArray & ) ),
00654              this, SLOT( pidMessage( const QCString &, const QByteArray & ) ) );
00655 
00656     if ( f.isOpen() ) {
00657         d->keep_running = FALSE;
00658         QDataStream ds( &f );
00659         QCString channel, message;
00660         QByteArray data;
00661         while ( !ds.atEnd() ) {
00662             ds >> channel >> message >> data;
00663             d->enqueueQCop( channel, message, data );
00664         }
00665 
00666         flock( f.handle(), LOCK_UN );
00667         f.close();
00668         f.remove();
00669     }
00670 
00671     for ( int a = 0; a < argc; a++ ) {
00672         if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) {
00673             argv[ a ] = argv[ a + 1 ];
00674             a++;
00675             d->preloaded = TRUE;
00676             argc -= 1;
00677         }
00678         else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) {
00679             argv[ a ] = argv[ a + 1 ];
00680             a++;
00681             d->preloaded = TRUE;
00682             d->forceshow = TRUE;
00683             argc -= 1;
00684         }
00685     }
00686 
00687     /* overide stored arguments */
00688     setArgs( argc, argv );
00689 
00690 #endif
00691 #else
00692         initApp( argc, argv );
00693 #endif
00694     //  qwsSetDecoration( new QPEDecoration() );
00695 
00696 #ifndef QT_NO_TRANSLATION
00697 
00698     d->langs = Global::languageList();
00699     for ( QStringList::ConstIterator it = d->langs.begin(); it != d->langs.end(); ++it ) {
00700         QString lang = *it;
00701 
00702                 installTranslation( lang + "/libopie.qm");
00703         installTranslation( lang + "/libqpe.qm" );
00704         installTranslation( lang + "/" + d->appName + ".qm" );
00705 
00706 
00707         //###language/font hack; should look it up somewhere
00708 #ifdef QWS
00709 
00710                 if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
00711                     QFont fn = FontManager::unicodeFont( FontManager::Proportional );
00712                     setFont( fn );
00713                 }
00714 #endif
00715         }
00716 #endif
00717 
00718     applyStyle();
00719 
00720     if ( type() == GuiServer ) {
00721         setVolume();
00722     }
00723 
00724     installEventFilter( this );
00725 
00726     QPEMenuToolFocusManager::initialize();
00727 
00728 #ifdef QT_NO_QWS_CURSOR
00729     // if we have no cursor, probably don't want tooltips
00730     QToolTip::setEnabled( FALSE );
00731 #endif
00732 }
00733 
00734 
00735 #ifdef QTOPIA_INTERNAL_INITAPP
00736 void QPEApplication::initApp( int argc, char **argv )
00737 {
00738     bool initial = pidChannel; // was set to 0 in the initializer
00739     delete pidChannel;
00740     d->keep_running = TRUE;
00741     d->preloaded = FALSE;
00742     d->forceshow = FALSE;
00743 
00744     QCString channel = QCString(argv[0]);
00745 
00746     channel.replace(QRegExp(".*/"),"");
00747     d->appName = channel;
00748 
00749     #if QT_VERSION > 235
00750     qt_fbdpy->setIdentity( channel ); // In Qt/E 2.3.6
00751     #endif
00752 
00753     channel = "QPE/Application/" + channel;
00754     pidChannel = new QCopChannel( channel, this);
00755     connect( pidChannel, SIGNAL(received(const QCString &, const QByteArray &)),
00756         this, SLOT(pidMessage(const QCString &, const QByteArray &)));
00757 
00758     if (!initial) {
00759         processQCopFile();
00760         d->keep_running = d->qcopq.isEmpty();
00761     }
00762 
00763     for (int a=0; a<argc; a++) {
00764     if ( qstrcmp(argv[a],"-preload")==0 ) {
00765         argv[a] = argv[a+1];
00766         a++;
00767         d->preloaded = TRUE;
00768         argc-=1;
00769     } else if ( qstrcmp(argv[a],"-preload-show")==0 ) {
00770         argv[a] = argv[a+1];
00771         a++;
00772         d->preloaded = TRUE;
00773         d->forceshow = TRUE;
00774         argc-=1;
00775     }
00776     }
00777 
00778     /* overide stored arguments */
00779     setArgs(argc, argv);
00780 
00781     /* install translation here */
00782     for ( QStringList::ConstIterator it = d->langs.begin(); it != d->langs.end(); ++it )
00783         installTranslation( (*it) + "/" + d->appName + ".qm" );
00784 }
00785 #endif
00786 
00787 
00788 static QPtrDict<void>* inputMethodDict = 0;
00789 static void createInputMethodDict()
00790 {
00791     if ( !inputMethodDict )
00792         inputMethodDict = new QPtrDict<void>;
00793 }
00794 
00802 QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w )
00803 {
00804     if ( inputMethodDict && w )
00805         return ( InputMethodHint ) ( int ) inputMethodDict->find( w );
00806     return Normal;
00807 }
00808 
00823 void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode )
00824 {
00825     createInputMethodDict();
00826     if ( mode == Normal ) {
00827         inputMethodDict->remove
00828         ( w );
00829     }
00830     else {
00831         inputMethodDict->insert( w, ( void* ) mode );
00832     }
00833 }
00834 
00835 class HackDialog : public QDialog
00836 {
00837 public:
00838     void acceptIt()
00839     {
00840         accept();
00841     }
00842     void rejectIt()
00843     {
00844         reject();
00845     }
00846 };
00847 
00848 
00849 void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key )
00850 {
00851     // specialised actions for certain widgets. May want to
00852     // add more stuff here.
00853     if ( activePopupWidget() && activePopupWidget() ->inherits( "QListBox" )
00854             && activePopupWidget() ->parentWidget()
00855             && activePopupWidget() ->parentWidget() ->inherits( "QComboBox" ) )
00856         key = Qt::Key_Return;
00857 
00858     if ( activePopupWidget() && activePopupWidget() ->inherits( "QPopupMenu" ) )
00859         key = Qt::Key_Return;
00860 
00861 #ifdef QWS
00862 
00863     ke->simpleData.keycode = key;
00864 #endif
00865 }
00866 
00867 class HackWidget : public QWidget
00868 {
00869 public:
00870     bool needsOk()
00871     {
00872         return ( getWState() & WState_Reserved1 );
00873     }
00874 };
00875 
00880 #ifdef QWS
00881 bool QPEApplication::qwsEventFilter( QWSEvent * e )
00882 {
00883     if ( !d->notbusysent && e->type == QWSEvent::Focus ) {
00884         if ( qApp->type() != QApplication::GuiServer ) {
00885             QCopEnvelope e( "QPE/System", "notBusy(QString)" );
00886             e << d->appName;
00887         }
00888         d->notbusysent = TRUE;
00889     }
00890     if ( type() == GuiServer ) {
00891         switch ( e->type ) {
00892             case QWSEvent::Mouse:
00893                 if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) )
00894                     emit clientMoused();
00895                 break;
00896             default:
00897                 break;
00898         }
00899     }
00900     if ( e->type == QWSEvent::Key ) {
00901         QWSKeyEvent *ke = ( QWSKeyEvent * ) e;
00902         if ( ke->simpleData.keycode == Qt::Key_F33 ) {
00903             // Use special "OK" key to press "OK" on top level widgets
00904             QWidget * active = activeWindow();
00905             QWidget *popup = 0;
00906             if ( active && active->isPopup() ) {
00907                 popup = active;
00908                 active = active->parentWidget();
00909             }
00910             if ( active && ( int ) active->winId() == ke->simpleData.window &&
00911                     !active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) {
00912                 if ( ke->simpleData.is_press ) {
00913                     if ( popup )
00914                         popup->close();
00915                     if ( active->inherits( "QDialog" ) ) {
00916                         HackDialog * d = ( HackDialog * ) active;
00917                         d->acceptIt();
00918                         return TRUE;
00919                     }
00920                     else if ( ( ( HackWidget * ) active ) ->needsOk() ) {
00921                         QSignal s;
00922                         s.connect( active, SLOT( accept() ) );
00923                         s.activate();
00924                     }
00925                     else {
00926                         // do the same as with the select key: Map to the default action of the widget:
00927                         mapToDefaultAction( ke, Qt::Key_Return );
00928                     }
00929                 }
00930             }
00931         }
00932         else if ( ke->simpleData.keycode == Qt::Key_F30 ) {
00933             // Use special "select" key to do whatever default action a widget has
00934             mapToDefaultAction( ke, Qt::Key_Space );
00935         }
00936         else if ( ke->simpleData.keycode == Qt::Key_Escape &&
00937                   ke->simpleData.is_press ) {
00938             // Escape key closes app if focus on toplevel
00939             QWidget * active = activeWindow();
00940             if ( active && active->testWFlags( WType_TopLevel ) &&
00941                     ( int ) active->winId() == ke->simpleData.window &&
00942                     !active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) {
00943                 if ( active->inherits( "QDialog" ) ) {
00944                     HackDialog * d = ( HackDialog * ) active;
00945                     d->rejectIt();
00946                     return TRUE;
00947                 }
00948                 else if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 ) {
00949                     active->close();
00950                 }
00951             }
00952         }
00953         else if ( ke->simpleData.keycode >= Qt::Key_F1 && ke->simpleData.keycode <= Qt::Key_F29 ) {
00954             // this should be if ( ODevice::inst ( )-> buttonForKeycode ( ... ))
00955             // but we cannot access libopie function within libqpe :(
00956 
00957             QWidget * active = activeWindow ( );
00958             if ( active && ((int) active-> winId ( ) == ke-> simpleData.window )) {
00959                 if ( d-> kbgrabbed ) { // we grabbed the keyboard
00960                     QChar ch ( ke-> simpleData.unicode );
00961                     QKeyEvent qke ( ke-> simpleData. is_press ? QEvent::KeyPress : QEvent::KeyRelease,
00962                                     ke-> simpleData.keycode,
00963                                     ch. latin1 ( ),
00964                                     ke-> simpleData.modifiers,
00965                                     QString ( ch ),
00966                                     ke-> simpleData.is_auto_repeat, 1 );
00967 
00968                     QObject *which = QWidget::keyboardGrabber ( );
00969                     if ( !which )
00970                         which = QApplication::focusWidget ( );
00971                     if ( !which )
00972                         which = QApplication::activeWindow ( );
00973                     if ( !which )
00974                         which = qApp;
00975 
00976                     QApplication::sendEvent ( which, &qke );
00977                 }
00978                 else { // we didn't grab the keyboard, so send the event to the launcher
00979                     QCopEnvelope e ( "QPE/Launcher", "deviceButton(int,int,int)" );
00980                     e << int( ke-> simpleData.keycode ) << int( ke-> simpleData. is_press ) << int( ke-> simpleData.is_auto_repeat );
00981                 }
00982             }
00983             return true;
00984         }
00985     }
00986     if ( e->type == QWSEvent::Focus ) {
00987         QWSFocusEvent * fe = ( QWSFocusEvent* ) e;
00988         if ( !fe->simpleData.get_focus ) {
00989             QWidget * active = activeWindow();
00990             while ( active && active->isPopup() ) {
00991                 active->close();
00992                 active = activeWindow();
00993             }
00994         }
00995         else {
00996             // make sure our modal widget is ALWAYS on top
00997             QWidget *topm = activeModalWidget();
00998             if ( topm ) {
00999                 topm->raise();
01000             }
01001         }
01002         if ( fe->simpleData.get_focus && inputMethodDict ) {
01003             InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) );
01004             if ( m == AlwaysOff )
01005                 Global::hideInputMethod();
01006             if ( m == AlwaysOn )
01007                 Global::showInputMethod();
01008         }
01009     }
01010 
01011 
01012     return QApplication::qwsEventFilter( e );
01013 }
01014 #endif
01015 
01019 QPEApplication::~QPEApplication()
01020 {
01021     ungrabKeyboard();
01022 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
01023     // Need to delete QCopChannels early, since the display will
01024     // be gone by the time we get to ~QObject().
01025     delete sysChannel;
01026     delete pidChannel;
01027 #endif
01028 
01029     delete d;
01030 }
01031 
01035 QString QPEApplication::qpeDir()
01036 {
01037     const char * base = getenv( "OPIEDIR" );
01038     if ( base )
01039         return QString( base ) + "/";
01040 
01041     return QString( "../" );
01042 }
01043 
01048 QString QPEApplication::documentDir()
01049 {
01050     const char* base = getenv( "HOME");
01051     if ( base )
01052         return QString( base ) + "/Documents";
01053 
01054     return QString( "../Documents" );
01055 }
01056 
01057 static int deforient = -1;
01058 
01062 int QPEApplication::defaultRotation()
01063 {
01064     if ( deforient < 0 ) {
01065         QString d = getenv( "QWS_DISPLAY" );
01066         if ( d.contains( "Rot90" ) ) {
01067             deforient = 90;
01068         }
01069         else if ( d.contains( "Rot180" ) ) {
01070             deforient = 180;
01071         }
01072         else if ( d.contains( "Rot270" ) ) {
01073             deforient = 270;
01074         }
01075         else {
01076             deforient = 0;
01077         }
01078     }
01079     return deforient;
01080 }
01081 
01085 void QPEApplication::setDefaultRotation( int r )
01086 {
01087     if ( qApp->type() == GuiServer ) {
01088         deforient = r;
01089         setenv( "QWS_DISPLAY", QString( "Transformed:Rot%1:0" ).arg( r ).latin1(), 1 );
01090         Config config("qpe");
01091         config.setGroup( "Rotation" );
01092         config.writeEntry( "Rot", r );
01093     }
01094     else {
01095 #ifndef QT_NO_COP
01096         { QCopEnvelope e( "QPE/System", "setDefaultRotation(int)" );
01097             e << r;
01098         }
01099 #endif
01100 
01101     }
01102 }
01103 
01104 #include <qgfx_qws.h>
01105 #include <qwindowsystem_qws.h>
01106 #include <qpixmapcache.h>
01107 
01108 extern void qws_clearLoadedFonts();
01109 
01110 void QPEApplication::setCurrentMode( int x, int y, int depth )
01111 {
01112     // Reset the caches
01113     qws_clearLoadedFonts();
01114     QPixmapCache::clear();
01115 
01116     // Change the screen mode
01117     qt_screen->setMode(x, y, depth);
01118 
01119     if ( qApp->type() == GuiServer ) {
01120         // Reconfigure the GuiServer
01121         qwsServer->beginDisplayReconfigure();
01122         qwsServer->endDisplayReconfigure();
01123 
01124         // Get all the running apps to reset
01125         QCopEnvelope env( "QPE/System", "reset()" );
01126     }
01127 }
01128 
01129 void QPEApplication::reset() {
01130     // Reconnect to the screen
01131     qt_screen->disconnect();
01132     qt_screen->connect( QString::null );
01133 
01134     // Redraw everything
01135     applyStyle();
01136 }
01137 
01141 void QPEApplication::applyStyle()
01142 {
01143     Config config( "qpe" );
01144     config.setGroup( "Appearance" );
01145 
01146 #if QT_VERSION > 233
01147 #if !defined(OPIE_NO_OVERRIDE_QT)
01148     // don't block ourselves ...
01149     Opie::force_appearance = 0;
01150 
01151     static QString appname = Opie::binaryName ( );
01152 
01153     QStringList ex = config. readListEntry ( "NoStyle", ';' );
01154     int nostyle = 0;
01155     for ( QStringList::Iterator it = ex. begin ( ); it != ex. end ( ); ++it ) {
01156         if ( QRegExp (( *it ). mid ( 1 ), false, true ). find ( appname, 0 ) >= 0 ) {
01157             nostyle = ( *it ). left ( 1 ). toInt ( 0, 32 );
01158             break;
01159         }
01160     }
01161 #else
01162         int nostyle = 0;
01163 #endif
01164 
01165     // Widget style
01166     QString style = config.readEntry( "Style", "FlatStyle" );
01167 
01168     // don't set a custom style
01169     if ( nostyle & Opie::Force_Style )
01170         style = "FlatStyle";
01171 
01172     internalSetStyle ( style );
01173 
01174     // Colors - from /etc/colors/Liquid.scheme
01175     QColor bgcolor( config.readEntry( "Background", "#E0E0E0" ) );
01176     QColor btncolor( config.readEntry( "Button", "#96c8fa" ) );
01177     QPalette pal( btncolor, bgcolor );
01178     QString color = config.readEntry( "Highlight", "#73adef" );
01179     pal.setColor( QColorGroup::Highlight, QColor( color ) );
01180     color = config.readEntry( "HighlightedText", "#FFFFFF" );
01181     pal.setColor( QColorGroup::HighlightedText, QColor( color ) );
01182     color = config.readEntry( "Text", "#000000" );
01183     pal.setColor( QColorGroup::Text, QColor( color ) );
01184     color = config.readEntry( "ButtonText", "#000000" );
01185     pal.setColor( QPalette::Active, QColorGroup::ButtonText, QColor( color ) );
01186     color = config.readEntry( "Base", "#FFFFFF" );
01187     pal.setColor( QColorGroup::Base, QColor( color ) );
01188 
01189     pal.setColor( QPalette::Disabled, QColorGroup::Text,
01190                   pal.color( QPalette::Active, QColorGroup::Background ).dark() );
01191 
01192     setPalette( pal, TRUE );
01193 
01194     // Window Decoration
01195     QString dec = config.readEntry( "Decoration", "Flat" );
01196 
01197     // don't set a custom deco
01198     if ( nostyle & Opie::Force_Decoration )
01199         dec = "";
01200 
01201     //qDebug ( "Setting Deco: %s -- old %s (%d)", dec.latin1(), d-> decorationName.latin1(), nostyle);
01202 
01203     if ( dec != d->decorationName ) {
01204         qwsSetDecoration( new QPEDecoration( dec ) );
01205         d->decorationName = dec;
01206     }
01207 
01208     // Font
01209     QString ff = config.readEntry( "FontFamily", font().family() );
01210     int fs = config.readNumEntry( "FontSize", font().pointSize() );
01211 
01212     // don't set a custom font
01213     if ( nostyle & Opie::Force_Font ) {
01214         ff = "Vera";
01215         fs = 10;
01216     }
01217 
01218     setFont ( QFont ( ff, fs ), true );
01219 
01220 #if !defined(OPIE_NO_OVERRIDE_QT)
01221     // revert to global blocking policy ...
01222     Opie::force_appearance = config. readBoolEntry ( "ForceStyle", false ) ? Opie::Force_All : Opie::Force_None;
01223     Opie::force_appearance &= ~nostyle;
01224 #endif
01225 #endif
01226 }
01227 
01228 void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data )
01229 {
01230 #ifdef Q_WS_QWS
01231     QDataStream stream( data, IO_ReadOnly );
01232     if ( msg == "applyStyle()" ) {
01233         applyStyle();
01234     }
01235     else if ( msg == "toggleApplicationMenu()" ) {
01236         QWidget *active = activeWindow ( );
01237 
01238         if ( active ) {
01239             QPEMenuToolFocusManager *man = QPEMenuToolFocusManager::manager ( );
01240             bool oldactive = man-> isActive ( );
01241 
01242             man-> setActive( !man-> isActive() );
01243 
01244             if ( !oldactive && !man-> isActive ( )) { // no menubar to toggle -> try O-Menu
01245                 QCopEnvelope e ( "QPE/TaskBar", "toggleStartMenu()" );
01246             }
01247         }
01248     }
01249     else if ( msg == "setDefaultRotation(int)" ) {
01250         if ( type() == GuiServer ) {
01251             int r;
01252             stream >> r;
01253             setDefaultRotation( r );
01254         }
01255     }
01256     else if ( msg == "setCurrentMode(int,int,int)" ) { // Added: 2003-06-11 by Tim Ansell <mithro@mithis.net>
01257             if ( type() == GuiServer ) {
01258         int x, y, depth;
01259         stream >> x;
01260         stream >> y;
01261         stream >> depth;
01262         setCurrentMode( x, y, depth );
01263             }
01264     }
01265     else if ( msg == "reset()" ) {
01266             if ( type() != GuiServer )
01267                 reset();
01268     }
01269     else if ( msg == "setCurrentRotation(int)" ) {
01270         int r;
01271         stream >> r;
01272         setCurrentRotation( r );
01273     }
01274     else if ( msg == "shutdown()" ) {
01275         if ( type() == GuiServer )
01276             shutdown();
01277     }
01278     else if ( msg == "quit()" ) {
01279         if ( type() != GuiServer )
01280             tryQuit();
01281     }
01282     else if ( msg == "forceQuit()" ) {
01283         if ( type() != GuiServer )
01284             quit();
01285     }
01286     else if ( msg == "restart()" ) {
01287         if ( type() == GuiServer )
01288             restart();
01289     }
01290     else if ( msg == "language(QString)" ) {
01291         if ( type() == GuiServer ) {
01292             QString l;
01293             stream >> l;
01294             QString cl = getenv( "LANG" );
01295             if ( cl != l ) {
01296                 if ( l.isNull() )
01297                     unsetenv( "LANG" );
01298                 else
01299                     setenv( "LANG", l.latin1(), 1 );
01300                 restart();
01301             }
01302         }
01303     }
01304     else if ( msg == "timeChange(QString)" ) {
01305         QString t;
01306         stream >> t;
01307         if ( t.isNull() )
01308             unsetenv( "TZ" );
01309         else
01310             setenv( "TZ", t.latin1(), 1 );
01311         // emit the signal so everyone else knows...
01312         emit timeChanged();
01313     }
01314     else if ( msg == "addAlarm(QDateTime,QCString,QCString,int)" ) {
01315         if ( type() == GuiServer ) {
01316             QDateTime when;
01317             QCString channel, message;
01318             int data;
01319             stream >> when >> channel >> message >> data;
01320             AlarmServer::addAlarm( when, channel, message, data );
01321         }
01322     }
01323     else if ( msg == "deleteAlarm(QDateTime,QCString,QCString,int)" ) {
01324         if ( type() == GuiServer ) {
01325             QDateTime when;
01326             QCString channel, message;
01327             int data;
01328             stream >> when >> channel >> message >> data;
01329             AlarmServer::deleteAlarm( when, channel, message, data );
01330         }
01331     }
01332     else if ( msg == "clockChange(bool)" ) {
01333         int tmp;
01334         stream >> tmp;
01335         emit clockChanged( tmp );
01336     }
01337     else if ( msg == "weekChange(bool)" ) {
01338         int tmp;
01339         stream >> tmp;
01340         emit weekChanged( tmp );
01341     }
01342     else if ( msg == "setDateFormat(DateFormat)" ) {
01343         DateFormat tmp;
01344         stream >> tmp;
01345         emit dateFormatChanged( tmp );
01346     }
01347     else if ( msg == "setVolume(int,int)" ) {
01348         int t, v;
01349         stream >> t >> v;
01350         setVolume( t, v );
01351         emit volumeChanged( muted );
01352     }
01353     else if ( msg == "volumeChange(bool)" ) {
01354         stream >> muted;
01355         setVolume();
01356         emit volumeChanged( muted );
01357     }
01358     else if ( msg == "setMic(int,int)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
01359         int t, v;
01360         stream >> t >> v;
01361         setMic( t, v );
01362         emit micChanged( micMuted );
01363     }
01364     else if ( msg == "micChange(bool)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
01365         stream >> micMuted;
01366         setMic();
01367         emit micChanged( micMuted );
01368     }
01369     else if ( msg == "setBass(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01370         int t, v;
01371         stream >> t >> v;
01372         setBass( t, v );
01373     }
01374     else if ( msg == "bassChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01375             setBass();
01376     }
01377         else if ( msg == "setTreble(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01378         int t, v;
01379         stream >> t >> v;
01380         setTreble( t, v );
01381     }
01382     else if ( msg == "trebleChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
01383             setTreble();
01384     } else if ( msg == "getMarkedText()" ) {
01385     if ( type() == GuiServer ) {
01386         const ushort unicode = 'C'-'@';
01387         const int scan = Key_C;
01388         qwsServer->processKeyEvent( unicode, scan, ControlButton, TRUE, FALSE );
01389         qwsServer->processKeyEvent( unicode, scan, ControlButton, FALSE, FALSE );
01390     }
01391     } else if ( msg == "newChannel(QString)") {
01392     QString myChannel = "QPE/Application/" + d->appName;
01393     QString channel;
01394     stream >> channel;
01395     if (channel == myChannel) {
01396         processQCopFile();
01397         d->sendQCopQ();
01398     }
01399     }
01400 
01401 
01402 #endif
01403 }
01404 
01405 
01406 
01407 
01408 
01412 bool QPEApplication::raiseAppropriateWindow()
01413 {
01414     bool r=FALSE;
01415 
01416     // 1. Raise the main widget
01417     QWidget *top = d->qpe_main_widget;
01418     if ( !top ) top = mainWidget();
01419 
01420     if ( top && d->keep_running ) {
01421     if ( top->isVisible() )
01422         r = TRUE;
01423     else if (d->preloaded) {
01424         // We are preloaded and not visible.. pretend we just started..
01425 #ifndef QT_NO_COP
01426         QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
01427         e << d->appName;
01428 #endif
01429     }
01430 
01431     d->show_mx(top,d->nomaximize, d->appName);
01432     top->raise();
01433     }
01434 
01435     QWidget *topm = activeModalWidget();
01436 
01437     // 2. Raise any parentless widgets (except top and topm, as they
01438     //     are raised before and after this loop).  Order from most
01439     //     recently raised as deepest to least recently as top, so
01440     //     that repeated calls cycle through widgets.
01441     QWidgetList *list = topLevelWidgets();
01442     if ( list ) {
01443     bool foundlast = FALSE;
01444     QWidget* topsub = 0;
01445     if ( d->lastraised ) {
01446         for (QWidget* w = list->first(); w; w = list->next()) {
01447         if ( !w->parentWidget() && w != topm && w->isVisible() && !w->isDesktop() ) {
01448             if ( w == d->lastraised )
01449             foundlast = TRUE;
01450             if ( foundlast ) {
01451             w->raise();
01452             topsub = w;
01453             }
01454         }
01455         }
01456     }
01457     for (QWidget* w = list->first(); w; w = list->next()) {
01458         if ( !w->parentWidget() && w != topm && w->isVisible() && !w->isDesktop() ) {
01459         if ( w == d->lastraised )
01460             break;
01461         w->raise();
01462         topsub = w;
01463         }
01464     }
01465     d->lastraised = topsub;
01466     delete list;
01467     }
01468 
01469     // 3. Raise the active modal widget.
01470     if ( topm && topm != top ) {
01471     topm->show();
01472     topm->raise();
01473     // If we haven't already handled the fastAppShowing message
01474     if (!top && d->preloaded) {
01475 #ifndef QT_NO_COP
01476         QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
01477         e << d->appName;
01478 #endif
01479     }
01480     r = FALSE;
01481     }
01482 
01483     return r;
01484 }
01485 
01486 
01487 void QPEApplication::pidMessage( const QCString& msg, const QByteArray& data)
01488 {
01489 #ifdef Q_WS_QWS
01490 
01491     if ( msg == "quit()" ) {
01492         tryQuit();
01493     }
01494     else if ( msg == "quitIfInvisible()" ) {
01495         if ( d->qpe_main_widget && !d->qpe_main_widget->isVisible() )
01496             quit();
01497     }
01498     else if ( msg == "close()" ) {
01499         hideOrQuit();
01500     }
01501     else if ( msg == "disablePreload()" ) {
01502         d->preloaded = FALSE;
01503         d->keep_running = TRUE;
01504         /* so that quit will quit */
01505     }
01506     else if ( msg == "enablePreload()" ) {
01507         if (d->qpe_main_widget)
01508             d->preloaded = TRUE;
01509         d->keep_running = TRUE;
01510         /* so next quit won't quit */
01511     }
01512     else if ( msg == "raise()" ) {
01513         d->keep_running = TRUE;
01514         d->notbusysent = FALSE;
01515         raiseAppropriateWindow();
01516         // Tell the system we're still chugging along...
01517         QCopEnvelope e("QPE/System", "appRaised(QString)");
01518         e << d->appName;
01519     }
01520     else if ( msg == "flush()" ) {
01521         emit flush();
01522         // we need to tell the desktop
01523         QCopEnvelope e( "QPE/Desktop", "flushDone(QString)" );
01524         e << d->appName;
01525     }
01526     else if ( msg == "reload()" ) {
01527         emit reload();
01528     }
01529     else if ( msg == "setDocument(QString)" ) {
01530         d->keep_running = TRUE;
01531         QDataStream stream( data, IO_ReadOnly );
01532         QString doc;
01533         stream >> doc;
01534         QWidget *mw = mainWidget();
01535         if ( !mw )
01536             mw = d->qpe_main_widget;
01537         if ( mw )
01538             Global::setDocument( mw, doc );
01539 
01540     } else if ( msg == "QPEProcessQCop()" ) {
01541             processQCopFile();
01542             d->sendQCopQ();
01543         }else
01544         {
01545             bool p = d->keep_running;
01546             d->keep_running = FALSE;
01547             emit appMessage( msg, data);
01548             if ( d->keep_running ) {
01549                 d->notbusysent = FALSE;
01550                 raiseAppropriateWindow();
01551                 if ( !p ) {
01552                     // Tell the system we're still chugging along...
01553 #ifndef QT_NO_COP
01554                     QCopEnvelope e("QPE/System", "appRaised(QString)");
01555                     e << d->appName;
01556 #endif
01557                 }
01558             }
01559             if ( p )
01560                 d->keep_running = p;
01561     }
01562 #endif
01563 }
01564 
01565 
01572 void QPEApplication::showMainWidget( QWidget* mw, bool nomaximize )
01573 {
01574         setMainWidget(mw);
01575             d->show(mw, nomaximize );
01576 }
01577 
01589 void QPEApplication::showMainDocumentWidget( QWidget* mw, bool nomaximize )
01590 {
01591     if ( mw && argc() == 2 )
01592         Global::setDocument( mw, QString::fromUtf8(argv()[1]) );
01593 
01594 
01595     setMainWidget(mw);
01596     d->show(mw, nomaximize );
01597 }
01598 
01599 
01610 void QPEApplication::setKeepRunning()
01611 {
01612     if ( qApp && qApp->inherits( "QPEApplication" ) ) {
01613         QPEApplication * qpeApp = ( QPEApplication* ) qApp;
01614         qpeApp->d->keep_running = TRUE;
01615     }
01616 }
01617 
01624 bool QPEApplication::keepRunning() const
01625 {
01626     return d->keep_running;
01627 }
01628 
01632 void QPEApplication::internalSetStyle( const QString &style )
01633 {
01634 #if QT_VERSION >= 300
01635     if ( style == "QPE" ) {
01636         setStyle( new QPEStyle );
01637     }
01638     else {
01639         QStyle *s = QStyleFactory::create( style );
01640         if ( s )
01641             setStyle( s );
01642     }
01643 #else
01644     if ( style == "Windows" ) {
01645         setStyle( new QWindowsStyle );
01646     }
01647     else if ( style == "QPE" ) {
01648         setStyle( new QPEStyle );
01649     }
01650     else if ( style == "Light" ) {
01651         setStyle( new LightStyle );
01652     }
01653 #ifndef QT_NO_STYLE_PLATINUM
01654     else if ( style == "Platinum" ) {
01655         setStyle( new QPlatinumStyle );
01656     }
01657 #endif
01658 #ifndef QT_NO_STYLE_MOTIF
01659     else if ( style == "Motif" ) {
01660         setStyle( new QMotifStyle );
01661     }
01662 #endif
01663 #ifndef QT_NO_STYLE_MOTIFPLUS
01664     else if ( style == "MotifPlus" ) {
01665         setStyle( new QMotifPlusStyle );
01666     }
01667 #endif
01668 
01669     else {
01670         QStyle *sty = 0;
01671         QString path = QPEApplication::qpeDir ( ) + "/plugins/styles/";
01672 
01673 #ifdef Q_OS_MACX
01674         if ( style. find ( ".dylib" ) > 0 )
01675             path += style;
01676         else
01677             path = path + "lib" + style. lower ( ) + ".dylib"; // compatibility
01678 #else
01679         if ( style. find ( ".so" ) > 0 )
01680             path += style;
01681         else
01682             path = path + "lib" + style. lower ( ) + ".so"; // compatibility
01683 #endif
01684         static QLibrary *lastlib = 0;
01685         static StyleInterface *lastiface = 0;
01686 
01687         QLibrary *lib = new QLibrary ( path );
01688         StyleInterface *iface = 0;
01689 
01690         if (( lib-> queryInterface ( IID_Style, ( QUnknownInterface ** ) &iface ) == QS_OK ) && iface )
01691             sty = iface-> style ( );
01692 
01693         if ( sty ) {
01694             setStyle ( sty );
01695 
01696             if ( lastiface )
01697                 lastiface-> release ( );
01698             lastiface = iface;
01699 
01700             if ( lastlib ) {
01701                 lastlib-> unload ( );
01702                 delete lastlib;
01703             }
01704             lastlib = lib;
01705         }
01706         else {
01707             if ( iface )
01708                 iface-> release ( );
01709             delete lib;
01710 
01711             setStyle ( new LightStyle ( ));
01712         }
01713     }
01714 #endif
01715 }
01716 
01720 void QPEApplication::prepareForTermination( bool willrestart )
01721 {
01722     if ( willrestart ) {
01723         // Draw a big wait icon, the image can be altered in later revisions
01724         //  QWidget *d = QApplication::desktop();
01725         QImage img = Resource::loadImage( "launcher/new_wait" );
01726         QPixmap pix;
01727         pix.convertFromImage( img.smoothScale( 1 * img.width(), 1 * img.height() ) );
01728         QLabel *lblWait = new QLabel( 0, "wait hack!", QWidget::WStyle_Customize |
01729                                       QWidget::WStyle_NoBorder | QWidget::WStyle_Tool );
01730         lblWait->setPixmap( pix );
01731         lblWait->setAlignment( QWidget::AlignCenter );
01732         lblWait->show();
01733         lblWait->showMaximized();
01734     }
01735 #ifndef SINGLE_APP
01736     { QCopEnvelope envelope( "QPE/System", "forceQuit()" );
01737     }
01738     processEvents(); // ensure the message goes out.
01739     sleep( 1 ); // You have 1 second to comply.
01740 #endif
01741 }
01742 
01746 void QPEApplication::shutdown()
01747 {
01748     // Implement in server's QPEApplication subclass
01749 }
01750 
01754 void QPEApplication::restart()
01755 {
01756     // Implement in server's QPEApplication subclass
01757 }
01758 
01759 static QPtrDict<void>* stylusDict = 0;
01760 static void createDict()
01761 {
01762     if ( !stylusDict )
01763         stylusDict = new QPtrDict<void>;
01764 }
01765 
01771 QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w )
01772 {
01773     if ( stylusDict )
01774         return ( StylusMode ) ( int ) stylusDict->find( w );
01775     return LeftOnly;
01776 }
01777 
01795 void QPEApplication::setStylusOperation( QWidget * w, StylusMode mode )
01796 {
01797     createDict();
01798     if ( mode == LeftOnly ) {
01799         stylusDict->remove
01800         ( w );
01801         w->removeEventFilter( qApp );
01802     }
01803     else {
01804         stylusDict->insert( w, ( void* ) mode );
01805         connect( w, SIGNAL( destroyed() ), qApp, SLOT( removeSenderFromStylusDict() ) );
01806         w->installEventFilter( qApp );
01807     }
01808 }
01809 
01810 
01814 bool QPEApplication::eventFilter( QObject *o, QEvent *e )
01815 {
01816         if ( !o->isWidgetType() )
01817             return FALSE;
01818 
01819     if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) {
01820         QMouseEvent * me = ( QMouseEvent* ) e;
01821         StylusMode mode = (StylusMode)(int)stylusDict->find(o);
01822         switch (mode) {
01823             case RightOnHold:
01824                 switch ( me->type() ) {
01825                     case QEvent::MouseButtonPress:
01826                         if ( me->button() == LeftButton ) {
01827                                                     if (!d->presstimer )
01828                                                         d->presstimer = startTimer(500); // #### pref.
01829                             d->presswidget = (QWidget*)o;
01830                             d->presspos = me->pos();
01831                             d->rightpressed = FALSE;
01832                         }
01833                         break;
01834                     case QEvent::MouseMove:
01835                         if (d->presstimer && (me->pos() - d->presspos).manhattanLength() > 8) {
01836                             killTimer(d->presstimer);
01837                             d->presstimer = 0;
01838                         }
01839                         break;
01840                     case QEvent::MouseButtonRelease:
01841                         if ( me->button() == LeftButton ) {
01842                             if ( d->presstimer ) {
01843                                 killTimer(d->presstimer);
01844                                 d->presstimer = 0;
01845                             }
01846                             if ( d->rightpressed && d->presswidget ) {
01847                                 // Right released
01848                                 postEvent( d->presswidget,
01849                                            new QMouseEvent( QEvent::MouseButtonRelease, me->pos(),
01850                                                             RightButton, LeftButton + RightButton ) );
01851                                 // Left released, off-widget
01852                                 postEvent( d->presswidget,
01853                                            new QMouseEvent( QEvent::MouseMove, QPoint( -1, -1),
01854                                                             LeftButton, LeftButton ) );
01855                                 postEvent( d->presswidget,
01856                                            new QMouseEvent( QEvent::MouseButtonRelease, QPoint( -1, -1),
01857                                                             LeftButton, LeftButton ) );
01858                                 d->rightpressed = FALSE;
01859                                 return TRUE; // don't send the real Left release
01860                             }
01861                         }
01862                         break;
01863                     default:
01864                         break;
01865                 }
01866                 break;
01867             default:
01868                 ;
01869         }
01870     }
01871     else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
01872         QKeyEvent *ke = (QKeyEvent *)e;
01873         if ( ke->key() == Key_Enter ) {
01874             if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) {
01875                 postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ',
01876                                              ke->state(), " ", ke->isAutoRepeat(), ke->count() ) );
01877                 return TRUE;
01878             }
01879         }
01880     }
01881     return FALSE;
01882 }
01883 
01887 void QPEApplication::timerEvent( QTimerEvent *e )
01888 {
01889     if ( e->timerId() == d->presstimer && d->presswidget ) {
01890         // Right pressed
01891         postEvent( d->presswidget,
01892                    new QMouseEvent( QEvent::MouseButtonPress, d->presspos,
01893                                     RightButton, LeftButton ) );
01894         killTimer( d->presstimer );
01895         d->presstimer = 0;
01896         d->rightpressed = TRUE;
01897     }
01898 }
01899 
01900 void QPEApplication::removeSenderFromStylusDict()
01901 {
01902     stylusDict->remove
01903     ( ( void* ) sender() );
01904     if ( d->presswidget == sender() )
01905         d->presswidget = 0;
01906 }
01907 
01911 bool QPEApplication::keyboardGrabbed() const
01912 {
01913     return d->kbgrabbed;
01914 }
01915 
01916 
01921 void QPEApplication::ungrabKeyboard()
01922 {
01923     ((QPEApplication *) qApp )-> d-> kbgrabbed = false;
01924 }
01925 
01935 void QPEApplication::grabKeyboard()
01936 {
01937     ((QPEApplication *) qApp )-> d-> kbgrabbed = true;
01938 }
01939 
01943 int QPEApplication::exec()
01944 {
01945         d->qcopQok = true;
01946 #ifndef QT_NO_COP
01947     d->sendQCopQ();
01948         if ( !d->keep_running )
01949             processEvents(); // we may have received QCop messages in the meantime.
01950 #endif
01951 
01952     if ( d->keep_running )
01953         //|| d->qpe_main_widget && d->qpe_main_widget->isVisible() )
01954         return QApplication::exec();
01955 
01956 #ifndef QT_NO_COP
01957 
01958     {
01959         QCopEnvelope e( "QPE/System", "closing(QString)" );
01960         e << d->appName;
01961     }
01962 #endif
01963     processEvents();
01964     return 0;
01965 }
01966 
01972 void QPEApplication::tryQuit()
01973 {
01974     if ( activeModalWidget() || strcmp( argv() [ 0 ], "embeddedkonsole" ) == 0 )
01975         return ; // Inside modal loop or konsole. Too hard to save state.
01976 #ifndef QT_NO_COP
01977 
01978     {
01979         QCopEnvelope e( "QPE/System", "closing(QString)" );
01980         e << d->appName;
01981     }
01982 #endif
01983     processEvents();
01984 
01985     quit();
01986 }
01987 
01991 void QPEApplication::installTranslation( const QString& baseName ) {
01992     QTranslator* trans = new QTranslator(this);
01993     QString tfn = qpeDir() + "/i18n/"+baseName;
01994     if ( trans->load( tfn ) )
01995         installTranslator( trans );
01996     else
01997         delete trans;
01998 }
01999 
02006 void QPEApplication::hideOrQuit()
02007 {
02008     processEvents();
02009 
02010     // If we are a preloaded application we don't actually quit, so emit
02011     // a System message indicating we're quasi-closing.
02012     if ( d->preloaded && d->qpe_main_widget )
02013 #ifndef QT_NO_COP
02014 
02015     {
02016         QCopEnvelope e("QPE/System", "fastAppHiding(QString)" );
02017         e << d->appName;
02018         d->qpe_main_widget->hide();
02019     }
02020 #endif
02021     else
02022         quit();
02023 }
02024 
02025 #if (__GNUC__ > 2 )
02026 extern "C" void __cxa_pure_virtual();
02027 
02028 void __cxa_pure_virtual()
02029 {
02030     fprintf( stderr, "Pure virtual called\n");
02031     abort();
02032 
02033 }
02034 
02035 #endif
02036 
02037 
02038 #if defined(OPIE_NEW_MALLOC)
02039 
02040 // The libraries with the skiff package (and possibly others) have
02041 // completely useless implementations of builtin new and delete that
02042 // use about 50% of your CPU. Here we revert to the simple libc
02043 // functions.
02044 
02045 void* operator new[]( size_t size )
02046 {
02047     return malloc( size );
02048 }
02049 
02050 void* operator new( size_t size )
02051 {
02052     return malloc( size );
02053 }
02054 
02055 void operator delete[]( void* p )
02056 {
02057     free( p );
02058 }
02059 
02060 void operator delete[]( void* p, size_t /*size*/ )
02061 {
02062     free( p );
02063 }
02064 
02065 
02066 void operator delete( void* p )
02067 {
02068     free( p );
02069 }
02070 
02071 void operator delete( void* p, size_t /*size*/ )
02072 {
02073     free( p );
02074 }
02075 
02076 #endif
02077 
02078 #if ( QT_VERSION <= 230 ) && !defined(SINGLE_APP)
02079 #include <qwidgetlist.h>
02080 #ifdef QWS
02081 #include <qgfx_qws.h>
02082 extern QRect qt_maxWindowRect;
02083 void qt_setMaxWindowRect(const QRect& r )
02084 {
02085     qt_maxWindowRect = qt_screen->mapFromDevice( r,
02086                        qt_screen->mapToDevice( QSize( qt_screen->width(), qt_screen->height() ) ) );
02087     // Re-resize any maximized windows
02088     QWidgetList* l = QApplication::topLevelWidgets();
02089     if ( l ) {
02090         QWidget * w = l->first();
02091         while ( w ) {
02092             if ( w->isVisible() && w->isMaximized() ) {
02093                 w->showMaximized();
02094             }
02095             w = l->next();
02096         }
02097         delete l;
02098     }
02099 }
02100 #endif
02101 #endif
KDE Logo
This file is part of the documentation for OPIE Version 1.5.5.
Documentation copyright © 1997-2003 the KDE developers. 2003 OPIE developers
Generated on Tue Feb 10 20:24:07 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001