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