kio Library API Documentation

kfilemetainfo.cpp

00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 2001-2002 Rolf Magnus <ramagnus@kde.org> 00004 * Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation version 2.0. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 * Boston, MA 02111-1307, USA. 00019 * 00020 * $Id: kfilemetainfo.cpp,v 1.78 2004/01/12 19:15:09 mueller Exp $ 00021 */ 00022 00023 #include <qshared.h> 00024 #include <qdict.h> 00025 00026 #include <ktrader.h> 00027 #include <kstaticdeleter.h> 00028 #include <kparts/componentfactory.h> 00029 #include <kuserprofile.h> 00030 #include <kdebug.h> 00031 #include <kmimetype.h> 00032 #include <kdatastream.h> // needed for serialization of bool 00033 #include <klocale.h> 00034 #include <kio/global.h> 00035 00036 #include "kfilemetainfo.h" 00037 00038 // shared data of a KFileMetaInfoItem 00039 class KFileMetaInfoItem::Data : public QShared 00040 { 00041 public: 00042 Data( const KFileMimeTypeInfo::ItemInfo* mti, const QString& _key, 00043 const QVariant& _value ) 00044 : QShared(), 00045 mimeTypeInfo( mti ), 00046 key( _key ), 00047 value( _value ), 00048 dirty( false ), 00049 added( false ), 00050 removed( false ) 00051 {} 00052 00053 // we use this one for the streaming operators 00054 Data() : mimeTypeInfo( 0L ) 00055 {} 00056 00057 ~Data() 00058 { 00059 if ( this == null ) // only the null item owns its mimeTypeInfo 00060 delete mimeTypeInfo; 00061 } 00062 00063 const KFileMimeTypeInfo::ItemInfo* mimeTypeInfo; 00064 // mimeTypeInfo has the key, too, but only for non-variable ones 00065 QString key; 00066 QVariant value; 00067 bool dirty :1; 00068 bool added :1; 00069 bool removed :1; 00070 00071 static Data* null; 00072 static Data* makeNull(); 00073 }; 00074 00075 //this is our null data 00076 KFileMetaInfoItem::Data* KFileMetaInfoItem::Data::null; 00077 static KStaticDeleter<KFileMetaInfoItem::Data> sd_KFileMetaInfoItemData; 00078 00079 KFileMetaInfoItem::Data* KFileMetaInfoItem::Data::makeNull() 00080 { 00081 if (!null) 00082 { 00083 // We deliberately do not reset "null" after it has been destroyed! 00084 // Otherwise we will run into problems later in ~KFileMetaInfoItem 00085 // where the d-pointer is compared against null. 00086 00087 KFileMimeTypeInfo::ItemInfo* info = new KFileMimeTypeInfo::ItemInfo(); 00088 null = new Data(info, QString::null, QVariant()); 00089 sd_KFileMetaInfoItemData.setObject( null ); 00090 } 00091 return null; 00092 } 00093 00094 KFileMetaInfoItem::KFileMetaInfoItem( const KFileMimeTypeInfo::ItemInfo* mti, 00095 const QString& key, const QVariant& value ) 00096 : d( new Data( mti, key, value ) ) 00097 { 00098 } 00099 00100 KFileMetaInfoItem::KFileMetaInfoItem( const KFileMetaInfoItem& item ) 00101 { 00102 // operator= does everything that's necessary 00103 d = Data::makeNull(); 00104 *this = item; 00105 } 00106 00107 KFileMetaInfoItem::KFileMetaInfoItem() 00108 { 00109 d = Data::makeNull(); 00110 } 00111 00112 KFileMetaInfoItem::~KFileMetaInfoItem() 00113 { 00114 deref(); 00115 } 00116 00117 const KFileMetaInfoItem& KFileMetaInfoItem::operator= 00118 (const KFileMetaInfoItem & item ) 00119 { 00120 if (d != item.d) 00121 { 00122 // first deref the old one 00123 deref(); 00124 d = item.d; 00125 // and now ref the new one 00126 ref(); 00127 } 00128 00129 return *this; 00130 } 00131 00132 bool KFileMetaInfoItem::setValue( const QVariant& value ) 00133 { 00134 // We don't call makeNull here since it isn't necassery, see deref() 00135 if ( d == Data::null ) return false; 00136 00137 if ( ! (d->mimeTypeInfo->attributes() & KFileMimeTypeInfo::Modifiable ) || 00138 ! (value.canCast(d->mimeTypeInfo->type()))) 00139 { 00140 kdDebug(7033) << "setting the value of " << key() << "failed\n"; 00141 return false; 00142 } 00143 00144 // kdDebug(7033) << key() << ".setValue()\n"; 00145 00146 if ( d->value == value ) 00147 return true; 00148 00149 d->dirty = true; 00150 d->value = value; 00151 // If we don't cast (and test for canCast in the above if), QVariant is 00152 // very picky about types (e.g. QString vs. QCString or int vs. uint) 00153 d->value.cast(d->mimeTypeInfo->type()); 00154 00155 return true; 00156 } 00157 00158 bool KFileMetaInfoItem::isRemoved() const 00159 { 00160 return d->removed; 00161 } 00162 00163 QString KFileMetaInfoItem::key() const 00164 { 00165 return d->key; 00166 } 00167 00168 QString KFileMetaInfoItem::translatedKey() const 00169 { 00170 // are we a variable key? 00171 if (d->mimeTypeInfo->key().isNull()) 00172 { 00173 // then try if we have luck with i18n() 00174 return i18n(d->key.utf8()); 00175 } 00176 00177 return d->mimeTypeInfo->translatedKey(); 00178 } 00179 00180 const QVariant& KFileMetaInfoItem::value() const 00181 { 00182 return d->value; 00183 } 00184 00185 QString KFileMetaInfoItem::string( bool mangle ) const 00186 { 00187 return d->mimeTypeInfo->string(d->value, mangle); 00188 } 00189 00190 QVariant::Type KFileMetaInfoItem::type() const 00191 { 00192 return d->mimeTypeInfo->type(); 00193 } 00194 00195 uint KFileMetaInfoItem::unit() const 00196 { 00197 return d->mimeTypeInfo->unit(); 00198 } 00199 00200 bool KFileMetaInfoItem::isModified() const 00201 { 00202 return d->dirty; 00203 } 00204 00205 QString KFileMetaInfoItem::prefix() const 00206 { 00207 return d->mimeTypeInfo->prefix(); 00208 } 00209 00210 QString KFileMetaInfoItem::suffix() const 00211 { 00212 return d->mimeTypeInfo->suffix(); 00213 } 00214 00215 uint KFileMetaInfoItem::hint() const 00216 { 00217 return d->mimeTypeInfo->hint(); 00218 } 00219 00220 uint KFileMetaInfoItem::attributes() const 00221 { 00222 return d->mimeTypeInfo->attributes(); 00223 } 00224 00225 bool KFileMetaInfoItem::isEditable() const 00226 { 00227 return d->mimeTypeInfo->attributes() & KFileMimeTypeInfo::Modifiable; 00228 } 00229 00230 bool KFileMetaInfoItem::isValid() const 00231 { 00232 // We don't call makeNull here since it isn't necassery: 00233 // If d is equal to null it means that null is initialized already. 00234 // null is 0L when it hasn't been initialized and d is never 0L. 00235 return d != Data::null; 00236 } 00237 00238 void KFileMetaInfoItem::setAdded() 00239 { 00240 d->added = true; 00241 } 00242 00243 void KFileMetaInfoItem::setRemoved() 00244 { 00245 d->removed = true; 00246 } 00247 00248 void KFileMetaInfoItem::ref() 00249 { 00250 if (d != Data::null) d->ref(); 00251 } 00252 00253 void KFileMetaInfoItem::deref() 00254 { 00255 // We don't call makeNull here since it isn't necassery: 00256 // If d is equal to null it means that null is initialized already. 00257 // null is 0L when it hasn't been initialized and d is never 0L. 00258 if ((d != Data::null) && d->deref()) 00259 { 00260 // kdDebug(7033) << "item " << d->key 00261 // << " is finally deleted\n"; 00262 delete d; 00263 } 00264 } 00265 00268 00269 // shared data of a KFileMetaInfo 00270 class KFileMetaInfo::Data : public QShared 00271 { 00272 public: 00273 Data(const KURL& _url, uint _what) 00274 : QShared(), 00275 url(_url), 00276 what(_what), 00277 mimeTypeInfo( 0L ) 00278 {} 00279 00280 // wee use this one for the streaming operators 00281 Data() {}; 00282 00283 KURL url; 00284 uint what; 00285 QMap<QString, KFileMetaInfoGroup> groups; 00286 const KFileMimeTypeInfo* mimeTypeInfo; 00287 QStringList removedGroups; 00288 00289 static Data* null; 00290 static Data* makeNull(); 00291 00292 }; 00293 00294 KFileMetaInfo::KFileMetaInfo( const QString& path, const QString& mimeType, 00295 uint what ) 00296 { 00297 KURL u; 00298 00299 u.setPath(path); 00300 init(u, mimeType, what); 00301 } 00302 00303 KFileMetaInfo::KFileMetaInfo( const KURL& url, const QString& mimeType, 00304 uint what ) 00305 { 00306 init(url, mimeType, what); 00307 } 00308 00309 void KFileMetaInfo::init( const KURL& url, const QString& mimeType, 00310 uint what ) 00311 { 00312 d = new Data( url, what ); 00313 00314 QString mT; 00315 if (mimeType.isEmpty()) 00316 mT = KMimeType::findByURL(url)->name(); 00317 else 00318 mT = mimeType; 00319 00320 // let's "share our property" 00321 KFileMetaInfo item(*this); 00322 00323 d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mT); 00324 if ( d->mimeTypeInfo ) 00325 { 00326 // kdDebug(7033) << "Found mimetype info for " << mT << endl; 00327 KFilePlugin *p = plugin(); 00328 if (p && !p->readInfo( item, what)) 00329 *this=KFileMetaInfo(); 00330 } 00331 else 00332 { 00333 // kdDebug(7033) << "No mimetype info for " << mimeType << endl; 00334 d = Data::makeNull(); 00335 } 00336 } 00337 00338 KFileMetaInfo::KFileMetaInfo( const KFileMetaInfo& original ) 00339 { 00340 // operator= does everything that's necessary 00341 d = Data::makeNull(); 00342 *this = original; 00343 } 00344 00345 KFileMetaInfo::KFileMetaInfo() 00346 { 00347 d = Data::makeNull(); 00348 } 00349 00350 KFileMetaInfo::~KFileMetaInfo() 00351 { 00352 deref(); 00353 } 00354 00355 QStringList KFileMetaInfo::supportedGroups() const 00356 { 00357 return d->mimeTypeInfo->supportedGroups(); 00358 } 00359 00360 QStringList KFileMetaInfo::supportedKeys() const 00361 { 00362 return d->mimeTypeInfo->supportedKeys(); 00363 } 00364 00365 QStringList KFileMetaInfo::groups() const 00366 { 00367 QStringList list; 00368 QMapConstIterator<QString, KFileMetaInfoGroup> it = d->groups.begin(); 00369 for ( ; it != d->groups.end(); ++it ) 00370 list += (*it).name(); 00371 00372 return list; 00373 } 00374 00375 QStringList KFileMetaInfo::editableGroups() const 00376 { 00377 QStringList list; 00378 QStringList supported = supportedGroups(); 00379 QStringList::ConstIterator it = supported.begin(); 00380 for ( ; it != supported.end(); ++it ) { 00381 const KFileMimeTypeInfo::GroupInfo * groupInfo = d->mimeTypeInfo->groupInfo( *it ); 00382 if ( groupInfo && groupInfo->attributes() & 00383 (KFileMimeTypeInfo::Addable | KFileMimeTypeInfo::Removable) ) 00384 list.append( *it ); 00385 } 00386 00387 return list; 00388 } 00389 00390 QStringList KFileMetaInfo::preferredGroups() const 00391 { 00392 QStringList list = groups(); 00393 QStringList newlist; 00394 QStringList preferred = d->mimeTypeInfo->preferredGroups(); 00395 QStringList::Iterator pref; 00396 00397 // move all keys from the preferred groups that are in our list to a new list 00398 for ( pref = preferred.begin(); pref != preferred.end(); pref++ ) 00399 { 00400 QStringList::Iterator group = list.find(*pref); 00401 if ( group != list.end() ) 00402 { 00403 newlist.append( *group ); 00404 list.remove(group); 00405 } 00406 } 00407 00408 // now the old list only contains the non-preferred items, so we 00409 // add the remaining ones to newlist 00410 newlist += list; 00411 00412 return newlist; 00413 } 00414 00415 QStringList KFileMetaInfo::preferredKeys() const 00416 { 00417 QStringList newlist; 00418 00419 QStringList list = preferredGroups(); 00420 for (QStringList::Iterator git = list.begin(); git != list.end(); ++git) 00421 { 00422 newlist += d->groups[*git].preferredKeys(); 00423 } 00424 00425 return newlist; 00426 } 00427 00428 KFileMetaInfoGroup KFileMetaInfo::group(const QString& key) const 00429 { 00430 QMapIterator<QString,KFileMetaInfoGroup> it = d->groups.find( key ); 00431 if ( it != d->groups.end() ) 00432 return it.data(); 00433 else 00434 return KFileMetaInfoGroup(); 00435 } 00436 00437 bool KFileMetaInfo::addGroup( const QString& name ) 00438 { 00439 if ( d->mimeTypeInfo->supportedGroups().contains(name) && 00440 ! d->groups.contains(name) ) 00441 { 00442 KFileMetaInfoGroup group( name, d->mimeTypeInfo ); 00443 00444 // add all the items that can't be added by the user later 00445 const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(name); 00446 Q_ASSERT(ginfo); 00447 if (!ginfo) return false; 00448 00449 QStringList keys = ginfo->supportedKeys(); 00450 for (QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) 00451 { 00452 const KFileMimeTypeInfo::ItemInfo* iteminfo = ginfo->itemInfo(*it); 00453 Q_ASSERT(ginfo); 00454 if (!iteminfo) return false; 00455 00456 if ( !(iteminfo->attributes() & KFileMimeTypeInfo::Addable) && 00457 (iteminfo->attributes() & KFileMimeTypeInfo::Modifiable)) 00458 { 00459 // append it now or never 00460 group.appendItem(iteminfo->key(), QVariant()); 00461 } 00462 00463 } 00464 00465 d->groups.insert(name, group); 00466 group.setAdded(); 00467 return true; 00468 } 00469 00470 return false; 00471 } 00472 00473 bool KFileMetaInfo::removeGroup( const QString& name ) 00474 { 00475 QMapIterator<QString, KFileMetaInfoGroup> it = d->groups.find(name); 00476 if ( (it==d->groups.end()) || 00477 !((*it).attributes() & KFileMimeTypeInfo::Removable)) 00478 return false; 00479 00480 d->groups.remove(it); 00481 d->removedGroups.append(name); 00482 return true; 00483 } 00484 00485 QStringList KFileMetaInfo::removedGroups() 00486 { 00487 return d->removedGroups; 00488 } 00489 00490 const KFileMetaInfo& KFileMetaInfo::operator= (const KFileMetaInfo& info ) 00491 { 00492 if (d != info.d) 00493 { 00494 deref(); 00495 // first deref the old one 00496 d = info.d; 00497 // and now ref the new one 00498 ref(); 00499 } 00500 return *this; 00501 } 00502 00503 bool KFileMetaInfo::isValid() const 00504 { 00505 // We don't call makeNull here since it isn't necassery, see deref() 00506 return d != Data::null; 00507 } 00508 00509 bool KFileMetaInfo::isEmpty() const 00510 { 00511 for (QMapIterator<QString, KFileMetaInfoGroup> it = d->groups.begin(); 00512 it!=d->groups.end(); ++it) 00513 if (!(*it).isEmpty()) 00514 return false; 00515 return true; 00516 } 00517 00518 bool KFileMetaInfo::applyChanges() 00519 { 00520 bool doit = false; 00521 00522 // kdDebug(7033) << "KFileMetaInfo::applyChanges()\n"; 00523 00524 // look up if we need to write to the file 00525 QMapConstIterator<QString, KFileMetaInfoGroup> it; 00526 for (it = d->groups.begin(); it!=d->groups.end() && !doit; ++it) 00527 { 00528 if ( (*it).isModified() ) 00529 doit = true; 00530 00531 else 00532 { 00533 QStringList keys = it.data().keys(); 00534 for (QStringList::Iterator it2 = keys.begin(); it2!=keys.end(); ++it2) 00535 { 00536 if ( (*it)[*it2].isModified() ) 00537 { 00538 doit = true; 00539 break; 00540 } 00541 } 00542 } 00543 } 00544 00545 if (!doit) 00546 { 00547 kdDebug(7033) << "Don't need to write, nothing changed\n"; 00548 return true; 00549 } 00550 00551 KFilePlugin* p = plugin(); 00552 if (!p) return false; 00553 00554 // kdDebug(7033) << "Ok, trying to write the info\n"; 00555 00556 return p->writeInfo(*this); 00557 } 00558 00559 KFilePlugin * const KFileMetaInfo::plugin() const 00560 { 00561 KFileMetaInfoProvider* prov = KFileMetaInfoProvider::self(); 00562 return prov->plugin( d->mimeTypeInfo->mimeType() ); 00563 } 00564 00565 QString KFileMetaInfo::mimeType() const 00566 { 00567 return d->mimeTypeInfo->mimeType(); 00568 } 00569 00570 bool KFileMetaInfo::contains(const QString& key) const 00571 { 00572 QStringList glist = groups(); 00573 for (QStringList::Iterator it = glist.begin(); it != glist.end(); ++it) 00574 { 00575 KFileMetaInfoGroup g = d->groups[*it]; 00576 if (g.contains(key)) return true; 00577 } 00578 return false; 00579 } 00580 00581 bool KFileMetaInfo::containsGroup(const QString& key) const 00582 { 00583 return groups().contains(key); 00584 } 00585 00586 KFileMetaInfoItem KFileMetaInfo::item( const QString& key) const 00587 { 00588 QStringList groups = preferredGroups(); 00589 for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it) 00590 { 00591 KFileMetaInfoItem i = d->groups[*it][key]; 00592 if (i.isValid()) return i; 00593 } 00594 return KFileMetaInfoItem(); 00595 } 00596 00597 KFileMetaInfoItem KFileMetaInfo::item(const KFileMetaInfoItem::Hint hint) const 00598 { 00599 QStringList groups = preferredGroups(); 00600 QStringList::ConstIterator it; 00601 for (it = groups.begin(); it != groups.end(); ++it) 00602 { 00603 KFileMetaInfoItem i = d->groups[*it].item(hint); 00604 if (i.isValid()) return i; 00605 } 00606 return KFileMetaInfoItem(); 00607 } 00608 00609 KFileMetaInfoItem KFileMetaInfo::saveItem( const QString& key, 00610 const QString& preferredGroup, 00611 bool createGroup ) 00612 { 00613 // try the preferred groups first 00614 if ( !preferredGroup.isEmpty() ) { 00615 QMapIterator<QString,KFileMetaInfoGroup> it = 00616 d->groups.find( preferredGroup ); 00617 00618 // try to create the preferred group, if necessary 00619 if ( it == d->groups.end() && createGroup ) { 00620 const KFileMimeTypeInfo::GroupInfo *groupInfo = 00621 d->mimeTypeInfo->groupInfo( preferredGroup ); 00622 if ( groupInfo && groupInfo->supportedKeys().contains( key ) ) { 00623 if ( addGroup( preferredGroup ) ) 00624 it = d->groups.find( preferredGroup ); 00625 } 00626 } 00627 00628 if ( it != d->groups.end() ) { 00629 KFileMetaInfoItem item = it.data().addItem( key ); 00630 if ( item.isValid() ) 00631 return item; 00632 } 00633 } 00634 00635 QStringList groups = preferredGroups(); 00636 00637 KFileMetaInfoItem item; 00638 00639 QStringList::ConstIterator groupIt = groups.begin(); 00640 for ( ; groupIt != groups.end(); ++groupIt ) 00641 { 00642 QMapIterator<QString,KFileMetaInfoGroup> it = d->groups.find( *groupIt ); 00643 if ( it != d->groups.end() ) 00644 { 00645 KFileMetaInfoGroup group = it.data(); 00646 item = findEditableItem( group, key ); 00647 if ( item.isValid() ) 00648 return item; 00649 } 00650 else // not existant -- try to create the group 00651 { 00652 const KFileMimeTypeInfo::GroupInfo *groupInfo = 00653 d->mimeTypeInfo->groupInfo( *groupIt ); 00654 if ( groupInfo && groupInfo->supportedKeys().contains( key ) ) 00655 { 00656 if ( addGroup( *groupIt ) ) 00657 { 00658 KFileMetaInfoGroup group = d->groups[*groupIt]; 00659 KFileMetaInfoItem item = group.addItem( key ); 00660 if ( item.isValid() ) 00661 return item; 00662 // else ### add when removeGroup() is implemented :) 00663 // removeGroup( *groupIt ); // couldn't add item -> remove 00664 } 00665 } 00666 } 00667 } 00668 00669 // finally check for variable items 00670 00671 return item; 00672 } 00673 00674 KFileMetaInfoItem KFileMetaInfo::findEditableItem( KFileMetaInfoGroup& group, 00675 const QString& key ) 00676 { 00677 KFileMetaInfoItem item = group.addItem( key ); 00678 if ( item.isValid() && item.isEditable() ) 00679 return item; 00680 00681 if ( (d->mimeTypeInfo->groupInfo( group.name() )->attributes() & KFileMimeTypeInfo::Addable) ) 00682 return item; 00683 00684 return KFileMetaInfoItem(); 00685 } 00686 00687 KFileMetaInfoGroup KFileMetaInfo::appendGroup(const QString& name) 00688 { 00689 if ( d->mimeTypeInfo->supportedGroups().contains(name) && 00690 ! d->groups.contains(name) ) 00691 { 00692 KFileMetaInfoGroup group( name, d->mimeTypeInfo ); 00693 d->groups.insert(name, group); 00694 return group; 00695 } 00696 00697 else { 00698 kdWarning(7033) << "Someone's trying to add a KFileMetaInfoGroup which is not supported or already existing: " << name << endl; 00699 return KFileMetaInfoGroup(); 00700 } 00701 } 00702 00703 QString KFileMetaInfo::path() const 00704 { 00705 return d->url.isLocalFile() ? d->url.path() : QString::null; 00706 } 00707 00708 KURL KFileMetaInfo::url() const 00709 { 00710 return d->url; 00711 } 00712 00713 void KFileMetaInfo::ref() 00714 { 00715 if (d != Data::null) d->ref(); 00716 00717 } 00718 00719 void KFileMetaInfo::deref() 00720 { 00721 // We don't call makeNull here since it isn't necassery: 00722 // If d is equal to null it means that null is initialized already. 00723 // null is 0L when it hasn't been initialized and d is never 0L. 00724 if ((d != Data::null) && d->deref()) 00725 { 00726 // kdDebug(7033) << "metainfo object for " << d->url.path << " is finally deleted\n"; 00727 delete d; 00728 } 00729 00730 } 00731 00732 00733 KFileMetaInfo::Data* KFileMetaInfo::Data::null = 0L; 00734 static KStaticDeleter<KFileMetaInfo::Data> sd_KFileMetaInfoData; 00735 00736 KFileMetaInfo::Data* KFileMetaInfo::Data::makeNull() 00737 { 00738 if (!null) 00739 // We deliberately do not reset "null" after it has been destroyed! 00740 // Otherwise we will run into problems later in ~KFileMetaInfoItem 00741 // where the d-pointer is compared against null. 00742 null = sd_KFileMetaInfoData.setObject( new KFileMetaInfo::Data(KURL(), 0) ); 00743 return null; 00744 } 00745 00748 00749 KFilePlugin::KFilePlugin( QObject *parent, const char *name, 00750 const QStringList& /*args*/) 00751 : QObject( parent, name ) 00752 { 00753 // kdDebug(7033) << "loaded a plugin for " << name << endl; 00754 } 00755 00756 KFilePlugin::~KFilePlugin() 00757 { 00758 kdDebug(7033) << "unloaded a plugin for " << name() << endl; 00759 } 00760 00761 KFileMimeTypeInfo * KFilePlugin::addMimeTypeInfo( const QString& mimeType ) 00762 { 00763 KFileMimeTypeInfo* info; 00764 00765 info = KFileMetaInfoProvider::self()-> addMimeTypeInfo( mimeType ); 00766 return info; 00767 } 00768 00769 void KFilePlugin::virtual_hook( int, void* ) 00770 { /*BASE::virtual_hook( id, data );*/ } 00771 00772 00773 KFileMimeTypeInfo::GroupInfo* KFilePlugin::addGroupInfo(KFileMimeTypeInfo* info, 00774 const QString& key, const QString& translatedKey) const 00775 { 00776 return info->addGroupInfo(key, translatedKey); 00777 } 00778 00779 void KFilePlugin::setAttributes(KFileMimeTypeInfo::GroupInfo* gi, uint attr) const 00780 { 00781 gi->m_attr = attr; 00782 } 00783 00784 void KFilePlugin::addVariableInfo(KFileMimeTypeInfo::GroupInfo* gi, 00785 QVariant::Type type, uint attr) const 00786 { 00787 gi->addVariableInfo(type, attr); 00788 } 00789 00790 KFileMimeTypeInfo::ItemInfo* KFilePlugin::addItemInfo(KFileMimeTypeInfo::GroupInfo* gi, 00791 const QString& key, 00792 const QString& translatedKey, 00793 QVariant::Type type) 00794 { 00795 return gi->addItemInfo(key, translatedKey, type); 00796 } 00797 00798 void KFilePlugin::setAttributes(KFileMimeTypeInfo::ItemInfo* item, uint attr) 00799 { 00800 item->m_attr = attr; 00801 } 00802 00803 void KFilePlugin::setHint(KFileMimeTypeInfo::ItemInfo* item, uint hint) 00804 { 00805 item->m_hint = hint; 00806 } 00807 00808 void KFilePlugin::setUnit(KFileMimeTypeInfo::ItemInfo* item, uint unit) 00809 { 00810 item->m_unit = unit; 00811 // set prefix and suffix 00812 switch (unit) 00813 { 00814 case KFileMimeTypeInfo::Seconds: 00815 item->m_suffix = i18n("s"); break; 00816 00817 case KFileMimeTypeInfo::MilliSeconds: 00818 item->m_suffix = i18n("ms"); break; 00819 00820 case KFileMimeTypeInfo::BitsPerSecond: 00821 item->m_suffix = i18n("bps"); break; 00822 00823 case KFileMimeTypeInfo::Pixels: 00824 item->m_suffix = i18n("pixels"); break; 00825 00826 case KFileMimeTypeInfo::Inches: 00827 item->m_suffix = i18n("in"); break; 00828 00829 case KFileMimeTypeInfo::Centimeters: 00830 item->m_suffix = i18n("cm"); break; 00831 00832 case KFileMimeTypeInfo::Bytes: 00833 item->m_suffix = i18n("B"); break; 00834 00835 case KFileMimeTypeInfo::KiloBytes: 00836 item->m_suffix = i18n("KB"); break; 00837 00838 case KFileMimeTypeInfo::FramesPerSecond: 00839 item->m_suffix = i18n("fps"); break; 00840 00841 case KFileMimeTypeInfo::DotsPerInch: 00842 item->m_suffix = i18n("dpi"); break; 00843 00844 case KFileMimeTypeInfo::BitsPerPixel: 00845 item->m_suffix = i18n("bpp"); break; 00846 00847 case KFileMimeTypeInfo::Hertz: 00848 item->m_suffix = i18n("Hz"); 00849 } 00850 } 00851 00852 void KFilePlugin::setPrefix(KFileMimeTypeInfo::ItemInfo* item, const QString& prefix) 00853 { 00854 item->m_prefix = prefix; 00855 } 00856 00857 void KFilePlugin::setSuffix(KFileMimeTypeInfo::ItemInfo* item, const QString& suffix) 00858 { 00859 item->m_suffix = suffix; 00860 } 00861 00862 KFileMetaInfoGroup KFilePlugin::appendGroup(KFileMetaInfo& info, const QString& key) 00863 { 00864 return info.appendGroup(key); 00865 } 00866 00867 void KFilePlugin::appendItem(KFileMetaInfoGroup& group, const QString& key, QVariant value) 00868 { 00869 group.appendItem(key, value); 00870 } 00871 00874 00875 00876 KFileMetaInfoProvider * KFileMetaInfoProvider::s_self; 00877 static KStaticDeleter<KFileMetaInfoProvider> sd; 00878 00879 KFileMetaInfoProvider * KFileMetaInfoProvider::self() 00880 { 00881 if ( !s_self ) 00882 s_self = sd.setObject( s_self, new KFileMetaInfoProvider() ); 00883 00884 return s_self; 00885 } 00886 00887 KFileMetaInfoProvider::KFileMetaInfoProvider() 00888 { 00889 m_plugins.setAutoDelete( true ); 00890 m_mimeTypeDict.setAutoDelete( true ); 00891 } 00892 00893 KFileMetaInfoProvider::~KFileMetaInfoProvider() 00894 { 00895 sd.setObject( 0 ); 00896 } 00897 00898 KFilePlugin * KFileMetaInfoProvider::plugin(const QString& mimeType) 00899 { 00900 KFilePlugin *p = m_plugins.find( mimeType ); 00901 00902 // kdDebug(7033) << "mimetype is " << mimeType << endl; 00903 00904 if ( !p ) 00905 { 00906 // kdDebug(7033) << "need to look for a plugin to load\n"; 00907 00908 KService::Ptr service = 00909 KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); 00910 00911 if ( !service || !service->isValid() ) 00912 { 00913 // kdDebug(7033) << "no valid service found\n"; 00914 return 0; 00915 } 00916 00917 p = KParts::ComponentFactory::createInstanceFromService<KFilePlugin> 00918 ( service, this, mimeType.local8Bit() ); 00919 00920 if (!p) 00921 { 00922 kdWarning(7033) << "error loading the plugin\n"; 00923 return 0; 00924 } 00925 00926 // kdDebug(7033) << "found a plugin\n"; 00927 m_plugins.insert( mimeType, p ); 00928 00929 } 00930 // else 00931 // kdDebug(7033) << "plugin already loaded\n"; 00932 00933 // kdDebug(7033) << "currently loaded plugins:\n"; 00934 00935 // QDictIterator<KFilePlugin> it( m_plugins ); 00936 // for( ; it.current(); ++it ) 00937 // kdDebug(7033) << it.currentKey() << ": " << it.current()->className() << endl; 00938 00939 return p; 00940 } 00941 00942 QStringList KFileMetaInfoProvider::preferredKeys( const QString& mimeType ) const 00943 { 00944 KService::Ptr service = 00945 KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); 00946 00947 if ( !service || !service->isValid() ) 00948 { 00949 // kdDebug(7033) << "no valid service found\n"; 00950 return QStringList(); 00951 } 00952 return service->property("PreferredItems").toStringList(); 00953 } 00954 00955 QStringList KFileMetaInfoProvider::preferredGroups( const QString& mimeType ) const 00956 { 00957 KService::Ptr service = 00958 KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); 00959 00960 if ( !service || !service->isValid() ) 00961 { 00962 // kdDebug(7033) << "no valid service found\n"; 00963 return QStringList(); 00964 } 00965 return service->property("PreferredGroups").toStringList(); 00966 } 00967 00968 const KFileMimeTypeInfo * KFileMetaInfoProvider::mimeTypeInfo( const QString& mimeType ) 00969 { 00970 KFileMimeTypeInfo *info = m_mimeTypeDict.find( mimeType ); 00971 if ( !info ) { 00972 // create the plugin (adds the mimeTypeInfo, if possible) 00973 KFilePlugin *p = plugin( mimeType ); 00974 if ( p ) 00975 info = m_mimeTypeDict.find( mimeType ); 00976 } 00977 00978 return info; 00979 } 00980 00981 KFileMimeTypeInfo * KFileMetaInfoProvider::addMimeTypeInfo( 00982 const QString& mimeType ) 00983 { 00984 KFileMimeTypeInfo *info = m_mimeTypeDict.find( mimeType ); 00985 if ( !info ) 00986 { 00987 info = new KFileMimeTypeInfo( mimeType ); 00988 m_mimeTypeDict.replace( mimeType, info ); 00989 } 00990 00991 info->m_preferredKeys = preferredKeys( mimeType ); 00992 info->m_preferredGroups = preferredGroups( mimeType ); 00993 00994 return info; 00995 } 00996 00997 QStringList KFileMetaInfoProvider::supportedMimeTypes() const 00998 { 00999 QStringList allMimeTypes; 01000 QString kfilePlugin = "KFilePlugin"; 01001 01002 KTrader::OfferList offers = KTrader::self()->query( "KFilePlugin" ); 01003 KTrader::OfferListIterator it = offers.begin(); 01004 for ( ; it != offers.end(); ++it ) 01005 { 01006 QStringList mimeTypes = (*it)->serviceTypes(); 01007 QStringList::ConstIterator it2 = mimeTypes.begin(); 01008 for ( ; it2 != mimeTypes.end(); ++it2 ) 01009 if ( allMimeTypes.find( *it2 ) == allMimeTypes.end() && 01010 *it2 != kfilePlugin ) // also in serviceTypes() 01011 allMimeTypes.append( *it2 ); 01012 } 01013 01014 return allMimeTypes; 01015 } 01016 01021 01022 01023 // shared data of a KFileMetaInfoGroup 01024 class KFileMetaInfoGroup::Data : public QShared 01025 { 01026 public: 01027 Data(const QString& _name) 01028 : QShared(), 01029 name(_name), 01030 mimeTypeInfo(0L), 01031 dirty( false ), 01032 added( false ) 01033 {} 01034 01035 // we use this one for the streaming operators 01036 Data() : mimeTypeInfo(0L) {} 01037 ~Data() { 01038 if ( this == null ) 01039 delete mimeTypeInfo; 01040 }; 01041 01042 QString name; 01043 QMap<QString, KFileMetaInfoItem> items; 01044 const KFileMimeTypeInfo* mimeTypeInfo; 01045 QStringList removedItems; 01046 bool dirty :1; 01047 bool added :1; 01048 01049 static Data* null; 01050 static Data* makeNull(); 01051 01052 }; 01053 01054 KFileMetaInfoGroup::KFileMetaInfoGroup( const QString& name, 01055 const KFileMimeTypeInfo* info ) 01056 : d(new Data( name ) ) 01057 { 01058 d->mimeTypeInfo = info; 01059 } 01060 01061 KFileMetaInfoGroup::KFileMetaInfoGroup( const KFileMetaInfoGroup& original ) 01062 { 01063 // operator= does everything that's necessary 01064 d = Data::makeNull(); 01065 *this = original; 01066 } 01067 01068 KFileMetaInfoGroup::KFileMetaInfoGroup() 01069 { 01070 d = Data::makeNull(); 01071 } 01072 01073 KFileMetaInfoGroup::~KFileMetaInfoGroup() 01074 { 01075 deref(); 01076 } 01077 01078 const KFileMetaInfoGroup& KFileMetaInfoGroup::operator= (const KFileMetaInfoGroup& info ) 01079 { 01080 if (d != info.d) 01081 { 01082 deref(); 01083 // first deref the old one 01084 d = info.d; 01085 // and now ref the new one 01086 ref(); 01087 } 01088 return *this; 01089 } 01090 01091 bool KFileMetaInfoGroup::isValid() const 01092 { 01093 // We don't call makeNull here since it isn't necassery, see deref() 01094 return d != Data::null; 01095 } 01096 01097 bool KFileMetaInfoGroup::isEmpty() const 01098 { 01099 return d->items.isEmpty(); 01100 } 01101 01102 QStringList KFileMetaInfoGroup::preferredKeys() const 01103 { 01104 if (d == Data::makeNull()) 01105 kdWarning(7033) << "attempt to get the preferredKeys of " 01106 "an invalid metainfo group"; 01107 01108 QStringList list = keys(); 01109 QStringList newlist; 01110 QStringList preferredKeys = d->mimeTypeInfo->preferredKeys(); 01111 QStringList::Iterator pref; 01112 QStringList::Iterator begin = preferredKeys.begin(); 01113 QStringList::Iterator end = preferredKeys.end(); 01114 01115 // move all keys from the preferred keys that are in our list to a new list 01116 for ( pref = begin; pref!=end; pref++ ) 01117 { 01118 QStringList::Iterator item = list.find(*pref); 01119 if ( item != list.end() ) 01120 { 01121 newlist.append( *item ); 01122 list.remove(item); 01123 } 01124 } 01125 01126 // now the old list only contains the non-preferred items, so we 01127 // add the remaining ones to newlist 01128 newlist += list; 01129 01130 return newlist; 01131 } 01132 01133 QStringList KFileMetaInfoGroup::keys() const 01134 { 01135 if (d == Data::makeNull()) 01136 kdWarning(7033) << "attempt to get the keys of " 01137 "an invalid metainfo group"; 01138 01139 QStringList list; 01140 01141 // make a QStringList with all available keys 01142 QMapConstIterator<QString, KFileMetaInfoItem> it; 01143 for (it = d->items.begin(); it!=d->items.end(); ++it) 01144 { 01145 list.append(it.data().key()); 01146 // kdDebug(7033) << "Item " << it.data().key() << endl; 01147 } 01148 return list; 01149 } 01150 01151 QString KFileMetaInfoGroup::translatedName() const 01152 { 01153 return d->mimeTypeInfo->groupInfo(d->name)->translatedName(); 01154 } 01155 01156 QStringList KFileMetaInfoGroup::supportedKeys() const 01157 { 01158 return d->mimeTypeInfo->groupInfo(d->name)->supportedKeys(); 01159 } 01160 01161 bool KFileMetaInfoGroup::supportsVariableKeys() const 01162 { 01163 return d->mimeTypeInfo->groupInfo(d->name)->supportsVariableKeys(); 01164 } 01165 01166 bool KFileMetaInfoGroup::contains( const QString& key ) const 01167 { 01168 return d->items.contains(key); 01169 } 01170 01171 KFileMetaInfoItem KFileMetaInfoGroup::item( const QString& key) const 01172 { 01173 QMapIterator<QString,KFileMetaInfoItem> it = d->items.find( key ); 01174 if ( it != d->items.end() ) 01175 return it.data(); 01176 01177 return KFileMetaInfoItem(); 01178 } 01179 01180 KFileMetaInfoItem KFileMetaInfoGroup::item(uint hint) const 01181 { 01182 QMapIterator<QString, KFileMetaInfoItem> it; 01183 01184 for (it = d->items.begin(); it!=d->items.end(); ++it) 01185 if (it.data().hint() == hint) 01186 return it.data(); 01187 01188 return KFileMetaInfoItem(); 01189 } 01190 01191 QString KFileMetaInfoGroup::name() const 01192 { 01193 return d->name; 01194 } 01195 01196 uint KFileMetaInfoGroup::attributes() const 01197 { 01198 return d->mimeTypeInfo->groupInfo(d->name)->attributes(); 01199 } 01200 01201 void KFileMetaInfoGroup::setAdded() 01202 { 01203 d->added = true; 01204 } 01205 01206 bool KFileMetaInfoGroup::isModified() const 01207 { 01208 return d->dirty; 01209 } 01210 01211 void KFileMetaInfoGroup::ref() 01212 { 01213 if (d != Data::null) d->ref(); 01214 01215 } 01216 01217 void KFileMetaInfoGroup::deref() 01218 { 01219 // We don't call makeNull here since it isn't necassery: 01220 // If d is equal to null it means that null is initialized already. 01221 // null is 0L when it hasn't been initialized and d is never 0L. 01222 if ((d != Data::null) && d->deref()) 01223 { 01224 // kdDebug(7033) << "metainfo group " << d->name 01225 // << " is finally deleted\n"; 01226 delete d; 01227 } 01228 01229 } 01230 01231 KFileMetaInfoItem KFileMetaInfoGroup::addItem( const QString& key ) 01232 { 01233 QMapIterator<QString,KFileMetaInfoItem> it = d->items.find( key ); 01234 if ( it != d->items.end() ) 01235 return it.data(); 01236 01237 const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(d->name); 01238 01239 if ( !ginfo ) { 01240 Q_ASSERT( ginfo ); 01241 return KFileMetaInfoItem(); 01242 } 01243 01244 const KFileMimeTypeInfo::ItemInfo* info = ginfo->itemInfo(key); 01245 01246 if ( !info ) { 01247 Q_ASSERT( info ); 01248 return KFileMetaInfoItem(); 01249 } 01250 01251 KFileMetaInfoItem item; 01252 01253 if (info->isVariableItem()) 01254 item = KFileMetaInfoItem(ginfo->variableItemInfo(), key, QVariant()); 01255 else 01256 item = KFileMetaInfoItem(info, key, QVariant()); 01257 01258 d->items.insert(key, item); 01259 item.setAdded(); // mark as added 01260 d->dirty = true; // mark ourself as dirty, too 01261 return item; 01262 } 01263 01264 bool KFileMetaInfoGroup::removeItem( const QString& key ) 01265 { 01266 if (!isValid()) 01267 { 01268 kdDebug(7033) << "trying to remove an item from an invalid group\n"; 01269 return false; 01270 } 01271 01272 QMapIterator<QString, KFileMetaInfoItem> it = d->items.find(key); 01273 if ( it==d->items.end() ) 01274 { 01275 kdDebug(7033) << "trying to remove the non existant item " << key << "\n"; 01276 return false; 01277 } 01278 01279 if (!((*it).attributes() & KFileMimeTypeInfo::Removable)) 01280 { 01281 kdDebug(7033) << "trying to remove a non removable item\n"; 01282 return false; 01283 } 01284 01285 (*it).setRemoved(); 01286 d->items.remove(it); 01287 d->removedItems.append(key); 01288 d->dirty = true; 01289 return true; 01290 } 01291 01292 QStringList KFileMetaInfoGroup::removedItems() 01293 { 01294 return d->removedItems; 01295 } 01296 01297 KFileMetaInfoItem KFileMetaInfoGroup::appendItem(const QString& key, 01298 const QVariant& value) 01299 { 01300 const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(d->name); 01301 if ( !ginfo ) { 01302 kdWarning() << "Trying to append a Metadata item for a non-existant group:" << d->name << endl; 01303 return KFileMetaInfoItem(); 01304 } 01305 const KFileMimeTypeInfo::ItemInfo* info = ginfo->itemInfo(key); 01306 if ( !info ) { 01307 kdWarning() << "Trying to append a Metadata item for an unknown key (no ItemInfo): " << key << endl; 01308 return KFileMetaInfoItem(); 01309 } 01310 01311 KFileMetaInfoItem item; 01312 01313 if (info->key().isNull()) 01314 item = KFileMetaInfoItem(ginfo->variableItemInfo(), key, value); 01315 else 01316 item = KFileMetaInfoItem(info, key, value); 01317 01318 kdDebug(7033) << "KFileMetaInfogroup inserting a " << key << endl; 01319 01320 d->items.insert(key, item); 01321 return item; 01322 } 01323 01324 KFileMetaInfoGroup::Data* KFileMetaInfoGroup::Data::null = 0L; 01325 static KStaticDeleter<KFileMetaInfoGroup::Data> sd_KFileMetaInfoGroupData; 01326 01327 KFileMetaInfoGroup::Data* KFileMetaInfoGroup::Data::makeNull() 01328 { 01329 if (!null) 01330 { 01331 // We deliberately do not reset "null" after it has been destroyed! 01332 // Otherwise we will run into problems later in ~KFileMetaInfoItem 01333 // where the d-pointer is compared against null. 01334 null = new Data(QString::null); 01335 null->mimeTypeInfo = new KFileMimeTypeInfo(); 01336 sd_KFileMetaInfoGroupData.setObject( null ); 01337 } 01338 return null; 01339 } 01340 01341 01344 01345 KFileMimeTypeInfo::KFileMimeTypeInfo( const QString& mimeType ) 01346 : m_mimeType( mimeType ) 01347 { 01348 m_groups.setAutoDelete( true ); 01349 } 01350 01351 KFileMimeTypeInfo::~KFileMimeTypeInfo() 01352 { 01353 } 01354 01355 const KFileMimeTypeInfo::GroupInfo * KFileMimeTypeInfo::groupInfo( const QString& group ) const 01356 { 01357 return m_groups.find( group ); 01358 } 01359 01360 KFileMimeTypeInfo::GroupInfo * KFileMimeTypeInfo::addGroupInfo( 01361 const QString& name, const QString& translatedName ) 01362 { 01363 GroupInfo* group = new GroupInfo( name, translatedName ); 01364 m_groups.insert(name, group); 01365 return group; 01366 } 01367 01368 QStringList KFileMimeTypeInfo::supportedGroups() const 01369 { 01370 QStringList list; 01371 QDictIterator<GroupInfo> it( m_groups ); 01372 for ( ; it.current(); ++it ) 01373 list.append( it.current()->name() ); 01374 01375 return list; 01376 } 01377 01378 QStringList KFileMimeTypeInfo::translatedGroups() const 01379 { 01380 QStringList list; 01381 QDictIterator<GroupInfo> it( m_groups ); 01382 for ( ; it.current(); ++it ) 01383 list.append( it.current()->translatedName() ); 01384 01385 return list; 01386 } 01387 01388 QStringList KFileMimeTypeInfo::supportedKeys() const 01389 { 01390 // not really efficient, but not those are not large lists, probably. 01391 // maybe cache the result? 01392 QStringList keys; 01393 QStringList::ConstIterator lit; 01394 QDictIterator<GroupInfo> it( m_groups ); 01395 for ( ; it.current(); ++it ) { // need to nuke dupes 01396 QStringList list = it.current()->supportedKeys(); 01397 for ( lit = list.begin(); lit != list.end(); ++lit ) { 01398 if ( keys.find( *lit ) == keys.end() ) 01399 keys.append( *lit ); 01400 } 01401 } 01402 01403 return keys; 01404 } 01405 01406 QValidator * KFileMimeTypeInfo::createValidator(const QString& group, 01407 const QString& key, 01408 QObject *parent, 01409 const char *name) const 01410 { 01411 KFilePlugin* plugin = KFileMetaInfoProvider::self()->plugin(m_mimeType); 01412 if (plugin) return plugin->createValidator(mimeType(), group, key, 01413 parent, name); 01414 return 0; 01415 } 01416 01417 01420 01421 KFileMimeTypeInfo::GroupInfo::GroupInfo( const QString& name, 01422 const QString& translatedName ) 01423 : m_name( name ), 01424 m_translatedName( translatedName ), 01425 m_attr( 0 ), 01426 m_variableItemInfo( 0 ) 01427 01428 { 01429 m_itemDict.setAutoDelete( true ); 01430 } 01431 01432 const KFileMimeTypeInfo::ItemInfo * KFileMimeTypeInfo::GroupInfo::itemInfo( const QString& key ) const 01433 { 01434 ItemInfo* item = m_itemDict.find( key ); 01435 01436 // if we the item isn't found and variable keys are supported, we need to 01437 // return the default variable key iteminfo. 01438 if (!item && m_variableItemInfo) 01439 { 01440 return m_variableItemInfo; 01441 } 01442 return item; 01443 } 01444 01445 KFileMimeTypeInfo::ItemInfo* KFileMimeTypeInfo::GroupInfo::addItemInfo( 01446 const QString& key, const QString& translatedKey, 01447 QVariant::Type type) 01448 { 01449 // kdDebug(7034) << key << "(" << translatedKey << ") -> " << QVariant::typeToName(type) << endl; 01450 01451 ItemInfo* item = new ItemInfo(key, translatedKey, type); 01452 m_supportedKeys.append(key); 01453 m_itemDict.insert(key, item); 01454 return item; 01455 } 01456 01457 01458 void KFileMimeTypeInfo::GroupInfo::addVariableInfo( QVariant::Type type, 01459 uint attr ) 01460 { 01461 // just make sure that it's not already there 01462 delete m_variableItemInfo; 01463 m_variableItemInfo = new ItemInfo(QString::null, QString::null, type); 01464 m_variableItemInfo->m_attr = attr; 01465 } 01466 01469 01470 QString KFileMimeTypeInfo::ItemInfo::string(const QVariant& value, bool mangle) const 01471 { 01472 QString s; 01473 01474 switch (value.type()) 01475 { 01476 case QVariant::Invalid : 01477 return "---"; 01478 01479 case QVariant::Bool : 01480 s = value.toBool() ? i18n("Yes") : i18n("No"); 01481 break; 01482 01483 case QVariant::Int : 01484 if (unit() == KFileMimeTypeInfo::Seconds) 01485 { 01486 int seconds = value.toInt() % 60; 01487 int minutes = value.toInt() / 60 % 60; 01488 int hours = value.toInt() / 3600; 01489 s = hours ? QString().sprintf("%d:%02d:%02d",hours, minutes, seconds) 01490 : QString().sprintf("%02d:%02d", minutes, seconds); 01491 return s; // no suffix wanted 01492 } 01493 else if (unit() == KFileMimeTypeInfo::Bytes) 01494 { 01495 // convertSize already adds the correct suffix 01496 return KIO::convertSize(value.toInt()); 01497 } 01498 else if (unit() == KFileMimeTypeInfo::KiloBytes) 01499 { 01500 // convertSizeFromKB already adds the correct suffix 01501 return KIO::convertSizeFromKB(value.toInt()); 01502 } 01503 else 01504 s = KGlobal::locale()->formatNumber( value.toInt() , 0); 01505 break; 01506 01507 #if QT_VERSION >= 0x030200 01508 case QVariant::LongLong : 01509 s = KGlobal::locale()->formatNumber( value.toLongLong(), 0 ); 01510 break; 01511 01512 case QVariant::ULongLong : 01513 if ( unit() == KFileMimeTypeInfo::Bytes ) 01514 return KIO::convertSize( value.toULongLong() ); 01515 else if ( unit() == KFileMimeTypeInfo::KiloBytes ) 01516 return KIO::convertSizeFromKB( value.toULongLong() ); 01517 else 01518 s = KGlobal::locale()->formatNumber( value.toULongLong(), 0 ); 01519 break; 01520 #endif 01521 case QVariant::UInt : 01522 s = KGlobal::locale()->formatNumber( value.toUInt() , 0); 01523 break; 01524 01525 case QVariant::Double : 01526 s = KGlobal::locale()->formatNumber( value.toDouble(), 3); 01527 break; 01528 01529 case QVariant::Date : 01530 s = KGlobal::locale()->formatDate( value.toDate(), true ); 01531 break; 01532 01533 case QVariant::Time : 01534 s = KGlobal::locale()->formatTime( value.toTime(), true ); 01535 break; 01536 01537 case QVariant::DateTime : 01538 s = KGlobal::locale()->formatDateTime( value.toDateTime(), 01539 true, true ); 01540 break; 01541 01542 case QVariant::Size : 01543 s = QString("%1 x %2").arg(value.toSize().width()) 01544 .arg(value.toSize().height()); 01545 break; 01546 01547 case QVariant::Point : 01548 s = QString("%1/%2").arg(value.toSize().width()) 01549 .arg(value.toSize().height()); 01550 break; 01551 01552 default: 01553 s = value.toString(); 01554 } 01555 01556 if (mangle && !s.isNull()) 01557 { 01558 s.prepend(prefix()); 01559 s.append(" " + suffix()); 01560 } 01561 return s; 01562 } 01563 01564 01567 01568 01569 01570 // stream operators 01571 01572 /* serialization of a KFileMetaInfoItem: 01573 first a bool that says if the items is valid, and if yes, 01574 all the elements of the Data 01575 */ 01576 QDataStream& operator <<(QDataStream& s, const KFileMetaInfoItem& item ) 01577 { 01578 01579 KFileMetaInfoItem::Data* d = item.d; 01580 01581 // if the object is invalid, put only a char in the stream 01582 bool isValid = item.isValid(); 01583 s << isValid; 01584 // ### what do about mimetypeInfo ? 01585 if (isValid) 01586 s << d->key 01587 << d->value 01588 << d->dirty 01589 << d->added 01590 << d->removed; 01591 01592 return s; 01593 } 01594 01595 01596 QDataStream& operator >>(QDataStream& s, KFileMetaInfoItem& item ) 01597 { 01598 bool isValid; 01599 s >> isValid; 01600 01601 if (!isValid) 01602 { 01603 item = KFileMetaInfoItem(); 01604 return s; 01605 } 01606 01607 // we need a new object for our data 01608 item.deref(); 01609 item.d = new KFileMetaInfoItem::Data(); 01610 01611 // ### what do about mimetypeInfo ? 01612 bool dirty, added, removed; 01613 s >> item.d->key 01614 >> item.d->value 01615 >> dirty 01616 >> added 01617 >> removed; 01618 item.d->dirty = dirty; 01619 item.d->added = added; 01620 item.d->removed = removed; 01621 01622 return s; 01623 } 01624 01625 01626 // serialization of a KFileMetaInfoGroup 01627 // we serialize the name of the mimetype here instead of the mimetype info 01628 // on the other side, we can simply use this to ask the provider for the info 01629 QDataStream& operator <<(QDataStream& s, const KFileMetaInfoGroup& group ) 01630 { 01631 KFileMetaInfoGroup::Data* d = group.d; 01632 01633 // if the object is invalid, put only a byte in the stream 01634 bool isValid = group.isValid(); 01635 01636 s << isValid; 01637 if (isValid) 01638 { 01639 s << d->name 01640 << d->items 01641 << d->mimeTypeInfo->mimeType(); 01642 } 01643 return s; 01644 } 01645 01646 QDataStream& operator >>(QDataStream& s, KFileMetaInfoGroup& group ) 01647 { 01648 QString mimeType; 01649 bool isValid; 01650 s >> isValid; 01651 01652 // if it's invalid, there is not much to do 01653 if (!isValid) 01654 { 01655 group = KFileMetaInfoGroup(); 01656 return s; 01657 } 01658 01659 // we need a new object for our data 01660 group.deref(); 01661 group.d = new KFileMetaInfoGroup::Data(); 01662 group.ref(); 01663 01664 s >> group.d->name 01665 >> group.d->items 01666 >> mimeType; 01667 01668 group.d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mimeType); 01669 01670 // we need to set the item info for the items here 01671 QMapIterator<QString, KFileMetaInfoItem> it = group.d->items.begin(); 01672 for ( ; it != group.d->items.end(); ++it) 01673 { 01674 (*it).d->mimeTypeInfo = group.d->mimeTypeInfo->groupInfo(group.d->name) 01675 ->itemInfo((*it).key()); 01676 } 01677 01678 return s; 01679 } 01680 01681 // serialization of a KFileMetaInfo object 01682 // we serialize the name of the mimetype here instead of the mimetype info 01683 // on the other side, we can simply use this to ask the provider for the info 01684 QDataStream& operator <<(QDataStream& s, const KFileMetaInfo& info ) 01685 { 01686 KFileMetaInfo::Data* d = info.d; 01687 01688 // if the object is invalid, put only a byte that tells this 01689 bool isValid = info.isValid(); 01690 01691 s << isValid; 01692 if (isValid) 01693 { 01694 s << d->url 01695 << d->what 01696 << d->groups 01697 << d->mimeTypeInfo->mimeType(); 01698 } 01699 return s; 01700 } 01701 01702 QDataStream& operator >>(QDataStream& s, KFileMetaInfo& info ) 01703 { 01704 QString mimeType; 01705 bool isValid; 01706 s >> isValid; 01707 01708 // if it's invalid, there is not much to do 01709 if (!isValid) 01710 { 01711 info = KFileMetaInfo(); 01712 return s; 01713 } 01714 01715 // we need a new object for our data 01716 info.deref(); 01717 info.d = new KFileMetaInfo::Data(); 01718 info.ref(); 01719 01720 s >> info.d->url 01721 >> info.d->what 01722 >> info.d->groups 01723 >> mimeType; 01724 info.d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mimeType); 01725 01726 return s; 01727 } 01728 01729 01730 01731 01732 #include "kfilemetainfo.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 12 15:08:44 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003