• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • khtml
 

khtml

khtml_part.cpp
00001 // -*- c-basic-offset: 2 -*-
00002 /* This file is part of the KDE project
00003  *
00004  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00005  *                     1999 Lars Knoll <knoll@kde.org>
00006  *                     1999 Antti Koivisto <koivisto@kde.org>
00007  *                     2000 Simon Hausmann <hausmann@kde.org>
00008  *                     2000 Stefan Schimanski <1Stein@gmx.de>
00009  *                     2001-2003 George Staikos <staikos@kde.org>
00010  *                     2001-2003 Dirk Mueller <mueller@kde.org>
00011  *                     2000-2005 David Faure <faure@kde.org>
00012  *                     2002 Apple Computer, Inc.
00013  *
00014  * This library is free software; you can redistribute it and/or
00015  * modify it under the terms of the GNU Library General Public
00016  * License as published by the Free Software Foundation; either
00017  * version 2 of the License, or (at your option) any later version.
00018  *
00019  * This library is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022  * Library General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Library General Public License
00025  * along with this library; see the file COPYING.LIB.  If not, write to
00026  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00027  * Boston, MA 02110-1301, USA.
00028  */
00029 
00030 //#define SPEED_DEBUG
00031 #include "khtml_part.h"
00032 
00033 #include "khtml_pagecache.h"
00034 
00035 #include "dom/dom_string.h"
00036 #include "dom/dom_element.h"
00037 #include "dom/dom_exception.h"
00038 #include "html/html_documentimpl.h"
00039 #include "html/html_baseimpl.h"
00040 #include "html/html_objectimpl.h"
00041 #include "html/html_miscimpl.h"
00042 #include "html/html_imageimpl.h"
00043 #include "html/html_objectimpl.h"
00044 #include "rendering/render_text.h"
00045 #include "rendering/render_frames.h"
00046 #include "rendering/render_layer.h"
00047 #include "misc/htmlhashes.h"
00048 #include "misc/loader.h"
00049 #include "xml/dom2_eventsimpl.h"
00050 #include "xml/dom2_rangeimpl.h"
00051 #include "xml/xml_tokenizer.h"
00052 #include "css/cssstyleselector.h"
00053 #include "css/csshelper.h"
00054 using namespace DOM;
00055 
00056 #include "khtmlview.h"
00057 #include <kparts/partmanager.h>
00058 #include "ecma/kjs_proxy.h"
00059 #include "ecma/kjs_window.h"
00060 #include "khtml_settings.h"
00061 #include "kjserrordlg.h"
00062 
00063 #include <kjs/function.h>
00064 #include <kjs/interpreter.h>
00065 
00066 #include "htmlpageinfo.h"
00067 
00068 #include <sys/types.h>
00069 #include <assert.h>
00070 #include <unistd.h>
00071 
00072 #include <config.h>
00073 
00074 #include <dcopclient.h>
00075 #include <dcopref.h>
00076 #include <kstandarddirs.h>
00077 #include <kstringhandler.h>
00078 #include <kio/job.h>
00079 #include <kio/global.h>
00080 #include <kio/netaccess.h>
00081 #include <kprotocolmanager.h>
00082 #include <kdebug.h>
00083 #include <kiconloader.h>
00084 #include <klocale.h>
00085 #include <kcharsets.h>
00086 #include <kmessagebox.h>
00087 #include <kstdaction.h>
00088 #include <kfiledialog.h>
00089 #include <ktrader.h>
00090 #include <kdatastream.h>
00091 #include <ktempfile.h>
00092 #include <kglobalsettings.h>
00093 #include <kurldrag.h>
00094 #include <kapplication.h>
00095 #include <kparts/browserinterface.h>
00096 #if !defined(QT_NO_DRAGANDDROP)
00097 #include <kmultipledrag.h>
00098 #endif
00099 #include "../kutils/kfinddialog.h"
00100 #include "../kutils/kfind.h"
00101 
00102 #include <ksslcertchain.h>
00103 #include <ksslinfodlg.h>
00104 
00105 #include <kfileitem.h>
00106 #include <kurifilter.h>
00107 #include <kstatusbar.h>
00108 #include <kurllabel.h>
00109 
00110 #include <tqclipboard.h>
00111 #include <tqfile.h>
00112 #include <tqtooltip.h>
00113 #include <tqmetaobject.h>
00114 #include <tqucomextra_p.h>
00115 
00116 #include "khtmlpart_p.h"
00117 #include "kpassivepopup.h"
00118 #include "kpopupmenu.h"
00119 #include "rendering/render_form.h"
00120 #include <kwin.h>
00121 
00122 #define HINT_UTF8   106
00123 
00124 namespace khtml {
00125     class PartStyleSheetLoader : public CachedObjectClient
00126     {
00127     public:
00128         PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
00129         {
00130             m_part = part;
00131             m_cachedSheet = dl->requestStyleSheet(url, TQString(), "text/css",
00132                                                   true /* "user sheet" */);
00133             if (m_cachedSheet)
00134         m_cachedSheet->ref( this );
00135         }
00136         virtual ~PartStyleSheetLoader()
00137         {
00138             if ( m_cachedSheet ) m_cachedSheet->deref(this);
00139         }
00140         virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet, const DOM::DOMString &)
00141         {
00142           if ( m_part )
00143             m_part->setUserStyleSheet( sheet.string() );
00144 
00145             delete this;
00146         }
00147         virtual void error( int, const TQString& ) {
00148           delete this;
00149         }
00150         TQGuardedPtr<KHTMLPart> m_part;
00151         khtml::CachedCSSStyleSheet *m_cachedSheet;
00152     };
00153 }
00154 
00155 void khtml::ChildFrame::liveConnectEvent(const unsigned long, const TQString & event, const KParts::LiveConnectExtension::ArgList & args)
00156 {
00157     if (!m_part || !m_frame || !m_liveconnect)
00158         // hmmm
00159         return;
00160 
00161     TQString script;
00162     script.sprintf("%s(", event.latin1());
00163 
00164     KParts::LiveConnectExtension::ArgList::const_iterator i = args.begin();
00165     const KParts::LiveConnectExtension::ArgList::const_iterator argsBegin = i;
00166     const KParts::LiveConnectExtension::ArgList::const_iterator argsEnd = args.end();
00167 
00168     for ( ; i != argsEnd; ++i) {
00169         if (i != argsBegin)
00170             script += ",";
00171         if ((*i).first == KParts::LiveConnectExtension::TypeString) {
00172             script += "\"";
00173             script += TQString((*i).second).replace('\\', "\\\\").replace('"', "\\\"");
00174             script += "\"";
00175         } else
00176             script += (*i).second;
00177     }
00178     script += ")";
00179     kdDebug(6050) << "khtml::ChildFrame::liveConnectEvent " << script << endl;
00180 
00181     KHTMLPart * part = ::tqqt_cast<KHTMLPart *>(m_part->parent());
00182     if (!part)
00183         return;
00184     if (!m_jscript)
00185         part->framejScript(m_part);
00186     if (m_jscript) {
00187         // we have a jscript => a part in an iframe
00188         KJS::Completion cmp;
00189         m_jscript->evaluate(TQString(), 1, script, 0L, &cmp);
00190     } else
00191         part->executeScript(m_frame->element(), script);
00192 }
00193 
00194 KHTMLFrameList::Iterator KHTMLFrameList::find( const TQString &name )
00195 {
00196     Iterator it = begin();
00197     const Iterator e = end();
00198 
00199     for (; it!=e; ++it )
00200         if ( (*it)->m_name==name )
00201             break;
00202 
00203     return it;
00204 }
00205 
00206 KHTMLPart::KHTMLPart( TQWidget *parentWidget, const char *widgetname, TQObject *parent, const char *name, GUIProfile prof )
00207 : KParts::ReadOnlyPart( parent, name )
00208 {
00209     d = 0;
00210     KHTMLFactory::registerPart( this );
00211     setInstance(  KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00212     // TODO KDE4 - don't load plugins yet
00213     //setInstance( KHTMLFactory::instance(), false );
00214     init( new KHTMLView( this, parentWidget, widgetname ), prof );
00215 }
00216 
00217 KHTMLPart::KHTMLPart( KHTMLView *view, TQObject *parent, const char *name, GUIProfile prof )
00218 : KParts::ReadOnlyPart( parent, name )
00219 {
00220     d = 0;
00221     KHTMLFactory::registerPart( this );
00222     setInstance(  KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00223     // TODO KDE4 - don't load plugins yet
00224     //setInstance( KHTMLFactory::instance(), false );
00225     assert( view );
00226     init( view, prof );
00227 }
00228 
00229 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
00230 {
00231   if ( prof == DefaultGUI )
00232     setXMLFile( "khtml.rc" );
00233   else if ( prof == BrowserViewGUI )
00234     setXMLFile( "khtml_browser.rc" );
00235 
00236   d = new KHTMLPartPrivate(parent());
00237 
00238   d->m_view = view;
00239   setWidget( d->m_view );
00240 
00241   d->m_guiProfile = prof;
00242   d->m_extension = new KHTMLPartBrowserExtension( this, "KHTMLBrowserExtension" );
00243   d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
00244   d->m_statusBarExtension = new KParts::StatusBarExtension( this );
00245   d->m_statusBarIconLabel = 0L;
00246   d->m_statusBarPopupLabel = 0L;
00247   d->m_openableSuppressedPopups = 0;
00248 
00249   d->m_bSecurityInQuestion = false;
00250   d->m_paLoadImages = 0;
00251   d->m_paDebugScript = 0;
00252   d->m_bMousePressed = false;
00253   d->m_bRightMousePressed = false;
00254   d->m_bCleared = false;
00255   d->m_paViewDocument = new KAction( i18n( "View Do&cument Source" ), CTRL + Key_U, this, TQT_SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
00256   d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, TQT_SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
00257   d->m_paViewInfo = new KAction( i18n( "View Document Information" ), CTRL+Key_I, this, TQT_SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
00258   d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, TQT_SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
00259   d->m_paSaveDocument = KStdAction::saveAs( this, TQT_SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
00260   if ( parentPart() )
00261       d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
00262   d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, TQT_SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
00263   d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, TQT_SLOT( slotSecurity() ), actionCollection(), "security" );
00264   d->m_paSecurity->setWhatsThis( i18n( "Security Settings<p>"
00265                                        "Shows the certificate of the displayed page. Only "
00266                        "pages that have been transmitted using a secure, encrypted connection have a "
00267                        "certificate.<p> "
00268                        "Hint: If the image shows a closed lock, the page has been transmitted over a "
00269                        "secure connection.") );
00270   d->m_paDebugRenderTree = new KAction( i18n( "Print Rendering Tree to STDOUT" ), ALT + CTRL + SHIFT + Key_A, this, TQT_SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
00271   d->m_paDebugDOMTree = new KAction( i18n( "Print DOM Tree to STDOUT" ), ALT + CTRL + SHIFT + Key_D, this, TQT_SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
00272   d->m_paStopAnimations = new KAction( i18n( "Stop Animated Images" ), 0, this, TQT_SLOT( slotStopAnimations() ), actionCollection(), "stopAnimations" );
00273 
00274   d->m_paSetEncoding = new KActionMenu( i18n( "Set &Encoding" ), "charset", actionCollection(), "setEncoding" );
00275   d->m_paSetEncoding->setDelayed( false );
00276 
00277   d->m_automaticDetection = new KPopupMenu( 0L );
00278 
00279   d->m_automaticDetection->insertItem( i18n( "Semi-Automatic" ), 0 );
00280   d->m_automaticDetection->insertItem( i18n( "Arabic" ), 1 );
00281   d->m_automaticDetection->insertItem( i18n( "Baltic" ), 2 );
00282   d->m_automaticDetection->insertItem( i18n( "Central European" ), 3 );
00283   //d->m_automaticDetection->insertItem( i18n( "Chinese" ), 4 );
00284   d->m_automaticDetection->insertItem( i18n( "Greek" ), 5 );
00285   d->m_automaticDetection->insertItem( i18n( "Hebrew" ), 6 );
00286   d->m_automaticDetection->insertItem( i18n( "Japanese" ), 7 );
00287   //d->m_automaticDetection->insertItem( i18n( "Korean" ), 8 );
00288   d->m_automaticDetection->insertItem( i18n( "Russian" ), 9 );
00289   //d->m_automaticDetection->insertItem( i18n( "Thai" ), 10 );
00290   d->m_automaticDetection->insertItem( i18n( "Turkish" ), 11 );
00291   d->m_automaticDetection->insertItem( i18n( "Ukrainian" ), 12 );
00292   //d->m_automaticDetection->insertItem( i18n( "Unicode" ), 13 );
00293   d->m_automaticDetection->insertItem( i18n( "Western European" ), 14 );
00294 
00295   connect( d->m_automaticDetection, TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotAutomaticDetectionLanguage( int ) ) );
00296 
00297   d->m_paSetEncoding->popupMenu()->insertItem( i18n( "Automatic Detection" ), d->m_automaticDetection, 0 );
00298 
00299   d->m_paSetEncoding->insert( new KActionSeparator( actionCollection() ) );
00300 
00301 
00302   d->m_manualDetection = new KSelectAction( i18n( "short for Manual Detection", "Manual" ), 0, this, TQT_SLOT( slotSetEncoding() ), actionCollection(), "manualDetection" );
00303   TQStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
00304   d->m_manualDetection->setItems( encodings );
00305   d->m_manualDetection->setCurrentItem( -1 );
00306   d->m_paSetEncoding->insert( d->m_manualDetection );
00307 
00308 
00309   KConfig *config = KGlobal::config();
00310   if ( config->hasGroup( "HTML Settings" ) ) {
00311     config->setGroup( "HTML Settings" );
00312     khtml::Decoder::AutoDetectLanguage language;
00313     TQCString name = TQTextCodec::codecForLocale()->name();
00314     name = name.lower();
00315 
00316     if ( name == "cp1256" || name == "iso-8859-6" ) {
00317       language = khtml::Decoder::Arabic;
00318     }
00319     else if ( name == "cp1257" || name == "iso-8859-13" || name == "iso-8859-4" ) {
00320       language = khtml::Decoder::Baltic;
00321     }
00322     else if ( name == "cp1250" || name == "ibm852" || name == "iso-8859-2" || name == "iso-8859-3" ) {
00323       language = khtml::Decoder::CentralEuropean;
00324     }
00325     else if ( name == "cp1251" || name == "koi8-r" || name == "iso-8859-5" ) {
00326       language = khtml::Decoder::Russian;
00327     }
00328     else if ( name == "koi8-u" ) {
00329       language = khtml::Decoder::Ukrainian;
00330     }
00331     else if ( name == "cp1253" || name == "iso-8859-7" ) {
00332       language = khtml::Decoder::Greek;
00333     }
00334     else if ( name == "cp1255" || name == "iso-8859-8" || name == "iso-8859-8-i" ) {
00335       language = khtml::Decoder::Hebrew;
00336     }
00337     else if ( name == "jis7" || name == "eucjp" || name == "sjis"  ) {
00338       language = khtml::Decoder::Japanese;
00339     }
00340     else if ( name == "cp1254" || name == "iso-8859-9" ) {
00341       language = khtml::Decoder::Turkish;
00342     }
00343     else if ( name == "cp1252" || name == "iso-8859-1" || name == "iso-8859-15" ) {
00344       language = khtml::Decoder::WesternEuropean;
00345     }
00346     else
00347       language = khtml::Decoder::SemiautomaticDetection;
00348 
00349     int _id = config->readNumEntry( "AutomaticDetectionLanguage", language );
00350     d->m_automaticDetection->setItemChecked( _id, true );
00351     d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
00352 
00353     d->m_autoDetectLanguage = static_cast< khtml::Decoder::AutoDetectLanguage >( _id );
00354   }
00355 
00356 
00357   d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, TQT_SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
00358 
00359   if ( prof == BrowserViewGUI ) {
00360       d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n(
00361                   "Enlarge Font" ), "viewmag+", "CTRL++;CTRL+=", this,
00362               TQT_SLOT( slotIncZoomFast() ), actionCollection(), "incFontSizes" );
00363       d->m_paIncZoomFactor->setWhatsThis( i18n( "Enlarge Font<p>"
00364                                                 "Make the font in this window bigger. "
00365                             "Click and hold down the mouse button for a menu with all available font sizes." ) );
00366       d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n(
00367                   "Shrink Font" ), "viewmag-", CTRL + Key_Minus, this,
00368               TQT_SLOT( slotDecZoomFast() ), actionCollection(), "decFontSizes" );
00369       d->m_paDecZoomFactor->setWhatsThis( i18n( "Shrink Font<p>"
00370                                                 "Make the font in this window smaller. "
00371                             "Click and hold down the mouse button for a menu with all available font sizes." ) );
00372   }
00373 
00374   d->m_paFind = KStdAction::find( this, TQT_SLOT( slotFind() ), actionCollection(), "find" );
00375   d->m_paFind->setWhatsThis( i18n( "Find text<p>"
00376                    "Shows a dialog that allows you to find text on the displayed page." ) );
00377 
00378   d->m_paFindNext = KStdAction::findNext( this, TQT_SLOT( slotFindNext() ), actionCollection(), "findNext" );
00379   d->m_paFindNext->setWhatsThis( i18n( "Find next<p>"
00380                        "Find the next occurrence of the text that you "
00381                        "have found using the <b>Find Text</b> function" ) );
00382 
00383   d->m_paFindPrev = KStdAction::findPrev( this, TQT_SLOT( slotFindPrev() ), actionCollection(), "findPrevious" );
00384   d->m_paFindPrev->setWhatsThis( i18n( "Find previous<p>"
00385                        "Find the previous occurrence of the text that you "
00386                        "have found using the <b>Find Text</b> function" ) );
00387 
00388   d->m_paFindAheadText = new KAction( i18n("Find Text as You Type"), KShortcut( '/' ), this, TQT_SLOT( slotFindAheadText()),
00389       actionCollection(), "findAheadText");
00390   d->m_paFindAheadLinks = new KAction( i18n("Find Links as You Type"), KShortcut( '\'' ), this, TQT_SLOT( slotFindAheadLink()),
00391       actionCollection(), "findAheadLink");
00392   d->m_paFindAheadText->setEnabled( false );
00393   d->m_paFindAheadLinks->setEnabled( false );
00394 
00395   if ( parentPart() )
00396   {
00397       d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
00398       d->m_paFindNext->setShortcut( KShortcut() ); // avoid clashes
00399       d->m_paFindPrev->setShortcut( KShortcut() ); // avoid clashes
00400       d->m_paFindAheadText->setShortcut( KShortcut());
00401       d->m_paFindAheadLinks->setShortcut( KShortcut());
00402   }
00403 
00404   d->m_paPrintFrame = new KAction( i18n( "Print Frame..." ), "frameprint", 0, this, TQT_SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
00405   d->m_paPrintFrame->setWhatsThis( i18n( "Print Frame<p>"
00406                      "Some pages have several frames. To print only a single frame, click "
00407                      "on it and then use this function." ) );
00408 
00409   d->m_paSelectAll = KStdAction::selectAll( this, TQT_SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
00410   if ( parentPart() )
00411       d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
00412 
00413   d->m_paToggleCaretMode = new KToggleAction(i18n("Toggle Caret Mode"),
00414                 Key_F7, this, TQT_SLOT(slotToggleCaretMode()),
00415                                 actionCollection(), "caretMode");
00416   d->m_paToggleCaretMode->setChecked(isCaretMode());
00417   if (parentPart())
00418       d->m_paToggleCaretMode->setShortcut(KShortcut()); // avoid clashes
00419 
00420   // set the default java(script) flags according to the current host.
00421   d->m_bOpenMiddleClick = d->m_settings->isOpenMiddleClickEnabled();
00422   d->m_bBackRightClick = d->m_settings->isBackRightClickEnabled();
00423   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
00424   setDebugScript( d->m_settings->isJavaScriptDebugEnabled() );
00425   d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
00426   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
00427 
00428   // Set the meta-refresh flag...
00429   d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();
00430 
00431   connect( view, TQT_SIGNAL( zoomView( int ) ), TQT_SLOT( slotZoomView( int ) ) );
00432 
00433   connect( this, TQT_SIGNAL( completed() ),
00434            this, TQT_SLOT( updateActions() ) );
00435   connect( this, TQT_SIGNAL( completed( bool ) ),
00436            this, TQT_SLOT( updateActions() ) );
00437   connect( this, TQT_SIGNAL( started( KIO::Job * ) ),
00438            this, TQT_SLOT( updateActions() ) );
00439 
00440   d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
00441 
00442   connect( khtml::Cache::loader(), TQT_SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00443            this, TQT_SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00444   connect( khtml::Cache::loader(), TQT_SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00445            this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00446   connect( khtml::Cache::loader(), TQT_SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00447            this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00448 
00449   connect ( &d->m_progressUpdateTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotProgressUpdate() ) );
00450 
00451   findTextBegin(); //reset find variables
00452 
00453   connect( &d->m_redirectionTimer, TQT_SIGNAL( timeout() ),
00454            this, TQT_SLOT( slotRedirect() ) );
00455 
00456   d->m_dcopobject = new KHTMLPartIface(this);
00457 
00458   // TODO KDE4 - load plugins now (see also the constructors)
00459   //if ( prof == BrowserViewGUI && !parentPart() )
00460   //        loadPlugins( partObject(), this, instance() );
00461 
00462   // "khtml" catalog does not exist, our translations are in kdelibs.
00463   // removing this catalog from KGlobal::locale() prevents problems
00464   // with changing the language in applications at runtime -Thomas Reitelbach
00465   KGlobal::locale()->removeCatalogue("khtml");
00466 }
00467 
00468 KHTMLPart::~KHTMLPart()
00469 {
00470   //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
00471 
00472   KConfig *config = KGlobal::config();
00473   config->setGroup( "HTML Settings" );
00474   config->writeEntry( "AutomaticDetectionLanguage", d->m_autoDetectLanguage );
00475 
00476   delete d->m_automaticDetection;
00477   delete d->m_manualDetection;
00478 
00479   slotWalletClosed();
00480   if (!parentPart()) { // only delete it if the top khtml_part closes
00481     removeJSErrorExtension();
00482     delete d->m_statusBarPopupLabel;
00483   }
00484 
00485   d->m_find = 0; // deleted by its parent, the view.
00486 
00487   if ( d->m_manager )
00488   {
00489     d->m_manager->setActivePart( 0 );
00490     // We specify "this" as parent qobject for d->manager, so no need to delete it.
00491   }
00492 
00493   stopAutoScroll();
00494   d->m_redirectionTimer.stop();
00495 
00496   if (!d->m_bComplete)
00497     closeURL();
00498 
00499   disconnect( khtml::Cache::loader(), TQT_SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00500            this, TQT_SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00501   disconnect( khtml::Cache::loader(), TQT_SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00502            this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00503   disconnect( khtml::Cache::loader(), TQT_SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00504            this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00505 
00506   clear();
00507 
00508   if ( d->m_view )
00509   {
00510     d->m_view->hide();
00511     d->m_view->viewport()->hide();
00512     d->m_view->m_part = 0;
00513   }
00514 
00515   // Have to delete this here since we forward declare it in khtmlpart_p and
00516   // at least some compilers won't call the destructor in this case.
00517   delete d->m_jsedlg;
00518   d->m_jsedlg = 0;
00519 
00520   if (!parentPart()) // only delete d->m_frame if the top khtml_part closes
00521       delete d->m_frame;
00522   delete d; d = 0;
00523   KHTMLFactory::deregisterPart( this );
00524 }
00525 
00526 bool KHTMLPart::restoreURL( const KURL &url )
00527 {
00528   kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
00529 
00530   d->m_redirectionTimer.stop();
00531 
00532   /*
00533    * That's not a good idea as it will call closeURL() on all
00534    * child frames, preventing them from further loading. This
00535    * method gets called from restoreState() in case of a full frameset
00536    * restoral, and restoreState() calls closeURL() before restoring
00537    * anyway.
00538   kdDebug( 6050 ) << "closing old URL" << endl;
00539   closeURL();
00540   */
00541 
00542   d->m_bComplete = false;
00543   d->m_bLoadEventEmitted = false;
00544   d->m_workingURL = url;
00545 
00546   // set the java(script) flags according to the current host.
00547   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00548   setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
00549   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00550   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00551 
00552   m_url = url;
00553 
00554   d->m_restoreScrollPosition = true;
00555   disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
00556   connect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
00557 
00558   KHTMLPageCache::self()->fetchData( d->m_cacheId, this, TQT_SLOT(slotRestoreData(const TQByteArray &)));
00559 
00560   emit started( 0L );
00561 
00562   return true;
00563 }
00564 
00565 
00566 bool KHTMLPart::openURL( const KURL &url )
00567 {
00568   kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
00569 
00570   d->m_redirectionTimer.stop();
00571 
00572   // check to see if this is an "error://" URL. This is caused when an error
00573   // occurs before this part was loaded (e.g. KonqRun), and is passed to
00574   // khtmlpart so that it can display the error.
00575   if ( url.protocol() == "error" && url.hasSubURL() ) {
00576     closeURL();
00577 
00578     if(  d->m_bJScriptEnabled )
00579       d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = TQString();
00580 
00586     KURL::List urls = KURL::split( url );
00587     //kdDebug(6050) << "Handling error URL. URL count:" << urls.count() << endl;
00588 
00589     if ( urls.count() > 1 ) {
00590       KURL mainURL = urls.first();
00591       int error = mainURL.queryItem( "error" ).toInt();
00592       // error=0 isn't a valid error code, so 0 means it's missing from the URL
00593       if ( error == 0 ) error = KIO::ERR_UNKNOWN;
00594       TQString errorText = mainURL.queryItem( "errText", HINT_UTF8 );
00595       urls.pop_front();
00596       d->m_workingURL = KURL::join( urls );
00597       //kdDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
00598       emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
00599       htmlError( error, errorText, d->m_workingURL );
00600       return true;
00601     }
00602   }
00603 
00604   if (!parentPart()) { // only do it for toplevel part
00605     TQString host = url.isLocalFile() ? "localhost" : url.host();
00606     TQString userAgent = KProtocolManager::userAgentForHost(host);
00607     if (userAgent != KProtocolManager::userAgentForHost(TQString())) {
00608       if (!d->m_statusBarUALabel) {
00609         d->m_statusBarUALabel = new KURLLabel(d->m_statusBarExtension->statusBar());
00610         d->m_statusBarUALabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
00611         d->m_statusBarUALabel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
00612         d->m_statusBarUALabel->setUseCursor(false);
00613         d->m_statusBarExtension->addStatusBarItem(d->m_statusBarUALabel, 0, false);
00614         d->m_statusBarUALabel->setPixmap(SmallIcon("agent", instance()));
00615       } else {
00616         TQToolTip::remove(d->m_statusBarUALabel);
00617       }
00618       TQToolTip::add(d->m_statusBarUALabel, i18n("The fake user-agent '%1' is in use.").arg(userAgent));
00619     } else if (d->m_statusBarUALabel) {
00620       d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarUALabel);
00621       delete d->m_statusBarUALabel;
00622       d->m_statusBarUALabel = 0L;
00623     }
00624   }
00625 
00626   KParts::URLArgs args( d->m_extension->urlArgs() );
00627 
00628   // in case
00629   // a) we have no frameset (don't test m_frames.count(), iframes get in there)
00630   // b) the url is identical with the currently displayed one (except for the htmlref!)
00631   // c) the url request is not a POST operation and
00632   // d) the caller did not request to reload the page
00633   // e) there was no HTTP redirection meanwhile (testcase: webmin's software/tree.cgi)
00634   // => we don't reload the whole document and
00635   // we just jump to the requested html anchor
00636   bool isFrameSet = false;
00637   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00638       HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
00639       isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
00640   }
00641 
00642   if ( url.hasRef() && !isFrameSet )
00643   {
00644     bool noReloadForced = !args.reload && !args.redirectedRequest() && !args.doPost();
00645     if (noReloadForced && urlcmp( url.url(), m_url.url(), true, true ))
00646     {
00647         kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
00648         m_url = url;
00649         emit started( 0L );
00650 
00651         if ( !gotoAnchor( url.encodedHtmlRef()) )
00652           gotoAnchor( url.htmlRef() );
00653 
00654         d->m_bComplete = true;
00655         if (d->m_doc)
00656         d->m_doc->setParsing(false);
00657 
00658         kdDebug( 6050 ) << "completed..." << endl;
00659         emit completed();
00660         return true;
00661     }
00662   }
00663 
00664   // Save offset of viewport when page is reloaded to be compliant
00665   // to every other capable browser out there.
00666   if (args.reload) {
00667     args.xOffset = d->m_view->contentsX();
00668     args.yOffset = d->m_view->contentsY();
00669     d->m_extension->setURLArgs(args);
00670   }
00671 
00672   if (!d->m_restored)
00673     closeURL();
00674 
00675   d->m_restoreScrollPosition = d->m_restored;
00676   disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
00677   connect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
00678 
00679   // 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
00680   // data arrives) (Simon)
00681   m_url = url;
00682   if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
00683      m_url.path().isEmpty()) {
00684     m_url.setPath("/");
00685     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00686   }
00687   // copy to m_workingURL after fixing m_url above
00688   d->m_workingURL = m_url;
00689 
00690   args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
00691   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
00692   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
00693   args.metaData().insert("PropagateHttpHeader", "true");
00694   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
00695   args.metaData().insert("ssl_activate_warnings", "TRUE" );
00696   args.metaData().insert("cross-domain", toplevelURL().url());
00697 
00698   if (d->m_restored)
00699   {
00700      args.metaData().insert("referrer", d->m_pageReferrer);
00701      d->m_cachePolicy = KIO::CC_Cache;
00702   }
00703   else if (args.reload)
00704      d->m_cachePolicy = KIO::CC_Reload;
00705   else
00706      d->m_cachePolicy = KProtocolManager::cacheControl();
00707 
00708   if ( args.doPost() && (m_url.protocol().startsWith("http")) )
00709   {
00710       d->m_job = KIO::http_post( m_url, args.postData, false );
00711       d->m_job->addMetaData("content-type", args.contentType() );
00712   }
00713   else
00714   {
00715       d->m_job = KIO::get( m_url, false, false );
00716       d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
00717   }
00718 
00719   if (widget())
00720      d->m_job->setWindow(widget()->topLevelWidget());
00721   d->m_job->addMetaData(args.metaData());
00722 
00723   connect( d->m_job, TQT_SIGNAL( result( KIO::Job* ) ),
00724            TQT_SLOT( slotFinished( KIO::Job* ) ) );
00725   connect( d->m_job, TQT_SIGNAL( data( KIO::Job*, const TQByteArray& ) ),
00726            TQT_SLOT( slotData( KIO::Job*, const TQByteArray& ) ) );
00727   connect ( d->m_job, TQT_SIGNAL( infoMessage( KIO::Job*, const TQString& ) ),
00728            TQT_SLOT( slotInfoMessage(KIO::Job*, const TQString& ) ) );
00729   connect( d->m_job, TQT_SIGNAL(redirection(KIO::Job*, const KURL& ) ),
00730            TQT_SLOT( slotRedirection(KIO::Job*, const KURL&) ) );
00731 
00732   d->m_bComplete = false;
00733   d->m_bLoadEventEmitted = false;
00734 
00735   // delete old status bar msg's from kjs (if it _was_ activated on last URL)
00736   if( d->m_bJScriptEnabled )
00737     d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = TQString();
00738 
00739   // set the javascript flags according to the current url
00740   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00741   setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
00742   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00743   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00744 
00745 
00746   connect( d->m_job, TQT_SIGNAL( speed( KIO::Job*, unsigned long ) ),
00747            this, TQT_SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
00748 
00749   connect( d->m_job, TQT_SIGNAL( percent( KIO::Job*, unsigned long ) ),
00750            this, TQT_SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
00751 
00752   connect( d->m_job, TQT_SIGNAL( result( KIO::Job* ) ),
00753            this, TQT_SLOT( slotJobDone( KIO::Job* ) ) );
00754 
00755   d->m_jobspeed = 0;
00756 
00757   // If this was an explicit reload and the user style sheet should be used,
00758   // do a stat to see whether the stylesheet was changed in the meanwhile.
00759   if ( args.reload && !settings()->userStyleSheet().isEmpty() ) {
00760     KURL url( settings()->userStyleSheet() );
00761     KIO::StatJob *job = KIO::stat( url, false /* don't show progress */ );
00762     connect( job, TQT_SIGNAL( result( KIO::Job * ) ),
00763              this, TQT_SLOT( slotUserSheetStatDone( KIO::Job * ) ) );
00764   }
00765   emit started( 0L );
00766 
00767   return true;
00768 }
00769 
00770 bool KHTMLPart::closeURL()
00771 {
00772   if ( d->m_job )
00773   {
00774     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
00775     d->m_job->kill();
00776     d->m_job = 0;
00777   }
00778 
00779   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00780     HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
00781 
00782     if ( hdoc->body() && d->m_bLoadEventEmitted ) {
00783       hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
00784       if ( d->m_doc )
00785         d->m_doc->updateRendering();
00786       d->m_bLoadEventEmitted = false;
00787     }
00788   }
00789 
00790   d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
00791   d->m_bLoadEventEmitted = true; // don't want that one either
00792   d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
00793 
00794   disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
00795 
00796   KHTMLPageCache::self()->cancelFetch(this);
00797   if ( d->m_doc && d->m_doc->parsing() )
00798   {
00799     kdDebug( 6050 ) << " was still parsing... calling end " << endl;
00800     slotFinishedParsing();
00801     d->m_doc->setParsing(false);
00802   }
00803 
00804   if ( !d->m_workingURL.isEmpty() )
00805   {
00806     // Aborted before starting to render
00807     kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
00808     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00809   }
00810 
00811   d->m_workingURL = KURL();
00812 
00813   if ( d->m_doc && d->m_doc->docLoader() )
00814     khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
00815 
00816   // tell all subframes to stop as well
00817   {
00818     ConstFrameIt it = d->m_frames.begin();
00819     const ConstFrameIt end = d->m_frames.end();
00820     for (; it != end; ++it )
00821     {
00822       if ( (*it)->m_run )
00823         (*it)->m_run->abort();
00824       if ( !( *it )->m_part.isNull() )
00825         ( *it )->m_part->closeURL();
00826     }
00827   }
00828   // tell all objects to stop as well
00829   {
00830     ConstFrameIt it = d->m_objects.begin();
00831     const ConstFrameIt end = d->m_objects.end();
00832     for (; it != end; ++it)
00833     {
00834       if ( !( *it )->m_part.isNull() )
00835         ( *it )->m_part->closeURL();
00836     }
00837   }
00838   // Stop any started redirections as well!! (DA)
00839   if ( d && d->m_redirectionTimer.isActive() )
00840     d->m_redirectionTimer.stop();
00841 
00842   // null node activated.
00843   emit nodeActivated(Node());
00844 
00845   // make sure before clear() runs, we pop out of a dialog's message loop
00846   if ( d->m_view )
00847     d->m_view->closeChildDialogs();
00848 
00849   return true;
00850 }
00851 
00852 DOM::HTMLDocument KHTMLPart::htmlDocument() const
00853 {
00854   if (d->m_doc && d->m_doc->isHTMLDocument())
00855     return static_cast<HTMLDocumentImpl*>(d->m_doc);
00856   else
00857     return static_cast<HTMLDocumentImpl*>(0);
00858 }
00859 
00860 DOM::Document KHTMLPart::document() const
00861 {
00862     return d->m_doc;
00863 }
00864 
00865 TQString KHTMLPart::documentSource() const
00866 {
00867   TQString sourceStr;
00868   if ( !( m_url.isLocalFile() ) && KHTMLPageCache::self()->isComplete( d->m_cacheId ) )
00869   {
00870      TQByteArray sourceArray;
00871      TQDataStream dataStream( sourceArray, IO_WriteOnly );
00872      KHTMLPageCache::self()->saveData( d->m_cacheId, &dataStream );
00873      TQTextStream stream( sourceArray, IO_ReadOnly );
00874      stream.setCodec( TQTextCodec::codecForName( encoding().latin1() ) );
00875      sourceStr = stream.read();
00876   } else
00877   {
00878     TQString tmpFile;
00879     if( KIO::NetAccess::download( m_url, tmpFile, NULL ) )
00880     {
00881       TQFile f( tmpFile );
00882       if ( f.open( IO_ReadOnly ) )
00883       {
00884         TQTextStream stream( &f );
00885         stream.setCodec( TQTextCodec::codecForName( encoding().latin1() ) );
00886     sourceStr = stream.read();
00887         f.close();
00888       }
00889       KIO::NetAccess::removeTempFile( tmpFile );
00890     }
00891   }
00892 
00893   return sourceStr;
00894 }
00895 
00896 
00897 KParts::BrowserExtension *KHTMLPart::browserExtension() const
00898 {
00899   return d->m_extension;
00900 }
00901 
00902 KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
00903 {
00904   return d->m_hostExtension;
00905 }
00906 
00907 KHTMLView *KHTMLPart::view() const
00908 {
00909   return d->m_view;
00910 }
00911 
00912 void KHTMLPart::setStatusMessagesEnabled( bool enable )
00913 {
00914   d->m_statusMessagesEnabled = enable;
00915 }
00916 
00917 KJS::Interpreter *KHTMLPart::jScriptInterpreter()
00918 {
00919   KJSProxy *proxy = jScript();
00920   if (!proxy || proxy->paused())
00921     return 0;
00922 
00923   return proxy->interpreter();
00924 }
00925 
00926 bool KHTMLPart::statusMessagesEnabled() const
00927 {
00928   return d->m_statusMessagesEnabled;
00929 }
00930 
00931 void KHTMLPart::setJScriptEnabled( bool enable )
00932 {
00933   if ( !enable && jScriptEnabled() && d->m_frame && d->m_frame->m_jscript ) {
00934     d->m_frame->m_jscript->clear();
00935   }
00936   d->m_bJScriptForce = enable;
00937   d->m_bJScriptOverride = true;
00938 }
00939 
00940 bool KHTMLPart::jScriptEnabled() const
00941 {
00942   if(onlyLocalReferences()) return false;
00943 
00944   if ( d->m_bJScriptOverride )
00945       return d->m_bJScriptForce;
00946   return d->m_bJScriptEnabled;
00947 }
00948 
00949 void KHTMLPart::setMetaRefreshEnabled( bool enable )
00950 {
00951   d->m_metaRefreshEnabled = enable;
00952 }
00953 
00954 bool KHTMLPart::metaRefreshEnabled() const
00955 {
00956   return d->m_metaRefreshEnabled;
00957 }
00958 
00959 // Define this to disable dlopening kjs_html, when directly linking to it.
00960 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
00961 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
00962 //        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
00963 //        Also, change the order of "ecma" and "." in khtml's SUBDIRS line.
00964 // OK - that's the default now, use the opposite of the above instructions to go back
00965 // to "dlopening it" - but it breaks exception catching in kjs_binding.cpp
00966 #define DIRECT_LINKAGE_TO_ECMA
00967 
00968 #ifdef DIRECT_LINKAGE_TO_ECMA
00969 extern "C" { KJSProxy *kjs_html_init(khtml::ChildFrame * childframe); }
00970 #endif
00971 
00972 static bool createJScript(khtml::ChildFrame *frame)
00973 {
00974 #ifndef DIRECT_LINKAGE_TO_ECMA
00975   KLibrary *lib = KLibLoader::self()->library("kjs_html");
00976   if ( !lib ) {
00977     setJScriptEnabled( false );
00978     return false;
00979   }
00980   // look for plain C init function
00981   void *sym = lib->symbol("kjs_html_init");
00982   if ( !sym ) {
00983     lib->unload();
00984     setJScriptEnabled( false );
00985     return false;
00986   }
00987   typedef KJSProxy* (*initFunction)(khtml::ChildFrame *);
00988   initFunction initSym = (initFunction) sym;
00989   frame->m_jscript = (*initSym)(d->m_frame);
00990   frame->m_kjs_lib = lib;
00991 #else
00992   frame->m_jscript = kjs_html_init(frame);
00993   // frame->m_kjs_lib remains 0L.
00994 #endif
00995   return true;
00996 }
00997 
00998 KJSProxy *KHTMLPart::jScript()
00999 {
01000   if (!jScriptEnabled()) return 0;
01001 
01002   if ( !d->m_frame ) {
01003       KHTMLPart * p = parentPart();
01004       if (!p) {
01005           d->m_frame = new khtml::ChildFrame;
01006           d->m_frame->m_part = this;
01007       } else {
01008           ConstFrameIt it = p->d->m_frames.begin();
01009           const ConstFrameIt end = p->d->m_frames.end();
01010           for (; it != end; ++it)
01011               if ((*it)->m_part.operator->() == this) {
01012                   d->m_frame = *it;
01013                   break;
01014               }
01015       }
01016       if ( !d->m_frame )
01017         return 0;
01018   }
01019   if ( !d->m_frame->m_jscript )
01020     if (!createJScript(d->m_frame))
01021       return 0;
01022   if (d->m_bJScriptDebugEnabled)
01023     d->m_frame->m_jscript->setDebugEnabled(true);
01024 
01025   return d->m_frame->m_jscript;
01026 }
01027 
01028 TQVariant KHTMLPart::crossFrameExecuteScript(const TQString& target,  const TQString& script)
01029 {
01030   KHTMLPart* destpart = this;
01031 
01032   TQString trg = target.lower();
01033 
01034   if (target == "_top") {
01035     while (destpart->parentPart())
01036       destpart = destpart->parentPart();
01037   }
01038   else if (target == "_parent") {
01039     if (parentPart())
01040       destpart = parentPart();
01041   }
01042   else if (target == "_self" || target == "_blank")  {
01043     // we always allow these
01044   }
01045   else {
01046     destpart = findFrame(target);
01047     if (!destpart)
01048        destpart = this;
01049   }
01050 
01051   // easy way out?
01052   if (destpart == this)
01053     return executeScript(DOM::Node(), script);
01054 
01055   // now compare the domains
01056   if (destpart->checkFrameAccess(this))
01057     return destpart->executeScript(DOM::Node(), script);
01058 
01059   // eww, something went wrong. better execute it in our frame
01060   return executeScript(DOM::Node(), script);
01061 }
01062 
01063 //Enable this to see all JS scripts being executed
01064 //#define KJS_VERBOSE
01065 
01066 KJSErrorDlg *KHTMLPart::jsErrorExtension() {
01067   if (!d->m_settings->jsErrorsEnabled()) {
01068     return 0L;
01069   }
01070 
01071   if (parentPart()) {
01072     return parentPart()->jsErrorExtension();
01073   }
01074 
01075   if (!d->m_statusBarJSErrorLabel) {
01076     d->m_statusBarJSErrorLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
01077     d->m_statusBarJSErrorLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
01078     d->m_statusBarJSErrorLabel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
01079     d->m_statusBarJSErrorLabel->setUseCursor(false);
01080     d->m_statusBarExtension->addStatusBarItem(d->m_statusBarJSErrorLabel, 0, false);
01081     TQToolTip::add(d->m_statusBarJSErrorLabel, i18n("This web page contains coding errors."));
01082     d->m_statusBarJSErrorLabel->setPixmap(SmallIcon("bug", instance()));
01083     connect(d->m_statusBarJSErrorLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(launchJSErrorDialog()));
01084     connect(d->m_statusBarJSErrorLabel, TQT_SIGNAL(rightClickedURL()), TQT_SLOT(jsErrorDialogContextMenu()));
01085   }
01086   if (!d->m_jsedlg) {
01087     d->m_jsedlg = new KJSErrorDlg;
01088     d->m_jsedlg->setURL(m_url.prettyURL());
01089     if (KGlobalSettings::showIconsOnPushButtons()) {
01090       d->m_jsedlg->_clear->setIconSet(SmallIconSet("locationbar_erase"));
01091       d->m_jsedlg->_close->setIconSet(SmallIconSet("fileclose"));
01092     }
01093   }
01094   return d->m_jsedlg;
01095 }
01096 
01097 void KHTMLPart::removeJSErrorExtension() {
01098   if (parentPart()) {
01099     parentPart()->removeJSErrorExtension();
01100     return;
01101   }
01102   if (d->m_statusBarJSErrorLabel != 0) {
01103     d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarJSErrorLabel );
01104     delete d->m_statusBarJSErrorLabel;
01105     d->m_statusBarJSErrorLabel = 0;
01106   }
01107   delete d->m_jsedlg;
01108   d->m_jsedlg = 0;
01109 }
01110 
01111 void KHTMLPart::disableJSErrorExtension() {
01112   removeJSErrorExtension();
01113   // These two lines are really kind of hacky, and it sucks to do this inside
01114   // KHTML but I don't know of anything that's reasonably easy as an alternative
01115   // right now.  It makes me wonder if there should be a more clean way to
01116   // contact all running "KHTML" instance as opposed to Konqueror instances too.
01117   d->m_settings->setJSErrorsEnabled(false);
01118   DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", TQByteArray());
01119 }
01120 
01121 void KHTMLPart::jsErrorDialogContextMenu() {
01122   KPopupMenu *m = new KPopupMenu(0L);
01123   m->insertItem(i18n("&Hide Errors"), this, TQT_SLOT(removeJSErrorExtension()));
01124   m->insertItem(i18n("&Disable Error Reporting"), this, TQT_SLOT(disableJSErrorExtension()));
01125   m->popup(TQCursor::pos());
01126 }
01127 
01128 void KHTMLPart::launchJSErrorDialog() {
01129   KJSErrorDlg *dlg = jsErrorExtension();
01130   if (dlg) {
01131     dlg->show();
01132     dlg->raise();
01133   }
01134 }
01135 
01136 void KHTMLPart::launchJSConfigDialog() {
01137   TQStringList args;
01138   args << "khtml_java_js";
01139   KApplication::kdeinitExec( "kcmshell", args );
01140 }
01141 
01142 TQVariant KHTMLPart::executeScript(const TQString& filename, int baseLine, const DOM::Node& n, const TQString& script)
01143 {
01144 #ifdef KJS_VERBOSE
01145   // The script is now printed by KJS's Parser::parse
01146   kdDebug(6070) << "executeScript: caller='" << name() << "' filename=" << filename << " baseLine=" << baseLine /*<< " script=" << script*/ << endl;
01147 #endif
01148   KJSProxy *proxy = jScript();
01149 
01150   if (!proxy || proxy->paused())
01151     return TQVariant();
01152 
01153   KJS::Completion comp;
01154 
01155   TQVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);
01156 
01157   /*
01158    *  Error handling
01159    */
01160   if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
01161     KJSErrorDlg *dlg = jsErrorExtension();
01162     if (dlg) {
01163       KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
01164       dlg->addError(i18n("<b>Error</b>: %1: %2").arg(filename, msg.qstring()));
01165     }
01166   }
01167 
01168   // Handle immediate redirects now (e.g. location='foo')
01169   if ( !d->m_redirectURL.isEmpty() && d->m_delayRedirect == -1 )
01170   {
01171     kdDebug(6070) << "executeScript done, handling immediate redirection NOW" << endl;
01172     // Must abort tokenizer, no further script must execute.
01173     khtml::Tokenizer* t = d->m_doc->tokenizer();
01174     if(t)
01175       t->abort();
01176     d->m_redirectionTimer.start( 0, true );
01177   }
01178 
01179   return ret;
01180 }
01181 
01182 TQVariant KHTMLPart::executeScript( const TQString &script )
01183 {
01184     return executeScript( DOM::Node(), script );
01185 }
01186 
01187 TQVariant KHTMLPart::executeScript( const DOM::Node &n, const TQString &script )
01188 {
01189 #ifdef KJS_VERBOSE
01190   kdDebug(6070) << "KHTMLPart::executeScript caller='" << name() << "' node=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " /* << script */ << endl;
01191 #endif
01192   KJSProxy *proxy = jScript();
01193 
01194   if (!proxy || proxy->paused())
01195     return TQVariant();
01196   ++(d->m_runningScripts);
01197   KJS::Completion comp;
01198   const TQVariant ret = proxy->evaluate( TQString(), 1, script, n, &comp );
01199   --(d->m_runningScripts);
01200 
01201   /*
01202    *  Error handling
01203    */
01204   if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
01205     KJSErrorDlg *dlg = jsErrorExtension();
01206     if (dlg) {
01207       KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
01208       dlg->addError(i18n("<b>Error</b>: node %1: %2").arg(n.nodeName().string()).arg(msg.qstring()));
01209     }
01210   }
01211 
01212   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
01213       submitFormAgain();
01214 
01215 #ifdef KJS_VERBOSE
01216   kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
01217 #endif
01218   return ret;
01219 }
01220 
01221 bool KHTMLPart::scheduleScript(const DOM::Node &n, const TQString& script)
01222 {
01223     //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
01224 
01225     d->scheduledScript = script;
01226     d->scheduledScriptNode = n;
01227 
01228     return true;
01229 }
01230 
01231 TQVariant KHTMLPart::executeScheduledScript()
01232 {
01233   if( d->scheduledScript.isEmpty() )
01234     return TQVariant();
01235 
01236   //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
01237 
01238   TQVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
01239   d->scheduledScript = TQString();
01240   d->scheduledScriptNode = DOM::Node();
01241 
01242   return ret;
01243 }
01244 
01245 void KHTMLPart::setJavaEnabled( bool enable )
01246 {
01247   d->m_bJavaForce = enable;
01248   d->m_bJavaOverride = true;
01249 }
01250 
01251 bool KHTMLPart::javaEnabled() const
01252 {
01253   if (onlyLocalReferences()) return false;
01254 
01255 #ifndef Q_WS_QWS
01256   if( d->m_bJavaOverride )
01257       return d->m_bJavaForce;
01258   return d->m_bJavaEnabled;
01259 #else
01260   return false;
01261 #endif
01262 }
01263 
01264 KJavaAppletContext *KHTMLPart::javaContext()
01265 {
01266   return 0;
01267 }
01268 
01269 KJavaAppletContext *KHTMLPart::createJavaContext()
01270 {
01271   return 0;
01272 }
01273 
01274 void KHTMLPart::setPluginsEnabled( bool enable )
01275 {
01276   d->m_bPluginsForce = enable;
01277   d->m_bPluginsOverride = true;
01278 }
01279 
01280 bool KHTMLPart::pluginsEnabled() const
01281 {
01282   if (onlyLocalReferences()) return false;
01283 
01284   if ( d->m_bPluginsOverride )
01285       return d->m_bPluginsForce;
01286   return d->m_bPluginsEnabled;
01287 }
01288 
01289 static int s_DOMTreeIndentLevel = 0;
01290 
01291 void KHTMLPart::slotDebugDOMTree()
01292 {
01293   if ( d->m_doc && d->m_doc->firstChild() )
01294     qDebug("%s", d->m_doc->firstChild()->toString().string().latin1());
01295 
01296   // Now print the contents of the frames that contain HTML
01297 
01298   const int indentLevel = s_DOMTreeIndentLevel++;
01299 
01300   ConstFrameIt it = d->m_frames.begin();
01301   const ConstFrameIt end = d->m_frames.end();
01302   for (; it != end; ++it )
01303     if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
01304       KParts::ReadOnlyPart* const p = ( *it )->m_part;
01305       kdDebug(6050) << TQString().leftJustify(s_DOMTreeIndentLevel*4,' ') << "FRAME " << p->name() << " " << endl;
01306       static_cast<KHTMLPart*>( p )->slotDebugDOMTree();
01307     }
01308   s_DOMTreeIndentLevel = indentLevel;
01309 }
01310 
01311 void KHTMLPart::slotDebugScript()
01312 {
01313   if (jScript())
01314     jScript()->showDebugWindow();
01315 }
01316 
01317 void KHTMLPart::slotDebugRenderTree()
01318 {
01319 #ifndef NDEBUG
01320   if ( d->m_doc ) {
01321     d->m_doc->renderer()->printTree();
01322     // dump out the contents of the rendering & DOM trees
01323 //    TQString dumps;
01324 //    TQTextStream outputStream(dumps,IO_WriteOnly);
01325 //    d->m_doc->renderer()->layer()->dump( outputStream );
01326 //    kdDebug() << "dump output:" << "\n" + dumps;
01327   }
01328 #endif
01329 }
01330 
01331 void KHTMLPart::slotStopAnimations()
01332 {
01333   stopAnimations();
01334 }
01335 
01336 void KHTMLPart::setAutoloadImages( bool enable )
01337 {
01338   if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
01339     return;
01340 
01341   if ( d->m_doc )
01342     d->m_doc->docLoader()->setAutoloadImages( enable );
01343 
01344   unplugActionList( "loadImages" );
01345 
01346   if ( enable ) {
01347     delete d->m_paLoadImages;
01348     d->m_paLoadImages = 0;
01349   }
01350   else if ( !d->m_paLoadImages )
01351     d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, TQT_SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
01352 
01353   if ( d->m_paLoadImages ) {
01354     TQPtrList<KAction> lst;
01355     lst.append( d->m_paLoadImages );
01356     plugActionList( "loadImages", lst );
01357   }
01358 }
01359 
01360 bool KHTMLPart::autoloadImages() const
01361 {
01362   if ( d->m_doc )
01363     return d->m_doc->docLoader()->autoloadImages();
01364 
01365   return true;
01366 }
01367 
01368 void KHTMLPart::clear()
01369 {
01370   if ( d->m_bCleared )
01371     return;
01372 
01373   d->m_bCleared = true;
01374 
01375   d->m_bClearing = true;
01376 
01377   {
01378     ConstFrameIt it = d->m_frames.begin();
01379     const ConstFrameIt end = d->m_frames.end();
01380     for(; it != end; ++it )
01381     {
01382       // Stop HTMLRun jobs for frames
01383       if ( (*it)->m_run )
01384         (*it)->m_run->abort();
01385     }
01386   }
01387 
01388   {
01389     ConstFrameIt it = d->m_objects.begin();
01390     const ConstFrameIt end = d->m_objects.end();
01391     for(; it != end; ++it )
01392     {
01393       // Stop HTMLRun jobs for objects
01394       if ( (*it)->m_run )
01395         (*it)->m_run->abort();
01396     }
01397   }
01398 
01399 
01400   findTextBegin(); // resets d->m_findNode and d->m_findPos
01401   d->m_mousePressNode = DOM::Node();
01402 
01403 
01404   if ( d->m_doc )
01405   {
01406     if (d->m_doc->attached()) //the view may have detached it already
01407     d->m_doc->detach();
01408   }
01409 
01410   // Moving past doc so that onUnload works.
01411   if ( d->m_frame && d->m_frame->m_jscript )
01412     d->m_frame->m_jscript->clear();
01413 
01414   // stopping marquees
01415   if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->layer())
01416       d->m_doc->renderer()->layer()->suspendMarquees();
01417 
01418   if ( d->m_view )
01419     d->m_view->clear();
01420 
01421   // do not dereference the document before the jscript and view are cleared, as some destructors
01422   // might still try to access the document.
01423   if ( d->m_doc ) {
01424     d->m_doc->deref();
01425   }
01426   d->m_doc = 0;
01427 
01428   delete d->m_decoder;
01429   d->m_decoder = 0;
01430 
01431   // We don't want to change between parts if we are going to delete all of them anyway
01432   if (partManager()) {
01433     disconnect( partManager(), TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
01434                this, TQT_SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
01435   }
01436 
01437   if (d->m_frames.count())
01438   {
01439     KHTMLFrameList frames = d->m_frames;
01440     d->m_frames.clear();
01441     ConstFrameIt it = frames.begin();
01442     const ConstFrameIt end = frames.end();
01443     for(; it != end; ++it )
01444     {
01445       if ( (*it)->m_part )
01446       {
01447         partManager()->removePart( (*it)->m_part );
01448         delete (KParts::ReadOnlyPart *)(*it)->m_part;
01449       }
01450       delete *it;
01451     }
01452   }
01453   d->m_suppressedPopupOriginParts.clear();
01454 
01455   if (d->m_objects.count())
01456   {
01457     KHTMLFrameList objects = d->m_objects;
01458     d->m_objects.clear();
01459     ConstFrameIt oi = objects.begin();
01460     const ConstFrameIt oiEnd = objects.end();
01461 
01462     for (; oi != oiEnd; ++oi )
01463       delete *oi;
01464   }
01465 
01466   // Listen to part changes again
01467   if (partManager()) {
01468     connect( partManager(), TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
01469              this, TQT_SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
01470   }
01471 
01472   d->m_delayRedirect = 0;
01473   d->m_redirectURL = TQString();
01474   d->m_redirectionTimer.stop();
01475   d->m_redirectLockHistory = true;
01476   d->m_bClearing = false;
01477   d->m_frameNameId = 1;
01478   d->m_bFirstData = true;
01479 
01480   d->m_bMousePressed = false;
01481 
01482   d->m_selectionStart = DOM::Node();
01483   d->m_selectionEnd = DOM::Node();
01484   d->m_startOffset = 0;
01485   d->m_endOffset = 0;
01486 #ifndef QT_NO_CLIPBOARD
01487   connect( kapp->clipboard(), TQT_SIGNAL( selectionChanged()), TQT_SLOT( slotClearSelection()));
01488 #endif
01489 
01490   d->m_jobPercent = 0;
01491 
01492   if ( !d->m_haveEncoding )
01493     d->m_encoding = TQString();
01494 #ifdef SPEED_DEBUG
01495   d->m_parsetime.restart();
01496 #endif
01497 }
01498 
01499 bool KHTMLPart::openFile()
01500 {
01501   return true;
01502 }
01503 
01504 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
01505 {
01506     if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
01507         return static_cast<HTMLDocumentImpl*>(d->m_doc);
01508     return 0;
01509 }
01510 
01511 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
01512 {
01513     if ( d )
01514         return d->m_doc;
01515     return 0;
01516 }
01517 
01518 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const TQString& msg)
01519 {
01520   assert(d->m_job == kio_job);
01521 
01522   if (!parentPart())
01523     setStatusBarText(msg, BarDefaultText);
01524 }
01525 
01526 void KHTMLPart::setPageSecurity( PageSecurity sec )
01527 {
01528   emit d->m_extension->setPageSecurity( sec );
01529   if ( sec != NotCrypted && !d->m_statusBarIconLabel && !parentPart() ) {
01530     d->m_statusBarIconLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
01531     d->m_statusBarIconLabel->setFixedHeight( instance()->iconLoader()->currentSize(KIcon::Small) );
01532     d->m_statusBarIconLabel->setSizePolicy(TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ));
01533     d->m_statusBarIconLabel->setUseCursor( false );
01534     d->m_statusBarExtension->addStatusBarItem( d->m_statusBarIconLabel, 0, false );
01535     connect( d->m_statusBarIconLabel, TQT_SIGNAL( leftClickedURL() ), TQT_SLOT( slotSecurity() ) );
01536   } else if (d->m_statusBarIconLabel) {
01537     TQToolTip::remove(d->m_statusBarIconLabel);
01538   }
01539 
01540   if (d->m_statusBarIconLabel) {
01541     if (d->m_ssl_in_use)
01542       TQToolTip::add(d->m_statusBarIconLabel,
01543             i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
01544     else TQToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
01545   }
01546 
01547   TQString iconName;
01548   switch (sec)  {
01549   case NotCrypted:
01550     iconName = "decrypted";
01551     if ( d->m_statusBarIconLabel )  {
01552       d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarIconLabel );
01553       delete d->m_statusBarIconLabel;
01554       d->m_statusBarIconLabel = 0L;
01555     }
01556     break;
01557   case Encrypted:
01558     iconName = "encrypted";
01559     break;
01560   case Mixed:
01561     iconName = "halfencrypted";
01562     break;
01563   }
01564   d->m_paSecurity->setIcon( iconName );
01565   if ( d->m_statusBarIconLabel )
01566     d->m_statusBarIconLabel->setPixmap( SmallIcon( iconName, instance() ) );
01567 }
01568 
01569 void KHTMLPart::slotData( KIO::Job* kio_job, const TQByteArray &data )
01570 {
01571   assert ( d->m_job == kio_job );
01572 
01573   //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
01574   // The first data ?
01575   if ( !d->m_workingURL.isEmpty() )
01576   {
01577       //kdDebug( 6050 ) << "begin!" << endl;
01578 
01579     // We must suspend KIO while we're inside begin() because it can cause
01580     // crashes if a window (such as kjsdebugger) goes back into the event loop,
01581     // more data arrives, and begin() gets called again (re-entered).
01582     d->m_job->suspend();
01583     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
01584     d->m_job->resume();
01585 
01586     if (d->m_cachePolicy == KIO::CC_Refresh)
01587       d->m_doc->docLoader()->setCachePolicy(KIO::CC_Verify);
01588     else
01589       d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
01590 
01591     d->m_workingURL = KURL();
01592 
01593     d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
01594 
01595     // When the first data arrives, the metadata has just been made available
01596     d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
01597     time_t cacheCreationDate =  d->m_job->queryMetaData("cache-creation-date").toLong();
01598     d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);
01599 
01600     d->m_pageServices = d->m_job->queryMetaData("PageServices");
01601     d->m_pageReferrer = d->m_job->queryMetaData("referrer");
01602     d->m_bSecurityInQuestion = false;
01603     d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
01604 
01605     {
01606     KHTMLPart *p = parentPart();
01607     if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
01608     while (p->parentPart()) p = p->parentPart();
01609 
01610         p->setPageSecurity( Mixed );
01611         p->d->m_bSecurityInQuestion = true;
01612     }
01613     }
01614 
01615     setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
01616 
01617     // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
01618     d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
01619     d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
01620     d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
01621     d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
01622     d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
01623     d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
01624     d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
01625     d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
01626     d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
01627     d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
01628     d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
01629 
01630     if (d->m_statusBarIconLabel) {
01631       TQToolTip::remove(d->m_statusBarIconLabel);
01632       if (d->m_ssl_in_use) {
01633         TQToolTip::add(d->m_statusBarIconLabel, i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
01634       } else {
01635         TQToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
01636       }
01637     }
01638 
01639     // Check for charset meta-data
01640     TQString qData = d->m_job->queryMetaData("charset");
01641     if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
01642        d->m_encoding = qData;
01643 
01644 
01645     // Support for http-refresh
01646     qData = d->m_job->queryMetaData("http-refresh");
01647     if( !qData.isEmpty())
01648       d->m_doc->processHttpEquiv("refresh", qData);
01649 
01650     // DISABLED: Support Content-Location per section 14.14 of RFC 2616.
01651     // See BR# 51185,BR# 82747
01652     /*
01653     TQString baseURL = d->m_job->queryMetaData ("content-location");
01654     if (!baseURL.isEmpty())
01655       d->m_doc->setBaseURL(KURL( d->m_doc->completeURL(baseURL) ));
01656     */
01657 
01658     // Support for Content-Language
01659     TQString language = d->m_job->queryMetaData("content-language");
01660     if (!language.isEmpty())
01661         d->m_doc->setContentLanguage(language);
01662 
01663     if ( !m_url.isLocalFile() ) {
01664         // Support for http last-modified
01665         d->m_lastModified = d->m_job->queryMetaData("modified");
01666     } else
01667         d->m_lastModified = TQString(); // done on-demand by lastModified()
01668   }
01669 
01670   KHTMLPageCache::self()->addData(d->m_cacheId, data);
01671   write( data.data(), data.size() );
01672   if (d->m_frame && d->m_frame->m_jscript)
01673     d->m_frame->m_jscript->dataReceived();
01674 }
01675 
01676 void KHTMLPart::slotRestoreData(const TQByteArray &data )
01677 {
01678   // The first data ?
01679   if ( !d->m_workingURL.isEmpty() )
01680   {
01681      long saveCacheId = d->m_cacheId;
01682      TQString savePageReferrer = d->m_pageReferrer;
01683      TQString saveEncoding     = d->m_encoding;
01684      begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
01685      d->m_encoding     = saveEncoding;
01686      d->m_pageReferrer = savePageReferrer;
01687      d->m_cacheId = saveCacheId;
01688      d->m_workingURL = KURL();
01689   }
01690 
01691   //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
01692   write( data.data(), data.size() );
01693 
01694   if (data.size() == 0)
01695   {
01696       //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
01697      // End of data.
01698     if (d->m_doc && d->m_doc->parsing())
01699         end(); //will emit completed()
01700   }
01701 }
01702 
01703 void KHTMLPart::showError( KIO::Job* job )
01704 {
01705   kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
01706                 << " d->m_bCleared=" << d->m_bCleared << endl;
01707 
01708   if (job->error() == KIO::ERR_NO_CONTENT)
01709     return;
01710 
01711   if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
01712     job->showErrorDialog( /*d->m_view*/ );
01713   else
01714   {
01715     htmlError( job->error(), job->errorText(), d->m_workingURL );
01716   }
01717 }
01718 
01719 // This is a protected method, placed here because of it's relevance to showError
01720 void KHTMLPart::htmlError( int errorCode, const TQString& text, const KURL& reqUrl )
01721 {
01722   kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
01723   // make sure we're not executing any embedded JS
01724   bool bJSFO = d->m_bJScriptForce;
01725   bool bJSOO = d->m_bJScriptOverride;
01726   d->m_bJScriptForce = false;
01727   d->m_bJScriptOverride = true;
01728   begin();
01729   TQString errText = TQString::fromLatin1( "<HTML dir=%1><HEAD><TITLE>" )
01730                            .arg(TQApplication::reverseLayout() ? "rtl" : "ltr");
01731   errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
01732   errText += TQString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
01733   errText += i18n( "An error occurred while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
01734   errText += TQString::fromLatin1( "</P>" );
01735   errText += TQStyleSheet::convertFromPlainText( KIO::buildErrorString( errorCode, text ) );
01736   errText += TQString::fromLatin1( "</BODY></HTML>" );
01737   write(errText);
01738   end();
01739 
01740   d->m_bJScriptForce = bJSFO;
01741   d->m_bJScriptOverride = bJSOO;
01742 
01743   // make the working url the current url, so that reload works and
01744   // emit the progress signals to advance one step in the history
01745   // (so that 'back' works)
01746   m_url = reqUrl; // same as d->m_workingURL
01747   d->m_workingURL = KURL();
01748   emit started( 0 );
01749   emit completed();
01750   return;
01751   // following disabled until 3.1
01752 
01753   TQString errorName, techName, description;
01754   TQStringList causes, solutions;
01755 
01756   TQByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
01757   TQDataStream stream(raw, IO_ReadOnly);
01758 
01759   stream >> errorName >> techName >> description >> causes >> solutions;
01760 
01761   TQString url, protocol, datetime;
01762   url = reqUrl.prettyURL();
01763   protocol = reqUrl.protocol();
01764   datetime = KGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(),
01765                                                 false );
01766 
01767   TQString doc = TQString::fromLatin1( "<html><head><title>" );
01768   doc += i18n( "Error: " );
01769   doc += errorName;
01770   doc += TQString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
01771   doc += i18n( "The requested operation could not be completed" );
01772   doc += TQString::fromLatin1( "</h1><h2>" );
01773   doc += errorName;
01774   doc += TQString::fromLatin1( "</h2>" );
01775   if ( !techName.isNull() ) {
01776     doc += TQString::fromLatin1( "<h2>" );
01777     doc += i18n( "Technical Reason: " );
01778     doc += techName;
01779     doc += TQString::fromLatin1( "</h2>" );
01780   }
01781   doc += TQString::fromLatin1( "<h3>" );
01782   doc += i18n( "Details of the Request:" );
01783   doc += TQString::fromLatin1( "</h3><ul><li>" );
01784   doc += i18n( "URL: %1" ).arg( url );
01785   doc += TQString::fromLatin1( "</li><li>" );
01786   if ( !protocol.isNull() ) {
01787     // uncomment for 3.1... i18n change
01788     // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
01789     doc += TQString::fromLatin1( "</li><li>" );
01790   }
01791   doc += i18n( "Date and Time: %1" ).arg( datetime );
01792   doc += TQString::fromLatin1( "</li><li>" );
01793   doc += i18n( "Additional Information: %1" ).arg( text );
01794   doc += TQString::fromLatin1( "</li></ul><h3>" );
01795   doc += i18n( "Description:" );
01796   doc += TQString::fromLatin1( "</h3><p>" );
01797   doc += description;
01798   doc += TQString::fromLatin1( "</p>" );
01799   if ( causes.count() ) {
01800     doc += TQString::fromLatin1( "<h3>" );
01801     doc += i18n( "Possible Causes:" );
01802     doc += TQString::fromLatin1( "</h3><ul><li>" );
01803     doc += causes.join( "</li><li>" );
01804     doc += TQString::fromLatin1( "</li></ul>" );
01805   }
01806   if ( solutions.count() ) {
01807     doc += TQString::fromLatin1( "<h3>" );
01808     doc += i18n( "Possible Solutions:" );
01809     doc += TQString::fromLatin1( "</h3><ul><li>" );
01810     doc += solutions.join( "</li><li>" );
01811     doc += TQString::fromLatin1( "</li></ul>" );
01812   }
01813   doc += TQString::fromLatin1( "</body></html>" );
01814 
01815   write( doc );
01816   end();
01817 }
01818 
01819 void KHTMLPart::slotFinished( KIO::Job * job )
01820 {
01821   d->m_job = 0L;
01822   d->m_jobspeed = 0L;
01823 
01824   if (job->error())
01825   {
01826     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
01827 
01828     // The following catches errors that occur as a result of HTTP
01829     // to FTP redirections where the FTP URL is a directory. Since
01830     // KIO cannot change a redirection request from GET to LISTDIR,
01831     // we have to take care of it here once we know for sure it is
01832     // a directory...
01833     if (job->error() == KIO::ERR_IS_DIRECTORY)
01834     {
01835       KParts::URLArgs args;
01836       emit d->m_extension->openURLRequest( d->m_workingURL, args );
01837     }
01838     else
01839     {
01840       emit canceled( job->errorString() );
01841       // TODO: what else ?
01842       checkCompleted();
01843       showError( job );
01844     }
01845 
01846     return;
01847   }
01848   KIO::TransferJob *tjob = ::tqqt_cast<KIO::TransferJob*>(job);
01849   if (tjob && tjob->isErrorPage()) {
01850     khtml::RenderPart *renderPart = d->m_frame ? static_cast<khtml::RenderPart *>(d->m_frame->m_frame) : 0;
01851     if (renderPart) {
01852       HTMLObjectElementImpl* elt = static_cast<HTMLObjectElementImpl *>(renderPart->element());
01853       if (!elt)
01854         return;
01855       elt->renderAlternative();
01856       checkCompleted();
01857      }
01858      if (d->m_bComplete) return;
01859   }
01860 
01861   //kdDebug( 6050 ) << "slotFinished" << endl;
01862 
01863   KHTMLPageCache::self()->endData(d->m_cacheId);
01864   if (d->m_frame && d->m_frame->m_jscript)
01865     d->m_frame->m_jscript->dataReceived();
01866 
01867   if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
01868       KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
01869 
01870   d->m_workingURL = KURL();
01871 
01872   if ( d->m_doc && d->m_doc->parsing())
01873     end(); //will emit completed()
01874 }
01875 
01876 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
01877 {
01878   // No need to show this for a new page until an error is triggered
01879   if (!parentPart()) {
01880     removeJSErrorExtension();
01881     setSuppressedPopupIndicator( false );
01882     d->m_openableSuppressedPopups = 0;
01883     for ( TQValueListIterator<TQGuardedPtr<KHTMLPart> > i = d->m_suppressedPopupOriginParts.begin();
01884           i != d->m_suppressedPopupOriginParts.end(); ++i ) {
01885 
01886       if (KHTMLPart* part = *i) {
01887         KJS::Window *w = KJS::Window::retrieveWindow( part );
01888         if (w)
01889           w->forgetSuppressedWindows();
01890       }
01891     }
01892   }
01893 
01894   clear();
01895   d->m_bCleared = false;
01896   d->m_cacheId = 0;
01897   d->m_bComplete = false;
01898   d->m_bLoadEventEmitted = false;
01899 
01900   if(url.isValid()) {
01901       TQString urlString = url.url();
01902       KHTMLFactory::vLinks()->insert( urlString );
01903       TQString urlString2 = url.prettyURL();
01904       if ( urlString != urlString2 ) {
01905           KHTMLFactory::vLinks()->insert( urlString2 );
01906       }
01907   }
01908 
01909 
01910   // ###
01911   //stopParser();
01912 
01913   KParts::URLArgs args( d->m_extension->urlArgs() );
01914   args.xOffset = xOffset;
01915   args.yOffset = yOffset;
01916   d->m_extension->setURLArgs( args );
01917 
01918   d->m_pageReferrer = TQString();
01919 
01920   KURL ref(url);
01921   d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : "";
01922 
01923   m_url = url;
01924 
01925   bool servedAsXHTML = args.serviceType == "application/xhtml+xml";
01926   bool servedAsXML = KMimeType::mimeType(args.serviceType)->is( "text/xml" );
01927   // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
01928   if ( servedAsXML && !servedAsXHTML ) { // any XML derivative, except XHTML
01929     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
01930   } else {
01931     d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
01932     // HTML or XHTML? (#86446)
01933     static_cast<HTMLDocumentImpl *>(d->m_doc)->setHTMLRequested( !servedAsXHTML );
01934   }
01935 #ifndef KHTML_NO_CARET
01936 //  d->m_view->initCaret();
01937 #endif
01938 
01939   d->m_doc->ref();
01940   d->m_doc->setURL( m_url.url() );
01941   if (!d->m_doc->attached())
01942     d->m_doc->attach( );
01943   d->m_doc->setBaseURL( KURL() );
01944   d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
01945   emit docCreated();
01946 
01947   d->m_paUseStylesheet->setItems(TQStringList());
01948   d->m_paUseStylesheet->setEnabled( false );
01949 
01950   setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
01951   TQString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
01952   if ( !userStyleSheet.isEmpty() )
01953     setUserStyleSheet( KURL( userStyleSheet ) );
01954 
01955   d->m_doc->setRestoreState(args.docState);
01956   d->m_doc->open();
01957   connect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
01958 
01959   emit d->m_extension->enableAction( "print", true );
01960 
01961   d->m_doc->setParsing(true);
01962 }
01963 
01964 void KHTMLPart::write( const char *str, int len )
01965 {
01966   if ( !d->m_decoder )
01967     d->m_decoder = createDecoder();
01968 
01969   if ( len == -1 )
01970     len = strlen( str );
01971 
01972   if ( len == 0 )
01973     return;
01974 
01975   TQString decoded = d->m_decoder->decode( str, len );
01976 
01977   if(decoded.isEmpty()) return;
01978 
01979   if(d->m_bFirstData) {
01980       // determine the parse mode
01981       d->m_doc->determineParseMode( decoded );
01982       d->m_bFirstData = false;
01983 
01984   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
01985       // ### this is still quite hacky, but should work a lot better than the old solution
01986       if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
01987       d->m_doc->setDecoderCodec(d->m_decoder->codec());
01988       d->m_doc->recalcStyle( NodeImpl::Force );
01989   }
01990 
01991   khtml::Tokenizer* t = d->m_doc->tokenizer();
01992   if(t)
01993     t->write( decoded, true );
01994 }
01995 
01996 void KHTMLPart::write( const TQString &str )
01997 {
01998     if ( str.isNull() )
01999         return;
02000 
02001     if(d->m_bFirstData) {
02002         // determine the parse mode
02003         d->m_doc->setParseMode( DocumentImpl::Strict );
02004         d->m_bFirstData = false;
02005     }
02006     khtml::Tokenizer* t = d->m_doc->tokenizer();
02007     if(t)
02008         t->write( str, true );
02009 }
02010 
02011 void KHTMLPart::end()
02012 {
02013     if (d->m_doc) {
02014         if (d->m_decoder) {
02015             TQString decoded = d->m_decoder->flush();
02016             if (d->m_bFirstData) {
02017                 d->m_bFirstData = false;
02018                 d->m_doc->determineParseMode(decoded);
02019             }
02020             write(decoded);
02021         }
02022         d->m_doc->finishParsing();
02023     }
02024 }
02025 
02026 bool KHTMLPart::doOpenStream( const TQString& mimeType )
02027 {
02028     KMimeType::Ptr mime = KMimeType::mimeType(mimeType);
02029     if ( mime->is( "text/html" ) || mime->is( "text/xml" ) )
02030     {
02031         begin( url() );
02032         return true;
02033     }
02034     return false;
02035 }
02036 
02037 bool KHTMLPart::doWriteStream( const TQByteArray& data )
02038 {
02039     write( data.data(), data.size() );
02040     return true;
02041 }
02042 
02043 bool KHTMLPart::doCloseStream()
02044 {
02045     end();
02046     return true;
02047 }
02048 
02049 
02050 void KHTMLPart::paint(TQPainter *p, const TQRect &rc, int yOff, bool *more)
02051 {
02052     if (!d->m_view) return;
02053     d->m_view->paint(p, rc, yOff, more);
02054 }
02055 
02056 void KHTMLPart::stopAnimations()
02057 {
02058   if ( d->m_doc )
02059     d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
02060 
02061   ConstFrameIt it = d->m_frames.begin();
02062   const ConstFrameIt end = d->m_frames.end();
02063   for (; it != end; ++it )
02064     if ( !(*it)->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
02065       KParts::ReadOnlyPart* const p = ( *it )->m_part;
02066       static_cast<KHTMLPart*>( p )->stopAnimations();
02067     }
02068 }
02069 
02070 void KHTMLPart::resetFromScript()
02071 {
02072     closeURL();
02073     d->m_bComplete = false;
02074     d->m_bLoadEventEmitted = false;
02075     disconnect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
02076     connect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
02077     d->m_doc->setParsing(true);
02078 
02079     emit started( 0L );
02080 }
02081 
02082 void KHTMLPart::slotFinishedParsing()
02083 {
02084   d->m_doc->setParsing(false);
02085   checkEmitLoadEvent();
02086   disconnect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
02087 
02088   if (!d->m_view)
02089     return; // We are probably being destructed.
02090 
02091   checkCompleted();
02092 }
02093 
02094 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
02095 {
02096   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
02097     KHTMLPart* p = this;
02098     while ( p ) {
02099       KHTMLPart* const op = p;
02100       ++(p->d->m_totalObjectCount);
02101       p = p->parentPart();
02102       if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
02103         && !op->d->m_progressUpdateTimer.isActive())
02104     op->d->m_progressUpdateTimer.start( 200, true );
02105     }
02106   }
02107 }
02108 
02109 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
02110 {
02111   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
02112     KHTMLPart* p = this;
02113     while ( p ) {
02114       KHTMLPart* const op = p;
02115       ++(p->d->m_loadedObjects);
02116       p = p->parentPart();
02117       if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
02118         && !op->d->m_progressUpdateTimer.isActive())
02119     op->d->m_progressUpdateTimer.start( 200, true );
02120     }
02121   }
02122 
02123   checkCompleted();
02124 }
02125 
02126 void KHTMLPart::slotProgressUpdate()
02127 {
02128   int percent;
02129   if ( d->m_loadedObjects < d->m_totalObjectCount )
02130     percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
02131   else
02132     percent = d->m_jobPercent;
02133 
02134   if( d->m_bComplete )
02135     percent = 100;
02136 
02137   if (d->m_statusMessagesEnabled) {
02138     if( d->m_bComplete )
02139       emit d->m_extension->infoMessage( i18n( "Page loaded." ));
02140     else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
02141       emit d->m_extension->infoMessage( i18n( "%n Image of %1 loaded.", "%n Images of %1 loaded.", d->m_loadedObjects).arg(d->m_totalObjectCount) );
02142   }
02143 
02144   emit d->m_extension->loadingProgress( percent );
02145 }
02146 
02147 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
02148 {
02149   d->m_jobspeed = speed;
02150   if (!parentPart())
02151     setStatusBarText(jsStatusBarText(), BarOverrideText);
02152 }
02153 
02154 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
02155 {
02156   d->m_jobPercent = percent;
02157 
02158   if ( !parentPart() )
02159     d->m_progressUpdateTimer.start( 0, true );
02160 }
02161 
02162 void KHTMLPart::slotJobDone( KIO::Job* /*job*/ )
02163 {
02164   d->m_jobPercent = 100;
02165 
02166   if ( !parentPart() )
02167     d->m_progressUpdateTimer.start( 0, true );
02168 }
02169 
02170 void KHTMLPart::slotUserSheetStatDone( KIO::Job *_job )
02171 {
02172   using namespace KIO;
02173 
02174   if ( _job->error() ) {
02175     showError( _job );
02176     return;
02177   }
02178 
02179   const UDSEntry entry = dynamic_cast<KIO::StatJob *>( _job )->statResult();
02180   UDSEntry::ConstIterator it = entry.begin();
02181   const UDSEntry::ConstIterator end = entry.end();
02182   for ( ; it != end; ++it ) {
02183     if ( ( *it ).m_uds == UDS_MODIFICATION_TIME ) {
02184      break;
02185     }
02186   }
02187 
02188   // If the filesystem supports modification times, only reload the
02189   // user-defined stylesheet if necessary - otherwise always reload.
02190   if ( it != end ) {
02191     const time_t lastModified = static_cast<time_t>( ( *it ).m_long );
02192     if ( d->m_userStyleSheetLastModified >= lastModified ) {
02193       return;
02194     }
02195     d->m_userStyleSheetLastModified = lastModified;
02196   }
02197 
02198   setUserStyleSheet( KURL( settings()->userStyleSheet() ) );
02199 }
02200 
02201 void KHTMLPart::checkCompleted()
02202 {
02203 //   kdDebug( 6050 ) << "KHTMLPart::checkCompleted() " << this << " " << name() << endl;
02204 //   kdDebug( 6050 ) << "                           parsing: " << (d->m_doc && d->m_doc->parsing()) << endl;
02205 //   kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;
02206 
02207   // restore the cursor position
02208   if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
02209   {
02210       if (d->m_focusNodeNumber >= 0)
02211           d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
02212 
02213       d->m_focusNodeRestored = true;
02214   }
02215 
02216   bool bPendingChildRedirection = false;
02217   // Any frame that hasn't completed yet ?
02218   ConstFrameIt it = d->m_frames.begin();
02219   const ConstFrameIt end = d->m_frames.end();
02220   for (; it != end; ++it ) {
02221     if ( !(*it)->m_bCompleted )
02222     {
02223       //kdDebug( 6050 ) << this << " is waiting for " << (*it)->m_part << endl;
02224       return;
02225     }
02226     // Check for frames with pending redirections
02227     if ( (*it)->m_bPendingRedirection )
02228       bPendingChildRedirection = true;
02229   }
02230 
02231   // Any object that hasn't completed yet ?
02232   {
02233     ConstFrameIt oi = d->m_objects.begin();
02234     const ConstFrameIt oiEnd = d->m_objects.end();
02235 
02236     for (; oi != oiEnd; ++oi )
02237       if ( !(*oi)->m_bCompleted )
02238         return;
02239   }
02240   // Are we still parsing - or have we done the completed stuff already ?
02241   if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
02242     return;
02243 
02244   // Still waiting for images/scripts from the loader ?
02245   int requests = 0;
02246   if ( d->m_doc && d->m_doc->docLoader() )
02247     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
02248 
02249   if ( requests > 0 )
02250   {
02251     //kdDebug(6050) << "still waiting for images/scripts from the loader - requests:" << requests << endl;
02252     return;
02253   }
02254 
02255   // OK, completed.
02256   // Now do what should be done when we are really completed.
02257   d->m_bComplete = true;
02258   d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
02259   d->m_totalObjectCount = 0;
02260   d->m_loadedObjects = 0;
02261 
02262   KHTMLPart* p = this;
02263   while ( p ) {
02264     KHTMLPart* op = p;
02265     p = p->parentPart();
02266     if ( !p && !op->d->m_progressUpdateTimer.isActive())
02267       op->d->m_progressUpdateTimer.start( 0, true );
02268   }
02269 
02270   checkEmitLoadEvent(); // if we didn't do it before
02271 
02272   bool pendingAction = false;
02273 
02274   if ( !d->m_redirectURL.isEmpty() )
02275   {
02276     // DA: Do not start redirection for frames here! That action is
02277     // deferred until the parent emits a completed signal.
02278     if ( parentPart() == 0 ) {
02279       //kdDebug(6050) << this << " starting redirection timer" << endl;
02280       d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
02281     } else {
02282       //kdDebug(6050) << this << " not toplevel -> not starting redirection timer. Waiting for slotParentCompleted." << endl;
02283     }
02284 
02285     pendingAction = true;
02286   }
02287   else if ( bPendingChildRedirection )
02288   {
02289     pendingAction = true;
02290   }
02291 
02292   // the view will emit completed on our behalf,
02293   // either now or at next repaint if one is pending
02294 
02295   //kdDebug(6050) << this << " asks the view to emit completed. pendingAction=" << pendingAction << endl;
02296   d->m_view->complete( pendingAction );
02297 
02298   // find the alternate stylesheets
02299   TQStringList sheets;
02300   if (d->m_doc)
02301      sheets = d->m_doc->availableStyleSheets();
02302   sheets.prepend( i18n( "Automatic Detection" ) );
02303   d->m_paUseStylesheet->setItems( sheets );
02304 
02305   d->m_paUseStylesheet->setEnabled( sheets.count() > 2);
02306   if (sheets.count() > 2)
02307   {
02308     d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
02309     slotUseStylesheet();
02310   }
02311 
02312   setJSDefaultStatusBarText(TQString());
02313 
02314 #ifdef SPEED_DEBUG
02315   kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
02316 #endif
02317 }
02318 
02319 void KHTMLPart::checkEmitLoadEvent()
02320 {
02321   if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
02322 
02323   ConstFrameIt it = d->m_frames.begin();
02324   const ConstFrameIt end = d->m_frames.end();
02325   for (; it != end; ++it )
02326     if ( !(*it)->m_bCompleted ) // still got a frame running -> too early
02327       return;
02328 
02329   ConstFrameIt oi = d->m_objects.begin();
02330   const ConstFrameIt oiEnd = d->m_objects.end();
02331 
02332   for (; oi != oiEnd; ++oi )
02333     if ( !(*oi)->m_bCompleted ) // still got a object running -> too early
02334       return;
02335 
02336   // Still waiting for images/scripts from the loader ?
02337   // (onload must happen afterwards, #45607)
02338   // ## This makes this method very similar to checkCompleted. A brave soul should try merging them.
02339   int requests = 0;
02340   if ( d->m_doc && d->m_doc->docLoader() )
02341     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
02342 
02343   if ( requests > 0 )
02344     return;
02345 
02346   d->m_bLoadEventEmitted = true;
02347   if (d->m_doc)
02348     d->m_doc->close();
02349 }
02350 
02351 const KHTMLSettings *KHTMLPart::settings() const
02352 {
02353   return d->m_settings;
02354 }
02355 
02356 #ifndef KDE_NO_COMPAT
02357 KURL KHTMLPart::baseURL() const
02358 {
02359   if ( !d->m_doc ) return KURL();
02360 
02361   return d->m_doc->baseURL();
02362 }
02363 
02364 TQString KHTMLPart::baseTarget() const
02365 {
02366   if ( !d->m_doc ) return TQString();
02367 
02368   return d->m_doc->baseTarget();
02369 }
02370 #endif
02371 
02372 KURL KHTMLPart::completeURL( const TQString &url )
02373 {
02374   if ( !d->m_doc ) return KURL( url );
02375 
02376   if (d->m_decoder)
02377     return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
02378 
02379   return KURL( d->m_doc->completeURL( url ) );
02380 }
02381 
02382 // Called by ecma/kjs_window in case of redirections from Javascript,
02383 // and by xml/dom_docimpl.cpp in case of http-equiv meta refresh.
02384 void KHTMLPart::scheduleRedirection( int delay, const TQString &url, bool doLockHistory )
02385 {
02386   kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
02387   kdDebug(6050) << "current redirectURL=" << d->m_redirectURL << " with delay " << d->m_delayRedirect <<  endl;
02388   if( delay < 24*60*60 &&
02389       ( d->m_redirectURL.isEmpty() || delay <= d->m_delayRedirect) ) {
02390     d->m_delayRedirect = delay;
02391     d->m_redirectURL = url;
02392     d->m_redirectLockHistory = doLockHistory;
02393     kdDebug(6050) << " d->m_bComplete=" << d->m_bComplete << endl;
02394     if ( d->m_bComplete ) {
02395       d->m_redirectionTimer.stop();
02396       d->m_redirectionTimer.start( kMax(0, 1000 * d->m_delayRedirect), true );
02397     }
02398   }
02399 }
02400 
02401 void KHTMLPart::slotRedirect()
02402 {
02403   kdDebug(6050) << this << " slotRedirect()" << endl;
02404   TQString u = d->m_redirectURL;
02405   d->m_delayRedirect = 0;
02406   d->m_redirectURL = TQString();
02407 
02408   // SYNC check with ecma/kjs_window.cpp::goURL !
02409   if ( u.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 )
02410   {
02411     TQString script = KURL::decode_string( u.right( u.length() - 11 ) );
02412     kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
02413     TQVariant res = executeScript( DOM::Node(), script );
02414     if ( res.type() == TQVariant::String ) {
02415       begin( url() );
02416       write( res.asString() );
02417       end();
02418     }
02419     emit completed();
02420     return;
02421   }
02422   KParts::URLArgs args;
02423   KURL cUrl( m_url );
02424   KURL url( u );
02425 
02426   // handle windows opened by JS
02427   if ( openedByJS() && d->m_opener )
02428       cUrl = d->m_opener->url();
02429 
02430   if (!kapp || !kapp->authorizeURLAction("redirect", cUrl, url))
02431   {
02432     kdWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << cUrl << " to " << url << " REJECTED!" << endl;
02433     emit completed();
02434     return;
02435   }
02436 
02437   if ( urlcmp( u, m_url.url(), true, true ) )
02438   {
02439     args.metaData().insert("referrer", d->m_pageReferrer);
02440   }
02441 
02442   // For javascript and META-tag based redirections:
02443   //   - We don't take cross-domain-ness in consideration if we are the
02444   //   toplevel frame because the new URL may be in a different domain as the current URL
02445   //   but that's ok.
02446   //   - If we are not the toplevel frame then we check against the toplevelURL()
02447   if (parentPart())
02448       args.metaData().insert("cross-domain", toplevelURL().url());
02449 
02450   args.setLockHistory( d->m_redirectLockHistory );
02451   // _self: make sure we don't use any <base target=>'s
02452 
02453   d->m_urlSelectedOpenedURL = true; // In case overriden, default to success
02454   urlSelected( u, 0, 0, "_self", args );
02455 
02456   if ( !d->m_urlSelectedOpenedURL ) // urlSelected didn't open a url, so emit completed ourselves
02457     emit completed();
02458 }
02459 
02460 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
02461 {
02462   // the slave told us that we got redirected
02463   //kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
02464   emit d->m_extension->setLocationBarURL( url.prettyURL() );
02465   d->m_workingURL = url;
02466 }
02467 
02468 bool KHTMLPart::setEncoding( const TQString &name, bool override )
02469 {
02470     d->m_encoding = name;
02471     d->m_haveEncoding = override;
02472 
02473     if( !m_url.isEmpty() ) {
02474         // reload document
02475         closeURL();
02476         KURL url = m_url;
02477         m_url = 0;
02478         d->m_restored = true;
02479         openURL(url);
02480         d->m_restored = false;
02481     }
02482 
02483     return true;
02484 }
02485 
02486 TQString KHTMLPart::encoding() const
02487 {
02488     if(d->m_haveEncoding && !d->m_encoding.isEmpty())
02489         return d->m_encoding;
02490 
02491     if(d->m_decoder && d->m_decoder->encoding())
02492         return TQString(d->m_decoder->encoding());
02493 
02494     return defaultEncoding();
02495 }
02496 
02497 TQString KHTMLPart::defaultEncoding() const
02498 {
02499   TQString encoding = settings()->encoding();
02500   if ( !encoding.isEmpty() )
02501     return encoding;
02502   // HTTP requires the default encoding to be latin1, when neither
02503   // the user nor the page requested a particular encoding.
02504   if ( url().protocol().startsWith( "http" ) )
02505     return "iso-8859-1";
02506   else
02507     return KGlobal::locale()->encoding();
02508 }
02509 
02510 void KHTMLPart::setUserStyleSheet(const KURL &url)
02511 {
02512   if ( d->m_doc && d->m_doc->docLoader() )
02513     (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
02514 }
02515 
02516 void KHTMLPart::setUserStyleSheet(const TQString &styleSheet)
02517 {
02518   if ( d->m_doc )
02519     d->m_doc->setUserStyleSheet( styleSheet );
02520 }
02521 
02522 bool KHTMLPart::gotoAnchor( const TQString &name )
02523 {
02524   if (!d->m_doc)
02525     return false;
02526 
02527   HTMLCollectionImpl *anchors =
02528       new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
02529   anchors->ref();
02530   NodeImpl *n = anchors->namedItem(name);
02531   anchors->deref();
02532 
02533   if(!n) {
02534       n = d->m_doc->getElementById( name );
02535   }
02536 
02537   d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
02538 
02539   // Implement the rule that "" and "top" both mean top of page as in other browsers.
02540   bool quirkyName = !n && !d->m_doc->inStrictMode() && (name.isEmpty() || name.lower() == "top");
02541 
02542   if (quirkyName) {
02543       d->m_view->setContentsPos(0, 0);
02544       return true;
02545   } else if (!n) {
02546       kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
02547       return false;
02548   }
02549 
02550   int x = 0, y = 0;
02551   int gox, dummy;
02552   HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
02553 
02554   a->getUpperLeftCorner(x, y);
02555   if (x <= d->m_view->contentsX())
02556     gox = x - 10;
02557   else {
02558     gox = d->m_view->contentsX();
02559     if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
02560       a->getLowerRightCorner(x, dummy);
02561       gox = x - d->m_view->visibleWidth() + 10;
02562     }
02563   }
02564 
02565   d->m_view->setContentsPos(gox, y);
02566 
02567   return true;
02568 }
02569 
02570 bool KHTMLPart::nextAnchor()
02571 {
02572   if (!d->m_doc)
02573     return false;
02574   d->m_view->focusNextPrevNode ( true );
02575 
02576   return true;
02577 }
02578 
02579 bool KHTMLPart::prevAnchor()
02580 {
02581   if (!d->m_doc)
02582     return false;
02583   d->m_view->focusNextPrevNode ( false );
02584 
02585   return true;
02586 }
02587 
02588 void KHTMLPart::setStandardFont( const TQString &name )
02589 {
02590     d->m_settings->setStdFontName(name);
02591 }
02592 
02593 void KHTMLPart::setFixedFont( const TQString &name )
02594 {
02595     d->m_settings->setFixedFontName(name);
02596 }
02597 
02598 void KHTMLPart::setURLCursor( const TQCursor &c )
02599 {
02600   d->m_linkCursor = c;
02601 }
02602 
02603 TQCursor KHTMLPart::urlCursor() const
02604 {
02605   return d->m_linkCursor;
02606 }
02607 
02608 bool KHTMLPart::onlyLocalReferences() const
02609 {
02610   return d->m_onlyLocalReferences;
02611 }
02612 
02613 void KHTMLPart::setOnlyLocalReferences(bool enable)
02614 {
02615   d->m_onlyLocalReferences = enable;
02616 }
02617 
02618 void KHTMLPartPrivate::setFlagRecursively(
02619     bool KHTMLPartPrivate::*flag, bool value)
02620 {
02621   // first set it on the current one
02622   this->*flag = value;
02623 
02624   // descend into child frames recursively
02625   {
02626     TQValueList<khtml::ChildFrame*>::Iterator it = m_frames.begin();
02627     const TQValueList<khtml::ChildFrame*>::Iterator itEnd = m_frames.end();
02628     for (; it != itEnd; ++it) {
02629       KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
02630       if (part->inherits("KHTMLPart"))
02631         part->d->setFlagRecursively(flag, value);
02632     }/*next it*/
02633   }
02634   // do the same again for objects
02635   {
02636     TQValueList<khtml::ChildFrame*>::Iterator it = m_objects.begin();
02637     const TQValueList<khtml::ChildFrame*>::Iterator itEnd = m_objects.end();
02638     for (; it != itEnd; ++it) {
02639       KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
02640       if (part->inherits("KHTMLPart"))
02641         part->d->setFlagRecursively(flag, value);
02642     }/*next it*/
02643   }
02644 }
02645 
02646 void KHTMLPart::setCaretMode(bool enable)
02647 {
02648 #ifndef KHTML_NO_CARET
02649   kdDebug(6200) << "setCaretMode(" << enable << ")" << endl;
02650   if (isCaretMode() == enable) return;
02651   d->setFlagRecursively(&KHTMLPartPrivate::m_caretMode, enable);
02652   // FIXME: this won't work on frames as expected
02653   if (!isEditable()) {
02654     if (enable) {
02655       view()->initCaret(true);
02656       view()->ensureCaretVisible();
02657     } else
02658       view()->caretOff();
02659   }/*end if*/
02660 #endif // KHTML_NO_CARET
02661 }
02662 
02663 bool KHTMLPart::isCaretMode() const
02664 {
02665   return d->m_caretMode;
02666 }
02667 
02668 void KHTMLPart::setEditable(bool enable)
02669 {
02670 #ifndef KHTML_NO_CARET
02671   if (isEditable() == enable) return;
02672   d->setFlagRecursively(&KHTMLPartPrivate::m_designMode, enable);
02673   // FIXME: this won't work on frames as expected
02674   if (!isCaretMode()) {
02675     if (enable) {
02676       view()->initCaret(true);
02677       view()->ensureCaretVisible();
02678     } else
02679       view()->caretOff();
02680   }/*end if*/
02681 #endif // KHTML_NO_CARET
02682 }
02683 
02684 bool KHTMLPart::isEditable() const
02685 {
02686   return d->m_designMode;
02687 }
02688 
02689 void KHTMLPart::setCaretPosition(DOM::Node node, long offset, bool extendSelection)
02690 {
02691 #ifndef KHTML_NO_CARET
02692 #if 0
02693   kdDebug(6200) << k_funcinfo << "node: " << node.handle() << " nodeName: "
02694     << node.nodeName().string() << " offset: " << offset
02695     << " extendSelection " << extendSelection << endl;
02696 #endif
02697   if (view()->moveCaretTo(node.handle(), offset, !extendSelection))
02698     emitSelectionChanged();
02699   view()->ensureCaretVisible();
02700 #endif // KHTML_NO_CARET
02701 }
02702 
02703 KHTMLPart::CaretDisplayPolicy KHTMLPart::caretDisplayPolicyNonFocused() const
02704 {
02705 #ifndef KHTML_NO_CARET
02706   return (CaretDisplayPolicy)view()->caretDisplayPolicyNonFocused();
02707 #else // KHTML_NO_CARET
02708   return CaretInvisible;
02709 #endif // KHTML_NO_CARET
02710 }
02711 
02712 void KHTMLPart::setCaretDisplayPolicyNonFocused(CaretDisplayPolicy policy)
02713 {
02714 #ifndef KHTML_NO_CARET
02715   view()->setCaretDisplayPolicyNonFocused(policy);
02716 #endif // KHTML_NO_CARET
02717 }
02718 
02719 void KHTMLPart::setCaretVisible(bool show)
02720 {
02721 #ifndef KHTML_NO_CARET
02722   if (show) {
02723 
02724     NodeImpl *caretNode = xmlDocImpl()->focusNode();
02725     if (isCaretMode() || isEditable()
02726     || (caretNode && caretNode->contentEditable())) {
02727       view()->caretOn();
02728     }/*end if*/
02729 
02730   } else {
02731 
02732     view()->caretOff();
02733 
02734   }/*end if*/
02735 #endif // KHTML_NO_CARET
02736 }
02737 
02738 void KHTMLPart::findTextBegin()
02739 {
02740   d->m_findPos = -1;
02741   d->m_findNode = 0;
02742   d->m_findPosEnd = -1;
02743   d->m_findNodeEnd= 0;
02744   d->m_findPosStart = -1;
02745   d->m_findNodeStart = 0;
02746   d->m_findNodePrevious = 0;
02747   delete d->m_find;
02748   d->m_find = 0L;
02749 }
02750 
02751 bool KHTMLPart::initFindNode( bool selection, bool reverse, bool fromCursor )
02752 {
02753     if ( !d->m_doc )
02754         return false;
02755 
02756     DOM::NodeImpl* firstNode = 0L;
02757     if (d->m_doc->isHTMLDocument())
02758       firstNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
02759     else
02760       firstNode = d->m_doc;
02761 
02762     if ( !firstNode )
02763     {
02764       //kdDebug(6050) << k_funcinfo << "no first node (body or doc) -> return false" << endl;
02765       return false;
02766     }
02767     if ( firstNode->id() == ID_FRAMESET )
02768     {
02769       //kdDebug(6050) << k_funcinfo << "FRAMESET -> return false" << endl;
02770       return false;
02771     }
02772 
02773     if ( selection && hasSelection() )
02774     {
02775       //kdDebug(6050) << k_funcinfo << "using selection" << endl;
02776       if ( !fromCursor )
02777       {
02778         d->m_findNode = reverse ? d->m_selectionEnd.handle() : d->m_selectionStart.handle();
02779         d->m_findPos = reverse ? d->m_endOffset : d->m_startOffset;
02780       }
02781       d->m_findNodeEnd = reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
02782       d->m_findPosEnd = reverse ? d->m_startOffset : d->m_endOffset;
02783       d->m_findNodeStart = !reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
02784       d->m_findPosStart = !reverse ? d->m_startOffset : d->m_endOffset;
02785       d->m_findNodePrevious = d->m_findNodeStart;
02786     }
02787     else // whole document
02788     {
02789       //kdDebug(6050) << k_funcinfo << "whole doc" << endl;
02790       if ( !fromCursor )
02791       {
02792         d->m_findNode = firstNode;
02793         d->m_findPos = reverse ? -1 : 0;
02794       }
02795       d->m_findNodeEnd = reverse ? firstNode : 0;
02796       d->m_findPosEnd = reverse ? 0 : -1;
02797       d->m_findNodeStart = !reverse ? firstNode : 0;
02798       d->m_findPosStart = !reverse ? 0 : -1;
02799       d->m_findNodePrevious = d->m_findNodeStart;
02800       if ( reverse )
02801       {
02802         // Need to find out the really last object, to start from it
02803         khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
02804         if ( obj )
02805         {
02806           // find the last object in the render tree
02807           while ( obj->lastChild() )
02808           {
02809               obj = obj->lastChild();
02810           }
02811           // now get the last object with a NodeImpl associated
02812           while ( !obj->element() && obj->objectAbove() )
02813           {
02814              obj = obj->objectAbove();
02815           }
02816           d->m_findNode = obj->element();
02817         }
02818       }
02819     }
02820     return true;
02821 }
02822 
02823 // Old method (its API limits the available features - remove in KDE-4)
02824 bool KHTMLPart::findTextNext( const TQString &str, bool forward, bool caseSensitive, bool isRegExp )
02825 {
02826     if ( !initFindNode( false, !forward, d->m_findNode ) )
02827       return false;
02828     while(1)
02829     {
02830         if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
02831         {
02832             DOMString nodeText = d->m_findNode->nodeValue();
02833             DOMStringImpl *t = nodeText.implementation();
02834             TQConstString s(t->s, t->l);
02835 
02836             int matchLen = 0;
02837             if ( isRegExp ) {
02838               TQRegExp matcher( str );
02839               matcher.setCaseSensitive( caseSensitive );
02840               d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
02841               if ( d->m_findPos != -1 )
02842                 matchLen = matcher.matchedLength();
02843             }
02844             else {
02845               d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
02846               matchLen = str.length();
02847             }
02848 
02849             if(d->m_findPos != -1)
02850             {
02851                 int x = 0, y = 0;
02852                 if(static_cast<khtml::RenderText *>(d->m_findNode->renderer())
02853                   ->posOfChar(d->m_findPos, x, y))
02854                     d->m_view->setContentsPos(x-50, y-50);
02855 
02856                 d->m_selectionStart = d->m_findNode;
02857                 d->m_startOffset = d->m_findPos;
02858                 d->m_selectionEnd = d->m_findNode;
02859                 d->m_endOffset = d->m_findPos + matchLen;
02860                 d->m_startBeforeEnd = true;
02861 
02862                 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
02863                                         d->m_selectionEnd.handle(), d->m_endOffset );
02864                 emitSelectionChanged();
02865                 return true;
02866             }
02867         }
02868         d->m_findPos = -1;
02869 
02870         NodeImpl *next;
02871 
02872         if ( forward )
02873         {
02874           next = d->m_findNode->firstChild();
02875 
02876           if(!next) next = d->m_findNode->nextSibling();
02877           while(d->m_findNode && !next) {
02878               d->m_findNode = d->m_findNode->parentNode();
02879               if( d->m_findNode ) {
02880                   next = d->m_findNode->nextSibling();
02881               }
02882           }
02883         }
02884         else
02885         {
02886           next = d->m_findNode->lastChild();
02887 
02888           if (!next ) next = d->m_findNode->previousSibling();
02889           while ( d->m_findNode && !next )
02890           {
02891             d->m_findNode = d->m_findNode->parentNode();
02892             if( d->m_findNode )
02893             {
02894               next = d->m_findNode->previousSibling();
02895             }
02896           }
02897         }
02898 
02899         d->m_findNode = next;
02900         if(!d->m_findNode) return false;
02901     }
02902 }
02903 
02904 
02905 void KHTMLPart::slotFind()
02906 {
02907   KParts::ReadOnlyPart *part = currentFrame();
02908   if (!part)
02909     return;
02910   if (!part->inherits("KHTMLPart") )
02911   {
02912       kdError(6000) << "slotFind: part is a " << part->className() << ", can't do a search into it" << endl;
02913       return;
02914   }
02915   static_cast<KHTMLPart *>( part )->findText();
02916 }
02917 
02918 void KHTMLPart::slotFindNext()
02919 {
02920   KParts::ReadOnlyPart *part = currentFrame();
02921   if (!part)
02922     return;
02923   if (!part->inherits("KHTMLPart") )
02924   {
02925       kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
02926       return;
02927   }
02928   static_cast<KHTMLPart *>( part )->findTextNext();
02929 }
02930 
02931 void KHTMLPart::slotFindPrev()
02932 {
02933   KParts::ReadOnlyPart *part = currentFrame();
02934   if (!part)
02935     return;
02936   if (!part->inherits("KHTMLPart") )
02937   {
02938       kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
02939       return;
02940   }
02941   static_cast<KHTMLPart *>( part )->findTextNext( true ); // reverse
02942 }
02943 
02944 void KHTMLPart::slotFindDone()
02945 {
02946   // ### remove me
02947 }
02948 
02949 void KHTMLPart::slotFindAheadText()
02950 {
02951 #ifndef KHTML_NO_TYPE_AHEAD_FIND
02952   KParts::ReadOnlyPart *part = currentFrame();
02953   if (!part)
02954     return;
02955   if (!part->inherits("KHTMLPart") )
02956   {
02957       kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
02958       return;
02959   }
02960   static_cast<KHTMLPart *>( part )->view()->startFindAhead( false );
02961 #endif // KHTML_NO_TYPE_AHEAD_FIND
02962 }
02963 
02964 void KHTMLPart::slotFindAheadLink()
02965 {
02966 #ifndef KHTML_NO_TYPE_AHEAD_FIND
02967   KParts::ReadOnlyPart *part = currentFrame();
02968   if (!part)
02969     return;
02970   if (!part->inherits("KHTMLPart") )
02971   {
02972       kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
02973       return;
02974   }
02975   static_cast<KHTMLPart *>( part )->view()->startFindAhead( true );
02976 #endif // KHTML_NO_TYPE_AHEAD_FIND
02977 }
02978 
02979 void KHTMLPart::enableFindAheadActions( bool enable )
02980 {
02981   // only the topmost one has shortcuts
02982   KHTMLPart* p = this;
02983   while( p->parentPart())
02984     p = p->parentPart();
02985   p->d->m_paFindAheadText->setEnabled( enable );
02986   p->d->m_paFindAheadLinks->setEnabled( enable );
02987 }
02988 
02989 void KHTMLPart::slotFindDialogDestroyed()
02990 {
02991   d->m_lastFindState.options = d->m_findDialog->options();
02992   d->m_lastFindState.history = d->m_findDialog->findHistory();
02993   d->m_findDialog->deleteLater();
02994   d->m_findDialog = 0L;
02995 }
02996 
02997 void KHTMLPart::findText()
02998 {
02999   // First do some init to make sure we can search in this frame
03000   if ( !d->m_doc )
03001     return;
03002 
03003   // Raise if already opened
03004   if ( d->m_findDialog )
03005   {
03006     KWin::activateWindow( d->m_findDialog->winId() );
03007     return;
03008   }
03009 
03010   // The lineedit of the dialog would make khtml lose its selection, otherwise
03011 #ifndef QT_NO_CLIPBOARD
03012   disconnect( kapp->clipboard(), TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotClearSelection()) );
03013 #endif
03014 
03015   // Now show the dialog in which the user can choose options.
03016   d->m_findDialog = new KFindDialog( false /*non-modal*/, widget(), "khtmlfind" );
03017   d->m_findDialog->setHasSelection( hasSelection() );
03018   d->m_findDialog->setHasCursor( d->m_findNode != 0 );
03019   if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
03020     d->m_lastFindState.options |= KFindDialog::FromCursor;
03021 
03022   // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
03023   d->m_findDialog->setFindHistory( d->m_lastFindState.history );
03024   d->m_findDialog->setOptions( d->m_lastFindState.options );
03025 
03026   d->m_lastFindState.options = -1; // force update in findTextNext
03027   d->m_lastFindState.last_dir = -1;
03028 
03029   d->m_findDialog->show();
03030   connect( d->m_findDialog, TQT_SIGNAL(okClicked()), this, TQT_SLOT(slotFindNext()) );
03031   connect( d->m_findDialog, TQT_SIGNAL(finished()), this, TQT_SLOT(slotFindDialogDestroyed()) );
03032 
03033   findText( d->m_findDialog->pattern(), 0 /*options*/, widget(), d->m_findDialog );
03034 }
03035 
03036 void KHTMLPart::findText( const TQString &str, long options, TQWidget *parent, KFindDialog *findDialog )
03037 {
03038   // First do some init to make sure we can search in this frame
03039   if ( !d->m_doc )
03040     return;
03041 
03042 #ifndef QT_NO_CLIPBOARD
03043   connect( kapp->clipboard(), TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotClearSelection()) );
03044 #endif
03045 
03046   // Create the KFind object
03047   delete d->m_find;
03048   d->m_find = new KFind( str, options, parent, findDialog );
03049   d->m_find->closeFindNextDialog(); // we use KFindDialog non-modal, so we don't want other dlg popping up
03050   connect( d->m_find, TQT_SIGNAL( highlight( const TQString &, int, int ) ),
03051            this, TQT_SLOT( slotHighlight( const TQString &, int, int ) ) );
03052   //connect(d->m_find, TQT_SIGNAL( findNext() ),
03053   //        this, TQT_SLOT( slotFindNext() ) );
03054 
03055   if ( !findDialog )
03056   {
03057     d->m_lastFindState.options = options;
03058     initFindNode( options & KFindDialog::SelectedText,
03059                   options & KFindDialog::FindBackwards,
03060                   options & KFindDialog::FromCursor );
03061   }
03062 }
03063 
03064 bool KHTMLPart::findTextNext()
03065 {
03066   return findTextNext( false );
03067 }
03068 
03069 // New method
03070 bool KHTMLPart::findTextNext( bool reverse )
03071 {
03072   if (!d->m_find)
03073   {
03074     // We didn't show the find dialog yet, let's do it then (#49442)
03075     findText();
03076     return false;
03077   }
03078 
03079   view()->updateFindAheadTimeout();
03080   long options = 0;
03081   if ( d->m_findDialog ) // 0 when we close the dialog
03082   {
03083     if ( d->m_find->pattern() != d->m_findDialog->pattern() ) {
03084       d->m_find->setPattern( d->m_findDialog->pattern() );
03085       d->m_find->resetCounts();
03086     }
03087     options = d->m_findDialog->options();
03088     if ( d->m_lastFindState.options != options )
03089     {
03090       d->m_find->setOptions( options );
03091 
03092       if ( options & KFindDialog::SelectedText )
03093         Q_ASSERT( hasSelection() );
03094 
03095       long difference = d->m_lastFindState.options ^ options;
03096       if ( difference & (KFindDialog::SelectedText | KFindDialog::FromCursor ) )
03097       {
03098           // Important options changed -> reset search range
03099         (void) initFindNode( options & KFindDialog::SelectedText,
03100                              options & KFindDialog::FindBackwards,
03101                              options & KFindDialog::FromCursor );
03102       }
03103       d->m_lastFindState.options = options;
03104     }
03105   } else
03106     options = d->m_lastFindState.options;
03107   if( reverse )
03108     options = options ^ KFindDialog::FindBackwards;
03109   if( d->m_find->options() != options )
03110     d->m_find->setOptions( options );
03111 
03112   // Changing find direction. Start and end nodes must be switched.
03113   // Additionally since d->m_findNode points after the last node
03114   // that was searched, it needs to be "after" it in the opposite direction.
03115   if( d->m_lastFindState.last_dir != -1
03116       && bool( d->m_lastFindState.last_dir ) != bool( options & KFindDialog::FindBackwards ))
03117   {
03118     tqSwap( d->m_findNodeEnd, d->m_findNodeStart );
03119     tqSwap( d->m_findPosEnd, d->m_findPosStart );
03120     tqSwap( d->m_findNode, d->m_findNodePrevious );
03121     // d->m_findNode now point at the end of the last searched line - advance one node
03122     khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
03123     khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
03124     if ( obj == end )
03125       obj = 0L;
03126     else if ( obj )
03127     {
03128       do {
03129         obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
03130       } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
03131     }
03132     if ( obj )
03133       d->m_findNode = obj->element();
03134     else
03135       d->m_findNode = 0;
03136   }
03137   d->m_lastFindState.last_dir = ( options & KFindDialog::FindBackwards ) ? 1 : 0;
03138 
03139   KFind::Result res = KFind::NoMatch;
03140   khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
03141   khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
03142   khtml::RenderTextArea *tmpTextArea=0L;
03143   //kdDebug(6050) << k_funcinfo << "obj=" << obj << " end=" << end << endl;
03144   while( res == KFind::NoMatch )
03145   {
03146     if ( d->m_find->needData() )
03147     {
03148       if ( !obj ) {
03149         //kdDebug(6050) << k_funcinfo << "obj=0 -> done" << endl;
03150         break; // we're done
03151       }
03152       //kdDebug(6050) << k_funcinfo << " gathering data" << endl;
03153       // First make up the TQString for the current 'line' (i.e. up to \n)
03154       // We also want to remember the DOMNode for every portion of the string.
03155       // We store this in an index->node list.
03156 
03157       d->m_stringPortions.clear();
03158       bool newLine = false;
03159       TQString str;
03160       DOM::NodeImpl* lastNode = d->m_findNode;
03161       while ( obj && !newLine )
03162       {
03163         // Grab text from render object
03164         TQString s;
03165         bool renderAreaText = obj->parent() && (TQCString(obj->parent()->renderName())== "RenderTextArea");
03166         bool renderLineText = (TQCString(obj->renderName())== "RenderLineEdit");
03167         if ( renderAreaText )
03168         {
03169           khtml::RenderTextArea *parent= static_cast<khtml::RenderTextArea *>(obj->parent());
03170           s = parent->text();
03171           s = s.replace(0xa0, ' ');
03172           tmpTextArea = parent;
03173         }
03174         else if ( renderLineText )
03175         {
03176           khtml::RenderLineEdit *parentLine= static_cast<khtml::RenderLineEdit *>(obj);
03177           if (parentLine->widget()->echoMode() == TQLineEdit::Normal)
03178             s = parentLine->widget()->text();
03179           s = s.replace(0xa0, ' ');
03180         }
03181         else if ( obj->isText() )
03182         {
03183           bool isLink = false;
03184 
03185           // checks whether the node has a <A> parent
03186           if ( options & FindLinksOnly )
03187           {
03188             DOM::NodeImpl *parent = obj->element();
03189             while ( parent )
03190             {
03191               if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
03192               {
03193                 isLink = true;
03194                 break;
03195               }
03196               parent = parent->parentNode();
03197             }
03198           }
03199           else
03200           {
03201             isLink = true;
03202           }
03203 
03204           if ( isLink && obj->parent()!=tmpTextArea )
03205           {
03206             s = static_cast<khtml::RenderText *>(obj)->data().string();
03207             s = s.replace(0xa0, ' ');
03208           }
03209         }
03210         else if ( obj->isBR() )
03211           s = '\n';
03212         else if ( !obj->isInline() && !str.isEmpty() )
03213           s = '\n';
03214 
03215         if ( lastNode == d->m_findNodeEnd )
03216           s.truncate( d->m_findPosEnd );
03217         if ( !s.isEmpty() )
03218         {
03219           newLine = s.find( '\n' ) != -1; // did we just get a newline?
03220           if( !( options & KFindDialog::FindBackwards ))
03221           {
03222             //kdDebug(6050) << "StringPortion: " << index << "-" << index+s.length()-1 << " -> " << lastNode << endl;
03223             d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( str.length(), lastNode ) );
03224             str += s;
03225           }
03226           else // KFind itself can search backwards, so str must not be built backwards
03227           {
03228             for( TQValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
03229                  it != d->m_stringPortions.end();
03230                  ++it )
03231                 (*it).index += s.length();
03232             d->m_stringPortions.prepend( KHTMLPartPrivate::StringPortion( 0, lastNode ) );
03233             str.prepend( s );
03234           }
03235         }
03236         // Compare obj and end _after_ we processed the 'end' node itself
03237         if ( obj == end )
03238           obj = 0L;
03239         else
03240         {
03241           // Move on to next object (note: if we found a \n already, then obj (and lastNode)
03242           // will point to the _next_ object, i.e. they are in advance.
03243           do {
03244             // We advance until the next RenderObject that has a NodeImpl as its element().
03245             // Otherwise (if we keep the 'last node', and it has a '\n') we might be stuck
03246             // on that object forever...
03247             obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
03248           } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
03249         }
03250         if ( obj )
03251           lastNode = obj->element();
03252         else
03253           lastNode = 0;
03254       } // end while
03255       //kdDebug()<<" str : "<<str<<endl;
03256       if ( !str.isEmpty() )
03257       {
03258         d->m_find->setData( str, d->m_findPos );
03259       }
03260 
03261       d->m_findPos = -1; // not used during the findnext loops. Only during init.
03262       d->m_findNodePrevious = d->m_findNode;
03263       d->m_findNode = lastNode;
03264     }
03265     if ( !d->m_find->needData() ) // happens if str was empty
03266     {
03267       // Let KFind inspect the text fragment, and emit highlighted if a match is found
03268       res = d->m_find->find();
03269     }
03270   } // end while
03271 
03272   if ( res == KFind::NoMatch ) // i.e. we're done
03273   {
03274     kdDebug() << "No more matches." << endl;
03275     if ( !(options & FindNoPopups) && d->m_find->shouldRestart() )
03276     {
03277       //kdDebug(6050) << "Restarting" << endl;
03278       initFindNode( false, options & KFindDialog::FindBackwards, false );
03279       d->m_find->resetCounts();
03280       findTextNext( reverse );
03281     }
03282     else // really done
03283     {
03284       //kdDebug(6050) << "Finishing" << endl;
03285       //delete d->m_find;
03286       //d->m_find = 0L;
03287       initFindNode( false, options & KFindDialog::FindBackwards, false );
03288       d->m_find->resetCounts();
03289       slotClearSelection();
03290     }
03291     kdDebug() << "Dialog closed." << endl;
03292   }
03293 
03294   return res == KFind::Match;
03295 }
03296 
03297 void KHTMLPart::slotHighlight( const TQString& /*text*/, int index, int length )
03298 {
03299   //kdDebug(6050) << "slotHighlight index=" << index << " length=" << length << endl;
03300   TQValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
03301   const TQValueList<KHTMLPartPrivate::StringPortion>::Iterator itEnd = d->m_stringPortions.end();
03302   TQValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
03303   // We stop at the first portion whose index is 'greater than', and then use the previous one
03304   while ( it != itEnd && (*it).index <= index )
03305   {
03306     prev = it;
03307     ++it;
03308   }
03309   Q_ASSERT ( prev != itEnd );
03310   DOM::NodeImpl* node = (*prev).node;
03311   Q_ASSERT( node );
03312 
03313   d->m_selectionStart = node;
03314   d->m_startOffset = index - (*prev).index;
03315 
03316   khtml::RenderObject* obj = node->renderer();
03317   khtml::RenderTextArea *parent = 0L;
03318   khtml::RenderLineEdit *parentLine = 0L;
03319   bool renderLineText =false;
03320 
03321   TQRect highlightedRect;
03322   bool renderAreaText =false;
03323   Q_ASSERT( obj );
03324   if ( obj )
03325   {
03326     int x = 0, y = 0;
03327     renderAreaText = (TQCString(obj->parent()->renderName())== "RenderTextArea");
03328     renderLineText = (TQCString(obj->renderName())== "RenderLineEdit");
03329 
03330 
03331     if( renderAreaText )
03332       parent= static_cast<khtml::RenderTextArea *>(obj->parent());
03333     if ( renderLineText )
03334       parentLine= static_cast<khtml::RenderLineEdit *>(obj);
03335     if ( !renderLineText )
03336       //if (static_cast<khtml::RenderText *>(node->renderer())
03337       //    ->posOfChar(d->m_startOffset, x, y))
03338       {
03339         int dummy;
03340         static_cast<khtml::RenderText *>(node->renderer())
03341           ->caretPos( d->m_startOffset, false, x, y, dummy, dummy ); // more precise than posOfChar
03342         //kdDebug(6050) << "topleft: " << x << "," << y << endl;
03343         if ( x != -1 || y != -1 )
03344         {
03345           int gox = d->m_view->contentsX();
03346           if (x+50 > d->m_view->contentsX() + d->m_view->visibleWidth())
03347               gox = x - d->m_view->visibleWidth() + 50;
03348           if (x-10 < d->m_view->contentsX())
03349               gox = x - d->m_view->visibleWidth() - 10;
03350           if (gox < 0) gox = 0;
03351           d->m_view->setContentsPos(gox, y-50);
03352           highlightedRect.setTopLeft( d->m_view->mapToGlobal(TQPoint(x, y)) );
03353         }
03354       }
03355   }
03356   // Now look for end node
03357   it = prev; // no need to start from beginning again
03358   while ( it != itEnd && (*it).index < index + length )
03359   {
03360     prev = it;
03361     ++it;
03362   }
03363   Q_ASSERT ( prev != itEnd );
03364 
03365   d->m_selectionEnd = (*prev).node;
03366   d->m_endOffset = index + length - (*prev).index;
03367   d->m_startBeforeEnd = true;
03368 
03369   // if the selection is limited to a single link, that link gets focus
03370   if(d->m_selectionStart == d->m_selectionEnd)
03371   {
03372     bool isLink = false;
03373 
03374     // checks whether the node has a <A> parent
03375     DOM::NodeImpl *parent = d->m_selectionStart.handle();
03376     while ( parent )
03377     {
03378       if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
03379       {
03380         isLink = true;
03381         break;
03382       }
03383       parent = parent->parentNode();
03384     }
03385 
03386     if(isLink == true)
03387     {
03388       d->m_doc->setFocusNode( parent );
03389     }
03390   }
03391 
03392 #if 0
03393   kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
03394     d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
03395   it = d->m_stringPortions.begin();
03396   for ( ; it != d->m_stringPortions.end() ; ++it )
03397     kdDebug(6050) << "  StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
03398 #endif
03399   if( renderAreaText )
03400   {
03401     if( parent )
03402       parent->highLightWord( length, d->m_endOffset-length );
03403   }
03404   else if ( renderLineText )
03405   {
03406     if( parentLine )
03407       parentLine->highLightWord( length, d->m_endOffset-length );
03408   }
03409   else
03410   {
03411     d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
03412                             d->m_selectionEnd.handle(), d->m_endOffset );
03413     if (d->m_selectionEnd.handle()->renderer() )
03414     {
03415       int x, y, height, dummy;
03416       static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
03417           ->caretPos( d->m_endOffset, false, x, y, dummy, height ); // more precise than posOfChar
03418       //kdDebug(6050) << "bottomright: " << x << "," << y+height << endl;
03419       if ( x != -1 || y != -1 )
03420       {
03421         // if ( static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
03422         //  ->posOfChar(d->m_endOffset-1, x, y))
03423         highlightedRect.setBottomRight( d->m_view->mapToGlobal( TQPoint(x, y+height) ) );
03424       }
03425     }
03426   }
03427   emitSelectionChanged();
03428 
03429   // make the finddialog move away from the selected area
03430   if ( d->m_findDialog && !highlightedRect.isNull() )
03431   {
03432     highlightedRect.moveBy( -d->m_view->contentsX(), -d->m_view->contentsY() );
03433     //kdDebug(6050) << "avoiding " << highlightedRect << endl;
03434     KDialog::avoidArea( d->m_findDialog, highlightedRect );
03435   }
03436 }
03437 
03438 TQString KHTMLPart::selectedTextAsHTML() const
03439 {
03440   if(!hasSelection()) {
03441     kdDebug() << "selectedTextAsHTML(): selection is not valid.  Returning empty selection" << endl;
03442     return TQString();
03443   }
03444   if(d->m_startOffset < 0 || d->m_endOffset <0) {
03445     kdDebug() << "invalid values for end/startOffset " << d->m_startOffset << " " << d->m_endOffset << endl;
03446     return TQString();
03447   }
03448   DOM::Range r = selection();
03449   if(r.isNull() || r.isDetached())
03450     return TQString();
03451   int exceptioncode = 0; //ignore the result
03452   return r.handle()->toHTML(exceptioncode).string();
03453 }
03454 
03455 TQString KHTMLPart::selectedText() const
03456 {
03457   bool hasNewLine = true;
03458   bool seenTDTag = false;
03459   TQString text;
03460   DOM::Node n = d->m_selectionStart;
03461   while(!n.isNull()) {
03462       if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
03463         DOM::DOMStringImpl *dstr = static_cast<DOM::TextImpl*>(n.handle())->renderString();
03464         TQString str(dstr->s, dstr->l);
03465     if(!str.isEmpty()) {
03466           if(seenTDTag) {
03467         text += "  ";
03468         seenTDTag = false;
03469       }
03470           hasNewLine = false;
03471           if(n == d->m_selectionStart && n == d->m_selectionEnd)
03472             text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
03473           else if(n == d->m_selectionStart)
03474             text = str.mid(d->m_startOffset);
03475           else if(n == d->m_selectionEnd)
03476             text += str.left(d->m_endOffset);
03477           else
03478             text += str;
03479     }
03480       }
03481       else {
03482         // This is our simple HTML -> ASCII transformation:
03483         unsigned short id = n.elementId();
03484         switch(id) {
03485       case ID_TEXTAREA:
03486         text += static_cast<HTMLTextAreaElementImpl*>(n.handle())->value().string();
03487         break;
03488       case ID_INPUT:
03489             if (static_cast<HTMLInputElementImpl*>(n.handle())->inputType() != HTMLInputElementImpl::PASSWORD)
03490           text += static_cast<HTMLInputElementImpl*>(n.handle())->value().string();
03491         break;
03492       case ID_SELECT:
03493         text += static_cast<HTMLSelectElementImpl*>(n.handle())->value().string();
03494         break;
03495           case ID_BR:
03496             text += "\n";
03497             hasNewLine = true;
03498             break;
03499           case ID_IMG:
03500         text += static_cast<HTMLImageElementImpl*>(n.handle())->altText().string();
03501         break;
03502           case ID_TD:
03503         break;
03504           case ID_TH:
03505           case ID_HR:
03506           case ID_OL:
03507           case ID_UL:
03508           case ID_LI:
03509           case ID_DD:
03510           case ID_DL:
03511           case ID_DT:
03512           case ID_PRE:
03513           case ID_BLOCKQUOTE:
03514           case ID_DIV:
03515             if (!hasNewLine)
03516                text += "\n";
03517             hasNewLine = true;
03518             break;
03519           case ID_P:
03520           case ID_TR:
03521           case ID_H1:
03522           case ID_H2:
03523           case ID_H3:
03524           case ID_H4:
03525           case ID_H5:
03526           case ID_H6:
03527             if (!hasNewLine)
03528                text += "\n";
03529 //            text += "\n";
03530             hasNewLine = true;
03531             break;
03532         }
03533       }
03534       if(n == d->m_selectionEnd) break;
03535       DOM::Node next = n.firstChild();
03536       if(next.isNull()) next = n.nextSibling();
03537       while( next.isNull() && !n.parentNode().isNull() ) {
03538         n = n.parentNode();
03539         next = n.nextSibling();
03540         unsigned short id = n.elementId();
03541         switch(id) {
03542           case ID_TD:
03543         seenTDTag = true; //Add two spaces after a td if then followed by text.
03544         break;
03545           case ID_TH:
03546           case ID_HR:
03547           case ID_OL:
03548           case ID_UL:
03549           case ID_LI:
03550           case ID_DD:
03551           case ID_DL:
03552           case ID_DT:
03553           case ID_PRE:
03554           case ID_BLOCKQUOTE:
03555           case ID_DIV:
03556         seenTDTag = false;
03557             if (!hasNewLine)
03558                text += "\n";
03559             hasNewLine = true;
03560             break;
03561           case ID_P:
03562           case ID_TR:
03563           case ID_H1:
03564           case ID_H2:
03565           case ID_H3:
03566           case ID_H4:
03567           case ID_H5:
03568           case ID_H6:
03569             if (!hasNewLine)
03570                text += "\n";
03571 //            text += "\n";
03572             hasNewLine = true;
03573             break;
03574         }
03575       }
03576 
03577       n = next;
03578     }
03579 
03580     if(text.isEmpty())
03581         return TQString();
03582 
03583     int start = 0;
03584     int end = text.length();
03585 
03586     // Strip leading LFs
03587     while ((start < end) && (text[start] == '\n'))
03588        ++start;
03589 
03590     // Strip excessive trailing LFs
03591     while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
03592        --end;
03593 
03594     return text.mid(start, end-start);
03595 }
03596 
03597 bool KHTMLPart::hasSelection() const
03598 {
03599   if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
03600       return false;
03601   if ( d->m_selectionStart == d->m_selectionEnd &&
03602        d->m_startOffset == d->m_endOffset )
03603       return false; // empty
03604   return true;
03605 }
03606 
03607 DOM::Range KHTMLPart::selection() const
03608 {
03609     if( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
03610         return DOM::Range();
03611     DOM::Range r = document().createRange();
03612     RangeImpl *rng = r.handle();
03613     int exception = 0;
03614     NodeImpl *n = d->m_selectionStart.handle();
03615     if(!n->parentNode() ||
03616        !n->renderer() ||
03617        (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
03618         rng->setStart( n, d->m_startOffset, exception );
03619     if(exception) {
03620         kdDebug(6000) << "1 -selection() threw the exception " << exception << ".  Returning empty range." << endl;
03621         return DOM::Range();
03622     }
03623     } else {
03624         int o_start = 0;
03625         while ((n = n->previousSibling()))
03626             o_start++;
03627     rng->setStart( d->m_selectionStart.parentNode().handle(), o_start + d->m_startOffset, exception );
03628     if(exception) {
03629         kdDebug(6000) << "2 - selection() threw the exception " << exception << ".  Returning empty range." << endl;
03630         return DOM::Range();
03631     }
03632 
03633     }
03634 
03635     n = d->m_selectionEnd.handle();
03636     if(!n->parentNode() ||
03637        !n->renderer() ||
03638        (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
03639 
03640     rng->setEnd( n, d->m_endOffset, exception );
03641     if(exception) {
03642         kdDebug(6000) << "3 - selection() threw the exception " << exception << ".  Returning empty range." << endl;
03643         return DOM::Range();
03644     }
03645 
03646     } else {
03647         int o_end = 0;
03648         while ((n = n->previousSibling()))
03649             o_end++;
03650     rng->setEnd( d->m_selectionEnd.parentNode().handle(), o_end + d->m_endOffset, exception);
03651     if(exception) {
03652         kdDebug(6000) << "4 - selection() threw the exception " << exception << ".  Returning empty range." << endl;
03653         return DOM::Range();
03654     }
03655 
03656     }
03657 
03658     return r;
03659 }
03660 
03661 void KHTMLPart::selection(DOM::Node &s, long &so, DOM::Node &e, long &eo) const
03662 {
03663     s = d->m_selectionStart;
03664     so = d->m_startOffset;
03665     e = d->m_selectionEnd;
03666     eo = d->m_endOffset;
03667 }
03668 
03669 void KHTMLPart::setSelection( const DOM::Range &r )
03670 {
03671     // Quick-fix: a collapsed range shouldn't select the whole node.
03672     // The real problem is in RenderCanvas::setSelection though (when index==0 the whole node is selected).
03673     if ( r.collapsed() )
03674         slotClearSelection();
03675     else {
03676         d->m_selectionStart = r.startContainer();
03677         d->m_startOffset = r.startOffset();
03678         d->m_selectionEnd = r.endContainer();
03679         d->m_endOffset = r.endOffset();
03680         d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
03681                                d->m_selectionEnd.handle(),d->m_endOffset);
03682 #ifndef KHTML_NO_CARET
03683         bool v = d->m_view->placeCaret();
03684         emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
03685 #endif
03686     }
03687 }
03688 
03689 void KHTMLPart::slotClearSelection()
03690 {
03691     bool hadSelection = hasSelection();
03692 #ifndef KHTML_NO_CARET
03693     //kdDebug(6000) << "d->m_selectionStart " << d->m_selectionStart.handle()
03694     //      << " d->m_selectionEnd " << d->m_selectionEnd.handle() << endl;
03695     // nothing, leave selection parameters as is
03696 #else
03697     d->m_selectionStart = 0;
03698     d->m_startOffset = 0;
03699     d->m_selectionEnd = 0;
03700     d->m_endOffset = 0;
03701 #endif
03702     if ( d->m_doc ) d->m_doc->clearSelection();
03703     if ( hadSelection )
03704       emitSelectionChanged();
03705 #ifndef KHTML_NO_CARET
03706     bool v = d->m_view->placeCaret();
03707     emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
03708 #endif
03709 }
03710 
03711 void KHTMLPart::resetHoverText()
03712 {
03713    if( !d->m_overURL.isEmpty() ) // Only if we were showing a link
03714    {
03715      d->m_overURL = d->m_overURLTarget = TQString();
03716      emit onURL( TQString() );
03717      // revert to default statusbar text
03718      setStatusBarText(TQString(), BarHoverText);
03719      emit d->m_extension->mouseOverInfo(0);
03720   }
03721 }
03722 
03723 void KHTMLPart::overURL( const TQString &url, const TQString &target, bool /*shiftPressed*/ )
03724 {
03725   KURL u = completeURL(url);
03726 
03727   // special case for <a href="">
03728   if ( url.isEmpty() )
03729     u.setFileName( url );
03730 
03731   emit onURL( url );
03732 
03733   if ( url.isEmpty() ) {
03734     setStatusBarText(u.htmlURL(), BarHoverText);
03735     return;
03736   }
03737 
03738   if (url.find( TQString::fromLatin1( "javascript:" ),0, false ) == 0 ) {
03739     TQString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
03740     jscode = KStringHandler::rsqueeze( jscode, 80 ); // truncate if too long
03741     if (url.startsWith("javascript:window.open"))
03742       jscode += i18n(" (In new window)");
03743     setStatusBarText( TQStyleSheet::escape( jscode ), BarHoverText );
03744     return;
03745   }
03746 
03747   KFileItem item(u, TQString(), KFileItem::Unknown);
03748   emit d->m_extension->mouseOverInfo(&item);
03749 
03750   TQString com;
03751 
03752   KMimeType::Ptr typ = KMimeType::findByURL( u );
03753 
03754   if ( typ )
03755     com = typ->comment( u, false );
03756 
03757   if ( !u.isValid() ) {
03758     setStatusBarText(u.htmlURL(), BarHoverText);
03759     return;
03760   }
03761 
03762   if ( u.isLocalFile() )
03763   {
03764     // TODO : use KIO::stat() and create a KFileItem out of its result,
03765     // to use KFileItem::statusBarText()
03766     TQCString path = TQFile::encodeName( u.path() );
03767 
03768     struct stat buff;
03769     bool ok = !stat( path.data(), &buff );
03770 
03771     struct stat lbuff;
03772     if (ok) ok = !lstat( path.data(), &lbuff );
03773 
03774     TQString text = u.htmlURL();
03775     TQString text2 = text;
03776 
03777     if (ok && S_ISLNK( lbuff.st_mode ) )
03778     {
03779       TQString tmp;
03780       if ( com.isNull() )
03781         tmp = i18n( "Symbolic Link");
03782       else
03783         tmp = i18n("%1 (Link)").arg(com);
03784       char buff_two[1024];
03785       text += " -> ";
03786       int n = readlink ( path.data(), buff_two, 1022);
03787       if (n == -1)
03788       {
03789         text2 += "  ";
03790         text2 += tmp;
03791         setStatusBarText(text2, BarHoverText);
03792         return;
03793       }
03794       buff_two[n] = 0;
03795 
03796       text += buff_two;
03797       text += "  ";
03798       text += tmp;
03799     }
03800     else if ( ok && S_ISREG( buff.st_mode ) )
03801     {
03802       if (buff.st_size < 1024)
03803         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
03804       else
03805       {
03806         float d = (float) buff.st_size/1024.0;
03807         text = i18n("%2 (%1 K)").arg(KGlobal::locale()->formatNumber(d, 2)).arg(text2); // was %.2f
03808       }
03809       text += "  ";
03810       text += com;
03811     }
03812     else if ( ok && S_ISDIR( buff.st_mode ) )
03813     {
03814       text += "  ";
03815       text += com;
03816     }
03817     else
03818     {
03819       text += "  ";
03820       text += com;
03821     }
03822     setStatusBarText(text, BarHoverText);
03823   }
03824   else
03825   {
03826     TQString extra;
03827     if (target.lower() == "_blank")
03828     {
03829       extra = i18n(" (In new window)");
03830     }
03831     else if (!target.isEmpty() &&
03832              (target.lower() != "_top") &&
03833              (target.lower() != "_self") &&
03834              (target.lower() != "_parent"))
03835     {
03836       KHTMLPart *p = this;
03837       while (p->parentPart())
03838           p = p->parentPart();
03839       if (!p->frameExists(target))
03840         extra = i18n(" (In new window)");
03841       else
03842         extra = i18n(" (In other frame)");
03843     }
03844 
03845     if (u.protocol() == TQString::fromLatin1("mailto")) {
03846       TQString mailtoMsg /* = TQString::fromLatin1("<img src=%1>").arg(locate("icon", TQString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
03847       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
03848       TQStringList queries = TQStringList::split('&', u.query().mid(1));
03849       TQStringList::Iterator it = queries.begin();
03850       const TQStringList::Iterator itEnd = queries.end();
03851       for (; it != itEnd; ++it)
03852         if ((*it).startsWith(TQString::fromLatin1("subject=")))
03853           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
03854         else if ((*it).startsWith(TQString::fromLatin1("cc=")))
03855           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
03856         else if ((*it).startsWith(TQString::fromLatin1("bcc=")))
03857           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
03858       mailtoMsg = TQStyleSheet::escape(mailtoMsg);
03859       mailtoMsg.replace(TQRegExp("([\n\r\t]|[ ]{10})"), TQString());
03860       setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
03861       return;
03862     }
03863    // Is this check necessary at all? (Frerich)
03864 #if 0
03865     else if (u.protocol() == TQString::fromLatin1("http")) {
03866         DOM::Node hrefNode = nodeUnderMouse().parentNode();
03867         while (hrefNode.nodeName().string() != TQString::fromLatin1("A") && !hrefNode.isNull())
03868           hrefNode = hrefNode.parentNode();
03869 
03870         if (!hrefNode.isNull()) {
03871           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
03872           if (!hreflangNode.isNull()) {
03873             TQString countryCode = hreflangNode.nodeValue().string().lower();
03874             // Map the language code to an appropriate country code.
03875             if (countryCode == TQString::fromLatin1("en"))
03876               countryCode = TQString::fromLatin1("gb");
03877             TQString flagImg = TQString::fromLatin1("<img src=%1>").arg(
03878                 locate("locale", TQString::fromLatin1("l10n/")
03879                 + countryCode
03880                 + TQString::fromLatin1("/flag.png")));
03881             emit setStatusBarText(flagImg + u.prettyURL() + extra);
03882           }
03883         }
03884       }
03885 #endif
03886     setStatusBarText(u.htmlURL() + extra, BarHoverText);
03887   }
03888 }
03889 
03890 //
03891 // This executes in the active part on a click or other url selection action in
03892 // that active part.
03893 //
03894 void KHTMLPart::urlSelected( const TQString &url, int button, int state, const TQString &_target, KParts::URLArgs args )
03895 {
03896   // The member var is so that slotRedirection still calls the virtual urlSelected
03897   // but is able to know if is opened a url. KDE4: just make urlSelected return a bool
03898   // and move the urlSelectedIntern code back here.
03899   d->m_urlSelectedOpenedURL = urlSelectedIntern( url, button, state, _target, args );
03900 }
03901 
03902 // Return value: true if an url was opened, false if not (e.g. error, or jumping to anchor)
03903 bool KHTMLPart::urlSelectedIntern( const TQString &url, int button, int state, const TQString &_target, KParts::URLArgs args )
03904 {
03905   bool hasTarget = false;
03906 
03907   TQString target = _target;
03908   if ( target.isEmpty() && d->m_doc )
03909     target = d->m_doc->baseTarget();
03910   if ( !target.isEmpty() )
03911       hasTarget = true;
03912 
03913   if ( url.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 )
03914   {
03915     crossFrameExecuteScript( target, KURL::decode_string( url.mid( 11 ) ) );
03916     return false;
03917   }
03918 
03919   KURL cURL = completeURL(url);
03920   // special case for <a href="">  (IE removes filename, mozilla doesn't)
03921   if ( url.isEmpty() )
03922     cURL.setFileName( url ); // removes filename
03923 
03924   if ( !cURL.isValid() )
03925     // ### ERROR HANDLING
03926     return false;
03927 
03928   kdDebug(6050) << this << " urlSelected: complete URL:" << cURL.url() << " target=" << target << endl;
03929 
03930   if ( state & ControlButton )
03931   {
03932     args.setNewTab(true);
03933     emit d->m_extension->createNewWindow( cURL, args );
03934     return true;
03935   }
03936 
03937   if ( button == Qt::LeftButton && ( state & ShiftButton ) )
03938   {
03939     KIO::MetaData metaData;
03940     metaData["referrer"] = d->m_referrer;
03941     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), cURL, metaData );
03942     return false;
03943   }
03944 
03945   if (!checkLinkSecurity(cURL,
03946              i18n( "<qt>This untrusted page links to<BR><B>%1</B>.<BR>Do you want to follow the link?" ),
03947              i18n( "Follow" )))
03948     return false;
03949 
03950   args.frameName = target;
03951 
03952   args.metaData().insert("main_frame_request",
03953                          parentPart() == 0 ? "TRUE":"FALSE");
03954   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
03955   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
03956   args.metaData().insert("PropagateHttpHeader", "true");
03957   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
03958   args.metaData().insert("ssl_activate_warnings", "TRUE");
03959 
03960   if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" )
03961   {
03962     // unknown frame names should open in a new window.
03963     khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
03964     if ( frame )
03965     {
03966       args.metaData()["referrer"] = d->m_referrer;
03967       requestObject( frame, cURL, args );
03968       return true;
03969     }
03970   }
03971 
03972   if (!d->m_referrer.isEmpty() && !args.metaData().contains("referrer"))
03973     args.metaData()["referrer"] = d->m_referrer;
03974 
03975 
03976   if ( button == Qt::NoButton && (state & ShiftButton) && (state & ControlButton) )
03977   {
03978     emit d->m_extension->createNewWindow( cURL, args );
03979     return true;
03980   }
03981 
03982   if ( state & ShiftButton)
03983   {
03984     KParts::WindowArgs winArgs;
03985     winArgs.lowerWindow = true;
03986     KParts::ReadOnlyPart *newPart = 0;
03987     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
03988     return true;
03989   }
03990 
03991   //If we're asked to open up an anchor in the current URL, in current window,
03992   //merely gotoanchor, and do not reload the new page. Note that this does
03993   //not apply if the URL is the same page, but without a ref
03994   if (cURL.hasRef() && (!hasTarget || target == "_self"))
03995   {
03996     KURL curUrl = this->url();
03997     if (urlcmp(cURL.url(), curUrl.url(),
03998               false,  // ignore trailing / diff, IE does, even if FFox doesn't
03999               true))  // don't care if the ref changes!
04000     {
04001       m_url = cURL;
04002       emit d->m_extension->openURLNotify();
04003       if ( !gotoAnchor( m_url.encodedHtmlRef()) )
04004         gotoAnchor( m_url.htmlRef() );
04005       emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
04006       return false; // we jumped, but we didn't open a URL
04007     }
04008   }
04009 
04010   if ( !d->m_bComplete && !hasTarget )
04011     closeURL();
04012 
04013   view()->viewport()->unsetCursor();
04014   emit d->m_extension->openURLRequest( cURL, args );
04015   return true;
04016 }
04017 
04018 void KHTMLPart::slotViewDocumentSource()
04019 {
04020   KURL url(m_url);
04021   bool isTempFile = false;
04022   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isComplete(d->m_cacheId))
04023   {
04024      KTempFile sourceFile(TQString(), defaultExtension());
04025      if (sourceFile.status() == 0)
04026      {
04027         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
04028         url = KURL();
04029         url.setPath(sourceFile.name());
04030         isTempFile = true;
04031      }
04032   }
04033 
04034   (void) KRun::runURL( url, TQString::fromLatin1("text/plain"), isTempFile );
04035 }
04036 
04037 void KHTMLPart::slotViewPageInfo()
04038 {
04039   KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, (WFlags)WDestructiveClose);
04040   dlg->_close->setGuiItem(KStdGuiItem::close());
04041 
04042   if (d->m_doc)
04043      dlg->_title->setText(d->m_doc->title().string());
04044 
04045   // If it's a frame, set the caption to "Frame Information"
04046   if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
04047      dlg->setCaption(i18n("Frame Information"));
04048   }
04049 
04050   TQString editStr = TQString();
04051 
04052   if (!d->m_pageServices.isEmpty())
04053     editStr = i18n("   <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);
04054 
04055   TQString squeezedURL = KStringHandler::csqueeze( url().prettyURL(), 80 );
04056   dlg->_url->setText("<a href=\"" + url().url() + "\">" + squeezedURL + "</a>" + editStr);
04057   if (lastModified().isEmpty())
04058   {
04059     dlg->_lastModified->hide();
04060     dlg->_lmLabel->hide();
04061   }
04062   else
04063     dlg->_lastModified->setText(lastModified());
04064 
04065   const TQString& enc = encoding();
04066   if (enc.isEmpty()) {
04067     dlg->_eLabel->hide();
04068     dlg->_encoding->hide();
04069   } else {
04070     dlg->_encoding->setText(enc);
04071   }
04072   /* populate the list view now */
04073   const TQStringList headers = TQStringList::split("\n", d->m_httpHeaders);
04074 
04075   TQStringList::ConstIterator it = headers.begin();
04076   const TQStringList::ConstIterator itEnd = headers.end();
04077 
04078   for (; it != itEnd; ++it) {
04079     const TQStringList header = TQStringList::split(TQRegExp(":[ ]+"), *it);
04080     if (header.count() != 2)
04081        continue;
04082     new TQListViewItem(dlg->_headers, header[0], header[1]);
04083   }
04084 
04085   dlg->show();
04086   /* put no code here */
04087 }
04088 
04089 
04090 void KHTMLPart::slotViewFrameSource()
04091 {
04092   KParts::ReadOnlyPart *frame = currentFrame();
04093   if ( !frame )
04094     return;
04095 
04096   KURL url = frame->url();
04097   bool isTempFile = false;
04098   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
04099   {
04100        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
04101 
04102        if (KHTMLPageCache::self()->isComplete(cacheId))
04103        {
04104            KTempFile sourceFile(TQString(), defaultExtension());
04105            if (sourceFile.status() == 0)
04106            {
04107                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
04108                url = KURL();
04109                url.setPath(sourceFile.name());
04110                isTempFile = true;
04111            }
04112      }
04113   }
04114 
04115   (void) KRun::runURL( url, TQString::fromLatin1("text/plain"), isTempFile );
04116 }
04117 
04118 KURL KHTMLPart::backgroundURL() const
04119 {
04120   // ### what about XML documents? get from CSS?
04121   if (!d->m_doc || !d->m_doc->isHTMLDocument())
04122     return KURL();
04123 
04124   TQString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
04125 
04126   return KURL( m_url, relURL );
04127 }
04128 
04129 void KHTMLPart::slotSaveBackground()
04130 {
04131   KIO::MetaData metaData;
04132   metaData["referrer"] = d->m_referrer;
04133   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save Background Image As"), backgroundURL(), metaData );
04134 }
04135 
04136 void KHTMLPart::slotSaveDocument()
04137 {
04138   KURL srcURL( m_url );
04139 
04140   if ( srcURL.fileName(false).isEmpty() )
04141     srcURL.setFileName( "index" + defaultExtension() );
04142 
04143   KIO::MetaData metaData;
04144   // Referre unknown?
04145   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, "text/html", d->m_cacheId );
04146 }
04147 
04148 void KHTMLPart::slotSecurity()
04149 {
04150 //   kdDebug( 6050 ) << "Meta Data:" << endl
04151 //                   << d->m_ssl_peer_cert_subject
04152 //                   << endl
04153 //                   << d->m_ssl_peer_cert_issuer
04154 //                   << endl
04155 //                   << d->m_ssl_cipher
04156 //                   << endl
04157 //                   << d->m_ssl_cipher_desc
04158 //                   << endl
04159 //                   << d->m_ssl_cipher_version
04160 //                   << endl
04161 //                   << d->m_ssl_good_from
04162 //                   << endl
04163 //                   << d->m_ssl_good_until
04164 //                   << endl
04165 //                   << d->m_ssl_cert_state
04166 //                   << endl;
04167 
04168   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
04169 
04170   if (d->m_bSecurityInQuestion)
04171       kid->setSecurityInQuestion(true);
04172 
04173   if (d->m_ssl_in_use) {
04174     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
04175     if (x) {
04176        // Set the chain back onto the certificate
04177        const TQStringList cl = TQStringList::split(TQString("\n"), d->m_ssl_peer_chain);
04178        TQPtrList<KSSLCertificate> ncl;
04179 
04180        ncl.setAutoDelete(true);
04181        TQStringList::ConstIterator it = cl.begin();
04182        const TQStringList::ConstIterator itEnd = cl.end();
04183        for (; it != itEnd; ++it) {
04184           KSSLCertificate* const y = KSSLCertificate::fromString((*it).local8Bit());
04185           if (y) ncl.append(y);
04186        }
04187 
04188        if (ncl.count() > 0)
04189           x->chain().setChain(ncl);
04190 
04191        kid->setup(x,
04192                   d->m_ssl_peer_ip,
04193                   m_url.url(),
04194                   d->m_ssl_cipher,
04195                   d->m_ssl_cipher_desc,
04196                   d->m_ssl_cipher_version,
04197                   d->m_ssl_cipher_used_bits.toInt(),
04198                   d->m_ssl_cipher_bits.toInt(),
04199                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
04200                   );
04201         kid->exec();
04202         delete x;
04203      } else kid->exec();
04204   } else kid->exec();
04205 }
04206 
04207 void KHTMLPart::slotSaveFrame()
04208 {
04209     KParts::ReadOnlyPart *frame = currentFrame();
04210     if ( !frame )
04211         return;
04212 
04213     KURL srcURL( frame->url() );
04214 
04215     if ( srcURL.fileName(false).isEmpty() )
04216         srcURL.setFileName( "index" + defaultExtension() );
04217 
04218     KIO::MetaData metaData;
04219     // Referrer unknown?
04220     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save Frame As" ), srcURL, metaData, "text/html" );
04221 }
04222 
04223 void KHTMLPart::slotSetEncoding()
04224 {
04225   d->m_automaticDetection->setItemChecked( int( d->m_autoDetectLanguage ), false );
04226   d->m_paSetEncoding->popupMenu()->setItemChecked( 0, false );
04227   d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), true );
04228 
04229   TQString enc = KGlobal::charsets()->encodingForName( d->m_manualDetection->currentText() );
04230   setEncoding( enc, true );
04231 }
04232 
04233 void KHTMLPart::slotUseStylesheet()
04234 {
04235   if (d->m_doc)
04236   {
04237     bool autoselect = (d->m_paUseStylesheet->currentItem() == 0);
04238     d->m_sheetUsed = autoselect ? TQString() : d->m_paUseStylesheet->currentText();
04239     d->m_doc->updateStyleSelector();
04240   }
04241 }
04242 
04243 void KHTMLPart::updateActions()
04244 {
04245   bool frames = false;
04246 
04247   TQValueList<khtml::ChildFrame*>::ConstIterator it = d->m_frames.begin();
04248   const TQValueList<khtml::ChildFrame*>::ConstIterator end = d->m_frames.end();
04249   for (; it != end; ++it )
04250       if ( (*it)->m_type == khtml::ChildFrame::Frame )
04251       {
04252           frames = true;
04253           break;
04254       }
04255 
04256   d->m_paViewFrame->setEnabled( frames );
04257   d->m_paSaveFrame->setEnabled( frames );
04258 
04259   if ( frames )
04260     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
04261   else
04262     d->m_paFind->setText( i18n( "&Find..." ) );
04263 
04264   KParts::Part *frame = 0;
04265 
04266   if ( frames )
04267     frame = currentFrame();
04268 
04269   bool enableFindAndSelectAll = true;
04270 
04271   if ( frame )
04272     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
04273 
04274   d->m_paFind->setEnabled( enableFindAndSelectAll );
04275   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
04276 
04277   bool enablePrintFrame = false;
04278 
04279   if ( frame )
04280   {
04281     TQObject *ext = KParts::BrowserExtension::childObject( frame );
04282     if ( ext )
04283       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
04284   }
04285 
04286   d->m_paPrintFrame->setEnabled( enablePrintFrame );
04287 
04288   TQString bgURL;
04289 
04290   // ### frames
04291   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
04292     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
04293 
04294   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
04295 
04296   if ( d->m_paDebugScript )
04297     d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
04298 }
04299 
04300 KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
04301     const ConstFrameIt end = d->m_objects.end();
04302     for(ConstFrameIt it = d->m_objects.begin(); it != end; ++it )
04303         if ((*it)->m_frame == frame)
04304             return (*it)->m_liveconnect;
04305     return 0L;
04306 }
04307 
04308 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const TQString &url, const TQString &frameName,
04309                               const TQStringList &params, bool isIFrame )
04310 {
04311   //kdDebug( 6050 ) << this << " requestFrame( ..., " << url << ", " << frameName << " )" << endl;
04312   FrameIt it = d->m_frames.find( frameName );
04313   if ( it == d->m_frames.end() )
04314   {
04315     khtml::ChildFrame * child = new khtml::ChildFrame;
04316     //kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
04317     child->m_name = frameName;
04318     it = d->m_frames.append( child );
04319   }
04320 
04321   (*it)->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
04322   (*it)->m_frame = frame;
04323   (*it)->m_params = params;
04324 
04325   // Support for <frame src="javascript:string">
04326   if ( url.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 )
04327   {
04328     if ( processObjectRequest(*it, KURL("about:blank"), TQString("text/html") ) ) {
04329       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>((*it)->m_part));
04330 
04331       // See if we want to replace content with javascript: output..
04332       TQVariant res = p->executeScript( DOM::Node(), KURL::decode_string( url.right( url.length() - 11) ) );
04333       if ( res.type() == TQVariant::String ) {
04334         p->begin();
04335         p->write( res.asString() );
04336         p->end();
04337       }
04338       return true;
04339     }
04340     return false;
04341   }
04342   KURL u = url.isEmpty() ? KURL() : completeURL( url );
04343   return requestObject( *it, u );
04344 }
04345 
04346 TQString KHTMLPart::requestFrameName()
04347 {
04348    return TQString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
04349 }
04350 
04351 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const TQString &url, const TQString &serviceType,
04352                                const TQStringList &params )
04353 {
04354   //kdDebug( 6005 ) << "KHTMLPart::requestObject " << this << " frame=" << frame << endl;
04355   khtml::ChildFrame *child = new khtml::ChildFrame;
04356   FrameIt it = d->m_objects.append( child );
04357   (*it)->m_frame = frame;
04358   (*it)->m_type = khtml::ChildFrame::Object;
04359   (*it)->m_params = params;
04360 
04361   KParts::URLArgs args;
04362   args.serviceType = serviceType;
04363   if (!requestObject( *it, completeURL( url ), args ) && !(*it)->m_run) {
04364       (*it)->m_bCompleted = true;
04365       return false;
04366   }
04367   return true;
04368 }
04369 
04370 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
04371 {
04372   if (!checkLinkSecurity(url))
04373   {
04374     kdDebug(6005) << this << " KHTMLPart::requestObject checkLinkSecurity refused" << endl;
04375     return false;
04376   }
04377   if ( child->m_bPreloaded )
04378   {
04379     kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
04380     if ( child->m_frame && child->m_part )
04381       child->m_frame->setWidget( child->m_part->widget() );
04382 
04383     child->m_bPreloaded = false;
04384     return true;
04385   }
04386 
04387   //kdDebug(6005) << "KHTMLPart::requestObject child=" << child << " child->m_part=" << child->m_part << endl;
04388 
04389   KParts::URLArgs args( _args );
04390 
04391   if ( child->m_run )
04392     child->m_run->abort();
04393 
04394   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
04395     args.serviceType = child->m_serviceType;
04396 
04397   child->m_args = args;
04398   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04399   child->m_serviceName = TQString();
04400   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
04401     child->m_args.metaData()["referrer"] = d->m_referrer;
04402 
04403   child->m_args.metaData().insert("PropagateHttpHeader", "true");
04404   child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04405   child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04406   child->m_args.metaData().insert("main_frame_request",
04407                                   parentPart() == 0 ? "TRUE":"FALSE");
04408   child->m_args.metaData().insert("ssl_was_in_use",
04409                                   d->m_ssl_in_use ? "TRUE":"FALSE");
04410   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
04411   child->m_args.metaData().insert("cross-domain", toplevelURL().url());
04412 
04413   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
04414   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
04415     args.serviceType = TQString::fromLatin1( "text/html" );
04416 
04417   if ( args.serviceType.isEmpty() ) {
04418     kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << endl;
04419     child->m_run = new KHTMLRun( this, child, url, child->m_args, true );
04420     d->m_bComplete = false; // ensures we stop it in checkCompleted...
04421     return false;
04422   } else {
04423     return processObjectRequest( child, url, args.serviceType );
04424   }
04425 }
04426 
04427 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const TQString &mimetype )
04428 {
04429   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
04430 
04431   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
04432   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
04433   // though -> the reference becomes invalid -> crash is likely
04434   KURL url( _url );
04435 
04436   // khtmlrun called us this way to indicate a loading error
04437   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
04438   {
04439       child->m_bCompleted = true;
04440       checkCompleted();
04441       return true;
04442   }
04443 
04444   if (child->m_bNotify)
04445   {
04446       child->m_bNotify = false;
04447       if ( !child->m_args.lockHistory() )
04448           emit d->m_extension->openURLNotify();
04449   }
04450 
04451   if ( child->m_serviceType != mimetype || !child->m_part )
04452   {
04453     // Before attempting to load a part, check if the user wants that.
04454     // Many don't like getting ZIP files embedded.
04455     // However we don't want to ask for flash and other plugin things..
04456     if ( child->m_type != khtml::ChildFrame::Object )
04457     {
04458       TQString suggestedFilename;
04459       if ( child->m_run )
04460         suggestedFilename = child->m_run->suggestedFilename();
04461 
04462       KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave(
04463         url, mimetype, suggestedFilename  );
04464       switch( res ) {
04465       case KParts::BrowserRun::Save:
04466         KHTMLPopupGUIClient::saveURL( widget(), i18n( "Save As" ), url, child->m_args.metaData(), TQString(), 0, suggestedFilename);
04467         // fall-through
04468       case KParts::BrowserRun::Cancel:
04469         child->m_bCompleted = true;
04470         checkCompleted();
04471         return true; // done
04472       default: // Open
04473         break;
04474       }
04475     }
04476 
04477     TQStringList dummy; // the list of servicetypes handled by the part is now unused.
04478     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 );
04479 
04480     if ( !part )
04481     {
04482         if ( child->m_frame )
04483           if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
04484             return true; // we succeeded after all (a fallback was used)
04485 
04486         checkEmitLoadEvent();
04487         return false;
04488     }
04489 
04490     //CRITICAL STUFF
04491     if ( child->m_part )
04492     {
04493       if (!::tqqt_cast<KHTMLPart*>(child->m_part) && child->m_jscript)
04494           child->m_jscript->clear();
04495       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
04496       delete (KParts::ReadOnlyPart *)child->m_part;
04497       if (child->m_liveconnect) {
04498         disconnect(child->m_liveconnect, TQT_SIGNAL(partEvent(const unsigned long, const TQString &, const KParts::LiveConnectExtension::ArgList &)), child, TQT_SLOT(liveConnectEvent(const unsigned long, const TQString&, const KParts::LiveConnectExtension::ArgList &)));
04499         child->m_liveconnect = 0L;
04500       }
04501     }
04502 
04503     child->m_serviceType = mimetype;
04504     if ( child->m_frame  && part->widget() )
04505       child->m_frame->setWidget( part->widget() );
04506 
04507     if ( child->m_type != khtml::ChildFrame::Object )
04508       partManager()->addPart( part, false );
04509 //  else
04510 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
04511 
04512     child->m_part = part;
04513 
04514     if (::tqqt_cast<KHTMLPart*>(part)) {
04515       static_cast<KHTMLPart*>(part)->d->m_frame = child;
04516     } else if (child->m_frame) {
04517       child->m_liveconnect = KParts::LiveConnectExtension::childObject(part);
04518       if (child->m_liveconnect)
04519         connect(child->m_liveconnect, TQT_SIGNAL(partEvent(const unsigned long, const TQString &, const KParts::LiveConnectExtension::ArgList &)), child, TQT_SLOT(liveConnectEvent(const unsigned long, const TQString&, const KParts::LiveConnectExtension::ArgList &)));
04520     }
04521     KParts::StatusBarExtension *sb = KParts::StatusBarExtension::childObject(part);
04522     if (sb)
04523       sb->setStatusBar( d->m_statusBarExtension->statusBar() );
04524 
04525     connect( part, TQT_SIGNAL( started( KIO::Job *) ),
04526              this, TQT_SLOT( slotChildStarted( KIO::Job *) ) );
04527     connect( part, TQT_SIGNAL( completed() ),
04528              this, TQT_SLOT( slotChildCompleted() ) );
04529     connect( part, TQT_SIGNAL( completed(bool) ),
04530              this, TQT_SLOT( slotChildCompleted(bool) ) );
04531     connect( part, TQT_SIGNAL( setStatusBarText( const TQString & ) ),
04532                 this, TQT_SIGNAL( setStatusBarText( const TQString & ) ) );
04533     if ( part->inherits( "KHTMLPart" ) )
04534     {
04535       connect( this, TQT_SIGNAL( completed() ),
04536                part, TQT_SLOT( slotParentCompleted() ) );
04537       connect( this, TQT_SIGNAL( completed(bool) ),
04538                part, TQT_SLOT( slotParentCompleted() ) );
04539       // As soon as the child's document is created, we need to set its domain
04540       // (but we do so only once, so it can't be simply done in the child)
04541       connect( part, TQT_SIGNAL( docCreated() ),
04542                this, TQT_SLOT( slotChildDocCreated() ) );
04543     }
04544 
04545     child->m_extension = KParts::BrowserExtension::childObject( part );
04546 
04547     if ( child->m_extension )
04548     {
04549       connect( child->m_extension, TQT_SIGNAL( openURLNotify() ),
04550                d->m_extension, TQT_SIGNAL( openURLNotify() ) );
04551 
04552       connect( child->m_extension, TQT_SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
04553                this, TQT_SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
04554 
04555       connect( child->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
04556                d->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
04557       connect( child->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
04558                d->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
04559 
04560       connect( child->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KFileItemList & ) ),
04561                d->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KFileItemList & ) ) );
04562       connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList & ) ),
04563                d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList & ) ) );
04564       connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ),
04565                d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) );
04566       connect( child->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KURL &, const TQString &, mode_t ) ),
04567                d->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KURL &, const TQString &, mode_t ) ) );
04568       connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const TQString &, mode_t ) ),
04569                d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const TQString &, mode_t ) ) );
04570       connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ),
04571                d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) );
04572 
04573       connect( child->m_extension, TQT_SIGNAL( infoMessage( const TQString & ) ),
04574                d->m_extension, TQT_SIGNAL( infoMessage( const TQString & ) ) );
04575 
04576       connect( child->m_extension, TQT_SIGNAL( requestFocus( KParts::ReadOnlyPart * ) ),
04577                this, TQT_SLOT( slotRequestFocus( KParts::ReadOnlyPart * ) ) );
04578 
04579       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
04580     }
04581   }
04582   else if ( child->m_frame && child->m_part &&
04583             child->m_frame->widget() != child->m_part->widget() )
04584     child->m_frame->setWidget( child->m_part->widget() );
04585 
04586   checkEmitLoadEvent();
04587   // Some JS code in the load event may have destroyed the part
04588   // In that case, abort
04589   if ( !child->m_part )
04590     return false;
04591 
04592   if ( child->m_bPreloaded )
04593   {
04594     if ( child->m_frame && child->m_part )
04595       child->m_frame->setWidget( child->m_part->widget() );
04596 
04597     child->m_bPreloaded = false;
04598     return true;
04599   }
04600 
04601   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04602 
04603   // make sure the part has a way to find out about the mimetype.
04604   // we actually set it in child->m_args in requestObject already,
04605   // but it's useless if we had to use a KHTMLRun instance, as the
04606   // point the run object is to find out exactly the mimetype.
04607   child->m_args.serviceType = mimetype;
04608 
04609   // if not a frame set child as completed
04610   child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;
04611 
04612   if ( child->m_extension )
04613     child->m_extension->setURLArgs( child->m_args );
04614 
04615   if(url.protocol() == "javascript" || url.url() == "about:blank") {
04616       if (!child->m_part->inherits("KHTMLPart"))
04617           return false;
04618 
04619       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
04620 
04621       p->begin();
04622       if (d->m_doc && p->d->m_doc)
04623         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
04624       if (!url.url().startsWith("about:")) {
04625         p->write(url.path());
04626       } else {
04627     p->m_url = url;
04628         // we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
04629         p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
04630       }
04631       p->end();
04632       return true;
04633   }
04634   else if ( !url.isEmpty() )
04635   {
04636       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
04637       bool b = child->m_part->openURL( url );
04638       if (child->m_bCompleted)
04639           checkCompleted();
04640       return b;
04641   }
04642   else
04643   {
04644       child->m_bCompleted = true;
04645       checkCompleted();
04646       return true;
04647   }
04648 }
04649 
04650 KParts::ReadOnlyPart *KHTMLPart::createPart( TQWidget *parentWidget, const char *widgetName,
04651                                              TQObject *parent, const char *name, const TQString &mimetype,
04652                                              TQString &serviceName, TQStringList &serviceTypes,
04653                                              const TQStringList &params )
04654 {
04655   TQString constr;
04656   if ( !serviceName.isEmpty() )
04657     constr.append( TQString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
04658 
04659   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, TQString() );
04660 
04661   if ( offers.isEmpty() ) {
04662     int pos = mimetype.find( "-plugin" );
04663     if (pos < 0)
04664         return 0L;
04665     TQString stripped_mime = mimetype.left( pos );
04666     offers = KTrader::self()->query( stripped_mime, "KParts/ReadOnlyPart", constr, TQString() );
04667     if ( offers.isEmpty() )
04668         return 0L;
04669   }
04670 
04671   KTrader::OfferList::ConstIterator it = offers.begin();
04672   const KTrader::OfferList::ConstIterator itEnd = offers.end();
04673   for ( ; it != itEnd; ++it )
04674   {
04675     KService::Ptr service = (*it);
04676 
04677     KLibFactory* const factory = KLibLoader::self()->factory( TQFile::encodeName(service->library()) );
04678     if ( factory ) {
04679       KParts::ReadOnlyPart *res = 0L;
04680 
04681       const char *className = "KParts::ReadOnlyPart";
04682       if ( service->serviceTypes().contains( "Browser/View" ) )
04683         className = "Browser/View";
04684 
04685       if ( factory->inherits( "KParts::Factory" ) )
04686         res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
04687       else
04688         res = static_cast<KParts::ReadOnlyPart *>(factory->create( TQT_TQOBJECT(parentWidget), widgetName, className ));
04689 
04690       if ( res ) {
04691         serviceTypes = service->serviceTypes();
04692         serviceName = service->name();
04693         return res;
04694       }
04695     } else {
04696       // TODO KMessageBox::error and i18n, like in KonqFactory::createView?
04697       kdWarning() << TQString(TQString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
04698                       .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage())) << endl;
04699     }
04700   }
04701   return 0;
04702 }
04703 
04704 KParts::PartManager *KHTMLPart::partManager()
04705 {
04706   if ( !d->m_manager && d->m_view )
04707   {
04708     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
04709     d->m_manager->setAllowNestedParts( true );
04710     connect( d->m_manager, TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
04711              this, TQT_SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
04712     connect( d->m_manager, TQT_SIGNAL( partRemoved( KParts::Part * ) ),
04713              this, TQT_SLOT( slotPartRemoved( KParts::Part * ) ) );
04714   }
04715 
04716   return d->m_manager;
04717 }
04718 
04719 void KHTMLPart::submitFormAgain()
04720 {
04721   disconnect(this, TQT_SIGNAL(completed()), this, TQT_SLOT(submitFormAgain()));
04722   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
04723     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 );
04724 
04725   delete d->m_submitForm;
04726   d->m_submitForm = 0;
04727 }
04728 
04729 void KHTMLPart::submitFormProxy( const char *action, const TQString &url, const TQByteArray &formData, const TQString &_target, const TQString& contentType, const TQString& boundary )
04730 {
04731   submitForm(action, url, formData, _target, contentType, boundary);
04732 }
04733 
04734 void KHTMLPart::submitForm( const char *action, const TQString &url, const TQByteArray &formData, const TQString &_target, const TQString& contentType, const TQString& boundary )
04735 {
04736   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
04737   if (d->m_formNotification == KHTMLPart::Only) {
04738     emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04739     return;
04740   } else if (d->m_formNotification == KHTMLPart::Before) {
04741     emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04742   }
04743 
04744   KURL u = completeURL( url );
04745 
04746   if ( !u.isValid() )
04747   {
04748     // ### ERROR HANDLING!
04749     return;
04750   }
04751 
04752   // Form security checks
04753   //
04754   /*
04755    * If these form security checks are still in this place in a month or two
04756    * I'm going to simply delete them.
04757    */
04758 
04759   /* This is separate for a reason.  It has to be _before_ all script, etc,
04760    * AND I don't want to break anything that uses checkLinkSecurity() in
04761    * other places.
04762    */
04763 
04764   if (!d->m_submitForm) {
04765     if (u.protocol() != "https" && u.protocol() != "mailto") {
04766       if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
04767         int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
04768                                                                "\nA third party may be able to intercept and view this information."
04769                                                                "\nAre you sure you wish to continue?"),
04770                                                     i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
04771         if (rc == KMessageBox::Cancel)
04772           return;
04773       } else {                  // Going from nonSSL -> nonSSL
04774         KSSLSettings kss(true);
04775         if (kss.warnOnUnencrypted()) {
04776           int rc = KMessageBox::warningContinueCancel(NULL,
04777                                                       i18n("Warning: Your data is about to be transmitted across the network unencrypted."
04778                                                            "\nAre you sure you wish to continue?"),
04779                                                       i18n("Network Transmission"),
04780                                                       KGuiItem(i18n("&Send Unencrypted")),
04781                                                       "WarnOnUnencryptedForm");
04782           // Move this setting into KSSL instead
04783           KConfig *config = kapp->config();
04784           TQString grpNotifMsgs = TQString::fromLatin1("Notification Messages");
04785           KConfigGroupSaver saver( config, grpNotifMsgs );
04786 
04787           if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
04788             config->deleteEntry("WarnOnUnencryptedForm");
04789             config->sync();
04790             kss.setWarnOnUnencrypted(false);
04791             kss.save();
04792           }
04793           if (rc == KMessageBox::Cancel)
04794             return;
04795         }
04796       }
04797     }
04798 
04799     if (u.protocol() == "mailto") {
04800       int rc = KMessageBox::warningContinueCancel(NULL,
04801                                                   i18n("This site is attempting to submit form data via email.\n"
04802                                                        "Do you want to continue?"),
04803                                                   i18n("Network Transmission"),
04804                                                   KGuiItem(i18n("&Send Email")),
04805                                                   "WarnTriedEmailSubmit");
04806 
04807       if (rc == KMessageBox::Cancel) {
04808         return;
04809       }
04810     }
04811   }
04812 
04813   // End form security checks
04814   //
04815 
04816   TQString urlstring = u.url();
04817 
04818   if ( urlstring.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04819     urlstring = KURL::decode_string(urlstring);
04820     crossFrameExecuteScript( _target, urlstring.right( urlstring.length() - 11) );
04821     return;
04822   }
04823 
04824   if (!checkLinkSecurity(u,
04825              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?" ),
04826              i18n( "Submit" )))
04827     return;
04828 
04829   KParts::URLArgs args;
04830 
04831   if (!d->m_referrer.isEmpty())
04832      args.metaData()["referrer"] = d->m_referrer;
04833 
04834   args.metaData().insert("PropagateHttpHeader", "true");
04835   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04836   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04837   args.metaData().insert("main_frame_request",
04838                          parentPart() == 0 ? "TRUE":"FALSE");
04839   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
04840   args.metaData().insert("ssl_activate_warnings", "TRUE");
04841 //WABA: When we post a form we should treat it as the main url
04842 //the request should never be considered cross-domain
04843 //args.metaData().insert("cross-domain", toplevelURL().url());
04844   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
04845 
04846   // Handle mailto: forms
04847   if (u.protocol() == "mailto") {
04848       // 1)  Check for attach= and strip it
04849       TQString q = u.query().mid(1);
04850       TQStringList nvps = TQStringList::split("&", q);
04851       bool triedToAttach = false;
04852 
04853       TQStringList::Iterator nvp = nvps.begin();
04854       const TQStringList::Iterator nvpEnd = nvps.end();
04855 
04856 // cannot be a for loop as if something is removed we don't want to do ++nvp, as
04857 // remove returns an iterator pointing to the next item
04858 
04859       while (nvp != nvpEnd) {
04860          const TQStringList pair = TQStringList::split("=", *nvp);
04861          if (pair.count() >= 2) {
04862             if (pair.first().lower() == "attach") {
04863                nvp = nvps.remove(nvp);
04864                triedToAttach = true;
04865             } else {
04866                ++nvp;
04867             }
04868          } else {
04869             ++nvp;
04870          }
04871       }
04872 
04873       if (triedToAttach)
04874          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");
04875 
04876       // 2)  Append body=
04877       TQString bodyEnc;
04878       if (contentType.lower() == "multipart/form-data") {
04879          // FIXME: is this correct?  I suspect not
04880          bodyEnc = KURL::encode_string(TQString::fromLatin1(formData.data(),
04881                                                            formData.size()));
04882       } else if (contentType.lower() == "text/plain") {
04883          // Convention seems to be to decode, and s/&/\n/
04884          TQString tmpbody = TQString::fromLatin1(formData.data(),
04885                                                formData.size());
04886          tmpbody.replace(TQRegExp("[&]"), "\n");
04887          tmpbody.replace(TQRegExp("[+]"), " ");
04888          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
04889          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
04890       } else {
04891          bodyEnc = KURL::encode_string(TQString::fromLatin1(formData.data(),
04892                                                            formData.size()));
04893       }
04894 
04895       nvps.append(TQString("body=%1").arg(bodyEnc));
04896       q = nvps.join("&");
04897       u.setQuery(q);
04898   }
04899 
04900   if ( strcmp( action, "get" ) == 0 ) {
04901     if (u.protocol() != "mailto")
04902        u.setQuery( TQString::fromLatin1( formData.data(), formData.size() ) );
04903     args.setDoPost( false );
04904   }
04905   else {
04906     args.postData = formData;
04907     args.setDoPost( true );
04908 
04909     // construct some user headers if necessary
04910     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
04911       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
04912     else // contentType must be "multipart/form-data"
04913       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
04914   }
04915 
04916   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
04917     if( d->m_submitForm ) {
04918       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
04919       return;
04920     }
04921     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
04922     d->m_submitForm->submitAction = action;
04923     d->m_submitForm->submitUrl = url;
04924     d->m_submitForm->submitFormData = formData;
04925     d->m_submitForm->target = _target;
04926     d->m_submitForm->submitContentType = contentType;
04927     d->m_submitForm->submitBoundary = boundary;
04928     connect(this, TQT_SIGNAL(completed()), this, TQT_SLOT(submitFormAgain()));
04929   }
04930   else
04931   {
04932     emit d->m_extension->openURLRequest( u, args );
04933   }
04934 }
04935 
04936 void KHTMLPart::popupMenu( const TQString &linkUrl )
04937 {
04938   KURL popupURL;
04939   KURL linkKURL;
04940   KParts::URLArgs args;
04941   TQString referrer;
04942   KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;
04943 
04944   if ( linkUrl.isEmpty() ) { // click on background
04945     KHTMLPart* khtmlPart = this;
04946     while ( khtmlPart->parentPart() )
04947     {
04948       khtmlPart=khtmlPart->parentPart();
04949     }
04950     popupURL = khtmlPart->url();
04951     referrer = khtmlPart->pageReferrer();
04952     if (hasSelection())
04953       itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
04954     else
04955       itemflags |= KParts::BrowserExtension::ShowNavigationItems;
04956   } else {               // click on link
04957     popupURL = completeURL( linkUrl );
04958     linkKURL = popupURL;
04959     referrer = this->referrer();
04960 
04961     if (!(d->m_strSelectedURLTarget).isEmpty() &&
04962            (d->m_strSelectedURLTarget.lower() != "_top") &&
04963            (d->m_strSelectedURLTarget.lower() != "_self") &&
04964        (d->m_strSelectedURLTarget.lower() != "_parent")) {
04965       if (d->m_strSelectedURLTarget.lower() == "_blank")
04966         args.setForcesNewWindow(true);
04967       else {
04968     KHTMLPart *p = this;
04969     while (p->parentPart())
04970       p = p->parentPart();
04971     if (!p->frameExists(d->m_strSelectedURLTarget))
04972           args.setForcesNewWindow(true);
04973       }
04974     }
04975   }
04976 
04977   // Danger, Will Robinson. The Popup might stay around for a much
04978   // longer time than KHTMLPart. Deal with it.
04979   KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
04980   TQGuardedPtr<TQObject> guard( client );
04981 
04982   TQString mimetype = TQString::fromLatin1( "text/html" );
04983   args.metaData()["referrer"] = referrer;
04984 
04985   if (!linkUrl.isEmpty())               // over a link
04986   {
04987     if (popupURL.isLocalFile())             // safe to do this
04988     {
04989       mimetype = KMimeType::findByURL(popupURL,0,true,false)->name();
04990     }
04991     else                        // look at "extension" of link
04992     {
04993       const TQString fname(popupURL.fileName(false));
04994       if (!fname.isEmpty() && !popupURL.hasRef() && popupURL.query().isEmpty())
04995       {
04996         KMimeType::Ptr pmt = KMimeType::findByPath(fname,0,true);
04997 
04998         // Further check for mime types guessed from the extension which,
04999         // on a web page, are more likely to be a script delivering content
05000         // of undecidable type. If the mime type from the extension is one
05001         // of these, don't use it.  Retain the original type 'text/html'.
05002         if (pmt->name() != KMimeType::defaultMimeType() &&
05003             !pmt->is("application/x-perl") &&
05004             !pmt->is("application/x-perl-module") &&
05005             !pmt->is("application/x-php") &&
05006             !pmt->is("application/x-python-bytecode") &&
05007             !pmt->is("application/x-python") &&
05008             !pmt->is("application/x-shellscript"))
05009           mimetype = pmt->name();
05010       }
05011     }
05012   }
05013 
05014   args.serviceType = mimetype;
05015 
05016   emit d->m_extension->popupMenu( client, TQCursor::pos(), popupURL, args, itemflags, S_IFREG /*always a file*/);
05017 
05018   if ( !guard.isNull() ) {
05019      delete client;
05020      emit popupMenu(linkUrl, TQCursor::pos());
05021      d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
05022   }
05023 }
05024 
05025 void KHTMLPart::slotParentCompleted()
05026 {
05027   //kdDebug(6050) << this << " slotParentCompleted()" << endl;
05028   if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
05029   {
05030     //kdDebug(6050) << this << ": starting timer for child redirection -> " << d->m_redirectURL << endl;
05031     d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
05032   }
05033 }
05034 
05035 void KHTMLPart::slotChildStarted( KIO::Job *job )
05036 {
05037   khtml::ChildFrame *child = frame( TQT_TQOBJECT_CONST(sender()) );
05038 
05039   assert( child );
05040 
05041   child->m_bCompleted = false;
05042 
05043   if ( d->m_bComplete )
05044   {
05045 #if 0
05046     // WABA: Looks like this belongs somewhere else
05047     if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
05048     {
05049       emit d->m_extension->openURLNotify();
05050     }
05051 #endif
05052     d->m_bComplete = false;
05053     emit started( job );
05054   }
05055 }
05056 
05057 void KHTMLPart::slotChildCompleted()
05058 {
05059   slotChildCompleted( false );
05060 }
05061 
05062 void KHTMLPart::slotChildCompleted( bool pendingAction )
05063 {
05064   khtml::ChildFrame *child = frame( TQT_TQOBJECT_CONST(sender()) );
05065 
05066   if ( child ) {
05067     kdDebug(6050) << this << " slotChildCompleted child=" << child << " m_frame=" << child->m_frame << endl;
05068     child->m_bCompleted = true;
05069     child->m_bPendingRedirection = pendingAction;
05070     child->m_args = KParts::URLArgs();
05071   }
05072   checkCompleted();
05073 }
05074 
05075 void KHTMLPart::slotChildDocCreated()
05076 {
05077   const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
05078   // Set domain to the frameset's domain
05079   // This must only be done when loading the frameset initially (#22039),
05080   // not when following a link in a frame (#44162).
05081   if ( d->m_doc && d->m_doc->isHTMLDocument() )
05082   {
05083     if ( sender()->inherits("KHTMLPart") )
05084     {
05085       DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
05086       if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
05087         //kdDebug(6050) << "KHTMLPart::slotChildDocCreated: url: " << htmlFrame->m_url.url() << endl;
05088         static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
05089     }
05090   }
05091   // So it only happens once
05092   disconnect( htmlFrame, TQT_SIGNAL( docCreated() ), this, TQT_SLOT( slotChildDocCreated() ) );
05093 }
05094 
05095 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
05096 {
05097   khtml::ChildFrame *child = frame( TQT_TQOBJECT_CONST(sender())->parent() );
05098   KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
05099 
05100   // TODO: handle child target correctly! currently the script are always executed fur the parent
05101   TQString urlStr = url.url();
05102   if ( urlStr.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
05103       TQString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
05104       executeScript( DOM::Node(), script );
05105       return;
05106   }
05107 
05108   TQString frameName = args.frameName.lower();
05109   if ( !frameName.isEmpty() ) {
05110     if ( frameName == TQString::fromLatin1( "_top" ) )
05111     {
05112       emit d->m_extension->openURLRequest( url, args );
05113       return;
05114     }
05115     else if ( frameName == TQString::fromLatin1( "_blank" ) )
05116     {
05117       emit d->m_extension->createNewWindow( url, args );
05118       return;
05119     }
05120     else if ( frameName == TQString::fromLatin1( "_parent" ) )
05121     {
05122       KParts::URLArgs newArgs( args );
05123       newArgs.frameName = TQString();
05124 
05125       emit d->m_extension->openURLRequest( url, newArgs );
05126       return;
05127     }
05128     else if ( frameName != TQString::fromLatin1( "_self" ) )
05129     {
05130       khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
05131 
05132       if ( !_frame )
05133       {
05134         emit d->m_extension->openURLRequest( url, args );
05135         return;
05136       }
05137 
05138       child = _frame;
05139     }
05140   }
05141 
05142   if ( child && child->m_type != khtml::ChildFrame::Object ) {
05143       // Inform someone that we are about to show something else.
05144       child->m_bNotify = true;
05145       requestObject( child, url, args );
05146   }  else if ( frameName== "_self" ) // this is for embedded objects (via <object>) which want to replace the current document
05147   {
05148       KParts::URLArgs newArgs( args );
05149       newArgs.frameName = TQString();
05150       emit d->m_extension->openURLRequest( url, newArgs );
05151   }
05152 }
05153 
05154 void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
05155 {
05156   emit d->m_extension->requestFocus(this);
05157 }
05158 
05159 khtml::ChildFrame *KHTMLPart::frame( const TQObject *obj )
05160 {
05161     assert( obj->inherits( "KParts::ReadOnlyPart" ) );
05162     const KParts::ReadOnlyPart* const part = static_cast<const KParts::ReadOnlyPart *>( obj );
05163 
05164     FrameIt it = d->m_frames.begin();
05165     const FrameIt end = d->m_frames.end();
05166     for (; it != end; ++it )
05167       if ( (KParts::ReadOnlyPart *)(*it)->m_part == part )
05168         return *it;
05169 
05170     FrameIt oi = d->m_objects.begin();
05171     const FrameIt oiEnd = d->m_objects.end();
05172     for (; oi != oiEnd; ++oi )
05173       if ( (KParts::ReadOnlyPart *)(*oi)->m_part == part )
05174         return *oi;
05175 
05176     return 0L;
05177 }
05178 
05179 //#define DEBUG_FINDFRAME
05180 
05181 bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
05182 {
05183   if (callingHtmlPart == this)
05184     return true; // trivial
05185 
05186   if (htmlDocument().isNull()) {
05187 #ifdef DEBUG_FINDFRAME
05188     kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
05189 #endif
05190     return false; // we are empty?
05191   }
05192 
05193   // now compare the domains
05194   if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
05195       !htmlDocument().isNull())  {
05196     DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
05197     DOM::DOMString destDomain = htmlDocument().domain();
05198 
05199 #ifdef DEBUG_FINDFRAME
05200     kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
05201 #endif
05202 
05203     if (actDomain == destDomain)
05204       return true;
05205   }
05206 #ifdef DEBUG_FINDFRAME
05207   else
05208   {
05209     kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
05210   }
05211 #endif
05212   return false;
05213 }
05214 
05215 KHTMLPart *
05216 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const TQString &f, khtml::ChildFrame **childFrame )
05217 {
05218 #ifdef DEBUG_FINDFRAME
05219   kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " name = " << name() << " findFrameParent( " << f << " )" << endl;
05220 #endif
05221   // Check access
05222   KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
05223 
05224   if (!checkFrameAccess(callingHtmlPart))
05225      return 0;
05226 
05227   // match encoding used in KonqView::setViewName()
05228   if (!childFrame && !parentPart() && (TQString::fromLocal8Bit(name()) == f))
05229      return this;
05230 
05231   FrameIt it = d->m_frames.find( f );
05232   const FrameIt end = d->m_frames.end();
05233   if ( it != end )
05234   {
05235 #ifdef DEBUG_FINDFRAME
05236      kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
05237 #endif
05238      if (childFrame)
05239         *childFrame = *it;
05240      return this;
05241   }
05242 
05243   it = d->m_frames.begin();
05244   for (; it != end; ++it )
05245   {
05246     KParts::ReadOnlyPart* const p = (*it)->m_part;
05247     if ( p && p->inherits( "KHTMLPart" ))
05248     {
05249       KHTMLPart* const frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
05250       if (frameParent)
05251          return frameParent;
05252     }
05253   }
05254   return 0;
05255 }
05256 
05257 
05258 KHTMLPart *KHTMLPart::findFrame( const TQString &f )
05259 {
05260   khtml::ChildFrame *childFrame;
05261   KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
05262   if (parentFrame)
05263   {
05264      KParts::ReadOnlyPart *p = childFrame->m_part;
05265      if ( p && p->inherits( "KHTMLPart" ))
05266         return static_cast<KHTMLPart *>(p);
05267   }
05268   return 0;
05269 }
05270 
05271 KParts::ReadOnlyPart *KHTMLPart::findFramePart(const TQString &f)
05272 {
05273   khtml::ChildFrame *childFrame;
05274   return findFrameParent(this, f, &childFrame) ? static_cast<KParts::ReadOnlyPart *>(childFrame->m_part) : 0L;
05275 }
05276 
05277 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
05278 {
05279   KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
05280   // Find active part in our frame manager, in case we are a frameset
05281   // and keep doing that (in case of nested framesets).
05282   // Just realized we could also do this recursively, calling part->currentFrame()...
05283   while ( part && part->inherits("KHTMLPart") &&
05284           static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
05285     KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
05286     part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
05287     if ( !part ) return frameset;
05288   }
05289   return part;
05290 }
05291 
05292 bool KHTMLPart::frameExists( const TQString &frameName )
05293 {
05294   ConstFrameIt it = d->m_frames.find( frameName );
05295   if ( it == d->m_frames.end() )
05296     return false;
05297 
05298   // WABA: We only return true if the child actually has a frame
05299   // set. Otherwise we might find our preloaded-selve.
05300   // This happens when we restore the frameset.
05301   return (!(*it)->m_frame.isNull());
05302 }
05303 
05304 KJSProxy *KHTMLPart::framejScript(KParts::ReadOnlyPart *framePart)
05305 {
05306   KHTMLPart* const kp = ::tqqt_cast<KHTMLPart*>(framePart);
05307   if (kp)
05308     return kp->jScript();
05309 
05310   FrameIt it = d->m_frames.begin();
05311   const FrameIt itEnd = d->m_frames.end();
05312 
05313   for (; it != itEnd; ++it)
05314     if (framePart == (*it)->m_part) {
05315       if (!(*it)->m_jscript)
05316         createJScript(*it);
05317       return (*it)->m_jscript;
05318     }
05319   return 0L;
05320 }
05321 
05322 KHTMLPart *KHTMLPart::parentPart()
05323 {
05324   return ::tqqt_cast<KHTMLPart *>( parent() );
05325 }
05326 
05327 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
05328                                                      const KParts::URLArgs &args, bool callParent )
05329 {
05330 #ifdef DEBUG_FINDFRAME
05331   kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
05332 #endif
05333   khtml::ChildFrame *childFrame;
05334   KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
05335   if (childPart)
05336   {
05337      if (childPart == this)
05338         return childFrame;
05339 
05340      childPart->requestObject( childFrame, url, args );
05341      return 0;
05342   }
05343 
05344   if ( parentPart() && callParent )
05345   {
05346      khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
05347 
05348      if ( res )
05349        parentPart()->requestObject( res, url, args );
05350   }
05351 
05352   return 0L;
05353 }
05354 
05355 #ifndef NDEBUG
05356 static int s_saveStateIndentLevel = 0;
05357 #endif
05358 
05359 void KHTMLPart::saveState( TQDataStream &stream )
05360 {
05361 #ifndef NDEBUG
05362   TQString indent = TQString().leftJustify( s_saveStateIndentLevel * 4, ' ' );
05363   const int indentLevel = s_saveStateIndentLevel++;
05364   kdDebug( 6050 ) << indent << "saveState this=" << this << " '" << name() << "' saving URL " << m_url.url() << endl;
05365 #endif
05366 
05367   stream << m_url << (TQ_INT32)d->m_view->contentsX() << (TQ_INT32)d->m_view->contentsY()
05368          << (TQ_INT32) d->m_view->contentsWidth() << (TQ_INT32) d->m_view->contentsHeight() << (TQ_INT32) d->m_view->marginWidth() << (TQ_INT32) d->m_view->marginHeight();
05369 
05370   // save link cursor position
05371   int focusNodeNumber;
05372   if (!d->m_focusNodeRestored)
05373       focusNodeNumber = d->m_focusNodeNumber;
05374   else if (d->m_doc && d->m_doc->focusNode())
05375       focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
05376   else
05377       focusNodeNumber = -1;
05378   stream << focusNodeNumber;
05379 
05380   // Save the doc's cache id.
05381   stream << d->m_cacheId;
05382 
05383   // Save the state of the document (Most notably the state of any forms)
05384   TQStringList docState;
05385   if (d->m_doc)
05386   {
05387      docState = d->m_doc->docState();
05388   }
05389   stream << d->m_encoding << d->m_sheetUsed << docState;
05390 
05391   stream << d->m_zoomFactor;
05392 
05393   stream << d->m_httpHeaders;
05394   stream << d->m_pageServices;
05395   stream << d->m_pageReferrer;
05396 
05397   // Save ssl data
05398   stream << d->m_ssl_in_use
05399          << d->m_ssl_peer_certificate
05400          << d->m_ssl_peer_chain
05401          << d->m_ssl_peer_ip
05402          << d->m_ssl_cipher
05403          << d->m_ssl_cipher_desc
05404          << d->m_ssl_cipher_version
05405          << d->m_ssl_cipher_used_bits
05406          << d->m_ssl_cipher_bits
05407          << d->m_ssl_cert_state
05408          << d->m_ssl_parent_ip
05409          << d->m_ssl_parent_cert;
05410 
05411 
05412   TQStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
05413   KURL::List frameURLLst;
05414   TQValueList<TQByteArray> frameStateBufferLst;
05415 
05416   ConstFrameIt it = d->m_frames.begin();
05417   const ConstFrameIt end = d->m_frames.end();
05418   for (; it != end; ++it )
05419   {
05420     if ( !(*it)->m_part )
05421        continue;
05422 
05423     frameNameLst << (*it)->m_name;
05424     frameServiceTypeLst << (*it)->m_serviceType;
05425     frameServiceNameLst << (*it)->m_serviceName;
05426     frameURLLst << (*it)->m_part->url();
05427 
05428     TQByteArray state;
05429     TQDataStream frameStream( state, IO_WriteOnly );
05430 
05431     if ( (*it)->m_extension )
05432       (*it)->m_extension->saveState( frameStream );
05433 
05434     frameStateBufferLst << state;
05435   }
05436 
05437   // Save frame data
05438   stream << (TQ_UINT32) frameNameLst.count();
05439   stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
05440 #ifndef NDEBUG
05441   s_saveStateIndentLevel = indentLevel;
05442 #endif
05443 }
05444 
05445 void KHTMLPart::restoreState( TQDataStream &stream )
05446 {
05447   KURL u;
05448   TQ_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
05449   TQ_UINT32 frameCount;
05450   TQStringList frameNames, frameServiceTypes, docState, frameServiceNames;
05451   KURL::List frameURLs;
05452   TQValueList<TQByteArray> frameStateBuffers;
05453   TQValueList<int> fSizes;
05454   TQString encoding, sheetUsed;
05455   long old_cacheId = d->m_cacheId;
05456 
05457   stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
05458 
05459   d->m_view->setMarginWidth( mWidth );
05460   d->m_view->setMarginHeight( mHeight );
05461 
05462   // restore link cursor position
05463   // nth node is active. value is set in checkCompleted()
05464   stream >> d->m_focusNodeNumber;
05465   d->m_focusNodeRestored = false;
05466 
05467   stream >> d->m_cacheId;
05468 
05469   stream >> encoding >> sheetUsed >> docState;
05470 
05471   d->m_encoding = encoding;
05472   d->m_sheetUsed = sheetUsed;
05473 
05474   int zoomFactor;
05475   stream >> zoomFactor;
05476   setZoomFactor(zoomFactor);
05477 
05478   stream >> d->m_httpHeaders;
05479   stream >> d->m_pageServices;
05480   stream >> d->m_pageReferrer;
05481 
05482   // Restore ssl data
05483   stream >> d->m_ssl_in_use
05484          >> d->m_ssl_peer_certificate
05485          >> d->m_ssl_peer_chain
05486          >> d->m_ssl_peer_ip
05487          >> d->m_ssl_cipher
05488          >> d->m_ssl_cipher_desc
05489          >> d->m_ssl_cipher_version
05490          >> d->m_ssl_cipher_used_bits
05491          >> d->m_ssl_cipher_bits
05492          >> d->m_ssl_cert_state
05493          >> d->m_ssl_parent_ip
05494          >> d->m_ssl_parent_cert;
05495 
05496   setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
05497 
05498   stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
05499          >> frameURLs >> frameStateBuffers;
05500 
05501   d->m_bComplete = false;
05502   d->m_bLoadEventEmitted = false;
05503 
05504 //   kdDebug( 6050 ) << "restoreState() docState.count() = " << docState.count() << endl;
05505 //   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
05506 //   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
05507 
05508   if (d->m_cacheId == old_cacheId)
05509   {
05510     // Partial restore
05511     d->m_redirectionTimer.stop();
05512 
05513     FrameIt fIt = d->m_frames.begin();
05514     const FrameIt fEnd = d->m_frames.end();
05515 
05516     for (; fIt != fEnd; ++fIt )
05517         (*fIt)->m_bCompleted = false;
05518 
05519     fIt = d->m_frames.begin();
05520 
05521     TQStringList::ConstIterator fNameIt = frameNames.begin();
05522     TQStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
05523     TQStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
05524     KURL::List::ConstIterator fURLIt = frameURLs.begin();
05525     TQValueList<TQByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
05526 
05527     for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
05528     {
05529       khtml::ChildFrame* const child = *fIt;
05530 
05531 //      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;
05532 
05533       if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
05534       {
05535         child->m_bPreloaded = true;
05536         child->m_name = *fNameIt;
05537         child->m_serviceName = *fServiceNameIt;
05538         processObjectRequest( child, *fURLIt, *fServiceTypeIt );
05539       }
05540       if ( child->m_part )
05541       {
05542         child->m_bCompleted = false;
05543         if ( child->m_extension && !(*fBufferIt).isEmpty() )
05544         {
05545           TQDataStream frameStream( *fBufferIt, IO_ReadOnly );
05546           child->m_extension->restoreState( frameStream );
05547         }
05548         else
05549           child->m_part->openURL( *fURLIt );
05550       }
05551     }
05552 
05553     KParts::URLArgs args( d->m_extension->urlArgs() );
05554     args.xOffset = xOffset;
05555     args.yOffset = yOffset;
05556     args.docState = docState;
05557     d->m_extension->setURLArgs( args );
05558 
05559     d->m_view->resizeContents( wContents,  hContents);
05560     d->m_view->setContentsPos( xOffset, yOffset );
05561 
05562     m_url = u;
05563   }
05564   else
05565   {
05566     // Full restore.
05567     closeURL();
05568     // We must force a clear because we want to be sure to delete all
05569     // frames.
05570     d->m_bCleared = false;
05571     clear();
05572     d->m_encoding = encoding;
05573     d->m_sheetUsed = sheetUsed;
05574 
05575     TQStringList::ConstIterator fNameIt = frameNames.begin();
05576     const TQStringList::ConstIterator fNameEnd = frameNames.end();
05577 
05578     TQStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
05579     TQStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
05580     KURL::List::ConstIterator fURLIt = frameURLs.begin();
05581     TQValueList<TQByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
05582 
05583     for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
05584     {
05585       khtml::ChildFrame* const newChild = new khtml::ChildFrame;
05586       newChild->m_bPreloaded = true;
05587       newChild->m_name = *fNameIt;
05588       newChild->m_serviceName = *fServiceNameIt;
05589 
05590 //      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
05591 
05592       const FrameIt childFrame = d->m_frames.append( newChild );
05593 
05594       processObjectRequest( *childFrame, *fURLIt, *fServiceTypeIt );
05595 
05596       (*childFrame)->m_bPreloaded = true;
05597 
05598       if ( (*childFrame)->m_part )
05599       {
05600         if ( (*childFrame)->m_extension ) {
05601           if ( (*childFrame)->m_extension && !(*fBufferIt).isEmpty() )
05602           {
05603             TQDataStream frameStream( *fBufferIt, IO_ReadOnly );
05604             (*childFrame)->m_extension->restoreState( frameStream );
05605           }
05606           else {
05607             (*childFrame)->m_part->openURL( *fURLIt );
05608           }
05609         }
05610       }
05611     }
05612 
05613     KParts::URLArgs args( d->m_extension->urlArgs() );
05614     args.xOffset = xOffset;
05615     args.yOffset = yOffset;
05616     args.docState = docState;
05617 
05618     d->m_extension->setURLArgs( args );
05619     if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
05620     {
05621        d->m_restored = true;
05622        openURL( u );
05623        d->m_restored = false;
05624     }
05625     else
05626     {
05627        restoreURL( u );
05628     }
05629   }
05630 
05631 }
05632 
05633 void KHTMLPart::show()
05634 {
05635   if ( d->m_view )
05636     d->m_view->show();
05637 }
05638 
05639 void KHTMLPart::hide()
05640 {
05641   if ( d->m_view )
05642     d->m_view->hide();
05643 }
05644 
05645 DOM::Node KHTMLPart::nodeUnderMouse() const
05646 {
05647     return d->m_view->nodeUnderMouse();
05648 }
05649 
05650 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
05651 {
05652     return d->m_view->nonSharedNodeUnderMouse();
05653 }
05654 
05655 void KHTMLPart::emitSelectionChanged()
05656 {
05657   emit d->m_extension->enableAction( "copy", hasSelection() );
05658   if ( d->m_findDialog )
05659        d->m_findDialog->setHasSelection( hasSelection() );
05660 
05661   emit d->m_extension->selectionInfo( selectedText() );
05662   emit selectionChanged();
05663 }
05664 
05665 int KHTMLPart::zoomFactor() const
05666 {
05667   return d->m_zoomFactor;
05668 }
05669 
05670 // ### make the list configurable ?
05671 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
05672 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
05673 static const int minZoom = 20;
05674 static const int maxZoom = 300;
05675 
05676 // My idea of useful stepping ;-) (LS)
05677 extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
05678 extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
05679 
05680 void KHTMLPart::slotIncZoom()
05681 {
05682   zoomIn(zoomSizes, zoomSizeCount);
05683 }
05684 
05685 void KHTMLPart::slotDecZoom()
05686 {
05687   zoomOut(zoomSizes, zoomSizeCount);
05688 }
05689 
05690 void KHTMLPart::slotIncZoomFast()
05691 {
05692   zoomIn(fastZoomSizes, fastZoomSizeCount);
05693 }
05694 
05695 void KHTMLPart::slotDecZoomFast()
05696 {
05697   zoomOut(fastZoomSizes, fastZoomSizeCount);
05698 }
05699 
05700 void KHTMLPart::zoomIn(const int stepping[], int count)
05701 {
05702   int zoomFactor = d->m_zoomFactor;
05703 
05704   if (zoomFactor < maxZoom) {
05705     // find the entry nearest to the given zoomsizes
05706     for (int i = 0; i < count; ++i)
05707       if (stepping[i] > zoomFactor) {
05708         zoomFactor = stepping[i];
05709         break;
05710       }
05711     setZoomFactor(zoomFactor);
05712   }
05713 }
05714 
05715 void KHTMLPart::zoomOut(const int stepping[], int count)
05716 {
05717     int zoomFactor = d->m_zoomFactor;
05718     if (zoomFactor > minZoom) {
05719       // find the entry nearest to the given zoomsizes
05720       for (int i = count-1; i >= 0; --i)
05721         if (stepping[i] < zoomFactor) {
05722           zoomFactor = stepping[i];
05723           break;
05724         }
05725       setZoomFactor(zoomFactor);
05726     }
05727 }
05728 
05729 void KHTMLPart::setZoomFactor (int percent)
05730 {
05731   if (percent < minZoom) percent = minZoom;
05732   if (percent > maxZoom) percent = maxZoom;
05733   if (d->m_zoomFactor == percent) return;
05734   d->m_zoomFactor = percent;
05735 
05736   if(d->m_doc) {
05737       TQApplication::setOverrideCursor( tqwaitCursor );
05738     if (d->m_doc->styleSelector())
05739       d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
05740     d->m_doc->recalcStyle( NodeImpl::Force );
05741     TQApplication::restoreOverrideCursor();
05742   }
05743 
05744   ConstFrameIt it = d->m_frames.begin();
05745   const ConstFrameIt end = d->m_frames.end();
05746   for (; it != end; ++it )
05747     if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
05748       KParts::ReadOnlyPart* const p = ( *it )->m_part;
05749       static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
05750     }
05751 
05752   if ( d->m_guiProfile == BrowserViewGUI ) {
05753       d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
05754       d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
05755   }
05756 }
05757 
05758 void KHTMLPart::slotZoomView( int delta )
05759 {
05760   if ( delta < 0 )
05761     slotIncZoom();
05762   else
05763     slotDecZoom();
05764 }
05765 
05766 void KHTMLPart::setStatusBarText( const TQString& text, StatusBarPriority p)
05767 {
05768   if (!d->m_statusMessagesEnabled)
05769     return;
05770 
05771   d->m_statusBarText[p] = text;
05772 
05773   // shift handling ?
05774   TQString tobe = d->m_statusBarText[BarHoverText];
05775   if (tobe.isEmpty())
05776     tobe = d->m_statusBarText[BarOverrideText];
05777   if (tobe.isEmpty()) {
05778     tobe = d->m_statusBarText[BarDefaultText];
05779     if (!tobe.isEmpty() && d->m_jobspeed)
05780       tobe += " ";
05781     if (d->m_jobspeed)
05782       tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
05783   }
05784   tobe = "<qt>"+tobe;
05785 
05786   emit ReadOnlyPart::setStatusBarText(tobe);
05787 }
05788 
05789 
05790 void KHTMLPart::setJSStatusBarText( const TQString &text )
05791 {
05792   setStatusBarText(text, BarOverrideText);
05793 }
05794 
05795 void KHTMLPart::setJSDefaultStatusBarText( const TQString &text )
05796 {
05797   setStatusBarText(text, BarDefaultText);
05798 }
05799 
05800 TQString KHTMLPart::jsStatusBarText() const
05801 {
05802     return d->m_statusBarText[BarOverrideText];
05803 }
05804 
05805 TQString KHTMLPart::jsDefaultStatusBarText() const
05806 {
05807    return d->m_statusBarText[BarDefaultText];
05808 }
05809 
05810 TQString KHTMLPart::referrer() const
05811 {
05812    return d->m_referrer;
05813 }
05814 
05815 TQString KHTMLPart::pageReferrer() const
05816 {
05817    KURL referrerURL = KURL( d->m_pageReferrer );
05818    if (referrerURL.isValid())
05819    {
05820       TQString protocol = referrerURL.protocol();
05821 
05822       if ((protocol == "http") ||
05823          ((protocol == "https") && (m_url.protocol() == "https")))
05824       {
05825           referrerURL.setRef(TQString());
05826           referrerURL.setUser(TQString());
05827           referrerURL.setPass(TQString());
05828           return referrerURL.url();
05829       }
05830    }
05831 
05832    return TQString();
05833 }
05834 
05835 
05836 TQString KHTMLPart::lastModified() const
05837 {
05838   if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
05839     // Local file: set last-modified from the file's mtime.
05840     // Done on demand to save time when this isn't needed - but can lead
05841     // to slightly wrong results if updating the file on disk w/o reloading.
05842     TQDateTime lastModif = TQFileInfo( m_url.path() ).lastModified();
05843     d->m_lastModified = lastModif.toString( Qt::LocalDate );
05844   }
05845   //kdDebug(6050) << "KHTMLPart::lastModified: " << d->m_lastModified << endl;
05846   return d->m_lastModified;
05847 }
05848 
05849 void KHTMLPart::slotLoadImages()
05850 {
05851   if (d->m_doc )
05852     d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
05853 
05854   ConstFrameIt it = d->m_frames.begin();
05855   const ConstFrameIt end = d->m_frames.end();
05856   for (; it != end; ++it )
05857     if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
05858       KParts::ReadOnlyPart* const p = ( *it )->m_part;
05859       static_cast<KHTMLPart*>( p )->slotLoadImages();
05860     }
05861 }
05862 
05863 void KHTMLPart::reparseConfiguration()
05864 {
05865   KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
05866   settings->init();
05867 
05868   setAutoloadImages( settings->autoLoadImages() );
05869   if (d->m_doc)
05870      d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
05871 
05872   d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
05873   d->m_bBackRightClick = settings->isBackRightClickEnabled();
05874   d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
05875   setDebugScript( settings->isJavaScriptDebugEnabled() );
05876   d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
05877   d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
05878   d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
05879 
05880   delete d->m_settings;
05881   d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
05882 
05883   TQApplication::setOverrideCursor( tqwaitCursor );
05884   khtml::CSSStyleSelector::reparseConfiguration();
05885   if(d->m_doc) d->m_doc->updateStyleSelector();
05886   TQApplication::restoreOverrideCursor();
05887 
05888   if (KHTMLFactory::defaultHTMLSettings()->isAdFilterEnabled())
05889      runAdFilter();
05890 }
05891 
05892 TQStringList KHTMLPart::frameNames() const
05893 {
05894   TQStringList res;
05895 
05896   ConstFrameIt it = d->m_frames.begin();
05897   const ConstFrameIt end = d->m_frames.end();
05898   for (; it != end; ++it )
05899     if (!(*it)->m_bPreloaded)
05900       res += (*it)->m_name;
05901 
05902   return res;
05903 }
05904 
05905 TQPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
05906 {
05907   TQPtrList<KParts::ReadOnlyPart> res;
05908 
05909   ConstFrameIt it = d->m_frames.begin();
05910   const ConstFrameIt end = d->m_frames.end();
05911   for (; it != end; ++it )
05912     if (!(*it)->m_bPreloaded)
05913       res.append( (*it)->m_part );
05914 
05915   return res;
05916 }
05917 
05918 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
05919 {
05920     kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
05921   FrameIt it = d->m_frames.find( urlArgs.frameName );
05922 
05923   if ( it == d->m_frames.end() )
05924     return false;
05925 
05926   // Inform someone that we are about to show something else.
05927   if ( !urlArgs.lockHistory() )
05928       emit d->m_extension->openURLNotify();
05929 
05930   requestObject( *it, url, urlArgs );
05931 
05932   return true;
05933 }
05934 
05935 void KHTMLPart::setDNDEnabled( bool b )
05936 {
05937   d->m_bDnd = b;
05938 }
05939 
05940 bool KHTMLPart::dndEnabled() const
05941 {
05942   return d->m_bDnd;
05943 }
05944 
05945 void KHTMLPart::customEvent( TQCustomEvent *event )
05946 {
05947   if ( khtml::MousePressEvent::test( event ) )
05948   {
05949     khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
05950     return;
05951   }
05952 
05953   if ( khtml::MouseDoubleClickEvent::test( event ) )
05954   {
05955     khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
05956     return;
05957   }
05958 
05959   if ( khtml::MouseMoveEvent::test( event ) )
05960   {
05961     khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
05962     return;
05963   }
05964 
05965   if ( khtml::MouseReleaseEvent::test( event ) )
05966   {
05967     khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
05968     return;
05969   }
05970 
05971   if ( khtml::DrawContentsEvent::test( event ) )
05972   {
05973     khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
05974     return;
05975   }
05976 
05977   KParts::ReadOnlyPart::customEvent( event );
05978 }
05979 
05985 static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
05986 {
05987     for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
05988         if (n->isText()) {
05989             khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
05990             const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05991             const unsigned lim = runs.count();
05992             for (unsigned i = 0; i != lim; ++i) {
05993                 if (runs[i]->m_y == y && textRenderer->element()) {
05994                     startNode = textRenderer->element();
05995                     startOffset = runs[i]->m_start;
05996                     return true;
05997                 }
05998             }
05999         }
06000 
06001         if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
06002             return true;
06003         }
06004     }
06005 
06006     return false;
06007 }
06008 
06014 static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
06015 {
06016     khtml::RenderObject *n = renderNode;
06017     if (!n) {
06018         return false;
06019     }
06020     khtml::RenderObject *next;
06021     while ((next = n->nextSibling())) {
06022         n = next;
06023     }
06024 
06025     while (1) {
06026         if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
06027             return true;
06028         }
06029 
06030         if (n->isText()) {
06031             khtml::RenderText* const textRenderer =  static_cast<khtml::RenderText *>(n);
06032             const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
06033             for (int i = (int)runs.count()-1; i >= 0; --i) {
06034                 if (runs[i]->m_y == y && textRenderer->element()) {
06035                     endNode = textRenderer->element();
06036                     endOffset = runs[i]->m_start + runs[i]->m_len;
06037                     return true;
06038                 }
06039             }
06040         }
06041 
06042         if (n == renderNode) {
06043             return false;
06044         }
06045 
06046         n = n->previousSibling();
06047     }
06048 }
06049 
06050 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
06051 {
06052   DOM::DOMString url = event->url();
06053   TQMouseEvent *_mouse = event->qmouseEvent();
06054   DOM::Node innerNode = event->innerNode();
06055   d->m_mousePressNode = innerNode;
06056 
06057    d->m_dragStartPos = _mouse->pos();
06058 
06059    if ( !event->url().isNull() ) {
06060      d->m_strSelectedURL = event->url().string();
06061      d->m_strSelectedURLTarget = event->target().string();
06062    }
06063    else
06064      d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
06065 
06066   if ( _mouse->button() == Qt::LeftButton ||
06067        _mouse->button() == Qt::MidButton )
06068   {
06069     d->m_bMousePressed = true;
06070 
06071 #ifndef KHTML_NO_SELECTION
06072     if ( _mouse->button() == Qt::LeftButton )
06073     {
06074       if ( (!d->m_strSelectedURL.isNull() && !isEditable())
06075             || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
06076       return;
06077       if ( !innerNode.isNull()  && innerNode.handle()->renderer()) {
06078           int offset = 0;
06079           DOM::NodeImpl* node = 0;
06080           khtml::RenderObject::SelPointState state;
06081           innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
06082                                                                event->absX()-innerNode.handle()->renderer()->xPos(),
06083                                                                event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
06084           d->m_extendMode = d->ExtendByChar;
06085 #ifdef KHTML_NO_CARET
06086           d->m_selectionStart = node;
06087           d->m_startOffset = offset;
06088           //if ( node )
06089           //  kdDebug(6005) << "KHTMLPart::khtmlMousePressEvent selectionStart=" << d->m_selectionStart.handle()->renderer()
06090           //                << " offset=" << d->m_startOffset << endl;
06091           //else
06092           //  kdDebug(6005) << "KHTML::khtmlMousePressEvent selectionStart=(nil)" << endl;
06093           d->m_selectionEnd = d->m_selectionStart;
06094           d->m_endOffset = d->m_startOffset;
06095           d->m_doc->clearSelection();
06096 #else // KHTML_NO_CARET
06097       d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
06098 #endif // KHTML_NO_CARET
06099       d->m_initialNode = d->m_selectionStart;
06100       d->m_initialOffset = d->m_startOffset;
06101 //           kdDebug(6000) << "press: initOfs " << d->m_initialOffset << endl;
06102       }
06103       else
06104       {
06105 #ifndef KHTML_NO_CARET
06106         // simply leave it. Is this a good idea?
06107 #else
06108         d->m_selectionStart = DOM::Node();
06109         d->m_selectionEnd = DOM::Node();
06110 #endif
06111       }
06112       emitSelectionChanged();
06113       startAutoScroll();
06114     }
06115 #else
06116     d->m_dragLastPos = _mouse->globalPos();
06117 #endif
06118   }
06119 
06120   if ( _mouse->button() == Qt::RightButton && parentPart() != 0 && d->m_bBackRightClick )
06121   {
06122     d->m_bRightMousePressed = true;
06123   } else if ( _mouse->button() == Qt::RightButton )
06124   {
06125     popupMenu( d->m_strSelectedURL );
06126     // might be deleted, don't touch "this"
06127   }
06128 }
06129 
06130 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
06131 {
06132   TQMouseEvent *_mouse = event->qmouseEvent();
06133   if ( _mouse->button() == Qt::LeftButton )
06134   {
06135     d->m_bMousePressed = true;
06136     DOM::Node innerNode = event->innerNode();
06137     // Find selectionStart again, khtmlMouseReleaseEvent lost it
06138     if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
06139       int offset = 0;
06140       DOM::NodeImpl* node = 0;
06141       khtml::RenderObject::SelPointState state;
06142       innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
06143                                                            event->absX()-innerNode.handle()->renderer()->xPos(),
06144                                                            event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);
06145 
06146       //kdDebug() << k_funcinfo << "checkSelectionPoint returned node=" << node << " offset=" << offset << endl;
06147 
06148       if ( node && node->renderer() )
06149       {
06150         // Extend selection to a complete word (double-click) or line (triple-click)
06151         bool selectLine = (event->clickCount() == 3);
06152         d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;
06153 
06154     // Extend existing selection if Shift was pressed
06155     if (_mouse->state() & ShiftButton) {
06156           d->caretNode() = node;
06157       d->caretOffset() = offset;
06158           d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06159                 d->m_selectionStart.handle(), d->m_startOffset,
06160             d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06161           d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
06162           d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
06163     } else {
06164       d->m_selectionStart = d->m_selectionEnd = node;
06165       d->m_startOffset = d->m_endOffset = offset;
06166           d->m_startBeforeEnd = true;
06167           d->m_initialNode = node;
06168           d->m_initialOffset = offset;
06169     }
06170 //         kdDebug(6000) << "dblclk: initOfs " << d->m_initialOffset << endl;
06171 
06172         // Extend the start
06173         extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
06174         // Extend the end
06175         extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );
06176 
06177         //kdDebug() << d->m_selectionStart.handle() << " " << d->m_startOffset << "  -  " <<
06178         //  d->m_selectionEnd.handle() << " " << d->m_endOffset << endl;
06179 
06180         emitSelectionChanged();
06181         d->m_doc
06182           ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
06183                          d->m_selectionEnd.handle(),d->m_endOffset);
06184 #ifndef KHTML_NO_CARET
06185         bool v = d->m_view->placeCaret();
06186         emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
06187 #endif
06188         startAutoScroll();
06189       }
06190     }
06191   }
06192 }
06193 
06194 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
06195 {
06196   khtml::RenderObject* obj = node->renderer();
06197 
06198   if (obj->isText() && selectLines) {
06199     int pos;
06200     khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
06201     khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
06202     DOMString t = node->nodeValue();
06203     DOM::NodeImpl* selNode = 0;
06204     long selOfs = 0;
06205 
06206     if (!run)
06207       return;
06208 
06209     int selectionPointY = run->m_y;
06210 
06211     // Go up to first non-inline element.
06212     khtml::RenderObject *renderNode = renderer;
06213     while (renderNode && renderNode->isInline())
06214       renderNode = renderNode->parent();
06215 
06216     renderNode = renderNode->firstChild();
06217 
06218     if (right) {
06219       // Look for all the last child in the block that is on the same line
06220       // as the selection point.
06221       if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
06222         return;
06223     } else {
06224       // Look for all the first child in the block that is on the same line
06225       // as the selection point.
06226       if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
06227         return;
06228     }
06229 
06230     selectionNode = selNode;
06231     selectionOffset = selOfs;
06232     return;
06233   }
06234 
06235   TQString str;
06236   int len = 0;
06237   if ( obj->isText() ) { // can be false e.g. when double-clicking on a disabled submit button
06238     str = static_cast<khtml::RenderText *>(obj)->data().string();
06239     len = str.length();
06240   }
06241   //kdDebug() << "extendSelection right=" << right << " offset=" << offset << " len=" << len << " Starting at obj=" << obj << endl;
06242   TQChar ch;
06243   do {
06244     // Last char was ok, point to it
06245     if ( node ) {
06246       selectionNode = node;
06247       selectionOffset = offset;
06248     }
06249 
06250     // Get another char
06251     while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
06252     {
06253       obj = right ? obj->objectBelow() : obj->objectAbove();
06254       //kdDebug() << "obj=" << obj << endl;
06255       if ( obj ) {
06256         //kdDebug() << "isText=" << obj->isText() << endl;
06257         str = TQString();
06258         if ( obj->isText() )
06259           str = static_cast<khtml::RenderText *>(obj)->data().string();
06260         else if ( obj->isBR() )
06261           str = '\n';
06262         else if ( !obj->isInline() ) {
06263           obj = 0L; // parag limit -> done
06264           break;
06265         }
06266         len = str.length();
06267         //kdDebug() << "str=" << str << " length=" << len << endl;
06268         // set offset - note that the first thing will be a ++ or -- on it.
06269         if ( right )
06270           offset = -1;
06271         else
06272           offset = len;
06273       }
06274     }
06275     if ( !obj ) // end of parag or document
06276       break;
06277     node = obj->element();
06278     if ( right )
06279     {
06280       Q_ASSERT( offset < len-1 );
06281       ++offset;
06282     }
06283     else
06284     {
06285       Q_ASSERT( offset > 0 );
06286       --offset;
06287     }
06288 
06289     // Test that char
06290     ch = str[ (int)offset ];
06291     //kdDebug() << " offset=" << offset << " ch=" << TQString(ch) << endl;
06292   } while ( !ch.isSpace() && !ch.isPunct() );
06293 
06294   // make offset point after last char
06295   if (right) ++selectionOffset;
06296 }
06297 
06298 #ifndef KHTML_NO_SELECTION
06299 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
06300 {
06301       int offset;
06302       //kdDebug(6000) << "KHTMLPart::khtmlMouseMoveEvent x=" << event->x() << " y=" << event->y() << endl;
06303       DOM::NodeImpl* node=0;
06304       khtml::RenderObject::SelPointState state;
06305       innerNode.handle()->renderer()->checkSelectionPoint( x, y,
06306                                                            absX-innerNode.handle()->renderer()->xPos(),
06307                                                            absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
06308       if (!node || !node->renderer()) return;
06309 
06310       // Words at the beginning/end of line cannot be deselected in
06311       // ExtendByWord mode. Therefore, do not enforce it if the selection
06312       // point does not match the node under the mouse cursor.
06313       bool withinNode = innerNode == node;
06314 
06315       // we have to get to know if end is before start or not...
06316       // shouldn't be null but it can happen with dynamic updating of nodes
06317       if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
06318           d->m_initialNode.isNull() ||
06319           !d->m_selectionStart.handle()->renderer() ||
06320           !d->m_selectionEnd.handle()->renderer()) return;
06321 
06322       if (d->m_extendMode != d->ExtendByChar) {
06323         // check whether we should extend at the front, or at the back
06324         bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
06325                 d->caretNode().handle(), d->caretOffset(),
06326             d->m_initialNode.handle(), d->m_initialOffset) <= 0;
06327         bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
06328             d->m_initialNode.handle(), d->m_initialOffset) <= 0;
06329         // have to fix up start to point to the original end
06330         if (caretBeforeInit != nodeBeforeInit) {
06331 //         kdDebug(6000) << "extto cbi: " << caretBeforeInit << " startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << " initOfs " << d->m_initialOffset << endl;
06332           extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
06333         d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
06334         d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
06335         nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
06336     }
06337       }
06338 
06339       d->caretNode() = node;
06340       d->caretOffset() = offset;
06341       //kdDebug( 6000 ) << "setting end of selection to " << d->m_selectionEnd.handle() << "/" << d->m_endOffset << endl;
06342 
06343       d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06344                 d->m_selectionStart.handle(), d->m_startOffset,
06345             d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06346 
06347       if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
06348       {
06349 //         kdDebug(6000) << "extto: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << " initOfs " << d->m_initialOffset << endl;
06350         if (d->m_extendMode != d->ExtendByChar && withinNode)
06351           extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );
06352 
06353         if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
06354           d->m_doc
06355             ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
06356                            d->m_selectionEnd.handle(),d->m_startOffset);
06357         else if (d->m_startBeforeEnd)
06358           d->m_doc
06359             ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
06360                            d->m_selectionEnd.handle(),d->m_endOffset);
06361         else
06362           d->m_doc
06363             ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
06364                            d->m_selectionStart.handle(),d->m_startOffset);
06365       }
06366 #ifndef KHTML_NO_CARET
06367       d->m_view->placeCaret();
06368 #endif
06369 }
06370 
06371 bool KHTMLPart::isExtendingSelection() const
06372 {
06373   // This is it, the whole detection. khtmlMousePressEvent only sets this
06374   // on LMB or MMB, but never on RMB. As text selection doesn't work for MMB,
06375   // it's sufficient to only rely on this flag to detect selection extension.
06376   return d->m_bMousePressed;
06377 }
06378 #endif // KHTML_NO_SELECTION
06379 
06380 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
06381 {
06382   TQMouseEvent *_mouse = event->qmouseEvent();
06383 
06384   if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
06385   {
06386     popupMenu( d->m_strSelectedURL );
06387     d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
06388     d->m_bRightMousePressed = false;
06389   }
06390 
06391   DOM::DOMString url = event->url();
06392   DOM::DOMString target = event->target();
06393   DOM::Node innerNode = event->innerNode();
06394 
06395 #ifndef QT_NO_DRAGANDDROP
06396   if( d->m_bDnd && d->m_bMousePressed &&
06397       ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
06398         || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
06399     if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
06400       return;
06401 
06402     TQPixmap pix;
06403     HTMLImageElementImpl *img = 0L;
06404     TQDragObject *drag = 0;
06405     KURL u;
06406 
06407     // qDebug("****************** Event URL: %s", url.string().latin1());
06408     // qDebug("****************** Event Target: %s", target.string().latin1());
06409 
06410     // Normal image...
06411     if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
06412     {
06413       img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
06414       u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
06415       pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
06416     }
06417     else
06418     {
06419       // Text or image link...
06420       u = completeURL( d->m_strSelectedURL );
06421       pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
06422     }
06423 
06424     u.setPass(TQString());
06425 
06426     KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
06427     if ( !d->m_referrer.isEmpty() )
06428       urlDrag->metaData()["referrer"] = d->m_referrer;
06429 
06430     if( img && img->complete()) {
06431       KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
06432       mdrag->addDragObject( new TQImageDrag( img->currentImage(), 0L ) );
06433       mdrag->addDragObject( urlDrag );
06434       drag = mdrag;
06435     }
06436     else
06437       drag = urlDrag;
06438 
06439     if ( !pix.isNull() )
06440       drag->setPixmap( pix );
06441 
06442     stopAutoScroll();
06443     if(drag)
06444       drag->drag();
06445 
06446     // when we finish our drag, we need to undo our mouse press
06447     d->m_bMousePressed = false;
06448     d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
06449     return;
06450   }
06451 #endif
06452 
06453   // Not clicked -> mouse over stuff
06454   if ( !d->m_bMousePressed )
06455   {
06456     // The mouse is over something
06457     if ( url.length() )
06458     {
06459       bool shiftPressed = ( _mouse->state() & ShiftButton );
06460 
06461       // Image map
06462       if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
06463       {
06464         HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
06465         if ( i && i->isServerMap() )
06466         {
06467           khtml::RenderObject *r = i->renderer();
06468           if(r)
06469           {
06470             int absx, absy, vx, vy;
06471             r->absolutePosition(absx, absy);
06472             view()->contentsToViewport( absx, absy, vx, vy );
06473 
06474             int x(_mouse->x() - vx), y(_mouse->y() - vy);
06475 
06476             d->m_overURL = url.string() + TQString("?%1,%2").arg(x).arg(y);
06477             d->m_overURLTarget = target.string();
06478             overURL( d->m_overURL, target.string(), shiftPressed );
06479             return;
06480           }
06481         }
06482       }
06483 
06484       // normal link
06485       if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
06486       {
06487         d->m_overURL = url.string();
06488         d->m_overURLTarget = target.string();
06489         overURL( d->m_overURL, target.string(), shiftPressed );
06490       }
06491     }
06492     else  // Not over a link...
06493     {
06494       // reset to "default statusbar text"
06495       resetHoverText();
06496     }
06497   }
06498   else {
06499 #ifndef KHTML_NO_SELECTION
06500     // selection stuff
06501     if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
06502         ( (_mouse->state() & Qt::LeftButton) != 0 )) {
06503       extendSelectionTo(event->x(), event->y(),
06504                         event->absX(), event->absY(), innerNode);
06505 #else
06506       if ( d->m_doc && d->m_view ) {
06507         TQPoint diff( _mouse->globalPos() - d->m_dragLastPos );
06508 
06509         if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
06510           d->m_view->scrollBy( -diff.x(), -diff.y() );
06511           d->m_dragLastPos = _mouse->globalPos();
06512         }
06513 #endif
06514     }
06515   }
06516 
06517 }
06518 
06519 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
06520 {
06521   DOM::Node innerNode = event->innerNode();
06522   d->m_mousePressNode = DOM::Node();
06523 
06524   if ( d->m_bMousePressed ) {
06525     setStatusBarText(TQString(), BarHoverText);
06526     stopAutoScroll();
06527   }
06528 
06529   // Used to prevent mouseMoveEvent from initiating a drag before
06530   // the mouse is pressed again.
06531   d->m_bMousePressed = false;
06532 
06533   TQMouseEvent *_mouse = event->qmouseEvent();
06534   if ( _mouse->button() == Qt::RightButton && parentPart() != 0 && d->m_bBackRightClick )
06535   {
06536     d->m_bRightMousePressed = false;
06537     KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
06538     if( tmp_iface ) {
06539       tmp_iface->callMethod( "goHistory(int)", -1 );
06540     }
06541   }
06542 #ifndef QT_NO_CLIPBOARD
06543   if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == Qt::MidButton) && (event->url().isNull())) {
06544     kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
06545                     << d->m_bOpenMiddleClick << endl;
06546 
06547     if (d->m_bOpenMiddleClick) {
06548     KHTMLPart *p = this;
06549     while (p->parentPart()) p = p->parentPart();
06550     p->d->m_extension->pasteRequest();
06551   }
06552   }
06553 #endif
06554 
06555 #ifndef KHTML_NO_SELECTION
06556   // delete selection in case start and end position are at the same point
06557   if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
06558 #ifndef KHTML_NO_CARET
06559     d->m_extendAtEnd = true;
06560 #else
06561     d->m_selectionStart = 0;
06562     d->m_selectionEnd = 0;
06563     d->m_startOffset = 0;
06564     d->m_endOffset = 0;
06565 #endif
06566     emitSelectionChanged();
06567   } else {
06568     // we have to get to know if end is before start or not...
06569 //     kdDebug(6000) << "rel: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << endl;
06570     DOM::Node n = d->m_selectionStart;
06571     d->m_startBeforeEnd = false;
06572     if( d->m_selectionStart == d->m_selectionEnd ) {
06573       if( d->m_startOffset < d->m_endOffset )
06574         d->m_startBeforeEnd = true;
06575     } else {
06576 #if 0
06577       while(!n.isNull()) {
06578         if(n == d->m_selectionEnd) {
06579           d->m_startBeforeEnd = true;
06580           break;
06581         }
06582         DOM::Node next = n.firstChild();
06583         if(next.isNull()) next = n.nextSibling();
06584         while( next.isNull() && !n.parentNode().isNull() ) {
06585           n = n.parentNode();
06586           next = n.nextSibling();
06587         }
06588         n = next;
06589       }
06590 #else
06591       // shouldn't be null but it can happen with dynamic updating of nodes
06592       if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
06593           !d->m_selectionStart.handle()->renderer() ||
06594           !d->m_selectionEnd.handle()->renderer()) return;
06595       d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06596                 d->m_selectionStart.handle(), d->m_startOffset,
06597             d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06598 #endif
06599     }
06600     if(!d->m_startBeforeEnd)
06601     {
06602       DOM::Node tmpNode = d->m_selectionStart;
06603       int tmpOffset = d->m_startOffset;
06604       d->m_selectionStart = d->m_selectionEnd;
06605       d->m_startOffset = d->m_endOffset;
06606       d->m_selectionEnd = tmpNode;
06607       d->m_endOffset = tmpOffset;
06608       d->m_startBeforeEnd = true;
06609       d->m_extendAtEnd = !d->m_extendAtEnd;
06610     }
06611 #ifndef KHTML_NO_CARET
06612     bool v = d->m_view->placeCaret();
06613     emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
06614 #endif
06615     // get selected text and paste to the clipboard
06616 #ifndef QT_NO_CLIPBOARD
06617     TQString text = selectedText();
06618     text.replace(TQChar(0xa0), ' ');
06619     disconnect( kapp->clipboard(), TQT_SIGNAL( selectionChanged()), this, TQT_SLOT( slotClearSelection()));
06620     kapp->clipboard()->setText(text,TQClipboard::Selection);
06621     connect( kapp->clipboard(), TQT_SIGNAL( selectionChanged()), TQT_SLOT( slotClearSelection()));
06622 #endif
06623     //kdDebug( 6000 ) << "selectedText = " << text << endl;
06624     emitSelectionChanged();
06625 //kdDebug(6000) << "rel2: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << "), caretOfs " << d->caretOffset() << endl;
06626   }
06627 #endif
06628   d->m_initialNode = 0;     // don't hold nodes longer than necessary
06629   d->m_initialOffset = 0;
06630 
06631 }
06632 
06633 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
06634 {
06635 }
06636 
06637 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
06638 {
06639   if ( event->activated() )
06640   {
06641     emitSelectionChanged();
06642     emit d->m_extension->enableAction( "print", d->m_doc != 0 );
06643 
06644     if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
06645     {
06646         TQPtrList<KAction> lst;
06647         lst.append( d->m_paLoadImages );
06648         plugActionList( "loadImages", lst );
06649     }
06650   }
06651 }
06652 
06653 void KHTMLPart::slotPrintFrame()
06654 {
06655   if ( d->m_frames.count() == 0 )
06656     return;
06657 
06658   KParts::ReadOnlyPart *frame = currentFrame();
06659   if (!frame)
06660     return;
06661 
06662   KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
06663 
06664   if ( !ext )
06665     return;
06666 
06667   TQMetaObject *mo = ext->metaObject();
06668 
06669   int idx = mo->findSlot( "print()", true );
06670   if ( idx >= 0 ) {
06671     TQUObject o[ 1 ];
06672     ext->qt_invoke( idx, o );
06673   }
06674 }
06675 
06676 void KHTMLPart::slotSelectAll()
06677 {
06678   KParts::ReadOnlyPart *part = currentFrame();
06679   if (part && part->inherits("KHTMLPart"))
06680     static_cast<KHTMLPart *>(part)->selectAll();
06681 }
06682 
06683 void KHTMLPart::startAutoScroll()
06684 {
06685    connect(&d->m_scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ));
06686    d->m_scrollTimer.start(100, false);
06687 }
06688 
06689 void KHTMLPart::stopAutoScroll()
06690 {
06691    disconnect(&d->m_scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ));
06692    if (d->m_scrollTimer.isActive())
06693        d->m_scrollTimer.stop();
06694 }
06695 
06696 
06697 void KHTMLPart::slotAutoScroll()
06698 {
06699     if (d->m_view)
06700       d->m_view->doAutoScroll();
06701     else
06702       stopAutoScroll(); // Safety
06703 }
06704 
06705 void KHTMLPart::runAdFilter()
06706 {
06707     if ( parentPart() )
06708         parentPart()->runAdFilter();
06709 
06710     if ( !d->m_doc )
06711         return;
06712 
06713     TQPtrDictIterator<khtml::CachedObject> it( d->m_doc->docLoader()->m_docObjects );
06714     for ( ; it.current(); ++it )
06715         if ( it.current()->type() == khtml::CachedObject::Image ) {
06716             khtml::CachedImage *image = static_cast<khtml::CachedImage *>(it.current());
06717             bool wasBlocked = image->m_wasBlocked;
06718             image->m_wasBlocked = KHTMLFactory::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( (*it).url().string() ) );
06719             if ( image->m_wasBlocked != wasBlocked )
06720                 image->do_notify(image->pixmap(), image->valid_rect());
06721         }
06722 
06723     if ( KHTMLFactory::defaultHTMLSettings()->isHideAdsEnabled() ) {
06724         for ( NodeImpl *nextNode, *node = d->m_doc; node; node = nextNode ) {
06725 
06726             // We might be deleting 'node' shortly.
06727             nextNode = node->traverseNextNode();
06728 
06729             if ( node->id() == ID_IMG ||
06730                  node->id() == ID_IFRAME ||
06731                  (node->id() == ID_INPUT && static_cast<HTMLInputElementImpl *>(node)->inputType() == HTMLInputElementImpl::IMAGE ))
06732             {
06733                 if ( KHTMLFactory::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( static_cast<ElementImpl *>(node)->getAttribute(ATTR_SRC).string() ) ) )
06734                 {
06735                     // We found an IMG, IFRAME or INPUT (of type IMAGE) matching a filter.
06736                     node->ref();
06737                     NodeImpl *parent = node->parent();
06738                     if( parent )
06739                     {
06740                         int exception = 0;
06741                         parent->removeChild(node, exception);
06742                     }
06743                     node->deref();
06744                 }
06745             }
06746         }
06747     }
06748 }
06749 
06750 void KHTMLPart::selectAll()
06751 {
06752   if (!d->m_doc) return;
06753 
06754   NodeImpl *first;
06755   if (d->m_doc->isHTMLDocument())
06756     first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06757   else
06758     first = d->m_doc;
06759   NodeImpl *next;
06760 
06761   // Look for first text/cdata node that has a renderer,
06762   // or first childless replaced element
06763   while ( first && !(first->renderer()
06764     && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
06765         || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
06766   {
06767     next = first->firstChild();
06768     if ( !next ) next = first->nextSibling();
06769     while( first && !next )
06770     {
06771       first = first->parentNode();
06772       if ( first )
06773         next = first->nextSibling();
06774     }
06775     first = next;
06776   }
06777 
06778   NodeImpl *last;
06779   if (d->m_doc->isHTMLDocument())
06780     last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06781   else
06782     last = d->m_doc;
06783   // Look for last text/cdata node that has a renderer,
06784   // or last childless replaced element
06785   // ### Instead of changing this loop, use findLastSelectableNode
06786   // in render_table.cpp (LS)
06787   while ( last && !(last->renderer()
06788     && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
06789         || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
06790   {
06791     next = last->lastChild();
06792     if ( !next ) next = last->previousSibling();
06793     while ( last && !next )
06794     {
06795       last = last->parentNode();
06796       if ( last )
06797         next = last->previousSibling();
06798     }
06799     last = next;
06800   }
06801 
06802   if ( !first || !last )
06803     return;
06804   Q_ASSERT(first->renderer());
06805   Q_ASSERT(last->renderer());
06806   d->m_selectionStart = first;
06807   d->m_startOffset = 0;
06808   d->m_selectionEnd = last;
06809   d->m_endOffset = last->nodeValue().length();
06810   d->m_startBeforeEnd = true;
06811 
06812   d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
06813                           d->m_selectionEnd.handle(), d->m_endOffset );
06814 
06815   emitSelectionChanged();
06816 }
06817 
06818 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const TQString &message, const TQString &button)
06819 {
06820   bool linkAllowed = true;
06821 
06822   if ( d->m_doc )
06823     linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);
06824 
06825   if ( !linkAllowed ) {
06826     khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
06827     if (tokenizer)
06828       tokenizer->setOnHold(true);
06829 
06830     int response = KMessageBox::Cancel;
06831     if (!message.isEmpty())
06832     {
06833         response = KMessageBox::warningContinueCancel( 0,
06834                                message.arg(linkURL.htmlURL()),
06835                                i18n( "Security Warning" ),
06836                                button);
06837     }
06838     else
06839     {
06840         KMessageBox::error( 0,
06841                 i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
06842                 i18n( "Security Alert" ));
06843     }
06844 
06845     if (tokenizer)
06846        tokenizer->setOnHold(false);
06847     return (response==KMessageBox::Continue);
06848   }
06849   return true;
06850 }
06851 
06852 void KHTMLPart::slotPartRemoved( KParts::Part *part )
06853 {
06854 //    kdDebug(6050) << "KHTMLPart::slotPartRemoved " << part << endl;
06855     if ( part == d->m_activeFrame )
06856     {
06857         d->m_activeFrame = 0L;
06858         if ( !part->inherits( "KHTMLPart" ) )
06859         {
06860             if (factory()) {
06861                 factory()->removeClient( part );
06862             }
06863             if (childClients()->containsRef(part)) {
06864                 removeChildClient( part );
06865             }
06866         }
06867     }
06868 }
06869 
06870 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
06871 {
06872 //    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged this=" << this << "part=" << part << endl;
06873     if ( part == this )
06874     {
06875         kdError(6050) << "strange error! we activated ourselves" << endl;
06876         assert( false );
06877         return;
06878     }
06879 //    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged d->m_activeFrame=" << d->m_activeFrame << endl;
06880     if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( TQFRAME_OBJECT_NAME_STRING ) )
06881     {
06882         TQFrame *frame = static_cast<TQFrame *>( d->m_activeFrame->widget() );
06883         if (frame->frameStyle() != TQFrame::NoFrame)
06884         {
06885            frame->setFrameStyle( TQFrame::StyledPanel | TQFrame::Sunken);
06886            frame->repaint();
06887         }
06888     }
06889 
06890     if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
06891     {
06892         if (factory()) {
06893             factory()->removeClient( d->m_activeFrame );
06894         }
06895         removeChildClient( d->m_activeFrame );
06896     }
06897     if( part && !part->inherits( "KHTMLPart" ) )
06898     {
06899         if (factory()) {
06900             factory()->addClient( part );
06901         }
06902         insertChildClient( part );
06903     }
06904 
06905 
06906     d->m_activeFrame = part;
06907 
06908     if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( TQFRAME_OBJECT_NAME_STRING ) )
06909     {
06910         TQFrame *frame = static_cast<TQFrame *>( d->m_activeFrame->widget() );
06911         if (frame->frameStyle() != TQFrame::NoFrame)
06912         {
06913            frame->setFrameStyle( TQFrame::StyledPanel | TQFrame::Plain);
06914            frame->repaint();
06915         }
06916         kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
06917     }
06918 
06919     updateActions();
06920 
06921     // (note: childObject returns 0 if the argument is 0)
06922     d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
06923 }
06924 
06925 void KHTMLPart::setActiveNode(const DOM::Node &node)
06926 {
06927     if (!d->m_doc || !d->m_view)
06928         return;
06929 
06930     // Set the document's active node
06931     d->m_doc->setFocusNode(node.handle());
06932 
06933     // Scroll the view if necessary to ensure that the new focus node is visible
06934     TQRect rect  = node.handle()->getRect();
06935     d->m_view->ensureVisible(rect.right(), rect.bottom());
06936     d->m_view->ensureVisible(rect.left(), rect.top());
06937 }
06938 
06939 DOM::Node KHTMLPart::activeNode() const
06940 {
06941     return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
06942 }
06943 
06944 DOM::EventListener *KHTMLPart::createHTMLEventListener( TQString code, TQString name, NodeImpl* node )
06945 {
06946   KJSProxy *proxy = jScript();
06947 
06948   if (!proxy)
06949     return 0;
06950 
06951   return proxy->createHTMLEventHandler( m_url.url(), name, code, node );
06952 }
06953 
06954 KHTMLPart *KHTMLPart::opener()
06955 {
06956     return d->m_opener;
06957 }
06958 
06959 void KHTMLPart::setOpener(KHTMLPart *_opener)
06960 {
06961     d->m_opener = _opener;
06962 }
06963 
06964 bool KHTMLPart::openedByJS()
06965 {
06966     return d->m_openedByJS;
06967 }
06968 
06969 void KHTMLPart::setOpenedByJS(bool _openedByJS)
06970 {
06971     d->m_openedByJS = _openedByJS;
06972 }
06973 
06974 void KHTMLPart::preloadStyleSheet(const TQString &url, const TQString &stylesheet)
06975 {
06976     khtml::Cache::preloadStyleSheet(url, stylesheet);
06977 }
06978 
06979 void KHTMLPart::preloadScript(const TQString &url, const TQString &script)
06980 {
06981     khtml::Cache::preloadScript(url, script);
06982 }
06983 
06984 TQCString KHTMLPart::dcopObjectId() const
06985 {
06986   TQCString id;
06987   id.sprintf("html-widget%d", d->m_dcop_counter);
06988   return id;
06989 }
06990 
06991 long KHTMLPart::cacheId() const
06992 {
06993   return d->m_cacheId;
06994 }
06995 
06996 bool KHTMLPart::restored() const
06997 {
06998   return d->m_restored;
06999 }
07000 
07001 bool KHTMLPart::pluginPageQuestionAsked(const TQString& mimetype) const
07002 {
07003   // parentPart() should be const!
07004   KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
07005   if ( parent )
07006     return parent->pluginPageQuestionAsked(mimetype);
07007 
07008   return d->m_pluginPageQuestionAsked.contains(mimetype);
07009 }
07010 
07011 void KHTMLPart::setPluginPageQuestionAsked(const TQString& mimetype)
07012 {
07013   if ( parentPart() )
07014     parentPart()->setPluginPageQuestionAsked(mimetype);
07015 
07016   d->m_pluginPageQuestionAsked.append(mimetype);
07017 }
07018 
07019 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
07020 {
07021   d->m_automaticDetection->setItemChecked( _id, true );
07022 
07023   switch ( _id ) {
07024     case 0 :
07025       d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
07026       break;
07027     case 1 :
07028       d->m_autoDetectLanguage = khtml::Decoder::Arabic;
07029       break;
07030     case 2 :
07031       d->m_autoDetectLanguage = khtml::Decoder::Baltic;
07032       break;
07033     case 3 :
07034       d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
07035       break;
07036     case 4 :
07037       d->m_autoDetectLanguage = khtml::Decoder::Chinese;
07038       break;
07039     case 5 :
07040       d->m_autoDetectLanguage = khtml::Decoder::Greek;
07041       break;
07042     case 6 :
07043       d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
07044       break;
07045     case 7 :
07046       d->m_autoDetectLanguage = khtml::Decoder::Japanese;
07047       break;
07048     case 8 :
07049       d->m_autoDetectLanguage = khtml::Decoder::Korean;
07050       break;
07051     case 9 :
07052       d->m_autoDetectLanguage = khtml::Decoder::Russian;
07053       break;
07054     case 10 :
07055       d->m_autoDetectLanguage = khtml::Decoder::Thai;
07056       break;
07057     case 11 :
07058       d->m_autoDetectLanguage = khtml::Decoder::Turkish;
07059       break;
07060     case 12 :
07061       d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
07062       break;
07063     case 13 :
07064       d->m_autoDetectLanguage = khtml::Decoder::Unicode;
07065       break;
07066     case 14 :
07067       d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
07068       break;
07069     default :
07070       d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
07071       break;
07072   }
07073 
07074   for ( int i = 0; i <= 14; ++i ) {
07075     if ( i != _id )
07076       d->m_automaticDetection->setItemChecked( i, false );
07077   }
07078 
07079   d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
07080 
07081   setEncoding( TQString(), false );
07082 
07083   if( d->m_manualDetection )
07084     d->m_manualDetection->setCurrentItem( -1 );
07085   d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
07086 }
07087 
07088 khtml::Decoder *KHTMLPart::createDecoder()
07089 {
07090     khtml::Decoder *dec = new khtml::Decoder();
07091     if( !d->m_encoding.isNull() )
07092         dec->setEncoding( d->m_encoding.latin1(),
07093             d->m_haveEncoding ? khtml::Decoder::UserChosenEncoding : khtml::Decoder::EncodingFromHTTPHeader);
07094     else {
07095         // Inherit the default encoding from the parent frame if there is one.
07096         const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
07097             ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
07098         dec->setEncoding(defaultEncoding, khtml::Decoder::DefaultEncoding);
07099     }
07100 #ifdef APPLE_CHANGES
07101     if (d->m_doc)
07102         d->m_doc->setDecoder(d->m_decoder);
07103 #endif
07104     dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
07105     return dec;
07106 }
07107 
07108 void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
07109   emit caretPositionChanged(node, offset);
07110 }
07111 
07112 void KHTMLPart::restoreScrollPosition()
07113 {
07114   KParts::URLArgs args = d->m_extension->urlArgs();
07115 
07116   if ( m_url.hasRef() && !d->m_restoreScrollPosition && !args.reload) {
07117     if ( !d->m_doc || !d->m_doc->parsing() )
07118       disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
07119     if ( !gotoAnchor(m_url.encodedHtmlRef()) )
07120       gotoAnchor(m_url.htmlRef());
07121     return;
07122   }
07123 
07124   // Check whether the viewport has become large enough to encompass the stored
07125   // offsets. If the document has been fully loaded, force the new coordinates,
07126   // even if the canvas is too short (can happen when user resizes the window
07127   // during loading).
07128   if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
07129       || d->m_bComplete) {
07130     d->m_view->setContentsPos(args.xOffset, args.yOffset);
07131     disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
07132   }
07133 }
07134 
07135 
07136 void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
07137 {
07138 #ifndef KHTML_NO_WALLET
07139   KHTMLPart *p;
07140 
07141   for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
07142   }
07143 
07144   if (p) {
07145     p->openWallet(form);
07146     return;
07147   }
07148 
07149   if (onlyLocalReferences()) { // avoid triggering on local apps, thumbnails
07150     return;
07151   }
07152 
07153   if (d->m_wallet) {
07154     if (d->m_bWalletOpened) {
07155       if (d->m_wallet->isOpen()) {
07156         form->walletOpened(d->m_wallet);
07157         return;
07158       }
07159       d->m_wallet->deleteLater();
07160       d->m_wallet = 0L;
07161       d->m_bWalletOpened = false;
07162     }
07163   }
07164 
07165   if (!d->m_wq) {
07166     KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
07167     d->m_wq = new KHTMLWalletQueue(this);
07168     d->m_wq->wallet = wallet;
07169     connect(wallet, TQT_SIGNAL(walletOpened(bool)), d->m_wq, TQT_SLOT(walletOpened(bool)));
07170     connect(d->m_wq, TQT_SIGNAL(walletOpened(KWallet::Wallet*)), this, TQT_SLOT(walletOpened(KWallet::Wallet*)));
07171   }
07172   assert(form);
07173   d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->getDocument()));
07174 #endif // KHTML_NO_WALLET
07175 }
07176 
07177 
07178 void KHTMLPart::saveToWallet(const TQString& key, const TQMap<TQString,TQString>& data)
07179 {
07180 #ifndef KHTML_NO_WALLET
07181   KHTMLPart *p;
07182 
07183   for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
07184   }
07185 
07186   if (p) {
07187     p->saveToWallet(key, data);
07188     return;
07189   }
07190 
07191   if (d->m_wallet) {
07192     if (d->m_bWalletOpened) {
07193       if (d->m_wallet->isOpen()) {
07194         if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
07195           d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
07196         }
07197         d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
07198         d->m_wallet->writeMap(key, data);
07199         return;
07200       }
07201       d->m_wallet->deleteLater();
07202       d->m_wallet = 0L;
07203       d->m_bWalletOpened = false;
07204     }
07205   }
07206 
07207   if (!d->m_wq) {
07208     KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
07209     d->m_wq = new KHTMLWalletQueue(this);
07210     d->m_wq->wallet = wallet;
07211     connect(wallet, TQT_SIGNAL(walletOpened(bool)), d->m_wq, TQT_SLOT(walletOpened(bool)));
07212     connect(d->m_wq, TQT_SIGNAL(walletOpened(KWallet::Wallet*)), this, TQT_SLOT(walletOpened(KWallet::Wallet*)));
07213   }
07214   d->m_wq->savers.append(qMakePair(key, data));
07215 #endif // KHTML_NO_WALLET
07216 }
07217 
07218 
07219 void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
07220 #ifndef KHTML_NO_WALLET
07221   KHTMLPart *p;
07222 
07223   for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
07224   }
07225 
07226   if (p) {
07227     p->dequeueWallet(form);
07228     return;
07229   }
07230 
07231   if (d->m_wq) {
07232     d->m_wq->callers.remove(KHTMLWalletQueue::Caller(form, form->getDocument()));
07233   }
07234 #endif // KHTML_NO_WALLET
07235 }
07236 
07237 
07238 void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
07239 #ifndef KHTML_NO_WALLET
07240   assert(!d->m_wallet);
07241   assert(d->m_wq);
07242 
07243   d->m_wq->deleteLater(); // safe?
07244   d->m_wq = 0L;
07245 
07246   if (!wallet) {
07247     d->m_bWalletOpened = false;
07248     return;
07249   }
07250 
07251   d->m_wallet = wallet;
07252   d->m_bWalletOpened = true;
07253   connect(d->m_wallet, TQT_SIGNAL(walletClosed()), TQT_SLOT(slotWalletClosed()));
07254 
07255   if (!d->m_statusBarWalletLabel) {
07256     d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
07257     d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
07258     d->m_statusBarWalletLabel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
07259     d->m_statusBarWalletLabel->setUseCursor(false);
07260     d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
07261     d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
07262     connect(d->m_statusBarWalletLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(launchWalletManager()));
07263     connect(d->m_statusBarWalletLabel, TQT_SIGNAL(rightClickedURL()), TQT_SLOT(walletMenu()));
07264   } else {
07265     TQToolTip::remove(d->m_statusBarWalletLabel);
07266   }
07267   TQToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
07268 #endif // KHTML_NO_WALLET
07269 }
07270 
07271 
07272 KWallet::Wallet *KHTMLPart::wallet()
07273 {
07274 #ifndef KHTML_NO_WALLET
07275   KHTMLPart *p;
07276 
07277   for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
07278     ;
07279 
07280   if (p)
07281     return p->wallet();
07282 
07283 #endif // KHTML_NO_WALLET
07284   return d->m_wallet;
07285 }
07286 
07287 
07288 void KHTMLPart::slotWalletClosed()
07289 {
07290 #ifndef KHTML_NO_WALLET
07291   if (d->m_wallet) {
07292     d->m_wallet->deleteLater();
07293     d->m_wallet = 0L;
07294   }
07295   d->m_bWalletOpened = false;
07296   if (d->m_statusBarWalletLabel) {
07297     d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
07298     delete d->m_statusBarWalletLabel;
07299     d->m_statusBarWalletLabel = 0L;
07300   }
07301 #endif // KHTML_NO_WALLET
07302 }
07303 
07304 void KHTMLPart::launchWalletManager()
07305 {
07306 #ifndef KHTML_NO_WALLET
07307   if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
07308     KApplication::startServiceByDesktopName("kwalletmanager_show");
07309   } else {
07310     DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
07311     r.send("show");
07312     r.send("raise");
07313   }
07314 #endif // KHTML_NO_WALLET
07315 }
07316 
07317 void KHTMLPart::walletMenu()
07318 {
07319 #ifndef KHTML_NO_WALLET
07320   KPopupMenu *m = new KPopupMenu(0L);
07321   m->insertItem(i18n("&Close Wallet"), this, TQT_SLOT(slotWalletClosed()));
07322   m->popup(TQCursor::pos());
07323 #endif // KHTML_NO_WALLET
07324 }
07325 
07326 void KHTMLPart::slotToggleCaretMode()
07327 {
07328   setCaretMode(d->m_paToggleCaretMode->isChecked());
07329 }
07330 
07331 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
07332   d->m_formNotification = fn;
07333 }
07334 
07335 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
07336   return d->m_formNotification;
07337 }
07338 
07339 KURL KHTMLPart::toplevelURL()
07340 {
07341   KHTMLPart* part = this;
07342   while (part->parentPart())
07343     part = part->parentPart();
07344 
07345   if (!part)
07346     return KURL();
07347 
07348   return part->url();
07349 }
07350 
07351 bool KHTMLPart::isModified() const
07352 {
07353   if ( !d->m_doc )
07354     return false;
07355 
07356   return d->m_doc->unsubmittedFormChanges();
07357 }
07358 
07359 void KHTMLPart::setDebugScript( bool enable )
07360 {
07361   unplugActionList( "debugScriptList" );
07362   if ( enable ) {
07363     if (!d->m_paDebugScript) {
07364       d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, TQT_SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
07365     }
07366     d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
07367     TQPtrList<KAction> lst;
07368     lst.append( d->m_paDebugScript );
07369     plugActionList( "debugScriptList", lst );
07370   }
07371   d->m_bJScriptDebugEnabled = enable;
07372 }
07373 
07374 void KHTMLPart::setSuppressedPopupIndicator( bool enable )
07375 {
07376     setSuppressedPopupIndicator( enable, 0 );
07377 }
07378 
07379 void KHTMLPart::setSuppressedPopupIndicator( bool enable, KHTMLPart *originPart )
07380 {
07381     if ( parentPart() ) {
07382         parentPart()->setSuppressedPopupIndicator( enable, originPart );
07383         return;
07384     }
07385 
07386     if ( enable && originPart ) {
07387         d->m_openableSuppressedPopups++;
07388         if ( d->m_suppressedPopupOriginParts.findIndex( originPart ) == -1 )
07389             d->m_suppressedPopupOriginParts.append( originPart );
07390     }
07391 
07392     if ( enable && !d->m_statusBarPopupLabel ) {
07393         d->m_statusBarPopupLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
07394         d->m_statusBarPopupLabel->setFixedHeight( instance()->iconLoader()->currentSize( KIcon::Small) );
07395         d->m_statusBarPopupLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ));
07396         d->m_statusBarPopupLabel->setUseCursor( false );
07397         d->m_statusBarExtension->addStatusBarItem( d->m_statusBarPopupLabel, 0, false );
07398         d->m_statusBarPopupLabel->setPixmap( SmallIcon( "window_suppressed", instance() ) );
07399         TQToolTip::add( d->m_statusBarPopupLabel, i18n("This page was prevented from opening a new window via JavaScript." ) );
07400 
07401         connect(d->m_statusBarPopupLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(suppressedPopupMenu()));
07402         if (d->m_settings->jsPopupBlockerPassivePopup()) {
07403             TQPixmap px;
07404             px = MainBarIcon( "window_suppressed" );
07405             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);
07406         }
07407     } else if ( !enable && d->m_statusBarPopupLabel ) {
07408         TQToolTip::remove( d->m_statusBarPopupLabel );
07409         d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarPopupLabel );
07410         delete d->m_statusBarPopupLabel;
07411         d->m_statusBarPopupLabel = 0L;
07412     }
07413 }
07414 
07415 void KHTMLPart::suppressedPopupMenu() {
07416   KPopupMenu *m = new KPopupMenu(0L);
07417   m->setCheckable(true);
07418   if ( d->m_openableSuppressedPopups )
07419       m->insertItem(i18n("&Show Blocked Popup Window","Show %n Blocked Popup Windows", d->m_openableSuppressedPopups), this, TQT_SLOT(showSuppressedPopups()));
07420   m->insertItem(i18n("Show Blocked Window Passive Popup &Notification"), this, TQT_SLOT(togglePopupPassivePopup()),0,57);
07421   m->setItemChecked(57,d->m_settings->jsPopupBlockerPassivePopup());
07422   m->insertItem(i18n("&Configure JavaScript New Window Policies..."), this, TQT_SLOT(launchJSConfigDialog()));
07423   m->popup(TQCursor::pos());
07424 }
07425 
07426 void KHTMLPart::togglePopupPassivePopup() {
07427   // Same hack as in disableJSErrorExtension()
07428   d->m_settings->setJSPopupBlockerPassivePopup( !d->m_settings->jsPopupBlockerPassivePopup() );
07429   DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", TQByteArray());
07430 }
07431 
07432 void KHTMLPart::showSuppressedPopups() {
07433     for ( TQValueListIterator<TQGuardedPtr<KHTMLPart> > i = d->m_suppressedPopupOriginParts.begin();
07434           i != d->m_suppressedPopupOriginParts.end(); ++i ) {
07435       if (KHTMLPart* part = *i) {
07436         KJS::Window *w = KJS::Window::retrieveWindow( part );
07437         if (w) {
07438             w->showSuppressedWindows();
07439             w->forgetSuppressedWindows();
07440         }
07441       }
07442     }
07443     setSuppressedPopupIndicator( false );
07444     d->m_openableSuppressedPopups = 0;
07445     d->m_suppressedPopupOriginParts.clear();
07446 }
07447 
07448 // Extension to use for "view document source", "save as" etc.
07449 // Using the right extension can help the viewer get into the right mode (#40496)
07450 TQString KHTMLPart::defaultExtension() const
07451 {
07452     if ( !d->m_doc )
07453         return ".html";
07454     if ( !d->m_doc->isHTMLDocument() )
07455         return ".xml";
07456     return d->m_doc->htmlMode() == DOM::DocumentImpl::XHtml ? ".xhtml" : ".html";
07457 }
07458 
07459 bool KHTMLPart::inProgress() const
07460 {
07461     if (d->m_runningScripts || (d->m_doc && d->m_doc->parsing()))
07462         return true;
07463 
07464     // Any frame that hasn't completed yet ?
07465     ConstFrameIt it = d->m_frames.begin();
07466     const ConstFrameIt end = d->m_frames.end();
07467     for (; it != end; ++it ) {
07468         if ((*it)->m_run || !(*it)->m_bCompleted)
07469         return true;
07470     }
07471 
07472     return d->m_submitForm || !d->m_redirectURL.isEmpty() || d->m_redirectionTimer.isActive() || d->m_job;
07473 }
07474 
07475 using namespace KParts;
07476 #include "khtml_part.moc"
07477 #include "khtmlpart_p.moc"

khtml

Skip menu "khtml"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

khtml

Skip menu "khtml"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for khtml by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |