KDevelop API Documentation

docindexdlg.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2001 by Bernd Gehrmann                                  *
00003  *   bernd@kdevelop.org                                                    *
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  ***************************************************************************/
00011 
00012 #include "docindexdlg.h"
00013 
00014 #include <qapplication.h>
00015 #include <qcheckbox.h>
00016 #include <qfile.h>
00017 #include <qfileinfo.h>
00018 #include <qlabel.h>
00019 #include <qlayout.h>
00020 #include <qpushbutton.h>
00021 #include <qvbuttongroup.h>
00022 #include <qregexp.h>
00023 #include <kbuttonbox.h>
00024 #include <kcombobox.h>
00025 #include <kdebug.h>
00026 #include <kdialog.h>
00027 #include <kglobal.h>
00028 #include <kinstance.h>
00029 #include <klocale.h>
00030 #include <kmessagebox.h>
00031 #include <kstandarddirs.h>
00032 #include <kprocess.h>
00033 #include <kdeversion.h>
00034 #include <kstdguiitem.h>
00035 
00036 #include "kdevcore.h"
00037 #include "kdevpartcontroller.h"
00038 #include "domutil.h"
00039 
00040 #include "misc.h"
00041 #include "doctreeviewfactory.h"
00042 #include "doctreeviewpart.h"
00043 
00044 
00045 DocIndexDialog::DocIndexDialog(DocTreeViewPart *part, QWidget *parent, const char *name)
00046     : QDialog(parent, name)
00047 {
00048     setCaption(i18n("Documentation Index"));
00049 
00050     QLabel *term_label = new QLabel(i18n("Search term:"), this);
00051 
00052     term_combo = new KComboBox(true, this);
00053     term_combo->setFocus();
00054     QFontMetrics fm(fontMetrics());
00055     term_combo->setMinimumWidth(fm.width('X')*40);
00056 
00057     QApplication::setOverrideCursor(waitCursor);
00058 
00059     readKDocIndex();
00060 
00061     KStandardDirs *dirs = DocTreeViewFactory::instance()->dirs();
00062     QStringList books = dirs->findAllResources("docindices", QString::null, false, true);
00063 
00064     QStringList::Iterator bit;
00065     for (bit = books.begin(); bit != books.end(); ++bit)
00066         readIndexFromFile(*bit);
00067 
00068     QApplication::restoreOverrideCursor();
00069 
00070     QVButtonGroup *book_group = new QVButtonGroup(this);
00071     book_group->setExclusive(false);
00072 
00073     QPtrListIterator<DocIndex> iit(indices);
00074     for (; iit.current(); ++iit) {
00075         QCheckBox *box = new QCheckBox(iit.current()->title, book_group);
00076         box->setChecked(true);
00077         books_boxes.append(box);
00078         connect( box, SIGNAL(toggled(bool)), this, SLOT(choiceChanged()) );
00079     }
00080 
00081     QVButtonGroup *category_group = new QVButtonGroup(this);
00082     category_group->setExclusive(false);
00083 
00084     concept_box = new QCheckBox(i18n("&Concept index"), category_group);
00085     concept_box->setChecked(true);
00086     ident_box = new QCheckBox(i18n("&Identifier index"), category_group);
00087     ident_box->setChecked(true);
00088     file_box = new QCheckBox(i18n("&File index"), category_group);
00089     file_box->setChecked(true);
00090 
00091     connect( concept_box, SIGNAL(toggled(bool)), this, SLOT(choiceChanged()) );
00092     connect( ident_box, SIGNAL(toggled(bool)), this, SLOT(choiceChanged()) );
00093     connect( file_box, SIGNAL(toggled(bool)), this, SLOT(choiceChanged()) );
00094 
00095 #if 0
00096     QFrame *frame = new QFrame(this);
00097     frame->setFrameStyle(QFrame::HLine | QFrame::Sunken);
00098     layout->addWidget(frame, 0);
00099 #endif
00100 
00101     KButtonBox *buttonbox = new KButtonBox(this);
00102     buttonbox->addStretch();
00103 #if KDE_IS_VERSION( 3, 2, 90 )
00104     QPushButton *ok_button = buttonbox->addButton(KStdGuiItem::ok());
00105     QPushButton *cancel_button = buttonbox->addButton(KStdGuiItem::cancel());
00106 #else
00107     QPushButton *ok_button = buttonbox->addButton(i18n("&OK"));
00108     QPushButton *cancel_button = buttonbox->addButton(i18n("Cancel"));
00109 #endif
00110 
00111     ok_button->setDefault(true);
00112     connect( ok_button, SIGNAL(clicked()), this, SLOT(accept()) );
00113     connect( cancel_button, SIGNAL(clicked()), this, SLOT(reject()) );
00114     buttonbox->layout();
00115 
00116     QVBoxLayout *layout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
00117     layout->addWidget(term_label, 0);
00118     layout->addWidget(term_combo, 0);
00119     layout->addWidget(book_group);
00120     layout->addWidget(category_group);
00121     layout->addWidget(buttonbox, 0);
00122 
00123     indices.setAutoDelete(true);
00124     m_part = part;
00125     choiceChanged();
00126 
00127     if (m_part->project())
00128         readConfig();
00129 }
00130 
00131 
00132 DocIndexDialog::~DocIndexDialog()
00133 {}
00134 
00135 
00136 void DocIndexDialog::projectChanged()
00137 {
00138     if (m_part->project())
00139         readConfig();
00140 }
00141 
00142 
00143 void DocIndexDialog::lookup(const QString &str)
00144 {
00145     term_combo->lineEdit()->setText(str);
00146 }
00147 
00148 
00149 void DocIndexDialog::readConfig()
00150 {
00151     QDomDocument &dom = *m_part->projectDom();
00152     QDomElement docEl = dom.documentElement();
00153     QDomElement doctreeviewEl = docEl.namedItem("kdevdoctreeview").toElement();
00154 
00155     QStringList indexbooks;
00156     QDomElement indexbooksEl = doctreeviewEl.namedItem("indexbooks").toElement();
00157     QDomElement bookEl = indexbooksEl.firstChild().toElement();
00158     while (!bookEl.isNull()) {
00159         if (bookEl.tagName() == "book")
00160             indexbooks << bookEl.firstChild().toText().data();
00161         bookEl = bookEl.nextSibling().toElement();
00162     }
00163 
00164     QPtrListIterator<QCheckBox> cit(books_boxes);
00165     QPtrListIterator<DocIndex> iit(indices);
00166     for (; cit.current() && iit.current(); ++cit,++iit)
00167         (*cit)->setChecked(indexbooks.isEmpty() || indexbooks.contains(iit.current()->indexName));
00168 
00169     concept_box->setChecked(DomUtil::readBoolEntry(dom, "/kdevdoctreeview/categories/concept"));
00170     ident_box->setChecked(DomUtil::readBoolEntry(dom, "/kdevdoctreeview/categories/identifier"));
00171     file_box->setChecked(DomUtil::readBoolEntry(dom, "/kdevdoctreeview/categories/file"));
00172 }
00173 
00174 
00175 void DocIndexDialog::storeConfig()
00176 {
00177     QDomDocument &dom = *m_part->projectDom();
00178     QDomElement docEl = dom.documentElement();
00179     QDomElement doctreeviewEl = docEl.namedItem("kdevdoctreeview").toElement();
00180 
00181     QDomElement indexbooksEl = doctreeviewEl.namedItem("indexbooks").toElement();
00182     if (indexbooksEl.isNull()) {
00183         indexbooksEl = dom.createElement("indexbooks");
00184         doctreeviewEl.appendChild(indexbooksEl);
00185     }
00186 
00187     // Clear old entries
00188     while (!indexbooksEl.firstChild().isNull())
00189         indexbooksEl.removeChild(indexbooksEl.firstChild());
00190 
00191     QPtrListIterator<QCheckBox> cit(books_boxes);
00192     QPtrListIterator<DocIndex> iit(indices);
00193     for (; cit.current() && iit.current(); ++cit,++iit)
00194         if ((*cit)->isChecked()) {
00195             QDomElement bookEl = dom.createElement("book");
00196             bookEl.appendChild(dom.createTextNode((*iit)->indexName));
00197             indexbooksEl.appendChild(bookEl);
00198             kdDebug() << "Appending " << ((*iit)->indexName) << endl;
00199         }
00200 
00201     DomUtil::writeBoolEntry(dom, "/kdevdoctreeview/categories/concept", concept_box->isChecked());
00202     DomUtil::writeBoolEntry(dom, "/kdevdoctreeview/categories/identifier", ident_box->isChecked());
00203     DomUtil::writeBoolEntry(dom, "/kdevdoctreeview/categories/file", file_box->isChecked());
00204 }
00205 
00206 
00207 void DocIndexDialog::readKDocIndex()
00208 {
00209     DocIndex *index = new DocIndex;
00210     indices.append(index);
00211 
00212     index->indexName = "qt";
00213     index->title = i18n("Qt/KDE API");
00214 
00215     QStringList itemNames, fileNames, hiddenNames;
00216     DocTreeViewTool::getAllLibraries(&itemNames, &fileNames);
00217     DocTreeViewTool::getHiddenLibraries(&hiddenNames);
00218 
00219     QStringList::Iterator it;
00220     for (it = fileNames.begin(); it != fileNames.end(); ++it)
00221         if (!hiddenNames.contains(*it)) {
00222             FILE *f;
00223             if ((*it).right(3) != QString::fromLatin1(".gz")) {
00224                 if ( (f = fopen(QFile::encodeName( *it ).data(), "r")) != 0) {
00225                     readKDocEntryList(f, &index->identNames, &index->identUrls);
00226                     fclose(f);
00227                 }
00228             } else {
00229                 QString cmd = "gzip -c -d ";
00230 #if (KDE_VERSION > 305)
00231                 cmd += KProcess::quote(*it);
00232 #else
00233                 cmd += KShellProcess::quote(*it);
00234 #endif
00235                 cmd += " 2>/dev/null";
00236                 if ( (f = popen(QFile::encodeName(cmd), "r")) != 0) {
00237                     readKDocEntryList(f, &index->identNames, &index->identUrls);
00238                     pclose(f);
00239                 }
00240             }
00241         }
00242 }
00243 
00244 
00245 void DocIndexDialog::readKDocEntryList(FILE *f,
00246                                        QStringList *nameList, QStringList *urlList)
00247 {
00248     char buf[1024];
00249     int pos0;
00250     QString classname, membername, base, filename;
00251 
00252     while (fgets(buf, sizeof buf, f)) {
00253         QString s = buf;
00254         if (s.left(pos0=11) == "<BASE URL=\"") {
00255             int pos2 = s.find("\">", pos0);
00256             if (pos2 != -1)
00257                 base = s.mid(pos0, pos2-pos0);
00258         }
00259         else if (s.left(pos0=9) == "<C NAME=\"") {
00260             int pos1 = s.find("\" REF=\"", pos0);
00261             if (pos1 == -1)
00262                 continue;
00263                 int pos2 = s.find("\">", pos1+7);
00264                 if (pos2 == -1)
00265                     continue;
00266                 classname = s.mid(pos0, pos1-pos0);
00267                 filename = s.mid(pos1+7, pos2-(pos1+7));
00268                 filename.replace(QRegExp("::"), "__");
00269                 (*nameList) << classname;
00270                 (*urlList) << (base + "/" + filename);
00271         }
00272       else if (s.left(pos0=9) == "<M NAME=\"" || s.left(pos0=10) == "<ME NAME=\"")
00273           {
00274               int pos1 = s.find("\" REF=\"", pos0);
00275               if (pos1 == -1)
00276                   continue;
00277               int pos2 = s.find("\">", pos1+7);
00278               if (pos2 == -1)
00279                   continue;
00280 
00281               // Long version: membername = classname + "::" + s.mid(pos0, pos1-pos0);
00282               membername = s.mid(pos0, pos1-pos0);
00283               filename = s.mid(pos1+7, pos2-(pos1+7));
00284               filename.replace(QRegExp("::"), "__");
00285               (*nameList) << (membername + " (" + classname + ")");
00286               (*urlList) << (base + "/" + filename);
00287           }
00288     }
00289 }
00290 
00291 
00292 void DocIndexDialog::readIndexFromFile(const QString &fileName)
00293 {
00294     QFileInfo fi(fileName);
00295     QString name = fi.baseName();
00296 
00297     QFile f(fileName);
00298     if (!f.open(IO_ReadOnly)) {
00299         kdDebug(9002) << "Could not read doc index: " << fileName << endl;
00300         return;
00301     }
00302 
00303     QDomDocument doc;
00304     if (!doc.setContent(&f) || doc.doctype().name() != "kdevelopindex") {
00305         kdDebug() << "Not a valid kdevelopindex file: " << fileName << endl;
00306         return;
00307     }
00308 
00309     f.close();
00310 
00311     kdDebug(9002) << "Parsing: " << fileName << endl;
00312 
00313     DocIndex *index = new DocIndex;
00314     indices.append(index);
00315 
00316     QDomElement docEl = doc.documentElement();
00317     QDomElement titleEl = docEl.namedItem("title").toElement();
00318     QDomElement baseEl = docEl.namedItem("base").toElement();
00319     QDomElement conceptEl = docEl.namedItem("conceptindex").toElement();
00320     QDomElement identEl = docEl.namedItem("identindex").toElement();
00321     QDomElement fileEl = docEl.namedItem("fileindex").toElement();
00322     index->indexName = name;
00323     index->title = titleEl.firstChild().toText().data();
00324     index->base = baseEl.attribute("href");
00325     if (!index->base.isEmpty())
00326         index->base += "/";
00327     readEntryList(conceptEl, &index->conceptNames, &index->conceptUrls);
00328     readEntryList(identEl, &index->identNames, &index->identUrls);
00329     readEntryList(fileEl, &index->fileNames, &index->fileUrls);
00330 }
00331 
00332 
00333 void DocIndexDialog::readEntryList(const QDomElement &el,
00334                                    QStringList *nameList, QStringList *urlList)
00335 {
00336     QDomElement childEl = el.firstChild().toElement();
00337     while (!childEl.isNull()) {
00338         if (childEl.tagName() == "entry") {
00339             nameList->append(childEl.attribute("name"));
00340             urlList->append(childEl.attribute("url"));
00341         }
00342 
00343         childEl = childEl.nextSibling().toElement();
00344     }
00345 }
00346 
00347 
00348 void DocIndexDialog::accept()
00349 {
00350     QString term = term_combo->currentText();
00351     QString url;
00352     int pos;
00353 
00354     if (term.isEmpty())
00355         return;
00356 
00357     QPtrListIterator<QCheckBox> cit(books_boxes);
00358     QPtrListIterator<DocIndex> iit(indices);
00359     for (; cit.current() && iit.current(); ++cit,++iit)
00360         if ((*cit)->isChecked()) {
00361             if (concept_box->isChecked())
00362                 if ( (pos = (*iit)->conceptNames.findIndex(term)) != -1) {
00363                     kdDebug(9002) << "found in concept index of " << (*iit)->title << endl;
00364                     url = (*iit)->base + (*iit)->conceptUrls[pos];
00365                     break;
00366                 }
00367             if (ident_box->isChecked())
00368                 if ( (pos = (*iit)->identNames.findIndex(term)) != -1) {
00369                     kdDebug(9002) << "found in ident index of " << (*iit)->title << endl;
00370                     url = (*iit)->base + (*iit)->identUrls[pos];
00371                     break;
00372                 }
00373             if (file_box->isChecked())
00374                 if ( (pos = (*iit)->fileNames.findIndex(term)) != -1) {
00375                     kdDebug(9002) << "found in file index of " << (*iit)->title << endl;
00376                     url = (*iit)->base + (*iit)->fileUrls[pos];
00377                     break;
00378                 }
00379         }
00380 
00381     if (url.isEmpty()) {
00382         KMessageBox::sorry(this, i18n("Term not found in the indices."));
00383         return;
00384     }
00385 
00386     m_part->partController()->showDocument(KURL(url));
00387 
00388     if (m_part->project())
00389         storeConfig();
00390 
00391     QDialog::accept();
00392 }
00393 
00394 
00395 void DocIndexDialog::choiceChanged()
00396 {
00397     QStringList completions;
00398 
00399     QPtrListIterator<QCheckBox> cit(books_boxes);
00400     QPtrListIterator<DocIndex> iit(indices);
00401     for (; cit.current() && iit.current(); ++cit,++iit)
00402         if ((*cit)->isChecked()) {
00403             if (concept_box->isChecked())
00404                 completions += (*iit)->conceptNames;
00405             if (ident_box->isChecked())
00406                 completions += (*iit)->identNames;
00407             if (file_box->isChecked())
00408                 completions += (*iit)->fileNames;
00409         }
00410 
00411     term_combo->completionObject()->setItems(completions);
00412 }
00413 #include "docindexdlg.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:39 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003