📄 render_form.cpp
字号:
HTMLSelectElementImpl* f = static_cast<HTMLSelectElementImpl*>(m_element); m_ignoreSelectEvents = true; // change widget type bool oldMultiple = m_multiple; unsigned oldSize = m_size; bool oldListbox = m_useListBox; m_multiple = f->multiple(); m_size = f->size(); m_useListBox = (m_multiple || m_size > 1); if (oldMultiple != m_multiple || oldSize != m_size) { if (m_useListBox != oldListbox) { // type of select has changed delete m_widget; if(m_useListBox) setQWidget(createListBox()); else setQWidget(createComboBox()); } if (m_useListBox && oldMultiple != m_multiple) { static_cast<KListBox*>(m_widget)->setSelectionMode(m_multiple ? QListBox::Multi : QListBox::Single); } m_selectionChanged = true; m_optionsChanged = true; } HTMLSelectElementImpl *select = static_cast<HTMLSelectElementImpl*>(m_element); // update contents listbox/combobox based on options in m_element if ( m_optionsChanged ) { QArray<HTMLGenericFormElementImpl*> listItems = select->listItems(); int listIndex; if(m_useListBox) static_cast<KListBox*>(m_widget)->clear(); else static_cast<KComboBox*>(m_widget)->clear(); for (listIndex = 0; listIndex < int(listItems.size()); listIndex++) { if (listItems[listIndex]->id() == ID_OPTGROUP) { DOMString text = listItems[listIndex]->getAttribute(ATTR_LABEL); if (text.isNull()) text = ""; if(m_useListBox) { QListBoxText *item = new QListBoxText(QString(text.implementation()->s, text.implementation()->l).visual()); static_cast<KListBox*>(m_widget) ->insertItem(item, listIndex); item->setSelectable(false); } else static_cast<KComboBox*>(m_widget) ->insertItem(QString(text.implementation()->s, text.implementation()->l).visual(), listIndex); } else if (listItems[listIndex]->id() == ID_OPTION) { DOMString text = static_cast<HTMLOptionElementImpl*>(listItems[listIndex])->text(); if (text.isNull()) text = ""; if (listItems[listIndex]->parentNode()->id() == ID_OPTGROUP) text = DOMString(" ")+text; if(m_useListBox) static_cast<KListBox*>(m_widget) ->insertItem(QString(text.implementation()->s, text.implementation()->l).visual(), listIndex); else static_cast<KComboBox*>(m_widget) ->insertItem(QString(text.implementation()->s, text.implementation()->l).visual(), listIndex); } else assert(false); m_selectionChanged = true; } m_optionsChanged = false; } // update selection if (m_selectionChanged) updateSelection(); // calculate size if(m_useListBox) { KListBox* w = static_cast<KListBox*>(m_widget); QListBoxItem* p = w->firstItem(); int width = 0; int height = 0; while(p) { width = QMAX(width, p->width(p->listBox())); height = QMAX(height, p->height(p->listBox())); p = p->next(); } int size = m_size; // check if multiple and size was not given or invalid // Internet Exploder sets size to QMIN(number of elements, 4) // Netscape seems to simply set it to "number of elements" // the average of that is IMHO QMIN(number of elements, 10) // so I did that ;-) if(size < 1) size = QMIN(static_cast<KListBox*>(m_widget)->count(), 10); width += 2*w->frameWidth() + w->verticalScrollBar()->sizeHint().width(); height = size*height + 2*w->frameWidth(); setIntrinsicWidth( width ); setIntrinsicHeight( height ); } else { QSize s(m_widget->sizeHint()); setIntrinsicWidth( s.width() ); setIntrinsicHeight( s.height() ); } /// uuh, ignore the following line.. setLayouted( false ); RenderFormElement::layout(); // and now disable the widget in case there is no <option> given QArray<HTMLGenericFormElementImpl*> listItems = select->listItems(); bool foundOption = false; for (uint i = 0; i < listItems.size() && !foundOption; i++) foundOption = (listItems[i]->id() == ID_OPTION); if (!foundOption) m_widget->setEnabled(false); m_ignoreSelectEvents = false;}void RenderSelect::close(){ HTMLSelectElementImpl* f = static_cast<HTMLSelectElementImpl*>(m_element); // Restore state QString state = f->ownerDocument()->registerElement(f); if ( !state.isEmpty()) static_cast<HTMLSelectElementImpl*>(m_element)->restoreState( state ); setLayouted(false); static_cast<HTMLSelectElementImpl*>(m_element)->recalcListItems(); RenderFormElement::close();}void RenderSelect::slotSelected(int index){ if ( m_ignoreSelectEvents ) return; assert( !m_useListBox ); QArray<HTMLGenericFormElementImpl*> listItems = static_cast<HTMLSelectElementImpl*>(m_element)->listItems(); if(index >= 0 && index < int(listItems.size())) { if ( listItems[index]->id() == ID_OPTGROUP ) { // this one is not selectable, we need to find an option element bool found = false; 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 ) static_cast<HTMLOptionElementImpl*>(listItems[index])->setSelected(true); } else { static_cast<HTMLOptionElementImpl*>(listItems[index])->setSelected(true); } } static_cast<HTMLSelectElementImpl*>(m_element)->onChange();}void RenderSelect::slotSelectionChanged(){ if ( m_ignoreSelectEvents ) return; QArray<HTMLGenericFormElementImpl*> listItems = static_cast<HTMLSelectElementImpl*>(m_element)->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 ); static_cast<HTMLSelectElementImpl*>(m_element)->onChange();}void RenderSelect::setOptionsChanged(bool _optionsChanged){ m_optionsChanged = _optionsChanged;}KListBox* RenderSelect::createListBox(){ KListBox *lb = new KListBox(m_view->viewport()); lb->installEventFilter(this); lb->setSelectionMode(m_multiple ? QListBox::Extended : QListBox::Single); // ### looks broken //lb->setAutoMask(true); connect( lb, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) ); m_ignoreSelectEvents = false; lb->setMouseTracking(true); return lb;}ComboBoxWidget *RenderSelect::createComboBox(){ ComboBoxWidget *cb = new ComboBoxWidget(m_view->viewport()); cb->installEventFilter(this); connect(cb, SIGNAL(activated(int)), this, SLOT(slotSelected(int))); return cb;}void RenderSelect::updateSelection(){ QArray<HTMLGenericFormElementImpl*> listItems = static_cast<HTMLSelectElementImpl*>(m_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()); } else { for (i = 0; i < int(listItems.size()); i++) if (listItems[i]->id() == ID_OPTION && static_cast<HTMLOptionElementImpl*>(listItems[i])->selected()) { static_cast<KComboBox*>(m_widget)->setCurrentItem(i); return; } static_cast<KComboBox*>(m_widget)->setCurrentItem(0); // ### wrong if item 0 is an optgroup } m_selectionChanged = false;}// -------------------------------------------------------------------------TextAreaWidget::TextAreaWidget(int wrap, QWidget* parent) : KEdit(parent){ if(wrap != DOM::HTMLTextAreaElementImpl::ta_NoWrap) { setWordWrap(QMultiLineEdit::WidgetWidth); clearTableFlags(Tbl_autoScrollBars); setTableFlags(Tbl_vScrollBar); } else { clearTableFlags(Tbl_autoScrollBars); setTableFlags(Tbl_vScrollBar | Tbl_hScrollBar); } KCursor::setAutoHideCursor(this, true); setAutoMask(true); setMouseTracking(true);}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 KEdit::event( e );}void TextAreaWidget::resizeEvent( QResizeEvent *ev ){ QTableView::resizeEvent( ev );#if QT_VERSION <= 232 // updates widget mask when autoMask == true. Qt <= 2.3.2 // didn't call the base impl, causing ugly cropped form widget // bugs in konq/e :-( (Simon) QFrame::resizeEvent( ev );#endif}// -------------------------------------------------------------------------// ### allow contents to be manipulated via DOM - will require updating// of text node childRenderTextArea::RenderTextArea(QScrollView *view, HTMLTextAreaElementImpl *element) : RenderFormElement(view, element){ TextAreaWidget *edit = new TextAreaWidget(element->wrap(), view); setQWidget(edit); edit->installEventFilter(this); connect(edit,SIGNAL(textChanged()),this,SLOT(slotTextChanged()));}RenderTextArea::~RenderTextArea(){ HTMLTextAreaElementImpl* e = static_cast<HTMLTextAreaElementImpl*>( m_element ); if ( e->m_dirtyvalue ) { e->m_value = text(); e->m_dirtyvalue = false; }}void RenderTextArea::calcMinMaxWidth(){ TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget); HTMLTextAreaElementImpl* f = static_cast<HTMLTextAreaElementImpl*>(m_element); QFontMetrics m = fontMetrics(style()->font()); QSize size( QMAX(f->cols(), 1)*m.width('x') + w->frameWidth()*5 + w->verticalScrollBar()->sizeHint().width(), QMAX(f->rows(), 1)*m.height() + w->frameWidth()*3 + (w->wordWrap() == QMultiLineEdit::NoWrap ? w->horizontalScrollBar()->sizeHint().height() : 0) ); setIntrinsicWidth( size.width() ); setIntrinsicHeight( size.height() ); RenderFormElement::calcMinMaxWidth();}void RenderTextArea::layout( ){ TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget); HTMLTextAreaElementImpl* f = static_cast<HTMLTextAreaElementImpl*>(m_element); if (!layouted()) { w->setReadOnly(m_element->readOnly()); w->blockSignals(true); int line, col; w->getCursorPosition( &line, &col ); w->setText(f->value().string().visual()); w->setCursorPosition( line, col ); w->blockSignals(false); } RenderFormElement::layout();}void RenderTextArea::close( ){ HTMLTextAreaElementImpl *e = static_cast<HTMLTextAreaElementImpl*>(m_element); e->setValue( e->defaultValue() ); QString state = e->ownerDocument()->registerElement( e ); if ( !state.isEmpty() ) e->restoreState( state ); RenderFormElement::close();}QString RenderTextArea::text(){ QString txt; HTMLTextAreaElementImpl* e = static_cast<HTMLTextAreaElementImpl*>(m_element); TextAreaWidget* w = static_cast<TextAreaWidget*>(m_widget); if(e->wrap() == DOM::HTMLTextAreaElementImpl::ta_Physical) { for(int i=0; i < w->numLines(); i++) txt += w->textLine(i) + QString::fromLatin1("\n"); } else txt = w->text(); return txt;}void RenderTextArea::slotTextChanged(){ static_cast<HTMLTextAreaElementImpl*>( m_element )->m_dirtyvalue = true;}void RenderTextArea::select(){ static_cast<TextAreaWidget *>(m_widget)->selectAll();}// ---------------------------------------------------------------------------#include "render_form.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -