/* * This file is part of the KDE libraries * Copyright (C) 2001-2002 Rolf Magnus * Copyright (C) 2001-2002 Carsten Pfeiffer * * 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 TDEFILEMETAINFO_H #define TDEFILEMETAINFO_H /* Hack for HPUX: Namespace pollution m_unit is a define in */ #define m_unit outouftheway_m_unit #include #include #include #include #include #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 TDEIO_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 TDEIO_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 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 TDEIO_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 m_itemDict; // ### this should be made private instead, but this would be BIC protected: /** @internal */ KFileMimeTypeInfo( const TQString& mimeType ); TQDict 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 TDEIO_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; TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& ); TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& ); TDEIO_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 TDEIO_EXPORT KFileMetaInfoGroup { friend class KFilePlugin; friend class KFileMetaInfo; TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& ); TDEIO_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& 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 TDEIO_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; TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& ); TDEIO_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 * 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 FooFactory; * K_EXPORT_COMPONENT_FACTORY(tdefile_foo, FooFactory("tdefile_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-TDE-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-TDE-Library=tdefile_foo * MimeType=application/x-foo * PreferredGroups=FooInfo * PreferredItems=Items,Size * @endcode **/ class TDEIO_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 TDEIO_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 TDESharedPtr? // 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 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 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; }; TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& ); TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& ); TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& ); TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& ); TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& ); TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& ); #endif // TDEFILEMETAINFO_H