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

tdehtml

  • tdehtml
tdehtmlview.cpp
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
4  * 1999 Lars Knoll <knoll@kde.org>
5  * 1999 Antti Koivisto <koivisto@kde.org>
6  * 2000-2004 Dirk Mueller <mueller@kde.org>
7  * 2003 Leo Savernik <l.savernik@aon.at>
8  * 2003-2004 Apple Computer, Inc.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB. If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25 
26 
27 #include "tdehtmlview.moc"
28 
29 #include "tdehtmlview.h"
30 
31 #include "tdehtml_part.h"
32 #include "tdehtml_events.h"
33 
34 #include "html/html_documentimpl.h"
35 #include "html/html_inlineimpl.h"
36 #include "html/html_formimpl.h"
37 #include "rendering/render_arena.h"
38 #include "rendering/render_canvas.h"
39 #include "rendering/render_frames.h"
40 #include "rendering/render_replaced.h"
41 #include "rendering/render_layer.h"
42 #include "rendering/render_line.h"
43 #include "rendering/render_table.h"
44 // removeme
45 #define protected public
46 #include "rendering/render_text.h"
47 #undef protected
48 #include "xml/dom2_eventsimpl.h"
49 #include "css/cssstyleselector.h"
50 #include "css/csshelper.h"
51 #include "misc/htmlhashes.h"
52 #include "misc/helper.h"
53 #include "misc/loader.h"
54 #include "tdehtml_settings.h"
55 #include "tdehtml_printsettings.h"
56 
57 #include "tdehtmlpart_p.h"
58 
59 #ifndef TDEHTML_NO_CARET
60 #include "tdehtml_caret_p.h"
61 #include "xml/dom2_rangeimpl.h"
62 #endif
63 
64 #include <tdeapplication.h>
65 #include <kcursor.h>
66 #include <kdebug.h>
67 #include <kdialogbase.h>
68 #include <kiconloader.h>
69 #include <kimageio.h>
70 #include <tdelocale.h>
71 #include <knotifyclient.h>
72 #include <kprinter.h>
73 #include <ksimpleconfig.h>
74 #include <kstandarddirs.h>
75 #include <tdestdaccel.h>
76 #include <kstringhandler.h>
77 #include <kurldrag.h>
78 
79 #include <tqbitmap.h>
80 #include <tqlabel.h>
81 #include <tqobjectlist.h>
82 #include <tqpaintdevicemetrics.h>
83 #include <tqpainter.h>
84 #include <tqptrdict.h>
85 #include <tqtooltip.h>
86 #include <tqstring.h>
87 #include <tqstylesheet.h>
88 #include <tqtimer.h>
89 #include <tqvaluevector.h>
90 
91 //#define DEBUG_NO_PAINT_BUFFER
92 
93 //#define DEBUG_FLICKER
94 
95 //#define DEBUG_PIXEL
96 
97 #ifdef TQ_WS_X11
98 #include <X11/Xlib.h>
99 #include <fixx11h.h>
100 #endif
101 
102 #define PAINT_BUFFER_HEIGHT 128
103 
104 #if 0
105 namespace tdehtml {
106  void dumpLineBoxes(RenderFlow *flow);
107 }
108 #endif
109 
110 using namespace DOM;
111 using namespace tdehtml;
112 class TDEHTMLToolTip;
113 
114 
115 #ifndef TQT_NO_TOOLTIP
116 
117 class TDEHTMLToolTip : public TQToolTip
118 {
119 public:
120  TDEHTMLToolTip(TDEHTMLView *view, TDEHTMLViewPrivate* vp) : TQToolTip(view->viewport())
121  {
122  m_view = view;
123  m_viewprivate = vp;
124  };
125 
126 protected:
127  virtual void maybeTip(const TQPoint &);
128 
129 private:
130  TDEHTMLView *m_view;
131  TDEHTMLViewPrivate* m_viewprivate;
132 };
133 
134 #endif
135 
136 class TDEHTMLViewPrivate {
137  friend class TDEHTMLToolTip;
138 public:
139 
140  enum PseudoFocusNodes {
141  PFNone,
142  PFTop,
143  PFBottom
144  };
145 
146  enum CompletedState {
147  CSNone = 0,
148  CSFull,
149  CSActionPending
150  };
151 
152  TDEHTMLViewPrivate()
153  : underMouse( 0 ), underMouseNonShared( 0 ), visibleWidgets( 107 )
154 #ifndef NO_SMOOTH_SCROLL_HACK
155  , dx(0), dy(0), ddx(0), ddy(0), rdx(0), rdy(0), scrolling(false)
156 #endif
157  {
158 #ifndef TDEHTML_NO_CARET
159  m_caretViewContext = 0;
160  m_editorContext = 0;
161 #endif // TDEHTML_NO_CARET
162  postponed_autorepeat = NULL;
163  reset();
164  vmode = TQScrollView::Auto;
165  hmode = TQScrollView::Auto;
166  tp=0;
167  paintBuffer=0;
168  vertPaintBuffer=0;
169  formCompletions=0;
170  prevScrollbarVisible = true;
171  tooltip = 0;
172  possibleTripleClick = false;
173  emitCompletedAfterRepaint = CSNone;
174  cursor_icon_widget = NULL;
175  m_mouseScrollTimer = 0;
176  m_mouseScrollIndicator = 0;
177  }
178  ~TDEHTMLViewPrivate()
179  {
180  delete formCompletions;
181  delete tp; tp = 0;
182  delete paintBuffer; paintBuffer =0;
183  delete vertPaintBuffer;
184  delete postponed_autorepeat;
185  if (underMouse)
186  underMouse->deref();
187  if (underMouseNonShared)
188  underMouseNonShared->deref();
189  delete tooltip;
190 #ifndef TDEHTML_NO_CARET
191  delete m_caretViewContext;
192  delete m_editorContext;
193 #endif // TDEHTML_NO_CARET
194  delete cursor_icon_widget;
195  delete m_mouseScrollTimer;
196  delete m_mouseScrollIndicator;
197  }
198  void reset()
199  {
200  if (underMouse)
201  underMouse->deref();
202  underMouse = 0;
203  if (underMouseNonShared)
204  underMouseNonShared->deref();
205  underMouseNonShared = 0;
206  linkPressed = false;
207  useSlowRepaints = false;
208  tabMovePending = false;
209  lastTabbingDirection = true;
210  pseudoFocusNode = PFNone;
211 #ifndef TDEHTML_NO_SCROLLBARS
212  //We don't turn off the toolbars here
213  //since if the user turns them
214  //off, then chances are they want them turned
215  //off always - even after a reset.
216 #else
217  vmode = TQScrollView::AlwaysOff;
218  hmode = TQScrollView::AlwaysOff;
219 #endif
220 #ifdef DEBUG_PIXEL
221  timer.start();
222  pixelbooth = 0;
223  repaintbooth = 0;
224 #endif
225  scrollBarMoved = false;
226  contentsMoving = false;
227  ignoreWheelEvents = false;
228  borderX = 30;
229  borderY = 30;
230  paged = false;
231  clickX = -1;
232  clickY = -1;
233  prevMouseX = -1;
234  prevMouseY = -1;
235  clickCount = 0;
236  isDoubleClick = false;
237  scrollingSelf = false;
238  delete postponed_autorepeat;
239  postponed_autorepeat = NULL;
240  layoutTimerId = 0;
241  repaintTimerId = 0;
242  scrollTimerId = 0;
243  scrollSuspended = false;
244  scrollSuspendPreActivate = false;
245  complete = false;
246  firstRelayout = true;
247  needsFullRepaint = true;
248  dirtyLayout = false;
249  layoutSchedulingEnabled = true;
250  painting = false;
251  updateRegion = TQRegion();
252  m_dialogsAllowed = true;
253 #ifndef TDEHTML_NO_CARET
254  if (m_caretViewContext) {
255  m_caretViewContext->caretMoved = false;
256  m_caretViewContext->keyReleasePending = false;
257  }/*end if*/
258 #endif // TDEHTML_NO_CARET
259 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
260  typeAheadActivated = false;
261 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
262  accessKeysActivated = false;
263  accessKeysPreActivate = false;
264 
265  // We ref/deref to ensure defaultHTMLSettings is available
266  TDEHTMLFactory::ref();
267  accessKeysEnabled = TDEHTMLFactory::defaultHTMLSettings()->accessKeysEnabled();
268  TDEHTMLFactory::deref();
269 
270  emitCompletedAfterRepaint = CSNone;
271  }
272  void newScrollTimer(TQWidget *view, int tid)
273  {
274  //kdDebug(6000) << "newScrollTimer timer " << tid << endl;
275  view->killTimer(scrollTimerId);
276  scrollTimerId = tid;
277  scrollSuspended = false;
278  }
279  enum ScrollDirection { ScrollLeft, ScrollRight, ScrollUp, ScrollDown };
280 
281  void adjustScroller(TQWidget *view, ScrollDirection direction, ScrollDirection oppositedir)
282  {
283  static const struct { int msec, pixels; } timings [] = {
284  {320,1}, {224,1}, {160,1}, {112,1}, {80,1}, {56,1}, {40,1},
285  {28,1}, {20,1}, {20,2}, {20,3}, {20,4}, {20,6}, {20,8}, {0,0}
286  };
287  if (!scrollTimerId ||
288  (static_cast<int>(scrollDirection) != direction &&
289  (static_cast<int>(scrollDirection) != oppositedir || scrollSuspended))) {
290  scrollTiming = 6;
291  scrollBy = timings[scrollTiming].pixels;
292  scrollDirection = direction;
293  newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
294  } else if (scrollDirection == direction &&
295  timings[scrollTiming+1].msec && !scrollSuspended) {
296  scrollBy = timings[++scrollTiming].pixels;
297  newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
298  } else if (scrollDirection == oppositedir) {
299  if (scrollTiming) {
300  scrollBy = timings[--scrollTiming].pixels;
301  newScrollTimer(view, view->startTimer(timings[scrollTiming].msec));
302  }
303  }
304  scrollSuspended = false;
305  }
306 
307 #ifndef TDEHTML_NO_CARET
311  CaretViewContext *caretViewContext() {
312  if (!m_caretViewContext) m_caretViewContext = new CaretViewContext();
313  return m_caretViewContext;
314  }
318  EditorContext *editorContext() {
319  if (!m_editorContext) m_editorContext = new EditorContext();
320  return m_editorContext;
321  }
322 #endif // TDEHTML_NO_CARET
323 
324 #ifdef DEBUG_PIXEL
325  TQTime timer;
326  unsigned int pixelbooth;
327  unsigned int repaintbooth;
328 #endif
329 
330  TQPainter *tp;
331  TQPixmap *paintBuffer;
332  TQPixmap *vertPaintBuffer;
333  NodeImpl *underMouse;
334  NodeImpl *underMouseNonShared;
335 
336  bool tabMovePending:1;
337  bool lastTabbingDirection:1;
338  PseudoFocusNodes pseudoFocusNode:2;
339  bool scrollBarMoved:1;
340  bool contentsMoving:1;
341 
342  TQScrollView::ScrollBarMode vmode;
343  TQScrollView::ScrollBarMode hmode;
344  bool prevScrollbarVisible:1;
345  bool linkPressed:1;
346  bool useSlowRepaints:1;
347  bool ignoreWheelEvents:1;
348 
349  int borderX, borderY;
350  KSimpleConfig *formCompletions;
351 
352  bool paged;
353 
354  int clickX, clickY, clickCount;
355  bool isDoubleClick;
356 
357  int prevMouseX, prevMouseY;
358  bool scrollingSelf;
359  int layoutTimerId;
360  TQKeyEvent* postponed_autorepeat;
361 
362  int repaintTimerId;
363  int scrollTimerId;
364  int scrollTiming;
365  int scrollBy;
366  ScrollDirection scrollDirection :2;
367  bool scrollSuspended :1;
368  bool scrollSuspendPreActivate :1;
369  bool complete :1;
370  bool firstRelayout :1;
371  bool layoutSchedulingEnabled :1;
372  bool needsFullRepaint :1;
373  bool painting :1;
374  bool possibleTripleClick :1;
375  bool dirtyLayout :1;
376  bool m_dialogsAllowed :1;
377  TQRegion updateRegion;
378  TDEHTMLToolTip *tooltip;
379  TQPtrDict<TQWidget> visibleWidgets;
380 #ifndef TDEHTML_NO_CARET
381  CaretViewContext *m_caretViewContext;
382  EditorContext *m_editorContext;
383 #endif // TDEHTML_NO_CARET
384 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
385  TQString findString;
386  TQTimer timer;
387  bool findLinksOnly;
388  bool typeAheadActivated;
389 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
390  bool accessKeysEnabled;
391  bool accessKeysActivated;
392  bool accessKeysPreActivate;
393  CompletedState emitCompletedAfterRepaint;
394 
395  TQWidget* cursor_icon_widget;
396 
397  // scrolling activated by MMB
398  short m_mouseScroll_byX;
399  short m_mouseScroll_byY;
400  TQTimer *m_mouseScrollTimer;
401  TQWidget *m_mouseScrollIndicator;
402 #ifndef NO_SMOOTH_SCROLL_HACK
403  TQTimer timer2;
404  int dx;
405  int dy;
406  // Step size * 16 and residual to avoid huge difference between 1px/step and 2px/step
407  int ddx;
408  int ddy;
409  int rdx;
410  int rdy;
411  bool scrolling;
412 #endif
413 };
414 
415 #ifndef TQT_NO_TOOLTIP
416 
426 static bool findImageMapRect(HTMLImageElementImpl *img, const TQPoint &scrollOfs,
427  const TQPoint &p, TQRect &r, TQString &s)
428 {
429  HTMLMapElementImpl* map;
430  if (img && img->getDocument()->isHTMLDocument() &&
431  (map = static_cast<HTMLDocumentImpl*>(img->getDocument())->getMap(img->imageMap()))) {
432  RenderObject::NodeInfo info(true, false);
433  RenderObject *rend = img->renderer();
434  int ax, ay;
435  if (!rend || !rend->absolutePosition(ax, ay))
436  return false;
437  // we're a client side image map
438  bool inside = map->mapMouseEvent(p.x() - ax + scrollOfs.x(),
439  p.y() - ay + scrollOfs.y(), rend->contentWidth(),
440  rend->contentHeight(), info);
441  if (inside && info.URLElement()) {
442  HTMLAreaElementImpl *area = static_cast<HTMLAreaElementImpl *>(info.URLElement());
443  Q_ASSERT(area->id() == ID_AREA);
444  s = area->getAttribute(ATTR_TITLE).string();
445  TQRegion reg = area->cachedRegion();
446  if (!s.isEmpty() && !reg.isEmpty()) {
447  r = reg.boundingRect();
448  r.moveBy(ax, ay);
449  return true;
450  }
451  }
452  }
453  return false;
454 }
455 
456 void TDEHTMLToolTip::maybeTip(const TQPoint& p)
457 {
458  DOM::NodeImpl *node = m_viewprivate->underMouseNonShared;
459  TQRect region;
460  while ( node ) {
461  if ( node->isElementNode() ) {
462  DOM::ElementImpl *e = static_cast<DOM::ElementImpl*>( node );
463  TQRect r;
464  TQString s;
465  bool found = false;
466  // for images, check if it is part of a client-side image map,
467  // and query the <area>s' title attributes, too
468  if (e->id() == ID_IMG && !e->getAttribute( ATTR_USEMAP ).isEmpty()) {
469  found = findImageMapRect(static_cast<HTMLImageElementImpl *>(e),
470  m_view->viewportToContents(TQPoint(0, 0)), p, r, s);
471  }
472  if (!found) {
473  s = e->getAttribute( ATTR_TITLE ).string();
474  r = node->getRect();
475  }
476  region |= TQRect( m_view->contentsToViewport( r.topLeft() ), r.size() );
477  if ( !s.isEmpty() ) {
478  tip( region, TQStyleSheet::convertFromPlainText( s, TQStyleSheetItem::WhiteSpaceNormal ) );
479  break;
480  }
481  }
482  node = node->parentNode();
483  }
484 }
485 #endif
486 
487 TDEHTMLView::TDEHTMLView( TDEHTMLPart *part, TQWidget *parent, const char *name)
488  : TQScrollView( parent, name, (WFlags)(WResizeNoErase | WRepaintNoErase) )
489 {
490  m_medium = "screen";
491 
492  m_part = part;
493  d = new TDEHTMLViewPrivate;
494  TQScrollView::setVScrollBarMode(d->vmode);
495  TQScrollView::setHScrollBarMode(d->hmode);
496  connect(kapp, TQ_SIGNAL(tdedisplayPaletteChanged()), this, TQ_SLOT(slotPaletteChanged()));
497  connect(this, TQ_SIGNAL(contentsMoving(int, int)), this, TQ_SLOT(slotScrollBarMoved()));
498 
499  // initialize QScrollView
500  enableClipper(true);
501  // hack to get unclipped painting on the viewport.
502  static_cast<TDEHTMLView *>(viewport())->setWFlags(WPaintUnclipped);
503 
504  setResizePolicy(Manual);
505  viewport()->setMouseTracking(true);
506  viewport()->setBackgroundMode(NoBackground);
507 
508  KImageIO::registerFormats();
509 
510 #ifndef TQT_NO_TOOLTIP
511  d->tooltip = new TDEHTMLToolTip( this, d );
512 #endif
513 
514 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
515  connect(&d->timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(findTimeout()));
516 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
517 
518  init();
519 
520  viewport()->show();
521 #ifndef NO_SMOOTH_SCROLL_HACK
522 #define timer timer2
523  connect(&d->timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(scrollTick()));
524 #undef timer
525 #endif
526 }
527 
528 TDEHTMLView::~TDEHTMLView()
529 {
530  closeChildDialogs();
531  if (m_part)
532  {
533  //WABA: Is this Ok? Do I need to deref it as well?
534  //Does this need to be done somewhere else?
535  DOM::DocumentImpl *doc = m_part->xmlDocImpl();
536  if (doc)
537  doc->detach();
538  }
539  delete d; d = 0;
540 }
541 
542 void TDEHTMLView::init()
543 {
544  if(!d->paintBuffer) d->paintBuffer = new TQPixmap(PAINT_BUFFER_HEIGHT, PAINT_BUFFER_HEIGHT);
545  if(!d->vertPaintBuffer)
546  d->vertPaintBuffer = new TQPixmap(10, PAINT_BUFFER_HEIGHT);
547  if(!d->tp) d->tp = new TQPainter();
548 
549  setFocusPolicy(TQWidget::StrongFocus);
550  viewport()->setFocusProxy(this);
551 
552  _marginWidth = -1; // undefined
553  _marginHeight = -1;
554  _width = 0;
555  _height = 0;
556 
557  installEventFilter(this);
558 
559  setAcceptDrops(true);
560  TQSize s = viewportSize(4095, 4095);
561  resizeContents(s.width(), s.height());
562 }
563 
564 void TDEHTMLView::clear()
565 {
566  // work around QScrollview's unbelievable bugginess
567  setStaticBackground(true);
568 #ifndef TDEHTML_NO_CARET
569  if (!m_part->isCaretMode() && !m_part->isEditable()) caretOff();
570 #endif
571 
572 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
573  if( d->typeAheadActivated )
574  findTimeout();
575 #endif
576  if (d->accessKeysEnabled && d->accessKeysActivated)
577  accessKeysTimeout();
578  viewport()->unsetCursor();
579  if ( d->cursor_icon_widget )
580  d->cursor_icon_widget->hide();
581  d->reset();
582  this->killTimers();
583  emit cleared();
584 
585  TQScrollView::setHScrollBarMode(d->hmode);
586  TQScrollView::setVScrollBarMode(d->vmode);
587  verticalScrollBar()->setEnabled( false );
588  horizontalScrollBar()->setEnabled( false );
589 }
590 
591 void TDEHTMLView::hideEvent(TQHideEvent* e)
592 {
593  TQScrollView::hideEvent(e);
594  if ( m_part && m_part->xmlDocImpl() )
595  m_part->xmlDocImpl()->docLoader()->pauseAnimations();
596 }
597 
598 void TDEHTMLView::showEvent(TQShowEvent* e)
599 {
600  TQScrollView::showEvent(e);
601  if ( m_part && m_part->xmlDocImpl() )
602  m_part->xmlDocImpl()->docLoader()->resumeAnimations();
603 }
604 
605 void TDEHTMLView::resizeEvent (TQResizeEvent* e)
606 {
607  int dw = e->oldSize().width() - e->size().width();
608  int dh = e->oldSize().height() - e->size().height();
609 
610  // if we are shrinking the view, don't allow the content to overflow
611  // before the layout occurs - we don't know if we need scrollbars yet
612  dw = dw>0 ? kMax(0, contentsWidth()-dw) : contentsWidth();
613  dh = dh>0 ? kMax(0, contentsHeight()-dh) : contentsHeight();
614 
615  resizeContents(dw, dh);
616 
617  TQScrollView::resizeEvent(e);
618 
619  if ( m_part && m_part->xmlDocImpl() )
620  m_part->xmlDocImpl()->dispatchWindowEvent( EventImpl::RESIZE_EVENT, false, false );
621 }
622 
623 void TDEHTMLView::viewportResizeEvent (TQResizeEvent* e)
624 {
625  TQScrollView::viewportResizeEvent(e);
626 
627  //int w = visibleWidth();
628  //int h = visibleHeight();
629 
630  if (d->layoutSchedulingEnabled)
631  layout();
632 #ifndef TDEHTML_NO_CARET
633  else {
634  hideCaret();
635  recalcAndStoreCaretPos();
636  showCaret();
637  }/*end if*/
638 #endif
639 
640  TDEApplication::sendPostedEvents(viewport(), TQEvent::Paint);
641 }
642 
643 // this is to get rid of a compiler virtual overload mismatch warning. do not remove
644 void TDEHTMLView::drawContents( TQPainter*)
645 {
646 }
647 
648 void TDEHTMLView::drawContents( TQPainter *p, int ex, int ey, int ew, int eh )
649 {
650 #ifdef DEBUG_PIXEL
651 
652  if ( d->timer.elapsed() > 5000 ) {
653  tqDebug( "drawed %d pixels in %d repaints the last %d milliseconds",
654  d->pixelbooth, d->repaintbooth, d->timer.elapsed() );
655  d->timer.restart();
656  d->pixelbooth = 0;
657  d->repaintbooth = 0;
658  }
659  d->pixelbooth += ew*eh;
660  d->repaintbooth++;
661 #endif
662 
663  //kdDebug( 6000 ) << "drawContents this="<< this <<" x=" << ex << ",y=" << ey << ",w=" << ew << ",h=" << eh << endl;
664  if(!m_part || !m_part->xmlDocImpl() || !m_part->xmlDocImpl()->renderer()) {
665  p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
666  return;
667  } else if ( d->complete && static_cast<RenderCanvas*>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
668  // an external update request happens while we have a layout scheduled
669  unscheduleRelayout();
670  layout();
671  }
672 
673  if (d->painting) {
674  kdDebug( 6000 ) << "WARNING: drawContents reentered! " << endl;
675  return;
676  }
677  d->painting = true;
678 
679  TQPoint pt = contentsToViewport(TQPoint(ex, ey));
680  TQRegion cr = TQRect(pt.x(), pt.y(), ew, eh);
681 
682  // kdDebug(6000) << "clip rect: " << TQRect(pt.x(), pt.y(), ew, eh) << endl;
683  for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
684  TQWidget *w = it.current();
685  RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
686  if (w && rw && !rw->isTDEHTMLWidget()) {
687  int x, y;
688  rw->absolutePosition(x, y);
689  contentsToViewport(x, y, x, y);
690  int pbx = rw->borderLeft()+rw->paddingLeft();
691  int pby = rw->borderTop()+rw->paddingTop();
692  TQRect g = TQRect(x+pbx, y+pby,
693  rw->width()-pbx-rw->borderRight()-rw->paddingRight(),
694  rw->height()-pby-rw->borderBottom()-rw->paddingBottom());
695  if ( !rw->isFrame() && ((g.top() > pt.y()+eh) || (g.bottom() <= pt.y()) ||
696  (g.right() <= pt.x()) || (g.left() > pt.x()+ew) ))
697  continue;
698  RenderLayer* rl = rw->needsMask() ? rw->enclosingStackingContext() : 0;
699  TQRegion mask = rl ? rl->getMask() : TQRegion();
700  if (!mask.isNull()) {
701  TQPoint o(0,0);
702  o = contentsToViewport(o);
703  mask.translate(o.x(),o.y());
704  mask = mask.intersect( TQRect(g.x(),g.y(),g.width(),g.height()) );
705  cr -= mask;
706  } else {
707  cr -= g;
708  }
709  }
710  }
711 
712 #if 0
713  // this is commonly the case with framesets. we still do
714  // want to paint them, otherwise the widgets don't get placed.
715  if (cr.isEmpty()) {
716  d->painting = false;
717  return;
718  }
719 #endif
720 
721 #ifndef DEBUG_NO_PAINT_BUFFER
722  p->setClipRegion(cr);
723 
724  if (eh > PAINT_BUFFER_HEIGHT && ew <= 10) {
725  if ( d->vertPaintBuffer->height() < visibleHeight() )
726  d->vertPaintBuffer->resize(10, visibleHeight());
727  d->tp->begin(d->vertPaintBuffer);
728  d->tp->translate(-ex, -ey);
729  d->tp->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
730  m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey, ew, eh));
731  d->tp->end();
732  p->drawPixmap(ex, ey, *d->vertPaintBuffer, 0, 0, ew, eh);
733  }
734  else {
735  if ( d->paintBuffer->width() < visibleWidth() )
736  d->paintBuffer->resize(visibleWidth(),PAINT_BUFFER_HEIGHT);
737 
738  int py=0;
739  while (py < eh) {
740  int ph = eh-py < PAINT_BUFFER_HEIGHT ? eh-py : PAINT_BUFFER_HEIGHT;
741  d->tp->begin(d->paintBuffer);
742  d->tp->translate(-ex, -ey-py);
743  d->tp->fillRect(ex, ey+py, ew, ph, palette().active().brush(TQColorGroup::Base));
744  m_part->xmlDocImpl()->renderer()->layer()->paint(d->tp, TQRect(ex, ey+py, ew, ph));
745  d->tp->end();
746 
747  p->drawPixmap(ex, ey+py, *d->paintBuffer, 0, 0, ew, ph);
748  py += PAINT_BUFFER_HEIGHT;
749  }
750  }
751 #else // !DEBUG_NO_PAINT_BUFFER
752 static int cnt=0;
753  ex = contentsX(); ey = contentsY();
754  ew = visibleWidth(); eh = visibleHeight();
755  TQRect pr(ex,ey,ew,eh);
756  kdDebug() << "[" << ++cnt << "]" << " clip region: " << pr << endl;
757 // p->setClipRegion(TQRect(0,0,ew,eh));
758 // p->translate(-ex, -ey);
759  p->fillRect(ex, ey, ew, eh, palette().active().brush(TQColorGroup::Base));
760  m_part->xmlDocImpl()->renderer()->layer()->paint(p, pr);
761 #endif // DEBUG_NO_PAINT_BUFFER
762 
763 #ifndef TDEHTML_NO_CARET
764  if (d->m_caretViewContext && d->m_caretViewContext->visible) {
765  TQRect pos(d->m_caretViewContext->x, d->m_caretViewContext->y,
766  d->m_caretViewContext->width, d->m_caretViewContext->height);
767  if (pos.intersects(TQRect(ex, ey, ew, eh))) {
768  p->setRasterOp(XorROP);
769  p->setPen(white);
770  if (pos.width() == 1)
771  p->drawLine(pos.topLeft(), pos.bottomRight());
772  else {
773  p->fillRect(pos, white);
774  }/*end if*/
775  }/*end if*/
776  }/*end if*/
777 #endif // TDEHTML_NO_CARET
778 
779 // p->setPen(TQPen(magenta,0,DashDotDotLine));
780 // p->drawRect(dbg_paint_rect);
781 
782  tdehtml::DrawContentsEvent event( p, ex, ey, ew, eh );
783  TQApplication::sendEvent( m_part, &event );
784 
785  d->painting = false;
786 }
787 
788 void TDEHTMLView::setMarginWidth(int w)
789 {
790  // make it update the rendering area when set
791  _marginWidth = w;
792 }
793 
794 void TDEHTMLView::setMarginHeight(int h)
795 {
796  // make it update the rendering area when set
797  _marginHeight = h;
798 }
799 
800 void TDEHTMLView::layout()
801 {
802  if( m_part && m_part->xmlDocImpl() ) {
803  DOM::DocumentImpl *document = m_part->xmlDocImpl();
804 
805  tdehtml::RenderCanvas* canvas = static_cast<tdehtml::RenderCanvas *>(document->renderer());
806  if ( !canvas ) return;
807 
808  d->layoutSchedulingEnabled=false;
809 
810  // the reference object for the overflow property on canvas
811  RenderObject * ref = 0;
812  RenderObject* root = document->documentElement() ? document->documentElement()->renderer() : 0;
813 
814  if (document->isHTMLDocument()) {
815  NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
816  if(body && body->renderer() && body->id() == ID_FRAMESET) {
817  TQScrollView::setVScrollBarMode(AlwaysOff);
818  TQScrollView::setHScrollBarMode(AlwaysOff);
819  body->renderer()->setNeedsLayout(true);
820 // if (d->tooltip) {
821 // delete d->tooltip;
822 // d->tooltip = 0;
823 // }
824  }
825  else {
826  if (!d->tooltip)
827  d->tooltip = new TDEHTMLToolTip( this, d );
828  // only apply body's overflow to canvas if root as a visible overflow
829  if (root)
830  ref = (!body || root->style()->hidesOverflow()) ? root : body->renderer();
831  }
832  } else {
833  ref = root;
834  }
835  if (ref) {
836  if( ref->style()->overflowX() == OHIDDEN ) {
837  if (d->hmode == Auto) TQScrollView::setHScrollBarMode(AlwaysOff);
838  } else if (ref->style()->overflowX() == OSCROLL ) {
839  if (d->hmode == Auto) TQScrollView::setHScrollBarMode(AlwaysOn);
840  } else {
841  if (TQScrollView::hScrollBarMode() == AlwaysOff) TQScrollView::setHScrollBarMode(d->hmode);
842  } if ( ref->style()->overflowY() == OHIDDEN ) {
843  if (d->vmode == Auto) TQScrollView::setVScrollBarMode(AlwaysOff);
844  } else if (ref->style()->overflowY() == OSCROLL ) {
845  if (d->vmode == Auto) TQScrollView::setVScrollBarMode(AlwaysOn);
846  } else {
847  if (TQScrollView::vScrollBarMode() == AlwaysOff) TQScrollView::setVScrollBarMode(d->vmode);
848  }
849  }
850  d->needsFullRepaint = d->firstRelayout;
851  if (_height != visibleHeight() || _width != visibleWidth()) {;
852  d->needsFullRepaint = true;
853  _height = visibleHeight();
854  _width = visibleWidth();
855  }
856  //TQTime qt;
857  //qt.start();
858  canvas->layout();
859 
860  emit finishedLayout();
861  if (d->firstRelayout) {
862  // make sure firstRelayout is set to false now in case this layout
863  // wasn't scheduled
864  d->firstRelayout = false;
865  verticalScrollBar()->setEnabled( true );
866  horizontalScrollBar()->setEnabled( true );
867  }
868 #if 0
869  ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
870  if (listitem) kdDebug(6000) << "after layout, before repaint" << endl;
871  if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
872 #endif
873 #ifndef TDEHTML_NO_CARET
874  hideCaret();
875  if ((m_part->isCaretMode() || m_part->isEditable())
876  && !d->complete && d->m_caretViewContext
877  && !d->m_caretViewContext->caretMoved) {
878  initCaret();
879  } else {
880  recalcAndStoreCaretPos();
881  showCaret();
882  }/*end if*/
883 #endif
884  if (d->accessKeysEnabled && d->accessKeysActivated) {
885  emit hideAccessKeys();
886  displayAccessKeys();
887  }
888  //kdDebug( 6000 ) << "TIME: layout() dt=" << qt.elapsed() << endl;
889  }
890  else
891  _width = visibleWidth();
892 
893  killTimer(d->layoutTimerId);
894  d->layoutTimerId = 0;
895  d->layoutSchedulingEnabled=true;
896 }
897 
898 void TDEHTMLView::closeChildDialogs()
899 {
900  TQObjectList *dlgs = queryList("TQDialog");
901  for (TQObject *dlg = dlgs->first(); dlg; dlg = dlgs->next())
902  {
903  KDialogBase* dlgbase = dynamic_cast<KDialogBase *>( dlg );
904  if ( dlgbase ) {
905  if ( dlgbase->testWFlags( WShowModal ) ) {
906  kdDebug(6000) << "closeChildDialogs: closing dialog " << dlgbase << endl;
907  // close() ends up calling TQButton::animateClick, which isn't immediate
908  // we need something the exits the event loop immediately (#49068)
909  dlgbase->cancel();
910  }
911  }
912  else
913  {
914  kdWarning() << "closeChildDialogs: not a KDialogBase! Don't use QDialogs in KDE! " << static_cast<TQWidget*>(dlg) << endl;
915  static_cast<TQWidget*>(dlg)->hide();
916  }
917  }
918  delete dlgs;
919  d->m_dialogsAllowed = false;
920 }
921 
922 bool TDEHTMLView::dialogsAllowed() {
923  bool allowed = d->m_dialogsAllowed;
924  TDEHTMLPart* p = m_part->parentPart();
925  if (p && p->view())
926  allowed &= p->view()->dialogsAllowed();
927  return allowed;
928 }
929 
930 void TDEHTMLView::closeEvent( TQCloseEvent* ev )
931 {
932  closeChildDialogs();
933  TQScrollView::closeEvent( ev );
934 }
935 
936 //
937 // Event Handling
938 //
940 
941 void TDEHTMLView::viewportMousePressEvent( TQMouseEvent *_mouse )
942 {
943  if (!m_part->xmlDocImpl()) return;
944  if (d->possibleTripleClick && ( _mouse->button() & TQt::MouseButtonMask ) == TQt::LeftButton)
945  {
946  viewportMouseDoubleClickEvent( _mouse ); // it handles triple clicks too
947  return;
948  }
949 
950  int xm, ym;
951  viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
952  //kdDebug( 6000 ) << "mousePressEvent: viewport=("<<_mouse->x()<<"/"<<_mouse->y()<<"), contents=(" << xm << "/" << ym << ")\n";
953 
954  d->isDoubleClick = false;
955 
956  DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MousePress );
957  m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
958 
959  //kdDebug(6000) << "innerNode="<<mev.innerNode.nodeName().string()<<endl;
960 
961  if ( (_mouse->button() == TQt::MidButton) &&
962  !m_part->d->m_bOpenMiddleClick && !d->m_mouseScrollTimer &&
963  mev.url.isNull() && (mev.innerNode.elementId() != ID_INPUT) ) {
964  TQPoint point = mapFromGlobal( _mouse->globalPos() );
965 
966  d->m_mouseScroll_byX = 0;
967  d->m_mouseScroll_byY = 0;
968 
969  d->m_mouseScrollTimer = new TQTimer( this );
970  connect( d->m_mouseScrollTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotMouseScrollTimer()) );
971 
972  if ( !d->m_mouseScrollIndicator ) {
973  TQPixmap pixmap, icon;
974  pixmap.resize( 48, 48 );
975  pixmap.fill( TQColor( tqRgba( 127, 127, 127, 127 ) ) );
976 
977  TQPainter p( &pixmap );
978  icon = TDEGlobal::iconLoader()->loadIcon( "1uparrow", TDEIcon::Small );
979  p.drawPixmap( 16, 0, icon );
980  icon = TDEGlobal::iconLoader()->loadIcon( "1leftarrow", TDEIcon::Small );
981  p.drawPixmap( 0, 16, icon );
982  icon = TDEGlobal::iconLoader()->loadIcon( "1downarrow", TDEIcon::Small );
983  p.drawPixmap( 16, 32,icon );
984  icon = TDEGlobal::iconLoader()->loadIcon( "1rightarrow", TDEIcon::Small );
985  p.drawPixmap( 32, 16, icon );
986  p.drawEllipse( 23, 23, 2, 2 );
987 
988  d->m_mouseScrollIndicator = new TQWidget( this, 0 );
989  d->m_mouseScrollIndicator->setFixedSize( 48, 48 );
990  d->m_mouseScrollIndicator->setPaletteBackgroundPixmap( pixmap );
991  }
992  d->m_mouseScrollIndicator->move( point.x()-24, point.y()-24 );
993 
994  bool hasHorBar = visibleWidth() < contentsWidth();
995  bool hasVerBar = visibleHeight() < contentsHeight();
996 
997  TDEConfig *config = TDEGlobal::config();
998  TDEConfigGroupSaver saver( config, "HTML Settings" );
999  if ( config->readBoolEntry( "ShowMouseScrollIndicator", true ) ) {
1000  d->m_mouseScrollIndicator->show();
1001  d->m_mouseScrollIndicator->unsetCursor();
1002 
1003  TQBitmap mask = d->m_mouseScrollIndicator->paletteBackgroundPixmap()->createHeuristicMask( true );
1004 
1005  if ( hasHorBar && !hasVerBar ) {
1006  TQBitmap bm( 16, 16, true );
1007  bitBlt( &mask, 16, 0, &bm, 0, 0, -1, -1 );
1008  bitBlt( &mask, 16, 32, &bm, 0, 0, -1, -1 );
1009  d->m_mouseScrollIndicator->setCursor( KCursor::SizeHorCursor );
1010  }
1011  else if ( !hasHorBar && hasVerBar ) {
1012  TQBitmap bm( 16, 16, true );
1013  bitBlt( &mask, 0, 16, &bm, 0, 0, -1, -1 );
1014  bitBlt( &mask, 32, 16, &bm, 0, 0, -1, -1 );
1015  d->m_mouseScrollIndicator->setCursor( KCursor::SizeVerCursor );
1016  }
1017  else
1018  d->m_mouseScrollIndicator->setCursor( KCursor::SizeAllCursor );
1019 
1020  d->m_mouseScrollIndicator->setMask( mask );
1021  }
1022  else {
1023  if ( hasHorBar && !hasVerBar )
1024  viewport()->setCursor( KCursor::SizeHorCursor );
1025  else if ( !hasHorBar && hasVerBar )
1026  viewport()->setCursor( KCursor::SizeVerCursor );
1027  else
1028  viewport()->setCursor( KCursor::SizeAllCursor );
1029  }
1030 
1031  return;
1032  }
1033  else if ( d->m_mouseScrollTimer ) {
1034  delete d->m_mouseScrollTimer;
1035  d->m_mouseScrollTimer = 0;
1036 
1037  if ( d->m_mouseScrollIndicator )
1038  d->m_mouseScrollIndicator->hide();
1039  }
1040 
1041  d->clickCount = 1;
1042  d->clickX = xm;
1043  d->clickY = ym;
1044 
1045  bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
1046  d->clickCount,_mouse,true,DOM::NodeImpl::MousePress);
1047 
1048  tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1049  if (r && r->isWidget())
1050  _mouse->ignore();
1051 
1052  if (!swallowEvent) {
1053  emit m_part->nodeActivated(mev.innerNode);
1054 
1055  tdehtml::MousePressEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
1056  TQApplication::sendEvent( m_part, &event );
1057  // we might be deleted after this
1058  }
1059 }
1060 
1061 void TDEHTMLView::viewportMouseDoubleClickEvent( TQMouseEvent *_mouse )
1062 {
1063  if(!m_part->xmlDocImpl()) return;
1064 
1065  int xm, ym;
1066  viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
1067 
1068  kdDebug( 6000 ) << "mouseDblClickEvent: x=" << xm << ", y=" << ym << endl;
1069 
1070  d->isDoubleClick = true;
1071 
1072  DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseDblClick );
1073  m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
1074 
1075  // We do the same thing as viewportMousePressEvent() here, since the DOM does not treat
1076  // single and double-click events as separate (only the detail, i.e. number of clicks differs)
1077  if (d->clickCount > 0 &&
1078  TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance())
1079  d->clickCount++;
1080  else { // shouldn't happen, if Qt has the same criterias for double clicks.
1081  d->clickCount = 1;
1082  d->clickX = xm;
1083  d->clickY = ym;
1084  }
1085  bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEDOWN_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
1086  d->clickCount,_mouse,true,DOM::NodeImpl::MouseDblClick);
1087 
1088  tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1089  if (r && r->isWidget())
1090  _mouse->ignore();
1091 
1092  if (!swallowEvent) {
1093  tdehtml::MouseDoubleClickEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode, d->clickCount );
1094  TQApplication::sendEvent( m_part, &event );
1095  }
1096 
1097  d->possibleTripleClick=true;
1098  TQTimer::singleShot(TQApplication::doubleClickInterval(),this,TQ_SLOT(tripleClickTimeout()));
1099 }
1100 
1101 void TDEHTMLView::tripleClickTimeout()
1102 {
1103  d->possibleTripleClick = false;
1104  d->clickCount = 0;
1105 }
1106 
1107 static inline void forwardPeripheralEvent(tdehtml::RenderWidget* r, TQMouseEvent* me, int x, int y)
1108 {
1109  int absx = 0;
1110  int absy = 0;
1111  r->absolutePosition(absx, absy);
1112  TQPoint p(x-absx, y-absy);
1113  TQMouseEvent fw(me->type(), p, me->button(), me->state());
1114  TQWidget* w = r->widget();
1115  TQScrollView* sc = ::tqt_cast<TQScrollView*>(w);
1116  if (sc && !::tqt_cast<TQListBox*>(w))
1117  static_cast<tdehtml::RenderWidget::ScrollViewEventPropagator*>(sc)->sendEvent(static_cast<TQEvent*>(&fw));
1118  else if(w)
1119  static_cast<tdehtml::RenderWidget::EventPropagator*>(w)->sendEvent(static_cast<TQEvent*>(&fw));
1120 }
1121 
1122 
1123 static bool targetOpensNewWindow(TDEHTMLPart *part, TQString target)
1124 {
1125  if (!target.isEmpty() && (target.lower() != "_top") &&
1126  (target.lower() != "_self") && (target.lower() != "_parent")) {
1127  if (target.lower() == "_blank")
1128  return true;
1129  else {
1130  while (part->parentPart())
1131  part = part->parentPart();
1132  if (!part->frameExists(target))
1133  return true;
1134  }
1135  }
1136  return false;
1137 }
1138 
1139 void TDEHTMLView::viewportMouseMoveEvent( TQMouseEvent * _mouse )
1140 {
1141  if ( d->m_mouseScrollTimer ) {
1142  TQPoint point = mapFromGlobal( _mouse->globalPos() );
1143 
1144  int deltaX = point.x() - d->m_mouseScrollIndicator->x() - 24;
1145  int deltaY = point.y() - d->m_mouseScrollIndicator->y() - 24;
1146 
1147  (deltaX > 0) ? d->m_mouseScroll_byX = 1 : d->m_mouseScroll_byX = -1;
1148  (deltaY > 0) ? d->m_mouseScroll_byY = 1 : d->m_mouseScroll_byY = -1;
1149 
1150  double adX = TQABS(deltaX)/30.0;
1151  double adY = TQABS(deltaY)/30.0;
1152 
1153  d->m_mouseScroll_byX = kMax(kMin(d->m_mouseScroll_byX * int(adX*adX), SHRT_MAX), SHRT_MIN);
1154  d->m_mouseScroll_byY = kMax(kMin(d->m_mouseScroll_byY * int(adY*adY), SHRT_MAX), SHRT_MIN);
1155 
1156  if (d->m_mouseScroll_byX == 0 && d->m_mouseScroll_byY == 0) {
1157  d->m_mouseScrollTimer->stop();
1158  }
1159  else if (!d->m_mouseScrollTimer->isActive()) {
1160  d->m_mouseScrollTimer->changeInterval( 20 );
1161  }
1162  }
1163 
1164  if(!m_part->xmlDocImpl()) return;
1165 
1166  int xm, ym;
1167  viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
1168 
1169  DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseMove );
1170  // Do not modify :hover/:active state while mouse is pressed.
1171  m_part->xmlDocImpl()->prepareMouseEvent( _mouse->state() & TQt::MouseButtonMask /*readonly ?*/, xm, ym, &mev );
1172 
1173 // kdDebug(6000) << "mouse move: " << _mouse->pos()
1174 // << " button " << _mouse->button()
1175 // << " state " << _mouse->state() << endl;
1176 
1177  bool swallowEvent = dispatchMouseEvent(EventImpl::MOUSEMOVE_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),false,
1178  0,_mouse,true,DOM::NodeImpl::MouseMove);
1179 
1180  if (d->clickCount > 0 &&
1181  TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() > TQApplication::startDragDistance()) {
1182  d->clickCount = 0; // moving the mouse outside the threshold invalidates the click
1183  }
1184 
1185  // execute the scheduled script. This is to make sure the mouseover events come after the mouseout events
1186  m_part->executeScheduledScript();
1187 
1188  DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1189  if (fn && fn != mev.innerNode.handle() &&
1190  fn->renderer() && fn->renderer()->isWidget()) {
1191  forwardPeripheralEvent(static_cast<tdehtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
1192  }
1193 
1194  tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1195  tdehtml::RenderStyle* style = (r && r->style()) ? r->style() : 0;
1196  TQCursor c;
1197  bool mailtoCursor = false;
1198  bool newWindowCursor = false;
1199  switch ( style ? style->cursor() : CURSOR_AUTO) {
1200  case CURSOR_AUTO:
1201  if ( r && r->isText() )
1202  c = KCursor::ibeamCursor();
1203  if ( mev.url.length() && m_part->settings()->changeCursor() ) {
1204  c = m_part->urlCursor();
1205  if (mev.url.string().startsWith("mailto:") && mev.url.string().find('@')>0)
1206  mailtoCursor = true;
1207  else
1208  newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
1209  }
1210 
1211  if (r && r->isFrameSet() && !static_cast<RenderFrameSet*>(r)->noResize())
1212  c = TQCursor(static_cast<RenderFrameSet*>(r)->cursorShape());
1213 
1214  break;
1215  case CURSOR_CROSS:
1216  c = KCursor::crossCursor();
1217  break;
1218  case CURSOR_POINTER:
1219  c = m_part->urlCursor();
1220  if (mev.url.string().startsWith("mailto:") && mev.url.string().find('@')>0)
1221  mailtoCursor = true;
1222  else
1223  newWindowCursor = targetOpensNewWindow( m_part, mev.target.string() );
1224  break;
1225  case CURSOR_PROGRESS:
1226  c = KCursor::workingCursor();
1227  break;
1228  case CURSOR_MOVE:
1229  c = KCursor::sizeAllCursor();
1230  break;
1231  case CURSOR_E_RESIZE:
1232  case CURSOR_W_RESIZE:
1233  c = KCursor::sizeHorCursor();
1234  break;
1235  case CURSOR_N_RESIZE:
1236  case CURSOR_S_RESIZE:
1237  c = KCursor::sizeVerCursor();
1238  break;
1239  case CURSOR_NE_RESIZE:
1240  case CURSOR_SW_RESIZE:
1241  c = KCursor::sizeBDiagCursor();
1242  break;
1243  case CURSOR_NW_RESIZE:
1244  case CURSOR_SE_RESIZE:
1245  c = KCursor::sizeFDiagCursor();
1246  break;
1247  case CURSOR_TEXT:
1248  c = KCursor::ibeamCursor();
1249  break;
1250  case CURSOR_WAIT:
1251  c = KCursor::waitCursor();
1252  break;
1253  case CURSOR_HELP:
1254  c = KCursor::whatsThisCursor();
1255  break;
1256  case CURSOR_DEFAULT:
1257  break;
1258  }
1259 
1260  if ( viewport()->cursor().handle() != c.handle() ) {
1261  if( c.handle() == KCursor::arrowCursor().handle()) {
1262  for (TDEHTMLPart* p = m_part; p; p = p->parentPart())
1263  p->view()->viewport()->unsetCursor();
1264  }
1265  else {
1266  viewport()->setCursor( c );
1267  }
1268  }
1269 
1270  if ( ( mailtoCursor || newWindowCursor ) && isVisible() && hasFocus() ) {
1271 #ifdef TQ_WS_X11
1272  TQPixmap icon_pixmap = TDEGlobal::iconLoader()->loadIcon( mailtoCursor ? "mail_generic" : "window-new", TDEIcon::Small, 0, TDEIcon::DefaultState, 0, true );
1273 
1274  if (d->cursor_icon_widget) {
1275  const TQPixmap *pm = d->cursor_icon_widget->backgroundPixmap();
1276  if (!pm || pm->serialNumber()!=icon_pixmap.serialNumber()) {
1277  delete d->cursor_icon_widget;
1278  d->cursor_icon_widget = 0;
1279  }
1280  }
1281 
1282  if( !d->cursor_icon_widget ) {
1283  d->cursor_icon_widget = new TQWidget( NULL, NULL, WX11BypassWM );
1284  XSetWindowAttributes attr;
1285  attr.save_under = True;
1286  XChangeWindowAttributes( tqt_xdisplay(), d->cursor_icon_widget->winId(), CWSaveUnder, &attr );
1287  d->cursor_icon_widget->resize( icon_pixmap.width(), icon_pixmap.height());
1288  if( icon_pixmap.mask() )
1289  d->cursor_icon_widget->setMask( *icon_pixmap.mask());
1290  else
1291  d->cursor_icon_widget->clearMask();
1292  d->cursor_icon_widget->setBackgroundPixmap( icon_pixmap );
1293  d->cursor_icon_widget->erase();
1294  }
1295  TQPoint c_pos = TQCursor::pos();
1296  d->cursor_icon_widget->move( c_pos.x() + 15, c_pos.y() + 15 );
1297  XRaiseWindow( tqt_xdisplay(), d->cursor_icon_widget->winId());
1298  TQApplication::flushX();
1299  d->cursor_icon_widget->show();
1300 #endif
1301  }
1302  else if ( d->cursor_icon_widget )
1303  d->cursor_icon_widget->hide();
1304 
1305  if (r && r->isWidget()) {
1306  _mouse->ignore();
1307  }
1308 
1309 
1310  d->prevMouseX = xm;
1311  d->prevMouseY = ym;
1312 
1313  if (!swallowEvent) {
1314  tdehtml::MouseMoveEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
1315  TQApplication::sendEvent( m_part, &event );
1316  }
1317 }
1318 
1319 void TDEHTMLView::viewportMouseReleaseEvent( TQMouseEvent * _mouse )
1320 {
1321  bool swallowEvent = false;
1322  int xm, ym;
1323  viewportToContents(_mouse->x(), _mouse->y(), xm, ym);
1324  DOM::NodeImpl::MouseEvent mev( _mouse->stateAfter(), DOM::NodeImpl::MouseRelease );
1325 
1326  if ( m_part->xmlDocImpl() )
1327  {
1328  m_part->xmlDocImpl()->prepareMouseEvent( false, xm, ym, &mev );
1329 
1330  swallowEvent = dispatchMouseEvent(EventImpl::MOUSEUP_EVENT,mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
1331  d->clickCount,_mouse,false,DOM::NodeImpl::MouseRelease);
1332 
1333  if (d->clickCount > 0 &&
1334  TQPoint(d->clickX-xm,d->clickY-ym).manhattanLength() <= TQApplication::startDragDistance()) {
1335  TQMouseEvent me(d->isDoubleClick ? TQEvent::MouseButtonDblClick : TQEvent::MouseButtonRelease,
1336  _mouse->pos(), _mouse->button(), _mouse->state());
1337  dispatchMouseEvent(EventImpl::CLICK_EVENT, mev.innerNode.handle(),mev.innerNonSharedNode.handle(),true,
1338  d->clickCount, &me, true, DOM::NodeImpl::MouseRelease);
1339  }
1340 
1341  DOM::NodeImpl* fn = m_part->xmlDocImpl()->focusNode();
1342  if (fn && fn != mev.innerNode.handle() &&
1343  fn->renderer() && fn->renderer()->isWidget() &&
1344  _mouse->button() != TQt::MidButton) {
1345  forwardPeripheralEvent(static_cast<tdehtml::RenderWidget*>(fn->renderer()), _mouse, xm, ym);
1346  }
1347 
1348  tdehtml::RenderObject* r = mev.innerNode.handle() ? mev.innerNode.handle()->renderer() : 0;
1349  if (r && r->isWidget())
1350  _mouse->ignore();
1351  }
1352 
1353  if (!swallowEvent) {
1354  tdehtml::MouseReleaseEvent event( _mouse, xm, ym, mev.url, mev.target, mev.innerNode );
1355  TQApplication::sendEvent( m_part, &event );
1356  }
1357 }
1358 
1359 // returns true if event should be swallowed
1360 bool TDEHTMLView::dispatchKeyEvent( TQKeyEvent *_ke )
1361 {
1362  if (!m_part->xmlDocImpl())
1363  return false;
1364  // Pressing and releasing a key should generate keydown, keypress and keyup events
1365  // Holding it down should generated keydown, keypress (repeatedly) and keyup events
1366  // The problem here is that Qt generates two autorepeat events (keyrelease+keypress)
1367  // for autorepeating, while DOM wants only one autorepeat event (keypress), so one
1368  // of the Qt events shouldn't be passed to DOM, but it should be still filtered
1369  // out if DOM would filter the autorepeat event. Additional problem is that Qt keyrelease
1370  // events don't have text() set (Qt bug?), so DOM often would ignore the keypress event
1371  // if it was created using Qt keyrelease, but Qt autorepeat keyrelease comes
1372  // before Qt autorepeat keypress (i.e. problem whether to filter it out or not).
1373  // The solution is to filter out and postpone the Qt autorepeat keyrelease until
1374  // the following Qt keypress event comes. If DOM accepts the DOM keypress event,
1375  // the postponed event will be simply discarded. If not, it will be passed to keyPressEvent()
1376  // again, and here it will be ignored.
1377  //
1378  // Qt: Press | Release(autorepeat) Press(autorepeat) etc. | Release
1379  // DOM: Down + Press | (nothing) Press | Up
1380 
1381  // It's also possible to get only Releases. E.g. the release of alt-tab,
1382  // or when the keypresses get captured by an accel.
1383 
1384  if( _ke == d->postponed_autorepeat ) // replayed event
1385  {
1386  return false;
1387  }
1388 
1389  if( _ke->type() == TQEvent::KeyPress )
1390  {
1391  if( !_ke->isAutoRepeat())
1392  {
1393  bool ret = dispatchKeyEventHelper( _ke, false ); // keydown
1394  // don't send keypress even if keydown was blocked, like IE (and unlike Mozilla)
1395  if( !ret && dispatchKeyEventHelper( _ke, true )) // keypress
1396  ret = true;
1397  return ret;
1398  }
1399  else // autorepeat
1400  {
1401  bool ret = dispatchKeyEventHelper( _ke, true ); // keypress
1402  if( !ret && d->postponed_autorepeat )
1403  keyPressEvent( d->postponed_autorepeat );
1404  delete d->postponed_autorepeat;
1405  d->postponed_autorepeat = NULL;
1406  return ret;
1407  }
1408  }
1409  else // TQEvent::KeyRelease
1410  {
1411  // Discard postponed "autorepeat key-release" events that didn't see
1412  // a keypress after them (e.g. due to TQAccel)
1413  if ( d->postponed_autorepeat ) {
1414  delete d->postponed_autorepeat;
1415  d->postponed_autorepeat = 0;
1416  }
1417 
1418  if( !_ke->isAutoRepeat()) {
1419  return dispatchKeyEventHelper( _ke, false ); // keyup
1420  }
1421  else
1422  {
1423  d->postponed_autorepeat = new TQKeyEvent( _ke->type(), _ke->key(), _ke->ascii(), _ke->state(),
1424  _ke->text(), _ke->isAutoRepeat(), _ke->count());
1425  if( _ke->isAccepted())
1426  d->postponed_autorepeat->accept();
1427  else
1428  d->postponed_autorepeat->ignore();
1429  return true;
1430  }
1431  }
1432 }
1433 
1434 // returns true if event should be swallowed
1435 bool TDEHTMLView::dispatchKeyEventHelper( TQKeyEvent *_ke, bool keypress )
1436 {
1437  DOM::NodeImpl* keyNode = m_part->xmlDocImpl()->focusNode();
1438  if (keyNode) {
1439  return keyNode->dispatchKeyEvent(_ke, keypress);
1440  } else { // no focused node, send to document
1441  return m_part->xmlDocImpl()->dispatchKeyEvent(_ke, keypress);
1442  }
1443 }
1444 
1445 void TDEHTMLView::keyPressEvent( TQKeyEvent *_ke )
1446 {
1447 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
1448  if(d->typeAheadActivated)
1449  {
1450  // type-ahead find aka find-as-you-type
1451  if(_ke->key() == Key_BackSpace)
1452  {
1453  d->findString = d->findString.left(d->findString.length() - 1);
1454 
1455  if(!d->findString.isEmpty())
1456  {
1457  findAhead(false);
1458  }
1459  else
1460  {
1461  findTimeout();
1462  }
1463 
1464  d->timer.start(3000, true);
1465  _ke->accept();
1466  return;
1467  }
1468  else if(_ke->key() == Key_Escape)
1469  {
1470  findTimeout();
1471 
1472  _ke->accept();
1473  return;
1474  }
1475  else if(_ke->key() == Key_Space || !TQString(_ke->text()).stripWhiteSpace().isEmpty())
1476  {
1477  d->findString += _ke->text();
1478 
1479  findAhead(true);
1480 
1481  d->timer.start(3000, true);
1482  _ke->accept();
1483  return;
1484  }
1485  }
1486 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
1487 
1488 #ifndef TDEHTML_NO_CARET
1489  if (m_part->isEditable() || m_part->isCaretMode()
1490  || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
1491  && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
1492  d->caretViewContext()->keyReleasePending = true;
1493  caretKeyPressEvent(_ke);
1494  return;
1495  }
1496 #endif // TDEHTML_NO_CARET
1497 
1498  // If CTRL was hit, be prepared for access keys
1499  if (d->accessKeysEnabled && _ke->key() == Key_Control && _ke->state()==0 && !d->accessKeysActivated)
1500  {
1501  d->accessKeysPreActivate=true;
1502  _ke->accept();
1503  return;
1504  }
1505 
1506  if (_ke->key() == Key_Shift && _ke->state()==0)
1507  d->scrollSuspendPreActivate=true;
1508 
1509  // accesskey handling needs to be done before dispatching, otherwise e.g. lineedits
1510  // may eat the event
1511 
1512  if (d->accessKeysEnabled && d->accessKeysActivated)
1513  {
1514  int state = ( _ke->state() & ( ShiftButton | ControlButton | AltButton | MetaButton ));
1515  if ( state==0 || state==ShiftButton) {
1516  if (_ke->key() != Key_Shift) accessKeysTimeout();
1517  handleAccessKey( _ke );
1518  _ke->accept();
1519  return;
1520  }
1521  accessKeysTimeout();
1522  }
1523 
1524  if ( dispatchKeyEvent( _ke )) {
1525  // If either keydown or keypress was accepted by a widget, or canceled by JS, stop here.
1526  _ke->accept();
1527  return;
1528  }
1529 
1530  int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
1531  if (_ke->state() & TQt::ShiftButton)
1532  switch(_ke->key())
1533  {
1534  case Key_Space:
1535  scrollBy( 0, -clipper()->height() + offs );
1536  if(d->scrollSuspended)
1537  d->newScrollTimer(this, 0);
1538  break;
1539 
1540  case Key_Down:
1541  case Key_J:
1542  d->adjustScroller(this, TDEHTMLViewPrivate::ScrollDown, TDEHTMLViewPrivate::ScrollUp);
1543  break;
1544 
1545  case Key_Up:
1546  case Key_K:
1547  d->adjustScroller(this, TDEHTMLViewPrivate::ScrollUp, TDEHTMLViewPrivate::ScrollDown);
1548  break;
1549 
1550  case Key_Left:
1551  case Key_H:
1552  d->adjustScroller(this, TDEHTMLViewPrivate::ScrollLeft, TDEHTMLViewPrivate::ScrollRight);
1553  break;
1554 
1555  case Key_Right:
1556  case Key_L:
1557  d->adjustScroller(this, TDEHTMLViewPrivate::ScrollRight, TDEHTMLViewPrivate::ScrollLeft);
1558  break;
1559  }
1560  else
1561  switch ( _ke->key() )
1562  {
1563  case Key_Down:
1564  case Key_J:
1565  if (!d->scrollTimerId || d->scrollSuspended)
1566  scrollBy( 0, 10 * _ke->count() );
1567  if (d->scrollTimerId)
1568  d->newScrollTimer(this, 0);
1569  break;
1570 
1571  case Key_Space:
1572  case Key_Next:
1573  scrollBy( 0, clipper()->height() - offs );
1574  if(d->scrollSuspended)
1575  d->newScrollTimer(this, 0);
1576  break;
1577 
1578  case Key_Up:
1579  case Key_K:
1580  if (!d->scrollTimerId || d->scrollSuspended)
1581  scrollBy( 0, -10 * _ke->count());
1582  if (d->scrollTimerId)
1583  d->newScrollTimer(this, 0);
1584  break;
1585 
1586  case Key_Prior:
1587  scrollBy( 0, -clipper()->height() + offs );
1588  if(d->scrollSuspended)
1589  d->newScrollTimer(this, 0);
1590  break;
1591  case Key_Right:
1592  case Key_L:
1593  if (!d->scrollTimerId || d->scrollSuspended)
1594  scrollBy( 10 * _ke->count(), 0 );
1595  if (d->scrollTimerId)
1596  d->newScrollTimer(this, 0);
1597  break;
1598  case Key_Left:
1599  case Key_H:
1600  if (!d->scrollTimerId || d->scrollSuspended)
1601  scrollBy( -10 * _ke->count(), 0 );
1602  if (d->scrollTimerId)
1603  d->newScrollTimer(this, 0);
1604  break;
1605  case Key_Enter:
1606  case Key_Return:
1607  // ### FIXME:
1608  // or even better to HTMLAnchorElementImpl::event()
1609  if (m_part->xmlDocImpl()) {
1610  NodeImpl *n = m_part->xmlDocImpl()->focusNode();
1611  if (n)
1612  n->setActive();
1613  }
1614  break;
1615  case Key_Home:
1616  setContentsPos( 0, 0 );
1617  if(d->scrollSuspended)
1618  d->newScrollTimer(this, 0);
1619  break;
1620  case Key_End:
1621  setContentsPos( 0, contentsHeight() - visibleHeight() );
1622  if(d->scrollSuspended)
1623  d->newScrollTimer(this, 0);
1624  break;
1625  case Key_Shift:
1626  // what are you doing here?
1627  _ke->ignore();
1628  return;
1629  default:
1630  if (d->scrollTimerId)
1631  d->newScrollTimer(this, 0);
1632  _ke->ignore();
1633  return;
1634  }
1635 
1636  _ke->accept();
1637 }
1638 
1639 void TDEHTMLView::findTimeout()
1640 {
1641 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
1642  d->typeAheadActivated = false;
1643  d->findString = "";
1644  m_part->setStatusBarText(i18n("Find stopped."), TDEHTMLPart::BarDefaultText);
1645  m_part->enableFindAheadActions( true );
1646 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
1647 }
1648 
1649 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
1650 void TDEHTMLView::startFindAhead( bool linksOnly )
1651 {
1652  if( linksOnly )
1653  {
1654  d->findLinksOnly = true;
1655  m_part->setStatusBarText(i18n("Starting -- find links as you type"),
1656  TDEHTMLPart::BarDefaultText);
1657  }
1658  else
1659  {
1660  d->findLinksOnly = false;
1661  m_part->setStatusBarText(i18n("Starting -- find text as you type"),
1662  TDEHTMLPart::BarDefaultText);
1663  }
1664 
1665  m_part->findTextBegin();
1666  d->typeAheadActivated = true;
1667  // disable, so that the shortcut ( / or ' by default ) doesn't interfere
1668  m_part->enableFindAheadActions( false );
1669  d->timer.start(3000, true);
1670 }
1671 
1672 void TDEHTMLView::findAhead(bool increase)
1673 {
1674  TQString status;
1675 
1676  if(d->findLinksOnly)
1677  {
1678  m_part->findText(d->findString, TDEHTMLPart::FindNoPopups |
1679  TDEHTMLPart::FindLinksOnly, this);
1680  if(m_part->findTextNext())
1681  {
1682  status = i18n("Link found: \"%1\".");
1683  }
1684  else
1685  {
1686  if(increase) KNotifyClient::beep();
1687  status = i18n("Link not found: \"%1\".");
1688  }
1689  }
1690  else
1691  {
1692  m_part->findText(d->findString, TDEHTMLPart::FindNoPopups, this);
1693  if(m_part->findTextNext())
1694  {
1695  status = i18n("Text found: \"%1\".");
1696  }
1697  else
1698  {
1699  if(increase) KNotifyClient::beep();
1700  status = i18n("Text not found: \"%1\".");
1701  }
1702  }
1703 
1704  m_part->setStatusBarText(status.arg(d->findString.lower()),
1705  TDEHTMLPart::BarDefaultText);
1706 }
1707 
1708 void TDEHTMLView::updateFindAheadTimeout()
1709 {
1710  if( d->typeAheadActivated )
1711  d->timer.start( 3000, true );
1712 }
1713 
1714 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
1715 
1716 void TDEHTMLView::keyReleaseEvent(TQKeyEvent *_ke)
1717 {
1718 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
1719  if(d->typeAheadActivated) {
1720  _ke->accept();
1721  return;
1722  }
1723 #endif
1724  if (d->m_caretViewContext && d->m_caretViewContext->keyReleasePending) {
1725  //caretKeyReleaseEvent(_ke);
1726  d->m_caretViewContext->keyReleasePending = false;
1727  return;
1728  }
1729 
1730  if( d->scrollSuspendPreActivate && _ke->key() != Key_Shift )
1731  d->scrollSuspendPreActivate = false;
1732  if( _ke->key() == Key_Shift && d->scrollSuspendPreActivate && _ke->state() == TQt::ShiftButton
1733  && !(TDEApplication::keyboardMouseState() & TQt::ShiftButton))
1734  {
1735  if (d->scrollTimerId)
1736  {
1737  d->scrollSuspended = !d->scrollSuspended;
1738 #ifndef NO_SMOOTH_SCROLL_HACK
1739  if( d->scrollSuspended )
1740  stopScrolling();
1741 #endif
1742  }
1743  }
1744 
1745  if (d->accessKeysEnabled)
1746  {
1747  if (d->accessKeysPreActivate && _ke->key() != Key_Control)
1748  d->accessKeysPreActivate=false;
1749  if (d->accessKeysPreActivate && _ke->state() == TQt::ControlButton && !(TDEApplication::keyboardMouseState() & TQt::ControlButton))
1750  {
1751  displayAccessKeys();
1752  m_part->setStatusBarText(i18n("Access Keys activated"),TDEHTMLPart::BarOverrideText);
1753  d->accessKeysActivated = true;
1754  d->accessKeysPreActivate = false;
1755  _ke->accept();
1756  return;
1757  }
1758  else if (d->accessKeysActivated)
1759  {
1760  accessKeysTimeout();
1761  _ke->accept();
1762  return;
1763  }
1764  }
1765 
1766  // Send keyup event
1767  if ( dispatchKeyEvent( _ke ) )
1768  {
1769  _ke->accept();
1770  return;
1771  }
1772 
1773  TQScrollView::keyReleaseEvent(_ke);
1774 }
1775 
1776 void TDEHTMLView::contentsContextMenuEvent ( TQContextMenuEvent * /*ce*/ )
1777 {
1778 // ### what kind of c*** is that ?
1779 #if 0
1780  if (!m_part->xmlDocImpl()) return;
1781  int xm = _ce->x();
1782  int ym = _ce->y();
1783 
1784  DOM::NodeImpl::MouseEvent mev( _ce->state(), DOM::NodeImpl::MouseMove ); // ### not a mouse event!
1785  m_part->xmlDocImpl()->prepareMouseEvent( xm, ym, &mev );
1786 
1787  NodeImpl *targetNode = mev.innerNode.handle();
1788  if (targetNode && targetNode->renderer() && targetNode->renderer()->isWidget()) {
1789  int absx = 0;
1790  int absy = 0;
1791  targetNode->renderer()->absolutePosition(absx,absy);
1792  TQPoint pos(xm-absx,ym-absy);
1793 
1794  TQWidget *w = static_cast<RenderWidget*>(targetNode->renderer())->widget();
1795  TQContextMenuEvent cme(_ce->reason(),pos,_ce->globalPos(),_ce->state());
1796  setIgnoreEvents(true);
1797  TQApplication::sendEvent(w,&cme);
1798  setIgnoreEvents(false);
1799  }
1800 #endif
1801 }
1802 
1803 bool TDEHTMLView::focusNextPrevChild( bool next )
1804 {
1805  // Now try to find the next child
1806  if (m_part->xmlDocImpl() && focusNextPrevNode(next))
1807  {
1808  if (m_part->xmlDocImpl()->focusNode())
1809  kdDebug() << "focusNode.name: "
1810  << m_part->xmlDocImpl()->focusNode()->nodeName().string() << endl;
1811  return true; // focus node found
1812  }
1813 
1814  // If we get here, pass tabbing control up to the next/previous child in our parent
1815  d->pseudoFocusNode = TDEHTMLViewPrivate::PFNone;
1816  if (m_part->parentPart() && m_part->parentPart()->view())
1817  return m_part->parentPart()->view()->focusNextPrevChild(next);
1818 
1819  return TQWidget::focusNextPrevChild(next);
1820 }
1821 
1822 void TDEHTMLView::doAutoScroll()
1823 {
1824  TQPoint pos = TQCursor::pos();
1825  pos = viewport()->mapFromGlobal( pos );
1826 
1827  int xm, ym;
1828  viewportToContents(pos.x(), pos.y(), xm, ym);
1829 
1830  pos = TQPoint(pos.x() - viewport()->x(), pos.y() - viewport()->y());
1831  if ( (pos.y() < 0) || (pos.y() > visibleHeight()) ||
1832  (pos.x() < 0) || (pos.x() > visibleWidth()) )
1833  {
1834  ensureVisible( xm, ym, 0, 5 );
1835 
1836 #ifndef TDEHTML_NO_SELECTION
1837  // extend the selection while scrolling
1838  DOM::Node innerNode;
1839  if (m_part->isExtendingSelection()) {
1840  RenderObject::NodeInfo renderInfo(true/*readonly*/, false/*active*/);
1841  m_part->xmlDocImpl()->renderer()->layer()
1842  ->nodeAtPoint(renderInfo, xm, ym);
1843  innerNode = renderInfo.innerNode();
1844  }/*end if*/
1845 
1846  if (innerNode.handle() && innerNode.handle()->renderer()) {
1847  int absX, absY;
1848  innerNode.handle()->renderer()->absolutePosition(absX, absY);
1849 
1850  m_part->extendSelectionTo(xm, ym, absX, absY, innerNode);
1851  }/*end if*/
1852 #endif // TDEHTML_NO_SELECTION
1853  }
1854 }
1855 
1856 
1857 class HackWidget : public TQWidget
1858 {
1859  public:
1860  inline void setNoErase() { setWFlags(getWFlags()|WRepaintNoErase); }
1861 };
1862 
1863 bool TDEHTMLView::eventFilter(TQObject *o, TQEvent *e)
1864 {
1865  if ( e->type() == TQEvent::AccelOverride ) {
1866  TQKeyEvent* ke = (TQKeyEvent*) e;
1867 //kdDebug(6200) << "TQEvent::AccelOverride" << endl;
1868  if (m_part->isEditable() || m_part->isCaretMode()
1869  || (m_part->xmlDocImpl() && m_part->xmlDocImpl()->focusNode()
1870  && m_part->xmlDocImpl()->focusNode()->contentEditable())) {
1871 //kdDebug(6200) << "editable/navigable" << endl;
1872  if ( (ke->state() & ControlButton) || (ke->state() & ShiftButton) ) {
1873  switch ( ke->key() ) {
1874  case Key_Left:
1875  case Key_Right:
1876  case Key_Up:
1877  case Key_Down:
1878  case Key_Home:
1879  case Key_End:
1880  ke->accept();
1881 //kdDebug(6200) << "eaten" << endl;
1882  return true;
1883  default:
1884  break;
1885  }
1886  }
1887  }
1888  }
1889 
1890  if ( e->type() == TQEvent::Leave ) {
1891  if ( d->cursor_icon_widget )
1892  d->cursor_icon_widget->hide();
1893  m_part->resetHoverText();
1894  }
1895 
1896  TQWidget *view = viewport();
1897 
1898  if (o == view) {
1899  // we need to install an event filter on all children of the viewport to
1900  // be able to get correct stacking of children within the document.
1901  if(e->type() == TQEvent::ChildInserted) {
1902  TQObject *c = static_cast<TQChildEvent*>(e)->child();
1903  if (c->isWidgetType()) {
1904  TQWidget *w = static_cast<TQWidget*>(c);
1905  // don't install the event filter on toplevels
1906  if (w->parentWidget(true) == view) {
1907  if (!strcmp(w->name(), "__tdehtml")) {
1908  w->installEventFilter(this);
1909  w->unsetCursor();
1910  if (!::tqt_cast<TQFrame*>(w))
1911  w->setBackgroundMode( TQWidget::NoBackground );
1912  static_cast<HackWidget *>(w)->setNoErase();
1913  if (!w->childrenListObject().isEmpty()) {
1914  TQObjectListIterator it(w->childrenListObject());
1915  for (; it.current(); ++it) {
1916  TQWidget *widget = ::tqt_cast<TQWidget *>(it.current());
1917  if (widget && !widget->isTopLevel()) {
1918  if (!::tqt_cast<TQFrame*>(w))
1919  widget->setBackgroundMode( TQWidget::NoBackground );
1920  static_cast<HackWidget *>(widget)->setNoErase();
1921  widget->installEventFilter(this);
1922  }
1923  }
1924  }
1925  }
1926  }
1927  }
1928  }
1929  } else if (o->isWidgetType()) {
1930  TQWidget *v = static_cast<TQWidget*>(o);
1931  TQWidget *c = v;
1932  while (v && v != view) {
1933  c = v;
1934  v = v->parentWidget(true);
1935  }
1936 
1937  if (v && !strcmp(c->name(), "__tdehtml")) {
1938  bool block = false;
1939  TQWidget *w = static_cast<TQWidget*>(o);
1940  switch(e->type()) {
1941  case TQEvent::Paint:
1942  if (!allowWidgetPaintEvents) {
1943  // eat the event. Like this we can control exactly when the widget
1944  // get's repainted.
1945  block = true;
1946  int x = 0, y = 0;
1947  TQWidget *v = w;
1948  while (v && v != view) {
1949  x += v->x();
1950  y += v->y();
1951  v = v->parentWidget();
1952  }
1953  viewportToContents( x, y, x, y );
1954  TQPaintEvent *pe = static_cast<TQPaintEvent*>(e);
1955  bool asap = !d->contentsMoving && ::tqt_cast<TQScrollView *>(c);
1956 
1957  // TQScrollView needs fast repaints
1958  if ( asap && !d->painting && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() &&
1959  !static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer())->needsLayout() ) {
1960  repaintContents(x + pe->rect().x(), y + pe->rect().y(),
1961  pe->rect().width(), pe->rect().height(), true);
1962  } else {
1963  scheduleRepaint(x + pe->rect().x(), y + pe->rect().y(),
1964  pe->rect().width(), pe->rect().height(), asap);
1965  }
1966  }
1967  break;
1968  case TQEvent::MouseMove:
1969  case TQEvent::MouseButtonPress:
1970  case TQEvent::MouseButtonRelease:
1971  case TQEvent::MouseButtonDblClick: {
1972  if ( (w->parentWidget() == view || ::tqt_cast<TQScrollView*>(c)) && !::tqt_cast<TQScrollBar *>(w)) {
1973  TQMouseEvent *me = static_cast<TQMouseEvent*>(e);
1974  TQPoint pt = w->mapTo( view, me->pos());
1975  TQMouseEvent me2(me->type(), pt, me->button(), me->state());
1976 
1977  if (e->type() == TQEvent::MouseMove)
1978  viewportMouseMoveEvent(&me2);
1979  else if(e->type() == TQEvent::MouseButtonPress)
1980  viewportMousePressEvent(&me2);
1981  else if(e->type() == TQEvent::MouseButtonRelease)
1982  viewportMouseReleaseEvent(&me2);
1983  else
1984  viewportMouseDoubleClickEvent(&me2);
1985  block = true;
1986  }
1987  break;
1988  }
1989  case TQEvent::KeyPress:
1990  case TQEvent::KeyRelease:
1991  if (w->parentWidget() == view && !::tqt_cast<TQScrollBar *>(w)) {
1992  TQKeyEvent *ke = static_cast<TQKeyEvent*>(e);
1993  if (e->type() == TQEvent::KeyPress)
1994  keyPressEvent(ke);
1995  else
1996  keyReleaseEvent(ke);
1997  block = true;
1998  }
1999  default:
2000  break;
2001  }
2002  if (block) {
2003  //tqDebug("eating event");
2004  return true;
2005  }
2006  }
2007  }
2008 
2009 // kdDebug(6000) <<"passing event on to sv event filter object=" << o->className() << " event=" << e->type() << endl;
2010  return TQScrollView::eventFilter(o, e);
2011 }
2012 
2013 
2014 DOM::NodeImpl *TDEHTMLView::nodeUnderMouse() const
2015 {
2016  return d->underMouse;
2017 }
2018 
2019 DOM::NodeImpl *TDEHTMLView::nonSharedNodeUnderMouse() const
2020 {
2021  return d->underMouseNonShared;
2022 }
2023 
2024 bool TDEHTMLView::scrollTo(const TQRect &bounds)
2025 {
2026  d->scrollingSelf = true; // so scroll events get ignored
2027 
2028  int x, y, xe, ye;
2029  x = bounds.left();
2030  y = bounds.top();
2031  xe = bounds.right();
2032  ye = bounds.bottom();
2033 
2034  //kdDebug(6000)<<"scrolling coords: x="<<x<<" y="<<y<<" width="<<xe-x<<" height="<<ye-y<<endl;
2035 
2036  int deltax;
2037  int deltay;
2038 
2039  int curHeight = visibleHeight();
2040  int curWidth = visibleWidth();
2041 
2042  if (ye-y>curHeight-d->borderY)
2043  ye = y + curHeight - d->borderY;
2044 
2045  if (xe-x>curWidth-d->borderX)
2046  xe = x + curWidth - d->borderX;
2047 
2048  // is xpos of target left of the view's border?
2049  if (x < contentsX() + d->borderX )
2050  deltax = x - contentsX() - d->borderX;
2051  // is xpos of target right of the view's right border?
2052  else if (xe + d->borderX > contentsX() + curWidth)
2053  deltax = xe + d->borderX - ( contentsX() + curWidth );
2054  else
2055  deltax = 0;
2056 
2057  // is ypos of target above upper border?
2058  if (y < contentsY() + d->borderY)
2059  deltay = y - contentsY() - d->borderY;
2060  // is ypos of target below lower border?
2061  else if (ye + d->borderY > contentsY() + curHeight)
2062  deltay = ye + d->borderY - ( contentsY() + curHeight );
2063  else
2064  deltay = 0;
2065 
2066  int maxx = curWidth-d->borderX;
2067  int maxy = curHeight-d->borderY;
2068 
2069  int scrollX,scrollY;
2070 
2071  scrollX = deltax > 0 ? (deltax > maxx ? maxx : deltax) : deltax == 0 ? 0 : (deltax>-maxx ? deltax : -maxx);
2072  scrollY = deltay > 0 ? (deltay > maxy ? maxy : deltay) : deltay == 0 ? 0 : (deltay>-maxy ? deltay : -maxy);
2073 
2074  if (contentsX() + scrollX < 0)
2075  scrollX = -contentsX();
2076  else if (contentsWidth() - visibleWidth() - contentsX() < scrollX)
2077  scrollX = contentsWidth() - visibleWidth() - contentsX();
2078 
2079  if (contentsY() + scrollY < 0)
2080  scrollY = -contentsY();
2081  else if (contentsHeight() - visibleHeight() - contentsY() < scrollY)
2082  scrollY = contentsHeight() - visibleHeight() - contentsY();
2083 
2084  scrollBy(scrollX, scrollY);
2085 
2086  d->scrollingSelf = false;
2087 
2088  if ( (abs(deltax)<=maxx) && (abs(deltay)<=maxy) )
2089  return true;
2090  else return false;
2091 
2092 }
2093 
2094 bool TDEHTMLView::focusNextPrevNode(bool next)
2095 {
2096  // Sets the focus node of the document to be the node after (or if
2097  // next is false, before) the current focus node. Only nodes that
2098  // are selectable (i.e. for which isFocusable() returns true) are
2099  // taken into account, and the order used is that specified in the
2100  // HTML spec (see DocumentImpl::nextFocusNode() and
2101  // DocumentImpl::previousFocusNode() for details).
2102 
2103  DocumentImpl *doc = m_part->xmlDocImpl();
2104  NodeImpl *oldFocusNode = doc->focusNode();
2105 
2106  // See whether we're in the middle of detach. If so, we want to
2107  // clear focus... The document code will be careful to not
2108  // emit events in that case..
2109  if (oldFocusNode && oldFocusNode->renderer() &&
2110  !oldFocusNode->renderer()->parent()) {
2111  doc->setFocusNode(0);
2112  return true;
2113  }
2114 
2115 #if 1
2116  // If the user has scrolled the document, then instead of picking
2117  // the next focusable node in the document, use the first one that
2118  // is within the visible area (if possible).
2119  if (d->scrollBarMoved)
2120  {
2121  NodeImpl *toFocus;
2122  if (next)
2123  toFocus = doc->nextFocusNode(oldFocusNode);
2124  else
2125  toFocus = doc->previousFocusNode(oldFocusNode);
2126 
2127  if (!toFocus && oldFocusNode)
2128  if (next)
2129  toFocus = doc->nextFocusNode(NULL);
2130  else
2131  toFocus = doc->previousFocusNode(NULL);
2132 
2133  while (toFocus && toFocus != oldFocusNode)
2134  {
2135 
2136  TQRect focusNodeRect = toFocus->getRect();
2137  if ((focusNodeRect.left() > contentsX()) && (focusNodeRect.right() < contentsX() + visibleWidth()) &&
2138  (focusNodeRect.top() > contentsY()) && (focusNodeRect.bottom() < contentsY() + visibleHeight())) {
2139  {
2140  TQRect r = toFocus->getRect();
2141  ensureVisible( r.right(), r.bottom());
2142  ensureVisible( r.left(), r.top());
2143  d->scrollBarMoved = false;
2144  d->tabMovePending = false;
2145  d->lastTabbingDirection = next;
2146  d->pseudoFocusNode = TDEHTMLViewPrivate::PFNone;
2147  m_part->xmlDocImpl()->setFocusNode(toFocus);
2148  Node guard(toFocus);
2149  if (!toFocus->hasOneRef() )
2150  {
2151  emit m_part->nodeActivated(Node(toFocus));
2152  }
2153  return true;
2154  }
2155  }
2156  if (next)
2157  toFocus = doc->nextFocusNode(toFocus);
2158  else
2159  toFocus = doc->previousFocusNode(toFocus);
2160 
2161  if (!toFocus && oldFocusNode)
2162  if (next)
2163  toFocus = doc->nextFocusNode(NULL);
2164  else
2165  toFocus = doc->previousFocusNode(NULL);
2166  }
2167 
2168  d->scrollBarMoved = false;
2169  }
2170 #endif
2171 
2172  if (!oldFocusNode && d->pseudoFocusNode == TDEHTMLViewPrivate::PFNone)
2173  {
2174  ensureVisible(contentsX(), next?0:contentsHeight());
2175  d->scrollBarMoved = false;
2176  d->pseudoFocusNode = next?TDEHTMLViewPrivate::PFTop:TDEHTMLViewPrivate::PFBottom;
2177  return true;
2178  }
2179 
2180  NodeImpl *newFocusNode = NULL;
2181 
2182  if (d->tabMovePending && next != d->lastTabbingDirection)
2183  {
2184  //kdDebug ( 6000 ) << " tab move pending and tabbing direction changed!\n";
2185  newFocusNode = oldFocusNode;
2186  }
2187  else if (next)
2188  {
2189  if (oldFocusNode || d->pseudoFocusNode == TDEHTMLViewPrivate::PFTop )
2190  newFocusNode = doc->nextFocusNode(oldFocusNode);
2191  }
2192  else
2193  {
2194  if (oldFocusNode || d->pseudoFocusNode == TDEHTMLViewPrivate::PFBottom )
2195  newFocusNode = doc->previousFocusNode(oldFocusNode);
2196  }
2197 
2198  bool targetVisible = false;
2199  if (!newFocusNode)
2200  {
2201  if ( next )
2202  {
2203  targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,contentsHeight()-d->borderY,0,0));
2204  }
2205  else
2206  {
2207  targetVisible = scrollTo(TQRect(contentsX()+visibleWidth()/2,d->borderY,0,0));
2208  }
2209  }
2210  else
2211  {
2212 #ifndef TDEHTML_NO_CARET
2213  // if it's an editable element, activate the caret
2214  if (!m_part->isCaretMode() && !m_part->isEditable()
2215  && newFocusNode->contentEditable()) {
2216  d->caretViewContext();
2217  moveCaretTo(newFocusNode, 0L, true);
2218  } else {
2219  caretOff();
2220  }
2221 #endif // TDEHTML_NO_CARET
2222 
2223  targetVisible = scrollTo(newFocusNode->getRect());
2224  }
2225 
2226  if (targetVisible)
2227  {
2228  //kdDebug ( 6000 ) << " target reached.\n";
2229  d->tabMovePending = false;
2230 
2231  m_part->xmlDocImpl()->setFocusNode(newFocusNode);
2232  if (newFocusNode)
2233  {
2234  Node guard(newFocusNode);
2235  if (!newFocusNode->hasOneRef() )
2236  {
2237  emit m_part->nodeActivated(Node(newFocusNode));
2238  }
2239  return true;
2240  }
2241  else
2242  {
2243  d->pseudoFocusNode = next?TDEHTMLViewPrivate::PFBottom:TDEHTMLViewPrivate::PFTop;
2244  return false;
2245  }
2246  }
2247  else
2248  {
2249  if (!d->tabMovePending)
2250  d->lastTabbingDirection = next;
2251  d->tabMovePending = true;
2252  return true;
2253  }
2254 }
2255 
2256 void TDEHTMLView::displayAccessKeys()
2257 {
2258  TQValueVector< TQChar > taken;
2259  displayAccessKeys( NULL, this, taken, false );
2260  displayAccessKeys( NULL, this, taken, true );
2261 }
2262 
2263 void TDEHTMLView::displayAccessKeys( TDEHTMLView* caller, TDEHTMLView* origview, TQValueVector< TQChar >& taken, bool use_fallbacks )
2264 {
2265  TQMap< ElementImpl*, TQChar > fallbacks;
2266  if( use_fallbacks )
2267  fallbacks = buildFallbackAccessKeys();
2268  for( NodeImpl* n = m_part->xmlDocImpl(); n != NULL; n = n->traverseNextNode()) {
2269  if( n->isElementNode()) {
2270  ElementImpl* en = static_cast< ElementImpl* >( n );
2271  DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2272  TQString accesskey;
2273  if( s.length() == 1 ) {
2274  TQChar a = s.string()[ 0 ].upper();
2275  if( tqFind( taken.begin(), taken.end(), a ) == taken.end()) // !contains
2276  accesskey = a;
2277  }
2278  if( accesskey.isNull() && fallbacks.contains( en )) {
2279  TQChar a = fallbacks[ en ].upper();
2280  if( tqFind( taken.begin(), taken.end(), a ) == taken.end()) // !contains
2281  accesskey = TQString( "<qt><i>" ) + a + "</i></qt>";
2282  }
2283  if( !accesskey.isNull()) {
2284  TQRect rec=en->getRect();
2285  TQLabel *lab=new TQLabel(accesskey,viewport(),0,(WFlags)WDestructiveClose);
2286  connect( origview, TQ_SIGNAL(hideAccessKeys()), lab, TQ_SLOT(close()) );
2287  connect( this, TQ_SIGNAL(repaintAccessKeys()), lab, TQ_SLOT(repaint()));
2288  lab->setPalette(TQToolTip::palette());
2289  lab->setLineWidth(2);
2290  lab->setFrameStyle(TQFrame::Box | TQFrame::Plain);
2291  lab->setMargin(3);
2292  lab->adjustSize();
2293  addChild(lab,
2294  KMIN(rec.left()+rec.width()/2, contentsWidth() - lab->width()),
2295  KMIN(rec.top()+rec.height()/2, contentsHeight() - lab->height()));
2296  showChild(lab);
2297  taken.append( accesskey[ 0 ] );
2298  }
2299  }
2300  }
2301  if( use_fallbacks )
2302  return;
2303  TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
2304  for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
2305  it != NULL;
2306  ++it ) {
2307  if( !(*it)->inherits( "TDEHTMLPart" ))
2308  continue;
2309  TDEHTMLPart* part = static_cast< TDEHTMLPart* >( *it );
2310  if( part->view() && part->view() != caller )
2311  part->view()->displayAccessKeys( this, origview, taken, use_fallbacks );
2312  }
2313  // pass up to the parent
2314  if (m_part->parentPart() && m_part->parentPart()->view()
2315  && m_part->parentPart()->view() != caller)
2316  m_part->parentPart()->view()->displayAccessKeys( this, origview, taken, use_fallbacks );
2317 }
2318 
2319 
2320 
2321 void TDEHTMLView::accessKeysTimeout()
2322 {
2323 d->accessKeysActivated=false;
2324 d->accessKeysPreActivate = false;
2325 m_part->setStatusBarText(TQString::null, TDEHTMLPart::BarOverrideText);
2326 emit hideAccessKeys();
2327 }
2328 
2329 // Handling of the HTML accesskey attribute.
2330 bool TDEHTMLView::handleAccessKey( const TQKeyEvent* ev )
2331 {
2332 // Qt interprets the keyevent also with the modifiers, and ev->text() matches that,
2333 // but this code must act as if the modifiers weren't pressed
2334  TQChar c;
2335  if( ev->key() >= Key_A && ev->key() <= Key_Z )
2336  c = 'A' + ev->key() - Key_A;
2337  else if( ev->key() >= Key_0 && ev->key() <= Key_9 )
2338  c = '0' + ev->key() - Key_0;
2339  else {
2340  // TODO fake XKeyEvent and XLookupString ?
2341  // This below seems to work e.g. for eacute though.
2342  if( ev->text().length() == 1 )
2343  c = ev->text()[ 0 ];
2344  }
2345  if( c.isNull())
2346  return false;
2347  return focusNodeWithAccessKey( c );
2348 }
2349 
2350 bool TDEHTMLView::focusNodeWithAccessKey( TQChar c, TDEHTMLView* caller )
2351 {
2352  DocumentImpl *doc = m_part->xmlDocImpl();
2353  if( !doc )
2354  return false;
2355  ElementImpl* node = doc->findAccessKeyElement( c );
2356  if( !node ) {
2357  TQPtrList<KParts::ReadOnlyPart> frames = m_part->frames();
2358  for( TQPtrListIterator<KParts::ReadOnlyPart> it( frames );
2359  it != NULL;
2360  ++it ) {
2361  if( !(*it)->inherits( "TDEHTMLPart" ))
2362  continue;
2363  TDEHTMLPart* part = static_cast< TDEHTMLPart* >( *it );
2364  if( part->view() && part->view() != caller
2365  && part->view()->focusNodeWithAccessKey( c, this ))
2366  return true;
2367  }
2368  // pass up to the parent
2369  if (m_part->parentPart() && m_part->parentPart()->view()
2370  && m_part->parentPart()->view() != caller
2371  && m_part->parentPart()->view()->focusNodeWithAccessKey( c, this ))
2372  return true;
2373  if( caller == NULL ) { // the active frame (where the accesskey was pressed)
2374  TQMap< ElementImpl*, TQChar > fallbacks = buildFallbackAccessKeys();
2375  for( TQMap< ElementImpl*, TQChar >::ConstIterator it = fallbacks.begin();
2376  it != fallbacks.end();
2377  ++it )
2378  if( *it == c ) {
2379  node = it.key();
2380  break;
2381  }
2382  }
2383  if( node == NULL )
2384  return false;
2385  }
2386 
2387  // Scroll the view as necessary to ensure that the new focus node is visible
2388 #ifndef TDEHTML_NO_CARET
2389  // if it's an editable element, activate the caret
2390  if (!m_part->isCaretMode() && !m_part->isEditable()
2391  && node->contentEditable()) {
2392  d->caretViewContext();
2393  moveCaretTo(node, 0L, true);
2394  } else {
2395  caretOff();
2396  }
2397 #endif // TDEHTML_NO_CARET
2398 
2399  TQRect r = node->getRect();
2400  ensureVisible( r.right(), r.bottom());
2401  ensureVisible( r.left(), r.top());
2402 
2403  Node guard( node );
2404  if( node->isFocusable()) {
2405  if (node->id()==ID_LABEL) {
2406  // if Accesskey is a label, give focus to the label's referrer.
2407  node=static_cast<ElementImpl *>(static_cast< HTMLLabelElementImpl* >( node )->getFormElement());
2408  if (!node) return true;
2409  guard = node;
2410  }
2411  // Set focus node on the document
2412  TQFocusEvent::setReason( TQFocusEvent::Shortcut );
2413  m_part->xmlDocImpl()->setFocusNode(node);
2414  TQFocusEvent::resetReason();
2415  if( node != NULL && node->hasOneRef()) // deleted, only held by guard
2416  return true;
2417  emit m_part->nodeActivated(Node(node));
2418  if( node != NULL && node->hasOneRef())
2419  return true;
2420  }
2421 
2422  switch( node->id()) {
2423  case ID_A:
2424  static_cast< HTMLAnchorElementImpl* >( node )->click();
2425  break;
2426  case ID_INPUT:
2427  static_cast< HTMLInputElementImpl* >( node )->click();
2428  break;
2429  case ID_BUTTON:
2430  static_cast< HTMLButtonElementImpl* >( node )->click();
2431  break;
2432  case ID_AREA:
2433  static_cast< HTMLAreaElementImpl* >( node )->click();
2434  break;
2435  case ID_TEXTAREA:
2436  break; // just focusing it is enough
2437  case ID_LEGEND:
2438  // TODO
2439  break;
2440  }
2441  return true;
2442 }
2443 
2444 static TQString getElementText( NodeImpl* start, bool after )
2445 {
2446  TQString ret; // nextSibling(), to go after e.g. </select>
2447  for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
2448  n != NULL;
2449  n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
2450  if( n->isTextNode()) {
2451  if( after )
2452  ret += static_cast< TextImpl* >( n )->toString().string();
2453  else
2454  ret.prepend( static_cast< TextImpl* >( n )->toString().string());
2455  } else {
2456  switch( n->id()) {
2457  case ID_A:
2458  case ID_FONT:
2459  case ID_TT:
2460  case ID_U:
2461  case ID_B:
2462  case ID_I:
2463  case ID_S:
2464  case ID_STRIKE:
2465  case ID_BIG:
2466  case ID_SMALL:
2467  case ID_EM:
2468  case ID_STRONG:
2469  case ID_DFN:
2470  case ID_CODE:
2471  case ID_SAMP:
2472  case ID_KBD:
2473  case ID_VAR:
2474  case ID_CITE:
2475  case ID_ABBR:
2476  case ID_ACRONYM:
2477  case ID_SUB:
2478  case ID_SUP:
2479  case ID_SPAN:
2480  case ID_NOBR:
2481  case ID_WBR:
2482  break;
2483  case ID_TD:
2484  if( ret.stripWhiteSpace().isEmpty())
2485  break;
2486  // fall through
2487  default:
2488  return ret.simplifyWhiteSpace();
2489  }
2490  }
2491  }
2492  return ret.simplifyWhiteSpace();
2493 }
2494 
2495 static TQMap< NodeImpl*, TQString > buildLabels( NodeImpl* start )
2496 {
2497  TQMap< NodeImpl*, TQString > ret;
2498  for( NodeImpl* n = start;
2499  n != NULL;
2500  n = n->traverseNextNode()) {
2501  if( n->id() == ID_LABEL ) {
2502  HTMLLabelElementImpl* label = static_cast< HTMLLabelElementImpl* >( n );
2503  NodeImpl* labelfor = label->getFormElement();
2504  if( labelfor )
2505  ret[ labelfor ] = label->innerText().string().simplifyWhiteSpace();
2506  }
2507  }
2508  return ret;
2509 }
2510 
2511 namespace tdehtml {
2512 struct AccessKeyData {
2513  ElementImpl* element;
2514  TQString text;
2515  TQString url;
2516  int priority; // 10(highest) - 0(lowest)
2517 };
2518 }
2519 
2520 TQMap< ElementImpl*, TQChar > TDEHTMLView::buildFallbackAccessKeys() const
2521 {
2522  // build a list of all possible candidate elements that could use an accesskey
2523  TQValueList< AccessKeyData > data;
2524  TQMap< NodeImpl*, TQString > labels = buildLabels( m_part->xmlDocImpl());
2525  for( NodeImpl* n = m_part->xmlDocImpl();
2526  n != NULL;
2527  n = n->traverseNextNode()) {
2528  if( n->isElementNode()) {
2529  ElementImpl* element = static_cast< ElementImpl* >( n );
2530  if( element->getAttribute( ATTR_ACCESSKEY ).length() == 1 )
2531  continue; // has accesskey set, ignore
2532  if( element->renderer() == NULL )
2533  continue; // not visible
2534  TQString text;
2535  TQString url;
2536  int priority = 0;
2537  bool ignore = false;
2538  bool text_after = false;
2539  bool text_before = false;
2540  switch( element->id()) {
2541  case ID_A:
2542  url = tdehtml::parseURL(element->getAttribute(ATTR_HREF)).string();
2543  if( url.isEmpty()) // doesn't have href, it's only an anchor
2544  continue;
2545  text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
2546  priority = 2;
2547  break;
2548  case ID_INPUT: {
2549  HTMLInputElementImpl* in = static_cast< HTMLInputElementImpl* >( element );
2550  switch( in->inputType()) {
2551  case HTMLInputElementImpl::SUBMIT:
2552  text = in->value().string();
2553  if( text.isEmpty())
2554  text = i18n( "Submit" );
2555  priority = 7;
2556  break;
2557  case HTMLInputElementImpl::IMAGE:
2558  text = in->altText().string();
2559  priority = 7;
2560  break;
2561  case HTMLInputElementImpl::BUTTON:
2562  text = in->value().string();
2563  priority = 5;
2564  break;
2565  case HTMLInputElementImpl::RESET:
2566  text = in->value().string();
2567  if( text.isEmpty())
2568  text = i18n( "Reset" );
2569  priority = 5;
2570  break;
2571  case HTMLInputElementImpl::HIDDEN:
2572  ignore = true;
2573  break;
2574  case HTMLInputElementImpl::CHECKBOX:
2575  case HTMLInputElementImpl::RADIO:
2576  text_after = true;
2577  priority = 5;
2578  break;
2579  case HTMLInputElementImpl::TEXT:
2580  case HTMLInputElementImpl::PASSWORD:
2581  case HTMLInputElementImpl::FILE:
2582  text_before = true;
2583  priority = 5;
2584  break;
2585  default:
2586  priority = 5;
2587  break;
2588  }
2589  break;
2590  }
2591  case ID_BUTTON:
2592  text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
2593  switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
2594  case HTMLButtonElementImpl::SUBMIT:
2595  if( text.isEmpty())
2596  text = i18n( "Submit" );
2597  priority = 7;
2598  break;
2599  case HTMLButtonElementImpl::RESET:
2600  if( text.isEmpty())
2601  text = i18n( "Reset" );
2602  priority = 5;
2603  break;
2604  default:
2605  priority = 5;
2606  break;
2607  break;
2608  }
2609  case ID_SELECT: // these don't have accesskey attribute, but quick access may be handy
2610  text_before = true;
2611  text_after = true;
2612  priority = 5;
2613  break;
2614  case ID_FRAME:
2615  ignore = true;
2616  break;
2617  default:
2618  ignore = !element->isFocusable();
2619  priority = 2;
2620  break;
2621  }
2622  if( ignore )
2623  continue;
2624  if( text.isNull() && labels.contains( element ))
2625  text = labels[ element ];
2626  if( text.isNull() && text_before )
2627  text = getElementText( element, false );
2628  if( text.isNull() && text_after )
2629  text = getElementText( element, true );
2630  text = text.stripWhiteSpace();
2631  // increase priority of items which have explicitly specified accesskeys in the config
2632  TQValueList< TQPair< TQString, TQChar > > priorities
2633  = m_part->settings()->fallbackAccessKeysAssignments();
2634  for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
2635  it != priorities.end();
2636  ++it ) {
2637  if( text == (*it).first )
2638  priority = 10;
2639  }
2640  AccessKeyData tmp = { element, text, url, priority };
2641  data.append( tmp );
2642  }
2643  }
2644 
2645  TQValueList< TQChar > keys;
2646  for( char c = 'A'; c <= 'Z'; ++c )
2647  keys << c;
2648  for( char c = '0'; c <= '9'; ++c )
2649  keys << c;
2650  for( NodeImpl* n = m_part->xmlDocImpl();
2651  n != NULL;
2652  n = n->traverseNextNode()) {
2653  if( n->isElementNode()) {
2654  ElementImpl* en = static_cast< ElementImpl* >( n );
2655  DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2656  if( s.length() == 1 ) {
2657  TQChar c = s.string()[ 0 ].upper();
2658  keys.remove( c ); // remove manually assigned accesskeys
2659  }
2660  }
2661  }
2662 
2663  TQMap< ElementImpl*, TQChar > ret;
2664  for( int priority = 10;
2665  priority >= 0;
2666  --priority ) {
2667  for( TQValueList< AccessKeyData >::Iterator it = data.begin();
2668  it != data.end();
2669  ) {
2670  if( (*it).priority != priority ) {
2671  ++it;
2672  continue;
2673  }
2674  if( keys.isEmpty())
2675  break;
2676  TQString text = (*it).text;
2677  TQChar key;
2678  if( key.isNull() && !text.isEmpty()) {
2679  TQValueList< TQPair< TQString, TQChar > > priorities
2680  = m_part->settings()->fallbackAccessKeysAssignments();
2681  for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
2682  it != priorities.end();
2683  ++it )
2684  if( text == (*it).first && keys.contains( (*it).second )) {
2685  key = (*it).second;
2686  break;
2687  }
2688  }
2689  // try first to select the first character as the accesskey,
2690  // then first character of the following words,
2691  // and then simply the first free character
2692  if( key.isNull() && !text.isEmpty()) {
2693  TQStringList words = TQStringList::split( ' ', text );
2694  for( TQStringList::ConstIterator it = words.begin();
2695  it != words.end();
2696  ++it ) {
2697  if( keys.contains( (*it)[ 0 ].upper())) {
2698  key = (*it)[ 0 ].upper();
2699  break;
2700  }
2701  }
2702  }
2703  if( key.isNull() && !text.isEmpty()) {
2704  for( unsigned int i = 0;
2705  i < text.length();
2706  ++i ) {
2707  if( keys.contains( text[ i ].upper())) {
2708  key = text[ i ].upper();
2709  break;
2710  }
2711  }
2712  }
2713  if( key.isNull())
2714  key = keys.front();
2715  ret[ (*it).element ] = key;
2716  keys.remove( key );
2717  TQString url = (*it).url;
2718  it = data.remove( it );
2719  // assign the same accesskey also to other elements pointing to the same url
2720  if( !url.isEmpty() && !url.startsWith( "javascript:", false )) {
2721  for( TQValueList< AccessKeyData >::Iterator it2 = data.begin();
2722  it2 != data.end();
2723  ) {
2724  if( (*it2).url == url ) {
2725  ret[ (*it2).element ] = key;
2726  if( it == it2 )
2727  ++it;
2728  it2 = data.remove( it2 );
2729  } else
2730  ++it2;
2731  }
2732  }
2733  }
2734  }
2735  return ret;
2736 }
2737 
2738 void TDEHTMLView::setMediaType( const TQString &medium )
2739 {
2740  m_medium = medium;
2741 }
2742 
2743 TQString TDEHTMLView::mediaType() const
2744 {
2745  return m_medium;
2746 }
2747 
2748 bool TDEHTMLView::pagedMode() const
2749 {
2750  return d->paged;
2751 }
2752 
2753 void TDEHTMLView::setWidgetVisible(RenderWidget* w, bool vis)
2754 {
2755  if (vis) {
2756  d->visibleWidgets.replace(w, w->widget());
2757  }
2758  else
2759  d->visibleWidgets.remove(w);
2760 }
2761 
2762 bool TDEHTMLView::needsFullRepaint() const
2763 {
2764  return d->needsFullRepaint;
2765 }
2766 
2767 void TDEHTMLView::print()
2768 {
2769  print( false );
2770 }
2771 
2772 void TDEHTMLView::print(bool quick)
2773 {
2774  if(!m_part->xmlDocImpl()) return;
2775  tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
2776  if(!root) return;
2777 
2778  KPrinter *printer = new KPrinter(true, TQPrinter::ScreenResolution);
2779  printer->addDialogPage(new TDEHTMLPrintSettings());
2780  TQString docname = m_part->xmlDocImpl()->URL().prettyURL();
2781  if ( !docname.isEmpty() )
2782  docname = KStringHandler::csqueeze(docname, 80);
2783  if(quick || printer->setup(this, i18n("Print %1").arg(docname))) {
2784  viewport()->setCursor( TQt::waitCursor ); // only viewport(), no TQApplication::, otherwise we get the busy cursor in tdeprint's dialogs
2785  // set up KPrinter
2786  printer->setFullPage(false);
2787  printer->setCreator(TQString("TDE %1.%2.%3 HTML Library").arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(TDE_VERSION_RELEASE));
2788  printer->setDocName(docname);
2789 
2790  TQPainter *p = new TQPainter;
2791  p->begin( printer );
2792  tdehtml::setPrintPainter( p );
2793 
2794  m_part->xmlDocImpl()->setPaintDevice( printer );
2795  TQString oldMediaType = mediaType();
2796  setMediaType( "print" );
2797  // We ignore margin settings for html and body when printing
2798  // and use the default margins from the print-system
2799  // (In Qt 3.0.x the default margins are hardcoded in Qt)
2800  m_part->xmlDocImpl()->setPrintStyleSheet( printer->option("app-khtml-printfriendly") == "true" ?
2801  "* { background-image: none !important;"
2802  " background-color: white !important;"
2803  " color: black !important; }"
2804  "body { margin: 0px !important; }"
2805  "html { margin: 0px !important; }" :
2806  "body { margin: 0px !important; }"
2807  "html { margin: 0px !important; }"
2808  );
2809 
2810  TQPaintDeviceMetrics metrics( printer );
2811 
2812  kdDebug(6000) << "printing: physical page width = " << metrics.width()
2813  << " height = " << metrics.height() << endl;
2814  root->setStaticMode(true);
2815  root->setPagedMode(true);
2816  root->setWidth(metrics.width());
2817 // root->setHeight(metrics.height());
2818  root->setPageTop(0);
2819  root->setPageBottom(0);
2820  d->paged = true;
2821 
2822  m_part->xmlDocImpl()->styleSelector()->computeFontSizes(&metrics, 100);
2823  m_part->xmlDocImpl()->updateStyleSelector();
2824  root->setPrintImages( printer->option("app-khtml-printimages") == "true");
2825  root->makePageBreakAvoidBlocks();
2826 
2827  root->setNeedsLayoutAndMinMaxRecalc();
2828  root->layout();
2829  tdehtml::RenderWidget::flushWidgetResizes(); // make sure widgets have their final size
2830 
2831  // check sizes ask for action.. (scale or clip)
2832 
2833  bool printHeader = (printer->option("app-khtml-printheader") == "true");
2834 
2835  int headerHeight = 0;
2836  TQFont headerFont("Sans Serif", 8);
2837 
2838  TQString headerLeft = TDEGlobal::locale()->formatDate(TQDate::currentDate(),true);
2839  TQString headerMid = docname;
2840  TQString headerRight;
2841 
2842  if (printHeader)
2843  {
2844  p->setFont(headerFont);
2845  headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
2846  }
2847 
2848  // ok. now print the pages.
2849  kdDebug(6000) << "printing: html page width = " << root->docWidth()
2850  << " height = " << root->docHeight() << endl;
2851  kdDebug(6000) << "printing: margins left = " << printer->margins().width()
2852  << " top = " << printer->margins().height() << endl;
2853  kdDebug(6000) << "printing: paper width = " << metrics.width()
2854  << " height = " << metrics.height() << endl;
2855  // if the width is too large to fit on the paper we just scale
2856  // the whole thing.
2857  int pageWidth = metrics.width();
2858  int pageHeight = metrics.height();
2859  p->setClipRect(0,0, pageWidth, pageHeight);
2860 
2861  pageHeight -= headerHeight;
2862 
2863  bool scalePage = false;
2864  double scale = 0.0;
2865 #ifndef TQT_NO_TRANSFORMATIONS
2866  if(root->docWidth() > metrics.width()) {
2867  scalePage = true;
2868  scale = ((double) metrics.width())/((double) root->docWidth());
2869  pageHeight = (int) (pageHeight/scale);
2870  pageWidth = (int) (pageWidth/scale);
2871  headerHeight = (int) (headerHeight/scale);
2872  }
2873 #endif
2874  kdDebug(6000) << "printing: scaled html width = " << pageWidth
2875  << " height = " << pageHeight << endl;
2876 
2877  root->setHeight(pageHeight);
2878  root->setPageBottom(pageHeight);
2879  root->setNeedsLayout(true);
2880  root->layoutIfNeeded();
2881 // m_part->slotDebugRenderTree();
2882 
2883  // Squeeze header to make it it on the page.
2884  if (printHeader)
2885  {
2886  int available_width = metrics.width() - 10 -
2887  2 * kMax(p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), TQt::AlignLeft, headerLeft).width(),
2888  p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), TQt::AlignLeft, headerRight).width());
2889  if (available_width < 150)
2890  available_width = 150;
2891  int mid_width;
2892  int squeeze = 120;
2893  do {
2894  headerMid = KStringHandler::csqueeze(docname, squeeze);
2895  mid_width = p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), TQt::AlignLeft, headerMid).width();
2896  squeeze -= 10;
2897  } while (mid_width > available_width);
2898  }
2899 
2900  int top = 0;
2901  int bottom = 0;
2902  int page = 1;
2903  while(top < root->docHeight()) {
2904  if(top > 0) printer->newPage();
2905  p->setClipRect(0, 0, pageWidth, headerHeight, TQPainter::CoordDevice);
2906  if (printHeader)
2907  {
2908  int dy = p->fontMetrics().lineSpacing();
2909  p->setPen(TQt::black);
2910  p->setFont(headerFont);
2911 
2912  headerRight = TQString("#%1").arg(page);
2913 
2914  p->drawText(0, 0, metrics.width(), dy, TQt::AlignLeft, headerLeft);
2915  p->drawText(0, 0, metrics.width(), dy, TQt::AlignHCenter, headerMid);
2916  p->drawText(0, 0, metrics.width(), dy, TQt::AlignRight, headerRight);
2917  }
2918 
2919 
2920 #ifndef TQT_NO_TRANSFORMATIONS
2921  if (scalePage)
2922  p->scale(scale, scale);
2923 #endif
2924 
2925  p->setClipRect(0, headerHeight, pageWidth, pageHeight, TQPainter::CoordDevice);
2926  p->translate(0, headerHeight-top);
2927 
2928  bottom = top+pageHeight;
2929 
2930  root->setPageTop(top);
2931  root->setPageBottom(bottom);
2932  root->setPageNumber(page);
2933 
2934  root->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
2935 // m_part->xmlDocImpl()->renderer()->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
2936 // root->repaint();
2937 // p->flush();
2938  kdDebug(6000) << "printed: page " << page <<" bottom At = " << bottom << endl;
2939 
2940  top = bottom;
2941  p->resetXForm();
2942  page++;
2943  }
2944 
2945  p->end();
2946  delete p;
2947 
2948  // and now reset the layout to the usual one...
2949  root->setPagedMode(false);
2950  root->setStaticMode(false);
2951  d->paged = false;
2952  tdehtml::setPrintPainter( 0 );
2953  setMediaType( oldMediaType );
2954  m_part->xmlDocImpl()->setPaintDevice( this );
2955  m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->paintDeviceMetrics(), m_part->zoomFactor());
2956  m_part->xmlDocImpl()->updateStyleSelector();
2957  viewport()->unsetCursor();
2958  }
2959  delete printer;
2960 }
2961 
2962 void TDEHTMLView::slotPaletteChanged()
2963 {
2964  if(!m_part->xmlDocImpl()) return;
2965  DOM::DocumentImpl *document = m_part->xmlDocImpl();
2966  if (!document->isHTMLDocument()) return;
2967  tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(document->renderer());
2968  if(!root) return;
2969  root->style()->resetPalette();
2970  NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
2971  if(!body) return;
2972  body->setChanged(true);
2973  body->recalcStyle( NodeImpl::Force );
2974 }
2975 
2976 void TDEHTMLView::paint(TQPainter *p, const TQRect &rc, int yOff, bool *more)
2977 {
2978  if(!m_part->xmlDocImpl()) return;
2979  tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
2980  if(!root) return;
2981 
2982  m_part->xmlDocImpl()->setPaintDevice(p->device());
2983  root->setPagedMode(true);
2984  root->setStaticMode(true);
2985  root->setWidth(rc.width());
2986 
2987  p->save();
2988  p->setClipRect(rc);
2989  p->translate(rc.left(), rc.top());
2990  double scale = ((double) rc.width()/(double) root->docWidth());
2991  int height = (int) ((double) rc.height() / scale);
2992 #ifndef TQT_NO_TRANSFORMATIONS
2993  p->scale(scale, scale);
2994 #endif
2995  root->setPageTop(yOff);
2996  root->setPageBottom(yOff+height);
2997 
2998  root->layer()->paint(p, TQRect(0, yOff, root->docWidth(), height));
2999  if (more)
3000  *more = yOff + height < root->docHeight();
3001  p->restore();
3002 
3003  root->setPagedMode(false);
3004  root->setStaticMode(false);
3005  m_part->xmlDocImpl()->setPaintDevice( this );
3006 }
3007 
3008 
3009 void TDEHTMLView::useSlowRepaints()
3010 {
3011  d->useSlowRepaints = true;
3012  setStaticBackground(true);
3013 }
3014 
3015 
3016 void TDEHTMLView::setVScrollBarMode ( ScrollBarMode mode )
3017 {
3018 #ifndef TDEHTML_NO_SCROLLBARS
3019  d->vmode = mode;
3020  TQScrollView::setVScrollBarMode(mode);
3021 #else
3022  Q_UNUSED( mode );
3023 #endif
3024 }
3025 
3026 void TDEHTMLView::setHScrollBarMode ( ScrollBarMode mode )
3027 {
3028 #ifndef TDEHTML_NO_SCROLLBARS
3029  d->hmode = mode;
3030  TQScrollView::setHScrollBarMode(mode);
3031 #else
3032  Q_UNUSED( mode );
3033 #endif
3034 }
3035 
3036 void TDEHTMLView::restoreScrollBar()
3037 {
3038  int ow = visibleWidth();
3039  TQScrollView::setVScrollBarMode(d->vmode);
3040  if (visibleWidth() != ow)
3041  layout();
3042  d->prevScrollbarVisible = verticalScrollBar()->isVisible();
3043 }
3044 
3045 TQStringList TDEHTMLView::formCompletionItems(const TQString &name) const
3046 {
3047  if (!m_part->settings()->isFormCompletionEnabled())
3048  return TQStringList();
3049  if (!d->formCompletions)
3050  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3051  return d->formCompletions->readListEntry(name);
3052 }
3053 
3054 void TDEHTMLView::clearCompletionHistory(const TQString& name)
3055 {
3056  if (!d->formCompletions)
3057  {
3058  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3059  }
3060  d->formCompletions->writeEntry(name, "");
3061  d->formCompletions->sync();
3062 }
3063 
3064 void TDEHTMLView::addFormCompletionItem(const TQString &name, const TQString &value)
3065 {
3066  if (!m_part->settings()->isFormCompletionEnabled())
3067  return;
3068  // don't store values that are all numbers or just numbers with
3069  // dashes or spaces as those are likely credit card numbers or
3070  // something similar
3071  bool cc_number(true);
3072  for (unsigned int i = 0; i < value.length(); ++i)
3073  {
3074  TQChar c(value[i]);
3075  if (!c.isNumber() && c != '-' && !c.isSpace())
3076  {
3077  cc_number = false;
3078  break;
3079  }
3080  }
3081  if (cc_number)
3082  return;
3083  TQStringList items = formCompletionItems(name);
3084  if (!items.contains(value))
3085  items.prepend(value);
3086  while ((int)items.count() > m_part->settings()->maxFormCompletionItems())
3087  items.remove(items.fromLast());
3088  d->formCompletions->writeEntry(name, items);
3089 }
3090 
3091 void TDEHTMLView::removeFormCompletionItem(const TQString &name, const TQString &value)
3092 {
3093  if (!m_part->settings()->isFormCompletionEnabled())
3094  return;
3095 
3096  TQStringList items = formCompletionItems(name);
3097  if (items.remove(value))
3098  d->formCompletions->writeEntry(name, items);
3099 }
3100 
3101 void TDEHTMLView::addNonPasswordStorableSite(const TQString& host)
3102 {
3103  if (!d->formCompletions) {
3104  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3105  }
3106 
3107  d->formCompletions->setGroup("NonPasswordStorableSites");
3108  TQStringList sites = d->formCompletions->readListEntry("Sites");
3109  sites.append(host);
3110  d->formCompletions->writeEntry("Sites", sites);
3111  d->formCompletions->sync();
3112  d->formCompletions->setGroup(TQString::null);//reset
3113 }
3114 
3115 bool TDEHTMLView::nonPasswordStorableSite(const TQString& host) const
3116 {
3117  if (!d->formCompletions) {
3118  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3119  }
3120  d->formCompletions->setGroup("NonPasswordStorableSites");
3121  TQStringList sites = d->formCompletions->readListEntry("Sites");
3122  d->formCompletions->setGroup(TQString::null);//reset
3123 
3124  return (sites.find(host) != sites.end());
3125 }
3126 
3127 // returns true if event should be swallowed
3128 bool TDEHTMLView::dispatchMouseEvent(int eventId, DOM::NodeImpl *targetNode,
3129  DOM::NodeImpl *targetNodeNonShared, bool cancelable,
3130  int detail,TQMouseEvent *_mouse, bool setUnder,
3131  int mouseEventType)
3132 {
3133  // if the target node is a text node, dispatch on the parent node - rdar://4196646 (and #76948)
3134  if (targetNode && targetNode->isTextNode())
3135  targetNode = targetNode->parentNode();
3136 
3137  if (d->underMouse)
3138  d->underMouse->deref();
3139  d->underMouse = targetNode;
3140  if (d->underMouse)
3141  d->underMouse->ref();
3142 
3143  if (d->underMouseNonShared)
3144  d->underMouseNonShared->deref();
3145  d->underMouseNonShared = targetNodeNonShared;
3146  if (d->underMouseNonShared)
3147  d->underMouseNonShared->ref();
3148 
3149  int exceptioncode = 0;
3150  int pageX = 0;
3151  int pageY = 0;
3152  viewportToContents(_mouse->x(), _mouse->y(), pageX, pageY);
3153  int clientX = pageX - contentsX();
3154  int clientY = pageY - contentsY();
3155  int screenX = _mouse->globalX();
3156  int screenY = _mouse->globalY();
3157  int button = -1;
3158  switch (_mouse->button()) {
3159  case TQt::LeftButton:
3160  button = 0;
3161  break;
3162  case TQt::MidButton:
3163  button = 1;
3164  break;
3165  case TQt::RightButton:
3166  button = 2;
3167  break;
3168  default:
3169  break;
3170  }
3171  if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
3172  d->accessKeysPreActivate=false;
3173 
3174  bool ctrlKey = (_mouse->state() & ControlButton);
3175  bool altKey = (_mouse->state() & AltButton);
3176  bool shiftKey = (_mouse->state() & ShiftButton);
3177  bool metaKey = (_mouse->state() & MetaButton);
3178 
3179  // mouseout/mouseover
3180  if (setUnder && (d->prevMouseX != pageX || d->prevMouseY != pageY)) {
3181 
3182  // ### this code sucks. we should save the oldUnder instead of calculating
3183  // it again. calculating is expensive! (Dirk)
3184  NodeImpl *oldUnder = 0;
3185  if (d->prevMouseX >= 0 && d->prevMouseY >= 0) {
3186  NodeImpl::MouseEvent mev( _mouse->stateAfter(), static_cast<NodeImpl::MouseEventType>(mouseEventType));
3187  m_part->xmlDocImpl()->prepareMouseEvent( true, d->prevMouseX, d->prevMouseY, &mev );
3188  oldUnder = mev.innerNode.handle();
3189 
3190  if (oldUnder && oldUnder->isTextNode())
3191  oldUnder = oldUnder->parentNode();
3192  }
3193 // tqDebug("oldunder=%p (%s), target=%p (%s) x/y=%d/%d", oldUnder, oldUnder ? oldUnder->renderer()->renderName() : 0, targetNode, targetNode ? targetNode->renderer()->renderName() : 0, _mouse->x(), _mouse->y());
3194  if (oldUnder != targetNode) {
3195  // send mouseout event to the old node
3196  if (oldUnder){
3197  oldUnder->ref();
3198  MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
3199  true,true,m_part->xmlDocImpl()->defaultView(),
3200  0,screenX,screenY,clientX,clientY,pageX, pageY,
3201  ctrlKey,altKey,shiftKey,metaKey,
3202  button,targetNode);
3203  me->ref();
3204  oldUnder->dispatchEvent(me,exceptioncode,true);
3205  me->deref();
3206  }
3207 
3208  // send mouseover event to the new node
3209  if (targetNode) {
3210  MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
3211  true,true,m_part->xmlDocImpl()->defaultView(),
3212  0,screenX,screenY,clientX,clientY,pageX, pageY,
3213  ctrlKey,altKey,shiftKey,metaKey,
3214  button,oldUnder);
3215 
3216  me->ref();
3217  targetNode->dispatchEvent(me,exceptioncode,true);
3218  me->deref();
3219  }
3220 
3221  if (oldUnder)
3222  oldUnder->deref();
3223  }
3224  }
3225 
3226  bool swallowEvent = false;
3227 
3228  if (targetNode) {
3229  // send the actual event
3230  bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
3231  _mouse->type() == TQEvent::MouseButtonDblClick );
3232  MouseEventImpl *me = new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
3233  true,cancelable,m_part->xmlDocImpl()->defaultView(),
3234  detail,screenX,screenY,clientX,clientY,pageX, pageY,
3235  ctrlKey,altKey,shiftKey,metaKey,
3236  button,0, _mouse, dblclick );
3237  me->ref();
3238  targetNode->dispatchEvent(me,exceptioncode,true);
3239  bool defaultHandled = me->defaultHandled();
3240  if (defaultHandled || me->defaultPrevented())
3241  swallowEvent = true;
3242  me->deref();
3243 
3244  if (eventId == EventImpl::MOUSEDOWN_EVENT) {
3245  // Focus should be shifted on mouse down, not on a click. -dwh
3246  // Blur current focus node when a link/button is clicked; this
3247  // is expected by some sites that rely on onChange handlers running
3248  // from form fields before the button click is processed.
3249  DOM::NodeImpl* nodeImpl = targetNode;
3250  for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode());
3251  if (nodeImpl && nodeImpl->isMouseFocusable())
3252  m_part->xmlDocImpl()->setFocusNode(nodeImpl);
3253  else if (!nodeImpl || !nodeImpl->focused())
3254  m_part->xmlDocImpl()->setFocusNode(0);
3255  }
3256  }
3257 
3258  return swallowEvent;
3259 }
3260 
3261 void TDEHTMLView::setIgnoreWheelEvents( bool e )
3262 {
3263  d->ignoreWheelEvents = e;
3264 }
3265 
3266 #ifndef TQT_NO_WHEELEVENT
3267 
3268 void TDEHTMLView::viewportWheelEvent(TQWheelEvent* e)
3269 {
3270  if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=false;
3271 
3272  if ( ( e->state() & ControlButton) == ControlButton )
3273  {
3274  emit zoomView( - e->delta() );
3275  e->accept();
3276  }
3277  else if (d->firstRelayout)
3278  {
3279  e->accept();
3280  }
3281  else if( ( (e->orientation() == TQt::Vertical &&
3282  ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
3283  || e->delta() > 0 && contentsY() <= 0
3284  || e->delta() < 0 && contentsY() >= contentsHeight() - visibleHeight()))
3285  ||
3286  (e->orientation() == TQt::Horizontal &&
3287  ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
3288  || e->delta() > 0 && contentsX() <=0
3289  || e->delta() < 0 && contentsX() >= contentsWidth() - visibleWidth())))
3290  && m_part->parentPart())
3291  {
3292  if ( m_part->parentPart()->view() )
3293  m_part->parentPart()->view()->wheelEvent( e );
3294  e->ignore();
3295  }
3296  else
3297  {
3298  d->scrollBarMoved = true;
3299 #ifndef NO_SMOOTH_SCROLL_HACK
3300  scrollViewWheelEvent( e );
3301 #else
3302  TQScrollView::viewportWheelEvent( e );
3303 #endif
3304 
3305  TQMouseEvent *tempEvent = new TQMouseEvent( TQEvent::MouseMove, TQPoint(-1,-1), TQPoint(-1,-1), TQt::NoButton, e->state() );
3306  emit viewportMouseMoveEvent ( tempEvent );
3307  delete tempEvent;
3308  }
3309 
3310 }
3311 #endif
3312 
3313 void TDEHTMLView::dragEnterEvent( TQDragEnterEvent* ev )
3314 {
3315  // Handle drops onto frames (#16820)
3316  // Drops on the main html part is handled by Konqueror (and shouldn't do anything
3317  // in e.g. kmail, so not handled here).
3318  if ( m_part->parentPart() )
3319  {
3320  TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
3321  return;
3322  }
3323  TQScrollView::dragEnterEvent( ev );
3324 }
3325 
3326 void TDEHTMLView::dropEvent( TQDropEvent *ev )
3327 {
3328  // Handle drops onto frames (#16820)
3329  // Drops on the main html part is handled by Konqueror (and shouldn't do anything
3330  // in e.g. kmail, so not handled here).
3331  if ( m_part->parentPart() )
3332  {
3333  TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
3334  return;
3335  }
3336  TQScrollView::dropEvent( ev );
3337 }
3338 
3339 void TDEHTMLView::focusInEvent( TQFocusEvent *e )
3340 {
3341 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
3342  m_part->enableFindAheadActions( true );
3343 #endif
3344  DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
3345  if (fn && fn->renderer() && fn->renderer()->isWidget() &&
3346  (e->reason() != TQFocusEvent::Mouse) &&
3347  static_cast<tdehtml::RenderWidget*>(fn->renderer())->widget())
3348  static_cast<tdehtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
3349 #ifndef TDEHTML_NO_CARET
3350  // Restart blink frequency timer if it has been killed, but only on
3351  // editable nodes
3352  if (d->m_caretViewContext &&
3353  d->m_caretViewContext->freqTimerId == -1 &&
3354  fn) {
3355  if (m_part->isCaretMode()
3356  || m_part->isEditable()
3357  || (fn && fn->renderer()
3358  && fn->renderer()->style()->userInput()
3359  == UI_ENABLED)) {
3360  d->m_caretViewContext->freqTimerId = startTimer(500);
3361  d->m_caretViewContext->visible = true;
3362  }/*end if*/
3363  }/*end if*/
3364  showCaret();
3365 #endif // TDEHTML_NO_CARET
3366  TQScrollView::focusInEvent( e );
3367 }
3368 
3369 void TDEHTMLView::focusOutEvent( TQFocusEvent *e )
3370 {
3371  if(m_part) m_part->stopAutoScroll();
3372 
3373 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
3374  if(d->typeAheadActivated)
3375  {
3376  findTimeout();
3377  }
3378  m_part->enableFindAheadActions( false );
3379 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
3380 
3381 #ifndef TDEHTML_NO_CARET
3382  if (d->m_caretViewContext) {
3383  switch (d->m_caretViewContext->displayNonFocused) {
3384  case TDEHTMLPart::CaretInvisible:
3385  hideCaret();
3386  break;
3387  case TDEHTMLPart::CaretVisible: {
3388  killTimer(d->m_caretViewContext->freqTimerId);
3389  d->m_caretViewContext->freqTimerId = -1;
3390  NodeImpl *caretNode = m_part->xmlDocImpl()->focusNode();
3391  if (!d->m_caretViewContext->visible && (m_part->isCaretMode()
3392  || m_part->isEditable()
3393  || (caretNode && caretNode->renderer()
3394  && caretNode->renderer()->style()->userInput()
3395  == UI_ENABLED))) {
3396  d->m_caretViewContext->visible = true;
3397  showCaret(true);
3398  }/*end if*/
3399  break;
3400  }
3401  case TDEHTMLPart::CaretBlink:
3402  // simply leave as is
3403  break;
3404  }/*end switch*/
3405  }/*end if*/
3406 #endif // TDEHTML_NO_CARET
3407 
3408  if ( d->cursor_icon_widget )
3409  d->cursor_icon_widget->hide();
3410 
3411  TQScrollView::focusOutEvent( e );
3412 }
3413 
3414 void TDEHTMLView::slotScrollBarMoved()
3415 {
3416  if ( !d->firstRelayout && !d->complete && m_part->xmlDocImpl() &&
3417  d->layoutSchedulingEnabled) {
3418  // contents scroll while we are not complete: we need to check our layout *now*
3419  tdehtml::RenderCanvas* root = static_cast<tdehtml::RenderCanvas *>( m_part->xmlDocImpl()->renderer() );
3420  if (root && root->needsLayout()) {
3421  unscheduleRelayout();
3422  layout();
3423  }
3424  }
3425  if (!d->scrollingSelf) {
3426  d->scrollBarMoved = true;
3427  d->contentsMoving = true;
3428  // ensure quick reset of contentsMoving flag
3429  scheduleRepaint(0, 0, 0, 0);
3430  }
3431 
3432  if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement())
3433  m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT, true, false);
3434 }
3435 
3436 void TDEHTMLView::timerEvent ( TQTimerEvent *e )
3437 {
3438 // kdDebug() << "timer event " << e->timerId() << endl;
3439  if ( e->timerId() == d->scrollTimerId ) {
3440  if( d->scrollSuspended )
3441  return;
3442  switch (d->scrollDirection) {
3443  case TDEHTMLViewPrivate::ScrollDown:
3444  if (contentsY() + visibleHeight () >= contentsHeight())
3445  d->newScrollTimer(this, 0);
3446  else
3447  scrollBy( 0, d->scrollBy );
3448  break;
3449  case TDEHTMLViewPrivate::ScrollUp:
3450  if (contentsY() <= 0)
3451  d->newScrollTimer(this, 0);
3452  else
3453  scrollBy( 0, -d->scrollBy );
3454  break;
3455  case TDEHTMLViewPrivate::ScrollRight:
3456  if (contentsX() + visibleWidth () >= contentsWidth())
3457  d->newScrollTimer(this, 0);
3458  else
3459  scrollBy( d->scrollBy, 0 );
3460  break;
3461  case TDEHTMLViewPrivate::ScrollLeft:
3462  if (contentsX() <= 0)
3463  d->newScrollTimer(this, 0);
3464  else
3465  scrollBy( -d->scrollBy, 0 );
3466  break;
3467  }
3468  return;
3469  }
3470  else if ( e->timerId() == d->layoutTimerId ) {
3471  d->dirtyLayout = true;
3472  layout();
3473  if (d->firstRelayout) {
3474  d->firstRelayout = false;
3475  verticalScrollBar()->setEnabled( true );
3476  horizontalScrollBar()->setEnabled( true );
3477  }
3478  }
3479 #ifndef TDEHTML_NO_CARET
3480  else if (d->m_caretViewContext
3481  && e->timerId() == d->m_caretViewContext->freqTimerId) {
3482  d->m_caretViewContext->visible = !d->m_caretViewContext->visible;
3483  if (d->m_caretViewContext->displayed) {
3484  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3485  d->m_caretViewContext->width,
3486  d->m_caretViewContext->height);
3487  }/*end if*/
3488 // if (d->m_caretViewContext->visible) cout << "|" << flush;
3489 // else cout << "" << flush;
3490  return;
3491  }
3492 #endif
3493 
3494  d->contentsMoving = false;
3495  if( m_part->xmlDocImpl() ) {
3496  DOM::DocumentImpl *document = m_part->xmlDocImpl();
3497  tdehtml::RenderCanvas* root = static_cast<tdehtml::RenderCanvas *>(document->renderer());
3498 
3499  if ( root && root->needsLayout() ) {
3500  killTimer(d->repaintTimerId);
3501  d->repaintTimerId = 0;
3502  scheduleRelayout();
3503  return;
3504  }
3505  }
3506 
3507  setStaticBackground(d->useSlowRepaints);
3508 
3509 // kdDebug() << "scheduled repaint "<< d->repaintTimerId << endl;
3510  killTimer(d->repaintTimerId);
3511  d->repaintTimerId = 0;
3512 
3513  TQRect updateRegion;
3514  TQMemArray<TQRect> rects = d->updateRegion.rects();
3515 
3516  d->updateRegion = TQRegion();
3517 
3518  if ( rects.size() )
3519  updateRegion = rects[0];
3520 
3521  for ( unsigned i = 1; i < rects.size(); ++i ) {
3522  TQRect newRegion = updateRegion.unite(rects[i]);
3523  if (2*newRegion.height() > 3*updateRegion.height() )
3524  {
3525  repaintContents( updateRegion );
3526  updateRegion = rects[i];
3527  }
3528  else
3529  updateRegion = newRegion;
3530  }
3531 
3532  if ( !updateRegion.isNull() )
3533  repaintContents( updateRegion );
3534 
3535  // As widgets can only be accurately positioned during painting, every layout might
3536  // dissociate a widget from its RenderWidget. E.g: if a RenderWidget was visible before layout, but the layout
3537  // pushed it out of the viewport, it will not be repainted, and consequently it's assocoated widget won't be repositioned!
3538  // Thus we need to check each supposedly 'visible' widget at the end of each layout, and remove it in case it's no more in sight.
3539 
3540  if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
3541  TQWidget* w;
3542  d->dirtyLayout = false;
3543 
3544  TQRect visibleRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
3545  TQPtrList<RenderWidget> toRemove;
3546  for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
3547  int xp = 0, yp = 0;
3548  w = it.current();
3549  RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
3550  if (!rw->absolutePosition(xp, yp) ||
3551  !visibleRect.intersects(TQRect(xp, yp, w->width(), w->height())))
3552  toRemove.append(rw);
3553  }
3554  for (RenderWidget* r = toRemove.first(); r; r = toRemove.next())
3555  if ( (w = d->visibleWidgets.take(r) ) )
3556  addChild(w, 0, -500000);
3557  }
3558 
3559  emit repaintAccessKeys();
3560  if (d->emitCompletedAfterRepaint) {
3561  bool full = d->emitCompletedAfterRepaint == TDEHTMLViewPrivate::CSFull;
3562  d->emitCompletedAfterRepaint = TDEHTMLViewPrivate::CSNone;
3563  if ( full )
3564  emit m_part->completed();
3565  else
3566  emit m_part->completed(true);
3567  }
3568 }
3569 
3570 void TDEHTMLView::scheduleRelayout(tdehtml::RenderObject * /*clippedObj*/)
3571 {
3572  if (!d->layoutSchedulingEnabled || d->layoutTimerId)
3573  return;
3574 
3575  d->layoutTimerId = startTimer( m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()
3576  ? 1000 : 0 );
3577 }
3578 
3579 void TDEHTMLView::unscheduleRelayout()
3580 {
3581  if (!d->layoutTimerId)
3582  return;
3583 
3584  killTimer(d->layoutTimerId);
3585  d->layoutTimerId = 0;
3586 }
3587 
3588 void TDEHTMLView::unscheduleRepaint()
3589 {
3590  if (!d->repaintTimerId)
3591  return;
3592 
3593  killTimer(d->repaintTimerId);
3594  d->repaintTimerId = 0;
3595 }
3596 
3597 void TDEHTMLView::scheduleRepaint(int x, int y, int w, int h, bool asap)
3598 {
3599  bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
3600 
3601 // kdDebug() << "parsing " << parsing << endl;
3602 // kdDebug() << "complete " << d->complete << endl;
3603 
3604  int time = parsing ? 300 : (!asap ? ( !d->complete ? 100 : 20 ) : 0);
3605 
3606 #ifdef DEBUG_FLICKER
3607  TQPainter p;
3608  p.begin( viewport() );
3609 
3610  int vx, vy;
3611  contentsToViewport( x, y, vx, vy );
3612  p.fillRect( vx, vy, w, h, TQt::red );
3613  p.end();
3614 #endif
3615 
3616  d->updateRegion = d->updateRegion.unite(TQRect(x,y,w,h));
3617 
3618  if (asap && !parsing)
3619  unscheduleRepaint();
3620 
3621  if ( !d->repaintTimerId )
3622  d->repaintTimerId = startTimer( time );
3623 
3624 // kdDebug() << "starting timer " << time << endl;
3625 }
3626 
3627 void TDEHTMLView::complete( bool pendingAction )
3628 {
3629 // kdDebug() << "TDEHTMLView::complete()" << endl;
3630 
3631  d->complete = true;
3632 
3633  // is there a relayout pending?
3634  if (d->layoutTimerId)
3635  {
3636 // kdDebug() << "requesting relayout now" << endl;
3637  // do it now
3638  killTimer(d->layoutTimerId);
3639  d->layoutTimerId = startTimer( 0 );
3640  d->emitCompletedAfterRepaint = pendingAction ?
3641  TDEHTMLViewPrivate::CSActionPending : TDEHTMLViewPrivate::CSFull;
3642  }
3643 
3644  // is there a repaint pending?
3645  if (d->repaintTimerId)
3646  {
3647 // kdDebug() << "requesting repaint now" << endl;
3648  // do it now
3649  killTimer(d->repaintTimerId);
3650  d->repaintTimerId = startTimer( 20 );
3651  d->emitCompletedAfterRepaint = pendingAction ?
3652  TDEHTMLViewPrivate::CSActionPending : TDEHTMLViewPrivate::CSFull;
3653  }
3654 
3655  if (!d->emitCompletedAfterRepaint)
3656  {
3657  if (!pendingAction)
3658  emit m_part->completed();
3659  else
3660  emit m_part->completed(true);
3661  }
3662 
3663 }
3664 
3665 void TDEHTMLView::slotMouseScrollTimer()
3666 {
3667  scrollBy( d->m_mouseScroll_byX, d->m_mouseScroll_byY );
3668 }
3669 
3670 #ifndef TDEHTML_NO_CARET
3671 
3672 // ### the dependencies on static functions are a nightmare. just be
3673 // hacky and include the implementation here. Clean me up, please.
3674 
3675 #include "tdehtml_caret.cpp"
3676 
3677 void TDEHTMLView::initCaret(bool keepSelection)
3678 {
3679 #if DEBUG_CARETMODE > 0
3680  kdDebug(6200) << "begin initCaret" << endl;
3681 #endif
3682  // save caretMoved state as moveCaretTo changes it
3683  if (m_part->xmlDocImpl()) {
3684 #if 0
3685  ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
3686  if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
3687 #endif
3688  d->caretViewContext();
3689  bool cmoved = d->m_caretViewContext->caretMoved;
3690  if (m_part->d->caretNode().isNull()) {
3691  // set to document, position will be sanitized anyway
3692  m_part->d->caretNode() = m_part->document();
3693  m_part->d->caretOffset() = 0L;
3694  // This sanity check is necessary for the not so unlikely case that
3695  // setEditable or setCaretMode is called before any render objects have
3696  // been created.
3697  if (!m_part->d->caretNode().handle()->renderer()) return;
3698  }/*end if*/
3699 // kdDebug(6200) << "d->m_selectionStart " << m_part->d->m_selectionStart.handle()
3700 // << " d->m_selectionEnd " << m_part->d->m_selectionEnd.handle() << endl;
3701  // ### does not repaint the selection on keepSelection!=false
3702  moveCaretTo(m_part->d->caretNode().handle(), m_part->d->caretOffset(), !keepSelection);
3703 // kdDebug(6200) << "d->m_selectionStart " << m_part->d->m_selectionStart.handle()
3704 // << " d->m_selectionEnd " << m_part->d->m_selectionEnd.handle() << endl;
3705  d->m_caretViewContext->caretMoved = cmoved;
3706  }/*end if*/
3707 #if DEBUG_CARETMODE > 0
3708  kdDebug(6200) << "end initCaret" << endl;
3709 #endif
3710 }
3711 
3712 bool TDEHTMLView::caretOverrides() const
3713 {
3714  bool cm = m_part->isCaretMode();
3715  bool dm = m_part->isEditable();
3716  return cm && !dm ? false
3717  : (dm || m_part->d->caretNode().handle()->contentEditable())
3718  && d->editorContext()->override;
3719 }
3720 
3721 void TDEHTMLView::ensureNodeHasFocus(NodeImpl *node)
3722 {
3723  if (m_part->isCaretMode() || m_part->isEditable()) return;
3724  if (node->focused()) return;
3725 
3726  // Find first ancestor whose "user-input" is "enabled"
3727  NodeImpl *firstAncestor = 0;
3728  while (node) {
3729  if (node->renderer()
3730  && node->renderer()->style()->userInput() != UI_ENABLED)
3731  break;
3732  firstAncestor = node;
3733  node = node->parentNode();
3734  }/*wend*/
3735 
3736  if (!node) firstAncestor = 0;
3737 
3738  DocumentImpl *doc = m_part->xmlDocImpl();
3739  // ensure that embedded widgets don't lose their focus
3740  if (!firstAncestor && doc->focusNode() && doc->focusNode()->renderer()
3741  && doc->focusNode()->renderer()->isWidget())
3742  return;
3743 
3744  // Set focus node on the document
3745 #if DEBUG_CARETMODE > 1
3746  kdDebug(6200) << k_funcinfo << "firstAncestor " << firstAncestor << ": "
3747  << (firstAncestor ? firstAncestor->nodeName().string() : TQString::null) << endl;
3748 #endif
3749  doc->setFocusNode(firstAncestor);
3750  emit m_part->nodeActivated(Node(firstAncestor));
3751 }
3752 
3753 void TDEHTMLView::recalcAndStoreCaretPos(CaretBox *hintBox)
3754 {
3755  if (!m_part || m_part->d->caretNode().isNull()) return;
3756  d->caretViewContext();
3757  NodeImpl *caretNode = m_part->d->caretNode().handle();
3758 #if DEBUG_CARETMODE > 0
3759  kdDebug(6200) << "recalcAndStoreCaretPos: caretNode=" << caretNode << (caretNode ? " "+caretNode->nodeName().string() : TQString::null) << " r@" << caretNode->renderer() << (caretNode->renderer() && caretNode->renderer()->isText() ? " \"" + TQConstString(static_cast<RenderText *>(caretNode->renderer())->str->s, kMin(static_cast<RenderText *>(caretNode->renderer())->str->l, 15u)).string() + "\"" : TQString::null) << endl;
3760 #endif
3761  caretNode->getCaret(m_part->d->caretOffset(), caretOverrides(),
3762  d->m_caretViewContext->x, d->m_caretViewContext->y,
3763  d->m_caretViewContext->width,
3764  d->m_caretViewContext->height);
3765 
3766  if (hintBox && d->m_caretViewContext->x == -1) {
3767 #if DEBUG_CARETMODE > 1
3768  kdDebug(6200) << "using hint inline box coordinates" << endl;
3769 #endif
3770  RenderObject *r = caretNode->renderer();
3771  const TQFontMetrics &fm = r->style()->fontMetrics();
3772  int absx, absy;
3773  r->containingBlock()->absolutePosition(absx, absy,
3774  false); // ### what about fixed?
3775  d->m_caretViewContext->x = absx + hintBox->xPos();
3776  d->m_caretViewContext->y = absy + hintBox->yPos();
3777 // + hintBox->baseline() - fm.ascent();
3778  d->m_caretViewContext->width = 1;
3779  // ### firstline not regarded. But I think it can be safely neglected
3780  // as hint boxes are only used for empty lines.
3781  d->m_caretViewContext->height = fm.height();
3782  }/*end if*/
3783 
3784 #if DEBUG_CARETMODE > 4
3785 // kdDebug(6200) << "freqTimerId: "<<d->m_caretViewContext->freqTimerId<<endl;
3786 #endif
3787 #if DEBUG_CARETMODE > 0
3788  kdDebug(6200) << "caret: ofs="<<m_part->d->caretOffset()<<" "
3789  <<" x="<<d->m_caretViewContext->x<<" y="<<d->m_caretViewContext->y
3790  <<" h="<<d->m_caretViewContext->height<<endl;
3791 #endif
3792 }
3793 
3794 void TDEHTMLView::caretOn()
3795 {
3796  if (d->m_caretViewContext) {
3797  killTimer(d->m_caretViewContext->freqTimerId);
3798 
3799  if (hasFocus() || d->m_caretViewContext->displayNonFocused
3800  == TDEHTMLPart::CaretBlink) {
3801  d->m_caretViewContext->freqTimerId = startTimer(500);
3802  } else {
3803  d->m_caretViewContext->freqTimerId = -1;
3804  }/*end if*/
3805 
3806  d->m_caretViewContext->visible = true;
3807  if ((d->m_caretViewContext->displayed = (hasFocus()
3808  || d->m_caretViewContext->displayNonFocused
3809  != TDEHTMLPart::CaretInvisible))) {
3810  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3811  d->m_caretViewContext->width,
3812  d->m_caretViewContext->height);
3813  }/*end if*/
3814 // kdDebug(6200) << "caret on" << endl;
3815  }/*end if*/
3816 }
3817 
3818 void TDEHTMLView::caretOff()
3819 {
3820  if (d->m_caretViewContext) {
3821  killTimer(d->m_caretViewContext->freqTimerId);
3822  d->m_caretViewContext->freqTimerId = -1;
3823  d->m_caretViewContext->displayed = false;
3824  if (d->m_caretViewContext->visible) {
3825  d->m_caretViewContext->visible = false;
3826  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3827  d->m_caretViewContext->width,
3828  d->m_caretViewContext->height);
3829  }/*end if*/
3830 // kdDebug(6200) << "caret off" << endl;
3831  }/*end if*/
3832 }
3833 
3834 void TDEHTMLView::showCaret(bool forceRepaint)
3835 {
3836  if (d->m_caretViewContext) {
3837  d->m_caretViewContext->displayed = true;
3838  if (d->m_caretViewContext->visible) {
3839  if (!forceRepaint) {
3840  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3841  d->m_caretViewContext->width,
3842  d->m_caretViewContext->height);
3843  } else {
3844  repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3845  d->m_caretViewContext->width,
3846  d->m_caretViewContext->height);
3847  }/*end if*/
3848  }/*end if*/
3849 // kdDebug(6200) << "caret shown" << endl;
3850  }/*end if*/
3851 }
3852 
3853 bool TDEHTMLView::foldSelectionToCaret(NodeImpl *startNode, long startOffset,
3854  NodeImpl *endNode, long endOffset)
3855 {
3856  m_part->d->m_selectionStart = m_part->d->m_selectionEnd = m_part->d->caretNode();
3857  m_part->d->m_startOffset = m_part->d->m_endOffset = m_part->d->caretOffset();
3858  m_part->d->m_extendAtEnd = true;
3859 
3860  bool folded = startNode != endNode || startOffset != endOffset;
3861 
3862  // Only clear the selection if there has been one.
3863  if (folded) {
3864  m_part->xmlDocImpl()->clearSelection();
3865  }/*end if*/
3866 
3867  return folded;
3868 }
3869 
3870 void TDEHTMLView::hideCaret()
3871 {
3872  if (d->m_caretViewContext) {
3873  if (d->m_caretViewContext->visible) {
3874 // kdDebug(6200) << "redraw caret hidden" << endl;
3875  d->m_caretViewContext->visible = false;
3876  // force repaint, otherwise the event won't be handled
3877  // before the focus leaves the window
3878  repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3879  d->m_caretViewContext->width,
3880  d->m_caretViewContext->height);
3881  d->m_caretViewContext->visible = true;
3882  }/*end if*/
3883  d->m_caretViewContext->displayed = false;
3884 // kdDebug(6200) << "caret hidden" << endl;
3885  }/*end if*/
3886 }
3887 
3888 int TDEHTMLView::caretDisplayPolicyNonFocused() const
3889 {
3890  if (d->m_caretViewContext)
3891  return d->m_caretViewContext->displayNonFocused;
3892  else
3893  return TDEHTMLPart::CaretInvisible;
3894 }
3895 
3896 void TDEHTMLView::setCaretDisplayPolicyNonFocused(int policy)
3897 {
3898  d->caretViewContext();
3899 // int old = d->m_caretViewContext->displayNonFocused;
3900  d->m_caretViewContext->displayNonFocused = (TDEHTMLPart::CaretDisplayPolicy)policy;
3901 
3902  // make change immediately take effect if not focused
3903  if (!hasFocus()) {
3904  switch (d->m_caretViewContext->displayNonFocused) {
3905  case TDEHTMLPart::CaretInvisible:
3906  hideCaret();
3907  break;
3908  case TDEHTMLPart::CaretBlink:
3909  if (d->m_caretViewContext->freqTimerId != -1) break;
3910  d->m_caretViewContext->freqTimerId = startTimer(500);
3911  // fall through
3912  case TDEHTMLPart::CaretVisible:
3913  d->m_caretViewContext->displayed = true;
3914  showCaret();
3915  break;
3916  }/*end switch*/
3917  }/*end if*/
3918 }
3919 
3920 bool TDEHTMLView::placeCaret(CaretBox *hintBox)
3921 {
3922  CaretViewContext *cv = d->caretViewContext();
3923  caretOff();
3924  NodeImpl *caretNode = m_part->d->caretNode().handle();
3925  // ### why is it sometimes null?
3926  if (!caretNode || !caretNode->renderer()) return false;
3927  ensureNodeHasFocus(caretNode);
3928  if (m_part->isCaretMode() || m_part->isEditable()
3929  || caretNode->renderer()->style()->userInput() == UI_ENABLED) {
3930  recalcAndStoreCaretPos(hintBox);
3931 
3932  cv->origX = cv->x;
3933 
3934  caretOn();
3935  return true;
3936  }/*end if*/
3937  return false;
3938 }
3939 
3940 void TDEHTMLView::ensureCaretVisible()
3941 {
3942  CaretViewContext *cv = d->m_caretViewContext;
3943  if (!cv) return;
3944  ensureVisible(cv->x, cv->y, cv->width, cv->height);
3945  d->scrollBarMoved = false;
3946 }
3947 
3948 bool TDEHTMLView::extendSelection(NodeImpl *oldStartSel, long oldStartOfs,
3949  NodeImpl *oldEndSel, long oldEndOfs)
3950 {
3951  bool changed = false;
3952  if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
3953  && m_part->d->m_startOffset == m_part->d->m_endOffset) {
3954  changed = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
3955  m_part->d->m_extendAtEnd = true;
3956  } else do {
3957  changed = m_part->d->m_selectionStart.handle() != oldStartSel
3958  || m_part->d->m_startOffset != oldStartOfs
3959  || m_part->d->m_selectionEnd.handle() != oldEndSel
3960  || m_part->d->m_endOffset != oldEndOfs;
3961  if (!changed) break;
3962 
3963  // determine start position -- caret position is always at end.
3964  NodeImpl *startNode;
3965  long startOffset;
3966  if (m_part->d->m_extendAtEnd) {
3967  startNode = m_part->d->m_selectionStart.handle();
3968  startOffset = m_part->d->m_startOffset;
3969  } else {
3970  startNode = m_part->d->m_selectionEnd.handle();
3971  startOffset = m_part->d->m_endOffset;
3972  m_part->d->m_selectionEnd = m_part->d->m_selectionStart;
3973  m_part->d->m_endOffset = m_part->d->m_startOffset;
3974  m_part->d->m_extendAtEnd = true;
3975  }/*end if*/
3976 
3977  bool swapNeeded = false;
3978  if (!m_part->d->m_selectionEnd.isNull() && startNode) {
3979  swapNeeded = RangeImpl::compareBoundaryPoints(startNode, startOffset,
3980  m_part->d->m_selectionEnd.handle(),
3981  m_part->d->m_endOffset) >= 0;
3982  }/*end if*/
3983 
3984  m_part->d->m_selectionStart = startNode;
3985  m_part->d->m_startOffset = startOffset;
3986 
3987  if (swapNeeded) {
3988  m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionEnd.handle(),
3989  m_part->d->m_endOffset, m_part->d->m_selectionStart.handle(),
3990  m_part->d->m_startOffset);
3991  } else {
3992  m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
3993  m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
3994  m_part->d->m_endOffset);
3995  }/*end if*/
3996  } while(false);/*end if*/
3997  return changed;
3998 }
3999 
4000 void TDEHTMLView::updateSelection(NodeImpl *oldStartSel, long oldStartOfs,
4001  NodeImpl *oldEndSel, long oldEndOfs)
4002 {
4003  if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
4004  && m_part->d->m_startOffset == m_part->d->m_endOffset) {
4005  if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs)) {
4006  m_part->emitSelectionChanged();
4007  }/*end if*/
4008  m_part->d->m_extendAtEnd = true;
4009  } else {
4010  // check if the extending end has passed the immobile end
4011  if (!m_part->d->m_selectionEnd.isNull() && !m_part->d->m_selectionEnd.isNull()) {
4012  bool swapNeeded = RangeImpl::compareBoundaryPoints(
4013  m_part->d->m_selectionStart.handle(), m_part->d->m_startOffset,
4014  m_part->d->m_selectionEnd.handle(), m_part->d->m_endOffset) >= 0;
4015  if (swapNeeded) {
4016  DOM::Node tmpNode = m_part->d->m_selectionStart;
4017  long tmpOffset = m_part->d->m_startOffset;
4018  m_part->d->m_selectionStart = m_part->d->m_selectionEnd;
4019  m_part->d->m_startOffset = m_part->d->m_endOffset;
4020  m_part->d->m_selectionEnd = tmpNode;
4021  m_part->d->m_endOffset = tmpOffset;
4022  m_part->d->m_startBeforeEnd = true;
4023  m_part->d->m_extendAtEnd = !m_part->d->m_extendAtEnd;
4024  }/*end if*/
4025  }/*end if*/
4026 
4027  m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
4028  m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
4029  m_part->d->m_endOffset);
4030  m_part->emitSelectionChanged();
4031  }/*end if*/
4032 }
4033 
4034 void TDEHTMLView::caretKeyPressEvent(TQKeyEvent *_ke)
4035 {
4036  NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
4037  long oldStartOfs = m_part->d->m_startOffset;
4038  NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
4039  long oldEndOfs = m_part->d->m_endOffset;
4040 
4041  NodeImpl *oldCaretNode = m_part->d->caretNode().handle();
4042  long oldOffset = m_part->d->caretOffset();
4043 
4044  bool ctrl = _ke->state() & ControlButton;
4045 
4046 // FIXME: this is that widely indented because I will write ifs around it.
4047  switch(_ke->key()) {
4048  case Key_Space:
4049  break;
4050 
4051  case Key_Down:
4052  moveCaretNextLine(1);
4053  break;
4054 
4055  case Key_Up:
4056  moveCaretPrevLine(1);
4057  break;
4058 
4059  case Key_Left:
4060  moveCaretBy(false, ctrl ? CaretByWord : CaretByCharacter, 1);
4061  break;
4062 
4063  case Key_Right:
4064  moveCaretBy(true, ctrl ? CaretByWord : CaretByCharacter, 1);
4065  break;
4066 
4067  case Key_Next:
4068  moveCaretNextPage();
4069  break;
4070 
4071  case Key_Prior:
4072  moveCaretPrevPage();
4073  break;
4074 
4075  case Key_Home:
4076  if (ctrl)
4077  moveCaretToDocumentBoundary(false);
4078  else
4079  moveCaretToLineBegin();
4080  break;
4081 
4082  case Key_End:
4083  if (ctrl)
4084  moveCaretToDocumentBoundary(true);
4085  else
4086  moveCaretToLineEnd();
4087  break;
4088 
4089  }/*end switch*/
4090 
4091  if ((m_part->d->caretNode().handle() != oldCaretNode
4092  || m_part->d->caretOffset() != oldOffset)
4093  // node should never be null, but faulty conditions may cause it to be
4094  && !m_part->d->caretNode().isNull()) {
4095 
4096  d->m_caretViewContext->caretMoved = true;
4097 
4098  if (_ke->state() & ShiftButton) { // extend selection
4099  updateSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4100  } else { // clear any selection
4101  if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs))
4102  m_part->emitSelectionChanged();
4103  }/*end if*/
4104 
4105  m_part->emitCaretPositionChanged(m_part->d->caretNode(), m_part->d->caretOffset());
4106  }/*end if*/
4107 
4108  _ke->accept();
4109 }
4110 
4111 bool TDEHTMLView::moveCaretTo(NodeImpl *node, long offset, bool clearSel)
4112 {
4113  if (!node) return false;
4114  ElementImpl *baseElem = determineBaseElement(node);
4115  RenderFlow *base = static_cast<RenderFlow *>(baseElem ? baseElem->renderer() : 0);
4116  if (!node) return false;
4117 
4118  // need to find out the node's inline box. If there is none, this function
4119  // will snap to the next node that has one. This is necessary to make the
4120  // caret visible in any case.
4121  CaretBoxLineDeleter cblDeleter;
4122 // RenderBlock *cb;
4123  long r_ofs;
4124  CaretBoxIterator cbit;
4125  CaretBoxLine *cbl = findCaretBoxLine(node, offset, &cblDeleter, base, r_ofs, cbit);
4126  if(!cbl) {
4127  kdWarning() << "TDEHTMLView::moveCaretTo - findCaretBoxLine() returns NULL" << endl;
4128  return false;
4129  }
4130 
4131 #if DEBUG_CARETMODE > 3
4132  if (cbl) kdDebug(6200) << cbl->information() << endl;
4133 #endif
4134  CaretBox *box = *cbit;
4135  if (cbit != cbl->end() && box->object() != node->renderer()) {
4136  if (box->object()->element()) {
4137  mapRenderPosToDOMPos(box->object(), r_ofs, box->isOutside(),
4138  box->isOutsideEnd(), node, offset);
4139  //if (!outside) offset = node->minOffset();
4140 #if DEBUG_CARETMODE > 1
4141  kdDebug(6200) << "set new node " << node->nodeName().string() << "@" << node << endl;
4142 #endif
4143  } else { // box has no associated element -> do not use
4144  // this case should actually never happen.
4145  box = 0;
4146  kdError(6200) << "Box contains no node! Crash imminent" << endl;
4147  }/*end if*/
4148  }
4149 
4150  NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
4151  long oldStartOfs = m_part->d->m_startOffset;
4152  NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
4153  long oldEndOfs = m_part->d->m_endOffset;
4154 
4155  // test for position change
4156  bool posChanged = m_part->d->caretNode().handle() != node
4157  || m_part->d->caretOffset() != offset;
4158  bool selChanged = false;
4159 
4160  m_part->d->caretNode() = node;
4161  m_part->d->caretOffset() = offset;
4162  if (clearSel || !oldStartSel || !oldEndSel) {
4163  selChanged = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4164  } else {
4165  //kdDebug(6200) << "moveToCaret: extendSelection: m_extendAtEnd " << m_part->d->m_extendAtEnd << endl;
4166  //kdDebug(6200) << "selection: start(" << m_part->d->m_selectionStart.handle() << "," << m_part->d->m_startOffset << "), end(" << m_part->d->m_selectionEnd.handle() << "," << m_part->d->m_endOffset << "), caret(" << m_part->d->caretNode().handle() << "," << m_part->d->caretOffset() << ")" << endl;
4167  selChanged = extendSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4168  //kdDebug(6200) << "after extendSelection: m_extendAtEnd " << m_part->d->m_extendAtEnd << endl;
4169  //kdDebug(6200) << "selection: start(" << m_part->d->m_selectionStart.handle() << "," << m_part->d->m_startOffset << "), end(" << m_part->d->m_selectionEnd.handle() << "," << m_part->d->m_endOffset << "), caret(" << m_part->d->caretNode().handle() << "," << m_part->d->caretOffset() << ")" << endl;
4170  }/*end if*/
4171 
4172  d->caretViewContext()->caretMoved = true;
4173 
4174  bool visible_caret = placeCaret(box);
4175 
4176  // FIXME: if the old position was !visible_caret, and the new position is
4177  // also, then two caretPositionChanged signals with a null Node are
4178  // emitted in series.
4179  if (posChanged) {
4180  m_part->emitCaretPositionChanged(visible_caret ? node : 0, offset);
4181  }/*end if*/
4182 
4183  return selChanged;
4184 }
4185 
4186 void TDEHTMLView::moveCaretByLine(bool next, int count)
4187 {
4188  Node &caretNodeRef = m_part->d->caretNode();
4189  if (caretNodeRef.isNull()) return;
4190 
4191  NodeImpl *caretNode = caretNodeRef.handle();
4192 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4193  long offset = m_part->d->caretOffset();
4194 
4195  CaretViewContext *cv = d->caretViewContext();
4196 
4197  ElementImpl *baseElem = determineBaseElement(caretNode);
4198  LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4199 
4200  ErgonomicEditableLineIterator it(ld.current(), cv->origX);
4201 
4202  // move count lines vertically
4203  while (count > 0 && it != ld.end() && it != ld.preBegin()) {
4204  count--;
4205  if (next) ++it; else --it;
4206  }/*wend*/
4207 
4208  // Nothing? Then leave everything as is.
4209  if (it == ld.end() || it == ld.preBegin()) return;
4210 
4211  int x, absx, absy;
4212  CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
4213 
4214  placeCaretOnLine(caretBox, x, absx, absy);
4215 }
4216 
4217 void TDEHTMLView::placeCaretOnLine(CaretBox *caretBox, int x, int absx, int absy)
4218 {
4219  // paranoia sanity check
4220  if (!caretBox) return;
4221 
4222  RenderObject *caretRender = caretBox->object();
4223 
4224 #if DEBUG_CARETMODE > 0
4225  kdDebug(6200) << "got valid caretBox " << caretBox << endl;
4226  kdDebug(6200) << "xPos: " << caretBox->xPos() << " yPos: " << caretBox->yPos()
4227  << " width: " << caretBox->width() << " height: " << caretBox->height() << endl;
4228  InlineTextBox *tb = static_cast<InlineTextBox *>(caretBox->inlineBox());
4229  if (caretBox->isInlineTextBox()) { kdDebug(6200) << "contains \"" << TQString(static_cast<RenderText *>(tb->object())->str->s + tb->m_start, tb->m_len) << "\"" << endl;}
4230 #endif
4231  // inquire height of caret
4232  int caretHeight = caretBox->height();
4233  bool isText = caretBox->isInlineTextBox();
4234  int yOfs = 0; // y-offset for text nodes
4235  if (isText) {
4236  // text boxes need extrawurst
4237  RenderText *t = static_cast<RenderText *>(caretRender);
4238  const TQFontMetrics &fm = t->metrics(caretBox->inlineBox()->m_firstLine);
4239  caretHeight = fm.height();
4240  yOfs = caretBox->inlineBox()->baseline() - fm.ascent();
4241  }/*end if*/
4242 
4243  caretOff();
4244 
4245  // set new caret node
4246  NodeImpl *caretNode;
4247  long &offset = m_part->d->caretOffset();
4248  mapRenderPosToDOMPos(caretRender, offset, caretBox->isOutside(),
4249  caretBox->isOutsideEnd(), caretNode, offset);
4250 
4251  // set all variables not needing special treatment
4252  d->m_caretViewContext->y = caretBox->yPos() + yOfs;
4253  d->m_caretViewContext->height = caretHeight;
4254  d->m_caretViewContext->width = 1; // FIXME: regard override
4255 
4256  int xPos = caretBox->xPos();
4257  int caretBoxWidth = caretBox->width();
4258  d->m_caretViewContext->x = xPos;
4259 
4260  if (!caretBox->isOutside()) {
4261  // before or at beginning of inline box -> place at beginning
4262  long r_ofs = 0;
4263  if (x <= xPos) {
4264  r_ofs = caretBox->minOffset();
4265  // somewhere within this block
4266  } else if (x > xPos && x <= xPos + caretBoxWidth) {
4267  if (isText) { // find out where exactly
4268  r_ofs = static_cast<InlineTextBox *>(caretBox->inlineBox())
4269  ->offsetForPoint(x, d->m_caretViewContext->x);
4270 #if DEBUG_CARETMODE > 2
4271  kdDebug(6200) << "deviation from origX " << d->m_caretViewContext->x - x << endl;
4272 #endif
4273 #if 0
4274  } else { // snap to nearest end
4275  if (xPos + caretBoxWidth - x < x - xPos) {
4276  d->m_caretViewContext->x = xPos + caretBoxWidth;
4277  r_ofs = caretNode ? caretNode->maxOffset() : 1;
4278  } else {
4279  d->m_caretViewContext->x = xPos;
4280  r_ofs = caretNode ? caretNode->minOffset() : 0;
4281  }/*end if*/
4282 #endif
4283  }/*end if*/
4284  } else { // after the inline box -> place at end
4285  d->m_caretViewContext->x = xPos + caretBoxWidth;
4286  r_ofs = caretBox->maxOffset();
4287  }/*end if*/
4288  offset = r_ofs;
4289  }/*end if*/
4290 #if DEBUG_CARETMODE > 0
4291  kdDebug(6200) << "new offset: " << offset << endl;
4292 #endif
4293 
4294  m_part->d->caretNode() = caretNode;
4295  m_part->d->caretOffset() = offset;
4296 
4297  d->m_caretViewContext->x += absx;
4298  d->m_caretViewContext->y += absy;
4299 
4300 #if DEBUG_CARETMODE > 1
4301  kdDebug(6200) << "new caret position: x " << d->m_caretViewContext->x << " y " << d->m_caretViewContext->y << " w " << d->m_caretViewContext->width << " h " << d->m_caretViewContext->height << " absx " << absx << " absy " << absy << endl;
4302 #endif
4303 
4304  ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
4305  d->m_caretViewContext->width, d->m_caretViewContext->height);
4306  d->scrollBarMoved = false;
4307 
4308  ensureNodeHasFocus(caretNode);
4309  caretOn();
4310 }
4311 
4312 void TDEHTMLView::moveCaretToLineBoundary(bool end)
4313 {
4314  Node &caretNodeRef = m_part->d->caretNode();
4315  if (caretNodeRef.isNull()) return;
4316 
4317  NodeImpl *caretNode = caretNodeRef.handle();
4318 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4319  long offset = m_part->d->caretOffset();
4320 
4321  ElementImpl *baseElem = determineBaseElement(caretNode);
4322  LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4323 
4324  EditableLineIterator it = ld.current();
4325  if (it == ld.end()) return; // should not happen, but who knows
4326 
4327  EditableCaretBoxIterator fbit(it, end);
4328  Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
4329  CaretBox *b = *fbit;
4330 
4331  RenderObject *cb = b->containingBlock();
4332  int absx, absy;
4333 
4334  if (cb) cb->absolutePosition(absx,absy);
4335  else absx = absy = 0;
4336 
4337  int x = b->xPos() + (end && !b->isOutside() ? b->width() : 0);
4338  d->m_caretViewContext->origX = absx + x;
4339  placeCaretOnLine(b, x, absx, absy);
4340 }
4341 
4342 void TDEHTMLView::moveCaretToDocumentBoundary(bool end)
4343 {
4344  Node &caretNodeRef = m_part->d->caretNode();
4345  if (caretNodeRef.isNull()) return;
4346 
4347  NodeImpl *caretNode = caretNodeRef.handle();
4348 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4349  long offset = m_part->d->caretOffset();
4350 
4351  ElementImpl *baseElem = determineBaseElement(caretNode);
4352  LinearDocument ld(m_part, caretNode, offset, IndicatedFlows, baseElem);
4353 
4354  EditableLineIterator it(end ? ld.preEnd() : ld.begin(), end);
4355  if (it == ld.end() || it == ld.preBegin()) return; // should not happen, but who knows
4356 
4357  EditableCaretBoxIterator fbit = it;
4358  Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
4359  CaretBox *b = *fbit;
4360 
4361  RenderObject *cb = (*it)->containingBlock();
4362  int absx, absy;
4363 
4364  if (cb) cb->absolutePosition(absx, absy);
4365  else absx = absy = 0;
4366 
4367  int x = b->xPos()/* + (end ? b->width() : 0) reactivate for rtl*/;
4368  d->m_caretViewContext->origX = absx + x;
4369  placeCaretOnLine(b, x, absx, absy);
4370 }
4371 
4372 void TDEHTMLView::moveCaretBy(bool next, CaretMovement cmv, int count)
4373 {
4374  if (!m_part) return;
4375  Node &caretNodeRef = m_part->d->caretNode();
4376  if (caretNodeRef.isNull()) return;
4377 
4378  NodeImpl *caretNode = caretNodeRef.handle();
4379 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4380  long &offset = m_part->d->caretOffset();
4381 
4382  ElementImpl *baseElem = determineBaseElement(caretNode);
4383  CaretAdvancePolicy advpol = cmv != CaretByWord ? IndicatedFlows : LeafsOnly;
4384  LinearDocument ld(m_part, caretNode, offset, advpol, baseElem);
4385 
4386  EditableCharacterIterator it(&ld);
4387  while (!it.isEnd() && count > 0) {
4388  count--;
4389  if (cmv == CaretByCharacter) {
4390  if (next) ++it;
4391  else --it;
4392  } else if (cmv == CaretByWord) {
4393  if (next) moveItToNextWord(it);
4394  else moveItToPrevWord(it);
4395  }/*end if*/
4396 //kdDebug(6200) << "movecaret" << endl;
4397  }/*wend*/
4398  CaretBox *hintBox = 0; // make gcc uninit warning disappear
4399  if (!it.isEnd()) {
4400  NodeImpl *node = caretNodeRef.handle();
4401  hintBox = it.caretBox();
4402 //kdDebug(6200) << "hintBox = " << hintBox << endl;
4403 //kdDebug(6200) << " outside " << hintBox->isOutside() << " outsideEnd " << hintBox->isOutsideEnd() << " r " << it.renderer() << " ofs " << it.offset() << " cb " << hintBox->containingBlock() << endl;
4404  mapRenderPosToDOMPos(it.renderer(), it.offset(), hintBox->isOutside(),
4405  hintBox->isOutsideEnd(), node, offset);
4406 //kdDebug(6200) << "mapRTD" << endl;
4407  caretNodeRef = node;
4408 #if DEBUG_CARETMODE > 2
4409  kdDebug(6200) << "set by valid node " << node << " " << (node?node->nodeName().string():TQString::null) << " offset: " << offset << endl;
4410 #endif
4411  } else {
4412  offset = next ? caretNode->maxOffset() : caretNode->minOffset();
4413 #if DEBUG_CARETMODE > 0
4414  kdDebug(6200) << "set by INvalid node. offset: " << offset << endl;
4415 #endif
4416  }/*end if*/
4417  placeCaretOnChar(hintBox);
4418 }
4419 
4420 void TDEHTMLView::placeCaretOnChar(CaretBox *hintBox)
4421 {
4422  caretOff();
4423  recalcAndStoreCaretPos(hintBox);
4424  ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
4425  d->m_caretViewContext->width, d->m_caretViewContext->height);
4426  d->m_caretViewContext->origX = d->m_caretViewContext->x;
4427  d->scrollBarMoved = false;
4428 #if DEBUG_CARETMODE > 3
4429  //if (caretNode->isTextNode()) kdDebug(6200) << "text[0] = " << (int)*((TextImpl *)caretNode)->data().unicode() << " text :\"" << ((TextImpl *)caretNode)->data().string() << "\"" << endl;
4430 #endif
4431  ensureNodeHasFocus(m_part->d->caretNode().handle());
4432  caretOn();
4433 }
4434 
4435 void TDEHTMLView::moveCaretByPage(bool next)
4436 {
4437  Node &caretNodeRef = m_part->d->caretNode();
4438  if (caretNodeRef.isNull()) return;
4439 
4440  NodeImpl *caretNode = caretNodeRef.handle();
4441 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4442  long offset = m_part->d->caretOffset();
4443 
4444  int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
4445  // Minimum distance the caret must be moved
4446  int mindist = clipper()->height() - offs;
4447 
4448  CaretViewContext *cv = d->caretViewContext();
4449 // int y = cv->y; // we always measure the top border
4450 
4451  ElementImpl *baseElem = determineBaseElement(caretNode);
4452  LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4453 
4454  ErgonomicEditableLineIterator it(ld.current(), cv->origX);
4455 
4456  moveIteratorByPage(ld, it, mindist, next);
4457 
4458  int x, absx, absy;
4459  CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
4460 
4461  placeCaretOnLine(caretBox, x, absx, absy);
4462 }
4463 
4464 void TDEHTMLView::moveCaretPrevWord()
4465 {
4466  moveCaretBy(false, CaretByWord, 1);
4467 }
4468 
4469 void TDEHTMLView::moveCaretNextWord()
4470 {
4471  moveCaretBy(true, CaretByWord, 1);
4472 }
4473 
4474 void TDEHTMLView::moveCaretPrevLine(int n)
4475 {
4476  moveCaretByLine(false, n);
4477 }
4478 
4479 void TDEHTMLView::moveCaretNextLine(int n)
4480 {
4481  moveCaretByLine(true, n);
4482 }
4483 
4484 void TDEHTMLView::moveCaretPrevPage()
4485 {
4486  moveCaretByPage(false);
4487 }
4488 
4489 void TDEHTMLView::moveCaretNextPage()
4490 {
4491  moveCaretByPage(true);
4492 }
4493 
4494 void TDEHTMLView::moveCaretToLineBegin()
4495 {
4496  moveCaretToLineBoundary(false);
4497 }
4498 
4499 void TDEHTMLView::moveCaretToLineEnd()
4500 {
4501  moveCaretToLineBoundary(true);
4502 }
4503 
4504 #endif // TDEHTML_NO_CARET
4505 
4506 #ifndef NO_SMOOTH_SCROLL_HACK
4507 #define timer timer2
4508 
4509 // All scrolls must be completed within 240ms of last keypress
4510 static const int SCROLL_TIME = 240;
4511 // Each step is 20 ms == 50 frames/second
4512 static const int SCROLL_TICK = 20;
4513 
4514 void TDEHTMLView::scrollBy(int dx, int dy)
4515 {
4516  TDEConfigGroup cfg( TDEGlobal::config(), "KDE" );
4517  if( !cfg.readBoolEntry( "SmoothScrolling", false )) {
4518  TQScrollView::scrollBy( dx, dy );
4519  return;
4520  }
4521  // scrolling destination
4522  int full_dx = d->dx + dx;
4523  int full_dy = d->dy + dy;
4524 
4525  // scrolling speed
4526  int ddx = 0;
4527  int ddy = 0;
4528 
4529  int steps = SCROLL_TIME/SCROLL_TICK;
4530 
4531  ddx = (full_dx*16)/steps;
4532  ddy = (full_dy*16)/steps;
4533 
4534  // don't go under 1px/step
4535  if (ddx > 0 && ddx < 16) ddx = 16;
4536  if (ddy > 0 && ddy < 16) ddy = 16;
4537  if (ddx < 0 && ddx > -16) ddx = -16;
4538  if (ddy < 0 && ddy > -16) ddy = -16;
4539 
4540  d->dx = full_dx;
4541  d->dy = full_dy;
4542  d->ddx = ddx;
4543  d->ddy = ddy;
4544 
4545  if (!d->scrolling) {
4546  scrollTick();
4547  startScrolling();
4548  }
4549 }
4550 
4551 void TDEHTMLView::scrollTick() {
4552  if (d->dx == 0 && d->dy == 0) {
4553  stopScrolling();
4554  return;
4555  }
4556 
4557  int tddx = d->ddx + d->rdx;
4558  int tddy = d->ddy + d->rdy;
4559 
4560  int ddx = tddx / 16;
4561  int ddy = tddy / 16;
4562  d->rdx = tddx % 16;
4563  d->rdy = tddy % 16;
4564 
4565  if (d->dx > 0 && ddx > d->dx) ddx = d->dx;
4566  else
4567  if (d->dx < 0 && ddx < d->dx) ddx = d->dx;
4568 
4569  if (d->dy > 0 && ddy > d->dy) ddy = d->dy;
4570  else
4571  if (d->dy < 0 && ddy < d->dy) ddy = d->dy;
4572 
4573  d->dx -= ddx;
4574  d->dy -= ddy;
4575 
4576 // TQScrollView::setContentsPos( contentsX() + ddx, contentsY() + ddy);
4577  kapp->syncX();
4578  TQScrollView::scrollBy(ddx, ddy);
4579 // Unaccelerated X can get seriously overloaded by scrolling and for some reason
4580 // will send KeyPress events only infrequently. This should help to reduce
4581 // the load.
4582  kapp->syncX();
4583 }
4584 
4585 void TDEHTMLView::startScrolling()
4586 {
4587  d->scrolling = true;
4588  d->timer.start(SCROLL_TICK, false);
4589 }
4590 
4591 void TDEHTMLView::stopScrolling()
4592 {
4593  d->timer.stop();
4594  d->dx = d->dy = 0;
4595  d->scrolling = false;
4596 }
4597 
4598 // Overloaded from TQScrollView and TQScrollBar
4599 void TDEHTMLView::scrollViewWheelEvent( TQWheelEvent *e )
4600 {
4601  int pageStep = verticalScrollBar()->pageStep();
4602  int lineStep = verticalScrollBar()->lineStep();
4603  int step = TQMIN( TQApplication::wheelScrollLines()*lineStep, pageStep );
4604  if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
4605  step = pageStep;
4606 
4607  if(e->orientation() == TQt::Horizontal)
4608  scrollBy(-((e->delta()*step)/120), 0);
4609  else if(e->orientation() == TQt::Vertical)
4610  scrollBy(0,-((e->delta()*step)/120));
4611 
4612  e->accept();
4613 }
4614 
4615 #undef timer
4616 
4617 #endif // NO_SMOOTH_SCROLL_HACK
4618 
4619 #undef DEBUG_CARETMODE
DOM::DOMString
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
DOM::Node
The Node interface is the primary datatype for the entire Document Object Model.
Definition: dom_node.h:275
DOM::Node::isNull
bool isNull() const
tests if this Node is 0.
Definition: dom_node.h:892
KCursor::arrowCursor
static TQCursor arrowCursor()
KCursor::sizeHorCursor
static TQCursor sizeHorCursor()
KCursor::sizeAllCursor
static TQCursor sizeAllCursor()
KCursor::crossCursor
static TQCursor crossCursor()
KCursor::sizeFDiagCursor
static TQCursor sizeFDiagCursor()
KCursor::waitCursor
static TQCursor waitCursor()
KCursor::whatsThisCursor
static TQCursor whatsThisCursor()
KCursor::workingCursor
static TQCursor workingCursor()
KCursor::ibeamCursor
static TQCursor ibeamCursor()
KCursor::sizeVerCursor
static TQCursor sizeVerCursor()
KCursor::sizeBDiagCursor
static TQCursor sizeBDiagCursor()
KDialogBase
KDialogBase::cancel
void cancel()
KParts::Part::widget
virtual TQWidget * widget()
KParts::ReadOnlyPart::completed
void completed()
KSimpleConfig
KStringHandler::csqueeze
static TQString csqueeze(const TQString &str, uint maxlen=40)
TDEApplication::keyboardMouseState
static ButtonState keyboardMouseState()
TDEConfigBase::readBoolEntry
bool readBoolEntry(const TQString &pKey, bool bDefault=false) const
TDEConfigGroupSaver
TDEConfigGroup
TDEConfig
TDEGlobal::iconLoader
static TDEIconLoader * iconLoader()
TDEGlobal::config
static TDEConfig * config()
TDEGlobal::locale
static TDELocale * locale()
KMIN
#define KMIN(a, b)
TDEHTMLPart
This class is tdehtml's main class.
Definition: tdehtml_part.h:184
TDEHTMLPart::document
DOM::Document document() const
Returns a reference to the DOM document.
Definition: tdehtml_part.cpp:859
TDEHTMLPart::CaretDisplayPolicy
CaretDisplayPolicy
Enumeration for displaying the caret.
Definition: tdehtml_part.h:495
TDEHTMLPart::zoomFactor
int zoomFactor() const
Returns the current zoom factor.
Definition: tdehtml_part.cpp:5664
TDEHTMLPart::urlCursor
TQCursor urlCursor() const
Returns the cursor which is used when the cursor is on a link.
Definition: tdehtml_part.cpp:2602
TDEHTMLPart::isCaretMode
bool isCaretMode() const
Returns whether caret mode is on/off.
Definition: tdehtml_part.cpp:2662
TDEHTMLPart::view
TDEHTMLView * view() const
Returns a pointer to the HTML document's view.
Definition: tdehtml_part.cpp:906
TDEHTMLPart::findTextNext
bool findTextNext(const TQString &str, bool forward, bool caseSensitive, bool isRegExp)
Finds the next occurrence of the string or expression.
Definition: tdehtml_part.cpp:2823
TDEHTMLPart::begin
virtual void begin(const KURL &url=KURL(), int xOffset=0, int yOffset=0)
Clears the widget and prepares it for new content.
Definition: tdehtml_part.cpp:1875
TDEHTMLPart::findTextBegin
void findTextBegin()
Initiates a text search.
Definition: tdehtml_part.cpp:2737
TDEHTMLPart::isEditable
bool isEditable() const
Returns true if the document is editable, false otherwise.
Definition: tdehtml_part.cpp:2683
TDEHTMLPart::frameExists
bool frameExists(const TQString &frameName)
Returns whether a frame with the specified name is exists or not.
Definition: tdehtml_part.cpp:5291
TDEHTMLPart::nodeActivated
void nodeActivated(const DOM::Node &)
This signal is emitted when an element retrieves the keyboard focus.
TDEHTMLPart::findText
void findText()
Starts a new search by popping up a dialog asking the user what he wants to search for.
Definition: tdehtml_part.cpp:2996
TDEHTMLPart::parentPart
TDEHTMLPart * parentPart()
Returns a pointer to the parent TDEHTMLPart if the part is a frame in an HTML frameset.
Definition: tdehtml_part.cpp:5321
TDEHTMLView
Renders and displays HTML in a TQScrollView.
Definition: tdehtmlview.h:79
TDEHTMLView::layout
void layout()
ensure the display is up to date
Definition: tdehtmlview.cpp:800
TDEHTMLView::displayAccessKeys
void displayAccessKeys()
Display all accesskeys in small tooltips.
Definition: tdehtmlview.cpp:2256
TDEHTMLView::setVScrollBarMode
virtual void setVScrollBarMode(ScrollBarMode mode)
Sets verticals scrollbar mode.
Definition: tdehtmlview.cpp:3016
TDEHTMLView::print
void print()
Prints the HTML document.
Definition: tdehtmlview.cpp:2767
TDEHTMLView::setMarginWidth
void setMarginWidth(int x)
Sets a margin in x direction.
Definition: tdehtmlview.cpp:788
TDEHTMLView::setHScrollBarMode
virtual void setHScrollBarMode(ScrollBarMode mode)
Sets horizontal scrollbar mode.
Definition: tdehtmlview.cpp:3026
TDEHTMLView::TDEHTMLView
TDEHTMLView(TDEHTMLPart *part, TQWidget *parent, const char *name=0)
Constructs a TDEHTMLView.
Definition: tdehtmlview.cpp:487
TDEHTMLView::part
TDEHTMLPart * part() const
Returns a pointer to the TDEHTMLPart that is rendering the page.
Definition: tdehtmlview.h:113
TDEHTMLView::finishedLayout
void finishedLayout()
This signal is used for internal layouting.
TDEIconLoader::loadIcon
TQPixmap loadIcon(const TQString &name, TDEIcon::Group group, int size=0, int state=TDEIcon::DefaultState, TQString *path_store=0L, bool canReturnNull=false) const
TDEIcon::DefaultState
DefaultState
TDEIcon::Small
Small
TDELocale::formatDate
TQString formatDate(const TQDate &pDate, bool shortFormat=false) const
endl
kndbgstream & endl(kndbgstream &s)
kdWarning
kdbgstream kdWarning(int area=0)
kdError
kdbgstream kdError(int area=0)
kdDebug
kdbgstream kdDebug(int area=0)
locateLocal
TQString locateLocal(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())
DOM
The Document Object Model (DOM) is divided into two parts, the COREDOM core DOM, specifying some core...
Definition: design.h:57
KNotifyClient::event
int event(const TQString &message, const TQString &text=TQString::null) TDE_DEPRECATED
KNotifyClient::beep
void beep(const TQString &reason=TQString::null)
TDEStdAccel::next
const TDEShortcut & next()
TDEStdAccel::key
int key(StdAccel id)
TDEStdAccel::end
const TDEShortcut & end()
TDEStdAccel::close
const TDEShortcut & close()
TDEStdAccel::label
TQString label(StdAccel id)
tdelocale.h

tdehtml

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

tdehtml

Skip menu "tdehtml"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdehtml by doxygen 1.9.1
This website is maintained by Timothy Pearson.