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