You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebase/khelpcenter/view.cpp

388 lines
10 KiB

#include "view.h"
#include "formatter.h"
#include "history.h"
#include <dom/html_document.h>
#include <dom/html_misc.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <kapplication.h>
#include <kdebug.h>
#include <khtml_settings.h>
#include <khtmlview.h>
#include <klocale.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <tqfileinfo.h>
#include <tqclipboard.h>
using namespace KHC;
View::View( TQWidget *parentWidget, const char *widgetName,
TQObject *parent, const char *name, KHTMLPart::GUIProfile prof, KActionCollection *col )
: KHTMLPart( parentWidget, widgetName, parent, name, prof ), mState( Docu ), mActionCollection(col)
{
setJScriptEnabled(false);
setJavaEnabled(false);
setPluginsEnabled(false);
mFormatter = new Formatter;
if ( !mFormatter->readTemplates() ) {
kdDebug() << "Unable to read Formatter templates." << endl;
}
m_zoomStepping = 10;
connect( this, TQT_SIGNAL( setWindowCaption( const TQString & ) ),
this, TQT_SLOT( setTitle( const TQString & ) ) );
connect( this, TQT_SIGNAL( popupMenu( const TQString &, const TQPoint& ) ),
this, TQT_SLOT( showMenu( const TQString &, const TQPoint& ) ) );
TQString css = langLookup("common/kde-default.css");
if (!css.isEmpty())
{
TQFile css_file(css);
if (css_file.open(IO_ReadOnly))
{
TQTextStream s(&css_file);
TQString stylesheet = s.read();
preloadStyleSheet("help:/common/kde-default.css", stylesheet);
}
}
view()->installEventFilter( this );
}
View::~View()
{
delete mFormatter;
}
void View::copySelectedText()
{
kapp->clipboard()->setText( selectedText() );
}
bool View::openURL( const KURL &url )
{
if ( url.protocol().lower() == "about" )
{
showAboutPage();
return true;
}
mState = Docu;
return KHTMLPart::openURL( url );
}
void View::saveState( TQDataStream &stream )
{
stream << mState;
if ( mState == Docu )
KHTMLPart::saveState( stream );
}
void View::restoreState( TQDataStream &stream )
{
stream >> mState;
if ( mState == Docu )
KHTMLPart::restoreState( stream );
else if ( mState == About )
showAboutPage();
}
void View::showAboutPage()
{
TQString file = locate( "data", "khelpcenter/intro.html.in" );
if ( file.isEmpty() )
return;
TQFile f( file );
if ( !f.open( IO_ReadOnly ) )
return;
mState = About;
emit started( 0 );
TQTextStream t( &f );
TQString res = t.read();
res = res.arg( i18n("Conquer your Desktop!") )
.arg( langLookup( "khelpcenter/konq.css" ) )
.arg( langLookup( "khelpcenter/pointers.png" ) )
.arg( langLookup( "khelpcenter/khelpcenter.png" ) )
.arg( i18n("Help Center") )
.arg( langLookup( "khelpcenter/lines.png" ) )
.arg( i18n( "Welcome to the Trinity Desktop Environment" ) )
.arg( i18n( "The TDE team welcomes you to user-friendly UNIX computing" ) )
.arg( i18n( "TDE is a graphical desktop environment for UNIX workstations. The\n"
"Trinity Desktop Environment combines ease of use, contemporary functionality, and\n"
"professional graphical design along with the technical advantages of\n"
"the UNIX operating system." ) )
.arg( i18n( "What is the Trinity Desktop Environment?" ) )
.arg( i18n( "Contacting the TDE Project Members" ) )
.arg( i18n( "Supporting the TDE Project" ) )
.arg( i18n( "Useful links" ) )
.arg( i18n( "Getting the most out of TDE" ) )
.arg( i18n( "General Documentation" ) )
.arg( i18n( "A Quick Start Guide to the Desktop" ) )
.arg( i18n( "TDE Users' guide" ) )
.arg( i18n( "Frequently Asked Questions" ) )
.arg( i18n( "Basic Applications" ) )
.arg( i18n( "The Kicker Desktop Panel" ) )
.arg( i18n( "The TDE Control Center" ) )
.arg( i18n( "The Konqueror File manager and Web Browser" ) )
.arg( langLookup( "khelpcenter/kdelogo2.png" ) );
begin( KURL( "about:khelpcenter" ) );
write( res );
end();
emit completed();
}
TQString View::langLookup( const TQString &fname )
{
TQStringList search;
// assemble the local search paths
const TQStringList localDoc = KGlobal::dirs()->resourceDirs("html");
// look up the different languages
for (int id=localDoc.count()-1; id >= 0; --id)
{
TQStringList langs = KGlobal::locale()->languageList();
langs.append( "en" );
langs.remove( "C" );
TQStringList::ConstIterator lang;
for (lang = langs.begin(); lang != langs.end(); ++lang)
search.append(TQString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname));
}
// try to locate the file
TQStringList::Iterator it;
for (it = search.begin(); it != search.end(); ++it)
{
TQFileInfo info(*it);
if (info.exists() && info.isFile() && info.isReadable())
return *it;
// Fall back to the index.docbook for this language if we couldn't find its
// specific docbook file. If we are not looking up docbook (images,
// css etc) then look in other languages first.
if ( ( *it ).endsWith( "docbook" ) )
{
TQString file = (*it).left((*it).findRev('/')) + "/index.docbook";
info.setFile(file);
if (info.exists() && info.isFile() && info.isReadable())
{
return *it;
}
}
}
return TQString::null;
}
void View::setTitle( const TQString &title )
{
mTitle = title;
}
void View::beginSearchResult()
{
mState = Search;
begin();
mSearchResult = "";
}
void View::writeSearchResult( const TQString &str )
{
write( str );
mSearchResult += str;
}
void View::endSearchResult()
{
end();
if ( !mSearchResult.isEmpty() ) emit searchResultCacheAvailable();
}
void View::beginInternal( const KURL &url )
{
mInternalUrl = url;
begin();
}
KURL View::internalUrl() const
{
return mInternalUrl;
}
void View::lastSearch()
{
if ( mSearchResult.isEmpty() ) return;
mState = Search;
begin();
write( mSearchResult );
end();
}
void View::slotIncFontSizes()
{
setZoomFactor( zoomFactor() + m_zoomStepping );
}
void View::slotDecFontSizes()
{
setZoomFactor( zoomFactor() - m_zoomStepping );
}
void View::showMenu( const TQString& url, const TQPoint& pos)
{
KPopupMenu* pop = new KPopupMenu(view());
if (url.isEmpty())
{
KAction *action;
action = mActionCollection->action("go_home");
if (action) action->plug(pop);
pop->insertSeparator();
action = mActionCollection->action("prevPage");
if (action) action->plug(pop);
action = mActionCollection->action("nextPage");
if (action) action->plug(pop);
pop->insertSeparator();
History::self().m_backAction->plug(pop);
History::self().m_forwardAction->plug(pop);
}
else
{
pop->insertItem(i18n("Copy Link Address"), this, TQT_SLOT(slotCopyLink()));
mCopyURL = completeURL(url).url();
}
pop->exec(pos);
delete pop;
}
void View::slotCopyLink()
{
TQApplication::clipboard()->setText(mCopyURL);
}
bool View::prevPage(bool checkOnly)
{
const DOM::HTMLCollection links = htmlDocument().links();
// The first link on a page (top-left corner) would be the Prev link.
const DOM::Node prevLinkNode = links.item( 0 );
KURL prevURL = urlFromLinkNode( prevLinkNode );
if (!prevURL.isValid())
return false;
if (!checkOnly)
openURL( prevURL );
return true;
}
bool View::nextPage(bool checkOnly)
{
const DOM::HTMLCollection links = htmlDocument().links();
KURL nextURL;
// If we're on the first page, the "Next" link is the last link
if ( baseURL().path().endsWith( "/index.html" ) )
nextURL = urlFromLinkNode( links.item( links.length() - 1 ) );
else
nextURL = urlFromLinkNode( links.item( links.length() - 2 ) );
if (!nextURL.isValid())
return false;
// If we get a mail link instead of a http URL, or the next link points
// to an index.html page (a index.html page is always the first page
// there can't be a Next link pointing to it!) there's probably nowhere
// to go. Next link at all.
if ( nextURL.protocol() == "mailto" ||
nextURL.path().endsWith( "/index.html" ) )
return false;
if (!checkOnly)
openURL( nextURL );
return true;
}
bool View::eventFilter( TQObject *o, TQEvent *e )
{
if ( e->type() != TQEvent::KeyPress ||
htmlDocument().links().length() == 0 )
return KHTMLPart::eventFilter( o, e );
TQKeyEvent *ke = TQT_TQKEYEVENT( e );
if ( ke->state() & TQt::ShiftButton && ke->key() == Key_Space ) {
// If we're on the first page, it does not make sense to go back.
if ( baseURL().path().endsWith( "/index.html" ) )
return KHTMLPart::eventFilter( o, e );
const TQScrollBar * const scrollBar = view()->verticalScrollBar();
if ( scrollBar->value() == scrollBar->minValue() ) {
if (prevPage())
return true;
}
} else if ( ke->key() == Key_Space ) {
const TQScrollBar * const scrollBar = view()->verticalScrollBar();
if ( scrollBar->value() == scrollBar->maxValue() ) {
if (nextPage())
return true;
}
}
return KHTMLPart::eventFilter( o, e );
}
KURL View::urlFromLinkNode( const DOM::Node &n ) const
{
if ( n.isNull() || n.nodeType() != DOM::Node::ELEMENT_NODE )
return KURL();
DOM::Element elem = static_cast<DOM::Element>( n );
KURL href ( elem.getAttribute( "href" ).string() );
if ( !href.protocol().isNull() )
return href;
TQString path = baseURL().path();
path.truncate( path.findRev( '/' ) + 1 );
path += href.url();
KURL url = baseURL();
url.setRef( TQString::null );
url.setEncodedPathAndQuery( path );
return url;
}
void View::slotReload( const KURL &url )
{
const_cast<KHTMLSettings *>( settings() )->init( kapp->config() );
KParts::URLArgs args = browserExtension()->urlArgs();
args.reload = true;
browserExtension()->setURLArgs( args );
if ( url.isEmpty() )
openURL( baseURL() );
else
openURL( url );
}
#include "view.moc"
// vim:ts=2:sw=2:et