00001 #include <qmultilineedit.h>
00002 #include <qmessagebox.h>
00003 #include <qpopupmenu.h>
00004 #include <qcombobox.h>
00005 #include <qlineedit.h>
00006 #include <qaction.h>
00007 #include <qtimer.h>
00008 #include <qlabel.h>
00009 #include <qapplication.h>
00010
00011 #include <qpe/resource.h>
00012 #include <qpe/config.h>
00013
00014 #include <opie/ofiledialog.h>
00015
00016 #include "mailstatusbar.h"
00017 #include "addresspicker.h"
00018 #include "listviewplus.h"
00019 #include "smtphandler.h"
00020 #include "composer.h"
00021 #include "rename.h"
00022
00023 AttachViewItem::AttachViewItem(QListView *parent, Attachment &attachment)
00024 : QListViewItem(parent), _attachment(attachment)
00025 {
00026 setPixmap(0, _attachment.docLnk().pixmap().isNull() ? Resource::loadPixmap("UnknownDocument-14") : _attachment.docLnk().pixmap());
00027 setText(0, _attachment.newName().isEmpty() ? _attachment.fileName() : _attachment.newName());
00028 setText(1, _attachment.description());
00029 }
00030
00031 Composer::Composer(QWidget *parent, const char *name, WFlags fl, bool sendQueue)
00032 : ComposerBase(parent, name, fl), _inLoop(false)
00033 {
00034 _sendQueued = sendQueue;
00035 status->setStopEnabled(false);
00036 to->setFocus();
00037
00038 connect(sendmail, SIGNAL(activated()), SLOT(slotSendMail()));
00039 connect(queuemail, SIGNAL(activated()), SLOT(slotQueueMail()));
00040 connect(addressbook, SIGNAL(activated()), SLOT(slotOpenAddressPicker()));
00041 connect(addattach, SIGNAL(activated()), SLOT(slotAddAttach()));
00042 connect(delattach, SIGNAL(activated()), SLOT(slotDelAttach()));
00043
00044 connect(from, SIGNAL(activated(int)), SLOT(slotFromChanged(int)));
00045
00046 connect(attachPopup, SIGNAL(activated(int)), SLOT(slotPopupHandler(int)));
00047
00048 QTimer::singleShot(0, this, SLOT(slotFillStuff()));
00049 QTimer::singleShot(0, this, SLOT(slotResizing()));
00050
00051 }
00052
00053 Composer::~Composer()
00054 {
00055 hide();
00056 }
00057
00058 void Composer::hide()
00059 {
00060 QWidget::hide();
00061
00062 if (_inLoop) {
00063 _inLoop = false;
00064 qApp->exit_loop();
00065 }
00066 }
00067
00068 void Composer::exec()
00069 {
00070 show();
00071 if (!_inLoop) {
00072 _inLoop = true;
00073 qApp->enter_loop();
00074 }
00075 }
00076
00077 void Composer::setSendMail(SendMail &sendMail)
00078 {
00079 to->setText(sendMail.to());
00080 cc->setText(sendMail.cc());
00081 bcc->setText(sendMail.bcc());
00082 subject->setText(sendMail.subject());
00083 message->setText(sendMail.message());
00084 _inReplyTo = sendMail.inReplyTo();
00085
00086 QValueList<Attachment> attachments = sendMail.attachments();
00087 QValueList<Attachment>::Iterator it;
00088 for (it = attachments.begin(); it != attachments.end(); it++) {
00089 (void) new AttachViewItem(attachView, *it);
00090 if (attachView->isHidden()) attachView->show();
00091 }
00092 }
00093
00094 void Composer::slotResizing()
00095 {
00096 from->setMaximumWidth(width() - fromBox->width());
00097 from->resize(width() - fromBox->width(), y());
00098 if (_sendQueued) slotSendQueued();
00099 }
00100
00101 void Composer::slotPopupHandler(int itemid)
00102 {
00103 if (attachView->currentItem() == NULL) {
00104 QMessageBox::information(this, tr("Error"), tr("Please select an entry first."), tr("Ok"));
00105 return;
00106 }
00107
00108 if (itemid == POPUP_ATTACH_RENAME) {
00109 QString tmp = Rename::rename(attachView->currentItem()->text(0), this);
00110 if (tmp != QString(0)) attachView->currentItem()->setText(0, tmp);
00111 } else if (itemid == POPUP_ATTACH_DESC) {
00112 QString tmp = Rename::getText(tr("Set Description"), tr("<div align=center>Description"), this);
00113 if (tmp != QString(0)) attachView->currentItem()->setText(1, tmp);
00114 } else if (itemid == POPUP_ATTACH_REMOVE) {
00115 attachView->takeItem(attachView->currentItem());
00116 }
00117 }
00118
00119 void Composer::slotSendMail()
00120 {
00121 if (to->text().find(QRegExp(".*\\@.*\\..*")) == -1) {
00122 QMessageBox::information(this, tr("Error"), tr("<p>You have to specify a recipient.<br>(eg: foo@bar.org)</p>"), tr("Ok"));
00123 return;
00124 }
00125
00126 SendMail smail;
00127 smail.setFrom(from->currentText());
00128 smail.setReplyTo(replyto->text());
00129 smail.setTo(to->text());
00130 smail.setCc(cc->text());
00131 smail.setBcc(bcc->text());
00132 smail.setSubject(subject->text());
00133 smail.setMessage(message->text());
00134 smail.setNeedsMime(attachView->childCount() == 0 ? false : true);
00135 smail.setAccount(accountsLoaded[from->currentItem()]);
00136
00137 if (priority->currentItem() == POPUP_PRIO_LOW) {
00138 smail.setPriority("Low");
00139 } else if (priority->currentItem() == POPUP_PRIO_NORMAL) {
00140 smail.setPriority("Normal");
00141 } else if (priority->currentItem() == POPUP_PRIO_HIGH) {
00142 smail.setPriority("High");
00143 }
00144
00145 QValueList<Attachment> attachments;
00146 QListViewItem *item;
00147 for (item = attachView->firstChild(); item != 0; item = item->itemBelow()) {
00148 attachments.append(((AttachViewItem *)item)->attachment());
00149 }
00150
00151 smail.setAttachments(attachments);
00152
00153 QString header, message;
00154 MailFactory::genMail(header, message, smail, this);
00155 if (header.isNull() || message.isNull()) return;
00156
00157 status->setStopEnabled(true);
00158
00159 SmtpHandler *handler = new SmtpHandler(header, message, accountsLoaded[from->currentItem()], to->text());
00160 connect(handler, SIGNAL(finished()), SLOT(slotSendFinished()));
00161 connect(handler, SIGNAL(error(const QString&)), SLOT(slotSendError(const QString&)));
00162 connect(handler, SIGNAL(status(const QString&)), status, SLOT(setStatusText(const QString&)));
00163 }
00164
00165 void Composer::slotSendQueued()
00166 {
00167 int effSendCount = 0;
00168 qDebug("Sending queued messages");
00169 Config cfg( "mailqueue", Config::User );
00170 cfg.setGroup( "Settings" );
00171 _sendCount = 0;
00172 _sendError = 0;
00173 _toSend = cfg.readNumEntry( "count", 0 );
00174
00175 if (_toSend == 0) close();
00176
00177 qDebug("%i messages to send", _toSend);
00178 QString str;
00179 for (int i=1;i<=_toSend;i++)
00180 {
00181 qDebug("sending message %i",i);
00182 cfg.setGroup( "Mail_" + QString::number(i) );
00183 SendMail smail;
00184 str = cfg.readEntry("from");
00185 qDebug("setFrom %s",str.latin1());
00186 smail.setFrom( str );
00187 str = cfg.readEntry("reply");
00188 qDebug("setReplyTo %s",str.latin1());
00189 smail.setReplyTo( str );
00190 QString toAdr = cfg.readEntry("to");
00191 qDebug("to %s",toAdr.latin1());
00192 smail.setTo( toAdr );
00193 str = cfg.readEntry("cc");
00194 qDebug("setCc %s",str.latin1());
00195 smail.setCc( str );
00196 smail.setBcc( cfg.readEntry("bcc") );
00197 str = cfg.readEntry("subject");
00198 qDebug("setSubject %s",str.latin1());
00199 smail.setSubject( str );
00200 str = cfg.readEntryCrypt("message");
00201 qDebug("setMessage %s",str.latin1());
00202 smail.setMessage( str );
00203 smail.setNeedsMime( cfg.readBoolEntry("mime") );
00204
00205 qDebug("setting account [%i]",cfg.readNumEntry("account"));
00206 Account accnt = accountsLoaded[ cfg.readNumEntry("account") ];
00207 smail.setAccount( accnt );
00208
00209
00210 int prio = cfg.readNumEntry( "priority" );
00211 qDebug("setting priority %i",prio);
00212 if (prio == POPUP_PRIO_LOW) {
00213 smail.setPriority("Low");
00214 } else if (prio == POPUP_PRIO_NORMAL) {
00215 smail.setPriority("Normal");
00216 } else if (prio == POPUP_PRIO_HIGH) {
00217 smail.setPriority("High");
00218 }
00219
00220 QValueList<Attachment> attachments;
00221 Attachment a;
00222 QString an;
00223
00224 int ac = cfg.readNumEntry( "attachments", 0 );
00225 qDebug("%i Attachments",ac);
00226 for (int j = 0; i < ac; ac++) {
00227 an = "Attachment_" + QString::number( j );
00228 qDebug(an.latin1());
00229 a.setFileName(cfg.readEntry( an + "fileName" ));
00230 a.setNewName(cfg.readEntry( an + "newName" ));
00231 a.setDescription(cfg.readEntry( an + "description" ));
00232 a.setDocLnk( DocLnk( cfg.readEntry( an + "docLnk" )) );
00233 attachments.append( a );
00234 }
00235
00236 smail.setAttachments(attachments);
00237
00238 qDebug("putting mail together");
00239
00240 QString header, message;
00241 MailFactory::genMail(header, message, smail, this);
00242 if (header.isNull() || message.isNull()) continue;
00243
00244
00245
00246 qDebug("Sending to %s",toAdr.latin1());
00247 SmtpHandler *handler = new SmtpHandler(header, message, accnt ,toAdr);
00248 effSendCount++;
00249 connect(handler, SIGNAL(finished()), SLOT(slotSendQueuedFinished()));
00250 connect(handler, SIGNAL(error(const QString&)), SLOT(slotSendQueuedError(const QString&)));
00251 connect(handler, SIGNAL(status(const QString&)), status, SLOT(setStatusText(const QString&)));
00252
00253 }
00254 if (effSendCount < _toSend)
00255 {
00256 _toSend = effSendCount;
00257 QMessageBox::information(this, tr("Error"), tr("<p>There was a problem sending some of the queued mails.</p>"), tr("Ok"));
00258 }
00259 }
00260
00261 void Composer::slotQueueMail()
00262 {
00263 if (to->text().find(QRegExp(".*\\@.*\\..*")) == -1) {
00264 QMessageBox::information(this, tr("Error"), tr("<p>You have to specify a recipient.<br>(eg: foo@bar.org)</p>"), tr("Ok"));
00265 return;
00266 }
00267
00268 Config cfg( "mailqueue", Config::User );
00269
00270 cfg.setGroup( "Settings" );
00271 int count = cfg.readNumEntry( "count", 0 );
00272 count++;
00273 cfg.writeEntry( "count", count );
00274 qDebug("queueing mail %i",count);
00275
00276 cfg.setGroup( "Mail_" + QString::number( count ));
00277 cfg.writeEntry( "from", from->currentText() );
00278 cfg.writeEntry( "reply", replyto->text());
00279 cfg.writeEntry( "to", to->text());
00280 cfg.writeEntry( "cc", cc->text());
00281 cfg.writeEntry( "bcc", bcc->text());
00282 cfg.writeEntry( "subject", subject->text());
00283 cfg.writeEntryCrypt( "message", message->text());
00284 cfg.writeEntry( "mime", attachView->childCount() == 0 );
00285 cfg.writeEntry( "account", from->currentItem());
00286 cfg.writeEntry( "priority", priority->currentItem() );
00287 cfg.writeEntry( "attachments", attachView->childCount() );
00288
00289 Attachment a;
00290 QListViewItem *item;
00291 QString an;
00292 int i = 0;
00293 for (item = attachView->firstChild(); item != 0; item = item->itemBelow()) {
00294 a = ((AttachViewItem *)item)->attachment();
00295 an = "Attachment_" + QString::number( i++ );
00296 cfg.writeEntry( an + "fileName", a.fileName() );
00297 cfg.writeEntry( an + "newName", a.newName() );
00298 cfg.writeEntry( an + "description", a.description() );
00299 cfg.writeEntry( an + "docLnk", a.docLnk().file() );
00300 }
00301
00302 QMessageBox::information(this, tr("Success"), tr("<p>The mail was queued successfully.</p><p>The queue contains ")+QString::number(count)+tr(" mails.</p>"), tr("Ok"));
00303
00304 }
00305
00306 void Composer::slotSendError(const QString &error)
00307 {
00308 status->setStatusText(tr("<font color=#ff0000>Error occoured during sending.</font>"));
00309 QMessageBox::warning(this, tr("Error"), tr("<p>%1</p").arg(error), tr("Ok"));
00310 }
00311
00312 void Composer::slotSendQueuedError(const QString &error)
00313 {
00314 _sendError++;
00315 qDebug("error send mail %i",_sendCount);
00316 status->setStatusText(tr("<font color=#ff0000>Error occoured during sending.</font>"));
00317 QMessageBox::warning(this, tr("Error"), tr("<p>%1</p").arg(error), tr("Ok"));
00318 }
00319
00320 void Composer::slotSendFinished()
00321 {
00322 QMessageBox::information(this, tr("Success"), tr("<p>The mail was sent successfully.</p>"), tr("Ok"));
00323
00324 status->setStatusText(QString(0));
00325 status->setStopEnabled(false);
00326 }
00327
00328 void Composer::slotSendQueuedFinished()
00329 {
00330
00331 _sendCount++;
00332 qDebug("finished send mail %i of %i (error %i)",_sendCount,_toSend,_sendError);
00333 if (_sendCount < _toSend) return;
00334 if (_sendError == _toSend) close();
00335 QMessageBox::information(this, tr("Success"), tr("<p>The queued mails ")+QString::number(_toSend-_sendError)+tr(" of ")+QString::number(_toSend)+(" were sent successfully.</p>"), tr("Ok"));
00336 Config cfg( "mailqueue", Config::User );
00337 cfg.setGroup( "Settings" );
00338 cfg.writeEntry( "count", 0 );
00339 for (int i=1;i<=_sendCount;i++)
00340 {
00341 cfg.setGroup( "Mail_" + QString::number(i) );
00342 qDebug("remove mail %i", i);
00343 cfg.clearGroup();
00344 cfg.removeEntry( "Mail_" + QString::number(i) );
00345 }
00346 close();
00347 }
00348
00349 void Composer::slotFillStuff()
00350 {
00351 QValueList<Account> accounts = ConfigFile::getAccounts();
00352 int i = 0;
00353
00354 QValueList<Account>::Iterator it;
00355 for (it = accounts.begin(); it != accounts.end(); it++) {
00356 if (!(*it).email().isEmpty() && !(*it).smtpServer().isEmpty() && !(*it).smtpPort().isEmpty()) {
00357 if (!(*it).realName().isEmpty())
00358 from->insertItem((*it).realName() + " <" + (*it).email() + ">", i);
00359 else
00360 from->insertItem((*it).email());
00361
00362 accountsLoaded.append(*it);
00363 i++;
00364 }
00365 }
00366 }
00367
00368 void Composer::slotFromChanged(int id)
00369 {
00370 Account account = accountsLoaded[id];
00371
00372 if (account.defaultCc()) cc->setText(account.cc());
00373 if (account.defaultBcc()) bcc->setText(account.bcc());
00374 if (account.defaultReplyTo()) replyto->setText(account.replyTo());
00375 if (!account.signature().isEmpty())
00376 message->setText(message->text() + "\n\n-- \n" + account.signature());
00377 }
00378
00379 void Composer::slotOpenAddressPicker()
00380 {
00381 if (!to->isHidden() && cc->isHidden() && bcc->isHidden()) {
00382 if (to->text().isEmpty()) {
00383 to->setText(AddressPicker::getNames());
00384 } else {
00385 to->setText(to->text() + ", " + AddressPicker::getNames());
00386 }
00387 } else if (to->isHidden() && !cc->isHidden() && bcc->isHidden()) {
00388 if (cc->text().isEmpty()) {
00389 cc->setText(AddressPicker::getNames());
00390 } else {
00391 cc->setText(cc->text() + ", " + AddressPicker::getNames());
00392 }
00393 } else if (to->isHidden() && cc->isHidden() && !bcc->isHidden()) {
00394 if (bcc->text().isEmpty()) {
00395 bcc->setText(AddressPicker::getNames());
00396 } else {
00397 bcc->setText(bcc->text() + ", " + AddressPicker::getNames());
00398 }
00399 }
00400 }
00401
00402 void Composer::slotAddAttach()
00403 {
00404 DocLnk lnk = OFileDialog::getOpenFileName( 1,"/");
00405
00406 if (lnk.name().isEmpty()) return;
00407
00408 Attachment attachment;
00409 attachment.setFileName(lnk.file());
00410 attachment.setNewName(lnk.name());
00411 attachment.setDocLnk(lnk);
00412
00413 (void) new AttachViewItem(attachView, attachment);
00414 }
00415
00416 void Composer::slotDelAttach()
00417 {
00418 if (attachView->currentItem() == NULL) return;
00419 attachView->takeItem(attachView->currentItem());
00420 }