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