Wt examples  3.2.3
/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 }

Generated on Thu Nov 1 2012 for the C++ Web Toolkit (Wt) by doxygen 1.7.5.1