• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • KDevelop Generic Shell
 

KDevelop Generic Shell

  • src
projectmanager.cpp
1#include <tqfile.h>
2#include <tqfileinfo.h>
3#include <tqdir.h>
4#include <tqdom.h>
5#include <tqstringlist.h>
6#include <tqptrlist.h>
7#include <tqvbox.h>
8#include <tqsize.h>
9#include <tqtimer.h>
10
11class TQDomDocument;
12
13#include <tdemessagebox.h>
14#include <kdebug.h>
15#include <tdelocale.h>
16#include <kservice.h>
17#include <ktrader.h>
18#include <tdefiledialog.h>
19#include <tdemainwindow.h>
20#include <tdeparts/componentfactory.h>
21#include <tdeaction.h>
22#include <tdeapplication.h>
23#include <tdecmdlineargs.h>
24#include <kprocess.h>
25#include <tdeglobal.h>
26#include <kstandarddirs.h>
27#include <tdeio/netaccess.h>
28#include <tdetempfile.h>
29#include <tdemenubar.h>
30#include <kstatusbar.h>
31#include <kiconloader.h>
32
33#include "kdevproject.h"
34#include "kdevlanguagesupport.h"
35#include "kdevplugin.h"
36#include "kdevcreatefile.h"
37#include "kdevversioncontrol.h"
38
39
40#include "toplevel.h"
41#include "core.h"
42#include "api.h"
43#include "plugincontroller.h"
44#include "partcontroller.h"
45#include "codemodel.h"
46// #include "partselectwidget.h"
47#include "languageselectwidget.h"
48#include "generalinfowidget.h"
49#include "projectsession.h"
50#include "domutil.h"
51#include "settings.h"
52
53#include "projectmanager.h"
54
55TQString ProjectInfo::sessionFile() const
56{
57 TQString sf = m_projectURL.path(-1);
58 sf.truncate(sf.length() - 8); // without ".kdevelop"
59 sf += "kdevses"; // suffix for a TDevelop session file
60 return sf;
61}
62
63TQString ProjectManager::projectDirectory( const TQString& path, bool absolute ) {
64 if(absolute)
65 return path;
66 KURL url(ProjectManager::getInstance()->projectFile(), path);
67 url.cleanPath();
68 return url.path(-1);
69}
70
71ProjectManager *ProjectManager::s_instance = 0;
72
73ProjectManager::ProjectManager()
74: m_info(0L)
75 ,m_pProjectSession(new ProjectSession)
76{
77}
78
79ProjectManager::~ProjectManager()
80{
81 delete m_pProjectSession;
82 delete m_info;
83}
84
85ProjectManager *ProjectManager::getInstance()
86{
87 if (!s_instance)
88 s_instance = new ProjectManager;
89 return s_instance;
90}
91
92void ProjectManager::createActions( TDEActionCollection* ac )
93{
94 TDEAction *action;
95
96 action = new TDEAction(i18n("&Open Project..."), "project_open", 0,
97 this, TQ_SLOT(slotOpenProject()),
98 ac, "project_open");
99 action->setToolTip( i18n("Open project"));
100 action->setWhatsThis(i18n("<b>Open project</b><p>Opens a KDevelop3 or KDevelop2 project."));
101
102 m_openRecentProjectAction =
103 new TDERecentFilesAction(i18n("Open &Recent Project"), 0,
104 this, TQ_SLOT(loadProject(const KURL &)),
105 ac, "project_open_recent");
106 m_openRecentProjectAction->setToolTip(i18n("Open recent project"));
107 m_openRecentProjectAction->setWhatsThis(i18n("<b>Open recent project</b><p>Opens recently opened project."));
108 m_openRecentProjectAction->loadEntries(kapp->config(), "RecentProjects");
109
110 m_closeProjectAction =
111 new TDEAction(i18n("C&lose Project"), "window-close",0,
112 this, TQ_SLOT(closeProject()),
113 ac, "project_close");
114 m_closeProjectAction->setEnabled(false);
115 m_closeProjectAction->setToolTip(i18n("Close project"));
116 m_closeProjectAction->setWhatsThis(i18n("<b>Close project</b><p>Closes the current project."));
117
118 m_projectOptionsAction = new TDEAction(i18n("Project &Options"), "configure", 0,
119 this, TQ_SLOT(slotProjectOptions()),
120 ac, "project_options" );
121 m_projectOptionsAction->setToolTip(i18n("Project options"));
122 m_projectOptionsAction->setWhatsThis(i18n("<b>Project options</b><p>Lets you customize project options."));
123 m_projectOptionsAction->setEnabled(false);
124}
125
126void ProjectManager::slotOpenProject()
127{
128 TDEConfig *config = kapp->config();
129 config->setGroup("General Options");
130 TQString defaultProjectsDir = config->readPathEntry("DefaultProjectsDir", TQDir::homeDirPath()+"/");
131
132 KURL url = KFileDialog::getOpenURL(defaultProjectsDir,
133 i18n("*.kdevelop|KDevelop 3 Project Files\n"
134 "*.kdevprj|KDevelop 2 Project Files"),
135 TopLevel::getInstance()->main(), i18n("Open Project") );
136
137 if( url.isEmpty() )
138 return;
139
140 if (url.path().endsWith("kdevprj"))
141 loadKDevelop2Project( url );
142 else
143 loadProject( url );
144}
145
146void ProjectManager::slotProjectOptions()
147{
148 KDialogBase dlg(KDialogBase::IconList, i18n("Project Options"),
149 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, TopLevel::getInstance()->main(),
150 "project options dialog");
151
152 TQVBox *box = dlg.addVBoxPage( i18n("General"), i18n("General"), BarIcon( "tdevelop", TDEIcon::SizeMedium ) );
153 GeneralInfoWidget *g = new GeneralInfoWidget(*API::getInstance()->projectDom(), box, "general informations widget");
154 connect (&dlg, TQ_SIGNAL(okClicked()), g, TQ_SLOT(accept()));
155
156 TDEConfig *config = kapp->config();
157 config->setGroup("Project Settings Dialog");
158 int height = config->readNumEntry( "Height", 600 );
159 int width = config->readNumEntry( "Width", 800 );
160
161 dlg.resize( width, height );
162
163 Core::getInstance()->doEmitProjectConfigWidget(&dlg);
164 dlg.exec();
165
166 saveProjectFile();
167
168 config->setGroup("Project Settings Dialog");
169 config->writeEntry( "Height", dlg.size().height() );
170 config->writeEntry( "Width", dlg.size().width() );
171}
172
173void ProjectManager::loadSettings()
174{
175}
176
177void ProjectManager::saveSettings()
178{
179 TDEConfig *config = kapp->config();
180
181 if (projectLoaded())
182 {
183 config->setGroup("General Options");
184 config->writePathEntry("Last Project", ProjectManager::getInstance()->projectFile().url());
185 }
186
187 m_openRecentProjectAction->saveEntries(config, "RecentProjects");
188}
189
190void ProjectManager::loadDefaultProject()
191{
192 TDEConfig *config = kapp->config();
193 config->setGroup("General Options");
194 TQString project = config->readPathEntry("Last Project");
195 bool readProject = config->readBoolEntry("Read Last Project On Startup", true);
196 if (!project.isEmpty() && readProject)
197 {
198 loadProject(KURL(project));
199 }
200}
201
202bool ProjectManager::loadProject(const KURL &projectURL)
203{
204 KURL url = projectURL;
205
206 if (!url.isValid())
207 return false;
208
209 if (url.isLocalFile())
210 {
211 TQDir dir(url.path());
212 TQString can_path = dir.canonicalPath();
213 //if the directory doesn't exist, the returned string is null which confuses the user later on. so better short-cut here
214 if(can_path.isNull())
215 return false;
216 else
217 url.setPath(can_path);
218 }
219
220 // reopen the already opened project?
221 if( projectLoaded() && url.path() == projectFile().path() )
222 {
223 if (KMessageBox::questionYesNo(TopLevel::getInstance()->main(),
224 i18n("Are you sure you want to reopen the current project?"), TQString(), i18n("Reopen"), i18n("Do Not Reopen")) == KMessageBox::No)
225 return false;
226 }
227
228 TopLevel::getInstance()->main()->menuBar()->setEnabled( false );
229 kapp->setOverrideCursor( waitCursor );
230
231 if( projectLoaded() && !closeProject() )
232 {
233 m_openRecentProjectAction->setCurrentItem( -1 );
234 TopLevel::getInstance()->main()->menuBar()->setEnabled( true );
235 kapp->restoreOverrideCursor();
236 return false;
237 }
238
239 m_info = new ProjectInfo;
240 m_info->m_projectURL = url;
241
242 TQTimer::singleShot( 0, this, TQ_SLOT(slotLoadProject()) );
243
244 // no one cares about this value
245 return true;
246}
247
248void ProjectManager::slotLoadProject( )
249{
250 if( !loadProjectFile() )
251 {
252 m_openRecentProjectAction->removeURL(m_info->m_projectURL);
253 delete m_info; m_info = 0;
254 saveSettings();
255 TopLevel::getInstance()->main()->menuBar()->setEnabled( true );
256 kapp->restoreOverrideCursor();
257 return;
258 }
259
260 getGeneralInfo();
261
262 if( !loadLanguageSupport(m_info->m_language) ) {
263 delete m_info; m_info = 0;
264 TopLevel::getInstance()->main()->menuBar()->setEnabled( true );
265 kapp->restoreOverrideCursor();
266 return;
267 }
268
269 if( !loadProjectPart() ) {
270 unloadLanguageSupport();
271 delete m_info; m_info = 0;
272 API::getInstance()->setProjectDom( 0 );
273 TopLevel::getInstance()->main()->menuBar()->setEnabled( true );
274 kapp->restoreOverrideCursor();
275 return;
276 }
277
278 TopLevel::getInstance()->statusBar()->message( i18n("Changing plugin profile...") );
279 m_oldProfileName = PluginController::getInstance()->changeProfile(m_info->m_profileName);
280
281 TopLevel::getInstance()->statusBar()->message( i18n("Loading project plugins...") );
282 loadLocalParts();
283
284 // shall we try to load a session file from network?? Probably not.
285 if (m_info->m_projectURL.isLocalFile())
286 {
287 // first restore the project session stored in a .kdevses file
288 if (!m_pProjectSession->restoreFromFile(m_info->sessionFile(), PluginController::getInstance()->loadedPlugins() ))
289 {
290 kdWarning() << i18n("error during restoring of the TDevelop session !") << endl;
291 }
292 }
293 m_openRecentProjectAction->addURL(projectFile(), projectName()); // KDE >= 3.5.x
294 m_closeProjectAction->setEnabled(true);
295 m_projectOptionsAction->setEnabled(true);
296
297 Core::getInstance()->doEmitProjectOpened();
298
299 TopLevel::getInstance()->main()->menuBar()->setEnabled( true );
300 kapp->restoreOverrideCursor();
301
302 TopLevel::getInstance()->statusBar()->message( i18n("Project loaded."), 3000 );
303
304 return;
305}
306
307
308bool ProjectManager::closeProject( bool exiting )
309{
310 if( !projectLoaded() )
311 return true;
312
313 // save the session if it is a local file
314 if (m_info->m_projectURL.isLocalFile())
315 {
316 m_pProjectSession->saveToFile(m_info->sessionFile(), PluginController::getInstance()->loadedPlugins() );
317 }
318
319 if ( !PartController::getInstance()->querySaveFiles() )
320 return false;
321
322 Core::getInstance()->doEmitProjectClosed();
323
324 PluginController::getInstance()->unloadProjectPlugins();
325 PluginController::getInstance()->changeProfile(m_oldProfileName);
326 unloadLanguageSupport();
327 unloadProjectPart();
328
330 saveProjectFile();
331
332 API::getInstance()->setProjectDom(0);
333 API::getInstance()->codeModel()->wipeout();
334
335 delete m_info;
336 m_info = 0;
337
338 m_closeProjectAction->setEnabled(false);
339 m_projectOptionsAction->setEnabled(false);
340
341 if ( !exiting )
342 {
343 PartController::getInstance()->slotCloseAllWindows();
344 }
345
346 return true;
347}
348
349bool ProjectManager::loadProjectFile()
350{
351 TQString path;
352 if (!TDEIO::NetAccess::download(m_info->m_projectURL, path, 0)) {
353 KMessageBox::sorry(TopLevel::getInstance()->main(),
354 i18n("Could not read project file: %1").arg(m_info->m_projectURL.prettyURL()));
355 return false;
356 }
357
358 TQFile fin(path);
359 if (!fin.open(IO_ReadOnly))
360 {
361 KMessageBox::sorry(TopLevel::getInstance()->main(),
362 i18n("Could not read project file: %1").arg(m_info->m_projectURL.prettyURL()));
363 return false;
364 }
365
366 int errorLine, errorCol;
367 TQString errorMsg;
368 if (!m_info->m_document.setContent(&fin, &errorMsg, &errorLine, &errorCol))
369 {
370 KMessageBox::sorry(TopLevel::getInstance()->main(),
371 i18n("This is not a valid project file.\n"
372 "XML error in line %1, column %2:\n%3")
373 .arg(errorLine).arg(errorCol).arg(errorMsg));
374 fin.close();
375 TDEIO::NetAccess::removeTempFile(path);
376 return false;
377 }
378 if (m_info->m_document.documentElement().nodeName() != "kdevelop")
379 {
380 KMessageBox::sorry(TopLevel::getInstance()->main(),
381 i18n("This is not a valid project file."));
382 fin.close();
383 TDEIO::NetAccess::removeTempFile(path);
384 return false;
385 }
386
387 fin.close();
388 TDEIO::NetAccess::removeTempFile(path);
389
390 API::getInstance()->setProjectDom(&m_info->m_document);
391
392 return true;
393}
394
395bool ProjectManager::saveProjectFile()
396{
397 Q_ASSERT( API::getInstance()->projectDom() );
398
399 if (m_info->m_projectURL.isLocalFile()) {
400 TQFile fout(m_info->m_projectURL.path());
401 if( !fout.open(IO_WriteOnly) ) {
402 KMessageBox::sorry(TopLevel::getInstance()->main(), i18n("Could not write the project file."));
403 return false;
404 }
405
406 TQTextStream stream(&fout);
407 API::getInstance()->projectDom()->save(stream, 2);
408 fout.close();
409 } else {
410 KTempFile fout(TQString::fromLatin1("kdevelop3"));
411 fout.setAutoDelete(true);
412 if (fout.status() != 0) {
413 KMessageBox::sorry(TopLevel::getInstance()->main(), i18n("Could not write the project file."));
414 return false;
415 }
416 API::getInstance()->projectDom()->save(*(fout.textStream()), 2);
417 fout.close();
418 TDEIO::NetAccess::upload(fout.name(), m_info->m_projectURL, 0);
419 }
420
421 return true;
422}
423
424static TQString getAttribute(TQDomElement elem, TQString attr)
425{
426 TQDomElement el = elem.namedItem(attr).toElement();
427 return el.firstChild().toText().data();
428}
429
430static void getAttributeList(TQDomElement elem, TQString attr, TQString tag, TQStringList &list)
431{
432 list.clear();
433
434 TQDomElement el = elem.namedItem(attr).toElement();
435 TQDomElement item = el.firstChild().toElement();
436 while (!item.isNull())
437 {
438 if (item.tagName() == tag)
439 list << item.firstChild().toText().data();
440 item = item.nextSibling().toElement();
441 }
442}
443
444void ProjectManager::getGeneralInfo()
445{
446 TQDomElement docEl = m_info->m_document.documentElement();
447 TQDomElement generalEl = docEl.namedItem("general").toElement();
448
449 m_info->m_projectPlugin = getAttribute(generalEl, "projectmanagement");
450 m_info->m_vcsPlugin = getAttribute(generalEl, "versioncontrol");
451 m_info->m_language = getAttribute(generalEl, "primarylanguage");
452 m_info->m_projectName = getAttribute(generalEl, "projectname");
453 if( m_info->m_projectName.isEmpty() )
454 {
455 m_info->m_projectName = m_info->m_projectURL.filename();
456 m_info->m_projectName = m_info->m_projectName.left(m_info->m_projectName.length()-TQString(".kdevelop").length());
457 TQDomElement prjname = m_info->m_document.createElement("projectname");
458 prjname.appendChild( m_info->m_document.createTextNode( m_info->m_projectName) );
459 generalEl.appendChild( prjname );
460 }
461
462 getAttributeList(generalEl, "ignoreparts", "part", m_info->m_ignoreParts);
463 getAttributeList(generalEl, "keywords", "keyword", m_info->m_keywords);
464
465 //FIXME: adymo: workaround for those project templates without "profile" element
466// m_info->m_profileName = getAttribute(generalEl, "profile");
467 TQDomElement el = generalEl.namedItem("profile").toElement();
468 if (el.isNull())
469// m_info->m_profileName = profileByAttributes(m_info->m_language, m_info->m_keywords);
470 m_info->m_profileName = Settings::profileByAttributes(m_info->m_language, m_info->m_keywords);
471 else
472 m_info->m_profileName = el.firstChild().toText().data();
473}
474
475bool ProjectManager::loadProjectPart()
476{
477 KService::Ptr projectService = KService::serviceByDesktopName(m_info->m_projectPlugin);
478 if (!projectService) {
479 // this is for backwards compatibility with pre-alpha6 projects
480 projectService = KService::serviceByDesktopName(m_info->m_projectPlugin.lower());
481 }
482 if (!projectService) {
483 KMessageBox::sorry(TopLevel::getInstance()->main(),
484 i18n("No project management plugin %1 found.")
485 .arg(m_info->m_projectPlugin));
486 return false;
487 }
488
489 KDevProject *projectPart = KParts::ComponentFactory
490 ::createInstanceFromService< KDevProject >( projectService, API::getInstance(), 0,
491 PluginController::argumentsFromService( projectService ) );
492 if ( !projectPart ) {
493 KMessageBox::sorry(TopLevel::getInstance()->main(),
494 i18n("Could not create project management plugin %1.")
495 .arg(m_info->m_projectPlugin));
496 return false;
497 }
498
499 API::getInstance()->setProject( projectPart );
500
501 TQDomDocument& dom = *API::getInstance()->projectDom();
502 TQString path = DomUtil::readEntry(dom,"/general/projectdirectory", ".");
503 bool absolute = DomUtil::readBoolEntry(dom,"/general/absoluteprojectpath",false);
504 TQString projectDir = projectDirectory( path, absolute );
505 kdDebug(9000) << "projectDir: " << projectDir << " projectName: " << m_info->m_projectName << endl;
506
507 projectPart->openProject(projectDir, m_info->m_projectName);
508
509 PluginController::getInstance()->integratePart( projectPart );
510
511 return true;
512}
513
514void ProjectManager::unloadProjectPart()
515{
516 KDevProject *projectPart = API::getInstance()->project();
517 if( !projectPart ) return;
518 PluginController::getInstance()->removePart( projectPart );
519 projectPart->closeProject();
520 delete projectPart;
521 API::getInstance()->setProject(0);
522}
523
524bool ProjectManager::loadLanguageSupport(const TQString& lang)
525{
526 kdDebug(9000) << "Looking for language support for " << lang << endl;
527
528 if (lang == m_info->m_activeLanguage)
529 {
530 kdDebug(9000) << "Language support already loaded" << endl;
531 return true;
532 }
533
534 TDETrader::OfferList languageSupportOffers =
535 TDETrader::self()->query(TQString::fromLatin1("TDevelop/LanguageSupport"),
536 TQString::fromLatin1("[X-TDevelop-Language] == '%1' and [X-TDevelop-Version] == %2").arg(lang).arg(TDEVELOP_PLUGIN_VERSION));
537
538 if (languageSupportOffers.isEmpty()) {
539 KMessageBox::sorry(TopLevel::getInstance()->main(),
540 i18n("No language plugin for %1 found.")
541 .arg(lang));
542 return false;
543 }
544
545 KService::Ptr languageSupportService = *languageSupportOffers.begin();
546 KDevLanguageSupport *langSupport = KParts::ComponentFactory
547 ::createInstanceFromService<KDevLanguageSupport>( languageSupportService,
548 API::getInstance(),
549 0,
550 PluginController::argumentsFromService( languageSupportService ) );
551
552 if ( !langSupport ) {
553 KMessageBox::sorry(TopLevel::getInstance()->main(),
554 i18n("Could not create language plugin for %1.")
555 .arg(lang));
556 return false;
557 }
558
559 API::getInstance()->setLanguageSupport( langSupport );
560 PluginController::getInstance()->integratePart( langSupport );
561 m_info->m_activeLanguage = lang;
562 kdDebug(9000) << "Language support for " << lang << " successfully loaded." << endl;
563 return true;
564}
565
566void ProjectManager::unloadLanguageSupport()
567{
568 KDevLanguageSupport *langSupport = API::getInstance()->languageSupport();
569 if( !langSupport ) return;
570 kdDebug(9000) << "Language support for " << langSupport->name() << " unloading..." << endl;
571 PluginController::getInstance()->removePart( langSupport );
572 delete langSupport;
573 API::getInstance()->setLanguageSupport(0);
574}
575
576void ProjectManager::loadLocalParts()
577{
578 // Make sure to refresh load/ignore lists
579 getGeneralInfo();
580
581 PluginController::getInstance()->unloadPlugins( m_info->m_ignoreParts );
582 PluginController::getInstance()->loadProjectPlugins( m_info->m_ignoreParts );
583 PluginController::getInstance()->loadGlobalPlugins( m_info->m_ignoreParts );
584}
585
586KURL ProjectManager::projectFile() const
587{
588 if (!m_info)
589 return KURL();
590 return m_info->m_projectURL;
591}
592
593TQString ProjectManager::projectName() const
594{
595 if (!m_info) return TQString();
596
597 return m_info->m_projectName;
598}
599
600bool ProjectManager::projectLoaded() const
601{
602 return m_info != 0;
603}
604
605ProjectSession* ProjectManager::projectSession() const
606{
607 return m_pProjectSession;
608}
609
610bool ProjectManager::loadKDevelop2Project( const KURL & url )
611{
612 if( !url.isValid() || !url.isLocalFile() ){
613 KMessageBox::sorry(0, i18n("Invalid URL."));
614 return false;
615 }
616
617 TQString cmd = TDEGlobal::dirs()->findExe( "kdevprj2kdevelop" );
618 if (cmd.isEmpty()) {
619 KMessageBox::sorry(0, i18n("You do not have 'kdevprj2kdevelop' installed."));
620 return false;
621 }
622
623 TQFileInfo fileInfo( url.path() );
624
625 KShellProcess proc( "/bin/sh" );
626 proc.setWorkingDirectory( fileInfo.dirPath(true) );
627 proc << "perl" << cmd << KShellProcess::quote( url.path() );
628 proc.start( TDEProcess::Block );
629
630 TQString projectFile = fileInfo.dirPath( true ) + "/" + fileInfo.baseName() + ".kdevelop";
631 return loadProject( KURL(projectFile) );
632}
633
634// TQString ProjectManager::profileByAttributes(const TQString &language, const TQStringList &keywords)
635// {
636// TDEConfig config(locate("data", "tdevelop/profiles/projectprofiles"));
637// config.setGroup(language);
638//
639// TQStringList profileKeywords = TQStringList::split("/", "Empty");
640// if (config.hasKey("Keywords"))
641// profileKeywords = config.readListEntry("Keywords");
642//
643// int idx = 0;
644// for (TQStringList::const_iterator it = profileKeywords.constBegin();
645// it != profileKeywords.constEnd(); ++it)
646// {
647// if (keywords.contains(*it))
648// {
649// idx = profileKeywords.findIndex(*it);
650// break;
651// }
652// }
653//
654// TQStringList profiles;
655// if (config.hasKey("Profiles"))
656// {
657// profiles = config.readListEntry("Profiles");
658// kdDebug() << "IDX: " << idx << " PROFILE: " << profiles[idx] << endl;
659// return profiles[idx];
660// }
661// return "TDevelop";
662// }
663
664#include "projectmanager.moc"
ProjectManager
Project manager.
Definition projectmanager.h:41
ProjectManager::closeProject
bool closeProject(bool exiting=false)
Definition projectmanager.cpp:308
ProjectSession
This class stores and restores the last situation before the certain project was closed.
Definition projectsession.h:36
TopLevel::getInstance
static KDevMainWindow * getInstance()
Get a pointer to the single KDevTopLevel object.
Definition toplevel.cpp:18

KDevelop Generic Shell

Skip menu "KDevelop Generic Shell"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

KDevelop Generic Shell

Skip menu "KDevelop Generic Shell"
  • buildtools
  •   lib
  •     base
  •     parsers
  •       autotools
  •       qmake
  •     widgets
  •   api
  • languages
  •   lib
  •     debugger
  •     designer_integration
  •     interfaces
  • lib
  •   catalog
  •   interfaces
  •     extensions
  •     external
  •     extras
  •   util
  •   widgets
  •     propeditor
  • parts
  •   documentation
  •     interfaces
  • src
  •   profileengine
  •     lib
Generated for KDevelop Generic Shell by doxygen 1.15.0
This website is maintained by Timothy Pearson.