diff options
Diffstat (limited to 'khelpcenter/view.cpp')
-rw-r--r-- | khelpcenter/view.cpp | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/khelpcenter/view.cpp b/khelpcenter/view.cpp new file mode 100644 index 000000000..36a12c9ca --- /dev/null +++ b/khelpcenter/view.cpp @@ -0,0 +1,387 @@ +#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 <qfileinfo.h> +#include <qclipboard.h> + +using namespace KHC; + +View::View( QWidget *parentWidget, const char *widgetName, + QObject *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, SIGNAL( setWindowCaption( const QString & ) ), + this, SLOT( setTitle( const QString & ) ) ); + connect( this, SIGNAL( popupMenu( const QString &, const QPoint& ) ), + this, SLOT( showMenu( const QString &, const QPoint& ) ) ); + + QString css = langLookup("common/kde-default.css"); + if (!css.isEmpty()) + { + QFile css_file(css); + if (css_file.open(IO_ReadOnly)) + { + QTextStream s(&css_file); + QString 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( QDataStream &stream ) +{ + stream << mState; + if ( mState == Docu ) + KHTMLPart::saveState( stream ); +} + +void View::restoreState( QDataStream &stream ) +{ + stream >> mState; + if ( mState == Docu ) + KHTMLPart::restoreState( stream ); + else if ( mState == About ) + showAboutPage(); +} + +void View::showAboutPage() +{ + QString file = locate( "data", "khelpcenter/intro.html.in" ); + if ( file.isEmpty() ) + return; + + QFile f( file ); + + if ( !f.open( IO_ReadOnly ) ) + return; + + mState = About; + + emit started( 0 ); + + QTextStream t( &f ); + + QString 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 K Desktop Environment" ) ) + .arg( i18n( "The KDE team welcomes you to user-friendly UNIX computing" ) ) + .arg( i18n( "KDE is a powerful graphical desktop environment for UNIX workstations. A\n" + "KDE desktop combines ease of use, contemporary functionality and outstanding\n" + "graphical design with the technological superiority of the UNIX operating\n" + "system." ) ) + .arg( i18n( "What is the K Desktop Environment?" ) ) + .arg( i18n( "Contacting the KDE Project" ) ) + .arg( i18n( "Supporting the KDE Project" ) ) + .arg( i18n( "Useful links" ) ) + .arg( i18n( "Getting the most out of KDE" ) ) + .arg( i18n( "General Documentation" ) ) + .arg( i18n( "A Quick Start Guide to the Desktop" ) ) + .arg( i18n( "KDE Users' guide" ) ) + .arg( i18n( "Frequently asked questions" ) ) + .arg( i18n( "Basic Applications" ) ) + .arg( i18n( "The Kicker Desktop Panel" ) ) + .arg( i18n( "The KDE 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(); +} + +QString View::langLookup( const QString &fname ) +{ + QStringList search; + + // assemble the local search paths + const QStringList localDoc = KGlobal::dirs()->resourceDirs("html"); + + // look up the different languages + for (int id=localDoc.count()-1; id >= 0; --id) + { + QStringList langs = KGlobal::locale()->languageList(); + langs.append( "en" ); + langs.remove( "C" ); + QStringList::ConstIterator lang; + for (lang = langs.begin(); lang != langs.end(); ++lang) + search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname)); + } + + // try to locate the file + QStringList::Iterator it; + for (it = search.begin(); it != search.end(); ++it) + { + QFileInfo 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" ) ) + { + QString file = (*it).left((*it).findRev('/')) + "/index.docbook"; + info.setFile(file); + if (info.exists() && info.isFile() && info.isReadable()) + { + return *it; + } + } + } + + return QString::null; +} + +void View::setTitle( const QString &title ) +{ + mTitle = title; +} + +void View::beginSearchResult() +{ + mState = Search; + + begin(); + mSearchResult = ""; +} + +void View::writeSearchResult( const QString &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 QString& url, const QPoint& 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, SLOT(slotCopyLink())); + mCopyURL = completeURL(url).url(); + } + + pop->exec(pos); + delete pop; +} + +void View::slotCopyLink() +{ + QApplication::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( QObject *o, QEvent *e ) +{ + if ( e->type() != QEvent::KeyPress || + htmlDocument().links().length() == 0 ) + return KHTMLPart::eventFilter( o, e ); + + QKeyEvent *ke = static_cast<QKeyEvent *>( e ); + if ( ke->state() & Qt::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 QScrollBar * const scrollBar = view()->verticalScrollBar(); + if ( scrollBar->value() == scrollBar->minValue() ) { + if (prevPage()) + return true; + } + } else if ( ke->key() == Key_Space ) { + const QScrollBar * 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; + + QString path = baseURL().path(); + path.truncate( path.findRev( '/' ) + 1 ); + path += href.url(); + + KURL url = baseURL(); + url.setRef( QString::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 |