# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:13:31 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001