void WSuggestionPopup::modelDataChanged(const WModelIndex& topLeft, const WModelIndex& bottomRight) { if (topLeft.parent().isValid()) return; if (modelColumn_ < topLeft.column() || modelColumn_ > bottomRight.column()) return; for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { WContainerWidget *w = dynamic_cast<WContainerWidget *>(impl_->widget(i)); WAnchor *anchor = dynamic_cast<WAnchor *>(w->widget(0)); WText *value = dynamic_cast<WText *>(anchor->widget(0)); WModelIndex index = model_->index(i, modelColumn_); boost::any d = index.data(); value->setText(asString(d)); TextFormat format = index.flags() & ItemIsXHTMLText ? XHTMLText : PlainText; value->setTextFormat(format); boost::any d2 = model_->data(i, modelColumn_, UserRole); if (d2.empty()) d2 = d; value->setAttributeValue("sug", asString(d2)); } }
WWidget* WCalendar::renderCell(WWidget* widget, const WDate& date) { WText* t = dynamic_cast<WText*>(widget); if (!t) { t = new WText(); t->setInline(false); t->setTextFormat(PlainText); } #ifndef WT_TARGET_JAVA char buf[30]; #else char *buf; #endif // WT_TARGET_JAVA Utils::itoa(date.day(), buf); t->setText(WString::fromUTF8(buf)); std::string styleClass; if (isInvalid(date)) styleClass += " Wt-cal-oor"; else if (date.month() != currentMonth()) styleClass += " Wt-cal-oom"; if (isSelected(date)) styleClass += " Wt-cal-sel"; WDate currentDate = WDate::currentDate(); if (date.day() == currentDate.day() && date.month() == currentDate.month() && date.year() == currentDate.year()) { if (!isSelected(date)) styleClass += " Wt-cal-now"; t->setToolTip(WString::tr("Wt.WCalendar.today")); } else t->setToolTip(""); t->setStyleClass(styleClass.c_str()); return t; }
void WsTwitterStream::load() { Wt::WApplication::instance()->require("//platform.twitter.com/widgets.js"); WContainerWidget::load(); std::string width = Wt::asString(option("width")).toUTF8(); std::string url = Wt::asString(option("url")).toUTF8(); std::string widgetId = Wt::asString(option("widgetId")).toUTF8(); std::string text = Wt::asString(option("text")).toUTF8(); setId("twitterstream"); //resize(WLength(25, WLength::Percentage), WLength(25, WLength::Percentage)); setOverflow(WContainerWidget::OverflowAuto); std::string html = "<a class=\"twitter-timeline\""; if (width!="") html+=" width=\""+width+"\""; html+=" data-dnt=\"true\" href=\""+url+"\" data-widget-id=\""+widgetId+"\">"+text+"</a>"; wApp->log("notice") << "WsModTwitterStream::load() "+html; WText* textField = new WText(this); textField->setTextFormat(Wt::XHTMLUnsafeText); textField->setText(html); addWidget(textField); }
void SimpleChatWidget::processChatEvent(const ChatEvent& event) { WApplication *app = WApplication::instance(); /* * This is where the "server-push" happens. The chat server posts to this * event from other sessions, see SimpleChatServer::postChatEvent() */ /* * Format and append the line to the conversation. * * This is also the step where the automatic XSS filtering will kick in: * - if another user tried to pass on some JavaScript, it is filtered away. * - if another user did not provide valid XHTML, the text is automatically * interpreted as PlainText */ /* * If it is not a plain message, also update the user list. */ if (event.type() != ChatEvent::Message) { if (event.type() == ChatEvent::Rename && event.user() == user_) user_ = event.data(); updateUsers(); } /* * This is the server call: we (schedule to) propagate the updated UI to * the client. * * This schedules an update and returns immediately */ app->triggerUpdate(); newMessage(); /* * Anything else doesn't matter if we are not logged in. */ if (!loggedIn()) return; bool display = event.type() != ChatEvent::Message || !userList_ || (users_.find(event.user()) != users_.end() && users_[event.user()]); if (display) { WText *w = new WText(messages_); /* * If it fails, it is because the content wasn't valid XHTML */ if (!w->setText(event.formattedHTML(user_, XHTMLText))) { w->setText(event.formattedHTML(user_, PlainText)); w->setTextFormat(XHTMLText); } w->setInline(false); w->setStyleClass("chat-msg"); /* * Leave no more than 100 messages in the back-log */ if (messages_->count() > 100) delete messages_->children()[0]; /* * Little javascript trick to make sure we scroll along with new content */ app->doJavaScript(messages_->jsRef() + ".scrollTop += " + messages_->jsRef() + ".scrollHeight;"); /* If this message belongs to another user, play a received sound */ if (event.user() != user_ && messageReceived_) messageReceived_->play(); } }
WWidget *WItemDelegate::update(WWidget *widget, const WModelIndex& index, WFlags<ViewItemRenderFlag> flags) { bool editing = widget && widget->find("t") == 0; if (flags & RenderEditing) { if (!editing) { widget = createEditor(index, flags); WInteractWidget *iw = dynamic_cast<WInteractWidget *>(widget); if (iw) { // Disable drag & drop and selection behaviour iw->mouseWentDown().preventPropagation(); iw->clicked().preventPropagation(); } } } else { if (editing) widget = 0; } WidgetRef widgetRef(widget); bool isNew = false; if (!(flags & RenderEditing)) { if (!widgetRef.w) { isNew = true; WText *t = new WText(); t->setObjectName("t"); if (index.isValid() && !(index.flags() & ItemIsXHTMLText)) t->setTextFormat(PlainText); t->setWordWrap(true); widgetRef.w = t; } if (!index.isValid()) return widgetRef.w; bool haveCheckBox = false; if (index.flags() & ItemIsUserCheckable) { boost::any checkedData = index.data(CheckStateRole); CheckState state = checkedData.empty() ? Unchecked : (checkedData.type() == typeid(bool) ? (boost::any_cast<bool>(checkedData) ? Checked : Unchecked) : (checkedData.type() == typeid(CheckState) ? boost::any_cast<CheckState>(checkedData) : Unchecked)); checkBox(widgetRef, index, true, index.flags() & ItemIsTristate) ->setCheckState(state); haveCheckBox = true; } else if (!isNew) delete checkBox(widgetRef, index, false); boost::any linkData = index.data(LinkRole); if (!linkData.empty()) { WLink link = boost::any_cast<WLink>(linkData); WAnchor *a = anchorWidget(widgetRef); a->setLink(link); if (link.type() == WLink::Resource) a->setTarget(TargetNewWindow); } WText *t = textWidget(widgetRef); WString label = asString(index.data(), textFormat_); if (label.empty() && haveCheckBox) label = WString::fromUTF8(" "); t->setText(label); std::string iconUrl = asString(index.data(DecorationRole)).toUTF8(); if (!iconUrl.empty()) { iconWidget(widgetRef, true)->setImageLink(WLink(iconUrl)); } else if (!isNew) delete iconWidget(widgetRef, false); } WString tooltip = asString(index.data(ToolTipRole)); if (!tooltip.empty() || !isNew) widgetRef.w->setToolTip(tooltip); WT_USTRING sc = asString(index.data(StyleClassRole)); if (flags & RenderSelected) sc += WT_USTRING::fromUTF8 (" " + WApplication::instance()->theme()->activeClass()); if (flags & RenderEditing) sc += WT_USTRING::fromUTF8(" Wt-delegate-edit"); widgetRef.w->setStyleClass(sc); if (index.flags() & ItemIsDropEnabled) widgetRef.w->setAttributeValue("drop", WString::fromUTF8("true")); else if (!widgetRef.w->attributeValue("drop").empty()) widgetRef.w->setAttributeValue("drop", WString::fromUTF8("f")); return widgetRef.w; }
void WsContent::selectWidget(std::string path) { std::string sysPath(m_sDocumentRoot + path); boost::filesystem::path p(path); std::string strExt (p.extension().string()); std::string strName(p.stem().string()); std::string strFileName(strName + strExt); std::string fileContent; if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : path = " << path << " name = " << strName << " extension = " << strExt << " system path = " << sysPath; // This extension is mainly created for allowing text in a image without a link if ( strExt == ".nolink" ) { addWidget(new WsErrorPage(WsErrorPage::Error, path, 0, "Extension not allowed", true)); return; } // .html if ( strExt == ".html" ) { if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : render a html file : " << sysPath; if ( !m_bAllowHtmlRendering ) { addWidget(new WsErrorPage(WsErrorPage::Error, path, 0, "Rendering a html file is not allowed")); return; } clear(); WsApp->hideImages(false); WText* pIFrame = new WText(); pIFrame->setTextFormat(XHTMLUnsafeText); pIFrame->setText("<iframe src='" + m_sRelativeDocumentRoot + path + "' height='98%' width='100%' frameborder='0'></iframe>"); addWidget(pIFrame); return; } // .form if ( strExt == ".form" ) { if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : render a form : " << sysPath; clear(); m_curWForm = new gdWForm(sysPath); addWidget(m_curWForm); return; } // .itpl, Inside template : Extension that create a template in the content. if ( strExt == ".itpl" ) { if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : render an inside template : " << sysPath; clear(); WsTemplate* pTemplate = new WsTemplate(strFileName); addWidget(pTemplate); return; } // directory if ( gdcore_isPathDirectory(sysPath) ) { if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : render a directory : " << sysPath; viewDirectory(path); return; } /* Koen : mmm this is a tricky problem. you could do this using an internal path so that you can first let the user authenticate, if necessary, and then you redirect to a static resource with some randomly generated token in the URL so that you can serve the file so the permalink is clean, like /cms/folder1/folder2/file.doc if your app is deployed at / or /cms, you handle the internal path, authenticate, etc... then finally, you create a random ID, and redirect to /resource/folder1/folder2/file.doc?auth=randomid and this is handled by a WResource which checks the path and serves the file if you prefer I can create a small example ... ooops ! must run ! */ if ( strExt == ".rss" ) { if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : render a " << strExt << " file : " << sysPath; clear(); WsApp->hideImages(false); addWidget(new WText("Download file : " + path + " ...")); return wApp->redirect(m_sRelativeDocumentRoot + path); } for (int iModule = 0; iModule < WsApp->WsModules().modules().size(); iModule++) { WsModule* curModule = WsApp->WsModules().modules()[iModule]->module; if ( curModule->isLoaded() ) continue; if ( (strExt.size() == 0 && strName == curModule->fileName()) || (strExt.size() > 0 && strExt == curModule->extension(strExt)) ) { if ( m_bLogContent ) if ( strExt == curModule->extension(strExt) ) wApp->log("notice") << "WsContent::selectWidget : module, render a " << strExt << " file extension : " << sysPath; else wApp->log("notice") << "WsContent::selectWidget : module, render " << strName << " file name: " << sysPath; clear(); WsApp->hideImages(curModule->hideImages()); curModule->setSysPath(sysPath); curModule->setDiffPath(m_sRelativeDocumentRoot); WWidget* w = curModule->createContents(); if ( w ) { if ( asString(curModule->option("useLayout")) == "true" ) { WVBoxLayout* vbox = new WVBoxLayout(); vbox->addWidget(w, 1); setLayout(vbox); } else { addWidget(w); } } else { wApp->log("notice") << "WsContent::selectWidget : module, render " << curModule->moduleName() << " CANNOT call create content: "; } return; } } if ( strExt == ".pdf" ) { if ( m_bLogContent ) wApp->log("notice") << "WsContent::selectWidget : render a " << strExt << " file : " << sysPath; // if ( !allowedPath(userUID, syspath) ) return; clear(); WsApp->hideImages(false); addWidget(new WText("Download file : " + path + " ...")); return wApp->redirect(m_sRelativeDocumentRoot + path); } clear(); addWidget(new WsErrorPage(WsErrorPage::Error, path, 0, "Unknown extension", false)); }