From f1665873cb033698209f45eb217d01e11309979f Mon Sep 17 00:00:00 2001 From: Michael Haeckel Date: Wed, 21 Mar 2001 21:01:16 +0000 Subject: [PATCH] We are now able to move and copy messages from local folders to IMAP folders. svn path=/trunk/kdenetwork/kmail/; revision=88124 --- kmacctimap.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++---- kmacctimap.h | 5 +++- kmfolder.cpp | 26 ++++++++++++++++-- kmfolder.h | 6 ++++- kmheaders.cpp | 10 ++++--- kmmessage.cpp | 3 +++ kmmessage.h | 9 ++++++- 7 files changed, 116 insertions(+), 14 deletions(-) diff --git a/kmacctimap.cpp b/kmacctimap.cpp index 41e2b75cc..c6fdc2b04 100644 --- a/kmacctimap.cpp +++ b/kmacctimap.cpp @@ -388,12 +388,14 @@ void KMAcctImap::slotListFolderResult(KIO::Job * job) folder->getMsgString(idx, cstr); a = cstr.find("X-UID: "); b = cstr.find("\n", a); - mailUid = cstr.mid(a + 7, b - a - 7).toLong(); + if (a == -1 || b == -1) mailUid = -1; + else mailUid = cstr.mid(a + 7, b - a - 7).toLong(); serverUid = (*uid).toLong(); if (mailUid < serverUid) folder->removeMsg(idx, TRUE); else if (mailUid > serverUid) uid++; else { idx++; uid = (*it).items.remove(uid); } } + while (idx < folder->count()) folder->removeMsg(idx, TRUE); } jobData jd; jd.parent = (*it).parent; @@ -485,7 +487,7 @@ void KMAcctImap::slotGetMessagesData(KIO::Job * job, const QByteArray & data) if (flags & 2) msg->setStatus(KMMsgStatusReplied); else if (flags & 1) msg->setStatus(KMMsgStatusRead); KMFolder *kf = (*it).parent->folder; - kf->addMsg(msg); + kf->addMsg(msg, NULL, TRUE); if (kf->count() > 1) kf->unGetMsg(kf->count() - 1); if (kf->count() % 100 == 0) { kf->quiet(FALSE); kf->quiet(TRUE); } (*it).cdata.remove(0, pos); @@ -563,6 +565,7 @@ void KMAcctImap::slotCreateFolderResult(KIO::Job * job) //----------------------------------------------------------------------------- KMImapJob::KMImapJob(QList msgList, KMFolder *destFolder) { + mType = tGetMessage; mSingleMessage = false; mDestFolder = destFolder; mMsgList = msgList; @@ -572,12 +575,40 @@ KMImapJob::KMImapJob(QList msgList, KMFolder *destFolder) //----------------------------------------------------------------------------- -KMImapJob::KMImapJob(KMMessage *msg) +KMImapJob::KMImapJob(KMMessage *msg, bool put, KMFolder* folder) { + assert(!put || folder); + mType = (put) ? tPutMessage : tGetMessage; mSingleMessage = true; + mDestFolder = folder; mMsgList.append(msg); - msg->parent()->account()->mJobList.append(this); - slotGetNextMessage(); + KMAcctImap *account = (folder) ? folder->account() : msg->parent()->account(); + account->mJobList.append(this); + if (put) + { + KURL url = account->getUrl(); + url.setPath(folder->imapPath()); + KMAcctImap::jobData jd; + jd.parent = NULL; + jd.total = 1; jd.done = 0; + QCString cstr(msg->asString()); + int a = cstr.find("\nX-UID: "); + int b = cstr.find("\n", a); + if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a); + mData = cstr; + account->makeConnection(); + KIO::SimpleJob *simpleJob = KIO::put(url, 0, FALSE, FALSE, FALSE); + KIO::Scheduler::assignJobToSlave(account->slave(), simpleJob); + mJob = simpleJob; + account->mapJobData.insert(mJob, jd); + connect(mJob, SIGNAL(result(KIO::Job *)), + SLOT(slotPutMessageResult(KIO::Job *))); + connect(mJob, SIGNAL(dataReq(KIO::Job *, QByteArray &)), + SLOT(slotPutMessageDataReq(KIO::Job *, QByteArray &))); + account->displayProgress(); + } else { + slotGetNextMessage(); + } } @@ -635,6 +666,36 @@ void KMImapJob::slotGetMessageResult(KIO::Job * job) } +//----------------------------------------------------------------------------- +void KMImapJob::slotPutMessageDataReq(KIO::Job *job, QByteArray &data) +{ + assert(mJob == job); + data = mData; + mData.resize(0); +} + + +//----------------------------------------------------------------------------- +void KMImapJob::slotPutMessageResult(KIO::Job *job) +{ + KMAcctImap *account = mDestFolder->account(); + QMap::Iterator it = + account->mapJobData.find(job); + if (it == account->mapJobData.end()) return; + if (job->error()) + { + job->showErrorDialog(); + if (job->error() == KIO::ERR_SLAVE_DIED) account->slaveDied(); + } else { + emit messageStored(mMsgList.first()); + } + account->mapJobData.remove(it); + account->displayProgress(); + account->mJobList.remove(this); + delete this; +} + + //----------------------------------------------------------------------------- void KMAcctImap::slotSimpleData(KIO::Job * job, const QByteArray & data) { diff --git a/kmacctimap.h b/kmacctimap.h index 76d46f4a5..c95c8d6e2 100644 --- a/kmacctimap.h +++ b/kmacctimap.h @@ -50,14 +50,17 @@ class KMImapJob : public QObject public: KMImapJob(QList msgList, KMFolder *destFolder); - KMImapJob(KMMessage *msg); + KMImapJob(KMMessage *msg, bool put = false, KMFolder *folder = NULL); static void killJobsForMessage(KMMessage *msg); signals: void messagesRetrieved(QList, KMFolder*); void messageRetrieved(KMMessage *); + void messageStored(KMMessage *); private slots: void slotGetMessageResult(KIO::Job * job); void slotGetNextMessage(); + void slotPutMessageDataReq(KIO::Job *job, QByteArray &data); + void slotPutMessageResult(KIO::Job *job); private: enum JobType { tListDirectory, tGetFolder, tCreateFolder, tDeleteMessage, tGetMessage, tPutMessage }; diff --git a/kmfolder.cpp b/kmfolder.cpp index e314c6e0c..774dd9717 100644 --- a/kmfolder.cpp +++ b/kmfolder.cpp @@ -1190,7 +1190,9 @@ int KMFolder::find(const QString& msgIdMD5) const void KMFolder::reallyAddMsg(KMMessage* aMsg) { KMFolder *folder = aMsg->parent(); - addMsg(aMsg); + int index; + addMsg(aMsg, &index); + if (index < 0) return; KMMsgBase *mb = unGetMsg(count() - 1); kernel->undoStack()->pushAction( mb->msgIdMD5(), folder, this ); } @@ -1206,7 +1208,17 @@ void KMFolder::reallyAddCopyOfMsg(KMMessage* aMsg) //----------------------------------------------------------------------------- -int KMFolder::addMsg(KMMessage* aMsg, int* aIndex_ret) +void KMFolder::addMsgQuiet(KMMessage* aMsg) +{ + KMFolder *folder = aMsg->parent(); + addMsg( aMsg, NULL, TRUE ); + KMMsgBase *mb = unGetMsg(count() - 1); + kernel->undoStack()->pushAction( mb->msgIdMD5(), folder, this ); +} + + +//----------------------------------------------------------------------------- +int KMFolder::addMsg(KMMessage* aMsg, int* aIndex_ret, bool imapQuiet) { long offs, size, len, revert; bool opened = FALSE; @@ -1252,6 +1264,16 @@ int KMFolder::addMsg(KMMessage* aMsg, int* aIndex_ret) } } + if (mAccount && !imapQuiet) + { + aMsg->setTransferInProgress(TRUE); + KMImapJob *imapJob = new KMImapJob(aMsg, TRUE, this); + connect(imapJob, SIGNAL(messageStored(KMMessage*)), + SLOT(addMsgQuiet(KMMessage*))); + if (aIndex_ret) *aIndex_ret = -1; + return 0; + } + aMsg->setStatusFields(); msgText = aMsg->asString(); msgText.replace(QRegExp("\nFrom "),"\n>From "); diff --git a/kmfolder.h b/kmfolder.h index 789d9b410..817e3ff74 100644 --- a/kmfolder.h +++ b/kmfolder.h @@ -113,7 +113,8 @@ public: is stored in index_return if given. Please note that the message is added as is to the folder and the folder takes ownership of the message (deleting it in the destructor).*/ - virtual int addMsg(KMMessage* msg, int* index_return = NULL); + virtual int addMsg(KMMessage* msg, int* index_return = NULL, + bool imapQuiet = FALSE); /** Remove (first occurance of) given message from the folder. */ virtual void removeMsg(int i, bool imapQuiet = FALSE); @@ -307,6 +308,9 @@ public slots: server */ virtual void reallyAddMsg(KMMessage *); + /** Add a message to a folder after is has been added on an IMAP server */ + virtual void addMsgQuiet(KMMessage *); + /** Add a copy of the message to the folder after it has been retrieved from an IMAP server */ virtual void reallyAddCopyOfMsg(KMMessage *); diff --git a/kmheaders.cpp b/kmheaders.cpp index 38a8009d9..a378f31de 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -1409,7 +1409,7 @@ void KMHeaders::copyMsgToFolder (KMFolder* destFolder, int msgId) KMMessageList* msgList; KMMsgBase *msgBase; KMMessage *msg, *newMsg; - int top, rc, idx = -1; + int top, rc, index, idx = -1; bool isMessage; if (!destFolder) return; @@ -1441,8 +1441,9 @@ void KMHeaders::copyMsgToFolder (KMFolder* destFolder, int msgId) connect(imapJob, SIGNAL(messageRetrieved(KMMessage*)), destFolder, SLOT(reallyAddCopyOfMsg(KMMessage*))); } else { - rc = destFolder->addMsg(newMsg); - destFolder->unGetMsg( destFolder->count() - 1 ); + rc = destFolder->addMsg(newMsg, &index); + if (rc == 0 && index != -1) + destFolder->unGetMsg( destFolder->count() - 1 ); } if (!isMessage) { @@ -1743,7 +1744,8 @@ void KMHeaders::highlightMessage(QListViewItem* lvi) { if (mFolder->account()) KMImapJob::killJobsForMessage( mFolder->getMsg(mPrevCurrent->msgId())); - mFolder->unGetMsg(mPrevCurrent->msgId()); + if (!mFolder->getMsg(mPrevCurrent->msgId())->transferInProgress()) + mFolder->unGetMsg(mPrevCurrent->msgId()); } mPrevCurrent = item; } diff --git a/kmmessage.cpp b/kmmessage.cpp index 2bad4511e..2aae00240 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -62,6 +62,7 @@ KMMessage::KMMessage(DwMessage* aMsg) mMsg = aMsg; mCodec = NULL; mIsComplete = FALSE; + mTransferInProgress = FALSE; } @@ -92,6 +93,7 @@ KMMessage::KMMessage(KMFolder* parent): KMMessageInherited(parent) mMsg = new DwMessage; mCodec = NULL; mIsComplete = FALSE; + mTransferInProgress = FALSE; } @@ -102,6 +104,7 @@ KMMessage::KMMessage(const KMMsgInfo& msgInfo): KMMessageInherited() mMsg = new DwMessage; mCodec = NULL; mIsComplete = FALSE; + mTransferInProgress = FALSE; assign(&msgInfo); } diff --git a/kmmessage.h b/kmmessage.h index 9031f3a95..f7aa55801 100644 --- a/kmmessage.h +++ b/kmmessage.h @@ -297,6 +297,13 @@ public: virtual void setComplete(bool value) { mIsComplete = value; } + /** Return, if the message should not be deleted */ + virtual bool transferInProgress() { return mTransferInProgress; } + + /** Set that the message shall not be deleted because it is still required */ + virtual void setTransferInProgress(bool value) + { mTransferInProgress = value; } + /** Reads config settings from group "KMMessage" and sets all internal * variables (e.g. indent-prefix, etc.) */ static void readConfig(void); @@ -312,7 +319,7 @@ protected: protected: DwMessage* mMsg; - bool mNeedsAssembly, mIsComplete; + bool mNeedsAssembly, mIsComplete, mTransferInProgress; static int sHdrStyle; static QString sForwardStr; QTextCodec* mCodec;