00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define QTOPIA_INTERNAL_MIMEEXT
00022 #define QTOPIA_INTERNAL_PRELOADACCESS
00023 #define QTOPIA_INTERNAL_APPLNKASSIGN
00024
00025 #include "applnk.h"
00026
00027 #include <qpe/qpeapplication.h>
00028 #include <qpe/categories.h>
00029 #include <qpe/categoryselect.h>
00030 #include <qpe/qcopenvelope_qws.h>
00031 #include <qpe/global.h>
00032 #include <qpe/mimetype.h>
00033 #include <qpe/config.h>
00034 #include <qpe/storage.h>
00035 #include <qpe/resource.h>
00036
00037 #include <qdict.h>
00038 #include <qdir.h>
00039 #include <qregexp.h>
00040
00041 #include <qgfx_qws.h>
00042
00043 #include <stdlib.h>
00044
00045 int AppLnk::lastId = 5000;
00046
00047 static int smallSize = 14;
00048 static int bigSize = 32;
00049
00050 static QString safeFileName(const QString& n)
00051 {
00052 QString safename=n;
00053 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_");
00054 safename.replace(QRegExp("^[^A-Za-z]*"),"");
00055 if ( safename.isEmpty() )
00056 safename = "_";
00057 return safename;
00058 }
00059
00060 static bool prepareDirectories(const QString& lf)
00061 {
00062 if ( !QFile::exists(lf) ) {
00063
00064 QFileInfo fi(lf);
00065 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
00066 return FALSE;
00067 }
00068 return TRUE;
00069 }
00070
00071 class AppLnkPrivate
00072 {
00073 public:
00074
00075 enum Size {Normal = 0, Big };
00076 AppLnkPrivate() {
00077
00078
00079 QPixmap pix;
00080 mPixmaps.insert(0, pix );
00081 mPixmaps.insert(1, pix);
00082 }
00083
00084 QStringList mCatList;
00085 QArray<int> mCat;
00086 QMap<int, QPixmap> mPixmaps;
00087
00088 void updateCatListFromArray()
00089 {
00090 Categories cat( 0 );
00091 cat.load( categoryFileName() );
00092
00093 mCatList.clear();
00094 for (uint i = 0; i < mCat.count(); i++ )
00095 mCatList << cat.label("Document View", mCat[i] );
00096
00097 }
00098
00099 void setCatArrayDirty()
00100 {
00101 mCat.resize(0);
00102 }
00103
00104 void ensureCatArray()
00105 {
00106 if ( mCat.count() > 0 || mCatList.count()==0 )
00107 return;
00108
00109 Categories cat( 0 );
00110 cat.load( categoryFileName() );
00111 mCat.resize( mCatList.count() );
00112 int i;
00113 QStringList::ConstIterator it;
00114 for ( i = 0, it = mCatList.begin(); it != mCatList.end();
00115 ++it, i++ ) {
00116
00117 bool number;
00118 int id = (*it).toInt( &number );
00119 if ( !number ) {
00120 id = cat.id( "Document View", *it );
00121 if ( id == 0 )
00122 id = cat.addCategory( "Document View", *it );
00123 }
00124 mCat[i] = id;
00125 }
00126 }
00127 };
00128
00229 void AppLnk::setSmallIconSize(int small)
00230 {
00231 smallSize = small;
00232 }
00233
00239 int AppLnk::smallIconSize()
00240 {
00241 return smallSize;
00242 }
00243
00244
00251 void AppLnk::setBigIconSize(int big)
00252 {
00253 bigSize = big;
00254 }
00255
00261 int AppLnk::bigIconSize()
00262 {
00263 return bigSize;
00264 }
00265
00266
00314 const QArray<int>& AppLnk::categories() const
00315 {
00316 d->ensureCatArray();
00317 return d->mCat;
00318 }
00319
00357 AppLnk::AppLnk()
00358 {
00359 mId = 0;
00360 d = new AppLnkPrivate();
00361 }
00362
00368 AppLnk::AppLnk( const QString &file )
00369 {
00370 QStringList sl;
00371 d = new AppLnkPrivate();
00372 if ( !file.isNull() ) {
00373 Config config( file, Config::File );
00374
00375 if ( config.isValid() ) {
00376 config.setGroup( "Desktop Entry" );
00377
00378 mName = config.readEntry( "Name", file );
00379 mExec = config.readEntry( "Exec" );
00380 mType = config.readEntry( "Type", QString::null );
00381 mIconFile = config.readEntry( "Icon", QString::null );
00382 mRotation = config.readEntry( "Rotation", "" );
00383 mComment = config.readEntry( "Comment", QString::null );
00384
00385 mMimeTypes = config.readListEntry( "MimeType", ';' );
00386 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it)
00387 *it = (*it).lower();
00388 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
00389 mLinkFile = file;
00390 mFile = config.readEntry("File", QString::null);
00391 if ( !mExec. isEmpty ( )) {
00392 mFile = QString::null;
00393 }
00394 else if ( mFile[0] != '/' ) {
00395 int slash = file.findRev('/');
00396 if ( slash >= 0 ) {
00397 mFile = file.left(slash) + '/' + mFile;
00398 }
00399 }
00400 d->mCatList = config.readListEntry("Categories", ';');
00401 if ( d->mCatList[0].toInt() < -1 ) {
00402
00403 Categories cat( 0 );
00404 cat.load( categoryFileName() );
00405 d->mCat.resize( d->mCatList.count() );
00406 int i;
00407 QStringList::ConstIterator it;
00408 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end();
00409 ++it, i++ ) {
00410 bool number;
00411 int id = (*it).toInt( &number );
00412 if ( !number ) {
00413
00414 id = cat.id( "Document View", *it );
00415 if ( id == 0 )
00416 id = cat.addCategory( "Document View", *it );
00417 }
00418 d->mCat[i] = id;
00419 }
00420 d->updateCatListFromArray();
00421 }
00422 }
00423 }
00424 mId = 0;
00425 }
00426
00427 AppLnk& AppLnk::operator=(const AppLnk ©)
00428 {
00429 if ( this == © ) return *this;
00430 if ( mId )
00431 qWarning("Deleting AppLnk that is in an AppLnkSet");
00432 if ( d )
00433 delete d;
00434
00435
00436 mName = copy.mName;
00437
00438
00439 mPixmap = copy.mPixmap;
00440 mBigPixmap = copy.mBigPixmap;
00441
00442 mExec = copy.mExec;
00443 mType = copy.mType;
00444 mRotation = copy.mRotation;
00445 mComment = copy.mComment;
00446 mFile = copy.mFile;
00447 mLinkFile = copy.mLinkFile;
00448 mIconFile = copy.mIconFile;
00449 mMimeTypes = copy.mMimeTypes;
00450 mMimeTypeIcons = copy.mMimeTypeIcons;
00451 mId = 0;
00452 d = new AppLnkPrivate();
00453 d->mCat = copy.d->mCat;
00454 d->mCatList = copy.d->mCatList;
00455 d->mPixmaps = copy.d->mPixmaps;
00456
00457 return *this;
00458 }
00464 const QPixmap& AppLnk::pixmap( int pos, int size ) const {
00465 if ( d->mPixmaps[pos].isNull() ) {
00466 AppLnk* that = (AppLnk*)this;
00467 if ( mIconFile.isEmpty() ) {
00468 MimeType mt(type());
00469 that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap();
00470 if ( that->d->mPixmaps[pos].isNull() )
00471 that->d->mPixmaps[pos].convertFromImage(
00472 Resource::loadImage("UnknownDocument")
00473 .smoothScale( size, size ) );
00474 return that->d->mPixmaps[pos];
00475 }
00476 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
00477 if ( unscaledIcon.isNull() ) {
00478
00479 that->d->mPixmaps[pos].convertFromImage(
00480 Resource::loadImage("UnknownDocument")
00481 .smoothScale( size, size ) );
00482 } else {
00483 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
00484 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
00485 }
00486 return that->d->mPixmaps[pos];
00487 }
00488 return d->mPixmaps[pos];
00489 }
00490
00496 const QPixmap& AppLnk::pixmap() const
00497 {
00498 if ( d->mPixmaps[0].isNull() ) {
00499 return pixmap(AppLnkPrivate::Normal, smallSize );
00500 }
00501 return d->mPixmaps[0];
00502 }
00503
00509 const QPixmap& AppLnk::bigPixmap() const
00510 {
00511 if ( d->mPixmaps[1].isNull() ) {
00512 return pixmap( AppLnkPrivate::Big, bigSize );
00513 }
00514 return d->mPixmaps[1];
00515 }
00516
00522 QString AppLnk::type() const
00523 {
00524 if ( mType.isNull() ) {
00525 AppLnk* that = (AppLnk*)this;
00526 QString f = file();
00527 if ( !f.isNull() ) {
00528 MimeType mt(f);
00529 that->mType = mt.id();
00530 return that->mType;
00531 }
00532 }
00533 return mType;
00534 }
00535
00541 QString AppLnk::file() const
00542 {
00543 if ( mExec.isEmpty ( ) && mFile.isNull() ) {
00544 AppLnk* that = (AppLnk*)this;
00545 QString ext = MimeType(mType).extension();
00546 if ( !ext.isEmpty() )
00547 ext = "." + ext;
00548 if ( !mLinkFile.isEmpty() ) {
00549 that->mFile =
00550 mLinkFile.right(8)==".desktop"
00551 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
00552 qDebug("mFile now == %s", mFile.latin1());
00553 } else if ( mType.contains('/') ) {
00554 that->mFile =
00555 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
00556
00557
00558
00559 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) {
00560 int n=1;
00561 QString nn;
00562 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
00563 || QFile::exists(nn+".desktop"))
00564 n++;
00565 that->mFile = nn;
00566 }
00567 that->mLinkFile = that->mFile+".desktop";
00568 that->mFile += ext;
00569 }
00570 prepareDirectories(that->mFile);
00571 if ( !that->mFile.isEmpty() ) {
00572 QFile f(that->mFile);
00573 if ( !f.open(IO_WriteOnly) )
00574 that->mFile = QString::null;
00575 return that->mFile;
00576 }
00577 }
00578 return mFile;
00579 }
00580
00586 QString AppLnk::linkFile() const
00587 {
00588 if ( mLinkFile.isNull() ) {
00589 AppLnk* that = (AppLnk*)this;
00590 if ( type().contains('/') ) {
00591 StorageInfo storage;
00592 const FileSystem *fs = storage.fileSystemOf( that->mFile );
00593
00594
00595
00596 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) {
00597 that->mLinkFile = fs->path();
00598 } else
00599 that->mLinkFile = getenv( "HOME" );
00600 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
00601
00602
00603 if ( QFile::exists(that->mLinkFile+".desktop") ) {
00604 AppLnk lnk( that->mLinkFile + ".desktop" );
00605
00606
00607 if(that->file() != lnk.file() ) {
00608 int n = 1;
00609 QString nn;
00610 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) {
00611 n++;
00612
00613 AppLnk lnk(nn );
00614 if (lnk.file() == that->file() )
00615 break;
00616 }
00617 that->mLinkFile = nn;
00618 }
00619 }
00620 that->mLinkFile += ".desktop";
00621 storeLink();
00622 }
00623 return that->mLinkFile;
00624 }
00625 return mLinkFile;
00626 }
00627
00631 AppLnk::AppLnk( const AppLnk © )
00632 {
00633 mName = copy.mName;
00634 mPixmap = copy.mPixmap;
00635 mBigPixmap = copy.mBigPixmap;
00636 mExec = copy.mExec;
00637 mType = copy.mType;
00638 mRotation = copy.mRotation;
00639 mComment = copy.mComment;
00640 mFile = copy.mFile;
00641 mLinkFile = copy.mLinkFile;
00642 mIconFile = copy.mIconFile;
00643 mMimeTypes = copy.mMimeTypes;
00644 mMimeTypeIcons = copy.mMimeTypeIcons;
00645 mId = 0;
00646 d = new AppLnkPrivate();
00647 d->mCat = copy.d->mCat;
00648 d->mCatList = copy.d->mCatList;
00649 d->mPixmaps = copy.d->mPixmaps;
00650 }
00651
00658 AppLnk::~AppLnk()
00659 {
00660 if ( mId )
00661 qWarning("Deleting AppLnk that is in an AppLnkSet");
00662 if ( d )
00663 delete d;
00664 }
00665
00672 void AppLnk::execute() const
00673 {
00674 execute(QStringList());
00675 }
00676
00683 void AppLnk::execute(const QStringList& args) const
00684 {
00685 #ifdef Q_WS_QWS
00686 if ( !mRotation.isEmpty() ) {
00687
00688 int rot = QPEApplication::defaultRotation();
00689 rot = (rot+mRotation.toInt())%360;
00690 QCString old = getenv("QWS_DISPLAY");
00691 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1);
00692 invoke(args);
00693 setenv("QWS_DISPLAY", old.data(), 1);
00694 } else
00695 #endif
00696 invoke(args);
00697 }
00698
00706 void AppLnk::invoke(const QStringList& args) const
00707 {
00708 Global::execute( exec(), args[0] );
00709 }
00710
00716 void AppLnk::setExec( const QString& exec )
00717 {
00718 mExec = exec;
00719 }
00720
00721 #if 0 // this was inlined for better BC
00722
00727 void AppLnk::setRotation ( const QString &rot )
00728 {
00729 mRotation = rot;
00730 }
00731 #endif
00732
00738 void AppLnk::setName( const QString& docname )
00739 {
00740 mName = docname;
00741 }
00742
00748 void AppLnk::setFile( const QString& filename )
00749 {
00750 mFile = filename;
00751 }
00752
00758 void AppLnk::setLinkFile( const QString& filename )
00759 {
00760 mLinkFile = filename;
00761 }
00762
00771 void AppLnk::setComment( const QString& comment )
00772 {
00773 mComment = comment;
00774 }
00775
00785 void AppLnk::setType( const QString& type )
00786 {
00787 mType = type;
00788 }
00789
00804 void AppLnk::setIcon( const QString& iconname )
00805 {
00806 mIconFile = iconname;
00807 QImage unscaledIcon = Resource::loadImage( mIconFile );
00808 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
00809 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
00810 }
00811
00819 void AppLnk::setCategories( const QArray<int>& c )
00820 {
00821 d->mCat = c;
00822 d->updateCatListFromArray();
00823 }
00824
00838 bool AppLnk::ensureLinkExists() const
00839 {
00840 QString lf = linkFile();
00841 return prepareDirectories(lf);
00842 }
00843
00851 bool AppLnk::writeLink() const
00852 {
00853
00854 QString lf = linkFile();
00855 if ( !ensureLinkExists() )
00856 return FALSE;
00857 storeLink();
00858 return TRUE;
00859 }
00860
00864 void AppLnk::storeLink() const
00865 {
00866 Config config( mLinkFile, Config::File );
00867 config.setGroup("Desktop Entry");
00868 config.writeEntry("Name",mName);
00869 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
00870 config.writeEntry("Type",type());
00871 if(!rotation().isEmpty())
00872 config.writeEntry("Rotation",rotation());
00873 else
00874 config.removeEntry("Rotation");
00875 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
00876 QString f = file();
00877 int i = 0;
00878 while ( i < (int)f.length() && i < (int)mLinkFile.length() && f[i] == mLinkFile[i] )
00879 i++;
00880 while ( i && f[i] != '/' )
00881 i--;
00882
00883 if ( mLinkFile.find( '/', i + 1 ) < 0 )
00884 f = f.mid(i+1);
00885
00886 config.writeEntry("File",f);
00887 config.writeEntry( "Categories", d->mCatList, ';' );
00888
00889 #ifndef QT_NO_COP
00890 QCopEnvelope e("QPE/System", "linkChanged(QString)");
00891 e << mLinkFile;
00892 #endif
00893 }
00894
00900 void AppLnk::setProperty(const QString& key, const QString& value)
00901 {
00902 if ( ensureLinkExists() ) {
00903 Config cfg(linkFile(), Config::File);
00904 cfg.writeEntry(key,value);
00905 }
00906 }
00907
00913 QString AppLnk::property(const QString& key) const
00914 {
00915 QString lf = linkFile();
00916 if ( !QFile::exists(lf) )
00917 return QString::null;
00918 Config cfg(lf, Config::File);
00919 return cfg.readEntry(key);
00920 }
00921
00922 bool AppLnk::isPreloaded() const {
00923
00924 Config cfg("Launcher");
00925 cfg.setGroup("Preload");
00926 QStringList apps = cfg.readListEntry("Apps",',');
00927 if (apps.contains(exec()))
00928 return true;
00929 return false;
00930 }
00931
00932 void AppLnk::setPreloaded(bool yesNo) {
00933
00934 Config cfg("Launcher");
00935 cfg.setGroup("Preload");
00936 QStringList apps = cfg.readListEntry("Apps", ',');
00937 if (apps.contains(exec()) && !yesNo)
00938 apps.remove(exec());
00939 else if (yesNo && !apps.contains(exec()))
00940 apps.append(exec());
00941 cfg.writeEntry("Apps", apps, ',');
00942 }
00943
00944
00950 void AppLnk::removeFiles()
00951 {
00952 bool valid = isValid();
00953 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
00954 if ( QFile::remove(file()) ) {
00955 #ifndef QT_NO_COP
00956 QCopEnvelope e("QPE/System", "linkChanged(QString)");
00957 if ( linkFileKnown() )
00958 e << linkFile();
00959 else
00960 e << file();
00961 #endif
00962 } else if ( valid ) {
00963
00964 writeLink();
00965 }
00966 }
00967 }
00968
00974 void AppLnk::removeLinkFile()
00975 {
00976 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
00977 #ifndef QT_NO_COP
00978 QCopEnvelope e("QPE/System", "linkChanged(QString)");
00979 e << linkFile();
00980 #endif
00981 }
00982 }
00983
00984 class AppLnkSetPrivate {
00985 public:
00986 AppLnkSetPrivate()
00987 {
00988 typPix.setAutoDelete(TRUE);
00989 typPixBig.setAutoDelete(TRUE);
00990 typName.setAutoDelete(TRUE);
00991 }
00992
00993 QDict<QPixmap> typPix;
00994 QDict<QPixmap> typPixBig;
00995 QDict<QString> typName;
00996 };
00997
01023 AppLnkSet::AppLnkSet() :
01024 d(new AppLnkSetPrivate)
01025 {
01026 }
01027
01039 AppLnkSet::AppLnkSet( const QString &directory ) :
01040 d(new AppLnkSetPrivate)
01041 {
01042 QDir dir( directory );
01043 mFile = directory;
01044 findChildren(directory,QString::null,QString::null);
01045 }
01046
01051 void AppLnkSet::detachChildren()
01052 {
01053 QListIterator<AppLnk> it( mApps );
01054 for ( ; it.current(); ) {
01055 AppLnk* a = *it;
01056 ++it;
01057 a->mId = 0;
01058 }
01059 mApps.clear();
01060 }
01061
01067 AppLnkSet::~AppLnkSet()
01068 {
01069 QListIterator<AppLnk> it( mApps );
01070 for ( ; it.current(); ) {
01071 AppLnk* a = *it;
01072 ++it;
01073 a->mId = 0;
01074 delete a;
01075 }
01076 delete d;
01077 }
01078
01079 void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth)
01080 {
01081 depth++;
01082 if ( depth > 10 )
01083 return;
01084
01085 QDir dir( dr );
01086 QString typNameLocal = typName;
01087
01088 if ( dir.exists( ".directory" ) ) {
01089 Config config( dr + "/.directory", Config::File );
01090 config.setGroup( "Desktop Entry" );
01091 typNameLocal = config.readEntry( "Name", typNameLocal );
01092 if ( !typ.isEmpty() ) {
01093 QString iconFile = config.readEntry( "Icon", "AppsIcon" );
01094 QImage unscaledIcon = Resource::loadImage( iconFile );
01095 QPixmap pm, bpm;
01096 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
01097 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
01098 d->typPix.insert(typ, new QPixmap(pm));
01099 d->typPixBig.insert(typ, new QPixmap(bpm));
01100 d->typName.insert(typ, new QString(typNameLocal));
01101 }
01102 }
01103
01104 const QFileInfoList *list = dir.entryInfoList();
01105 if ( list ) {
01106 QFileInfo* fi;
01107 bool cadded=FALSE;
01108 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
01109 QString bn = fi->fileName();
01110
01111 if ( bn[0] != '.' && bn != "CVS" ) {
01112 if ( fi->isDir() ) {
01113 QString c = typ.isNull() ? bn : typ+"/"+bn;
01114 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
01115 findChildren(fi->filePath(), c, d, depth );
01116 } else {
01117 if ( fi->extension(FALSE) == "desktop" ) {
01118 AppLnk* app = new AppLnk( fi->filePath() );
01119 #ifdef QT_NO_QWS_MULTIPROCESS
01120 if ( !Global::isBuiltinCommand( app->exec() ) )
01121 delete app;
01122 else
01123 #endif
01124 {
01125 if ( !typ.isEmpty() ) {
01126 if ( !cadded ) {
01127 typs.append(typ);
01128 cadded = TRUE;
01129 }
01130 app->setType(typ);
01131 }
01132 add(app);
01133 }
01134 }
01135 }
01136 }
01137 }
01138 }
01139 }
01140
01147 void AppLnkSet::add( AppLnk *f )
01148 {
01149 if ( f->mId == 0 ) {
01150 AppLnk::lastId++;
01151 f->mId = AppLnk::lastId;
01152 mApps.append( f );
01153 } else {
01154 qWarning("Attempt to add an AppLnk twice");
01155 }
01156 }
01157
01165 bool AppLnkSet::remove( AppLnk *f )
01166 {
01167 if ( mApps.remove( f ) ) {
01168 f->mId = 0;
01169 return TRUE;
01170 }
01171 return FALSE;
01172 }
01173
01174
01181 QString AppLnkSet::typeName( const QString& t ) const
01182 {
01183 QString *st = d->typName.find(t);
01184 return st ? *st : QString::null;
01185 }
01186
01193 QPixmap AppLnkSet::typePixmap( const QString& t ) const
01194 {
01195 QPixmap *pm = d->typPix.find(t);
01196 return pm ? *pm : QPixmap();
01197 }
01198
01205 QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
01206 {
01207 QPixmap *pm = d->typPixBig.find(t);
01208 return pm ? *pm : QPixmap();
01209 }
01210
01214 const AppLnk *AppLnkSet::find( int id ) const
01215 {
01216 QListIterator<AppLnk> it( children() );
01217
01218 for ( ; it.current(); ++it ) {
01219 const AppLnk *app = it.current();
01220 if ( app->id() == id )
01221 return app;
01222 }
01223
01224 return 0;
01225 }
01226
01230 const AppLnk *AppLnkSet::findExec( const QString& exec ) const
01231 {
01232 QListIterator<AppLnk> it( children() );
01233
01234 for ( ; it.current(); ++it ) {
01235 const AppLnk *app = it.current();
01236 if ( app->exec() == exec )
01237 return app;
01238 }
01239
01240 return 0;
01241 }
01242
01259 DocLnkSet::DocLnkSet()
01260 {
01261 }
01262
01275 DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
01276 AppLnkSet()
01277 {
01278 QDir dir( directory );
01279 mFile = dir.dirName();
01280 QDict<void> reference;
01281
01282 QStringList subFilter = QStringList::split(";", mimefilter);
01283 QValueList<QRegExp> mimeFilters;
01284 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
01285 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
01286
01287 findChildren(directory, mimeFilters, reference);
01288
01289 const QList<DocLnk> &list = children();
01290 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
01291 reference.remove( (*it)->file() );
01292 }
01293 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
01294 if ( dit.current() == (void*)2 ) {
01295
01296 DocLnk* dl = new DocLnk;
01297 QFileInfo fi( dit.currentKey() );
01298 dl->setFile(fi.filePath());
01299 dl->setName(fi.baseName());
01300
01301
01302 bool match = mimefilter.isNull();
01303 if ( !match )
01304 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it )
01305 if ( (*it).match(dl->type()) >= 0 )
01306 match = TRUE;
01307 if ( match
01308 && !!dl->exec() )
01309 add(dl);
01310 else
01311 delete dl;
01312 }
01313 }
01314 }
01315
01316
01321 void DocLnkSet::appendFrom( DocLnkSet& other )
01322 {
01323 if ( &other == this )
01324 return;
01325 QListIterator<AppLnk> it( other.mApps );
01326 for ( ; it.current(); ) {
01327 mApps.append(*it);
01328 ++it;
01329 }
01330 other.mApps.clear();
01331 }
01332
01333 void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth)
01334 {
01335 depth++;
01336 if ( depth > 10 )
01337 return;
01338
01339 QDir dir( dr );
01340
01341
01342
01343
01344
01345 if ( dir.exists( ".Qtopia-ignore" ) )
01346 return;
01347
01348 const QFileInfoList *list = dir.entryInfoList();
01349 if ( list ) {
01350 QFileInfo* fi;
01351 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
01352 QString bn = fi->fileName();
01353 if ( bn[0] != '.' ) {
01354 if ( fi->isDir() ) {
01355 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" )
01356 findChildren(fi->filePath(), mimeFilters, reference, depth);
01357 } else {
01358 if ( fi->extension(FALSE) == "desktop" ) {
01359 DocLnk* dl = new DocLnk( fi->filePath() );
01360 QFileInfo fi2(dl->file());
01361 bool match = FALSE;
01362 if ( !fi2.exists() ) {
01363 dir.remove( dl->file() );
01364 }
01365 if ( mimeFilters.count() == 0 ) {
01366 add( dl );
01367 match = TRUE;
01368 } else {
01369 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
01370 if ( (*it).match(dl->type()) >= 0 ) {
01371 add(dl);
01372 match = TRUE;
01373 }
01374 }
01375 }
01376 if ( !match )
01377 delete dl;
01378 } else {
01379 if ( !reference.find(fi->fileName()) )
01380 reference.insert(fi->filePath(), (void*)2);
01381 }
01382 }
01383 }
01384 }
01385 }
01386 }
01387
01403 DocLnk::DocLnk( const QString &file ) :
01404 AppLnk(file)
01405 {
01406 init(file);
01407 }
01408
01415 DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
01416 AppLnk(may_be_desktopfile ? file : QString::null)
01417 {
01418 init(file);
01419 }
01420
01421 void DocLnk::init(const QString &file)
01422 {
01423 if ( isValid() ) {
01424 #ifndef FORCED_DIR_STRUCTURE_WAY
01425 if ( mType.isNull() )
01426
01427 #endif
01428 {
01429 int s0 = file.findRev('/');
01430 if ( s0 > 0 ) {
01431 int s1 = file.findRev('/',s0-1);
01432 if ( s1 > 0 ) {
01433 int s2 = file.findRev('/',s1-1);
01434 if ( s2 > 0 ) {
01435 mType = file.mid(s2+1,s0-s2-1);
01436 }
01437 }
01438 }
01439 }
01440 } else if ( QFile::exists(file) ) {
01441 QString n = file;
01442 n.replace(QRegExp(".*/"),"");
01443 n.replace(QRegExp("\\..*"),"");
01444 setName( n );
01445 setFile( file );
01446 }
01447 MimeType mt(mType);
01448 if( mt.application() )
01449 mExec = mt.application()->exec();
01450 }
01451
01455 DocLnk::DocLnk()
01456 {
01457 }
01458
01463 DocLnk::~DocLnk()
01464 {
01465 }
01466
01470 QString DocLnk::exec() const
01471 {
01472 MimeType mt(type());
01473 const AppLnk* app = mt.application();
01474 if ( app )
01475 return app->exec();
01476 else
01477 return QString::null;
01478 }
01479
01483 void DocLnk::invoke(const QStringList& args) const
01484 {
01485 MimeType mt(type());
01486 const AppLnk* app = mt.application();
01487 if ( app ) {
01488 QStringList a = args;
01489 if ( linkFileKnown() && QFile::exists( linkFile() ) )
01490 a.append(linkFile());
01491 else
01492 a.append(file());
01493 app->execute(a);
01494 }
01495 }
01496
01497