Wt examples: /home/koen/project/wt/public-git/wt/examples/composer/AttachmentEdit.C Source File

Wt examples 3.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

/home/koen/project/wt/public-git/wt/examples/composer/AttachmentEdit.C
Go to the documentation of this file.

    00001 /*
    00002  * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
    00003  *
    00004  * See the LICENSE file for terms of use.
    00005  */
    00006
    00007 #include <fstream>
    00008 #ifndef WIN32
    00009 #include <unistd.h>
    00010 #endif
    00011 #include <boost/lexical_cast.hpp>
    00012
    00013 #include <iostream>
    00014
    00015 #include <Wt/WAnchor>
    00016 #include <Wt/WApplication>
    00017 #include <Wt/WCheckBox>
    00018 #include <Wt/WCssDecorationStyle>
    00019 #include <Wt/WFileResource>
    00020 #include <Wt/WFileUpload>
    00021 #include <Wt/WProgressBar>
    00022 #include <Wt/WText>
    00023
    00024 #include "Attachment.h"
    00025 #include "AttachmentEdit.h"
    00026 #include "Composer.h"
    00027 #include "Option.h"
    00028
    00029 AttachmentEdit::UploadInfo::UploadInfo(const Http::UploadedFile& f,
    00030                                        WContainerWidget *parent)
    00031   : WContainerWidget(parent),
    00032     info_(f)
    00033 {
    00034   /*
    00035    * Include the file ?
    00036    */
    00037   keep_ = new WCheckBox(this);
    00038   keep_->setChecked();
    00039
    00040   /*
    00041    * Give information on the file uploaded.
    00042    */
    00043   std::streamsize fsize = 0;
    00044   {
    00045     std::ifstream theFile(info_.spoolFileName().c_str());
    00046     theFile.seekg(0, std::ios_base::end);
    00047     fsize = theFile.tellg();
    00048     theFile.seekg(0);
    00049   }
    00050   std::wstring size;
    00051   if (fsize < 1024)
    00052     size = boost::lexical_cast<std::wstring>(fsize) + L" bytes";
    00053   else
    00054     size = boost::lexical_cast<std::wstring>((int)(fsize / 1024))
    00055       + L"kb";
    00056
    00057   std::wstring fn = static_cast<std::wstring>
    00058     (escapeText(WString::fromUTF8(info_.clientFileName())));
    00059
    00060   downloadLink_
    00061     = new WAnchor("", fn + L" (<i>" + WString::fromUTF8(info_.contentType())
    00062                   + L"</i>) " + size, this);
    00063
    00064   WFileResource *res = new WFileResource(info_.contentType(),
    00065                                          info_.spoolFileName(),
    00066                                          this);
    00067   res->suggestFileName(info_.clientFileName());
    00068   downloadLink_->setLink(res);
    00069 }
    00070
    00071 AttachmentEdit::AttachmentEdit(Composer *composer, WContainerWidget *parent)
    00072   : WContainerWidget(parent),
    00073     composer_(composer),
    00074     uploadDone_(this),
    00075     uploadFailed_(false)
    00076 {
    00077   /*
    00078    * The file upload itself.
    00079    */
    00080   upload_ = new WFileUpload(this);
    00081   upload_->setMultiple(true);
    00082   upload_->setFileTextSize(40);
    00083
    00084   /*
    00085    * A progress bar
    00086    */
    00087   WProgressBar *progress = new WProgressBar();
    00088   progress->setFormat(WString::Empty);
    00089   progress->setVerticalAlignment(AlignMiddle);
    00090   upload_->setProgressBar(progress);
    00091
    00092   /*
    00093    * The 'remove' option.
    00094    */
    00095   remove_ = new Option(tr("msg.remove"), this);
    00096   upload_->decorationStyle().font().setSize(WFont::Smaller);
    00097   upload_->setVerticalAlignment(AlignMiddle);
    00098   remove_->setMargin(5, Left);
    00099   remove_->item()->clicked().connect(this, &WWidget::hide);
    00100   remove_->item()->clicked().connect(this, &AttachmentEdit::remove);
    00101
    00102   // The error message.
    00103   error_ = new WText("", this);
    00104   error_->setStyleClass("error");
    00105   error_->setMargin(WLength(5), Left);
    00106
    00107   /*
    00108    * React to events.
    00109    */
    00110
    00111   // Try to catch the fileupload change signal to trigger an upload.
    00112   // We could do like google and at a delay with a WTimer as well...
    00113   upload_->changed().connect(upload_, &WFileUpload::upload);
    00114
    00115   // React to a succesfull upload.
    00116   upload_->uploaded().connect(this, &AttachmentEdit::uploaded);
    00117
    00118   // React to a fileupload problem.
    00119   upload_->fileTooLarge().connect(this, &AttachmentEdit::fileTooLarge);
    00120
    00121   /*
    00122    * Connect the uploadDone signal to the Composer's attachmentDone,
    00123    * so that the Composer can keep track of attachment upload progress,
    00124    * if it wishes.
    00125    */
    00126   uploadDone_.connect(composer, &Composer::attachmentDone);
    00127 }
    00128
    00129 bool AttachmentEdit::uploadNow()
    00130 {
    00131   /*
    00132    * See if this attachment still needs to be uploaded,
    00133    * and return if a new asynchronous upload is started.
    00134    */
    00135   if (upload_) {
    00136     if (upload_->canUpload()) {
    00137       upload_->upload();
    00138       return true;
    00139     } else
    00140       return false;
    00141   } else
    00142     return false;
    00143 }
    00144
    00145 void AttachmentEdit::uploaded()
    00146 {
    00147   std::vector<Http::UploadedFile> files = upload_->uploadedFiles();
    00148
    00149   if (!files.empty()) {
    00150     /*
    00151      * Delete this widgets since we have a succesfull upload.
    00152      */
    00153     delete upload_;
    00154     upload_ = 0;
    00155     delete remove_;
    00156     remove_ = 0;
    00157     delete error_;
    00158     error_ = 0;
    00159
    00160     for (unsigned i = 0; i < files.size(); ++i)
    00161       uploadInfo_.push_back(new UploadInfo(files[i], this));
    00162   } else {
    00163     error_->setText(tr("msg.file-empty"));
    00164     uploadFailed_ = true;
    00165   }
    00166
    00167   /*
    00168    * Signal to the Composer that a new asynchronous file upload was processed.
    00169    */
    00170   uploadDone_.emit();
    00171 }
    00172
    00173 void AttachmentEdit::remove()
    00174 {
    00175   composer_->removeAttachment(this);
    00176 }
    00177
    00178 void AttachmentEdit::fileTooLarge(::int64_t size)
    00179 {
    00180   error_->setText(tr("msg.file-too-large")
    00181                   .arg(size / 1024)
    00182                   .arg(WApplication::instance()->maximumRequestSize() / 1024));
    00183   uploadFailed_ = true;
    00184
    00185   /*
    00186    * Signal to the Composer that a new asyncrhonous file upload was processed.
    00187    */
    00188   uploadDone_.emit();
    00189 }
    00190
    00191 std::vector<Attachment> AttachmentEdit::attachments()
    00192 {
    00193   std::vector<Attachment> result;
    00194
    00195   for (unsigned i = 0; i < uploadInfo_.size(); ++i) {
    00196     if (uploadInfo_[i]->keep_->isChecked()) {
    00197       Http::UploadedFile& f = uploadInfo_[i]->info_;
    00198       f.stealSpoolFile();
    00199       result.push_back(Attachment
    00200                        (WString::fromUTF8(f.clientFileName()),
    00201                         WString::fromUTF8(f.contentType()),
    00202                         f.spoolFileName()));
    00203     }
    00204   }
    00205
    00206   return result;
    00207 }