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 << " findFrameParent( " << f << " )" << endl;
04617 #endif
04618
04619 KHTMLPart *callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
04620
04621 if (!checkFrameAccess(callingHtmlPart))
04622 return 0;
04623
04624 FrameIt it = d->m_frames.find( f );
04625 FrameIt end = d->m_frames.end();
04626 if ( it != end )
04627 {
04628 #ifdef DEBUG_FINDFRAME
04629 kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
04630 #endif
04631 if (childFrame)
04632 *childFrame = &(*it);
04633 return this;
04634 }
04635
04636 it = d->m_frames.begin();
04637 for (; it != end; ++it )
04638 {
04639 KParts::ReadOnlyPart *p = (*it).m_part;
04640 if ( p && p->inherits( "KHTMLPart" ))
04641 {
04642 KHTMLPart *frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
04643 if (frameParent)
04644 return frameParent;
04645 }
04646 }
04647 return 0;
04648 }
04649
04650
04651 KHTMLPart *KHTMLPart::findFrame( const QString &f )
04652 {
04653 khtml::ChildFrame *childFrame;
04654 KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
04655 if (parentFrame)
04656 {
04657 KParts::ReadOnlyPart *p = childFrame->m_part;
04658 if ( p && p->inherits( "KHTMLPart" ))
04659 return static_cast<KHTMLPart *>(p);
04660 }
04661 return 0;
04662 }
04663
04664 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
04665 {
04666 KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
04667
04668
04669
04670 while ( part && part->inherits("KHTMLPart") &&
04671 static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
04672 KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
04673 part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
04674 if ( !part ) return frameset;
04675 }
04676 return part;
04677 }
04678
04679 bool KHTMLPart::frameExists( const QString &frameName )
04680 {
04681 ConstFrameIt it = d->m_frames.find( frameName );
04682 if ( it == d->m_frames.end() )
04683 return false;
04684
04685
04686
04687
04688 return (!(*it).m_frame.isNull());
04689 }
04690
04691 KHTMLPart *KHTMLPart::parentPart()
04692 {
04693 if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
04694 return 0L;
04695
04696 return (KHTMLPart *)parent();
04697 }
04698
04699 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
04700 const KParts::URLArgs &args, bool callParent )
04701 {
04702 #ifdef DEBUG_FINDFRAME
04703 kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
04704 #endif
04705 khtml::ChildFrame *childFrame;
04706 KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
04707 if (childPart)
04708 {
04709 if (childPart == this)
04710 return childFrame;
04711
04712 childPart->requestObject( childFrame, url, args );
04713 return 0;
04714 }
04715
04716 if ( parentPart() && callParent )
04717 {
04718 khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
04719
04720 if ( res )
04721 parentPart()->requestObject( res, url, args );
04722 }
04723
04724 return 0L;
04725 }
04726
04727 void KHTMLPart::saveState( QDataStream &stream )
04728 {
04729 kdDebug( 6050 ) << "KHTMLPart::saveState this = " << this << " saving URL " << m_url.url() << endl;
04730
04731 stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
04732 << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
04733
04734
04735 int focusNodeNumber;
04736 if (!d->m_focusNodeRestored)
04737 focusNodeNumber = d->m_focusNodeNumber;
04738 else if (d->m_doc && d->m_doc->focusNode())
04739 focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
04740 else
04741 focusNodeNumber = -1;
04742 stream << focusNodeNumber;
04743
04744
04745 stream << d->m_cacheId;
04746
04747
04748 QStringList docState;
04749 if (d->m_doc)
04750 {
04751 docState = d->m_doc->docState();
04752 }
04753 stream << d->m_encoding << d->m_sheetUsed << docState;
04754
04755 stream << d->m_zoomFactor;
04756
04757 stream << d->m_httpHeaders;
04758 stream << d->m_pageServices;
04759 stream << d->m_pageReferrer;
04760
04761
04762 stream << d->m_ssl_in_use
04763 << d->m_ssl_peer_certificate
04764 << d->m_ssl_peer_chain
04765 << d->m_ssl_peer_ip
04766 << d->m_ssl_cipher
04767 << d->m_ssl_cipher_desc
04768 << d->m_ssl_cipher_version
04769 << d->m_ssl_cipher_used_bits
04770 << d->m_ssl_cipher_bits
04771 << d->m_ssl_cert_state
04772 << d->m_ssl_parent_ip
04773 << d->m_ssl_parent_cert;
04774
04775
04776 QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
04777 KURL::List frameURLLst;
04778 QValueList<QByteArray> frameStateBufferLst;
04779
04780 ConstFrameIt it = d->m_frames.begin();
04781 ConstFrameIt end = d->m_frames.end();
04782 for (; it != end; ++it )
04783 {
04784 if ( !(*it).m_part )
04785 continue;
04786
04787 frameNameLst << (*it).m_name;
04788 frameServiceTypeLst << (*it).m_serviceType;
04789 frameServiceNameLst << (*it).m_serviceName;
04790 frameURLLst << (*it).m_part->url();
04791
04792 QByteArray state;
04793 QDataStream frameStream( state, IO_WriteOnly );
04794
04795 if ( (*it).m_extension )
04796 (*it).m_extension->saveState( frameStream );
04797
04798 frameStateBufferLst << state;
04799 }
04800
04801
04802 stream << (Q_UINT32) frameNameLst.count();
04803 stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
04804 }
04805
04806 void KHTMLPart::restoreState( QDataStream &stream )
04807 {
04808 KURL u;
04809 Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
04810 Q_UINT32 frameCount;
04811 QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
04812 KURL::List frameURLs;
04813 QValueList<QByteArray> frameStateBuffers;
04814 QValueList<int> fSizes;
04815 QString encoding, sheetUsed;
04816 long old_cacheId = d->m_cacheId;
04817
04818 stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
04819
04820 d->m_view->setMarginWidth( mWidth );
04821 d->m_view->setMarginHeight( mHeight );
04822
04823
04824
04825 stream >> d->m_focusNodeNumber;
04826 d->m_focusNodeRestored = false;
04827
04828 stream >> d->m_cacheId;
04829
04830 stream >> encoding >> sheetUsed >> docState;
04831
04832 d->m_encoding = encoding;
04833 d->m_sheetUsed = sheetUsed;
04834
04835 int zoomFactor;
04836 stream >> zoomFactor;
04837 setZoomFactor(zoomFactor);
04838
04839 stream >> d->m_httpHeaders;
04840 stream >> d->m_pageServices;
04841 stream >> d->m_pageReferrer;
04842
04843
04844 stream >> d->m_ssl_in_use
04845 >> d->m_ssl_peer_certificate
04846 >> d->m_ssl_peer_chain
04847 >> d->m_ssl_peer_ip
04848 >> d->m_ssl_cipher
04849 >> d->m_ssl_cipher_desc
04850 >> d->m_ssl_cipher_version
04851 >> d->m_ssl_cipher_used_bits
04852 >> d->m_ssl_cipher_bits
04853 >> d->m_ssl_cert_state
04854 >> d->m_ssl_parent_ip
04855 >> d->m_ssl_parent_cert;
04856
04857 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
04858
04859 stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
04860 >> frameURLs >> frameStateBuffers;
04861
04862 d->m_bComplete = false;
04863 d->m_bLoadEventEmitted = false;
04864
04865
04866
04867
04868
04869 if (d->m_cacheId == old_cacheId)
04870 {
04871
04872 d->m_redirectionTimer.stop();
04873
04874 FrameIt fIt = d->m_frames.begin();
04875 FrameIt fEnd = d->m_frames.end();
04876
04877 for (; fIt != fEnd; ++fIt )
04878 (*fIt).m_bCompleted = false;
04879
04880 fIt = d->m_frames.begin();
04881
04882 QStringList::ConstIterator fNameIt = frameNames.begin();
04883 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
04884 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
04885 KURL::List::ConstIterator fURLIt = frameURLs.begin();
04886 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
04887
04888 for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
04889 {
04890 khtml::ChildFrame *child = &(*fIt);
04891
04892
04893
04894 if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
04895 {
04896 child->m_bPreloaded = true;
04897 child->m_name = *fNameIt;
04898 child->m_serviceName = *fServiceNameIt;
04899 processObjectRequest( child, *fURLIt, *fServiceTypeIt );
04900 }
04901
04902 if ( child->m_part )
04903 {
04904 child->m_bCompleted = false;
04905 if ( child->m_extension && !(*fBufferIt).isEmpty() )
04906 {
04907 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
04908 child->m_extension->restoreState( frameStream );
04909 }
04910 else
04911 child->m_part->openURL( *fURLIt );
04912 }
04913 }
04914
04915 KParts::URLArgs args( d->m_extension->urlArgs() );
04916 args.xOffset = xOffset;
04917 args.yOffset = yOffset;
04918 args.docState = docState;
04919 d->m_extension->setURLArgs( args );
04920
04921 d->m_view->resizeContents( wContents, hContents);
04922 d->m_view->setContentsPos( xOffset, yOffset );
04923
04924 m_url = u;
04925 }
04926 else
04927 {
04928
04929 closeURL();
04930
04931
04932 d->m_bCleared = false;
04933 clear();
04934 d->m_encoding = encoding;
04935 d->m_sheetUsed = sheetUsed;
04936
04937 QStringList::ConstIterator fNameIt = frameNames.begin();
04938 QStringList::ConstIterator fNameEnd = frameNames.end();
04939
04940 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
04941 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
04942 KURL::List::ConstIterator fURLIt = frameURLs.begin();
04943 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
04944
04945 for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
04946 {
04947 khtml::ChildFrame newChild;
04948 newChild.m_bPreloaded = true;
04949 newChild.m_name = *fNameIt;
04950 newChild.m_serviceName = *fServiceNameIt;
04951
04952
04953
04954 FrameIt childFrame = d->m_frames.append( newChild );
04955
04956 processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
04957
04958 (*childFrame).m_bPreloaded = true;
04959
04960 if ( (*childFrame).m_part )
04961 {
04962 if ( (*childFrame).m_extension )
04963 if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
04964 {
04965 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
04966 (*childFrame).m_extension->restoreState( frameStream );
04967 }
04968 else
04969 (*childFrame).m_part->openURL( *fURLIt );
04970 }
04971 }
04972
04973 KParts::URLArgs args( d->m_extension->urlArgs() );
04974 args.xOffset = xOffset;
04975 args.yOffset = yOffset;
04976 args.docState = docState;
04977
04978 d->m_view->resizeContents( wContents, hContents);
04979 d->m_view->setContentsPos( xOffset, yOffset );
04980
04981 d->m_extension->setURLArgs( args );
04982 if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
04983 {
04984 d->m_restored = true;
04985 openURL( u );
04986 d->m_restored = false;
04987 }
04988 else
04989 {
04990 restoreURL( u );
04991 }
04992 }
04993
04994 }
04995
04996 void KHTMLPart::show()
04997 {
04998 if ( d->m_view )
04999 d->m_view->show();
05000 }
05001
05002 void KHTMLPart::hide()
05003 {
05004 if ( d->m_view )
05005 d->m_view->hide();
05006 }
05007
05008 DOM::Node KHTMLPart::nodeUnderMouse() const
05009 {
05010 return d->m_view->nodeUnderMouse();
05011 }
05012
05013 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
05014 {
05015 return d->m_view->nonSharedNodeUnderMouse();
05016 }
05017
05018 void KHTMLPart::emitSelectionChanged()
05019 {
05020 emit d->m_extension->enableAction( "copy", hasSelection() );
05021 if ( d->m_findDialog )
05022 d->m_findDialog->setHasSelection( hasSelection() );
05023
05024 emit d->m_extension->selectionInfo( selectedText() );
05025 emit selectionChanged();
05026 }
05027
05028 int KHTMLPart::zoomFactor() const
05029 {
05030 return d->m_zoomFactor;
05031 }
05032
05033
05034 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
05035 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
05036 static const int minZoom = 20;
05037 static const int maxZoom = 300;
05038
05039
05040 extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
05041 extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
05042
05043 void KHTMLPart::slotIncZoom()
05044 {
05045 zoomIn(zoomSizes, zoomSizeCount);
05046 }
05047
05048 void KHTMLPart::slotDecZoom()
05049 {
05050 zoomOut(zoomSizes, zoomSizeCount);
05051 }
05052
05053 void KHTMLPart::slotIncZoomFast()
05054 {
05055 zoomIn(fastZoomSizes, fastZoomSizeCount);
05056 }
05057
05058 void KHTMLPart::slotDecZoomFast()
05059 {
05060 zoomOut(fastZoomSizes, fastZoomSizeCount);
05061 }
05062
05063 void KHTMLPart::zoomIn(const int stepping[], int count)
05064 {
05065 int zoomFactor = d->m_zoomFactor;
05066
05067 if (zoomFactor < maxZoom) {
05068
05069 for (int i = 0; i < count; ++i)
05070 if (stepping[i] > zoomFactor) {
05071 zoomFactor = stepping[i];
05072 break;
05073 }
05074 setZoomFactor(zoomFactor);
05075 }
05076 }
05077
05078 void KHTMLPart::zoomOut(const int stepping[], int count)
05079 {
05080 int zoomFactor = d->m_zoomFactor;
05081 if (zoomFactor > minZoom) {
05082
05083 for (int i = count-1; i >= 0; --i)
05084 if (stepping[i] < zoomFactor) {
05085 zoomFactor = stepping[i];
05086 break;
05087 }
05088 setZoomFactor(zoomFactor);
05089 }
05090 }
05091
05092 void KHTMLPart::setZoomFactor (int percent)
05093 {
05094 if (percent < minZoom) percent = minZoom;
05095 if (percent > maxZoom) percent = maxZoom;
05096 if (d->m_zoomFactor == percent) return;
05097 d->m_zoomFactor = percent;
05098
05099 if(d->m_doc) {
05100 QApplication::setOverrideCursor( waitCursor );
05101 if (d->m_doc->styleSelector())
05102 d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
05103 d->m_doc->recalcStyle( NodeImpl::Force );
05104 QApplication::restoreOverrideCursor();
05105 }
05106
05107 ConstFrameIt it = d->m_frames.begin();
05108 ConstFrameIt end = d->m_frames.end();
05109 for (; it != end; ++it )
05110 if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
05111 KParts::ReadOnlyPart* p = ( *it ).m_part;
05112 static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
05113 }
05114
05115 if ( d->m_guiProfile == BrowserViewGUI ) {
05116 d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
05117 d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
05118 }
05119 }
05120
05121 void KHTMLPart::slotZoomView( int delta )
05122 {
05123 if ( delta < 0 )
05124 slotIncZoom();
05125 else
05126 slotDecZoom();
05127 }
05128
05129 void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
05130 {
05131 if (!d->m_statusMessagesEnabled)
05132 return;
05133
05134 d->m_statusBarText[p] = text;
05135
05136
05137 QString tobe = d->m_statusBarText[BarHoverText];
05138 if (tobe.isEmpty())
05139 tobe = d->m_statusBarText[BarOverrideText];
05140 if (tobe.isEmpty()) {
05141 tobe = d->m_statusBarText[BarDefaultText];
05142 if (!tobe.isEmpty() && d->m_jobspeed)
05143 tobe += " ";
05144 if (d->m_jobspeed)
05145 tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
05146 }
05147 tobe = "<qt>"+tobe;
05148
05149 emit ReadOnlyPart::setStatusBarText(tobe);
05150 }
05151
05152
05153 void KHTMLPart::setJSStatusBarText( const QString &text )
05154 {
05155 setStatusBarText(text, BarOverrideText);
05156 }
05157
05158 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
05159 {
05160 setStatusBarText(text, BarDefaultText);
05161 }
05162
05163 QString KHTMLPart::jsStatusBarText() const
05164 {
05165 return d->m_statusBarText[BarOverrideText];
05166 }
05167
05168 QString KHTMLPart::jsDefaultStatusBarText() const
05169 {
05170 return d->m_statusBarText[BarDefaultText];
05171 }
05172
05173 QString KHTMLPart::referrer() const
05174 {
05175 return d->m_referrer;
05176 }
05177
05178 QString KHTMLPart::pageReferrer() const
05179 {
05180 KURL referrerURL = KURL( d->m_pageReferrer );
05181 if (referrerURL.isValid())
05182 {
05183 QString protocol = referrerURL.protocol();
05184
05185 if ((protocol == "http") ||
05186 ((protocol == "https") && (m_url.protocol() == "https")))
05187 {
05188 referrerURL.setRef(QString::null);
05189 referrerURL.setUser(QString::null);
05190 referrerURL.setPass(QString::null);
05191 return referrerURL.url();
05192 }
05193 }
05194
05195 return QString::null;
05196 }
05197
05198
05199 QString KHTMLPart::lastModified() const
05200 {
05201 if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
05202
05203
05204
05205 QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
05206 d->m_lastModified = lastModif.toString( Qt::LocalDate );
05207 }
05208
05209 return d->m_lastModified;
05210 }
05211
05212 void KHTMLPart::slotLoadImages()
05213 {
05214 if (d->m_doc )
05215 d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
05216
05217 ConstFrameIt it = d->m_frames.begin();
05218 ConstFrameIt end = d->m_frames.end();
05219 for (; it != end; ++it )
05220 if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
05221 KParts::ReadOnlyPart* p = ( *it ).m_part;
05222 static_cast<KHTMLPart*>( p )->slotLoadImages();
05223 }
05224 }
05225
05226 void KHTMLPart::reparseConfiguration()
05227 {
05228 KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
05229 settings->init();
05230
05231 setAutoloadImages( settings->autoLoadImages() );
05232 if (d->m_doc)
05233 d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
05234
05235 d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
05236 d->m_bBackRightClick = settings->isBackRightClickEnabled();
05237 d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
05238 setDebugScript( settings->isJavaScriptDebugEnabled() );
05239 d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
05240 d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
05241 d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
05242
05243 delete d->m_settings;
05244 d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
05245
05246 QApplication::setOverrideCursor( waitCursor );
05247 khtml::CSSStyleSelector::reparseConfiguration();
05248 if(d->m_doc) d->m_doc->updateStyleSelector();
05249 QApplication::restoreOverrideCursor();
05250 }
05251
05252 QStringList KHTMLPart::frameNames() const
05253 {
05254 QStringList res;
05255
05256 ConstFrameIt it = d->m_frames.begin();
05257 ConstFrameIt end = d->m_frames.end();
05258 for (; it != end; ++it )
05259 if (!(*it).m_bPreloaded)
05260 res += (*it).m_name;
05261
05262 return res;
05263 }
05264
05265 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
05266 {
05267 QPtrList<KParts::ReadOnlyPart> res;
05268
05269 ConstFrameIt it = d->m_frames.begin();
05270 ConstFrameIt end = d->m_frames.end();
05271 for (; it != end; ++it )
05272 if (!(*it).m_bPreloaded)
05273 res.append( (*it).m_part );
05274
05275 return res;
05276 }
05277
05278 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
05279 {
05280 kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
05281 FrameIt it = d->m_frames.find( urlArgs.frameName );
05282
05283 if ( it == d->m_frames.end() )
05284 return false;
05285
05286
05287 if ( !urlArgs.lockHistory() )
05288 emit d->m_extension->openURLNotify();
05289
05290 requestObject( &(*it), url, urlArgs );
05291
05292 return true;
05293 }
05294
05295 void KHTMLPart::setDNDEnabled( bool b )
05296 {
05297 d->m_bDnd = b;
05298 }
05299
05300 bool KHTMLPart::dndEnabled() const
05301 {
05302 return d->m_bDnd;
05303 }
05304
05305 void KHTMLPart::customEvent( QCustomEvent *event )
05306 {
05307 if ( khtml::MousePressEvent::test( event ) )
05308 {
05309 khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
05310 return;
05311 }
05312
05313 if ( khtml::MouseDoubleClickEvent::test( event ) )
05314 {
05315 khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
05316 return;
05317 }
05318
05319 if ( khtml::MouseMoveEvent::test( event ) )
05320 {
05321 khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
05322 return;
05323 }
05324
05325 if ( khtml::MouseReleaseEvent::test( event ) )
05326 {
05327 khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
05328 return;
05329 }
05330
05331 if ( khtml::DrawContentsEvent::test( event ) )
05332 {
05333 khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
05334 return;
05335 }
05336
05337 KParts::ReadOnlyPart::customEvent( event );
05338 }
05339
05345 static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
05346 {
05347 for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
05348 if (n->isText()) {
05349 khtml::RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
05350 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05351 for (unsigned i = 0; i != runs.count(); i++) {
05352 if (runs[i]->m_y == y) {
05353 startNode = textRenderer->element();
05354 startOffset = runs[i]->m_start;
05355 return true;
05356 }
05357 }
05358 }
05359
05360 if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
05361 return true;
05362 }
05363 }
05364
05365 return false;
05366 }
05367
05373 static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
05374 {
05375 khtml::RenderObject *n = renderNode;
05376 if (!n) {
05377 return false;
05378 }
05379 khtml::RenderObject *next;
05380 while ((next = n->nextSibling())) {
05381 n = next;
05382 }
05383
05384 while (1) {
05385 if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
05386 return true;
05387 }
05388
05389 if (n->isText()) {
05390 khtml::RenderText *textRenderer = static_cast<khtml::RenderText *>(n);
05391 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05392 for (int i = (int)runs.count()-1; i >= 0; i--) {
05393 if (runs[i]->m_y == y) {
05394 endNode = textRenderer->element();
05395 endOffset = runs[i]->m_start + runs[i]->m_len;
05396 return true;
05397 }
05398 }
05399 }
05400
05401 if (n == renderNode) {
05402 return false;
05403 }
05404
05405 n = n->previousSibling();
05406 }
05407 }
05408
05409 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
05410 {
05411 DOM::DOMString url = event->url();
05412 QMouseEvent *_mouse = event->qmouseEvent();
05413 DOM::Node innerNode = event->innerNode();
05414 d->m_mousePressNode = innerNode;
05415
05416 d->m_dragStartPos = _mouse->pos();
05417
05418 if ( !event->url().isNull() ) {
05419 d->m_strSelectedURL = event->url().string();
05420 d->m_strSelectedURLTarget = event->target().string();
05421 }
05422 else
05423 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05424
05425 if ( _mouse->button() == LeftButton ||
05426 _mouse->button() == MidButton )
05427 {
05428 d->m_bMousePressed = true;
05429
05430 #ifndef KHTML_NO_SELECTION
05431 if ( _mouse->button() == LeftButton )
05432 {
05433 if ( (!d->m_strSelectedURL.isNull() && !isEditable())
05434 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
05435 return;
05436 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05437 int offset = 0;
05438 DOM::NodeImpl* node = 0;
05439 khtml::RenderObject::SelPointState state;
05440 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05441 event->absX()-innerNode.handle()->renderer()->xPos(),
05442 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
05443 d->m_extendMode = d->ExtendByChar;
05444 #ifdef KHTML_NO_CARET
05445 d->m_selectionStart = node;
05446 d->m_startOffset = offset;
05447
05448
05449
05450
05451
05452 d->m_selectionEnd = d->m_selectionStart;
05453 d->m_endOffset = d->m_startOffset;
05454 d->m_doc->clearSelection();
05455 #else // KHTML_NO_CARET
05456 d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
05457 #endif // KHTML_NO_CARET
05458 d->m_initialNode = d->m_selectionStart;
05459 d->m_initialOffset = d->m_startOffset;
05460
05461 }
05462 else
05463 {
05464 #ifndef KHTML_NO_CARET
05465
05466 #else
05467 d->m_selectionStart = DOM::Node();
05468 d->m_selectionEnd = DOM::Node();
05469 #endif
05470 }
05471 emitSelectionChanged();
05472 startAutoScroll();
05473 }
05474 #else
05475 d->m_dragLastPos = _mouse->globalPos();
05476 #endif
05477 }
05478
05479 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
05480 {
05481 d->m_bRightMousePressed = true;
05482 } else if ( _mouse->button() == RightButton )
05483 {
05484 popupMenu( d->m_strSelectedURL );
05485
05486 }
05487 }
05488
05489 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
05490 {
05491 QMouseEvent *_mouse = event->qmouseEvent();
05492 if ( _mouse->button() == LeftButton )
05493 {
05494 d->m_bMousePressed = true;
05495 DOM::Node innerNode = event->innerNode();
05496
05497 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05498 int offset = 0;
05499 DOM::NodeImpl* node = 0;
05500 khtml::RenderObject::SelPointState state;
05501 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05502 event->absX()-innerNode.handle()->renderer()->xPos(),
05503 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);
05504
05505
05506
05507 if ( node && node->renderer() )
05508 {
05509
05510 bool selectLine = (event->clickCount() == 3);
05511 d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;
05512
05513
05514 if (_mouse->state() & ShiftButton) {
05515 d->caretNode() = node;
05516 d->caretOffset() = offset;
05517 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05518 d->m_selectionStart.handle(), d->m_startOffset,
05519 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05520 d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
05521 d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
05522 } else {
05523 d->m_selectionStart = d->m_selectionEnd = node;
05524 d->m_startOffset = d->m_endOffset = offset;
05525 d->m_startBeforeEnd = true;
05526 d->m_initialNode = node;
05527 d->m_initialOffset = offset;
05528 }
05529
05530
05531
05532 extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
05533
05534 extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );
05535
05536
05537
05538
05539 emitSelectionChanged();
05540 d->m_doc
05541 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
05542 d->m_selectionEnd.handle(),d->m_endOffset);
05543 #ifndef KHTML_NO_CARET
05544 bool v = d->m_view->placeCaret();
05545 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
05546 #endif
05547 startAutoScroll();
05548 }
05549 }
05550 }
05551 }
05552
05553 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
05554 {
05555 khtml::RenderObject* obj = node->renderer();
05556
05557 if (obj->isText() && selectLines) {
05558 int pos;
05559 khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
05560 khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
05561 DOMString t = node->nodeValue();
05562 DOM::NodeImpl* selNode = 0;
05563 long selOfs = 0;
05564
05565 if (!run)
05566 return;
05567
05568 int selectionPointY = run->m_y;
05569
05570
05571 khtml::RenderObject *renderNode = renderer;
05572 while (renderNode && renderNode->isInline())
05573 renderNode = renderNode->parent();
05574
05575 renderNode = renderNode->firstChild();
05576
05577 if (right) {
05578
05579
05580 if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
05581 return;
05582 } else {
05583
05584
05585 if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
05586 return;
05587 }
05588
05589 selectionNode = selNode;
05590 selectionOffset = selOfs;
05591 return;
05592 }
05593
05594 QString str;
05595 int len = 0;
05596 if ( obj->isText() ) {
05597 str = static_cast<khtml::RenderText *>(obj)->data().string();
05598 len = str.length();
05599 }
05600
05601 QChar ch;
05602 do {
05603
05604 if ( node ) {
05605 selectionNode = node;
05606 selectionOffset = offset;
05607 }
05608
05609
05610 while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
05611 {
05612 obj = right ? obj->objectBelow() : obj->objectAbove();
05613
05614 if ( obj ) {
05615
05616 str = QString::null;
05617 if ( obj->isText() )
05618 str = static_cast<khtml::RenderText *>(obj)->data().string();
05619 else if ( obj->isBR() )
05620 str = '\n';
05621 else if ( !obj->isInline() ) {
05622 obj = 0L;
05623 break;
05624 }
05625 len = str.length();
05626
05627
05628 if ( right )
05629 offset = -1;
05630 else
05631 offset = len;
05632 }
05633 }
05634 if ( !obj )
05635 break;
05636 node = obj->element();
05637 if ( right )
05638 {
05639 Q_ASSERT( offset < len-1 );
05640 offset++;
05641 }
05642 else
05643 {
05644 Q_ASSERT( offset > 0 );
05645 offset--;
05646 }
05647
05648
05649 ch = str[ offset ];
05650
05651 } while ( !ch.isSpace() && !ch.isPunct() );
05652
05653
05654 if (right) selectionOffset++;
05655 }
05656
05657 #ifndef KHTML_NO_SELECTION
05658 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
05659 {
05660 int offset;
05661
05662 DOM::NodeImpl* node=0;
05663 khtml::RenderObject::SelPointState state;
05664 innerNode.handle()->renderer()->checkSelectionPoint( x, y,
05665 absX-innerNode.handle()->renderer()->xPos(),
05666 absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
05667 if (!node || !node->renderer()) return;
05668
05669
05670
05671
05672 bool withinNode = innerNode == node;
05673
05674
05675
05676 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
05677 d->m_initialNode.isNull() ||
05678 !d->m_selectionStart.handle()->renderer() ||
05679 !d->m_selectionEnd.handle()->renderer()) return;
05680
05681 if (d->m_extendMode != d->ExtendByChar) {
05682
05683 bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
05684 d->caretNode().handle(), d->caretOffset(),
05685 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
05686 bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
05687 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
05688
05689 if (caretBeforeInit != nodeBeforeInit) {
05690
05691 extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
05692 d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
05693 d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
05694 nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
05695 }
05696 }
05697
05698 d->caretNode() = node;
05699 d->caretOffset() = offset;
05700
05701
05702 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05703 d->m_selectionStart.handle(), d->m_startOffset,
05704 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05705
05706 if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
05707 {
05708
05709 if (d->m_extendMode != d->ExtendByChar && withinNode)
05710 extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );
05711
05712 if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
05713 d->m_doc
05714 ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
05715 d->m_selectionEnd.handle(),d->m_startOffset);
05716 else if (d->m_startBeforeEnd)
05717 d->m_doc
05718 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
05719 d->m_selectionEnd.handle(),d->m_endOffset);
05720 else
05721 d->m_doc
05722 ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
05723 d->m_selectionStart.handle(),d->m_startOffset);
05724 }
05725 #ifndef KHTML_NO_CARET
05726 d->m_view->placeCaret();
05727 #endif
05728 }
05729
05730 bool KHTMLPart::isExtendingSelection() const
05731 {
05732
05733
05734
05735 return d->m_bMousePressed;
05736 }
05737 #endif // KHTML_NO_SELECTION
05738
05739 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
05740 {
05741 QMouseEvent *_mouse = event->qmouseEvent();
05742
05743 if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
05744 {
05745 popupMenu( d->m_strSelectedURL );
05746 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05747 d->m_bRightMousePressed = false;
05748 }
05749
05750 DOM::DOMString url = event->url();
05751 DOM::DOMString target = event->target();
05752 DOM::Node innerNode = event->innerNode();
05753
05754 #ifndef QT_NO_DRAGANDDROP
05755 if( d->m_bDnd && d->m_bMousePressed &&
05756 ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
05757 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
05758 if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
05759 return;
05760
05761 QPixmap pix;
05762 HTMLImageElementImpl *img = 0L;
05763 QDragObject *drag = 0;
05764 KURL u;
05765
05766
05767
05768
05769
05770 if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
05771 {
05772 img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
05773 u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
05774 pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
05775 }
05776 else
05777 {
05778
05779 u = completeURL( d->m_strSelectedURL );
05780 pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
05781 }
05782
05783 KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
05784 if ( !d->m_referrer.isEmpty() )
05785 urlDrag->metaData()["referrer"] = d->m_referrer;
05786
05787 if( img ) {
05788 KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
05789 mdrag->addDragObject( new QImageDrag( img->currentImage(), 0L ) );
05790 mdrag->addDragObject( urlDrag );
05791 drag = mdrag;
05792 }
05793 else
05794 drag = urlDrag;
05795
05796 if ( !pix.isNull() )
05797 drag->setPixmap( pix );
05798
05799 stopAutoScroll();
05800 if(drag)
05801 drag->drag();
05802
05803
05804 d->m_bMousePressed = false;
05805 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05806 return;
05807 }
05808 #endif
05809
05810
05811 if ( !d->m_bMousePressed )
05812 {
05813
05814 if ( url.length() )
05815 {
05816 bool shiftPressed = ( _mouse->state() & ShiftButton );
05817
05818
05819 if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
05820 {
05821 HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
05822 if ( i && i->isServerMap() )
05823 {
05824 khtml::RenderObject *r = i->renderer();
05825 if(r)
05826 {
05827 int absx, absy, vx, vy;
05828 r->absolutePosition(absx, absy);
05829 view()->contentsToViewport( absx, absy, vx, vy );
05830
05831 int x(_mouse->x() - vx), y(_mouse->y() - vy);
05832
05833 d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
05834 d->m_overURLTarget = target.string();
05835 overURL( d->m_overURL, target.string(), shiftPressed );
05836 return;
05837 }
05838 }
05839 }
05840
05841
05842 if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
05843 {
05844 d->m_overURL = url.string();
05845 d->m_overURLTarget = target.string();
05846 overURL( d->m_overURL, target.string(), shiftPressed );
05847 }
05848 }
05849 else
05850 {
05851 if( !d->m_overURL.isEmpty() )
05852 {
05853 d->m_overURL = d->m_overURLTarget = QString::null;
05854 emit onURL( QString::null );
05855
05856 setStatusBarText(QString::null, BarHoverText);
05857 emit d->m_extension->mouseOverInfo(0);
05858 }
05859 }
05860 }
05861 else {
05862 #ifndef KHTML_NO_SELECTION
05863
05864 if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
05865 ( (_mouse->state() & LeftButton) != 0 )) {
05866 extendSelectionTo(event->x(), event->y(),
05867 event->absX(), event->absY(), innerNode);
05868 #else
05869 if ( d->m_doc && d->m_view ) {
05870 QPoint diff( _mouse->globalPos() - d->m_dragLastPos );
05871
05872 if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
05873 d->m_view->scrollBy( -diff.x(), -diff.y() );
05874 d->m_dragLastPos = _mouse->globalPos();
05875 }
05876 #endif
05877 }
05878 }
05879
05880 }
05881
05882 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
05883 {
05884 DOM::Node innerNode = event->innerNode();
05885 d->m_mousePressNode = DOM::Node();
05886
05887 if ( d->m_bMousePressed ) {
05888 setStatusBarText(QString::null, BarHoverText);
05889 stopAutoScroll();
05890 }
05891
05892
05893
05894 d->m_bMousePressed = false;
05895
05896 QMouseEvent *_mouse = event->qmouseEvent();
05897 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
05898 {
05899 d->m_bRightMousePressed = false;
05900 KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
05901 if( tmp_iface ) {
05902 tmp_iface->callMethod( "goHistory(int)", -1 );
05903 }
05904 }
05905 #ifndef QT_NO_CLIPBOARD
05906 if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull())) {
05907 kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
05908 << d->m_bOpenMiddleClick << endl;
05909
05910 if (d->m_bOpenMiddleClick) {
05911 KHTMLPart *p = this;
05912 while (p->parentPart()) p = p->parentPart();
05913 p->d->m_extension->pasteRequest();
05914 }
05915 }
05916 #endif
05917
05918 #ifndef KHTML_NO_SELECTION
05919
05920 if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
05921 #ifndef KHTML_NO_CARET
05922 d->m_extendAtEnd = true;
05923 #else
05924 d->m_selectionStart = 0;
05925 d->m_selectionEnd = 0;
05926 d->m_startOffset = 0;
05927 d->m_endOffset = 0;
05928 #endif
05929 emitSelectionChanged();
05930 } else {
05931
05932
05933 DOM::Node n = d->m_selectionStart;
05934 d->m_startBeforeEnd = false;
05935 if( d->m_selectionStart == d->m_selectionEnd ) {
05936 if( d->m_startOffset < d->m_endOffset )
05937 d->m_startBeforeEnd = true;
05938 } else {
05939 #if 0
05940 while(!n.isNull()) {
05941 if(n == d->m_selectionEnd) {
05942 d->m_startBeforeEnd = true;
05943 break;
05944 }
05945 DOM::Node next = n.firstChild();
05946 if(next.isNull()) next = n.nextSibling();
05947 while( next.isNull() && !n.parentNode().isNull() ) {
05948 n = n.parentNode();
05949 next = n.nextSibling();
05950 }
05951 n = next;
05952 }
05953 #else
05954
05955 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
05956 !d->m_selectionStart.handle()->renderer() ||
05957 !d->m_selectionEnd.handle()->renderer()) return;
05958 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05959 d->m_selectionStart.handle(), d->m_startOffset,
05960 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05961 #endif
05962 }
05963 if(!d->m_startBeforeEnd)
05964 {
05965 DOM::Node tmpNode = d->m_selectionStart;
05966 int tmpOffset = d->m_startOffset;
05967 d->m_selectionStart = d->m_selectionEnd;
05968 d->m_startOffset = d->m_endOffset;
05969 d->m_selectionEnd = tmpNode;
05970 d->m_endOffset = tmpOffset;
05971 d->m_startBeforeEnd = true;
05972 d->m_extendAtEnd = !d->m_extendAtEnd;
05973 }
05974 #ifndef KHTML_NO_CARET
05975 bool v = d->m_view->placeCaret();
05976 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
05977 #endif
05978
05979 #ifndef QT_NO_CLIPBOARD
05980 QString text = selectedText();
05981 text.replace(QChar(0xa0), ' ');
05982 disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
05983 kapp->clipboard()->setText(text,QClipboard::Selection);
05984 connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
05985 #endif
05986
05987 emitSelectionChanged();
05988
05989 }
05990 #endif
05991 d->m_initialNode = 0;
05992 d->m_initialOffset = 0;
05993
05994 }
05995
05996 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
05997 {
05998 }
05999
06000 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
06001 {
06002 if ( event->activated() )
06003 {
06004 emitSelectionChanged();
06005 emit d->m_extension->enableAction( "print", d->m_doc != 0 );
06006
06007 if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
06008 {
06009 QPtrList<KAction> lst;
06010 lst.append( d->m_paLoadImages );
06011 plugActionList( "loadImages", lst );
06012 }
06013 }
06014 }
06015
06016 void KHTMLPart::slotPrintFrame()
06017 {
06018 if ( d->m_frames.count() == 0 )
06019 return;
06020
06021 KParts::ReadOnlyPart *frame = currentFrame();
06022 if (!frame)
06023 return;
06024
06025 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
06026
06027 if ( !ext )
06028 return;
06029
06030 QMetaObject *mo = ext->metaObject();
06031
06032 int idx = mo->findSlot( "print()", true );
06033 if ( idx >= 0 ) {
06034 QUObject o[ 1 ];
06035 ext->qt_invoke( idx, o );
06036 }
06037 }
06038
06039 void KHTMLPart::slotSelectAll()
06040 {
06041 KParts::ReadOnlyPart *part = currentFrame();
06042 if (part && part->inherits("KHTMLPart"))
06043 static_cast<KHTMLPart *>(part)->selectAll();
06044 }
06045
06046 void KHTMLPart::startAutoScroll()
06047 {
06048 connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06049 d->m_scrollTimer.start(100, false);
06050 }
06051
06052 void KHTMLPart::stopAutoScroll()
06053 {
06054 disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06055 if (d->m_scrollTimer.isActive())
06056 d->m_scrollTimer.stop();
06057 }
06058
06059
06060 void KHTMLPart::slotAutoScroll()
06061 {
06062 if (d->m_view)
06063 d->m_view->doAutoScroll();
06064 else
06065 stopAutoScroll();
06066 }
06067
06068 void KHTMLPart::selectAll()
06069 {
06070 if (!d->m_doc) return;
06071
06072 NodeImpl *first;
06073 if (d->m_doc->isHTMLDocument())
06074 first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06075 else
06076 first = d->m_doc;
06077 NodeImpl *next;
06078
06079
06080
06081 while ( first && !(first->renderer()
06082 && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
06083 || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
06084 {
06085 next = first->firstChild();
06086 if ( !next ) next = first->nextSibling();
06087 while( first && !next )
06088 {
06089 first = first->parentNode();
06090 if ( first )
06091 next = first->nextSibling();
06092 }
06093 first = next;
06094 }
06095
06096 NodeImpl *last;
06097 if (d->m_doc->isHTMLDocument())
06098 last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06099 else
06100 last = d->m_doc;
06101
06102
06103
06104
06105 while ( last && !(last->renderer()
06106 && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
06107 || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
06108 {
06109 next = last->lastChild();
06110 if ( !next ) next = last->previousSibling();
06111 while ( last && !next )
06112 {
06113 last = last->parentNode();
06114 if ( last )
06115 next = last->previousSibling();
06116 }
06117 last = next;
06118 }
06119
06120 if ( !first || !last )
06121 return;
06122 Q_ASSERT(first->renderer());
06123 Q_ASSERT(last->renderer());
06124 d->m_selectionStart = first;
06125 d->m_startOffset = 0;
06126 d->m_selectionEnd = last;
06127 d->m_endOffset = last->nodeValue().length();
06128 d->m_startBeforeEnd = true;
06129
06130 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
06131 d->m_selectionEnd.handle(), d->m_endOffset );
06132
06133 emitSelectionChanged();
06134 }
06135
06136 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
06137 {
06138 bool linkAllowed = true;
06139
06140 if ( d->m_doc )
06141 linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);
06142
06143 if ( !linkAllowed ) {
06144 khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
06145 if (tokenizer)
06146 tokenizer->setOnHold(true);
06147
06148 int response = KMessageBox::Cancel;
06149 if (!message.isEmpty())
06150 {
06151 response = KMessageBox::warningContinueCancel( 0,
06152 message.arg(linkURL.htmlURL()),
06153 i18n( "Security Warning" ),
06154 button);
06155 }
06156 else
06157 {
06158 KMessageBox::error( 0,
06159 i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
06160 i18n( "Security Alert" ));
06161 }
06162
06163 if (tokenizer)
06164 tokenizer->setOnHold(false);
06165 return (response==KMessageBox::Continue);
06166 }
06167 return true;
06168 }
06169
06170 void KHTMLPart::slotPartRemoved( KParts::Part *part )
06171 {
06172
06173 if ( part == d->m_activeFrame )
06174 {
06175 d->m_activeFrame = 0L;
06176 if ( !part->inherits( "KHTMLPart" ) )
06177 {
06178 if (factory()) {
06179 factory()->removeClient( part );
06180 }
06181 if (childClients()->containsRef(part)) {
06182 removeChildClient( part );
06183 }
06184 }
06185 }
06186 }
06187
06188 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
06189 {
06190
06191 if ( part == this )
06192 {
06193 kdError(6050) << "strange error! we activated ourselves" << endl;
06194 assert( false );
06195 return;
06196 }
06197
06198 if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06199 {
06200 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06201 if (frame->frameStyle() != QFrame::NoFrame)
06202 {
06203 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
06204 frame->repaint();
06205 }
06206 }
06207
06208 if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
06209 {
06210 if (factory()) {
06211 factory()->removeClient( d->m_activeFrame );
06212 }
06213 removeChildClient( d->m_activeFrame );
06214 }
06215 if( part && !part->inherits( "KHTMLPart" ) )
06216 {
06217 if (factory()) {
06218 factory()->addClient( part );
06219 }
06220 insertChildClient( part );
06221 }
06222
06223
06224 d->m_activeFrame = part;
06225
06226 if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06227 {
06228 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06229 if (frame->frameStyle() != QFrame::NoFrame)
06230 {
06231 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
06232 frame->repaint();
06233 }
06234 kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
06235 }
06236
06237 updateActions();
06238
06239
06240 d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
06241 }
06242
06243 void KHTMLPart::setActiveNode(const DOM::Node &node)
06244 {
06245 if (!d->m_doc || !d->m_view)
06246 return;
06247
06248
06249 d->m_doc->setFocusNode(node.handle());
06250
06251
06252 QRect rect = node.handle()->getRect();
06253 d->m_view->ensureVisible(rect.right(), rect.bottom());
06254 d->m_view->ensureVisible(rect.left(), rect.top());
06255 }
06256
06257 DOM::Node KHTMLPart::activeNode() const
06258 {
06259 return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
06260 }
06261
06262 DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code, QString name )
06263 {
06264 KJSProxy *proxy = jScript();
06265
06266 if (!proxy)
06267 return 0;
06268
06269 return proxy->createHTMLEventHandler( m_url.url(), name, code );
06270 }
06271
06272 KHTMLPart *KHTMLPart::opener()
06273 {
06274 return d->m_opener;
06275 }
06276
06277 void KHTMLPart::setOpener(KHTMLPart *_opener)
06278 {
06279 d->m_opener = _opener;
06280 }
06281
06282 bool KHTMLPart::openedByJS()
06283 {
06284 return d->m_openedByJS;
06285 }
06286
06287 void KHTMLPart::setOpenedByJS(bool _openedByJS)
06288 {
06289 d->m_openedByJS = _openedByJS;
06290 }
06291
06292 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
06293 {
06294 khtml::Cache::preloadStyleSheet(url, stylesheet);
06295 }
06296
06297 void KHTMLPart::preloadScript(const QString &url, const QString &script)
06298 {
06299 khtml::Cache::preloadScript(url, script);
06300 }
06301
06302 QCString KHTMLPart::dcopObjectId() const
06303 {
06304 QCString id;
06305 id.sprintf("html-widget%d", d->m_dcop_counter);
06306 return id;
06307 }
06308
06309 long KHTMLPart::cacheId() const
06310 {
06311 return d->m_cacheId;
06312 }
06313
06314 bool KHTMLPart::restored() const
06315 {
06316 return d->m_restored;
06317 }
06318
06319 bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
06320 {
06321
06322 KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
06323 if ( parent )
06324 return parent->pluginPageQuestionAsked(mimetype);
06325
06326 return d->m_pluginPageQuestionAsked.contains(mimetype);
06327 }
06328
06329 void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
06330 {
06331 if ( parentPart() )
06332 parentPart()->setPluginPageQuestionAsked(mimetype);
06333
06334 d->m_pluginPageQuestionAsked.append(mimetype);
06335 }
06336
06337 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
06338 {
06339 d->m_automaticDetection->setItemChecked( _id, true );
06340
06341 switch ( _id ) {
06342 case 0 :
06343 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06344 break;
06345 case 1 :
06346 d->m_autoDetectLanguage = khtml::Decoder::Arabic;
06347 break;
06348 case 2 :
06349 d->m_autoDetectLanguage = khtml::Decoder::Baltic;
06350 break;
06351 case 3 :
06352 d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
06353 break;
06354 case 4 :
06355 d->m_autoDetectLanguage = khtml::Decoder::Chinese;
06356 break;
06357 case 5 :
06358 d->m_autoDetectLanguage = khtml::Decoder::Greek;
06359 break;
06360 case 6 :
06361 d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
06362 break;
06363 case 7 :
06364 d->m_autoDetectLanguage = khtml::Decoder::Japanese;
06365 break;
06366 case 8 :
06367 d->m_autoDetectLanguage = khtml::Decoder::Korean;
06368 break;
06369 case 9 :
06370 d->m_autoDetectLanguage = khtml::Decoder::Russian;
06371 break;
06372 case 10 :
06373 d->m_autoDetectLanguage = khtml::Decoder::Thai;
06374 break;
06375 case 11 :
06376 d->m_autoDetectLanguage = khtml::Decoder::Turkish;
06377 break;
06378 case 12 :
06379 d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
06380 break;
06381 case 13 :
06382 d->m_autoDetectLanguage = khtml::Decoder::Unicode;
06383 break;
06384 case 14 :
06385 d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
06386 break;
06387 default :
06388 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06389 break;
06390 }
06391
06392 for ( int i = 0; i <= 14; ++i ) {
06393 if ( i != _id )
06394 d->m_automaticDetection->setItemChecked( i, false );
06395 }
06396
06397 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
06398
06399 setEncoding( QString::null, false );
06400
06401 if( d->m_manualDetection )
06402 d->m_manualDetection->setCurrentItem( -1 );
06403 d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
06404 }
06405
06406 khtml::Decoder *KHTMLPart::createDecoder()
06407 {
06408 khtml::Decoder *dec = new khtml::Decoder();
06409 if( !d->m_encoding.isNull() )
06410 dec->setEncoding( d->m_encoding.latin1(), true );
06411 else
06412 dec->setEncoding( defaultEncoding().latin1(), d->m_haveEncoding );
06413
06414 dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
06415 return dec;
06416 }
06417
06418 void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
06419 emit caretPositionChanged(node, offset);
06420 }
06421
06422 void KHTMLPart::restoreScrollPosition()
06423 {
06424 KParts::URLArgs args = d->m_extension->urlArgs();
06425 if (!args.reload) {
06426 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06427 return;
06428 }
06429
06430
06431
06432
06433
06434 if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
06435 || d->m_bComplete) {
06436 d->m_view->setContentsPos(args.xOffset, args.yOffset);
06437 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06438 }
06439 }
06440
06441 KWallet::Wallet* KHTMLPart::wallet()
06442 {
06443
06444
06445
06446
06447
06448 KHTMLPart* p;
06449
06450 for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
06451 ;
06452
06453 if (p)
06454 return p->wallet();
06455
06456 if (!d->m_wallet && !d->m_bWalletOpened) {
06457 d->m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0);
06458 d->m_bWalletOpened = true;
06459 if (d->m_wallet) {
06460 connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));
06461 d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
06462 d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
06463 d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
06464 d->m_statusBarWalletLabel->setUseCursor(false);
06465 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
06466 QToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
06467 d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
06468 connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedURL()), SLOT(launchWalletManager()));
06469 connect(d->m_statusBarWalletLabel, SIGNAL(rightClickedURL()), SLOT(walletMenu()));
06470 } else if (d->m_statusBarWalletLabel) {
06471 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
06472 delete d->m_statusBarWalletLabel;
06473 d->m_statusBarWalletLabel = 0L;
06474 }
06475 }
06476 return d->m_wallet;
06477 }
06478
06479 void KHTMLPart::slotWalletClosed()
06480 {
06481 if (d->m_wallet) {
06482 d->m_wallet->deleteLater();
06483 d->m_wallet = 0L;
06484 }
06485 d->m_bWalletOpened = false;
06486 if (d->m_statusBarWalletLabel) {
06487 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
06488 delete d->m_statusBarWalletLabel;
06489 d->m_statusBarWalletLabel = 0L;
06490 }
06491 }
06492
06493 void KHTMLPart::launchWalletManager()
06494 {
06495 if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
06496 KApplication::startServiceByDesktopName("kwalletmanager_show");
06497 } else {
06498 DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
06499 r.send("show");
06500 r.send("raise");
06501 }
06502 }
06503
06504 void KHTMLPart::walletMenu()
06505 {
06506 KPopupMenu *m = new KPopupMenu(0L);
06507 m->insertItem(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
06508 m->popup(QCursor::pos());
06509 }
06510
06511 void KHTMLPart::slotToggleCaretMode()
06512 {
06513 setCaretMode(d->m_paToggleCaretMode->isChecked());
06514 }
06515
06516 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
06517 d->m_formNotification = fn;
06518 }
06519
06520 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
06521 return d->m_formNotification;
06522 }
06523
06524 KURL KHTMLPart::toplevelURL()
06525 {
06526 KHTMLPart* part = this;
06527 while (part->parentPart())
06528 part = part->parentPart();
06529
06530 if (!part)
06531 return KURL();
06532
06533 return part->url();
06534 }
06535
06536 bool KHTMLPart::isModified() const
06537 {
06538 if ( !d->m_doc )
06539 return false;
06540
06541 return d->m_doc->unsubmittedFormChanges();
06542 }
06543
06544 void KHTMLPart::setDebugScript( bool enable )
06545 {
06546 unplugActionList( "debugScriptList" );
06547 if ( enable ) {
06548 if (!d->m_paDebugScript) {
06549 d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
06550 }
06551 d->m_paDebugScript->setEnabled( d->m_jscript );
06552 QPtrList<KAction> lst;
06553 lst.append( d->m_paDebugScript );
06554 plugActionList( "debugScriptList", lst );
06555 }
06556 d->m_bJScriptDebugEnabled = enable;
06557 }
06558
06559 using namespace KParts;
06560 #include "khtml_part.moc"