📄 render_form.cpp
字号:
void RenderSubmitButton::updateFromElement()
{
QPushButton *w = static_cast<QPushButton*>(m_widget);
QString oldText = w->text();
QString newText = rawText();
w->setText(newText);
if ( oldText != newText )
setNeedsLayoutAndMinMaxRecalc();
RenderFormElement::updateFromElement();
}
short RenderSubmitButton::baselinePosition( bool f, bool isRootLineBox ) const
{
return RenderFormElement::baselinePosition( f, isRootLineBox );
}
// -------------------------------------------------------------------------------
RenderImageButton::RenderImageButton(HTMLInputElementImpl *element)
: RenderImage(element)
{
// ### support DOMActivate event when clicked
}
#ifdef NOKIA_CHANGES
int RenderImageButton::calcReplacedWidth() const
{
int zoom(canvas()->view()->scalingFactor());
int width = RenderBox::calcReplacedWidth();
Length w = style()->width();
switch(w.type) {
case Fixed:
case Variable:
width = width*100/zoom;
}
return width;
}
int RenderImageButton::calcReplacedHeight() const
{
int zoom(canvas()->view()->scalingFactor());
int height = RenderBox::calcReplacedHeight();
Length h = style()->width();
switch(h.type) {
case Fixed:
case Variable:
height = height*100/zoom;
}
return height;
}
void RenderImageButton::getRenderersInRect(QPtrList<BoxInfo>& boxInfoList,int deltaX,int deltaY,const QRect& rect)
{
deltaX += m_x;
deltaY += m_y;
QRect absoluteBoxRect = QRect(deltaX, deltaY, m_width, m_height);
if(!rect.intersects(absoluteBoxRect))
return;
BoxInfo* imageButton = new BoxInfo;
imageButton->renderObject = this;
imageButton->absoluteXPos = deltaX;
imageButton->absoluteYPos = deltaY;
imageButton->width = m_width;
imageButton->height = m_height;
imageButton->area = 0;
boxInfoList.append(imageButton);
}
#endif
// -------------------------------------------------------------------------------
// FIXME: No real reason to need separate classes for RenderResetButton and
// RenderSubmitButton now that the default label is handled on the DOM side.
RenderResetButton::RenderResetButton(HTMLInputElementImpl *element)
: RenderSubmitButton(element)
{
}
// -------------------------------------------------------------------------------
// FIXME: No real reason to need separate classes for RenderPushButton and
// RenderSubmitButton now that the default label is handled on the DOM side.
RenderPushButton::RenderPushButton(HTMLInputElementImpl *element)
: RenderSubmitButton(element)
{
}
// -------------------------------------------------------------------------------
#if !APPLE_CHANGES
LineEditWidget::LineEditWidget(QWidget *parent)
: KLineEdit(parent)
{
setMouseTracking(true);
}
bool LineEditWidget::event( QEvent *e )
{
if ( e->type() == QEvent::AccelAvailable && isReadOnly() ) {
QKeyEvent* ke = (QKeyEvent*) e;
if ( ke->state() & ControlButton ) {
switch ( ke->key() ) {
case Key_Left:
case Key_Right:
case Key_Up:
case Key_Down:
case Key_Home:
case Key_End:
ke->accept();
default:
break;
}
}
}
return KLineEdit::event( e );
}
#endif
// -----------------------------------------------------------------------------
RenderLineEdit::RenderLineEdit(HTMLInputElementImpl *element)
: RenderFormElement(element), m_updating(false)
{
#if APPLE_CHANGES
QLineEdit::Type type;
switch (element->inputType()) {
case HTMLInputElementImpl::PASSWORD:
type = QLineEdit::Password;
break;
case HTMLInputElementImpl::SEARCH:
type = QLineEdit::Search;
break;
default:
type = QLineEdit::Normal;
}
KLineEdit *edit = new KLineEdit(type);
if (type == QLineEdit::Search)
edit->setLiveSearch(false);
#else
LineEditWidget *edit = new LineEditWidget(view()->viewport());
#endif
connect(edit,SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
connect(edit,SIGNAL(textChanged(const QString &)),this,SLOT(slotTextChanged(const QString &)));
connect(edit,SIGNAL(clicked()),this,SLOT(slotClicked()));
#if APPLE_CHANGES
connect(edit,SIGNAL(performSearch()), this, SLOT(slotPerformSearch()));
#endif
#if !APPLE_CHANGES
if(element->inputType() == HTMLInputElementImpl::PASSWORD)
edit->setEchoMode( QLineEdit::Password );
if ( element->autoComplete() ) {
QStringList completions = view()->formCompletionItems(element->name().string());
if (completions.count()) {
edit->completionObject()->setItems(completions);
edit->setContextMenuEnabled(true);
}
}
#endif
setQWidget(edit);
}
void RenderLineEdit::slotReturnPressed()
{
#if !APPLE_CHANGES
// don't submit the form when return was pressed in a completion-popup
KCompletionBox *box = widget()->completionBox(false);
if ( box && box->isVisible() && box->currentItem() != -1 )
return;
#endif
// Emit onChange if necessary
// Works but might not be enough, dirk said he had another solution at
// hand (can't remember which) - David
handleFocusOut();
HTMLFormElementImpl* fe = element()->form();
if ( fe )
fe->submitClick();
}
#if APPLE_CHANGES
void RenderLineEdit::slotPerformSearch()
{
// Fire the "search" DOM event.
element()->dispatchHTMLEvent(EventImpl::SEARCH_EVENT, true, false);
}
void RenderLineEdit::addSearchResult()
{
if (widget())
widget()->addSearchResult();
}
#endif
void RenderLineEdit::handleFocusOut()
{
if ( widget() && widget()->edited() ) {
element()->onChange();
widget()->setEdited( false );
}
}
void RenderLineEdit::calcMinMaxWidth()
{
KHTMLAssert( !minMaxKnown() );
#if APPLE_CHANGES
// Let the widget tell us how big it wants to be.
m_updating = true;
int size = element()->size();
QSize s(widget()->sizeForCharacterWidth(size > 0 ? size : 20));
m_updating = false;
#else
const QFontMetrics &fm = style()->fontMetrics();
QSize s;
int size = element()->size();
int h = fm.lineSpacing();
int w = fm.width( 'x' ) * (size > 0 ? size : 17); // "some"
s = QSize(w + 2 + 2*widget()->frameWidth(),
QMAX(h, 14) + 2 + 2*widget()->frameWidth())
.expandedTo(QApplication::globalStrut());
#endif
setIntrinsicWidth( s.width() );
setIntrinsicHeight( s.height() );
RenderFormElement::calcMinMaxWidth();
}
void RenderLineEdit::setStyle(RenderStyle *s)
{
RenderFormElement::setStyle(s);
KLineEdit *w = widget();
w->setAlignment(textAlignment());
#if APPLE_CHANGES
w->setWritingDirection(style()->direction() == RTL ? QPainter::RTL : QPainter::LTR);
#endif
}
void RenderLineEdit::updateFromElement()
{
HTMLInputElementImpl *e = element();
KLineEdit *w = widget();
int ml = e->maxLength();
if ( ml <= 0 || ml > 1024 )
ml = 1024;
if ( w->maxLength() != ml )
w->setMaxLength( ml );
if (!e->valueMatchesRenderer()) {
QString widgetText = w->text();
QString newText = e->value().string();
newText.replace(QChar('\\'), backslashAsCurrencySymbol());
if (widgetText != newText) {
w->blockSignals(true);
int pos = w->cursorPosition();
m_updating = true;
w->setText(newText);
m_updating = false;
w->setEdited( false );
w->setCursorPosition(pos);
w->blockSignals(false);
}
e->setValueMatchesRenderer();
}
w->setReadOnly(e->readOnly());
#if APPLE_CHANGES
// Handle updating the search attributes.
w->setPlaceholderString(e->getAttribute(ATTR_PLACEHOLDER).string());
if (w->type() == QLineEdit::Search) {
w->setLiveSearch(!e->getAttribute(ATTR_INCREMENTAL).isNull());
w->setAutoSaveName(e->getAttribute(ATTR_AUTOSAVE).string());
w->setMaxResults(e->maxResults());
}
#endif
RenderFormElement::updateFromElement();
}
void RenderLineEdit::slotTextChanged(const QString &string)
{
if (m_updating) // Don't alter the value if we are in the middle of initing the control, since
return; // we are getting the value from the DOM and it's not user input.
// A null string value is used to indicate that the form control has not altered the original
// default value. That means that we should never use the null string value when the user
// empties a textfield, but should always force an empty textfield to use the empty string.
QString newText = string.isNull() ? "" : string;
newText.replace(backslashAsCurrencySymbol(), QChar('\\'));
element()->setValueFromRenderer(newText);
}
void RenderLineEdit::select()
{
static_cast<KLineEdit*>(m_widget)->selectAll();
}
// ---------------------------------------------------------------------------
RenderFieldset::RenderFieldset(HTMLGenericFormElementImpl *element)
: RenderBlock(element)
{
}
RenderObject* RenderFieldset::layoutLegend(bool relayoutChildren)
{
RenderObject* legend = findLegend();
if (legend) {
if (relayoutChildren)
legend->setNeedsLayout(true);
legend->layoutIfNeeded();
int xPos = borderLeft() + paddingLeft() + legend->marginLeft();
if (style()->direction() == RTL)
xPos = m_width - paddingRight() - borderRight() - legend->width() - legend->marginRight();
int b = borderTop();
int h = legend->height();
legend->setPos(xPos, QMAX((b-h)/2, 0));
m_height = QMAX(b,h) + paddingTop();
}
return legend;
}
RenderObject* RenderFieldset::findLegend()
{
for (RenderObject* legend = firstChild(); legend; legend = legend->nextSibling()) {
if (!legend->isFloatingOrPositioned() && legend->element() &&
legend->element()->id() == ID_LEGEND)
return legend;
}
return 0;
}
void RenderFieldset::paintBoxDecorations(PaintInfo& i, int _tx, int _ty)
{
//kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl;
int w = width();
int h = height() + borderTopExtra() + borderBottomExtra();
RenderObject* legend = findLegend();
if (!legend)
return RenderBlock::paintBoxDecorations(i, _tx, _ty);
int yOff = (legend->yPos() > 0) ? 0 : (legend->height()-borderTop())/2;
h -= yOff;
_ty += yOff - borderTopExtra();
int my = kMax(_ty, i.r.y());
int end = kMin(i.r.y() + i.r.height(), _ty + h);
int mh = end - my;
paintBackground(i.p, style()->backgroundColor(), style()->backgroundLayers(), my, mh, _tx, _ty, w, h);
if (style()->hasBorder())
paintBorderMinusLegend(i.p, _tx, _ty, w, h, style(), legend->xPos(), legend->width());
}
void RenderFieldset::paintBorderMinusLegend(QPainter *p, int _tx, int _ty, int w, int h,
const RenderStyle* style, int lx, int lw)
{
const QColor& tc = style->borderTopColor();
const QColor& bc = style->borderBottomColor();
EBorderStyle ts = style->borderTopStyle();
EBorderStyle bs = style->borderBottomStyle();
EBorderStyle ls = style->borderLeftStyle();
EBorderStyle rs = style->borderRightStyle();
bool render_t = ts > BHIDDEN;
bool render_l = ls > BHIDDEN;
bool render_r = rs > BHIDDEN;
bool render_b = bs > BHIDDEN;
if(render_t) {
drawBorder(p, _tx, _ty, _tx + lx, _ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
(render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE)?style->borderLeftWidth():0), 0);
drawBorder(p, _tx+lx+lw, _ty, _tx + w, _ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
0, (render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE)?style->borderRightWidth():0));
}
if(render_b)
drawBorder(p, _tx, _ty + h - style->borderBottomWidth(), _tx + w, _ty + h, BSBottom, bc, style->color(), bs,
(render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE)?style->borderLeftWidth():0),
(render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE)?style->borderRightWidth():0));
if(render_l)
{
const QColor& lc = style->borderLeftColor();
bool ignore_top =
(tc == lc) &&
(ls >= OUTSET) &&
(ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET);
bool ignore_bottom =
(bc == lc) &&
(ls >= OUTSET) &&
(bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET);
drawBorder(p, _tx, _ty, _tx + style->borderLeftWidth(), _ty + h, BSLeft, lc, style->color(), ls,
ignore_top?0:style->borderTopWidth(),
ignore_bottom?0:style->borderBottomWidth());
}
if(render_r)
{
const QColor& rc = style->borderRightColor();
bool ignore_top =
(tc == rc) &&
(rs >= DOTTED || rs == INSET) &&
(ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET);
bool ignore_bottom =
(bc == rc) &&
(rs >= DOTTED || rs == INSET) &&
(bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET);
drawBorder(p, _tx + w - style->borderRightWidth(), _ty, _tx + w, _ty + h, BSRight, rc, style->color(), rs,
ignore_top?0:style->borderTopWidth(),
ignore_bottom?0:style->borderBottomWidth());
}
}
void RenderFieldset::setStyle(RenderStyle* _style)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -