summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/global.cpp246
1 files changed, 114 insertions, 132 deletions
diff --git a/library/global.cpp b/library/global.cpp
index 4aca08b..a627348 100644
--- a/library/global.cpp
+++ b/library/global.cpp
@@ -1,832 +1,814 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 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 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 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 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. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#define QTOPIA_INTERNAL_LANGLIST 20#define QTOPIA_INTERNAL_LANGLIST
21#include <qpe/qpedebug.h> 21#include <qpe/qpedebug.h>
22#include <qpe/global.h> 22#include <qpe/global.h>
23#include <qpe/qdawg.h> 23#include <qpe/qdawg.h>
24#include <qpe/qpeapplication.h> 24#include <qpe/qpeapplication.h>
25#include <qpe/resource.h> 25#include <qpe/resource.h>
26#include <qpe/storage.h> 26#include <qpe/storage.h>
27#include <qpe/applnk.h> 27#include <qpe/applnk.h>
28#include <qpe/qcopenvelope_qws.h> 28#include <qpe/qcopenvelope_qws.h>
29#include <qpe/config.h> 29#include <qpe/config.h>
30 30
31#include <qfile.h> 31#include <qfile.h>
32#include <qlabel.h> 32#include <qlabel.h>
33#include <qtimer.h> 33#include <qtimer.h>
34#include <qmap.h> 34#include <qmap.h>
35#include <qdict.h> 35#include <qdict.h>
36#include <qdir.h> 36#include <qdir.h>
37#include <qmessagebox.h> 37#include <qmessagebox.h>
38#include <qregexp.h> 38#include <qregexp.h>
39 39
40#include <stdlib.h> 40#include <stdlib.h>
41#include <sys/stat.h> 41#include <sys/stat.h>
42#include <sys/wait.h> 42#include <sys/wait.h>
43#include <sys/types.h> 43#include <sys/types.h>
44#include <fcntl.h> 44#include <fcntl.h>
45#include <unistd.h> 45#include <unistd.h>
46#include <errno.h> 46#include <errno.h>
47 47
48#include <qwindowsystem_qws.h> // for qwsServer 48#include <qwindowsystem_qws.h> // for qwsServer
49#include <qdatetime.h> 49#include <qdatetime.h>
50 50
51#include <qfile.h> 51#include <qfile.h>
52 52
53namespace {
54 // checks if the storage should be searched
55 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke
56 QFile file(path );
57 if(!file.open(IO_ReadOnly ) )
58 return true;
59
60 QByteArray array = file.readAll();
61 QStringList list = QStringList::split('\n', QString( array ) );
62 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){
63 if( (*it).startsWith("check = 0" ) ){
64 return false;
65 }else if( (*it).startsWith("check = 1" ) ){
66 return true;
67 }
68 }
69 return true;
70 }
71}
72
73//#include "quickexec_p.h" 53//#include "quickexec_p.h"
74 54
75class Emitter : public QObject { 55class Emitter : public QObject {
76 Q_OBJECT 56 Q_OBJECT
77public: 57public:
78 Emitter( QWidget* receiver, const QString& document ) 58 Emitter( QWidget* receiver, const QString& document )
79 { 59 {
80 connect(this, SIGNAL(setDocument(const QString&)), 60 connect(this, SIGNAL(setDocument(const QString&)),
81 receiver, SLOT(setDocument(const QString&))); 61 receiver, SLOT(setDocument(const QString&)));
82 emit setDocument(document); 62 emit setDocument(document);
83 disconnect(this, SIGNAL(setDocument(const QString&)), 63 disconnect(this, SIGNAL(setDocument(const QString&)),
84 receiver, SLOT(setDocument(const QString&))); 64 receiver, SLOT(setDocument(const QString&)));
85 } 65 }
86 66
87signals: 67signals:
88 void setDocument(const QString&); 68 void setDocument(const QString&);
89}; 69};
90 70
91 71
92class StartingAppList : public QObject { 72class StartingAppList : public QObject {
93 Q_OBJECT 73 Q_OBJECT
94public: 74public:
95 static void add( const QString& name ); 75 static void add( const QString& name );
96 static bool isStarting( const QString name ); 76 static bool isStarting( const QString name );
97private slots: 77private slots:
98 void handleNewChannel( const QString &); 78 void handleNewChannel( const QString &);
99private: 79private:
100 StartingAppList( QObject *parent=0, const char* name=0 ) ; 80 StartingAppList( QObject *parent=0, const char* name=0 ) ;
101 81
102 QDict<QTime> dict; 82 QDict<QTime> dict;
103 static StartingAppList *appl; 83 static StartingAppList *appl;
104}; 84};
105 85
106StartingAppList* StartingAppList::appl = 0; 86StartingAppList* StartingAppList::appl = 0;
107 87
108StartingAppList::StartingAppList( QObject *parent, const char* name ) 88StartingAppList::StartingAppList( QObject *parent, const char* name )
109 :QObject( parent, name ) 89 :QObject( parent, name )
110{ 90{
111#if QT_VERSION >= 232 && defined(QWS) 91#if QT_VERSION >= 232 && defined(QWS)
112 connect( qwsServer, SIGNAL( newChannel(const QString&)), 92 connect( qwsServer, SIGNAL( newChannel(const QString&)),
113 this, SLOT( handleNewChannel(const QString&)) ); 93 this, SLOT( handleNewChannel(const QString&)) );
114#endif 94#endif
115 dict.setAutoDelete( TRUE ); 95 dict.setAutoDelete( TRUE );
116} 96}
117 97
118void StartingAppList::add( const QString& name ) 98void StartingAppList::add( const QString& name )
119{ 99{
120#if QT_VERSION >= 232 && !defined(QT_NO_COP) 100#if QT_VERSION >= 232 && !defined(QT_NO_COP)
121 if ( !appl ) 101 if ( !appl )
122 appl = new StartingAppList; 102 appl = new StartingAppList;
123 QTime *t = new QTime; 103 QTime *t = new QTime;
124 t->start(); 104 t->start();
125 appl->dict.insert( "QPE/Application/" + name, t ); 105 appl->dict.insert( "QPE/Application/" + name, t );
126#endif 106#endif
127} 107}
128 108
129bool StartingAppList::isStarting( const QString name ) 109bool StartingAppList::isStarting( const QString name )
130{ 110{
131#if QT_VERSION >= 232 && !defined(QT_NO_COP) 111#if QT_VERSION >= 232 && !defined(QT_NO_COP)
132 if ( appl ) { 112 if ( appl ) {
133 QTime *t = appl->dict.find( "QPE/Application/" + name ); 113 QTime *t = appl->dict.find( "QPE/Application/" + name );
134 if ( !t ) 114 if ( !t )
135 return FALSE; 115 return FALSE;
136 if ( t->elapsed() > 10000 ) { 116 if ( t->elapsed() > 10000 ) {
137 // timeout in case of crash or something 117 // timeout in case of crash or something
138 appl->dict.remove( "QPE/Application/" + name ); 118 appl->dict.remove( "QPE/Application/" + name );
139 return FALSE; 119 return FALSE;
140 } 120 }
141 return TRUE; 121 return TRUE;
142 } 122 }
143#endif 123#endif
144 return FALSE; 124 return FALSE;
145} 125}
146 126
147void StartingAppList::handleNewChannel( const QString & name ) 127void StartingAppList::handleNewChannel( const QString & name )
148{ 128{
149#if QT_VERSION >= 232 && !defined(QT_NO_COP) 129#if QT_VERSION >= 232 && !defined(QT_NO_COP)
150 dict.remove( name ); 130 dict.remove( name );
151#endif 131#endif
152} 132}
153 133
154static bool docDirCreated = FALSE; 134static bool docDirCreated = FALSE;
155static QDawg* fixed_dawg = 0; 135static QDawg* fixed_dawg = 0;
156static QDict<QDawg> *named_dawg = 0; 136static QDict<QDawg> *named_dawg = 0;
157 137
158static QString qpeDir() 138static QString qpeDir()
159{ 139{
160 QString dir = getenv("OPIEDIR"); 140 QString dir = getenv("OPIEDIR");
161 if ( dir.isEmpty() ) dir = ".."; 141 if ( dir.isEmpty() ) dir = "..";
162 return dir; 142 return dir;
163} 143}
164 144
165static QString dictDir() 145static QString dictDir()
166{ 146{
167 return qpeDir() + "/etc/dict"; 147 return qpeDir() + "/etc/dict";
168} 148}
169 149
170/*! 150/*!
171 \class Global global.h 151 \class Global global.h
172 \brief The Global class provides application-wide global functions. 152 \brief The Global class provides application-wide global functions.
173 153
174 The Global functions are grouped as follows: 154 The Global functions are grouped as follows:
175 \tableofcontents 155 \tableofcontents
176 156
177 \section1 User Interface 157 \section1 User Interface
178 158
179 The statusMessage() function provides short-duration messages to the 159 The statusMessage() function provides short-duration messages to the
180 user. The showInputMethod() function shows the current input method, 160 user. The showInputMethod() function shows the current input method,
181 and hideInputMethod() hides the input method. 161 and hideInputMethod() hides the input method.
182 162
183 \section1 Document related 163 \section1 Document related
184 164
185 The findDocuments() function creates a set of \link doclnk.html 165 The findDocuments() function creates a set of \link doclnk.html
186 DocLnk\endlink objects in a particular folder. 166 DocLnk\endlink objects in a particular folder.
187 167
188 \section1 Filesystem related 168 \section1 Filesystem related
189 169
190 Global provides an applicationFileName() function that returns the 170 Global provides an applicationFileName() function that returns the
191 full path of an application-specific file. 171 full path of an application-specific file.
192 172
193 The execute() function runs an application. 173 The execute() function runs an application.
194 174
195 \section1 Word list related 175 \section1 Word list related
196 176
197 A list of words relevant to the current locale is maintained by the 177 A list of words relevant to the current locale is maintained by the
198 system. The list is held in a \link qdawg.html DAWG\endlink 178 system. The list is held in a \link qdawg.html DAWG\endlink
199 (implemented by the QDawg class). This list is used, for example, by 179 (implemented by the QDawg class). This list is used, for example, by
200 the pickboard input method. 180 the pickboard input method.
201 181
202 The global QDawg is returned by fixedDawg(); this cannot be updated. 182 The global QDawg is returned by fixedDawg(); this cannot be updated.
203 An updatable copy of the global QDawg is returned by addedDawg(). 183 An updatable copy of the global QDawg is returned by addedDawg().
204 Applications may have their own word lists stored in \l{QDawg}s 184 Applications may have their own word lists stored in \l{QDawg}s
205 which are returned by dawg(). Use addWords() to add words to the 185 which are returned by dawg(). Use addWords() to add words to the
206 updateable copy of the global QDawg or to named application 186 updateable copy of the global QDawg or to named application
207 \l{QDawg}s. 187 \l{QDawg}s.
208 188
209 \section1 Quoting 189 \section1 Quoting
210 190
211 The shellQuote() function quotes a string suitable for passing to a 191 The shellQuote() function quotes a string suitable for passing to a
212 shell. The stringQuote() function backslash escapes '\' and '"' 192 shell. The stringQuote() function backslash escapes '\' and '"'
213 characters. 193 characters.
214 194
215 \section1 Hardware 195 \section1 Hardware
216 196
217 The implementation of the writeHWClock() function depends on the AlarmServer 197 The implementation of the writeHWClock() function depends on the AlarmServer
218 implementation. If the AlarmServer is using atd the clock will be synced to 198 implementation. If the AlarmServer is using atd the clock will be synced to
219 hardware. If opie-alarm is used the hardware clock will be synced before 199 hardware. If opie-alarm is used the hardware clock will be synced before
220 suspending the device. opie-alarm is used by iPAQ and Zaurii implementation 200 suspending the device. opie-alarm is used by iPAQ and Zaurii implementation
221 201
222 \ingroup qtopiaemb 202 \ingroup qtopiaemb
223*/ 203*/
224 204
225/*! 205/*!
226 \internal 206 \internal
227*/ 207*/
228Global::Global() 208Global::Global()
229{ 209{
230} 210}
231 211
232/*! 212/*!
233 Returns the unchangeable QDawg that contains general 213 Returns the unchangeable QDawg that contains general
234 words for the current locale. 214 words for the current locale.
235 215
236 \sa addedDawg() 216 \sa addedDawg()
237*/ 217*/
238const QDawg& Global::fixedDawg() 218const QDawg& Global::fixedDawg()
239{ 219{
240 if ( !fixed_dawg ) { 220 if ( !fixed_dawg ) {
241 if ( !docDirCreated ) 221 if ( !docDirCreated )
242 createDocDir(); 222 createDocDir();
243 223
244 fixed_dawg = new QDawg; 224 fixed_dawg = new QDawg;
245 QString dawgfilename = dictDir() + "/dawg"; 225 QString dawgfilename = dictDir() + "/dawg";
246 QString words_lang; 226 QString words_lang;
247 QStringList langs = Global::languageList(); 227 QStringList langs = Global::languageList();
248 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { 228 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
249 QString lang = *it; 229 QString lang = *it;
250 words_lang = dictDir() + "/words." + lang; 230 words_lang = dictDir() + "/words." + lang;
251 QString dawgfilename_lang = dawgfilename + "." + lang; 231 QString dawgfilename_lang = dawgfilename + "." + lang;
252 if ( QFile::exists(dawgfilename_lang) || 232 if ( QFile::exists(dawgfilename_lang) ||
253 QFile::exists(words_lang) ) { 233 QFile::exists(words_lang) ) {
254 dawgfilename = dawgfilename_lang; 234 dawgfilename = dawgfilename_lang;
255 break; 235 break;
256 } 236 }
257 } 237 }
258 QFile dawgfile(dawgfilename); 238 QFile dawgfile(dawgfilename);
259 239
260 if ( !dawgfile.exists() ) { 240 if ( !dawgfile.exists() ) {
261 QString fn = dictDir() + "/words"; 241 QString fn = dictDir() + "/words";
262 if ( QFile::exists(words_lang) ) 242 if ( QFile::exists(words_lang) )
263 fn = words_lang; 243 fn = words_lang;
264 QFile in(fn); 244 QFile in(fn);
265 if ( in.open(IO_ReadOnly) ) { 245 if ( in.open(IO_ReadOnly) ) {
266 fixed_dawg->createFromWords(&in); 246 fixed_dawg->createFromWords(&in);
267 dawgfile.open(IO_WriteOnly); 247 dawgfile.open(IO_WriteOnly);
268 fixed_dawg->write(&dawgfile); 248 fixed_dawg->write(&dawgfile);
269 dawgfile.close(); 249 dawgfile.close();
270 } 250 }
271 } else { 251 } else {
272 fixed_dawg->readFile(dawgfilename); 252 fixed_dawg->readFile(dawgfilename);
273 } 253 }
274 } 254 }
275 255
276 return *fixed_dawg; 256 return *fixed_dawg;
277} 257}
278 258
279/*! 259/*!
280 Returns the changeable QDawg that contains general 260 Returns the changeable QDawg that contains general
281 words for the current locale. 261 words for the current locale.
282 262
283 \sa fixedDawg() 263 \sa fixedDawg()
284*/ 264*/
285const QDawg& Global::addedDawg() 265const QDawg& Global::addedDawg()
286{ 266{
287 return dawg("local"); 267 return dawg("local");
288} 268}
289 269
290/*! 270/*!
291 Returns the QDawg with the given \a name. 271 Returns the QDawg with the given \a name.
292 This is an application-specific word list. 272 This is an application-specific word list.
293 273
294 \a name should not contain "/". 274 \a name should not contain "/".
295*/ 275*/
296const QDawg& Global::dawg(const QString& name) 276const QDawg& Global::dawg(const QString& name)
297{ 277{
298 createDocDir(); 278 createDocDir();
299 if ( !named_dawg ) 279 if ( !named_dawg )
300 named_dawg = new QDict<QDawg>; 280 named_dawg = new QDict<QDawg>;
301 QDawg* r = named_dawg->find(name); 281 QDawg* r = named_dawg->find(name);
302 if ( !r ) { 282 if ( !r ) {
303 r = new QDawg; 283 r = new QDawg;
304 named_dawg->insert(name,r); 284 named_dawg->insert(name,r);
305 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg"; 285 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg";
306 QFile dawgfile(dawgfilename); 286 QFile dawgfile(dawgfilename);
307 if ( dawgfile.open(IO_ReadOnly) ) 287 if ( dawgfile.open(IO_ReadOnly) )
308 r->readFile(dawgfilename); 288 r->readFile(dawgfilename);
309 } 289 }
310 return *r; 290 return *r;
311} 291}
312 292
313/*! 293/*!
314 \overload 294 \overload
315 Adds \a wordlist to the addedDawg(). 295 Adds \a wordlist to the addedDawg().
316 296
317 Note that the addition of words persists between program executions 297 Note that the addition of words persists between program executions
318 (they are saved in the dictionary files), so you should confirm the 298 (they are saved in the dictionary files), so you should confirm the
319 words with the user before adding them. 299 words with the user before adding them.
320*/ 300*/
321void Global::addWords(const QStringList& wordlist) 301void Global::addWords(const QStringList& wordlist)
322{ 302{
323 addWords("local",wordlist); 303 addWords("local",wordlist);
324} 304}
325 305
326/*! 306/*!
327 \overload 307 \overload
328 Adds \a wordlist to the addedDawg(). 308 Adds \a wordlist to the addedDawg().
329 309
330 Note that the addition of words persists between program executions 310 Note that the addition of words persists between program executions
331 (they are saved in the dictionary files), so you should confirm the 311 (they are saved in the dictionary files), so you should confirm the
332 words with the user before adding them. 312 words with the user before adding them.
333*/ 313*/
334void Global::addWords(const QString& dictname, const QStringList& wordlist) 314void Global::addWords(const QString& dictname, const QStringList& wordlist)
335{ 315{
336 QDawg& d = (QDawg&)dawg(dictname); 316 QDawg& d = (QDawg&)dawg(dictname);
337 QStringList all = d.allWords() + wordlist; 317 QStringList all = d.allWords() + wordlist;
338 d.createFromWords(all); 318 d.createFromWords(all);
339 319
340 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg"; 320 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg";
341 QFile dawgfile(dawgfilename); 321 QFile dawgfile(dawgfilename);
342 if ( dawgfile.open(IO_WriteOnly) ) { 322 if ( dawgfile.open(IO_WriteOnly) ) {
343 d.write(&dawgfile); 323 d.write(&dawgfile);
344 dawgfile.close(); 324 dawgfile.close();
345 } 325 }
346 326
347 // #### Re-read the dawg here if we use mmap(). 327 // #### Re-read the dawg here if we use mmap().
348 328
349 // #### Signal other processes to re-read. 329 // #### Signal other processes to re-read.
350} 330}
351 331
352 332
353/*! 333/*!
354 Returns the full path for the application called \a appname, with the 334 Returns the full path for the application called \a appname, with the
355 given \a filename. Returns QString::null if there was a problem creating 335 given \a filename. Returns QString::null if there was a problem creating
356 the directory tree for \a appname. 336 the directory tree for \a appname.
357 If \a filename contains "/", it is the caller's responsibility to 337 If \a filename contains "/", it is the caller's responsibility to
358 ensure that those directories exist. 338 ensure that those directories exist.
359*/ 339*/
360QString Global::applicationFileName(const QString& appname, const QString& filename) 340QString Global::applicationFileName(const QString& appname, const QString& filename)
361{ 341{
362 QDir d; 342 QDir d;
363 QString r = getenv("HOME"); 343 QString r = getenv("HOME");
364 r += "/Applications/"; 344 r += "/Applications/";
365 if ( !QFile::exists( r ) ) 345 if ( !QFile::exists( r ) )
366 if ( d.mkdir(r) == false ) 346 if ( d.mkdir(r) == false )
367 return QString::null; 347 return QString::null;
368 r += appname; 348 r += appname;
369 if ( !QFile::exists( r ) ) 349 if ( !QFile::exists( r ) )
370 if ( d.mkdir(r) == false ) 350 if ( d.mkdir(r) == false )
371 return QString::null; 351 return QString::null;
372 r += "/"; r += filename; 352 r += "/"; r += filename;
373 return r; 353 return r;
374} 354}
375 355
376/*! 356/*!
377 \internal 357 \internal
378*/ 358*/
379void Global::createDocDir() 359void Global::createDocDir()
380{ 360{
381 if ( !docDirCreated ) { 361 if ( !docDirCreated ) {
382 docDirCreated = TRUE; 362 docDirCreated = TRUE;
383 mkdir( QPEApplication::documentDir().latin1(), 0755 ); 363 mkdir( QPEApplication::documentDir().latin1(), 0755 );
384 } 364 }
385} 365}
386 366
387 367
388/*! 368/*!
389 Displays a status \a message to the user. This usually appears 369 Displays a status \a message to the user. This usually appears
390 in the taskbar for a short amount of time, then disappears. 370 in the taskbar for a short amount of time, then disappears.
391*/ 371*/
392void Global::statusMessage(const QString& message) 372void Global::statusMessage(const QString& message)
393{ 373{
394#if !defined(QT_NO_COP) 374#if !defined(QT_NO_COP)
395 QCopEnvelope e( "QPE/TaskBar", "message(QString)" ); 375 QCopEnvelope e( "QPE/TaskBar", "message(QString)" );
396 e << message; 376 e << message;
397#endif 377#endif
398} 378}
399 379
400/*! 380/*!
401 \internal 381 \internal
402*/ 382*/
403void Global::applyStyle() 383void Global::applyStyle()
404{ 384{
405#if !defined(QT_NO_COP) 385#if !defined(QT_NO_COP)
406 QCopChannel::send( "QPE/System", "applyStyle()" ); 386 QCopChannel::send( "QPE/System", "applyStyle()" );
407#else 387#else
408 ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version 388 ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version
409#endif 389#endif
410} 390}
411 391
412/*! 392/*!
413 \internal 393 \internal
414*/ 394*/
415QWidget *Global::shutdown( bool ) 395QWidget *Global::shutdown( bool )
416{ 396{
417#if !defined(QT_NO_COP) 397#if !defined(QT_NO_COP)
418 QCopChannel::send( "QPE/System", "shutdown()" ); 398 QCopChannel::send( "QPE/System", "shutdown()" );
419#endif 399#endif
420 return 0; 400 return 0;
421} 401}
422 402
423/*! 403/*!
424 \internal 404 \internal
425*/ 405*/
426QWidget *Global::restart( bool ) 406QWidget *Global::restart( bool )
427{ 407{
428#if !defined(QT_NO_COP) 408#if !defined(QT_NO_COP)
429 QCopChannel::send( "QPE/System", "restart()" ); 409 QCopChannel::send( "QPE/System", "restart()" );
430#endif 410#endif
431 return 0; 411 return 0;
432} 412}
433 413
434/*! 414/*!
435 Explicitly show the current input method. 415 Explicitly show the current input method.
436 416
437 Input methods are indicated in the taskbar by a small icon. If the 417 Input methods are indicated in the taskbar by a small icon. If the
438 input method is activated (shown) then it takes up some proportion 418 input method is activated (shown) then it takes up some proportion
439 of the bottom of the screen, to allow the user to interact (input 419 of the bottom of the screen, to allow the user to interact (input
440 characters) with it. 420 characters) with it.
441 421
442 \sa hideInputMethod() 422 \sa hideInputMethod()
443*/ 423*/
444void Global::showInputMethod() 424void Global::showInputMethod()
445{ 425{
446#if !defined(QT_NO_COP) 426#if !defined(QT_NO_COP)
447 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" ); 427 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" );
448#endif 428#endif
449} 429}
450 430
451/*! 431/*!
452 Explicitly hide the current input method. 432 Explicitly hide the current input method.
453 433
454 The current input method is still indicated in the taskbar, but no 434 The current input method is still indicated in the taskbar, but no
455 longer takes up screen space, and can no longer be interacted with. 435 longer takes up screen space, and can no longer be interacted with.
456 436
457 \sa showInputMethod() 437 \sa showInputMethod()
458*/ 438*/
459void Global::hideInputMethod() 439void Global::hideInputMethod()
460{ 440{
461#if !defined(QT_NO_COP) 441#if !defined(QT_NO_COP)
462 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); 442 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" );
463#endif 443#endif
464} 444}
465 445
466 446
467/*! 447/*!
468 \internal 448 \internal
469*/ 449*/
470bool Global::isBuiltinCommand( const QString &name ) 450bool Global::isBuiltinCommand( const QString &name )
471{ 451{
472 if(!builtin) 452 if(!builtin)
473 return FALSE; // yes, it can happen 453 return FALSE; // yes, it can happen
474 for (int i = 0; builtin[i].file; i++) { 454 for (int i = 0; builtin[i].file; i++) {
475 if ( builtin[i].file == name ) { 455 if ( builtin[i].file == name ) {
476 return TRUE; 456 return TRUE;
477 } 457 }
478 } 458 }
479 return FALSE; 459 return FALSE;
480} 460}
481 461
482Global::Command* Global::builtin=0; 462Global::Command* Global::builtin=0;
483QGuardedPtr<QWidget> *Global::running=0; 463QGuardedPtr<QWidget> *Global::running=0;
484 464
485/*! 465/*!
486 \class Global::Command 466 \class Global::Command
487 \brief The Global::Command class is internal. 467 \brief The Global::Command class is internal.
488 \internal 468 \internal
489*/ 469*/
490 470
491/*! 471/*!
492 \internal 472 \internal
493*/ 473*/
494void Global::setBuiltinCommands( Command* list ) 474void Global::setBuiltinCommands( Command* list )
495{ 475{
496 if ( running ) 476 if ( running )
497 delete [] running; 477 delete [] running;
498 478
499 builtin = list; 479 builtin = list;
500 int count = 0; 480 int count = 0;
501 if (!builtin) 481 if (!builtin)
502 return; 482 return;
503 while ( builtin[count].file ) 483 while ( builtin[count].file )
504 count++; 484 count++;
505 485
506 running = new QGuardedPtr<QWidget> [ count ]; 486 running = new QGuardedPtr<QWidget> [ count ];
507} 487}
508 488
509/*! 489/*!
510 \internal 490 \internal
511*/ 491*/
512void Global::setDocument( QWidget* receiver, const QString& document ) 492void Global::setDocument( QWidget* receiver, const QString& document )
513{ 493{
514 Emitter emitter(receiver,document); 494 Emitter emitter(receiver,document);
515} 495}
516 496
517/*! 497/*!
518 \internal 498 \internal
519*/ 499*/
520bool Global::terminateBuiltin( const QString& n ) 500bool Global::terminateBuiltin( const QString& n )
521{ 501{
522 if (!builtin) 502 if (!builtin)
523 return FALSE; 503 return FALSE;
524 for (int i = 0; builtin[i].file; i++) { 504 for (int i = 0; builtin[i].file; i++) {
525 if ( builtin[i].file == n ) { 505 if ( builtin[i].file == n ) {
526 delete running[i]; 506 delete running[i];
527 return TRUE; 507 return TRUE;
528 } 508 }
529 } 509 }
530 return FALSE; 510 return FALSE;
531} 511}
532 512
533/*! 513/*!
534 \internal 514 \internal
535*/ 515*/
536void Global::terminate( const AppLnk* app ) 516void Global::terminate( const AppLnk* app )
537{ 517{
538 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this 518 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this
539 519
540#ifndef QT_NO_COP 520#ifndef QT_NO_COP
541 QCString channel = "QPE/Application/" + app->exec().utf8(); 521 QCString channel = "QPE/Application/" + app->exec().utf8();
542 if ( QCopChannel::isRegistered(channel) ) { 522 if ( QCopChannel::isRegistered(channel) ) {
543 QCopEnvelope e(channel, "quit()"); 523 QCopEnvelope e(channel, "quit()");
544 } 524 }
545#endif 525#endif
546} 526}
547 527
548/*! 528/*!
549 Low-level function to run command \a c. 529 Low-level function to run command \a c.
550 530
551 \warning Do not use this function. Use execute instead. 531 \warning Do not use this function. Use execute instead.
552 532
553 \sa execute() 533 \sa execute()
554*/ 534*/
555void Global::invoke(const QString &c) 535void Global::invoke(const QString &c)
556{ 536{
557 // Convert the command line in to a list of arguments 537 // Convert the command line in to a list of arguments
558 QStringList list = QStringList::split(QRegExp(" *"),c); 538 QStringList list = QStringList::split(QRegExp(" *"),c);
559 539
560#if !defined(QT_NO_COP) 540#if !defined(QT_NO_COP)
561 QString ap=list[0]; 541 QString ap=list[0];
562 // see if the application is already running 542 // see if the application is already running
563 // XXX should lock file /tmp/qcop-msg-ap 543 // XXX should lock file /tmp/qcop-msg-ap
564 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { 544 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) {
565 // If the channel is already register, the app is already running, so show it. 545 // If the channel is already register, the app is already running, so show it.
566 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } 546 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); }
567 547
568 //QCopEnvelope e("QPE/System", "notBusy(QString)" ); 548 //QCopEnvelope e("QPE/System", "notBusy(QString)" );
569 //e << ap; 549 //e << ap;
570 return; 550 return;
571 } 551 }
572 // XXX should unlock file /tmp/qcop-msg-ap 552 // XXX should unlock file /tmp/qcop-msg-ap
573 //see if it is being started 553 //see if it is being started
574 if ( StartingAppList::isStarting( ap ) ) { 554 if ( StartingAppList::isStarting( ap ) ) {
575 // FIXME take it out for now, since it leads to a much to short showing of wait if 555 // FIXME take it out for now, since it leads to a much to short showing of wait if
576 // some entry is clicked. 556 // some entry is clicked.
577 // Real cause is that ::execute is called twice for document tab. But it would need some larger changes 557 // Real cause is that ::execute is called twice for document tab. But it would need some larger changes
578 // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there 558 // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there
579 // had the idea that an apploader belongs to the launcher ... 559 // had the idea that an apploader belongs to the launcher ...
580 //QCopEnvelope e("QPE/System", "notBusy(QString)" ); 560 //QCopEnvelope e("QPE/System", "notBusy(QString)" );
581 //e << ap; 561 //e << ap;
582 return; 562 return;
583 } 563 }
584 564
585#endif 565#endif
586 566
587#ifdef QT_NO_QWS_MULTIPROCESS 567#ifdef QT_NO_QWS_MULTIPROCESS
588 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); 568 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 );
589#else 569#else
590 570
591 QStrList slist; 571 QStrList slist;
592 unsigned int j; 572 unsigned int j;
593 for ( j = 0; j < list.count(); j++ ) 573 for ( j = 0; j < list.count(); j++ )
594 slist.append( list[j].utf8() ); 574 slist.append( list[j].utf8() );
595 575
596 const char **args = new (const char *)[slist.count() + 1]; 576 const char **args = new (const char *)[slist.count() + 1];
597 for ( j = 0; j < slist.count(); j++ ) 577 for ( j = 0; j < slist.count(); j++ )
598 args[j] = slist.at(j); 578 args[j] = slist.at(j);
599 args[j] = NULL; 579 args[j] = NULL;
600 580
601#if !defined(QT_NO_COP) 581#if !defined(QT_NO_COP)
602 // an attempt to show a wait... 582 // an attempt to show a wait...
603 // more logic should be used, but this will be fine for the moment... 583 // more logic should be used, but this will be fine for the moment...
604 QCopEnvelope ( "QPE/System", "busy()" ); 584 QCopEnvelope ( "QPE/System", "busy()" );
605#endif 585#endif
606 586
607#ifdef HAVE_QUICKEXEC 587#ifdef HAVE_QUICKEXEC
608#ifdef Q_OS_MACX 588#ifdef Q_OS_MACX
609 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; 589 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib";
610#else 590#else
611 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; 591 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
612#endif 592#endif
613 qDebug("libfile = %s", libexe.latin1() ); 593 qDebug("libfile = %s", libexe.latin1() );
614 if ( QFile::exists( libexe ) ) { 594 if ( QFile::exists( libexe ) ) {
615 qDebug("calling quickexec %s", libexe.latin1() ); 595 qDebug("calling quickexec %s", libexe.latin1() );
616 quickexecv( libexe.utf8().data(), (const char **)args ); 596 quickexecv( libexe.utf8().data(), (const char **)args );
617 } else 597 } else
618#endif 598#endif
619 { 599 {
620 bool success = false; 600 bool success = false;
621 int pfd [2]; 601 int pfd [2];
622 if ( ::pipe ( pfd ) < 0 ) 602 if ( ::pipe ( pfd ) < 0 )
623 pfd [0] = pfd [1] = -1; 603 pfd [0] = pfd [1] = -1;
624 604
625 pid_t pid = ::fork ( ); 605 pid_t pid = ::fork ( );
626 606
627 if ( pid == 0 ) { // child 607 if ( pid == 0 ) { // child
628 for ( int fd = 3; fd < 100; fd++ ) { 608 for ( int fd = 3; fd < 100; fd++ ) {
629 if ( fd != pfd [1] ) 609 if ( fd != pfd [1] )
630 ::close ( fd ); 610 ::close ( fd );
631 } 611 }
632 ::setpgid ( ::getpid ( ), ::getppid ( )); 612 ::setpgid ( ::getpid ( ), ::getppid ( ));
633 613
634 // Closing of fd[1] indicates that the execvp succeeded! 614 // Closing of fd[1] indicates that the execvp succeeded!
635 if ( pfd [1] >= 0 ) 615 if ( pfd [1] >= 0 )
636 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); 616 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
637 617
638 // Try bindir first, so that foo/bar works too 618 // Try bindir first, so that foo/bar works too
639 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); 619 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
640 ::execvp ( args [0], (char * const *) args ); 620 ::execvp ( args [0], (char * const *) args );
641 621
642 char resultByte = 1; 622 char resultByte = 1;
643 if ( pfd [1] >= 0 ) 623 if ( pfd [1] >= 0 )
644 ::write ( pfd [1], &resultByte, 1 ); 624 ::write ( pfd [1], &resultByte, 1 );
645 ::_exit ( -1 ); 625 ::_exit ( -1 );
646 } 626 }
647 else if ( pid > 0 ) { 627 else if ( pid > 0 ) {
648 success = true; 628 success = true;
649 629
650 if ( pfd [1] >= 0 ) 630 if ( pfd [1] >= 0 )
651 ::close ( pfd [1] ); 631 ::close ( pfd [1] );
652 if ( pfd [0] >= 0 ) { 632 if ( pfd [0] >= 0 ) {
653 while ( true ) { 633 while ( true ) {
654 char resultByte; 634 char resultByte;
655 int n = ::read ( pfd [0], &resultByte, 1 ); 635 int n = ::read ( pfd [0], &resultByte, 1 );
656 if ( n == 1 ) { 636 if ( n == 1 ) {
657 success = false; 637 success = false;
658 break; 638 break;
659 } 639 }
660 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) 640 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
661 continue; 641 continue;
662 642
663 break; // success 643 break; // success
664 } 644 }
665 ::close ( pfd [0] ); 645 ::close ( pfd [0] );
666 } 646 }
667 } 647 }
668 if ( success ) 648 if ( success )
669 StartingAppList::add( list[0] ); 649 StartingAppList::add( list[0] );
670 else 650 else
671 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); 651 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
672 } 652 }
673#endif //QT_NO_QWS_MULTIPROCESS 653#endif //QT_NO_QWS_MULTIPROCESS
674} 654}
675 655
676 656
677/*! 657/*!
678 Executes the application identfied by \a c, passing \a 658 Executes the application identfied by \a c, passing \a
679 document if it isn't null. 659 document if it isn't null.
680 660
681 Note that a better approach might be to send a QCop message to the 661 Note that a better approach might be to send a QCop message to the
682 application's QPE/Application/\e{appname} channel. 662 application's QPE/Application/\e{appname} channel.
683*/ 663*/
684void Global::execute( const QString &c, const QString& document ) 664void Global::execute( const QString &c, const QString& document )
685{ 665{
686 // ask the server to do the work 666 // ask the server to do the work
687#if !defined(QT_NO_COP) 667#if !defined(QT_NO_COP)
688 if ( document.isNull() ) { 668 if ( document.isNull() ) {
689 QCopEnvelope e( "QPE/System", "execute(QString)" ); 669 QCopEnvelope e( "QPE/System", "execute(QString)" );
690 e << c; 670 e << c;
691 } else { 671 } else {
692 QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); 672 QCopEnvelope e( "QPE/System", "execute(QString,QString)" );
693 e << c << document; 673 e << c << document;
694 } 674 }
695#endif 675#endif
696 return; 676 return;
697} 677}
698 678
699/*! 679/*!
700 Returns the string \a s with the characters '\', '"', and '$' quoted 680 Returns the string \a s with the characters '\', '"', and '$' quoted
701 by a preceeding '\'. 681 by a preceeding '\'.
702 682
703 \sa stringQuote() 683 \sa stringQuote()
704*/ 684*/
705QString Global::shellQuote(const QString& s) 685QString Global::shellQuote(const QString& s)
706{ 686{
707 QString r="\""; 687 QString r="\"";
708 for (int i=0; i<(int)s.length(); i++) { 688 for (int i=0; i<(int)s.length(); i++) {
709 char c = s[i].latin1(); 689 char c = s[i].latin1();
710 switch (c) { 690 switch (c) {
711 case '\\': case '"': case '$': 691 case '\\': case '"': case '$':
712 r+="\\"; 692 r+="\\";
713 } 693 }
714 r += s[i]; 694 r += s[i];
715 } 695 }
716 r += "\""; 696 r += "\"";
717 return r; 697 return r;
718} 698}
719 699
720/*! 700/*!
721 Returns the string \a s with the characters '\' and '"' quoted by a 701 Returns the string \a s with the characters '\' and '"' quoted by a
722 preceeding '\'. 702 preceeding '\'.
723 703
724 \sa shellQuote() 704 \sa shellQuote()
725*/ 705*/
726QString Global::stringQuote(const QString& s) 706QString Global::stringQuote(const QString& s)
727{ 707{
728 QString r="\""; 708 QString r="\"";
729 for (int i=0; i<(int)s.length(); i++) { 709 for (int i=0; i<(int)s.length(); i++) {
730 char c = s[i].latin1(); 710 char c = s[i].latin1();
731 switch (c) { 711 switch (c) {
732 case '\\': case '"': 712 case '\\': case '"':
733 r+="\\"; 713 r+="\\";
734 } 714 }
735 r += s[i]; 715 r += s[i];
736 } 716 }
737 r += "\""; 717 r += "\"";
738 return r; 718 return r;
739} 719}
740 720
741/*! 721/*!
742 Finds all documents on the system's document directories which 722 Finds all documents on the system's document directories which
743 match the filter \a mimefilter, and appends the resulting DocLnk 723 match the filter \a mimefilter, and appends the resulting DocLnk
744 objects to \a folder. 724 objects to \a folder.
745*/ 725*/
746void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) 726void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter)
747{ 727{
748 QString homedocs = QString(getenv("HOME")) + "/Documents"; 728 QString homedocs = QString(getenv("HOME")) + "/Documents";
749 DocLnkSet d(homedocs,mimefilter); 729 DocLnkSet d(homedocs,mimefilter);
750 folder->appendFrom(d); 730 folder->appendFrom(d);
751 /** let's do intellegint way of searching these files 731 /** let's do intellegint way of searching these files
752 * a) the user don't want to check mediums global 732 * a) the user don't want to check mediums global
753 * b) the user wants to check but use the global options for it 733 * b) the user wants to check but use the global options for it
754 * c) the user wants to check it but not this medium 734 * c) the user wants to check it but not this medium
755 * d) the user wants to check and this medium as well 735 * d) the user wants to check and this medium as well
756 * 736 *
757 * In all cases we need to apply a different mimefilter to 737 * In all cases we need to apply a different mimefilter to
758 * the medium. 738 * the medium.
759 * a) mimefilter.isEmpty() we need to apply the responding filter 739 * a) mimefilter.isEmpty() we need to apply the responding filter
760 * either the global or the one on the medium 740 * either the global or the one on the medium
761 * 741 *
762 * b) mimefilter is set to an application we need to find out if the 742 * b) mimefilter is set to an application we need to find out if the
763 * mimetypes are included in the mime mask of the medium 743 * mimetypes are included in the mime mask of the medium
764 */ 744 */
765 StorageInfo storage; 745 StorageInfo storage;
766 const QList<FileSystem> &fs = storage.fileSystems(); 746 const QList<FileSystem> &fs = storage.fileSystems();
767 QListIterator<FileSystem> it ( fs ); 747 QListIterator<FileSystem> it ( fs );
768 for ( ; it.current(); ++it ) { 748 for ( ; it.current(); ++it ) {
769 if ( (*it)->isRemovable() ) { // let's find out if we should search on it 749 if ( (*it)->isRemovable() ) { // let's find out if we should search on it
770 // this is a candidate look at the cf and see if we should search on it 750 // this is a candidate look at the cf and see if we should search on it
771 QString path = (*it)->path(); 751 QString path = (*it)->path();
772 if( !checkStorage((*it)->path() + "/.opiestorage.cf" ) )
773 continue;
774 Config conf((*it)->path() + "/.opiestorage.cf", Config::File ); 752 Config conf((*it)->path() + "/.opiestorage.cf", Config::File );
753 conf.setGroup("main");
754 if (!conf.readBoolEntry("check",true)) {
755 continue;
756 }
775 conf.setGroup("subdirs"); 757 conf.setGroup("subdirs");
776 if (conf.readBoolEntry("wholemedia",true)) { 758 if (conf.readBoolEntry("wholemedia",true)) {
777 DocLnkSet ide( path,mimefilter); 759 DocLnkSet ide( path,mimefilter);
778 folder->appendFrom(ide); 760 folder->appendFrom(ide);
779 } else { 761 } else {
780 QStringList subDirs = conf.readListEntry("subdirs",':'); 762 QStringList subDirs = conf.readListEntry("subdirs",':');
781 if (subDirs.isEmpty()) { 763 if (subDirs.isEmpty()) {
782 subDirs.append("Documents"); 764 subDirs.append("Documents");
783 } 765 }
784 for (unsigned c = 0; c < subDirs.count();++c) { 766 for (unsigned c = 0; c < subDirs.count();++c) {
785 DocLnkSet ide( path+"/"+subDirs[c], mimefilter ); 767 DocLnkSet ide( path+"/"+subDirs[c], mimefilter );
786 folder->appendFrom(ide); 768 folder->appendFrom(ide);
787 } 769 }
788 } 770 }
789 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { 771 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
790 QString path = (*it)->path() + "/Documents"; 772 QString path = (*it)->path() + "/Documents";
791 DocLnkSet ide( path, mimefilter ); 773 DocLnkSet ide( path, mimefilter );
792 folder->appendFrom(ide); 774 folder->appendFrom(ide);
793 } 775 }
794 } 776 }
795} 777}
796 778
797QStringList Global::languageList() 779QStringList Global::languageList()
798{ 780{
799 QString lang = getenv("LANG"); 781 QString lang = getenv("LANG");
800 QStringList langs; 782 QStringList langs;
801 langs.append(lang); 783 langs.append(lang);
802 int i = lang.find("."); 784 int i = lang.find(".");
803 if ( i > 0 ) 785 if ( i > 0 )
804 lang = lang.left( i ); 786 lang = lang.left( i );
805 i = lang.find( "_" ); 787 i = lang.find( "_" );
806 if ( i > 0 ) 788 if ( i > 0 )
807 langs.append(lang.left(i)); 789 langs.append(lang.left(i));
808 return langs; 790 return langs;
809} 791}
810 792
811QStringList Global::helpPath() 793QStringList Global::helpPath()
812{ 794{
813 QString qpeDir = QPEApplication::qpeDir(); 795 QString qpeDir = QPEApplication::qpeDir();
814 QStringList path; 796 QStringList path;
815 QStringList langs = Global::languageList(); 797 QStringList langs = Global::languageList();
816 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { 798 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) {
817 QString lang = *it; 799 QString lang = *it;
818 if ( !lang.isEmpty() ) 800 if ( !lang.isEmpty() )
819 path += qpeDir + "/help/" + lang + "/html"; 801 path += qpeDir + "/help/" + lang + "/html";
820 } 802 }
821 path += qpeDir + "/pics"; 803 path += qpeDir + "/pics";
822 path += qpeDir + "/help/html"; 804 path += qpeDir + "/help/html";
823 /* we even put english into the en dir so try it as fallback as well for opie */ 805 /* we even put english into the en dir so try it as fallback as well for opie */
824 path += qpeDir + "/help/en/html"; 806 path += qpeDir + "/help/en/html";
825 path += qpeDir + "/docs"; 807 path += qpeDir + "/docs";
826 808
827 809
828 return path; 810 return path;
829} 811}
830 812
831 813
832#include "global.moc" 814#include "global.moc"