delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / runtime / khelpcenter / view.cpp
blob06cdc242922c86c674402253a874d58a8712b2cb
1 #include "view.h"
3 #include "formatter.h"
4 #include "history.h"
6 #include <dom/html_document.h>
7 #include <dom/html_misc.h>
8 #include <kaction.h>
9 #include <kactioncollection.h>
10 #include <kapplication.h>
11 #include <kdebug.h>
12 #include <khtml_settings.h>
13 #include <khtmlview.h>
14 #include <klocale.h>
15 #include <kmenu.h>
16 #include <kstandarddirs.h>
17 #include <ktoolbarpopupaction.h>
19 #include <QFileInfo>
20 #include <QClipboard>
21 //Added by qt3to4:
22 #include <QTextStream>
23 #include <QKeyEvent>
24 #include <QEvent>
25 #include <kglobal.h>
27 using namespace KHC;
29 View::View( QWidget *parentWidget, QObject *parent, KHTMLPart::GUIProfile prof, KActionCollection *col )
30 : KHTMLPart( parentWidget, parent, prof ), mState( Docu ), mActionCollection(col)
32 setJScriptEnabled(false);
33 setJavaEnabled(false);
34 setPluginsEnabled(false);
36 mFormatter = new Formatter;
37 if ( !mFormatter->readTemplates() ) {
38 kDebug() << "Unable to read Formatter templates.";
41 m_zoomStepping = 10;
43 connect( this, SIGNAL( setWindowCaption( const QString & ) ),
44 this, SLOT( setTitle( const QString & ) ) );
45 connect( this, SIGNAL( popupMenu( const QString &, const QPoint& ) ),
46 this, SLOT( showMenu( const QString &, const QPoint& ) ) );
48 QString css = langLookup("common/kde-default.css");
49 if (!css.isEmpty())
51 QFile css_file(css);
52 if (css_file.open(QIODevice::ReadOnly))
54 QTextStream s(&css_file);
55 QString stylesheet = s.readAll();
56 preloadStyleSheet("help:/common/kde-default.css", stylesheet);
60 view()->installEventFilter( this );
63 View::~View()
65 delete mFormatter;
68 void View::copySelectedText()
70 kapp->clipboard()->setText( selectedText() );
73 bool View::openUrl( const KUrl &url )
75 mState = Docu;
76 return KHTMLPart::openUrl( url );
79 void View::saveState( QDataStream &stream )
81 stream << mState;
82 if ( mState == Docu )
83 KHTMLPart::saveState( stream );
86 void View::restoreState( QDataStream &stream )
88 stream >> mState;
89 if ( mState == Docu )
90 KHTMLPart::restoreState( stream );
93 QString View::langLookup( const QString &fname )
95 QStringList search;
97 // assemble the local search paths
98 const QStringList localDoc = KGlobal::dirs()->resourceDirs("html");
100 // look up the different languages
101 for (int id=localDoc.count()-1; id >= 0; --id)
103 QStringList langs = KGlobal::locale()->languageList();
104 langs.append( "en" );
105 langs.removeAll( "C" );
106 QStringList::ConstIterator lang;
107 for (lang = langs.constBegin(); lang != langs.constEnd(); ++lang)
108 search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname));
111 // try to locate the file
112 QStringList::Iterator it;
113 for (it = search.begin(); it != search.end(); ++it)
115 QFileInfo info(*it);
116 if (info.exists() && info.isFile() && info.isReadable())
117 return *it;
119 QString file = (*it).left((*it).lastIndexOf('/')) + "/index.docbook";
120 info.setFile(file);
121 if (info.exists() && info.isFile() && info.isReadable())
122 return *it;
125 return QString();
128 void View::setTitle( const QString &title )
130 mTitle = title;
133 void View::beginSearchResult()
135 mState = Search;
137 begin();
138 mSearchResult = "";
141 void View::writeSearchResult( const QString &str )
143 write( str );
144 mSearchResult += str;
147 void View::endSearchResult()
149 end();
150 if ( !mSearchResult.isEmpty() ) emit searchResultCacheAvailable();
153 void View::beginInternal( const KUrl &url )
155 mInternalUrl = url;
156 begin();
159 KUrl View::internalUrl() const
161 return mInternalUrl;
164 void View::lastSearch()
166 if ( mSearchResult.isEmpty() ) return;
168 mState = Search;
170 begin();
171 write( mSearchResult );
172 end();
175 void View::slotIncFontSizes()
177 setZoomFactor( zoomFactor() + m_zoomStepping );
180 void View::slotDecFontSizes()
182 setZoomFactor( zoomFactor() - m_zoomStepping );
185 void View::showMenu( const QString& url, const QPoint& pos)
187 KMenu pop(view());
189 if (url.isEmpty())
191 QAction *action;
192 action = mActionCollection->action("go_home");
193 if (action) pop.addAction( action );
195 pop.addSeparator();
197 action = mActionCollection->action("prevPage");
198 if (action) pop.addAction( action );
199 action = mActionCollection->action("nextPage");
200 if (action) pop.addAction( action);
202 pop.addSeparator();
204 pop.addAction( History::self().m_backAction );
205 pop.addAction( History::self().m_forwardAction );
207 else
209 QAction *action = pop.addAction(i18n("Copy Link Address"));
210 connect( action, SIGNAL( triggered() ), this, SLOT( slotCopyLink() ) );
212 mCopyURL = completeURL(url).url();
215 pop.exec(pos);
218 void View::slotCopyLink()
220 QApplication::clipboard()->setText(mCopyURL);
223 bool View::prevPage(bool checkOnly)
225 const DOM::HTMLCollection links = htmlDocument().links();
227 KUrl prevURL;
229 // The first link on a page (top-left corner) would be the Prev link.
230 if ( !baseURL().path().endsWith( "/index.html" ) )
231 prevURL = urlFromLinkNode( links.item( 0 ) );
232 else
233 return false;
235 if (!prevURL.isValid())
236 return false;
238 if (!checkOnly)
239 openUrl( prevURL );
240 return true;
243 bool View::nextPage(bool checkOnly)
245 const DOM::HTMLCollection links = htmlDocument().links();
247 KUrl nextURL;
249 // If we're on the first page, the "Next" link is the second to the last link
250 if ( baseURL().path().endsWith( "/index.html" ) )
251 nextURL = urlFromLinkNode( links.item( links.length() - 2 ) );
252 else
253 nextURL = urlFromLinkNode( links.item( links.length() - 4 ) );
255 if (!nextURL.isValid())
256 return false;
258 // If we get a mail link instead of a http URL, or the next link points
259 // to an index.html page (a index.html page is always the first page
260 // there can't be a Next link pointing to it!) there's probably nowhere
261 // to go. Next link at all.
262 if ( nextURL.protocol() == "mailto" ||
263 nextURL.path().endsWith( "/index.html" ) )
264 return false;
266 if (!checkOnly)
267 openUrl( nextURL );
268 return true;
271 bool View::eventFilter( QObject *o, QEvent *e )
273 if ( e->type() != QEvent::KeyPress ||
274 htmlDocument().links().length() == 0 )
275 return KHTMLPart::eventFilter( o, e );
277 QKeyEvent *ke = static_cast<QKeyEvent *>( e );
278 if ( ke->modifiers() & Qt::ShiftModifier && ke->key() == Qt::Key_Space ) {
279 // If we're on the first page, it does not make sense to go back.
280 if ( baseURL().path().endsWith( "/index.html" ) )
281 return KHTMLPart::eventFilter( o, e );
283 const QScrollBar * const scrollBar = view()->verticalScrollBar();
284 if ( scrollBar->value() == scrollBar->minimum() ) {
285 if (prevPage())
286 return true;
288 } else if ( ke->key() == Qt::Key_Space ) {
289 const QScrollBar * const scrollBar = view()->verticalScrollBar();
290 if ( scrollBar->value() == scrollBar->maximum() ) {
291 if (nextPage())
292 return true;
295 return KHTMLPart::eventFilter( o, e );
298 KUrl View::urlFromLinkNode( const DOM::Node &n ) const
300 if ( n.isNull() || n.nodeType() != DOM::Node::ELEMENT_NODE )
301 return KUrl();
303 DOM::Element elem = static_cast<DOM::Element>( n );
305 KUrl href ( elem.getAttribute( "href" ).string() );
306 if ( !href.protocol().isNull() )
307 return href;
309 QString path = baseURL().path();
310 path.truncate( path.lastIndexOf( '/' ) + 1 );
311 path += href.url();
313 KUrl url = baseURL();
314 url.setRef( QString() );
315 url.setEncodedPathAndQuery( path );
317 return url;
320 void View::slotReload( const KUrl &url )
322 const_cast<KHTMLSettings *>( settings() )->init( KGlobal::config().data() );
323 KParts::OpenUrlArguments args = arguments();
324 args.setReload( true );
325 setArguments( args );
326 if ( url.isEmpty() )
327 openUrl( baseURL() );
328 else
329 openUrl( url );
332 #include "view.moc"
333 // vim:ts=2:sw=2:et