Next Previous Contents

3. Sample

This sample describes the development of a KMovisto export plugin with export Dialog and file management by KMovisto. You will find a sample program which shows the programming principles but you won't find a complete library here that could be used in any usefull way than as template. The sample plugin will print out the current molecule data and the filename which should be used to the standard output.

3.1 Step1: Preparation

In this description I assume, that you have created a project directory somewhere in your home directory named myplugin and that you have copied the files iplugin.h and iplugin.cpp (shipped with your KMovisto tar ball or KMovisto plugin development kit) in this directory. You should not change iplugin.h or iplugin.cpp in any way, so you may use a static library archive file libiplugin.a instead created by the following commands:

  g++ -v -c iplugin.cpp
  ar r libiplugin.a iplugin.o
  ranlib libiplugin.a
Furthermore you should create the empty files myplugin.h and myplugin.cpp.

3.2 Step2: Programming and compilation

First of all is the implementation and declaration of the plugin requirements via macros DECLARE_PLUGIN_CLASS/IMPLEMENT_PLUGIN_CLASS(CMyPlugin) and the declaration of the class CMyPlugin:

myplugin.h

/* plugin class declarations */
DECLARE_PLUGIN_CLASS(CMyPlugin)

class CMyPlugin : public CIPluginFileExportDialog
{
};

myplugin.cpp

#include "myplugin.h"

/* plugin class implementations */
IMPLEMENT_PLUGIN_CLASS(CMyPlugin)

CMyPlugin is inherited by CIPluginFileExportDialog, the base class for export plugins with file dialog management. The macro DECLARE_PLUGIN_CLASS(CMyPlugin) declares a global function which enables KMovisto to create an instance of the plugin class CMyPlugin. It also includes the using namespace kmpi; for you. DECLARE_PLUGIN_CLASS(CMyPlugin) provides a declaration of a function which creates the instance of CMyPlugin used by KMovisto.

Next step is a declaration and implementation of virtual member functions declared by the base classes CIPlugin and CIPluginFile. Because they are very simple member functions which are only used for providing plugin informations they may defined in the header file:

myplugin.h

#include "iplugin.h"

/* plugin class declarations */ DECLARE_PLUGIN_CLASS(CMyPlugin)

class CMyPlugin : public CIPluginFileExportDialog {   public:   /* plugin properties */   virtual string getName(void) {return(string("My KMovisto Plugin"));};   virtual string getDescription(void) {string("This Plugin demonstrates the developing of KMovisto plugins");};   virtual string getPluginVersion(void) {return(string("0.1.0"));};   virtual string getInterfaceVersion(void) {return(string("1.0.0"));};   virtual string getAuthor(void) {return(string("Mario Hoverath"));};   virtual string getEmail(void) {return(string("mario.hoverath@uni-koeln.de"));};   virtual string getHomepage(void) {return(string("http://members.tripod.de/PageOfMH/index.html"));};   virtual string getLicense(void) {return(string("GPL"));};   virtual string getTooltipText(void) {return(string("Plugin demonstration"));};   virtual string getMenuText(void) {return(string("MyPlugin"));};   virtual string getWhatsThisText(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};   virtual string getStatusText(void) {return(string("MyPlugin is executed"));};   virtual string getHighlightText(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));}; };

myplugin.cpp

#include "myplugin.h"

/* plugin class implementations */
IMPLEMENT_PLUGIN_CLASS(CMyPlugin)

At this point we would like to add the following toolbar button icon:

As described in chapter 2.2.2 this has to be done by overwriting the member function virtual const char** getButtonXPM(void). The xpm bitmap should be stored in a static xpm member variable like that static const char* xpm[];.

myplugin.h

#include "iplugin.h"

/* plugin class declarations */
DECLARE_PLUGIN_CLASS(CMyPlugin)

class CMyPlugin : public CIPluginFileExportDialog
{
  public:
  /* plugin properties */
  virtual string getName(void) {return(string("My KMovisto Plugin"));};
  virtual string getDescription(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};
  virtual string getPluginVersion(void) {return(string("0.1.0"));};
  virtual string getInterfaceVersion(void) {return(string("1.0.0"));};
  virtual string getAuthor(void) {return(string("Mario Hoverath"));};
  virtual string getEmail(void) {return(string("mario.hoverath@uni-koeln.de"));};
  virtual string getHomepage(void) {return(string("http://members.tripod.de/PageOfMH/index.html"));};
  virtual string getLicense(void) {return(string("GPL"));};
  virtual string getTooltipText(void) {return(string("Plugin demonstration"));};
  virtual string getMenuText(void) {return(string("MyPlugin"));};
  virtual string getWhatsThisText(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};
  virtual string getStatusText(void) {return(string("MyPlugin is executed"));};
  virtual string getHighlightText(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};
  virtual const char** getButtonXPM(void) {return((const char**)CMyPlugin::xpm);};

  protected:
  /* protected members */
  static const char* xpm[];
};

myplugin.cpp

#include "myplugin.h"

/* plugin class implementations */ IMPLEMENT_PLUGIN_CLASS(CMyPlugin)

const char* CMyPlugin::xpm[] = {   "16 16 33 1",   "     c None",   ".    c #000000",   "+    c #FFFF00",   "@    c #AFAFCB",   "#    c #A4A4B5",   "$    c #DCDCDC",   "%    c #A8A8D5",   "&    c #BBBBE3",   "*    c #555588",   "=    c #8D8DD1",   "-    c #7777A4",   ";    c #C9C9CF",   ">    c #6F6FAE",   ",    c #AAAAFF",   "'    c #4444FF",   ")    c #C6C6FF",   "!    c #595980",   "~    c #9191D0",   "{    c #9999FF",   "]    c #646475",   "^    c #6B6B8D",   "/    c #7777CC",   "(    c #4F4F93",   "_    c #8484A6",   ":    c #393971",   "<    c #7777DD",   "[    c #606077",   "}    c #7D7DE3",   "|    c #2D2DCC",   "1    c #5555AA",   "2    c #9191A8",   "3    c #ABABAB",   "4    c #444488",   "       ..       ",   "      .++.      ",   "     .++++.     ",   "      .++.      ",   "      .++.      ",   "      ....      ",   "                ",   "      @#        ",   "    $%&*=-$     ",   "   $;>,'))!;    ",   " ===~*,'{{*]^^^ ",   " ///((,'{{((/// ",   " ###_:,'<<:_### ",   "    $[}|112     ",   "     34:##      ",   "                " };

In the last step, the plugin class has to interact with the events KMPI_RESULT onCreate(void);, virtual KMPI_RESULT onDestroy(void); and virtual KMPI_RESULT onOpenFile(const string& file, string& errorMsg);. The last member function is the main function which should contain the data export routines in 'real' plugins. This sample plugin dumps molecule data and the export file name to the standard output.

myplugin.h

#include "iplugin.h"

/* plugin class declarations */ DECLARE_PLUGIN_CLASS(CMyPlugin)

class CMyPlugin : public CIPluginFileExportDialog {   public:   /* plugin properties */   virtual string getName(void) {return(string("My KMovisto Plugin"));};   virtual string getDescription(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};   virtual string getPluginVersion(void) {return(string("0.1.0"));};   virtual string getInterfaceVersion(void) {return(string("1.0.0"));};   virtual string getAuthor(void) {return(string("Mario Hoverath"));};   virtual string getEmail(void) {return(string("mario.hoverath@uni-koeln.de"));};   virtual string getHomepage(void) {return(string("http://members.tripod.de/PageOfMH/index.html"));};   virtual string getLicense(void) {return(string("GPL"));};   virtual string getTooltipText(void) {return(string("Plugin demonstration"));};   virtual string getMenuText(void) {return(string("MyPlugin"));};   virtual string getWhatsThisText(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};   virtual string getStatusText(void) {return(string("MyPlugin is executed"));};   virtual string getHighlightText(void) {return(string("This Plugin demonstrates the developing of KMovisto plugins"));};   virtual const char** getButtonXPM(void) {return((const char**)CMyPlugin::xpm);};   protected:   /* protected members */   static const char* xpm[];   public:   /* events */   virtual KMPI_RESULT onCreate(void);   virtual KMPI_RESULT onDestroy(void);   virtual KMPI_RESULT onOpenFile(const string& file, string& errorMsg); };

myplugin.cpp

#include "myplugin.h"

/* plugin class implementations */ IMPLEMENT_PLUGIN_CLASS(CMyPlugin)

const char* CMyPlugin::xpm[] = {   "16 16 33 1",   "     c None",   ".    c #000000",   "+    c #FFFF00",   "@    c #AFAFCB",   "#    c #A4A4B5",   "$    c #DCDCDC",   "%    c #A8A8D5",   "&    c #BBBBE3",   "*    c #555588",   "=    c #8D8DD1",   "-    c #7777A4",   ";    c #C9C9CF",   ">    c #6F6FAE",   ",    c #AAAAFF",   "'    c #4444FF",   ")    c #C6C6FF",   "!    c #595980",   "~    c #9191D0",   "{    c #9999FF",   "]    c #646475",   "^    c #6B6B8D",   "/    c #7777CC",   "(    c #4F4F93",   "_    c #8484A6",   ":    c #393971",   "<    c #7777DD",   "[    c #606077",   "}    c #7D7DE3",   "|    c #2D2DCC",   "1    c #5555AA",   "2    c #9191A8",   "3    c #ABABAB",   "4    c #444488",   "       ..       ",   "      .++.      ",   "     .++++.     ",   "      .++.      ",   "      .++.      ",   "      ....      ",   "                ",   "      @#        ",   "    $%&*=-$     ",   "   $;>,'))!;    ",   " ===~*,'{{*]^^^ ",   " ///((,'{{((/// ",   " ###_:,'<<:_### ",   "    $[}|112     ",   "     34:##      ",   "                " }; KMPI_RESULT CMyPlugin::onCreate(void) {   fprintf(stdout, "CMyPlugin::onCreate called\n");   return(KMPI_SUCCESS); } KMPI_RESULT CMyPlugin::onDestroy(void) {   fprintf(stdout, "CMyPlugin::onDestroy called\n");   return(KMPI_SUCCESS); } KMPI_RESULT CMyPlugin::onOpenFile(const string& file, string& errorMsg) {   unsigned int i = 1;   fprintf(stdout, "CMyPlugin::onOpenFile called\n");   fprintf(stdout, "file=%s\n", file.c_str());   fprintf(stdout, "\nMolecule properties:\n--------------------\n\n*** Atoms: ***\n");   for(i = 1; i <= molecule->getNumberOfAtoms(); i++)   {     fprintf(stdout, "Atom %d: \nNumber=%d\n", i, molecule->getAtomNumber(i));     fprintf(stdout,  "Symbol=%s\n", molecule->getAtomSymbol(i).c_str());     fprintf(stdout, "Radius=%f\n", molecule->getAtomRadius(i));     fprintf(stdout, "Position: x=%f y=%f z=%f\n",             molecule->getAtomPosition(i).getPositionX(),             molecule->getAtomPosition(i).getPositionY(),             molecule->getAtomPosition(i).getPositionZ());     fprintf(stdout, "Color: red=%d green=%d blue=%d\n",             molecule->getAtomColor(i).getColorRed(),             molecule->getAtomColor(i).getColorGreen(),             molecule->getAtomColor(i).getColorBlue());     fprintf(stdout, "--------------------\n");   }   fprintf(stdout, "\n*** Bonds: ***\n");   for(i = 1; i <= molecule->getNumberOfBonds(); i++)   {     fprintf(stdout, "Connection between atom%d and atom%d\n",                      molecule->getBond(i)->getBondPartner1(),                      molecule->getBond(i)->getBondPartner2());     fprintf(stdout, "--------------------\n");   }   fprintf(stdout, "Color: red=%d green=%d blue=%d\n",           molecule->getBondColor().getColorRed(),           molecule->getBondColor().getColorGreen(),           molecule->getBondColor().getColorBlue());   fprintf(stdout, "Radius=%f\n", molecule->getBondRadius());   errorMsg = (string)"";   return(KMPI_SUCCESS); }

Now it is time to compile the export plugin. If you use the static library libiplugin.a as described in capter 3.1 the library is created with the following command:

  g++ -shared -fPIC -L. -o libMyPlugin.so myplugin.cpp -liplugin
Or if the interface sourcecode iplugin.cpp is used instead of a static library:
  g++ -shared -fPIC -o libMyPlugin.so myplugin.cpp iplugin.cpp

3.3 Step3: Installation

The installation of the plugin is as simple as possible: The plugin file libMyPlugin.so should be copied to /usr/lib to make it available to all users or copied to a local user directory, ~/lib, respectively. Now you have the ability to load the plugin library via KMovisto plugin manager. After loading the plugin the plugin properties are displayed (Fig. 2 - 4):

Fig. 2: Plugin manager - description

Fig. 3: Plugin manager - properties

Fig. 4: Plugin manager - legacy

When the new plugin is added to KMovisto it is usable immediately via tool bar button or menu (Fig. 5):

Fig. 5: Menu and toolbar entries

The sample plugin includes file funtionality, so the user has also the ability to configure working directories and file format filters (Fig. 6).

Fig. 6: Working directory and filter configuration


Next Previous Contents