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