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 <tdeio/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 <tqstring.h>
00044 #include <tqfile.h>
00045 #include <kmessageboxwrapper.h>
00046
00047 #include <dcopclient.h>
00048 #include <dcopref.h>
00049 #include <tdeapplication.h>
00050 #include <kprocess.h>
00051 #include <kdebug.h>
00052 #include <kdesktopfile.h>
00053 #include <kdirwatch.h>
00054 #include <kiconloader.h>
00055 #include <tdelocale.h>
00056 #include <ksimpleconfig.h>
00057 #include <kstandarddirs.h>
00058 #include <kurl.h>
00059 #include <tdesycoca.h>
00060 #include <kde_file.h>
00061
00062 template class TDESharedPtr<KMimeType>;
00063 template class TQValueList<KMimeType::Ptr>;
00064
00065 KMimeType::Ptr KMimeType::s_pDefaultType = 0L;
00066 bool KMimeType::s_bChecked = false;
00067
00068 void KMimeType::buildDefaultType()
00069 {
00070 assert ( !s_pDefaultType );
00071
00072 KServiceType * mime = KServiceTypeFactory::self()->
00073 findServiceTypeByName( defaultMimeType() );
00074
00075 if (mime && mime->isType( KST_KMimeType ))
00076 {
00077 s_pDefaultType = KMimeType::Ptr((KMimeType *) mime);
00078 }
00079 else
00080 {
00081 errorMissingMimeType( defaultMimeType() );
00082 TDEStandardDirs stdDirs;
00083 TQString sDefaultMimeType = stdDirs.resourceDirs("mime").first()+defaultMimeType()+".desktop";
00084 s_pDefaultType = new KMimeType( sDefaultMimeType, defaultMimeType(),
00085 "unknown", "mime", TQStringList() );
00086 }
00087 }
00088
00089 KMimeType::Ptr KMimeType::defaultMimeTypePtr()
00090 {
00091 if ( !s_pDefaultType )
00092 buildDefaultType();
00093 return s_pDefaultType;
00094 }
00095
00096
00097 void KMimeType::checkEssentialMimeTypes()
00098 {
00099 if ( s_bChecked )
00100 return;
00101 if ( !s_pDefaultType )
00102 buildDefaultType();
00103
00104 s_bChecked = true;
00105
00106
00107
00108 if ( !KServiceTypeFactory::self()->checkMimeTypes() )
00109 {
00110 KMessageBoxWrapper::error( 0L, i18n( "No mime types installed." ) );
00111 return;
00112 }
00113
00114 if ( KMimeType::mimeType( "inode/directory" ) == s_pDefaultType )
00115 errorMissingMimeType( "inode/directory" );
00116 if ( KMimeType::mimeType( "inode/directory-locked" ) == s_pDefaultType )
00117 errorMissingMimeType( "inode/directory-locked" );
00118 if ( KMimeType::mimeType( "inode/blockdevice" ) == s_pDefaultType )
00119 errorMissingMimeType( "inode/blockdevice" );
00120 if ( KMimeType::mimeType( "inode/chardevice" ) == s_pDefaultType )
00121 errorMissingMimeType( "inode/chardevice" );
00122 if ( KMimeType::mimeType( "inode/socket" ) == s_pDefaultType )
00123 errorMissingMimeType( "inode/socket" );
00124 if ( KMimeType::mimeType( "inode/fifo" ) == s_pDefaultType )
00125 errorMissingMimeType( "inode/fifo" );
00126 if ( KMimeType::mimeType( "application/x-shellscript" ) == s_pDefaultType )
00127 errorMissingMimeType( "application/x-shellscript" );
00128 if ( KMimeType::mimeType( "application/x-executable" ) == s_pDefaultType )
00129 errorMissingMimeType( "application/x-executable" );
00130 if ( KMimeType::mimeType( "application/x-desktop" ) == s_pDefaultType )
00131 errorMissingMimeType( "application/x-desktop" );
00132 }
00133
00134 void KMimeType::errorMissingMimeType( const TQString& _type )
00135 {
00136 TQString tmp = i18n( "Could not find mime type\n%1" ).arg( _type );
00137
00138 KMessageBoxWrapper::sorry( 0, tmp );
00139 }
00140
00141 KMimeType::Ptr KMimeType::mimeType( const TQString& _name )
00142 {
00143 KServiceType * mime = KServiceTypeFactory::self()->findServiceTypeByName( _name );
00144
00145 if ( !mime || !mime->isType( KST_KMimeType ) )
00146 {
00147
00148
00149 if ( !KSycoca::self()->isBuilding() )
00150 delete mime;
00151 if ( !s_pDefaultType )
00152 buildDefaultType();
00153 return s_pDefaultType;
00154 }
00155
00156
00157 return KMimeType::Ptr((KMimeType *) mime);
00158 }
00159
00160 KMimeType::List KMimeType::allMimeTypes()
00161 {
00162 return KServiceTypeFactory::self()->allMimeTypes();
00163 }
00164
00165 KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode,
00166 bool _is_local_file, bool _fast_mode )
00167 {
00168 checkEssentialMimeTypes();
00169 TQString path = _url.path();
00170
00171 if ( !_fast_mode && !_is_local_file && _url.isLocalFile() )
00172 _is_local_file = true;
00173
00174 if ( !_fast_mode && _is_local_file && (_mode == 0 || _mode == (mode_t)-1) )
00175 {
00176 KDE_struct_stat buff;
00177 if ( KDE_stat( TQFile::encodeName(path), &buff ) != -1 )
00178 _mode = buff.st_mode;
00179 }
00180
00181
00182 if ( S_ISDIR( _mode ) )
00183 {
00184
00185
00186 if ( _is_local_file )
00187 {
00188 if ( access( TQFile::encodeName(path), R_OK ) == -1 )
00189 return mimeType( "inode/directory-locked" );
00190 }
00191 return mimeType( "inode/directory" );
00192 }
00193 if ( S_ISCHR( _mode ) )
00194 return mimeType( "inode/chardevice" );
00195 if ( S_ISBLK( _mode ) )
00196 return mimeType( "inode/blockdevice" );
00197 if ( S_ISFIFO( _mode ) )
00198 return mimeType( "inode/fifo" );
00199 if ( S_ISSOCK( _mode ) )
00200 return mimeType( "inode/socket" );
00201
00202 if ( !_is_local_file && S_ISREG( _mode ) && ( _mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) )
00203 return mimeType( "application/x-executable" );
00204
00205 TQString fileName ( _url.fileName() );
00206
00207 static const TQString& slash = TDEGlobal::staticQString("/");
00208 if ( ! fileName.isNull() && !path.endsWith( slash ) )
00209 {
00210
00211 KMimeType::Ptr mime = KServiceTypeFactory::self()->findFromPattern( fileName );
00212 if ( mime )
00213 {
00214
00215 if ( _is_local_file || _url.hasSubURL() ||
00216 KProtocolInfo::determineMimetypeFromExtension( _url.protocol() ) )
00217 {
00218 if ( _is_local_file && !_fast_mode ) {
00219 if ( mime->patternsAccuracy()<100 )
00220 {
00221 KMimeMagicResult* result =
00222 KMimeMagic::self()->findFileType( path );
00223
00224 if ( result && result->isValid() && result->accuracy() > 0 ) {
00225 KMimeType::Ptr resultMime = mimeType( result->mimeType() );
00226 if (resultMime->patternsAccuracy() > 0) {
00227 return resultMime;
00228 }
00229 }
00230 }
00231 }
00232
00233 return mime;
00234 }
00235 }
00236
00237 static const TQString& dotdesktop = TDEGlobal::staticQString(".desktop");
00238 static const TQString& dotkdelnk = TDEGlobal::staticQString(".kdelnk");
00239 static const TQString& dotdirectory = TDEGlobal::staticQString(".directory");
00240
00241
00242 if ( fileName.endsWith( dotdesktop ) )
00243 return mimeType( "application/x-desktop" );
00244
00245
00246 if ( fileName.endsWith( dotkdelnk ) )
00247 return mimeType( "application/x-desktop" );
00248
00249
00250 if ( fileName == dotdirectory )
00251 return mimeType( "text/plain" );
00252 }
00253
00254 if ( !_is_local_file || _fast_mode )
00255 {
00256 TQString def = KProtocolInfo::defaultMimetype( _url );
00257 if ( !def.isEmpty() && def != defaultMimeType() )
00258 {
00259
00260 return mimeType( def );
00261 }
00262 if ( path.endsWith( slash ) || path.isEmpty() )
00263 {
00264
00265
00266
00267
00268 if ( def.isEmpty() )
00269 {
00270
00271 if ( KProtocolInfo::supportsListing( _url ) )
00272 return mimeType( TQString::fromLatin1("inode/directory") );
00273 else
00274 return defaultMimeTypePtr();
00275 }
00276 }
00277
00278
00279 return defaultMimeTypePtr();
00280 }
00281
00282
00283
00284 KMimeMagicResult* result = KMimeMagic::self()->findFileType( path );
00285
00286
00287 if ( !result || !result->isValid() )
00288 return defaultMimeTypePtr();
00289
00290
00291 return mimeType( result->mimeType() );
00292 }
00293
00294 KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode,
00295 bool _is_local_file, bool _fast_mode,
00296 bool *accurate)
00297 {
00298 KMimeType::Ptr mime = findByURL(_url, _mode, _is_local_file, _fast_mode);
00299 if (accurate) *accurate = !(_fast_mode) || ((mime->patternsAccuracy() == 100) && mime != defaultMimeTypePtr());
00300 return mime;
00301 }
00302
00303 KMimeType::Ptr KMimeType::diagnoseFileName(const TQString &fileName, TQString &pattern)
00304 {
00305 return KServiceTypeFactory::self()->findFromPattern( fileName, &pattern );
00306 }
00307
00308 KMimeType::Ptr KMimeType::findByPath( const TQString& path, mode_t mode, bool fast_mode )
00309 {
00310 KURL u;
00311 u.setPath(path);
00312 return findByURL( u, mode, true, fast_mode );
00313 }
00314
00315 KMimeType::Ptr KMimeType::findByContent( const TQByteArray &data, int *accuracy )
00316 {
00317 KMimeMagicResult *result = KMimeMagic::self()->findBufferType(data);
00318 if (accuracy)
00319 *accuracy = result->accuracy();
00320 return mimeType( result->mimeType() );
00321 }
00322
00323 KMimeType::Ptr KMimeType::findByFileContent( const TQString &fileName, int *accuracy )
00324 {
00325 KMimeMagicResult *result = KMimeMagic::self()->findFileType(fileName);
00326 if (accuracy)
00327 *accuracy = result->accuracy();
00328 return mimeType( result->mimeType() );
00329 }
00330
00331 #define GZIP_MAGIC1 0x1f
00332 #define GZIP_MAGIC2 0x8b
00333
00334 KMimeType::Format KMimeType::findFormatByFileContent( const TQString &fileName )
00335 {
00336 KMimeType::Format result;
00337 result.compression = Format::NoCompression;
00338 KMimeType::Ptr mime = findByPath(fileName);
00339
00340 result.text = mime->name().startsWith("text/");
00341 TQVariant v = mime->property("X-TDE-text");
00342 if (v.isValid())
00343 result.text = v.toBool();
00344
00345 if (mime->name().startsWith("inode/"))
00346 return result;
00347
00348 TQFile 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 TQString & _fullpath, const TQString& _type, const TQString& _icon,
00360 const TQString& _comment, const TQStringList& _patterns )
00361 : KServiceType( _fullpath, _type, _icon, _comment )
00362 {
00363 m_lstPatterns = _patterns;
00364 }
00365
00366 KMimeType::KMimeType( const TQString & _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 TQString XKDEAutoEmbed = TQString::fromLatin1("X-TDE-AutoEmbed");
00390 if ( config->hasKey( XKDEAutoEmbed ) )
00391 m_mapProps.insert( XKDEAutoEmbed, TQVariant( config->readBoolEntry( XKDEAutoEmbed ), 0 ) );
00392
00393 TQString XKDEText = TQString::fromLatin1("X-TDE-text");
00394 if ( config->hasKey( XKDEText ) )
00395 m_mapProps.insert( XKDEText, config->readBoolEntry( XKDEText ) );
00396
00397 TQString XKDEIsAlso = TQString::fromLatin1("X-TDE-IsAlso");
00398 if ( config->hasKey( XKDEIsAlso ) ) {
00399 TQString 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 TQString XKDEPatternsAccuracy = TQString::fromLatin1("X-TDE-PatternsAccuracy");
00407 if ( config->hasKey( XKDEPatternsAccuracy ) )
00408 m_mapProps.insert( XKDEPatternsAccuracy, config->readEntry( XKDEPatternsAccuracy ) );
00409
00410 }
00411
00412 KMimeType::KMimeType( TQDataStream& _str, int offset ) : KServiceType( _str, offset )
00413 {
00414 loadInternal( _str );
00415 }
00416
00417 void KMimeType::load( TQDataStream& _str )
00418 {
00419 KServiceType::load( _str );
00420 loadInternal( _str );
00421 }
00422
00423 void KMimeType::loadInternal( TQDataStream& _str )
00424 {
00425
00426 _str >> m_lstPatterns;
00427 }
00428
00429 void KMimeType::save( TQDataStream& _str )
00430 {
00431 KServiceType::save( _str );
00432
00433
00434 _str << m_lstPatterns;
00435 }
00436
00437 TQVariant KMimeType::property( const TQString& _name ) const
00438 {
00439 if ( _name == "Patterns" )
00440 return TQVariant( m_lstPatterns );
00441
00442 return KServiceType::property( _name );
00443 }
00444
00445 TQStringList KMimeType::propertyNames() const
00446 {
00447 TQStringList res = KServiceType::propertyNames();
00448 res.append( "Patterns" );
00449
00450 return res;
00451 }
00452
00453 KMimeType::~KMimeType()
00454 {
00455 }
00456
00457 TQPixmap KMimeType::pixmap( TDEIcon::Group _group, int _force_size, int _state,
00458 TQString * _path ) const
00459 {
00460 TDEIconLoader *iconLoader=TDEGlobal::iconLoader();
00461 TQString iconName=icon( TQString::null, false );
00462 if (!iconLoader->extraDesktopThemesAdded())
00463 {
00464 TQPixmap 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 TQPixmap KMimeType::pixmap( const KURL& _url, TDEIcon::Group _group, int _force_size,
00474 int _state, TQString * _path ) const
00475 {
00476 TDEIconLoader *iconLoader=TDEGlobal::iconLoader();
00477 TQString iconName=icon( _url, _url.isLocalFile() );
00478 if (!iconLoader->extraDesktopThemesAdded())
00479 {
00480 TQPixmap 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 TQPixmap KMimeType::pixmapForURL( const KURL & _url, mode_t _mode, TDEIcon::Group _group,
00490 int _force_size, int _state, TQString * _path )
00491 {
00492 TDEIconLoader *iconLoader=TDEGlobal::iconLoader();
00493 TQString iconName = iconForURL( _url, _mode );
00494
00495 if (!iconLoader->extraDesktopThemesAdded())
00496 {
00497 TQPixmap 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 TQString KMimeType::iconForURL( const KURL & _url, mode_t _mode )
00508 {
00509 const KMimeType::Ptr mt = findByURL( _url, _mode, _url.isLocalFile(),
00510 false );
00511 static const TQString& unknown = TDEGlobal::staticQString("unknown");
00512 const TQString mimeTypeIcon = mt->icon( _url, _url.isLocalFile() );
00513 TQString 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 TQString 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 TDEConfig *config = TDEGlobal::config();
00541 TDEConfigGroupSaver cs( config, "HTML Settings" );
00542 useFavIcons = config->readBoolEntry( "EnableFavicon", true );
00543 }
00544
00545 if ( url.isLocalFile() || !url.protocol().startsWith("http")
00546 || !useFavIcons )
00547 return TQString::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 TQString::null;
00555 }
00556
00557 TQString KMimeType::parentMimeType() const
00558 {
00559 TQVariant v = property("X-TDE-IsAlso");
00560 return v.toString();
00561 }
00562
00563 bool KMimeType::is( const TQString& mimeTypeName ) const
00564 {
00565 if ( name() == mimeTypeName )
00566 return true;
00567 TQString 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 TQVariant v = property("X-TDE-PatternsAccuracy");
00583 if (!v.isValid()) return 100;
00584 else
00585 return v.toInt();
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595 TQString KFolderType::icon( const TQString& _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 TQString 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 TQString icon;
00612
00613
00614 if ( TDEStandardDirs::exists( u.path() ) )
00615 {
00616 KSimpleConfig cfg( u.path(), true );
00617 cfg.setDesktopGroup();
00618 icon = cfg.readEntry( "Icon" );
00619 TQString 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( TQFile::encodeName(_url.path()) );
00627 if ( dp )
00628 {
00629 TQValueList<TQCString> 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 TQString KFolderType::comment( const TQString& _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 TQString 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 KDesktopFile cfg( u.path(), true );
00685 TQString comment = cfg.readComment();
00686 if ( comment.isEmpty() )
00687 return KMimeType::comment( _url, _is_local );
00688
00689 return comment;
00690 }
00691
00692
00693
00694
00695
00696
00697
00698 TQString KDEDesktopMimeType::icon( const TQString& _url, bool _is_local ) const
00699 {
00700 if ( !_is_local || _url.isEmpty() )
00701 return KMimeType::icon( _url, _is_local );
00702
00703 KURL u( _url );
00704 return icon( u, _is_local );
00705 }
00706
00707 TQString KDEDesktopMimeType::icon( const KURL& _url, bool _is_local ) const
00708 {
00709 if ( !_is_local )
00710 return KMimeType::icon( _url, _is_local );
00711
00712 KSimpleConfig cfg( _url.path(), true );
00713 cfg.setDesktopGroup();
00714 TQString icon = cfg.readEntry( "Icon" );
00715 TQString type = cfg.readEntry( "Type" );
00716
00717 if ( type == "FSDevice" || type == "FSDev")
00718
00719 {
00720 TQString unmount_icon = cfg.readEntry( "UnmountIcon" );
00721 TQString dev = cfg.readEntry( "Dev" );
00722 if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() )
00723 {
00724 TQString mp = TDEIO::findDeviceMountPoint( dev );
00725
00726 if ( mp.isNull() )
00727 return unmount_icon;
00728 }
00729 } else if ( type == "Link" ) {
00730 const TQString emptyIcon = cfg.readEntry( "EmptyIcon" );
00731 if ( !emptyIcon.isEmpty() ) {
00732 const TQString u = cfg.readPathEntry( "URL" );
00733 const KURL url( u );
00734 if ( url.protocol() == "trash" ) {
00735
00736
00737 KSimpleConfig trashConfig( "trashrc", true );
00738 trashConfig.setGroup( "Status" );
00739 if ( trashConfig.readBoolEntry( "Empty", true ) ) {
00740 return emptyIcon;
00741 }
00742 }
00743 }
00744 }
00745
00746 if ( icon.isEmpty() )
00747 return KMimeType::icon( _url, _is_local );
00748
00749 return icon;
00750 }
00751
00752 TQPixmap KDEDesktopMimeType::pixmap( const KURL& _url, TDEIcon::Group _group, int _force_size,
00753 int _state, TQString * _path ) const
00754 {
00755 TQString _icon = icon( _url, _url.isLocalFile() );
00756 TQPixmap pix = TDEGlobal::iconLoader()->loadIcon( _icon, _group,
00757 _force_size, _state, _path, false );
00758 if ( pix.isNull() )
00759 pix = TDEGlobal::iconLoader()->loadIcon( "unknown", _group,
00760 _force_size, _state, _path, false );
00761 return pix;
00762 }
00763
00764 TQString KDEDesktopMimeType::comment( const TQString& _url, bool _is_local ) const
00765 {
00766 if ( !_is_local || _url.isEmpty() )
00767 return KMimeType::comment( _url, _is_local );
00768
00769 KURL u( _url );
00770 return comment( u, _is_local );
00771 }
00772
00773 TQString KDEDesktopMimeType::comment( const KURL& _url, bool _is_local ) const
00774 {
00775 if ( !_is_local )
00776 return KMimeType::comment( _url, _is_local );
00777
00778 KDesktopFile cfg( _url.path(), true );
00779 TQString comment = cfg.readComment();
00780 if ( comment.isEmpty() )
00781 return KMimeType::comment( _url, _is_local );
00782
00783 return comment;
00784 }
00785
00786 pid_t KDEDesktopMimeType::run( const KURL& u, bool _is_local )
00787 {
00788
00789
00790 if ( !_is_local )
00791 return 0;
00792
00793 KSimpleConfig cfg( u.path(), true );
00794 cfg.setDesktopGroup();
00795 TQString type = cfg.readEntry( "Type" );
00796 if ( type.isEmpty() )
00797 {
00798 TQString tmp = i18n("The desktop entry file %1 "
00799 "has no Type=... entry.").arg(u.path() );
00800 KMessageBoxWrapper::error( 0, tmp);
00801 return 0;
00802 }
00803
00804
00805
00806 if ( type == "FSDevice" )
00807 return runFSDevice( u, cfg );
00808 else if ( type == "Application" )
00809 return runApplication( u, u.path() );
00810 else if ( type == "Link" )
00811 {
00812 cfg.setDollarExpansion( true );
00813 return runLink( u, cfg );
00814 }
00815 else if ( type == "MimeType" )
00816 return runMimeType( u, cfg );
00817
00818
00819 TQString tmp = i18n("The desktop entry of type\n%1\nis unknown.").arg( type );
00820 KMessageBoxWrapper::error( 0, tmp);
00821
00822 return 0;
00823 }
00824
00825 pid_t KDEDesktopMimeType::runFSDevice( const KURL& _url, const KSimpleConfig &cfg )
00826 {
00827 pid_t retval = 0;
00828
00829 TQString dev = cfg.readEntry( "Dev" );
00830
00831 if ( dev.isEmpty() )
00832 {
00833 TQString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() );
00834 KMessageBoxWrapper::error( 0, tmp);
00835 return retval;
00836 }
00837
00838 TQString mp = TDEIO::findDeviceMountPoint( dev );
00839
00840 if ( !mp.isNull() )
00841 {
00842 KURL mpURL;
00843 mpURL.setPath( mp );
00844
00845 retval = KRun::runURL( mpURL, TQString::fromLatin1("inode/directory") );
00846 }
00847 else
00848 {
00849 bool ro = cfg.readBoolEntry( "ReadOnly", false );
00850 TQString fstype = cfg.readEntry( "FSType" );
00851 if ( fstype == "Default" )
00852 fstype = TQString::null;
00853 TQString point = cfg.readEntry( "MountPoint" );
00854 #ifndef Q_WS_WIN
00855 (void) new KAutoMount( ro, fstype, dev, point, _url.path() );
00856 #endif
00857 retval = -1;
00858 }
00859
00860 return retval;
00861 }
00862
00863 pid_t KDEDesktopMimeType::runApplication( const KURL& , const TQString & _serviceFile )
00864 {
00865 KService s( _serviceFile );
00866 if ( !s.isValid() )
00867
00868 return 0;
00869
00870 KURL::List lst;
00871 return KRun::run( s, lst );
00872 }
00873
00874 pid_t KDEDesktopMimeType::runLink( const KURL& _url, const KSimpleConfig &cfg )
00875 {
00876 TQString u = cfg.readPathEntry( "URL" );
00877 if ( u.isEmpty() )
00878 {
00879 TQString tmp = i18n("The desktop entry file\n%1\nis of type Link but has no URL=... entry.").arg( _url.prettyURL() );
00880 KMessageBoxWrapper::error( 0, tmp );
00881 return 0;
00882 }
00883
00884 KURL url ( u );
00885 KRun* run = new KRun(url);
00886
00887
00888
00889
00890 TQString lastOpenedWidth = cfg.readEntry( "X-TDE-LastOpenedWith" );
00891 if ( !lastOpenedWidth.isEmpty() )
00892 run->setPreferredService( lastOpenedWidth );
00893
00894 return -1;
00895 }
00896
00897 pid_t KDEDesktopMimeType::runMimeType( const KURL& url , const KSimpleConfig & )
00898 {
00899
00900
00901
00902 TQStringList args;
00903 args << "openProperties";
00904 args << url.path();
00905
00906 int pid;
00907 if ( !TDEApplication::tdeinitExec("kfmclient", args, 0, &pid) )
00908 return pid;
00909
00910 TDEProcess p;
00911 p << "kfmclient" << args;
00912 p.start(TDEProcess::DontCare);
00913 return p.pid();
00914 }
00915
00916 TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::builtinServices( const KURL& _url )
00917 {
00918 TQValueList<Service> result;
00919
00920 if ( !_url.isLocalFile() )
00921 return result;
00922
00923 KSimpleConfig cfg( _url.path(), true );
00924 cfg.setDesktopGroup();
00925 TQString type = cfg.readEntry( "Type" );
00926
00927 if ( type.isEmpty() )
00928 return result;
00929
00930 if ( type == "FSDevice" )
00931 {
00932 TQString dev = cfg.readEntry( "Dev" );
00933 if ( dev.isEmpty() )
00934 {
00935 TQString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() );
00936 KMessageBoxWrapper::error( 0, tmp);
00937 }
00938 else
00939 {
00940 TQString mp = TDEIO::findDeviceMountPoint( dev );
00941
00942 if ( mp.isEmpty() )
00943 {
00944 Service mount;
00945 mount.m_strName = i18n("Mount");
00946 mount.m_type = ST_MOUNT;
00947 result.append( mount );
00948 }
00949 else
00950 {
00951 Service unmount;
00952 #ifdef HAVE_VOLMGT
00953
00954
00955
00956 unmount.m_strName = i18n("Eject");
00957 #else
00958 unmount.m_strName = i18n("Unmount");
00959 #endif
00960 unmount.m_type = ST_UNMOUNT;
00961 result.append( unmount );
00962 }
00963 }
00964 }
00965
00966 return result;
00967 }
00968
00969 TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const TQString& path, bool bLocalFiles )
00970 {
00971 KSimpleConfig cfg( path, true );
00972 return userDefinedServices( path, cfg, bLocalFiles );
00973 }
00974
00975 TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const TQString& path, TDEConfig& cfg, bool bLocalFiles )
00976 {
00977 return userDefinedServices( path, cfg, bLocalFiles, KURL::List() );
00978 }
00979
00980 TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const TQString& path, TDEConfig& cfg, bool bLocalFiles, const KURL::List & file_list )
00981 {
00982 TQValueList<Service> result;
00983
00984 cfg.setDesktopGroup();
00985
00986 if ( !cfg.hasKey( "Actions" ) && !cfg.hasKey( "X-TDE-GetActionMenu") )
00987 return result;
00988
00989 if ( cfg.hasKey( "TryExec" ) )
00990 {
00991 TQString tryexec = cfg.readPathEntry( "TryExec" );
00992 TQString exe = TDEStandardDirs::findExe( tryexec );
00993 if (exe.isEmpty()) {
00994 return result;
00995 }
00996 }
00997
00998 TQStringList keys;
00999
01000 if( cfg.hasKey( "X-TDE-GetActionMenu" )) {
01001 TQString dcopcall = cfg.readEntry( "X-TDE-GetActionMenu" );
01002 const TQCString app = TQString(dcopcall.section(' ', 0,0)).utf8();
01003
01004 TQByteArray dataToSend;
01005 TQDataStream dataStream(dataToSend, IO_WriteOnly);
01006 dataStream << file_list;
01007 TQCString replyType;
01008 TQByteArray replyData;
01009 TQCString object = TQString(dcopcall.section(' ', 1,-2)).utf8();
01010 TQString function = dcopcall.section(' ', -1);
01011 if(!function.endsWith("(KURL::List)")) {
01012 kdWarning() << "Desktop file " << path << " contains an invalid X-TDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl;
01013 } else {
01014 if(kapp->dcopClient()->call( app, object,
01015 function.utf8(),
01016 dataToSend, replyType, replyData, true, -1)
01017 && replyType == "TQStringList" ) {
01018
01019 TQDataStream dataStreamIn(replyData, IO_ReadOnly);
01020 dataStreamIn >> keys;
01021 }
01022 }
01023 }
01024
01025 keys += cfg.readListEntry( "Actions", ';' );
01026
01027 if ( keys.count() == 0 )
01028 return result;
01029
01030 TQStringList::ConstIterator it = keys.begin();
01031 TQStringList::ConstIterator end = keys.end();
01032 for ( ; it != end; ++it )
01033 {
01034
01035
01036 TQString group = *it;
01037
01038 if (group == "_SEPARATOR_")
01039 {
01040 Service s;
01041 result.append(s);
01042 continue;
01043 }
01044
01045 group.prepend( "Desktop Action " );
01046
01047 bool bInvalidMenu = false;
01048
01049 if ( cfg.hasGroup( group ) )
01050 {
01051 cfg.setGroup( group );
01052
01053 if ( !cfg.hasKey( "Name" ) || !cfg.hasKey( "Exec" ) )
01054 bInvalidMenu = true;
01055 else
01056 {
01057 TQString exec = cfg.readPathEntry( "Exec" );
01058 if ( bLocalFiles || exec.contains("%U") || exec.contains("%u") )
01059 {
01060 Service s;
01061 s.m_strName = cfg.readEntry( "Name" );
01062 s.m_strIcon = cfg.readEntry( "Icon" );
01063 s.m_strExec = exec;
01064 s.m_type = ST_USER_DEFINED;
01065 s.m_display = !cfg.readBoolEntry( "NoDisplay" );
01066 result.append( s );
01067 }
01068 }
01069 }
01070 else
01071 bInvalidMenu = true;
01072
01073 if ( bInvalidMenu )
01074 {
01075 TQString tmp = i18n("The desktop entry file\n%1\n has an invalid menu entry\n%2.").arg( path ).arg( *it );
01076 KMessageBoxWrapper::error( 0, tmp );
01077 }
01078 }
01079
01080 return result;
01081 }
01082
01083 void KDEDesktopMimeType::executeService( const TQString& _url, KDEDesktopMimeType::Service& _service )
01084 {
01085 KURL u;
01086 u.setPath(_url);
01087 KURL::List lst;
01088 lst.append( u );
01089 executeService( lst, _service );
01090 }
01091
01092 void KDEDesktopMimeType::executeService( const KURL::List& urls, KDEDesktopMimeType::Service& _service )
01093 {
01094
01095
01096 if ( _service.m_type == ST_USER_DEFINED )
01097 {
01098 kdDebug() << "KDEDesktopMimeType::executeService " << _service.m_strName
01099 << " first url's path=" << urls.first().path() << " exec=" << _service.m_strExec << endl;
01100 KRun::run( _service.m_strExec, urls, _service.m_strName, _service.m_strIcon, _service.m_strIcon );
01101
01102 KDirNotify_stub allDirNotify("*", "KDirNotify*");
01103 allDirNotify.FilesChanged( urls );
01104 return;
01105 }
01106 else if ( _service.m_type == ST_MOUNT || _service.m_type == ST_UNMOUNT )
01107 {
01108 Q_ASSERT( urls.count() == 1 );
01109 TQString path = urls.first().path();
01110
01111
01112 KSimpleConfig cfg( path, true );
01113 cfg.setDesktopGroup();
01114 TQString dev = cfg.readEntry( "Dev" );
01115 if ( dev.isEmpty() )
01116 {
01117 TQString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( path );
01118 KMessageBoxWrapper::error( 0, tmp );
01119 return;
01120 }
01121 TQString mp = TDEIO::findDeviceMountPoint( dev );
01122
01123 if ( _service.m_type == ST_MOUNT )
01124 {
01125
01126 if ( !mp.isEmpty() )
01127 {
01128 kdDebug(7009) << "ALREADY Mounted" << endl;
01129 return;
01130 }
01131
01132 bool ro = cfg.readBoolEntry( "ReadOnly", false );
01133 TQString fstype = cfg.readEntry( "FSType" );
01134 if ( fstype == "Default" )
01135 fstype = TQString::null;
01136 TQString point = cfg.readEntry( "MountPoint" );
01137 #ifndef Q_WS_WIN
01138 (void)new KAutoMount( ro, fstype, dev, point, path, false );
01139 #endif
01140 }
01141 else if ( _service.m_type == ST_UNMOUNT )
01142 {
01143
01144 if ( mp.isEmpty() )
01145 return;
01146
01147 #ifndef Q_WS_WIN
01148 (void)new KAutoUnmount( mp, path );
01149 #endif
01150 }
01151 }
01152 else
01153 assert( 0 );
01154 }
01155
01156 const TQString & KMimeType::defaultMimeType()
01157 {
01158 static const TQString & s_strDefaultMimeType =
01159 TDEGlobal::staticQString( "application/octet-stream" );
01160 return s_strDefaultMimeType;
01161 }
01162
01163 void KMimeType::virtual_hook( int id, void* data )
01164 { KServiceType::virtual_hook( id, data ); }
01165
01166 void KFolderType::virtual_hook( int id, void* data )
01167 { KMimeType::virtual_hook( id, data ); }
01168
01169 void KDEDesktopMimeType::virtual_hook( int id, void* data )
01170 { KMimeType::virtual_hook( id, data ); }
01171
01172 void KExecMimeType::virtual_hook( int id, void* data )
01173 { KMimeType::virtual_hook( id, data ); }
01174
01175 #include "kmimetyperesolver.moc"
01176