00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "doctreeviewwidget.h"
00017
00018 #include <qdir.h>
00019 #include <qfileinfo.h>
00020 #include <qheader.h>
00021 #include <qregexp.h>
00022 #include <qtimer.h>
00023 #include <qtoolbutton.h>
00024 #include <qtooltip.h>
00025 #include <qlistview.h>
00026 #include <qmessagebox.h>
00027 #include <qlabel.h>
00028 #include <qptrlist.h>
00029 #include <qprogressdialog.h>
00030 #include <qwhatsthis.h>
00031 #include <qxml.h>
00032 #include <qdatastream.h>
00033
00034 #include <kdebug.h>
00035 #include <kapplication.h>
00036 #include <kdialogbase.h>
00037 #include <kcombobox.h>
00038 #include <kglobal.h>
00039 #include <kiconloader.h>
00040 #include <klocale.h>
00041 #include <kpopupmenu.h>
00042 #include <kstandarddirs.h>
00043 #include <ksimpleconfig.h>
00044 #include <kprocess.h>
00045 #include <kdeversion.h>
00046
00047 #include "choosedlg.h"
00048
00049 #include "kdevcore.h"
00050 #include "domutil.h"
00051 #include "urlutil.h"
00052 #include "kdevmainwindow.h"
00053 #include "kdevproject.h"
00054 #include "kdevpartcontroller.h"
00055
00056 #include "../../config.h"
00057 #include "misc.h"
00058 #include "doctreeitem.h"
00059 #include "doctreeviewfactory.h"
00060 #include "doctreeviewpart.h"
00061 #include "doctreeglobalconfigwidget.h"
00062 #include "doctreeprojectconfigwidget.h"
00063 #include "doclineedit.h"
00064
00065 #include "docsearchdlg.h"
00066
00067 IndexTreeData::IndexTreeData(const QString &text, const QString &parent, const QString &filename) :
00068 m_text(text), m_parent(parent), m_filename(filename), m_visible(true)
00069 {
00070 }
00071
00072
00073
00074
00075
00076
00082 class DocTreeKDELibsBook : public DocTreeItem
00083 {
00084 public:
00085 DocTreeKDELibsBook( DocTreeItem *parent, const QString &name, const QString &idxfilename, const QString &context);
00086 ~DocTreeKDELibsBook();
00087
00088 virtual QString fileName();
00089 virtual void refresh();
00090
00091 private:
00092 void readContents();
00093 void readKdoc2Index(FILE *f);
00094 };
00095
00096
00097 DocTreeKDELibsBook::DocTreeKDELibsBook(DocTreeItem *parent, const QString &name, const QString &idxfilename, const QString &context)
00098 : DocTreeItem(parent, Book, name, context, true)
00099 {
00100 setIndexFileName(idxfilename);
00101 }
00102
00103
00104 DocTreeKDELibsBook::~DocTreeKDELibsBook()
00105 {}
00106
00107
00108 QString DocTreeKDELibsBook::fileName()
00109 {
00110 if (DocTreeItem::fileName().isNull())
00111 readContents();
00112
00113 return DocTreeItem::fileName() + "/index.html";
00114 }
00115
00116
00117 void DocTreeKDELibsBook::refresh()
00118 {
00119 DocTreeItem::refresh();
00120
00121 if (DocTreeItem::fileName().isNull())
00122 readContents();
00123 }
00124
00125
00126 void DocTreeKDELibsBook::readContents()
00127 {
00128 FILE *f;
00129 bool success = false;
00130 if (indexFileName().right(3) != QString::fromLatin1(".gz"))
00131 {
00132 if ( (f = fopen(QFile::encodeName( indexFileName() ).data(), "r")) != 0)
00133 {
00134 readKdoc2Index(f);
00135 fclose(f);
00136 success = true;
00137 }
00138 }
00139 else
00140 {
00141 QString cmd = "gzip -c -d ";
00142 #if (KDE_VERSION > 305)
00143 cmd += KProcess::quote(indexFileName());
00144 #else
00145 cmd += KShellProcess::quote(indexFileName());
00146 #endif
00147 cmd += " 2>/dev/null";
00148 if ( (f = popen(QFile::encodeName(cmd), "r")) != 0)
00149 {
00150 readKdoc2Index(f);
00151 pclose(f);
00152 success = true;
00153 }
00154 }
00155 setExpandable(success);
00156 }
00157
00158
00159 void DocTreeKDELibsBook::readKdoc2Index(FILE *f)
00160 {
00161 char buf[1024];
00162 DocTreeItem *classItem = 0;
00163 int pos0;
00164 QString classname, membername, filename;
00165
00166 while (fgets(buf, sizeof buf, f))
00167 {
00168 QString s = buf;
00169 if (s.left(pos0=11) == "<BASE URL=\"")
00170 {
00171 int pos2 = s.find("\">", pos0);
00172 if (pos2 != -1)
00173 setFileName(s.mid(pos0, pos2-pos0));
00174 }
00175 else if (s.left(pos0=9) == "<C NAME=\"")
00176 {
00177 int pos1 = s.find("\" REF=\"", pos0);
00178 if (pos1 == -1)
00179 continue;
00180 int pos2 = s.find("\">", pos1+7);
00181 if (pos2 == -1)
00182 continue;
00183 classname = s.mid(pos0, pos1-pos0);
00184 filename = s.mid(pos1+7, pos2-(pos1+7));
00185 filename.replace(QRegExp("::"), "__");
00186 classItem = new DocTreeItem(this, Doc, classname, context());
00187 classItem->postInit();
00188 classItem->setFileName(DocTreeItem::fileName() + "/" + filename);
00189 }
00190 else if (s.left(pos0=10) == "<ME NAME=\"")
00191 {
00192 int pos1 = s.find("\" REF=\"", pos0);
00193 if (pos1 == -1)
00194 continue;
00195 int pos2 = s.find("\">", pos1+7);
00196 if (pos2 == -1)
00197 continue;
00198
00199
00200 membername = s.mid(pos0, pos1-pos0);
00201 filename = s.mid(pos1+7, pos2-(pos1+7));
00202 filename.replace(QRegExp("::"), "__");
00203 if (classItem)
00204 {
00205 DocTreeItem *item = new DocTreeItem(classItem, Doc, membername, context());
00206
00207 item->postInit();
00208 item->setFileName(DocTreeItem::fileName() + "/" + filename);
00209 }
00210 }
00211 }
00212
00213 sortChildItems(0, true);
00214 }
00215
00216
00217 class DocTreeKDELibsFolder : public DocTreeItem
00218 {
00219 public:
00220 DocTreeKDELibsFolder(QString location, QString name, KListView *parent, const QString &context)
00221 : DocTreeItem(parent, Folder, name, context, true), m_location(location)
00222 {}
00223 virtual void refresh();
00224 private:
00225 QString m_location;
00226 };
00227
00228
00229 void DocTreeKDELibsFolder::refresh()
00230 {
00231 DocTreeItem::refresh();
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 QStringList itemNames, fileNames, hiddenNames;
00243 DocTreeViewTool::readLibraryDocs(m_location,&itemNames, &fileNames);
00244 QStringList::Iterator it1, it2;
00245 for (it1 = itemNames.begin(), it2 = fileNames.begin();
00246 it1 != itemNames.end() && it2 != fileNames.end();
00247 ++it1, ++it2)
00248 {
00249 (new DocTreeKDELibsBook(this, *it1, *it2, context()))->postInit();
00250 }
00251
00252
00253 sortChildItems(0, true);
00254
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 }
00277
00278
00279
00280
00281
00282
00283
00288 class DocTreeDoxygenBook : public DocTreeItem
00289 {
00290 public:
00291 DocTreeDoxygenBook( DocTreeItem *parent, const QString &name,
00292 const QString &tagFileName, const QString &context);
00293
00294 static bool isInstallationOK(const QString& bookDir)
00295 {
00296 return QFile::exists(bookDir + "/html/index.html");
00297 }
00298
00299 virtual void refresh();
00300
00301 private:
00302 QString dirname;
00303 };
00304
00305
00306 DocTreeDoxygenBook::DocTreeDoxygenBook(DocTreeItem *parent, const QString &name,
00307 const QString &dirName, const QString &context)
00308 : DocTreeItem(parent, Book, name, context, true),
00309 dirname(dirName)
00310 {
00311 QString fileName = dirName + "index.html";
00312 setFileName(fileName);
00313
00314 QString tagName = dirname + "/" + text(0) + ".tag";
00315 if (!QFile::exists(tagName))
00316 {
00317 #if QT_VERSION >= 0x030100
00318 tagName.remove("/html/");
00319 #else
00320 tagName.replace( QRegExp( "\\/html\\/" ), QString() );
00321 #endif
00322 }
00323
00324 setIndexFileName(tagName);
00325 }
00326
00327 void DocTreeDoxygenBook::refresh()
00328 {
00329 DocTreeItem::refresh();
00330
00331 QFile f(indexFileName());
00332 if (!f.open(IO_ReadOnly))
00333 {
00334 kdDebug(9002) << "Could not open tag file: " << f.name() << endl;
00335 return;
00336 }
00337
00338 QDomDocument dom;
00339 if (!dom.setContent(&f) || dom.documentElement().nodeName() != "tagfile")
00340 {
00341 kdDebug(9002) << "No valid tag file" << endl;
00342 return;
00343 }
00344 f.close();
00345
00346 QDomElement docEl = dom.documentElement();
00347
00348 QDomElement childEl = docEl.firstChild().toElement();
00349 while (!childEl.isNull())
00350 {
00351 if (childEl.tagName() == "compound" && childEl.attribute("kind") == "class")
00352 {
00353 QString classname = childEl.namedItem("name").firstChild().toText().data();
00354 QString filename = childEl.namedItem("filename").firstChild().toText().data();
00355
00356 if (QFile::exists(dirname + filename))
00357 {
00358 DocTreeItem *item = new DocTreeItem(this, Doc, classname, context());
00359 item->postInit();
00360 item->setFileName(dirname + filename);
00361 }
00362 }
00363 childEl = childEl.nextSibling().toElement();
00364 }
00365
00366 sortChildItems(0, true);
00367 }
00368
00369
00370 class DocTreeDoxygenFolder : public DocTreeItem
00371 {
00372 public:
00373 DocTreeDoxygenFolder(QString location, QString name, KListView *parent, const QString &context)
00374 : DocTreeItem(parent, Folder, name, context, true), m_location(location)
00375 {}
00376 void refresh();
00377 private:
00378 QString m_location;
00379 };
00380
00381 void DocTreeDoxygenFolder::refresh()
00382 {
00383 DocTreeItem::refresh();
00384
00385
00386
00387
00388
00389
00390 QDir d(m_location);
00391 QStringList fileList = d.entryList("*", QDir::Dirs);
00392
00393 QStringList::ConstIterator it;
00394 for (it = fileList.begin(); it != fileList.end(); ++it)
00395 {
00396 QString dirName = (*it);
00397
00398 if (dirName == "." || dirName == ".." || dirName == "common")
00399 continue;
00400 if (DocTreeDoxygenBook::isInstallationOK(d.absFilePath(*it)))
00401 {
00402 (new DocTreeDoxygenBook(this, *it, d.absFilePath(*it) + "/html/", context()))->postInit();
00403
00404 }
00405 }
00406
00407 QFileInfo fi(m_location +"/index.html");
00408 if (fi.exists())
00409 setFileName(m_location +"/index.html");
00410
00411 sortChildItems(0, true);
00412 }
00413
00414
00415
00416
00417
00418
00419 class DocTreeTocFolder : public DocTreeItem
00420 {
00421 public:
00422 DocTreeTocFolder(const QString& name, KListView *parent, const QString &fileName, const QString &context);
00423 DocTreeTocFolder(KListView *parent, const QString &fileName, const QString &context);
00424
00425 QString tocName() const { return toc_name; }
00426
00427 virtual void refresh();
00428
00429 private:
00430
00431 void addTocSect(DocTreeItem *parent, QDomElement childEl, uint level);
00432
00433 QString base;
00434 QString toc_name;
00435 };
00436
00437 #if 0
00438 class TocNameExtractor : public QXmlDefaultHandler
00439 {
00440 public:
00441 TocNameExtractor(DocTreeTocFolder* parent)
00442 : m_parent(parent)
00443 , m_titleNext(false)
00444 {
00445 }
00446
00447 virtual bool notationDecl(const QString& name, const QString& , const QString& )
00448 {
00449 if (name != "kdeveloptoc") {
00450 kdDebug() << "Not a valid kdeveloptoc file: " << m_parent->indexFileName() << endl;
00451 return false;
00452 }
00453 return true;
00454 }
00455
00456 virtual bool startElement(const QString& , const QString& localName, const QString& , const QXmlAttributes& )
00457 {
00458 if (localName == "title")
00459 m_titleNext = true;
00460 return true;
00461 }
00462
00463 virtual bool characters(const QString& ch)
00464 {
00465 if (m_titleNext) {
00466 m_parent->setText(0, ch);
00467 return false;
00468 }
00469 return true;
00470 }
00471
00472 private:
00473 DocTreeTocFolder* m_parent;
00474 bool m_titleNext;
00475 };
00476 #endif
00477
00478 DocTreeTocFolder::DocTreeTocFolder(const QString& name, KListView *parent, const QString &fileName, const QString &context)
00479 : DocTreeItem(parent, Folder, fileName, context, true)
00480 {
00481 setFileName( fileName );
00482 setIndexFileName( fileName );
00483 setText(0, name);
00484
00485 QFileInfo fi(indexFileName());
00486 toc_name = fi.baseName();
00487 }
00488
00489 DocTreeTocFolder::DocTreeTocFolder(KListView *parent, const QString &fileName, const QString &context)
00490 : DocTreeItem(parent, Folder, fileName, context, true)
00491 {
00492 setFileName( fileName );
00493 setIndexFileName( fileName );
00494
00495 QFileInfo fi(indexFileName());
00496 toc_name = fi.baseName();
00497
00498 refresh();
00499 }
00500
00501 #if 0
00502 void DocTreeTocFolder::init()
00503 {
00504 QFileInfo fi(indexFileName());
00505 toc_name = fi.baseName();
00506 base = DocTreeViewTool::tocLocation( indexFileName() );
00507
00508 QFile f(indexFileName());
00509 if (!f.open(IO_ReadOnly))
00510 {
00511 kdDebug(9002) << "Could not read doc toc: " << indexFileName() << endl;
00512 return;
00513 }
00514
00515 QXmlInputSource s(&f);
00516 QXmlSimpleReader r;
00517 TocNameExtractor t(this);
00518 r.setContentHandler(&t);
00519 r.setDTDHandler(&t);
00520 r.parse(&s);
00521 }
00522 #endif
00523
00524 void DocTreeTocFolder::refresh()
00525 {
00526 DocTreeItem::refresh();
00527
00528 QFileInfo fi(indexFileName());
00529 toc_name = fi.baseName();
00530 base = DocTreeViewTool::tocLocation( indexFileName() );
00531
00532 QFile f(indexFileName());
00533 if (!f.open(IO_ReadOnly))
00534 {
00535 kdDebug(9002) << "Could not read doc toc: " << indexFileName() << endl;
00536 return;
00537 }
00538
00539 QDomDocument doc;
00540 if (!doc.setContent(&f) || doc.doctype().name() != "kdeveloptoc")
00541 {
00542 kdDebug() << "Not a valid kdeveloptoc file: " << indexFileName() << endl;
00543 return;
00544 }
00545 f.close();
00546
00547 QDomElement docEl = doc.documentElement();
00548 QDomElement titleEl = docEl.namedItem("title").toElement();
00549 setText(0, titleEl.firstChild().toText().data());
00550
00551 QDomElement childEl = docEl.firstChild().toElement();
00552
00554 addTocSect(0, childEl, 1);
00555 }
00556
00557
00558 void DocTreeTocFolder::addTocSect(DocTreeItem *parent, QDomElement childEl, uint level)
00559 {
00560 QListViewItem *lastChildItem = 0;
00561 while (!childEl.isNull())
00562 {
00563 if (childEl.tagName() == QString("tocsect%1").arg(level))
00564 {
00565 QString name = childEl.attribute("name");
00566 QString url = childEl.attribute("url");
00567 DocTreeItem *item = 0;
00568 if (parent == 0) {
00569 item = new DocTreeItem(this, Book, name, DocTreeItem::context());
00570 item->postInit();
00571 } else {
00572 item = new DocTreeItem(parent, Doc, name, DocTreeItem::context());
00573 item->postInit();
00574 }
00575
00576 if (!url.isEmpty())
00577 item->setFileName(base + url);
00578
00579 if (lastChildItem)
00580 item->moveItem(lastChildItem);
00581 lastChildItem = item;
00582
00583 QDomElement grandchildEl = childEl.firstChild().toElement();
00584 addTocSect(item, grandchildEl, level+1);
00585 }
00586 childEl = childEl.nextSibling().toElement();
00587 }
00588 }
00589
00590
00591
00592
00593 class DocTreeDevHelpFolder : public DocTreeItem
00594 {
00595 public:
00596 DocTreeDevHelpFolder(KListView *parent, const QString &fileName, const QString &context);
00597
00598 QString tocName() const { return toc_name; }
00599
00600 virtual void refresh();
00601
00602 private:
00603 void addTocSect(DocTreeItem *parent, QDomElement childEl);
00604
00605 QString base;
00606 QString toc_name;
00607 };
00608
00609 DocTreeDevHelpFolder::DocTreeDevHelpFolder(KListView *parent, const QString &fileName, const QString &context)
00610 : DocTreeItem(parent, Folder, fileName, context)
00611 {
00612 setIndexFileName(fileName);
00613 }
00614
00615 void DocTreeDevHelpFolder::refresh()
00616 {
00617 DocTreeItem::refresh();
00618
00619 QTime t;
00620 t.start();
00621
00622 QFileInfo fi(indexFileName());
00623 toc_name = fi.baseName();
00624 base = DocTreeViewTool::devhelpLocation( indexFileName() );
00625
00626 QFile f(indexFileName());
00627 if (!f.open(IO_ReadOnly))
00628 {
00629 kdDebug(9002) << "Could not read devhelp toc: " << indexFileName() << endl;
00630 return;
00631 }
00632
00633 QDomDocument doc;
00634 if (!doc.setContent(&f))
00635 {
00636 kdDebug() << "Not a valid devhelp file: " << indexFileName() << endl;
00637 return;
00638 }
00639 f.close();
00640
00641 QDomElement docEl = doc.documentElement();
00642 QDomElement chaptersEl = docEl.namedItem("chapters").toElement();
00643 setText(0, docEl.attribute("title"));
00644 setFileName( base + docEl.attribute("link") );
00645
00646 QDomElement childEl = chaptersEl.firstChild().toElement();
00647 addTocSect(0, childEl);
00648 }
00649
00650 void DocTreeDevHelpFolder::addTocSect(DocTreeItem *parent, QDomElement childEl)
00651 {
00652 QListViewItem *lastChildItem = 0;
00653 while (!childEl.isNull())
00654 {
00655 if ( (childEl.tagName() == "sub") || (childEl.tagName() == "chapter"))
00656 {
00657 QString name = childEl.attribute("name");
00658 QString url = childEl.attribute("link");
00659 DocTreeItem *item = 0;
00660 if (parent == 0) {
00661 item = new DocTreeItem(this, Book, name, DocTreeItem::context());
00662 item->postInit();
00663 } else {
00664 item = new DocTreeItem(parent, Doc, name, DocTreeItem::context());
00665 item->postInit();
00666 }
00667 if (!url.isEmpty())
00668 item->setFileName(base + url);
00669
00670 if (lastChildItem)
00671 item->moveItem(lastChildItem);
00672 lastChildItem = item;
00673
00674 QDomElement grandchildEl = childEl.firstChild().toElement();
00675 addTocSect(item, grandchildEl);
00676 }
00677 childEl = childEl.nextSibling().toElement();
00678 }
00679 }
00680
00681
00682
00683
00684
00685 #ifdef WITH_DOCBASE
00686
00687
00688 class DocTreeDocbaseFolder : public DocTreeItem
00689 {
00690 public:
00691 DocTreeDocbaseFolder(KListView *parent, const QString &context);
00692 virtual void refresh();
00693 private:
00694 void readDocbaseFile(FILE *f);
00695 };
00696
00697
00698 DocTreeDocbaseFolder::DocTreeDocbaseFolder(KListView *parent, const QString &context)
00699 : DocTreeItem(parent, Folder, i18n("Documentation Base"), context)
00700 {
00701 }
00702
00703
00704 void DocTreeDocbaseFolder::readDocbaseFile(FILE *f)
00705 {
00706 char buf[1024];
00707 QString title;
00708 bool html = false;
00709 while (fgets(buf, sizeof buf, f))
00710 {
00711 QString s = buf;
00712 if (s.right(1) == "\n")
00713 s.truncate(s.length()-1);
00714
00715 if (s.left(7) == "Title: ")
00716 title = s.mid(7, s.length()-7);
00717 else if (s.left(8) == "Format: ")
00718 html = s.find("HTML", 8, false) != -1;
00719 else if (s.left(7) == "Index: "
00720 && html && !title.isEmpty())
00721 {
00722 QString filename = s.mid(7, s.length()-7);
00723 DocTreeItem *item = new DocTreeItem(this, Doc, title, context());
00724 item->postInit();
00725 item->setFileName(filename);
00726 break;
00727 }
00728 else if (s.left(9) == "Section: "
00729 && s.find("programming", 9, false) == -1)
00730 break;
00731 }
00732 }
00733
00734
00735 void DocTreeDocbaseFolder::refresh()
00736 {
00737 DocTreeItem::refresh();
00738
00739 QDir d("/usr/share/doc-base");
00740 QStringList fileList = d.entryList("*", QDir::Files);
00741 QStringList::Iterator it;
00742 for (it = fileList.begin(); it != fileList.end(); ++it)
00743 {
00744 FILE *f;
00745 if ( (f = fopen( QFile::encodeName(d.filePath(*it)), "r")) != 0)
00746 {
00747 readDocbaseFile(f);
00748 fclose(f);
00749 }
00750 }
00751 }
00752
00753
00754 #endif
00755
00756
00757
00758
00759
00760
00761 class DocTreeBookmarksFolder : public DocTreeItem
00762 {
00763 public:
00764 DocTreeBookmarksFolder(KListView *parent, const QString &context);
00765 virtual void refresh();
00766 };
00767
00768 DocTreeBookmarksFolder::DocTreeBookmarksFolder(KListView *parent, const QString &context)
00769 : DocTreeItem(parent, Folder, i18n("Bookmarks"), context)
00770 {}
00771
00772 void DocTreeBookmarksFolder::refresh()
00773 {
00774 DocTreeItem::refresh();
00775
00776 QStringList othersTitle, othersURL;
00777 DocTreeViewTool::getBookmarks(&othersTitle, &othersURL);
00778 QStringList::Iterator it1, it2;
00779 for (it1 = othersTitle.begin(), it2 = othersURL.begin();
00780 it1 != othersTitle.end() && it2 != othersURL.end();
00781 ++it1, ++it2)
00782 {
00783 DocTreeItem *item = new DocTreeItem(this, Book, *it1, context());
00784 item->postInit();
00785 item->setFileName(*it2);
00786 }
00787 }
00788
00789
00790
00791
00792
00793
00794 class DocTreeProjectFolder : public DocTreeItem
00795 {
00796 public:
00797 DocTreeProjectFolder(KListView *parent, const QString &context);
00798 void setProject(KDevProject *project)
00799 { m_project = project; }
00800 virtual void refresh();
00801
00802 private:
00803 KDevProject *m_project;
00804 QString m_userdocDir, m_apidocDir;
00805 };
00806
00807 DocTreeProjectFolder::DocTreeProjectFolder(KListView *parent, const QString &context)
00808 : DocTreeItem(parent, Folder, i18n("Current Project"), context), m_project(0)
00809 {}
00810
00811
00812 void DocTreeProjectFolder::refresh()
00813 {
00814 DocTreeItem::refresh();
00815
00817 if( !m_project )
00818 return;
00819
00820 m_userdocDir = DomUtil::readEntry(
00821 *m_project->projectDom() , "/kdevdoctreeview/projectdoc/userdocDir");
00822 m_apidocDir = DomUtil::readEntry(
00823 *m_project->projectDom() , "/kdevdoctreeview/projectdoc/apidocDir");
00824
00825
00826 QDir apidir( m_apidocDir );
00827 if (apidir.exists())
00828 {
00829 QStringList entries = apidir.entryList("*.html", QDir::Files);
00830 QString filename = apidir.absPath() + "/index.html";
00831 if (!QFileInfo(filename).exists())
00832 return;
00833 DocTreeItem *item = new DocTreeItem(
00834 this, Book, i18n("API of %1").arg(m_project->projectName() ), context());
00835 item->postInit();
00836 item->setFileName(filename);
00837 for (QStringList::Iterator it = entries.begin(); it != entries.end(); ++it)
00838 {
00839 filename = *it;
00840 DocTreeItem *ditem = new DocTreeItem(item,
00841 Doc, QFileInfo(filename).baseName() , context());
00842 ditem->postInit();
00843 ditem->setFileName(apidir.absPath() +"/"+ filename);
00844 }
00845 }
00846
00847 QDir userdir( m_userdocDir );
00848 if (userdir.exists())
00849 {
00850 QStringList entries = userdir.entryList("*.html", QDir::Files);
00851 QString filename = userdir.absPath() + "/index.html";
00852 if (!QFileInfo(filename).exists())
00853 return;
00854 DocTreeItem *item = new DocTreeItem(
00855 this, Book, i18n("Usedoc for %1").arg(m_project->projectName() ), context());
00856 item->postInit();
00857 item->setFileName(filename);
00858 for (QStringList::Iterator it = entries.begin(); it != entries.end(); ++it)
00859 {
00860 filename = *it;
00861 DocTreeItem *ditem = new DocTreeItem(item,
00862 Doc, QFileInfo(filename).baseName() , context());
00863 ditem->postInit();
00864 ditem->setFileName(userdir.absPath() +"/"+ filename);
00865 }
00866 }
00867
00868 if (!firstChild())
00869 setExpandable(false);
00870 }
00871
00872
00873
00874
00875
00876
00877 class DocTreeQtFolder : public DocTreeItem
00878 {
00879 public:
00880 DocTreeQtFolder(QString xml, QString name, KListView *parent, const QString &context);
00881 void refresh();
00882 private:
00883 QString filename;
00884 };
00885
00886 DocTreeQtFolder::DocTreeQtFolder(QString xml, QString name, KListView *parent,
00887 const QString &context)
00888 : DocTreeItem(parent, Folder, name, context, true)
00889 {
00890 setIndexFileName(xml);
00891 }
00892
00893 void DocTreeQtFolder::refresh()
00894 {
00895 DocTreeItem::refresh();
00896
00897 QFileInfo fi(indexFileName());
00898
00899 QFile f(indexFileName());
00900 if (!f.open(IO_ReadOnly))
00901 {
00902 kdDebug(9002) << "Could not read" << indexFileName() << endl;
00903
00904 return;
00905 }
00906 QDomDocument doc;
00907 if (!doc.setContent(&f) || doc.doctype().name() != "DCF")
00908 {
00909 kdDebug(9002) << "Not a valid DCF file: " << indexFileName() << endl;
00910 return;
00911 }
00912
00913 f.close();
00914
00915 QDomElement docEl = doc.documentElement();
00916 QDomElement titleEl = docEl.namedItem("DCF").toElement();
00917
00918 setFileName(fi.dirPath( true ) +"/"+ docEl.attribute("ref", QString::null));
00919
00920 QDomElement childEl = docEl.lastChild().toElement();
00921 while (!childEl.isNull())
00922 {
00923 if (childEl.tagName() == "section")
00924 {
00925 QString ref = childEl.attribute("ref");
00926 QString title = childEl.attribute("title");
00927
00928
00929
00930
00931
00932
00933 DocTreeItem* item = item = new DocTreeItem(this, Book, title, context());
00934 item->postInit();
00935 item->setFileName(fi.dirPath( true ) +"/"+ ref);
00936
00937 QDomElement grandChild = childEl.lastChild().toElement();
00938 while(!grandChild.isNull())
00939 {
00940 if (grandChild.tagName() == "keyword")
00941 {
00942 QString dref = grandChild.attribute("ref");
00943 QString dtitle = grandChild.text();
00944
00945 DocTreeItem* dItem = new DocTreeItem(item, Doc, dtitle, context());
00946 dItem->postInit();
00947 dItem->setFileName(fi.dirPath( true ) +"/"+ dref);
00948 }
00949 grandChild = grandChild.previousSibling().toElement();
00950 }
00951
00952
00953 childEl = childEl.previousSibling().toElement();
00954 }
00955 }
00956 }
00957
00958 bool DocTreeViewWidget::initKDocKDELibs()
00959 {
00960 return true;
00961 }
00962
00963
00964
00965
00966
00967 DocTreeViewWidget::DocTreeViewWidget(DocTreeViewPart *part)
00968 : QVBox(0, "doc tree widget"), m_activeTreeItem ( 0L ), indexMode ( filteredMode ),
00969 subStringSearch( false )
00970 {
00971
00972
00973 modeSwitch = new KTabCtl(this, "mode switch");
00974
00975
00976 treeWidget = new QVBox(modeSwitch, "tree mode widget");
00977 indexWidget = new QVBox(modeSwitch, "index mode widget");
00978
00979
00980 QHBox *hbo = new QHBox(indexWidget, "label + edit");
00981 hbo->setMargin( 2 );
00982 QLabel *l = new QLabel( 0, i18n("Se&arch:"), hbo, "search-label" );
00983 filterEdit = new DocLineEdit( hbo, "index mode filter line edit" );
00984 l->setBuddy(filterEdit);
00985
00986 subSearchButton = new QToolButton ( hbo, "sub search check" );
00987 subSearchButton->setSizePolicy ( QSizePolicy ( (QSizePolicy::SizeType)0, ( QSizePolicy::SizeType)0, 0, 0, 0) );
00988 subSearchButton->setPixmap ( SmallIcon ( "grep" ) );
00989 subSearchButton->setToggleButton(true);
00990 QToolTip::add ( subSearchButton, i18n ( "Search substrings" ) );
00991 QWhatsThis::add(subSearchButton, i18n("<b>Search substrings</b><p>Index view searches for substrings in index items if toggled."));
00992
00993 indexModeSwitch = new QToolButton ( hbo, "index mode switch" );
00994 indexModeSwitch->setSizePolicy ( QSizePolicy ( (QSizePolicy::SizeType)0, ( QSizePolicy::SizeType)0, 0, 0, 0) );
00995 indexModeSwitch->setPixmap ( SmallIcon ( "contents" ) );
00996 indexModeSwitch->setToggleButton(true);
00997 indexModeSwitch->setOn( true );
00998 QToolTip::add ( indexModeSwitch, i18n ( "Show topics for index items" ) );
00999 QWhatsThis::add(indexModeSwitch, i18n("<b>Show topics for index items</b><p>Index view shows topics to which index items belong if toggled."));
01000
01001 indexView = new KListView ( indexWidget, "documentation index list view" );
01002
01003 indexView->setFocusPolicy(ClickFocus);
01004 indexView->setResizeMode(QListView::LastColumn);
01005 indexView->addColumn(QString::null);
01006 indexView->setSorting(0);
01007 indexView->header()->hide();
01008
01009 connect ( filterEdit, SIGNAL ( textChanged(const QString &) ), this, SLOT ( slotFilterTextChanged(const QString &) ) );
01010 connect ( filterEdit, SIGNAL ( returnPressed() ), this, SLOT ( slotFilterReturn() ) );
01011 connect ( filterEdit, SIGNAL ( upPressed() ), this, SLOT ( slotIndexPrevMatch() ) );
01012 connect ( filterEdit, SIGNAL ( downPressed() ), this, SLOT ( slotIndexNextMatch() ) );
01013 connect ( filterEdit, SIGNAL ( pgupPressed() ), this, SLOT ( slotIndexPgUp() ) );
01014 connect ( filterEdit, SIGNAL ( pgdownPressed() ), this, SLOT ( slotIndexPgDown() ) );
01015 connect ( filterEdit, SIGNAL ( homePressed() ), this, SLOT ( slotIndexHome() ) );
01016 connect ( filterEdit, SIGNAL ( endPressed() ), this, SLOT ( slotIndexEnd() ) );
01017 connect ( indexView, SIGNAL ( executed(QListViewItem *) ), this, SLOT ( slotIndexItemExecuted(QListViewItem *) ) );
01018 connect ( indexView, SIGNAL ( returnPressed(QListViewItem *) ), this, SLOT ( slotIndexItemExecuted(QListViewItem *) ) );
01019
01020 connect ( modeSwitch, SIGNAL ( tabSelected(int) ), this, SLOT ( slotCurrentTabChanged(int) ) );
01021
01022 connect ( subSearchButton, SIGNAL ( clicked() ), this, SLOT ( slotSubstringCheckClicked() ) );
01023 connect ( indexModeSwitch, SIGNAL ( clicked() ), this, SLOT ( slotIndexModeCheckClicked() ) );
01024
01025
01026
01027
01028 searchToolbar = new QHBox ( treeWidget, "search toolbar" );
01029 searchToolbar->setMargin ( 2 );
01030 searchToolbar->setSpacing ( 2 );
01031
01032 completionCombo = new KHistoryCombo ( true, searchToolbar, "completion combo box" );
01033
01034 startButton = new QToolButton ( searchToolbar, "start searching" );
01035 startButton->setSizePolicy ( QSizePolicy ( (QSizePolicy::SizeType)0, ( QSizePolicy::SizeType)0, 0, 0, startButton->sizePolicy().hasHeightForWidth()) );
01036 startButton->setPixmap ( SmallIcon ( "key_enter" ) );
01037 QToolTip::add ( startButton, i18n ( "Start searching" ) );
01038 QWhatsThis::add(startButton, i18n("<b>Start searching</b><p>Searches through the documentation topics for a given term and shows the topic found."));
01039
01040 nextButton = new QToolButton ( searchToolbar, "next match button" );
01041 nextButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType )0, ( QSizePolicy::SizeType) 0, 0, 0, nextButton->sizePolicy().hasHeightForWidth()) );
01042 nextButton->setPixmap ( SmallIcon ( "next" ) );
01043 QToolTip::add ( nextButton, i18n ( "Jump to next matching entry" ) );
01044 QWhatsThis::add(nextButton, i18n("<b>Jump to next matching entry</b><p>Shows the next topic found."));
01045 nextButton->setEnabled( false );
01046
01047 prevButton = new QToolButton ( searchToolbar, "previous match button" );
01048 prevButton->setSizePolicy ( QSizePolicy ( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, prevButton->sizePolicy().hasHeightForWidth()) );
01049 prevButton->setPixmap ( SmallIcon ( "previous" ) );
01050 QToolTip::add ( prevButton, i18n ( "Jump to previous matching entry" ) );
01051 QWhatsThis::add(prevButton, i18n("<b>Jump to previous matching entry</b><p>Shows the previous topic found."));
01052 prevButton->setEnabled( false );
01053
01054 docView = new KListView ( treeWidget, "documentation list view" );
01055
01056 docView->setFocusPolicy(ClickFocus);
01057 docView->setRootIsDecorated(true);
01058 docView->setResizeMode(QListView::LastColumn);
01059 docView->setSorting(-1);
01060 docView->header()->hide();
01061 docView->addColumn(QString::null);
01062
01063 folder_bookmarks = new DocTreeBookmarksFolder(docView, "ctx_bookmarks");
01064 folder_bookmarks->postInit();
01065
01066 folder_project = new DocTreeProjectFolder(docView, "ctx_current");
01067 folder_project->postInit();
01068
01069 #ifdef WITH_DOCBASE
01070 folder_docbase = new DocTreeDocbaseFolder(docView, "ctx_docbase");
01071 folder_docbase->postInit();
01072 #endif
01073
01074
01075 KConfig *configdh = DocTreeViewFactory::instance()->config();
01076 if (configdh)
01077 {
01078 configdh->setGroup("TocDevHelp");
01079 QString firstScan = configdh->readEntry("FirstScan", "yes");
01080 if (firstScan != "no")
01081 {
01082 DocTreeViewTool::scanDevHelpDirs();
01083 configdh->writeEntry("FirstScan", "no");
01084 }
01085 }
01086
01087 KStandardDirs *dirs = DocTreeViewFactory::instance()->dirs();
01088 QStringList dhtocs = dirs->findAllResources("docdevhelp", QString::null, false, true);
01089 for (QStringList::Iterator tit = dhtocs.begin(); tit != dhtocs.end(); ++tit) {
01090 DocTreeDevHelpFolder* item = new DocTreeDevHelpFolder(docView, *tit, QString("ctx_%1").arg(*tit));
01091 item->postInit();
01092 folder_devhelp.append(item);
01093 }
01094
01095
01096
01097 QStringList tocs = dirs->findAllResources("doctocs", QString::null, false, true);
01098 QString cache = dirs->findResource("data", "kdevdoctreeview/docpartcache");
01099 bool regenerateCache = false;
01100 QFile cacheFile(cache);
01101 if (!cache.isEmpty() && cacheFile.open(IO_ReadOnly)) {
01102 QDataStream ds(&cacheFile);
01103 int version;
01104 ds >> version;
01105
01106 if (version == 1) {
01107 QString fileName, title;
01108 while (!ds.atEnd()) {
01109 ds >> fileName >> title;
01110 if (tocs.contains(fileName) && QFileInfo(fileName).lastModified() < QFileInfo(cacheFile).lastModified()) {
01111
01112 DocTreeTocFolder* item = new DocTreeTocFolder(title, docView, fileName, QString("ctx_%1").arg(fileName));
01113 item->postInit();
01114 folder_toc.append(item);
01115 tocs.remove(fileName);
01116 } else {
01117
01118 }
01119 }
01120 } else {
01121
01122 regenerateCache = true;
01123 }
01124 cacheFile.close();
01125 }
01126
01127 if (tocs.count()) {
01128 regenerateCache = true;
01129 QStringList tocs = dirs->findAllResources("doctocs", QString::null, false, true);
01130 for (QStringList::Iterator tit = tocs.begin(); tit != tocs.end(); ++tit) {
01131 DocTreeTocFolder* item = new DocTreeTocFolder(docView, *tit, QString("ctx_%1").arg(*tit));
01132 item->postInit();
01133 folder_toc.append(item);
01134 }
01135 }
01136
01137 if (regenerateCache) {
01138
01139 if (cache.isEmpty()) {
01140 cache = dirs->saveLocation("data");
01141 cache += "kdevdoctreeview/docpartcache";
01142 cacheFile.setName(cache);
01143 }
01144
01145 cacheFile.open(IO_WriteOnly);
01146 QDataStream ds(&cacheFile);
01147 ds << 1;
01148 for (DocTreeTocFolder* f = folder_toc.first(); f; f = folder_toc.next())
01149 ds << f->fileName() << f->text(0);
01150 }
01151
01152
01153
01154 KConfig *config = DocTreeViewFactory::instance()->config();
01155 if (config)
01156 {
01157 config->setGroup("General KDoc");
01158 QMap<QString, QString> dmap = config->entryMap("General KDoc");
01159 QString kdocdir(KDELIBS_DOCDIR);
01160 kdocdir = URLUtil::envExpand(kdocdir);
01161 if (dmap.empty() && (!kdocdir.isEmpty()))
01162 {
01163 config->writePathEntry("KDE Libraries (KDoc)", kdocdir);
01164 dmap["KDE Libraries (KDoc)"] = kdocdir;
01165 }
01166
01167 QMap<QString, QString>::Iterator it;
01168 for (it = dmap.begin(); it != dmap.end(); ++it)
01169 {
01170 DocTreeKDELibsFolder *kdf = new DocTreeKDELibsFolder(it.data(), it.key(), docView, "ctx_kdelibs");
01171 kdf->postInit();
01172 folder_kdoc.append(kdf);
01173 }
01174 }
01175
01176 if (config)
01177 {
01178 config->setGroup("General Doxygen");
01179 QMap<QString, QString> xmap = config->entryMap("General Doxygen");
01180 QString doxydir(KDELIBS_DOXYDIR);
01181 doxydir = URLUtil::envExpand(doxydir);
01182 if (xmap.empty() && (!doxydir.isEmpty()))
01183 {
01184 config->writePathEntry("KDE Libraries (Doxygen)", doxydir);
01185 xmap["KDE Libraries (Doxygen)"] = doxydir;
01186 }
01187
01188 QMap<QString, QString>::Iterator it;
01189 for (it = xmap.begin(); it != xmap.end(); ++it)
01190 {
01191 DocTreeDoxygenFolder *dxf = new DocTreeDoxygenFolder(config->readPathEntry(it.key()), it.key(), docView, "ctx_doxygen");
01192 dxf->postInit();
01193 folder_doxygen.append(dxf);
01194 }
01195 }
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 if (config)
01207 {
01208 config->setGroup("General Qt");
01209 QMap<QString, QString> emap = config->entryMap("General Qt");
01210
01211 QString qtdocdir(config->readPathEntry("qtdocdir", QT_DOCDIR));
01212 qtdocdir = URLUtil::envExpand(qtdocdir);
01213 if (emap.empty() && (!qtdocdir.isEmpty()))
01214 {
01215 #if QT_VERSION >= 0x030200
01216 config->writePathEntry("Qt Reference Documentation", qtdocdir + QString("/qt.dcf"));
01217 emap["Qt Reference Documentation"] = qtdocdir + QString("/qt.dcf");
01218 config->writePathEntry("Qt Assistant Manual", qtdocdir + QString("/assistant.dcf"));
01219 emap["Qt Assistant Manual"] = qtdocdir + QString("/assistant.dcf");
01220 config->writePathEntry("Qt Designer Manual", qtdocdir + QString("/designer.dcf"));
01221 emap["Qt Designer Manual"] = qtdocdir + QString("/designer.dcf");
01222 config->writePathEntry("Guide to the Qt Translation Tools", qtdocdir + QString("/linguist.dcf"));
01223 emap["Guide to the Qt Translation Tools"] = qtdocdir + QString("/linguist.dcf");
01224 config->writePathEntry("qmake User Guide", qtdocdir + QString("/qmake.dcf"));
01225 emap["qmake User Guide"] = qtdocdir + QString("/qmake.dcf");
01226 #else
01227 config->writePathEntry("Qt Reference Documentation", qtdocdir + QString("/qt.xml"));
01228 emap["Qt Reference Documentation"] = qtdocdir + QString("/qt.xml");
01229 config->writePathEntry("Qt Assistant Manual", qtdocdir + QString("/assistant.xml"));
01230 emap["Qt Assistant Manual"] = qtdocdir + QString("/assistant.xml");
01231 config->writePathEntry("Qt Designer Manual", qtdocdir + QString("/designer.xml"));
01232 emap["Qt Designer Manual"] = qtdocdir + QString("/designer.xml");
01233 config->writePathEntry("Guide to the Qt Translation Tools", qtdocdir + QString("/linguist.xml"));
01234 emap["Guide to the Qt Translation Tools"] = qtdocdir + QString("/linguist.xml");
01235 config->writePathEntry("qmake User Guide", qtdocdir + QString("/qmake.xml"));
01236 emap["qmake User Guide"] = qtdocdir + QString("/qmake.xml");
01237 #endif
01238 }
01239
01240 QMap<QString, QString>::Iterator it;
01241 for (it = emap.begin(); it != emap.end(); ++it)
01242 {
01243 DocTreeQtFolder *qtf = new DocTreeQtFolder(it.data(), it.key(), docView, "ctx_qt");
01244 qtf->postInit();
01245 folder_qt.append(qtf);
01246 }
01247 }
01248
01249 connect ( nextButton, SIGNAL ( clicked() ), this, SLOT ( slotJumpToNextMatch() ) );
01250 connect ( prevButton, SIGNAL ( clicked() ), this, SLOT ( slotJumpToPrevMatch() ) );
01251 connect ( startButton, SIGNAL ( clicked() ), this, SLOT ( slotStartSearching() ) );
01252 connect ( completionCombo, SIGNAL ( returnPressed ( const QString& ) ), this, SLOT ( slotHistoryReturnPressed ( const QString& ) ) );
01253
01254 connect( docView, SIGNAL(executed(QListViewItem*)),
01255 this, SLOT(slotItemExecuted(QListViewItem*)) );
01256 connect( docView, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
01257 this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)) );
01258 connect ( docView, SIGNAL ( selectionChanged ( QListViewItem* ) ), this, SLOT ( slotSelectionChanged ( QListViewItem* ) ) );
01259
01260 m_part = part;
01261
01262
01263 modeSwitch->setBorder(false);
01264 modeSwitch->addTab(treeWidget, i18n("Co&ntents"));
01265 modeSwitch->addTab(indexWidget, i18n("&Index"));
01266 }
01267
01268
01269 DocTreeViewWidget::~DocTreeViewWidget()
01270 {}
01271
01272 void DocTreeViewWidget::searchForItem ( const QString& currentText )
01273 {
01274 completionCombo->addToHistory( currentText );
01275
01276 QListViewItemIterator docViewIterator( docView );
01277 while( docViewIterator.current() )
01278 {
01279
01280 docViewIterator.current()->setOpen(true);
01281 docViewIterator.current()->setOpen(false);
01282
01283 if( docViewIterator.current()->text(0).find( currentText, false ) >= 0 )
01284 {
01285 searchResultList.append( docViewIterator.current() );
01286 }
01287 ++docViewIterator;
01288 }
01289 }
01290
01291 void DocTreeViewWidget::slotJumpToNextMatch()
01292 {
01293 if( searchResultList.next() )
01294 {
01295 docView->setSelected ( searchResultList.current(), true );
01296 docView->ensureItemVisible ( searchResultList.current() );
01297 slotItemExecuted ( searchResultList.current() );
01298 prevButton->setEnabled( true );
01299
01300 if(searchResultList.current() == searchResultList.getLast() )
01301 nextButton->setEnabled( false );
01302 }
01303 else
01304 {
01305 searchResultList.last();
01306 }
01307
01308 }
01309
01310 void DocTreeViewWidget::slotJumpToPrevMatch()
01311 {
01312 if( searchResultList.prev() )
01313 {
01314 docView->setSelected ( searchResultList.current(), true );
01315 docView->ensureItemVisible ( searchResultList.current() );
01316 slotItemExecuted ( searchResultList.current() );
01317 nextButton->setEnabled( true );
01318
01319 if(searchResultList.current() == searchResultList.getFirst() )
01320 prevButton->setEnabled( false );
01321 }
01322 else
01323 {
01324 searchResultList.first();
01325 }
01326 }
01327
01328 void DocTreeViewWidget::slotStartSearching()
01329 {
01330 QString currentText = completionCombo->currentText();
01331 slotHistoryReturnPressed ( currentText );
01332 }
01333
01334 void DocTreeViewWidget::slotHistoryReturnPressed ( const QString& currentText )
01335 {
01336 if( !docView->selectedItem() )
01337 docView->setCurrentItem( docView->firstChild() );
01338
01339 nextButton->setEnabled( false );
01340 prevButton->setEnabled( false );
01341 searchResultList.clear();
01342
01343 if( currentText.length() > 0 )
01344 searchForItem( currentText );
01345
01346
01347 if ( searchResultList.count() )
01348 {
01349 kdDebug ( 9002 ) << "Found a matching entry!" << endl;
01350 docView->setSelected ( searchResultList.first(), true );
01351 docView->ensureItemVisible ( searchResultList.first() );
01352 slotItemExecuted ( searchResultList.first() );
01353 }
01354 if ( searchResultList.count() > 1 )
01355 {
01356 nextButton->setEnabled( true );
01357 }
01358 }
01359
01360 void DocTreeViewWidget::slotSelectionChanged ( QListViewItem* item )
01361 {
01362 contextItem = item;
01363
01364 if( !item->parent() )
01365 {
01366 QListViewItem * myChild = item->firstChild();
01367 while( myChild && myChild->parent())
01368 {
01369 myChild->setOpen( true );
01370 myChild->setOpen( false );
01371
01372 myChild = myChild->itemBelow();
01373 }
01374 }
01375
01376 }
01377
01378 void DocTreeViewWidget::slotItemExecuted(QListViewItem *item)
01379 {
01380 if (!item)
01381 return;
01382
01383
01384
01385 DocTreeItem *dtitem = static_cast<DocTreeItem*>(item);
01386
01387 QString ident = dtitem->fileName();
01388 if (ident.isEmpty())
01389 return;
01390
01391
01392 if (ident.right(4) == ".toc")
01393 {
01394 dtitem = static_cast<DocTreeItem*>(dtitem->firstChild());
01395 if (!dtitem) return;
01396 ident = dtitem->fileName();
01397 if (ident.isEmpty()) return;
01398 }
01399
01400 kdDebug(9002) << "Showing: " << ident << endl;
01401 m_part->partController()->showDocument(KURL(ident));
01402 m_part->mainWindow()->lowerView(this);
01403 }
01404
01405
01406 void DocTreeViewWidget::slotContextMenu(KListView *, QListViewItem *item, const QPoint &p)
01407 {
01408 if (!item)
01409 return;
01410 contextItem = item;
01411 KPopupMenu popup(i18n("Documentation Tree"), this);
01412
01413 DocTreeItem *dItem = dynamic_cast<DocTreeItem*>( item );
01414 DocumentationContext dcontext( dItem->fileName(), "" );
01415
01416 QListViewItem* i = contextItem;
01417 while(i->parent())
01418 {
01419 i = i->parent();
01420 }
01421 if ( i == folder_project )
01422 {
01423 int id = popup.insertItem(i18n("Project Properties"), this, SLOT(slotConfigureProject()));
01424 popup.setWhatsThis(id, i18n("<b>Project properties</b><p>Displays <b>Project Documentation</b> properties dialog."));
01425 }
01426 else
01427 {
01428 int id = popup.insertItem(i18n("Properties"), this, SLOT(slotConfigure()));
01429 popup.setWhatsThis(id, i18n("<b>Properties</b><p>Displays <b>Documentation Tree</b> properties dialog."));
01430 }
01431 if ( i != folder_bookmarks && dItem && !dItem->fileName().isEmpty() )
01432 {
01433 int id = popup.insertItem(i18n("Add to Bookmarks"), this, SLOT(slotAddBookmark()));
01434 dcontext = DocumentationContext( dItem->fileName(), dItem->text(0) );
01435 popup.setWhatsThis(id, i18n("<b>Add to bookmarks</b><p>Adds currently selected topic to the bookmarks list."));
01436 }
01437 if ( contextItem->parent() && dItem && contextItem->parent() == folder_bookmarks )
01438 {
01439 int id = popup.insertItem(i18n("Remove"), this, SLOT(slotRemoveBookmark()));
01440 popup.setWhatsThis(id, i18n("<b>Remove</b><p>Removes currently selected bookmark from the bookmarks list."));
01441 dcontext = DocumentationContext( dItem->fileName(), dItem->text(0) );
01442 }
01443 m_part->core()->fillContextMenu( &popup , &dcontext );
01444 popup.exec(p);
01445 }
01446
01447
01448 void DocTreeViewWidget::slotConfigure()
01449 {
01450 KDialogBase dlg(KDialogBase::Tabbed, i18n("Customize Documentation Tree"),
01451 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, this,
01452 "customization dialog");
01453
01454 QVBox *vbox1 = dlg.addVBoxPage(i18n("Documentation Tree: Global"));
01455 DocTreeGlobalConfigWidget *w1 = new DocTreeGlobalConfigWidget( m_part, this, vbox1, "doctreeview global config widget");
01456 connect(&dlg, SIGNAL(okClicked()), w1, SLOT(accept()));
01457
01458 dlg.exec();
01459
01460 delete w1;
01461 }
01462
01463 void DocTreeViewWidget::slotConfigureProject()
01464 {
01465 KDialogBase dlg(KDialogBase::Tabbed, i18n("Customize Documentation Tree"),
01466 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, this,
01467 "customization dialog");
01468
01469 DocTreeProjectConfigWidget *w2 = 0;
01470
01471 if(m_part->project())
01472 {
01473 QVBox *vbox2 = dlg.addVBoxPage(i18n("Documentation Tree: Project"));
01474 w2 = new DocTreeProjectConfigWidget(this, vbox2, m_part->project(),"doctreeview project config widget");
01475 connect(&dlg, SIGNAL(okClicked()), w2, SLOT(accept()));
01476 dlg.exec();
01477 }
01478 if(w2)
01479 delete w2;
01480 }
01481
01482
01483 void DocTreeViewWidget::configurationChanged()
01484 {
01485 kdDebug(9002) << "DocTreeViewWidget::configurationChanged()" << endl;
01486 initKDocKDELibs();
01487 QTimer::singleShot(0, this, SLOT(refresh()));
01488 }
01489
01490
01491 void DocTreeViewWidget::refresh()
01492 {
01493 kdDebug(9002) << "DocTreeViewWidget::refresh()" << endl;
01494 folder_bookmarks->refresh();
01495 folder_project->refresh();
01496
01497
01498
01499
01500 folder_devhelp.setAutoDelete(true);
01501 folder_devhelp.clear();
01502 folder_devhelp.setAutoDelete(false);
01503
01504 KStandardDirs *dirs = DocTreeViewFactory::instance()->dirs();
01505 QStringList dhtocs = dirs->findAllResources("docdevhelp", QString::null, false, true);
01506 QStringList ignoredh( DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoredevhelp", "toc") );
01507
01508 for (QStringList::Iterator tit = dhtocs.begin(); tit != dhtocs.end(); ++tit)
01509 {
01510 if( !ignoredh.contains( QFileInfo(*tit).baseName() ) ) {
01511 DocTreeDevHelpFolder* item = new DocTreeDevHelpFolder(docView, *tit, QString("ctx_%1").arg(*tit));
01512 item->postInit();
01513 folder_devhelp.append(item);
01514 }
01515 }
01516
01517
01518 DocTreeTocFolder *item;
01519 for ( item = folder_toc.first(); item; item = folder_toc.next() )
01520 delete item;
01521
01522 folder_toc.clear();
01523
01524 QStringList tocs = dirs->findAllResources("doctocs", QString::null, false, true);
01525 QStringList ignore( DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoretocs", "toc") );
01526
01527 for (QStringList::Iterator tit = tocs.begin(); tit != tocs.end(); ++tit)
01528 {
01529 if( !ignore.contains( QFileInfo(*tit).baseName() ) ) {
01530 DocTreeTocFolder* item = new DocTreeTocFolder(docView, *tit, QString("ctx_%1").arg(*tit));
01531 item->postInit();
01532 folder_toc.append(item);
01533 }
01534 }
01535
01536 folder_kdoc.setAutoDelete(true);
01537 folder_kdoc.clear();
01538 folder_kdoc.setAutoDelete(false);
01539
01540 KConfig *config = DocTreeViewFactory::instance()->config();
01541 if (config)
01542 {
01543 QStringList ignorekdocs( DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignorekdocs", "toc") );
01544 config->setGroup("General KDoc");
01545 QMap<QString, QString> emap = config->entryMap("General KDoc");
01546 QMap<QString, QString>::Iterator it;
01547 for (it = emap.begin(); it != emap.end(); ++it)
01548 {
01549 if (!ignorekdocs.contains(it.key()))
01550 {
01551 DocTreeKDELibsFolder *kdf = new DocTreeKDELibsFolder(it.data(), it.key(), docView, "ctx_kdelibs");
01552 kdf->postInit();
01553 folder_kdoc.append(kdf);
01554 }
01555 }
01556 }
01557
01558 folder_doxygen.setAutoDelete(true);
01559 folder_doxygen.clear();
01560 folder_doxygen.setAutoDelete(false);
01561
01562 if (config)
01563 {
01564 QStringList ignoredoxygen( DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoredoxygen", "toc") );
01565 config->setGroup("General Doxygen");
01566 QMap<QString, QString> emap = config->entryMap("General Doxygen");
01567 QMap<QString, QString>::Iterator it;
01568 for (it = emap.begin(); it != emap.end(); ++it)
01569 {
01570 if (!ignoredoxygen.contains(it.key()))
01571 {
01572 DocTreeDoxygenFolder *dxf = new DocTreeDoxygenFolder(it.data(), it.key(), docView, "ctx_doxygen");
01573 dxf->postInit();
01574 folder_doxygen.append(dxf);
01575 }
01576 }
01577 }
01578
01579
01580 folder_qt.setAutoDelete(true);
01581 folder_qt.clear();
01582 folder_qt.setAutoDelete(false);
01583
01584 if (config)
01585 {
01586 QStringList ignoreqt_xml( DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoreqt_xml", "toc") );
01587 config->setGroup("General Qt");
01588 QMap<QString, QString> emap = config->entryMap("General Qt");
01589 QMap<QString, QString>::Iterator it;
01590 for (it = emap.begin(); it != emap.end(); ++it)
01591 {
01592 if (!ignoreqt_xml.contains(it.key()))
01593 {
01594 DocTreeQtFolder *qtf = new DocTreeQtFolder(it.data(), it.key(), docView, "ctx_qt");
01595 qtf->postInit();
01596 folder_qt.append(qtf);
01597 }
01598 }
01599 }
01600 }
01601
01602
01603 void DocTreeViewWidget::projectChanged(KDevProject *project)
01604 {
01605 folder_project->setProject(project);
01606
01607
01608
01609
01610 folder_project->refresh();
01611 if(!project)
01612 {
01613 kdDebug(9002) << "No Project...." << endl;
01614 return;
01615 }
01616
01617
01618
01619 docView->takeItem(folder_bookmarks);
01620 docView->takeItem(folder_project);
01621 #ifdef WITH_DOCBASE
01622 docView->takeItem(folder_docbase);
01623 #endif
01624 QPtrListIterator<DocTreeDevHelpFolder> itdh(folder_devhelp);
01625 for (; itdh.current(); ++itdh)
01626 docView->takeItem(itdh.current());
01627
01628 QPtrListIterator<DocTreeTocFolder> it1(folder_toc);
01629 for (; it1.current(); ++it1)
01630 docView->takeItem(it1.current());
01631
01632 QPtrListIterator<DocTreeKDELibsFolder> itk(folder_kdoc);
01633 for (; itk.current(); ++itk)
01634 docView->takeItem(itk.current());
01635
01636 QPtrListIterator<DocTreeDoxygenFolder> itx(folder_doxygen);
01637 for (; itx.current(); ++itx)
01638 docView->takeItem(itx.current());
01639
01640 QPtrListIterator<DocTreeQtFolder> itq(folder_qt);
01641 for (; itq.current(); ++itq)
01642 docView->takeItem(itq.current());
01643
01644
01645
01646
01647
01648 QStringList ignoretocs = DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoretocs", "toc");
01649
01650 QStringList ignoredh = DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoredevhelp", "toc");
01651 QStringList ignoredoxygen = DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoredoxygen", "toc");
01652 QStringList ignorekdocs = DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignorekdocs", "toc");
01653 QStringList ignoreqt_xml = DomUtil::readListEntry(*m_part->projectDom(), "/kdevdoctreeview/ignoreqt_xml", "toc");
01654
01655 docView->insertItem(folder_bookmarks);
01656 docView->insertItem(folder_project);
01657 #ifdef WITH_DOCBASE
01658 docView->insertItem(folder_docbase);
01659 #endif
01660 QPtrListIterator<DocTreeDevHelpFolder> itdh2(folder_devhelp);
01661 for (; itdh2.current(); ++itdh2)
01662 {
01663 if (!ignoredh.contains(itdh2.current()->tocName()))
01664 docView->insertItem(itdh2.current());
01665 }
01666
01667 QPtrListIterator<DocTreeTocFolder> it2(folder_toc);
01668
01669
01670 for (; it2.current(); ++it2)
01671 {
01672
01673 if (!ignoretocs.contains(it2.current()->tocName()))
01674 docView->insertItem(it2.current());
01675 }
01676
01677
01678 QPtrListIterator<DocTreeKDELibsFolder> itk2(folder_kdoc);
01679
01680
01681 for (; itk2.current(); ++itk2)
01682 {
01683 if (!ignorekdocs.contains(itk2.current()->text(0)))
01684 docView->insertItem(itk2.current());
01685 }
01686
01687 QPtrListIterator<DocTreeDoxygenFolder> itx2(folder_doxygen);
01688
01689
01690 for (; itx2.current(); ++itx2)
01691 {
01692 if (!ignoredoxygen.contains(itx2.current()->text(0)))
01693 docView->insertItem(itx2.current());
01694 }
01695
01696
01697
01698
01699
01700 QPtrListIterator<DocTreeQtFolder> itq2(folder_qt);
01701
01702
01703 for (; itq2.current(); ++itq2)
01704 {
01705 if (!ignoreqt_xml.contains(itq2.current()->text(0)))
01706 docView->insertItem(itq2.current());
01707 }
01708
01709
01710 docView->triggerUpdate();
01711 }
01712
01713
01714 QString DocTreeViewWidget::locatehtml(const QString &fileName)
01715 {
01716
01717 QString path = locate("html", KGlobal::locale()->language() + '/' + fileName);
01718 if (path.isNull())
01719 path = locate("html", "default/" + fileName);
01720
01721 return path;
01722 }
01723
01724
01725 void DocTreeViewWidget::slotAddBookmark()
01726 {
01727 DocTreeItem *item = dynamic_cast<DocTreeItem*>( contextItem );
01728 if( item )
01729 {
01730 DocTreeViewTool::addBookmark( item->text(0), item->fileName() );
01731 folder_bookmarks->refresh();
01732 }
01733 }
01734
01735 void DocTreeViewWidget::slotRemoveBookmark()
01736 {
01737 DocTreeItem *item = dynamic_cast<DocTreeItem*>( contextItem );
01738 if( item )
01739 {
01740 int posFolder = docView->itemIndex( folder_bookmarks );
01741 int i = docView->itemIndex( item ) - posFolder;
01742
01743
01744 DocTreeViewTool::removeBookmark( i );
01745
01746 folder_bookmarks->refresh();
01747 }
01748 }
01749
01750
01751
01752 void DocTreeViewWidget::slotFilterTextChanged(const QString &nt)
01753 {
01754 int res;
01755 QListViewItemIterator docViewIterator( indexView );
01756 QListViewItem *it = 0;
01757
01758 while( docViewIterator.current() )
01759 {
01760 res = docViewIterator.current()->text(0).find(nt, 0, false);
01761
01762 if( (res == -1) || (!subStringSearch && (res > 0)) ) docViewIterator.current()->setVisible(false);
01763 else
01764 {
01765 if (it == 0) it = docViewIterator.current();
01766 docViewIterator.current()->setVisible(true);
01767 }
01768
01769 ++docViewIterator;
01770 }
01771 if (it)
01772 indexView->setCurrentItem(it);
01773 }
01774
01775 void DocTreeViewWidget::slotFilterReturn()
01776 {
01777 indexView->setFocus();
01778
01779
01780
01781
01782
01783 }
01784
01785 void DocTreeViewWidget::slotIndexItemExecuted(QListViewItem *item)
01786 {
01787 IndexTreeData *itd;
01788 QPtrList<IndexTreeData> *resultList;
01789
01790 if (!item) return;
01791
01792 QString ident = item->text(0);
01793 if (ident.isEmpty()) return;
01794
01795 QPtrListIterator<IndexTreeData> ptrListIterator( indexItems );
01796 resultList = new QPtrList<IndexTreeData>();
01797
01798 while( ptrListIterator.current() )
01799 {
01800 itd = static_cast<IndexTreeData *>(ptrListIterator.current());
01801
01802 if((indexMode == filteredMode) && (itd->text() == ident)) resultList->append(itd);
01803 else if((indexMode == plainListMode) && ((itd->text() + " (" + itd->parent() + ")") == ident)) resultList->append(itd);
01804 ++ptrListIterator;
01805 }
01806
01807 if(resultList->count() == 0)
01808 {
01809 }
01810 else if(resultList->count() == 1)
01811 {
01812 m_part->partController()->showDocument(KURL::fromPathOrURL( resultList->first()->fileName() ));
01813 m_part->mainWindow()->lowerView(this);
01814 }
01815 else
01816 {
01817 ChooseDlg chooseDlg(this, "choose dlg", m_part);
01818 chooseDlg.setList(resultList);
01819 chooseDlg.exec();
01820 }
01821
01822 delete resultList;
01823 }
01824
01825 void DocTreeViewWidget::filterMultiReferences()
01826 {
01827 bool bFound;
01828 IndexTreeData *itd;
01829 IndexTreeData *itd2;
01830
01831 QPtrListIterator<IndexTreeData> ptrListIterator( indexItems );
01832 while( ptrListIterator.current() )
01833 {
01834 itd = static_cast<IndexTreeData *>(ptrListIterator.current());
01835 bFound = false;
01836
01837 QPtrListIterator<IndexTreeData> ptrListIterator2( indexItems );
01838 while( ptrListIterator2.current() )
01839 {
01840 itd2 = static_cast<IndexTreeData *>(ptrListIterator2.current());
01841
01842 if( itd2->isVisible() && (itd2->text() == itd->text()) )
01843 {
01844 bFound = true;
01845 break;
01846 }
01847 ++ptrListIterator2;
01848 }
01849
01850
01851 if(bFound == false) itd->setVisible(true);
01852
01853 qApp->processEvents();
01854 ++ptrListIterator;
01855 }
01856 }
01857
01858 void DocTreeViewWidget::slotCurrentTabChanged(int curtab)
01859 {
01860 IndexTreeData *iI;
01861
01862 if((curtab == 1) && (indexView->childCount() == 0))
01863 {
01864
01865 QProgressDialog progress(i18n("Generating Index..."), 0, 100, this, "progDialog", true);
01866
01867 indexItems.clear();
01868 progress.setProgress(0);
01869
01870
01871 QListViewItemIterator docViewIterator( docView );
01872 while( docViewIterator.current() )
01873 {
01874
01875 docViewIterator.current()->setOpen(true);
01876 docViewIterator.current()->setOpen(false);
01877
01878 DocTreeItem *dtitem = static_cast<DocTreeItem*>(docViewIterator.current());
01879
01880
01881 iI = new IndexTreeData(dtitem->text(0), (dtitem->parent() != 0) ? dtitem->parent()->text(0) : QString(" "), dtitem->fileName());
01882 indexItems.append(iI);
01883
01884 qApp->processEvents();
01885 ++docViewIterator;
01886 }
01887 progress.setProgress(30);
01888
01889
01890
01891 progress.setProgress(90);
01892
01893
01894 slotIndexModeCheckClicked();
01895
01896 progress.setProgress(100);
01897 }
01898 }
01899
01900 void DocTreeViewWidget::slotSubstringCheckClicked()
01901 {
01902 subStringSearch = !subStringSearch;
01903 slotFilterTextChanged(filterEdit->text());
01904 }
01905
01906 void DocTreeViewWidget::slotIndexModeCheckClicked()
01907 {
01908 QString s;
01909
01910 if(indexMode == filteredMode) indexMode = plainListMode;
01911 else indexMode = filteredMode;
01912
01913 indexView->clear();
01914
01915 QPtrListIterator<IndexTreeData> ptrListIterator( indexItems );
01916 while( ptrListIterator.current() )
01917 {
01918 IndexTreeData *itd = static_cast<IndexTreeData *>(ptrListIterator.current());
01919
01920 if(indexMode == plainListMode) s = itd->text() + " (" + itd->parent() + ")";
01921 else s = itd->text();
01922
01923 if((indexMode == plainListMode) || itd->isVisible()) new QListViewItem(indexView, s);
01924
01925 ++ptrListIterator;
01926 }
01927
01928 slotFilterTextChanged(filterEdit->text());
01929 }
01930
01931 void DocTreeViewWidget::slotIndexNextMatch( )
01932 {
01933 if (indexView->currentItem())
01934 {
01935 QListViewItem *below = indexView->currentItem()->itemBelow();
01936 if (below)
01937 {
01938 indexView->setCurrentItem(below);
01939 indexView->ensureItemVisible(below);
01940 }
01941 }
01942 }
01943
01944 void DocTreeViewWidget::slotIndexPrevMatch( )
01945 {
01946 if (indexView->currentItem())
01947 {
01948 QListViewItem *above = indexView->currentItem()->itemAbove();
01949 if (above)
01950 {
01951 indexView->setCurrentItem(above);
01952 indexView->ensureItemVisible(above);
01953 }
01954 }
01955 }
01956
01957 void DocTreeViewWidget::slotIndexPgUp( )
01958 {
01959 }
01960
01961 void DocTreeViewWidget::slotIndexPgDown( )
01962 {
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 }
01977
01978 void DocTreeViewWidget::slotIndexHome( )
01979 {
01980
01981
01982
01983
01984
01985
01986 }
01987
01988 void DocTreeViewWidget::slotIndexEnd( )
01989 {
01990
01991
01992
01993
01994
01995
01996 }
01997
01998 #include "doctreeviewwidget.moc"