|
|
|
/*
|
|
|
|
* This file is part of the TDE Help Center
|
|
|
|
*
|
|
|
|
* Copyright (C) 1999 Matthias Elter (me@kde.org)
|
|
|
|
*
|
|
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqheader.h>
|
|
|
|
#include <tqdom.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqlineedit.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tqtooltip.h>
|
|
|
|
|
|
|
|
#include <tdeaction.h>
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <ksimpleconfig.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <tdeglobal.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdelistview.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kprocio.h>
|
|
|
|
#include <kcharsets.h>
|
|
|
|
#include <kdialog.h>
|
|
|
|
#include <kdesktopfile.h>
|
|
|
|
#include <kprotocolinfo.h>
|
|
|
|
#include <kservicegroup.h>
|
|
|
|
|
|
|
|
#include "navigatoritem.h"
|
|
|
|
#include "navigatorappitem.h"
|
|
|
|
#include "searchwidget.h"
|
|
|
|
#include "searchengine.h"
|
|
|
|
#include "docmetainfo.h"
|
|
|
|
#include "docentrytraverser.h"
|
|
|
|
#include "glossary.h"
|
|
|
|
#include "toc.h"
|
|
|
|
#include "view.h"
|
|
|
|
#include "infotree.h"
|
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "plugintraverser.h"
|
|
|
|
#include "scrollkeepertreebuilder.h"
|
|
|
|
#include "kcmhelpcenter.h"
|
|
|
|
#include "formatter.h"
|
|
|
|
#include "history.h"
|
|
|
|
#include "prefs.h"
|
|
|
|
|
|
|
|
#include "navigator.h"
|
|
|
|
|
|
|
|
using namespace KHC;
|
|
|
|
|
|
|
|
Navigator::Navigator( View *view, TQWidget *parent, const char *name )
|
|
|
|
: TQWidget( parent, name ), mIndexDialog( 0 ),
|
|
|
|
mView( view ), mSelected( false )
|
|
|
|
{
|
|
|
|
TDEConfig *config = kapp->config();
|
|
|
|
config->setGroup("General");
|
|
|
|
mShowMissingDocs = config->readBoolEntry("ShowMissingDocs",false);
|
|
|
|
|
|
|
|
mSearchEngine = new SearchEngine( view );
|
|
|
|
connect( mSearchEngine, TQT_SIGNAL( searchFinished() ),
|
|
|
|
TQT_SLOT( slotSearchFinished() ) );
|
|
|
|
|
|
|
|
DocMetaInfo::self()->scanMetaInfo();
|
|
|
|
|
|
|
|
TQBoxLayout *topLayout = new TQVBoxLayout( this );
|
|
|
|
|
|
|
|
mSearchFrame = new TQFrame( this );
|
|
|
|
topLayout->addWidget( mSearchFrame );
|
|
|
|
|
|
|
|
TQBoxLayout *searchLayout = new TQHBoxLayout( mSearchFrame );
|
|
|
|
searchLayout->setSpacing( KDialog::spacingHint() );
|
|
|
|
searchLayout->setMargin( 6 );
|
|
|
|
|
|
|
|
TQPushButton *clearButton = new TQPushButton( mSearchFrame );
|
|
|
|
clearButton->setIconSet( TDEApplication::reverseLayout() ?
|
|
|
|
SmallIconSet( "clear_left" ) : SmallIconSet("locationbar_erase") );
|
|
|
|
searchLayout->addWidget( clearButton );
|
|
|
|
connect( clearButton, TQT_SIGNAL( clicked() ), TQT_SLOT( clearSearch() ) );
|
|
|
|
TQToolTip::add( clearButton, i18n("Clear search") );
|
|
|
|
|
|
|
|
mSearchEdit = new TQLineEdit( mSearchFrame );
|
|
|
|
searchLayout->addWidget( mSearchEdit );
|
|
|
|
connect( mSearchEdit, TQT_SIGNAL( returnPressed() ), TQT_SLOT( slotSearch() ) );
|
|
|
|
connect( mSearchEdit, TQT_SIGNAL( textChanged( const TQString & ) ),
|
|
|
|
TQT_SLOT( checkSearchButton() ) );
|
|
|
|
|
|
|
|
mSearchButton = new TQPushButton( i18n("&Search"), mSearchFrame );
|
|
|
|
searchLayout->addWidget( mSearchButton );
|
|
|
|
connect( mSearchButton, TQT_SIGNAL( clicked() ), TQT_SLOT( slotSearch() ) );
|
|
|
|
|
|
|
|
clearButton->setFixedHeight( mSearchButton->height() );
|
|
|
|
|
|
|
|
mTabWidget = new TQTabWidget( this );
|
|
|
|
topLayout->addWidget( mTabWidget );
|
|
|
|
|
|
|
|
setupContentsTab();
|
|
|
|
setupGlossaryTab();
|
|
|
|
setupSearchTab();
|
|
|
|
|
|
|
|
insertPlugins();
|
|
|
|
|
|
|
|
if ( !mSearchEngine->initSearchHandlers() ) {
|
|
|
|
hideSearch();
|
|
|
|
} else {
|
|
|
|
mSearchWidget->updateScopeList();
|
|
|
|
mSearchWidget->readConfig( TDEGlobal::config() );
|
|
|
|
}
|
|
|
|
|
|
|
|
connect( mTabWidget, TQT_SIGNAL( currentChanged( QWidget * ) ),
|
|
|
|
TQT_SLOT( slotTabChanged( QWidget * ) ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
Navigator::~Navigator()
|
|
|
|
{
|
|
|
|
delete mSearchEngine;
|
|
|
|
}
|
|
|
|
|
|
|
|
SearchEngine *Navigator::searchEngine() const
|
|
|
|
{
|
|
|
|
return mSearchEngine;
|
|
|
|
}
|
|
|
|
|
|
|
|
Formatter *Navigator::formatter() const
|
|
|
|
{
|
|
|
|
return mView->formatter();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Navigator::showMissingDocs() const
|
|
|
|
{
|
|
|
|
return mShowMissingDocs;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::setupContentsTab()
|
|
|
|
{
|
|
|
|
mContentsTree = new TDEListView( mTabWidget );
|
|
|
|
mContentsTree->setFrameStyle(TQFrame::Panel | TQFrame::Sunken);
|
|
|
|
mContentsTree->addColumn(TQString::null);
|
|
|
|
mContentsTree->setAllColumnsShowFocus(true);
|
|
|
|
mContentsTree->header()->hide();
|
|
|
|
mContentsTree->setRootIsDecorated(false);
|
|
|
|
mContentsTree->setSorting(-1, false);
|
|
|
|
|
|
|
|
connect(mContentsTree, TQT_SIGNAL(clicked(TQListViewItem*)),
|
|
|
|
TQT_SLOT(slotItemSelected(TQListViewItem*)));
|
|
|
|
connect(mContentsTree, TQT_SIGNAL(returnPressed(TQListViewItem*)),
|
|
|
|
TQT_SLOT(slotItemSelected(TQListViewItem*)));
|
|
|
|
mTabWidget->addTab(mContentsTree, i18n("&Contents"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::setupSearchTab()
|
|
|
|
{
|
|
|
|
mSearchWidget = new SearchWidget( mSearchEngine, mTabWidget );
|
|
|
|
connect( mSearchWidget, TQT_SIGNAL( searchResult( const TQString & ) ),
|
|
|
|
TQT_SLOT( slotShowSearchResult( const TQString & ) ) );
|
|
|
|
connect( mSearchWidget, TQT_SIGNAL( scopeCountChanged( int ) ),
|
|
|
|
TQT_SLOT( checkSearchButton() ) );
|
|
|
|
connect( mSearchWidget, TQT_SIGNAL( showIndexDialog() ),
|
|
|
|
TQT_SLOT( showIndexDialog() ) );
|
|
|
|
|
|
|
|
mTabWidget->addTab( mSearchWidget, i18n("Search Options"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::setupGlossaryTab()
|
|
|
|
{
|
|
|
|
mGlossaryTree = new Glossary( mTabWidget );
|
|
|
|
connect( mGlossaryTree, TQT_SIGNAL( entrySelected( const GlossaryEntry & ) ),
|
|
|
|
this, TQT_SIGNAL( glossSelected( const GlossaryEntry & ) ) );
|
|
|
|
mTabWidget->addTab( mGlossaryTree, i18n( "G&lossary" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::insertPlugins()
|
|
|
|
{
|
|
|
|
PluginTraverser t( this, mContentsTree );
|
|
|
|
DocMetaInfo::self()->traverseEntries( &t );
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
kdDebug( 1400 ) << "<docmetainfo>" << endl;
|
|
|
|
DocEntry::List entries = DocMetaInfo::self()->docEntries();
|
|
|
|
DocEntry::List::ConstIterator it;
|
|
|
|
for( it = entries.begin(); it != entries.end(); ++it ) {
|
|
|
|
(*it)->dump();
|
|
|
|
}
|
|
|
|
kdDebug( 1400 ) << "</docmetainfo>" << endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::insertParentAppDocs( const TQString &name, NavigatorItem *topItem )
|
|
|
|
{
|
|
|
|
kdDebug(1400) << "Requested plugin documents for ID " << name << endl;
|
|
|
|
|
|
|
|
KServiceGroup::Ptr grp = KServiceGroup::childGroup( name );
|
|
|
|
if ( !grp )
|
|
|
|
return;
|
|
|
|
|
|
|
|
KServiceGroup::List entries = grp->entries();
|
|
|
|
KServiceGroup::List::ConstIterator it = entries.begin();
|
|
|
|
KServiceGroup::List::ConstIterator end = entries.end();
|
|
|
|
for ( ; it != end; ++it ) {
|
|
|
|
TQString desktopFile = ( *it )->entryPath();
|
|
|
|
if ( TQDir::isRelativePath( desktopFile ) ) {
|
|
|
|
desktopFile = locate( "apps", desktopFile );
|
|
|
|
}
|
|
|
|
createItemFromDesktopFile( topItem, desktopFile );
|
|
|
|
}
|
|
|
|
topItem->sortChildItems( 0, true /* ascending */ );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::insertIOSlaveDocs( const TQString &name, NavigatorItem *topItem )
|
|
|
|
{
|
|
|
|
kdDebug(1400) << "Requested IOSlave documents for ID " << name << endl;
|
|
|
|
|
|
|
|
#if KDE_IS_VERSION( 3, 1, 90 )
|
|
|
|
TQStringList list = KProtocolInfo::protocols();
|
|
|
|
list.sort();
|
|
|
|
|
|
|
|
NavigatorItem *prevItem = 0;
|
|
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
|
|
{
|
|
|
|
TQString docPath = KProtocolInfo::docPath(*it);
|
|
|
|
if ( !docPath.isNull() )
|
|
|
|
{
|
|
|
|
// First parameter is ignored if second is an absolute path
|
|
|
|
KURL url(KURL("help:/"), docPath);
|
|
|
|
TQString icon = KProtocolInfo::icon(*it);
|
|
|
|
if ( icon.isEmpty() ) icon = "document2";
|
|
|
|
DocEntry *entry = new DocEntry( *it, url.url(), icon );
|
|
|
|
NavigatorItem *item = new NavigatorItem( entry, topItem, prevItem );
|
|
|
|
prevItem = item;
|
|
|
|
item->setAutoDeleteDocEntry( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
Q_UNUSED( topItem );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::insertAppletDocs( NavigatorItem *topItem )
|
|
|
|
{
|
|
|
|
TQDir appletDir( locate( "data", TQString::fromLatin1( "kicker/applets/" ) ) );
|
|
|
|
appletDir.setNameFilter( TQString::fromLatin1( "*.desktop" ) );
|
|
|
|
|
|
|
|
TQStringList files = appletDir.entryList( TQDir::Files | TQDir::Readable );
|
|
|
|
TQStringList::ConstIterator it = files.begin();
|
|
|
|
TQStringList::ConstIterator end = files.end();
|
|
|
|
for ( ; it != end; ++it ) {
|
|
|
|
createItemFromDesktopFile( topItem, appletDir.absPath() + "/" + *it );
|
|
|
|
}
|
|
|
|
topItem->sortChildItems( 0, true /* ascending */ );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::createItemFromDesktopFile( NavigatorItem *topItem,
|
|
|
|
const TQString &file )
|
|
|
|
{
|
|
|
|
KDesktopFile desktopFile( file );
|
|
|
|
TQString docPath = desktopFile.readDocPath();
|
|
|
|
if ( !docPath.isNull() ) {
|
|
|
|
// First parameter is ignored if second is an absolute path
|
|
|
|
KURL url(KURL("help:/"), docPath);
|
|
|
|
TQString icon = desktopFile.readIcon();
|
|
|
|
if ( icon.isEmpty() ) icon = "document2";
|
|
|
|
DocEntry *entry = new DocEntry( desktopFile.readName(), url.url(), icon );
|
|
|
|
NavigatorItem *item = new NavigatorItem( entry, topItem );
|
|
|
|
item->setAutoDeleteDocEntry( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::insertInfoDocs( NavigatorItem *topItem )
|
|
|
|
{
|
|
|
|
InfoTree *infoTree = new InfoTree( TQT_TQOBJECT(this) );
|
|
|
|
infoTree->build( topItem );
|
|
|
|
}
|
|
|
|
|
|
|
|
NavigatorItem *Navigator::insertScrollKeeperDocs( NavigatorItem *topItem,
|
|
|
|
NavigatorItem *after )
|
|
|
|
{
|
|
|
|
ScrollKeeperTreeBuilder *builder = new ScrollKeeperTreeBuilder( TQT_TQOBJECT(this) );
|
|
|
|
return builder->build( topItem, after );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::selectItem( const KURL &url )
|
|
|
|
{
|
|
|
|
kdDebug() << "Navigator::selectItem(): " << url.url() << endl;
|
|
|
|
|
|
|
|
if ( url.url() == "khelpcenter:home" ) {
|
|
|
|
clearSelection();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// help:/foo&anchor=bar gets redirected to help:/foo#bar
|
|
|
|
// Make sure that we match both the original URL as well as
|
|
|
|
// its counterpart.
|
|
|
|
KURL alternativeURL = url;
|
|
|
|
if (url.hasRef())
|
|
|
|
{
|
|
|
|
alternativeURL.setQuery("anchor="+url.ref());
|
|
|
|
alternativeURL.setRef(TQString::null);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the navigator already has the given URL selected, do nothing.
|
|
|
|
NavigatorItem *item;
|
|
|
|
item = static_cast<NavigatorItem *>( mContentsTree->selectedItem() );
|
|
|
|
if ( item && mSelected ) {
|
|
|
|
KURL currentURL ( item->entry()->url() );
|
|
|
|
if ( (currentURL == url) || (currentURL == alternativeURL) ) {
|
|
|
|
kdDebug() << "URL already shown." << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// First, populate the NavigatorAppItems if we don't want the home page
|
|
|
|
if ( url != homeURL() ) {
|
|
|
|
for ( TQListViewItem *item = mContentsTree->firstChild(); item;
|
|
|
|
item = item->nextSibling() ) {
|
|
|
|
NavigatorAppItem *appItem = dynamic_cast<NavigatorAppItem *>( item );
|
|
|
|
if ( appItem ) appItem->populate( true /* recursive */ );
|
|
|
|
for ( TQListViewItem *subitem = item->firstChild(); subitem;
|
|
|
|
subitem = subitem->nextSibling() ) {
|
|
|
|
appItem = dynamic_cast<NavigatorAppItem *>( subitem );
|
|
|
|
if ( appItem ) appItem->populate( true /* recursive */ );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQListViewItemIterator it( mContentsTree );
|
|
|
|
while ( it.current() ) {
|
|
|
|
NavigatorItem *item = static_cast<NavigatorItem *>( it.current() );
|
|
|
|
KURL itemUrl( item->entry()->url() );
|
|
|
|
if ( (itemUrl == url) || (itemUrl == alternativeURL) ) {
|
|
|
|
mContentsTree->setCurrentItem( item );
|
|
|
|
// If the current item was not selected and remained unchanged it
|
|
|
|
// needs to be explicitly selected
|
|
|
|
mContentsTree->setSelected(item, true);
|
|
|
|
item->setOpen( true );
|
|
|
|
mContentsTree->ensureItemVisible( item );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
if ( !it.current() ) {
|
|
|
|
clearSelection();
|
|
|
|
} else {
|
|
|
|
mSelected = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::clearSelection()
|
|
|
|
{
|
|
|
|
mContentsTree->clearSelection();
|
|
|
|
mSelected = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::slotItemSelected( TQListViewItem *currentItem )
|
|
|
|
{
|
|
|
|
if ( !currentItem ) return;
|
|
|
|
|
|
|
|
mSelected = true;
|
|
|
|
|
|
|
|
NavigatorItem *item = static_cast<NavigatorItem *>( currentItem );
|
|
|
|
|
|
|
|
kdDebug(1400) << "Navigator::slotItemSelected(): " << item->entry()->name()
|
|
|
|
<< endl;
|
|
|
|
|
|
|
|
if ( item->childCount() > 0 || item->isExpandable() )
|
|
|
|
item->setOpen( !item->isOpen() );
|
|
|
|
|
|
|
|
KURL url ( item->entry()->url() );
|
|
|
|
|
|
|
|
if ( url.protocol() == "khelpcenter" ) {
|
|
|
|
mView->closeURL();
|
|
|
|
History::self().updateCurrentEntry( mView );
|
|
|
|
History::self().createEntry();
|
|
|
|
showOverview( item, url );
|
|
|
|
} else {
|
|
|
|
if ( url.protocol() == "help" ) {
|
|
|
|
kdDebug( 1400 ) << "slotItemSelected(): Got help URL " << url.url()
|
|
|
|
<< endl;
|
|
|
|
if ( !item->toc() ) {
|
|
|
|
TOC *tocTree = item->createTOC();
|
|
|
|
kdDebug( 1400 ) << "slotItemSelected(): Trying to build TOC for "
|
|
|
|
<< item->entry()->name() << endl;
|
|
|
|
tocTree->setApplication( url.directory() );
|
|
|
|
TQString doc = View::langLookup( url.path() );
|
|
|
|
// Enforce the original .docbook version, in case langLookup returns a
|
|
|
|
// cached version
|
|
|
|
if ( !doc.isNull() ) {
|
|
|
|
int pos = doc.find( ".html" );
|
|
|
|
if ( pos >= 0 ) {
|
|
|
|
doc.replace( pos, 5, ".docbook" );
|
|
|
|
}
|
|
|
|
kdDebug( 1400 ) << "slotItemSelected(): doc = " << doc << endl;
|
|
|
|
|
|
|
|
tocTree->build( doc );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
emit itemSelected( url.url() );
|
|
|
|
}
|
|
|
|
|
|
|
|
mLastUrl = url;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::openInternalUrl( const KURL &url )
|
|
|
|
{
|
|
|
|
if ( url.url() == "khelpcenter:home" ) {
|
|
|
|
clearSelection();
|
|
|
|
showOverview( 0, url );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
selectItem( url );
|
|
|
|
if ( !mSelected ) return;
|
|
|
|
|
|
|
|
NavigatorItem *item =
|
|
|
|
static_cast<NavigatorItem *>( mContentsTree->currentItem() );
|
|
|
|
|
|
|
|
if ( item ) showOverview( item, url );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::showOverview( NavigatorItem *item, const KURL &url )
|
|
|
|
{
|
|
|
|
mView->beginInternal( url );
|
|
|
|
|
|
|
|
TQString fileName = locate( "data", "khelpcenter/index.html.in" );
|
|
|
|
if ( fileName.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQFile file( fileName );
|
|
|
|
|
|
|
|
if ( !file.open( IO_ReadOnly ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQTextStream stream( &file );
|
|
|
|
TQString res = stream.read();
|
|
|
|
|
|
|
|
TQString title,name,content;
|
|
|
|
uint childCount;
|
|
|
|
|
|
|
|
if ( item ) {
|
|
|
|
title = item->entry()->name();
|
|
|
|
name = item->entry()->name();
|
|
|
|
|
|
|
|
TQString info = item->entry()->info();
|
|
|
|
if ( !info.isEmpty() ) content = "<p>" + info + "</p>\n";
|
|
|
|
|
|
|
|
childCount = item->childCount();
|
|
|
|
} else {
|
|
|
|
title = i18n("Start Page");
|
|
|
|
name = i18n("The Trinity Help Center");
|
|
|
|
|
|
|
|
childCount = mContentsTree->childCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( childCount > 0 ) {
|
|
|
|
TQListViewItem *child;
|
|
|
|
if ( item ) child = item->firstChild();
|
|
|
|
else child = mContentsTree->firstChild();
|
|
|
|
|
|
|
|
mDirLevel = 0;
|
|
|
|
|
|
|
|
content += createChildrenList( child );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
content += "<p></p>";
|
|
|
|
|
|
|
|
res = res.arg(title).arg(name).arg(content);
|
|
|
|
|
|
|
|
mView->write( res );
|
|
|
|
|
|
|
|
mView->end();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Navigator::createChildrenList( TQListViewItem *child )
|
|
|
|
{
|
|
|
|
++mDirLevel;
|
|
|
|
|
|
|
|
TQString t;
|
|
|
|
|
|
|
|
t += "<ul>\n";
|
|
|
|
|
|
|
|
while ( child ) {
|
|
|
|
NavigatorItem *childItem = static_cast<NavigatorItem *>( child );
|
|
|
|
|
|
|
|
DocEntry *e = childItem->entry();
|
|
|
|
|
|
|
|
t += "<li><a href=\"" + e->url() + "\">";
|
|
|
|
if ( e->isDirectory() ) t += "<b>";
|
|
|
|
t += e->name();
|
|
|
|
if ( e->isDirectory() ) t += "</b>";
|
|
|
|
t += "</a>";
|
|
|
|
|
|
|
|
if ( !e->info().isEmpty() ) {
|
|
|
|
t += "<br>" + e->info();
|
|
|
|
}
|
|
|
|
|
|
|
|
t += "</li>\n";
|
|
|
|
|
|
|
|
if ( childItem->childCount() > 0 && mDirLevel < 2 ) {
|
|
|
|
t += createChildrenList( childItem->firstChild() );
|
|
|
|
}
|
|
|
|
|
|
|
|
child = child->nextSibling();
|
|
|
|
}
|
|
|
|
|
|
|
|
t += "</ul>\n";
|
|
|
|
|
|
|
|
--mDirLevel;
|
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::slotSearch()
|
|
|
|
{
|
|
|
|
kdDebug(1400) << "Navigator::slotSearch()" << endl;
|
|
|
|
|
|
|
|
if ( !checkSearchIndex() ) return;
|
|
|
|
|
|
|
|
if ( mSearchEngine->isRunning() ) return;
|
|
|
|
|
|
|
|
TQString words = mSearchEdit->text();
|
|
|
|
TQString method = mSearchWidget->method();
|
|
|
|
int pages = mSearchWidget->pages();
|
|
|
|
TQString scope = mSearchWidget->scope();
|
|
|
|
|
|
|
|
kdDebug(1400) << "Navigator::slotSearch() words: " << words << endl;
|
|
|
|
kdDebug(1400) << "Navigator::slotSearch() scope: " << scope << endl;
|
|
|
|
|
|
|
|
if ( words.isEmpty() || scope.isEmpty() ) return;
|
|
|
|
|
|
|
|
// disable search Button during searches
|
|
|
|
mSearchButton->setEnabled(false);
|
|
|
|
TQApplication::setOverrideCursor(tqwaitCursor);
|
|
|
|
|
|
|
|
if ( !mSearchEngine->search( words, method, pages, scope ) ) {
|
|
|
|
slotSearchFinished();
|
|
|
|
KMessageBox::sorry( this, i18n("Unable to run search program.") );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::slotShowSearchResult( const TQString &url )
|
|
|
|
{
|
|
|
|
TQString u = url;
|
|
|
|
u.replace( "%k", mSearchEdit->text() );
|
|
|
|
|
|
|
|
emit itemSelected( u );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::slotSearchFinished()
|
|
|
|
{
|
|
|
|
mSearchButton->setEnabled(true);
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
|
|
|
|
kdDebug( 1400 ) << "Search finished." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::checkSearchButton()
|
|
|
|
{
|
|
|
|
mSearchButton->setEnabled( !mSearchEdit->text().isEmpty() &&
|
|
|
|
mSearchWidget->scopeCount() > 0 );
|
|
|
|
mTabWidget->showPage( mSearchWidget );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::hideSearch()
|
|
|
|
{
|
|
|
|
mSearchFrame->hide();
|
|
|
|
mTabWidget->removePage( mSearchWidget );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Navigator::checkSearchIndex()
|
|
|
|
{
|
|
|
|
TDEConfig *cfg = TDEGlobal::config();
|
|
|
|
cfg->setGroup( "Search" );
|
|
|
|
if ( cfg->readBoolEntry( "IndexExists", false ) ) return true;
|
|
|
|
|
|
|
|
if ( mIndexDialog && mIndexDialog->isShown() ) return true;
|
|
|
|
|
|
|
|
TQString text = i18n( "A search index does not yet exist. Do you want "
|
|
|
|
"to create the index now?" );
|
|
|
|
|
|
|
|
int result = KMessageBox::questionYesNo( this, text, TQString::null,
|
|
|
|
i18n("Create"),
|
|
|
|
i18n("Do Not Create"),
|
|
|
|
"indexcreation" );
|
|
|
|
if ( result == KMessageBox::Yes ) {
|
|
|
|
showIndexDialog();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::slotTabChanged( TQWidget *wid )
|
|
|
|
{
|
|
|
|
if ( wid == mSearchWidget ) checkSearchIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::slotSelectGlossEntry( const TQString &id )
|
|
|
|
{
|
|
|
|
mGlossaryTree->slotSelectGlossEntry( id );
|
|
|
|
}
|
|
|
|
|
|
|
|
KURL Navigator::homeURL()
|
|
|
|
{
|
|
|
|
if ( !mHomeUrl.isEmpty() ) return mHomeUrl;
|
|
|
|
|
|
|
|
TDEConfig *cfg = TDEGlobal::config();
|
|
|
|
// We have to reparse the configuration here in order to get a
|
|
|
|
// language-specific StartUrl, e.g. "StartUrl[de]".
|
|
|
|
cfg->reparseConfiguration();
|
|
|
|
cfg->setGroup( "General" );
|
|
|
|
mHomeUrl = cfg->readPathEntry( "StartUrl", "khelpcenter:home" );
|
|
|
|
return mHomeUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::showIndexDialog()
|
|
|
|
{
|
|
|
|
if ( !mIndexDialog ) {
|
|
|
|
mIndexDialog = new KCMHelpCenter( mSearchEngine, this );
|
|
|
|
connect( mIndexDialog, TQT_SIGNAL( searchIndexUpdated() ), mSearchWidget,
|
|
|
|
TQT_SLOT( updateScopeList() ) );
|
|
|
|
}
|
|
|
|
mIndexDialog->show();
|
|
|
|
mIndexDialog->raise();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::readConfig()
|
|
|
|
{
|
|
|
|
if ( Prefs::currentTab() == Prefs::Search ) {
|
|
|
|
mTabWidget->showPage( mSearchWidget );
|
|
|
|
} else if ( Prefs::currentTab() == Prefs::Glossary ) {
|
|
|
|
mTabWidget->showPage( mGlossaryTree );
|
|
|
|
} else {
|
|
|
|
mTabWidget->showPage( mContentsTree );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::writeConfig()
|
|
|
|
{
|
|
|
|
if ( mTabWidget->currentPage() == mSearchWidget ) {
|
|
|
|
Prefs::setCurrentTab( Prefs::Search );
|
|
|
|
} else if ( mTabWidget->currentPage() == mGlossaryTree ) {
|
|
|
|
Prefs::setCurrentTab( Prefs::Glossary );
|
|
|
|
} else {
|
|
|
|
Prefs::setCurrentTab( Prefs::Content );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Navigator::clearSearch()
|
|
|
|
{
|
|
|
|
mSearchEdit->setText( TQString::null );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "navigator.moc"
|
|
|
|
|
|
|
|
// vim:ts=2:sw=2:et
|