Warning, file /frameworks/khtml/src/rendering/render_frames.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /**
0002  * This file is part of the KDE project.
0003  *
0004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
0005  *           (C) 2000 Simon Hausmann <hausmann@kde.org>
0006  *           (C) 2000 Stefan Schimanski (1Stein@gmx.de)
0007  *           (C) 2003 Apple Computer, Inc.
0008  *           (C) 2005 Niels Leenheer <niels.leenheer@gmail.com>
0009  *
0010  * This library is free software; you can redistribute it and/or
0011  * modify it under the terms of the GNU Library General Public
0012  * License as published by the Free Software Foundation; either
0013  * version 2 of the License, or (at your option) any later version.
0014  *
0015  * This library is distributed in the hope that it will be useful,
0016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0018  * Library General Public License for more details.
0019  *
0020  * You should have received a copy of the GNU Library General Public License
0021  * along with this library; see the file COPYING.LIB.  If not, write to
0022  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0023  * Boston, MA 02110-1301, USA.
0024  *
0025  */
0026 //#define DEBUG_LAYOUT
0027 
0028 #include "rendering/render_frames.h"
0029 #include "rendering/render_canvas.h"
0030 #include "html/html_objectimpl.h"
0031 #include "html/htmltokenizer.h"
0032 #include "xml/dom2_eventsimpl.h"
0033 #include "xml/dom_docimpl.h"
0034 #include "khtmlview.h"
0035 #include "khtml_part.h"
0036 
0037 #include "khtml_debug.h"
0038 #include <QPainter>
0039 #include <QCursor>
0040 #include <QApplication>
0041 
0042 using namespace khtml;
0043 using namespace DOM;
0044 
0045 RenderFrameSet::RenderFrameSet(HTMLFrameSetElementImpl *frameSet)
0046     : RenderBox(frameSet)
0047 {
0048     // init RenderObject attributes
0049     setInline(false);
0050 
0051     for (int k = 0; k < 2; ++k) {
0052         m_gridLen[k] = -1;
0053         m_gridDelta[k] = nullptr;
0054         m_gridLayout[k] = nullptr;
0055     }
0056 
0057     m_resizing = m_clientresizing = false;
0058 
0059     m_cursor = Qt::ArrowCursor;
0060 
0061     m_hSplit = -1;
0062     m_vSplit = -1;
0063 
0064     m_hSplitVar = nullptr;
0065     m_vSplitVar = nullptr;
0066 }
0067 
0068 RenderFrameSet::~RenderFrameSet()
0069 {
0070     for (int k = 0; k < 2; ++k) {
0071         delete [] m_gridLayout[k];
0072         delete [] m_gridDelta[k];
0073     }
0074     delete [] m_hSplitVar;
0075     delete [] m_vSplitVar;
0076 }
0077 
0078 bool RenderFrameSet::nodeAtPoint(NodeInfo &info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction,  bool inBox)
0079 {
0080     RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inBox);
0081 
0082     bool inside = m_resizing || canResize(_x, _y);
0083 
0084     if (inside && element() && !element()->noResize() && !info.readonly()) {
0085         info.setInnerNode(element());
0086         info.setInnerNonSharedNode(element());
0087     }
0088 
0089     return inside || m_clientresizing;
0090 }
0091 
0092 void RenderFrameSet::layout()
0093 {
0094     KHTMLAssert(needsLayout());
0095     KHTMLAssert(minMaxKnown());
0096 
0097     if (!parent()->isFrameSet()) {
0098         KHTMLView *view = canvas()->view();
0099         m_width = view ? view->visibleWidth() : 0;
0100         m_height = view ? view->visibleHeight() : 0;
0101     }
0102 
0103 #ifdef DEBUG_LAYOUT
0104     // qCDebug(KHTML_LOG) << renderName() << "(FrameSet)::layout( ) width=" << width() << ", height=" << height();
0105 #endif
0106 
0107     int remainingLen[2];
0108     remainingLen[1] = m_width - (element()->totalCols() - 1) * element()->border();
0109     if (remainingLen[1] < 0) {
0110         remainingLen[1] = 0;
0111     }
0112     remainingLen[0] = m_height - (element()->totalRows() - 1) * element()->border();
0113     if (remainingLen[0] < 0) {
0114         remainingLen[0] = 0;
0115     }
0116 
0117     int availableLen[2];
0118     availableLen[0] = remainingLen[0];
0119     availableLen[1] = remainingLen[1];
0120 
0121     if (m_gridLen[0] != element()->totalRows() || m_gridLen[1] != element()->totalCols()) {
0122         // number of rows or cols changed
0123         // need to zero out the deltas
0124         m_gridLen[0] = element()->totalRows();
0125         m_gridLen[1] = element()->totalCols();
0126         for (int k = 0; k < 2; ++k) {
0127             delete [] m_gridDelta[k];
0128             m_gridDelta[k] = new int[m_gridLen[k]];
0129             delete [] m_gridLayout[k];
0130             m_gridLayout[k] = new int[m_gridLen[k]];
0131             for (int i = 0; i < m_gridLen[k]; ++i) {
0132                 m_gridDelta[k][i] = 0;
0133             }
0134         }
0135     }
0136 
0137     for (int k = 0; k < 2; ++k) {
0138         int totalRelative = 0;
0139         int totalFixed = 0;
0140         int totalPercent = 0;
0141         int countRelative = 0;
0142         int countFixed = 0;
0143         int countPercent = 0;
0144         int gridLen = m_gridLen[k];
0145         int *gridDelta = m_gridDelta[k];
0146         khtml::Length *grid =  k ? element()->m_cols : element()->m_rows;
0147         int *gridLayout = m_gridLayout[k];
0148 
0149         if (grid) {
0150             // First we need to investigate how many columns of each type we have and
0151             // how much space these columns are going to require.
0152             for (int i = 0; i < gridLen; ++i) {
0153                 // Count the total length of all of the fixed columns/rows -> totalFixed
0154                 // Count the number of columns/rows which are fixed -> countFixed
0155                 if (grid[i].isFixed()) {
0156                     gridLayout[i] = qMax(grid[i].value(), 0);
0157                     totalFixed += gridLayout[i];
0158                     countFixed++;
0159                 }
0160 
0161                 // Count the total percentage of all of the percentage columns/rows -> totalPercent
0162                 // Count the number of columns/rows which are percentages -> countPercent
0163                 if (grid[i].isPercent()) {
0164                     gridLayout[i] = qMax(grid[i].width(availableLen[k]), 0);
0165                     totalPercent += gridLayout[i];
0166                     countPercent++;
0167                 }
0168 
0169                 // Count the total relative of all the relative columns/rows -> totalRelative
0170                 // Count the number of columns/rows which are relative -> countRelative
0171                 if (grid[i].isRelative()) {
0172                     totalRelative += qMax(grid[i].value(), 1);
0173                     countRelative++;
0174                 }
0175             }
0176 
0177             // Fixed columns/rows are our first priority. If there is not enough space to fit all fixed
0178             // columns/rows we need to proportionally adjust their size.
0179             if (totalFixed > remainingLen[k]) {
0180                 int remainingFixed = remainingLen[k];
0181 
0182                 for (int i = 0; i < gridLen; ++i) {
0183                     if (grid[i].isFixed()) {
0184                         gridLayout[i] = (gridLayout[i] * remainingFixed) / totalFixed;
0185                         remainingLen[k] -= gridLayout[i];
0186                     }
0187                 }
0188             } else {
0189                 remainingLen[k] -= totalFixed;
0190             }
0191 
0192             // Percentage columns/rows are our second priority. Divide the remaining space proportionally
0193             // over all percentage columns/rows. IMPORTANT: the size of each column/row is not relative
0194             // to 100%, but to the total percentage. For example, if there are three columns, each of 75%,
0195             // and the available space is 300px, each column will become 100px in width.
0196             if (totalPercent > remainingLen[k]) {
0197                 int remainingPercent = remainingLen[k];
0198 
0199                 for (int i = 0; i < gridLen; ++i) {
0200                     if (grid[i].isPercent()) {
0201                         gridLayout[i] = (gridLayout[i] * remainingPercent) / totalPercent;
0202                         remainingLen[k] -= gridLayout[i];
0203                     }
0204                 }
0205             } else {
0206                 remainingLen[k] -= totalPercent;
0207             }
0208 
0209             // Relative columns/rows are our last priority. Divide the remaining space proportionally
0210             // over all relative columns/rows. IMPORTANT: the relative value of 0* is treated as 1*.
0211             if (countRelative) {
0212                 int lastRelative = 0;
0213                 int remainingRelative = remainingLen[k];
0214 
0215                 for (int i = 0; i < gridLen; ++i) {
0216                     if (grid[i].isRelative()) {
0217                         gridLayout[i] = (qMax(grid[i].value(), 1) * remainingRelative) / totalRelative;
0218                         remainingLen[k] -= gridLayout[i];
0219                         lastRelative = i;
0220                     }
0221                 }
0222 
0223                 // If we could not evently distribute the available space of all of the relative
0224                 // columns/rows, the remainder will be added to the last column/row.
0225                 // For example: if we have a space of 100px and three columns (*,*,*), the remainder will
0226                 // be 1px and will be added to the last column: 33px, 33px, 34px.
0227                 if (remainingLen[k]) {
0228                     gridLayout[lastRelative] += remainingLen[k];
0229                     remainingLen[k] = 0;
0230                 }
0231             }
0232 
0233             // If we still have some left over space we need to divide it over the already existing
0234             // columns/rows
0235             if (remainingLen[k]) {
0236                 // Our first priority is to spread if over the percentage columns. The remaining
0237                 // space is spread evenly, for example: if we have a space of 100px, the columns
0238                 // definition of 25%,25% used to result in two columns of 25px. After this the
0239                 // columns will each be 50px in width.
0240                 if (countPercent && totalPercent) {
0241                     int remainingPercent = remainingLen[k];
0242                     int changePercent = 0;
0243 
0244                     for (int i = 0; i < gridLen; ++i) {
0245                         if (grid[i].isPercent()) {
0246                             changePercent = (remainingPercent * gridLayout[i]) / totalPercent;
0247                             gridLayout[i] += changePercent;
0248                             remainingLen[k] -= changePercent;
0249                         }
0250                     }
0251                 } else if (totalFixed) {
0252                     // Our last priority is to spread the remaining space over the fixed columns.
0253                     // For example if we have 100px of space and two column of each 40px, both
0254                     // columns will become exactly 50px.
0255                     int remainingFixed = remainingLen[k];
0256                     int changeFixed = 0;
0257 
0258                     for (int i = 0; i < gridLen; ++i) {
0259                         if (grid[i].isFixed()) {
0260                             changeFixed = (remainingFixed * gridLayout[i]) / totalFixed;
0261                             gridLayout[i] += changeFixed;
0262                             remainingLen[k] -= changeFixed;
0263                         }
0264                     }
0265                 }
0266             }
0267 
0268             // If we still have some left over space we probably ended up with a remainder of
0269             // a division. We can not spread it evenly anymore. If we have any percentage
0270             // columns/rows simply spread the remainder equally over all available percentage columns,
0271             // regardless of their size.
0272             if (remainingLen[k] && countPercent) {
0273                 int remainingPercent = remainingLen[k];
0274                 int changePercent = 0;
0275 
0276                 for (int i = 0; i < gridLen; ++i) {
0277                     if (grid[i].isPercent()) {
0278                         changePercent = remainingPercent / countPercent;
0279                         gridLayout[i] += changePercent;
0280                         remainingLen[k] -= changePercent;
0281                     }
0282                 }
0283             }
0284 
0285             // If we don't have any percentage columns/rows we only have fixed columns. Spread
0286             // the remainder equally over all fixed columns/rows.
0287             else if (remainingLen[k] && countFixed) {
0288                 int remainingFixed = remainingLen[k];
0289                 int changeFixed = 0;
0290 
0291                 for (int i = 0; i < gridLen; ++i) {
0292                     if (grid[i].isFixed()) {
0293                         changeFixed = remainingFixed / countFixed;
0294                         gridLayout[i] += changeFixed;
0295                         remainingLen[k] -= changeFixed;
0296                     }
0297                 }
0298             }
0299 
0300             // Still some left over... simply add it to the last column, because it is impossible
0301             // spread it evenly or equally.
0302             if (remainingLen[k]) {
0303                 gridLayout[gridLen - 1] += remainingLen[k];
0304             }
0305 
0306             // now we have the final layout, distribute the delta over it
0307             bool worked = true;
0308             for (int i = 0; i < gridLen; ++i) {
0309                 if (gridLayout[i] && gridLayout[i] + gridDelta[i] <= 0) {
0310                     worked = false;
0311                 }
0312                 gridLayout[i] += gridDelta[i];
0313             }
0314             // now the delta's broke something, undo it and reset deltas
0315             if (!worked)
0316                 for (int i = 0; i < gridLen; ++i) {
0317                     gridLayout[i] -= gridDelta[i];
0318                     gridDelta[i] = 0;
0319                 }
0320         } else {
0321             gridLayout[0] = remainingLen[k];
0322         }
0323     }
0324 
0325     positionFrames();
0326 
0327     RenderObject *child = firstChild();
0328     if (!child) {
0329         goto end2;
0330     }
0331 
0332     if (!m_hSplitVar && !m_vSplitVar) {
0333 #ifdef DEBUG_LAYOUT
0334         // qCDebug(KHTML_LOG) << "calculationg fixed Splitters";
0335 #endif
0336         if (!m_vSplitVar && element()->totalCols() > 1) {
0337             m_vSplitVar = new bool[element()->totalCols()];
0338             for (int i = 0; i < element()->totalCols(); i++) {
0339                 m_vSplitVar[i] = true;
0340             }
0341         }
0342         if (!m_hSplitVar && element()->totalRows() > 1) {
0343             m_hSplitVar = new bool[element()->totalRows()];
0344             for (int i = 0; i < element()->totalRows(); i++) {
0345                 m_hSplitVar[i] = true;
0346             }
0347         }
0348 
0349         for (int r = 0; r < element()->totalRows(); r++) {
0350             for (int c = 0; c < element()->totalCols(); c++) {
0351                 bool fixed = false;
0352 
0353                 if (child->isFrameSet()) {
0354                     fixed = static_cast<RenderFrameSet *>(child)->element()->noResize();
0355                 } else {
0356                     fixed = static_cast<RenderFrame *>(child)->element()->noResize();
0357                 }
0358 
0359                 if (fixed) {
0360 #ifdef DEBUG_LAYOUT
0361                     // qCDebug(KHTML_LOG) << "found fixed cell " << r << "/" << c << "!";
0362 #endif
0363                     if (element()->totalCols() > 1) {
0364                         if (c > 0) {
0365                             m_vSplitVar[c - 1] = false;
0366                         }
0367                         m_vSplitVar[c] = false;
0368                     }
0369                     if (element()->totalRows() > 1) {
0370                         if (r > 0) {
0371                             m_hSplitVar[r - 1] = false;
0372                         }
0373                         m_hSplitVar[r] = false;
0374                     }
0375                     child = child->nextSibling();
0376                     if (!child) {
0377                         goto end2;
0378                     }
0379                 }
0380 #ifdef DEBUG_LAYOUT
0381                 else
0382                     // qCDebug(KHTML_LOG) << "not fixed: " << r << "/" << c << "!";
0383 #endif
0384                 }
0385         }
0386 
0387     }
0388     RenderContainer::layout();
0389 end2:
0390     setNeedsLayout(false);
0391 }
0392 
0393 void RenderFrameSet::positionFrames()
0394 {
0395     int r;
0396     int c;
0397 
0398     RenderObject *child = firstChild();
0399     if (!child) {
0400         return;
0401     }
0402 
0403     //  NodeImpl *child = _first;
0404     //  if(!child) return;
0405 
0406     int yPos = 0;
0407 
0408     for (r = 0; r < element()->totalRows(); r++) {
0409         int xPos = 0;
0410         for (c = 0; c < element()->totalCols(); c++) {
0411             child->setPos(xPos, yPos);
0412 #ifdef DEBUG_LAYOUT
0413             // qCDebug(KHTML_LOG) << "child frame at (" << xPos << "/" << yPos << ") size (" << m_gridLayout[1][c] << "/" << m_gridLayout[0][r] << ")";
0414 #endif
0415             // has to be resized and itself resize its contents
0416             if ((m_gridLayout[1][c] != child->width()) || (m_gridLayout[0][r] != child->height())) {
0417                 child->setWidth(m_gridLayout[1][c]);
0418                 child->setHeight(m_gridLayout[0][r]);
0419                 child->setNeedsLayout(true);
0420                 child->layout();
0421             }
0422 
0423             xPos += m_gridLayout[1][c] + element()->border();
0424             child = child->nextSibling();
0425 
0426             if (!child) {
0427                 return;
0428             }
0429 
0430         }
0431 
0432         yPos += m_gridLayout[0][r] + element()->border();
0433     }
0434 
0435     // all the remaining frames are hidden to avoid ugly
0436     // spurious unflowed frames
0437     while (child) {
0438         child->setWidth(0);
0439         child->setHeight(0);
0440         child->setNeedsLayout(false);
0441 
0442         child = child->nextSibling();
0443     }
0444 }
0445 
0446 bool RenderFrameSet::userResize(MouseEventImpl *evt)
0447 {
0448     if (needsLayout()) {
0449         return false;
0450     }
0451 
0452     bool res = false;
0453     int _x = evt->clientX();
0454     int _y = evt->clientY();
0455 
0456     if ((!m_resizing && evt->id() == EventImpl::MOUSEMOVE_EVENT) || evt->id() == EventImpl::MOUSEDOWN_EVENT) {
0457 #ifdef DEBUG_LAYOUT
0458         // qCDebug(KHTML_LOG) << "mouseEvent:check";
0459 #endif
0460 
0461         m_hSplit = -1;
0462         m_vSplit = -1;
0463 
0464         // check if we're over a horizontal or vertical boundary
0465         int pos = m_gridLayout[1][0] + xPos();
0466         for (int c = 1; c < element()->totalCols(); c++) {
0467             if (_x >= pos && _x <= pos + element()->border()) {
0468                 if (m_vSplitVar && m_vSplitVar[c - 1] == true) {
0469                     m_vSplit = c - 1;
0470                 }
0471 #ifdef DEBUG_LAYOUT
0472                 // qCDebug(KHTML_LOG) << "vsplit!";
0473 #endif
0474                 res = true;
0475                 break;
0476             }
0477             pos += m_gridLayout[1][c] + element()->border();
0478         }
0479 
0480         pos = m_gridLayout[0][0] + yPos();
0481         for (int r = 1; r < element()->totalRows(); r++) {
0482             if (_y >= pos && _y <= pos + element()->border()) {
0483                 if (m_hSplitVar && m_hSplitVar[r - 1] == true) {
0484                     m_hSplit = r - 1;
0485                 }
0486 #ifdef DEBUG_LAYOUT
0487                 // qCDebug(KHTML_LOG) << "hsplitvar = " << m_hSplitVar;
0488                 // qCDebug(KHTML_LOG) << "hsplit!";
0489 #endif
0490                 res = true;
0491                 break;
0492             }
0493             pos += m_gridLayout[0][r] + element()->border();
0494         }
0495 #ifdef DEBUG_LAYOUT
0496         // qCDebug(KHTML_LOG) << m_hSplit << "/" << m_vSplit;
0497 #endif
0498     }
0499 
0500     m_cursor = Qt::ArrowCursor;
0501     if (m_hSplit != -1 && m_vSplit != -1) {
0502         m_cursor = Qt::SizeAllCursor;
0503     } else if (m_vSplit != -1) {
0504         m_cursor = Qt::SizeHorCursor;
0505     } else if (m_hSplit != -1) {
0506         m_cursor = Qt::SizeVerCursor;
0507     }
0508 
0509     if (!m_resizing && evt->id() == EventImpl::MOUSEDOWN_EVENT) {
0510         setResizing(true);
0511         QApplication::setOverrideCursor(QCursor(m_cursor));
0512         m_vSplitPos = _x;
0513         m_hSplitPos = _y;
0514         m_oldpos = -1;
0515     }
0516 
0517     // ### check the resize is not going out of bounds.
0518     if (m_resizing) {
0519         if (evt->id() == EventImpl::MOUSEUP_EVENT) {
0520             setResizing(false);
0521             QApplication::restoreOverrideCursor();
0522         }
0523 
0524         if (m_vSplit != -1) {
0525 #ifdef DEBUG_LAYOUT
0526             // qCDebug(KHTML_LOG) << "split xpos=" << _x;
0527 #endif
0528             int delta = m_vSplitPos - _x;
0529             m_gridDelta[1][m_vSplit] -= delta;
0530             m_gridDelta[1][m_vSplit + 1] += delta;
0531             m_vSplitPos = _x;
0532         }
0533         if (m_hSplit != -1) {
0534 #ifdef DEBUG_LAYOUT
0535             // qCDebug(KHTML_LOG) << "split ypos=" << _y;
0536 #endif
0537             int delta = m_hSplitPos - _y;
0538             m_gridDelta[0][m_hSplit] -= delta;
0539             m_gridDelta[0][m_hSplit + 1] += delta;
0540             m_hSplitPos = _y;
0541         }
0542 
0543         // this just schedules the relayout
0544         // important, otherwise the moving indicator is not correctly erased
0545         setNeedsLayout(true);
0546     }
0547 
0548     /*
0549       KHTMLView *view = canvas()->view();
0550       if ((m_resizing || evt->id() == EventImpl::MOUSEUP_EVENT) && view) {
0551           QPainter paint( view );
0552           paint.setPen( Qt::gray );
0553           paint.setBrush( Qt::gray );
0554           paint.setCompositionMode(QPainter::CompositionMode_Xor);
0555           QRect r(xPos(), yPos(), width(), height());
0556           const int rBord = 3;
0557           int sw = element()->border();
0558           int p = m_resizing ? (m_vSplit > -1 ? _x : _y) : -1;
0559           if (m_vSplit > -1) {
0560               if ( m_oldpos >= 0 )
0561                   paint.drawRect( m_oldpos + sw/2 - rBord , r.y(),
0562                                   2*rBord, r.height() );
0563               if ( p >= 0 )
0564                   paint.drawRect( p  + sw/2 - rBord, r.y(), 2*rBord, r.height() );
0565           } else {
0566               if ( m_oldpos >= 0 )
0567                   paint.drawRect( r.x(), m_oldpos + sw/2 - rBord,
0568                                   r.width(), 2*rBord );
0569               if ( p >= 0 )
0570                   paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
0571           }
0572           m_oldpos = p;
0573       }
0574     */
0575     return res;
0576 }
0577 
0578 void RenderFrameSet::paintFrameSetRules(QPainter *paint, const QRect &damageRect)
0579 {
0580     Q_UNUSED(damageRect);
0581     KHTMLView *view = canvas()->view();
0582     if (view && !noResize()) {
0583         paint->setPen(Qt::gray);
0584         paint->setBrush(Qt::gray);
0585         const int rBord = 3;
0586         int sw = element()->border();
0587 
0588         // ### implement me
0589 
0590         (void) rBord;
0591         (void) sw;
0592     }
0593 
0594 }
0595 
0596 void RenderFrameSet::setResizing(bool e)
0597 {
0598     m_resizing = e;
0599     for (RenderObject *p = parent(); p; p = p->parent())
0600         if (p->isFrameSet()) {
0601             static_cast<RenderFrameSet *>(p)->m_clientresizing = m_resizing;
0602         }
0603 }
0604 
0605 bool RenderFrameSet::canResize(int _x, int _y)
0606 {
0607     // if we haven't received a layout, then the gridLayout doesn't contain useful data yet
0608     if (needsLayout() || !m_gridLayout[0] || !m_gridLayout[1]) {
0609         return false;
0610     }
0611 
0612     // check if we're over a horizontal or vertical boundary
0613     int pos = m_gridLayout[1][0];
0614     for (int c = 1; c < element()->totalCols(); c++)
0615         if (_x >= pos && _x <= pos + element()->border()) {
0616             return true;
0617         }
0618 
0619     pos = m_gridLayout[0][0];
0620     for (int r = 1; r < element()->totalRows(); r++)
0621         if (_y >= pos && _y <= pos + element()->border()) {
0622             return true;
0623         }
0624 
0625     return false;
0626 }
0627 
0628 #ifdef ENABLE_DUMP
0629 void RenderFrameSet::dump(QTextStream &stream, const QString &ind) const
0630 {
0631     RenderBox::dump(stream, ind);
0632     stream << " totalrows=" << element()->totalRows();
0633     stream << " totalcols=" << element()->totalCols();
0634 
0635     if (m_hSplitVar)
0636         for (uint i = 0; i < (uint)element()->totalRows(); i++) {
0637             stream << " hSplitvar(" << i << ")=" << m_hSplitVar[i];
0638         }
0639 
0640     if (m_vSplitVar)
0641         for (uint i = 0; i < (uint)element()->totalCols(); i++) {
0642             stream << " vSplitvar(" << i << ")=" << m_vSplitVar[i];
0643         }
0644 }
0645 #endif
0646 
0647 /**************************************************************************************/
0648 
0649 RenderPart::RenderPart(DOM::HTMLElementImpl *node)
0650     : RenderWidget(node)
0651 {
0652     // init RenderObject attributes
0653     setInline(false);
0654 
0655     // HTMLPartContainerElementImpl does memory management, not us
0656     setDoesNotOwnWidget();
0657 }
0658 
0659 void RenderPart::setWidget(QWidget *widget)
0660 {
0661 #ifdef DEBUG_LAYOUT
0662     // qCDebug(KHTML_LOG) << "RenderPart::setWidget()";
0663 #endif
0664 
0665     setQWidget(widget);
0666     if (widget) {
0667         widget->setFocusPolicy(Qt::WheelFocus);
0668         if (widget->inherits("KHTMLView")) {
0669             connect(widget, SIGNAL(cleared()), this, SLOT(slotViewCleared()));
0670         }
0671     }
0672 
0673     setNeedsLayoutAndMinMaxRecalc();
0674 
0675     // make sure the scrollbars are set correctly for restore
0676     // ### find better fix
0677     slotViewCleared();
0678 }
0679 
0680 short RenderPart::intrinsicWidth() const
0681 {
0682     return 300;
0683 }
0684 
0685 int RenderPart::intrinsicHeight() const
0686 {
0687     return 150;
0688 }
0689 
0690 void RenderPart::slotViewCleared()
0691 {
0692 }
0693 
0694 /***************************************************************************************/
0695 
0696 RenderFrame::RenderFrame(DOM::HTMLFrameElementImpl *frame)
0697     : RenderPart(frame)
0698 {
0699     setInline(false);
0700 }
0701 
0702 void RenderFrame::slotViewCleared()
0703 {
0704     if (QScrollArea *view = qobject_cast<QScrollArea *>(m_widget)) {
0705 #ifdef DEBUG_LAYOUT
0706         // qCDebug(KHTML_LOG) << "frame is a scrollarea!";
0707 #endif
0708         if (!element()->frameBorder || !((static_cast<HTMLFrameSetElementImpl *>(element()->parentNode()))->frameBorder())) {
0709             view->setFrameStyle(QFrame::NoFrame);
0710         }
0711         if (KHTMLView *htmlView = qobject_cast<KHTMLView *>(view)) {
0712 #ifdef DEBUG_LAYOUT
0713             // qCDebug(KHTML_LOG) << "frame is a KHTMLview!";
0714 #endif
0715             htmlView->setVerticalScrollBarPolicy(element()->scrolling);
0716             htmlView->setHorizontalScrollBarPolicy(element()->scrolling);
0717             if (element()->marginWidth != -1) {
0718                 htmlView->setMarginWidth(element()->marginWidth);
0719             }
0720             if (element()->marginHeight != -1) {
0721                 htmlView->setMarginHeight(element()->marginHeight);
0722             }
0723         } else {
0724             // those are no more virtual in Qt4 ;(
0725             view->setVerticalScrollBarPolicy(element()->scrolling);
0726             view->setHorizontalScrollBarPolicy(element()->scrolling);
0727         }
0728     }
0729 
0730 }
0731 
0732 /****************************************************************************************/
0733 
0734 RenderPartObject::RenderPartObject(DOM::HTMLElementImpl *element)
0735     : RenderPart(element)
0736 {
0737     // init RenderObject attributes
0738     setInline(true);
0739 }
0740 
0741 void RenderPartObject::layout()
0742 {
0743     KHTMLAssert(needsLayout());
0744     KHTMLAssert(minMaxKnown());
0745 
0746     calcWidth();
0747     calcHeight();
0748 
0749     RenderPart::layout();
0750 
0751     setNeedsLayout(false);
0752 }
0753 
0754 void RenderPartObject::slotViewCleared()
0755 {
0756     if (QScrollArea *view = qobject_cast<QScrollArea *>(m_widget)) {
0757 #ifdef DEBUG_LAYOUT
0758         // qCDebug(KHTML_LOG) << "iframe is a scrollview!";
0759 #endif
0760         int frameStyle = QFrame::NoFrame;
0761         Qt::ScrollBarPolicy scroll = Qt::ScrollBarAsNeeded;
0762         int marginw = -1;
0763         int marginh = -1;
0764         if (element()->id() == ID_IFRAME) {
0765             HTMLIFrameElementImpl *frame = static_cast<HTMLIFrameElementImpl *>(element());
0766             if (frame->frameBorder) {
0767                 frameStyle = QFrame::Box;
0768             }
0769             scroll = frame->scrolling;
0770             marginw = frame->marginWidth;
0771             marginh = frame->marginHeight;
0772         }
0773         view->setFrameStyle(frameStyle);
0774         if (KHTMLView *htmlView = qobject_cast<KHTMLView *>(view)) {
0775 #ifdef DEBUG_LAYOUT
0776             // qCDebug(KHTML_LOG) << "frame is a KHTMLview!";
0777 #endif
0778             htmlView->setIgnoreWheelEvents(element()->id() == ID_IFRAME);
0779             htmlView->setVerticalScrollBarPolicy(scroll);
0780             htmlView->setHorizontalScrollBarPolicy(scroll);
0781             if (marginw != -1) {
0782                 htmlView->setMarginWidth(marginw);
0783             }
0784             if (marginh != -1) {
0785                 htmlView->setMarginHeight(marginh);
0786             }
0787         } else {
0788             // those are no more virtual in Qt4 ;(
0789             view->setVerticalScrollBarPolicy(scroll);
0790             view->setHorizontalScrollBarPolicy(scroll);
0791         }
0792 
0793     }
0794 }
0795 
0796 #include "moc_render_frames.cpp"