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 ( path.endsWith( slash ) || path.isEmpty() )
00253 {
00254
00255
00256
00257
00258 return mimeType( def.isEmpty() ? QString::fromLatin1("inode/directory") : def );
00259 }
00260 if ( !def.isEmpty() && def != defaultMimeType() )
00261 {
00262
00263 return mimeType( def );
00264 }
00265
00266
00267 return defaultMimeTypePtr();
00268 }
00269
00270
00271
00272 KMimeMagicResult* result = KMimeMagic::self()->findFileType( path );
00273
00274
00275 if ( !result || !result->isValid() )
00276 return defaultMimeTypePtr();
00277
00278
00279 return mimeType( result->mimeType() );
00280 }
00281
00282 KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode,
00283 bool _is_local_file, bool _fast_mode,
00284 bool *accurate)
00285 {
00286 KMimeType::Ptr mime = findByURL(_url, _mode, _is_local_file, _fast_mode);
00287 if (accurate) *accurate = !(_fast_mode) || ((mime->patternsAccuracy() == 100) && mime != defaultMimeTypePtr());
00288 return mime;
00289 }
00290
00291 KMimeType::Ptr KMimeType::diagnoseFileName(const QString &fileName, QString &pattern)
00292 {
00293 return KServiceTypeFactory::self()->findFromPattern( fileName, &pattern );
00294 }
00295
00296 KMimeType::Ptr KMimeType::findByPath( const QString& path, mode_t mode, bool fast_mode )
00297 {
00298 KURL u;
00299 u.setPath(path);
00300 return findByURL( u, mode, true, fast_mode );
00301 }
00302
00303 KMimeType::Ptr KMimeType::findByContent( const QByteArray &data, int *accuracy )
00304 {
00305 KMimeMagicResult *result = KMimeMagic::self()->findBufferType(data);
00306 QString type = (result && result->isValid())?
00307 result->mimeType() : defaultMimeType();
00308 if (accuracy)
00309 *accuracy = result->accuracy();
00310 return mimeType( result->mimeType() );
00311 }
00312
00313 KMimeType::Ptr KMimeType::findByFileContent( const QString &fileName, int *accuracy )
00314 {
00315 KMimeMagicResult *result = KMimeMagic::self()->findFileType(fileName);
00316 QString type = (result && result->isValid())?
00317 result->mimeType() : defaultMimeType();
00318 if (accuracy)
00319 *accuracy = result->accuracy();
00320 return mimeType( result->mimeType() );
00321 }
00322
00323 #define GZIP_MAGIC1 0x1f
00324 #define GZIP_MAGIC2 0x8b
00325
00326 KMimeType::Format KMimeType::findFormatByFileContent( const QString &fileName )
00327 {
00328 KMimeType::Format result;
00329 result.compression = Format::NoCompression;
00330 KMimeType::Ptr mime = findByPath(fileName);
00331 if (mime->name() == "application/octet-stream")
00332 mime = findByFileContent(fileName);
00333
00334 result.text = mime->name().startsWith("text/");
00335 QVariant v = mime->property("X-KDE-text");
00336 if (v.isValid())
00337 result.text = v.toBool();
00338
00339 if (mime->name().startsWith("inode/"))
00340 return result;
00341
00342 QFile f(fileName);
00343 if (f.open(IO_ReadOnly))
00344 {
00345 unsigned char buf[10+1];
00346 int l = f.readBlock((char *)buf, 10);
00347 if ((l > 2) && (buf[0] == GZIP_MAGIC1) && (buf[1] == GZIP_MAGIC2))
00348 result.compression = Format::GZipCompression;
00349 }
00350 return result;
00351 }
00352
00353 KMimeType::KMimeType( const QString & _fullpath, const QString& _type, const QString& _icon,
00354 const QString& _comment, const QStringList& _patterns )
00355 : KServiceType( _fullpath, _type, _icon, _comment )
00356 {
00357 m_lstPatterns = _patterns;
00358 }
00359
00360 KMimeType::KMimeType( const QString & _fullpath ) : KServiceType( _fullpath )
00361 {
00362 KDesktopFile _cfg( _fullpath, true );
00363 init ( &_cfg );
00364
00365 if ( !isValid() )
00366 kdWarning(7009) << "mimetype not valid '" << m_strName << "' (missing entry in the file ?)" << endl;
00367 }
00368
00369 KMimeType::KMimeType( KDesktopFile *config ) : KServiceType( config )
00370 {
00371 init( config );
00372
00373 if ( !isValid() )
00374 kdWarning(7009) << "mimetype not valid '" << m_strName << "' (missing entry in the file ?)" << endl;
00375 }
00376
00377 void KMimeType::init( KDesktopFile * config )
00378 {
00379 config->setDesktopGroup();
00380 m_lstPatterns = config->readListEntry( "Patterns", ';' );
00381
00382
00383 QString XKDEAutoEmbed = QString::fromLatin1("X-KDE-AutoEmbed");
00384 if ( config->hasKey( XKDEAutoEmbed ) )
00385 m_mapProps.insert( XKDEAutoEmbed, QVariant( config->readBoolEntry( XKDEAutoEmbed ), 0 ) );
00386
00387 QString XKDEText = QString::fromLatin1("X-KDE-text");
00388 if ( config->hasKey( XKDEText ) )
00389 m_mapProps.insert( XKDEText, config->readBoolEntry( XKDEText ) );
00390
00391 QString XKDEIsAlso = QString::fromLatin1("X-KDE-IsAlso");
00392 if ( config->hasKey( XKDEIsAlso ) )
00393 m_mapProps.insert( XKDEIsAlso, config->readEntry( XKDEIsAlso ) );
00394
00395 QString XKDEPatternsAccuracy = QString::fromLatin1("X-KDE-PatternsAccuracy");
00396 if ( config->hasKey( XKDEPatternsAccuracy ) )
00397 m_mapProps.insert( XKDEPatternsAccuracy, config->readEntry( XKDEPatternsAccuracy ) );
00398
00399 }
00400
00401 KMimeType::KMimeType( QDataStream& _str, int offset ) : KServiceType( _str, offset )
00402 {
00403 loadInternal( _str );
00404 }
00405
00406 void KMimeType::load( QDataStream& _str )
00407 {
00408 KServiceType::load( _str );
00409 loadInternal( _str );
00410 }
00411
00412 void KMimeType::loadInternal( QDataStream& _str )
00413 {
00414
00415 _str >> m_lstPatterns;
00416 }
00417
00418 void KMimeType::save( QDataStream& _str )
00419 {
00420 KServiceType::save( _str );
00421
00422
00423 _str << m_lstPatterns;
00424 }
00425
00426 QVariant KMimeType::property( const QString& _name ) const
00427 {
00428 if ( _name == "Patterns" )
00429 return QVariant( m_lstPatterns );
00430
00431 return KServiceType::property( _name );
00432 }
00433
00434 QStringList KMimeType::propertyNames() const
00435 {
00436 QStringList res = KServiceType::propertyNames();
00437 res.append( "Patterns" );
00438
00439 return res;
00440 }
00441
00442 KMimeType::~KMimeType()
00443 {
00444 }
00445
00446 QPixmap KMimeType::pixmap( KIcon::Group _group, int _force_size, int _state,
00447 QString * _path ) const
00448 {
00449 KIconLoader *iconLoader=KGlobal::iconLoader();
00450 QString iconName=icon( QString::null, false );
00451 if (!iconLoader->extraDesktopThemesAdded())
00452 {
00453 QPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true );
00454 if (!pixmap.isNull() ) return pixmap;
00455
00456 iconLoader->addExtraDesktopThemes();
00457 }
00458
00459 return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false );
00460 }
00461
00462 QPixmap KMimeType::pixmap( const KURL& _url, KIcon::Group _group, int _force_size,
00463 int _state, QString * _path ) const
00464 {
00465 KIconLoader *iconLoader=KGlobal::iconLoader();
00466 QString iconName=icon( _url, _url.isLocalFile() );
00467 if (!iconLoader->extraDesktopThemesAdded())
00468 {
00469 QPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true );
00470 if (!pixmap.isNull() ) return pixmap;
00471
00472 iconLoader->addExtraDesktopThemes();
00473 }
00474
00475 return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false );
00476 }
00477
00478 QPixmap KMimeType::pixmapForURL( const KURL & _url, mode_t _mode, KIcon::Group _group,
00479 int _force_size, int _state, QString * _path )
00480 {
00481 KIconLoader *iconLoader=KGlobal::iconLoader();
00482 QString iconName = iconForURL( _url, _mode );
00483
00484 if (!iconLoader->extraDesktopThemesAdded())
00485 {
00486 QPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true );
00487 if (!pixmap.isNull() ) return pixmap;
00488
00489 iconLoader->addExtraDesktopThemes();
00490 }
00491
00492 return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false );
00493
00494 }
00495
00496 QString KMimeType::iconForURL( const KURL & _url, mode_t _mode )
00497 {
00498 KMimeType::Ptr mt = findByURL( _url, _mode, _url.isLocalFile(),
00499 false );
00500 static const QString& unknown = KGlobal::staticQString("unknown");
00501 QString i( mt->icon( _url, _url.isLocalFile() ));
00502
00503
00504 if ( i == unknown || i.isEmpty() || mt == defaultMimeTypePtr()) {
00505 i = favIconForURL( _url );
00506
00507 if ( i.isEmpty() )
00508 i = KProtocolInfo::icon( _url.protocol() );
00509 }
00510 return i;
00511 }
00512
00513 QString KMimeType::favIconForURL( const KURL& url )
00514 {
00515
00516
00517 static bool useFavIcons = true;
00518 static bool check = true;
00519 if ( check ) {
00520 check = false;
00521 KConfig *config = KGlobal::config();
00522 KConfigGroupSaver cs( config, "HTML Settings" );
00523 useFavIcons = config->readBoolEntry( "EnableFavicon", true );
00524 }
00525
00526 if ( url.isLocalFile() || !url.protocol().startsWith("http")
00527 || !useFavIcons )
00528 return QString::null;
00529
00530 DCOPRef kded( "kded", "favicons" );
00531 DCOPReply result = kded.call( "iconForURL(KURL)", url );
00532 if ( result.isValid() )
00533 return result;
00534
00535 return QString::null;
00536 }
00537
00538 QString KMimeType::parentMimeType() const
00539 {
00540 QVariant v = property("X-KDE-IsAlso");
00541 return v.toString();
00542 }
00543
00544 bool KMimeType::is( const QString& mimeTypeName ) const
00545 {
00546 if ( name() == mimeTypeName )
00547 return true;
00548 QString st = parentMimeType();
00549 while ( !st.isEmpty() )
00550 {
00551 KMimeType::Ptr ptr = KMimeType::mimeType( st );
00552 if (!ptr) return false;
00553 if ( ptr->name() == mimeTypeName )
00554 return true;
00555 st = ptr->parentMimeType();
00556 }
00557 return false;
00558 }
00559
00560 int KMimeType::patternsAccuracy() const {
00561 QVariant v = property("X-KDE-PatternsAccuracy");
00562 if (!v.isValid()) return 100;
00563 else
00564 return v.toInt();
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574 QString KFolderType::icon( const QString& _url, bool _is_local ) const
00575 {
00576 if ( !_is_local || _url.isEmpty() )
00577 return KMimeType::icon( _url, _is_local );
00578
00579 return KFolderType::icon( KURL(_url), _is_local );
00580 }
00581
00582 QString KFolderType::icon( const KURL& _url, bool _is_local ) const
00583 {
00584 if ( !_is_local )
00585 return KMimeType::icon( _url, _is_local );
00586
00587 KURL u( _url );
00588 if( u.path() == KIO::findPathMountPoint( u.path())) {
00589
00590 if( KIO::probably_slow_mounted( u.path()))
00591 return KMimeType::icon( _url, _is_local );
00592 }
00593 u.addPath( ".directory" );
00594
00595 QString icon;
00596
00597
00598 if ( KStandardDirs::exists( u.path() ) )
00599 {
00600 KSimpleConfig cfg( u.path(), true );
00601 cfg.setDesktopGroup();
00602 icon = cfg.readEntry( "Icon" );
00603 QString empty_icon = cfg.readEntry( "EmptyIcon" );
00604
00605 if ( !empty_icon.isEmpty() )
00606 {
00607 bool isempty = false;
00608 DIR *dp = 0L;
00609 struct dirent *ep;
00610 dp = opendir( QFile::encodeName(_url.path()) );
00611 if ( dp )
00612 {
00613 ep=readdir( dp );
00614 ep=readdir( dp );
00615 if ( (ep=readdir( dp )) == 0L )
00616 isempty = true;
00617
00618 if (!isempty && !strcmp(ep->d_name, ".directory"))
00619 isempty = (readdir(dp) == 0L);
00620 closedir( dp );
00621 }
00622
00623 if ( isempty )
00624 return empty_icon;
00625 }
00626 }
00627
00628 if ( icon.isEmpty() )
00629 return KMimeType::icon( _url, _is_local );
00630
00631 return icon;
00632 }
00633
00634 QString KFolderType::comment( const QString& _url, bool _is_local ) const
00635 {
00636 if ( !_is_local || _url.isEmpty() )
00637 return KMimeType::comment( _url, _is_local );
00638
00639 return KFolderType::comment( KURL(_url), _is_local );
00640 }
00641
00642 QString KFolderType::comment( const KURL& _url, bool _is_local ) const
00643 {
00644 if ( !_is_local )
00645 return KMimeType::comment( _url, _is_local );
00646
00647 KURL u( _url );
00648 u.addPath( ".directory" );
00649
00650 KSimpleConfig cfg( u.path(), true );
00651 cfg.setDesktopGroup();
00652 QString comment = cfg.readEntry( "Comment" );
00653 if ( comment.isEmpty() )
00654 return KMimeType::comment( _url, _is_local );
00655
00656 return comment;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665 QString KDEDesktopMimeType::icon( const QString& _url, bool _is_local ) const
00666 {
00667 if ( !_is_local || _url.isEmpty() )
00668 return KMimeType::icon( _url, _is_local );
00669
00670 KURL u( _url );
00671 return icon( u, _is_local );
00672 }
00673
00674 QString KDEDesktopMimeType::icon( const KURL& _url, bool _is_local ) const
00675 {
00676 if ( !_is_local )
00677 return KMimeType::icon( _url, _is_local );
00678
00679 KSimpleConfig cfg( _url.path(), true );
00680 cfg.setDesktopGroup();
00681 QString icon = cfg.readEntry( "Icon" );
00682 QString type = cfg.readEntry( "Type" );
00683
00684 if ( type == "FSDevice" || type == "FSDev")
00685
00686 {
00687 QString unmount_icon = cfg.readEntry( "UnmountIcon" );
00688 QString dev = cfg.readEntry( "Dev" );
00689 if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() )
00690 {
00691 QString mp = KIO::findDeviceMountPoint( dev );
00692
00693 if ( mp.isNull() )
00694 return unmount_icon;
00695 }
00696 }
00697
00698 if ( icon.isEmpty() )
00699 return KMimeType::icon( _url, _is_local );
00700
00701 return icon;
00702 }
00703
00704 QPixmap KDEDesktopMimeType::pixmap( const KURL& _url, KIcon::Group _group, int _force_size,
00705 int _state, QString * _path ) const
00706 {
00707 QString _icon = icon( _url, _url.isLocalFile() );
00708 QPixmap pix = KGlobal::iconLoader()->loadIcon( _icon, _group,
00709 _force_size, _state, _path, false );
00710 if ( pix.isNull() )
00711 pix = KGlobal::iconLoader()->loadIcon( "unknown", _group,
00712 _force_size, _state, _path, false );
00713 return pix;
00714 }
00715
00716 QString KDEDesktopMimeType::comment( const QString& _url, bool _is_local ) const
00717 {
00718 if ( !_is_local || _url.isEmpty() )
00719 return KMimeType::comment( _url, _is_local );
00720
00721 KURL u( _url );
00722 return comment( u, _is_local );
00723 }
00724
00725 QString KDEDesktopMimeType::comment( const KURL& _url, bool _is_local ) const
00726 {
00727 if ( !_is_local )
00728 return KMimeType::comment( _url, _is_local );
00729
00730 KSimpleConfig cfg( _url.path(), true );
00731 cfg.setDesktopGroup();
00732 QString comment = cfg.readEntry( "Comment" );
00733 if ( comment.isEmpty() )
00734 return KMimeType::comment( _url, _is_local );
00735
00736 return comment;
00737 }
00738
00739 pid_t KDEDesktopMimeType::run( const KURL& u, bool _is_local )
00740 {
00741
00742
00743 if ( !_is_local )
00744 return 0;
00745
00746 KSimpleConfig cfg( u.path(), true );
00747 cfg.setDesktopGroup();
00748 QString type = cfg.readEntry( "Type" );
00749 if ( type.isEmpty() )
00750 {
00751 QString tmp = i18n("The desktop entry file %1 "
00752 "has no Type=... entry.").arg(u.path() );
00753 KMessageBoxWrapper::error( 0, tmp);
00754 return 0;
00755 }
00756
00757
00758
00759 if ( type == "FSDevice" )
00760 return runFSDevice( u, cfg );
00761 else if ( type == "Application" )
00762 return runApplication( u, u.path() );
00763 else if ( type == "Link" )
00764 {
00765 cfg.setDollarExpansion( true );
00766 return runLink( u, cfg );
00767 }
00768 else if ( type == "MimeType" )
00769 return runMimeType( u, cfg );
00770
00771
00772 QString tmp = i18n("The desktop entry of type\n%1\nis unknown.").arg( type );
00773 KMessageBoxWrapper::error( 0, tmp);
00774
00775 return 0;
00776 }
00777
00778 pid_t KDEDesktopMimeType::runFSDevice( const KURL& _url, const KSimpleConfig &cfg )
00779 {
00780 pid_t retval = 0;
00781
00782 QString dev = cfg.readEntry( "Dev" );
00783
00784 if ( dev.isEmpty() )
00785 {
00786 QString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() );
00787 KMessageBoxWrapper::error( 0, tmp);
00788 return retval;
00789 }
00790
00791 QString mp = KIO::findDeviceMountPoint( dev );
00792
00793 if ( !mp.isNull() )
00794 {
00795 KURL mpURL;
00796 mpURL.setPath( mp );
00797
00798 retval = KRun::runURL( mpURL, QString::fromLatin1("inode/directory") );
00799 }
00800 else
00801 {
00802 bool ro = cfg.readBoolEntry( "ReadOnly", false );
00803 QString fstype = cfg.readEntry( "FSType" );
00804 if ( fstype == "Default" )
00805 fstype = QString::null;
00806 QString point = cfg.readEntry( "MountPoint" );
00807 (void) new KAutoMount( ro, fstype, dev, point, _url.path() );
00808 retval = -1;
00809 }
00810
00811 return retval;
00812 }
00813
00814 pid_t KDEDesktopMimeType::runApplication( const KURL& , const QString & _serviceFile )
00815 {
00816 KService s( _serviceFile );
00817 if ( !s.isValid() )
00818
00819 return 0;
00820
00821 KURL::List lst;
00822 return KRun::run( s, lst );
00823 }
00824
00825 pid_t KDEDesktopMimeType::runLink( const KURL& _url, const KSimpleConfig &cfg )
00826 {
00827 QString u = cfg.readPathEntry( "URL" );
00828 if ( u.isEmpty() )
00829 {
00830 QString tmp = i18n("The desktop entry file\n%1\nis of type Link but has no URL=... entry.").arg( _url.prettyURL() );
00831 KMessageBoxWrapper::error( 0, tmp );
00832 return 0;
00833 }
00834
00835 KURL url ( u );
00836 KRun* run = new KRun(url);
00837
00838
00839
00840
00841 QString lastOpenedWidth = cfg.readEntry( "X-KDE-LastOpenedWith" );
00842 if ( !lastOpenedWidth.isEmpty() )
00843 run->setPreferredService( lastOpenedWidth );
00844
00845 return -1;
00846 }
00847
00848 pid_t KDEDesktopMimeType::runMimeType( const KURL& url , const KSimpleConfig & )
00849 {
00850
00851
00852
00853 QStringList args;
00854 args << "openProperties";
00855 args << url.path();
00856
00857 int pid;
00858 if ( !KApplication::kdeinitExec("kfmclient", args, 0, &pid) )
00859 return pid;
00860
00861 KProcess p;
00862 p << "kfmclient" << args;
00863 p.start(KProcess::DontCare);
00864 return p.pid();
00865 }
00866
00867 QValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::builtinServices( const KURL& _url )
00868 {
00869 QValueList<Service> result;
00870
00871 if ( !_url.isLocalFile() )
00872 return result;
00873
00874 KSimpleConfig cfg( _url.path(), true );
00875 cfg.setDesktopGroup();
00876 QString type = cfg.readEntry( "Type" );
00877
00878 if ( type.isEmpty() )
00879 return result;
00880
00881 if ( type == "FSDevice" )
00882 {
00883 QString dev = cfg.readEntry( "Dev" );
00884 if ( dev.isEmpty() )
00885 {
00886 QString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() );
00887 KMessageBoxWrapper::error( 0, tmp);
00888 }
00889 else
00890 {
00891 QString mp = KIO::findDeviceMountPoint( dev );
00892
00893 if ( mp.isEmpty() )
00894 {
00895 Service mount;
00896 mount.m_strName = i18n("Mount");
00897 mount.m_type = ST_MOUNT;
00898 result.append( mount );
00899 }
00900 else
00901 {
00902 Service unmount;
00903 #ifdef HAVE_VOLMGT
00904
00905
00906
00907 unmount.m_strName = i18n("Eject");
00908 #else
00909 unmount.m_strName = i18n("Unmount");
00910 #endif
00911 unmount.m_type = ST_UNMOUNT;
00912 result.append( unmount );
00913 }
00914 }
00915 }
00916
00917 return result;
00918 }
00919
00920 QValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const QString& path, bool bLocalFiles )
00921 {
00922 QValueList<Service> result;
00923
00924 KSimpleConfig cfg( path, true );
00925
00926 cfg.setDesktopGroup();
00927
00928 if ( !cfg.hasKey( "Actions" ) )
00929 return result;
00930
00931 if ( cfg.hasKey( "TryExec" ) )
00932 {
00933 QString tryexec = cfg.readPathEntry( "TryExec" );
00934 QString exe = KStandardDirs::findExe( tryexec );
00935 if (exe.isEmpty()) {
00936 return result;
00937 }
00938 }
00939
00940 QStringList keys = cfg.readListEntry( "Actions", ';' );
00941
00942 if ( keys.count() == 0 )
00943 return result;
00944
00945 QStringList::ConstIterator it = keys.begin();
00946 QStringList::ConstIterator end = keys.end();
00947 for ( ; it != end; ++it )
00948 {
00949
00950
00951 QString group = *it;
00952
00953 if (group == "_SEPARATOR_")
00954 {
00955 Service s;
00956 result.append(s);
00957 continue;
00958 }
00959
00960 group.prepend( "Desktop Action " );
00961
00962 bool bInvalidMenu = false;
00963
00964 if ( cfg.hasGroup( group ) )
00965 {
00966 cfg.setGroup( group );
00967
00968 if ( !cfg.hasKey( "Name" ) || !cfg.hasKey( "Exec" ) )
00969 bInvalidMenu = true;
00970 else
00971 {
00972 QString exec = cfg.readPathEntry( "Exec" );
00973 if ( bLocalFiles || exec.contains("%U") || exec.contains("%u") )
00974 {
00975 Service s;
00976 s.m_strName = cfg.readEntry( "Name" );
00977 s.m_strIcon = cfg.readEntry( "Icon" );
00978 s.m_strExec = exec;
00979 s.m_type = ST_USER_DEFINED;
00980 s.m_display = !cfg.readBoolEntry( "NoDisplay" );
00981 result.append( s );
00982 }
00983 }
00984 }
00985 else
00986 bInvalidMenu = true;
00987
00988 if ( bInvalidMenu )
00989 {
00990 QString tmp = i18n("The desktop entry file\n%1\n has an invalid menu entry\n%2.").arg( path ).arg( *it );
00991 KMessageBoxWrapper::error( 0, tmp );
00992 }
00993 }
00994
00995 return result;
00996 }
00997
00998 void KDEDesktopMimeType::executeService( const QString& _url, KDEDesktopMimeType::Service& _service )
00999 {
01000 KURL u;
01001 u.setPath(_url);
01002 KURL::List lst;
01003 lst.append( u );
01004 executeService( lst, _service );
01005 }
01006
01007 void KDEDesktopMimeType::executeService( const KURL::List& urls, KDEDesktopMimeType::Service& _service )
01008 {
01009
01010
01011 if ( _service.m_type == ST_USER_DEFINED )
01012 {
01013 kdDebug() << "KDEDesktopMimeType::executeService " << _service.m_strName
01014 << " first url's path=" << urls.first().path() << " exec=" << _service.m_strExec << endl;
01015 KRun::run( _service.m_strExec, urls, _service.m_strName, _service.m_strIcon, _service.m_strIcon );
01016
01017 KDirNotify_stub allDirNotify("*", "KDirNotify*");
01018 allDirNotify.FilesChanged( urls );
01019 return;
01020 }
01021 else if ( _service.m_type == ST_MOUNT || _service.m_type == ST_UNMOUNT )
01022 {
01023 Q_ASSERT( urls.count() == 1 );
01024 QString path = urls.first().path();
01025
01026
01027 KSimpleConfig cfg( path, true );
01028 cfg.setDesktopGroup();
01029 QString dev = cfg.readEntry( "Dev" );
01030 if ( dev.isEmpty() )
01031 {
01032 QString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( path );
01033 KMessageBoxWrapper::error( 0, tmp );
01034 return;
01035 }
01036 QString mp = KIO::findDeviceMountPoint( dev );
01037
01038 if ( _service.m_type == ST_MOUNT )
01039 {
01040
01041 if ( !mp.isEmpty() )
01042 {
01043 kdDebug(7009) << "ALREADY Mounted" << endl;
01044 return;
01045 }
01046
01047 bool ro = cfg.readBoolEntry( "ReadOnly", false );
01048 QString fstype = cfg.readEntry( "FSType" );
01049 if ( fstype == "Default" )
01050 fstype = QString::null;
01051 QString point = cfg.readEntry( "MountPoint" );
01052 (void)new KAutoMount( ro, fstype, dev, point, path, false );
01053 }
01054 else if ( _service.m_type == ST_UNMOUNT )
01055 {
01056
01057 if ( mp.isEmpty() )
01058 return;
01059
01060 (void)new KAutoUnmount( mp, path );
01061 }
01062 }
01063 else
01064 assert( 0 );
01065 }
01066
01067 const QString & KMimeType::defaultMimeType()
01068 {
01069 static const QString & s_strDefaultMimeType =
01070 KGlobal::staticQString( "application/octet-stream" );
01071 return s_strDefaultMimeType;
01072 }
01073
01074 void KMimeType::virtual_hook( int id, void* data )
01075 { KServiceType::virtual_hook( id, data ); }
01076
01077 void KFolderType::virtual_hook( int id, void* data )
01078 { KMimeType::virtual_hook( id, data ); }
01079
01080 void KDEDesktopMimeType::virtual_hook( int id, void* data )
01081 { KMimeType::virtual_hook( id, data ); }
01082
01083 void KExecMimeType::virtual_hook( int id, void* data )
01084 { KMimeType::virtual_hook( id, data ); }
01085
01086 #include "kmimetyperesolver.moc"
01087