summaryrefslogtreecommitdiff
path: root/library
Unidiff
Diffstat (limited to 'library') (more/less context) (ignore whitespace changes)
-rw-r--r--library/global.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/library/global.cpp b/library/global.cpp
index 05d23ac..6c0a66a 100644
--- a/library/global.cpp
+++ b/library/global.cpp
@@ -1,284 +1,285 @@
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 30
30#include <qfile.h> 31#include <qfile.h>
31#include <qlabel.h> 32#include <qlabel.h>
32#include <qtimer.h> 33#include <qtimer.h>
33#include <qmap.h> 34#include <qmap.h>
34#include <qdict.h> 35#include <qdict.h>
35#include <qdir.h> 36#include <qdir.h>
36#include <qmessagebox.h> 37#include <qmessagebox.h>
37#include <qregexp.h> 38#include <qregexp.h>
38 39
39#include <stdlib.h> 40#include <stdlib.h>
40#include <sys/stat.h> 41#include <sys/stat.h>
41#include <sys/wait.h> 42#include <sys/wait.h>
42#include <sys/types.h> 43#include <sys/types.h>
43#include <fcntl.h> 44#include <fcntl.h>
44#include <unistd.h> 45#include <unistd.h>
45#include <errno.h> 46#include <errno.h>
46 47
47#include <qwindowsystem_qws.h> // for qwsServer 48#include <qwindowsystem_qws.h> // for qwsServer
48#include <qdatetime.h> 49#include <qdatetime.h>
49 50
50#include <qfile.h> 51#include <qfile.h>
51 52
52namespace { 53namespace {
53 // checks if the storage should be searched 54 // checks if the storage should be searched
54 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke 55 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke
55 QFile file(path ); 56 QFile file(path );
56 if(!file.open(IO_ReadOnly ) ) 57 if(!file.open(IO_ReadOnly ) )
57 return true; 58 return true;
58 59
59 QByteArray array = file.readAll(); 60 QByteArray array = file.readAll();
60 QStringList list = QStringList::split('\n', QString( array ) ); 61 QStringList list = QStringList::split('\n', QString( array ) );
61 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){ 62 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){
62 if( (*it).startsWith("autocheck = 0" ) ){ 63 if( (*it).startsWith("autocheck = 0" ) ){
63 return false; 64 return false;
64 }else if( (*it).startsWith("autocheck = 1" ) ){ 65 }else if( (*it).startsWith("autocheck = 1" ) ){
65 return true; 66 return true;
66 } 67 }
67 } 68 }
68 return true; 69 return true;
69 } 70 }
70} 71}
71 72
72//#include "quickexec_p.h" 73//#include "quickexec_p.h"
73 74
74class Emitter : public QObject { 75class Emitter : public QObject {
75 Q_OBJECT 76 Q_OBJECT
76public: 77public:
77 Emitter( QWidget* receiver, const QString& document ) 78 Emitter( QWidget* receiver, const QString& document )
78 { 79 {
79 connect(this, SIGNAL(setDocument(const QString&)), 80 connect(this, SIGNAL(setDocument(const QString&)),
80 receiver, SLOT(setDocument(const QString&))); 81 receiver, SLOT(setDocument(const QString&)));
81 emit setDocument(document); 82 emit setDocument(document);
82 disconnect(this, SIGNAL(setDocument(const QString&)), 83 disconnect(this, SIGNAL(setDocument(const QString&)),
83 receiver, SLOT(setDocument(const QString&))); 84 receiver, SLOT(setDocument(const QString&)));
84 } 85 }
85 86
86signals: 87signals:
87 void setDocument(const QString&); 88 void setDocument(const QString&);
88}; 89};
89 90
90 91
91class StartingAppList : public QObject { 92class StartingAppList : public QObject {
92 Q_OBJECT 93 Q_OBJECT
93public: 94public:
94 static void add( const QString& name ); 95 static void add( const QString& name );
95 static bool isStarting( const QString name ); 96 static bool isStarting( const QString name );
96private slots: 97private slots:
97 void handleNewChannel( const QString &); 98 void handleNewChannel( const QString &);
98private: 99private:
99 StartingAppList( QObject *parent=0, const char* name=0 ) ; 100 StartingAppList( QObject *parent=0, const char* name=0 ) ;
100 101
101 QDict<QTime> dict; 102 QDict<QTime> dict;
102 static StartingAppList *appl; 103 static StartingAppList *appl;
103}; 104};
104 105
105StartingAppList* StartingAppList::appl = 0; 106StartingAppList* StartingAppList::appl = 0;
106 107
107StartingAppList::StartingAppList( QObject *parent, const char* name ) 108StartingAppList::StartingAppList( QObject *parent, const char* name )
108 :QObject( parent, name ) 109 :QObject( parent, name )
109{ 110{
110#if QT_VERSION >= 232 && defined(QWS) 111#if QT_VERSION >= 232 && defined(QWS)
111 connect( qwsServer, SIGNAL( newChannel(const QString&)), 112 connect( qwsServer, SIGNAL( newChannel(const QString&)),
112 this, SLOT( handleNewChannel(const QString&)) ); 113 this, SLOT( handleNewChannel(const QString&)) );
113#endif 114#endif
114 dict.setAutoDelete( TRUE ); 115 dict.setAutoDelete( TRUE );
115} 116}
116 117
117void StartingAppList::add( const QString& name ) 118void StartingAppList::add( const QString& name )
118{ 119{
119#if QT_VERSION >= 232 && !defined(QT_NO_COP) 120#if QT_VERSION >= 232 && !defined(QT_NO_COP)
120 if ( !appl ) 121 if ( !appl )
121 appl = new StartingAppList; 122 appl = new StartingAppList;
122 QTime *t = new QTime; 123 QTime *t = new QTime;
123 t->start(); 124 t->start();
124 appl->dict.insert( "QPE/Application/" + name, t ); 125 appl->dict.insert( "QPE/Application/" + name, t );
125#endif 126#endif
126} 127}
127 128
128bool StartingAppList::isStarting( const QString name ) 129bool StartingAppList::isStarting( const QString name )
129{ 130{
130#if QT_VERSION >= 232 && !defined(QT_NO_COP) 131#if QT_VERSION >= 232 && !defined(QT_NO_COP)
131 if ( appl ) { 132 if ( appl ) {
132 QTime *t = appl->dict.find( "QPE/Application/" + name ); 133 QTime *t = appl->dict.find( "QPE/Application/" + name );
133 if ( !t ) 134 if ( !t )
134 return FALSE; 135 return FALSE;
135 if ( t->elapsed() > 10000 ) { 136 if ( t->elapsed() > 10000 ) {
136 // timeout in case of crash or something 137 // timeout in case of crash or something
137 appl->dict.remove( "QPE/Application/" + name ); 138 appl->dict.remove( "QPE/Application/" + name );
138 return FALSE; 139 return FALSE;
139 } 140 }
140 return TRUE; 141 return TRUE;
141 } 142 }
142#endif 143#endif
143 return FALSE; 144 return FALSE;
144} 145}
145 146
146void StartingAppList::handleNewChannel( const QString & name ) 147void StartingAppList::handleNewChannel( const QString & name )
147{ 148{
148#if QT_VERSION >= 232 && !defined(QT_NO_COP) 149#if QT_VERSION >= 232 && !defined(QT_NO_COP)
149 dict.remove( name ); 150 dict.remove( name );
150#endif 151#endif
151} 152}
152 153
153static bool docDirCreated = FALSE; 154static bool docDirCreated = FALSE;
154static QDawg* fixed_dawg = 0; 155static QDawg* fixed_dawg = 0;
155static QDict<QDawg> *named_dawg = 0; 156static QDict<QDawg> *named_dawg = 0;
156 157
157static QString qpeDir() 158static QString qpeDir()
158{ 159{
159 QString dir = getenv("OPIEDIR"); 160 QString dir = getenv("OPIEDIR");
160 if ( dir.isEmpty() ) dir = ".."; 161 if ( dir.isEmpty() ) dir = "..";
161 return dir; 162 return dir;
162} 163}
163 164
164static QString dictDir() 165static QString dictDir()
165{ 166{
166 return qpeDir() + "/etc/dict"; 167 return qpeDir() + "/etc/dict";
167} 168}
168 169
169/*! 170/*!
170 \class Global global.h 171 \class Global global.h
171 \brief The Global class provides application-wide global functions. 172 \brief The Global class provides application-wide global functions.
172 173
173 The Global functions are grouped as follows: 174 The Global functions are grouped as follows:
174 \tableofcontents 175 \tableofcontents
175 176
176 \section1 User Interface 177 \section1 User Interface
177 178
178 The statusMessage() function provides short-duration messages to the 179 The statusMessage() function provides short-duration messages to the
179 user. The showInputMethod() function shows the current input method, 180 user. The showInputMethod() function shows the current input method,
180 and hideInputMethod() hides the input method. 181 and hideInputMethod() hides the input method.
181 182
182 \section1 Document related 183 \section1 Document related
183 184
184 The findDocuments() function creates a set of \link doclnk.html 185 The findDocuments() function creates a set of \link doclnk.html
185 DocLnk\endlink objects in a particular folder. 186 DocLnk\endlink objects in a particular folder.
186 187
187 \section1 Filesystem related 188 \section1 Filesystem related
188 189
189 Global provides an applicationFileName() function that returns the 190 Global provides an applicationFileName() function that returns the
190 full path of an application-specific file. 191 full path of an application-specific file.
191 192
192 The execute() function runs an application. 193 The execute() function runs an application.
193 194
194 \section1 Word list related 195 \section1 Word list related
195 196
196 A list of words relevant to the current locale is maintained by the 197 A list of words relevant to the current locale is maintained by the
197 system. The list is held in a \link qdawg.html DAWG\endlink 198 system. The list is held in a \link qdawg.html DAWG\endlink
198 (implemented by the QDawg class). This list is used, for example, by 199 (implemented by the QDawg class). This list is used, for example, by
199 the pickboard input method. 200 the pickboard input method.
200 201
201 The global QDawg is returned by fixedDawg(); this cannot be updated. 202 The global QDawg is returned by fixedDawg(); this cannot be updated.
202 An updatable copy of the global QDawg is returned by addedDawg(). 203 An updatable copy of the global QDawg is returned by addedDawg().
203 Applications may have their own word lists stored in \l{QDawg}s 204 Applications may have their own word lists stored in \l{QDawg}s
204 which are returned by dawg(). Use addWords() to add words to the 205 which are returned by dawg(). Use addWords() to add words to the
205 updateable copy of the global QDawg or to named application 206 updateable copy of the global QDawg or to named application
206 \l{QDawg}s. 207 \l{QDawg}s.
207 208
208 \section1 Quoting 209 \section1 Quoting
209 210
210 The shellQuote() function quotes a string suitable for passing to a 211 The shellQuote() function quotes a string suitable for passing to a
211 shell. The stringQuote() function backslash escapes '\' and '"' 212 shell. The stringQuote() function backslash escapes '\' and '"'
212 characters. 213 characters.
213 214
214 \section1 Hardware 215 \section1 Hardware
215 216
216 The implementation of the writeHWClock() function depends on the AlarmServer 217 The implementation of the writeHWClock() function depends on the AlarmServer
217 implementation. If the AlarmServer is using atd the clock will be synced to 218 implementation. If the AlarmServer is using atd the clock will be synced to
218 hardware. If opie-alarm is used the hardware clock will be synced before 219 hardware. If opie-alarm is used the hardware clock will be synced before
219 suspending the device. opie-alarm is used by iPAQ and Zaurii implementation 220 suspending the device. opie-alarm is used by iPAQ and Zaurii implementation
220 221
221 \ingroup qtopiaemb 222 \ingroup qtopiaemb
222*/ 223*/
223 224
224/*! 225/*!
225 \internal 226 \internal
226*/ 227*/
227Global::Global() 228Global::Global()
228{ 229{
229} 230}
230 231
231/*! 232/*!
232 Returns the unchangeable QDawg that contains general 233 Returns the unchangeable QDawg that contains general
233 words for the current locale. 234 words for the current locale.
234 235
235 \sa addedDawg() 236 \sa addedDawg()
236*/ 237*/
237const QDawg& Global::fixedDawg() 238const QDawg& Global::fixedDawg()
238{ 239{
239 if ( !fixed_dawg ) { 240 if ( !fixed_dawg ) {
240 if ( !docDirCreated ) 241 if ( !docDirCreated )
241 createDocDir(); 242 createDocDir();
242 243
243 fixed_dawg = new QDawg; 244 fixed_dawg = new QDawg;
244 QString dawgfilename = dictDir() + "/dawg"; 245 QString dawgfilename = dictDir() + "/dawg";
245 QString words_lang; 246 QString words_lang;
246 QStringList langs = Global::languageList(); 247 QStringList langs = Global::languageList();
247 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { 248 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
248 QString lang = *it; 249 QString lang = *it;
249 words_lang = dictDir() + "/words." + lang; 250 words_lang = dictDir() + "/words." + lang;
250 QString dawgfilename_lang = dawgfilename + "." + lang; 251 QString dawgfilename_lang = dawgfilename + "." + lang;
251 if ( QFile::exists(dawgfilename_lang) || 252 if ( QFile::exists(dawgfilename_lang) ||
252 QFile::exists(words_lang) ) { 253 QFile::exists(words_lang) ) {
253 dawgfilename = dawgfilename_lang; 254 dawgfilename = dawgfilename_lang;
254 break; 255 break;
255 } 256 }
256 } 257 }
257 QFile dawgfile(dawgfilename); 258 QFile dawgfile(dawgfilename);
258 259
259 if ( !dawgfile.exists() ) { 260 if ( !dawgfile.exists() ) {
260 QString fn = dictDir() + "/words"; 261 QString fn = dictDir() + "/words";
261 if ( QFile::exists(words_lang) ) 262 if ( QFile::exists(words_lang) )
262 fn = words_lang; 263 fn = words_lang;
263 QFile in(fn); 264 QFile in(fn);
264 if ( in.open(IO_ReadOnly) ) { 265 if ( in.open(IO_ReadOnly) ) {
265 fixed_dawg->createFromWords(&in); 266 fixed_dawg->createFromWords(&in);
266 dawgfile.open(IO_WriteOnly); 267 dawgfile.open(IO_WriteOnly);
267 fixed_dawg->write(&dawgfile); 268 fixed_dawg->write(&dawgfile);
268 dawgfile.close(); 269 dawgfile.close();
269 } 270 }
270 } else { 271 } else {
271 fixed_dawg->readFile(dawgfilename); 272 fixed_dawg->readFile(dawgfilename);
272 } 273 }
273 } 274 }
274 275
275 return *fixed_dawg; 276 return *fixed_dawg;
276} 277}
277 278
278/*! 279/*!
279 Returns the changeable QDawg that contains general 280 Returns the changeable QDawg that contains general
280 words for the current locale. 281 words for the current locale.
281 282
282 \sa fixedDawg() 283 \sa fixedDawg()
283*/ 284*/
284const QDawg& Global::addedDawg() 285const QDawg& Global::addedDawg()
@@ -513,306 +514,314 @@ void Global::setDocument( QWidget* receiver, const QString& document )
513 Emitter emitter(receiver,document); 514 Emitter emitter(receiver,document);
514} 515}
515 516
516/*! 517/*!
517 \internal 518 \internal
518*/ 519*/
519bool Global::terminateBuiltin( const QString& n ) 520bool Global::terminateBuiltin( const QString& n )
520{ 521{
521 if (!builtin) 522 if (!builtin)
522 return FALSE; 523 return FALSE;
523 for (int i = 0; builtin[i].file; i++) { 524 for (int i = 0; builtin[i].file; i++) {
524 if ( builtin[i].file == n ) { 525 if ( builtin[i].file == n ) {
525 delete running[i]; 526 delete running[i];
526 return TRUE; 527 return TRUE;
527 } 528 }
528 } 529 }
529 return FALSE; 530 return FALSE;
530} 531}
531 532
532/*! 533/*!
533 \internal 534 \internal
534*/ 535*/
535void Global::terminate( const AppLnk* app ) 536void Global::terminate( const AppLnk* app )
536{ 537{
537 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this 538 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this
538 539
539#ifndef QT_NO_COP 540#ifndef QT_NO_COP
540 QCString channel = "QPE/Application/" + app->exec().utf8(); 541 QCString channel = "QPE/Application/" + app->exec().utf8();
541 if ( QCopChannel::isRegistered(channel) ) { 542 if ( QCopChannel::isRegistered(channel) ) {
542 QCopEnvelope e(channel, "quit()"); 543 QCopEnvelope e(channel, "quit()");
543 } 544 }
544#endif 545#endif
545} 546}
546 547
547/*! 548/*!
548 Low-level function to run command \a c. 549 Low-level function to run command \a c.
549 550
550 \warning Do not use this function. Use execute instead. 551 \warning Do not use this function. Use execute instead.
551 552
552 \sa execute() 553 \sa execute()
553*/ 554*/
554void Global::invoke(const QString &c) 555void Global::invoke(const QString &c)
555{ 556{
556 // Convert the command line in to a list of arguments 557 // Convert the command line in to a list of arguments
557 QStringList list = QStringList::split(QRegExp(" *"),c); 558 QStringList list = QStringList::split(QRegExp(" *"),c);
558 559
559#if !defined(QT_NO_COP) 560#if !defined(QT_NO_COP)
560 QString ap=list[0]; 561 QString ap=list[0];
561 // see if the application is already running 562 // see if the application is already running
562 // XXX should lock file /tmp/qcop-msg-ap 563 // XXX should lock file /tmp/qcop-msg-ap
563 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { 564 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) {
564 // If the channel is already register, the app is already running, so show it. 565 // If the channel is already register, the app is already running, so show it.
565 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } 566 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); }
566 567
567 //QCopEnvelope e("QPE/System", "notBusy(QString)" ); 568 //QCopEnvelope e("QPE/System", "notBusy(QString)" );
568 //e << ap; 569 //e << ap;
569 return; 570 return;
570 } 571 }
571 // XXX should unlock file /tmp/qcop-msg-ap 572 // XXX should unlock file /tmp/qcop-msg-ap
572 //see if it is being started 573 //see if it is being started
573 if ( StartingAppList::isStarting( ap ) ) { 574 if ( StartingAppList::isStarting( ap ) ) {
574 // FIXME take it out for now, since it leads to a much to short showing of wait if 575 // FIXME take it out for now, since it leads to a much to short showing of wait if
575 // some entry is clicked. 576 // some entry is clicked.
576 // Real cause is that ::execute is called twice for document tab. But it would need some larger changes 577 // Real cause is that ::execute is called twice for document tab. But it would need some larger changes
577 // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there 578 // to fix that, and with future syncs with qtopia 1.6 it will change anyway big time since somebody there
578 // had the idea that an apploader belongs to the launcher ... 579 // had the idea that an apploader belongs to the launcher ...
579 //QCopEnvelope e("QPE/System", "notBusy(QString)" ); 580 //QCopEnvelope e("QPE/System", "notBusy(QString)" );
580 //e << ap; 581 //e << ap;
581 return; 582 return;
582 } 583 }
583 584
584#endif 585#endif
585 586
586#ifdef QT_NO_QWS_MULTIPROCESS 587#ifdef QT_NO_QWS_MULTIPROCESS
587 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); 588 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 );
588#else 589#else
589 590
590 QStrList slist; 591 QStrList slist;
591 unsigned int j; 592 unsigned int j;
592 for ( j = 0; j < list.count(); j++ ) 593 for ( j = 0; j < list.count(); j++ )
593 slist.append( list[j].utf8() ); 594 slist.append( list[j].utf8() );
594 595
595 const char **args = new (const char *)[slist.count() + 1]; 596 const char **args = new (const char *)[slist.count() + 1];
596 for ( j = 0; j < slist.count(); j++ ) 597 for ( j = 0; j < slist.count(); j++ )
597 args[j] = slist.at(j); 598 args[j] = slist.at(j);
598 args[j] = NULL; 599 args[j] = NULL;
599 600
600#if !defined(QT_NO_COP) 601#if !defined(QT_NO_COP)
601 // an attempt to show a wait... 602 // an attempt to show a wait...
602 // more logic should be used, but this will be fine for the moment... 603 // more logic should be used, but this will be fine for the moment...
603 QCopEnvelope ( "QPE/System", "busy()" ); 604 QCopEnvelope ( "QPE/System", "busy()" );
604#endif 605#endif
605 606
606#ifdef HAVE_QUICKEXEC 607#ifdef HAVE_QUICKEXEC
607#ifdef Q_OS_MACX 608#ifdef Q_OS_MACX
608 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib"; 609 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib";
609#else 610#else
610 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; 611 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
611#endif 612#endif
612 qDebug("libfile = %s", libexe.latin1() ); 613 qDebug("libfile = %s", libexe.latin1() );
613 if ( QFile::exists( libexe ) ) { 614 if ( QFile::exists( libexe ) ) {
614 qDebug("calling quickexec %s", libexe.latin1() ); 615 qDebug("calling quickexec %s", libexe.latin1() );
615 quickexecv( libexe.utf8().data(), (const char **)args ); 616 quickexecv( libexe.utf8().data(), (const char **)args );
616 } else 617 } else
617#endif 618#endif
618 { 619 {
619 bool success = false; 620 bool success = false;
620 int pfd [2]; 621 int pfd [2];
621 if ( ::pipe ( pfd ) < 0 ) 622 if ( ::pipe ( pfd ) < 0 )
622 pfd [0] = pfd [1] = -1; 623 pfd [0] = pfd [1] = -1;
623 624
624 pid_t pid = ::fork ( ); 625 pid_t pid = ::fork ( );
625 626
626 if ( pid == 0 ) { // child 627 if ( pid == 0 ) { // child
627 for ( int fd = 3; fd < 100; fd++ ) { 628 for ( int fd = 3; fd < 100; fd++ ) {
628 if ( fd != pfd [1] ) 629 if ( fd != pfd [1] )
629 ::close ( fd ); 630 ::close ( fd );
630 } 631 }
631 ::setpgid ( ::getpid ( ), ::getppid ( )); 632 ::setpgid ( ::getpid ( ), ::getppid ( ));
632 633
633 // Closing of fd[1] indicates that the execvp succeeded! 634 // Closing of fd[1] indicates that the execvp succeeded!
634 if ( pfd [1] >= 0 ) 635 if ( pfd [1] >= 0 )
635 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); 636 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
636 637
637 // Try bindir first, so that foo/bar works too 638 // Try bindir first, so that foo/bar works too
638 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); 639 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
639 ::execvp ( args [0], (char * const *) args ); 640 ::execvp ( args [0], (char * const *) args );
640 641
641 char resultByte = 1; 642 char resultByte = 1;
642 if ( pfd [1] >= 0 ) 643 if ( pfd [1] >= 0 )
643 ::write ( pfd [1], &resultByte, 1 ); 644 ::write ( pfd [1], &resultByte, 1 );
644 ::_exit ( -1 ); 645 ::_exit ( -1 );
645 } 646 }
646 else if ( pid > 0 ) { 647 else if ( pid > 0 ) {
647 success = true; 648 success = true;
648 649
649 if ( pfd [1] >= 0 ) 650 if ( pfd [1] >= 0 )
650 ::close ( pfd [1] ); 651 ::close ( pfd [1] );
651 if ( pfd [0] >= 0 ) { 652 if ( pfd [0] >= 0 ) {
652 while ( true ) { 653 while ( true ) {
653 char resultByte; 654 char resultByte;
654 int n = ::read ( pfd [0], &resultByte, 1 ); 655 int n = ::read ( pfd [0], &resultByte, 1 );
655 if ( n == 1 ) { 656 if ( n == 1 ) {
656 success = false; 657 success = false;
657 break; 658 break;
658 } 659 }
659 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) 660 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
660 continue; 661 continue;
661 662
662 break; // success 663 break; // success
663 } 664 }
664 ::close ( pfd [0] ); 665 ::close ( pfd [0] );
665 } 666 }
666 } 667 }
667 if ( success ) 668 if ( success )
668 StartingAppList::add( list[0] ); 669 StartingAppList::add( list[0] );
669 else 670 else
670 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); 671 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
671 } 672 }
672#endif //QT_NO_QWS_MULTIPROCESS 673#endif //QT_NO_QWS_MULTIPROCESS
673} 674}
674 675
675 676
676/*! 677/*!
677 Executes the application identfied by \a c, passing \a 678 Executes the application identfied by \a c, passing \a
678 document if it isn't null. 679 document if it isn't null.
679 680
680 Note that a better approach might be to send a QCop message to the 681 Note that a better approach might be to send a QCop message to the
681 application's QPE/Application/\e{appname} channel. 682 application's QPE/Application/\e{appname} channel.
682*/ 683*/
683void Global::execute( const QString &c, const QString& document ) 684void Global::execute( const QString &c, const QString& document )
684{ 685{
685 // ask the server to do the work 686 // ask the server to do the work
686#if !defined(QT_NO_COP) 687#if !defined(QT_NO_COP)
687 if ( document.isNull() ) { 688 if ( document.isNull() ) {
688 QCopEnvelope e( "QPE/System", "execute(QString)" ); 689 QCopEnvelope e( "QPE/System", "execute(QString)" );
689 e << c; 690 e << c;
690 } else { 691 } else {
691 QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); 692 QCopEnvelope e( "QPE/System", "execute(QString,QString)" );
692 e << c << document; 693 e << c << document;
693 } 694 }
694#endif 695#endif
695 return; 696 return;
696} 697}
697 698
698/*! 699/*!
699 Returns the string \a s with the characters '\', '"', and '$' quoted 700 Returns the string \a s with the characters '\', '"', and '$' quoted
700 by a preceeding '\'. 701 by a preceeding '\'.
701 702
702 \sa stringQuote() 703 \sa stringQuote()
703*/ 704*/
704QString Global::shellQuote(const QString& s) 705QString Global::shellQuote(const QString& s)
705{ 706{
706 QString r="\""; 707 QString r="\"";
707 for (int i=0; i<(int)s.length(); i++) { 708 for (int i=0; i<(int)s.length(); i++) {
708 char c = s[i].latin1(); 709 char c = s[i].latin1();
709 switch (c) { 710 switch (c) {
710 case '\\': case '"': case '$': 711 case '\\': case '"': case '$':
711 r+="\\"; 712 r+="\\";
712 } 713 }
713 r += s[i]; 714 r += s[i];
714 } 715 }
715 r += "\""; 716 r += "\"";
716 return r; 717 return r;
717} 718}
718 719
719/*! 720/*!
720 Returns the string \a s with the characters '\' and '"' quoted by a 721 Returns the string \a s with the characters '\' and '"' quoted by a
721 preceeding '\'. 722 preceeding '\'.
722 723
723 \sa shellQuote() 724 \sa shellQuote()
724*/ 725*/
725QString Global::stringQuote(const QString& s) 726QString Global::stringQuote(const QString& s)
726{ 727{
727 QString r="\""; 728 QString r="\"";
728 for (int i=0; i<(int)s.length(); i++) { 729 for (int i=0; i<(int)s.length(); i++) {
729 char c = s[i].latin1(); 730 char c = s[i].latin1();
730 switch (c) { 731 switch (c) {
731 case '\\': case '"': 732 case '\\': case '"':
732 r+="\\"; 733 r+="\\";
733 } 734 }
734 r += s[i]; 735 r += s[i];
735 } 736 }
736 r += "\""; 737 r += "\"";
737 return r; 738 return r;
738} 739}
739 740
740/*! 741/*!
741 Finds all documents on the system's document directories which 742 Finds all documents on the system's document directories which
742 match the filter \a mimefilter, and appends the resulting DocLnk 743 match the filter \a mimefilter, and appends the resulting DocLnk
743 objects to \a folder. 744 objects to \a folder.
744*/ 745*/
745void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) 746void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter)
746{ 747{
747 QString homedocs = QString(getenv("HOME")) + "/Documents"; 748 QString homedocs = QString(getenv("HOME")) + "/Documents";
748 DocLnkSet d(homedocs,mimefilter); 749 DocLnkSet d(homedocs,mimefilter);
749 folder->appendFrom(d); 750 folder->appendFrom(d);
750 /** let's do intellegint way of searching these files 751 /** let's do intellegint way of searching these files
751 * a) the user don't want to check mediums global 752 * a) the user don't want to check mediums global
752 * b) the user wants to check but use the global options for it 753 * b) the user wants to check but use the global options for it
753 * c) the user wants to check it but not this medium 754 * c) the user wants to check it but not this medium
754 * d) the user wants to check and this medium as well 755 * d) the user wants to check and this medium as well
755 * 756 *
756 * In all cases we need to apply a different mimefilter to 757 * In all cases we need to apply a different mimefilter to
757 * the medium. 758 * the medium.
758 * a) mimefilter.isEmpty() we need to apply the responding filter 759 * a) mimefilter.isEmpty() we need to apply the responding filter
759 * either the global or the one on the medium 760 * either the global or the one on the medium
760 * 761 *
761 * b) mimefilter is set to an application we need to find out if the 762 * b) mimefilter is set to an application we need to find out if the
762 * mimetypes are included in the mime mask of the medium 763 * mimetypes are included in the mime mask of the medium
763 */ 764 */
764 StorageInfo storage; 765 StorageInfo storage;
765 const QList<FileSystem> &fs = storage.fileSystems(); 766 const QList<FileSystem> &fs = storage.fileSystems();
766 QListIterator<FileSystem> it ( fs ); 767 QListIterator<FileSystem> it ( fs );
767 for ( ; it.current(); ++it ) { 768 for ( ; it.current(); ++it ) {
768 if ( (*it)->isRemovable() ) { // let's find out if we should search on it 769 if ( (*it)->isRemovable() ) { // let's find out if we should search on it
769 // this is a candidate look at the cf and see if we should search on it 770 // this is a candidate look at the cf and see if we should search on it
770 QString path = (*it)->path(); 771 QString path = (*it)->path();
771 if( !checkStorage((*it)->path() + "/.opiestorage.cf" ) ) 772 if( !checkStorage((*it)->path() + "/.opiestorage.cf" ) )
772 continue; 773 continue;
773 DocLnkSet ide( path, mimefilter ); 774 Config conf((*it)->path() + "/.opiestorage.cf", Config::File );
774 folder->appendFrom(ide); 775 conf.setGroup("subdirs");
776 QStringList subDirs = conf.readListEntry("subdirs",':');
777 if (subDirs.isEmpty()) {
778 subDirs.append("Documents");
779 }
780 for (unsigned c = 0; c < subDirs.count();++c) {
781 DocLnkSet ide( path+"/"+subDirs[c], mimefilter );
782 folder->appendFrom(ide);
783 }
775 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { 784 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
776 QString path = (*it)->path() + "/Documents"; 785 QString path = (*it)->path() + "/Documents";
777 DocLnkSet ide( path, mimefilter ); 786 DocLnkSet ide( path, mimefilter );
778 folder->appendFrom(ide); 787 folder->appendFrom(ide);
779 } 788 }
780 } 789 }
781} 790}
782 791
783QStringList Global::languageList() 792QStringList Global::languageList()
784{ 793{
785 QString lang = getenv("LANG"); 794 QString lang = getenv("LANG");
786 QStringList langs; 795 QStringList langs;
787 langs.append(lang); 796 langs.append(lang);
788 int i = lang.find("."); 797 int i = lang.find(".");
789 if ( i > 0 ) 798 if ( i > 0 )
790 lang = lang.left( i ); 799 lang = lang.left( i );
791 i = lang.find( "_" ); 800 i = lang.find( "_" );
792 if ( i > 0 ) 801 if ( i > 0 )
793 langs.append(lang.left(i)); 802 langs.append(lang.left(i));
794 return langs; 803 return langs;
795} 804}
796 805
797QStringList Global::helpPath() 806QStringList Global::helpPath()
798{ 807{
799 QString qpeDir = QPEApplication::qpeDir(); 808 QString qpeDir = QPEApplication::qpeDir();
800 QStringList path; 809 QStringList path;
801 QStringList langs = Global::languageList(); 810 QStringList langs = Global::languageList();
802 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { 811 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) {
803 QString lang = *it; 812 QString lang = *it;
804 if ( !lang.isEmpty() ) 813 if ( !lang.isEmpty() )
805 path += qpeDir + "/help/" + lang + "/html"; 814 path += qpeDir + "/help/" + lang + "/html";
806 } 815 }
807 path += qpeDir + "/pics"; 816 path += qpeDir + "/pics";
808 path += qpeDir + "/help/html"; 817 path += qpeDir + "/help/html";
809 /* we even put english into the en dir so try it as fallback as well for opie */ 818 /* we even put english into the en dir so try it as fallback as well for opie */
810 path += qpeDir + "/help/en/html"; 819 path += qpeDir + "/help/en/html";
811 path += qpeDir + "/docs"; 820 path += qpeDir + "/docs";
812 821
813 822
814 return path; 823 return path;
815} 824}
816 825
817 826
818#include "global.moc" 827#include "global.moc"