📄 render_form.cpp
字号:
else {
QSize s(m_widget->sizeHint());
setIntrinsicWidth( s.width() );
setIntrinsicHeight( s.height() );
}
/// uuh, ignore the following line..
setNeedsLayout(true);
RenderFormElement::layout();
// and now disable the widget in case there is no <option> given
QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
bool foundOption = false;
for (uint i = 0; i < listItems.size() && !foundOption; i++)
foundOption = (listItems[i]->id() == ID_OPTION);
m_widget->setEnabled(foundOption && ! element()->disabled());
}
void RenderSelect::slotSelected(int index)
{
if ( m_ignoreSelectEvents ) return;
KHTMLAssert( !m_useListBox );
QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
if(index >= 0 && index < int(listItems.size()))
{
bool found = ( listItems[index]->id() == ID_OPTION );
if ( !found ) {
// this one is not selectable, we need to find an option element
while ( ( unsigned ) index < listItems.size() ) {
if ( listItems[index]->id() == ID_OPTION ) {
found = true;
break;
}
++index;
}
if ( !found ) {
while ( index >= 0 ) {
if ( listItems[index]->id() == ID_OPTION ) {
found = true;
break;
}
--index;
}
}
}
if ( found ) {
if ( index != static_cast<ComboBoxWidget*>( m_widget )->currentItem() )
static_cast<ComboBoxWidget*>( m_widget )->setCurrentItem( index );
for ( unsigned int i = 0; i < listItems.size(); ++i )
if ( listItems[i]->id() == ID_OPTION && i != (unsigned int) index )
static_cast<HTMLOptionElementImpl*>( listItems[i] )->m_selected = false;
static_cast<HTMLOptionElementImpl*>(listItems[index])->m_selected = true;
}
}
element()->onChange();
}
void RenderSelect::slotSelectionChanged()
{
if ( m_ignoreSelectEvents ) return;
// don't use listItems() here as we have to avoid recalculations - changing the
// option list will make use update options not in the way the user expects them
QMemArray<HTMLGenericFormElementImpl*> listItems = element()->m_listItems;
for ( unsigned i = 0; i < listItems.count(); i++ )
// don't use setSelected() here because it will cause us to be called
// again with updateSelection.
if ( listItems[i]->id() == ID_OPTION )
static_cast<HTMLOptionElementImpl*>( listItems[i] )
->m_selected = static_cast<KListBox*>( m_widget )->isSelected( i );
element()->onChange();
}
void RenderSelect::setOptionsChanged(bool _optionsChanged)
{
m_optionsChanged = _optionsChanged;
}
KListBox* RenderSelect::createListBox()
{
KListBox *lb = new KListBox(view()->viewport());
lb->setSelectionMode(m_multiple ? QListBox::Extended : QListBox::Single);
// ### looks broken
//lb->setAutoMask(true);
connect( lb, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) );
connect( lb, SIGNAL( clicked( QListBoxItem * ) ), this, SLOT( slotClicked() ) );
m_ignoreSelectEvents = false;
lb->setMouseTracking(true);
return lb;
}
ComboBoxWidget *RenderSelect::createComboBox()
{
ComboBoxWidget *cb = new ComboBoxWidget(view()->viewport());
connect(cb, SIGNAL(activated(int)), this, SLOT(slotSelected(int)));
return cb;
}
void RenderSelect::updateSelection()
{
QMemArray<HTMLGenericFormElementImpl*> listItems = element()->listItems();
int i;
if (m_useListBox) {
// if multi-select, we select only the new selected index
KListBox *listBox = static_cast<KListBox*>(m_widget);
for (i = 0; i < int(listItems.size()); i++)
listBox->setSelected(i,listItems[i]->id() == ID_OPTION &&
static_cast<HTMLOptionElementImpl*>(listItems[i])->selected());
#ifdef NOKIA_CHANGES
listBox->doneSelectingItems();
#endif
}
else {
bool found = false;
unsigned firstOption = listItems.size();
i = listItems.size();
while (i--)
if (listItems[i]->id() == ID_OPTION) {
if (found)
static_cast<HTMLOptionElementImpl*>(listItems[i])->m_selected = false;
else if (static_cast<HTMLOptionElementImpl*>(listItems[i])->selected()) {
static_cast<KComboBox*>( m_widget )->setCurrentItem(i);
found = true;
}
firstOption = i;
}
Q_ASSERT(firstOption == listItems.size() || found);
}
m_selectionChanged = false;
}
// -------------------------------------------------------------------------
#if !APPLE_CHANGES
TextAreaWidget::TextAreaWidget(QWidget* parent)
: KTextEdit(parent)
{
}
bool TextAreaWidget::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 KTextEdit::event( e );
}
#endif
// -------------------------------------------------------------------------
RenderTextArea::RenderTextArea(HTMLTextAreaElementImpl *element)
: RenderFormElement(element), m_dirty(false)
{
#if APPLE_CHANGES
QTextEdit *edit = new KTextEdit(view());
#else
QTextEdit *edit = new TextAreaWidget(view());
#endif
if (element->wrap() != HTMLTextAreaElementImpl::ta_NoWrap)
edit->setWordWrap(QTextEdit::WidgetWidth);
else
edit->setWordWrap(QTextEdit::NoWrap);
#if !APPLE_CHANGES
KCursor::setAutoHideCursor(edit->viewport(), true);
edit->setTextFormat(QTextEdit::PlainText);
edit->setAutoMask(true);
edit->setMouseTracking(true);
#endif
setQWidget(edit);
connect(edit,SIGNAL(textChanged()),this,SLOT(slotTextChanged()));
connect(edit,SIGNAL(clicked()),this,SLOT(slotClicked()));
}
void RenderTextArea::detach()
{
element()->updateValue();
RenderFormElement::detach();
}
void RenderTextArea::handleFocusOut()
{
if ( m_dirty && element() ) {
element()->updateValue();
element()->onChange();
}
m_dirty = false;
}
void RenderTextArea::calcMinMaxWidth()
{
KHTMLAssert( !minMaxKnown() );
QTextEdit* w = static_cast<QTextEdit*>(m_widget);
#if APPLE_CHANGES
QSize size(w->sizeWithColumnsAndRows(QMAX(element()->cols(), 1), QMAX(element()->rows(), 1)));
#else
const QFontMetrics &m = style()->fontMetrics();
w->setTabStopWidth(8 * m.width(" "));
QSize size( QMAX(element()->cols(), 1)*m.width('x') + w->frameWidth() +
w->verticalScrollBar()->sizeHint().width(),
QMAX(element()->rows(), 1)*m.height() + w->frameWidth()*2 +
(w->wordWrap() == QTextEdit::NoWrap ?
w->horizontalScrollBar()->sizeHint().height() : 0)
);
#endif
setIntrinsicWidth( size.width() );
setIntrinsicHeight( size.height() );
RenderFormElement::calcMinMaxWidth();
}
void RenderTextArea::setStyle(RenderStyle *s)
{
RenderFormElement::setStyle(s);
QTextEdit* w = static_cast<QTextEdit*>(m_widget);
w->setAlignment(textAlignment());
#if APPLE_CHANGES
w->setWritingDirection(style()->direction() == RTL ? QPainter::RTL : QPainter::LTR);
#endif
QScrollView::ScrollBarMode scrollMode = QScrollView::Auto;
switch (style()->overflow()) {
case OAUTO:
case OMARQUEE: // makes no sense, map to auto
case OOVERLAY: // not implemented for text, map to auto
case OVISIBLE:
break;
case OHIDDEN:
scrollMode = QScrollView::AlwaysOff;
break;
case OSCROLL:
scrollMode = QScrollView::AlwaysOn;
break;
}
QScrollView::ScrollBarMode horizontalScrollMode = scrollMode;
if (element()->wrap() != HTMLTextAreaElementImpl::ta_NoWrap)
horizontalScrollMode = QScrollView::AlwaysOff;
#if APPLE_CHANGES
w->setScrollBarModes(horizontalScrollMode, scrollMode);
#else
w->setHScrollBarMode(horizontalScrollMode);
w->setVScrollBarMode(scrollMode);
#endif
}
void RenderTextArea::updateFromElement()
{
HTMLTextAreaElementImpl *e = element();
QTextEdit* w = static_cast<QTextEdit*>(m_widget);
w->setReadOnly(e->readOnly());
#if APPLE_CHANGES
w->setDisabled(e->disabled());
#endif
e->updateValue();
if (!e->valueMatchesRenderer()) {
QString widgetText = text();
QString text = e->value().string();
text.replace(QChar('\\'), backslashAsCurrencySymbol());
if (widgetText != text) {
w->blockSignals(true);
int line, col;
w->getCursorPosition( &line, &col );
w->setText(text);
w->setCursorPosition( line, col );
w->blockSignals(false);
}
e->setValueMatchesRenderer();
m_dirty = false;
}
RenderFormElement::updateFromElement();
}
QString RenderTextArea::text()
{
QString txt;
QTextEdit* w = static_cast<QTextEdit*>(m_widget);
if (element()->wrap() == HTMLTextAreaElementImpl::ta_Physical) {
#if APPLE_CHANGES
txt = w->textWithHardLineBreaks();
#else
// yeah, QTextEdit has no accessor for getting the visually wrapped text
for (int p=0; p < w->paragraphs(); ++p) {
int pl = w->paragraphLength(p);
int ll = 0;
int lindex = w->lineOfChar(p, 0);
QString paragraphText = w->text(p);
for (int l = 0; l < pl; ++l) {
if (lindex != w->lineOfChar(p, l)) {
paragraphText.insert(l+ll++, QString::fromLatin1("\n"));
lindex = w->lineOfChar(p, l);
}
}
txt += paragraphText;
if (p < w->paragraphs() - 1)
txt += QString::fromLatin1("\n");
}
#endif
}
else
txt = w->text();
txt.replace(backslashAsCurrencySymbol(), QChar('\\'));
return txt;
}
void RenderTextArea::slotTextChanged()
{
element()->invalidateValue();
m_dirty = true;
}
void RenderTextArea::select()
{
static_cast<QTextEdit *>(m_widget)->selectAll();
}
// ---------------------------------------------------------------------------
#if APPLE_CHANGES
RenderSlider::RenderSlider(HTMLInputElementImpl* element)
:RenderFormElement(element)
{
QSlider* slider = new QSlider();
setQWidget(slider);
connect(slider, SIGNAL(sliderValueChanged()), this, SLOT(slotSliderValueChanged()));
connect(slider, SIGNAL(clicked()), this, SLOT(slotClicked()));
}
void RenderSlider::calcMinMaxWidth()
{
KHTMLAssert(!minMaxKnown());
// Let the widget tell us how big it wants to be.
QSize s(widget()->sizeHint());
bool widthSet = !style()->width().isVariable();
bool heightSet = !style()->height().isVariable();
if (heightSet && !widthSet) {
// Flip the intrinsic dimensions.
int barLength = s.width();
s = QSize(s.height(), barLength);
}
setIntrinsicWidth(s.width());
setIntrinsicHeight(s.height());
RenderFormElement::calcMinMaxWidth();
}
void RenderSlider::updateFromElement()
{
const DOMString& value = element()->value();
const DOMString& min = element()->getAttribute(ATTR_MIN);
const DOMString& max = element()->getAttribute(ATTR_MAX);
const DOMString& precision = element()->getAttribute(ATTR_PRECISION);
double minVal = min.isNull() ? 0.0 : min.string().toDouble();
double maxVal = max.isNull() ? 100.0 : max.string().toDouble();
minVal = kMin(minVal, maxVal); // Make sure the range is sane.
double val = value.isNull() ? (maxVal + minVal)/2.0 : value.string().toDouble();
val = kMax(minVal, kMin(val, maxVal)); // Make sure val is within min/max.
// Force integer value if not float (strcasecmp returns confusingly backward boolean).
if (strcasecmp(precision, "float"))
val = (int)(val + 0.5);
element()->setValue(QString::number(val));
QSlider* slider = (QSlider*)widget();
slider->setMinValue(minVal);
slider->setMaxValue(maxVal);
slider->setValue(val);
RenderFormElement::updateFromElement();
}
void RenderSlider::slotSliderValueChanged()
{
QSlider* slider = (QSlider*)widget();
double val = slider->value();
const DOMString& precision = element()->getAttribute(ATTR_PRECISION);
// Force integer value if not float (strcasecmp returns confusingly backward boolean).
if (strcasecmp(precision, "float"))
val = (int)(val + 0.5);
element()->setValue(QString::number(val));
// Fire the "input" DOM event.
element()->dispatchHTMLEvent(EventImpl::INPUT_EVENT, true, false);
}
void RenderSlider::slotClicked()
{
// emit mouseClick event etc
RenderFormElement::slotClicked();
}
#endif
#include "render_form.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -