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