mimetype.cpp
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 #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 <qdict.h>
00030 #include <qregexp.h>
00031 #include <qstringlist.h>
00032 #include <qtextstream.h>
00033 #include <qmap.h>
00034
00035
00036 static void cleanupMime()
00037 {
00038 MimeType::clear();
00039 }
00040
00041 class MimeTypeData {
00042 public:
00043 MimeTypeData(const QString& i) :
00044 id(i)
00045 {
00046 apps.setAutoDelete(TRUE);
00047 }
00048 QString id;
00049 QString extension;
00050 QList<AppLnk> apps;
00051
00052 QString description()
00053 {
00054 if ( desc.isEmpty() )
00055 desc = QPEApplication::tr("%1 document").arg(apps.first()->name());
00056 return desc;
00057 }
00058
00059 QPixmap regIcon()
00060 {
00061 if ( regicon.isNull() )
00062 loadPixmaps();
00063 return regicon;
00064 }
00065
00066 QPixmap bigIcon()
00067 {
00068 if ( bigicon.isNull() )
00069 loadPixmaps();
00070 return bigicon;
00071 }
00072
00073 private:
00074 void loadPixmaps()
00075 {
00076 if ( apps.count() ) {
00077 QString icon;
00078 for (AppLnk* lnk = apps.first(); icon.isNull() && lnk; lnk=apps.next()) {
00079 QStringList icons = lnk->mimeTypeIcons();
00080 if ( icons.count() ) {
00081 QStringList types = lnk->mimeTypes();
00082 for (QStringList::ConstIterator t=types.begin(),i=icons.begin(); t!=types.end() && i!=icons.end(); ++i,++t) {
00083 if ( *t == id ) {
00084 icon = *i;
00085 break;
00086 }
00087 }
00088 }
00089 }
00090 if ( icon.isNull() ) {
00091 AppLnk* lnk = apps.first();
00092 regicon = lnk->pixmap();
00093 bigicon = lnk->bigPixmap();
00094 } else {
00095 QImage unscaledIcon = Resource::loadImage( icon );
00096 regicon.convertFromImage( unscaledIcon.smoothScale( AppLnk::smallIconSize(), AppLnk::smallIconSize() ) );
00097 bigicon.convertFromImage( unscaledIcon.smoothScale( AppLnk::bigIconSize(), AppLnk::bigIconSize() ) );
00098 }
00099 }
00100 }
00101
00102 QPixmap regicon;
00103 QPixmap bigicon;
00104 QString desc;
00105 };
00106
00107 class MimeType::Private : public QDict<MimeTypeData> {
00108 public:
00109 Private() {}
00110 ~Private() {}
00111
00112
00113 };
00114
00115 MimeType::Private* MimeType::d=0;
00116 static QMap<QString,QString> *typeFor = 0;
00117 static QMap<QString,QStringList> *extFor = 0;
00118
00119 MimeType::Private& MimeType::data()
00120 {
00121 if ( !d ) {
00122 d = new Private;
00123 d->setAutoDelete(TRUE);
00124 static bool setCleanup = FALSE;
00125 if ( !setCleanup ) {
00126 qAddPostRoutine( cleanupMime );
00127 setCleanup = TRUE;
00128 }
00129 }
00130 return *d;
00131 }
00132
00151 MimeType::MimeType( const QString& ext_or_id )
00152 {
00153 init(ext_or_id);
00154 }
00155
00159 MimeType::MimeType( const DocLnk& lnk )
00160 {
00161 init(lnk.type());
00162 }
00163
00167 QString MimeType::id() const
00168 {
00169 return i;
00170 }
00171
00176 QString MimeType::description() const
00177 {
00178 MimeTypeData* d = data(i);
00179 return d ? d->description() : QString::null;
00180 }
00181
00185 QPixmap MimeType::pixmap() const
00186 {
00187 MimeTypeData* d = data(i);
00188 return d ? d->regIcon() : QPixmap();
00189 }
00190
00195 QString MimeType::extension() const
00196 {
00197 return extensions().first();
00198 }
00199
00200
00205 QStringList MimeType::extensions() const
00206 {
00207 loadExtensions();
00208 return *(*extFor).find(i);
00209 }
00210
00214 QPixmap MimeType::bigPixmap() const
00215 {
00216 MimeTypeData* d = data(i);
00217 return d ? d->bigIcon() : QPixmap();
00218 }
00219
00229 const AppLnk* MimeType::application() const
00230 {
00231 MimeTypeData* d = data(i);
00232 return d ? d->apps.first() : 0;
00233 }
00234
00235 static QString serviceBinding(const QString& service)
00236 {
00237
00238 QString svrc = service;
00239 for (int i=0; i<(int)svrc.length(); i++)
00240 if ( svrc[i]=='/' ) svrc[i] = '-';
00241 return "Service-"+svrc;
00242 }
00243
00247 void MimeType::registerApp( const AppLnk& lnk )
00248 {
00249 QStringList list = lnk.mimeTypes();
00250 for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
00251 MimeTypeData* cur = data()[*it];
00252 AppLnk* l = new AppLnk(lnk);
00253 if ( !cur ) {
00254 cur = new MimeTypeData( *it );
00255 data().insert( *it, cur );
00256 cur->apps.append(l);
00257 } else if ( cur->apps.count() ) {
00258 Config binding(serviceBinding("Open/"+*it));
00259 binding.setGroup("Service");
00260 QString def = binding.readEntry("default");
00261 if ( l->exec() == def )
00262 cur->apps.prepend(l);
00263 else
00264 cur->apps.append(l);
00265 } else {
00266 cur->apps.append(l);
00267 }
00268 }
00269 }
00270
00274 void MimeType::clear()
00275 {
00276 delete d;
00277 d = 0;
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
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 static bool appsUpdated = FALSE;
00330 if ( !appsUpdated ) {
00331 appsUpdated = TRUE;
00332 updateApplications();
00333 }
00334 }
00335
00336 MimeTypeData* MimeType::data(const QString& id)
00337 {
00338 MimeTypeData* d = data()[id];
00339 if ( !d ) {
00340 int s = id.find('/');
00341 QString idw = id.left(s)+"/*";
00342 d = data()[idw];
00343 }
00344 return d;
00345 }
00346
00350 QString MimeType::appsFolderName()
00351 {
00352 return QPEApplication::qpeDir() + "apps";
00353 }
00354
00358 void MimeType::updateApplications()
00359 {
00360 clear();
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 }
This file is part of the documentation for OPIE Version 1.5.5.