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