📄 render_form.cpp
字号:
/* * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */#include <kdebug.h>#include <klocale.h>#include <kfiledialog.h>#include <kcompletionbox.h>#include <kcursor.h>#include <qstyle.h>#include "misc/helper.h"#include "xml/dom2_eventsimpl.h"#include "html/html_formimpl.h"#include "misc/htmlhashes.h"#include "rendering/render_form.h"#include <assert.h>#include "khtmlview.h"#include "khtml_ext.h"#include "xml/dom_docimpl.h"#include <kdebug.h>#if APPLE_CHANGES #include "KWQFileButton.h"#if !KWIQ#include "KWQSlider.h"#endif#endifusing namespace khtml;using namespace DOM;RenderFormElement::RenderFormElement(HTMLGenericFormElementImpl *element) : RenderWidget(element){#if KWIQ QOBJECT_TYPE(RenderFormElement);#endif // init RenderObject attributes setInline(true); // our object is Inline m_clickCount = 0; m_state = 0; m_button = 0; m_isDoubleClick = false;}RenderFormElement::~RenderFormElement(){}short RenderFormElement::baselinePosition( bool f, bool isRootLineBox ) const{#if APPLE_CHANGES return marginTop() + widget()->baselinePosition(m_height);#else return RenderWidget::baselinePosition( f, isRootLineBox ) - 2 - style()->fontMetrics().descent();#endif}void RenderFormElement::setStyle(RenderStyle* s){#if APPLE_CHANGES if (canHaveIntrinsicMargins()) addIntrinsicMarginsIfAllowed(s);#endif RenderWidget::setStyle(s);#if APPLE_CHANGES // Do not paint a background or border for Aqua form elements setShouldPaintBackgroundOrBorder(false);#endif m_widget->setFont(style()->font());}void RenderFormElement::updateFromElement(){ m_widget->setEnabled(!element()->disabled());#if !APPLE_CHANGES QColor color = style()->color(); QColor backgroundColor = style()->backgroundColor(); if ( color.isValid() || backgroundColor.isValid() ) { QPalette pal(m_widget->palette()); int contrast_ = KGlobalSettings::contrast(); int highlightVal = 100 + (2*contrast_+4)*16/10; int lowlightVal = 100 + (2*contrast_+4)*10; if (backgroundColor.isValid()) { for ( int i = 0; i < QPalette::NColorGroups; i++ ) { pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Background, backgroundColor ); pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Light, backgroundColor.light(highlightVal) ); pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Dark, backgroundColor.dark(lowlightVal) ); pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Mid, backgroundColor.dark(120) ); pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Midlight, backgroundColor.light(110) ); pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Button, backgroundColor ); pal.setColor( (QPalette::ColorGroup)i, QColorGroup::Base, backgroundColor ); } } if ( color.isValid() ) { struct ColorSet { QPalette::ColorGroup cg; QColorGroup::ColorRole cr; }; const struct ColorSet toSet [] = { { QPalette::Active, QColorGroup::Foreground }, { QPalette::Active, QColorGroup::ButtonText }, { QPalette::Active, QColorGroup::Text }, { QPalette::Inactive, QColorGroup::Foreground }, { QPalette::Inactive, QColorGroup::ButtonText }, { QPalette::Inactive, QColorGroup::Text }, { QPalette::Disabled,QColorGroup::ButtonText }, { QPalette::NColorGroups, QColorGroup::NColorRoles }, }; const ColorSet *set = toSet; while( set->cg != QPalette::NColorGroups ) { pal.setColor( set->cg, set->cr, color ); ++set; } QColor disfg = color; int h, s, v; disfg.hsv( &h, &s, &v ); if (v > 128) // dark bg, light fg - need a darker disabled fg disfg = disfg.dark(lowlightVal); else if (disfg != Qt::black) // light bg, dark fg - need a lighter disabled fg - but only if !black disfg = disfg.light(highlightVal); else // black fg - use darkgrey disabled fg disfg = Qt::darkGray; pal.setColor(QPalette::Disabled,QColorGroup::Foreground,disfg); } m_widget->setPalette(pal); } else m_widget->unsetPalette();#endif}void RenderFormElement::layout(){ KHTMLAssert( needsLayout() ); KHTMLAssert( minMaxKnown() ); // minimum height m_height = 0; calcWidth(); calcHeight();#if !APPLE_CHANGES if ( m_widget ) resizeWidget(m_widget, m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(), m_height-borderLeft()-borderRight()-paddingLeft()-paddingRight());#endif setNeedsLayout(false);}void RenderFormElement::slotClicked(){ RenderArena *arena = ref(); QMouseEvent e2( QEvent::MouseButtonRelease, m_mousePos, m_button, m_state); element()->dispatchMouseEvent(&e2, EventImpl::CLICK_EVENT, m_clickCount); // We also send the KHTML_CLICK or KHTML_DBLCLICK event for // CLICK. This is not part of the DOM specs, but is used for // compatibility with the traditional onclick="" and ondblclick="" // attributes, as there is no way to tell the difference between // single & double clicks using DOM (only the click count is // stored, which is not necessarily the same) element()->dispatchMouseEvent(&e2, m_isDoubleClick ? EventImpl::KHTML_DBLCLICK_EVENT : EventImpl::KHTML_CLICK_EVENT, m_clickCount); m_isDoubleClick = false; deref(arena);}Qt::AlignmentFlags RenderFormElement::textAlignment() const{ switch (style()->textAlign()) { case LEFT: case KHTML_LEFT: return AlignLeft; case RIGHT: case KHTML_RIGHT: return AlignRight; case CENTER: case KHTML_CENTER: return AlignHCenter; case JUSTIFY: // Just fall into the auto code for justify. case TAAUTO: return style()->direction() == RTL ? AlignRight : AlignLeft; } assert(false); // Should never be reached. return AlignLeft;}#if APPLE_CHANGESvoid RenderFormElement::addIntrinsicMarginsIfAllowed(RenderStyle* _style){ // Cut out the intrinsic margins completely if we end up using mini controls. if (_style->font().pixelSize() < 11) return; int m = intrinsicMargin(); if (_style->width().isVariable()) { if (_style->marginLeft().quirk) _style->setMarginLeft(Length(m, Fixed)); if (_style->marginRight().quirk) _style->setMarginRight(Length(m, Fixed)); } if (_style->height().isVariable()) { if (_style->marginTop().quirk) _style->setMarginTop(Length(m, Fixed)); if (_style->marginBottom().quirk) _style->setMarginBottom(Length(m, Fixed)); }}#endif// -------------------------------------------------------------------------RenderButton::RenderButton(HTMLGenericFormElementImpl *element) : RenderFormElement(element){#if KWIQ QOBJECT_TYPE(RenderButton);#endif}short RenderButton::baselinePosition( bool f, bool isRootLineBox ) const{#if APPLE_CHANGES return RenderFormElement::baselinePosition( f, isRootLineBox );#else return RenderWidget::baselinePosition( f, isRootLineBox ) - 2;#endif}// -------------------------------------------------------------------------------RenderCheckBox::RenderCheckBox(HTMLInputElementImpl *element) : RenderButton(element){#if KWIQ QOBJECT_TYPE(RenderCheckBox);#endif QCheckBox* b = new QCheckBox(view()->viewport()); b->setAutoMask(true); b->setMouseTracking(true); setQWidget(b); connect(b,SIGNAL(stateChanged(int)),this,SLOT(slotStateChanged(int))); connect(b, SIGNAL(clicked()), this, SLOT(slotClicked()));}void RenderCheckBox::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() );#if APPLE_CHANGES // Let the widget tell us how big it wants to be. QSize s(widget()->sizeHint());#else QCheckBox *cb = static_cast<QCheckBox *>( m_widget ); QSize s( cb->style().pixelMetric( QStyle::PM_IndicatorWidth ), cb->style().pixelMetric( QStyle::PM_IndicatorHeight ) );#endif setIntrinsicWidth( s.width() ); setIntrinsicHeight( s.height() ); RenderButton::calcMinMaxWidth();}void RenderCheckBox::updateFromElement(){ widget()->setChecked(element()->checked()); RenderButton::updateFromElement();}// From the Qt documentation:// state is 2 if the button is on, 1 if it is in the "no change" state or 0 if the button is off. void RenderCheckBox::slotStateChanged(int state){ element()->setChecked(state == 2);}// -------------------------------------------------------------------------------RenderRadioButton::RenderRadioButton(HTMLInputElementImpl *element) : RenderButton(element){#if KWIQ QOBJECT_TYPE(RenderRadioButton);#endif QRadioButton* b = new QRadioButton(view()->viewport()); b->setAutoMask(true); b->setMouseTracking(true); setQWidget(b); connect(b, SIGNAL(clicked()), this, SLOT(slotClicked()));}void RenderRadioButton::updateFromElement(){ widget()->setChecked(element()->checked()); RenderButton::updateFromElement();}void RenderRadioButton::slotClicked(){ element()->setChecked(true); // emit mouseClick event etc RenderButton::slotClicked();}void RenderRadioButton::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() );#if APPLE_CHANGES // Let the widget tell us how big it wants to be. QSize s(widget()->sizeHint());#else QRadioButton *rb = static_cast<QRadioButton *>( m_widget ); QSize s( rb->style().pixelMetric( QStyle::PM_ExclusiveIndicatorWidth ), rb->style().pixelMetric( QStyle::PM_ExclusiveIndicatorHeight ) );#endif setIntrinsicWidth( s.width() ); setIntrinsicHeight( s.height() ); RenderButton::calcMinMaxWidth();}// -------------------------------------------------------------------------------RenderSubmitButton::RenderSubmitButton(HTMLInputElementImpl *element) : RenderButton(element){ QPushButton* p = new QPushButton(view()->viewport()); setQWidget(p); p->setAutoMask(true); p->setMouseTracking(true); connect(p, SIGNAL(clicked()), this, SLOT(slotClicked()));}QString RenderSubmitButton::rawText(){ QString value = element()->value().isEmpty() ? defaultLabel() : element()->value().string(); value = value.stripWhiteSpace(); value.replace('\\', backslashAsCurrencySymbol());#if APPLE_CHANGES return value;#else QString raw; for(unsigned int i = 0; i < value.length(); i++) { raw += value[i]; if(value[i] == '&') raw += '&'; } return raw;#endif}void RenderSubmitButton::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() );#if APPLE_CHANGES // Let the widget tell us how big it wants to be. QSize s(widget()->sizeHint()); setIntrinsicWidth(s.width()); setIntrinsicHeight(s.height());#else QString raw = rawText(); QPushButton* pb = static_cast<QPushButton*>(m_widget); pb->setText(raw); pb->setFont(style()->font()); bool empty = raw.isEmpty(); if ( empty ) raw = QString::fromLatin1("XXXX"); QFontMetrics fm = pb->fontMetrics(); int margin = pb->style().pixelMetric( QStyle::PM_ButtonMargin, pb); QSize s(pb->style().sizeFromContents( QStyle::CT_PushButton, pb, fm.size( ShowPrefix, raw)) .expandedTo(QApplication::globalStrut())); setIntrinsicWidth( s.width() - margin / 2 ); setIntrinsicHeight( s.height() - margin / 2);#endif RenderButton::calcMinMaxWidth();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -