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