00001
00002
00003
00004
00005
00006 #include <iostream>
00007
00008 #include "AddresseeEdit.h"
00009 #include "AttachmentEdit.h"
00010 #include "Composer.h"
00011 #include "ContactSuggestions.h"
00012 #include "Label.h"
00013 #include "Option.h"
00014 #include "OptionList.h"
00015
00016 #include <Wt/WContainerWidget>
00017 #include <Wt/WImage>
00018 #include <Wt/WLineEdit>
00019 #include <Wt/WPushButton>
00020 #include <Wt/WText>
00021 #include <Wt/WTable>
00022 #include <Wt/WTableCell>
00023 #include <Wt/WStringUtil>
00024
00025 Composer::Composer(WContainerWidget *parent)
00026 : WCompositeWidget(parent),
00027 saving_(false),
00028 sending_(false)
00029 {
00030 setImplementation(layout_ = new WContainerWidget());
00031
00032 createUi();
00033 }
00034
00035 void Composer::setTo(const std::vector<Contact>& to)
00036 {
00037 toEdit_->setAddressees(to);
00038 }
00039
00040 void Composer::setSubject(const WString& subject)
00041 {
00042 subject_->setText(subject);
00043 }
00044
00045 void Composer::setMessage(const WString& message)
00046 {
00047 message_->setText(message);
00048 }
00049
00050 std::vector<Contact> Composer::to() const
00051 {
00052 return toEdit_->addressees();
00053 }
00054
00055 std::vector<Contact> Composer::cc() const
00056 {
00057 return ccEdit_->addressees();
00058 }
00059
00060 std::vector<Contact> Composer::bcc() const
00061 {
00062 return bccEdit_->addressees();
00063 }
00064
00065 void Composer::setAddressBook(const std::vector<Contact>& contacts)
00066 {
00067 contactSuggestions_->setAddressBook(contacts);
00068 }
00069
00070 const WString& Composer::subject() const
00071 {
00072 return subject_->text();
00073 }
00074
00075 std::vector<Attachment> Composer::attachments() const
00076 {
00077 std::vector<Attachment> attachments;
00078
00079 for (unsigned i = 0; i < attachments_.size() - 1; ++i) {
00080 if (attachments_[i]->include())
00081 attachments.push_back(attachments_[i]->attachment());
00082 }
00083
00084 return attachments;
00085 }
00086
00087 const WString& Composer::message() const
00088 {
00089 return message_->text();
00090 }
00091
00092 void Composer::createUi()
00093 {
00094 setStyleClass("darker");
00095
00096
00097 WContainerWidget *horiz;
00098
00099
00100
00101
00102 horiz = new WContainerWidget(layout_);
00103 horiz->setPadding(5);
00104 topSendButton_ = new WPushButton(tr("msg.send"), horiz);
00105 topSendButton_->setStyleClass("default");
00106 topSaveNowButton_ = new WPushButton(tr("msg.savenow"), horiz);
00107 topDiscardButton_ = new WPushButton(tr("msg.discard"), horiz);
00108
00109
00110 statusMsg_ = new WText(horiz);
00111 statusMsg_->setMargin(15, Left);
00112
00113
00114
00115
00116
00117
00118
00119 edits_ = new WTable(layout_);
00120 edits_->setStyleClass("lighter");
00121 edits_->resize(WLength(100, WLength::Percentage), WLength::Auto);
00122 edits_->elementAt(0, 0)->resize(WLength(1, WLength::Percentage),
00123 WLength::Auto);
00124
00125
00126
00127
00128 toEdit_ = new AddresseeEdit(tr("msg.to"), edits_->elementAt(0, 1),
00129 edits_->elementAt(0, 0));
00130
00131 edits_->elementAt(0, 1)->setMargin(5, Top);
00132 ccEdit_ = new AddresseeEdit(tr("msg.cc"), edits_->elementAt(1, 1),
00133 edits_->elementAt(1, 0));
00134 bccEdit_ = new AddresseeEdit(tr("msg.bcc"), edits_->elementAt(2, 1),
00135 edits_->elementAt(2, 0));
00136
00137 ccEdit_->hide();
00138 bccEdit_->hide();
00139
00140
00141
00142
00143 contactSuggestions_ = new ContactSuggestions(layout_);
00144 contactSuggestions_->setStyleClass("suggest");
00145
00146 contactSuggestions_->forEdit(toEdit_);
00147 contactSuggestions_->forEdit(ccEdit_);
00148 contactSuggestions_->forEdit(bccEdit_);
00149
00150
00151
00152
00153
00154
00155 options_ = new OptionList(edits_->elementAt(3, 1));
00156
00157 options_->add(addcc_ = new Option(tr("msg.addcc")));
00158 options_->add(addbcc_ = new Option(tr("msg.addbcc")));
00159
00160
00161
00162
00163 new Label(tr("msg.subject"), edits_->elementAt(4, 0));
00164 subject_ = new WLineEdit(edits_->elementAt(4, 1));
00165 subject_->resize(WLength(99, WLength::Percentage), WLength::Auto);
00166
00167
00168
00169
00170 new WImage("icons/paperclip.png", edits_->elementAt(5, 0));
00171 edits_->elementAt(5, 0)->setContentAlignment(AlignRight | AlignTop);
00172
00173
00174
00175
00176
00177 attachments_.push_back(new AttachmentEdit(this, edits_->elementAt(5, 1)));
00178 attachments_.back()->hide();
00179
00180
00181
00182
00183 attachFile_ = new Option(tr("msg.attachfile"),
00184 edits_->elementAt(5, 1));
00185 attachOtherFile_ = new Option(tr("msg.attachanother"),
00186 edits_->elementAt(5, 1));
00187 attachOtherFile_->hide();
00188
00189
00190
00191
00192 message_ = new WTextArea(layout_);
00193 message_->setColumns(80);
00194 message_->setRows(10);
00195 message_->setMargin(10);
00196
00197
00198
00199
00200 horiz = new WContainerWidget(layout_);
00201 horiz->setPadding(5);
00202 botSendButton_ = new WPushButton(tr("msg.send"), horiz);
00203 botSendButton_->setStyleClass("default");
00204 botSaveNowButton_ = new WPushButton(tr("msg.savenow"), horiz);
00205 botDiscardButton_ = new WPushButton(tr("msg.discard"), horiz);
00206
00207
00208
00209
00210 topSendButton_->clicked().connect(SLOT(this, Composer::sendIt));
00211 botSendButton_->clicked().connect(SLOT(this, Composer::sendIt));
00212 topSaveNowButton_->clicked().connect(SLOT(this, Composer::saveNow));
00213 botSaveNowButton_->clicked().connect(SLOT(this, Composer::saveNow));
00214 topDiscardButton_->clicked().connect(SLOT(this, Composer::discardIt));
00215 botDiscardButton_->clicked().connect(SLOT(this, Composer::discardIt));
00216
00217
00218
00219
00220
00221
00222
00223 addcc_->item()->clicked().connect(SLOT(ccEdit_, WWidget::show));
00224 addcc_->item()->clicked().connect(SLOT(addcc_, WWidget::hide));
00225 addcc_->item()->clicked().connect(SLOT(options_, OptionList::update));
00226 addcc_->item()->clicked().connect(SLOT(ccEdit_, WFormWidget::setFocus));
00227
00228 addbcc_->item()->clicked().connect(SLOT(bccEdit_, WWidget::show));
00229 addbcc_->item()->clicked().connect(SLOT(addbcc_, WWidget::hide));
00230 addbcc_->item()->clicked().connect(SLOT(options_, OptionList::update));
00231 addbcc_->item()->clicked().connect(SLOT(bccEdit_, WFormWidget::setFocus));
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 attachFile_->item()->clicked().connect(SLOT(attachments_.back(),
00243 WWidget::show));
00244 attachFile_->item()->clicked().connect(SLOT(attachOtherFile_, WWidget::show));
00245 attachFile_->item()->clicked().connect(SLOT(attachFile_, WWidget::hide));
00246 attachFile_->item()->clicked().connect(SLOT(this, Composer::attachMore));
00247 attachOtherFile_->item()->clicked().connect(SLOT(this, Composer::attachMore));
00248 }
00249
00250 void Composer::attachMore()
00251 {
00252
00253
00254
00255 AttachmentEdit *edit = new AttachmentEdit(this);
00256 edits_->elementAt(5, 1)->insertBefore(edit, attachOtherFile_);
00257 attachments_.push_back(edit);
00258 attachments_.back()->hide();
00259
00260
00261 attachOtherFile_->item()->clicked().connect(SLOT(attachments_.back(),
00262 WWidget::show));
00263 }
00264
00265 void Composer::removeAttachment(AttachmentEdit *attachment)
00266 {
00267
00268
00269
00270 std::vector<AttachmentEdit *>::iterator i
00271 = std::find(attachments_.begin(), attachments_.end(), attachment);
00272
00273 if (i != attachments_.end()) {
00274 attachments_.erase(i);
00275 delete attachment;
00276
00277 if (attachments_.size() == 1) {
00278
00279
00280
00281
00282 attachOtherFile_->hide();
00283 attachFile_->show();
00284 attachFile_->item()->clicked().connect(SLOT(attachments_.back(),
00285 WWidget::show));
00286 }
00287 }
00288 }
00289
00290 void Composer::sendIt()
00291 {
00292 if (!sending_) {
00293 sending_ = true;
00294
00295
00296
00297
00298
00299 saveNow();
00300 }
00301 }
00302
00303 void Composer::saveNow()
00304 {
00305 if (!saving_) {
00306 saving_ = true;
00307
00308
00309
00310
00311
00312
00313 attachmentsPending_ = 0;
00314
00315 for (unsigned i = 0; i < attachments_.size() - 1; ++i) {
00316 if (attachments_[i]->uploadNow()) {
00317 ++attachmentsPending_;
00318
00319
00320
00321 }
00322 }
00323
00324 std::cerr << "Attachments pending: " << attachmentsPending_ << std::endl;
00325 if (attachmentsPending_)
00326 setStatus(tr("msg.uploading"), "status");
00327 else
00328 saved();
00329 }
00330 }
00331
00332 void Composer::attachmentDone()
00333 {
00334 if (saving_) {
00335 --attachmentsPending_;
00336 std::cerr << "Attachments still: " << attachmentsPending_ << std::endl;
00337
00338 if (attachmentsPending_ == 0)
00339 saved();
00340 }
00341 }
00342
00343 void Composer::setStatus(const WString& text, const WString& style)
00344 {
00345 statusMsg_->setText(text);
00346 statusMsg_->setStyleClass(style);
00347 }
00348
00349 void Composer::saved()
00350 {
00351
00352
00353
00354
00355 bool attachmentsFailed = false;
00356 for (unsigned i = 0; i < attachments_.size() - 1; ++i)
00357 if (attachments_[i]->uploadFailed()) {
00358 attachmentsFailed = true;
00359 break;
00360 }
00361
00362 if (attachmentsFailed) {
00363 setStatus(tr("msg.attachment.failed"), "error");
00364 } else {
00365 #ifndef WIN32
00366 time_t t = time(0);
00367 struct tm td;
00368 gmtime_r(&t, &td);
00369 char buffer[100];
00370 strftime(buffer, 100, "%H:%M", &td);
00371 #else
00372 char buffer[] = "server";
00373 #endif
00374 setStatus(tr("msg.ok"), "status");
00375 statusMsg_->setText(std::string("Draft saved at ") + buffer);
00376
00377 if (sending_) {
00378 send.emit();
00379 return;
00380 }
00381 }
00382
00383 saving_ = false;
00384 sending_ = false;
00385 }
00386
00387 void Composer::discardIt()
00388 {
00389 discard.emit();
00390 }