-rw-r--r-- | library/alarmserver.cpp | 9 | ||||
-rw-r--r-- | library/applnk.cpp | 1 | ||||
-rw-r--r-- | library/tzselect.cpp | 1 |
3 files changed, 6 insertions, 5 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp index 48ab9c1..ba7b015 100644 --- a/library/alarmserver.cpp +++ b/library/alarmserver.cpp @@ -1,507 +1,506 @@ /********************************************************************** ** 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. ** **********************************************************************/ -#include <qdir.h> - +#include "alarmserver.h" +#include <qpe/global.h> #include <qpe/qpeapplication.h> - #include <qpe/qcopenvelope_qws.h> -#include "alarmserver.h" #include <qpe/timeconversion.h> +#include <qdir.h> + #include <sys/types.h> #include <sys/stat.h> - #include <stdlib.h> #include <unistd.h> #undef USE_ATD // not used anymore -- we run opie-alarm on suspend/resume struct timerEventItem { time_t UTCtime; QCString channel, message; int data; bool operator==( const timerEventItem &right ) const { return ( UTCtime == right.UTCtime && channel == right.channel && message == right.message && data == right.data ); } }; class TimerReceiverObject : public QObject { public: TimerReceiverObject() { } ~TimerReceiverObject() { } void resetTimer(); void setTimerEventItem(); void deleteTimer(); protected: void timerEvent( QTimerEvent *te ); #ifdef USE_ATD private: QString atfilename; #endif }; TimerReceiverObject *timerEventReceiver = NULL; QList<timerEventItem> timerEventList; timerEventItem *nearestTimerEvent = NULL; // set the timer to go off on the next event in the list void setNearestTimerEvent() { nearestTimerEvent = NULL; QListIterator<timerEventItem> it( timerEventList ); if ( *it ) nearestTimerEvent = *it; for ( ; *it; ++it ) if ( (*it)->UTCtime < nearestTimerEvent->UTCtime ) nearestTimerEvent = *it; if (nearestTimerEvent) timerEventReceiver->resetTimer(); else timerEventReceiver->deleteTimer(); } //store current state to file //Simple implementation. Should run on a timer. static void saveState() { QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); if ( timerEventList.isEmpty() ) { unlink( savefilename ); return ; } QFile savefile(savefilename + ".new"); if ( savefile.open(IO_WriteOnly) ) { QDataStream ds( &savefile ); //save QListIterator<timerEventItem> it( timerEventList ); for ( ; *it; ++it ) { ds << it.current()->UTCtime; ds << it.current()->channel; ds << it.current()->message; ds << it.current()->data; } savefile.close(); unlink( savefilename ); QDir d; d.rename(savefilename + ".new", savefilename); } } /*! Sets up the alarm server. Restoring to previous state (session management). */ void AlarmServer::initialize() { //read autosave file and put events in timerEventList QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); QFile savefile(savefilename); if ( savefile.open(IO_ReadOnly) ) { QDataStream ds( &savefile ); while ( !ds.atEnd() ) { timerEventItem *newTimerEventItem = new timerEventItem; ds >> newTimerEventItem->UTCtime; ds >> newTimerEventItem->channel; ds >> newTimerEventItem->message; ds >> newTimerEventItem->data; timerEventList.append( newTimerEventItem ); } savefile.close(); if (!timerEventReceiver) timerEventReceiver = new TimerReceiverObject; setNearestTimerEvent(); } } #ifdef USE_ATD static const char* atdir = "/var/spool/at/"; static bool triggerAtd( bool writeHWClock = FALSE ) { QFile trigger(QString(atdir) + "trigger"); if ( trigger.open(IO_WriteOnly | IO_Raw) ) { if ( trigger.writeBlock("\n", 2) != 2 ) { QMessageBox::critical( 0, QObject::tr( "Out of Space" ), QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) ); trigger.close(); QFile::remove ( trigger.name() ); return FALSE; } return TRUE; } return FALSE; } #else static bool writeResumeAt ( time_t wakeup ) { FILE *fp = ::fopen ( "/var/run/resumeat", "w" ); if ( fp ) { ::fprintf ( fp, "%d\n", (int) wakeup ); ::fclose ( fp ); } else qWarning ( "Failed to write wakeup time to /var/run/resumeat" ); return ( fp ); } #endif void TimerReceiverObject::deleteTimer() { #ifdef USE_ATD if ( !atfilename.isEmpty() ) { unlink( atfilename ); atfilename = QString::null; triggerAtd( FALSE ); } #else writeResumeAt ( 0 ); #endif } void TimerReceiverObject::resetTimer() { const int maxsecs = 2147000; QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); QDateTime now = QDateTime::currentDateTime(); if ( nearest < now ) nearest = now; int secs = TimeConversion::secsTo( now, nearest ); if ( secs > maxsecs ) { // too far for millisecond timing secs = maxsecs; } // System timer (needed so that we wake from deep sleep), // from the Epoch in seconds. // int at_secs = TimeConversion::toUTC(nearest); // qDebug("reset timer to %d seconds from Epoch",at_secs); #ifdef USE_ATD QString fn = atdir + QString::number(at_secs) + "." + QString::number(getpid()); if ( fn != atfilename ) { QFile atfile(fn + ".new"); if ( atfile.open(IO_WriteOnly | IO_Raw) ) { int total_written; // just wake up and delete the at file QString cmd = "#!/bin/sh\nrm " + fn; total_written = atfile.writeBlock(cmd.latin1(), cmd.length()); if ( total_written != int(cmd.length()) ) { QMessageBox::critical( 0, tr("Out of Space"), tr("Unable to schedule alarm.\n" "Please free up space and try again") ); atfile.close(); QFile::remove ( atfile.name() ); return ; } atfile.close(); unlink( atfilename ); QDir d; d.rename(fn + ".new", fn); chmod(fn.latin1(), 0755); atfilename = fn; triggerAtd( FALSE ); } else { qWarning("Cannot open atd file %s", fn.latin1()); } } #else writeResumeAt ( at_secs ); #endif // Qt timers (does the actual alarm) // from now in milliseconds // qDebug("AlarmServer waiting %d seconds", secs); startTimer( 1000 * secs + 500 ); } void TimerReceiverObject::timerEvent( QTimerEvent * ) { bool needSave = FALSE; killTimers(); if (nearestTimerEvent) { if ( nearestTimerEvent->UTCtime <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) { #ifndef QT_NO_COP QCopEnvelope e( nearestTimerEvent->channel, nearestTimerEvent->message ); e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) << nearestTimerEvent->data; #endif timerEventList.remove( nearestTimerEvent ); needSave = TRUE; } setNearestTimerEvent(); } else { resetTimer(); } if ( needSave ) saveState(); } /*! \class AlarmServer alarmserver.h \brief The AlarmServer class allows alarms to be scheduled and unscheduled. Applications can schedule alarms with addAlarm() and can unschedule alarms with deleteAlarm(). When the time for an alarm to go off is reached the specified \link qcop.html QCop\endlink message is sent on the specified channel (optionally with additional data). Scheduling an alarm using this class is important (rather just using a QTimer) since the machine may be asleep and needs to get woken up using the Linux kernel which implements this at the kernel level to minimize battery usage while asleep. A small example on how to use AlarmServer. First we need to connect a slot the AppMessage QCOP call. appMessage will be emitted if QPE/Application/appname gets called. \code TestApp::TestApp(QWidget *parent, const char* name, WFlags fl ) : QMainWindow(parent,name,fl){ connect(qApp,SIGNAL(appMessage(const QCString&,const QByteArray&)), this,SLOT(slotAppMessage(const QCString&,const QByteArray&))); } \endcode To add / delete an alarm, you can use the static method AlarmServer::addAlarm and AlarmServer::deleteAlarm. Note that an old (expired) alarm will automatically be deleted from the alarmserver list, but a change in timing will have the effect, that both alarms will be emitted. So if you change an Alarm be sure to delete the old one! @see addAlarm \code QDateTime oldDt = oldAlarmDateTime(); QPEApplication::execDialog(ourDlg); QDateTime newDt = ourDlg->dateTime(); if(newDt == oldDt ) return; @slash* code is missing for unsetting an alarm *@slash AlarmServer::deleteAlarm(oldDt,"QPE/Application/appname","checkAlarm(QDateTime,int)",0); AlarmServer::addAlarm( newDt,"QPE/AlarmServer/appname","checkAlarm(QDateTime,int)",0); \endcode Now once the Alarm is emitted you need to check the appMessage and then do what you want. \code void TestApp::slotAppMessage(const QCString& str, const QByteArray& ar ){ QDataStream stream(ar,IO_ReadOnly); if(str == "checkAlarm(QDateTime,int)" ){ QDateTime dt; int a; stream >> dt >> a; // fire up alarm } } \endcode \ingroup qtopiaemb \sa QCopEnvelope @see QPEApplication::appMessage(const QCString&,const QByteArray&) @see OPimMainWindow @see ODevice::alarmSound() @see Sound::soundAlarm() */ /*! Schedules an alarm to go off at (or soon after) time \a when. When the alarm goes off, the \link qcop.html QCop\endlink \a message will be sent to \a channel, with \a data as a parameter. If this function is called with exactly the same data as a previous call the subsequent call is ignored, so there is only ever one alarm with a given set of parameters. Once an alarm is emitted. The \a channel with a \a message will be emitted and data will be send. The QDateTime and int are the two parameters included in the QCOP message. You can specify channel, message and the integer parameter. QDateTime will be the datetime of the QCop call. @param when The QDateTime of the alarm @param channel The channel which gets called once the alarm is emitted @param message The message to be send to the channel @param data Additional data as integer @see QCopChannel \sa deleteAlarm() */ void AlarmServer::addAlarm ( QDateTime when, const QCString& channel, const QCString& message, int data) { if ( qApp->type() == QApplication::GuiServer ) { bool needSave = FALSE; // Here we are the server so either it has been directly called from // within the server or it has been sent to us from a client via QCop if (!timerEventReceiver) timerEventReceiver = new TimerReceiverObject; timerEventItem *newTimerEventItem = new timerEventItem; newTimerEventItem->UTCtime = TimeConversion::toUTC( when ); newTimerEventItem->channel = channel; newTimerEventItem->message = message; newTimerEventItem->data = data; // explore the case of already having the event in here... QListIterator<timerEventItem> it( timerEventList ); for ( ; *it; ++it ) if ( *(*it) == *newTimerEventItem ) return ; // if we made it here, it is okay to add the item... timerEventList.append( newTimerEventItem ); needSave = TRUE; // quicker than using setNearestTimerEvent() if ( nearestTimerEvent ) { if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) { nearestTimerEvent = newTimerEventItem; timerEventReceiver->killTimers(); timerEventReceiver->resetTimer(); } } else { nearestTimerEvent = newTimerEventItem; timerEventReceiver->resetTimer(); } if ( needSave ) saveState(); } else { #ifndef QT_NO_COP QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" ); e << when << channel << message << data; #endif } } /*! Deletes previously scheduled alarms which match \a when, \a channel, \a message, and \a data. Passing null values for \a when, \a channel, or for the \link qcop.html QCop\endlink \a message, acts as a wildcard meaning "any". Similarly, passing -1 for \a data indicates "any". If there is no matching alarm, nothing happens. \sa addAlarm() */ void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data) { if ( qApp->type() == QApplication::GuiServer) { bool needSave = FALSE; if ( timerEventReceiver != NULL ) { timerEventReceiver->killTimers(); // iterate over the list of events QListIterator<timerEventItem> it( timerEventList ); time_t deleteTime = TimeConversion::toUTC( when ); for ( ; *it; ++it ) { // if its a match, delete it if ( ( (*it)->UTCtime == deleteTime || when.isNull() ) && ( channel.isNull() || (*it)->channel == channel ) && ( message.isNull() || (*it)->message == message ) && ( data == -1 || (*it)->data == data ) ) { // if it's first, then we need to update the timer if ( (*it) == nearestTimerEvent ) { timerEventList.remove(*it); setNearestTimerEvent(); } else { timerEventList.remove(*it); } needSave = TRUE; } } if ( nearestTimerEvent ) timerEventReceiver->resetTimer(); } if ( needSave ) saveState(); } else { #ifndef QT_NO_COP QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" ); e << when << channel << message << data; #endif } } /*! The implementation depends on the mode of AlarmServer. If the AlarmServer uses atd the current system time will be written to the hardware clock. If the AlarmServer relies on opie-alarm the time will be written once the device gets suspended. opie-alarm is used by the Zaurus, iPAQs and SIMpad */ void Global::writeHWClock() { #ifdef USE_ATD if ( !triggerAtd( TRUE ) ) { // atd not running? set it ourselves system("/sbin/hwclock --systohc"); // ##### UTC? } #else // hwclock is written on suspend #endif } diff --git a/library/applnk.cpp b/library/applnk.cpp index e9d519e..1c1a227 100644 --- a/library/applnk.cpp +++ b/library/applnk.cpp @@ -1,541 +1,542 @@ /********************************************************************** ** 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. ** **********************************************************************/ #define QTOPIA_INTERNAL_MIMEEXT #define QTOPIA_INTERNAL_PRELOADACCESS #define QTOPIA_INTERNAL_APPLNKASSIGN #include "applnk.h" #include <qpe/qpeapplication.h> #include <qpe/categories.h> #include <qpe/categoryselect.h> +#include <qpe/global.h> #include <qpe/qcopenvelope_qws.h> #include <qpe/mimetype.h> #include <qpe/config.h> #include <qpe/storage.h> #include <qpe/resource.h> #include <qdir.h> #include <stdlib.h> int AppLnk::lastId = 5000; static int smallSize = 14; static int bigSize = 32; static QString safeFileName(const QString& n) { QString safename=n; safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); safename.replace(QRegExp("^[^A-Za-z]*"),""); if ( safename.isEmpty() ) safename = "_"; return safename; } static bool prepareDirectories(const QString& lf) { if ( !QFile::exists(lf) ) { // May need to create directories QFileInfo fi(lf); if ( system(("mkdir -p "+fi.dirPath(TRUE))) ) return FALSE; } return TRUE; } class AppLnkPrivate { public: /* the size of the Pixmap */ enum Size {Normal = 0, Big }; AppLnkPrivate() { /* we want one normal and one big item */ QPixmap pix; mPixmaps.insert(0, pix ); mPixmaps.insert(1, pix); } QStringList mCatList; // always correct QArray<int> mCat; // cached value; correct if not empty QMap<int, QPixmap> mPixmaps; void updateCatListFromArray() { Categories cat( 0 ); cat.load( categoryFileName() ); // we need to update the names for the mCat... to mCatList mCatList.clear(); for (uint i = 0; i < mCat.count(); i++ ) mCatList << cat.label("Document View", mCat[i] ); } void setCatArrayDirty() { mCat.resize(0); } void ensureCatArray() { if ( mCat.count() > 0 || mCatList.count()==0 ) return; Categories cat( 0 ); cat.load( categoryFileName() ); mCat.resize( mCatList.count() ); int i; QStringList::ConstIterator it; for ( i = 0, it = mCatList.begin(); it != mCatList.end(); ++it, i++ ) { bool number; int id = (*it).toInt( &number ); if ( !number ) { id = cat.id( "Document View", *it ); if ( id == 0 ) id = cat.addCategory( "Document View", *it ); } mCat[i] = id; } } }; /*! \class AppLnk applnk.h \brief The AppLnk class represents an application available on the system. Every Qtopia application \e app has a corresponding \e app.desktop file. When one of these files is read its data is stored as an AppLnk object. The AppLnk class introduces some Qtopia-specific concepts, and provides a variety of functions, as described in the following sections. \tableofcontents \target Types \section1 Types Every AppLnk object has a \e type. For applications, games and settings the type is \c Application; for documents the type is the document's MIME type. \target files-and-links \section1 Files and Links When you create an AppLnk (or more likely, a \link doclnk.html DocLnk\endlink), you don't deal directly with filenames in the filesystem. Instead you do this: \code DocLnk d; d.setType("text/plain"); d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal. \endcode At this point, the file() and linkFile() are unknown. Normally this is uninteresting, and the names become automatically known, and more importantly, becomes reserved, when you ask what they are: \code QString fn = d.file(); \endcode This invents a filename, and creates the file on disk (an empty reservation file) to prevent the name being used by another application. In some circumstances, you don't want to create the file if it doesn't already exist (e.g. in the Document tab, some of the \link doclnk.html DocLnk\endlink objects represented by icons are DocLnk's created just for that view - they don't have corresponding \c .desktop files. To avoid littering empty reservation files around, we check in a few places to see whether the file really needs to exist). \section1 Functionality AppLnk objects are created by calling the constructor with the name of a \e .desktop file. The object can be checked for validity using isValid(). The following functions are used to set or retrieve information about the application: \table \header \i Get Function \i Set Function \i Short Description \row \i \l name() \i \l setName() \i application's name \row \i \l pixmap() \i \e none \i application's icon \row \i \l bigPixmap() \i \e none \i application's large icon \row \i \e none \i setIcon() \i sets the icon's filename \row \i \l type() \i \l setType() \i see \link #Types Types\endlink above \row \i \l rotation() \i \e none \i 0, 90, 180 or 270 degrees \row \i \l comment() \i \l setComment() \i text for the Details dialog \row \i \l exec() \i \l setExec() \i executable's filename \row \i \l file() \i \e none \i document's filename \row \i \l linkFile() \i \l setLinkFile() \i \e .desktop filename \row \i \l mimeTypes() \i \e none \i the mime types the application can view or edit \row \i \l categories() \i \l setCategories() \i \e{see the function descriptions} \row \i \l fileKnown() \i \e none \i see \link #files-and-links Files and Links\endlink above \row \i \l linkFileKnown() \i \e none \i see \link #files-and-links Files and Links\endlink above \row \i \l property() \i \l setProperty() \i any AppLnk property can be retrieved or set (if writeable) using these \endtable To save an AppLnk to disk use writeLink(). To execute the application that the AppLnk object refers to, use execute(). AppLnk's can be deleted from disk using removeLinkFile(). To remove both the link and the application's executable use removeFiles(). Icon sizes can be globally changed (but only for AppLnk objects created after the calls) with setSmallIconSize() and setBigIconSize(). \ingroup qtopiaemb */ /*! Sets the size used for small icons to \a small pixels. Only affects AppLnk objects created after the call. \sa smallIconSize() setIcon() */ void AppLnk::setSmallIconSize(int small) { smallSize = small; } /*! Returns the size used for small icons. \sa setSmallIconSize() setIcon() */ int AppLnk::smallIconSize() { return smallSize; } /*! Sets the size used for large icons to \a big pixels. Only affects AppLnk objects created after the call. \sa bigIconSize() setIcon() */ void AppLnk::setBigIconSize(int big) { bigSize = big; } /*! Returns the size used for large icons. \sa setBigIconSize() setIcon() */ int AppLnk::bigIconSize() { return bigSize; } /*! \fn QString AppLnk::name() const Returns the Name property. This is the user-visible name for the document or application, not the filename. See \link #files-and-links Files and Links\endlink. \sa setName() */ /*! \fn QString AppLnk::exec() const Returns the Exec property. This is the name of the executable program associated with the AppLnk. \sa setExec() */ /*! \fn QString AppLnk::rotation() const Returns the Rotation property. The value is 0, 90, 180 or 270 degrees. */ /*! \fn QString AppLnk::comment() const Returns the Comment property. \sa setComment() */ /*! \fn QStringList AppLnk::mimeTypes() const Returns the MimeTypes property. This is the list of MIME types that the application can view or edit. */ /*! \fn const QArray<int>& AppLnk::categories() const Returns the Categories property. See the CategoryWidget for more details. \sa setCategories() */ const QArray<int>& AppLnk::categories() const { d->ensureCatArray(); return d->mCat; } /*! \fn int AppLnk::id() const Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet, this value is 0, otherwise it is a value that is unique for the duration of the current process. \sa AppLnkSet::find() */ /*! \fn bool AppLnk::isValid() const Returns TRUE if this AppLnk is valid; otherwise returns FALSE. */ /*! \fn bool AppLnk::fileKnown() const If the with the AppLnk associated file is not equal to QString::null */ /*! \fn bool AppLnk::linkFileKnown()const The filename of the AppLnk */ /*! \fn void AppLnk::setRotation( const QString& ) The default rotation of the associated application. This function is included inline for binary compatible issues */ /*! Creates an invalid AppLnk. \sa isValid() */ AppLnk::AppLnk() { mId = 0; d = new AppLnkPrivate(); } /*! Loads \a file (e.g. \e app.desktop) as an AppLnk. \sa writeLink() */ AppLnk::AppLnk( const QString &file ) { QStringList sl; d = new AppLnkPrivate(); if ( !file.isNull() ) { Config config( file, Config::File ); if ( config.isValid() ) { config.setGroup( "Desktop Entry" ); mName = config.readEntry( "Name", file ); mExec = config.readEntry( "Exec" ); mType = config.readEntry( "Type", QString::null ); mIconFile = config.readEntry( "Icon", QString::null ); mRotation = config.readEntry( "Rotation", "" ); mComment = config.readEntry( "Comment", QString::null ); // MIME types are case-insensitive. mMimeTypes = config.readListEntry( "MimeType", ';' ); for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it) *it = (*it).lower(); mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' ); mLinkFile = file; mFile = config.readEntry("File", QString::null); if ( !mExec. isEmpty ( )) { mFile = QString::null; } else if ( mFile[0] != '/' ) { int slash = file.findRev('/'); if ( slash >= 0 ) { mFile = file.left(slash) + '/' + mFile; } } d->mCatList = config.readListEntry("Categories", ';'); if ( d->mCatList[0].toInt() < -1 ) { // numeric cats in file! convert to text Categories cat( 0 ); cat.load( categoryFileName() ); d->mCat.resize( d->mCatList.count() ); int i; QStringList::ConstIterator it; for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end(); ++it, i++ ) { bool number; int id = (*it).toInt( &number ); if ( !number ) { // convert from text id = cat.id( "Document View", *it ); if ( id == 0 ) id = cat.addCategory( "Document View", *it ); } d->mCat[i] = id; } d->updateCatListFromArray(); } } } mId = 0; } AppLnk& AppLnk::operator=(const AppLnk ©) { if ( this == © ) return *this; if ( mId ) qWarning("Deleting AppLnk that is in an AppLnkSet"); if ( d ) delete d; mName = copy.mName; /* remove for Qtopia 3.0 -zecke */ mPixmap = copy.mPixmap; mBigPixmap = copy.mBigPixmap; mExec = copy.mExec; mType = copy.mType; mRotation = copy.mRotation; mComment = copy.mComment; mFile = copy.mFile; mLinkFile = copy.mLinkFile; mIconFile = copy.mIconFile; mMimeTypes = copy.mMimeTypes; mMimeTypeIcons = copy.mMimeTypeIcons; mId = 0; d = new AppLnkPrivate(); d->mCat = copy.d->mCat; d->mCatList = copy.d->mCatList; d->mPixmaps = copy.d->mPixmaps; return *this; } /*! protected internally to share code should I document that at all? I don't know the TT style for that */ const QPixmap& AppLnk::pixmap( int pos, int size ) const { if ( d->mPixmaps[pos].isNull() ) { AppLnk* that = (AppLnk*)this; if ( mIconFile.isEmpty() ) { MimeType mt(type()); that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap(); if ( that->d->mPixmaps[pos].isNull() ) that->d->mPixmaps[pos].convertFromImage( Resource::loadImage("UnknownDocument") .smoothScale( size, size ) ); return that->d->mPixmaps[pos]; } QImage unscaledIcon = Resource::loadImage( that->mIconFile ); if ( unscaledIcon.isNull() ) { // qDebug( "Cannot find icon: %s", that->mIconFile.latin1() ); that->d->mPixmaps[pos].convertFromImage( Resource::loadImage("UnknownDocument") .smoothScale( size, size ) ); } else { that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); } return that->d->mPixmaps[pos]; } return d->mPixmaps[pos]; } /*! Returns a small pixmap associated with the application. \sa bigPixmap() setIcon() */ const QPixmap& AppLnk::pixmap() const { if ( d->mPixmaps[0].isNull() ) { return pixmap(AppLnkPrivate::Normal, smallSize ); } return d->mPixmaps[0]; } /*! Returns a large pixmap associated with the application. \sa pixmap() setIcon() */ const QPixmap& AppLnk::bigPixmap() const { if ( d->mPixmaps[1].isNull() ) { return pixmap( AppLnkPrivate::Big, bigSize ); } return d->mPixmaps[1]; } /*! Returns the type of the AppLnk. For applications, games and settings the type is \c Application; for documents the type is the document's MIME type. */ QString AppLnk::type() const { if ( mType.isNull() ) { AppLnk* that = (AppLnk*)this; QString f = file(); if ( !f.isNull() ) { MimeType mt(f); that->mType = mt.id(); return that->mType; } } return mType; } /*! Returns the file associated with the AppLnk. \sa exec() name() */ QString AppLnk::file() const { if ( mExec.isEmpty ( ) && mFile.isNull() ) { AppLnk* that = (AppLnk*)this; QString ext = MimeType(mType).extension(); diff --git a/library/tzselect.cpp b/library/tzselect.cpp index 848dfb7..8dd427f 100644 --- a/library/tzselect.cpp +++ b/library/tzselect.cpp @@ -1,302 +1,303 @@ /********************************************************************** ** 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. ** **********************************************************************/ #define QTOPIA_INTERNAL_TZSELECT_INC_LOCAL #include "tzselect.h" #include "resource.h" #include "config.h" #include <qtoolbutton.h> #include <qfile.h> #include <stdlib.h> #include <qcopchannel_qws.h> +#include <qpe/global.h> #include <qpe/qpeapplication.h> #include <qmessagebox.h> /*! \class TimeZoneSelector \brief The TimeZoneSelector widget allows users to configure their time zone information. \ingroup qtopiaemb */ class TimeZoneSelectorPrivate { public: TimeZoneSelectorPrivate() : includeLocal(FALSE) {} bool includeLocal; }; TZCombo::TZCombo( QWidget *p, const char* n ) : QComboBox( p, n ) { updateZones(); // check to see if TZ is set, if it is set the current item to that QString tz = getenv("TZ"); if (parent()->inherits("TimeZoneSelector")) { if ( ((TimeZoneSelector *)parent())->localIncluded() ) { // overide to the 'local' type. tz = "None"; } } if ( !tz.isNull() ) { int n = 0, index = 0; for ( QStringList::Iterator it=identifiers.begin(); it!=identifiers.end(); ++it) { if ( *it == tz ) index = n; n++; } setCurrentItem(index); } else { setCurrentItem(0); } // listen on QPE/System #if !defined(QT_NO_COP) QCopChannel *channel = new QCopChannel( "QPE/System", this ); connect( channel, SIGNAL(received(const QCString&,const QByteArray&)), this, SLOT(handleSystemChannel(const QCString&,const QByteArray&)) ); #endif } TZCombo::~TZCombo() { } void TZCombo::updateZones() { QString cur = currentText(); clear(); identifiers.clear(); int curix=0; QString tz = getenv("TZ"); bool tzFound = FALSE; Config cfg("CityTime"); cfg.setGroup("TimeZones"); int listIndex = 0; if (parent()->inherits("TimeZoneSelector")) { if ( ((TimeZoneSelector *)parent())->localIncluded() ) { // overide to the 'local' type. identifiers.append( "None" ); insertItem( tr("None") ); if ( cur == tr("None")) curix = 0; listIndex++; } } int cfgIndex = 0; while (1) { QString zn = cfg.readEntry("Zone"+QString::number(cfgIndex), QString::null); if ( zn.isNull() ) break; if ( zn == tz ) tzFound = TRUE; QString nm = cfg.readEntry("ZoneName"+QString::number(cfgIndex)); identifiers.append(zn); insertItem(nm); if ( nm == cur ) curix = listIndex; ++cfgIndex; ++listIndex; } if ( !listIndex ) { QStringList list = timezoneDefaults(); for ( QStringList::Iterator it = list.begin(); it!=list.end(); ++it ) { QString zn = *it; QString nm = *++it; if ( zn == tz ) tzFound = TRUE; if ( nm == cur ) curix = listIndex; identifiers.append(zn); insertItem(nm); ++listIndex; } } for (QStringList::Iterator it=extras.begin(); it!=extras.end(); ++it) { insertItem(*it); identifiers.append(*it); if ( *it == cur ) curix = listIndex; ++listIndex; } if ( !tzFound && !tz.isEmpty()) { int i = tz.find( '/' ); QString nm = tz.mid( i+1 ).replace(QRegExp("_"), " "); identifiers.append(tz); insertItem(nm); if ( nm == cur ) curix = listIndex; ++listIndex; } setCurrentItem(curix); } void TZCombo::keyPressEvent( QKeyEvent *e ) { // ### should popup() in Qt 3.0 (it's virtual there) // updateZones(); QComboBox::keyPressEvent(e); } void TZCombo::mousePressEvent(QMouseEvent*e) { // ### should popup() in Qt 3.0 (it's virtual there) // updateZones(); QComboBox::mousePressEvent(e); } QString TZCombo::currZone() const { return identifiers[currentItem()]; } void TZCombo::setCurrZone( const QString& id ) { for (int i=0; i< count(); i++) { if ( identifiers[i] == id ) { setCurrentItem(i); return; } } insertItem(id); setCurrentItem( count() - 1); identifiers.append(id); extras.append(id); } void TZCombo::handleSystemChannel(const QCString&msg, const QByteArray&) { if ( msg == "timeZoneListChange()" ) { updateZones(); } } /*! Creates a new TimeZoneSelector with parent \a p and name \a n. The combobox will be populated with the available timezones. */ TimeZoneSelector::TimeZoneSelector(QWidget* p, const char* n) : QHBox(p,n) { d = new TimeZoneSelectorPrivate(); // build the combobox before we do any updates... cmbTz = new TZCombo( this, "timezone combo" ); cmdTz = new QToolButton( this, "timezone button" ); cmdTz->setIconSet( Resource::loadIconSet( "citytime_icon" ) ); cmdTz->setMaximumSize( cmdTz->sizeHint() ); // set up a connection to catch a newly selected item and throw our // signal QObject::connect( cmbTz, SIGNAL( activated(int) ), this, SLOT( slotTzActive(int) ) ); QObject::connect( cmdTz, SIGNAL( clicked() ), this, SLOT( slotExecute() ) ); } /*! Destroys a TimeZoneSelector. */ TimeZoneSelector::~TimeZoneSelector() { } void TimeZoneSelector::setLocalIncluded(bool b) { d->includeLocal = b; cmbTz->updateZones(); } bool TimeZoneSelector::localIncluded() const { return d->includeLocal; } /*! Returns the currently selected timezone as a string in location format, e.g. \code Australia/Brisbane \endcode */ QString TimeZoneSelector::currentZone() const { return cmbTz->currZone(); } /*! Sets the current timezone to \a id. */ void TimeZoneSelector::setCurrentZone( const QString& id ) { cmbTz->setCurrZone( id ); } /*! \fn void TimeZoneSelector::signalNewTz( const QString& id ) This signal is emitted when a timezone has been selected by the user. The id is a \l QString in location format, eg \code Australia/Brisbane \endcode */ void TimeZoneSelector::slotTzActive( int ) { emit signalNewTz( cmbTz->currZone() ); } void TimeZoneSelector::slotExecute( void ) { // execute the world time application... if (QFile::exists(QPEApplication::qpeDir()+"bin/citytime")) Global::execute( "citytime" ); else QMessageBox::warning(this,tr("citytime executable not found"), tr("In order to choose the time zones,\nplease install citytime.")); } QStringList timezoneDefaults( void ) { QStringList tzs; // load up the list just like the file format (citytime.cpp) tzs.append( "America/New_York" ); tzs.append( "New York" ); tzs.append( "America/Los_Angeles" ); tzs.append( "Los Angeles" ); tzs.append( "Australia/Brisbane" ); tzs.append( "Brisbane" ); tzs.append( "Europe/Berlin" ); tzs.append( "Berlin" ); tzs.append( "Asia/Tokyo" ); tzs.append( "Tokyo" ); tzs.append( "America/Denver" ); tzs.append( "Denver" ); return tzs; } |