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