00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025
00026 #include <assert.h>
00027 #include <dirent.h>
00028 #include <errno.h>
00029 #include <stddef.h>
00030 #include <unistd.h>
00031 #include <stdlib.h>
00032
00033 #include <kprotocolinfo.h>
00034 #include <kio/global.h>
00035 #include "kmimetype.h"
00036 #include "kservicetypefactory.h"
00037 #include "kmimemagic.h"
00038 #include "kservice.h"
00039 #include "krun.h"
00040 #include "kautomount.h"
00041 #include <kdirnotify_stub.h>
00042
00043 #include <qstring.h>
00044 #include <qfile.h>
00045 #include <kmessageboxwrapper.h>
00046
00047 #include <dcopclient.h>
00048 #include <dcopref.h>
00049 #include <kapplication.h>
00050 #include <kprocess.h>
00051 #include <kdebug.h>
00052 #include <kdesktopfile.h>
00053 #include <kdirwatch.h>
00054 #include <kiconloader.h>
00055 #include <klocale.h>
00056 #include <ksimpleconfig.h>
00057 #include <kstandarddirs.h>
00058 #include <kurl.h>
00059 #include <ksycoca.h>
00060 #include <kde_file.h>
00061
00062 template class KSharedPtr<KMimeType>;
00063 template class QValueList<KMimeType::Ptr>;
00064
00065 KMimeType::Ptr KMimeType::s_pDefaultType = 0L;
00066 bool KMimeType::s_bChecked = false;
00067
00068 void KMimeType::buildDefaultType()
00069 {
00070 assert ( !s_pDefaultType );
00071
00072 KServiceType * mime = KServiceTypeFactory::self()->
00073 findServiceTypeByName( defaultMimeType() );
00074
00075 if (mime && mime->isType( KST_KMimeType ))
00076 {
00077 s_pDefaultType = KMimeType::Ptr((KMimeType *) mime);
00078 }
00079 else
00080 {
00081 errorMissingMimeType( defaultMimeType() );
00082 KStandardDirs stdDirs;
00083 QString sDefaultMimeType = stdDirs.resourceDirs("mime").first()+defaultMimeType()+".desktop";
00084 s_pDefaultType = new KMimeType( sDefaultMimeType, defaultMimeType(),
00085 "unknown", "mime", QStringList() );
00086 }
00087 }
00088
00089 KMimeType::Ptr KMimeType::defaultMimeTypePtr()
00090 {
00091 if ( !s_pDefaultType )
00092 buildDefaultType();
00093 return s_pDefaultType;
00094 }
00095
00096
00097 void KMimeType::checkEssentialMimeTypes()
00098 {
00099 if ( s_bChecked )
00100 return;
00101 if ( !s_pDefaultType )
00102 buildDefaultType();
00103
00104 s_bChecked = true;
00105
00106
00107
00108 if ( !KServiceTypeFactory::self()->checkMimeTypes() )
00109 {
00110 KMessageBoxWrapper::error( 0L, i18n( "No mime types installed." ) );
00111 return;
00112 }
00113
00114 if ( KMimeType::mimeType( "inode/directory" ) == s_pDefaultType )
00115 errorMissingMimeType( "inode/directory" );
00116 if ( KMimeType::mimeType( "inode/directory-locked" ) == s_pDefaultType )
00117 errorMissingMimeType( "inode/directory-locked" );
00118 if ( KMimeType::mimeType( "inode/blockdevice" ) == s_pDefaultType )
00119 errorMissingMimeType( "inode/blockdevice" );
00120 if ( KMimeType::mimeType( "inode/chardevice" ) == s_pDefaultType )
00121 errorMissingMimeType( "inode/chardevice" );
00122 if ( KMimeType::mimeType( "inode/socket" ) == s_pDefaultType )
00123 errorMissingMimeType( "inode/socket" );
00124 if ( KMimeType::mimeType( "inode/fifo" ) == s_pDefaultType )
00125 errorMissingMimeType( "inode/fifo" );
00126 if ( KMimeType::mimeType( "application/x-shellscript" ) == s_pDefaultType )
00127 errorMissingMimeType( "application/x-shellscript" );
00128 if ( KMimeType::mimeType( "application/x-executable" ) == s_pDefaultType )
00129 errorMissingMimeType( "application/x-executable" );
00130 if ( KMimeType::mimeType( "application/x-desktop" ) == s_pDefaultType )
00131 errorMissingMimeType( "application/x-desktop" );
00132 }
00133
00134 void KMimeType::errorMissingMimeType( const QString& _type )
00135 {
00136 QString tmp = i18n( "Could not find mime type\n%1" ).arg( _type );
00137
00138 KMessageBoxWrapper::sorry( 0, tmp );
00139 }
00140
00141 KMimeType::Ptr KMimeType::mimeType( const QString& _name )
00142 {
00143 KServiceType * mime = KServiceTypeFactory::self()->findServiceTypeByName( _name );
00144
00145 if ( !mime || !mime->isType( KST_KMimeType ) )
00146 {
00147
00148
00149 if ( !KSycoca::self()->isBuilding() )
00150 delete mime;
00151 if ( !s_pDefaultType )
00152 buildDefaultType();
00153 return s_pDefaultType;
00154 }
00155
00156
00157 return KMimeType::Ptr((KMimeType *) mime);
00158 }
00159
00160 KMimeType::List KMimeType::allMimeTypes()
00161 {
00162 return KServiceTypeFactory::self()->allMimeTypes();
00163 }
00164
00165 KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode,
00166 bool _is_local_file, bool _fast_mode )
00167 {
00168 checkEssentialMimeTypes();
00169 QString path = _url.path();
00170
00171 if ( !_fast_mode && !_is_local_file && _url.isLocalFile() )
00172 _is_local_file = true;
00173
00174 if ( !_fast_mode && _is_local_file && (_mode == 0 || _mode == (mode_t)-1) )
00175 {
00176 KDE_struct_stat buff;
00177 if ( KDE_stat( QFile::encodeName(path), &buff ) != -1 )
00178 _mode = buff.st_mode;
00179 }
00180
00181
00182 if ( S_ISDIR( _mode ) )
00183 {
00184
00185
00186 if ( _is_local_file )
00187 {
00188 if ( access( QFile::encodeName(path), R_OK ) == -1 )
00189 return mimeType( "inode/directory-locked" );
00190 }
00191 return mimeType( "inode/directory" );
00192 }
00193 if ( S_ISCHR( _mode ) )
00194 return mimeType( "inode/chardevice" );
00195 if ( S_ISBLK( _mode ) )
00196 return mimeType( "inode/blockdevice" );
00197 if ( S_ISFIFO( _mode ) )
00198 return mimeType( "inode/fifo" );
00199 if ( S_ISSOCK( _mode ) )
00200 return mimeType( "inode/socket" );
00201
00202 if ( !_is_local_file && S_ISREG( _mode ) && ( _mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) )
00203 return mimeType( "application/x-executable" );
00204
00205 QString fileName ( _url.fileName() );
00206
00207 static const QString& slash = KGlobal::staticQString("/");
00208 if ( ! fileName.isNull() && !path.endsWith( slash ) )
00209 {
00210
00211 KMimeType::Ptr mime = KServiceTypeFactory::self()->findFromPattern( fileName );
00212 if ( mime )
00213 {
00214
00215 if ( _is_local_file || _url.hasSubURL() ||
00216 KProtocolInfo::determineMimetypeFromExtension( _url.protocol() ) )
00217 {
00218 if ( _is_local_file && !_fast_mode ) {
00219 if ( mime->patternsAccuracy()<100 )
00220 {
00221 KMimeMagicResult* result =
00222 KMimeMagic::self()->findFileType( path );
00223
00224 if ( result && result->isValid() && result->accuracy() > 0 )
00225 return mimeType( result->mimeType() );
00226 }
00227 }
00228
00229 return mime;
00230 }
00231 }
00232
00233 static const QString& dotdesktop = KGlobal::staticQString(".desktop");
00234 static const QString& dotkdelnk = KGlobal::staticQString(".kdelnk");
00235 static const QString& dotdirectory = KGlobal::staticQString(".directory");
00236
00237
00238 if ( fileName.endsWith( dotdesktop ) )
00239 return mimeType( "application/x-desktop" );
00240
00241
00242 if ( fileName.endsWith( dotkdelnk ) )
00243 return mimeType( "application/x-desktop" );
00244
00245
00246 if ( fileName == dotdirectory )
00247 return mimeType( "text/plain" );
00248 }
00249
00250 if ( !_is_local_file || _fast_mode )
00251 {
00252 QString def = KProtocolInfo::defaultMimetype( _url );
00253 if ( !def.isEmpty() && def != defaultMimeType() )
00254 {
00255
00256 return mimeType( def );
00257 }
00258 if ( path.endsWith( slash ) || path.isEmpty() )
00259 {
00260
00261
00262
00263
00264 if ( def.isEmpty() )
00265 {
00266
00267 if ( KProtocolInfo::supportsListing( _url ) )
00268 return mimeType( QString::fromLatin1("inode/directory") );
00269 else
00270 return defaultMimeTypePtr();
00271 }
00272 }
00273
00274
00275 return defaultMimeTypePtr();
00276 }
00277
00278
00279
00280 KMimeMagicResult* result = KMimeMagic::self()->findFileType( path );
00281
00282
00283 if ( !result || !result->isValid() )
00284 return defaultMimeTypePtr();
00285
00286
00287 return mimeType( result->mimeType() );
00288 }
00289
00290 KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode,
00291 bool _is_local_file, bool _fast_mode,
00292 bool *accurate)
00293 {
00294 KMimeType::Ptr mime = findByURL(_url, _mode, _is_local_file, _fast_mode);
00295 if (accurate) *accurate = !(_fast_mode) || ((mime->patternsAccuracy() == 100) && mime != defaultMimeTypePtr());
00296 return mime;
00297 }
00298
00299 KMimeType::Ptr KMimeType::diagnoseFileName(const QString &fileName, QString &pattern)
00300 {
00301 return KServiceTypeFactory::self()->findFromPattern( fileName, &pattern );
00302 }
00303
00304 KMimeType::Ptr KMimeType::findByPath( const QString& path, mode_t mode, bool fast_mode )
00305 {
00306 KURL u;
00307 u.setPath(path);
00308 return findByURL( u, mode, true, fast_mode );
00309 }
00310
00311 KMimeType::Ptr KMimeType::findByContent( const QByteArray &data, int *accuracy )
00312 {
00313 KMimeMagicResult *result = KMimeMagic::self()->findBufferType(data);
00314 if (accuracy)
00315 *accuracy = result->accuracy();
00316 return mimeType( result->mimeType() );
00317 }
00318
00319 KMimeType::Ptr KMimeType::findByFileContent( const QString &fileName, int *accuracy )
00320 {
00321 KMimeMagicResult *result = KMimeMagic::self()->findFileType(fileName);
00322 if (accuracy)
00323 *accuracy = result->accuracy();
00324 return mimeType( result->mimeType() );
00325 }
00326
00327 #define GZIP_MAGIC1 0x1f
00328 #define GZIP_MAGIC2 0x8b
00329
00330 KMimeType::Format KMimeType::findFormatByFileContent( const QString &fileName )
00331 {
00332 KMimeType::Format result;
00333 result.compression = Format::NoCompression;
00334 KMimeType::Ptr mime = findByPath(fileName);
00335
00336 result.text = mime->name().startsWith("text/");
00337 QVariant v = mime->property("X-KDE-text");
00338 if (v.isValid())
00339 result.text = v.toBool();
00340
00341 if (mime->name().startsWith("inode/"))
00342 return result;
00343
00344 QFile f(fileName);
00345 if (f.open(IO_ReadOnly))
00346 {
00347 unsigned char buf[10+1];
00348 int l = f.readBlock((char *)buf, 10);
00349 if ((l > 2) && (buf[0] == GZIP_MAGIC1) && (buf[1] == GZIP_MAGIC2))
00350 result.compression = Format::GZipCompression;
00351 }
00352 return result;
00353 }
00354
00355 KMimeType::KMimeType( const QString & _fullpath, const QString& _type, const QString& _icon,
00356 const QString& _comment, const QStringList& _patterns )
00357 : KServiceType( _fullpath, _type, _icon, _comment )
00358 {
00359 m_lstPatterns = _patterns;
00360 }
00361
00362 KMimeType::KMimeType( const QString & _fullpath ) : KServiceType( _fullpath )
00363 {
00364 KDesktopFile _cfg( _fullpath, true );
00365 init ( &_cfg );
00366
00367 if ( !isValid() )
00368 kdWarning(7009) << "mimetype not valid '" << m_strName << "' (missing entry in the file ?)" << endl;
00369 }
00370
00371 KMimeType::KMimeType( KDesktopFile *config ) : KServiceType( config )
00372 {
00373 init( config );
00374
00375 if ( !isValid() )
00376 kdWarning(7009) << "mimetype not valid '" << m_strName << "' (missing entry in the file ?)" << endl;
00377 }
00378
00379 void KMimeType::init( KDesktopFile * config )
00380 {
00381 config->setDesktopGroup();
00382 m_lstPatterns = config->readListEntry( "Patterns", ';' );
00383
00384
00385 QString XKDEAutoEmbed = QString::fromLatin1("X-KDE-AutoEmbed");
00386 if ( config->hasKey( XKDEAutoEmbed ) )
00387 m_mapProps.insert( XKDEAutoEmbed, QVariant( config->readBoolEntry( XKDEAutoEmbed ), 0 ) );
00388
00389 QString XKDEText = QString::fromLatin1("X-KDE-text");
00390 if ( config->hasKey( XKDEText ) )
00391 m_mapProps.insert( XKDEText, config->readBoolEntry( XKDEText ) );
00392
00393 QString XKDEIsAlso = QString::fromLatin1("X-KDE-IsAlso");
00394 if ( config->hasKey( XKDEIsAlso ) ) {
00395 QString inherits = config->readEntry( XKDEIsAlso );
00396 if ( inherits != name() )
00397 m_mapProps.insert( XKDEIsAlso, inherits );
00398 else
00399 kdWarning(7009) << "Error: " << inherits << " inherits from itself!!!!" << endl;
00400 }
00401
00402 QString XKDEPatternsAccuracy = QString::fromLatin1("X-KDE-PatternsAccuracy");
00403 if ( config->hasKey( XKDEPatternsAccuracy ) )
00404 m_mapProps.insert( XKDEPatternsAccuracy, config->readEntry( XKDEPatternsAccuracy ) );
00405
00406 }
00407
00408 KMimeType::KMimeType( QDataStream& _str, int offset ) : KServiceType( _str, offset )
00409 {
00410 loadInternal( _str );
00411 }
00412
00413 void KMimeType::load( QDataStream& _str )
00414 {
00415 KServiceType::load( _str );
00416 loadInternal( _str );
00417 }
00418
00419 void KMimeType::loadInternal( QDataStream& _str )
00420 {
00421
00422 _str >> m_lstPatterns;
00423 }
00424
00425 void KMimeType::save( QDataStream& _str )
00426 {
00427 KServiceType::save( _str );
00428
00429
00430 _str << m_lstPatterns;
00431 }
00432
00433 QVariant KMimeType::property( const QString& _name ) const
00434 {
00435 if ( _name == "Patterns" )
00436 return QVariant( m_lstPatterns );
00437
00438 return KServiceType::property( _name );
00439 }
00440
00441 QStringList KMimeType::propertyNames() const
00442 {
00443 QStringList res = KServiceType::propertyNames();
00444 res.append( "Patterns" );
00445
00446 return res;
00447 }
00448
00449 KMimeType::~KMimeType()
00450 {
00451 }
00452
00453 QPixmap KMimeType::pixmap( KIcon::Group _group, int _force_size, int _state,
00454 QString * _path ) const
00455 {
00456 KIconLoader *iconLoader=KGlobal::iconLoader();
00457 QString iconName=icon( QString::null, false );
00458 if (!iconLoader->extraDesktopThemesAdded())
00459 {
00460 QPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true );
00461 if (!pixmap.isNull() ) return pixmap;
00462
00463 iconLoader->addExtraDesktopThemes();
00464 }
00465
00466 return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false );
00467 }
00468
00469 QPixmap KMimeType::pixmap( const KURL& _url, KIcon::Group _group, int _force_size,
00470 int _state, QString * _path ) const
00471 {
00472 KIconLoader *iconLoader=KGlobal::iconLoader();
00473 QString iconName=icon( _url, _url.isLocalFile() );
00474 if (!iconLoader->extraDesktopThemesAdded())
00475 {
00476 QPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true );
00477 if (!pixmap.isNull() ) return pixmap;
00478
00479 iconLoader->addExtraDesktopThemes();
00480 }
00481
00482 return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false );
00483 }
00484
00485 QPixmap KMimeType::pixmapForURL( const KURL & _url, mode_t _mode, KIcon::Group _group,
00486 int _force_size, int _state, QString * _path )
00487 {
00488 KIconLoader *iconLoader=KGlobal::iconLoader();
00489 QString iconName = iconForURL( _url, _mode );
00490
00491 if (!iconLoader->extraDesktopThemesAdded())
00492 {
00493 QPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true );
00494 if (!pixmap.isNull() ) return pixmap;
00495
00496 iconLoader->addExtraDesktopThemes();
00497 }
00498
00499 return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false );
00500
00501 }
00502
00503 QString KMimeType::iconForURL( const KURL & _url, mode_t _mode )
00504 {
00505 const KMimeType::Ptr mt = findByURL( _url, _mode, _url.isLocalFile(),
00506 false );
00507 static const QString& unknown = KGlobal::staticQString("unknown");
00508 const QString mimeTypeIcon = mt->icon( _url, _url.isLocalFile() );
00509 QString i = mimeTypeIcon;
00510
00511
00512 if ( i == unknown || i.isEmpty() || mt == defaultMimeTypePtr()
00513
00514 || _url.path().length() <= 1 )
00515 {
00516 i = favIconForURL( _url );
00517
00518 if ( i.isEmpty() )
00519 i = KProtocolInfo::icon( _url.protocol() );
00520
00521
00522 if ( _url.path().length() <= 1 && ( i == unknown || i.isEmpty() ) )
00523 i = mimeTypeIcon;
00524 }
00525 return i;
00526 }
00527
00528 QString KMimeType::favIconForURL( const KURL& url )
00529 {
00530
00531
00532 static bool useFavIcons = true;
00533 static bool check = true;
00534 if ( check ) {
00535 check = false;
00536 KConfig *config = KGlobal::config();
00537 KConfigGroupSaver cs( config, "HTML Settings" );
00538 useFavIcons = config->readBoolEntry( "EnableFavicon", true );
00539 }
00540
00541 if ( url.isLocalFile() || !url.protocol().startsWith("http")
00542 || !useFavIcons )
00543 return QString::null;
00544
00545 DCOPRef kded( "kded", "favicons" );
00546 DCOPReply result = kded.call( "iconForURL(KURL)", url );
00547 if ( result.isValid() )
00548 return result;
00549
00550 return QString::null;
00551 }
00552
00553 QString KMimeType::parentMimeType() const
00554 {
00555 QVariant v = property("X-KDE-IsAlso");
00556 return v.toString();
00557 }
00558
00559 bool KMimeType::is( const QString& mimeTypeName ) const
00560 {
00561 if ( name() == mimeTypeName )
00562 return true;
00563 QString st = parentMimeType();
00564
00565 while ( !st.isEmpty() )
00566 {
00567
00568 KMimeType::Ptr ptr = KMimeType::mimeType( st );
00569 if (!ptr) return false;
00570 if ( ptr->name() == mimeTypeName )
00571 return true;
00572 st = ptr->parentMimeType();
00573 }
00574 return false;
00575 }
00576
00577 int KMimeType::patternsAccuracy() const {
00578 QVariant v = property("X-KDE-PatternsAccuracy");
00579 if (!v.isValid()) return 100;
00580 else
00581 return v.toInt();
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591 QString KFolderType::icon( const QString& _url, bool _is_local ) const
00592 {
00593 if ( !_is_local || _url.isEmpty() )
00594 return KMimeType::icon( _url, _is_local );
00595
00596 return KFolderType::icon( KURL(_url), _is_local );
00597 }
00598
00599 QString KFolderType::icon( const KURL& _url, bool _is_local ) const
00600 {
00601 if ( !_is_local )
00602 return KMimeType::icon( _url, _is_local );
00603
00604 KURL u( _url );
00605 u.addPath( ".directory" );
00606
00607 QString icon;
00608
00609
00610 if ( KStandardDirs::exists( u.path() ) )
00611 {
00612 KSimpleConfig cfg( u.path(), true );
00613 cfg.setDesktopGroup();
00614 icon = cfg.readEntry( "Icon" );
00615 QString empty_icon = cfg.readEntry( "EmptyIcon" );
00616
00617 if ( !empty_icon.isEmpty() )
00618 {
00619 bool isempty = false;
00620 DIR *dp = 0L;
00621 struct dirent *ep;
00622 dp = opendir( QFile::encodeName(_url.path()) );
00623 if ( dp )
00624 {
00625 QValueList<QCString> entries;
00626
00627 ep=readdir( dp ); if ( ep ) entries.append( ep->d_name );
00628 ep=readdir( dp ); if ( ep ) entries.append( ep->d_name );
00629 if ( (ep=readdir( dp )) == 0L )
00630 isempty = true;
00631 else {
00632 entries.append( ep->d_name );
00633 if ( readdir( dp ) == 0 ) {
00634
00635 isempty = entries.find( "." ) != entries.end() &&
00636 entries.find( ".." ) != entries.end() &&
00637 entries.find( ".directory" ) != entries.end();
00638 }
00639 }
00640 if (!isempty && !strcmp(ep->d_name, ".directory"))
00641 isempty = (readdir(dp) == 0L);
00642 closedir( dp );
00643 }
00644
00645 if ( isempty )
00646 return empty_icon;
00647 }
00648 }
00649
00650 if ( icon.isEmpty() )
00651 return KMimeType::icon( _url, _is_local );
00652
00653 if ( icon.startsWith( "./" ) ) {
00654
00655
00656 KURL v( _url );
00657 v.addPath( icon.mid( 2 ) );
00658 icon = v.path();
00659 }
00660
00661 return icon;
00662 }
00663
00664 QString KFolderType::comment( const QString& _url, bool _is_local ) const
00665 {
00666 if ( !_is_local || _url.isEmpty() )
00667 return KMimeType::comment( _url, _is_local );
00668
00669 return KFolderType::comment( KURL(_url), _is_local );
00670 }
00671
00672 QString KFolderType::comment( const KURL& _url, bool _is_local ) const
00673 {
00674 if ( !_is_local )
00675 return KMimeType::comment( _url, _is_local );
00676
00677 KURL u( _url );
00678 u.addPath( ".directory" );
00679
00680 KDesktopFile cfg( u.path(), true );
00681 QString comment = cfg.readComment();
00682 if ( comment.isEmpty() )
00683 return KMimeType::comment( _url, _is_local );
00684
00685 return comment;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694 QString KDEDesktopMimeType::icon( const QString& _url, bool _is_local ) const
00695 {
00696 if ( !_is_local || _url.isEmpty() )
00697 return KMimeType::icon( _url, _is_local );
00698
00699 KURL u( _url );
00700 return icon( u, _is_local );
00701 }
00702
00703 QString KDEDesktopMimeType::icon( const KURL& _url, bool _is_local ) const
00704 {
00705 if ( !_is_local )
00706 return KMimeType::icon( _url, _is_local );
00707
00708 KSimpleConfig cfg( _url.path(), true );
00709 cfg.setDesktopGroup();
00710 QString icon = cfg.readEntry( "Icon" );
00711 QString type = cfg.readEntry( "Type" );
00712
00713 if ( type == "FSDevice" || type == "FSDev")
00714
00715 {
00716 QString unmount_icon = cfg.readEntry( "UnmountIcon" );
00717 QString dev = cfg.readEntry( "Dev" );
00718 if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() )
00719 {
00720 QString mp = KIO::findDeviceMountPoint( dev );
00721
00722 if ( mp.isNull() )
00723 return unmount_icon;
00724 }
00725 } else if ( type == "Link" ) {
00726 const QString emptyIcon = cfg.readEntry( "EmptyIcon" );
00727 if ( !emptyIcon.isEmpty() ) {
00728 const QString u = cfg.readPathEntry( "URL" );
00729 const KURL url( u );
00730 if ( url.protocol() == "trash" ) {
00731
00732
00733 KSimpleConfig trashConfig( "trashrc", true );
00734 trashConfig.setGroup( "Status" );
00735 if ( trashConfig.readBoolEntry( "Empty", true ) ) {
00736 return emptyIcon;
00737 }
00738 }
00739 }
00740 }
00741
00742 if ( icon.isEmpty() )
00743 return KMimeType::icon( _url, _is_local );
00744
00745 return icon;
00746 }
00747
00748 QPixmap KDEDesktopMimeType::pixmap( const KURL& _url, KIcon::Group _group, int _force_size,
00749 int _state, QString * _path ) const
00750 {
00751 QString _icon = icon( _url, _url.isLocalFile() );
00752 QPixmap pix = KGlobal::iconLoader()->loadIcon( _icon, _group,
00753 _force_size, _state, _path, false );
00754 if ( pix.isNull() )
00755 pix = KGlobal::iconLoader()->loadIcon( "unknown", _group,
00756 _force_size, _state, _path, false );
00757 return pix;
00758 }
00759
00760 QString KDEDesktopMimeType::comment( const QString& _url, bool _is_local ) const
00761 {
00762 if ( !_is_local || _url.isEmpty() )
00763 return KMimeType::comment( _url, _is_local );
00764
00765 KURL u( _url );
00766 return comment( u, _is_local );
00767 }
00768
00769 QString KDEDesktopMimeType::comment( const KURL& _url, bool _is_local ) const
00770 {
00771 if ( !_is_local )
00772 return KMimeType::comment( _url, _is_local );
00773
00774 KDesktopFile cfg( _url.path(), true );
00775 QString comment = cfg.readComment();
00776 if ( comment.isEmpty() )
00777 return KMimeType::comment( _url, _is_local );
00778
00779 return comment;
00780 }
00781
00782 pid_t KDEDesktopMimeType::run( const KURL& u, bool _is_local )
00783 {
00784
00785
00786 if ( !_is_local )
00787 return 0;
00788
00789 KSimpleConfig cfg( u.path(), true );
00790 cfg.setDesktopGroup();
00791 QString type = cfg.readEntry( "Type" );
00792 if ( type.isEmpty() )
00793 {
00794 QString tmp = i18n("The desktop entry file %1 "
00795 "has no Type=... entry.").arg(u.path() );
00796 KMessageBoxWrapper::error( 0, tmp);
00797 return 0;
00798 }
00799
00800
00801
00802 if ( type == "FSDevice" )
00803 return runFSDevice( u, cfg );
00804 else if ( type == "Application" )
00805 return runApplication( u, u.path() );
00806 else if ( type == "Link" )
00807 {
00808 cfg.setDollarExpansion( true );
00809 return runLink( u, cfg );
00810 }
00811 else if ( type == "MimeType" )
00812 return runMimeType( u, cfg );
00813
00814
00815 QString tmp = i18n("The desktop entry of type\n%1\nis unknown.").arg( type );
00816 KMessageBoxWrapper::error( 0, tmp);
00817
00818 return 0;
00819 }
00820
00821 pid_t KDEDesktopMimeType::runFSDevice( const KURL& _url, const KSimpleConfig &cfg )
00822 {
00823 pid_t retval = 0;
00824
00825 QString dev = cfg.readEntry( "Dev" );
00826
00827 if ( dev.isEmpty() )
00828 {
00829 QString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() );
00830 KMessageBoxWrapper::error( 0, tmp);
00831 return retval;
00832 }
00833
00834 QString mp = KIO::findDeviceMountPoint( dev );
00835
00836 if ( !mp.isNull() )
00837 {
00838 KURL mpURL;
00839 mpURL.setPath( mp );
00840
00841 retval = KRun::runURL( mpURL, QString::fromLatin1("inode/directory") );
00842 }
00843 else
00844 {
00845 bool ro = cfg.readBoolEntry( "ReadOnly", false );
00846 QString fstype = cfg.readEntry( "FSType" );
00847 if ( fstype == "Default" )
00848 fstype = QString::null;
00849 QString point = cfg.readEntry( "MountPoint" );
00850 #ifndef Q_WS_WIN
00851 (void) new KAutoMount( ro, fstype, dev, point, _url.path() );
00852 #endif
00853 retval = -1;
00854 }
00855
00856 return retval;
00857 }
00858
00859 pid_t KDEDesktopMimeType::runApplication( const KURL& , const QString & _serviceFile )
00860 {
00861 KService s( _serviceFile );
00862 if ( !s.isValid() )
00863
00864 return 0;
00865
00866 KURL::List lst;
00867 return KRun::run( s, lst );
00868 }
00869
00870 pid_t KDEDesktopMimeType::runLink( const KURL& _url, const KSimpleConfig &cfg )
00871 {
00872 QString u = cfg.readPathEntry( "URL" );
00873 if ( u.isEmpty() )
00874 {
00875 QString tmp = i18n("The desktop entry file\n%1\nis of type Link but has no URL=... entry.").arg( _url.prettyURL() );
00876 KMessageBoxWrapper::error( 0, tmp );
00877 return 0;
00878 }
00879
00880 KURL url ( u );
00881 KRun* run = new KRun(url);
00882
00883
00884
00885
00886 QString lastOpenedWidth = cfg.readEntry( "X-KDE-LastOpenedWith" );
00887 if ( !lastOpenedWidth.isEmpty() )
00888 run->setPreferredService( lastOpenedWidth );
00889
00890 return -1;
00891 }
00892
00893 pid_t KDEDesktopMimeType::runMimeType( const KURL& url , const KSimpleConfig & )
00894 {
00895
00896
00897
00898 QStringList args;
00899 args << "openProperties";
00900 args << url.path();
00901
00902 int pid;
00903 if ( !KApplication::kdeinitExec("kfmclient", args, 0, &pid) )
00904 return pid;
00905
00906 KProcess p;
00907 p << "kfmclient" << args;
00908 p.start(KProcess::DontCare);
00909 return p.pid();
00910 }
00911
00912 QValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::builtinServices( const KURL& _url )
00913 {
00914 QValueList<Service> result;
00915
00916 if ( !_url.isLocalFile() )
00917 return result;
00918
00919 KSimpleConfig cfg( _url.path(), true );
00920 cfg.setDesktopGroup();
00921 QString type = cfg.readEntry( "Type" );
00922
00923 if ( type.isEmpty() )
00924 return result;
00925
00926 if ( type == "FSDevice" )
00927 {
00928 QString dev = cfg.readEntry( "Dev" );
00929 if ( dev.isEmpty() )
00930 {
00931 QString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() );
00932 KMessageBoxWrapper::error( 0, tmp);
00933 }
00934 else
00935 {
00936 QString mp = KIO::findDeviceMountPoint( dev );
00937
00938 if ( mp.isEmpty() )
00939 {
00940 Service mount;
00941 mount.m_strName = i18n("Mount");
00942 mount.m_type = ST_MOUNT;
00943 result.append( mount );
00944 }
00945 else
00946 {
00947 Service unmount;
00948 #ifdef HAVE_VOLMGT
00949
00950
00951
00952 unmount.m_strName = i18n("Eject");
00953 #else
00954 unmount.m_strName = i18n("Unmount");
00955 #endif
00956 unmount.m_type = ST_UNMOUNT;
00957 result.append( unmount );
00958 }
00959 }
00960 }
00961
00962 return result;
00963 }
00964
00965 QValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const QString& path, bool bLocalFiles )
00966 {
00967 KSimpleConfig cfg( path, true );
00968 return userDefinedServices( path, cfg, bLocalFiles );
00969 }
00970
00971 QValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const QString& path, KConfig& cfg, bool bLocalFiles )
00972 {
00973 return userDefinedServices( path, cfg, bLocalFiles, KURL::List() );
00974 }
00975
00976 QValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const QString& path, KConfig& cfg, bool bLocalFiles, const KURL::List & file_list )
00977 {
00978 QValueList<Service> result;
00979
00980 cfg.setDesktopGroup();
00981
00982 if ( !cfg.hasKey( "Actions" ) && !cfg.hasKey( "X-KDE-GetActionMenu") )
00983 return result;
00984
00985 if ( cfg.hasKey( "TryExec" ) )
00986 {
00987 QString tryexec = cfg.readPathEntry( "TryExec" );
00988 QString exe = KStandardDirs::findExe( tryexec );
00989 if (exe.isEmpty()) {
00990 return result;
00991 }
00992 }
00993
00994 QStringList keys;
00995
00996 if( cfg.hasKey( "X-KDE-GetActionMenu" )) {
00997 QString dcopcall = cfg.readEntry( "X-KDE-GetActionMenu" );
00998 const QCString app = dcopcall.section(' ', 0,0).utf8();
00999
01000 QByteArray dataToSend;
01001 QDataStream dataStream(dataToSend, IO_WriteOnly);
01002 dataStream << file_list;
01003 QCString replyType;
01004 QByteArray replyData;
01005 QCString object = dcopcall.section(' ', 1,-2).utf8();
01006 QString function = dcopcall.section(' ', -1);
01007 if(!function.endsWith("(KURL::List)")) {
01008 kdWarning() << "Desktop file " << path << " contains an invalid X-KDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl;
01009 } else {
01010 if(kapp->dcopClient()->call( app, object,
01011 function.utf8(),
01012 dataToSend, replyType, replyData, true, -1)
01013 && replyType == "QStringList" ) {
01014
01015 QDataStream dataStreamIn(replyData, IO_ReadOnly);
01016 dataStreamIn >> keys;
01017 }
01018 }
01019 }
01020
01021 keys += cfg.readListEntry( "Actions", ';' );
01022
01023 if ( keys.count() == 0 )
01024 return result;
01025
01026 QStringList::ConstIterator it = keys.begin();
01027 QStringList::ConstIterator end = keys.end();
01028 for ( ; it != end; ++it )
01029 {
01030
01031
01032 QString group = *it;
01033
01034 if (group == "_SEPARATOR_")
01035 {
01036 Service s;
01037 result.append(s);
01038 continue;
01039 }
01040
01041 group.prepend( "Desktop Action " );
01042
01043 bool bInvalidMenu = false;
01044
01045 if ( cfg.hasGroup( group ) )
01046 {
01047 cfg.setGroup( group );
01048
01049 if ( !cfg.hasKey( "Name" ) || !cfg.hasKey( "Exec" ) )
01050 bInvalidMenu = true;
01051 else
01052 {
01053 QString exec = cfg.readPathEntry( "Exec" );
01054 if ( bLocalFiles || exec.contains("%U") || exec.contains("%u") )
01055 {
01056 Service s;
01057 s.m_strName = cfg.readEntry( "Name" );
01058 s.m_strIcon = cfg.readEntry( "Icon" );
01059 s.m_strExec = exec;
01060 s.m_type = ST_USER_DEFINED;
01061 s.m_display = !cfg.readBoolEntry( "NoDisplay" );
01062 result.append( s );
01063 }
01064 }
01065 }
01066 else
01067 bInvalidMenu = true;
01068
01069 if ( bInvalidMenu )
01070 {
01071 QString tmp = i18n("The desktop entry file\n%1\n has an invalid menu entry\n%2.").arg( path ).arg( *it );
01072 KMessageBoxWrapper::error( 0, tmp );
01073 }
01074 }
01075
01076 return result;
01077 }
01078
01079 void KDEDesktopMimeType::executeService( const QString& _url, KDEDesktopMimeType::Service& _service )
01080 {
01081 KURL u;
01082 u.setPath(_url);
01083 KURL::List lst;
01084 lst.append( u );
01085 executeService( lst, _service );
01086 }
01087
01088 void KDEDesktopMimeType::executeService( const KURL::List& urls, KDEDesktopMimeType::Service& _service )
01089 {
01090
01091
01092 if ( _service.m_type == ST_USER_DEFINED )
01093 {
01094 kdDebug() << "KDEDesktopMimeType::executeService " << _service.m_strName
01095 << " first url's path=" << urls.first().path() << " exec=" << _service.m_strExec << endl;
01096 KRun::run( _service.m_strExec, urls, _service.m_strName, _service.m_strIcon, _service.m_strIcon );
01097
01098 KDirNotify_stub allDirNotify("*", "KDirNotify*");
01099 allDirNotify.FilesChanged( urls );
01100 return;
01101 }
01102 else if ( _service.m_type == ST_MOUNT || _service.m_type == ST_UNMOUNT )
01103 {
01104 Q_ASSERT( urls.count() == 1 );
01105 QString path = urls.first().path();
01106
01107
01108 KSimpleConfig cfg( path, true );
01109 cfg.setDesktopGroup();
01110 QString dev = cfg.readEntry( "Dev" );
01111 if ( dev.isEmpty() )
01112 {
01113 QString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( path );
01114 KMessageBoxWrapper::error( 0, tmp );
01115 return;
01116 }
01117 QString mp = KIO::findDeviceMountPoint( dev );
01118
01119 if ( _service.m_type == ST_MOUNT )
01120 {
01121
01122 if ( !mp.isEmpty() )
01123 {
01124 kdDebug(7009) << "ALREADY Mounted" << endl;
01125 return;
01126 }
01127
01128 bool ro = cfg.readBoolEntry( "ReadOnly", false );
01129 QString fstype = cfg.readEntry( "FSType" );
01130 if ( fstype == "Default" )
01131 fstype = QString::null;
01132 QString point = cfg.readEntry( "MountPoint" );
01133 #ifndef Q_WS_WIN
01134 (void)new KAutoMount( ro, fstype, dev, point, path, false );
01135 #endif
01136 }
01137 else if ( _service.m_type == ST_UNMOUNT )
01138 {
01139
01140 if ( mp.isEmpty() )
01141 return;
01142
01143 #ifndef Q_WS_WIN
01144 (void)new KAutoUnmount( mp, path );
01145 #endif
01146 }
01147 }
01148 else
01149 assert( 0 );
01150 }
01151
01152 const QString & KMimeType::defaultMimeType()
01153 {
01154 static const QString & s_strDefaultMimeType =
01155 KGlobal::staticQString( "application/octet-stream" );
01156 return s_strDefaultMimeType;
01157 }
01158
01159 void KMimeType::virtual_hook( int id, void* data )
01160 { KServiceType::virtual_hook( id, data ); }
01161
01162 void KFolderType::virtual_hook( int id, void* data )
01163 { KMimeType::virtual_hook( id, data ); }
01164
01165 void KDEDesktopMimeType::virtual_hook( int id, void* data )
01166 { KMimeType::virtual_hook( id, data ); }
01167
01168 void KExecMimeType::virtual_hook( int id, void* data )
01169 { KMimeType::virtual_hook( id, data ); }
01170
01171 #include "kmimetyperesolver.moc"
01172