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() || obj->isInlineContinuation() ) );
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 || !child->m_part )
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 connect( child->m_extension, SIGNAL( requestFocus( KParts::ReadOnlyPart * ) ),
04041 this, SLOT( slotRequestFocus( KParts::ReadOnlyPart * ) ) );
04042
04043 child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
04044 }
04045 }
04046 else if ( child->m_frame && child->m_part &&
04047 child->m_frame->widget() != child->m_part->widget() )
04048 child->m_frame->setWidget( child->m_part->widget() );
04049
04050 checkEmitLoadEvent();
04051
04052
04053 if ( !child->m_part )
04054 return false;
04055
04056 if ( child->m_bPreloaded )
04057 {
04058 if ( child->m_frame && child->m_part )
04059 child->m_frame->setWidget( child->m_part->widget() );
04060
04061 child->m_bPreloaded = false;
04062 return true;
04063 }
04064
04065 child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04066
04067
04068
04069
04070
04071 child->m_args.serviceType = mimetype;
04072
04073
04074 child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;
04075
04076 if ( child->m_extension )
04077 child->m_extension->setURLArgs( child->m_args );
04078
04079 if(url.protocol() == "javascript" || url.url() == "about:blank") {
04080 if (!child->m_part->inherits("KHTMLPart"))
04081 return false;
04082
04083 KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
04084
04085 p->begin();
04086 if (d->m_doc && p->d->m_doc)
04087 p->d->m_doc->setBaseURL(d->m_doc->baseURL());
04088 if (!url.url().startsWith("about:")) {
04089 p->write(url.path());
04090 } else {
04091 p->m_url = url;
04092
04093 p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
04094 }
04095 p->end();
04096 return true;
04097 }
04098 else if ( !url.isEmpty() )
04099 {
04100
04101 bool b = child->m_part->openURL( url );
04102 if (child->m_bCompleted)
04103 checkCompleted();
04104 return b;
04105 }
04106 else
04107 {
04108 child->m_bCompleted = true;
04109 checkCompleted();
04110 return true;
04111 }
04112 }
04113
04114 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
04115 QObject *parent, const char *name, const QString &mimetype,
04116 QString &serviceName, QStringList &serviceTypes,
04117 const QStringList ¶ms )
04118 {
04119 QString constr;
04120 if ( !serviceName.isEmpty() )
04121 constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
04122
04123 KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
04124
04125 if ( offers.isEmpty() )
04126 return 0L;
04127
04128 KTrader::OfferList::Iterator it = offers.begin();
04129 for ( ; it != offers.end() ; ++it )
04130 {
04131 KService::Ptr service = (*it);
04132
04133 KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
04134 if ( factory ) {
04135 KParts::ReadOnlyPart *res = 0L;
04136
04137 const char *className = "KParts::ReadOnlyPart";
04138 if ( service->serviceTypes().contains( "Browser/View" ) )
04139 className = "Browser/View";
04140
04141 if ( factory->inherits( "KParts::Factory" ) )
04142 res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
04143 else
04144 res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
04145
04146 if ( res ) {
04147 serviceTypes = service->serviceTypes();
04148 serviceName = service->name();
04149 return res;
04150 }
04151 } else {
04152
04153 kdWarning() << QString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
04154 .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage()) << endl;
04155 }
04156 }
04157 return 0;
04158 }
04159
04160 KParts::PartManager *KHTMLPart::partManager()
04161 {
04162 if ( !d->m_manager )
04163 {
04164 d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
04165 d->m_manager->setAllowNestedParts( true );
04166 connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
04167 this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
04168 connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
04169 this, SLOT( slotPartRemoved( KParts::Part * ) ) );
04170 }
04171
04172 return d->m_manager;
04173 }
04174
04175 void KHTMLPart::submitFormAgain()
04176 {
04177 if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
04178 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 );
04179
04180 delete d->m_submitForm;
04181 d->m_submitForm = 0;
04182 disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
04183 }
04184
04185 void KHTMLPart::submitFormProxy( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
04186 {
04187 submitForm(action, url, formData, _target, contentType, boundary);
04188 }
04189
04190 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
04191 {
04192 kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
04193 if (d->m_formNotification == KHTMLPart::Only) {
04194 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04195 return;
04196 } else if (d->m_formNotification == KHTMLPart::Before) {
04197 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04198 }
04199
04200 KURL u = completeURL( url );
04201
04202 if ( !u.isValid() )
04203 {
04204
04205 return;
04206 }
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220 if (!d->m_submitForm) {
04221 if (u.protocol() != "https" && u.protocol() != "mailto") {
04222 if (d->m_ssl_in_use) {
04223 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning: This is a secure form but it is attempting to send your data back unencrypted."
04224 "\nA third party may be able to intercept and view this information."
04225 "\nAre you sure you wish to continue?"),
04226 i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
04227 if (rc == KMessageBox::Cancel)
04228 return;
04229 } else {
04230 KSSLSettings kss(true);
04231 if (kss.warnOnUnencrypted()) {
04232 int rc = KMessageBox::warningContinueCancel(NULL,
04233 i18n("Warning: Your data is about to be transmitted across the network unencrypted."
04234 "\nAre you sure you wish to continue?"),
04235 i18n("Network Transmission"),
04236 KGuiItem(i18n("&Send Unencrypted")),
04237 "WarnOnUnencryptedForm");
04238
04239 KConfig *config = kapp->config();
04240 QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
04241 KConfigGroupSaver saver( config, grpNotifMsgs );
04242
04243 if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
04244 config->deleteEntry("WarnOnUnencryptedForm");
04245 config->sync();
04246 kss.setWarnOnUnencrypted(false);
04247 kss.save();
04248 }
04249 if (rc == KMessageBox::Cancel)
04250 return;
04251 }
04252 }
04253 }
04254
04255 if (u.protocol() == "mailto") {
04256 int rc = KMessageBox::warningContinueCancel(NULL,
04257 i18n("This site is attempting to submit form data via email.\n"
04258 "Do you want to continue?"),
04259 i18n("Network Transmission"),
04260 KGuiItem(i18n("&Send Email")),
04261 "WarnTriedEmailSubmit");
04262
04263 if (rc == KMessageBox::Cancel) {
04264 return;
04265 }
04266 }
04267 }
04268
04269
04270
04271
04272 QString urlstring = u.url();
04273
04274 if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04275 urlstring = KURL::decode_string(urlstring);
04276 crossFrameExecuteScript( _target, urlstring.right( urlstring.length() - 11) );
04277 return;
04278 }
04279
04280 if (!checkLinkSecurity(u,
04281 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?" ),
04282 i18n( "Submit" )))
04283 return;
04284
04285 KParts::URLArgs args;
04286
04287 if (!d->m_referrer.isEmpty())
04288 args.metaData()["referrer"] = d->m_referrer;
04289
04290 args.metaData().insert("PropagateHttpHeader", "true");
04291 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04292 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04293 args.metaData().insert("main_frame_request",
04294 parentPart() == 0 ? "TRUE":"FALSE");
04295 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
04296 args.metaData().insert("ssl_activate_warnings", "TRUE");
04297
04298
04299
04300 args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
04301
04302
04303 if (u.protocol() == "mailto") {
04304
04305 QString q = u.query().mid(1);
04306 QStringList nvps = QStringList::split("&", q);
04307 bool triedToAttach = false;
04308
04309 for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
04310 QStringList pair = QStringList::split("=", *nvp);
04311 if (pair.count() >= 2) {
04312 if (pair.first().lower() == "attach") {
04313 nvp = nvps.remove(nvp);
04314 triedToAttach = true;
04315 }
04316 }
04317 }
04318
04319 if (triedToAttach)
04320 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");
04321
04322
04323 QString bodyEnc;
04324 if (contentType.lower() == "multipart/form-data") {
04325
04326 bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
04327 formData.size()));
04328 } else if (contentType.lower() == "text/plain") {
04329
04330 QString tmpbody = QString::fromLatin1(formData.data(),
04331 formData.size());
04332 tmpbody.replace(QRegExp("[&]"), "\n");
04333 tmpbody.replace(QRegExp("[+]"), " ");
04334 tmpbody = KURL::decode_string(tmpbody);
04335 bodyEnc = KURL::encode_string(tmpbody);
04336 } else {
04337 bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
04338 formData.size()));
04339 }
04340
04341 nvps.append(QString("body=%1").arg(bodyEnc));
04342 q = nvps.join("&");
04343 u.setQuery(q);
04344 }
04345
04346 if ( strcmp( action, "get" ) == 0 ) {
04347 if (u.protocol() != "mailto")
04348 u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
04349 args.setDoPost( false );
04350 }
04351 else {
04352 args.postData = formData;
04353 args.setDoPost( true );
04354
04355
04356 if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
04357 args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
04358 else
04359 args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
04360 }
04361
04362 if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
04363 if( d->m_submitForm ) {
04364 kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
04365 return;
04366 }
04367 d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
04368 d->m_submitForm->submitAction = action;
04369 d->m_submitForm->submitUrl = url;
04370 d->m_submitForm->submitFormData = formData;
04371 d->m_submitForm->target = _target;
04372 d->m_submitForm->submitContentType = contentType;
04373 d->m_submitForm->submitBoundary = boundary;
04374 connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
04375 }
04376 else
04377 {
04378 emit d->m_extension->openURLRequest( u, args );
04379 }
04380 }
04381
04382 void KHTMLPart::popupMenu( const QString &linkUrl )
04383 {
04384 KURL popupURL;
04385 KURL linkKURL;
04386 QString referrer;
04387 KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;
04388
04389 if ( linkUrl.isEmpty() ) {
04390 KHTMLPart* khtmlPart = this;
04391 while ( khtmlPart->parentPart() )
04392 {
04393 khtmlPart=khtmlPart->parentPart();
04394 }
04395 popupURL = khtmlPart->url();
04396 referrer = khtmlPart->pageReferrer();
04397 if (hasSelection())
04398 itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
04399 else
04400 itemflags |= KParts::BrowserExtension::ShowNavigationItems;
04401 } else {
04402 popupURL = completeURL( linkUrl );
04403 linkKURL = popupURL;
04404 referrer = this->referrer();
04405 }
04406
04407
04408
04409 KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
04410 QGuardedPtr<QObject> guard( client );
04411
04412 KParts::URLArgs args;
04413 args.serviceType = QString::fromLatin1( "text/html" );
04414 args.metaData()["referrer"] = referrer;
04415
04416 emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL, args, itemflags, S_IFREG );
04417
04418 if ( !guard.isNull() ) {
04419 delete client;
04420 emit popupMenu(linkUrl, QCursor::pos());
04421 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04422 }
04423 }
04424
04425 void KHTMLPart::slotParentCompleted()
04426 {
04427 if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
04428 {
04429
04430 d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
04431 }
04432 }
04433
04434 void KHTMLPart::slotChildStarted( KIO::Job *job )
04435 {
04436 khtml::ChildFrame *child = frame( sender() );
04437
04438 assert( child );
04439
04440 child->m_bCompleted = false;
04441
04442 if ( d->m_bComplete )
04443 {
04444 #if 0
04445
04446 if ( !parentPart() )
04447 {
04448 emit d->m_extension->openURLNotify();
04449 }
04450 #endif
04451 d->m_bComplete = false;
04452 emit started( job );
04453 }
04454 }
04455
04456 void KHTMLPart::slotChildCompleted()
04457 {
04458 slotChildCompleted( false );
04459 }
04460
04461 void KHTMLPart::slotChildCompleted( bool pendingAction )
04462 {
04463 khtml::ChildFrame *child = frame( sender() );
04464
04465 if ( child ) {
04466 kdDebug(6050) << this << " slotChildCompleted child=" << child << " m_frame=" << child->m_frame << endl;
04467 child->m_bCompleted = true;
04468 child->m_bPendingRedirection = pendingAction;
04469 child->m_args = KParts::URLArgs();
04470 }
04471 checkCompleted();
04472 }
04473
04474 void KHTMLPart::slotChildDocCreated()
04475 {
04476 const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
04477
04478
04479
04480 if ( d->m_doc && d->m_doc->isHTMLDocument() )
04481 {
04482 if ( sender()->inherits("KHTMLPart") )
04483 {
04484 DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
04485 if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
04486
04487 static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
04488 }
04489 }
04490
04491 disconnect( htmlFrame, SIGNAL( docCreated() ), this, SLOT( slotChildDocCreated() ) );
04492 }
04493
04494 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
04495 {
04496 khtml::ChildFrame *child = frame( sender()->parent() );
04497 KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
04498
04499
04500 QString urlStr = url.url();
04501 if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04502 QString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
04503 executeScript( DOM::Node(), script );
04504 return;
04505 }
04506
04507 QString frameName = args.frameName.lower();
04508 if ( !frameName.isEmpty() ) {
04509 if ( frameName == QString::fromLatin1( "_top" ) )
04510 {
04511 emit d->m_extension->openURLRequest( url, args );
04512 return;
04513 }
04514 else if ( frameName == QString::fromLatin1( "_blank" ) )
04515 {
04516 emit d->m_extension->createNewWindow( url, args );
04517 return;
04518 }
04519 else if ( frameName == QString::fromLatin1( "_parent" ) )
04520 {
04521 KParts::URLArgs newArgs( args );
04522 newArgs.frameName = QString::null;
04523
04524 emit d->m_extension->openURLRequest( url, newArgs );
04525 return;
04526 }
04527 else if ( frameName != QString::fromLatin1( "_self" ) )
04528 {
04529 khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
04530
04531 if ( !_frame )
04532 {
04533 emit d->m_extension->openURLRequest( url, args );
04534 return;
04535 }
04536
04537 child = _frame;
04538 }
04539 }
04540
04541 if ( child && child->m_type != khtml::ChildFrame::Object ) {
04542
04543 child->m_bNotify = true;
04544 requestObject( child, url, args );
04545 } else if ( frameName== "_self" )
04546 {
04547 KParts::URLArgs newArgs( args );
04548 newArgs.frameName = QString::null;
04549 emit d->m_extension->openURLRequest( url, newArgs );
04550 }
04551 }
04552
04553 void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
04554 {
04555 emit d->m_extension->requestFocus(this);
04556 }
04557
04558 khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
04559 {
04560 assert( obj->inherits( "KParts::ReadOnlyPart" ) );
04561 const KParts::ReadOnlyPart *part = static_cast<const KParts::ReadOnlyPart *>( obj );
04562
04563 FrameIt it = d->m_frames.begin();
04564 FrameIt end = d->m_frames.end();
04565 for (; it != end; ++it )
04566 if ( (KParts::ReadOnlyPart *)(*it).m_part == part )
04567 return &(*it);
04568
04569 for (it = d->m_objects.begin(); it != d->m_objects.end(); ++it )
04570 if ( (KParts::ReadOnlyPart *)(*it).m_part == part )
04571 return &(*it);
04572
04573 return 0L;
04574 }
04575
04576
04577
04578 bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
04579 {
04580 if (callingHtmlPart == this)
04581 return true;
04582
04583 if (htmlDocument().isNull()) {
04584 #ifdef DEBUG_FINDFRAME
04585 kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
04586 #endif
04587 return false;
04588 }
04589
04590
04591 if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
04592 !htmlDocument().isNull()) {
04593 DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
04594 DOM::DOMString destDomain = htmlDocument().domain();
04595
04596 #ifdef DEBUG_FINDFRAME
04597 kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
04598 #endif
04599
04600 if (actDomain == destDomain)
04601 return true;
04602 }
04603 #ifdef DEBUG_FINDFRAME
04604 else
04605 {
04606 kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
04607 }
04608 #endif
04609 return false;
04610 }
04611
04612 KHTMLPart *
04613 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
04614 {
04615 #ifdef DEBUG_FINDFRAME
04616 kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " name = " << name() << " findFrameParent( " << f << " )" << endl;
04617 #endif
04618
04619 KHTMLPart *callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
04620
04621 if (!checkFrameAccess(callingHtmlPart))
04622 return 0;
04623
04624 if (!childFrame && !parentPart() && (name() == f))
04625 return this;
04626
04627 FrameIt it = d->m_frames.find( f );
04628 FrameIt end = d->m_frames.end();
04629 if ( it != end )
04630 {
04631 #ifdef DEBUG_FINDFRAME
04632 kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
04633 #endif
04634 if (childFrame)
04635 *childFrame = &(*it);
04636 return this;
04637 }
04638
04639 it = d->m_frames.begin();
04640 for (; it != end; ++it )
04641 {
04642 KParts::ReadOnlyPart *p = (*it).m_part;
04643 if ( p && p->inherits( "KHTMLPart" ))
04644 {
04645 KHTMLPart *frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
04646 if (frameParent)
04647 return frameParent;
04648 }
04649 }
04650 return 0;
04651 }
04652
04653
04654 KHTMLPart *KHTMLPart::findFrame( const QString &f )
04655 {
04656 khtml::ChildFrame *childFrame;
04657 KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
04658 if (parentFrame)
04659 {
04660 KParts::ReadOnlyPart *p = childFrame->m_part;
04661 if ( p && p->inherits( "KHTMLPart" ))
04662 return static_cast<KHTMLPart *>(p);
04663 }
04664 return 0;
04665 }
04666
04667 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
04668 {
04669 KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
04670
04671
04672
04673 while ( part && part->inherits("KHTMLPart") &&
04674 static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
04675 KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
04676 part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
04677 if ( !part ) return frameset;
04678 }
04679 return part;
04680 }
04681
04682 bool KHTMLPart::frameExists( const QString &frameName )
04683 {
04684 ConstFrameIt it = d->m_frames.find( frameName );
04685 if ( it == d->m_frames.end() )
04686 return false;
04687
04688
04689
04690
04691 return (!(*it).m_frame.isNull());
04692 }
04693
04694 KHTMLPart *KHTMLPart::parentPart()
04695 {
04696 if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
04697 return 0L;
04698
04699 return (KHTMLPart *)parent();
04700 }
04701
04702 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
04703 const KParts::URLArgs &args, bool callParent )
04704 {
04705 #ifdef DEBUG_FINDFRAME
04706 kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
04707 #endif
04708 khtml::ChildFrame *childFrame;
04709 KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
04710 if (childPart)
04711 {
04712 if (childPart == this)
04713 return childFrame;
04714
04715 childPart->requestObject( childFrame, url, args );
04716 return 0;
04717 }
04718
04719 if ( parentPart() && callParent )
04720 {
04721 khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
04722
04723 if ( res )
04724 parentPart()->requestObject( res, url, args );
04725 }
04726
04727 return 0L;
04728 }
04729
04730 void KHTMLPart::saveState( QDataStream &stream )
04731 {
04732 kdDebug( 6050 ) << "KHTMLPart::saveState this = " << this << " saving URL " << m_url.url() << endl;
04733
04734 stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
04735 << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
04736
04737
04738 int focusNodeNumber;
04739 if (!d->m_focusNodeRestored)
04740 focusNodeNumber = d->m_focusNodeNumber;
04741 else if (d->m_doc && d->m_doc->focusNode())
04742 focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
04743 else
04744 focusNodeNumber = -1;
04745 stream << focusNodeNumber;
04746
04747
04748 stream << d->m_cacheId;
04749
04750
04751 QStringList docState;
04752 if (d->m_doc)
04753 {
04754 docState = d->m_doc->docState();
04755 }
04756 stream << d->m_encoding << d->m_sheetUsed << docState;
04757
04758 stream << d->m_zoomFactor;
04759
04760 stream << d->m_httpHeaders;
04761 stream << d->m_pageServices;
04762 stream << d->m_pageReferrer;
04763
04764
04765 stream << d->m_ssl_in_use
04766 << d->m_ssl_peer_certificate
04767 << d->m_ssl_peer_chain
04768 << d->m_ssl_peer_ip
04769 << d->m_ssl_cipher
04770 << d->m_ssl_cipher_desc
04771 << d->m_ssl_cipher_version
04772 << d->m_ssl_cipher_used_bits
04773 << d->m_ssl_cipher_bits
04774 << d->m_ssl_cert_state
04775 << d->m_ssl_parent_ip
04776 << d->m_ssl_parent_cert;
04777
04778
04779 QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
04780 KURL::List frameURLLst;
04781 QValueList<QByteArray> frameStateBufferLst;
04782
04783 ConstFrameIt it = d->m_frames.begin();
04784 ConstFrameIt end = d->m_frames.end();
04785 for (; it != end; ++it )
04786 {
04787 if ( !(*it).m_part )
04788 continue;
04789
04790 frameNameLst << (*it).m_name;
04791 frameServiceTypeLst << (*it).m_serviceType;
04792 frameServiceNameLst << (*it).m_serviceName;
04793 frameURLLst << (*it).m_part->url();
04794
04795 QByteArray state;
04796 QDataStream frameStream( state, IO_WriteOnly );
04797
04798 if ( (*it).m_extension )
04799 (*it).m_extension->saveState( frameStream );
04800
04801 frameStateBufferLst << state;
04802 }
04803
04804
04805 stream << (Q_UINT32) frameNameLst.count();
04806 stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
04807 }
04808
04809 void KHTMLPart::restoreState( QDataStream &stream )
04810 {
04811 KURL u;
04812 Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
04813 Q_UINT32 frameCount;
04814 QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
04815 KURL::List frameURLs;
04816 QValueList<QByteArray> frameStateBuffers;
04817 QValueList<int> fSizes;
04818 QString encoding, sheetUsed;
04819 long old_cacheId = d->m_cacheId;
04820
04821 stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
04822
04823 d->m_view->setMarginWidth( mWidth );
04824 d->m_view->setMarginHeight( mHeight );
04825
04826
04827
04828 stream >> d->m_focusNodeNumber;
04829 d->m_focusNodeRestored = false;
04830
04831 stream >> d->m_cacheId;
04832
04833 stream >> encoding >> sheetUsed >> docState;
04834
04835 d->m_encoding = encoding;
04836 d->m_sheetUsed = sheetUsed;
04837
04838 int zoomFactor;
04839 stream >> zoomFactor;
04840 setZoomFactor(zoomFactor);
04841
04842 stream >> d->m_httpHeaders;
04843 stream >> d->m_pageServices;
04844 stream >> d->m_pageReferrer;
04845
04846
04847 stream >> d->m_ssl_in_use
04848 >> d->m_ssl_peer_certificate
04849 >> d->m_ssl_peer_chain
04850 >> d->m_ssl_peer_ip
04851 >> d->m_ssl_cipher
04852 >> d->m_ssl_cipher_desc
04853 >> d->m_ssl_cipher_version
04854 >> d->m_ssl_cipher_used_bits
04855 >> d->m_ssl_cipher_bits
04856 >> d->m_ssl_cert_state
04857 >> d->m_ssl_parent_ip
04858 >> d->m_ssl_parent_cert;
04859
04860 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
04861
04862 stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
04863 >> frameURLs >> frameStateBuffers;
04864
04865 d->m_bComplete = false;
04866 d->m_bLoadEventEmitted = false;
04867
04868
04869
04870
04871
04872 if (d->m_cacheId == old_cacheId)
04873 {
04874
04875 d->m_redirectionTimer.stop();
04876
04877 FrameIt fIt = d->m_frames.begin();
04878 FrameIt fEnd = d->m_frames.end();
04879
04880 for (; fIt != fEnd; ++fIt )
04881 (*fIt).m_bCompleted = false;
04882
04883 fIt = d->m_frames.begin();
04884
04885 QStringList::ConstIterator fNameIt = frameNames.begin();
04886 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
04887 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
04888 KURL::List::ConstIterator fURLIt = frameURLs.begin();
04889 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
04890
04891 for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
04892 {
04893 khtml::ChildFrame *child = &(*fIt);
04894
04895
04896
04897 if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
04898 {
04899 child->m_bPreloaded = true;
04900 child->m_name = *fNameIt;
04901 child->m_serviceName = *fServiceNameIt;
04902 processObjectRequest( child, *fURLIt, *fServiceTypeIt );
04903 }
04904
04905 if ( child->m_part )
04906 {
04907 child->m_bCompleted = false;
04908 if ( child->m_extension && !(*fBufferIt).isEmpty() )
04909 {
04910 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
04911 child->m_extension->restoreState( frameStream );
04912 }
04913 else
04914 child->m_part->openURL( *fURLIt );
04915 }
04916 }
04917
04918 KParts::URLArgs args( d->m_extension->urlArgs() );
04919 args.xOffset = xOffset;
04920 args.yOffset = yOffset;
04921 args.docState = docState;
04922 d->m_extension->setURLArgs( args );
04923
04924 d->m_view->resizeContents( wContents, hContents);
04925 d->m_view->setContentsPos( xOffset, yOffset );
04926
04927 m_url = u;
04928 }
04929 else
04930 {
04931
04932 closeURL();
04933
04934
04935 d->m_bCleared = false;
04936 clear();
04937 d->m_encoding = encoding;
04938 d->m_sheetUsed = sheetUsed;
04939
04940 QStringList::ConstIterator fNameIt = frameNames.begin();
04941 QStringList::ConstIterator fNameEnd = frameNames.end();
04942
04943 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
04944 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
04945 KURL::List::ConstIterator fURLIt = frameURLs.begin();
04946 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
04947
04948 for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
04949 {
04950 khtml::ChildFrame newChild;
04951 newChild.m_bPreloaded = true;
04952 newChild.m_name = *fNameIt;
04953 newChild.m_serviceName = *fServiceNameIt;
04954
04955
04956
04957 FrameIt childFrame = d->m_frames.append( newChild );
04958
04959 processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
04960
04961 (*childFrame).m_bPreloaded = true;
04962
04963 if ( (*childFrame).m_part )
04964 {
04965 if ( (*childFrame).m_extension )
04966 if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
04967 {
04968 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
04969 (*childFrame).m_extension->restoreState( frameStream );
04970 }
04971 else
04972 (*childFrame).m_part->openURL( *fURLIt );
04973 }
04974 }
04975
04976 KParts::URLArgs args( d->m_extension->urlArgs() );
04977 args.xOffset = xOffset;
04978 args.yOffset = yOffset;
04979 args.docState = docState;
04980
04981 d->m_view->resizeContents( wContents, hContents);
04982 d->m_view->setContentsPos( xOffset, yOffset );
04983
04984 d->m_extension->setURLArgs( args );
04985 if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
04986 {
04987 d->m_restored = true;
04988 openURL( u );
04989 d->m_restored = false;
04990 }
04991 else
04992 {
04993 restoreURL( u );
04994 }
04995 }
04996
04997 }
04998
04999 void KHTMLPart::show()
05000 {
05001 if ( d->m_view )
05002 d->m_view->show();
05003 }
05004
05005 void KHTMLPart::hide()
05006 {
05007 if ( d->m_view )
05008 d->m_view->hide();
05009 }
05010
05011 DOM::Node KHTMLPart::nodeUnderMouse() const
05012 {
05013 return d->m_view->nodeUnderMouse();
05014 }
05015
05016 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
05017 {
05018 return d->m_view->nonSharedNodeUnderMouse();
05019 }
05020
05021 void KHTMLPart::emitSelectionChanged()
05022 {
05023 emit d->m_extension->enableAction( "copy", hasSelection() );
05024 if ( d->m_findDialog )
05025 d->m_findDialog->setHasSelection( hasSelection() );
05026
05027 emit d->m_extension->selectionInfo( selectedText() );
05028 emit selectionChanged();
05029 }
05030
05031 int KHTMLPart::zoomFactor() const
05032 {
05033 return d->m_zoomFactor;
05034 }
05035
05036
05037 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
05038 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
05039 static const int minZoom = 20;
05040 static const int maxZoom = 300;
05041
05042
05043 extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
05044 extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
05045
05046 void KHTMLPart::slotIncZoom()
05047 {
05048 zoomIn(zoomSizes, zoomSizeCount);
05049 }
05050
05051 void KHTMLPart::slotDecZoom()
05052 {
05053 zoomOut(zoomSizes, zoomSizeCount);
05054 }
05055
05056 void KHTMLPart::slotIncZoomFast()
05057 {
05058 zoomIn(fastZoomSizes, fastZoomSizeCount);
05059 }
05060
05061 void KHTMLPart::slotDecZoomFast()
05062 {
05063 zoomOut(fastZoomSizes, fastZoomSizeCount);
05064 }
05065
05066 void KHTMLPart::zoomIn(const int stepping[], int count)
05067 {
05068 int zoomFactor = d->m_zoomFactor;
05069
05070 if (zoomFactor < maxZoom) {
05071
05072 for (int i = 0; i < count; ++i)
05073 if (stepping[i] > zoomFactor) {
05074 zoomFactor = stepping[i];
05075 break;
05076 }
05077 setZoomFactor(zoomFactor);
05078 }
05079 }
05080
05081 void KHTMLPart::zoomOut(const int stepping[], int count)
05082 {
05083 int zoomFactor = d->m_zoomFactor;
05084 if (zoomFactor > minZoom) {
05085
05086 for (int i = count-1; i >= 0; --i)
05087 if (stepping[i] < zoomFactor) {
05088 zoomFactor = stepping[i];
05089 break;
05090 }
05091 setZoomFactor(zoomFactor);
05092 }
05093 }
05094
05095 void KHTMLPart::setZoomFactor (int percent)
05096 {
05097 if (percent < minZoom) percent = minZoom;
05098 if (percent > maxZoom) percent = maxZoom;
05099 if (d->m_zoomFactor == percent) return;
05100 d->m_zoomFactor = percent;
05101
05102 if(d->m_doc) {
05103 QApplication::setOverrideCursor( waitCursor );
05104 if (d->m_doc->styleSelector())
05105 d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
05106 d->m_doc->recalcStyle( NodeImpl::Force );
05107 QApplication::restoreOverrideCursor();
05108 }
05109
05110 ConstFrameIt it = d->m_frames.begin();
05111 ConstFrameIt end = d->m_frames.end();
05112 for (; it != end; ++it )
05113 if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
05114 KParts::ReadOnlyPart* p = ( *it ).m_part;
05115 static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
05116 }
05117
05118 if ( d->m_guiProfile == BrowserViewGUI ) {
05119 d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
05120 d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
05121 }
05122 }
05123
05124 void KHTMLPart::slotZoomView( int delta )
05125 {
05126 if ( delta < 0 )
05127 slotIncZoom();
05128 else
05129 slotDecZoom();
05130 }
05131
05132 void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
05133 {
05134 if (!d->m_statusMessagesEnabled)
05135 return;
05136
05137 d->m_statusBarText[p] = text;
05138
05139
05140 QString tobe = d->m_statusBarText[BarHoverText];
05141 if (tobe.isEmpty())
05142 tobe = d->m_statusBarText[BarOverrideText];
05143 if (tobe.isEmpty()) {
05144 tobe = d->m_statusBarText[BarDefaultText];
05145 if (!tobe.isEmpty() && d->m_jobspeed)
05146 tobe += " ";
05147 if (d->m_jobspeed)
05148 tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
05149 }
05150 tobe = "<qt>"+tobe;
05151
05152 emit ReadOnlyPart::setStatusBarText(tobe);
05153 }
05154
05155
05156 void KHTMLPart::setJSStatusBarText( const QString &text )
05157 {
05158 setStatusBarText(text, BarOverrideText);
05159 }
05160
05161 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
05162 {
05163 setStatusBarText(text, BarDefaultText);
05164 }
05165
05166 QString KHTMLPart::jsStatusBarText() const
05167 {
05168 return d->m_statusBarText[BarOverrideText];
05169 }
05170
05171 QString KHTMLPart::jsDefaultStatusBarText() const
05172 {
05173 return d->m_statusBarText[BarDefaultText];
05174 }
05175
05176 QString KHTMLPart::referrer() const
05177 {
05178 return d->m_referrer;
05179 }
05180
05181 QString KHTMLPart::pageReferrer() const
05182 {
05183 KURL referrerURL = KURL( d->m_pageReferrer );
05184 if (referrerURL.isValid())
05185 {
05186 QString protocol = referrerURL.protocol();
05187
05188 if ((protocol == "http") ||
05189 ((protocol == "https") && (m_url.protocol() == "https")))
05190 {
05191 referrerURL.setRef(QString::null);
05192 referrerURL.setUser(QString::null);
05193 referrerURL.setPass(QString::null);
05194 return referrerURL.url();
05195 }
05196 }
05197
05198 return QString::null;
05199 }
05200
05201
05202 QString KHTMLPart::lastModified() const
05203 {
05204 if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
05205
05206
05207
05208 QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
05209 d->m_lastModified = lastModif.toString( Qt::LocalDate );
05210 }
05211
05212 return d->m_lastModified;
05213 }
05214
05215 void KHTMLPart::slotLoadImages()
05216 {
05217 if (d->m_doc )
05218 d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
05219
05220 ConstFrameIt it = d->m_frames.begin();
05221 ConstFrameIt end = d->m_frames.end();
05222 for (; it != end; ++it )
05223 if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
05224 KParts::ReadOnlyPart* p = ( *it ).m_part;
05225 static_cast<KHTMLPart*>( p )->slotLoadImages();
05226 }
05227 }
05228
05229 void KHTMLPart::reparseConfiguration()
05230 {
05231 KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
05232 settings->init();
05233
05234 setAutoloadImages( settings->autoLoadImages() );
05235 if (d->m_doc)
05236 d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
05237
05238 d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
05239 d->m_bBackRightClick = settings->isBackRightClickEnabled();
05240 d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
05241 setDebugScript( settings->isJavaScriptDebugEnabled() );
05242 d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
05243 d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
05244 d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
05245
05246 delete d->m_settings;
05247 d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
05248
05249 QApplication::setOverrideCursor( waitCursor );
05250 khtml::CSSStyleSelector::reparseConfiguration();
05251 if(d->m_doc) d->m_doc->updateStyleSelector();
05252 QApplication::restoreOverrideCursor();
05253 }
05254
05255 QStringList KHTMLPart::frameNames() const
05256 {
05257 QStringList res;
05258
05259 ConstFrameIt it = d->m_frames.begin();
05260 ConstFrameIt end = d->m_frames.end();
05261 for (; it != end; ++it )
05262 if (!(*it).m_bPreloaded)
05263 res += (*it).m_name;
05264
05265 return res;
05266 }
05267
05268 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
05269 {
05270 QPtrList<KParts::ReadOnlyPart> res;
05271
05272 ConstFrameIt it = d->m_frames.begin();
05273 ConstFrameIt end = d->m_frames.end();
05274 for (; it != end; ++it )
05275 if (!(*it).m_bPreloaded)
05276 res.append( (*it).m_part );
05277
05278 return res;
05279 }
05280
05281 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
05282 {
05283 kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
05284 FrameIt it = d->m_frames.find( urlArgs.frameName );
05285
05286 if ( it == d->m_frames.end() )
05287 return false;
05288
05289
05290 if ( !urlArgs.lockHistory() )
05291 emit d->m_extension->openURLNotify();
05292
05293 requestObject( &(*it), url, urlArgs );
05294
05295 return true;
05296 }
05297
05298 void KHTMLPart::setDNDEnabled( bool b )
05299 {
05300 d->m_bDnd = b;
05301 }
05302
05303 bool KHTMLPart::dndEnabled() const
05304 {
05305 return d->m_bDnd;
05306 }
05307
05308 void KHTMLPart::customEvent( QCustomEvent *event )
05309 {
05310 if ( khtml::MousePressEvent::test( event ) )
05311 {
05312 khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
05313 return;
05314 }
05315
05316 if ( khtml::MouseDoubleClickEvent::test( event ) )
05317 {
05318 khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
05319 return;
05320 }
05321
05322 if ( khtml::MouseMoveEvent::test( event ) )
05323 {
05324 khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
05325 return;
05326 }
05327
05328 if ( khtml::MouseReleaseEvent::test( event ) )
05329 {
05330 khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
05331 return;
05332 }
05333
05334 if ( khtml::DrawContentsEvent::test( event ) )
05335 {
05336 khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
05337 return;
05338 }
05339
05340 KParts::ReadOnlyPart::customEvent( event );
05341 }
05342
05348 static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
05349 {
05350 for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
05351 if (n->isText()) {
05352 khtml::RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
05353 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05354 for (unsigned i = 0; i != runs.count(); i++) {
05355 if (runs[i]->m_y == y) {
05356 startNode = textRenderer->element();
05357 startOffset = runs[i]->m_start;
05358 return true;
05359 }
05360 }
05361 }
05362
05363 if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
05364 return true;
05365 }
05366 }
05367
05368 return false;
05369 }
05370
05376 static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
05377 {
05378 khtml::RenderObject *n = renderNode;
05379 if (!n) {
05380 return false;
05381 }
05382 khtml::RenderObject *next;
05383 while ((next = n->nextSibling())) {
05384 n = next;
05385 }
05386
05387 while (1) {
05388 if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
05389 return true;
05390 }
05391
05392 if (n->isText()) {
05393 khtml::RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
05394 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05395 for (int i = (int)runs.count()-1; i >= 0; i--) {
05396 if (runs[i]->m_y == y) {
05397 endNode = textRenderer->element();
05398 endOffset = runs[i]->m_start + runs[i]->m_len;
05399 return true;
05400 }
05401 }
05402 }
05403
05404 if (n == renderNode) {
05405 return false;
05406 }
05407
05408 n = n->previousSibling();
05409 }
05410 }
05411
05412 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
05413 {
05414 DOM::DOMString url = event->url();
05415 QMouseEvent *_mouse = event->qmouseEvent();
05416 DOM::Node innerNode = event->innerNode();
05417 d->m_mousePressNode = innerNode;
05418
05419 d->m_dragStartPos = _mouse->pos();
05420
05421 if ( !event->url().isNull() ) {
05422 d->m_strSelectedURL = event->url().string();
05423 d->m_strSelectedURLTarget = event->target().string();
05424 }
05425 else
05426 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05427
05428 if ( _mouse->button() == LeftButton ||
05429 _mouse->button() == MidButton )
05430 {
05431 d->m_bMousePressed = true;
05432
05433 #ifndef KHTML_NO_SELECTION
05434 if ( _mouse->button() == LeftButton )
05435 {
05436 if ( (!d->m_strSelectedURL.isNull() && !isEditable())
05437 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
05438 return;
05439 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05440 int offset = 0;
05441 DOM::NodeImpl* node = 0;
05442 khtml::RenderObject::SelPointState state;
05443 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05444 event->absX()-innerNode.handle()->renderer()->xPos(),
05445 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
05446 d->m_extendMode = d->ExtendByChar;
05447 #ifdef KHTML_NO_CARET
05448 d->m_selectionStart = node;
05449 d->m_startOffset = offset;
05450
05451
05452
05453
05454
05455 d->m_selectionEnd = d->m_selectionStart;
05456 d->m_endOffset = d->m_startOffset;
05457 d->m_doc->clearSelection();
05458 #else // KHTML_NO_CARET
05459 d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
05460 #endif // KHTML_NO_CARET
05461 d->m_initialNode = d->m_selectionStart;
05462 d->m_initialOffset = d->m_startOffset;
05463
05464 }
05465 else
05466 {
05467 #ifndef KHTML_NO_CARET
05468
05469 #else
05470 d->m_selectionStart = DOM::Node();
05471 d->m_selectionEnd = DOM::Node();
05472 #endif
05473 }
05474 emitSelectionChanged();
05475 startAutoScroll();
05476 }
05477 #else
05478 d->m_dragLastPos = _mouse->globalPos();
05479 #endif
05480 }
05481
05482 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
05483 {
05484 d->m_bRightMousePressed = true;
05485 } else if ( _mouse->button() == RightButton )
05486 {
05487 popupMenu( d->m_strSelectedURL );
05488
05489 }
05490 }
05491
05492 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
05493 {
05494 QMouseEvent *_mouse = event->qmouseEvent();
05495 if ( _mouse->button() == LeftButton )
05496 {
05497 d->m_bMousePressed = true;
05498 DOM::Node innerNode = event->innerNode();
05499
05500 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05501 int offset = 0;
05502 DOM::NodeImpl* node = 0;
05503 khtml::RenderObject::SelPointState state;
05504 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05505 event->absX()-innerNode.handle()->renderer()->xPos(),
05506 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);
05507
05508
05509
05510 if ( node && node->renderer() )
05511 {
05512
05513 bool selectLine = (event->clickCount() == 3);
05514 d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;
05515
05516
05517 if (_mouse->state() & ShiftButton) {
05518 d->caretNode() = node;
05519 d->caretOffset() = offset;
05520 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05521 d->m_selectionStart.handle(), d->m_startOffset,
05522 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05523 d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
05524 d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
05525 } else {
05526 d->m_selectionStart = d->m_selectionEnd = node;
05527 d->m_startOffset = d->m_endOffset = offset;
05528 d->m_startBeforeEnd = true;
05529 d->m_initialNode = node;
05530 d->m_initialOffset = offset;
05531 }
05532
05533
05534
05535 extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
05536
05537 extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );
05538
05539
05540
05541
05542 emitSelectionChanged();
05543 d->m_doc
05544 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
05545 d->m_selectionEnd.handle(),d->m_endOffset);
05546 #ifndef KHTML_NO_CARET
05547 bool v = d->m_view->placeCaret();
05548 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
05549 #endif
05550 startAutoScroll();
05551 }
05552 }
05553 }
05554 }
05555
05556 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
05557 {
05558 khtml::RenderObject* obj = node->renderer();
05559
05560 if (obj->isText() && selectLines) {
05561 int pos;
05562 khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
05563 khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
05564 DOMString t = node->nodeValue();
05565 DOM::NodeImpl* selNode = 0;
05566 long selOfs = 0;
05567
05568 if (!run)
05569 return;
05570
05571 int selectionPointY = run->m_y;
05572
05573
05574 khtml::RenderObject *renderNode = renderer;
05575 while (renderNode && renderNode->isInline())
05576 renderNode = renderNode->parent();
05577
05578 renderNode = renderNode->firstChild();
05579
05580 if (right) {
05581
05582
05583 if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
05584 return;
05585 } else {
05586
05587
05588 if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
05589 return;
05590 }
05591
05592 selectionNode = selNode;
05593 selectionOffset = selOfs;
05594 return;
05595 }
05596
05597 QString str;
05598 int len = 0;
05599 if ( obj->isText() ) {
05600 str = static_cast<khtml::RenderText *>(obj)->data().string();
05601 len = str.length();
05602 }
05603
05604 QChar ch;
05605 do {
05606
05607 if ( node ) {
05608 selectionNode = node;
05609 selectionOffset = offset;
05610 }
05611
05612
05613 while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
05614 {
05615 obj = right ? obj->objectBelow() : obj->objectAbove();
05616
05617 if ( obj ) {
05618
05619 str = QString::null;
05620 if ( obj->isText() )
05621 str = static_cast<khtml::RenderText *>(obj)->data().string();
05622 else if ( obj->isBR() )
05623 str = '\n';
05624 else if ( !obj->isInline() ) {
05625 obj = 0L;
05626 break;
05627 }
05628 len = str.length();
05629
05630
05631 if ( right )
05632 offset = -1;
05633 else
05634 offset = len;
05635 }
05636 }
05637 if ( !obj )
05638 break;
05639 node = obj->element();
05640 if ( right )
05641 {
05642 Q_ASSERT( offset < len-1 );
05643 offset++;
05644 }
05645 else
05646 {
05647 Q_ASSERT( offset > 0 );
05648 offset--;
05649 }
05650
05651
05652 ch = str[ offset ];
05653
05654 } while ( !ch.isSpace() && !ch.isPunct() );
05655
05656
05657 if (right) selectionOffset++;
05658 }
05659
05660 #ifndef KHTML_NO_SELECTION
05661 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
05662 {
05663 int offset;
05664
05665 DOM::NodeImpl* node=0;
05666 khtml::RenderObject::SelPointState state;
05667 innerNode.handle()->renderer()->checkSelectionPoint( x, y,
05668 absX-innerNode.handle()->renderer()->xPos(),
05669 absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
05670 if (!node || !node->renderer()) return;
05671
05672
05673
05674
05675 bool withinNode = innerNode == node;
05676
05677
05678
05679 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
05680 d->m_initialNode.isNull() ||
05681 !d->m_selectionStart.handle()->renderer() ||
05682 !d->m_selectionEnd.handle()->renderer()) return;
05683
05684 if (d->m_extendMode != d->ExtendByChar) {
05685
05686 bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
05687 d->caretNode().handle(), d->caretOffset(),
05688 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
05689 bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
05690 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
05691
05692 if (caretBeforeInit != nodeBeforeInit) {
05693
05694 extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
05695 d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
05696 d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
05697 nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
05698 }
05699 }
05700
05701 d->caretNode() = node;
05702 d->caretOffset() = offset;
05703
05704
05705 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05706 d->m_selectionStart.handle(), d->m_startOffset,
05707 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05708
05709 if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
05710 {
05711
05712 if (d->m_extendMode != d->ExtendByChar && withinNode)
05713 extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );
05714
05715 if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
05716 d->m_doc
05717 ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
05718 d->m_selectionEnd.handle(),d->m_startOffset);
05719 else if (d->m_startBeforeEnd)
05720 d->m_doc
05721 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
05722 d->m_selectionEnd.handle(),d->m_endOffset);
05723 else
05724 d->m_doc
05725 ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
05726 d->m_selectionStart.handle(),d->m_startOffset);
05727 }
05728 #ifndef KHTML_NO_CARET
05729 d->m_view->placeCaret();
05730 #endif
05731 }
05732
05733 bool KHTMLPart::isExtendingSelection() const
05734 {
05735
05736
05737
05738 return d->m_bMousePressed;
05739 }
05740 #endif // KHTML_NO_SELECTION
05741
05742 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
05743 {
05744 QMouseEvent *_mouse = event->qmouseEvent();
05745
05746 if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
05747 {
05748 popupMenu( d->m_strSelectedURL );
05749 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05750 d->m_bRightMousePressed = false;
05751 }
05752
05753 DOM::DOMString url = event->url();
05754 DOM::DOMString target = event->target();
05755 DOM::Node innerNode = event->innerNode();
05756
05757 #ifndef QT_NO_DRAGANDDROP
05758 if( d->m_bDnd && d->m_bMousePressed &&
05759 ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
05760 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
05761 if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
05762 return;
05763
05764 QPixmap pix;
05765 HTMLImageElementImpl *img = 0L;
05766 QDragObject *drag = 0;
05767 KURL u;
05768
05769
05770
05771
05772
05773 if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
05774 {
05775 img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
05776 u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
05777 pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
05778 }
05779 else
05780 {
05781
05782 u = completeURL( d->m_strSelectedURL );
05783 pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
05784 }
05785
05786 u.setPass(QString::null);
05787
05788 KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
05789 if ( !d->m_referrer.isEmpty() )
05790 urlDrag->metaData()["referrer"] = d->m_referrer;
05791
05792 if( img ) {
05793 KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
05794 mdrag->addDragObject( new QImageDrag( img->currentImage(), 0L ) );
05795 mdrag->addDragObject( urlDrag );
05796 drag = mdrag;
05797 }
05798 else
05799 drag = urlDrag;
05800
05801 if ( !pix.isNull() )
05802 drag->setPixmap( pix );
05803
05804 stopAutoScroll();
05805 if(drag)
05806 drag->drag();
05807
05808
05809 d->m_bMousePressed = false;
05810 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05811 return;
05812 }
05813 #endif
05814
05815
05816 if ( !d->m_bMousePressed )
05817 {
05818
05819 if ( url.length() )
05820 {
05821 bool shiftPressed = ( _mouse->state() & ShiftButton );
05822
05823
05824 if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
05825 {
05826 HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
05827 if ( i && i->isServerMap() )
05828 {
05829 khtml::RenderObject *r = i->renderer();
05830 if(r)
05831 {
05832 int absx, absy, vx, vy;
05833 r->absolutePosition(absx, absy);
05834 view()->contentsToViewport( absx, absy, vx, vy );
05835
05836 int x(_mouse->x() - vx), y(_mouse->y() - vy);
05837
05838 d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
05839 d->m_overURLTarget = target.string();
05840 overURL( d->m_overURL, target.string(), shiftPressed );
05841 return;
05842 }
05843 }
05844 }
05845
05846
05847 if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
05848 {
05849 d->m_overURL = url.string();
05850 d->m_overURLTarget = target.string();
05851 overURL( d->m_overURL, target.string(), shiftPressed );
05852 }
05853 }
05854 else
05855 {
05856 if( !d->m_overURL.isEmpty() )
05857 {
05858 d->m_overURL = d->m_overURLTarget = QString::null;
05859 emit onURL( QString::null );
05860
05861 setStatusBarText(QString::null, BarHoverText);
05862 emit d->m_extension->mouseOverInfo(0);
05863 }
05864 }
05865 }
05866 else {
05867 #ifndef KHTML_NO_SELECTION
05868
05869 if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
05870 ( (_mouse->state() & LeftButton) != 0 )) {
05871 extendSelectionTo(event->x(), event->y(),
05872 event->absX(), event->absY(), innerNode);
05873 #else
05874 if ( d->m_doc && d->m_view ) {
05875 QPoint diff( _mouse->globalPos() - d->m_dragLastPos );
05876
05877 if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
05878 d->m_view->scrollBy( -diff.x(), -diff.y() );
05879 d->m_dragLastPos = _mouse->globalPos();
05880 }
05881 #endif
05882 }
05883 }
05884
05885 }
05886
05887 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
05888 {
05889 DOM::Node innerNode = event->innerNode();
05890 d->m_mousePressNode = DOM::Node();
05891
05892 if ( d->m_bMousePressed ) {
05893 setStatusBarText(QString::null, BarHoverText);
05894 stopAutoScroll();
05895 }
05896
05897
05898
05899 d->m_bMousePressed = false;
05900
05901 QMouseEvent *_mouse = event->qmouseEvent();
05902 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
05903 {
05904 d->m_bRightMousePressed = false;
05905 KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
05906 if( tmp_iface ) {
05907 tmp_iface->callMethod( "goHistory(int)", -1 );
05908 }
05909 }
05910 #ifndef QT_NO_CLIPBOARD
05911 if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull())) {
05912 kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
05913 << d->m_bOpenMiddleClick << endl;
05914
05915 if (d->m_bOpenMiddleClick) {
05916 KHTMLPart *p = this;
05917 while (p->parentPart()) p = p->parentPart();
05918 p->d->m_extension->pasteRequest();
05919 }
05920 }
05921 #endif
05922
05923 #ifndef KHTML_NO_SELECTION
05924
05925 if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
05926 #ifndef KHTML_NO_CARET
05927 d->m_extendAtEnd = true;
05928 #else
05929 d->m_selectionStart = 0;
05930 d->m_selectionEnd = 0;
05931 d->m_startOffset = 0;
05932 d->m_endOffset = 0;
05933 #endif
05934 emitSelectionChanged();
05935 } else {
05936
05937
05938 DOM::Node n = d->m_selectionStart;
05939 d->m_startBeforeEnd = false;
05940 if( d->m_selectionStart == d->m_selectionEnd ) {
05941 if( d->m_startOffset < d->m_endOffset )
05942 d->m_startBeforeEnd = true;
05943 } else {
05944 #if 0
05945 while(!n.isNull()) {
05946 if(n == d->m_selectionEnd) {
05947 d->m_startBeforeEnd = true;
05948 break;
05949 }
05950 DOM::Node next = n.firstChild();
05951 if(next.isNull()) next = n.nextSibling();
05952 while( next.isNull() && !n.parentNode().isNull() ) {
05953 n = n.parentNode();
05954 next = n.nextSibling();
05955 }
05956 n = next;
05957 }
05958 #else
05959
05960 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
05961 !d->m_selectionStart.handle()->renderer() ||
05962 !d->m_selectionEnd.handle()->renderer()) return;
05963 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05964 d->m_selectionStart.handle(), d->m_startOffset,
05965 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05966 #endif
05967 }
05968 if(!d->m_startBeforeEnd)
05969 {
05970 DOM::Node tmpNode = d->m_selectionStart;
05971 int tmpOffset = d->m_startOffset;
05972 d->m_selectionStart = d->m_selectionEnd;
05973 d->m_startOffset = d->m_endOffset;
05974 d->m_selectionEnd = tmpNode;
05975 d->m_endOffset = tmpOffset;
05976 d->m_startBeforeEnd = true;
05977 d->m_extendAtEnd = !d->m_extendAtEnd;
05978 }
05979 #ifndef KHTML_NO_CARET
05980 bool v = d->m_view->placeCaret();
05981 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
05982 #endif
05983
05984 #ifndef QT_NO_CLIPBOARD
05985 QString text = selectedText();
05986 text.replace(QChar(0xa0), ' ');
05987 disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
05988 kapp->clipboard()->setText(text,QClipboard::Selection);
05989 connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
05990 #endif
05991
05992 emitSelectionChanged();
05993
05994 }
05995 #endif
05996 d->m_initialNode = 0;
05997 d->m_initialOffset = 0;
05998
05999 }
06000
06001 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
06002 {
06003 }
06004
06005 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
06006 {
06007 if ( event->activated() )
06008 {
06009 emitSelectionChanged();
06010 emit d->m_extension->enableAction( "print", d->m_doc != 0 );
06011
06012 if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
06013 {
06014 QPtrList<KAction> lst;
06015 lst.append( d->m_paLoadImages );
06016 plugActionList( "loadImages", lst );
06017 }
06018 }
06019 }
06020
06021 void KHTMLPart::slotPrintFrame()
06022 {
06023 if ( d->m_frames.count() == 0 )
06024 return;
06025
06026 KParts::ReadOnlyPart *frame = currentFrame();
06027 if (!frame)
06028 return;
06029
06030 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
06031
06032 if ( !ext )
06033 return;
06034
06035 QMetaObject *mo = ext->metaObject();
06036
06037 int idx = mo->findSlot( "print()", true );
06038 if ( idx >= 0 ) {
06039 QUObject o[ 1 ];
06040 ext->qt_invoke( idx, o );
06041 }
06042 }
06043
06044 void KHTMLPart::slotSelectAll()
06045 {
06046 KParts::ReadOnlyPart *part = currentFrame();
06047 if (part && part->inherits("KHTMLPart"))
06048 static_cast<KHTMLPart *>(part)->selectAll();
06049 }
06050
06051 void KHTMLPart::startAutoScroll()
06052 {
06053 connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06054 d->m_scrollTimer.start(100, false);
06055 }
06056
06057 void KHTMLPart::stopAutoScroll()
06058 {
06059 disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06060 if (d->m_scrollTimer.isActive())
06061 d->m_scrollTimer.stop();
06062 }
06063
06064
06065 void KHTMLPart::slotAutoScroll()
06066 {
06067 if (d->m_view)
06068 d->m_view->doAutoScroll();
06069 else
06070 stopAutoScroll();
06071 }
06072
06073 void KHTMLPart::selectAll()
06074 {
06075 if (!d->m_doc) return;
06076
06077 NodeImpl *first;
06078 if (d->m_doc->isHTMLDocument())
06079 first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06080 else
06081 first = d->m_doc;
06082 NodeImpl *next;
06083
06084
06085
06086 while ( first && !(first->renderer()
06087 && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
06088 || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
06089 {
06090 next = first->firstChild();
06091 if ( !next ) next = first->nextSibling();
06092 while( first && !next )
06093 {
06094 first = first->parentNode();
06095 if ( first )
06096 next = first->nextSibling();
06097 }
06098 first = next;
06099 }
06100
06101 NodeImpl *last;
06102 if (d->m_doc->isHTMLDocument())
06103 last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06104 else
06105 last = d->m_doc;
06106
06107
06108
06109
06110 while ( last && !(last->renderer()
06111 && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
06112 || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
06113 {
06114 next = last->lastChild();
06115 if ( !next ) next = last->previousSibling();
06116 while ( last && !next )
06117 {
06118 last = last->parentNode();
06119 if ( last )
06120 next = last->previousSibling();
06121 }
06122 last = next;
06123 }
06124
06125 if ( !first || !last )
06126 return;
06127 Q_ASSERT(first->renderer());
06128 Q_ASSERT(last->renderer());
06129 d->m_selectionStart = first;
06130 d->m_startOffset = 0;
06131 d->m_selectionEnd = last;
06132 d->m_endOffset = last->nodeValue().length();
06133 d->m_startBeforeEnd = true;
06134
06135 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
06136 d->m_selectionEnd.handle(), d->m_endOffset );
06137
06138 emitSelectionChanged();
06139 }
06140
06141 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
06142 {
06143 bool linkAllowed = true;
06144
06145 if ( d->m_doc )
06146 linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);
06147
06148 if ( !linkAllowed ) {
06149 khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
06150 if (tokenizer)
06151 tokenizer->setOnHold(true);
06152
06153 int response = KMessageBox::Cancel;
06154 if (!message.isEmpty())
06155 {
06156 response = KMessageBox::warningContinueCancel( 0,
06157 message.arg(linkURL.htmlURL()),
06158 i18n( "Security Warning" ),
06159 button);
06160 }
06161 else
06162 {
06163 KMessageBox::error( 0,
06164 i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
06165 i18n( "Security Alert" ));
06166 }
06167
06168 if (tokenizer)
06169 tokenizer->setOnHold(false);
06170 return (response==KMessageBox::Continue);
06171 }
06172 return true;
06173 }
06174
06175 void KHTMLPart::slotPartRemoved( KParts::Part *part )
06176 {
06177
06178 if ( part == d->m_activeFrame )
06179 {
06180 d->m_activeFrame = 0L;
06181 if ( !part->inherits( "KHTMLPart" ) )
06182 {
06183 if (factory()) {
06184 factory()->removeClient( part );
06185 }
06186 if (childClients()->containsRef(part)) {
06187 removeChildClient( part );
06188 }
06189 }
06190 }
06191 }
06192
06193 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
06194 {
06195
06196 if ( part == this )
06197 {
06198 kdError(6050) << "strange error! we activated ourselves" << endl;
06199 assert( false );
06200 return;
06201 }
06202
06203 if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06204 {
06205 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06206 if (frame->frameStyle() != QFrame::NoFrame)
06207 {
06208 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
06209 frame->repaint();
06210 }
06211 }
06212
06213 if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
06214 {
06215 if (factory()) {
06216 factory()->removeClient( d->m_activeFrame );
06217 }
06218 removeChildClient( d->m_activeFrame );
06219 }
06220 if( part && !part->inherits( "KHTMLPart" ) )
06221 {
06222 if (factory()) {
06223 factory()->addClient( part );
06224 }
06225 insertChildClient( part );
06226 }
06227
06228
06229 d->m_activeFrame = part;
06230
06231 if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06232 {
06233 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06234 if (frame->frameStyle() != QFrame::NoFrame)
06235 {
06236 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
06237 frame->repaint();
06238 }
06239 kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
06240 }
06241
06242 updateActions();
06243
06244
06245 d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
06246 }
06247
06248 void KHTMLPart::setActiveNode(const DOM::Node &node)
06249 {
06250 if (!d->m_doc || !d->m_view)
06251 return;
06252
06253
06254 d->m_doc->setFocusNode(node.handle());
06255
06256
06257 QRect rect = node.handle()->getRect();
06258 d->m_view->ensureVisible(rect.right(), rect.bottom());
06259 d->m_view->ensureVisible(rect.left(), rect.top());
06260 }
06261
06262 DOM::Node KHTMLPart::activeNode() const
06263 {
06264 return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
06265 }
06266
06267 DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code, QString name )
06268 {
06269 KJSProxy *proxy = jScript();
06270
06271 if (!proxy)
06272 return 0;
06273
06274 return proxy->createHTMLEventHandler( m_url.url(), name, code );
06275 }
06276
06277 KHTMLPart *KHTMLPart::opener()
06278 {
06279 return d->m_opener;
06280 }
06281
06282 void KHTMLPart::setOpener(KHTMLPart *_opener)
06283 {
06284 d->m_opener = _opener;
06285 }
06286
06287 bool KHTMLPart::openedByJS()
06288 {
06289 return d->m_openedByJS;
06290 }
06291
06292 void KHTMLPart::setOpenedByJS(bool _openedByJS)
06293 {
06294 d->m_openedByJS = _openedByJS;
06295 }
06296
06297 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
06298 {
06299 khtml::Cache::preloadStyleSheet(url, stylesheet);
06300 }
06301
06302 void KHTMLPart::preloadScript(const QString &url, const QString &script)
06303 {
06304 khtml::Cache::preloadScript(url, script);
06305 }
06306
06307 QCString KHTMLPart::dcopObjectId() const
06308 {
06309 QCString id;
06310 id.sprintf("html-widget%d", d->m_dcop_counter);
06311 return id;
06312 }
06313
06314 long KHTMLPart::cacheId() const
06315 {
06316 return d->m_cacheId;
06317 }
06318
06319 bool KHTMLPart::restored() const
06320 {
06321 return d->m_restored;
06322 }
06323
06324 bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
06325 {
06326
06327 KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
06328 if ( parent )
06329 return parent->pluginPageQuestionAsked(mimetype);
06330
06331 return d->m_pluginPageQuestionAsked.contains(mimetype);
06332 }
06333
06334 void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
06335 {
06336 if ( parentPart() )
06337 parentPart()->setPluginPageQuestionAsked(mimetype);
06338
06339 d->m_pluginPageQuestionAsked.append(mimetype);
06340 }
06341
06342 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
06343 {
06344 d->m_automaticDetection->setItemChecked( _id, true );
06345
06346 switch ( _id ) {
06347 case 0 :
06348 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06349 break;
06350 case 1 :
06351 d->m_autoDetectLanguage = khtml::Decoder::Arabic;
06352 break;
06353 case 2 :
06354 d->m_autoDetectLanguage = khtml::Decoder::Baltic;
06355 break;
06356 case 3 :
06357 d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
06358 break;
06359 case 4 :
06360 d->m_autoDetectLanguage = khtml::Decoder::Chinese;
06361 break;
06362 case 5 :
06363 d->m_autoDetectLanguage = khtml::Decoder::Greek;
06364 break;
06365 case 6 :
06366 d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
06367 break;
06368 case 7 :
06369 d->m_autoDetectLanguage = khtml::Decoder::Japanese;
06370 break;
06371 case 8 :
06372 d->m_autoDetectLanguage = khtml::Decoder::Korean;
06373 break;
06374 case 9 :
06375 d->m_autoDetectLanguage = khtml::Decoder::Russian;
06376 break;
06377 case 10 :
06378 d->m_autoDetectLanguage = khtml::Decoder::Thai;
06379 break;
06380 case 11 :
06381 d->m_autoDetectLanguage = khtml::Decoder::Turkish;
06382 break;
06383 case 12 :
06384 d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
06385 break;
06386 case 13 :
06387 d->m_autoDetectLanguage = khtml::Decoder::Unicode;
06388 break;
06389 case 14 :
06390 d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
06391 break;
06392 default :
06393 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06394 break;
06395 }
06396
06397 for ( int i = 0; i <= 14; ++i ) {
06398 if ( i != _id )
06399 d->m_automaticDetection->setItemChecked( i, false );
06400 }
06401
06402 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
06403
06404 setEncoding( QString::null, false );
06405
06406 if( d->m_manualDetection )
06407 d->m_manualDetection->setCurrentItem( -1 );
06408 d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
06409 }
06410
06411 khtml::Decoder *KHTMLPart::createDecoder()
06412 {
06413 khtml::Decoder *dec = new khtml::Decoder();
06414 if( !d->m_encoding.isNull() )
06415 dec->setEncoding( d->m_encoding.latin1(), true );
06416 else
06417 dec->setEncoding( defaultEncoding().latin1(), d->m_haveEncoding );
06418
06419 dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
06420 return dec;
06421 }
06422
06423 void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
06424 emit caretPositionChanged(node, offset);
06425 }
06426
06427 void KHTMLPart::restoreScrollPosition()
06428 {
06429 KParts::URLArgs args = d->m_extension->urlArgs();
06430 if (!args.reload) {
06431 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06432 return;
06433 }
06434
06435
06436
06437
06438
06439 if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
06440 || d->m_bComplete) {
06441 d->m_view->setContentsPos(args.xOffset, args.yOffset);
06442 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06443 }
06444 }
06445
06446 KWallet::Wallet* KHTMLPart::wallet()
06447 {
06448
06449
06450
06451
06452
06453 KHTMLPart* p;
06454
06455 for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
06456 ;
06457
06458 if (p)
06459 return p->wallet();
06460
06461 if (!d->m_wallet && !d->m_bWalletOpened) {
06462 d->m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0);
06463 d->m_bWalletOpened = true;
06464 if (d->m_wallet) {
06465 connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));
06466 d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
06467 d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
06468 d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
06469 d->m_statusBarWalletLabel->setUseCursor(false);
06470 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
06471 QToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
06472 d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
06473 connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedURL()), SLOT(launchWalletManager()));
06474 connect(d->m_statusBarWalletLabel, SIGNAL(rightClickedURL()), SLOT(walletMenu()));
06475 } else if (d->m_statusBarWalletLabel) {
06476 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
06477 delete d->m_statusBarWalletLabel;
06478 d->m_statusBarWalletLabel = 0L;
06479 }
06480 }
06481 return d->m_wallet;
06482 }
06483
06484 void KHTMLPart::slotWalletClosed()
06485 {
06486 if (d->m_wallet) {
06487 d->m_wallet->deleteLater();
06488 d->m_wallet = 0L;
06489 }
06490 d->m_bWalletOpened = false;
06491 if (d->m_statusBarWalletLabel) {
06492 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
06493 delete d->m_statusBarWalletLabel;
06494 d->m_statusBarWalletLabel = 0L;
06495 }
06496 }
06497
06498 void KHTMLPart::launchWalletManager()
06499 {
06500 if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
06501 KApplication::startServiceByDesktopName("kwalletmanager_show");
06502 } else {
06503 DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
06504 r.send("show");
06505 r.send("raise");
06506 }
06507 }
06508
06509 void KHTMLPart::walletMenu()
06510 {
06511 KPopupMenu *m = new KPopupMenu(0L);
06512 m->insertItem(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
06513 m->popup(QCursor::pos());
06514 }
06515
06516 void KHTMLPart::slotToggleCaretMode()
06517 {
06518 setCaretMode(d->m_paToggleCaretMode->isChecked());
06519 }
06520
06521 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
06522 d->m_formNotification = fn;
06523 }
06524
06525 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
06526 return d->m_formNotification;
06527 }
06528
06529 KURL KHTMLPart::toplevelURL()
06530 {
06531 KHTMLPart* part = this;
06532 while (part->parentPart())
06533 part = part->parentPart();
06534
06535 if (!part)
06536 return KURL();
06537
06538 return part->url();
06539 }
06540
06541 bool KHTMLPart::isModified() const
06542 {
06543 if ( !d->m_doc )
06544 return false;
06545
06546 return d->m_doc->unsubmittedFormChanges();
06547 }
06548
06549 void KHTMLPart::setDebugScript( bool enable )
06550 {
06551 unplugActionList( "debugScriptList" );
06552 if ( enable ) {
06553 if (!d->m_paDebugScript) {
06554 d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
06555 }
06556 d->m_paDebugScript->setEnabled( d->m_jscript );
06557 QPtrList<KAction> lst;
06558 lst.append( d->m_paDebugScript );
06559 plugActionList( "debugScriptList", lst );
06560 }
06561 d->m_bJScriptDebugEnabled = enable;
06562 }
06563
06564 using namespace KParts;
06565 #include "khtml_part.moc"