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

Generated on Wed Jul 27 2011 for the C++ Web Toolkit (Wt) by doxygen 1.7.4