Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

firstuse.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003               =.             (C) 2000-2002 Trolltech AS
00004             .=l.             (C) 2002-2005 The Opie Team <opie-devel@handhelds.org>
00005            .>+-=
00006  _;:,     .>    :=|.         This program is free software; you can
00007 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00008     :`=1 )Y*s>-.--   :       the terms of the GNU Library General Public
00009 .="- .-=="i,     .._         License as published by the Free Software
00010  - .   .-<_>     .<>         Foundation; version 2 of the License.
00011      ._= =}       :
00012     .%`+i>       _;_.
00013     .i_,=:_.      -<s.       This program is distributed in the hope that
00014      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00015     : ..    .:,     . . .    without even the implied warranty of
00016     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00017   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00018 ..}^=.=       =       ;      Library General Public License for more
00019 ++=   -.     .`     .:       details.
00020     :     =  ...= . :.=-
00021  -.   .:....=;==+<;          You should have received a copy of the GNU
00022   -_. . .   )=.  =           Library General Public License along with
00023     --        :-=`           this library; see the file COPYING.LIB.
00024                              If not, write to the Free Software Foundation,
00025                              Inc., 59 Temple Place - Suite 330,
00026                              Boston, MA 02111-1307, USA.
00027 */
00028 
00029 // I need access to some things you don't normally get access to.
00030 #ifndef _MSC_VER
00031   //### revise to allow removal of translators under MSVC
00032 #define private public
00033 #define protected public
00034 #endif
00035 #include "firstuse.h"
00036 #include "inputmethods.h"
00037 #include "applauncher.h"
00038 #include "serverapp.h"
00039 #include "calibrate.h"
00040 #include "documentlist.h"
00041 
00042 /* OPIE */
00043 #include <opie2/odebug.h>
00044 #include <opie2/oresource.h>
00045 #include <qtopia/qcopenvelope_qws.h>
00046 #include <qtopia/config.h>
00047 #include <qtopia/fontmanager.h>
00048 using namespace Opie::Core;
00049 
00050 /* QT */
00051 #include <qfile.h>
00052 #include <qpainter.h>
00053 #include <qsimplerichtext.h>
00054 #include <qpushbutton.h>
00055 #include <qlabel.h>
00056 #include <qtimer.h>
00057 
00058 #if defined( Q_WS_QWS )
00059 #include <qwsdisplay_qws.h>
00060 #include <qgfx_qws.h>
00061 #endif
00062 
00063 /* STD */
00064 #include <stdlib.h>
00065 #include <sys/types.h>
00066 #if defined(Q_OS_LINUX) || defined(_OS_LINUX_)
00067 #include <unistd.h>
00068 #endif
00069 
00070 
00071 struct settingsTable_t {
00072     bool enabled : 1;
00073     const char *app;
00074     const char *start;
00075     const char *stop;
00076     const char *desc;
00077 };
00078 
00079 static settingsTable_t settingsTable [] =
00080 {
00081     { FALSE, "language", "raise()", "accept()", // No tr
00082         QT_TR_NOOP("Language") },
00083     { FALSE, "doctab", "raise()", "accept()", // No tr
00084         QT_TR_NOOP("DocTab") },
00085 #ifndef Q_OS_WIN32
00086     { FALSE, "systemtime", "raise()", "accept()", // No tr
00087         QT_TR_NOOP("Time and Date") },
00088 #endif
00089     { FALSE, "addressbook", "editPersonalAndClose()", "accept()", // No tr
00090         QT_TR_NOOP("Personal Information") },
00091     { FALSE, 0, 0, 0, 0 }
00092 };
00093 
00094 
00095 FirstUse::FirstUse(QWidget* parent, const char * name, WFlags wf) :
00096     QDialog( parent, name, TRUE, wf),
00097     transApp(0), transLib(0), needCalibrate(FALSE), currApp(-1),
00098     waitForExit(-1), waitingForLaunch(FALSE), needRestart(FALSE)
00099 {
00100     ServerApplication::allowRestart = FALSE;
00101     // we force our height beyound the maximum (which we set anyway)
00102     QRect desk = qApp->desktop()->geometry();
00103     setGeometry( 0, 0, desk.width(), desk.height() );
00104 
00105     connect(qwsServer, SIGNAL(newChannel(const QString&)),
00106         this, SLOT(newQcopChannel(const QString&)));
00107 
00108     // Create a DocumentList so appLauncher has appLnkSet to search
00109     docList = new DocumentList( 0, FALSE );
00110     appLauncher = new AppLauncher( this );
00111     connect( appLauncher, SIGNAL(terminated(int,const QString&)),
00112             this, SLOT(terminated(int,const QString&)) );
00113 
00114     // more hackery
00115     // I will be run as either the main server or as part of the main server
00116     QWSServer::setScreenSaverIntervals(0);
00117     loadPixmaps();
00118 
00119     //check if there is a language program
00120 #ifndef Q_OS_WIN32
00121     QString exeSuffix;
00122 #else
00123     QString exeSuffix(".exe");
00124 #endif
00125 
00126     for ( int i = 0; settingsTable[i].app; i++ ) {
00127         QString file = QPEApplication::qpeDir() + "bin/";
00128         file += settingsTable[i].app;
00129         file += exeSuffix;
00130         if ( QFile::exists(file) )
00131             settingsTable[i].enabled = TRUE;
00132     }
00133 
00134     setFocusPolicy(NoFocus);
00135 
00136     taskBar = new QWidget(0, 0, WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop | WGroupLeader);
00137 
00138     inputMethods = new InputMethods(taskBar);
00139     connect(inputMethods, SIGNAL(inputToggled(bool)),
00140             this, SLOT(calcMaxWindowRect()));
00141 
00142     back = new QPushButton(tr("<< Back"), taskBar);
00143     back->setFocusPolicy(NoFocus);
00144     connect(back, SIGNAL(clicked()), this, SLOT(previousDialog()) );
00145 
00146     next = new QPushButton(tr("Next >>"), taskBar);
00147     next->setFocusPolicy(NoFocus);
00148     connect(next, SIGNAL(clicked()), this, SLOT(nextDialog()) );
00149 
00150     // need to set the geom to lower corner
00151     QSize sz = inputMethods->sizeHint();
00152     int buttonWidth = (width() - sz.width()) / 2;
00153     int x = 0;
00154 
00155     controlHeight = back->sizeHint().height();
00156 
00157     inputMethods->setGeometry(0,0, sz.width(), controlHeight );
00158     x += sz.width();
00159 
00160     back->setGeometry(x, 0, buttonWidth, controlHeight);
00161     x += buttonWidth;
00162     next->setGeometry(x, 0, buttonWidth, controlHeight);
00163 
00164     taskBar->setGeometry( 0, height() - controlHeight, desk.width(), controlHeight);
00165     taskBar->hide();
00166 
00167 #if defined(Q_WS_QWS) && !defined(QT_NO_COP)
00168     odebug << "Setting up QCop to QPE/System" << oendl;
00169     QCopChannel* sysChannel = new QCopChannel( "QPE/System", this );
00170     connect(sysChannel, SIGNAL(received(const QCString&,const QByteArray&)),
00171             this, SLOT(message(const QCString&,const QByteArray&)) );
00172 #endif
00173     calcMaxWindowRect();
00174 
00175     m_calHandler = ( QWSServer::mouseHandler() && QWSServer::mouseHandler()->inherits("QCalibratedMouseHandler") ) ? true : false;
00176 
00177     if ( m_calHandler) {
00178         if ( !QFile::exists("/etc/pointercal") ) {
00179             needCalibrate = TRUE;
00180             grabMouse();
00181         }
00182     }
00183 
00184     Config config("locale");
00185     config.setGroup( "Language");
00186     lang = config.readEntry( "Language", "en");
00187 
00188     defaultFont = font();
00189 
00190     //###language/font hack; should look it up somewhere
00191 #ifdef Q_WS_QWS
00192     if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
00193         QFont fn = FontManager::unicodeFont( FontManager::Proportional );
00194         qApp->setFont( fn, TRUE );
00195     }
00196 #endif
00197 }
00198 
00199 FirstUse::~FirstUse()
00200 {
00201     delete appLauncher;
00202     delete docList;
00203     delete taskBar;
00204     ServerApplication::allowRestart = TRUE;
00205 }
00206 
00207 void FirstUse::calcMaxWindowRect()
00208 {
00209 #ifdef Q_WS_QWS
00210     QRect wr;
00211     int displayWidth  = qApp->desktop()->width();
00212     QRect ir = inputMethods->inputRect();
00213     if ( ir.isValid() ) {
00214         wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 );
00215     } else {
00216         wr.setCoords( 0, 0, displayWidth-1,
00217                 qApp->desktop()->height() - controlHeight-1);
00218     }
00219 
00220 #if QT_VERSION < 0x030000
00221     QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr,
00222                 QSize(qt_screen->width(),qt_screen->height()))
00223                                );
00224 #else
00225     QWSServer::setMaxWindowRect( wr );
00226 #endif
00227 #endif
00228 }
00229 
00230 /* cancel current dialog, and bring up next */
00231 void FirstUse::nextDialog()
00232 {
00233     int prevApp = currApp;
00234     do {
00235         currApp++;
00236     odebug << "currApp = " << currApp << "" << oendl;
00237         if ( settingsTable[currApp].app == 0 ) {
00238             if ( prevApp >= 0 && appLauncher->isRunning(settingsTable[prevApp].app) ) {
00239                 // The last application is still running.
00240                 // Tell it to stop, and when its done we'll come back
00241                 // to nextDialog and exit.
00242         odebug << "Waiting for " << settingsTable[prevApp].app << " to exit" << oendl;
00243                 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
00244                         settingsTable[prevApp].stop );
00245                 currApp = prevApp;
00246             } else {
00247         odebug << "Done!" << oendl;
00248                 Config config( "qpe" );
00249                 config.setGroup( "Startup" );
00250                 config.writeEntry( "FirstUse", FALSE );
00251                 QLabel *lblWait = new QLabel("Please Wait...", 0, "wait hack!", // No tr
00252                         QWidget::WStyle_Customize | QWidget::WDestructiveClose |
00253                         QWidget::WStyle_NoBorder | QWidget::WStyle_Tool |
00254                         QWidget::WStyle_StaysOnTop);
00255                 lblWait->setAlignment( QWidget::AlignCenter );
00256                 lblWait->setGeometry( qApp->desktop()->geometry() );
00257                 lblWait->show();
00258                 qApp->processEvents();
00259                 QTimer::singleShot( 1000, lblWait, SLOT(close()) );
00260                 repaint();
00261                 close();
00262                 ServerApplication::allowRestart = TRUE;
00263             }
00264             return;
00265         }
00266     } while ( !settingsTable[currApp].enabled );
00267 
00268     if ( prevApp >= 0 && appLauncher->isRunning(settingsTable[prevApp].app) ) {
00269     odebug << "Shutdown: " << settingsTable[prevApp].app << "" << oendl;
00270         QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
00271                         settingsTable[prevApp].stop );
00272         waitForExit = prevApp;
00273     } else {
00274     odebug << "Startup: " << settingsTable[currApp].app << "" << oendl;
00275         QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
00276                 settingsTable[currApp].start );
00277         waitingForLaunch = TRUE;
00278     }
00279 
00280     updateButtons();
00281 }
00282 
00283 /* accept current dialog and bring up previous */
00284 void FirstUse::previousDialog()
00285 {
00286     int prevApp = currApp;
00287     do {
00288         currApp--;
00289         if ( currApp < 0 ) {
00290             currApp = prevApp;
00291             return;
00292         }
00293     } while ( !settingsTable[currApp].enabled );
00294 
00295     if ( prevApp >= 0 ) {
00296     odebug << "Shutdown: " << settingsTable[prevApp].app << "" << oendl;
00297         QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
00298                         settingsTable[prevApp].stop );
00299 /*
00300         if (settingsTable[prevApp].app == QString("systemtime"))
00301             QCopEnvelope e("QPE/Application/citytime", "close()");
00302 */
00303         waitForExit = prevApp;
00304     } else {
00305     odebug << "Startup: " << settingsTable[currApp].app << "" << oendl;
00306         QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
00307                 settingsTable[currApp].start );
00308         waitingForLaunch = TRUE;
00309     }
00310 
00311     updateButtons();
00312 }
00313 
00314 void FirstUse::message(const QCString &msg, const QByteArray &data)
00315 {
00316     QDataStream stream( data, IO_ReadOnly );
00317     if ( msg == "timeChange(QString)" ) {
00318         QString t;
00319         stream >> t;
00320         if ( t.isNull() )
00321             unsetenv("TZ");
00322         else
00323             setenv( "TZ", t.latin1(), 1 );
00324     }
00325 }
00326 
00327 void FirstUse::terminated( int, const QString &app )
00328 {
00329     odebug << "--- terminated: " << app << "" << oendl;
00330     if ( waitForExit != -1 && settingsTable[waitForExit].app == app ) {
00331     odebug << "Startup: " << settingsTable[currApp].app << "" << oendl;
00332         if ( settingsTable[waitForExit].app == "language" ) { // No tr
00333             Config config("locale");
00334             config.setGroup( "Language");
00335             QString l = config.readEntry( "Language", "en");
00336             if ( l != lang ) {
00337                 reloadLanguages();
00338                 needRestart = TRUE;
00339                 lang = l;
00340             }
00341         }
00342         QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
00343                 settingsTable[currApp].start );
00344         waitingForLaunch = TRUE;
00345         updateButtons();
00346         repaint();
00347         waitForExit = -1;
00348     } else if ( settingsTable[currApp].app == app ) {
00349         nextDialog();
00350     } else {
00351         back->setEnabled(TRUE);
00352         next->setEnabled(TRUE);
00353     }
00354 }
00355 
00356 void FirstUse::newQcopChannel(const QString& channelName)
00357 {
00358     odebug << "channel " << channelName.data() << " added" << oendl;
00359     QString prefix("QPE/Application/");
00360     if (channelName.startsWith(prefix)) {
00361         QString appName = channelName.mid(prefix.length());
00362         if ( currApp >= 0 && appName == settingsTable[currApp].app ) {
00363         odebug << "Application: " << settingsTable[currApp].app << " started" << oendl;
00364             waitingForLaunch = FALSE;
00365             updateButtons();
00366             repaint();
00367         } else if (appName != "quicklauncher") {
00368             back->setEnabled(FALSE);
00369             next->setEnabled(FALSE);
00370         }
00371     }
00372 }
00373 
00374 void FirstUse::reloadLanguages()
00375 {
00376     // read language from config file.  Waiting on QCop takes too long.
00377     Config config("locale");
00378     config.setGroup( "Language");
00379     QString l = config.readEntry( "Language", "en");
00380     QString cl = getenv("LANG");
00381     owarn << "language message - " + l << oendl;
00382     // setting anyway...
00383     if (l.isNull() )
00384         unsetenv( "LANG" );
00385     else {
00386     owarn << "and its not null" << oendl;
00387         setenv( "LANG", l.latin1(), 1 );
00388     }
00389 #ifndef QT_NO_TRANSLATION
00390     // clear old translators
00391 #ifndef _MSC_VER
00392   //### revise to allow removal of translators under MSVC
00393   if(qApp->translators) {
00394         qApp->translators->setAutoDelete(TRUE);
00395         delete (qApp->translators);
00396         qApp->translators = 0;
00397     }
00398 #endif
00399 
00400     // load translation tables
00401     transApp = new QTranslator(qApp);
00402     QString tfn = QPEApplication::qpeDir() + "i18n/"+l+"/qpe.qm";
00403     owarn << "loading " + tfn << oendl;
00404     if ( transApp->load(tfn) ) {
00405     owarn << "installing translator" << oendl;
00406         qApp->installTranslator( transApp );
00407     } else  {
00408         delete transApp;
00409         transApp = 0;
00410     }
00411 
00412     transLib = new QTranslator(qApp);
00413     tfn = QPEApplication::qpeDir() + "i18n/"+l+"/libqpe.qm";
00414     owarn << "loading " + tfn << oendl;
00415     if ( transLib->load(tfn) ) {
00416     owarn << "installing translator library" << oendl;
00417         qApp->installTranslator( transLib );
00418     } else  {
00419         delete transLib;
00420         transLib = 0;
00421     }
00422     loadPixmaps();
00423     //###language/font hack; should look it up somewhere
00424 #ifdef Q_WS_QWS
00425     if ( l == "ja" || l == "zh_CN" || l == "zh_TW" || l == "ko" ) {
00426         QFont fn = FontManager::unicodeFont( FontManager::Proportional );
00427         qApp->setFont( fn, TRUE );
00428     } else {
00429         qApp->setFont( defaultFont, TRUE );
00430     }
00431 #endif
00432 #endif
00433 }
00434 
00435 void FirstUse::paintEvent( QPaintEvent * )
00436 {
00437     QPainter p( this );
00438     p.drawPixmap(0,0, splash);
00439 
00440     if ( currApp < 0 ) {
00441         drawText(p, tr( "Tap anywhere on the screen to continue." ));
00442     } else if ( settingsTable[currApp].app ) {
00443         if ( waitingForLaunch )
00444             drawText(p, tr("Please wait, loading %1 settings.").arg(tr(settingsTable[currApp].desc)) );
00445     } else {
00446         drawText(p, tr("Please wait..."));
00447     }
00448 }
00449 
00450 void FirstUse::loadPixmaps()
00451 {
00452     splash.convertFromImage( OResource::loadImage("launcher/firstuse", OResource::NoScale )
00453                              .smoothScale( width(), height() ) );
00454 
00455     setBackgroundPixmap(splash);
00456 }
00457 
00458 void FirstUse::drawText(QPainter &p, const QString &text)
00459 {
00460     QString altered = "<CENTER>" + text + "</CENTER>";
00461 
00462     QSimpleRichText rt(altered, p.font());
00463     rt.setWidth(width() - 20);
00464 
00465     int h = (height() * 3) / 10; // start at 30%
00466     if (rt.height() < height() / 2)
00467         h += ((height() / 2) - rt.height()) / 2;
00468     rt.draw(&p, 10, h, QRegion(0,0, width()-20, height()), palette());
00469 }
00470 
00471 void FirstUse::updateButtons()
00472 {
00473     if ( currApp >= 0 ) {
00474         taskBar->show();
00475     }
00476 
00477     int i = currApp-1;
00478     while ( i >= 0 && !settingsTable[i].enabled )
00479         i--;
00480     back->setText(tr("<< Back"));
00481     back->setEnabled( i >= 0 && !waitingForLaunch );
00482 
00483     i = currApp+1;
00484     while ( settingsTable[i].app && !settingsTable[i].enabled )
00485         i++;
00486     if ( !settingsTable[i].app )
00487         next->setText(tr("Finish"));
00488     else
00489         next->setText(tr("Next >>"));
00490 
00491     next->setEnabled( !waitingForLaunch );
00492 }
00493 
00494 void FirstUse::keyPressEvent( QKeyEvent *e )
00495 {
00496     // Allow cancelling at first dialog, in case display is broken.
00497     if ( e->key() == Key_Escape && currApp < 0 )
00498         QDialog::keyPressEvent(e);
00499 }
00500 
00501 void FirstUse::mouseReleaseEvent( QMouseEvent * )
00502 {
00503     if ( currApp < 0 ) {
00504         if ( m_calHandler && needCalibrate ) {
00505             releaseMouse();
00506             Calibrate *cal = new Calibrate;
00507             cal->exec();
00508             delete cal;
00509         }
00510         nextDialog();
00511     }
00512 }

Generated on Sat Nov 5 16:15:30 2005 for OPIE by  doxygen 1.4.2