Development/Tutorials/Writing kontact plugins: Difference between revisions

From KDE TechBase
m (add Category:PIM)
No edit summary
Line 23: Line 23:


<pre>
<pre>
PROJECT( kdepart )
project(hello)
FIND_PACKAGE(KDE4 REQUIRED)
find_package (KDE4 REQUIRED)
INCLUDE_DIRECTORIES(${KDE4_INCLUDES} .)
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} . )


SET(kdepartSources main.cpp mypart.cpp)
include_directories( ${KDE4_INCLUDE_DIR}/kcal ${CMAKE_SOURCE_DIR}/kresources/remote  )


KDE4_ADD_EXECUTABLE(kdepart ${kdepartSources})


TARGET_LINK_LIBRARIES(kdepart ${KDE4_KDEUI_LIBS}  
########### next target ###############
  ${KDE4_KPARTS_LIBS})
set(hello_shared_SRCS
hello_part.cpp
)
 
 
set(hellopart_PART_SRCS hello_part.cpp)
 
kde4_add_plugin(hellopart ${hellopart_PART_SRCS})
 
target_link_libraries(hellopart ${KDE4_KPARTS_LIBS} ${KDE4_KCAL_LIBS}  ${KDE4_KIO_LIBS} kdepim kcal_resourceremote)
if(X11_Xscreensaver_LIB)
target_link_libraries(hellopart  ${X11_Xscreensaver_LIB} )
endif(X11_Xscreensaver_LIB)
 
 
install(TARGETS hellopart  DESTINATION ${PLUGIN_INSTALL_DIR})
 
 
########### install files ###############
 
install( FILES hello_part.desktop  DESTINATION ${SERVICES_INSTALL_DIR})
</pre>
</pre>


== main.cpp ==
== hello_part.h ==


<code cpp>
<code cpp>
#include <kapplication.h>
#ifndef _HELLOPART_H_
#include <kaboutdata.h>
#define _HELLOPART_H_
#include <kparts/mainwindow.h>
 
#include <kparts/part.h>
#include <kparts/part.h>
#include <kcmdlineargs.h>
#include <kparts/factory.h>
#include "mypart.h"
#include <QTreeWidget>


int main (int argc, char *argv[])
/**
* This is a "Part".  It that does all the real work in a KPart
* application.
*/
class helloPart : public KParts::ReadWritePart
{
{
   const QByteArray& ba=QByteArray("test");
   Q_OBJECT
  const KLocalizedString name=ki18n("myName");
 
  KAboutData aboutData( ba, ba, name, ba, name);
   private:
   KCmdLineArgs::init( argc, argv, &aboutData );
    QTreeWidget *mMainWidget;
  KApplication khello;
  mypartmainwindow* mw=new mypartmainwindow();
  mw->show();
  khello.exec();
}
</code>


== mypart.h ==
public:
    helloPart(QWidget *parentWidget, QObject *parent, const QVariantList&);


<code cpp>
    QTreeWidget* MainWidget() { return mMainWidget; };
#include <KParts/Part>
#include <KParts/MainWindow>


class mypart:public KParts::Part
    virtual ~helloPart();
{
    bool openFile(){};
     Q_OBJECT
     bool saveFile(){};
public:
  mypart(QObject *parent=0);
};
};


class mypartmainwindow:public KParts::MainWindow
#endif // _HELLOPART_H_
{
    Q_OBJECT
public:
  mypartmainwindow(QWidget* parent=0,
                  Qt::WindowFlags f=KDE_DEFAULT_WINDOWFLAGS);
};
</code>
</code>


== mypart.cpp ==
== hello_part.cpp ==


<code cpp>
<code cpp>
#include <kdebug.h>
#include "hello_part.h"
#include <KPushButton>
 
#include "mypart.h"
#include <kdemacros.h>
#include <kparts/genericfactory.h>
 
K_PLUGIN_FACTORY(helloPartFactory, registerPlugin<helloPart>();)  // produce a factory
K_EXPORT_PLUGIN(helloPartFactory("hello","hello") )


mypart::mypart(QObject* parent)
helloPart::helloPart( QWidget *parentWidget, QObject *parent, const QVariantList& )
    : KParts::ReadWritePart(parent)
{
{
   kDebug() << "Entering mypart";
   KGlobal::locale()->insertCatalog("hello");
   QWidget* mywidget=new QWidget();
   // we need an instance
   new KPushButton("hello world",mywidget);
  setComponentData( helloPartFactory::componentData() );
   setWidget(mywidget);
 
   mMainWidget = new QTreeWidget( parentWidget );
   setWidget( mMainWidget );
}
}


mypartmainwindow::mypartmainwindow(QWidget* parent,
helloPart::~helloPart()
                                  Qt::WindowFlags f)
{
{
  kDebug() << "Entering mypartmainwindow";
  mypart* mypart1=new mypart(this);
  mypart1->embed(this);
}
}
#include "hello_part.moc"
</code>
</code>


= Compiling your KPart =
= Compiling your KPart =


To compile, link and run the code above, use
To compile and link the code above, use
  cmake . && make && ./kdepart
  cmake . && make  


= Using your KPart =
= Using your KPart =

Revision as of 20:16, 28 May 2008

Introduction

Kontact is a KDE PIM (personal information management) framework that allows embedding several pim applications like kmail and korganizer as plugins into one window. Kontact plugins are KParts that get loaded at runtime. So, this is a good time to learn how to write a kPart... Read on.

Writing a KPart

We will write a "hello world"-KPart here. And we will write a MainWindow to hold this KPart. A KPart also gives you the flexibility to be integrated into kontact or konqueror, but we will do this later. So, the "hello world"-KPart only consists of a pushbutton labeled "hello world". We chose a pushbutton because it is the easiest viewable thing to create. It does not trigger an action on your click. The following is what you do

  • write a subclass mypart of KParts::Part
    • because setWidget is protected
    • use a Widget in it and use setWidget to get your widget into the KPart
  • write a subclass mypartmainwindow of KParts::MainWindow
    • because createGUI is protected (and you may want createGUI later)
  • write main.cpp
    • use new mypart(mw) to get your part into your main window

We will use 4 files to do this:

  • CMakeLists.txt to ease building work
  • main.cpp to show our MainWindow
  • mypart.h to declare our classes
  • mypart.cpp to implement our classes

CMakeLists.txt

project(hello)
find_package (KDE4 REQUIRED)
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} . )

include_directories( ${KDE4_INCLUDE_DIR}/kcal ${CMAKE_SOURCE_DIR}/kresources/remote  )


########### next target ###############
set(hello_shared_SRCS 
	hello_part.cpp
 )


set(hellopart_PART_SRCS hello_part.cpp)

kde4_add_plugin(hellopart ${hellopart_PART_SRCS})

target_link_libraries(hellopart ${KDE4_KPARTS_LIBS} ${KDE4_KCAL_LIBS}  ${KDE4_KIO_LIBS} kdepim kcal_resourceremote)
if(X11_Xscreensaver_LIB)
	target_link_libraries(hellopart  ${X11_Xscreensaver_LIB} )
endif(X11_Xscreensaver_LIB)


install(TARGETS hellopart  DESTINATION ${PLUGIN_INSTALL_DIR})


########### install files ###############

install( FILES hello_part.desktop  DESTINATION ${SERVICES_INSTALL_DIR})

hello_part.h

  1. ifndef _HELLOPART_H_
  2. define _HELLOPART_H_
  1. include <kparts/part.h>
  2. include <kparts/factory.h>
  3. include <QTreeWidget>

/**

* This is a "Part".  It that does all the real work in a KPart
* application.
*/

class helloPart : public KParts::ReadWritePart {

 Q_OBJECT
 private:
   QTreeWidget *mMainWidget;

public:

   helloPart(QWidget *parentWidget, QObject *parent, const QVariantList&);
   QTreeWidget* MainWidget() { return mMainWidget; };
   virtual ~helloPart();
   bool openFile(){};
   bool saveFile(){};

};

  1. endif // _HELLOPART_H_

hello_part.cpp

  1. include "hello_part.h"
  1. include <kdemacros.h>
  2. include <kparts/genericfactory.h>

K_PLUGIN_FACTORY(helloPartFactory, registerPlugin<helloPart>();) // produce a factory K_EXPORT_PLUGIN(helloPartFactory("hello","hello") )

helloPart::helloPart( QWidget *parentWidget, QObject *parent, const QVariantList& )

   : KParts::ReadWritePart(parent)

{

 KGlobal::locale()->insertCatalog("hello");
 // we need an instance
 setComponentData( helloPartFactory::componentData() );
 mMainWidget = new QTreeWidget( parentWidget );
 setWidget( mMainWidget );

}

helloPart::~helloPart() { }

  1. include "hello_part.moc"

Compiling your KPart

To compile and link the code above, use

cmake . && make 

Using your KPart

To use your KPart, we need an object file, ending in .so. So, let's modify CMakeLists.txt a bit:

PROJECT( kdepart )
FIND_PACKAGE(KDE4 REQUIRED)
INCLUDE_DIRECTORIES(${KDE4_INCLUDES} .)

SET(kdepartSources main.cpp mypart.cpp)

KDE4_ADD_EXECUTABLE(kdepart ${kdepartSources})

TARGET_LINK_LIBRARIES(kdepart ${KDE4_KDEUI_LIBS}
  ${KDE4_KPARTS_LIBS})

set(kdepartplugin_PART_SRCS ${kdepartSources})

kde4_add_plugin(kdepartplugin ${kdepartSources})

target_link_libraries(kdepartplugin ${KDE4_KDEUI_LIBS}
  ${KDE4_KPARTS_LIBS} )

You can use konqueror to display your kpart: konqueror -> Settings -> Configure Konqueror -> Web browsing -> Plugins

Kontact integration

To integrate your KPart into kontact, you will need to have a .desktop file. This can be e.g. here:

$ ls /home/kde-devel/kde/share/kde4/services/kontact/
akregatorplugin.desktop     knotesplugin.desktop
akregatorplugin3.2.desktop  korganizerplugin.desktop
journalplugin.desktop       newstickerplugin.desktop
kaddressbookplugin.desktop  plannerplugin.desktop
karmplugin.desktop          specialdatesplugin.desktop
kmailplugin.desktop         summaryplugin.desktop
kmobiletools.desktop        todoplugin.desktop
knodeplugin.desktop         weatherplugin.desktop

You will also need your plugin, maybe here:

$ find /home/kde-devel/kde/lib/ -iname "karmpart*"
/home/kde-devel/kde/lib/kde4/karmpart.so

You will also need to make your KPart a subclass of Kontact::Plugin

See also