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