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