Wt examples: composer/AttachmentEdit.C Source File

Wt examples 4.10.4

Loading...
Searching...
No Matches
AttachmentEdit.C
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6
7#include <fstream>
8#ifndef WIN32
9#include <unistd.h>
10#endif
11
12#include <iostream>
13
14#include <Wt/WAnchor.h>
15#include <Wt/WApplication.h>
16#include <Wt/WCheckBox.h>
17#include <Wt/WCssDecorationStyle.h>
18#include <Wt/WFileResource.h>
19#include <Wt/WLink.h>
20#include <Wt/WFileUpload.h>
21#include <Wt/WProgressBar.h>
22#include <Wt/WText.h>
23
24#include "Attachment.h"
25#include "AttachmentEdit.h"
26#include "Composer.h"
27#include "Option.h"
28
29AttachmentEdit::UploadInfo::UploadInfo(const Http::UploadedFile& f)
30 : WContainerWidget(),
31 info_(f)
32{
33 /*
34 * Include the file ?
35 */
36 keep_ = this->addWidget(std::make_unique<WCheckBox>());
37 keep_->setChecked();
38
39 /*
40 * Give information on the file uploaded.
41 */
42 std::streamsize fsize = 0;
43 {
44 std::ifstream theFile(info_.spoolFileName().c_str());
45 theFile.seekg(0, std::ios_base::end);
46 fsize = theFile.tellg();
47 theFile.seekg(0);
48 }
49 std::u32string size;
50 if (fsize < 1024)
51 size = WString(std::to_string(fsize)) + U" bytes";
52 else
53 size = WString(std::to_string((int)(fsize / 1024)))
54 + U"kb";
55
56 std::u32string fn = static_cast<std::u32string>
57 (escapeText(WString(info_.clientFileName())));
58
59 downloadLink_
60 = this->addWidget(std::make_unique<WAnchor>("", fn + U" (<i>" + WString(info_.contentType())
61 + U"</i>) " + size));
62
63 auto res = std::make_shared<WFileResource>(info_.contentType(),info_.spoolFileName());
64 res->suggestFileName(info_.clientFileName());
65 downloadLink_->setLink(WLink(res));
66}
67
68AttachmentEdit::AttachmentEdit(Composer *composer)
69 : WContainerWidget(),
70 composer_(composer),
71 uploadDone_(),
72 uploadFailed_(false)
73{
74 /*
75 * The file upload itself.
76 */
77 upload_ = this->addWidget(std::make_unique<WFileUpload>());
78 upload_->setMultiple(true);
79 upload_->setFileTextSize(40);
80
81 /*
82 * A progress bar
83 */
84 std::unique_ptr<WProgressBar> progress = std::make_unique<WProgressBar>();
85 progress->setFormat(WString::Empty);
86 progress->setVerticalAlignment(AlignmentFlag::Middle);
87 upload_->setProgressBar(std::move(progress));
88
89 /*
90 * The 'remove' option.
91 */
92 remove_ = this->addWidget(std::make_unique<Option>(tr("msg.remove")));
93 upload_->decorationStyle().font().setSize(FontSize::Smaller);
94 upload_->setVerticalAlignment(AlignmentFlag::Middle);
95 remove_->setMargin(5, Side::Left);
96 remove_->item()->clicked().connect(this, &WWidget::hide);
97 remove_->item()->clicked().connect(this, &AttachmentEdit::remove);
98
99 // The error message.
100 error_ = this->addWidget(std::make_unique<WText>(""));
101 error_->setStyleClass("error");
102 error_->setMargin(WLength(5), Side::Left);
103
104 /*
105 * React to events.
106 */
107
108 // Try to catch the fileupload change signal to trigger an upload.
109 // We could do like google and at a delay with a WTimer as well...
110 upload_->changed().connect(upload_, &WFileUpload::upload);
111
112 // React to a succesfull upload.
113 upload_->uploaded().connect(this, &AttachmentEdit::uploaded);
114
115 // React to a fileupload problem.
116 upload_->fileTooLarge().connect(this, &AttachmentEdit::fileTooLarge);
117
118 /*
119 * Connect the uploadDone signal to the Composer's attachmentDone,
120 * so that the Composer can keep track of attachment upload progress,
121 * if it wishes.
122 */
123 uploadDone_.connect(composer, &Composer::attachmentDone);
124}
125
126 bool AttachmentEdit::uploadNow()
127{
128 /*
129 * See if this attachment still needs to be uploaded,
130 * and return if a new asynchronous upload is started.
131 */
132 if (upload_) {
133 if (upload_->canUpload()) {
134 upload_->upload();
135 return true;
136 } else
137 return false;
138 } else
139 return false;
140}
141
142 void AttachmentEdit::uploaded()
143{
144 std::vector<Http::UploadedFile> files = upload_->uploadedFiles();
145
146 if (!files.empty()) {
147 /*
148 * Delete this widgets since we have a succesfull upload.
149 */
150 upload_ = 0;
151 this->removeWidget(remove_);
152 remove_ = 0;
153 this->removeWidget(error_);
154 error_ = 0;
155
156 for (unsigned i = 0; i < files.size(); ++i) {
157 UploadInfo *info = this->addWidget(std::make_unique<UploadInfo>(files[i]));
158 uploadInfo_.push_back(info);
159 }
160 } else {
161 error_->setText(tr("msg.file-empty"));
162 uploadFailed_ = true;
163 }
164
165 /*
166 * Signal to the Composer that a new asynchronous file upload was processed.
167 */
168 uploadDone_.emit();
169}
170
171 void AttachmentEdit::remove()
172{
173 composer_->removeAttachment(this);
174}
175
176 void AttachmentEdit::fileTooLarge(::int64_t size)
177{
178 error_->setText(tr("msg.file-too-large")
179 .arg(size / 1024)
180 .arg(WApplication::instance()->maximumRequestSize() / 1024));
181 uploadFailed_ = true;
182
183 /*
184 * Signal to the Composer that a new asyncrhonous file upload was processed.
185 */
186 uploadDone_.emit();
187}
188
189std::vector<Attachment> AttachmentEdit::attachments()
190{
191 std::vector<Attachment> result;
192
193 for (unsigned i = 0; i < uploadInfo_.size(); ++i) {
194 if (uploadInfo_[i]->keep_->isChecked()) {
195 Http::UploadedFile& f = uploadInfo_[i]->info_;
196 f.stealSpoolFile();
197 result.push_back(Attachment
198 (WString(f.clientFileName()),
199 WString(f.contentType()),
200 f.spoolFileName()));
201 }
202 }
203
204 return result;
205}
AttachmentEdit.h
Attachment.h
Composer.h
Option.h
AttachmentEdit::UploadInfo
Definition AttachmentEdit.h:74
AttachmentEdit::UploadInfo::keep_
WCheckBox * keep_
The check box to keep or discard the uploaded file.
Definition AttachmentEdit.h:84
AttachmentEdit::UploadInfo::downloadLink_
WAnchor * downloadLink_
Anchor referencing the file.
Definition AttachmentEdit.h:81
AttachmentEdit::UploadInfo::UploadInfo
UploadInfo(const Http::UploadedFile &f)
Definition AttachmentEdit.C:29
AttachmentEdit::UploadInfo::info_
Http::UploadedFile info_
Definition AttachmentEdit.h:78
AttachmentEdit::uploadNow
bool uploadNow()
Updates the file now.
Definition AttachmentEdit.C:126
AttachmentEdit::remove
void remove()
Slot triggered when the users wishes to remove this attachment edit.
Definition AttachmentEdit.C:171
AttachmentEdit::error_
WText * error_
The text box to display an error (empty or too big file)
Definition AttachmentEdit.h:90
AttachmentEdit::composer_
Composer * composer_
Definition AttachmentEdit.h:66
AttachmentEdit::remove_
Option * remove_
The option to cancel the file upload.
Definition AttachmentEdit.h:93
AttachmentEdit::uploadDone_
Signal uploadDone_
Definition AttachmentEdit.h:68
AttachmentEdit::uploadFailed_
bool uploadFailed_
The state of the last upload process.
Definition AttachmentEdit.h:96
AttachmentEdit::uploaded
void uploaded()
Slot triggered when the WFileUpload completed an upload.
Definition AttachmentEdit.C:142
AttachmentEdit::attachments
std::vector< Attachment > attachments()
Returns the attachment.
Definition AttachmentEdit.C:189
AttachmentEdit::upload_
WFileUpload * upload_
The WFileUpload control.
Definition AttachmentEdit.h:71
AttachmentEdit::uploadInfo_
std::vector< UploadInfo * > uploadInfo_
Definition AttachmentEdit.h:87
AttachmentEdit::AttachmentEdit
AttachmentEdit(Composer *composer)
Creates an attachment edit field.
Definition AttachmentEdit.C:68
AttachmentEdit::fileTooLarge
void fileTooLarge(::int64_t size)
Slot triggered when the WFileUpload received an oversized file.
Definition AttachmentEdit.C:176
Attachment
An email attachment.
Definition Attachment.h:20
Composer
An E-mail composer widget.
Definition Composer.h:41
Composer::attachmentDone
void attachmentDone()
Slotcalled when an attachment has been uploaded.
Definition Composer.C:338
Composer::removeAttachment
void removeAttachment(AttachmentEdit *attachment)
Remove the given attachment edit.
Definition Composer.C:271
Option::item
WInteractWidget * item()
Returns the clickable part.
Definition Option.h:44