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/global.h>
00031 #include <qpe/qcopenvelope_qws.h>
00032 #include <qpe/mimetype.h>
00033 #include <qpe/config.h>
00034 #include <qpe/storage.h>
00035 #include <qpe/resource.h>
00036
00037 #include <qdir.h>
00038
00039
00040 #include <stdlib.h>
00041
00042 int AppLnk::lastId = 5000;
00043
00044 static int smallSize = 14;
00045 static int bigSize = 32;
00046
00047 static QString safeFileName(const QString& n)
00048 {
00049 QString safename=n;
00050 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_");
00051 safename.replace(QRegExp("^[^A-Za-z]*"),"");
00052 if ( safename.isEmpty() )
00053 safename = "_";
00054 return safename;
00055 }
00056
00057 static bool prepareDirectories(const QString& lf)
00058 {
00059 if ( !QFile::exists(lf) ) {
00060
00061 QFileInfo fi(lf);
00062 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
00063 return FALSE;
00064 }
00065 return TRUE;
00066 }
00067
00068 class AppLnkPrivate
00069 {
00070 public:
00071
00072 enum Size {Normal = 0, Big };
00073 AppLnkPrivate() {
00074
00075
00076 QPixmap pix;
00077 mPixmaps.insert(0, pix );
00078 mPixmaps.insert(1, pix);
00079 }
00080
00081 QStringList mCatList;
00082 QArray<int> mCat;
00083 QMap<int, QPixmap> mPixmaps;
00084
00085 void updateCatListFromArray()
00086 {
00087 Categories cat( 0 );
00088 cat.load( categoryFileName() );
00089
00090 mCatList.clear();
00091 for (uint i = 0; i < mCat.count(); i++ )
00092 mCatList << cat.label("Document View", mCat[i] );
00093
00094 }
00095
00096 void setCatArrayDirty()
00097 {
00098 mCat.resize(0);
00099 }
00100
00101 void ensureCatArray()
00102 {
00103 if ( mCat.count() > 0 || mCatList.count()==0 )
00104 return;
00105
00106 Categories cat( 0 );
00107 cat.load( categoryFileName() );
00108 mCat.resize( mCatList.count() );
00109 int i;
00110 QStringList::ConstIterator it;
00111 for ( i = 0, it = mCatList.begin(); it != mCatList.end();
00112 ++it, i++ ) {
00113
00114 bool number;
00115 int id = (*it).toInt( &number );
00116 if ( !number ) {
00117 id = cat.id( "Document View", *it );
00118 if ( id == 0 )
00119 id = cat.addCategory( "Document View", *it );
00120 }
00121 mCat[i] = id;
00122 }
00123 }
00124 };
00125
00226 void AppLnk::setSmallIconSize(int small)
00227 {
00228 smallSize = small;
00229 }
00230
00236 int AppLnk::smallIconSize()
00237 {
00238 return smallSize;
00239 }
00240
00241
00248 void AppLnk::setBigIconSize(int big)
00249 {
00250 bigSize = big;
00251 }
00252
00258 int AppLnk::bigIconSize()
00259 {
00260 return bigSize;
00261 }
00262
00263
00311 const QArray<int>& AppLnk::categories() const
00312 {
00313 d->ensureCatArray();
00314 return d->mCat;
00315 }
00316
00354 AppLnk::AppLnk()
00355 {
00356 mId = 0;
00357 d = new AppLnkPrivate();
00358 }
00359
00365 AppLnk::AppLnk( const QString &file )
00366 {
00367 QStringList sl;
00368 d = new AppLnkPrivate();
00369 if ( !file.isNull() ) {
00370 Config config( file, Config::File );
00371
00372 if ( config.isValid() ) {
00373 config.setGroup( "Desktop Entry" );
00374
00375 mName = config.readEntry( "Name", file );
00376 mExec = config.readEntry( "Exec" );
00377 mType = config.readEntry( "Type", QString::null );
00378 mIconFile = config.readEntry( "Icon", QString::null );
00379 mRotation = config.readEntry( "Rotation", "" );
00380 mComment = config.readEntry( "Comment", QString::null );
00381
00382 mMimeTypes = config.readListEntry( "MimeType", ';' );
00383 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it)
00384 *it = (*it).lower();
00385 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
00386 mLinkFile = file;
00387 mFile = config.readEntry("File", QString::null);
00388 if ( !mExec. isEmpty ( )) {
00389 mFile = QString::null;
00390 }
00391 else if ( mFile[0] != '/' ) {
00392 int slash = file.findRev('/');
00393 if ( slash >= 0 ) {
00394 mFile = file.left(slash) + '/' + mFile;
00395 }
00396 }
00397 d->mCatList = config.readListEntry("Categories", ';');
00398 if ( d->mCatList[0].toInt() < -1 ) {
00399
00400 Categories cat( 0 );
00401 cat.load( categoryFileName() );
00402 d->mCat.resize( d->mCatList.count() );
00403 int i;
00404 QStringList::ConstIterator it;
00405 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end();
00406 ++it, i++ ) {
00407 bool number;
00408 int id = (*it).toInt( &number );
00409 if ( !number ) {
00410
00411 id = cat.id( "Document View", *it );
00412 if ( id == 0 )
00413 id = cat.addCategory( "Document View", *it );
00414 }
00415 d->mCat[i] = id;
00416 }
00417 d->updateCatListFromArray();
00418 }
00419 }
00420 }
00421 mId = 0;
00422 }
00423
00424 AppLnk& AppLnk::operator=(const AppLnk ©)
00425 {
00426 if ( this == © ) return *this;
00427 if ( mId )
00428 qWarning("Deleting AppLnk that is in an AppLnkSet");
00429 if ( d )
00430 delete d;
00431
00432
00433 mName = copy.mName;
00434
00435
00436 mPixmap = copy.mPixmap;
00437 mBigPixmap = copy.mBigPixmap;
00438
00439 mExec = copy.mExec;
00440 mType = copy.mType;
00441 mRotation = copy.mRotation;
00442 mComment = copy.mComment;
00443 mFile = copy.mFile;
00444 mLinkFile = copy.mLinkFile;
00445 mIconFile = copy.mIconFile;
00446 mMimeTypes = copy.mMimeTypes;
00447 mMimeTypeIcons = copy.mMimeTypeIcons;
00448 mId = 0;
00449 d = new AppLnkPrivate();
00450 d->mCat = copy.d->mCat;
00451 d->mCatList = copy.d->mCatList;
00452 d->mPixmaps = copy.d->mPixmaps;
00453
00454 return *this;
00455 }
00461 const QPixmap& AppLnk::pixmap( int pos, int size ) const {
00462 if ( d->mPixmaps[pos].isNull() ) {
00463 AppLnk* that = (AppLnk*)this;
00464 if ( mIconFile.isEmpty() ) {
00465 MimeType mt(type());
00466 that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap();
00467 if ( that->d->mPixmaps[pos].isNull() )
00468 that->d->mPixmaps[pos].convertFromImage(
00469 Resource::loadImage("UnknownDocument")
00470 .smoothScale( size, size ) );
00471 return that->d->mPixmaps[pos];
00472 }
00473
00474 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
00475 if ( unscaledIcon.isNull() ) {
00476
00477 that->d->mPixmaps[pos].convertFromImage(
00478 Resource::loadImage("UnknownDocument")
00479 .smoothScale( size, size ) );
00480 } else {
00481 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
00482 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
00483 }
00484 return that->d->mPixmaps[pos];
00485 }
00486
00487 return d->mPixmaps[pos];
00488 }
00489
00495 const QPixmap& AppLnk::pixmap() const
00496 {
00497 if ( d->mPixmaps[0].isNull() ) {
00498 return pixmap(AppLnkPrivate::Normal, smallSize );
00499 }
00500 return d->mPixmaps[0];
00501 }
00502
00508 const QPixmap& AppLnk::bigPixmap() const
00509 {
00510 if ( d->mPixmaps[1].isNull() ) {
00511 return pixmap( AppLnkPrivate::Big, bigSize );
00512 }
00513 return d->mPixmaps[1];
00514 }
00515
00521 QString AppLnk::type() const
00522 {
00523 if ( mType.isNull() ) {
00524 AppLnk* that = (AppLnk*)this;
00525 QString f = file();
00526 if ( !f.isNull() ) {
00527 MimeType mt(f);
00528 that->mType = mt.id();
00529 return that->mType;
00530 }
00531 }
00532 return mType;
00533 }
00534
00540 QString AppLnk::file() const
00541 {
00542 if ( mExec.isEmpty ( ) && mFile.isNull() ) {
00543 AppLnk* that = (AppLnk*)this;
00544 QString ext = MimeType(mType).extension();
00545 if ( !ext.isEmpty() )
00546 ext = "." + ext;
00547 if ( !mLinkFile.isEmpty() ) {
00548 that->mFile =
00549 mLinkFile.right(8)==".desktop"
00550 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
00551 qDebug("mFile now == %s", mFile.latin1());
00552 } else if ( mType.contains('/') ) {
00553 that->mFile =
00554 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
00555
00556
00557
00558 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) {
00559 int n=1;
00560 QString nn;
00561 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
00562 || QFile::exists(nn+".desktop"))
00563 n++;
00564 that->mFile = nn;
00565 }
00566 that->mLinkFile = that->mFile+".desktop";
00567 that->mFile += ext;
00568 }
00569 prepareDirectories(that->mFile);
00570 if ( !that->mFile.isEmpty() ) {
00571 QFile f(that->mFile);
00572 if ( !f.open(IO_WriteOnly) )
00573 that->mFile = QString::null;
00574 return that->mFile;
00575 }
00576 }
00577 return mFile;
00578 }
00579
00585 QString AppLnk::linkFile() const
00586 {
00587 if ( mLinkFile.isNull() ) {
00588 AppLnk* that = (AppLnk*)this;
00589 if ( type().contains('/') ) {
00590 StorageInfo storage;
00591 const FileSystem *fs = storage.fileSystemOf( that->mFile );
00592
00593
00594
00595 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) {
00596 that->mLinkFile = fs->path();
00597 } else
00598 that->mLinkFile = getenv( "HOME" );
00599 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
00600
00601
00602 if ( QFile::exists(that->mLinkFile+".desktop") ) {
00603 AppLnk lnk( that->mLinkFile + ".desktop" );
00604
00605
00606 if(that->file() != lnk.file() ) {
00607 int n = 1;
00608 QString nn;
00609 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) {
00610 n++;
00611
00612 AppLnk lnk(nn );
00613 if (lnk.file() == that->file() )
00614 break;
00615 }
00616 that->mLinkFile = nn;
00617 }
00618 }
00619 that->mLinkFile += ".desktop";
00620 storeLink();
00621 }
00622 return that->mLinkFile;
00623 }
00624 return mLinkFile;
00625 }
00626
00630 AppLnk::AppLnk( const AppLnk © )
00631 {
00632 mName = copy.mName;
00633 mPixmap = copy.mPixmap;
00634 mBigPixmap = copy.mBigPixmap;
00635 mExec = copy.mExec;
00636 mType = copy.mType;
00637 mRotation = copy.mRotation;
00638 mComment = copy.mComment;
00639 mFile = copy.mFile;
00640 mLinkFile = copy.mLinkFile;
00641 mIconFile = copy.mIconFile;
00642 mMimeTypes = copy.mMimeTypes;
00643 mMimeTypeIcons = copy.mMimeTypeIcons;
00644 mId = 0;
00645 d = new AppLnkPrivate();
00646 d->mCat = copy.d->mCat;
00647 d->mCatList = copy.d->mCatList;
00648 d->mPixmaps = copy.d->mPixmaps;
00649 }
00650
00657 AppLnk::~AppLnk()
00658 {
00659 if ( mId )
00660 qWarning("Deleting AppLnk that is in an AppLnkSet");
00661 if ( d )
00662 delete d;
00663 }
00664
00671 void AppLnk::execute() const
00672 {
00673 execute( QStringList::split( ' ', property( "Arguments" ) ) );
00674 }
00675
00682 void AppLnk::execute(const QStringList& args) const
00683 {
00684 #ifdef Q_WS_QWS
00685 if ( !mRotation.isEmpty() ) {
00686
00687 int rot = QPEApplication::defaultRotation();
00688 int j = 0;
00689 rot = (rot+mRotation.toInt())%360;
00690 QCString old = getenv( "QWS_DISPLAY" ) ? getenv( "QWS_DISPLAY" ) : "Transformed";
00691 QString driver( old.left( ( ( j = old.find( ':' ) ) >= 0 ) ? j : old.size() ).data() );
00692 setenv( "QWS_DISPLAY", QString( "%1:Rot%2:0" ).arg( driver ).arg( rot ), 1 );
00693 invoke(args);
00694 setenv("QWS_DISPLAY", old.data(), 1);
00695 } else
00696 #endif
00697 invoke(args);
00698 }
00699
00707 void AppLnk::invoke(const QStringList& args) const
00708 {
00709 if ( property( "Arguments" ).isEmpty() )
00710 Global::execute( exec(), args[0] );
00711 else
00712 Global::execute( exec(), args.join( " " ) );
00713 }
00714
00720 void AppLnk::setExec( const QString& exec )
00721 {
00722 mExec = exec;
00723 }
00724
00725 #if 0 // this was inlined for better BC
00726
00731 void AppLnk::setRotation ( const QString &rot )
00732 {
00733 mRotation = rot;
00734 }
00735 #endif
00736
00742 void AppLnk::setName( const QString& docname )
00743 {
00744 mName = docname;
00745 }
00746
00752 void AppLnk::setFile( const QString& filename )
00753 {
00754 mFile = filename;
00755 }
00756
00762 void AppLnk::setLinkFile( const QString& filename )
00763 {
00764 mLinkFile = filename;
00765 }
00766
00775 void AppLnk::setComment( const QString& comment )
00776 {
00777 mComment = comment;
00778 }
00779
00789 void AppLnk::setType( const QString& type )
00790 {
00791 mType = type;
00792 }
00793
00808 void AppLnk::setIcon( const QString& iconname )
00809 {
00810 mIconFile = iconname;
00811 QImage unscaledIcon = Resource::loadImage( mIconFile );
00812 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
00813 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
00814 }
00815
00823 void AppLnk::setCategories( const QArray<int>& c )
00824 {
00825 d->mCat = c;
00826 d->updateCatListFromArray();
00827 }
00828
00842 bool AppLnk::ensureLinkExists() const
00843 {
00844 QString lf = linkFile();
00845 return prepareDirectories(lf);
00846 }
00847
00855 bool AppLnk::writeLink() const
00856 {
00857
00858 QString lf = linkFile();
00859 if ( !ensureLinkExists() )
00860 return FALSE;
00861 storeLink();
00862 return TRUE;
00863 }
00864
00868 void AppLnk::storeLink() const
00869 {
00870 Config config( mLinkFile, Config::File );
00871 config.setGroup("Desktop Entry");
00872 config.writeEntry("Name",mName);
00873 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
00874 config.writeEntry("Type",type());
00875 if(!rotation().isEmpty())
00876 config.writeEntry("Rotation",rotation());
00877 else
00878 config.removeEntry("Rotation");
00879 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
00880 QString f = file();
00881 int i = 0;
00882 while ( i < (int)f.length() && i < (int)mLinkFile.length() && f[i] == mLinkFile[i] )
00883 i++;
00884 while ( i && f[i] != '/' )
00885 i--;
00886
00887 if ( mLinkFile.find( '/', i + 1 ) < 0 )
00888 f = f.mid(i+1);
00889
00890 config.writeEntry("File",f);
00891 config.writeEntry( "Categories", d->mCatList, ';' );
00892
00893 #ifndef QT_NO_COP
00894 QCopEnvelope e("QPE/System", "linkChanged(QString)");
00895 e << mLinkFile;
00896 #endif
00897 }
00898
00904 void AppLnk::setProperty(const QString& key, const QString& value)
00905 {
00906 if ( ensureLinkExists() ) {
00907 Config cfg(linkFile(), Config::File);
00908 cfg.writeEntry(key,value);
00909 }
00910 }
00911
00917 QString AppLnk::property(const QString& key) const
00918 {
00919 QString lf = linkFile();
00920 if ( !QFile::exists(lf) )
00921 return QString::null;
00922 Config cfg(lf, Config::File);
00923 return cfg.readEntry(key);
00924 }
00925
00926 bool AppLnk::isPreloaded() const {
00927
00928 Config cfg("Launcher");
00929 cfg.setGroup("Preload");
00930 QStringList apps = cfg.readListEntry("Apps",',');
00931 if (apps.contains(exec()))
00932 return true;
00933 return false;
00934 }
00935
00936 void AppLnk::setPreloaded(bool yesNo) {
00937
00938 Config cfg("Launcher");
00939 cfg.setGroup("Preload");
00940 QStringList apps = cfg.readListEntry("Apps", ',');
00941 if (apps.contains(exec()) && !yesNo)
00942 apps.remove(exec());
00943 else if (yesNo && !apps.contains(exec()))
00944 apps.append(exec());
00945 cfg.writeEntry("Apps", apps, ',');
00946 }
00947
00948
00954 void AppLnk::removeFiles()
00955 {
00956 bool valid = isValid();
00957 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
00958 if ( QFile::remove(file()) ) {
00959 #ifndef QT_NO_COP
00960 QCopEnvelope e("QPE/System", "linkChanged(QString)");
00961 if ( linkFileKnown() )
00962 e << linkFile();
00963 else
00964 e << file();
00965 #endif
00966 } else if ( valid ) {
00967
00968 writeLink();
00969 }
00970 }
00971 }
00972
00978 void AppLnk::removeLinkFile()
00979 {
00980 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
00981 #ifndef QT_NO_COP
00982 QCopEnvelope e("QPE/System", "linkChanged(QString)");
00983 e << linkFile();
00984 #endif
00985 }
00986 }
00987
00988 class AppLnkImagePrivate {
00989 public :
00990 AppLnkImagePrivate( const QString & ImageName ) {
00991 IconName = ImageName;
00992 Small = 0;
00993 Big = 0;
00994 }
00995 ~AppLnkImagePrivate( ) {
00996 if ( Small ) delete Small;
00997 if ( Big ) delete Big;
00998 }
00999
01000 inline QPixmap * small( void ) {
01001 if( ! Small ) {
01002 QImage unscaledIcon = Resource::loadImage( IconName );
01003
01004 Small = new QPixmap();
01005 Small->convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
01006 }
01007 return Small;
01008 }
01009
01010 inline QPixmap * big( void ) {
01011 if( ! Big ) {
01012 QImage unscaledIcon = Resource::loadImage( IconName );
01013
01014 Big = new QPixmap();
01015 Big->convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
01016 }
01017 return Big;
01018 }
01019
01020 QString IconName;
01021 QPixmap * Small;
01022 QPixmap * Big;
01023 };
01024
01025 class AppLnkSetPrivate {
01026 public:
01027 AppLnkSetPrivate()
01028 {
01029 typPix.setAutoDelete(TRUE);
01030 typName.setAutoDelete(TRUE);
01031 }
01032
01033 QDict<AppLnkImagePrivate> typPix;
01034 QDict<QString> typName;
01035 };
01036
01062 AppLnkSet::AppLnkSet() :
01063 d(new AppLnkSetPrivate)
01064 {
01065 }
01066
01078 AppLnkSet::AppLnkSet( const QString &directory ) :
01079 d(new AppLnkSetPrivate)
01080 {
01081 QDir dir( directory );
01082 mFile = directory;
01083 findChildren(directory,QString::null,QString::null);
01084 }
01085
01090 void AppLnkSet::detachChildren()
01091 {
01092 QListIterator<AppLnk> it( mApps );
01093 for ( ; it.current(); ) {
01094 AppLnk* a = *it;
01095 ++it;
01096 a->mId = 0;
01097 }
01098 mApps.clear();
01099 }
01100
01106 AppLnkSet::~AppLnkSet()
01107 {
01108 QListIterator<AppLnk> it( mApps );
01109 for ( ; it.current(); ) {
01110 AppLnk* a = *it;
01111 ++it;
01112 a->mId = 0;
01113 delete a;
01114 }
01115 delete d;
01116 }
01117
01118 void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth)
01119 {
01120 depth++;
01121 if ( depth > 10 )
01122 return;
01123
01124 QDir dir( dr );
01125 QString typNameLocal = typName;
01126
01127 if ( dir.exists( ".directory" ) ) {
01128 Config config( dr + "/.directory", Config::File );
01129 config.setGroup( "Desktop Entry" );
01130 typNameLocal = config.readEntry( "Name", typNameLocal );
01131 if ( !typ.isEmpty() ) {
01132 d->typPix.insert( typ,
01133 new AppLnkImagePrivate( config.readEntry( "Icon", "AppsIcon" ) )
01134 );
01135 d->typName.insert(typ, new QString(typNameLocal));
01136
01137 }
01138 }
01139
01140 const QFileInfoList *list = dir.entryInfoList();
01141 if ( list ) {
01142 QFileInfo* fi;
01143 bool cadded=FALSE;
01144 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
01145 QString bn = fi->fileName();
01146
01147 if ( bn[0] != '.' && bn != "CVS" ) {
01148 if ( fi->isDir() ) {
01149 QString c = typ.isNull() ? bn : typ+"/"+bn;
01150 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
01151 findChildren(fi->filePath(), c, d, depth );
01152 } else {
01153 if ( fi->extension(FALSE) == "desktop" ) {
01154 AppLnk* app = new AppLnk( fi->filePath() );
01155 #ifdef QT_NO_QWS_MULTIPROCESS
01156 if ( !Global::isBuiltinCommand( app->exec() ) )
01157 delete app;
01158 else
01159 #endif
01160 {
01161 if ( !typ.isEmpty() ) {
01162 if ( !cadded ) {
01163 typs.append(typ);
01164 cadded = TRUE;
01165 }
01166 app->setType(typ);
01167 }
01168 add(app);
01169 }
01170 }
01171 }
01172 }
01173 }
01174 }
01175 }
01176
01183 void AppLnkSet::add( AppLnk *f )
01184 {
01185 if ( f->mId == 0 ) {
01186 AppLnk::lastId++;
01187 f->mId = AppLnk::lastId;
01188 mApps.append( f );
01189 } else {
01190 qWarning("Attempt to add an AppLnk twice");
01191 }
01192 }
01193
01201 bool AppLnkSet::remove( AppLnk *f )
01202 {
01203 if ( mApps.remove( f ) ) {
01204 f->mId = 0;
01205 return TRUE;
01206 }
01207 return FALSE;
01208 }
01209
01210
01217 QString AppLnkSet::typeName( const QString& t ) const
01218 {
01219 QString *st = d->typName.find(t);
01220 return st ? *st : QString::null;
01221 }
01222
01229 QPixmap AppLnkSet::typePixmap( const QString& t ) const
01230 {
01231 AppLnkImagePrivate *alip = d->typPix.find(t);
01232 return alip ? *(alip->small()) : QPixmap();
01233 }
01234
01241 QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
01242 {
01243 AppLnkImagePrivate *alip = d->typPix.find(t);
01244 return alip ? *(alip->big()) : QPixmap();
01245 }
01246
01250 const AppLnk *AppLnkSet::find( int id ) const
01251 {
01252 QListIterator<AppLnk> it( children() );
01253
01254 for ( ; it.current(); ++it ) {
01255 const AppLnk *app = it.current();
01256 if ( app->id() == id )
01257 return app;
01258 }
01259
01260 return 0;
01261 }
01262
01266 const AppLnk *AppLnkSet::findExec( const QString& exec ) const
01267 {
01268 QListIterator<AppLnk> it( children() );
01269
01270 for ( ; it.current(); ++it ) {
01271 const AppLnk *app = it.current();
01272 if ( app->exec() == exec )
01273 return app;
01274 }
01275
01276 return 0;
01277 }
01278
01295 DocLnkSet::DocLnkSet()
01296 {
01297 }
01298
01311 DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
01312 AppLnkSet()
01313 {
01314 QDir dir( directory );
01315 mFile = dir.dirName();
01316 QDict<void> reference(1021);
01317
01318 QStringList subFilter = QStringList::split(";", mimefilter);
01319 QValueList<QRegExp> mimeFilters;
01320 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
01321 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
01322
01323 findChildren(directory, mimeFilters, reference);
01324
01325 const QList<DocLnk> &list = children();
01326 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
01327 reference.remove( (*it)->file() );
01328 }
01329 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
01330 if ( dit.current() == (void*)2 ) {
01331
01332 DocLnk* dl = new DocLnk;
01333 QFileInfo fi( dit.currentKey() );
01334 dl->setFile(fi.filePath());
01335 dl->setName(fi.baseName());
01336
01337
01338 bool match = mimefilter.isNull();
01339 if ( !match )
01340 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it )
01341 if ( (*it).match(dl->type()) >= 0 )
01342 match = TRUE;
01343 if ( match
01344 && !!dl->exec() )
01345 add(dl);
01346 else
01347 delete dl;
01348 }
01349 }
01350 }
01351
01352
01357 void DocLnkSet::appendFrom( DocLnkSet& other )
01358 {
01359 if ( &other == this )
01360 return;
01361 QListIterator<AppLnk> it( other.mApps );
01362 for ( ; it.current(); ) {
01363 mApps.append(*it);
01364 ++it;
01365 }
01366 other.mApps.clear();
01367 }
01368
01369 void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth)
01370 {
01371 depth++;
01372 if ( depth > 10 )
01373 return;
01374
01375 QDir dir( dr );
01376
01377
01378
01379
01380
01381 if ( dir.exists( ".Qtopia-ignore" ) )
01382 return;
01383
01384 const QFileInfoList *list = dir.entryInfoList();
01385 if ( list ) {
01386 QFileInfo* fi;
01387 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
01388 QString bn = fi->fileName();
01389 if ( bn[0] != '.' ) {
01390 if ( fi->isDir() ) {
01391 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" )
01392 findChildren(fi->filePath(), mimeFilters, reference, depth);
01393 } else {
01394 if ( fi->extension(FALSE) == "desktop" ) {
01395 DocLnk* dl = new DocLnk( fi->filePath() );
01396 QFileInfo fi2(dl->file());
01397 bool match = FALSE;
01398 if ( !fi2.exists() ) {
01399 dir.remove( dl->file() );
01400 }
01401 if ( mimeFilters.count() == 0 ) {
01402 add( dl );
01403 match = TRUE;
01404 } else {
01405 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
01406 if ( (*it).match(dl->type()) >= 0 ) {
01407 add(dl);
01408 match = TRUE;
01409 }
01410 }
01411 }
01412 if ( !match )
01413 delete dl;
01414 } else {
01415 if ( !reference.find(fi->fileName()) )
01416 reference.insert(fi->filePath(), (void*)2);
01417 }
01418 }
01419 }
01420 }
01421 }
01422 }
01423
01439 DocLnk::DocLnk( const QString &file ) :
01440 AppLnk(file)
01441 {
01442 init(file);
01443 }
01444
01451 DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
01452 AppLnk(may_be_desktopfile ? file : QString::null)
01453 {
01454 init(file);
01455 }
01456
01457 void DocLnk::init(const QString &file)
01458 {
01459 if ( isValid() ) {
01460 #ifndef FORCED_DIR_STRUCTURE_WAY
01461 if ( mType.isNull() )
01462
01463 #endif
01464 {
01465 int s0 = file.findRev('/');
01466 if ( s0 > 0 ) {
01467 int s1 = file.findRev('/',s0-1);
01468 if ( s1 > 0 ) {
01469 int s2 = file.findRev('/',s1-1);
01470 if ( s2 > 0 ) {
01471 mType = file.mid(s2+1,s0-s2-1);
01472 }
01473 }
01474 }
01475 }
01476 } else if ( QFile::exists(file) ) {
01477 QString n = file;
01478 n.replace(QRegExp(".*/"),"");
01479 n.replace(QRegExp("\\..*"),"");
01480 setName( n );
01481 setFile( file );
01482 }
01483 MimeType mt(mType);
01484 if( mt.application() )
01485 mExec = mt.application()->exec();
01486 }
01487
01491 DocLnk::DocLnk()
01492 {
01493 }
01494
01499 DocLnk::~DocLnk()
01500 {
01501 }
01502
01506 QString DocLnk::exec() const
01507 {
01508 MimeType mt(type());
01509 const AppLnk* app = mt.application();
01510 if ( app )
01511 return app->exec();
01512 else
01513 return QString::null;
01514 }
01515
01519 void DocLnk::invoke(const QStringList& args) const
01520 {
01521 MimeType mt(type());
01522 const AppLnk* app = mt.application();
01523 if ( app ) {
01524 QStringList a = args;
01525 if ( linkFileKnown() && QFile::exists( linkFile() ) )
01526 a.append(linkFile());
01527 else
01528 a.append(file());
01529 app->execute(a);
01530 }
01531 }
01532
01533