|
#include <Wt/WBootstrapTheme>
|
|
#include <Wt/WApplication>
|
|
#include <Wt/WContainerWidget>
|
|
#include <Wt/WPushButton>
|
|
#include <Wt/WFileUpload>
|
|
#include <Wt/WProgressBar>
|
|
#include <Wt/DomElement.h>
|
|
|
|
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");
|
|
Wt::DomElement *e = Wt::DomElement::getForUpdate(this, domElementType());
|
|
updateDom(*e, true);
|
|
repaint();
|
|
}
|
|
void setFailure()
|
|
{
|
|
// How can the Progressbar be updated with the correct inner div style class?
|
|
setValueStyleClass("progress-bar-danger");
|
|
Wt::DomElement *e = Wt::DomElement::getForUpdate(this, domElementType());
|
|
updateDom(*e, true);
|
|
repaint();
|
|
}
|
|
void reset()
|
|
{
|
|
setValueStyleClass("");
|
|
hide();
|
|
setValue(0);
|
|
}
|
|
};
|
|
|
|
class FileUpload : public Wt::WContainerWidget
|
|
{
|
|
Wt::WHBoxLayout* hbox_;
|
|
public:
|
|
FileUpload() :
|
|
hbox_(new Wt::WHBoxLayout()),
|
|
progress_(new BootstrapProgressBar()),
|
|
button_(new Wt::WPushButton("Upload Button"))
|
|
{
|
|
addWidget(progress_);
|
|
addWidget(button_);
|
|
|
|
progress_->hide();
|
|
button_->clicked().connect([this](const Wt::WMouseEvent&) {
|
|
progress_->reset();
|
|
});
|
|
reset();
|
|
}
|
|
|
|
Wt::Signal<>& uploadSuccessful()
|
|
{
|
|
return uploadSuccessful_;
|
|
}
|
|
Wt::Signal<int64_t>& uploadFailed()
|
|
{
|
|
return uploadFailed_;
|
|
}
|
|
|
|
Wt::Http::UploadedFile getUploadedFile()
|
|
{
|
|
return upload_->uploadedFiles().front();
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
upload_ = std::make_unique<Wt::WFileUpload>();
|
|
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<int64_t> uploadFailed_;
|
|
|
|
std::unique_ptr<Wt::WFileUpload> 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);
|
|
}
|