#include #include #include #include #include #include #include //#define USE_HBOX_LAYOUT class BootstrapProgressBar : public Wt::WProgressBar { public: BootstrapProgressBar(Wt::WContainerWidget *parent = 0) : Wt::WProgressBar(parent) { } void setSuccess() { // How can the Progressbar be updated with the correct inner div style class? setValueStyleClass("progress-bar-success"); } void setFailure() { // How can the Progressbar be updated with the correct inner div style class? setValueStyleClass("progress-bar-danger"); } void reset() { setValueStyleClass(""); hide(); setValue(0); } }; class FileUpload : public Wt::WContainerWidget { public: FileUpload() : progress_(new BootstrapProgressBar()), button_(new Wt::WPushButton("Upload Button")) { #if defined USE_HBOX_LAYOUT auto hbox = new Wt::WHBoxLayout(); setLayout(hbox); hbox->addWidget(progress_, 1); hbox->addWidget(button_); #else addWidget(progress_); addWidget(button_); #endif progress_->hide(); button_->clicked().connect([this](const Wt::WMouseEvent&) { progress_->reset(); }); reset(); } Wt::Signal<>& uploadSuccessful() { return uploadSuccessful_; } Wt::Signal& uploadFailed() { return uploadFailed_; } Wt::Http::UploadedFile getUploadedFile() { return upload_->uploadedFiles().front(); } void reset() { upload_ = std::make_unique(); upload_->setMultiple(false); upload_->setProgressBar(progress_); // connect fileupload signals upload_->changed() .connect(this, &FileUpload::upload); upload_->uploaded() .connect(this, &FileUpload::uploaded); upload_->fileTooLarge() .connect(this, &FileUpload::failed); // show fileupload widget addWidget(upload_.get()); upload_->setDisplayWidget(button_); } void setFailed() { progress_->setFailure(); } void setSuccessful() { progress_->setSuccess(); } private: Wt::Signal<> uploadSuccessful_; Wt::Signal uploadFailed_; std::unique_ptr upload_; BootstrapProgressBar* progress_; Wt::WPushButton* button_; void upload() { progress_->show(); upload_->upload(); } void uploaded() { uploadSuccessful().emit(); } void failed(const int64_t filesize) { uploadFailed().emit(filesize); } }; class TestApplication : public Wt::WApplication { FileUpload* fileUpload_; public: TestApplication(const Wt::WEnvironment& env) : WApplication(env) { Wt::WBootstrapTheme *bootstrapTheme = new Wt::WBootstrapTheme(this); bootstrapTheme->setVersion(Wt::WBootstrapTheme::Version3); bootstrapTheme->setResponsive(true); this->setTheme(bootstrapTheme); // load the default bootstrap3 (sub-)theme this->useStyleSheet("resources/themes/bootstrap/3/bootstrap-theme.min.css"); setTitle("Test"); auto container = new Wt::WContainerWidget(root()); container->setWidth(Wt::WLength(200)); fileUpload_ = new FileUpload(); container->addWidget(fileUpload_); fileUpload_->uploadSuccessful().connect(this, &TestApplication::fileUploaded); fileUpload_->uploadFailed().connect(this, &TestApplication::uploadFailed); } void fileUploaded() { auto uploadedFile = fileUpload_->getUploadedFile(); // validate file auto isValid = rand() % 2 == 1; if (isValid) fileUpload_->setSuccessful(); else fileUpload_->setFailed(); // recreate fileupload widget fileUpload_->reset(); } void uploadFailed(const int64_t filesize) { fileUpload_->setFailed(); // recreate fileupload widget fileUpload_->reset(); } }; Wt::WApplication *createApplication(const Wt::WEnvironment& env) { return new TestApplication(env); } int main(int argc, char **argv) { return Wt::WRun(argc, argv, &createApplication); }