Wt examples 3.3.12
Composer.C
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6#include <iostream>
7
8#include "AddresseeEdit.h"
9#include "AttachmentEdit.h"
10#include "Composer.h"
11#include "ContactSuggestions.h"
12#include "Label.h"
13#include "Option.h"
14#include "OptionList.h"
15
16#include <Wt/WContainerWidget>
17#include <Wt/WImage>
18#include <Wt/WLineEdit>
19#include <Wt/WPushButton>
20#include <Wt/WText>
21#include <Wt/WTable>
22#include <Wt/WTableCell>
23#include <Wt/WStringUtil>
24
26 : WCompositeWidget(parent),
27 saving_(false),
28 sending_(false)
29{
31
32 createUi();
33}
34
35void Composer::setTo(const std::vector<Contact>& to)
36{
38}
39
40void Composer::setSubject(const WString& subject)
41{
43}
44
45void Composer::setMessage(const WString& message)
46{
48}
49
50std::vector<Contact> Composer::to() const
51{
52 return toEdit_->addressees();
53}
54
55std::vector<Contact> Composer::cc() const
56{
57 return ccEdit_->addressees();
58}
59
60std::vector<Contact> Composer::bcc() const
61{
62 return bccEdit_->addressees();
63}
64
65void Composer::setAddressBook(const std::vector<Contact>& contacts)
66{
68}
69
71{
72 return subject_->text();
73}
74
75std::vector<Attachment> Composer::attachments() const
76{
77 std::vector<Attachment> attachments;
78
79 for (unsigned i = 0; i < attachments_.size() - 1; ++i) {
80 std::vector<Attachment> toadd = attachments_[i]->attachments();
81
82 attachments.insert(attachments.end(), toadd.begin(), toadd.end());
83 }
84
85 return attachments;
86}
87
89{
90 return message_->text();
91}
92
94{
95 setStyleClass("darker");
96
97 // horizontal layout container, used for top and bottom buttons.
98 WContainerWidget *horiz;
99
100 /*
101 * Top buttons
102 */
103 horiz = new WContainerWidget(layout_);
104 horiz->setPadding(5);
105 topSendButton_ = new WPushButton(tr("msg.send"), horiz);
106 topSendButton_->setStyleClass("default"); // default action
107 topSaveNowButton_ = new WPushButton(tr("msg.savenow"), horiz);
108 topDiscardButton_ = new WPushButton(tr("msg.discard"), horiz);
109
110 // Text widget which shows status messages, next to the top buttons.
111 statusMsg_ = new WText(horiz);
113
114 /*
115 * To, Cc, Bcc, Subject, Attachments
116 *
117 * They are organized in a two-column table: left column for
118 * labels, and right column for the edit.
119 */
120 edits_ = new WTable(layout_);
121 edits_->setStyleClass("lighter");
125
126 /*
127 * To, Cc, Bcc
128 */
129 toEdit_ = new AddresseeEdit(tr("msg.to"), edits_->elementAt(0, 1),
130 edits_->elementAt(0, 0));
131 // add some space above To:
132 edits_->elementAt(0, 1)->setMargin(5, Top);
133 ccEdit_ = new AddresseeEdit(tr("msg.cc"), edits_->elementAt(1, 1),
134 edits_->elementAt(1, 0));
135 bccEdit_ = new AddresseeEdit(tr("msg.bcc"), edits_->elementAt(2, 1),
136 edits_->elementAt(2, 0));
137
138 ccEdit_->hide();
139 bccEdit_->hide();
140
141 /*
142 * Addressbook suggestions popup
143 */
145
149
150 /*
151 * We use an OptionList widget to show the expand options for
152 * ccEdit_ and bccEdit_ nicely next to each other, separated
153 * by pipe characters.
154 */
155 options_ = new OptionList(edits_->elementAt(3, 1));
156
157 options_->add(addcc_ = new Option(tr("msg.addcc")));
158 options_->add(addbcc_ = new Option(tr("msg.addbcc")));
159
160 /*
161 * Subject
162 */
163 new Label(tr("msg.subject"), edits_->elementAt(4, 0));
164 subject_ = new WLineEdit(edits_->elementAt(4, 1));
166
167 /*
168 * Attachments
169 */
170 new WImage("icons/paperclip.png", edits_->elementAt(5, 0));
172 edits_->elementAt(5, 0)->setPadding(3);
173
174 // Attachment edits: we always have the next attachmentedit ready
175 // but hidden. This improves the response time, since the show()
176 // and hide() slots are stateless.
177 attachments_.push_back(new AttachmentEdit(this, edits_->elementAt(5, 1)));
178 attachments_.back()->hide();
179
180 /*
181 * Two options for attaching files. The first does not say 'another'.
182 */
183 attachFile_ = new Option(tr("msg.attachfile"),
184 edits_->elementAt(5, 1));
185 attachOtherFile_ = new Option(tr("msg.attachanother"),
186 edits_->elementAt(5, 1));
188
189 /*
190 * Message
191 */
193 message_->setColumns(80);
194 message_->setRows(10); // should be 20, but let's keep it smaller
195 message_->setMargin(10);
196
197 /*
198 * Bottom buttons
199 */
200 horiz = new WContainerWidget(layout_);
201 horiz->setPadding(5);
202 botSendButton_ = new WPushButton(tr("msg.send"), horiz);
203 botSendButton_->setStyleClass("default");
204 botSaveNowButton_ = new WPushButton(tr("msg.savenow"), horiz);
205 botDiscardButton_ = new WPushButton(tr("msg.discard"), horiz);
206
207 /*
208 * Button events.
209 */
210 topSendButton_->clicked().connect(this, &Composer::sendIt);
211 botSendButton_->clicked().connect(this, &Composer::sendIt);
216
217 /*
218 * Option events to show the cc or Bcc edit.
219 *
220 * Clicking on the option should both show the corresponding edit, and
221 * hide the option itself.
222 */
223 addcc_->item()->clicked().connect(ccEdit_, &WWidget::show);
224 addcc_->item()->clicked().connect(addcc_, &WWidget::hide);
227
228 addbcc_->item()->clicked().connect(bccEdit_, &WWidget::show);
229 addbcc_->item()->clicked().connect(addbcc_, &WWidget::hide);
232
233 /*
234 * Option event to attach the first attachment.
235 *
236 * We show the first attachment, and call attachMore() to prepare the
237 * next attachment edit that will be hidden.
238 *
239 * In addition, we need to show the 'attach More' option, and hide the
240 * 'attach' option.
241 */
242 attachFile_->item()->clicked().connect(attachments_.back(), &WWidget::show);
245 attachFile_->item()->clicked().connect(this, &Composer::attachMore);
247}
248
250{
251 /*
252 * Create and append the next AttachmentEdit, that will be hidden.
253 */
254 AttachmentEdit *edit = new AttachmentEdit(this);
256 attachments_.push_back(edit);
257 attachments_.back()->hide();
258
259 // Connect the attachOtherFile_ option to show this attachment.
261 .connect(attachments_.back(), &WWidget::show);
262}
263
265{
266 /*
267 * Remove the given attachment from the attachments list.
268 */
269 std::vector<AttachmentEdit *>::iterator i
270 = std::find(attachments_.begin(), attachments_.end(), attachment);
271
272 if (i != attachments_.end()) {
273 attachments_.erase(i);
274 delete attachment;
275
276 if (attachments_.size() == 1) {
277 /*
278 * This was the last visible attachment, thus, we should switch
279 * the option control again.
280 */
282 attachFile_->show();
284 .connect(attachments_.back(), &WWidget::show);
285 }
286 }
287}
288
290{
291 if (!sending_) {
292 sending_ = true;
293
294 /*
295 * First save -- this will check for the sending_ state
296 * signal if successfull.
297 */
298 saveNow();
299 }
300}
301
303{
304 if (!saving_) {
305 saving_ = true;
306
307 /*
308 * Check if any attachments still need to be uploaded.
309 * This may be the case when fileupload change events could not
310 * be caught (for example in Konqueror).
311 */
313
314 for (unsigned i = 0; i < attachments_.size() - 1; ++i) {
315 if (attachments_[i]->uploadNow()) {
317
318 // this will trigger attachmentDone() when done, see
319 // the AttachmentEdit constructor.
320 }
321 }
322
323 std::cerr << "Attachments pending: " << attachmentsPending_ << std::endl;
325 setStatus(tr("msg.uploading"), "status");
326 else
327 saved();
328 }
329}
330
332{
333 if (saving_) {
335 std::cerr << "Attachments still: " << attachmentsPending_ << std::endl;
336
337 if (attachmentsPending_ == 0)
338 saved();
339 }
340}
341
342void Composer::setStatus(const WString& text, const WString& style)
343{
344 statusMsg_->setText(text);
346}
347
349{
350 /*
351 * All attachments have been processed.
352 */
353
354 bool attachmentsFailed = false;
355 for (unsigned i = 0; i < attachments_.size() - 1; ++i)
356 if (attachments_[i]->uploadFailed()) {
357 attachmentsFailed = true;
358 break;
359 }
360
361 if (attachmentsFailed) {
362 setStatus(tr("msg.attachment.failed"), "error");
363 } else {
364#ifndef WIN32
365 time_t t = time(0);
366 struct tm td;
367 gmtime_r(&t, &td);
368 char buffer[100];
369 strftime(buffer, 100, "%H:%M", &td);
370#else
371 char buffer[] = "server"; // Should fix this; for now just make sense
372#endif
373 setStatus(tr("msg.ok"), "status");
374 statusMsg_->setText(std::string("Draft saved at ") + buffer);
375
376 if (sending_) {
377 send.emit();
378 return;
379 }
380 }
381
382 saving_ = false;
383 sending_ = false;
384}
385
387{
388 discard.emit();
389}
An edit field for an email addressee.
std::vector< Contact > addressees() const
Get a list of addressees.
void setAddressees(const std::vector< Contact > &contacts)
Set a list of addressees.
An edit field for an email attachment.
WPushButton * botSaveNowButton_
Definition Composer.h:103
void sendIt()
Slot attached to the Send button.
Definition Composer.C:289
Composer(WContainerWidget *parent=0)
Construct a new Composer.
Definition Composer.C:25
WText * statusMsg_
Definition Composer.h:104
Option * attachOtherFile_
Option for attaching another file.
Definition Composer.h:131
void setMessage(const WString &message)
Set the message.
Definition Composer.C:45
void saved()
All attachments have been processed, determine the result of saving the message.
Definition Composer.C:348
WTextArea * message_
WTextArea for the main message.
Definition Composer.h:137
WPushButton * topSaveNowButton_
Definition Composer.h:102
std::vector< Contact > bcc() const
Get the Bc: contacts.
Definition Composer.C:60
const WString & message() const
Get the message.
Definition Composer.C:88
WPushButton * topSendButton_
Definition Composer.h:102
void setStatus(const WString &text, const WString &style)
Set the status, and apply the given style.
Definition Composer.C:342
AddresseeEdit * toEdit_
To: Addressees edit.
Definition Composer.h:109
Wt::Signal< void > send
The message is ready to be sent...
Definition Composer.h:93
void discardIt()
Slot attached to the Discard button.
Definition Composer.C:386
std::vector< Contact > to() const
Get the To: contacts.
Definition Composer.C:50
void attachMore()
Add an attachment edit.
Definition Composer.C:249
void saveNow()
Slot attached to the Save now button.
Definition Composer.C:302
WPushButton * botSendButton_
Definition Composer.h:103
bool saving_
state when waiting asyncrhonously for attachments to be uploaded
Definition Composer.h:140
WLineEdit * subject_
The subject line edit.
Definition Composer.h:119
WPushButton * topDiscardButton_
Definition Composer.h:102
int attachmentsPending_
number of attachments waiting to be uploaded during saving
Definition Composer.h:143
void setTo(const std::vector< Contact > &to)
Set message To: contacts.
Definition Composer.C:35
ContactSuggestions * contactSuggestions_
The suggestions popup for the addressee edits.
Definition Composer.h:116
Option * attachFile_
Option for attaching a file.
Definition Composer.h:129
WPushButton * botDiscardButton_
Definition Composer.h:103
Wt::Signal< void > discard
The message must be discarded.
Definition Composer.h:97
std::vector< AttachmentEdit * > attachments_
Array which holds all the attachments, including one extra invisible one.
Definition Composer.h:134
WTable * edits_
Definition Composer.h:106
Option * addbcc_
Option for editing Bcc:
Definition Composer.h:127
AddresseeEdit * ccEdit_
Cc: Addressees edit.
Definition Composer.h:111
bool sending_
Definition Composer.h:140
friend class AttachmentEdit
Definition Composer.h:194
void attachmentDone()
Slotcalled when an attachment has been uploaded.
Definition Composer.C:331
WContainerWidget * layout_
Definition Composer.h:100
void setSubject(const WString &subject)
Set subject.
Definition Composer.C:40
void removeAttachment(AttachmentEdit *attachment)
Remove the given attachment edit.
Definition Composer.C:264
const WString & subject() const
Get the subject.
Definition Composer.C:70
Option * addcc_
Option for editing Cc:
Definition Composer.h:125
void setAddressBook(const std::vector< Contact > &addressBook)
Set the address book, for autocomplete suggestions.
Definition Composer.C:65
std::vector< Contact > cc() const
Get the Cc: contacts.
Definition Composer.C:55
void createUi()
Definition Composer.C:93
AddresseeEdit * bccEdit_
Bcc: Addressees edit.
Definition Composer.h:113
OptionList * options_
OptionsList for editing Cc or Bcc.
Definition Composer.h:122
std::vector< Attachment > attachments() const
Get the list of attachments.
Definition Composer.C:75
A suggestion popup suggesting contacts from an addressbook.
void setAddressBook(const std::vector< Contact > &contacts)
Set the address book.
A label.
Definition Label.h:25
A list of options, separated by '|'.
Definition OptionList.h:41
void add(Option *option)
Add an Option to the list.
Definition OptionList.C:18
void update()
Updates the stateless implementations after an Option has been hidden or shown.
Definition OptionList.C:30
A clickable option.
Definition Option.h:32
WInteractWidget * item()
Returns the clickable part.
Definition Option.h:44
void emit(A1 a1=NoClass::none, A2 a2=NoClass::none, A3 a3=NoClass::none, A4 a4=NoClass::none, A5 a5=NoClass::none, A6 a6=NoClass::none) const
void setImplementation(WWidget *widget)
virtual void setStyleClass(const WString &styleClass)
virtual void insertBefore(WWidget *widget, WWidget *before)
void setContentAlignment(WFlags< AlignmentFlag > contentAlignment)
void setPadding(const WLength &padding, WFlags< Side > sides=All)
EventSignal< WMouseEvent > & clicked()
static WLength Auto
const WString & text() const
virtual void setText(const WString &text)
void forEdit(WFormWidget *edit, WFlags< PopupTrigger > popupTriggers=Editing)
WTableCell * elementAt(int row, int column)
virtual void setText(const WString &text)
const WString & text() const
void setRows(int rows)
void setColumns(int cols)
bool setText(const WString &text)
virtual void resize(const WLength &width, const WLength &height)
virtual void setMargin(const WLength &margin, WFlags< Side > sides=All)
virtual void setStyleClass(const WString &styleClass)
void setFocus()
static WString tr(const char *key)
AlignTop
AlignRight

Generated on Fri May 17 2024 for the C++ Web Toolkit (Wt) by doxygen 1.9.8