KDevelop API Documentation

kdevdocumentationplugin.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 by Alexander Dymo <cloudtemple@mksat.net>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 #include "kdevdocumentationplugin.h"
00020 
00021 #include <qfile.h>
00022 #include <qpainter.h>
00023 #include <qstyle.h>
00024 #include <qheader.h>
00025 #include <qtextstream.h>
00026 
00027 #include <kstandarddirs.h>
00028 #include <kiconloader.h>
00029 #include <kconfig.h>
00030 #include <kdebug.h>
00031 #include <kdirwatch.h>
00032 #include <klocale.h>
00033 
00034 //class DocumentationItem
00035 
00036 DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListView *parent,
00037     const QString &name)
00038     :KListViewItem(parent, name), m_type(type)
00039 {
00040     init();
00041 }
00042 
00043 DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListViewItem *parent,
00044     const QString &name)
00045     :KListViewItem(parent, name), m_type(type)
00046 {
00047     init();
00048 }
00049 
00050 DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListView *parent, 
00051     KListViewItem *after, const QString &name)
00052     :KListViewItem(parent, after, name), m_type(type)
00053 {
00054     init();
00055 }
00056 
00057 DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListViewItem * parent,
00058     KListViewItem * after, const QString & name )
00059     :KListViewItem(parent, after, name), m_type(type)
00060 {
00061     init();
00062 }
00063 
00064 
00065 void DocumentationItem::init( )
00066 {
00067     QString icon;
00068     
00069     switch (m_type)
00070     {
00071         case Collection:
00072         case Catalog:
00073             icon = "folder";
00074             break;
00075         case Book:
00076             icon = "contents";
00077             break;
00078         default:
00079             icon = "document";
00080     }
00081     
00082     setPixmap(0, SmallIcon(icon));
00083 }
00084 
00085 
00086 
00087 
00088 
00089 //class DocumentationCatalogItem
00090 
00091   
00092 DocumentationCatalogItem::DocumentationCatalogItem(DocumentationPlugin* plugin,
00093     KListView *parent, const QString &name)
00094     :DocumentationItem(DocumentationItem::Catalog, parent, name), m_plugin(plugin),
00095     isLoaded(false), isActivated(false), m_isProjectDocumentationItem(false)
00096 {
00097     setExpandable(true);
00098     m_plugin->addCatalog(this);
00099 }
00100 
00101 DocumentationCatalogItem::DocumentationCatalogItem(DocumentationPlugin* plugin,
00102     DocumentationItem *parent, const QString &name)
00103     :DocumentationItem(DocumentationItem::Catalog, parent, name), m_plugin(plugin),
00104     isLoaded(false), isActivated(false), m_isProjectDocumentationItem(false)
00105 {
00106     setExpandable(true);
00107     m_plugin->addCatalog(this);
00108 }
00109 
00110 DocumentationCatalogItem::~ DocumentationCatalogItem( )
00111 {
00112     m_plugin->clearCatalog(this);
00113 }
00114 
00115 void DocumentationCatalogItem::setOpen(bool o)
00116 {
00117     if (o)
00118     {
00119         load();
00120     }
00121     DocumentationItem::setOpen(o);
00122 }
00123 
00124 void DocumentationCatalogItem::load()
00125 {
00126 if(isLoaded)
00127 return;
00128 
00129         plugin()->createTOC(this);
00130         isLoaded = true;
00131 }
00132 
00133 void DocumentationCatalogItem::activate()
00134 {
00135     if (!isActivated)
00136     {
00137         plugin()->setCatalogURL(this);
00138         isActivated = true;
00139     }
00140     DocumentationItem::activate();
00141 }
00142 
00143 
00144 
00145 
00146 //class IndexItemProto
00147 
00148 IndexItemProto::IndexItemProto(DocumentationPlugin *plugin, DocumentationCatalogItem *catalog, 
00149     IndexBox *listbox, const QString &text, const QString &description)
00150     : m_listbox(listbox), m_text(text), m_description(description)
00151 {
00152     plugin->indexes[catalog].append(this);
00153     m_listbox->addIndexItem(this);
00154 }
00155 
00156 IndexItemProto::~IndexItemProto()
00157 {
00158     m_listbox->removeIndexItem(this);
00159 }
00160 
00161 
00162 //class IndexItem
00163 
00164 IndexItem::IndexItem(IndexBox *listbox, const QString &text)
00165     :QListBoxText(listbox, text), m_listbox(listbox)
00166 {
00167 }
00168 
00169 IndexItem::List IndexItem::urls() const
00170 {
00171     List urlList;
00172     QValueList<IndexItemProto*> itemProtos = m_listbox->items[text()];
00173     for (QValueList<IndexItemProto*>::const_iterator it = itemProtos.begin();
00174         it != itemProtos.end(); ++it)
00175         urlList.append(qMakePair((*it)->description(), (*it)->url()));
00176     return urlList;
00177 }
00178 
00179 
00180 
00181 
00182 //class ConfigurationItem
00183 
00184 ConfigurationItem::ConfigurationItem(QListView *parent, const QString &title, const QString &url,
00185     bool indexPossible, bool fullTextSearchPossible)
00186     :QCheckListItem(parent, "", QCheckListItem::CheckBox), m_title(title), m_url(url),
00187     m_origTitle(title), m_contents(true), m_index(false), m_fullTextSearch(false),
00188     m_indexPossible(indexPossible), m_fullTextSearchPossible(fullTextSearchPossible)
00189 {
00190     setText(3, m_title);
00191     setText(4, m_url);
00192 }
00193 
00194 void ConfigurationItem::paintCell(QPainter *p, const QColorGroup &cg, int column,
00195     int width, int align)
00196 {
00197     if ( (column == 0) || (column == 1) || (column == 2) )
00198     {
00199         if ( !p )
00200             return;
00201     
00202         QListView *lv = listView();
00203         if ( !lv )
00204             return;
00205     
00206         const BackgroundMode bgmode = lv->viewport()->backgroundMode();
00207         const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode );
00208         p->fillRect(0, 0, width, height(), cg.brush(crole));
00209 
00210         QFontMetrics fm(lv->fontMetrics());
00211         int boxsize = lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv);
00212         int marg = lv->itemMargin();
00213         int styleflags = QStyle::Style_Default;
00214                 
00215         if (((column == 0) && m_contents) || ((column == 1) && m_index) || ((column == 2) && m_fullTextSearch))
00216             styleflags |= QStyle::Style_On;
00217         else
00218             styleflags |= QStyle::Style_Off;
00219         if ((column == 0) || ((column == 1) && m_indexPossible) || ((column == 2) && m_fullTextSearchPossible))
00220             styleflags |= QStyle::Style_Enabled;
00221 
00222         int x = 0;
00223         int y = 0;
00224         x += 3;
00225         if (align & AlignVCenter)
00226             y = ((height() - boxsize) / 2) + marg;
00227         else
00228             y = (fm.height() + 2 + marg - boxsize) / 2;
00229 
00230         QStyleOption opt(this);
00231         lv->style().drawPrimitive(QStyle::PE_CheckListIndicator, p,
00232             QRect(x, y, boxsize, fm.height() + 2 + marg), cg, styleflags, opt);
00233                
00234         return;
00235     }
00236     QListViewItem::paintCell(p, cg, column, width, align);
00237 }
00238 
00239 int ConfigurationItem::width(const QFontMetrics &fm, const QListView *lv, int c) const
00240 {
00241     if ((c == 0) || (c == 1) || (c == 2))
00242         return lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv) + 4;
00243     return QListViewItem::width(fm, lv, c);
00244 }
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 //class DocumentationPlugin
00254 
00255 DocumentationPlugin::DocumentationPlugin(KConfig *pluginConfig, QObject *parent, const char *name)
00256     :QObject(parent, name), config(pluginConfig), m_indexCreated(false)
00257 {
00258 }
00259 
00260 DocumentationPlugin::~DocumentationPlugin()
00261 {
00262 }
00263 
00264 void DocumentationPlugin::autoSetup()
00265 {
00266     config->setGroup("General");    
00267     if ( ! config->readBoolEntry("Autosetup", false) )
00268     {
00269         autoSetupPlugin();
00270         config->setGroup("General");
00271         config->writeEntry("Autosetup", true);
00272         config->sync();
00273     }
00274 }
00275 
00276 void DocumentationPlugin::reload()
00277 {
00278     clear();
00279     for (QValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin();
00280         it != catalogs.end(); ++it)
00281     {
00282         createTOC(*it);
00283     }
00284 }
00285 
00286 void DocumentationPlugin::clear()
00287 {
00288     for (QValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin();
00289         it != catalogs.end(); ++it)
00290     {
00291         clearCatalog(*it);
00292     }
00293 }
00294 
00295 void DocumentationPlugin::clearCatalog(DocumentationCatalogItem *item)
00296 {
00297     //clear named catalog map
00298     for (QMap<QString, DocumentationCatalogItem*>::iterator it = namedCatalogs.begin();
00299         it != namedCatalogs.end(); ++it)
00300     {
00301         if (it.data() == item)
00302             namedCatalogs.remove(it);
00303     }
00304     //clear indexes for catalog
00305     QValueList<IndexItemProto *> idx = indexes[item];
00306     for (QValueList<IndexItemProto *>::iterator it = idx.begin(); it != idx.end(); ++it)
00307     {
00308         delete *it;
00309     }
00310     indexes.remove(item);
00311 
00312     //remove catalog
00313     catalogs.remove(item);
00314 }
00315 
00316 void DocumentationPlugin::createIndex(IndexBox *index)
00317 {
00318     if (m_indexCreated)
00319         return;
00320     
00321     for (QValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin();
00322         it != catalogs.end(); ++it)
00323     {
00324         loadIndex(index, *it);
00325     }
00326     m_indexCreated = true;
00327 }
00328 
00329 void DocumentationPlugin::cacheIndex(DocumentationCatalogItem *item)
00330 {
00331     kdDebug() << "Creating index cache for " << item->text(0) << endl;
00332     
00333     QString cacheName = locateLocal("data", QString("kdevdocumentation/index/cache_") + item->text(0));
00334     QFile cacheFile(cacheName);
00335     if (!cacheFile.open(IO_WriteOnly))
00336         return;
00337     
00338     QTextStream str(&cacheFile);
00339     str.setEncoding(QTextStream::Unicode);
00340     str << CACHE_VERSION << endl;
00341 
00342     QValueList<IndexItemProto*> catalogIndexes = indexes[item];
00343     for (QValueList<IndexItemProto*>::const_iterator it = catalogIndexes.constBegin();
00344         it != catalogIndexes.constEnd(); ++it)
00345     {
00346         str << (*it)->text() << endl;
00347         str << (*it)->description() << endl;
00348         str << (*it)->url().url() << endl;
00349     }
00350    
00351     cacheFile.close();
00352 }
00353 
00354 bool DocumentationPlugin::loadCachedIndex(IndexBox *index, DocumentationCatalogItem *item)
00355 {
00356     QString cacheName = locateLocal("data", QString("kdevdocumentation/index/cache_") + item->text(0));
00357     QFile cacheFile(cacheName);
00358     if (!cacheFile.open(IO_ReadOnly))
00359         return false;
00360 
00361     kdDebug() << "Using cached index for item: " << item->text(0) << endl;
00362     
00363     QTextStream str(&cacheFile);
00364     str.setEncoding(QTextStream::Unicode);
00365     QString cache = str.read();
00366     QStringList cacheList = QStringList::split("\n", cache, true);
00367     QString ver = cacheList.first();
00368     if (ver != CACHE_VERSION)
00369     {
00370         kdDebug() << "Wrong cache version: " << ver << endl;
00371         return false;
00372     }
00373     QStringList::const_iterator it = cacheList.begin();
00374     it++;
00375     QString s[3]; int c = 0;
00376     for (; it != cacheList.end(); ++it)
00377     {
00378         s[c] = *it;
00379         if (c == 2)
00380         {
00381             IndexItemProto *ii = new IndexItemProto(this, item, index, s[0], s[1]);
00382             ii->addURL(KURL(s[2]));
00383             c = 0;
00384         }
00385         else c++;
00386     }
00387     cacheFile.close();
00388     
00389     return true;
00390 }
00391 
00392 void DocumentationPlugin::addCatalog(DocumentationCatalogItem *item)
00393 {
00394     catalogs.append(item);
00395     namedCatalogs[item->text(0)] = item;
00396 //    indexes[item] = QValueList<IndexItem*>();
00397 }
00398 
00399 void DocumentationPlugin::addCatalogConfiguration(KListView *configurationView,
00400     const QString &title, const QString &url)
00401 {
00402     new ConfigurationItem(configurationView, title, url, 
00403         hasCapability(Index), hasCapability(FullTextSearch));
00404 }
00405 
00406 void DocumentationPlugin::editCatalogConfiguration(ConfigurationItem *configurationItem,
00407     const QString &title, const QString &url)
00408 {
00409     configurationItem->setTitle(title);
00410     configurationItem->setURL(url);
00411 }
00412 
00413 void DocumentationPlugin::deleteCatalogConfiguration(const ConfigurationItem *const configurationItem)
00414 {
00415     deletedConfigurationItems << configurationItem->title();
00416 }
00417 
00418 void DocumentationPlugin::clearCatalogIndex(DocumentationCatalogItem *item)
00419 {
00420     //clear indexes for catalog
00421     QValueList<IndexItemProto *> idx = indexes[item];
00422     for (QValueList<IndexItemProto *>::iterator it = idx.begin(); it != idx.end(); ++it)
00423     {
00424         delete *it;
00425     }
00426     indexes.remove(item);
00427 }
00428 
00429 void DocumentationPlugin::loadIndex(IndexBox *index, DocumentationCatalogItem *item)
00430 {
00431     if (!indexEnabled(item))
00432         return;
00433     if (!needRefreshIndex(item) && loadCachedIndex(index, item))
00434         return;
00435     createIndex(index, item);
00436     cacheIndex(item);
00437 }
00438 
00439 void DocumentationPlugin::init(KListView *contents)
00440 {
00441     config->setGroup("Locations");
00442     QMap<QString, QString> entryMap = config->entryMap("Locations");
00443     
00444     for (QMap<QString, QString>::const_iterator it = entryMap.begin();
00445         it != entryMap.end(); ++it)
00446     {
00447         if (catalogEnabled(it.key()))
00448             createCatalog(contents, it.key(), config->readPathEntry(it.key()));
00449     }
00450 }
00451 
00452 void DocumentationPlugin::reinit(KListView *contents, IndexBox *index, QStringList restrictions)
00453 {
00454     config->setGroup("Locations");
00455     QMap<QString, QString> entryMap = config->entryMap("Locations");
00456 
00457     //remove deleted in configuration catalogs
00458     for (QStringList::const_iterator it = deletedConfigurationItems.constBegin();
00459         it != deletedConfigurationItems.constEnd(); ++it)
00460     {
00461         if (namedCatalogs.contains(*it))
00462             delete namedCatalogs[*it];
00463     }
00464     deletedConfigurationItems.clear();
00465     
00466     //update configuration
00467     for (QMap<QString, QString>::const_iterator it = entryMap.begin();
00468         it != entryMap.end(); ++it)
00469     {
00470         config->setGroup("Locations");
00471         if (restrictions.contains(it.key()) || (!catalogEnabled(it.key())))
00472         {
00473             if (namedCatalogs.contains(it.key()))
00474                 delete namedCatalogs[it.key()];
00475         }
00476         else
00477         {
00478             kdDebug() << "updating 1" << endl;
00479             if (!namedCatalogs.contains(it.key()))    //create catalog if it does not exist
00480             {
00481                 DocumentationCatalogItem * item = createCatalog(contents, it.key(), config->readPathEntry(it.key()));
00482                 loadIndex(index, item);
00483                 index->setDirty(true);
00484 //                index->refill(indexes[item]);
00485             }
00486             else if (!indexEnabled(namedCatalogs[it.key()]))    //clear index if it is disabled in configuration
00487             {
00488                 kdDebug() << "    updating: clearCatalogIndex" << endl;
00489                 clearCatalogIndex(namedCatalogs[it.key()]);
00490             }
00491             else if ( (indexEnabled(namedCatalogs[it.key()]))    //index is requested in configuration but does not yet exist
00492                 && (!indexes.contains(namedCatalogs[it.key()])) )
00493             {
00494                 kdDebug() << "    index requested " << endl;
00495                 loadIndex(index, namedCatalogs[it.key()]);
00496                 index->setDirty(true);
00497             }
00498             m_indexCreated = true;
00499         }
00500     }
00501 }
00502 
00503 void DocumentationPlugin::loadCatalogConfiguration(KListView *configurationView)
00504 {
00505     config->setGroup("Locations");
00506     QMap<QString, QString> entryMap = config->entryMap("Locations");
00507 
00508     for (QMap<QString, QString>::const_iterator it = entryMap.begin();
00509         it != entryMap.end(); ++it)
00510     {
00511         if (namedCatalogs.contains(it.key())
00512             && namedCatalogs[it.key()]->isProjectDocumentationItem())
00513             continue;
00514         
00515         ConfigurationItem *item = new ConfigurationItem(configurationView, it.key(), it.data(),
00516             hasCapability(Index), hasCapability(FullTextSearch));
00517         config->setGroup("TOC Settings");
00518         item->setContents(config->readBoolEntry(item->title(), true));
00519         config->setGroup("Index Settings");
00520         item->setIndex(config->readBoolEntry(item->title(), false));
00521         config->setGroup("Search Settings");
00522         item->setFullTextSearch(config->readBoolEntry(item->title(), false));
00523     }
00524 }
00525 
00526 void DocumentationPlugin::saveCatalogConfiguration(KListView *configurationView)
00527 {
00528     config->setGroup("Locations");
00529     
00530     for (QStringList::const_iterator it = deletedConfigurationItems.constBegin();
00531         it != deletedConfigurationItems.constEnd(); ++it)
00532     {
00533         config->deleteEntry(*it);
00534     }
00535     
00536     QListViewItemIterator it(configurationView);
00537     while (it.current())
00538     {
00539         config->setGroup("Locations");
00540         ConfigurationItem *confItem = dynamic_cast<ConfigurationItem*>(it.current());
00541         if (confItem->isChanged())
00542             config->deleteEntry(confItem->origTitle());
00543         config->writePathEntry(confItem->title(), confItem->url());
00544         
00545         config->setGroup("TOC Settings");
00546         if (confItem->isChanged())
00547             config->deleteEntry(confItem->origTitle());
00548         config->writeEntry(confItem->title(), confItem->contents());
00549         
00550         config->setGroup("Index Settings");
00551         if (confItem->isChanged())
00552             config->deleteEntry(confItem->origTitle());
00553         config->writeEntry(confItem->title(), confItem->index());
00554 
00555         config->setGroup("Search Settings");
00556         if (confItem->isChanged())
00557             config->deleteEntry(confItem->origTitle());
00558         config->writeEntry(confItem->title(), confItem->fullTextSearch());
00559 
00560         ++it;
00561     }
00562     config->sync();
00563 }
00564 
00565 void DocumentationPlugin::setIndexEnabled( DocumentationCatalogItem * item, bool e )
00566 {
00567     QString group = config->group();
00568     config->setGroup("Index Settings");
00569     config->writeEntry(item->text(0), e);
00570     config->setGroup(group);
00571 }
00572 
00573 bool DocumentationPlugin::indexEnabled( DocumentationCatalogItem * item ) const
00574 {
00575     QString group = config->group();
00576     config->setGroup("Index Settings");
00577     bool b = config->readBoolEntry(item->text(0), false);
00578     config->setGroup(group);
00579     return b;
00580 }
00581 
00582 bool DocumentationPlugin::catalogEnabled(const QString &name) const
00583 {
00584     QString group = config->group();
00585     config->setGroup("TOC Settings");
00586     bool b = config->readBoolEntry(name, true);
00587     config->setGroup(group);
00588     return b;
00589 }
00590 
00591 void DocumentationPlugin::setCatalogEnabled(const QString &name, bool e)
00592 {
00593     QString group = config->group();
00594     config->setGroup("TOC Settings");
00595     config->writeEntry(name, e);
00596     config->setGroup(group);
00597 }
00598 
00599 
00600 
00601 
00602 //class IndexBox
00603 
00604 IndexBox::IndexBox(QWidget *parent, const char *name)
00605     :KListBox(parent, name), m_dirty(false)
00606 {
00607 }
00608 
00609 void IndexBox::addIndexItem(IndexItemProto *item)
00610 {
00611     items[item->text()].append(item);
00612 }
00613 
00614 void IndexBox::removeIndexItem(IndexItemProto *item)
00615 {
00616     QString text = item->text();
00617     items[text].remove(item);
00618     if (items[text].count() == 0)
00619     {
00620         items.remove(text);
00621         QListBoxItem *item = findItem(text, Qt::CaseSensitive | Qt::ExactMatch);
00622         if (item)
00623             delete item;
00624     }
00625 }
00626 
00627 void IndexBox::fill()
00628 {
00629     for (QMap<QString, QValueList<IndexItemProto*> >::const_iterator it = items.begin();
00630         it != items.end(); ++it)
00631     {
00632         new IndexItem(this, it.key());
00633     }
00634 }
00635 
00636 void IndexBox::setDirty(bool dirty)
00637 {
00638     m_dirty = dirty;
00639 }
00640 
00641 void IndexBox::refill()
00642 {
00643     if (m_dirty)
00644     {
00645         clear();
00646         fill();
00647         setDirty(false);
00648     }
00649 }
00650 
00651 
00652 ProjectDocumentationPlugin::ProjectDocumentationPlugin(DocumentationPlugin *docPlugin, DocumentationPlugin::ProjectDocType type)
00653     :QObject(0, 0), m_docPlugin(docPlugin), m_catalog(0), m_type(type), m_contents(0), m_index(0)
00654 {
00655     kdDebug() << "ProjectDocumentationPlugin::ProjectDocumentationPlugin for type " << type << endl;
00656     
00657     m_watch = new KDirWatch(this);
00658     connect(m_watch, SIGNAL(dirty(const QString&)), this, SLOT(reinit()));
00659     m_watch->startScan();
00660 }
00661 
00662 ProjectDocumentationPlugin::~ProjectDocumentationPlugin()
00663 {
00664     deinit();
00665 }
00666 
00667 void ProjectDocumentationPlugin::init(KListView *contents, IndexBox *index, const QString &url)
00668 {
00669     m_contents = contents;
00670     m_index = index;
00671     m_url = url;
00672     
00673     if (m_catalog)
00674         deinit();
00675     m_catalog = m_docPlugin->createCatalog(contents, 
00676         m_type == DocumentationPlugin::APIDocs ? i18n("Project API Documentation")
00677         : i18n("Project User Manual"), url);
00678     if (m_catalog)
00679     {
00680         m_catalog->setProjectDocumentationItem(true);
00681         m_watch->addFile(url);
00682     }
00683 }
00684 
00685 void ProjectDocumentationPlugin::reinit()
00686 {
00687     deinit();
00688     if (m_contents != 0 && m_index != 0 && m_url != 0)
00689         init(m_contents, m_index, m_url);
00690 }
00691 
00692 void ProjectDocumentationPlugin::deinit()
00693 {
00694     m_watch->removeFile(m_url);
00695     delete m_catalog;
00696     m_catalog = 0;
00697 }
00698 
00699 QString ProjectDocumentationPlugin::pluginName() const
00700 {
00701     return m_docPlugin->pluginName();
00702 }
00703 
00704 QString ProjectDocumentationPlugin::catalogURL() const
00705 {
00706     return m_url;
00707 }
00708 
00709 #include "kdevdocumentationplugin.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:36 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003