Getting started - MNG file

This section provides a trivial (as in, doesn't actually do anything useful) example of a KFile meta-data plugin for the MNG file format. MNG (or Multi-image Network Graphics, pronounced "ming") is a similar file format to the very popular PNG (or Portable Network Graphics) format, and allows simple animations. You can find out more about MNG at http://www.libpng.org/pub/mng/. If you don't have any MNG images handy, now would be a good time to get one - there are several linked off the MNG site, or you can grab the sample image that I'm going to use for many examples in this tutorial.

Before going into how to write the KFile meta-data plugin, I thought it might help to show you what the finished product will look like, since then you will be able to see it emerging through the code.

Figure 3. Trivial meta-data properties for MNG image file

Actually writing a KFile meta-data plugin basically consists of making three parts - a header file, a source file, and a .desktop file.

The .desktop (which for the MNG meta-data plugin would be kfile_mng.desktop) is used by KDE to relate the MIME type (which is video/x-mng for MNG) to the name of the library which needs to be loaded (which is kfile_mng.so in these examples). kfile_mng.desktop looks like the following:

Example 1. .desktop example

	     1	[Desktop Entry]
     2	Encoding=UTF-8
     3	Type=Service
     4	Name=MNG Info
     5	Name[ca]=Informació mng
     6	Name[de]=MNG-Information
     7	Name[es]=Información de mng
     8	Name[et]=mng info
     9	Name[hu]=mng jellemzői
    10	Name[it]=Informazioni su mng
    11	Name[nl]=Info over mng
    12	Name[pt]=Informação do mng
    13	Name[pt_BR]=Informações de mng
    14	Name[ru]=Информация о mng
    15	Name[sr]=mng информације
    16	Name[sv]=mng information
    17	Name[xx]=xxmng Infoxx
    18	Name[zh_CN]=mng的信息
    19	ServiceTypes=KFilePlugin
    20	X-KDE-Library=kfile_mng
    21	MimeType=video/x-mng
    22	# change PreferredGroups here! (example: FolderInfo)
    23	PreferredGroups=
    24	# change PreferredItems here! (example: Items;Size)
    25	PreferredItems=
      

The format of a .desktop file is based on the Desktop Entry Specification, which you can read at http://www.freedesktop.org/Standards/desktop-entry-spec.

Working through kfile_mng.desktop, the first line is a flag to show that this file follows the Desktop Entry Specification. Line two is the encoding used in the file - this should almost always be UTF-8. Line 3 shows that this is a Service type .desktop file. Lines four to eighteen are descriptions of the service in various languages. Line nineteen indicates that the specific service offered is a KFilePlugin. Line 20 provides the name of the shared object library that has to be loaded to provide the required service. Line 21 specifies the MIME type that the shared object can provide a service for. Lines 22 to 25 allow specific control over which meta-data should be shown first - they're blank for now (and they could equally be omitted), but we'll come back to fill them in later.

The interface for the plugin is provided in the header file. kfile_mng.h looks like:

Example 2. header file 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_MNG_H__
    21	#define __KFILE_MNG_H__
       

    22	/**
    23	 * Note: For further information look into <$KDEDIR/include/kfilemetainfo.h>
    24	 */
    25	#include <kfilemetainfo.h>
       

    26	class QStringList;
       

    27	class mngPlugin: public KFilePlugin
    28	{
    29	    Q_OBJECT
    30	    
    31	public:
    32	    mngPlugin( QObject *parent, const char *name, const QStringList& args );
    33	    
    34	    virtual bool readInfo( KFileMetaInfo& info, uint what);
    35	};
       

    36	#endif // __KFILE_MNG_H__
       

      

Working through the header file, lines 1 to 19 provide description and license. Lines 20 and 21, and line 36, are used to prevent problems if the header file is accidently included multiple times. Line 25 brings in the KFilePlugin class and some supporting definitions, while line 26 provides a forward declaration of the QStringList class. Lines 27 to 35 provide the actual interface for the mngPlugin, which is a subclass of KFilePlugin - see line 27. Line 29 adds the Q_OBJECT macro definition, which is needed for some of Qt's functionality, such as introspection. Line 31 declares the constructor for the mngPlugin class. Line 33 declares the other public method - readInfo.

The implementation for the plugin is provided in the source file. kfile_mng.h looks like:

Example 3. source file 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 "kfile_mng.h"
       

    22	#include <kgenericfactory.h>
       

    23	typedef KGenericFactory<mngPlugin> mngFactory;
       

    24	K_EXPORT_COMPONENT_FACTORY(kfile_mng, mngFactory( "kfile_mng" ))
       

    25	mngPlugin::mngPlugin(QObject *parent, const char *name,
    26	                       const QStringList &args)
    27	    : KFilePlugin(parent, name, args)
    28	{
    29	    KFileMimeTypeInfo* info = addMimeTypeInfo( "video/x-mng" );
       

    30	    // our new group
    31	    KFileMimeTypeInfo::GroupInfo* group = 0L;
    32	    group = addGroupInfo(info, "mngInfo", i18n("MNG Information"));
       

    33	    KFileMimeTypeInfo::ItemInfo* item;
       

    34	    // our new items in the group
    35	    item = addItemInfo(group, "Items", i18n("Items"), QVariant::Int);
    36	    item = addItemInfo(group, "Size", i18n("Size"), QVariant::Int);
    37	    setUnit(item, KFileMimeTypeInfo::KiloBytes);
       

    38	    // strings are possible, too:
    39	    //addItemInfo(group, "Text", i18n("Document type"), QVariant::String);
    40	}
       

    41	bool mngPlugin::readInfo( KFileMetaInfo& info, uint /*what*/)
    42	{
    43	    KFileMetaInfoGroup group = appendGroup(info, "mngInfo");
       

    44	    appendItem(group, "Items", 100);
    45	    appendItem(group, "Size", int(5000/1024));
    46	    
    47	    return true;
    48	}
       

    49	#include "kfile_mng.moc"
       

      

Working through the source file, lines 1 to 19 again provide description and license. Lines 20 and 21 bring in local declarations, and line 22 brings in the KGenericFactory template. Line 23 applies the KGenericFactory template to produce the mngFactory. Line 24 uses the K_EXPORT_COMPONENT_FACTORY macro to provide an appropriate initialation point for the shared library.

Lines 25 to 40 define the constructor for the mngPlugin, which passes each of its arguments to the parent KFilePlugin. Line 29 invokes the addMimeTypeInfo method (which is inherited from the KFilePlugin class) for the video/x-mng MIME type. Lines 31 and 32 declares a group, labelled MNG Information, as shown in the screenshot above. Line 35 adds an integer item to the group - labelled Items. Lines 36 and 37 add a second integer item to the same group, this time labelled Size, which is expressed in kilobytes.

Lines 41 to 48 define the readInfo method, which actually adds the values to the display. Line 43 adds in the group label (where the "mngInfo" relates to the second argument in addGroupInfo at line 32). Line 44 adds the value 100 to the "Items", while line 45 adds the value 4 kilobytes to the "Size" item.

Having written the three key files, we can now proceed to build the shared library. There are two basic ways to do so - either as part of one of the KDE modules, or as a standalone build.

Integrated build

As in integrated build, for MNG, the plugin would probably be part of the kdegraphics module, in kfile-plugins/mng. All that is required (apart from kfile_mng.h, kfile_mng.cpp and kfile_mng.desktop) is a suitable Makefile.am within the kfile-plugins/mng directory, and to include the mng directory in the SUBDIRS line in kfile_plugins/Makefile.am. The kdegraphics/kfile-plugins/mng/Makefile.am looks like:

Example 4. Makefile.am example

	       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_mng.h
       

     5	kde_module_LTLIBRARIES = kfile_mng.la
       

     6	kfile_mng_la_SOURCES = kfile_mng.cpp
     7	kfile_mng_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
     8	kfile_mng_la_LIBADD = $(LIB_KIO)
       

     9	# let automoc handle all of the meta source files (moc)
    10	METASOURCES = AUTO
       

    11	services_DATA = kfile_mng.desktop
    12	servicesdir = $(kde_servicesdir)
       

    13	messages:
    14		$(XGETTEXT) *.cpp -o $(podir)/kfile_mng.pot
	

This is fairly standard Automake code. At line four, any header files that should not be installed (likely any headers in the plugin directory) will be listed. Line 5 specifies the name of the target shared object file. Line 6 specifies the source files that are built into the shared library, while lines 7 and 8 provide direction to the linker. Line 11 provides the desktop file that needs to be installed, while line 12 provides the installation location. Lines 13 and 14 provide support for KDE's internationalisation features.

You can then go through the normal KDE CVS routine in the top level directory (make -f Makefile.cvs && ./configure && make && make install), and then make sure KDE recognises the new addition (probably easiest by logging out of the session and logging back in again, although you may just be able to run kdeinit from a terminal session).

You should now be able to right-click to bring up the properties dialog, which should now include the meta-data tab as shown in the screenshot above. Congratulations on getting this far!

Standalone build

It is somewhat more difficult to construct a standalone build by hand, and I recommend using the excellent KDevelop integrated development environment, which has direct support for KFile plugins. Indeed, the example code provided earlier in this section was produced with the KFilePlugin wizard and slightly adapted for an integrated build. For more information on this, refer to the documentation provided with KDevelop, or just try it - the wizard is quite intuitive.

You can then use the normal KDevelop project build and install functions.