diff options
Diffstat (limited to 'tdeio/tdeio/tdefilemetainfo.cpp')
-rw-r--r-- | tdeio/tdeio/tdefilemetainfo.cpp | 1859 |
1 files changed, 1859 insertions, 0 deletions
diff --git a/tdeio/tdeio/tdefilemetainfo.cpp b/tdeio/tdeio/tdefilemetainfo.cpp new file mode 100644 index 000000000..4943dea93 --- /dev/null +++ b/tdeio/tdeio/tdefilemetainfo.cpp @@ -0,0 +1,1859 @@ +/* + * This file is part of the KDE libraries + * Copyright (C) 2001-2002 Rolf Magnus <[email protected]> + * Copyright (C) 2001-2002 Carsten Pfeiffer <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation version 2.0. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $Id$ + */ + +#include <assert.h> + +#include <tqshared.h> +#include <tqdict.h> + +#include <ktrader.h> +#include <kstaticdeleter.h> +#include <tdeparts/componentfactory.h> +#include <kuserprofile.h> +#include <kdebug.h> +#include <kmimetype.h> +#include <kdatastream.h> // needed for serialization of bool +#include <klocale.h> +#include <tdeio/global.h> + +#include "tdefilemetainfo.h" + +// shared data of a KFileMetaInfoItem +class KFileMetaInfoItem::Data : public TQShared +{ +public: + Data( const KFileMimeTypeInfo::ItemInfo* mti, const TQString& _key, + const TQVariant& _value ) + : TQShared(), + mimeTypeInfo( mti ), + key( _key ), + value( _value ), + dirty( false ), + added( false ), + removed( false ) + {} + + // we use this one for the streaming operators + Data() : mimeTypeInfo( 0L ) + {} + + ~Data() + { + if ( this == null ) // only the null item owns its mimeTypeInfo + delete mimeTypeInfo; + } + + const KFileMimeTypeInfo::ItemInfo* mimeTypeInfo; + // mimeTypeInfo has the key, too, but only for non-variable ones + TQString key; + TQVariant value; + bool dirty :1; + bool added :1; + bool removed :1; + + static Data* null; + static Data* makeNull(); +}; + +//this is our null data +KFileMetaInfoItem::Data* KFileMetaInfoItem::Data::null = 0L; +static KStaticDeleter<KFileMetaInfoItem::Data> sd_KFileMetaInfoItemData; + +KFileMetaInfoItem::Data* KFileMetaInfoItem::Data::makeNull() +{ + if (!null) + { + // We deliberately do not reset "null" after it has been destroyed! + // Otherwise we will run into problems later in ~KFileMetaInfoItem + // where the d-pointer is compared against null. + + KFileMimeTypeInfo::ItemInfo* info = new KFileMimeTypeInfo::ItemInfo(); + null = new Data(info, TQString::null, TQVariant()); + sd_KFileMetaInfoItemData.setObject( null ); + } + return null; +} + +KFileMetaInfoItem::KFileMetaInfoItem( const KFileMimeTypeInfo::ItemInfo* mti, + const TQString& key, const TQVariant& value ) + : d( new Data( mti, key, value ) ) +{ +} + +KFileMetaInfoItem::KFileMetaInfoItem( const KFileMetaInfoItem& item ) +{ + // operator= does everything that's necessary + d = Data::makeNull(); + *this = item; +} + +KFileMetaInfoItem::KFileMetaInfoItem() +{ + d = Data::makeNull(); +} + +KFileMetaInfoItem::~KFileMetaInfoItem() +{ + deref(); +} + +const KFileMetaInfoItem& KFileMetaInfoItem::operator= + (const KFileMetaInfoItem & item ) +{ + if (d != item.d) + { + // first deref the old one + deref(); + d = item.d; + // and now ref the new one + ref(); + } + + return *this; +} + +bool KFileMetaInfoItem::setValue( const TQVariant& value ) +{ + // We don't call makeNull here since it isn't necassery, see deref() + if ( d == Data::null ) return false; + + if ( ! (d->mimeTypeInfo->attributes() & KFileMimeTypeInfo::Modifiable ) || + ! (value.canCast(d->mimeTypeInfo->type()))) + { + kdDebug(7033) << "setting the value of " << key() << "failed\n"; + return false; + } + +// kdDebug(7033) << key() << ".setValue()\n"; + + if ( d->value == value ) + return true; + + d->dirty = true; + d->value = value; + // If we don't cast (and test for canCast in the above if), TQVariant is + // very picky about types (e.g. TQString vs. TQCString or int vs. uint) + d->value.cast(d->mimeTypeInfo->type()); + + return true; +} + +bool KFileMetaInfoItem::isRemoved() const +{ + return d->removed; +} + +TQString KFileMetaInfoItem::key() const +{ + return d->key; +} + +TQString KFileMetaInfoItem::translatedKey() const +{ + // are we a variable key? + if (d->mimeTypeInfo->key().isNull()) + { + // then try if we have luck with i18n() + return i18n(d->key.utf8()); + } + + return d->mimeTypeInfo->translatedKey(); +} + +const TQVariant& KFileMetaInfoItem::value() const +{ + return d->value; +} + +TQString KFileMetaInfoItem::string( bool mangle ) const +{ + return d->mimeTypeInfo->string(d->value, mangle); +} + +TQVariant::Type KFileMetaInfoItem::type() const +{ + return d->mimeTypeInfo->type(); +} + +uint KFileMetaInfoItem::unit() const +{ + return d->mimeTypeInfo->unit(); +} + +bool KFileMetaInfoItem::isModified() const +{ + return d->dirty; +} + +TQString KFileMetaInfoItem::prefix() const +{ + return d->mimeTypeInfo->prefix(); +} + +TQString KFileMetaInfoItem::suffix() const +{ + return d->mimeTypeInfo->suffix(); +} + +uint KFileMetaInfoItem::hint() const +{ + return d->mimeTypeInfo->hint(); +} + +uint KFileMetaInfoItem::attributes() const +{ + return d->mimeTypeInfo->attributes(); +} + +bool KFileMetaInfoItem::isEditable() const +{ + return d->mimeTypeInfo->attributes() & KFileMimeTypeInfo::Modifiable; +} + +bool KFileMetaInfoItem::isValid() const +{ + // We don't call makeNull here since it isn't necassery: + // If d is equal to null it means that null is initialized already. + // null is 0L when it hasn't been initialized and d is never 0L. + return d != Data::null; +} + +void KFileMetaInfoItem::setAdded() +{ + d->added = true; +} + +void KFileMetaInfoItem::setRemoved() +{ + d->removed = true; +} + +void KFileMetaInfoItem::ref() +{ + if (d != Data::null) d->ref(); +} + +void KFileMetaInfoItem::deref() +{ + // We don't call makeNull here since it isn't necassery: + // If d is equal to null it means that null is initialized already. + // null is 0L when it hasn't been initialized and d is never 0L. + if ((d != Data::null) && d->deref()) + { +// kdDebug(7033) << "item " << d->key +// << " is finally deleted\n"; + delete d; + d = 0; + } +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +// shared data of a KFileMetaInfo +class KFileMetaInfo::Data : public TQShared +{ +public: + Data(const KURL& _url, uint _what) + : TQShared(), + url(_url), + what(_what), + mimeTypeInfo( 0L ) + {} + + // wee use this one for the streaming operators + Data() {}; + + KURL url; + uint what; + TQMap<TQString, KFileMetaInfoGroup> groups; + const KFileMimeTypeInfo* mimeTypeInfo; + TQStringList removedGroups; + + static Data* null; + static Data* makeNull(); + +}; + +KFileMetaInfo::KFileMetaInfo( const TQString& path, const TQString& mimeType, + uint what ) +{ + KURL u; + + u.setPath(path); + init(u, mimeType, what); +} + +KFileMetaInfo::KFileMetaInfo( const KURL& url, const TQString& mimeType, + uint what ) +{ + init(url, mimeType, what); +} + +void KFileMetaInfo::init( const KURL& url, const TQString& mimeType, + uint what ) +{ + d = new Data( url, what ); + + TQString mT; + if (mimeType.isEmpty()) + mT = KMimeType::findByURL(url)->name(); + else + mT = mimeType; + + // let's "share our property" + KFileMetaInfo item(*this); + + //kdDebug() << k_funcinfo << mT << " " << url << endl; + + d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo( mT, url.protocol() ); + if ( d->mimeTypeInfo ) + { + //kdDebug(7033) << "Found mimetype info for " << mT /* or protocol*/ << endl; + KFilePlugin *p = plugin(); + Q_ASSERT( p ); + if ( p && !p->readInfo( item, what) ) + { + deref(); + d = Data::makeNull(); + } + } + else + { +// kdDebug(7033) << "No mimetype info for " << mimeType << endl; + deref(); + d = Data::makeNull(); + } +} + +KFileMetaInfo::KFileMetaInfo( const KFileMetaInfo& original ) +{ + // operator= does everything that's necessary + d = Data::makeNull(); + *this = original; +} + +KFileMetaInfo::KFileMetaInfo() +{ + d = Data::makeNull(); +} + +KFileMetaInfo::~KFileMetaInfo() +{ + deref(); +} + +TQStringList KFileMetaInfo::supportedGroups() const +{ + assert(isValid()); + return d->mimeTypeInfo->supportedGroups(); +} + +TQStringList KFileMetaInfo::supportedKeys() const +{ + assert(isValid()); + return d->mimeTypeInfo->supportedKeys(); +} + +TQStringList KFileMetaInfo::groups() const +{ + TQStringList list; + TQMapConstIterator<TQString, KFileMetaInfoGroup> it = d->groups.begin(); + for ( ; it != d->groups.end(); ++it ) + list += (*it).name(); + + return list; +} + +TQStringList KFileMetaInfo::editableGroups() const +{ + TQStringList list; + TQStringList supported = supportedGroups(); + TQStringList::ConstIterator it = supported.begin(); + for ( ; it != supported.end(); ++it ) { + const KFileMimeTypeInfo::GroupInfo * groupInfo = d->mimeTypeInfo->groupInfo( *it ); + if ( groupInfo && groupInfo->attributes() & + (KFileMimeTypeInfo::Addable | KFileMimeTypeInfo::Removable) ) + list.append( *it ); + } + + return list; +} + +TQStringList KFileMetaInfo::preferredGroups() const +{ + assert(isValid()); + TQStringList list = groups(); + TQStringList newlist; + TQStringList preferred = d->mimeTypeInfo->preferredGroups(); + TQStringList::Iterator pref; + + // move all keys from the preferred groups that are in our list to a new list + for ( pref = preferred.begin(); pref != preferred.end(); ++pref ) + { + TQStringList::Iterator group = list.find(*pref); + if ( group != list.end() ) + { + newlist.append( *group ); + list.remove(group); + } + } + + // now the old list only contains the non-preferred items, so we + // add the remaining ones to newlist + newlist += list; + + return newlist; +} + +TQStringList KFileMetaInfo::preferredKeys() const +{ + TQStringList newlist; + + TQStringList list = preferredGroups(); + for (TQStringList::Iterator git = list.begin(); git != list.end(); ++git) + { + newlist += d->groups[*git].preferredKeys(); + } + + return newlist; +} + +KFileMetaInfoGroup KFileMetaInfo::group(const TQString& key) const +{ + TQMapIterator<TQString,KFileMetaInfoGroup> it = d->groups.find( key ); + if ( it != d->groups.end() ) + return it.data(); + else + return KFileMetaInfoGroup(); +} + +bool KFileMetaInfo::addGroup( const TQString& name ) +{ + assert(isValid()); + if ( d->mimeTypeInfo->supportedGroups().contains(name) && + ! d->groups.contains(name) ) + { + KFileMetaInfoGroup group( name, d->mimeTypeInfo ); + + // add all the items that can't be added by the user later + const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(name); + Q_ASSERT(ginfo); + if (!ginfo) return false; + + TQStringList keys = ginfo->supportedKeys(); + for (TQStringList::Iterator it = keys.begin(); it != keys.end(); ++it) + { + const KFileMimeTypeInfo::ItemInfo* iteminfo = ginfo->itemInfo(*it); + Q_ASSERT(ginfo); + if (!iteminfo) return false; + + if ( !(iteminfo->attributes() & KFileMimeTypeInfo::Addable) && + (iteminfo->attributes() & KFileMimeTypeInfo::Modifiable)) + { + // append it now or never + group.appendItem(iteminfo->key(), TQVariant()); + } + + } + + d->groups.insert(name, group); + group.setAdded(); + return true; + } + + return false; +} + +bool KFileMetaInfo::removeGroup( const TQString& name ) +{ + TQMapIterator<TQString, KFileMetaInfoGroup> it = d->groups.find(name); + if ( (it==d->groups.end()) || + !((*it).attributes() & KFileMimeTypeInfo::Removable)) + return false; + + d->groups.remove(it); + d->removedGroups.append(name); + return true; +} + +TQStringList KFileMetaInfo::removedGroups() +{ + return d->removedGroups; +} + +const KFileMetaInfo& KFileMetaInfo::operator= (const KFileMetaInfo& info ) +{ + if (d != info.d) + { + deref(); + // first deref the old one + d = info.d; + // and now ref the new one + ref(); + } + return *this; +} + +bool KFileMetaInfo::isValid() const +{ + // We don't call makeNull here since it isn't necassery, see deref() + return d != Data::null; +} + +bool KFileMetaInfo::isEmpty() const +{ + for (TQMapIterator<TQString, KFileMetaInfoGroup> it = d->groups.begin(); + it!=d->groups.end(); ++it) + if (!(*it).isEmpty()) + return false; + return true; +} + +bool KFileMetaInfo::applyChanges() +{ + return applyChanges( path() ); +} + +bool KFileMetaInfo::applyChanges( const TQString& path ) +{ + bool doit = false; + +// kdDebug(7033) << "KFileMetaInfo::applyChanges()\n"; + + // look up if we need to write to the file + TQMapConstIterator<TQString, KFileMetaInfoGroup> it; + for (it = d->groups.begin(); it!=d->groups.end() && !doit; ++it) + { + if ( (*it).isModified() ) + doit = true; + + else + { + TQStringList keys = it.data().keys(); + for (TQStringList::Iterator it2 = keys.begin(); it2!=keys.end(); ++it2) + { + if ( (*it)[*it2].isModified() ) + { + doit = true; + break; + } + } + } + } + + if (!doit) + { + kdDebug(7033) << "Don't need to write, nothing changed\n"; + return true; + } + + KFilePlugin* p = plugin(); + if (!p) return false; + +// kdDebug(7033) << "Ok, trying to write the info\n"; + + KURL savedURL = url(); + d->url = KURL(); + d->url.setPath( path ); + + bool ret = p->writeInfo(*this); + + d->url = savedURL; + return ret; +} + +KFilePlugin * KFileMetaInfo::plugin() const +{ + assert(isValid()); + KFileMetaInfoProvider* prov = KFileMetaInfoProvider::self(); + return prov->plugin( d->mimeTypeInfo->mimeType(), d->url.protocol() ); +} + +TQString KFileMetaInfo::mimeType() const +{ + assert(isValid()); + return d->mimeTypeInfo->mimeType(); +} + +bool KFileMetaInfo::contains(const TQString& key) const +{ + TQStringList glist = groups(); + for (TQStringList::Iterator it = glist.begin(); it != glist.end(); ++it) + { + KFileMetaInfoGroup g = d->groups[*it]; + if (g.contains(key)) return true; + } + return false; +} + +bool KFileMetaInfo::containsGroup(const TQString& key) const +{ + return groups().contains(key); +} + +KFileMetaInfoItem KFileMetaInfo::item( const TQString& key) const +{ + TQStringList groups = preferredGroups(); + for (TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it) + { + KFileMetaInfoItem i = d->groups[*it][key]; + if (i.isValid()) return i; + } + return KFileMetaInfoItem(); +} + +KFileMetaInfoItem KFileMetaInfo::item(const KFileMetaInfoItem::Hint hint) const +{ + TQStringList groups = preferredGroups(); + TQStringList::ConstIterator it; + for (it = groups.begin(); it != groups.end(); ++it) + { + KFileMetaInfoItem i = d->groups[*it].item(hint); + if (i.isValid()) return i; + } + return KFileMetaInfoItem(); +} + +KFileMetaInfoItem KFileMetaInfo::saveItem( const TQString& key, + const TQString& preferredGroup, + bool createGroup ) +{ + assert(isValid()); + // try the preferred groups first + if ( !preferredGroup.isEmpty() ) { + TQMapIterator<TQString,KFileMetaInfoGroup> it = + d->groups.find( preferredGroup ); + + // try to create the preferred group, if necessary + if ( it == d->groups.end() && createGroup ) { + const KFileMimeTypeInfo::GroupInfo *groupInfo = + d->mimeTypeInfo->groupInfo( preferredGroup ); + if ( groupInfo && groupInfo->supportedKeys().contains( key ) ) { + if ( addGroup( preferredGroup ) ) + it = d->groups.find( preferredGroup ); + } + } + + if ( it != d->groups.end() ) { + KFileMetaInfoItem item = it.data().addItem( key ); + if ( item.isValid() ) + return item; + } + } + + TQStringList groups = preferredGroups(); + + KFileMetaInfoItem item; + + TQStringList::ConstIterator groupIt = groups.begin(); + for ( ; groupIt != groups.end(); ++groupIt ) + { + TQMapIterator<TQString,KFileMetaInfoGroup> it = d->groups.find( *groupIt ); + if ( it != d->groups.end() ) + { + KFileMetaInfoGroup group = it.data(); + item = findEditableItem( group, key ); + if ( item.isValid() ) + return item; + } + else // not existant -- try to create the group + { + const KFileMimeTypeInfo::GroupInfo *groupInfo = + d->mimeTypeInfo->groupInfo( *groupIt ); + if ( groupInfo && groupInfo->supportedKeys().contains( key ) ) + { + if ( addGroup( *groupIt ) ) + { + KFileMetaInfoGroup group = d->groups[*groupIt]; + KFileMetaInfoItem item = group.addItem( key ); + if ( item.isValid() ) + return item; +// else ### add when removeGroup() is implemented :) +// removeGroup( *groupIt ); // couldn't add item -> remove + } + } + } + } + + // finally check for variable items + + return item; +} + +KFileMetaInfoItem KFileMetaInfo::findEditableItem( KFileMetaInfoGroup& group, + const TQString& key ) +{ + assert(isValid()); + KFileMetaInfoItem item = group.addItem( key ); + if ( item.isValid() && item.isEditable() ) + return item; + + if ( (d->mimeTypeInfo->groupInfo( group.name() )->attributes() & KFileMimeTypeInfo::Addable) ) + return item; + + return KFileMetaInfoItem(); +} + +KFileMetaInfoGroup KFileMetaInfo::appendGroup(const TQString& name) +{ + assert(isValid()); + if ( d->mimeTypeInfo->supportedGroups().contains(name) && + ! d->groups.contains(name) ) + { + KFileMetaInfoGroup group( name, d->mimeTypeInfo ); + d->groups.insert(name, group); + return group; + } + + else { + kdWarning(7033) << "Someone's trying to add a KFileMetaInfoGroup which is not supported or already existing: " << name << endl; + return KFileMetaInfoGroup(); + } +} + +TQString KFileMetaInfo::path() const +{ + return d->url.isLocalFile() ? d->url.path() : TQString::null; +} + +KURL KFileMetaInfo::url() const +{ + return d->url; +} + +void KFileMetaInfo::ref() +{ + if (d != Data::null) d->ref(); + +} + +void KFileMetaInfo::deref() +{ + // We don't call makeNull here since it isn't necassery: + // If d is equal to null it means that null is initialized already. + // null is 0L when it hasn't been initialized and d is never 0L. + if ((d != Data::null) && d->deref()) + { +// kdDebug(7033) << "metainfo object for " << d->url.path << " is finally deleted\n"; + delete d; + d = 0; + } + +} + + +KFileMetaInfo::Data* KFileMetaInfo::Data::null = 0L; +static KStaticDeleter<KFileMetaInfo::Data> sd_KFileMetaInfoData; + +KFileMetaInfo::Data* KFileMetaInfo::Data::makeNull() +{ + if (!null) + // We deliberately do not reset "null" after it has been destroyed! + // Otherwise we will run into problems later in ~KFileMetaInfoItem + // where the d-pointer is compared against null. + null = sd_KFileMetaInfoData.setObject( new KFileMetaInfo::Data(KURL(), 0) ); + return null; +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +KFilePlugin::KFilePlugin( TQObject *parent, const char *name, + const TQStringList& /*args*/) + : TQObject( parent, name ) +{ +// kdDebug(7033) << "loaded a plugin for " << name << endl; +} + +KFilePlugin::~KFilePlugin() +{ +// kdDebug(7033) << "unloaded a plugin for " << name() << endl; +} + +KFileMimeTypeInfo * KFilePlugin::addMimeTypeInfo( const TQString& mimeType ) +{ + return KFileMetaInfoProvider::self()->addMimeTypeInfo( mimeType ); +} + +void KFilePlugin::virtual_hook( int, void* ) +{ /*BASE::virtual_hook( id, data );*/ } + + +KFileMimeTypeInfo::GroupInfo* KFilePlugin::addGroupInfo(KFileMimeTypeInfo* info, + const TQString& key, const TQString& translatedKey) const +{ + return info->addGroupInfo(key, translatedKey); +} + +void KFilePlugin::setAttributes(KFileMimeTypeInfo::GroupInfo* gi, uint attr) const +{ + gi->m_attr = attr; +} + +void KFilePlugin::addVariableInfo(KFileMimeTypeInfo::GroupInfo* gi, + TQVariant::Type type, uint attr) const +{ + gi->addVariableInfo(type, attr); +} + +KFileMimeTypeInfo::ItemInfo* KFilePlugin::addItemInfo(KFileMimeTypeInfo::GroupInfo* gi, + const TQString& key, + const TQString& translatedKey, + TQVariant::Type type) +{ + return gi->addItemInfo(key, translatedKey, type); +} + +void KFilePlugin::setAttributes(KFileMimeTypeInfo::ItemInfo* item, uint attr) +{ + item->m_attr = attr; +} + +void KFilePlugin::setHint(KFileMimeTypeInfo::ItemInfo* item, uint hint) +{ + item->m_hint = hint; +} + +void KFilePlugin::setUnit(KFileMimeTypeInfo::ItemInfo* item, uint unit) +{ + item->m_unit = unit; + // set prefix and suffix + switch (unit) + { + case KFileMimeTypeInfo::Seconds: + item->m_suffix = i18n("s"); break; + + case KFileMimeTypeInfo::MilliSeconds: + item->m_suffix = i18n("ms"); break; + + case KFileMimeTypeInfo::BitsPerSecond: + item->m_suffix = i18n("bps"); break; + + case KFileMimeTypeInfo::Pixels: + item->m_suffix = i18n("pixels"); break; + + case KFileMimeTypeInfo::Inches: + item->m_suffix = i18n("in"); break; + + case KFileMimeTypeInfo::Centimeters: + item->m_suffix = i18n("cm"); break; + + case KFileMimeTypeInfo::Bytes: + item->m_suffix = i18n("B"); break; + + case KFileMimeTypeInfo::KiloBytes: + item->m_suffix = i18n("KB"); break; + + case KFileMimeTypeInfo::FramesPerSecond: + item->m_suffix = i18n("fps"); break; + + case KFileMimeTypeInfo::DotsPerInch: + item->m_suffix = i18n("dpi"); break; + + case KFileMimeTypeInfo::BitsPerPixel: + item->m_suffix = i18n("bpp"); break; + + case KFileMimeTypeInfo::Hertz: + item->m_suffix = i18n("Hz"); break; + + case KFileMimeTypeInfo::Millimeters: + item->m_suffix = i18n("mm"); + } +} + +void KFilePlugin::setPrefix(KFileMimeTypeInfo::ItemInfo* item, const TQString& prefix) +{ + item->m_prefix = prefix; +} + +void KFilePlugin::setSuffix(KFileMimeTypeInfo::ItemInfo* item, const TQString& suffix) +{ + item->m_suffix = suffix; +} + +KFileMetaInfoGroup KFilePlugin::appendGroup(KFileMetaInfo& info, const TQString& key) +{ + return info.appendGroup(key); +} + +void KFilePlugin::appendItem(KFileMetaInfoGroup& group, const TQString& key, TQVariant value) +{ + group.appendItem(key, value); +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + +KFileMetaInfoProvider * KFileMetaInfoProvider::s_self; +static KStaticDeleter<KFileMetaInfoProvider> sd; + +KFileMetaInfoProvider * KFileMetaInfoProvider::self() +{ + if ( !s_self ) + s_self = sd.setObject( s_self, new KFileMetaInfoProvider() ); + + return s_self; +} + +KFileMetaInfoProvider::KFileMetaInfoProvider() +{ + m_plugins.setAutoDelete( true ); +} + +KFileMetaInfoProvider::~KFileMetaInfoProvider() +{ + m_plugins.clear(); + sd.setObject( 0 ); +} + +KFilePlugin* KFileMetaInfoProvider::loadPlugin( const TQString& mimeType, const TQString& protocol ) +{ + //kdDebug() << "loadPlugin: mimeType=" << mimeType << " protocol=" << protocol << endl; + // Currently the idea is: either the mimetype is set or the protocol, but not both. + // We need PNG fileinfo, and trash: fileinfo, but not "PNG in the trash". + TQString queryMimeType, query; + if ( !mimeType.isEmpty() ) { + query = "(not exist [X-TDE-Protocol])"; + queryMimeType = mimeType; + } else { + query = TQString::fromLatin1( "[X-TDE-Protocol] == '%1'" ).arg(protocol); + // querying for a protocol: we have no mimetype, so we need to use KFilePlugin as one + queryMimeType = "KFilePlugin"; + // hopefully using KFilePlugin as genericMimeType too isn't a problem + } + const KTrader::OfferList offers = KTrader::self()->query( queryMimeType, "KFilePlugin", query, TQString::null ); + if ( offers.isEmpty() ) + return 0; + KService::Ptr service = *(offers.begin()); + Q_ASSERT( service && service->isValid() ); + if ( !service || !service->isValid() ) + return 0; + + KFilePlugin* plugin = KParts::ComponentFactory::createInstanceFromService<KFilePlugin> + ( service, TQT_TQOBJECT(this), mimeType.local8Bit() ); + if (!plugin) + kdWarning(7033) << "error loading the plugin from " << service->desktopEntryPath() << endl; + + return plugin; +} + +KFilePlugin* KFileMetaInfoProvider::loadAndRegisterPlugin( const TQString& mimeType, const TQString& protocol ) +{ + Q_ASSERT( m_pendingMimetypeInfos.isEmpty() ); + m_pendingMimetypeInfos.clear(); + + KFilePlugin* plugin = loadPlugin( mimeType, protocol ); + if ( !plugin ) { + // No plugin found. Remember that, to save time. + m_plugins.insert( protocol.isEmpty() ? mimeType : protocol, new CachedPluginInfo ); + return 0; + } + + if ( !protocol.isEmpty() ) { + // Protocol-metainfo: only one entry + Q_ASSERT( m_pendingMimetypeInfos.count() == 1 ); + KFileMimeTypeInfo* info = m_pendingMimetypeInfos[ protocol ]; + Q_ASSERT( info ); + m_plugins.insert( protocol, new CachedPluginInfo( plugin, info, true ) ); + } else { + // Mimetype-metainfo: the plugin can register itself for multiple mimetypes, remember them all + bool first = true; + TQDictIterator<KFileMimeTypeInfo> it( m_pendingMimetypeInfos ); + for( ; it.current(); ++it ) { + KFileMimeTypeInfo* info = it.current(); + m_plugins.insert( it.currentKey(), new CachedPluginInfo( plugin, info, first ) ); + first = false; + } + // Hopefully the above includes the mimetype we asked for! + if ( m_pendingMimetypeInfos.find( mimeType ) == 0 ) + kdWarning(7033) << plugin->className() << " was created for " << mimeType << " but doesn't call addMimeTypeInfo for it!" << endl; + } + m_pendingMimetypeInfos.clear(); + return plugin; +} + +KFilePlugin * KFileMetaInfoProvider::plugin(const TQString& mimeType) +{ + return plugin( mimeType, TQString::null ); +} + +KFilePlugin * KFileMetaInfoProvider::plugin(const TQString& mimeType, const TQString& protocol) +{ + //kdDebug(7033) << "plugin() : looking for plugin for protocol=" << protocol << " mimeType=" << mimeType << endl; + + if ( !protocol.isEmpty() ) { + CachedPluginInfo *cache = m_plugins.find( protocol ); + if ( cache && cache->plugin ) { + return cache->plugin; + } + if ( !cache ) { + KFilePlugin* plugin = loadAndRegisterPlugin( TQString::null, protocol ); + if ( plugin ) + return plugin; + } + } + + CachedPluginInfo *cache = m_plugins.find( mimeType ); + if ( cache ) { + return cache->plugin; + } + + KFilePlugin* plugin = loadAndRegisterPlugin( mimeType, TQString::null ); + +#if 0 + kdDebug(7033) << "currently loaded plugins:\n"; + + TQDictIterator<CachedPluginInfo> it( m_plugins ); + for( ; it.current(); ++it ) { + CachedPluginInfo* cache = it.current(); + kdDebug(7033) + << it.currentKey() // mimetype or protocol + << " : " << (cache->plugin ? cache->plugin->className() : "(no plugin)") << endl; // plugin + // TODO print cache->mimeTypeInfo + } +#endif + + return plugin; +} + +TQStringList KFileMetaInfoProvider::preferredKeys( const TQString& mimeType ) const +{ + KService::Ptr service = + KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); + + if ( !service || !service->isValid() ) + { +// kdDebug(7033) << "no valid service found\n"; + return TQStringList(); + } + return service->property("PreferredItems").toStringList(); +} + +TQStringList KFileMetaInfoProvider::preferredGroups( const TQString& mimeType ) const +{ + KService::Ptr service = + KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); + + if ( !service || !service->isValid() ) + { +// kdDebug(7033) << "no valid service found\n"; + return TQStringList(); + } + return service->property("PreferredGroups").toStringList(); +} + +const KFileMimeTypeInfo * KFileMetaInfoProvider::mimeTypeInfo( const TQString& mimeType ) +{ + return mimeTypeInfo( mimeType, TQString::null ); +} + +const KFileMimeTypeInfo * KFileMetaInfoProvider::mimeTypeInfo( const TQString& mimeType, const TQString& protocol ) +{ + //kdDebug(7033) << "mimeTypeInfo() : looking for plugin for protocol=" << protocol << " mimeType=" << mimeType << endl; + if ( !protocol.isEmpty() ) { + CachedPluginInfo *cache = m_plugins.find( protocol ); + if ( cache && cache->mimeTypeInfo ) { + return cache->mimeTypeInfo; + } + + if ( !cache ) { + loadAndRegisterPlugin( TQString::null, protocol ); + cache = m_plugins.find( protocol ); + if ( cache && cache->mimeTypeInfo ) { + return cache->mimeTypeInfo; + } + } + } + + CachedPluginInfo *cache = m_plugins.find( mimeType ); + if ( cache ) { + return cache->mimeTypeInfo; + } + + loadAndRegisterPlugin( mimeType, TQString::null ); + cache = m_plugins.find( mimeType ); + if ( cache ) { + return cache->mimeTypeInfo; + } + return 0; +} + +KFileMimeTypeInfo * KFileMetaInfoProvider::addMimeTypeInfo( + const TQString& mimeType ) +{ + + KFileMimeTypeInfo *info = m_pendingMimetypeInfos.find( mimeType ); + Q_ASSERT( !info ); + if ( !info ) + { + info = new KFileMimeTypeInfo( mimeType ); + m_pendingMimetypeInfos.insert( mimeType, info ); + } + + info->m_preferredKeys = preferredKeys( mimeType ); + info->m_preferredGroups = preferredGroups( mimeType ); + + return info; +} + +TQStringList KFileMetaInfoProvider::supportedMimeTypes() const +{ + TQStringList allMimeTypes; + TQString tdefilePlugin = "KFilePlugin"; + + KTrader::OfferList offers = KTrader::self()->query( "KFilePlugin" ); + KTrader::OfferListIterator it = offers.begin(); + for ( ; it != offers.end(); ++it ) + { + const TQStringList mimeTypes = (*it)->serviceTypes(); + TQStringList::ConstIterator it2 = mimeTypes.begin(); + for ( ; it2 != mimeTypes.end(); ++it2 ) + if ( allMimeTypes.find( *it2 ) == allMimeTypes.end() && + *it2 != tdefilePlugin ) // also in serviceTypes() + allMimeTypes.append( *it2 ); + } + + return allMimeTypes; +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + +// shared data of a KFileMetaInfoGroup +class KFileMetaInfoGroup::Data : public TQShared +{ +public: + Data(const TQString& _name) + : TQShared(), + name(_name), + mimeTypeInfo(0L), + dirty( false ), + added( false ) + {} + + // we use this one for the streaming operators + Data() : mimeTypeInfo(0L) {} + ~Data() { + if ( this == null ) + delete mimeTypeInfo; + }; + + TQString name; + TQMap<TQString, KFileMetaInfoItem> items; + const KFileMimeTypeInfo* mimeTypeInfo; + TQStringList removedItems; + bool dirty :1; + bool added :1; + + static Data* null; + static Data* makeNull(); + +}; + +KFileMetaInfoGroup::KFileMetaInfoGroup( const TQString& name, + const KFileMimeTypeInfo* info ) + : d(new Data( name ) ) +{ + d->mimeTypeInfo = info; +} + +KFileMetaInfoGroup::KFileMetaInfoGroup( const KFileMetaInfoGroup& original ) +{ + // operator= does everything that's necessary + d = Data::makeNull(); + *this = original; +} + +KFileMetaInfoGroup::KFileMetaInfoGroup() +{ + d = Data::makeNull(); +} + +KFileMetaInfoGroup::~KFileMetaInfoGroup() +{ + deref(); +} + +const KFileMetaInfoGroup& KFileMetaInfoGroup::operator= (const KFileMetaInfoGroup& info ) +{ + if (d != info.d) + { + deref(); + // first deref the old one + d = info.d; + // and now ref the new one + ref(); + } + return *this; +} + +bool KFileMetaInfoGroup::isValid() const +{ + // We don't call makeNull here since it isn't necassery, see deref() + return d != Data::null; +} + +bool KFileMetaInfoGroup::isEmpty() const +{ + return d->items.isEmpty(); +} + +TQStringList KFileMetaInfoGroup::preferredKeys() const +{ + assert(isValid()); + TQStringList list = keys(); + TQStringList newlist; + TQStringList preferredKeys = d->mimeTypeInfo->preferredKeys(); + TQStringList::Iterator pref; + TQStringList::Iterator begin = preferredKeys.begin(); + TQStringList::Iterator end = preferredKeys.end(); + + // move all keys from the preferred keys that are in our list to a new list + for ( pref = begin; pref!=end; ++pref ) + { + TQStringList::Iterator item = list.find(*pref); + if ( item != list.end() ) + { + newlist.append( *item ); + list.remove(item); + } + } + + // now the old list only contains the non-preferred items, so we + // add the remaining ones to newlist + newlist += list; + + return newlist; +} + +TQStringList KFileMetaInfoGroup::keys() const +{ + if (d == Data::makeNull()) + kdWarning(7033) << "attempt to get the keys of " + "an invalid metainfo group"; + + TQStringList list; + + // make a TQStringList with all available keys + TQMapConstIterator<TQString, KFileMetaInfoItem> it; + for (it = d->items.begin(); it!=d->items.end(); ++it) + { + list.append(it.data().key()); +// kdDebug(7033) << "Item " << it.data().key() << endl; + } + return list; +} + +TQString KFileMetaInfoGroup::translatedName() const +{ + assert(isValid()); + return d->mimeTypeInfo->groupInfo(d->name)->translatedName(); +} + +TQStringList KFileMetaInfoGroup::supportedKeys() const +{ + assert(isValid()); + return d->mimeTypeInfo->groupInfo(d->name)->supportedKeys(); +} + +bool KFileMetaInfoGroup::supportsVariableKeys() const +{ + assert(isValid()); + return d->mimeTypeInfo->groupInfo(d->name)->supportsVariableKeys(); +} + +bool KFileMetaInfoGroup::contains( const TQString& key ) const +{ + return d->items.contains(key); +} + +KFileMetaInfoItem KFileMetaInfoGroup::item( const TQString& key) const +{ + TQMapIterator<TQString,KFileMetaInfoItem> it = d->items.find( key ); + if ( it != d->items.end() ) + return it.data(); + + return KFileMetaInfoItem(); +} + +KFileMetaInfoItem KFileMetaInfoGroup::item(uint hint) const +{ + TQMapIterator<TQString, KFileMetaInfoItem> it; + + for (it = d->items.begin(); it!=d->items.end(); ++it) + if (it.data().hint() == hint) + return it.data(); + + return KFileMetaInfoItem(); +} + +TQString KFileMetaInfoGroup::name() const +{ + return d->name; +} + +uint KFileMetaInfoGroup::attributes() const +{ + assert(isValid()); + return d->mimeTypeInfo->groupInfo(d->name)->attributes(); +} + +void KFileMetaInfoGroup::setAdded() +{ + d->added = true; +} + +bool KFileMetaInfoGroup::isModified() const +{ + return d->dirty; +} + +void KFileMetaInfoGroup::ref() +{ + if (d != Data::null) d->ref(); + +} + +void KFileMetaInfoGroup::deref() +{ + // We don't call makeNull here since it isn't necassery: + // If d is equal to null it means that null is initialized already. + // null is 0L when it hasn't been initialized and d is never 0L. + if ((d != Data::null) && d->deref()) + { +// kdDebug(7033) << "metainfo group " << d->name +// << " is finally deleted\n"; + delete d; + d = 0; + } + +} + +KFileMetaInfoItem KFileMetaInfoGroup::addItem( const TQString& key ) +{ + assert(isValid()); + TQMapIterator<TQString,KFileMetaInfoItem> it = d->items.find( key ); + if ( it != d->items.end() ) + return it.data(); + + const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(d->name); + + if ( !ginfo ) { + Q_ASSERT( ginfo ); + return KFileMetaInfoItem(); + } + + const KFileMimeTypeInfo::ItemInfo* info = ginfo->itemInfo(key); + + if ( !info ) { + Q_ASSERT( info ); + return KFileMetaInfoItem(); + } + + KFileMetaInfoItem item; + + if (info->isVariableItem()) + item = KFileMetaInfoItem(ginfo->variableItemInfo(), key, TQVariant()); + else + item = KFileMetaInfoItem(info, key, TQVariant()); + + d->items.insert(key, item); + item.setAdded(); // mark as added + d->dirty = true; // mark ourself as dirty, too + return item; +} + +bool KFileMetaInfoGroup::removeItem( const TQString& key ) +{ + if (!isValid()) + { + kdDebug(7033) << "trying to remove an item from an invalid group\n"; + return false; + } + + TQMapIterator<TQString, KFileMetaInfoItem> it = d->items.find(key); + if ( it==d->items.end() ) + { + kdDebug(7033) << "trying to remove the non existant item " << key << "\n"; + return false; + } + + if (!((*it).attributes() & KFileMimeTypeInfo::Removable)) + { + kdDebug(7033) << "trying to remove a non removable item\n"; + return false; + } + + (*it).setRemoved(); + d->items.remove(it); + d->removedItems.append(key); + d->dirty = true; + return true; +} + +TQStringList KFileMetaInfoGroup::removedItems() +{ + return d->removedItems; +} + +KFileMetaInfoItem KFileMetaInfoGroup::appendItem(const TQString& key, + const TQVariant& value) +{ + //KDE4 enforce (value.type() == d->mimeTypeInfo->type()) + assert(isValid()); + const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(d->name); + if ( !ginfo ) { + kdWarning() << "Trying to append a Metadata item for a non-existant group:" << d->name << endl; + return KFileMetaInfoItem(); + } + const KFileMimeTypeInfo::ItemInfo* info = ginfo->itemInfo(key); + if ( !info ) { + kdWarning() << "Trying to append a Metadata item for an unknown key (no ItemInfo): " << key << endl; + return KFileMetaInfoItem(); + } + + KFileMetaInfoItem item; + + if (info->key().isNull()) + item = KFileMetaInfoItem(ginfo->variableItemInfo(), key, value); + else + item = KFileMetaInfoItem(info, key, value); + + kdDebug(7033) << "KFileMetaInfogroup inserting a " << key << endl; + + d->items.insert(key, item); + return item; +} + +KFileMetaInfoGroup::Data* KFileMetaInfoGroup::Data::null = 0L; +static KStaticDeleter<KFileMetaInfoGroup::Data> sd_KFileMetaInfoGroupData; + +KFileMetaInfoGroup::Data* KFileMetaInfoGroup::Data::makeNull() +{ + if (!null) + { + // We deliberately do not reset "null" after it has been destroyed! + // Otherwise we will run into problems later in ~KFileMetaInfoItem + // where the d-pointer is compared against null. + null = new Data(TQString::null); + null->mimeTypeInfo = new KFileMimeTypeInfo(); + sd_KFileMetaInfoGroupData.setObject( null ); + } + return null; +} + + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +KFileMimeTypeInfo::KFileMimeTypeInfo( const TQString& mimeType ) + : m_mimeType( mimeType ) +{ + m_groups.setAutoDelete( true ); +} + +KFileMimeTypeInfo::~KFileMimeTypeInfo() +{ +} + +const KFileMimeTypeInfo::GroupInfo * KFileMimeTypeInfo::groupInfo( const TQString& group ) const +{ + return m_groups.find( group ); +} + +KFileMimeTypeInfo::GroupInfo * KFileMimeTypeInfo::addGroupInfo( + const TQString& name, const TQString& translatedName ) +{ + GroupInfo* group = new GroupInfo( name, translatedName ); + m_groups.insert(name, group); + return group; +} + +TQStringList KFileMimeTypeInfo::supportedGroups() const +{ + TQStringList list; + TQDictIterator<GroupInfo> it( m_groups ); + for ( ; it.current(); ++it ) + list.append( it.current()->name() ); + + return list; +} + +TQStringList KFileMimeTypeInfo::translatedGroups() const +{ + TQStringList list; + TQDictIterator<GroupInfo> it( m_groups ); + for ( ; it.current(); ++it ) + list.append( it.current()->translatedName() ); + + return list; +} + +TQStringList KFileMimeTypeInfo::supportedKeys() const +{ + // not really efficient, but not those are not large lists, probably. + // maybe cache the result? + TQStringList keys; + TQStringList::ConstIterator lit; + TQDictIterator<GroupInfo> it( m_groups ); + for ( ; it.current(); ++it ) { // need to nuke dupes + TQStringList list = it.current()->supportedKeys(); + for ( lit = list.begin(); lit != list.end(); ++lit ) { + if ( keys.find( *lit ) == keys.end() ) + keys.append( *lit ); + } + } + + return keys; +} + +TQValidator * KFileMimeTypeInfo::createValidator(const TQString& group, + const TQString& key, + TQObject *parent, + const char *name) const +{ + KFilePlugin* plugin = KFileMetaInfoProvider::self()->plugin(m_mimeType); + if (plugin) return plugin->createValidator(mimeType(), group, key, + parent, name); + return 0; +} + + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +KFileMimeTypeInfo::GroupInfo::GroupInfo( const TQString& name, + const TQString& translatedName ) + : m_name( name ), + m_translatedName( translatedName ), + m_attr( 0 ), + m_variableItemInfo( 0 ) + +{ + m_itemDict.setAutoDelete( true ); +} + +KFileMimeTypeInfo::GroupInfo::~GroupInfo() +{ + delete m_variableItemInfo; +} + +const KFileMimeTypeInfo::ItemInfo * KFileMimeTypeInfo::GroupInfo::itemInfo( const TQString& key ) const +{ + ItemInfo* item = m_itemDict.find( key ); + + // if we the item isn't found and variable keys are supported, we need to + // return the default variable key iteminfo. + if (!item && m_variableItemInfo) + { + return m_variableItemInfo; + } + return item; +} + +KFileMimeTypeInfo::ItemInfo* KFileMimeTypeInfo::GroupInfo::addItemInfo( + const TQString& key, const TQString& translatedKey, + TQVariant::Type type) +{ +// kdDebug(7034) << key << "(" << translatedKey << ") -> " << TQVariant::typeToName(type) << endl; + + ItemInfo* item = new ItemInfo(key, translatedKey, type); + m_supportedKeys.append(key); + m_itemDict.insert(key, item); + return item; +} + + +void KFileMimeTypeInfo::GroupInfo::addVariableInfo( TQVariant::Type type, + uint attr ) +{ + // just make sure that it's not already there + delete m_variableItemInfo; + m_variableItemInfo = new ItemInfo(TQString::null, TQString::null, type); + m_variableItemInfo->m_attr = attr; +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + +TQString KFileMimeTypeInfo::ItemInfo::string(const TQVariant& value, bool mangle) const +{ + TQString s; + + switch (value.type()) + { + case TQVariant::Invalid : + return "---"; + + case TQVariant::Bool : + s = value.toBool() ? i18n("Yes") : i18n("No"); + break; + + case TQVariant::Int : + if (unit() == KFileMimeTypeInfo::Seconds) + { + int seconds = value.toInt() % 60; + int minutes = value.toInt() / 60 % 60; + int hours = value.toInt() / 3600; + s = hours ? TQString().sprintf("%d:%02d:%02d",hours, minutes, seconds) + : TQString().sprintf("%02d:%02d", minutes, seconds); + return s; // no suffix wanted + } + else if (unit() == KFileMimeTypeInfo::Bytes) + { + // convertSize already adds the correct suffix + return TDEIO::convertSize(value.toInt()); + } + else if (unit() == KFileMimeTypeInfo::KiloBytes) + { + // convertSizeFromKB already adds the correct suffix + return TDEIO::convertSizeFromKB(value.toInt()); + } + else + s = TDEGlobal::locale()->formatNumber( value.toInt() , 0); + break; + + case TQVariant::LongLong : + s = TDEGlobal::locale()->formatNumber( value.toLongLong(), 0 ); + break; + + case TQVariant::ULongLong : + if ( unit() == KFileMimeTypeInfo::Bytes ) + return TDEIO::convertSize( value.toULongLong() ); + else if ( unit() == KFileMimeTypeInfo::KiloBytes ) + return TDEIO::convertSizeFromKB( value.toULongLong() ); + else + s = TDEGlobal::locale()->formatNumber( value.toULongLong(), 0 ); + break; + + case TQVariant::UInt : + s = TDEGlobal::locale()->formatNumber( value.toUInt() , 0); + break; + + case TQVariant::Double : + s = TDEGlobal::locale()->formatNumber( value.toDouble(), 3); + break; + + case TQVariant::Date : + s = TDEGlobal::locale()->formatDate( value.toDate(), true ); + break; + + case TQVariant::Time : + s = TDEGlobal::locale()->formatTime( value.toTime(), true ); + break; + + case TQVariant::DateTime : + s = TDEGlobal::locale()->formatDateTime( value.toDateTime(), + true, true ); + break; + + case TQVariant::Size : + s = TQString("%1 x %2").arg(value.toSize().width()) + .arg(value.toSize().height()); + break; + + case TQVariant::Point : + s = TQString("%1/%2").arg(value.toSize().width()) + .arg(value.toSize().height()); + break; + + default: + s = value.toString(); + } + + if (mangle && !s.isNull()) + { + s.prepend(prefix()); + s.append(" " + suffix()); + } + return s; +} + + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + + +// stream operators + +/* serialization of a KFileMetaInfoItem: + first a bool that says if the items is valid, and if yes, + all the elements of the Data +*/ +TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& item ) +{ + + KFileMetaInfoItem::Data* d = item.d; + + // if the object is invalid, put only a char in the stream + bool isValid = item.isValid(); + s << isValid; + // ### what do about mimetypeInfo ? + if (isValid) + s << d->key + << d->value + << d->dirty + << d->added + << d->removed; + + return s; +} + + +TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& item ) +{ + bool isValid; + s >> isValid; + + if (!isValid) + { + item = KFileMetaInfoItem(); + return s; + } + + // we need a new object for our data + item.deref(); + item.d = new KFileMetaInfoItem::Data(); + + // ### what do about mimetypeInfo ? + bool dirty, added, removed; + s >> item.d->key + >> item.d->value + >> dirty + >> added + >> removed; + item.d->dirty = dirty; + item.d->added = added; + item.d->removed = removed; + + return s; +} + + +// serialization of a KFileMetaInfoGroup +// we serialize the name of the mimetype here instead of the mimetype info +// on the other side, we can simply use this to ask the provider for the info +TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& group ) +{ + KFileMetaInfoGroup::Data* d = group.d; + + // if the object is invalid, put only a byte in the stream + bool isValid = group.isValid(); + + s << isValid; + if (isValid) + { + s << d->name + << d->items + << d->mimeTypeInfo->mimeType(); + } + return s; +} + +TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& group ) +{ + TQString mimeType; + bool isValid; + s >> isValid; + + // if it's invalid, there is not much to do + if (!isValid) + { + group = KFileMetaInfoGroup(); + return s; + } + + // we need a new object for our data + group.deref(); + group.d = new KFileMetaInfoGroup::Data(); + + s >> group.d->name + >> group.d->items + >> mimeType; + + group.d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mimeType); + + // we need to set the item info for the items here + TQMapIterator<TQString, KFileMetaInfoItem> it = group.d->items.begin(); + for ( ; it != group.d->items.end(); ++it) + { + (*it).d->mimeTypeInfo = group.d->mimeTypeInfo->groupInfo(group.d->name) + ->itemInfo((*it).key()); + } + + return s; +} + +// serialization of a KFileMetaInfo object +// we serialize the name of the mimetype here instead of the mimetype info +// on the other side, we can simply use this to ask the provider for the info +TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& info ) +{ + KFileMetaInfo::Data* d = info.d; + + // if the object is invalid, put only a byte that tells this + bool isValid = info.isValid(); + + s << isValid; + if (isValid) + { + s << d->url + << d->what + << d->groups + << d->mimeTypeInfo->mimeType(); + } + return s; +} + +TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& info ) +{ + TQString mimeType; + bool isValid; + s >> isValid; + + // if it's invalid, there is not much to do + if (!isValid) + { + info = KFileMetaInfo(); + return s; + } + + // we need a new object for our data + info.deref(); + info.d = new KFileMetaInfo::Data(); + + s >> info.d->url + >> info.d->what + >> info.d->groups + >> mimeType; + info.d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mimeType); + + return s; +} + +#include "tdefilemetainfo.moc" |