# khtml Library API Documentation

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

# render_form.cpp

    00001 /*
    00002  * This file is part of the DOM implementation for KDE.
    00003  *
    00004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
    00005  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    00006  *           (C) 2000 Dirk Mueller (mueller@kde.org)
    00007  *
    00008  * This library is free software; you can redistribute it and/or
    00009  * modify it under the terms of the GNU Library General Public
    00010  * License as published by the Free Software Foundation; either
    00011  * version 2 of the License, or (at your option) any later version.
    00012  *
    00013  * This library is distributed in the hope that it will be useful,
    00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00016  * Library General Public License for more details.
    00017  *
    00018  * You should have received a copy of the GNU Library General Public License
    00019  * along with this library; see the file COPYING.LIB.  If not, write to
    00020  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00021  * Boston, MA 02111-1307, USA.
    00022  *
    00023  * $Id: render_form.cpp,v 1.198.2.11 2003/10/25 13:36:01 ggarand Exp $
    00024  */
    00025
    00026 #include <kdebug.h>
    00027 #include <klocale.h>
    00028 #include <kfiledialog.h>
    00029 #include <kcompletionbox.h>
    00030 #include <kcursor.h>
    00031
    00032 #include <qstyle.h>
    00033
    00034 #include "misc/helper.h"
    00035 #include "xml/dom2_eventsimpl.h"
    00036 #include "html/html_formimpl.h"
    00037 #include "misc/htmlhashes.h"
    00038
    00039 #include "rendering/render_form.h"
    00040 #include <assert.h>
    00041
    00042 #include "khtmlview.h"
    00043 #include "khtml_ext.h"
    00044 #include "xml/dom_docimpl.h"
    00045
    00046 #include <qpopupmenu.h>
    00047
    00048 using namespace khtml;
    00049
    00050 RenderFormElement::RenderFormElement(HTMLGenericFormElementImpl *element)
    00051     : RenderWidget(element)
    00052 {
    00053     // init RenderObject attributes
    00054     setInline(true);   // our object is Inline
    00055
    00056     m_state = 0;
    00057     m_isDoubleClick = false;
    00058 }
    00059
    00060 RenderFormElement::~RenderFormElement()
    00061 {
    00062 }
    00063
    00064 short RenderFormElement::baselinePosition( bool f ) const
    00065 {
    00066     return RenderWidget::baselinePosition( f ) - 2 - style()->fontMetrics().descent();
    00067 }
    00068
    00069
    00070 void RenderFormElement::updateFromElement()
    00071 {
    00072     m_widget->setEnabled(!element()->disabled());
    00073     RenderWidget::updateFromElement();
    00074 }
    00075
    00076 void RenderFormElement::layout()
    00077 {
    00078     KHTMLAssert( !layouted() );
    00079     KHTMLAssert( minMaxKnown() );
    00080
    00081     // minimum height
    00082     m_height = 0;
    00083
    00084     calcWidth();
    00085     calcHeight();
    00086
    00087     if ( m_widget )
    00088         resizeWidget(m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(),
    00089                      m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom());
    00090
    00091     if ( !style()->width().isPercent() )
    00092         setLayouted();
    00093 }
    00094
    00095 void RenderFormElement::slotClicked()
    00096 {
    00097     ref();
    00098     QMouseEvent e2( QEvent::MouseButtonRelease, m_mousePos, 1, m_state);
    00099
    00100     element()->dispatchMouseEvent(&e2, EventImpl::CLICK_EVENT, m_isDoubleClick + 1);
    00101     m_isDoubleClick = false;
    00102     deref();
    00103 }
    00104
    00105 void RenderFormElement::slotPressed()
    00106 {
    00107     ref();
    00108     QMouseEvent e2( QEvent::MouseButtonPress, m_mousePos, 1, m_state);
    00109     element()->dispatchMouseEvent(&e2, EventImpl::MOUSEDOWN_EVENT, 1);
    00110     deref();
    00111 }
    00112
    00113 void RenderFormElement::slotReleased()
    00114 {
    00115     ref();
    00116     QMouseEvent e2( QEvent::MouseButtonRelease, m_mousePos, 1, m_state);
    00117     element()->dispatchMouseEvent(&e2, EventImpl::MOUSEUP_EVENT, 1);
    00118     deref();
    00119 }
    00120
    00121 // -------------------------------------------------------------------------
    00122
    00123 RenderButton::RenderButton(HTMLGenericFormElementImpl *element)
    00124     : RenderFormElement(element)
    00125 {
    00126 }
    00127
    00128 short RenderButton::baselinePosition( bool f ) const
    00129 {
    00130     return RenderWidget::baselinePosition( f ) - 2;
    00131 }
    00132
    00133 // -------------------------------------------------------------------------------
    00134
    00135
    00136 RenderCustomButton::RenderCustomButton(HTMLGenericFormElementImpl *element)
    00137     : RenderReplacedFlow(element)
    00138 {
    00139 }
    00140
    00141 // -------------------------------------------------------------------------------
    00142
    00143 RenderCheckBox::RenderCheckBox(HTMLInputElementImpl *element)
    00144     : RenderButton(element)
    00145 {
    00146     QCheckBox* b = new QCheckBox(view()->viewport());
    00147     b->setAutoMask(true);
    00148     b->setMouseTracking(true);
    00149     setQWidget(b);
    00150     connect(b,SIGNAL(stateChanged(int)),this,SLOT(slotStateChanged(int)));
    00151     connect(b, SIGNAL(clicked()), this, SLOT(slotClicked()));
    00152     connect(b, SIGNAL(pressed()), this, SLOT(slotPressed()));
    00153     connect(b, SIGNAL(released()), this, SLOT(slotReleased()));
    00154 }
    00155
    00156
    00157 void RenderCheckBox::calcMinMaxWidth()
    00158 {
    00159     KHTMLAssert( !minMaxKnown() );
    00160
    00161     QCheckBox *cb = static_cast<QCheckBox *>( m_widget );
    00162     QSize s( cb->style().pixelMetric( QStyle::PM_IndicatorWidth ),
    00163              cb->style().pixelMetric( QStyle::PM_IndicatorHeight ) );
    00164     setIntrinsicWidth( s.width() );
    00165     setIntrinsicHeight( s.height() );
    00166
    00167     RenderButton::calcMinMaxWidth();
    00168 }
    00169
    00170 void RenderCheckBox::updateFromElement()
    00171 {
    00172     widget()->setChecked(element()->checked());
    00173
    00174     RenderButton::updateFromElement();
    00175 }
    00176
    00177 void RenderCheckBox::slotStateChanged(int state)
    00178 {
    00179     element()->setChecked(state == 2);
    00180 }
    00181
    00182 // -------------------------------------------------------------------------------
    00183
    00184 RenderRadioButton::RenderRadioButton(HTMLInputElementImpl *element)
    00185     : RenderButton(element)
    00186 {
    00187     QRadioButton* b = new QRadioButton(view()->viewport());
    00188     b->setAutoMask(true);
    00189     b->setMouseTracking(true);
    00190     setQWidget(b);
    00191     connect(b, SIGNAL(clicked()), this, SLOT(slotClicked()));
    00192     connect(b, SIGNAL(pressed()), this, SLOT(slotPressed()));
    00193     connect(b, SIGNAL(released()), this, SLOT(slotReleased()));
    00194 }
    00195
    00196 void RenderRadioButton::updateFromElement()
    00197 {
    00198     widget()->setChecked(element()->checked());
    00199
    00200     RenderButton::updateFromElement();
    00201 }
    00202
    00203 void RenderRadioButton::slotClicked()
    00204 {
    00205     element()->setChecked(true);
    00206
    00207     // emit mouseClick event etc
    00208     RenderButton::slotClicked();
    00209 }
    00210
    00211 void RenderRadioButton::calcMinMaxWidth()
    00212 {
    00213     KHTMLAssert( !minMaxKnown() );
    00214
    00215     QRadioButton *rb = static_cast<QRadioButton *>( m_widget );
    00216     QSize s( rb->style().pixelMetric( QStyle::PM_ExclusiveIndicatorWidth ),
    00217              rb->style().pixelMetric( QStyle::PM_ExclusiveIndicatorHeight ) );
    00218     setIntrinsicWidth( s.width() );
    00219     setIntrinsicHeight( s.height() );
    00220
    00221     RenderButton::calcMinMaxWidth();
    00222 }
    00223
    00224 // -------------------------------------------------------------------------------
    00225
    00226
    00227 RenderSubmitButton::RenderSubmitButton(HTMLInputElementImpl *element)
    00228     : RenderButton(element)
    00229 {
    00230     QPushButton* p = new QPushButton(view()->viewport());
    00231     setQWidget(p);
    00232     p->setAutoMask(true);
    00233     p->setMouseTracking(true);
    00234     connect(p, SIGNAL(clicked()), this, SLOT(slotClicked()));
    00235     connect(p, SIGNAL(pressed()), this, SLOT(slotPressed()));
    00236     connect(p, SIGNAL(released()), this, SLOT(slotReleased()));
    00237 }
    00238
    00239 QString RenderSubmitButton::rawText()
    00240 {
    00241     QString value = element()->value().isEmpty() ? defaultLabel() : element()->value().string();
    00242     value = value.stripWhiteSpace();
    00243     QString raw;
    00244     for(unsigned int i = 0; i < value.length(); i++) {
    00245         raw += value[i];
    00246         if(value[i] == '&')
    00247             raw += '&';
    00248     }
    00249     return raw;
    00250 }
    00251
    00252 void RenderSubmitButton::calcMinMaxWidth()
    00253 {
    00254     KHTMLAssert( !minMaxKnown() );
    00255
    00256     QString raw = rawText();
    00257     QPushButton* pb = static_cast<QPushButton*>(m_widget);
    00258     pb->setText(raw);
    00259     pb->setFont(style()->font());
    00260
    00261     bool empty = raw.isEmpty();
    00262     if ( empty )
    00263         raw = QString::fromLatin1("X");
    00264     QFontMetrics fm = pb->fontMetrics();
    00265     QSize ts = fm.size( ShowPrefix, raw);
    00266     QSize s(pb->style().sizeFromContents( QStyle::CT_PushButton, pb, ts )
    00267             .expandedTo(QApplication::globalStrut()));
    00268     int margin = pb->style().pixelMetric( QStyle::PM_ButtonMargin, pb) +
    00269                  pb->style().pixelMetric( QStyle::PM_DefaultFrameWidth, pb ) * 2;
    00270     int w = ts.width() + margin;
    00271     int h = s.height();
    00272     if (pb->isDefault() || pb->autoDefault()) {
    00273         int dbw = pb->style().pixelMetric( QStyle::PM_ButtonDefaultIndicator, pb ) * 2;
    00274         w += dbw;
    00275     }
    00276
    00277     // add 30% margins to the width (heuristics to make it look similar to IE)
    00278     s = QSize( w*13/10, h ).expandedTo(QApplication::globalStrut());
    00279
    00280     setIntrinsicWidth( s.width() );
    00281     setIntrinsicHeight( s.height() );
    00282
    00283     RenderButton::calcMinMaxWidth();
    00284 }
    00285
    00286 void RenderSubmitButton::updateFromElement()
    00287 {
    00288     QString oldText = static_cast<QPushButton*>(m_widget)->text();
    00289     QString newText = rawText();
    00290     static_cast<QPushButton*>(m_widget)->setText(newText);
    00291     if ( oldText != newText ) {
    00292         setMinMaxKnown(false);
    00293         setLayouted(false);
    00294     }
    00295     RenderFormElement::updateFromElement();
    00296 }
    00297
    00298 QString RenderSubmitButton::defaultLabel() {
    00299     return i18n("Submit");
    00300 }
    00301
    00302 short RenderSubmitButton::baselinePosition( bool f ) const
    00303 {
    00304     return RenderFormElement::baselinePosition( f );
    00305 }
    00306
    00307 // -------------------------------------------------------------------------------
    00308
    00309 RenderImageButton::RenderImageButton(HTMLInputElementImpl *element)
    00310     : RenderImage(element)
    00311 {
    00312     // ### support DOMActivate event when clicked
    00313 }
    00314
    00315
    00316 // -------------------------------------------------------------------------------
    00317
    00318 RenderResetButton::RenderResetButton(HTMLInputElementImpl *element)
    00319     : RenderSubmitButton(element)
    00320 {
    00321 }
    00322
    00323 QString RenderResetButton::defaultLabel() {
    00324     return i18n("Reset");
    00325 }
    00326
    00327
    00328 // -------------------------------------------------------------------------------
    00329
    00330 RenderPushButton::RenderPushButton(HTMLInputElementImpl *element)
    00331     : RenderSubmitButton(element)
    00332 {
    00333 }
    00334
    00335 QString RenderPushButton::defaultLabel()
    00336 {
    00337     return QString::null;
    00338 }
    00339
    00340 // -------------------------------------------------------------------------------
    00341
    00342 LineEditWidget::LineEditWidget(QWidget *parent)
    00343         : KLineEdit(parent)
    00344 {
    00345     setMouseTracking(true);
    00346 }
    00347
    00348 QPopupMenu *LineEditWidget::createPopupMenu()
    00349 {
    00350     QPopupMenu *popup = KLineEdit::createPopupMenu();
    00351     if ( !popup )
    00352         return 0L;
    00353     connect( popup, SIGNAL( activated( int ) ),
    00354              this, SLOT( extendedMenuActivated( int ) ) );
    00355     return popup;
    00356 }
    00357
    00358 void LineEditWidget::extendedMenuActivated( int id)
    00359 {
    00360     switch ( id )
    00361     {
    00362     case ClearHistory:
    00363         clearMenuHistory();
    00364         break;
    00365     default:
    00366         break;
    00367     }
    00368 }
    00369
    00370 void LineEditWidget::clearMenuHistory()
    00371 {
    00372     emit clearCompletionHistory();
    00373 }
    00374
    00375
    00376 bool LineEditWidget::event( QEvent *e )
    00377 {
    00378     if ( e->type() == QEvent::AccelAvailable && isReadOnly() ) {
    00379         QKeyEvent* ke = (QKeyEvent*) e;
    00380         if ( ke->state() & ControlButton ) {
    00381             switch ( ke->key() ) {
    00382                 case Key_Left:
    00383                 case Key_Right:
    00384                 case Key_Up:
    00385                 case Key_Down:
    00386                 case Key_Home:
    00387                 case Key_End:
    00388                     ke->accept();
    00389                 default:
    00390                 break;
    00391             }
    00392         }
    00393     }
    00394     else if ( e->type() == QEvent::MouseButtonPress )
    00395         emit pressed();
    00396     else if ( e->type() == QEvent::MouseButtonRelease )
    00397         emit released();
    00398     return KLineEdit::event( e );
    00399 }
    00400
    00401 // -----------------------------------------------------------------------------
    00402
    00403 RenderLineEdit::RenderLineEdit(HTMLInputElementImpl *element)
    00404     : RenderFormElement(element)
    00405 {
    00406     LineEditWidget *edit = new LineEditWidget(view()->viewport());
    00407     connect(edit,SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
    00408     connect(edit,SIGNAL(textChanged(const QString &)),this,SLOT(slotTextChanged(const QString &)));
    00409     connect(edit,SIGNAL(pressed()), this, SLOT(slotPressed()));
    00410     connect(edit,SIGNAL(released()), this, SLOT(slotReleased()));
    00411     connect(edit, SIGNAL(clearCompletionHistory()), this, SLOT( slotClearCompletionHistory()));
    00412     if(element->inputType() == HTMLInputElementImpl::PASSWORD)
    00413         edit->setEchoMode( QLineEdit::Password );
    00414
    00415     if ( element->autoComplete() ) {
    00416         QStringList completions = view()->formCompletionItems(element->name().string());
    00417         if (completions.count()) {
    00418             edit->completionObject()->setItems(completions);
    00419             edit->setContextMenuEnabled(true);
    00420         }
    00421     }
    00422
    00423     setQWidget(edit);
    00424 }
    00425
    00426 void RenderLineEdit::slotClearCompletionHistory()
    00427 {
    00428     if ( element()->autoComplete() ) {
    00429         view()->clearCompletionHistory(element()->name().string());
    00430         static_cast<LineEditWidget*>(m_widget)->completionObject()->clear();
    00431     }
    00432 }
    00433
    00434 void RenderLineEdit::slotReturnPressed()
    00435 {
    00436     // don't submit the form when return was pressed in a completion-popup
    00437     KCompletionBox *box = widget()->completionBox(false);
    00438     if ( box && box->isVisible() && box->currentItem() != -1 )
    00439         return;
    00440
    00441     // Emit onChange if necessary
    00442     // Works but might not be enough, dirk said he had another solution at
    00443     // hand (can't remember which) - David
    00444     handleFocusOut();
    00445
    00446     HTMLFormElementImpl* fe = element()->form();
    00447     if ( fe )
    00448         fe->submitFromKeyboard();
    00449 }
    00450
    00451 void RenderLineEdit::handleFocusOut()
    00452 {
    00453     if ( widget() && widget()->edited() ) {
    00454         element()->onChange();
    00455         widget()->setEdited( false );
    00456     }
    00457 }
    00458
    00459 void RenderLineEdit::calcMinMaxWidth()
    00460 {
    00461     KHTMLAssert( !minMaxKnown() );
    00462
    00463     const QFontMetrics &fm = style()->fontMetrics();
    00464     QSize s;
    00465
    00466     int size = element()->size();
    00467
    00468     int h = fm.lineSpacing();
    00469     int w = fm.width( 'x' ) * (size > 0 ? size+1 : 17); // "some"
    00470     s = QSize(w + 2 + 2*widget()->frameWidth(),
    00471               QMAX(h, 14) + 2 + 2*widget()->frameWidth())
    00472         .expandedTo(QApplication::globalStrut());
    00473
    00474     setIntrinsicWidth( s.width() );
    00475     setIntrinsicHeight( s.height() );
    00476
    00477     RenderFormElement::calcMinMaxWidth();
    00478 }
    00479
    00480 void RenderLineEdit::updateFromElement()
    00481 {
    00482     int ml = element()->maxLength();
    00483     if ( ml < 0 || ml > 1024 )
    00484         ml = 1024;
    00485     if ( widget()->maxLength() != ml ) {
    00486         widget()->blockSignals( true );
    00487         widget()->setMaxLength( ml );
    00488         widget()->blockSignals( false );
    00489     }
    00490
    00491     if (element()->value().string() != widget()->text()) {
    00492         widget()->blockSignals(true);
    00493         int pos = widget()->cursorPosition();
    00494         widget()->setText(element()->value().string());
    00495
    00496         widget()->setEdited( false );
    00497
    00498         widget()->setCursorPosition(pos);
    00499         widget()->blockSignals(false);
    00500     }
    00501     widget()->setReadOnly(element()->readOnly());
    00502
    00503     RenderFormElement::updateFromElement();
    00504 }
    00505
    00506 void RenderLineEdit::slotTextChanged(const QString &string)
    00507 {
    00508     // don't use setValue here!
    00509     element()->m_value = string;
    00510 }
    00511
    00512 void RenderLineEdit::select()
    00513 {
    00514     static_cast<LineEditWidget*>(m_widget)->selectAll();
    00515 }
    00516
    00517 // ---------------------------------------------------------------------------
    00518
    00519 RenderFieldset::RenderFieldset(HTMLGenericFormElementImpl *element)
    00520     : RenderFlow(element)
    00521 {
    00522 }
    00523
    00524 bool RenderFieldset::findLegend( int &lx, int &ly, int &lw, int &lh)
    00525 {
    00526     RenderObject *r = this, *ref = 0;
    00527     int minx = 0, curx = 0, maxw = 0;
    00528     if( r->firstChild() && r->firstChild()->element() &&
    00529         r->firstChild()->element()->id() == ID_LEGEND)
    00530             r = r->firstChild();
    00531     else
    00532         return false;
    00533     if(!r->firstChild() || r->isSpecial())
    00534         return false;
    00535     ly = r->yPos();
    00536     minx = r->width();
    00537     curx = r->xPos();
    00538     lh = r->height();
    00539     ref = r;
    00540
    00541     while(r) {
    00542         if(r->firstChild())
    00543             r = r->firstChild();
    00544         else if(r->nextSibling())
    00545             r = r->nextSibling();
    00546         else {
    00547             RenderObject *next = 0;
    00548             while(!next) {
    00549                 r = r->parent();
    00550                 if(!r || r == (RenderObject *)ref ) goto end;
    00551                 next = r->nextSibling();
    00552             }
    00553             r = next;
    00554         }
    00555         if(r->isSpecial())
    00556             continue;
    00557         curx += r->xPos();
    00558         if(r->width() && curx<minx)
    00559              minx = curx;
    00560         if(curx-minx+r->width() > maxw) {
    00561                 maxw = curx-minx+r->width();
    00562         }
    00563         if(!r->childrenInline())
    00564             curx -= r->xPos();
    00565     }
    00566     end:
    00567         lx = minx - ref->paddingLeft();
    00568         lw = maxw + ref->paddingLeft() + ref->paddingRight();
    00569         if(lx < 0 || lx+lw > width())
    00570             return false;
    00571         return !!maxw;
    00572 }
    00573
    00574 void RenderFieldset::paintBoxDecorations(QPainter *p,int, int _y,
    00575                                        int, int _h, int _tx, int _ty)
    00576 {
    00577     //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl;
    00578
    00579     int w = width();
    00580     int h = height() + borderTopExtra() + borderBottomExtra();
    00581     int lx = 0, ly = 0, lw = 0, lh = 0;
    00582     bool legend = findLegend(lx, ly, lw, lh);
    00583
    00584     if(legend) {
    00585         int yOff = ly + lh/2 - borderTop()/2;
    00586         h -= yOff;
    00587         _ty += yOff;
    00588     }
    00589     _ty -= borderTopExtra();
    00590
    00591     int my = QMAX(_ty,_y);
    00592     int end = QMIN( _y + _h,  _ty + h );
    00593     int mh = end - my;
    00594
    00595     paintBackground(p, style()->backgroundColor(), style()->backgroundImage(), my, mh, _tx, _ty, w, h);
    00596
    00597     if ( style()->hasBorder() ) {
    00598         if ( legend )
    00599             paintBorderMinusLegend(p, _tx, _ty, w, h, style(), lx, lw);
    00600         else
    00601             paintBorder(p, _tx, _ty, w, h, style());
    00602     }
    00603 }
    00604
    00605 void RenderFieldset::paintBorderMinusLegend(QPainter *p, int _tx, int _ty, int w, int h,
    00606                                             const RenderStyle* style, int lx, int lw)
    00607 {
    00608
    00609     const QColor& tc = style->borderTopColor();
    00610     const QColor& bc = style->borderBottomColor();
    00611
    00612     EBorderStyle ts = style->borderTopStyle();
    00613     EBorderStyle bs = style->borderBottomStyle();
    00614     EBorderStyle ls = style->borderLeftStyle();
    00615     EBorderStyle rs = style->borderRightStyle();
    00616
    00617     bool render_t = ts > BHIDDEN;
    00618     bool render_l = ls > BHIDDEN;
    00619     bool render_r = rs > BHIDDEN;
    00620     bool render_b = bs > BHIDDEN;
    00621
    00622     if(render_t) {
    00623         drawBorder(p, _tx, _ty, _tx + lx, _ty +  style->borderTopWidth(), BSTop, tc, style->color(), ts,
    00624                    (render_l && ls<=DOUBLE?style->borderLeftWidth():0), 0);
    00625         drawBorder(p, _tx+lx+lw, _ty, _tx + w, _ty +  style->borderTopWidth(), BSTop, tc, style->color(), ts,
    00626                    0, (render_r && rs<=DOUBLE?style->borderRightWidth():0));
    00627     }
    00628
    00629     if(render_b)
    00630         drawBorder(p, _tx, _ty + h - style->borderBottomWidth(), _tx + w, _ty + h, BSBottom, bc, style->color(), bs,
    00631                    (render_l && ls<=DOUBLE?style->borderLeftWidth():0),
    00632                    (render_r && rs<=DOUBLE?style->borderRightWidth():0));
    00633
    00634     if(render_l)
    00635     {
    00636         const QColor& lc = style->borderLeftColor();
    00637
    00638         bool ignore_top =
    00639           (tc == lc) &&
    00640           (ls <= OUTSET) &&
    00641           (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET);
    00642
    00643         bool ignore_bottom =
    00644           (bc == lc) &&
    00645           (ls <= OUTSET) &&
    00646           (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET);
    00647
    00648         drawBorder(p, _tx, _ty, _tx + style->borderLeftWidth(), _ty + h, BSLeft, lc, style->color(), ls,
    00649                    ignore_top?0:style->borderTopWidth(),
    00650                    ignore_bottom?0:style->borderBottomWidth());
    00651     }
    00652
    00653     if(render_r)
    00654     {
    00655         const QColor& rc = style->borderRightColor();
    00656
    00657         bool ignore_top =
    00658           (tc == rc) &&
    00659           (rs <= SOLID || rs == INSET) &&
    00660           (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET);
    00661
    00662         bool ignore_bottom =
    00663           (bc == rc) &&
    00664           (rs <= SOLID || rs == INSET) &&
    00665           (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET);
    00666
    00667         drawBorder(p, _tx + w - style->borderRightWidth(), _ty, _tx + w, _ty + h, BSRight, rc, style->color(), rs,
    00668                    ignore_top?0:style->borderTopWidth(),
    00669                    ignore_bottom?0:style->borderBottomWidth());
    00670     }
    00671 }
    00672
    00673 // -------------------------------------------------------------------------
    00674
    00675 RenderFileButton::RenderFileButton(HTMLInputElementImpl *element)
    00676     : RenderFormElement(element)
    00677 {
    00678     // this sucks, it creates a grey background
    00679     QHBox *w = new QHBox(view()->viewport());
    00680
    00681     m_edit = new LineEditWidget(w);
    00682
    00683     connect(m_edit, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
    00684     connect(m_edit, SIGNAL(textChanged(const QString &)),this,SLOT(slotTextChanged(const QString &)));
    00685
    00686     m_button = new QPushButton(i18n("Browse..."), w);
    00687     m_button->setFocusPolicy(QWidget::ClickFocus);
    00688     connect(m_button,SIGNAL(clicked()), this, SLOT(slotClicked()));
    00689     connect(m_button, SIGNAL(pressed()), this, SLOT(slotPressed()));
    00690     connect(m_button, SIGNAL(released()), this, SLOT(slotReleased()));
    00691
    00692     w->setStretchFactor(m_edit, 2);
    00693     w->setFocusProxy(m_edit);
    00694
    00695     setQWidget(w);
    00696     m_haveFocus = false;
    00697 }
    00698
    00699 void RenderFileButton::calcMinMaxWidth()
    00700 {
    00701     KHTMLAssert( !minMaxKnown() );
    00702
    00703     const QFontMetrics &fm = style()->fontMetrics();
    00704     int size = element()->size();
    00705
    00706     int h = fm.lineSpacing();
    00707     int w = fm.width( 'x' ) * (size > 0 ? size : 17); // "some"
    00708     QSize s = m_edit->style().sizeFromContents(QStyle::CT_LineEdit, m_edit,
    00709           QSize(w + 2 + 2*m_edit->frameWidth(), kMax(h, 14) + 2 + 2*m_edit->frameWidth()))
    00710         .expandedTo(QApplication::globalStrut());
    00711     QSize bs = m_button->sizeHint();
    00712
    00713     setIntrinsicWidth( s.width() + bs.width() );
    00714     setIntrinsicHeight( kMax(s.height(), bs.height()) );
    00715
    00716     RenderFormElement::calcMinMaxWidth();
    00717 }
    00718
    00719 void RenderFileButton::handleFocusOut()
    00720 {
    00721     if ( m_edit && m_edit->edited() ) {
    00722         element()->onChange();
    00723         m_edit->setEdited( false );
    00724     }
    00725 }
    00726
    00727 void RenderFileButton::slotClicked()
    00728 {
    00729     QString file_name = KFileDialog::getOpenFileName(QString::null, QString::null, 0, i18n("Browse"));
    00730     if (!file_name.isNull()) {
    00731         element()->m_value = DOMString(file_name);
    00732         m_edit->setText(file_name);
    00733     }
    00734 }
    00735
    00736 void RenderFileButton::updateFromElement()
    00737 {
    00738     m_edit->blockSignals(true);
    00739     m_edit->setText(element()->value().string());
    00740     m_edit->blockSignals(false);
    00741     int ml = element()->maxLength();
    00742     if ( ml < 0 || ml > 1024 )
    00743         ml = 1024;
    00744     m_edit->setMaxLength( ml );
    00745     m_edit->setEdited( false );
    00746
    00747     RenderFormElement::updateFromElement();
    00748 }
    00749
    00750 void RenderFileButton::slotReturnPressed()
    00751 {
    00752     if (element()->form())
    00753         element()->form()->submitFromKeyboard();
    00754 }
    00755
    00756 void RenderFileButton::slotTextChanged(const QString &string)
    00757 {
    00758    element()->m_value = DOMString(string);
    00759 }
    00760
    00761 void RenderFileButton::select()
    00762 {
    00763     m_edit->selectAll();
    00764 }
    00765
    00766 // -------------------------------------------------------------------------
    00767
    00768 RenderLabel::RenderLabel(HTMLGenericFormElementImpl *element)
    00769     : RenderFormElement(element)
    00770 {
    00771
    00772 }
    00773
    00774 // -------------------------------------------------------------------------
    00775
    00776 RenderLegend::RenderLegend(HTMLGenericFormElementImpl *element)
    00777     : RenderFlow(element)
    00778 {
    00779     setInline(false);
    00780 }
    00781
    00782 // -------------------------------------------------------------------------------
    00783
    00784 ComboBoxWidget::ComboBoxWidget(QWidget *parent)
    00785     : KComboBox(false, parent)
    00786 {
    00787     setAutoMask(true);
    00788     if (listBox()) listBox()->installEventFilter(this);
    00789     setMouseTracking(true);
    00790 }
    00791
    00792 bool ComboBoxWidget::event(QEvent *e)
    00793 {
    00794     if (e->type()==QEvent::KeyPress)
    00795     {
    00796         QKeyEvent *ke = static_cast<QKeyEvent *>(e);
    00797         switch(ke->key())
    00798         {
    00799         case Key_Return:
    00800         case Key_Enter:
    00801             popup();
    00802             ke->accept();
    00803             return true;
    00804         default:
    00805             return KComboBox::event(e);
    00806         }
    00807     }
    00808     return KComboBox::event(e);
    00809 }
    00810
    00811 bool ComboBoxWidget::eventFilter(QObject *dest, QEvent *e)
    00812 {
    00813     if (dest==listBox() &&  e->type()==QEvent::KeyPress)
    00814     {
    00815         QKeyEvent *ke = static_cast<QKeyEvent *>(e);
    00816         bool forward = false;
    00817         switch(ke->key())
    00818         {
    00819         case Key_Tab:
    00820             forward=true;
    00821         case Key_BackTab:
    00822             // ugly hack. emulate popdownlistbox() (private in QComboBox)
    00823             // we re-use ke here to store the reference to the generated event.
    00824             ke = new QKeyEvent(QEvent::KeyPress, Key_Escape, 0, 0);
    00825             QApplication::sendEvent(dest,ke);
    00826             focusNextPrevChild(forward);
    00827             delete ke;
    00828             return true;
    00829         default:
    00830             return KComboBox::eventFilter(dest, e);
    00831         }
    00832     }
    00833     return KComboBox::eventFilter(dest, e);
    00834 }
    00835
    00836 // -------------------------------------------------------------------------
    00837
    00838 RenderSelect::RenderSelect(HTMLSelectElementImpl *element)
    00839     : RenderFormElement(element)
    00840 {
    00841     m_ignoreSelectEvents = false;
    00842     m_multiple = element->multiple();
    00843     m_size = element->size();
    00844     m_useListBox = (m_multiple || m_size > 1);
    00845     m_selectionChanged = true;
    00846     m_optionsChanged = true;
    00847
    00848     if(m_useListBox)
    00849         setQWidget(createListBox());
    00850     else
    00851         setQWidget(createComboBox());
    00852 }
    00853
    00854 void RenderSelect::updateFromElement()
    00855 {
    00856     m_ignoreSelectEvents = true;
    00857
    00858     // change widget type
    00859     bool oldMultiple = m_multiple;
    00860     unsigned oldSize = m_size;
    00861     bool oldListbox = m_useListBox;
    00862
    00863     m_multiple = element()->multiple();
    00864     m_size = element()->size();
    00865     m_useListBox = (m_multiple || m_size > 1);
    00866
    00867     if (oldMultiple != m_multiple || oldSize != m_size) {
    00868         if (m_useListBox != oldListbox) {
    00869             // type of select has changed
    00870             if(m_useListBox)
    00871                 setQWidget(createListBox());
    00872             else
    00873                 setQWidget(createComboBox());
    00874         }
    00875
    00876         if (m_useListBox && oldMultiple != m_multiple) {
    00877             static_cast<KListBox*>(m_widget)->setSelectionMode(m_multiple ? QListBox::Extended : QListBox::Single);
    00878         }
    00879         m_selectionChanged = true;
    00880         m_optionsChanged = true;
    00881     }
    00882
    00883     // update contents listbox/combobox based on options in m_element
    00884     if ( m_optionsChanged ) {
    00885         if (element()->m_recalcListItems)
    00886             element()->recalcListItems();
    00887         QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
    00888         int listIndex;
    00889
    00890         if(m_useListBox) {
    00891             static_cast<KListBox*>(m_widget)->clear();
    00892         }
    00893
    00894         else
    00895             static_cast<KComboBox*>(m_widget)->clear();
    00896
    00897         for (listIndex = 0; listIndex < int(listItems.size()); listIndex++) {
    00898             if (listItems[listIndex]->id() == ID_OPTGROUP) {
    00899                 DOMString text = listItems[listIndex]->getAttribute(ATTR_LABEL);
    00900                 if (text.isNull())
    00901                     text = "";
    00902
    00903                 if(m_useListBox) {
    00904                     QListBoxText *item = new QListBoxText(QString(text.implementation()->s, text.implementation()->l));
    00905                     static_cast<KListBox*>(m_widget)
    00906                         ->insertItem(item, listIndex);
    00907                     item->setSelectable(false);
    00908                 }
    00909                 else
    00910                     static_cast<KComboBox*>(m_widget)
    00911                         ->insertItem(QString(text.implementation()->s, text.implementation()->l), listIndex);
    00912             }
    00913             else if (listItems[listIndex]->id() == ID_OPTION) {
    00914                 HTMLOptionElementImpl* optElem = static_cast<HTMLOptionElementImpl*>(listItems[listIndex]);
    00915                 QString text = optElem->text().string();
    00916                 if (optElem->parentNode()->id() == ID_OPTGROUP)
    00917                 {
    00918                     // Prefer label if set
    00919                     DOMString label = optElem->getAttribute(ATTR_LABEL);
    00920                     if (!label.isEmpty())
    00921                         text = label.string();
    00922                     text = QString::fromLatin1("    ")+text;
    00923                 }
    00924
    00925                 if(m_useListBox)
    00926                     static_cast<KListBox*>(m_widget)->insertItem(text, listIndex);
    00927                 else
    00928                     static_cast<KComboBox*>(m_widget)->insertItem(text, listIndex);
    00929             }
    00930             else
    00931                 KHTMLAssert(false);
    00932             m_selectionChanged = true;
    00933         }
    00934         setMinMaxKnown(false);
    00935         setLayouted(false);
    00936         m_optionsChanged = false;
    00937     }
    00938
    00939     // update selection
    00940     if (m_selectionChanged) {
    00941         updateSelection();
    00942     }
    00943
    00944
    00945     m_ignoreSelectEvents = false;
    00946
    00947     RenderFormElement::updateFromElement();
    00948 }
    00949
    00950 void RenderSelect::calcMinMaxWidth()
    00951 {
    00952     KHTMLAssert( !minMaxKnown() );
    00953
    00954     if (m_optionsChanged)
    00955         updateFromElement();
    00956
    00957     // ### ugly HACK FIXME!!!
    00958     setMinMaxKnown();
    00959     if ( !layouted() )
    00960         layout();
    00961     setLayouted( false );
    00962     setMinMaxKnown( false );
    00963     // ### end FIXME
    00964
    00965     RenderFormElement::calcMinMaxWidth();
    00966 }
    00967
    00968 void RenderSelect::layout( )
    00969 {
    00970     KHTMLAssert(!layouted());
    00971     KHTMLAssert(minMaxKnown());
    00972
    00973     // ### maintain selection properly between type/size changes, and work
    00974     // out how to handle multiselect->singleselect (probably just select
    00975     // first selected one)
    00976
    00977     // calculate size
    00978     if(m_useListBox) {
    00979         KListBox* w = static_cast<KListBox*>(m_widget);
    00980
    00981         QListBoxItem* p = w->firstItem();
    00982         int width = 0;
    00983         int height = 0;
    00984         while(p) {
    00985             width = QMAX(width, p->width(p->listBox()));
    00986             height = QMAX(height, p->height(p->listBox()));
    00987             p = p->next();
    00988         }
    00989
    00990         int size = m_size;
    00991         // check if multiple and size was not given or invalid
    00992         // Internet Exploder sets size to QMIN(number of elements, 4)
    00993         // Netscape seems to simply set it to "number of elements"
    00994         // the average of that is IMHO QMIN(number of elements, 10)
    00995         // so I did that ;-)
    00996         if(size < 1)
    00997             size = QMIN(static_cast<KListBox*>(m_widget)->count(), 10);
    00998
    00999         width += 2*w->frameWidth() + w->verticalScrollBar()->sizeHint().width();
    01000         height = size*height + 2*w->frameWidth();
    01001
    01002         setIntrinsicWidth( width );
    01003         setIntrinsicHeight( height );
    01004     }
    01005     else {
    01006         QSize s(m_widget->sizeHint());
    01007         setIntrinsicWidth( s.width() );
    01008         setIntrinsicHeight( s.height() );
    01009     }
    01010
    01012     setLayouted( false );
    01013     RenderFormElement::layout();
    01014
    01015     // and now disable the widget in case there is no <option> given
    01016     QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
    01017
    01018     bool foundOption = false;
    01019     for (uint i = 0; i < listItems.size() && !foundOption; i++)
    01020         foundOption = (listItems[i]->id() == ID_OPTION);
    01021
    01022     m_widget->setEnabled(foundOption && ! element()->disabled());
    01023 }
    01024
    01025 void RenderSelect::slotSelected(int index) // emitted by the combobox only
    01026 {
    01027     if ( m_ignoreSelectEvents ) return;
    01028
    01029     KHTMLAssert( !m_useListBox );
    01030
    01031     QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
    01032     if(index >= 0 && index < int(listItems.size()))
    01033     {
    01034         bool found = ( listItems[index]->id() == ID_OPTION );
    01035
    01036         if ( !found ) {
    01037             // this one is not selectable,  we need to find an option element
    01038             while ( ( unsigned ) index < listItems.size() ) {
    01039                 if ( listItems[index]->id() == ID_OPTION ) {
    01040                     found = true;
    01041                     break;
    01042                 }
    01043                 ++index;
    01044             }
    01045
    01046             if ( !found ) {
    01047                 while ( index >= 0 ) {
    01048                     if ( listItems[index]->id() == ID_OPTION ) {
    01049                         found = true;
    01050                         break;
    01051                     }
    01052                     --index;
    01053                 }
    01054             }
    01055         }
    01056
    01057         if ( found ) {
    01058             bool changed = false;
    01059
    01060             for ( unsigned int i = 0; i < listItems.size(); ++i )
    01061                 if ( listItems[i]->id() == ID_OPTION && i != (unsigned int) index )
    01062                 {
    01063                     HTMLOptionElementImpl* opt = static_cast<HTMLOptionElementImpl*>( listItems[i] );
    01064                     changed |= (opt->m_selected == true);
    01065                     opt->m_selected = false;
    01066                 }
    01067
    01068             HTMLOptionElementImpl* opt = static_cast<HTMLOptionElementImpl*>(listItems[index]);
    01069             changed |= (opt->m_selected == false);
    01070             opt->m_selected = true;
    01071
    01072             if ( index != static_cast<ComboBoxWidget*>( m_widget )->currentItem() )
    01073                 static_cast<ComboBoxWidget*>( m_widget )->setCurrentItem( index );
    01074
    01075             // When selecting an optgroup item, and we move forward to we
    01076             // shouldn't emit onChange. Hence this bool, the if above doesn't do it.
    01077             if ( changed )
    01078             {
    01079                 ref();
    01080                 element()->onChange();
    01081                 deref();
    01082             }
    01083         }
    01084     }
    01085 }
    01086
    01087
    01088 void RenderSelect::slotSelectionChanged() // emitted by the listbox only
    01089 {
    01090     if ( m_ignoreSelectEvents ) return;
    01091
    01092     // don't use listItems() here as we have to avoid recalculations - changing the
    01093     // option list will make use update options not in the way the user expects them
    01094     QMemArray<HTMLGenericFormElementImpl*> listItems = element()->m_listItems;
    01095     for ( unsigned i = 0; i < listItems.count(); i++ )
    01096         // don't use setSelected() here because it will cause us to be called
    01097         // again with updateSelection.
    01098         if ( listItems[i]->id() == ID_OPTION )
    01099             static_cast<HTMLOptionElementImpl*>( listItems[i] )
    01100                 ->m_selected = static_cast<KListBox*>( m_widget )->isSelected( i );
    01101
    01102     ref();
    01103     element()->onChange();
    01104     deref();
    01105 }
    01106
    01107 void RenderSelect::setOptionsChanged(bool _optionsChanged)
    01108 {
    01109     m_optionsChanged = _optionsChanged;
    01110 }
    01111
    01112 KListBox* RenderSelect::createListBox()
    01113 {
    01114     KListBox *lb = new KListBox(view()->viewport());
    01115     lb->setSelectionMode(m_multiple ? QListBox::Extended : QListBox::Single);
    01116     // ### looks broken
    01117     //lb->setAutoMask(true);
    01118     connect( lb, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) );
    01119     connect( lb, SIGNAL( clicked( QListBoxItem * ) ), this, SLOT( slotClicked() ) );
    01120     m_ignoreSelectEvents = false;
    01121     lb->setMouseTracking(true);
    01122
    01123     return lb;
    01124 }
    01125
    01126 ComboBoxWidget *RenderSelect::createComboBox()
    01127 {
    01128     ComboBoxWidget *cb = new ComboBoxWidget(view()->viewport());
    01129     connect(cb, SIGNAL(activated(int)), this, SLOT(slotSelected(int)));
    01130     return cb;
    01131 }
    01132
    01133 void RenderSelect::updateSelection()
    01134 {
    01135     QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
    01136     int i;
    01137     if (m_useListBox) {
    01138         // if multi-select, we select only the new selected index
    01139         KListBox *listBox = static_cast<KListBox*>(m_widget);
    01140         for (i = 0; i < int(listItems.size()); i++)
    01141             listBox->setSelected(i,listItems[i]->id() == ID_OPTION &&
    01142                                 static_cast<HTMLOptionElementImpl*>(listItems[i])->selected());
    01143     }
    01144     else {
    01145         bool found = false;
    01146         unsigned firstOption = listItems.size();
    01147         i = listItems.size();
    01148         while (i--)
    01149             if (listItems[i]->id() == ID_OPTION) {
    01150                 if (found)
    01151                     static_cast<HTMLOptionElementImpl*>(listItems[i])->m_selected = false;
    01152                 else if (static_cast<HTMLOptionElementImpl*>(listItems[i])->selected()) {
    01153                     static_cast<KComboBox*>( m_widget )->setCurrentItem(i);
    01154                     found = true;
    01155                 }
    01156                 firstOption = i;
    01157             }
    01158
    01159         Q_ASSERT(firstOption == listItems.size() || found);
    01160     }
    01161
    01162     m_selectionChanged = false;
    01163 }
    01164
    01165
    01166 // -------------------------------------------------------------------------
    01167
    01168 TextAreaWidget::TextAreaWidget(int wrap, QWidget* parent)
    01169     : KTextEdit(parent)
    01170 {
    01171     if(wrap != DOM::HTMLTextAreaElementImpl::ta_NoWrap) {
    01172         setWordWrap(QTextEdit::WidgetWidth);
    01173         setHScrollBarMode( AlwaysOff );
    01174         setVScrollBarMode( AlwaysOn );
    01175     }
    01176     else {
    01177         setWordWrap(QTextEdit::NoWrap);
    01178         setHScrollBarMode( Auto );
    01179         setVScrollBarMode( Auto );
    01180     }
    01181     KCursor::setAutoHideCursor(viewport(), true);
    01182     setTextFormat(QTextEdit::PlainText);
    01183     setAutoMask(true);
    01184     setMouseTracking(true);
    01185 }
    01186
    01187 bool TextAreaWidget::event( QEvent *e )
    01188 {
    01189     if ( e->type() == QEvent::AccelAvailable && isReadOnly() ) {
    01190         QKeyEvent* ke = (QKeyEvent*) e;
    01191         if ( ke->state() & ControlButton ) {
    01192             switch ( ke->key() ) {
    01193                 case Key_Left:
    01194                 case Key_Right:
    01195                 case Key_Up:
    01196                 case Key_Down:
    01197                 case Key_Home:
    01198                 case Key_End:
    01199                     ke->accept();
    01200                 default:
    01201                 break;
    01202             }
    01203         }
    01204     }
    01205     return KTextEdit::event( e );
    01206 }
    01207
    01208 // -------------------------------------------------------------------------
    01209
    01210 RenderTextArea::RenderTextArea(HTMLTextAreaElementImpl *element)
    01211     : RenderFormElement(element)
    01212 {
    01213     TextAreaWidget *edit = new TextAreaWidget(element->wrap(), view());
    01214     setQWidget(edit);
    01215
    01216     connect(edit,SIGNAL(textChanged()),this,SLOT(slotTextChanged()));
    01217 }
    01218
    01219 RenderTextArea::~RenderTextArea()
    01220 {
    01221     if ( element()->m_dirtyvalue ) {
    01222         element()->m_value = text();
    01223         element()->m_dirtyvalue = false;
    01224     }
    01225 }
    01226
    01227 void RenderTextArea::handleFocusOut()
    01228 {
    01229     TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget);
    01230     if ( w && element()->m_dirtyvalue ) {
    01231         element()->m_value = text();
    01232         element()->m_dirtyvalue = false;
    01233         element()->onChange();
    01234     }
    01235 }
    01236
    01237 void RenderTextArea::calcMinMaxWidth()
    01238 {
    01239     KHTMLAssert( !minMaxKnown() );
    01240
    01241     TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget);
    01242     const QFontMetrics &m = style()->fontMetrics();
    01243     w->setTabStopWidth(8 * m.width(" "));
    01244     QSize size( QMAX(element()->cols(), 1)*m.width('x') + w->frameWidth() +
    01245                 w->verticalScrollBar()->sizeHint().width(),
    01246                 QMAX(element()->rows(), 1)*m.lineSpacing() + w->frameWidth()*4 +
    01247                 (w->wordWrap() == QTextEdit::NoWrap ?
    01248                  w->horizontalScrollBar()->sizeHint().height() : 0)
    01249         );
    01250
    01251     setIntrinsicWidth( size.width() );
    01252     setIntrinsicHeight( size.height() );
    01253
    01254     RenderFormElement::calcMinMaxWidth();
    01255 }
    01256
    01257 void RenderTextArea::updateFromElement()
    01258 {
    01259     TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget);
    01260     w->setReadOnly(element()->readOnly());
    01261     QString elementText = element()->value().string();
    01262     if ( elementText != text() )
    01263     {
    01264         w->blockSignals(true);
    01265         int line, col;
    01266         w->getCursorPosition( &line, &col );
    01267         w->setText( elementText );
    01268         w->setCursorPosition( line, col );
    01269         w->blockSignals(false);
    01270     }
    01271     element()->m_dirtyvalue = false;
    01272
    01273     RenderFormElement::updateFromElement();
    01274 }
    01275
    01276 void RenderTextArea::close( )
    01277 {
    01278     element()->setValue( element()->defaultValue() );
    01279
    01280     RenderFormElement::close();
    01281 }
    01282
    01283 QString RenderTextArea::text()
    01284 {
    01285     QString txt;
    01286     TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget);
    01287
    01288     if(element()->wrap() == DOM::HTMLTextAreaElementImpl::ta_Physical) {
    01289         // yeah, QTextEdit has no accessor for getting the visually wrapped text
    01290         for (int p=0; p < w->paragraphs(); ++p) {
    01291             int pl = w->paragraphLength(p);
    01292             int ll = 0;
    01293             int lindex = w->lineOfChar(p, 0);
    01294             QString paragraphText = w->text(p);
    01295             for (int l = 0; l < pl; ++l) {
    01296                 if (lindex != w->lineOfChar(p, l)) {
    01297                     paragraphText.insert(l+ll++, QString::fromLatin1("\n"));
    01298                     lindex = w->lineOfChar(p, l);
    01299                 }
    01300             }
    01301             txt += paragraphText;
    01302             if (p < w->paragraphs() - 1)
    01303                 txt += QString::fromLatin1("\n");
    01304         }
    01305     }
    01306     else
    01307         txt = w->text();
    01308
    01309     return txt;
    01310 }
    01311
    01312 void RenderTextArea::slotTextChanged()
    01313 {
    01314     element()->m_dirtyvalue = true;
    01315 }
    01316
    01317 void RenderTextArea::select()
    01318 {
    01319     static_cast<TextAreaWidget *>(m_widget)->selectAll();
    01320 }
    01321
    01322 // ---------------------------------------------------------------------------
    01323
    01324 #include "render_form.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