Providing file meta-data support with KFile plugins | ||
|---|---|---|
| <<< Previous | Next >>> | |
In addition to reading the meta-data for a file, it is also possible
to change it and save it back into the file. Not all
KFile plugins
need to support this - sometimes it wouldn't even be
meaningful. However it can be very useful, and you should consider
providing write support if practicable.
To implement write support, you have to do two things - mark the items as changeable, and provide a write function. In some circumstances, you may also have to provide a validator function for the new or modified data, to ensure that the meta-data remains valid. We'll take on each of these tasks in turn.
In our MNG KFile plugin, there really isn't
anything that would be meaningful to change. So in this part of the
tutorial, I'm going to
change the theme, and make up my own format (called tutetext), using a
combination of text and numbers, with the input and output handled by
the QDataStream class. You can download a suitable
example as example.tutetext.
Remember that we need a MIME type association so that the KDE Trader
mechanism knows which KFile plugin is required
for a particular
file. In the case of the tutetext document, we're always going to use the
same file (which will be have suffix .tutetext),
and instead of using a magic number association, we'll just define a
.desktop association.
The .desktop association looks like this:
Example 11. x-tutetext.desktop example
1 [Desktop Entry]
2 Encoding=UTF-8
3 Comment=TuteText Document
4 Type=MimeType
5 MimeType=text/x-tutetext
6 Patterns=*.tutetext
|
This is a very simple .desktop entry, and typically there would be many more entries for things such as tranlated names, icons and other properties. However the important parts are lines 4, 5 and 6. Line 4 marks this as a MIME type linkage, while line 5 defines the MIME type (text probably isn't appropriate, but is close enough for this example). Line 6 specifies the files that will be associated with the mimetype, which will be any filename that ends with .tutetext.
I built this in kdelibs/mimetypes/text, but as long as it gets installed in the right place for the KDE Trader to find it, the original location doesn't really matter.
As for the MNG KFile plugin, we need a
.desktop, as shown below:
Example 12. kfile_tutetext.desktop example
1 [Desktop Entry]
2 Encoding=UTF-8
3 Type=Service
4 Name=TuteText Info
5 ServiceTypes=KFilePlugin
6 X-KDE-Library=kfile_tutetext
7 MimeType=text/x-tutetext
|
This is fairly similar to the .desktop we saw for
the MNG KFile plugin, although the names have
changed to match the different MIME type (in line 7), and the
different library we want to have loaded (in line 6). The name (line
4) also changed to avoid any confusion.
The header file (kfile_tutetext.h) has to be updated to include the write method, as shown below:
Example 13. kfile_tutetext.h example
1 /***************************************************************************
2 * Copyright (C) 2004 by Brad Hards *
3 * bhards@bigpond.net.au *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifndef __KFILE_TUTETEXT_H__
21 #define __KFILE_TUTETEXT_H__
22 /**
23 * Note: For further information look into <$KDEDIR/include/kfilemetainfo.h>
24 */
25 #include <kfilemetainfo.h>
26 class QStringList;
27 class tuteTextPlugin: public KFilePlugin
28 {
29 Q_OBJECT
30
31 public:
32 tuteTextPlugin( QObject *parent, const char *name, const QStringList& args );
33
34 virtual bool readInfo( KFileMetaInfo& info, uint what);
35 virtual bool writeInfo( const KFileMetaInfo& info ) const;
36 };
37 #endif // __KFILE_TUTETEXT_H__
|
This pretty much as we've seen before, although the name of the plugin has changed, and the write method in line 35 is new. Quickly stepping through it, lines 1 to 19 provide a standard copyright. Lines 20, 21 and 37 provide the normal idempotent construction for headers (preventing warnings if the header is accidentally included twice). Lines 22 to 25 provide the required class to derive from, and line 26 provides a forward reference for one of the arguments required in the constructor. Lines 27 to 36 provide the class declaration, including the required Q_OBJECT macro definition.
We now have a constructor, read method and write method, as shown below:
Example 14. kfile_tutetext.cpp example
1 /***************************************************************************
2 * Copyright (C) 2004 by Brad Hards *
3 * bhards@bigpond.net.au *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include <config.h>
21 #include <qfile.h>
22 #include <kdebug.h>
23 #include "kfile_tutetext.h"
24 #include <kgenericfactory.h>
25 typedef KGenericFactory<tuteTextPlugin> tuteTextFactory;
26 K_EXPORT_COMPONENT_FACTORY(kfile_tutetext, tuteTextFactory( "kfile_tutetext" ))
27 tuteTextPlugin::tuteTextPlugin(QObject *parent, const char *name,
28 const QStringList &args)
29 : KFilePlugin(parent, name, args)
30 {
31 KFileMimeTypeInfo* info = addMimeTypeInfo( "text/x-tutetext" );
32 KFileMimeTypeInfo::GroupInfo* technicalGroup = 0L;
33 technicalGroup = addGroupInfo(info, "tuteTextTechnical", i18n("Technical"));
34 KFileMimeTypeInfo::ItemInfo* item;
35 // our new items in the group
36 item = addItemInfo(technicalGroup, "An integer", i18n("An integer"), QVariant::Int);
37 setAttributes( item,
38 KFileMimeTypeInfo::Modifiable |
39 KFileMimeTypeInfo::Addable );
40 item = addItemInfo(technicalGroup, "A String", i18n("A String"), QVariant::String);
41 setAttributes( item,
42 KFileMimeTypeInfo::Modifiable |
43 KFileMimeTypeInfo::Addable );
44 item = addItemInfo(technicalGroup, "Another integer", i18n("Another integer"), QVariant::Int);
45 setAttributes( item,
46 KFileMimeTypeInfo::Modifiable |
47 KFileMimeTypeInfo::Addable );
48 }
49 bool tuteTextPlugin::readInfo( KFileMetaInfo& info, uint /*what*/)
50 {
51 QFile file( info.path().latin1() );
52 file.open( IO_ReadOnly );
53 QDataStream stream( &file );
54 // Read the data
55 Q_INT32 firstInt, secondInt;
56 QString myString;
57 stream >> firstInt;
58 stream >> myString;
59 stream >> secondInt;
60 KFileMetaInfoGroup technicalGroup = appendGroup( info, "tuteTextTechnical" );
61 appendItem( technicalGroup, "An integer", firstInt );
62 appendItem( technicalGroup, "A String", myString );
63 appendItem( technicalGroup, "Another integer", secondInt );
64 file.close();
65 return true;
66 }
67 bool tuteTextPlugin::writeInfo( const KFileMetaInfo& info ) const
68 {
69 QFile file( info.path().latin1() );
70 file.open( IO_WriteOnly );
71 QDataStream stream( &file );
72 stream << info["tuteTextTechnical"].value("An integer").toInt();
73 stream << info["tuteTextTechnical"].value("A String").toString();
74 stream << info["tuteTextTechnical"].value("Another integer").toInt();
75 file.close();
76 return true;
77 }
78 #include "kfile_tutetext.moc"
|
Lines 1 to 26 are fairly standard - all I've done is changed it to reflect the updated names.
Lines 27 to 48 are the constructor, and it is broadly similar to the constructor for the MNG example. In this case, we only have one group, consisting of three items (two integers and a string). The setAttributes call in lines 37 to 39 (and repeated in lines 41-43 and 45-47) is an important change, because it marks the items as able to be modified or added. Note that not all of the items have to be able to be updated, so you can do whatever makes sense for your particular file format.
Lines 49 to 66 provide the readInfo method, which
is heavily based on the QDataStream class.
A production quality KFile plugin would
obviously have extensive error checking, however I've omitted it in
this case to make it easier to read.
Lines 67 to 77 provide the writeInfo method,
which is also heavily based on the
QDataStream class, and again omits any error
checking. Lines 69 to 71 provide an open data stream on the required
file, which is passed in as info.path(). Lines 72
to 74 dump the variables back out, to update the file. Lines 75 and 76
then clean up and return.
To complete the build, you'll obviously need a suitable Makefile.am, as shown below:
Example 15. Makefile.am example for tutetext
1 ## Makefile.am for folder file meta info plugin
2 INCLUDES = $(all_includes)
3 # these are the headers for your project
4 noinst_HEADERS = kfile_tutetext.h
5 kde_module_LTLIBRARIES = kfile_tutetext.la
6 kfile_tutetext_la_SOURCES = kfile_tutetext.cpp
7 kfile_tutetext_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
8 kfile_tutetext_la_LIBADD = $(LIB_KIO)
9 # let automoc handle all of the meta source files (moc)
10 METASOURCES = AUTO
11 services_DATA = kfile_tutetext.desktop
12 servicesdir = $(kde_servicesdir)
13 messages:
14 $(XGETTEXT) *.cpp -o $(podir)/kfile_tutetext.pot
|
This is very similar to the previous examples, so I won't work through this one in detail. The only real changes are in the names, and in the absence of any format specific library, since Qt is always linked in.
| <<< Previous | Home | Next >>> |
| Preferred Groups and Items | Displaying and using meta-data in your application |