File indexing completed on 2024-05-05 12:15:56
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"