You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kio/kio/kfilemetainfo.h

1739 lines
57 KiB

/*
* This file is part of the KDE libraries
* Copyright (C) 2001-2002 Rolf Magnus <ramagnus@kde.org>
* Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org>
*
* 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.
*/
#ifndef KILEMETAINFO_H
#define KILEMETAINFO_H
/* Hack for HPUX: Namespace pollution
m_unit is a define in <sys/sysmacros.h> */
#define m_unit outouftheway_m_unit
#include <tqdict.h>
#include <tqvariant.h>
#include <tqobject.h>
#include <tqstring.h>
#include <kurl.h>
#undef m_unit
class TQValidator;
class KFilePlugin;
class KFileMetaInfoGroup;
/**
* @brief Represents the capabilities of a KFilePlugin for a given mimetype
*
* This class provides information about the capabilities that a
* KFilePlugin for a given mimetype has. It includes a list of metainfo
* groups and items together with their type, a prefix, suffix and some other
* information about how to use, display or edit the items.
*
* @author Rolf Magnus
* @author Carsten Pfeiffer
*/
class KIO_EXPORT KFileMimeTypeInfo
{
// the plugin needs to be a friend because it puts the data into the object,
// and it should be the only one allowed to do this.
friend class KFilePlugin;
friend class KFileMetaInfoProvider;
public:
KFileMimeTypeInfo() {}
/**
* This enum is used to specify some attributes that an item can have,
* which fit neither in the Hint nor in the Unit enum.
*/
enum Attributes
{
Addable = 1, ///< The item or group can be added by a user
Removable = 2, ///< It can be removed
Modifiable = 4, ///< The value can be edited (no meaning for a group)
Cumulative = 8, /**< If an application wants to display information
for more than one file, it may add up the values
for this item (e.g. play time of an mp3 file) */
Cummulative = Cumulative, ///< @deprecated Use Cumulative instead
Averaged = 16, /**< Similar to Cumulative, but the average should
be calculated instead of the sum */
MultiLine = 32, /**< This attribute says that a string item is likely
to be more than one line long, so for editing, a
widget capable for multline text should be used
@since 3.1 */
SqueezeText = 64 /**< If the text for this item is very long, it
should be squeezed to the size of the widget
where it's displayed
@since 3.1 */
};
/**
* This enum is mainly for items that have a special meaning for some
* applications.
*/
enum Hint {
NoHint = 0, ///< No hint
Name = 1, ///< The name or title of the document
Author = 2, ///< The one who created the contents of it
Description = 3, ///< Description Some information about the document
Width = 4, ///< The width in pixels
Height = 5, ///< The height in pixels
Size = 6, ///< The size in pixels (width and height)
Bitrate = 7, ///< For media files
Length = 8, ///< The length of the file, also for media files
Hidden = 9, ///< The item is usually not shown to the user
Thumbnail = 10 ///< The item is a thumbnail picture of the file
};
/**
* This enum exists so that you can specify units for items, which you
* can usually use for integer items, so an application knows how to
* display it (e.g. a time in seconds in a hh:mm:ss form). You can either
* use one of those units, or if you don't find one that fits, you can
* add it yourself using a prefix and/or suffix.
*/
enum Unit {
NoUnit = 0, ///< None of the listed units
Seconds = 1, ///< The item represents a time in seconds
MilliSeconds = 2, ///< The item represents a time in milliseconds
BitsPerSecond = 3, ///< A bit rate
Pixels = 4, ///< For image dimensions and similar
Inches = 5, ///< Sizes
Centimeters = 6, ///< Sizes
Bytes = 7, ///< Some data/file size in bytes
FramesPerSecond = 8, ///< A frame rate @since 3.1
DotsPerInch = 9, ///< Resolution in DPI @since 3.1
BitsPerPixel = 10, ///< A bit depth @since 3.1
Hertz = 11, ///< Sample rates and similar @since 3.1
KiloBytes = 12, ///< Some data/file size in kilobytes @since 3.1
Millimeters = 13 ///< Sizes @since 3.3
};
class ItemInfo;
/**
* @brief Information about a meta information group
*
* This is the class for one group of items of a KFileMimeTypeInfo.
* It contains, among other things, the information about the group's name
* and a list of supported items.
*/
class KIO_EXPORT GroupInfo
{
friend class KFilePlugin;
friend class KFileMimeTypeInfo;
public:
/**
* Use this method to get a list of keys in the specified group that
* the plugin knows about. No variable keys.
* For a group that doesn't support variable keys, all keys that this
* group may have are returned. For a group that does support them, the
* non-variable ones are returned. See KFileMetaInfo about variable
* keys
*
* @return the list of keys supported for this mimetype
**/
TQStringList supportedKeys() const
{
return m_supportedKeys;
}
/**
* Use this method to get the name of the group. This string doesn't
* depend on the user's locale settings
*
* @return the group name
*/
const TQString& name() const
{
return m_name;
}
/**
* Use this method to get the string to display to the user as group
* name. This may be different to name() and it returns the
* name in the user's language
*
* @return the translated group name
*/
const TQString& translatedName() const
{
return m_translatedName;
}
/**
* A group object can contain several item objects (of which you can
* get the names with supportedKeys() . With this method, you can
* get one of those item objects. See ItemInfo
*
* @return a pointer to the item info. Don't delete this object!
*/
const ItemInfo * itemInfo( const TQString& key ) const;
/**
* Get the attributes of this group (see Attributes)
*
* @return the attributes
*/
uint attributes() const
{
return m_attr;
}
/**
* @return true if this group supports adding or removing arbitrary
* keys, false if not.
**/
bool supportsVariableKeys() const
{
return m_variableItemInfo;
}
/**
* If the group supports variable keys, you can query their item
* info with this method. The main reason for this is that you can
* get the type and attributes of variable keys.
*
* @return a pointer to the item info. Don't delete this object!
**/
const ItemInfo* variableItemInfo( ) const
{
return m_variableItemInfo;
}
/** @internal */
~GroupInfo();
private:
/** @internal */
GroupInfo( const TQString& name, const TQString& translatedName);
/** @internal */
KFileMimeTypeInfo::ItemInfo* addItemInfo( const TQString& key,
const TQString& translatedKey,
TQVariant::Type type);
/** @internal */
void addVariableInfo( TQVariant::Type type, uint attr );
TQString m_name;
TQString m_translatedName;
TQStringList m_supportedKeys;
uint m_attr;
ItemInfo* m_variableItemInfo;
TQDict<ItemInfo> m_itemDict;
};
/**
* This is the class for one item of a KFileMimeTypeInfo.
* It contains every information about a KFileMetaInfoItem that this
* item has in common for each file of a specific mimetype.
**/
class KIO_EXPORT ItemInfo
{
friend class KFilePlugin;
friend class GroupInfo;
public:
/** @internal */
ItemInfo() {} // ### should be private?
/**
*
* This method returns a translated prefix to be displayed before the
* value. Think e.g. of the $ in $30
*
* @return the prefix
*/
const TQString& prefix() const
{
return m_prefix;
}
/**
* This method returns a translated suffix to be displayed after the
* value. Think of the kbps in 128kbps
*
* @return the prefix
*/
const TQString& suffix() const
{
return m_suffix;
}
/**
* The items for a file are stored as a TQVariant and this method
* can be used to get the data type of this item.
*
* @return the TQVariant type
*/
TQVariant::Type type() const
{
return m_type;
}
/**
* Returns the name of the item.
* @return the name of the item
*/
const TQString& key() const
{
return m_key;
}
/**
* Returns a string for the specified @p value, if possible. If not,
* TQString::null is returned. This can be used by programs if they want
* to display a sum or an average of some item for a list of files.
*
* @param value the value to convert
* @param mangle if true, the string will already contain prefix and
* suffix
* @return the converted string, or TQString::null if not possible
* @since 3.1
*/
TQString string( const TQVariant& value, bool mangle = true ) const;
/**
* Is this item the variable item?
*
* @return true if it is, false if not
*/
bool isVariableItem() const
{
// every valid item is supposed to have a non-null key
return key().isNull();
}
/**
* Returns a translation of the key for displaying to the user. If the
* plugin provides translation to the key, it's also in the user's
* language.
* @return the translated key
*/
const TQString& translatedKey() const
{
return m_translatedKey;
}
/**
* Return the attributes of the item. See
* KFileMimeTypeInfo::Attributes.
* @return the attributes
*/
uint attributes() const
{
return m_attr;
}
/**
* Return the hints for the item. See
* KFileMimeTypeInfo::Hint
* @return the hint
*/
uint hint() const
{
return m_hint;
}
/**
* Return the unit of the item. See
* KFileMimeTypeInfo::Unit
* @return the unit
*/
uint unit() const
{
return m_unit;
}
private:
/** @internal */
ItemInfo(const TQString& key, const TQString& translatedKey,
TQVariant::Type type)
: m_key(key), m_translatedKey(translatedKey),
m_type(type),
m_attr(0), m_unit(NoUnit), m_hint(NoHint),
m_prefix(TQString::null), m_suffix(TQString::null)
{}
TQString m_key;
TQString m_translatedKey;
TQVariant::Type m_type;
uint m_attr;
uint m_unit;
uint m_hint;
TQString m_prefix;
TQString m_suffix;
};
// ### could it be made private? Would this be BC?
~KFileMimeTypeInfo();
/**
* Creates a validator for this item. Make sure to supply a proper
* @p parent argument or delete the validator yourself.
*
* @param group the group of the item
* @param key the key of the item
* @param parent the parent of the TQObject, or 0 for a parent-less object
* @param name the name of the TQObject, can be 0
* @return the validator. You are responsible for deleting it. 0 if
* creation failed
*/
TQValidator * createValidator(const TQString& group, const TQString& key,
TQObject *parent = 0, const char *name = 0) const;
/**
* Returns the list of all groups that the plugin for this mimetype
* supports.
*
* @return the list of groups
*/
TQStringList supportedGroups() const;
/**
* Same as the above function, but returns the strings to display to the
* user.
*
* @return the list of groups
*/
TQStringList translatedGroups() const;
/**
* This returns the list of groups in the preferred order that's specified
* in the .desktop file.
*
* @return the list of groups
*/
TQStringList preferredGroups() const
{
return m_preferredGroups;
}
/**
* Returns the mimetype to which this info belongs.
*
* @return the mimetype of this info
*/
TQString mimeType() const {return m_mimeType;}
/**
* Get the group info for a specific group.
*
* @param group the group whose group info should be retrieved
* @return a pointer to the info. 0 if it does not
* exist. Don't delete this object!
*/
const GroupInfo * groupInfo( const TQString& group ) const;
// always returning stringlists which the user has to iterate and use them
// to look up the real items sounds strange to me. I think we should add
// our own iterators some time (somewhere in the future ;)
/**
* Return a list of all supported keys without looking for a specific
* group
*
* @return the list of keys
*/
TQStringList supportedKeys() const;
/**
* Return a list of all supported keys in preference order
*
* @return the list of keys
*/
TQStringList preferredKeys() const
{
return m_preferredKeys;
}
// ### shouldn't this be private? BC?
GroupInfo * addGroupInfo( const TQString& name,
const TQString& translatedName);
TQString m_translatedName;
TQStringList m_supportedKeys;
uint m_attr;
// bool m_supportsVariableKeys : 1;
TQDict<ItemInfo> m_itemDict;
// ### this should be made private instead, but this would be BIC
protected:
/** @internal */
KFileMimeTypeInfo( const TQString& mimeType );
TQDict<GroupInfo> m_groups;
TQString m_mimeType;
TQStringList m_preferredKeys; // same as KFileMetaInfoProvider::preferredKeys()
TQStringList m_preferredGroups; // same as KFileMetaInfoProvider::preferredKeys()
};
/**
* @brief A meta information item about a file
*
* This is one item of the meta information about a file (see
* KFileMetaInfo).
*/
class KIO_EXPORT KFileMetaInfoItem
{
public:
class Data;
typedef KFileMimeTypeInfo::Hint Hint;
typedef KFileMimeTypeInfo::Unit Unit;
typedef KFileMimeTypeInfo::Attributes Attributes;
/**
* @internal
* You usually don't need to use this constructor yourself. Let
* KFileMetaInfo do it for you.
**/
// ### hmm, then it should be private
KFileMetaInfoItem( const KFileMimeTypeInfo::ItemInfo* mti,
const TQString& key, const TQVariant& value);
/**
* Copy constructor
**/
KFileMetaInfoItem( const KFileMetaInfoItem & item );
/**
* The assignment operator, so you can do:
* @code
* KFileMetaInfoItem item = info.item("Title");
* @endcode
*
* This will create a shared copy of the object. The actual data
* is automatically deleted if all copies go out of scope
**/
const KFileMetaInfoItem& operator= (const KFileMetaInfoItem & item );
/**
* Default constructor. This creates an "invalid" item
*/
KFileMetaInfoItem();
~KFileMetaInfoItem();
/**
* Returns the key of the item.
*
* @return the key of this item
*/
TQString key() const;
/**
* Returns a translation of the key for displaying to the user. If the
* plugin provides translation to the key, it's also in the user's language
*
* @return the translated key
*/
TQString translatedKey() const;
/**
* Returns the value of the item.
*
* @return the value of the item.
*/
const TQVariant& value() const;
/**
* Returns a string containing the value, if possible. If not,
* TQString::null is returned.
*
* @param mangle if true, the string will already contain prefix and
* suffix
* @return the value string, or TQString::null if not possible
*/
TQString string( bool mangle = true ) const;
/**
* Changes the value of the item.
*
* @param value the new value
* @return true if successful, false otherwise
*/
bool setValue( const TQVariant& value );
/**
* Return the type of the item.
*
* @return the type of the item
*/
TQVariant::Type type() const;
/**
* You can query if the application can edit the item and write it back to
* the file with this method.
*
* @note This doesn't ensure that you have write access to the file and
* that enough space is available.
*
* @return true if the item's value can be changed, false if not
*/
bool isEditable() const;
/**
* If you remove an item, it is only marked for removal for the file. On
* the next KFileMetaInfo::applyChanges() , it will be removed from
* the file. With this method, you can ask if the item is marked for
* removal.
*
* @return true if the item was removed, false if not
*/
bool isRemoved() const;
/**
* If you change an item, it is marked as "dirty". On the next
* KFileMetaInfo::applyChanges() , the change will be written to the
* file. With this method, you can ask if this item is dirty.
*
* @return true if the item contains changes that have not yet been written
* back into the file. Removing or adding an item counts as such a change
*/
bool isModified() const;
/**
* This method returns a translated prefix to be displayed before the
* value. Think e.g. of the $ in $30
*
* @return the prefix
*/
TQString prefix() const;
/**
* This method returns a translated suffix to be displayed after the
* value. Think of the kbps in 128kbps
*
* @return the suffix
*/
TQString suffix() const;
/**
* Returns the hint for this item. See KFileMimeTypeInfo::Hint.
*
* @return the hint
**/
uint hint() const;
/**
* Returns the unit for this item. See KFileMimeTypeInfo::Unit.
*
* @return the unit
* @since 3.2
**/
uint unit() const;
/**
* Returns the attributes for this item. See
* KFileMimeTypeInfo::Attributes.
*
* @return the attributes
**/
uint attributes() const;
/**
* Return true if the item is valid, i.e. if it contains data, false
* if it's invalid (created with the default constructor and not been
* assigned anything), or if KFileMetaInfoGroup::item() didn't find
* your requested item).
*
* @return true if valid, false if invalid
*/
bool isValid() const;
KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& );
KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& );
KIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& );
friend class KFileMetaInfoGroup;
protected:
void setAdded();
void setRemoved();
void ref();
void deref();
Data *d;
};
/**
* @brief A group of meta information items about a file
*
* This is one group of meta information items about a file (see
* KFileMetaInfo).
*/
class KIO_EXPORT KFileMetaInfoGroup
{
friend class KFilePlugin;
friend class KFileMetaInfo;
KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& );
KIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& );
public:
class Data;
/**
* @internal
* You usually don't need to use this constructor yourself. Let
* KFileMetaInfo do it for you.
**/
// ### hmm, then it should be private
KFileMetaInfoGroup( const TQString& name, const KFileMimeTypeInfo* info );
/**
* Copy constructor
**/
KFileMetaInfoGroup( const KFileMetaInfoGroup& original );
/**
* The assignment operator, so you can do:
* @code
* KFileMetaInfoGroup group = info.group("Technical");
* @endcode
*
* This will create a shared copy of the object. The actual data
* is automatically deleted if all copies go out of scope
**/
const KFileMetaInfoGroup& operator= (const KFileMetaInfoGroup& info );
/**
* Default constructor. This creates an "invalid" item
*
* @since 3.1
*/
KFileMetaInfoGroup();
~KFileMetaInfoGroup();
/**
* Returns true if the item is valid, i.e. if it contains data, false
* if it's invalid (created with the default constructor and not been
* assigned anything), or if KFileMetaInfoGroup::item() didn't find
* your requested item).
*
* @return true if valid, false if invalid
*/
bool isValid() const;
/**
* Returns false if the object contains data, true if it's empty. An
* empty group is a group with no items (amazing, isn't it?).
*
* @return true if empty, false otherwise
*/
bool isEmpty() const;
/**
* Returns true if an item as added or removed from the group.
*
* @return true if an item was added or removed from the group, otherwise
* false.
*
* @since 3.1
*/
bool isModified() const;
/**
* Operator for convenience. It does the same as item(),
* but you cannot specify a group to search in
*/
KFileMetaInfoItem operator[]( const TQString& key ) const
{ return item( key ); }
/**
* This method searches for the specified item.
*
* @param key the key of the item to search
* @return the specified item if found, an invalid item, if not
**/
KFileMetaInfoItem item( const TQString& key ) const;
/**
* Returns the item with the given @p hint.
*
* @param hint the hint of the item
* @return the item with the specified @p hint
**/
KFileMetaInfoItem item( uint hint ) const;
/**
* Convenience function. Returns the value of the specified key.
* It does the same as item(key).value().
*
* @param key the key of the item to search
* @return the value with the given key
*/
const TQVariant value( const TQString& key ) const
{
const KFileMetaInfoItem &i = item( key );
return i.value();
}
/**
* Use this method to get a list of keys in the specified group that
* the plugin knows about. No variable keys.
* For a group that doesn't support variable keys, all keys that this
* group may have are returned. For a group that does support them, the
* non-variable ones are returned. See KFileMetaInfo about variable
* keys
*
* @return the list of keys supported for this mimetype
**/
TQStringList supportedKeys() const;
/**
* Returns true if this group supports adding or removing arbitrary
* keys, false if not.
*
* @return true is variable keys are supported, false otherwise
**/
bool supportsVariableKeys() const;
/**
* Checks whether an item with the given @p key exists.
*
* @return true if an item for this @p key exists.
*/
bool contains( const TQString& key ) const;
/**
* Returns a list of all keys.
*
* @return a list of all keys in the order they were inserted.
**/
TQStringList keys() const;
/**
* Returns a list of all keys in preference order.
*
* @return a list of all keys in preference order.
**/
TQStringList preferredKeys() const;
/**
* @return the list of possible types that the value for the specified key
* can be. You can use this to determine the possible types for new
* keys before you add them.
*
**/
// ### do we really want to support that?
// let's not waste time on thinking about it. Let's just kick it for now
// and add it in 4.0 if needed ;)
// const TQMemArray<TQVariant::Type>& types( const TQString& key ) const;
/**
* Add an item to the info. This is only possible if the specified @p key
* is in the supportedKeys list and not yet defined or if
* the group supports variable keys.
*
* @param key the key of the item
* @return the KFileMetaInfoItem for the given @p key
**/
KFileMetaInfoItem addItem( const TQString& key );
/**
* Remove this item from the meta info of the file. You cannot query
* KFileMetaInfo for a removed object, but you can query for a list of
* removed items with removedItems() if you need to.
* If you re-add it, its value will be cleared.
*
* @param key the key of the removed item
* @return true if successful, false otherwise
*/
bool removeItem(const TQString& key);
/**
* Returns a list of all removed items.
*
* @return a list of all removed items
*/
TQStringList removedItems();
/**
* The name of this group.
*
* @return the name of this group
*/
TQString name() const;
/**
* The translated name of this group.
*
* @return the translated name of this group
*
* @since 3.2
*/
TQString translatedName() const;
/**
* Returns the attributes of this item.
*
* @return the attributes
*/
uint attributes() const;
protected:
void setAdded();
KFileMetaInfoItem appendItem( const TQString& key, const TQVariant& value);
Data* d;
void ref();
void deref();
};
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/**
* @brief Meta Information about a file
*
* This is the class for objects that hold meta information about a file.
* The information is kept in form of a system of key/value pairs. See also
* KFileMetaInfoItem.
* This information is retrieved from the file through a plugin system, and
* this class is the main interface to it.
* If you want to write your own plugin, have a look at KFilePlugin.
* There are basically two different kinds of meta information: Fixed ones
* that the plugin knows about (e.g. an mp3 id3v1 tag has a well defined
* fixed list of fields), and variable keys that exist in mimetypes that
* support their own key/value system (comments in png files are of this type).
* Almost every file has fixed keys, but some also have variable keys.
*
* The groups and the What enum are not yet supported, but already added to
* the interface so that adding support doesn't break compatibility.
*/
class KIO_EXPORT KFileMetaInfo
{
public:
typedef KFileMimeTypeInfo::Hint Hint;
typedef KFileMimeTypeInfo::Unit Unit;
typedef KFileMimeTypeInfo::Attributes Attributes;
class Data;
/**
* This is used to specify what a KFileMetaInfo object should read, so
* you can specify if you want to read "expensive" items or not.
*/
enum What
{
Fastest = 0x1, /**< do the fastest possible read and omit all items
that might need a significantly longer time
than the others */
DontCare = 0x2, ///< let the plugin decide what to read
TechnicalInfo = 0x4, /**< extract technical details about the file, like
e.g. play time, resolution or a compressioni
type */
ContentInfo = 0x8, /**< read information about the content of the file,
like comments or id3 tags */
ExtenedAttr = 0x10, /**< read filesystem based extended attributes if
they are supported for the filesystem */
Thumbnail = 0x20, /**< only read the file's thumbnail, if it contains
one */
Preferred = 0x40, ///< get at least the preferred items
Everything = 0xffff ///< read everything, even if it might take a while
};
/**
* The constructor.
*
* creating a KFileMetaInfo item through this will autoload the plugin
* belonging to the mimetype and try to get meta information about
* the specified file.
*
* If no info is available, you'll get an empty (not invalid) object.
* You can test for it with the isEmpty() method.
*
* @param path The file name. This must be the path to a local file.
* @param mimeType The name of the file's mimetype. If ommited, the
* mimetype is autodetected
* @param what one or more of the What enum values. It gives some
* hint to the plugin what information is desired. The plugin
* may still return more items.
*
* @note This version will @b only work for @b local (file:/) files.
*
**/
KFileMetaInfo( const TQString& path,
const TQString& mimeType = TQString::null,
uint what = Fastest);
/**
* Another constructor
*
* Similar to the above, but takes a URL so that meta-data may be retrieved
* over other protocols (ftp, etc.)
*
**/
KFileMetaInfo( const KURL& url,
const TQString& mimeType = TQString::null,
uint what = Fastest);
/**
* Default constructor. This will create an invalid object (see
* isValid().
**/
KFileMetaInfo();
/**
* Copy constructor. This creates a copy of the original object, but
* that copy will point to the same data, so if you change the original,
* the copy will be changed, too. After all, they are referring to the same
* file.
**/
KFileMetaInfo( const KFileMetaInfo& original);
~KFileMetaInfo();
/**
* The assignment operator, so you can do e.g.:
* @code
* KFileMetaInfo info;
* if (something) info = KFileMetaInfo("/the/file");
* @endcode
*
* This will create a shared copy of the object. The actual data
* is automatically deleted if all copies go out of scope.
**/
const KFileMetaInfo& operator= (const KFileMetaInfo& info );
/**
* Returns a list of all groups.
*
* @return the keys of the groups that the file has.
*/
TQStringList groups() const;
/**
* Returns a list of all supported groups.
*
* @return the supported keys of the groups that the file has.
*/
TQStringList supportedGroups() const;
/**
* Returns a list of the preferred groups.
*
* @return the keys of the preferred groups that the file has.
*/
TQStringList preferredGroups() const;
/**
* Returns a list of all preferred keys.
*
* @return a list of all preferred keys.
*/
TQStringList preferredKeys() const;
/**
* Returns a list of supported keys.
*
* @return a list of supported keys
*/
TQStringList supportedKeys() const;
/**
* Returns the list of groups that you can add or remove from the file.
*
* @return the groups can be added or removed
*/
TQStringList editableGroups() const;
// I'd like to keep those for lookup without group, at least the hint
// version
/**
* Returns the KFileMetaInfoItem with the given @p key.
*
* @param key the key of the item
* @return the item. Invalid if there is no item with the given @p key.
*/
KFileMetaInfoItem item(const TQString& key) const;
/**
* Returns the KFileMetaInfoItem with the given @p hint.
*
* @param hint the hint of the item
* @return the item. Invalid if there is no item with the given @p hint.
*/
KFileMetaInfoItem item(const KFileMetaInfoItem::Hint hint) const;
/**
* Saves the item with the given @p key.
*
* @param key the key of the item
* @param preferredGroup the preferred group, or TQString::null
* @param createGroup true to create the group if necessary
* @return the saved item
*/
KFileMetaInfoItem saveItem( const TQString& key,
const TQString& preferredGroup = TQString::null,
bool createGroup = true );
/**
* Returns the KFileMetaInfoGroup with the given @p key.
*
* @param key the key of the item
* @return the group. Invalid if there is no group with the given @p key.
*/
KFileMetaInfoGroup group(const TQString& key) const;
/**
* Returns the KFileMetaInfoGroup with the given @p key.
*
* @param key the key of the item
* @return the group. Invalid if there is no group with the given @p key.
*/
KFileMetaInfoGroup operator[] (const TQString& key) const
{
return group(key);
}
/**
* Try to add the specified group. This will only succeed if it is
* in the list of editableGroups().
*
* @note that all non-variable items that belong to this group are
* automatically added as empty item.
*
* @param name the name of the group to add
* @return true if successful, false if not
*/
bool addGroup( const TQString& name );
/**
* Remove the specified group. This will only succeed if it is
* in the list of editableGroups(). Beware that this also
* removes all the items in that group, so always ask the user
* before removing it!
*
* @param name the name of the group to remove
* @return true if successful, false if not
*/
bool removeGroup( const TQString& name );
/**
* Returns a list of removed groups.
*
* @return a list of removed groups.
*/
TQStringList removedGroups();
/**
* This method writes all pending changes of the meta info back to the file.
* If any items are marked as removed, they are really removed from the
* list. The info object as well as all items are updated.
*
* @return true if successful, false if not
*/
bool applyChanges();
/**
* This method writes all pending changes of the meta info to the file @p path.
* If any items are marked as removed, they are really removed from the
* list. The info object as well as all items are updated.
*
* @return true if successful, false if not
*/
bool applyChanges(const TQString& path);
/**
* Checks whether an item with the given @p key exists.
*
* @param key the key to check
* @return whether an item for this @p key exists.
*/
bool contains( const TQString& key ) const;
/**
* Checks whether a group with the given @p key exists.
*
* @param key the key to check
* @return whether a group with this name exists.
*/
bool containsGroup( const TQString& key ) const;
/**
* Returns the value with the given @p key.
*
* @param key the key to retrieve
* @return the value. Invalid if it does not exist
*/
const TQVariant value( const TQString& key ) const
{
return item(key).value();
}
/**
* Returns true if the item is valid, i.e. if actually represents the info
* about a file, false if the object is uninitialized.
*
* @return true if valid, false otherwise
*/
bool isValid() const;
/**
* Returns false if the object contains data, true if it's empty. You'll
* get an empty object if no plugin for the file could be found.
*
* @return true if empty, false otherwise
*/
bool isEmpty() const;
/**
* Returns the mime type of file.
*
* @return the file's mime type
*/
TQString mimeType() const;
/**
* Returns the path of file - or TQString::null if file is non-local
*
* @return the file's path - or TQString::null if file is non-local
*/
TQString path() const;
/**
* Returns the url of file
*
* @return the file's url
*/
KURL url() const;
KIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& );
KIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& );
friend class KFilePlugin;
protected:
KFileMetaInfoGroup appendGroup(const TQString& name);
/**
* @return a pointer to the plugin that belogs to this object's mimetype.
* It will be auto-loaded if it's currently not loaded
**/
KFilePlugin * const plugin() const;
void ref();
void deref();
Data* d;
private:
KFileMetaInfoItem findEditableItem( KFileMetaInfoGroup& group,
const TQString& key );
void init( const KURL& url,
const TQString& mimeType = TQString::null,
uint what = Fastest);
};
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/**
* @brief Base class for a meta information plugin
*
* Meta information plugins are used to extract useful information from files
* of a given type. These plugins are used in Konqueror's file properties
* dialog, for example.
*
* If you want to write your own plugin, you need to derive from this class.
*
* In the constructor of your class, you need to call addMimeTypeInfo() to tell
* the KFile framework which mimetype(s) your plugin supports. For each
* mimetype, use the addGroupInfo() and addItemInfo() methods to declare the
* meta information items the plugin calculates and to group them accordingly.
* For groups, use setAttributes() to customize your group (see
* KFileMimeTypeInfo::Attributes). For items, use setAttributes() to define the
* behaviour of the item; use setHint() to define the meaning of the item; use
* setUnit() to define the Unit, such as KFileMimeTypeInfo::Seconds or
* KFileMimeTypeInfo::KiloBytes. In short, the constructor defines the data
* structure of the meta information supported by your plugin.
*
* Example:
* @code
* FooPlugin::FooPlugin(TQObject *parent, const char *name,
* const TQStringList &args)
* : KFilePlugin(parent, name, args)
* {
* KFileMimeTypeInfo* info = addMimeTypeInfo( "application/x-foo" );
*
* // our new group
* KFileMimeTypeInfo::GroupInfo* group = 0L;
* group = addGroupInfo(info, "FooInfo", i18n("Foo Information"));
*
* KFileMimeTypeInfo::ItemInfo* item;
*
* // our new items in the group
* item = addItemInfo(group, "Items", i18n("Items"), TQVariant::Int);
* item = addItemInfo(group, "Size", i18n("Size"), TQVariant::Int);
* setUnit(item, KFileMimeTypeInfo::KiloBytes);
*
* // strings are possible, too:
* //addItemInfo(group, "Document Type", i18n("Document type"), TQVariant::String);
* }
* @endcode
*
* Some meta information items are likely to be available in several different
* file formats, such as @c "Author", @c "Title" (for documents), and
* @c "Length" (for multimedia files). Be sure to use the naming scheme from
* existing plugins for your meta information items if possible. If, for
* example, the meta information of a group of files is shown in a table view,
* this will allow two files to share the same column (say "Length") even if
* they are of a different file type.
*
* You must overwrite the readInfo() method. In this method you need to extract
* the meta information of the given file. You can use a third-party library to
* achieve this task. This might be the best way for binary files, since a
* change in the file format is likely to be supported by subsequent releases
* of that library. Alternatively, for text-based file formats, you can use
* TQTextStream to parse the file. For simple file formats, TQRegExp can be of
* great help, too.
*
* After you extracted the relevant information, use appendGroup() and
* appendItem() to fill the meta information data structure (as defined in the
* constructor) with values. Note that you can leave out groups or items
* which are not appropriate for a particular file.
*
* Example:
* @code
* bool FooPlugin::readInfo( KFileMetaInfo& info, uint what)
* {
* int numItems = 0;
* int size = 0;
*
* // do your calculations here, e.g. using a third-party
* // library or by writing an own parser using e.g. QTextStream
*
* // calculate numItems and size ...
*
* // note: use the same key strings as in the constructor
* KFileMetaInfoGroup group = appendGroup(info, "FooInfo");
*
* appendItem(group, "Items", numItems);
* appendItem(group, "Size", size);
*
* return true;
* }
* @endcode
*
* If you want to define mutable meta information items, you need to overwrite
* the writeInfo() method. In this method, you can use third-party library
* (appropriate mostly for binary files, see above) or TQTextStream to write the
* information back to the file. If you use TQTextStream, be sure to write all
* file contents back.
*
* For some items, it might be that not all possible values are allowed. You
* can overwrite the createValidator() method to define constraints for a meta
* information item. For example, the @c "Year" field for an MP3 file could
* reject values outside the range 1500 - 2050 (at least for now). The
* validator is used to check values before the writeInfo() method is called so
* that writeInfo() is only provided correct values.
*
* In your plugin, you need to create a factory for the KFilePlugin
*
* Example:
* @code
* typedef KGenericFactory<FooPlugin> FooFactory;
* K_EXPORT_COMPONENT_FACTORY(kfile_foo, FooFactory("kfile_foo"));
* @endcode
*
* To make your plugin available within KDE, you also need to provide a
* @c .desktop file which describes your plugin. The required fields in the
* file are:
*
* - @c Type: must be @c "Service"
* - @c Name: the name of the plugin
* - @c ServiceTypes: must contain @c "KFilePlugin"
* - @c X-KDE-Library: the name of the library containing the KFile plugin
* - @c MimeType: the mimetype(s) which are supported by the plugin
* - @c PreferredGroups: a comma-separated list of the most important groups.
* This list defines the order in which the meta information groups should be
* displayed
* - @c PreferredItems: a comma-separated list of the most important items.
* This list defines the order in which the meta information items should be
* displayed
*
* Example:
* @code
* [Desktop Entry]
* Encoding=UTF-8
* Type=Service
* Name=Foo Info
* ServiceTypes=KFilePlugin
* X-KDE-Library=kfile_foo
* MimeType=application/x-foo
* PreferredGroups=FooInfo
* PreferredItems=Items,Size
* @endcode
**/
class KIO_EXPORT KFilePlugin : public TQObject
{
Q_OBJECT
public:
/**
* Creates a new KFilePlugin instance. You need to implement a constructor
* with the same argument list as this is required by KGenericFactory
*
* @param parent the parent of the TQObject, can be @c 0
* @param name the name of the TQObject, can be @c 0
* @param args currently ignored
*
* @see addMimeTypeInfo()
* @see addGroupInfo()
* @see addItemInfo()
* @see TQObject()
**/
KFilePlugin( TQObject *parent, const char *name,
const TQStringList& args );
/**
* Destructor
*/
virtual ~KFilePlugin();
/**
* Read the info from the file in this method and insert it into the
* provided KFileMetaInfo object. You can get the path to the file with
* KFileMetaInfo::path(). Use appendGroup() and appendItem() to fill
* @p info with the extracted values
*
* @param info the information will be written here
* @param what defines what to read, see KFileMetaInfo::What
* @return @c true if successful, @c false if it failed
*
* @see writeInfo()
**/
virtual bool readInfo( KFileMetaInfo& info,
uint what = KFileMetaInfo::Fastest ) = 0;
/**
* Similar to the readInfo() but for writing the info back to the file.
* If you don't have any writable keys, don't implement this method
*
* @param info the information that will be written
* @return @c true if successful, @c false if it failed
**/
virtual bool writeInfo( const KFileMetaInfo& info ) const
{
Q_UNUSED(info);
return true;
}
/**
* This method should create an appropriate validator for the specified
* item if it's editable or return a null pointer if not. If you don't have
* any editable items, you don't need to implement this method.
*
* If you you don't need any validation, e.g. you accept any input, you can
* simply return @c 0L, or not reimplement this method at all.
*
* @param mimeType the mime type
* @param group the group name of the validator item
* @param key the key name of the validator item
* @param parent the TQObject parent, can be @c 0
* @param name the name of the TQObject, can be @c 0
**/
virtual TQValidator* createValidator( const TQString& mimeType,
const TQString& group,
const TQString& key,
TQObject* parent,
const char* name) const
{
Q_UNUSED(mimeType); Q_UNUSED(group);Q_UNUSED(key);
Q_UNUSED(parent);Q_UNUSED(name);
return 0;
}
protected:
/**
* Call this from within your constructor to tell the KFile framework what
* mimetypes your plugin supports.
*
* @param mimeType a string containing the mimetype, e.g. @c "text/html"
* @return a KFileMimeTypeInfo object, to be used with addGroupInfo()
**/
KFileMimeTypeInfo * addMimeTypeInfo( const TQString& mimeType );
// ### do we need this, if it only calls the provider?
// IMHO the Plugin shouldn't call its provider.
// DF: yes we need this. A plugin can create more than one mimetypeinfo.
// What sucks though, is to let plugins do that in their ctor.
// Would be much simpler to have a virtual init method for that,
// so that the provider can set up stuff with the plugin pointer first!
/**
* Creates a meta information group for KFileMimeTypeInfo object returned
* by addMimeTypeInfo().
*
* @param info the object returned by addMimeTypeInfo()
* @param key a unique string identifiing this group. For simplicity it is
* recommended to use the same string as for the translatedKey
* parameter
* @param translatedKey the translated version of the key string for
* displaying in user interfaces. Use i18n() to translate the string
* @return a GroupInfo object. Pass this object to addItemInfo to add meta
* information attributed to this group.
*
* @see setAttributes()
* @see addItemInfo()
**/
KFileMimeTypeInfo::GroupInfo* addGroupInfo(KFileMimeTypeInfo* info,
const TQString& key, const TQString& translatedKey) const;
/**
* Sets attributes of the GroupInfo object returned by addGroupInfo().
*
* @param gi the object returned by addGroupInfo()
* @param attr the attributes for this group; these are values of type
* KFileMimeTypeInfo::Attributes, or'ed together
**/
void setAttributes(KFileMimeTypeInfo::GroupInfo* gi, uint attr) const;
void addVariableInfo(KFileMimeTypeInfo::GroupInfo* gi, TQVariant::Type type,
uint attr) const;
/**
* Adds a meta information item to a GroupInfo object as returned by
* addGroupInfo().
*
* @param gi the GroupInfo object to add a new item to
* @param key a unique string to identify this item. For simplicity it is
* recommended to use the same string as for the translatedKey
* parameter
* @param translatedKey the translated version of the key string for
* displaying in user interfaces. Use i18n() to translate the string
* @param type the type of the meta information item, e.g. TQVariant::Int
* or TQVariant::String.
* @return an ItemInfo object. Pass this object to setAttributes()
**/
KFileMimeTypeInfo::ItemInfo* addItemInfo(KFileMimeTypeInfo::GroupInfo* gi,
const TQString& key,
const TQString& translatedKey,
TQVariant::Type type);
/**
* Sets some attributes for a meta information item. The attributes
* describe if the item is mutable, how it should be computed for a list of
* files, and how it should be displayed
*
* @param item the ItemInfo object as returned by addItemInfo()
* @param attr the attributes for this item; these are values of type
* KFileMimeTypeInfo::Attributes, or'ed together
**/
void setAttributes(KFileMimeTypeInfo::ItemInfo* item, uint attr);
/**
* Defines the meaning of the meta information item. Some applications make
* use of this information, so be sure to check KFileMimeTypeInfo::Hint to
* see if an item's meaning is in the list.
*
* @param item the ItemInfo object as returned by addItemInfo()
* @param hint the item's meaning. See KFileMimeTypeInfo::Hint for a list
* of available meanings
**/
void setHint(KFileMimeTypeInfo::ItemInfo* item, uint hint);
/**
* Sets the unit used in the meta information item. This unit is used to
* format the value and to make large values human-readable. For example,
* if the item's unit is KFileMimeTypeInfo::Seconds and the value is 276,
* it will be displayed as 4:36.
*
* @param item the ItemInfo object as returned by addItemInfo()
* @param unit the item's unit. See KFileMimeTypeInfo::Unit for a list of
* available units
**/
void setUnit(KFileMimeTypeInfo::ItemInfo* item, uint unit);
/**
* Sets a prefix string which is displayed before the item's value. Use
* this string if no predefined unit fits the item's unit. Be sure to
* translate the string with i18n()
*
* @param item the ItemInfo object as returned by addItemInfo()
* @param prefix the prefix string to display
**/
void setPrefix(KFileMimeTypeInfo::ItemInfo* item, const TQString& prefix);
/**
* Sets a suffix string which is displayed before the item's value. Use
* this string if no predefined unit fits the item's unit. Be sure to
* translate the string with i18n()
*
* @param item the ItemInfo object as returned by addItemInfo()
* @param suffix the suffix string to display
**/
void setSuffix(KFileMimeTypeInfo::ItemInfo* item, const TQString& suffix);
/**
* Call this method from within readInfo() to indicate that you wish to
* fill meta information items of the group identified by @p key with
* values.
*
* @param info the KFileMetaInfo object. Use the parameter of the
* readInfo() method
* @param key the key string to identify the group. Use the string that you
* defined in your class' constructor
* @return a KFileMetaInfoGroup object, to be used in appendItem()
**/
KFileMetaInfoGroup appendGroup(KFileMetaInfo& info, const TQString& key);
/**
* Call this method from within readInfo() to fill the meta information item
* identified by @p key with a @p value
*
* @param group the KFileMetaInfoGroup object, as returned by appendGroup()
* @param key the key string to identify the item.
* @param value the value of the meta information item
**/
void appendItem(KFileMetaInfoGroup& group, const TQString& key, TQVariant value);
TQStringList m_preferredKeys;
TQStringList m_preferredGroups;
protected:
/**
* Helper method to allow binary compatible extensions when needing
* "new virtual methods"
*
* @param id the identifier of the new "virtual" method
* @param data any parameter data the new "virtual" method needs
*/
virtual void virtual_hook( int id, void* data );
private:
class KFilePluginPrivate;
KFilePluginPrivate *d;
};
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/**
* @internal
* Synchronous access to metadata of a local file. Usually, you don't want
* to use this class for getting metainfo from a file. Use KFileMetaInfo
* directly. However, if you want to find out if a specific mimetype is
* supported and which groups and items are provided for it, you can ask
* the KFileMetainfoProvider for it.
**/
class KIO_EXPORT KFileMetaInfoProvider: private QObject
{
friend class KFilePlugin;
Q_OBJECT
public:
virtual ~KFileMetaInfoProvider();
static KFileMetaInfoProvider * self();
/**
* @return a pointer to the plugin that belongs to the specified mimetype,
* which means also load the plugin if it's not in memory
*/
KFilePlugin * plugin( const TQString& mimeType ); // KDE4: merge with method below
/**
* @return a pointer to the plugin that belongs to the specified mimetype,
* for the given protocol.
* This loads the plugin if it's not in memory yet.
*/
KFilePlugin * plugin( const TQString& mimeType, const TQString& protocol );
const KFileMimeTypeInfo * mimeTypeInfo( const TQString& mimeType ); // KDE4: merge with below
const KFileMimeTypeInfo * mimeTypeInfo( const TQString& mimeType, const TQString& protocol );
TQStringList preferredKeys( const TQString& mimeType ) const;
TQStringList preferredGroups( const TQString& mimeType ) const;
/// @since 3.1
TQStringList supportedMimeTypes() const;
protected: // ## should be private, right?
KFileMetaInfoProvider();
private:
// Data structure:
// Mimetype or Protocol -> { Plugin and MimeTypeInfo }
// The {} struct is CachedPluginInfo
struct CachedPluginInfo
{
CachedPluginInfo() : plugin( 0 ), mimeTypeInfo( 0 ), ownsPlugin( false ) {}
CachedPluginInfo( KFilePlugin* p, KFileMimeTypeInfo* i, bool owns )
: plugin( p ), mimeTypeInfo( i ), ownsPlugin( owns ) {}
// auto-delete behavior
~CachedPluginInfo() {
if ( ownsPlugin ) delete plugin;
delete mimeTypeInfo;
}
// If plugin and mimeTypeInfo are 0, means that no plugin is available.
KFilePlugin* plugin;
KFileMimeTypeInfo* mimeTypeInfo;
// The problem here is that plugin can be shared in multiple instances,
// so the memory management isn't easy. KDE4 solution: use KSharedPtr?
// For now we flag one copy of the KFilePlugin pointer as being "owned".
bool ownsPlugin;
};
// The key is either a mimetype or a protocol. Those things don't look the same
// so there's no need for two QDicts.
TQDict<CachedPluginInfo> m_plugins;
// This data is aggregated during the creation of a plugin,
// before being moved to the appropriate CachedPluginInfo(s)
// At any other time than during the loading of a plugin, this dict is EMPTY.
// Same key as in m_plugins: mimetype or protocol
TQDict<KFileMimeTypeInfo> m_pendingMimetypeInfos;
private:
static KFileMetaInfoProvider * s_self;
KFilePlugin* loadPlugin( const TQString& mimeType, const TQString& protocol );
KFilePlugin* loadAndRegisterPlugin( const TQString& mimeType, const TQString& protocol );
KFileMimeTypeInfo * addMimeTypeInfo( const TQString& mimeType );
class KFileMetaInfoProviderPrivate;
KFileMetaInfoProviderPrivate *d;
};
KIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& );
KIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& );
KIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& );
KIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& );
KIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& );
KIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& );
#endif // KILEMETAINFO_H