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