• 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 Q_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 QT_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
308 
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 QT_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, TQT_SIGNAL(tdedisplayPaletteChanged()), this, TQT_SLOT(slotPaletteChanged()));
497  connect(this, TQT_SIGNAL(contentsMoving(int, int)), this, TQT_SLOT(slotScrollBarMoved()));
498 
499  // initialize QScrollView
500  enableClipper(true);
501  // hack to get unclipped painting on the viewport.
502  static_cast<TDEHTMLView *>(TQT_TQWIDGET(viewport()))->setWFlags(WPaintUnclipped);
503 
504  setResizePolicy(Manual);
505  viewport()->setMouseTracking(true);
506  viewport()->setBackgroundMode(NoBackground);
507 
508  KImageIO::registerFormats();
509 
510 #ifndef QT_NO_TOOLTIP
511  d->tooltip = new TDEHTMLToolTip( this, d );
512 #endif
513 
514 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
515  connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_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, TQT_SIGNAL(timeout()), this, TQT_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(TQ_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  TQT_TQOBJECT(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_OBJECT_NAME_STRING);
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! " << TQT_TQWIDGET(dlg) << endl;
915  TQT_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() & Qt::MouseButtonMask ) == Qt::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() == Qt::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, TQT_SIGNAL(timeout()), this, TQT_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,TQT_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 = ::tqqt_cast<TQScrollView*>(w);
1116  if (sc && !::tqqt_cast<TQListBox*>(w))
1117  static_cast<tdehtml::RenderWidget::ScrollViewEventPropagator*>(sc)->sendEvent(TQT_TQEVENT(&fw));
1118  else if(w)
1119  static_cast<tdehtml::RenderWidget::EventPropagator*>(w)->sendEvent(TQT_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() & Qt::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 Q_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() != Qt::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 (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(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 = TQT_TQOBJECT(TQT_TQCHILDEVENT(e)->child());
1903  if (c->isWidgetType()) {
1904  TQWidget *w = TQT_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 (!::tqqt_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 = ::tqqt_cast<TQWidget *>(it.current());
1917  if (widget && !widget->isTopLevel()) {
1918  if (!::tqqt_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 = TQT_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 = TQT_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 = TQT_TQPAINTEVENT(e);
1955  bool asap = !d->contentsMoving && ::tqqt_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 || ::tqqt_cast<TQScrollView*>(c)) && !::tqqt_cast<TQScrollBar *>(w)) {
1973  TQMouseEvent *me = TQT_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 && !::tqqt_cast<TQScrollBar *>(w)) {
1992  TQKeyEvent *ke = TQT_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, TQT_SIGNAL(hideAccessKeys()), lab, TQT_SLOT(close()) );
2287  connect( this, TQT_SIGNAL(repaintAccessKeys()), lab, TQT_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 #ifdef USE_QT4
2413  m_part->xmlDocImpl()->setFocusNode(node);
2414 #else // USE_QT4
2415  TQFocusEvent::setReason( TQFocusEvent::Shortcut );
2416  m_part->xmlDocImpl()->setFocusNode(node);
2417  TQFocusEvent::resetReason();
2418 #endif // USE_QT4
2419  if( node != NULL && node->hasOneRef()) // deleted, only held by guard
2420  return true;
2421  emit m_part->nodeActivated(Node(node));
2422  if( node != NULL && node->hasOneRef())
2423  return true;
2424  }
2425 
2426  switch( node->id()) {
2427  case ID_A:
2428  static_cast< HTMLAnchorElementImpl* >( node )->click();
2429  break;
2430  case ID_INPUT:
2431  static_cast< HTMLInputElementImpl* >( node )->click();
2432  break;
2433  case ID_BUTTON:
2434  static_cast< HTMLButtonElementImpl* >( node )->click();
2435  break;
2436  case ID_AREA:
2437  static_cast< HTMLAreaElementImpl* >( node )->click();
2438  break;
2439  case ID_TEXTAREA:
2440  break; // just focusing it is enough
2441  case ID_LEGEND:
2442  // TODO
2443  break;
2444  }
2445  return true;
2446 }
2447 
2448 static TQString getElementText( NodeImpl* start, bool after )
2449 {
2450  TQString ret; // nextSibling(), to go after e.g. </select>
2451  for( NodeImpl* n = after ? start->nextSibling() : start->traversePreviousNode();
2452  n != NULL;
2453  n = after ? n->traverseNextNode() : n->traversePreviousNode()) {
2454  if( n->isTextNode()) {
2455  if( after )
2456  ret += static_cast< TextImpl* >( n )->toString().string();
2457  else
2458  ret.prepend( static_cast< TextImpl* >( n )->toString().string());
2459  } else {
2460  switch( n->id()) {
2461  case ID_A:
2462  case ID_FONT:
2463  case ID_TT:
2464  case ID_U:
2465  case ID_B:
2466  case ID_I:
2467  case ID_S:
2468  case ID_STRIKE:
2469  case ID_BIG:
2470  case ID_SMALL:
2471  case ID_EM:
2472  case ID_STRONG:
2473  case ID_DFN:
2474  case ID_CODE:
2475  case ID_SAMP:
2476  case ID_KBD:
2477  case ID_VAR:
2478  case ID_CITE:
2479  case ID_ABBR:
2480  case ID_ACRONYM:
2481  case ID_SUB:
2482  case ID_SUP:
2483  case ID_SPAN:
2484  case ID_NOBR:
2485  case ID_WBR:
2486  break;
2487  case ID_TD:
2488  if( ret.stripWhiteSpace().isEmpty())
2489  break;
2490  // fall through
2491  default:
2492  return ret.simplifyWhiteSpace();
2493  }
2494  }
2495  }
2496  return ret.simplifyWhiteSpace();
2497 }
2498 
2499 static TQMap< NodeImpl*, TQString > buildLabels( NodeImpl* start )
2500 {
2501  TQMap< NodeImpl*, TQString > ret;
2502  for( NodeImpl* n = start;
2503  n != NULL;
2504  n = n->traverseNextNode()) {
2505  if( n->id() == ID_LABEL ) {
2506  HTMLLabelElementImpl* label = static_cast< HTMLLabelElementImpl* >( n );
2507  NodeImpl* labelfor = label->getFormElement();
2508  if( labelfor )
2509  ret[ labelfor ] = label->innerText().string().simplifyWhiteSpace();
2510  }
2511  }
2512  return ret;
2513 }
2514 
2515 namespace tdehtml {
2516 struct AccessKeyData {
2517  ElementImpl* element;
2518  TQString text;
2519  TQString url;
2520  int priority; // 10(highest) - 0(lowest)
2521 };
2522 }
2523 
2524 TQMap< ElementImpl*, TQChar > TDEHTMLView::buildFallbackAccessKeys() const
2525 {
2526  // build a list of all possible candidate elements that could use an accesskey
2527  TQValueList< AccessKeyData > data;
2528  TQMap< NodeImpl*, TQString > labels = buildLabels( m_part->xmlDocImpl());
2529  for( NodeImpl* n = m_part->xmlDocImpl();
2530  n != NULL;
2531  n = n->traverseNextNode()) {
2532  if( n->isElementNode()) {
2533  ElementImpl* element = static_cast< ElementImpl* >( n );
2534  if( element->getAttribute( ATTR_ACCESSKEY ).length() == 1 )
2535  continue; // has accesskey set, ignore
2536  if( element->renderer() == NULL )
2537  continue; // not visible
2538  TQString text;
2539  TQString url;
2540  int priority = 0;
2541  bool ignore = false;
2542  bool text_after = false;
2543  bool text_before = false;
2544  switch( element->id()) {
2545  case ID_A:
2546  url = tdehtml::parseURL(element->getAttribute(ATTR_HREF)).string();
2547  if( url.isEmpty()) // doesn't have href, it's only an anchor
2548  continue;
2549  text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
2550  priority = 2;
2551  break;
2552  case ID_INPUT: {
2553  HTMLInputElementImpl* in = static_cast< HTMLInputElementImpl* >( element );
2554  switch( in->inputType()) {
2555  case HTMLInputElementImpl::SUBMIT:
2556  text = in->value().string();
2557  if( text.isEmpty())
2558  text = i18n( "Submit" );
2559  priority = 7;
2560  break;
2561  case HTMLInputElementImpl::IMAGE:
2562  text = in->altText().string();
2563  priority = 7;
2564  break;
2565  case HTMLInputElementImpl::BUTTON:
2566  text = in->value().string();
2567  priority = 5;
2568  break;
2569  case HTMLInputElementImpl::RESET:
2570  text = in->value().string();
2571  if( text.isEmpty())
2572  text = i18n( "Reset" );
2573  priority = 5;
2574  break;
2575  case HTMLInputElementImpl::HIDDEN:
2576  ignore = true;
2577  break;
2578  case HTMLInputElementImpl::CHECKBOX:
2579  case HTMLInputElementImpl::RADIO:
2580  text_after = true;
2581  priority = 5;
2582  break;
2583  case HTMLInputElementImpl::TEXT:
2584  case HTMLInputElementImpl::PASSWORD:
2585  case HTMLInputElementImpl::FILE:
2586  text_before = true;
2587  priority = 5;
2588  break;
2589  default:
2590  priority = 5;
2591  break;
2592  }
2593  break;
2594  }
2595  case ID_BUTTON:
2596  text = static_cast< HTMLElementImpl* >( element )->innerText().string().simplifyWhiteSpace();
2597  switch( static_cast< HTMLButtonElementImpl* >( element )->buttonType()) {
2598  case HTMLButtonElementImpl::SUBMIT:
2599  if( text.isEmpty())
2600  text = i18n( "Submit" );
2601  priority = 7;
2602  break;
2603  case HTMLButtonElementImpl::RESET:
2604  if( text.isEmpty())
2605  text = i18n( "Reset" );
2606  priority = 5;
2607  break;
2608  default:
2609  priority = 5;
2610  break;
2611  break;
2612  }
2613  case ID_SELECT: // these don't have accesskey attribute, but quick access may be handy
2614  text_before = true;
2615  text_after = true;
2616  priority = 5;
2617  break;
2618  case ID_FRAME:
2619  ignore = true;
2620  break;
2621  default:
2622  ignore = !element->isFocusable();
2623  priority = 2;
2624  break;
2625  }
2626  if( ignore )
2627  continue;
2628  if( text.isNull() && labels.contains( element ))
2629  text = labels[ element ];
2630  if( text.isNull() && text_before )
2631  text = getElementText( element, false );
2632  if( text.isNull() && text_after )
2633  text = getElementText( element, true );
2634  text = text.stripWhiteSpace();
2635  // increase priority of items which have explicitly specified accesskeys in the config
2636  TQValueList< TQPair< TQString, TQChar > > priorities
2637  = m_part->settings()->fallbackAccessKeysAssignments();
2638  for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
2639  it != priorities.end();
2640  ++it ) {
2641  if( text == (*it).first )
2642  priority = 10;
2643  }
2644  AccessKeyData tmp = { element, text, url, priority };
2645  data.append( tmp );
2646  }
2647  }
2648 
2649  TQValueList< TQChar > keys;
2650  for( char c = 'A'; c <= 'Z'; ++c )
2651  keys << c;
2652  for( char c = '0'; c <= '9'; ++c )
2653  keys << c;
2654  for( NodeImpl* n = m_part->xmlDocImpl();
2655  n != NULL;
2656  n = n->traverseNextNode()) {
2657  if( n->isElementNode()) {
2658  ElementImpl* en = static_cast< ElementImpl* >( n );
2659  DOMString s = en->getAttribute( ATTR_ACCESSKEY );
2660  if( s.length() == 1 ) {
2661  TQChar c = s.string()[ 0 ].upper();
2662  keys.remove( c ); // remove manually assigned accesskeys
2663  }
2664  }
2665  }
2666 
2667  TQMap< ElementImpl*, TQChar > ret;
2668  for( int priority = 10;
2669  priority >= 0;
2670  --priority ) {
2671  for( TQValueList< AccessKeyData >::Iterator it = data.begin();
2672  it != data.end();
2673  ) {
2674  if( (*it).priority != priority ) {
2675  ++it;
2676  continue;
2677  }
2678  if( keys.isEmpty())
2679  break;
2680  TQString text = (*it).text;
2681  TQChar key;
2682  if( key.isNull() && !text.isEmpty()) {
2683  TQValueList< TQPair< TQString, TQChar > > priorities
2684  = m_part->settings()->fallbackAccessKeysAssignments();
2685  for( TQValueList< TQPair< TQString, TQChar > >::ConstIterator it = priorities.begin();
2686  it != priorities.end();
2687  ++it )
2688  if( text == (*it).first && keys.contains( (*it).second )) {
2689  key = (*it).second;
2690  break;
2691  }
2692  }
2693  // try first to select the first character as the accesskey,
2694  // then first character of the following words,
2695  // and then simply the first free character
2696  if( key.isNull() && !text.isEmpty()) {
2697  TQStringList words = TQStringList::split( ' ', text );
2698  for( TQStringList::ConstIterator it = words.begin();
2699  it != words.end();
2700  ++it ) {
2701  if( keys.contains( (*it)[ 0 ].upper())) {
2702  key = (*it)[ 0 ].upper();
2703  break;
2704  }
2705  }
2706  }
2707  if( key.isNull() && !text.isEmpty()) {
2708  for( unsigned int i = 0;
2709  i < text.length();
2710  ++i ) {
2711  if( keys.contains( text[ i ].upper())) {
2712  key = text[ i ].upper();
2713  break;
2714  }
2715  }
2716  }
2717  if( key.isNull())
2718  key = keys.front();
2719  ret[ (*it).element ] = key;
2720  keys.remove( key );
2721  TQString url = (*it).url;
2722  it = data.remove( it );
2723  // assign the same accesskey also to other elements pointing to the same url
2724  if( !url.isEmpty() && !url.startsWith( "javascript:", false )) {
2725  for( TQValueList< AccessKeyData >::Iterator it2 = data.begin();
2726  it2 != data.end();
2727  ) {
2728  if( (*it2).url == url ) {
2729  ret[ (*it2).element ] = key;
2730  if( it == it2 )
2731  ++it;
2732  it2 = data.remove( it2 );
2733  } else
2734  ++it2;
2735  }
2736  }
2737  }
2738  }
2739  return ret;
2740 }
2741 
2742 void TDEHTMLView::setMediaType( const TQString &medium )
2743 {
2744  m_medium = medium;
2745 }
2746 
2747 TQString TDEHTMLView::mediaType() const
2748 {
2749  return m_medium;
2750 }
2751 
2752 bool TDEHTMLView::pagedMode() const
2753 {
2754  return d->paged;
2755 }
2756 
2757 void TDEHTMLView::setWidgetVisible(RenderWidget* w, bool vis)
2758 {
2759  if (vis) {
2760  d->visibleWidgets.replace(w, w->widget());
2761  }
2762  else
2763  d->visibleWidgets.remove(w);
2764 }
2765 
2766 bool TDEHTMLView::needsFullRepaint() const
2767 {
2768  return d->needsFullRepaint;
2769 }
2770 
2771 void TDEHTMLView::print()
2772 {
2773  print( false );
2774 }
2775 
2776 void TDEHTMLView::print(bool quick)
2777 {
2778  if(!m_part->xmlDocImpl()) return;
2779  tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
2780  if(!root) return;
2781 
2782  KPrinter *printer = new KPrinter(true, TQPrinter::ScreenResolution);
2783  printer->addDialogPage(new TDEHTMLPrintSettings());
2784  TQString docname = m_part->xmlDocImpl()->URL().prettyURL();
2785  if ( !docname.isEmpty() )
2786  docname = KStringHandler::csqueeze(docname, 80);
2787  if(quick || printer->setup(this, i18n("Print %1").arg(docname))) {
2788  viewport()->setCursor( tqwaitCursor ); // only viewport(), no TQApplication::, otherwise we get the busy cursor in tdeprint's dialogs
2789  // set up KPrinter
2790  printer->setFullPage(false);
2791  printer->setCreator(TQString("TDE %1.%2.%3 HTML Library").arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(TDE_VERSION_RELEASE));
2792  printer->setDocName(docname);
2793 
2794  TQPainter *p = new TQPainter;
2795  p->begin( printer );
2796  tdehtml::setPrintPainter( p );
2797 
2798  m_part->xmlDocImpl()->setPaintDevice( printer );
2799  TQString oldMediaType = mediaType();
2800  setMediaType( "print" );
2801  // We ignore margin settings for html and body when printing
2802  // and use the default margins from the print-system
2803  // (In Qt 3.0.x the default margins are hardcoded in Qt)
2804  m_part->xmlDocImpl()->setPrintStyleSheet( printer->option("app-khtml-printfriendly") == "true" ?
2805  "* { background-image: none !important;"
2806  " background-color: white !important;"
2807  " color: black !important; }"
2808  "body { margin: 0px !important; }"
2809  "html { margin: 0px !important; }" :
2810  "body { margin: 0px !important; }"
2811  "html { margin: 0px !important; }"
2812  );
2813 
2814  TQPaintDeviceMetrics metrics( printer );
2815 
2816  kdDebug(6000) << "printing: physical page width = " << metrics.width()
2817  << " height = " << metrics.height() << endl;
2818  root->setStaticMode(true);
2819  root->setPagedMode(true);
2820  root->setWidth(metrics.width());
2821 // root->setHeight(metrics.height());
2822  root->setPageTop(0);
2823  root->setPageBottom(0);
2824  d->paged = true;
2825 
2826  m_part->xmlDocImpl()->styleSelector()->computeFontSizes(&metrics, 100);
2827  m_part->xmlDocImpl()->updateStyleSelector();
2828  root->setPrintImages( printer->option("app-khtml-printimages") == "true");
2829  root->makePageBreakAvoidBlocks();
2830 
2831  root->setNeedsLayoutAndMinMaxRecalc();
2832  root->layout();
2833  tdehtml::RenderWidget::flushWidgetResizes(); // make sure widgets have their final size
2834 
2835  // check sizes ask for action.. (scale or clip)
2836 
2837  bool printHeader = (printer->option("app-khtml-printheader") == "true");
2838 
2839  int headerHeight = 0;
2840  TQFont headerFont("Sans Serif", 8);
2841 
2842  TQString headerLeft = TDEGlobal::locale()->formatDate(TQDate::currentDate(),true);
2843  TQString headerMid = docname;
2844  TQString headerRight;
2845 
2846  if (printHeader)
2847  {
2848  p->setFont(headerFont);
2849  headerHeight = (p->fontMetrics().lineSpacing() * 3) / 2;
2850  }
2851 
2852  // ok. now print the pages.
2853  kdDebug(6000) << "printing: html page width = " << root->docWidth()
2854  << " height = " << root->docHeight() << endl;
2855  kdDebug(6000) << "printing: margins left = " << printer->margins().width()
2856  << " top = " << printer->margins().height() << endl;
2857  kdDebug(6000) << "printing: paper width = " << metrics.width()
2858  << " height = " << metrics.height() << endl;
2859  // if the width is too large to fit on the paper we just scale
2860  // the whole thing.
2861  int pageWidth = metrics.width();
2862  int pageHeight = metrics.height();
2863  p->setClipRect(0,0, pageWidth, pageHeight);
2864 
2865  pageHeight -= headerHeight;
2866 
2867  bool scalePage = false;
2868  double scale = 0.0;
2869 #ifndef QT_NO_TRANSFORMATIONS
2870  if(root->docWidth() > metrics.width()) {
2871  scalePage = true;
2872  scale = ((double) metrics.width())/((double) root->docWidth());
2873  pageHeight = (int) (pageHeight/scale);
2874  pageWidth = (int) (pageWidth/scale);
2875  headerHeight = (int) (headerHeight/scale);
2876  }
2877 #endif
2878  kdDebug(6000) << "printing: scaled html width = " << pageWidth
2879  << " height = " << pageHeight << endl;
2880 
2881  root->setHeight(pageHeight);
2882  root->setPageBottom(pageHeight);
2883  root->setNeedsLayout(true);
2884  root->layoutIfNeeded();
2885 // m_part->slotDebugRenderTree();
2886 
2887  // Squeeze header to make it it on the page.
2888  if (printHeader)
2889  {
2890  int available_width = metrics.width() - 10 -
2891  2 * kMax(p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerLeft).width(),
2892  p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerRight).width());
2893  if (available_width < 150)
2894  available_width = 150;
2895  int mid_width;
2896  int squeeze = 120;
2897  do {
2898  headerMid = KStringHandler::csqueeze(docname, squeeze);
2899  mid_width = p->boundingRect(0, 0, metrics.width(), p->fontMetrics().lineSpacing(), Qt::AlignLeft, headerMid).width();
2900  squeeze -= 10;
2901  } while (mid_width > available_width);
2902  }
2903 
2904  int top = 0;
2905  int bottom = 0;
2906  int page = 1;
2907  while(top < root->docHeight()) {
2908  if(top > 0) printer->newPage();
2909  p->setClipRect(0, 0, pageWidth, headerHeight, TQPainter::CoordDevice);
2910  if (printHeader)
2911  {
2912  int dy = p->fontMetrics().lineSpacing();
2913  p->setPen(Qt::black);
2914  p->setFont(headerFont);
2915 
2916  headerRight = TQString("#%1").arg(page);
2917 
2918  p->drawText(0, 0, metrics.width(), dy, Qt::AlignLeft, headerLeft);
2919  p->drawText(0, 0, metrics.width(), dy, Qt::AlignHCenter, headerMid);
2920  p->drawText(0, 0, metrics.width(), dy, Qt::AlignRight, headerRight);
2921  }
2922 
2923 
2924 #ifndef QT_NO_TRANSFORMATIONS
2925  if (scalePage)
2926  p->scale(scale, scale);
2927 #endif
2928 
2929  p->setClipRect(0, headerHeight, pageWidth, pageHeight, TQPainter::CoordDevice);
2930  p->translate(0, headerHeight-top);
2931 
2932  bottom = top+pageHeight;
2933 
2934  root->setPageTop(top);
2935  root->setPageBottom(bottom);
2936  root->setPageNumber(page);
2937 
2938  root->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
2939 // m_part->xmlDocImpl()->renderer()->layer()->paint(p, TQRect(0, top, pageWidth, pageHeight));
2940 // root->repaint();
2941 // p->flush();
2942  kdDebug(6000) << "printed: page " << page <<" bottom At = " << bottom << endl;
2943 
2944  top = bottom;
2945  p->resetXForm();
2946  page++;
2947  }
2948 
2949  p->end();
2950  delete p;
2951 
2952  // and now reset the layout to the usual one...
2953  root->setPagedMode(false);
2954  root->setStaticMode(false);
2955  d->paged = false;
2956  tdehtml::setPrintPainter( 0 );
2957  setMediaType( oldMediaType );
2958  m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(this) );
2959  m_part->xmlDocImpl()->styleSelector()->computeFontSizes(m_part->xmlDocImpl()->paintDeviceMetrics(), m_part->zoomFactor());
2960  m_part->xmlDocImpl()->updateStyleSelector();
2961  viewport()->unsetCursor();
2962  }
2963  delete printer;
2964 }
2965 
2966 void TDEHTMLView::slotPaletteChanged()
2967 {
2968  if(!m_part->xmlDocImpl()) return;
2969  DOM::DocumentImpl *document = m_part->xmlDocImpl();
2970  if (!document->isHTMLDocument()) return;
2971  tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(document->renderer());
2972  if(!root) return;
2973  root->style()->resetPalette();
2974  NodeImpl *body = static_cast<HTMLDocumentImpl*>(document)->body();
2975  if(!body) return;
2976  body->setChanged(true);
2977  body->recalcStyle( NodeImpl::Force );
2978 }
2979 
2980 void TDEHTMLView::paint(TQPainter *p, const TQRect &rc, int yOff, bool *more)
2981 {
2982  if(!m_part->xmlDocImpl()) return;
2983  tdehtml::RenderCanvas *root = static_cast<tdehtml::RenderCanvas *>(m_part->xmlDocImpl()->renderer());
2984  if(!root) return;
2985 
2986  m_part->xmlDocImpl()->setPaintDevice(p->device());
2987  root->setPagedMode(true);
2988  root->setStaticMode(true);
2989  root->setWidth(rc.width());
2990 
2991  p->save();
2992  p->setClipRect(rc);
2993  p->translate(rc.left(), rc.top());
2994  double scale = ((double) rc.width()/(double) root->docWidth());
2995  int height = (int) ((double) rc.height() / scale);
2996 #ifndef QT_NO_TRANSFORMATIONS
2997  p->scale(scale, scale);
2998 #endif
2999  root->setPageTop(yOff);
3000  root->setPageBottom(yOff+height);
3001 
3002  root->layer()->paint(p, TQRect(0, yOff, root->docWidth(), height));
3003  if (more)
3004  *more = yOff + height < root->docHeight();
3005  p->restore();
3006 
3007  root->setPagedMode(false);
3008  root->setStaticMode(false);
3009  m_part->xmlDocImpl()->setPaintDevice( TQT_TQPAINTDEVICE(this) );
3010 }
3011 
3012 
3013 void TDEHTMLView::useSlowRepaints()
3014 {
3015  d->useSlowRepaints = true;
3016  setStaticBackground(true);
3017 }
3018 
3019 
3020 void TDEHTMLView::setVScrollBarMode ( ScrollBarMode mode )
3021 {
3022 #ifndef TDEHTML_NO_SCROLLBARS
3023  d->vmode = mode;
3024  TQScrollView::setVScrollBarMode(mode);
3025 #else
3026  Q_UNUSED( mode );
3027 #endif
3028 }
3029 
3030 void TDEHTMLView::setHScrollBarMode ( ScrollBarMode mode )
3031 {
3032 #ifndef TDEHTML_NO_SCROLLBARS
3033  d->hmode = mode;
3034  TQScrollView::setHScrollBarMode(mode);
3035 #else
3036  Q_UNUSED( mode );
3037 #endif
3038 }
3039 
3040 void TDEHTMLView::restoreScrollBar()
3041 {
3042  int ow = visibleWidth();
3043  TQScrollView::setVScrollBarMode(d->vmode);
3044  if (visibleWidth() != ow)
3045  layout();
3046  d->prevScrollbarVisible = verticalScrollBar()->isVisible();
3047 }
3048 
3049 TQStringList TDEHTMLView::formCompletionItems(const TQString &name) const
3050 {
3051  if (!m_part->settings()->isFormCompletionEnabled())
3052  return TQStringList();
3053  if (!d->formCompletions)
3054  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3055  return d->formCompletions->readListEntry(name);
3056 }
3057 
3058 void TDEHTMLView::clearCompletionHistory(const TQString& name)
3059 {
3060  if (!d->formCompletions)
3061  {
3062  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3063  }
3064  d->formCompletions->writeEntry(name, "");
3065  d->formCompletions->sync();
3066 }
3067 
3068 void TDEHTMLView::addFormCompletionItem(const TQString &name, const TQString &value)
3069 {
3070  if (!m_part->settings()->isFormCompletionEnabled())
3071  return;
3072  // don't store values that are all numbers or just numbers with
3073  // dashes or spaces as those are likely credit card numbers or
3074  // something similar
3075  bool cc_number(true);
3076  for (unsigned int i = 0; i < value.length(); ++i)
3077  {
3078  TQChar c(value[i]);
3079  if (!c.isNumber() && c != '-' && !c.isSpace())
3080  {
3081  cc_number = false;
3082  break;
3083  }
3084  }
3085  if (cc_number)
3086  return;
3087  TQStringList items = formCompletionItems(name);
3088  if (!items.contains(value))
3089  items.prepend(value);
3090  while ((int)items.count() > m_part->settings()->maxFormCompletionItems())
3091  items.remove(items.fromLast());
3092  d->formCompletions->writeEntry(name, items);
3093 }
3094 
3095 void TDEHTMLView::removeFormCompletionItem(const TQString &name, const TQString &value)
3096 {
3097  if (!m_part->settings()->isFormCompletionEnabled())
3098  return;
3099 
3100  TQStringList items = formCompletionItems(name);
3101  if (items.remove(value))
3102  d->formCompletions->writeEntry(name, items);
3103 }
3104 
3105 void TDEHTMLView::addNonPasswordStorableSite(const TQString& host)
3106 {
3107  if (!d->formCompletions) {
3108  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3109  }
3110 
3111  d->formCompletions->setGroup("NonPasswordStorableSites");
3112  TQStringList sites = d->formCompletions->readListEntry("Sites");
3113  sites.append(host);
3114  d->formCompletions->writeEntry("Sites", sites);
3115  d->formCompletions->sync();
3116  d->formCompletions->setGroup(TQString::null);//reset
3117 }
3118 
3119 bool TDEHTMLView::nonPasswordStorableSite(const TQString& host) const
3120 {
3121  if (!d->formCompletions) {
3122  d->formCompletions = new KSimpleConfig(locateLocal("data", "tdehtml/formcompletions"));
3123  }
3124  d->formCompletions->setGroup("NonPasswordStorableSites");
3125  TQStringList sites = d->formCompletions->readListEntry("Sites");
3126  d->formCompletions->setGroup(TQString::null);//reset
3127 
3128  return (sites.find(host) != sites.end());
3129 }
3130 
3131 // returns true if event should be swallowed
3132 bool TDEHTMLView::dispatchMouseEvent(int eventId, DOM::NodeImpl *targetNode,
3133  DOM::NodeImpl *targetNodeNonShared, bool cancelable,
3134  int detail,TQMouseEvent *_mouse, bool setUnder,
3135  int mouseEventType)
3136 {
3137  // if the target node is a text node, dispatch on the parent node - rdar://4196646 (and #76948)
3138  if (targetNode && targetNode->isTextNode())
3139  targetNode = targetNode->parentNode();
3140 
3141  if (d->underMouse)
3142  d->underMouse->deref();
3143  d->underMouse = targetNode;
3144  if (d->underMouse)
3145  d->underMouse->ref();
3146 
3147  if (d->underMouseNonShared)
3148  d->underMouseNonShared->deref();
3149  d->underMouseNonShared = targetNodeNonShared;
3150  if (d->underMouseNonShared)
3151  d->underMouseNonShared->ref();
3152 
3153  int exceptioncode = 0;
3154  int pageX = 0;
3155  int pageY = 0;
3156  viewportToContents(_mouse->x(), _mouse->y(), pageX, pageY);
3157  int clientX = pageX - contentsX();
3158  int clientY = pageY - contentsY();
3159  int screenX = _mouse->globalX();
3160  int screenY = _mouse->globalY();
3161  int button = -1;
3162  switch (_mouse->button()) {
3163  case Qt::LeftButton:
3164  button = 0;
3165  break;
3166  case Qt::MidButton:
3167  button = 1;
3168  break;
3169  case Qt::RightButton:
3170  button = 2;
3171  break;
3172  default:
3173  break;
3174  }
3175  if (d->accessKeysEnabled && d->accessKeysPreActivate && button!=-1)
3176  d->accessKeysPreActivate=false;
3177 
3178  bool ctrlKey = (_mouse->state() & ControlButton);
3179  bool altKey = (_mouse->state() & AltButton);
3180  bool shiftKey = (_mouse->state() & ShiftButton);
3181  bool metaKey = (_mouse->state() & MetaButton);
3182 
3183  // mouseout/mouseover
3184  if (setUnder && (d->prevMouseX != pageX || d->prevMouseY != pageY)) {
3185 
3186  // ### this code sucks. we should save the oldUnder instead of calculating
3187  // it again. calculating is expensive! (Dirk)
3188  NodeImpl *oldUnder = 0;
3189  if (d->prevMouseX >= 0 && d->prevMouseY >= 0) {
3190  NodeImpl::MouseEvent mev( _mouse->stateAfter(), static_cast<NodeImpl::MouseEventType>(mouseEventType));
3191  m_part->xmlDocImpl()->prepareMouseEvent( true, d->prevMouseX, d->prevMouseY, &mev );
3192  oldUnder = mev.innerNode.handle();
3193 
3194  if (oldUnder && oldUnder->isTextNode())
3195  oldUnder = oldUnder->parentNode();
3196  }
3197 // 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());
3198  if (oldUnder != targetNode) {
3199  // send mouseout event to the old node
3200  if (oldUnder){
3201  oldUnder->ref();
3202  MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOUT_EVENT,
3203  true,true,m_part->xmlDocImpl()->defaultView(),
3204  0,screenX,screenY,clientX,clientY,pageX, pageY,
3205  ctrlKey,altKey,shiftKey,metaKey,
3206  button,targetNode);
3207  me->ref();
3208  oldUnder->dispatchEvent(me,exceptioncode,true);
3209  me->deref();
3210  }
3211 
3212  // send mouseover event to the new node
3213  if (targetNode) {
3214  MouseEventImpl *me = new MouseEventImpl(EventImpl::MOUSEOVER_EVENT,
3215  true,true,m_part->xmlDocImpl()->defaultView(),
3216  0,screenX,screenY,clientX,clientY,pageX, pageY,
3217  ctrlKey,altKey,shiftKey,metaKey,
3218  button,oldUnder);
3219 
3220  me->ref();
3221  targetNode->dispatchEvent(me,exceptioncode,true);
3222  me->deref();
3223  }
3224 
3225  if (oldUnder)
3226  oldUnder->deref();
3227  }
3228  }
3229 
3230  bool swallowEvent = false;
3231 
3232  if (targetNode) {
3233  // send the actual event
3234  bool dblclick = ( eventId == EventImpl::CLICK_EVENT &&
3235  _mouse->type() == TQEvent::MouseButtonDblClick );
3236  MouseEventImpl *me = new MouseEventImpl(static_cast<EventImpl::EventId>(eventId),
3237  true,cancelable,m_part->xmlDocImpl()->defaultView(),
3238  detail,screenX,screenY,clientX,clientY,pageX, pageY,
3239  ctrlKey,altKey,shiftKey,metaKey,
3240  button,0, _mouse, dblclick );
3241  me->ref();
3242  targetNode->dispatchEvent(me,exceptioncode,true);
3243  bool defaultHandled = me->defaultHandled();
3244  if (defaultHandled || me->defaultPrevented())
3245  swallowEvent = true;
3246  me->deref();
3247 
3248  if (eventId == EventImpl::MOUSEDOWN_EVENT) {
3249  // Focus should be shifted on mouse down, not on a click. -dwh
3250  // Blur current focus node when a link/button is clicked; this
3251  // is expected by some sites that rely on onChange handlers running
3252  // from form fields before the button click is processed.
3253  DOM::NodeImpl* nodeImpl = targetNode;
3254  for ( ; nodeImpl && !nodeImpl->isFocusable(); nodeImpl = nodeImpl->parentNode());
3255  if (nodeImpl && nodeImpl->isMouseFocusable())
3256  m_part->xmlDocImpl()->setFocusNode(nodeImpl);
3257  else if (!nodeImpl || !nodeImpl->focused())
3258  m_part->xmlDocImpl()->setFocusNode(0);
3259  }
3260  }
3261 
3262  return swallowEvent;
3263 }
3264 
3265 void TDEHTMLView::setIgnoreWheelEvents( bool e )
3266 {
3267  d->ignoreWheelEvents = e;
3268 }
3269 
3270 #ifndef QT_NO_WHEELEVENT
3271 
3272 void TDEHTMLView::viewportWheelEvent(TQWheelEvent* e)
3273 {
3274  if (d->accessKeysEnabled && d->accessKeysPreActivate) d->accessKeysPreActivate=false;
3275 
3276  if ( ( e->state() & ControlButton) == ControlButton )
3277  {
3278  emit zoomView( - e->delta() );
3279  e->accept();
3280  }
3281  else if (d->firstRelayout)
3282  {
3283  e->accept();
3284  }
3285  else if( ( (e->orientation() == Qt::Vertical &&
3286  ((d->ignoreWheelEvents && !verticalScrollBar()->isVisible())
3287  || e->delta() > 0 && contentsY() <= 0
3288  || e->delta() < 0 && contentsY() >= contentsHeight() - visibleHeight()))
3289  ||
3290  (e->orientation() == Qt::Horizontal &&
3291  ((d->ignoreWheelEvents && !horizontalScrollBar()->isVisible())
3292  || e->delta() > 0 && contentsX() <=0
3293  || e->delta() < 0 && contentsX() >= contentsWidth() - visibleWidth())))
3294  && m_part->parentPart())
3295  {
3296  if ( m_part->parentPart()->view() )
3297  m_part->parentPart()->view()->wheelEvent( e );
3298  e->ignore();
3299  }
3300  else
3301  {
3302  d->scrollBarMoved = true;
3303 #ifndef NO_SMOOTH_SCROLL_HACK
3304  scrollViewWheelEvent( e );
3305 #else
3306  TQScrollView::viewportWheelEvent( e );
3307 #endif
3308 
3309  TQMouseEvent *tempEvent = new TQMouseEvent( TQEvent::MouseMove, TQPoint(-1,-1), TQPoint(-1,-1), Qt::NoButton, e->state() );
3310  emit viewportMouseMoveEvent ( tempEvent );
3311  delete tempEvent;
3312  }
3313 
3314 }
3315 #endif
3316 
3317 void TDEHTMLView::dragEnterEvent( TQDragEnterEvent* ev )
3318 {
3319  // Handle drops onto frames (#16820)
3320  // Drops on the main html part is handled by Konqueror (and shouldn't do anything
3321  // in e.g. kmail, so not handled here).
3322  if ( m_part->parentPart() )
3323  {
3324  TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
3325  return;
3326  }
3327  TQScrollView::dragEnterEvent( ev );
3328 }
3329 
3330 void TDEHTMLView::dropEvent( TQDropEvent *ev )
3331 {
3332  // Handle drops onto frames (#16820)
3333  // Drops on the main html part is handled by Konqueror (and shouldn't do anything
3334  // in e.g. kmail, so not handled here).
3335  if ( m_part->parentPart() )
3336  {
3337  TQApplication::sendEvent(m_part->parentPart()->widget(), ev);
3338  return;
3339  }
3340  TQScrollView::dropEvent( ev );
3341 }
3342 
3343 void TDEHTMLView::focusInEvent( TQFocusEvent *e )
3344 {
3345 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
3346  m_part->enableFindAheadActions( true );
3347 #endif
3348  DOM::NodeImpl* fn = m_part->xmlDocImpl() ? m_part->xmlDocImpl()->focusNode() : 0;
3349  if (fn && fn->renderer() && fn->renderer()->isWidget() &&
3350  (e->reason() != TQFocusEvent::Mouse) &&
3351  static_cast<tdehtml::RenderWidget*>(fn->renderer())->widget())
3352  static_cast<tdehtml::RenderWidget*>(fn->renderer())->widget()->setFocus();
3353 #ifndef TDEHTML_NO_CARET
3354  // Restart blink frequency timer if it has been killed, but only on
3355  // editable nodes
3356  if (d->m_caretViewContext &&
3357  d->m_caretViewContext->freqTimerId == -1 &&
3358  fn) {
3359  if (m_part->isCaretMode()
3360  || m_part->isEditable()
3361  || (fn && fn->renderer()
3362  && fn->renderer()->style()->userInput()
3363  == UI_ENABLED)) {
3364  d->m_caretViewContext->freqTimerId = startTimer(500);
3365  d->m_caretViewContext->visible = true;
3366  }/*end if*/
3367  }/*end if*/
3368  showCaret();
3369 #endif // TDEHTML_NO_CARET
3370  TQScrollView::focusInEvent( e );
3371 }
3372 
3373 void TDEHTMLView::focusOutEvent( TQFocusEvent *e )
3374 {
3375  if(m_part) m_part->stopAutoScroll();
3376 
3377 #ifndef TDEHTML_NO_TYPE_AHEAD_FIND
3378  if(d->typeAheadActivated)
3379  {
3380  findTimeout();
3381  }
3382  m_part->enableFindAheadActions( false );
3383 #endif // TDEHTML_NO_TYPE_AHEAD_FIND
3384 
3385 #ifndef TDEHTML_NO_CARET
3386  if (d->m_caretViewContext) {
3387  switch (d->m_caretViewContext->displayNonFocused) {
3388  case TDEHTMLPart::CaretInvisible:
3389  hideCaret();
3390  break;
3391  case TDEHTMLPart::CaretVisible: {
3392  killTimer(d->m_caretViewContext->freqTimerId);
3393  d->m_caretViewContext->freqTimerId = -1;
3394  NodeImpl *caretNode = m_part->xmlDocImpl()->focusNode();
3395  if (!d->m_caretViewContext->visible && (m_part->isCaretMode()
3396  || m_part->isEditable()
3397  || (caretNode && caretNode->renderer()
3398  && caretNode->renderer()->style()->userInput()
3399  == UI_ENABLED))) {
3400  d->m_caretViewContext->visible = true;
3401  showCaret(true);
3402  }/*end if*/
3403  break;
3404  }
3405  case TDEHTMLPart::CaretBlink:
3406  // simply leave as is
3407  break;
3408  }/*end switch*/
3409  }/*end if*/
3410 #endif // TDEHTML_NO_CARET
3411 
3412  if ( d->cursor_icon_widget )
3413  d->cursor_icon_widget->hide();
3414 
3415  TQScrollView::focusOutEvent( e );
3416 }
3417 
3418 void TDEHTMLView::slotScrollBarMoved()
3419 {
3420  if ( !d->firstRelayout && !d->complete && m_part->xmlDocImpl() &&
3421  d->layoutSchedulingEnabled) {
3422  // contents scroll while we are not complete: we need to check our layout *now*
3423  tdehtml::RenderCanvas* root = static_cast<tdehtml::RenderCanvas *>( m_part->xmlDocImpl()->renderer() );
3424  if (root && root->needsLayout()) {
3425  unscheduleRelayout();
3426  layout();
3427  }
3428  }
3429  if (!d->scrollingSelf) {
3430  d->scrollBarMoved = true;
3431  d->contentsMoving = true;
3432  // ensure quick reset of contentsMoving flag
3433  scheduleRepaint(0, 0, 0, 0);
3434  }
3435 
3436  if (m_part->xmlDocImpl() && m_part->xmlDocImpl()->documentElement())
3437  m_part->xmlDocImpl()->documentElement()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT, true, false);
3438 }
3439 
3440 void TDEHTMLView::timerEvent ( TQTimerEvent *e )
3441 {
3442 // kdDebug() << "timer event " << e->timerId() << endl;
3443  if ( e->timerId() == d->scrollTimerId ) {
3444  if( d->scrollSuspended )
3445  return;
3446  switch (d->scrollDirection) {
3447  case TDEHTMLViewPrivate::ScrollDown:
3448  if (contentsY() + visibleHeight () >= contentsHeight())
3449  d->newScrollTimer(this, 0);
3450  else
3451  scrollBy( 0, d->scrollBy );
3452  break;
3453  case TDEHTMLViewPrivate::ScrollUp:
3454  if (contentsY() <= 0)
3455  d->newScrollTimer(this, 0);
3456  else
3457  scrollBy( 0, -d->scrollBy );
3458  break;
3459  case TDEHTMLViewPrivate::ScrollRight:
3460  if (contentsX() + visibleWidth () >= contentsWidth())
3461  d->newScrollTimer(this, 0);
3462  else
3463  scrollBy( d->scrollBy, 0 );
3464  break;
3465  case TDEHTMLViewPrivate::ScrollLeft:
3466  if (contentsX() <= 0)
3467  d->newScrollTimer(this, 0);
3468  else
3469  scrollBy( -d->scrollBy, 0 );
3470  break;
3471  }
3472  return;
3473  }
3474  else if ( e->timerId() == d->layoutTimerId ) {
3475  d->dirtyLayout = true;
3476  layout();
3477  if (d->firstRelayout) {
3478  d->firstRelayout = false;
3479  verticalScrollBar()->setEnabled( true );
3480  horizontalScrollBar()->setEnabled( true );
3481  }
3482  }
3483 #ifndef TDEHTML_NO_CARET
3484  else if (d->m_caretViewContext
3485  && e->timerId() == d->m_caretViewContext->freqTimerId) {
3486  d->m_caretViewContext->visible = !d->m_caretViewContext->visible;
3487  if (d->m_caretViewContext->displayed) {
3488  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3489  d->m_caretViewContext->width,
3490  d->m_caretViewContext->height);
3491  }/*end if*/
3492 // if (d->m_caretViewContext->visible) cout << "|" << flush;
3493 // else cout << "" << flush;
3494  return;
3495  }
3496 #endif
3497 
3498  d->contentsMoving = false;
3499  if( m_part->xmlDocImpl() ) {
3500  DOM::DocumentImpl *document = m_part->xmlDocImpl();
3501  tdehtml::RenderCanvas* root = static_cast<tdehtml::RenderCanvas *>(document->renderer());
3502 
3503  if ( root && root->needsLayout() ) {
3504  killTimer(d->repaintTimerId);
3505  d->repaintTimerId = 0;
3506  scheduleRelayout();
3507  return;
3508  }
3509  }
3510 
3511  setStaticBackground(d->useSlowRepaints);
3512 
3513 // kdDebug() << "scheduled repaint "<< d->repaintTimerId << endl;
3514  killTimer(d->repaintTimerId);
3515  d->repaintTimerId = 0;
3516 
3517  TQRect updateRegion;
3518  TQMemArray<TQRect> rects = d->updateRegion.rects();
3519 
3520  d->updateRegion = TQRegion();
3521 
3522  if ( rects.size() )
3523  updateRegion = rects[0];
3524 
3525  for ( unsigned i = 1; i < rects.size(); ++i ) {
3526  TQRect newRegion = updateRegion.unite(rects[i]);
3527  if (2*newRegion.height() > 3*updateRegion.height() )
3528  {
3529  repaintContents( updateRegion );
3530  updateRegion = rects[i];
3531  }
3532  else
3533  updateRegion = newRegion;
3534  }
3535 
3536  if ( !updateRegion.isNull() )
3537  repaintContents( updateRegion );
3538 
3539  // As widgets can only be accurately positioned during painting, every layout might
3540  // dissociate a widget from its RenderWidget. E.g: if a RenderWidget was visible before layout, but the layout
3541  // pushed it out of the viewport, it will not be repainted, and consequently it's assocoated widget won't be repositioned!
3542  // 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.
3543 
3544  if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
3545  TQWidget* w;
3546  d->dirtyLayout = false;
3547 
3548  TQRect visibleRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
3549  TQPtrList<RenderWidget> toRemove;
3550  for (TQPtrDictIterator<TQWidget> it(d->visibleWidgets); it.current(); ++it) {
3551  int xp = 0, yp = 0;
3552  w = it.current();
3553  RenderWidget* rw = static_cast<RenderWidget*>( it.currentKey() );
3554  if (!rw->absolutePosition(xp, yp) ||
3555  !visibleRect.intersects(TQRect(xp, yp, w->width(), w->height())))
3556  toRemove.append(rw);
3557  }
3558  for (RenderWidget* r = toRemove.first(); r; r = toRemove.next())
3559  if ( (w = d->visibleWidgets.take(r) ) )
3560  addChild(w, 0, -500000);
3561  }
3562 
3563  emit repaintAccessKeys();
3564  if (d->emitCompletedAfterRepaint) {
3565  bool full = d->emitCompletedAfterRepaint == TDEHTMLViewPrivate::CSFull;
3566  d->emitCompletedAfterRepaint = TDEHTMLViewPrivate::CSNone;
3567  if ( full )
3568  emit m_part->completed();
3569  else
3570  emit m_part->completed(true);
3571  }
3572 }
3573 
3574 void TDEHTMLView::scheduleRelayout(tdehtml::RenderObject * /*clippedObj*/)
3575 {
3576  if (!d->layoutSchedulingEnabled || d->layoutTimerId)
3577  return;
3578 
3579  d->layoutTimerId = startTimer( m_part->xmlDocImpl() && m_part->xmlDocImpl()->parsing()
3580  ? 1000 : 0 );
3581 }
3582 
3583 void TDEHTMLView::unscheduleRelayout()
3584 {
3585  if (!d->layoutTimerId)
3586  return;
3587 
3588  killTimer(d->layoutTimerId);
3589  d->layoutTimerId = 0;
3590 }
3591 
3592 void TDEHTMLView::unscheduleRepaint()
3593 {
3594  if (!d->repaintTimerId)
3595  return;
3596 
3597  killTimer(d->repaintTimerId);
3598  d->repaintTimerId = 0;
3599 }
3600 
3601 void TDEHTMLView::scheduleRepaint(int x, int y, int w, int h, bool asap)
3602 {
3603  bool parsing = !m_part->xmlDocImpl() || m_part->xmlDocImpl()->parsing();
3604 
3605 // kdDebug() << "parsing " << parsing << endl;
3606 // kdDebug() << "complete " << d->complete << endl;
3607 
3608  int time = parsing ? 300 : (!asap ? ( !d->complete ? 100 : 20 ) : 0);
3609 
3610 #ifdef DEBUG_FLICKER
3611  TQPainter p;
3612  p.begin( viewport() );
3613 
3614  int vx, vy;
3615  contentsToViewport( x, y, vx, vy );
3616  p.fillRect( vx, vy, w, h, TQt::red );
3617  p.end();
3618 #endif
3619 
3620  d->updateRegion = d->updateRegion.unite(TQRect(x,y,w,h));
3621 
3622  if (asap && !parsing)
3623  unscheduleRepaint();
3624 
3625  if ( !d->repaintTimerId )
3626  d->repaintTimerId = startTimer( time );
3627 
3628 // kdDebug() << "starting timer " << time << endl;
3629 }
3630 
3631 void TDEHTMLView::complete( bool pendingAction )
3632 {
3633 // kdDebug() << "TDEHTMLView::complete()" << endl;
3634 
3635  d->complete = true;
3636 
3637  // is there a relayout pending?
3638  if (d->layoutTimerId)
3639  {
3640 // kdDebug() << "requesting relayout now" << endl;
3641  // do it now
3642  killTimer(d->layoutTimerId);
3643  d->layoutTimerId = startTimer( 0 );
3644  d->emitCompletedAfterRepaint = pendingAction ?
3645  TDEHTMLViewPrivate::CSActionPending : TDEHTMLViewPrivate::CSFull;
3646  }
3647 
3648  // is there a repaint pending?
3649  if (d->repaintTimerId)
3650  {
3651 // kdDebug() << "requesting repaint now" << endl;
3652  // do it now
3653  killTimer(d->repaintTimerId);
3654  d->repaintTimerId = startTimer( 20 );
3655  d->emitCompletedAfterRepaint = pendingAction ?
3656  TDEHTMLViewPrivate::CSActionPending : TDEHTMLViewPrivate::CSFull;
3657  }
3658 
3659  if (!d->emitCompletedAfterRepaint)
3660  {
3661  if (!pendingAction)
3662  emit m_part->completed();
3663  else
3664  emit m_part->completed(true);
3665  }
3666 
3667 }
3668 
3669 void TDEHTMLView::slotMouseScrollTimer()
3670 {
3671  scrollBy( d->m_mouseScroll_byX, d->m_mouseScroll_byY );
3672 }
3673 
3674 #ifndef TDEHTML_NO_CARET
3675 
3676 // ### the dependencies on static functions are a nightmare. just be
3677 // hacky and include the implementation here. Clean me up, please.
3678 
3679 #include "tdehtml_caret.cpp"
3680 
3681 void TDEHTMLView::initCaret(bool keepSelection)
3682 {
3683 #if DEBUG_CARETMODE > 0
3684  kdDebug(6200) << "begin initCaret" << endl;
3685 #endif
3686  // save caretMoved state as moveCaretTo changes it
3687  if (m_part->xmlDocImpl()) {
3688 #if 0
3689  ElementImpl *listitem = m_part->xmlDocImpl()->getElementById("__test_element__");
3690  if (listitem) dumpLineBoxes(static_cast<RenderFlow *>(listitem->renderer()));
3691 #endif
3692  d->caretViewContext();
3693  bool cmoved = d->m_caretViewContext->caretMoved;
3694  if (m_part->d->caretNode().isNull()) {
3695  // set to document, position will be sanitized anyway
3696  m_part->d->caretNode() = m_part->document();
3697  m_part->d->caretOffset() = 0L;
3698  // This sanity check is necessary for the not so unlikely case that
3699  // setEditable or setCaretMode is called before any render objects have
3700  // been created.
3701  if (!m_part->d->caretNode().handle()->renderer()) return;
3702  }/*end if*/
3703 // kdDebug(6200) << "d->m_selectionStart " << m_part->d->m_selectionStart.handle()
3704 // << " d->m_selectionEnd " << m_part->d->m_selectionEnd.handle() << endl;
3705  // ### does not repaint the selection on keepSelection!=false
3706  moveCaretTo(m_part->d->caretNode().handle(), m_part->d->caretOffset(), !keepSelection);
3707 // kdDebug(6200) << "d->m_selectionStart " << m_part->d->m_selectionStart.handle()
3708 // << " d->m_selectionEnd " << m_part->d->m_selectionEnd.handle() << endl;
3709  d->m_caretViewContext->caretMoved = cmoved;
3710  }/*end if*/
3711 #if DEBUG_CARETMODE > 0
3712  kdDebug(6200) << "end initCaret" << endl;
3713 #endif
3714 }
3715 
3716 bool TDEHTMLView::caretOverrides() const
3717 {
3718  bool cm = m_part->isCaretMode();
3719  bool dm = m_part->isEditable();
3720  return cm && !dm ? false
3721  : (dm || m_part->d->caretNode().handle()->contentEditable())
3722  && d->editorContext()->override;
3723 }
3724 
3725 void TDEHTMLView::ensureNodeHasFocus(NodeImpl *node)
3726 {
3727  if (m_part->isCaretMode() || m_part->isEditable()) return;
3728  if (node->focused()) return;
3729 
3730  // Find first ancestor whose "user-input" is "enabled"
3731  NodeImpl *firstAncestor = 0;
3732  while (node) {
3733  if (node->renderer()
3734  && node->renderer()->style()->userInput() != UI_ENABLED)
3735  break;
3736  firstAncestor = node;
3737  node = node->parentNode();
3738  }/*wend*/
3739 
3740  if (!node) firstAncestor = 0;
3741 
3742  DocumentImpl *doc = m_part->xmlDocImpl();
3743  // ensure that embedded widgets don't lose their focus
3744  if (!firstAncestor && doc->focusNode() && doc->focusNode()->renderer()
3745  && doc->focusNode()->renderer()->isWidget())
3746  return;
3747 
3748  // Set focus node on the document
3749 #if DEBUG_CARETMODE > 1
3750  kdDebug(6200) << k_funcinfo << "firstAncestor " << firstAncestor << ": "
3751  << (firstAncestor ? firstAncestor->nodeName().string() : TQString::null) << endl;
3752 #endif
3753  doc->setFocusNode(firstAncestor);
3754  emit m_part->nodeActivated(Node(firstAncestor));
3755 }
3756 
3757 void TDEHTMLView::recalcAndStoreCaretPos(CaretBox *hintBox)
3758 {
3759  if (!m_part || m_part->d->caretNode().isNull()) return;
3760  d->caretViewContext();
3761  NodeImpl *caretNode = m_part->d->caretNode().handle();
3762 #if DEBUG_CARETMODE > 0
3763  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;
3764 #endif
3765  caretNode->getCaret(m_part->d->caretOffset(), caretOverrides(),
3766  d->m_caretViewContext->x, d->m_caretViewContext->y,
3767  d->m_caretViewContext->width,
3768  d->m_caretViewContext->height);
3769 
3770  if (hintBox && d->m_caretViewContext->x == -1) {
3771 #if DEBUG_CARETMODE > 1
3772  kdDebug(6200) << "using hint inline box coordinates" << endl;
3773 #endif
3774  RenderObject *r = caretNode->renderer();
3775  const TQFontMetrics &fm = r->style()->fontMetrics();
3776  int absx, absy;
3777  r->containingBlock()->absolutePosition(absx, absy,
3778  false); // ### what about fixed?
3779  d->m_caretViewContext->x = absx + hintBox->xPos();
3780  d->m_caretViewContext->y = absy + hintBox->yPos();
3781 // + hintBox->baseline() - fm.ascent();
3782  d->m_caretViewContext->width = 1;
3783  // ### firstline not regarded. But I think it can be safely neglected
3784  // as hint boxes are only used for empty lines.
3785  d->m_caretViewContext->height = fm.height();
3786  }/*end if*/
3787 
3788 #if DEBUG_CARETMODE > 4
3789 // kdDebug(6200) << "freqTimerId: "<<d->m_caretViewContext->freqTimerId<<endl;
3790 #endif
3791 #if DEBUG_CARETMODE > 0
3792  kdDebug(6200) << "caret: ofs="<<m_part->d->caretOffset()<<" "
3793  <<" x="<<d->m_caretViewContext->x<<" y="<<d->m_caretViewContext->y
3794  <<" h="<<d->m_caretViewContext->height<<endl;
3795 #endif
3796 }
3797 
3798 void TDEHTMLView::caretOn()
3799 {
3800  if (d->m_caretViewContext) {
3801  killTimer(d->m_caretViewContext->freqTimerId);
3802 
3803  if (hasFocus() || d->m_caretViewContext->displayNonFocused
3804  == TDEHTMLPart::CaretBlink) {
3805  d->m_caretViewContext->freqTimerId = startTimer(500);
3806  } else {
3807  d->m_caretViewContext->freqTimerId = -1;
3808  }/*end if*/
3809 
3810  d->m_caretViewContext->visible = true;
3811  if ((d->m_caretViewContext->displayed = (hasFocus()
3812  || d->m_caretViewContext->displayNonFocused
3813  != TDEHTMLPart::CaretInvisible))) {
3814  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3815  d->m_caretViewContext->width,
3816  d->m_caretViewContext->height);
3817  }/*end if*/
3818 // kdDebug(6200) << "caret on" << endl;
3819  }/*end if*/
3820 }
3821 
3822 void TDEHTMLView::caretOff()
3823 {
3824  if (d->m_caretViewContext) {
3825  killTimer(d->m_caretViewContext->freqTimerId);
3826  d->m_caretViewContext->freqTimerId = -1;
3827  d->m_caretViewContext->displayed = false;
3828  if (d->m_caretViewContext->visible) {
3829  d->m_caretViewContext->visible = false;
3830  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3831  d->m_caretViewContext->width,
3832  d->m_caretViewContext->height);
3833  }/*end if*/
3834 // kdDebug(6200) << "caret off" << endl;
3835  }/*end if*/
3836 }
3837 
3838 void TDEHTMLView::showCaret(bool forceRepaint)
3839 {
3840  if (d->m_caretViewContext) {
3841  d->m_caretViewContext->displayed = true;
3842  if (d->m_caretViewContext->visible) {
3843  if (!forceRepaint) {
3844  updateContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3845  d->m_caretViewContext->width,
3846  d->m_caretViewContext->height);
3847  } else {
3848  repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3849  d->m_caretViewContext->width,
3850  d->m_caretViewContext->height);
3851  }/*end if*/
3852  }/*end if*/
3853 // kdDebug(6200) << "caret shown" << endl;
3854  }/*end if*/
3855 }
3856 
3857 bool TDEHTMLView::foldSelectionToCaret(NodeImpl *startNode, long startOffset,
3858  NodeImpl *endNode, long endOffset)
3859 {
3860  m_part->d->m_selectionStart = m_part->d->m_selectionEnd = m_part->d->caretNode();
3861  m_part->d->m_startOffset = m_part->d->m_endOffset = m_part->d->caretOffset();
3862  m_part->d->m_extendAtEnd = true;
3863 
3864  bool folded = startNode != endNode || startOffset != endOffset;
3865 
3866  // Only clear the selection if there has been one.
3867  if (folded) {
3868  m_part->xmlDocImpl()->clearSelection();
3869  }/*end if*/
3870 
3871  return folded;
3872 }
3873 
3874 void TDEHTMLView::hideCaret()
3875 {
3876  if (d->m_caretViewContext) {
3877  if (d->m_caretViewContext->visible) {
3878 // kdDebug(6200) << "redraw caret hidden" << endl;
3879  d->m_caretViewContext->visible = false;
3880  // force repaint, otherwise the event won't be handled
3881  // before the focus leaves the window
3882  repaintContents(d->m_caretViewContext->x, d->m_caretViewContext->y,
3883  d->m_caretViewContext->width,
3884  d->m_caretViewContext->height);
3885  d->m_caretViewContext->visible = true;
3886  }/*end if*/
3887  d->m_caretViewContext->displayed = false;
3888 // kdDebug(6200) << "caret hidden" << endl;
3889  }/*end if*/
3890 }
3891 
3892 int TDEHTMLView::caretDisplayPolicyNonFocused() const
3893 {
3894  if (d->m_caretViewContext)
3895  return d->m_caretViewContext->displayNonFocused;
3896  else
3897  return TDEHTMLPart::CaretInvisible;
3898 }
3899 
3900 void TDEHTMLView::setCaretDisplayPolicyNonFocused(int policy)
3901 {
3902  d->caretViewContext();
3903 // int old = d->m_caretViewContext->displayNonFocused;
3904  d->m_caretViewContext->displayNonFocused = (TDEHTMLPart::CaretDisplayPolicy)policy;
3905 
3906  // make change immediately take effect if not focused
3907  if (!hasFocus()) {
3908  switch (d->m_caretViewContext->displayNonFocused) {
3909  case TDEHTMLPart::CaretInvisible:
3910  hideCaret();
3911  break;
3912  case TDEHTMLPart::CaretBlink:
3913  if (d->m_caretViewContext->freqTimerId != -1) break;
3914  d->m_caretViewContext->freqTimerId = startTimer(500);
3915  // fall through
3916  case TDEHTMLPart::CaretVisible:
3917  d->m_caretViewContext->displayed = true;
3918  showCaret();
3919  break;
3920  }/*end switch*/
3921  }/*end if*/
3922 }
3923 
3924 bool TDEHTMLView::placeCaret(CaretBox *hintBox)
3925 {
3926  CaretViewContext *cv = d->caretViewContext();
3927  caretOff();
3928  NodeImpl *caretNode = m_part->d->caretNode().handle();
3929  // ### why is it sometimes null?
3930  if (!caretNode || !caretNode->renderer()) return false;
3931  ensureNodeHasFocus(caretNode);
3932  if (m_part->isCaretMode() || m_part->isEditable()
3933  || caretNode->renderer()->style()->userInput() == UI_ENABLED) {
3934  recalcAndStoreCaretPos(hintBox);
3935 
3936  cv->origX = cv->x;
3937 
3938  caretOn();
3939  return true;
3940  }/*end if*/
3941  return false;
3942 }
3943 
3944 void TDEHTMLView::ensureCaretVisible()
3945 {
3946  CaretViewContext *cv = d->m_caretViewContext;
3947  if (!cv) return;
3948  ensureVisible(cv->x, cv->y, cv->width, cv->height);
3949  d->scrollBarMoved = false;
3950 }
3951 
3952 bool TDEHTMLView::extendSelection(NodeImpl *oldStartSel, long oldStartOfs,
3953  NodeImpl *oldEndSel, long oldEndOfs)
3954 {
3955  bool changed = false;
3956  if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
3957  && m_part->d->m_startOffset == m_part->d->m_endOffset) {
3958  changed = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
3959  m_part->d->m_extendAtEnd = true;
3960  } else do {
3961  changed = m_part->d->m_selectionStart.handle() != oldStartSel
3962  || m_part->d->m_startOffset != oldStartOfs
3963  || m_part->d->m_selectionEnd.handle() != oldEndSel
3964  || m_part->d->m_endOffset != oldEndOfs;
3965  if (!changed) break;
3966 
3967  // determine start position -- caret position is always at end.
3968  NodeImpl *startNode;
3969  long startOffset;
3970  if (m_part->d->m_extendAtEnd) {
3971  startNode = m_part->d->m_selectionStart.handle();
3972  startOffset = m_part->d->m_startOffset;
3973  } else {
3974  startNode = m_part->d->m_selectionEnd.handle();
3975  startOffset = m_part->d->m_endOffset;
3976  m_part->d->m_selectionEnd = m_part->d->m_selectionStart;
3977  m_part->d->m_endOffset = m_part->d->m_startOffset;
3978  m_part->d->m_extendAtEnd = true;
3979  }/*end if*/
3980 
3981  bool swapNeeded = false;
3982  if (!m_part->d->m_selectionEnd.isNull() && startNode) {
3983  swapNeeded = RangeImpl::compareBoundaryPoints(startNode, startOffset,
3984  m_part->d->m_selectionEnd.handle(),
3985  m_part->d->m_endOffset) >= 0;
3986  }/*end if*/
3987 
3988  m_part->d->m_selectionStart = startNode;
3989  m_part->d->m_startOffset = startOffset;
3990 
3991  if (swapNeeded) {
3992  m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionEnd.handle(),
3993  m_part->d->m_endOffset, m_part->d->m_selectionStart.handle(),
3994  m_part->d->m_startOffset);
3995  } else {
3996  m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
3997  m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
3998  m_part->d->m_endOffset);
3999  }/*end if*/
4000  } while(false);/*end if*/
4001  return changed;
4002 }
4003 
4004 void TDEHTMLView::updateSelection(NodeImpl *oldStartSel, long oldStartOfs,
4005  NodeImpl *oldEndSel, long oldEndOfs)
4006 {
4007  if (m_part->d->m_selectionStart == m_part->d->m_selectionEnd
4008  && m_part->d->m_startOffset == m_part->d->m_endOffset) {
4009  if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs)) {
4010  m_part->emitSelectionChanged();
4011  }/*end if*/
4012  m_part->d->m_extendAtEnd = true;
4013  } else {
4014  // check if the extending end has passed the immobile end
4015  if (!m_part->d->m_selectionEnd.isNull() && !m_part->d->m_selectionEnd.isNull()) {
4016  bool swapNeeded = RangeImpl::compareBoundaryPoints(
4017  m_part->d->m_selectionStart.handle(), m_part->d->m_startOffset,
4018  m_part->d->m_selectionEnd.handle(), m_part->d->m_endOffset) >= 0;
4019  if (swapNeeded) {
4020  DOM::Node tmpNode = m_part->d->m_selectionStart;
4021  long tmpOffset = m_part->d->m_startOffset;
4022  m_part->d->m_selectionStart = m_part->d->m_selectionEnd;
4023  m_part->d->m_startOffset = m_part->d->m_endOffset;
4024  m_part->d->m_selectionEnd = tmpNode;
4025  m_part->d->m_endOffset = tmpOffset;
4026  m_part->d->m_startBeforeEnd = true;
4027  m_part->d->m_extendAtEnd = !m_part->d->m_extendAtEnd;
4028  }/*end if*/
4029  }/*end if*/
4030 
4031  m_part->xmlDocImpl()->setSelection(m_part->d->m_selectionStart.handle(),
4032  m_part->d->m_startOffset, m_part->d->m_selectionEnd.handle(),
4033  m_part->d->m_endOffset);
4034  m_part->emitSelectionChanged();
4035  }/*end if*/
4036 }
4037 
4038 void TDEHTMLView::caretKeyPressEvent(TQKeyEvent *_ke)
4039 {
4040  NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
4041  long oldStartOfs = m_part->d->m_startOffset;
4042  NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
4043  long oldEndOfs = m_part->d->m_endOffset;
4044 
4045  NodeImpl *oldCaretNode = m_part->d->caretNode().handle();
4046  long oldOffset = m_part->d->caretOffset();
4047 
4048  bool ctrl = _ke->state() & ControlButton;
4049 
4050 // FIXME: this is that widely indented because I will write ifs around it.
4051  switch(_ke->key()) {
4052  case Key_Space:
4053  break;
4054 
4055  case Key_Down:
4056  moveCaretNextLine(1);
4057  break;
4058 
4059  case Key_Up:
4060  moveCaretPrevLine(1);
4061  break;
4062 
4063  case Key_Left:
4064  moveCaretBy(false, ctrl ? CaretByWord : CaretByCharacter, 1);
4065  break;
4066 
4067  case Key_Right:
4068  moveCaretBy(true, ctrl ? CaretByWord : CaretByCharacter, 1);
4069  break;
4070 
4071  case Key_Next:
4072  moveCaretNextPage();
4073  break;
4074 
4075  case Key_Prior:
4076  moveCaretPrevPage();
4077  break;
4078 
4079  case Key_Home:
4080  if (ctrl)
4081  moveCaretToDocumentBoundary(false);
4082  else
4083  moveCaretToLineBegin();
4084  break;
4085 
4086  case Key_End:
4087  if (ctrl)
4088  moveCaretToDocumentBoundary(true);
4089  else
4090  moveCaretToLineEnd();
4091  break;
4092 
4093  }/*end switch*/
4094 
4095  if ((m_part->d->caretNode().handle() != oldCaretNode
4096  || m_part->d->caretOffset() != oldOffset)
4097  // node should never be null, but faulty conditions may cause it to be
4098  && !m_part->d->caretNode().isNull()) {
4099 
4100  d->m_caretViewContext->caretMoved = true;
4101 
4102  if (_ke->state() & ShiftButton) { // extend selection
4103  updateSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4104  } else { // clear any selection
4105  if (foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs))
4106  m_part->emitSelectionChanged();
4107  }/*end if*/
4108 
4109  m_part->emitCaretPositionChanged(m_part->d->caretNode(), m_part->d->caretOffset());
4110  }/*end if*/
4111 
4112  _ke->accept();
4113 }
4114 
4115 bool TDEHTMLView::moveCaretTo(NodeImpl *node, long offset, bool clearSel)
4116 {
4117  if (!node) return false;
4118  ElementImpl *baseElem = determineBaseElement(node);
4119  RenderFlow *base = static_cast<RenderFlow *>(baseElem ? baseElem->renderer() : 0);
4120  if (!node) return false;
4121 
4122  // need to find out the node's inline box. If there is none, this function
4123  // will snap to the next node that has one. This is necessary to make the
4124  // caret visible in any case.
4125  CaretBoxLineDeleter cblDeleter;
4126 // RenderBlock *cb;
4127  long r_ofs;
4128  CaretBoxIterator cbit;
4129  CaretBoxLine *cbl = findCaretBoxLine(node, offset, &cblDeleter, base, r_ofs, cbit);
4130  if(!cbl) {
4131  kdWarning() << "TDEHTMLView::moveCaretTo - findCaretBoxLine() returns NULL" << endl;
4132  return false;
4133  }
4134 
4135 #if DEBUG_CARETMODE > 3
4136  if (cbl) kdDebug(6200) << cbl->information() << endl;
4137 #endif
4138  CaretBox *box = *cbit;
4139  if (cbit != cbl->end() && box->object() != node->renderer()) {
4140  if (box->object()->element()) {
4141  mapRenderPosToDOMPos(box->object(), r_ofs, box->isOutside(),
4142  box->isOutsideEnd(), node, offset);
4143  //if (!outside) offset = node->minOffset();
4144 #if DEBUG_CARETMODE > 1
4145  kdDebug(6200) << "set new node " << node->nodeName().string() << "@" << node << endl;
4146 #endif
4147  } else { // box has no associated element -> do not use
4148  // this case should actually never happen.
4149  box = 0;
4150  kdError(6200) << "Box contains no node! Crash imminent" << endl;
4151  }/*end if*/
4152  }
4153 
4154  NodeImpl *oldStartSel = m_part->d->m_selectionStart.handle();
4155  long oldStartOfs = m_part->d->m_startOffset;
4156  NodeImpl *oldEndSel = m_part->d->m_selectionEnd.handle();
4157  long oldEndOfs = m_part->d->m_endOffset;
4158 
4159  // test for position change
4160  bool posChanged = m_part->d->caretNode().handle() != node
4161  || m_part->d->caretOffset() != offset;
4162  bool selChanged = false;
4163 
4164  m_part->d->caretNode() = node;
4165  m_part->d->caretOffset() = offset;
4166  if (clearSel || !oldStartSel || !oldEndSel) {
4167  selChanged = foldSelectionToCaret(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4168  } else {
4169  //kdDebug(6200) << "moveToCaret: extendSelection: m_extendAtEnd " << m_part->d->m_extendAtEnd << endl;
4170  //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;
4171  selChanged = extendSelection(oldStartSel, oldStartOfs, oldEndSel, oldEndOfs);
4172  //kdDebug(6200) << "after extendSelection: m_extendAtEnd " << m_part->d->m_extendAtEnd << endl;
4173  //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;
4174  }/*end if*/
4175 
4176  d->caretViewContext()->caretMoved = true;
4177 
4178  bool visible_caret = placeCaret(box);
4179 
4180  // FIXME: if the old position was !visible_caret, and the new position is
4181  // also, then two caretPositionChanged signals with a null Node are
4182  // emitted in series.
4183  if (posChanged) {
4184  m_part->emitCaretPositionChanged(visible_caret ? node : 0, offset);
4185  }/*end if*/
4186 
4187  return selChanged;
4188 }
4189 
4190 void TDEHTMLView::moveCaretByLine(bool next, int count)
4191 {
4192  Node &caretNodeRef = m_part->d->caretNode();
4193  if (caretNodeRef.isNull()) return;
4194 
4195  NodeImpl *caretNode = caretNodeRef.handle();
4196 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4197  long offset = m_part->d->caretOffset();
4198 
4199  CaretViewContext *cv = d->caretViewContext();
4200 
4201  ElementImpl *baseElem = determineBaseElement(caretNode);
4202  LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4203 
4204  ErgonomicEditableLineIterator it(ld.current(), cv->origX);
4205 
4206  // move count lines vertically
4207  while (count > 0 && it != ld.end() && it != ld.preBegin()) {
4208  count--;
4209  if (next) ++it; else --it;
4210  }/*wend*/
4211 
4212  // Nothing? Then leave everything as is.
4213  if (it == ld.end() || it == ld.preBegin()) return;
4214 
4215  int x, absx, absy;
4216  CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
4217 
4218  placeCaretOnLine(caretBox, x, absx, absy);
4219 }
4220 
4221 void TDEHTMLView::placeCaretOnLine(CaretBox *caretBox, int x, int absx, int absy)
4222 {
4223  // paranoia sanity check
4224  if (!caretBox) return;
4225 
4226  RenderObject *caretRender = caretBox->object();
4227 
4228 #if DEBUG_CARETMODE > 0
4229  kdDebug(6200) << "got valid caretBox " << caretBox << endl;
4230  kdDebug(6200) << "xPos: " << caretBox->xPos() << " yPos: " << caretBox->yPos()
4231  << " width: " << caretBox->width() << " height: " << caretBox->height() << endl;
4232  InlineTextBox *tb = static_cast<InlineTextBox *>(caretBox->inlineBox());
4233  if (caretBox->isInlineTextBox()) { kdDebug(6200) << "contains \"" << TQString(static_cast<RenderText *>(tb->object())->str->s + tb->m_start, tb->m_len) << "\"" << endl;}
4234 #endif
4235  // inquire height of caret
4236  int caretHeight = caretBox->height();
4237  bool isText = caretBox->isInlineTextBox();
4238  int yOfs = 0; // y-offset for text nodes
4239  if (isText) {
4240  // text boxes need extrawurst
4241  RenderText *t = static_cast<RenderText *>(caretRender);
4242  const TQFontMetrics &fm = t->metrics(caretBox->inlineBox()->m_firstLine);
4243  caretHeight = fm.height();
4244  yOfs = caretBox->inlineBox()->baseline() - fm.ascent();
4245  }/*end if*/
4246 
4247  caretOff();
4248 
4249  // set new caret node
4250  NodeImpl *caretNode;
4251  long &offset = m_part->d->caretOffset();
4252  mapRenderPosToDOMPos(caretRender, offset, caretBox->isOutside(),
4253  caretBox->isOutsideEnd(), caretNode, offset);
4254 
4255  // set all variables not needing special treatment
4256  d->m_caretViewContext->y = caretBox->yPos() + yOfs;
4257  d->m_caretViewContext->height = caretHeight;
4258  d->m_caretViewContext->width = 1; // FIXME: regard override
4259 
4260  int xPos = caretBox->xPos();
4261  int caretBoxWidth = caretBox->width();
4262  d->m_caretViewContext->x = xPos;
4263 
4264  if (!caretBox->isOutside()) {
4265  // before or at beginning of inline box -> place at beginning
4266  long r_ofs = 0;
4267  if (x <= xPos) {
4268  r_ofs = caretBox->minOffset();
4269  // somewhere within this block
4270  } else if (x > xPos && x <= xPos + caretBoxWidth) {
4271  if (isText) { // find out where exactly
4272  r_ofs = static_cast<InlineTextBox *>(caretBox->inlineBox())
4273  ->offsetForPoint(x, d->m_caretViewContext->x);
4274 #if DEBUG_CARETMODE > 2
4275  kdDebug(6200) << "deviation from origX " << d->m_caretViewContext->x - x << endl;
4276 #endif
4277 #if 0
4278  } else { // snap to nearest end
4279  if (xPos + caretBoxWidth - x < x - xPos) {
4280  d->m_caretViewContext->x = xPos + caretBoxWidth;
4281  r_ofs = caretNode ? caretNode->maxOffset() : 1;
4282  } else {
4283  d->m_caretViewContext->x = xPos;
4284  r_ofs = caretNode ? caretNode->minOffset() : 0;
4285  }/*end if*/
4286 #endif
4287  }/*end if*/
4288  } else { // after the inline box -> place at end
4289  d->m_caretViewContext->x = xPos + caretBoxWidth;
4290  r_ofs = caretBox->maxOffset();
4291  }/*end if*/
4292  offset = r_ofs;
4293  }/*end if*/
4294 #if DEBUG_CARETMODE > 0
4295  kdDebug(6200) << "new offset: " << offset << endl;
4296 #endif
4297 
4298  m_part->d->caretNode() = caretNode;
4299  m_part->d->caretOffset() = offset;
4300 
4301  d->m_caretViewContext->x += absx;
4302  d->m_caretViewContext->y += absy;
4303 
4304 #if DEBUG_CARETMODE > 1
4305  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;
4306 #endif
4307 
4308  ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
4309  d->m_caretViewContext->width, d->m_caretViewContext->height);
4310  d->scrollBarMoved = false;
4311 
4312  ensureNodeHasFocus(caretNode);
4313  caretOn();
4314 }
4315 
4316 void TDEHTMLView::moveCaretToLineBoundary(bool end)
4317 {
4318  Node &caretNodeRef = m_part->d->caretNode();
4319  if (caretNodeRef.isNull()) return;
4320 
4321  NodeImpl *caretNode = caretNodeRef.handle();
4322 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4323  long offset = m_part->d->caretOffset();
4324 
4325  ElementImpl *baseElem = determineBaseElement(caretNode);
4326  LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4327 
4328  EditableLineIterator it = ld.current();
4329  if (it == ld.end()) return; // should not happen, but who knows
4330 
4331  EditableCaretBoxIterator fbit(it, end);
4332  Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
4333  CaretBox *b = *fbit;
4334 
4335  RenderObject *cb = b->containingBlock();
4336  int absx, absy;
4337 
4338  if (cb) cb->absolutePosition(absx,absy);
4339  else absx = absy = 0;
4340 
4341  int x = b->xPos() + (end && !b->isOutside() ? b->width() : 0);
4342  d->m_caretViewContext->origX = absx + x;
4343  placeCaretOnLine(b, x, absx, absy);
4344 }
4345 
4346 void TDEHTMLView::moveCaretToDocumentBoundary(bool end)
4347 {
4348  Node &caretNodeRef = m_part->d->caretNode();
4349  if (caretNodeRef.isNull()) return;
4350 
4351  NodeImpl *caretNode = caretNodeRef.handle();
4352 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4353  long offset = m_part->d->caretOffset();
4354 
4355  ElementImpl *baseElem = determineBaseElement(caretNode);
4356  LinearDocument ld(m_part, caretNode, offset, IndicatedFlows, baseElem);
4357 
4358  EditableLineIterator it(end ? ld.preEnd() : ld.begin(), end);
4359  if (it == ld.end() || it == ld.preBegin()) return; // should not happen, but who knows
4360 
4361  EditableCaretBoxIterator fbit = it;
4362  Q_ASSERT(fbit != (*it)->end() && fbit != (*it)->preBegin());
4363  CaretBox *b = *fbit;
4364 
4365  RenderObject *cb = (*it)->containingBlock();
4366  int absx, absy;
4367 
4368  if (cb) cb->absolutePosition(absx, absy);
4369  else absx = absy = 0;
4370 
4371  int x = b->xPos()/* + (end ? b->width() : 0) reactivate for rtl*/;
4372  d->m_caretViewContext->origX = absx + x;
4373  placeCaretOnLine(b, x, absx, absy);
4374 }
4375 
4376 void TDEHTMLView::moveCaretBy(bool next, CaretMovement cmv, int count)
4377 {
4378  if (!m_part) return;
4379  Node &caretNodeRef = m_part->d->caretNode();
4380  if (caretNodeRef.isNull()) return;
4381 
4382  NodeImpl *caretNode = caretNodeRef.handle();
4383 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4384  long &offset = m_part->d->caretOffset();
4385 
4386  ElementImpl *baseElem = determineBaseElement(caretNode);
4387  CaretAdvancePolicy advpol = cmv != CaretByWord ? IndicatedFlows : LeafsOnly;
4388  LinearDocument ld(m_part, caretNode, offset, advpol, baseElem);
4389 
4390  EditableCharacterIterator it(&ld);
4391  while (!it.isEnd() && count > 0) {
4392  count--;
4393  if (cmv == CaretByCharacter) {
4394  if (next) ++it;
4395  else --it;
4396  } else if (cmv == CaretByWord) {
4397  if (next) moveItToNextWord(it);
4398  else moveItToPrevWord(it);
4399  }/*end if*/
4400 //kdDebug(6200) << "movecaret" << endl;
4401  }/*wend*/
4402  CaretBox *hintBox = 0; // make gcc uninit warning disappear
4403  if (!it.isEnd()) {
4404  NodeImpl *node = caretNodeRef.handle();
4405  hintBox = it.caretBox();
4406 //kdDebug(6200) << "hintBox = " << hintBox << endl;
4407 //kdDebug(6200) << " outside " << hintBox->isOutside() << " outsideEnd " << hintBox->isOutsideEnd() << " r " << it.renderer() << " ofs " << it.offset() << " cb " << hintBox->containingBlock() << endl;
4408  mapRenderPosToDOMPos(it.renderer(), it.offset(), hintBox->isOutside(),
4409  hintBox->isOutsideEnd(), node, offset);
4410 //kdDebug(6200) << "mapRTD" << endl;
4411  caretNodeRef = node;
4412 #if DEBUG_CARETMODE > 2
4413  kdDebug(6200) << "set by valid node " << node << " " << (node?node->nodeName().string():TQString::null) << " offset: " << offset << endl;
4414 #endif
4415  } else {
4416  offset = next ? caretNode->maxOffset() : caretNode->minOffset();
4417 #if DEBUG_CARETMODE > 0
4418  kdDebug(6200) << "set by INvalid node. offset: " << offset << endl;
4419 #endif
4420  }/*end if*/
4421  placeCaretOnChar(hintBox);
4422 }
4423 
4424 void TDEHTMLView::placeCaretOnChar(CaretBox *hintBox)
4425 {
4426  caretOff();
4427  recalcAndStoreCaretPos(hintBox);
4428  ensureVisible(d->m_caretViewContext->x, d->m_caretViewContext->y,
4429  d->m_caretViewContext->width, d->m_caretViewContext->height);
4430  d->m_caretViewContext->origX = d->m_caretViewContext->x;
4431  d->scrollBarMoved = false;
4432 #if DEBUG_CARETMODE > 3
4433  //if (caretNode->isTextNode()) kdDebug(6200) << "text[0] = " << (int)*((TextImpl *)caretNode)->data().unicode() << " text :\"" << ((TextImpl *)caretNode)->data().string() << "\"" << endl;
4434 #endif
4435  ensureNodeHasFocus(m_part->d->caretNode().handle());
4436  caretOn();
4437 }
4438 
4439 void TDEHTMLView::moveCaretByPage(bool next)
4440 {
4441  Node &caretNodeRef = m_part->d->caretNode();
4442  if (caretNodeRef.isNull()) return;
4443 
4444  NodeImpl *caretNode = caretNodeRef.handle();
4445 // kdDebug(6200) << ": caretNode=" << caretNode << endl;
4446  long offset = m_part->d->caretOffset();
4447 
4448  int offs = (clipper()->height() < 30) ? clipper()->height() : 30;
4449  // Minimum distance the caret must be moved
4450  int mindist = clipper()->height() - offs;
4451 
4452  CaretViewContext *cv = d->caretViewContext();
4453 // int y = cv->y; // we always measure the top border
4454 
4455  ElementImpl *baseElem = determineBaseElement(caretNode);
4456  LinearDocument ld(m_part, caretNode, offset, LeafsOnly, baseElem);
4457 
4458  ErgonomicEditableLineIterator it(ld.current(), cv->origX);
4459 
4460  moveIteratorByPage(ld, it, mindist, next);
4461 
4462  int x, absx, absy;
4463  CaretBox *caretBox = nearestCaretBox(it, d->m_caretViewContext, x, absx, absy);
4464 
4465  placeCaretOnLine(caretBox, x, absx, absy);
4466 }
4467 
4468 void TDEHTMLView::moveCaretPrevWord()
4469 {
4470  moveCaretBy(false, CaretByWord, 1);
4471 }
4472 
4473 void TDEHTMLView::moveCaretNextWord()
4474 {
4475  moveCaretBy(true, CaretByWord, 1);
4476 }
4477 
4478 void TDEHTMLView::moveCaretPrevLine(int n)
4479 {
4480  moveCaretByLine(false, n);
4481 }
4482 
4483 void TDEHTMLView::moveCaretNextLine(int n)
4484 {
4485  moveCaretByLine(true, n);
4486 }
4487 
4488 void TDEHTMLView::moveCaretPrevPage()
4489 {
4490  moveCaretByPage(false);
4491 }
4492 
4493 void TDEHTMLView::moveCaretNextPage()
4494 {
4495  moveCaretByPage(true);
4496 }
4497 
4498 void TDEHTMLView::moveCaretToLineBegin()
4499 {
4500  moveCaretToLineBoundary(false);
4501 }
4502 
4503 void TDEHTMLView::moveCaretToLineEnd()
4504 {
4505  moveCaretToLineBoundary(true);
4506 }
4507 
4508 #endif // TDEHTML_NO_CARET
4509 
4510 #ifndef NO_SMOOTH_SCROLL_HACK
4511 #define timer timer2
4512 
4513 // All scrolls must be completed within 240ms of last keypress
4514 static const int SCROLL_TIME = 240;
4515 // Each step is 20 ms == 50 frames/second
4516 static const int SCROLL_TICK = 20;
4517 
4518 void TDEHTMLView::scrollBy(int dx, int dy)
4519 {
4520  TDEConfigGroup cfg( TDEGlobal::config(), "KDE" );
4521  if( !cfg.readBoolEntry( "SmoothScrolling", false )) {
4522  TQScrollView::scrollBy( dx, dy );
4523  return;
4524  }
4525  // scrolling destination
4526  int full_dx = d->dx + dx;
4527  int full_dy = d->dy + dy;
4528 
4529  // scrolling speed
4530  int ddx = 0;
4531  int ddy = 0;
4532 
4533  int steps = SCROLL_TIME/SCROLL_TICK;
4534 
4535  ddx = (full_dx*16)/steps;
4536  ddy = (full_dy*16)/steps;
4537 
4538  // don't go under 1px/step
4539  if (ddx > 0 && ddx < 16) ddx = 16;
4540  if (ddy > 0 && ddy < 16) ddy = 16;
4541  if (ddx < 0 && ddx > -16) ddx = -16;
4542  if (ddy < 0 && ddy > -16) ddy = -16;
4543 
4544  d->dx = full_dx;
4545  d->dy = full_dy;
4546  d->ddx = ddx;
4547  d->ddy = ddy;
4548 
4549  if (!d->scrolling) {
4550  scrollTick();
4551  startScrolling();
4552  }
4553 }
4554 
4555 void TDEHTMLView::scrollTick() {
4556  if (d->dx == 0 && d->dy == 0) {
4557  stopScrolling();
4558  return;
4559  }
4560 
4561  int tddx = d->ddx + d->rdx;
4562  int tddy = d->ddy + d->rdy;
4563 
4564  int ddx = tddx / 16;
4565  int ddy = tddy / 16;
4566  d->rdx = tddx % 16;
4567  d->rdy = tddy % 16;
4568 
4569  if (d->dx > 0 && ddx > d->dx) ddx = d->dx;
4570  else
4571  if (d->dx < 0 && ddx < d->dx) ddx = d->dx;
4572 
4573  if (d->dy > 0 && ddy > d->dy) ddy = d->dy;
4574  else
4575  if (d->dy < 0 && ddy < d->dy) ddy = d->dy;
4576 
4577  d->dx -= ddx;
4578  d->dy -= ddy;
4579 
4580 // TQScrollView::setContentsPos( contentsX() + ddx, contentsY() + ddy);
4581  kapp->syncX();
4582  TQScrollView::scrollBy(ddx, ddy);
4583 // Unaccelerated X can get seriously overloaded by scrolling and for some reason
4584 // will send KeyPress events only infrequently. This should help to reduce
4585 // the load.
4586  kapp->syncX();
4587 }
4588 
4589 void TDEHTMLView::startScrolling()
4590 {
4591  d->scrolling = true;
4592  d->timer.start(SCROLL_TICK, false);
4593 }
4594 
4595 void TDEHTMLView::stopScrolling()
4596 {
4597  d->timer.stop();
4598  d->dx = d->dy = 0;
4599  d->scrolling = false;
4600 }
4601 
4602 // Overloaded from TQScrollView and TQScrollBar
4603 void TDEHTMLView::scrollViewWheelEvent( TQWheelEvent *e )
4604 {
4605  int pageStep = verticalScrollBar()->pageStep();
4606  int lineStep = verticalScrollBar()->lineStep();
4607  int step = TQMIN( TQApplication::wheelScrollLines()*lineStep, pageStep );
4608  if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
4609  step = pageStep;
4610 
4611  if(e->orientation() == Qt::Horizontal)
4612  scrollBy(-((e->delta()*step)/120), 0);
4613  else if(e->orientation() == Qt::Vertical)
4614  scrollBy(0,-((e->delta()*step)/120));
4615 
4616  e->accept();
4617 }
4618 
4619 #undef timer
4620 
4621 #endif // NO_SMOOTH_SCROLL_HACK
4622 
4623 #undef DEBUG_CARETMODE
TDEConfig
TDEHTMLView::layout
void layout()
ensure the display is up to date
Definition: tdehtmlview.cpp:800
KNotifyClient::event
int event(const TQString &message, const TQString &text=TQString::null) KDE_DEPRECATED
TDEHTMLView::setVScrollBarMode
virtual void setVScrollBarMode(ScrollBarMode mode)
Sets verticals scrollbar mode.
Definition: tdehtmlview.cpp:3020
TDEHTMLPart::isCaretMode
bool isCaretMode() const
Returns whether caret mode is on/off.
Definition: tdehtml_part.cpp:2662
TDEIcon::DefaultState
DOM::Node
The Node interface is the primary datatype for the entire Document Object Model.
Definition: dom_node.h:274
KCursor::sizeAllCursor
static TQCursor sizeAllCursor()
TDEHTMLPart::urlCursor
TQCursor urlCursor() const
Returns the cursor which is used when the cursor is on a link.
Definition: tdehtml_part.cpp:2602
locateLocal
TQString locateLocal(const char *type, const TQString &filename, const TDEInstance *instance=TDEGlobal::instance())
KNotifyClient::beep
void beep(const TQString &reason=TQString::null)
TDEHTMLPart::isEditable
bool isEditable() const
Returns true if the document is editable, false otherwise.
Definition: tdehtml_part.cpp:2683
KCursor::whatsThisCursor
static TQCursor whatsThisCursor()
KStringHandler::csqueeze
static TQString csqueeze(const TQString &str, uint maxlen=40)
TDEHTMLPart::document
DOM::Document document() const
Returns a reference to the DOM document.
Definition: tdehtml_part.cpp:859
TDEConfigGroupSaver
TDEStdAccel::key
int key(StdAccel) KDE_DEPRECATED
KParts::ReadOnlyPart::completed
void completed()
kdError
kdbgstream kdError(int area=0)
TDEGlobal::iconLoader
static TDEIconLoader * iconLoader()
TDEHTMLPart::findTextBegin
void findTextBegin()
Initiates a text search.
Definition: tdehtml_part.cpp:2737
KParts::Part::widget
virtual TQWidget * widget()
TDEHTMLView::print
void print()
Prints the HTML document.
Definition: tdehtmlview.cpp:2771
kdDebug
kdbgstream kdDebug(int area=0)
TDEHTMLView::TDEHTMLView
TDEHTMLView(TDEHTMLPart *part, TQWidget *parent, const char *name=0)
Constructs a TDEHTMLView.
Definition: tdehtmlview.cpp:487
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
KCursor::workingCursor
static TQCursor workingCursor()
KCursor::sizeBDiagCursor
static TQCursor sizeBDiagCursor()
KDialogBase
TDEHTMLView::finishedLayout
void finishedLayout()
This signal is used for internal layouting.
tdehtml
Definition: tdehtml_caret.cpp:26
TDEConfigGroup
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
tdelocale.h
KCursor::waitCursor
static TQCursor waitCursor()
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
KCursor::arrowCursor
static TQCursor arrowCursor()
KCursor::sizeHorCursor
static TQCursor sizeHorCursor()
KMIN
#define KMIN(a, b)
kdWarning
kdbgstream kdWarning(int area=0)
TDEHTMLView::setMarginWidth
void setMarginWidth(int x)
Sets a margin in x direction.
Definition: tdehtmlview.cpp:788
DOM::Node::isNull
bool isNull() const
tests if this Node is 0.
Definition: dom_node.h:892
DOM::DOMString
This class implements the basic string we use in the DOM.
Definition: dom_string.h:43
KCursor::ibeamCursor
static TQCursor ibeamCursor()
KCursor::sizeVerCursor
static TQCursor sizeVerCursor()
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::Small
KCursor::sizeFDiagCursor
static TQCursor sizeFDiagCursor()
TDEStdAccel::close
const TDEShortcut & close()
TDEHTMLPart::view
TDEHTMLView * view() const
Returns a pointer to the HTML document's view.
Definition: tdehtml_part.cpp:906
TDEHTMLView::displayAccessKeys
void displayAccessKeys()
Display all accesskeys in small tooltips.
Definition: tdehtmlview.cpp:2256
DOM
The Document Object Model (DOM) is divided into two parts, the COREDOM core DOM, specifying some core...
Definition: design.h:56
TDEGlobal::locale
static TDELocale * locale()
TDELocale::formatDate
TQString formatDate(const TQDate &pDate, bool shortFormat=false) const
TDEHTMLPart::nodeActivated
void nodeActivated(const DOM::Node &)
This signal is emitted when an element retrieves the keyboard focus.
TDEHTMLPart::zoomFactor
int zoomFactor() const
Returns the current zoom factor.
Definition: tdehtml_part.cpp:5664
TDEHTMLPart
This class is tdehtml's main class.
Definition: tdehtml_part.h:183
TDEHTMLView::part
TDEHTMLPart * part() const
Returns a pointer to the TDEHTMLPart that is rendering the page.
Definition: tdehtmlview.h:113
TDEHTMLView
Renders and displays HTML in a TQScrollView.
Definition: tdehtmlview.h:78
TDEGlobal::config
static TDEConfig * config()
endl
kndbgstream & endl(kndbgstream &s)
KSimpleConfig
TDEHTMLPart::CaretDisplayPolicy
CaretDisplayPolicy
Enumeration for displaying the caret.
Definition: tdehtml_part.h:495
TDEStdAccel::label
TQString label(StdAccel id)
TDEHTMLView::setHScrollBarMode
virtual void setHScrollBarMode(ScrollBarMode mode)
Sets horizontal scrollbar mode.
Definition: tdehtmlview.cpp:3030
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::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
KCursor::crossCursor
static TQCursor crossCursor()

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdehtml by doxygen 1.8.8
This website is maintained by Timothy Pearson.