|
|
|
/* 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., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
#include "kdevdocumentationplugin.h"
|
|
|
|
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqstyle.h>
|
|
|
|
#include <tqheader.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <tdeconfig.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kdirwatch.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
|
|
|
|
//class DocumentationItem
|
|
|
|
|
|
|
|
DocumentationItem::DocumentationItem(DocumentationItem::Type type, TDEListView *parent,
|
|
|
|
const TQString &name)
|
|
|
|
:TDEListViewItem(parent, name), m_type(type)
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
DocumentationItem::DocumentationItem(DocumentationItem::Type type, TDEListViewItem *parent,
|
|
|
|
const TQString &name)
|
|
|
|
:TDEListViewItem(parent, name), m_type(type)
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
DocumentationItem::DocumentationItem(DocumentationItem::Type type, TDEListView *parent,
|
|
|
|
TDEListViewItem *after, const TQString &name)
|
|
|
|
:TDEListViewItem(parent, after, name), m_type(type)
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
DocumentationItem::DocumentationItem(DocumentationItem::Type type, TDEListViewItem * parent,
|
|
|
|
TDEListViewItem * after, const TQString & name )
|
|
|
|
:TDEListViewItem(parent, after, name), m_type(type)
|
|
|
|
{
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationItem::init( )
|
|
|
|
{
|
|
|
|
TQString icon;
|
|
|
|
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case Collection:
|
|
|
|
case Catalog:
|
|
|
|
icon = "folder";
|
|
|
|
break;
|
|
|
|
case Book:
|
|
|
|
icon = "contents";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
icon = "text-x-generic";
|
|
|
|
}
|
|
|
|
|
|
|
|
setPixmap(0, SmallIcon(icon));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
//class DocumentationCatalogItem
|
|
|
|
|
|
|
|
DocumentationCatalogItem::DocumentationCatalogItem(DocumentationPlugin* plugin,
|
|
|
|
TDEListView *parent, TDEListViewItem *after, const TQString &name)
|
|
|
|
:DocumentationItem(DocumentationItem::Catalog, parent, after, name), m_plugin(plugin),
|
|
|
|
isLoaded(false), isActivated(false), m_isProjectDocumentationItem(false)
|
|
|
|
{
|
|
|
|
setExpandable(true);
|
|
|
|
m_plugin->addCatalog(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
DocumentationCatalogItem::DocumentationCatalogItem(DocumentationPlugin* plugin,
|
|
|
|
DocumentationItem *parent, const TQString &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 TQString &text, const TQString &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 TQString &text)
|
|
|
|
:TQListBoxText(listbox, text), m_listbox(listbox)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
IndexItem::List IndexItem::urls() const
|
|
|
|
{
|
|
|
|
List urlList;
|
|
|
|
TQValueList<IndexItemProto*> itemProtos = m_listbox->items[text()];
|
|
|
|
for (TQValueList<IndexItemProto*>::const_iterator it = itemProtos.begin();
|
|
|
|
it != itemProtos.end(); ++it)
|
|
|
|
urlList.append(qMakePair((*it)->description(), (*it)->url()));
|
|
|
|
return urlList;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
//class ConfigurationItem
|
|
|
|
|
|
|
|
ConfigurationItem::ConfigurationItem(TQListView *parent, DocumentationPlugin * plugin, const TQString &title, const TQString &url,
|
|
|
|
bool indexPossible, bool fullTextSearchPossible)
|
|
|
|
:TQCheckListItem(parent, "", TQCheckListItem::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(TQPainter *p, const TQColorGroup &cg, int column,
|
|
|
|
int width, int align)
|
|
|
|
{
|
|
|
|
if ( (column == 0) || (column == 1) || (column == 2) )
|
|
|
|
{
|
|
|
|
if ( !p )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQListView *lv = listView();
|
|
|
|
if ( !lv )
|
|
|
|
return;
|
|
|
|
|
|
|
|
const BackgroundMode bgmode = lv->viewport()->backgroundMode();
|
|
|
|
const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
|
|
|
|
p->fillRect(0, 0, width, height(), cg.brush(crole));
|
|
|
|
|
|
|
|
TQFontMetrics fm(lv->fontMetrics());
|
|
|
|
int boxsize = lv->style().pixelMetric(TQStyle::PM_CheckListButtonSize, lv);
|
|
|
|
int marg = lv->itemMargin();
|
|
|
|
int styleflags = TQStyle::Style_Default;
|
|
|
|
|
|
|
|
if (((column == 0) && m_contents) || ((column == 1) && m_index) || ((column == 2) && m_fullTextSearch))
|
|
|
|
styleflags |= TQStyle::Style_On;
|
|
|
|
else
|
|
|
|
styleflags |= TQStyle::Style_Off;
|
|
|
|
if ((column == 0) || ((column == 1) && m_indexPossible) || ((column == 2) && m_fullTextSearchPossible))
|
|
|
|
styleflags |= TQStyle::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;
|
|
|
|
|
|
|
|
TQStyleOption opt(this);
|
|
|
|
lv->style().drawPrimitive(TQStyle::PE_CheckListIndicator, p,
|
|
|
|
TQRect(x, y, boxsize, fm.height() + 2 + marg), cg, styleflags, opt);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
TQListViewItem::paintCell(p, cg, column, width, align);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ConfigurationItem::width(const TQFontMetrics &fm, const TQListView *lv, int c) const
|
|
|
|
{
|
|
|
|
if ((c == 0) || (c == 1) || (c == 2))
|
|
|
|
return lv->style().pixelMetric(TQStyle::PM_CheckListButtonSize, lv) + 4;
|
|
|
|
return TQListViewItem::width(fm, lv, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
//class DocumentationPlugin
|
|
|
|
|
|
|
|
DocumentationPlugin::DocumentationPlugin(TDEConfig *pluginConfig, TQObject *parent, const char *name)
|
|
|
|
:TQObject(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::clear()
|
|
|
|
{
|
|
|
|
// Do not clear the project documentation catalogs, since those are handled by
|
|
|
|
// the ProjectDocumentationPlugin class
|
|
|
|
for (TQValueList<DocumentationCatalogItem *>::iterator it = catalogs.begin();
|
|
|
|
it != catalogs.end(); /*none*/)
|
|
|
|
{
|
|
|
|
if (!(*it)->isProjectDocumentationItem())
|
|
|
|
{
|
|
|
|
DocumentationCatalogItem *curr = *it;
|
|
|
|
++it; // Need to advance before destroying the catalog, otherwise it could crash
|
|
|
|
//clearCatalog(curr); -- not necessary, already invoked by ~DocumentationCatalogItem()
|
|
|
|
delete curr; // Destroy and removes the item from the TDEListView
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::clearCatalog(DocumentationCatalogItem *item)
|
|
|
|
{
|
|
|
|
//clear named catalog map
|
|
|
|
for (TQMap<TQString, DocumentationCatalogItem*>::iterator it = namedCatalogs.begin();
|
|
|
|
it != namedCatalogs.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it.data() == item)
|
|
|
|
{
|
|
|
|
namedCatalogs.remove(it);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//clear indexes for catalog
|
|
|
|
TQValueList<IndexItemProto *> idx = indexes[item];
|
|
|
|
for (TQValueList<IndexItemProto *>::iterator it = idx.begin(); it != idx.end(); ++it)
|
|
|
|
{
|
|
|
|
delete *it;
|
|
|
|
}
|
|
|
|
indexes.remove(item);
|
|
|
|
//clear the catalog
|
|
|
|
catalogs.remove(item); // Removes the item from the catalog list
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::createIndex(IndexBox *index)
|
|
|
|
{
|
|
|
|
if (m_indexCreated)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (TQValueList<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;
|
|
|
|
|
|
|
|
TQString cacheName = locateLocal("data", TQString("kdevdocumentation/index/cache_") + item->text(0));
|
|
|
|
TQFile cacheFile(cacheName);
|
|
|
|
if (!cacheFile.open(IO_WriteOnly))
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQTextStream str(&cacheFile);
|
|
|
|
str.setEncoding(TQTextStream::Unicode);
|
|
|
|
str << CACHE_VERSION << endl;
|
|
|
|
|
|
|
|
TQValueList<IndexItemProto*> catalogIndexes = indexes[item];
|
|
|
|
for (TQValueList<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)
|
|
|
|
{
|
|
|
|
TQString cacheName = locateLocal("data", TQString("kdevdocumentation/index/cache_") + item->cacheVersion() + item->text(0));
|
|
|
|
TQFile cacheFile(cacheName);
|
|
|
|
if (!cacheFile.open(IO_ReadOnly))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
kdDebug() << "Using cached index for item: " << item->text(0) << endl;
|
|
|
|
|
|
|
|
TQTextStream str(&cacheFile);
|
|
|
|
str.setEncoding(TQTextStream::Unicode);
|
|
|
|
TQString cache = str.read();
|
|
|
|
TQStringList cacheList = TQStringList::split("\n", cache, true);
|
|
|
|
TQString ver = cacheList.first();
|
|
|
|
if (ver != CACHE_VERSION)
|
|
|
|
{
|
|
|
|
kdDebug() << "Wrong cache version: " << ver << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
TQStringList::const_iterator it = cacheList.begin();
|
|
|
|
it++;
|
|
|
|
TQString 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] = TQValueList<IndexItem*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::addCatalogConfiguration(TDEListView *configurationView,
|
|
|
|
const TQString &title, const TQString &url)
|
|
|
|
{
|
|
|
|
new ConfigurationItem(configurationView, this, title, url,
|
|
|
|
hasCapability(Index), hasCapability(FullTextSearch));
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::editCatalogConfiguration(ConfigurationItem *configurationItem,
|
|
|
|
const TQString &title, const TQString &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
|
|
|
|
TQValueList<IndexItemProto *> idx = indexes[item];
|
|
|
|
for (TQValueList<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);
|
|
|
|
}
|
|
|
|
|
|
|
|
TDEListViewItem* DocumentationPlugin::findCatalogPosition(const TQString &key, const TDEListView *contents) const
|
|
|
|
{
|
|
|
|
TDEListViewItem *curr_item = (TDEListViewItem*)(contents->firstChild());
|
|
|
|
if (!curr_item)
|
|
|
|
return NULL; // Empty listview
|
|
|
|
|
|
|
|
TDEListViewItem *prev_item = NULL;
|
|
|
|
while (curr_item && curr_item->text(0) <= key)
|
|
|
|
{
|
|
|
|
prev_item = curr_item;
|
|
|
|
curr_item = (TDEListViewItem*)(curr_item->nextSibling());
|
|
|
|
}
|
|
|
|
return prev_item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::init(TDEListView *contents)
|
|
|
|
{
|
|
|
|
config->setGroup("Locations");
|
|
|
|
TQMap<TQString, TQString> entryMap = config->entryMap("Locations");
|
|
|
|
|
|
|
|
for (TQMap<TQString, TQString>::const_iterator it = entryMap.begin();
|
|
|
|
it != entryMap.end(); ++it)
|
|
|
|
{
|
|
|
|
TQString cat_key = it.key();
|
|
|
|
if (catalogEnabled(cat_key))
|
|
|
|
{
|
|
|
|
// Keep the list in increasing sorted order. Given that the list is
|
|
|
|
// reasonably short, we can affort to scan through the list each time
|
|
|
|
// a new item is created
|
|
|
|
TDEListViewItem *afterItem = findCatalogPosition(cat_key, contents);
|
|
|
|
createCatalog(contents, afterItem, cat_key, config->readPathEntry(cat_key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::reinit(TDEListView *contents, IndexBox *index, TQStringList restrictions)
|
|
|
|
{
|
|
|
|
config->setGroup("Locations");
|
|
|
|
TQMap<TQString, TQString> entryMap = config->entryMap("Locations");
|
|
|
|
|
|
|
|
//remove deleted in configuration catalogs
|
|
|
|
for (TQStringList::const_iterator it = deletedConfigurationItems.constBegin();
|
|
|
|
it != deletedConfigurationItems.constEnd(); ++it)
|
|
|
|
{
|
|
|
|
if (namedCatalogs.contains(*it))
|
|
|
|
delete namedCatalogs[*it];
|
|
|
|
}
|
|
|
|
deletedConfigurationItems.clear();
|
|
|
|
|
|
|
|
//update configuration
|
|
|
|
for (TQMap<TQString, TQString>::const_iterator it = entryMap.begin();
|
|
|
|
it != entryMap.end(); ++it)
|
|
|
|
{
|
|
|
|
config->setGroup("Locations");
|
|
|
|
TQString cat_key = it.key();
|
|
|
|
if (restrictions.contains(cat_key) || (!catalogEnabled(cat_key)))
|
|
|
|
{
|
|
|
|
if (namedCatalogs.contains(cat_key))
|
|
|
|
delete namedCatalogs[cat_key];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdDebug() << "updating 1" << endl;
|
|
|
|
if (!namedCatalogs.contains(cat_key)) //create catalog if it does not exist
|
|
|
|
{
|
|
|
|
TDEListViewItem *afterItem = findCatalogPosition(cat_key, contents);
|
|
|
|
DocumentationCatalogItem *item = createCatalog(contents, afterItem, cat_key, config->readPathEntry(cat_key));
|
|
|
|
loadIndex(index, item);
|
|
|
|
index->setDirty(true);
|
|
|
|
// index->refill(indexes[item]);
|
|
|
|
}
|
|
|
|
else if (!indexEnabled(namedCatalogs[cat_key])) //clear index if it is disabled in configuration
|
|
|
|
{
|
|
|
|
kdDebug() << " updating: clearCatalogIndex" << endl;
|
|
|
|
clearCatalogIndex(namedCatalogs[cat_key]);
|
|
|
|
}
|
|
|
|
else if ( (indexEnabled(namedCatalogs[cat_key])) //index is requested in configuration but does not yet exist
|
|
|
|
&& (!indexes.contains(namedCatalogs[cat_key])) )
|
|
|
|
{
|
|
|
|
kdDebug() << " index requested " << endl;
|
|
|
|
loadIndex(index, namedCatalogs[cat_key]);
|
|
|
|
index->setDirty(true);
|
|
|
|
}
|
|
|
|
m_indexCreated = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::loadCatalogConfiguration(TDEListView *configurationView)
|
|
|
|
{
|
|
|
|
config->setGroup("Locations");
|
|
|
|
TQMap<TQString, TQString> entryMap = config->entryMap("Locations");
|
|
|
|
|
|
|
|
for (TQMap<TQString, TQString>::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(TDEListView *configurationView)
|
|
|
|
{
|
|
|
|
|
|
|
|
for (TQStringList::const_iterator it = deletedConfigurationItems.constBegin();
|
|
|
|
it != deletedConfigurationItems.constEnd(); ++it)
|
|
|
|
{
|
|
|
|
config->setGroup("Locations");
|
|
|
|
config->deleteEntry(*it);
|
|
|
|
config->setGroup("TOC Settings");
|
|
|
|
config->deleteEntry(*it);
|
|
|
|
config->setGroup("Index Settings");
|
|
|
|
config->deleteEntry(*it);
|
|
|
|
config->setGroup("Search Settings");
|
|
|
|
config->deleteEntry(*it);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQListViewItemIterator 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 )
|
|
|
|
{
|
|
|
|
TQString group = config->group();
|
|
|
|
config->setGroup("Index Settings");
|
|
|
|
config->writeEntry(item->text(0), e);
|
|
|
|
config->setGroup(group);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DocumentationPlugin::indexEnabled( DocumentationCatalogItem * item ) const
|
|
|
|
{
|
|
|
|
TQString group = config->group();
|
|
|
|
config->setGroup("Index Settings");
|
|
|
|
bool b = config->readBoolEntry(item->text(0), false);
|
|
|
|
config->setGroup(group);
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DocumentationPlugin::catalogEnabled(const TQString &name) const
|
|
|
|
{
|
|
|
|
TQString group = config->group();
|
|
|
|
config->setGroup("TOC Settings");
|
|
|
|
bool b = config->readBoolEntry(name, true);
|
|
|
|
config->setGroup(group);
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DocumentationPlugin::setCatalogEnabled(const TQString &name, bool e)
|
|
|
|
{
|
|
|
|
TQString group = config->group();
|
|
|
|
config->setGroup("TOC Settings");
|
|
|
|
config->writeEntry(name, e);
|
|
|
|
config->setGroup(group);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------
|
|
|
|
//class IndexBox
|
|
|
|
|
|
|
|
IndexBox::IndexBox(TQWidget *parent, const char *name)
|
|
|
|
:TDEListBox(parent, name), m_dirty(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void IndexBox::addIndexItem(IndexItemProto *item)
|
|
|
|
{
|
|
|
|
items[item->text()].append(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IndexBox::removeIndexItem(IndexItemProto *item)
|
|
|
|
{
|
|
|
|
TQString text = item->text();
|
|
|
|
items[text].remove(item);
|
|
|
|
if (items[text].count() == 0)
|
|
|
|
{
|
|
|
|
items.remove(text);
|
|
|
|
TQListBoxItem *item = findItem(text, TQt::CaseSensitive | TQt::ExactMatch);
|
|
|
|
if (item)
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IndexBox::fill()
|
|
|
|
{
|
|
|
|
for (TQMap<TQString, TQValueList<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)
|
|
|
|
:TQObject(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, TQT_SIGNAL(dirty(const TQString&)), this, TQT_SLOT(reinit()));
|
|
|
|
m_watch->startScan();
|
|
|
|
}
|
|
|
|
|
|
|
|
ProjectDocumentationPlugin::~ProjectDocumentationPlugin()
|
|
|
|
{
|
|
|
|
deinit();
|
|
|
|
}
|
|
|
|
|
|
|
|
TDEListViewItem* ProjectDocumentationPlugin::findCatalogPosition(const TQString &key, const TDEListView *contents) const
|
|
|
|
{
|
|
|
|
TDEListViewItem *curr_item = (TDEListViewItem*)(contents->firstChild());
|
|
|
|
if (!curr_item)
|
|
|
|
return NULL; // Empty listview
|
|
|
|
|
|
|
|
TDEListViewItem *prev_item = NULL;
|
|
|
|
while (curr_item && curr_item->text(0) <= key)
|
|
|
|
{
|
|
|
|
prev_item = curr_item;
|
|
|
|
curr_item = (TDEListViewItem*)(curr_item->nextSibling());
|
|
|
|
}
|
|
|
|
return prev_item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectDocumentationPlugin::init(TDEListView *contents, IndexBox *index, const TQString &url)
|
|
|
|
{
|
|
|
|
m_contents = contents;
|
|
|
|
m_index = index;
|
|
|
|
m_url = url;
|
|
|
|
|
|
|
|
if (m_catalog)
|
|
|
|
deinit();
|
|
|
|
TQString cat_key = (m_type == DocumentationPlugin::APIDocs ? i18n("Project API Documentation")
|
|
|
|
: i18n("Project User Manual"));
|
|
|
|
TDEListViewItem *afterItem = findCatalogPosition(cat_key, contents);
|
|
|
|
m_catalog = m_docPlugin->createCatalog(contents, afterItem, cat_key, 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);
|
|
|
|
if (m_catalog)
|
|
|
|
{
|
|
|
|
delete m_catalog;
|
|
|
|
m_catalog = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ProjectDocumentationPlugin::pluginName() const
|
|
|
|
{
|
|
|
|
return m_docPlugin->pluginName();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ProjectDocumentationPlugin::catalogURL() const
|
|
|
|
{
|
|
|
|
return m_url;
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kdevdocumentationplugin.moc"
|