1
/** \file HowToAddPlugins.dox
2
* \brief How to extend KDevelop via plugins
5
/** \page howToAddPlugins How to extend KDevelop via plugins
7
\section createDesktop Step 1: Make your plugin loadable
9
For a plugin <code>foo</code>, create a file <code>foo.desktop</code> which contains KDevelop/Part in its list of ServiceTypes.
11
- See <code>parts/doctreeview/kdevdoctreeview.desktop</code> for an example.
14
If you install this file into <code>\$(kde_servicesdir)</code>, your plugin will automatically be loaded.
16
\subsection changeLoading How to change the default loading
18
You can change the default loading by changing some settings in your <code>foo.desktop</code> file:
20
- Set <code>X-KDevelop-Scope=</code> to <code>Global</code> or
22
- <b>Note:</b> This property is <i>not</i> optional
24
- You can add a list of programming languages which are supported by your
26
- If your plugin works with all languages leave the
27
<code>X-KDevelop-ProgrammingLanguages=</code> field empty
30
- You can add a list of keywords.
31
- The plugin will only be loaded if all keywords match with the
32
<code>Keywords=</code> field in the projectfile <i>(optional)</i>.
36
An example from the Java Debugger Plugin:
39
#######################
40
X-KDevelop-Scope=Project
41
X-KDevelop-ProgrammingLanguages=Java
43
##########################
47
\section createFactory Step 2: Make the plugin accessible by the factory
49
Create a factory class <code>FooFactory</code> which inherits
50
<code>KDevFactory</code>. Put a section
56
return new FooFactory;
61
into the source file, so that the factory can be accessed by KDE's library
62
loader. Keep in mind that the name of the method <code>init_libfoo()</code> is
63
required for a library with the name <code>libfoo.so</code>.
65
This may be simplified by the use of the
66
<code>K_EXPORT_COMPONENT_FACTORY</code> macro which is defined in
67
<code>klibloader.h</code>:
70
K_EXPORT_COMPONENT_FACTORY( libfoo, FooFactory );
73
- <i>Note:</i> Your factory must reimplement the
74
<code>createPartObject()</code> method of <code>KDevFactory</code> and
75
produce the part there.
78
See <code>parts/doctreeview/doctreeviewfactory.cpp</code> for an example.
81
\section implementPart Step 3: Implement your part.
83
Your part must be derived from <code>KDevPlugin</code>.
85
- KDevPlugin takes two arguments:
86
- 1) A <i>parent</i> argument. This also comes from
87
<code>createPartObject()</code>.
88
- 2) A <i>name</i>, which in turn is given to the <code>QObject</code>
93
\subsection accessIDE How to access other IDE components
95
A part can access other components of the IDE via some accessors
96
of <code>KDevPlugin</code>:
98
- The <i>application core</i> via <code>core()</code>,
99
- the <i>build tools</i> via <code>project()</code>,
100
- the <i>programming language specific stuff</i> via
101
<code>languageSupport()</code>,
102
- the <i>make frontend</i> via <code>makeFrontend()</code>,
103
- the part which displays <i>appication output</i> via
104
<code>appFrontend()</code>,
106
- the <i>symbol database</i> via <code>classStore()</code>.
109
In order to see what these components provide, see <code>lib/interfaces/kdev*.h</code>.
111
\subsection userPrefs How to store user preferences
113
Parts can also store user preferences on a per-project basis. To this
114
end, they can access a <code>QDomDocument</code> representing the project file
115
(which is stored as xml) via <code>document()</code>.
117
Take attention to the issue that the project file usually is shared in a team of
118
developers (e.g. via version control application CVS). So some user preferences might be
119
very individual, and some may be valid for all of the team - project-wide so to speak.
121
That's why the KDevelop architecture makes a difference here and supports two files
122
which will be stored in the project root directory. They are the project file (*.kdevelop)
123
and the session (*.kdevses) file. The later is for individual settings, not to be thought
126
\subsection domProject Project file (*.kdevelop)
128
For your convenience, you don't have to use the quite complex DOM API. Strings
129
can very easily be read from and written to this document using the
130
<code>DomUtil</code> class. Here, entries are identified by a 'path' in the
131
document. You can think of the DOM document as representing a file system
132
rooted in the <code>dom</code> document node.
134
For example, the <code>autoproject</code> part uses the statement
137
QString cflags = DomUtil::readEntry( *part->document(),
138
"/kdevautoproject/cflags" );
141
to read the <code>CFLAGS</code> variable set by the user, and uses the statement similar to
144
DomUtil::writeEntry( *part->document(),
145
"kdevautoproject/cflags",
151
- <i>Note:</i> In order to avoid conflicts between different plugins, you
152
should use your part name as top-level 'directory' in the configuration
156
\subsection sessionAccess Project session file (*.kdevses)
158
The base class of all KDevelop plugins is KDevPlugin. It provides two virtual methods
159
restorePartialProjectSession(..) and savePartialProjectSession(..)
160
that you should reimplement in your special plugin to attach to session loading and saving.
162
When KDevelop loads or closes a project, the program's project session manager
163
(class ProjectSession) calls them for each plugin. That manager gives a QDOM node to the
164
plugin where it can read out or build up its partial DOM subtree with the session settings.
165
That subtree will be stored in the .kdevses file by that session manager.
167
For example each programmer has set breakpoints in different files than the other ones of
168
the team. So the debugger plugin saves them to project session file:
171
void DebuggerPart::savePartialProjectSession(QDomElement* el)
173
gdbBreakpointWidget->savePartialProjectSession(el);
175
void GDBBreakpointWidget::savePartialProjectSession(QDomElement* el)
177
QDomDocument domDoc = el->ownerDocument();
178
if (domDoc.isNull()) return;
179
QDomElement breakpointListEl = domDoc.createElement("breakpointList");
180
for ( int row = 0; row < m_table->numRows(); row++ )
182
BreakpointTableRow* btr = (BreakpointTableRow *) m_table->item(row, Control);
183
Breakpoint* bp = btr->breakpoint();
184
QDomElement breakpointEl = domDoc.createElement("breakpoint"+QString::number(row));
185
breakpointEl.setAttribute("type", bp->type());
186
breakpointEl.setAttribute("location", bp->location(false));
187
breakpointEl.setAttribute("enabled", bp->isEnabled());
188
breakpointEl.setAttribute("condition", bp->conditional());
189
breakpointListEl.appendChild(breakpointEl);
191
if (!breakpointListEl.isNull()) el->appendChild(breakpointListEl);
197
Note that the .kdevses is related to a project. User settings equal for all projects don't
198
belong to here. You save them to ~/.kde/share/config/kdeveloprc via class KConfig of the
201
Document your part in the way described at \ref howToDocument (doc/api/HowToDocument.dox file).