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