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