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 <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
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
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
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 }