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

mimetype.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 #include "mimetype.h"
00023 #include "applnk.h"
00024 #include "resource.h"
00025 #include <qpe/qpeapplication.h>
00026 #include "config.h"
00027 
00028 #include <qfile.h>
00029 #include <qtextstream.h>
00030 
00031 
00032 static void cleanupMime()
00033 {
00034     MimeType::clear();
00035 }
00036 
00037 class MimeTypeData {
00038 public:
00039     MimeTypeData(const QString& i) :
00040         id(i)
00041     {
00042         apps.setAutoDelete(TRUE);
00043     }
00044     QString id;
00045     QString extension;
00046     QList<AppLnk> apps;
00047 
00048     QString description()
00049     {
00050         if ( desc.isEmpty() )
00051             desc = QPEApplication::tr("%1 document").arg(apps.first()->name());
00052         return desc;
00053     }
00054 
00055     QPixmap regIcon()
00056     {
00057         if ( regicon.isNull() )
00058             loadPixmaps();
00059         return regicon;
00060     }
00061 
00062     QPixmap bigIcon()
00063     {
00064         if ( bigicon.isNull() )
00065             loadPixmaps();
00066         return bigicon;
00067     }
00068 
00069 private:
00070     void loadPixmaps()
00071     {
00072         if ( apps.count() ) {
00073             QString icon;
00074             for (AppLnk* lnk = apps.first(); icon.isNull() && lnk; lnk=apps.next()) {
00075                 QStringList icons = lnk->mimeTypeIcons();
00076                 if ( icons.count() ) {
00077                     QStringList types = lnk->mimeTypes();
00078                     for (QStringList::ConstIterator t=types.begin(),i=icons.begin(); t!=types.end() && i!=icons.end(); ++i,++t) {
00079                         if ( *t == id ) {
00080                             icon = *i;
00081                             break;
00082                         }
00083                     }
00084                 }
00085             }
00086             if ( icon.isNull() ) {
00087                 AppLnk* lnk = apps.first();
00088                 regicon = lnk->pixmap();
00089                 bigicon = lnk->bigPixmap();
00090             } else {
00091                 QImage unscaledIcon = Resource::loadImage( icon );
00092                 regicon.convertFromImage( unscaledIcon.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ) );
00093                 bigicon.convertFromImage( unscaledIcon.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ) );
00094             }
00095         }
00096     }
00097 
00098     QPixmap regicon;
00099     QPixmap bigicon;
00100     QString desc;
00101 };
00102 
00103 class MimeType::Private : public QDict<MimeTypeData> {
00104 public:
00105     Private() {}
00106     ~Private() {}
00107 
00108     // ...
00109 };
00110 
00111 MimeType::Private* MimeType::d=0;
00112 static QMap<QString,QString> *typeFor = 0;
00113 static QMap<QString,QStringList> *extFor = 0;
00114 static bool appsUpdated = FALSE;
00115 
00116 MimeType::Private& MimeType::data()
00117 {
00118     if ( !d ) {
00119         d = new Private;
00120         d->setAutoDelete(TRUE);
00121         static bool setCleanup = FALSE;
00122         if ( !setCleanup ) {
00123             qAddPostRoutine( cleanupMime );
00124             setCleanup = TRUE;
00125         }
00126     }
00127     return *d;
00128 }
00129 
00148 MimeType::MimeType( const QString& ext_or_id )
00149 {
00150     init(ext_or_id);
00151 }
00152 
00156 MimeType::MimeType( const DocLnk& lnk )
00157 {
00158     init(lnk.type());
00159 }
00160 
00164 QString MimeType::id() const
00165 {
00166     return i;
00167 }
00168 
00173 QString MimeType::description() const
00174 {
00175     MimeTypeData* d = data(i);
00176     return d ? d->description() : QString::null;
00177 }
00178 
00182 QPixmap MimeType::pixmap() const
00183 {
00184     MimeTypeData* d = data(i);
00185     return d ? d->regIcon() : QPixmap();
00186 }
00187 
00192 QString MimeType::extension() const
00193 {
00194     return extensions().first();
00195 }
00196 
00197 
00202 QStringList MimeType::extensions() const
00203 {
00204     loadExtensions();
00205     return *(*extFor).find(i);
00206 }
00207 
00211 QPixmap MimeType::bigPixmap() const
00212 {
00213     MimeTypeData* d = data(i);
00214     return d ? d->bigIcon() : QPixmap();
00215 }
00216 
00226 const AppLnk* MimeType::application() const
00227 {
00228     MimeTypeData* d = data(i);
00229     return d ? d->apps.first() : 0;
00230 }
00231 
00232 static QString serviceBinding(const QString& service)
00233 {
00234     // Copied from qtopiaservices
00235     QString svrc = service;
00236     for (int i=0; i<(int)svrc.length(); i++)
00237         if ( svrc[i]=='/' ) svrc[i] = '-';
00238     return "Service-"+svrc;
00239 }
00240 
00244 void MimeType::registerApp( const AppLnk& lnk )
00245 {
00246     QStringList list = lnk.mimeTypes();
00247     for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
00248         MimeTypeData* cur = data()[*it];
00249         AppLnk* l = new AppLnk(lnk);
00250         if ( !cur ) {
00251             cur = new MimeTypeData( *it );
00252             data().insert( *it, cur );
00253             cur->apps.append(l);
00254         } else if ( cur->apps.count() ) {
00255             Config binding(serviceBinding("Open/"+*it));
00256             binding.setGroup("Service");
00257             QString def = binding.readEntry("default");
00258             if ( l->exec() == def )
00259                 cur->apps.prepend(l);
00260             else
00261                 cur->apps.append(l);
00262         } else {
00263             cur->apps.append(l);
00264         }
00265     }
00266 }
00267 
00271 void MimeType::clear()
00272 {
00273     delete d;
00274     d = 0;
00275     delete typeFor; typeFor = 0;
00276     delete extFor ; extFor  = 0;
00277     appsUpdated = FALSE;
00278 }
00279 
00280 void MimeType::loadExtensions()
00281 {
00282     if ( !typeFor ) {
00283         extFor = new QMap<QString,QStringList>;
00284         typeFor = new QMap<QString,QString>;
00285         loadExtensions("/etc/mime.types");
00286         loadExtensions(QPEApplication::qpeDir()+"etc/mime.types");
00287     }
00288 }
00289 
00290 void MimeType::loadExtensions(const QString& filename)
00291 {
00292     QFile file(filename);
00293     if ( file.open(IO_ReadOnly) ) {
00294         QTextStream in(&file);
00295         QRegExp space("[ \t]+");
00296         while (!in.atEnd()) {
00297             QStringList tokens = QStringList::split(space, in.readLine());
00298             QStringList::ConstIterator it = tokens.begin();
00299             if ( it != tokens.end() ) {
00300                 QString id = *it; ++it;
00301                 // new override old (though left overrides right)
00302                 QStringList exts = (*extFor)[id];
00303                 QStringList newexts;
00304                 while ( it != tokens.end() ) {
00305                     exts.remove(*it);
00306                     if ( !newexts.contains(*it) )
00307                         newexts.append(*it);
00308                     (*typeFor)[*it] = id;
00309                     ++it;
00310                 }
00311                 (*extFor)[id] = newexts + exts;
00312             }
00313         }
00314     }
00315 }
00316 
00317 void MimeType::init( const QString& ext_or_id )
00318 {
00319     if ( ext_or_id[0] != '/' && ext_or_id.contains('/') ) {
00320         i = ext_or_id.lower();
00321     } else {
00322         loadExtensions();
00323         int dot = ext_or_id.findRev('.');
00324         QString ext = dot >= 0 ? ext_or_id.mid(dot+1) : ext_or_id;
00325         i = (*typeFor)[ext.lower()];
00326         if ( i.isNull() )
00327             i = "application/octet-stream";
00328     }
00329 
00330     if ( !appsUpdated ) {
00331         updateApplications();
00332     }
00333 }
00334 
00335 MimeTypeData* MimeType::data(const QString& id)
00336 {
00337     MimeTypeData* d = data()[id];
00338     if ( !d ) {
00339         int s = id.find('/');
00340         QString idw = id.left(s)+"/*";
00341         d = data()[idw];
00342     }
00343     return d;
00344 }
00345 
00349 QString MimeType::appsFolderName()
00350 {
00351     return QPEApplication::qpeDir() + "apps";
00352 }
00353 
00357 void MimeType::updateApplications()
00358 {
00359 //    clear();
00360     appsUpdated = true;
00361     AppLnkSet apps( appsFolderName() );
00362     updateApplications(&apps);
00363 }
00364 
00365 void MimeType::updateApplications(AppLnkSet* folder)
00366 {
00367     for ( QListIterator<AppLnk> it( folder->children() ); it.current(); ++it ) {
00368         registerApp(*it.current());
00369     }
00370 }

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