summaryrefslogtreecommitdiff
path: root/core/launcher/firstuse.cpp
Unidiff
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 @@
1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3**
4** This file is part of the Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21// I need access to some things you don't normally get access to.
22
23#ifndef _MSC_VER
24 //### revise to allow removal of translators under MSVC
25#define private public
26#define protected public
27#endif
28#include "firstuse.h"
29#include "inputmethods.h"
30#include "applauncher.h"
31#include "serverapp.h"
32#include <qtopia/custom.h>
33#if defined(QPE_NEED_CALIBRATION)
34#include "../settings/calibrate/calibrate.h"
35#endif
36#include "documentlist.h"
37
38#include <qtopia/resource.h>
39#include <qtopia/qcopenvelope_qws.h>
40#include <qtopia/qpeapplication.h>
41#include <qtopia/config.h>
42#include <qtopia/applnk.h>
43#include <qtopia/mimetype.h>
44#include <qtopia/fontmanager.h>
45
46#include <qapplication.h>
47#include <qfile.h>
48#include <qpainter.h>
49#include <qcstring.h>
50#include <qsimplerichtext.h>
51#include <qcolor.h>
52#include <qpushbutton.h>
53#include <qhbox.h>
54#include <qlabel.h>
55#include <qtimer.h>
56
57#if defined( Q_WS_QWS )
58#include <qwsdisplay_qws.h>
59#include <qgfx_qws.h>
60#endif
61
62#include <qwindowsystem_qws.h>
63
64#include <stdlib.h>
65#include <sys/types.h>
66#if defined(Q_OS_LINUX) || defined(_OS_LINUX_)
67#include <unistd.h>
68#endif
69
70
71struct {
72 bool enabled;
73 const char *app;
74 const char *start;
75 const char *stop;
76 const char *desc;
77}
78settingsTable [] =
79{
80 { FALSE, "language", "raise()", "accept()", // No tr
81 QT_TR_NOOP("Language") },
82#ifndef Q_OS_WIN32
83 { FALSE, "systemtime", "raise()", "accept()", // No tr
84 QT_TR_NOOP("Time and Date") },
85#endif
86 { FALSE, "addressbook", "editPersonalAndClose()", "accept()", // No tr
87 QT_TR_NOOP("Personal Information") },
88 { FALSE, 0, 0, 0, 0 }
89};
90
91
92FirstUse::FirstUse(QWidget* parent, const char * name, WFlags wf) :
93 QDialog( parent, name, TRUE, wf),
94 transApp(0), transLib(0), needCalibrate(FALSE), currApp(-1),
95 waitForExit(-1), waitingForLaunch(FALSE), needRestart(FALSE)
96{
97 ServerApplication::allowRestart = FALSE;
98 // we force our height beyound the maximum (which we set anyway)
99 QRect desk = qApp->desktop()->geometry();
100 setGeometry( 0, 0, desk.width(), desk.height() );
101
102 connect(qwsServer, SIGNAL(newChannel(const QString&)),
103 this, SLOT(newQcopChannel(const QString&)));
104
105 // Create a DocumentList so appLauncher has appLnkSet to search
106 docList = new DocumentList( 0, FALSE );
107 appLauncher = new AppLauncher( this );
108 connect( appLauncher, SIGNAL(terminated(int, const QString&)),
109 this, SLOT(terminated(int, const QString&)) );
110
111 // more hackery
112 // I will be run as either the main server or as part of the main server
113 QWSServer::setScreenSaverIntervals(0);
114 loadPixmaps();
115
116 //check if there is a language program
117#ifndef Q_OS_WIN32
118 QString exeSuffix;
119#else
120 QString exeSuffix(".exe");
121#endif
122
123 for ( int i = 0; settingsTable[i].app; i++ ) {
124 QString file = QPEApplication::qpeDir() + "bin/";
125 file += settingsTable[i].app;
126 file += exeSuffix;
127 if ( QFile::exists(file) )
128 settingsTable[i].enabled = TRUE;
129 }
130
131 setFocusPolicy(NoFocus);
132
133 taskBar = new QWidget(0, 0, WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop | WGroupLeader);
134
135 inputMethods = new InputMethods(taskBar);
136 connect(inputMethods, SIGNAL(inputToggled(bool)),
137 this, SLOT(calcMaxWindowRect()));
138
139 back = new QPushButton(tr("<< Back"), taskBar);
140 back->setFocusPolicy(NoFocus);
141 connect(back, SIGNAL(clicked()), this, SLOT(previousDialog()) );
142
143 next = new QPushButton(tr("Next >>"), taskBar);
144 next->setFocusPolicy(NoFocus);
145 connect(next, SIGNAL(clicked()), this, SLOT(nextDialog()) );
146
147 // need to set the geom to lower corner
148 QSize sz = inputMethods->sizeHint();
149 int buttonWidth = (width() - sz.width()) / 2;
150 int x = 0;
151
152 controlHeight = back->sizeHint().height();
153
154 inputMethods->setGeometry(0,0, sz.width(), controlHeight );
155 x += sz.width();
156
157 back->setGeometry(x, 0, buttonWidth, controlHeight);
158 x += buttonWidth;
159 next->setGeometry(x, 0, buttonWidth, controlHeight);
160
161 taskBar->setGeometry( 0, height() - controlHeight, desk.width(), controlHeight);
162 taskBar->hide();
163
164#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
165 qDebug("Setting up QCop to QPE/System");
166 QCopChannel* sysChannel = new QCopChannel( "QPE/System", this );
167 connect(sysChannel, SIGNAL(received(const QCString &, const QByteArray &)),
168 this, SLOT(message(const QCString &, const QByteArray &)) );
169#endif
170 calcMaxWindowRect();
171#if defined(QPE_NEED_CALIBRATION)
172 if ( !QFile::exists("/etc/pointercal") ) {
173 needCalibrate = TRUE;
174 grabMouse();
175 }
176#endif
177 Config config("locale");
178 config.setGroup( "Language");
179 lang = config.readEntry( "Language", "en");
180
181 defaultFont = font();
182
183 //###language/font hack; should look it up somewhere
184#ifdef Q_WS_QWS
185 if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
186 QFont fn = FontManager::unicodeFont( FontManager::Proportional );
187 qApp->setFont( fn, TRUE );
188 }
189#endif
190}
191
192FirstUse::~FirstUse()
193{
194 delete appLauncher;
195 delete docList;
196 delete taskBar;
197 ServerApplication::allowRestart = TRUE;
198}
199
200void FirstUse::calcMaxWindowRect()
201{
202#ifdef Q_WS_QWS
203 QRect wr;
204 int displayWidth = qApp->desktop()->width();
205 QRect ir = inputMethods->inputRect();
206 if ( ir.isValid() ) {
207 wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 );
208 } else {
209 wr.setCoords( 0, 0, displayWidth-1,
210 qApp->desktop()->height() - controlHeight-1);
211 }
212
213#if QT_VERSION < 0x030000
214 QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr,
215 QSize(qt_screen->width(),qt_screen->height()))
216 );
217#else
218 QWSServer::setMaxWindowRect( wr );
219#endif
220#endif
221}
222
223/* cancel current dialog, and bring up next */
224void FirstUse::nextDialog()
225{
226 int prevApp = currApp;
227 do {
228 currApp++;
229 qDebug( "currApp = %d", currApp );
230 if ( settingsTable[currApp].app == 0 ) {
231 if ( prevApp >= 0 && appLauncher->isRunning(settingsTable[prevApp].app) ) {
232 // The last application is still running.
233 // Tell it to stop, and when its done we'll come back
234 // to nextDialog and exit.
235 qDebug( "Waiting for %s to exit", settingsTable[prevApp].app );
236 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
237 settingsTable[prevApp].stop );
238 currApp = prevApp;
239 } else {
240 qDebug( "Done!" );
241 Config config( "qpe" );
242 config.setGroup( "Startup" );
243 config.writeEntry( "FirstUse", FALSE );
244 QPixmap pix = Resource::loadPixmap("bigwait");
245 QLabel *lblWait = new QLabel(0, "wait hack!", // No tr
246 QWidget::WStyle_Customize | QWidget::WDestructiveClose |
247 QWidget::WStyle_NoBorder | QWidget::WStyle_Tool |
248 QWidget::WStyle_StaysOnTop);
249 lblWait->setPixmap( pix );
250 lblWait->setAlignment( QWidget::AlignCenter );
251 lblWait->setGeometry( qApp->desktop()->geometry() );
252 lblWait->show();
253 qApp->processEvents();
254 QTimer::singleShot( 1000, lblWait, SLOT(close()) );
255 repaint();
256 close();
257 ServerApplication::allowRestart = TRUE;
258 }
259 return;
260 }
261 } while ( !settingsTable[currApp].enabled );
262
263 if ( prevApp >= 0 && appLauncher->isRunning(settingsTable[prevApp].app) ) {
264 qDebug( "Shutdown: %s", settingsTable[prevApp].app );
265 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
266 settingsTable[prevApp].stop );
267 waitForExit = prevApp;
268 } else {
269 qDebug( "Startup: %s", settingsTable[currApp].app );
270 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
271 settingsTable[currApp].start );
272 waitingForLaunch = TRUE;
273 }
274
275 updateButtons();
276}
277
278/* accept current dialog and bring up previous */
279void FirstUse::previousDialog()
280{
281 int prevApp = currApp;
282 do {
283 currApp--;
284 if ( currApp < 0 ) {
285 currApp = prevApp;
286 return;
287 }
288 } while ( !settingsTable[currApp].enabled );
289
290 if ( prevApp >= 0 ) {
291 qDebug( "Shutdown: %s", settingsTable[prevApp].app );
292 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[prevApp].app,
293 settingsTable[prevApp].stop );
294/*
295 if (settingsTable[prevApp].app == QString("systemtime"))
296 QCopEnvelope e("QPE/Application/citytime", "close()");
297*/
298 waitForExit = prevApp;
299 } else {
300 qDebug( "Startup: %s", settingsTable[currApp].app );
301 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
302 settingsTable[currApp].start );
303 waitingForLaunch = TRUE;
304 }
305
306 updateButtons();
307}
308
309void FirstUse::message(const QCString &msg, const QByteArray &data)
310{
311 QDataStream stream( data, IO_ReadOnly );
312 if ( msg == "timeChange(QString)" ) {
313 QString t;
314 stream >> t;
315 if ( t.isNull() )
316 unsetenv("TZ");
317 else
318 setenv( "TZ", t.latin1(), 1 );
319 }
320}
321
322void FirstUse::terminated( int, const QString &app )
323{
324 qDebug( "--- terminated: %s", app.latin1() );
325 if ( waitForExit != -1 && settingsTable[waitForExit].app == app ) {
326 qDebug( "Startup: %s", settingsTable[currApp].app );
327 if ( settingsTable[waitForExit].app == "language" ) { // No tr
328 Config config("locale");
329 config.setGroup( "Language");
330 QString l = config.readEntry( "Language", "en");
331 if ( l != lang ) {
332 reloadLanguages();
333 needRestart = TRUE;
334 lang = l;
335 }
336 }
337 QCopEnvelope e(QCString("QPE/Application/") + settingsTable[currApp].app,
338 settingsTable[currApp].start );
339 waitingForLaunch = TRUE;
340 updateButtons();
341 repaint();
342 waitForExit = -1;
343 } else if ( settingsTable[currApp].app == app ) {
344 nextDialog();
345 } else {
346 back->setEnabled(TRUE);
347 next->setEnabled(TRUE);
348 }
349}
350
351void FirstUse::newQcopChannel(const QString& channelName)
352{
353 qDebug("channel %s added", channelName.data() );
354 QString prefix("QPE/Application/");
355 if (channelName.startsWith(prefix)) {
356 QString appName = channelName.mid(prefix.length());
357 if ( currApp >= 0 && appName == settingsTable[currApp].app ) {
358 qDebug( "Application: %s started", settingsTable[currApp].app );
359 waitingForLaunch = FALSE;
360 updateButtons();
361 repaint();
362 } else if (appName != "quicklauncher") {
363 back->setEnabled(FALSE);
364 next->setEnabled(FALSE);
365 }
366 }
367}
368
369void FirstUse::reloadLanguages()
370{
371 // read language from config file. Waiting on QCop takes too long.
372 Config config("locale");
373 config.setGroup( "Language");
374 QString l = config.readEntry( "Language", "en");
375 QString cl = getenv("LANG");
376 qWarning("language message - " + l);
377 // setting anyway...
378 if (l.isNull() )
379 unsetenv( "LANG" );
380 else {
381 qWarning("and its not null");
382 setenv( "LANG", l.latin1(), 1 );
383 }
384#ifndef QT_NO_TRANSLATION
385 // clear old translators
386#ifndef _MSC_VER
387 //### revise to allow removal of translators under MSVC
388 if(qApp->translators) {
389 qApp->translators->setAutoDelete(TRUE);
390 delete (qApp->translators);
391 qApp->translators = 0;
392 }
393#endif
394
395 // load translation tables
396 transApp = new QTranslator(qApp);
397 QString tfn = QPEApplication::qpeDir() + "i18n/"+l+"/qpe.qm";
398 qWarning("loading " + tfn);
399 if ( transApp->load(tfn) ) {
400 qWarning("installing translator");
401 qApp->installTranslator( transApp );
402 } else {
403 delete transApp;
404 transApp = 0;
405 }
406
407 transLib = new QTranslator(qApp);
408 tfn = QPEApplication::qpeDir() + "i18n/"+l+"/libqpe.qm";
409 qWarning("loading " + tfn);
410 if ( transLib->load(tfn) ) {
411 qWarning("installing translator library");
412 qApp->installTranslator( transLib );
413 } else {
414 delete transLib;
415 transLib = 0;
416 }
417 loadPixmaps();
418 //###language/font hack; should look it up somewhere
419#ifdef Q_WS_QWS
420 if ( l == "ja" || l == "zh_CN" || l == "zh_TW" || l == "ko" ) {
421 QFont fn = FontManager::unicodeFont( FontManager::Proportional );
422 qApp->setFont( fn, TRUE );
423 } else {
424 qApp->setFont( defaultFont, TRUE );
425 }
426#endif
427#endif
428}
429
430void FirstUse::paintEvent( QPaintEvent * )
431{
432 QPainter p( this );
433
434 p.drawPixmap(0,0, splash);
435
436 QFont f = p.font();
437 f.setPointSize(15);
438 f.setItalic(FALSE);
439 f.setBold(FALSE);
440 p.setFont(f);
441
442 if ( currApp < 0 ) {
443 drawText(p, tr( "Tap anywhere on the screen to continue." ));
444 } else if ( settingsTable[currApp].app ) {
445 if ( waitingForLaunch )
446 drawText(p, tr("Please wait, loading %1 settings.").arg(tr(settingsTable[currApp].desc)) );
447 } else {
448 drawText(p, tr("Please wait..."));
449 }
450}
451
452void FirstUse::loadPixmaps()
453{
454 /* create background, tr so can change image with language.
455 images will likely contain text. */
456 splash.convertFromImage( Resource::loadImage(tr("FirstUseBackground"))
457 .smoothScale( width(), height() ) );
458
459 setBackgroundPixmap(splash);
460}
461
462void FirstUse::drawText(QPainter &p, const QString &text)
463{
464 QString altered = "<CENTER>" + text + "</CENTER>";
465
466 QSimpleRichText rt(altered, p.font());
467 rt.setWidth(width() - 20);
468
469 int h = (height() * 3) / 10; // start at 30%
470 if (rt.height() < height() / 2)
471 h += ((height() / 2) - rt.height()) / 2;
472 rt.draw(&p, 10, h, QRegion(0,0, width()-20, height()), palette());
473}
474
475void FirstUse::updateButtons()
476{
477 if ( currApp >= 0 ) {
478 taskBar->show();
479 }
480
481 int i = currApp-1;
482 while ( i >= 0 && !settingsTable[i].enabled )
483 i--;
484 back->setText(tr("<< Back"));
485 back->setEnabled( i >= 0 && !waitingForLaunch );
486
487 i = currApp+1;
488 while ( settingsTable[i].app && !settingsTable[i].enabled )
489 i++;
490 if ( !settingsTable[i].app )
491 next->setText(tr("Finish"));
492 else
493 next->setText(tr("Next >>"));
494 next->setEnabled( !waitingForLaunch );
495}
496
497void FirstUse::keyPressEvent( QKeyEvent *e )
498{
499 // Allow cancelling at first dialog, in case display is broken.
500 if ( e->key() == Key_Escape && currApp < 0 )
501 QDialog::keyPressEvent(e);
502}
503
504void FirstUse::mouseReleaseEvent( QMouseEvent * )
505{
506 if ( currApp < 0 ) {
507#if defined(QPE_NEED_CALIBRATION)
508 if ( needCalibrate ) {
509 releaseMouse();
510 Calibrate *cal = new Calibrate;
511 cal->exec();
512 delete cal;
513 }
514#endif
515 nextDialog();
516 }
517}