Logo Search packages:      
Sourcecode: ia32-libs-kde version File versions

khtml_part.cpp

// -*- c-basic-offset: 2 -*-
/* This file is part of the KDE project
 *
 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
 *                     1999 Lars Knoll <knoll@kde.org>
 *                     1999 Antti Koivisto <koivisto@kde.org>
 *                     2000 Simon Hausmann <hausmann@kde.org>
 *                     2000 Stefan Schimanski <1Stein@gmx.de>
 *                     2001-2003 George Staikos <staikos@kde.org>
 *                     2001-2003 Dirk Mueller <mueller@kde.org>
 *                     2000-2005 David Faure <faure@kde.org>
 *                     2002 Apple Computer, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

//#define SPEED_DEBUG
#include "khtml_part.h"

#include "khtml_pagecache.h"

#include "dom/dom_string.h"
#include "dom/dom_element.h"
#include "dom/dom_exception.h"
#include "html/html_documentimpl.h"
#include "html/html_baseimpl.h"
#include "html/html_objectimpl.h"
#include "html/html_miscimpl.h"
#include "html/html_imageimpl.h"
#include "html/html_objectimpl.h"
#include "rendering/render_text.h"
#include "rendering/render_frames.h"
#include "rendering/render_layer.h"
#include "misc/htmlhashes.h"
#include "misc/loader.h"
#include "xml/dom2_eventsimpl.h"
#include "xml/dom2_rangeimpl.h"
#include "xml/xml_tokenizer.h"
#include "css/cssstyleselector.h"
#include "css/csshelper.h"
using namespace DOM;

#include "khtmlview.h"
#include <kparts/partmanager.h>
#include "ecma/kjs_proxy.h"
#include "ecma/kjs_window.h"
#include "khtml_settings.h"
#include "kjserrordlg.h"

#include <kjs/function.h>
#include <kjs/interpreter.h>

#include "htmlpageinfo.h"

#include <sys/types.h>
#include <assert.h>
#include <unistd.h>

#include <config.h>

#include <dcopclient.h>
#include <dcopref.h>
#include <kstandarddirs.h>
#include <kstringhandler.h>
#include <kio/job.h>
#include <kio/global.h>
#include <kio/netaccess.h>
#include <kprotocolmanager.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kcharsets.h>
#include <kmessagebox.h>
#include <kstdaction.h>
#include <kfiledialog.h>
#include <ktrader.h>
#include <kdatastream.h>
#include <ktempfile.h>
#include <kglobalsettings.h>
#include <kurldrag.h>
#include <kapplication.h>
#include <kparts/browserinterface.h>
#if !defined(QT_NO_DRAGANDDROP)
#include <kmultipledrag.h>
#endif
#include "../kutils/kfinddialog.h"
#include "../kutils/kfind.h"

#include <ksslcertchain.h>
#include <ksslinfodlg.h>

#include <kfileitem.h>
#include <kurifilter.h>
#include <kstatusbar.h>
#include <kurllabel.h>

#include <qclipboard.h>
#include <qfile.h>
#include <qtooltip.h>
#include <qmetaobject.h>
#include <private/qucomextra_p.h>

#include "khtmlpart_p.h"
#include "kpassivepopup.h"
#include "kpopupmenu.h"
#include "rendering/render_form.h"
#include <kwin.h>

#define HINT_UTF8 106

namespace khtml {
    class PartStyleSheetLoader : public CachedObjectClient
    {
    public:
        PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
        {
            m_part = part;
            m_cachedSheet = dl->requestStyleSheet(url, QString::null, "text/css",
                                                  true /* "user sheet" */);
            if (m_cachedSheet)
            m_cachedSheet->ref( this );
        }
        virtual ~PartStyleSheetLoader()
        {
            if ( m_cachedSheet ) m_cachedSheet->deref(this);
        }
        virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet, const DOM::DOMString &)
        {
          if ( m_part )
            m_part->setUserStyleSheet( sheet.string() );

            delete this;
        }
        virtual void error( int, const QString& ) {
          delete this;
        }
        QGuardedPtr<KHTMLPart> m_part;
        khtml::CachedCSSStyleSheet *m_cachedSheet;
    };
}

void khtml::ChildFrame::liveConnectEvent(const unsigned long, const QString & event, const KParts::LiveConnectExtension::ArgList & args)
{
    if (!m_part || !m_frame || !m_liveconnect)
        // hmmm
        return;

    QString script;
    script.sprintf("%s(", event.latin1());

    KParts::LiveConnectExtension::ArgList::const_iterator i = args.begin();
    const KParts::LiveConnectExtension::ArgList::const_iterator argsBegin = i;
    const KParts::LiveConnectExtension::ArgList::const_iterator argsEnd = args.end();

    for ( ; i != argsEnd; ++i) {
        if (i != argsBegin)
            script += ",";
        if ((*i).first == KParts::LiveConnectExtension::TypeString) {
            script += "\"";
            script += QString((*i).second).replace('\\', "\\\\").replace('"', "\\\"");
            script += "\"";
        } else
            script += (*i).second;
    }
    script += ")";
    kdDebug(6050) << "khtml::ChildFrame::liveConnectEvent " << script << endl;

    KHTMLPart * part = ::qt_cast<KHTMLPart *>(m_part->parent());
    if (!part)
        return;
    if (!m_jscript)
        part->framejScript(m_part);
    if (m_jscript) {
        // we have a jscript => a part in an iframe
        KJS::Completion cmp;
        m_jscript->evaluate(QString::null, 1, script, 0L, &cmp);
    } else
        part->executeScript(m_frame->element(), script);
}

KHTMLFrameList::Iterator KHTMLFrameList::find( const QString &name )
{
    Iterator it = begin();
    const Iterator e = end();

    for (; it!=e; ++it )
        if ( (*it)->m_name==name )
            break;

    return it;
}

00206 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name, GUIProfile prof )
: KParts::ReadOnlyPart( parent, name )
{
    d = 0;
    KHTMLFactory::registerPart( this );
    setInstance(  KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
    // TODO KDE4 - don't load plugins yet
    //setInstance( KHTMLFactory::instance(), false );
    init( new KHTMLView( this, parentWidget, widgetname ), prof );
}

KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
: KParts::ReadOnlyPart( parent, name )
{
    d = 0;
    KHTMLFactory::registerPart( this );
    setInstance(  KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
    // TODO KDE4 - don't load plugins yet
    //setInstance( KHTMLFactory::instance(), false );
    assert( view );
    init( view, prof );
}

void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
{
  if ( prof == DefaultGUI )
    setXMLFile( "khtml.rc" );
  else if ( prof == BrowserViewGUI )
    setXMLFile( "khtml_browser.rc" );

  d = new KHTMLPartPrivate(parent());

  d->m_view = view;
  setWidget( d->m_view );

  d->m_guiProfile = prof;
  d->m_extension = new KHTMLPartBrowserExtension( this, "KHTMLBrowserExtension" );
  d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
  d->m_statusBarExtension = new KParts::StatusBarExtension( this );
  d->m_statusBarIconLabel = 0L;
  d->m_statusBarPopupLabel = 0L;
  d->m_openableSuppressedPopups = 0;

  d->m_bSecurityInQuestion = false;
  d->m_paLoadImages = 0;
  d->m_paDebugScript = 0;
  d->m_bMousePressed = false;
  d->m_bRightMousePressed = false;
  d->m_bCleared = false;
  d->m_paViewDocument = new KAction( i18n( "View Do&cument Source" ), CTRL + Key_U, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
  d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
  d->m_paViewInfo = new KAction( i18n( "View Document Information" ), CTRL+Key_I, this, SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
  d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
  d->m_paSaveDocument = KStdAction::saveAs( this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
  if ( parentPart() )
      d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
  d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
  d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
  d->m_paSecurity->setWhatsThis( i18n( "Security Settings<p>"
                                       "Shows the certificate of the displayed page. Only "
                               "pages that have been transmitted using a secure, encrypted connection have a "
                               "certificate.<p> "
                               "Hint: If the image shows a closed lock, the page has been transmitted over a "
                               "secure connection.") );
  d->m_paDebugRenderTree = new KAction( i18n( "Print Rendering Tree to STDOUT" ), ALT + CTRL + SHIFT + Key_A, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
  d->m_paDebugDOMTree = new KAction( i18n( "Print DOM Tree to STDOUT" ), ALT + CTRL + SHIFT + Key_D, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
  d->m_paStopAnimations = new KAction( i18n( "Stop Animated Images" ), 0, this, SLOT( slotStopAnimations() ), actionCollection(), "stopAnimations" );

  d->m_paSetEncoding = new KActionMenu( i18n( "Set &Encoding" ), "charset", actionCollection(), "setEncoding" );
  d->m_paSetEncoding->setDelayed( false );

  d->m_automaticDetection = new KPopupMenu( 0L );

  d->m_automaticDetection->insertItem( i18n( "Semi-Automatic" ), 0 );
  d->m_automaticDetection->insertItem( i18n( "Arabic" ), 1 );
  d->m_automaticDetection->insertItem( i18n( "Baltic" ), 2 );
  d->m_automaticDetection->insertItem( i18n( "Central European" ), 3 );
  //d->m_automaticDetection->insertItem( i18n( "Chinese" ), 4 );
  d->m_automaticDetection->insertItem( i18n( "Greek" ), 5 );
  d->m_automaticDetection->insertItem( i18n( "Hebrew" ), 6 );
  d->m_automaticDetection->insertItem( i18n( "Japanese" ), 7 );
  //d->m_automaticDetection->insertItem( i18n( "Korean" ), 8 );
  d->m_automaticDetection->insertItem( i18n( "Russian" ), 9 );
  //d->m_automaticDetection->insertItem( i18n( "Thai" ), 10 );
  d->m_automaticDetection->insertItem( i18n( "Turkish" ), 11 );
  d->m_automaticDetection->insertItem( i18n( "Ukrainian" ), 12 );
  //d->m_automaticDetection->insertItem( i18n( "Unicode" ), 13 );
  d->m_automaticDetection->insertItem( i18n( "Western European" ), 14 );

  connect( d->m_automaticDetection, SIGNAL( activated( int ) ), this, SLOT( slotAutomaticDetectionLanguage( int ) ) );

  d->m_paSetEncoding->popupMenu()->insertItem( i18n( "Automatic Detection" ), d->m_automaticDetection, 0 );

  d->m_paSetEncoding->insert( new KActionSeparator( actionCollection() ) );


  d->m_manualDetection = new KSelectAction( i18n( "short for Manual Detection", "Manual" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "manualDetection" );
  QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
  d->m_manualDetection->setItems( encodings );
  d->m_manualDetection->setCurrentItem( -1 );
  d->m_paSetEncoding->insert( d->m_manualDetection );


  KConfig *config = KGlobal::config();
  if ( config->hasGroup( "HTML Settings" ) ) {
    config->setGroup( "HTML Settings" );
    khtml::Decoder::AutoDetectLanguage language;
    QCString name = QTextCodec::codecForLocale()->name();
    name = name.lower();

    if ( name == "cp1256" || name == "iso-8859-6" ) {
      language = khtml::Decoder::Arabic;
    }
    else if ( name == "cp1257" || name == "iso-8859-13" || name == "iso-8859-4" ) {
      language = khtml::Decoder::Baltic;
    }
    else if ( name == "cp1250" || name == "ibm852" || name == "iso-8859-2" || name == "iso-8859-3" ) {
      language = khtml::Decoder::CentralEuropean;
    }
    else if ( name == "cp1251" || name == "koi8-r" || name == "iso-8859-5" ) {
      language = khtml::Decoder::Russian;
    }
    else if ( name == "koi8-u" ) {
      language = khtml::Decoder::Ukrainian;
    }
    else if ( name == "cp1253" || name == "iso-8859-7" ) {
      language = khtml::Decoder::Greek;
    }
    else if ( name == "cp1255" || name == "iso-8859-8" || name == "iso-8859-8-i" ) {
      language = khtml::Decoder::Hebrew;
    }
    else if ( name == "jis7" || name == "eucjp" || name == "sjis"  ) {
      language = khtml::Decoder::Japanese;
    }
    else if ( name == "cp1254" || name == "iso-8859-9" ) {
      language = khtml::Decoder::Turkish;
    }
    else if ( name == "cp1252" || name == "iso-8859-1" || name == "iso-8859-15" ) {
      language = khtml::Decoder::WesternEuropean;
    }
    else
      language = khtml::Decoder::SemiautomaticDetection;

    int _id = config->readNumEntry( "AutomaticDetectionLanguage", language );
    d->m_automaticDetection->setItemChecked( _id, true );
    d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );

    d->m_autoDetectLanguage = static_cast< khtml::Decoder::AutoDetectLanguage >( _id );
  }


  d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );

  if ( prof == BrowserViewGUI ) {
      d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n(
                  "Enlarge Font" ), "viewmag+", "CTRL++;CTRL+=", this,
              SLOT( slotIncZoomFast() ), actionCollection(), "incFontSizes" );
      d->m_paIncZoomFactor->setWhatsThis( i18n( "Enlarge Font<p>"
                                                "Make the font in this window bigger. "
                            "Click and hold down the mouse button for a menu with all available font sizes." ) );
      d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n(
                  "Shrink Font" ), "viewmag-", CTRL + Key_Minus, this,
              SLOT( slotDecZoomFast() ), actionCollection(), "decFontSizes" );
      d->m_paDecZoomFactor->setWhatsThis( i18n( "Shrink Font<p>"
                                                "Make the font in this window smaller. "
                            "Click and hold down the mouse button for a menu with all available font sizes." ) );
  }

  d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
  d->m_paFind->setWhatsThis( i18n( "Find text<p>"
                           "Shows a dialog that allows you to find text on the displayed page." ) );

  d->m_paFindNext = KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection(), "findNext" );
  d->m_paFindNext->setWhatsThis( i18n( "Find next<p>"
                               "Find the next occurrence of the text that you "
                               "have found using the <b>Find Text</b> function" ) );

  d->m_paFindPrev = KStdAction::findPrev( this, SLOT( slotFindPrev() ), actionCollection(), "findPrevious" );
  d->m_paFindPrev->setWhatsThis( i18n( "Find previous<p>"
                               "Find the previous occurrence of the text that you "
                               "have found using the <b>Find Text</b> function" ) );

  d->m_paFindAheadText = new KAction( i18n("Find Text as You Type"), KShortcut( '/' ), this, SLOT( slotFindAheadText()),
      actionCollection(), "findAheadText");
  d->m_paFindAheadLinks = new KAction( i18n("Find Links as You Type"), KShortcut( '\'' ), this, SLOT( slotFindAheadLink()),
      actionCollection(), "findAheadLink");
  d->m_paFindAheadText->setEnabled( false );
  d->m_paFindAheadLinks->setEnabled( false );

  if ( parentPart() )
  {
      d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
      d->m_paFindNext->setShortcut( KShortcut() ); // avoid clashes
      d->m_paFindPrev->setShortcut( KShortcut() ); // avoid clashes
      d->m_paFindAheadText->setShortcut( KShortcut());
      d->m_paFindAheadLinks->setShortcut( KShortcut());
  }

  d->m_paPrintFrame = new KAction( i18n( "Print Frame..." ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
  d->m_paPrintFrame->setWhatsThis( i18n( "Print Frame<p>"
                               "Some pages have several frames. To print only a single frame, click "
                               "on it and then use this function." ) );

  d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
  if ( parentPart() )
      d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes

  d->m_paToggleCaretMode = new KToggleAction(i18n("Toggle Caret Mode"),
                        Key_F7, this, SLOT(slotToggleCaretMode()),
                                actionCollection(), "caretMode");
  d->m_paToggleCaretMode->setChecked(isCaretMode());
  if (parentPart())
      d->m_paToggleCaretMode->setShortcut(KShortcut()); // avoid clashes

  // set the default java(script) flags according to the current host.
  d->m_bOpenMiddleClick = d->m_settings->isOpenMiddleClickEnabled();
  d->m_bBackRightClick = d->m_settings->isBackRightClickEnabled();
  d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
  setDebugScript( d->m_settings->isJavaScriptDebugEnabled() );
  d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
  d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();

  // Set the meta-refresh flag...
  d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();

  connect( view, SIGNAL( zoomView( int ) ), SLOT( slotZoomView( int ) ) );

  connect( this, SIGNAL( completed() ),
           this, SLOT( updateActions() ) );
  connect( this, SIGNAL( completed( bool ) ),
           this, SLOT( updateActions() ) );
  connect( this, SIGNAL( started( KIO::Job * ) ),
           this, SLOT( updateActions() ) );

  d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );

  connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
           this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
  connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
           this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
  connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
           this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );

  connect ( &d->m_progressUpdateTimer, SIGNAL( timeout() ), this, SLOT( slotProgressUpdate() ) );

  findTextBegin(); //reset find variables

  connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
           this, SLOT( slotRedirect() ) );

  d->m_dcopobject = new KHTMLPartIface(this);

  // TODO KDE4 - load plugins now (see also the constructors)
  //if ( prof == BrowserViewGUI && !parentPart() )
  //        loadPlugins( partObject(), this, instance() );

  // "khtml" catalog does not exist, our translations are in kdelibs.
  // removing this catalog from KGlobal::locale() prevents problems
  // with changing the language in applications at runtime -Thomas Reitelbach
  KGlobal::locale()->removeCatalogue("khtml");
}

00468 KHTMLPart::~KHTMLPart()
{
  //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;

  KConfig *config = KGlobal::config();
  config->setGroup( "HTML Settings" );
  config->writeEntry( "AutomaticDetectionLanguage", d->m_autoDetectLanguage );

  delete d->m_automaticDetection;
  delete d->m_manualDetection;

  slotWalletClosed();
  if (!parentPart()) { // only delete it if the top khtml_part closes
    removeJSErrorExtension();
    delete d->m_statusBarPopupLabel;
  }

  d->m_find = 0; // deleted by its parent, the view.

  if ( d->m_manager )
  {
    d->m_manager->setActivePart( 0 );
    // We specify "this" as parent qobject for d->manager, so no need to delete it.
  }

  stopAutoScroll();
  d->m_redirectionTimer.stop();

  if (!d->m_bComplete)
    closeURL();

  disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
           this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
  disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
           this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
  disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
           this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );

  clear();

  if ( d->m_view )
  {
    d->m_view->hide();
    d->m_view->viewport()->hide();
    d->m_view->m_part = 0;
  }

  // Have to delete this here since we forward declare it in khtmlpart_p and
  // at least some compilers won't call the destructor in this case.
  delete d->m_jsedlg;
  d->m_jsedlg = 0;

  if (!parentPart()) // only delete d->m_frame if the top khtml_part closes
      delete d->m_frame;
  delete d; d = 0;
  KHTMLFactory::deregisterPart( this );
}

bool KHTMLPart::restoreURL( const KURL &url )
{
  kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;

  d->m_redirectionTimer.stop();

  /*
   * That's not a good idea as it will call closeURL() on all
   * child frames, preventing them from further loading. This
   * method gets called from restoreState() in case of a full frameset
   * restoral, and restoreState() calls closeURL() before restoring
   * anyway.
  kdDebug( 6050 ) << "closing old URL" << endl;
  closeURL();
  */

  d->m_bComplete = false;
  d->m_bLoadEventEmitted = false;
  d->m_workingURL = url;

  // set the java(script) flags according to the current host.
  d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
  setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
  d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
  d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());

  m_url = url;

  d->m_restoreScrollPosition = true;
  disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
  connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));

  KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));

  emit started( 0L );

  return true;
}


00566 bool KHTMLPart::openURL( const KURL &url )
{
  kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;

  d->m_redirectionTimer.stop();

  // check to see if this is an "error://" URL. This is caused when an error
  // occurs before this part was loaded (e.g. KonqRun), and is passed to
  // khtmlpart so that it can display the error.
  if ( url.protocol() == "error" && url.hasSubURL() ) {
    closeURL();

    if(  d->m_bJScriptEnabled )
      d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;

    /**
     * The format of the error url is that two variables are passed in the query:
     * error = int kio error code, errText = QString error text from kio
     * and the URL where the error happened is passed as a sub URL.
     */
    KURL::List urls = KURL::split( url );
    //kdDebug(6050) << "Handling error URL. URL count:" << urls.count() << endl;

    if ( urls.count() > 1 ) {
      KURL mainURL = urls.first();
      int error = mainURL.queryItem( "error" ).toInt();
      // error=0 isn't a valid error code, so 0 means it's missing from the URL
      if ( error == 0 ) error = KIO::ERR_UNKNOWN;
      QString errorText = mainURL.queryItem( "errText", HINT_UTF8 );
      urls.pop_front();
      d->m_workingURL = KURL::join( urls );
      //kdDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
      emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
      htmlError( error, errorText, d->m_workingURL );
      return true;
    }
  }

  if (!parentPart()) { // only do it for toplevel part
    QString host = url.isLocalFile() ? "localhost" : url.host();
    QString userAgent = KProtocolManager::userAgentForHost(host);
    if (userAgent != KProtocolManager::userAgentForHost(QString::null)) {
      if (!d->m_statusBarUALabel) {
        d->m_statusBarUALabel = new KURLLabel(d->m_statusBarExtension->statusBar());
        d->m_statusBarUALabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
        d->m_statusBarUALabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
        d->m_statusBarUALabel->setUseCursor(false);
        d->m_statusBarExtension->addStatusBarItem(d->m_statusBarUALabel, 0, false);
        d->m_statusBarUALabel->setPixmap(SmallIcon("agent", instance()));
      } else {
        QToolTip::remove(d->m_statusBarUALabel);
      }
      QToolTip::add(d->m_statusBarUALabel, i18n("The fake user-agent '%1' is in use.").arg(userAgent));
    } else if (d->m_statusBarUALabel) {
      d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarUALabel);
      delete d->m_statusBarUALabel;
      d->m_statusBarUALabel = 0L;
    }
  }

  KParts::URLArgs args( d->m_extension->urlArgs() );

  // in case
  // a) we have no frameset (don't test m_frames.count(), iframes get in there)
  // b) the url is identical with the currently displayed one (except for the htmlref!)
  // c) the url request is not a POST operation and
  // d) the caller did not request to reload the page
  // e) there was no HTTP redirection meanwhile (testcase: webmin's software/tree.cgi)
  // => we don't reload the whole document and
  // we just jump to the requested html anchor
  bool isFrameSet = false;
  if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
      HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
      isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
  }

  if ( url.hasRef() && !isFrameSet )
  {
    bool noReloadForced = !args.reload && !args.redirectedRequest() && !args.doPost();
    if (noReloadForced && urlcmp( url.url(), m_url.url(), true, true ))
    {
        kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
        m_url = url;
        emit started( 0L );

        if ( !gotoAnchor( url.encodedHtmlRef()) )
          gotoAnchor( url.htmlRef() );

        d->m_bComplete = true;
        if (d->m_doc)
        d->m_doc->setParsing(false);

        kdDebug( 6050 ) << "completed..." << endl;
        emit completed();
        return true;
    }
  }

  // Save offset of viewport when page is reloaded to be compliant
  // to every other capable browser out there.
  if (args.reload) {
    args.xOffset = d->m_view->contentsX();
    args.yOffset = d->m_view->contentsY();
    d->m_extension->setURLArgs(args);
  }

  if (!d->m_restored)
    closeURL();

  d->m_restoreScrollPosition = d->m_restored;
  disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
  connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));

  // 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
  // data arrives) (Simon)
  m_url = url;
  if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
     m_url.path().isEmpty()) {
    m_url.setPath("/");
    emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
  }
  // copy to m_workingURL after fixing m_url above
  d->m_workingURL = m_url;

  args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
  args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
  args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
  args.metaData().insert("PropagateHttpHeader", "true");
  args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
  args.metaData().insert("ssl_activate_warnings", "TRUE" );
  args.metaData().insert("cross-domain", toplevelURL().url());

  if (d->m_restored)
  {
     args.metaData().insert("referrer", d->m_pageReferrer);
     d->m_cachePolicy = KIO::CC_Cache;
  }
  else if (args.reload)
     d->m_cachePolicy = KIO::CC_Reload;
  else
     d->m_cachePolicy = KProtocolManager::cacheControl();

  if ( args.doPost() && (m_url.protocol().startsWith("http")) )
  {
      d->m_job = KIO::http_post( m_url, args.postData, false );
      d->m_job->addMetaData("content-type", args.contentType() );
  }
  else
  {
      d->m_job = KIO::get( m_url, false, false );
      d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
  }

  if (widget())
     d->m_job->setWindow(widget()->topLevelWidget());
  d->m_job->addMetaData(args.metaData());

  connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
           SLOT( slotFinished( KIO::Job* ) ) );
  connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
           SLOT( slotData( KIO::Job*, const QByteArray& ) ) );
  connect ( d->m_job, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
           SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) );
  connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL& ) ),
           SLOT( slotRedirection(KIO::Job*, const KURL&) ) );

  d->m_bComplete = false;
  d->m_bLoadEventEmitted = false;

  // delete old status bar msg's from kjs (if it _was_ activated on last URL)
  if( d->m_bJScriptEnabled )
    d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;

  // set the javascript flags according to the current url
  d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
  setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
  d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
  d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());


  connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
           this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );

  connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
           this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );

  connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
           this, SLOT( slotJobDone( KIO::Job* ) ) );

  d->m_jobspeed = 0;

  // If this was an explicit reload and the user style sheet should be used,
  // do a stat to see whether the stylesheet was changed in the meanwhile.
  if ( args.reload && !settings()->userStyleSheet().isEmpty() ) {
    KURL url( settings()->userStyleSheet() );
    KIO::StatJob *job = KIO::stat( url, false /* don't show progress */ );
    connect( job, SIGNAL( result( KIO::Job * ) ),
             this, SLOT( slotUserSheetStatDone( KIO::Job * ) ) );
  }
  emit started( 0L );

  return true;
}

00770 bool KHTMLPart::closeURL()
{
  if ( d->m_job )
  {
    KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
    d->m_job->kill();
    d->m_job = 0;
  }

  if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
    HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );

    if ( hdoc->body() && d->m_bLoadEventEmitted ) {
      hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
      if ( d->m_doc )
        d->m_doc->updateRendering();
      d->m_bLoadEventEmitted = false;
    }
  }

  d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
  d->m_bLoadEventEmitted = true; // don't want that one either
  d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy

  disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));

  KHTMLPageCache::self()->cancelFetch(this);
  if ( d->m_doc && d->m_doc->parsing() )
  {
    kdDebug( 6050 ) << " was still parsing... calling end " << endl;
    slotFinishedParsing();
    d->m_doc->setParsing(false);
  }

  if ( !d->m_workingURL.isEmpty() )
  {
    // Aborted before starting to render
    kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
    emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
  }

  d->m_workingURL = KURL();

  if ( d->m_doc && d->m_doc->docLoader() )
    khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );

  // tell all subframes to stop as well
  {
    ConstFrameIt it = d->m_frames.begin();
    const ConstFrameIt end = d->m_frames.end();
    for (; it != end; ++it )
    {
      if ( (*it)->m_run )
        (*it)->m_run->abort();
      if ( !( *it )->m_part.isNull() )
        ( *it )->m_part->closeURL();
    }
  }
  // tell all objects to stop as well
  {
    ConstFrameIt it = d->m_objects.begin();
    const ConstFrameIt end = d->m_objects.end();
    for (; it != end; ++it)
    {
      if ( !( *it )->m_part.isNull() )
        ( *it )->m_part->closeURL();
    }
  }
  // Stop any started redirections as well!! (DA)
  if ( d && d->m_redirectionTimer.isActive() )
    d->m_redirectionTimer.stop();

  // null node activated.
  emit nodeActivated(Node());

  // make sure before clear() runs, we pop out of a dialog's message loop
  if ( d->m_view )
    d->m_view->closeChildDialogs();

  return true;
}

00852 DOM::HTMLDocument KHTMLPart::htmlDocument() const
{
  if (d->m_doc && d->m_doc->isHTMLDocument())
    return static_cast<HTMLDocumentImpl*>(d->m_doc);
  else
    return static_cast<HTMLDocumentImpl*>(0);
}

00860 DOM::Document KHTMLPart::document() const
{
    return d->m_doc;
}

00865 QString KHTMLPart::documentSource() const
{
  QString sourceStr;
  if ( !( m_url.isLocalFile() ) && KHTMLPageCache::self()->isComplete( d->m_cacheId ) )
  {
     QByteArray sourceArray;
     QDataStream dataStream( sourceArray, IO_WriteOnly );
     KHTMLPageCache::self()->saveData( d->m_cacheId, &dataStream );
     QTextStream stream( sourceArray, IO_ReadOnly );
     stream.setCodec( QTextCodec::codecForName( encoding().latin1() ) );
     sourceStr = stream.read();
  } else
  {
    QString tmpFile;
    if( KIO::NetAccess::download( m_url, tmpFile, NULL ) )
    {
      QFile f( tmpFile );
      if ( f.open( IO_ReadOnly ) )
      {
        QTextStream stream( &f );
        stream.setCodec( QTextCodec::codecForName( encoding().latin1() ) );
      sourceStr = stream.read();
        f.close();
      }
      KIO::NetAccess::removeTempFile( tmpFile );
    }
  }

  return sourceStr;
}


00897 KParts::BrowserExtension *KHTMLPart::browserExtension() const
{
  return d->m_extension;
}

KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
{
  return d->m_hostExtension;
}

00907 KHTMLView *KHTMLPart::view() const
{
  return d->m_view;
}

00912 void KHTMLPart::setStatusMessagesEnabled( bool enable )
{
  d->m_statusMessagesEnabled = enable;
}

00917 KJS::Interpreter *KHTMLPart::jScriptInterpreter()
{
  KJSProxy *proxy = jScript();
  if (!proxy || proxy->paused())
    return 0;

  return proxy->interpreter();
}

00926 bool KHTMLPart::statusMessagesEnabled() const
{
  return d->m_statusMessagesEnabled;
}

00931 void KHTMLPart::setJScriptEnabled( bool enable )
{
  if ( !enable && jScriptEnabled() && d->m_frame && d->m_frame->m_jscript ) {
    d->m_frame->m_jscript->clear();
  }
  d->m_bJScriptForce = enable;
  d->m_bJScriptOverride = true;
}

00940 bool KHTMLPart::jScriptEnabled() const
{
  if(onlyLocalReferences()) return false;

  if ( d->m_bJScriptOverride )
      return d->m_bJScriptForce;
  return d->m_bJScriptEnabled;
}

00949 void KHTMLPart::setMetaRefreshEnabled( bool enable )
{
  d->m_metaRefreshEnabled = enable;
}

00954 bool KHTMLPart::metaRefreshEnabled() const
{
  return d->m_metaRefreshEnabled;
}

// Define this to disable dlopening kjs_html, when directly linking to it.
// You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
// and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
//        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
//        Also, change the order of "ecma" and "." in khtml's SUBDIRS line.
// OK - that's the default now, use the opposite of the above instructions to go back
// to "dlopening it" - but it breaks exception catching in kjs_binding.cpp
#define DIRECT_LINKAGE_TO_ECMA

#ifdef DIRECT_LINKAGE_TO_ECMA
extern "C" { KJSProxy *kjs_html_init(khtml::ChildFrame * childframe); }
#endif

static bool createJScript(khtml::ChildFrame *frame)
{
#ifndef DIRECT_LINKAGE_TO_ECMA
  KLibrary *lib = KLibLoader::self()->library("kjs_html");
  if ( !lib ) {
    setJScriptEnabled( false );
    return false;
  }
  // look for plain C init function
  void *sym = lib->symbol("kjs_html_init");
  if ( !sym ) {
    lib->unload();
    setJScriptEnabled( false );
    return false;
  }
  typedef KJSProxy* (*initFunction)(khtml::ChildFrame *);
  initFunction initSym = (initFunction) sym;
  frame->m_jscript = (*initSym)(d->m_frame);
  frame->m_kjs_lib = lib;
#else
  frame->m_jscript = kjs_html_init(frame);
  // frame->m_kjs_lib remains 0L.
#endif
  return true;
}

KJSProxy *KHTMLPart::jScript()
{
  if (!jScriptEnabled()) return 0;

  if ( !d->m_frame ) {
      KHTMLPart * p = parentPart();
      if (!p) {
          d->m_frame = new khtml::ChildFrame;
          d->m_frame->m_part = this;
      } else {
          ConstFrameIt it = p->d->m_frames.begin();
          const ConstFrameIt end = p->d->m_frames.end();
          for (; it != end; ++it)
              if ((*it)->m_part.operator->() == this) {
                  d->m_frame = *it;
                  break;
              }
      }
      if ( !d->m_frame )
        return 0;
  }
  if ( !d->m_frame->m_jscript )
    if (!createJScript(d->m_frame))
      return 0;
  if (d->m_bJScriptDebugEnabled)
    d->m_frame->m_jscript->setDebugEnabled(true);

  return d->m_frame->m_jscript;
}

QVariant KHTMLPart::crossFrameExecuteScript(const QString& target,  const QString& script)
{
  KHTMLPart* destpart = this;

  QString trg = target.lower();

  if (target == "_top") {
    while (destpart->parentPart())
      destpart = destpart->parentPart();
  }
  else if (target == "_parent") {
    if (parentPart())
      destpart = parentPart();
  }
  else if (target == "_self" || target == "_blank")  {
    // we always allow these
  }
  else {
    destpart = findFrame(target);
    if (!destpart)
       destpart = this;
  }

  // easy way out?
  if (destpart == this)
    return executeScript(DOM::Node(), script);

  // now compare the domains
  if (destpart->checkFrameAccess(this))
    return destpart->executeScript(DOM::Node(), script);

  // eww, something went wrong. better execute it in our frame
  return executeScript(DOM::Node(), script);
}

//Enable this to see all JS scripts being executed
//#define KJS_VERBOSE

KJSErrorDlg *KHTMLPart::jsErrorExtension() {
  if (!d->m_settings->jsErrorsEnabled()) {
    return 0L;
  }

  if (parentPart()) {
    return parentPart()->jsErrorExtension();
  }

  if (!d->m_statusBarJSErrorLabel) {
    d->m_statusBarJSErrorLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
    d->m_statusBarJSErrorLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
    d->m_statusBarJSErrorLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
    d->m_statusBarJSErrorLabel->setUseCursor(false);
    d->m_statusBarExtension->addStatusBarItem(d->m_statusBarJSErrorLabel, 0, false);
    QToolTip::add(d->m_statusBarJSErrorLabel, i18n("This web page contains coding errors."));
    d->m_statusBarJSErrorLabel->setPixmap(SmallIcon("bug", instance()));
    connect(d->m_statusBarJSErrorLabel, SIGNAL(leftClickedURL()), SLOT(launchJSErrorDialog()));
    connect(d->m_statusBarJSErrorLabel, SIGNAL(rightClickedURL()), SLOT(jsErrorDialogContextMenu()));
  }
  if (!d->m_jsedlg) {
    d->m_jsedlg = new KJSErrorDlg;
    d->m_jsedlg->setURL(m_url.prettyURL());
    if (KGlobalSettings::showIconsOnPushButtons()) {
      d->m_jsedlg->_clear->setIconSet(SmallIconSet("locationbar_erase"));
      d->m_jsedlg->_close->setIconSet(SmallIconSet("fileclose"));
    }
  }
  return d->m_jsedlg;
}

01097 void KHTMLPart::removeJSErrorExtension() {
  if (parentPart()) {
    parentPart()->removeJSErrorExtension();
    return;
  }
  if (d->m_statusBarJSErrorLabel != 0) {
    d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarJSErrorLabel );
    delete d->m_statusBarJSErrorLabel;
    d->m_statusBarJSErrorLabel = 0;
  }
  delete d->m_jsedlg;
  d->m_jsedlg = 0;
}

01111 void KHTMLPart::disableJSErrorExtension() {
  removeJSErrorExtension();
  // These two lines are really kind of hacky, and it sucks to do this inside
  // KHTML but I don't know of anything that's reasonably easy as an alternative
  // right now.  It makes me wonder if there should be a more clean way to
  // contact all running "KHTML" instance as opposed to Konqueror instances too.
  d->m_settings->setJSErrorsEnabled(false);
  DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", QByteArray());
}

01121 void KHTMLPart::jsErrorDialogContextMenu() {
  KPopupMenu *m = new KPopupMenu(0L);
  m->insertItem(i18n("&Hide Errors"), this, SLOT(removeJSErrorExtension()));
  m->insertItem(i18n("&Disable Error Reporting"), this, SLOT(disableJSErrorExtension()));
  m->popup(QCursor::pos());
}

01128 void KHTMLPart::launchJSErrorDialog() {
  KJSErrorDlg *dlg = jsErrorExtension();
  if (dlg) {
    dlg->show();
    dlg->raise();
  }
}

01136 void KHTMLPart::launchJSConfigDialog() {
  QStringList args;
  args << "khtml_java_js";
  KApplication::kdeinitExec( "kcmshell", args );
}

QVariant KHTMLPart::executeScript(const QString& filename, int baseLine, const DOM::Node& n, const QString& script)
{
#ifdef KJS_VERBOSE
  // The script is now printed by KJS's Parser::parse
  kdDebug(6070) << "executeScript: caller='" << name() << "' filename=" << filename << " baseLine=" << baseLine /*<< " script=" << script*/ << endl;
#endif
  KJSProxy *proxy = jScript();

  if (!proxy || proxy->paused())
    return QVariant();

  KJS::Completion comp;

  QVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);

  /*
   *  Error handling
   */
  if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
    KJSErrorDlg *dlg = jsErrorExtension();
    if (dlg) {
      KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
      dlg->addError(i18n("<b>Error</b>: %1: %2").arg(filename, msg.qstring()));
    }
  }

  // Handle immediate redirects now (e.g. location='foo')
  if ( !d->m_redirectURL.isEmpty() && d->m_delayRedirect == -1 )
  {
    kdDebug(6070) << "executeScript done, handling immediate redirection NOW" << endl;
    // Must abort tokenizer, no further script must execute.
    khtml::Tokenizer* t = d->m_doc->tokenizer();
    if(t)
      t->abort();
    d->m_redirectionTimer.start( 0, true );
  }

  return ret;
}

01182 QVariant KHTMLPart::executeScript( const QString &script )
{
    return executeScript( DOM::Node(), script );
}

01187 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
{
#ifdef KJS_VERBOSE
  kdDebug(6070) << "KHTMLPart::executeScript caller='" << name() << "' node=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " /* << script */ << endl;
#endif
  KJSProxy *proxy = jScript();

  if (!proxy || proxy->paused())
    return QVariant();
  ++(d->m_runningScripts);
  KJS::Completion comp;
  const QVariant ret = proxy->evaluate( QString::null, 1, script, n, &comp );
  --(d->m_runningScripts);

  /*
   *  Error handling
   */
  if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
    KJSErrorDlg *dlg = jsErrorExtension();
    if (dlg) {
      KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
      dlg->addError(i18n("<b>Error</b>: node %1: %2").arg(n.nodeName().string()).arg(msg.qstring()));
    }
  }

  if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
      submitFormAgain();

#ifdef KJS_VERBOSE
  kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
#endif
  return ret;
}

bool KHTMLPart::scheduleScript(const DOM::Node &n, const QString& script)
{
    //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;

    d->scheduledScript = script;
    d->scheduledScriptNode = n;

    return true;
}

QVariant KHTMLPart::executeScheduledScript()
{
  if( d->scheduledScript.isEmpty() )
    return QVariant();

  //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;

  QVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
  d->scheduledScript = QString();
  d->scheduledScriptNode = DOM::Node();

  return ret;
}

01245 void KHTMLPart::setJavaEnabled( bool enable )
{
  d->m_bJavaForce = enable;
  d->m_bJavaOverride = true;
}

bool KHTMLPart::javaEnabled() const
{
  if (onlyLocalReferences()) return false;

#ifndef Q_WS_QWS
  if( d->m_bJavaOverride )
      return d->m_bJavaForce;
  return d->m_bJavaEnabled;
#else
  return false;
#endif
}

01264 KJavaAppletContext *KHTMLPart::javaContext()
{
  return 0;
}

01269 KJavaAppletContext *KHTMLPart::createJavaContext()
{
  return 0;
}

01274 void KHTMLPart::setPluginsEnabled( bool enable )
{
  d->m_bPluginsForce = enable;
  d->m_bPluginsOverride = true;
}

bool KHTMLPart::pluginsEnabled() const
{
  if (onlyLocalReferences()) return false;

  if ( d->m_bPluginsOverride )
      return d->m_bPluginsForce;
  return d->m_bPluginsEnabled;
}

static int s_DOMTreeIndentLevel = 0;

01291 void KHTMLPart::slotDebugDOMTree()
{
  if ( d->m_doc && d->m_doc->firstChild() )
    qDebug("%s", d->m_doc->firstChild()->toString().string().latin1());

  // Now print the contents of the frames that contain HTML

  const int indentLevel = s_DOMTreeIndentLevel++;

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
      KParts::ReadOnlyPart* const p = ( *it )->m_part;
      kdDebug(6050) << QString().leftJustify(s_DOMTreeIndentLevel*4,' ') << "FRAME " << p->name() << " " << endl;
      static_cast<KHTMLPart*>( p )->slotDebugDOMTree();
    }
  s_DOMTreeIndentLevel = indentLevel;
}

01311 void KHTMLPart::slotDebugScript()
{
  if (jScript())
    jScript()->showDebugWindow();
}

01317 void KHTMLPart::slotDebugRenderTree()
{
#ifndef NDEBUG
  if ( d->m_doc ) {
    d->m_doc->renderer()->printTree();
    // dump out the contents of the rendering & DOM trees
//    QString dumps;
//    QTextStream outputStream(dumps,IO_WriteOnly);
//    d->m_doc->renderer()->layer()->dump( outputStream );
//    kdDebug() << "dump output:" << "\n" + dumps;
  }
#endif
}

01331 void KHTMLPart::slotStopAnimations()
{
  stopAnimations();
}

01336 void KHTMLPart::setAutoloadImages( bool enable )
{
  if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
    return;

  if ( d->m_doc )
    d->m_doc->docLoader()->setAutoloadImages( enable );

  unplugActionList( "loadImages" );

  if ( enable ) {
    delete d->m_paLoadImages;
    d->m_paLoadImages = 0;
  }
  else if ( !d->m_paLoadImages )
    d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );

  if ( d->m_paLoadImages ) {
    QPtrList<KAction> lst;
    lst.append( d->m_paLoadImages );
    plugActionList( "loadImages", lst );
  }
}

bool KHTMLPart::autoloadImages() const
{
  if ( d->m_doc )
    return d->m_doc->docLoader()->autoloadImages();

  return true;
}

void KHTMLPart::clear()
{
  if ( d->m_bCleared )
    return;

  d->m_bCleared = true;

  d->m_bClearing = true;

  {
    ConstFrameIt it = d->m_frames.begin();
    const ConstFrameIt end = d->m_frames.end();
    for(; it != end; ++it )
    {
      // Stop HTMLRun jobs for frames
      if ( (*it)->m_run )
        (*it)->m_run->abort();
    }
  }

  {
    ConstFrameIt it = d->m_objects.begin();
    const ConstFrameIt end = d->m_objects.end();
    for(; it != end; ++it )
    {
      // Stop HTMLRun jobs for objects
      if ( (*it)->m_run )
        (*it)->m_run->abort();
    }
  }


  findTextBegin(); // resets d->m_findNode and d->m_findPos
  d->m_mousePressNode = DOM::Node();


  if ( d->m_doc )
  {
    if (d->m_doc->attached()) //the view may have detached it already
      d->m_doc->detach();
  }

  // Moving past doc so that onUnload works.
  if ( d->m_frame && d->m_frame->m_jscript )
    d->m_frame->m_jscript->clear();

  // stopping marquees
  if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->layer())
      d->m_doc->renderer()->layer()->suspendMarquees();

  if ( d->m_view )
    d->m_view->clear();

  // do not dereference the document before the jscript and view are cleared, as some destructors
  // might still try to access the document.
  if ( d->m_doc ) {
    d->m_doc->deref();
  }
  d->m_doc = 0;

  delete d->m_decoder;
  d->m_decoder = 0;

  // We don't want to change between parts if we are going to delete all of them anyway
  disconnect( partManager(), SIGNAL( activePartChanged( KParts::Part * ) ),
               this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );

  if (d->m_frames.count())
  {
    KHTMLFrameList frames = d->m_frames;
    d->m_frames.clear();
    ConstFrameIt it = frames.begin();
    const ConstFrameIt end = frames.end();
    for(; it != end; ++it )
    {
      if ( (*it)->m_part )
      {
        partManager()->removePart( (*it)->m_part );
        delete (KParts::ReadOnlyPart *)(*it)->m_part;
      }
      delete *it;
    }
  }
  d->m_suppressedPopupOriginParts.clear();

  if (d->m_objects.count())
  {
    KHTMLFrameList objects = d->m_objects;
    d->m_objects.clear();
    ConstFrameIt oi = objects.begin();
    const ConstFrameIt oiEnd = objects.end();

    for (; oi != oiEnd; ++oi )
      delete *oi;
  }

  // Listen to part changes again
  connect( partManager(), SIGNAL( activePartChanged( KParts::Part * ) ),
             this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );

  d->m_delayRedirect = 0;
  d->m_redirectURL = QString::null;
  d->m_redirectionTimer.stop();
  d->m_redirectLockHistory = true;
  d->m_bClearing = false;
  d->m_frameNameId = 1;
  d->m_bFirstData = true;

  d->m_bMousePressed = false;

  d->m_selectionStart = DOM::Node();
  d->m_selectionEnd = DOM::Node();
  d->m_startOffset = 0;
  d->m_endOffset = 0;
#ifndef QT_NO_CLIPBOARD
  connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
#endif

  d->m_jobPercent = 0;

  if ( !d->m_haveEncoding )
    d->m_encoding = QString::null;
#ifdef SPEED_DEBUG
  d->m_parsetime.restart();
#endif
}

01495 bool KHTMLPart::openFile()
{
  return true;
}

DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
{
    if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
        return static_cast<HTMLDocumentImpl*>(d->m_doc);
    return 0;
}

DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
{
    if ( d )
        return d->m_doc;
    return 0;
}

01514 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const QString& msg)
{
  assert(d->m_job == kio_job);

  if (!parentPart())
    setStatusBarText(msg, BarDefaultText);
}

void KHTMLPart::setPageSecurity( PageSecurity sec )
{
  emit d->m_extension->setPageSecurity( sec );
  if ( sec != NotCrypted && !d->m_statusBarIconLabel && !parentPart() ) {
    d->m_statusBarIconLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
    d->m_statusBarIconLabel->setFixedHeight( instance()->iconLoader()->currentSize(KIcon::Small) );
    d->m_statusBarIconLabel->setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
    d->m_statusBarIconLabel->setUseCursor( false );
    d->m_statusBarExtension->addStatusBarItem( d->m_statusBarIconLabel, 0, false );
    connect( d->m_statusBarIconLabel, SIGNAL( leftClickedURL() ), SLOT( slotSecurity() ) );
  } else if (d->m_statusBarIconLabel) {
    QToolTip::remove(d->m_statusBarIconLabel);
  }

  if (d->m_statusBarIconLabel) {
    if (d->m_ssl_in_use)
      QToolTip::add(d->m_statusBarIconLabel,
                i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
    else QToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
  }

  QString iconName;
  switch (sec)  {
  case NotCrypted:
    iconName = "decrypted";
    if ( d->m_statusBarIconLabel )  {
      d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarIconLabel );
      delete d->m_statusBarIconLabel;
      d->m_statusBarIconLabel = 0L;
    }
    break;
  case Encrypted:
    iconName = "encrypted";
    break;
  case Mixed:
    iconName = "halfencrypted";
    break;
  }
  d->m_paSecurity->setIcon( iconName );
  if ( d->m_statusBarIconLabel )
    d->m_statusBarIconLabel->setPixmap( SmallIcon( iconName, instance() ) );
}

01565 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
{
  assert ( d->m_job == kio_job );

  //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
  // The first data ?
  if ( !d->m_workingURL.isEmpty() )
  {
      //kdDebug( 6050 ) << "begin!" << endl;

    // We must suspend KIO while we're inside begin() because it can cause
    // crashes if a window (such as kjsdebugger) goes back into the event loop,
    // more data arrives, and begin() gets called again (re-entered).
    d->m_job->suspend();
    begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
    d->m_job->resume();

    if (d->m_cachePolicy == KIO::CC_Refresh)
      d->m_doc->docLoader()->setCachePolicy(KIO::CC_Verify);
    else
      d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);

    d->m_workingURL = KURL();

    d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();

    // When the first data arrives, the metadata has just been made available
    d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
    time_t cacheCreationDate =  d->m_job->queryMetaData("cache-creation-date").toLong();
    d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);

    d->m_pageServices = d->m_job->queryMetaData("PageServices");
    d->m_pageReferrer = d->m_job->queryMetaData("referrer");
    d->m_bSecurityInQuestion = false;
    d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");

    {
    KHTMLPart *p = parentPart();
    if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
      while (p->parentPart()) p = p->parentPart();

        p->setPageSecurity( Mixed );
        p->d->m_bSecurityInQuestion = true;
    }
    }

    setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );

    // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
    d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
    d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
    d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
    d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
    d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
    d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
    d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
    d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
    d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
    d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
    d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");

    if (d->m_statusBarIconLabel) {
      QToolTip::remove(d->m_statusBarIconLabel);
      if (d->m_ssl_in_use) {
        QToolTip::add(d->m_statusBarIconLabel, i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
      } else {
        QToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
      }
    }

    // Check for charset meta-data
    QString qData = d->m_job->queryMetaData("charset");
    if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
       d->m_encoding = qData;


    // Support for http-refresh
    qData = d->m_job->queryMetaData("http-refresh");
    if( !qData.isEmpty())
      d->m_doc->processHttpEquiv("refresh", qData);

    // DISABLED: Support Content-Location per section 14.14 of RFC 2616.
    // See BR# 51185,BR# 82747
    /*
    QString baseURL = d->m_job->queryMetaData ("content-location");
    if (!baseURL.isEmpty())
      d->m_doc->setBaseURL(KURL( d->m_doc->completeURL(baseURL) ));
    */

    // Support for Content-Language
    QString language = d->m_job->queryMetaData("content-language");
    if (!language.isEmpty())
        d->m_doc->setContentLanguage(language);

    if ( !m_url.isLocalFile() ) {
        // Support for http last-modified
        d->m_lastModified = d->m_job->queryMetaData("modified");
    } else
        d->m_lastModified = QString::null; // done on-demand by lastModified()
  }

  KHTMLPageCache::self()->addData(d->m_cacheId, data);
  write( data.data(), data.size() );
  if (d->m_frame && d->m_frame->m_jscript)
    d->m_frame->m_jscript->dataReceived();
}

01672 void KHTMLPart::slotRestoreData(const QByteArray &data )
{
  // The first data ?
  if ( !d->m_workingURL.isEmpty() )
  {
     long saveCacheId = d->m_cacheId;
     QString savePageReferrer = d->m_pageReferrer;
     QString saveEncoding     = d->m_encoding;
     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
     d->m_encoding     = saveEncoding;
     d->m_pageReferrer = savePageReferrer;
     d->m_cacheId = saveCacheId;
     d->m_workingURL = KURL();
  }

  //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
  write( data.data(), data.size() );

  if (data.size() == 0)
  {
      //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
     // End of data.
    if (d->m_doc && d->m_doc->parsing())
        end(); //will emit completed()
  }
}

01699 void KHTMLPart::showError( KIO::Job* job )
{
  kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
                << " d->m_bCleared=" << d->m_bCleared << endl;

  if (job->error() == KIO::ERR_NO_CONTENT)
      return;

  if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
    job->showErrorDialog( /*d->m_view*/ );
  else
  {
    htmlError( job->error(), job->errorText(), d->m_workingURL );
  }
}

// This is a protected method, placed here because of it's relevance to showError
01716 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
{
  kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
  // make sure we're not executing any embedded JS
  bool bJSFO = d->m_bJScriptForce;
  bool bJSOO = d->m_bJScriptOverride;
  d->m_bJScriptForce = false;
  d->m_bJScriptOverride = true;
  begin();
  QString errText = QString::fromLatin1( "<HTML dir=%1><HEAD><TITLE>" )
                           .arg(QApplication::reverseLayout() ? "rtl" : "ltr");
  errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
  errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
  errText += i18n( "An error occurred while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
  errText += QString::fromLatin1( "</P>" );
  errText += QStyleSheet::convertFromPlainText( KIO::buildErrorString( errorCode, text ) );
  errText += QString::fromLatin1( "</BODY></HTML>" );
  write(errText);
  end();

  d->m_bJScriptForce = bJSFO;
  d->m_bJScriptOverride = bJSOO;

  // make the working url the current url, so that reload works and
  // emit the progress signals to advance one step in the history
  // (so that 'back' works)
  m_url = reqUrl; // same as d->m_workingURL
  d->m_workingURL = KURL();
  emit started( 0 );
  emit completed();
  return;
  // following disabled until 3.1

  QString errorName, techName, description;
  QStringList causes, solutions;

  QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
  QDataStream stream(raw, IO_ReadOnly);

  stream >> errorName >> techName >> description >> causes >> solutions;

  QString url, protocol, datetime;
  url = reqUrl.prettyURL();
  protocol = reqUrl.protocol();
  datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
                                                false );

  QString doc = QString::fromLatin1( "<html><head><title>" );
  doc += i18n( "Error: " );
  doc += errorName;
  doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
  doc += i18n( "The requested operation could not be completed" );
  doc += QString::fromLatin1( "</h1><h2>" );
  doc += errorName;
  doc += QString::fromLatin1( "</h2>" );
  if ( !techName.isNull() ) {
    doc += QString::fromLatin1( "<h2>" );
    doc += i18n( "Technical Reason: " );
    doc += techName;
    doc += QString::fromLatin1( "</h2>" );
  }
  doc += QString::fromLatin1( "<h3>" );
  doc += i18n( "Details of the Request:" );
  doc += QString::fromLatin1( "</h3><ul><li>" );
  doc += i18n( "URL: %1" ).arg( url );
  doc += QString::fromLatin1( "</li><li>" );
  if ( !protocol.isNull() ) {
    // uncomment for 3.1... i18n change
    // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
    doc += QString::fromLatin1( "</li><li>" );
  }
  doc += i18n( "Date and Time: %1" ).arg( datetime );
  doc += QString::fromLatin1( "</li><li>" );
  doc += i18n( "Additional Information: %1" ).arg( text );
  doc += QString::fromLatin1( "</li></ul><h3>" );
  doc += i18n( "Description:" );
  doc += QString::fromLatin1( "</h3><p>" );
  doc += description;
  doc += QString::fromLatin1( "</p>" );
  if ( causes.count() ) {
    doc += QString::fromLatin1( "<h3>" );
    doc += i18n( "Possible Causes:" );
    doc += QString::fromLatin1( "</h3><ul><li>" );
    doc += causes.join( "</li><li>" );
    doc += QString::fromLatin1( "</li></ul>" );
  }
  if ( solutions.count() ) {
    doc += QString::fromLatin1( "<h3>" );
    doc += i18n( "Possible Solutions:" );
    doc += QString::fromLatin1( "</h3><ul><li>" );
    doc += solutions.join( "</li><li>" );
    doc += QString::fromLatin1( "</li></ul>" );
  }
  doc += QString::fromLatin1( "</body></html>" );

  write( doc );
  end();
}

01815 void KHTMLPart::slotFinished( KIO::Job * job )
{
  d->m_job = 0L;
  d->m_jobspeed = 0L;

  if (job->error())
  {
    KHTMLPageCache::self()->cancelEntry(d->m_cacheId);

    // The following catches errors that occur as a result of HTTP
    // to FTP redirections where the FTP URL is a directory. Since
    // KIO cannot change a redirection request from GET to LISTDIR,
    // we have to take care of it here once we know for sure it is
    // a directory...
    if (job->error() == KIO::ERR_IS_DIRECTORY)
    {
      KParts::URLArgs args;
      emit d->m_extension->openURLRequest( d->m_workingURL, args );
    }
    else
    {
      emit canceled( job->errorString() );
      // TODO: what else ?
      checkCompleted();
      showError( job );
    }

    return;
  }
  KIO::TransferJob *tjob = ::qt_cast<KIO::TransferJob*>(job);
  if (tjob && tjob->isErrorPage()) {
    khtml::RenderPart *renderPart = d->m_frame->m_frame;
    if (renderPart) {
      HTMLObjectElementImpl* elt = static_cast<HTMLObjectElementImpl *>(renderPart->element());
      if (!elt)
        return;
      elt->renderAlternative();
      checkCompleted();
     }
     if (d->m_bComplete) return;
  }

  //kdDebug( 6050 ) << "slotFinished" << endl;

  KHTMLPageCache::self()->endData(d->m_cacheId);
  if (d->m_frame && d->m_frame->m_jscript)
    d->m_frame->m_jscript->dataReceived();

  if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
      KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());

  d->m_workingURL = KURL();

  if ( d->m_doc && d->m_doc->parsing())
    end(); //will emit completed()
}

01872 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
{
  // No need to show this for a new page until an error is triggered
  if (!parentPart()) {
    removeJSErrorExtension();
    setSuppressedPopupIndicator( false );
    d->m_openableSuppressedPopups = 0;
    for ( QValueListIterator<QGuardedPtr<KHTMLPart> > i = d->m_suppressedPopupOriginParts.begin();
          i != d->m_suppressedPopupOriginParts.end(); ++i ) {
       
      if (KHTMLPart* part = *i) {
        KJS::Window *w = KJS::Window::retrieveWindow( part );
        if (w)
          w->forgetSuppressedWindows();
      }
    }
  }

  clear();
  d->m_bCleared = false;
  d->m_cacheId = 0;
  d->m_bComplete = false;
  d->m_bLoadEventEmitted = false;

  if(url.isValid()) {
      QString urlString = url.url();
      KHTMLFactory::vLinks()->insert( urlString );
      QString urlString2 = url.prettyURL();
      if ( urlString != urlString2 ) {
          KHTMLFactory::vLinks()->insert( urlString2 );
      }
  }


  // ###
  //stopParser();

  KParts::URLArgs args( d->m_extension->urlArgs() );
  args.xOffset = xOffset;
  args.yOffset = yOffset;
  d->m_extension->setURLArgs( args );

  d->m_pageReferrer = QString::null;

  KURL ref(url);
  d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : "";

  m_url = url;

  bool servedAsXHTML = args.serviceType == "application/xhtml+xml";
  bool servedAsXML = KMimeType::mimeType(args.serviceType)->is( "text/xml" );
  // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
  if ( servedAsXML && !servedAsXHTML ) { // any XML derivative, except XHTML
    d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
  } else {
    d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
    // HTML or XHTML? (#86446)
    static_cast<HTMLDocumentImpl *>(d->m_doc)->setHTMLRequested( !servedAsXHTML );
  }
#ifndef KHTML_NO_CARET
//  d->m_view->initCaret();
#endif

  d->m_doc->ref();
  d->m_doc->setURL( m_url.url() );
  if (!d->m_doc->attached())
    d->m_doc->attach( );
  d->m_doc->setBaseURL( KURL() );
  d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
  emit docCreated();

  d->m_paUseStylesheet->setItems(QStringList());
  d->m_paUseStylesheet->setEnabled( false );

  setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
  QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
  if ( !userStyleSheet.isEmpty() )
    setUserStyleSheet( KURL( userStyleSheet ) );

  d->m_doc->setRestoreState(args.docState);
  d->m_doc->open();
  connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));

  emit d->m_extension->enableAction( "print", true );

  d->m_doc->setParsing(true);
}

01960 void KHTMLPart::write( const char *str, int len )
{
  if ( !d->m_decoder )
    d->m_decoder = createDecoder();

  if ( len == -1 )
    len = strlen( str );

  if ( len == 0 )
    return;

  QString decoded = d->m_decoder->decode( str, len );

  if(decoded.isEmpty()) return;

  if(d->m_bFirstData) {
      // determine the parse mode
      d->m_doc->determineParseMode( decoded );
      d->m_bFirstData = false;

  //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
      // ### this is still quite hacky, but should work a lot better than the old solution
      if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
      d->m_doc->setDecoderCodec(d->m_decoder->codec());
      d->m_doc->recalcStyle( NodeImpl::Force );
  }

  khtml::Tokenizer* t = d->m_doc->tokenizer();
  if(t)
    t->write( decoded, true );
}

01992 void KHTMLPart::write( const QString &str )
{
  if ( str.isNull() )
    return;

  if(d->m_bFirstData) {
      // determine the parse mode
      d->m_doc->setParseMode( DocumentImpl::Strict );
      d->m_bFirstData = false;
  }
  khtml::Tokenizer* t = d->m_doc->tokenizer();
  if(t)
    t->write( str, true );
}

02007 void KHTMLPart::end()
{
    // make sure nothing's left in there...
    if(d->m_decoder)
        write(d->m_decoder->flush());
    if (d->m_doc)
        d->m_doc->finishParsing();
}

02016 bool KHTMLPart::doOpenStream( const QString& mimeType )
{
    KMimeType::Ptr mime = KMimeType::mimeType(mimeType);
    if ( mime->is( "text/html" ) || mime->is( "text/xml" ) )
    {
        begin( url() );
        return true;
    }
    return false;
}

02027 bool KHTMLPart::doWriteStream( const QByteArray& data )
{
    write( data.data(), data.size() );
    return true;
}

02033 bool KHTMLPart::doCloseStream()
{
    end();
    return true;
}


02040 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
{
    if (!d->m_view) return;
    d->m_view->paint(p, rc, yOff, more);
}

02046 void KHTMLPart::stopAnimations()
{
  if ( d->m_doc )
    d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if ( !(*it)->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
      KParts::ReadOnlyPart* const p = ( *it )->m_part;
      static_cast<KHTMLPart*>( p )->stopAnimations();
    }
}

void KHTMLPart::resetFromScript()
{
    closeURL();
    d->m_bComplete = false;
    d->m_bLoadEventEmitted = false;
    disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
    connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
    d->m_doc->setParsing(true);

    emit started( 0L );
}

02072 void KHTMLPart::slotFinishedParsing()
{
  d->m_doc->setParsing(false);
  checkEmitLoadEvent();
  disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));

  if (!d->m_view)
    return; // We are probably being destructed.

  checkCompleted();
}

void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
{
  if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
    KHTMLPart* p = this;
    while ( p ) {
      KHTMLPart* const op = p;
      ++(p->d->m_totalObjectCount);
      p = p->parentPart();
      if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
        && !op->d->m_progressUpdateTimer.isActive())
      op->d->m_progressUpdateTimer.start( 200, true );
    }
  }
}

void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
{
  if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
    KHTMLPart* p = this;
    while ( p ) {
      KHTMLPart* const op = p;
      ++(p->d->m_loadedObjects);
      p = p->parentPart();
      if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
        && !op->d->m_progressUpdateTimer.isActive())
      op->d->m_progressUpdateTimer.start( 200, true );
    }
  }

  checkCompleted();
}

02116 void KHTMLPart::slotProgressUpdate()
{
  int percent;
  if ( d->m_loadedObjects < d->m_totalObjectCount )
    percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
  else
    percent = d->m_jobPercent;

  if( d->m_bComplete )
    percent = 100;

  if (d->m_statusMessagesEnabled) {
    if( d->m_bComplete )
      emit d->m_extension->infoMessage( i18n( "Page loaded." ));
    else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
      emit d->m_extension->infoMessage( i18n( "%n Image of %1 loaded.", "%n Images of %1 loaded.", d->m_loadedObjects).arg(d->m_totalObjectCount) );
  }

  emit d->m_extension->loadingProgress( percent );
}

void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
{
  d->m_jobspeed = speed;
  if (!parentPart())
    setStatusBarText(jsStatusBarText(), BarOverrideText);
}

void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
{
  d->m_jobPercent = percent;

  if ( !parentPart() )
    d->m_progressUpdateTimer.start( 0, true );
}

void KHTMLPart::slotJobDone( KIO::Job* /*job*/ )
{
  d->m_jobPercent = 100;

  if ( !parentPart() )
    d->m_progressUpdateTimer.start( 0, true );
}

void KHTMLPart::slotUserSheetStatDone( KIO::Job *_job )
{
  using namespace KIO;

  if ( _job->error() ) {
    showError( _job );
    return;
  }

  const UDSEntry entry = dynamic_cast<KIO::StatJob *>( _job )->statResult();
  UDSEntry::ConstIterator it = entry.begin();
  const UDSEntry::ConstIterator end = entry.end();
  for ( ; it != end; ++it ) {
    if ( ( *it ).m_uds == UDS_MODIFICATION_TIME ) {
     break;
    }
  }

  // If the filesystem supports modification times, only reload the
  // user-defined stylesheet if necessary - otherwise always reload.
  if ( it != end ) {
    const time_t lastModified = static_cast<time_t>( ( *it ).m_long );
    if ( d->m_userStyleSheetLastModified >= lastModified ) {
      return;
    }
    d->m_userStyleSheetLastModified = lastModified;
  }

  setUserStyleSheet( KURL( settings()->userStyleSheet() ) );
}

void KHTMLPart::checkCompleted()
{
//   kdDebug( 6050 ) << "KHTMLPart::checkCompleted() " << this << " " << name() << endl;
//   kdDebug( 6050 ) << "                           parsing: " << (d->m_doc && d->m_doc->parsing()) << endl;
//   kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;

  // restore the cursor position
  if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
  {
      if (d->m_focusNodeNumber >= 0)
          d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));

      d->m_focusNodeRestored = true;
  }

  bool bPendingChildRedirection = false;
  // Any frame that hasn't completed yet ?
  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it ) {
    if ( !(*it)->m_bCompleted )
    {
      //kdDebug( 6050 ) << this << " is waiting for " << (*it)->m_part << endl;
      return;
    }
    // Check for frames with pending redirections
    if ( (*it)->m_bPendingRedirection )
      bPendingChildRedirection = true;
  }

  // Any object that hasn't completed yet ?
  {
    ConstFrameIt oi = d->m_objects.begin();
    const ConstFrameIt oiEnd = d->m_objects.end();

    for (; oi != oiEnd; ++oi )
      if ( !(*oi)->m_bCompleted )
        return;
  }
  // Are we still parsing - or have we done the completed stuff already ?
  if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
    return;

  // Still waiting for images/scripts from the loader ?
  int requests = 0;
  if ( d->m_doc && d->m_doc->docLoader() )
    requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );

  if ( requests > 0 )
  {
    //kdDebug(6050) << "still waiting for images/scripts from the loader - requests:" << requests << endl;
    return;
  }

  // OK, completed.
  // Now do what should be done when we are really completed.
  d->m_bComplete = true;
  d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
  d->m_totalObjectCount = 0;
  d->m_loadedObjects = 0;

  KHTMLPart* p = this;
  while ( p ) {
    KHTMLPart* op = p;
    p = p->parentPart();
    if ( !p && !op->d->m_progressUpdateTimer.isActive())
      op->d->m_progressUpdateTimer.start( 0, true );
  }

  checkEmitLoadEvent(); // if we didn't do it before

  bool pendingAction = false;

  if ( !d->m_redirectURL.isEmpty() )
  {
    // DA: Do not start redirection for frames here! That action is
    // deferred until the parent emits a completed signal.
    if ( parentPart() == 0 ) {
      //kdDebug(6050) << this << " starting redirection timer" << endl;
      d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
    } else {
      //kdDebug(6050) << this << " not toplevel -> not starting redirection timer. Waiting for slotParentCompleted." << endl;
    }

    pendingAction = true;
  }
  else if ( bPendingChildRedirection )
  {
    pendingAction = true;
  }

  // the view will emit completed on our behalf,
  // either now or at next repaint if one is pending

  //kdDebug(6050) << this << " asks the view to emit completed. pendingAction=" << pendingAction << endl;
  d->m_view->complete( pendingAction );

  // find the alternate stylesheets
  QStringList sheets;
  if (d->m_doc)
     sheets = d->m_doc->availableStyleSheets();
  sheets.prepend( i18n( "Automatic Detection" ) );
  d->m_paUseStylesheet->setItems( sheets );

  d->m_paUseStylesheet->setEnabled( sheets.count() > 2);
  if (sheets.count() > 2)
  {
    d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
    slotUseStylesheet();
  }

  setJSDefaultStatusBarText(QString::null);

#ifdef SPEED_DEBUG
  kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
#endif
}

void KHTMLPart::checkEmitLoadEvent()
{
  if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if ( !(*it)->m_bCompleted ) // still got a frame running -> too early
      return;

  ConstFrameIt oi = d->m_objects.begin();
  const ConstFrameIt oiEnd = d->m_objects.end();

  for (; oi != oiEnd; ++oi )
    if ( !(*oi)->m_bCompleted ) // still got a object running -> too early
      return;

  // Still waiting for images/scripts from the loader ?
  // (onload must happen afterwards, #45607)
  // ## This makes this method very similar to checkCompleted. A brave soul should try merging them.
  int requests = 0;
  if ( d->m_doc && d->m_doc->docLoader() )
    requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );

  if ( requests > 0 )
    return;

  d->m_bLoadEventEmitted = true;
  if (d->m_doc)
    d->m_doc->close();
}

02341 const KHTMLSettings *KHTMLPart::settings() const
{
  return d->m_settings;
}

#ifndef KDE_NO_COMPAT
KURL KHTMLPart::baseURL() const
{
  if ( !d->m_doc ) return KURL();

  return d->m_doc->baseURL();
}

QString KHTMLPart::baseTarget() const
{
  if ( !d->m_doc ) return QString::null;

  return d->m_doc->baseTarget();
}
#endif

02362 KURL KHTMLPart::completeURL( const QString &url )
{
  if ( !d->m_doc ) return KURL( url );

  if (d->m_decoder)
    return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());

  return KURL( d->m_doc->completeURL( url ) );
}

// Called by ecma/kjs_window in case of redirections from Javascript,
// and by xml/dom_docimpl.cpp in case of http-equiv meta refresh.
02374 void KHTMLPart::scheduleRedirection( int delay, const QString &url, bool doLockHistory )
{
  kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
  kdDebug(6050) << "current redirectURL=" << d->m_redirectURL << " with delay " << d->m_delayRedirect <<  endl;
  if( delay < 24*60*60 &&
      ( d->m_redirectURL.isEmpty() || delay <= d->m_delayRedirect) ) {
    d->m_delayRedirect = delay;
    d->m_redirectURL = url;
    d->m_redirectLockHistory = doLockHistory;
    kdDebug(6050) << " d->m_bComplete=" << d->m_bComplete << endl;
    if ( d->m_bComplete ) {
      d->m_redirectionTimer.stop();
      d->m_redirectionTimer.start( kMax(0, 1000 * d->m_delayRedirect), true );
    }
  }
}

02391 void KHTMLPart::slotRedirect()
{
  kdDebug(6050) << this << " slotRedirect()" << endl;
  QString u = d->m_redirectURL;
  d->m_delayRedirect = 0;
  d->m_redirectURL = QString::null;

  // SYNC check with ecma/kjs_window.cpp::goURL !
  if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
  {
    QString script = KURL::decode_string( u.right( u.length() - 11 ) );
    kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
    QVariant res = executeScript( DOM::Node(), script );
    if ( res.type() == QVariant::String ) {
      begin( url() );
      write( res.asString() );
      end();
    }
    emit completed();
    return;
  }
  KParts::URLArgs args;
  KURL cUrl( m_url );
  KURL url( u );

  // handle windows opened by JS
  if ( openedByJS() && d->m_opener )
      cUrl = d->m_opener->url();

  if (!kapp || !kapp->authorizeURLAction("redirect", cUrl, url))
  {
    kdWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << cUrl << " to " << url << " REJECTED!" << endl;
    emit completed();
    return;
  }

  if ( urlcmp( u, m_url.url(), true, true ) )
  {
    args.metaData().insert("referrer", d->m_pageReferrer);
  }

  // For javascript and META-tag based redirections:
  //   - We don't take cross-domain-ness in consideration if we are the
  //   toplevel frame because the new URL may be in a different domain as the current URL
  //   but that's ok.
  //   - If we are not the toplevel frame then we check against the toplevelURL()
  if (parentPart())
      args.metaData().insert("cross-domain", toplevelURL().url());

  args.setLockHistory( d->m_redirectLockHistory );
  // _self: make sure we don't use any <base target=>'s

  d->m_urlSelectedOpenedURL = true; // In case overriden, default to success
  urlSelected( u, 0, 0, "_self", args );

  if ( !d->m_urlSelectedOpenedURL ) // urlSelected didn't open a url, so emit completed ourselves
    emit completed();
}

02450 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
{
  // the slave told us that we got redirected
  //kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
  emit d->m_extension->setLocationBarURL( url.prettyURL() );
  d->m_workingURL = url;
}

02458 bool KHTMLPart::setEncoding( const QString &name, bool override )
{
    d->m_encoding = name;
    d->m_haveEncoding = override;

    if( !m_url.isEmpty() ) {
        // reload document
        closeURL();
        KURL url = m_url;
        m_url = 0;
        d->m_restored = true;
        openURL(url);
        d->m_restored = false;
    }

    return true;
}

02476 QString KHTMLPart::encoding() const
{
    if(d->m_haveEncoding && !d->m_encoding.isEmpty())
        return d->m_encoding;

    if(d->m_decoder && d->m_decoder->encoding())
        return QString(d->m_decoder->encoding());

    return defaultEncoding();
}

QString KHTMLPart::defaultEncoding() const
{
  QString encoding = settings()->encoding();
  if ( !encoding.isEmpty() )
    return encoding;
  // HTTP requires the default encoding to be latin1, when neither
  // the user nor the page requested a particular encoding.
  if ( url().protocol().startsWith( "http" ) )
    return "iso-8859-1";
  else
    return KGlobal::locale()->encoding();
}

02500 void KHTMLPart::setUserStyleSheet(const KURL &url)
{
  if ( d->m_doc && d->m_doc->docLoader() )
    (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
}

02506 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
{
  if ( d->m_doc )
    d->m_doc->setUserStyleSheet( styleSheet );
}

02512 bool KHTMLPart::gotoAnchor( const QString &name )
{
  if (!d->m_doc)
    return false;

  HTMLCollectionImpl *anchors =
      new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
  anchors->ref();
  NodeImpl *n = anchors->namedItem(name);
  anchors->deref();

  if(!n) {
      n = d->m_doc->getElementById( name );
  }

  d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.

  // Implement the rule that "" and "top" both mean top of page as in other browsers.
  bool quirkyName = !n && !d->m_doc->inStrictMode() && (name.isEmpty() || name.lower() == "top");

  if (quirkyName) {
      d->m_view->setContentsPos(0, 0);
      return true;
  } else if (!n) {
      kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
      return false;
  }

  int x = 0, y = 0;
  int gox, dummy;
  HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);

  a->getUpperLeftCorner(x, y);
  if (x <= d->m_view->contentsX())
    gox = x - 10;
  else {
    gox = d->m_view->contentsX();
    if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
      a->getLowerRightCorner(x, dummy);
      gox = x - d->m_view->visibleWidth() + 10;
    }
  }

  d->m_view->setContentsPos(gox, y);

  return true;
}

02560 bool KHTMLPart::nextAnchor()
{
  if (!d->m_doc)
    return false;
  d->m_view->focusNextPrevNode ( true );

  return true;
}

02569 bool KHTMLPart::prevAnchor()
{
  if (!d->m_doc)
    return false;
  d->m_view->focusNextPrevNode ( false );

  return true;
}

02578 void KHTMLPart::setStandardFont( const QString &name )
{
    d->m_settings->setStdFontName(name);
}

02583 void KHTMLPart::setFixedFont( const QString &name )
{
    d->m_settings->setFixedFontName(name);
}

02588 void KHTMLPart::setURLCursor( const QCursor &c )
{
  d->m_linkCursor = c;
}

02593 QCursor KHTMLPart::urlCursor() const
{
  return d->m_linkCursor;
}

02598 bool KHTMLPart::onlyLocalReferences() const
{
  return d->m_onlyLocalReferences;
}

02603 void KHTMLPart::setOnlyLocalReferences(bool enable)
{
  d->m_onlyLocalReferences = enable;
}

void KHTMLPartPrivate::setFlagRecursively(
      bool KHTMLPartPrivate::*flag, bool value)
{
  // first set it on the current one
  this->*flag = value;

  // descend into child frames recursively
  {
    QValueList<khtml::ChildFrame*>::Iterator it = m_frames.begin();
    const QValueList<khtml::ChildFrame*>::Iterator itEnd = m_frames.end();
    for (; it != itEnd; ++it) {
      KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
      if (part->inherits("KHTMLPart"))
        part->d->setFlagRecursively(flag, value);
    }/*next it*/
  }
  // do the same again for objects
  {
    QValueList<khtml::ChildFrame*>::Iterator it = m_objects.begin();
    const QValueList<khtml::ChildFrame*>::Iterator itEnd = m_objects.end();
    for (; it != itEnd; ++it) {
      KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
      if (part->inherits("KHTMLPart"))
        part->d->setFlagRecursively(flag, value);
    }/*next it*/
  }
}

02636 void KHTMLPart::setCaretMode(bool enable)
{
#ifndef KHTML_NO_CARET
  kdDebug(6200) << "setCaretMode(" << enable << ")" << endl;
  if (isCaretMode() == enable) return;
  d->setFlagRecursively(&KHTMLPartPrivate::m_caretMode, enable);
  // FIXME: this won't work on frames as expected
  if (!isEditable()) {
    if (enable) {
      view()->initCaret(true);
      view()->ensureCaretVisible();
    } else
      view()->caretOff();
  }/*end if*/
#endif // KHTML_NO_CARET
}

02653 bool KHTMLPart::isCaretMode() const
{
  return d->m_caretMode;
}

02658 void KHTMLPart::setEditable(bool enable)
{
#ifndef KHTML_NO_CARET
  if (isEditable() == enable) return;
  d->setFlagRecursively(&KHTMLPartPrivate::m_designMode, enable);
  // FIXME: this won't work on frames as expected
  if (!isCaretMode()) {
    if (enable) {
      view()->initCaret(true);
      view()->ensureCaretVisible();
    } else
      view()->caretOff();
  }/*end if*/
#endif // KHTML_NO_CARET
}

02674 bool KHTMLPart::isEditable() const
{
  return d->m_designMode;
}

02679 void KHTMLPart::setCaretPosition(DOM::Node node, long offset, bool extendSelection)
{
#ifndef KHTML_NO_CARET
#if 0
  kdDebug(6200) << k_funcinfo << "node: " << node.handle() << " nodeName: "
      << node.nodeName().string() << " offset: " << offset
      << " extendSelection " << extendSelection << endl;
#endif
  if (view()->moveCaretTo(node.handle(), offset, !extendSelection))
    emitSelectionChanged();
  view()->ensureCaretVisible();
#endif // KHTML_NO_CARET
}

02693 KHTMLPart::CaretDisplayPolicy KHTMLPart::caretDisplayPolicyNonFocused() const
{
#ifndef KHTML_NO_CARET
  return (CaretDisplayPolicy)view()->caretDisplayPolicyNonFocused();
#else // KHTML_NO_CARET
  return CaretInvisible;
#endif // KHTML_NO_CARET
}

02702 void KHTMLPart::setCaretDisplayPolicyNonFocused(CaretDisplayPolicy policy)
{
#ifndef KHTML_NO_CARET
  view()->setCaretDisplayPolicyNonFocused(policy);
#endif // KHTML_NO_CARET
}

02709 void KHTMLPart::setCaretVisible(bool show)
{
#ifndef KHTML_NO_CARET
  if (show) {

    NodeImpl *caretNode = xmlDocImpl()->focusNode();
    if (isCaretMode() || isEditable()
      || (caretNode && caretNode->contentEditable())) {
      view()->caretOn();
    }/*end if*/

  } else {

    view()->caretOff();

  }/*end if*/
#endif // KHTML_NO_CARET
}

02728 void KHTMLPart::findTextBegin()
{
  d->m_findPos = -1;
  d->m_findNode = 0;
  d->m_findPosEnd = -1;
  d->m_findNodeEnd= 0;
  d->m_findPosStart = -1;
  d->m_findNodeStart = 0;
  d->m_findNodePrevious = 0;
  delete d->m_find;
  d->m_find = 0L;
}

bool KHTMLPart::initFindNode( bool selection, bool reverse, bool fromCursor )
{
    if ( !d->m_doc )
        return false;

    DOM::NodeImpl* firstNode = 0L;
    if (d->m_doc->isHTMLDocument())
      firstNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
    else
      firstNode = d->m_doc;

    if ( !firstNode )
    {
      //kdDebug(6050) << k_funcinfo << "no first node (body or doc) -> return false" << endl;
      return false;
    }
    if ( firstNode->id() == ID_FRAMESET )
    {
      //kdDebug(6050) << k_funcinfo << "FRAMESET -> return false" << endl;
      return false;
    }

    if ( selection && hasSelection() )
    {
      //kdDebug(6050) << k_funcinfo << "using selection" << endl;
      if ( !fromCursor )
      {
        d->m_findNode = reverse ? d->m_selectionEnd.handle() : d->m_selectionStart.handle();
        d->m_findPos = reverse ? d->m_endOffset : d->m_startOffset;
      }
      d->m_findNodeEnd = reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
      d->m_findPosEnd = reverse ? d->m_startOffset : d->m_endOffset;
      d->m_findNodeStart = !reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
      d->m_findPosStart = !reverse ? d->m_startOffset : d->m_endOffset;
      d->m_findNodePrevious = d->m_findNodeStart;
    }
    else // whole document
    {
      //kdDebug(6050) << k_funcinfo << "whole doc" << endl;
      if ( !fromCursor )
      {
        d->m_findNode = firstNode;
        d->m_findPos = reverse ? -1 : 0;
      }
      d->m_findNodeEnd = reverse ? firstNode : 0;
      d->m_findPosEnd = reverse ? 0 : -1;
      d->m_findNodeStart = !reverse ? firstNode : 0;
      d->m_findPosStart = !reverse ? 0 : -1;
      d->m_findNodePrevious = d->m_findNodeStart;
      if ( reverse )
      {
        // Need to find out the really last object, to start from it
        khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
        if ( obj )
        {
          // find the last object in the render tree
          while ( obj->lastChild() )
          {
              obj = obj->lastChild();
          }
          // now get the last object with a NodeImpl associated
          while ( !obj->element() && obj->objectAbove() )
          {
             obj = obj->objectAbove();
          }
          d->m_findNode = obj->element();
        }
      }
    }
    return true;
}

// Old method (its API limits the available features - remove in KDE-4)
02814 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
{
    if ( !initFindNode( false, !forward, d->m_findNode ) )
      return false;
    while(1)
    {
        if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
        {
            DOMString nodeText = d->m_findNode->nodeValue();
            DOMStringImpl *t = nodeText.implementation();
            QConstString s(t->s, t->l);

            int matchLen = 0;
            if ( isRegExp ) {
              QRegExp matcher( str );
              matcher.setCaseSensitive( caseSensitive );
              d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
              if ( d->m_findPos != -1 )
                matchLen = matcher.matchedLength();
            }
            else {
              d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
              matchLen = str.length();
            }

            if(d->m_findPos != -1)
            {
                int x = 0, y = 0;
                if(static_cast<khtml::RenderText *>(d->m_findNode->renderer())
                  ->posOfChar(d->m_findPos, x, y))
                    d->m_view->setContentsPos(x-50, y-50);

                d->m_selectionStart = d->m_findNode;
                d->m_startOffset = d->m_findPos;
                d->m_selectionEnd = d->m_findNode;
                d->m_endOffset = d->m_findPos + matchLen;
                d->m_startBeforeEnd = true;

                d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
                                        d->m_selectionEnd.handle(), d->m_endOffset );
                emitSelectionChanged();
                return true;
            }
        }
        d->m_findPos = -1;

        NodeImpl *next;

        if ( forward )
        {
          next = d->m_findNode->firstChild();

          if(!next) next = d->m_findNode->nextSibling();
          while(d->m_findNode && !next) {
              d->m_findNode = d->m_findNode->parentNode();
              if( d->m_findNode ) {
                  next = d->m_findNode->nextSibling();
              }
          }
        }
        else
        {
          next = d->m_findNode->lastChild();

          if (!next ) next = d->m_findNode->previousSibling();
          while ( d->m_findNode && !next )
          {
            d->m_findNode = d->m_findNode->parentNode();
            if( d->m_findNode )
            {
              next = d->m_findNode->previousSibling();
            }
          }
        }

        d->m_findNode = next;
        if(!d->m_findNode) return false;
    }
}


void KHTMLPart::slotFind()
{
  KParts::ReadOnlyPart *part = currentFrame();
  if (!part)
    return;
  if (!part->inherits("KHTMLPart") )
  {
      kdError(6000) << "slotFind: part is a " << part->className() << ", can't do a search into it" << endl;
      return;
  }
  static_cast<KHTMLPart *>( part )->findText();
}

void KHTMLPart::slotFindNext()
{
  KParts::ReadOnlyPart *part = currentFrame();
  if (!part)
    return;
  if (!part->inherits("KHTMLPart") )
  {
      kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
      return;
  }
  static_cast<KHTMLPart *>( part )->findTextNext();
}

void KHTMLPart::slotFindPrev()
{
  KParts::ReadOnlyPart *part = currentFrame();
  if (!part)
    return;
  if (!part->inherits("KHTMLPart") )
  {
      kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
      return;
  }
  static_cast<KHTMLPart *>( part )->findTextNext( true ); // reverse
}

void KHTMLPart::slotFindDone()
{
  // ### remove me
}

void KHTMLPart::slotFindAheadText()
{
#ifndef KHTML_NO_TYPE_AHEAD_FIND
  KParts::ReadOnlyPart *part = currentFrame();
  if (!part)
    return;
  if (!part->inherits("KHTMLPart") )
  {
      kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
      return;
  }
  static_cast<KHTMLPart *>( part )->view()->startFindAhead( false );
#endif // KHTML_NO_TYPE_AHEAD_FIND
}

void KHTMLPart::slotFindAheadLink()
{
#ifndef KHTML_NO_TYPE_AHEAD_FIND
  KParts::ReadOnlyPart *part = currentFrame();
  if (!part)
    return;
  if (!part->inherits("KHTMLPart") )
  {
      kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
      return;
  }
  static_cast<KHTMLPart *>( part )->view()->startFindAhead( true );
#endif // KHTML_NO_TYPE_AHEAD_FIND
}

void KHTMLPart::enableFindAheadActions( bool enable )
{
  // only the topmost one has shortcuts
  KHTMLPart* p = this;
  while( p->parentPart())
    p = p->parentPart();
  p->d->m_paFindAheadText->setEnabled( enable );
  p->d->m_paFindAheadLinks->setEnabled( enable );
}

void KHTMLPart::slotFindDialogDestroyed()
{
  d->m_lastFindState.options = d->m_findDialog->options();
  d->m_lastFindState.history = d->m_findDialog->findHistory();
  d->m_findDialog->deleteLater();
  d->m_findDialog = 0L;
}

02987 void KHTMLPart::findText()
{
  // First do some init to make sure we can search in this frame
  if ( !d->m_doc )
    return;

  // Raise if already opened
  if ( d->m_findDialog )
  {
    KWin::activateWindow( d->m_findDialog->winId() );
    return;
  }

  // The lineedit of the dialog would make khtml lose its selection, otherwise
#ifndef QT_NO_CLIPBOARD
  disconnect( kapp->clipboard(), SIGNAL(selectionChanged()), this, SLOT(slotClearSelection()) );
#endif

  // Now show the dialog in which the user can choose options.
  d->m_findDialog = new KFindDialog( false /*non-modal*/, widget(), "khtmlfind" );
  d->m_findDialog->setHasSelection( hasSelection() );
  d->m_findDialog->setHasCursor( d->m_findNode != 0 );
  if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
    d->m_lastFindState.options |= KFindDialog::FromCursor;

  // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
  d->m_findDialog->setFindHistory( d->m_lastFindState.history );
  d->m_findDialog->setOptions( d->m_lastFindState.options );

  d->m_lastFindState.options = -1; // force update in findTextNext
  d->m_lastFindState.last_dir = -1;

  d->m_findDialog->show();
  connect( d->m_findDialog, SIGNAL(okClicked()), this, SLOT(slotFindNext()) );
  connect( d->m_findDialog, SIGNAL(finished()), this, SLOT(slotFindDialogDestroyed()) );

  findText( d->m_findDialog->pattern(), 0 /*options*/, widget(), d->m_findDialog );
}

03026 void KHTMLPart::findText( const QString &str, long options, QWidget *parent, KFindDialog *findDialog )
{
  // First do some init to make sure we can search in this frame
  if ( !d->m_doc )
    return;

#ifndef QT_NO_CLIPBOARD
  connect( kapp->clipboard(), SIGNAL(selectionChanged()), SLOT(slotClearSelection()) );
#endif

  // Create the KFind object
  delete d->m_find;
  d->m_find = new KFind( str, options, parent, findDialog );
  d->m_find->closeFindNextDialog(); // we use KFindDialog non-modal, so we don't want other dlg popping up
  connect( d->m_find, SIGNAL( highlight( const QString &, int, int ) ),
           this, SLOT( slotHighlight( const QString &, int, int ) ) );
  //connect(d->m_find, SIGNAL( findNext() ),
  //        this, SLOT( slotFindNext() ) );

  if ( !findDialog )
  {
    d->m_lastFindState.options = options;
    initFindNode( options & KFindDialog::SelectedText,
                  options & KFindDialog::FindBackwards,
                  options & KFindDialog::FromCursor );
  }
}

03054 bool KHTMLPart::findTextNext()
{
  return findTextNext( false );
}

// New method
03060 bool KHTMLPart::findTextNext( bool reverse )
{
  if (!d->m_find)
  {
    // We didn't show the find dialog yet, let's do it then (#49442)
    findText();
    return false;
  }

  view()->updateFindAheadTimeout();
  long options = 0;
  if ( d->m_findDialog ) // 0 when we close the dialog
  {
    if ( d->m_find->pattern() != d->m_findDialog->pattern() ) {
      d->m_find->setPattern( d->m_findDialog->pattern() );
      d->m_find->resetCounts();
    }
    options = d->m_findDialog->options();
    if ( d->m_lastFindState.options != options )
    {
      d->m_find->setOptions( options );

      if ( options & KFindDialog::SelectedText )
        Q_ASSERT( hasSelection() );

      long difference = d->m_lastFindState.options ^ options;
      if ( difference & (KFindDialog::SelectedText | KFindDialog::FromCursor ) )
      {
          // Important options changed -> reset search range
        (void) initFindNode( options & KFindDialog::SelectedText,
                             options & KFindDialog::FindBackwards,
                             options & KFindDialog::FromCursor );
      }
      d->m_lastFindState.options = options;
    }
  } else
    options = d->m_lastFindState.options;
  if( reverse )
    options = options ^ KFindDialog::FindBackwards;
  if( d->m_find->options() != options )
    d->m_find->setOptions( options );

  // Changing find direction. Start and end nodes must be switched.
  // Additionally since d->m_findNode points after the last node
  // that was searched, it needs to be "after" it in the opposite direction.
  if( d->m_lastFindState.last_dir != -1
      && bool( d->m_lastFindState.last_dir ) != bool( options & KFindDialog::FindBackwards ))
  {
    qSwap( d->m_findNodeEnd, d->m_findNodeStart );
    qSwap( d->m_findPosEnd, d->m_findPosStart );
    qSwap( d->m_findNode, d->m_findNodePrevious );
    // d->m_findNode now point at the end of the last searched line - advance one node
    khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
    khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
    if ( obj == end )
      obj = 0L;
    else
    {
      do {
        obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
      } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
    }
    if ( obj )
      d->m_findNode = obj->element();
    else
      d->m_findNode = 0;
  }
  d->m_lastFindState.last_dir = ( options & KFindDialog::FindBackwards ) ? 1 : 0;

  KFind::Result res = KFind::NoMatch;
  khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
  khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
  khtml::RenderTextArea *tmpTextArea=0L;
  //kdDebug(6050) << k_funcinfo << "obj=" << obj << " end=" << end << endl;
  while( res == KFind::NoMatch )
  {
    if ( d->m_find->needData() )
    {
      if ( !obj ) {
        //kdDebug(6050) << k_funcinfo << "obj=0 -> done" << endl;
        break; // we're done
      }
      //kdDebug(6050) << k_funcinfo << " gathering data" << endl;
      // First make up the QString for the current 'line' (i.e. up to \n)
      // We also want to remember the DOMNode for every portion of the string.
      // We store this in an index->node list.

      d->m_stringPortions.clear();
      bool newLine = false;
      QString str;
      DOM::NodeImpl* lastNode = d->m_findNode;
      while ( obj && !newLine )
      {
        // Grab text from render object
        QString s;
        bool renderAreaText = obj->parent() && (QCString(obj->parent()->renderName())== "RenderTextArea");
        bool renderLineText = (QCString(obj->renderName())== "RenderLineEdit");
        if ( renderAreaText )
        {
          khtml::RenderTextArea *parent= static_cast<khtml::RenderTextArea *>(obj->parent());
          s = parent->text();
          s = s.replace(0xa0, ' ');
          tmpTextArea = parent;
        }
        else if ( renderLineText )
        {
          khtml::RenderLineEdit *parentLine= static_cast<khtml::RenderLineEdit *>(obj);
          if (parentLine->widget()->echoMode() == QLineEdit::Normal)
            s = parentLine->widget()->text();
          s = s.replace(0xa0, ' ');
        }
        else if ( obj->isText() )
        {
          bool isLink = false;

          // checks whether the node has a <A> parent
          if ( options & FindLinksOnly )
          {
            DOM::NodeImpl *parent = obj->element();
            while ( parent )
            {
              if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
              {
                isLink = true;
                break;
              }
              parent = parent->parentNode();
            }
          }
          else
          {
            isLink = true;
          }

          if ( isLink && obj->parent()!=tmpTextArea )
          {
            s = static_cast<khtml::RenderText *>(obj)->data().string();
            s = s.replace(0xa0, ' ');
          }
        }
        else if ( obj->isBR() )
          s = '\n';
        else if ( !obj->isInline() && !str.isEmpty() )
          s = '\n';

        if ( lastNode == d->m_findNodeEnd )
          s.truncate( d->m_findPosEnd );
        if ( !s.isEmpty() )
        {
          newLine = s.find( '\n' ) != -1; // did we just get a newline?
          if( !( options & KFindDialog::FindBackwards ))
          {
            //kdDebug(6050) << "StringPortion: " << index << "-" << index+s.length()-1 << " -> " << lastNode << endl;
            d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( str.length(), lastNode ) );
            str += s;
          }
          else // KFind itself can search backwards, so str must not be built backwards
          {
            for( QValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
                 it != d->m_stringPortions.end();
                 ++it )
                (*it).index += s.length();
            d->m_stringPortions.prepend( KHTMLPartPrivate::StringPortion( 0, lastNode ) );
            str.prepend( s );
          }
        }
        // Compare obj and end _after_ we processed the 'end' node itself
        if ( obj == end )
          obj = 0L;
        else
        {
          // Move on to next object (note: if we found a \n already, then obj (and lastNode)
          // will point to the _next_ object, i.e. they are in advance.
          do {
            // We advance until the next RenderObject that has a NodeImpl as its element().
            // Otherwise (if we keep the 'last node', and it has a '\n') we might be stuck
            // on that object forever...
            obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
          } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
        }
        if ( obj )
          lastNode = obj->element();
        else
          lastNode = 0;
      } // end while
      //kdDebug()<<" str : "<<str<<endl;
      if ( !str.isEmpty() )
      {
        d->m_find->setData( str, d->m_findPos );
      }

      d->m_findPos = -1; // not used during the findnext loops. Only during init.
      d->m_findNodePrevious = d->m_findNode;
      d->m_findNode = lastNode;
    }
    if ( !d->m_find->needData() ) // happens if str was empty
    {
      // Let KFind inspect the text fragment, and emit highlighted if a match is found
      res = d->m_find->find();
    }
  } // end while

  if ( res == KFind::NoMatch ) // i.e. we're done
  {
    kdDebug() << "No more matches." << endl;
    if ( !(options & FindNoPopups) && d->m_find->shouldRestart() )
    {
      //kdDebug(6050) << "Restarting" << endl;
      initFindNode( false, options & KFindDialog::FindBackwards, false );
      findTextNext( reverse );
    }
    else // really done
    {
      //kdDebug(6050) << "Finishing" << endl;
      //delete d->m_find;
      //d->m_find = 0L;
      initFindNode( false, options & KFindDialog::FindBackwards, false );
      d->m_find->resetCounts();
      slotClearSelection();
    }
    kdDebug() << "Dialog closed." << endl;
  }

  return res == KFind::Match;
}

03286 void KHTMLPart::slotHighlight( const QString& /*text*/, int index, int length )
{
  //kdDebug(6050) << "slotHighlight index=" << index << " length=" << length << endl;
  QValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
  const QValueList<KHTMLPartPrivate::StringPortion>::Iterator itEnd = d->m_stringPortions.end();
  QValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
  // We stop at the first portion whose index is 'greater than', and then use the previous one
  while ( it != itEnd && (*it).index <= index )
  {
    prev = it;
    ++it;
  }
  Q_ASSERT ( prev != itEnd );
  DOM::NodeImpl* node = (*prev).node;
  Q_ASSERT( node );

  d->m_selectionStart = node;
  d->m_startOffset = index - (*prev).index;

  khtml::RenderObject* obj = node->renderer();
  khtml::RenderTextArea *parent = 0L;
  khtml::RenderLineEdit *parentLine = 0L;
  bool renderLineText =false;

  QRect highlightedRect;
  bool renderAreaText =false;
  Q_ASSERT( obj );
  if ( obj )
  {
    int x = 0, y = 0;
    renderAreaText = (QCString(obj->parent()->renderName())== "RenderTextArea");
    renderLineText = (QCString(obj->renderName())== "RenderLineEdit");


    if( renderAreaText )
      parent= static_cast<khtml::RenderTextArea *>(obj->parent());
    if ( renderLineText )
      parentLine= static_cast<khtml::RenderLineEdit *>(obj);
    if ( !renderLineText )
      //if (static_cast<khtml::RenderText *>(node->renderer())
      //    ->posOfChar(d->m_startOffset, x, y))
      {
        int dummy;
        static_cast<khtml::RenderText *>(node->renderer())
          ->caretPos( d->m_startOffset, false, x, y, dummy, dummy ); // more precise than posOfChar
        //kdDebug(6050) << "topleft: " << x << "," << y << endl;
        if ( x != -1 || y != -1 )
        {
          int gox = d->m_view->contentsX();
          if (x+50 > d->m_view->contentsX() + d->m_view->visibleWidth())
              gox = x - d->m_view->visibleWidth() + 50;
          if (x-10 < d->m_view->contentsX())
              gox = x - d->m_view->visibleWidth() - 10;
          if (gox < 0) gox = 0;
          d->m_view->setContentsPos(gox, y-50);
          highlightedRect.setTopLeft( d->m_view->mapToGlobal(QPoint(x, y)) );
        }
      }
  }
  // Now look for end node
  it = prev; // no need to start from beginning again
  while ( it != itEnd && (*it).index < index + length )
  {
    prev = it;
    ++it;
  }
  Q_ASSERT ( prev != itEnd );

  d->m_selectionEnd = (*prev).node;
  d->m_endOffset = index + length - (*prev).index;
  d->m_startBeforeEnd = true;

  // if the selection is limited to a single link, that link gets focus
  if(d->m_selectionStart == d->m_selectionEnd)
  {
    bool isLink = false;

    // checks whether the node has a <A> parent
    DOM::NodeImpl *parent = d->m_selectionStart.handle();
    while ( parent )
    {
      if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
      {
        isLink = true;
        break;
      }
      parent = parent->parentNode();
    }

    if(isLink == true)
    {
      d->m_doc->setFocusNode( parent );
    }
  }

#if 0
  kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
    d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
  it = d->m_stringPortions.begin();
  for ( ; it != d->m_stringPortions.end() ; ++it )
    kdDebug(6050) << "  StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
#endif
  if( renderAreaText )
  {
    if( parent )
      parent->highLightWord( length, d->m_endOffset-length );
  }
  else if ( renderLineText )
  {
    if( parentLine )
      parentLine->highLightWord( length, d->m_endOffset-length );
  }
  else
  {
    d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
                            d->m_selectionEnd.handle(), d->m_endOffset );
    if (d->m_selectionEnd.handle()->renderer() )
    {
      int x, y, height, dummy;
      static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
          ->caretPos( d->m_endOffset, false, x, y, dummy, height ); // more precise than posOfChar
      //kdDebug(6050) << "bottomright: " << x << "," << y+height << endl;
      if ( x != -1 || y != -1 )
      {
        // if ( static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
        //  ->posOfChar(d->m_endOffset-1, x, y))
        highlightedRect.setBottomRight( d->m_view->mapToGlobal( QPoint(x, y+height) ) );
      }
    }
  }
  emitSelectionChanged();

  // make the finddialog move away from the selected area
  if ( d->m_findDialog && !highlightedRect.isNull() )
  {
    highlightedRect.moveBy( -d->m_view->contentsX(), -d->m_view->contentsY() );
    //kdDebug(6050) << "avoiding " << highlightedRect << endl;
    KDialog::avoidArea( d->m_findDialog, highlightedRect );
  }
}

03427 QString KHTMLPart::selectedTextAsHTML() const
{
  if(!hasSelection()) {
    kdDebug() << "selectedTextAsHTML(): selection is not valid.  Returning empty selection" << endl;
    return QString::null;
  }
  if(d->m_startOffset < 0 || d->m_endOffset <0) {
    kdDebug() << "invalid values for end/startOffset " << d->m_startOffset << " " << d->m_endOffset << endl;
    return QString::null;
  }
  DOM::Range r = selection();
  if(r.isNull() || r.isDetached())
    return QString::null;
  int exceptioncode = 0; //ignore the result
  return r.handle()->toHTML(exceptioncode).string();
}

03444 QString KHTMLPart::selectedText() const
{
  bool hasNewLine = true;
  bool seenTDTag = false;
  QString text;
  DOM::Node n = d->m_selectionStart;
  while(!n.isNull()) {
      if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
        DOM::DOMStringImpl *dstr = static_cast<DOM::TextImpl*>(n.handle())->renderString();
        QString str(dstr->s, dstr->l);
      if(!str.isEmpty()) {
          if(seenTDTag) {
          text += "  ";
          seenTDTag = false;
        }
          hasNewLine = false;
          if(n == d->m_selectionStart && n == d->m_selectionEnd)
            text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
          else if(n == d->m_selectionStart)
            text = str.mid(d->m_startOffset);
          else if(n == d->m_selectionEnd)
            text += str.left(d->m_endOffset);
          else
            text += str;
      }
      }
      else {
        // This is our simple HTML -> ASCII transformation:
        unsigned short id = n.elementId();
        switch(id) {
        case ID_TEXTAREA:
          text += static_cast<HTMLTextAreaElementImpl*>(n.handle())->value().string();
          break;
        case ID_INPUT:
            if (static_cast<HTMLInputElementImpl*>(n.handle())->inputType() != HTMLInputElementImpl::PASSWORD)
            text += static_cast<HTMLInputElementImpl*>(n.handle())->value().string();
          break;
        case ID_SELECT:
          text += static_cast<HTMLSelectElementImpl*>(n.handle())->value().string();
          break;
          case ID_BR:
            text += "\n";
            hasNewLine = true;
            break;
          case ID_IMG:
          text += static_cast<HTMLImageElementImpl*>(n.handle())->altText().string();
          break;
          case ID_TD:
          break;
          case ID_TH:
          case ID_HR:
          case ID_OL:
          case ID_UL:
          case ID_LI:
          case ID_DD:
          case ID_DL:
          case ID_DT:
          case ID_PRE:
          case ID_BLOCKQUOTE:
          case ID_DIV:
            if (!hasNewLine)
               text += "\n";
            hasNewLine = true;
            break;
          case ID_P:
          case ID_TR:
          case ID_H1:
          case ID_H2:
          case ID_H3:
          case ID_H4:
          case ID_H5:
          case ID_H6:
            if (!hasNewLine)
               text += "\n";
//            text += "\n";
            hasNewLine = true;
            break;
        }
      }
      if(n == d->m_selectionEnd) break;
      DOM::Node next = n.firstChild();
      if(next.isNull()) next = n.nextSibling();
      while( next.isNull() && !n.parentNode().isNull() ) {
        n = n.parentNode();
        next = n.nextSibling();
        unsigned short id = n.elementId();
        switch(id) {
          case ID_TD:
          seenTDTag = true; //Add two spaces after a td if then followed by text.
          break;
          case ID_TH:
          case ID_HR:
          case ID_OL:
          case ID_UL:
          case ID_LI:
          case ID_DD:
          case ID_DL:
          case ID_DT:
          case ID_PRE:
          case ID_BLOCKQUOTE:
          case ID_DIV:
          seenTDTag = false;
            if (!hasNewLine)
               text += "\n";
            hasNewLine = true;
            break;
          case ID_P:
          case ID_TR:
          case ID_H1:
          case ID_H2:
          case ID_H3:
          case ID_H4:
          case ID_H5:
          case ID_H6:
            if (!hasNewLine)
               text += "\n";
//            text += "\n";
            hasNewLine = true;
            break;
        }
      }

      n = next;
    }

    if(text.isEmpty())
        return QString::null;

    int start = 0;
    int end = text.length();

    // Strip leading LFs
    while ((start < end) && (text[start] == '\n'))
       ++start;

    // Strip excessive trailing LFs
    while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
       --end;

    return text.mid(start, end-start);
}

03586 bool KHTMLPart::hasSelection() const
{
  if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
      return false;
  if ( d->m_selectionStart == d->m_selectionEnd &&
       d->m_startOffset == d->m_endOffset )
      return false; // empty
  return true;
}

03596 DOM::Range KHTMLPart::selection() const
{
    if( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
        return DOM::Range();
    DOM::Range r = document().createRange();
    RangeImpl *rng = r.handle();
    int exception = 0;
    NodeImpl *n = d->m_selectionStart.handle();
    if(!n->parentNode() ||
       !n->renderer() ||
       (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
        rng->setStart( n, d->m_startOffset, exception );
      if(exception) {
          kdDebug(6000) << "1 -selection() threw the exception " << exception << ".  Returning empty range." << endl;
          return DOM::Range();
      }
    } else {
        int o_start = 0;
        while ((n = n->previousSibling()))
            o_start++;
      rng->setStart( d->m_selectionStart.parentNode().handle(), o_start + d->m_startOffset, exception );
      if(exception) {
          kdDebug(6000) << "2 - selection() threw the exception " << exception << ".  Returning empty range." << endl;
          return DOM::Range();
      }

    }

    n = d->m_selectionEnd.handle();
    if(!n->parentNode() ||
       !n->renderer() ||
       (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {

      rng->setEnd( n, d->m_endOffset, exception );
      if(exception) {
          kdDebug(6000) << "3 - selection() threw the exception " << exception << ".  Returning empty range." << endl;
          return DOM::Range();
      }

    } else {
        int o_end = 0;
        while ((n = n->previousSibling()))
            o_end++;
      rng->setEnd( d->m_selectionEnd.parentNode().handle(), o_end + d->m_endOffset, exception);
      if(exception) {
          kdDebug(6000) << "4 - selection() threw the exception " << exception << ".  Returning empty range." << endl;
          return DOM::Range();
      }

    }

    return r;
}

03650 void KHTMLPart::selection(DOM::Node &s, long &so, DOM::Node &e, long &eo) const
{
    s = d->m_selectionStart;
    so = d->m_startOffset;
    e = d->m_selectionEnd;
    eo = d->m_endOffset;
}

03658 void KHTMLPart::setSelection( const DOM::Range &r )
{
    // Quick-fix: a collapsed range shouldn't select the whole node.
    // The real problem is in RenderCanvas::setSelection though (when index==0 the whole node is selected).
    if ( r.collapsed() )
        slotClearSelection();
    else {
        d->m_selectionStart = r.startContainer();
        d->m_startOffset = r.startOffset();
        d->m_selectionEnd = r.endContainer();
        d->m_endOffset = r.endOffset();
        d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
                               d->m_selectionEnd.handle(),d->m_endOffset);
#ifndef KHTML_NO_CARET
        bool v = d->m_view->placeCaret();
        emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
#endif
    }
}

03678 void KHTMLPart::slotClearSelection()
{
    bool hadSelection = hasSelection();
#ifndef KHTML_NO_CARET
    //kdDebug(6000) << "d->m_selectionStart " << d->m_selectionStart.handle()
    //            << " d->m_selectionEnd " << d->m_selectionEnd.handle() << endl;
    // nothing, leave selection parameters as is
#else
    d->m_selectionStart = 0;
    d->m_startOffset = 0;
    d->m_selectionEnd = 0;
    d->m_endOffset = 0;
#endif
    if ( d->m_doc ) d->m_doc->clearSelection();
    if ( hadSelection )
      emitSelectionChanged();
#ifndef KHTML_NO_CARET
    bool v = d->m_view->placeCaret();
    emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
#endif
}

void KHTMLPart::resetHoverText()
{
   if( !d->m_overURL.isEmpty() ) // Only if we were showing a link
   {
     d->m_overURL = d->m_overURLTarget = QString::null;
     emit onURL( QString::null );
     // revert to default statusbar text
     setStatusBarText(QString::null, BarHoverText);
     emit d->m_extension->mouseOverInfo(0);
  }
}

void KHTMLPart::overURL( const QString &url, const QString &target, bool /*shiftPressed*/ )
{
  KURL u = completeURL(url);

  // special case for <a href="">
  if ( url.isEmpty() )
    u.setFileName( url );

  emit onURL( url );

  if ( url.isEmpty() ) {
    setStatusBarText(u.htmlURL(), BarHoverText);
    return;
  }

  if (url.find( QString::fromLatin1( "javascript:" ),0, false ) == 0 ) {
    QString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
    jscode = KStringHandler::rsqueeze( jscode, 80 ); // truncate if too long
    if (url.startsWith("javascript:window.open"))
      jscode += i18n(" (In new window)");
    setStatusBarText( QStyleSheet::escape( jscode ), BarHoverText );
    return;
  }

  KFileItem item(u, QString::null, KFileItem::Unknown);
  emit d->m_extension->mouseOverInfo(&item);

  QString com;

  KMimeType::Ptr typ = KMimeType::findByURL( u );

  if ( typ )
    com = typ->comment( u, false );

  if ( !u.isValid() ) {
    setStatusBarText(u.htmlURL(), BarHoverText);
    return;
  }

  if ( u.isLocalFile() )
  {
    // TODO : use KIO::stat() and create a KFileItem out of its result,
    // to use KFileItem::statusBarText()
    QCString path = QFile::encodeName( u.path() );

    struct stat buff;
    bool ok = !stat( path.data(), &buff );

    struct stat lbuff;
    if (ok) ok = !lstat( path.data(), &lbuff );

    QString text = u.htmlURL();
    QString text2 = text;

    if (ok && S_ISLNK( lbuff.st_mode ) )
    {
      QString tmp;
      if ( com.isNull() )
        tmp = i18n( "Symbolic Link");
      else
        tmp = i18n("%1 (Link)").arg(com);
      char buff_two[1024];
      text += " -> ";
      int n = readlink ( path.data(), buff_two, 1022);
      if (n == -1)
      {
        text2 += "  ";
        text2 += tmp;
        setStatusBarText(text2, BarHoverText);
        return;
      }
      buff_two[n] = 0;

      text += buff_two;
      text += "  ";
      text += tmp;
    }
    else if ( ok && S_ISREG( buff.st_mode ) )
    {
      if (buff.st_size < 1024)
        text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
      else
      {
        float d = (float) buff.st_size/1024.0;
        text = i18n("%2 (%1 K)").arg(KGlobal::locale()->formatNumber(d, 2)).arg(text2); // was %.2f
      }
      text += "  ";
      text += com;
    }
    else if ( ok && S_ISDIR( buff.st_mode ) )
    {
      text += "  ";
      text += com;
    }
    else
    {
      text += "  ";
      text += com;
    }
    setStatusBarText(text, BarHoverText);
  }
  else
  {
    QString extra;
    if (target.lower() == "_blank")
    {
      extra = i18n(" (In new window)");
    }
    else if (!target.isEmpty() &&
             (target.lower() != "_top") &&
             (target.lower() != "_self") &&
             (target.lower() != "_parent"))
    {
      KHTMLPart *p = this;
      while (p->parentPart())
          p = p->parentPart();
      if (!p->frameExists(target))
        extra = i18n(" (In new window)");
      else
        extra = i18n(" (In other frame)");
    }

    if (u.protocol() == QString::fromLatin1("mailto")) {
      QString mailtoMsg /* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
      mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
      QStringList queries = QStringList::split('&', u.query().mid(1));
      QStringList::Iterator it = queries.begin();
      const QStringList::Iterator itEnd = queries.end();
      for (; it != itEnd; ++it)
        if ((*it).startsWith(QString::fromLatin1("subject=")))
          mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
        else if ((*it).startsWith(QString::fromLatin1("cc=")))
          mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
        else if ((*it).startsWith(QString::fromLatin1("bcc=")))
          mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
      mailtoMsg = QStyleSheet::escape(mailtoMsg);
      mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), QString::null);
      setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
      return;
    }
   // Is this check necessary at all? (Frerich)
#if 0
    else if (u.protocol() == QString::fromLatin1("http")) {
        DOM::Node hrefNode = nodeUnderMouse().parentNode();
        while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
          hrefNode = hrefNode.parentNode();

        if (!hrefNode.isNull()) {
          DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
          if (!hreflangNode.isNull()) {
            QString countryCode = hreflangNode.nodeValue().string().lower();
            // Map the language code to an appropriate country code.
            if (countryCode == QString::fromLatin1("en"))
              countryCode = QString::fromLatin1("gb");
            QString flagImg = QString::fromLatin1("<img src=%1>").arg(
                locate("locale", QString::fromLatin1("l10n/")
                + countryCode
                + QString::fromLatin1("/flag.png")));
            emit setStatusBarText(flagImg + u.prettyURL() + extra);
          }
        }
      }
#endif
    setStatusBarText(u.htmlURL() + extra, BarHoverText);
  }
}

//
// This executes in the active part on a click or other url selection action in
// that active part.
//
void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target, KParts::URLArgs args )
{
  // The member var is so that slotRedirection still calls the virtual urlSelected
  // but is able to know if is opened a url. KDE4: just make urlSelected return a bool
  // and move the urlSelectedIntern code back here.
  d->m_urlSelectedOpenedURL = urlSelectedIntern( url, button, state, _target, args );
}

// Return value: true if an url was opened, false if not (e.g. error, or jumping to anchor)
bool KHTMLPart::urlSelectedIntern( const QString &url, int button, int state, const QString &_target, KParts::URLArgs args )
{
  bool hasTarget = false;

  QString target = _target;
  if ( target.isEmpty() && d->m_doc )
    target = d->m_doc->baseTarget();
  if ( !target.isEmpty() )
      hasTarget = true;

  if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
  {
    crossFrameExecuteScript( target, KURL::decode_string( url.mid( 11 ) ) );
    return false;
  }

  KURL cURL = completeURL(url);
  // special case for <a href="">  (IE removes filename, mozilla doesn't)
  if ( url.isEmpty() )
    cURL.setFileName( url ); // removes filename

  if ( !cURL.isValid() )
    // ### ERROR HANDLING
    return false;

  kdDebug(6050) << this << " urlSelected: complete URL:" << cURL.url() << " target=" << target << endl;

  if ( state & ControlButton )
  {
    args.setNewTab(true);
    emit d->m_extension->createNewWindow( cURL, args );
    return true;
  }

  if ( button == LeftButton && ( state & ShiftButton ) )
  {
    KIO::MetaData metaData;
    metaData["referrer"] = d->m_referrer;
    KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), cURL, metaData );
    return false;
  }

  if (!checkLinkSecurity(cURL,
                   i18n( "<qt>This untrusted page links to<BR><B>%1</B>.<BR>Do you want to follow the link?" ),
                   i18n( "Follow" )))
    return false;

  args.frameName = target;

  args.metaData().insert("main_frame_request",
                         parentPart() == 0 ? "TRUE":"FALSE");
  args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
  args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
  args.metaData().insert("PropagateHttpHeader", "true");
  args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
  args.metaData().insert("ssl_activate_warnings", "TRUE");

  if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" )
  {
    // unknown frame names should open in a new window.
    khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
    if ( frame )
    {
      args.metaData()["referrer"] = d->m_referrer;
      requestObject( frame, cURL, args );
      return true;
    }
  }

  if (!d->m_referrer.isEmpty() && !args.metaData().contains("referrer"))
    args.metaData()["referrer"] = d->m_referrer;


  if ( button == NoButton && (state & ShiftButton) && (state & ControlButton) )
  {
    emit d->m_extension->createNewWindow( cURL, args );
    return true;
  }

  if ( state & ShiftButton)
  {
    KParts::WindowArgs winArgs;
    winArgs.lowerWindow = true;
    KParts::ReadOnlyPart *newPart = 0;
    emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
    return true;
  }

  //If we're asked to open up an anchor in the current URL, in current window,
  //merely gotoanchor, and do not reload the new page. Note that this does
  //not apply if the URL is the same page, but without a ref
  if (cURL.hasRef() && (!hasTarget || target == "_self"))
  {
    KURL curUrl = this->url();
    if (urlcmp(cURL.url(), curUrl.url(),
              false,  // ignore trailing / diff, IE does, even if FFox doesn't
              true))  // don't care if the ref changes!
    {
      m_url = cURL;
      emit d->m_extension->openURLNotify();
      if ( !gotoAnchor( m_url.encodedHtmlRef()) )
        gotoAnchor( m_url.htmlRef() );
      emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
      return false; // we jumped, but we didn't open a URL
    }
  }

  if ( !d->m_bComplete && !hasTarget )
    closeURL();

  view()->viewport()->unsetCursor();
  emit d->m_extension->openURLRequest( cURL, args );
  return true;
}

04007 void KHTMLPart::slotViewDocumentSource()
{
  KURL url(m_url);
  bool isTempFile = false;
  if (!(url.isLocalFile()) && KHTMLPageCache::self()->isComplete(d->m_cacheId))
  {
     KTempFile sourceFile(QString::null, defaultExtension());
     if (sourceFile.status() == 0)
     {
        KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
        url = KURL();
        url.setPath(sourceFile.name());
        isTempFile = true;
     }
  }

  (void) KRun::runURL( url, QString::fromLatin1("text/plain"), isTempFile );
}

04026 void KHTMLPart::slotViewPageInfo()
{
  KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, WDestructiveClose);
  dlg->_close->setGuiItem(KStdGuiItem::close());

  if (d->m_doc)
     dlg->_title->setText(d->m_doc->title().string());

  // If it's a frame, set the caption to "Frame Information"
  if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
     dlg->setCaption(i18n("Frame Information"));
  }

  QString editStr = QString::null;

  if (!d->m_pageServices.isEmpty())
    editStr = i18n("   <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);

  QString squeezedURL = KStringHandler::csqueeze( url().prettyURL(), 80 );
  dlg->_url->setText("<a href=\"" + url().url() + "\">" + squeezedURL + "</a>" + editStr);
  if (lastModified().isEmpty())
  {
    dlg->_lastModified->hide();
    dlg->_lmLabel->hide();
  }
  else
    dlg->_lastModified->setText(lastModified());

  const QString& enc = encoding();
  if (enc.isEmpty()) {
    dlg->_eLabel->hide();
    dlg->_encoding->hide();
  } else {
    dlg->_encoding->setText(enc);
  }
  /* populate the list view now */
  const QStringList headers = QStringList::split("\n", d->m_httpHeaders);

  QStringList::ConstIterator it = headers.begin();
  const QStringList::ConstIterator itEnd = headers.end();

  for (; it != itEnd; ++it) {
    const QStringList header = QStringList::split(QRegExp(":[ ]+"), *it);
    if (header.count() != 2)
       continue;
    new QListViewItem(dlg->_headers, header[0], header[1]);
  }

  dlg->show();
  /* put no code here */
}


04079 void KHTMLPart::slotViewFrameSource()
{
  KParts::ReadOnlyPart *frame = currentFrame();
  if ( !frame )
    return;

  KURL url = frame->url();
  bool isTempFile = false;
  if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
  {
       long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;

       if (KHTMLPageCache::self()->isComplete(cacheId))
       {
           KTempFile sourceFile(QString::null, defaultExtension());
           if (sourceFile.status() == 0)
           {
               KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
               url = KURL();
               url.setPath(sourceFile.name());
               isTempFile = true;
           }
     }
  }

  (void) KRun::runURL( url, QString::fromLatin1("text/plain"), isTempFile );
}

04107 KURL KHTMLPart::backgroundURL() const
{
  // ### what about XML documents? get from CSS?
  if (!d->m_doc || !d->m_doc->isHTMLDocument())
    return KURL();

  QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();

  return KURL( m_url, relURL );
}

04118 void KHTMLPart::slotSaveBackground()
{
  KIO::MetaData metaData;
  metaData["referrer"] = d->m_referrer;
  KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save Background Image As"), backgroundURL(), metaData );
}

04125 void KHTMLPart::slotSaveDocument()
{
  KURL srcURL( m_url );

  if ( srcURL.fileName(false).isEmpty() )
    srcURL.setFileName( "index" + defaultExtension() );

  KIO::MetaData metaData;
  // Referre unknown?
  KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, "text/html", d->m_cacheId );
}

04137 void KHTMLPart::slotSecurity()
{
//   kdDebug( 6050 ) << "Meta Data:" << endl
//                   << d->m_ssl_peer_cert_subject
//                   << endl
//                   << d->m_ssl_peer_cert_issuer
//                   << endl
//                   << d->m_ssl_cipher
//                   << endl
//                   << d->m_ssl_cipher_desc
//                   << endl
//                   << d->m_ssl_cipher_version
//                   << endl
//                   << d->m_ssl_good_from
//                   << endl
//                   << d->m_ssl_good_until
//                   << endl
//                   << d->m_ssl_cert_state
//                   << endl;

  KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );

  if (d->m_bSecurityInQuestion)
        kid->setSecurityInQuestion(true);

  if (d->m_ssl_in_use) {
    KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
    if (x) {
       // Set the chain back onto the certificate
       const QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
       QPtrList<KSSLCertificate> ncl;

       ncl.setAutoDelete(true);
       QStringList::ConstIterator it = cl.begin();
       const QStringList::ConstIterator itEnd = cl.end();
       for (; it != itEnd; ++it) {
          KSSLCertificate* const y = KSSLCertificate::fromString((*it).local8Bit());
          if (y) ncl.append(y);
       }

       if (ncl.count() > 0)
          x->chain().setChain(ncl);

       kid->setup(x,
                  d->m_ssl_peer_ip,
                  m_url.url(),
                  d->m_ssl_cipher,
                  d->m_ssl_cipher_desc,
                  d->m_ssl_cipher_version,
                  d->m_ssl_cipher_used_bits.toInt(),
                  d->m_ssl_cipher_bits.toInt(),
                  (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
                  );
        kid->exec();
        delete x;
     } else kid->exec();
  } else kid->exec();
}

04196 void KHTMLPart::slotSaveFrame()
{
    KParts::ReadOnlyPart *frame = currentFrame();
    if ( !frame )
        return;

    KURL srcURL( frame->url() );

    if ( srcURL.fileName(false).isEmpty() )
        srcURL.setFileName( "index" + defaultExtension() );

    KIO::MetaData metaData;
    // Referrer unknown?
    KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save Frame As" ), srcURL, metaData, "text/html" );
}

04212 void KHTMLPart::slotSetEncoding()
{
  d->m_automaticDetection->setItemChecked( int( d->m_autoDetectLanguage ), false );
  d->m_paSetEncoding->popupMenu()->setItemChecked( 0, false );
  d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), true );

  QString enc = KGlobal::charsets()->encodingForName( d->m_manualDetection->currentText() );
  setEncoding( enc, true );
}

04222 void KHTMLPart::slotUseStylesheet()
{
  if (d->m_doc)
  {
    bool autoselect = (d->m_paUseStylesheet->currentItem() == 0);
    d->m_sheetUsed = autoselect ? QString() : d->m_paUseStylesheet->currentText();
    d->m_doc->updateStyleSelector();
  }
}

04232 void KHTMLPart::updateActions()
{
  bool frames = false;

  QValueList<khtml::ChildFrame*>::ConstIterator it = d->m_frames.begin();
  const QValueList<khtml::ChildFrame*>::ConstIterator end = d->m_frames.end();
  for (; it != end; ++it )
      if ( (*it)->m_type == khtml::ChildFrame::Frame )
      {
          frames = true;
          break;
      }

  d->m_paViewFrame->setEnabled( frames );
  d->m_paSaveFrame->setEnabled( frames );

  if ( frames )
    d->m_paFind->setText( i18n( "&Find in Frame..." ) );
  else
    d->m_paFind->setText( i18n( "&Find..." ) );

  KParts::Part *frame = 0;

  if ( frames )
    frame = currentFrame();

  bool enableFindAndSelectAll = true;

  if ( frame )
    enableFindAndSelectAll = frame->inherits( "KHTMLPart" );

  d->m_paFind->setEnabled( enableFindAndSelectAll );
  d->m_paSelectAll->setEnabled( enableFindAndSelectAll );

  bool enablePrintFrame = false;

  if ( frame )
  {
    QObject *ext = KParts::BrowserExtension::childObject( frame );
    if ( ext )
      enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
  }

  d->m_paPrintFrame->setEnabled( enablePrintFrame );

  QString bgURL;

  // ### frames
  if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
    bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();

  d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );

  if ( d->m_paDebugScript )
    d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
}

KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
    const ConstFrameIt end = d->m_objects.end();
    for(ConstFrameIt it = d->m_objects.begin(); it != end; ++it )
        if ((*it)->m_frame == frame)
            return (*it)->m_liveconnect;
    return 0L;
}

bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
                              const QStringList &params, bool isIFrame )
{
  //kdDebug( 6050 ) << this << " requestFrame( ..., " << url << ", " << frameName << " )" << endl;
  FrameIt it = d->m_frames.find( frameName );
  if ( it == d->m_frames.end() )
  {
    khtml::ChildFrame * child = new khtml::ChildFrame;
    //kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
    child->m_name = frameName;
    it = d->m_frames.append( child );
  }

  (*it)->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
  (*it)->m_frame = frame;
  (*it)->m_params = params;

  // Support for <frame src="javascript:string">
  if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
  {
    if ( processObjectRequest(*it, KURL("about:blank"), QString("text/html") ) ) {
      KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>((*it)->m_part));
      
      // See if we want to replace content with javascript: output..
      QVariant res = p->executeScript( DOM::Node(), KURL::decode_string( url.right( url.length() - 11) ) );
      if ( res.type() == QVariant::String ) {
        p->begin();
        p->write( res.asString() );
        p->end();
      }
      return true;
    }
    return false;
  }
  KURL u = url.isEmpty() ? KURL() : completeURL( url );
  return requestObject( *it, u );
}

04335 QString KHTMLPart::requestFrameName()
{
   return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
}

bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
                               const QStringList &params )
{
  //kdDebug( 6005 ) << "KHTMLPart::requestObject " << this << " frame=" << frame << endl;
  khtml::ChildFrame *child = new khtml::ChildFrame;
  FrameIt it = d->m_objects.append( child );
  (*it)->m_frame = frame;
  (*it)->m_type = khtml::ChildFrame::Object;
  (*it)->m_params = params;

  KParts::URLArgs args;
  args.serviceType = serviceType;
  if (!requestObject( *it, completeURL( url ), args ) && !(*it)->m_run) {
      (*it)->m_bCompleted = true;
      return false;
  }
  return true;
}

bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
{
  if (!checkLinkSecurity(url))
  {
    kdDebug(6005) << this << " KHTMLPart::requestObject checkLinkSecurity refused" << endl;
    return false;
  }
  if ( child->m_bPreloaded )
  {
    kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
    if ( child->m_frame && child->m_part )
      child->m_frame->setWidget( child->m_part->widget() );

    child->m_bPreloaded = false;
    return true;
  }

  //kdDebug(6005) << "KHTMLPart::requestObject child=" << child << " child->m_part=" << child->m_part << endl;

  KParts::URLArgs args( _args );

  if ( child->m_run )
    child->m_run->abort();

  if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
    args.serviceType = child->m_serviceType;

  child->m_args = args;
  child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
  child->m_serviceName = QString::null;
  if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
    child->m_args.metaData()["referrer"] = d->m_referrer;

  child->m_args.metaData().insert("PropagateHttpHeader", "true");
  child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
  child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
  child->m_args.metaData().insert("main_frame_request",
                                  parentPart() == 0 ? "TRUE":"FALSE");
  child->m_args.metaData().insert("ssl_was_in_use",
                                  d->m_ssl_in_use ? "TRUE":"FALSE");
  child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
  child->m_args.metaData().insert("cross-domain", toplevelURL().url());

  // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
  if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
    args.serviceType = QString::fromLatin1( "text/html" );

  if ( args.serviceType.isEmpty() ) {
    kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << endl;
    child->m_run = new KHTMLRun( this, child, url, child->m_args, true );
    d->m_bComplete = false; // ensures we stop it in checkCompleted...
    return false;
  } else {
    return processObjectRequest( child, url, args.serviceType );
  }
}

bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
{
  //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;

  // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
  // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
  // though -> the reference becomes invalid -> crash is likely
  KURL url( _url );

  // khtmlrun called us this way to indicate a loading error
  if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
  {
      child->m_bCompleted = true;
      checkCompleted();
      return true;
  }

  if (child->m_bNotify)
  {
      child->m_bNotify = false;
      if ( !child->m_args.lockHistory() )
          emit d->m_extension->openURLNotify();
  }

  if ( child->m_serviceType != mimetype || !child->m_part )
  {
    // Before attempting to load a part, check if the user wants that.
    // Many don't like getting ZIP files embedded.
    // However we don't want to ask for flash and other plugin things..
    if ( child->m_type != khtml::ChildFrame::Object )
    {
      QString suggestedFilename;
      if ( child->m_run )
        suggestedFilename = child->m_run->suggestedFilename();

      KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave(
        url, mimetype, suggestedFilename  );
      switch( res ) {
      case KParts::BrowserRun::Save:
        KHTMLPopupGUIClient::saveURL( widget(), i18n( "Save As" ), url, child->m_args.metaData(), QString::null, 0, suggestedFilename);
        // fall-through
      case KParts::BrowserRun::Cancel:
        child->m_bCompleted = true;
        checkCompleted();
        return true; // done
      default: // Open
        break;
      }
    }

    QStringList dummy; // the list of servicetypes handled by the part is now unused.
    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 );

    if ( !part )
    {
        if ( child->m_frame )
          if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
            return true; // we succeeded after all (a fallback was used)

        checkEmitLoadEvent();
        return false;
    }

    //CRITICAL STUFF
    if ( child->m_part )
    {
      if (!::qt_cast<KHTMLPart*>(child->m_part) && child->m_jscript)
          child->m_jscript->clear();
      partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
      delete (KParts::ReadOnlyPart *)child->m_part;
      if (child->m_liveconnect) {
        disconnect(child->m_liveconnect, SIGNAL(partEvent(const unsigned long, const QString &, const KParts::LiveConnectExtension::ArgList &)), child, SLOT(liveConnectEvent(const unsigned long, const QString&, const KParts::LiveConnectExtension::ArgList &)));
        child->m_liveconnect = 0L;
      }
    }

    child->m_serviceType = mimetype;
    if ( child->m_frame  && part->widget() )
      child->m_frame->setWidget( part->widget() );

    if ( child->m_type != khtml::ChildFrame::Object )
      partManager()->addPart( part, false );
//  else
//      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;

    child->m_part = part;

    if (::qt_cast<KHTMLPart*>(part)) {
      static_cast<KHTMLPart*>(part)->d->m_frame = child;
    } else if (child->m_frame) {
      child->m_liveconnect = KParts::LiveConnectExtension::childObject(part);
      if (child->m_liveconnect)
        connect(child->m_liveconnect, SIGNAL(partEvent(const unsigned long, const QString &, const KParts::LiveConnectExtension::ArgList &)), child, SLOT(liveConnectEvent(const unsigned long, const QString&, const KParts::LiveConnectExtension::ArgList &)));
    }
    KParts::StatusBarExtension *sb = KParts::StatusBarExtension::childObject(part);
    if (sb)
      sb->setStatusBar( d->m_statusBarExtension->statusBar() );

    connect( part, SIGNAL( started( KIO::Job *) ),
             this, SLOT( slotChildStarted( KIO::Job *) ) );
    connect( part, SIGNAL( completed() ),
             this, SLOT( slotChildCompleted() ) );
    connect( part, SIGNAL( completed(bool) ),
             this, SLOT( slotChildCompleted(bool) ) );
    connect( part, SIGNAL( setStatusBarText( const QString & ) ),
                this, SIGNAL( setStatusBarText( const QString & ) ) );
    if ( part->inherits( "KHTMLPart" ) )
    {
      connect( this, SIGNAL( completed() ),
               part, SLOT( slotParentCompleted() ) );
      connect( this, SIGNAL( completed(bool) ),
               part, SLOT( slotParentCompleted() ) );
      // As soon as the child's document is created, we need to set its domain
      // (but we do so only once, so it can't be simply done in the child)
      connect( part, SIGNAL( docCreated() ),
               this, SLOT( slotChildDocCreated() ) );
    }

    child->m_extension = KParts::BrowserExtension::childObject( part );

    if ( child->m_extension )
    {
      connect( child->m_extension, SIGNAL( openURLNotify() ),
               d->m_extension, SIGNAL( openURLNotify() ) );

      connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
               this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );

      connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
               d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
      connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
               d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );

      connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
               d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
      connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
               d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
      connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ),
               d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) );
      connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
               d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
      connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
               d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
      connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ),
               d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) );

      connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
               d->m_extension, SIGNAL( infoMessage( const QString & ) ) );

      connect( child->m_extension, SIGNAL( requestFocus( KParts::ReadOnlyPart * ) ),
               this, SLOT( slotRequestFocus( KParts::ReadOnlyPart * ) ) );

      child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
    }
  }
  else if ( child->m_frame && child->m_part &&
            child->m_frame->widget() != child->m_part->widget() )
    child->m_frame->setWidget( child->m_part->widget() );

  checkEmitLoadEvent();
  // Some JS code in the load event may have destroyed the part
  // In that case, abort
  if ( !child->m_part )
    return false;

  if ( child->m_bPreloaded )
  {
    if ( child->m_frame && child->m_part )
      child->m_frame->setWidget( child->m_part->widget() );

    child->m_bPreloaded = false;
    return true;
  }

  child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);

  // make sure the part has a way to find out about the mimetype.
  // we actually set it in child->m_args in requestObject already,
  // but it's useless if we had to use a KHTMLRun instance, as the
  // point the run object is to find out exactly the mimetype.
  child->m_args.serviceType = mimetype;

  // if not a frame set child as completed
  child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;

  if ( child->m_extension )
    child->m_extension->setURLArgs( child->m_args );

  if(url.protocol() == "javascript" || url.url() == "about:blank") {
      if (!child->m_part->inherits("KHTMLPart"))
          return false;

      KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));

      p->begin();
      if (d->m_doc && p->d->m_doc)
        p->d->m_doc->setBaseURL(d->m_doc->baseURL());
      if (!url.url().startsWith("about:")) {
        p->write(url.path());
      } else {
      p->m_url = url;
        // we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
        p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
      }
      p->end();
      return true;
  }
  else if ( !url.isEmpty() )
  {
      //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
      bool b = child->m_part->openURL( url );
      if (child->m_bCompleted)
          checkCompleted();
      return b;
  }
  else
  {
      child->m_bCompleted = true;
      checkCompleted();
      return true;
  }
}

04639 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
                                             QObject *parent, const char *name, const QString &mimetype,
                                             QString &serviceName, QStringList &serviceTypes,
                                             const QStringList &params )
{
  QString constr;
  if ( !serviceName.isEmpty() )
    constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );

  KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );

  if ( offers.isEmpty() ) {
    int pos = mimetype.find( "-plugin" );
    if (pos < 0)
        return 0L;
    QString stripped_mime = mimetype.left( pos );
    offers = KTrader::self()->query( stripped_mime, "KParts/ReadOnlyPart", constr, QString::null );
    if ( offers.isEmpty() )
        return 0L;
  }

  KTrader::OfferList::ConstIterator it = offers.begin();
  const KTrader::OfferList::ConstIterator itEnd = offers.end();
  for ( ; it != itEnd; ++it )
  {
    KService::Ptr service = (*it);

    KLibFactory* const factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
    if ( factory ) {
      KParts::ReadOnlyPart *res = 0L;

      const char *className = "KParts::ReadOnlyPart";
      if ( service->serviceTypes().contains( "Browser/View" ) )
        className = "Browser/View";

      if ( factory->inherits( "KParts::Factory" ) )
        res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
      else
        res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));

      if ( res ) {
        serviceTypes = service->serviceTypes();
        serviceName = service->name();
        return res;
      }
    } else {
      // TODO KMessageBox::error and i18n, like in KonqFactory::createView?
      kdWarning() << QString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
                      .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage()) << endl;
    }
  }
  return 0;
}

04693 KParts::PartManager *KHTMLPart::partManager()
{
  if ( !d->m_manager && d->m_view )
  {
    d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
    d->m_manager->setAllowNestedParts( true );
    connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
             this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
    connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
             this, SLOT( slotPartRemoved( KParts::Part * ) ) );
  }

  return d->m_manager;
}

04708 void KHTMLPart::submitFormAgain()
{
  disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
  if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
    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 );

  delete d->m_submitForm;
  d->m_submitForm = 0;
}

void KHTMLPart::submitFormProxy( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
{
  submitForm(action, url, formData, _target, contentType, boundary);
}

04723 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
{
  kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
  if (d->m_formNotification == KHTMLPart::Only) {
    emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
    return;
  } else if (d->m_formNotification == KHTMLPart::Before) {
    emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
  }

  KURL u = completeURL( url );

  if ( !u.isValid() )
  {
    // ### ERROR HANDLING!
    return;
  }

  // Form security checks
  //
  /*
   * If these form security checks are still in this place in a month or two
   * I'm going to simply delete them.
   */

  /* This is separate for a reason.  It has to be _before_ all script, etc,
   * AND I don't want to break anything that uses checkLinkSecurity() in
   * other places.
   */

  if (!d->m_submitForm) {
    if (u.protocol() != "https" && u.protocol() != "mailto") {
      if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
        int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
                                                               "\nA third party may be able to intercept and view this information."
                                                               "\nAre you sure you wish to continue?"),
                                                    i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
        if (rc == KMessageBox::Cancel)
          return;
      } else {                  // Going from nonSSL -> nonSSL
        KSSLSettings kss(true);
        if (kss.warnOnUnencrypted()) {
          int rc = KMessageBox::warningContinueCancel(NULL,
                                                      i18n("Warning: Your data is about to be transmitted across the network unencrypted."
                                                           "\nAre you sure you wish to continue?"),
                                                      i18n("Network Transmission"),
                                                      KGuiItem(i18n("&Send Unencrypted")),
                                                      "WarnOnUnencryptedForm");
          // Move this setting into KSSL instead
          KConfig *config = kapp->config();
          QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
          KConfigGroupSaver saver( config, grpNotifMsgs );

          if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
            config->deleteEntry("WarnOnUnencryptedForm");
            config->sync();
            kss.setWarnOnUnencrypted(false);
            kss.save();
          }
          if (rc == KMessageBox::Cancel)
            return;
            }
      }
    }

    if (u.protocol() == "mailto") {
      int rc = KMessageBox::warningContinueCancel(NULL,
                                                  i18n("This site is attempting to submit form data via email.\n"
                                                       "Do you want to continue?"),
                                                  i18n("Network Transmission"),
                                                  KGuiItem(i18n("&Send Email")),
                                                  "WarnTriedEmailSubmit");

      if (rc == KMessageBox::Cancel) {
        return;
      }
    }
  }

  // End form security checks
  //

  QString urlstring = u.url();

  if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
    urlstring = KURL::decode_string(urlstring);
    crossFrameExecuteScript( _target, urlstring.right( urlstring.length() - 11) );
    return;
  }

  if (!checkLinkSecurity(u,
                   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?" ),
                   i18n( "Submit" )))
    return;

  KParts::URLArgs args;

  if (!d->m_referrer.isEmpty())
     args.metaData()["referrer"] = d->m_referrer;

  args.metaData().insert("PropagateHttpHeader", "true");
  args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
  args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
  args.metaData().insert("main_frame_request",
                         parentPart() == 0 ? "TRUE":"FALSE");
  args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
  args.metaData().insert("ssl_activate_warnings", "TRUE");
//WABA: When we post a form we should treat it as the main url
//the request should never be considered cross-domain
//args.metaData().insert("cross-domain", toplevelURL().url());
  args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;

  // Handle mailto: forms
  if (u.protocol() == "mailto") {
      // 1)  Check for attach= and strip it
      QString q = u.query().mid(1);
      QStringList nvps = QStringList::split("&", q);
      bool triedToAttach = false;

      QStringList::Iterator nvp = nvps.begin();
      const QStringList::Iterator nvpEnd = nvps.end();

// cannot be a for loop as if something is removed we don't want to do ++nvp, as
// remove returns an iterator pointing to the next item

      while (nvp != nvpEnd) {
         const QStringList pair = QStringList::split("=", *nvp);
         if (pair.count() >= 2) {
            if (pair.first().lower() == "attach") {
               nvp = nvps.remove(nvp);
               triedToAttach = true;
            } else {
               ++nvp;
            }
         } else {
            ++nvp;
         }
      }

      if (triedToAttach)
         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");

      // 2)  Append body=
      QString bodyEnc;
      if (contentType.lower() == "multipart/form-data") {
         // FIXME: is this correct?  I suspect not
         bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
                                                           formData.size()));
      } else if (contentType.lower() == "text/plain") {
         // Convention seems to be to decode, and s/&/\n/
         QString tmpbody = QString::fromLatin1(formData.data(),
                                               formData.size());
         tmpbody.replace(QRegExp("[&]"), "\n");
         tmpbody.replace(QRegExp("[+]"), " ");
         tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
         bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
      } else {
         bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
                                                           formData.size()));
      }

      nvps.append(QString("body=%1").arg(bodyEnc));
      q = nvps.join("&");
      u.setQuery(q);
  }

  if ( strcmp( action, "get" ) == 0 ) {
    if (u.protocol() != "mailto")
       u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
    args.setDoPost( false );
  }
  else {
    args.postData = formData;
    args.setDoPost( true );

    // construct some user headers if necessary
    if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
      args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
    else // contentType must be "multipart/form-data"
      args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
  }

  if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
    if( d->m_submitForm ) {
      kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
      return;
    }
    d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
    d->m_submitForm->submitAction = action;
    d->m_submitForm->submitUrl = url;
    d->m_submitForm->submitFormData = formData;
    d->m_submitForm->target = _target;
    d->m_submitForm->submitContentType = contentType;
    d->m_submitForm->submitBoundary = boundary;
    connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
  }
  else
  {
    emit d->m_extension->openURLRequest( u, args );
  }
}

void KHTMLPart::popupMenu( const QString &linkUrl )
{
  KURL popupURL;
  KURL linkKURL;
  KParts::URLArgs args;
  QString referrer;
  KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;

  if ( linkUrl.isEmpty() ) { // click on background
    KHTMLPart* khtmlPart = this;
    while ( khtmlPart->parentPart() )
    {
      khtmlPart=khtmlPart->parentPart();
    }
    popupURL = khtmlPart->url();
    referrer = khtmlPart->pageReferrer();
    if (hasSelection())
      itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
    else
      itemflags |= KParts::BrowserExtension::ShowNavigationItems;
  } else {               // click on link
    popupURL = completeURL( linkUrl );
    linkKURL = popupURL;
    referrer = this->referrer();

    if (!(d->m_strSelectedURLTarget).isEmpty() &&
           (d->m_strSelectedURLTarget.lower() != "_top") &&
           (d->m_strSelectedURLTarget.lower() != "_self") &&
         (d->m_strSelectedURLTarget.lower() != "_parent")) {
      if (d->m_strSelectedURLTarget.lower() == "_blank")
        args.setForcesNewWindow(true);
      else {
      KHTMLPart *p = this;
      while (p->parentPart())
        p = p->parentPart();
      if (!p->frameExists(d->m_strSelectedURLTarget))
          args.setForcesNewWindow(true);
      }
    }
  }

  // Danger, Will Robinson. The Popup might stay around for a much
  // longer time than KHTMLPart. Deal with it.
  KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
  QGuardedPtr<QObject> guard( client );

  QString mimetype = QString::fromLatin1( "text/html" );
  args.metaData()["referrer"] = referrer;

  if (!linkUrl.isEmpty())                       // over a link
  {
    if (popupURL.isLocalFile())                       // safe to do this
    {
      mimetype = KMimeType::findByURL(popupURL,0,true,false)->name();
    }
    else                                  // look at "extension" of link
    {
      const QString fname(popupURL.fileName(false));
      if (!fname.isEmpty() && !popupURL.hasRef() && popupURL.query().isEmpty())
      {
        KMimeType::Ptr pmt = KMimeType::findByPath(fname,0,true);

        // Further check for mime types guessed from the extension which,
        // on a web page, are more likely to be a script delivering content
        // of undecidable type. If the mime type from the extension is one
        // of these, don't use it.  Retain the original type 'text/html'.
        if (pmt->name() != KMimeType::defaultMimeType() &&
            !pmt->is("application/x-perl") &&
            !pmt->is("application/x-perl-module") &&
            !pmt->is("application/x-php") &&
            !pmt->is("application/x-python-bytecode") &&
            !pmt->is("application/x-python") &&
            !pmt->is("application/x-shellscript"))
          mimetype = pmt->name();
      }
    }
  }

  args.serviceType = mimetype;

  emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL, args, itemflags, S_IFREG /*always a file*/);

  if ( !guard.isNull() ) {
     delete client;
     emit popupMenu(linkUrl, QCursor::pos());
     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
  }
}

05014 void KHTMLPart::slotParentCompleted()
{
  //kdDebug(6050) << this << " slotParentCompleted()" << endl;
  if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
  {
    //kdDebug(6050) << this << ": starting timer for child redirection -> " << d->m_redirectURL << endl;
    d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
  }
}

05024 void KHTMLPart::slotChildStarted( KIO::Job *job )
{
  khtml::ChildFrame *child = frame( sender() );

  assert( child );

  child->m_bCompleted = false;

  if ( d->m_bComplete )
  {
#if 0
    // WABA: Looks like this belongs somewhere else
    if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
    {
      emit d->m_extension->openURLNotify();
    }
#endif
    d->m_bComplete = false;
    emit started( job );
  }
}

05046 void KHTMLPart::slotChildCompleted()
{
  slotChildCompleted( false );
}

05051 void KHTMLPart::slotChildCompleted( bool pendingAction )
{
  khtml::ChildFrame *child = frame( sender() );

  if ( child ) {
    kdDebug(6050) << this << " slotChildCompleted child=" << child << " m_frame=" << child->m_frame << endl;
    child->m_bCompleted = true;
    child->m_bPendingRedirection = pendingAction;
    child->m_args = KParts::URLArgs();
  }
  checkCompleted();
}

05064 void KHTMLPart::slotChildDocCreated()
{
  const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
  // Set domain to the frameset's domain
  // This must only be done when loading the frameset initially (#22039),
  // not when following a link in a frame (#44162).
  if ( d->m_doc && d->m_doc->isHTMLDocument() )
  {
    if ( sender()->inherits("KHTMLPart") )
    {
      DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
      if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
        //kdDebug(6050) << "KHTMLPart::slotChildDocCreated: url: " << htmlFrame->m_url.url() << endl;
        static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
    }
  }
  // So it only happens once
  disconnect( htmlFrame, SIGNAL( docCreated() ), this, SLOT( slotChildDocCreated() ) );
}

05084 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
{
  khtml::ChildFrame *child = frame( sender()->parent() );
  KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));

  // TODO: handle child target correctly! currently the script are always executed fur the parent
  QString urlStr = url.url();
  if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
      QString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
      executeScript( DOM::Node(), script );
      return;
  }

  QString frameName = args.frameName.lower();
  if ( !frameName.isEmpty() ) {
    if ( frameName == QString::fromLatin1( "_top" ) )
    {
      emit d->m_extension->openURLRequest( url, args );
      return;
    }
    else if ( frameName == QString::fromLatin1( "_blank" ) )
    {
      emit d->m_extension->createNewWindow( url, args );
      return;
    }
    else if ( frameName == QString::fromLatin1( "_parent" ) )
    {
      KParts::URLArgs newArgs( args );
      newArgs.frameName = QString::null;

      emit d->m_extension->openURLRequest( url, newArgs );
      return;
    }
    else if ( frameName != QString::fromLatin1( "_self" ) )
    {
      khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );

      if ( !_frame )
      {
        emit d->m_extension->openURLRequest( url, args );
        return;
      }

      child = _frame;
    }
  }

  if ( child && child->m_type != khtml::ChildFrame::Object ) {
      // Inform someone that we are about to show something else.
      child->m_bNotify = true;
      requestObject( child, url, args );
  }  else if ( frameName== "_self" ) // this is for embedded objects (via <object>) which want to replace the current document
  {
      KParts::URLArgs newArgs( args );
      newArgs.frameName = QString::null;
      emit d->m_extension->openURLRequest( url, newArgs );
  }
}

05143 void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
{
  emit d->m_extension->requestFocus(this);
}

khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
{
    assert( obj->inherits( "KParts::ReadOnlyPart" ) );
    const KParts::ReadOnlyPart* const part = static_cast<const KParts::ReadOnlyPart *>( obj );

    FrameIt it = d->m_frames.begin();
    const FrameIt end = d->m_frames.end();
    for (; it != end; ++it )
      if ( (KParts::ReadOnlyPart *)(*it)->m_part == part )
        return *it;

    FrameIt oi = d->m_objects.begin();
    const FrameIt oiEnd = d->m_objects.end();
    for (; oi != oiEnd; ++oi )
      if ( (KParts::ReadOnlyPart *)(*oi)->m_part == part )
        return *oi;

    return 0L;
}

//#define DEBUG_FINDFRAME

bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
{
  if (callingHtmlPart == this)
    return true; // trivial

  if (htmlDocument().isNull()) {
#ifdef DEBUG_FINDFRAME
    kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
#endif
    return false; // we are empty?
  }

  // now compare the domains
  if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
      !htmlDocument().isNull())  {
    DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
    DOM::DOMString destDomain = htmlDocument().domain();

#ifdef DEBUG_FINDFRAME
    kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
#endif

    if (actDomain == destDomain)
      return true;
  }
#ifdef DEBUG_FINDFRAME
  else
  {
    kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
  }
#endif
  return false;
}

KHTMLPart *
05205 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
{
#ifdef DEBUG_FINDFRAME
  kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " name = " << name() << " findFrameParent( " << f << " )" << endl;
#endif
  // Check access
  KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);

  if (!checkFrameAccess(callingHtmlPart))
     return 0;

  if (!childFrame && !parentPart() && (name() == f))
     return this;

  FrameIt it = d->m_frames.find( f );
  const FrameIt end = d->m_frames.end();
  if ( it != end )
  {
#ifdef DEBUG_FINDFRAME
     kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
#endif
     if (childFrame)
        *childFrame = *it;
     return this;
  }

  it = d->m_frames.begin();
  for (; it != end; ++it )
  {
    KParts::ReadOnlyPart* const p = (*it)->m_part;
    if ( p && p->inherits( "KHTMLPart" ))
    {
      KHTMLPart* const frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
      if (frameParent)
         return frameParent;
    }
  }
  return 0;
}


05246 KHTMLPart *KHTMLPart::findFrame( const QString &f )
{
  khtml::ChildFrame *childFrame;
  KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
  if (parentFrame)
  {
     KParts::ReadOnlyPart *p = childFrame->m_part;
     if ( p && p->inherits( "KHTMLPart" ))
        return static_cast<KHTMLPart *>(p);
  }
  return 0;
}

05259 KParts::ReadOnlyPart *KHTMLPart::findFramePart(const QString &f)
{
  khtml::ChildFrame *childFrame;
  return findFrameParent(this, f, &childFrame) ? static_cast<KParts::ReadOnlyPart *>(childFrame->m_part) : 0L;
}

05265 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
{
  KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
  // Find active part in our frame manager, in case we are a frameset
  // and keep doing that (in case of nested framesets).
  // Just realized we could also do this recursively, calling part->currentFrame()...
  while ( part && part->inherits("KHTMLPart") &&
          static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
    KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
    part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
    if ( !part ) return frameset;
  }
  return part;
}

05280 bool KHTMLPart::frameExists( const QString &frameName )
{
  ConstFrameIt it = d->m_frames.find( frameName );
  if ( it == d->m_frames.end() )
    return false;

  // WABA: We only return true if the child actually has a frame
  // set. Otherwise we might find our preloaded-selve.
  // This happens when we restore the frameset.
  return (!(*it)->m_frame.isNull());
}

05292 KJSProxy *KHTMLPart::framejScript(KParts::ReadOnlyPart *framePart)
{
  KHTMLPart* const kp = ::qt_cast<KHTMLPart*>(framePart);
  if (kp)
    return kp->jScript();

  FrameIt it = d->m_frames.begin();
  const FrameIt itEnd = d->m_frames.end();

  for (; it != itEnd; ++it)
    if (framePart == (*it)->m_part) {
      if (!(*it)->m_jscript)
        createJScript(*it);
      return (*it)->m_jscript;
    }
  return 0L;
}

05310 KHTMLPart *KHTMLPart::parentPart()
{
  return ::qt_cast<KHTMLPart *>( parent() );
}

khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
                                                     const KParts::URLArgs &args, bool callParent )
{
#ifdef DEBUG_FINDFRAME
  kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
#endif
  khtml::ChildFrame *childFrame;
  KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
  if (childPart)
  {
     if (childPart == this)
        return childFrame;

     childPart->requestObject( childFrame, url, args );
     return 0;
  }

  if ( parentPart() && callParent )
  {
     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );

     if ( res )
       parentPart()->requestObject( res, url, args );
  }

  return 0L;
}

#ifndef NDEBUG
static int s_saveStateIndentLevel = 0;
#endif

05347 void KHTMLPart::saveState( QDataStream &stream )
{
#ifndef NDEBUG
  QString indent = QString().leftJustify( s_saveStateIndentLevel * 4, ' ' );
  const int indentLevel = s_saveStateIndentLevel++;
  kdDebug( 6050 ) << indent << "saveState this=" << this << " '" << name() << "' saving URL " << m_url.url() << endl;
#endif

  stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
         << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();

  // save link cursor position
  int focusNodeNumber;
  if (!d->m_focusNodeRestored)
      focusNodeNumber = d->m_focusNodeNumber;
  else if (d->m_doc && d->m_doc->focusNode())
      focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
  else
      focusNodeNumber = -1;
  stream << focusNodeNumber;

  // Save the doc's cache id.
  stream << d->m_cacheId;

  // Save the state of the document (Most notably the state of any forms)
  QStringList docState;
  if (d->m_doc)
  {
     docState = d->m_doc->docState();
  }
  stream << d->m_encoding << d->m_sheetUsed << docState;

  stream << d->m_zoomFactor;

  stream << d->m_httpHeaders;
  stream << d->m_pageServices;
  stream << d->m_pageReferrer;

  // Save ssl data
  stream << d->m_ssl_in_use
         << d->m_ssl_peer_certificate
         << d->m_ssl_peer_chain
         << d->m_ssl_peer_ip
         << d->m_ssl_cipher
         << d->m_ssl_cipher_desc
         << d->m_ssl_cipher_version
         << d->m_ssl_cipher_used_bits
         << d->m_ssl_cipher_bits
         << d->m_ssl_cert_state
         << d->m_ssl_parent_ip
         << d->m_ssl_parent_cert;


  QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
  KURL::List frameURLLst;
  QValueList<QByteArray> frameStateBufferLst;

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
  {
    if ( !(*it)->m_part )
       continue;

    frameNameLst << (*it)->m_name;
    frameServiceTypeLst << (*it)->m_serviceType;
    frameServiceNameLst << (*it)->m_serviceName;
    frameURLLst << (*it)->m_part->url();

    QByteArray state;
    QDataStream frameStream( state, IO_WriteOnly );

    if ( (*it)->m_extension )
      (*it)->m_extension->saveState( frameStream );

    frameStateBufferLst << state;
  }

  // Save frame data
  stream << (Q_UINT32) frameNameLst.count();
  stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
#ifndef NDEBUG
  s_saveStateIndentLevel = indentLevel;
#endif
}

05433 void KHTMLPart::restoreState( QDataStream &stream )
{
  KURL u;
  Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
  Q_UINT32 frameCount;
  QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
  KURL::List frameURLs;
  QValueList<QByteArray> frameStateBuffers;
  QValueList<int> fSizes;
  QString encoding, sheetUsed;
  long old_cacheId = d->m_cacheId;

  stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;

  d->m_view->setMarginWidth( mWidth );
  d->m_view->setMarginHeight( mHeight );

  // restore link cursor position
  // nth node is active. value is set in checkCompleted()
  stream >> d->m_focusNodeNumber;
  d->m_focusNodeRestored = false;

  stream >> d->m_cacheId;

  stream >> encoding >> sheetUsed >> docState;

  d->m_encoding = encoding;
  d->m_sheetUsed = sheetUsed;

  int zoomFactor;
  stream >> zoomFactor;
  setZoomFactor(zoomFactor);

  stream >> d->m_httpHeaders;
  stream >> d->m_pageServices;
  stream >> d->m_pageReferrer;

  // Restore ssl data
  stream >> d->m_ssl_in_use
         >> d->m_ssl_peer_certificate
         >> d->m_ssl_peer_chain
         >> d->m_ssl_peer_ip
         >> d->m_ssl_cipher
         >> d->m_ssl_cipher_desc
         >> d->m_ssl_cipher_version
         >> d->m_ssl_cipher_used_bits
         >> d->m_ssl_cipher_bits
         >> d->m_ssl_cert_state
         >> d->m_ssl_parent_ip
         >> d->m_ssl_parent_cert;

  setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );

  stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
         >> frameURLs >> frameStateBuffers;

  d->m_bComplete = false;
  d->m_bLoadEventEmitted = false;

//   kdDebug( 6050 ) << "restoreState() docState.count() = " << docState.count() << endl;
//   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
//   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;

  if (d->m_cacheId == old_cacheId)
  {
    // Partial restore
    d->m_redirectionTimer.stop();

    FrameIt fIt = d->m_frames.begin();
    const FrameIt fEnd = d->m_frames.end();

    for (; fIt != fEnd; ++fIt )
        (*fIt)->m_bCompleted = false;

    fIt = d->m_frames.begin();

    QStringList::ConstIterator fNameIt = frameNames.begin();
    QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
    QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
    KURL::List::ConstIterator fURLIt = frameURLs.begin();
    QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();

    for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
    {
      khtml::ChildFrame* const child = *fIt;

//      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;

      if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
      {
        child->m_bPreloaded = true;
        child->m_name = *fNameIt;
        child->m_serviceName = *fServiceNameIt;
        processObjectRequest( child, *fURLIt, *fServiceTypeIt );
      }
      if ( child->m_part )
      {
        child->m_bCompleted = false;
        if ( child->m_extension && !(*fBufferIt).isEmpty() )
        {
          QDataStream frameStream( *fBufferIt, IO_ReadOnly );
          child->m_extension->restoreState( frameStream );
        }
        else
          child->m_part->openURL( *fURLIt );
      }
    }

    KParts::URLArgs args( d->m_extension->urlArgs() );
    args.xOffset = xOffset;
    args.yOffset = yOffset;
    args.docState = docState;
    d->m_extension->setURLArgs( args );

    d->m_view->resizeContents( wContents,  hContents);
    d->m_view->setContentsPos( xOffset, yOffset );

    m_url = u;
  }
  else
  {
    // Full restore.
    closeURL();
    // We must force a clear because we want to be sure to delete all
    // frames.
    d->m_bCleared = false;
    clear();
    d->m_encoding = encoding;
    d->m_sheetUsed = sheetUsed;

    QStringList::ConstIterator fNameIt = frameNames.begin();
    const QStringList::ConstIterator fNameEnd = frameNames.end();

    QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
    QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
    KURL::List::ConstIterator fURLIt = frameURLs.begin();
    QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();

    for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
    {
      khtml::ChildFrame* const newChild = new khtml::ChildFrame;
      newChild->m_bPreloaded = true;
      newChild->m_name = *fNameIt;
      newChild->m_serviceName = *fServiceNameIt;

//      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;

      const FrameIt childFrame = d->m_frames.append( newChild );

      processObjectRequest( *childFrame, *fURLIt, *fServiceTypeIt );

      (*childFrame)->m_bPreloaded = true;

      if ( (*childFrame)->m_part )
      {
        if ( (*childFrame)->m_extension )
        if ( (*childFrame)->m_extension && !(*fBufferIt).isEmpty() )
        {
          QDataStream frameStream( *fBufferIt, IO_ReadOnly );
          (*childFrame)->m_extension->restoreState( frameStream );
        }
        else
          (*childFrame)->m_part->openURL( *fURLIt );
      }
    }

    KParts::URLArgs args( d->m_extension->urlArgs() );
    args.xOffset = xOffset;
    args.yOffset = yOffset;
    args.docState = docState;

    d->m_extension->setURLArgs( args );
    if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
    {
       d->m_restored = true;
       openURL( u );
       d->m_restored = false;
    }
    else
    {
       restoreURL( u );
    }
  }

}

05619 void KHTMLPart::show()
{
  if ( d->m_view )
    d->m_view->show();
}

05625 void KHTMLPart::hide()
{
  if ( d->m_view )
    d->m_view->hide();
}

05631 DOM::Node KHTMLPart::nodeUnderMouse() const
{
    return d->m_view->nodeUnderMouse();
}

05636 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
{
    return d->m_view->nonSharedNodeUnderMouse();
}

void KHTMLPart::emitSelectionChanged()
{
  emit d->m_extension->enableAction( "copy", hasSelection() );
  if ( d->m_findDialog )
       d->m_findDialog->setHasSelection( hasSelection() );

  emit d->m_extension->selectionInfo( selectedText() );
  emit selectionChanged();
}

05651 int KHTMLPart::zoomFactor() const
{
  return d->m_zoomFactor;
}

// ### make the list configurable ?
static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
static const int minZoom = 20;
static const int maxZoom = 300;

// My idea of useful stepping ;-) (LS)
extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];

void KHTMLPart::slotIncZoom()
{
  zoomIn(zoomSizes, zoomSizeCount);
}

void KHTMLPart::slotDecZoom()
{
  zoomOut(zoomSizes, zoomSizeCount);
}

void KHTMLPart::slotIncZoomFast()
{
  zoomIn(fastZoomSizes, fastZoomSizeCount);
}

void KHTMLPart::slotDecZoomFast()
{
  zoomOut(fastZoomSizes, fastZoomSizeCount);
}

05686 void KHTMLPart::zoomIn(const int stepping[], int count)
{
  int zoomFactor = d->m_zoomFactor;

  if (zoomFactor < maxZoom) {
    // find the entry nearest to the given zoomsizes
    for (int i = 0; i < count; ++i)
      if (stepping[i] > zoomFactor) {
        zoomFactor = stepping[i];
        break;
      }
    setZoomFactor(zoomFactor);
  }
}

05701 void KHTMLPart::zoomOut(const int stepping[], int count)
{
    int zoomFactor = d->m_zoomFactor;
    if (zoomFactor > minZoom) {
      // find the entry nearest to the given zoomsizes
      for (int i = count-1; i >= 0; --i)
        if (stepping[i] < zoomFactor) {
          zoomFactor = stepping[i];
          break;
        }
      setZoomFactor(zoomFactor);
    }
}

05715 void KHTMLPart::setZoomFactor (int percent)
{
  if (percent < minZoom) percent = minZoom;
  if (percent > maxZoom) percent = maxZoom;
  if (d->m_zoomFactor == percent) return;
  d->m_zoomFactor = percent;

  if(d->m_doc) {
      QApplication::setOverrideCursor( waitCursor );
    if (d->m_doc->styleSelector())
      d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
    d->m_doc->recalcStyle( NodeImpl::Force );
    QApplication::restoreOverrideCursor();
  }

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
      KParts::ReadOnlyPart* const p = ( *it )->m_part;
      static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
    }

  if ( d->m_guiProfile == BrowserViewGUI ) {
      d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
      d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
  }
}

05744 void KHTMLPart::slotZoomView( int delta )
{
  if ( delta < 0 )
    slotIncZoom();
  else
    slotDecZoom();
}

void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
{
  if (!d->m_statusMessagesEnabled)
    return;

  d->m_statusBarText[p] = text;

  // shift handling ?
  QString tobe = d->m_statusBarText[BarHoverText];
  if (tobe.isEmpty())
    tobe = d->m_statusBarText[BarOverrideText];
  if (tobe.isEmpty()) {
    tobe = d->m_statusBarText[BarDefaultText];
    if (!tobe.isEmpty() && d->m_jobspeed)
      tobe += " ";
    if (d->m_jobspeed)
      tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
  }
  tobe = "<qt>"+tobe;

  emit ReadOnlyPart::setStatusBarText(tobe);
}


05776 void KHTMLPart::setJSStatusBarText( const QString &text )
{
  setStatusBarText(text, BarOverrideText);
}

05781 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
{
  setStatusBarText(text, BarDefaultText);
}

05786 QString KHTMLPart::jsStatusBarText() const
{
    return d->m_statusBarText[BarOverrideText];
}

05791 QString KHTMLPart::jsDefaultStatusBarText() const
{
   return d->m_statusBarText[BarDefaultText];
}

05796 QString KHTMLPart::referrer() const
{
   return d->m_referrer;
}

05801 QString KHTMLPart::pageReferrer() const
{
   KURL referrerURL = KURL( d->m_pageReferrer );
   if (referrerURL.isValid())
   {
      QString protocol = referrerURL.protocol();

      if ((protocol == "http") ||
         ((protocol == "https") && (m_url.protocol() == "https")))
      {
          referrerURL.setRef(QString::null);
          referrerURL.setUser(QString::null);
          referrerURL.setPass(QString::null);
          return referrerURL.url();
      }
   }

   return QString::null;
}


05822 QString KHTMLPart::lastModified() const
{
  if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
    // Local file: set last-modified from the file's mtime.
    // Done on demand to save time when this isn't needed - but can lead
    // to slightly wrong results if updating the file on disk w/o reloading.
    QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
    d->m_lastModified = lastModif.toString( Qt::LocalDate );
  }
  //kdDebug(6050) << "KHTMLPart::lastModified: " << d->m_lastModified << endl;
  return d->m_lastModified;
}

void KHTMLPart::slotLoadImages()
{
  if (d->m_doc )
    d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
      KParts::ReadOnlyPart* const p = ( *it )->m_part;
      static_cast<KHTMLPart*>( p )->slotLoadImages();
    }
}

05849 void KHTMLPart::reparseConfiguration()
{
  KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
  settings->init();

  setAutoloadImages( settings->autoLoadImages() );
  if (d->m_doc)
     d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );

  d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
  d->m_bBackRightClick = settings->isBackRightClickEnabled();
  d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
  setDebugScript( settings->isJavaScriptDebugEnabled() );
  d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
  d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
  d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();

  delete d->m_settings;
  d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());

  QApplication::setOverrideCursor( waitCursor );
  khtml::CSSStyleSelector::reparseConfiguration();
  if(d->m_doc) d->m_doc->updateStyleSelector();
  QApplication::restoreOverrideCursor();

  if (KHTMLFactory::defaultHTMLSettings()->isAdFilterEnabled())
     runAdFilter();
}

05878 QStringList KHTMLPart::frameNames() const
{
  QStringList res;

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if (!(*it)->m_bPreloaded)
      res += (*it)->m_name;

  return res;
}

QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
{
  QPtrList<KParts::ReadOnlyPart> res;

  ConstFrameIt it = d->m_frames.begin();
  const ConstFrameIt end = d->m_frames.end();
  for (; it != end; ++it )
    if (!(*it)->m_bPreloaded)
      res.append( (*it)->m_part );

  return res;
}

bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
{
    kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
  FrameIt it = d->m_frames.find( urlArgs.frameName );

  if ( it == d->m_frames.end() )
    return false;

  // Inform someone that we are about to show something else.
  if ( !urlArgs.lockHistory() )
      emit d->m_extension->openURLNotify();

  requestObject( *it, url, urlArgs );

  return true;
}

05921 void KHTMLPart::setDNDEnabled( bool b )
{
  d->m_bDnd = b;
}

bool KHTMLPart::dndEnabled() const
{
  return d->m_bDnd;
}

05931 void KHTMLPart::customEvent( QCustomEvent *event )
{
  if ( khtml::MousePressEvent::test( event ) )
  {
    khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
    return;
  }

  if ( khtml::MouseDoubleClickEvent::test( event ) )
  {
    khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
    return;
  }

  if ( khtml::MouseMoveEvent::test( event ) )
  {
    khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
    return;
  }

  if ( khtml::MouseReleaseEvent::test( event ) )
  {
    khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
    return;
  }

  if ( khtml::DrawContentsEvent::test( event ) )
  {
    khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
    return;
  }

  KParts::ReadOnlyPart::customEvent( event );
}

/** returns the position of the first inline text box of the line at
 * coordinate y in renderNode
 *
 * This is a helper function for line-by-line text selection.
 */
static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
{
    for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
        if (n->isText()) {
            khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
            const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
            const unsigned lim = runs.count();
            for (unsigned i = 0; i != lim; ++i) {
                if (runs[i]->m_y == y && textRenderer->element()) {
                    startNode = textRenderer->element();
                    startOffset = runs[i]->m_start;
                    return true;
                }
            }
        }

        if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
            return true;
        }
    }

    return false;
}

/** returns the position of the last inline text box of the line at
 * coordinate y in renderNode
 *
 * This is a helper function for line-by-line text selection.
 */
static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
{
    khtml::RenderObject *n = renderNode;
    if (!n) {
        return false;
    }
    khtml::RenderObject *next;
    while ((next = n->nextSibling())) {
        n = next;
    }

    while (1) {
        if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
            return true;
        }

        if (n->isText()) {
            khtml::RenderText* const textRenderer =  static_cast<khtml::RenderText *>(n);
            const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
            for (int i = (int)runs.count()-1; i >= 0; --i) {
                if (runs[i]->m_y == y && textRenderer->element()) {
                    endNode = textRenderer->element();
                    endOffset = runs[i]->m_start + runs[i]->m_len;
                    return true;
                }
            }
        }

        if (n == renderNode) {
            return false;
        }

        n = n->previousSibling();
    }
}

06036 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
{
  DOM::DOMString url = event->url();
  QMouseEvent *_mouse = event->qmouseEvent();
  DOM::Node innerNode = event->innerNode();
  d->m_mousePressNode = innerNode;

   d->m_dragStartPos = _mouse->pos();

   if ( !event->url().isNull() ) {
     d->m_strSelectedURL = event->url().string();
     d->m_strSelectedURLTarget = event->target().string();
   }
   else
     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;

  if ( _mouse->button() == LeftButton ||
       _mouse->button() == MidButton )
  {
    d->m_bMousePressed = true;

#ifndef KHTML_NO_SELECTION
    if ( _mouse->button() == LeftButton )
    {
      if ( (!d->m_strSelectedURL.isNull() && !isEditable())
              || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
        return;
      if ( !innerNode.isNull()  && innerNode.handle()->renderer()) {
          int offset = 0;
          DOM::NodeImpl* node = 0;
          khtml::RenderObject::SelPointState state;
          innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
                                                               event->absX()-innerNode.handle()->renderer()->xPos(),
                                                               event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
          d->m_extendMode = d->ExtendByChar;
#ifdef KHTML_NO_CARET
          d->m_selectionStart = node;
          d->m_startOffset = offset;
          //if ( node )
          //  kdDebug(6005) << "KHTMLPart::khtmlMousePressEvent selectionStart=" << d->m_selectionStart.handle()->renderer()
          //                << " offset=" << d->m_startOffset << endl;
          //else
          //  kdDebug(6005) << "KHTML::khtmlMousePressEvent selectionStart=(nil)" << endl;
          d->m_selectionEnd = d->m_selectionStart;
          d->m_endOffset = d->m_startOffset;
          d->m_doc->clearSelection();
#else // KHTML_NO_CARET
        d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
#endif // KHTML_NO_CARET
        d->m_initialNode = d->m_selectionStart;
        d->m_initialOffset = d->m_startOffset;
//           kdDebug(6000) << "press: initOfs " << d->m_initialOffset << endl;
      }
      else
      {
#ifndef KHTML_NO_CARET
        // simply leave it. Is this a good idea?
#else
        d->m_selectionStart = DOM::Node();
        d->m_selectionEnd = DOM::Node();
#endif
      }
      emitSelectionChanged();
      startAutoScroll();
    }
#else
    d->m_dragLastPos = _mouse->globalPos();
#endif
  }

  if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
  {
    d->m_bRightMousePressed = true;
  } else if ( _mouse->button() == RightButton )
  {
    popupMenu( d->m_strSelectedURL );
    // might be deleted, don't touch "this"
  }
}

06116 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
{
  QMouseEvent *_mouse = event->qmouseEvent();
  if ( _mouse->button() == LeftButton )
  {
    d->m_bMousePressed = true;
    DOM::Node innerNode = event->innerNode();
    // Find selectionStart again, khtmlMouseReleaseEvent lost it
    if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
      int offset = 0;
      DOM::NodeImpl* node = 0;
      khtml::RenderObject::SelPointState state;
      innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
                                                           event->absX()-innerNode.handle()->renderer()->xPos(),
                                                           event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);

      //kdDebug() << k_funcinfo << "checkSelectionPoint returned node=" << node << " offset=" << offset << endl;

      if ( node && node->renderer() )
      {
        // Extend selection to a complete word (double-click) or line (triple-click)
        bool selectLine = (event->clickCount() == 3);
        d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;

      // Extend existing selection if Shift was pressed
      if (_mouse->state() & ShiftButton) {
          d->caretNode() = node;
        d->caretOffset() = offset;
          d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
                        d->m_selectionStart.handle(), d->m_startOffset,
                  d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
          d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
          d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
      } else {
        d->m_selectionStart = d->m_selectionEnd = node;
        d->m_startOffset = d->m_endOffset = offset;
          d->m_startBeforeEnd = true;
          d->m_initialNode = node;
          d->m_initialOffset = offset;
      }
//         kdDebug(6000) << "dblclk: initOfs " << d->m_initialOffset << endl;

        // Extend the start
        extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
        // Extend the end
        extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );

        //kdDebug() << d->m_selectionStart.handle() << " " << d->m_startOffset << "  -  " <<
        //  d->m_selectionEnd.handle() << " " << d->m_endOffset << endl;

        emitSelectionChanged();
        d->m_doc
          ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
                         d->m_selectionEnd.handle(),d->m_endOffset);
#ifndef KHTML_NO_CARET
        bool v = d->m_view->placeCaret();
        emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
#endif
        startAutoScroll();
      }
    }
  }
}

void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
{
  khtml::RenderObject* obj = node->renderer();

  if (obj->isText() && selectLines) {
    int pos;
    khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
    khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
    DOMString t = node->nodeValue();
    DOM::NodeImpl* selNode = 0;
    long selOfs = 0;

    if (!run)
      return;

    int selectionPointY = run->m_y;

    // Go up to first non-inline element.
    khtml::RenderObject *renderNode = renderer;
    while (renderNode && renderNode->isInline())
      renderNode = renderNode->parent();

    renderNode = renderNode->firstChild();

    if (right) {
      // Look for all the last child in the block that is on the same line
      // as the selection point.
      if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
        return;
    } else {
      // Look for all the first child in the block that is on the same line
      // as the selection point.
      if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
        return;
    }

    selectionNode = selNode;
    selectionOffset = selOfs;
    return;
  }

  QString str;
  int len = 0;
  if ( obj->isText() ) { // can be false e.g. when double-clicking on a disabled submit button
    str = static_cast<khtml::RenderText *>(obj)->data().string();
    len = str.length();
  }
  //kdDebug() << "extendSelection right=" << right << " offset=" << offset << " len=" << len << " Starting at obj=" << obj << endl;
  QChar ch;
  do {
    // Last char was ok, point to it
    if ( node ) {
      selectionNode = node;
      selectionOffset = offset;
    }

    // Get another char
    while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
    {
      obj = right ? obj->objectBelow() : obj->objectAbove();
      //kdDebug() << "obj=" << obj << endl;
      if ( obj ) {
        //kdDebug() << "isText=" << obj->isText() << endl;
        str = QString::null;
        if ( obj->isText() )
          str = static_cast<khtml::RenderText *>(obj)->data().string();
        else if ( obj->isBR() )
          str = '\n';
        else if ( !obj->isInline() ) {
          obj = 0L; // parag limit -> done
          break;
        }
        len = str.length();
        //kdDebug() << "str=" << str << " length=" << len << endl;
        // set offset - note that the first thing will be a ++ or -- on it.
        if ( right )
          offset = -1;
        else
          offset = len;
      }
    }
    if ( !obj ) // end of parag or document
      break;
    node = obj->element();
    if ( right )
    {
      Q_ASSERT( offset < len-1 );
      ++offset;
    }
    else
    {
      Q_ASSERT( offset > 0 );
      --offset;
    }

    // Test that char
    ch = str[ (int)offset ];
    //kdDebug() << " offset=" << offset << " ch=" << QString(ch) << endl;
  } while ( !ch.isSpace() && !ch.isPunct() );

  // make offset point after last char
  if (right) ++selectionOffset;
}

#ifndef KHTML_NO_SELECTION
06285 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
{
      int offset;
      //kdDebug(6000) << "KHTMLPart::khtmlMouseMoveEvent x=" << event->x() << " y=" << event->y() << endl;
      DOM::NodeImpl* node=0;
      khtml::RenderObject::SelPointState state;
      innerNode.handle()->renderer()->checkSelectionPoint( x, y,
                                                           absX-innerNode.handle()->renderer()->xPos(),
                                                           absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
      if (!node || !node->renderer()) return;

      // Words at the beginning/end of line cannot be deselected in
      // ExtendByWord mode. Therefore, do not enforce it if the selection
      // point does not match the node under the mouse cursor.
      bool withinNode = innerNode == node;

      // we have to get to know if end is before start or not...
      // shouldn't be null but it can happen with dynamic updating of nodes
      if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
          d->m_initialNode.isNull() ||
          !d->m_selectionStart.handle()->renderer() ||
          !d->m_selectionEnd.handle()->renderer()) return;

      if (d->m_extendMode != d->ExtendByChar) {
        // check whether we should extend at the front, or at the back
        bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
                        d->caretNode().handle(), d->caretOffset(),
                  d->m_initialNode.handle(), d->m_initialOffset) <= 0;
        bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
                  d->m_initialNode.handle(), d->m_initialOffset) <= 0;
        // have to fix up start to point to the original end
        if (caretBeforeInit != nodeBeforeInit) {
//         kdDebug(6000) << "extto cbi: " << caretBeforeInit << " startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << " initOfs " << d->m_initialOffset << endl;
          extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
            d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
            d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
            nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
      }
      }

      d->caretNode() = node;
      d->caretOffset() = offset;
      //kdDebug( 6000 ) << "setting end of selection to " << d->m_selectionEnd.handle() << "/" << d->m_endOffset << endl;

      d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
                        d->m_selectionStart.handle(), d->m_startOffset,
                  d->m_selectionEnd.handle(), d->m_endOffset) <= 0;

      if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
      {
//         kdDebug(6000) << "extto: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << " initOfs " << d->m_initialOffset << endl;
        if (d->m_extendMode != d->ExtendByChar && withinNode)
          extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );

        if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
          d->m_doc
            ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
                           d->m_selectionEnd.handle(),d->m_startOffset);
        else if (d->m_startBeforeEnd)
          d->m_doc
            ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
                           d->m_selectionEnd.handle(),d->m_endOffset);
        else
          d->m_doc
            ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
                           d->m_selectionStart.handle(),d->m_startOffset);
      }
#ifndef KHTML_NO_CARET
      d->m_view->placeCaret();
#endif
}

06357 bool KHTMLPart::isExtendingSelection() const
{
  // This is it, the whole detection. khtmlMousePressEvent only sets this
  // on LMB or MMB, but never on RMB. As text selection doesn't work for MMB,
  // it's sufficient to only rely on this flag to detect selection extension.
  return d->m_bMousePressed;
}
#endif // KHTML_NO_SELECTION

06366 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
{
  QMouseEvent *_mouse = event->qmouseEvent();

  if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
  {
    popupMenu( d->m_strSelectedURL );
    d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
    d->m_bRightMousePressed = false;
  }

  DOM::DOMString url = event->url();
  DOM::DOMString target = event->target();
  DOM::Node innerNode = event->innerNode();

#ifndef QT_NO_DRAGANDDROP
  if( d->m_bDnd && d->m_bMousePressed &&
      ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
        || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
    if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
      return;

    QPixmap pix;
    HTMLImageElementImpl *img = 0L;
    QDragObject *drag = 0;
    KURL u;

    // qDebug("****************** Event URL: %s", url.string().latin1());
    // qDebug("****************** Event Target: %s", target.string().latin1());

    // Normal image...
    if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
    {
      img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
      u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
      pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
    }
    else
    {
      // Text or image link...
      u = completeURL( d->m_strSelectedURL );
      pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
    }

    u.setPass(QString::null);

    KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
    if ( !d->m_referrer.isEmpty() )
      urlDrag->metaData()["referrer"] = d->m_referrer;

    if( img && img->complete()) {
      KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
      mdrag->addDragObject( new QImageDrag( img->currentImage(), 0L ) );
      mdrag->addDragObject( urlDrag );
      drag = mdrag;
    }
    else
      drag = urlDrag;

    if ( !pix.isNull() )
      drag->setPixmap( pix );

    stopAutoScroll();
    if(drag)
      drag->drag();

    // when we finish our drag, we need to undo our mouse press
    d->m_bMousePressed = false;
    d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
    return;
  }
#endif

  // Not clicked -> mouse over stuff
  if ( !d->m_bMousePressed )
  {
    // The mouse is over something
    if ( url.length() )
    {
      bool shiftPressed = ( _mouse->state() & ShiftButton );

      // Image map
      if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
      {
        HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
        if ( i && i->isServerMap() )
        {
          khtml::RenderObject *r = i->renderer();
          if(r)
          {
            int absx, absy, vx, vy;
            r->absolutePosition(absx, absy);
            view()->contentsToViewport( absx, absy, vx, vy );

            int x(_mouse->x() - vx), y(_mouse->y() - vy);

            d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
            d->m_overURLTarget = target.string();
            overURL( d->m_overURL, target.string(), shiftPressed );
            return;
          }
        }
      }

      // normal link
      if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
      {
        d->m_overURL = url.string();
        d->m_overURLTarget = target.string();
        overURL( d->m_overURL, target.string(), shiftPressed );
      }
    }
    else  // Not over a link...
    {
      // reset to "default statusbar text"
      resetHoverText();
    }
  }
  else {
#ifndef KHTML_NO_SELECTION
    // selection stuff
    if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
        ( (_mouse->state() & LeftButton) != 0 )) {
      extendSelectionTo(event->x(), event->y(),
                        event->absX(), event->absY(), innerNode);
#else
      if ( d->m_doc && d->m_view ) {
        QPoint diff( _mouse->globalPos() - d->m_dragLastPos );

        if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
          d->m_view->scrollBy( -diff.x(), -diff.y() );
          d->m_dragLastPos = _mouse->globalPos();
        }
#endif
    }
  }

}

06505 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
{
  DOM::Node innerNode = event->innerNode();
  d->m_mousePressNode = DOM::Node();

  if ( d->m_bMousePressed ) {
    setStatusBarText(QString::null, BarHoverText);
    stopAutoScroll();
  }

  // Used to prevent mouseMoveEvent from initiating a drag before
  // the mouse is pressed again.
  d->m_bMousePressed = false;

  QMouseEvent *_mouse = event->qmouseEvent();
  if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
  {
    d->m_bRightMousePressed = false;
    KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
    if( tmp_iface ) {
      tmp_iface->callMethod( "goHistory(int)", -1 );
    }
  }
#ifndef QT_NO_CLIPBOARD
  if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull())) {
    kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
                    << d->m_bOpenMiddleClick << endl;

    if (d->m_bOpenMiddleClick) {
    KHTMLPart *p = this;
    while (p->parentPart()) p = p->parentPart();
    p->d->m_extension->pasteRequest();
  }
  }
#endif

#ifndef KHTML_NO_SELECTION
  // delete selection in case start and end position are at the same point
  if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
#ifndef KHTML_NO_CARET
    d->m_extendAtEnd = true;
#else
    d->m_selectionStart = 0;
    d->m_selectionEnd = 0;
    d->m_startOffset = 0;
    d->m_endOffset = 0;
#endif
    emitSelectionChanged();
  } else {
    // we have to get to know if end is before start or not...
//     kdDebug(6000) << "rel: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << endl;
    DOM::Node n = d->m_selectionStart;
    d->m_startBeforeEnd = false;
    if( d->m_selectionStart == d->m_selectionEnd ) {
      if( d->m_startOffset < d->m_endOffset )
        d->m_startBeforeEnd = true;
    } else {
#if 0
      while(!n.isNull()) {
        if(n == d->m_selectionEnd) {
          d->m_startBeforeEnd = true;
          break;
        }
        DOM::Node next = n.firstChild();
        if(next.isNull()) next = n.nextSibling();
        while( next.isNull() && !n.parentNode().isNull() ) {
          n = n.parentNode();
          next = n.nextSibling();
        }
        n = next;
      }
#else
      // shouldn't be null but it can happen with dynamic updating of nodes
      if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
          !d->m_selectionStart.handle()->renderer() ||
          !d->m_selectionEnd.handle()->renderer()) return;
      d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
                        d->m_selectionStart.handle(), d->m_startOffset,
                  d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
#endif
    }
    if(!d->m_startBeforeEnd)
    {
      DOM::Node tmpNode = d->m_selectionStart;
      int tmpOffset = d->m_startOffset;
      d->m_selectionStart = d->m_selectionEnd;
      d->m_startOffset = d->m_endOffset;
      d->m_selectionEnd = tmpNode;
      d->m_endOffset = tmpOffset;
      d->m_startBeforeEnd = true;
      d->m_extendAtEnd = !d->m_extendAtEnd;
    }
#ifndef KHTML_NO_CARET
    bool v = d->m_view->placeCaret();
    emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
#endif
    // get selected text and paste to the clipboard
#ifndef QT_NO_CLIPBOARD
    QString text = selectedText();
    text.replace(QChar(0xa0), ' ');
    disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
    kapp->clipboard()->setText(text,QClipboard::Selection);
    connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
#endif
    //kdDebug( 6000 ) << "selectedText = " << text << endl;
    emitSelectionChanged();
//kdDebug(6000) << "rel2: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << "), caretOfs " << d->caretOffset() << endl;
  }
#endif
  d->m_initialNode = 0;       // don't hold nodes longer than necessary
  d->m_initialOffset = 0;

}

06619 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
{
}

06623 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
{
  if ( event->activated() )
  {
    emitSelectionChanged();
    emit d->m_extension->enableAction( "print", d->m_doc != 0 );

    if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
    {
        QPtrList<KAction> lst;
        lst.append( d->m_paLoadImages );
        plugActionList( "loadImages", lst );
    }
  }
}

void KHTMLPart::slotPrintFrame()
{
  if ( d->m_frames.count() == 0 )
    return;

  KParts::ReadOnlyPart *frame = currentFrame();
  if (!frame)
    return;

  KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );

  if ( !ext )
    return;

  QMetaObject *mo = ext->metaObject();

  int idx = mo->findSlot( "print()", true );
  if ( idx >= 0 ) {
    QUObject o[ 1 ];
    ext->qt_invoke( idx, o );
  }
}

void KHTMLPart::slotSelectAll()
{
  KParts::ReadOnlyPart *part = currentFrame();
  if (part && part->inherits("KHTMLPart"))
    static_cast<KHTMLPart *>(part)->selectAll();
}

void KHTMLPart::startAutoScroll()
{
   connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
   d->m_scrollTimer.start(100, false);
}

void KHTMLPart::stopAutoScroll()
{
   disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
   if (d->m_scrollTimer.isActive())
       d->m_scrollTimer.stop();
}


06683 void KHTMLPart::slotAutoScroll()
{
    if (d->m_view)
      d->m_view->doAutoScroll();
    else
      stopAutoScroll(); // Safety
}

void KHTMLPart::runAdFilter()
{
    if ( parentPart() )
        parentPart()->runAdFilter();

    if ( !d->m_doc )
        return;

    QPtrDictIterator<khtml::CachedObject> it( d->m_doc->docLoader()->m_docObjects );
    for ( ; it.current(); ++it )
        if ( it.current()->type() == khtml::CachedObject::Image ) {
            khtml::CachedImage *image = static_cast<khtml::CachedImage *>(it.current());
            bool wasBlocked = image->m_wasBlocked;
            image->m_wasBlocked = KHTMLFactory::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( (*it).url().string() ) );
            if ( image->m_wasBlocked != wasBlocked )
                image->do_notify(image->pixmap(), image->valid_rect());
        }

    if ( KHTMLFactory::defaultHTMLSettings()->isHideAdsEnabled() ) {
        for ( NodeImpl *nextNode, *node = d->m_doc; node; node = nextNode ) {

            // We might be deleting 'node' shortly.
            nextNode = node->traverseNextNode();

            if ( node->id() == ID_IMG ||
                 node->id() == ID_IFRAME ||
                 (node->id() == ID_INPUT && static_cast<HTMLInputElementImpl *>(node)->inputType() == HTMLInputElementImpl::IMAGE ))
            {
                if ( KHTMLFactory::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( static_cast<ElementImpl *>(node)->getAttribute(ATTR_SRC).string() ) ) )
                {
                    // We found an IMG, IFRAME or INPUT (of type IMAGE) matching a filter.
                    node->ref();
                    NodeImpl *parent = node->parent();
                    if( parent )
                    {
                        int exception = 0;
                        parent->removeChild(node, exception);
                    }
                    node->deref();
                }
            }
        }
    }
}

06736 void KHTMLPart::selectAll()
{
  if (!d->m_doc) return;

  NodeImpl *first;
  if (d->m_doc->isHTMLDocument())
    first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
  else
    first = d->m_doc;
  NodeImpl *next;

  // Look for first text/cdata node that has a renderer,
  // or first childless replaced element
  while ( first && !(first->renderer()
      && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
            || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
  {
    next = first->firstChild();
    if ( !next ) next = first->nextSibling();
    while( first && !next )
    {
      first = first->parentNode();
      if ( first )
        next = first->nextSibling();
    }
    first = next;
  }

  NodeImpl *last;
  if (d->m_doc->isHTMLDocument())
    last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
  else
    last = d->m_doc;
  // Look for last text/cdata node that has a renderer,
  // or last childless replaced element
  // ### Instead of changing this loop, use findLastSelectableNode
  // in render_table.cpp (LS)
  while ( last && !(last->renderer()
      && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
            || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
  {
    next = last->lastChild();
    if ( !next ) next = last->previousSibling();
    while ( last && !next )
    {
      last = last->parentNode();
      if ( last )
        next = last->previousSibling();
    }
    last = next;
  }

  if ( !first || !last )
    return;
  Q_ASSERT(first->renderer());
  Q_ASSERT(last->renderer());
  d->m_selectionStart = first;
  d->m_startOffset = 0;
  d->m_selectionEnd = last;
  d->m_endOffset = last->nodeValue().length();
  d->m_startBeforeEnd = true;

  d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
                          d->m_selectionEnd.handle(), d->m_endOffset );

  emitSelectionChanged();
}

bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
{
  bool linkAllowed = true;

  if ( d->m_doc )
    linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);

  if ( !linkAllowed ) {
    khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
    if (tokenizer)
      tokenizer->setOnHold(true);

    int response = KMessageBox::Cancel;
    if (!message.isEmpty())
    {
          response = KMessageBox::warningContinueCancel( 0,
                                             message.arg(linkURL.htmlURL()),
                                             i18n( "Security Warning" ),
                                             button);
    }
    else
    {
          KMessageBox::error( 0,
                        i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
                        i18n( "Security Alert" ));
    }

    if (tokenizer)
       tokenizer->setOnHold(false);
    return (response==KMessageBox::Continue);
  }
  return true;
}

06838 void KHTMLPart::slotPartRemoved( KParts::Part *part )
{
//    kdDebug(6050) << "KHTMLPart::slotPartRemoved " << part << endl;
    if ( part == d->m_activeFrame )
    {
        d->m_activeFrame = 0L;
        if ( !part->inherits( "KHTMLPart" ) )
        {
            if (factory()) {
                factory()->removeClient( part );
            }
            if (childClients()->containsRef(part)) {
                removeChildClient( part );
            }
        }
    }
}

06856 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
{
//    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged this=" << this << "part=" << part << endl;
    if ( part == this )
    {
        kdError(6050) << "strange error! we activated ourselves" << endl;
        assert( false );
        return;
    }
//    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged d->m_activeFrame=" << d->m_activeFrame << endl;
    if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
    {
        QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
        if (frame->frameStyle() != QFrame::NoFrame)
        {
           frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
           frame->repaint();
        }
    }

    if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
    {
        if (factory()) {
            factory()->removeClient( d->m_activeFrame );
        }
        removeChildClient( d->m_activeFrame );
    }
    if( part && !part->inherits( "KHTMLPart" ) )
    {
        if (factory()) {
            factory()->addClient( part );
        }
        insertChildClient( part );
    }


    d->m_activeFrame = part;

    if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
    {
        QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
        if (frame->frameStyle() != QFrame::NoFrame)
        {
           frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
           frame->repaint();
        }
        kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
    }

    updateActions();

    // (note: childObject returns 0 if the argument is 0)
    d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
}

06911 void KHTMLPart::setActiveNode(const DOM::Node &node)
{
    if (!d->m_doc || !d->m_view)
        return;

    // Set the document's active node
    d->m_doc->setFocusNode(node.handle());

    // Scroll the view if necessary to ensure that the new focus node is visible
    QRect rect  = node.handle()->getRect();
    d->m_view->ensureVisible(rect.right(), rect.bottom());
    d->m_view->ensureVisible(rect.left(), rect.top());
}

06925 DOM::Node KHTMLPart::activeNode() const
{
    return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
}

DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code, QString name, NodeImpl* node )
{
  KJSProxy *proxy = jScript();

  if (!proxy)
    return 0;

  return proxy->createHTMLEventHandler( m_url.url(), name, code, node );
}

KHTMLPart *KHTMLPart::opener()
{
    return d->m_opener;
}

void KHTMLPart::setOpener(KHTMLPart *_opener)
{
    d->m_opener = _opener;
}

bool KHTMLPart::openedByJS()
{
    return d->m_openedByJS;
}

void KHTMLPart::setOpenedByJS(bool _openedByJS)
{
    d->m_openedByJS = _openedByJS;
}

06960 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
{
    khtml::Cache::preloadStyleSheet(url, stylesheet);
}

06965 void KHTMLPart::preloadScript(const QString &url, const QString &script)
{
    khtml::Cache::preloadScript(url, script);
}

QCString KHTMLPart::dcopObjectId() const
{
  QCString id;
  id.sprintf("html-widget%d", d->m_dcop_counter);
  return id;
}

long KHTMLPart::cacheId() const
{
  return d->m_cacheId;
}

06982 bool KHTMLPart::restored() const
{
  return d->m_restored;
}

bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
{
  // parentPart() should be const!
  KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
  if ( parent )
    return parent->pluginPageQuestionAsked(mimetype);

  return d->m_pluginPageQuestionAsked.contains(mimetype);
}

void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
{
  if ( parentPart() )
    parentPart()->setPluginPageQuestionAsked(mimetype);

  d->m_pluginPageQuestionAsked.append(mimetype);
}

07005 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
{
  d->m_automaticDetection->setItemChecked( _id, true );

  switch ( _id ) {
    case 0 :
      d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
      break;
    case 1 :
      d->m_autoDetectLanguage = khtml::Decoder::Arabic;
      break;
    case 2 :
      d->m_autoDetectLanguage = khtml::Decoder::Baltic;
      break;
    case 3 :
      d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
      break;
    case 4 :
      d->m_autoDetectLanguage = khtml::Decoder::Chinese;
      break;
    case 5 :
      d->m_autoDetectLanguage = khtml::Decoder::Greek;
      break;
    case 6 :
      d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
      break;
    case 7 :
      d->m_autoDetectLanguage = khtml::Decoder::Japanese;
      break;
    case 8 :
      d->m_autoDetectLanguage = khtml::Decoder::Korean;
      break;
    case 9 :
      d->m_autoDetectLanguage = khtml::Decoder::Russian;
      break;
    case 10 :
      d->m_autoDetectLanguage = khtml::Decoder::Thai;
      break;
    case 11 :
      d->m_autoDetectLanguage = khtml::Decoder::Turkish;
      break;
    case 12 :
      d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
      break;
    case 13 :
      d->m_autoDetectLanguage = khtml::Decoder::Unicode;
      break;
    case 14 :
      d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
      break;
    default :
      d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
      break;
  }

  for ( int i = 0; i <= 14; ++i ) {
    if ( i != _id )
      d->m_automaticDetection->setItemChecked( i, false );
  }

  d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );

  setEncoding( QString::null, false );

  if( d->m_manualDetection )
    d->m_manualDetection->setCurrentItem( -1 );
  d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
}

khtml::Decoder *KHTMLPart::createDecoder()
{
    khtml::Decoder *dec = new khtml::Decoder();
    if( !d->m_encoding.isNull() )
        dec->setEncoding( d->m_encoding.latin1(),
            d->m_haveEncoding ? khtml::Decoder::UserChosenEncoding : khtml::Decoder::EncodingFromHTTPHeader);
    else {
        // Inherit the default encoding from the parent frame if there is one.
        const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
            ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
        dec->setEncoding(defaultEncoding, khtml::Decoder::DefaultEncoding);
    }
#ifdef APPLE_CHANGES
    if (d->m_doc)
        d->m_doc->setDecoder(d->m_decoder);
#endif
    dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
    return dec;
}

void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
  emit caretPositionChanged(node, offset);
}

07098 void KHTMLPart::restoreScrollPosition()
{
  KParts::URLArgs args = d->m_extension->urlArgs();

  if ( m_url.hasRef() && !d->m_restoreScrollPosition && !args.reload) {
    if ( !d->m_doc || !d->m_doc->parsing() )
      disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
    if ( !gotoAnchor(m_url.encodedHtmlRef()) )
      gotoAnchor(m_url.htmlRef());
    return;
  }

  // Check whether the viewport has become large enough to encompass the stored
  // offsets. If the document has been fully loaded, force the new coordinates,
  // even if the canvas is too short (can happen when user resizes the window
  // during loading).
  if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
      || d->m_bComplete) {
    d->m_view->setContentsPos(args.xOffset, args.yOffset);
    disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
  }
}


void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
{
#ifndef KHTML_NO_WALLET
  KHTMLPart *p;

  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
  }

  if (p) {
    p->openWallet(form);
    return;
  }

  if (onlyLocalReferences()) { // avoid triggering on local apps, thumbnails
    return;
  }

  if (d->m_wallet) {
    if (d->m_bWalletOpened) {
      if (d->m_wallet->isOpen()) {
        form->walletOpened(d->m_wallet);
        return;
      }
      d->m_wallet->deleteLater();
      d->m_wallet = 0L;
      d->m_bWalletOpened = false;
    }
  }

  if (!d->m_wq) {
    KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
    d->m_wq = new KHTMLWalletQueue(this);
    d->m_wq->wallet = wallet;
    connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
    connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
  }
  assert(form);
  d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->getDocument()));
#endif // KHTML_NO_WALLET
}


void KHTMLPart::saveToWallet(const QString& key, const QMap<QString,QString>& data)
{
#ifndef KHTML_NO_WALLET
  KHTMLPart *p;

  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
  }

  if (p) {
    p->saveToWallet(key, data);
    return;
  }

  if (d->m_wallet) {
    if (d->m_bWalletOpened) {
      if (d->m_wallet->isOpen()) {
        if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
          d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
        }
        d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
        d->m_wallet->writeMap(key, data);
        return;
      }
      d->m_wallet->deleteLater();
      d->m_wallet = 0L;
      d->m_bWalletOpened = false;
    }
  }

  if (!d->m_wq) {
    KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
    d->m_wq = new KHTMLWalletQueue(this);
    d->m_wq->wallet = wallet;
    connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
    connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
  }
  d->m_wq->savers.append(qMakePair(key, data));
#endif // KHTML_NO_WALLET
}


void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
#ifndef KHTML_NO_WALLET
  KHTMLPart *p;

  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
  }

  if (p) {
    p->dequeueWallet(form);
    return;
  }

  if (d->m_wq) {
    d->m_wq->callers.remove(KHTMLWalletQueue::Caller(form, form->getDocument()));
  }
#endif // KHTML_NO_WALLET
}


void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
#ifndef KHTML_NO_WALLET
  assert(!d->m_wallet);
  assert(d->m_wq);

  d->m_wq->deleteLater(); // safe?
  d->m_wq = 0L;

  if (!wallet) {
    d->m_bWalletOpened = false;
    return;
  }

  d->m_wallet = wallet;
  d->m_bWalletOpened = true;
  connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));

  if (!d->m_statusBarWalletLabel) {
    d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
    d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
    d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
    d->m_statusBarWalletLabel->setUseCursor(false);
    d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
    d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
    connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedURL()), SLOT(launchWalletManager()));
    connect(d->m_statusBarWalletLabel, SIGNAL(rightClickedURL()), SLOT(walletMenu()));
  } else {
    QToolTip::remove(d->m_statusBarWalletLabel);
  }
  QToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
#endif // KHTML_NO_WALLET
}


KWallet::Wallet *KHTMLPart::wallet()
{
#ifndef KHTML_NO_WALLET
  KHTMLPart *p;

  for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
    ;

  if (p)
    return p->wallet();

#endif // KHTML_NO_WALLET
  return d->m_wallet;
}


void KHTMLPart::slotWalletClosed()
{
#ifndef KHTML_NO_WALLET
  if (d->m_wallet) {
    d->m_wallet->deleteLater();
    d->m_wallet = 0L;
  }
  d->m_bWalletOpened = false;
  if (d->m_statusBarWalletLabel) {
    d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
    delete d->m_statusBarWalletLabel;
    d->m_statusBarWalletLabel = 0L;
  }
#endif // KHTML_NO_WALLET
}

void KHTMLPart::launchWalletManager()
{
#ifndef KHTML_NO_WALLET
  if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
    KApplication::startServiceByDesktopName("kwalletmanager_show");
  } else {
    DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
    r.send("show");
    r.send("raise");
  }
#endif // KHTML_NO_WALLET
}

void KHTMLPart::walletMenu()
{
#ifndef KHTML_NO_WALLET
  KPopupMenu *m = new KPopupMenu(0L);
  m->insertItem(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
  m->popup(QCursor::pos());
#endif // KHTML_NO_WALLET
}

07312 void KHTMLPart::slotToggleCaretMode()
{
  setCaretMode(d->m_paToggleCaretMode->isChecked());
}

07317 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
  d->m_formNotification = fn;
}

07321 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
  return d->m_formNotification;
}

07325 KURL KHTMLPart::toplevelURL()
{
  KHTMLPart* part = this;
  while (part->parentPart())
    part = part->parentPart();

  if (!part)
    return KURL();

  return part->url();
}

07337 bool KHTMLPart::isModified() const
{
  if ( !d->m_doc )
    return false;

  return d->m_doc->unsubmittedFormChanges();
}

void KHTMLPart::setDebugScript( bool enable )
{
  unplugActionList( "debugScriptList" );
  if ( enable ) {
    if (!d->m_paDebugScript) {
      d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
    }
    d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
    QPtrList<KAction> lst;
    lst.append( d->m_paDebugScript );
    plugActionList( "debugScriptList", lst );
  }
  d->m_bJScriptDebugEnabled = enable;
}

07360 void KHTMLPart::setSuppressedPopupIndicator( bool enable )
{
    setSuppressedPopupIndicator( enable, 0 );
}

07365 void KHTMLPart::setSuppressedPopupIndicator( bool enable, KHTMLPart *originPart )
{
    if ( parentPart() ) {
        parentPart()->setSuppressedPopupIndicator( enable, originPart );
        return;
    }

    if ( enable && originPart ) {
        d->m_openableSuppressedPopups++;
        if ( d->m_suppressedPopupOriginParts.findIndex( originPart ) == -1 )
            d->m_suppressedPopupOriginParts.append( originPart );
    }

    if ( enable && !d->m_statusBarPopupLabel ) {
        d->m_statusBarPopupLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
        d->m_statusBarPopupLabel->setFixedHeight( instance()->iconLoader()->currentSize( KIcon::Small) );
        d->m_statusBarPopupLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
        d->m_statusBarPopupLabel->setUseCursor( false );
        d->m_statusBarExtension->addStatusBarItem( d->m_statusBarPopupLabel, 0, false );
        d->m_statusBarPopupLabel->setPixmap( SmallIcon( "window_suppressed", instance() ) );
        QToolTip::add( d->m_statusBarPopupLabel, i18n("This page was prevented from opening a new window via JavaScript." ) );

        connect(d->m_statusBarPopupLabel, SIGNAL(leftClickedURL()), SLOT(suppressedPopupMenu()));
        if (d->m_settings->jsPopupBlockerPassivePopup()) {
            QPixmap px;
            px = MainBarIcon( "window_suppressed" );
            KPassivePopup::message(i18n("Popup Window Blocked"),i18n("This page has attempted to open a popup window but was blocked.\nYou can click on this icon in the status bar to control this behavior\nor to open the popup."),px,d->m_statusBarPopupLabel);
        }
    } else if ( !enable && d->m_statusBarPopupLabel ) {
        QToolTip::remove( d->m_statusBarPopupLabel );
        d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarPopupLabel );
        delete d->m_statusBarPopupLabel;
        d->m_statusBarPopupLabel = 0L;
    }
}

07401 void KHTMLPart::suppressedPopupMenu() {
  KPopupMenu *m = new KPopupMenu(0L);
  m->setCheckable(true);
  if ( d->m_openableSuppressedPopups )
      m->insertItem(i18n("&Show Blocked Popup Window","Show %n Blocked Popup Windows", d->m_openableSuppressedPopups), this, SLOT(showSuppressedPopups()));
  m->insertItem(i18n("Show Blocked Window Passive Popup &Notification"), this, SLOT(togglePopupPassivePopup()),0,57);
  m->setItemChecked(57,d->m_settings->jsPopupBlockerPassivePopup());
  m->insertItem(i18n("&Configure JavaScript New Window Policies..."), this, SLOT(launchJSConfigDialog()));
  m->popup(QCursor::pos());
}

07412 void KHTMLPart::togglePopupPassivePopup() {
  // Same hack as in disableJSErrorExtension()
  d->m_settings->setJSPopupBlockerPassivePopup( !d->m_settings->jsPopupBlockerPassivePopup() );
  DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", QByteArray());
}

07418 void KHTMLPart::showSuppressedPopups() {
    for ( QValueListIterator<QGuardedPtr<KHTMLPart> > i = d->m_suppressedPopupOriginParts.begin();
          i != d->m_suppressedPopupOriginParts.end(); ++i ) {
      if (KHTMLPart* part = *i) {
        KJS::Window *w = KJS::Window::retrieveWindow( part );
        if (w) {
            w->showSuppressedWindows();
            w->forgetSuppressedWindows();
        }
      }
    }
    setSuppressedPopupIndicator( false );
    d->m_openableSuppressedPopups = 0;
    d->m_suppressedPopupOriginParts.clear();
}

// Extension to use for "view document source", "save as" etc.
// Using the right extension can help the viewer get into the right mode (#40496)
07436 QString KHTMLPart::defaultExtension() const
{
    if ( !d->m_doc )
        return ".html";
    if ( !d->m_doc->isHTMLDocument() )
        return ".xml";
    return d->m_doc->htmlMode() == DOM::DocumentImpl::XHtml ? ".xhtml" : ".html";
}

07445 bool KHTMLPart::inProgress() const
{
    if (d->m_runningScripts || (d->m_doc && d->m_doc->parsing()))
        return true;

    // Any frame that hasn't completed yet ?
    ConstFrameIt it = d->m_frames.begin();
    const ConstFrameIt end = d->m_frames.end();
    for (; it != end; ++it ) {
        if ((*it)->m_run || !(*it)->m_bCompleted)
          return true;
    }

    return d->m_submitForm || !d->m_redirectURL.isEmpty() || d->m_redirectionTimer.isActive() || d->m_job;
}

using namespace KParts;
#include "khtml_part.moc"
#include "khtmlpart_p.moc"

Generated by  Doxygen 1.6.0   Back to index