⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render_form.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 + -