00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define QTOPIA_INTERNAL_LANGLIST
00021 #include <qpe/qpedebug.h>
00022 #include <qpe/global.h>
00023 #include <qpe/qdawg.h>
00024 #include <qpe/qpeapplication.h>
00025 #include <qpe/resource.h>
00026 #include <qpe/storage.h>
00027 #include <qpe/applnk.h>
00028 #include <qpe/qcopenvelope_qws.h>
00029
00030 #include <qfile.h>
00031 #include <qlabel.h>
00032 #include <qtimer.h>
00033 #include <qmap.h>
00034 #include <qdict.h>
00035 #include <qdir.h>
00036 #include <qmessagebox.h>
00037 #include <qregexp.h>
00038
00039 #include <stdlib.h>
00040 #include <sys/stat.h>
00041 #include <sys/wait.h>
00042 #include <sys/types.h>
00043 #include <fcntl.h>
00044 #include <unistd.h>
00045 #include <errno.h>
00046
00047 #include <qwindowsystem_qws.h>
00048 #include <qdatetime.h>
00049
00050 #include <qfile.h>
00051
00052 namespace {
00053
00054 bool checkStorage(const QString &path ){
00055 QFile file(path );
00056 if(!file.open(IO_ReadOnly ) )
00057 return true;
00058
00059 QByteArray array = file.readAll();
00060 QStringList list = QStringList::split('\n', QString( array ) );
00061 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){
00062 if( (*it).startsWith("autocheck = 0" ) ){
00063 return false;
00064 }else if( (*it).startsWith("autocheck = 1" ) ){
00065 return true;
00066 }
00067 }
00068 return true;
00069 }
00070 }
00071
00072
00073
00074 class Emitter : public QObject {
00075 Q_OBJECT
00076 public:
00077 Emitter( QWidget* receiver, const QString& document )
00078 {
00079 connect(this, SIGNAL(setDocument(const QString&)),
00080 receiver, SLOT(setDocument(const QString&)));
00081 emit setDocument(document);
00082 disconnect(this, SIGNAL(setDocument(const QString&)),
00083 receiver, SLOT(setDocument(const QString&)));
00084 }
00085
00086 signals:
00087 void setDocument(const QString&);
00088 };
00089
00090
00091 class StartingAppList : public QObject {
00092 Q_OBJECT
00093 public:
00094 static void add( const QString& name );
00095 static bool isStarting( const QString name );
00096 private slots:
00097 void handleNewChannel( const QString &);
00098 private:
00099 StartingAppList( QObject *parent=0, const char* name=0 ) ;
00100
00101 QDict<QTime> dict;
00102 static StartingAppList *appl;
00103 };
00104
00105 StartingAppList* StartingAppList::appl = 0;
00106
00107 StartingAppList::StartingAppList( QObject *parent, const char* name )
00108 :QObject( parent, name )
00109 {
00110 #if QT_VERSION >= 232 && defined(QWS)
00111 connect( qwsServer, SIGNAL( newChannel(const QString&)),
00112 this, SLOT( handleNewChannel(const QString&)) );
00113 #endif
00114 dict.setAutoDelete( TRUE );
00115 }
00116
00117 void StartingAppList::add( const QString& name )
00118 {
00119 #if QT_VERSION >= 232 && !defined(QT_NO_COP)
00120 if ( !appl )
00121 appl = new StartingAppList;
00122 QTime *t = new QTime;
00123 t->start();
00124 appl->dict.insert( "QPE/Application/" + name, t );
00125 #endif
00126 }
00127
00128 bool StartingAppList::isStarting( const QString name )
00129 {
00130 #if QT_VERSION >= 232 && !defined(QT_NO_COP)
00131 if ( appl ) {
00132 QTime *t = appl->dict.find( "QPE/Application/" + name );
00133 if ( !t )
00134 return FALSE;
00135 if ( t->elapsed() > 10000 ) {
00136
00137 appl->dict.remove( "QPE/Application/" + name );
00138 return FALSE;
00139 }
00140 return TRUE;
00141 }
00142 #endif
00143 return FALSE;
00144 }
00145
00146 void StartingAppList::handleNewChannel( const QString & name )
00147 {
00148 #if QT_VERSION >= 232 && !defined(QT_NO_COP)
00149 dict.remove( name );
00150 #endif
00151 }
00152
00153 static bool docDirCreated = FALSE;
00154 static QDawg* fixed_dawg = 0;
00155 static QDict<QDawg> *named_dawg = 0;
00156
00157 static QString qpeDir()
00158 {
00159 QString dir = getenv("OPIEDIR");
00160 if ( dir.isEmpty() ) dir = "..";
00161 return dir;
00162 }
00163
00164 static QString dictDir()
00165 {
00166 return qpeDir() + "/etc/dict";
00167 }
00168
00227 Global::Global()
00228 {
00229 }
00230
00237 const QDawg& Global::fixedDawg()
00238 {
00239 if ( !fixed_dawg ) {
00240 if ( !docDirCreated )
00241 createDocDir();
00242
00243 fixed_dawg = new QDawg;
00244 QString dawgfilename = dictDir() + "/dawg";
00245 QString words_lang;
00246 QStringList langs = Global::languageList();
00247 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
00248 QString lang = *it;
00249 words_lang = dictDir() + "/words." + lang;
00250 QString dawgfilename_lang = dawgfilename + "." + lang;
00251 if ( QFile::exists(dawgfilename_lang) ||
00252 QFile::exists(words_lang) ) {
00253 dawgfilename = dawgfilename_lang;
00254 break;
00255 }
00256 }
00257 QFile dawgfile(dawgfilename);
00258
00259 if ( !dawgfile.exists() ) {
00260 QString fn = dictDir() + "/words";
00261 if ( QFile::exists(words_lang) )
00262 fn = words_lang;
00263 QFile in(fn);
00264 if ( in.open(IO_ReadOnly) ) {
00265 fixed_dawg->createFromWords(&in);
00266 dawgfile.open(IO_WriteOnly);
00267 fixed_dawg->write(&dawgfile);
00268 dawgfile.close();
00269 }
00270 } else {
00271 fixed_dawg->readFile(dawgfilename);
00272 }
00273 }
00274
00275 return *fixed_dawg;
00276 }
00277
00284 const QDawg& Global::addedDawg()
00285 {
00286 return dawg("local");
00287 }
00288
00295 const QDawg& Global::dawg(const QString& name)
00296 {
00297 createDocDir();
00298 if ( !named_dawg )
00299 named_dawg = new QDict<QDawg>;
00300 QDawg* r = named_dawg->find(name);
00301 if ( !r ) {
00302 r = new QDawg;
00303 named_dawg->insert(name,r);
00304 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg";
00305 QFile dawgfile(dawgfilename);
00306 if ( dawgfile.open(IO_ReadOnly) )
00307 r->readFile(dawgfilename);
00308 }
00309 return *r;
00310 }
00311
00320 void Global::addWords(const QStringList& wordlist)
00321 {
00322 addWords("local",wordlist);
00323 }
00324
00333 void Global::addWords(const QString& dictname, const QStringList& wordlist)
00334 {
00335 QDawg& d = (QDawg&)dawg(dictname);
00336 QStringList all = d.allWords() + wordlist;
00337 d.createFromWords(all);
00338
00339 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg";
00340 QFile dawgfile(dawgfilename);
00341 if ( dawgfile.open(IO_WriteOnly) ) {
00342 d.write(&dawgfile);
00343 dawgfile.close();
00344 }
00345
00346
00347
00348
00349 }
00350
00351
00359 QString Global::applicationFileName(const QString& appname, const QString& filename)
00360 {
00361 QDir d;
00362 QString r = getenv("HOME");
00363 r += "/Applications/";
00364 if ( !QFile::exists( r ) )
00365 if ( d.mkdir(r) == false )
00366 return QString::null;
00367 r += appname;
00368 if ( !QFile::exists( r ) )
00369 if ( d.mkdir(r) == false )
00370 return QString::null;
00371 r += "/"; r += filename;
00372 return r;
00373 }
00374
00378 void Global::createDocDir()
00379 {
00380 if ( !docDirCreated ) {
00381 docDirCreated = TRUE;
00382 mkdir( QPEApplication::documentDir().latin1(), 0755 );
00383 }
00384 }
00385
00386
00391 void Global::statusMessage(const QString& message)
00392 {
00393 #if !defined(QT_NO_COP)
00394 QCopEnvelope e( "QPE/TaskBar", "message(QString)" );
00395 e << message;
00396 #endif
00397 }
00398
00402 void Global::applyStyle()
00403 {
00404 #if !defined(QT_NO_COP)
00405 QCopChannel::send( "QPE/System", "applyStyle()" );
00406 #else
00407 ((QPEApplication *)qApp)->applyStyle();
00408 #endif
00409 }
00410
00414 QWidget *Global::shutdown( bool )
00415 {
00416 #if !defined(QT_NO_COP)
00417 QCopChannel::send( "QPE/System", "shutdown()" );
00418 #endif
00419 return 0;
00420 }
00421
00425 QWidget *Global::restart( bool )
00426 {
00427 #if !defined(QT_NO_COP)
00428 QCopChannel::send( "QPE/System", "restart()" );
00429 #endif
00430 return 0;
00431 }
00432
00443 void Global::showInputMethod()
00444 {
00445 #if !defined(QT_NO_COP)
00446 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" );
00447 #endif
00448 }
00449
00458 void Global::hideInputMethod()
00459 {
00460 #if !defined(QT_NO_COP)
00461 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" );
00462 #endif
00463 }
00464
00465
00469 bool Global::isBuiltinCommand( const QString &name )
00470 {
00471 if(!builtin)
00472 return FALSE;
00473 for (int i = 0; builtin[i].file; i++) {
00474 if ( builtin[i].file == name ) {
00475 return TRUE;
00476 }
00477 }
00478 return FALSE;
00479 }
00480
00481 Global::Command* Global::builtin=0;
00482 QGuardedPtr<QWidget> *Global::running=0;
00483
00493 void Global::setBuiltinCommands( Command* list )
00494 {
00495 if ( running )
00496 delete [] running;
00497
00498 builtin = list;
00499 int count = 0;
00500 if (!builtin)
00501 return;
00502 while ( builtin[count].file )
00503 count++;
00504
00505 running = new QGuardedPtr<QWidget> [ count ];
00506 }
00507
00511 void Global::setDocument( QWidget* receiver, const QString& document )
00512 {
00513 Emitter emitter(receiver,document);
00514 }
00515
00519 bool Global::terminateBuiltin( const QString& n )
00520 {
00521 if (!builtin)
00522 return FALSE;
00523 for (int i = 0; builtin[i].file; i++) {
00524 if ( builtin[i].file == n ) {
00525 delete running[i];
00526 return TRUE;
00527 }
00528 }
00529 return FALSE;
00530 }
00531
00535 void Global::terminate( const AppLnk* app )
00536 {
00537
00538
00539 #ifndef QT_NO_COP
00540 QCString channel = "QPE/Application/" + app->exec().utf8();
00541 if ( QCopChannel::isRegistered(channel) ) {
00542 QCopEnvelope e(channel, "quit()");
00543 }
00544 #endif
00545 }
00546
00554 void Global::invoke(const QString &c)
00555 {
00556
00557 QStringList list = QStringList::split(QRegExp(" *"),c);
00558
00559 #if !defined(QT_NO_COP)
00560 QString ap=list[0];
00561
00562
00563 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) {
00564
00565 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); }
00566
00567
00568
00569 return;
00570 }
00571
00572
00573 if ( StartingAppList::isStarting( ap ) ) {
00574
00575
00576
00577
00578
00579
00580
00581 return;
00582 }
00583
00584 #endif
00585
00586 #ifdef QT_NO_QWS_MULTIPROCESS
00587 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 );
00588 #else
00589
00590 QStrList slist;
00591 unsigned int j;
00592 for ( j = 0; j < list.count(); j++ )
00593 slist.append( list[j].utf8() );
00594
00595 const char **args = new (const char *)[slist.count() + 1];
00596 for ( j = 0; j < slist.count(); j++ )
00597 args[j] = slist.at(j);
00598 args[j] = NULL;
00599
00600 #if !defined(QT_NO_COP)
00601
00602
00603 QCopEnvelope ( "QPE/System", "busy()" );
00604 #endif
00605
00606 #ifdef HAVE_QUICKEXEC
00607 #ifdef Q_OS_MACX
00608 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib";
00609 #else
00610 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
00611 #endif
00612 qDebug("libfile = %s", libexe.latin1() );
00613 if ( QFile::exists( libexe ) ) {
00614 qDebug("calling quickexec %s", libexe.latin1() );
00615 quickexecv( libexe.utf8().data(), (const char **)args );
00616 } else
00617 #endif
00618 {
00619 bool success = false;
00620 int pfd [2];
00621 if ( ::pipe ( pfd ) < 0 )
00622 pfd [0] = pfd [1] = -1;
00623
00624 pid_t pid = ::fork ( );
00625
00626 if ( pid == 0 ) {
00627 for ( int fd = 3; fd < 100; fd++ ) {
00628 if ( fd != pfd [1] )
00629 ::close ( fd );
00630 }
00631 ::setpgid ( ::getpid ( ), ::getppid ( ));
00632
00633
00634 if ( pfd [1] >= 0 )
00635 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
00636
00637
00638 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
00639 ::execvp ( args [0], (char * const *) args );
00640
00641 char resultByte = 1;
00642 if ( pfd [1] >= 0 )
00643 ::write ( pfd [1], &resultByte, 1 );
00644 ::_exit ( -1 );
00645 }
00646 else if ( pid > 0 ) {
00647 success = true;
00648
00649 if ( pfd [1] >= 0 )
00650 ::close ( pfd [1] );
00651 if ( pfd [0] >= 0 ) {
00652 while ( true ) {
00653 char resultByte;
00654 int n = ::read ( pfd [0], &resultByte, 1 );
00655 if ( n == 1 ) {
00656 success = false;
00657 break;
00658 }
00659 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
00660 continue;
00661
00662 break;
00663 }
00664 ::close ( pfd [0] );
00665 }
00666 }
00667 if ( success )
00668 StartingAppList::add( list[0] );
00669 else
00670 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
00671 }
00672 #endif //QT_NO_QWS_MULTIPROCESS
00673 }
00674
00675
00683 void Global::execute( const QString &c, const QString& document )
00684 {
00685
00686 #if !defined(QT_NO_COP)
00687 if ( document.isNull() ) {
00688 QCopEnvelope e( "QPE/System", "execute(QString)" );
00689 e << c;
00690 } else {
00691 QCopEnvelope e( "QPE/System", "execute(QString,QString)" );
00692 e << c << document;
00693 }
00694 #endif
00695 return;
00696 }
00697
00704 QString Global::shellQuote(const QString& s)
00705 {
00706 QString r="\"";
00707 for (int i=0; i<(int)s.length(); i++) {
00708 char c = s[i].latin1();
00709 switch (c) {
00710 case '\\': case '"': case '$':
00711 r+="\\";
00712 }
00713 r += s[i];
00714 }
00715 r += "\"";
00716 return r;
00717 }
00718
00725 QString Global::stringQuote(const QString& s)
00726 {
00727 QString r="\"";
00728 for (int i=0; i<(int)s.length(); i++) {
00729 char c = s[i].latin1();
00730 switch (c) {
00731 case '\\': case '"':
00732 r+="\\";
00733 }
00734 r += s[i];
00735 }
00736 r += "\"";
00737 return r;
00738 }
00739
00745 void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter)
00746 {
00747 QString homedocs = QString(getenv("HOME")) + "/Documents";
00748 DocLnkSet d(homedocs,mimefilter);
00749 folder->appendFrom(d);
00764 StorageInfo storage;
00765 const QList<FileSystem> &fs = storage.fileSystems();
00766 QListIterator<FileSystem> it ( fs );
00767 for ( ; it.current(); ++it ) {
00768 if ( (*it)->isRemovable() ) {
00769
00770 QString path = (*it)->path();
00771 if( !checkStorage((*it)->path() + "/.opiestorage.cf" ) )
00772 continue;
00773 DocLnkSet ide( path, mimefilter );
00774 folder->appendFrom(ide);
00775 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
00776 QString path = (*it)->path() + "/Documents";
00777 DocLnkSet ide( path, mimefilter );
00778 folder->appendFrom(ide);
00779 }
00780 }
00781 }
00782
00783 QStringList Global::languageList()
00784 {
00785 QString lang = getenv("LANG");
00786 QStringList langs;
00787 langs.append(lang);
00788 int i = lang.find(".");
00789 if ( i > 0 )
00790 lang = lang.left( i );
00791 i = lang.find( "_" );
00792 if ( i > 0 )
00793 langs.append(lang.left(i));
00794 return langs;
00795 }
00796
00797 QStringList Global::helpPath()
00798 {
00799 QString qpeDir = QPEApplication::qpeDir();
00800 QStringList path;
00801 QStringList langs = Global::languageList();
00802 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) {
00803 QString lang = *it;
00804 if ( !lang.isEmpty() )
00805 path += qpeDir + "/help/" + lang + "/html";
00806 }
00807 path += qpeDir + "/pics";
00808 path += qpeDir + "/help/html";
00809
00810 path += qpeDir + "/help/en/html";
00811 path += qpeDir + "/docs";
00812
00813
00814 return path;
00815 }
00816
00817
00818 #include "global.moc"