Step 1: Make your plugin loadable
For a plugin foo
, create a file foo.desktop
which contains TDevelop/Part in its list of ServiceTypes.
- See
parts/doctreeview/kdevdoctreeview.desktop
for an example.
If you install this file into $(kde_servicesdir)
, your plugin will automatically be loaded.
How to change the default loading
You can change the default loading by changing some settings in your foo.desktop
file:
- Set
X-TDevelop-Scope=
toGlobal
orProject
- Note: This property is not optional
- You can add a list of programming languages which are supported by your plugin
- If your plugin works with all languages leave the
X-TDevelop-ProgrammingLanguages=
field empty (optional)
- If your plugin works with all languages leave the
- You can add a list of keywords.
- The plugin will only be loaded if all keywords match with the
Keywords=
field in the projectfile (optional).
- The plugin will only be loaded if all keywords match with the
An example from the Java Debugger Plugin:
####################### X-TDevelop-Scope=Project X-TDevelop-ProgrammingLanguages=Java Keywords= ##########################
Step 2: Make the plugin accessible by the factory
Create a factory class FooFactory
which inherits KDevFactory
. Put a section
extern "C" { void *init_libfoo() { return new FooFactory; } }
into the source file, so that the factory can be accessed by KDE's library loader. Keep in mind that the name of the method init_libfoo()
is required for a library with the name libfoo.so
.
This may be simplified by the use of the K_EXPORT_COMPONENT_FACTORY
macro which is defined in klibloader.h
:
K_EXPORT_COMPONENT_FACTORY( libfoo, FooFactory );
- Note: Your factory must reimplement the
createPartObject()
method ofKDevFactory
and produce the part there.
See parts/doctreeview/doctreeviewfactory.cpp
for an example.
Step 3: Implement your part.
Your part must be derived from KDevPlugin
.
- KDevPlugin takes two arguments:
- 1) A parent argument. This also comes from
createPartObject()
. - 2) A name, which in turn is given to the
QObject
constructor.
- 1) A parent argument. This also comes from
How to access other IDE components
A part can access other components of the IDE via some accessors of KDevPlugin
:
- The application core via
core()
, - the build tools via
project()
, - the programming language specific stuff via
languageSupport()
, - the make frontend via
makeFrontend()
, - the part which displays appication output via
appFrontend()
, and finally - the symbol database via
classStore()
.
In order to see what these components provide, see lib/interfaces/kdev*.h
.
How to store user preferences
Parts can also store user preferences on a per-project basis. To this end, they can access a QDomDocument
representing the project file (which is stored as xml) via document()
.
Take attention to the issue that the project file usually is shared in a team of developers (e.g. via version control application CVS). So some user preferences might be very individual, and some may be valid for all of the team - project-wide so to speak.
That's why the TDevelop architecture makes a difference here and supports two files which will be stored in the project root directory. They are the project file (*.kdevelop) and the session (*.kdevses) file. The later is for individual settings, not to be thought to be shared.
Project file (*.kdevelop)
For your convenience, you don't have to use the quite complex DOM API. Strings can very easily be read from and written to this document using the DomUtil
class. Here, entries are identified by a 'path' in the document. You can think of the DOM document as representing a file system rooted in the dom
document node.
For example, the autoproject
part uses the statement
QString cflags = DomUtil::readEntry( *part->document(), "/kdevautoproject/cflags" );
to read the CFLAGS
variable set by the user, and uses the statement similar to
DomUtil::writeEntry( *part->document(), "kdevautoproject/cflags", "--no-exceptions" );
to write it back.
- Note: In order to avoid conflicts between different plugins, you should use your part name as top-level 'directory' in the configuration tree.
Project session file (*.kdevses)
The base class of all TDevelop plugins is KDevPlugin. It provides two virtual methods restorePartialProjectSession(..) and savePartialProjectSession(..) that you should reimplement in your special plugin to attach to session loading and saving.
When TDevelop loads or closes a project, the program's project session manager (class ProjectSession) calls them for each plugin. That manager gives a QDOM node to the plugin where it can read out or build up its partial DOM subtree with the session settings. That subtree will be stored in the .kdevses file by that session manager.
For example each programmer has set breakpoints in different files than the other ones of the team. So the debugger plugin saves them to project session file:
void DebuggerPart::savePartialProjectSession(QDomElement* el) { gdbBreakpointWidget->savePartialProjectSession(el); } void GDBBreakpointWidget::savePartialProjectSession(QDomElement* el) { QDomDocument domDoc = el->ownerDocument(); if (domDoc.isNull()) return; QDomElement breakpointListEl = domDoc.createElement("breakpointList"); for ( int row = 0; row < m_table->numRows(); row++ ) { BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control); Breakpoint* bp = btr->breakpoint(); QDomElement breakpointEl = domDoc.createElement("breakpoint"+QString::number(row)); breakpointEl.setAttribute("type", bp->type()); breakpointEl.setAttribute("location", bp->location(false)); breakpointEl.setAttribute("enabled", bp->isEnabled()); breakpointEl.setAttribute("condition", bp->conditional()); breakpointListEl.appendChild(breakpointEl); } if (!breakpointListEl.isNull()) el->appendChild(breakpointListEl); }
}
Note that the .kdevses is related to a project. User settings equal for all projects don't belong to here. You save them to ~/.trinity/share/config/tdeveloprc via class TDEConfig of the tdecore library.
Document your part in the way described at How to document TDevelop parts (doc/api/HowToDocument.dox file).