Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

applnk.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
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   // May need to create directories
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     /* the size of the Pixmap */
00072     enum Size {Normal = 0, Big };
00073     AppLnkPrivate() {
00074         /* we want one normal and one big item */
00075 
00076         QPixmap pix;
00077         mPixmaps.insert(0, pix );
00078         mPixmaps.insert(1,  pix);
00079     }
00080 
00081     QStringList mCatList; // always correct
00082     QArray<int> mCat; // cached value; correct if not empty
00083     QMap<int,  QPixmap> mPixmaps;
00084 
00085     void updateCatListFromArray()
00086     {
00087   Categories cat( 0 );
00088   cat.load( categoryFileName() );
00089   // we need to update the names for the mCat... to mCatList
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       // MIME types are case-insensitive.
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     // numeric cats in file! convert to text
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       // convert from text
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 &copy)
00425 {
00426     if ( this == &copy ) 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     /* remove for Qtopia 3.0 -zecke */
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            //  qDebug( "Cannot find icon: %s", that->mIconFile.latin1() );
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" // 8 = strlen(".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              * A file with the same name or a .desktop file already exists
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             /* tmpfs + and ramfs are available too but not removable
00593              * either we fix storage or add this
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             /* the desktop file exists make sure we don't point to the same file */
00602       if ( QFile::exists(that->mLinkFile+".desktop") ) {
00603                 AppLnk lnk( that->mLinkFile + ".desktop" );
00604 
00605                 /* the linked is different */
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                         /* just to be sure */
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 &copy )
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   // ######## this will only work in the server
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     // Only re-writes settable parts
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     // simple case where in the same directory
00887     if ( mLinkFile.find( '/', i + 1 ) < 0 )
00888   f = f.mid(i+1);
00889     // ### could do relative ie ../../otherDocs/file.doc
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   // Preload information is stored in the Launcher config in v1.5.
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   // Preload information is stored in the Launcher config in v1.5.
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       // restore link
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               // works as long as smallSize remains static
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               // works as long as bigSize remains static
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   //      qDebug("findChildren "+bn);
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       // Unreferenced, make an unwritten link
01332       DocLnk* dl = new DocLnk;
01333       QFileInfo fi( dit.currentKey() );
01334       dl->setFile(fi.filePath());
01335       dl->setName(fi.baseName());
01336       // #### default to current path?
01337       // dl->setCategories( ... );
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 /* && dl->type() != "application/octet-stream" */
01344         && !!dl->exec() )
01345     add(dl);
01346       else
01347     delete dl;
01348   }
01349     }
01350 }
01351 
01352 // other becomes empty
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     /* Opie got a different approach
01378      * I guess it's geek vs. consumer
01379      * in this case to be discussed
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       // try to infer it
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 

Generated on Sat Nov 5 16:16:31 2005 for OPIE by  doxygen 1.4.2