KDevelop API Documentation

docdevhelpplugin.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004 by Alexander Dymo                                  *
00003  *   cloudtemple@mksat.net                                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "docdevhelpplugin.h"
00021 
00022 #include <unistd.h>
00023 
00024 #include <qdom.h>
00025 #include <qfile.h>
00026 #include <qfileinfo.h>
00027 #include <qdialog.h>
00028 
00029 #include <kurl.h>
00030 #include <kaboutdata.h>
00031 #include <kconfig.h>
00032 #include <klocale.h>
00033 #include <kstandarddirs.h>
00034 
00035 #include <kdevgenericfactory.h>
00036 
00037 #include "../../../../config.h"
00038 
00039 class DevHelpDocumentationCatalogItem: public DocumentationCatalogItem
00040 {
00041 public:
00042     DevHelpDocumentationCatalogItem(const QString &devHelpFile, DocumentationPlugin* plugin,
00043         KListView *parent, const QString &name)
00044         :DocumentationCatalogItem(plugin, parent, name), m_devHelpFile(devHelpFile)
00045     {
00046     }
00047     DevHelpDocumentationCatalogItem(const QString &devHelpFile, DocumentationPlugin* plugin,
00048         DocumentationItem *parent, const QString &name)
00049         :DocumentationCatalogItem(plugin, parent, name), m_devHelpFile(devHelpFile)
00050     {
00051     }
00052     QString devHelpFile() const { return m_devHelpFile; }
00053     
00054 private:
00055     QString m_devHelpFile;
00056 };
00057 
00058 
00059 static const KAboutData data("docdevhelpplugin", I18N_NOOP("DevHelp documentation plugin"), "1.0");
00060 typedef KDevGenericFactory<DocDevHelpPlugin> DocDevHelpPluginFactory;
00061 K_EXPORT_COMPONENT_FACTORY( libdocdevhelpplugin, DocDevHelpPluginFactory(&data) )
00062 
00063 DocDevHelpPlugin::DocDevHelpPlugin(QObject* parent, const char* name,
00064     const QStringList /*args*/)
00065     :DocumentationPlugin(DocDevHelpPluginFactory::instance()->config(), parent, name)
00066 {
00067     setCapabilities(Index | FullTextSearch | ProjectDocumentation);
00068     autoSetup();
00069 }
00070 
00071 DocDevHelpPlugin::~DocDevHelpPlugin()
00072 {
00073 }
00074 
00075 DocumentationCatalogItem* DocDevHelpPlugin::createCatalog(KListView* contents, const QString& title, const QString& url)
00076 {
00077     return new DevHelpDocumentationCatalogItem(url, this, contents, title);
00078 }
00079 
00080 QPair<KFile::Mode, QString> DocDevHelpPlugin::catalogLocatorProps()
00081 {
00082     return QPair<KFile::Mode, QString>(KFile::File, "*.devhelp");
00083 }
00084 
00085 QString DocDevHelpPlugin::catalogTitle(const QString& url)
00086 {
00087     QFileInfo fi(url);
00088     if (!fi.exists())
00089         return QString::null;
00090 
00091     QFile f(url);
00092     if (!f.open(IO_ReadOnly))
00093         return QString::null;
00094     
00095     QDomDocument doc;
00096     if (!doc.setContent(&f))
00097         return QString::null;
00098     f.close();
00099 
00100     QDomElement docEl = doc.documentElement();
00101 
00102     return docEl.attribute("title", QString::null);
00103 }
00104 
00105 QString DocDevHelpPlugin::pluginName() const
00106 {
00107     return i18n("Devhelp Documentation Collection");
00108 }
00109 
00110 QStringList DocDevHelpPlugin::fullTextSearchLocations()
00111 {
00112     QStringList locs;
00113         
00114     QMap<QString, QString> entryMap = config->entryMap("Locations");
00115 
00116     for (QMap<QString, QString>::const_iterator it = entryMap.begin();
00117         it != entryMap.end(); ++it)
00118     {
00119         config->setGroup("Search Settings");
00120         if (config->readBoolEntry(it.key(), false))
00121         {
00122             config->setGroup("Locations");
00123             QFileInfo fi(config->readPathEntry(it.key()));
00124             locs << fi.dirPath(true);
00125         }
00126     }
00127     
00128     return locs;
00129 }
00130 
00131 bool DocDevHelpPlugin::needRefreshIndex(DocumentationCatalogItem* item)
00132 {
00133     DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item);
00134     if (!dhItem)
00135         return false;
00136     
00137     QFileInfo fi(dhItem->devHelpFile());
00138     config->setGroup("Index");
00139     if (fi.lastModified() > config->readDateTimeEntry(dhItem->text(0), new QDateTime()))
00140     {
00141         kdDebug() << "need rebuild index for " << dhItem->text(0) << endl;
00142         config->writeEntry(item->text(0), fi.lastModified());
00143         return true;
00144     }
00145     else
00146         return false;
00147 }
00148 
00149 void DocDevHelpPlugin::autoSetupPlugin()
00150 {
00151     QValueStack<QString> scanStack;
00152     
00153     pushToScanStack(scanStack, getenv("DEVHELP_SEARCH_PATH"));
00154     pushToScanStack(scanStack, QString(getenv("HOME")) + "/.devhelp/books");
00155     
00156     QString dhexepath = DocDevHelpPluginFactory::instance()->dirs()->findExe("devhelp");
00157     if (!dhexepath.isEmpty())
00158     {
00159         QFileInfo fi(dhexepath);
00160         QString path = KURL(fi.dirPath(true)).upURL().path(1);
00161         pushToScanStack(scanStack, path + "share/devhelp/books");
00162         pushToScanStack(scanStack, path + "share/gtk-doc/html");
00163     }
00164     
00165     pushToScanStack(scanStack, "/usr/share/gtk-doc/html");
00166     pushToScanStack(scanStack, "/usr/share/devhelp/books/");
00167     pushToScanStack(scanStack, "/usr/local/share/devhelp/books");
00168     pushToScanStack(scanStack, "/usr/local/share/gtk-doc/html");
00169     pushToScanStack(scanStack, "/opt/gnome/share/devhelp/books");
00170     pushToScanStack(scanStack, "/opt/gnome/share/gtk-doc/html");
00171     pushToScanStack(scanStack, "/opt/gnome2/share/devhelp/books");
00172     pushToScanStack(scanStack, "/opt/gnome2/share/gtk-doc/html");
00173 
00174     //fill the list of scan dirs (with subdirectories)
00175     QStringList scanList;
00176     QDir dir;
00177     do 
00178     {
00179         dir.setPath(scanStack.pop());
00180         if (!dir.exists())
00181             continue;
00182         scanList << dir.path();
00183 
00184         const QFileInfoList *dirEntries = dir.entryInfoList();
00185         QPtrListIterator<QFileInfo> it(*dirEntries);
00186         for (; it.current(); ++it) 
00187         {
00188             QString fileName = it.current()->fileName();
00189             if (fileName == "." || fileName == "..")
00190                 continue;
00191             QString path = it.current()->absFilePath();
00192             if (it.current()->isDir()) 
00193             {
00194                 scanStack.push(path);
00195             }
00196         }
00197     } while (!scanStack.isEmpty());
00198 
00199     for (QStringList::const_iterator it = scanList.begin(); it != scanList.end(); ++it)
00200     {
00201         scanDevHelpDir(*it);
00202     }
00203 }
00204 
00205 void DocDevHelpPlugin::scanDevHelpDir(const QString &path)
00206 {
00207     QDir d(path);
00208     if (! d.exists())
00209         return;
00210     
00211     d.setFilter(QDir::Files);
00212     //scan for *.devhelp files
00213     const QFileInfoList *list = d.entryInfoList();
00214     QFileInfoListIterator it( *list );
00215     QFileInfo *fi;
00216     while ( (fi = it.current()) != 0 ) 
00217     {
00218         if (fi->extension() == "devhelp")
00219         {
00220             config->setGroup("Locations");
00221             config->writePathEntry(catalogTitle(fi->absFilePath()), fi->absFilePath());
00222         }
00223         ++it;
00224     }
00225 }
00226 
00227 void DocDevHelpPlugin::pushToScanStack(QValueStack<QString> &stack, const QString &value)
00228 {
00229     if ( (!value.isEmpty()) && (!stack.contains(value)) )
00230     {
00231         stack << value;
00232         kdDebug() << "Devhelp scan stack: +: " << value << endl;
00233     }
00234 }
00235 
00236 void DocDevHelpPlugin::createIndex(IndexBox* index, DocumentationCatalogItem* item)
00237 {
00238     DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item);
00239     if (!dhItem)
00240         return;
00241     
00242     QFileInfo fi(dhItem->devHelpFile());
00243 
00244     QFile f(dhItem->devHelpFile());
00245     if (!f.open(IO_ReadOnly))
00246     {
00247         kdDebug(9002) << "Could not read" << dhItem->devHelpFile() << endl;
00248         return;
00249     }
00250 
00251     QDomDocument doc;
00252     if (!doc.setContent(&f))
00253     {
00254         kdDebug() << "Not a valid devhelp file: " << dhItem->devHelpFile() << endl;
00255         return;
00256     }
00257     f.close();
00258     
00259     QString baseUrl = KURL(dhItem->devHelpFile()).directory();
00260     
00261     QDomElement docEl = doc.documentElement();
00262     QDomElement chaptersEl = docEl.namedItem("functions").toElement();
00263     QDomElement childEl = chaptersEl.firstChild().toElement();
00264     while (!childEl.isNull())
00265     {
00266         if (childEl.tagName() == "function")
00267         {
00268             QString name = childEl.attribute("name");
00269             QString url = childEl.attribute("link");
00270             
00271             IndexItemProto *ii = new IndexItemProto(this, item, index, name, item->text(0));
00272             ii->addURL(KURL(baseUrl+"/"+url));
00273         }
00274         childEl = childEl.nextSibling().toElement();
00275     }
00276 }
00277 
00278 void DocDevHelpPlugin::createTOC(DocumentationCatalogItem* item)
00279 {
00280     DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item);
00281     if (!dhItem)
00282         return;
00283     
00284     QFileInfo fi(dhItem->devHelpFile());
00285 
00286     QFile f(dhItem->devHelpFile());
00287     if (!f.open(IO_ReadOnly))
00288     {
00289         kdDebug(9002) << "Could not read" << dhItem->devHelpFile() << endl;
00290         return;
00291     }
00292 
00293     QDomDocument doc;
00294     if (!doc.setContent(&f))
00295     {
00296         kdDebug() << "Not a valid devhelp file: " << dhItem->devHelpFile() << endl;
00297         return;
00298     }
00299     f.close();
00300     
00301     QDomElement docEl = doc.documentElement();
00302     QDomElement chaptersEl = docEl.namedItem("chapters").toElement();
00303 
00304     QDomElement childEl = chaptersEl.lastChild().toElement();
00305     QString baseUrl = KURL(dhItem->devHelpFile()).directory();
00306     addTocSect(dhItem, childEl, baseUrl, true);
00307 }
00308 
00309 void DocDevHelpPlugin::addTocSect(DocumentationItem *parent, QDomElement childEl, 
00310     QString baseUrl, bool book)
00311 {
00312     while (!childEl.isNull())
00313     {
00314         if ( (childEl.tagName() == "sub") || (childEl.tagName() == "chapter"))
00315         {
00316             QString name = childEl.attribute("name");
00317             QString url = childEl.attribute("link");
00318             
00319             if (name.isEmpty() && url.contains("ix"))
00320                 name = "Index";
00321             
00322             DocumentationItem *item = new DocumentationItem(
00323                 book ? DocumentationItem::Book : DocumentationItem::Document, parent, name);
00324             item->setURL(KURL(baseUrl+"/"+url));
00325             
00326             QDomElement grandchildEl = childEl.lastChild().toElement();
00327             addTocSect(item, grandchildEl, baseUrl);
00328         }
00329         childEl = childEl.previousSibling().toElement();
00330     }
00331 }
00332 
00333 void DocDevHelpPlugin::setCatalogURL(DocumentationCatalogItem* item)
00334 {
00335     DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item);
00336     if (!dhItem)
00337         return;
00338     
00339     QFileInfo fi(dhItem->devHelpFile());
00340 
00341     QFile f(dhItem->devHelpFile());
00342     if (!f.open(IO_ReadOnly))
00343     {
00344         kdDebug(9002) << "Could not read" << dhItem->devHelpFile() << endl;
00345         return;
00346     }
00347     QDomDocument doc;
00348     if (!doc.setContent(&f))
00349     {
00350         kdDebug(9002) << "Not a valid Devhelp file: " << dhItem->devHelpFile() << endl;
00351         return;
00352     }
00353     f.close();
00354 
00355     QDomElement docEl = doc.documentElement();
00356     QDomElement titleEl = docEl.namedItem("book").toElement();
00357 
00358     if (item->url().isEmpty())
00359     {
00360         KURL url(fi.dirPath(true) + "/" + docEl.attribute("link", QString::null));
00361         item->setURL(url);
00362     }
00363 }
00364 
00365 ProjectDocumentationPlugin *DocDevHelpPlugin::projectDocumentationPlugin(ProjectDocType type)
00366 {
00367     if (type == APIDocs)
00368         return new ProjectDocumentationPlugin(this, type);
00369     return DocumentationPlugin::projectDocumentationPlugin(type);
00370 }
00371 
00372 #include "docdevhelpplugin.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 Wed Mar 23 00:03:56 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003