# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# render_frames.cpp

    00001
    00025 //#define DEBUG_LAYOUT
    00026
    00027 #include "rendering/render_frames.h"
    00028 #include "rendering/render_root.h"
    00029 #include "html/html_baseimpl.h"
    00030 #include "html/html_objectimpl.h"
    00031 #include "html/htmltokenizer.h"
    00032 #include "misc/htmlattrs.h"
    00033 #include "xml/dom2_eventsimpl.h"
    00034 #include "xml/dom_docimpl.h"
    00035 #include "css/csshelper.h"
    00036 #include "misc/htmltags.h"
    00037 #include "khtmlview.h"
    00038 #include "khtml_part.h"
    00039
    00040 #include <kapplication.h>
    00041 #include <kmessagebox.h>
    00042 #include <kmimetype.h>
    00043 #include <klocale.h>
    00044 #include <kdebug.h>
    00045 #include <qtimer.h>
    00046 #include <qpainter.h>
    00047 #include <qcursor.h>
    00048
    00049 #include <assert.h>
    00050
    00051 using namespace khtml;
    00052 using namespace DOM;
    00053
    00054 RenderFrameSet::RenderFrameSet( HTMLFrameSetElementImpl *frameSet)
    00055     : RenderBox(frameSet)
    00056 {
    00057   // init RenderObject attributes
    00058     setInline(false);
    00059
    00060   for (int k = 0; k < 2; ++k) {
    00061       m_gridLen[k] = -1;
    00062       m_gridDelta[k] = 0;
    00063       m_gridLayout[k] = 0;
    00064   }
    00065
    00066   m_resizing = m_clientresizing= false;
    00067
    00068   m_cursor = Qt::ArrowCursor;
    00069
    00070   m_hSplit = -1;
    00071   m_vSplit = -1;
    00072
    00073   m_hSplitVar = 0;
    00074   m_vSplitVar = 0;
    00075 }
    00076
    00077 RenderFrameSet::~RenderFrameSet()
    00078 {
    00079     for (int k = 0; k < 2; ++k) {
    00080         if (m_gridLayout[k]) delete [] m_gridLayout[k];
    00081         if (m_gridDelta[k]) delete [] m_gridDelta[k];
    00082     }
    00083   if (m_hSplitVar)
    00084       delete [] m_hSplitVar;
    00085   if (m_vSplitVar)
    00086       delete [] m_vSplitVar;
    00087 }
    00088
    00089 bool RenderFrameSet::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty)
    00090 {
    00091     RenderBox::nodeAtPoint(info, _x, _y, _tx, _ty);
    00092
    00093     bool inside = m_resizing || canResize(_x, _y);
    00094
    00095     if ( inside && element() && !element()->noResize() && !info.readonly())
    00096         info.setInnerNode(element());
    00097
    00098     return inside || m_clientresizing;
    00099 }
    00100
    00101 void RenderFrameSet::layout( )
    00102 {
    00103     KHTMLAssert( !layouted() );
    00104     KHTMLAssert( minMaxKnown() );
    00105
    00106     if ( !parent()->isFrameSet() ) {
    00107         KHTMLView* view = root()->view();
    00108         m_width = view->visibleWidth();
    00109         m_height = view->visibleHeight();
    00110     }
    00111
    00112 #ifdef DEBUG_LAYOUT
    00113     kdDebug( 6040 ) << renderName() << "(FrameSet)::layout( ) width=" << width() << ", height=" << height() << endl;
    00114 #endif
    00115
    00116     int remainingLen[2];
    00117     remainingLen[1] = m_width - (element()->totalCols()-1)*element()->border();
    00118     if(remainingLen[1]<0) remainingLen[1]=0;
    00119     remainingLen[0] = m_height - (element()->totalRows()-1)*element()->border();
    00120     if(remainingLen[0]<0) remainingLen[0]=0;
    00121
    00122     int availableLen[2];
    00123     availableLen[0] = remainingLen[0];
    00124     availableLen[1] = remainingLen[1];
    00125
    00126     if (m_gridLen[0] != element()->totalRows() || m_gridLen[1] != element()->totalCols()) {
    00127         // number of rows or cols changed
    00128         // need to zero out the deltas
    00129         m_gridLen[0] = element()->totalRows();
    00130         m_gridLen[1] = element()->totalCols();
    00131         for (int k = 0; k < 2; ++k) {
    00132             if (m_gridDelta[k]) delete [] m_gridDelta[k];
    00133             m_gridDelta[k] = new int[m_gridLen[k]];
    00134             if (m_gridLayout[k]) delete [] m_gridLayout[k];
    00135             m_gridLayout[k] = new int[m_gridLen[k]];
    00136             for (int i = 0; i < m_gridLen[k]; ++i)
    00137                 m_gridDelta[k][i] = 0;
    00138         }
    00139     }
    00140
    00141     for (int k = 0; k < 2; ++k) {
    00142         int totalRelative = 0;
    00143         int totalFixed = 0;
    00144         int totalPercent = 0;
    00145         int countRelative = 0;
    00146         int countPercent = 0;
    00147         int gridLen = m_gridLen[k];
    00148         int* gridDelta = m_gridDelta[k];
    00149         khtml::Length* grid =  k ? element()->m_cols : element()->m_rows;
    00150         int* gridLayout = m_gridLayout[k];
    00151
    00152         if (grid) {
    00153             // first distribute the available width for fixed rows, then handle the
    00154             // percentage ones and distribute remaining over relative
    00155             for(int i = 0; i< gridLen; ++i)
    00156                 if (grid[i].isFixed()) {
    00157                     gridLayout[i] = kMin(grid[i].value() > 0 ? grid[i].value() : 0, remainingLen[k]);
    00158                     remainingLen[k] -= gridLayout[i];
    00159                     totalFixed += gridLayout[i];
    00160                 }
    00161                 else if(grid[i].isRelative()) {
    00162                     totalRelative += grid[i].value() > 1 ? grid[i].value() : 1;
    00163                     countRelative++;
    00164                 }
    00165
    00166             for(int i = 0; i < gridLen; i++)
    00167                 if(grid[i].isPercent()) {
    00168                     gridLayout[i] = kMin(kMax(grid[i].width(availableLen[k]), 0), remainingLen[k]);
    00169                     remainingLen[k] -= gridLayout[i];
    00170                     totalPercent += grid[i].value();
    00171                     countPercent++;
    00172                 }
    00173
    00174             assert(remainingLen[k] >= 0);
    00175
    00176             if (countRelative) {
    00177                 int remaining = remainingLen[k];
    00178                 for (int i = 0; i < gridLen; ++i)
    00179                     if (grid[i].isRelative()) {
    00180                         gridLayout[i] = ((grid[i].value() > 1 ? grid[i].value() : 1) * remaining) / totalRelative;
    00181                         remainingLen[k] -= gridLayout[i];
    00182                     }
    00183             }
    00184
    00185             // distribute the rest
    00186             if (remainingLen[k]) {
    00187                 LengthType distributeType = countPercent ? Percent : Fixed;
    00188                 int total = countPercent ? totalPercent : totalFixed;
    00189                 if (!total) total = 1;
    00190                 for (int i = 0; i < gridLen; ++i)
    00191                     if (grid[i].type() == distributeType) {
    00192                         int toAdd = (remainingLen[k] * grid[i].value()) / total;
    00193                         gridLayout[i] += toAdd;
    00194                     }
    00195             }
    00196
    00197             // now we have the final layout, distribute the delta over it
    00198             bool worked = true;
    00199             for (int i = 0; i < gridLen; ++i) {
    00200                 if (gridLayout[i] && gridLayout[i] + gridDelta[i] <= 0)
    00201                     worked = false;
    00202                 gridLayout[i] += gridDelta[i];
    00203             }
    00204             // now the delta's broke something, undo it and reset deltas
    00205             if (!worked)
    00206                 for (int i = 0; i < gridLen; ++i) {
    00207                     gridLayout[i] -= gridDelta[i];
    00208                     gridDelta[i] = 0;
    00209                 }
    00210         }
    00211         else
    00212             gridLayout[0] = remainingLen[k];
    00213     }
    00214
    00215     positionFrames();
    00216
    00217     RenderObject *child = firstChild();
    00218     if ( !child )
    00219       return;
    00220
    00221     if(!m_hSplitVar && !m_vSplitVar)
    00222     {
    00223 #ifdef DEBUG_LAYOUT
    00224         kdDebug( 6031 ) << "calculationg fixed Splitters" << endl;
    00225 #endif
    00226         if(!m_vSplitVar && element()->totalCols() > 1)
    00227         {
    00228             m_vSplitVar = new bool[element()->totalCols()];
    00229             for(int i = 0; i < element()->totalCols(); i++) m_vSplitVar[i] = true;
    00230         }
    00231         if(!m_hSplitVar && element()->totalRows() > 1)
    00232         {
    00233             m_hSplitVar = new bool[element()->totalRows()];
    00234             for(int i = 0; i < element()->totalRows(); i++) m_hSplitVar[i] = true;
    00235         }
    00236
    00237         for(int r = 0; r < element()->totalRows(); r++)
    00238         {
    00239             for(int c = 0; c < element()->totalCols(); c++)
    00240             {
    00241                 bool fixed = false;
    00242
    00243                 if ( child->isFrameSet() )
    00244                   fixed = static_cast<RenderFrameSet *>(child)->element()->noResize();
    00245                 else
    00246                   fixed = static_cast<RenderFrame *>(child)->element()->noResize();
    00247
    00248                 if(fixed)
    00249                 {
    00250 #ifdef DEBUG_LAYOUT
    00251                     kdDebug( 6031 ) << "found fixed cell " << r << "/" << c << "!" << endl;
    00252 #endif
    00253                     if( element()->totalCols() > 1)
    00254                     {
    00255                         if(c>0) m_vSplitVar[c-1] = false;
    00256                         m_vSplitVar[c] = false;
    00257                     }
    00258                     if( element()->totalRows() > 1)
    00259                     {
    00260                         if(r>0) m_hSplitVar[r-1] = false;
    00261                         m_hSplitVar[r] = false;
    00262                     }
    00263                     child = child->nextSibling();
    00264                     if(!child) goto end2;
    00265                 }
    00266 #ifdef DEBUG_LAYOUT
    00267                 else
    00268                     kdDebug( 6031 ) << "not fixed: " << r << "/" << c << "!" << endl;
    00269 #endif
    00270             }
    00271         }
    00272
    00273     }
    00274     RenderContainer::layout();
    00275  end2:
    00276     setLayouted();
    00277 }
    00278
    00279 void RenderFrameSet::positionFrames()
    00280 {
    00281   int r;
    00282   int c;
    00283
    00284   RenderObject *child = firstChild();
    00285   if ( !child )
    00286     return;
    00287
    00288   //  NodeImpl *child = _first;
    00289   //  if(!child) return;
    00290
    00291   int yPos = 0;
    00292
    00293   for(r = 0; r < element()->totalRows(); r++)
    00294   {
    00295     int xPos = 0;
    00296     for(c = 0; c < element()->totalCols(); c++)
    00297     {
    00298       child->setPos( xPos, yPos );
    00299 #ifdef DEBUG_LAYOUT
    00300       kdDebug(6040) << "child frame at (" << xPos << "/" << yPos << ") size (" << m_gridLayout[1][c] << "/" << m_gridLayout[0][r] << ")" << endl;
    00301 #endif
    00302       // has to be resized and itself resize its contents
    00303       if ((m_gridLayout[1][c] != child->width()) || (m_gridLayout[0][r] != child->height())) {
    00304           child->setWidth( m_gridLayout[1][c] );
    00305           child->setHeight( m_gridLayout[0][r] );
    00306           child->setLayouted(false);
    00307           child->layout();
    00308       }
    00309
    00310       xPos += m_gridLayout[1][c] + element()->border();
    00311       child = child->nextSibling();
    00312
    00313       if ( !child )
    00314         return;
    00315
    00316     }
    00317
    00318     yPos += m_gridLayout[0][r] + element()->border();
    00319   }
    00320
    00321   // all the remaining frames are hidden to avoid ugly
    00322   // spurious nonlayouted frames
    00323   while ( child ) {
    00324       child->setWidth( 0 );
    00325       child->setHeight( 0 );
    00326       child->setLayouted();
    00327
    00328       child = child->nextSibling();
    00329   }
    00330 }
    00331
    00332 bool RenderFrameSet::userResize( MouseEventImpl *evt )
    00333 {
    00334     if (!layouted()) return false;
    00335
    00336   bool res = false;
    00337   int _x = evt->clientX();
    00338   int _y = evt->clientY();
    00339
    00340   if ( !m_resizing && evt->id() == EventImpl::MOUSEMOVE_EVENT || evt->id() == EventImpl::MOUSEDOWN_EVENT )
    00341   {
    00342 #ifdef DEBUG_LAYOUT
    00343     kdDebug( 6031 ) << "mouseEvent:check" << endl;
    00344 #endif
    00345
    00346     m_hSplit = -1;
    00347     m_vSplit = -1;
    00348     //bool resizePossible = true;
    00349
    00350     // check if we're over a horizontal or vertical boundary
    00351     int pos = m_gridLayout[1][0] + xPos();
    00352     for(int c = 1; c < element()->totalCols(); c++)
    00353     {
    00354       if(_x >= pos && _x <= pos+element()->border())
    00355       {
    00356         if(m_vSplitVar && m_vSplitVar[c-1] == true) m_vSplit = c-1;
    00357 #ifdef DEBUG_LAYOUT
    00358         kdDebug( 6031 ) << "vsplit!" << endl;
    00359 #endif
    00360         res = true;
    00361         break;
    00362       }
    00363       pos += m_gridLayout[1][c] + element()->border();
    00364     }
    00365
    00366     pos = m_gridLayout[0][0] + yPos();
    00367     for(int r = 1; r < element()->totalRows(); r++)
    00368     {
    00369       if( _y >= pos && _y <= pos+element()->border())
    00370       {
    00371         if(m_hSplitVar && m_hSplitVar[r-1] == true) m_hSplit = r-1;
    00372 #ifdef DEBUG_LAYOUT
    00373         kdDebug( 6031 ) << "hsplitvar = " << m_hSplitVar << endl;
    00374         kdDebug( 6031 ) << "hsplit!" << endl;
    00375 #endif
    00376         res = true;
    00377         break;
    00378       }
    00379       pos += m_gridLayout[0][r] + element()->border();
    00380     }
    00381 #ifdef DEBUG_LAYOUT
    00382     kdDebug( 6031 ) << m_hSplit << "/" << m_vSplit << endl;
    00383 #endif
    00384   }
    00385
    00386
    00387   m_cursor = Qt::ArrowCursor;
    00388   if(m_hSplit != -1 && m_vSplit != -1)
    00389       m_cursor = Qt::SizeAllCursor;
    00390   else if( m_vSplit != -1 )
    00391       m_cursor = Qt::SizeHorCursor;
    00392   else if( m_hSplit != -1 )
    00393       m_cursor = Qt::SizeVerCursor;
    00394
    00395   if(!m_resizing && evt->id() == EventImpl::MOUSEDOWN_EVENT)
    00396   {
    00397       setResizing(true);
    00398       KApplication::setOverrideCursor(QCursor(m_cursor));
    00399       m_vSplitPos = _x;
    00400       m_hSplitPos = _y;
    00401       m_oldpos = -1;
    00402   }
    00403
    00404   // ### check the resize is not going out of bounds.
    00405   if(m_resizing && evt->id() == EventImpl::MOUSEUP_EVENT)
    00406   {
    00407     setResizing(false);
    00408     KApplication::restoreOverrideCursor();
    00409
    00410     if(m_vSplit != -1 )
    00411     {
    00412 #ifdef DEBUG_LAYOUT
    00413       kdDebug( 6031 ) << "split xpos=" << _x << endl;
    00414 #endif
    00415       int delta = m_vSplitPos - _x;
    00416       m_gridDelta[1][m_vSplit] -= delta;
    00417       m_gridDelta[1][m_vSplit+1] += delta;
    00418     }
    00419     if(m_hSplit != -1 )
    00420     {
    00421 #ifdef DEBUG_LAYOUT
    00422       kdDebug( 6031 ) << "split ypos=" << _y << endl;
    00423 #endif
    00424       int delta = m_hSplitPos - _y;
    00425       m_gridDelta[0][m_hSplit] -= delta;
    00426       m_gridDelta[0][m_hSplit+1] += delta;
    00427     }
    00428
    00429     // this just schedules the relayout
    00430     // important, otherwise the moving indicator is not correctly erased
    00431     setLayouted(false);
    00432   }
    00433
    00434   if (m_resizing || evt->id() == EventImpl::MOUSEUP_EVENT) {
    00435       QPainter paint( root()->view() );
    00436       paint.setPen( Qt::gray );
    00437       paint.setBrush( Qt::gray );
    00438       paint.setRasterOp( Qt::XorROP );
    00439       QRect r(xPos(), yPos(), width(), height());
    00440       const int rBord = 3;
    00441       int sw = element()->border();
    00442       int p = m_resizing ? (m_vSplit > -1 ? _x : _y) : -1;
    00443       if (m_vSplit > -1) {
    00444           if ( m_oldpos >= 0 )
    00445               paint.drawRect( m_oldpos + sw/2 - rBord , r.y(),
    00446                               2*rBord, r.height() );
    00447           if ( p >= 0 )
    00448               paint.drawRect( p  + sw/2 - rBord, r.y(), 2*rBord, r.height() );
    00449       } else {
    00450           if ( m_oldpos >= 0 )
    00451               paint.drawRect( r.x(), m_oldpos + sw/2 - rBord,
    00452                               r.width(), 2*rBord );
    00453           if ( p >= 0 )
    00454               paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
    00455       }
    00456       m_oldpos = p;
    00457   }
    00458
    00459   return res;
    00460 }
    00461
    00462 void RenderFrameSet::setResizing(bool e)
    00463 {
    00464       m_resizing = e;
    00465       for (RenderObject* p = parent(); p; p = p->parent())
    00466           if (p->isFrameSet()) static_cast<RenderFrameSet*>(p)->m_clientresizing = m_resizing;
    00467 }
    00468
    00469 bool RenderFrameSet::canResize( int _x, int _y )
    00470 {
    00471     // if we're not layouted, the gridLayout doesn't contain useful data
    00472     if (!layouted() || !m_gridLayout[0] || !m_gridLayout[1] ) return false;
    00473
    00474     // check if we're over a horizontal or vertical boundary
    00475     int pos = m_gridLayout[1][0];
    00476     for(int c = 1; c < element()->totalCols(); c++)
    00477         if(_x >= pos && _x <= pos+element()->border())
    00478             return true;
    00479
    00480     pos = m_gridLayout[0][0];
    00481     for(int r = 1; r < element()->totalRows(); r++)
    00482         if( _y >= pos && _y <= pos+element()->border())
    00483             return true;
    00484
    00485     return false;
    00486 }
    00487
    00488 #ifndef NDEBUG
    00489 void RenderFrameSet::dump(QTextStream *stream, QString ind) const
    00490 {
    00491   *stream << " totalrows=" << element()->totalRows();
    00492   *stream << " totalcols=" << element()->totalCols();
    00493
    00494   uint i;
    00495   for (i = 0; i < (uint)element()->totalRows(); i++)
    00496     *stream << " hSplitvar(" << i << ")=" << m_hSplitVar[i];
    00497
    00498   for (i = 0; i < (uint)element()->totalCols(); i++)
    00499     *stream << " vSplitvar(" << i << ")=" << m_vSplitVar[i];
    00500
    00501   RenderBox::dump(stream,ind);
    00502 }
    00503 #endif
    00504
    00505 /**************************************************************************************/
    00506
    00507 RenderPart::RenderPart(DOM::HTMLElementImpl* node)
    00508     : RenderWidget(node)
    00509 {
    00510     // init RenderObject attributes
    00511     setInline(false);
    00512 }
    00513
    00514 void RenderPart::setWidget( QWidget *widget )
    00515 {
    00516 #ifdef DEBUG_LAYOUT
    00517     kdDebug(6031) << "RenderPart::setWidget()" << endl;
    00518 #endif
    00519     setQWidget( widget );
    00520     widget->setFocusPolicy(QWidget::WheelFocus);
    00521     if(widget->inherits("KHTMLView"))
    00522         connect( widget, SIGNAL( cleared() ), this, SLOT( slotViewCleared() ) );
    00523
    00524     setLayouted( false );
    00525     setMinMaxKnown( false );
    00526
    00527     // make sure the scrollbars are set correctly for restore
    00528     // ### find better fix
    00529     slotViewCleared();
    00530 }
    00531
    00532 bool RenderPart::partLoadingErrorNotify(khtml::ChildFrame *, const KURL& , const QString& )
    00533 {
    00534     return false;
    00535 }
    00536
    00537 short RenderPart::intrinsicWidth() const
    00538 {
    00539     return 300;
    00540 }
    00541
    00542 int RenderPart::intrinsicHeight() const
    00543 {
    00544     return 200;
    00545 }
    00546
    00547 void RenderPart::slotViewCleared()
    00548 {
    00549 }
    00550
    00551 /***************************************************************************************/
    00552
    00553 RenderFrame::RenderFrame( DOM::HTMLFrameElementImpl *frame )
    00554     : RenderPart(frame)
    00555 {
    00556     setInline( false );
    00557 }
    00558
    00559 void RenderFrame::slotViewCleared()
    00560 {
    00561     if(m_widget->inherits("QScrollView")) {
    00562 #ifdef DEBUG_LAYOUT
    00563         kdDebug(6031) << "frame is a scrollview!" << endl;
    00564 #endif
    00565         QScrollView *view = static_cast<QScrollView *>(m_widget);
    00566         if(!element()->frameBorder || !((static_cast<HTMLFrameSetElementImpl *>(element()->parentNode()))->frameBorder()))
    00567             view->setFrameStyle(QFrame::NoFrame);
    00568             view->setVScrollBarMode(element()->scrolling );
    00569             view->setHScrollBarMode(element()->scrolling );
    00570         if(view->inherits("KHTMLView")) {
    00571 #ifdef DEBUG_LAYOUT
    00572             kdDebug(6031) << "frame is a KHTMLview!" << endl;
    00573 #endif
    00574             KHTMLView *htmlView = static_cast<KHTMLView *>(view);
    00575             if(element()->marginWidth != -1) htmlView->setMarginWidth(element()->marginWidth);
    00576             if(element()->marginHeight != -1) htmlView->setMarginHeight(element()->marginHeight);
    00577         }
    00578     }
    00579 }
    00580
    00581 /****************************************************************************************/
    00582
    00583 RenderPartObject::RenderPartObject( DOM::HTMLElementImpl* element )
    00584     : RenderPart( element )
    00585 {
    00586     // init RenderObject attributes
    00587     setInline(true);
    00588 }
    00589
    00590 void RenderPartObject::updateWidget()
    00591 {
    00592   QString url;
    00593   QString serviceType;
    00594   QStringList params;
    00595   KHTMLPart *part = m_view->part();
    00596
    00597   setMinMaxKnown(false);
    00598   setLayouted(false);
    00599
    00600   // ### this should be constant true - move iframe to somewhere else
    00601   if (element()->id() == ID_OBJECT || element()->id() == ID_EMBED) {
    00602
    00603       for (NodeImpl* child = element()->firstChild(); child; child=child->nextSibling()) {
    00604           if ( child->id() == ID_PARAM ) {
    00605               HTMLParamElementImpl *p = static_cast<HTMLParamElementImpl *>( child );
    00606
    00607               QString aStr = p->name();
    00608               aStr += QString::fromLatin1("=\"");
    00609               aStr += p->value();
    00610               aStr += QString::fromLatin1("\"");
    00611               params.append(aStr);
    00612           }
    00613       }
    00614       params.append( QString::fromLatin1("__KHTML__PLUGINEMBED=\"YES\"") );
    00615       params.append( QString::fromLatin1("__KHTML__PLUGINBASEURL=\"%1\"").arg( part->url().url() ) );
    00616   }
    00617
    00618   if(element()->id() == ID_OBJECT) {
    00619
    00620       // check for embed child object
    00621       HTMLObjectElementImpl *o = static_cast<HTMLObjectElementImpl *>(element());
    00622       HTMLEmbedElementImpl *embed = 0;
    00623       for (NodeImpl *child = o->firstChild(); child; child = child->nextSibling())
    00624           if ( child->id() == ID_EMBED ) {
    00625               embed = static_cast<HTMLEmbedElementImpl *>( child );
    00626               break;
    00627           }
    00628
    00629       params.append( QString::fromLatin1("__KHTML__CLASSID=\"%1\"").arg( o->classId ) );
    00630       params.append( QString::fromLatin1("__KHTML__CODEBASE=\"%1\"").arg( o->getAttribute(ATTR_CODEBASE).string() ) );
    00631       if (!o->getAttribute(ATTR_WIDTH).isEmpty())
    00632           params.append( QString::fromLatin1("WIDTH=\"%1\"").arg( o->getAttribute(ATTR_WIDTH).string() ) );
    00633       if (!o->getAttribute(ATTR_HEIGHT).isEmpty())
    00634           params.append( QString::fromLatin1("HEIGHT=\"%1\"").arg( o->getAttribute(ATTR_HEIGHT).string() ) );
    00635
    00636       if ( !embed )
    00637       {
    00638           url = o->url;
    00639           serviceType = o->serviceType;
    00640           if(serviceType.isEmpty() || serviceType.isNull()) {
    00641               if(!o->classId.isEmpty()) {
    00642                   // We have a clsid, means this is activex (Niko)
    00643                   serviceType = "application/x-activex-handler";
    00644                   url = "dummy"; // Not needed, but KHTMLPart aborts the request if empty
    00645               }
    00646
    00647               if(o->classId.contains(QString::fromLatin1("D27CDB6E-AE6D-11cf-96B8-444553540000"))) {
    00648                   // It is ActiveX, but the nsplugin system handling
    00649                   // should also work, that's why we don't override the
    00650                   // serviceType with application/x-activex-handler
    00651                   // but let the KTrader in khtmlpart::createPart() detect
    00652                   // the user's preference: launch with activex viewer or
    00653                   // with nspluginviewer (Niko)
    00654                   serviceType = "application/x-shockwave-flash";
    00655               }
    00656               else if(o->classId.contains(QString::fromLatin1("CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA")))
    00657                   serviceType = "audio/x-pn-realaudio-plugin";
    00658
    00659               // TODO: add more plugins here
    00660           }
    00661
    00662           if(url.isEmpty()) {
    00663               // look for a SRC attribute in the params
    00664               NodeImpl *child = o->firstChild();
    00665               while ( child ) {
    00666                   if ( child->id() == ID_PARAM ) {
    00667                       HTMLParamElementImpl *p = static_cast<HTMLParamElementImpl *>( child );
    00668
    00669                       if ( ( p->name().lower()==QString::fromLatin1("src") ||
    00670                              p->name().lower()==QString::fromLatin1("movie") ||
    00671                              p->name().lower()==QString::fromLatin1("code") ) && !p->value().isNull() )
    00672                       {
    00673                           url = p->getDocument()->completeURL(khtml::parseURL(p->value()).string());
    00674                           if (!p->getDocument()->isURLAllowed(url))
    00675                               url = QString::null;
    00676                           else
    00677                               break;
    00678                       }
    00679                   }
    00680                   child = child->nextSibling();
    00681               }
    00682           }
    00683
    00684
    00685           if ( url.isEmpty() && serviceType.isEmpty() ) {
    00686 #ifdef DEBUG_LAYOUT
    00687               kdDebug() << "RenderPartObject::close - empty url and serverType" << endl;
    00688 #endif
    00689               return;
    00690           }
    00691           part->requestObject( this, url, serviceType, params );
    00692       }
    00693       else {
    00694           // render embed object
    00695           url = embed->url;
    00696           serviceType = embed->serviceType;
    00697
    00698           if ( url.isEmpty() && serviceType.isEmpty() ) {
    00699 #ifdef DEBUG_LAYOUT
    00700               kdDebug() << "RenderPartObject::close - empty url and serverType" << endl;
    00701 #endif
    00702               return;
    00703           }
    00704           part->requestObject( this, url, serviceType, params );
    00705       }
    00706       o->setLiveConnect(part->liveConnectExtension(this));
    00707   }
    00708   else if ( element()->id() == ID_EMBED ) {
    00709
    00710       HTMLEmbedElementImpl *o = static_cast<HTMLEmbedElementImpl *>(element());
    00711       url = o->url;
    00712       serviceType = o->serviceType;
    00713
    00714       if ( url.isEmpty() && serviceType.isEmpty() ) {
    00715 #ifdef DEBUG_LAYOUT
    00716           kdDebug() << "RenderPartObject::close - empty url and serverType" << endl;
    00717 #endif
    00718           return;
    00719       }
    00720       // add all attributes set on the embed object
    00721       NamedAttrMapImpl* a = o->attributes();
    00722       if (a) {
    00723           for (unsigned long i = 0; i < a->length(); ++i) {
    00724               AttributeImpl* it = a->attributeItem(i);
    00725               params.append(o->getDocument()->attrName(it->id()).string() + "=\"" + it->value().string() + "\"");
    00726           }
    00727       }
    00728       part->requestObject( this, url, serviceType, params );
    00729   } else {
    00730       assert(element()->id() == ID_IFRAME);
    00731       HTMLIFrameElementImpl *o = static_cast<HTMLIFrameElementImpl *>(element());
    00732       url = o->url.string();
    00733       if( url.isEmpty()) return;
    00734       KHTMLView *v = static_cast<KHTMLView *>(m_view);
    00735       v->part()->requestFrame( this, url, o->name.string(), QStringList(), true );
    00736   }
    00737 }
    00738
    00739 // ugly..
    00740 void RenderPartObject::close()
    00741 {
    00742     if ( element()->id() == ID_OBJECT )
    00743         updateWidget();
    00744     RenderPart::close();
    00745 }
    00746
    00747
    00748 bool RenderPartObject::partLoadingErrorNotify( khtml::ChildFrame *childFrame, const KURL& url, const QString& serviceType )
    00749 {
    00750     KHTMLPart *part = static_cast<KHTMLView *>(m_view)->part();
    00751     //kdDebug() << "RenderPartObject::partLoadingErrorNotify serviceType=" << serviceType << endl;
    00752     // Check if we just tried with e.g. nsplugin
    00753     // and fallback to the activexhandler if there is a classid
    00754     // and a codebase, where we may download the ocx if it's missing
    00755     if( serviceType != "application/x-activex-handler" && element()->id()==ID_OBJECT ) {
    00756
    00757         // check for embed child object
    00758         HTMLObjectElementImpl *o = static_cast<HTMLObjectElementImpl *>(element());
    00759         HTMLEmbedElementImpl *embed = 0;
    00760         NodeImpl *child = o->firstChild();
    00761         while ( child ) {
    00762             if ( child->id() == ID_EMBED )
    00763                 embed = static_cast<HTMLEmbedElementImpl *>( child );
    00764
    00765             child = child->nextSibling();
    00766         }
    00767         if( embed && !o->classId.isEmpty() &&
    00768             !( static_cast<ElementImpl *>(o)->getAttribute(ATTR_CODEBASE).string() ).isEmpty() )
    00769         {
    00770             KParts::URLArgs args;
    00771             args.serviceType = "application/x-activex-handler";
    00772             if (part->requestObject( childFrame, url, args ))
    00773                 return true; // success
    00774         }
    00775     }
    00776     // Dissociate ourselves from the current event loop (to prevent crashes
    00777     // due to the message box staying up)
    00778     QTimer::singleShot( 0, this, SLOT( slotPartLoadingErrorNotify() ) );
    00779 #if 0
    00780     Tokenizer *tokenizer = static_cast<DOM::DocumentImpl *>(part->document().handle())->tokenizer();
    00781     if (tokenizer) tokenizer->setOnHold( true );
    00782     slotPartLoadingErrorNotify();
    00783     if (tokenizer) tokenizer->setOnHold( false );
    00784 #endif
    00785     return false;
    00786 }
    00787
    00788 void RenderPartObject::slotPartLoadingErrorNotify()
    00789 {
    00790     // First we need to find out the servicetype - again - this code is too duplicated !
    00791     HTMLEmbedElementImpl *embed = 0;
    00792     QString serviceType;
    00793     if( element()->id()==ID_OBJECT ) {
    00794
    00795         // check for embed child object
    00796         HTMLObjectElementImpl *o = static_cast<HTMLObjectElementImpl *>(element());
    00797         serviceType = o->serviceType;
    00798         NodeImpl *child = o->firstChild();
    00799         while ( child ) {
    00800             if ( child->id() == ID_EMBED )
    00801                 embed = static_cast<HTMLEmbedElementImpl *>( child );
    00802
    00803             child = child->nextSibling();
    00804         }
    00805
    00806     } else if( element()->id()==ID_EMBED ) {
    00807         embed = static_cast<HTMLEmbedElementImpl *>(element());
    00808     }
    00809     if ( embed )
    00810         serviceType = embed->serviceType;
    00811
    00812     KHTMLPart *part = static_cast<KHTMLView *>(m_view)->part();
    00813     KParts::BrowserExtension *ext = part->browserExtension();
    00814     if( embed && !embed->pluginPage.isEmpty() && ext ) {
    00815         // Prepare the mimetype to show in the question (comment if available, name as fallback)
    00816         QString mimeName = serviceType;
    00817         KMimeType::Ptr mime = KMimeType::mimeType(serviceType);
    00818         if ( mime->name() != KMimeType::defaultMimeType() )
    00819             mimeName = mime->comment();
    00820
    00821         // Check if we already asked the user, for this page
    00822         if (!mimeName.isEmpty() && part->docImpl() && !part->pluginPageQuestionAsked( serviceType ) )
    00823         {
    00824             part->setPluginPageQuestionAsked( serviceType );
    00825             // Prepare the URL to show in the question (host only if http, to make it short)
    00826             KURL pluginPageURL( embed->pluginPage );
    00827             QString shortURL = pluginPageURL.protocol() == "http" ? pluginPageURL.host() : pluginPageURL.prettyURL();
    00828             int res = KMessageBox::questionYesNo( m_view,
    00829                                                   i18n("No plugin found for '%1'.\nDo you want to download one from %2?").arg(mimeName).arg(shortURL),
    00830                                                   i18n("Missing Plugin"), QString::null, QString::null, QString("plugin-")+serviceType);
    00831             if ( res == KMessageBox::Yes )
    00832             {
    00833                 // Display vendor download page
    00834                 ext->createNewWindow( pluginPageURL );
    00835                 return;
    00836             }
    00837         }
    00838     }
    00839
    00840     // didn't work, render alternative content.
    00841  //   if ( element() && element()->id() == ID_OBJECT )
    00842    //     static_cast<HTMLObjectElementImpl*>( element() )->renderAlternative();
    00843 }
    00844
    00845 void RenderPartObject::layout( )
    00846 {
    00847     KHTMLAssert( !layouted() );
    00848     KHTMLAssert( minMaxKnown() );
    00849
    00850     calcWidth();
    00851     calcHeight();
    00852
    00853     RenderPart::layout();
    00854
    00855     setLayouted();
    00856 }
    00857
    00858 void RenderPartObject::slotViewCleared()
    00859 {
    00860   if(m_widget->inherits("QScrollView") ) {
    00861 #ifdef DEBUG_LAYOUT
    00862       kdDebug(6031) << "iframe is a scrollview!" << endl;
    00863 #endif
    00864       QScrollView *view = static_cast<QScrollView *>(m_widget);
    00865       int frameStyle = QFrame::NoFrame;
    00866       QScrollView::ScrollBarMode scroll = QScrollView::Auto;
    00867       int marginw = 0;
    00868       int marginh = 0;
    00869       if ( element()->id() == ID_IFRAME) {
    00870           HTMLIFrameElementImpl *frame = static_cast<HTMLIFrameElementImpl *>(element());
    00871           if(frame->frameBorder)
    00872               frameStyle = QFrame::Box;
    00873           scroll = frame->scrolling;
    00874           marginw = frame->marginWidth;
    00875           marginh = frame->marginHeight;
    00876       }
    00877       view->setFrameStyle(frameStyle);
    00878       view->setVScrollBarMode(scroll );
    00879       view->setHScrollBarMode(scroll );
    00880       if(view->inherits("KHTMLView")) {
    00881 #ifdef DEBUG_LAYOUT
    00882           kdDebug(6031) << "frame is a KHTMLview!" << endl;
    00883 #endif
    00884           KHTMLView *htmlView = static_cast<KHTMLView *>(view);
    00885           htmlView->setIgnoreWheelEvents( element()->id() == ID_IFRAME );
    00886           if(marginw != -1) htmlView->setMarginWidth(marginw);
    00887           if(marginh != -1) htmlView->setMarginHeight(marginh);
    00888         }
    00889   }
    00890 }
    00891
    00892 #include "render_frames.moc"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:34:35 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001