khtml Library API Documentation

khtml_part.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /* This file is part of the KDE project
00003  *
00004  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00005  *                     1999 Lars Knoll <knoll@kde.org>
00006  *                     1999 Antti Koivisto <koivisto@kde.org>
00007  *                     2000 Simon Hausmann <hausmann@kde.org>
00008  *                     2000 Stefan Schimanski <1Stein@gmx.de>
00009  *                     2001 George Staikos <staikos@kde.org>
00010  *                     2001-2003 Dirk Mueller <mueller@kde.org>
00011  *                     2002 Apple Computer, Inc.
00012  *
00013  * This library is free software; you can redistribute it and/or
00014  * modify it under the terms of the GNU Library General Public
00015  * License as published by the Free Software Foundation; either
00016  * version 2 of the License, or (at your option) any later version.
00017  *
00018  * This library is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  * Library General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU Library General Public License
00024  * along with this library; see the file COPYING.LIB.  If not, write to
00025  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00026  * Boston, MA 02111-1307, USA.
00027  */
00028 
00029 //#define SPEED_DEBUG
00030 #include "khtml_part.h"
00031 
00032 #include "khtml_pagecache.h"
00033 
00034 #include "dom/dom_string.h"
00035 #include "dom/dom_element.h"
00036 #include "html/html_documentimpl.h"
00037 #include "html/html_baseimpl.h"
00038 #include "html/html_miscimpl.h"
00039 #include "html/html_imageimpl.h"
00040 #include "rendering/render_text.h"
00041 #include "rendering/render_frames.h"
00042 #include "misc/htmlhashes.h"
00043 #include "misc/loader.h"
00044 #include "xml/dom2_eventsimpl.h"
00045 #include "xml/xml_tokenizer.h"
00046 #include "css/cssstyleselector.h"
00047 #include "css/csshelper.h"
00048 using namespace DOM;
00049 
00050 #include "khtmlview.h"
00051 #include <kparts/partmanager.h>
00052 #include "ecma/kjs_proxy.h"
00053 #include "khtml_settings.h"
00054 
00055 #include "htmlpageinfo.h"
00056 
00057 #include <sys/types.h>
00058 #include <assert.h>
00059 #include <unistd.h>
00060 
00061 #include <kstandarddirs.h>
00062 #include <kstringhandler.h>
00063 #include <kio/job.h>
00064 #include <kio/global.h>
00065 #include <kdebug.h>
00066 #include <kiconloader.h>
00067 #include <klocale.h>
00068 #include <kcharsets.h>
00069 #include <kmessagebox.h>
00070 #include <kstdaction.h>
00071 #include <kfiledialog.h>
00072 #include <ktrader.h>
00073 #include <kdatastream.h>
00074 #include <ktempfile.h>
00075 #include <kglobalsettings.h>
00076 #include <kurldrag.h>
00077 #include <kapplication.h>
00078 #include <kparts/browserinterface.h>
00079 #if !defined(QT_NO_DRAGANDDROP)
00080 #include <kmultipledrag.h>
00081 #endif
00082 #include "../kutils/kfinddialog.h"
00083 #include "../kutils/kfind.h"
00084 
00085 #include <ksslcertchain.h>
00086 #include <ksslinfodlg.h>
00087 
00088 #include <kfileitem.h>
00089 #include <kurifilter.h>
00090 
00091 #include <qclipboard.h>
00092 #include <qfile.h>
00093 #include <qmetaobject.h>
00094 #include <private/qucomextra_p.h>
00095 
00096 #include "khtmlpart_p.h"
00097 
00098 namespace khtml {
00099     class PartStyleSheetLoader : public CachedObjectClient
00100     {
00101     public:
00102         PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
00103         {
00104             m_part = part;
00105             m_cachedSheet = Cache::requestStyleSheet(dl, url );
00106             if (m_cachedSheet)
00107         m_cachedSheet->ref( this );
00108         }
00109         virtual ~PartStyleSheetLoader()
00110         {
00111             if ( m_cachedSheet ) m_cachedSheet->deref(this);
00112         }
00113         virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet)
00114         {
00115           if ( m_part )
00116             m_part->setUserStyleSheet( sheet.string() );
00117 
00118             delete this;
00119         }
00120         QGuardedPtr<KHTMLPart> m_part;
00121         khtml::CachedCSSStyleSheet *m_cachedSheet;
00122     };
00123 };
00124 
00125 
00126 FrameList::Iterator FrameList::find( const QString &name )
00127 {
00128     Iterator it = begin();
00129     Iterator e = end();
00130 
00131     for (; it!=e; ++it )
00132         if ( (*it).m_name==name )
00133             break;
00134 
00135     return it;
00136 }
00137 
00138 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name,
00139                       GUIProfile prof )
00140 : KParts::ReadOnlyPart( parent, name )
00141 {
00142     d = 0;
00143     KHTMLFactory::registerPart( this );
00144     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00145     init( new KHTMLView( this, parentWidget, widgetname ), prof );
00146 }
00147 
00148 KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
00149 : KParts::ReadOnlyPart( parent, name )
00150 {
00151     d = 0;
00152     KHTMLFactory::registerPart( this );
00153     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00154     assert( view );
00155     init( view, prof );
00156 }
00157 
00158 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
00159 {
00160   if ( prof == DefaultGUI )
00161     setXMLFile( "khtml.rc" );
00162   else if ( prof == BrowserViewGUI )
00163     setXMLFile( "khtml_browser.rc" );
00164 
00165   d = new KHTMLPartPrivate(parent());
00166 
00167   d->m_view = view;
00168   setWidget( d->m_view );
00169 
00170   d->m_guiProfile = prof;
00171   d->m_extension = new KHTMLPartBrowserExtension( this );
00172   d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
00173 
00174   d->m_bSecurityInQuestion = false;
00175   d->m_paLoadImages = 0;
00176   d->m_bMousePressed = false;
00177   d->m_bRightMousePressed = false;
00178   d->m_paViewDocument = new KAction( i18n( "View Document Source" ), 0, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
00179   d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
00180   d->m_paViewInfo = new KAction( i18n( "View Document Information" ), 0, this, SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
00181   d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
00182   d->m_paSaveDocument = new KAction( i18n( "&Save As..." ), CTRL+Key_S, this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
00183   if ( parentPart() )
00184       d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
00185   d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
00186   d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
00187   d->m_paDebugRenderTree = new KAction( "Print Rendering Tree to STDOUT", 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
00188   d->m_paDebugDOMTree = new KAction( "Print DOM Tree to STDOUT", 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
00189 
00190   QString foo1 = i18n("Show Images");
00191   QString foo2 = i18n("Show Animated Images");
00192   QString foo3 = i18n("Stop Animated Images");
00193 
00194   d->m_paSetEncoding = new KSelectAction( i18n( "Set &Encoding" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "setEncoding" );
00195   QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
00196   encodings.prepend( i18n( "Auto" ) );
00197   d->m_paSetEncoding->setItems( encodings );
00198   d->m_paSetEncoding->setCurrentItem(0);
00199 
00200   d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
00201 
00202   d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n( "Increase Font Sizes" ), "viewmag+", this, SLOT( slotIncZoom() ), actionCollection(), "incFontSizes" );
00203   d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n( "Decrease Font Sizes" ), "viewmag-", this, SLOT( slotDecZoom() ), actionCollection(), "decFontSizes" );
00204 
00205   d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
00206   d->m_paFindNext = KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection(), "findNext" );
00207   if ( parentPart() )
00208   {
00209       d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
00210       d->m_paFindNext->setShortcut( KShortcut() ); // avoid clashes
00211   }
00212 
00213   d->m_paPrintFrame = new KAction( i18n( "Print Frame" ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
00214 
00215   d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
00216   if ( parentPart() )
00217       d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
00218 
00219   // set the default java(script) flags according to the current host.
00220   d->m_bBackRightClick = KHTMLFactory::defaultHTMLSettings()->isBackRightClickEnabled();
00221   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled();
00222   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
00223   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled();
00224   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled();
00225 
00226   connect( view, SIGNAL( zoomView( int ) ), SLOT( slotZoomView( int ) ) );
00227 
00228   connect( this, SIGNAL( completed() ),
00229            this, SLOT( updateActions() ) );
00230   connect( this, SIGNAL( completed( bool ) ),
00231            this, SLOT( updateActions() ) );
00232   connect( this, SIGNAL( started( KIO::Job * ) ),
00233            this, SLOT( updateActions() ) );
00234 
00235   d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
00236 
00237   connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00238            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00239   connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00240            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00241   connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00242            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00243 
00244   connect ( &d->m_progressUpdateTimer, SIGNAL( timeout() ), this, SLOT( slotProgressUpdate() ) );
00245 
00246   findTextBegin(); //reset find variables
00247 
00248   connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
00249            this, SLOT( slotRedirect() ) );
00250 
00251   d->m_dcopobject = new KHTMLPartIface(this);
00252 
00253   // "khtml" catalogue does not exist, our translations are in kdelibs.
00254   // removing this catalogue from KGlobal::locale() prevents problems
00255   // with changing the language in applications at runtime -Thomas Reitelbach
00256   KGlobal::locale()->removeCatalogue("khtml");
00257 }
00258 
00259 KHTMLPart::~KHTMLPart()
00260 {
00261   //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
00262 
00263   delete d->m_find;
00264   d->m_find = 0;
00265 
00266   if ( d->m_manager )
00267   {
00268     d->m_manager->setActivePart( 0 );
00269     // We specify "this" as parent qobject for d->manager, so no need to delete it.
00270   }
00271 
00272   stopAutoScroll();
00273   d->m_redirectionTimer.stop();
00274 
00275   if (!d->m_bComplete)
00276     closeURL();
00277 
00278   disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00279            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00280   disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00281            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00282   disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00283            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00284 
00285   clear();
00286 
00287   if ( d->m_view )
00288   {
00289     d->m_view->hide();
00290     d->m_view->viewport()->hide();
00291     d->m_view->m_part = 0;
00292   }
00293 
00294   delete d; d = 0;
00295   KHTMLFactory::deregisterPart( this );
00296 }
00297 
00298 bool KHTMLPart::restoreURL( const KURL &url )
00299 {
00300   kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
00301 
00302   d->m_redirectionTimer.stop();
00303 
00304   /*
00305    * That's not a good idea as it will call closeURL() on all
00306    * child frames, preventing them from further loading. This
00307    * method gets called from restoreState() in case of a full frameset
00308    * restoral, and restoreState() calls closeURL() before restoring
00309    * anyway.
00310   kdDebug( 6050 ) << "closing old URL" << endl;
00311   closeURL();
00312   */
00313 
00314   d->m_bComplete = false;
00315   d->m_bLoadEventEmitted = false;
00316   d->m_workingURL = url;
00317 
00318   // set the java(script) flags according to the current host.
00319   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00320   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
00321   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00322   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00323 
00324   m_url = url;
00325 
00326   KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));
00327 
00328   emit started( 0L );
00329 
00330   return true;
00331 }
00332 
00333 
00334 bool KHTMLPart::openURL( const KURL &url )
00335 {
00336   kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
00337 
00338   d->m_redirectionTimer.stop();
00339 
00340   // check to see if this is an "error://" URL. This is caused when an error
00341   // occurs before this part was loaded (e.g. KonqRun), and is passed to
00342   // khtmlpart so that it can display the error.
00343   if ( url.protocol() == "error" && url.hasSubURL() ) {
00344     closeURL();
00345 
00346     if(  d->m_bJScriptEnabled )
00347       d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
00348 
00354     KURL::List urls = KURL::split( url );
00355     //kdDebug(6050) << "Handling error URL. URL count:" << urls.count() << endl;
00356 
00357     if ( urls.count() > 1 ) {
00358       KURL mainURL = urls.first();
00359       int error = mainURL.queryItem( "error" ).toInt();
00360       // error=0 isn't a valid error code, so 0 means it's missing from the URL
00361       if ( error == 0 ) error = KIO::ERR_UNKNOWN;
00362       QString errorText = mainURL.queryItem( "errText" );
00363       urls.pop_front();
00364       d->m_workingURL = KURL::join( urls );
00365       //kdDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
00366       emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
00367       htmlError( error, errorText, d->m_workingURL );
00368       return true;
00369     }
00370   }
00371 
00372   KParts::URLArgs args( d->m_extension->urlArgs() );
00373   // in case we have a) no frameset (don't test m_frames.count(), iframes get in there)
00374   // b) the url is identical with the currently
00375   // displayed one (except for the htmlref!) , c) the url request is not a POST
00376   // operation and d) the caller did not request to reload the page we try to
00377   // be smart and instead of reloading the whole document we just jump to the
00378   // request html anchor
00379   bool isFrameSet = false;
00380   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00381       HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
00382       isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
00383   }
00384   if ( !isFrameSet &&
00385        urlcmp( url.url(), m_url.url(), true, true ) &&
00386        url.hasRef() && !args.doPost() && !args.reload )
00387   {
00388     kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
00389     m_url = url;
00390     emit started( 0L );
00391 
00392     if ( !gotoAnchor( url.encodedHtmlRef()) )
00393        gotoAnchor( url.htmlRef() );
00394 
00395     d->m_bComplete = true;
00396     if (d->m_doc)
00397        d->m_doc->setParsing(false);
00398 
00399     kdDebug( 6050 ) << "completed..." << endl;
00400     emit completed();
00401     return true;
00402   }
00403 
00404   if (!d->m_restored)
00405   {
00406     kdDebug( 6050 ) << "closing old URL" << endl;
00407     closeURL();
00408   }
00409 
00410   // initializing m_url to the new url breaks relative links when opening such a link after this call and _before_ begin() is called (when the first
00411   // data arrives) (Simon)
00412   m_url = url;
00413   if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
00414      m_url.path().isEmpty()) {
00415     m_url.setPath("/");
00416     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00417   }
00418   // copy to m_workingURL after fixing m_url above
00419   d->m_workingURL = m_url;
00420 
00421   args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
00422   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
00423   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
00424   args.metaData().insert("PropagateHttpHeader", "true");
00425   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
00426   args.metaData().insert("ssl_activate_warnings", "TRUE" );
00427   if (d->m_restored)
00428      d->m_cachePolicy = KIO::CC_Cache;
00429   else if (args.reload)
00430      d->m_cachePolicy = KIO::CC_Refresh;
00431   else
00432      d->m_cachePolicy = KIO::CC_Verify;
00433 
00434   if ( args.doPost() && (m_url.protocol().startsWith("http")) )
00435   {
00436       d->m_job = KIO::http_post( m_url, args.postData, false );
00437       d->m_job->addMetaData("content-type", args.contentType() );
00438   }
00439   else
00440   {
00441       d->m_job = KIO::get( m_url, false, false );
00442       d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
00443   }
00444 
00445   if (widget())
00446      d->m_job->setWindow(widget()->topLevelWidget());
00447   d->m_job->addMetaData(args.metaData());
00448 
00449   connect( d->m_job, SIGNAL( result( KIO::Job * ) ),
00450            SLOT( slotFinished( KIO::Job * ) ) );
00451   connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray &)),
00452            SLOT( slotData( KIO::Job*, const QByteArray &)));
00453   connect ( d->m_job, SIGNAL( infoMessage( KIO::Job*,  const QString& ) ),
00454             SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) );
00455   connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL&) ),
00456            SLOT( slotRedirection(KIO::Job*,const KURL&) ) );
00457 
00458   d->m_bComplete = false;
00459   d->m_bLoadEventEmitted = false;
00460 
00461   // delete old status bar msg's from kjs (if it _was_ activated on last URL)
00462   if( d->m_bJScriptEnabled )
00463     d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
00464 
00465   // set the javascript flags according to the current url
00466   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00467   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
00468   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00469   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00470 
00471 
00472   kdDebug( 6050 ) << "KHTMLPart::openURL now (before started) m_url = " << m_url.url() << endl;
00473 
00474   connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
00475            this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
00476 
00477   connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
00478            this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
00479 
00480   connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
00481            this, SLOT( slotJobDone( KIO::Job* ) ) );
00482 
00483   d->m_jobspeed = 0;
00484   emit started( 0L );
00485 
00486   return true;
00487 }
00488 
00489 bool KHTMLPart::closeURL()
00490 {
00491   if ( d->m_job )
00492   {
00493     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
00494     d->m_job->kill();
00495     d->m_job = 0;
00496   }
00497 
00498   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00499     HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
00500 
00501     if ( hdoc->body() && d->m_bLoadEventEmitted ) {
00502       hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
00503       if ( d->m_doc )
00504         d->m_doc->updateRendering();
00505       d->m_bLoadEventEmitted = false;
00506     }
00507   }
00508 
00509   d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
00510   d->m_bLoadEventEmitted = true; // don't want that one either
00511   d->m_cachePolicy = KIO::CC_Verify; // reset cache policy
00512 
00513   KHTMLPageCache::self()->cancelFetch(this);
00514   if ( d->m_doc && d->m_doc->parsing() )
00515   {
00516     kdDebug( 6050 ) << " was still parsing... calling end " << endl;
00517     slotFinishedParsing();
00518     d->m_doc->setParsing(false);
00519   }
00520 
00521   if ( !d->m_workingURL.isEmpty() )
00522   {
00523     // Aborted before starting to render
00524     kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
00525     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00526   }
00527 
00528   d->m_workingURL = KURL();
00529 
00530   if ( d->m_doc && d->m_doc->docLoader() )
00531     khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
00532 
00533   // tell all subframes to stop as well
00534   ConstFrameIt it = d->m_frames.begin();
00535   ConstFrameIt end = d->m_frames.end();
00536   for (; it != end; ++it )
00537   {
00538     if ( (*it).m_run )
00539       (*it).m_run->abort();
00540     if ( !( *it ).m_part.isNull() )
00541       ( *it ).m_part->closeURL();
00542   }
00543 
00544   // Stop any started redirections as well!! (DA)
00545   if ( d && d->m_redirectionTimer.isActive() )
00546     d->m_redirectionTimer.stop();
00547 
00548   // null node activated.
00549   emit nodeActivated(Node());
00550 
00551   // make sure before clear() runs, we pop out of a dialog's message loop
00552   if ( d->m_view )
00553     d->m_view->closeChildDialogs();
00554 
00555   return true;
00556 }
00557 
00558 DOM::HTMLDocument KHTMLPart::htmlDocument() const
00559 {
00560   if (d->m_doc && d->m_doc->isHTMLDocument())
00561     return static_cast<HTMLDocumentImpl*>(d->m_doc);
00562   else
00563     return static_cast<HTMLDocumentImpl*>(0);
00564 }
00565 
00566 DOM::Document KHTMLPart::document() const
00567 {
00568     return d->m_doc;
00569 }
00570 
00571 KParts::BrowserExtension *KHTMLPart::browserExtension() const
00572 {
00573   return d->m_extension;
00574 }
00575 
00576 KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
00577 {
00578   return d->m_hostExtension;
00579 }
00580 
00581 KHTMLView *KHTMLPart::view() const
00582 {
00583   return d->m_view;
00584 }
00585 
00586 void KHTMLPart::setJScriptEnabled( bool enable )
00587 {
00588   if ( !enable && jScriptEnabled() && d->m_jscript ) {
00589     d->m_jscript->clear();
00590   }
00591   d->m_bJScriptForce = enable;
00592   d->m_bJScriptOverride = true;
00593 }
00594 
00595 bool KHTMLPart::jScriptEnabled() const
00596 {
00597   if ( d->m_bJScriptOverride )
00598       return d->m_bJScriptForce;
00599   return d->m_bJScriptEnabled;
00600 }
00601 
00602 void KHTMLPart::setMetaRefreshEnabled( bool enable )
00603 {
00604   d->m_metaRefreshEnabled = enable;
00605 }
00606 
00607 bool KHTMLPart::metaRefreshEnabled() const
00608 {
00609   return d->m_metaRefreshEnabled;
00610 }
00611 
00612 // Define this to disable dlopening kjs_html, when directly linking to it.
00613 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
00614 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
00615 //        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
00616 //#define DIRECT_LINKAGE_TO_ECMA
00617 
00618 #ifdef DIRECT_LINKAGE_TO_ECMA
00619 extern "C" { KJSProxy *kjs_html_init(KHTMLPart *khtmlpart); }
00620 #endif
00621 
00622 KJSProxy *KHTMLPart::jScript()
00623 {
00624   if (!jScriptEnabled()) return 0;
00625 
00626   if ( !d->m_jscript )
00627   {
00628 #ifndef DIRECT_LINKAGE_TO_ECMA
00629     KLibrary *lib = KLibLoader::self()->library("kjs_html");
00630     if ( !lib ) {
00631       setJScriptEnabled( false );
00632       return 0;
00633     }
00634     // look for plain C init function
00635     void *sym = lib->symbol("kjs_html_init");
00636     if ( !sym ) {
00637       lib->unload();
00638       setJScriptEnabled( false );
00639       return 0;
00640     }
00641     typedef KJSProxy* (*initFunction)(KHTMLPart *);
00642     initFunction initSym = (initFunction) sym;
00643     d->m_jscript = (*initSym)(this);
00644     d->m_kjs_lib = lib;
00645 #else
00646     d->m_jscript = kjs_html_init(this);
00647     // d->m_kjs_lib remains 0L.
00648 #endif
00649     if (d->m_bJScriptDebugEnabled)
00650         d->m_jscript->setDebugEnabled(true);
00651   }
00652 
00653   return d->m_jscript;
00654 }
00655 
00656 QVariant KHTMLPart::executeScript( const QString &script )
00657 {
00658     return executeScript( DOM::Node(), script );
00659 }
00660 
00661 //Enable this to see all JS scripts being executed
00662 //#define KJS_VERBOSE
00663 
00664 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
00665 {
00666 #ifdef KJS_VERBOSE
00667   kdDebug(6070) << "KHTMLPart::executeScript n=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " << script << endl;
00668 #endif
00669   KJSProxy *proxy = jScript();
00670 
00671   if (!proxy || proxy->paused())
00672     return QVariant();
00673   d->m_runningScripts++;
00674   QVariant ret = proxy->evaluate( QString::null, 0, script, n );
00675   d->m_runningScripts--;
00676   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
00677       submitFormAgain();
00678 
00679 #ifdef KJS_VERBOSE
00680   kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
00681 #endif
00682   return ret;
00683 }
00684 
00685 bool KHTMLPart::scheduleScript(const DOM::Node &n, const QString& script)
00686 {
00687     //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
00688 
00689     d->scheduledScript = script;
00690     d->scheduledScriptNode = n;
00691 
00692     return true;
00693 }
00694 
00695 QVariant KHTMLPart::executeScheduledScript()
00696 {
00697   if( d->scheduledScript.isEmpty() )
00698     return QVariant();
00699 
00700   //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
00701 
00702   QVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
00703   d->scheduledScript = QString();
00704   d->scheduledScriptNode = DOM::Node();
00705 
00706   return ret;
00707 }
00708 
00709 void KHTMLPart::setJavaEnabled( bool enable )
00710 {
00711   d->m_bJavaForce = enable;
00712   d->m_bJavaOverride = true;
00713 }
00714 
00715 bool KHTMLPart::javaEnabled() const
00716 {
00717 #ifndef Q_WS_QWS
00718   if( d->m_bJavaOverride )
00719       return d->m_bJavaForce;
00720   return d->m_bJavaEnabled;
00721 #else
00722   return false;
00723 #endif
00724 }
00725 
00726 KJavaAppletContext *KHTMLPart::javaContext()
00727 {
00728 #ifndef Q_WS_QWS
00729   return d->m_javaContext;
00730 #else
00731   return 0;
00732 #endif
00733 }
00734 
00735 KJavaAppletContext *KHTMLPart::createJavaContext()
00736 {
00737 #ifndef Q_WS_QWS
00738   if ( !d->m_javaContext ) {
00739       d->m_javaContext = new KJavaAppletContext();
00740       connect( d->m_javaContext, SIGNAL(showStatus(const QString&)),
00741                this, SIGNAL(setStatusBarText(const QString&)) );
00742       connect( d->m_javaContext, SIGNAL(showDocument(const QString&, const QString&)),
00743                this, SLOT(slotShowDocument(const QString&, const QString&)) );
00744       connect( d->m_javaContext, SIGNAL(appletLoaded()),
00745                this, SLOT(checkCompleted()) );
00746   }
00747 
00748   return d->m_javaContext;
00749 #else
00750   return 0;
00751 #endif
00752 }
00753 
00754 void KHTMLPart::setPluginsEnabled( bool enable )
00755 {
00756   d->m_bPluginsForce = enable;
00757   d->m_bPluginsOverride = true;
00758 }
00759 
00760 bool KHTMLPart::pluginsEnabled() const
00761 {
00762   if ( d->m_bPluginsOverride )
00763       return d->m_bPluginsForce;
00764   return d->m_bPluginsEnabled;
00765 }
00766 
00767 void KHTMLPart::slotShowDocument( const QString &url, const QString &target )
00768 {
00769   // this is mostly copied from KHTMLPart::slotChildURLRequest. The better approach
00770   // would be to put those functions into a single one.
00771   khtml::ChildFrame *child = 0;
00772   KParts::URLArgs args;
00773   args.frameName = target;
00774 
00775   QString frameName = args.frameName.lower();
00776   if ( !frameName.isEmpty() )
00777   {
00778     if ( frameName == QString::fromLatin1( "_top" ) )
00779     {
00780       emit d->m_extension->openURLRequest( url, args );
00781       return;
00782     }
00783     else if ( frameName == QString::fromLatin1( "_blank" ) )
00784     {
00785       emit d->m_extension->createNewWindow( url, args );
00786       return;
00787     }
00788     else if ( frameName == QString::fromLatin1( "_parent" ) )
00789     {
00790       KParts::URLArgs newArgs( args );
00791       newArgs.frameName = QString::null;
00792 
00793       emit d->m_extension->openURLRequest( url, newArgs );
00794       return;
00795     }
00796     else if ( frameName != QString::fromLatin1( "_self" ) )
00797     {
00798       khtml::ChildFrame *_frame = recursiveFrameRequest( this, url, args );
00799 
00800       if ( !_frame )
00801       {
00802         emit d->m_extension->openURLRequest( url, args );
00803         return;
00804       }
00805 
00806       child = _frame;
00807     }
00808   }
00809 
00810   // TODO: handle child target correctly! currently the script are always executed fur the parent
00811   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
00812       executeScript( KURL::decode_string( url.right( url.length() - 11) ) );
00813       return;
00814   }
00815 
00816   if ( child ) {
00817       requestObject( child, KURL(url), args );
00818   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
00819   {
00820       KParts::URLArgs newArgs( args );
00821       newArgs.frameName = QString::null;
00822       emit d->m_extension->openURLRequest( KURL(url), newArgs );
00823   }
00824 }
00825 
00826 void KHTMLPart::slotDebugDOMTree()
00827 {
00828   if ( d->m_doc && d->m_doc->firstChild() )
00829     qDebug("%s", d->m_doc->firstChild()->toHTML().latin1());
00830 }
00831 
00832 void KHTMLPart::slotDebugRenderTree()
00833 {
00834 #ifndef NDEBUG
00835   if ( d->m_doc )
00836     d->m_doc->renderer()->printTree();
00837 #endif
00838 }
00839 
00840 void KHTMLPart::setAutoloadImages( bool enable )
00841 {
00842   if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
00843     return;
00844 
00845   if ( d->m_doc )
00846     d->m_doc->docLoader()->setAutoloadImages( enable );
00847 
00848   unplugActionList( "loadImages" );
00849 
00850   if ( enable ) {
00851     delete d->m_paLoadImages;
00852     d->m_paLoadImages = 0;
00853   }
00854   else if ( !d->m_paLoadImages )
00855     d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
00856 
00857   if ( d->m_paLoadImages ) {
00858     QPtrList<KAction> lst;
00859     lst.append( d->m_paLoadImages );
00860     plugActionList( "loadImages", lst );
00861   }
00862 }
00863 
00864 bool KHTMLPart::autoloadImages() const
00865 {
00866   if ( d->m_doc )
00867     return d->m_doc->docLoader()->autoloadImages();
00868 
00869   return true;
00870 }
00871 
00872 void KHTMLPart::clear()
00873 {
00874   if ( d->m_bCleared )
00875     return;
00876   d->m_bCleared = true;
00877 
00878   d->m_bClearing = true;
00879 
00880   {
00881     ConstFrameIt it = d->m_frames.begin();
00882     ConstFrameIt end = d->m_frames.end();
00883     for(; it != end; ++it )
00884     {
00885       // Stop HTMLRun jobs for frames
00886       if ( (*it).m_run )
00887         (*it).m_run->abort();
00888     }
00889   }
00890 
00891   {
00892     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
00893     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
00894     for(; it != end; ++it )
00895     {
00896       // Stop HTMLRun jobs for objects
00897       if ( (*it).m_run )
00898         (*it).m_run->abort();
00899     }
00900   }
00901 
00902 
00903   findTextBegin(); // resets d->m_findNode and d->m_findPos
00904 
00905   d->m_mousePressNode = DOM::Node();
00906 
00907 
00908   if ( d->m_doc )
00909     d->m_doc->detach();
00910 
00911   // Moving past doc so that onUnload works.
00912   if ( d->m_jscript )
00913     d->m_jscript->clear();
00914 
00915   if ( d->m_view )
00916     d->m_view->clear();
00917 
00918   // do not dereference the document before the jscript and view are cleared, as some destructors
00919   // might still try to access the document.
00920   if ( d->m_doc )
00921     d->m_doc->deref();
00922   d->m_doc = 0;
00923 
00924   delete d->m_decoder;
00925   d->m_decoder = 0;
00926 
00927   {
00928     ConstFrameIt it = d->m_frames.begin();
00929     ConstFrameIt end = d->m_frames.end();
00930     for(; it != end; ++it )
00931     {
00932       if ( (*it).m_part )
00933       {
00934         partManager()->removePart( (*it).m_part );
00935         delete (KParts::ReadOnlyPart *)(*it).m_part;
00936       }
00937     }
00938   }
00939 
00940   d->m_frames.clear();
00941   d->m_objects.clear();
00942 
00943 #ifndef Q_WS_QWS
00944   if( d->m_javaContext )
00945   {
00946     d->m_javaContext->deleteLater();
00947     d->m_javaContext = 0;
00948   }
00949 #endif
00950 
00951   d->m_delayRedirect = 0;
00952   d->m_redirectURL = QString::null;
00953   d->m_redirectLockHistory = true;
00954   d->m_bHTTPRefresh = false;
00955   d->m_bClearing = false;
00956   d->m_frameNameId = 1;
00957   d->m_bFirstData = true;
00958 
00959   d->m_bMousePressed = false;
00960 
00961   d->m_selectionStart = DOM::Node();
00962   d->m_selectionEnd = DOM::Node();
00963   d->m_startOffset = 0;
00964   d->m_endOffset = 0;
00965 #ifndef QT_NO_CLIPBOARD
00966   connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
00967 #endif
00968 
00969   d->m_totalObjectCount = 0;
00970   d->m_loadedObjects = 0;
00971   d->m_jobPercent = 0;
00972 
00973   if ( !d->m_haveEncoding )
00974     d->m_encoding = QString::null;
00975 #ifdef SPEED_DEBUG
00976   d->m_parsetime.restart();
00977 #endif
00978 }
00979 
00980 bool KHTMLPart::openFile()
00981 {
00982   return true;
00983 }
00984 
00985 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
00986 {
00987     if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
00988         return static_cast<HTMLDocumentImpl*>(d->m_doc);
00989     return 0;
00990 }
00991 
00992 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
00993 {
00994     if ( d )
00995         return d->m_doc;
00996     return 0;
00997 }
00998 
00999 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const QString& msg)
01000 {
01001   assert(d->m_job == kio_job);
01002 
01003   if (!parentPart())
01004     setStatusBarText(msg, BarDefaultText);
01005 }
01006 
01007 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
01008 {
01009   assert ( d->m_job == kio_job );
01010 
01011   //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
01012   // The first data ?
01013   if ( !d->m_workingURL.isEmpty() )
01014   {
01015       //kdDebug( 6050 ) << "begin!" << endl;
01016 
01017     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
01018 
01019 
01020     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
01021     d->m_workingURL = KURL();
01022 
01023     d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
01024 
01025     // When the first data arrives, the metadata has just been made available
01026     d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
01027     time_t cacheCreationDate =  d->m_job->queryMetaData("cache-creation-date").toLong();
01028     d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);
01029 
01030     d->m_pageServices = d->m_job->queryMetaData("PageServices");
01031 
01032     d->m_bSecurityInQuestion = false;
01033     d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
01034     kdDebug(6050) << "SSL in use? " << d->m_job->queryMetaData("ssl_in_use") << endl;
01035 
01036     {
01037     KHTMLPart *p = parentPart();
01038     if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
01039     while (p->parentPart()) p = p->parentPart();
01040 
01041     p->d->m_paSecurity->setIcon( "halfencrypted" );
01042         p->d->m_bSecurityInQuestion = true;
01043     kdDebug(6050) << "parent setIcon half done." << endl;
01044     }
01045     }
01046 
01047     d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
01048     kdDebug(6050) << "setIcon " << ( d->m_ssl_in_use ? "encrypted" : "decrypted" ) << " done." << endl;
01049 
01050     // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
01051 
01052     d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
01053     d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
01054     d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
01055     d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
01056     d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
01057     d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
01058     d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
01059     d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
01060     d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
01061     d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
01062     d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
01063 
01064     // Check for charset meta-data
01065     QString qData = d->m_job->queryMetaData("charset");
01066     if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
01067        d->m_encoding = qData;
01068 
01069     // Support for http-refresh
01070     qData = d->m_job->queryMetaData("http-refresh");
01071     if( !qData.isEmpty() && d->m_metaRefreshEnabled )
01072     {
01073       kdDebug(6050) << "HTTP Refresh Request: " << qData << endl;
01074       int delay;
01075       int pos = qData.find( ';' );
01076       if ( pos == -1 )
01077         pos = qData.find( ',' );
01078 
01079       if( pos == -1 )
01080       {
01081         delay = qData.stripWhiteSpace().toInt();
01082         scheduleRedirection( qData.toInt(), m_url.url());
01083       }
01084       else
01085       {
01086         int end_pos = qData.length();
01087         delay = qData.left(pos).stripWhiteSpace().toInt();
01088         while ( qData[++pos] == ' ' );
01089         if ( qData.find( "url", pos, false ) == pos )
01090         {
01091           pos += 3;
01092           while (qData[pos] == ' ' || qData[pos] == '=' )
01093               pos++;
01094           if ( qData[pos] == '"' )
01095           {
01096               pos++;
01097               int index = end_pos-1;
01098               while( index > pos )
01099               {
01100                 if ( qData[index] == '"' )
01101                     break;
01102                 index--;
01103               }
01104               if ( index > pos )
01105                 end_pos = index;
01106           }
01107         }
01108         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ));
01109       }
01110       d->m_bHTTPRefresh = true;
01111     }
01112 
01113     if ( !m_url.isLocalFile() ) {
01114         // Support for http last-modified
01115         d->m_lastModified = d->m_job->queryMetaData("modified");
01116     } else
01117         d->m_lastModified = QString::null; // done on-demand by lastModified()
01118   }
01119 
01120   KHTMLPageCache::self()->addData(d->m_cacheId, data);
01121   write( data.data(), data.size() );
01122 }
01123 
01124 void KHTMLPart::slotRestoreData(const QByteArray &data )
01125 {
01126   // The first data ?
01127   if ( !d->m_workingURL.isEmpty() )
01128   {
01129      long saveCacheId = d->m_cacheId;
01130      begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
01131      d->m_cacheId = saveCacheId;
01132      d->m_workingURL = KURL();
01133   }
01134 
01135   //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
01136   write( data.data(), data.size() );
01137 
01138   if (data.size() == 0)
01139   {
01140       //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
01141      // End of data.
01142     if (d->m_doc && d->m_doc->parsing())
01143         end(); //will emit completed()
01144   }
01145 }
01146 
01147 void KHTMLPart::showError( KIO::Job* job )
01148 {
01149   kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
01150                 << " d->m_bCleared=" << d->m_bCleared << endl;
01151 
01152   if (job->error() == KIO::ERR_NO_CONTENT)
01153     return;
01154 
01155   if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
01156     job->showErrorDialog( /*d->m_view*/ );
01157   else
01158   {
01159     htmlError( job->error(), job->errorText(), d->m_workingURL );
01160   }
01161 }
01162 
01163 // This is a protected method, placed here because of it's relevance to showError
01164 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
01165 {
01166   kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
01167   // make sure we're not executing any embedded JS
01168   bool bJSFO = d->m_bJScriptForce;
01169   bool bJSOO = d->m_bJScriptOverride;
01170   d->m_bJScriptForce = false;
01171   d->m_bJScriptOverride = true;
01172   begin();
01173   QString errText = QString::fromLatin1( "<HTML><HEAD><TITLE>" );
01174   errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
01175   errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
01176   errText += i18n( "An error occured while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
01177   errText += QString::fromLatin1( "</P><P>" );
01178   QString kioErrString = KIO::buildErrorString( errorCode, text );
01179 
01180   kioErrString.replace(QRegExp("&"), QString("&amp;"));
01181   kioErrString.replace(QRegExp("<"), QString("&lt;"));
01182   kioErrString.replace(QRegExp(">"), QString("&gt;"));
01183 
01184   // In case the error string has '\n' in it, replace with <BR/>
01185   kioErrString.replace( QRegExp("\n"), "<BR/>" );
01186 
01187   errText += kioErrString;
01188   errText += QString::fromLatin1( "</P></BODY></HTML>" );
01189   write(errText);
01190   end();
01191 
01192   d->m_bJScriptForce = bJSFO;
01193   d->m_bJScriptOverride = bJSOO;
01194 
01195   // make the working url the current url, so that reload works and
01196   // emit the progress signals to advance one step in the history
01197   // (so that 'back' works)
01198   m_url = reqUrl; // same as d->m_workingURL
01199   d->m_workingURL = KURL();
01200   emit started( 0 );
01201   emit completed();
01202   return;
01203   // following disabled until 3.1
01204 
01205   QString errorName, techName, description;
01206   QStringList causes, solutions;
01207 
01208   QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
01209   QDataStream stream(raw, IO_ReadOnly);
01210 
01211   stream >> errorName >> techName >> description >> causes >> solutions;
01212 
01213   QString url, protocol, datetime;
01214   url = reqUrl.prettyURL();
01215   protocol = reqUrl.protocol();
01216   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
01217                                                 false );
01218 
01219   QString doc = QString::fromLatin1( "<html><head><title>" );
01220   doc += i18n( "Error: " );
01221   doc += errorName;
01222   doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
01223   doc += i18n( "The requested operation could not be completed" );
01224   doc += QString::fromLatin1( "</h1><h2>" );
01225   doc += errorName;
01226   doc += QString::fromLatin1( "</h2>" );
01227   if ( techName != QString::null ) {
01228     doc += QString::fromLatin1( "<h2>" );
01229     doc += i18n( "Technical Reason: " );
01230     doc += techName;
01231     doc += QString::fromLatin1( "</h2>" );
01232   }
01233   doc += QString::fromLatin1( "<h3>" );
01234   doc += i18n( "Details of the Request:" );
01235   doc += QString::fromLatin1( "</h3><ul><li>" );
01236   doc += i18n( "URL: %1" ).arg( url );
01237   doc += QString::fromLatin1( "</li><li>" );
01238   if ( protocol != QString::null ) {
01239     // uncomment for 3.1... i18n change
01240     // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
01241     doc += QString::fromLatin1( "</li><li>" );
01242   }
01243   doc += i18n( "Date and Time: %1" ).arg( datetime );
01244   doc += QString::fromLatin1( "</li><li>" );
01245   doc += i18n( "Additional Information: %1" ).arg( text );
01246   doc += QString::fromLatin1( "</li></ul><h3>" );
01247   doc += i18n( "Description:" );
01248   doc += QString::fromLatin1( "</h3><p>" );
01249   doc += description;
01250   doc += QString::fromLatin1( "</p>" );
01251   if ( causes.count() ) {
01252     doc += QString::fromLatin1( "<h3>" );
01253     doc += i18n( "Possible Causes:" );
01254     doc += QString::fromLatin1( "</h3><ul><li>" );
01255     doc += causes.join( "</li><li>" );
01256     doc += QString::fromLatin1( "</li></ul>" );
01257   }
01258   if ( solutions.count() ) {
01259     doc += QString::fromLatin1( "<h3>" );
01260     doc += i18n( "Possible Solutions:" );
01261     doc += QString::fromLatin1( "</h3><ul><li>" );
01262     doc += solutions.join( "</li><li>" );
01263     doc += QString::fromLatin1( "</li></ul>" );
01264   }
01265   doc += QString::fromLatin1( "</body></html>" );
01266 
01267   write( doc );
01268   end();
01269 }
01270 
01271 void KHTMLPart::slotFinished( KIO::Job * job )
01272 {
01273   d->m_job = 0L;
01274   d->m_jobspeed = 0L;
01275 
01276   if (job->error())
01277   {
01278     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
01279     emit canceled( job->errorString() );
01280     // TODO: what else ?
01281     checkCompleted();
01282     showError( job );
01283     return;
01284   }
01285   //kdDebug( 6050 ) << "slotFinished" << endl;
01286 
01287   KHTMLPageCache::self()->endData(d->m_cacheId);
01288 
01289   if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
01290       KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
01291 
01292   d->m_workingURL = KURL();
01293 
01294   if (d->m_doc->parsing())
01295     end(); //will emit completed()
01296 }
01297 
01298 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
01299 {
01300   clear();
01301   d->m_bCleared = false;
01302   d->m_cacheId = 0;
01303   d->m_bComplete = false;
01304   d->m_bLoadEventEmitted = false;
01305 
01306   if(url.isValid()) {
01307       QString urlString = url.url();
01308       KHTMLFactory::vLinks()->insert( urlString );
01309       QString urlString2 = url.prettyURL();
01310       if ( urlString != urlString2 ) {
01311           KHTMLFactory::vLinks()->insert( urlString2 );
01312       }
01313   }
01314 
01315   // ###
01316   //stopParser();
01317 
01318   KParts::URLArgs args( d->m_extension->urlArgs() );
01319   args.xOffset = xOffset;
01320   args.yOffset = yOffset;
01321   d->m_extension->setURLArgs( args );
01322 
01323   KURL ref(url);
01324   ref.setRef(QString::null);
01325   d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : QString::null;
01326 
01327   m_url = url;
01328   KURL baseurl;
01329 
01330   if ( !m_url.isEmpty() )
01331   {
01332     KURL::List lst = KURL::split( m_url );
01333     if ( !lst.isEmpty() )
01334       baseurl = *lst.begin();
01335 
01336     KURL title( baseurl );
01337     title.setRef( QString::null );
01338     title.setQuery( QString::null );
01339     emit setWindowCaption( title.url() );
01340   }
01341   else
01342     emit setWindowCaption( i18n( "no title", "* Unknown *" ) );
01343 
01344   // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
01345   if (args.serviceType == "text/xml")
01346     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
01347   else
01348     d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
01349 
01350   d->m_doc->ref();
01351   if (!d->m_doc->attached())
01352     d->m_doc->attach( );
01353   d->m_doc->setURL( m_url.url() );
01354   // We prefer m_baseURL over m_url because m_url changes when we are
01355   // about to load a new page.
01356   d->m_doc->setBaseURL( baseurl.url() );
01357   d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
01358   emit docCreated(); // so that the parent can set the domain
01359 
01360   d->m_paUseStylesheet->setItems(QStringList());
01361   d->m_paUseStylesheet->setEnabled( false );
01362 
01363   setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
01364   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
01365   if ( !userStyleSheet.isEmpty() )
01366     setUserStyleSheet( KURL( userStyleSheet ) );
01367 
01368   d->m_doc->setRestoreState(args.docState);
01369   d->m_doc->open();
01370   // clear widget
01371   d->m_view->resizeContents( 0, 0 );
01372   connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
01373 
01374   emit d->m_extension->enableAction( "print", true );
01375 
01376   d->m_doc->setParsing(true);
01377 }
01378 
01379 void KHTMLPart::write( const char *str, int len )
01380 {
01381     if ( !d->m_decoder ) {
01382         d->m_decoder = new khtml::Decoder();
01383         if(!d->m_encoding.isNull())
01384             d->m_decoder->setEncoding(d->m_encoding.latin1(), d->m_haveEncoding);
01385         else
01386             d->m_decoder->setEncoding(settings()->encoding().latin1(), d->m_haveEncoding);
01387     }
01388   if ( len == 0 )
01389     return;
01390 
01391   if ( len == -1 )
01392     len = strlen( str );
01393 
01394   QString decoded = d->m_decoder->decode( str, len );
01395 
01396   if(decoded.isEmpty()) return;
01397 
01398   if(d->m_bFirstData) {
01399       // determine the parse mode
01400       d->m_doc->determineParseMode( decoded );
01401       d->m_bFirstData = false;
01402 
01403   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
01404       // ### this is still quite hacky, but should work a lot better than the old solution
01405       if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
01406       d->m_doc->setDecoderCodec(d->m_decoder->codec());
01407       d->m_doc->recalcStyle( NodeImpl::Force );
01408   }
01409 
01410   if (jScript())
01411     jScript()->appendSourceFile(m_url.url(),decoded);
01412   Tokenizer* t = d->m_doc->tokenizer();
01413   if(t)
01414     t->write( decoded, true );
01415 }
01416 
01417 void KHTMLPart::write( const QString &str )
01418 {
01419   if ( str.isNull() )
01420     return;
01421 
01422   if(d->m_bFirstData) {
01423       // determine the parse mode
01424       d->m_doc->setParseMode( DocumentImpl::Strict );
01425       d->m_bFirstData = false;
01426   }
01427   if (jScript())
01428     jScript()->appendSourceFile(m_url.url(),str);
01429   Tokenizer* t = d->m_doc->tokenizer();
01430   if(t)
01431     t->write( str, true );
01432 }
01433 
01434 void KHTMLPart::end()
01435 {
01436     // make sure nothing's left in there...
01437     if(d->m_decoder)
01438         write(d->m_decoder->flush());
01439     if (d->m_doc)
01440     d->m_doc->finishParsing();
01441 }
01442 
01443 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
01444 {
01445     if (!d->m_view) return;
01446     d->m_view->paint(p, rc, yOff, more);
01447 }
01448 
01449 void KHTMLPart::stopAnimations()
01450 {
01451   if ( d->m_doc )
01452     d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
01453 
01454   ConstFrameIt it = d->m_frames.begin();
01455   ConstFrameIt end = d->m_frames.end();
01456   for (; it != end; ++it )
01457     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
01458       KParts::ReadOnlyPart* p = ( *it ).m_part;
01459       static_cast<KHTMLPart*>( p )->stopAnimations();
01460     }
01461 }
01462 
01463 void KHTMLPart::slotFinishedParsing()
01464 {
01465   d->m_doc->setParsing(false);
01466   checkEmitLoadEvent();
01467   disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
01468 
01469   if (!d->m_view)
01470     return; // We are probably being destructed.
01471   // check if the scrollbars are really needed for the content
01472   // if not, remove them, relayout, and repaint
01473 
01474   d->m_view->restoreScrollBar();
01475 
01476   if ( !m_url.encodedHtmlRef().isEmpty() )
01477     if ( !gotoAnchor( m_url.encodedHtmlRef()) )
01478        gotoAnchor( m_url.htmlRef() );
01479 
01480   checkCompleted();
01481 }
01482 
01483 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
01484 {
01485   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
01486     KHTMLPart* p = this;
01487     while ( p ) {
01488       KHTMLPart* op = p;
01489       p->d->m_totalObjectCount++;
01490       p = p->parentPart();
01491       if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
01492         && !op->d->m_progressUpdateTimer.isActive())
01493     op->d->m_progressUpdateTimer.start( 200, true );
01494     }
01495   }
01496 }
01497 
01498 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
01499 {
01500   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
01501     KHTMLPart* p = this;
01502     while ( p ) {
01503       KHTMLPart* op = p;
01504       p->d->m_loadedObjects++;
01505       p = p->parentPart();
01506       if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
01507         && !op->d->m_progressUpdateTimer.isActive())
01508     op->d->m_progressUpdateTimer.start( 200, true );
01509     }
01510   }
01511 
01512   checkCompleted();
01513 }
01514 
01515 void KHTMLPart::slotProgressUpdate()
01516 {
01517   int percent;
01518   if ( d->m_loadedObjects < d->m_totalObjectCount )
01519     percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
01520   else
01521     percent = d->m_jobPercent;
01522 
01523   if( percent == 100 ) // never set 100% here
01524     percent = 99;
01525   if( d->m_bComplete ) // only if it's really complete
01526     percent = 100;
01527 
01528   if( d->m_bComplete )
01529     emit d->m_extension->infoMessage( i18n( "Page loaded." ));
01530   else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
01531     emit d->m_extension->infoMessage( i18n( "%n Image of %1 loaded.", "%n Images of %1 loaded.", d->m_loadedObjects).arg(d->m_totalObjectCount) );
01532 
01533   emit d->m_extension->loadingProgress( percent );
01534 }
01535 
01536 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
01537 {
01538   d->m_jobspeed = speed;
01539   if (!parentPart())
01540     setStatusBarText(jsStatusBarText(), BarOverrideText);
01541 }
01542 
01543 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
01544 {
01545   d->m_jobPercent = percent;
01546 
01547   if ( !parentPart() )
01548     d->m_progressUpdateTimer.start( 0, true );
01549 }
01550 
01551 void KHTMLPart::slotJobDone( KIO::Job* /*job*/ )
01552 {
01553   d->m_jobPercent = 100;
01554 
01555   if ( !parentPart() )
01556     d->m_progressUpdateTimer.start( 0, true );
01557 }
01558 
01559 void KHTMLPart::checkCompleted()
01560 {
01561   //kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << (d->m_doc && d->m_doc->parsing()) << endl;
01562   //kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;
01563 
01564   // restore the cursor position
01565   if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
01566   {
01567       if (d->m_focusNodeNumber >= 0)
01568           d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
01569       else
01570           d->m_doc->setFocusNode(0);
01571       d->m_focusNodeRestored = true;
01572   }
01573 
01574   bool bPendingChildRedirection = false;
01575   // Any frame that hasn't completed yet ?
01576   ConstFrameIt it = d->m_frames.begin();
01577   ConstFrameIt end = d->m_frames.end();
01578   for (; it != end; ++it ) {
01579     if ( !(*it).m_bCompleted )
01580       return;
01581     // Check for frames with pending redirections
01582     if ( (*it).m_bPendingRedirection )
01583       bPendingChildRedirection = true;
01584   }
01585 
01586   // Are we still parsing - or have we done the completed stuff already ?
01587   if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
01588     return;
01589 
01590   // Still waiting for images/scripts from the loader ?
01591   int requests = 0;
01592   if ( d->m_doc && d->m_doc->docLoader() )
01593     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
01594 
01595   if ( requests > 0 )
01596     return;
01597 
01598 #ifndef Q_WS_QWS
01599   if (d->m_javaContext && !d->m_javaContext->appletsLoaded())
01600       return;
01601 #endif
01602 
01603   // OK, completed.
01604   // Now do what should be done when we are really completed.
01605   d->m_bComplete = true;
01606   d->m_cachePolicy = KIO::CC_Verify; // reset cache policy
01607 
01608   KHTMLPart* p = this;
01609   while ( p ) {
01610     KHTMLPart* op = p;
01611     p = p->parentPart();
01612     if ( !p && !op->d->m_progressUpdateTimer.isActive())
01613       op->d->m_progressUpdateTimer.start( 0, true );
01614   }
01615 
01616   checkEmitLoadEvent(); // if we didn't do it before
01617 
01618   // check that the view has not been moved by the user
01619   if ( m_url.encodedHtmlRef().isEmpty() && d->m_view->contentsY() == 0 )
01620       d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset,
01621                                  d->m_extension->urlArgs().yOffset );
01622 
01623   d->m_view->complete();
01624 
01625   if ( !d->m_redirectURL.isEmpty() )
01626   {
01627     // Do not start redirection for frames here! That action is
01628     // deferred until the parent emits a completed signal.
01629     if ( parentPart() == 0 )
01630       d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
01631 
01632     emit completed( true );
01633   }
01634   else
01635   {
01636     if ( bPendingChildRedirection )
01637       emit completed( true );
01638     else
01639       emit completed();
01640   }
01641 
01642   // find the alternate stylesheets
01643   QStringList sheets;
01644   if (d->m_doc)
01645      sheets = d->m_doc->availableStyleSheets();
01646   d->m_paUseStylesheet->setItems( sheets );
01647   d->m_paUseStylesheet->setEnabled( !sheets.isEmpty() );
01648   if (!sheets.isEmpty())
01649   {
01650     d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
01651     slotUseStylesheet();
01652   }
01653 
01654   setJSDefaultStatusBarText(QString::null);
01655 
01656 #ifdef SPEED_DEBUG
01657   kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
01658 #endif
01659 }
01660 
01661 void KHTMLPart::checkEmitLoadEvent()
01662 {
01663   if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
01664 
01665   ConstFrameIt it = d->m_frames.begin();
01666   ConstFrameIt end = d->m_frames.end();
01667   for (; it != end; ++it )
01668     if ( !(*it).m_bCompleted ) // still got a frame running -> too early
01669       return;
01670 
01671 #ifndef Q_WS_QWS
01672   if (d->m_javaContext && !d->m_javaContext->appletsLoaded())
01673       return;
01674 #endif
01675   // Still waiting for images/scripts from the loader ?
01676   // (onload must happen afterwards, #45607)
01677   // ## This makes this method very similar to checkCompleted. A brave soul should try merging them.
01678   int requests = 0;
01679   if ( d->m_doc && d->m_doc->docLoader() )
01680     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
01681 
01682   if ( requests > 0 )
01683     return;
01684 
01685   d->m_bLoadEventEmitted = true;
01686   if (d->m_doc)
01687     d->m_doc->close();
01688 }
01689 
01690 const KHTMLSettings *KHTMLPart::settings() const
01691 {
01692   return d->m_settings;
01693 }
01694 
01695 #ifndef KDE_NO_COMPAT
01696 KURL KHTMLPart::baseURL() const
01697 {
01698   if ( !d->m_doc ) return KURL();
01699 
01700   return d->m_doc->baseURL();
01701 }
01702 
01703 QString KHTMLPart::baseTarget() const
01704 {
01705   if ( !d->m_doc ) return QString::null;
01706 
01707   return d->m_doc->baseTarget();
01708 }
01709 #endif
01710 
01711 KURL KHTMLPart::completeURL( const QString &url )
01712 {
01713   if ( !d->m_doc ) return url;
01714 
01715   if (d->m_decoder)
01716     return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
01717 
01718   return KURL( d->m_doc->completeURL( url ) );
01719 }
01720 
01721 void KHTMLPart::scheduleRedirection( int delay, const QString &url, bool doLockHistory )
01722 {
01723   //kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
01724     if ( delay < 24*60*60 &&
01725        ( d->m_redirectURL.isEmpty() || delay < d->m_delayRedirect ) )
01726     {
01727        d->m_delayRedirect = delay;
01728        d->m_redirectURL = url;
01729        d->m_redirectLockHistory = doLockHistory;
01730        if ( d->m_bComplete ) {
01731          d->m_redirectionTimer.stop();
01732          d->m_redirectionTimer.start( kMax(0, 1000 * d->m_delayRedirect), true );
01733        }
01734     }
01735 }
01736 
01737 void KHTMLPart::slotRedirect()
01738 {
01739   QString u = d->m_redirectURL;
01740   d->m_delayRedirect = 0;
01741   d->m_redirectURL = QString::null;
01742   d->m_referrer = QString::null;
01743   if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
01744   {
01745     QString script = KURL::decode_string( u.right( u.length() - 11 ) );
01746     //kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
01747     QVariant res = executeScript( script );
01748     if ( res.type() == QVariant::String ) {
01749       begin( url() );
01750       write( res.asString() );
01751       end();
01752     }
01753     return;
01754   }
01755   KParts::URLArgs args;
01756   // Redirecting to the current URL leads to a reload.
01757   // But jumping to an anchor never leads to a reload.
01758   KURL url( u );
01759 
01760   if (!kapp || !kapp->kapp->authorizeURLAction("redirect", m_url, url))
01761   {
01762     kdWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << m_url.prettyURL() << " to " << url.prettyURL() << " REJECTED!" << endl;
01763     return;
01764   }
01765 
01766   if ( !url.hasRef() && urlcmp( u, m_url.url(), true, true ) )
01767   {
01768     args.reload = true;
01769   }
01770 
01771   args.setLockHistory( d->m_redirectLockHistory );
01772   // _self: make sure we don't use any <base target=>'s
01773   urlSelected( u, 0, 0, "_self", args );
01774 }
01775 
01776 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
01777 {
01778   // the slave told us that we got redirected
01779   // kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
01780   emit d->m_extension->setLocationBarURL( url.prettyURL() );
01781   d->m_workingURL = url;
01782 }
01783 
01784 bool KHTMLPart::setEncoding( const QString &name, bool override )
01785 {
01786     d->m_encoding = name;
01787     d->m_haveEncoding = override;
01788 
01789     if( !m_url.isEmpty() ) {
01790         // reload document
01791         closeURL();
01792         KURL url = m_url;
01793         m_url = 0;
01794         d->m_restored = true;
01795         openURL(url);
01796         d->m_restored = false;
01797     }
01798 
01799     return true;
01800 }
01801 
01802 QString KHTMLPart::encoding() const
01803 {
01804     if(d->m_haveEncoding && !d->m_encoding.isEmpty())
01805         return d->m_encoding;
01806 
01807     if(d->m_decoder && d->m_decoder->encoding())
01808         return QString(d->m_decoder->encoding());
01809 
01810     return(settings()->encoding());
01811 }
01812 
01813 void KHTMLPart::setUserStyleSheet(const KURL &url)
01814 {
01815   if ( d->m_doc && d->m_doc->docLoader() )
01816     (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
01817 }
01818 
01819 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
01820 {
01821   if ( d->m_doc )
01822     d->m_doc->setUserStyleSheet( styleSheet );
01823 }
01824 
01825 bool KHTMLPart::gotoAnchor( const QString &name )
01826 {
01827   if (!d->m_doc)
01828     return false;
01829 
01830   HTMLCollectionImpl *anchors =
01831       new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
01832   anchors->ref();
01833   NodeImpl *n = anchors->namedItem(name);
01834   anchors->deref();
01835 
01836   if(!n) {
01837       n = d->m_doc->getElementById( name );
01838   }
01839 
01840   if(!n) {
01841       kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
01842       return false;
01843   }
01844 
01845   int x = 0, y = 0;
01846   int gox, dummy;
01847   HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
01848 
01849   a->getUpperLeftCorner(x, y);
01850   if (x <= d->m_view->contentsX())
01851     gox = x - 10;
01852   else {
01853     gox = d->m_view->contentsX();
01854     if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
01855       a->getLowerRightCorner(x, dummy);
01856       gox = x - d->m_view->visibleWidth() + 10;
01857     }
01858   }
01859 
01860   d->m_view->setContentsPos(gox, y-20);
01861 
01862   return true;
01863 }
01864 
01865 void KHTMLPart::setStandardFont( const QString &name )
01866 {
01867     d->m_settings->setStdFontName(name);
01868 }
01869 
01870 void KHTMLPart::setFixedFont( const QString &name )
01871 {
01872     d->m_settings->setFixedFontName(name);
01873 }
01874 
01875 void KHTMLPart::setURLCursor( const QCursor &c )
01876 {
01877   d->m_linkCursor = c;
01878 }
01879 
01880 QCursor KHTMLPart::urlCursor() const
01881 {
01882   return d->m_linkCursor;
01883 }
01884 
01885 bool KHTMLPart::onlyLocalReferences() const
01886 {
01887   return d->m_onlyLocalReferences;
01888 }
01889 
01890 void KHTMLPart::setOnlyLocalReferences(bool enable)
01891 {
01892   d->m_onlyLocalReferences = enable;
01893 }
01894 
01895 void KHTMLPart::findTextBegin()
01896 {
01897   d->m_findPos = -1;
01898   d->m_findNode = 0;
01899   d->m_findPosEnd = -1;
01900   d->m_findNodeEnd= 0;
01901   d->m_paFindNext->setEnabled( false ); // needs a 'find' first
01902 }
01903 
01904 bool KHTMLPart::initFindNode( bool selection, bool reverse )
01905 {
01906     if ( !d->m_doc )
01907         return false;
01908 
01909     if(!d->m_findNode) {
01910         if (d->m_doc->isHTMLDocument())
01911             d->m_findNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
01912         else
01913             d->m_findNode = d->m_doc;
01914     }
01915 
01916     if ( !d->m_findNode )
01917     {
01918       kdDebug(6050) << k_funcinfo << "no findNode -> return false" << endl;
01919       return false;
01920     }
01921     if ( d->m_findNode->id() == ID_FRAMESET )
01922     {
01923       kdDebug(6050) << k_funcinfo << "FRAMESET -> return false" << endl;
01924       return false;
01925     }
01926 
01927     if ( selection && hasSelection() )
01928     {
01929       kdDebug(6050) << k_funcinfo << "using selection" << endl;
01930       d->m_findNode = d->m_selectionStart.handle();
01931       d->m_findPos = d->m_startOffset;
01932       d->m_findNodeEnd = d->m_selectionEnd.handle();
01933       d->m_findPosEnd = d->m_endOffset;
01934       if ( reverse ) {
01935         qSwap( d->m_findNode, d->m_findNodeEnd );
01936         qSwap( d->m_findPos, d->m_findPosEnd );
01937       }
01938     }
01939     else // whole document
01940     {
01941       //kdDebug(6050) << k_funcinfo << "whole doc" << endl;
01942       d->m_findPos = 0;
01943       d->m_findPosEnd = -1;
01944       d->m_findNodeEnd = 0;
01945       if ( reverse ) {
01946         qSwap( d->m_findPos, d->m_findPosEnd );
01947         // Need to find out the really last object, to start from it
01948         while ( d->m_findNode->lastChild() )
01949           d->m_findNode = d->m_findNode->lastChild();
01950       }
01951     }
01952     return true;
01953 }
01954 
01955 // Old method (its API limits the available features - remove in KDE-4)
01956 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
01957 {
01958     if ( !initFindNode( false, !forward ) )
01959       return false;
01960     while(1)
01961     {
01962         if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
01963         {
01964             DOMString nodeText = d->m_findNode->nodeValue();
01965             DOMStringImpl *t = nodeText.implementation();
01966             QConstString s(t->s, t->l);
01967 
01968             int matchLen = 0;
01969             if ( isRegExp ) {
01970               QRegExp matcher( str );
01971               matcher.setCaseSensitive( caseSensitive );
01972               d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
01973               if ( d->m_findPos != -1 )
01974                 matchLen = matcher.matchedLength();
01975             }
01976             else {
01977               d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
01978               matchLen = str.length();
01979             }
01980 
01981             if(d->m_findPos != -1)
01982             {
01983                 int x = 0, y = 0;
01984                 if(static_cast<khtml::RenderText *>(d->m_findNode->renderer())
01985                   ->posOfChar(d->m_findPos, x, y))
01986                     d->m_view->setContentsPos(x-50, y-50);
01987 
01988                 d->m_selectionStart = d->m_findNode;
01989                 d->m_startOffset = d->m_findPos;
01990                 d->m_selectionEnd = d->m_findNode;
01991                 d->m_endOffset = d->m_findPos + matchLen;
01992                 d->m_startBeforeEnd = true;
01993 
01994                 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
01995                                         d->m_selectionEnd.handle(), d->m_endOffset );
01996                 emitSelectionChanged();
01997                 return true;
01998             }
01999         }
02000         d->m_findPos = -1;
02001 
02002         NodeImpl *next;
02003 
02004         if ( forward )
02005         {
02006           next = d->m_findNode->firstChild();
02007 
02008           if(!next) next = d->m_findNode->nextSibling();
02009           while(d->m_findNode && !next) {
02010               d->m_findNode = d->m_findNode->parentNode();
02011               if( d->m_findNode ) {
02012                   next = d->m_findNode->nextSibling();
02013               }
02014           }
02015         }
02016         else
02017         {
02018           next = d->m_findNode->lastChild();
02019 
02020           if (!next ) next = d->m_findNode->previousSibling();
02021           while ( d->m_findNode && !next )
02022           {
02023             d->m_findNode = d->m_findNode->parentNode();
02024             if( d->m_findNode )
02025             {
02026               next = d->m_findNode->previousSibling();
02027             }
02028           }
02029         }
02030 
02031         d->m_findNode = next;
02032         if(!d->m_findNode) return false;
02033     }
02034 }
02035 
02036 
02037 void KHTMLPart::slotFind()
02038 {
02039   KParts::ReadOnlyPart *part = currentFrame();
02040   if (!part)
02041     return;
02042   if (!part->inherits("KHTMLPart") )
02043   {
02044       kdError(6000) << "slotFind: part is a " << part->className() << ", can't do a search into it" << endl;
02045       return;
02046   }
02047   static_cast<KHTMLPart *>( part )->findText();
02048 }
02049 
02050 void KHTMLPart::slotFindNext()
02051 {
02052   KParts::ReadOnlyPart *part = currentFrame();
02053   if (!part)
02054     return;
02055   if (!part->inherits("KHTMLPart") )
02056   {
02057       kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
02058       return;
02059   }
02060   static_cast<KHTMLPart *>( part )->findTextNext();
02061 }
02062 
02063 void KHTMLPart::slotFindDone()
02064 {
02065   // ### remove me
02066 }
02067 
02068 void KHTMLPart::slotFindDialogDestroyed()
02069 {
02070   // ### remove me
02071 }
02072 
02073 void KHTMLPart::findText()
02074 {
02075   // First do some init to make sure we can search in this frame
02076   if ( !d->m_doc )
02077     return;
02078 
02079   // The lineedit of the dialog would make khtml lose its selection, otherwise
02080 #ifndef QT_NO_CLIPBOARD
02081   disconnect( kapp->clipboard(), SIGNAL(selectionChanged()), this, SLOT(slotClearSelection()) );
02082 #endif
02083 
02084   // Now show the dialog in which the user can choose options.
02085   KFindDialog optionsDialog( widget(), "khtmlfind" );
02086   optionsDialog.setHasSelection( hasSelection() );
02087   optionsDialog.setHasCursor( d->m_findNode != 0 );
02088   if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
02089     d->m_lastFindState.options |= KFindDialog::FromCursor;
02090 
02091   // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
02092   optionsDialog.setFindHistory( d->m_lastFindState.history );
02093   optionsDialog.setOptions( d->m_lastFindState.options );
02094 
02095   if ( optionsDialog.exec() != QDialog::Accepted )
02096       return;
02097 
02098 #ifndef QT_NO_CLIPBOARD
02099   connect( kapp->clipboard(), SIGNAL(selectionChanged()), SLOT(slotClearSelection()) );
02100 #endif
02101 
02102   // Save for next time
02103   //d->m_lastFindState.text = optionsDialog.pattern();
02104   int options = optionsDialog.options();
02105   d->m_lastFindState.options = options;
02106   d->m_lastFindState.history = optionsDialog.findHistory();
02107 
02108   // Create the KFind object
02109   delete d->m_find;
02110   d->m_find = new KFind( optionsDialog.pattern(), options, widget() );
02111   connect(d->m_find, SIGNAL( highlight( const QString &, int, int ) ),
02112           this, SLOT( slotHighlight( const QString &, int, int ) ) );
02113   connect(d->m_find, SIGNAL( findNext() ),
02114           this, SLOT( slotFindNext() ) );
02115 
02116   if ( options & KFindDialog::SelectedText )
02117     Q_ASSERT( hasSelection() );
02118 
02119   if ( (options & KFindDialog::FromCursor) == 0 )
02120       (void) initFindNode( options & KFindDialog::SelectedText, options & KFindDialog::FindBackwards );
02121   findTextNext();
02122 }
02123 
02124 // New method
02125 void KHTMLPart::findTextNext()
02126 {
02127   if (!d->m_find) // shouldn't be called before find is activated
02128     return;
02129 
02130   long options = d->m_find->options();
02131   KFind::Result res = KFind::NoMatch;
02132   khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
02133   khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
02134   //kdDebug(6050) << k_funcinfo << "obj=" << obj << " end=" << end << endl;
02135   while( res == KFind::NoMatch )
02136   {
02137     if ( d->m_find->needData() )
02138     {
02139       if ( !obj ) {
02140         //kdDebug(6050) << k_funcinfo << "obj=0 -> done" << endl;
02141         break; // we're done
02142       }
02143       //kdDebug(6050) << k_funcinfo << " gathering data" << endl;
02144       // First make up the QString for the current 'line' (i.e. up to \n)
02145       // We also want to remember the DOMNode for every portion of the string.
02146       // We store this in an index->node list.
02147 
02148       d->m_stringPortions.clear();
02149       int newLinePos = -1;
02150       QString str;
02151       DOM::NodeImpl* lastNode = d->m_findNode;
02152       while ( obj && newLinePos == -1 )
02153       {
02154         // Grab text from render object
02155         QString s;
02156         if ( obj->isText() )
02157           s = static_cast<khtml::RenderText *>(obj)->data().string();
02158         else if ( obj->isBR() )
02159           s = '\n';
02160         else if ( !obj->isInline() && !str.isEmpty() )
02161           s = '\n';
02162         if ( lastNode == d->m_findNodeEnd )
02163           s.truncate( d->m_findPosEnd );
02164         if ( !s.isEmpty() )
02165         {
02166           newLinePos = s.find( '\n' ); // did we just get a newline?
02167           int index = str.length();
02168           if ( newLinePos != -1 )
02169             newLinePos += index;
02170           str += s;
02171           //kdDebug(6050) << "StringPortion: " << index << "-" << index+s.length()-1 << " -> " << node << endl;
02172           d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( index, lastNode ) );
02173         }
02174         // Compare obj and end _after_ we processed the 'end' node itself
02175         if ( obj == end )
02176           obj = 0L;
02177         else
02178         {
02179           // Move on to next object (note: if we found a \n already, then obj (and lastNode)
02180           // will point to the _next_ object, i.e. they are in advance.
02181           do {
02182             // We advance until the next RenderObject that has a NodeImpl as its element().
02183             // Otherwise (if we keep the 'last node', and it has a '\n') we might be stuck
02184             // on that object forever...
02185             obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
02186           } while ( obj && !obj->element() );
02187         }
02188         if ( obj )
02189           lastNode = obj->element();
02190         else
02191           lastNode = 0;
02192       } // end while
02193 
02194       if ( !str.isEmpty() )
02195       {
02196         //kdDebug(6050) << "str=" << str << endl;
02197         d->m_find->setData( str, d->m_findPos );
02198       }
02199 
02200       d->m_findPos = -1; // not used during the findnext loops. Only during init.
02201       d->m_findNode = lastNode;
02202     }
02203     if ( !d->m_find->needData() ) // happens if str was empty
02204     {
02205       // Let KFind inspect the text fragment, and display a dialog if a match is found
02206       res = d->m_find->find();
02207     }
02208   } // end while
02209 
02210   if ( res == KFind::NoMatch ) // i.e. we're done
02211   {
02212     if ( d->m_find->shouldRestart() )
02213     {
02214       //kdDebug(6050) << "Restarting" << endl;
02215       initFindNode( false, options & KFindDialog::FindBackwards );
02216       findTextNext();
02217     }
02218     else // really done, close 'find next' dialog
02219     {
02220       //kdDebug(6050) << "Finishing" << endl;
02221       delete d->m_find;
02222       d->m_find = 0L;
02223       slotClearSelection();
02224     }
02225   }
02226   d->m_paFindNext->setEnabled( d->m_find != 0L  ); // true, except when completely done
02227 }
02228 
02229 void KHTMLPart::slotHighlight( const QString &, int index, int length )
02230 {
02231   //kdDebug(6050) << "slotHighlight index=" << index << " length=" << length << endl;
02232   QValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
02233   QValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
02234   // We stop at the first portion whose index is 'greater than', and then use the previous one
02235   while ( it != d->m_stringPortions.end() && (*it).index <= index )
02236   {
02237     prev = it;
02238     ++it;
02239   }
02240   Q_ASSERT ( prev != d->m_stringPortions.end() );
02241   DOM::NodeImpl* node = (*prev).node;
02242   Q_ASSERT( node );
02243 
02244   d->m_selectionStart = node;
02245   d->m_startOffset = index - (*prev).index;
02246 
02247   Q_ASSERT( node->renderer() );
02248   if ( node->renderer() )
02249   {
02250     int x = 0, y = 0;
02251     if (static_cast<khtml::RenderText *>(node->renderer())
02252       ->posOfChar(d->m_startOffset, x, y))
02253         d->m_view->setContentsPos(x-50, y-50);
02254   }
02255 
02256   // Now look for end node
02257   it = prev; // no need to start from beginning again
02258   while ( it != d->m_stringPortions.end() && (*it).index < index + length )
02259   {
02260     prev = it;
02261     ++it;
02262   }
02263   Q_ASSERT ( prev != d->m_stringPortions.end() );
02264 
02265   d->m_selectionEnd = (*prev).node;
02266   d->m_endOffset = index + length - (*prev).index;
02267   d->m_startBeforeEnd = true;
02268 
02269 #if 0
02270   kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
02271     d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
02272   it = d->m_stringPortions.begin();
02273   for ( ; it != d->m_stringPortions.end() ; ++it )
02274     kdDebug(6050) << "  StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
02275 #endif
02276   d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
02277                           d->m_selectionEnd.handle(), d->m_endOffset );
02278   emitSelectionChanged();
02279 }
02280 
02281 QString KHTMLPart::selectedText() const
02282 {
02283   bool hasNewLine = true;
02284   QString text;
02285   DOM::Node n = d->m_selectionStart;
02286   while(!n.isNull()) {
02287       if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
02288         QString str = n.nodeValue().string();
02289         hasNewLine = false;
02290         if(n == d->m_selectionStart && n == d->m_selectionEnd)
02291           text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
02292         else if(n == d->m_selectionStart)
02293           text = str.mid(d->m_startOffset);
02294         else if(n == d->m_selectionEnd)
02295           text += str.left(d->m_endOffset);
02296         else
02297           text += str;
02298       }
02299       else {
02300         // This is our simple HTML -> ASCII transformation:
02301         unsigned short id = n.elementId();
02302         switch(id) {
02303           case ID_BR:
02304             text += "\n";
02305             hasNewLine = true;
02306             break;
02307 
02308           case ID_TD:
02309           case ID_TH:
02310           case ID_HR:
02311           case ID_OL:
02312           case ID_UL:
02313           case ID_LI:
02314           case ID_DD:
02315           case ID_DL:
02316           case ID_DT:
02317           case ID_PRE:
02318           case ID_BLOCKQUOTE:
02319           case ID_DIV:
02320             if (!hasNewLine)
02321                text += "\n";
02322             hasNewLine = true;
02323             break;
02324           case ID_P:
02325           case ID_TR:
02326           case ID_H1:
02327           case ID_H2:
02328           case ID_H3:
02329           case ID_H4:
02330           case ID_H5:
02331           case ID_H6:
02332             if (!hasNewLine)
02333                text += "\n";
02334             text += "\n";
02335             hasNewLine = true;
02336             break;
02337         }
02338       }
02339       if(n == d->m_selectionEnd) break;
02340       DOM::Node next = n.firstChild();
02341       if(next.isNull()) next = n.nextSibling();
02342       while( next.isNull() && !n.parentNode().isNull() ) {
02343         n = n.parentNode();
02344         next = n.nextSibling();
02345         unsigned short id = n.elementId();
02346         switch(id) {
02347           case ID_TD:
02348           case ID_TH:
02349           case ID_HR:
02350           case ID_OL:
02351           case ID_UL:
02352           case ID_LI:
02353           case ID_DD:
02354           case ID_DL:
02355           case ID_DT:
02356           case ID_PRE:
02357           case ID_BLOCKQUOTE:
02358           case ID_DIV:
02359             if (!hasNewLine)
02360                text += "\n";
02361             hasNewLine = true;
02362             break;
02363           case ID_P:
02364           case ID_TR:
02365           case ID_H1:
02366           case ID_H2:
02367           case ID_H3:
02368           case ID_H4:
02369           case ID_H5:
02370           case ID_H6:
02371             if (!hasNewLine)
02372                text += "\n";
02373             text += "\n";
02374             hasNewLine = true;
02375             break;
02376         }
02377       }
02378 
02379       n = next;
02380     }
02381 
02382     if(text.isEmpty())
02383         return QString::null;
02384 
02385     int start = 0;
02386     int end = text.length();
02387 
02388     // Strip leading LFs
02389     while ((start < end) && (text[start] == '\n'))
02390        start++;
02391 
02392     // Strip excessive trailing LFs
02393     while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
02394        end--;
02395 
02396     return text.mid(start, end-start);
02397 }
02398 
02399 bool KHTMLPart::hasSelection() const
02400 {
02401   if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
02402       return false;
02403   if ( d->m_selectionStart == d->m_selectionEnd &&
02404        d->m_startOffset == d->m_endOffset )
02405       return false; // empty
02406   return true;
02407 }
02408 
02409 DOM::Range KHTMLPart::selection() const
02410 {
02411     DOM::Range r = document().createRange();DOM::Range();
02412     r.setStart( d->m_selectionStart, d->m_startOffset );
02413     r.setEnd( d->m_selectionEnd, d->m_endOffset );
02414     return r;
02415 }
02416 
02417 
02418 void KHTMLPart::setSelection( const DOM::Range &r )
02419 {
02420     d->m_selectionStart = r.startContainer();
02421     d->m_startOffset = r.startOffset();
02422     d->m_selectionEnd = r.endContainer();
02423     d->m_endOffset = r.endOffset();
02424     d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
02425                            d->m_selectionEnd.handle(),d->m_endOffset);
02426 }
02427 
02428 void KHTMLPart::slotClearSelection()
02429 {
02430     bool hadSelection = hasSelection();
02431     d->m_selectionStart = 0;
02432     d->m_startOffset = 0;
02433     d->m_selectionEnd = 0;
02434     d->m_endOffset = 0;
02435     if ( d->m_doc ) d->m_doc->clearSelection();
02436     if ( hadSelection )
02437       emitSelectionChanged();
02438 }
02439 
02440 void KHTMLPart::overURL( const QString &url, const QString &target, bool /*shiftPressed*/ )
02441 {
02442   KURL u = completeURL(url);
02443 
02444   // special case for <a href="">
02445   if ( url.isEmpty() )
02446     u.setFileName( url );
02447 
02448   emit onURL( url );
02449 
02450   if ( url.isEmpty() ) {
02451     setStatusBarText(u.htmlURL(), BarHoverText);
02452     return;
02453   }
02454 
02455   if (url.find( QString::fromLatin1( "javascript:" ),0, false ) != -1 ) {
02456     QString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
02457     jscode = KStringHandler::rsqueeze( jscode, 80 ); // truncate if too long
02458     setStatusBarText( QStyleSheet::escape( jscode ), BarHoverText );
02459     return;
02460   }
02461 
02462   KFileItem item(u, QString::null, KFileItem::Unknown);
02463   emit d->m_extension->mouseOverInfo(&item);
02464 
02465   QString com;
02466 
02467   KMimeType::Ptr typ = KMimeType::findByURL( u );
02468 
02469   if ( typ )
02470     com = typ->comment( u, false );
02471 
02472   if ( u.isMalformed() ) {
02473     setStatusBarText(u.htmlURL(), BarHoverText);
02474     return;
02475   }
02476 
02477   if ( u.isLocalFile() )
02478   {
02479     // TODO : use KIO::stat() and create a KFileItem out of its result,
02480     // to use KFileItem::statusBarText()
02481     QCString path = QFile::encodeName( u.path() );
02482 
02483     struct stat buff;
02484     bool ok = !stat( path.data(), &buff );
02485 
02486     struct stat lbuff;
02487     if (ok) ok = !lstat( path.data(), &lbuff );
02488 
02489     QString text = u.htmlURL();
02490     QString text2 = text;
02491 
02492     if (ok && S_ISLNK( lbuff.st_mode ) )
02493     {
02494       QString tmp;
02495       if ( com.isNull() )
02496         tmp = i18n( "Symbolic Link");
02497       else
02498         tmp = i18n("%1 (Link)").arg(com);
02499       char buff_two[1024];
02500       text += " -> ";
02501       int n = readlink ( path.data(), buff_two, 1022);
02502       if (n == -1)
02503       {
02504         text2 += "  ";
02505         text2 += tmp;
02506         setStatusBarText(text2, BarHoverText);
02507         return;
02508       }
02509       buff_two[n] = 0;
02510 
02511       text += buff_two;
02512       text += "  ";
02513       text += tmp;
02514     }
02515     else if ( ok && S_ISREG( buff.st_mode ) )
02516     {
02517       if (buff.st_size < 1024)
02518         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
02519       else
02520       {
02521         float d = (float) buff.st_size/1024.0;
02522         text = i18n("%1 (%2 K)").arg(text2).arg(KGlobal::locale()->formatNumber(d, 2)); // was %.2f
02523       }
02524       text += "  ";
02525       text += com;
02526     }
02527     else if ( ok && S_ISDIR( buff.st_mode ) )
02528     {
02529       text += "  ";
02530       text += com;
02531     }
02532     else
02533     {
02534       text += "  ";
02535       text += com;
02536     }
02537     setStatusBarText(text, BarHoverText);
02538   }
02539   else
02540   {
02541     QString extra;
02542     if (target == QString::fromLatin1("_blank"))
02543     {
02544       extra = i18n(" (In new window)");
02545     }
02546     else if (!target.isEmpty() &&
02547              (target != QString::fromLatin1("_top")) &&
02548              (target != QString::fromLatin1("_self")) &&
02549              (target != QString::fromLatin1("_parent")))
02550     {
02551       extra = i18n(" (In other frame)");
02552     }
02553 
02554     if (u.protocol() == QString::fromLatin1("mailto")) {
02555       QString mailtoMsg /* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
02556       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
02557       QStringList queries = QStringList::split('&', u.query().mid(1));
02558       for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
02559         if ((*it).startsWith(QString::fromLatin1("subject=")))
02560           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
02561         else if ((*it).startsWith(QString::fromLatin1("cc=")))
02562           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
02563         else if ((*it).startsWith(QString::fromLatin1("bcc=")))
02564           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
02565       mailtoMsg.replace(QRegExp("&"), QString("&amp;"));
02566       mailtoMsg.replace(QRegExp("<"), QString("&lt;"));
02567       mailtoMsg.replace(QRegExp(">"), QString("&gt;"));
02568       mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), "");
02569       setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
02570       return;
02571     }
02572    // Is this check neccessary at all? (Frerich)
02573 #if 0
02574     else if (u.protocol() == QString::fromLatin1("http")) {
02575         DOM::Node hrefNode = nodeUnderMouse().parentNode();
02576         while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
02577           hrefNode = hrefNode.parentNode();
02578 
02579         if (!hrefNode.isNull()) {
02580           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
02581           if (!hreflangNode.isNull()) {
02582             QString countryCode = hreflangNode.nodeValue().string().lower();
02583             // Map the language code to an appropriate country code.
02584             if (countryCode == QString::fromLatin1("en"))
02585               countryCode = QString::fromLatin1("gb");
02586             QString flagImg = QString::fromLatin1("<img src=%1>").arg(
02587                 locate("locale", QString::fromLatin1("l10n/")
02588                 + countryCode
02589                 + QString::fromLatin1("/flag.png")));
02590             emit setStatusBarText(flagImg + u.prettyURL() + extra);
02591           }
02592         }
02593       }
02594 #endif
02595     setStatusBarText(u.htmlURL() + extra, BarHoverText);
02596   }
02597 }
02598 
02599 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target,
02600                              KParts::URLArgs args )
02601 {
02602   bool hasTarget = false;
02603 
02604   QString target = _target;
02605   if ( target.isEmpty() && d->m_doc )
02606     target = d->m_doc->baseTarget();
02607   if ( !target.isEmpty() )
02608       hasTarget = true;
02609 
02610   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
02611   {
02612     executeScript( KURL::decode_string( url.right( url.length() - 11 ) ) );
02613     return;
02614   }
02615 
02616   KURL cURL = completeURL(url);
02617   // special case for <a href="">  (IE removes filename, mozilla doesn't)
02618   if ( url.isEmpty() )
02619     cURL.setFileName( url ); // removes filename
02620 
02621   if ( !cURL.isValid() )
02622     // ### ERROR HANDLING
02623     return;
02624 
02625   //kdDebug( 6000 ) << "urlSelected: complete URL:" << cURL.url() << " target = " << target << endl;
02626 
02627   if ( button == LeftButton && ( state & ShiftButton ) )
02628   {
02629     KIO::MetaData metaData;
02630     metaData["referrer"] = d->m_referrer;
02631     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As..." ), cURL, metaData );
02632     return;
02633   }
02634 
02635   if (!checkLinkSecurity(cURL,
02636              i18n( "<qt>The link <B>%1</B><BR>leads from this untrusted page to your local filesystem.<BR>Do you want to follow the link?" ),
02637              i18n( "Follow" )))
02638     return;
02639 
02640   args.frameName = target;
02641 
02642   if ( d->m_bHTTPRefresh )
02643   {
02644     d->m_bHTTPRefresh = false;
02645     args.metaData()["cache"] = "refresh";
02646   }
02647 
02648   args.metaData().insert("main_frame_request",
02649                          parentPart() == 0 ? "TRUE":"FALSE");
02650   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
02651   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
02652   args.metaData().insert("PropagateHttpHeader", "true");
02653   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
02654   args.metaData().insert("ssl_activate_warnings", "TRUE");
02655 
02656   if ( hasTarget )
02657   {
02658     // unknown frame names should open in a new window.
02659     khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
02660     if ( frame )
02661     {
02662       args.metaData()["referrer"] = d->m_referrer;
02663       requestObject( frame, cURL, args );
02664       return;
02665     }
02666   }
02667 
02668   if ( !d->m_bComplete && !hasTarget )
02669     closeURL();
02670 
02671   if (!d->m_referrer.isEmpty())
02672     args.metaData()["referrer"] = d->m_referrer;
02673 
02674   if ( button == MidButton && (state & ShiftButton) )
02675   {
02676     KParts::WindowArgs winArgs;
02677     winArgs.lowerWindow = true;
02678     KParts::ReadOnlyPart *newPart = 0;
02679     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
02680     return;
02681   }
02682 
02683   if ( button == LeftButton && (state & ControlButton) )
02684   {
02685     args.setNewTab(true);
02686     emit d->m_extension->createNewWindow( cURL, args );
02687     return;
02688   }
02689 
02690   view()->viewport()->unsetCursor();
02691   emit d->m_extension->openURLRequest( cURL, args );
02692 }
02693 
02694 void KHTMLPart::slotViewDocumentSource()
02695 {
02696   KURL url(m_url);
02697   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isValid(d->m_cacheId))
02698   {
02699      KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
02700      if (sourceFile.status() == 0)
02701      {
02702         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
02703         url = KURL();
02704         url.setPath(sourceFile.name());
02705      }
02706   }
02707 
02708   //  emit d->m_extension->openURLRequest( m_url, KParts::URLArgs( false, 0, 0, QString::fromLatin1( "text/plain" ) ) );
02709   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
02710 }
02711 
02712 void KHTMLPart::slotViewPageInfo()
02713 {
02714   KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, WDestructiveClose);
02715 
02716   if (d->m_doc)
02717      dlg->_title->setText(d->m_doc->title().string());
02718 
02719   // If it's a frame, set the caption to "Frame Information"
02720   if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
02721      dlg->setCaption(i18n("Frame Information"));
02722   }
02723 
02724   QString editStr = QString::null;
02725 
02726   if (!d->m_pageServices.isEmpty())
02727     editStr = i18n("   <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);
02728 
02729   dlg->_url->setText(QString("<a href=\"%1\">%2</a>%3").arg(url().url()).arg(url().prettyURL()).arg(editStr));
02730   dlg->_lastModified->setText(lastModified());
02731 
02732   /* populate the list view now */
02733   QStringList headers = QStringList::split("\n", d->m_httpHeaders);
02734 
02735   for (QStringList::Iterator it = headers.begin(); it != headers.end(); ++it) {
02736     QStringList header = QStringList::split(QRegExp(":[ ]+"), *it);
02737     if (header.count() != 2)
02738        continue;
02739     new QListViewItem(dlg->_headers, header[0], header[1]);
02740   }
02741 
02742   dlg->show();
02743   /* put no code here */
02744 }
02745 
02746 
02747 void KHTMLPart::slotViewFrameSource()
02748 {
02749   KParts::ReadOnlyPart *frame = currentFrame();
02750   if ( !frame )
02751     return;
02752 
02753   KURL url = frame->url();
02754   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
02755   {
02756        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
02757 
02758        if (KHTMLPageCache::self()->isValid(cacheId))
02759        {
02760            KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
02761            if (sourceFile.status() == 0)
02762            {
02763                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
02764                url = KURL();
02765                url.setPath(sourceFile.name());
02766            }
02767      }
02768   }
02769 
02770   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
02771 }
02772 
02773 KURL KHTMLPart::backgroundURL() const
02774 {
02775   // ### what about XML documents? get from CSS?
02776   if (!d->m_doc || !d->m_doc->isHTMLDocument())
02777     return KURL();
02778 
02779   QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
02780 
02781   return KURL( m_url, relURL );
02782 }
02783 
02784 void KHTMLPart::slotSaveBackground()
02785 {
02786   KIO::MetaData metaData;
02787   metaData["referrer"] = d->m_referrer;
02788   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save background image as"), backgroundURL(), metaData );
02789 }
02790 
02791 void KHTMLPart::slotSaveDocument()
02792 {
02793   KURL srcURL( m_url );
02794 
02795   if ( srcURL.fileName(false).isEmpty() )
02796     srcURL.setFileName( "index.html" );
02797 
02798   KIO::MetaData metaData;
02799   // Referre unknown?
02800   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files"), d->m_cacheId );
02801 }
02802 
02803 void KHTMLPart::slotSecurity()
02804 {
02805 //   kdDebug( 6050 ) << "Meta Data:" << endl
02806 //                   << d->m_ssl_peer_cert_subject
02807 //                   << endl
02808 //                   << d->m_ssl_peer_cert_issuer
02809 //                   << endl
02810 //                   << d->m_ssl_cipher
02811 //                   << endl
02812 //                   << d->m_ssl_cipher_desc
02813 //                   << endl
02814 //                   << d->m_ssl_cipher_version
02815 //                   << endl
02816 //                   << d->m_ssl_good_from
02817 //                   << endl
02818 //                   << d->m_ssl_good_until
02819 //                   << endl
02820 //                   << d->m_ssl_cert_state
02821 //                   << endl;
02822 
02823   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
02824 
02825   if (d->m_bSecurityInQuestion)
02826       kid->setSecurityInQuestion(true);
02827 
02828   if (d->m_ssl_in_use) {
02829     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
02830     if (x) {
02831        // Set the chain back onto the certificate
02832        QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
02833        QPtrList<KSSLCertificate> ncl;
02834 
02835        ncl.setAutoDelete(true);
02836        for (QStringList::Iterator it = cl.begin(); it != cl.end(); ++it) {
02837           KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit());
02838           if (y) ncl.append(y);
02839        }
02840 
02841        if (ncl.count() > 0)
02842           x->chain().setChain(ncl);
02843 
02844        kid->setup(x,
02845                   d->m_ssl_peer_ip,
02846                   m_url.url(),
02847                   d->m_ssl_cipher,
02848                   d->m_ssl_cipher_desc,
02849                   d->m_ssl_cipher_version,
02850                   d->m_ssl_cipher_used_bits.toInt(),
02851                   d->m_ssl_cipher_bits.toInt(),
02852                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
02853                   );
02854         kid->exec();
02855         delete x;
02856      } else kid->exec();
02857   } else kid->exec();
02858 }
02859 
02860 void KHTMLPart::slotSaveFrame()
02861 {
02862     if ( !d->m_activeFrame )
02863         return; // should never be the case, but one never knows :-)
02864 
02865     KURL srcURL( static_cast<KParts::ReadOnlyPart *>( d->m_activeFrame )->url() );
02866 
02867     if ( srcURL.fileName(false).isEmpty() )
02868         srcURL.setFileName( "index.html" );
02869 
02870     KIO::MetaData metaData;
02871     // Referrer unknown?
02872     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files") );
02873 }
02874 
02875 void KHTMLPart::slotSetEncoding()
02876 {
02877     // first Item is always auto
02878     if(d->m_paSetEncoding->currentItem() == 0)
02879         setEncoding(QString::null, false);
02880     else {
02881         // strip of the language to get the raw encoding again.
02882         QString enc = KGlobal::charsets()->encodingForName(d->m_paSetEncoding->currentText());
02883         setEncoding(enc, true);
02884     }
02885 }
02886 
02887 void KHTMLPart::slotUseStylesheet()
02888 {
02889   if (d->m_doc && d->m_paUseStylesheet->currentText() != d->m_sheetUsed) {
02890     d->m_sheetUsed = d->m_paUseStylesheet->currentText();
02891     d->m_doc->updateStyleSelector();
02892   }
02893 }
02894 
02895 void KHTMLPart::updateActions()
02896 {
02897   bool frames = false;
02898 
02899   QValueList<khtml::ChildFrame>::ConstIterator it = d->m_frames.begin();
02900   QValueList<khtml::ChildFrame>::ConstIterator end = d->m_frames.end();
02901   for (; it != end; ++it )
02902       if ( (*it).m_type == khtml::ChildFrame::Frame )
02903       {
02904           frames = true;
02905           break;
02906       }
02907 
02908   d->m_paViewFrame->setEnabled( frames );
02909   d->m_paSaveFrame->setEnabled( frames );
02910 
02911   if ( frames )
02912     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
02913   else
02914     d->m_paFind->setText( i18n( "&Find..." ) );
02915 
02916   KParts::Part *frame = 0;
02917 
02918   if ( frames )
02919     frame = currentFrame();
02920 
02921   bool enableFindAndSelectAll = true;
02922 
02923   if ( frame )
02924     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
02925 
02926   d->m_paFind->setEnabled( enableFindAndSelectAll );
02927   d->m_paFindNext->setEnabled( false ); // needs a 'find' first
02928   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
02929 
02930   bool enablePrintFrame = false;
02931 
02932   if ( frame )
02933   {
02934     QObject *ext = KParts::BrowserExtension::childObject( frame );
02935     if ( ext )
02936       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
02937   }
02938 
02939   d->m_paPrintFrame->setEnabled( enablePrintFrame );
02940 
02941   QString bgURL;
02942 
02943   // ### frames
02944   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
02945     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
02946 
02947   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
02948 }
02949 
02950 KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
02951     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
02952     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
02953     for(; it != end; ++it )
02954         if ((*it).m_frame == frame)
02955             return (*it).m_liveconnect;
02956     return 0L;
02957 }
02958 
02959 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
02960                               const QStringList &params, bool isIFrame )
02961 {
02962 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
02963   FrameIt it = d->m_frames.find( frameName );
02964   if ( it == d->m_frames.end() )
02965   {
02966     khtml::ChildFrame child;
02967 //    kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
02968     child.m_name = frameName;
02969     it = d->m_frames.append( child );
02970   }
02971 
02972   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
02973   (*it).m_frame = frame;
02974   (*it).m_params = params;
02975 
02976   // Support for <frame src="javascript:string">
02977   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
02978   {
02979       QVariant res = executeScript( DOM::Node(frame->element()), KURL::decode_string( url.right( url.length() - 11) ) );
02980       KURL myurl;
02981       myurl.setProtocol("javascript");
02982       if ( res.type() == QVariant::String )
02983     myurl.setPath(res.asString());
02984       return processObjectRequest(&(*it), myurl, QString("text/html") );
02985   }
02986   KURL u = url.isEmpty() ? KURL() : completeURL( url );
02987   return requestObject( &(*it), u );
02988 }
02989 
02990 QString KHTMLPart::requestFrameName()
02991 {
02992    return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
02993 }
02994 
02995 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
02996                                const QStringList &params )
02997 {
02998   khtml::ChildFrame child;
02999   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
03000   (*it).m_frame = frame;
03001   (*it).m_type = khtml::ChildFrame::Object;
03002   (*it).m_params = params;
03003 
03004   KParts::URLArgs args;
03005   args.serviceType = serviceType;
03006   return requestObject( &(*it), completeURL( url ), args );
03007 }
03008 
03009 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
03010 {
03011   if (!checkLinkSecurity(url))
03012     return false;
03013   if ( child->m_bPreloaded )
03014   {
03015     // kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
03016     if ( child->m_frame && child->m_part )
03017       child->m_frame->setWidget( child->m_part->widget() );
03018 
03019     child->m_bPreloaded = false;
03020     return true;
03021   }
03022 
03023   KParts::URLArgs args( _args );
03024 
03025   if ( child->m_run )
03026     child->m_run->abort();
03027 
03028   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
03029     args.serviceType = child->m_serviceType;
03030 
03031   child->m_args = args;
03032   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
03033   child->m_serviceName = QString::null;
03034   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
03035     child->m_args.metaData()["referrer"] = d->m_referrer;
03036 
03037   child->m_args.metaData().insert("PropagateHttpHeader", "true");
03038   child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
03039   child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
03040   child->m_args.metaData().insert("main_frame_request",
03041                                   parentPart() == 0 ? "TRUE":"FALSE");
03042   child->m_args.metaData().insert("ssl_was_in_use",
03043                                   d->m_ssl_in_use ? "TRUE":"FALSE");
03044   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
03045 
03046   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
03047   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
03048     args.serviceType = QString::fromLatin1( "text/html" );
03049 
03050   if ( args.serviceType.isEmpty() ) {
03051     child->m_run = new KHTMLRun( this, child, url, child->m_args,
03052                                  child->m_type != khtml::ChildFrame::Frame );
03053     return false;
03054   } else {
03055     return processObjectRequest( child, url, args.serviceType );
03056   }
03057 }
03058 
03059 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
03060 {
03061   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
03062 
03063   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
03064   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
03065   // though -> the reference becomes invalid -> crash is likely
03066   KURL url( _url );
03067 
03068   // khtmlrun called us this way to indicate a loading error
03069   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
03070   {
03071       checkEmitLoadEvent();
03072       child->m_bCompleted = true;
03073       return true;
03074   }
03075 
03076   if (child->m_bNotify)
03077   {
03078       child->m_bNotify = false;
03079       if ( !child->m_args.lockHistory() )
03080           emit d->m_extension->openURLNotify();
03081   }
03082 
03083   if ( child->m_serviceType != mimetype )
03084   {
03085     QStringList dummy; // the list of servicetypes handled by the part is now unused.
03086     KParts::ReadOnlyPart *part = createPart( d->m_view->viewport(), child->m_name.ascii(), this, child->m_name.ascii(), mimetype, child->m_serviceName, dummy, child->m_params );
03087 
03088     if ( !part )
03089     {
03090         if ( child->m_frame )
03091           if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
03092             return true; // we succeeded after all (a fallback was used)
03093 
03094         checkEmitLoadEvent();
03095         return false;
03096     }
03097 
03098     //CRITICAL STUFF
03099     if ( child->m_part )
03100     {
03101       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
03102       delete (KParts::ReadOnlyPart *)child->m_part;
03103     }
03104 
03105     child->m_serviceType = mimetype;
03106     if ( child->m_frame )
03107       child->m_frame->setWidget( part->widget() );
03108 
03109     if ( child->m_type != khtml::ChildFrame::Object )
03110       partManager()->addPart( part, false );
03111 //  else
03112 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
03113 
03114     child->m_part = part;
03115     assert( ((void*) child->m_part) != 0);
03116 
03117     if ( child->m_type != khtml::ChildFrame::Object )
03118     {
03119       connect( part, SIGNAL( started( KIO::Job *) ),
03120                this, SLOT( slotChildStarted( KIO::Job *) ) );
03121       connect( part, SIGNAL( completed() ),
03122                this, SLOT( slotChildCompleted() ) );
03123       connect( part, SIGNAL( completed(bool) ),
03124                this, SLOT( slotChildCompleted(bool) ) );
03125       connect( part, SIGNAL( setStatusBarText( const QString & ) ),
03126                this, SIGNAL( setStatusBarText( const QString & ) ) );
03127       if ( part->inherits( "KHTMLPart" ) )
03128       {
03129           connect( this, SIGNAL( completed() ),
03130                    part, SLOT( slotParentCompleted() ) );
03131           connect( this, SIGNAL( completed(bool) ),
03132                    part, SLOT( slotParentCompleted() ) );
03133           // As soon as the child's document is created, we need to set its domain
03134           // (but we do so only once, so it can't be simply done in the child)
03135           connect( part, SIGNAL( docCreated() ),
03136                    this, SLOT( slotChildDocCreated() ) );
03137       }
03138     }
03139 
03140     child->m_extension = KParts::BrowserExtension::childObject( part );
03141 
03142     if ( child->m_extension )
03143     {
03144       connect( child->m_extension, SIGNAL( openURLNotify() ),
03145                d->m_extension, SIGNAL( openURLNotify() ) );
03146 
03147       connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
03148                this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
03149 
03150       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
03151                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
03152       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
03153                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
03154 
03155       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
03156                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
03157       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
03158                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
03159       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
03160                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
03161       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
03162                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
03163 
03164       connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
03165                d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
03166 
03167       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
03168     }
03169     child->m_liveconnect = KParts::LiveConnectExtension::childObject( part );
03170   }
03171 
03172   checkEmitLoadEvent();
03173   // Some JS code in the load event may have destroyed the part
03174   // In that case, abort
03175   if ( !child->m_part )
03176     return false;
03177 
03178   if ( child->m_bPreloaded )
03179   {
03180     if ( child->m_frame && child->m_part )
03181       child->m_frame->setWidget( child->m_part->widget() );
03182 
03183     child->m_bPreloaded = false;
03184     return true;
03185   }
03186 
03187   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
03188 
03189   // make sure the part has a way to find out about the mimetype.
03190   // we actually set it in child->m_args in requestObject already,
03191   // but it's useless if we had to use a KHTMLRun instance, as the
03192   // point the run object is to find out exactly the mimetype.
03193   child->m_args.serviceType = mimetype;
03194 
03195   child->m_bCompleted = false;
03196   if ( child->m_extension )
03197     child->m_extension->setURLArgs( child->m_args );
03198 
03199   if(url.protocol() == "javascript" || url.url() == "about:blank") {
03200       if (!child->m_part->inherits("KHTMLPart"))
03201           return false;
03202 
03203       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
03204 
03205       p->begin();
03206       if (d->m_doc && p->d->m_doc)
03207         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
03208       if (!url.url().startsWith("about:")) {
03209         p->write(url.path());
03210       } else {
03211     p->m_url = url;
03212         // we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
03213         p->write("<HTML><BODY></BODY></HTML>");
03214       }
03215       p->end();
03216       return true;
03217   }
03218   else if ( !url.isEmpty() )
03219   {
03220       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
03221       return child->m_part->openURL( url );
03222   }
03223   else
03224       return true;
03225 }
03226 
03227 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
03228                                              QObject *parent, const char *name, const QString &mimetype,
03229                                              QString &serviceName, QStringList &serviceTypes,
03230                                              const QStringList &params )
03231 {
03232   QString constr;
03233   if ( !serviceName.isEmpty() )
03234     constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
03235 
03236   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
03237 
03238   if ( offers.isEmpty() )
03239     return 0L;
03240 
03241   KService::Ptr service = *offers.begin();
03242 
03243   KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
03244 
03245   if ( !factory )
03246     return 0L;
03247 
03248   KParts::ReadOnlyPart *res = 0L;
03249 
03250   const char *className = "KParts::ReadOnlyPart";
03251   if ( service->serviceTypes().contains( "Browser/View" ) )
03252     className = "Browser/View";
03253 
03254   if ( factory->inherits( "KParts::Factory" ) )
03255     res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
03256   else
03257   res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
03258 
03259   if ( !res )
03260     return res;
03261 
03262   serviceTypes = service->serviceTypes();
03263   serviceName = service->name();
03264 
03265   return res;
03266 }
03267 
03268 KParts::PartManager *KHTMLPart::partManager()
03269 {
03270   if ( !d->m_manager )
03271   {
03272     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
03273     d->m_manager->setAllowNestedParts( true );
03274     connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
03275              this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
03276     connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
03277              this, SLOT( slotPartRemoved( KParts::Part * ) ) );
03278   }
03279 
03280   return d->m_manager;
03281 }
03282 
03283 void KHTMLPart::submitFormAgain()
03284 {
03285   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
03286     KHTMLPart::submitForm( d->m_submitForm->submitAction, d->m_submitForm->submitUrl, d->m_submitForm->submitFormData, d->m_submitForm->target, d->m_submitForm->submitContentType, d->m_submitForm->submitBoundary );
03287 
03288   delete d->m_submitForm;
03289   d->m_submitForm = 0;
03290   disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
03291 }
03292 
03293 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
03294 {
03295   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
03296   KURL u = completeURL( url );
03297 
03298   if ( !u.isValid() )
03299   {
03300     // ### ERROR HANDLING!
03301     return;
03302   }
03303 
03304   // Form security checks
03305   //
03306   /*
03307    * If these form security checks are still in this place in a month or two
03308    * I'm going to simply delete them.
03309    */
03310 
03311   /* This is separate for a reason.  It has to be _before_ all script, etc,
03312    * AND I don't want to break anything that uses checkLinkSecurity() in
03313    * other places.
03314    */
03315 
03316   if (!d->m_submitForm) {
03317     if (u.protocol() != "https" && u.protocol() != "mailto") {
03318       if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
03319         int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
03320                                                                "\nA third party may be able to intercept and view this information."
03321                                                                "\nAre you sure you wish to continue?"),
03322                                                     i18n("SSL"));
03323         if (rc == KMessageBox::Cancel)
03324           return;
03325       } else {                  // Going from nonSSL -> nonSSL
03326         KSSLSettings kss(true);
03327         if (kss.warnOnUnencrypted()) {
03328           int rc = KMessageBox::warningContinueCancel(NULL,
03329                                                       i18n("Warning: Your data is about to be transmitted across the network unencrypted."
03330                                                            "\nAre you sure you wish to continue?"),
03331                                                       i18n("KDE"),
03332                                                       QString::null,
03333                                                       "WarnOnUnencryptedForm");
03334           // Move this setting into KSSL instead
03335           KConfig *config = kapp->config();
03336           QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
03337           KConfigGroupSaver saver( config, grpNotifMsgs );
03338 
03339           if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
03340             config->deleteEntry("WarnOnUnencryptedForm");
03341             config->sync();
03342             kss.setWarnOnUnencrypted(false);
03343             kss.save();
03344           }
03345           if (rc == KMessageBox::Cancel)
03346             return;
03347         }
03348       }
03349     }
03350 
03351     if (u.protocol() == "mailto") {
03352       int rc = KMessageBox::warningContinueCancel(NULL,
03353                                                   i18n("This site is attempting to submit form data via email.\n"
03354                                                        "Do you want to continue?"),
03355                                                   i18n("KDE"),
03356                                                   QString::null,
03357                                                   "WarnTriedEmailSubmit");
03358 
03359       if (rc == KMessageBox::Cancel) {
03360         return;
03361       }
03362     }
03363   }
03364 
03365   // End form security checks
03366   //
03367 
03368   QString urlstring = u.url();
03369 
03370   if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
03371     urlstring = KURL::decode_string(urlstring);
03372     executeScript( urlstring.right( urlstring.length() - 11) );
03373     return;
03374   }
03375 
03376   if (!checkLinkSecurity(u,
03377              i18n( "<qt>The form will be submitted to <BR><B>%1</B><BR>on your local filesystem.<BR>Do you want to submit the form?" ),
03378              i18n( "Submit" )))
03379     return;
03380 
03381   KParts::URLArgs args;
03382 
03383   if (!d->m_referrer.isEmpty())
03384      args.metaData()["referrer"] = d->m_referrer;
03385 
03386   args.metaData().insert("PropagateHttpHeader", "true");
03387   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
03388   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
03389   args.metaData().insert("main_frame_request",
03390                          parentPart() == 0 ? "TRUE":"FALSE");
03391   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
03392   args.metaData().insert("ssl_activate_warnings", "TRUE");
03393   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
03394 
03395   // Handle mailto: forms
03396   if (u.protocol() == "mailto") {
03397       // 1)  Check for attach= and strip it
03398       QString q = u.query().mid(1);
03399       QStringList nvps = QStringList::split("&", q);
03400       bool triedToAttach = false;
03401 
03402       for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
03403          QStringList pair = QStringList::split("=", *nvp);
03404          if (pair.count() >= 2) {
03405             if (pair.first().lower() == "attach") {
03406                nvp = nvps.remove(nvp);
03407                triedToAttach = true;
03408             }
03409          }
03410       }
03411 
03412       if (triedToAttach)
03413          KMessageBox::information(NULL, i18n("This site attempted to attach a file from your computer in the form submission. The attachment was removed for your protection."), i18n("KDE"), "WarnTriedAttach");
03414 
03415       // 2)  Append body=
03416       QString bodyEnc;
03417       if (contentType.lower() == "multipart/form-data") {
03418          // FIXME: is this correct?  I suspect not
03419          bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
03420                                                            formData.size()));
03421       } else if (contentType.lower() == "text/plain") {
03422          // Convention seems to be to decode, and s/&/\n/
03423          QString tmpbody = QString::fromLatin1(formData.data(),
03424                                                formData.size());
03425          tmpbody.replace(QRegExp("[&]"), "\n");
03426          tmpbody.replace(QRegExp("[+]"), " ");
03427          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
03428          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
03429       } else {
03430          bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
03431                                                            formData.size()));
03432       }
03433 
03434       nvps.append(QString("body=%1").arg(bodyEnc));
03435       q = nvps.join("&");
03436       u.setQuery(q);
03437   }
03438 
03439   if ( strcmp( action, "get" ) == 0 ) {
03440     if (u.protocol() != "mailto")
03441        u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
03442     args.setDoPost( false );
03443   }
03444   else {
03445     args.postData = formData;
03446     args.setDoPost( true );
03447 
03448     // construct some user headers if necessary
03449     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
03450       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
03451     else // contentType must be "multipart/form-data"
03452       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
03453   }
03454 
03455   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
03456     if( d->m_submitForm ) {
03457       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
03458       return;
03459     }
03460     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
03461     d->m_submitForm->submitAction = action;
03462     d->m_submitForm->submitUrl = url;
03463     d->m_submitForm->submitFormData = formData;
03464     d->m_submitForm->target = _target;
03465     d->m_submitForm->submitContentType = contentType;
03466     d->m_submitForm->submitBoundary = boundary;
03467     connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
03468   }
03469   else
03470   {
03471     emit d->m_extension->openURLRequest( u, args );
03472   }
03473 }
03474 
03475 void KHTMLPart::popupMenu( const QString &linkUrl )
03476 {
03477   KURL popupURL;
03478   KURL linkKURL;
03479   if ( linkUrl.isEmpty() ) // click on background
03480     popupURL = this->url();
03481   else {               // click on link
03482     popupURL = completeURL( linkUrl );
03483     linkKURL = popupURL;
03484   }
03485 
03486   KXMLGUIClient *client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
03487 
03488   emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL,
03489                                   QString::fromLatin1( "text/html" ), S_IFREG /*always a file*/ );
03490 
03491   delete client;
03492 
03493   emit popupMenu(linkUrl, QCursor::pos());
03494 }
03495 
03496 void KHTMLPart::slotParentCompleted()
03497 {
03498   if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
03499   {
03500     // kdDebug(6050) << this << ": Child redirection -> " << d->m_redirectURL << endl;
03501     d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
03502   }
03503 }
03504 
03505 void KHTMLPart::slotChildStarted( KIO::Job *job )
03506 {
03507   khtml::ChildFrame *child = frame( sender() );
03508 
03509   assert( child );
03510 
03511   child->m_bCompleted = false;
03512 
03513   if ( d->m_bComplete )
03514   {
03515 #if 0
03516     // WABA: Looks like this belongs somewhere else
03517     if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
03518     {
03519       emit d->m_extension->openURLNotify();
03520     }
03521 #endif
03522     d->m_bComplete = false;
03523     emit started( job );
03524   }
03525 }
03526 
03527 void KHTMLPart::slotChildCompleted()
03528 {
03529   slotChildCompleted( false );
03530 }
03531 
03532 void KHTMLPart::slotChildCompleted( bool pendingAction )
03533 {
03534   khtml::ChildFrame *child = frame( sender() );
03535 
03536   assert( child );
03537 
03538   child->m_bCompleted = true;
03539   child->m_bPendingRedirection = pendingAction;
03540   child->m_args = KParts::URLArgs();
03541 
03542   checkCompleted();
03543 }
03544 
03545 void KHTMLPart::slotChildDocCreated()
03546 {
03547   const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
03548   // Set domain to the frameset's domain
03549   // This must only be done when loading the frameset initially (#22039),
03550   // not when following a link in a frame (#44162).
03551   if ( d->m_doc && d->m_doc->isHTMLDocument() )
03552   {
03553     if ( sender()->inherits("KHTMLPart") )
03554     {
03555       DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
03556       if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
03557         //kdDebug(6050) << "KHTMLPart::slotChildDocCreated: url: " << htmlFrame->m_url.url() << endl;
03558         static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
03559     }
03560   }
03561   // So it only happens once
03562   disconnect( htmlFrame, SIGNAL( docCreated() ), this, SLOT( slotChildDocCreated() ) );
03563 }
03564 
03565 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
03566 {
03567   khtml::ChildFrame *child = frame( sender()->parent() );
03568   KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
03569 
03570   // TODO: handle child target correctly! currently the script are always executed fur the parent
03571   QString urlStr = url.url();
03572   if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
03573       QString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
03574       executeScript( script );
03575       return;
03576   }
03577 
03578   QString frameName = args.frameName.lower();
03579   if ( !frameName.isEmpty() )
03580   {
03581     if ( frameName == QString::fromLatin1( "_top" ) )
03582     {
03583       emit d->m_extension->openURLRequest( url, args );
03584       return;
03585     }
03586     else if ( frameName == QString::fromLatin1( "_blank" ) )
03587     {
03588       emit d->m_extension->createNewWindow( url, args );
03589       return;
03590     }
03591     else if ( frameName == QString::fromLatin1( "_parent" ) )
03592     {
03593       KParts::URLArgs newArgs( args );
03594       newArgs.frameName = QString::null;
03595 
03596       emit d->m_extension->openURLRequest( url, newArgs );
03597       return;
03598     }
03599     else if ( frameName != QString::fromLatin1( "_self" ) )
03600     {
03601       khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
03602 
03603       if ( !_frame )
03604       {
03605         emit d->m_extension->openURLRequest( url, args );
03606         return;
03607       }
03608 
03609       child = _frame;
03610     }
03611   }
03612 
03613   if ( child ) {
03614       // Inform someone that we are about to show something else.
03615       child->m_bNotify = true;
03616       requestObject( child, url, args );
03617   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
03618   {
03619       KParts::URLArgs newArgs( args );
03620       newArgs.frameName = QString::null;
03621       emit d->m_extension->openURLRequest( url, newArgs );
03622   }
03623 }
03624 
03625 khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
03626 {
03627     assert( obj->inherits( "KParts::ReadOnlyPart" ) );
03628     const KParts::ReadOnlyPart *part = static_cast<const KParts::ReadOnlyPart *>( obj );
03629 
03630     FrameIt it = d->m_frames.begin();
03631     FrameIt end = d->m_frames.end();
03632     for (; it != end; ++it )
03633       if ( (KParts::ReadOnlyPart *)(*it).m_part == part )
03634         return &(*it);
03635 
03636     return 0L;
03637 }
03638 
03639 //#define DEBUG_FINDFRAME
03640 
03641 bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
03642 {
03643   if (callingHtmlPart == this)
03644     return true; // trivial
03645 
03646   if (htmlDocument().isNull()) {
03647 #ifdef DEBUG_FINDFRAME
03648     kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url.prettyURL() << endl;
03649 #endif
03650     return false; // we are empty?
03651   }
03652 
03653   // now compare the domains
03654   if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
03655       !htmlDocument().isNull())  {
03656     DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
03657     DOM::DOMString destDomain = htmlDocument().domain();
03658 
03659 #ifdef DEBUG_FINDFRAME
03660     kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
03661 #endif
03662 
03663     if (actDomain == destDomain)
03664       return true;
03665   }
03666 #ifdef DEBUG_FINDFRAME
03667   else
03668   {
03669     kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
03670   }
03671 #endif
03672   return false;
03673 }
03674 
03675 KHTMLPart *
03676 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
03677 {
03678 #ifdef DEBUG_FINDFRAME
03679   kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url.prettyURL() << " findFrameParent( " << f << " )" << endl;
03680 #endif
03681   // Check access
03682   KHTMLPart *callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
03683   
03684   if (!checkFrameAccess(callingHtmlPart))
03685      return 0;
03686 
03687   FrameIt it = d->m_frames.find( f );
03688   FrameIt end = d->m_frames.end();
03689   if ( it != end )
03690   {
03691 #ifdef DEBUG_FINDFRAME
03692      kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
03693 #endif
03694      if (childFrame)
03695         *childFrame = &(*it);
03696      return this;
03697   }
03698      
03699   it = d->m_frames.begin();
03700   for (; it != end; ++it )
03701   {
03702     KParts::ReadOnlyPart *p = (*it).m_part;
03703     if ( p && p->inherits( "KHTMLPart" ))
03704     {
03705       KHTMLPart *frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
03706       if (frameParent)
03707          return frameParent;
03708     }
03709   }
03710   return 0;
03711 }
03712 
03713 
03714 KHTMLPart *KHTMLPart::findFrame( const QString &f )
03715 {
03716   khtml::ChildFrame *childFrame;
03717   KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
03718   if (parentFrame)
03719   {
03720      KParts::ReadOnlyPart *p = childFrame->m_part;
03721      if ( p && p->inherits( "KHTMLPart" ))
03722         return static_cast<KHTMLPart *>(p);
03723   }
03724   return 0;
03725 }
03726 
03727 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
03728 {
03729   KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
03730   // Find active part in our frame manager, in case we are a frameset
03731   // and keep doing that (in case of nested framesets).
03732   // Just realized we could also do this recursively, calling part->currentFrame()...
03733   while ( part && part->inherits("KHTMLPart") &&
03734           static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
03735     KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
03736     part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
03737     if ( !part ) return frameset;
03738   }
03739   return part;
03740 }
03741 
03742 bool KHTMLPart::frameExists( const QString &frameName )
03743 {
03744   ConstFrameIt it = d->m_frames.find( frameName );
03745   if ( it == d->m_frames.end() )
03746     return false;
03747 
03748   // WABA: We only return true if the child actually has a frame
03749   // set. Otherwise we might find our preloaded-selve.
03750   // This happens when we restore the frameset.
03751   return (!(*it).m_frame.isNull());
03752 }
03753 
03754 KHTMLPart *KHTMLPart::parentPart()
03755 {
03756   if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
03757     return 0L;
03758 
03759   return (KHTMLPart *)parent();
03760 }
03761 
03762 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, 
03763                                                      const KParts::URLArgs &args, bool callParent )
03764 {
03765 #ifdef DEBUG_FINDFRAME
03766   kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url.prettyURL() << endl;
03767 #endif  
03768   khtml::ChildFrame *childFrame;
03769   KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
03770   if (childPart)
03771   {
03772      if (childPart == this)
03773         return childFrame;
03774      
03775      childPart->requestObject( childFrame, url, args );
03776      return 0;
03777   }
03778 
03779   if ( parentPart() && callParent )
03780   {
03781      khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
03782 
03783      if ( res )
03784        parentPart()->requestObject( res, url, args );
03785   }
03786 
03787   return 0L;
03788 }
03789 
03790 void KHTMLPart::saveState( QDataStream &stream )
03791 {
03792   kdDebug( 6050 ) << "KHTMLPart::saveState this = " << this << " saving URL " << m_url.url() << endl;
03793 
03794   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
03795          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
03796 
03797   // save link cursor position
03798   int focusNodeNumber;
03799   if (!d->m_focusNodeRestored)
03800       focusNodeNumber = d->m_focusNodeNumber;
03801   else if (d->m_doc && d->m_doc->focusNode())
03802       focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
03803   else
03804       focusNodeNumber = -1;
03805   stream << focusNodeNumber;
03806 
03807   // Save the doc's cache id.
03808   stream << d->m_cacheId;
03809 
03810   // Save the state of the document (Most notably the state of any forms)
03811   QStringList docState;
03812   if (d->m_doc)
03813   {
03814      docState = d->m_doc->docState();
03815   }
03816   stream << d->m_encoding << d->m_sheetUsed << docState;
03817 
03818   stream << d->m_zoomFactor;
03819 
03820   stream << d->m_httpHeaders;
03821   stream << d->m_pageServices;
03822 
03823   // Save ssl data
03824   stream << d->m_ssl_in_use
03825          << d->m_ssl_peer_certificate
03826          << d->m_ssl_peer_chain
03827          << d->m_ssl_peer_ip
03828          << d->m_ssl_cipher
03829          << d->m_ssl_cipher_desc
03830          << d->m_ssl_cipher_version
03831          << d->m_ssl_cipher_used_bits
03832          << d->m_ssl_cipher_bits
03833          << d->m_ssl_cert_state
03834          << d->m_ssl_parent_ip
03835          << d->m_ssl_parent_cert;
03836 
03837 
03838   QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
03839   KURL::List frameURLLst;
03840   QValueList<QByteArray> frameStateBufferLst;
03841 
03842   ConstFrameIt it = d->m_frames.begin();
03843   ConstFrameIt end = d->m_frames.end();
03844   for (; it != end; ++it )
03845   {
03846     if ( !(*it).m_part )
03847        continue;
03848 
03849     frameNameLst << (*it).m_name;
03850     frameServiceTypeLst << (*it).m_serviceType;
03851     frameServiceNameLst << (*it).m_serviceName;
03852     frameURLLst << (*it).m_part->url();
03853 
03854     QByteArray state;
03855     QDataStream frameStream( state, IO_WriteOnly );
03856 
03857     if ( (*it).m_extension )
03858       (*it).m_extension->saveState( frameStream );
03859 
03860     frameStateBufferLst << state;
03861   }
03862 
03863   // Save frame data
03864   stream << (Q_UINT32) frameNameLst.count();
03865   stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
03866 }
03867 
03868 void KHTMLPart::restoreState( QDataStream &stream )
03869 {
03870   KURL u;
03871   Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
03872   Q_UINT32 frameCount;
03873   QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
03874   KURL::List frameURLs;
03875   QValueList<QByteArray> frameStateBuffers;
03876   QValueList<int> fSizes;
03877   QString encoding, sheetUsed;
03878   long old_cacheId = d->m_cacheId;
03879 
03880   stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
03881 
03882   d->m_view->setMarginWidth( mWidth );
03883   d->m_view->setMarginHeight( mHeight );
03884 
03885   // restore link cursor position
03886   // nth node is active. value is set in checkCompleted()
03887   stream >> d->m_focusNodeNumber;
03888   d->m_focusNodeRestored = false;
03889   kdDebug(6050)<<"new focus Node number is:"<<d->m_focusNodeNumber<<endl;
03890 
03891   stream >> d->m_cacheId;
03892 
03893   stream >> encoding >> sheetUsed >> docState;
03894 
03895   d->m_encoding = encoding;
03896   d->m_sheetUsed = sheetUsed;
03897 
03898   int zoomFactor;
03899   stream >> zoomFactor;
03900   setZoomFactor(zoomFactor);
03901 
03902   stream >> d->m_httpHeaders;
03903   stream >> d->m_pageServices;
03904 
03905   // Restore ssl data
03906   stream >> d->m_ssl_in_use
03907          >> d->m_ssl_peer_certificate
03908          >> d->m_ssl_peer_chain
03909          >> d->m_ssl_peer_ip
03910          >> d->m_ssl_cipher
03911          >> d->m_ssl_cipher_desc
03912          >> d->m_ssl_cipher_version
03913          >> d->m_ssl_cipher_used_bits
03914          >> d->m_ssl_cipher_bits
03915          >> d->m_ssl_cert_state
03916          >> d->m_ssl_parent_ip
03917          >> d->m_ssl_parent_cert;
03918 
03919   d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
03920 
03921   stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
03922          >> frameURLs >> frameStateBuffers;
03923 
03924   d->m_bComplete = false;
03925   d->m_bLoadEventEmitted = false;
03926 
03927 //   kdDebug( 6050 ) << "restoreStakte() docState.count() = " << docState.count() << endl;
03928 //   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
03929 //   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
03930 
03931   if (d->m_cacheId == old_cacheId)
03932   {
03933     // Partial restore
03934     d->m_redirectionTimer.stop();
03935 
03936     FrameIt fIt = d->m_frames.begin();
03937     FrameIt fEnd = d->m_frames.end();
03938 
03939     for (; fIt != fEnd; ++fIt )
03940         (*fIt).m_bCompleted = false;
03941 
03942     fIt = d->m_frames.begin();
03943 
03944     QStringList::ConstIterator fNameIt = frameNames.begin();
03945     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
03946     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
03947     KURL::List::ConstIterator fURLIt = frameURLs.begin();
03948     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
03949 
03950     for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
03951     {
03952       khtml::ChildFrame *child = &(*fIt);
03953 
03954 //      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;
03955 
03956       if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
03957       {
03958         child->m_bPreloaded = true;
03959         child->m_name = *fNameIt;
03960         child->m_serviceName = *fServiceNameIt;
03961         processObjectRequest( child, *fURLIt, *fServiceTypeIt );
03962       }
03963 
03964       if ( child->m_part )
03965       {
03966         child->m_bCompleted = false;
03967         if ( child->m_extension && !(*fBufferIt).isEmpty() )
03968         {
03969           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
03970           child->m_extension->restoreState( frameStream );
03971         }
03972         else
03973           child->m_part->openURL( *fURLIt );
03974       }
03975     }
03976 
03977     KParts::URLArgs args( d->m_extension->urlArgs() );
03978     args.xOffset = xOffset;
03979     args.yOffset = yOffset;
03980     args.docState = docState;
03981     d->m_extension->setURLArgs( args );
03982 
03983     d->m_view->resizeContents( wContents,  hContents);
03984     d->m_view->setContentsPos( xOffset, yOffset );
03985   }
03986   else
03987   {
03988     // Full restore.
03989     closeURL();
03990     // We must force a clear because we want to be sure to delete all
03991     // frames.
03992     d->m_bCleared = false;
03993     clear();
03994     d->m_encoding = encoding;
03995     d->m_sheetUsed = sheetUsed;
03996 
03997     QStringList::ConstIterator fNameIt = frameNames.begin();
03998     QStringList::ConstIterator fNameEnd = frameNames.end();
03999 
04000     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
04001     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
04002     KURL::List::ConstIterator fURLIt = frameURLs.begin();
04003     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
04004 
04005     for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
04006     {
04007       khtml::ChildFrame newChild;
04008       newChild.m_bPreloaded = true;
04009       newChild.m_name = *fNameIt;
04010       newChild.m_serviceName = *fServiceNameIt;
04011 
04012 //      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
04013 
04014       FrameIt childFrame = d->m_frames.append( newChild );
04015 
04016       processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
04017 
04018       (*childFrame).m_bPreloaded = true;
04019 
04020       if ( (*childFrame).m_part )
04021       {
04022         if ( (*childFrame).m_extension )
04023         if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
04024         {
04025           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
04026           (*childFrame).m_extension->restoreState( frameStream );
04027         }
04028         else
04029           (*childFrame).m_part->openURL( *fURLIt );
04030       }
04031     }
04032 
04033     KParts::URLArgs args( d->m_extension->urlArgs() );
04034     args.xOffset = xOffset;
04035     args.yOffset = yOffset;
04036     args.docState = docState;
04037     d->m_extension->setURLArgs( args );
04038     if (!KHTMLPageCache::self()->isValid(d->m_cacheId))
04039     {
04040        d->m_restored = true;
04041        openURL( u );
04042        d->m_restored = false;
04043     }
04044     else
04045     {
04046        restoreURL( u );
04047     }
04048   }
04049 
04050 }
04051 
04052 void KHTMLPart::show()
04053 {
04054   if ( d->m_view )
04055     d->m_view->show();
04056 }
04057 
04058 void KHTMLPart::hide()
04059 {
04060   if ( d->m_view )
04061     d->m_view->hide();
04062 }
04063 
04064 DOM::Node KHTMLPart::nodeUnderMouse() const
04065 {
04066     return d->m_view->nodeUnderMouse();
04067 }
04068 
04069 void KHTMLPart::emitSelectionChanged()
04070 {
04071   emit d->m_extension->enableAction( "copy", hasSelection() );
04072   emit d->m_extension->selectionInfo( selectedText() );
04073   emit selectionChanged();
04074 }
04075 
04076 int KHTMLPart::zoomFactor() const
04077 {
04078   return d->m_zoomFactor;
04079 }
04080 
04081 // ### make the list configurable ?
04082 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
04083 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
04084 static const int minZoom = 20;
04085 static const int maxZoom = 300;
04086 
04087 void KHTMLPart::slotIncZoom()
04088 {
04089   int zoomFactor = d->m_zoomFactor;
04090 
04091   if (zoomFactor < maxZoom) {
04092     // find the entry nearest to the given zoomsizes
04093     for (int i = 0; i < zoomSizeCount; ++i)
04094       if (zoomSizes[i] > zoomFactor) {
04095         zoomFactor = zoomSizes[i];
04096         break;
04097       }
04098     setZoomFactor(zoomFactor);
04099   }
04100 }
04101 
04102 void KHTMLPart::slotDecZoom()
04103 {
04104     int zoomFactor = d->m_zoomFactor;
04105     if (zoomFactor > minZoom) {
04106       // find the entry nearest to the given zoomsizes
04107       for (int i = zoomSizeCount-1; i >= 0; --i)
04108         if (zoomSizes[i] < zoomFactor) {
04109           zoomFactor = zoomSizes[i];
04110           break;
04111         }
04112       setZoomFactor(zoomFactor);
04113     }
04114 }
04115 
04116 void KHTMLPart::setZoomFactor (int percent)
04117 {
04118   if (percent < minZoom) percent = minZoom;
04119   if (percent > maxZoom) percent = maxZoom;
04120   if (d->m_zoomFactor == percent) return;
04121   d->m_zoomFactor = percent;
04122 
04123   if(d->m_doc) {
04124       QApplication::setOverrideCursor( waitCursor );
04125     if (d->m_doc->styleSelector())
04126       d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
04127     d->m_doc->recalcStyle( NodeImpl::Force );
04128     QApplication::restoreOverrideCursor();
04129   }
04130 
04131   ConstFrameIt it = d->m_frames.begin();
04132   ConstFrameIt end = d->m_frames.end();
04133   for (; it != end; ++it )
04134     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
04135       KParts::ReadOnlyPart* p = ( *it ).m_part;
04136       static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
04137     }
04138 
04139   d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
04140   d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
04141 }
04142 
04143 void KHTMLPart::slotZoomView( int delta )
04144 {
04145   if ( delta < 0 )
04146     slotIncZoom();
04147   else
04148     slotDecZoom();
04149 }
04150 
04151 void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
04152 {
04153   d->m_statusBarText[p] = text;
04154 
04155   // shift handling ?
04156   QString tobe = d->m_statusBarText[BarHoverText];
04157   if (tobe.isEmpty())
04158     tobe = d->m_statusBarText[BarOverrideText];
04159   if (tobe.isEmpty()) {
04160     tobe = d->m_statusBarText[BarDefaultText];
04161     if (!tobe.isEmpty() && d->m_jobspeed)
04162       tobe += " ";
04163     if (d->m_jobspeed)
04164       tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
04165   }
04166   tobe = "<qt>"+tobe;
04167 
04168   emit ReadOnlyPart::setStatusBarText(tobe);
04169 }
04170 
04171 
04172 void KHTMLPart::setJSStatusBarText( const QString &text )
04173 {
04174   setStatusBarText(text, BarOverrideText);
04175 }
04176 
04177 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
04178 {
04179   setStatusBarText(text, BarDefaultText);
04180 }
04181 
04182 QString KHTMLPart::jsStatusBarText() const
04183 {
04184     return d->m_statusBarText[BarOverrideText];
04185 }
04186 
04187 QString KHTMLPart::jsDefaultStatusBarText() const
04188 {
04189    return d->m_statusBarText[BarDefaultText];
04190 }
04191 
04192 QString KHTMLPart::referrer() const
04193 {
04194    return d->m_referrer;
04195 }
04196 
04197 QString KHTMLPart::lastModified() const
04198 {
04199   if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
04200     // Local file: set last-modified from the file's mtime.
04201     // Done on demand to save time when this isn't needed - but can lead
04202     // to slightly wrong results if updating the file on disk w/o reloading.
04203     QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
04204     d->m_lastModified = lastModif.toString( Qt::LocalDate );
04205   }
04206   //kdDebug(6050) << "KHTMLPart::lastModified: " << d->m_lastModified << endl;
04207   return d->m_lastModified;
04208 }
04209 
04210 void KHTMLPart::slotLoadImages()
04211 {
04212   if (d->m_doc )
04213     d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
04214 
04215   ConstFrameIt it = d->m_frames.begin();
04216   ConstFrameIt end = d->m_frames.end();
04217   for (; it != end; ++it )
04218     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
04219       KParts::ReadOnlyPart* p = ( *it ).m_part;
04220       static_cast<KHTMLPart*>( p )->slotLoadImages();
04221     }
04222 }
04223 
04224 void KHTMLPart::reparseConfiguration()
04225 {
04226   KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
04227   settings->init();
04228 
04229   setAutoloadImages( settings->autoLoadImages() );
04230   if (d->m_doc)
04231      d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
04232 
04233   d->m_bBackRightClick = settings->isBackRightClickEnabled();
04234   d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
04235   d->m_bJScriptDebugEnabled = settings->isJavaScriptDebugEnabled();
04236   d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
04237   d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
04238   delete d->m_settings;
04239   d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
04240 
04241   QApplication::setOverrideCursor( waitCursor );
04242   if(d->m_doc) d->m_doc->updateStyleSelector();
04243   QApplication::restoreOverrideCursor();
04244 }
04245 
04246 QStringList KHTMLPart::frameNames() const
04247 {
04248   QStringList res;
04249 
04250   ConstFrameIt it = d->m_frames.begin();
04251   ConstFrameIt end = d->m_frames.end();
04252   for (; it != end; ++it )
04253     if (!(*it).m_bPreloaded)
04254       res += (*it).m_name;
04255 
04256   return res;
04257 }
04258 
04259 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
04260 {
04261   QPtrList<KParts::ReadOnlyPart> res;
04262 
04263   ConstFrameIt it = d->m_frames.begin();
04264   ConstFrameIt end = d->m_frames.end();
04265   for (; it != end; ++it )
04266     if (!(*it).m_bPreloaded)
04267       res.append( (*it).m_part );
04268 
04269   return res;
04270 }
04271 
04272 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
04273 {
04274   FrameIt it = d->m_frames.find( urlArgs.frameName );
04275 
04276   if ( it == d->m_frames.end() )
04277     return false;
04278 
04279   // Inform someone that we are about to show something else.
04280   if ( !urlArgs.lockHistory() )
04281       emit d->m_extension->openURLNotify();
04282 
04283   requestObject( &(*it), url, urlArgs );
04284 
04285   return true;
04286 }
04287 
04288 void KHTMLPart::setDNDEnabled( bool b )
04289 {
04290   d->m_bDnd = b;
04291 }
04292 
04293 bool KHTMLPart::dndEnabled() const
04294 {
04295   return d->m_bDnd;
04296 }
04297 
04298 void KHTMLPart::customEvent( QCustomEvent *event )
04299 {
04300   if ( khtml::MousePressEvent::test( event ) )
04301   {
04302     khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
04303     return;
04304   }
04305 
04306   if ( khtml::MouseDoubleClickEvent::test( event ) )
04307   {
04308     khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
04309     return;
04310   }
04311 
04312   if ( khtml::MouseMoveEvent::test( event ) )
04313   {
04314     khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
04315     return;
04316   }
04317 
04318   if ( khtml::MouseReleaseEvent::test( event ) )
04319   {
04320     khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
04321     return;
04322   }
04323 
04324   if ( khtml::DrawContentsEvent::test( event ) )
04325   {
04326     khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
04327     return;
04328   }
04329 
04330   KParts::ReadOnlyPart::customEvent( event );
04331 }
04332 
04333 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
04334 {
04335   DOM::DOMString url = event->url();
04336   QMouseEvent *_mouse = event->qmouseEvent();
04337   DOM::Node innerNode = event->innerNode();
04338   d->m_mousePressNode = innerNode;
04339 
04340    d->m_dragStartPos = _mouse->pos();
04341 
04342    if ( !event->url().isNull() ) {
04343      d->m_strSelectedURL = event->url().string();
04344      d->m_strSelectedURLTarget = event->target().string();
04345    }
04346    else
04347      d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04348 
04349   if ( _mouse->button() == LeftButton ||
04350        _mouse->button() == MidButton )
04351   {
04352     d->m_bMousePressed = true;
04353 
04354 #ifndef KHTML_NO_SELECTION
04355     if ( _mouse->button() == LeftButton )
04356     {
04357       if ( !innerNode.isNull()  && innerNode.handle()->renderer()) {
04358           int offset = 0;
04359           DOM::NodeImpl* node = 0;
04360           innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
04361                                                                event->absX()-innerNode.handle()->renderer()->xPos(),
04362                                                                event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
04363 
04364           d->m_selectionStart = node;
04365           d->m_startOffset = offset;
04366           //if ( node )
04367           //  kdDebug(6005) << "KHTMLPart::khtmlMousePressEvent selectionStart=" << d->m_selectionStart.handle()->renderer()
04368           //                << " offset=" << d->m_startOffset << endl;
04369           //else
04370           //  kdDebug(6005) << "KHTML::khtmlMousePressEvent selectionStart=(nil)" << endl;
04371           d->m_selectionEnd = d->m_selectionStart;
04372           d->m_endOffset = d->m_startOffset;
04373           d->m_doc->clearSelection();
04374       }
04375       else
04376       {
04377         d->m_selectionStart = DOM::Node();
04378         d->m_selectionEnd = DOM::Node();
04379       }
04380       emitSelectionChanged();
04381       startAutoScroll();
04382     }
04383 #else
04384     d->m_dragLastPos = _mouse->globalPos();
04385 #endif
04386   }
04387 
04388   if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
04389   {
04390     d->m_bRightMousePressed = true;
04391   } else if ( _mouse->button() == RightButton )
04392   {
04393     popupMenu( d->m_strSelectedURL );
04394     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04395   }
04396 }
04397 
04398 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
04399 {
04400   QMouseEvent *_mouse = event->qmouseEvent();
04401   if ( _mouse->button() == LeftButton )
04402   {
04403     d->m_bMousePressed = true;
04404     DOM::Node innerNode = event->innerNode();
04405     // Find selectionStart again, khtmlMouseReleaseEvent lost it
04406     if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
04407       int offset = 0;
04408       DOM::NodeImpl* node = 0;
04409       innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
04410                                                            event->absX()-innerNode.handle()->renderer()->xPos(),
04411                                                            event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
04412 
04413       //kdDebug() << k_funcinfo << "checkSelectionPoint returned node=" << node << " offset=" << offset << endl;
04414 
04415       if ( node && node->renderer() )
04416       {
04417         // Extend selection to a complete word (double-click) or paragraph (triple-click)
04418         bool selectParagraph = (event->clickCount() == 3);
04419 
04420         // Extend to the left
04421         extendSelection( node, offset, d->m_selectionStart, d->m_startOffset, false, selectParagraph );
04422         // Extend to the right
04423         extendSelection( node, offset, d->m_selectionEnd, d->m_endOffset, true, selectParagraph );
04424 
04425         d->m_endOffset++; // the last char must be in
04426         //kdDebug() << d->m_selectionStart.handle() << " " << d->m_startOffset << "  -  " <<
04427         //  d->m_selectionEnd.handle() << " " << d->m_endOffset << endl;
04428 
04429         d->m_startBeforeEnd = true;
04430         emitSelectionChanged();
04431         d->m_doc
04432           ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
04433                          d->m_selectionEnd.handle(),d->m_endOffset);
04434       }
04435     }
04436   }
04437 }
04438 
04439 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectParagraph )
04440 {
04441   khtml::RenderObject* obj = node->renderer();
04442   QString str;
04443   int len = 0;
04444   if ( obj->isText() ) { // can be false e.g. when double-clicking on a disabled submit button
04445     str = static_cast<khtml::RenderText *>(obj)->data().string();
04446     len = str.length();
04447   }
04448   //kdDebug() << "extendSelection right=" << right << " offset=" << offset << " len=" << len << " Starting at obj=" << obj << endl;
04449   QChar ch;
04450   do {
04451     // Last char was ok, point to it
04452     if ( node ) {
04453       selectionNode = node;
04454       selectionOffset = offset;
04455     }
04456 
04457     // Get another char
04458     while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
04459     {
04460       obj = right ? obj->objectBelow() : obj->objectAbove();
04461       //kdDebug() << "obj=" << obj << endl;
04462       if ( obj ) {
04463         //kdDebug() << "isText=" << obj->isText() << endl;
04464         str = QString::null;
04465         if ( obj->isText() )
04466           str = static_cast<khtml::RenderText *>(obj)->data().string();
04467         else if ( obj->isBR() )
04468           str = '\n';
04469         else if ( !obj->isInline() ) {
04470           obj = 0L; // parag limit -> done
04471           break;
04472         }
04473         len = str.length();
04474         //kdDebug() << "str=" << str << " length=" << len << endl;
04475         // set offset - note that the first thing will be a ++ or -- on it.
04476         if ( right )
04477           offset = -1;
04478         else
04479           offset = len;
04480       }
04481     }
04482     if ( !obj ) // end of parag or document
04483       break;
04484     node = obj->element();
04485     if ( right )
04486     {
04487       Q_ASSERT( offset < len-1 );
04488       offset++;
04489     }
04490     else
04491     {
04492       Q_ASSERT( offset > 0 );
04493       offset--;
04494     }
04495 
04496     // Test that char
04497     ch = str[ offset ];
04498     //kdDebug() << " offset=" << offset << " ch=" << QString(ch) << endl;
04499   } while ( selectParagraph || (!ch.isSpace() && !ch.isPunct()) );
04500 }
04501 
04502 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
04503 {
04504   QMouseEvent *_mouse = event->qmouseEvent();
04505   DOM::Node innerNode = event->innerNode();
04506 
04507   if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
04508   {
04509     popupMenu( d->m_strSelectedURL );
04510     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04511     d->m_bRightMousePressed = false;
04512   }
04513 #ifndef QT_NO_DRAGANDDROP
04514   if( d->m_bMousePressed && (!d->m_strSelectedURL.isEmpty() || (!innerNode.isNull() && innerNode.elementId() == ID_IMG) ) &&
04515       ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() > KGlobalSettings::dndEventDelay() &&
04516       d->m_bDnd && d->m_mousePressNode == innerNode ) {
04517 
04518       QPixmap p;
04519       QDragObject *drag = 0;
04520       if( !d->m_strSelectedURL.isEmpty() ) {
04521           KURL u( completeURL( d->m_strSelectedURL) );
04522           KURLDrag* urlDrag = KURLDrag::newDrag( u, d->m_view->viewport() );
04523           if ( !d->m_referrer.isEmpty() )
04524             urlDrag->metaData()["referrer"] = d->m_referrer;
04525           drag = urlDrag;
04526           p = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
04527       } else {
04528           HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
04529           if( i ) {
04530             KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
04531             mdrag->addDragObject( new QImageDrag( i->currentImage(), 0L ) );
04532             KURL u( completeURL( khtml::parseURL(i->getAttribute(ATTR_SRC)).string() ) );
04533             KURLDrag* urlDrag = KURLDrag::newDrag( u, 0L );
04534             if ( !d->m_referrer.isEmpty() )
04535               urlDrag->metaData()["referrer"] = d->m_referrer;
04536             mdrag->addDragObject( urlDrag );
04537             drag = mdrag;
04538             p = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
04539           }
04540       }
04541 
04542     if ( !p.isNull() )
04543       drag->setPixmap(p);
04544 
04545     stopAutoScroll();
04546     if(drag)
04547         drag->drag();
04548 
04549     // when we finish our drag, we need to undo our mouse press
04550     d->m_bMousePressed = false;
04551     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04552     return;
04553   }
04554 #endif
04555 
04556   DOM::DOMString url = event->url();
04557   DOM::DOMString target = event->target();
04558 
04559   // Not clicked -> mouse over stuff
04560   if ( !d->m_bMousePressed )
04561   {
04562     // The mouse is over something
04563     if ( url.length() )
04564     {
04565       bool shiftPressed = ( _mouse->state() & ShiftButton );
04566 
04567       // Image map
04568       if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
04569       {
04570         HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
04571         if ( i && i->isServerMap() )
04572         {
04573           khtml::RenderObject *r = i->renderer();
04574           if(r)
04575           {
04576             int absx, absy, vx, vy;
04577             r->absolutePosition(absx, absy);
04578             view()->contentsToViewport( absx, absy, vx, vy );
04579 
04580             int x(_mouse->x() - vx), y(_mouse->y() - vy);
04581 
04582             d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
04583             d->m_overURLTarget = target.string();
04584             overURL( d->m_overURL, target.string(), shiftPressed );
04585             return;
04586           }
04587         }
04588       }
04589 
04590       // normal link
04591       if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
04592       {
04593         d->m_overURL = url.string();
04594         d->m_overURLTarget = target.string();
04595         overURL( d->m_overURL, target.string(), shiftPressed );
04596       }
04597     }
04598     else  // Not over a link...
04599     {
04600       if( !d->m_overURL.isEmpty() ) // and we were over a link  -> reset to "default statusbar text"
04601       {
04602         d->m_overURL = d->m_overURLTarget = QString::null;
04603         emit onURL( QString::null );
04604         // revert to default statusbar text
04605         setStatusBarText(QString::null, BarHoverText);
04606         emit d->m_extension->mouseOverInfo(0);
04607      }
04608     }
04609   }
04610   else {
04611 #ifndef KHTML_NO_SELECTION
04612     // selection stuff
04613     if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
04614         ( _mouse->state() == LeftButton )) {
04615       int offset;
04616       //kdDebug(6000) << "KHTMLPart::khtmlMouseMoveEvent x=" << event->x() << " y=" << event->y() << endl;
04617       DOM::NodeImpl* node=0;
04618       innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
04619                                                            event->absX()-innerNode.handle()->renderer()->xPos(),
04620                                                            event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
04621       d->m_selectionEnd = node;
04622       d->m_endOffset = offset;
04623       //kdDebug( 6000 ) << "setting end of selection to " << d->m_selectionEnd.handle() << "/" << d->m_endOffset << endl;
04624 
04625       // we have to get to know if end is before start or not...
04626       DOM::Node n = d->m_selectionStart;
04627       d->m_startBeforeEnd = false;
04628       while(!n.isNull()) {
04629         if(n == d->m_selectionEnd) {
04630           d->m_startBeforeEnd = true;
04631           break;
04632         }
04633         DOM::Node next = n.firstChild();
04634         if(next.isNull()) next = n.nextSibling();
04635         while( next.isNull() && !n.parentNode().isNull() ) {
04636           n = n.parentNode();
04637           next = n.nextSibling();
04638         }
04639         n = next;
04640         //d->m_view->viewport()->repaint(false);
04641       }
04642 
04643       if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
04644       {
04645         if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
04646           d->m_doc
04647             ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
04648                            d->m_selectionEnd.handle(),d->m_startOffset);
04649         else if (d->m_startBeforeEnd)
04650           d->m_doc
04651             ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
04652                            d->m_selectionEnd.handle(),d->m_endOffset);
04653         else
04654           d->m_doc
04655             ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
04656                            d->m_selectionStart.handle(),d->m_startOffset);
04657       }
04658 #else
04659       if ( d->m_doc && d->m_view ) {
04660         QPoint diff( _mouse->globalPos() - d->m_dragLastPos );
04661 
04662         if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
04663           d->m_view->scrollBy( -diff.x(), -diff.y() );
04664           d->m_dragLastPos = _mouse->globalPos();
04665         }
04666 #endif
04667     }
04668   }
04669 
04670 }
04671 
04672 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
04673 {
04674   DOM::Node innerNode = event->innerNode();
04675   d->m_mousePressNode = DOM::Node();
04676 
04677   if ( d->m_bMousePressed ) {
04678     setStatusBarText(QString::null, BarHoverText);
04679     stopAutoScroll();
04680   }
04681 
04682   // Used to prevent mouseMoveEvent from initiating a drag before
04683   // the mouse is pressed again.
04684   d->m_bMousePressed = false;
04685 
04686   QMouseEvent *_mouse = event->qmouseEvent();
04687   if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
04688   {
04689     d->m_bRightMousePressed = false;
04690     KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
04691     if( tmp_iface ) {
04692       tmp_iface->callMethod( "goHistory(int)", -1 );
04693     }
04694   }
04695 #ifndef QT_NO_CLIPBOARD
04696   if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull()))
04697   {
04698     QClipboard *cb = QApplication::clipboard();
04699     cb->setSelectionMode( true );
04700     QCString plain("plain");
04701     QString url = cb->text(plain).stripWhiteSpace();
04702 
04703     // Check if it's a URL
04704     KURIFilterData m_filterData;
04705     m_filterData.setData( url );
04706     if (KURIFilter::self()->filterURI(m_filterData))
04707     {
04708       int uriType = m_filterData.uriType();
04709       if ( uriType == KURIFilterData::LOCAL_FILE
04710            || uriType == KURIFilterData::LOCAL_DIR
04711            || uriType == KURIFilterData::NET_PROTOCOL )
04712       {
04713         KURL u = m_filterData.uri();
04714         QString savedReferrer = d->m_referrer;
04715         d->m_referrer = QString::null; // Disable referrer.
04716         urlSelected(u.url(), 0,0, "_top");
04717         d->m_referrer = savedReferrer; // Restore original referrer.
04718       }
04719     }
04720   }
04721 #endif
04722 
04723 #ifndef KHTML_NO_SELECTION
04724   // delete selection in case start and end position are at the same point
04725   if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
04726     d->m_selectionStart = 0;
04727     d->m_selectionEnd = 0;
04728     d->m_startOffset = 0;
04729     d->m_endOffset = 0;
04730     emitSelectionChanged();
04731   } else {
04732     // we have to get to know if end is before start or not...
04733     DOM::Node n = d->m_selectionStart;
04734     d->m_startBeforeEnd = false;
04735     if( d->m_selectionStart == d->m_selectionEnd ) {
04736       if( d->m_startOffset < d->m_endOffset )
04737         d->m_startBeforeEnd = true;
04738     } else {
04739       while(!n.isNull()) {
04740         if(n == d->m_selectionEnd) {
04741           d->m_startBeforeEnd = true;
04742           break;
04743         }
04744         DOM::Node next = n.firstChild();
04745         if(next.isNull()) next = n.nextSibling();
04746         while( next.isNull() && !n.parentNode().isNull() ) {
04747           n = n.parentNode();
04748           next = n.nextSibling();
04749         }
04750         n = next;
04751       }
04752     }
04753     if(!d->m_startBeforeEnd)
04754     {
04755       DOM::Node tmpNode = d->m_selectionStart;
04756       int tmpOffset = d->m_startOffset;
04757       d->m_selectionStart = d->m_selectionEnd;
04758       d->m_startOffset = d->m_endOffset;
04759       d->m_selectionEnd = tmpNode;
04760       d->m_endOffset = tmpOffset;
04761       d->m_startBeforeEnd = true;
04762     }
04763     // get selected text and paste to the clipboard
04764 #ifndef QT_NO_CLIPBOARD
04765     QString text = selectedText();
04766     text.replace(QRegExp(QChar(0xa0)), " ");
04767     QClipboard *cb = QApplication::clipboard();
04768     cb->setSelectionMode( true );
04769     disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
04770     cb->setText(text);
04771     connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
04772     cb->setSelectionMode( false );
04773 #endif
04774     //kdDebug( 6000 ) << "selectedText = " << text << endl;
04775     emitSelectionChanged();
04776   }
04777 #endif
04778 
04779 }
04780 
04781 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
04782 {
04783 }
04784 
04785 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
04786 {
04787   if ( event->activated() )
04788   {
04789     emitSelectionChanged();
04790     emit d->m_extension->enableAction( "print", d->m_doc != 0 );
04791 
04792     if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
04793     {
04794         QPtrList<KAction> lst;
04795         lst.append( d->m_paLoadImages );
04796         plugActionList( "loadImages", lst );
04797     }
04798   }
04799 }
04800 
04801 void KHTMLPart::slotPrintFrame()
04802 {
04803   if ( d->m_frames.count() == 0 )
04804     return;
04805 
04806   KParts::ReadOnlyPart *frame = currentFrame();
04807   if (!frame)
04808     return;
04809 
04810   KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
04811 
04812   if ( !ext )
04813     return;
04814 
04815   QMetaObject *mo = ext->metaObject();
04816 
04817   int idx = mo->findSlot( "print()", TRUE );
04818   if ( idx >= 0 ) {
04819     QUObject o[ 1 ];
04820     ext->qt_invoke( idx, o );
04821   }
04822 }
04823 
04824 void KHTMLPart::slotSelectAll()
04825 {
04826   KParts::ReadOnlyPart *part = currentFrame();
04827   if (part && part->inherits("KHTMLPart"))
04828     static_cast<KHTMLPart *>(part)->selectAll();
04829 }
04830 
04831 void KHTMLPart::startAutoScroll()
04832 {
04833    connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
04834    d->m_scrollTimer.start(100, false);
04835 }
04836 
04837 void KHTMLPart::stopAutoScroll()
04838 {
04839    disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
04840    if (d->m_scrollTimer.isActive())
04841        d->m_scrollTimer.stop();
04842 }
04843 
04844 
04845 void KHTMLPart::slotAutoScroll()
04846 {
04847     if (d->m_view)
04848       d->m_view->doAutoScroll();
04849     else
04850       stopAutoScroll(); // Safety
04851 }
04852 
04853 void KHTMLPart::selectAll()
04854 {
04855   if (!d->m_doc) return;
04856 
04857   NodeImpl *first;
04858   if (d->m_doc->isHTMLDocument())
04859     first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
04860   else
04861     first = d->m_doc;
04862   NodeImpl *next;
04863 
04864   // Look for first text/cdata node that has a renderer
04865   while ( first && !((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE) && first->renderer()) )
04866   {
04867     next = first->firstChild();
04868     if ( !next ) next = first->nextSibling();
04869     while( first && !next )
04870     {
04871       first = first->parentNode();
04872       if ( first )
04873         next = first->nextSibling();
04874     }
04875     first = next;
04876   }
04877 
04878   NodeImpl *last;
04879   if (d->m_doc->isHTMLDocument())
04880     last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
04881   else
04882     last = d->m_doc;
04883   // Look for last text/cdata node that has a renderer
04884   while ( last && !((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE) && last->renderer()) )
04885   {
04886     next = last->lastChild();
04887     if ( !next ) next = last->previousSibling();
04888     while ( last && !next )
04889     {
04890       last = last->parentNode();
04891       if ( last )
04892         next = last->previousSibling();
04893     }
04894     last = next;
04895   }
04896 
04897   if ( !first || !last )
04898     return;
04899   Q_ASSERT(first->renderer());
04900   Q_ASSERT(last->renderer());
04901   d->m_selectionStart = first;
04902   d->m_startOffset = 0;
04903   d->m_selectionEnd = last;
04904   d->m_endOffset = last->nodeValue().length();
04905   d->m_startBeforeEnd = true;
04906 
04907   d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
04908                           d->m_selectionEnd.handle(), d->m_endOffset );
04909 
04910   emitSelectionChanged();
04911 }
04912 
04913 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
04914 {
04915   // Security check on the link.
04916   // KURL u( url ); Wrong!! Relative URL could be mis-interpreted!!! (DA)
04917   QString linkProto = linkURL.protocol().lower();
04918   QString proto = m_url.protocol().lower();
04919 
04920   if ( !linkProto.isEmpty() && !proto.isEmpty() &&
04921        ( linkProto == "cgi" || linkProto == "file" ) &&
04922        proto != "file" && proto != "cgi" && proto != "man" && proto != "about")
04923   {
04924     Tokenizer *tokenizer = d->m_doc->tokenizer();
04925     if (tokenizer)
04926       tokenizer->setOnHold(true);
04927 
04928     int response = KMessageBox::Cancel;
04929     if (!message.isEmpty())
04930     {
04931         response = KMessageBox::warningContinueCancel( 0,
04932                                message.arg(linkURL.url()),
04933                                i18n( "Security Warning" ),
04934                                button);
04935     }
04936     else
04937     {
04938         KMessageBox::error( 0,
04939                 i18n( "<qt>This untrusted page contains a link<BR><B>%1</B><BR>to your local file system.").arg(linkURL.url()),
04940                 i18n( "Security Alert" ));
04941     }
04942 
04943     if (tokenizer)
04944        tokenizer->setOnHold(false);
04945     return (response==KMessageBox::Continue);
04946   }
04947   return true;
04948 }
04949 
04950 QVariant KHTMLPart::executeScript(QString filename, int baseLine, const DOM::Node &n, const QString &script)
04951 {
04952 #ifdef KJS_VERBOSE
04953   kdDebug(6070) << "executeScript: filename=" << filename << " baseLine=" << baseLine << " script=" << script << endl;
04954 #endif
04955   KJSProxy *proxy = jScript();
04956 
04957   if (!proxy || proxy->paused())
04958     return QVariant();
04959   QVariant ret = proxy->evaluate(filename,baseLine,script, n );
04960   return ret;
04961 }
04962 
04963 void KHTMLPart::slotPartRemoved( KParts::Part *part )
04964 {
04965 //    kdDebug(6050) << "KHTMLPart::slotPartRemoved " << part << endl;
04966     if ( part == d->m_activeFrame )
04967         d->m_activeFrame = 0L;
04968 }
04969 
04970 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
04971 {
04972 //    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged part=" << part << endl;
04973     if ( part == this )
04974     {
04975         kdError(6050) << "strange error! we activated ourselves" << endl;
04976         assert( false );
04977         return;
04978     }
04979 //    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged d->m_activeFrame=" << d->m_activeFrame << endl;
04980     if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
04981     {
04982         QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
04983         if (frame->frameStyle() != QFrame::NoFrame)
04984         {
04985            frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
04986            frame->repaint();
04987         }
04988     }
04989 
04990     d->m_activeFrame = part;
04991 
04992     if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
04993     {
04994         QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
04995         if (frame->frameStyle() != QFrame::NoFrame)
04996         {
04997            frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
04998            frame->repaint();
04999         }
05000         kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
05001     }
05002 
05003     updateActions();
05004 
05005     // (note: childObject returns 0 if the argument is 0)
05006     d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
05007 }
05008 
05009 void KHTMLPart::setActiveNode(const DOM::Node &node)
05010 {
05011     if (!d->m_doc || !d->m_view)
05012         return;
05013 
05014     // Set the document's active node
05015     d->m_doc->setFocusNode(node.handle());
05016 
05017     // Scroll the view if necessary to ensure that the new focus node is visible
05018     QRect rect  = node.handle()->getRect();
05019     d->m_view->ensureVisible(rect.right(), rect.bottom());
05020     d->m_view->ensureVisible(rect.left(), rect.top());
05021 }
05022 
05023 DOM::Node KHTMLPart::activeNode() const
05024 {
05025     return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
05026 }
05027 
05028 DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code )
05029 {
05030   KJSProxy *proxy = jScript();
05031 
05032   if (!proxy)
05033     return 0;
05034 
05035   return proxy->createHTMLEventHandler( m_url.url(), code );
05036 }
05037 
05038 KHTMLPart *KHTMLPart::opener()
05039 {
05040     return d->m_opener;
05041 }
05042 
05043 void KHTMLPart::setOpener(KHTMLPart *_opener)
05044 {
05045     d->m_opener = _opener;
05046 }
05047 
05048 bool KHTMLPart::openedByJS()
05049 {
05050     return d->m_openedByJS;
05051 }
05052 
05053 void KHTMLPart::setOpenedByJS(bool _openedByJS)
05054 {
05055     d->m_openedByJS = _openedByJS;
05056 }
05057 
05058 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
05059 {
05060     khtml::Cache::preloadStyleSheet(url, stylesheet);
05061 }
05062 
05063 void KHTMLPart::preloadScript(const QString &url, const QString &script)
05064 {
05065     khtml::Cache::preloadScript(url, script);
05066 }
05067 
05068 QCString KHTMLPart::dcopObjectId() const
05069 {
05070   QCString id;
05071   id.sprintf("html-widget%d", d->m_dcop_counter);
05072   return id;
05073 }
05074 
05075 long KHTMLPart::cacheId() const
05076 {
05077   return d->m_cacheId;
05078 }
05079 
05080 bool KHTMLPart::restored() const
05081 {
05082   return d->m_restored;
05083 }
05084 
05085 bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
05086 {
05087   // parentPart() should be const!
05088   KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
05089   if ( parent )
05090     return parent->pluginPageQuestionAsked(mimetype);
05091 
05092   return d->m_pluginPageQuestionAsked.contains(mimetype);
05093 }
05094 
05095 void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
05096 {
05097   if ( parentPart() )
05098     parentPart()->setPluginPageQuestionAsked(mimetype);
05099 
05100   d->m_pluginPageQuestionAsked.append(mimetype);
05101 }
05102 
05103 using namespace KParts;
05104 #include "khtml_part.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Mon Oct 24 13:07:08 2011 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001