summaryrefslogtreecommitdiff
path: root/core/launcher/firstuse.cpp
authorzecke <zecke>2003-08-25 15:00:50 (UTC)
committer zecke <zecke>2003-08-25 15:00:50 (UTC)
commitbf3c4abb9dff716e098f05852d9a3d8ac8cbcb44 (patch) (side-by-side diff)
treef74d4765868000d27c45771573032515ac8db8be /core/launcher/firstuse.cpp
parent292b097e7db25dd231381c5b09307a1fbe81a492 (diff)
downloadopie-bf3c4abb9dff716e098f05852d9a3d8ac8cbcb44.zip
opie-bf3c4abb9dff716e098f05852d9a3d8ac8cbcb44.tar.gz
opie-bf3c4abb9dff716e098f05852d9a3d8ac8cbcb44.tar.bz2
Initial revision
Diffstat (limited to 'core/launcher/firstuse.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/firstuse.cpp517
1 files changed, 517 insertions, 0 deletions
diff --git a/core/launcher/firstuse.cpp b/core/launcher/firstuse.cpp
new file mode 100644
index 0000000..31b7923
--- a/dev/null
+++ b/core/launcher/firstuse.cpp
@@ -0,0 +1,517 @@
+/**********************************************************************
+** 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.
+**
+**********************************************************************/
+
+// I need access to some things you don't normally get access to.
+
+#ifndef _MSC_VER
+ //### revise to allow removal of translators under MSVC
+#define private public
+#define protected public
+#endif
+#include "firstuse.h"
+#include "inputmethods.h"
+#include "applauncher.h"
+#include "serverapp.h"
+#include <qtopia/custom.h>
+#if defined(QPE_NEED_CALIBRATION)
+#include "../settings/calibrate/calibrate.h"
+#endif
+#include "documentlist.h"
+
+#include <qtopia/resource.h>
+#include <qtopia/qcopenvelope_qws.h>
+#include <qtopia/qpeapplication.h>
+#include <qtopia/config.h>
+#include <qtopia/applnk.h>
+#include <qtopia/mimetype.h>
+#include <qtopia/fontmanager.h>
+
+#include <qapplication.h>
+#include <qfile.h>
+#include <qpainter.h>
+#include <qcstring.h>
+#include <qsimplerichtext.h>
+#include <qcolor.h>
+#include <qpushbutton.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qtimer.h>
+
+#if defined( Q_WS_QWS )
+#include <qwsdisplay_qws.h>
+#include <qgfx_qws.h>
+#endif
+
+#include <qwindowsystem_qws.h>
+
+#include <stdlib.h>
+#include <sys/types.h>
+#if defined(Q_OS_LINUX) || defined(_OS_LINUX_)
+#include <unistd.h>
+#endif
+
+
+struct {
+ bool enabled;
+ const char *app;
+ const char *start;
+ const char *stop;
+ const char *desc;
+}
+settingsTable [] =
+{
+ { FALSE, "language", "raise()", "accept()", // No tr
+ QT_TR_NOOP("Language") },
+#ifndef Q_OS_WIN32
+ { FALSE, "systemtime", "raise()", "accept()", // No tr
+ QT_TR_NOOP("Time and Date") },
+#endif
+ { FALSE, "addressbook", "editPersonalAndClose()", "accept()", // No tr
+ QT_TR_NOOP("Personal Information") },
+ { FALSE, 0, 0, 0, 0 }
+};
+
+
+FirstUse::FirstUse(QWidget* parent, const char * name, WFlags wf) :
+ QDialog( parent, name, TRUE, wf),
+ transApp(0), transLib(0), needCalibrate(FALSE), currApp(-1),
+ waitForExit(-1), waitingForLaunch(FALSE), needRestart(FALSE)
+{
+ ServerApplication::allowRestart = FALSE;
+ // we force our height beyound the maximum (which we set anyway)
+ QRect desk = qApp->desktop()->geometry();
+ setGeometry( 0, 0, desk.width(), desk.height() );
+
+ connect(qwsServer, SIGNAL(newChannel(const QString&)),
+ this, SLOT(newQcopChannel(const QString&)));
+
+ // Create a DocumentList so appLauncher has appLnkSet to search
+ docList = new DocumentList( 0, FALSE );
+ appLauncher = new AppLauncher( this );
+ connect( appLauncher, SIGNAL(terminated(int, const QString&)),
+ this, SLOT(terminated(int, const QString&)) );
+
+ // more hackery
+ // I will be run as either the main server or as part of the main server
+ QWSServer::setScreenSaverIntervals(0);
+ loadPixmaps();
+
+ //check if there is a language program
+#ifndef Q_OS_WIN32
+ QString exeSuffix;
+#else
+ QString exeSuffix(".exe");
+#endif
+
+ for ( int i = 0; settingsTable[i].app; i++ ) {
+ QString file = QPEApplication::qpeDir() + "bin/";
+ file += settingsTable[i].app;
+ file += exeSuffix;
+ if ( QFile::exists(file) )
+ settingsTable[i].enabled = TRUE;
+ }
+
+ setFocusPolicy(NoFocus);
+
+ taskBar = new QWidget(0, 0, WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop | WGroupLeader);
+
+ inputMethods = new InputMethods(taskBar);
+ connect(inputMethods, SIGNAL(inputToggled(bool)),
+ this, SLOT(calcMaxWindowRect()));
+
+ back = new QPushButton(tr("<< Back"), taskBar);
+ back->setFocusPolicy(NoFocus);
+ connect(back, SIGNAL(clicked()), this, SLOT(previousDialog()) );
+
+ next = new QPushButton(tr("Next >>"), taskBar);
+ next->setFocusPolicy(NoFocus);
+ connect(next, SIGNAL(clicked()), this, SLOT(nextDialog()) );
+
+ // need to set the geom to lower corner
+ QSize sz = inputMethods->sizeHint();
+ int buttonWidth = (width() - sz.width()) / 2;
+ int x = 0;
+
+ controlHeight = back->sizeHint().height();
+
+ inputMethods->setGeometry(0,0, sz.width(), controlHeight );
+ x += sz.width();
+
+ back->setGeometry(x, 0, buttonWidth, controlHeight);
+ x += buttonWidth;
+ next->setGeometry(x, 0, buttonWidth, controlHeight);
+
+ taskBar->setGeometry( 0, height() - controlHeight, desk.width(), controlHeight);
+ taskBar->hide();
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ qDebug("Setting up QCop to QPE/System");
+ QCopChannel* sysChannel = new QCopChannel( "QPE/System", this );
+ connect(sysChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(message(const QCString &, const QByteArray &)) );
+#endif
+ calcMaxWindowRect();
+#if defined(QPE_NEED_CALIBRATION)
+ if ( !QFile::exists("/etc/pointercal") ) {
+ needCalibrate = TRUE;
+ grabMouse();
+ }
+#endif
+ Config config("locale");
+ config.setGroup( "Language");
+ lang = config.readEntry( "Language", "en");
+
+ defaultFont = font();
+
+ //###language/font hack; should look it up somewhere
+#ifdef Q_WS_QWS
+ if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
+ QFont fn = FontManager::unicodeFont( FontManager::Proportional );
+ qApp->setFont( fn, TRUE );
+ }
+#endif
+}
+
+FirstUse::~FirstUse()
+{
+ delete appLauncher;
+ delete docList;
+ delete taskBar;
+ ServerApplication::allowRestart = TRUE;
+}
+
+void FirstUse::calcMaxWindowRect()
+{
+#ifdef Q_WS_QWS
+ QRect wr;
+ int displayWidth = qApp->desktop()->width();
+ QRect ir = inputMethods->inputRect();
+ if ( ir.isValid() ) {
+ wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 );
+ } else {
+ wr.setCoords( 0, 0, displayWidth-1,
+ qApp->desktop()->height() - controlHeight-1);
+ }
+
+#if QT_VERSION < 0x030000
+ QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr,
+ QSize(qt_screen->width(),qt_screen->height()))
+ );
+#else
+ QWSServer::setMaxWindowRect( wr );
+#endif
+#endif
+}
+
+/* cancel current dialog, and bring up next */
+void FirstUse::nextDialog()
+{
+ int prevApp = currApp;
+ do {
+ currApp++;
+ qDebug( "currApp = %d", currApp );
+ if ( settingsTable[currApp].app == 0 ) {
+ if ( prevApp >= 0 && appLauncher->isRunning(settingsTable[prevApp].app) ) {
+ // The last application is still running.
+ // Tell it to stop, and when its done we'll come back
+ // to nextDialog and exit.
+ qDebug( "Waiting for %s to exit", settingsTable[prevApp].app );
+ QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
+ settingsTable[prevApp].stop );
+ currApp = prevApp;
+ } else {
+ qDebug( "Done!" );
+ Config config( "qpe" );
+ config.setGroup( "Startup" );
+ config.writeEntry( "FirstUse", FALSE );
+ QPixmap pix = Resource::loadPixmap("bigwait");
+ QLabel *lblWait = new QLabel(0, "wait hack!", // No tr
+ QWidget::WStyle_Customize | QWidget::WDestructiveClose |
+ QWidget::WStyle_NoBorder | QWidget::WStyle_Tool |
+ QWidget::WStyle_StaysOnTop);
+ lblWait->setPixmap( pix );
+ lblWait->setAlignment( QWidget::AlignCenter );
+ lblWait->setGeometry( qApp->desktop()->geometry() );
+ lblWait->show();
+ qApp->processEvents();
+ QTimer::singleShot( 1000, lblWait, SLOT(close()) );
+ repaint();
+ close();
+ ServerApplication::allowRestart = TRUE;
+ }
+ return;
+ }
+ } while ( !settingsTable[currApp].enabled );
+
+ if ( prevApp >= 0 && appLauncher->isRunning(settingsTable[prevApp].app) ) {
+ qDebug( "Shutdown: %s", settingsTable[prevApp].app );
+ QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
+ settingsTable[prevApp].stop );
+ waitForExit = prevApp;
+ } else {
+ qDebug( "Startup: %s", settingsTable[currApp].app );
+ QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
+ settingsTable[currApp].start );
+ waitingForLaunch = TRUE;
+ }
+
+ updateButtons();
+}
+
+/* accept current dialog and bring up previous */
+void FirstUse::previousDialog()
+{
+ int prevApp = currApp;
+ do {
+ currApp--;
+ if ( currApp < 0 ) {
+ currApp = prevApp;
+ return;
+ }
+ } while ( !settingsTable[currApp].enabled );
+
+ if ( prevApp >= 0 ) {
+ qDebug( "Shutdown: %s", settingsTable[prevApp].app );
+ QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
+ settingsTable[prevApp].stop );
+/*
+ if (settingsTable[prevApp].app == QString("systemtime"))
+ QCopEnvelope e("QPE/Application/citytime", "close()");
+*/
+ waitForExit = prevApp;
+ } else {
+ qDebug( "Startup: %s", settingsTable[currApp].app );
+ QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
+ settingsTable[currApp].start );
+ waitingForLaunch = TRUE;
+ }
+
+ updateButtons();
+}
+
+void FirstUse::message(const QCString &msg, const QByteArray &data)
+{
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "timeChange(QString)" ) {
+ QString t;
+ stream >> t;
+ if ( t.isNull() )
+ unsetenv("TZ");
+ else
+ setenv( "TZ", t.latin1(), 1 );
+ }
+}
+
+void FirstUse::terminated( int, const QString &app )
+{
+ qDebug( "--- terminated: %s", app.latin1() );
+ if ( waitForExit != -1 && settingsTable[waitForExit].app == app ) {
+ qDebug( "Startup: %s", settingsTable[currApp].app );
+ if ( settingsTable[waitForExit].app == "language" ) { // No tr
+ Config config("locale");
+ config.setGroup( "Language");
+ QString l = config.readEntry( "Language", "en");
+ if ( l != lang ) {
+ reloadLanguages();
+ needRestart = TRUE;
+ lang = l;
+ }
+ }
+ QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
+ settingsTable[currApp].start );
+ waitingForLaunch = TRUE;
+ updateButtons();
+ repaint();
+ waitForExit = -1;
+ } else if ( settingsTable[currApp].app == app ) {
+ nextDialog();
+ } else {
+ back->setEnabled(TRUE);
+ next->setEnabled(TRUE);
+ }
+}
+
+void FirstUse::newQcopChannel(const QString& channelName)
+{
+ qDebug("channel %s added", channelName.data() );
+ QString prefix("QPE/Application/");
+ if (channelName.startsWith(prefix)) {
+ QString appName = channelName.mid(prefix.length());
+ if ( currApp >= 0 && appName == settingsTable[currApp].app ) {
+ qDebug( "Application: %s started", settingsTable[currApp].app );
+ waitingForLaunch = FALSE;
+ updateButtons();
+ repaint();
+ } else if (appName != "quicklauncher") {
+ back->setEnabled(FALSE);
+ next->setEnabled(FALSE);
+ }
+ }
+}
+
+void FirstUse::reloadLanguages()
+{
+ // read language from config file. Waiting on QCop takes too long.
+ Config config("locale");
+ config.setGroup( "Language");
+ QString l = config.readEntry( "Language", "en");
+ QString cl = getenv("LANG");
+ qWarning("language message - " + l);
+ // setting anyway...
+ if (l.isNull() )
+ unsetenv( "LANG" );
+ else {
+ qWarning("and its not null");
+ setenv( "LANG", l.latin1(), 1 );
+ }
+#ifndef QT_NO_TRANSLATION
+ // clear old translators
+#ifndef _MSC_VER
+ //### revise to allow removal of translators under MSVC
+ if(qApp->translators) {
+ qApp->translators->setAutoDelete(TRUE);
+ delete (qApp->translators);
+ qApp->translators = 0;
+ }
+#endif
+
+ // load translation tables
+ transApp = new QTranslator(qApp);
+ QString tfn = QPEApplication::qpeDir() + "i18n/"+l+"/qpe.qm";
+ qWarning("loading " + tfn);
+ if ( transApp->load(tfn) ) {
+ qWarning("installing translator");
+ qApp->installTranslator( transApp );
+ } else {
+ delete transApp;
+ transApp = 0;
+ }
+
+ transLib = new QTranslator(qApp);
+ tfn = QPEApplication::qpeDir() + "i18n/"+l+"/libqpe.qm";
+ qWarning("loading " + tfn);
+ if ( transLib->load(tfn) ) {
+ qWarning("installing translator library");
+ qApp->installTranslator( transLib );
+ } else {
+ delete transLib;
+ transLib = 0;
+ }
+ loadPixmaps();
+ //###language/font hack; should look it up somewhere
+#ifdef Q_WS_QWS
+ if ( l == "ja" || l == "zh_CN" || l == "zh_TW" || l == "ko" ) {
+ QFont fn = FontManager::unicodeFont( FontManager::Proportional );
+ qApp->setFont( fn, TRUE );
+ } else {
+ qApp->setFont( defaultFont, TRUE );
+ }
+#endif
+#endif
+}
+
+void FirstUse::paintEvent( QPaintEvent * )
+{
+ QPainter p( this );
+
+ p.drawPixmap(0,0, splash);
+
+ QFont f = p.font();
+ f.setPointSize(15);
+ f.setItalic(FALSE);
+ f.setBold(FALSE);
+ p.setFont(f);
+
+ if ( currApp < 0 ) {
+ drawText(p, tr( "Tap anywhere on the screen to continue." ));
+ } else if ( settingsTable[currApp].app ) {
+ if ( waitingForLaunch )
+ drawText(p, tr("Please wait, loading %1 settings.").arg(tr(settingsTable[currApp].desc)) );
+ } else {
+ drawText(p, tr("Please wait..."));
+ }
+}
+
+void FirstUse::loadPixmaps()
+{
+ /* create background, tr so can change image with language.
+ images will likely contain text. */
+ splash.convertFromImage( Resource::loadImage(tr("FirstUseBackground"))
+ .smoothScale( width(), height() ) );
+
+ setBackgroundPixmap(splash);
+}
+
+void FirstUse::drawText(QPainter &p, const QString &text)
+{
+ QString altered = "<CENTER>" + text + "</CENTER>";
+
+ QSimpleRichText rt(altered, p.font());
+ rt.setWidth(width() - 20);
+
+ int h = (height() * 3) / 10; // start at 30%
+ if (rt.height() < height() / 2)
+ h += ((height() / 2) - rt.height()) / 2;
+ rt.draw(&p, 10, h, QRegion(0,0, width()-20, height()), palette());
+}
+
+void FirstUse::updateButtons()
+{
+ if ( currApp >= 0 ) {
+ taskBar->show();
+ }
+
+ int i = currApp-1;
+ while ( i >= 0 && !settingsTable[i].enabled )
+ i--;
+ back->setText(tr("<< Back"));
+ back->setEnabled( i >= 0 && !waitingForLaunch );
+
+ i = currApp+1;
+ while ( settingsTable[i].app && !settingsTable[i].enabled )
+ i++;
+ if ( !settingsTable[i].app )
+ next->setText(tr("Finish"));
+ else
+ next->setText(tr("Next >>"));
+ next->setEnabled( !waitingForLaunch );
+}
+
+void FirstUse::keyPressEvent( QKeyEvent *e )
+{
+ // Allow cancelling at first dialog, in case display is broken.
+ if ( e->key() == Key_Escape && currApp < 0 )
+ QDialog::keyPressEvent(e);
+}
+
+void FirstUse::mouseReleaseEvent( QMouseEvent * )
+{
+ if ( currApp < 0 ) {
+#if defined(QPE_NEED_CALIBRATION)
+ if ( needCalibrate ) {
+ releaseMouse();
+ Calibrate *cal = new Calibrate;
+ cal->exec();
+ delete cal;
+ }
+#endif
+ nextDialog();
+ }
+}