KHtml

render_frames.cpp
1 /**
2  * This file is part of the KDE project.
3  *
4  * Copyright (C) 1999 Lars Knoll ([email protected])
5  * (C) 2000 Simon Hausmann <[email protected]>
6  * (C) 2000 Stefan Schimanski ([email protected])
7  * (C) 2003 Apple Computer, Inc.
8  * (C) 2005 Niels Leenheer <[email protected]>
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 //#define DEBUG_LAYOUT
27 
28 #include "rendering/render_frames.h"
29 #include "rendering/render_canvas.h"
30 #include "html/html_objectimpl.h"
31 #include "html/htmltokenizer.h"
32 #include "xml/dom2_eventsimpl.h"
33 #include "xml/dom_docimpl.h"
34 #include "khtmlview.h"
35 #include "khtml_part.h"
36 
37 #include "khtml_debug.h"
38 #include <QPainter>
39 #include <QCursor>
40 #include <QApplication>
41 
42 using namespace khtml;
43 using namespace DOM;
44 
45 RenderFrameSet::RenderFrameSet(HTMLFrameSetElementImpl *frameSet)
46  : RenderBox(frameSet)
47 {
48  // init RenderObject attributes
49  setInline(false);
50 
51  for (int k = 0; k < 2; ++k) {
52  m_gridLen[k] = -1;
53  m_gridDelta[k] = nullptr;
54  m_gridLayout[k] = nullptr;
55  }
56 
57  m_resizing = m_clientresizing = false;
58 
59  m_cursor = Qt::ArrowCursor;
60 
61  m_hSplit = -1;
62  m_vSplit = -1;
63 
64  m_hSplitVar = nullptr;
65  m_vSplitVar = nullptr;
66 }
67 
68 RenderFrameSet::~RenderFrameSet()
69 {
70  for (int k = 0; k < 2; ++k) {
71  delete [] m_gridLayout[k];
72  delete [] m_gridDelta[k];
73  }
74  delete [] m_hSplitVar;
75  delete [] m_vSplitVar;
76 }
77 
78 bool RenderFrameSet::nodeAtPoint(NodeInfo &info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inBox)
79 {
80  RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inBox);
81 
82  bool inside = m_resizing || canResize(_x, _y);
83 
84  if (inside && element() && !element()->noResize() && !info.readonly()) {
85  info.setInnerNode(element());
86  info.setInnerNonSharedNode(element());
87  }
88 
89  return inside || m_clientresizing;
90 }
91 
92 void RenderFrameSet::layout()
93 {
94  KHTMLAssert(needsLayout());
95  KHTMLAssert(minMaxKnown());
96 
97  if (!parent()->isFrameSet()) {
98  KHTMLView *view = canvas()->view();
99  m_width = view ? view->visibleWidth() : 0;
100  m_height = view ? view->visibleHeight() : 0;
101  }
102 
103 #ifdef DEBUG_LAYOUT
104  // qCDebug(KHTML_LOG) << renderName() << "(FrameSet)::layout( ) width=" << width() << ", height=" << height();
105 #endif
106 
107  int remainingLen[2];
108  remainingLen[1] = m_width - (element()->totalCols() - 1) * element()->border();
109  if (remainingLen[1] < 0) {
110  remainingLen[1] = 0;
111  }
112  remainingLen[0] = m_height - (element()->totalRows() - 1) * element()->border();
113  if (remainingLen[0] < 0) {
114  remainingLen[0] = 0;
115  }
116 
117  int availableLen[2];
118  availableLen[0] = remainingLen[0];
119  availableLen[1] = remainingLen[1];
120 
121  if (m_gridLen[0] != element()->totalRows() || m_gridLen[1] != element()->totalCols()) {
122  // number of rows or cols changed
123  // need to zero out the deltas
124  m_gridLen[0] = element()->totalRows();
125  m_gridLen[1] = element()->totalCols();
126  for (int k = 0; k < 2; ++k) {
127  delete [] m_gridDelta[k];
128  m_gridDelta[k] = new int[m_gridLen[k]];
129  delete [] m_gridLayout[k];
130  m_gridLayout[k] = new int[m_gridLen[k]];
131  for (int i = 0; i < m_gridLen[k]; ++i) {
132  m_gridDelta[k][i] = 0;
133  }
134  }
135  }
136 
137  for (int k = 0; k < 2; ++k) {
138  int totalRelative = 0;
139  int totalFixed = 0;
140  int totalPercent = 0;
141  int countRelative = 0;
142  int countFixed = 0;
143  int countPercent = 0;
144  int gridLen = m_gridLen[k];
145  int *gridDelta = m_gridDelta[k];
146  khtml::Length *grid = k ? element()->m_cols : element()->m_rows;
147  int *gridLayout = m_gridLayout[k];
148 
149  if (grid) {
150  // First we need to investigate how many columns of each type we have and
151  // how much space these columns are going to require.
152  for (int i = 0; i < gridLen; ++i) {
153  // Count the total length of all of the fixed columns/rows -> totalFixed
154  // Count the number of columns/rows which are fixed -> countFixed
155  if (grid[i].isFixed()) {
156  gridLayout[i] = qMax(grid[i].value(), 0);
157  totalFixed += gridLayout[i];
158  countFixed++;
159  }
160 
161  // Count the total percentage of all of the percentage columns/rows -> totalPercent
162  // Count the number of columns/rows which are percentages -> countPercent
163  if (grid[i].isPercent()) {
164  gridLayout[i] = qMax(grid[i].width(availableLen[k]), 0);
165  totalPercent += gridLayout[i];
166  countPercent++;
167  }
168 
169  // Count the total relative of all the relative columns/rows -> totalRelative
170  // Count the number of columns/rows which are relative -> countRelative
171  if (grid[i].isRelative()) {
172  totalRelative += qMax(grid[i].value(), 1);
173  countRelative++;
174  }
175  }
176 
177  // Fixed columns/rows are our first priority. If there is not enough space to fit all fixed
178  // columns/rows we need to proportionally adjust their size.
179  if (totalFixed > remainingLen[k]) {
180  int remainingFixed = remainingLen[k];
181 
182  for (int i = 0; i < gridLen; ++i) {
183  if (grid[i].isFixed()) {
184  gridLayout[i] = (gridLayout[i] * remainingFixed) / totalFixed;
185  remainingLen[k] -= gridLayout[i];
186  }
187  }
188  } else {
189  remainingLen[k] -= totalFixed;
190  }
191 
192  // Percentage columns/rows are our second priority. Divide the remaining space proportionally
193  // over all percentage columns/rows. IMPORTANT: the size of each column/row is not relative
194  // to 100%, but to the total percentage. For example, if there are three columns, each of 75%,
195  // and the available space is 300px, each column will become 100px in width.
196  if (totalPercent > remainingLen[k]) {
197  int remainingPercent = remainingLen[k];
198 
199  for (int i = 0; i < gridLen; ++i) {
200  if (grid[i].isPercent()) {
201  gridLayout[i] = (gridLayout[i] * remainingPercent) / totalPercent;
202  remainingLen[k] -= gridLayout[i];
203  }
204  }
205  } else {
206  remainingLen[k] -= totalPercent;
207  }
208 
209  // Relative columns/rows are our last priority. Divide the remaining space proportionally
210  // over all relative columns/rows. IMPORTANT: the relative value of 0* is treated as 1*.
211  if (countRelative) {
212  int lastRelative = 0;
213  int remainingRelative = remainingLen[k];
214 
215  for (int i = 0; i < gridLen; ++i) {
216  if (grid[i].isRelative()) {
217  gridLayout[i] = (qMax(grid[i].value(), 1) * remainingRelative) / totalRelative;
218  remainingLen[k] -= gridLayout[i];
219  lastRelative = i;
220  }
221  }
222 
223  // If we could not evently distribute the available space of all of the relative
224  // columns/rows, the remainder will be added to the last column/row.
225  // For example: if we have a space of 100px and three columns (*,*,*), the remainder will
226  // be 1px and will be added to the last column: 33px, 33px, 34px.
227  if (remainingLen[k]) {
228  gridLayout[lastRelative] += remainingLen[k];
229  remainingLen[k] = 0;
230  }
231  }
232 
233  // If we still have some left over space we need to divide it over the already existing
234  // columns/rows
235  if (remainingLen[k]) {
236  // Our first priority is to spread if over the percentage columns. The remaining
237  // space is spread evenly, for example: if we have a space of 100px, the columns
238  // definition of 25%,25% used to result in two columns of 25px. After this the
239  // columns will each be 50px in width.
240  if (countPercent && totalPercent) {
241  int remainingPercent = remainingLen[k];
242  int changePercent = 0;
243 
244  for (int i = 0; i < gridLen; ++i) {
245  if (grid[i].isPercent()) {
246  changePercent = (remainingPercent * gridLayout[i]) / totalPercent;
247  gridLayout[i] += changePercent;
248  remainingLen[k] -= changePercent;
249  }
250  }
251  } else if (totalFixed) {
252  // Our last priority is to spread the remaining space over the fixed columns.
253  // For example if we have 100px of space and two column of each 40px, both
254  // columns will become exactly 50px.
255  int remainingFixed = remainingLen[k];
256  int changeFixed = 0;
257 
258  for (int i = 0; i < gridLen; ++i) {
259  if (grid[i].isFixed()) {
260  changeFixed = (remainingFixed * gridLayout[i]) / totalFixed;
261  gridLayout[i] += changeFixed;
262  remainingLen[k] -= changeFixed;
263  }
264  }
265  }
266  }
267 
268  // If we still have some left over space we probably ended up with a remainder of
269  // a division. We can not spread it evenly anymore. If we have any percentage
270  // columns/rows simply spread the remainder equally over all available percentage columns,
271  // regardless of their size.
272  if (remainingLen[k] && countPercent) {
273  int remainingPercent = remainingLen[k];
274  int changePercent = 0;
275 
276  for (int i = 0; i < gridLen; ++i) {
277  if (grid[i].isPercent()) {
278  changePercent = remainingPercent / countPercent;
279  gridLayout[i] += changePercent;
280  remainingLen[k] -= changePercent;
281  }
282  }
283  }
284 
285  // If we don't have any percentage columns/rows we only have fixed columns. Spread
286  // the remainder equally over all fixed columns/rows.
287  else if (remainingLen[k] && countFixed) {
288  int remainingFixed = remainingLen[k];
289  int changeFixed = 0;
290 
291  for (int i = 0; i < gridLen; ++i) {
292  if (grid[i].isFixed()) {
293  changeFixed = remainingFixed / countFixed;
294  gridLayout[i] += changeFixed;
295  remainingLen[k] -= changeFixed;
296  }
297  }
298  }
299 
300  // Still some left over... simply add it to the last column, because it is impossible
301  // spread it evenly or equally.
302  if (remainingLen[k]) {
303  gridLayout[gridLen - 1] += remainingLen[k];
304  }
305 
306  // now we have the final layout, distribute the delta over it
307  bool worked = true;
308  for (int i = 0; i < gridLen; ++i) {
309  if (gridLayout[i] && gridLayout[i] + gridDelta[i] <= 0) {
310  worked = false;
311  }
312  gridLayout[i] += gridDelta[i];
313  }
314  // now the delta's broke something, undo it and reset deltas
315  if (!worked)
316  for (int i = 0; i < gridLen; ++i) {
317  gridLayout[i] -= gridDelta[i];
318  gridDelta[i] = 0;
319  }
320  } else {
321  gridLayout[0] = remainingLen[k];
322  }
323  }
324 
325  positionFrames();
326 
327  RenderObject *child = firstChild();
328  if (!child) {
329  goto end2;
330  }
331 
332  if (!m_hSplitVar && !m_vSplitVar) {
333 #ifdef DEBUG_LAYOUT
334  // qCDebug(KHTML_LOG) << "calculationg fixed Splitters";
335 #endif
336  if (!m_vSplitVar && element()->totalCols() > 1) {
337  m_vSplitVar = new bool[element()->totalCols()];
338  for (int i = 0; i < element()->totalCols(); i++) {
339  m_vSplitVar[i] = true;
340  }
341  }
342  if (!m_hSplitVar && element()->totalRows() > 1) {
343  m_hSplitVar = new bool[element()->totalRows()];
344  for (int i = 0; i < element()->totalRows(); i++) {
345  m_hSplitVar[i] = true;
346  }
347  }
348 
349  for (int r = 0; r < element()->totalRows(); r++) {
350  for (int c = 0; c < element()->totalCols(); c++) {
351  bool fixed = false;
352 
353  if (child->isFrameSet()) {
354  fixed = static_cast<RenderFrameSet *>(child)->element()->noResize();
355  } else {
356  fixed = static_cast<RenderFrame *>(child)->element()->noResize();
357  }
358 
359  if (fixed) {
360 #ifdef DEBUG_LAYOUT
361  // qCDebug(KHTML_LOG) << "found fixed cell " << r << "/" << c << "!";
362 #endif
363  if (element()->totalCols() > 1) {
364  if (c > 0) {
365  m_vSplitVar[c - 1] = false;
366  }
367  m_vSplitVar[c] = false;
368  }
369  if (element()->totalRows() > 1) {
370  if (r > 0) {
371  m_hSplitVar[r - 1] = false;
372  }
373  m_hSplitVar[r] = false;
374  }
375  child = child->nextSibling();
376  if (!child) {
377  goto end2;
378  }
379  }
380 #ifdef DEBUG_LAYOUT
381  else
382  // qCDebug(KHTML_LOG) << "not fixed: " << r << "/" << c << "!";
383 #endif
384  }
385  }
386 
387  }
388  RenderContainer::layout();
389 end2:
390  setNeedsLayout(false);
391 }
392 
393 void RenderFrameSet::positionFrames()
394 {
395  int r;
396  int c;
397 
398  RenderObject *child = firstChild();
399  if (!child) {
400  return;
401  }
402 
403  // NodeImpl *child = _first;
404  // if(!child) return;
405 
406  int yPos = 0;
407 
408  for (r = 0; r < element()->totalRows(); r++) {
409  int xPos = 0;
410  for (c = 0; c < element()->totalCols(); c++) {
411  child->setPos(xPos, yPos);
412 #ifdef DEBUG_LAYOUT
413  // qCDebug(KHTML_LOG) << "child frame at (" << xPos << "/" << yPos << ") size (" << m_gridLayout[1][c] << "/" << m_gridLayout[0][r] << ")";
414 #endif
415  // has to be resized and itself resize its contents
416  if ((m_gridLayout[1][c] != child->width()) || (m_gridLayout[0][r] != child->height())) {
417  child->setWidth(m_gridLayout[1][c]);
418  child->setHeight(m_gridLayout[0][r]);
419  child->setNeedsLayout(true);
420  child->layout();
421  }
422 
423  xPos += m_gridLayout[1][c] + element()->border();
424  child = child->nextSibling();
425 
426  if (!child) {
427  return;
428  }
429 
430  }
431 
432  yPos += m_gridLayout[0][r] + element()->border();
433  }
434 
435  // all the remaining frames are hidden to avoid ugly
436  // spurious unflowed frames
437  while (child) {
438  child->setWidth(0);
439  child->setHeight(0);
440  child->setNeedsLayout(false);
441 
442  child = child->nextSibling();
443  }
444 }
445 
446 bool RenderFrameSet::userResize(MouseEventImpl *evt)
447 {
448  if (needsLayout()) {
449  return false;
450  }
451 
452  bool res = false;
453  int _x = evt->clientX();
454  int _y = evt->clientY();
455 
456  if ((!m_resizing && evt->id() == EventImpl::MOUSEMOVE_EVENT) || evt->id() == EventImpl::MOUSEDOWN_EVENT) {
457 #ifdef DEBUG_LAYOUT
458  // qCDebug(KHTML_LOG) << "mouseEvent:check";
459 #endif
460 
461  m_hSplit = -1;
462  m_vSplit = -1;
463 
464  // check if we're over a horizontal or vertical boundary
465  int pos = m_gridLayout[1][0] + xPos();
466  for (int c = 1; c < element()->totalCols(); c++) {
467  if (_x >= pos && _x <= pos + element()->border()) {
468  if (m_vSplitVar && m_vSplitVar[c - 1] == true) {
469  m_vSplit = c - 1;
470  }
471 #ifdef DEBUG_LAYOUT
472  // qCDebug(KHTML_LOG) << "vsplit!";
473 #endif
474  res = true;
475  break;
476  }
477  pos += m_gridLayout[1][c] + element()->border();
478  }
479 
480  pos = m_gridLayout[0][0] + yPos();
481  for (int r = 1; r < element()->totalRows(); r++) {
482  if (_y >= pos && _y <= pos + element()->border()) {
483  if (m_hSplitVar && m_hSplitVar[r - 1] == true) {
484  m_hSplit = r - 1;
485  }
486 #ifdef DEBUG_LAYOUT
487  // qCDebug(KHTML_LOG) << "hsplitvar = " << m_hSplitVar;
488  // qCDebug(KHTML_LOG) << "hsplit!";
489 #endif
490  res = true;
491  break;
492  }
493  pos += m_gridLayout[0][r] + element()->border();
494  }
495 #ifdef DEBUG_LAYOUT
496  // qCDebug(KHTML_LOG) << m_hSplit << "/" << m_vSplit;
497 #endif
498  }
499 
500  m_cursor = Qt::ArrowCursor;
501  if (m_hSplit != -1 && m_vSplit != -1) {
502  m_cursor = Qt::SizeAllCursor;
503  } else if (m_vSplit != -1) {
504  m_cursor = Qt::SizeHorCursor;
505  } else if (m_hSplit != -1) {
506  m_cursor = Qt::SizeVerCursor;
507  }
508 
509  if (!m_resizing && evt->id() == EventImpl::MOUSEDOWN_EVENT) {
510  setResizing(true);
512  m_vSplitPos = _x;
513  m_hSplitPos = _y;
514  m_oldpos = -1;
515  }
516 
517  // ### check the resize is not going out of bounds.
518  if (m_resizing) {
519  if (evt->id() == EventImpl::MOUSEUP_EVENT) {
520  setResizing(false);
522  }
523 
524  if (m_vSplit != -1) {
525 #ifdef DEBUG_LAYOUT
526  // qCDebug(KHTML_LOG) << "split xpos=" << _x;
527 #endif
528  int delta = m_vSplitPos - _x;
529  m_gridDelta[1][m_vSplit] -= delta;
530  m_gridDelta[1][m_vSplit + 1] += delta;
531  m_vSplitPos = _x;
532  }
533  if (m_hSplit != -1) {
534 #ifdef DEBUG_LAYOUT
535  // qCDebug(KHTML_LOG) << "split ypos=" << _y;
536 #endif
537  int delta = m_hSplitPos - _y;
538  m_gridDelta[0][m_hSplit] -= delta;
539  m_gridDelta[0][m_hSplit + 1] += delta;
540  m_hSplitPos = _y;
541  }
542 
543  // this just schedules the relayout
544  // important, otherwise the moving indicator is not correctly erased
545  setNeedsLayout(true);
546  }
547 
548  /*
549  KHTMLView *view = canvas()->view();
550  if ((m_resizing || evt->id() == EventImpl::MOUSEUP_EVENT) && view) {
551  QPainter paint( view );
552  paint.setPen( Qt::gray );
553  paint.setBrush( Qt::gray );
554  paint.setCompositionMode(QPainter::CompositionMode_Xor);
555  QRect r(xPos(), yPos(), width(), height());
556  const int rBord = 3;
557  int sw = element()->border();
558  int p = m_resizing ? (m_vSplit > -1 ? _x : _y) : -1;
559  if (m_vSplit > -1) {
560  if ( m_oldpos >= 0 )
561  paint.drawRect( m_oldpos + sw/2 - rBord , r.y(),
562  2*rBord, r.height() );
563  if ( p >= 0 )
564  paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() );
565  } else {
566  if ( m_oldpos >= 0 )
567  paint.drawRect( r.x(), m_oldpos + sw/2 - rBord,
568  r.width(), 2*rBord );
569  if ( p >= 0 )
570  paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
571  }
572  m_oldpos = p;
573  }
574  */
575  return res;
576 }
577 
578 void RenderFrameSet::paintFrameSetRules(QPainter *paint, const QRect &damageRect)
579 {
580  Q_UNUSED(damageRect);
581  KHTMLView *view = canvas()->view();
582  if (view && !noResize()) {
583  paint->setPen(Qt::gray);
584  paint->setBrush(Qt::gray);
585  const int rBord = 3;
586  int sw = element()->border();
587 
588  // ### implement me
589 
590  (void) rBord;
591  (void) sw;
592  }
593 
594 }
595 
596 void RenderFrameSet::setResizing(bool e)
597 {
598  m_resizing = e;
599  for (RenderObject *p = parent(); p; p = p->parent())
600  if (p->isFrameSet()) {
601  static_cast<RenderFrameSet *>(p)->m_clientresizing = m_resizing;
602  }
603 }
604 
605 bool RenderFrameSet::canResize(int _x, int _y)
606 {
607  // if we haven't received a layout, then the gridLayout doesn't contain useful data yet
608  if (needsLayout() || !m_gridLayout[0] || !m_gridLayout[1]) {
609  return false;
610  }
611 
612  // check if we're over a horizontal or vertical boundary
613  int pos = m_gridLayout[1][0];
614  for (int c = 1; c < element()->totalCols(); c++)
615  if (_x >= pos && _x <= pos + element()->border()) {
616  return true;
617  }
618 
619  pos = m_gridLayout[0][0];
620  for (int r = 1; r < element()->totalRows(); r++)
621  if (_y >= pos && _y <= pos + element()->border()) {
622  return true;
623  }
624 
625  return false;
626 }
627 
628 #ifdef ENABLE_DUMP
629 void RenderFrameSet::dump(QTextStream &stream, const QString &ind) const
630 {
631  RenderBox::dump(stream, ind);
632  stream << " totalrows=" << element()->totalRows();
633  stream << " totalcols=" << element()->totalCols();
634 
635  if (m_hSplitVar)
636  for (uint i = 0; i < (uint)element()->totalRows(); i++) {
637  stream << " hSplitvar(" << i << ")=" << m_hSplitVar[i];
638  }
639 
640  if (m_vSplitVar)
641  for (uint i = 0; i < (uint)element()->totalCols(); i++) {
642  stream << " vSplitvar(" << i << ")=" << m_vSplitVar[i];
643  }
644 }
645 #endif
646 
647 /**************************************************************************************/
648 
649 RenderPart::RenderPart(DOM::HTMLElementImpl *node)
650  : RenderWidget(node)
651 {
652  // init RenderObject attributes
653  setInline(false);
654 
655  // HTMLPartContainerElementImpl does memory management, not us
656  setDoesNotOwnWidget();
657 }
658 
659 void RenderPart::setWidget(QWidget *widget)
660 {
661 #ifdef DEBUG_LAYOUT
662  // qCDebug(KHTML_LOG) << "RenderPart::setWidget()";
663 #endif
664 
665  setQWidget(widget);
666  if (widget) {
668  if (widget->inherits("KHTMLView")) {
669  connect(widget, SIGNAL(cleared()), this, SLOT(slotViewCleared()));
670  }
671  }
672 
673  setNeedsLayoutAndMinMaxRecalc();
674 
675  // make sure the scrollbars are set correctly for restore
676  // ### find better fix
677  slotViewCleared();
678 }
679 
680 short RenderPart::intrinsicWidth() const
681 {
682  return 300;
683 }
684 
685 int RenderPart::intrinsicHeight() const
686 {
687  return 150;
688 }
689 
690 void RenderPart::slotViewCleared()
691 {
692 }
693 
694 /***************************************************************************************/
695 
696 RenderFrame::RenderFrame(DOM::HTMLFrameElementImpl *frame)
697  : RenderPart(frame)
698 {
699  setInline(false);
700 }
701 
702 void RenderFrame::slotViewCleared()
703 {
704  if (QScrollArea *view = qobject_cast<QScrollArea *>(m_widget)) {
705 #ifdef DEBUG_LAYOUT
706  // qCDebug(KHTML_LOG) << "frame is a scrollarea!";
707 #endif
708  if (!element()->frameBorder || !((static_cast<HTMLFrameSetElementImpl *>(element()->parentNode()))->frameBorder())) {
710  }
711  if (KHTMLView *htmlView = qobject_cast<KHTMLView *>(view)) {
712 #ifdef DEBUG_LAYOUT
713  // qCDebug(KHTML_LOG) << "frame is a KHTMLview!";
714 #endif
715  htmlView->setVerticalScrollBarPolicy(element()->scrolling);
716  htmlView->setHorizontalScrollBarPolicy(element()->scrolling);
717  if (element()->marginWidth != -1) {
718  htmlView->setMarginWidth(element()->marginWidth);
719  }
720  if (element()->marginHeight != -1) {
721  htmlView->setMarginHeight(element()->marginHeight);
722  }
723  } else {
724  // those are no more virtual in Qt4 ;(
725  view->setVerticalScrollBarPolicy(element()->scrolling);
726  view->setHorizontalScrollBarPolicy(element()->scrolling);
727  }
728  }
729 
730 }
731 
732 /****************************************************************************************/
733 
734 RenderPartObject::RenderPartObject(DOM::HTMLElementImpl *element)
735  : RenderPart(element)
736 {
737  // init RenderObject attributes
738  setInline(true);
739 }
740 
741 void RenderPartObject::layout()
742 {
743  KHTMLAssert(needsLayout());
744  KHTMLAssert(minMaxKnown());
745 
746  calcWidth();
747  calcHeight();
748 
749  RenderPart::layout();
750 
751  setNeedsLayout(false);
752 }
753 
754 void RenderPartObject::slotViewCleared()
755 {
756  if (QScrollArea *view = qobject_cast<QScrollArea *>(m_widget)) {
757 #ifdef DEBUG_LAYOUT
758  // qCDebug(KHTML_LOG) << "iframe is a scrollview!";
759 #endif
760  int frameStyle = QFrame::NoFrame;
762  int marginw = -1;
763  int marginh = -1;
764  if (element()->id() == ID_IFRAME) {
765  HTMLIFrameElementImpl *frame = static_cast<HTMLIFrameElementImpl *>(element());
766  if (frame->frameBorder) {
767  frameStyle = QFrame::Box;
768  }
769  scroll = frame->scrolling;
770  marginw = frame->marginWidth;
771  marginh = frame->marginHeight;
772  }
773  view->setFrameStyle(frameStyle);
774  if (KHTMLView *htmlView = qobject_cast<KHTMLView *>(view)) {
775 #ifdef DEBUG_LAYOUT
776  // qCDebug(KHTML_LOG) << "frame is a KHTMLview!";
777 #endif
778  htmlView->setIgnoreWheelEvents(element()->id() == ID_IFRAME);
779  htmlView->setVerticalScrollBarPolicy(scroll);
780  htmlView->setHorizontalScrollBarPolicy(scroll);
781  if (marginw != -1) {
782  htmlView->setMarginWidth(marginw);
783  }
784  if (marginh != -1) {
785  htmlView->setMarginHeight(marginh);
786  }
787  } else {
788  // those are no more virtual in Qt4 ;(
789  view->setVerticalScrollBarPolicy(scroll);
790  view->setHorizontalScrollBarPolicy(scroll);
791  }
792 
793  }
794 }
795 
QTextStream & fixed(QTextStream &stream)
ScrollBarPolicy
WheelFocus
void setFocusPolicy(Qt::FocusPolicy policy)
This file is part of the HTML rendering engine for KDE.
Renders and displays HTML in a QScrollArea.
Definition: khtmlview.h:97
void setFrameStyle(int style)
void restoreOverrideCursor()
int visibleWidth() const
Returns the width of the viewport.
Definition: khtmlview.cpp:719
int visibleHeight() const
Returns the height of the viewport.
Definition: khtmlview.cpp:735
virtual void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
Sets vertical scrollbar mode.
Definition: khtmlview.cpp:3468
bool inherits(const char *className) const const
void setPen(const QColor &color)
void setBrush(const QBrush &brush)
ArrowCursor
void setOverrideCursor(const QCursor &cursor)
This library provides a full-featured HTML parser and widget.
virtual void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
Sets horizontal scrollbar mode.
Definition: khtmlview.cpp:3478
Base Class for all rendering tree objects.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:07 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.