1 /**
2 * This file is part of the KDE project.
3 *
4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5 * (C) 2000 Simon Hausmann <hausmann@kde.org>
6 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
7 * (C) 2003 Apple Computer, Inc.
8 * (C) 2005 Niels Leenheer <niels.leenheer@gmail.com>
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
RenderFrameSet(HTMLFrameSetElementImpl * frameSet)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
~RenderFrameSet()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
nodeAtPoint(NodeInfo & info,int _x,int _y,int _tx,int _ty,HitTestAction hitTestAction,bool inBox)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
layout()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
positionFrames()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
userResize(MouseEventImpl * evt)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);
511 QApplication::setOverrideCursor(QCursor(m_cursor));
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);
521 QApplication::restoreOverrideCursor();
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
paintFrameSetRules(QPainter * paint,const QRect & damageRect)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
setResizing(bool e)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
canResize(int _x,int _y)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
dump(QTextStream & stream,const QString & ind) const629 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
RenderPart(DOM::HTMLElementImpl * node)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
setWidget(QWidget * widget)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) {
667 widget->setFocusPolicy(Qt::WheelFocus);
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
intrinsicWidth() const680 short RenderPart::intrinsicWidth() const
681 {
682 return 300;
683 }
684
intrinsicHeight() const685 int RenderPart::intrinsicHeight() const
686 {
687 return 150;
688 }
689
slotViewCleared()690 void RenderPart::slotViewCleared()
691 {
692 }
693
694 /***************************************************************************************/
695
RenderFrame(DOM::HTMLFrameElementImpl * frame)696 RenderFrame::RenderFrame(DOM::HTMLFrameElementImpl *frame)
697 : RenderPart(frame)
698 {
699 setInline(false);
700 }
701
slotViewCleared()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())) {
709 view->setFrameStyle(QFrame::NoFrame);
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
RenderPartObject(DOM::HTMLElementImpl * element)734 RenderPartObject::RenderPartObject(DOM::HTMLElementImpl *element)
735 : RenderPart(element)
736 {
737 // init RenderObject attributes
738 setInline(true);
739 }
740
layout()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
slotViewCleared()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;
761 Qt::ScrollBarPolicy scroll = Qt::ScrollBarAsNeeded;
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
796