Ejemplo n.º 1
0
void WContainerWidget::addWidget(WWidget *widget)
{
  if (widget->parent()) {
    if (widget->parent() != this) {
      LOG_WARN("addWidget(): reparenting widget");
      widget->setParentWidget(0);
    } else
      return;
  }

  if (!transientImpl_) {
    transientImpl_ = new TransientImpl();

    // A TD/TH node cannot be stubbed
    if (domElementType() != DomElement_TD
	&& domElementType() != DomElement_TH)
      setLoadLaterWhenInvisible(true);
  }

  transientImpl_->addedChildren_.push_back(widget);
  flags_.set(BIT_ADJUST_CHILDREN_ALIGN); // children margins hacks
  repaint(RepaintInnerHtml);

  widget->setParentWidget(this);
}
Ejemplo n.º 2
0
std::string WAbstractToggleButton::formName() const
{
  if (domElementType() == DomElement_LABEL)
    return "in" + id();
  else
    return WFormWidget::formName();
}
Ejemplo n.º 3
0
Archivo: WTable.C Proyecto: DTidd/wt
DomElement *WTable::createDomElement(WApplication *app)
{
  bool withIds = !app->environment().agentIsSpiderBot();

  DomElement *table = DomElement::createNew(domElementType());
  setId(table, app);

  DomElement *thead = 0;
  if (headerRowCount_ != 0) {
    thead = DomElement::createNew(DomElement_THEAD);
    if (withIds)
      thead->setId(id() + "th");
  }

  DomElement *tbody = DomElement::createNew(DomElement_TBODY);
  if (withIds)
    tbody->setId(id() + "tb");

  DomElement *colgroup = DomElement::createNew(DomElement_COLGROUP);

  for (unsigned col = 0; col < columns_.size(); ++col) {
    DomElement *c = DomElement::createNew(DomElement_COL);
    if (withIds)
      c->setId(columns_[col]->id());
    columns_[col]->updateDom(*c, true);
    colgroup->addChild(c);
  }

  table->addChild(colgroup);
  
  flags_.reset(BIT_COLUMNS_CHANGED);

  for (unsigned row = 0; row < (unsigned)rowCount(); ++row)
    for (unsigned col = 0; col < (unsigned)columnCount(); ++col)
      itemAt(row, col).overSpanned = false;
  
  for (unsigned row = 0; row < (unsigned)rowCount(); ++row) {
    DomElement *tr = createRowDomElement(row, withIds, app);
    if (row < static_cast<unsigned>(headerRowCount_))
      thead->addChild(tr);
    else
      tbody->addChild(tr);
  }
  rowsAdded_ = 0;

  if (thead)
    table->addChild(thead);
  table->addChild(tbody);

  updateDom(*table, true);

  flags_.reset(BIT_GRID_CHANGED);
  delete rowsChanged_;
  rowsChanged_ = 0;

  return table;
}
Ejemplo n.º 4
0
Archivo: Widget.C Proyecto: ReWeb3D/wt
DomElement *Widget::createDomElement(WApplication *app)
{
  DomElement *result = DomElement::createNew(domElementType());
  setId(result, app);

  std::stringstream js;
  createExtElement(js, result);
  result->callJavaScript(js.str());

  return result;
}
Ejemplo n.º 5
0
void WLineEdit::getDomChanges(std::vector<DomElement *>& result,
			      WApplication *app)
{
  if (app->environment().agentIsIE() && flags_.test(BIT_ECHO_MODE_CHANGED)) {
    DomElement *e = DomElement::getForUpdate(this, domElementType());
    DomElement *d = createDomElement(app);
    e->replaceWith(d);
    result.push_back(e);
  } else
    WFormWidget::getDomChanges(result, app);
}
Ejemplo n.º 6
0
DomElement *WPaintedWidget::createDomElement(WApplication *app)
{
  createPainter();

  DomElement *result = DomElement::createNew(domElementType());
  setId(result, app);

  DomElement *wrap = result;

  if (width().isAuto() && height().isAuto()) {
    result->setProperty(PropertyStylePosition, "relative");

    wrap = DomElement::createNew(DomElement_DIV);
    wrap->setProperty(PropertyStylePosition, "absolute");
    wrap->setProperty(PropertyStyleLeft, "0");
    wrap->setProperty(PropertyStyleRight, "0");
  }

  DomElement *canvas = DomElement::createNew(DomElement_DIV);

  if (!app->environment().agentIsSpiderBot())
    canvas->setId('p' + id());

  WPaintDevice *device = painter_->getPaintDevice(false);

  //handle the widget correctly when inline and using VML 
  if (painter_->renderType() == WWidgetPainter::InlineVml && isInline()) {
    result->setProperty(PropertyStyle, "zoom: 1;");
    canvas->setProperty(PropertyStyleDisplay, "inline");
    canvas->setProperty(PropertyStyle, "zoom: 1;");
  }

  if (renderWidth_ != 0 && renderHeight_ != 0) {
    paintEvent(device);

#ifdef WT_TARGET_JAVA
    if (device->painter())
      device->painter()->end();
#endif // WT_TARGET_JAVA
  }

  painter_->createContents(canvas, device);

  needRepaint_ = false;

  wrap->addChild(canvas);
  if (wrap != result)
    result->addChild(wrap);

  updateDom(*result, true);

  return result;
}
Ejemplo n.º 7
0
Archivo: WTable.C Proyecto: DTidd/wt
void WTable::getDomChanges(std::vector<DomElement *>& result,
			   WApplication *app)
{
  DomElement *e = DomElement::getForUpdate(this, domElementType());

  if (!isStubbed() && flags_.test(BIT_GRID_CHANGED)) {
    DomElement *newE = createDomElement(app);
    e->replaceWith(newE);
  } else {
    if (rowsChanged_) {
      for (std::set<WTableRow *>::iterator i = rowsChanged_->begin();
	   i != rowsChanged_->end(); ++i) {
	DomElement *e2 = DomElement::getForUpdate(*i, DomElement_TR);
	(*i)->updateDom(*e2, false);
	result.push_back(e2);
      }

      delete rowsChanged_;
      rowsChanged_ = 0;
    }

    if (rowsAdded_) {
      DomElement *etb = DomElement::getForUpdate(id() + "tb",
						 DomElement_TBODY);
      for (unsigned i = 0; i < static_cast<unsigned>(rowsAdded_); ++i) {
        DomElement *tr = createRowDomElement(rowCount() - rowsAdded_ + i, true, app);
	etb->addChild(tr);
      }

      result.push_back(etb);

      rowsAdded_ = 0;
    }

    if (flags_.test(BIT_COLUMNS_CHANGED)) {
	for (unsigned i = 0; i < columns_.size(); ++i) {
	  DomElement *e2
	    = DomElement::getForUpdate(columns_[i], DomElement_COL);
	  columns_[i]->updateDom(*e2, false);
	  result.push_back(e2);
	}

      flags_.reset(BIT_COLUMNS_CHANGED);
    }

    updateDom(*e, false);
  }

  result.push_back(e);
}
Ejemplo n.º 8
0
DomElement *WGLWidget::createDomElement(WApplication *app)
{
  DomElement *result = nullptr;

  if (!pImpl_) { // no GL support whatsoever
    result = DomElement::createNew(DomElementType::DIV);
    result->addChild(alternative_->createSDomElement(app));
    webGlNotAvailable_ = true;
  } else {
    result = DomElement::createNew(domElementType());
    repaintGL(GLClientSideRenderer::PAINT_GL | GLClientSideRenderer::RESIZE_GL);
  }
  setId(result, app);

  updateDom(*result, true);

  return result;
}
Ejemplo n.º 9
0
Archivo: Widget.C Proyecto: ReWeb3D/wt
void Widget::getDomChanges(std::vector<DomElement *>& result,
			   WApplication *app)
{
  std::string el = elRef() + ".el.dom";

  DomElement *e = DomElement::updateGiven(el, domElementType());

  updateExt();

  if (!jsUpdates_.empty()) {
    e->callJavaScript("var " + elVar() + "=" + elRef() + ";" + jsUpdates_);
    jsUpdates_.clear();
  }

  updateDom(*e, false);
  e->removeProperty(PropertyStyleDisplay);
  result.push_back(e);
}
Ejemplo n.º 10
0
void WFormWidget::validatorChanged()
{
  std::string validateJS = validator_->javaScriptValidate();
  if (!validateJS.empty()) {
    setJavaScriptMember("wtValidate", validateJS);

    if (!validateJs_) {
      validateJs_ = new JSlot();
      validateJs_->setJavaScript("function(o){" WT_CLASS ".validate(o)}");

      keyWentUp().connect(*validateJs_);
      changed().connect(*validateJs_);
      if (domElementType() != DomElement_SELECT)
	clicked().connect(*validateJs_);
    } else if (isRendered())
      validateJs_->exec(jsRef());
  } else {
    delete validateJs_;
    validateJs_ = 0;
  }

  std::string inputFilter = validator_->inputFilter();

  if (!inputFilter.empty()) {
    if (!filterInput_) {
      filterInput_ = new JSlot();

      keyPressed().connect(*filterInput_);
    }

    Wt::Utils::replace(inputFilter, '/', "\\/");

    filterInput_->setJavaScript
      ("function(o,e){" WT_CLASS ".filter(o,e,"
       + jsStringLiteral(inputFilter) + ")}");
  } else {
    delete filterInput_;
    filterInput_ = 0;
  }

  validate();
}
Ejemplo n.º 11
0
void WContainerWidget::getDomChanges(std::vector<DomElement *>& result,
				     WApplication *app)
{
  DomElement *e = DomElement::getForUpdate(this, domElementType());

#ifndef WT_NO_LAYOUT
  if (!app->session()->renderer().preLearning()) {
    if (flags_.test(BIT_LAYOUT_NEEDS_RERENDER)) {
      e->removeAllChildren(firstChildIndex());
      createDomChildren(*e, app);

      flags_.reset(BIT_LAYOUT_NEEDS_RERENDER);
      flags_.reset(BIT_LAYOUT_NEEDS_UPDATE);
    }
  }
#endif // WT_NO_LAYOUT

  updateDomChildren(*e, app);

  updateDom(*e, false);

  result.push_back(e);
}
Ejemplo n.º 12
0
Archivo: Widget.C Proyecto: ReWeb3D/wt
std::string Widget::createExtElement(std::stringstream& alljs,
				     DomElement *inContainer)
{
  if (inContainer) {
    updateDom(*inContainer, true);
    inContainer->removeProperty(PropertyStyleDisplay);
  }

  setRendered(false);

  alljs << "var " << elVar() << ";"
	<< createJS(inContainer)
	<< elRef() << "=" << elVar() << ";";

  if (isHidden())
    alljs << elVar() << ".hide();";

  jsUpdates_.clear();

  if (!inContainer) {
    DomElement *e
      = DomElement::updateGiven(elVar() + ".getEl().dom", domElementType());
    updateDom(*e, true);

    {
      EscapeOStream out(alljs);
      e->asJavaScript(out, DomElement::Update);
    }

    delete e;
  }

  setRendered(true);

  return elVar();
}
Ejemplo n.º 13
0
DomElement *WFileUpload::createDomElement(WApplication *app)
{
  DomElement *result = DomElement::createNew(domElementType());
  if (result->type() == DomElement_FORM)
    result->setId(id());
  else
    result->setName(id());

  EventSignal<> *change = voidEventSignal(CHANGE_SIGNAL, false);

  if (fileUploadTarget_) {
    DomElement *i = DomElement::createNew(DomElement_IFRAME);
    i->setProperty(PropertyClass, "Wt-resource");
    i->setProperty(PropertySrc, fileUploadTarget_->url());
    i->setName("if" + id());
    if (app->environment().agentIsIE()) {
      // http://msdn.microsoft.com/en-us/library/ms536474%28v=vs.85%29.aspx
      // HTA's (started by mshta.exe) have a different security model than
      // a normal web app, and therefore a HTA browser does not allow
      // interaction from iframes to the parent window unless this
      // attribute is set. If omitted, this causes the 'uploaded()'
      // signal to be blocked when a Wt app is executed as a HTA.
      i->setAttribute("APPLICATION", "yes");
    }

    DomElement *form = result;

    form->setAttribute("method", "post");
    form->setAttribute("action", fileUploadTarget_->url());
    form->setAttribute("enctype", "multipart/form-data");
    form->setProperty(PropertyStyle, "margin:0;padding:0;display:inline");
    form->setProperty(PropertyTarget, "if" + id());

    /*
     * wrap iframe in an extra span to work around bug in IE which does
     * not set the name use DOM methods
     */
    DomElement *d = DomElement::createNew(DomElement_SPAN);
    d->addChild(i);

    form->addChild(d);

    DomElement *input = DomElement::createNew(DomElement_INPUT);
    input->setAttribute("type", "file");
    if (flags_.test(BIT_MULTIPLE))
      input->setAttribute("multiple", "multiple");
    input->setAttribute("name", "data");
    input->setAttribute("size", boost::lexical_cast<std::string>(textSize_));
    input->setId("in" + id());

    if (!isEnabled())
      input->setProperty(Wt::PropertyDisabled, "true");

    if (change)
      updateSignalConnection(*input, *change, "change", true);

    form->addChild(input);

  } else {
    result->setAttribute("type", "file");
    if (flags_.test(BIT_MULTIPLE))
      result->setAttribute("multiple", "multiple");
    result->setAttribute("size", boost::lexical_cast<std::string>(textSize_));

    if (!isEnabled())
      result->setProperty(Wt::PropertyDisabled, "true");

    if (change)
      updateSignalConnection(*result, *change, "change", true);
  }

  updateDom(*result, true);

  flags_.reset(BIT_ENABLE_AJAX);

  return result;
}
Ejemplo n.º 14
0
void WContainerWidget::updateDom(DomElement& element, bool all)
{
  if (all && element.type() == DomElement_LI && isInline())
    element.setProperty(PropertyStyleDisplay, "inline");

  if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) {
    AlignmentFlag hAlign = contentAlignment_ & AlignHorizontalMask;

    bool ltr = WApplication::instance()->layoutDirection() == LeftToRight;

    switch (hAlign) {
    case AlignLeft:
      if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED))
	element.setProperty(PropertyStyleTextAlign, ltr ? "left" : "right");
      break;
    case AlignRight:
      element.setProperty(PropertyStyleTextAlign, ltr ? "right" : "left");
      break;
    case AlignCenter:
      element.setProperty(PropertyStyleTextAlign, "center");
      break;
    case AlignJustify:
#ifndef WT_NO_LAYOUT
      if (!layout_)
#endif // WT_NO_LAYOUT
	element.setProperty(PropertyStyleTextAlign, "justify");
      break;
    default:
      break;
    }

    if (domElementType() == DomElement_TD) {
      AlignmentFlag vAlign = contentAlignment_ & AlignVerticalMask;
      switch (vAlign) {
      case AlignTop:
	if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED))
	  element.setProperty(PropertyStyleVerticalAlign, "top");
	break;
      case AlignMiddle:
	element.setProperty(PropertyStyleVerticalAlign, "middle");
	break;
      case AlignBottom:
	element.setProperty(PropertyStyleVerticalAlign, "bottom");
      default:
	break;
      }
    }
  }

  if (flags_.test(BIT_ADJUST_CHILDREN_ALIGN)
      || flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) {
    /*
     * Welcome to CSS hell.
     *
     * Apparently, the text-align property only applies to inline elements.
     * To center non-inline children, the standard says to set its left and
     * right margin to 'auto'.
     *
     * I assume the same applies for aligning to the right ?
     */
    for (unsigned i = 0; i < children_->size(); ++i) {
      WWidget *child = (*children_)[i];

      if (!child->isInline()) {
	AlignmentFlag ha = contentAlignment_ & AlignHorizontalMask;
	if (ha == AlignCenter) {
	  if (!child->margin(Left).isAuto())
	    child->setMargin(WLength::Auto, Left);
	  if (!child->margin(Right).isAuto())
	    child->setMargin(WLength::Auto, Right);
	} else if (ha == AlignRight) {
	  if (!child->margin(Left).isAuto())
	    child->setMargin(WLength::Auto, Left);
	}
      }
    }

    flags_.reset(BIT_CONTENT_ALIGNMENT_CHANGED);
    flags_.reset(BIT_ADJUST_CHILDREN_ALIGN);
  }

  if (flags_.test(BIT_PADDINGS_CHANGED)
      || (all && padding_ &&
	  !(   padding_[0].isAuto() && padding_[1].isAuto()
	    && padding_[2].isAuto() && padding_[3].isAuto()))) {

    if ((padding_[0] == padding_[1])
	&& (padding_[0] == padding_[2])
	&& (padding_[0] == padding_[3]))
      element.setProperty(PropertyStylePadding,
			  padding_[0].cssText());
    else
      element.setProperty(PropertyStylePadding,
			  padding_[0].cssText()
			  + " " + padding_[1].cssText()
			  + " " + padding_[2].cssText()
			  + " " + padding_[3].cssText());

    flags_.reset(BIT_PADDINGS_CHANGED);
  }

  WInteractWidget::updateDom(element, all);

  if (flags_.test(BIT_OVERFLOW_CHANGED)
      || (all && overflow_ &&
	  !(overflow_[0] == OverflowVisible
	    && overflow_[1] == OverflowVisible))) {
    static const char *cssText[] = { "visible", "auto", "hidden", "scroll" };

    element.setProperty(PropertyStyleOverflowX, cssText[overflow_[0]]);
    element.setProperty(PropertyStyleOverflowY, cssText[overflow_[1]]);

    flags_.reset(BIT_OVERFLOW_CHANGED);

    /* If a container widget has overflow, then, if ever something
     * inside it has position scheme relative/absolute, it will not
     * scroll properly unless every element up to the container and including 
     * the container itself has overflow: relative.
     *
     * The following fixes the common case:
     * container (overflow) - container - layout
     */
    WApplication *app = WApplication::instance();
    if (app->environment().agentIsIE()
	&& (overflow_[0] == OverflowAuto || overflow_[0] == OverflowScroll))
      if (positionScheme() == Static)
	element.setProperty(PropertyStylePosition, "relative");
  }
}