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