bool MessageCopyHelper::inReadOnlyFolder(const QList< quint32 > & sernums) { KMFolder *f = 0; int index; for ( QList<quint32>::ConstIterator it = sernums.begin(); it != sernums.end(); ++it ) { KMMsgDict::instance()->getLocation( *it, &f, &index ); if ( !f ) // not found continue; if ( f->isReadOnly() ) return true; } return false; }
//----------------------------------------------------------------------------- void KMSender::doSendMsg() { if(!kmkernel) //To handle message sending in progress when kaplan is exited return; //TODO: handle this case better const bool someSent = mCurrentMsg; if(someSent) { mSentMessages++; mSentBytes += mCurrentMsg->msgSize(); } // Post-process sent message (filtering) KMFolder *sentFolder = 0, *imapSentFolder = 0; if(mCurrentMsg && kmkernel->filterMgr()) { mCurrentMsg->setTransferInProgress(false); if(mCurrentMsg->hasUnencryptedMsg()) { kdDebug(5006) << "KMSender::doSendMsg() post-processing: replace mCurrentMsg body by unencryptedMsg data" << endl; // delete all current body parts mCurrentMsg->deleteBodyParts(); // copy Content-[..] headers from unencrypted message to current one KMMessage &newMsg(*mCurrentMsg->unencryptedMsg()); mCurrentMsg->dwContentType() = newMsg.dwContentType(); mCurrentMsg->setContentTransferEncodingStr(newMsg.contentTransferEncodingStr()); QCString newDispo = newMsg.headerField("Content-Disposition").latin1(); if(newDispo.isEmpty()) mCurrentMsg->removeHeaderField("Content-Disposition"); else mCurrentMsg->setHeaderField("Content-Disposition", newDispo); // copy the body mCurrentMsg->setBody(newMsg.body()); // copy all the body parts KMMessagePart msgPart; for(int i = 0; i < newMsg.numBodyParts(); ++i) { newMsg.bodyPart(i, &msgPart); mCurrentMsg->addBodyPart(&msgPart); } } mCurrentMsg->setStatus(KMMsgStatusSent); mCurrentMsg->setStatus(KMMsgStatusRead); // otherwise it defaults to new on imap mCurrentMsg->updateAttachmentState(); const KPIM::Identity &id = kmkernel->identityManager() ->identityForUoidOrDefault(mCurrentMsg->headerField("X-KMail-Identity").stripWhiteSpace().toUInt()); if(!mCurrentMsg->fcc().isEmpty()) { sentFolder = kmkernel->folderMgr()->findIdString(mCurrentMsg->fcc()); if(sentFolder == 0) // This is *NOT* supposed to be imapSentFolder! sentFolder = kmkernel->dimapFolderMgr()->findIdString(mCurrentMsg->fcc()); if(sentFolder == 0) imapSentFolder = kmkernel->imapFolderMgr()->findIdString(mCurrentMsg->fcc()); } // No, or no usable sentFolder, and no, or no usable imapSentFolder, // let's try the on in the identity if((sentFolder == 0 || sentFolder->isReadOnly()) && (imapSentFolder == 0 || imapSentFolder->isReadOnly()) && !id.fcc().isEmpty()) { sentFolder = kmkernel->folderMgr()->findIdString(id.fcc()); if(sentFolder == 0) // This is *NOT* supposed to be imapSentFolder! sentFolder = kmkernel->dimapFolderMgr()->findIdString(id.fcc()); if(sentFolder == 0) imapSentFolder = kmkernel->imapFolderMgr()->findIdString(id.fcc()); } if(imapSentFolder && (imapSentFolder->noContent() || imapSentFolder->isReadOnly())) imapSentFolder = 0; if(sentFolder == 0 || sentFolder->isReadOnly()) sentFolder = kmkernel->sentFolder(); if(sentFolder) { if(const int err = sentFolder->open("sentFolder")) { Q_UNUSED(err); cleanup(); return; } } // Disable the emitting of msgAdded signal, because the message is taken out of the // current folder (outbox) and re-added, to make filter actions changing the message // work. We don't want that to screw up message counts. if(mCurrentMsg->parent()) mCurrentMsg->parent()->quiet(true); const int processResult = kmkernel->filterMgr()->process(mCurrentMsg, KMFilterMgr::Outbound); if(mCurrentMsg->parent()) mCurrentMsg->parent()->quiet(false); // 0==processed ok, 1==no filter matched, 2==critical error, abort! switch(processResult) { case 2: perror("Critical error: Unable to process sent mail (out of space?)"); KMessageBox::information(0, i18n("Critical error: " "Unable to process sent mail (out of space?)" "Moving failing message to \"sent-mail\" folder.")); if(sentFolder) { sentFolder->moveMsg(mCurrentMsg); sentFolder->close("sentFolder"); } cleanup(); return; case 1: if(sentFolder && sentFolder->moveMsg(mCurrentMsg) != 0) { KMessageBox::error(0, i18n("Moving the sent message \"%1\" from the " "\"outbox\" to the \"sent-mail\" folder failed.\n" "Possible reasons are lack of disk space or write permission. " "Please try to fix the problem and move the message manually.") .arg(mCurrentMsg->subject())); cleanup(); return; } if(imapSentFolder) { // Does proper folder refcounting and message locking KMCommand *command = new KMMoveCommand(imapSentFolder, mCurrentMsg); command->keepFolderOpen(sentFolder); // will open it, and close it once done command->start(); } default: break; } setStatusByLink(mCurrentMsg); if(mCurrentMsg->parent() && !imapSentFolder) { // for speed optimization, this code assumes that mCurrentMsg is the // last one in it's parent folder; make sure that's really the case: assert(mCurrentMsg->parent()->find(mCurrentMsg) == mCurrentMsg->parent()->count() - 1); // unGet this message: mCurrentMsg->parent()->unGetMsg(mCurrentMsg->parent()->count() - 1); } mCurrentMsg = 0; } // See if there is another queued message mCurrentMsg = mOutboxFolder->getMsg(mFailedMessages); if(mCurrentMsg && !mCurrentMsg->transferInProgress() && mCurrentMsg->sender().isEmpty()) { // if we do not have a sender address then use the email address of the // message's identity or of the default identity unless those two are also // empty const KPIM::Identity &id = kmkernel->identityManager() ->identityForUoidOrDefault(mCurrentMsg->headerField("X-KMail-Identity").stripWhiteSpace().toUInt()); if(!id.emailAddr().isEmpty()) { mCurrentMsg->setFrom(id.fullEmailAddr()); } else if(!kmkernel->identityManager()->defaultIdentity().emailAddr().isEmpty()) { mCurrentMsg->setFrom(kmkernel->identityManager()->defaultIdentity().fullEmailAddr()); } else { KMessageBox::sorry(0, i18n("It's not possible to send messages " "without specifying a sender address.\n" "Please set the email address of " "identity '%1' in the Identities " "section of the configuration dialog " "and then try again.") .arg(id.identityName())); mOutboxFolder->unGetMsg(mFailedMessages); mCurrentMsg = 0; } } if(!mCurrentMsg || mCurrentMsg->transferInProgress()) { // a message is locked finish the send if(mCurrentMsg && mCurrentMsg->transferInProgress()) mCurrentMsg = 0; // no more message: cleanup and done if(sentFolder != 0) sentFolder->close("sentFolder"); if(someSent) { if(mSentMessages == mTotalMessages) { setStatusMsg(i18n("%n queued message successfully sent.", "%n queued messages successfully sent.", mSentMessages)); } else { setStatusMsg(i18n("%1 of %2 queued messages successfully sent.") .arg(mSentMessages).arg(mTotalMessages)); } } cleanup(); return; } mCurrentMsg->setTransferInProgress(true); // start the sender process or initialize communication if(!mSendInProgress) { Q_ASSERT(!mProgressItem); mProgressItem = KPIM::ProgressManager::createProgressItem( "Sender", i18n("Sending messages"), i18n("Initiating sender process..."), true); connect(mProgressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem *)), this, SLOT(slotAbortSend())); kapp->ref(); mSendInProgress = true; }