00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <unistd.h>
00026 #include <stdio.h>
00027
00028 #include <klocale.h>
00029 #include <kstandarddirs.h>
00030 #include <kdebug.h>
00031 #include <kmessagebox.h>
00032 #include <kurl.h>
00033 #include <kapplication.h>
00034 #include <dcopclient.h>
00035 #include <kprocess.h>
00036
00037 #include <libkcal/event.h>
00038 #include <libkcal/todo.h>
00039
00040 #include "version.h"
00041 #include "koprefs.h"
00042
00043 #include "komailclient.h"
00044
00045 KOMailClient::KOMailClient()
00046 {
00047 }
00048
00049 KOMailClient::~KOMailClient()
00050 {
00051 }
00052
00053 bool KOMailClient::mailAttendees(IncidenceBase *incidence,const QString &attachment)
00054 {
00055 Attendee::List attendees = incidence->attendees();
00056 if (attendees.count() == 0) return false;
00057
00058 QString from = KOPrefs::instance()->email();
00059 QStringList toList;
00060 for(uint i=0; i<attendees.count();++i) {
00061 QString email = (*attendees.at(i))->email();
00062 if( email != from )
00063
00064 toList << email;
00065 }
00066 if( toList.count() == 0 )
00067
00068 return false;
00069 QString to = toList.join( ", " );
00070
00071 QString subject;
00072 if(incidence->type()!="FreeBusy") {
00073 Incidence *inc = static_cast<Incidence *>(incidence);
00074 subject = inc->summary();
00075 } else {
00076 subject = "Free Busy Object";
00077 }
00078
00079 QString body = createBody(incidence);
00080
00081 bool bcc = KOPrefs::instance()->mBcc;
00082
00083 return send(from,to,subject,body,bcc,attachment);
00084 }
00085
00086 bool KOMailClient::mailOrganizer(IncidenceBase *incidence,const QString &attachment)
00087 {
00088 QString to = incidence->organizer();
00089
00090 QString from = KOPrefs::instance()->email();
00091
00092 QString subject;
00093 if(incidence->type()!="FreeBusy") {
00094 Incidence *inc = static_cast<Incidence *>(incidence);
00095 subject = inc->summary();
00096 } else {
00097 subject = "Free Busy Message";
00098 }
00099
00100 QString body = createBody(incidence);
00101
00102 bool bcc = KOPrefs::instance()->mBcc;
00103
00104 return send(from,to,subject,body,bcc,attachment);
00105 }
00106
00107 bool KOMailClient::mailTo(IncidenceBase *incidence,const QString &recipients,
00108 const QString &attachment)
00109 {
00110 QString from = KOPrefs::instance()->email();
00111 QString subject;
00112 if(incidence->type()!="FreeBusy") {
00113 Incidence *inc = static_cast<Incidence *>(incidence);
00114 subject = inc->summary();
00115 } else {
00116 subject = "Free Busy Message";
00117 }
00118 QString body = createBody(incidence);
00119 bool bcc = KOPrefs::instance()->mBcc;
00120 kdDebug () << "KOMailClient::mailTo " << recipients << endl;
00121 return send(from,recipients,subject,body,bcc,attachment);
00122 }
00123
00124 bool KOMailClient::send(const QString &from,const QString &to,
00125 const QString &subject,const QString &body,bool bcc,
00126 const QString &attachment)
00127 {
00128 kdDebug(5850) << "KOMailClient::sendMail():\nFrom: " << from << "\nTo: " << to
00129 << "\nSubject: " << subject << "\nBody: \n" << body
00130 << "\nAttachment:\n" << attachment << endl;
00131
00132 if (KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail) {
00133 bool needHeaders = true;
00134
00135 QString command = KStandardDirs::findExe(QString::fromLatin1("sendmail"),
00136 QString::fromLatin1("/sbin:/usr/sbin:/usr/lib"));
00137 if (!command.isNull()) command += QString::fromLatin1(" -oi -t");
00138 else {
00139 command = KStandardDirs::findExe(QString::fromLatin1("mail"));
00140 if (command.isNull()) return false;
00141
00142 command.append(QString::fromLatin1(" -s "));
00143 command.append(KProcess::quote(subject));
00144
00145 if (bcc) {
00146 command.append(QString::fromLatin1(" -b "));
00147 command.append(KProcess::quote(from));
00148 }
00149
00150 command.append(" ");
00151 command.append(KProcess::quote(to));
00152
00153 needHeaders = false;
00154 }
00155
00156 FILE * fd = popen(command.local8Bit(),"w");
00157 if (!fd)
00158 {
00159 kdError() << "Unable to open a pipe to " << command << endl;
00160 return false;
00161 }
00162
00163 QString textComplete;
00164 if (needHeaders)
00165 {
00166 textComplete += QString::fromLatin1("From: ") + from + '\n';
00167 textComplete += QString::fromLatin1("To: ") + to + '\n';
00168 if (bcc) textComplete += QString::fromLatin1("Bcc: ") + from + '\n';
00169 textComplete += QString::fromLatin1("Subject: ") + subject + '\n';
00170 textComplete += QString::fromLatin1("X-Mailer: KOrganizer") + korgVersion + '\n';
00171 }
00172 textComplete += '\n';
00173 textComplete += body;
00174 textComplete += '\n';
00175 textComplete += attachment;
00176
00177 fwrite(textComplete.local8Bit(),textComplete.length(),1,fd);
00178
00179 pclose(fd);
00180 } else {
00181 if (!kapp->dcopClient()->isApplicationRegistered("kmail")) {
00182 if (KApplication::startServiceByDesktopName("kmail")) {
00183 KMessageBox::error(0,i18n("No running instance of KMail found."));
00184 return false;
00185 }
00186 }
00187
00188 if (attachment.isEmpty()) {
00189 if (!kMailOpenComposer(to,"",from,subject,body,0,KURL())) return false;
00190 } else {
00191 QString meth;
00192 int idx = attachment.find("METHOD");
00193 if (idx>=0) {
00194 idx = attachment.find(':',idx)+1;
00195 meth = attachment.mid(idx,attachment.find('\n',idx)-idx);
00196 meth = meth.lower();
00197 } else {
00198 meth = "publish";
00199 }
00200 if (!kMailOpenComposer(to,"",from,subject,body,0,"cal.ics","7bit",
00201 attachment.utf8(),"text","calendar","method",meth,
00202 "attachment")) return false;
00203 }
00204 }
00205 return true;
00206 }
00207
00208 int KOMailClient::kMailOpenComposer(const QString& arg0,const QString& arg1,
00209 const QString& arg2,const QString& arg3,const QString& arg4,int arg5,
00210 const KURL& arg6)
00211 {
00212 int result = 0;
00213
00214 QByteArray data, replyData;
00215 QCString replyType;
00216 QDataStream arg( data, IO_WriteOnly );
00217 arg << arg0;
00218 arg << arg1;
00219 arg << arg2;
00220 arg << arg3;
00221 arg << arg4;
00222 arg << arg5;
00223 arg << arg6;
00224 if (kapp->dcopClient()->call("kmail","KMailIface","openComposer(QString,QString,QString,QString,QString,int,KURL)", data, replyType, replyData ) ) {
00225 if ( replyType == "int" ) {
00226 QDataStream _reply_stream( replyData, IO_ReadOnly );
00227 _reply_stream >> result;
00228 } else {
00229 kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
00230 }
00231 } else {
00232 kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
00233 }
00234 return result;
00235 }
00236
00237 int KOMailClient::kMailOpenComposer( const QString& arg0, const QString& arg1,
00238 const QString& arg2, const QString& arg3,
00239 const QString& arg4, int arg5, const QString& arg6,
00240 const QCString& arg7, const QCString& arg8,
00241 const QCString& arg9, const QCString& arg10,
00242 const QCString& arg11, const QString& arg12,
00243 const QCString& arg13 )
00244 {
00245 int result = 0;
00246
00247 QByteArray data, replyData;
00248 QCString replyType;
00249 QDataStream arg( data, IO_WriteOnly );
00250 arg << arg0;
00251 arg << arg1;
00252 arg << arg2;
00253 arg << arg3;
00254 arg << arg4;
00255 arg << arg5;
00256 arg << arg6;
00257 arg << arg7;
00258 arg << arg8;
00259 arg << arg9;
00260 arg << arg10;
00261 arg << arg11;
00262 arg << arg12;
00263 arg << arg13;
00264 if ( kapp->dcopClient()->call("kmail","KMailIface","openComposer(QString,QString,QString,QString,QString,int,QString,QCString,QCString,QCString,QCString,QCString,QString,QCString)", data, replyType, replyData ) ) {
00265 if ( replyType == "int" ) {
00266 QDataStream _reply_stream( replyData, IO_ReadOnly );
00267 _reply_stream >> result;
00268 } else {
00269 kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
00270 }
00271 } else {
00272 kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
00273 }
00274 return result;
00275 }
00276
00277
00278 QString KOMailClient::createBody(IncidenceBase *incidence)
00279 {
00280 QString CR = ("\n");
00281
00282 QString body;
00283
00284
00285 if (incidence->type()=="Event") {
00286 Event *selectedEvent = static_cast<Event *>(incidence);
00287 QString recurrence[]= {i18n("no recurrence", "None"),
00288 i18n("Minutely"), i18n("Hourly"), i18n("Daily"),
00289 i18n("Weekly"), i18n("Monthly Same Day"), i18n("Monthly Same Position"),
00290 i18n("Yearly"), i18n("Yearly"), i18n("Yearly")};
00291
00292 if (!selectedEvent->organizer().isEmpty()) {
00293 body += i18n("Organizer: %1").arg(selectedEvent->organizer());
00294 body += CR;
00295 }
00296 body += i18n("Summary: %1").arg(selectedEvent->summary());
00297 body += CR;
00298 if (!selectedEvent->location().isEmpty()) {
00299 body += i18n("Location: %1").arg(selectedEvent->location());
00300 body += CR;
00301 }
00302 body += i18n("Start Date: %1").arg(selectedEvent->dtStartDateStr());
00303 body += CR;
00304 if (!selectedEvent->doesFloat()) {
00305 body += i18n("Start Time: %1").arg(selectedEvent->dtStartTimeStr());
00306 body += CR;
00307 }
00308 if ( selectedEvent->dtStart()!=selectedEvent->dtEnd() ) {
00309 body += i18n("End Date: %1").arg(selectedEvent->dtEndDateStr());
00310 body += CR;
00311 }
00312 if (!selectedEvent->doesFloat()) {
00313 body += i18n("End Time: %1").arg(selectedEvent->dtEndTimeStr());
00314 body += CR;
00315 }
00316 if (selectedEvent->doesRecur()) {
00317 body += i18n("Recurs: %1")
00318 .arg(recurrence[selectedEvent->recurrence()->doesRecur()]);
00319 body += CR;
00320
00321
00322
00323
00324
00325 if (selectedEvent->recurrence()->duration() > 0 ) {
00326 body += i18n ("Repeats %1 times")
00327 .arg(QString::number(selectedEvent->recurrence()->duration()));
00328 body += CR;
00329 } else {
00330 if (selectedEvent->recurrence()->duration() != -1) {
00331
00332 body += i18n("End Date: %1")
00333 .arg(selectedEvent->recurrence()->endDateStr());
00334 body += CR;
00335 } else {
00336 body += i18n("Repeats forever");
00337 body += CR;
00338 }
00339 }
00340 }
00341 QString details = selectedEvent->description();
00342 if (!details.isEmpty()) {
00343 body += i18n("Details:");
00344 body += CR;
00345 body += details;
00346 body += CR;
00347 }
00348 }
00349
00350
00351 if (incidence->type()=="Todo") {
00352 Todo *selectedEvent = static_cast<Todo *>(incidence);
00353 if (!selectedEvent->organizer().isEmpty()) {
00354 body += i18n("Organizer: %1").arg(selectedEvent->organizer());
00355 body += CR;
00356 }
00357 body += i18n("Summary: %1").arg(selectedEvent->summary());
00358 body += CR;
00359 if (!selectedEvent->location().isEmpty()) {
00360 body += i18n("Location: %1").arg(selectedEvent->location());
00361 body += CR;
00362 }
00363 if (selectedEvent->hasStartDate()) {
00364 body += i18n("Start Date: %1").arg(selectedEvent->dtStartDateStr());
00365 body += CR;
00366 if (!selectedEvent->doesFloat()) {
00367 body += i18n("Start Time: %1").arg(selectedEvent->dtStartTimeStr());
00368 body += CR;
00369 }
00370 }
00371 if (selectedEvent->hasDueDate()) {
00372 body += i18n("Due Date: %1").arg(selectedEvent->dtDueDateStr());
00373 body += CR;
00374 if (!selectedEvent->doesFloat()) {
00375 body += i18n("Due Time: %1").arg(selectedEvent->dtDueTimeStr());
00376 body += CR;
00377 }
00378 }
00379 QString details = selectedEvent->description();
00380 if (!details.isEmpty()) {
00381 body += i18n("Details:");
00382 body += CR;
00383 body += details;
00384 body += CR;
00385 }
00386 }
00387
00388
00389 if(incidence->type()=="FreeBusy") {
00390 body = i18n("This is a Free Busy Object");
00391 }
00392
00393
00394 if(incidence->type()=="Journal") {
00395 Incidence *inc = static_cast<Incidence *>(incidence);
00396 body = inc->summary();
00397 body += CR;
00398 body += inc->description();
00399 body += CR;
00400 }
00401
00402 return body;
00403 }