• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • khtml
 

khtml

  • khtml
khtml_part.cpp
1 // -*- c-basic-offset: 2 -*-
2 /* This file is part of the KDE project
3  *
4  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
5  * 1999 Lars Knoll <knoll@kde.org>
6  * 1999 Antti Koivisto <koivisto@kde.org>
7  * 2000 Simon Hausmann <hausmann@kde.org>
8  * 2000 Stefan Schimanski <1Stein@gmx.de>
9  * 2001-2003 George Staikos <staikos@kde.org>
10  * 2001-2003 Dirk Mueller <mueller@kde.org>
11  * 2000-2005 David Faure <faure@kde.org>
12  * 2002 Apple Computer, Inc.
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Library General Public
16  * License as published by the Free Software Foundation; either
17  * version 2 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public License
25  * along with this library; see the file COPYING.LIB. If not, write to
26  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27  * Boston, MA 02110-1301, USA.
28  */
29 
30 //#define SPEED_DEBUG
31 #include "khtml_part.h"
32 
33 #include "khtml_pagecache.h"
34 
35 #include "dom/dom_string.h"
36 #include "dom/dom_element.h"
37 #include "dom/dom_exception.h"
38 #include "html/html_documentimpl.h"
39 #include "html/html_baseimpl.h"
40 #include "html/html_objectimpl.h"
41 #include "html/html_miscimpl.h"
42 #include "html/html_imageimpl.h"
43 #include "html/html_objectimpl.h"
44 #include "rendering/render_text.h"
45 #include "rendering/render_frames.h"
46 #include "rendering/render_layer.h"
47 #include "misc/htmlhashes.h"
48 #include "misc/loader.h"
49 #include "xml/dom2_eventsimpl.h"
50 #include "xml/dom2_rangeimpl.h"
51 #include "xml/xml_tokenizer.h"
52 #include "css/cssstyleselector.h"
53 #include "css/csshelper.h"
54 using namespace DOM;
55 
56 #include "khtmlview.h"
57 #include <kparts/partmanager.h>
58 #include "ecma/kjs_proxy.h"
59 #include "ecma/kjs_window.h"
60 #include "khtml_settings.h"
61 #include "kjserrordlg.h"
62 
63 #include <kjs/function.h>
64 #include <kjs/interpreter.h>
65 
66 #include "htmlpageinfo.h"
67 
68 #include <sys/types.h>
69 #include <assert.h>
70 #include <unistd.h>
71 
72 #include <config.h>
73 
74 #include <dcopclient.h>
75 #include <dcopref.h>
76 #include <kstandarddirs.h>
77 #include <kstringhandler.h>
78 #include <kio/job.h>
79 #include <kio/global.h>
80 #include <kio/netaccess.h>
81 #include <kprotocolmanager.h>
82 #include <kdebug.h>
83 #include <kiconloader.h>
84 #include <klocale.h>
85 #include <kcharsets.h>
86 #include <kmessagebox.h>
87 #include <kstdaction.h>
88 #include <kfiledialog.h>
89 #include <ktrader.h>
90 #include <kdatastream.h>
91 #include <ktempfile.h>
92 #include <kglobalsettings.h>
93 #include <kurldrag.h>
94 #include <kapplication.h>
95 #include <kparts/browserinterface.h>
96 #if !defined(QT_NO_DRAGANDDROP)
97 #include <kmultipledrag.h>
98 #endif
99 #include "../kutils/kfinddialog.h"
100 #include "../kutils/kfind.h"
101 
102 #include <ksslcertchain.h>
103 #include <ksslinfodlg.h>
104 
105 #include <kfileitem.h>
106 #include <kurifilter.h>
107 #include <kstatusbar.h>
108 #include <kurllabel.h>
109 
110 #include <tqclipboard.h>
111 #include <tqfile.h>
112 #include <tqtooltip.h>
113 #include <tqmetaobject.h>
114 #include <tqucomextra_p.h>
115 
116 #include "khtmlpart_p.h"
117 #include "kpassivepopup.h"
118 #include "kpopupmenu.h"
119 #include "rendering/render_form.h"
120 #include <kwin.h>
121 
122 #define HINT_UTF8 106
123 
124 namespace khtml {
125  class PartStyleSheetLoader : public CachedObjectClient
126  {
127  public:
128  PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
129  {
130  m_part = part;
131  m_cachedSheet = dl->requestStyleSheet(url, TQString(), "text/css",
132  true /* "user sheet" */);
133  if (m_cachedSheet)
134  m_cachedSheet->ref( this );
135  }
136  virtual ~PartStyleSheetLoader()
137  {
138  if ( m_cachedSheet ) m_cachedSheet->deref(this);
139  }
140  virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet, const DOM::DOMString &)
141  {
142  if ( m_part )
143  m_part->setUserStyleSheet( sheet.string() );
144 
145  delete this;
146  }
147  virtual void error( int, const TQString& ) {
148  delete this;
149  }
150  TQGuardedPtr<KHTMLPart> m_part;
151  khtml::CachedCSSStyleSheet *m_cachedSheet;
152  };
153 }
154 
155 void khtml::ChildFrame::liveConnectEvent(const unsigned long, const TQString & event, const KParts::LiveConnectExtension::ArgList & args)
156 {
157  if (!m_part || !m_frame || !m_liveconnect)
158  // hmmm
159  return;
160 
161  TQString script;
162  script.sprintf("%s(", event.latin1());
163 
164  KParts::LiveConnectExtension::ArgList::const_iterator i = args.begin();
165  const KParts::LiveConnectExtension::ArgList::const_iterator argsBegin = i;
166  const KParts::LiveConnectExtension::ArgList::const_iterator argsEnd = args.end();
167 
168  for ( ; i != argsEnd; ++i) {
169  if (i != argsBegin)
170  script += ",";
171  if ((*i).first == KParts::LiveConnectExtension::TypeString) {
172  script += "\"";
173  script += TQString((*i).second).replace('\\', "\\\\").replace('"', "\\\"");
174  script += "\"";
175  } else
176  script += (*i).second;
177  }
178  script += ")";
179  kdDebug(6050) << "khtml::ChildFrame::liveConnectEvent " << script << endl;
180 
181  KHTMLPart * part = ::tqqt_cast<KHTMLPart *>(m_part->parent());
182  if (!part)
183  return;
184  if (!m_jscript)
185  part->framejScript(m_part);
186  if (m_jscript) {
187  // we have a jscript => a part in an iframe
188  KJS::Completion cmp;
189  m_jscript->evaluate(TQString(), 1, script, 0L, &cmp);
190  } else
191  part->executeScript(m_frame->element(), script);
192 }
193 
194 KHTMLFrameList::Iterator KHTMLFrameList::find( const TQString &name )
195 {
196  Iterator it = begin();
197  const Iterator e = end();
198 
199  for (; it!=e; ++it )
200  if ( (*it)->m_name==name )
201  break;
202 
203  return it;
204 }
205 
206 KHTMLPart::KHTMLPart( TQWidget *parentWidget, const char *widgetname, TQObject *parent, const char *name, GUIProfile prof )
207 : KParts::ReadOnlyPart( parent, name )
208 {
209  d = 0;
210  KHTMLFactory::registerPart( this );
211  setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
212  // TODO KDE4 - don't load plugins yet
213  //setInstance( KHTMLFactory::instance(), false );
214  init( new KHTMLView( this, parentWidget, widgetname ), prof );
215 }
216 
217 KHTMLPart::KHTMLPart( KHTMLView *view, TQObject *parent, const char *name, GUIProfile prof )
218 : KParts::ReadOnlyPart( parent, name )
219 {
220  d = 0;
221  KHTMLFactory::registerPart( this );
222  setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
223  // TODO KDE4 - don't load plugins yet
224  //setInstance( KHTMLFactory::instance(), false );
225  assert( view );
226  init( view, prof );
227 }
228 
229 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
230 {
231  if ( prof == DefaultGUI )
232  setXMLFile( "khtml.rc" );
233  else if ( prof == BrowserViewGUI )
234  setXMLFile( "khtml_browser.rc" );
235 
236  d = new KHTMLPartPrivate(parent());
237 
238  d->m_view = view;
239  setWidget( d->m_view );
240 
241  d->m_guiProfile = prof;
242  d->m_extension = new KHTMLPartBrowserExtension( this, "KHTMLBrowserExtension" );
243  d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
244  d->m_statusBarExtension = new KParts::StatusBarExtension( this );
245  d->m_statusBarIconLabel = 0L;
246  d->m_statusBarPopupLabel = 0L;
247  d->m_openableSuppressedPopups = 0;
248 
249  d->m_bSecurityInQuestion = false;
250  d->m_paLoadImages = 0;
251  d->m_paDebugScript = 0;
252  d->m_bMousePressed = false;
253  d->m_bRightMousePressed = false;
254  d->m_bCleared = false;
255  d->m_paViewDocument = new KAction( i18n( "View Do&cument Source" ), CTRL + Key_U, this, TQT_SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
256  d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, TQT_SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
257  d->m_paViewInfo = new KAction( i18n( "View Document Information" ), CTRL+Key_I, this, TQT_SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
258  d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, TQT_SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
259  d->m_paSaveDocument = KStdAction::saveAs( this, TQT_SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
260  if ( parentPart() )
261  d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
262  d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, TQT_SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
263  d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, TQT_SLOT( slotSecurity() ), actionCollection(), "security" );
264  d->m_paSecurity->setWhatsThis( i18n( "Security Settings<p>"
265  "Shows the certificate of the displayed page. Only "
266  "pages that have been transmitted using a secure, encrypted connection have a "
267  "certificate.<p> "
268  "Hint: If the image shows a closed lock, the page has been transmitted over a "
269  "secure connection.") );
270  d->m_paDebugRenderTree = new KAction( i18n( "Print Rendering Tree to STDOUT" ), ALT + CTRL + SHIFT + Key_A, this, TQT_SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
271  d->m_paDebugDOMTree = new KAction( i18n( "Print DOM Tree to STDOUT" ), ALT + CTRL + SHIFT + Key_D, this, TQT_SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
272  d->m_paStopAnimations = new KAction( i18n( "Stop Animated Images" ), 0, this, TQT_SLOT( slotStopAnimations() ), actionCollection(), "stopAnimations" );
273 
274  d->m_paSetEncoding = new KActionMenu( i18n( "Set &Encoding" ), "charset", actionCollection(), "setEncoding" );
275  d->m_paSetEncoding->setDelayed( false );
276 
277  d->m_automaticDetection = new KPopupMenu( 0L );
278 
279  d->m_automaticDetection->insertItem( i18n( "Semi-Automatic" ), 0 );
280  d->m_automaticDetection->insertItem( i18n( "Arabic" ), 1 );
281  d->m_automaticDetection->insertItem( i18n( "Baltic" ), 2 );
282  d->m_automaticDetection->insertItem( i18n( "Central European" ), 3 );
283  //d->m_automaticDetection->insertItem( i18n( "Chinese" ), 4 );
284  d->m_automaticDetection->insertItem( i18n( "Greek" ), 5 );
285  d->m_automaticDetection->insertItem( i18n( "Hebrew" ), 6 );
286  d->m_automaticDetection->insertItem( i18n( "Japanese" ), 7 );
287  //d->m_automaticDetection->insertItem( i18n( "Korean" ), 8 );
288  d->m_automaticDetection->insertItem( i18n( "Russian" ), 9 );
289  //d->m_automaticDetection->insertItem( i18n( "Thai" ), 10 );
290  d->m_automaticDetection->insertItem( i18n( "Turkish" ), 11 );
291  d->m_automaticDetection->insertItem( i18n( "Ukrainian" ), 12 );
292  //d->m_automaticDetection->insertItem( i18n( "Unicode" ), 13 );
293  d->m_automaticDetection->insertItem( i18n( "Western European" ), 14 );
294 
295  connect( d->m_automaticDetection, TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotAutomaticDetectionLanguage( int ) ) );
296 
297  d->m_paSetEncoding->popupMenu()->insertItem( i18n( "Automatic Detection" ), d->m_automaticDetection, 0 );
298 
299  d->m_paSetEncoding->insert( new KActionSeparator( actionCollection() ) );
300 
301 
302  d->m_manualDetection = new KSelectAction( i18n( "short for Manual Detection", "Manual" ), 0, this, TQT_SLOT( slotSetEncoding() ), actionCollection(), "manualDetection" );
303  TQStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
304  d->m_manualDetection->setItems( encodings );
305  d->m_manualDetection->setCurrentItem( -1 );
306  d->m_paSetEncoding->insert( d->m_manualDetection );
307 
308 
309  KConfig *config = KGlobal::config();
310  if ( config->hasGroup( "HTML Settings" ) ) {
311  config->setGroup( "HTML Settings" );
312  khtml::Decoder::AutoDetectLanguage language;
313  TQCString name = TQTextCodec::codecForLocale()->name();
314  name = name.lower();
315 
316  if ( name == "cp1256" || name == "iso-8859-6" ) {
317  language = khtml::Decoder::Arabic;
318  }
319  else if ( name == "cp1257" || name == "iso-8859-13" || name == "iso-8859-4" ) {
320  language = khtml::Decoder::Baltic;
321  }
322  else if ( name == "cp1250" || name == "ibm852" || name == "iso-8859-2" || name == "iso-8859-3" ) {
323  language = khtml::Decoder::CentralEuropean;
324  }
325  else if ( name == "cp1251" || name == "koi8-r" || name == "iso-8859-5" ) {
326  language = khtml::Decoder::Russian;
327  }
328  else if ( name == "koi8-u" ) {
329  language = khtml::Decoder::Ukrainian;
330  }
331  else if ( name == "cp1253" || name == "iso-8859-7" ) {
332  language = khtml::Decoder::Greek;
333  }
334  else if ( name == "cp1255" || name == "iso-8859-8" || name == "iso-8859-8-i" ) {
335  language = khtml::Decoder::Hebrew;
336  }
337  else if ( name == "jis7" || name == "eucjp" || name == "sjis" ) {
338  language = khtml::Decoder::Japanese;
339  }
340  else if ( name == "cp1254" || name == "iso-8859-9" ) {
341  language = khtml::Decoder::Turkish;
342  }
343  else if ( name == "cp1252" || name == "iso-8859-1" || name == "iso-8859-15" ) {
344  language = khtml::Decoder::WesternEuropean;
345  }
346  else
347  language = khtml::Decoder::SemiautomaticDetection;
348 
349  int _id = config->readNumEntry( "AutomaticDetectionLanguage", language );
350  d->m_automaticDetection->setItemChecked( _id, true );
351  d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
352 
353  d->m_autoDetectLanguage = static_cast< khtml::Decoder::AutoDetectLanguage >( _id );
354  }
355 
356 
357  d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, TQT_SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
358 
359  if ( prof == BrowserViewGUI ) {
360  d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n(
361  "Enlarge Font" ), "viewmag+", "CTRL++;CTRL+=", this,
362  TQT_SLOT( slotIncZoomFast() ), actionCollection(), "incFontSizes" );
363  d->m_paIncZoomFactor->setWhatsThis( i18n( "Enlarge Font<p>"
364  "Make the font in this window bigger. "
365  "Click and hold down the mouse button for a menu with all available font sizes." ) );
366  d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n(
367  "Shrink Font" ), "viewmag-", CTRL + Key_Minus, this,
368  TQT_SLOT( slotDecZoomFast() ), actionCollection(), "decFontSizes" );
369  d->m_paDecZoomFactor->setWhatsThis( i18n( "Shrink Font<p>"
370  "Make the font in this window smaller. "
371  "Click and hold down the mouse button for a menu with all available font sizes." ) );
372  }
373 
374  d->m_paFind = KStdAction::find( this, TQT_SLOT( slotFind() ), actionCollection(), "find" );
375  d->m_paFind->setWhatsThis( i18n( "Find text<p>"
376  "Shows a dialog that allows you to find text on the displayed page." ) );
377 
378  d->m_paFindNext = KStdAction::findNext( this, TQT_SLOT( slotFindNext() ), actionCollection(), "findNext" );
379  d->m_paFindNext->setWhatsThis( i18n( "Find next<p>"
380  "Find the next occurrence of the text that you "
381  "have found using the <b>Find Text</b> function" ) );
382 
383  d->m_paFindPrev = KStdAction::findPrev( this, TQT_SLOT( slotFindPrev() ), actionCollection(), "findPrevious" );
384  d->m_paFindPrev->setWhatsThis( i18n( "Find previous<p>"
385  "Find the previous occurrence of the text that you "
386  "have found using the <b>Find Text</b> function" ) );
387 
388  d->m_paFindAheadText = new KAction( i18n("Find Text as You Type"), KShortcut( '/' ), this, TQT_SLOT( slotFindAheadText()),
389  actionCollection(), "findAheadText");
390  d->m_paFindAheadLinks = new KAction( i18n("Find Links as You Type"), KShortcut( '\'' ), this, TQT_SLOT( slotFindAheadLink()),
391  actionCollection(), "findAheadLink");
392  d->m_paFindAheadText->setEnabled( false );
393  d->m_paFindAheadLinks->setEnabled( false );
394 
395  if ( parentPart() )
396  {
397  d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
398  d->m_paFindNext->setShortcut( KShortcut() ); // avoid clashes
399  d->m_paFindPrev->setShortcut( KShortcut() ); // avoid clashes
400  d->m_paFindAheadText->setShortcut( KShortcut());
401  d->m_paFindAheadLinks->setShortcut( KShortcut());
402  }
403 
404  d->m_paPrintFrame = new KAction( i18n( "Print Frame..." ), "frameprint", 0, this, TQT_SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
405  d->m_paPrintFrame->setWhatsThis( i18n( "Print Frame<p>"
406  "Some pages have several frames. To print only a single frame, click "
407  "on it and then use this function." ) );
408 
409  d->m_paSelectAll = KStdAction::selectAll( this, TQT_SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
410  if ( parentPart() )
411  d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
412 
413  d->m_paToggleCaretMode = new KToggleAction(i18n("Toggle Caret Mode"),
414  Key_F7, this, TQT_SLOT(slotToggleCaretMode()),
415  actionCollection(), "caretMode");
416  d->m_paToggleCaretMode->setChecked(isCaretMode());
417  if (parentPart())
418  d->m_paToggleCaretMode->setShortcut(KShortcut()); // avoid clashes
419 
420  // set the default java(script) flags according to the current host.
421  d->m_bOpenMiddleClick = d->m_settings->isOpenMiddleClickEnabled();
422  d->m_bBackRightClick = d->m_settings->isBackRightClickEnabled();
423  d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
424  setDebugScript( d->m_settings->isJavaScriptDebugEnabled() );
425  d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
426  d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
427 
428  // Set the meta-refresh flag...
429  d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();
430 
431  connect( view, TQT_SIGNAL( zoomView( int ) ), TQT_SLOT( slotZoomView( int ) ) );
432 
433  connect( this, TQT_SIGNAL( completed() ),
434  this, TQT_SLOT( updateActions() ) );
435  connect( this, TQT_SIGNAL( completed( bool ) ),
436  this, TQT_SLOT( updateActions() ) );
437  connect( this, TQT_SIGNAL( started( KIO::Job * ) ),
438  this, TQT_SLOT( updateActions() ) );
439 
440  d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
441 
442  connect( khtml::Cache::loader(), TQT_SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
443  this, TQT_SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
444  connect( khtml::Cache::loader(), TQT_SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
445  this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
446  connect( khtml::Cache::loader(), TQT_SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
447  this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
448 
449  connect ( &d->m_progressUpdateTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotProgressUpdate() ) );
450 
451  findTextBegin(); //reset find variables
452 
453  connect( &d->m_redirectionTimer, TQT_SIGNAL( timeout() ),
454  this, TQT_SLOT( slotRedirect() ) );
455 
456  d->m_dcopobject = new KHTMLPartIface(this);
457 
458  // TODO KDE4 - load plugins now (see also the constructors)
459  //if ( prof == BrowserViewGUI && !parentPart() )
460  // loadPlugins( partObject(), this, instance() );
461 
462  // "khtml" catalog does not exist, our translations are in kdelibs.
463  // removing this catalog from KGlobal::locale() prevents problems
464  // with changing the language in applications at runtime -Thomas Reitelbach
465  KGlobal::locale()->removeCatalogue("khtml");
466 }
467 
468 KHTMLPart::~KHTMLPart()
469 {
470  //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
471 
472  KConfig *config = KGlobal::config();
473  config->setGroup( "HTML Settings" );
474  config->writeEntry( "AutomaticDetectionLanguage", d->m_autoDetectLanguage );
475 
476  delete d->m_automaticDetection;
477  delete d->m_manualDetection;
478 
479  slotWalletClosed();
480  if (!parentPart()) { // only delete it if the top khtml_part closes
481  removeJSErrorExtension();
482  delete d->m_statusBarPopupLabel;
483  }
484 
485  d->m_find = 0; // deleted by its parent, the view.
486 
487  if ( d->m_manager )
488  {
489  d->m_manager->setActivePart( 0 );
490  // We specify "this" as parent qobject for d->manager, so no need to delete it.
491  }
492 
493  stopAutoScroll();
494  d->m_redirectionTimer.stop();
495 
496  if (!d->m_bComplete)
497  closeURL();
498 
499  disconnect( khtml::Cache::loader(), TQT_SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
500  this, TQT_SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
501  disconnect( khtml::Cache::loader(), TQT_SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
502  this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
503  disconnect( khtml::Cache::loader(), TQT_SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
504  this, TQT_SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
505 
506  clear();
507 
508  if ( d->m_view )
509  {
510  d->m_view->hide();
511  d->m_view->viewport()->hide();
512  d->m_view->m_part = 0;
513  }
514 
515  // Have to delete this here since we forward declare it in khtmlpart_p and
516  // at least some compilers won't call the destructor in this case.
517  delete d->m_jsedlg;
518  d->m_jsedlg = 0;
519 
520  if (!parentPart()) // only delete d->m_frame if the top khtml_part closes
521  delete d->m_frame;
522  delete d; d = 0;
523  KHTMLFactory::deregisterPart( this );
524 }
525 
526 bool KHTMLPart::restoreURL( const KURL &url )
527 {
528  kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
529 
530  d->m_redirectionTimer.stop();
531 
532  /*
533  * That's not a good idea as it will call closeURL() on all
534  * child frames, preventing them from further loading. This
535  * method gets called from restoreState() in case of a full frameset
536  * restoral, and restoreState() calls closeURL() before restoring
537  * anyway.
538  kdDebug( 6050 ) << "closing old URL" << endl;
539  closeURL();
540  */
541 
542  d->m_bComplete = false;
543  d->m_bLoadEventEmitted = false;
544  d->m_workingURL = url;
545 
546  // set the java(script) flags according to the current host.
547  d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
548  setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
549  d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
550  d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
551 
552  m_url = url;
553 
554  d->m_restoreScrollPosition = true;
555  disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
556  connect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
557 
558  KHTMLPageCache::self()->fetchData( d->m_cacheId, this, TQT_SLOT(slotRestoreData(const TQByteArray &)));
559 
560  emit started( 0L );
561 
562  return true;
563 }
564 
565 
566 bool KHTMLPart::openURL( const KURL &url )
567 {
568  kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
569 
570  d->m_redirectionTimer.stop();
571 
572  // check to see if this is an "error://" URL. This is caused when an error
573  // occurs before this part was loaded (e.g. KonqRun), and is passed to
574  // khtmlpart so that it can display the error.
575  if ( url.protocol() == "error" && url.hasSubURL() ) {
576  closeURL();
577 
578  if( d->m_bJScriptEnabled )
579  d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = TQString();
580 
586  KURL::List urls = KURL::split( url );
587  //kdDebug(6050) << "Handling error URL. URL count:" << urls.count() << endl;
588 
589  if ( urls.count() > 1 ) {
590  KURL mainURL = urls.first();
591  int error = mainURL.queryItem( "error" ).toInt();
592  // error=0 isn't a valid error code, so 0 means it's missing from the URL
593  if ( error == 0 ) error = KIO::ERR_UNKNOWN;
594  TQString errorText = mainURL.queryItem( "errText", HINT_UTF8 );
595  urls.pop_front();
596  d->m_workingURL = KURL::join( urls );
597  //kdDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
598  emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
599  htmlError( error, errorText, d->m_workingURL );
600  return true;
601  }
602  }
603 
604  if (!parentPart()) { // only do it for toplevel part
605  TQString host = url.isLocalFile() ? "localhost" : url.host();
606  TQString userAgent = KProtocolManager::userAgentForHost(host);
607  if (userAgent != KProtocolManager::userAgentForHost(TQString())) {
608  if (!d->m_statusBarUALabel) {
609  d->m_statusBarUALabel = new KURLLabel(d->m_statusBarExtension->statusBar());
610  d->m_statusBarUALabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
611  d->m_statusBarUALabel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
612  d->m_statusBarUALabel->setUseCursor(false);
613  d->m_statusBarExtension->addStatusBarItem(d->m_statusBarUALabel, 0, false);
614  d->m_statusBarUALabel->setPixmap(SmallIcon("agent", instance()));
615  } else {
616  TQToolTip::remove(d->m_statusBarUALabel);
617  }
618  TQToolTip::add(d->m_statusBarUALabel, i18n("The fake user-agent '%1' is in use.").arg(userAgent));
619  } else if (d->m_statusBarUALabel) {
620  d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarUALabel);
621  delete d->m_statusBarUALabel;
622  d->m_statusBarUALabel = 0L;
623  }
624  }
625 
626  KParts::URLArgs args( d->m_extension->urlArgs() );
627 
628  // in case
629  // a) we have no frameset (don't test m_frames.count(), iframes get in there)
630  // b) the url is identical with the currently displayed one (except for the htmlref!)
631  // c) the url request is not a POST operation and
632  // d) the caller did not request to reload the page
633  // e) there was no HTTP redirection meanwhile (testcase: webmin's software/tree.cgi)
634  // => we don't reload the whole document and
635  // we just jump to the requested html anchor
636  bool isFrameSet = false;
637  if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
638  HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
639  isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
640  }
641 
642  if ( url.hasRef() && !isFrameSet )
643  {
644  bool noReloadForced = !args.reload && !args.redirectedRequest() && !args.doPost();
645  if (noReloadForced && urlcmp( url.url(), m_url.url(), true, true ))
646  {
647  kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
648  m_url = url;
649  emit started( 0L );
650 
651  if ( !gotoAnchor( url.encodedHtmlRef()) )
652  gotoAnchor( url.htmlRef() );
653 
654  d->m_bComplete = true;
655  if (d->m_doc)
656  d->m_doc->setParsing(false);
657 
658  kdDebug( 6050 ) << "completed..." << endl;
659  emit completed();
660  return true;
661  }
662  }
663 
664  // Save offset of viewport when page is reloaded to be compliant
665  // to every other capable browser out there.
666  if (args.reload) {
667  args.xOffset = d->m_view->contentsX();
668  args.yOffset = d->m_view->contentsY();
669  d->m_extension->setURLArgs(args);
670  }
671 
672  if (!d->m_restored)
673  closeURL();
674 
675  d->m_restoreScrollPosition = d->m_restored;
676  disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
677  connect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
678 
679  // initializing m_url to the new url breaks relative links when opening such a link after this call and _before_ begin() is called (when the first
680  // data arrives) (Simon)
681  m_url = url;
682  if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
683  m_url.path().isEmpty()) {
684  m_url.setPath("/");
685  emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
686  }
687  // copy to m_workingURL after fixing m_url above
688  d->m_workingURL = m_url;
689 
690  args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
691  args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
692  args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
693  args.metaData().insert("PropagateHttpHeader", "true");
694  args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
695  args.metaData().insert("ssl_activate_warnings", "TRUE" );
696  args.metaData().insert("cross-domain", toplevelURL().url());
697 
698  if (d->m_restored)
699  {
700  args.metaData().insert("referrer", d->m_pageReferrer);
701  d->m_cachePolicy = KIO::CC_Cache;
702  }
703  else if (args.reload)
704  d->m_cachePolicy = KIO::CC_Reload;
705  else
706  d->m_cachePolicy = KProtocolManager::cacheControl();
707 
708  if ( args.doPost() && (m_url.protocol().startsWith("http")) )
709  {
710  d->m_job = KIO::http_post( m_url, args.postData, false );
711  d->m_job->addMetaData("content-type", args.contentType() );
712  }
713  else
714  {
715  d->m_job = KIO::get( m_url, false, false );
716  d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
717  }
718 
719  if (widget())
720  d->m_job->setWindow(widget()->topLevelWidget());
721  d->m_job->addMetaData(args.metaData());
722 
723  connect( d->m_job, TQT_SIGNAL( result( KIO::Job* ) ),
724  TQT_SLOT( slotFinished( KIO::Job* ) ) );
725  connect( d->m_job, TQT_SIGNAL( data( KIO::Job*, const TQByteArray& ) ),
726  TQT_SLOT( slotData( KIO::Job*, const TQByteArray& ) ) );
727  connect ( d->m_job, TQT_SIGNAL( infoMessage( KIO::Job*, const TQString& ) ),
728  TQT_SLOT( slotInfoMessage(KIO::Job*, const TQString& ) ) );
729  connect( d->m_job, TQT_SIGNAL(redirection(KIO::Job*, const KURL& ) ),
730  TQT_SLOT( slotRedirection(KIO::Job*, const KURL&) ) );
731 
732  d->m_bComplete = false;
733  d->m_bLoadEventEmitted = false;
734 
735  // delete old status bar msg's from kjs (if it _was_ activated on last URL)
736  if( d->m_bJScriptEnabled )
737  d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = TQString();
738 
739  // set the javascript flags according to the current url
740  d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
741  setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
742  d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
743  d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
744 
745 
746  connect( d->m_job, TQT_SIGNAL( speed( KIO::Job*, unsigned long ) ),
747  this, TQT_SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
748 
749  connect( d->m_job, TQT_SIGNAL( percent( KIO::Job*, unsigned long ) ),
750  this, TQT_SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
751 
752  connect( d->m_job, TQT_SIGNAL( result( KIO::Job* ) ),
753  this, TQT_SLOT( slotJobDone( KIO::Job* ) ) );
754 
755  d->m_jobspeed = 0;
756 
757  // If this was an explicit reload and the user style sheet should be used,
758  // do a stat to see whether the stylesheet was changed in the meanwhile.
759  if ( args.reload && !settings()->userStyleSheet().isEmpty() ) {
760  KURL url( settings()->userStyleSheet() );
761  KIO::StatJob *job = KIO::stat( url, false /* don't show progress */ );
762  connect( job, TQT_SIGNAL( result( KIO::Job * ) ),
763  this, TQT_SLOT( slotUserSheetStatDone( KIO::Job * ) ) );
764  }
765  emit started( 0L );
766 
767  return true;
768 }
769 
770 bool KHTMLPart::closeURL()
771 {
772  if ( d->m_job )
773  {
774  KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
775  d->m_job->kill();
776  d->m_job = 0;
777  }
778 
779  if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
780  HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
781 
782  if ( hdoc->body() && d->m_bLoadEventEmitted ) {
783  hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
784  if ( d->m_doc )
785  d->m_doc->updateRendering();
786  d->m_bLoadEventEmitted = false;
787  }
788  }
789 
790  d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
791  d->m_bLoadEventEmitted = true; // don't want that one either
792  d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
793 
794  disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
795 
796  KHTMLPageCache::self()->cancelFetch(this);
797  if ( d->m_doc && d->m_doc->parsing() )
798  {
799  kdDebug( 6050 ) << " was still parsing... calling end " << endl;
800  slotFinishedParsing();
801  d->m_doc->setParsing(false);
802  }
803 
804  if ( !d->m_workingURL.isEmpty() )
805  {
806  // Aborted before starting to render
807  kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
808  emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
809  }
810 
811  d->m_workingURL = KURL();
812 
813  if ( d->m_doc && d->m_doc->docLoader() )
814  khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
815 
816  // tell all subframes to stop as well
817  {
818  ConstFrameIt it = d->m_frames.begin();
819  const ConstFrameIt end = d->m_frames.end();
820  for (; it != end; ++it )
821  {
822  if ( (*it)->m_run )
823  (*it)->m_run->abort();
824  if ( !( *it )->m_part.isNull() )
825  ( *it )->m_part->closeURL();
826  }
827  }
828  // tell all objects to stop as well
829  {
830  ConstFrameIt it = d->m_objects.begin();
831  const ConstFrameIt end = d->m_objects.end();
832  for (; it != end; ++it)
833  {
834  if ( !( *it )->m_part.isNull() )
835  ( *it )->m_part->closeURL();
836  }
837  }
838  // Stop any started redirections as well!! (DA)
839  if ( d && d->m_redirectionTimer.isActive() )
840  d->m_redirectionTimer.stop();
841 
842  // null node activated.
843  emit nodeActivated(Node());
844 
845  // make sure before clear() runs, we pop out of a dialog's message loop
846  if ( d->m_view )
847  d->m_view->closeChildDialogs();
848 
849  return true;
850 }
851 
852 DOM::HTMLDocument KHTMLPart::htmlDocument() const
853 {
854  if (d->m_doc && d->m_doc->isHTMLDocument())
855  return static_cast<HTMLDocumentImpl*>(d->m_doc);
856  else
857  return static_cast<HTMLDocumentImpl*>(0);
858 }
859 
860 DOM::Document KHTMLPart::document() const
861 {
862  return d->m_doc;
863 }
864 
865 TQString KHTMLPart::documentSource() const
866 {
867  TQString sourceStr;
868  if ( !( m_url.isLocalFile() ) && KHTMLPageCache::self()->isComplete( d->m_cacheId ) )
869  {
870  TQByteArray sourceArray;
871  TQDataStream dataStream( sourceArray, IO_WriteOnly );
872  KHTMLPageCache::self()->saveData( d->m_cacheId, &dataStream );
873  TQTextStream stream( sourceArray, IO_ReadOnly );
874  stream.setCodec( TQTextCodec::codecForName( encoding().latin1() ) );
875  sourceStr = stream.read();
876  } else
877  {
878  TQString tmpFile;
879  if( KIO::NetAccess::download( m_url, tmpFile, NULL ) )
880  {
881  TQFile f( tmpFile );
882  if ( f.open( IO_ReadOnly ) )
883  {
884  TQTextStream stream( &f );
885  stream.setCodec( TQTextCodec::codecForName( encoding().latin1() ) );
886  sourceStr = stream.read();
887  f.close();
888  }
889  KIO::NetAccess::removeTempFile( tmpFile );
890  }
891  }
892 
893  return sourceStr;
894 }
895 
896 
897 KParts::BrowserExtension *KHTMLPart::browserExtension() const
898 {
899  return d->m_extension;
900 }
901 
902 KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
903 {
904  return d->m_hostExtension;
905 }
906 
907 KHTMLView *KHTMLPart::view() const
908 {
909  return d->m_view;
910 }
911 
912 void KHTMLPart::setStatusMessagesEnabled( bool enable )
913 {
914  d->m_statusMessagesEnabled = enable;
915 }
916 
917 KJS::Interpreter *KHTMLPart::jScriptInterpreter()
918 {
919  KJSProxy *proxy = jScript();
920  if (!proxy || proxy->paused())
921  return 0;
922 
923  return proxy->interpreter();
924 }
925 
926 bool KHTMLPart::statusMessagesEnabled() const
927 {
928  return d->m_statusMessagesEnabled;
929 }
930 
931 void KHTMLPart::setJScriptEnabled( bool enable )
932 {
933  if ( !enable && jScriptEnabled() && d->m_frame && d->m_frame->m_jscript ) {
934  d->m_frame->m_jscript->clear();
935  }
936  d->m_bJScriptForce = enable;
937  d->m_bJScriptOverride = true;
938 }
939 
940 bool KHTMLPart::jScriptEnabled() const
941 {
942  if(onlyLocalReferences()) return false;
943 
944  if ( d->m_bJScriptOverride )
945  return d->m_bJScriptForce;
946  return d->m_bJScriptEnabled;
947 }
948 
949 void KHTMLPart::setMetaRefreshEnabled( bool enable )
950 {
951  d->m_metaRefreshEnabled = enable;
952 }
953 
954 bool KHTMLPart::metaRefreshEnabled() const
955 {
956  return d->m_metaRefreshEnabled;
957 }
958 
959 // Define this to disable dlopening kjs_html, when directly linking to it.
960 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
961 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
962 // remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
963 // Also, change the order of "ecma" and "." in khtml's SUBDIRS line.
964 // OK - that's the default now, use the opposite of the above instructions to go back
965 // to "dlopening it" - but it breaks exception catching in kjs_binding.cpp
966 #define DIRECT_LINKAGE_TO_ECMA
967 
968 #ifdef DIRECT_LINKAGE_TO_ECMA
969 extern "C" { KJSProxy *kjs_html_init(khtml::ChildFrame * childframe); }
970 #endif
971 
972 static bool createJScript(khtml::ChildFrame *frame)
973 {
974 #ifndef DIRECT_LINKAGE_TO_ECMA
975  KLibrary *lib = KLibLoader::self()->library("kjs_html");
976  if ( !lib ) {
977  setJScriptEnabled( false );
978  return false;
979  }
980  // look for plain C init function
981  void *sym = lib->symbol("kjs_html_init");
982  if ( !sym ) {
983  lib->unload();
984  setJScriptEnabled( false );
985  return false;
986  }
987  typedef KJSProxy* (*initFunction)(khtml::ChildFrame *);
988  initFunction initSym = (initFunction) sym;
989  frame->m_jscript = (*initSym)(d->m_frame);
990  frame->m_kjs_lib = lib;
991 #else
992  frame->m_jscript = kjs_html_init(frame);
993  // frame->m_kjs_lib remains 0L.
994 #endif
995  return true;
996 }
997 
998 KJSProxy *KHTMLPart::jScript()
999 {
1000  if (!jScriptEnabled()) return 0;
1001 
1002  if ( !d->m_frame ) {
1003  KHTMLPart * p = parentPart();
1004  if (!p) {
1005  d->m_frame = new khtml::ChildFrame;
1006  d->m_frame->m_part = this;
1007  } else {
1008  ConstFrameIt it = p->d->m_frames.begin();
1009  const ConstFrameIt end = p->d->m_frames.end();
1010  for (; it != end; ++it)
1011  if ((*it)->m_part.operator->() == this) {
1012  d->m_frame = *it;
1013  break;
1014  }
1015  }
1016  if ( !d->m_frame )
1017  return 0;
1018  }
1019  if ( !d->m_frame->m_jscript )
1020  if (!createJScript(d->m_frame))
1021  return 0;
1022  if (d->m_bJScriptDebugEnabled)
1023  d->m_frame->m_jscript->setDebugEnabled(true);
1024 
1025  return d->m_frame->m_jscript;
1026 }
1027 
1028 TQVariant KHTMLPart::crossFrameExecuteScript(const TQString& target, const TQString& script)
1029 {
1030  KHTMLPart* destpart = this;
1031 
1032  TQString trg = target.lower();
1033 
1034  if (target == "_top") {
1035  while (destpart->parentPart())
1036  destpart = destpart->parentPart();
1037  }
1038  else if (target == "_parent") {
1039  if (parentPart())
1040  destpart = parentPart();
1041  }
1042  else if (target == "_self" || target == "_blank") {
1043  // we always allow these
1044  }
1045  else {
1046  destpart = findFrame(target);
1047  if (!destpart)
1048  destpart = this;
1049  }
1050 
1051  // easy way out?
1052  if (destpart == this)
1053  return executeScript(DOM::Node(), script);
1054 
1055  // now compare the domains
1056  if (destpart->checkFrameAccess(this))
1057  return destpart->executeScript(DOM::Node(), script);
1058 
1059  // eww, something went wrong. better execute it in our frame
1060  return executeScript(DOM::Node(), script);
1061 }
1062 
1063 //Enable this to see all JS scripts being executed
1064 //#define KJS_VERBOSE
1065 
1066 KJSErrorDlg *KHTMLPart::jsErrorExtension() {
1067  if (!d->m_settings->jsErrorsEnabled()) {
1068  return 0L;
1069  }
1070 
1071  if (parentPart()) {
1072  return parentPart()->jsErrorExtension();
1073  }
1074 
1075  if (!d->m_statusBarJSErrorLabel) {
1076  d->m_statusBarJSErrorLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
1077  d->m_statusBarJSErrorLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
1078  d->m_statusBarJSErrorLabel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
1079  d->m_statusBarJSErrorLabel->setUseCursor(false);
1080  d->m_statusBarExtension->addStatusBarItem(d->m_statusBarJSErrorLabel, 0, false);
1081  TQToolTip::add(d->m_statusBarJSErrorLabel, i18n("This web page contains coding errors."));
1082  d->m_statusBarJSErrorLabel->setPixmap(SmallIcon("bug", instance()));
1083  connect(d->m_statusBarJSErrorLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(launchJSErrorDialog()));
1084  connect(d->m_statusBarJSErrorLabel, TQT_SIGNAL(rightClickedURL()), TQT_SLOT(jsErrorDialogContextMenu()));
1085  }
1086  if (!d->m_jsedlg) {
1087  d->m_jsedlg = new KJSErrorDlg;
1088  d->m_jsedlg->setURL(m_url.prettyURL());
1089  if (KGlobalSettings::showIconsOnPushButtons()) {
1090  d->m_jsedlg->_clear->setIconSet(SmallIconSet("locationbar_erase"));
1091  d->m_jsedlg->_close->setIconSet(SmallIconSet("fileclose"));
1092  }
1093  }
1094  return d->m_jsedlg;
1095 }
1096 
1097 void KHTMLPart::removeJSErrorExtension() {
1098  if (parentPart()) {
1099  parentPart()->removeJSErrorExtension();
1100  return;
1101  }
1102  if (d->m_statusBarJSErrorLabel != 0) {
1103  d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarJSErrorLabel );
1104  delete d->m_statusBarJSErrorLabel;
1105  d->m_statusBarJSErrorLabel = 0;
1106  }
1107  delete d->m_jsedlg;
1108  d->m_jsedlg = 0;
1109 }
1110 
1111 void KHTMLPart::disableJSErrorExtension() {
1112  removeJSErrorExtension();
1113  // These two lines are really kind of hacky, and it sucks to do this inside
1114  // KHTML but I don't know of anything that's reasonably easy as an alternative
1115  // right now. It makes me wonder if there should be a more clean way to
1116  // contact all running "KHTML" instance as opposed to Konqueror instances too.
1117  d->m_settings->setJSErrorsEnabled(false);
1118  DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", TQByteArray());
1119 }
1120 
1121 void KHTMLPart::jsErrorDialogContextMenu() {
1122  KPopupMenu *m = new KPopupMenu(0L);
1123  m->insertItem(i18n("&Hide Errors"), this, TQT_SLOT(removeJSErrorExtension()));
1124  m->insertItem(i18n("&Disable Error Reporting"), this, TQT_SLOT(disableJSErrorExtension()));
1125  m->popup(TQCursor::pos());
1126 }
1127 
1128 void KHTMLPart::launchJSErrorDialog() {
1129  KJSErrorDlg *dlg = jsErrorExtension();
1130  if (dlg) {
1131  dlg->show();
1132  dlg->raise();
1133  }
1134 }
1135 
1136 void KHTMLPart::launchJSConfigDialog() {
1137  TQStringList args;
1138  args << "khtml_java_js";
1139  KApplication::kdeinitExec( "kcmshell", args );
1140 }
1141 
1142 TQVariant KHTMLPart::executeScript(const TQString& filename, int baseLine, const DOM::Node& n, const TQString& script)
1143 {
1144 #ifdef KJS_VERBOSE
1145  // The script is now printed by KJS's Parser::parse
1146  kdDebug(6070) << "executeScript: caller='" << name() << "' filename=" << filename << " baseLine=" << baseLine /*<< " script=" << script*/ << endl;
1147 #endif
1148  KJSProxy *proxy = jScript();
1149 
1150  if (!proxy || proxy->paused())
1151  return TQVariant();
1152 
1153  KJS::Completion comp;
1154 
1155  TQVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);
1156 
1157  /*
1158  * Error handling
1159  */
1160  if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
1161  KJSErrorDlg *dlg = jsErrorExtension();
1162  if (dlg) {
1163  KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
1164  dlg->addError(i18n("<b>Error</b>: %1: %2").arg(filename, msg.qstring()));
1165  }
1166  }
1167 
1168  // Handle immediate redirects now (e.g. location='foo')
1169  if ( !d->m_redirectURL.isEmpty() && d->m_delayRedirect == -1 )
1170  {
1171  kdDebug(6070) << "executeScript done, handling immediate redirection NOW" << endl;
1172  // Must abort tokenizer, no further script must execute.
1173  khtml::Tokenizer* t = d->m_doc->tokenizer();
1174  if(t)
1175  t->abort();
1176  d->m_redirectionTimer.start( 0, true );
1177  }
1178 
1179  return ret;
1180 }
1181 
1182 TQVariant KHTMLPart::executeScript( const TQString &script )
1183 {
1184  return executeScript( DOM::Node(), script );
1185 }
1186 
1187 TQVariant KHTMLPart::executeScript( const DOM::Node &n, const TQString &script )
1188 {
1189 #ifdef KJS_VERBOSE
1190  kdDebug(6070) << "KHTMLPart::executeScript caller='" << name() << "' node=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " /* << script */ << endl;
1191 #endif
1192  KJSProxy *proxy = jScript();
1193 
1194  if (!proxy || proxy->paused())
1195  return TQVariant();
1196  ++(d->m_runningScripts);
1197  KJS::Completion comp;
1198  const TQVariant ret = proxy->evaluate( TQString(), 1, script, n, &comp );
1199  --(d->m_runningScripts);
1200 
1201  /*
1202  * Error handling
1203  */
1204  if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
1205  KJSErrorDlg *dlg = jsErrorExtension();
1206  if (dlg) {
1207  KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
1208  dlg->addError(i18n("<b>Error</b>: node %1: %2").arg(n.nodeName().string()).arg(msg.qstring()));
1209  }
1210  }
1211 
1212  if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
1213  submitFormAgain();
1214 
1215 #ifdef KJS_VERBOSE
1216  kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
1217 #endif
1218  return ret;
1219 }
1220 
1221 bool KHTMLPart::scheduleScript(const DOM::Node &n, const TQString& script)
1222 {
1223  //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
1224 
1225  d->scheduledScript = script;
1226  d->scheduledScriptNode = n;
1227 
1228  return true;
1229 }
1230 
1231 TQVariant KHTMLPart::executeScheduledScript()
1232 {
1233  if( d->scheduledScript.isEmpty() )
1234  return TQVariant();
1235 
1236  //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
1237 
1238  TQVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
1239  d->scheduledScript = TQString();
1240  d->scheduledScriptNode = DOM::Node();
1241 
1242  return ret;
1243 }
1244 
1245 void KHTMLPart::setJavaEnabled( bool enable )
1246 {
1247  d->m_bJavaForce = enable;
1248  d->m_bJavaOverride = true;
1249 }
1250 
1251 bool KHTMLPart::javaEnabled() const
1252 {
1253  if (onlyLocalReferences()) return false;
1254 
1255 #ifndef Q_WS_QWS
1256  if( d->m_bJavaOverride )
1257  return d->m_bJavaForce;
1258  return d->m_bJavaEnabled;
1259 #else
1260  return false;
1261 #endif
1262 }
1263 
1264 KJavaAppletContext *KHTMLPart::javaContext()
1265 {
1266  return 0;
1267 }
1268 
1269 KJavaAppletContext *KHTMLPart::createJavaContext()
1270 {
1271  return 0;
1272 }
1273 
1274 void KHTMLPart::setPluginsEnabled( bool enable )
1275 {
1276  d->m_bPluginsForce = enable;
1277  d->m_bPluginsOverride = true;
1278 }
1279 
1280 bool KHTMLPart::pluginsEnabled() const
1281 {
1282  if (onlyLocalReferences()) return false;
1283 
1284  if ( d->m_bPluginsOverride )
1285  return d->m_bPluginsForce;
1286  return d->m_bPluginsEnabled;
1287 }
1288 
1289 static int s_DOMTreeIndentLevel = 0;
1290 
1291 void KHTMLPart::slotDebugDOMTree()
1292 {
1293  if ( d->m_doc && d->m_doc->firstChild() )
1294  qDebug("%s", d->m_doc->firstChild()->toString().string().latin1());
1295 
1296  // Now print the contents of the frames that contain HTML
1297 
1298  const int indentLevel = s_DOMTreeIndentLevel++;
1299 
1300  ConstFrameIt it = d->m_frames.begin();
1301  const ConstFrameIt end = d->m_frames.end();
1302  for (; it != end; ++it )
1303  if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
1304  KParts::ReadOnlyPart* const p = ( *it )->m_part;
1305  kdDebug(6050) << TQString().leftJustify(s_DOMTreeIndentLevel*4,' ') << "FRAME " << p->name() << " " << endl;
1306  static_cast<KHTMLPart*>( p )->slotDebugDOMTree();
1307  }
1308  s_DOMTreeIndentLevel = indentLevel;
1309 }
1310 
1311 void KHTMLPart::slotDebugScript()
1312 {
1313  if (jScript())
1314  jScript()->showDebugWindow();
1315 }
1316 
1317 void KHTMLPart::slotDebugRenderTree()
1318 {
1319 #ifndef NDEBUG
1320  if ( d->m_doc ) {
1321  d->m_doc->renderer()->printTree();
1322  // dump out the contents of the rendering & DOM trees
1323 // TQString dumps;
1324 // TQTextStream outputStream(dumps,IO_WriteOnly);
1325 // d->m_doc->renderer()->layer()->dump( outputStream );
1326 // kdDebug() << "dump output:" << "\n" + dumps;
1327  }
1328 #endif
1329 }
1330 
1331 void KHTMLPart::slotStopAnimations()
1332 {
1333  stopAnimations();
1334 }
1335 
1336 void KHTMLPart::setAutoloadImages( bool enable )
1337 {
1338  if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
1339  return;
1340 
1341  if ( d->m_doc )
1342  d->m_doc->docLoader()->setAutoloadImages( enable );
1343 
1344  unplugActionList( "loadImages" );
1345 
1346  if ( enable ) {
1347  delete d->m_paLoadImages;
1348  d->m_paLoadImages = 0;
1349  }
1350  else if ( !d->m_paLoadImages )
1351  d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, TQT_SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
1352 
1353  if ( d->m_paLoadImages ) {
1354  TQPtrList<KAction> lst;
1355  lst.append( d->m_paLoadImages );
1356  plugActionList( "loadImages", lst );
1357  }
1358 }
1359 
1360 bool KHTMLPart::autoloadImages() const
1361 {
1362  if ( d->m_doc )
1363  return d->m_doc->docLoader()->autoloadImages();
1364 
1365  return true;
1366 }
1367 
1368 void KHTMLPart::clear()
1369 {
1370  if ( d->m_bCleared )
1371  return;
1372 
1373  d->m_bCleared = true;
1374 
1375  d->m_bClearing = true;
1376 
1377  {
1378  ConstFrameIt it = d->m_frames.begin();
1379  const ConstFrameIt end = d->m_frames.end();
1380  for(; it != end; ++it )
1381  {
1382  // Stop HTMLRun jobs for frames
1383  if ( (*it)->m_run )
1384  (*it)->m_run->abort();
1385  }
1386  }
1387 
1388  {
1389  ConstFrameIt it = d->m_objects.begin();
1390  const ConstFrameIt end = d->m_objects.end();
1391  for(; it != end; ++it )
1392  {
1393  // Stop HTMLRun jobs for objects
1394  if ( (*it)->m_run )
1395  (*it)->m_run->abort();
1396  }
1397  }
1398 
1399 
1400  findTextBegin(); // resets d->m_findNode and d->m_findPos
1401  d->m_mousePressNode = DOM::Node();
1402 
1403 
1404  if ( d->m_doc )
1405  {
1406  if (d->m_doc->attached()) //the view may have detached it already
1407  d->m_doc->detach();
1408  }
1409 
1410  // Moving past doc so that onUnload works.
1411  if ( d->m_frame && d->m_frame->m_jscript )
1412  d->m_frame->m_jscript->clear();
1413 
1414  // stopping marquees
1415  if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->layer())
1416  d->m_doc->renderer()->layer()->suspendMarquees();
1417 
1418  if ( d->m_view )
1419  d->m_view->clear();
1420 
1421  // do not dereference the document before the jscript and view are cleared, as some destructors
1422  // might still try to access the document.
1423  if ( d->m_doc ) {
1424  d->m_doc->deref();
1425  }
1426  d->m_doc = 0;
1427 
1428  delete d->m_decoder;
1429  d->m_decoder = 0;
1430 
1431  // We don't want to change between parts if we are going to delete all of them anyway
1432  if (partManager()) {
1433  disconnect( partManager(), TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
1434  this, TQT_SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
1435  }
1436 
1437  if (d->m_frames.count())
1438  {
1439  KHTMLFrameList frames = d->m_frames;
1440  d->m_frames.clear();
1441  ConstFrameIt it = frames.begin();
1442  const ConstFrameIt end = frames.end();
1443  for(; it != end; ++it )
1444  {
1445  if ( (*it)->m_part )
1446  {
1447  partManager()->removePart( (*it)->m_part );
1448  delete (KParts::ReadOnlyPart *)(*it)->m_part;
1449  }
1450  delete *it;
1451  }
1452  }
1453  d->m_suppressedPopupOriginParts.clear();
1454 
1455  if (d->m_objects.count())
1456  {
1457  KHTMLFrameList objects = d->m_objects;
1458  d->m_objects.clear();
1459  ConstFrameIt oi = objects.begin();
1460  const ConstFrameIt oiEnd = objects.end();
1461 
1462  for (; oi != oiEnd; ++oi )
1463  delete *oi;
1464  }
1465 
1466  // Listen to part changes again
1467  if (partManager()) {
1468  connect( partManager(), TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
1469  this, TQT_SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
1470  }
1471 
1472  d->m_delayRedirect = 0;
1473  d->m_redirectURL = TQString();
1474  d->m_redirectionTimer.stop();
1475  d->m_redirectLockHistory = true;
1476  d->m_bClearing = false;
1477  d->m_frameNameId = 1;
1478  d->m_bFirstData = true;
1479 
1480  d->m_bMousePressed = false;
1481 
1482  d->m_selectionStart = DOM::Node();
1483  d->m_selectionEnd = DOM::Node();
1484  d->m_startOffset = 0;
1485  d->m_endOffset = 0;
1486 #ifndef QT_NO_CLIPBOARD
1487  connect( kapp->clipboard(), TQT_SIGNAL( selectionChanged()), TQT_SLOT( slotClearSelection()));
1488 #endif
1489 
1490  d->m_jobPercent = 0;
1491 
1492  if ( !d->m_haveEncoding )
1493  d->m_encoding = TQString();
1494 #ifdef SPEED_DEBUG
1495  d->m_parsetime.restart();
1496 #endif
1497 }
1498 
1499 bool KHTMLPart::openFile()
1500 {
1501  return true;
1502 }
1503 
1504 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
1505 {
1506  if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
1507  return static_cast<HTMLDocumentImpl*>(d->m_doc);
1508  return 0;
1509 }
1510 
1511 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
1512 {
1513  if ( d )
1514  return d->m_doc;
1515  return 0;
1516 }
1517 
1518 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const TQString& msg)
1519 {
1520  assert(d->m_job == kio_job);
1521 
1522  if (!parentPart())
1523  setStatusBarText(msg, BarDefaultText);
1524 }
1525 
1526 void KHTMLPart::setPageSecurity( PageSecurity sec )
1527 {
1528  emit d->m_extension->setPageSecurity( sec );
1529  if ( sec != NotCrypted && !d->m_statusBarIconLabel && !parentPart() ) {
1530  d->m_statusBarIconLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
1531  d->m_statusBarIconLabel->setFixedHeight( instance()->iconLoader()->currentSize(KIcon::Small) );
1532  d->m_statusBarIconLabel->setSizePolicy(TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ));
1533  d->m_statusBarIconLabel->setUseCursor( false );
1534  d->m_statusBarExtension->addStatusBarItem( d->m_statusBarIconLabel, 0, false );
1535  connect( d->m_statusBarIconLabel, TQT_SIGNAL( leftClickedURL() ), TQT_SLOT( slotSecurity() ) );
1536  } else if (d->m_statusBarIconLabel) {
1537  TQToolTip::remove(d->m_statusBarIconLabel);
1538  }
1539 
1540  if (d->m_statusBarIconLabel) {
1541  if (d->m_ssl_in_use)
1542  TQToolTip::add(d->m_statusBarIconLabel,
1543  i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
1544  else TQToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
1545  }
1546 
1547  TQString iconName;
1548  switch (sec) {
1549  case NotCrypted:
1550  iconName = "decrypted";
1551  if ( d->m_statusBarIconLabel ) {
1552  d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarIconLabel );
1553  delete d->m_statusBarIconLabel;
1554  d->m_statusBarIconLabel = 0L;
1555  }
1556  break;
1557  case Encrypted:
1558  iconName = "encrypted";
1559  break;
1560  case Mixed:
1561  iconName = "halfencrypted";
1562  break;
1563  }
1564  d->m_paSecurity->setIcon( iconName );
1565  if ( d->m_statusBarIconLabel )
1566  d->m_statusBarIconLabel->setPixmap( SmallIcon( iconName, instance() ) );
1567 }
1568 
1569 void KHTMLPart::slotData( KIO::Job* kio_job, const TQByteArray &data )
1570 {
1571  assert ( d->m_job == kio_job );
1572 
1573  //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
1574  // The first data ?
1575  if ( !d->m_workingURL.isEmpty() )
1576  {
1577  //kdDebug( 6050 ) << "begin!" << endl;
1578 
1579  // We must suspend KIO while we're inside begin() because it can cause
1580  // crashes if a window (such as kjsdebugger) goes back into the event loop,
1581  // more data arrives, and begin() gets called again (re-entered).
1582  d->m_job->suspend();
1583  begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1584  d->m_job->resume();
1585 
1586  if (d->m_cachePolicy == KIO::CC_Refresh)
1587  d->m_doc->docLoader()->setCachePolicy(KIO::CC_Verify);
1588  else
1589  d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
1590 
1591  d->m_workingURL = KURL();
1592 
1593  d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
1594 
1595  // When the first data arrives, the metadata has just been made available
1596  d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
1597  time_t cacheCreationDate = d->m_job->queryMetaData("cache-creation-date").toLong();
1598  d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);
1599 
1600  d->m_pageServices = d->m_job->queryMetaData("PageServices");
1601  d->m_pageReferrer = d->m_job->queryMetaData("referrer");
1602  d->m_bSecurityInQuestion = false;
1603  d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
1604 
1605  {
1606  KHTMLPart *p = parentPart();
1607  if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
1608  while (p->parentPart()) p = p->parentPart();
1609 
1610  p->setPageSecurity( Mixed );
1611  p->d->m_bSecurityInQuestion = true;
1612  }
1613  }
1614 
1615  setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
1616 
1617  // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
1618  d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
1619  d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
1620  d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
1621  d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
1622  d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
1623  d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
1624  d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
1625  d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
1626  d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
1627  d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
1628  d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
1629 
1630  if (d->m_statusBarIconLabel) {
1631  TQToolTip::remove(d->m_statusBarIconLabel);
1632  if (d->m_ssl_in_use) {
1633  TQToolTip::add(d->m_statusBarIconLabel, i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
1634  } else {
1635  TQToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
1636  }
1637  }
1638 
1639  // Check for charset meta-data
1640  TQString qData = d->m_job->queryMetaData("charset");
1641  if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
1642  d->m_encoding = qData;
1643 
1644 
1645  // Support for http-refresh
1646  qData = d->m_job->queryMetaData("http-refresh");
1647  if( !qData.isEmpty())
1648  d->m_doc->processHttpEquiv("refresh", qData);
1649 
1650  // DISABLED: Support Content-Location per section 14.14 of RFC 2616.
1651  // See BR# 51185,BR# 82747
1652  /*
1653  TQString baseURL = d->m_job->queryMetaData ("content-location");
1654  if (!baseURL.isEmpty())
1655  d->m_doc->setBaseURL(KURL( d->m_doc->completeURL(baseURL) ));
1656  */
1657 
1658  // Support for Content-Language
1659  TQString language = d->m_job->queryMetaData("content-language");
1660  if (!language.isEmpty())
1661  d->m_doc->setContentLanguage(language);
1662 
1663  if ( !m_url.isLocalFile() ) {
1664  // Support for http last-modified
1665  d->m_lastModified = d->m_job->queryMetaData("modified");
1666  } else
1667  d->m_lastModified = TQString(); // done on-demand by lastModified()
1668  }
1669 
1670  KHTMLPageCache::self()->addData(d->m_cacheId, data);
1671  write( data.data(), data.size() );
1672  if (d->m_frame && d->m_frame->m_jscript)
1673  d->m_frame->m_jscript->dataReceived();
1674 }
1675 
1676 void KHTMLPart::slotRestoreData(const TQByteArray &data )
1677 {
1678  // The first data ?
1679  if ( !d->m_workingURL.isEmpty() )
1680  {
1681  long saveCacheId = d->m_cacheId;
1682  TQString savePageReferrer = d->m_pageReferrer;
1683  TQString saveEncoding = d->m_encoding;
1684  begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1685  d->m_encoding = saveEncoding;
1686  d->m_pageReferrer = savePageReferrer;
1687  d->m_cacheId = saveCacheId;
1688  d->m_workingURL = KURL();
1689  }
1690 
1691  //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
1692  write( data.data(), data.size() );
1693 
1694  if (data.size() == 0)
1695  {
1696  //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
1697  // End of data.
1698  if (d->m_doc && d->m_doc->parsing())
1699  end(); //will emit completed()
1700  }
1701 }
1702 
1703 void KHTMLPart::showError( KIO::Job* job )
1704 {
1705  kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
1706  << " d->m_bCleared=" << d->m_bCleared << endl;
1707 
1708  if (job->error() == KIO::ERR_NO_CONTENT)
1709  return;
1710 
1711  if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
1712  job->showErrorDialog( /*d->m_view*/ );
1713  else
1714  {
1715  htmlError( job->error(), job->errorText(), d->m_workingURL );
1716  }
1717 }
1718 
1719 // This is a protected method, placed here because of it's relevance to showError
1720 void KHTMLPart::htmlError( int errorCode, const TQString& text, const KURL& reqUrl )
1721 {
1722  kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
1723  // make sure we're not executing any embedded JS
1724  bool bJSFO = d->m_bJScriptForce;
1725  bool bJSOO = d->m_bJScriptOverride;
1726  d->m_bJScriptForce = false;
1727  d->m_bJScriptOverride = true;
1728  begin();
1729  TQString errText = TQString::fromLatin1( "<HTML dir=%1><HEAD><TITLE>" )
1730  .arg(TQApplication::reverseLayout() ? "rtl" : "ltr");
1731  errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
1732  errText += TQString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
1733  errText += i18n( "An error occurred while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
1734  errText += TQString::fromLatin1( "</P>" );
1735  errText += TQStyleSheet::convertFromPlainText( KIO::buildErrorString( errorCode, text ) );
1736  errText += TQString::fromLatin1( "</BODY></HTML>" );
1737  write(errText);
1738  end();
1739 
1740  d->m_bJScriptForce = bJSFO;
1741  d->m_bJScriptOverride = bJSOO;
1742 
1743  // make the working url the current url, so that reload works and
1744  // emit the progress signals to advance one step in the history
1745  // (so that 'back' works)
1746  m_url = reqUrl; // same as d->m_workingURL
1747  d->m_workingURL = KURL();
1748  emit started( 0 );
1749  emit completed();
1750  return;
1751  // following disabled until 3.1
1752 
1753  TQString errorName, techName, description;
1754  TQStringList causes, solutions;
1755 
1756  TQByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
1757  TQDataStream stream(raw, IO_ReadOnly);
1758 
1759  stream >> errorName >> techName >> description >> causes >> solutions;
1760 
1761  TQString url, protocol, datetime;
1762  url = reqUrl.prettyURL();
1763  protocol = reqUrl.protocol();
1764  datetime = KGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(),
1765  false );
1766 
1767  TQString doc = TQString::fromLatin1( "<html><head><title>" );
1768  doc += i18n( "Error: " );
1769  doc += errorName;
1770  doc += TQString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
1771  doc += i18n( "The requested operation could not be completed" );
1772  doc += TQString::fromLatin1( "</h1><h2>" );
1773  doc += errorName;
1774  doc += TQString::fromLatin1( "</h2>" );
1775  if ( !techName.isNull() ) {
1776  doc += TQString::fromLatin1( "<h2>" );
1777  doc += i18n( "Technical Reason: " );
1778  doc += techName;
1779  doc += TQString::fromLatin1( "</h2>" );
1780  }
1781  doc += TQString::fromLatin1( "<h3>" );
1782  doc += i18n( "Details of the Request:" );
1783  doc += TQString::fromLatin1( "</h3><ul><li>" );
1784  doc += i18n( "URL: %1" ).arg( url );
1785  doc += TQString::fromLatin1( "</li><li>" );
1786  if ( !protocol.isNull() ) {
1787  // uncomment for 3.1... i18n change
1788  // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
1789  doc += TQString::fromLatin1( "</li><li>" );
1790  }
1791  doc += i18n( "Date and Time: %1" ).arg( datetime );
1792  doc += TQString::fromLatin1( "</li><li>" );
1793  doc += i18n( "Additional Information: %1" ).arg( text );
1794  doc += TQString::fromLatin1( "</li></ul><h3>" );
1795  doc += i18n( "Description:" );
1796  doc += TQString::fromLatin1( "</h3><p>" );
1797  doc += description;
1798  doc += TQString::fromLatin1( "</p>" );
1799  if ( causes.count() ) {
1800  doc += TQString::fromLatin1( "<h3>" );
1801  doc += i18n( "Possible Causes:" );
1802  doc += TQString::fromLatin1( "</h3><ul><li>" );
1803  doc += causes.join( "</li><li>" );
1804  doc += TQString::fromLatin1( "</li></ul>" );
1805  }
1806  if ( solutions.count() ) {
1807  doc += TQString::fromLatin1( "<h3>" );
1808  doc += i18n( "Possible Solutions:" );
1809  doc += TQString::fromLatin1( "</h3><ul><li>" );
1810  doc += solutions.join( "</li><li>" );
1811  doc += TQString::fromLatin1( "</li></ul>" );
1812  }
1813  doc += TQString::fromLatin1( "</body></html>" );
1814 
1815  write( doc );
1816  end();
1817 }
1818 
1819 void KHTMLPart::slotFinished( KIO::Job * job )
1820 {
1821  d->m_job = 0L;
1822  d->m_jobspeed = 0L;
1823 
1824  if (job->error())
1825  {
1826  KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
1827 
1828  // The following catches errors that occur as a result of HTTP
1829  // to FTP redirections where the FTP URL is a directory. Since
1830  // KIO cannot change a redirection request from GET to LISTDIR,
1831  // we have to take care of it here once we know for sure it is
1832  // a directory...
1833  if (job->error() == KIO::ERR_IS_DIRECTORY)
1834  {
1835  KParts::URLArgs args;
1836  emit d->m_extension->openURLRequest( d->m_workingURL, args );
1837  }
1838  else
1839  {
1840  emit canceled( job->errorString() );
1841  // TODO: what else ?
1842  checkCompleted();
1843  showError( job );
1844  }
1845 
1846  return;
1847  }
1848  KIO::TransferJob *tjob = ::tqqt_cast<KIO::TransferJob*>(job);
1849  if (tjob && tjob->isErrorPage()) {
1850  khtml::RenderPart *renderPart = d->m_frame ? static_cast<khtml::RenderPart *>(d->m_frame->m_frame) : 0;
1851  if (renderPart) {
1852  HTMLObjectElementImpl* elt = static_cast<HTMLObjectElementImpl *>(renderPart->element());
1853  if (!elt)
1854  return;
1855  elt->renderAlternative();
1856  checkCompleted();
1857  }
1858  if (d->m_bComplete) return;
1859  }
1860 
1861  //kdDebug( 6050 ) << "slotFinished" << endl;
1862 
1863  KHTMLPageCache::self()->endData(d->m_cacheId);
1864  if (d->m_frame && d->m_frame->m_jscript)
1865  d->m_frame->m_jscript->dataReceived();
1866 
1867  if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
1868  KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
1869 
1870  d->m_workingURL = KURL();
1871 
1872  if ( d->m_doc && d->m_doc->parsing())
1873  end(); //will emit completed()
1874 }
1875 
1876 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
1877 {
1878  // No need to show this for a new page until an error is triggered
1879  if (!parentPart()) {
1880  removeJSErrorExtension();
1881  setSuppressedPopupIndicator( false );
1882  d->m_openableSuppressedPopups = 0;
1883  for ( TQValueListIterator<TQGuardedPtr<KHTMLPart> > i = d->m_suppressedPopupOriginParts.begin();
1884  i != d->m_suppressedPopupOriginParts.end(); ++i ) {
1885 
1886  if (KHTMLPart* part = *i) {
1887  KJS::Window *w = KJS::Window::retrieveWindow( part );
1888  if (w)
1889  w->forgetSuppressedWindows();
1890  }
1891  }
1892  }
1893 
1894  clear();
1895  d->m_bCleared = false;
1896  d->m_cacheId = 0;
1897  d->m_bComplete = false;
1898  d->m_bLoadEventEmitted = false;
1899 
1900  if(url.isValid()) {
1901  TQString urlString = url.url();
1902  KHTMLFactory::vLinks()->insert( urlString );
1903  TQString urlString2 = url.prettyURL();
1904  if ( urlString != urlString2 ) {
1905  KHTMLFactory::vLinks()->insert( urlString2 );
1906  }
1907  }
1908 
1909 
1910  // ###
1911  //stopParser();
1912 
1913  KParts::URLArgs args( d->m_extension->urlArgs() );
1914  args.xOffset = xOffset;
1915  args.yOffset = yOffset;
1916  d->m_extension->setURLArgs( args );
1917 
1918  d->m_pageReferrer = TQString();
1919 
1920  KURL ref(url);
1921  d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : "";
1922 
1923  m_url = url;
1924 
1925  bool servedAsXHTML = args.serviceType == "application/xhtml+xml";
1926  bool servedAsXML = KMimeType::mimeType(args.serviceType)->is( "text/xml" );
1927  // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
1928  if ( servedAsXML && !servedAsXHTML ) { // any XML derivative, except XHTML
1929  d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
1930  } else {
1931  d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
1932  // HTML or XHTML? (#86446)
1933  static_cast<HTMLDocumentImpl *>(d->m_doc)->setHTMLRequested( !servedAsXHTML );
1934  }
1935 #ifndef KHTML_NO_CARET
1936 // d->m_view->initCaret();
1937 #endif
1938 
1939  d->m_doc->ref();
1940  d->m_doc->setURL( m_url.url() );
1941  if (!d->m_doc->attached())
1942  d->m_doc->attach( );
1943  d->m_doc->setBaseURL( KURL() );
1944  d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
1945  emit docCreated();
1946 
1947  d->m_paUseStylesheet->setItems(TQStringList());
1948  d->m_paUseStylesheet->setEnabled( false );
1949 
1950  setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
1951  TQString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
1952  if ( !userStyleSheet.isEmpty() )
1953  setUserStyleSheet( KURL( userStyleSheet ) );
1954 
1955  d->m_doc->setRestoreState(args.docState);
1956  d->m_doc->open();
1957  connect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
1958 
1959  emit d->m_extension->enableAction( "print", true );
1960 
1961  d->m_doc->setParsing(true);
1962 }
1963 
1964 void KHTMLPart::write( const char *str, int len )
1965 {
1966  if ( !d->m_decoder )
1967  d->m_decoder = createDecoder();
1968 
1969  if ( len == -1 )
1970  len = strlen( str );
1971 
1972  if ( len == 0 )
1973  return;
1974 
1975  TQString decoded = d->m_decoder->decode( str, len );
1976 
1977  if(decoded.isEmpty()) return;
1978 
1979  if(d->m_bFirstData) {
1980  // determine the parse mode
1981  d->m_doc->determineParseMode( decoded );
1982  d->m_bFirstData = false;
1983 
1984  //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
1985  // ### this is still quite hacky, but should work a lot better than the old solution
1986  if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
1987  d->m_doc->setDecoderCodec(d->m_decoder->codec());
1988  d->m_doc->recalcStyle( NodeImpl::Force );
1989  }
1990 
1991  khtml::Tokenizer* t = d->m_doc->tokenizer();
1992  if(t)
1993  t->write( decoded, true );
1994 }
1995 
1996 void KHTMLPart::write( const TQString &str )
1997 {
1998  if ( str.isNull() )
1999  return;
2000 
2001  if(d->m_bFirstData) {
2002  // determine the parse mode
2003  d->m_doc->setParseMode( DocumentImpl::Strict );
2004  d->m_bFirstData = false;
2005  }
2006  khtml::Tokenizer* t = d->m_doc->tokenizer();
2007  if(t)
2008  t->write( str, true );
2009 }
2010 
2011 void KHTMLPart::end()
2012 {
2013  if (d->m_doc) {
2014  if (d->m_decoder) {
2015  TQString decoded = d->m_decoder->flush();
2016  if (d->m_bFirstData) {
2017  d->m_bFirstData = false;
2018  d->m_doc->determineParseMode(decoded);
2019  }
2020  write(decoded);
2021  }
2022  d->m_doc->finishParsing();
2023  }
2024 }
2025 
2026 bool KHTMLPart::doOpenStream( const TQString& mimeType )
2027 {
2028  KMimeType::Ptr mime = KMimeType::mimeType(mimeType);
2029  if ( mime->is( "text/html" ) || mime->is( "text/xml" ) )
2030  {
2031  begin( url() );
2032  return true;
2033  }
2034  return false;
2035 }
2036 
2037 bool KHTMLPart::doWriteStream( const TQByteArray& data )
2038 {
2039  write( data.data(), data.size() );
2040  return true;
2041 }
2042 
2043 bool KHTMLPart::doCloseStream()
2044 {
2045  end();
2046  return true;
2047 }
2048 
2049 
2050 void KHTMLPart::paint(TQPainter *p, const TQRect &rc, int yOff, bool *more)
2051 {
2052  if (!d->m_view) return;
2053  d->m_view->paint(p, rc, yOff, more);
2054 }
2055 
2056 void KHTMLPart::stopAnimations()
2057 {
2058  if ( d->m_doc )
2059  d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
2060 
2061  ConstFrameIt it = d->m_frames.begin();
2062  const ConstFrameIt end = d->m_frames.end();
2063  for (; it != end; ++it )
2064  if ( !(*it)->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
2065  KParts::ReadOnlyPart* const p = ( *it )->m_part;
2066  static_cast<KHTMLPart*>( p )->stopAnimations();
2067  }
2068 }
2069 
2070 void KHTMLPart::resetFromScript()
2071 {
2072  closeURL();
2073  d->m_bComplete = false;
2074  d->m_bLoadEventEmitted = false;
2075  disconnect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
2076  connect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
2077  d->m_doc->setParsing(true);
2078 
2079  emit started( 0L );
2080 }
2081 
2082 void KHTMLPart::slotFinishedParsing()
2083 {
2084  d->m_doc->setParsing(false);
2085  checkEmitLoadEvent();
2086  disconnect(d->m_doc,TQT_SIGNAL(finishedParsing()),this,TQT_SLOT(slotFinishedParsing()));
2087 
2088  if (!d->m_view)
2089  return; // We are probably being destructed.
2090 
2091  checkCompleted();
2092 }
2093 
2094 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
2095 {
2096  if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
2097  KHTMLPart* p = this;
2098  while ( p ) {
2099  KHTMLPart* const op = p;
2100  ++(p->d->m_totalObjectCount);
2101  p = p->parentPart();
2102  if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
2103  && !op->d->m_progressUpdateTimer.isActive())
2104  op->d->m_progressUpdateTimer.start( 200, true );
2105  }
2106  }
2107 }
2108 
2109 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
2110 {
2111  if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
2112  KHTMLPart* p = this;
2113  while ( p ) {
2114  KHTMLPart* const op = p;
2115  ++(p->d->m_loadedObjects);
2116  p = p->parentPart();
2117  if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
2118  && !op->d->m_progressUpdateTimer.isActive())
2119  op->d->m_progressUpdateTimer.start( 200, true );
2120  }
2121  }
2122 
2123  checkCompleted();
2124 }
2125 
2126 void KHTMLPart::slotProgressUpdate()
2127 {
2128  int percent;
2129  if ( d->m_loadedObjects < d->m_totalObjectCount )
2130  percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
2131  else
2132  percent = d->m_jobPercent;
2133 
2134  if( d->m_bComplete )
2135  percent = 100;
2136 
2137  if (d->m_statusMessagesEnabled) {
2138  if( d->m_bComplete )
2139  emit d->m_extension->infoMessage( i18n( "Page loaded." ));
2140  else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
2141  emit d->m_extension->infoMessage( i18n( "%n Image of %1 loaded.", "%n Images of %1 loaded.", d->m_loadedObjects).arg(d->m_totalObjectCount) );
2142  }
2143 
2144  emit d->m_extension->loadingProgress( percent );
2145 }
2146 
2147 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
2148 {
2149  d->m_jobspeed = speed;
2150  if (!parentPart())
2151  setStatusBarText(jsStatusBarText(), BarOverrideText);
2152 }
2153 
2154 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
2155 {
2156  d->m_jobPercent = percent;
2157 
2158  if ( !parentPart() )
2159  d->m_progressUpdateTimer.start( 0, true );
2160 }
2161 
2162 void KHTMLPart::slotJobDone( KIO::Job* /*job*/ )
2163 {
2164  d->m_jobPercent = 100;
2165 
2166  if ( !parentPart() )
2167  d->m_progressUpdateTimer.start( 0, true );
2168 }
2169 
2170 void KHTMLPart::slotUserSheetStatDone( KIO::Job *_job )
2171 {
2172  using namespace KIO;
2173 
2174  if ( _job->error() ) {
2175  showError( _job );
2176  return;
2177  }
2178 
2179  const UDSEntry entry = dynamic_cast<KIO::StatJob *>( _job )->statResult();
2180  UDSEntry::ConstIterator it = entry.begin();
2181  const UDSEntry::ConstIterator end = entry.end();
2182  for ( ; it != end; ++it ) {
2183  if ( ( *it ).m_uds == UDS_MODIFICATION_TIME ) {
2184  break;
2185  }
2186  }
2187 
2188  // If the filesystem supports modification times, only reload the
2189  // user-defined stylesheet if necessary - otherwise always reload.
2190  if ( it != end ) {
2191  const time_t lastModified = static_cast<time_t>( ( *it ).m_long );
2192  if ( d->m_userStyleSheetLastModified >= lastModified ) {
2193  return;
2194  }
2195  d->m_userStyleSheetLastModified = lastModified;
2196  }
2197 
2198  setUserStyleSheet( KURL( settings()->userStyleSheet() ) );
2199 }
2200 
2201 void KHTMLPart::checkCompleted()
2202 {
2203 // kdDebug( 6050 ) << "KHTMLPart::checkCompleted() " << this << " " << name() << endl;
2204 // kdDebug( 6050 ) << " parsing: " << (d->m_doc && d->m_doc->parsing()) << endl;
2205 // kdDebug( 6050 ) << " complete: " << d->m_bComplete << endl;
2206 
2207  // restore the cursor position
2208  if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
2209  {
2210  if (d->m_focusNodeNumber >= 0)
2211  d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
2212 
2213  d->m_focusNodeRestored = true;
2214  }
2215 
2216  bool bPendingChildRedirection = false;
2217  // Any frame that hasn't completed yet ?
2218  ConstFrameIt it = d->m_frames.begin();
2219  const ConstFrameIt end = d->m_frames.end();
2220  for (; it != end; ++it ) {
2221  if ( !(*it)->m_bCompleted )
2222  {
2223  //kdDebug( 6050 ) << this << " is waiting for " << (*it)->m_part << endl;
2224  return;
2225  }
2226  // Check for frames with pending redirections
2227  if ( (*it)->m_bPendingRedirection )
2228  bPendingChildRedirection = true;
2229  }
2230 
2231  // Any object that hasn't completed yet ?
2232  {
2233  ConstFrameIt oi = d->m_objects.begin();
2234  const ConstFrameIt oiEnd = d->m_objects.end();
2235 
2236  for (; oi != oiEnd; ++oi )
2237  if ( !(*oi)->m_bCompleted )
2238  return;
2239  }
2240  // Are we still parsing - or have we done the completed stuff already ?
2241  if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
2242  return;
2243 
2244  // Still waiting for images/scripts from the loader ?
2245  int requests = 0;
2246  if ( d->m_doc && d->m_doc->docLoader() )
2247  requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
2248 
2249  if ( requests > 0 )
2250  {
2251  //kdDebug(6050) << "still waiting for images/scripts from the loader - requests:" << requests << endl;
2252  return;
2253  }
2254 
2255  // OK, completed.
2256  // Now do what should be done when we are really completed.
2257  d->m_bComplete = true;
2258  d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
2259  d->m_totalObjectCount = 0;
2260  d->m_loadedObjects = 0;
2261 
2262  KHTMLPart* p = this;
2263  while ( p ) {
2264  KHTMLPart* op = p;
2265  p = p->parentPart();
2266  if ( !p && !op->d->m_progressUpdateTimer.isActive())
2267  op->d->m_progressUpdateTimer.start( 0, true );
2268  }
2269 
2270  checkEmitLoadEvent(); // if we didn't do it before
2271 
2272  bool pendingAction = false;
2273 
2274  if ( !d->m_redirectURL.isEmpty() )
2275  {
2276  // DA: Do not start redirection for frames here! That action is
2277  // deferred until the parent emits a completed signal.
2278  if ( parentPart() == 0 ) {
2279  //kdDebug(6050) << this << " starting redirection timer" << endl;
2280  d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
2281  } else {
2282  //kdDebug(6050) << this << " not toplevel -> not starting redirection timer. Waiting for slotParentCompleted." << endl;
2283  }
2284 
2285  pendingAction = true;
2286  }
2287  else if ( bPendingChildRedirection )
2288  {
2289  pendingAction = true;
2290  }
2291 
2292  // the view will emit completed on our behalf,
2293  // either now or at next repaint if one is pending
2294 
2295  //kdDebug(6050) << this << " asks the view to emit completed. pendingAction=" << pendingAction << endl;
2296  d->m_view->complete( pendingAction );
2297 
2298  // find the alternate stylesheets
2299  TQStringList sheets;
2300  if (d->m_doc)
2301  sheets = d->m_doc->availableStyleSheets();
2302  sheets.prepend( i18n( "Automatic Detection" ) );
2303  d->m_paUseStylesheet->setItems( sheets );
2304 
2305  d->m_paUseStylesheet->setEnabled( sheets.count() > 2);
2306  if (sheets.count() > 2)
2307  {
2308  d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
2309  slotUseStylesheet();
2310  }
2311 
2312  setJSDefaultStatusBarText(TQString());
2313 
2314 #ifdef SPEED_DEBUG
2315  kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
2316 #endif
2317 }
2318 
2319 void KHTMLPart::checkEmitLoadEvent()
2320 {
2321  if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
2322 
2323  ConstFrameIt it = d->m_frames.begin();
2324  const ConstFrameIt end = d->m_frames.end();
2325  for (; it != end; ++it )
2326  if ( !(*it)->m_bCompleted ) // still got a frame running -> too early
2327  return;
2328 
2329  ConstFrameIt oi = d->m_objects.begin();
2330  const ConstFrameIt oiEnd = d->m_objects.end();
2331 
2332  for (; oi != oiEnd; ++oi )
2333  if ( !(*oi)->m_bCompleted ) // still got a object running -> too early
2334  return;
2335 
2336  // Still waiting for images/scripts from the loader ?
2337  // (onload must happen afterwards, #45607)
2338  // ## This makes this method very similar to checkCompleted. A brave soul should try merging them.
2339  int requests = 0;
2340  if ( d->m_doc && d->m_doc->docLoader() )
2341  requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
2342 
2343  if ( requests > 0 )
2344  return;
2345 
2346  d->m_bLoadEventEmitted = true;
2347  if (d->m_doc)
2348  d->m_doc->close();
2349 }
2350 
2351 const KHTMLSettings *KHTMLPart::settings() const
2352 {
2353  return d->m_settings;
2354 }
2355 
2356 #ifndef KDE_NO_COMPAT
2357 KURL KHTMLPart::baseURL() const
2358 {
2359  if ( !d->m_doc ) return KURL();
2360 
2361  return d->m_doc->baseURL();
2362 }
2363 
2364 TQString KHTMLPart::baseTarget() const
2365 {
2366  if ( !d->m_doc ) return TQString();
2367 
2368  return d->m_doc->baseTarget();
2369 }
2370 #endif
2371 
2372 KURL KHTMLPart::completeURL( const TQString &url )
2373 {
2374  if ( !d->m_doc ) return KURL( url );
2375 
2376  if (d->m_decoder)
2377  return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
2378 
2379  return KURL( d->m_doc->completeURL( url ) );
2380 }
2381 
2382 // Called by ecma/kjs_window in case of redirections from Javascript,
2383 // and by xml/dom_docimpl.cpp in case of http-equiv meta refresh.
2384 void KHTMLPart::scheduleRedirection( int delay, const TQString &url, bool doLockHistory )
2385 {
2386  kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
2387  kdDebug(6050) << "current redirectURL=" << d->m_redirectURL << " with delay " << d->m_delayRedirect << endl;
2388  if( delay < 24*60*60 &&
2389  ( d->m_redirectURL.isEmpty() || delay <= d->m_delayRedirect) ) {
2390  d->m_delayRedirect = delay;
2391  d->m_redirectURL = url;
2392  d->m_redirectLockHistory = doLockHistory;
2393  kdDebug(6050) << " d->m_bComplete=" << d->m_bComplete << endl;
2394  if ( d->m_bComplete ) {
2395  d->m_redirectionTimer.stop();
2396  d->m_redirectionTimer.start( kMax(0, 1000 * d->m_delayRedirect), true );
2397  }
2398  }
2399 }
2400 
2401 void KHTMLPart::slotRedirect()
2402 {
2403  kdDebug(6050) << this << " slotRedirect()" << endl;
2404  TQString u = d->m_redirectURL;
2405  d->m_delayRedirect = 0;
2406  d->m_redirectURL = TQString();
2407 
2408  // SYNC check with ecma/kjs_window.cpp::goURL !
2409  if ( u.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2410  {
2411  TQString script = KURL::decode_string( u.right( u.length() - 11 ) );
2412  kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
2413  TQVariant res = executeScript( DOM::Node(), script );
2414  if ( res.type() == TQVariant::String ) {
2415  begin( url() );
2416  write( res.asString() );
2417  end();
2418  }
2419  emit completed();
2420  return;
2421  }
2422  KParts::URLArgs args;
2423  KURL cUrl( m_url );
2424  KURL url( u );
2425 
2426  // handle windows opened by JS
2427  if ( openedByJS() && d->m_opener )
2428  cUrl = d->m_opener->url();
2429 
2430  if (!kapp || !kapp->authorizeURLAction("redirect", cUrl, url))
2431  {
2432  kdWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << cUrl << " to " << url << " REJECTED!" << endl;
2433  emit completed();
2434  return;
2435  }
2436 
2437  if ( urlcmp( u, m_url.url(), true, true ) )
2438  {
2439  args.metaData().insert("referrer", d->m_pageReferrer);
2440  }
2441 
2442  // For javascript and META-tag based redirections:
2443  // - We don't take cross-domain-ness in consideration if we are the
2444  // toplevel frame because the new URL may be in a different domain as the current URL
2445  // but that's ok.
2446  // - If we are not the toplevel frame then we check against the toplevelURL()
2447  if (parentPart())
2448  args.metaData().insert("cross-domain", toplevelURL().url());
2449 
2450  args.setLockHistory( d->m_redirectLockHistory );
2451  // _self: make sure we don't use any <base target=>'s
2452 
2453  d->m_urlSelectedOpenedURL = true; // In case overriden, default to success
2454  urlSelected( u, 0, 0, "_self", args );
2455 
2456  if ( !d->m_urlSelectedOpenedURL ) // urlSelected didn't open a url, so emit completed ourselves
2457  emit completed();
2458 }
2459 
2460 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
2461 {
2462  // the slave told us that we got redirected
2463  //kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
2464  emit d->m_extension->setLocationBarURL( url.prettyURL() );
2465  d->m_workingURL = url;
2466 }
2467 
2468 bool KHTMLPart::setEncoding( const TQString &name, bool override )
2469 {
2470  d->m_encoding = name;
2471  d->m_haveEncoding = override;
2472 
2473  if( !m_url.isEmpty() ) {
2474  // reload document
2475  closeURL();
2476  KURL url = m_url;
2477  m_url = 0;
2478  d->m_restored = true;
2479  openURL(url);
2480  d->m_restored = false;
2481  }
2482 
2483  return true;
2484 }
2485 
2486 TQString KHTMLPart::encoding() const
2487 {
2488  if(d->m_haveEncoding && !d->m_encoding.isEmpty())
2489  return d->m_encoding;
2490 
2491  if(d->m_decoder && d->m_decoder->encoding())
2492  return TQString(d->m_decoder->encoding());
2493 
2494  return defaultEncoding();
2495 }
2496 
2497 TQString KHTMLPart::defaultEncoding() const
2498 {
2499  TQString encoding = settings()->encoding();
2500  if ( !encoding.isEmpty() )
2501  return encoding;
2502  // HTTP requires the default encoding to be latin1, when neither
2503  // the user nor the page requested a particular encoding.
2504  if ( url().protocol().startsWith( "http" ) )
2505  return "iso-8859-1";
2506  else
2507  return KGlobal::locale()->encoding();
2508 }
2509 
2510 void KHTMLPart::setUserStyleSheet(const KURL &url)
2511 {
2512  if ( d->m_doc && d->m_doc->docLoader() )
2513  (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
2514 }
2515 
2516 void KHTMLPart::setUserStyleSheet(const TQString &styleSheet)
2517 {
2518  if ( d->m_doc )
2519  d->m_doc->setUserStyleSheet( styleSheet );
2520 }
2521 
2522 bool KHTMLPart::gotoAnchor( const TQString &name )
2523 {
2524  if (!d->m_doc)
2525  return false;
2526 
2527  HTMLCollectionImpl *anchors =
2528  new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
2529  anchors->ref();
2530  NodeImpl *n = anchors->namedItem(name);
2531  anchors->deref();
2532 
2533  if(!n) {
2534  n = d->m_doc->getElementById( name );
2535  }
2536 
2537  d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
2538 
2539  // Implement the rule that "" and "top" both mean top of page as in other browsers.
2540  bool quirkyName = !n && !d->m_doc->inStrictMode() && (name.isEmpty() || name.lower() == "top");
2541 
2542  if (quirkyName) {
2543  d->m_view->setContentsPos(0, 0);
2544  return true;
2545  } else if (!n) {
2546  kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
2547  return false;
2548  }
2549 
2550  int x = 0, y = 0;
2551  int gox, dummy;
2552  HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
2553 
2554  a->getUpperLeftCorner(x, y);
2555  if (x <= d->m_view->contentsX())
2556  gox = x - 10;
2557  else {
2558  gox = d->m_view->contentsX();
2559  if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
2560  a->getLowerRightCorner(x, dummy);
2561  gox = x - d->m_view->visibleWidth() + 10;
2562  }
2563  }
2564 
2565  d->m_view->setContentsPos(gox, y);
2566 
2567  return true;
2568 }
2569 
2570 bool KHTMLPart::nextAnchor()
2571 {
2572  if (!d->m_doc)
2573  return false;
2574  d->m_view->focusNextPrevNode ( true );
2575 
2576  return true;
2577 }
2578 
2579 bool KHTMLPart::prevAnchor()
2580 {
2581  if (!d->m_doc)
2582  return false;
2583  d->m_view->focusNextPrevNode ( false );
2584 
2585  return true;
2586 }
2587 
2588 void KHTMLPart::setStandardFont( const TQString &name )
2589 {
2590  d->m_settings->setStdFontName(name);
2591 }
2592 
2593 void KHTMLPart::setFixedFont( const TQString &name )
2594 {
2595  d->m_settings->setFixedFontName(name);
2596 }
2597 
2598 void KHTMLPart::setURLCursor( const TQCursor &c )
2599 {
2600  d->m_linkCursor = c;
2601 }
2602 
2603 TQCursor KHTMLPart::urlCursor() const
2604 {
2605  return d->m_linkCursor;
2606 }
2607 
2608 bool KHTMLPart::onlyLocalReferences() const
2609 {
2610  return d->m_onlyLocalReferences;
2611 }
2612 
2613 void KHTMLPart::setOnlyLocalReferences(bool enable)
2614 {
2615  d->m_onlyLocalReferences = enable;
2616 }
2617 
2618 void KHTMLPartPrivate::setFlagRecursively(
2619  bool KHTMLPartPrivate::*flag, bool value)
2620 {
2621  // first set it on the current one
2622  this->*flag = value;
2623 
2624  // descend into child frames recursively
2625  {
2626  TQValueList<khtml::ChildFrame*>::Iterator it = m_frames.begin();
2627  const TQValueList<khtml::ChildFrame*>::Iterator itEnd = m_frames.end();
2628  for (; it != itEnd; ++it) {
2629  KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
2630  if (part->inherits("KHTMLPart"))
2631  part->d->setFlagRecursively(flag, value);
2632  }/*next it*/
2633  }
2634  // do the same again for objects
2635  {
2636  TQValueList<khtml::ChildFrame*>::Iterator it = m_objects.begin();
2637  const TQValueList<khtml::ChildFrame*>::Iterator itEnd = m_objects.end();
2638  for (; it != itEnd; ++it) {
2639  KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
2640  if (part->inherits("KHTMLPart"))
2641  part->d->setFlagRecursively(flag, value);
2642  }/*next it*/
2643  }
2644 }
2645 
2646 void KHTMLPart::setCaretMode(bool enable)
2647 {
2648 #ifndef KHTML_NO_CARET
2649  kdDebug(6200) << "setCaretMode(" << enable << ")" << endl;
2650  if (isCaretMode() == enable) return;
2651  d->setFlagRecursively(&KHTMLPartPrivate::m_caretMode, enable);
2652  // FIXME: this won't work on frames as expected
2653  if (!isEditable()) {
2654  if (enable) {
2655  view()->initCaret(true);
2656  view()->ensureCaretVisible();
2657  } else
2658  view()->caretOff();
2659  }/*end if*/
2660 #endif // KHTML_NO_CARET
2661 }
2662 
2663 bool KHTMLPart::isCaretMode() const
2664 {
2665  return d->m_caretMode;
2666 }
2667 
2668 void KHTMLPart::setEditable(bool enable)
2669 {
2670 #ifndef KHTML_NO_CARET
2671  if (isEditable() == enable) return;
2672  d->setFlagRecursively(&KHTMLPartPrivate::m_designMode, enable);
2673  // FIXME: this won't work on frames as expected
2674  if (!isCaretMode()) {
2675  if (enable) {
2676  view()->initCaret(true);
2677  view()->ensureCaretVisible();
2678  } else
2679  view()->caretOff();
2680  }/*end if*/
2681 #endif // KHTML_NO_CARET
2682 }
2683 
2684 bool KHTMLPart::isEditable() const
2685 {
2686  return d->m_designMode;
2687 }
2688 
2689 void KHTMLPart::setCaretPosition(DOM::Node node, long offset, bool extendSelection)
2690 {
2691 #ifndef KHTML_NO_CARET
2692 #if 0
2693  kdDebug(6200) << k_funcinfo << "node: " << node.handle() << " nodeName: "
2694  << node.nodeName().string() << " offset: " << offset
2695  << " extendSelection " << extendSelection << endl;
2696 #endif
2697  if (view()->moveCaretTo(node.handle(), offset, !extendSelection))
2698  emitSelectionChanged();
2699  view()->ensureCaretVisible();
2700 #endif // KHTML_NO_CARET
2701 }
2702 
2703 KHTMLPart::CaretDisplayPolicy KHTMLPart::caretDisplayPolicyNonFocused() const
2704 {
2705 #ifndef KHTML_NO_CARET
2706  return (CaretDisplayPolicy)view()->caretDisplayPolicyNonFocused();
2707 #else // KHTML_NO_CARET
2708  return CaretInvisible;
2709 #endif // KHTML_NO_CARET
2710 }
2711 
2712 void KHTMLPart::setCaretDisplayPolicyNonFocused(CaretDisplayPolicy policy)
2713 {
2714 #ifndef KHTML_NO_CARET
2715  view()->setCaretDisplayPolicyNonFocused(policy);
2716 #endif // KHTML_NO_CARET
2717 }
2718 
2719 void KHTMLPart::setCaretVisible(bool show)
2720 {
2721 #ifndef KHTML_NO_CARET
2722  if (show) {
2723 
2724  NodeImpl *caretNode = xmlDocImpl()->focusNode();
2725  if (isCaretMode() || isEditable()
2726  || (caretNode && caretNode->contentEditable())) {
2727  view()->caretOn();
2728  }/*end if*/
2729 
2730  } else {
2731 
2732  view()->caretOff();
2733 
2734  }/*end if*/
2735 #endif // KHTML_NO_CARET
2736 }
2737 
2738 void KHTMLPart::findTextBegin()
2739 {
2740  d->m_findPos = -1;
2741  d->m_findNode = 0;
2742  d->m_findPosEnd = -1;
2743  d->m_findNodeEnd= 0;
2744  d->m_findPosStart = -1;
2745  d->m_findNodeStart = 0;
2746  d->m_findNodePrevious = 0;
2747  delete d->m_find;
2748  d->m_find = 0L;
2749 }
2750 
2751 bool KHTMLPart::initFindNode( bool selection, bool reverse, bool fromCursor )
2752 {
2753  if ( !d->m_doc )
2754  return false;
2755 
2756  DOM::NodeImpl* firstNode = 0L;
2757  if (d->m_doc->isHTMLDocument())
2758  firstNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
2759  else
2760  firstNode = d->m_doc;
2761 
2762  if ( !firstNode )
2763  {
2764  //kdDebug(6050) << k_funcinfo << "no first node (body or doc) -> return false" << endl;
2765  return false;
2766  }
2767  if ( firstNode->id() == ID_FRAMESET )
2768  {
2769  //kdDebug(6050) << k_funcinfo << "FRAMESET -> return false" << endl;
2770  return false;
2771  }
2772 
2773  if ( selection && hasSelection() )
2774  {
2775  //kdDebug(6050) << k_funcinfo << "using selection" << endl;
2776  if ( !fromCursor )
2777  {
2778  d->m_findNode = reverse ? d->m_selectionEnd.handle() : d->m_selectionStart.handle();
2779  d->m_findPos = reverse ? d->m_endOffset : d->m_startOffset;
2780  }
2781  d->m_findNodeEnd = reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
2782  d->m_findPosEnd = reverse ? d->m_startOffset : d->m_endOffset;
2783  d->m_findNodeStart = !reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
2784  d->m_findPosStart = !reverse ? d->m_startOffset : d->m_endOffset;
2785  d->m_findNodePrevious = d->m_findNodeStart;
2786  }
2787  else // whole document
2788  {
2789  //kdDebug(6050) << k_funcinfo << "whole doc" << endl;
2790  if ( !fromCursor )
2791  {
2792  d->m_findNode = firstNode;
2793  d->m_findPos = reverse ? -1 : 0;
2794  }
2795  d->m_findNodeEnd = reverse ? firstNode : 0;
2796  d->m_findPosEnd = reverse ? 0 : -1;
2797  d->m_findNodeStart = !reverse ? firstNode : 0;
2798  d->m_findPosStart = !reverse ? 0 : -1;
2799  d->m_findNodePrevious = d->m_findNodeStart;
2800  if ( reverse )
2801  {
2802  // Need to find out the really last object, to start from it
2803  khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
2804  if ( obj )
2805  {
2806  // find the last object in the render tree
2807  while ( obj->lastChild() )
2808  {
2809  obj = obj->lastChild();
2810  }
2811  // now get the last object with a NodeImpl associated
2812  while ( !obj->element() && obj->objectAbove() )
2813  {
2814  obj = obj->objectAbove();
2815  }
2816  d->m_findNode = obj->element();
2817  }
2818  }
2819  }
2820  return true;
2821 }
2822 
2823 // Old method (its API limits the available features - remove in KDE-4)
2824 bool KHTMLPart::findTextNext( const TQString &str, bool forward, bool caseSensitive, bool isRegExp )
2825 {
2826  if ( !initFindNode( false, !forward, d->m_findNode ) )
2827  return false;
2828  while(1)
2829  {
2830  if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
2831  {
2832  DOMString nodeText = d->m_findNode->nodeValue();
2833  DOMStringImpl *t = nodeText.implementation();
2834  TQConstString s(t->s, t->l);
2835 
2836  int matchLen = 0;
2837  if ( isRegExp ) {
2838  TQRegExp matcher( str );
2839  matcher.setCaseSensitive( caseSensitive );
2840  d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
2841  if ( d->m_findPos != -1 )
2842  matchLen = matcher.matchedLength();
2843  }
2844  else {
2845  d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
2846  matchLen = str.length();
2847  }
2848 
2849  if(d->m_findPos != -1)
2850  {
2851  int x = 0, y = 0;
2852  if(static_cast<khtml::RenderText *>(d->m_findNode->renderer())
2853  ->posOfChar(d->m_findPos, x, y))
2854  d->m_view->setContentsPos(x-50, y-50);
2855 
2856  d->m_selectionStart = d->m_findNode;
2857  d->m_startOffset = d->m_findPos;
2858  d->m_selectionEnd = d->m_findNode;
2859  d->m_endOffset = d->m_findPos + matchLen;
2860  d->m_startBeforeEnd = true;
2861 
2862  d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
2863  d->m_selectionEnd.handle(), d->m_endOffset );
2864  emitSelectionChanged();
2865  return true;
2866  }
2867  }
2868  d->m_findPos = -1;
2869 
2870  NodeImpl *next;
2871 
2872  if ( forward )
2873  {
2874  next = d->m_findNode->firstChild();
2875 
2876  if(!next) next = d->m_findNode->nextSibling();
2877  while(d->m_findNode && !next) {
2878  d->m_findNode = d->m_findNode->parentNode();
2879  if( d->m_findNode ) {
2880  next = d->m_findNode->nextSibling();
2881  }
2882  }
2883  }
2884  else
2885  {
2886  next = d->m_findNode->lastChild();
2887 
2888  if (!next ) next = d->m_findNode->previousSibling();
2889  while ( d->m_findNode && !next )
2890  {
2891  d->m_findNode = d->m_findNode->parentNode();
2892  if( d->m_findNode )
2893  {
2894  next = d->m_findNode->previousSibling();
2895  }
2896  }
2897  }
2898 
2899  d->m_findNode = next;
2900  if(!d->m_findNode) return false;
2901  }
2902 }
2903 
2904 
2905 void KHTMLPart::slotFind()
2906 {
2907  KParts::ReadOnlyPart *part = currentFrame();
2908  if (!part)
2909  return;
2910  if (!part->inherits("KHTMLPart") )
2911  {
2912  kdError(6000) << "slotFind: part is a " << part->className() << ", can't do a search into it" << endl;
2913  return;
2914  }
2915  static_cast<KHTMLPart *>( part )->findText();
2916 }
2917 
2918 void KHTMLPart::slotFindNext()
2919 {
2920  KParts::ReadOnlyPart *part = currentFrame();
2921  if (!part)
2922  return;
2923  if (!part->inherits("KHTMLPart") )
2924  {
2925  kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
2926  return;
2927  }
2928  static_cast<KHTMLPart *>( part )->findTextNext();
2929 }
2930 
2931 void KHTMLPart::slotFindPrev()
2932 {
2933  KParts::ReadOnlyPart *part = currentFrame();
2934  if (!part)
2935  return;
2936  if (!part->inherits("KHTMLPart") )
2937  {
2938  kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
2939  return;
2940  }
2941  static_cast<KHTMLPart *>( part )->findTextNext( true ); // reverse
2942 }
2943 
2944 void KHTMLPart::slotFindDone()
2945 {
2946  // ### remove me
2947 }
2948 
2949 void KHTMLPart::slotFindAheadText()
2950 {
2951 #ifndef KHTML_NO_TYPE_AHEAD_FIND
2952  KParts::ReadOnlyPart *part = currentFrame();
2953  if (!part)
2954  return;
2955  if (!part->inherits("KHTMLPart") )
2956  {
2957  kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
2958  return;
2959  }
2960  static_cast<KHTMLPart *>( part )->view()->startFindAhead( false );
2961 #endif // KHTML_NO_TYPE_AHEAD_FIND
2962 }
2963 
2964 void KHTMLPart::slotFindAheadLink()
2965 {
2966 #ifndef KHTML_NO_TYPE_AHEAD_FIND
2967  KParts::ReadOnlyPart *part = currentFrame();
2968  if (!part)
2969  return;
2970  if (!part->inherits("KHTMLPart") )
2971  {
2972  kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
2973  return;
2974  }
2975  static_cast<KHTMLPart *>( part )->view()->startFindAhead( true );
2976 #endif // KHTML_NO_TYPE_AHEAD_FIND
2977 }
2978 
2979 void KHTMLPart::enableFindAheadActions( bool enable )
2980 {
2981  // only the topmost one has shortcuts
2982  KHTMLPart* p = this;
2983  while( p->parentPart())
2984  p = p->parentPart();
2985  p->d->m_paFindAheadText->setEnabled( enable );
2986  p->d->m_paFindAheadLinks->setEnabled( enable );
2987 }
2988 
2989 void KHTMLPart::slotFindDialogDestroyed()
2990 {
2991  d->m_lastFindState.options = d->m_findDialog->options();
2992  d->m_lastFindState.history = d->m_findDialog->findHistory();
2993  d->m_findDialog->deleteLater();
2994  d->m_findDialog = 0L;
2995 }
2996 
2997 void KHTMLPart::findText()
2998 {
2999  // First do some init to make sure we can search in this frame
3000  if ( !d->m_doc )
3001  return;
3002 
3003  // Raise if already opened
3004  if ( d->m_findDialog )
3005  {
3006  KWin::activateWindow( d->m_findDialog->winId() );
3007  return;
3008  }
3009 
3010  // The lineedit of the dialog would make khtml lose its selection, otherwise
3011 #ifndef QT_NO_CLIPBOARD
3012  disconnect( kapp->clipboard(), TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotClearSelection()) );
3013 #endif
3014 
3015  // Now show the dialog in which the user can choose options.
3016  d->m_findDialog = new KFindDialog( false /*non-modal*/, widget(), "khtmlfind" );
3017  d->m_findDialog->setHasSelection( hasSelection() );
3018  d->m_findDialog->setHasCursor( d->m_findNode != 0 );
3019  if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
3020  d->m_lastFindState.options |= KFindDialog::FromCursor;
3021 
3022  // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
3023  d->m_findDialog->setFindHistory( d->m_lastFindState.history );
3024  d->m_findDialog->setOptions( d->m_lastFindState.options );
3025 
3026  d->m_lastFindState.options = -1; // force update in findTextNext
3027  d->m_lastFindState.last_dir = -1;
3028 
3029  d->m_findDialog->show();
3030  connect( d->m_findDialog, TQT_SIGNAL(okClicked()), this, TQT_SLOT(slotFindNext()) );
3031  connect( d->m_findDialog, TQT_SIGNAL(finished()), this, TQT_SLOT(slotFindDialogDestroyed()) );
3032 
3033  findText( d->m_findDialog->pattern(), 0 /*options*/, widget(), d->m_findDialog );
3034 }
3035 
3036 void KHTMLPart::findText( const TQString &str, long options, TQWidget *parent, KFindDialog *findDialog )
3037 {
3038  // First do some init to make sure we can search in this frame
3039  if ( !d->m_doc )
3040  return;
3041 
3042 #ifndef QT_NO_CLIPBOARD
3043  connect( kapp->clipboard(), TQT_SIGNAL(selectionChanged()), TQT_SLOT(slotClearSelection()) );
3044 #endif
3045 
3046  // Create the KFind object
3047  delete d->m_find;
3048  d->m_find = new KFind( str, options, parent, findDialog );
3049  d->m_find->closeFindNextDialog(); // we use KFindDialog non-modal, so we don't want other dlg popping up
3050  connect( d->m_find, TQT_SIGNAL( highlight( const TQString &, int, int ) ),
3051  this, TQT_SLOT( slotHighlight( const TQString &, int, int ) ) );
3052  //connect(d->m_find, TQT_SIGNAL( findNext() ),
3053  // this, TQT_SLOT( slotFindNext() ) );
3054 
3055  if ( !findDialog )
3056  {
3057  d->m_lastFindState.options = options;
3058  initFindNode( options & KFindDialog::SelectedText,
3059  options & KFindDialog::FindBackwards,
3060  options & KFindDialog::FromCursor );
3061  }
3062 }
3063 
3064 bool KHTMLPart::findTextNext()
3065 {
3066  return findTextNext( false );
3067 }
3068 
3069 // New method
3070 bool KHTMLPart::findTextNext( bool reverse )
3071 {
3072  if (!d->m_find)
3073  {
3074  // We didn't show the find dialog yet, let's do it then (#49442)
3075  findText();
3076  return false;
3077  }
3078 
3079  view()->updateFindAheadTimeout();
3080  long options = 0;
3081  if ( d->m_findDialog ) // 0 when we close the dialog
3082  {
3083  if ( d->m_find->pattern() != d->m_findDialog->pattern() ) {
3084  d->m_find->setPattern( d->m_findDialog->pattern() );
3085  d->m_find->resetCounts();
3086  }
3087  options = d->m_findDialog->options();
3088  if ( d->m_lastFindState.options != options )
3089  {
3090  d->m_find->setOptions( options );
3091 
3092  if ( options & KFindDialog::SelectedText )
3093  Q_ASSERT( hasSelection() );
3094 
3095  long difference = d->m_lastFindState.options ^ options;
3096  if ( difference & (KFindDialog::SelectedText | KFindDialog::FromCursor ) )
3097  {
3098  // Important options changed -> reset search range
3099  (void) initFindNode( options & KFindDialog::SelectedText,
3100  options & KFindDialog::FindBackwards,
3101  options & KFindDialog::FromCursor );
3102  }
3103  d->m_lastFindState.options = options;
3104  }
3105  } else
3106  options = d->m_lastFindState.options;
3107  if( reverse )
3108  options = options ^ KFindDialog::FindBackwards;
3109  if( d->m_find->options() != options )
3110  d->m_find->setOptions( options );
3111 
3112  // Changing find direction. Start and end nodes must be switched.
3113  // Additionally since d->m_findNode points after the last node
3114  // that was searched, it needs to be "after" it in the opposite direction.
3115  if( d->m_lastFindState.last_dir != -1
3116  && bool( d->m_lastFindState.last_dir ) != bool( options & KFindDialog::FindBackwards ))
3117  {
3118  tqSwap( d->m_findNodeEnd, d->m_findNodeStart );
3119  tqSwap( d->m_findPosEnd, d->m_findPosStart );
3120  tqSwap( d->m_findNode, d->m_findNodePrevious );
3121  // d->m_findNode now point at the end of the last searched line - advance one node
3122  khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
3123  khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
3124  if ( obj == end )
3125  obj = 0L;
3126  else if ( obj )
3127  {
3128  do {
3129  obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
3130  } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
3131  }
3132  if ( obj )
3133  d->m_findNode = obj->element();
3134  else
3135  d->m_findNode = 0;
3136  }
3137  d->m_lastFindState.last_dir = ( options & KFindDialog::FindBackwards ) ? 1 : 0;
3138 
3139  KFind::Result res = KFind::NoMatch;
3140  khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
3141  khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
3142  khtml::RenderTextArea *tmpTextArea=0L;
3143  //kdDebug(6050) << k_funcinfo << "obj=" << obj << " end=" << end << endl;
3144  while( res == KFind::NoMatch )
3145  {
3146  if ( d->m_find->needData() )
3147  {
3148  if ( !obj ) {
3149  //kdDebug(6050) << k_funcinfo << "obj=0 -> done" << endl;
3150  break; // we're done
3151  }
3152  //kdDebug(6050) << k_funcinfo << " gathering data" << endl;
3153  // First make up the TQString for the current 'line' (i.e. up to \n)
3154  // We also want to remember the DOMNode for every portion of the string.
3155  // We store this in an index->node list.
3156 
3157  d->m_stringPortions.clear();
3158  bool newLine = false;
3159  TQString str;
3160  DOM::NodeImpl* lastNode = d->m_findNode;
3161  while ( obj && !newLine )
3162  {
3163  // Grab text from render object
3164  TQString s;
3165  bool renderAreaText = obj->parent() && (TQCString(obj->parent()->renderName())== "RenderTextArea");
3166  bool renderLineText = (TQCString(obj->renderName())== "RenderLineEdit");
3167  if ( renderAreaText )
3168  {
3169  khtml::RenderTextArea *parent= static_cast<khtml::RenderTextArea *>(obj->parent());
3170  s = parent->text();
3171  s = s.replace(0xa0, ' ');
3172  tmpTextArea = parent;
3173  }
3174  else if ( renderLineText )
3175  {
3176  khtml::RenderLineEdit *parentLine= static_cast<khtml::RenderLineEdit *>(obj);
3177  if (parentLine->widget()->echoMode() == TQLineEdit::Normal)
3178  s = parentLine->widget()->text();
3179  s = s.replace(0xa0, ' ');
3180  }
3181  else if ( obj->isText() )
3182  {
3183  bool isLink = false;
3184 
3185  // checks whether the node has a <A> parent
3186  if ( options & FindLinksOnly )
3187  {
3188  DOM::NodeImpl *parent = obj->element();
3189  while ( parent )
3190  {
3191  if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
3192  {
3193  isLink = true;
3194  break;
3195  }
3196  parent = parent->parentNode();
3197  }
3198  }
3199  else
3200  {
3201  isLink = true;
3202  }
3203 
3204  if ( isLink && obj->parent()!=tmpTextArea )
3205  {
3206  s = static_cast<khtml::RenderText *>(obj)->data().string();
3207  s = s.replace(0xa0, ' ');
3208  }
3209  }
3210  else if ( obj->isBR() )
3211  s = '\n';
3212  else if ( !obj->isInline() && !str.isEmpty() )
3213  s = '\n';
3214 
3215  if ( lastNode == d->m_findNodeEnd )
3216  s.truncate( d->m_findPosEnd );
3217  if ( !s.isEmpty() )
3218  {
3219  newLine = s.find( '\n' ) != -1; // did we just get a newline?
3220  if( !( options & KFindDialog::FindBackwards ))
3221  {
3222  //kdDebug(6050) << "StringPortion: " << index << "-" << index+s.length()-1 << " -> " << lastNode << endl;
3223  d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( str.length(), lastNode ) );
3224  str += s;
3225  }
3226  else // KFind itself can search backwards, so str must not be built backwards
3227  {
3228  for( TQValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
3229  it != d->m_stringPortions.end();
3230  ++it )
3231  (*it).index += s.length();
3232  d->m_stringPortions.prepend( KHTMLPartPrivate::StringPortion( 0, lastNode ) );
3233  str.prepend( s );
3234  }
3235  }
3236  // Compare obj and end _after_ we processed the 'end' node itself
3237  if ( obj == end )
3238  obj = 0L;
3239  else
3240  {
3241  // Move on to next object (note: if we found a \n already, then obj (and lastNode)
3242  // will point to the _next_ object, i.e. they are in advance.
3243  do {
3244  // We advance until the next RenderObject that has a NodeImpl as its element().
3245  // Otherwise (if we keep the 'last node', and it has a '\n') we might be stuck
3246  // on that object forever...
3247  obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
3248  } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
3249  }
3250  if ( obj )
3251  lastNode = obj->element();
3252  else
3253  lastNode = 0;
3254  } // end while
3255  //kdDebug()<<" str : "<<str<<endl;
3256  if ( !str.isEmpty() )
3257  {
3258  d->m_find->setData( str, d->m_findPos );
3259  }
3260 
3261  d->m_findPos = -1; // not used during the findnext loops. Only during init.
3262  d->m_findNodePrevious = d->m_findNode;
3263  d->m_findNode = lastNode;
3264  }
3265  if ( !d->m_find->needData() ) // happens if str was empty
3266  {
3267  // Let KFind inspect the text fragment, and emit highlighted if a match is found
3268  res = d->m_find->find();
3269  }
3270  } // end while
3271 
3272  if ( res == KFind::NoMatch ) // i.e. we're done
3273  {
3274  kdDebug() << "No more matches." << endl;
3275  if ( !(options & FindNoPopups) && d->m_find->shouldRestart() )
3276  {
3277  //kdDebug(6050) << "Restarting" << endl;
3278  initFindNode( false, options & KFindDialog::FindBackwards, false );
3279  d->m_find->resetCounts();
3280  findTextNext( reverse );
3281  }
3282  else // really done
3283  {
3284  //kdDebug(6050) << "Finishing" << endl;
3285  //delete d->m_find;
3286  //d->m_find = 0L;
3287  initFindNode( false, options & KFindDialog::FindBackwards, false );
3288  d->m_find->resetCounts();
3289  slotClearSelection();
3290  }
3291  kdDebug() << "Dialog closed." << endl;
3292  }
3293 
3294  return res == KFind::Match;
3295 }
3296 
3297 void KHTMLPart::slotHighlight( const TQString& /*text*/, int index, int length )
3298 {
3299  //kdDebug(6050) << "slotHighlight index=" << index << " length=" << length << endl;
3300  TQValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
3301  const TQValueList<KHTMLPartPrivate::StringPortion>::Iterator itEnd = d->m_stringPortions.end();
3302  TQValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
3303  // We stop at the first portion whose index is 'greater than', and then use the previous one
3304  while ( it != itEnd && (*it).index <= index )
3305  {
3306  prev = it;
3307  ++it;
3308  }
3309  Q_ASSERT ( prev != itEnd );
3310  DOM::NodeImpl* node = (*prev).node;
3311  Q_ASSERT( node );
3312 
3313  d->m_selectionStart = node;
3314  d->m_startOffset = index - (*prev).index;
3315 
3316  khtml::RenderObject* obj = node->renderer();
3317  khtml::RenderTextArea *parent = 0L;
3318  khtml::RenderLineEdit *parentLine = 0L;
3319  bool renderLineText =false;
3320 
3321  TQRect highlightedRect;
3322  bool renderAreaText =false;
3323  Q_ASSERT( obj );
3324  if ( obj )
3325  {
3326  int x = 0, y = 0;
3327  renderAreaText = (TQCString(obj->parent()->renderName())== "RenderTextArea");
3328  renderLineText = (TQCString(obj->renderName())== "RenderLineEdit");
3329 
3330 
3331  if( renderAreaText )
3332  parent= static_cast<khtml::RenderTextArea *>(obj->parent());
3333  if ( renderLineText )
3334  parentLine= static_cast<khtml::RenderLineEdit *>(obj);
3335  if ( !renderLineText )
3336  //if (static_cast<khtml::RenderText *>(node->renderer())
3337  // ->posOfChar(d->m_startOffset, x, y))
3338  {
3339  int dummy;
3340  static_cast<khtml::RenderText *>(node->renderer())
3341  ->caretPos( d->m_startOffset, false, x, y, dummy, dummy ); // more precise than posOfChar
3342  //kdDebug(6050) << "topleft: " << x << "," << y << endl;
3343  if ( x != -1 || y != -1 )
3344  {
3345  int gox = d->m_view->contentsX();
3346  if (x+50 > d->m_view->contentsX() + d->m_view->visibleWidth())
3347  gox = x - d->m_view->visibleWidth() + 50;
3348  if (x-10 < d->m_view->contentsX())
3349  gox = x - d->m_view->visibleWidth() - 10;
3350  if (gox < 0) gox = 0;
3351  d->m_view->setContentsPos(gox, y-50);
3352  highlightedRect.setTopLeft( d->m_view->mapToGlobal(TQPoint(x, y)) );
3353  }
3354  }
3355  }
3356  // Now look for end node
3357  it = prev; // no need to start from beginning again
3358  while ( it != itEnd && (*it).index < index + length )
3359  {
3360  prev = it;
3361  ++it;
3362  }
3363  Q_ASSERT ( prev != itEnd );
3364 
3365  d->m_selectionEnd = (*prev).node;
3366  d->m_endOffset = index + length - (*prev).index;
3367  d->m_startBeforeEnd = true;
3368 
3369  // if the selection is limited to a single link, that link gets focus
3370  if(d->m_selectionStart == d->m_selectionEnd)
3371  {
3372  bool isLink = false;
3373 
3374  // checks whether the node has a <A> parent
3375  DOM::NodeImpl *parent = d->m_selectionStart.handle();
3376  while ( parent )
3377  {
3378  if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
3379  {
3380  isLink = true;
3381  break;
3382  }
3383  parent = parent->parentNode();
3384  }
3385 
3386  if(isLink == true)
3387  {
3388  d->m_doc->setFocusNode( parent );
3389  }
3390  }
3391 
3392 #if 0
3393  kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
3394  d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
3395  it = d->m_stringPortions.begin();
3396  for ( ; it != d->m_stringPortions.end() ; ++it )
3397  kdDebug(6050) << " StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
3398 #endif
3399  if( renderAreaText )
3400  {
3401  if( parent )
3402  parent->highLightWord( length, d->m_endOffset-length );
3403  }
3404  else if ( renderLineText )
3405  {
3406  if( parentLine )
3407  parentLine->highLightWord( length, d->m_endOffset-length );
3408  }
3409  else
3410  {
3411  d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
3412  d->m_selectionEnd.handle(), d->m_endOffset );
3413  if (d->m_selectionEnd.handle()->renderer() )
3414  {
3415  int x, y, height, dummy;
3416  static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
3417  ->caretPos( d->m_endOffset, false, x, y, dummy, height ); // more precise than posOfChar
3418  //kdDebug(6050) << "bottomright: " << x << "," << y+height << endl;
3419  if ( x != -1 || y != -1 )
3420  {
3421  // if ( static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
3422  // ->posOfChar(d->m_endOffset-1, x, y))
3423  highlightedRect.setBottomRight( d->m_view->mapToGlobal( TQPoint(x, y+height) ) );
3424  }
3425  }
3426  }
3427  emitSelectionChanged();
3428 
3429  // make the finddialog move away from the selected area
3430  if ( d->m_findDialog && !highlightedRect.isNull() )
3431  {
3432  highlightedRect.moveBy( -d->m_view->contentsX(), -d->m_view->contentsY() );
3433  //kdDebug(6050) << "avoiding " << highlightedRect << endl;
3434  KDialog::avoidArea( d->m_findDialog, highlightedRect );
3435  }
3436 }
3437 
3438 TQString KHTMLPart::selectedTextAsHTML() const
3439 {
3440  if(!hasSelection()) {
3441  kdDebug() << "selectedTextAsHTML(): selection is not valid. Returning empty selection" << endl;
3442  return TQString();
3443  }
3444  if(d->m_startOffset < 0 || d->m_endOffset <0) {
3445  kdDebug() << "invalid values for end/startOffset " << d->m_startOffset << " " << d->m_endOffset << endl;
3446  return TQString();
3447  }
3448  DOM::Range r = selection();
3449  if(r.isNull() || r.isDetached())
3450  return TQString();
3451  int exceptioncode = 0; //ignore the result
3452  return r.handle()->toHTML(exceptioncode).string();
3453 }
3454 
3455 TQString KHTMLPart::selectedText() const
3456 {
3457  bool hasNewLine = true;
3458  bool seenTDTag = false;
3459  TQString text;
3460  DOM::Node n = d->m_selectionStart;
3461  while(!n.isNull()) {
3462  if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
3463  DOM::DOMStringImpl *dstr = static_cast<DOM::TextImpl*>(n.handle())->renderString();
3464  TQString str(dstr->s, dstr->l);
3465  if(!str.isEmpty()) {
3466  if(seenTDTag) {
3467  text += " ";
3468  seenTDTag = false;
3469  }
3470  hasNewLine = false;
3471  if(n == d->m_selectionStart && n == d->m_selectionEnd)
3472  text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
3473  else if(n == d->m_selectionStart)
3474  text = str.mid(d->m_startOffset);
3475  else if(n == d->m_selectionEnd)
3476  text += str.left(d->m_endOffset);
3477  else
3478  text += str;
3479  }
3480  }
3481  else {
3482  // This is our simple HTML -> ASCII transformation:
3483  unsigned short id = n.elementId();
3484  switch(id) {
3485  case ID_TEXTAREA:
3486  text += static_cast<HTMLTextAreaElementImpl*>(n.handle())->value().string();
3487  break;
3488  case ID_INPUT:
3489  if (static_cast<HTMLInputElementImpl*>(n.handle())->inputType() != HTMLInputElementImpl::PASSWORD)
3490  text += static_cast<HTMLInputElementImpl*>(n.handle())->value().string();
3491  break;
3492  case ID_SELECT:
3493  text += static_cast<HTMLSelectElementImpl*>(n.handle())->value().string();
3494  break;
3495  case ID_BR:
3496  text += "\n";
3497  hasNewLine = true;
3498  break;
3499  case ID_IMG:
3500  text += static_cast<HTMLImageElementImpl*>(n.handle())->altText().string();
3501  break;
3502  case ID_TD:
3503  break;
3504  case ID_TH:
3505  case ID_HR:
3506  case ID_OL:
3507  case ID_UL:
3508  case ID_LI:
3509  case ID_DD:
3510  case ID_DL:
3511  case ID_DT:
3512  case ID_PRE:
3513  case ID_BLOCKQUOTE:
3514  case ID_DIV:
3515  if (!hasNewLine)
3516  text += "\n";
3517  hasNewLine = true;
3518  break;
3519  case ID_P:
3520  case ID_TR:
3521  case ID_H1:
3522  case ID_H2:
3523  case ID_H3:
3524  case ID_H4:
3525  case ID_H5:
3526  case ID_H6:
3527  if (!hasNewLine)
3528  text += "\n";
3529 // text += "\n";
3530  hasNewLine = true;
3531  break;
3532  }
3533  }
3534  if(n == d->m_selectionEnd) break;
3535  DOM::Node next = n.firstChild();
3536  if(next.isNull()) next = n.nextSibling();
3537  while( next.isNull() && !n.parentNode().isNull() ) {
3538  n = n.parentNode();
3539  next = n.nextSibling();
3540  unsigned short id = n.elementId();
3541  switch(id) {
3542  case ID_TD:
3543  seenTDTag = true; //Add two spaces after a td if then followed by text.
3544  break;
3545  case ID_TH:
3546  case ID_HR:
3547  case ID_OL:
3548  case ID_UL:
3549  case ID_LI:
3550  case ID_DD:
3551  case ID_DL:
3552  case ID_DT:
3553  case ID_PRE:
3554  case ID_BLOCKQUOTE:
3555  case ID_DIV:
3556  seenTDTag = false;
3557  if (!hasNewLine)
3558  text += "\n";
3559  hasNewLine = true;
3560  break;
3561  case ID_P:
3562  case ID_TR:
3563  case ID_H1:
3564  case ID_H2:
3565  case ID_H3:
3566  case ID_H4:
3567  case ID_H5:
3568  case ID_H6:
3569  if (!hasNewLine)
3570  text += "\n";
3571 // text += "\n";
3572  hasNewLine = true;
3573  break;
3574  }
3575  }
3576 
3577  n = next;
3578  }
3579 
3580  if(text.isEmpty())
3581  return TQString();
3582 
3583  int start = 0;
3584  int end = text.length();
3585 
3586  // Strip leading LFs
3587  while ((start < end) && (text[start] == '\n'))
3588  ++start;
3589 
3590  // Strip excessive trailing LFs
3591  while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
3592  --end;
3593 
3594  return text.mid(start, end-start);
3595 }
3596 
3597 bool KHTMLPart::hasSelection() const
3598 {
3599  if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
3600  return false;
3601  if ( d->m_selectionStart == d->m_selectionEnd &&
3602  d->m_startOffset == d->m_endOffset )
3603  return false; // empty
3604  return true;
3605 }
3606 
3607 DOM::Range KHTMLPart::selection() const
3608 {
3609  if( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
3610  return DOM::Range();
3611  DOM::Range r = document().createRange();
3612  RangeImpl *rng = r.handle();
3613  int exception = 0;
3614  NodeImpl *n = d->m_selectionStart.handle();
3615  if(!n->parentNode() ||
3616  !n->renderer() ||
3617  (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
3618  rng->setStart( n, d->m_startOffset, exception );
3619  if(exception) {
3620  kdDebug(6000) << "1 -selection() threw the exception " << exception << ". Returning empty range." << endl;
3621  return DOM::Range();
3622  }
3623  } else {
3624  int o_start = 0;
3625  while ((n = n->previousSibling()))
3626  o_start++;
3627  rng->setStart( d->m_selectionStart.parentNode().handle(), o_start + d->m_startOffset, exception );
3628  if(exception) {
3629  kdDebug(6000) << "2 - selection() threw the exception " << exception << ". Returning empty range." << endl;
3630  return DOM::Range();
3631  }
3632 
3633  }
3634 
3635  n = d->m_selectionEnd.handle();
3636  if(!n->parentNode() ||
3637  !n->renderer() ||
3638  (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
3639 
3640  rng->setEnd( n, d->m_endOffset, exception );
3641  if(exception) {
3642  kdDebug(6000) << "3 - selection() threw the exception " << exception << ". Returning empty range." << endl;
3643  return DOM::Range();
3644  }
3645 
3646  } else {
3647  int o_end = 0;
3648  while ((n = n->previousSibling()))
3649  o_end++;
3650  rng->setEnd( d->m_selectionEnd.parentNode().handle(), o_end + d->m_endOffset, exception);
3651  if(exception) {
3652  kdDebug(6000) << "4 - selection() threw the exception " << exception << ". Returning empty range." << endl;
3653  return DOM::Range();
3654  }
3655 
3656  }
3657 
3658  return r;
3659 }
3660 
3661 void KHTMLPart::selection(DOM::Node &s, long &so, DOM::Node &e, long &eo) const
3662 {
3663  s = d->m_selectionStart;
3664  so = d->m_startOffset;
3665  e = d->m_selectionEnd;
3666  eo = d->m_endOffset;
3667 }
3668 
3669 void KHTMLPart::setSelection( const DOM::Range &r )
3670 {
3671  // Quick-fix: a collapsed range shouldn't select the whole node.
3672  // The real problem is in RenderCanvas::setSelection though (when index==0 the whole node is selected).
3673  if ( r.collapsed() )
3674  slotClearSelection();
3675  else {
3676  d->m_selectionStart = r.startContainer();
3677  d->m_startOffset = r.startOffset();
3678  d->m_selectionEnd = r.endContainer();
3679  d->m_endOffset = r.endOffset();
3680  d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
3681  d->m_selectionEnd.handle(),d->m_endOffset);
3682 #ifndef KHTML_NO_CARET
3683  bool v = d->m_view->placeCaret();
3684  emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
3685 #endif
3686  }
3687 }
3688 
3689 void KHTMLPart::slotClearSelection()
3690 {
3691  bool hadSelection = hasSelection();
3692 #ifndef KHTML_NO_CARET
3693  //kdDebug(6000) << "d->m_selectionStart " << d->m_selectionStart.handle()
3694  // << " d->m_selectionEnd " << d->m_selectionEnd.handle() << endl;
3695  // nothing, leave selection parameters as is
3696 #else
3697  d->m_selectionStart = 0;
3698  d->m_startOffset = 0;
3699  d->m_selectionEnd = 0;
3700  d->m_endOffset = 0;
3701 #endif
3702  if ( d->m_doc ) d->m_doc->clearSelection();
3703  if ( hadSelection )
3704  emitSelectionChanged();
3705 #ifndef KHTML_NO_CARET
3706  bool v = d->m_view->placeCaret();
3707  emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
3708 #endif
3709 }
3710 
3711 void KHTMLPart::resetHoverText()
3712 {
3713  if( !d->m_overURL.isEmpty() ) // Only if we were showing a link
3714  {
3715  d->m_overURL = d->m_overURLTarget = TQString();
3716  emit onURL( TQString() );
3717  // revert to default statusbar text
3718  setStatusBarText(TQString(), BarHoverText);
3719  emit d->m_extension->mouseOverInfo(0);
3720  }
3721 }
3722 
3723 void KHTMLPart::overURL( const TQString &url, const TQString &target, bool /*shiftPressed*/ )
3724 {
3725  KURL u = completeURL(url);
3726 
3727  // special case for <a href="">
3728  if ( url.isEmpty() )
3729  u.setFileName( url );
3730 
3731  emit onURL( url );
3732 
3733  if ( url.isEmpty() ) {
3734  setStatusBarText(u.htmlURL(), BarHoverText);
3735  return;
3736  }
3737 
3738  if (url.find( TQString::fromLatin1( "javascript:" ),0, false ) == 0 ) {
3739  TQString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
3740  jscode = KStringHandler::rsqueeze( jscode, 80 ); // truncate if too long
3741  if (url.startsWith("javascript:window.open"))
3742  jscode += i18n(" (In new window)");
3743  setStatusBarText( TQStyleSheet::escape( jscode ), BarHoverText );
3744  return;
3745  }
3746 
3747  KFileItem item(u, TQString(), KFileItem::Unknown);
3748  emit d->m_extension->mouseOverInfo(&item);
3749 
3750  TQString com;
3751 
3752  KMimeType::Ptr typ = KMimeType::findByURL( u );
3753 
3754  if ( typ )
3755  com = typ->comment( u, false );
3756 
3757  if ( !u.isValid() ) {
3758  setStatusBarText(u.htmlURL(), BarHoverText);
3759  return;
3760  }
3761 
3762  if ( u.isLocalFile() )
3763  {
3764  // TODO : use KIO::stat() and create a KFileItem out of its result,
3765  // to use KFileItem::statusBarText()
3766  TQCString path = TQFile::encodeName( u.path() );
3767 
3768  struct stat buff;
3769  bool ok = !stat( path.data(), &buff );
3770 
3771  struct stat lbuff;
3772  if (ok) ok = !lstat( path.data(), &lbuff );
3773 
3774  TQString text = u.htmlURL();
3775  TQString text2 = text;
3776 
3777  if (ok && S_ISLNK( lbuff.st_mode ) )
3778  {
3779  TQString tmp;
3780  if ( com.isNull() )
3781  tmp = i18n( "Symbolic Link");
3782  else
3783  tmp = i18n("%1 (Link)").arg(com);
3784  char buff_two[1024];
3785  text += " -> ";
3786  int n = readlink ( path.data(), buff_two, 1022);
3787  if (n == -1)
3788  {
3789  text2 += " ";
3790  text2 += tmp;
3791  setStatusBarText(text2, BarHoverText);
3792  return;
3793  }
3794  buff_two[n] = 0;
3795 
3796  text += buff_two;
3797  text += " ";
3798  text += tmp;
3799  }
3800  else if ( ok && S_ISREG( buff.st_mode ) )
3801  {
3802  if (buff.st_size < 1024)
3803  text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
3804  else
3805  {
3806  float d = (float) buff.st_size/1024.0;
3807  text = i18n("%2 (%1 K)").arg(KGlobal::locale()->formatNumber(d, 2)).arg(text2); // was %.2f
3808  }
3809  text += " ";
3810  text += com;
3811  }
3812  else if ( ok && S_ISDIR( buff.st_mode ) )
3813  {
3814  text += " ";
3815  text += com;
3816  }
3817  else
3818  {
3819  text += " ";
3820  text += com;
3821  }
3822  setStatusBarText(text, BarHoverText);
3823  }
3824  else
3825  {
3826  TQString extra;
3827  if (target.lower() == "_blank")
3828  {
3829  extra = i18n(" (In new window)");
3830  }
3831  else if (!target.isEmpty() &&
3832  (target.lower() != "_top") &&
3833  (target.lower() != "_self") &&
3834  (target.lower() != "_parent"))
3835  {
3836  KHTMLPart *p = this;
3837  while (p->parentPart())
3838  p = p->parentPart();
3839  if (!p->frameExists(target))
3840  extra = i18n(" (In new window)");
3841  else
3842  extra = i18n(" (In other frame)");
3843  }
3844 
3845  if (u.protocol() == TQString::fromLatin1("mailto")) {
3846  TQString mailtoMsg /* = TQString::fromLatin1("<img src=%1>").arg(locate("icon", TQString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
3847  mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
3848  TQStringList queries = TQStringList::split('&', u.query().mid(1));
3849  TQStringList::Iterator it = queries.begin();
3850  const TQStringList::Iterator itEnd = queries.end();
3851  for (; it != itEnd; ++it)
3852  if ((*it).startsWith(TQString::fromLatin1("subject=")))
3853  mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
3854  else if ((*it).startsWith(TQString::fromLatin1("cc=")))
3855  mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
3856  else if ((*it).startsWith(TQString::fromLatin1("bcc=")))
3857  mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
3858  mailtoMsg = TQStyleSheet::escape(mailtoMsg);
3859  mailtoMsg.replace(TQRegExp("([\n\r\t]|[ ]{10})"), TQString());
3860  setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
3861  return;
3862  }
3863  // Is this check necessary at all? (Frerich)
3864 #if 0
3865  else if (u.protocol() == TQString::fromLatin1("http")) {
3866  DOM::Node hrefNode = nodeUnderMouse().parentNode();
3867  while (hrefNode.nodeName().string() != TQString::fromLatin1("A") && !hrefNode.isNull())
3868  hrefNode = hrefNode.parentNode();
3869 
3870  if (!hrefNode.isNull()) {
3871  DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
3872  if (!hreflangNode.isNull()) {
3873  TQString countryCode = hreflangNode.nodeValue().string().lower();
3874  // Map the language code to an appropriate country code.
3875  if (countryCode == TQString::fromLatin1("en"))
3876  countryCode = TQString::fromLatin1("gb");
3877  TQString flagImg = TQString::fromLatin1("<img src=%1>").arg(
3878  locate("locale", TQString::fromLatin1("l10n/")
3879  + countryCode
3880  + TQString::fromLatin1("/flag.png")));
3881  emit setStatusBarText(flagImg + u.prettyURL() + extra);
3882  }
3883  }
3884  }
3885 #endif
3886  setStatusBarText(u.htmlURL() + extra, BarHoverText);
3887  }
3888 }
3889 
3890 //
3891 // This executes in the active part on a click or other url selection action in
3892 // that active part.
3893 //
3894 void KHTMLPart::urlSelected( const TQString &url, int button, int state, const TQString &_target, KParts::URLArgs args )
3895 {
3896  // The member var is so that slotRedirection still calls the virtual urlSelected
3897  // but is able to know if is opened a url. KDE4: just make urlSelected return a bool
3898  // and move the urlSelectedIntern code back here.
3899  d->m_urlSelectedOpenedURL = urlSelectedIntern( url, button, state, _target, args );
3900 }
3901 
3902 // Return value: true if an url was opened, false if not (e.g. error, or jumping to anchor)
3903 bool KHTMLPart::urlSelectedIntern( const TQString &url, int button, int state, const TQString &_target, KParts::URLArgs args )
3904 {
3905  bool hasTarget = false;
3906 
3907  TQString target = _target;
3908  if ( target.isEmpty() && d->m_doc )
3909  target = d->m_doc->baseTarget();
3910  if ( !target.isEmpty() )
3911  hasTarget = true;
3912 
3913  if ( url.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 )
3914  {
3915  crossFrameExecuteScript( target, KURL::decode_string( url.mid( 11 ) ) );
3916  return false;
3917  }
3918 
3919  KURL cURL = completeURL(url);
3920  // special case for <a href=""> (IE removes filename, mozilla doesn't)
3921  if ( url.isEmpty() )
3922  cURL.setFileName( url ); // removes filename
3923 
3924  if ( !cURL.isValid() )
3925  // ### ERROR HANDLING
3926  return false;
3927 
3928  kdDebug(6050) << this << " urlSelected: complete URL:" << cURL.url() << " target=" << target << endl;
3929 
3930  if ( state & ControlButton )
3931  {
3932  args.setNewTab(true);
3933  emit d->m_extension->createNewWindow( cURL, args );
3934  return true;
3935  }
3936 
3937  if ( button == Qt::LeftButton && ( state & ShiftButton ) )
3938  {
3939  KIO::MetaData metaData;
3940  metaData["referrer"] = d->m_referrer;
3941  KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), cURL, metaData );
3942  return false;
3943  }
3944 
3945  if (!checkLinkSecurity(cURL,
3946  i18n( "<qt>This untrusted page links to<BR><B>%1</B>.<BR>Do you want to follow the link?" ),
3947  i18n( "Follow" )))
3948  return false;
3949 
3950  args.frameName = target;
3951 
3952  args.metaData().insert("main_frame_request",
3953  parentPart() == 0 ? "TRUE":"FALSE");
3954  args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
3955  args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
3956  args.metaData().insert("PropagateHttpHeader", "true");
3957  args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
3958  args.metaData().insert("ssl_activate_warnings", "TRUE");
3959 
3960  if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" )
3961  {
3962  // unknown frame names should open in a new window.
3963  khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
3964  if ( frame )
3965  {
3966  args.metaData()["referrer"] = d->m_referrer;
3967  requestObject( frame, cURL, args );
3968  return true;
3969  }
3970  }
3971 
3972  if (!d->m_referrer.isEmpty() && !args.metaData().contains("referrer"))
3973  args.metaData()["referrer"] = d->m_referrer;
3974 
3975 
3976  if ( button == Qt::NoButton && (state & ShiftButton) && (state & ControlButton) )
3977  {
3978  emit d->m_extension->createNewWindow( cURL, args );
3979  return true;
3980  }
3981 
3982  if ( state & ShiftButton)
3983  {
3984  KParts::WindowArgs winArgs;
3985  winArgs.lowerWindow = true;
3986  KParts::ReadOnlyPart *newPart = 0;
3987  emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
3988  return true;
3989  }
3990 
3991  //If we're asked to open up an anchor in the current URL, in current window,
3992  //merely gotoanchor, and do not reload the new page. Note that this does
3993  //not apply if the URL is the same page, but without a ref
3994  if (cURL.hasRef() && (!hasTarget || target == "_self"))
3995  {
3996  KURL curUrl = this->url();
3997  if (urlcmp(cURL.url(), curUrl.url(),
3998  false, // ignore trailing / diff, IE does, even if FFox doesn't
3999  true)) // don't care if the ref changes!
4000  {
4001  m_url = cURL;
4002  emit d->m_extension->openURLNotify();
4003  if ( !gotoAnchor( m_url.encodedHtmlRef()) )
4004  gotoAnchor( m_url.htmlRef() );
4005  emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
4006  return false; // we jumped, but we didn't open a URL
4007  }
4008  }
4009 
4010  if ( !d->m_bComplete && !hasTarget )
4011  closeURL();
4012 
4013  view()->viewport()->unsetCursor();
4014  emit d->m_extension->openURLRequest( cURL, args );
4015  return true;
4016 }
4017 
4018 void KHTMLPart::slotViewDocumentSource()
4019 {
4020  KURL url(m_url);
4021  bool isTempFile = false;
4022  if (!(url.isLocalFile()) && KHTMLPageCache::self()->isComplete(d->m_cacheId))
4023  {
4024  KTempFile sourceFile(TQString(), defaultExtension());
4025  if (sourceFile.status() == 0)
4026  {
4027  KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
4028  url = KURL();
4029  url.setPath(sourceFile.name());
4030  isTempFile = true;
4031  }
4032  }
4033 
4034  (void) KRun::runURL( url, TQString::fromLatin1("text/plain"), isTempFile );
4035 }
4036 
4037 void KHTMLPart::slotViewPageInfo()
4038 {
4039  KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, (WFlags)WDestructiveClose);
4040  dlg->_close->setGuiItem(KStdGuiItem::close());
4041 
4042  if (d->m_doc)
4043  dlg->_title->setText(d->m_doc->title().string());
4044 
4045  // If it's a frame, set the caption to "Frame Information"
4046  if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
4047  dlg->setCaption(i18n("Frame Information"));
4048  }
4049 
4050  TQString editStr = TQString();
4051 
4052  if (!d->m_pageServices.isEmpty())
4053  editStr = i18n(" <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);
4054 
4055  TQString squeezedURL = KStringHandler::csqueeze( url().prettyURL(), 80 );
4056  dlg->_url->setText("<a href=\"" + url().url() + "\">" + squeezedURL + "</a>" + editStr);
4057  if (lastModified().isEmpty())
4058  {
4059  dlg->_lastModified->hide();
4060  dlg->_lmLabel->hide();
4061  }
4062  else
4063  dlg->_lastModified->setText(lastModified());
4064 
4065  const TQString& enc = encoding();
4066  if (enc.isEmpty()) {
4067  dlg->_eLabel->hide();
4068  dlg->_encoding->hide();
4069  } else {
4070  dlg->_encoding->setText(enc);
4071  }
4072  /* populate the list view now */
4073  const TQStringList headers = TQStringList::split("\n", d->m_httpHeaders);
4074 
4075  TQStringList::ConstIterator it = headers.begin();
4076  const TQStringList::ConstIterator itEnd = headers.end();
4077 
4078  for (; it != itEnd; ++it) {
4079  const TQStringList header = TQStringList::split(TQRegExp(":[ ]+"), *it);
4080  if (header.count() != 2)
4081  continue;
4082  new TQListViewItem(dlg->_headers, header[0], header[1]);
4083  }
4084 
4085  dlg->show();
4086  /* put no code here */
4087 }
4088 
4089 
4090 void KHTMLPart::slotViewFrameSource()
4091 {
4092  KParts::ReadOnlyPart *frame = currentFrame();
4093  if ( !frame )
4094  return;
4095 
4096  KURL url = frame->url();
4097  bool isTempFile = false;
4098  if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
4099  {
4100  long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
4101 
4102  if (KHTMLPageCache::self()->isComplete(cacheId))
4103  {
4104  KTempFile sourceFile(TQString(), defaultExtension());
4105  if (sourceFile.status() == 0)
4106  {
4107  KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
4108  url = KURL();
4109  url.setPath(sourceFile.name());
4110  isTempFile = true;
4111  }
4112  }
4113  }
4114 
4115  (void) KRun::runURL( url, TQString::fromLatin1("text/plain"), isTempFile );
4116 }
4117 
4118 KURL KHTMLPart::backgroundURL() const
4119 {
4120  // ### what about XML documents? get from CSS?
4121  if (!d->m_doc || !d->m_doc->isHTMLDocument())
4122  return KURL();
4123 
4124  TQString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
4125 
4126  return KURL( m_url, relURL );
4127 }
4128 
4129 void KHTMLPart::slotSaveBackground()
4130 {
4131  KIO::MetaData metaData;
4132  metaData["referrer"] = d->m_referrer;
4133  KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save Background Image As"), backgroundURL(), metaData );
4134 }
4135 
4136 void KHTMLPart::slotSaveDocument()
4137 {
4138  KURL srcURL( m_url );
4139 
4140  if ( srcURL.fileName(false).isEmpty() )
4141  srcURL.setFileName( "index" + defaultExtension() );
4142 
4143  KIO::MetaData metaData;
4144  // Referre unknown?
4145  KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, "text/html", d->m_cacheId );
4146 }
4147 
4148 void KHTMLPart::slotSecurity()
4149 {
4150 // kdDebug( 6050 ) << "Meta Data:" << endl
4151 // << d->m_ssl_peer_cert_subject
4152 // << endl
4153 // << d->m_ssl_peer_cert_issuer
4154 // << endl
4155 // << d->m_ssl_cipher
4156 // << endl
4157 // << d->m_ssl_cipher_desc
4158 // << endl
4159 // << d->m_ssl_cipher_version
4160 // << endl
4161 // << d->m_ssl_good_from
4162 // << endl
4163 // << d->m_ssl_good_until
4164 // << endl
4165 // << d->m_ssl_cert_state
4166 // << endl;
4167 
4168  KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
4169 
4170  if (d->m_bSecurityInQuestion)
4171  kid->setSecurityInQuestion(true);
4172 
4173  if (d->m_ssl_in_use) {
4174  KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
4175  if (x) {
4176  // Set the chain back onto the certificate
4177  const TQStringList cl = TQStringList::split(TQString("\n"), d->m_ssl_peer_chain);
4178  TQPtrList<KSSLCertificate> ncl;
4179 
4180  ncl.setAutoDelete(true);
4181  TQStringList::ConstIterator it = cl.begin();
4182  const TQStringList::ConstIterator itEnd = cl.end();
4183  for (; it != itEnd; ++it) {
4184  KSSLCertificate* const y = KSSLCertificate::fromString((*it).local8Bit());
4185  if (y) ncl.append(y);
4186  }
4187 
4188  if (ncl.count() > 0)
4189  x->chain().setChain(ncl);
4190 
4191  kid->setup(x,
4192  d->m_ssl_peer_ip,
4193  m_url.url(),
4194  d->m_ssl_cipher,
4195  d->m_ssl_cipher_desc,
4196  d->m_ssl_cipher_version,
4197  d->m_ssl_cipher_used_bits.toInt(),
4198  d->m_ssl_cipher_bits.toInt(),
4199  (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
4200  );
4201  kid->exec();
4202  delete x;
4203  } else kid->exec();
4204  } else kid->exec();
4205 }
4206 
4207 void KHTMLPart::slotSaveFrame()
4208 {
4209  KParts::ReadOnlyPart *frame = currentFrame();
4210  if ( !frame )
4211  return;
4212 
4213  KURL srcURL( frame->url() );
4214 
4215  if ( srcURL.fileName(false).isEmpty() )
4216  srcURL.setFileName( "index" + defaultExtension() );
4217 
4218  KIO::MetaData metaData;
4219  // Referrer unknown?
4220  KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save Frame As" ), srcURL, metaData, "text/html" );
4221 }
4222 
4223 void KHTMLPart::slotSetEncoding()
4224 {
4225  d->m_automaticDetection->setItemChecked( int( d->m_autoDetectLanguage ), false );
4226  d->m_paSetEncoding->popupMenu()->setItemChecked( 0, false );
4227  d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), true );
4228 
4229  TQString enc = KGlobal::charsets()->encodingForName( d->m_manualDetection->currentText() );
4230  setEncoding( enc, true );
4231 }
4232 
4233 void KHTMLPart::slotUseStylesheet()
4234 {
4235  if (d->m_doc)
4236  {
4237  bool autoselect = (d->m_paUseStylesheet->currentItem() == 0);
4238  d->m_sheetUsed = autoselect ? TQString() : d->m_paUseStylesheet->currentText();
4239  d->m_doc->updateStyleSelector();
4240  }
4241 }
4242 
4243 void KHTMLPart::updateActions()
4244 {
4245  bool frames = false;
4246 
4247  TQValueList<khtml::ChildFrame*>::ConstIterator it = d->m_frames.begin();
4248  const TQValueList<khtml::ChildFrame*>::ConstIterator end = d->m_frames.end();
4249  for (; it != end; ++it )
4250  if ( (*it)->m_type == khtml::ChildFrame::Frame )
4251  {
4252  frames = true;
4253  break;
4254  }
4255 
4256  d->m_paViewFrame->setEnabled( frames );
4257  d->m_paSaveFrame->setEnabled( frames );
4258 
4259  if ( frames )
4260  d->m_paFind->setText( i18n( "&Find in Frame..." ) );
4261  else
4262  d->m_paFind->setText( i18n( "&Find..." ) );
4263 
4264  KParts::Part *frame = 0;
4265 
4266  if ( frames )
4267  frame = currentFrame();
4268 
4269  bool enableFindAndSelectAll = true;
4270 
4271  if ( frame )
4272  enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
4273 
4274  d->m_paFind->setEnabled( enableFindAndSelectAll );
4275  d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
4276 
4277  bool enablePrintFrame = false;
4278 
4279  if ( frame )
4280  {
4281  TQObject *ext = KParts::BrowserExtension::childObject( frame );
4282  if ( ext )
4283  enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
4284  }
4285 
4286  d->m_paPrintFrame->setEnabled( enablePrintFrame );
4287 
4288  TQString bgURL;
4289 
4290  // ### frames
4291  if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
4292  bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
4293 
4294  d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
4295 
4296  if ( d->m_paDebugScript )
4297  d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
4298 }
4299 
4300 KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
4301  const ConstFrameIt end = d->m_objects.end();
4302  for(ConstFrameIt it = d->m_objects.begin(); it != end; ++it )
4303  if ((*it)->m_frame == frame)
4304  return (*it)->m_liveconnect;
4305  return 0L;
4306 }
4307 
4308 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const TQString &url, const TQString &frameName,
4309  const TQStringList &params, bool isIFrame )
4310 {
4311  //kdDebug( 6050 ) << this << " requestFrame( ..., " << url << ", " << frameName << " )" << endl;
4312  FrameIt it = d->m_frames.find( frameName );
4313  if ( it == d->m_frames.end() )
4314  {
4315  khtml::ChildFrame * child = new khtml::ChildFrame;
4316  //kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
4317  child->m_name = frameName;
4318  it = d->m_frames.append( child );
4319  }
4320 
4321  (*it)->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
4322  (*it)->m_frame = frame;
4323  (*it)->m_params = params;
4324 
4325  // Support for <frame src="javascript:string">
4326  if ( url.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 )
4327  {
4328  if ( processObjectRequest(*it, KURL("about:blank"), TQString("text/html") ) ) {
4329  KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>((*it)->m_part));
4330 
4331  // See if we want to replace content with javascript: output..
4332  TQVariant res = p->executeScript( DOM::Node(), KURL::decode_string( url.right( url.length() - 11) ) );
4333  if ( res.type() == TQVariant::String ) {
4334  p->begin();
4335  p->write( res.asString() );
4336  p->end();
4337  }
4338  return true;
4339  }
4340  return false;
4341  }
4342  KURL u = url.isEmpty() ? KURL() : completeURL( url );
4343  return requestObject( *it, u );
4344 }
4345 
4346 TQString KHTMLPart::requestFrameName()
4347 {
4348  return TQString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
4349 }
4350 
4351 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const TQString &url, const TQString &serviceType,
4352  const TQStringList &params )
4353 {
4354  //kdDebug( 6005 ) << "KHTMLPart::requestObject " << this << " frame=" << frame << endl;
4355  khtml::ChildFrame *child = new khtml::ChildFrame;
4356  FrameIt it = d->m_objects.append( child );
4357  (*it)->m_frame = frame;
4358  (*it)->m_type = khtml::ChildFrame::Object;
4359  (*it)->m_params = params;
4360 
4361  KParts::URLArgs args;
4362  args.serviceType = serviceType;
4363  if (!requestObject( *it, completeURL( url ), args ) && !(*it)->m_run) {
4364  (*it)->m_bCompleted = true;
4365  return false;
4366  }
4367  return true;
4368 }
4369 
4370 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
4371 {
4372  if (!checkLinkSecurity(url))
4373  {
4374  kdDebug(6005) << this << " KHTMLPart::requestObject checkLinkSecurity refused" << endl;
4375  return false;
4376  }
4377  if ( child->m_bPreloaded )
4378  {
4379  kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
4380  if ( child->m_frame && child->m_part )
4381  child->m_frame->setWidget( child->m_part->widget() );
4382 
4383  child->m_bPreloaded = false;
4384  return true;
4385  }
4386 
4387  //kdDebug(6005) << "KHTMLPart::requestObject child=" << child << " child->m_part=" << child->m_part << endl;
4388 
4389  KParts::URLArgs args( _args );
4390 
4391  if ( child->m_run )
4392  child->m_run->abort();
4393 
4394  if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
4395  args.serviceType = child->m_serviceType;
4396 
4397  child->m_args = args;
4398  child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
4399  child->m_serviceName = TQString();
4400  if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
4401  child->m_args.metaData()["referrer"] = d->m_referrer;
4402 
4403  child->m_args.metaData().insert("PropagateHttpHeader", "true");
4404  child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
4405  child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
4406  child->m_args.metaData().insert("main_frame_request",
4407  parentPart() == 0 ? "TRUE":"FALSE");
4408  child->m_args.metaData().insert("ssl_was_in_use",
4409  d->m_ssl_in_use ? "TRUE":"FALSE");
4410  child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
4411  child->m_args.metaData().insert("cross-domain", toplevelURL().url());
4412 
4413  // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
4414  if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
4415  args.serviceType = TQString::fromLatin1( "text/html" );
4416 
4417  if ( args.serviceType.isEmpty() ) {
4418  kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << endl;
4419  child->m_run = new KHTMLRun( this, child, url, child->m_args, true );
4420  d->m_bComplete = false; // ensures we stop it in checkCompleted...
4421  return false;
4422  } else {
4423  return processObjectRequest( child, url, args.serviceType );
4424  }
4425 }
4426 
4427 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const TQString &mimetype )
4428 {
4429  //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
4430 
4431  // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
4432  // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
4433  // though -> the reference becomes invalid -> crash is likely
4434  KURL url( _url );
4435 
4436  // khtmlrun called us this way to indicate a loading error
4437  if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
4438  {
4439  child->m_bCompleted = true;
4440  checkCompleted();
4441  return true;
4442  }
4443 
4444  if (child->m_bNotify)
4445  {
4446  child->m_bNotify = false;
4447  if ( !child->m_args.lockHistory() )
4448  emit d->m_extension->openURLNotify();
4449  }
4450 
4451  if ( child->m_serviceType != mimetype || !child->m_part )
4452  {
4453  // Before attempting to load a part, check if the user wants that.
4454  // Many don't like getting ZIP files embedded.
4455  // However we don't want to ask for flash and other plugin things..
4456  if ( child->m_type != khtml::ChildFrame::Object )
4457  {
4458  TQString suggestedFilename;
4459  if ( child->m_run )
4460  suggestedFilename = child->m_run->suggestedFilename();
4461 
4462  KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave(
4463  url, mimetype, suggestedFilename );
4464  switch( res ) {
4465  case KParts::BrowserRun::Save:
4466  KHTMLPopupGUIClient::saveURL( widget(), i18n( "Save As" ), url, child->m_args.metaData(), TQString(), 0, suggestedFilename);
4467  // fall-through
4468  case KParts::BrowserRun::Cancel:
4469  child->m_bCompleted = true;
4470  checkCompleted();
4471  return true; // done
4472  default: // Open
4473  break;
4474  }
4475  }
4476 
4477  TQStringList dummy; // the list of servicetypes handled by the part is now unused.
4478  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 );
4479 
4480  if ( !part )
4481  {
4482  if ( child->m_frame )
4483  if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
4484  return true; // we succeeded after all (a fallback was used)
4485 
4486  checkEmitLoadEvent();
4487  return false;
4488  }
4489 
4490  //CRITICAL STUFF
4491  if ( child->m_part )
4492  {
4493  if (!::tqqt_cast<KHTMLPart*>(child->m_part) && child->m_jscript)
4494  child->m_jscript->clear();
4495  partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
4496  delete (KParts::ReadOnlyPart *)child->m_part;
4497  if (child->m_liveconnect) {
4498  disconnect(child->m_liveconnect, TQT_SIGNAL(partEvent(const unsigned long, const TQString &, const KParts::LiveConnectExtension::ArgList &)), child, TQT_SLOT(liveConnectEvent(const unsigned long, const TQString&, const KParts::LiveConnectExtension::ArgList &)));
4499  child->m_liveconnect = 0L;
4500  }
4501  }
4502 
4503  child->m_serviceType = mimetype;
4504  if ( child->m_frame && part->widget() )
4505  child->m_frame->setWidget( part->widget() );
4506 
4507  if ( child->m_type != khtml::ChildFrame::Object )
4508  partManager()->addPart( part, false );
4509 // else
4510 // kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
4511 
4512  child->m_part = part;
4513 
4514  if (::tqqt_cast<KHTMLPart*>(part)) {
4515  static_cast<KHTMLPart*>(part)->d->m_frame = child;
4516  } else if (child->m_frame) {
4517  child->m_liveconnect = KParts::LiveConnectExtension::childObject(part);
4518  if (child->m_liveconnect)
4519  connect(child->m_liveconnect, TQT_SIGNAL(partEvent(const unsigned long, const TQString &, const KParts::LiveConnectExtension::ArgList &)), child, TQT_SLOT(liveConnectEvent(const unsigned long, const TQString&, const KParts::LiveConnectExtension::ArgList &)));
4520  }
4521  KParts::StatusBarExtension *sb = KParts::StatusBarExtension::childObject(part);
4522  if (sb)
4523  sb->setStatusBar( d->m_statusBarExtension->statusBar() );
4524 
4525  connect( part, TQT_SIGNAL( started( KIO::Job *) ),
4526  this, TQT_SLOT( slotChildStarted( KIO::Job *) ) );
4527  connect( part, TQT_SIGNAL( completed() ),
4528  this, TQT_SLOT( slotChildCompleted() ) );
4529  connect( part, TQT_SIGNAL( completed(bool) ),
4530  this, TQT_SLOT( slotChildCompleted(bool) ) );
4531  connect( part, TQT_SIGNAL( setStatusBarText( const TQString & ) ),
4532  this, TQT_SIGNAL( setStatusBarText( const TQString & ) ) );
4533  if ( part->inherits( "KHTMLPart" ) )
4534  {
4535  connect( this, TQT_SIGNAL( completed() ),
4536  part, TQT_SLOT( slotParentCompleted() ) );
4537  connect( this, TQT_SIGNAL( completed(bool) ),
4538  part, TQT_SLOT( slotParentCompleted() ) );
4539  // As soon as the child's document is created, we need to set its domain
4540  // (but we do so only once, so it can't be simply done in the child)
4541  connect( part, TQT_SIGNAL( docCreated() ),
4542  this, TQT_SLOT( slotChildDocCreated() ) );
4543  }
4544 
4545  child->m_extension = KParts::BrowserExtension::childObject( part );
4546 
4547  if ( child->m_extension )
4548  {
4549  connect( child->m_extension, TQT_SIGNAL( openURLNotify() ),
4550  d->m_extension, TQT_SIGNAL( openURLNotify() ) );
4551 
4552  connect( child->m_extension, TQT_SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
4553  this, TQT_SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
4554 
4555  connect( child->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
4556  d->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
4557  connect( child->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
4558  d->m_extension, TQT_SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
4559 
4560  connect( child->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KFileItemList & ) ),
4561  d->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KFileItemList & ) ) );
4562  connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList & ) ),
4563  d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList & ) ) );
4564  connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ),
4565  d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) );
4566  connect( child->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KURL &, const TQString &, mode_t ) ),
4567  d->m_extension, TQT_SIGNAL( popupMenu( const TQPoint &, const KURL &, const TQString &, mode_t ) ) );
4568  connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const TQString &, mode_t ) ),
4569  d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const TQString &, mode_t ) ) );
4570  connect( child->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ),
4571  d->m_extension, TQT_SIGNAL( popupMenu( KXMLGUIClient *, const TQPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) );
4572 
4573  connect( child->m_extension, TQT_SIGNAL( infoMessage( const TQString & ) ),
4574  d->m_extension, TQT_SIGNAL( infoMessage( const TQString & ) ) );
4575 
4576  connect( child->m_extension, TQT_SIGNAL( requestFocus( KParts::ReadOnlyPart * ) ),
4577  this, TQT_SLOT( slotRequestFocus( KParts::ReadOnlyPart * ) ) );
4578 
4579  child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
4580  }
4581  }
4582  else if ( child->m_frame && child->m_part &&
4583  child->m_frame->widget() != child->m_part->widget() )
4584  child->m_frame->setWidget( child->m_part->widget() );
4585 
4586  checkEmitLoadEvent();
4587  // Some JS code in the load event may have destroyed the part
4588  // In that case, abort
4589  if ( !child->m_part )
4590  return false;
4591 
4592  if ( child->m_bPreloaded )
4593  {
4594  if ( child->m_frame && child->m_part )
4595  child->m_frame->setWidget( child->m_part->widget() );
4596 
4597  child->m_bPreloaded = false;
4598  return true;
4599  }
4600 
4601  child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
4602 
4603  // make sure the part has a way to find out about the mimetype.
4604  // we actually set it in child->m_args in requestObject already,
4605  // but it's useless if we had to use a KHTMLRun instance, as the
4606  // point the run object is to find out exactly the mimetype.
4607  child->m_args.serviceType = mimetype;
4608 
4609  // if not a frame set child as completed
4610  child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;
4611 
4612  if ( child->m_extension )
4613  child->m_extension->setURLArgs( child->m_args );
4614 
4615  if(url.protocol() == "javascript" || url.url() == "about:blank") {
4616  if (!child->m_part->inherits("KHTMLPart"))
4617  return false;
4618 
4619  KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
4620 
4621  p->begin();
4622  if (d->m_doc && p->d->m_doc)
4623  p->d->m_doc->setBaseURL(d->m_doc->baseURL());
4624  if (!url.url().startsWith("about:")) {
4625  p->write(url.path());
4626  } else {
4627  p->m_url = url;
4628  // we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
4629  p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
4630  }
4631  p->end();
4632  return true;
4633  }
4634  else if ( !url.isEmpty() )
4635  {
4636  //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
4637  bool b = child->m_part->openURL( url );
4638  if (child->m_bCompleted)
4639  checkCompleted();
4640  return b;
4641  }
4642  else
4643  {
4644  child->m_bCompleted = true;
4645  checkCompleted();
4646  return true;
4647  }
4648 }
4649 
4650 KParts::ReadOnlyPart *KHTMLPart::createPart( TQWidget *parentWidget, const char *widgetName,
4651  TQObject *parent, const char *name, const TQString &mimetype,
4652  TQString &serviceName, TQStringList &serviceTypes,
4653  const TQStringList &params )
4654 {
4655  TQString constr;
4656  if ( !serviceName.isEmpty() )
4657  constr.append( TQString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
4658 
4659  KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, TQString() );
4660 
4661  if ( offers.isEmpty() ) {
4662  int pos = mimetype.find( "-plugin" );
4663  if (pos < 0)
4664  return 0L;
4665  TQString stripped_mime = mimetype.left( pos );
4666  offers = KTrader::self()->query( stripped_mime, "KParts/ReadOnlyPart", constr, TQString() );
4667  if ( offers.isEmpty() )
4668  return 0L;
4669  }
4670 
4671  KTrader::OfferList::ConstIterator it = offers.begin();
4672  const KTrader::OfferList::ConstIterator itEnd = offers.end();
4673  for ( ; it != itEnd; ++it )
4674  {
4675  KService::Ptr service = (*it);
4676 
4677  KLibFactory* const factory = KLibLoader::self()->factory( TQFile::encodeName(service->library()) );
4678  if ( factory ) {
4679  KParts::ReadOnlyPart *res = 0L;
4680 
4681  const char *className = "KParts::ReadOnlyPart";
4682  if ( service->serviceTypes().contains( "Browser/View" ) )
4683  className = "Browser/View";
4684 
4685  if ( factory->inherits( "KParts::Factory" ) )
4686  res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
4687  else
4688  res = static_cast<KParts::ReadOnlyPart *>(factory->create( TQT_TQOBJECT(parentWidget), widgetName, className ));
4689 
4690  if ( res ) {
4691  serviceTypes = service->serviceTypes();
4692  serviceName = service->name();
4693  return res;
4694  }
4695  } else {
4696  // TODO KMessageBox::error and i18n, like in KonqFactory::createView?
4697  kdWarning() << TQString(TQString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
4698  .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage())) << endl;
4699  }
4700  }
4701  return 0;
4702 }
4703 
4704 KParts::PartManager *KHTMLPart::partManager()
4705 {
4706  if ( !d->m_manager && d->m_view )
4707  {
4708  d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
4709  d->m_manager->setAllowNestedParts( true );
4710  connect( d->m_manager, TQT_SIGNAL( activePartChanged( KParts::Part * ) ),
4711  this, TQT_SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
4712  connect( d->m_manager, TQT_SIGNAL( partRemoved( KParts::Part * ) ),
4713  this, TQT_SLOT( slotPartRemoved( KParts::Part * ) ) );
4714  }
4715 
4716  return d->m_manager;
4717 }
4718 
4719 void KHTMLPart::submitFormAgain()
4720 {
4721  disconnect(this, TQT_SIGNAL(completed()), this, TQT_SLOT(submitFormAgain()));
4722  if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
4723  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 );
4724 
4725  delete d->m_submitForm;
4726  d->m_submitForm = 0;
4727 }
4728 
4729 void KHTMLPart::submitFormProxy( const char *action, const TQString &url, const TQByteArray &formData, const TQString &_target, const TQString& contentType, const TQString& boundary )
4730 {
4731  submitForm(action, url, formData, _target, contentType, boundary);
4732 }
4733 
4734 void KHTMLPart::submitForm( const char *action, const TQString &url, const TQByteArray &formData, const TQString &_target, const TQString& contentType, const TQString& boundary )
4735 {
4736  kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
4737  if (d->m_formNotification == KHTMLPart::Only) {
4738  emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
4739  return;
4740  } else if (d->m_formNotification == KHTMLPart::Before) {
4741  emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
4742  }
4743 
4744  KURL u = completeURL( url );
4745 
4746  if ( !u.isValid() )
4747  {
4748  // ### ERROR HANDLING!
4749  return;
4750  }
4751 
4752  // Form security checks
4753  //
4754  /*
4755  * If these form security checks are still in this place in a month or two
4756  * I'm going to simply delete them.
4757  */
4758 
4759  /* This is separate for a reason. It has to be _before_ all script, etc,
4760  * AND I don't want to break anything that uses checkLinkSecurity() in
4761  * other places.
4762  */
4763 
4764  if (!d->m_submitForm) {
4765  if (u.protocol() != "https" && u.protocol() != "mailto") {
4766  if (d->m_ssl_in_use) { // Going from SSL -> nonSSL
4767  int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning: This is a secure form but it is attempting to send your data back unencrypted."
4768  "\nA third party may be able to intercept and view this information."
4769  "\nAre you sure you wish to continue?"),
4770  i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
4771  if (rc == KMessageBox::Cancel)
4772  return;
4773  } else { // Going from nonSSL -> nonSSL
4774  KSSLSettings kss(true);
4775  if (kss.warnOnUnencrypted()) {
4776  int rc = KMessageBox::warningContinueCancel(NULL,
4777  i18n("Warning: Your data is about to be transmitted across the network unencrypted."
4778  "\nAre you sure you wish to continue?"),
4779  i18n("Network Transmission"),
4780  KGuiItem(i18n("&Send Unencrypted")),
4781  "WarnOnUnencryptedForm");
4782  // Move this setting into KSSL instead
4783  KConfig *config = kapp->config();
4784  TQString grpNotifMsgs = TQString::fromLatin1("Notification Messages");
4785  KConfigGroupSaver saver( config, grpNotifMsgs );
4786 
4787  if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
4788  config->deleteEntry("WarnOnUnencryptedForm");
4789  config->sync();
4790  kss.setWarnOnUnencrypted(false);
4791  kss.save();
4792  }
4793  if (rc == KMessageBox::Cancel)
4794  return;
4795  }
4796  }
4797  }
4798 
4799  if (u.protocol() == "mailto") {
4800  int rc = KMessageBox::warningContinueCancel(NULL,
4801  i18n("This site is attempting to submit form data via email.\n"
4802  "Do you want to continue?"),
4803  i18n("Network Transmission"),
4804  KGuiItem(i18n("&Send Email")),
4805  "WarnTriedEmailSubmit");
4806 
4807  if (rc == KMessageBox::Cancel) {
4808  return;
4809  }
4810  }
4811  }
4812 
4813  // End form security checks
4814  //
4815 
4816  TQString urlstring = u.url();
4817 
4818  if ( urlstring.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
4819  urlstring = KURL::decode_string(urlstring);
4820  crossFrameExecuteScript( _target, urlstring.right( urlstring.length() - 11) );
4821  return;
4822  }
4823 
4824  if (!checkLinkSecurity(u,
4825  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?" ),
4826  i18n( "Submit" )))
4827  return;
4828 
4829  KParts::URLArgs args;
4830 
4831  if (!d->m_referrer.isEmpty())
4832  args.metaData()["referrer"] = d->m_referrer;
4833 
4834  args.metaData().insert("PropagateHttpHeader", "true");
4835  args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
4836  args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
4837  args.metaData().insert("main_frame_request",
4838  parentPart() == 0 ? "TRUE":"FALSE");
4839  args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
4840  args.metaData().insert("ssl_activate_warnings", "TRUE");
4841 //WABA: When we post a form we should treat it as the main url
4842 //the request should never be considered cross-domain
4843 //args.metaData().insert("cross-domain", toplevelURL().url());
4844  args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
4845 
4846  // Handle mailto: forms
4847  if (u.protocol() == "mailto") {
4848  // 1) Check for attach= and strip it
4849  TQString q = u.query().mid(1);
4850  TQStringList nvps = TQStringList::split("&", q);
4851  bool triedToAttach = false;
4852 
4853  TQStringList::Iterator nvp = nvps.begin();
4854  const TQStringList::Iterator nvpEnd = nvps.end();
4855 
4856 // cannot be a for loop as if something is removed we don't want to do ++nvp, as
4857 // remove returns an iterator pointing to the next item
4858 
4859  while (nvp != nvpEnd) {
4860  const TQStringList pair = TQStringList::split("=", *nvp);
4861  if (pair.count() >= 2) {
4862  if (pair.first().lower() == "attach") {
4863  nvp = nvps.remove(nvp);
4864  triedToAttach = true;
4865  } else {
4866  ++nvp;
4867  }
4868  } else {
4869  ++nvp;
4870  }
4871  }
4872 
4873  if (triedToAttach)
4874  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");
4875 
4876  // 2) Append body=
4877  TQString bodyEnc;
4878  if (contentType.lower() == "multipart/form-data") {
4879  // FIXME: is this correct? I suspect not
4880  bodyEnc = KURL::encode_string(TQString::fromLatin1(formData.data(),
4881  formData.size()));
4882  } else if (contentType.lower() == "text/plain") {
4883  // Convention seems to be to decode, and s/&/\n/
4884  TQString tmpbody = TQString::fromLatin1(formData.data(),
4885  formData.size());
4886  tmpbody.replace(TQRegExp("[&]"), "\n");
4887  tmpbody.replace(TQRegExp("[+]"), " ");
4888  tmpbody = KURL::decode_string(tmpbody); // Decode the rest of it
4889  bodyEnc = KURL::encode_string(tmpbody); // Recode for the URL
4890  } else {
4891  bodyEnc = KURL::encode_string(TQString::fromLatin1(formData.data(),
4892  formData.size()));
4893  }
4894 
4895  nvps.append(TQString("body=%1").arg(bodyEnc));
4896  q = nvps.join("&");
4897  u.setQuery(q);
4898  }
4899 
4900  if ( strcmp( action, "get" ) == 0 ) {
4901  if (u.protocol() != "mailto")
4902  u.setQuery( TQString::fromLatin1( formData.data(), formData.size() ) );
4903  args.setDoPost( false );
4904  }
4905  else {
4906  args.postData = formData;
4907  args.setDoPost( true );
4908 
4909  // construct some user headers if necessary
4910  if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
4911  args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
4912  else // contentType must be "multipart/form-data"
4913  args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
4914  }
4915 
4916  if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
4917  if( d->m_submitForm ) {
4918  kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
4919  return;
4920  }
4921  d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
4922  d->m_submitForm->submitAction = action;
4923  d->m_submitForm->submitUrl = url;
4924  d->m_submitForm->submitFormData = formData;
4925  d->m_submitForm->target = _target;
4926  d->m_submitForm->submitContentType = contentType;
4927  d->m_submitForm->submitBoundary = boundary;
4928  connect(this, TQT_SIGNAL(completed()), this, TQT_SLOT(submitFormAgain()));
4929  }
4930  else
4931  {
4932  emit d->m_extension->openURLRequest( u, args );
4933  }
4934 }
4935 
4936 void KHTMLPart::popupMenu( const TQString &linkUrl )
4937 {
4938  KURL popupURL;
4939  KURL linkKURL;
4940  KParts::URLArgs args;
4941  TQString referrer;
4942  KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;
4943 
4944  if ( linkUrl.isEmpty() ) { // click on background
4945  KHTMLPart* khtmlPart = this;
4946  while ( khtmlPart->parentPart() )
4947  {
4948  khtmlPart=khtmlPart->parentPart();
4949  }
4950  popupURL = khtmlPart->url();
4951  referrer = khtmlPart->pageReferrer();
4952  if (hasSelection())
4953  itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
4954  else
4955  itemflags |= KParts::BrowserExtension::ShowNavigationItems;
4956  } else { // click on link
4957  popupURL = completeURL( linkUrl );
4958  linkKURL = popupURL;
4959  referrer = this->referrer();
4960 
4961  if (!(d->m_strSelectedURLTarget).isEmpty() &&
4962  (d->m_strSelectedURLTarget.lower() != "_top") &&
4963  (d->m_strSelectedURLTarget.lower() != "_self") &&
4964  (d->m_strSelectedURLTarget.lower() != "_parent")) {
4965  if (d->m_strSelectedURLTarget.lower() == "_blank")
4966  args.setForcesNewWindow(true);
4967  else {
4968  KHTMLPart *p = this;
4969  while (p->parentPart())
4970  p = p->parentPart();
4971  if (!p->frameExists(d->m_strSelectedURLTarget))
4972  args.setForcesNewWindow(true);
4973  }
4974  }
4975  }
4976 
4977  // Danger, Will Robinson. The Popup might stay around for a much
4978  // longer time than KHTMLPart. Deal with it.
4979  KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
4980  TQGuardedPtr<TQObject> guard( client );
4981 
4982  TQString mimetype = TQString::fromLatin1( "text/html" );
4983  args.metaData()["referrer"] = referrer;
4984 
4985  if (!linkUrl.isEmpty()) // over a link
4986  {
4987  if (popupURL.isLocalFile()) // safe to do this
4988  {
4989  mimetype = KMimeType::findByURL(popupURL,0,true,false)->name();
4990  }
4991  else // look at "extension" of link
4992  {
4993  const TQString fname(popupURL.fileName(false));
4994  if (!fname.isEmpty() && !popupURL.hasRef() && popupURL.query().isEmpty())
4995  {
4996  KMimeType::Ptr pmt = KMimeType::findByPath(fname,0,true);
4997 
4998  // Further check for mime types guessed from the extension which,
4999  // on a web page, are more likely to be a script delivering content
5000  // of undecidable type. If the mime type from the extension is one
5001  // of these, don't use it. Retain the original type 'text/html'.
5002  if (pmt->name() != KMimeType::defaultMimeType() &&
5003  !pmt->is("application/x-perl") &&
5004  !pmt->is("application/x-perl-module") &&
5005  !pmt->is("application/x-php") &&
5006  !pmt->is("application/x-python-bytecode") &&
5007  !pmt->is("application/x-python") &&
5008  !pmt->is("application/x-shellscript"))
5009  mimetype = pmt->name();
5010  }
5011  }
5012  }
5013 
5014  args.serviceType = mimetype;
5015 
5016  emit d->m_extension->popupMenu( client, TQCursor::pos(), popupURL, args, itemflags, S_IFREG /*always a file*/);
5017 
5018  if ( !guard.isNull() ) {
5019  delete client;
5020  emit popupMenu(linkUrl, TQCursor::pos());
5021  d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
5022  }
5023 }
5024 
5025 void KHTMLPart::slotParentCompleted()
5026 {
5027  //kdDebug(6050) << this << " slotParentCompleted()" << endl;
5028  if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
5029  {
5030  //kdDebug(6050) << this << ": starting timer for child redirection -> " << d->m_redirectURL << endl;
5031  d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
5032  }
5033 }
5034 
5035 void KHTMLPart::slotChildStarted( KIO::Job *job )
5036 {
5037  khtml::ChildFrame *child = frame( TQT_TQOBJECT_CONST(sender()) );
5038 
5039  assert( child );
5040 
5041  child->m_bCompleted = false;
5042 
5043  if ( d->m_bComplete )
5044  {
5045 #if 0
5046  // WABA: Looks like this belongs somewhere else
5047  if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
5048  {
5049  emit d->m_extension->openURLNotify();
5050  }
5051 #endif
5052  d->m_bComplete = false;
5053  emit started( job );
5054  }
5055 }
5056 
5057 void KHTMLPart::slotChildCompleted()
5058 {
5059  slotChildCompleted( false );
5060 }
5061 
5062 void KHTMLPart::slotChildCompleted( bool pendingAction )
5063 {
5064  khtml::ChildFrame *child = frame( TQT_TQOBJECT_CONST(sender()) );
5065 
5066  if ( child ) {
5067  kdDebug(6050) << this << " slotChildCompleted child=" << child << " m_frame=" << child->m_frame << endl;
5068  child->m_bCompleted = true;
5069  child->m_bPendingRedirection = pendingAction;
5070  child->m_args = KParts::URLArgs();
5071  }
5072  checkCompleted();
5073 }
5074 
5075 void KHTMLPart::slotChildDocCreated()
5076 {
5077  const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
5078  // Set domain to the frameset's domain
5079  // This must only be done when loading the frameset initially (#22039),
5080  // not when following a link in a frame (#44162).
5081  if ( d->m_doc && d->m_doc->isHTMLDocument() )
5082  {
5083  if ( sender()->inherits("KHTMLPart") )
5084  {
5085  DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
5086  if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
5087  //kdDebug(6050) << "KHTMLPart::slotChildDocCreated: url: " << htmlFrame->m_url.url() << endl;
5088  static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
5089  }
5090  }
5091  // So it only happens once
5092  disconnect( htmlFrame, TQT_SIGNAL( docCreated() ), this, TQT_SLOT( slotChildDocCreated() ) );
5093 }
5094 
5095 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
5096 {
5097  khtml::ChildFrame *child = frame( TQT_TQOBJECT_CONST(sender())->parent() );
5098  KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
5099 
5100  // TODO: handle child target correctly! currently the script are always executed fur the parent
5101  TQString urlStr = url.url();
5102  if ( urlStr.find( TQString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
5103  TQString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
5104  executeScript( DOM::Node(), script );
5105  return;
5106  }
5107 
5108  TQString frameName = args.frameName.lower();
5109  if ( !frameName.isEmpty() ) {
5110  if ( frameName == TQString::fromLatin1( "_top" ) )
5111  {
5112  emit d->m_extension->openURLRequest( url, args );
5113  return;
5114  }
5115  else if ( frameName == TQString::fromLatin1( "_blank" ) )
5116  {
5117  emit d->m_extension->createNewWindow( url, args );
5118  return;
5119  }
5120  else if ( frameName == TQString::fromLatin1( "_parent" ) )
5121  {
5122  KParts::URLArgs newArgs( args );
5123  newArgs.frameName = TQString();
5124 
5125  emit d->m_extension->openURLRequest( url, newArgs );
5126  return;
5127  }
5128  else if ( frameName != TQString::fromLatin1( "_self" ) )
5129  {
5130  khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
5131 
5132  if ( !_frame )
5133  {
5134  emit d->m_extension->openURLRequest( url, args );
5135  return;
5136  }
5137 
5138  child = _frame;
5139  }
5140  }
5141 
5142  if ( child && child->m_type != khtml::ChildFrame::Object ) {
5143  // Inform someone that we are about to show something else.
5144  child->m_bNotify = true;
5145  requestObject( child, url, args );
5146  } else if ( frameName== "_self" ) // this is for embedded objects (via <object>) which want to replace the current document
5147  {
5148  KParts::URLArgs newArgs( args );
5149  newArgs.frameName = TQString();
5150  emit d->m_extension->openURLRequest( url, newArgs );
5151  }
5152 }
5153 
5154 void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
5155 {
5156  emit d->m_extension->requestFocus(this);
5157 }
5158 
5159 khtml::ChildFrame *KHTMLPart::frame( const TQObject *obj )
5160 {
5161  assert( obj->inherits( "KParts::ReadOnlyPart" ) );
5162  const KParts::ReadOnlyPart* const part = static_cast<const KParts::ReadOnlyPart *>( obj );
5163 
5164  FrameIt it = d->m_frames.begin();
5165  const FrameIt end = d->m_frames.end();
5166  for (; it != end; ++it )
5167  if ( (KParts::ReadOnlyPart *)(*it)->m_part == part )
5168  return *it;
5169 
5170  FrameIt oi = d->m_objects.begin();
5171  const FrameIt oiEnd = d->m_objects.end();
5172  for (; oi != oiEnd; ++oi )
5173  if ( (KParts::ReadOnlyPart *)(*oi)->m_part == part )
5174  return *oi;
5175 
5176  return 0L;
5177 }
5178 
5179 //#define DEBUG_FINDFRAME
5180 
5181 bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
5182 {
5183  if (callingHtmlPart == this)
5184  return true; // trivial
5185 
5186  if (htmlDocument().isNull()) {
5187 #ifdef DEBUG_FINDFRAME
5188  kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
5189 #endif
5190  return false; // we are empty?
5191  }
5192 
5193  // now compare the domains
5194  if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
5195  !htmlDocument().isNull()) {
5196  DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
5197  DOM::DOMString destDomain = htmlDocument().domain();
5198 
5199 #ifdef DEBUG_FINDFRAME
5200  kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
5201 #endif
5202 
5203  if (actDomain == destDomain)
5204  return true;
5205  }
5206 #ifdef DEBUG_FINDFRAME
5207  else
5208  {
5209  kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
5210  }
5211 #endif
5212  return false;
5213 }
5214 
5215 KHTMLPart *
5216 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const TQString &f, khtml::ChildFrame **childFrame )
5217 {
5218 #ifdef DEBUG_FINDFRAME
5219  kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " name = " << name() << " findFrameParent( " << f << " )" << endl;
5220 #endif
5221  // Check access
5222  KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
5223 
5224  if (!checkFrameAccess(callingHtmlPart))
5225  return 0;
5226 
5227  // match encoding used in KonqView::setViewName()
5228  if (!childFrame && !parentPart() && (TQString::fromLocal8Bit(name()) == f))
5229  return this;
5230 
5231  FrameIt it = d->m_frames.find( f );
5232  const FrameIt end = d->m_frames.end();
5233  if ( it != end )
5234  {
5235 #ifdef DEBUG_FINDFRAME
5236  kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
5237 #endif
5238  if (childFrame)
5239  *childFrame = *it;
5240  return this;
5241  }
5242 
5243  it = d->m_frames.begin();
5244  for (; it != end; ++it )
5245  {
5246  KParts::ReadOnlyPart* const p = (*it)->m_part;
5247  if ( p && p->inherits( "KHTMLPart" ))
5248  {
5249  KHTMLPart* const frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
5250  if (frameParent)
5251  return frameParent;
5252  }
5253  }
5254  return 0;
5255 }
5256 
5257 
5258 KHTMLPart *KHTMLPart::findFrame( const TQString &f )
5259 {
5260  khtml::ChildFrame *childFrame;
5261  KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
5262  if (parentFrame)
5263  {
5264  KParts::ReadOnlyPart *p = childFrame->m_part;
5265  if ( p && p->inherits( "KHTMLPart" ))
5266  return static_cast<KHTMLPart *>(p);
5267  }
5268  return 0;
5269 }
5270 
5271 KParts::ReadOnlyPart *KHTMLPart::findFramePart(const TQString &f)
5272 {
5273  khtml::ChildFrame *childFrame;
5274  return findFrameParent(this, f, &childFrame) ? static_cast<KParts::ReadOnlyPart *>(childFrame->m_part) : 0L;
5275 }
5276 
5277 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
5278 {
5279  KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
5280  // Find active part in our frame manager, in case we are a frameset
5281  // and keep doing that (in case of nested framesets).
5282  // Just realized we could also do this recursively, calling part->currentFrame()...
5283  while ( part && part->inherits("KHTMLPart") &&
5284  static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
5285  KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
5286  part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
5287  if ( !part ) return frameset;
5288  }
5289  return part;
5290 }
5291 
5292 bool KHTMLPart::frameExists( const TQString &frameName )
5293 {
5294  ConstFrameIt it = d->m_frames.find( frameName );
5295  if ( it == d->m_frames.end() )
5296  return false;
5297 
5298  // WABA: We only return true if the child actually has a frame
5299  // set. Otherwise we might find our preloaded-selve.
5300  // This happens when we restore the frameset.
5301  return (!(*it)->m_frame.isNull());
5302 }
5303 
5304 KJSProxy *KHTMLPart::framejScript(KParts::ReadOnlyPart *framePart)
5305 {
5306  KHTMLPart* const kp = ::tqqt_cast<KHTMLPart*>(framePart);
5307  if (kp)
5308  return kp->jScript();
5309 
5310  FrameIt it = d->m_frames.begin();
5311  const FrameIt itEnd = d->m_frames.end();
5312 
5313  for (; it != itEnd; ++it)
5314  if (framePart == (*it)->m_part) {
5315  if (!(*it)->m_jscript)
5316  createJScript(*it);
5317  return (*it)->m_jscript;
5318  }
5319  return 0L;
5320 }
5321 
5322 KHTMLPart *KHTMLPart::parentPart()
5323 {
5324  return ::tqqt_cast<KHTMLPart *>( parent() );
5325 }
5326 
5327 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
5328  const KParts::URLArgs &args, bool callParent )
5329 {
5330 #ifdef DEBUG_FINDFRAME
5331  kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
5332 #endif
5333  khtml::ChildFrame *childFrame;
5334  KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
5335  if (childPart)
5336  {
5337  if (childPart == this)
5338  return childFrame;
5339 
5340  childPart->requestObject( childFrame, url, args );
5341  return 0;
5342  }
5343 
5344  if ( parentPart() && callParent )
5345  {
5346  khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
5347 
5348  if ( res )
5349  parentPart()->requestObject( res, url, args );
5350  }
5351 
5352  return 0L;
5353 }
5354 
5355 #ifndef NDEBUG
5356 static int s_saveStateIndentLevel = 0;
5357 #endif
5358 
5359 void KHTMLPart::saveState( TQDataStream &stream )
5360 {
5361 #ifndef NDEBUG
5362  TQString indent = TQString().leftJustify( s_saveStateIndentLevel * 4, ' ' );
5363  const int indentLevel = s_saveStateIndentLevel++;
5364  kdDebug( 6050 ) << indent << "saveState this=" << this << " '" << name() << "' saving URL " << m_url.url() << endl;
5365 #endif
5366 
5367  stream << m_url << (TQ_INT32)d->m_view->contentsX() << (TQ_INT32)d->m_view->contentsY()
5368  << (TQ_INT32) d->m_view->contentsWidth() << (TQ_INT32) d->m_view->contentsHeight() << (TQ_INT32) d->m_view->marginWidth() << (TQ_INT32) d->m_view->marginHeight();
5369 
5370  // save link cursor position
5371  int focusNodeNumber;
5372  if (!d->m_focusNodeRestored)
5373  focusNodeNumber = d->m_focusNodeNumber;
5374  else if (d->m_doc && d->m_doc->focusNode())
5375  focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
5376  else
5377  focusNodeNumber = -1;
5378  stream << focusNodeNumber;
5379 
5380  // Save the doc's cache id.
5381  stream << d->m_cacheId;
5382 
5383  // Save the state of the document (Most notably the state of any forms)
5384  TQStringList docState;
5385  if (d->m_doc)
5386  {
5387  docState = d->m_doc->docState();
5388  }
5389  stream << d->m_encoding << d->m_sheetUsed << docState;
5390 
5391  stream << d->m_zoomFactor;
5392 
5393  stream << d->m_httpHeaders;
5394  stream << d->m_pageServices;
5395  stream << d->m_pageReferrer;
5396 
5397  // Save ssl data
5398  stream << d->m_ssl_in_use
5399  << d->m_ssl_peer_certificate
5400  << d->m_ssl_peer_chain
5401  << d->m_ssl_peer_ip
5402  << d->m_ssl_cipher
5403  << d->m_ssl_cipher_desc
5404  << d->m_ssl_cipher_version
5405  << d->m_ssl_cipher_used_bits
5406  << d->m_ssl_cipher_bits
5407  << d->m_ssl_cert_state
5408  << d->m_ssl_parent_ip
5409  << d->m_ssl_parent_cert;
5410 
5411 
5412  TQStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
5413  KURL::List frameURLLst;
5414  TQValueList<TQByteArray> frameStateBufferLst;
5415 
5416  ConstFrameIt it = d->m_frames.begin();
5417  const ConstFrameIt end = d->m_frames.end();
5418  for (; it != end; ++it )
5419  {
5420  if ( !(*it)->m_part )
5421  continue;
5422 
5423  frameNameLst << (*it)->m_name;
5424  frameServiceTypeLst << (*it)->m_serviceType;
5425  frameServiceNameLst << (*it)->m_serviceName;
5426  frameURLLst << (*it)->m_part->url();
5427 
5428  TQByteArray state;
5429  TQDataStream frameStream( state, IO_WriteOnly );
5430 
5431  if ( (*it)->m_extension )
5432  (*it)->m_extension->saveState( frameStream );
5433 
5434  frameStateBufferLst << state;
5435  }
5436 
5437  // Save frame data
5438  stream << (TQ_UINT32) frameNameLst.count();
5439  stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
5440 #ifndef NDEBUG
5441  s_saveStateIndentLevel = indentLevel;
5442 #endif
5443 }
5444 
5445 void KHTMLPart::restoreState( TQDataStream &stream )
5446 {
5447  KURL u;
5448  TQ_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
5449  TQ_UINT32 frameCount;
5450  TQStringList frameNames, frameServiceTypes, docState, frameServiceNames;
5451  KURL::List frameURLs;
5452  TQValueList<TQByteArray> frameStateBuffers;
5453  TQValueList<int> fSizes;
5454  TQString encoding, sheetUsed;
5455  long old_cacheId = d->m_cacheId;
5456 
5457  stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
5458 
5459  d->m_view->setMarginWidth( mWidth );
5460  d->m_view->setMarginHeight( mHeight );
5461 
5462  // restore link cursor position
5463  // nth node is active. value is set in checkCompleted()
5464  stream >> d->m_focusNodeNumber;
5465  d->m_focusNodeRestored = false;
5466 
5467  stream >> d->m_cacheId;
5468 
5469  stream >> encoding >> sheetUsed >> docState;
5470 
5471  d->m_encoding = encoding;
5472  d->m_sheetUsed = sheetUsed;
5473 
5474  int zoomFactor;
5475  stream >> zoomFactor;
5476  setZoomFactor(zoomFactor);
5477 
5478  stream >> d->m_httpHeaders;
5479  stream >> d->m_pageServices;
5480  stream >> d->m_pageReferrer;
5481 
5482  // Restore ssl data
5483  stream >> d->m_ssl_in_use
5484  >> d->m_ssl_peer_certificate
5485  >> d->m_ssl_peer_chain
5486  >> d->m_ssl_peer_ip
5487  >> d->m_ssl_cipher
5488  >> d->m_ssl_cipher_desc
5489  >> d->m_ssl_cipher_version
5490  >> d->m_ssl_cipher_used_bits
5491  >> d->m_ssl_cipher_bits
5492  >> d->m_ssl_cert_state
5493  >> d->m_ssl_parent_ip
5494  >> d->m_ssl_parent_cert;
5495 
5496  setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
5497 
5498  stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
5499  >> frameURLs >> frameStateBuffers;
5500 
5501  d->m_bComplete = false;
5502  d->m_bLoadEventEmitted = false;
5503 
5504 // kdDebug( 6050 ) << "restoreState() docState.count() = " << docState.count() << endl;
5505 // kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
5506 // kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
5507 
5508  if (d->m_cacheId == old_cacheId)
5509  {
5510  // Partial restore
5511  d->m_redirectionTimer.stop();
5512 
5513  FrameIt fIt = d->m_frames.begin();
5514  const FrameIt fEnd = d->m_frames.end();
5515 
5516  for (; fIt != fEnd; ++fIt )
5517  (*fIt)->m_bCompleted = false;
5518 
5519  fIt = d->m_frames.begin();
5520 
5521  TQStringList::ConstIterator fNameIt = frameNames.begin();
5522  TQStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
5523  TQStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
5524  KURL::List::ConstIterator fURLIt = frameURLs.begin();
5525  TQValueList<TQByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
5526 
5527  for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
5528  {
5529  khtml::ChildFrame* const child = *fIt;
5530 
5531 // kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
5532 
5533  if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
5534  {
5535  child->m_bPreloaded = true;
5536  child->m_name = *fNameIt;
5537  child->m_serviceName = *fServiceNameIt;
5538  processObjectRequest( child, *fURLIt, *fServiceTypeIt );
5539  }
5540  if ( child->m_part )
5541  {
5542  child->m_bCompleted = false;
5543  if ( child->m_extension && !(*fBufferIt).isEmpty() )
5544  {
5545  TQDataStream frameStream( *fBufferIt, IO_ReadOnly );
5546  child->m_extension->restoreState( frameStream );
5547  }
5548  else
5549  child->m_part->openURL( *fURLIt );
5550  }
5551  }
5552 
5553  KParts::URLArgs args( d->m_extension->urlArgs() );
5554  args.xOffset = xOffset;
5555  args.yOffset = yOffset;
5556  args.docState = docState;
5557  d->m_extension->setURLArgs( args );
5558 
5559  d->m_view->resizeContents( wContents, hContents);
5560  d->m_view->setContentsPos( xOffset, yOffset );
5561 
5562  m_url = u;
5563  }
5564  else
5565  {
5566  // Full restore.
5567  closeURL();
5568  // We must force a clear because we want to be sure to delete all
5569  // frames.
5570  d->m_bCleared = false;
5571  clear();
5572  d->m_encoding = encoding;
5573  d->m_sheetUsed = sheetUsed;
5574 
5575  TQStringList::ConstIterator fNameIt = frameNames.begin();
5576  const TQStringList::ConstIterator fNameEnd = frameNames.end();
5577 
5578  TQStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
5579  TQStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
5580  KURL::List::ConstIterator fURLIt = frameURLs.begin();
5581  TQValueList<TQByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
5582 
5583  for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
5584  {
5585  khtml::ChildFrame* const newChild = new khtml::ChildFrame;
5586  newChild->m_bPreloaded = true;
5587  newChild->m_name = *fNameIt;
5588  newChild->m_serviceName = *fServiceNameIt;
5589 
5590 // kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
5591 
5592  const FrameIt childFrame = d->m_frames.append( newChild );
5593 
5594  processObjectRequest( *childFrame, *fURLIt, *fServiceTypeIt );
5595 
5596  (*childFrame)->m_bPreloaded = true;
5597 
5598  if ( (*childFrame)->m_part )
5599  {
5600  if ( (*childFrame)->m_extension ) {
5601  if ( (*childFrame)->m_extension && !(*fBufferIt).isEmpty() )
5602  {
5603  TQDataStream frameStream( *fBufferIt, IO_ReadOnly );
5604  (*childFrame)->m_extension->restoreState( frameStream );
5605  }
5606  else {
5607  (*childFrame)->m_part->openURL( *fURLIt );
5608  }
5609  }
5610  }
5611  }
5612 
5613  KParts::URLArgs args( d->m_extension->urlArgs() );
5614  args.xOffset = xOffset;
5615  args.yOffset = yOffset;
5616  args.docState = docState;
5617 
5618  d->m_extension->setURLArgs( args );
5619  if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
5620  {
5621  d->m_restored = true;
5622  openURL( u );
5623  d->m_restored = false;
5624  }
5625  else
5626  {
5627  restoreURL( u );
5628  }
5629  }
5630 
5631 }
5632 
5633 void KHTMLPart::show()
5634 {
5635  if ( d->m_view )
5636  d->m_view->show();
5637 }
5638 
5639 void KHTMLPart::hide()
5640 {
5641  if ( d->m_view )
5642  d->m_view->hide();
5643 }
5644 
5645 DOM::Node KHTMLPart::nodeUnderMouse() const
5646 {
5647  return d->m_view->nodeUnderMouse();
5648 }
5649 
5650 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
5651 {
5652  return d->m_view->nonSharedNodeUnderMouse();
5653 }
5654 
5655 void KHTMLPart::emitSelectionChanged()
5656 {
5657  emit d->m_extension->enableAction( "copy", hasSelection() );
5658  if ( d->m_findDialog )
5659  d->m_findDialog->setHasSelection( hasSelection() );
5660 
5661  emit d->m_extension->selectionInfo( selectedText() );
5662  emit selectionChanged();
5663 }
5664 
5665 int KHTMLPart::zoomFactor() const
5666 {
5667  return d->m_zoomFactor;
5668 }
5669 
5670 // ### make the list configurable ?
5671 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
5672 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
5673 static const int minZoom = 20;
5674 static const int maxZoom = 300;
5675 
5676 // My idea of useful stepping ;-) (LS)
5677 extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
5678 extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
5679 
5680 void KHTMLPart::slotIncZoom()
5681 {
5682  zoomIn(zoomSizes, zoomSizeCount);
5683 }
5684 
5685 void KHTMLPart::slotDecZoom()
5686 {
5687  zoomOut(zoomSizes, zoomSizeCount);
5688 }
5689 
5690 void KHTMLPart::slotIncZoomFast()
5691 {
5692  zoomIn(fastZoomSizes, fastZoomSizeCount);
5693 }
5694 
5695 void KHTMLPart::slotDecZoomFast()
5696 {
5697  zoomOut(fastZoomSizes, fastZoomSizeCount);
5698 }
5699 
5700 void KHTMLPart::zoomIn(const int stepping[], int count)
5701 {
5702  int zoomFactor = d->m_zoomFactor;
5703 
5704  if (zoomFactor < maxZoom) {
5705  // find the entry nearest to the given zoomsizes
5706  for (int i = 0; i < count; ++i)
5707  if (stepping[i] > zoomFactor) {
5708  zoomFactor = stepping[i];
5709  break;
5710  }
5711  setZoomFactor(zoomFactor);
5712  }
5713 }
5714 
5715 void KHTMLPart::zoomOut(const int stepping[], int count)
5716 {
5717  int zoomFactor = d->m_zoomFactor;
5718  if (zoomFactor > minZoom) {
5719  // find the entry nearest to the given zoomsizes
5720  for (int i = count-1; i >= 0; --i)
5721  if (stepping[i] < zoomFactor) {
5722  zoomFactor = stepping[i];
5723  break;
5724  }
5725  setZoomFactor(zoomFactor);
5726  }
5727 }
5728 
5729 void KHTMLPart::setZoomFactor (int percent)
5730 {
5731  if (percent < minZoom) percent = minZoom;
5732  if (percent > maxZoom) percent = maxZoom;
5733  if (d->m_zoomFactor == percent) return;
5734  d->m_zoomFactor = percent;
5735 
5736  if(d->m_doc) {
5737  TQApplication::setOverrideCursor( tqwaitCursor );
5738  if (d->m_doc->styleSelector())
5739  d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
5740  d->m_doc->recalcStyle( NodeImpl::Force );
5741  TQApplication::restoreOverrideCursor();
5742  }
5743 
5744  ConstFrameIt it = d->m_frames.begin();
5745  const ConstFrameIt end = d->m_frames.end();
5746  for (; it != end; ++it )
5747  if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
5748  KParts::ReadOnlyPart* const p = ( *it )->m_part;
5749  static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
5750  }
5751 
5752  if ( d->m_guiProfile == BrowserViewGUI ) {
5753  d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
5754  d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
5755  }
5756 }
5757 
5758 void KHTMLPart::slotZoomView( int delta )
5759 {
5760  if ( delta < 0 )
5761  slotIncZoom();
5762  else
5763  slotDecZoom();
5764 }
5765 
5766 void KHTMLPart::setStatusBarText( const TQString& text, StatusBarPriority p)
5767 {
5768  if (!d->m_statusMessagesEnabled)
5769  return;
5770 
5771  d->m_statusBarText[p] = text;
5772 
5773  // shift handling ?
5774  TQString tobe = d->m_statusBarText[BarHoverText];
5775  if (tobe.isEmpty())
5776  tobe = d->m_statusBarText[BarOverrideText];
5777  if (tobe.isEmpty()) {
5778  tobe = d->m_statusBarText[BarDefaultText];
5779  if (!tobe.isEmpty() && d->m_jobspeed)
5780  tobe += " ";
5781  if (d->m_jobspeed)
5782  tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
5783  }
5784  tobe = "<qt>"+tobe;
5785 
5786  emit ReadOnlyPart::setStatusBarText(tobe);
5787 }
5788 
5789 
5790 void KHTMLPart::setJSStatusBarText( const TQString &text )
5791 {
5792  setStatusBarText(text, BarOverrideText);
5793 }
5794 
5795 void KHTMLPart::setJSDefaultStatusBarText( const TQString &text )
5796 {
5797  setStatusBarText(text, BarDefaultText);
5798 }
5799 
5800 TQString KHTMLPart::jsStatusBarText() const
5801 {
5802  return d->m_statusBarText[BarOverrideText];
5803 }
5804 
5805 TQString KHTMLPart::jsDefaultStatusBarText() const
5806 {
5807  return d->m_statusBarText[BarDefaultText];
5808 }
5809 
5810 TQString KHTMLPart::referrer() const
5811 {
5812  return d->m_referrer;
5813 }
5814 
5815 TQString KHTMLPart::pageReferrer() const
5816 {
5817  KURL referrerURL = KURL( d->m_pageReferrer );
5818  if (referrerURL.isValid())
5819  {
5820  TQString protocol = referrerURL.protocol();
5821 
5822  if ((protocol == "http") ||
5823  ((protocol == "https") && (m_url.protocol() == "https")))
5824  {
5825  referrerURL.setRef(TQString());
5826  referrerURL.setUser(TQString());
5827  referrerURL.setPass(TQString());
5828  return referrerURL.url();
5829  }
5830  }
5831 
5832  return TQString();
5833 }
5834 
5835 
5836 TQString KHTMLPart::lastModified() const
5837 {
5838  if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
5839  // Local file: set last-modified from the file's mtime.
5840  // Done on demand to save time when this isn't needed - but can lead
5841  // to slightly wrong results if updating the file on disk w/o reloading.
5842  TQDateTime lastModif = TQFileInfo( m_url.path() ).lastModified();
5843  d->m_lastModified = lastModif.toString( Qt::LocalDate );
5844  }
5845  //kdDebug(6050) << "KHTMLPart::lastModified: " << d->m_lastModified << endl;
5846  return d->m_lastModified;
5847 }
5848 
5849 void KHTMLPart::slotLoadImages()
5850 {
5851  if (d->m_doc )
5852  d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
5853 
5854  ConstFrameIt it = d->m_frames.begin();
5855  const ConstFrameIt end = d->m_frames.end();
5856  for (; it != end; ++it )
5857  if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
5858  KParts::ReadOnlyPart* const p = ( *it )->m_part;
5859  static_cast<KHTMLPart*>( p )->slotLoadImages();
5860  }
5861 }
5862 
5863 void KHTMLPart::reparseConfiguration()
5864 {
5865  KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
5866  settings->init();
5867 
5868  setAutoloadImages( settings->autoLoadImages() );
5869  if (d->m_doc)
5870  d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
5871 
5872  d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
5873  d->m_bBackRightClick = settings->isBackRightClickEnabled();
5874  d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
5875  setDebugScript( settings->isJavaScriptDebugEnabled() );
5876  d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
5877  d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
5878  d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
5879 
5880  delete d->m_settings;
5881  d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
5882 
5883  TQApplication::setOverrideCursor( tqwaitCursor );
5884  khtml::CSSStyleSelector::reparseConfiguration();
5885  if(d->m_doc) d->m_doc->updateStyleSelector();
5886  TQApplication::restoreOverrideCursor();
5887 
5888  if (KHTMLFactory::defaultHTMLSettings()->isAdFilterEnabled())
5889  runAdFilter();
5890 }
5891 
5892 TQStringList KHTMLPart::frameNames() const
5893 {
5894  TQStringList res;
5895 
5896  ConstFrameIt it = d->m_frames.begin();
5897  const ConstFrameIt end = d->m_frames.end();
5898  for (; it != end; ++it )
5899  if (!(*it)->m_bPreloaded)
5900  res += (*it)->m_name;
5901 
5902  return res;
5903 }
5904 
5905 TQPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
5906 {
5907  TQPtrList<KParts::ReadOnlyPart> res;
5908 
5909  ConstFrameIt it = d->m_frames.begin();
5910  const ConstFrameIt end = d->m_frames.end();
5911  for (; it != end; ++it )
5912  if (!(*it)->m_bPreloaded)
5913  res.append( (*it)->m_part );
5914 
5915  return res;
5916 }
5917 
5918 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
5919 {
5920  kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
5921  FrameIt it = d->m_frames.find( urlArgs.frameName );
5922 
5923  if ( it == d->m_frames.end() )
5924  return false;
5925 
5926  // Inform someone that we are about to show something else.
5927  if ( !urlArgs.lockHistory() )
5928  emit d->m_extension->openURLNotify();
5929 
5930  requestObject( *it, url, urlArgs );
5931 
5932  return true;
5933 }
5934 
5935 void KHTMLPart::setDNDEnabled( bool b )
5936 {
5937  d->m_bDnd = b;
5938 }
5939 
5940 bool KHTMLPart::dndEnabled() const
5941 {
5942  return d->m_bDnd;
5943 }
5944 
5945 void KHTMLPart::customEvent( TQCustomEvent *event )
5946 {
5947  if ( khtml::MousePressEvent::test( event ) )
5948  {
5949  khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
5950  return;
5951  }
5952 
5953  if ( khtml::MouseDoubleClickEvent::test( event ) )
5954  {
5955  khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
5956  return;
5957  }
5958 
5959  if ( khtml::MouseMoveEvent::test( event ) )
5960  {
5961  khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
5962  return;
5963  }
5964 
5965  if ( khtml::MouseReleaseEvent::test( event ) )
5966  {
5967  khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
5968  return;
5969  }
5970 
5971  if ( khtml::DrawContentsEvent::test( event ) )
5972  {
5973  khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
5974  return;
5975  }
5976 
5977  KParts::ReadOnlyPart::customEvent( event );
5978 }
5979 
5985 static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
5986 {
5987  for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
5988  if (n->isText()) {
5989  khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
5990  const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
5991  const unsigned lim = runs.count();
5992  for (unsigned i = 0; i != lim; ++i) {
5993  if (runs[i]->m_y == y && textRenderer->element()) {
5994  startNode = textRenderer->element();
5995  startOffset = runs[i]->m_start;
5996  return true;
5997  }
5998  }
5999  }
6000 
6001  if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
6002  return true;
6003  }
6004  }
6005 
6006  return false;
6007 }
6008 
6014 static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
6015 {
6016  khtml::RenderObject *n = renderNode;
6017  if (!n) {
6018  return false;
6019  }
6020  khtml::RenderObject *next;
6021  while ((next = n->nextSibling())) {
6022  n = next;
6023  }
6024 
6025  while (1) {
6026  if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
6027  return true;
6028  }
6029 
6030  if (n->isText()) {
6031  khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
6032  const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
6033  for (int i = (int)runs.count()-1; i >= 0; --i) {
6034  if (runs[i]->m_y == y && textRenderer->element()) {
6035  endNode = textRenderer->element();
6036  endOffset = runs[i]->m_start + runs[i]->m_len;
6037  return true;
6038  }
6039  }
6040  }
6041 
6042  if (n == renderNode) {
6043  return false;
6044  }
6045 
6046  n = n->previousSibling();
6047  }
6048 }
6049 
6050 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
6051 {
6052  DOM::DOMString url = event->url();
6053  TQMouseEvent *_mouse = event->qmouseEvent();
6054  DOM::Node innerNode = event->innerNode();
6055  d->m_mousePressNode = innerNode;
6056 
6057  d->m_dragStartPos = _mouse->pos();
6058 
6059  if ( !event->url().isNull() ) {
6060  d->m_strSelectedURL = event->url().string();
6061  d->m_strSelectedURLTarget = event->target().string();
6062  }
6063  else
6064  d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
6065 
6066  if ( _mouse->button() == Qt::LeftButton ||
6067  _mouse->button() == Qt::MidButton )
6068  {
6069  d->m_bMousePressed = true;
6070 
6071 #ifndef KHTML_NO_SELECTION
6072  if ( _mouse->button() == Qt::LeftButton )
6073  {
6074  if ( (!d->m_strSelectedURL.isNull() && !isEditable())
6075  || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
6076  return;
6077  if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
6078  int offset = 0;
6079  DOM::NodeImpl* node = 0;
6080  khtml::RenderObject::SelPointState state;
6081  innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
6082  event->absX()-innerNode.handle()->renderer()->xPos(),
6083  event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
6084  d->m_extendMode = d->ExtendByChar;
6085 #ifdef KHTML_NO_CARET
6086  d->m_selectionStart = node;
6087  d->m_startOffset = offset;
6088  //if ( node )
6089  // kdDebug(6005) << "KHTMLPart::khtmlMousePressEvent selectionStart=" << d->m_selectionStart.handle()->renderer()
6090  // << " offset=" << d->m_startOffset << endl;
6091  //else
6092  // kdDebug(6005) << "KHTML::khtmlMousePressEvent selectionStart=(nil)" << endl;
6093  d->m_selectionEnd = d->m_selectionStart;
6094  d->m_endOffset = d->m_startOffset;
6095  d->m_doc->clearSelection();
6096 #else // KHTML_NO_CARET
6097  d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
6098 #endif // KHTML_NO_CARET
6099  d->m_initialNode = d->m_selectionStart;
6100  d->m_initialOffset = d->m_startOffset;
6101 // kdDebug(6000) << "press: initOfs " << d->m_initialOffset << endl;
6102  }
6103  else
6104  {
6105 #ifndef KHTML_NO_CARET
6106  // simply leave it. Is this a good idea?
6107 #else
6108  d->m_selectionStart = DOM::Node();
6109  d->m_selectionEnd = DOM::Node();
6110 #endif
6111  }
6112  emitSelectionChanged();
6113  startAutoScroll();
6114  }
6115 #else
6116  d->m_dragLastPos = _mouse->globalPos();
6117 #endif
6118  }
6119 
6120  if ( _mouse->button() == Qt::RightButton && parentPart() != 0 && d->m_bBackRightClick )
6121  {
6122  d->m_bRightMousePressed = true;
6123  } else if ( _mouse->button() == Qt::RightButton )
6124  {
6125  popupMenu( d->m_strSelectedURL );
6126  // might be deleted, don't touch "this"
6127  }
6128 }
6129 
6130 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
6131 {
6132  TQMouseEvent *_mouse = event->qmouseEvent();
6133  if ( _mouse->button() == Qt::LeftButton )
6134  {
6135  d->m_bMousePressed = true;
6136  DOM::Node innerNode = event->innerNode();
6137  // Find selectionStart again, khtmlMouseReleaseEvent lost it
6138  if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
6139  int offset = 0;
6140  DOM::NodeImpl* node = 0;
6141  khtml::RenderObject::SelPointState state;
6142  innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
6143  event->absX()-innerNode.handle()->renderer()->xPos(),
6144  event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);
6145 
6146  //kdDebug() << k_funcinfo << "checkSelectionPoint returned node=" << node << " offset=" << offset << endl;
6147 
6148  if ( node && node->renderer() )
6149  {
6150  // Extend selection to a complete word (double-click) or line (triple-click)
6151  bool selectLine = (event->clickCount() == 3);
6152  d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;
6153 
6154  // Extend existing selection if Shift was pressed
6155  if (_mouse->state() & ShiftButton) {
6156  d->caretNode() = node;
6157  d->caretOffset() = offset;
6158  d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
6159  d->m_selectionStart.handle(), d->m_startOffset,
6160  d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
6161  d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
6162  d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
6163  } else {
6164  d->m_selectionStart = d->m_selectionEnd = node;
6165  d->m_startOffset = d->m_endOffset = offset;
6166  d->m_startBeforeEnd = true;
6167  d->m_initialNode = node;
6168  d->m_initialOffset = offset;
6169  }
6170 // kdDebug(6000) << "dblclk: initOfs " << d->m_initialOffset << endl;
6171 
6172  // Extend the start
6173  extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
6174  // Extend the end
6175  extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );
6176 
6177  //kdDebug() << d->m_selectionStart.handle() << " " << d->m_startOffset << " - " <<
6178  // d->m_selectionEnd.handle() << " " << d->m_endOffset << endl;
6179 
6180  emitSelectionChanged();
6181  d->m_doc
6182  ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
6183  d->m_selectionEnd.handle(),d->m_endOffset);
6184 #ifndef KHTML_NO_CARET
6185  bool v = d->m_view->placeCaret();
6186  emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
6187 #endif
6188  startAutoScroll();
6189  }
6190  }
6191  }
6192 }
6193 
6194 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
6195 {
6196  khtml::RenderObject* obj = node->renderer();
6197 
6198  if (obj->isText() && selectLines) {
6199  int pos;
6200  khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
6201  khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
6202  DOMString t = node->nodeValue();
6203  DOM::NodeImpl* selNode = 0;
6204  long selOfs = 0;
6205 
6206  if (!run)
6207  return;
6208 
6209  int selectionPointY = run->m_y;
6210 
6211  // Go up to first non-inline element.
6212  khtml::RenderObject *renderNode = renderer;
6213  while (renderNode && renderNode->isInline())
6214  renderNode = renderNode->parent();
6215 
6216  renderNode = renderNode->firstChild();
6217 
6218  if (right) {
6219  // Look for all the last child in the block that is on the same line
6220  // as the selection point.
6221  if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
6222  return;
6223  } else {
6224  // Look for all the first child in the block that is on the same line
6225  // as the selection point.
6226  if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
6227  return;
6228  }
6229 
6230  selectionNode = selNode;
6231  selectionOffset = selOfs;
6232  return;
6233  }
6234 
6235  TQString str;
6236  int len = 0;
6237  if ( obj->isText() ) { // can be false e.g. when double-clicking on a disabled submit button
6238  str = static_cast<khtml::RenderText *>(obj)->data().string();
6239  len = str.length();
6240  }
6241  //kdDebug() << "extendSelection right=" << right << " offset=" << offset << " len=" << len << " Starting at obj=" << obj << endl;
6242  TQChar ch;
6243  do {
6244  // Last char was ok, point to it
6245  if ( node ) {
6246  selectionNode = node;
6247  selectionOffset = offset;
6248  }
6249 
6250  // Get another char
6251  while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
6252  {
6253  obj = right ? obj->objectBelow() : obj->objectAbove();
6254  //kdDebug() << "obj=" << obj << endl;
6255  if ( obj ) {
6256  //kdDebug() << "isText=" << obj->isText() << endl;
6257  str = TQString();
6258  if ( obj->isText() )
6259  str = static_cast<khtml::RenderText *>(obj)->data().string();
6260  else if ( obj->isBR() )
6261  str = '\n';
6262  else if ( !obj->isInline() ) {
6263  obj = 0L; // parag limit -> done
6264  break;
6265  }
6266  len = str.length();
6267  //kdDebug() << "str=" << str << " length=" << len << endl;
6268  // set offset - note that the first thing will be a ++ or -- on it.
6269  if ( right )
6270  offset = -1;
6271  else
6272  offset = len;
6273  }
6274  }
6275  if ( !obj ) // end of parag or document
6276  break;
6277  node = obj->element();
6278  if ( right )
6279  {
6280  Q_ASSERT( offset < len-1 );
6281  ++offset;
6282  }
6283  else
6284  {
6285  Q_ASSERT( offset > 0 );
6286  --offset;
6287  }
6288 
6289  // Test that char
6290  ch = str[ (int)offset ];
6291  //kdDebug() << " offset=" << offset << " ch=" << TQString(ch) << endl;
6292  } while ( !ch.isSpace() && !ch.isPunct() );
6293 
6294  // make offset point after last char
6295  if (right) ++selectionOffset;
6296 }
6297 
6298 #ifndef KHTML_NO_SELECTION
6299 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
6300 {
6301  int offset;
6302  //kdDebug(6000) << "KHTMLPart::khtmlMouseMoveEvent x=" << event->x() << " y=" << event->y() << endl;
6303  DOM::NodeImpl* node=0;
6304  khtml::RenderObject::SelPointState state;
6305  innerNode.handle()->renderer()->checkSelectionPoint( x, y,
6306  absX-innerNode.handle()->renderer()->xPos(),
6307  absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
6308  if (!node || !node->renderer()) return;
6309 
6310  // Words at the beginning/end of line cannot be deselected in
6311  // ExtendByWord mode. Therefore, do not enforce it if the selection
6312  // point does not match the node under the mouse cursor.
6313  bool withinNode = innerNode == node;
6314 
6315  // we have to get to know if end is before start or not...
6316  // shouldn't be null but it can happen with dynamic updating of nodes
6317  if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
6318  d->m_initialNode.isNull() ||
6319  !d->m_selectionStart.handle()->renderer() ||
6320  !d->m_selectionEnd.handle()->renderer()) return;
6321 
6322  if (d->m_extendMode != d->ExtendByChar) {
6323  // check whether we should extend at the front, or at the back
6324  bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
6325  d->caretNode().handle(), d->caretOffset(),
6326  d->m_initialNode.handle(), d->m_initialOffset) <= 0;
6327  bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
6328  d->m_initialNode.handle(), d->m_initialOffset) <= 0;
6329  // have to fix up start to point to the original end
6330  if (caretBeforeInit != nodeBeforeInit) {
6331 // kdDebug(6000) << "extto cbi: " << caretBeforeInit << " startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << " initOfs " << d->m_initialOffset << endl;
6332  extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
6333  d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
6334  d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
6335  nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
6336  }
6337  }
6338 
6339  d->caretNode() = node;
6340  d->caretOffset() = offset;
6341  //kdDebug( 6000 ) << "setting end of selection to " << d->m_selectionEnd.handle() << "/" << d->m_endOffset << endl;
6342 
6343  d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
6344  d->m_selectionStart.handle(), d->m_startOffset,
6345  d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
6346 
6347  if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
6348  {
6349 // kdDebug(6000) << "extto: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << " initOfs " << d->m_initialOffset << endl;
6350  if (d->m_extendMode != d->ExtendByChar && withinNode)
6351  extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );
6352 
6353  if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
6354  d->m_doc
6355  ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
6356  d->m_selectionEnd.handle(),d->m_startOffset);
6357  else if (d->m_startBeforeEnd)
6358  d->m_doc
6359  ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
6360  d->m_selectionEnd.handle(),d->m_endOffset);
6361  else
6362  d->m_doc
6363  ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
6364  d->m_selectionStart.handle(),d->m_startOffset);
6365  }
6366 #ifndef KHTML_NO_CARET
6367  d->m_view->placeCaret();
6368 #endif
6369 }
6370 
6371 bool KHTMLPart::isExtendingSelection() const
6372 {
6373  // This is it, the whole detection. khtmlMousePressEvent only sets this
6374  // on LMB or MMB, but never on RMB. As text selection doesn't work for MMB,
6375  // it's sufficient to only rely on this flag to detect selection extension.
6376  return d->m_bMousePressed;
6377 }
6378 #endif // KHTML_NO_SELECTION
6379 
6380 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
6381 {
6382  TQMouseEvent *_mouse = event->qmouseEvent();
6383 
6384  if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
6385  {
6386  popupMenu( d->m_strSelectedURL );
6387  d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
6388  d->m_bRightMousePressed = false;
6389  }
6390 
6391  DOM::DOMString url = event->url();
6392  DOM::DOMString target = event->target();
6393  DOM::Node innerNode = event->innerNode();
6394 
6395 #ifndef QT_NO_DRAGANDDROP
6396  if( d->m_bDnd && d->m_bMousePressed &&
6397  ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
6398  || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
6399  if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
6400  return;
6401 
6402  TQPixmap pix;
6403  HTMLImageElementImpl *img = 0L;
6404  TQDragObject *drag = 0;
6405  KURL u;
6406 
6407  // qDebug("****************** Event URL: %s", url.string().latin1());
6408  // qDebug("****************** Event Target: %s", target.string().latin1());
6409 
6410  // Normal image...
6411  if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
6412  {
6413  img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
6414  u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
6415  pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
6416  }
6417  else
6418  {
6419  // Text or image link...
6420  u = completeURL( d->m_strSelectedURL );
6421  pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
6422  }
6423 
6424  u.setPass(TQString());
6425 
6426  KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
6427  if ( !d->m_referrer.isEmpty() )
6428  urlDrag->metaData()["referrer"] = d->m_referrer;
6429 
6430  if( img && img->complete()) {
6431  KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
6432  mdrag->addDragObject( new TQImageDrag( img->currentImage(), 0L ) );
6433  mdrag->addDragObject( urlDrag );
6434  drag = mdrag;
6435  }
6436  else
6437  drag = urlDrag;
6438 
6439  if ( !pix.isNull() )
6440  drag->setPixmap( pix );
6441 
6442  stopAutoScroll();
6443  if(drag)
6444  drag->drag();
6445 
6446  // when we finish our drag, we need to undo our mouse press
6447  d->m_bMousePressed = false;
6448  d->m_strSelectedURL = d->m_strSelectedURLTarget = TQString();
6449  return;
6450  }
6451 #endif
6452 
6453  // Not clicked -> mouse over stuff
6454  if ( !d->m_bMousePressed )
6455  {
6456  // The mouse is over something
6457  if ( url.length() )
6458  {
6459  bool shiftPressed = ( _mouse->state() & ShiftButton );
6460 
6461  // Image map
6462  if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
6463  {
6464  HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
6465  if ( i && i->isServerMap() )
6466  {
6467  khtml::RenderObject *r = i->renderer();
6468  if(r)
6469  {
6470  int absx, absy, vx, vy;
6471  r->absolutePosition(absx, absy);
6472  view()->contentsToViewport( absx, absy, vx, vy );
6473 
6474  int x(_mouse->x() - vx), y(_mouse->y() - vy);
6475 
6476  d->m_overURL = url.string() + TQString("?%1,%2").arg(x).arg(y);
6477  d->m_overURLTarget = target.string();
6478  overURL( d->m_overURL, target.string(), shiftPressed );
6479  return;
6480  }
6481  }
6482  }
6483 
6484  // normal link
6485  if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
6486  {
6487  d->m_overURL = url.string();
6488  d->m_overURLTarget = target.string();
6489  overURL( d->m_overURL, target.string(), shiftPressed );
6490  }
6491  }
6492  else // Not over a link...
6493  {
6494  // reset to "default statusbar text"
6495  resetHoverText();
6496  }
6497  }
6498  else {
6499 #ifndef KHTML_NO_SELECTION
6500  // selection stuff
6501  if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
6502  ( (_mouse->state() & Qt::LeftButton) != 0 )) {
6503  extendSelectionTo(event->x(), event->y(),
6504  event->absX(), event->absY(), innerNode);
6505 #else
6506  if ( d->m_doc && d->m_view ) {
6507  TQPoint diff( _mouse->globalPos() - d->m_dragLastPos );
6508 
6509  if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
6510  d->m_view->scrollBy( -diff.x(), -diff.y() );
6511  d->m_dragLastPos = _mouse->globalPos();
6512  }
6513 #endif
6514  }
6515  }
6516 
6517 }
6518 
6519 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
6520 {
6521  DOM::Node innerNode = event->innerNode();
6522  d->m_mousePressNode = DOM::Node();
6523 
6524  if ( d->m_bMousePressed ) {
6525  setStatusBarText(TQString(), BarHoverText);
6526  stopAutoScroll();
6527  }
6528 
6529  // Used to prevent mouseMoveEvent from initiating a drag before
6530  // the mouse is pressed again.
6531  d->m_bMousePressed = false;
6532 
6533  TQMouseEvent *_mouse = event->qmouseEvent();
6534  if ( _mouse->button() == Qt::RightButton && parentPart() != 0 && d->m_bBackRightClick )
6535  {
6536  d->m_bRightMousePressed = false;
6537  KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
6538  if( tmp_iface ) {
6539  tmp_iface->callMethod( "goHistory(int)", -1 );
6540  }
6541  }
6542 #ifndef QT_NO_CLIPBOARD
6543  if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == Qt::MidButton) && (event->url().isNull())) {
6544  kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
6545  << d->m_bOpenMiddleClick << endl;
6546 
6547  if (d->m_bOpenMiddleClick) {
6548  KHTMLPart *p = this;
6549  while (p->parentPart()) p = p->parentPart();
6550  p->d->m_extension->pasteRequest();
6551  }
6552  }
6553 #endif
6554 
6555 #ifndef KHTML_NO_SELECTION
6556  // delete selection in case start and end position are at the same point
6557  if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
6558 #ifndef KHTML_NO_CARET
6559  d->m_extendAtEnd = true;
6560 #else
6561  d->m_selectionStart = 0;
6562  d->m_selectionEnd = 0;
6563  d->m_startOffset = 0;
6564  d->m_endOffset = 0;
6565 #endif
6566  emitSelectionChanged();
6567  } else {
6568  // we have to get to know if end is before start or not...
6569 // kdDebug(6000) << "rel: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << ")" << endl;
6570  DOM::Node n = d->m_selectionStart;
6571  d->m_startBeforeEnd = false;
6572  if( d->m_selectionStart == d->m_selectionEnd ) {
6573  if( d->m_startOffset < d->m_endOffset )
6574  d->m_startBeforeEnd = true;
6575  } else {
6576 #if 0
6577  while(!n.isNull()) {
6578  if(n == d->m_selectionEnd) {
6579  d->m_startBeforeEnd = true;
6580  break;
6581  }
6582  DOM::Node next = n.firstChild();
6583  if(next.isNull()) next = n.nextSibling();
6584  while( next.isNull() && !n.parentNode().isNull() ) {
6585  n = n.parentNode();
6586  next = n.nextSibling();
6587  }
6588  n = next;
6589  }
6590 #else
6591  // shouldn't be null but it can happen with dynamic updating of nodes
6592  if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
6593  !d->m_selectionStart.handle()->renderer() ||
6594  !d->m_selectionEnd.handle()->renderer()) return;
6595  d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
6596  d->m_selectionStart.handle(), d->m_startOffset,
6597  d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
6598 #endif
6599  }
6600  if(!d->m_startBeforeEnd)
6601  {
6602  DOM::Node tmpNode = d->m_selectionStart;
6603  int tmpOffset = d->m_startOffset;
6604  d->m_selectionStart = d->m_selectionEnd;
6605  d->m_startOffset = d->m_endOffset;
6606  d->m_selectionEnd = tmpNode;
6607  d->m_endOffset = tmpOffset;
6608  d->m_startBeforeEnd = true;
6609  d->m_extendAtEnd = !d->m_extendAtEnd;
6610  }
6611 #ifndef KHTML_NO_CARET
6612  bool v = d->m_view->placeCaret();
6613  emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
6614 #endif
6615  // get selected text and paste to the clipboard
6616 #ifndef QT_NO_CLIPBOARD
6617  TQString text = selectedText();
6618  text.replace(TQChar(0xa0), ' ');
6619  disconnect( kapp->clipboard(), TQT_SIGNAL( selectionChanged()), this, TQT_SLOT( slotClearSelection()));
6620  kapp->clipboard()->setText(text,TQClipboard::Selection);
6621  connect( kapp->clipboard(), TQT_SIGNAL( selectionChanged()), TQT_SLOT( slotClearSelection()));
6622 #endif
6623  //kdDebug( 6000 ) << "selectedText = " << text << endl;
6624  emitSelectionChanged();
6625 //kdDebug(6000) << "rel2: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << "), caretOfs " << d->caretOffset() << endl;
6626  }
6627 #endif
6628  d->m_initialNode = 0; // don't hold nodes longer than necessary
6629  d->m_initialOffset = 0;
6630 
6631 }
6632 
6633 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
6634 {
6635 }
6636 
6637 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
6638 {
6639  if ( event->activated() )
6640  {
6641  emitSelectionChanged();
6642  emit d->m_extension->enableAction( "print", d->m_doc != 0 );
6643 
6644  if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
6645  {
6646  TQPtrList<KAction> lst;
6647  lst.append( d->m_paLoadImages );
6648  plugActionList( "loadImages", lst );
6649  }
6650  }
6651 }
6652 
6653 void KHTMLPart::slotPrintFrame()
6654 {
6655  if ( d->m_frames.count() == 0 )
6656  return;
6657 
6658  KParts::ReadOnlyPart *frame = currentFrame();
6659  if (!frame)
6660  return;
6661 
6662  KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
6663 
6664  if ( !ext )
6665  return;
6666 
6667  TQMetaObject *mo = ext->metaObject();
6668 
6669  int idx = mo->findSlot( "print()", true );
6670  if ( idx >= 0 ) {
6671  TQUObject o[ 1 ];
6672  ext->qt_invoke( idx, o );
6673  }
6674 }
6675 
6676 void KHTMLPart::slotSelectAll()
6677 {
6678  KParts::ReadOnlyPart *part = currentFrame();
6679  if (part && part->inherits("KHTMLPart"))
6680  static_cast<KHTMLPart *>(part)->selectAll();
6681 }
6682 
6683 void KHTMLPart::startAutoScroll()
6684 {
6685  connect(&d->m_scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ));
6686  d->m_scrollTimer.start(100, false);
6687 }
6688 
6689 void KHTMLPart::stopAutoScroll()
6690 {
6691  disconnect(&d->m_scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotAutoScroll() ));
6692  if (d->m_scrollTimer.isActive())
6693  d->m_scrollTimer.stop();
6694 }
6695 
6696 
6697 void KHTMLPart::slotAutoScroll()
6698 {
6699  if (d->m_view)
6700  d->m_view->doAutoScroll();
6701  else
6702  stopAutoScroll(); // Safety
6703 }
6704 
6705 void KHTMLPart::runAdFilter()
6706 {
6707  if ( parentPart() )
6708  parentPart()->runAdFilter();
6709 
6710  if ( !d->m_doc )
6711  return;
6712 
6713  TQPtrDictIterator<khtml::CachedObject> it( d->m_doc->docLoader()->m_docObjects );
6714  for ( ; it.current(); ++it )
6715  if ( it.current()->type() == khtml::CachedObject::Image ) {
6716  khtml::CachedImage *image = static_cast<khtml::CachedImage *>(it.current());
6717  bool wasBlocked = image->m_wasBlocked;
6718  image->m_wasBlocked = KHTMLFactory::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( (*it).url().string() ) );
6719  if ( image->m_wasBlocked != wasBlocked )
6720  image->do_notify(image->pixmap(), image->valid_rect());
6721  }
6722 
6723  if ( KHTMLFactory::defaultHTMLSettings()->isHideAdsEnabled() ) {
6724  for ( NodeImpl *nextNode, *node = d->m_doc; node; node = nextNode ) {
6725 
6726  // We might be deleting 'node' shortly.
6727  nextNode = node->traverseNextNode();
6728 
6729  if ( node->id() == ID_IMG ||
6730  node->id() == ID_IFRAME ||
6731  (node->id() == ID_INPUT && static_cast<HTMLInputElementImpl *>(node)->inputType() == HTMLInputElementImpl::IMAGE ))
6732  {
6733  if ( KHTMLFactory::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( static_cast<ElementImpl *>(node)->getAttribute(ATTR_SRC).string() ) ) )
6734  {
6735  // We found an IMG, IFRAME or INPUT (of type IMAGE) matching a filter.
6736  node->ref();
6737  NodeImpl *parent = node->parent();
6738  if( parent )
6739  {
6740  int exception = 0;
6741  parent->removeChild(node, exception);
6742  }
6743  node->deref();
6744  }
6745  }
6746  }
6747  }
6748 }
6749 
6750 void KHTMLPart::selectAll()
6751 {
6752  if (!d->m_doc) return;
6753 
6754  NodeImpl *first;
6755  if (d->m_doc->isHTMLDocument())
6756  first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
6757  else
6758  first = d->m_doc;
6759  NodeImpl *next;
6760 
6761  // Look for first text/cdata node that has a renderer,
6762  // or first childless replaced element
6763  while ( first && !(first->renderer()
6764  && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
6765  || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
6766  {
6767  next = first->firstChild();
6768  if ( !next ) next = first->nextSibling();
6769  while( first && !next )
6770  {
6771  first = first->parentNode();
6772  if ( first )
6773  next = first->nextSibling();
6774  }
6775  first = next;
6776  }
6777 
6778  NodeImpl *last;
6779  if (d->m_doc->isHTMLDocument())
6780  last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
6781  else
6782  last = d->m_doc;
6783  // Look for last text/cdata node that has a renderer,
6784  // or last childless replaced element
6785  // ### Instead of changing this loop, use findLastSelectableNode
6786  // in render_table.cpp (LS)
6787  while ( last && !(last->renderer()
6788  && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
6789  || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
6790  {
6791  next = last->lastChild();
6792  if ( !next ) next = last->previousSibling();
6793  while ( last && !next )
6794  {
6795  last = last->parentNode();
6796  if ( last )
6797  next = last->previousSibling();
6798  }
6799  last = next;
6800  }
6801 
6802  if ( !first || !last )
6803  return;
6804  Q_ASSERT(first->renderer());
6805  Q_ASSERT(last->renderer());
6806  d->m_selectionStart = first;
6807  d->m_startOffset = 0;
6808  d->m_selectionEnd = last;
6809  d->m_endOffset = last->nodeValue().length();
6810  d->m_startBeforeEnd = true;
6811 
6812  d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
6813  d->m_selectionEnd.handle(), d->m_endOffset );
6814 
6815  emitSelectionChanged();
6816 }
6817 
6818 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const TQString &message, const TQString &button)
6819 {
6820  bool linkAllowed = true;
6821 
6822  if ( d->m_doc )
6823  linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);
6824 
6825  if ( !linkAllowed ) {
6826  khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
6827  if (tokenizer)
6828  tokenizer->setOnHold(true);
6829 
6830  int response = KMessageBox::Cancel;
6831  if (!message.isEmpty())
6832  {
6833  response = KMessageBox::warningContinueCancel( 0,
6834  message.arg(linkURL.htmlURL()),
6835  i18n( "Security Warning" ),
6836  button);
6837  }
6838  else
6839  {
6840  KMessageBox::error( 0,
6841  i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
6842  i18n( "Security Alert" ));
6843  }
6844 
6845  if (tokenizer)
6846  tokenizer->setOnHold(false);
6847  return (response==KMessageBox::Continue);
6848  }
6849  return true;
6850 }
6851 
6852 void KHTMLPart::slotPartRemoved( KParts::Part *part )
6853 {
6854 // kdDebug(6050) << "KHTMLPart::slotPartRemoved " << part << endl;
6855  if ( part == d->m_activeFrame )
6856  {
6857  d->m_activeFrame = 0L;
6858  if ( !part->inherits( "KHTMLPart" ) )
6859  {
6860  if (factory()) {
6861  factory()->removeClient( part );
6862  }
6863  if (childClients()->containsRef(part)) {
6864  removeChildClient( part );
6865  }
6866  }
6867  }
6868 }
6869 
6870 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
6871 {
6872 // kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged this=" << this << "part=" << part << endl;
6873  if ( part == this )
6874  {
6875  kdError(6050) << "strange error! we activated ourselves" << endl;
6876  assert( false );
6877  return;
6878  }
6879 // kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged d->m_activeFrame=" << d->m_activeFrame << endl;
6880  if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( TQFRAME_OBJECT_NAME_STRING ) )
6881  {
6882  TQFrame *frame = static_cast<TQFrame *>( d->m_activeFrame->widget() );
6883  if (frame->frameStyle() != TQFrame::NoFrame)
6884  {
6885  frame->setFrameStyle( TQFrame::StyledPanel | TQFrame::Sunken);
6886  frame->repaint();
6887  }
6888  }
6889 
6890  if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
6891  {
6892  if (factory()) {
6893  factory()->removeClient( d->m_activeFrame );
6894  }
6895  removeChildClient( d->m_activeFrame );
6896  }
6897  if( part && !part->inherits( "KHTMLPart" ) )
6898  {
6899  if (factory()) {
6900  factory()->addClient( part );
6901  }
6902  insertChildClient( part );
6903  }
6904 
6905 
6906  d->m_activeFrame = part;
6907 
6908  if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( TQFRAME_OBJECT_NAME_STRING ) )
6909  {
6910  TQFrame *frame = static_cast<TQFrame *>( d->m_activeFrame->widget() );
6911  if (frame->frameStyle() != TQFrame::NoFrame)
6912  {
6913  frame->setFrameStyle( TQFrame::StyledPanel | TQFrame::Plain);
6914  frame->repaint();
6915  }
6916  kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
6917  }
6918 
6919  updateActions();
6920 
6921  // (note: childObject returns 0 if the argument is 0)
6922  d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
6923 }
6924 
6925 void KHTMLPart::setActiveNode(const DOM::Node &node)
6926 {
6927  if (!d->m_doc || !d->m_view)
6928  return;
6929 
6930  // Set the document's active node
6931  d->m_doc->setFocusNode(node.handle());
6932 
6933  // Scroll the view if necessary to ensure that the new focus node is visible
6934  TQRect rect = node.handle()->getRect();
6935  d->m_view->ensureVisible(rect.right(), rect.bottom());
6936  d->m_view->ensureVisible(rect.left(), rect.top());
6937 }
6938 
6939 DOM::Node KHTMLPart::activeNode() const
6940 {
6941  return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
6942 }
6943 
6944 DOM::EventListener *KHTMLPart::createHTMLEventListener( TQString code, TQString name, NodeImpl* node )
6945 {
6946  KJSProxy *proxy = jScript();
6947 
6948  if (!proxy)
6949  return 0;
6950 
6951  return proxy->createHTMLEventHandler( m_url.url(), name, code, node );
6952 }
6953 
6954 KHTMLPart *KHTMLPart::opener()
6955 {
6956  return d->m_opener;
6957 }
6958 
6959 void KHTMLPart::setOpener(KHTMLPart *_opener)
6960 {
6961  d->m_opener = _opener;
6962 }
6963 
6964 bool KHTMLPart::openedByJS()
6965 {
6966  return d->m_openedByJS;
6967 }
6968 
6969 void KHTMLPart::setOpenedByJS(bool _openedByJS)
6970 {
6971  d->m_openedByJS = _openedByJS;
6972 }
6973 
6974 void KHTMLPart::preloadStyleSheet(const TQString &url, const TQString &stylesheet)
6975 {
6976  khtml::Cache::preloadStyleSheet(url, stylesheet);
6977 }
6978 
6979 void KHTMLPart::preloadScript(const TQString &url, const TQString &script)
6980 {
6981  khtml::Cache::preloadScript(url, script);
6982 }
6983 
6984 TQCString KHTMLPart::dcopObjectId() const
6985 {
6986  TQCString id;
6987  id.sprintf("html-widget%d", d->m_dcop_counter);
6988  return id;
6989 }
6990 
6991 long KHTMLPart::cacheId() const
6992 {
6993  return d->m_cacheId;
6994 }
6995 
6996 bool KHTMLPart::restored() const
6997 {
6998  return d->m_restored;
6999 }
7000 
7001 bool KHTMLPart::pluginPageQuestionAsked(const TQString& mimetype) const
7002 {
7003  // parentPart() should be const!
7004  KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
7005  if ( parent )
7006  return parent->pluginPageQuestionAsked(mimetype);
7007 
7008  return d->m_pluginPageQuestionAsked.contains(mimetype);
7009 }
7010 
7011 void KHTMLPart::setPluginPageQuestionAsked(const TQString& mimetype)
7012 {
7013  if ( parentPart() )
7014  parentPart()->setPluginPageQuestionAsked(mimetype);
7015 
7016  d->m_pluginPageQuestionAsked.append(mimetype);
7017 }
7018 
7019 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
7020 {
7021  d->m_automaticDetection->setItemChecked( _id, true );
7022 
7023  switch ( _id ) {
7024  case 0 :
7025  d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
7026  break;
7027  case 1 :
7028  d->m_autoDetectLanguage = khtml::Decoder::Arabic;
7029  break;
7030  case 2 :
7031  d->m_autoDetectLanguage = khtml::Decoder::Baltic;
7032  break;
7033  case 3 :
7034  d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
7035  break;
7036  case 4 :
7037  d->m_autoDetectLanguage = khtml::Decoder::Chinese;
7038  break;
7039  case 5 :
7040  d->m_autoDetectLanguage = khtml::Decoder::Greek;
7041  break;
7042  case 6 :
7043  d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
7044  break;
7045  case 7 :
7046  d->m_autoDetectLanguage = khtml::Decoder::Japanese;
7047  break;
7048  case 8 :
7049  d->m_autoDetectLanguage = khtml::Decoder::Korean;
7050  break;
7051  case 9 :
7052  d->m_autoDetectLanguage = khtml::Decoder::Russian;
7053  break;
7054  case 10 :
7055  d->m_autoDetectLanguage = khtml::Decoder::Thai;
7056  break;
7057  case 11 :
7058  d->m_autoDetectLanguage = khtml::Decoder::Turkish;
7059  break;
7060  case 12 :
7061  d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
7062  break;
7063  case 13 :
7064  d->m_autoDetectLanguage = khtml::Decoder::Unicode;
7065  break;
7066  case 14 :
7067  d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
7068  break;
7069  default :
7070  d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
7071  break;
7072  }
7073 
7074  for ( int i = 0; i <= 14; ++i ) {
7075  if ( i != _id )
7076  d->m_automaticDetection->setItemChecked( i, false );
7077  }
7078 
7079  d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
7080 
7081  setEncoding( TQString(), false );
7082 
7083  if( d->m_manualDetection )
7084  d->m_manualDetection->setCurrentItem( -1 );
7085  d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
7086 }
7087 
7088 khtml::Decoder *KHTMLPart::createDecoder()
7089 {
7090  khtml::Decoder *dec = new khtml::Decoder();
7091  if( !d->m_encoding.isNull() )
7092  dec->setEncoding( d->m_encoding.latin1(),
7093  d->m_haveEncoding ? khtml::Decoder::UserChosenEncoding : khtml::Decoder::EncodingFromHTTPHeader);
7094  else {
7095  // Inherit the default encoding from the parent frame if there is one.
7096  const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
7097  ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
7098  dec->setEncoding(defaultEncoding, khtml::Decoder::DefaultEncoding);
7099  }
7100 #ifdef APPLE_CHANGES
7101  if (d->m_doc)
7102  d->m_doc->setDecoder(d->m_decoder);
7103 #endif
7104  dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
7105  return dec;
7106 }
7107 
7108 void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
7109  emit caretPositionChanged(node, offset);
7110 }
7111 
7112 void KHTMLPart::restoreScrollPosition()
7113 {
7114  KParts::URLArgs args = d->m_extension->urlArgs();
7115 
7116  if ( m_url.hasRef() && !d->m_restoreScrollPosition && !args.reload) {
7117  if ( !d->m_doc || !d->m_doc->parsing() )
7118  disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
7119  if ( !gotoAnchor(m_url.encodedHtmlRef()) )
7120  gotoAnchor(m_url.htmlRef());
7121  return;
7122  }
7123 
7124  // Check whether the viewport has become large enough to encompass the stored
7125  // offsets. If the document has been fully loaded, force the new coordinates,
7126  // even if the canvas is too short (can happen when user resizes the window
7127  // during loading).
7128  if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
7129  || d->m_bComplete) {
7130  d->m_view->setContentsPos(args.xOffset, args.yOffset);
7131  disconnect(d->m_view, TQT_SIGNAL(finishedLayout()), this, TQT_SLOT(restoreScrollPosition()));
7132  }
7133 }
7134 
7135 
7136 void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
7137 {
7138 #ifndef KHTML_NO_WALLET
7139  KHTMLPart *p;
7140 
7141  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
7142  }
7143 
7144  if (p) {
7145  p->openWallet(form);
7146  return;
7147  }
7148 
7149  if (onlyLocalReferences()) { // avoid triggering on local apps, thumbnails
7150  return;
7151  }
7152 
7153  if (d->m_wallet) {
7154  if (d->m_bWalletOpened) {
7155  if (d->m_wallet->isOpen()) {
7156  form->walletOpened(d->m_wallet);
7157  return;
7158  }
7159  d->m_wallet->deleteLater();
7160  d->m_wallet = 0L;
7161  d->m_bWalletOpened = false;
7162  }
7163  }
7164 
7165  if (!d->m_wq) {
7166  KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
7167  d->m_wq = new KHTMLWalletQueue(this);
7168  d->m_wq->wallet = wallet;
7169  connect(wallet, TQT_SIGNAL(walletOpened(bool)), d->m_wq, TQT_SLOT(walletOpened(bool)));
7170  connect(d->m_wq, TQT_SIGNAL(walletOpened(KWallet::Wallet*)), this, TQT_SLOT(walletOpened(KWallet::Wallet*)));
7171  }
7172  assert(form);
7173  d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->getDocument()));
7174 #endif // KHTML_NO_WALLET
7175 }
7176 
7177 
7178 void KHTMLPart::saveToWallet(const TQString& key, const TQMap<TQString,TQString>& data)
7179 {
7180 #ifndef KHTML_NO_WALLET
7181  KHTMLPart *p;
7182 
7183  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
7184  }
7185 
7186  if (p) {
7187  p->saveToWallet(key, data);
7188  return;
7189  }
7190 
7191  if (d->m_wallet) {
7192  if (d->m_bWalletOpened) {
7193  if (d->m_wallet->isOpen()) {
7194  if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
7195  d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
7196  }
7197  d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
7198  d->m_wallet->writeMap(key, data);
7199  return;
7200  }
7201  d->m_wallet->deleteLater();
7202  d->m_wallet = 0L;
7203  d->m_bWalletOpened = false;
7204  }
7205  }
7206 
7207  if (!d->m_wq) {
7208  KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
7209  d->m_wq = new KHTMLWalletQueue(this);
7210  d->m_wq->wallet = wallet;
7211  connect(wallet, TQT_SIGNAL(walletOpened(bool)), d->m_wq, TQT_SLOT(walletOpened(bool)));
7212  connect(d->m_wq, TQT_SIGNAL(walletOpened(KWallet::Wallet*)), this, TQT_SLOT(walletOpened(KWallet::Wallet*)));
7213  }
7214  d->m_wq->savers.append(qMakePair(key, data));
7215 #endif // KHTML_NO_WALLET
7216 }
7217 
7218 
7219 void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
7220 #ifndef KHTML_NO_WALLET
7221  KHTMLPart *p;
7222 
7223  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
7224  }
7225 
7226  if (p) {
7227  p->dequeueWallet(form);
7228  return;
7229  }
7230 
7231  if (d->m_wq) {
7232  d->m_wq->callers.remove(KHTMLWalletQueue::Caller(form, form->getDocument()));
7233  }
7234 #endif // KHTML_NO_WALLET
7235 }
7236 
7237 
7238 void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
7239 #ifndef KHTML_NO_WALLET
7240  assert(!d->m_wallet);
7241  assert(d->m_wq);
7242 
7243  d->m_wq->deleteLater(); // safe?
7244  d->m_wq = 0L;
7245 
7246  if (!wallet) {
7247  d->m_bWalletOpened = false;
7248  return;
7249  }
7250 
7251  d->m_wallet = wallet;
7252  d->m_bWalletOpened = true;
7253  connect(d->m_wallet, TQT_SIGNAL(walletClosed()), TQT_SLOT(slotWalletClosed()));
7254 
7255  if (!d->m_statusBarWalletLabel) {
7256  d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
7257  d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
7258  d->m_statusBarWalletLabel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
7259  d->m_statusBarWalletLabel->setUseCursor(false);
7260  d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
7261  d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
7262  connect(d->m_statusBarWalletLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(launchWalletManager()));
7263  connect(d->m_statusBarWalletLabel, TQT_SIGNAL(rightClickedURL()), TQT_SLOT(walletMenu()));
7264  } else {
7265  TQToolTip::remove(d->m_statusBarWalletLabel);
7266  }
7267  TQToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
7268 #endif // KHTML_NO_WALLET
7269 }
7270 
7271 
7272 KWallet::Wallet *KHTMLPart::wallet()
7273 {
7274 #ifndef KHTML_NO_WALLET
7275  KHTMLPart *p;
7276 
7277  for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
7278  ;
7279 
7280  if (p)
7281  return p->wallet();
7282 
7283 #endif // KHTML_NO_WALLET
7284  return d->m_wallet;
7285 }
7286 
7287 
7288 void KHTMLPart::slotWalletClosed()
7289 {
7290 #ifndef KHTML_NO_WALLET
7291  if (d->m_wallet) {
7292  d->m_wallet->deleteLater();
7293  d->m_wallet = 0L;
7294  }
7295  d->m_bWalletOpened = false;
7296  if (d->m_statusBarWalletLabel) {
7297  d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
7298  delete d->m_statusBarWalletLabel;
7299  d->m_statusBarWalletLabel = 0L;
7300  }
7301 #endif // KHTML_NO_WALLET
7302 }
7303 
7304 void KHTMLPart::launchWalletManager()
7305 {
7306 #ifndef KHTML_NO_WALLET
7307  if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
7308  KApplication::startServiceByDesktopName("kwalletmanager_show");
7309  } else {
7310  DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
7311  r.send("show");
7312  r.send("raise");
7313  }
7314 #endif // KHTML_NO_WALLET
7315 }
7316 
7317 void KHTMLPart::walletMenu()
7318 {
7319 #ifndef KHTML_NO_WALLET
7320  KPopupMenu *m = new KPopupMenu(0L);
7321  m->insertItem(i18n("&Close Wallet"), this, TQT_SLOT(slotWalletClosed()));
7322  m->popup(TQCursor::pos());
7323 #endif // KHTML_NO_WALLET
7324 }
7325 
7326 void KHTMLPart::slotToggleCaretMode()
7327 {
7328  setCaretMode(d->m_paToggleCaretMode->isChecked());
7329 }
7330 
7331 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
7332  d->m_formNotification = fn;
7333 }
7334 
7335 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
7336  return d->m_formNotification;
7337 }
7338 
7339 KURL KHTMLPart::toplevelURL()
7340 {
7341  KHTMLPart* part = this;
7342  while (part->parentPart())
7343  part = part->parentPart();
7344 
7345  if (!part)
7346  return KURL();
7347 
7348  return part->url();
7349 }
7350 
7351 bool KHTMLPart::isModified() const
7352 {
7353  if ( !d->m_doc )
7354  return false;
7355 
7356  return d->m_doc->unsubmittedFormChanges();
7357 }
7358 
7359 void KHTMLPart::setDebugScript( bool enable )
7360 {
7361  unplugActionList( "debugScriptList" );
7362  if ( enable ) {
7363  if (!d->m_paDebugScript) {
7364  d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, TQT_SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
7365  }
7366  d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
7367  TQPtrList<KAction> lst;
7368  lst.append( d->m_paDebugScript );
7369  plugActionList( "debugScriptList", lst );
7370  }
7371  d->m_bJScriptDebugEnabled = enable;
7372 }
7373 
7374 void KHTMLPart::setSuppressedPopupIndicator( bool enable )
7375 {
7376  setSuppressedPopupIndicator( enable, 0 );
7377 }
7378 
7379 void KHTMLPart::setSuppressedPopupIndicator( bool enable, KHTMLPart *originPart )
7380 {
7381  if ( parentPart() ) {
7382  parentPart()->setSuppressedPopupIndicator( enable, originPart );
7383  return;
7384  }
7385 
7386  if ( enable && originPart ) {
7387  d->m_openableSuppressedPopups++;
7388  if ( d->m_suppressedPopupOriginParts.findIndex( originPart ) == -1 )
7389  d->m_suppressedPopupOriginParts.append( originPart );
7390  }
7391 
7392  if ( enable && !d->m_statusBarPopupLabel ) {
7393  d->m_statusBarPopupLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
7394  d->m_statusBarPopupLabel->setFixedHeight( instance()->iconLoader()->currentSize( KIcon::Small) );
7395  d->m_statusBarPopupLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ));
7396  d->m_statusBarPopupLabel->setUseCursor( false );
7397  d->m_statusBarExtension->addStatusBarItem( d->m_statusBarPopupLabel, 0, false );
7398  d->m_statusBarPopupLabel->setPixmap( SmallIcon( "window_suppressed", instance() ) );
7399  TQToolTip::add( d->m_statusBarPopupLabel, i18n("This page was prevented from opening a new window via JavaScript." ) );
7400 
7401  connect(d->m_statusBarPopupLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(suppressedPopupMenu()));
7402  if (d->m_settings->jsPopupBlockerPassivePopup()) {
7403  TQPixmap px;
7404  px = MainBarIcon( "window_suppressed" );
7405  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);
7406  }
7407  } else if ( !enable && d->m_statusBarPopupLabel ) {
7408  TQToolTip::remove( d->m_statusBarPopupLabel );
7409  d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarPopupLabel );
7410  delete d->m_statusBarPopupLabel;
7411  d->m_statusBarPopupLabel = 0L;
7412  }
7413 }
7414 
7415 void KHTMLPart::suppressedPopupMenu() {
7416  KPopupMenu *m = new KPopupMenu(0L);
7417  m->setCheckable(true);
7418  if ( d->m_openableSuppressedPopups )
7419  m->insertItem(i18n("&Show Blocked Popup Window","Show %n Blocked Popup Windows", d->m_openableSuppressedPopups), this, TQT_SLOT(showSuppressedPopups()));
7420  m->insertItem(i18n("Show Blocked Window Passive Popup &Notification"), this, TQT_SLOT(togglePopupPassivePopup()),0,57);
7421  m->setItemChecked(57,d->m_settings->jsPopupBlockerPassivePopup());
7422  m->insertItem(i18n("&Configure JavaScript New Window Policies..."), this, TQT_SLOT(launchJSConfigDialog()));
7423  m->popup(TQCursor::pos());
7424 }
7425 
7426 void KHTMLPart::togglePopupPassivePopup() {
7427  // Same hack as in disableJSErrorExtension()
7428  d->m_settings->setJSPopupBlockerPassivePopup( !d->m_settings->jsPopupBlockerPassivePopup() );
7429  DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", TQByteArray());
7430 }
7431 
7432 void KHTMLPart::showSuppressedPopups() {
7433  for ( TQValueListIterator<TQGuardedPtr<KHTMLPart> > i = d->m_suppressedPopupOriginParts.begin();
7434  i != d->m_suppressedPopupOriginParts.end(); ++i ) {
7435  if (KHTMLPart* part = *i) {
7436  KJS::Window *w = KJS::Window::retrieveWindow( part );
7437  if (w) {
7438  w->showSuppressedWindows();
7439  w->forgetSuppressedWindows();
7440  }
7441  }
7442  }
7443  setSuppressedPopupIndicator( false );
7444  d->m_openableSuppressedPopups = 0;
7445  d->m_suppressedPopupOriginParts.clear();
7446 }
7447 
7448 // Extension to use for "view document source", "save as" etc.
7449 // Using the right extension can help the viewer get into the right mode (#40496)
7450 TQString KHTMLPart::defaultExtension() const
7451 {
7452  if ( !d->m_doc )
7453  return ".html";
7454  if ( !d->m_doc->isHTMLDocument() )
7455  return ".xml";
7456  return d->m_doc->htmlMode() == DOM::DocumentImpl::XHtml ? ".xhtml" : ".html";
7457 }
7458 
7459 bool KHTMLPart::inProgress() const
7460 {
7461  if (d->m_runningScripts || (d->m_doc && d->m_doc->parsing()))
7462  return true;
7463 
7464  // Any frame that hasn't completed yet ?
7465  ConstFrameIt it = d->m_frames.begin();
7466  const ConstFrameIt end = d->m_frames.end();
7467  for (; it != end; ++it ) {
7468  if ((*it)->m_run || !(*it)->m_bCompleted)
7469  return true;
7470  }
7471 
7472  return d->m_submitForm || !d->m_redirectURL.isEmpty() || d->m_redirectionTimer.isActive() || d->m_job;
7473 }
7474 
7475 using namespace KParts;
7476 #include "khtml_part.moc"
7477 #include "khtmlpart_p.moc"

khtml

Skip menu "khtml"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

khtml

Skip menu "khtml"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for khtml by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |