-rw-r--r-- | library/qpeapplication.cpp | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp index 4bc08b3..619b4cb 100644 --- a/library/qpeapplication.cpp +++ b/library/qpeapplication.cpp @@ -1,722 +1,722 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** 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. ** ** $Id$ ** **********************************************************************/ #define QTOPIA_INTERNAL_LANGLIST #include <stdlib.h> #include <unistd.h> #include <linux/limits.h> // needed for some toolchains (PATH_MAX) #include <qfile.h> #ifdef Q_WS_QWS #ifndef QT_NO_COP #if QT_VERSION <= 231 #define private public #define sendLocally processEvent #include "qcopenvelope_qws.h" #undef private #else #include "qcopenvelope_qws.h" #endif #endif #include <qwindowsystem_qws.h> #endif #include <qtextstream.h> #include <qpalette.h> #include <qbuffer.h> #include <qptrdict.h> #include <qregexp.h> #include <qdir.h> #include <qlabel.h> #include <qdialog.h> #include <qdragobject.h> #include <qtextcodec.h> #include <qevent.h> #include <qtooltip.h> #include <qsignal.h> #include <qmainwindow.h> #include "qpeapplication.h" #include "qpestyle.h" #include "styleinterface.h" #if QT_VERSION >= 300 #include <qstylefactory.h> #else #include <qplatinumstyle.h> #include <qwindowsstyle.h> #include <qmotifstyle.h> #include <qmotifplusstyle.h> #include "lightstyle.h" #include <qpe/qlibrary.h> #endif #include "global.h" #include "resource.h" #if QT_VERSION <= 230 && defined(QT_NO_CODECS) #include "qutfcodec.h" #endif #include "config.h" #include "network.h" #ifdef QWS #include "fontmanager.h" #endif #include "alarmserver.h" #include "applnk.h" #include "qpemenubar.h" #include "textcodecinterface.h" #include "imagecodecinterface.h" #include <unistd.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sys/soundcard.h> #include "qt_override_p.h" class QPEApplicationData { public: QPEApplicationData ( ) : presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ), notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ), keep_running( true ), qpe_main_widget( 0 ) { qcopq.setAutoDelete( TRUE ); } int presstimer; QWidget* presswidget; QPoint presspos; bool rightpressed : 1; bool kbgrabbed : 1; bool notbusysent : 1; bool preloaded : 1; bool forceshow : 1; bool nomaximize : 1; bool keep_running : 1; QString appName; struct QCopRec { QCopRec( const QCString &ch, const QCString &msg, const QByteArray &d ) : channel( ch ), message( msg ), data( d ) { } QCString channel; QCString message; QByteArray data; }; QWidget* qpe_main_widget; QList<QCopRec> qcopq; void enqueueQCop( const QCString &ch, const QCString &msg, const QByteArray &data ) { qcopq.append( new QCopRec( ch, msg, data ) ); } void sendQCopQ() { QCopRec * r; #ifndef QT_NO_COP for ( QListIterator<QCopRec> it( qcopq ); ( r = it.current() ); ++it ) QCopChannel::sendLocally( r->channel, r->message, r->data ); #endif qcopq.clear(); } static void show_mx(QWidget* mw, bool nomaximize) { // ugly hack, remove that later after finding a sane solution // Addendum: Only Sharp currently has models with high resolution but (physically) small displays, - // so this is only useful if QT_QWS_SHARP is defined. E.g. SIMpad has 800x600 but has + // so this is only useful if QT_QWS_SIMPAD is NOT defined. E.g. SIMpad has 800x600 but has // a (physically) large enough display to use the small icons -#ifdef QT_QWS_SHARP +#ifndef QT_QWS_SIMPAD if ( QPEApplication::desktop() ->width() >= 600 && ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") ) ) { ( ( QMainWindow* ) mw )->setUsesBigPixmaps( true ); } #endif if ( mw->layout() && mw->inherits("QDialog") ) { QPEApplication::showDialog((QDialog*)mw, nomaximize); } else { #ifdef Q_WS_QWS if ( !nomaximize ) mw->showMaximized(); else #endif mw->show(); } } static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ ) { /* // This works but disable it for now until it is safe to apply // What is does is scan the .desktop files of all the apps for // the applnk that has the corresponding argv[0] as this program // then it uses the name stored in the .desktop file as the caption // for the main widget. This saves duplicating translations for // the app name in the program and in the .desktop files. AppLnkSet apps( appsPath ); QList<AppLnk> appsList = apps.children(); for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) { if ( (*it)->exec() == appName ) { mw->setCaption( (*it)->name() ); return TRUE; } } */ return FALSE; } void show(QWidget* mw, bool nomax) { setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" ); nomaximize = nomax; qpe_main_widget = mw; #ifndef QT_NO_COP sendQCopQ(); #endif if ( preloaded ) { if (forceshow) show_mx(mw, nomax); } else if ( keep_running ) { show_mx(mw, nomax); } } void loadTextCodecs() { QString path = QPEApplication::qpeDir() + "/plugins/textcodecs"; QDir dir( path, "lib*.so" ); QStringList list; if ( dir. exists ( )) list = dir.entryList(); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { TextCodecInterface *iface = 0; QLibrary *lib = new QLibrary( path + "/" + *it ); if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) { QValueList<int> mibs = iface->mibEnums(); for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) { (void)iface->createForMib(*i); // ### it exists now; need to remember if we can delete it } } else { lib->unload(); delete lib; } } } void loadImageCodecs() { QString path = QPEApplication::qpeDir() + "/plugins/imagecodecs"; QDir dir( path, "lib*.so" ); QStringList list; if ( dir. exists ( )) list = dir.entryList(); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { ImageCodecInterface *iface = 0; QLibrary *lib = new QLibrary( path + "/" + *it ); if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) { QStringList formats = iface->keys(); for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) { (void)iface->installIOHandler(*i); // ### it exists now; need to remember if we can delete it } } else { lib->unload(); delete lib; } } } QString styleName; QString decorationName; }; class ResourceMimeFactory : public QMimeSourceFactory { public: ResourceMimeFactory() { setFilePath( Global::helpPath() ); setExtensionType( "html", "text/html;charset=UTF-8" ); } const QMimeSource* data( const QString& abs_name ) const { const QMimeSource * r = QMimeSourceFactory::data( abs_name ); if ( !r ) { int sl = abs_name.length(); do { sl = abs_name.findRev( '/', sl - 1 ); QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name; int dot = name.findRev( '.' ); if ( dot >= 0 ) name = name.left( dot ); QImage img = Resource::loadImage( name ); if ( !img.isNull() ) r = new QImageDrag( img ); } while ( !r && sl > 0 ); } return r; } }; static int muted = 0; static int micMuted = 0; static void setVolume( int t = 0, int percent = -1 ) { switch ( t ) { case 0: { Config cfg( "qpe" ); cfg.setGroup( "Volume" ); if ( percent < 0 ) percent = cfg.readNumEntry( "VolumePercent", 50 ); int fd = 0; if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { int vol = muted ? 0 : percent; // set both channels to same volume vol |= vol << 8; ioctl( fd, MIXER_WRITE( 0 ), &vol ); ::close( fd ); } } break; } } static void setMic( int t = 0, int percent = -1 ) { switch ( t ) { case 0: { Config cfg( "qpe" ); cfg.setGroup( "Volume" ); if ( percent < 0 ) percent = cfg.readNumEntry( "Mic", 50 ); int fd = 0; int mic = micMuted ? 0 : percent; if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic ); ::close( fd ); } } break; } } static void setBass( int t = 0, int percent = -1 ) { switch ( t ) { case 0: { Config cfg( "qpe" ); cfg.setGroup( "Volume" ); if ( percent < 0 ) percent = cfg.readNumEntry( "BassPercent", 50 ); int fd = 0; int bass = percent; if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass ); ::close( fd ); } } break; } } static void setTreble( int t = 0, int percent = -1 ) { switch ( t ) { case 0: { Config cfg( "qpe" ); cfg.setGroup( "Volume" ); if ( percent < 0 ) percent = cfg.readNumEntry( "TreblePercent", 50 ); int fd = 0; int treble = percent; if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble ); ::close( fd ); } } break; } } /*! \class QPEApplication qpeapplication.h \brief The QPEApplication class implements various system services that are available to all Qtopia applications. Simply by using QPEApplication instead of QApplication, a standard Qt application becomes a Qtopia application. It automatically follows style changes, quits and raises, and in the case of \link docwidget.html document-oriented\endlink applications, changes the currently displayed document in response to the environment. To create a \link docwidget.html document-oriented\endlink application use showMainDocumentWidget(); to create a non-document-oriented application use showMainWidget(). The keepRunning() function indicates whether the application will continue running after it's processed the last \link qcop.html QCop\endlink message. This can be changed using setKeepRunning(). A variety of signals are emitted when certain events occur, for example, timeChanged(), clockChanged(), weekChanged(), dateFormatChanged() and volumeChanged(). If the application receives a \link qcop.html QCop\endlink message on the application's QPE/Application/\e{appname} channel, the appMessage() signal is emitted. There are also flush() and reload() signals, which are emitted when synching begins and ends respectively - upon these signals, the application should save and reload any data files that are involved in synching. Most of these signals will initially be received and unfiltered through the appMessage() signal. This class also provides a set of useful static functions. The qpeDir() and documentDir() functions return the respective paths. The grabKeyboard() and ungrabKeyboard() functions are used to control whether the application takes control of the device's physical buttons (e.g. application launch keys). The stylus' mode of operation is set with setStylusOperation() and retrieved with stylusOperation(). There are also setInputMethodHint() and inputMethodHint() functions. \ingroup qtopiaemb */ /*! \fn void QPEApplication::clientMoused() \internal */ /*! \fn void QPEApplication::timeChanged(); This signal is emitted when the time changes outside the normal passage of time, i.e. if the time is set backwards or forwards. */ /*! \fn void QPEApplication::clockChanged( bool ampm ); This signal is emitted when the user changes the clock's style. If \a ampm is TRUE, the user wants a 12-hour AM/PM clock, otherwise, they want a 24-hour clock. */ /*! \fn void QPEApplication::volumeChanged( bool muted ) This signal is emitted whenever the mute state is changed. If \a muted is TRUE, then sound output has been muted. */ /*! \fn void QPEApplication::weekChanged( bool startOnMonday ) This signal is emitted if the week start day is changed. If \a startOnMonday is TRUE then the first day of the week is Monday; if \a startOnMonday is FALSE then the first day of the week is Sunday. */ /*! \fn void QPEApplication::dateFormatChanged(DateFormat) This signal is emitted whenever the date format is changed. */ /*! \fn void QPEApplication::flush() ### */ /*! \fn void QPEApplication::reload() */ /*! \fn void QPEApplication::appMessage( const QCString& msg, const QByteArray& data ) This signal is emitted when a message is received on this application's QPE/Application/<i>appname</i> \link qcop.html QCop\endlink channel. The slot to which you connect this signal uses \a msg and \a data in the following way: \code void MyWidget::receive( const QCString& msg, const QByteArray& data ) { QDataStream stream( data, IO_ReadOnly ); if ( msg == "someMessage(int,int,int)" ) { int a,b,c; stream >> a >> b >> c; ... } else if ( msg == "otherMessage(QString)" ) { ... } } \endcode \sa qcop.html Note that messages received here may be processed by qpe application and emitted as signals, such as flush() and reload(). */ /*! Constructs a QPEApplication just as you would construct a QApplication, passing \a argc, \a argv, and \a t. For applications, \a t should be the default, GuiClient. Only the Qtopia server passes GuiServer. */ QPEApplication::QPEApplication( int & argc, char **argv, Type t ) : QApplication( argc, argv, t ) { d = new QPEApplicationData; d->loadTextCodecs(); d->loadImageCodecs(); int dw = desktop() ->width(); if ( dw < 200 ) { setFont( QFont( "vera", 8 ) ); AppLnk::setSmallIconSize( 10 ); AppLnk::setBigIconSize( 28 ); } -#ifdef QT_QWS_SHARP +#ifndef QT_QWS_SIMPAD else if ( dw > 600 ) { setFont( QFont( "vera", 16 ) ); AppLnk::setSmallIconSize( 24 ); AppLnk::setBigIconSize( 48 ); } #endif else if ( dw > 200 ) { setFont( QFont( "vera", 10 ) ); AppLnk::setSmallIconSize( 14 ); AppLnk::setBigIconSize( 32 ); } QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory ); connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) ); #if defined(Q_WS_QWS) && !defined(QT_NO_COP) QString qcopfn( "/tmp/qcop-msg-" ); qcopfn += QString( argv[ 0 ] ); // append command name QFile f( qcopfn ); if ( f.open( IO_ReadOnly ) ) { flock( f.handle(), LOCK_EX ); } sysChannel = new QCopChannel( "QPE/System", this ); connect( sysChannel, SIGNAL( received( const QCString &, const QByteArray & ) ), this, SLOT( systemMessage( const QCString &, const QByteArray & ) ) ); QCString channel = QCString( argv[ 0 ] ); channel.replace( QRegExp( ".*/" ), "" ); d->appName = channel; channel = "QPE/Application/" + channel; pidChannel = new QCopChannel( channel, this ); connect( pidChannel, SIGNAL( received( const QCString &, const QByteArray & ) ), this, SLOT( pidMessage( const QCString &, const QByteArray & ) ) ); if ( f.isOpen() ) { d->keep_running = FALSE; QDataStream ds( &f ); QCString channel, message; QByteArray data; while ( !ds.atEnd() ) { ds >> channel >> message >> data; d->enqueueQCop( channel, message, data ); } flock( f.handle(), LOCK_UN ); f.close(); f.remove(); } for ( int a = 0; a < argc; a++ ) { if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) { argv[ a ] = argv[ a + 1 ]; a++; d->preloaded = TRUE; argc -= 1; } else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) { argv[ a ] = argv[ a + 1 ]; a++; d->preloaded = TRUE; d->forceshow = TRUE; argc -= 1; } } /* overide stored arguments */ setArgs( argc, argv ); #endif // qwsSetDecoration( new QPEDecoration() ); #ifndef QT_NO_TRANSLATION QStringList langs = Global::languageList(); for ( QStringList::ConstIterator it = langs.begin(); it != langs.end(); ++it ) { QString lang = *it; installTranslation( lang + "/libopie.qm"); installTranslation( lang + "/libqpe.qm" ); installTranslation( lang + "/" + d->appName + ".qm" ); //###language/font hack; should look it up somewhere #ifdef QWS if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) { QFont fn = FontManager::unicodeFont( FontManager::Proportional ); setFont( fn ); } #endif } #endif applyStyle(); if ( type() == GuiServer ) { setVolume(); } installEventFilter( this ); QPEMenuToolFocusManager::initialize(); #ifdef QT_NO_QWS_CURSOR // if we have no cursor, probably don't want tooltips QToolTip::setEnabled( FALSE ); #endif } static QPtrDict<void>* inputMethodDict = 0; static void createInputMethodDict() { if ( !inputMethodDict ) inputMethodDict = new QPtrDict<void>; } /*! Returns the currently set hint to the system as to whether widget \a w has any use for text input methods. \sa setInputMethodHint() InputMethodHint */ QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w ) { if ( inputMethodDict && w ) return ( InputMethodHint ) ( int ) inputMethodDict->find( w ); return Normal; } /*! \enum QPEApplication::InputMethodHint \value Normal the application sometimes needs text input (the default). \value AlwaysOff the application never needs text input. \value AlwaysOn the application always needs text input. */ /*! Hints to the system that widget \a w has use for text input methods as specified by \a mode. \sa inputMethodHint() InputMethodHint */ void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode ) { createInputMethodDict(); if ( mode == Normal ) { inputMethodDict->remove ( w ); } else { inputMethodDict->insert( w, ( void* ) mode ); } } class HackDialog : public QDialog { public: void acceptIt() { accept(); } void rejectIt() { reject(); } }; void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key ) { // specialised actions for certain widgets. May want to // add more stuff here. if ( activePopupWidget() && activePopupWidget() ->inherits( "QListBox" ) && activePopupWidget() ->parentWidget() && activePopupWidget() ->parentWidget() ->inherits( "QComboBox" ) ) key = Qt::Key_Return; if ( activePopupWidget() && activePopupWidget() ->inherits( "QPopupMenu" ) ) key = Qt::Key_Return; #ifdef QWS ke->simpleData.keycode = key; #endif } |