Composer Class Reference
[Composer example]

An E-mail composer widget. More...

#include <Composer.h>

Inheritance diagram for Composer:

Inheritance graph
[legend]

List of all members.

Public Member Functions

 Composer (WContainerWidget *parent=0)
 Construct a new Composer.
void setTo (const std::vector< Contact > &to)
 Set message To: contacts.
void setSubject (const WString &subject)
 Set subject.
void setMessage (const WString &message)
 Set the message.
void setAddressBook (const std::vector< Contact > &addressBook)
 Set the address book, for autocomplete suggestions.
std::vector< Contactto () const
 Get the To: contacts.
std::vector< Contactcc () const
 Get the Cc: contacts.
std::vector< Contactbcc () const
 Get the Bc: contacts.
const WStringsubject () const
 Get the subject.
std::vector< Attachmentattachments () const
 Get the list of attachments.
const WStringmessage () const
 Get the message.

Public Attributes

Wt::Signal< void > send
 The message is ready to be sent...
Wt::Signal< void > discard
 The message must be discarded.

Private Slots

void attachMore ()
 Add an attachment edit.
void removeAttachment (AttachmentEdit *attachment)
 Remove the given attachment edit.
void sendIt ()
 Slot attached to the Send button.
void saveNow ()
 Slot attached to the Save now button.
void discardIt ()
 Slot attached to the Discard button.
void attachmentDone ()
 Slotcalled when an attachment has been uploaded.

Private Member Functions

void createUi ()
void saved ()
 All attachments have been processed, determine the result of saving the message.
void setStatus (const WString &text, const WString &style)
 Set the status, and apply the given style.

Private Attributes

WContainerWidgetlayout_
WPushButtontopSendButton_
WPushButtontopSaveNowButton_
WPushButtontopDiscardButton_
WPushButtonbotSendButton_
WPushButtonbotSaveNowButton_
WPushButtonbotDiscardButton_
WTextstatusMsg_
WTableedits_
AddresseeEdittoEdit_
 To: Addressees edit.
AddresseeEditccEdit_
 Cc: Addressees edit.
AddresseeEditbccEdit_
 Bcc: Addressees edit.
ContactSuggestionscontactSuggestions_
 The suggestions popup for the addressee edits.
WLineEditsubject_
 The subject line edit.
OptionListoptions_
 OptionsList for editing Cc or Bcc.
Optionaddcc_
 Option for editing Cc:.
Optionaddbcc_
 Option for editing Bcc:.
OptionattachFile_
 Option for attaching a file.
OptionattachOtherFile_
 Option for attaching another file.
std::vector< AttachmentEdit * > attachments_
 Array which holds all the attachments, including one extra invisible one.
WTextAreamessage_
 WTextArea for the main message.
bool saving_
 state when waiting asyncrhonously for attachments to be uploaded
bool sending_
int attachmentsPending_
 number of attachments waiting to be uploaded during saving

Friends

class AttachmentEdit


Detailed Description

An E-mail composer widget.

This widget is part of the Wt composer example.

Definition at line 40 of file Composer.h.


Constructor & Destructor Documentation

Composer::Composer ( WContainerWidget parent = 0  ) 

Construct a new Composer.

Definition at line 25 of file Composer.C.

00026   : WCompositeWidget(parent),
00027     saving_(false),
00028     sending_(false)
00029 {
00030   setImplementation(layout_ = new WContainerWidget());
00031 
00032   createUi();
00033 }


Member Function Documentation

void Composer::setTo ( const std::vector< Contact > &  to  ) 

Set message To: contacts.

Definition at line 35 of file Composer.C.

00036 {
00037   toEdit_->setAddressees(to);
00038 }

void Composer::setSubject ( const WString subject  ) 

Set subject.

Definition at line 40 of file Composer.C.

00041 {
00042   subject_->setText(subject);
00043 }

void Composer::setMessage ( const WString message  ) 

Set the message.

Definition at line 45 of file Composer.C.

00046 {
00047   message_->setText(message);
00048 }

void Composer::setAddressBook ( const std::vector< Contact > &  addressBook  ) 

Set the address book, for autocomplete suggestions.

Definition at line 65 of file Composer.C.

00066 {
00067   contactSuggestions_->setAddressBook(contacts);
00068 }

std::vector< Contact > Composer::to (  )  const

Get the To: contacts.

Definition at line 50 of file Composer.C.

00051 {
00052   return toEdit_->addressees();
00053 }

std::vector< Contact > Composer::cc (  )  const

Get the Cc: contacts.

Definition at line 55 of file Composer.C.

00056 {
00057   return ccEdit_->addressees();
00058 }

std::vector< Contact > Composer::bcc (  )  const

Get the Bc: contacts.

Definition at line 60 of file Composer.C.

00061 {
00062   return bccEdit_->addressees();
00063 }

const WString & Composer::subject (  )  const

Get the subject.

Definition at line 70 of file Composer.C.

00071 {
00072   return subject_->text();
00073 }

std::vector< Attachment > Composer::attachments (  )  const

Get the list of attachments.

The ownership of the attachment spool files is transferred to the caller as well, be sure to delete them !

Definition at line 75 of file Composer.C.

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 }

const WString & Composer::message (  )  const

Get the message.

Definition at line 87 of file Composer.C.

00088 {
00089   return message_->text();
00090 }

void Composer::attachMore (  )  [private, slot]

Add an attachment edit.

Definition at line 248 of file Composer.C.

00249 {
00250   /*
00251    * Create and append the next AttachmentEdit, that will be hidden.
00252    */
00253   AttachmentEdit *edit = new AttachmentEdit(this);
00254   edits_->elementAt(5, 1)->insertBefore(edit, attachOtherFile_);
00255   attachments_.push_back(edit);
00256   attachments_.back()->hide();
00257 
00258   // Connect the attachOtherFile_ option to show this attachment.
00259   attachOtherFile_->item()->clicked().connect(SLOT(attachments_.back(),
00260                                                    WWidget::show));
00261 }

void Composer::removeAttachment ( AttachmentEdit attachment  )  [private, slot]

Remove the given attachment edit.

Definition at line 263 of file Composer.C.

00264 {
00265   /*
00266    * Remove the given attachment from the attachments list.
00267    */
00268   std::vector<AttachmentEdit *>::iterator i
00269     = std::find(attachments_.begin(), attachments_.end(), attachment);
00270 
00271   if (i != attachments_.end()) {
00272     attachments_.erase(i);
00273     delete attachment;
00274 
00275     if (attachments_.size() == 1) {
00276       /*
00277        * This was the last visible attachment, thus, we should switch
00278        * the option control again.
00279        */
00280       attachOtherFile_->hide();
00281       attachFile_->show();
00282       attachFile_->item()->clicked().connect(SLOT(attachments_.back(),
00283                                                   WWidget::show));
00284     }
00285   }
00286 }

void Composer::sendIt (  )  [private, slot]

Slot attached to the Send button.

Tries to save the mail message, and if succesfull, sends it.

Definition at line 288 of file Composer.C.

00289 {
00290   if (!sending_) {
00291     sending_ = true;
00292 
00293     /*
00294      * First save -- this will check for the sending_ state
00295      * signal if successfull.
00296      */
00297     saveNow();
00298   }
00299 }

void Composer::saveNow (  )  [private, slot]

Slot attached to the Save now button.

Tries to save the mail message, and gives feedback on failure and on success.

Definition at line 301 of file Composer.C.

00302 {
00303   if (!saving_) {
00304     saving_ = true;
00305 
00306     /*
00307      * Check if any attachments still need to be uploaded.
00308      * This may be the case when fileupload change events could not
00309      * be caught (for example in Konqueror).
00310      */
00311     attachmentsPending_ = 0;
00312 
00313     for (unsigned i = 0; i < attachments_.size() - 1; ++i) {
00314       if (attachments_[i]->uploadNow()) {
00315         ++attachmentsPending_;
00316 
00317         // this will trigger attachmentDone() when done, see
00318         // the AttachmentEdit constructor.
00319       }
00320     }
00321 
00322     std::cerr << "Attachments pending: " << attachmentsPending_ << std::endl;
00323     if (attachmentsPending_)
00324       setStatus(tr("msg.uploading"), "status");
00325     else
00326       saved();
00327   }
00328 }

void Composer::discardIt (  )  [private, slot]

Slot attached to the Discard button.

Discards the current message: emits the discard event.

Definition at line 385 of file Composer.C.

00386 { 
00387   discard.emit();
00388 }

void Composer::attachmentDone (  )  [private, slot]

Slotcalled when an attachment has been uploaded.

This used during while saving the email and waiting for remaining attachments to be uploaded. It is connected to the AttachmentEdit control signals that are emitted when an attachment has been processed.

Definition at line 330 of file Composer.C.

00331 {
00332   if (saving_) {
00333     --attachmentsPending_;
00334     std::cerr << "Attachments still: " << attachmentsPending_ << std::endl;
00335 
00336     if (attachmentsPending_ == 0)
00337       saved();
00338   }
00339 }

void Composer::createUi (  )  [private]

Definition at line 92 of file Composer.C.

00093 {
00094   setStyleClass("darker");
00095 
00096   // horizontal layout container, used for top and bottom buttons.
00097   WContainerWidget *horiz;
00098 
00099   /*
00100    * Top buttons
00101    */
00102   horiz = new WContainerWidget(layout_);
00103   horiz->setPadding(5);
00104   topSendButton_ = new WPushButton(tr("msg.send"), horiz);
00105   topSendButton_->setStyleClass("default"); // default action
00106   topSaveNowButton_ = new WPushButton(tr("msg.savenow"), horiz);
00107   topDiscardButton_ = new WPushButton(tr("msg.discard"), horiz);
00108 
00109   // Text widget which shows status messages, next to the top buttons.
00110   statusMsg_ = new WText(horiz);
00111   statusMsg_->setMargin(15, Left);
00112 
00113   /*
00114    * To, Cc, Bcc, Subject, Attachments
00115    *
00116    * They are organized in a two-column table: left column for
00117    * labels, and right column for the edit.
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    * To, Cc, Bcc
00127    */
00128   toEdit_ = new AddresseeEdit(tr("msg.to"), edits_->elementAt(0, 1),
00129                               edits_->elementAt(0, 0));
00130   // add some space above To:
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    * Addressbook suggestions popup
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    * We use an OptionList widget to show the expand options for
00152    * ccEdit_ and bccEdit_ nicely next to each other, separated
00153    * by pipe characters.
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    * Subject
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    * Attachments
00169    */
00170   new WImage("icons/paperclip.png", edits_->elementAt(5, 0));
00171   edits_->elementAt(5, 0)->setContentAlignment(AlignRight | AlignTop);
00172 
00173   
00174   // Attachment edits: we always have the next attachmentedit ready
00175   // but hidden. This improves the response time, since the show()
00176   // and hide() slots are stateless.
00177   attachments_.push_back(new AttachmentEdit(this, edits_->elementAt(5, 1)));
00178   attachments_.back()->hide();
00179 
00180   /*
00181    * Two options for attaching files. The first does not say 'another'.
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    * Message
00191    */
00192   message_ = new WTextArea(layout_);
00193   message_->setColumns(80);
00194   message_->setRows(10); // should be 20, but let's keep it smaller
00195   message_->setMargin(10);
00196 
00197   /*
00198    * Bottom buttons
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    * Button events.
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    * Option events to show the cc or Bcc edit.
00219    *
00220    * Clicking on the option should both show the corresponding edit, and
00221    * hide the option itself.
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 
00227   addbcc_->item()->clicked().connect(SLOT(bccEdit_, WWidget::show));
00228   addbcc_->item()->clicked().connect(SLOT(addbcc_, WWidget::hide));
00229   addbcc_->item()->clicked().connect(SLOT(options_, OptionList::update));
00230 
00231   /*
00232    * Option event to attach the first attachment.
00233    *
00234    * We show the first attachment, and call attachMore() to prepare the
00235    * next attachment edit that will be hidden.
00236    *
00237    * In addition, we need to show the 'attach More' option, and hide the
00238    * 'attach' option.
00239    */
00240   attachFile_->item()->clicked().connect(SLOT(attachments_.back(),
00241                                               WWidget::show));
00242   attachFile_->item()->clicked().connect(SLOT(attachOtherFile_, WWidget::show));
00243   attachFile_->item()->clicked().connect(SLOT(attachFile_, WWidget::hide));
00244   attachFile_->item()->clicked().connect(SLOT(this, Composer::attachMore));
00245   attachOtherFile_->item()->clicked().connect(SLOT(this, Composer::attachMore));
00246 }

void Composer::saved (  )  [private]

All attachments have been processed, determine the result of saving the message.

Definition at line 347 of file Composer.C.

00348 {
00349   /*
00350    * All attachments have been processed.
00351    */
00352 
00353   bool attachmentsFailed = false;
00354   for (unsigned i = 0; i < attachments_.size() - 1; ++i)
00355     if (attachments_[i]->uploadFailed()) {
00356       attachmentsFailed = true;
00357       break;
00358     }
00359 
00360   if (attachmentsFailed) {
00361     setStatus(tr("msg.attachment.failed"), "error");
00362   } else {
00363 #ifndef WIN32
00364     time_t t = time(0);
00365     struct tm td;
00366     gmtime_r(&t, &td);
00367     char buffer[100];
00368     strftime(buffer, 100, "%H:%M", &td);
00369 #else
00370     char buffer[] = "server"; // Should fix this; for now just make sense
00371 #endif
00372     setStatus(tr("msg.ok"), "status");
00373     statusMsg_->setText(std::string("Draft saved at ") + buffer);
00374 
00375     if (sending_) {
00376       send.emit();
00377       return;
00378     }
00379   }
00380 
00381   saving_ = false;
00382   sending_ = false;
00383 }

void Composer::setStatus ( const WString text,
const WString style 
) [private]

Set the status, and apply the given style.

Definition at line 341 of file Composer.C.

00342 {
00343   statusMsg_->setText(text);
00344   statusMsg_->setStyleClass(style);
00345 }


Friends And Related Function Documentation

friend class AttachmentEdit [friend]

Definition at line 195 of file Composer.h.


Member Data Documentation

The message is ready to be sent...

Definition at line 93 of file Composer.h.

The message must be discarded.

Definition at line 97 of file Composer.h.

Definition at line 100 of file Composer.h.

Definition at line 102 of file Composer.h.

Definition at line 102 of file Composer.h.

Definition at line 102 of file Composer.h.

Definition at line 103 of file Composer.h.

Definition at line 103 of file Composer.h.

Definition at line 103 of file Composer.h.

Definition at line 104 of file Composer.h.

Definition at line 106 of file Composer.h.

To: Addressees edit.

Definition at line 109 of file Composer.h.

Cc: Addressees edit.

Definition at line 111 of file Composer.h.

Bcc: Addressees edit.

Definition at line 113 of file Composer.h.

The suggestions popup for the addressee edits.

Definition at line 116 of file Composer.h.

The subject line edit.

Definition at line 119 of file Composer.h.

OptionsList for editing Cc or Bcc.

Definition at line 122 of file Composer.h.

Option for editing Cc:.

Definition at line 125 of file Composer.h.

Option for editing Bcc:.

Definition at line 127 of file Composer.h.

Option for attaching a file.

Definition at line 129 of file Composer.h.

Option for attaching another file.

Definition at line 131 of file Composer.h.

std::vector<AttachmentEdit *> Composer::attachments_ [private]

Array which holds all the attachments, including one extra invisible one.

Definition at line 134 of file Composer.h.

WTextArea for the main message.

Definition at line 137 of file Composer.h.

bool Composer::saving_ [private]

state when waiting asyncrhonously for attachments to be uploaded

Definition at line 140 of file Composer.h.

bool Composer::sending_ [private]

Definition at line 140 of file Composer.h.

number of attachments waiting to be uploaded during saving

Definition at line 143 of file Composer.h.


The documentation for this class was generated from the following files:

Generated on Tue Sep 1 17:51:23 2009 for Wt by doxygen 1.5.6