diff options
Diffstat (limited to 'parts/documentation')
113 files changed, 13063 insertions, 0 deletions
diff --git a/parts/documentation/KDevDocumentationIface.cpp b/parts/documentation/KDevDocumentationIface.cpp new file mode 100644 index 00000000..baac8b52 --- /dev/null +++ b/parts/documentation/KDevDocumentationIface.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "KDevDocumentationIface.h" + +#include "documentation_part.h" + +KDevDocumentationIface::KDevDocumentationIface(DocumentationPart *part) + :QObject(part), DCOPObject("KDevDocumentation"), m_part(part) +{ +} + +KDevDocumentationIface::~KDevDocumentationIface() +{ +} + +void KDevDocumentationIface::lookupInIndex(QString term) +{ + m_part->lookInDocumentationIndex(term); +} + +void KDevDocumentationIface::findInFinder(QString term) +{ + m_part->findInDocumentation(term); +} + +void KDevDocumentationIface::searchInDocumentation(QString term) +{ + m_part->searchInDocumentation(term); +} + +void KDevDocumentationIface::lookupInIndex() +{ + m_part->lookInDocumentationIndex(); +} + +void KDevDocumentationIface::searchInDocumentation() +{ + m_part->searchInDocumentation(); +} + +void KDevDocumentationIface::manPage(QString term) +{ + m_part->manPage(term); +} + +void KDevDocumentationIface::infoPage(QString term) +{ + m_part->infoPage(term); +} + +void KDevDocumentationIface::manPage() +{ + m_part->manPage(); +} + +void KDevDocumentationIface::infoPage() +{ + m_part->infoPage(); +} + +void KDevDocumentationIface::findInFinder( ) +{ + m_part->findInDocumentation(); +} + +#include "KDevDocumentationIface.moc" diff --git a/parts/documentation/KDevDocumentationIface.h b/parts/documentation/KDevDocumentationIface.h new file mode 100644 index 00000000..e2fd402b --- /dev/null +++ b/parts/documentation/KDevDocumentationIface.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef KDEVDOCUMENTATIONIFACE_H +#define KDEVDOCUMENTATIONIFACE_H + +#include <qobject.h> +#include <dcopobject.h> + +class DocumentationPart; + +class KDevDocumentationIface : public QObject, public DCOPObject { + Q_OBJECT + K_DCOP +public: + KDevDocumentationIface(DocumentationPart *part); + ~KDevDocumentationIface(); + +k_dcop: + void lookupInIndex(QString term); + void findInFinder(QString term); + void searchInDocumentation(QString term); + void manPage(QString term); + void infoPage(QString term); + + void lookupInIndex(); + void findInFinder(); + void searchInDocumentation(); + void manPage(); + void infoPage(); + +private: + DocumentationPart *m_part; +}; + +#endif diff --git a/parts/documentation/Makefile.am b/parts/documentation/Makefile.am new file mode 100644 index 00000000..b8f4505d --- /dev/null +++ b/parts/documentation/Makefile.am @@ -0,0 +1,32 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) + +kde_module_LTLIBRARIES = libkdevdocumentation.la +libkdevdocumentation_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevdocumentation_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la $(LIB_KHTML) + +libkdevdocumentation_la_SOURCES = documentation_part.cpp \ + documentation_widget.cpp contentsview.cpp indexview.cpp docglobalconfigwidgetbase.ui \ + docglobalconfigwidget.cpp docconfiglistview.cpp editcatalogdlgbase.ui editcatalogdlg.cpp \ + docutils.cpp searchview.cpp bookmarkview.cpp editbookmarkdlg.ui \ + find_documentationbase.ui find_documentation.cpp find_documentation_optionsbase.ui \ + find_documentation_options.cpp selecttopicbase.ui selecttopic.cpp docprojectconfigwidgetbase.ui \ + docprojectconfigwidget.cpp KDevDocumentationIface.cpp KDevDocumentationIface.skel \ + addcatalogdlgbase.ui addcatalogdlg.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevdocumentation.desktop + +rcdir = $(kde_datadir)/kdevdocumentation +rc_DATA = kdevpart_documentation.rc + +noinst_HEADERS = contentsview.h indexview.h docglobalconfigwidget.h \ + docconfiglistview.h editcatalogdlg.h docutils.h searchview.h bookmarkview.h selecttopic.h \ + docprojectconfigwidget.h KDevDocumentationIface.h addcatalogdlg.h +SUBDIRS = interfaces plugins tools data protocols + +DOXYGEN_EMPTY = YES +include ../../Doxyfile.am diff --git a/parts/documentation/README.dox b/parts/documentation/README.dox new file mode 100644 index 00000000..63658d49 --- /dev/null +++ b/parts/documentation/README.dox @@ -0,0 +1,21 @@ +/** \class Documentation +Documentation plugin for KDevelop. + +\authors <a href="mailto:cloudtemple@mksat.net">Alexander Dymo</a> + +\maintainer <a href="mailto:cloudtemple@mksat.net">Alexander Dymo</a> + +\feature Qt API browsing +\feature KDE API browsing +\feature Devhelp books browsing (GTK/GNOME API) +\feature KDevelopTOC browsing + +\bug bugs in <a href="http://bugs.kde.org/buglist.cgi?product=kdevelop&component=documentation& +bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=Bug+Number"> +Documentation viewer at Bugzilla database</a> + +\requirement Ht://Dig requires htdig to be installed. + +\todo Add support for documentation profiles. Application wizard or an application template +can select necessary profile to modify the list of enabled documentation catalogs. +*/ diff --git a/parts/documentation/addcatalogdlg.cpp b/parts/documentation/addcatalogdlg.cpp new file mode 100644 index 00000000..9c46d2d1 --- /dev/null +++ b/parts/documentation/addcatalogdlg.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2005 by Jens Dagerbo * + * jens.dagerbo@swipnet.se * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "addcatalogdlg.h" + +#include <qlabel.h> +#include <qcombobox.h> + +#include <klineedit.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <kdebug.h> + +#include "docutils.h" +#include "kdevdocumentationplugin.h" + +AddCatalogDlg::AddCatalogDlg( QValueList<DocumentationPlugin*> const & plugins, + QWidget* parent, const char* name, bool modal, WFlags fl) + :AddCatalogDlgBase(parent,name, modal,fl), m_plugins( plugins ) +{ + for (QValueList<DocumentationPlugin*>::const_iterator it = m_plugins.constBegin(); it != m_plugins.constEnd(); ++it) + { + docTypeCombo->insertItem( (*it)->pluginName() ); + } + + docTypeChanged( QString() ); +} + +AddCatalogDlg::~AddCatalogDlg() +{ +} + +void AddCatalogDlg::locationURLChanged(const QString &text) +{ + DocumentationPlugin * plugin = this->plugin(); + if ( !plugin ) return; + + titleEdit->setText( plugin->catalogTitle(DocUtils::noEnvURL(text)) ); +} + +void AddCatalogDlg::accept() +{ + QDialog::accept(); +} + +QString AddCatalogDlg::title() const +{ + return titleEdit->text(); +} + +QString AddCatalogDlg::url() const +{ + return DocUtils::envURL(locationURL); +} + +void AddCatalogDlg::setTitle(const QString &title) +{ + titleEdit->setText(title); +} + +void AddCatalogDlg::setURL(const QString &url) +{ + locationURL->setURL(url); +} + +DocumentationPlugin * AddCatalogDlg::plugin( ) +{ + for (QValueList<DocumentationPlugin*>::const_iterator it = m_plugins.constBegin(); it != m_plugins.constEnd(); ++it) + { + if ( docTypeCombo->currentText() == (*it)->pluginName() ) + { + return *it; + } + } + return 0; +} + +void AddCatalogDlg::docTypeChanged( const QString & ) +{ + kdDebug() << k_funcinfo << endl; + + DocumentationPlugin * plugin = this->plugin(); + if ( plugin ) + { + titleLabel->setEnabled( plugin->hasCapability(DocumentationPlugin::CustomDocumentationTitles) ); + titleEdit->setEnabled( plugin->hasCapability(DocumentationPlugin::CustomDocumentationTitles) ); + locationURL->setMode( plugin->catalogLocatorProps().first ); + locationURL->setFilter( plugin->catalogLocatorProps().second ); + } + +} + + + +#include "addcatalogdlg.moc" diff --git a/parts/documentation/addcatalogdlg.h b/parts/documentation/addcatalogdlg.h new file mode 100644 index 00000000..a04d5edc --- /dev/null +++ b/parts/documentation/addcatalogdlg.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2005 by Jens Dagerbo * + * jens.dagerbo@swipnet.se * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef ADDCATALOGDLG_H +#define ADDCATALOGDLG_H + +#include <qvaluelist.h> +#include "addcatalogdlgbase.h" + +class DocumentationPlugin; + +class AddCatalogDlg: public AddCatalogDlgBase +{ + Q_OBJECT + public: + AddCatalogDlg( QValueList<DocumentationPlugin*> const & plugins, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0); + ~AddCatalogDlg(); + + QString title() const; + void setTitle(const QString &title); + QString url() const; + void setURL(const QString &url); + DocumentationPlugin * plugin(); + + public slots: + virtual void locationURLChanged(const QString &text); + virtual void docTypeChanged( const QString & ); + + protected slots: + virtual void accept(); + + private: + QValueList<DocumentationPlugin*> const & m_plugins; +}; + +#endif diff --git a/parts/documentation/addcatalogdlgbase.ui b/parts/documentation/addcatalogdlgbase.ui new file mode 100644 index 00000000..5274d12b --- /dev/null +++ b/parts/documentation/addcatalogdlgbase.ui @@ -0,0 +1,209 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>AddCatalogDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>AddCatalogDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>398</width> + <height>222</height> + </rect> + </property> + <property name="caption"> + <string>Documentation Catalog Properties</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout20</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="3" column="0"> + <property name="name"> + <cstring>titleEdit</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Type:</string> + </property> + </widget> + <spacer row="6" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>18</height> + </size> + </property> + </spacer> + <widget class="KURLRequester" row="1" column="0"> + <property name="name"> + <cstring>locationURL</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Locatio&n:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>locationURL</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>titleLabel</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Title:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>titleEdit</cstring> + </property> + </widget> + <widget class="QComboBox" row="5" column="0"> + <property name="name"> + <cstring>docTypeCombo</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>AddCatalogDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>AddCatalogDlgBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>locationURL</sender> + <signal>textChanged(const QString&)</signal> + <receiver>AddCatalogDlgBase</receiver> + <slot>locationURLChanged(const QString&)</slot> + </connection> + <connection> + <sender>docTypeCombo</sender> + <signal>activated(const QString&)</signal> + <receiver>AddCatalogDlgBase</receiver> + <slot>docTypeChanged(const QString&)</slot> + </connection> + <connection> + <sender>locationURL</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>AddCatalogDlgBase</receiver> + <slot>locationURLChanged(const QString&)</slot> + </connection> +</connections> +<slots> + <slot>locationURLChanged( const QString & )</slot> + <slot>docTypeChanged( const QString & )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/parts/documentation/bookmarkview.cpp b/parts/documentation/bookmarkview.cpp new file mode 100644 index 00000000..33f67da4 --- /dev/null +++ b/parts/documentation/bookmarkview.cpp @@ -0,0 +1,285 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "bookmarkview.h" + +#include <qlayout.h> +#include <qheader.h> +#include <qpoint.h> + +#include <klineedit.h> +#include <kstandarddirs.h> +#include <klocale.h> +#include <kdialog.h> +#include <kpushbutton.h> +#include <kurlrequester.h> +#include <kpopupmenu.h> +#include <kparts/part.h> +#include <khtml_part.h> +#include <dom/html_document.h> + +#include <kdevpartcontroller.h> +#include <kdevdocumentationplugin.h> + +#include "documentation_part.h" +#include "documentation_widget.h" +#include "editbookmarkdlg.h" +#include "docutils.h" + +DocBookmarkManager::DocBookmarkManager(DocumentationPart */*part*/) + :KBookmarkManager(locateLocal("data", + "kdevdocumentation/bookmarks/bookmarks.xml"), false) +{ + setEditorOptions(i18n("Documentation"), false); +} + +DocBookmarkOwner::DocBookmarkOwner(DocumentationPart *part) + :KBookmarkOwner(), m_part(part) +{ +} + +void DocBookmarkOwner::openBookmarkURL(const QString &_url) +{ + m_part->partController()->showDocument(KURL(_url)); +} + +QString DocBookmarkOwner::currentURL() const +{ + KParts::ReadOnlyPart *activePart = dynamic_cast<KParts::ReadOnlyPart*>(m_part->partController()->activePart()); + if (activePart) + return activePart->url().url(); + else + return QString::null; +} + +QString DocBookmarkOwner::currentTitle() const +{ + KParts::ReadOnlyPart *activePart = dynamic_cast<KParts::ReadOnlyPart*>(m_part->partController()->activePart()); + if (activePart) + { + KHTMLPart *htmlPart = dynamic_cast<KHTMLPart*>(activePart); + if (htmlPart) + return htmlPart->htmlDocument().title().string(); + return activePart->url().prettyURL(); + } + else + return QString::null; +} + +class DocBookmarkItem: public DocumentationItem { +public: + DocBookmarkItem(Type type, KListView *parent, const QString &name) + :DocumentationItem(type, parent, name) + { + } + DocBookmarkItem(Type type, KListView *parent, DocumentationItem *after, const QString &name) + :DocumentationItem(type, parent, after, name) + { + } + DocBookmarkItem(Type type, DocumentationItem *parent, const QString &name) + :DocumentationItem(type, parent, name) + { + } + void setBookmark(const KBookmark &bm) { m_bm = bm; } + KBookmark bookmark() const { return m_bm; } + +private: + KBookmark m_bm; +}; + + + +//class BookmarkView + +BookmarkView::BookmarkView(DocumentationWidget *parent, const char *name) + :QWidget(parent, name), m_widget(parent) +{ + m_bmManager = new DocBookmarkManager(m_widget->part()); + m_bmOwner = new DocBookmarkOwner(m_widget->part()); + + QVBoxLayout *l = new QVBoxLayout(this, 0, KDialog::spacingHint()); + m_view = new KListView(this); + m_view->addColumn(i18n("Title")); + m_view->setSorting(-1); + m_view->header()->hide(); + m_view->setResizeMode(QListView::AllColumns); + m_view->setAllColumnsShowFocus( true ); + l->addWidget(m_view); + QHBoxLayout *l2 = new QHBoxLayout(l, KDialog::spacingHint()); + m_addButton = new KPushButton(i18n("Add"), this); + m_editButton = new KPushButton(i18n("Edit..."), this); + m_removeButton = new KPushButton(i18n("Remove"), this); + l2->addWidget(m_addButton); + l2->addWidget(m_editButton); + l2->addWidget(m_removeButton); + l2->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed)); + l->addSpacing(2); + + showBookmarks(); + + connect(m_view, SIGNAL(executed(QListViewItem*, const QPoint&, int )), + this, SLOT(itemExecuted(QListViewItem*, const QPoint&, int ))); + connect(m_addButton, SIGNAL(pressed()), this, SLOT(addBookmark())); + connect(m_editButton, SIGNAL(clicked()), this, SLOT(editBookmark())); + connect(m_removeButton, SIGNAL(clicked()), this, SLOT(removeBookmark())); + + connect(m_widget->part(), SIGNAL(bookmarkLocation(const QString&, const KURL& )), + this, SLOT(addBookmark(const QString&, const KURL& ))); + connect(m_view, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int )), + this, SLOT(itemMouseButtonPressed(int, QListViewItem*, const QPoint&, int ))); +} + +BookmarkView::~BookmarkView() +{ + delete m_bmManager; + delete m_bmOwner; +} + +void BookmarkView::showBookmarks() +{ + const KBookmarkGroup &group = m_bmManager->root(); + DocBookmarkItem *item = 0; + for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) + { + if (item == 0) + item = new DocBookmarkItem(DocumentationItem::Document, m_view, bm.fullText()); + else + item = new DocBookmarkItem(DocumentationItem::Document, m_view, item, bm.fullText()); + item->setURL(bm.url()); + item->setBookmark(bm); + } +} + +void BookmarkView::itemExecuted(QListViewItem *item, const QPoint &// p + , int // col + ) +{ + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(item); + if (!docItem) + return; + m_widget->part()->partController()->showDocument(docItem->url()); +} + +void BookmarkView::removeBookmark() +{ + if (!m_view->currentItem()) + return; + DocBookmarkItem *item = dynamic_cast<DocBookmarkItem*>(m_view->currentItem()); + m_bmManager->root().deleteBookmark(item->bookmark()); + m_bmManager->save(); + delete item; +} + +void BookmarkView::editBookmark() +{ + if (!m_view->currentItem()) + return; + DocBookmarkItem *item = dynamic_cast<DocBookmarkItem*>(m_view->currentItem()); + if (!item) + return; + + EditBookmarkDlg dlg(this); + dlg.setCaption(i18n("Edit Bookmark")); + dlg.nameEdit->setText(item->bookmark().fullText()); + dlg.locationEdit->setURL(item->bookmark().url().url()); + dlg.nameEdit->setFocus(); + if (dlg.exec()) + { + item->bookmark().internalElement().namedItem("title").firstChild().toText().setData(dlg.nameEdit->text()); + item->bookmark().internalElement().setAttribute("href", KURL(dlg.locationEdit->url()).url()); + m_bmManager->save(); + + item->setText(0, item->bookmark().fullText()); + item->setURL(item->bookmark().url()); + } +} + +void BookmarkView::addBookmark() +{ + QString title = m_bmOwner->currentTitle(); + QString url = m_bmOwner->currentURL(); + + KPopupMenu menu; + bool useMenu = false; + if (!title.isEmpty() && !url.isEmpty()) + { + menu.insertItem(i18n("Current Document"), 1); + menu.insertItem(i18n("Custom..."), 2); + useMenu = true; + } + int mode = 2; + if (useMenu) + { + m_addButton->setDown(true); + mode = menu.exec(mapToGlobal(QPoint(m_addButton->x(), m_addButton->y()+m_addButton->height()))); + m_addButton->setDown(false); + } + + switch (mode) + { + case 1: + addBookmark(title, url); + break; + case 2: + EditBookmarkDlg dlg(this); + dlg.setCaption(i18n("Add Bookmark")); +/* dlg.nameEdit->setText(title); + dlg.locationEdit->setURL(url);*/ + dlg.nameEdit->setFocus(); + if (dlg.exec()) + addBookmark(dlg.nameEdit->text(), KURL(dlg.locationEdit->url())); + m_addButton->setDown(false); + break; + } +} + +void BookmarkView::addBookmark(const QString &title, const KURL &url) +{ + KBookmark bm = m_bmManager->root().addBookmark(m_bmManager, title, url); + m_bmManager->save(); + + DocBookmarkItem *item = 0; + if (m_view->lastItem()) + item = dynamic_cast<DocBookmarkItem*>(m_view->lastItem()); + if (item == 0) + item = new DocBookmarkItem(DocumentationItem::Document, m_view, bm.fullText()); + else + item = new DocBookmarkItem(DocumentationItem::Document, m_view, item, bm.fullText()); + item->setURL(bm.url()); + item->setBookmark(bm); +} + +void BookmarkView::itemMouseButtonPressed(int button, QListViewItem *item, const QPoint &pos, int // c + ) +{ + if ((button != Qt::RightButton) || (!item)) + return; + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(item); + if (!docItem) + return; + + DocUtils::docItemPopup(m_widget->part(), docItem, pos, false, true); +} + +void BookmarkView::focusInEvent(QFocusEvent */*e*/) +{ + m_view->setFocus(); +} + +#include "bookmarkview.moc" diff --git a/parts/documentation/bookmarkview.h b/parts/documentation/bookmarkview.h new file mode 100644 index 00000000..a46aa573 --- /dev/null +++ b/parts/documentation/bookmarkview.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef BOOKMARKVIEW_H +#define BOOKMARKVIEW_H + +#include <qwidget.h> + +#include <kbookmarkmanager.h> + +class KListView; +class KPushButton; +class DocumentationPart; +class DocumentationWidget; +class QListViewItem; + +class DocBookmarkManager: public KBookmarkManager { +public: + DocBookmarkManager(DocumentationPart *part); +}; + +class DocBookmarkOwner: public KBookmarkOwner { +public: + DocBookmarkOwner(DocumentationPart *part); + + virtual void openBookmarkURL(const QString &_url); + virtual QString currentTitle() const; + virtual QString currentURL() const; + +private: + DocumentationPart *m_part; +}; + +class BookmarkView : public QWidget +{ + Q_OBJECT +public: + BookmarkView(DocumentationWidget *parent = 0, const char *name = 0); + ~BookmarkView(); + +public slots: + void addBookmark(const QString &title, const KURL &url); + +protected: + void showBookmarks(); + virtual void focusInEvent(QFocusEvent *e); + +protected slots: + void itemExecuted(QListViewItem *item, const QPoint &p, int col); + void addBookmark(); + void editBookmark(); + void removeBookmark(); + void itemMouseButtonPressed(int button, QListViewItem *item, const QPoint &pos, int c); + +private: + DocumentationWidget *m_widget; + KListView *m_view; + KPushButton *m_addButton; + KPushButton *m_editButton; + KPushButton *m_removeButton; + + DocBookmarkManager *m_bmManager; + DocBookmarkOwner *m_bmOwner; +}; + +#endif diff --git a/parts/documentation/contentsview.cpp b/parts/documentation/contentsview.cpp new file mode 100644 index 00000000..e69b048e --- /dev/null +++ b/parts/documentation/contentsview.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "contentsview.h" + +#include <qheader.h> +#include <qlayout.h> + +#include <kdebug.h> +#include <klistview.h> +#include <klocale.h> + +#include <kdevpartcontroller.h> +#include <kdevdocumentationplugin.h> + +#include "documentation_widget.h" +#include "documentation_part.h" +#include "docutils.h" + +ContentsView::ContentsView(DocumentationWidget *parent, const char *name) + :QWidget(parent, name), m_widget(parent) +{ + QVBoxLayout *cl = new QVBoxLayout(this, 0, 0); + m_view = new KListView(this); + cl->addWidget(m_view); + + m_view->addColumn(i18n( "Contents" )); + m_view->header()->hide(); + m_view->setResizeMode(QListView::AllColumns); + m_view->setRootIsDecorated(true); + m_view->setSorting(-1); + m_view->setAllColumnsShowFocus( true ); + + connect(m_view, SIGNAL(executed(QListViewItem*, const QPoint&, int )), + this, SLOT(itemExecuted(QListViewItem*, const QPoint&, int ))); + connect(m_view, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int )), + this, SLOT(itemMouseButtonPressed(int, QListViewItem*, const QPoint&, int ))); +} + +ContentsView::~ContentsView() +{ + if (m_widget && m_widget->index()) + m_widget->index()->clear(); +} + +void ContentsView::itemExecuted(QListViewItem *item, const QPoint &// p + , int // col + ) +{ + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(item); + if (!docItem) + return; + KURL url = DocUtils::noEnvURL(docItem->url()); + if (url.isEmpty() || !url.isValid()) + return; + m_widget->part()->partController()->showDocument(url); +} + +void ContentsView::itemMouseButtonPressed(int button, QListViewItem *item, const QPoint &pos, int // c + ) +{ + if ((button != Qt::RightButton) || (!item)) + return; + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(item); + if (!docItem) + return; + + DocUtils::docItemPopup(m_widget->part(), docItem, pos, true, true); +} + +void ContentsView::focusInEvent(QFocusEvent */*e*/) +{ + m_view->setFocus(); +} + +#include "contentsview.moc" diff --git a/parts/documentation/contentsview.h b/parts/documentation/contentsview.h new file mode 100644 index 00000000..aaac6eee --- /dev/null +++ b/parts/documentation/contentsview.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef CONTENTSVIEW_H +#define CONTENTSVIEW_H + +#include <qwidget.h> + +class FindDocumentation; +class DocumentationWidget; +class QListViewItem; +class KListView; + +class ContentsView : public QWidget +{ + Q_OBJECT +public: + ContentsView(DocumentationWidget *parent, const char *name = 0); + ~ContentsView(); + + KListView *view() const { return m_view; } + +protected slots: + void itemExecuted(QListViewItem *item, const QPoint &p, int col); + void itemMouseButtonPressed(int button, QListViewItem *item, const QPoint &pos, int c); + +protected: + virtual void focusInEvent(QFocusEvent *e); + +private: + DocumentationWidget *m_widget; + KListView *m_view; + +friend class FindDocumentation; +}; + +#endif diff --git a/parts/documentation/data/Makefile.am b/parts/documentation/data/Makefile.am new file mode 100644 index 00000000..920c492a --- /dev/null +++ b/parts/documentation/data/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util $(all_includes) +METASOURCES = AUTO +htmldir = $(kde_datadir)/kdevdocumentation/en +picsdir = $(kde_datadir)/kdevdocumentation/pics +html_DATA = long.html nomatch.html short.html syntax.html wrapper.html +pics_DATA = checked.xpm htdig.png star.png star_blank.png unchecked.xpm diff --git a/parts/documentation/data/checked.xpm b/parts/documentation/data/checked.xpm new file mode 100644 index 00000000..1ed19024 --- /dev/null +++ b/parts/documentation/data/checked.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char*unchecked[]={ +"16 16 4 1", +"# c #000000", +"+ c #ffffff", +"D c #000000", +". c None", +"................", +"............++++", +"..++++++++++DDD+", +"..+########DDD+.", +"..+#++++++DDD+..", +"+DDD+...+DDD#+..", +"++DDD+++DDD+#+..", +"..+DDDDDDD++#+..", +"..+#DDDDD+.+#+..", +"..+#++DD+..+#+..", +"..+#+++++..+#+..", +"..+#++++++++#+..", +"..+##########+..", +"..++++++++++++..", +"................", +"................"}; diff --git a/parts/documentation/data/htdig.png b/parts/documentation/data/htdig.png Binary files differnew file mode 100644 index 00000000..fe6e7c92 --- /dev/null +++ b/parts/documentation/data/htdig.png diff --git a/parts/documentation/data/long.html b/parts/documentation/data/long.html new file mode 100644 index 00000000..1d0fa4ce --- /dev/null +++ b/parts/documentation/data/long.html @@ -0,0 +1,6 @@ +<dl><dt><strong><a href="$&(URL)">$&(TITLE)</a></strong>$(STARSLEFT) +</dt><dd>$(EXCERPT)<br> +<i><a href="$&(URL)">$&(URL)</a></i> +<font size="-1">$(MODIFIED), $(SIZE) bytes</font> +</dd></dl> + diff --git a/parts/documentation/data/nomatch.html b/parts/documentation/data/nomatch.html new file mode 100644 index 00000000..8951a604 --- /dev/null +++ b/parts/documentation/data/nomatch.html @@ -0,0 +1,21 @@ +<html><head><title>No match for '$&(LOGICAL_WORDS)'</title></head> +<body bgcolor="#ffffff" text="#000000" link="#aa0000"> +<h1><img src="$(PICDIR)kdevdocumentation/pics/htdig.png"> +Search results</h1> +<hr noshade size="4"> +<h2>No matches were found for '$&(LOGICAL_WORDS)'</h2> +<p> +Check the spelling of the search word(s) you used. +If the spelling is correct and you only used one word, +try using one or more similar search words with "<b>Any</b>." +</p><p> +If the spelling is correct and you used more than one +word with "<b>Any</b>," try using one or more similar search +words with "<b>Any</b>."</p><p> +If the spelling is correct and you used more than one +word with "<b>All</b>," try using one or more of the same words +with "<b>Any</b>."</p> +<hr noshade size="4"> +<a href="http://www.htdig.org/"> +<img src="$(PICDIR)kdevdocumentation/pics/htdig.png" border="0">ht://Dig $(VERSION)</a> +</body></html> diff --git a/parts/documentation/data/short.html b/parts/documentation/data/short.html new file mode 100644 index 00000000..e3e5e447 --- /dev/null +++ b/parts/documentation/data/short.html @@ -0,0 +1 @@ +$(STARSRIGHT) <strong><a href="$&(URL)">$&(TITLE)</a></strong><br> diff --git a/parts/documentation/data/star.png b/parts/documentation/data/star.png Binary files differnew file mode 100644 index 00000000..692cd35e --- /dev/null +++ b/parts/documentation/data/star.png diff --git a/parts/documentation/data/star_blank.png b/parts/documentation/data/star_blank.png Binary files differnew file mode 100644 index 00000000..2689281a --- /dev/null +++ b/parts/documentation/data/star_blank.png diff --git a/parts/documentation/data/syntax.html b/parts/documentation/data/syntax.html new file mode 100644 index 00000000..9701c37f --- /dev/null +++ b/parts/documentation/data/syntax.html @@ -0,0 +1,19 @@ +<html><head><title>Error in Boolean search for '$&(WORDS)'</title></head> +<body bgcolor="#ffffff" text="#000000" link="#aa0000"> +<h1><img src="$(PICDIR)kdevdocumentation/pics/htdig.png"> +Error in Boolean search for '$&(LOGICAL_WORDS)'</h1> +<hr noshade size="4"> +Boolean expressions need to be 'correct' in order for the search +system to use them. +The expression you entered has errors in it.<p> +Examples of correct expressions are: <b>cat and dog</b>, <b>cat +not dog</b>, <b>cat or (dog not nose)</b>.<br>Note that +the operator <b>not</b> has the meaning of 'without'. +<blockquote><b> +$(SYNTAXERROR) +</b></blockquote> +<hr noshade size="4"> +<a href="http://www.htdig.org/"> +<img src="$(PICDIR)kdevdocumentation/pics/htdig.png" border="0">ht://Dig $(VERSION)</a> +</body></html> + diff --git a/parts/documentation/data/unchecked.xpm b/parts/documentation/data/unchecked.xpm new file mode 100644 index 00000000..e447281a --- /dev/null +++ b/parts/documentation/data/unchecked.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char*unchecked[]={ +"16 16 3 1", +"# c #000000", +"+ c #ffffff", +". c None", +"................", +"................", +"..++++++++++++..", +"..+##########+..", +"..+#++++++++#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#+......+#+..", +"..+#++++++++#+..", +"..+##########+..", +"..++++++++++++..", +"................", +"................"}; diff --git a/parts/documentation/data/wrapper.html b/parts/documentation/data/wrapper.html new file mode 100644 index 00000000..20c1bbf2 --- /dev/null +++ b/parts/documentation/data/wrapper.html @@ -0,0 +1,16 @@ +<html><head><title>Search results for '$&(WORDS)'</title></head> +<body bgcolor="#ffffff" text="#000000" link="#aa0000"> +<h2><img src=$(PICDIR)kdevdocumentation/pics/htdig.png> +Search results for '$&(LOGICAL_WORDS)'</h2> +<hr noshade size="4"> +<b> +More <img src=$(PICDIR)kdevdocumentation/pics/star.png alt="*">'s indicate a better match. +</b> +<hr noshade size="1"> +$(HTSEARCH_RESULTS) +$(PAGEHEADER) +$(PREVPAGE) $(PAGELIST) $(NEXTPAGE) +<hr noshade size="4"> +<a href="http://www.htdig.org/"> +<img src=$(PICDIR)kdevdocumentation/pics/htdig.png border="0">ht://Dig $(VERSION)</a> +</body></html> diff --git a/parts/documentation/docconfiglistview.cpp b/parts/documentation/docconfiglistview.cpp new file mode 100644 index 00000000..0865f105 --- /dev/null +++ b/parts/documentation/docconfiglistview.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docconfiglistview.h" + +#include <klocale.h> + +#include "kdevdocumentationplugin.h" + +DocConfigListView::DocConfigListView(QWidget *parent, const char *name) + :KListView(parent, name) +{ +// setSorting(-1); + addColumn(i18n("TOC")); + addColumn(i18n("Index")); + addColumn(i18n("Search")); + addColumn(i18n("Title")); +// addColumn(i18n("URL")); + setColumnWidthMode(0, QListView::Maximum); + setColumnWidthMode(1, QListView::Maximum); + setColumnWidthMode(2, QListView::Maximum); + setColumnWidthMode(3, QListView::Maximum); +// setColumnWidthMode(4, QListView::Maximum); + setAllColumnsShowFocus(true); + setResizeMode( QListView::LastColumn ); + + connect(this, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), + this, SLOT(clickedItem(QListViewItem*, const QPoint&, int ))); +} + +DocConfigListView::~DocConfigListView() +{ +} + +void DocConfigListView::clickedItem(QListViewItem *item, const QPoint &// pnt + , int c) +{ + if (!item) + return; + ConfigurationItem *cfg = dynamic_cast<ConfigurationItem*>(item); + if (!cfg) + return; + if (c == 0) + { + cfg->setContents(!cfg->contents()); + if (!cfg->contents()) + cfg->setIndex(false); + } + if ((c == 1) && (cfg->indexPossible())) + cfg->setIndex(!cfg->index()); + else if ((c == 2) && (cfg->fullTextSearchPossible())) + cfg->setFullTextSearch(!cfg->fullTextSearch()); + repaintItem(item); +} + +#include "docconfiglistview.moc" diff --git a/parts/documentation/docconfiglistview.h b/parts/documentation/docconfiglistview.h new file mode 100644 index 00000000..089980cf --- /dev/null +++ b/parts/documentation/docconfiglistview.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCCONFIGLISTVIEW_H +#define DOCCONFIGLISTVIEW_H + +#include <klistview.h> + +class DocConfigListView : public KListView +{ + Q_OBJECT +public: + DocConfigListView(QWidget *parent = 0, const char *name = 0); + ~DocConfigListView(); + +protected slots: + void clickedItem(QListViewItem *item, const QPoint &pnt, int c); +}; + +#endif diff --git a/parts/documentation/docglobalconfigwidget.cpp b/parts/documentation/docglobalconfigwidget.cpp new file mode 100644 index 00000000..cef510dc --- /dev/null +++ b/parts/documentation/docglobalconfigwidget.cpp @@ -0,0 +1,259 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2002 by Sebastian Kratzert * + * skratzert@gmx.de * + * Copyright (C) 2003-2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docglobalconfigwidget.h" + +#include <qlayout.h> +#include <qtoolbox.h> +#include <qcheckbox.h> +#include <qwidgetstack.h> + +#include <kdebug.h> +#include <kconfig.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kapplication.h> +#include <kurlrequester.h> +#include <kfontcombo.h> +#include <khtml_part.h> +#include <khtml_settings.h> + +#include "kdevdocumentationplugin.h" +#include "kdevpartcontroller.h" + +#include "docconfiglistview.h" +#include "documentation_part.h" +#include "documentation_widget.h" +#include "editcatalogdlg.h" +#include "addcatalogdlg.h" +#include "contentsview.h" +#include "indexview.h" +#include "docutils.h" + +DocGlobalConfigWidget::DocGlobalConfigWidget(DocumentationPart *part, + DocumentationWidget *widget, QWidget *parent, const char *name, WFlags fl) + :DocGlobalConfigWidgetBase(parent, name, fl), m_part(part), m_widget(widget) +{ + m_View = new DocConfigListView( viewHolder ); + viewHolder->addWidget( m_View ); + viewHolder->raiseWidget( m_View ); + for (QValueList<DocumentationPlugin*>::const_iterator it = m_part->m_plugins.constBegin(); + it != m_part->m_plugins.constEnd(); ++it) + { + (*it)->loadCatalogConfiguration( m_View ); + } + + KConfig *config = m_part->config(); + //read full text search settings + config->setGroup("htdig"); + QString databaseDir = kapp->dirs()->saveLocation("data", + "kdevdocumentation/search"); + databaseDirEdit->setURL(config->readPathEntry("databaseDir", databaseDir)); + htdigbinEdit->setURL(config->readPathEntry("htdigbin", kapp->dirs()->findExe("htdig"))); + htmergebinEdit->setURL(config->readPathEntry("htmergebin", kapp->dirs()->findExe("htmerge"))); + htsearchbinEdit->setURL(config->readPathEntry("htsearchbin", kapp->dirs()->findExe("htsearch"))); + if (config->readBoolEntry("IsSetup", false) == false) + { + QFileInfo fi(htsearchbinEdit->url()); + if (!fi.exists()) + { + //try to guess htsearch location on Debian + QFileInfo fi("/usr/lib/cgi-bin/htsearch"); + if (!fi.exists()) + { + //try to guess htsearch location on SuSE + QFileInfo fi("/srv/www/cgi-bin/htsearch"); + if (fi.exists()) + htsearchbinEdit->setURL("/srv/www/cgi-bin/htsearch"); + } + else + htsearchbinEdit->setURL("/usr/lib/cgi-bin/htsearch"); + } + } + + find_box->setChecked(m_part->hasContextFeature(DocumentationPart::Finder)); + index_box->setChecked(m_part->hasContextFeature(DocumentationPart::IndexLookup)); + search_box->setChecked(m_part->hasContextFeature(DocumentationPart::FullTextSearch)); + man_box->setChecked(m_part->hasContextFeature(DocumentationPart::GotoMan)); + info_box->setChecked(m_part->hasContextFeature(DocumentationPart::GotoInfo)); + + useAssistant_box->setChecked(m_part->isAssistantUsed()); + + // Having app-specific settings isn't pretty, but this setting is nonsensical in kdevassistant + if ( kapp->instanceName().find("kdevassistant") != -1 ) + useAssistant_box->hide(); + + //font sizes and zoom levels + KHTMLPart htmlpart; + KConfig *appConfig = KGlobal::config(); + appConfig->setGroup("KHTMLPart"); + standardFont_combo->setCurrentText(appConfig->readEntry("StandardFont", + htmlpart.settings()->stdFontName())); + fixedFont_combo->setCurrentText(appConfig->readEntry("FixedFont", + htmlpart.settings()->fixedFontName())); + zoom_combo->setCurrentText(appConfig->readEntry("Zoom", "100")); +} + +DocGlobalConfigWidget::~DocGlobalConfigWidget() +{ +} + +/*$SPECIALIZATION$*/ +void DocGlobalConfigWidget::collectionsBoxCurrentChanged(int // box + ) +{ +} + +void DocGlobalConfigWidget::removeCollectionButtonClicked() +{ + ConfigurationItem *item = dynamic_cast<ConfigurationItem*>(activeView()->currentItem()); + if (!item) + return; + item->docPlugin()->deleteCatalogConfiguration(item); + delete activeView()->currentItem(); +} + +void DocGlobalConfigWidget::editCollectionButtonClicked() +{ + ConfigurationItem *item = dynamic_cast<ConfigurationItem*>(activeView()->currentItem()); + if (!item) + return; + EditCatalogDlg dlg( item->docPlugin(), this, "edit collection dlg", true); + dlg.setURL(item->url()); + dlg.setTitle(item->title()); + if (dlg.exec()) + { + item->docPlugin()->deleteCatalogConfiguration(item); // this removes the old entry by name + item->docPlugin()->editCatalogConfiguration(item, dlg.title(), dlg.url()); + } +} + +void DocGlobalConfigWidget::addCollectionButtonClicked() +{ + AddCatalogDlg dlg( m_part->m_plugins, this, "add collection dlg", true); + if (dlg.exec()) + { + dlg.plugin()->addCatalogConfiguration(activeView(), dlg.title(), dlg.url()); + } +} + +KListView *DocGlobalConfigWidget::activeView() +{ + return m_View; +} + +void DocGlobalConfigWidget::accept() +{ + //write catalog settings + for (QValueList<DocumentationPlugin*>::const_iterator it = m_part->m_plugins.constBegin(); + it != m_part->m_plugins.constEnd(); ++it) + { + (*it)->saveCatalogConfiguration( m_View ); + //@todo: take restrictions into account + (*it)->reinit(m_widget->contents(), m_widget->index(), QStringList()); + } + + KConfig *config = m_part->config(); + //write full text search settings + config->setGroup("htdig"); + config->writePathEntry("databaseDir", DocUtils::envURL(databaseDirEdit)); + config->writePathEntry("htdigbin", DocUtils::envURL(htdigbinEdit)); + config->writePathEntry("htmergebin", DocUtils::envURL(htmergebinEdit)); + config->writePathEntry("htsearchbin", DocUtils::envURL(htsearchbinEdit)); + + //write full text search locations file + QString ftsLocationsFile = locateLocal("data", "kdevdocumentation/search/locations.txt"); + QFile f(ftsLocationsFile); + QStringList locs; + if (f.open(IO_ReadWrite | IO_Truncate)) + { + QTextStream str(&f); + for (QValueList<DocumentationPlugin*>::const_iterator it = m_part->m_plugins.constBegin(); + it != m_part->m_plugins.constEnd(); ++ it) + { + QStringList app = (*it)->fullTextSearchLocations(); + for (QStringList::const_iterator it2 = app.constBegin(); + it2 != app.constEnd(); ++it2) + { + if (!locs.contains(*it2)) + locs.append(*it2); + } + } + str << locs.join("\n"); + + f.close(); + } + + //write editor context menu configuration + m_part->setContextFeature(DocumentationPart::Finder, find_box->isChecked()); + m_part->setContextFeature(DocumentationPart::IndexLookup, index_box->isChecked()); + m_part->setContextFeature(DocumentationPart::FullTextSearch, search_box->isChecked()); + m_part->setContextFeature(DocumentationPart::GotoMan, man_box->isChecked()); + m_part->setContextFeature(DocumentationPart::GotoInfo, info_box->isChecked()); + + m_part->setAssistantUsed(useAssistant_box->isChecked()); + + //font sizes and zoom levels + KConfig *appConfig = KGlobal::config(); + appConfig->setGroup("KHTMLPart"); + appConfig->writeEntry("StandardFont", standardFont_combo->currentText()); + appConfig->writeEntry("FixedFont", fixedFont_combo->currentText()); + appConfig->writeEntry("Zoom", zoom_combo->currentText()); + + appConfig->sync(); + updateConfigForHTMLParts(); + config->sync(); + + //refill the index + kdDebug() << "refill the index" << endl; + if (m_part->m_hasIndex) + { + kdDebug() << "m_part->m_hasIndex" << endl; + m_part->m_widget->index()->refill(); + } +} + +void DocGlobalConfigWidget::updateConfigForHTMLParts() +{ + KURL::List urls = m_part->partController()->openURLs(); + for (KURL::List::const_iterator it = urls.constBegin(); it != urls.constEnd(); ++it) + { + KHTMLPart *htmlPart = dynamic_cast<KHTMLPart*>(m_part->partController()->partForURL(*it)); + if (htmlPart) + { + KConfig *appConfig = KGlobal::config(); + appConfig->setGroup("KHTMLPart"); + htmlPart->setStandardFont(appConfig->readEntry("StandardFont")); + htmlPart->setFixedFont(appConfig->readEntry("FixedFont")); + //hack to force reloading the page + if (htmlPart->zoomFactor() == appConfig->readEntry("Zoom").toInt()) + { + htmlPart->setZoomFactor(htmlPart->zoomFactor()-1); + htmlPart->setZoomFactor(htmlPart->zoomFactor()+1); + } + htmlPart->setZoomFactor(appConfig->readEntry("Zoom").toInt()); + } + } +} + +#include "docglobalconfigwidget.moc" diff --git a/parts/documentation/docglobalconfigwidget.h b/parts/documentation/docglobalconfigwidget.h new file mode 100644 index 00000000..95b518e5 --- /dev/null +++ b/parts/documentation/docglobalconfigwidget.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCGLOBALCONFIGWIDGET_H +#define DOCGLOBALCONFIGWIDGET_H + +#include "docglobalconfigwidgetbase.h" + +#include <qmap.h> + +class DocumentationPart; +class DocumentationWidget; +class DocumentationPlugin; +class KListView; + +class DocGlobalConfigWidget : public DocGlobalConfigWidgetBase +{ + Q_OBJECT +public: + DocGlobalConfigWidget(DocumentationPart *part, DocumentationWidget *widget, + QWidget *parent = 0, const char *name = 0, WFlags fl = 0); + ~DocGlobalConfigWidget(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void collectionsBoxCurrentChanged(int box); + + virtual void removeCollectionButtonClicked(); + virtual void editCollectionButtonClicked(); + virtual void addCollectionButtonClicked(); + + virtual void accept(); + +protected: + /*$PROTECTED_FUNCTIONS$*/ + KListView *activeView(); + void updateConfigForHTMLParts(); + +protected slots: + /*$PROTECTED_SLOTS$*/ + +private: + DocumentationPart *m_part; + DocumentationWidget *m_widget; + + KListView * m_View; +}; + +#endif + diff --git a/parts/documentation/docglobalconfigwidgetbase.ui b/parts/documentation/docglobalconfigwidgetbase.ui new file mode 100644 index 00000000..1af1e011 --- /dev/null +++ b/parts/documentation/docglobalconfigwidgetbase.ui @@ -0,0 +1,572 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>DocGlobalConfigWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>DocGlobalConfigWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>553</width> + <height>397</height> + </rect> + </property> + <property name="caption"> + <string>Documentation</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>docTab</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>&Documentation Collections</string> + </attribute> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QWidgetStack"> + <property name="name"> + <cstring>viewHolder</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>WStackPage</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>addCollectionButton</cstring> + </property> + <property name="text"> + <string>&Add...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>editCollectionButton</cstring> + </property> + <property name="text"> + <string>&Edit...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeCollectionButton</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>Full Text &Search</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer20</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>190</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>htsearchbinLabel</cstring> + </property> + <property name="text"> + <string>htse&arch executable:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>htsearchbinEdit</cstring> + </property> + </widget> + <widget class="KURLRequester" row="4" column="1"> + <property name="name"> + <cstring>htsearchbinEdit</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="KURLRequester" row="0" column="1"> + <property name="name"> + <cstring>databaseDirEdit</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <widget class="KURLRequester" row="3" column="1"> + <property name="name"> + <cstring>htmergebinEdit</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>htdigbinLabel</cstring> + </property> + <property name="text"> + <string>htdi&g executable:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>htdigbinEdit</cstring> + </property> + </widget> + <widget class="KURLRequester" row="2" column="1"> + <property name="name"> + <cstring>htdigbinEdit</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>databaseDirLabel</cstring> + </property> + <property name="text"> + <string>Database di&rectory:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>databaseDirEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>htmergebinLabel</cstring> + </property> + <property name="text"> + <string>ht&merge executable:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>htmergebinEdit</cstring> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>O&ther</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="3" column="0"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QButtonGroup" row="1" column="0"> + <property name="name"> + <cstring>buttonGroup1</cstring> + </property> + <property name="title"> + <string>Editor Context Menu Items</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>find_box</cstring> + </property> + <property name="text"> + <string>&Find in documentation</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>index_box</cstring> + </property> + <property name="text"> + <string>&Look in documentation index</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>search_box</cstring> + </property> + <property name="text"> + <string>S&earch in documentation</string> + </property> + </widget> + <widget class="QCheckBox" row="4" column="0"> + <property name="name"> + <cstring>info_box</cstring> + </property> + <property name="text"> + <string>Goto &infopage</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>man_box</cstring> + </property> + <property name="text"> + <string>Goto &manpage</string> + </property> + </widget> + </grid> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>useAssistant_box</cstring> + </property> + <property name="text"> + <string>Use KDevelop &Assistant to browse documentation</string> + </property> + </widget> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Fonts && Sizes</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Sta&ndard font:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>standardFont_combo</cstring> + </property> + </widget> + <widget class="KFontCombo" row="0" column="1"> + <property name="name"> + <cstring>standardFont_combo</cstring> + </property> + </widget> + <widget class="KFontCombo" row="1" column="1"> + <property name="name"> + <cstring>fixedFont_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Fi&xed font:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>fixedFont_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Zoom factor:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>zoom_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <item> + <property name="text"> + <string>20</string> + </property> + </item> + <item> + <property name="text"> + <string>40</string> + </property> + </item> + <item> + <property name="text"> + <string>60</string> + </property> + </item> + <item> + <property name="text"> + <string>80</string> + </property> + </item> + <item> + <property name="text"> + <string>90</string> + </property> + </item> + <item> + <property name="text"> + <string>95</string> + </property> + </item> + <item> + <property name="text"> + <string>100</string> + </property> + </item> + <item> + <property name="text"> + <string>105</string> + </property> + </item> + <item> + <property name="text"> + <string>110</string> + </property> + </item> + <item> + <property name="text"> + <string>120</string> + </property> + </item> + <item> + <property name="text"> + <string>140</string> + </property> + </item> + <item> + <property name="text"> + <string>160</string> + </property> + </item> + <item> + <property name="text"> + <string>180</string> + </property> + </item> + <item> + <property name="text"> + <string>200</string> + </property> + </item> + <item> + <property name="text"> + <string>250</string> + </property> + </item> + <item> + <property name="text"> + <string>300</string> + </property> + </item> + <property name="name"> + <cstring>zoom_combo</cstring> + </property> + <property name="currentItem"> + <number>6</number> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>addCollectionButton</sender> + <signal>clicked()</signal> + <receiver>DocGlobalConfigWidgetBase</receiver> + <slot>addCollectionButtonClicked()</slot> + </connection> + <connection> + <sender>editCollectionButton</sender> + <signal>clicked()</signal> + <receiver>DocGlobalConfigWidgetBase</receiver> + <slot>editCollectionButtonClicked()</slot> + </connection> + <connection> + <sender>removeCollectionButton</sender> + <signal>clicked()</signal> + <receiver>DocGlobalConfigWidgetBase</receiver> + <slot>removeCollectionButtonClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>docTab</tabstop> + <tabstop>addCollectionButton</tabstop> + <tabstop>editCollectionButton</tabstop> + <tabstop>removeCollectionButton</tabstop> + <tabstop>databaseDirEdit</tabstop> + <tabstop>htdigbinEdit</tabstop> + <tabstop>htmergebinEdit</tabstop> + <tabstop>htsearchbinEdit</tabstop> + <tabstop>useAssistant_box</tabstop> + <tabstop>find_box</tabstop> + <tabstop>index_box</tabstop> + <tabstop>search_box</tabstop> + <tabstop>info_box</tabstop> + <tabstop>man_box</tabstop> +</tabstops> +<slots> + <slot>addCollectionButtonClicked()</slot> + <slot>editCollectionButtonClicked()</slot> + <slot>removeCollectionButtonClicked()</slot> + <slot>collectionsBoxCurrentChanged( int )</slot> + <slot>updateConfig()</slot> + <slot>updateIndex()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kfontcombo.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kfontcombo.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/parts/documentation/docprojectconfigwidget.cpp b/parts/documentation/docprojectconfigwidget.cpp new file mode 100644 index 00000000..0fd97c95 --- /dev/null +++ b/parts/documentation/docprojectconfigwidget.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docprojectconfigwidget.h" + +#include <qdir.h> +#include <qcombobox.h> + +#include <kdebug.h> +#include <kurlrequester.h> + +#include "domutil.h" +#include "urlutil.h" +#include "kdevproject.h" +#include "kdevdocumentationplugin.h" + +#include "documentation_part.h" +#include "documentation_widget.h" + +DocProjectConfigWidget::DocProjectConfigWidget(DocumentationPart *part, QWidget *parent, const char *name) + :DocProjectConfigWidgetBase(parent, name), m_part(part) +{ + for (QValueList<DocumentationPlugin*>::const_iterator it = m_part->m_plugins.constBegin(); + it != m_part->m_plugins.constEnd(); ++it) + { + if ((*it)->hasCapability(DocumentationPlugin::ProjectDocumentation)) + { + docSystemCombo->insertItem((*it)->pluginName()); + m_plugins[(*it)->pluginName()] = *it; + } + } + QString projectDocSystem = DomUtil::readEntry(*(m_part->projectDom()), "/kdevdocumentation/projectdoc/docsystem"); + + bool hasProjectDoc = false; + for (int i = 0; i < docSystemCombo->count(); ++i) + { + if (docSystemCombo->text(i) == projectDocSystem) + { + docSystemCombo->setCurrentItem(i); + hasProjectDoc = true; + changeDocSystem(docSystemCombo->currentText()); + break; + } + } + if (!hasProjectDoc && docSystemCombo->count() > 0) + { + docSystemCombo->setCurrentItem(0); + changeDocSystem(docSystemCombo->currentText()); + } + + manualURL->setURL(DomUtil::readEntry(*(m_part->projectDom()), "/kdevdocumentation/projectdoc/usermanualurl")); +} + +void DocProjectConfigWidget::changeDocSystem(const QString &text) +{ + if (text.isEmpty()) + return; + + DocumentationPlugin *plugin = m_plugins[text]; + if (!plugin) + return; + + catalogURL->setMode(plugin->catalogLocatorProps().first); + catalogURL->setFilter(plugin->catalogLocatorProps().second); + + QString projectDocURL = DomUtil::readEntry(*(m_part->projectDom()), "/kdevdocumentation/projectdoc/docurl"); + if (!projectDocURL.isEmpty()) + projectDocURL = QDir::cleanDirPath(m_part->project()->projectDirectory() + "/" + projectDocURL); + + catalogURL->setURL(projectDocURL); + catalogURL->setEnabled(true); +} + +void DocProjectConfigWidget::accept() +{ + if (manualURL->url().isEmpty()) + { + if (m_part->m_userManualPlugin) + { + delete m_part->m_userManualPlugin; + m_part->m_userManualPlugin = 0; + } + } + else + { + if (m_part->m_userManualPlugin) + { + delete m_part->m_userManualPlugin; + m_part->m_userManualPlugin = 0; + } + for (QValueList<DocumentationPlugin*>::const_iterator it = m_part->m_plugins.constBegin(); + it != m_part->m_plugins.constEnd(); ++it) + { + if ((*it)->hasCapability(DocumentationPlugin::ProjectUserManual)) + m_part->m_userManualPlugin = (*it)->projectDocumentationPlugin(DocumentationPlugin::UserManual); + } + if (m_part->m_userManualPlugin) + m_part->m_userManualPlugin->init(m_part->m_widget->contents(), m_part->m_widget->index(), manualURL->url()); + } + m_part->saveProjectDocumentationInfo(); + + if (docSystemCombo->currentText().isEmpty()) + return; + if (catalogURL->url().isEmpty()) + { + if (m_part->m_projectDocumentationPlugin) + { + delete m_part->m_projectDocumentationPlugin; + m_part->m_projectDocumentationPlugin = 0; + } + m_part->saveProjectDocumentationInfo(); + return; + } + + DocumentationPlugin *plugin = m_plugins[docSystemCombo->currentText()]; + if (!plugin) + return; + + if (m_part->m_projectDocumentationPlugin) + { + delete m_part->m_projectDocumentationPlugin; + m_part->m_projectDocumentationPlugin = 0; + } + m_part->m_projectDocumentationPlugin = plugin->projectDocumentationPlugin(DocumentationPlugin::APIDocs); + m_part->m_projectDocumentationPlugin->init(m_part->m_widget->contents(), m_part->m_widget->index(), catalogURL->url()); + + m_part->saveProjectDocumentationInfo(); +} + +#include "docprojectconfigwidget.moc" diff --git a/parts/documentation/docprojectconfigwidget.h b/parts/documentation/docprojectconfigwidget.h new file mode 100644 index 00000000..5905f6eb --- /dev/null +++ b/parts/documentation/docprojectconfigwidget.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCPROJECTCONFIGWIDGET_H +#define DOCPROJECTCONFIGWIDGET_H + +#include "docprojectconfigwidgetbase.h" + +class DocumentationPart; +class DocumentationPlugin; + +class DocProjectConfigWidget: public DocProjectConfigWidgetBase { + Q_OBJECT +public: + DocProjectConfigWidget(DocumentationPart *part, QWidget *parent = 0, const char *name = 0); + +public slots: + virtual void changeDocSystem(const QString &text); + virtual void accept(); + +private: + DocumentationPart *m_part; + QMap<QString, DocumentationPlugin*> m_plugins; +}; +#endif diff --git a/parts/documentation/docprojectconfigwidgetbase.ui b/parts/documentation/docprojectconfigwidgetbase.ui new file mode 100644 index 00000000..ccff4bfc --- /dev/null +++ b/parts/documentation/docprojectconfigwidgetbase.ui @@ -0,0 +1,152 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>DocProjectConfigWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>DocProjectConfigWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>484</width> + <height>292</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>60</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Project API Documentation</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KURLRequester" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>catalogURL</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Ca&talog location:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>catalogURL</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>C&ollection type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>docSystemCombo</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>docSystemCombo</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Project User Manual</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>&Location:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>manualURL</cstring> + </property> + </widget> + <widget class="KURLRequester" row="1" column="0"> + <property name="name"> + <cstring>manualURL</cstring> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>docSystemCombo</sender> + <signal>activated(const QString&)</signal> + <receiver>DocProjectConfigWidgetBase</receiver> + <slot>changeDocSystem(const QString&)</slot> + </connection> +</connections> +<tabstops> + <tabstop>catalogURL</tabstop> + <tabstop>docSystemCombo</tabstop> +</tabstops> +<slots> + <slot>changeDocSystem(const QString &)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> +</includehints> +</UI> diff --git a/parts/documentation/documentation_part.cpp b/parts/documentation/documentation_part.cpp new file mode 100644 index 00000000..0402efd5 --- /dev/null +++ b/parts/documentation/documentation_part.cpp @@ -0,0 +1,766 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "documentation_part.h" + +#include <unistd.h> + +#include <qtimer.h> +#include <qdir.h> +#include <qwhatsthis.h> +#include <qlayout.h> +#include <qpopupmenu.h> +#include <qtabwidget.h> +#include <qapplication.h> + +#include <kapplication.h> +#include <dcopclient.h> +#include <kiconloader.h> +#include <klocale.h> +#include <ktrader.h> +#include <kdebug.h> +#include <kparts/componentfactory.h> +#include <kservice.h> +#include <kdialogbase.h> +#include <kaction.h> +#include <kactionclasses.h> +#include <kbookmark.h> +#include <kbookmarkmenu.h> +#include <kinputdialog.h> +#include <kstringhandler.h> +#include <kconfig.h> +#include <kwin.h> +#include <ktexteditor/document.h> + +#include "kdevplugininfo.h" +#include "kdevcore.h" +#include "kdevproject.h" +#include "kdevmainwindow.h" +#include "kdevgenericfactory.h" +#include "kdevdocumentationplugin.h" +#include "configwidgetproxy.h" +#include "kdevpartcontroller.h" +#include "domutil.h" +#include "urlutil.h" +#include "kdeveditorutil.h" + +#include "documentation_widget.h" +#include "docglobalconfigwidget.h" +#include "docprojectconfigwidget.h" +#include "contentsview.h" +#include "find_documentation.h" + +#include "KDevDocumentationIface.h" + +#define GLOBALDOC_OPTIONS 1 +#define PROJECTDOC_OPTIONS 2 + +static const KDevPluginInfo data("kdevdocumentation"); + +typedef KDevGenericFactory<DocumentationPart> DocumentationFactory; +K_EXPORT_COMPONENT_FACTORY( libkdevdocumentation, DocumentationFactory( data ) ) + +DocumentationPart::DocumentationPart(QObject *parent, const char *name, const QStringList& ) + :KDevPlugin(&data, parent, name ? name : "DocumentationPart" ), + m_projectDocumentationPlugin(0), m_userManualPlugin(0), m_hasIndex(false) +{ + setInstance(DocumentationFactory::instance()); + setXMLFile("kdevpart_documentation.rc"); + + m_configProxy = new ConfigWidgetProxy(core()); + m_configProxy->createGlobalConfigPage(i18n("Documentation"), GLOBALDOC_OPTIONS, info()->icon() ); + m_configProxy->createProjectConfigPage(i18n("Project Documentation"), PROJECTDOC_OPTIONS, info()->icon() ); + connect(m_configProxy, SIGNAL(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )), this, SLOT(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int))); + connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), + this, SLOT(contextMenu(QPopupMenu *, const Context *))); + connect(core(), SIGNAL(projectOpened()), this, SLOT(projectOpened())); + connect(core(), SIGNAL(projectClosed()), this, SLOT(projectClosed())); + + m_widget = new DocumentationWidget(this); + m_widget->setIcon(SmallIcon( info()->icon() )); + m_widget->setCaption(i18n("Documentation")); + + QWhatsThis::add(m_widget, i18n("<b>Documentation browser</b><p>" + "The documentation browser gives access to various " + "documentation sources (Qt DCF, Doxygen, KDoc, KDevelopTOC and DevHelp " + "documentation) and the KDevelop manuals. It also provides documentation index " + "and full text search capabilities.")); + + mainWindow()->embedSelectViewRight(m_widget, i18n("Documentation"), + i18n("Documentation browser")); + + setupActions(); + + QTimer::singleShot(0, this, SLOT(init())); + + new KDevDocumentationIface(this); +} + +DocumentationPart::~DocumentationPart() +{ + if ( m_widget ) + { + mainWindow()->removeView( m_widget ); + } + delete m_widget; + delete m_configProxy; +} + +void DocumentationPart::loadDocumentationPlugins() +{ + KTrader::OfferList docPluginOffers = + KTrader::self()->query(QString::fromLatin1("KDevelop/DocumentationPlugins"), + QString("[X-KDevelop-Version] == %1").arg(KDEVELOP_PLUGIN_VERSION)); + + KTrader::OfferList::ConstIterator serviceIt = docPluginOffers.begin(); + for ( ; serviceIt != docPluginOffers.end(); ++serviceIt ) + { + KService::Ptr docPluginService; + docPluginService = *serviceIt; + kdDebug() << "DocumentationPart::loadDocumentationPlugins: creating plugin" + << docPluginService->name() << endl; + + int error; + DocumentationPlugin *docPlugin = KParts::ComponentFactory + ::createInstanceFromService<DocumentationPlugin>(docPluginService, 0, + docPluginService->name().latin1(), QStringList(), &error); + if (!docPlugin) + kdDebug() << " failed to create doc plugin " << docPluginService->name() << endl; + else + { + kdDebug() << " success" << endl; + docPlugin->init(m_widget->contents()); + connect(this, SIGNAL(indexSelected(IndexBox* )), docPlugin, SLOT(createIndex(IndexBox* ))); + m_plugins.append(docPlugin); + } + } +} + +void DocumentationPart::emitIndexSelected(IndexBox *indexBox) +{ + if (!m_hasIndex) + { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + emit indexSelected(indexBox); + indexBox->fill(); + m_hasIndex = true; + QApplication::restoreOverrideCursor(); + } +} + +void DocumentationPart::insertConfigWidget(const KDialogBase *dlg, QWidget *page, unsigned int pageNo) +{ + switch (pageNo) + { + case GLOBALDOC_OPTIONS: + { + DocGlobalConfigWidget *w1 = new DocGlobalConfigWidget(this, m_widget, page, "doc config widget"); + connect(dlg, SIGNAL(okClicked()), w1, SLOT(accept())); + break; + } + case PROJECTDOC_OPTIONS: + { + DocProjectConfigWidget *w1 = new DocProjectConfigWidget(this, page, "doc project config"); + connect(dlg, SIGNAL(okClicked()), w1, SLOT(accept())); + break; + } + } +} + +KConfig *DocumentationPart::config() +{ + return DocumentationFactory::instance()->config(); +} + +bool DocumentationPart::configure(int page) +{ + KDialogBase dlg(KDialogBase::Plain, i18n("Documentation Settings"), + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, m_widget, + "docsettings dialog"); + + QVBoxLayout *l = new QVBoxLayout(dlg.plainPage(), 0, 0); + DocGlobalConfigWidget *w1 = new DocGlobalConfigWidget(this, m_widget, dlg.plainPage()); + l->addWidget(w1); + w1->docTab->setCurrentPage(page); + connect(&dlg, SIGNAL(okClicked()), w1, SLOT(accept())); + return (dlg.exec() == QDialog::Accepted); +} + +void DocumentationPart::setupActions() +{ +/* KActionMenu *menu = new KActionMenu(i18n("&Bookmarks"), actionCollection(), "doc_bookmarks"); + KBookmarkMenu *bm = new KBookmarkMenu(new DocBookmarkManager(this), + new DocBookmarkOwner(this), menu->popupMenu(), actionCollection(), true);*/ + KAction *action; + + action = new KAction(i18n("&Search in Documentation..."), CTRL+ALT+Key_S, + this, SLOT(searchInDocumentation()), + actionCollection(), "help_search_in_doc" ); + action->setToolTip(i18n("Full text search in the documentation")); + action->setWhatsThis(i18n("<b>Search in documentation</b><p>" + "Opens the Search in documentation tab. It allows " + "a search term to be entered which will be searched for in " + "the documentation. For this to work, a " + "full text index must be created first, which can be done in the " + "configuration dialog of the documentation plugin.")); + + action = new KAction(i18n("&Look in Documentation Index..."), CTRL+ALT+Key_I, + this, SLOT(lookInDocumentationIndex()), + actionCollection(), "help_look_in_index" ); + action->setToolTip(i18n("Look in the documentation index")); + action->setWhatsThis(i18n("<b>Look in documentation index</b><p>" + "Opens the documentation index tab. It allows " + "a term to be entered which will be looked for in " + "the documentation index.")); + + action = new KAction(i18n("Man Page..."), 0, + this, SLOT(manPage()), + actionCollection(), "help_manpage" ); + action->setToolTip(i18n("Show a manpage")); + action->setWhatsThis(i18n("<b>Show a manpage</b><p>Opens a man page using embedded viewer.")); + + action = new KAction(i18n("Info Page..."), 0, + this, SLOT(infoPage()), + actionCollection(), "help_infopage"); + action->setToolTip(i18n("Show an infopage")); + action->setWhatsThis(i18n("<b>Show an infopage</b><p>Opens an info page using embedded viewer.")); + + action = new KAction(i18n("Find Documentation..."), 0, + this, SLOT(findInDocumentation()), + actionCollection(), "help_find_documentation"); + action->setToolTip(i18n("Find Documentation")); + action->setWhatsThis(i18n("<b>Find documentation</b><p>" + "Opens the documentation finder tab and searches " + "all possible sources of documentation like " + "table of contents, index, man and info databases, " + "Google, etc.")); +} + +void DocumentationPart::emitBookmarkLocation(const QString &title, const KURL &url) +{ + emit bookmarkLocation(title, url); +} + +void DocumentationPart::searchInDocumentation() +{ + QString word = KDevEditorUtil::currentWord( dynamic_cast<KTextEditor::Document*>( partController()->activePart() ) ); + + if ( word.isEmpty() ) + { + if ( isAssistantUsed() ) + callAssistant ( "KDevDocumentation", "searchInDocumentation()" ); + else + { + mainWindow()->raiseView ( m_widget ); + m_widget->searchInDocumentation(); + } + } + else + { + if ( isAssistantUsed() ) + callAssistant ( "KDevDocumentation", "searchInDocumentation(QString)", word ); + else + { + mainWindow()->raiseView ( m_widget ); + m_widget->searchInDocumentation ( word ); + } + } +} + +void DocumentationPart::searchInDocumentation(const QString &term) +{ + mainWindow()->raiseView(m_widget); + m_widget->searchInDocumentation(term); +} + +void DocumentationPart::contextSearchInDocumentation() +{ + if (isAssistantUsed()) + callAssistant("KDevDocumentation", "searchInDocumentation(QString)", m_contextStr); + else + searchInDocumentation(m_contextStr); +} + +void DocumentationPart::manPage() +{ + QString word = KDevEditorUtil::currentWord( dynamic_cast<KTextEditor::Document*>( partController()->activePart() ) ); + + if ( isAssistantUsed() ) + { + if ( word.isEmpty() ) + { + callAssistant ( "KDevDocumentation", "manPage()" ); + } + else + { + callAssistant ( "KDevDocumentation", "manPage(QString)", word ); + } + } + else + { + bool ok; + QString manpage = KInputDialog::getText ( i18n ( "Show Manual Page" ), i18n ( "Show manpage on:" ), word, &ok, 0 ); + if ( ok && !manpage.isEmpty() ) + manPage ( manpage ); + } +} + +void DocumentationPart::infoPage() +{ + QString word = KDevEditorUtil::currentWord( dynamic_cast<KTextEditor::Document*>( partController()->activePart() ) ); + + if ( isAssistantUsed() ) + { + if ( word.isEmpty() ) + { + callAssistant ( "KDevDocumentation", "infoPage()" ); + } + else + { + callAssistant ( "KDevDocumentation", "infoPage(QString)", word ); + } + } + else + { + bool ok; + QString infopage = KInputDialog::getText ( i18n ( "Show Info Page" ), i18n ( "Show infopage on:" ), word, &ok, 0 ); + if ( ok && !infopage.isEmpty() ) + infoPage ( infopage ); + } +} + +void DocumentationPart::manPage(const QString &term) +{ + QString url = QString::fromLatin1("man:/%1").arg(term); + partController()->showDocument(KURL(url)); +} + +void DocumentationPart::infoPage(const QString &term) +{ + QString url = QString::fromLatin1("info:/%1").arg(term); + partController()->showDocument(KURL(url)); +} + +void DocumentationPart::contextManPage() +{ + if (isAssistantUsed()) + callAssistant("KDevDocumentation", "manPage(QString)", m_contextStr); + else + manPage(m_contextStr); +} + +void DocumentationPart::contextInfoPage() +{ + if (isAssistantUsed()) + callAssistant("KDevDocumentation", "infoPage(QString)", m_contextStr); + else + infoPage(m_contextStr); +} + +void DocumentationPart::contextFindDocumentation() +{ + if (isAssistantUsed()) + callAssistant("KDevDocumentation", "findInFinder(QString)", m_contextStr); + else + findInDocumentation(m_contextStr); +} + +void DocumentationPart::findInDocumentation() +{ + QString word = KDevEditorUtil::currentWord( dynamic_cast<KTextEditor::Document*>( partController()->activePart() ) ); + + if ( word.isEmpty() ) + { + if ( isAssistantUsed() ) + callAssistant ( "KDevDocumentation", "findInFinder()" ); + else + { + mainWindow()->raiseView ( m_widget ); + m_widget->findInDocumentation(); + } + } + else + { + if ( isAssistantUsed() ) + callAssistant ( "KDevDocumentation", "findInFinder(QString)", word ); + else + { + mainWindow()->raiseView ( m_widget ); + m_widget->findInDocumentation ( word ); + } + } +} + +void DocumentationPart::findInDocumentation(const QString &term) +{ + mainWindow()->raiseView(m_widget); + m_widget->findInDocumentation(term); +} + +void DocumentationPart::lookInDocumentationIndex() +{ + QString word = KDevEditorUtil::currentWord( dynamic_cast<KTextEditor::Document*>( partController()->activePart() ) ); + + if ( word.isEmpty() ) + { + if ( isAssistantUsed() ) + callAssistant ( "KDevDocumentation", "lookupInIndex()" ); + else + { + mainWindow()->raiseView ( m_widget ); + m_widget->lookInDocumentationIndex(); + } + } + else + { + if ( isAssistantUsed() ) + callAssistant ( "KDevDocumentation", "lookupInIndex(QString)", word ); + else + { + mainWindow()->raiseView ( m_widget ); + m_widget->lookInDocumentationIndex ( word ); + } + } +} + +void DocumentationPart::lookInDocumentationIndex(const QString &term) +{ + mainWindow()->raiseView(m_widget); + m_widget->lookInDocumentationIndex(term); +} + +void DocumentationPart::contextLookInDocumentationIndex() +{ + if (isAssistantUsed()) + callAssistant("KDevDocumentation", "lookupInIndex(QString)", m_contextStr); + else + lookInDocumentationIndex(m_contextStr); +} + +void DocumentationPart::contextMenu(QPopupMenu *popup, const Context *context) +{ + if (context->hasType(Context::EditorContext)) + { + const EditorContext *econtext = static_cast<const EditorContext*>(context); + QString ident = econtext->currentWord(); + if (!ident.isEmpty()) + { + m_contextStr = ident; + QString squeezed = KStringHandler::csqueeze(m_contextStr, 30); + int id = -1; + if (hasContextFeature(Finder)) { + id = popup->insertItem(i18n("Find Documentation: %1").arg(squeezed), + this, SLOT(contextFindDocumentation())); + popup->setWhatsThis(id, i18n("<b>Find documentation</b><p>" + "Opens the documentation finder tab and searches " + "all possible sources of documentation like " + "table of contents, index, man and info databases, " + "Google, etc.")); + } + if (hasContextFeature(IndexLookup)) { + id = popup->insertItem(i18n("Look in Documentation Index: %1").arg(squeezed), + this, SLOT(contextLookInDocumentationIndex())); + popup->setWhatsThis(id, i18n("<b>Look in documentation index</b><p>" + "Opens the documentation index tab. It allows " + "a term to be entered which will be looked for in " + "the documentation index.")); + } + if (hasContextFeature(FullTextSearch)) { + id = popup->insertItem(i18n("Search in Documentation: %1").arg(squeezed), + this, SLOT(contextSearchInDocumentation())); + popup->setWhatsThis(id, i18n("<b>Search in documentation</b><p>Searches " + "for a term under the cursor in " + "the documentation. For this to work, " + "a full text index must be created first, which can be done in the " + "configuration dialog of the documentation plugin.")); + } + if (hasContextFeature(GotoMan)) { + id = popup->insertItem(i18n("Goto Manpage: %1").arg(squeezed), + this, SLOT(contextManPage())); + popup->setWhatsThis(id, i18n("<b>Goto manpage</b><p>Tries to open a man page for the term under the cursor.")); + } + if (hasContextFeature(GotoInfo)) { + id = popup->insertItem( i18n("Goto Infopage: %1").arg(squeezed), + this, SLOT(contextInfoPage()) ); + popup->setWhatsThis(id, i18n("<b>Goto infopage</b><p>Tries to open an info page for the term under the cursor.")); + } + if (id != -1) + popup->insertSeparator(); + } + } +} + +bool DocumentationPart::hasContextFeature(ContextFeature feature) +{ + KConfig *config = DocumentationFactory::instance()->config(); + QString group = config->group(); + config->setGroup("Context Features"); + switch (feature) + { + case Finder: + return config->readBoolEntry("Finder", true); + break; + case IndexLookup: + return config->readBoolEntry("IndexLookup", false); + break; + case FullTextSearch: + return config->readBoolEntry("FullTextSearch", true); + break; + case GotoMan: + return config->readBoolEntry("GotoMan", false); + break; + case GotoInfo: + return config->readBoolEntry("GotoInfo", false); + break; + } + config->setGroup(group); + return false; +} + +void DocumentationPart::setContextFeature(ContextFeature feature, bool b) +{ + KConfig *config = DocumentationFactory::instance()->config(); + QString group = config->group(); + config->setGroup("Context Features"); + QString key; + switch (feature) + { + case Finder: + key = "Finder"; + break; + case IndexLookup: + key = "IndexLookup"; + break; + case FullTextSearch: + key = "FullTextSearch"; + break; + case GotoMan: + key = "GotoMan"; + break; + case GotoInfo: + key = "GotoInfo"; + break; + } + if (!key.isEmpty()) + config->writeEntry(key, b); + config->setGroup(group); +} + +void DocumentationPart::projectOpened() +{ + QString projectDocSystem = DomUtil::readEntry(*(projectDom()), "/kdevdocumentation/projectdoc/docsystem"); + QString projectDocURL = DomUtil::readEntry(*(projectDom()), "/kdevdocumentation/projectdoc/docurl"); + if (!projectDocURL.isEmpty()) + projectDocURL = QDir::cleanDirPath(project()->projectDirectory() + "/" + projectDocURL); + QString userManualURL = DomUtil::readEntry(*(projectDom()), "/kdevdocumentation/projectdoc/usermanualurl"); + + for (QValueList<DocumentationPlugin*>::const_iterator it = m_plugins.constBegin(); + it != m_plugins.constEnd(); ++it) + { + if ((*it)->hasCapability(DocumentationPlugin::ProjectDocumentation) && + ((*it)->pluginName() == projectDocSystem)) + m_projectDocumentationPlugin = (*it)->projectDocumentationPlugin(DocumentationPlugin::APIDocs); + if ((*it)->hasCapability(DocumentationPlugin::ProjectUserManual)) + { + kdDebug() << "creating user manual for type: " << DocumentationPlugin::UserManual << endl; + m_userManualPlugin = (*it)->projectDocumentationPlugin(DocumentationPlugin::UserManual); + } + } + if (m_projectDocumentationPlugin) + m_projectDocumentationPlugin->init(m_widget->contents(), m_widget->index(), projectDocURL); + if (m_userManualPlugin && !userManualURL.isEmpty()) + m_userManualPlugin->init(m_widget->contents(), m_widget->index(), userManualURL); +} + +void DocumentationPart::projectClosed() +{ +// saveProjectDocumentationInfo(); + + delete m_projectDocumentationPlugin; + m_projectDocumentationPlugin = 0; + delete m_userManualPlugin; + m_userManualPlugin = 0; +} + +void DocumentationPart::saveProjectDocumentationInfo() +{ + if (m_projectDocumentationPlugin) + { + DomUtil::writeEntry(*(projectDom()), "/kdevdocumentation/projectdoc/docsystem", m_projectDocumentationPlugin->pluginName()); + + QString relPath = URLUtil::extractPathNameRelative(project()->projectDirectory(), + m_projectDocumentationPlugin->catalogURL()); + DomUtil::writeEntry(*(projectDom()), "/kdevdocumentation/projectdoc/docurl", relPath); + } + else + { + DomUtil::writeEntry(*(projectDom()), "/kdevdocumentation/projectdoc/docsystem", ""); + DomUtil::writeEntry(*(projectDom()), "/kdevdocumentation/projectdoc/docurl", ""); + } + if (m_userManualPlugin) + DomUtil::writeEntry(*(projectDom()), "/kdevdocumentation/projectdoc/usermanualurl", m_userManualPlugin->catalogURL()); + else + DomUtil::writeEntry(*(projectDom()), "/kdevdocumentation/projectdoc/usermanualurl", ""); +} + +QCString DocumentationPart::startAssistant() +{ + static QCString lastAssistant = ""; + + if (!lastAssistant.isEmpty() && KApplication::dcopClient()->isApplicationRegistered(lastAssistant)) + return lastAssistant; + + const char *function = 0; + QString app = "kdevassistant"; + function = "start_service_by_desktop_name(QString,QStringList)"; + QStringList URLs; + + QByteArray data, replyData; + QCString replyType; + QDataStream arg(data, IO_WriteOnly); + arg << app << URLs; + + if (!KApplication::dcopClient()->call("klauncher", "klauncher", function, data, replyType, replyData)) + { + kdDebug() << "call failed" << endl; + lastAssistant = ""; + } + else + { + QDataStream reply(replyData, IO_ReadOnly); + + if ( replyType != "serviceResult" ) + { + kdDebug() << "unexpected result: " << replyType.data() << endl; + lastAssistant = ""; + } + int result; + QCString dcopName; + QString error; + reply >> result >> dcopName >> error; + if (result != 0) + { + kdDebug() << "Error: " << error << endl; + lastAssistant = ""; + } + if (!dcopName.isEmpty()) + { + lastAssistant = dcopName; + kdDebug() << dcopName.data() << endl; + + //@fixme: is there another way to wait for the remote object to be loaded + while (!KApplication::dcopClient()->remoteObjects(dcopName).contains("KDevDocumentation")) + usleep(500); + } + } + return lastAssistant; +} + +bool DocumentationPart::isAssistantUsed() const +{ + // hack to solve BR #90334 - don't call kdevassistant via DCOP if we ARE kdevassistant + if ( kapp->instanceName().find("kdevassistant") != -1 ) + { + return false; + } + + return m_assistantUsed; +} + +void DocumentationPart::setAssistantUsed(bool b) +{ + m_assistantUsed = b; + //use global config to store different settings for kdevassistant and kdevelop + KConfig *config = kapp->config(); + config->setGroup("Documentation"); + config->writeEntry("UseAssistant", isAssistantUsed()); +} + +void DocumentationPart::activateAssistantWindow(const QCString &ref) +{ + kdDebug() << "DocumentationPart::activateAssistantWindow" << endl; + QByteArray data, replyData; + QCString replyType; + if (KApplication::dcopClient()->call(ref, "MainWindow", "getWinID()", data, replyType, replyData)) + { + kdDebug() << " call successful " << endl; + QDataStream reply(replyData, IO_ReadOnly); + + int winId; + reply >> winId; + kdDebug() << "Win ID: " << winId << endl; + KWin::forceActiveWindow(winId); + + KApplication::dcopClient()->send(ref, "MainWindow", "show()", QByteArray()); + } +} + +void DocumentationPart::callAssistant(const QCString &interface, const QCString &method) +{ + QCString ref = startAssistant(); + QByteArray data; + if (KApplication::dcopClient()->send(ref, interface, method, data)) + activateAssistantWindow(ref); + else + kdDebug() << "problem communicating with: " << ref; +} + +void DocumentationPart::callAssistant(const QCString &interface, const QCString &method, const QString &dataStr) +{ + QCString ref = startAssistant(); + QByteArray data; + QDataStream arg(data, IO_WriteOnly); + arg << dataStr; + if (KApplication::dcopClient()->send(ref, interface, method, data)) + activateAssistantWindow(ref); + else + kdDebug() << "problem communicating with: " << ref; +} + +void DocumentationPart::loadSettings() +{ + KConfig *config = kapp->config(); + config->setGroup("Documentation"); + m_assistantUsed = config->readBoolEntry("UseAssistant", false); + + if (QString(KGlobal::instance()->aboutData()->appName()) == "kdevassistant") + { + int page = config->readNumEntry("LastPage", 0); + switch (page) + { + case 1: + lookInDocumentationIndex(); + break; + case 2: + findInDocumentation(); + break; + case 3: + searchInDocumentation(); + break; + } + } +} + +void DocumentationPart::init( ) +{ + loadDocumentationPlugins(); + loadSettings(); +} + +#include "documentation_part.moc" diff --git a/parts/documentation/documentation_part.h b/parts/documentation/documentation_part.h new file mode 100644 index 00000000..cad19d7a --- /dev/null +++ b/parts/documentation/documentation_part.h @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __KDEVPART_DOCUMENTATION_H__ +#define __KDEVPART_DOCUMENTATION_H__ + +#include <qguardedptr.h> +#include <kdevplugin.h> + + +class FindDocumentation; +class DocumentationWidget; +class IndexBox; +class KConfig; +class KDialogBase; +class ConfigWidgetProxy; +class DocumentationPlugin; +class ProjectDocumentationPlugin; +class KURL; +class Context; +class QPopupMenu; + +/* + Please read the README.dox file for more info about this part + */ +class DocumentationPart : public KDevPlugin +{ + Q_OBJECT +public: + enum ContextFeature { Finder, IndexLookup, FullTextSearch, GotoMan, GotoInfo }; + + DocumentationPart(QObject *parent, const char *name, const QStringList &); + ~DocumentationPart(); + + void emitIndexSelected(IndexBox *indexBox); + void emitBookmarkLocation(const QString &title, const KURL &url); + bool configure(int page = 0); + + bool hasContextFeature(ContextFeature feature); + void setContextFeature(ContextFeature feature, bool b); + + bool isAssistantUsed() const; + void setAssistantUsed(bool b); + +public slots: + void lookInDocumentationIndex(); + void lookInDocumentationIndex(const QString &term); + void contextLookInDocumentationIndex(); + void contextFindDocumentation(); + void findInDocumentation(); + void findInDocumentation(const QString &term); + void searchInDocumentation(); + void searchInDocumentation(const QString &term); + void contextSearchInDocumentation(); + void manPage(); + void manPage(const QString &term); + void contextManPage(); + void infoPage(); + void infoPage(const QString &term); + void contextInfoPage(); + void projectOpened(); + void projectClosed(); + +signals: + void indexSelected(IndexBox *indexBox); + void bookmarkLocation(const QString &title, const KURL &url); + +protected: + void loadDocumentationPlugins(); + KConfig *config(); + void setupActions(); + void loadSettings(); + void saveProjectDocumentationInfo(); + + QCString startAssistant(); + void activateAssistantWindow(const QCString &ref); + void callAssistant(const QCString &interface, const QCString &method); + void callAssistant(const QCString &interface, const QCString &method, const QString &dataStr); + +protected slots: + void insertConfigWidget(const KDialogBase *dlg, QWidget *page, unsigned int pageNo); + void contextMenu(QPopupMenu *popup, const Context *context); + +private slots: + void init(); + +private: + QGuardedPtr<DocumentationWidget> m_widget; + ConfigWidgetProxy *m_configProxy; + + QValueList<DocumentationPlugin*> m_plugins; + ProjectDocumentationPlugin *m_projectDocumentationPlugin; + ProjectDocumentationPlugin *m_userManualPlugin; + + QString m_contextStr; + bool m_hasIndex; + bool m_assistantUsed; + +friend class DocGlobalConfigWidget; +friend class DocProjectConfigWidget; +friend class SearchView; +friend class FindDocumentation; +}; + +#endif diff --git a/parts/documentation/documentation_widget.cpp b/parts/documentation/documentation_widget.cpp new file mode 100644 index 00000000..255a834e --- /dev/null +++ b/parts/documentation/documentation_widget.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "documentation_widget.h" + +#include <qlayout.h> +#include <qtoolbox.h> + +#include <klineedit.h> +#include <kparts/part.h> +#include <klibloader.h> +#include <kurl.h> +#include <klocale.h> +#include <kdebug.h> +#include <kapplication.h> +#include <kconfig.h> + +#include <kdevcore.h> +#include <kdevdocumentationplugin.h> + +#include "documentation_part.h" +#include "contentsview.h" +#include "indexview.h" +#include "searchview.h" +#include "bookmarkview.h" +#include "find_documentation.h" + +DocumentationWidget::DocumentationWidget(DocumentationPart *part) + :QWidget(0, "documentation widget"), m_part(part) +{ + QVBoxLayout *l = new QVBoxLayout(this, 0, 0); + + m_tab = new QToolBox(this); + l->addWidget(m_tab); + + m_contents = new ContentsView(this); + m_tab->addItem(m_contents, i18n("Contents")); + + m_index = new IndexView(this); + m_tab->addItem(m_index, i18n("Index")); + + m_finder = new FindDocumentation(this); + m_tab->addItem(m_finder,i18n("Finder")); + + m_search = new SearchView(m_part, this); + m_tab->addItem(m_search, i18n("Search")); + + m_bookmarks = new BookmarkView(this); + m_tab->addItem(m_bookmarks, i18n("Bookmarks")); + + connect(m_tab, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); +} + +DocumentationWidget::~DocumentationWidget() +{ + KConfig *config = kapp->config(); + config->setGroup("Documentation"); + config->writeEntry("LastPage", m_tab->currentIndex()); +} + +void DocumentationWidget::tabChanged(int t) +{ + if (!m_tab->item(t)) + return; + m_tab->item(t)->setFocus(); + if (m_tab->item(t) == m_index) + m_part->emitIndexSelected(m_index->indexBox()); +} + +IndexBox *DocumentationWidget::index() const +{ + return m_index->indexBox(); +} + +void DocumentationWidget::searchInDocumentation() +{ + m_tab->setCurrentItem(m_search); + m_search->askSearchTerm(); +} + +void DocumentationWidget::searchInDocumentation(const QString &term) +{ + m_tab->setCurrentItem(m_search); + m_search->setSearchTerm(term); + m_search->search(); +} + +void DocumentationWidget::lookInDocumentationIndex() +{ + m_tab->setCurrentItem(m_index); + m_index->askSearchTerm(); +} + +void DocumentationWidget::lookInDocumentationIndex(const QString &term) +{ + m_tab->setCurrentItem(m_index); + m_index->setSearchTerm(term); + //adymo: let's allow the user to press enter here ;) +// m_index->searchInIndex(); +} + +void DocumentationWidget::findInDocumentation(const QString &term) +{ + m_tab->setCurrentItem(m_finder); + m_finder->setSearchTerm(term); + m_finder->startSearch(); +} + +void DocumentationWidget::findInDocumentation() +{ + m_tab->setCurrentItem(m_finder); + m_finder->search_term->setFocus(); +} + +void DocumentationWidget::focusInEvent(QFocusEvent */*e*/) +{ + if (m_tab->currentItem()) + m_tab->currentItem()->setFocus(); +} + +KListView * DocumentationWidget::contents( ) const +{ + return m_contents->view(); +} + +#include "documentation_widget.moc" diff --git a/parts/documentation/documentation_widget.h b/parts/documentation/documentation_widget.h new file mode 100644 index 00000000..c3a43ce7 --- /dev/null +++ b/parts/documentation/documentation_widget.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __DOCUMENTATION_WIDGET_H__ +#define __DOCUMENTATION_WIDGET_H__ + +#include <qwidget.h> + +class FindDocumentation; +class KDevProject; +class DocumentationPart; +class ContentsView; +class IndexView; +class DocumentationCatalogItem; +class QToolBox; +class IndexBox; +class SearchView; +class BookmarkView; +class KListView; + +class DocumentationWidget : public QWidget +{ + Q_OBJECT +public: + DocumentationWidget(DocumentationPart *part); + ~DocumentationWidget(); + + DocumentationPart *part() const { return m_part; } + + KListView *contents() const; + IndexBox *index() const; + +public slots: + void lookInDocumentationIndex(); + void lookInDocumentationIndex(const QString &term); + void searchInDocumentation(); + void searchInDocumentation(const QString &term); + void findInDocumentation(); + void findInDocumentation(const QString &term); + +protected: + virtual void focusInEvent(QFocusEvent *e); + +protected slots: + void tabChanged(int t); + +private: + DocumentationPart *m_part; + ContentsView *m_contents; + IndexView *m_index; + SearchView *m_search; + BookmarkView *m_bookmarks; + FindDocumentation *m_finder; + QToolBox *m_tab; + +friend class FindDocumentation; +}; + +#endif diff --git a/parts/documentation/docutils.cpp b/parts/documentation/docutils.cpp new file mode 100644 index 00000000..52b1964b --- /dev/null +++ b/parts/documentation/docutils.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docutils.h" + +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <klineedit.h> +#include <kcombobox.h> +#include <kpopupmenu.h> +#include <klocale.h> +#include <kstringhandler.h> + +#include <kdevpartcontroller.h> + +#include "kdevdocumentationplugin.h" +#include "documentation_part.h" + +QString DocUtils::noEnvURL(const QString &url) +{ + return KURLCompletion::replacedPath(url, true, true); +} + +KURL DocUtils::noEnvURL(const KURL &url) +{ + QString replaced = KURLCompletion::replacedPath(url.url(), true, true); + KURL kurl(replaced); + kurl.setQuery(url.query()); + kurl.setRef(url.ref()); + return kurl; +} + +QString DocUtils::envURL(KURLRequester *req) +{ + if (req->lineEdit()) + return req->lineEdit()->text(); + else if (req->comboBox()) + return req->comboBox()->currentText(); + else + return req->url(); +} + +void DocUtils::docItemPopup(DocumentationPart *part, DocumentationItem *docItem, + const QPoint &pos, bool showBookmark, bool showSearch, int titleCol) +{ + docItemPopup(part, docItem->text(titleCol), docItem->url(), pos, showBookmark, showSearch); +} + +void DocUtils::docItemPopup(DocumentationPart *part, IndexItem *docItem, const QPoint &pos, + bool showBookmark, bool showSearch) +{ + //FIXME: index item can have more than one url, what to do? + KURL url; + if (docItem->urls().count() > 0) + url = docItem->urls().first().second; + docItemPopup(part, docItem->text(), url, pos, showBookmark, showSearch); +} + +void DocUtils::docItemPopup(DocumentationPart *part, const QString &title, const KURL &url, + const QPoint &pos, bool showBookmark, bool showSearch) +{ + KPopupMenu menu; + menu.insertTitle(i18n("Documentation")); + menu.insertItem(i18n("Open in Current Tab"), 1); + menu.insertItem(i18n("Open in New Tab"), 2); + if (showBookmark) + { + menu.insertSeparator(); + menu.insertItem(i18n("Bookmark This Location"), 3); + } + if (showSearch) + { + menu.insertSeparator(); + menu.insertItem(QString("%1: %2").arg(i18n("Search")).arg(KStringHandler::csqueeze(title,20)), 4); + } + + switch (menu.exec(pos)) + { + case 1: part->partController()->showDocument(url); break; + case 2: part->partController()->showDocument(url, true); break; + case 3: part->emitBookmarkLocation(title, url); break; + case 4: part->searchInDocumentation(title); break; + } +} diff --git a/parts/documentation/docutils.h b/parts/documentation/docutils.h new file mode 100644 index 00000000..75b52324 --- /dev/null +++ b/parts/documentation/docutils.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOC_UTILS_H +#define DOC_UTILS_H + +#include <qstring.h> + +class KURLRequester; +class KPopupMenu; +class DocumentationItem; +class DocumentationPart; +class QPoint; +class IndexItem; +class KURL; + +namespace DocUtils{ + +/**Returns an url selected in KURLRequester but does not +resolve environment variables.*/ +QString envURL(KURLRequester *req); +/**Resolves environment variables in url.*/ +QString noEnvURL(const QString &url); +/**Resolves environment variables in url.*/ +KURL noEnvURL(const KURL &url); + +void docItemPopup(DocumentationPart *part, DocumentationItem *docItem, const QPoint &pos, + bool showBookmark = false, bool showSearch = false, int titleCol = 0); +void docItemPopup(DocumentationPart *part, IndexItem *docItem, const QPoint &pos, + bool showBookmark = false, bool showSearch = false); +void docItemPopup(DocumentationPart *part, const QString &title, const KURL &url, + const QPoint &pos, bool showBookmark = false, bool showSearch = false); +} + +#endif diff --git a/parts/documentation/editbookmarkdlg.ui b/parts/documentation/editbookmarkdlg.ui new file mode 100644 index 00000000..fec2dc11 --- /dev/null +++ b/parts/documentation/editbookmarkdlg.ui @@ -0,0 +1,165 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>EditBookmarkDlg</class> +<widget class="QDialog"> + <property name="name"> + <cstring>EditBookmarkDlg</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>323</width> + <height>121</height> + </rect> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KURLRequester" row="1" column="1"> + <property name="name"> + <cstring>locationEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nameEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>&Location:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>locationEdit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>nameEdit</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </grid> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>EditBookmarkDlg</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>EditBookmarkDlg</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>nameEdit</tabstop> + <tabstop>locationEdit</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kpushbutton.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> +</includehints> +</UI> diff --git a/parts/documentation/editcatalogdlg.cpp b/parts/documentation/editcatalogdlg.cpp new file mode 100644 index 00000000..11f4c4fc --- /dev/null +++ b/parts/documentation/editcatalogdlg.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "editcatalogdlg.h" + +#include <qlabel.h> + +#include <klineedit.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> + +#include "docutils.h" +#include "kdevdocumentationplugin.h" + +EditCatalogDlg::EditCatalogDlg(DocumentationPlugin *plugin, QWidget* parent, + const char* name, bool modal, WFlags fl) + :EditCatalogBase(parent,name, modal,fl), m_plugin(plugin) +{ + if (m_plugin->hasCapability(DocumentationPlugin::CustomDocumentationTitles)) + { + titleLabel->setEnabled(true); + titleEdit->setEnabled(true); + } + locationURL->setMode(m_plugin->catalogLocatorProps().first); + locationURL->setFilter(m_plugin->catalogLocatorProps().second); +} + +EditCatalogDlg::~EditCatalogDlg() +{ +} + +/*$SPECIALIZATION$*/ +void EditCatalogDlg::locationURLChanged(const QString &text) +{ + titleEdit->setText(m_plugin->catalogTitle(DocUtils::noEnvURL(text))); +} + +void EditCatalogDlg::accept() +{ + QDialog::accept(); +} + +QString EditCatalogDlg::title() const +{ + return titleEdit->text(); +} + +QString EditCatalogDlg::url() const +{ + return DocUtils::envURL(locationURL); +} + +void EditCatalogDlg::setTitle(const QString &title) +{ + titleEdit->setText(title); +} + +void EditCatalogDlg::setURL(const QString &url) +{ + locationURL->setURL(url); +} + +#include "editcatalogdlg.moc" diff --git a/parts/documentation/editcatalogdlg.h b/parts/documentation/editcatalogdlg.h new file mode 100644 index 00000000..5628fa99 --- /dev/null +++ b/parts/documentation/editcatalogdlg.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef EDITCATALOGDLG_H +#define EDITCATALOGDLG_H + +#include "editcatalogdlgbase.h" + +class DocumentationPlugin; + +class EditCatalogDlg : public EditCatalogBase +{ + Q_OBJECT +public: + EditCatalogDlg(DocumentationPlugin *plugin, + QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0); + ~EditCatalogDlg(); + /*$PUBLIC_FUNCTIONS$*/ + + QString title() const; + void setTitle(const QString &title); + QString url() const; + void setURL(const QString &url); + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void locationURLChanged(const QString &text); + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void accept(); + +private: + DocumentationPlugin *m_plugin; +}; + +#endif diff --git a/parts/documentation/editcatalogdlgbase.ui b/parts/documentation/editcatalogdlgbase.ui new file mode 100644 index 00000000..3fd4caf9 --- /dev/null +++ b/parts/documentation/editcatalogdlgbase.ui @@ -0,0 +1,196 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>EditCatalogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>EditCatalogBase</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>404</width> + <height>163</height> + </rect> + </property> + <property name="caption"> + <string>Documentation Catalog Properties</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="4" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>&Location:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>locationURL</cstring> + </property> + </widget> + <widget class="KURLRequester" row="1" column="0"> + <property name="name"> + <cstring>locationURL</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>titleLabel</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Title:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>titleEdit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="0"> + <property name="name"> + <cstring>titleEdit</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>EditCatalogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>EditCatalogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>locationURL</sender> + <signal>textChanged(const QString&)</signal> + <receiver>EditCatalogBase</receiver> + <slot>locationURLChanged(const QString&)</slot> + </connection> +</connections> +<tabstops> + <tabstop>locationURL</tabstop> + <tabstop>titleEdit</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot>locationURLChanged( const QString & )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kpushbutton.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> +</includehints> +</UI> diff --git a/parts/documentation/find_documentation.cpp b/parts/documentation/find_documentation.cpp new file mode 100644 index 00000000..6195536e --- /dev/null +++ b/parts/documentation/find_documentation.cpp @@ -0,0 +1,347 @@ +/*************************************************************************** + * Copyright (C) 2004 by Tobias Glaesser * + * tobi.web@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "find_documentation.h" + +#include <stdlib.h> +#include <qcheckbox.h> +#include <qheader.h> +#include <qapplication.h> +#include <qstringlist.h> + +#include <klineedit.h> +#include <kprocess.h> +#include <klistbox.h> + +#include <kdevpartcontroller.h> +#include <kdevdocumentationplugin.h> + +#include "documentation_widget.h" +#include "documentation_part.h" +#include "indexview.h" +#include "find_documentation_options.h" +#include "docutils.h" +#include "contentsview.h" + +#include <klocale.h> + +FindDocumentation::FindDocumentation(DocumentationWidget* parent, const char* name) + :FindDocumentationBase(parent, name), + man_item(0), info_item(0), index_item(0), google_item(0), contents_item(0), + last_item(0), m_widget(parent) +{ + QWidget* tmp = QApplication::desktop(); + setGeometry(tmp->width()/2 - width()/2, tmp->height()/2 - height()/2, width(), height()); + proc_man = new KProcess( this ); + proc_info = new KProcess( this ); + + connect( proc_man, SIGNAL(processExited( KProcess* )), + this, SLOT(procManExited( KProcess* )) ); + connect( proc_man, SIGNAL(receivedStdout( KProcess*, char*, int)), + this, SLOT(procManReadStdout( KProcess*, char*, int)) ); + + connect( proc_info, SIGNAL(processExited( KProcess* )), + this, SLOT(procInfoExited( KProcess* )) ); + connect( proc_info, SIGNAL(receivedStdout( KProcess*, char*, int)), + this, SLOT(procInfoReadStdout( KProcess*, char*, int)) ); + + result_list->header()->hide(); + result_list->setSorting(-1); + + m_options = new FindDocumentationOptions(this); +} + +FindDocumentation::~FindDocumentation() +{ +} + +/*$SPECIALIZATION$*/ +void FindDocumentation::buttonPressedOnItem( int button, QListViewItem * item, const QPoint & pos, int // c + ) +{ + if ((button != Qt::RightButton) || (!item)) + return; + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(item); + if (!docItem) + return; + + DocUtils::docItemPopup(m_widget->part(), docItem->text(0), docItem->url(), pos, true, false); +} + +void FindDocumentation::clickOnItem( QListViewItem * item ) +{ + if(!item) + return; + + if(item == man_item || item == info_item || item == index_item || item == google_item) + return; + + DocumentationItem* doc_item = dynamic_cast<DocumentationItem*>(item); + + if(item->parent() == man_item || + item->parent() == info_item || + item->parent() == google_item || + item->parent() == index_item || + item->parent() == contents_item) + m_widget->part()->partController()->showDocument(doc_item->url()); +} + +void FindDocumentation::procInfoExited( KProcess* ) +{ + if (proc_info->normalExit() && proc_info->exitStatus() == 0) + { + QStringList lines = QStringList::split("\n", proc_info_out); + for( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it ) + { + if( (*it) == "*") + break; + + DocumentationItem* newitem = new DocumentationItem(DocumentationItem::Document, info_item, *it); + newitem->setURL(KURL("info:/" + search_term->text())); + } + } + proc_info_out = ""; + + if(info_item->firstChild() && m_options->goto_first_match->isOn()) + { + m_widget->part()->partController()->showDocument(dynamic_cast<DocumentationItem*>(info_item->firstChild())->url()); + first_match_found = true; + } +} + +void FindDocumentation::procManExited( KProcess* ) +{ + if (proc_man->normalExit() && proc_man->exitStatus() == 0) + { + QStringList lines = QStringList::split("\n", proc_man_out); + for( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it ) + { + DocumentationItem* newitem = new DocumentationItem(DocumentationItem::Document, man_item, search_term->text()); + newitem->setURL(KURL("man://" + *it)); + } + } + proc_man_out = ""; + + if(man_item->firstChild() && m_options->goto_first_match->isOn()) + { + m_widget->part()->partController()->showDocument(dynamic_cast<DocumentationItem*>(man_item->firstChild())->url()); + first_match_found = true; + } +} + +void FindDocumentation::procInfoReadStdout( KProcess*, char* buf, int len) +{ + proc_info_out += QString::fromLatin1( buf, len ); +} + +void FindDocumentation::procManReadStdout( KProcess*, char* buf, int len) +{ + proc_man_out += QString::fromLatin1( buf, len ); +} + +void FindDocumentation::searchInInfo() +{ + info_item = new KListViewItem(result_list, last_item, "Info"); + info_item->setOpen(true); + last_item = info_item; + + proc_info->clearArguments(); + //Search Info documents + *proc_info << "info"; + *proc_info << "-w"; + *proc_info << search_term->text(); + + if ( !proc_info->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) + { + // error handling + } +} + +void FindDocumentation::searchInMan() +{ + man_item = new KListViewItem( result_list, last_item, i18n("Manual") ); + man_item->setOpen(true); + last_item = man_item; + + proc_man->clearArguments(); + //Search Manpages + *proc_man << "man"; + *proc_man << "-w"; + *proc_man << search_term->text(); + + if ( !proc_man->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) + { + // error handling + } + +} + +void FindDocumentation::searchInGoogle() +{ + google_item = new KListViewItem(result_list, last_item, "Google"); + google_item->setOpen(true); + last_item = google_item; + + DocumentationItem* newitem = new DocumentationItem(DocumentationItem::Document, + google_item, "First result for: " + search_term->text()); + newitem->setURL(KURL("http://www.google.com/search?q=" + search_term->text() + "&btnI")); + newitem = new DocumentationItem(DocumentationItem::Document, google_item, "All results for: " + search_term->text()); + newitem->setURL(KURL("http://www.google.com/search?q=" + search_term->text())); + + if (google_item->firstChild() && m_options->goto_first_match->isOn()) + { + m_widget->part()->partController()->showDocument(dynamic_cast<DocumentationItem*>(google_item->firstChild())->url()); + first_match_found = true; + } +} + +void FindDocumentation::searchInContents() +{ + contents_item = new KListViewItem( result_list, last_item, i18n("Contents") ); + contents_item->setOpen(true); + last_item = contents_item; + + QListViewItemIterator it( m_widget->m_contents->m_view ); + while ( it.current() ) + { + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(it.current()); + + if (docItem->type() == DocumentationItem::Catalog) + { + DocumentationCatalogItem *catalogItem = dynamic_cast<DocumentationCatalogItem*>(it.current()); + catalogItem->load(); + catalogItem->plugin()->setCatalogURL(catalogItem); + } + if (it.current()->text(0).contains(search_term->text(),false)) + { + DocumentationItem* newitem = new DocumentationItem(DocumentationItem::Document, + contents_item, it.current()->text(0) ); + newitem->setURL(docItem->url()); + } + ++it; + } + + if (contents_item->firstChild() && m_options->goto_first_match->isOn()) + { + m_widget->part()->partController()->showDocument(dynamic_cast<DocumentationItem*>(contents_item->firstChild())->url()); + first_match_found = true; + } +} + +void FindDocumentation::searchInIndex() +{ + index_item =new KListViewItem(result_list, last_item , "Index"); + index_item->setOpen(true); + last_item = index_item; + + m_widget->part()->emitIndexSelected(m_widget->m_index->indexBox()); + m_widget->m_index->setSearchTerm(search_term->text()); + m_widget->m_index->showIndex(search_term->text()); + + if(m_widget->m_index->m_index->selectedItem()) + { + IndexItem* item = dynamic_cast<IndexItem*>(m_widget->m_index->m_index->selectedItem()); + DocumentationItem* newitem = 0; + while(item) + { + if(!item->text().contains(search_term->text(),false)) + break; + + IndexItem::List urls = item->urls(); + for (IndexItem::List::const_iterator it = urls.begin(); it != urls.end(); ++it) + { + QString text = item->text(); + if (urls.count() > 1) + text = (*it).first; + if(newitem) + newitem = new DocumentationItem(DocumentationItem::Document, index_item, + newitem, text); + else + newitem = new DocumentationItem(DocumentationItem::Document, + index_item, text); + + newitem->setURL((*it).second); + } + + item = dynamic_cast<IndexItem*>(item->next()); + } + } + + if(index_item->firstChild() && m_options->goto_first_match->isOn()) + { + m_widget->part()->partController()->showDocument( + dynamic_cast<DocumentationItem*>(index_item->firstChild())->url()); + first_match_found = true; + } +} + +void FindDocumentation::startSearch() +{ + //Clear the contents of the listview + result_list->clear(); + + last_item = NULL; + first_match_found = false; + + QListViewItem* item = m_options->source_list->firstChild(); + + while ( item && ( !m_options->goto_first_match->isOn() || !first_match_found )) + { + if ( m_options->isMan(dynamic_cast<QCheckListItem*>(item)) ) + searchInMan(); + else if ( m_options->isInfo(dynamic_cast<QCheckListItem*>(item)) ) + searchInInfo(); + else if ( m_options->isIndex(dynamic_cast<QCheckListItem*>(item)) ) + searchInIndex(); + else if ( m_options->isGoogle(dynamic_cast<QCheckListItem*>(item)) ) + searchInGoogle(); + else if ( m_options->isContents(dynamic_cast<QCheckListItem*>(item)) ) + searchInContents(); + + item = item->itemBelow(); + } + + //Set the focus to the listview and the first child to the + //current item of the list, so that you can brows the items with your keyboard + result_list->setFocus(); + if(result_list->firstChild()) + result_list->setCurrentItem(result_list->firstChild()); + +} + +void FindDocumentation::setSearchTerm( const QString & term ) +{ + search_term->setText(term); +} + +void FindDocumentation::clickOptions() +{ + if( m_options->exec() == QDialog::Accepted ) + m_options->writeOptions(); + else + m_options->readOptions(); +} + +void FindDocumentation::focusInEvent( QFocusEvent * // e + ) +{ + search_term->setFocus(); +} + +#include "find_documentation.moc" diff --git a/parts/documentation/find_documentation.h b/parts/documentation/find_documentation.h new file mode 100644 index 00000000..26afa5be --- /dev/null +++ b/parts/documentation/find_documentation.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2004 by Tobias Glaesser * + * tobi.web@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef FINDDOCUMENTATION_H +#define FINDDOCUMENTATION_H + +#include "find_documentationbase.h" + +class DocumentationWidget; +class KListViewItem; +class FindDocumentationOptions; +class KProcess; + +class FindDocumentation : public FindDocumentationBase +{ +Q_OBJECT +public: + FindDocumentation(DocumentationWidget* parent, const char* name = 0); + ~FindDocumentation(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void buttonPressedOnItem( int button, QListViewItem * item, const QPoint & pos, int c ); + virtual void clickOnItem( QListViewItem * item ); + virtual void procInfoExited( KProcess* ); + virtual void procManExited( KProcess* ); + virtual void procManReadStdout( KProcess*, char*, int ); + virtual void procInfoReadStdout( KProcess*, char*, int ); + virtual void searchInInfo(); + virtual void searchInMan(); + virtual void searchInGoogle(); + virtual void searchInContents(); + virtual void searchInIndex(); + virtual void startSearch(); + virtual void setSearchTerm( const QString & term ); + virtual void clickOptions(); + +protected: + /*$PROTECTED_FUNCTIONS$*/ + virtual void focusInEvent(QFocusEvent *e); + +protected slots: + /*$PROTECTED_SLOTS$*/ + +private: + KProcess* proc_man; + KProcess* proc_info; + QString proc_man_out; + QString proc_info_out; + KListViewItem* man_item; + KListViewItem* info_item; + KListViewItem* index_item; + KListViewItem* google_item; + KListViewItem* contents_item; + KListViewItem* last_item; + DocumentationWidget* m_widget; + FindDocumentationOptions* m_options; + bool first_match_found; + +}; + +#endif + diff --git a/parts/documentation/find_documentation_options.cpp b/parts/documentation/find_documentation_options.cpp new file mode 100644 index 00000000..ba3ab46f --- /dev/null +++ b/parts/documentation/find_documentation_options.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2004 by Tobias Glaesser * + * tobi.web@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "find_documentation_options.h" + +#include <qheader.h> +#include <qcheckbox.h> + +#include <klistview.h> +#include <klocale.h> + +#include <kconfig.h> +#include <kapplication.h> + +FindDocumentationOptions::FindDocumentationOptions(QWidget* parent, const char* name, bool modal) + :FindDocumentationOptionsBase(parent,name, modal), + m_man_item(0), m_info_item(0), m_index_item(0), m_google_item(0), m_contents_item(0) +{ + readOptions(); + + source_list->header()->hide(); + source_list->setSorting(-1); +} + +FindDocumentationOptions::~FindDocumentationOptions() +{ +} + +/*$SPECIALIZATION$*/ +bool FindDocumentationOptions::isContents( QCheckListItem * item ) +{ + if ( item == m_contents_item && m_contents_item->isOn() ) + return true; + else + return false; +} + +bool FindDocumentationOptions::isGoogle( QCheckListItem * item ) +{ + if ( item == m_google_item && m_google_item->isOn() ) + return true; + else + return false; +} + +bool FindDocumentationOptions::isIndex( QCheckListItem * item ) +{ + if ( item == m_index_item && m_index_item->isOn() ) + return true; + else + return false; +} + +bool FindDocumentationOptions::isInfo( QCheckListItem * item ) +{ + if ( item == m_info_item && m_info_item->isOn() ) + return true; + else + return false; +} + +bool FindDocumentationOptions::isMan( QCheckListItem * item ) +{ + if ( item == m_man_item && m_man_item->isOn() ) + return true; + else + return false; +} + +void FindDocumentationOptions::sourceMoveDown() +{ + if (!source_list->currentItem()) + return; + if (source_list->currentItem()->nextSibling() == 0) + return; + + source_list->currentItem()->moveItem(source_list->currentItem()->nextSibling()); +} + +void FindDocumentationOptions::sourceMoveUp() +{ + if (!source_list->currentItem()) + return; + if (source_list->currentItem() == source_list->firstChild()) + return; + + QListViewItem *item = source_list->firstChild(); + while (item->nextSibling() != source_list->currentItem()) + item = item->nextSibling(); + item->moveItem( source_list->currentItem()); +} + +void FindDocumentationOptions::writeOptions() +{ + config = kapp->config(); + config->setGroup("DocumentationFinder"); + + config->writeEntry("goto_first_match", goto_first_match->isChecked()); + + QListViewItemIterator it( source_list ); + int i = 0; + while ( it.current() ) + { + if ( it.current() == m_man_item ) + { + config->writeEntry("Manpage",i); + config->writeEntry("ManpageEnabled",m_man_item->isOn()); + } + else if ( it.current() == m_info_item ) + { + config->writeEntry("Info",i); + config->writeEntry("InfoEnabled",m_info_item->isOn()); + } + else if ( it.current() == m_index_item ) + { + config->writeEntry("Index",i); + config->writeEntry("IndexEnabled",m_index_item->isOn()); + } + else if ( it.current() == m_google_item ) + { + config->writeEntry("Google",i); + config->writeEntry("GoogleEnabled",m_google_item->isOn()); + } + else if ( it.current() == m_contents_item ) + { + config->writeEntry("Contents",i); + config->writeEntry("ContentsEnabled",m_contents_item->isOn()); + } + ++it; + ++i; + } + + config->sync(); +} + +void FindDocumentationOptions::readOptions() +{ + config = kapp->config(); + config->setGroup("DocumentationFinder"); + + source_list->clear(); + + for(int i = 4; i > -1; --i ) + { + if( config->readPropertyEntry( "Manpage" , 0 ) == i) + { + m_man_item = new QCheckListItem( source_list, i18n("Manual"), QCheckListItem::CheckBox ); + m_man_item->setOn(config->readBoolEntry( "ManpageEnabled" , true)); + } + if( config->readPropertyEntry( "Info" , 1 ) == i) + { + m_info_item = new QCheckListItem( source_list, i18n("Info"), QCheckListItem::CheckBox ); + m_info_item->setOn(config->readBoolEntry( "InfoEnabled" , true)); + } + if( config->readPropertyEntry( "Index" , 2 ) == i) + { + m_index_item = new QCheckListItem( source_list, i18n("Index"), QCheckListItem::CheckBox ); + m_index_item->setOn(config->readBoolEntry( "IndexEnabled" , true)); + } + if( config->readPropertyEntry( "Google" , 3 ) == i) + { + m_google_item = new QCheckListItem( source_list, i18n("Google"), QCheckListItem::CheckBox ); + m_google_item->setOn(config->readBoolEntry( "GoogleEnabled" , false)); + } + if( config->readPropertyEntry( "Contents" , 4 ) == i) + { + m_contents_item = new QCheckListItem( source_list, i18n("Contents"), QCheckListItem::CheckBox ); + m_contents_item->setOn(config->readBoolEntry( "ContentsEnabled" , false)); + } + } + + goto_first_match->setChecked(config->readBoolEntry( "goto_first_match" , false)); +} + +#include "find_documentation_options.moc" + diff --git a/parts/documentation/find_documentation_options.h b/parts/documentation/find_documentation_options.h new file mode 100644 index 00000000..e2c24f9c --- /dev/null +++ b/parts/documentation/find_documentation_options.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2004 by Tobias Glaesser * + * tobi.web@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef FIND_DOCUMENTATIONOPTIONS_H +#define FIND_DOCUMENTATIONOPTIONS_H + +#include "find_documentation_optionsbase.h" + +class QCheckListItem; +class KConfig; + +class FindDocumentationOptions : public FindDocumentationOptionsBase +{ +Q_OBJECT +public: + FindDocumentationOptions(QWidget* parent = 0, const char* name = 0, bool modal = FALSE); + ~FindDocumentationOptions(); + /*$PUBLIC_FUNCTIONS$*/ + virtual bool isContents( QCheckListItem * item ); + virtual bool isGoogle( QCheckListItem * item ); + virtual bool isIndex( QCheckListItem * item ); + virtual bool isInfo( QCheckListItem * item ); + virtual bool isMan( QCheckListItem * item ); + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void sourceMoveDown(); + virtual void sourceMoveUp(); + virtual void writeOptions(); + virtual void readOptions(); + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +private: + QCheckListItem *m_man_item; + QCheckListItem *m_info_item; + QCheckListItem *m_index_item; + QCheckListItem *m_google_item; + QCheckListItem *m_contents_item; + + KConfig* config; +}; + +#endif + diff --git a/parts/documentation/find_documentation_optionsbase.ui b/parts/documentation/find_documentation_optionsbase.ui new file mode 100644 index 00000000..c2beadc9 --- /dev/null +++ b/parts/documentation/find_documentation_optionsbase.ui @@ -0,0 +1,218 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>FindDocumentationOptionsBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>FindDocumentationOptionsBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>349</width> + <height>310</height> + </rect> + </property> + <property name="caption"> + <string>Find Documentation Options</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView" row="1" column="0"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>source_list</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout9_3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>moveup_button</cstring> + </property> + <property name="text"> + <string>Move &Up</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>movedown_button</cstring> + </property> + <property name="text"> + <string>Move &Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>goto_first_match</cstring> + </property> + <property name="text"> + <string>Go to first match</string> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>You can enable and disable search +sources and change their priority here.</string> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>FindDocumentationOptionsBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>FindDocumentationOptionsBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>moveup_button</sender> + <signal>clicked()</signal> + <receiver>FindDocumentationOptionsBase</receiver> + <slot>sourceMoveUp()</slot> + </connection> + <connection> + <sender>movedown_button</sender> + <signal>clicked()</signal> + <receiver>FindDocumentationOptionsBase</receiver> + <slot>sourceMoveDown()</slot> + </connection> +</connections> +<slots> + <slot>sourceMoveUp()</slot> + <slot>sourceMoveDown()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/parts/documentation/find_documentationbase.ui b/parts/documentation/find_documentationbase.ui new file mode 100644 index 00000000..58e6aeb0 --- /dev/null +++ b/parts/documentation/find_documentationbase.ui @@ -0,0 +1,167 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>FindDocumentationBase</class> +<author>Tobias Gläßer</author> +<widget class="QWidget"> + <property name="name"> + <cstring>FindDocumentationBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>222</width> + <height>504</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Find Documentation</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Search term:</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>button_search</cstring> + </property> + <property name="text"> + <string>Search</string> + </property> + <property name="default"> + <bool>false</bool> + </property> + </widget> + <widget class="KLineEdit" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>search_term</cstring> + </property> + </widget> + <widget class="QPushButton" row="3" column="0"> + <property name="name"> + <cstring>butten_options</cstring> + </property> + <property name="text"> + <string>Options</string> + </property> + </widget> + <spacer row="3" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>100</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KListView" row="2" column="0" rowspan="1" colspan="3"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>result_list</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>button_search</sender> + <signal>clicked()</signal> + <receiver>FindDocumentationBase</receiver> + <slot>startSearch()</slot> + </connection> + <connection> + <sender>result_list</sender> + <signal>executed(QListViewItem*)</signal> + <receiver>FindDocumentationBase</receiver> + <slot>clickOnItem(QListViewItem*)</slot> + </connection> + <connection> + <sender>butten_options</sender> + <signal>clicked()</signal> + <receiver>FindDocumentationBase</receiver> + <slot>clickOptions()</slot> + </connection> + <connection> + <sender>result_list</sender> + <signal>mouseButtonPressed(int,QListViewItem*,const QPoint&,int)</signal> + <receiver>FindDocumentationBase</receiver> + <slot>buttonPressedOnItem(int,QListViewItem*,const QPoint&,int)</slot> + </connection> + <connection> + <sender>search_term</sender> + <signal>returnPressed()</signal> + <receiver>FindDocumentationBase</receiver> + <slot>startSearch()</slot> + </connection> + <connection> + <sender>result_list</sender> + <signal>returnPressed(QListViewItem*)</signal> + <receiver>FindDocumentationBase</receiver> + <slot>clickOnItem(QListViewItem*)</slot> + </connection> +</connections> +<tabstops> + <tabstop>search_term</tabstop> + <tabstop>button_search</tabstop> + <tabstop>result_list</tabstop> + <tabstop>butten_options</tabstop> +</tabstops> +<slots> + <slot>clickOptions()</slot> + <slot>setSearchTerm( const QString & term )</slot> + <slot>startSearch()</slot> + <slot>searchInIndex()</slot> + <slot>searchInContents()</slot> + <slot>searchInGoogle()</slot> + <slot>searchInMan()</slot> + <slot>searchInInfo()</slot> + <slot>procManReadFromStdout()</slot> + <slot>procInfoReadFromStdout()</slot> + <slot>clickOnItem( QListViewItem * item )</slot> + <slot>buttonPressedOnItem( int button, QListViewItem * item, const QPoint & pos, int c )</slot> +</slots> +<layoutdefaults spacing="1" margin="1"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/parts/documentation/indexview.cpp b/parts/documentation/indexview.cpp new file mode 100644 index 00000000..3c245aee --- /dev/null +++ b/parts/documentation/indexview.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "indexview.h" + +#include <qapplication.h> +#include <qevent.h> +#include <qlayout.h> +#include <qlabel.h> + +#include <klineedit.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kurl.h> +#include <kdebug.h> + +#include <kdevpartcontroller.h> +#include <kdevdocumentationplugin.h> + +#include "docutils.h" +#include "selecttopic.h" +#include "documentation_part.h" +#include "documentation_widget.h" + +IndexView::IndexView(DocumentationWidget *parent, const char *name) + :QWidget(parent, name), m_widget(parent) +{ + QVBoxLayout *l = new QVBoxLayout(this, 0, 0); + + QHBoxLayout *hl = new QHBoxLayout(this, 0, 0); + m_edit = new KLineEdit(this); + hl->addWidget(new QLabel(m_edit, i18n("&Look for:"), this)); + hl->addWidget(m_edit); + l->addLayout(hl); + + m_index = new IndexBox(this); + l->addWidget(m_index); + + connect(m_index, SIGNAL(executed(QListBoxItem* )), this, SLOT(searchInIndex(QListBoxItem* ))); + connect(m_index, SIGNAL(mouseButtonPressed(int, QListBoxItem*, const QPoint& )), + this, SLOT(itemMouseButtonPressed(int, QListBoxItem*, const QPoint& ))); + connect(m_edit, SIGNAL(returnPressed()), this, SLOT(searchInIndex())); + connect(m_edit, SIGNAL(textChanged(const QString&)), this, SLOT(showIndex(const QString&))); + + m_edit->installEventFilter(this); +} + +IndexView::~IndexView() +{ +} + +void IndexView::searchInIndex() +{ + if (m_index->currentItem() != -1) + searchInIndex(m_index->item(m_index->currentItem())); +} + +void IndexView::searchInIndex(QListBoxItem *item) +{ + kdDebug() << "IndexView::searchInIndex" << endl; + IndexItem *indexItem = dynamic_cast<IndexItem*>(item); + if (!indexItem) + return; + + IndexItem::List urls = indexItem->urls(); + if (urls.count() == 1) + m_widget->part()->partController()->showDocument(urls.first().second); + else if (urls.count() == 0) ; + else + { + SelectTopic *dia = new SelectTopic(urls); + dia->topicLabel->setText(dia->topicLabel->text().arg(item->text())); + if (dia->exec()) + m_widget->part()->partController()->showDocument(dia->selectedURL()); + delete dia; + } +} + +void IndexView::showIndex(const QString &term) +{ + QListBoxItem *i = m_index->firstItem(); + QString sl = term.lower(); + while (i) + { + QString t = i->text(); + if ((t.length() >= sl.length()) && (i->text().left(term.length()).lower() == sl)) + { + m_index->setCurrentItem(i); + m_index->setTopItem(m_index->index(i)); + break; + } + i = i->next(); + } +/* + for (uint i = 0; i < m_index->count(); ++ i) + { + if (m_index->text(i).startsWith(term)) + { + m_index->setCurrentItem(i); + m_index->setTopItem(i); + } + }*/ +} + +bool IndexView::eventFilter(QObject *watched, QEvent *e) +{ + if (!watched || !e) + return true; + + if ((watched == m_edit) && (e->type() == QEvent::KeyPress)) + { + QKeyEvent *ke = (QKeyEvent*)e; + if (ke->key() == Key_Up) + { + int i = m_index->currentItem(); + if (--i >= 0) + { + m_index->setCurrentItem(i); + m_edit->blockSignals(true); + m_edit->setText(m_index->currentText()); + m_edit->blockSignals(false); + } + return true; + } else if (ke->key() == Key_Down) + { + int i = m_index->currentItem(); + if ( ++i < int(m_index->count()) ) + { + m_index->setCurrentItem(i); + m_edit->blockSignals(true); + m_edit->setText(m_index->currentText()); + m_edit->blockSignals(false); + } + return true; + } else if ((ke->key() == Key_Next) || (ke->key() == Key_Prior)) + { + QApplication::sendEvent(m_index, e); + m_edit->blockSignals(true); + m_edit->setText(m_index->currentText()); + m_edit->blockSignals(false); + } + } + + return QWidget::eventFilter(watched, e); +} + +void IndexView::itemMouseButtonPressed(int button, QListBoxItem *item, const QPoint &pos) +{ + if ((button != Qt::RightButton) || (!item)) + return; + IndexItem *docItem = dynamic_cast<IndexItem*>(item); + if (!docItem) + return; + + DocUtils::docItemPopup(m_widget->part(), docItem, pos, false, true); +} + +void IndexView::setSearchTerm(const QString &term) +{ + m_edit->setFocus(); + m_edit->setText(term); +} + +void IndexView::askSearchTerm( ) +{ + m_edit->setFocus(); +} + +void IndexView::focusInEvent(QFocusEvent */*e*/) +{ + m_edit->setFocus(); +} + +#include "indexview.moc" diff --git a/parts/documentation/indexview.h b/parts/documentation/indexview.h new file mode 100644 index 00000000..50ffa704 --- /dev/null +++ b/parts/documentation/indexview.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef INDEXVIEW_H +#define INDEXVIEW_H + +#include <qwidget.h> + +class IndexBox; +class KLineEdit; +class QListBoxItem; +class DocumentationWidget; +class FindDocumentation; + +class IndexView : public QWidget +{ + Q_OBJECT +public: + IndexView(DocumentationWidget *parent = 0, const char *name = 0); + ~IndexView(); + + virtual bool eventFilter(QObject *watched, QEvent *e); + IndexBox *indexBox() const { return m_index; } + +public slots: + void searchInIndex(); + void setSearchTerm(const QString &term); + void askSearchTerm(); + +protected slots: + void searchInIndex(QListBoxItem *item); + void showIndex(const QString &term); + + void itemMouseButtonPressed(int button, QListBoxItem *item, const QPoint &pos); + +protected: + virtual void focusInEvent(QFocusEvent *e); + +private: + DocumentationWidget *m_widget; + + IndexBox *m_index; + KLineEdit *m_edit; + +friend class FindDocumentation; +}; + +#endif diff --git a/parts/documentation/interfaces/Mainpage.dox b/parts/documentation/interfaces/Mainpage.dox new file mode 100644 index 00000000..85126a6e --- /dev/null +++ b/parts/documentation/interfaces/Mainpage.dox @@ -0,0 +1,10 @@ +/** +@mainpage The KDevelop Documentation Part Interfaces Library + +This library contains interfaces to implement KDevelop documentation plugins. + +<b>Link with</b>: -ldocumentation_interfaces + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/parts/documentation +*/ + diff --git a/parts/documentation/interfaces/Makefile.am b/parts/documentation/interfaces/Makefile.am new file mode 100644 index 00000000..206f62f9 --- /dev/null +++ b/parts/documentation/interfaces/Makefile.am @@ -0,0 +1,16 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + $(all_includes) +METASOURCES = AUTO +partincludedirdir = $(includedir)/kdevelop/parts/documentation +lib_LTLIBRARIES = libdocumentation_interfaces.la +libdocumentation_interfaces_la_LDFLAGS = $(all_libraries) +libdocumentation_interfaces_la_LIBADD = $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) +libdocumentation_interfaces_la_SOURCES = kdevdocumentationplugin.cpp +partincludedir_HEADERS = kdevdocumentationplugin.h +servicetypedir = $(kde_servicetypesdir) +servicetype_DATA = kdevelopdocumentationplugins.desktop + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevutil kdevinterfaces +DOXYGEN_PROJECTNAME = KDevelop Documentation Part Interfaces Library +DOXYGEN_DOCDIRPREFIX = kdevdoc +include ../../../Doxyfile.am diff --git a/parts/documentation/interfaces/kdevdocumentationplugin.cpp b/parts/documentation/interfaces/kdevdocumentationplugin.cpp new file mode 100644 index 00000000..8e336c83 --- /dev/null +++ b/parts/documentation/interfaces/kdevdocumentationplugin.cpp @@ -0,0 +1,721 @@ +/* This file is part of the KDE project + Copyright (C) 2004 by Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "kdevdocumentationplugin.h" + +#include <qfile.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qheader.h> +#include <qtextstream.h> + +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdirwatch.h> +#include <klocale.h> + +//class DocumentationItem + +DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListView *parent, + const QString &name) + :KListViewItem(parent, name), m_type(type) +{ + init(); +} + +DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListViewItem *parent, + const QString &name) + :KListViewItem(parent, name), m_type(type) +{ + init(); +} + +DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListView *parent, + KListViewItem *after, const QString &name) + :KListViewItem(parent, after, name), m_type(type) +{ + init(); +} + +DocumentationItem::DocumentationItem(DocumentationItem::Type type, KListViewItem * parent, + KListViewItem * after, const QString & name ) + :KListViewItem(parent, after, name), m_type(type) +{ + init(); +} + + +void DocumentationItem::init( ) +{ + QString icon; + + switch (m_type) + { + case Collection: + case Catalog: + icon = "folder"; + break; + case Book: + icon = "contents"; + break; + default: + icon = "document"; + } + + setPixmap(0, SmallIcon(icon)); +} + + + + + +//class DocumentationCatalogItem + + +DocumentationCatalogItem::DocumentationCatalogItem(DocumentationPlugin* plugin, + KListView *parent, const QString &name) + :DocumentationItem(DocumentationItem::Catalog, parent, name), m_plugin(plugin), + isLoaded(false), isActivated(false), m_isProjectDocumentationItem(false) +{ + setExpandable(true); + m_plugin->addCatalog(this); +} + +DocumentationCatalogItem::DocumentationCatalogItem(DocumentationPlugin* plugin, + DocumentationItem *parent, const QString &name) + :DocumentationItem(DocumentationItem::Catalog, parent, name), m_plugin(plugin), + isLoaded(false), isActivated(false), m_isProjectDocumentationItem(false) +{ + setExpandable(true); + m_plugin->addCatalog(this); +} + +DocumentationCatalogItem::~ DocumentationCatalogItem( ) +{ + m_plugin->clearCatalog(this); +} + +void DocumentationCatalogItem::setOpen(bool o) +{ + if (o) + { + load(); + } + DocumentationItem::setOpen(o); +} + +void DocumentationCatalogItem::load() +{ +if(isLoaded) +return; + + plugin()->createTOC(this); + isLoaded = true; +} + +void DocumentationCatalogItem::activate() +{ + if (!isActivated) + { + plugin()->setCatalogURL(this); + isActivated = true; + } + DocumentationItem::activate(); +} + + + + +//class IndexItemProto + +IndexItemProto::IndexItemProto(DocumentationPlugin *plugin, DocumentationCatalogItem *catalog, + IndexBox *listbox, const QString &text, const QString &description) + : m_listbox(listbox), m_text(text), m_description(description) +{ + plugin->indexes[catalog].append(this); + m_listbox->addIndexItem(this); +} + +IndexItemProto::~IndexItemProto() +{ + m_listbox->removeIndexItem(this); +} + + +//class IndexItem + +IndexItem::IndexItem(IndexBox *listbox, const QString &text) + :QListBoxText(listbox, text), m_listbox(listbox) +{ +} + +IndexItem::List IndexItem::urls() const +{ + List urlList; + QValueList<IndexItemProto*> itemProtos = m_listbox->items[text()]; + for (QValueList<IndexItemProto*>::const_iterator it = itemProtos.begin(); + it != itemProtos.end(); ++it) + urlList.append(qMakePair((*it)->description(), (*it)->url())); + return urlList; +} + + + + +//class ConfigurationItem + +ConfigurationItem::ConfigurationItem(QListView *parent, DocumentationPlugin * plugin, const QString &title, const QString &url, + bool indexPossible, bool fullTextSearchPossible) + :QCheckListItem(parent, "", QCheckListItem::CheckBox), m_title(title), m_url(url), + m_origTitle(title), m_contents(true), m_index(false), m_fullTextSearch(false), + m_indexPossible(indexPossible), m_fullTextSearchPossible(fullTextSearchPossible), + m_docPlugin( plugin ) +{ + setText(3, m_title); + setText(4, m_url); +} + +void ConfigurationItem::paintCell(QPainter *p, const QColorGroup &cg, int column, + int width, int align) +{ + if ( (column == 0) || (column == 1) || (column == 2) ) + { + if ( !p ) + return; + + QListView *lv = listView(); + if ( !lv ) + return; + + const BackgroundMode bgmode = lv->viewport()->backgroundMode(); + const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); + p->fillRect(0, 0, width, height(), cg.brush(crole)); + + QFontMetrics fm(lv->fontMetrics()); + int boxsize = lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv); + int marg = lv->itemMargin(); + int styleflags = QStyle::Style_Default; + + if (((column == 0) && m_contents) || ((column == 1) && m_index) || ((column == 2) && m_fullTextSearch)) + styleflags |= QStyle::Style_On; + else + styleflags |= QStyle::Style_Off; + if ((column == 0) || ((column == 1) && m_indexPossible) || ((column == 2) && m_fullTextSearchPossible)) + styleflags |= QStyle::Style_Enabled; + + int x = 0; + int y = 0; + x += 3; + if (align & AlignVCenter) + y = ((height() - boxsize) / 2) + marg; + else + y = (fm.height() + 2 + marg - boxsize) / 2; + + QStyleOption opt(this); + lv->style().drawPrimitive(QStyle::PE_CheckListIndicator, p, + QRect(x, y, boxsize, fm.height() + 2 + marg), cg, styleflags, opt); + + return; + } + QListViewItem::paintCell(p, cg, column, width, align); +} + +int ConfigurationItem::width(const QFontMetrics &fm, const QListView *lv, int c) const +{ + if ((c == 0) || (c == 1) || (c == 2)) + return lv->style().pixelMetric(QStyle::PM_CheckListButtonSize, lv) + 4; + return QListViewItem::width(fm, lv, c); +} + + + + + + + + +//class DocumentationPlugin + +DocumentationPlugin::DocumentationPlugin(KConfig *pluginConfig, QObject *parent, const char *name) + :QObject(parent, name), config(pluginConfig), m_indexCreated(false) +{ +} + +DocumentationPlugin::~DocumentationPlugin() +{ +} + +void DocumentationPlugin::autoSetup() +{ + config->setGroup("General"); + if ( ! config->readBoolEntry("Autosetup", false) ) + { + autoSetupPlugin(); + config->setGroup("General"); + config->writeEntry("Autosetup", true); + config->sync(); + } +} + +void DocumentationPlugin::reload() +{ + clear(); + for (QValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin(); + it != catalogs.end(); ++it) + { + createTOC(*it); + } +} + +void DocumentationPlugin::clear() +{ + for (QValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin(); + it != catalogs.end(); ++it) + { + clearCatalog(*it); + } +} + +void DocumentationPlugin::clearCatalog(DocumentationCatalogItem *item) +{ + //clear named catalog map + for (QMap<QString, DocumentationCatalogItem*>::iterator it = namedCatalogs.begin(); + it != namedCatalogs.end(); ++it) + { + if (it.data() == item) + { + namedCatalogs.remove(it); + break; + } + } + //clear indexes for catalog + QValueList<IndexItemProto *> idx = indexes[item]; + for (QValueList<IndexItemProto *>::iterator it = idx.begin(); it != idx.end(); ++it) + { + delete *it; + } + indexes.remove(item); + + //remove catalog + catalogs.remove(item); +} + +void DocumentationPlugin::createIndex(IndexBox *index) +{ + if (m_indexCreated) + return; + + for (QValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin(); + it != catalogs.end(); ++it) + { + loadIndex(index, *it); + } + m_indexCreated = true; +} + +void DocumentationPlugin::cacheIndex(DocumentationCatalogItem *item) +{ + kdDebug() << "Creating index cache for " << item->text(0) << endl; + + QString cacheName = locateLocal("data", QString("kdevdocumentation/index/cache_") + item->text(0)); + QFile cacheFile(cacheName); + if (!cacheFile.open(IO_WriteOnly)) + return; + + QTextStream str(&cacheFile); + str.setEncoding(QTextStream::Unicode); + str << CACHE_VERSION << endl; + + QValueList<IndexItemProto*> catalogIndexes = indexes[item]; + for (QValueList<IndexItemProto*>::const_iterator it = catalogIndexes.constBegin(); + it != catalogIndexes.constEnd(); ++it) + { + str << (*it)->text() << endl; + str << (*it)->description() << endl; + str << (*it)->url().url() << endl; + } + + cacheFile.close(); +} + +bool DocumentationPlugin::loadCachedIndex(IndexBox *index, DocumentationCatalogItem *item) +{ + QString cacheName = locateLocal("data", QString("kdevdocumentation/index/cache_") + item->cacheVersion() + item->text(0)); + QFile cacheFile(cacheName); + if (!cacheFile.open(IO_ReadOnly)) + return false; + + kdDebug() << "Using cached index for item: " << item->text(0) << endl; + + QTextStream str(&cacheFile); + str.setEncoding(QTextStream::Unicode); + QString cache = str.read(); + QStringList cacheList = QStringList::split("\n", cache, true); + QString ver = cacheList.first(); + if (ver != CACHE_VERSION) + { + kdDebug() << "Wrong cache version: " << ver << endl; + return false; + } + QStringList::const_iterator it = cacheList.begin(); + it++; + QString s[3]; int c = 0; + for (; it != cacheList.end(); ++it) + { + s[c] = *it; + if (c == 2) + { + IndexItemProto *ii = new IndexItemProto(this, item, index, s[0], s[1]); + ii->addURL(KURL(s[2])); + c = 0; + } + else c++; + } + cacheFile.close(); + + return true; +} + +void DocumentationPlugin::addCatalog(DocumentationCatalogItem *item) +{ + catalogs.append(item); + namedCatalogs[item->text(0)] = item; +// indexes[item] = QValueList<IndexItem*>(); +} + +void DocumentationPlugin::addCatalogConfiguration(KListView *configurationView, + const QString &title, const QString &url) +{ + new ConfigurationItem(configurationView, this, title, url, + hasCapability(Index), hasCapability(FullTextSearch)); +} + +void DocumentationPlugin::editCatalogConfiguration(ConfigurationItem *configurationItem, + const QString &title, const QString &url) +{ + configurationItem->setTitle(title); + configurationItem->setURL(url); +} + +void DocumentationPlugin::deleteCatalogConfiguration(const ConfigurationItem *const configurationItem) +{ + deletedConfigurationItems << configurationItem->title(); +} + +void DocumentationPlugin::clearCatalogIndex(DocumentationCatalogItem *item) +{ + //clear indexes for catalog + QValueList<IndexItemProto *> idx = indexes[item]; + for (QValueList<IndexItemProto *>::iterator it = idx.begin(); it != idx.end(); ++it) + { + delete *it; + } + indexes.remove(item); +} + +void DocumentationPlugin::loadIndex(IndexBox *index, DocumentationCatalogItem *item) +{ + if (!indexEnabled(item)) + return; + if (!needRefreshIndex(item) && loadCachedIndex(index, item)) + return; + createIndex(index, item); + cacheIndex(item); +} + +void DocumentationPlugin::init(KListView *contents) +{ + config->setGroup("Locations"); + QMap<QString, QString> entryMap = config->entryMap("Locations"); + + for (QMap<QString, QString>::const_iterator it = entryMap.begin(); + it != entryMap.end(); ++it) + { + if (catalogEnabled(it.key())) + createCatalog(contents, it.key(), config->readPathEntry(it.key())); + } +} + +void DocumentationPlugin::reinit(KListView *contents, IndexBox *index, QStringList restrictions) +{ + config->setGroup("Locations"); + QMap<QString, QString> entryMap = config->entryMap("Locations"); + + //remove deleted in configuration catalogs + for (QStringList::const_iterator it = deletedConfigurationItems.constBegin(); + it != deletedConfigurationItems.constEnd(); ++it) + { + if (namedCatalogs.contains(*it)) + delete namedCatalogs[*it]; + } + deletedConfigurationItems.clear(); + + //update configuration + for (QMap<QString, QString>::const_iterator it = entryMap.begin(); + it != entryMap.end(); ++it) + { + config->setGroup("Locations"); + if (restrictions.contains(it.key()) || (!catalogEnabled(it.key()))) + { + if (namedCatalogs.contains(it.key())) + delete namedCatalogs[it.key()]; + } + else + { + kdDebug() << "updating 1" << endl; + if (!namedCatalogs.contains(it.key())) //create catalog if it does not exist + { + DocumentationCatalogItem * item = createCatalog(contents, it.key(), config->readPathEntry(it.key())); + loadIndex(index, item); + index->setDirty(true); +// index->refill(indexes[item]); + } + else if (!indexEnabled(namedCatalogs[it.key()])) //clear index if it is disabled in configuration + { + kdDebug() << " updating: clearCatalogIndex" << endl; + clearCatalogIndex(namedCatalogs[it.key()]); + } + else if ( (indexEnabled(namedCatalogs[it.key()])) //index is requested in configuration but does not yet exist + && (!indexes.contains(namedCatalogs[it.key()])) ) + { + kdDebug() << " index requested " << endl; + loadIndex(index, namedCatalogs[it.key()]); + index->setDirty(true); + } + m_indexCreated = true; + } + } +} + +void DocumentationPlugin::loadCatalogConfiguration(KListView *configurationView) +{ + config->setGroup("Locations"); + QMap<QString, QString> entryMap = config->entryMap("Locations"); + + for (QMap<QString, QString>::const_iterator it = entryMap.begin(); + it != entryMap.end(); ++it) + { + if (namedCatalogs.contains(it.key()) + && namedCatalogs[it.key()]->isProjectDocumentationItem()) + continue; + + config->setGroup("Locations"); + ConfigurationItem *item = new ConfigurationItem(configurationView, this, it.key(), + config->readPathEntry(it.key()), + hasCapability(Index), hasCapability(FullTextSearch)); + config->setGroup("TOC Settings"); + item->setContents(config->readBoolEntry(item->title(), true)); + config->setGroup("Index Settings"); + item->setIndex(config->readBoolEntry(item->title(), false)); + config->setGroup("Search Settings"); + item->setFullTextSearch(config->readBoolEntry(item->title(), false)); + } +} + +void DocumentationPlugin::saveCatalogConfiguration(KListView *configurationView) +{ + config->setGroup("Locations"); + + for (QStringList::const_iterator it = deletedConfigurationItems.constBegin(); + it != deletedConfigurationItems.constEnd(); ++it) + { + config->deleteEntry(*it); + } + + QListViewItemIterator it(configurationView); + while (it.current()) + { + ConfigurationItem *confItem = dynamic_cast<ConfigurationItem*>(it.current()); + if ( confItem->docPlugin() != this ) + { + ++it; + continue; + } + + config->setGroup("Locations"); + if (confItem->isChanged()) + config->deleteEntry(confItem->origTitle()); + config->writePathEntry(confItem->title(), confItem->url()); + + config->setGroup("TOC Settings"); + if (confItem->isChanged()) + config->deleteEntry(confItem->origTitle()); + config->writeEntry(confItem->title(), confItem->contents()); + + config->setGroup("Index Settings"); + if (confItem->isChanged()) + config->deleteEntry(confItem->origTitle()); + config->writeEntry(confItem->title(), confItem->index()); + + config->setGroup("Search Settings"); + if (confItem->isChanged()) + config->deleteEntry(confItem->origTitle()); + config->writeEntry(confItem->title(), confItem->fullTextSearch()); + + ++it; + } + config->sync(); +} + +void DocumentationPlugin::setIndexEnabled( DocumentationCatalogItem * item, bool e ) +{ + QString group = config->group(); + config->setGroup("Index Settings"); + config->writeEntry(item->text(0), e); + config->setGroup(group); +} + +bool DocumentationPlugin::indexEnabled( DocumentationCatalogItem * item ) const +{ + QString group = config->group(); + config->setGroup("Index Settings"); + bool b = config->readBoolEntry(item->text(0), false); + config->setGroup(group); + return b; +} + +bool DocumentationPlugin::catalogEnabled(const QString &name) const +{ + QString group = config->group(); + config->setGroup("TOC Settings"); + bool b = config->readBoolEntry(name, true); + config->setGroup(group); + return b; +} + +void DocumentationPlugin::setCatalogEnabled(const QString &name, bool e) +{ + QString group = config->group(); + config->setGroup("TOC Settings"); + config->writeEntry(name, e); + config->setGroup(group); +} + + + + +//class IndexBox + +IndexBox::IndexBox(QWidget *parent, const char *name) + :KListBox(parent, name), m_dirty(false) +{ +} + +void IndexBox::addIndexItem(IndexItemProto *item) +{ + items[item->text()].append(item); +} + +void IndexBox::removeIndexItem(IndexItemProto *item) +{ + QString text = item->text(); + items[text].remove(item); + if (items[text].count() == 0) + { + items.remove(text); + QListBoxItem *item = findItem(text, Qt::CaseSensitive | Qt::ExactMatch); + if (item) + delete item; + } +} + +void IndexBox::fill() +{ + for (QMap<QString, QValueList<IndexItemProto*> >::const_iterator it = items.begin(); + it != items.end(); ++it) + { + new IndexItem(this, it.key()); + } +} + +void IndexBox::setDirty(bool dirty) +{ + m_dirty = dirty; +} + +void IndexBox::refill() +{ + if (m_dirty) + { + clear(); + fill(); + setDirty(false); + } +} + + +ProjectDocumentationPlugin::ProjectDocumentationPlugin(DocumentationPlugin *docPlugin, DocumentationPlugin::ProjectDocType type) + :QObject(0, 0), m_docPlugin(docPlugin), m_catalog(0), m_type(type), m_contents(0), m_index(0) +{ + kdDebug() << "ProjectDocumentationPlugin::ProjectDocumentationPlugin for type " << type << endl; + + m_watch = new KDirWatch(this); + connect(m_watch, SIGNAL(dirty(const QString&)), this, SLOT(reinit())); + m_watch->startScan(); +} + +ProjectDocumentationPlugin::~ProjectDocumentationPlugin() +{ + deinit(); +} + +void ProjectDocumentationPlugin::init(KListView *contents, IndexBox *index, const QString &url) +{ + m_contents = contents; + m_index = index; + m_url = url; + + if (m_catalog) + deinit(); + m_catalog = m_docPlugin->createCatalog(contents, + m_type == DocumentationPlugin::APIDocs ? i18n("Project API Documentation") + : i18n("Project User Manual"), url); + if (m_catalog) + { + m_catalog->setProjectDocumentationItem(true); + m_watch->addFile(url); + } +} + +void ProjectDocumentationPlugin::reinit() +{ + deinit(); + if (m_contents != 0 && m_index != 0 && m_url != 0) + init(m_contents, m_index, m_url); +} + +void ProjectDocumentationPlugin::deinit() +{ + m_watch->removeFile(m_url); + delete m_catalog; + m_catalog = 0; +} + +QString ProjectDocumentationPlugin::pluginName() const +{ + return m_docPlugin->pluginName(); +} + +QString ProjectDocumentationPlugin::catalogURL() const +{ + return m_url; +} + +#include "kdevdocumentationplugin.moc" diff --git a/parts/documentation/interfaces/kdevdocumentationplugin.h b/parts/documentation/interfaces/kdevdocumentationplugin.h new file mode 100644 index 00000000..5d100ab5 --- /dev/null +++ b/parts/documentation/interfaces/kdevdocumentationplugin.h @@ -0,0 +1,421 @@ +/* This file is part of the KDE project + Copyright (C) 2004 by Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KDEV_DOC_PLUGIN_H +#define KDEV_DOC_PLUGIN_H + +#include <qmap.h> +#include <qvaluelist.h> +#include <qpair.h> + +#include <klistbox.h> +#include <klistview.h> +#include <kurl.h> +#include <kfile.h> + +#define CACHE_VERSION "3" + +/**Documentation list item. +Stores the type of a documentation it represents and an URL.*/ +class DocumentationItem: public KListViewItem +{ +public: + /**Type of documentation which is represented by this item.*/ + enum Type { + Collection /**<Collection - a collection of catalogs, folder with catalogs.*/, + Catalog /**<Catalog - a term which defines a document or a group of documents.*/, + Book /**<Book - a document with nested documents.*/, + Document /**<Document.*/ + }; + + DocumentationItem(Type type, KListView *parent, const QString &name); + DocumentationItem(Type type, KListView *parent, KListViewItem *after, const QString &name); + DocumentationItem(Type type, KListViewItem *parent, const QString &name); + DocumentationItem(Type type, KListViewItem *parent, KListViewItem *after, const QString &name); + + virtual void setURL(const KURL &url) { m_url = url; } + virtual KURL url() const { return m_url; } + + Type type() const { return m_type; } + + void setType(Type t) { + if(t != m_type) { + m_type = t; + init(); + } + } +private: + void init(); + + KURL m_url; + Type m_type; +}; + +class DocumentationPlugin; + +/**Documentation catalog list item.*/ +class DocumentationCatalogItem: public DocumentationItem +{ +public: + DocumentationCatalogItem(DocumentationPlugin* plugin, KListView *parent, const QString &name); + DocumentationCatalogItem(DocumentationPlugin* plugin, DocumentationItem *parent, const QString &name); + virtual ~DocumentationCatalogItem(); + + DocumentationPlugin* plugin() const { return m_plugin; } + + virtual void setOpen(bool o); + void load(); + + virtual bool isProjectDocumentationItem() const { return m_isProjectDocumentationItem; } + virtual void setProjectDocumentationItem(bool b) { m_isProjectDocumentationItem = b; } + + virtual QString cacheVersion() const { return ""; } /// should return a short string that identifies the version of the catalog + +protected: + virtual void activate(); + +private: + DocumentationPlugin* m_plugin; + bool isLoaded; + bool isActivated; + bool m_isProjectDocumentationItem; +}; + +class IndexBox; + +/**Prototype of index item. +Prototypes represent an index are used to build index items after index generation.*/ +class IndexItemProto +{ +public: + IndexItemProto(DocumentationPlugin *plugin, DocumentationCatalogItem *catalog, IndexBox *listbox, + const QString &text, const QString &description); + ~IndexItemProto(); + + void addURL(const KURL &url) { m_url = url; } + KURL url() const { return m_url; } + QString text() const { return m_text; } + QString description() const { return m_description; } + +private: + KURL m_url; + IndexBox *m_listbox; + QString m_text; + QString m_description; +}; + +/**Documentation index item.*/ +class IndexItem: public QListBoxText { +public: + typedef QPair<QString, KURL> URL; + typedef QValueList<URL> List; + + IndexItem(IndexBox *listbox, const QString &text); + + List urls() const; + +private: + IndexBox *m_listbox; +}; + +/**Documentation index view.*/ +class IndexBox: public KListBox{ +public: + IndexBox(QWidget *parent = 0, const char *name = 0); + + virtual void addIndexItem(IndexItemProto *item); + virtual void removeIndexItem(IndexItemProto *item); + virtual void fill(); + virtual void refill(); + virtual void setDirty(bool dirty); +// virtual void refill(QValueList<IndexItemProto*> &items); + +private: + QMap<QString, QValueList<IndexItemProto*> > items; + friend class IndexItem; + + bool m_dirty; +}; + +class QPainter; +class QColorGroup; +class QFontMetrics; +class DocumentationPlugin; + +/**Documentation configuration item.*/ +class ConfigurationItem: public QCheckListItem +{ +public: + ConfigurationItem(QListView *parent, DocumentationPlugin * plugin, const QString &title, const QString &url, + bool indexPossible, bool fullTextSearchPossible); + + virtual QString title() const { return m_title; } + virtual void setTitle(const QString title) { setText(3, m_title = title); } + virtual QString url() const { return m_url; } + virtual void setURL(const QString url) { setText(4, m_url = url); } + + virtual bool isChanged() const { return m_title == m_origTitle; } + virtual QString origTitle() const {return m_origTitle; } + + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align); + virtual int width(const QFontMetrics &fm, const QListView *lv, int c) const; + + bool contents() const { return m_contents; } + void setContents(bool contents) { m_contents = contents; } + bool index() const { return m_index; } + void setIndex(bool index) { m_index = index; } + bool fullTextSearch() const { return m_fullTextSearch; } + void setFullTextSearch(bool fullTextSearch) { m_fullTextSearch = fullTextSearch; } + + bool indexPossible() const { return m_indexPossible; } + bool fullTextSearchPossible() const { return m_fullTextSearchPossible; } + + DocumentationPlugin * docPlugin() { return m_docPlugin; } + +private: + QString m_title; + QString m_url; + QString m_origTitle; + + bool m_contents; + bool m_index; + bool m_fullTextSearch; + + bool m_indexPossible; + bool m_fullTextSearchPossible; + + DocumentationPlugin * m_docPlugin; +}; + + +class ProjectDocumentationPlugin; + +/** +@short Documentation Plugin Interface + +All KDevelop documentation plugins must implement this interface. +Documentation plugin handles certain documentation type. It provides +methods to load documentation catalogs and indexes for a documentation +of that type. It also has methods to configure catalogs and provides +a list of URL's for the full text search tool. +*/ +class DocumentationPlugin: public QObject +{ + Q_OBJECT +public: + /**Capability of documentation plugin.*/ + enum Capability { Index=1 /**<index can be built for catalogs*/, + FullTextSearch=2 /**<full text search is possible in catalog locations*/, + CustomDocumentationTitles=4 /**<user can specify titles for documentation catalogs*/, + ProjectDocumentation=8 /**<plugin can handle project API documentation*/, + ProjectUserManual=16 /**<plugin can handle project user manual*/ }; + /**Possible project documentation types.*/ + enum ProjectDocType { APIDocs, UserManual }; + + /**Constructor. Should initialize capabilities of the plugin by using setCapabilities + protected method. For example, + @code + setCapabilities(Index | FullTextSearch); + @endcode + */ + DocumentationPlugin(KConfig *pluginConfig, QObject *parent =0, const char *name =0); + virtual ~DocumentationPlugin(); + + /**Returns the i18n name of the plugin.*/ + virtual QString pluginName() const = 0; + + /**Creates documentation catalog with given title and url.*/ + virtual DocumentationCatalogItem *createCatalog(KListView *contents, const QString &title, const QString &url) = 0; + + /**Initialize a list of catalogs. + @param contents the listview to fill with catalogs + */ + virtual void init(KListView *contents); + /**Reloads a list of catalogs. This method should add missing catalogs to the view, + update index for added catalogs and also delete restricted catalogs. + @param contents the listview to fill with catalogs + @param index the listbox with index to update + @param restrictions the list of catalogs names to remove + */ + virtual void reinit(KListView *contents, IndexBox *index, QStringList restrictions); + /**Initializes plugin configuration. Documentation plugins should be able to + initialize the default configuration on startup without any user interaction. + Call this in the constructor of your plugin.*/ + virtual void autoSetup(); + /**Plugin specific automatic setup code. This method is called by @ref autoSetup.*/ + virtual void autoSetupPlugin() = 0; + + /**Indicates if a catalog with specified name is enabled. Documentation plugin + should check this and do not load catalogs disabled in configuration. + All catalogs are enabled by default.*/ + virtual bool catalogEnabled(const QString &name) const; + /**Enables or disables documentation catalog.*/ + virtual void setCatalogEnabled(const QString &name, bool e); + + /**Indicates if an index of given catalog should be rebuilt. This method + is used by index caching algorythm to make a descision to rebuild index + or to load it from cache.*/ + virtual bool needRefreshIndex(DocumentationCatalogItem *item) = 0; + /**Indicates if an index is enabled for given catalog. If documentation plugin + has Index capability, indices for it's catalogs can be enabled/disabled + in configuration dialog.*/ + virtual bool indexEnabled(DocumentationCatalogItem *item) const; + /**Enables or disables index for documentation catalog.*/ + virtual void setIndexEnabled(DocumentationCatalogItem *item, bool e); + /**Builds index for given catalog. This method should fill index with + IndexItem objects. + @param index the listbox which contains index items + @param item the catalog item that holds an index being built + */ + virtual void createIndex(IndexBox *index, DocumentationCatalogItem *item) = 0; + + /**Creates a table of contents for given catalog. Documentation part uses + lazy loading of toc's to reduce startup time. This means that createTOC + will be called on expand event of catalog item.*/ + virtual void createTOC(DocumentationCatalogItem *item) = 0; + /**Sets the URL to the catalog. This method will be called each time user + clicks the documentation item. If it is too much overhead to determine the + documentation catalog url in @ref createCatalog method then you can set it here.*/ + virtual void setCatalogURL(DocumentationCatalogItem *item) = 0; + virtual QStringList fullTextSearchLocations() = 0; + + /**Loads catalog configuration and fills configurationView with ConfigurationItem objects.*/ + virtual void loadCatalogConfiguration(KListView *configurationView); + /**Saves catalog configuration basing on configurationView and + deletedConfigurationItems contents. If you use KConfig to store configuration, + it is important that you call KConfig::sync() method after saving.*/ + virtual void saveCatalogConfiguration(KListView *configurationView); + /**Adds new catalog to a configuration.*/ + virtual void addCatalogConfiguration(KListView *configurationView, + const QString &title, const QString &url); + /**Edits catalog configuration.*/ + virtual void editCatalogConfiguration(ConfigurationItem *configurationItem, + const QString &title, const QString &url); + /**Removes catalog from configuration. configurationItem should not be removed here.*/ + virtual void deleteCatalogConfiguration(const ConfigurationItem *const configurationItem); + + /**Returns a mode and a filter for catalog locator dialogs.*/ + virtual QPair<KFile::Mode, QString> catalogLocatorProps() = 0; + /**Returns a title of catalog defined by an url parameter.*/ + virtual QString catalogTitle(const QString &url) = 0; + + /**Reloads documentation catalogs and indices.*/ + virtual void reload(); + /**Clears documentation catalogs and indices.*/ + virtual void clear(); + + /**Checks if documentation plugin has given capability.*/ + bool hasCapability(Capability cap) const { return m_capabilities & cap; } + + /**Sets dirty flag for all indices. Index caching algorythm will update + the cache next time @ref createIndex is called.*/ + void setDirtyIndex(bool dirty) { m_indexCreated = dirty; } + + /**Caches index for documentation catalog. Reimplement this only if custom + caching algorythm is used (do not forget to reimplement also @ref loadCachedIndex + and @ref createIndex).*/ + virtual void cacheIndex(DocumentationCatalogItem *item); + /**Loads index from the cache. Reimplement this only if custom + caching algorythm is used (do not forget to reimplement also @ref cacheIndex + and @ref createIndex).*/ + virtual bool loadCachedIndex(IndexBox *index, DocumentationCatalogItem *item); + + /**Returns associated project documentation plugin. Default implementation returns zero. + Reimplement this if the documentation plugin can also handle project documentation.*/ + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType /* type */) { return 0; } + +public slots: + /**Creates index and fills index listbox. Reimplement this only if custom + caching algorythm is used (do not forget to reimplement also @ref cacheIndex + and @ref loadCachedIndex).*/ + virtual void createIndex(IndexBox *index); + +protected: + /**A list of loaded documentation catalogs.*/ + QValueList<DocumentationCatalogItem*> catalogs; + /**A map of names of loaded documentation catalogs.*/ + QMap<QString, DocumentationCatalogItem*> namedCatalogs; + /**A map of indices of loaded documentation catalogs.*/ + QMap<DocumentationCatalogItem*, QValueList<IndexItemProto*> > indexes; + + /**Sets capabilities of documentation plugin.*/ + void setCapabilities(int caps) { m_capabilities = caps; } + /**Clears index of given catalog.*/ + virtual void clearCatalogIndex(DocumentationCatalogItem *item); + /**Loads index from cache or creates and caches it if does not exist.*/ + void loadIndex(IndexBox *index, DocumentationCatalogItem *item); + + /**Stores items deleted from configuration. @ref saveCatalogConfiguration + uses this to remove entries from configuration file.*/ + QStringList deletedConfigurationItems; + + /**Configuration object used by a plugin.*/ + KConfig *config; + +private: + /**Adds catalog item to catalogs, namedCatalogs and indexes lists and maps.*/ + virtual void addCatalog(DocumentationCatalogItem *item); + /**Removes catalog item from catalogs, namedCatalogs and indexes lists and maps.*/ + virtual void clearCatalog(DocumentationCatalogItem *item); + + int m_capabilities; + bool m_indexCreated; + + +friend class IndexItemProto; +friend class DocumentationCatalogItem; +}; + + +/** +@short Project documentation plugin + +Represents functionality to display project documentation catalog and index in documentation browser. +*/ +class ProjectDocumentationPlugin: public QObject { + Q_OBJECT +public: + ProjectDocumentationPlugin(DocumentationPlugin *docPlugin, DocumentationPlugin::ProjectDocType type); + virtual ~ProjectDocumentationPlugin(); + + /**Initializes project documentation plugin - creates documentation catalog.*/ + virtual void init(KListView *contents, IndexBox *index, const QString &url); + /**Deinitializes project documentation plugin - removes documentation catalog.*/ + virtual void deinit(); + + QString pluginName() const; + QString catalogURL() const; + +public slots: + /**Performs reinitialization if project documentation has changed (after building api documentation).*/ + virtual void reinit(); + +protected: + DocumentationPlugin *m_docPlugin; + DocumentationCatalogItem *m_catalog; + +private: + DocumentationPlugin::ProjectDocType m_type; + + class KDirWatch *m_watch; + class KListView *m_contents; + class IndexBox *m_index; + QString m_url; +}; + +#endif diff --git a/parts/documentation/interfaces/kdevelopdocumentationplugins.desktop b/parts/documentation/interfaces/kdevelopdocumentationplugins.desktop new file mode 100644 index 00000000..08fed218 --- /dev/null +++ b/parts/documentation/interfaces/kdevelopdocumentationplugins.desktop @@ -0,0 +1,36 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=KDevelop/DocumentationPlugins +X-KDE-Derived=KDevelop/Plugin +Name=KDevelop Documentation Plugin Interface +Name[ca]=Interfície de connectors de documentació de KDevelop +Name[da]=KDevelop grænseflade for dokumentations-plugin +Name[de]=Schnittstelle für Dokumentationsmodul (KDevelop) +Name[el]=Διασύνδεση πρόσθετου τεκμηρίωσης KDevelop +Name[es]=Interfaz de complemento de documentación de KDevelop +Name[et]=KDevelopi dokumentatsiooniplugina liides +Name[eu]=KDevelop-en dokumentazio plugin interfazea +Name[fa]=واسط وصلۀ مستندات KDevelop +Name[fr]=Interface du module externe de documentation de KDevelop +Name[gl]=Interface da extensión de documentación de KDevelop +Name[hu]=KDevelop dokumentációmodul-felület +Name[it]=Interfaccia a plugin della documentazione di KDevelop +Name[ja]=KDevelop ドキュメンテーションプラグイン インターフェース +Name[ms]=Antaramuka Plugin Dokumentasi KDevelop +Name[nds]=KDevelop-Koppelsteed för't Dokmentatschoon-Moduul +Name[ne]=केडीई विकास मिसिलीकरण प्लगइन इन्टरफेस +Name[nl]=KDevelop Documentatie Plugin Interface +Name[pl]=Interfejs do wtyczki dokumentacji dla KDevelop +Name[pt]=Interface de 'Plugin' de Documentação do KDevelop +Name[pt_BR]=Interface de Plug-in de Documentação do KDevelop +Name[ru]=Интерфейс для модулей документации KDevelop +Name[sk]=KDevelop rozhranie pre dokumentačný modul +Name[sl]=Vmesnik vstavka dokumentacije v KDevelopu +Name[sr]=Интерфејс KDevelop-овог прикључка за документацију +Name[sr@Latn]=Interfejs KDevelop-ovog priključka za dokumentaciju +Name[sv]=KDevelop insticksgränssnitt för dokumentation +Name[ta]=Kமுன்னேற்று தொகுப்பான் தேர்வுகள் உரை இடைமுகம் உள்ளீடு +Name[tg]=Интерфейс барои модулҳои ҳуҷҷатноки KDevelop +Name[tr]=KDevelop Belgelendirme Eklentisi Arayüzü +Name[zh_CN]=KDevelop 文档插件接口 +Name[zh_TW]=KDevelop 文件外掛程式介面 diff --git a/parts/documentation/kdevdocumentation.desktop b/parts/documentation/kdevdocumentation.desktop new file mode 100644 index 00000000..415d1e2e --- /dev/null +++ b/parts/documentation/kdevdocumentation.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=The Documentation plugin offers browsing and searching in local and online documentation with support for multiple documentation systems. +Comment[ca]=El connector de documentació ofereix navegació i recerca en documentació local i en línia amb suport per a múltiples sistemes de documentació. +Comment[da]=Dokumentations-plugin tilbyder visning og søgning i lokal og online dokumentation med understøttelse af flere dokumentations-systemer. +Comment[de]=Die Dokumentations-Komponente bietet eine Browsefunktion und Unterstützung für die Suche in mehreren Hilfedokumenten und Dokumentationssystemen. +Comment[el]=Το πρόσθετο τεκμηρίωσης προσφέρει περιήγηση και αναζήτηση σε τοπική και απομακρυσμένη τεκμηρίωση για πολλαπλά συστήματα τεκμηρίωσης. +Comment[es]=El complemento de documentación proporciona navegación y búsqueda en la documentación, tanto local como en línea, y permite múltiples sistemas de documentación. +Comment[et]=Dokumentatsiooniplugin võimaldab lehitseda ja otsida nii kohalikus kui võrgudokumentatsioonis paljusid dokumentatsioonisüsteeme kasutades. +Comment[eu]=Dokumentazio-pluginak lokaleko eta urruneko dokumentazio arakatzeko eta bilatzeko aukera ematen dizu, eta dokumentazio-sistema anitz onartzen ditu. +Comment[fa]=وصلۀ مستندسازی، مرور و جستجو در مستندات محلی و برخط را با پشتیبانی از سیستمهای مستندسازی چندگانه، ارائه میکند. +Comment[fr]=Le module externe de documentation offre une navigation et une recherche dans la documentation locale et en ligne ainsi que la prise en charge de systèmes de documentation mutiples. +Comment[gl]=A extensión de documentación ofrece navegación e búsqueda en documentación local e en liña con soporte para múltiples sistemas de documentación. +Comment[hu]=Dokumentációmegjelenítő elem helyi és távoli dokumentáció böngészéséhez, keresési lehetőséggel. Többféle formátumot támogat. +Comment[it]=Il plugin di documentazione offre navigazione e ricerca in locale e documentazione in linea con supporto per sistemi di documentazione multipla. +Comment[ms]=Plugin dokumentasi menawarkan pelungsuran dan pencarian dalam dokumentasi tempatan dan dalam talian dengan sokongan untuk pelbagai sistem dokumentasi. +Comment[nds]=Mit dat Dokmentatschoon-Moduul kannst Du lokale un Tokoppel-Dokmentatschoon dörkieken un -söken, mehr Dokmentatschoonsystemen warrt ünnerstütt. +Comment[ne]=मिसिलीकरण प्लगइनले बहुविध मिसिलीकरण प्रणालीको समर्थनसँग अनलाइन मिसिलीकरण र स्थानीय रूपमा ब्राउज र खोजी गर्न दिन्छ । +Comment[nl]=De documentatieplugin welke het mogelijk maakt om door lokale documentatie en documentatie op afstand te bladeren en te zoeken. Met ondersteuning voor verschillende documentatiesystemen. +Comment[pl]=Kontrola dokumentacji z obsługą przeglądania i wyszukiwania w różnych plikach pomocy i systemach dokumentacji. +Comment[pt]=O 'plugin' de documentação oferece navegação e procura em documentação local e em rede com suporte para vários sistemas de documentação. +Comment[pt_BR]=A documentação do plug-in oferece navegação e busca na documentação local e online com suporte para diversos sistemas de documentação. +Comment[ru]=Модуль документации позволяет упростить работу с документацией. +Comment[sk]=Dokumentačný modul proskytuje prehliadanie a vyhľadávanie v lokálnej a online dokumentácie s podporou viacerých dokumentačných systémov. +Comment[sr]=Прикључак за документацију са подршком за прегледање и тражење у локалној и документацији на вези, за више документационих система. +Comment[sr@Latn]=Priključak za dokumentaciju sa podrškom za pregledanje i traženje u lokalnoj i dokumentaciji na vezi, za više dokumentacionih sistema. +Comment[sv]=Dokumentationsinsticksprogrammet erbjuder bläddring och sökning i lokal dokumentation och dokumentation på nätet, med stöd för flera dokumentationssystem. +Comment[tr]=Belgelendirme eklentisi, çoklu belgelendirme sistemlerine destek ile, yerel ve çevrimiçi belgelere gözatma ve bu belgelerde arama yapılmasına izin verir. +Comment[zh_CN]=文档插件提供了本地和在线文档中提供浏览和搜索功能,支持多种文档系统 +Comment[zh_TW]=文件外掛程式提供對本地與線上文件的瀏覽與搜尋功能,並支援多重文件系統。 +Name=KDevDocumentation +Name[da]=KDevelop dokumentation +Name[nds]=KDevelop-Dokmentatschoon +Name[pt_BR]=KDevDocumentação +Name[sk]=KDev dokumentácia +Name[sv]=KDevelop dokumentation +Name[ta]=KDev ஆவணமாக்கல் +Name[tg]=Ҳуҷҷатҳои KDev +Name[zh_TW]=KDevelop 文件 +GenericName=Documentation +GenericName[br]=Teuliadur +GenericName[ca]=Documentació +GenericName[cy]=Dogfenniaeth +GenericName[da]=Dokumentation +GenericName[de]=Dokumentationsbaum +GenericName[el]=Τεκμηρίωση +GenericName[es]=Documentación +GenericName[et]=Dokumentatsioon +GenericName[eu]=Dokumentazioa +GenericName[fa]=مستندات +GenericName[ga]=Doiciméadú +GenericName[gl]=Documentación +GenericName[hi]=दस्तावेज़ीकरण +GenericName[hu]=Dokumentáció +GenericName[it]=Documentazione +GenericName[ja]=ドキュメンテーション +GenericName[ms]=Dokumentasi +GenericName[nds]=Dokmentatschoon +GenericName[ne]=मिसिलीकरण +GenericName[nl]=Documentatie +GenericName[pl]=Dokumentacja +GenericName[pt]=Documentação +GenericName[pt_BR]=Documentação +GenericName[ru]=Просмотр документации +GenericName[sk]=Dokumentácia +GenericName[sl]=Dokumentacija +GenericName[sr]=Документација +GenericName[sr@Latn]=Dokumentacija +GenericName[sv]=Dokumentation +GenericName[ta]=ஆவணமாக்கல் +GenericName[tg]=Намоиши ҳуҷҷатҳо +GenericName[tr]=Belgelendirme +GenericName[zh_CN]=文档 +GenericName[zh_TW]=文件 +Icon=khelpcenter +ServiceTypes=KDevelop/Plugin +X-KDevelop-Scope=Global +X-KDE-Library=libkdevdocumentation +X-KDevelop-Version=5 +X-KDevelop-Mode=AssistantMode +X-KDevelop-Properties=Documentation diff --git a/parts/documentation/kdevpart_documentation.rc b/parts/documentation/kdevpart_documentation.rc new file mode 100644 index 00000000..f8dac85a --- /dev/null +++ b/parts/documentation/kdevpart_documentation.rc @@ -0,0 +1,19 @@ +<!DOCTYPE kpartgui> +<kpartplugin name="documentation" library="libdocumentationplugin" version="4"> +<MenuBar> +<!-- <Action name="doc_bookmarks"/> --> +<!-- <Menu name="tools"><Text>&Tools</Text> + <Action name="plugin_action"/> + </Menu> --> + <Menu name="help"> + <Action name="help_look_in_index"/> + <Action name="help_search_in_doc"/> + <Action name="help_manpage"/> + <Action name="help_infopage"/> + <Action name="help_find_documentation" /> + </Menu> +</MenuBar> +<!--<ToolBar name="extraToolBar"> + <Action name="plugin_action"/> +</ToolBar> --> +</kpartplugin> diff --git a/parts/documentation/plugins/Makefile.am b/parts/documentation/plugins/Makefile.am new file mode 100644 index 00000000..c2002f78 --- /dev/null +++ b/parts/documentation/plugins/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util $(all_includes) +METASOURCES = AUTO +SUBDIRS = qt doxygen devhelp kdevtoc chm custom diff --git a/parts/documentation/plugins/chm/Makefile.am b/parts/documentation/plugins/chm/Makefile.am new file mode 100644 index 00000000..6df1ba52 --- /dev/null +++ b/parts/documentation/plugins/chm/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) + +METASOURCES = AUTO + +kde_module_LTLIBRARIES = libdocchmplugin.la + +noinst_HEADERS = docchmplugin.h +kde_services_DATA = docchmplugin.desktop + +libdocchmplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libdocchmplugin_la_SOURCES = docchmplugin.cpp +libdocchmplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la diff --git a/parts/documentation/plugins/chm/docchmplugin.cpp b/parts/documentation/plugins/chm/docchmplugin.cpp new file mode 100644 index 00000000..e2b2b556 --- /dev/null +++ b/parts/documentation/plugins/chm/docchmplugin.cpp @@ -0,0 +1,198 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docchmplugin.h" + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> +#include <kio/netaccess.h> +#include <iostream> +#include <fstream> +#include <qvaluevector.h> +#include <kdevgenericfactory.h> +#include <kdevplugininfo.h> +#include <qregexp.h> + +#include "../../../../config.h" + +static const KDevPluginInfo data("docchmplugin"); +typedef KDevGenericFactory<DocCHMPlugin> DocCHMPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocchmplugin, DocCHMPluginFactory(data) ) + +DocCHMPlugin::DocCHMPlugin(QObject* parent, const char* name, QStringList // args + ) + :DocumentationPlugin(DocCHMPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(CustomDocumentationTitles); // | Index | FullTextSearch | ProjectDocumentation + autoSetup(); +} + +DocCHMPlugin::~DocCHMPlugin() +{ +} + + +DocumentationCatalogItem* DocCHMPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + DocumentationCatalogItem *item = new DocumentationCatalogItem(this, contents, title); + item->setURL(KURL(url)); + + return item; +} + +QPair<KFile::Mode, QString> DocCHMPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "*.chm"); +} + +QString DocCHMPlugin::catalogTitle(const QString& // url + ) +{ + return QString::null; +} + +QString DocCHMPlugin::pluginName() const +{ + return i18n("CHM Documentation Collection"); +} + + +QString DocCHMPlugin::getSpecialData(const QString& name, KURL url) { + QString ret = ""; + url.setProtocol("ms-its"); + + url.addPath("/:" + name); + QString tmpFile; + if( KIO::NetAccess::download( url, tmpFile, 0 ) ) + { + std::filebuf fb; + fb.open (tmpFile.ascii(), std::ios::in); + std::istream is(&fb); + char buf[5000] = " "; + while(is.good()) { + is.getline(buf, 5000); + ret += buf; ret += "\n"; + } + fb.close(); + KIO::NetAccess::removeTempFile( tmpFile ); + } else { + kdDebug(9002) << "DocCHMPlugin::getSpecialData could not download data from " << url.url() << endl; + } + return ret; +} + + +///this currently is useless, because htdig cannot use kioslaves +QStringList DocCHMPlugin::fullTextSearchLocations() +{ + //return QStringList::split( '\n', getSpecialData("contents", m_url)); + return QStringList(); +} + +bool DocCHMPlugin::needRefreshIndex(DocumentationCatalogItem* // item + ) +{ + return false; +} + +void DocCHMPlugin::autoSetupPlugin() +{ + return; +} + +void DocCHMPlugin::createIndex(IndexBox* // index + , DocumentationCatalogItem* // item + ) +{ + return; +} + + +static KListViewItem* chainEnd(KListViewItem *parent) { + if(parent == 0) return 0; + KListViewItem* ret = dynamic_cast<KListViewItem*>(parent->firstChild()); + if(ret == 0) return 0; + while(ret->nextSibling() != 0) { + ret = dynamic_cast<KListViewItem*>(ret->nextSibling()); + } + return ret; +} + +static QString decodeHTML(const QString& s) { + QRegExp rx(QString::fromLatin1("&#(\\d+);| ")); + QString out = s; + int pos = rx.search(out); + while(pos > -1) { + QString found = rx.cap(0); + if(found != " ") { + out.replace(pos, found.length(), static_cast<char>(rx.cap(1).toInt())); + }else{ + out.replace(pos, found.length(), " "); + } + pos = rx.search(out, pos+1); + } + return out; +} + + +void DocCHMPlugin::createTOC(DocumentationCatalogItem* item) +{ + QStringList lines = QStringList::split("\n", getSpecialData("catalog", item->url()) ); + if(lines.count() % 4 != 0) { kdDebug(9002) << "DocCHMPlugin::createTOC: wrong count of strings"; return;} + + QValueVector<DocumentationItem*> items; + items.push_back(item); + for(QStringList::Iterator it = lines.begin(); it != lines.end();) { + bool ok1 = true, ok2 = true; + int parent = (*it).toInt(&ok1); + ++it; + int current = (*it).toInt(&ok2); + ++it; + if(int(items.size()) != current || !ok1 || !ok2 || parent < 0 || parent >= int(items.size()) || current < 0 || current != int(items.size())) { + kdDebug(9002) << "DocCHMPlugin::createTOC error while parsing output of ioslave" << endl; + break; + } + + QString& name(*it); + ++it; + KURL url(*it); + ++it; + + items.push_back(new DocumentationItem( + DocumentationItem::Document, items[parent], chainEnd(items[parent]), decodeHTML(name))); + items[current]->setURL(url); + if(parent != 0) items[parent]->setType(DocumentationItem::Book); + } + + + return; +} + +void DocCHMPlugin::setCatalogURL(DocumentationCatalogItem* item) +{ + KURL chmURL = item->url(); + chmURL.setProtocol("ms-its"); + chmURL.addPath("/"); + item->setURL(chmURL); +} + +#include "docchmplugin.moc" diff --git a/parts/documentation/plugins/chm/docchmplugin.desktop b/parts/documentation/plugins/chm/docchmplugin.desktop new file mode 100644 index 00000000..1e538ed7 --- /dev/null +++ b/parts/documentation/plugins/chm/docchmplugin.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Type=Service +Name=DocCHMPlugin +Name[da]=DocCHM-plugin +Name[hu]=DocCHMPPlugin +Name[sk]=Doc CHM modul +Name[sv]=CHM-dokumentationsinsticksmodul +Name[ta]=DocCHM சொருகு +Name[zh_TW]=Doc CHM 外掛程式 +Exec=blubb +Comment=Documentation plugin for CHM documentation +Comment[ca]=Connector de documentació per a documentació CHM +Comment[da]=Dokumentations-plugin for CHM-dokumentation +Comment[de]=Dokumentations-Modul für CHM-Dokumentation +Comment[el]=Πρόσθετο τεκμηρίωσης για τεκμηρίωση CHM +Comment[es]=Complemento de documentación para CHM +Comment[et]=CHM dokumentatsiooni plugin +Comment[eu]=CHM dokumentazioarako dokumentazioa plugin-aDocumentation plugin for CHM documentation +Comment[fa]=وصلۀ مستندسازی برای مستندات CHM +Comment[fr]=Module externe de documentation pour la documentation CHM +Comment[gl]=Extensión de documentación para documentación CHM +Comment[hu]=Dokumentációmodul CHM formátumú dokumentációhoz +Comment[it]=Plugin di documentazione per file CHM +Comment[ja]=CHM ドキュメンテーションのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk dokumentasi CHM +Comment[nds]=Dokmentatschoon-Moduul för CHM-Dokmentatschonen +Comment[ne]=CHM मिसिलीकरणका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor CHM documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie CHM +Comment[pt]='Plugin' para documentação CHM +Comment[pt_BR]=Plug-in de documentação para documento CHM +Comment[ru]=Модуль для просмотра документации в файлах CHM +Comment[sk]=Dokumentačný modul pre CHM dokumentáciu +Comment[sr]=Документациони прикључак за CHM документацију +Comment[sr@Latn]=Dokumentacioni priključak za CHM dokumentaciju +Comment[sv]=Dokumentationsinsticksmodul för CHM-dokumentation +Comment[ta]= CHM ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои намоиши файлҳои CHM-е, ки ҳуҷҷатҳо мавҷуд аст +Comment[tr]=CHM belgelendirmesi için belgelendirme eklentisi +Comment[zh_CN]=CHM 文档的文档插件 +Comment[zh_TW]=CHM 文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=5 +X-KDE-Library=libdocchmplugin diff --git a/parts/documentation/plugins/chm/docchmplugin.h b/parts/documentation/plugins/chm/docchmplugin.h new file mode 100644 index 00000000..69bc441b --- /dev/null +++ b/parts/documentation/plugins/chm/docchmplugin.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCCHMPLUGIN_H +#define DOCCHMPLUGIN_H + +#include <kdevdocumentationplugin.h> + +class DocCHMPlugin :public DocumentationPlugin +{ + Q_OBJECT +public: + DocCHMPlugin(QObject* parent, const char* name, QStringList args = QStringList()); + ~DocCHMPlugin(); + + virtual QString pluginName() const; + + virtual void setCatalogURL(DocumentationCatalogItem* item); + virtual QString catalogTitle(const QString& url); + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + virtual void createTOC(DocumentationCatalogItem* item); + + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual void autoSetupPlugin(); +protected: + QString getSpecialData(const QString& name, KURL url); +}; + +#endif diff --git a/parts/documentation/plugins/custom/Makefile.am b/parts/documentation/plugins/custom/Makefile.am new file mode 100644 index 00000000..999dc853 --- /dev/null +++ b/parts/documentation/plugins/custom/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libdoccustomplugin.la +libdoccustomplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libdoccustomplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la +noinst_HEADERS = doccustomplugin.h +libdoccustomplugin_la_SOURCES = doccustomplugin.cpp +kde_services_DATA = doccustomplugin.desktop diff --git a/parts/documentation/plugins/custom/doccustomplugin.cpp b/parts/documentation/plugins/custom/doccustomplugin.cpp new file mode 100644 index 00000000..b3cc7685 --- /dev/null +++ b/parts/documentation/plugins/custom/doccustomplugin.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "doccustomplugin.h" + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> + +#include <kdevgenericfactory.h> +#include <kdevplugininfo.h> + +static const KDevPluginInfo data("doccustomplugin"); +typedef KDevGenericFactory<DocCustomPlugin> DocCustomPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdoccustomplugin, DocCustomPluginFactory(data) ) + +DocCustomPlugin::DocCustomPlugin(QObject* parent, const char* name, const QStringList // args + ) + :DocumentationPlugin(DocCustomPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(CustomDocumentationTitles | ProjectUserManual); + autoSetup(); +} + +DocCustomPlugin::~DocCustomPlugin() +{ +} + +bool DocCustomPlugin::needRefreshIndex(DocumentationCatalogItem* // item + ) +{ + return false; +} + +QString DocCustomPlugin::pluginName() const +{ + return i18n("Custom Documentation Collection"); +} + +DocumentationCatalogItem* DocCustomPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + DocumentationCatalogItem *item = new DocumentationCatalogItem(this, contents, title); + item->setURL(KURL(url)); + return item; +} + +QPair<KFile::Mode, QString> DocCustomPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "all/allfiles"); +} + +QString DocCustomPlugin::catalogTitle(const QString& /*url*/) +{ + return QString::null; +} + +QStringList DocCustomPlugin::fullTextSearchLocations() +{ + return QStringList(); +} + + +void DocCustomPlugin::autoSetupPlugin() +{ + return; +} + +void DocCustomPlugin::createIndex(IndexBox* /*index*/, DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocCustomPlugin::createTOC(DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocCustomPlugin::setCatalogURL(DocumentationCatalogItem* /*item*/) +{ + return; +} + +ProjectDocumentationPlugin *DocCustomPlugin::projectDocumentationPlugin(ProjectDocType type) +{ + if (type == UserManual) + return new ProjectDocumentationPlugin(this, type); + return DocumentationPlugin::projectDocumentationPlugin(type); +} diff --git a/parts/documentation/plugins/custom/doccustomplugin.desktop b/parts/documentation/plugins/custom/doccustomplugin.desktop new file mode 100644 index 00000000..09b018e7 --- /dev/null +++ b/parts/documentation/plugins/custom/doccustomplugin.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Type=Service +Name=DocCustomPlugin +Name[da]=Brugerdefineret doc-plugin +Name[sk]=Doc vlastný modul +Name[sv]=Egen dokumentationsinsticksmodul +Name[ta]=ஆவண தனிப்பயன் சொருகுப்பொருள் +Name[zh_TW]=Doc 自訂外掛程式 +Exec=blubb +Comment=Documentation plugin for all types of documentation +Comment[ca]=Connector de documentació per a tot tipus de documentació +Comment[da]=Dokumentations-plugin for alle typer dokumentation +Comment[de]=Komponente für alle Arten von Dokumentation +Comment[el]=Πρόσθετο τεκμηρίωσης για όλους τους τύπους τεκμηρίωσης +Comment[es]=Complemento de documentación para todos los tipos de documentación +Comment[et]=Igat tüüpi dokumentatsiooni plugin +Comment[eu]=Dokumentu mota guztientzako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای همۀ انواع مستندات +Comment[fr]=Module externe de documentation pour tous les types de documentation +Comment[gl]=Extensión de documentación para tódolos tipos de documentación +Comment[hu]=Dokumentációmodul mindenféle dokumentációhoz +Comment[it]=Plugin di documentazione per tutti i tipi di documentazione +Comment[ja]=全種類のドキュメンテーションのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk semua jenis dokumentasi +Comment[nds]=Dokmentatschoon-Moduul för all Oorden vun Dokmentatschoon +Comment[ne]=सबै प्रकारको मिसिलीकरणका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor alle typen documentatie +Comment[pl]=Wtyczka dokumentacji dla wszystkich typów dokumentacji +Comment[pt]='Plugin' para documentação de todos os tipos +Comment[pt_BR]=Plug-in de documentação para todos os tipos de documentação +Comment[ru]=Модуль для работы с документацией +Comment[sk]=Dokumentačný modul pre všetky typy dokumentácie +Comment[sl]=Dokumentacijski vstavek za vse vrste dokumentacije +Comment[sr]=Документациони прикључак за све типове документације +Comment[sr@Latn]=Dokumentacioni priključak za sve tipove dokumentacije +Comment[sv]=Dokumentationsinsticksmodul för alla typer av dokumentation +Comment[ta]=எல்லா வகை ஆவணமயமாக்கலுக்கான ஆவணமயமாக்கல் சொருகுப்பொருள் +Comment[tg]=Модул барои кор кардан бо ҳуҷҷатҳо +Comment[tr]=Her tür belgelendirme için belgelendirme eklentisi +Comment[zh_CN]=全部类型文档的文档插件 +Comment[zh_TW]=所有型態的文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=5 +X-KDE-Library=libdoccustomplugin diff --git a/parts/documentation/plugins/custom/doccustomplugin.h b/parts/documentation/plugins/custom/doccustomplugin.h new file mode 100644 index 00000000..2888af81 --- /dev/null +++ b/parts/documentation/plugins/custom/doccustomplugin.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCCUSTOMPLUGIN_H +#define DOCCUSTOMPLUGIN_H + +#include <kdevdocumentationplugin.h> + +class DocCustomPlugin : public DocumentationPlugin { +public: + DocCustomPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocCustomPlugin(); + + virtual QString pluginName() const; + + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + + virtual void createTOC(DocumentationCatalogItem* item); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual QString catalogTitle(const QString& url); + + virtual void autoSetupPlugin(); + + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType type); +}; + +#endif diff --git a/parts/documentation/plugins/devhelp/Makefile.am b/parts/documentation/plugins/devhelp/Makefile.am new file mode 100644 index 00000000..e0682833 --- /dev/null +++ b/parts/documentation/plugins/devhelp/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) + +METASOURCES = AUTO + +kde_module_LTLIBRARIES = libdocdevhelpplugin.la + +noinst_HEADERS = docdevhelpplugin.h +kde_services_DATA = docdevhelpplugin.desktop + +libdocdevhelpplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libdocdevhelpplugin_la_SOURCES = docdevhelpplugin.cpp +libdocdevhelpplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la diff --git a/parts/documentation/plugins/devhelp/docdevhelpplugin.cpp b/parts/documentation/plugins/devhelp/docdevhelpplugin.cpp new file mode 100644 index 00000000..dca19e51 --- /dev/null +++ b/parts/documentation/plugins/devhelp/docdevhelpplugin.cpp @@ -0,0 +1,386 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docdevhelpplugin.h" + +#include <unistd.h> + +#include <qdom.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qdialog.h> + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include <kdevgenericfactory.h> +#include <kdevplugininfo.h> + +#include "../../../../config.h" + +class DevHelpDocumentationCatalogItem: public DocumentationCatalogItem +{ +public: + DevHelpDocumentationCatalogItem(const QString &devHelpFile, DocumentationPlugin* plugin, + KListView *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_devHelpFile(devHelpFile) + { + } + DevHelpDocumentationCatalogItem(const QString &devHelpFile, DocumentationPlugin* plugin, + DocumentationItem *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_devHelpFile(devHelpFile) + { + } + QString devHelpFile() const { return m_devHelpFile; } + + virtual QString cacheVersion() const { + unsigned int checksum=0; + for(int a=0;a<m_devHelpFile.length(); a++) { + checksum += (a+1) * (int)m_devHelpFile[a]; + } + QString str; + QTextOStream( &str ) << checksum; + return str; + } + +protected: + +private: + QString m_devHelpFile; +}; + + +static const KDevPluginInfo data("docdevhelpplugin"); +typedef KDevGenericFactory<DocDevHelpPlugin> DocDevHelpPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocdevhelpplugin, DocDevHelpPluginFactory(data) ) + +DocDevHelpPlugin::DocDevHelpPlugin(QObject* parent, const char* name, + const QStringList /*args*/) + :DocumentationPlugin(DocDevHelpPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(Index | FullTextSearch | ProjectDocumentation); + autoSetup(); +} + +DocDevHelpPlugin::~DocDevHelpPlugin() +{ +} + +DocumentationCatalogItem* DocDevHelpPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + return new DevHelpDocumentationCatalogItem(url, this, contents, title); +} + +QPair<KFile::Mode, QString> DocDevHelpPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "*.devhelp"); +} + +QString DocDevHelpPlugin::catalogTitle(const QString& url) +{ + QFileInfo fi(url); + if (!fi.exists()) + return QString::null; + + QFile f(url); + if (!f.open(IO_ReadOnly)) + return QString::null; + + QDomDocument doc; + if (!doc.setContent(&f)) + return QString::null; + f.close(); + + QDomElement docEl = doc.documentElement(); + + return docEl.attribute("title", QString::null); +} + +QString DocDevHelpPlugin::pluginName() const +{ + return i18n("Devhelp Documentation Collection"); +} + +QStringList DocDevHelpPlugin::fullTextSearchLocations() +{ + QStringList locs; + + QMap<QString, QString> entryMap = config->entryMap("Locations"); + + for (QMap<QString, QString>::const_iterator it = entryMap.begin(); + it != entryMap.end(); ++it) + { + config->setGroup("Search Settings"); + if (config->readBoolEntry(it.key(), false)) + { + config->setGroup("Locations"); + QFileInfo fi(config->readPathEntry(it.key())); + locs << fi.dirPath(true); + } + } + + return locs; +} + +bool DocDevHelpPlugin::needRefreshIndex(DocumentationCatalogItem* item) +{ + DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item); + if (!dhItem) + return false; + + QFileInfo fi(dhItem->devHelpFile()); + config->setGroup("Index"); + if (fi.lastModified() > config->readDateTimeEntry(dhItem->text(0), new QDateTime())) + { + kdDebug() << "need rebuild index for " << dhItem->text(0) << endl; + config->writeEntry(item->text(0), fi.lastModified()); + return true; + } + else + return false; +} + +void DocDevHelpPlugin::autoSetupPlugin() +{ + QValueStack<QString> scanStack; + + pushToScanStack(scanStack, getenv("DEVHELP_SEARCH_PATH")); + pushToScanStack(scanStack, QString(getenv("HOME")) + "/.devhelp/books"); + + QString dhexepath = DocDevHelpPluginFactory::instance()->dirs()->findExe("devhelp"); + if (!dhexepath.isEmpty()) + { + QFileInfo fi(dhexepath); + QString path = KURL(fi.dirPath(true)).upURL().path(1); + pushToScanStack(scanStack, path + "share/devhelp/books"); + pushToScanStack(scanStack, path + "share/gtk-doc/html"); + } + + pushToScanStack(scanStack, "/usr/share/gtk-doc/html"); + pushToScanStack(scanStack, "/usr/share/devhelp/books/"); + pushToScanStack(scanStack, "/usr/local/share/devhelp/books"); + pushToScanStack(scanStack, "/usr/local/share/gtk-doc/html"); + pushToScanStack(scanStack, "/opt/gnome/share/devhelp/books"); + pushToScanStack(scanStack, "/opt/gnome/share/gtk-doc/html"); + pushToScanStack(scanStack, "/opt/gnome2/share/devhelp/books"); + pushToScanStack(scanStack, "/opt/gnome2/share/gtk-doc/html"); + + //fill the list of scan dirs (with subdirectories) + QStringList scanList; + QDir dir; + do + { + dir.setPath(scanStack.pop()); + if (!dir.exists()) + continue; + scanList << dir.path(); + + const QFileInfoList *dirEntries = dir.entryInfoList(); + if ( !dirEntries ) continue; + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) + { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) + { + scanStack.push(path); + } + } + } while (!scanStack.isEmpty()); + + for (QStringList::const_iterator it = scanList.begin(); it != scanList.end(); ++it) + { + scanDevHelpDir(*it); + } +} + +void DocDevHelpPlugin::scanDevHelpDir(const QString &path) +{ + QDir d(path); + if (! d.exists() || !d.isReadable()) + return; + + d.setFilter(QDir::Files); + //scan for *.devhelp files + const QFileInfoList *list = d.entryInfoList(); + QFileInfoListIterator it( *list ); + QFileInfo *fi; + while ( (fi = it.current()) != 0 ) + { + if (fi->extension() == "devhelp") + { + config->setGroup("Locations"); + config->writePathEntry(catalogTitle(fi->absFilePath()), fi->absFilePath()); + } + ++it; + } +} + +void DocDevHelpPlugin::pushToScanStack(QValueStack<QString> &stack, const QString &value) +{ + if ( (!value.isEmpty()) && (!stack.contains(value)) ) + { + stack << value; + kdDebug() << "Devhelp scan stack: +: " << value << endl; + } +} + +void DocDevHelpPlugin::createIndex(IndexBox* index, DocumentationCatalogItem* item) +{ + DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item); + if (!dhItem) + return; + + QFileInfo fi(dhItem->devHelpFile()); + + QFile f(dhItem->devHelpFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << dhItem->devHelpFile() << endl; + return; + } + + QDomDocument doc; + if (!doc.setContent(&f)) + { + kdDebug() << "Not a valid devhelp file: " << dhItem->devHelpFile() << endl; + return; + } + f.close(); + + QString baseUrl = KURL(dhItem->devHelpFile()).directory(); + + QDomElement docEl = doc.documentElement(); + QDomElement chaptersEl = docEl.namedItem("functions").toElement(); + QDomElement childEl = chaptersEl.firstChild().toElement(); + while (!childEl.isNull()) + { + if (childEl.tagName() == "function") + { + QString name = childEl.attribute("name"); + QString url = childEl.attribute("link"); + + IndexItemProto *ii = new IndexItemProto(this, item, index, name, item->text(0)); + ii->addURL(KURL(baseUrl+"/"+url)); + } + childEl = childEl.nextSibling().toElement(); + } +} + +void DocDevHelpPlugin::createTOC(DocumentationCatalogItem* item) +{ + DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item); + if (!dhItem) + return; + + QFileInfo fi(dhItem->devHelpFile()); + + QFile f(dhItem->devHelpFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << dhItem->devHelpFile() << endl; + return; + } + + QDomDocument doc; + if (!doc.setContent(&f)) + { + kdDebug() << "Not a valid devhelp file: " << dhItem->devHelpFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement chaptersEl = docEl.namedItem("chapters").toElement(); + + QDomElement childEl = chaptersEl.lastChild().toElement(); + QString baseUrl = KURL(dhItem->devHelpFile()).directory(); + addTocSect(dhItem, childEl, baseUrl, true); +} + +void DocDevHelpPlugin::addTocSect(DocumentationItem *parent, QDomElement childEl, + QString baseUrl, bool book) +{ + while (!childEl.isNull()) + { + if ( (childEl.tagName() == "sub") || (childEl.tagName() == "chapter")) + { + QString name = childEl.attribute("name"); + QString url = childEl.attribute("link"); + + if (name.isEmpty() && url.contains("ix")) + name = "Index"; + + DocumentationItem *item = new DocumentationItem( + book ? DocumentationItem::Book : DocumentationItem::Document, parent, name); + item->setURL(KURL(baseUrl+"/"+url)); + + QDomElement grandchildEl = childEl.lastChild().toElement(); + addTocSect(item, grandchildEl, baseUrl); + } + childEl = childEl.previousSibling().toElement(); + } +} + +void DocDevHelpPlugin::setCatalogURL(DocumentationCatalogItem* item) +{ + DevHelpDocumentationCatalogItem *dhItem = dynamic_cast<DevHelpDocumentationCatalogItem *>(item); + if (!dhItem) + return; + + QFileInfo fi(dhItem->devHelpFile()); + + QFile f(dhItem->devHelpFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << dhItem->devHelpFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f)) + { + kdDebug(9002) << "Not a valid Devhelp file: " << dhItem->devHelpFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement titleEl = docEl.namedItem("book").toElement(); + + if (item->url().isEmpty()) + { + KURL url(fi.dirPath(true) + "/" + docEl.attribute("link", QString::null)); + item->setURL(url); + } +} + +ProjectDocumentationPlugin *DocDevHelpPlugin::projectDocumentationPlugin(ProjectDocType type) +{ + if (type == APIDocs) + return new ProjectDocumentationPlugin(this, type); + return DocumentationPlugin::projectDocumentationPlugin(type); +} + +#include "docdevhelpplugin.moc" diff --git a/parts/documentation/plugins/devhelp/docdevhelpplugin.desktop b/parts/documentation/plugins/devhelp/docdevhelpplugin.desktop new file mode 100644 index 00000000..14c3f700 --- /dev/null +++ b/parts/documentation/plugins/devhelp/docdevhelpplugin.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Type=Service +Name=DevHelpPlugin +Name[da]=DevHelp-plugin +Name[sk]=DevHelp modul +Name[sv]=DevHelp-insticksmodul +Name[ta]=Devஉதவி சொருகு +Name[zh_TW]=DevHelp 外掛程式 +Comment=Documentation plugin for DevHelp documentation +Comment[ca]=Connector de documentació per a documentació DevHelp +Comment[da]=Dokumentations-plugin for DevHelp-dokumentation +Comment[de]=Komponente für DevHelp-Dokumentation +Comment[el]=Πρόσθετο τεκμηρίωσης για τεκμηρίωση DevHelp +Comment[es]=Complemento de documentación para documentación DevHelp +Comment[et]=DevHelp dokumentatsiooni plugin +Comment[eu]=DevHelp dokumentaziorako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای مستندات DevHelp +Comment[fr]=Module externe de documentation pour la documentation DevHelp +Comment[gl]=Extensión de documentación para documentación DevHelp +Comment[hu]=Dokumentációmodul DevHelp-dokumentációhoz +Comment[it]=Plugin di documentazione per file DevHelp +Comment[ja]=DevHelp ドキュメンテーションのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk dokumentasi DevHelp +Comment[nds]=Dokmentatschoon-Moduul för DevHelp-Dokmentatschoon +Comment[ne]=DevHelp मिसिलीकरणका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin fvoor DevHelp documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie DevHelp +Comment[pt]='Plugin' para documentação DevHelp +Comment[pt_BR]=Plug-in de documentação para documento DevHelp +Comment[ru]=Модуль для просмотра документации DevHelp +Comment[sk]=Dokumentačný modul pre DevHelp dokumentáciu +Comment[sl]=Dokumentacijski vstavek za dokumentacijo DevHelp +Comment[sr]=Документациони прикључак за DevHelp документацију +Comment[sr@Latn]=Dokumentacioni priključak za DevHelp dokumentaciju +Comment[sv]=Dokumentationsinsticksmodul för DevHelp-dokumentation +Comment[ta]= DevHelp ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиш намудани DevHelp-и асоснок карда шуда +Comment[tr]=DevHelp belgelendirmesi için belgelendirme eklentisi +Comment[zh_CN]=DevHelp 文档的文档插件 +Comment[zh_TW]=DevHelp 文件外掛程式 +Exec=blubb +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=5 +X-KDE-Library=libdocdevhelpplugin diff --git a/parts/documentation/plugins/devhelp/docdevhelpplugin.h b/parts/documentation/plugins/devhelp/docdevhelpplugin.h new file mode 100644 index 00000000..ab0b0ece --- /dev/null +++ b/parts/documentation/plugins/devhelp/docdevhelpplugin.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCDEVHELPPLUGIN_H +#define DOCDEVHELPPLUGIN_H + +#include <qvaluestack.h> +#include <qdom.h> + +#include <kdevdocumentationplugin.h> + +class DocDevHelpPlugin: public DocumentationPlugin +{ + Q_OBJECT +public: + DocDevHelpPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocDevHelpPlugin(); + + virtual QString pluginName() const; + + virtual QString catalogTitle(const QString& url); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual void createTOC(DocumentationCatalogItem* item); + + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + virtual void autoSetupPlugin(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType type); + +protected: + void pushToScanStack(QValueStack<QString> &stack, const QString &value); + void scanDevHelpDir(const QString &path); + void addTocSect(DocumentationItem *parent, QDomElement childEl, QString baseUrl, bool book=false); +}; + +#endif diff --git a/parts/documentation/plugins/djvu/Makefile.am b/parts/documentation/plugins/djvu/Makefile.am new file mode 100644 index 00000000..716be5df --- /dev/null +++ b/parts/documentation/plugins/djvu/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libdocdjvuplugin.la +libdocdjvuplugin_la_LDFLAGS = $(all_libraries) +libdocdjvuplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la +noinst_HEADERS = docdjvuplugin.h +libdocdjvuplugin_la_SOURCES = docdjvuplugin.cpp +kde_services_DATA = docdjvuplugin.desktop diff --git a/parts/documentation/plugins/djvu/docdjvuplugin.cpp b/parts/documentation/plugins/djvu/docdjvuplugin.cpp new file mode 100644 index 00000000..0c53943e --- /dev/null +++ b/parts/documentation/plugins/djvu/docdjvuplugin.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2004 by Mathieu Chouinard * + * mathieu.chouinard@kdemail.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docdjvuplugin.h" + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> + +#include <kdevgenericfactory.h> + +static const KAboutData data("docdjvuplugin", I18N_NOOP("Djvu documentation plugin"), "1.0"); +typedef KDevGenericFactory<DocDjvuPlugin> DocDjvuPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocdjvuplugin, DocDjvuPluginFactory(&data) ) + +DocDjvuPlugin::DocDjvuPlugin(QObject* parent, const char* name, const QStringList args) + :DocumentationPlugin(DocDjvuPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(CustomDocumentationTitles | ProjectUserManual); + autoSetup(); +} + +DocDjvuPlugin::~DocDjvuPlugin() +{ +} + +bool DocDjvuPlugin::needRefreshIndex(DocumentationCatalogItem* item) +{ + return false; +} + +QString DocDjvuPlugin::pluginName() const +{ + return i18n("Djvu Documentation Collection"); +} + +DocumentationCatalogItem* DocDjvuPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + DocumentationCatalogItem *item = new DocumentationCatalogItem(this, contents, title); + item->setURL(KURL(url)); + return item; +} + +QPair<KFile::Mode, QString> DocDjvuPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "all/allfiles"); +} + +QString DocDjvuPlugin::catalogTitle(const QString& /*url*/) +{ + return QString::null; +} + +QStringList DocDjvuPlugin::fullTextSearchLocations() +{ + return QStringList(); +} + + +void DocDjvuPlugin::autoSetupPlugin() +{ + return; +} + +void DocDjvuPlugin::createIndex(IndexBox* /*index*/, DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocDjvuPlugin::createTOC(DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocDjvuPlugin::setCatalogURL(DocumentationCatalogItem* /*item*/) +{ + return; +} + +ProjectDocumentationPlugin *DocDjvuPlugin::projectDocumentationPlugin(ProjectDocType type) +{ + if (type == UserManual) + return new ProjectDocumentationPlugin(this, type); + return DocumentationPlugin::projectDocumentationPlugin(type); +} diff --git a/parts/documentation/plugins/djvu/docdjvuplugin.desktop b/parts/documentation/plugins/djvu/docdjvuplugin.desktop new file mode 100644 index 00000000..c88aa6a9 --- /dev/null +++ b/parts/documentation/plugins/djvu/docdjvuplugin.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Type=Service +Name=DocDjvuPlugin +Name[da]=DocDjvu-plugin +Name[ms]=PluginDocDjvu +Name[sk]=Doc Djvu modul +Name[sv]=DocDjvu-insticksmodul +Name[ta]=DocQt சொருகு +Name[zh_TW]=Djvu 文件外掛程式 +Exec=blubb +Comment=Documentation plugin for djvu format +Comment[ca]=Connector de documentació per al format djvu +Comment[da]=Dokumentations-plugin for djvu-dokumentation +Comment[de]=Komponente für das DjVu-Dokumentationsformat +Comment[el]=Πρόσθετο τεκμηρίωσης για τη μορφή djvu +Comment[es]=Complemento de documentación para el formato djvu +Comment[et]=Djvu vormingus dokumentatsiooni plugin +Comment[eu]=Djvu dokumentaziorako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای قالب djvu +Comment[fr]=Module externe de documentation pour le format djvu +Comment[gl]=Extensión de documentación para o formato djvu +Comment[hu]=Dokumentációmodul djvu formátumú dokumentációhoz +Comment[it]=Plugin documentazione per il formato djvu +Comment[ja]=djvu フォーマットのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk format djvu +Comment[nds]=Dokmentatschoon-Moduul för dat djvu-Dokmentatschoonformaat +Comment[ne]=djvu ढाँचाका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor het djvu-formaat +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie djvu +Comment[pt]='Plugin' para documentação no formato djvu +Comment[pt_BR]=Plug-in de documentação para o formato djvu +Comment[ru]=Модуль для просмотра документации в формате DJVU +Comment[sk]=Dokumentačný modul pre Djvu dokumentáciu +Comment[sr]=Документациони прикључак за djvu формат +Comment[sr@Latn]=Dokumentacioni priključak za djvu format +Comment[sv]=Dokumentationsinsticksmodul för djvu-format +Comment[ta]= CHM ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиш намудани ҳуҷҷатҳо дар формати DJVU +Comment[tr]=djvu biçimi için belgelendirme eklentisi +Comment[zh_CN]=djvu 格式文档插件 +Comment[zh_TW]=Djvu 格式文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=1 +X-KDE-Library=libdocdjvuplugin diff --git a/parts/documentation/plugins/djvu/docdjvuplugin.h b/parts/documentation/plugins/djvu/docdjvuplugin.h new file mode 100644 index 00000000..79bbf0ab --- /dev/null +++ b/parts/documentation/plugins/djvu/docdjvuplugin.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Mathieu Chouinard * + * mathieu.chouinard@kdemail.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCDJVUPLUGIN_H +#define DOCDVJUPLUGIN_H + +#include <kdevdocumentationplugin.h> + +class DocDjvuPlugin : public DocumentationPlugin { +public: + DocDjvuPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocDjvuPlugin(); + + virtual QString pluginName() const; + + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + + virtual void createTOC(DocumentationCatalogItem* item); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual QString catalogTitle(const QString& url); + + virtual void autoSetupPlugin(); + + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType type); +}; + +#endif diff --git a/parts/documentation/plugins/doxygen/Makefile.am b/parts/documentation/plugins/doxygen/Makefile.am new file mode 100644 index 00000000..eb6e2648 --- /dev/null +++ b/parts/documentation/plugins/doxygen/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libdocdoxygenplugin.la + +kde_services_DATA = docdoxygenplugin.desktop +libdocdoxygenplugin_la_SOURCES = docdoxygenplugin.cpp +noinst_HEADERS = docdoxygenplugin.h + + +libdocdoxygenplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libdocdoxygenplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la diff --git a/parts/documentation/plugins/doxygen/docdoxygenplugin.cpp b/parts/documentation/plugins/doxygen/docdoxygenplugin.cpp new file mode 100644 index 00000000..ddea5219 --- /dev/null +++ b/parts/documentation/plugins/doxygen/docdoxygenplugin.cpp @@ -0,0 +1,529 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docdoxygenplugin.h" + +#include <unistd.h> + +#include <qdom.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qdialog.h> +#include <qregexp.h> +#include <qvaluestack.h> + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include <urlutil.h> +#include <kdevgenericfactory.h> +#include <kdevplugininfo.h> + +#include "../../../../config.h" + +class DoxyDocumentationCatalogItem: public DocumentationCatalogItem +{ +public: + DoxyDocumentationCatalogItem(const QString &origUrl, DocumentationPlugin* plugin, + KListView *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_origUrl(origUrl) + { + } + DoxyDocumentationCatalogItem(const QString &origUrl, DocumentationPlugin* plugin, + DocumentationItem *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_origUrl(origUrl) + { + } + QString origUrl() const { return m_origUrl; } + +private: + QString m_origUrl; +}; + + +static const KDevPluginInfo data("docdoxygenplugin"); +typedef KDevGenericFactory<DocDoxygenPlugin> DocDoxygenPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocdoxygenplugin, DocDoxygenPluginFactory(data) ) + +DocDoxygenPlugin::DocDoxygenPlugin(QObject* parent, const char* name, const QStringList) + :DocumentationPlugin(DocDoxygenPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(Index | FullTextSearch | ProjectDocumentation | CustomDocumentationTitles ); + autoSetup(); +} + +DocDoxygenPlugin::~DocDoxygenPlugin() +{ +} + +QPair<KFile::Mode, QString> DocDoxygenPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "index.html *.tag"); +} + +QString DocDoxygenPlugin::catalogTitle(const QString& url) +{ + QFileInfo fi(url); + if (!fi.exists()) + return QString::null; + + if (fi.extension(false) == "html") + { + QFile f(url); + if (!f.open(IO_ReadOnly)) + return QString::null; + + QTextStream ts(&f); + QString contents = ts.read(); + QRegExp re(".*<title>(.*)</title>.*"); + re.setCaseSensitive(false); + re.search(contents); + return re.cap(1); + } + else if (fi.extension(false) == "tag") + { + QFile *f = 0; + QFile f1(fi.dirPath(true) + "/html/index.html"); + if (f1.open(IO_ReadOnly)) + f = &f1; + QFile f2(fi.dirPath(true) + "/index.html"); + if (f2.open(IO_ReadOnly)) + f = &f2; + if (f != 0) + { + QTextStream ts(f); + QString contents = ts.read(); + QRegExp re(".*<title>(.*)</title>.*"); + re.setCaseSensitive(false); + re.search(contents); + return re.cap(1); + } + } + return QString::null; +} + +QString DocDoxygenPlugin::pluginName() const +{ + return i18n("Doxygen Documentation Collection"); +} + +QStringList DocDoxygenPlugin::fullTextSearchLocations() +{ + QStringList locs; + + QMap<QString, QString> entryMap = config->entryMap("Locations"); + + for (QMap<QString, QString>::const_iterator it = entryMap.begin(); + it != entryMap.end(); ++it) + { + config->setGroup("Search Settings"); + if (config->readBoolEntry(it.key(), false)) + { + config->setGroup("Locations"); + QFileInfo fi(config->readPathEntry(it.key())); + locs << fi.dirPath(true); + } + } + + return locs; +} + +void DocDoxygenPlugin::setCatalogURL(DocumentationCatalogItem* item) +{ + if (item->url().url().endsWith("tag")) + { + QFileInfo fi(item->url().directory(false) + "html/index.html"); + if (fi.exists()) + { + item->setURL(KURL::fromPathOrURL(fi.absFilePath())); + return; + } + QFileInfo fi2(item->url().directory(false) + "index.html"); + if (fi2.exists()) + { + item->setURL(KURL::fromPathOrURL(fi2.absFilePath())); + return; + } + item->setURL(KURL()); + } +} + +bool DocDoxygenPlugin::needRefreshIndex(DocumentationCatalogItem* item) +{ + DoxyDocumentationCatalogItem *doxyItem = dynamic_cast<DoxyDocumentationCatalogItem*>(item); + if (!doxyItem) + return false; + + QFileInfo fi(doxyItem->origUrl()); + config->setGroup("Index"); + if (fi.lastModified() > config->readDateTimeEntry(item->text(0), new QDateTime())) + { + kdDebug() << "need rebuild index for " << item->text(0) << endl; + config->writeEntry(item->text(0), fi.lastModified()); + return true; + } + else + return false; +} + +void DocDoxygenPlugin::autoSetupPlugin() +{ + autoSetupDocs(KDELIBS_DOXYDIR, "en/kdelibs-apidocs", "The KDE API Reference (The KDE API Reference)"); + autoSetupDocs("", "en/kdevelop-apidocs", "The KDevelop Platform API Documentation (KDevelop)"); + +} + +void DocDoxygenPlugin::autoSetupDocs(const QString &defaultDir, const QString &searchDir, + const QString &name) +{ + QString doxyDocDir(defaultDir); + doxyDocDir = URLUtil::envExpand(doxyDocDir); + if (doxyDocDir.isEmpty()) + { + QStringList apiDirs = DocDoxygenPluginFactory::instance()->dirs()->findDirs("html", searchDir); + for (QStringList::const_iterator it = apiDirs.begin(); it != apiDirs.end(); ++it ) + { + doxyDocDir = *it; + QString indexFile = doxyDocDir + "index.html"; + if (QFile::exists(indexFile)) + { + doxyDocDir = doxyDocDir + "/" + searchDir; + break; + } + doxyDocDir = ""; + } + } + if (!doxyDocDir.isEmpty()) + { + config->setGroup("Search Settings"); + config->writeEntry(name, true); + config->setGroup("Index Settings"); + config->writeEntry(name, true); + config->setGroup("Locations"); + config->writePathEntry(name, doxyDocDir + QString("/index.html")); + } +} + +void DocDoxygenPlugin::createIndex(IndexBox* index, DocumentationCatalogItem* item) +{ + QFileInfo fi(item->url().path()); + if (!fi.exists()) + return; + + DoxyDocumentationCatalogItem *doxyItem = dynamic_cast<DoxyDocumentationCatalogItem*>(item); + if (!doxyItem) + return; + + //doxygen documentation mode (if catalog points to a .tag) + if (doxyItem->origUrl().endsWith("tag")) + { + QString htmlUrl; + QFileInfo fi2(item->url().directory(false) + "index.html"); + if (fi2.exists()) + htmlUrl = fi2.dirPath(true) + "/"; + QFileInfo fi(item->url().directory(false) + "html/index.html"); + if (fi.exists()) + htmlUrl = fi.dirPath(true) + "/"; + + createBookIndex(doxyItem->origUrl(), index, item, htmlUrl); + } + + //KDE doxygen documentation mode (if catalog points to a index.html) + QDir d; + QValueStack<QString> dirStack; + dirStack.push(fi.dirPath(true)); + do { + d.setPath(dirStack.pop()); + if (!d.exists()) + continue; + + const QFileInfoList *dirEntries = d.entryInfoList(); + if (!dirEntries) continue; + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) + { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == ".." || fileName == "common" || fileName == "html") + continue; + if (it.current()->isDir()) + dirStack.push(it.current()->absFilePath()); + } + + if (QFile::exists(d.absPath() + "/html/index.html")) + createBookIndex(d.absPath() + "/" + d.dirName() + ".tag", index, item); + } while (!dirStack.isEmpty()); +} + +void DocDoxygenPlugin::createTOC(DocumentationCatalogItem* item) +{ + QFileInfo fi(item->url().path()); + if (!fi.exists()) + return; + + DoxyDocumentationCatalogItem *doxyItem = dynamic_cast<DoxyDocumentationCatalogItem*>(item); + if (!doxyItem) + return; + + //doxygen documentation mode (if catalog points to a .tag) + if (doxyItem->origUrl().endsWith("tag")) + { + QString htmlUrl; + QFileInfo fi2(item->url().directory(false) + "index.html"); + if (fi2.exists()) + htmlUrl = fi2.dirPath(true) + "/"; + QFileInfo fi(item->url().directory(false) + "html/index.html"); + if (fi.exists()) + htmlUrl = fi.dirPath(true) + "/"; + if (!htmlUrl.isEmpty()) + createBookTOC(item, doxyItem->origUrl(), htmlUrl); + } + + //KDE doxygen documentation mode (if catalog points to a index.html) + QDir d; + QValueStack<QString> dirStack; + dirStack.push(fi.dirPath(true)); + do { + d.setPath(dirStack.pop()); + if (!d.exists()) + continue; + + const QFileInfoList *dirEntries = d.entryInfoList(); + if (!dirEntries) continue; + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) + { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == ".." || fileName == "common" || fileName == "html") + continue; + if (it.current()->isDir()) + dirStack.push(it.current()->absFilePath()); + } + + if (QFile::exists(d.absPath() + "/html/index.html")) + { + DocumentationItem *docItem = new DocumentationItem(DocumentationItem::Book, item, d.dirName()); + docItem->setURL(KURL(d.absPath() + "/html/index.html")); + docItem->setExpandable(true); + createBookTOC(docItem); + } + } while (!dirStack.isEmpty()); +} + +DocumentationCatalogItem *DocDoxygenPlugin::createCatalog(KListView *contents, const QString &title, const QString &url) +{ + kdDebug() << "DocDoxygenPlugin::createCatalog: url=" << url << endl; + DocumentationCatalogItem *item = new DoxyDocumentationCatalogItem(url, this, contents, title); + item->setURL(url); + return item; +} + +void DocDoxygenPlugin::createBookTOC(DocumentationItem *item, const QString &tagUrl, const QString &baseHtmlUrl) +{ + QString tagName; + if (tagUrl.isEmpty()) + tagName = item->url().upURL().directory(false) + item->text(0) + ".tag"; + else + tagName = tagUrl; + + QString baseUrl; + if (baseHtmlUrl.isEmpty()) + baseUrl = item->url().directory(false); + else + baseUrl = baseHtmlUrl; + + //@todo list html files in the directory if tag was not found + if (!QFile::exists(tagName)) + return; + + QStringList tagFileList; + if (tagName.endsWith(".tag")) + tagFileList = tagFiles(QFileInfo(tagName).dirPath() + "/"); + else + tagFileList += tagName; + + QStringList::ConstIterator end = tagFileList.constEnd(); + for (QStringList::ConstIterator it = tagFileList.constBegin(); it != end; ++it) + { + QFile f(*it); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not open tag file: " << f.name() << endl; + return; + } + + QDomDocument dom; + if (!dom.setContent(&f) || dom.documentElement().nodeName() != "tagfile") + { + kdDebug(9002) << "No valid tag file" << endl; + return; + } + f.close(); + + QDomElement docEl = dom.documentElement(); + + QDomElement childEl = docEl.lastChild().toElement(); + while (!childEl.isNull()) + { + if (childEl.tagName() == "compound" && childEl.attribute("kind") == "class") + { + QString classname = childEl.namedItem("name").firstChild().toText().data(); + QString filename = childEl.namedItem("filename").firstChild().toText().data(); + + if (QFile::exists(baseUrl + filename)) + { + DocumentationItem *docItem = new DocumentationItem(DocumentationItem::Document, + item, classname); + docItem->setURL(KURL(baseUrl + filename)); + } + } + childEl = childEl.previousSibling().toElement(); + } + } +} + +void DocDoxygenPlugin::createBookIndex(const QString &tagfile, IndexBox* index, DocumentationCatalogItem* item, const QString &baseHtmlUrl) +{ + QString tagName = tagfile; + kdDebug() << tagfile << endl; + if (!QFile::exists(tagName)) + return; + QString prefix = baseHtmlUrl.isEmpty() ? KURL(tagfile).directory(false) + "html/" : baseHtmlUrl; + + QStringList tagFileList = tagFiles(QFileInfo(tagName).dirPath() + "/"); + + QStringList::ConstIterator end = tagFileList.constEnd(); + for (QStringList::ConstIterator it = tagFileList.constBegin(); it != end; ++it) + { + QFile f(*it); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not open tag file: " << f.name() << endl; + return; + } + + QDomDocument dom; + if (!dom.setContent(&f) || dom.documentElement().nodeName() != "tagfile") + { + kdDebug(9002) << "No valid tag file" << endl; + return; + } + f.close(); + + QDomElement docEl = dom.documentElement(); + createIndexFromTag(dom, index, item, docEl, prefix); + } +} + +void DocDoxygenPlugin::createIndexFromTag(QDomDocument &dom, IndexBox *index, + DocumentationCatalogItem *item, QDomElement &parentEl, const QString &prefix) +{ + QDomElement docEl = parentEl; + + QDomElement childEl = docEl.firstChild().toElement(); + while (!childEl.isNull()) + { + if (childEl.tagName() == "compound" && + ((childEl.attribute("kind") == "class") + || (childEl.attribute("kind") == "struct") + || (childEl.attribute("kind") == "namespace") )) + { + QString classname = childEl.namedItem("name").firstChild().toText().data(); + QString filename = childEl.namedItem("filename").firstChild().toText().data(); + + IndexItemProto *indexItem = new IndexItemProto(this, item, index, classname, + i18n("%1 Class Reference").arg(classname)); + indexItem->addURL(KURL(prefix + filename)); + + createIndexFromTag(dom, index, item, childEl, prefix + filename); + } + else if ((childEl.tagName() == "member") && + ((childEl.attribute("kind") == "function") + || (childEl.attribute("kind") == "slot") + || (childEl.attribute("kind") == "signal") )) + { + QString classname = parentEl.namedItem("name").firstChild().toText().data(); + QString membername = childEl.namedItem("name").firstChild().toText().data(); + QString anchor = childEl.namedItem("anchor").firstChild().toText().data(); + QString arglist = childEl.namedItem("arglist").firstChild().toText().data(); + + if (classname != membername) + { + IndexItemProto *indexItem = new IndexItemProto(this, item, index, membername,i18n("%1::%2%3 Member Reference").arg(classname).arg(membername).arg(arglist)); + indexItem->addURL(KURL(prefix + "#" + anchor)); + } + } + childEl = childEl.nextSibling().toElement(); + } +} + +ProjectDocumentationPlugin *DocDoxygenPlugin::projectDocumentationPlugin(ProjectDocType type) +{ + if (type == APIDocs) + return new ProjectDocumentationPlugin(this, type); + return DocumentationPlugin::projectDocumentationPlugin(type); +} + +QStringList DocDoxygenPlugin::tagFiles(const QString& path, int level) +{ + QStringList r; + QDir dir(path); + if (level > 10) return r; + if (!dir.isReadable()) return r; + if (!dir.exists()) return r; + + QStringList dirList; + QStringList fileList; + QStringList::Iterator it; + + dir.setFilter ( QDir::Dirs); + dirList = dir.entryList(); + + dirList.remove("."); + dirList.remove(".."); + + dir.setFilter(QDir::Files | QDir::Hidden | QDir::System); + fileList = dir.entryList(); + QStringList::Iterator end = dirList.end(); + for ( it = dirList.begin(); it != end; ++it ) + { + QString name = *it; + if (QFileInfo( dir, *it ).isSymLink()) + continue; + r += tagFiles(path + name + "/", level + 1 ); + } + + QStringList::Iterator fend = fileList.end(); + for ( it = fileList.begin(); it != fend; ++it ) + { + QString name = *it; + QFileInfo fi( dir, *it ); + if (fi.isSymLink() || !fi.isFile()) + continue; + + if (QDir::match(QString("*.tag"), name)) + r += (path+name); + } + + return r; +} + +#include "docdoxygenplugin.moc" diff --git a/parts/documentation/plugins/doxygen/docdoxygenplugin.desktop b/parts/documentation/plugins/doxygen/docdoxygenplugin.desktop new file mode 100644 index 00000000..57bb4262 --- /dev/null +++ b/parts/documentation/plugins/doxygen/docdoxygenplugin.desktop @@ -0,0 +1,45 @@ +[Desktop Entry] +Type=Service +Name=DocDoxygenPlugin +Name[da]=DocDoxygen-plugin +Name[ms]=PluginDocDoxygen +Name[sk]=Doc Doxygen modul +Name[sv]=Doxygen-dokumentationsinsticksmodul +Name[ta]=DocDoxygen சொருகு +Name[zh_TW]=Doxygen 文件外掛程式 +Exec=blubb +Comment=Documentation plugin for Doxygen documentation +Comment[ca]=Connector de documentació per a documentació Doxygen +Comment[da]=Dokumentations-plugin for Doxygen-dokumentation +Comment[de]=Komponente für Doxygen-Dokumentation +Comment[el]=Πρόσθετο τεκμηρίωσης για τεκμηρίωση τύπου Doxygen +Comment[es]=Complemento de documentación para Doxygen +Comment[et]=Doxygeni dokumentatsiooni plugin +Comment[eu]=Doxygen dokumentaziorako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای مستندات Doxygen +Comment[fr]=Module externe de documentation pour la documentation Doxygen +Comment[gl]=Extensión de documentación para documentación Doxygen +Comment[hu]=Dokumentációmodul Doxygen-dokumentációhoz +Comment[it]=Plugin di documentazione per file di Doxygen +Comment[ja]=Doxygen ドキュメンテーションのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk dokumentasi Doxygen +Comment[nds]=Dokmentatschoon-Moduul för Doxygen-Dokmentatschoon +Comment[ne]=Doxygen मिसिलीकरणका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor Doxygen documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie Doxygen +Comment[pt]='Plugin' para documentação Doxygen +Comment[pt_BR]=Plug-in de documentação para documento Doxygen +Comment[ru]=Модуль для просмотра документации Doxygen +Comment[sk]=Dokumentačný modul pre Doxygen dokumentáciu +Comment[sl]=Dokumentacijski vstavek za dokumentacijo Doxygen +Comment[sr]=Документациони прикључак за Doxygen документацију +Comment[sr@Latn]=Dokumentacioni priključak za Doxygen dokumentaciju +Comment[sv]=Dokumentationsinsticksmodul för Doxygen-dokumentation +Comment[ta]= Doxygen ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиш намудани ҳуҷҷатҳо дар Doxygen +Comment[tr]=Doxygen belgelendirmesi için belgelendirme eklentisi +Comment[zh_CN]=Doxygen 文档的文档插件 +Comment[zh_TW]=Doxygen 文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=5 +X-KDE-Library=libdocdoxygenplugin diff --git a/parts/documentation/plugins/doxygen/docdoxygenplugin.h b/parts/documentation/plugins/doxygen/docdoxygenplugin.h new file mode 100644 index 00000000..fbd7e56f --- /dev/null +++ b/parts/documentation/plugins/doxygen/docdoxygenplugin.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCDOXYGENPLUGIN_H +#define DOCDOXYGENPLUGIN_H + +#include <kdevdocumentationplugin.h> + +class QDomDocument; +class QDomElement; + +class DocDoxygenPlugin: public DocumentationPlugin +{ + Q_OBJECT +public: + DocDoxygenPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocDoxygenPlugin(); + + virtual QString pluginName() const; + + virtual DocumentationCatalogItem *createCatalog(KListView *contents, const QString &title, const QString &url); + + virtual void createTOC(DocumentationCatalogItem* item); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual QString catalogTitle(const QString& url); + + virtual void autoSetupPlugin(); + + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType type); + +protected: + void createBookTOC(DocumentationItem* item, const QString &tagUrl = QString::null, + const QString &baseHtmlUrl = QString::null); + void createBookIndex(const QString &tagfile, IndexBox* index, DocumentationCatalogItem* item, const QString &baseHtmlUrl = QString::null); + + void createIndexFromTag(QDomDocument &dom, IndexBox* index, DocumentationCatalogItem* item, + QDomElement &parentEl, const QString &prefix); + + void autoSetupDocs(const QString &defaultDir, const QString &searchDir, + const QString &name); + + /** + * Returns all the tag files from a directory and its subdirectories. + * @param startDir the directory to start with + * @param level the depth of the current search + * @return a list with the absolute path to the ".tag" files in startDir + */ + QStringList tagFiles(const QString &startDir, int level = 0); +}; + + +#endif diff --git a/parts/documentation/plugins/kdevtoc/Makefile.am b/parts/documentation/plugins/kdevtoc/Makefile.am new file mode 100644 index 00000000..a40dd995 --- /dev/null +++ b/parts/documentation/plugins/kdevtoc/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libdockdevtocplugin.la +libdockdevtocplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +kde_services_DATA = dockdevtocplugin.desktop +noinst_HEADERS = dockdevtocplugin.h +libdockdevtocplugin_la_SOURCES = dockdevtocplugin.cpp +libdockdevtocplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la diff --git a/parts/documentation/plugins/kdevtoc/dockdevtocplugin.cpp b/parts/documentation/plugins/kdevtoc/dockdevtocplugin.cpp new file mode 100644 index 00000000..65ebf35f --- /dev/null +++ b/parts/documentation/plugins/kdevtoc/dockdevtocplugin.cpp @@ -0,0 +1,277 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "dockdevtocplugin.h" + +#include <unistd.h> + +#include <qdom.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qdialog.h> + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> +#include <kstandarddirs.h> + +#include <urlutil.h> +#include <kdevgenericfactory.h> +#include <kdevplugininfo.h> + +#include "../../../../config.h" + +class TOCDocumentationCatalogItem: public DocumentationCatalogItem +{ +public: + TOCDocumentationCatalogItem(const QString &tocFile, DocumentationPlugin* plugin, + KListView *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_tocFile(tocFile) + { + } + TOCDocumentationCatalogItem(const QString &tocFile, DocumentationPlugin* plugin, + DocumentationItem *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_tocFile(tocFile) + { + } + QString tocFile() const { return m_tocFile; } + +private: + QString m_tocFile; +}; + + +static const KDevPluginInfo data("dockdevtocplugin"); +typedef KDevGenericFactory<DocKDevTOCPlugin> DocKDevTOCPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdockdevtocplugin, DocKDevTOCPluginFactory(data) ) + +DocKDevTOCPlugin::DocKDevTOCPlugin(QObject* parent, const char* name, + const QStringList /*args*/) + :DocumentationPlugin(DocKDevTOCPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(Index); + autoSetup(); +} + +DocKDevTOCPlugin::~DocKDevTOCPlugin() +{ +} + +QString DocKDevTOCPlugin::pluginName() const +{ + return i18n("KDevelopTOC Documentation Collection"); +} + +DocumentationCatalogItem* DocKDevTOCPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + return new TOCDocumentationCatalogItem(url, this, contents, title); +} + +QPair<KFile::Mode, QString> DocKDevTOCPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "*.toc"); +} + +QString DocKDevTOCPlugin::catalogTitle(const QString& url) +{ + QFileInfo fi(url); + if (!fi.exists()) + return QString::null; + + QFile f(url); + if (!f.open(IO_ReadOnly)) + return QString::null; + + QDomDocument doc; + if (!doc.setContent(&f) || (doc.doctype().name() != "kdeveloptoc")) + return QString::null; + f.close(); + + QDomElement titleEl = doc.documentElement().namedItem("title").toElement(); + + return titleEl.firstChild().toText().data(); +} + + +QStringList DocKDevTOCPlugin::fullTextSearchLocations() +{ + return QStringList(); +} + +bool DocKDevTOCPlugin::needRefreshIndex(DocumentationCatalogItem* /*item*/) +{ + return false; +} + +void DocKDevTOCPlugin::autoSetupPlugin() +{ + QStringList tocsDir = DocKDevTOCPluginFactory::instance()->dirs()->findAllResources("data", "kdevdocumentation/tocs/*.toc"); + + for (QStringList::const_iterator it = tocsDir.begin(); it != tocsDir.end(); ++it) + { + config->setGroup("Locations"); + config->writePathEntry(catalogTitle(*it), *it); + } +} + +void DocKDevTOCPlugin::createIndex(IndexBox* index, DocumentationCatalogItem* item) +{ + TOCDocumentationCatalogItem *tocItem = dynamic_cast<TOCDocumentationCatalogItem *>(item); + if (!tocItem) + return; + + QFileInfo fi(tocItem->tocFile()); + + QFile f(tocItem->tocFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << tocItem->tocFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f) || doc.doctype().name() != "kdeveloptoc") + { + kdDebug(9002) << "Not a valid kdeveloptoc file: " << tocItem->tocFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement baseEl = docEl.namedItem("base").toElement(); + + QString base; + if (!baseEl.isNull()) + base = baseEl.attribute("href", QString::null); + + QDomElement indexEl = docEl.namedItem("index").toElement(); + QDomElement childEl = indexEl.firstChild().toElement(); + while (!childEl.isNull()) + { + if (childEl.tagName() == "entry") + { + QString name = childEl.attribute("name"); + QString url = childEl.attribute("url"); + + IndexItemProto *ii = new IndexItemProto(this, item, index, name, item->text(0)); + ii->addURL(KURL(constructURL(base, url))); + } + childEl = childEl.nextSibling().toElement(); + } +} + +void DocKDevTOCPlugin::createTOC(DocumentationCatalogItem* item) +{ + TOCDocumentationCatalogItem *tocItem = dynamic_cast<TOCDocumentationCatalogItem *>(item); + if (!tocItem) + return; + + QFileInfo fi(tocItem->tocFile()); + + QFile f(tocItem->tocFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << tocItem->tocFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f) || doc.doctype().name() != "kdeveloptoc") + { + kdDebug(9002) << "Not a valid kdeveloptoc file: " << tocItem->tocFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement baseEl = docEl.namedItem("base").toElement(); + + QString base; + if (!baseEl.isNull()) + base = baseEl.attribute("href", QString::null); + + QDomElement childEl = docEl.lastChild().toElement(); + addTocSect(tocItem, childEl, base, 1); +} + +void DocKDevTOCPlugin::addTocSect(DocumentationItem *parent, QDomElement childEl, const QString &base, uint level) +{ + while (!childEl.isNull()) + { + if (childEl.tagName() == QString("tocsect%1").arg(level)) + { + QString name = childEl.attribute("name"); + QString url = childEl.attribute("url"); + + DocumentationItem *item = new DocumentationItem(level == 1 ? DocumentationItem::Book : DocumentationItem::Document, parent, name); + item->setURL(KURL(constructURL(base, url))); + + QDomElement grandchildEl = childEl.lastChild().toElement(); + addTocSect(item, grandchildEl, base, level+1); + } + childEl = childEl.previousSibling().toElement(); + } +} + +void DocKDevTOCPlugin::setCatalogURL(DocumentationCatalogItem* item) +{ + TOCDocumentationCatalogItem *tocItem = dynamic_cast<TOCDocumentationCatalogItem *>(item); + if (!tocItem) + return; + + QFileInfo fi(tocItem->tocFile()); + + QFile f(tocItem->tocFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << tocItem->tocFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f) || doc.doctype().name() != "kdeveloptoc") + { + kdDebug(9002) << "Not a valid kdeveloptoc file: " << tocItem->tocFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement baseEl = docEl.namedItem("base").toElement(); + + if (item->url().isEmpty()) + { + if (baseEl.isNull()) + item->setURL(KURL()); + else + item->setURL(KURL(constructURL(baseEl.attribute("href", QString::null), + baseEl.attribute("url", QString::null)))); + } +} + +QString DocKDevTOCPlugin::constructURL(const QString &base, const QString &url) +{ + if (base.isEmpty() && !url.isEmpty()) + return url; + if (!url.isEmpty()) + return base.endsWith("/") ? base + url : base + "/" + url; + else + return base; +} + +#include "dockdevtocplugin.moc" diff --git a/parts/documentation/plugins/kdevtoc/dockdevtocplugin.desktop b/parts/documentation/plugins/kdevtoc/dockdevtocplugin.desktop new file mode 100644 index 00000000..d665e9af --- /dev/null +++ b/parts/documentation/plugins/kdevtoc/dockdevtocplugin.desktop @@ -0,0 +1,43 @@ +[Desktop Entry] +Type=Service +Name=DocKDevTOCPlugin +Name[da]=DocKDevTOC-plugin +Name[sk]=Doc KDevTOC modul +Name[sv]=KDevelop innehållsförteckning-dokumentationsinsticksmodul +Name[ta]=DocKDevTOC சொருகு +Name[zh_TW]=KDevelop 目錄文件外掛程式 +Exec=blubb +Comment=Documentation plugin for KDevelopTOC documentation +Comment[ca]=Connector de documentació per a documentació KDevelopTOC +Comment[da]=Dokumentations-plugin for KDevelopTOC-dokumentation +Comment[de]=Komponente für KDevelopTOC-Dokumentation +Comment[el]=Πρόσθετο τεκμηρίωσης για τεκμηρίωση τύπου KDevelopTOC +Comment[es]=Complemento de documentación para KDevelopTOC +Comment[et]=KDevelopTOC dokumentatsiooni plugin +Comment[eu]=KDevelopTOC dokumentaziorako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای مستندات KDevelopTOC +Comment[fr]=Module externe de documentation pour la documentation KDevelopTOC +Comment[gl]=Extensión de documentación para documentación KDevelopTOC +Comment[hu]=Dokumentációmodul KDevelopTOC-dokumentációhoz +Comment[it]=Plugin di documentazione per file di KDevelopTOC +Comment[ja]=KDevelopTOC ドキュメンテーションのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk dokumentasi KDevelopTOC +Comment[nds]=Dokmentatschoon-Moduul för KDevelopTOC-Dokmentatschoon +Comment[ne]=KDevelopTOC मिसिलीकरणका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin for KDevelopTOC documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie KDevelopTOC +Comment[pt]='Plugin' para documentação KDevelopTOC +Comment[pt_BR]=Plug-in de documentação para document TOC do KDevelop +Comment[ru]=Модуль для просмотра KDevelopTOC +Comment[sk]=Dokumentačný modul pre KDevelopTOC dokumentáciu +Comment[sr]=Документациони прикључак за KDevelopTOC документацију +Comment[sr@Latn]=Dokumentacioni priključak za KDevelopTOC dokumentaciju +Comment[sv]=Dokumentationsinsticksmodul för KDevelop innehållsförteckningsdokumentation +Comment[ta]= KDevelopTOC ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиши KDevelopTOC +Comment[tr]=KDevelopTOC belgelendirmesi için belgelendirme eklentisi +Comment[zh_CN]=KDevelopTOC 文档的文档插件 +Comment[zh_TW]=KDevelop 目錄文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=5 +X-KDE-Library=libdockdevtocplugin diff --git a/parts/documentation/plugins/kdevtoc/dockdevtocplugin.h b/parts/documentation/plugins/kdevtoc/dockdevtocplugin.h new file mode 100644 index 00000000..4a958473 --- /dev/null +++ b/parts/documentation/plugins/kdevtoc/dockdevtocplugin.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCKDEVTOCPLUGIN_H +#define DOCKDEVTOCPLUGIN_H + +#include <qdom.h> + +#include <kdevdocumentationplugin.h> + +class DocKDevTOCPlugin : public DocumentationPlugin +{ + Q_OBJECT +public: + DocKDevTOCPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocKDevTOCPlugin(); + + virtual QString pluginName() const; + + virtual QString catalogTitle(const QString& url); + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + virtual void createTOC(DocumentationCatalogItem* item); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString > catalogLocatorProps(); + virtual void autoSetupPlugin(); + +protected: + void addTocSect(DocumentationItem *parent, QDomElement childEl, const QString &base, uint level); + static QString constructURL(const QString &base, const QString &url) ; +}; + +#endif diff --git a/parts/documentation/plugins/pdb/Makefile.am b/parts/documentation/plugins/pdb/Makefile.am new file mode 100644 index 00000000..4d015e3c --- /dev/null +++ b/parts/documentation/plugins/pdb/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libdocpdbplugin.la +libdocpdbplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libdocpdbplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la +noinst_HEADERS = docpdbplugin.h +libdocpdbplugin_la_SOURCES = docpdbplugin.cpp +kde_services_DATA = docpdbplugin.desktop diff --git a/parts/documentation/plugins/pdb/docpdbplugin.cpp b/parts/documentation/plugins/pdb/docpdbplugin.cpp new file mode 100644 index 00000000..5c2f68c7 --- /dev/null +++ b/parts/documentation/plugins/pdb/docpdbplugin.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2004 by Mathieu Chouinard * + * mathieu.chouinard@kdemail.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docpdbplugin.h" + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> + +#include <kdevgenericfactory.h> + +static const KAboutData data("docpdbplugin", I18N_NOOP("PalmDoc documentation plugin"), "1.0"); +typedef KDevGenericFactory<DocPDBPlugin> DocPDBPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocpdbplugin, DocPDBPluginFactory(&data) ) + +DocPDBPlugin::DocPDBPlugin(QObject* parent, const char* name, const QStringList args) + :DocumentationPlugin(DocPDBPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(CustomDocumentationTitles | ProjectUserManual); + autoSetup(); +} + +DocPDBPlugin::~DocPDBPlugin() +{ +} + +bool DocPDBPlugin::needRefreshIndex(DocumentationCatalogItem* item) +{ + return false; +} + +QString DocPDBPlugin::pluginName() const +{ + return i18n("PalmDoc Documentation Collection"); +} + +DocumentationCatalogItem* DocPDBPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + DocumentationCatalogItem *item = new DocumentationCatalogItem(this, contents, title); + item->setURL(KURL(url)); + return item; +} + +QPair<KFile::Mode, QString> DocPDBPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "all/allfiles"); +} + +QString DocPDBPlugin::catalogTitle(const QString& /*url*/) +{ + return QString::null; +} + +QStringList DocPDBPlugin::fullTextSearchLocations() +{ + return QStringList(); +} + + +void DocPDBPlugin::autoSetupPlugin() +{ + return; +} + +void DocPDBPlugin::createIndex(IndexBox* /*index*/, DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocPDBPlugin::createTOC(DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocPDBPlugin::setCatalogURL(DocumentationCatalogItem* /*item*/) +{ + return; +} + +ProjectDocumentationPlugin *DocPDBPlugin::projectDocumentationPlugin(ProjectDocType type) +{ + if (type == UserManual) + return new ProjectDocumentationPlugin(this, type); + return DocumentationPlugin::projectDocumentationPlugin(type); +} diff --git a/parts/documentation/plugins/pdb/docpdbplugin.desktop b/parts/documentation/plugins/pdb/docpdbplugin.desktop new file mode 100644 index 00000000..76630793 --- /dev/null +++ b/parts/documentation/plugins/pdb/docpdbplugin.desktop @@ -0,0 +1,43 @@ +[Desktop Entry] +Type=Service +Name=DocPDBPlugin +Name[da]=DocPDB-plugin +Name[sk]=Doc PDB modul +Name[sv]=DocPDB-insticksmodul +Name[ta]=DocQt சொருகு +Name[zh_TW]=PDB 文件外掛程式 +Exec=blubb +Comment=Documentation plugin for Palmdoc format +Comment[ca]=Connector de documentació per al format Palmdoc +Comment[da]=Dokumentations-plugin for Palmdoc-format +Comment[de]=Komponente für das Palmdoc-Dokumentationsformat +Comment[el]=Πρόσθετο τεκμηρίωσης για τη μορφή Palmdoc +Comment[es]=Complemento de documentación para el formato Palmdoc +Comment[et]=PalmDOC-vormingus dokumentatsiooni plugin +Comment[eu]=Palmdoc formaturako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای قالب Palmdoc +Comment[fr]=Module externe de documentation pour le format Palmdoc +Comment[gl]=Extensión de documentación para o formato Palmdoc +Comment[hu]=Dokumentációmodul Palmdoc formátumú dokumentációhoz +Comment[it]=Plugin di documentazione per il formato Palmdoc +Comment[ja]=Palmdoc フォーマットのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk format Palmdoc +Comment[nds]=Komponente för dat Palmdoc-Dokmentatschoonformaat +Comment[ne]=Palmdoc ढाँचाका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor Palmdoc documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie Palmdoc +Comment[pt]='Plugin' para documentação no formato Palmdoc +Comment[pt_BR]=Plug-in de documentação para o formato Palmdoc +Comment[ru]=Модуль для просмотра документации в формате Palmdoc +Comment[sk]=Dokumentačný modul pre Palmdoc formát +Comment[sr]=Документациони прикључак за Palmdoc формат +Comment[sr@Latn]=Dokumentacioni priključak za Palmdoc format +Comment[sv]=Dokumentationsinsticksmodul för Palmdoc-format +Comment[ta]= CHM ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиш намудани ҳуҷҷатҳо дар формати Palmdoc +Comment[tr]=Palmdoc biçimi için belgelendirme eklentisi +Comment[zh_CN]=Palmdoc 格式的文档插件 +Comment[zh_TW]=Palmdoc 格式文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=1 +X-KDE-Library=libdocpdbplugin diff --git a/parts/documentation/plugins/pdb/docpdbplugin.h b/parts/documentation/plugins/pdb/docpdbplugin.h new file mode 100644 index 00000000..cdb9e90f --- /dev/null +++ b/parts/documentation/plugins/pdb/docpdbplugin.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Mathieu Chouinard * + * mathieu.chouinard@kdemail.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCPDBPLUGIN_H +#define DOCPDBPLUGIN_H + +#include <kdevdocumentationplugin.h> + +class DocPDBPlugin : public DocumentationPlugin { +public: + DocPDBPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocPDBPlugin(); + + virtual QString pluginName() const; + + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + + virtual void createTOC(DocumentationCatalogItem* item); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual QString catalogTitle(const QString& url); + + virtual void autoSetupPlugin(); + + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType type); +}; + +#endif diff --git a/parts/documentation/plugins/pdf/Makefile.am b/parts/documentation/plugins/pdf/Makefile.am new file mode 100644 index 00000000..8d9617d2 --- /dev/null +++ b/parts/documentation/plugins/pdf/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = libdocpdfplugin.la +libdocpdfplugin_la_LDFLAGS = $(all_libraries) +libdocpdfplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la +noinst_HEADERS = docpdfplugin.h +libdocpdfplugin_la_SOURCES = docpdfplugin.cpp +kde_services_DATA = docpdfplugin.desktop diff --git a/parts/documentation/plugins/pdf/docpdfplugin.cpp b/parts/documentation/plugins/pdf/docpdfplugin.cpp new file mode 100644 index 00000000..02bac373 --- /dev/null +++ b/parts/documentation/plugins/pdf/docpdfplugin.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2004 by Mathieu Chouinard * + * mathieu.chouinard@kdemail.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docpdfplugin.h" + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> + +#include <kdevgenericfactory.h> + +static const KAboutData data("docpdfplugin", I18N_NOOP("PDF documentation plugin"), "1.0"); +typedef KDevGenericFactory<DocPDFPlugin> DocPDFPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocpdfplugin, DocPDFPluginFactory(&data) ) + +DocPDFPlugin::DocPDFPlugin(QObject* parent, const char* name, const QStringList args) + :DocumentationPlugin(DocPDFPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(CustomDocumentationTitles | ProjectUserManual); + autoSetup(); +} + +DocPDFPlugin::~DocPDFPlugin() +{ +} + +bool DocPDFPlugin::needRefreshIndex(DocumentationCatalogItem* item) +{ + return false; +} + +QString DocPDFPlugin::pluginName() const +{ + return i18n("PDF Documentation Collection"); +} + +DocumentationCatalogItem* DocPDFPlugin::createCatalog(KListView* contents, const QString& title, const QString& url) +{ + DocumentationCatalogItem *item = new DocumentationCatalogItem(this, contents, title); + item->setURL(KURL(url)); + return item; +} + +QPair<KFile::Mode, QString> DocPDFPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "*.pdf"); +} + +QString DocPDFPlugin::catalogTitle(const QString& /*url*/) +{ + return QString::null; +} + +QStringList DocPDFPlugin::fullTextSearchLocations() +{ + return QStringList(); +} + + +void DocPDFPlugin::autoSetupPlugin() +{ + return; +} + +void DocPDFPlugin::createIndex(IndexBox* /*index*/, DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocPDFPlugin::createTOC(DocumentationCatalogItem* /*item*/) +{ + return; +} + +void DocPDFPlugin::setCatalogURL(DocumentationCatalogItem* /*item*/) +{ + return; +} + +ProjectDocumentationPlugin *DocPDFPlugin::projectDocumentationPlugin(ProjectDocType type) +{ + if (type == UserManual) + return new ProjectDocumentationPlugin(this, type); + return DocumentationPlugin::projectDocumentationPlugin(type); +} diff --git a/parts/documentation/plugins/pdf/docpdfplugin.desktop b/parts/documentation/plugins/pdf/docpdfplugin.desktop new file mode 100644 index 00000000..f42429ff --- /dev/null +++ b/parts/documentation/plugins/pdf/docpdfplugin.desktop @@ -0,0 +1,43 @@ +[Desktop Entry] +Type=Service +Name=DocPDFPlugin +Name[da]=DocPDF-plugin +Name[sk]=Doc PDF modul +Name[sv]=DocPDF-insticksmodul +Name[ta]=DocQt சொருகுபொருள் +Name[zh_TW]=PDF 文件外掛程式 +Exec=blubb +Comment=Documentation plugin for PDF format +Comment[ca]=Connector de documentació per al format PDF +Comment[da]=Dokumentations-plugin for PDF-format +Comment[de]=Komponente für das PDF-Dokumentationsformat +Comment[el]=Πρόσθετο τεκμηρίωσης για τη μορφή PDF +Comment[es]=Complemento de documentación para el formato PDF +Comment[et]=PDF-vormingus dokumentatsiooni plugin +Comment[eu]=PDF formaturako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای قالب PDF +Comment[fr]=Module externe de documentation pour le format PDF +Comment[gl]=Extensión de documentación para o formato PDF +Comment[hu]=Dokumentációmodul PDF formátumú dokumentációhoz +Comment[it]=Plugin di documentazione per formato PDF +Comment[ja]=PDF フォーマットのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk format PDF +Comment[nds]=Komponente för dat PDF-Dokmentatschoonformaat +Comment[ne]=PDF ढाँचाका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor PDF documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie PDF +Comment[pt]='Plugin' para documentação no formato PDF +Comment[pt_BR]=Plug-in de documentação para o formato PDF +Comment[ru]=Модуль для просмотра PDF +Comment[sk]=Dokumentačný modul pre PDF formát +Comment[sr]=Документациони прикључак за PDF формат +Comment[sr@Latn]=Dokumentacioni priključak za PDF format +Comment[sv]=Dokumentationsinsticksmodul för PDF-format +Comment[ta]= Qt DCF ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиши PDF +Comment[tr]=PDF biçimi için belgelendirme eklentisi +Comment[zh_CN]=PDF 格式的文档插件 +Comment[zh_TW]=PDF 格式文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=1 +X-KDE-Library=libdocpdfplugin diff --git a/parts/documentation/plugins/pdf/docpdfplugin.h b/parts/documentation/plugins/pdf/docpdfplugin.h new file mode 100644 index 00000000..4148454a --- /dev/null +++ b/parts/documentation/plugins/pdf/docpdfplugin.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2004 by Mathieu Chouinard * + * mathieu.chouinard@kdemail.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCPDFPLUGIN_H +#define DOCPDFPLUGIN_H + +#include <kdevdocumentationplugin.h> + +class DocPDFPlugin : public DocumentationPlugin { +public: + DocPDFPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocPDFPlugin(); + + virtual QString pluginName() const; + + virtual DocumentationCatalogItem* createCatalog(KListView* contents, const QString& title, const QString& url); + + virtual void createTOC(DocumentationCatalogItem* item); + virtual void setCatalogURL(DocumentationCatalogItem* item); + + virtual bool needRefreshIndex(DocumentationCatalogItem* item); + virtual void createIndex(IndexBox* index, DocumentationCatalogItem* item); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual QString catalogTitle(const QString& url); + + virtual void autoSetupPlugin(); + + virtual ProjectDocumentationPlugin *projectDocumentationPlugin(ProjectDocType type); +}; + +#endif diff --git a/parts/documentation/plugins/qt/Makefile.am b/parts/documentation/plugins/qt/Makefile.am new file mode 100644 index 00000000..a25419e7 --- /dev/null +++ b/parts/documentation/plugins/qt/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/parts/documentation/interfaces $(all_includes) + +METASOURCES = AUTO + +kde_module_LTLIBRARIES = libdocqtplugin.la + +noinst_HEADERS = docqtplugin.h +kde_services_DATA = docqtplugin.desktop + +libdocqtplugin_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libdocqtplugin_la_SOURCES = docqtplugin.cpp +libdocqtplugin_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/parts/documentation/interfaces/libdocumentation_interfaces.la diff --git a/parts/documentation/plugins/qt/docqtplugin.cpp b/parts/documentation/plugins/qt/docqtplugin.cpp new file mode 100644 index 00000000..ffbce63a --- /dev/null +++ b/parts/documentation/plugins/qt/docqtplugin.cpp @@ -0,0 +1,339 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "docqtplugin.h" + +#include <unistd.h> + +#include <qfile.h> +#include <qfileinfo.h> +#include <qdialog.h> + +#include <kurl.h> +#include <kaboutdata.h> +#include <kconfig.h> +#include <klocale.h> +#include <klistview.h> + +#include <urlutil.h> +#include <kdevgenericfactory.h> +#include <kdevplugininfo.h> + +#include "../../../../config.h" + +class QtDocumentationCatalogItem: public DocumentationCatalogItem +{ +public: + QtDocumentationCatalogItem(const QString &dcfFile, DocumentationPlugin* plugin, + KListView *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_dcfFile(dcfFile) + { + } + QtDocumentationCatalogItem(const QString &dcfFile, DocumentationPlugin* plugin, + DocumentationItem *parent, const QString &name) + :DocumentationCatalogItem(plugin, parent, name), m_dcfFile(dcfFile) + { + } + QString dcfFile() const { return m_dcfFile; } + +private: + QString m_dcfFile; +}; + +static const KDevPluginInfo data("docqtplugin"); +typedef KDevGenericFactory<DocQtPlugin> DocQtPluginFactory; +K_EXPORT_COMPONENT_FACTORY( libdocqtplugin, DocQtPluginFactory(data) ) + +DocQtPlugin::DocQtPlugin(QObject* parent, const char* name, const QStringList) + :DocumentationPlugin(DocQtPluginFactory::instance()->config(), parent, name) +{ + setCapabilities(Index | FullTextSearch | CustomDocumentationTitles); + autoSetup(); +} + +DocQtPlugin::~DocQtPlugin() +{ +} + +void DocQtPlugin::createTOC(DocumentationCatalogItem *item) +{ + QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item); + if (!qtItem) + return; + + QFileInfo fi(qtItem->dcfFile()); + + QFile f(qtItem->dcfFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << qtItem->dcfFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f) || doc.doctype().name() != "DCF") + { + kdDebug(9002) << "Not a valid DCF file: " << qtItem->dcfFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement titleEl = docEl.namedItem("DCF").toElement(); + + QDomElement childEl = docEl.lastChild().toElement(); + while (!childEl.isNull()) + { + if (childEl.tagName() == "section") + { + QString ref = childEl.attribute("ref"); + QString title = childEl.attribute("title"); + + DocumentationItem *sectionItem = new DocumentationItem(DocumentationItem::Book, item, title); + KURL sectionUrl(fi.dirPath(true) + "/" + ref); + sectionItem->setURL(sectionUrl); + + QDomElement grandChild = childEl.lastChild().toElement(); + while(!grandChild.isNull()) + { + if (grandChild.tagName() == "keyword") + { + QString keyRef = grandChild.attribute("ref"); + QString keyTitle = grandChild.text(); + + DocumentationItem *keyItem = new DocumentationItem(DocumentationItem::Document, sectionItem, keyTitle); + KURL keyUrl(fi.dirPath(true) + "/" + keyRef); + keyItem->setURL(keyUrl); + } + if (grandChild.tagName() == "section") + { + QString keyRef = grandChild.attribute("ref"); + QString keyTitle = grandChild.attribute("title"); + DocumentationItem *keyItem = new DocumentationItem(DocumentationItem::Book, sectionItem, keyTitle); + KURL keyUrl(fi.dirPath(true) + "/" + keyRef); + keyItem->setURL(keyUrl); + } + grandChild = grandChild.previousSibling().toElement(); + } + } + childEl = childEl.previousSibling().toElement(); + } +} + +void DocQtPlugin::autoSetupPlugin() +{ + QString qtDocDir(QT_DOCDIR); + qtDocDir = URLUtil::envExpand(qtDocDir); + if (qtDocDir.isEmpty()) + { + qtDocDir = getenv("QTDIR"); + } + if (!qtDocDir.isEmpty()) + { + config->setGroup("Search Settings"); + config->writeEntry("Qt Reference Documentation", true); + config->setGroup("Index Settings"); + config->writeEntry("Qt Reference Documentation", true); + config->setGroup("Locations"); + config->writePathEntry("Qt Reference Documentation", qtDocDir + QString("/qt.dcf")); + config->writePathEntry("Qt Assistant Manual", qtDocDir + QString("/assistant.dcf")); + config->writePathEntry("Qt Designer Manual", qtDocDir + QString("/designer.dcf")); + config->writePathEntry("Guide to the Qt Translation Tools", qtDocDir + QString("/linguist.dcf")); + config->writePathEntry("qmake User Guide", qtDocDir + QString("/qmake.dcf")); + } +} + +void DocQtPlugin::setCatalogURL(DocumentationCatalogItem *item) +{ + QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item); + if (!qtItem) + return; + + QFileInfo fi(qtItem->dcfFile()); + + QFile f(qtItem->dcfFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << qtItem->dcfFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f) || doc.doctype().name() != "DCF") + { + kdDebug(9002) << "Not a valid DCF file: " << qtItem->dcfFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement titleEl = docEl.namedItem("DCF").toElement(); + + if (item->url().isEmpty()) + { + KURL url(fi.dirPath(true) + "/" + docEl.attribute("ref", QString::null)); + item->setURL(url); + } +} + +QString DocQtPlugin::pluginName() const +{ + return i18n("Qt Documentation Collection"); +} + +bool DocQtPlugin::needRefreshIndex(DocumentationCatalogItem *item) +{ + QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item); + if (!qtItem) + return false; + + QFileInfo fi(qtItem->dcfFile()); + config->setGroup("Index"); + if (fi.lastModified() > config->readDateTimeEntry(qtItem->text(0), new QDateTime())) + { + kdDebug() << "need rebuild index for " << qtItem->text(0) << endl; + config->writeEntry(item->text(0), fi.lastModified()); + return true; + } + else + return false; +} + +void DocQtPlugin::createIndex(IndexBox *index, DocumentationCatalogItem *item) +{ + QtDocumentationCatalogItem *qtItem = dynamic_cast<QtDocumentationCatalogItem *>(item); + if (!qtItem) + return; + + QFileInfo fi(qtItem->dcfFile()); + + QFile f(qtItem->dcfFile()); + if (!f.open(IO_ReadOnly)) + { + kdDebug(9002) << "Could not read" << qtItem->dcfFile() << endl; + return; + } + QDomDocument doc; + if (!doc.setContent(&f) || doc.doctype().name() != "DCF") + { + kdDebug(9002) << "Not a valid DCF file: " << qtItem->dcfFile() << endl; + return; + } + f.close(); + + QDomElement docEl = doc.documentElement(); + QDomElement titleEl = docEl.namedItem("DCF").toElement(); + + QDomElement childEl = docEl.firstChild().toElement(); + while (!childEl.isNull()) + { + if (childEl.tagName() == "section") + { + createSectionIndex(fi, index, item, childEl); + } + childEl = childEl.nextSibling().toElement(); + } +} + +void DocQtPlugin::createSectionIndex(QFileInfo &fi, IndexBox *index, DocumentationCatalogItem *item, + QDomElement section) +{ + //adymo: do not load section to index for Qt reference documentation + QString title = section.attribute("title"); + if (fi.fileName() != "qt.dcf") + { + QString ref = section.attribute("ref"); + + IndexItemProto *ii = new IndexItemProto(this, item, index, title, item->text(0)); + ii->addURL(KURL(fi.dirPath(true) + "/" + ref)); + } + + QDomElement grandChild = section.firstChild().toElement(); + while(!grandChild.isNull()) + { + if (grandChild.tagName() == "keyword") + { + QString keyRef = grandChild.attribute("ref"); + QString keyTitle = grandChild.text(); + + //adymo: a little hack to avoid unwanted elements + if (keyRef != "qdir-example.html") + { + IndexItemProto *ii = new IndexItemProto(this, item, index, keyTitle, title); + ii->addURL(KURL(fi.dirPath(true) + "/" + keyRef)); + } + } + if (grandChild.tagName() == "section") + { + createSectionIndex(fi, index, item, grandChild); + } + grandChild = grandChild.nextSibling().toElement(); + } +} + +QStringList DocQtPlugin::fullTextSearchLocations() +{ + QStringList locs; + + QMap<QString, QString> entryMap = config->entryMap("Locations"); + + for (QMap<QString, QString>::const_iterator it = entryMap.begin(); + it != entryMap.end(); ++it) + { + config->setGroup("Search Settings"); + if (config->readBoolEntry(it.key(), false)) + { + config->setGroup("Locations"); + QFileInfo fi(config->readPathEntry(it.key())); + locs << fi.dirPath(true); + } + } + + return locs; +} + +QPair<KFile::Mode, QString> DocQtPlugin::catalogLocatorProps() +{ + return QPair<KFile::Mode, QString>(KFile::File, "*.xml *.dcf"); +} + +QString DocQtPlugin::catalogTitle(const QString &url) +{ + QFileInfo fi(url); + if (!fi.exists()) + return QString::null; + + QFile f(url); + if (!f.open(IO_ReadOnly)) + return QString::null; + + QDomDocument doc; + if (!doc.setContent(&f) || (doc.doctype().name() != "DCF")) + return QString::null; + f.close(); + + QDomElement docEl = doc.documentElement(); + + return docEl.attribute("title", QString::null); +} + +DocumentationCatalogItem *DocQtPlugin::createCatalog(KListView *contents, const QString &title, const QString &url) +{ + return new QtDocumentationCatalogItem(url, this, contents, title); +} + +#include "docqtplugin.moc" diff --git a/parts/documentation/plugins/qt/docqtplugin.desktop b/parts/documentation/plugins/qt/docqtplugin.desktop new file mode 100644 index 00000000..1e96eacf --- /dev/null +++ b/parts/documentation/plugins/qt/docqtplugin.desktop @@ -0,0 +1,44 @@ +[Desktop Entry] +Type=Service +Name=DocQtPlugin +Name[da]=DocQt-plugin +Name[sk]=Doc Qt modul +Name[sv]=Qt-dokumentationsinsticksmodul +Name[ta]=DocQt சொருகு +Name[zh_TW]=Qt 文件外掛程式 +Exec=blubb +Comment=Documentation plugin for Qt DCF documentation +Comment[ca]=Connector de documentació per a documentació Qt DCF +Comment[da]=Dokumentations-plugin for Qt DCF dokumentation +Comment[de]=Komponente für Qt-DCF-Dokumentation +Comment[el]=Πρόσθετο τεκμηρίωσης για τεκμηρίωση τύπου Qt DCF +Comment[es]=Complemento de documentación para Qt DCF +Comment[et]=Qt DCF dokumentatsiooni plugin +Comment[eu]=Qt DCF dokumentaziorako dokumentazio plugin-a +Comment[fa]=وصلۀ مستندسازی برای مستندات Qt DCF +Comment[fr]=Module externe de documentation pour la documentation Qt DCF +Comment[gl]=Extensión de documentación para documentación Qt DCF +Comment[hu]=Dokumentációmodul Qt DCF-dokumentációhoz +Comment[it]=Plugin di documentazione per file di Qt DCF +Comment[ja]=Qt DCF ドキュメンテーションのためのドキュメンテーションプラグイン +Comment[ms]=Plugin dokumentasi untuk dokumentasi Qt DCF +Comment[nds]=Dokmentatschoon-Moduul för Qt-DCF-Dokmentatschoon +Comment[ne]=Qt DCF मिसिलीकरणका लागि मिसिलीकरण प्लगइन +Comment[nl]=Documentatie plugin voor Qt DCF documentatie +Comment[pl]=Wtyczka dokumentacji dla dokumentacji w formacie Qt DCF +Comment[pt]='Plugin' para documentação Qt DCF +Comment[pt_BR]=Plug-in de documentação para documento DCF do Qt +Comment[ru]=Модуль для просмотра Qt DCF +Comment[sk]=Dokumentačný modul pre Qt DCF dokumentáciu +Comment[sl]=Vstavek dokumentacije za Qt DCF +Comment[sr]=Документациони прикључак за Qt DCF документацију +Comment[sr@Latn]=Dokumentacioni priključak za Qt DCF dokumentaciju +Comment[sv]=Dokumentationsinsticksmodul för Qt DCF-dokumentation +Comment[ta]= Qt DCF ஆவணத்திற்கான ஆவணச் சொருகு +Comment[tg]=Модул барои наоиши QT DCF +Comment[tr]=Qt DCF Belgelendirmesi için belgelendirme eklentisi +Comment[zh_CN]=Qt DCF 文档的文档插件 +Comment[zh_TW]=Qt DCF 文件外掛程式 +ServiceTypes=KDevelop/DocumentationPlugins +X-KDevelop-Version=5 +X-KDE-Library=libdocqtplugin diff --git a/parts/documentation/plugins/qt/docqtplugin.h b/parts/documentation/plugins/qt/docqtplugin.h new file mode 100644 index 00000000..802dd98a --- /dev/null +++ b/parts/documentation/plugins/qt/docqtplugin.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DOCQTPLUGIN_H +#define DOCQTPLUGIN_H + +#include <kdevdocumentationplugin.h> +#include <qdom.h> + +class KConfig; + +class DocQtPlugin : public DocumentationPlugin +{ + Q_OBJECT +public: + DocQtPlugin(QObject* parent, const char* name, const QStringList args = QStringList()); + ~DocQtPlugin(); + + virtual QString pluginName() const; + + virtual DocumentationCatalogItem *createCatalog(KListView *contents, const QString &title, const QString &url); + + virtual void createTOC(DocumentationCatalogItem *item); + virtual void setCatalogURL(DocumentationCatalogItem *item); + + virtual bool needRefreshIndex(DocumentationCatalogItem *item); + virtual void createIndex(IndexBox *index, DocumentationCatalogItem *item); + virtual void createSectionIndex(QFileInfo &fi, IndexBox *index, DocumentationCatalogItem *item, + QDomElement section); + + virtual QStringList fullTextSearchLocations(); + + virtual QPair<KFile::Mode, QString> catalogLocatorProps(); + virtual QString catalogTitle(const QString &url); + + virtual void autoSetupPlugin(); + +}; + +#endif diff --git a/parts/documentation/protocols/Makefile.am b/parts/documentation/protocols/Makefile.am new file mode 100644 index 00000000..ef837725 --- /dev/null +++ b/parts/documentation/protocols/Makefile.am @@ -0,0 +1,4 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util $(all_includes) +METASOURCES = AUTO + +SUBDIRS = chm diff --git a/parts/documentation/protocols/chm/Makefile.am b/parts/documentation/protocols/chm/Makefile.am new file mode 100644 index 00000000..59d02cfd --- /dev/null +++ b/parts/documentation/protocols/chm/Makefile.am @@ -0,0 +1,21 @@ +## Makefile.am of kdebase/kioslave/chm + +INCLUDES = -I$(top_srcdir)/lib/widgets $(all_includes) + +kde_module_LTLIBRARIES = kio_chm.la libkchmpart.la + +kio_chm_la_SOURCES = decompress.cpp chmfile.cpp chm.cpp +kio_chm_la_LIBADD = $(LIB_KIO) +kio_chm_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) + +libkchmpart_la_SOURCES = kchmpart.cpp +libkchmpart_la_LIBADD = -lkhtml $(LIB_KPARTS) $(top_builddir)/lib/widgets/libkdevwidgets.la +libkchmpart_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) + +noinst_HEADERS = chm.h chmfile.h decompress.h kchmpart.h + +kdelnk_DATA = chm.protocol kchmpart.desktop +kdelnkdir = $(kde_servicesdir) + +METASOURCES = AUTO + diff --git a/parts/documentation/protocols/chm/chm.cpp b/parts/documentation/protocols/chm/chm.cpp new file mode 100644 index 00000000..1383d2b6 --- /dev/null +++ b/parts/documentation/protocols/chm/chm.cpp @@ -0,0 +1,362 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <qcstring.h> +#include <qbitarray.h> +#include <qfile.h> +#include <qregexp.h> +#include <stack> + +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kinstance.h> +#include <kglobal.h> +#include <kurl.h> +#include <kmimemagic.h> +#include <ktempfile.h> + +#include "chm.h" + + +using namespace KIO; + +extern "C" +{ + int kdemain( int argc, char **argv ) + { + KInstance instance( "kio_chm" ); + + kdDebug() << "*** Starting kio_chm " << endl; + + if (argc != 4) { + kdDebug() << "Usage: kio_chm protocol domain-socket1 domain-socket2" << endl; + exit(-1); + } + + ChmProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + + kdDebug() << "*** kio_chm Done" << endl; + return 0; + } +} + +ChmProtocol::ChmProtocol(const QCString &pool_socket, const QCString &app_socket) +: SlaveBase("kio_chm", pool_socket, app_socket) +{ + kdDebug() << "ChmProtocol::ChmProtocol()" << endl; +} +/* ---------------------------------------------------------------------------------- */ + + +ChmProtocol::~ChmProtocol() +{ + kdDebug() << "ChmProtocol::~ChmProtocol()" << endl; +} + + +/* ---------------------------------------------------------------------------------- */ +void ChmProtocol::get( const KURL& url ) +{ + /** When :catalog is appended to the end, a plain-text representation of the catalog + * is given out where each entry consists of four lines, an integer representing the parent + * of the node, an integer representing a node's ID, the Title of the Node, and it's hyperlink. + * When :contents is appended, all contained htm- and html-files will be printed, each in a line. + */ + kdDebug() << "kio_chm::get(const KURL& url) " << url.path() << endl; + + bool catalog = false; + bool contents = false; + QString bigpath = url.path(); + + if(bigpath.endsWith(":catalog")) { + catalog = true; + int len = QString(":catalog").length(); + bigpath.remove(bigpath.length() - len, len); ///strip :catalog from the end + } + + if(bigpath.endsWith(":contents")) { + contents = true; + int len = QString(":contents").length(); + bigpath.remove(bigpath.length() - len, len); ///strip :catalog from the end + } + + QString path; + if ( !checkNewFile( bigpath, path ) ) { + error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() ); + return; + } + + + if (m_dirMap.find(path) == m_dirMap.end()) { + error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() ); + return; + } + + QByteArray theData; + + //init.. + //added by lucida lucida@users.sf.net + QString fname = QString(); + QString chmpath = QString(); + KTempFile f("",".html"); + fname = f.name(); + QTextStream *t = f.textStream(); + QString firstPage = QString(""); + QString m_strIndex = QString(""); + QString tmpstr = QString(""); + bool m_bIndex = 0; + + + if(contents) { + QString output; + KURL u = url; + + ChmDirectoryMap::Iterator it; + for ( it = m_dirMap.begin(); it != m_dirMap.end(); ++it) { + u.setPath(bigpath); + u.addPath(it.key()); + output += u.prettyURL() + "\n"; + } + + data(output.local8Bit()); + processedSize(output.length()); + finished(); + return; + } + + + //try get some page to display, if the chm missing index + ChmDirectoryMap::Iterator it; + for ( it = m_dirMap.begin(); it != m_dirMap.end(); ++it) { + tmpstr.sprintf("%s", it.key().latin1()); + if ((m_strIndex == "") && + (tmpstr.endsWith(".htm") || tmpstr.endsWith(".html"))) + m_strIndex = tmpstr; + if ((tmpstr == "/index.htm") || (tmpstr == "/index.html")) { + m_strIndex = tmpstr; + break; + } + } + m_strIndex.remove(0,1); + + + if (path == "/" || catalog) { + bool htmlOutput = !catalog; + int offset = m_dirMap["/@contents"].offset; + int length = m_dirMap["/@contents"].length; + theData.setRawData(&m_contents[offset], length); + QString s(theData); + QString output; + + QRegExp object("<OBJECT type=\"text/sitemap\">(.*)</OBJECT>", false); + object.setMinimal(true); + + QRegExp nameParam("<param name=\"Name\" value=\"(.*)\">", false); + nameParam.setMinimal(true); + + QRegExp localParam("<param name=\"Local\" value=\"(.*)\">", false); + localParam.setMinimal(true); + + QRegExp mergeParam("<param name=\"Merge\" value=\"(.*)\">", false); + mergeParam.setMinimal(true); + + std::stack<int> parents; + int counter = 1; + int current = 0; + int old = 0, pos = 0; + parents.push(0); + while ((pos = s.find(object, pos)) != -1) { + if(htmlOutput) output += s.mid(old, pos - old); + if(catalog) { + QRegExp ex("<UL>|</UL>", false); ex.setMinimal(true); + QString ms = s.mid(old, pos - old); + int pos = 0; + while( (pos = ms.find(ex, pos)) != -1) { + if(ms.mid(pos, 4) == "<UL>") { + parents.push(current); + } else{ + if(parents.empty()){ + }else{ + current = parents.top(); + parents.pop(); + } + } + pos++; + } + } + pos += object.matchedLength(); + old = pos; + QString obj = object.cap(1); + QString name, local; + if (obj.find(nameParam) != -1) { + name = nameParam.cap(1); + if (obj.find(localParam) != -1) { + local = localParam.cap(1); + //output += "<a href=\"" + local + "\">" + name + "</a>"; + //added by lucida lucida@users.sf.net + if (local != "" && local != "/") { + if(!catalog) { + output += "<a target=\"browse\" href=\"" + url.url() + local + "\">" + name + "</a>"; + }else{ + current = counter; + ++counter; + KURL u = url; + u.setPath(bigpath + local); + QString str; + output += str.sprintf("%i\n%i\n", parents.top(), current); + output += name + "\n" + u.prettyURL() + "\n"; + } + m_bIndex = 1; + if (firstPage == "") firstPage = url.url()+QString::fromLocal8Bit(local.latin1()); + } + else + if(htmlOutput) output += name; + } else { + if(htmlOutput) output += name; + } + } + if (obj.find(mergeParam) != -1 && htmlOutput) { + QString link = mergeParam.cap(1); + QString href = link.left(link.find("::")); + QString path = m_chmFile.left(m_chmFile.findRev("/") + 1); + //output += " (<a href=\"" + path + href + "\">link</a>)"; + m_bIndex = 1; + output += " (<a target=\"browse\" href=\"" + url.url() + path + href + "\">link</a>)"; + if (firstPage == "") firstPage = url.url()+QString::fromLocal8Bit(local.latin1()); + } + } + if(htmlOutput) output += s.mid(old); + + //set left pane + //added by lucida, lucida@users.sf.net + QString lframe = QString("</HEAD><FRAMESET COLS=\"25%,*\">\n"); + lframe += "<FRAME NAME=\"index\" src=\"file:"+ fname+"\"" + " marginwidth=\"0\"></FRAME>\n"; + if (!m_bIndex) { + lframe = "</HEAD><FRAMESET>"; + firstPage = url.url() + QString::fromLocal8Bit(m_strIndex.latin1()); + } + theData.resetRawData(&m_contents[offset], length); + //KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( output, path ); + //kdDebug() << "Emitting mimetype " << result->mimeType() << endl; + //mimeType( result->mimeType() ); +/* QCString output1 = (QCString)(output.latin1()); + data(output1); + processedSize(output1.length());*/ + + //construct the frame + //added by lucida lucida@users.sf.net + QString framestr = QString("<HTML><HEAD>\n"); + framestr += lframe; + framestr += "<FRAME NAME=\"browse\" src=\"" + firstPage + "\">\n"; + framestr += "</FRAME>\n"; + framestr += "</FRAMESET></HTML>"; + //write index file + //added by lucida lucida@users.sf.net + *t << QString::fromLocal8Bit(output.latin1()) << endl; + + if(catalog) { + data(output.local8Bit()); + processedSize(output.length()); + }else{ + data(framestr.local8Bit()); + processedSize(framestr.length()); + } + } else { + int offset = m_dirMap[path].offset; + int length = m_dirMap[path].length; + totalSize(length); + theData.setRawData(&m_contents[offset], length); + + KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( theData, path ); + kdDebug() << "Emitting mimetype " << result->mimeType() << endl; + mimeType( result->mimeType() ); + data(theData); + theData.resetRawData(&m_contents[offset], length); + processedSize(length); + } + + finished(); +} + +/* --------------------------------------------------------------------------- */ +bool ChmProtocol::checkNewFile( QString fullPath, QString& path ) +{ + //kdDebug() << "ChmProtocol::checkNewFile " << fullPath << endl; + + fullPath = fullPath.replace(QRegExp("::"), ""); + + // Are we already looking at that file ? + if ( !m_chmFile.isEmpty() && fullPath.startsWith(m_chmFile) ) + { + path = fullPath.mid(m_chmFile.length()).lower(); + return true; + } + + kdDebug() << "Need to open a new file" << endl; + + m_chmFile = ""; + + // Find where the chm file is in the full path + int pos = 0; + QString chmFile; + path = ""; + + int len = fullPath.length(); + if ( len != 0 && fullPath[ len - 1 ] != '/' ) + fullPath += '/'; + + //kdDebug() << "the full path is " << fullPath << endl; + while ( (pos=fullPath.find( '/', pos+1 )) != -1 ) + { + QString tryPath = fullPath.left( pos ); + //kdDebug() << fullPath << " trying " << tryPath << endl; + struct stat statbuf; + if ( ::stat( QFile::encodeName(tryPath), &statbuf ) == 0 && !S_ISDIR(statbuf.st_mode) ) + { + chmFile = tryPath; + path = fullPath.mid( pos ).lower(); + kdDebug() << "fullPath=" << fullPath << " path=" << path << endl; + len = path.length(); + if ( len > 2 ) + { + if ( path[ len - 1 ] == '/' ) + path.truncate( len - 1 ); + } + else + { + path = QString::fromLatin1("/"); + } + kdDebug() << "Found. chmFile=" << chmFile << " path=" << path << endl; + break; + } + } + if ( chmFile.isEmpty() ) + { + kdDebug() << "ChmProtocol::checkNewFile: not found" << endl; + return false; + } + + m_chmFile = chmFile; + + // Open new file + //kdDebug() << "Opening Chm file on " << chmFile << endl; + return m_chm.read(chmFile, m_dirMap, m_contents); +} diff --git a/parts/documentation/protocols/chm/chm.h b/parts/documentation/protocols/chm/chm.h new file mode 100644 index 00000000..92044173 --- /dev/null +++ b/parts/documentation/protocols/chm/chm.h @@ -0,0 +1,47 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __chm_h__ +#define __chm_h__ + +#include <qstring.h> +#include <qcstring.h> +#include <kurl.h> +#include <kio/global.h> +#include <kio/slavebase.h> +#include "chmfile.h" + +class QCString; + +class ChmProtocol : public KIO::SlaveBase +{ +public: + ChmProtocol( const QCString&, const QCString& ); + ~ChmProtocol(); + + void get( const KURL& ); + +private: + bool checkNewFile( QString, QString& ); + ChmDirectoryMap m_dirMap; + QByteArray m_contents; + QString m_chmFile; + Chm m_chm; +}; + + +#endif // __chm_h__ + diff --git a/parts/documentation/protocols/chm/chm.protocol b/parts/documentation/protocols/chm/chm.protocol new file mode 100644 index 00000000..90daa4c5 --- /dev/null +++ b/parts/documentation/protocols/chm/chm.protocol @@ -0,0 +1,36 @@ +[Protocol] +exec=kio_chm +protocol=ms-its +input=none +output=filesystem +reading=true +defaultMimetype=text/html +Description=A kioslave for displaying WinHelp files +Description[ca]=Un kioslave per a mostrar fitxers WinHelp +Description[da]=En kioslave til visning af Windows hjælpefiler +Description[de]=Ein Ein-/Ausgabemodul zur Anzeige von WinHelp-Dateien +Description[el]=Ένας υπηρέτης kio για εμφάνιση αρχείων WinHelp +Description[es]=Un kioslave para mostrar archivos WinHelp +Description[et]=WinHelp-failide kuvamise IO-moodul +Description[eu]=WinHelp fitxategiak bistaratzeko kioslave bat +Description[fa]=یک kioslave برای نمایش پروندههای WinHelp +Description[fr]=Un esclave d'E/S (kioslave) pour l'affichage des fichiers WinHelp +Description[gl]=Un kioslave para mostrar ficheiros WinHelp +Description[hu]=KDE-protokoll WinHelp-fájlok megjelenítéséhez +Description[it]=Un kioslave per mostrare i file WinHelp +Description[ja]=WinHelp を表示するための kioslave +Description[nds]=En In-/Utgaavmoduul för't Wiesen vun "WinHelp"-Dateien +Description[ne]=WinHelp फाइलहरूका लागि किवस्लेभ +Description[nl]=Een kioslave voor het weergeven van WinHelp-bestanden +Description[pl]=kioslave do pokazywania plików WinHelp +Description[pt]=A 'kioslave' para mostrar ficheiros WinHelp +Description[pt_BR]=Um kioslave para exibir arquivos WinHelp +Description[ru]=Обработчик ввода-вывода для файлов WinHelp +Description[sk]=kioslave pre zobrazenie WinHelp súborov +Description[sr]=KIOSlave за приказ WinHelp фајлова +Description[sr@Latn]=KIOSlave za prikaz WinHelp fajlova +Description[sv]=En I/O-slav för att visa WinHelp-filer +Description[tr]=WinHelp dosyalarını görüntülemek için bir kioslave +Description[zh_CN]=显示 WinHelp 文件的 kioslave +Description[zh_TW]=顯示 WinHelp 檔案的 kioslave +Icon=help diff --git a/parts/documentation/protocols/chm/chmfile.cpp b/parts/documentation/protocols/chm/chmfile.cpp new file mode 100644 index 00000000..f69d354a --- /dev/null +++ b/parts/documentation/protocols/chm/chmfile.cpp @@ -0,0 +1,197 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <qfile.h> +#include "chmfile.h" +#include "decompress.h" + +uint Chm::getEncInt(QFile& f, uint &value) const +{ + int c; + uint result = 0; + ulong count = 0; + + do + { + c = f.getch(); + result <<= 7; + result |= (c & 0x7F); + count++; + } while (c & 0x80); + + value = result; + return count; +} + +uint Chm::getName(QFile& f, QString& name) const +{ + int len = f.getch(); + char *buf = new char[len]; + f.readBlock(buf, len); + name = QString::fromUtf8(buf, len); + if (name.startsWith("/")) + name = name.lower(); + delete [] buf; + return len + 1; +} + +uint Chm::getIntel32(QFile& f) const +{ + uint value = f.getch() | f.getch() << 8 | f.getch() << 16 | f.getch() << 24; + return value; +} + +uint Chm::getIntel64(QFile& f) const +{ + uint value = getIntel32(f); + f.at(f.at() + 4); + return value; +} + +bool Chm::getChunk(QFile& f, uint chunkSize, ChmDirectoryMap& directoryMap) const +{ + char tag[4]; + if (f.readBlock(tag, 4) != 4) return false; + + if (!qstrncmp(tag, "PMGL", 4)) + { + uint quickref_length = getIntel32(f); + f.at(f.at() + 12); + + uint pos = 20; + while (pos < chunkSize - quickref_length) + { + uint section, offset, length; + QString name; + pos += getName(f, name); + pos += getEncInt(f, section); + pos += getEncInt(f, offset); + pos += getEncInt(f, length); + directoryMap[name] = ChmDirTableEntry(section, offset, length); + if (name.endsWith(".hhc")) + directoryMap["/@contents"] = ChmDirTableEntry(section, offset, length); + } + + return (f.at(f.at() + quickref_length)); + } + else if (!qstrncmp(tag, "PMGI", 4)) + { + // evaluation of the index chunk is not yet implemented => skip it + return f.at(f.at() + chunkSize - 4); + } + else + { + return false; + } +} + +bool Chm::read(const QString& fileSpec, ChmDirectoryMap& dirMap, QByteArray& contents) const +{ + QFile f(fileSpec); + if (!f.open(IO_ReadOnly)) return false; + + // read CHM file header + char tag[4]; + if (f.readBlock(tag, 4) != 4 || qstrncmp(tag, "ITSF", 4)) return false; + uint chm_version = getIntel32(f); + if (!f.at(f.at() + 0x30)) return false; + + // read header section table + uint section_0_offset = getIntel64(f); + uint section_0_length = getIntel64(f); + uint section_1_offset = getIntel64(f); + uint section_1_length = getIntel64(f); + + uint contentStart = 0; + if (chm_version >= 3) contentStart = getIntel32(f); + + // read directory header + if (!f.at(section_1_offset)) return false; + if (f.readBlock(tag, 4) != 4 || qstrncmp(tag, "ITSP", 4)) return false; + if (!f.at(f.at() + 12)) return false; + uint directory_chunk_size = getIntel32(f); + if (!f.at(f.at() + 24)) return false; + uint num_directory_chunks = getIntel32(f); + if (!f.at(f.at() + 36)) return false; + + // read directory table + for (uint i = 0; i < num_directory_chunks; i++) + if (!getChunk(f, directory_chunk_size, dirMap)) return false; + + // current position is start of content area + if (chm_version < 3) contentStart = f.at(); + + // read reset table + if (!f.at(contentStart)) return false; + uint resetTableOffset = + dirMap["::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable"].offset; + if (!f.at(f.at() + resetTableOffset + 4)) return false; + uint numResetTableEntries = getIntel32(f); + if (!f.at(f.at() + 8)) return false; + uint uncompressedLength = getIntel64(f); + uint compressedLength = getIntel64(f); + uint blockSize = getIntel64(f); + uint *resetTable = new uint[numResetTableEntries + 1]; + + for (uint i = 0; i < numResetTableEntries; i++) + resetTable[i] = getIntel64(f); + + resetTable[numResetTableEntries] = compressedLength; + + // read compressed contents + if (!f.at(contentStart)) return false; + uint contentsOffset = dirMap["::DataSpace/Storage/MSCompressed/Content"].offset; + if (!f.at(f.at() + contentsOffset)) return false; + char *compressedContents = new char[compressedLength]; + if ((uint)f.readBlock(compressedContents, compressedLength) != compressedLength) return false; + + f.close(); + + // allocate buffer for uncompressed contents + char *uncompressedContents = new char[uncompressedLength]; + + // get window size + uint window = 1; + uint tmp = blockSize; + while (tmp >>= 1) window++; + + // decompress + uint outlen = uncompressedLength; + int res = 1; + + for (uint i = 0; i < numResetTableEntries; i++) + { + if (!(i & 1)) LZXinit(window); + + uint inlen = resetTable[i+1] - resetTable[i]; + res = LZXdecompress((uchar*)&compressedContents[resetTable[i]], + inlen, + (uchar*)uncompressedContents + i * blockSize, + (outlen < blockSize) ? outlen : blockSize); + if (res) break; + outlen -= blockSize; + } + + delete [] resetTable; + delete [] compressedContents; + + if (res == 0) + contents.duplicate(uncompressedContents, uncompressedLength); + + delete [] uncompressedContents; + + return (res == 0); +} diff --git a/parts/documentation/protocols/chm/chmfile.h b/parts/documentation/protocols/chm/chmfile.h new file mode 100644 index 00000000..0040c135 --- /dev/null +++ b/parts/documentation/protocols/chm/chmfile.h @@ -0,0 +1,53 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __chmfile_h__ +#define __chmfile_h__ + +#include <cstdio> +#include <qmap.h> +#include <qstring.h> + +class QFile; + +struct ChmDirTableEntry +{ + ChmDirTableEntry() : section(0), offset(0), length(0) {} + ChmDirTableEntry( uint s, uint o, uint l ) + : section(s), offset(o), length(l) {} + + uint section; + uint offset; + uint length; +}; + +typedef QMap<QString, ChmDirTableEntry> ChmDirectoryMap; + +class Chm +{ +public: + bool read( const QString&, ChmDirectoryMap&, QByteArray& ) const; + +private: + bool getChunk( QFile&, uint, ChmDirectoryMap& ) const; + uint getEncInt( QFile&, uint& ) const; + uint getName( QFile&, QString& ) const; + uint getIntel32( QFile& ) const; + uint getIntel64( QFile& ) const; +}; + +#endif // __chmfile_h__ + diff --git a/parts/documentation/protocols/chm/decompress.cpp b/parts/documentation/protocols/chm/decompress.cpp new file mode 100644 index 00000000..0356d86e --- /dev/null +++ b/parts/documentation/protocols/chm/decompress.cpp @@ -0,0 +1,796 @@ +/* Most of this file is taken from: + cabextract 0.5 - a program to extract Microsoft Cabinet files + (C) 2000-2001 Stuart Caie <kyzer@4u.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "decompress.h" + +int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table); +int lzx_read_lens(UBYTE *lens, ULONG first, ULONG last, lzx_bits *lb); + + +/*--------------------------------------------------------------------------*/ +/* our archiver information / state */ + +/* LZX stuff */ + +/* some constants defined by the LZX specification */ +#define LZX_MIN_MATCH (2) +#define LZX_MAX_MATCH (257) +#define LZX_NUM_CHARS (256) +#define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */ +#define LZX_BLOCKTYPE_VERBATIM (1) +#define LZX_BLOCKTYPE_ALIGNED (2) +#define LZX_BLOCKTYPE_UNCOMPRESSED (3) +#define LZX_PRETREE_NUM_ELEMENTS (20) +#define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */ +#define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */ +#define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */ + +/* LZX huffman defines: tweak tablebits as desired */ +#define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS) +#define LZX_PRETREE_TABLEBITS (6) +#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8) +#define LZX_MAINTREE_TABLEBITS (12) +#define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1) +#define LZX_LENGTH_TABLEBITS (12) +#define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS) +#define LZX_ALIGNED_TABLEBITS (7) + +#define LZX_LENTABLE_SAFETY (64) /* we allow length table decoding overruns */ + +#define LZX_DECLARE_TABLE(tbl) \ + UWORD tbl##_table[(1<<LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS<<1)];\ + UBYTE tbl##_len [LZX_##tbl##_MAXSYMBOLS + LZX_LENTABLE_SAFETY] + +struct LZXstate +{ + UBYTE *window; /* the actual decoding window */ + ULONG window_size; /* window size (32Kb through 2Mb) */ + ULONG actual_size; /* window size when it was first allocated */ + ULONG window_posn; /* current offset within the window */ + ULONG R0, R1, R2; /* for the LRU offset system */ + UWORD main_elements; /* number of main tree elements */ + int header_read; /* have we started decoding at all yet? */ + UWORD block_type; /* type of this block */ + ULONG block_length; /* uncompressed length of this block */ + ULONG block_remaining; /* uncompressed bytes still left to decode */ + ULONG frames_read; /* the number of CFDATA blocks processed */ + LONG intel_filesize; /* magic header value used for transform */ + LONG intel_curpos; /* current offset in transform space */ + int intel_started; /* have we seen any translatable data yet? */ + + LZX_DECLARE_TABLE(PRETREE); + LZX_DECLARE_TABLE(MAINTREE); + LZX_DECLARE_TABLE(LENGTH); + LZX_DECLARE_TABLE(ALIGNED); +}; + + +/* generic stuff */ +#define CAB(x) (decomp_state.x) +#define LZX(x) (decomp_state.lzx.x) +#define DECR_OK (0) +#define DECR_DATAFORMAT (1) +#define DECR_ILLEGALDATA (2) +#define DECR_NOMEMORY (3) +#define DECR_CHECKSUM (4) +#define DECR_INPUT (5) +#define DECR_OUTPUT (6) + +struct +{ + struct LZXstate lzx; +} decomp_state; + + +/* LZX decruncher */ + +/* Microsoft's LZX document and their implementation of the + * com.ms.util.cab Java package do not concur. + * + * In the LZX document, there is a table showing the correlation between + * window size and the number of position slots. It states that the 1MB + * window = 40 slots and the 2MB window = 42 slots. In the implementation, + * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the + * first slot whose position base is equal to or more than the required + * window size'. This would explain why other tables in the document refer + * to 50 slots rather than 42. + * + * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode + * is not defined in the specification. + * + * The LZX document does not state the uncompressed block has an + * uncompressed length field. Where does this length field come from, so + * we can know how large the block is? The implementation has it as the 24 + * bits following after the 3 blocktype bits, before the alignment + * padding. + * + * The LZX document states that aligned offset blocks have their aligned + * offset huffman tree AFTER the main and length trees. The implementation + * suggests that the aligned offset tree is BEFORE the main and length + * trees. + * + * The LZX document decoding algorithm states that, in an aligned offset + * block, if an extra_bits value is 1, 2 or 3, then that number of bits + * should be read and the result added to the match offset. This is + * correct for 1 and 2, but not 3, where just a huffman symbol (using the + * aligned tree) should be read. + * + * Regarding the E8 preprocessing, the LZX document states 'No translation + * may be performed on the last 6 bytes of the input block'. This is + * correct. However, the pseudocode provided checks for the *E8 leader* + * up to the last 6 bytes. If the leader appears between -10 and -7 bytes + * from the end, this would cause the next four bytes to be modified, at + * least one of which would be in the last 6 bytes, which is not allowed + * according to the spec. + * + * The specification states that the huffman trees must always contain at + * least one element. However, many CAB files contain blocks where the + * length tree is completely empty (because there are no matches), and + * this is expected to succeed. + */ + + +/* LZX uses what it calls 'position slots' to represent match offsets. + * What this means is that a small 'position slot' number and a small + * offset from that slot are encoded instead of one large offset for + * every match. + * - position_base is an index to the position slot bases + * - extra_bits states how many bits of offset-from-base data is needed. + */ +static ULONG position_base[51]; +static UBYTE extra_bits[51]; + + +int LZXinit(int window) { + ULONG wndsize = 1 << window; + int i, j, posn_slots; + + /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */ + /* if a previously allocated window is big enough, keep it */ + if (window < 15 || window > 21) return DECR_DATAFORMAT; + if (LZX(actual_size) < wndsize) + { + if (LZX(window)) free(LZX(window)); + LZX(window) = NULL; + } + if (!LZX(window)) + { + if (!(LZX(window) = (UBYTE*)malloc(wndsize))) return DECR_NOMEMORY; + LZX(actual_size) = wndsize; + } + LZX(window_size) = wndsize; + + /* initialise static tables */ + for (i=0, j=0; i <= 49; i += 2) + { + extra_bits[i] = extra_bits[i+1] = j; /* 0,0,0,0,1,1,2,2,3,3... */ + if ((i != 0) && (j < 17)) j++; /* 0,0,1,2,3,4...15,16,17,17,17,17... */ + } + for (i=0, j=0; i <= 50; i++) + { + position_base[i] = j; /* 0,1,2,3,4,6,8,12,16,24,32,... */ + j += 1 << extra_bits[i]; /* 1,1,1,1,2,2,4,4,8,8,16,16,32,32,... */ + } + + /* calculate required position slots */ + if (window == 20) posn_slots = 42; + else if (window == 21) posn_slots = 50; + else posn_slots = window << 1; + + /*posn_slots=i=0; while (i < wndsize) i += 1 << extra_bits[posn_slots++]; */ + + + LZX(R0) = LZX(R1) = LZX(R2) = 1; + LZX(main_elements) = LZX_NUM_CHARS + (posn_slots << 3); + LZX(header_read) = 0; + LZX(frames_read) = 0; + LZX(block_remaining) = 0; + LZX(block_type) = LZX_BLOCKTYPE_INVALID; + LZX(intel_curpos) = 0; + LZX(intel_started) = 0; + LZX(window_posn) = 0; + + /* initialise tables to 0 (because deltas will be applied to them) */ + for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) LZX(MAINTREE_len)[i] = 0; + for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) LZX(LENGTH_len)[i] = 0; + + return DECR_OK; +} + + +/* Bitstream reading macros: + * + * INIT_BITSTREAM should be used first to set up the system + * READ_BITS(var,n) takes N bits from the buffer and puts them in var + * + * ENSURE_BITS(n) ensures there are at least N bits in the bit buffer + * PEEK_BITS(n) extracts (without removing) N bits from the bit buffer + * REMOVE_BITS(n) removes N bits from the bit buffer + * + * These bit access routines work by using the area beyond the MSB and the + * LSB as a free source of zeroes. This avoids having to mask any bits. + * So we have to know the bit width of the bitbuffer variable. This is + * sizeof(ULONG) * 8, also defined as ULONG_BITS + */ + +/* number of bits in ULONG. Note: This must be at multiple of 16, and at + * least 32 for the bitbuffer code to work (ie, it must be able to ensure + * up to 17 bits - that's adding 16 bits when there's one bit left, or + * adding 32 bits when there are no bits left. The code should work fine + * for machines where ULONG >= 32 bits. + */ +#define ULONG_BITS (sizeof(ULONG)<<3) + +#define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0) + +#define ENSURE_BITS(n) \ + while (bitsleft < (n)) { \ + bitbuf |= ((inpos[1]<<8)|inpos[0]) << (ULONG_BITS-16 - bitsleft); \ + bitsleft += 16; inpos+=2; \ + } + +#define PEEK_BITS(n) (bitbuf >> (ULONG_BITS - (n))) +#define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n))) + +#define READ_BITS(v,n) do { \ + ENSURE_BITS(n); \ + (v) = PEEK_BITS(n); \ + REMOVE_BITS(n); \ +} while (0) + + +/* Huffman macros */ + +#define TABLEBITS(tbl) (LZX_##tbl##_TABLEBITS) +#define MAXSYMBOLS(tbl) (LZX_##tbl##_MAXSYMBOLS) +#define SYMTABLE(tbl) (LZX(tbl##_table)) +#define LENTABLE(tbl) (LZX(tbl##_len)) + +/* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths. + * In reality, it just calls make_decode_table() with the appropriate + * values - they're all fixed by some #defines anyway, so there's no point + * writing each call out in full by hand. + */ +#define BUILD_TABLE(tbl) \ + if (make_decode_table( \ + MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl) \ + )) { return DECR_ILLEGALDATA; } + + +/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the + * bitstream using the stated table and puts it in var. + */ +#define READ_HUFFSYM(tbl,var) do { \ + ENSURE_BITS(16); \ + hufftbl = SYMTABLE(tbl); \ + if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \ + j = 1 << (ULONG_BITS - TABLEBITS(tbl)); \ + do { \ + j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \ + if (!j) { return DECR_ILLEGALDATA; } \ + } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl)); \ + } \ + j = LENTABLE(tbl)[(var) = i]; \ + REMOVE_BITS(j); \ +} while (0) + + +/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols + * first to last in the given table. The code lengths are stored in their + * own special LZX way. + */ +#define READ_LENGTHS(tbl,first,last) do { \ + lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \ + if (lzx_read_lens(LENTABLE(tbl),(first),(last),&lb)) { \ + return DECR_ILLEGALDATA; \ + } \ + bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \ +} while (0) + + +/* make_decode_table(nsyms, nbits, length[], table[]) + * + * This function was coded by David Tritscher. It builds a fast huffman + * decoding table out of just a canonical huffman code lengths table. + * + * nsyms = total number of symbols in this huffman tree. + * nbits = any symbols with a code length of nbits or less can be decoded + * in one lookup of the table. + * length = A table to get code lengths from [0 to syms-1] + * table = The table to fill up with decoded symbols and pointers. + * + * Returns 0 for OK or 1 for error + */ + +int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) { + register UWORD sym; + register ULONG leaf; + register UBYTE bit_num = 1; + ULONG fill; + ULONG pos = 0; /* the current position in the decode table */ + ULONG table_mask = 1 << nbits; + ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */ + ULONG next_symbol = bit_mask; /* base of allocation for long codes */ + + /* fill entries for codes short enough for a direct mapping */ + while (bit_num <= nbits) + { + for (sym = 0; sym < nsyms; sym++) + { + if (length[sym] == bit_num) + { + leaf = pos; + + if ((pos += bit_mask) > table_mask) return 1; /* table overrun */ + + /* fill all possible lookups of this symbol with the symbol itself */ + fill = bit_mask; + while (fill-- > 0) table[leaf++] = sym; + } + } + bit_mask >>= 1; + bit_num++; + } + + /* if there are any codes longer than nbits */ + if (pos != table_mask) + { + /* clear the remainder of the table */ + for (sym = pos; sym < table_mask; sym++) table[sym] = 0; + + /* give ourselves room for codes to grow by up to 16 more bits */ + pos <<= 16; + table_mask <<= 16; + bit_mask = 1 << 15; + + while (bit_num <= 16) + { + for (sym = 0; sym < nsyms; sym++) + { + if (length[sym] == bit_num) + { + leaf = pos >> 16; + for (fill = 0; fill < bit_num - nbits; fill++) + { + /* if this path hasn't been taken yet, 'allocate' two entries */ + if (table[leaf] == 0) + { + table[(next_symbol << 1)] = 0; + table[(next_symbol << 1) + 1] = 0; + table[leaf] = next_symbol++; + } + /* follow the path and select either left or right for next bit */ + leaf = table[leaf] << 1; + if ((pos >> (15-fill)) & 1) leaf++; + } + table[leaf] = sym; + + if ((pos += bit_mask) > table_mask) return 1; /* table overflow */ + } + } + bit_mask >>= 1; + bit_num++; + } + } + + /* full table? */ + if (pos == table_mask) return 0; + + /* either erroneous table, or all elements are 0 - let's find out. */ + for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1; + return 0; +} + +int lzx_read_lens(UBYTE *lens, ULONG first, ULONG last, lzx_bits *lb) { + ULONG i,j, x,y; + int z; + + register ULONG bitbuf = lb->bb; + register int bitsleft = lb->bl; + UBYTE *inpos = lb->ip; + UWORD *hufftbl; + + for (x = 0; x < 20; x++) + { + READ_BITS(y, 4); + LENTABLE(PRETREE)[x] = y; + } + BUILD_TABLE(PRETREE); + + for (x = first; x < last;) + { + READ_HUFFSYM(PRETREE, z); + if (z == 17) + { + READ_BITS(y, 4); y += 4; + while (y--) lens[x++] = 0; + } + else if (z == 18) + { + READ_BITS(y, 5); y += 20; + while (y--) lens[x++] = 0; + } + else if (z == 19) + { + READ_BITS(y, 1); y += 4; + READ_HUFFSYM(PRETREE, z); + z = lens[x] - z; if (z < 0) z += 17; + while (y--) lens[x++] = z; + } + else + { + z = lens[x] - z; if (z < 0) z += 17; + lens[x++] = z; + } + } + + lb->bb = bitbuf; + lb->bl = bitsleft; + lb->ip = inpos; + return 0; +} + +int LZXdecompress(UBYTE* inpos, int inlen, UBYTE* outpos, int outlen) { + UBYTE *endinp = inpos + inlen; + UBYTE *window = LZX(window); + UBYTE *runsrc, *rundest; + UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */ + + ULONG window_posn = LZX(window_posn); + ULONG window_size = LZX(window_size); + ULONG R0 = LZX(R0); + ULONG R1 = LZX(R1); + ULONG R2 = LZX(R2); + + register ULONG bitbuf; + register int bitsleft; + ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */ + lzx_bits lb; /* used in READ_LENGTHS macro */ + + int togo = outlen, this_run, main_element, aligned_bits; + int match_length, length_footer, extra, verbatim_bits; + + INIT_BITSTREAM; + + /* read header if necessary */ + if (!LZX(header_read)) + { + i = j = 0; + READ_BITS(k, 1); if (k) + { + READ_BITS(i,16); READ_BITS(j,16); + } + LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */ + LZX(header_read) = 1; + } + + /* main decoding loop */ + while (togo > 0) + { + /* last block finished, new block expected */ + if (LZX(block_remaining) == 0) + { + if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) + { + if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */ + INIT_BITSTREAM; + } + + READ_BITS(LZX(block_type), 3); + READ_BITS(i, 16); + READ_BITS(j, 8); + LZX(block_remaining) = LZX(block_length) = (i << 8) | j; + + switch (LZX(block_type)) + { + case LZX_BLOCKTYPE_ALIGNED: + for (i = 0; i < 8; i++) + { + READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; + } + BUILD_TABLE(ALIGNED); + /* rest of aligned header is same as verbatim */ + + case LZX_BLOCKTYPE_VERBATIM: + READ_LENGTHS(MAINTREE, 0, 256); + READ_LENGTHS(MAINTREE, 256, LZX(main_elements)); + BUILD_TABLE(MAINTREE); + if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1; + + READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS); + BUILD_TABLE(LENGTH); + break; + + case LZX_BLOCKTYPE_UNCOMPRESSED: + LZX(intel_started) = 1; /* because we can't assume otherwise */ + ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */ + if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */ + R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4; + R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4; + R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4; + break; + + default: + return DECR_ILLEGALDATA; + } + } + + /* buffer exhaustion check */ + if (inpos > endinp) + { + /* it's possible to have a file where the next run is less than + * 16 bits in size. In this case, the READ_HUFFSYM() macro used + * in building the tables will exhaust the buffer, so we should + * allow for this, but not allow those accidentally read bits to + * be used (so we check that there are at least 16 bits + * remaining - in this boundary case they aren't really part of + * the compressed data) + */ + if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA; + } + + while ((this_run = LZX(block_remaining)) > 0 && togo > 0) + { + if (this_run > togo) this_run = togo; + togo -= this_run; + LZX(block_remaining) -= this_run; + + /* apply 2^x-1 mask */ + window_posn &= window_size - 1; + /* runs can't straddle the window wraparound */ + if ((window_posn + this_run) > window_size) + return DECR_DATAFORMAT; + + switch (LZX(block_type)) + { + + case LZX_BLOCKTYPE_VERBATIM: + while (this_run > 0) + { + READ_HUFFSYM(MAINTREE, main_element); + + if (main_element < LZX_NUM_CHARS) + { + /* literal: 0 to LZX_NUM_CHARS-1 */ + window[window_posn++] = main_element; + this_run--; + } + else + { + /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */ + main_element -= LZX_NUM_CHARS; + + match_length = main_element & LZX_NUM_PRIMARY_LENGTHS; + if (match_length == LZX_NUM_PRIMARY_LENGTHS) + { + READ_HUFFSYM(LENGTH, length_footer); + match_length += length_footer; + } + match_length += LZX_MIN_MATCH; + + match_offset = main_element >> 3; + + if (match_offset > 2) + { + /* not repeated offset */ + if (match_offset != 3) + { + extra = extra_bits[match_offset]; + READ_BITS(verbatim_bits, extra); + match_offset = position_base[match_offset] - 2 + verbatim_bits; + } + else + { + match_offset = 1; + } + + /* update repeated offset LRU queue */ + R2 = R1; R1 = R0; R0 = match_offset; + } + else if (match_offset == 0) + { + match_offset = R0; + } + else if (match_offset == 1) + { + match_offset = R1; + R1 = R0; R0 = match_offset; + } + else /* match_offset == 2 */ + { + match_offset = R2; + R2 = R0; R0 = match_offset; + } + + rundest = window + window_posn; + runsrc = rundest - match_offset; + window_posn += match_length; + this_run -= match_length; + + /* copy any wrapped around source data */ + while ((runsrc < window) && (match_length-- > 0)) + { + *rundest++ = *(runsrc + window_size); runsrc++; + } + /* copy match data - no worries about destination wraps */ + while (match_length-- > 0) *rundest++ = *runsrc++; + + } + } + break; + + case LZX_BLOCKTYPE_ALIGNED: + while (this_run > 0) + { + READ_HUFFSYM(MAINTREE, main_element); + + if (main_element < LZX_NUM_CHARS) + { + /* literal: 0 to LZX_NUM_CHARS-1 */ + window[window_posn++] = main_element; + this_run--; + } + else + { + /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */ + main_element -= LZX_NUM_CHARS; + + match_length = main_element & LZX_NUM_PRIMARY_LENGTHS; + if (match_length == LZX_NUM_PRIMARY_LENGTHS) + { + READ_HUFFSYM(LENGTH, length_footer); + match_length += length_footer; + } + match_length += LZX_MIN_MATCH; + + match_offset = main_element >> 3; + + if (match_offset > 2) + { + /* not repeated offset */ + extra = extra_bits[match_offset]; + match_offset = position_base[match_offset] - 2; + if (extra > 3) + { + /* verbatim and aligned bits */ + extra -= 3; + READ_BITS(verbatim_bits, extra); + match_offset += (verbatim_bits << 3); + READ_HUFFSYM(ALIGNED, aligned_bits); + match_offset += aligned_bits; + } + else if (extra == 3) + { + /* aligned bits only */ + READ_HUFFSYM(ALIGNED, aligned_bits); + match_offset += aligned_bits; + } + else if (extra > 0) + { /* extra==1, extra==2 */ + /* verbatim bits only */ + READ_BITS(verbatim_bits, extra); + match_offset += verbatim_bits; + } + else /* extra == 0 */ + { + /* ??? */ + match_offset = 1; + } + + /* update repeated offset LRU queue */ + R2 = R1; R1 = R0; R0 = match_offset; + } + else if (match_offset == 0) + { + match_offset = R0; + } + else if (match_offset == 1) + { + match_offset = R1; + R1 = R0; R0 = match_offset; + } + else /* match_offset == 2 */ + { + match_offset = R2; + R2 = R0; R0 = match_offset; + } + + rundest = window + window_posn; + runsrc = rundest - match_offset; + window_posn += match_length; + this_run -= match_length; + + /* copy any wrapped around source data */ + while ((runsrc < window) && (match_length-- > 0)) + { + *rundest++ = *(runsrc + window_size); runsrc++; + } + /* copy match data - no worries about destination wraps */ + while (match_length-- > 0) *rundest++ = *runsrc++; + + } + } + break; + + case LZX_BLOCKTYPE_UNCOMPRESSED: + if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA; + memcpy(window + window_posn, inpos, (size_t) this_run); + inpos += this_run; window_posn += this_run; + break; + + default: + return DECR_ILLEGALDATA; /* might as well */ + } + + } + } + + if (togo != 0) return DECR_ILLEGALDATA; + memcpy(outpos, window + ((!window_posn) ? window_size : window_posn) - + outlen, (size_t) outlen); + + LZX(window_posn) = window_posn; + LZX(R0) = R0; + LZX(R1) = R1; + LZX(R2) = R2; + + /* intel E8 decoding */ + if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) + { + if (outlen <= 6 || !LZX(intel_started)) + { + LZX(intel_curpos) += outlen; + } + else + { + UBYTE *data = outpos; + UBYTE *dataend = data + outlen - 10; + LONG curpos = LZX(intel_curpos); + LONG filesize = LZX(intel_filesize); + LONG abs_off, rel_off; + + LZX(intel_curpos) = curpos + outlen; + + while (data < dataend) + { + if (*data++ != 0xE8) + { + curpos++; continue; + } + abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24); + if ((abs_off >= -curpos) && (abs_off < filesize)) + { + rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize; + data[0] = (UBYTE) rel_off; + data[1] = (UBYTE) (rel_off >> 8); + data[2] = (UBYTE) (rel_off >> 16); + data[3] = (UBYTE) (rel_off >> 24); + } + data += 4; + curpos += 5; + } + } + } + return DECR_OK; +} + diff --git a/parts/documentation/protocols/chm/decompress.h b/parts/documentation/protocols/chm/decompress.h new file mode 100644 index 00000000..4fa42615 --- /dev/null +++ b/parts/documentation/protocols/chm/decompress.h @@ -0,0 +1,43 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __decompress_h__ +#define __decompress_h__ + +#ifdef __cplusplus__ +extern "C" { +#endif + +typedef unsigned char UBYTE; /* 8 bits exactly */ +typedef unsigned short UWORD; /* 16 bits (or more) */ +typedef unsigned int ULONG; /* 32 bits (or more) */ +typedef signed int LONG; /* 32 bits (or more) */ + +typedef struct lzx_bits +{ + ULONG bb; + int bl; + UBYTE *ip; +} lzx_bits; + +int LZXinit( int window ); +int LZXdecompress( UBYTE *inpos, int inlen, UBYTE *outpos, int outlen ); + +#ifdef __cplusplus__ +} +#endif + +#endif // __decompress_h__ diff --git a/parts/documentation/protocols/chm/kchmpart.cpp b/parts/documentation/protocols/chm/kchmpart.cpp new file mode 100644 index 00000000..b72602c3 --- /dev/null +++ b/parts/documentation/protocols/chm/kchmpart.cpp @@ -0,0 +1,123 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "kchmpart.h" +#include <qstring.h> + +#include <kinstance.h> +#include <kglobal.h> +#include <kdebug.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kaboutdata.h> + +extern "C" +{ + void* init_libkchmpart() + { + return new KChmPartFactory; + } +} + +KInstance* KChmPartFactory::s_instance = 0L; +KAboutData* KChmPartFactory::s_about = 0L; + +KChmPartFactory::KChmPartFactory( QObject* parent, const char* name ) + : KParts::Factory( parent, name ) +{ +} + +KChmPartFactory::~KChmPartFactory() +{ + delete s_instance; + s_instance = 0L; + delete s_about; +} + +KParts::Part* KChmPartFactory::createPartObject( QWidget *parentWidget, const char *, QObject *, + const char *name, const char *, const QStringList & ) +{ + KChmPart* part = new KChmPart( parentWidget, name ); + return part; +} + +KInstance* KChmPartFactory::instance() +{ + if( !s_instance ) + { + s_about = new KAboutData( "kchmpart", + I18N_NOOP( "KChm" ), "1.0pre" ); + s_instance = new KInstance( s_about ); + } + return s_instance; +} + + +KChmPart::KChmPart( QWidget * parent, const char * name ) + : KDevHTMLPart( ), m_job(0) +{ + KInstance * instance = new KInstance( "kchmpart" ); + setInstance( instance ); + m_extension=new KParts::BrowserExtension(this); + setOptions(-1); +} + +bool KChmPart::openURL( const KURL &url ) +{ + KURL chmURL = url; + chmURL.setProtocol("ms-its"); + chmURL.addPath("/"); + return KDevHTMLPart::openURL(chmURL); +} + +void KChmPart::slotDuplicate() +{ +} + +void KChmPart::slotOpenInNewWindow(const KURL &url) +{ +} + + +/* +bool KChmPart::openFile() +{ + if (m_job!=0) + m_job->kill(); + + m_htmlData.truncate(0); + + m_job = KIO::get( QString("chm:")+m_file+"/", true, false ); + connect( m_job, SIGNAL( data( KIO::Job *, const QByteArray &) ), SLOT( readData( KIO::Job *, const QByteArray &) ) ); + connect( m_job, SIGNAL( result( KIO::Job * ) ), SLOT( jobDone( KIO::Job * ) ) ); + return true; +} + +void KChmPart::readData(KIO::Job * , const QByteArray & data) +{ + m_htmlData += data; +} + +void KChmPart::jobDone( KIO::Job *) +{ + m_job=0; + begin(); + write(QString::fromLocal8Bit(m_htmlData)); + end(); +} +*/ +#include "kchmpart.moc" + diff --git a/parts/documentation/protocols/chm/kchmpart.desktop b/parts/documentation/protocols/chm/kchmpart.desktop new file mode 100644 index 00000000..1ddefe13 --- /dev/null +++ b/parts/documentation/protocols/chm/kchmpart.desktop @@ -0,0 +1,46 @@ +[Desktop Entry] +Type=Service +Exec=foobar +Comment=Embeddable HTMLHelp Viewer +Comment[ca]=Visor encastat de l'ajuda HTML +Comment[da]=Indlejrbar HTMLHjælp-fremviser +Comment[de]=Eingebetteter Betrachter für HTMLHelp +Comment[el]=Ενσωματωμένος προβολέας HTMLHelp +Comment[es]=Visor de ayuda HTML empotrable +Comment[et]=Põimitav HTML-abifailide näitaja +Comment[eu]=HTMLHelp ikustaile kapsulagarria +Comment[fa]=مشاهدهگر کمک قابل نهفتۀ زنگام +Comment[fr]=Afficheur HTMLHelp intégrable +Comment[ga]=Comhpháirt inleabaithe amharctha HTML +Comment[gl]=Visor de HTMLHelp incrustable +Comment[hi]=अंतर्निर्मित योग्य एचटीएमएल मदद प्रदर्शक +Comment[hu]=Beágyazható HTML-es dokumentációnézegető +Comment[it]=Visualizzatore integrabile per la guida HTML +Comment[ja]=埋め込み可能な HTMLHelp ビューア +Comment[ms]=Pelihat HTMLHelp Terbinadalam +Comment[nds]=Inbettbor Kieker för HTMLHelp +Comment[ne]=सम्मिलित गर्न मिल्ने HTMLHelp दृश्यकर्ता +Comment[nl]=Ingebedde HTML Helpweergave +Comment[pl]=Wbudowywalna przeglądarka pomocy w formacie HTML +Comment[pt]=Visualizador de HTMLHelp Incorporado +Comment[pt_BR]=Visualizador de Ajuda HTML Embutido +Comment[ru]=Встроенный просмотр HTMLHelp +Comment[sk]=Vložiteľný HTMLHelp prezerač +Comment[sr]=Уградиви приказивач HTMLHelp-а +Comment[sr@Latn]=Ugradivi prikazivač HTMLHelp-a +Comment[sv]=Inbäddningsbar HTML-hjälpvisning +Comment[ta]=HTML உதவி பார்வையாளரை உட்பொதி +Comment[tg]=Намоиши ҳамвори HTMLHelp +Comment[tr]=Gömülebilir HTMLHelp Görüntüleyicisi +Comment[zh_CN]=嵌入的 HTML 帮助查看器 +Comment[zh_TW]=可嵌入 HTMLHelp 檢視器 +MimeType=application/chm +Name=KChmPart +Name[de]=CHM-Betrachter (KDevelop) +Name[hi]=के-सीएचएम-पार्ट +Name[nds]=Chm-Kieker (KDevelop) +Name[pl]=Program KChm +Name[sv]=Kchm-del +ServiceTypes=KParts/ReadOnlyPart,Browser/View +X-KDE-Library=libkchmpart +X-KDevelop-Version=5 diff --git a/parts/documentation/protocols/chm/kchmpart.h b/parts/documentation/protocols/chm/kchmpart.h new file mode 100644 index 00000000..03a12738 --- /dev/null +++ b/parts/documentation/protocols/chm/kchmpart.h @@ -0,0 +1,82 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __kchmpart_h__ +#define __kchmpart_h__ + +#include <kparts/factory.h> +#include <kparts/part.h> +#include <kparts/browserextension.h> +#include <khtml_part.h> +#include <kio/job.h> +#include <kio/jobclasses.h> +#include <kdevhtmlpart.h> + +#include <qcstring.h> + +class KInstance; +class KAboutData; + +class KChmPartFactory: public KParts::Factory +{ + Q_OBJECT + public: + KChmPartFactory( QObject *parent = 0, const char *name = 0 ); + virtual ~KChmPartFactory(); + + virtual KParts::Part* createPartObject( + QWidget *parentWidget, const char *widgetName, + QObject *parent, const char *name, + const char *classname, const QStringList &args ); + + static KInstance *instance(); + + private: + static KInstance *s_instance; + static KAboutData *s_about; + +}; + + +class KChmPart : public KDevHTMLPart +{ + Q_OBJECT + public: + KChmPart( QWidget *, const char * = 0 ); + KParts::BrowserExtension * extension() { return m_extension; } + + public slots: + virtual bool openURL( const KURL & ); +/* + protected slots: + void readData(KIO::Job * , const QByteArray & data); + void jobDone( KIO::Job *); +*/ + protected: + //virtual bool openFile(); + KInstance *m_instance; + KParts::BrowserExtension *m_extension; + KIO::TransferJob *m_job; + QCString m_htmlData; + + protected slots: + virtual void slotDuplicate(); + virtual void slotOpenInNewWindow(const KURL &url); + +}; + +#endif // __kchmpart_h__ + diff --git a/parts/documentation/searchview.cpp b/parts/documentation/searchview.cpp new file mode 100644 index 00000000..253e9f10 --- /dev/null +++ b/parts/documentation/searchview.cpp @@ -0,0 +1,330 @@ +/*************************************************************************** + * Copyright (C) 1999-2001 by Matthias Hoelzer-Kluepfel * + * hoelzer@kde.org * + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "searchview.h" + +#include <qlayout.h> +#include <qlabel.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qdir.h> +#include <qregexp.h> + +#include <kpushbutton.h> +#include <klistview.h> +#include <klineedit.h> +#include <kcombobox.h> +#include <klocale.h> +#include <kdialog.h> +#include <kprocess.h> +#include <kapplication.h> +#include <kstandarddirs.h> +#include <kconfig.h> +#include <kmessagebox.h> +#include <kdebug.h> + +#include <kdevpartcontroller.h> +#include <kdevdocumentationplugin.h> + +#include "documentation_part.h" +#include "docutils.h" + +SearchView::SearchView(DocumentationPart *part, QWidget *parent, const char *name) + :QWidget(parent, name), m_part(part) +{ + QVBoxLayout *l = new QVBoxLayout(this, 0, KDialog::spacingHint()); + + QVBoxLayout *l2 = new QVBoxLayout(l, 0); + QLabel *editLabel = new QLabel(i18n("Wor&ds to search:"), this); + l2->addWidget(editLabel); + QHBoxLayout *l21 = new QHBoxLayout(l2, 0); + m_edit = new KLineEdit(this); + editLabel->setBuddy(m_edit); + m_goSearchButton = new KPushButton(i18n("Se&arch"), this); + l21->addWidget(m_edit); + l21->addWidget(m_goSearchButton); + + QGridLayout *l3 = new QGridLayout(l, 2, 2, 0); + m_searchMethodBox = new KComboBox(this); + m_searchMethodBox->insertItem(i18n("and")); + m_searchMethodBox->insertItem(i18n("or")); + QLabel *smLabel = new QLabel(m_searchMethodBox, i18n("&Method:"), this); + m_sortMethodBox = new KComboBox(this); + m_sortMethodBox->insertItem(i18n("Score")); + m_sortMethodBox->insertItem(i18n("Title")); + m_sortMethodBox->insertItem(i18n("Date")); + QLabel *rmLabel = new QLabel(m_sortMethodBox, i18n("S&ort by:"), this); + l3->addWidget(smLabel, 0, 0); + l3->addWidget(m_searchMethodBox, 0, 1); + l3->addWidget(rmLabel, 1, 0); + l3->addWidget(m_sortMethodBox, 1, 1); + + QVBoxLayout *l4 = new QVBoxLayout(l, 0); + m_view = new KListView(this); + QLabel *vLabel = new QLabel(m_view, i18n("Search &results:"), this); + l4->addWidget(vLabel); + l4->addWidget(m_view); + + QHBoxLayout *l5 = new QHBoxLayout(l, KDialog::spacingHint()); + m_configButton = new KPushButton(i18n("Update Config"), this); + m_indexButton = new KPushButton(i18n("Update Index"), this); + l5->addWidget(m_configButton); + l5->addWidget(m_indexButton); + l5->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed)); + + l->addSpacing(2); + + m_view->setSorting(-1); + m_view->addColumn(i18n("Relevance")); + m_view->addColumn(i18n("Title")); + m_view->setColumnWidthMode(0, QListView::Maximum); + m_view->setColumnWidthMode(1, QListView::Maximum); + m_view->setAllColumnsShowFocus(true); + m_view->setResizeMode( QListView::LastColumn ); + + connect(m_configButton, SIGNAL(clicked()), this, SLOT(updateConfig())); + connect(m_indexButton, SIGNAL(clicked()), this, SLOT(updateIndex())); + connect(m_edit, SIGNAL(returnPressed()), this, SLOT(search())); + connect(m_goSearchButton, SIGNAL(clicked()), this, SLOT(search())); + connect(m_view, SIGNAL(executed(QListViewItem*)), this, SLOT(executed(QListViewItem*))); + connect(m_view, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int )), + this, SLOT(itemMouseButtonPressed(int, QListViewItem*, const QPoint&, int ))); +} + +SearchView::~SearchView() +{ +} + +void SearchView::updateConfig() +{ + runHtdig("-c"); +} + +void SearchView::updateIndex() +{ + runHtdig("-i"); + KConfig *config = m_part->config(); + config->setGroup("htdig"); + config->writeEntry("IsSetup", true); + config->sync(); +} + +void SearchView::runHtdig(const QString &arg) +{ + KProcess proc; + proc << "kdevelop-htdig" << arg; + proc.start(KProcess::DontCare); +} + +void qt_enter_modal(QWidget *widget); +void qt_leave_modal(QWidget *widget); + +void SearchView::search() +{ + KConfig *config = m_part->config(); + config->setGroup("htdig"); + if (config->readBoolEntry("IsSetup", false) == false) + { + KMessageBox::information(this, i18n("Full text search has to be set up before usage.")); + if (!m_part->configure(1)) + return; + KMessageBox::information(this, i18n("Now the full text search database will be created.\nWait for database creation to finish and then repeat search.")); + updateIndex(); + return; + } + QString exe = config->readPathEntry("htsearchbin", kapp->dirs()->findExe("htsearch")); + if (exe.isEmpty()) + { + KMessageBox::error(this, i18n("Cannot find the htsearch executable.\nIt is part of the ht://Dig package that is used by KDevelop to perform full text search. Please install ht://Dig and use Documentation page in Configure KDevelop dialog to set the htsearch location.")); + kdDebug() << "Can not find htsearch" << endl; + return; + } + + QString indexdir = kapp->dirs()->saveLocation("data", "kdevdocumentation/search"); + QDir d; + if (indexdir.isEmpty() || !QFile::exists(indexdir + "/htdig.conf")) + { + if (QFile::exists("/var/lib/kdevelop3/helpindex/htdig.conf")) + indexdir = "/var/lib/kdevelop3/helpindex"; + else if (QFile::exists("/var/lib/kdevelop/helpindex/htdig.conf")) + indexdir = "/var/lib/kdevelop/helpindex"; + + if (!QFile::exists(indexdir + "/htdig.conf")) + { + KMessageBox::error(this, i18n("Cannot find the htdig configuration file.")); + kdDebug() << "Cannot find the htdig configuration file" << endl; + return; + } + } + + QString savedir = kapp->dirs()->saveLocation("data", "kdevdocumentation/search"); + if (!d.exists(savedir)) + d.mkdir(savedir); + + QString query = QString("words=%1;method=%2;matchesperpage=%3;format=%4;sort=%5") + .arg(m_edit->text()) + .arg(m_searchMethodBox->currentItem()==1? "or" : "and") + .arg(50) + .arg("builtin-short") + .arg(m_sortMethodBox->currentItem()==2? "date" : m_sortMethodBox->currentItem()==1? "title" : "score"); + + kdDebug(9002) << "starting kprocess" << endl; + kdDebug(9002) << "htdig line:" << exe << " -c " << (indexdir + "/htdig.conf ") << query << endl; + KProcess *proc = new KProcess; + QString picdir = kapp->dirs()->findResourceDir("data", "kdevdocumentation/pics/htdig.png"); + proc->setEnvironment("PICDIR", picdir); + *proc << exe << "-c" << (indexdir + "/htdig.conf") << query; + + connect( proc, SIGNAL(receivedStdout(KProcess *,char*,int)), + this, SLOT(htsearchStdout(KProcess *,char*,int)) ); + connect( proc, SIGNAL(processExited(KProcess *)), + this, SLOT(htsearchExited(KProcess *)) ); + + searchResult = ""; + + if (!proc->start(KProcess::NotifyOnExit, KProcess::Stdout)) + { + KMessageBox::error(this, i18n("Cannot start the htsearch executable.")); + kdDebug() << "process start failed" << endl; + delete proc; + return; + } + + // While receiving data from the subprocess, we want + // to block the user interface, but still get repaint + // events. Hack taken from NetAccess... + kapp->setOverrideCursor(waitCursor); + QWidget blocker(0, 0, WType_Dialog | WShowModal); + qt_enter_modal(&blocker); + kapp->enter_loop(); + qt_leave_modal(&blocker); + kapp->restoreOverrideCursor(); + + if (!proc->normalExit() || proc->exitStatus() != 0) + { + kdDebug() << "Error running htsearch... returning now" << endl; + delete proc; + return; + } + + delete proc; + + // modify the search result + searchResult = searchResult.replace(QRegExp("http://localhost/"), "file:/"); + searchResult = searchResult.replace(QRegExp("Content-type: text/html"), ""); + + // dump the search result + QFile f(savedir + "/results.html"); + if (f.open(IO_WriteOnly)) + { + QTextStream ts(&f); + ts << searchResult << endl; + f.close(); + } + + //show results + analyseSearchResults(); +// m_part->partController()->showDocument(KURL("file://" + indexdir + "/results.html")); +} + +void SearchView::htsearchStdout(KProcess *, char *buffer, int len) +{ + searchResult += QString::fromLocal8Bit(buffer, len); +} + +void SearchView::htsearchExited(KProcess *) +{ + kapp->exit_loop(); +} + +void SearchView::analyseSearchResults() +{ + m_view->clear(); + QTextStream str(searchResult, IO_ReadOnly); + DocumentationItem *former = 0; + while (!str.eof()) + { + QString line = str.readLine(); + + QRegExp starsExp("alt=\"\\*\""); + starsExp.setMinimal(true); + int stars = line.contains(starsExp); + + QRegExp urlExp("<strong><a href=\"(.*)\">(.*)</a></strong>"); + if (urlExp.search(line)==-1) + continue; + QString url = urlExp.cap(1); + QString title = urlExp.cap(2); + + QString starsStr; + for (int i = 0; i < stars; ++i) + starsStr += "*"; + + if (former) + former = new DocumentationItem(DocumentationItem::Document, m_view, former, starsStr); + else + former = new DocumentationItem(DocumentationItem::Document, m_view, starsStr); + former->setText(1, title); + former->setURL(KURL(url)); + } + + executed( m_view->firstChild() ); +} + +void SearchView::executed(QListViewItem *item) +{ + DocumentationItem *d = dynamic_cast<DocumentationItem*>(item); + if (!d) + return; + + m_part->partController()->showDocument(d->url()); +} + +void SearchView::itemMouseButtonPressed(int button, QListViewItem *item, const QPoint &pos, int // c + ) +{ + if ((button != Qt::RightButton) || (!item)) + return; + DocumentationItem *docItem = dynamic_cast<DocumentationItem*>(item); + if (!docItem) + return; + + DocUtils::docItemPopup(m_part, docItem, pos, true, false, 1); +} + +void SearchView::setSearchTerm(const QString &term) +{ + m_edit->setText(term); +} + +void SearchView::askSearchTerm() +{ + m_edit->setFocus(); +} + +void SearchView::focusInEvent(QFocusEvent */*e*/) +{ + m_edit->setFocus(); +} + +#include "searchview.moc" diff --git a/parts/documentation/searchview.h b/parts/documentation/searchview.h new file mode 100644 index 00000000..3d37fdfe --- /dev/null +++ b/parts/documentation/searchview.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef SEARCHVIEW_H +#define SEARCHVIEW_H + +#include <qwidget.h> + +class DocumentationPart; +class KLineEdit; +class KComboBox; +class KListView; +class KPushButton; +class KProcess; +class QListViewItem; + +class SearchView: public QWidget +{ + Q_OBJECT +public: + SearchView(DocumentationPart *part, QWidget *parent = 0, const char *name = 0); + ~SearchView(); + +public slots: + void search(); + void setSearchTerm(const QString &term); + void askSearchTerm(); + +protected slots: + void updateConfig(); + void updateIndex(); + + void htsearchStdout(KProcess *, char *buffer, int len); + void htsearchExited(KProcess *); + void executed(QListViewItem *item); + + void itemMouseButtonPressed(int button, QListViewItem *item, const QPoint &pos, int c); + +protected: + virtual void focusInEvent(QFocusEvent *e); + + void runHtdig(const QString &arg); + void analyseSearchResults(); + +private: + DocumentationPart *m_part; + + KLineEdit *m_edit; + KComboBox *m_searchMethodBox; + KComboBox *m_sortMethodBox; + KListView *m_view; + KPushButton *m_configButton; + KPushButton *m_indexButton; + KPushButton *m_goSearchButton; + + QString searchResult; +}; + +#endif diff --git a/parts/documentation/selecttopic.cpp b/parts/documentation/selecttopic.cpp new file mode 100644 index 00000000..b0e64f4c --- /dev/null +++ b/parts/documentation/selecttopic.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "selecttopic.h" + +SelectTopic::SelectTopic(IndexItem::List &urls, QWidget *parent, const char *name) + :SelectTopicBase(parent, name), m_urls(urls) +{ + for (IndexItem::List::const_iterator it = m_urls.begin(); it != m_urls.end(); ++it) + topicBox->insertItem((*it).first); + if (topicBox->item(0)) + { + topicBox->setCurrentItem(0); + topicBox->setSelected(topicBox->item(0), true); + } +} + +void SelectTopic::accept() +{ + if (topicBox->currentItem() == -1) + return; + else + return QDialog::accept(); +} + +KURL SelectTopic::selectedURL() +{ + if (topicBox->currentItem() != -1) + return m_urls[topicBox->currentItem()].second; + return KURL(); +} + +#include "selecttopic.moc" diff --git a/parts/documentation/selecttopic.h b/parts/documentation/selecttopic.h new file mode 100644 index 00000000..1321bf99 --- /dev/null +++ b/parts/documentation/selecttopic.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef SELECT_TOPIC_H +#define SELECT_TOPIC_H + +#include "selecttopicbase.h" + +#include "kdevdocumentationplugin.h" + +class SelectTopic: public SelectTopicBase{ +Q_OBJECT +public: + SelectTopic(IndexItem::List &urls, QWidget *parent = 0, const char *name = 0); + KURL selectedURL(); + +public slots: + virtual void accept(); + +private: + IndexItem::List m_urls; +}; + +#endif diff --git a/parts/documentation/selecttopicbase.ui b/parts/documentation/selecttopicbase.ui new file mode 100644 index 00000000..b363be2a --- /dev/null +++ b/parts/documentation/selecttopicbase.ui @@ -0,0 +1,142 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>SelectTopicBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>SelectTopicBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>429</width> + <height>211</height> + </rect> + </property> + <property name="caption"> + <string>Choose Topic</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>topicLabel</cstring> + </property> + <property name="text"> + <string>Choose a topic for <b>%1</b>:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>listBox1</cstring> + </property> + </widget> + <widget class="QListBox" row="1" column="0"> + <property name="name"> + <cstring>topicBox</cstring> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>SelectTopicBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>SelectTopicBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>topicBox</sender> + <signal>doubleClicked(QListBoxItem*)</signal> + <receiver>SelectTopicBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>topicBox</sender> + <signal>returnPressed(QListBoxItem*)</signal> + <receiver>SelectTopicBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<tabstops> + <tabstop>topicBox</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot>newSlot()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/parts/documentation/tools/Makefile.am b/parts/documentation/tools/Makefile.am new file mode 100644 index 00000000..c2344983 --- /dev/null +++ b/parts/documentation/tools/Makefile.am @@ -0,0 +1,3 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util $(all_includes) +METASOURCES = AUTO +SUBDIRS = htdig diff --git a/parts/documentation/tools/htdig/Makefile.am b/parts/documentation/tools/htdig/Makefile.am new file mode 100644 index 00000000..8f38a799 --- /dev/null +++ b/parts/documentation/tools/htdig/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util $(all_includes) +METASOURCES = AUTO +bin_PROGRAMS = kdevelop-htdig +kdevelop_htdig_LDFLAGS = $(all_libraries) $(LIB_KIO) $(LIB_KDEUI) +kdevelop_htdig_SOURCES = htdigindex.cpp +noinst_HEADERS = htdigindex.h diff --git a/parts/documentation/tools/htdig/htdigindex.cpp b/parts/documentation/tools/htdig/htdigindex.cpp new file mode 100644 index 00000000..80161301 --- /dev/null +++ b/parts/documentation/tools/htdig/htdigindex.cpp @@ -0,0 +1,491 @@ +/*************************************************************************** + * Copyright (C) 1999-2001 by Matthias Hoelzer-Kluepfel * + * hoelzer@kde.org * + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "htdigindex.h" + +#include <iostream> + +#include <qapplication.h> +#include <qdir.h> +#include <qfile.h> +#include <qlayout.h> +#include <qtextstream.h> +#include <qtimer.h> +#include <qlabel.h> + +#include <kaboutdata.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kprocess.h> +#include <kdeversion.h> +#include <kprogress.h> + +#define INDEXER + +ProgressDialog::ProgressDialog(bool index, QWidget *parent, const char *name) + :KDialogBase(KDialogBase::Plain, i18n("Generating Search Index"), Cancel | Ok, Close, + parent, name, false) +{ + proc = 0; + + indexdir = kapp->dirs()->saveLocation("data", "kdevdocumentation/search"); + QDir d; d.mkdir(indexdir); + + KConfig config("kdevdocumentation", true); + config.setGroup("htdig"); + databaseDir = config.readPathEntry("databaseDir", indexdir); + + if (!index) + return; + + d.mkdir( databaseDir ); + + showButtonOK( false ); + QGridLayout *grid = new QGridLayout(plainPage(), 5,3, spacingHint()); + + QLabel *l = new QLabel(i18n("Scanning for files"), plainPage()); + grid->addMultiCellWidget(l, 0, 0, 1, 2); + + filesLabel = new QLabel(plainPage()); + grid->addWidget(filesLabel, 1, 2); + setFilesScanned(0); + + check1 = new QLabel(plainPage()); + grid->addWidget(check1, 0, 0); + + l = new QLabel(i18n("Extracting search terms"), plainPage()); + grid->addMultiCellWidget(l, 2,2, 1,2); + + bar = new KProgress(plainPage()); + grid->addWidget(bar, 3,2); + + check2 = new QLabel(plainPage()); + grid->addWidget(check2, 2,0); + + l = new QLabel(i18n("Generating index..."), plainPage()); + grid->addMultiCellWidget(l, 4,4, 1,2); + + check3 = new QLabel(plainPage()); + grid->addWidget(check3, 4,0); + + setState(0); + + setMinimumWidth(300); + connect(this, SIGNAL(cancelClicked()), this, SLOT(cancelClicked())); + connect(this, SIGNAL(okClicked()), this, SLOT(okClicked())); + QTimer::singleShot(0, this, SLOT(slotDelayedStart())); +} + +ProgressDialog::~ProgressDialog() +{ +} + +void ProgressDialog::slotDelayedStart() +{ + procdone = false; + scanDirectories(); + if (!createConfig()) + { + done(1); + return; + } + generateIndex(); +} + +void ProgressDialog::done(int r) +{ + if (!r) + { + showButtonCancel( false ); + showButtonOK( true ); + } + else + KDialogBase::done(r); +} + +void ProgressDialog::setFilesScanned(int n) +{ + filesLabel->setText(i18n("Files processed: %1").arg(n)); +} + +void ProgressDialog::setFilesToDig(int n) +{ + bar->setTotalSteps(n); +} + +void ProgressDialog::setFilesDigged(int n) +{ + bar->setValue(n); +} + +void ProgressDialog::setState(int n) +{ + QPixmap unchecked = QPixmap(locate("data", "kdevdocumentation/pics/unchecked.xpm")); + QPixmap checked = QPixmap(locate("data", "kdevdocumentation/pics/checked.xpm")); + + check1->setPixmap( n > 0 ? checked : unchecked); + check2->setPixmap( n > 1 ? checked : unchecked); + check3->setPixmap( n > 2 ? checked : unchecked); +} + + +void ProgressDialog::addDir(const QString &dir) +{ + kdDebug(9002) << "Add dir : " << dir << endl; + QDir d(dir, "*.html", QDir::Name|QDir::IgnoreCase, QDir::Files | QDir::Readable); + QStringList list = d.entryList(); + + QStringList::ConstIterator it; + for ( it=list.begin(); it!=list.end(); ++it ) + { + if( (*it).right( 12 ).lower( ) == "-source.html" ) + continue; + + files.append(dir + "/" + *it); + setFilesScanned(++filesScanned); + } + + QDir d2(dir, QString::null, QDir::Name|QDir::IgnoreCase, QDir::Dirs); + QStringList dlist = d2.entryList(); + + for ( it=dlist.begin(); it != dlist.end(); ++it ) + { + if (*it != "." && *it != "..") + { + addDir(dir + "/" + *it); + kapp->processEvents(); + } + if (procdone) + { + return; + } + } + kapp->processEvents(); +} + +void ProgressDialog::scanDirectories() +{ + QString ftsLocationsFile = locateLocal("data", "kdevdocumentation/search/locations.txt"); + + QFile f(ftsLocationsFile); + if (!f.open(IO_ReadOnly)) + return; + QTextStream str(&f); + + filesScanned = 0; + + while (!str.eof()) + { + QString loc = str.readLine(); + if (loc.isEmpty()) + continue; + QFileInfo fi(loc); + if (fi.isDir()) + addDir(loc); + else if (fi.isFile()) + { + files.append(loc); + setFilesScanned(++filesScanned); + } + } +} + +bool ProgressDialog::createConfig() +{ + // locate the common dir + QString language = KGlobal::locale()->language(); + if (language == "C") + language = "en"; + + QString wrapper = locate("data", QString("kdevdocumentation/%1/wrapper.html").arg(language)); + if (wrapper.isEmpty()) + wrapper = locate("data", QString("kdevdocumentation/en/wrapper.html")); + if (wrapper.isEmpty()) + return false; + wrapper = wrapper.left(wrapper.length()-12); + + // locate the image dir + QString images = locate("data", "kdevdocumentation/pics/star.png"); + if (images.isEmpty()) + return false; + images = images.left(images.length()-8); + + QFile f(indexdir + "/htdig.conf"); + if (f.open(IO_WriteOnly)) + { + QTextStream ts(&f); + + ts << "database_dir:\t\t" << databaseDir << endl; + ts << "start_url:\t\t`" << indexdir << "/files`" << endl; + ts << "local_urls:\t\thttp://localhost/=/" << endl; +// ts << "local_urls:\t\tfile://=" << endl; + ts << "local_urls_only:\ttrue" << endl; + ts << "limit_urls_to:\t\tfile:// http://localhost/" << endl; + ts << "maximum_pages:\t\t1" << endl; + ts << "image_url_prefix:\t" << images << endl; + ts << "star_image:\t\t" << images << "star.png" << endl; + ts << "star_blank:\t\t" << images << "star_blank.png" << endl; + ts << "compression_level:\t6" << endl; + ts << "max_hop_count:\t\t0" << endl; + + ts << "search_results_wrapper:\t" << wrapper << "wrapper.html" << endl; + ts << "nothing_found_file:\t" << wrapper << "nomatch.html" << endl; + ts << "syntax_error_file:\t" << wrapper << "syntax.html" << endl; + ts << "bad_word_list:\t\t" << wrapper << "bad_words" << endl; + + f.close(); + return true; + } + + return false; +} + +#define CHUNK_SIZE 100 + +void ProgressDialog::startHtdigProcess(bool initial) +{ + kdDebug(9002) << "htdig started" << endl; + delete proc; + proc = new KProcess(); + *proc << exe << "-c" << (indexdir + "/htdig.conf"); + if (initial) { + *proc << "-i"; + } + connect(proc, SIGNAL(processExited(KProcess *)), + this, SLOT(htdigExited(KProcess *))); + + htdigRunning = true; + + // write out file + QFile f(indexdir+"/files"); + if (!f.open(IO_WriteOnly)) { + kdDebug(9002) << "Could not open `files` for writing" << endl; + done(1); + return; + } + QTextStream ts(&f); + for (int i=0; i<CHUNK_SIZE; ++i, ++count) { + if (count >= filesToDig) { + procdone = true; + break; + } + // ts << "file://localhost/" + files[count] << endl; + ts << "http://localhost/" + files[count] << endl; + } + f.close(); + + // execute htdig + proc->start(KProcess::NotifyOnExit, KProcess::Stdout); +} + +bool ProgressDialog::generateIndex() +{ + setState(1); + procdone = false; + // run htdig + KConfig config("kdevdocumentation", true); + config.setGroup("htdig"); + exe = config.readPathEntry("htdigbin", kapp->dirs()->findExe("htdig")); + if (exe.isEmpty()) + { + done(1); + return true; + } + filesToDig = files.count(); + count = 0; + setFilesToDig(filesToDig); + filesDigged = 0; + + // QDir d; d.mkdir(indexdir); + startHtdigProcess(true); + return true; +} + +void ProgressDialog::htdigStdout(KProcess *, char *buffer, int len) +{ + QString line = QString(buffer).left(len); + + int cnt=0, index=-1; + while ( (index = line.find("http://", index+1)) > 0) + cnt++; + filesDigged += cnt; + + cnt=0, index=-1; + while ( (index = line.find("not changed", index+1)) > 0) + cnt++; + filesDigged -= cnt; + + setFilesDigged(filesDigged); +} + +void ProgressDialog::htdigExited(KProcess *proc) +{ + kdDebug(9002) << "htdig terminated" << endl; + if (!proc->normalExit()) + { + delete proc; + proc = 0L; + done(1); + return; + } + if (proc && proc->exitStatus() != 0) + { + KMessageBox::sorry(0, i18n("Running htdig failed")); + delete proc; + proc = 0L; + done(1); + return; + } + htdigRunning = false; + filesDigged += CHUNK_SIZE; + setFilesDigged(filesDigged); + if (!procdone) + { + startHtdigProcess(false); + } + else + { + setFilesDigged(filesToDig); + setState(2); + + KConfig config("kdevdocumentation", true); + config.setGroup("htdig"); + // run htmerge ----------------------------------------------------- + exe = config.readPathEntry("htmergebin", kapp->dirs()->findExe("htmerge")); + if (exe.isEmpty()) + { + done(1); + return; + } + startHtmergeProcess(); + } +} + +void ProgressDialog::startHtmergeProcess() +{ + kdDebug(9002) << "htmerge started" << endl; + delete proc; + proc = new KProcess(); + *proc << exe << "-c" << (indexdir + "/htdig.conf"); + + kdDebug(9002) << "Running htmerge" << endl; + + connect(proc, SIGNAL(processExited(KProcess *)), + this, SLOT(htmergeExited(KProcess *))); + + htmergeRunning = true; + + proc->start(KProcess::NotifyOnExit, KProcess::Stdout); +} + +void ProgressDialog::htmergeExited(KProcess *proc) +{ + kdDebug(9002) << "htmerge terminated" << endl; + htmergeRunning = false; + if (!proc->normalExit()) + { + delete proc; + proc = 0L; + done(1); + return; + } + if (proc && proc->exitStatus() != 0) + { + KMessageBox::sorry(0, i18n("Running htmerge failed")); + delete proc; + proc = 0L; + done(1); + return; + } + setState(3); + done(0); +} + +void ProgressDialog::cancelClicked() +{ + if ((htdigRunning || htmergeRunning) && proc && proc->isRunning()) + { + kdDebug(9002) << "Killing " << (htdigRunning ? "htdig" : "htmerge") << "daemon with Sig. 9" << endl; + proc->kill(9); + htdigRunning = htmergeRunning = false; + } + else + { + procdone = true; + done(2); + } +} + +void ProgressDialog::okClicked() +{ + if (proc) + proc->kill(); + + KDialogBase::done(0); +} + +int main(int argc, char *argv[]) +{ + static const KCmdLineOptions options[] = + { + { "c", I18N_NOOP( "Update user's htdig configuration file only" ), 0 }, + { "i", I18N_NOOP( "-c and generate index" ), 0 }, + KCmdLineLastOption + }; + + KAboutData aboutData("kdevelop-htdig", I18N_NOOP("KDevelop ht://Dig Indexer"), + "0.2", I18N_NOOP("KDE Index generator for documentation files.")); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + + KGlobal::locale()->setMainCatalogue("kdevelop"); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if (args->isSet("c")) + { + ProgressDialog *search = new ProgressDialog( false, 0, "progress dialog"); + + if (search->createConfig()) + KMessageBox::information(0, i18n("Configuration file updated.")); + else + KMessageBox::error(0, i18n("Configuration file update failed.")); + } + else + if (args->isSet("i")) + { + ProgressDialog *search = new ProgressDialog(true, 0, "progress dialog"); + app.setMainWidget(search); + search->show(); + app.exec(); + } + else + { + std::cerr << "Internal error generating index - unknown argument\n" << std::endl; + return 1; + } + + return 0; +} + +#include "htdigindex.moc" diff --git a/parts/documentation/tools/htdig/htdigindex.h b/parts/documentation/tools/htdig/htdigindex.h new file mode 100644 index 00000000..eec8b595 --- /dev/null +++ b/parts/documentation/tools/htdig/htdigindex.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 1999-2001 by Matthias Hoelzer-Kluepfel * + * hoelzer@kde.org * + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2004 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef _HTDIGINDEX_H_ +#define _HTDIGINDEX_H_ + +#include <kdialogbase.h> + +class QTimer; +class QLabel; +class KProcess; +class KProgress; + +class ProgressDialog : public KDialogBase +{ + Q_OBJECT +public: + ProgressDialog(bool index, QWidget *parent=0, const char *name=0); + ~ProgressDialog(); + + void addDir(const QString &dir); + void scanDirectories(); + bool createConfig(); + bool generateIndex(); + +private slots: + void htdigStdout(KProcess *proc, char *buffer, int buflen); + void htdigExited(KProcess *proc); + void htmergeExited(KProcess *proc); + void cancelClicked(); + void okClicked(); + void slotDelayedStart(); + +private: + void setFilesScanned(int s); + void setFilesToDig(int d); + void setFilesDigged(int d); + void setState(int n); + void done(int r); + void startHtdigProcess(bool initial); + void startHtmergeProcess(); + + QLabel *filesLabel, *check1, *check2, *check3; + KProgress *bar; + + int count; + bool procdone; + QString databaseDir; + QString indexdir; + QString exe; + QStringList files; + KProcess *proc; + volatile int filesToDig, filesDigged, filesScanned; + bool htdigRunning, htmergeRunning; +}; + +#endif |