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