00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "docqtplugin.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 <klistview.h>
00034
00035 #include <urlutil.h>
00036 #include <kdevgenericfactory.h>
00037
00038 #include "../../../../config.h"
00039
00040 class QtDocumentationCatalogItem: public DocumentationCatalogItem
00041 {
00042 public:
00043 QtDocumentationCatalogItem(const QString &dcfFile, DocumentationPlugin* plugin,
00044 KListView *parent, const QString &name)
00045 :DocumentationCatalogItem(plugin, parent, name), m_dcfFile(dcfFile)
00046 {
00047 }
00048 QtDocumentationCatalogItem(const QString &dcfFile, DocumentationPlugin* plugin,
00049 DocumentationItem *parent, const QString &name)
00050 :DocumentationCatalogItem(plugin, parent, name), m_dcfFile(dcfFile)
00051 {
00052 }
00053 QString dcfFile() const { return m_dcfFile; }
00054
00055 private:
00056 QString m_dcfFile;
00057 };
00058
00059 static const KAboutData data("docqtplugin", I18N_NOOP("Qt DCF documentation plugin"), "1.0");
00060 typedef KDevGenericFactory<DocQtPlugin> DocQtPluginFactory;
00061 K_EXPORT_COMPONENT_FACTORY( libdocqtplugin, DocQtPluginFactory(&data) )
00062
00063 DocQtPlugin::DocQtPlugin(QObject* parent, const char* name, const QStringList)
00064 :DocumentationPlugin(DocQtPluginFactory::instance()->config(), parent, name)
00065 {
00066 setCapabilities(Index | FullTextSearch);
00067 autoSetup();
00068 }
00069
00070 DocQtPlugin::~DocQtPlugin()
00071 {
00072 }
00073
00074 void DocQtPlugin::createTOC(DocumentationCatalogItem *item)
00075 {
00076 QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item);
00077 if (!qtItem)
00078 return;
00079
00080 QFileInfo fi(qtItem->dcfFile());
00081
00082 QFile f(qtItem->dcfFile());
00083 if (!f.open(IO_ReadOnly))
00084 {
00085 kdDebug(9002) << "Could not read" << qtItem->dcfFile() << endl;
00086 return;
00087 }
00088 QDomDocument doc;
00089 if (!doc.setContent(&f) || doc.doctype().name() != "DCF")
00090 {
00091 kdDebug(9002) << "Not a valid DCF file: " << qtItem->dcfFile() << endl;
00092 return;
00093 }
00094 f.close();
00095
00096 QDomElement docEl = doc.documentElement();
00097 QDomElement titleEl = docEl.namedItem("DCF").toElement();
00098
00099 QDomElement childEl = docEl.lastChild().toElement();
00100 while (!childEl.isNull())
00101 {
00102 if (childEl.tagName() == "section")
00103 {
00104 QString ref = childEl.attribute("ref");
00105 QString title = childEl.attribute("title");
00106
00107 DocumentationItem *sectionItem = new DocumentationItem(DocumentationItem::Book, item, title);
00108 KURL sectionUrl(fi.dirPath(true) + "/" + ref);
00109 sectionItem->setURL(sectionUrl);
00110
00111 QDomElement grandChild = childEl.lastChild().toElement();
00112 while(!grandChild.isNull())
00113 {
00114 if (grandChild.tagName() == "keyword")
00115 {
00116 QString keyRef = grandChild.attribute("ref");
00117 QString keyTitle = grandChild.text();
00118
00119 DocumentationItem *keyItem = new DocumentationItem(DocumentationItem::Document, sectionItem, keyTitle);
00120 KURL keyUrl(fi.dirPath(true) + "/" + keyRef);
00121 keyItem->setURL(keyUrl);
00122 }
00123 if (grandChild.tagName() == "section")
00124 {
00125 QString keyRef = grandChild.attribute("ref");
00126 QString keyTitle = grandChild.attribute("title");
00127 DocumentationItem *keyItem = new DocumentationItem(DocumentationItem::Book, sectionItem, keyTitle);
00128 KURL keyUrl(fi.dirPath(true) + "/" + keyRef);
00129 keyItem->setURL(keyUrl);
00130 }
00131 grandChild = grandChild.previousSibling().toElement();
00132 }
00133 }
00134 childEl = childEl.previousSibling().toElement();
00135 }
00136 }
00137
00138 void DocQtPlugin::autoSetupPlugin()
00139 {
00140 QString qtDocDir(QT_DOCDIR);
00141 qtDocDir = URLUtil::envExpand(qtDocDir);
00142 if (qtDocDir.isEmpty())
00143 {
00144 qtDocDir = getenv("QTDIR");
00145 }
00146 if (!qtDocDir.isEmpty())
00147 {
00148 config->setGroup("Search Settings");
00149 config->writeEntry("Qt Reference Documentation", true);
00150 config->setGroup("Index Settings");
00151 config->writeEntry("Qt Reference Documentation", true);
00152 config->setGroup("Locations");
00153 config->writePathEntry("Qt Reference Documentation", qtDocDir + QString("/qt.dcf"));
00154 config->writePathEntry("Qt Assistant Manual", qtDocDir + QString("/assistant.dcf"));
00155 config->writePathEntry("Qt Designer Manual", qtDocDir + QString("/designer.dcf"));
00156 config->writePathEntry("Guide to the Qt Translation Tools", qtDocDir + QString("/linguist.dcf"));
00157 config->writePathEntry("qmake User Guide", qtDocDir + QString("/qmake.dcf"));
00158 }
00159 }
00160
00161 void DocQtPlugin::setCatalogURL(DocumentationCatalogItem *item)
00162 {
00163 QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item);
00164 if (!qtItem)
00165 return;
00166
00167 QFileInfo fi(qtItem->dcfFile());
00168
00169 QFile f(qtItem->dcfFile());
00170 if (!f.open(IO_ReadOnly))
00171 {
00172 kdDebug(9002) << "Could not read" << qtItem->dcfFile() << endl;
00173 return;
00174 }
00175 QDomDocument doc;
00176 if (!doc.setContent(&f) || doc.doctype().name() != "DCF")
00177 {
00178 kdDebug(9002) << "Not a valid DCF file: " << qtItem->dcfFile() << endl;
00179 return;
00180 }
00181 f.close();
00182
00183 QDomElement docEl = doc.documentElement();
00184 QDomElement titleEl = docEl.namedItem("DCF").toElement();
00185
00186 if (item->url().isEmpty())
00187 {
00188 KURL url(fi.dirPath(true) + "/" + docEl.attribute("ref", QString::null));
00189 item->setURL(url);
00190 }
00191 }
00192
00193 QString DocQtPlugin::pluginName() const
00194 {
00195 return i18n("Qt Documentation Collection");
00196 }
00197
00198 bool DocQtPlugin::needRefreshIndex(DocumentationCatalogItem *item)
00199 {
00200 QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item);
00201 if (!qtItem)
00202 return false;
00203
00204 QFileInfo fi(qtItem->dcfFile());
00205 config->setGroup("Index");
00206 if (fi.lastModified() > config->readDateTimeEntry(qtItem->text(0), new QDateTime()))
00207 {
00208 kdDebug() << "need rebuild index for " << qtItem->text(0) << endl;
00209 config->writeEntry(item->text(0), fi.lastModified());
00210 return true;
00211 }
00212 else
00213 return false;
00214 }
00215
00216 void DocQtPlugin::createIndex(IndexBox *index, DocumentationCatalogItem *item)
00217 {
00218 QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item);
00219 if (!qtItem)
00220 return;
00221
00222 QFileInfo fi(qtItem->dcfFile());
00223
00224 QFile f(qtItem->dcfFile());
00225 if (!f.open(IO_ReadOnly))
00226 {
00227 kdDebug(9002) << "Could not read" << qtItem->dcfFile() << endl;
00228 return;
00229 }
00230 QDomDocument doc;
00231 if (!doc.setContent(&f) || doc.doctype().name() != "DCF")
00232 {
00233 kdDebug(9002) << "Not a valid DCF file: " << qtItem->dcfFile() << endl;
00234 return;
00235 }
00236 f.close();
00237
00238 QDomElement docEl = doc.documentElement();
00239 QDomElement titleEl = docEl.namedItem("DCF").toElement();
00240
00241 QDomElement childEl = docEl.firstChild().toElement();
00242 while (!childEl.isNull())
00243 {
00244 if (childEl.tagName() == "section")
00245 {
00246
00247 QString title = childEl.attribute("title");
00248 if (fi.fileName() != "qt.dcf")
00249 {
00250 QString ref = childEl.attribute("ref");
00251
00252 IndexItemProto *ii = new IndexItemProto(this, item, index, title, item->text(0));
00253 ii->addURL(KURL(fi.dirPath(true) + "/" + ref));
00254 }
00255
00256 QDomElement grandChild = childEl.firstChild().toElement();
00257 while(!grandChild.isNull())
00258 {
00259 if (grandChild.tagName() == "keyword")
00260 {
00261 QString keyRef = grandChild.attribute("ref");
00262 QString keyTitle = grandChild.text();
00263
00264
00265 if (keyRef != "qdir-example.html")
00266 {
00267 IndexItemProto *ii = new IndexItemProto(this, item, index, keyTitle, title);
00268 ii->addURL(KURL(fi.dirPath(true) + "/" + keyRef));
00269 }
00270 }
00271 grandChild = grandChild.nextSibling().toElement();
00272 }
00273 }
00274 childEl = childEl.nextSibling().toElement();
00275 }
00276 }
00277
00278 QStringList DocQtPlugin::fullTextSearchLocations()
00279 {
00280 QStringList locs;
00281
00282 QMap<QString, QString> entryMap = config->entryMap("Locations");
00283
00284 for (QMap<QString, QString>::const_iterator it = entryMap.begin();
00285 it != entryMap.end(); ++it)
00286 {
00287 config->setGroup("Search Settings");
00288 if (config->readBoolEntry(it.key(), false))
00289 {
00290 config->setGroup("Locations");
00291 QFileInfo fi(config->readPathEntry(it.key()));
00292 locs << fi.dirPath(true);
00293 }
00294 }
00295
00296 return locs;
00297 }
00298
00299 QPair<KFile::Mode, QString> DocQtPlugin::catalogLocatorProps()
00300 {
00301 return QPair<KFile::Mode, QString>(KFile::File, "*.xml *.dcf");
00302 }
00303
00304 QString DocQtPlugin::catalogTitle(const QString &url)
00305 {
00306 QFileInfo fi(url);
00307 if (!fi.exists())
00308 return QString::null;
00309
00310 QFile f(url);
00311 if (!f.open(IO_ReadOnly))
00312 return QString::null;
00313
00314 QDomDocument doc;
00315 if (!doc.setContent(&f) || (doc.doctype().name() != "DCF"))
00316 return QString::null;
00317 f.close();
00318
00319 QDomElement docEl = doc.documentElement();
00320
00321 return docEl.attribute("title", QString::null);
00322 }
00323
00324 DocumentationCatalogItem *DocQtPlugin::createCatalog(KListView *contents, const QString &title, const QString &url)
00325 {
00326 return new QtDocumentationCatalogItem(url, this, contents, title);
00327 }
00328
00329 #include "docqtplugin.moc"