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 #include <qpe/config.h>
00030
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
00051
00052
00053 class Emitter : public QObject {
00054 Q_OBJECT
00055 public:
00056 Emitter( QWidget* receiver, const QString& document )
00057 {
00058 connect(this, SIGNAL(setDocument(const QString&)),
00059 receiver, SLOT(setDocument(const QString&)));
00060 emit setDocument(document);
00061 disconnect(this, SIGNAL(setDocument(const QString&)),
00062 receiver, SLOT(setDocument(const QString&)));
00063 }
00064
00065 signals:
00066 void setDocument(const QString&);
00067 };
00068
00069
00070 class StartingAppList : public QObject {
00071 Q_OBJECT
00072 public:
00073 static void add( const QString& name );
00074 static bool isStarting( const QString name );
00075 private slots:
00076 void handleNewChannel( const QString &);
00077 private:
00078 StartingAppList( QObject *parent=0, const char* name=0 ) ;
00079
00080 QDict<QTime> dict;
00081 static StartingAppList *appl;
00082 };
00083
00084 StartingAppList* StartingAppList::appl = 0;
00085
00086 StartingAppList::StartingAppList( QObject *parent, const char* name )
00087 :QObject( parent, name )
00088 {
00089 #if QT_VERSION >= 232 && defined(QWS)
00090 connect( qwsServer, SIGNAL( newChannel(const QString&)),
00091 this, SLOT( handleNewChannel(const QString&)) );
00092 #endif
00093 dict.setAutoDelete( TRUE );
00094 }
00095
00096 void StartingAppList::add( const QString& name )
00097 {
00098 #if QT_VERSION >= 232 && !defined(QT_NO_COP)
00099 if ( !appl )
00100 appl = new StartingAppList;
00101 QTime *t = new QTime;
00102 t->start();
00103 appl->dict.insert( "QPE/Application/" + name, t );
00104 #endif
00105 }
00106
00107 bool StartingAppList::isStarting( const QString name )
00108 {
00109 #if QT_VERSION >= 232 && !defined(QT_NO_COP)
00110 if ( appl ) {
00111 QTime *t = appl->dict.find( "QPE/Application/" + name );
00112 if ( !t )
00113 return FALSE;
00114 if ( t->elapsed() > 10000 ) {
00115
00116 appl->dict.remove( "QPE/Application/" + name );
00117 return FALSE;
00118 }
00119 return TRUE;
00120 }
00121 #endif
00122 return FALSE;
00123 }
00124
00125 void StartingAppList::handleNewChannel( const QString & name )
00126 {
00127 #if QT_VERSION >= 232 && !defined(QT_NO_COP)
00128 dict.remove( name );
00129 #endif
00130 }
00131
00132 static bool docDirCreated = FALSE;
00133 static QDawg* fixed_dawg = 0;
00134 static QDict<QDawg> *named_dawg = 0;
00135
00136 static QString qpeDir()
00137 {
00138 QString dir = getenv("OPIEDIR");
00139 if ( dir.isEmpty() ) dir = "..";
00140 return dir;
00141 }
00142
00143 static QString dictDir()
00144 {
00145 return qpeDir() + "/etc/dict";
00146 }
00147
00206 Global::Global()
00207 {
00208 }
00209
00216 const QDawg& Global::fixedDawg()
00217 {
00218 if ( !fixed_dawg ) {
00219 if ( !docDirCreated )
00220 createDocDir();
00221
00222 fixed_dawg = new QDawg;
00223 QString dawgfilename = dictDir() + "/dawg";
00224 QString words_lang;
00225 QStringList langs = Global::languageList();
00226 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
00227 QString lang = *it;
00228 words_lang = dictDir() + "/words." + lang;
00229 QString dawgfilename_lang = dawgfilename + "." + lang;
00230 if ( QFile::exists(dawgfilename_lang) ||
00231 QFile::exists(words_lang) ) {
00232 dawgfilename = dawgfilename_lang;
00233 break;
00234 }
00235 }
00236 QFile dawgfile(dawgfilename);
00237
00238 if ( !dawgfile.exists() ) {
00239 QString fn = dictDir() + "/words";
00240 if ( QFile::exists(words_lang) )
00241 fn = words_lang;
00242 QFile in(fn);
00243 if ( in.open(IO_ReadOnly) ) {
00244 fixed_dawg->createFromWords(&in);
00245 dawgfile.open(IO_WriteOnly);
00246 fixed_dawg->write(&dawgfile);
00247 dawgfile.close();
00248 }
00249 } else {
00250 fixed_dawg->readFile(dawgfilename);
00251 }
00252 }
00253
00254 return *fixed_dawg;
00255 }
00256
00263 const QDawg& Global::addedDawg()
00264 {
00265 return dawg("local");
00266 }
00267
00274 const QDawg& Global::dawg(const QString& name)
00275 {
00276 createDocDir();
00277 if ( !named_dawg )
00278 named_dawg = new QDict<QDawg>;
00279 QDawg* r = named_dawg->find(name);
00280 if ( !r ) {
00281 r = new QDawg;
00282 named_dawg->insert(name,r);
00283 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg";
00284 QFile dawgfile(dawgfilename);
00285 if ( dawgfile.open(IO_ReadOnly) )
00286 r->readFile(dawgfilename);
00287 }
00288 return *r;
00289 }
00290
00299 void Global::addWords(const QStringList& wordlist)
00300 {
00301 addWords("local",wordlist);
00302 }
00303
00312 void Global::addWords(const QString& dictname, const QStringList& wordlist)
00313 {
00314 QDawg& d = (QDawg&)dawg(dictname);
00315 QStringList all = d.allWords() + wordlist;
00316 d.createFromWords(all);
00317
00318 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg";
00319 QFile dawgfile(dawgfilename);
00320 if ( dawgfile.open(IO_WriteOnly) ) {
00321 d.write(&dawgfile);
00322 dawgfile.close();
00323 }
00324
00325
00326
00327
00328 }
00329
00330
00338 QString Global::applicationFileName(const QString& appname, const QString& filename)
00339 {
00340 QDir d;
00341 QString r = getenv("HOME");
00342 r += "/Applications/";
00343 if ( !QFile::exists( r ) )
00344 if ( d.mkdir(r) == false )
00345 return QString::null;
00346 r += appname;
00347 if ( !QFile::exists( r ) )
00348 if ( d.mkdir(r) == false )
00349 return QString::null;
00350 r += "/"; r += filename;
00351 return r;
00352 }
00353
00357 void Global::createDocDir()
00358 {
00359 if ( !docDirCreated ) {
00360 docDirCreated = TRUE;
00361 mkdir( QPEApplication::documentDir().latin1(), 0755 );
00362 }
00363 }
00364
00365
00370 void Global::statusMessage(const QString& message)
00371 {
00372 #if !defined(QT_NO_COP)
00373 QCopEnvelope e( "QPE/TaskBar", "message(QString)" );
00374 e << message;
00375 #endif
00376 }
00377
00381 void Global::applyStyle()
00382 {
00383 #if !defined(QT_NO_COP)
00384 QCopChannel::send( "QPE/System", "applyStyle()" );
00385 #else
00386 ((QPEApplication *)qApp)->applyStyle();
00387 #endif
00388 }
00389
00393 QWidget *Global::shutdown( bool )
00394 {
00395 #if !defined(QT_NO_COP)
00396 QCopChannel::send( "QPE/System", "shutdown()" );
00397 #endif
00398 return 0;
00399 }
00400
00404 QWidget *Global::restart( bool )
00405 {
00406 #if !defined(QT_NO_COP)
00407 QCopChannel::send( "QPE/System", "restart()" );
00408 #endif
00409 return 0;
00410 }
00411
00422 void Global::showInputMethod()
00423 {
00424 #if !defined(QT_NO_COP)
00425 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" );
00426 #endif
00427 }
00428
00437 void Global::hideInputMethod()
00438 {
00439 #if !defined(QT_NO_COP)
00440 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" );
00441 #endif
00442 }
00443
00444
00448 bool Global::isBuiltinCommand( const QString &name )
00449 {
00450 if(!builtin)
00451 return FALSE;
00452 for (int i = 0; builtin[i].file; i++) {
00453 if ( builtin[i].file == name ) {
00454 return TRUE;
00455 }
00456 }
00457 return FALSE;
00458 }
00459
00460 Global::Command* Global::builtin=0;
00461 QGuardedPtr<QWidget> *Global::running=0;
00462
00472 void Global::setBuiltinCommands( Command* list )
00473 {
00474 if ( running )
00475 delete [] running;
00476
00477 builtin = list;
00478 int count = 0;
00479 if (!builtin)
00480 return;
00481 while ( builtin[count].file )
00482 count++;
00483
00484 running = new QGuardedPtr<QWidget> [ count ];
00485 }
00486
00490 void Global::setDocument( QWidget* receiver, const QString& document )
00491 {
00492 Emitter emitter(receiver,document);
00493 }
00494
00498 bool Global::terminateBuiltin( const QString& n )
00499 {
00500 if (!builtin)
00501 return FALSE;
00502 for (int i = 0; builtin[i].file; i++) {
00503 if ( builtin[i].file == n ) {
00504 delete running[i];
00505 return TRUE;
00506 }
00507 }
00508 return FALSE;
00509 }
00510
00514 void Global::terminate( const AppLnk* app )
00515 {
00516
00517
00518 #ifndef QT_NO_COP
00519 QCString channel = "QPE/Application/" + app->exec().utf8();
00520 if ( QCopChannel::isRegistered(channel) ) {
00521 QCopEnvelope e(channel, "quit()");
00522 }
00523 #endif
00524 }
00525
00533 void Global::invoke(const QString &c)
00534 {
00535
00536 QStringList list = QStringList::split(QRegExp(" *"),c);
00537
00538 #if !defined(QT_NO_COP)
00539 QString ap=list[0];
00540
00541
00542 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) {
00543
00544 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); }
00545
00546
00547
00548 return;
00549 }
00550
00551
00552 if ( StartingAppList::isStarting( ap ) ) {
00553
00554
00555
00556
00557
00558
00559
00560 return;
00561 }
00562
00563 #endif
00564
00565 #ifdef QT_NO_QWS_MULTIPROCESS
00566 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 );
00567 #else
00568
00569 QStrList slist;
00570 unsigned int j;
00571 for ( j = 0; j < list.count(); j++ )
00572 slist.append( list[j].utf8() );
00573
00574 const char **args = new const char *[slist.count() + 1];
00575 for ( j = 0; j < slist.count(); j++ )
00576 args[j] = slist.at(j);
00577 args[j] = NULL;
00578
00579 #if !defined(QT_NO_COP)
00580
00581
00582 QCopEnvelope ( "QPE/System", "busy()" );
00583 #endif
00584
00585 #ifdef HAVE_QUICKEXEC
00586 #ifdef Q_OS_MACX
00587 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".dylib";
00588 #else
00589 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
00590 #endif
00591 qDebug("libfile = %s", libexe.latin1() );
00592 if ( QFile::exists( libexe ) ) {
00593 qDebug("calling quickexec %s", libexe.latin1() );
00594 quickexecv( libexe.utf8().data(), (const char **)args );
00595 } else
00596 #endif
00597 {
00598 bool success = false;
00599 int pfd [2];
00600 if ( ::pipe ( pfd ) < 0 )
00601 pfd [0] = pfd [1] = -1;
00602
00603 pid_t pid = ::fork ( );
00604
00605 if ( pid == 0 ) {
00606 for ( int fd = 3; fd < 100; fd++ ) {
00607 if ( fd != pfd [1] )
00608 ::close ( fd );
00609 }
00610 ::setpgid ( ::getpid ( ), ::getppid ( ));
00611
00612
00613 if ( pfd [1] >= 0 )
00614 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
00615
00616
00617 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
00618 ::execvp ( args [0], (char * const *) args );
00619
00620 char resultByte = 1;
00621 if ( pfd [1] >= 0 )
00622 ::write ( pfd [1], &resultByte, 1 );
00623 ::_exit ( -1 );
00624 }
00625 else if ( pid > 0 ) {
00626 success = true;
00627
00628 if ( pfd [1] >= 0 )
00629 ::close ( pfd [1] );
00630 if ( pfd [0] >= 0 ) {
00631 while ( true ) {
00632 char resultByte;
00633 int n = ::read ( pfd [0], &resultByte, 1 );
00634 if ( n == 1 ) {
00635 success = false;
00636 break;
00637 }
00638 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
00639 continue;
00640
00641 break;
00642 }
00643 ::close ( pfd [0] );
00644 }
00645 }
00646 if ( success )
00647 StartingAppList::add( list[0] );
00648 else
00649 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
00650 }
00651 #endif //QT_NO_QWS_MULTIPROCESS
00652 }
00653
00654
00662 void Global::execute( const QString &c, const QString& document )
00663 {
00664
00665 #if !defined(QT_NO_COP)
00666 if ( document.isNull() ) {
00667 QCopEnvelope e( "QPE/System", "execute(QString)" );
00668 e << c;
00669 } else {
00670 QCopEnvelope e( "QPE/System", "execute(QString,QString)" );
00671 e << c << document;
00672 }
00673 #endif
00674 return;
00675 }
00676
00683 QString Global::shellQuote(const QString& s)
00684 {
00685 QString r="\"";
00686 for (int i=0; i<(int)s.length(); i++) {
00687 char c = s[i].latin1();
00688 switch (c) {
00689 case '\\': case '"': case '$':
00690 r+="\\";
00691 }
00692 r += s[i];
00693 }
00694 r += "\"";
00695 return r;
00696 }
00697
00704 QString Global::stringQuote(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 '"':
00711 r+="\\";
00712 }
00713 r += s[i];
00714 }
00715 r += "\"";
00716 return r;
00717 }
00718
00724 void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter)
00725 {
00726 QString homedocs = QString(getenv("HOME")) + "/Documents";
00727 DocLnkSet d(homedocs,mimefilter);
00728 folder->appendFrom(d);
00743 StorageInfo storage;
00744 const QList<FileSystem> &fs = storage.fileSystems();
00745 QListIterator<FileSystem> it ( fs );
00746 for ( ; it.current(); ++it ) {
00747 if ( (*it)->isRemovable() ) {
00748
00749 QString path = (*it)->path();
00750 Config conf((*it)->path() + "/.opiestorage.cf", Config::File );
00751 conf.setGroup("main");
00752 if (!conf.readBoolEntry("check",true)) {
00753 continue;
00754 }
00755 conf.setGroup("subdirs");
00756 if (conf.readBoolEntry("wholemedia",true)) {
00757 DocLnkSet ide( path,mimefilter);
00758 folder->appendFrom(ide);
00759 } else {
00760 QStringList subDirs = conf.readListEntry("subdirs",':');
00761 if (subDirs.isEmpty()) {
00762 subDirs.append("Documents");
00763 }
00764 for (unsigned c = 0; c < subDirs.count();++c) {
00765 DocLnkSet ide( path+"/"+subDirs[c], mimefilter );
00766 folder->appendFrom(ide);
00767 }
00768 }
00769 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
00770 QString path = (*it)->path() + "/Documents";
00771 DocLnkSet ide( path, mimefilter );
00772 folder->appendFrom(ide);
00773 }
00774 }
00775 }
00776
00777 QStringList Global::languageList()
00778 {
00779 QString lang = getenv("LANG");
00780 QStringList langs;
00781 langs.append(lang);
00782 int i = lang.find(".");
00783 if ( i > 0 )
00784 lang = lang.left( i );
00785 i = lang.find( "_" );
00786 if ( i > 0 )
00787 langs.append(lang.left(i));
00788 return langs;
00789 }
00790
00791 QStringList Global::helpPath()
00792 {
00793 QString qpeDir = QPEApplication::qpeDir();
00794 QStringList path;
00795 QStringList langs = Global::languageList();
00796 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) {
00797 QString lang = *it;
00798 if ( !lang.isEmpty() )
00799 path += qpeDir + "/help/" + lang + "/html";
00800 }
00801 path += qpeDir + "/pics";
00802 path += qpeDir + "/help/html";
00803
00804 path += qpeDir + "/help/en/html";
00805 path += qpeDir + "/docs";
00806
00807
00808 return path;
00809 }
00810
00811
00812 #include "global.moc"