/** * kmacctimap.cpp * * Copyright (c) 2000 Michael Haeckel * * This file is based on kmacctexppop.cpp by Don Sanders * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "kmacctimap.moc" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kmacctimap.h" #include "kalarmtimer.h" #include "kmglobal.h" #include "kbusyptr.h" #include "kmacctfolder.h" #include "kmfoldertree.h" #include #include #include #include #include "kmbroadcaststatus.h" #include #include //----------------------------------------------------------------------------- KMAcctImap::KMAcctImap(KMAcctMgr* aOwner, const char* aAccountName): KMAcctImapInherited(aOwner, aAccountName) { initMetaObject(); init(); mSlave = NULL; mTotal = 0; connect(KMBroadcastStatus::instance(), SIGNAL(signalAbortRequested()), this, SLOT(slotAbortRequested())); KIO::Scheduler::connect( SIGNAL(slaveError(KIO::Slave *, int, const QString &)), this, SLOT(slotSlaveError(KIO::Slave *, int, const QString &))); } //----------------------------------------------------------------------------- KMAcctImap::~KMAcctImap() { killAllJobs(); if (mSlave) KIO::Scheduler::disconnectSlave(mSlave); } //----------------------------------------------------------------------------- const char* KMAcctImap::type(void) const { return "imap"; } //----------------------------------------------------------------------------- void KMAcctImap::init(void) { mHost = ""; struct servent *serv = getservbyname("imap-4", "tcp"); if (serv) { mPort = ntohs(serv->s_port); } else { mPort = 143; } mLogin = ""; mPasswd = ""; mAuth = "*"; mStorePasswd = FALSE; mProgressEnabled = FALSE; } //----------------------------------------------------------------------------- void KMAcctImap::pseudoAssign(KMAccount* account) { assert(account->type() == "imap"); KMAcctImap *acct = static_cast(account); setName(acct->name()); setCheckInterval( 0 ); setCheckExclude( TRUE ); setFolder(acct->folder()); setHost(acct->host()); setPort(acct->port()); setPrefix(acct->prefix()); setLogin(acct->login()); setAuth(acct->auth()); setHiddenFolders(acct->hiddenFolders()); setStorePasswd(acct->storePasswd()); setPasswd(acct->passwd(), acct->storePasswd()); } //----------------------------------------------------------------------------- KURL KMAcctImap::getUrl() { KURL url; url.setProtocol(QString("imap")); url.setUser(mLogin + ";AUTH=" + mAuth); url.setPass(decryptStr(mPasswd)); url.setHost(mHost); url.setPort(mPort); return url; } //----------------------------------------------------------------------------- bool KMAcctImap::makeConnection() { if (mSlave) return TRUE; mSlave = KIO::Scheduler::getConnectedSlave(getUrl()); if (!mSlave) return FALSE; return TRUE; } //----------------------------------------------------------------------------- void KMAcctImap::slotSlaveError(KIO::Slave *aSlave, int errorCode, const QString &errorMsg) { if (aSlave != mSlave) return; if (errorCode == KIO::ERR_SLAVE_DIED) { mSlave = NULL; KMessageBox::error(0, i18n("The process for \n%1\ndied unexpectedly").arg(errorMsg)); } } //----------------------------------------------------------------------------- void KMAcctImap::displayProgress() { if (mProgressEnabled == mapJobData.isEmpty()) { mProgressEnabled = !mapJobData.isEmpty(); KMBroadcastStatus::instance()->setStatusProgressEnable( mProgressEnabled ); } int total = 0, done = 0; for (QMap::Iterator it = mapJobData.begin(); it != mapJobData.end(); it++) { total += (*it).total; done += (*it).done; } if (total == 0) { mTotal = 0; return; } if (total > mTotal) mTotal = total; done += mTotal - total; KMBroadcastStatus::instance()->setStatusProgressPercent( 100*done / mTotal ); } //----------------------------------------------------------------------------- void KMAcctImap::listDirectory(KMFolderTreeItem * fti, bool secondStep) { fti->mImapState = KMFolderTreeItem::imapInProgress; jobData jd; jd.parent = fti; jd.total = 1; jd.done = 0; jd.inboxOnly = !secondStep && mPrefix != "/" && fti->folder->imapPath() == mPrefix; KURL url = getUrl(); url.setPath((jd.inboxOnly) ? QString("/") : fti->folder->imapPath()); makeConnection(); KIO::SimpleJob *job = KIO::listDir(url, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotListResult(KIO::Job *))); connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList &)), this, SLOT(slotListEntries(KIO::Job *, const KIO::UDSEntryList &))); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::slotListResult(KIO::Job * job) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); if (job->error()) { job->showErrorDialog(); if (job->error() == KIO::ERR_SLAVE_DIED) mSlave = NULL; } else if ((*it).inboxOnly) listDirectory((*it).parent, TRUE); (*it).parent->mImapState = KMFolderTreeItem::imapFinished; mapJobData.remove(it); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::slotListEntries(KIO::Job * job, const KIO::UDSEntryList & uds) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); QString name, url, mimeType; for (KIO::UDSEntryList::ConstIterator udsIt = uds.begin(); udsIt != uds.end(); udsIt++) { mimeType = QString::null; for (KIO::UDSEntry::ConstIterator eIt = (*udsIt).begin(); eIt != (*udsIt).end(); eIt++) { if ((*eIt).m_uds == KIO::UDS_NAME) name = (*eIt).m_str; else if ((*eIt).m_uds == KIO::UDS_URL) url = (*eIt).m_str; else if ((*eIt).m_uds == KIO::UDS_MIME_TYPE) mimeType = (*eIt).m_str; } if ((mimeType == "inode/directory" || mimeType == "message/digest" || mimeType == "message/directory") && name != ".." && (mHiddenFolders || name.at(0) != '.') && (!(*it).inboxOnly || name == "INBOX")) { static_cast((*it).parent->listView()) ->addImapChildFolder((*it).parent, name, KURL(url).path(), mimeType, (*it).inboxOnly); } } static_cast((*it).parent->listView())->delayedUpdate(); } //----------------------------------------------------------------------------- void KMAcctImap::checkValidity(KMFolderTreeItem * fti) { jobData jd; jd.parent = fti; jd.total = 1; jd.done = 0; KURL url = getUrl(); url.setPath(fti->folder->imapPath() + ";UID=0:0"); makeConnection(); KIO::SimpleJob *job = KIO::get(url, FALSE, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), SLOT(slotCheckValidityResult(KIO::Job *))); connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), SLOT(slotSimpleData(KIO::Job *, const QByteArray &))); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::slotCheckValidityResult(KIO::Job * job) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; if (job->error()) { job->showErrorDialog(); if (job->error() == KIO::ERR_SLAVE_DIED) mSlave = NULL; emit folderComplete((*it).parent, FALSE); mapJobData.remove(it); displayProgress(); } else { QCString cstr((*it).data + '\0'); int a = cstr.find("X-uidValidity: "); int b = cstr.find("\r\n", a); if ((*it).parent->folder->uidValidity() != QString(cstr.mid(a + 15, b - a - 15))) (*it).parent->folder->expunge(); KMFolderTreeItem *fti = (*it).parent; mapJobData.remove(it); reallyGetFolder(fti); } } //----------------------------------------------------------------------------- void KMAcctImap::getFolder(KMFolderTreeItem * fti) { fti->mImapState = KMFolderTreeItem::imapInProgress; if (!fti->folder->uidValidity().isEmpty()) checkValidity(fti); else reallyGetFolder(fti); } //----------------------------------------------------------------------------- void KMAcctImap::reallyGetFolder(KMFolderTreeItem * fti) { jobData jd; jd.parent = fti; jd.total = 1; jd.done = 0; KURL url = getUrl(); url.setPath(fti->folder->imapPath()); url.setQuery("UNDELETED"); makeConnection(); KIO::SimpleJob *job = KIO::listDir(url, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotListFolderResult(KIO::Job *))); connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList &)), this, SLOT(slotListFolderEntries(KIO::Job *, const KIO::UDSEntryList &))); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::getNextMessage(jobData & jd) { if (jd.items.isEmpty()) { jd.parent->mImapState = KMFolderTreeItem::imapFinished; return; } KURL url = getUrl(); url.setPath(jd.parent->folder->imapPath() + ";UID=" + *jd.items.begin() + ";SECTION=ENVELOPE"); jd.items.remove(jd.items.begin()); makeConnection(); KIO::SimpleJob *job = KIO::get(url, FALSE, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotGetMessageResult(KIO::Job *))); connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotSimpleData(KIO::Job *, const QByteArray &))); } //----------------------------------------------------------------------------- void KMAcctImap::slotListFolderResult(KIO::Job * job) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); if (job->error()) { job->showErrorDialog(); if (job->error() == KIO::ERR_SLAVE_DIED) mSlave = NULL; emit folderComplete((*it).parent, FALSE); mapJobData.remove(it); return; } QString uids; QStringList::Iterator uid; (*it).parent->folder->quiet(TRUE); // Check for already retrieved headers if ((*it).parent->folder->count()) { QCString cstr; KMFolder *folder = (*it).parent->folder; int idx = 0, a, b; long int mailUid, serverUid; uid = (*it).items.begin(); while (idx < folder->count() && uid != (*it).items.end()) { folder->getMsgString(idx, cstr); a = cstr.find("X-UID: "); b = cstr.find("\n", a); 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) { idx++; uid = (*it).items.remove(uid); } else break; // happens only, if deleted mails reappear on the server } while (idx < folder->count()) folder->removeMsg(idx, TRUE); } jobData jd; jd.parent = (*it).parent; // jd.items = (*it).items; jd.total = (*it).items.count(); jd.done = 0; uid = (*it).items.begin(); if (jd.total == 0) { (*it).parent->folder->quiet(FALSE); (*it).parent->mImapState = KMFolderTreeItem::imapFinished; emit folderComplete((*it).parent, TRUE); mapJobData.remove(it); displayProgress(); return; } // Force digest mode, even if there is only one message in the folder if (jd.total == 1) uids = *uid + ":" + *uid; else while (uid != (*it).items.end()) { int first = (*uid).toInt(); int last = first - 1; while (uid != (*it).items.end() && (*uid).toInt() == last + 1) { last = (*uid).toInt(); uid++; } if (!uids.isEmpty()) uids += ","; if (first == last) uids += QString::number(first); else uids += QString::number(first) + ":" + QString::number(last); } KURL url = getUrl(); url.setPath((*it).parent->folder->imapPath() + ";UID=" + uids + ";SECTION=ENVELOPE"); makeConnection(); KIO::SimpleJob *newJob = KIO::get(url, FALSE, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, newJob); mapJobData.insert(newJob, jd); connect(newJob, SIGNAL(result(KIO::Job *)), this, SLOT(slotGetMessagesResult(KIO::Job *))); connect(newJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotGetMessagesData(KIO::Job *, const QByteArray &))); mapJobData.remove(it); } //----------------------------------------------------------------------------- void KMAcctImap::slotListFolderEntries(KIO::Job * job, const KIO::UDSEntryList & uds) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); QString mimeType, name; for (KIO::UDSEntryList::ConstIterator udsIt = uds.begin(); udsIt != uds.end(); udsIt++) { for (KIO::UDSEntry::ConstIterator eIt = (*udsIt).begin(); eIt != (*udsIt).end(); eIt++) { if ((*eIt).m_uds == KIO::UDS_NAME) name = (*eIt).m_str; else if ((*eIt).m_uds == KIO::UDS_MIME_TYPE) mimeType = (*eIt).m_str; } if (mimeType == "message/rfc822-imap") (*it).items.append(name); } } //----------------------------------------------------------------------------- void KMAcctImap::slotGetMessagesData(KIO::Job * job, const QByteArray & data) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); (*it).cdata += QCString(data + "\0"); int pos = (*it).cdata.find("\r\n--IMAPDIGEST"); if (pos > 0) { int p = (*it).cdata.find("\r\nX-uidValidity:"); if (p != -1) (*it).parent->folder->setUidValidity((*it).cdata .mid(p + 17, (*it).cdata.find("\r\n", p+1) - p - 17)); (*it).cdata.remove(0, pos); } pos = (*it).cdata.find("\r\n--IMAPDIGEST", 1); while (pos >= 0) { KMMessage *msg = new KMMessage; msg->fromString((*it).cdata.mid(16, pos - 16). replace(QRegExp("\r\n\r\n"),"\r\n")); int flags = msg->headerField("X-Flags").toInt(); if (flags & 2) msg->setStatus(KMMsgStatusReplied); else if (flags & 1) msg->setStatus(KMMsgStatusOld); KMFolder *kf = (*it).parent->folder; 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); (*it).done++; pos = (*it).cdata.find("\r\n--IMAPDIGEST", 1); } displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::slotGetMessagesResult(KIO::Job * job) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); if (job->error()) { job->showErrorDialog(); if (job->error() == KIO::ERR_SLAVE_DIED) mSlave = NULL; (*it).parent->mImapState = KMFolderTreeItem::imapNoInformation; emit folderComplete((*it).parent, FALSE); } else (*it).parent->mImapState = KMFolderTreeItem::imapFinished; (*it).parent->folder->quiet(FALSE); KMFolderTreeItem *fti = (*it).parent; mapJobData.remove(it); displayProgress(); if (!job->error()) emit folderComplete(fti, TRUE); } //----------------------------------------------------------------------------- void KMAcctImap::createFolder(KMFolderTreeItem * fti, const QString &name) { KURL url = getUrl(); url.setPath(fti->folder->imapPath() + name); makeConnection(); KIO::SimpleJob *job = KIO::mkdir(url); KIO::Scheduler::assignJobToSlave(mSlave, job); jobData jd; jd.parent = fti; jd.items = name; jd.total = 1; jd.done = 0; mapJobData.insert(job, jd); displayProgress(); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotCreateFolderResult(KIO::Job *))); } //----------------------------------------------------------------------------- void KMAcctImap::slotCreateFolderResult(KIO::Job * job) { QMap::Iterator it = mapJobData.find(job); assert(it != mapJobData.end()); if (job->error()) job->showErrorDialog(); else { KMFolderTreeItem *fti = new KMFolderTreeItem( (*it).parent, new KMFolder((*it).parent->folder->createChildFolder(), *(*it).items.begin()), (*it).parent->mPaintInfo ); if (fti->folder->create()) { fti->folder->remove(); fti->folder->create(); } fti->setText(0, *(*it).items.begin()); fti->folder->setAccount( this ); fti->folder->setImapPath( (*it).parent->folder->imapPath() + *(*it).items.begin() + "/" ); connect(fti->folder,SIGNAL(numUnreadMsgsChanged(KMFolder*)), static_cast(fti->listView()), SLOT(refresh(KMFolder*))); } mapJobData.remove(it); displayProgress(); } //----------------------------------------------------------------------------- KMImapJob::KMImapJob(KMMessage *msg, JobType jt, KMFolder* folder) { assert(jt == tGetMessage || folder); mType = jt; mDestFolder = folder; mMsg = msg; KMAcctImap *account = (folder) ? folder->account() : msg->parent()->account(); account->mJobList.append(this); if (jt == tPutMessage) { KURL url = account->getUrl(); url.setPath(folder->imapPath()); KMAcctImap::jobData jd; jd.parent = NULL; mOffset = 0; 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.resize(cstr.length() + cstr.contains("\n")); unsigned int i = 0; for (char *ch = cstr.data(); *ch; ch++) { if (*ch == '\n') { mData.at(i) = '\r'; i++; } mData.at(i) = *ch; i++; } 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 if (jt == tCopyMessage) { KURL url = account->getUrl(); url.setPath(msg->parent()->imapPath() + ";UID=" + msg->headerField("X-UID")); KURL destUrl = account->getUrl(); destUrl.setPath(folder->imapPath()); KMAcctImap::jobData jd; jd.parent = NULL; mOffset = 0; jd.total = 1; jd.done = 0; QCString urlStr("C" + url.url()); QByteArray data; QBuffer buff(data); buff.open(IO_WriteOnly | IO_Append); buff.writeBlock(urlStr.data(), urlStr.size()); urlStr = destUrl.url(); buff.writeBlock(urlStr.data(), urlStr.size()); buff.close(); account->makeConnection(); KIO::SimpleJob *simpleJob = KIO::special(url, data, FALSE); KIO::Scheduler::assignJobToSlave(account->slave(), simpleJob); mJob = simpleJob; account->mapJobData.insert(mJob, jd); connect(mJob, SIGNAL(result(KIO::Job *)), SLOT(slotCopyMessageResult(KIO::Job *))); account->displayProgress(); } else { slotGetNextMessage(); } } //----------------------------------------------------------------------------- KMImapJob::~KMImapJob() { if (mMsg) mMsg->setTransferInProgress( FALSE ); } //----------------------------------------------------------------------------- void KMImapJob::slotGetNextMessage() { if (mMsg->headerField("X-UID").isEmpty()) { emit messageRetrieved(mMsg); return; } KMAcctImap *account = mMsg->parent()->account(); KURL url = account->getUrl(); url.setPath(mMsg->parent()->imapPath() + ";UID=" + mMsg->headerField("X-UID")); KMAcctImap::jobData jd; jd.parent = NULL; jd.total = 1; jd.done = 0; account->makeConnection(); KIO::SimpleJob *simpleJob = KIO::get(url, FALSE, FALSE); KIO::Scheduler::assignJobToSlave(account->slave(), simpleJob); mJob = simpleJob; account->mapJobData.insert(mJob, jd); connect(mJob, SIGNAL(result(KIO::Job *)), this, SLOT(slotGetMessageResult(KIO::Job *))); connect(mJob, SIGNAL(data(KIO::Job *, const QByteArray &)), account, SLOT(slotSimpleData(KIO::Job *, const QByteArray &))); account->displayProgress(); } //----------------------------------------------------------------------------- void KMImapJob::slotGetMessageResult(KIO::Job * job) { KMAcctImap *account = mMsg->parent()->account(); QMap::Iterator it = account->mapJobData.find(job); if (it == account->mapJobData.end()) return; assert(it != account->mapJobData.end()); if (job->error()) { job->showErrorDialog(); if (job->error() == KIO::ERR_SLAVE_DIED) account->slaveDied(); } else { QString uid = mMsg->headerField("X-UID"); mMsg->fromString((*it).data); mMsg->setHeaderField("X-UID",uid); mMsg->setComplete( TRUE ); emit messageRetrieved(mMsg); mMsg = NULL; } account->mapJobData.remove(it); account->displayProgress(); account->mJobList.remove(this); delete this; } //----------------------------------------------------------------------------- void KMImapJob::slotPutMessageDataReq(KIO::Job *job, QByteArray &data) { assert(mJob == job); if (mData.size() - mOffset > 0x8000) { data.duplicate(mData.data() + mOffset, 0x8000); mOffset += 0x8000; } else if (mData.size() - mOffset > 0) { data.duplicate(mData.data() + mOffset, mData.size() - mOffset); mOffset = mData.size(); } else data.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(mMsg); mMsg = NULL; } account->mapJobData.remove(it); account->displayProgress(); account->mJobList.remove(this); delete this; } //----------------------------------------------------------------------------- void KMImapJob::slotCopyMessageResult(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 messageCopied(mMsg); mMsg = NULL; } account->mapJobData.remove(it); account->displayProgress(); account->mJobList.remove(this); delete this; } //----------------------------------------------------------------------------- void KMAcctImap::slotSimpleData(KIO::Job * job, const QByteArray & data) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; assert(it != mapJobData.end()); QBuffer buff((*it).data); buff.open(IO_WriteOnly | IO_Append); buff.writeBlock(data.data(), data.size()); buff.close(); } //----------------------------------------------------------------------------- void KMImapJob::ignoreJobsForMessage(KMMessage *msg) { if (!msg || msg->transferInProgress()) return; KMAcctImap *account; if (!msg->parent() || !(account = msg->parent()->account())) return; for (KMImapJob *it = account->mJobList.first(); it; it = account->mJobList.next()) { if ((*it).mMsg == msg) { account->mapJobData.remove( (*it).mJob ); account->mJobList.remove( it ); delete it; break; } } } //----------------------------------------------------------------------------- void KMAcctImap::killAllJobs() { QMap::Iterator it = mapJobData.begin(); for (it = mapJobData.begin(); it != mapJobData.end(); it++) if ((*it).parent) { (*it).parent->mImapState = KMFolderTreeItem::imapFinished; emit folderComplete((*it).parent, FALSE); (*it).parent->folder->quiet(FALSE); } if (mapJobData.begin() != mapJobData.end()) { mSlave->kill(); mSlave = NULL; } mapJobData.clear(); mJobList.setAutoDelete(true); mJobList.clear(); mJobList.setAutoDelete(false); } //----------------------------------------------------------------------------- void KMAcctImap::killJobsForItem(KMFolderTreeItem * fti) { QMap::Iterator it = mapJobData.begin(); while (it != mapJobData.end()) { if (it.data().parent == fti) { killAllJobs(); break; } else it++; } } //----------------------------------------------------------------------------- void KMAcctImap::deleteMessage(KMMessage * msg) { KURL url = getUrl(); url.setPath(msg->parent()->imapPath() + ";UID=" + msg->headerField("X-UID")); makeConnection(); KIO::SimpleJob *job = KIO::file_delete(url, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); jobData jd; jd.total = 1; jd.done = 0; jd.parent = NULL; mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotSimpleResult(KIO::Job *))); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::setStatus(KMMessage * msg, KMMsgStatus status) { QCString flags; switch (status) { case KMMsgStatusNew: case KMMsgStatusUnread: break; case KMMsgStatusDeleted: flags = "\\DELETED"; break; case KMMsgStatusReplied: flags = "\\SEEN \\ANSWERED"; break; default: flags = "\\SEEN"; } KURL url = getUrl(); if (!msg || !msg->parent()) return; url.setPath(msg->parent()->imapPath() + ";UID=" + msg->headerField("X-UID")); QCString urlStr("S" + url.url()); QByteArray data; QBuffer buff(data); buff.open(IO_WriteOnly | IO_Append); buff.writeBlock(urlStr.data(), urlStr.size()); buff.writeBlock(flags.data(), flags.size()); buff.close(); makeConnection(); KIO::SimpleJob *job = KIO::special(url, data, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); jobData jd; jd.total = 1; jd.done = 0; jd.parent = NULL; mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotSimpleResult(KIO::Job *))); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::expungeFolder(KMFolder * aFolder) { KURL url = getUrl(); url.setPath(aFolder->imapPath() + ";UID=*"); makeConnection(); KIO::SimpleJob *job = KIO::file_delete(url, FALSE); KIO::Scheduler::assignJobToSlave(mSlave, job); jobData jd; jd.parent = NULL; jd.total = 1; jd.done = 0; mapJobData.insert(job, jd); connect(job, SIGNAL(result(KIO::Job *)), this, SLOT(slotSimpleResult(KIO::Job *))); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::slotSimpleResult(KIO::Job * job) { QMap::Iterator it = mapJobData.find(job); if (it == mapJobData.end()) return; mapJobData.remove(it); if (job->error()) { job->showErrorDialog(); if (job->error() == KIO::ERR_SLAVE_DIED) mSlave = NULL; } displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::slotAbortRequested() { killAllJobs(); displayProgress(); } //----------------------------------------------------------------------------- void KMAcctImap::readConfig(KConfig& config) { KMAcctImapInherited::readConfig(config); mLogin = config.readEntry("login", ""); mStorePasswd = config.readNumEntry("store-passwd", FALSE); if (mStorePasswd) mPasswd = config.readEntry("passwd"); else mPasswd = ""; mHost = config.readEntry("host"); mPort = config.readNumEntry("port"); mAuth = config.readEntry("auth", "*"); mPrefix = config.readEntry("prefix", "/"); mHiddenFolders = config.readBoolEntry("hidden-folders", FALSE); } //----------------------------------------------------------------------------- void KMAcctImap::writeConfig(KConfig& config) { KMAcctImapInherited::writeConfig(config); config.writeEntry("login", mLogin); config.writeEntry("store-passwd", mStorePasswd); if (mStorePasswd) config.writeEntry("passwd", mPasswd); else config.writeEntry("passwd", ""); config.writeEntry("host", mHost); config.writeEntry("port", static_cast(mPort)); config.writeEntry("auth", mAuth); config.writeEntry("prefix", mPrefix); config.writeEntry("hidden-folders", mHiddenFolders); } //----------------------------------------------------------------------------- const QString KMAcctImap::encryptStr(const QString aStr) const { unsigned int i, val; unsigned int len = aStr.length(); QCString result; result.resize(len+1); for (i=0; ikbp()->idle(); act = account; KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon()); if (!caption.isNull()) setCaption(caption); QGridLayout *gl = new QGridLayout(this, 5, 2, 10); QPixmap pix(locate("data", QString::fromLatin1("kdeui/pics/keys.png"))); if(!pix.isNull()) { l = new QLabel(this); l->setPixmap(pix); l->setFixedSize(l->sizeHint()); gl->addWidget(l, 0, 0); } l = new QLabel(i18n("You need to supply a username and a\n" "password to access this mailbox."), this); l->setFixedSize(l->sizeHint()); gl->addWidget(l, 0, 1); l = new QLabel(i18n("Server:"), this); l->setMinimumSize(l->sizeHint()); gl->addWidget(l, 1, 0); l = new QLabel(act->host(), this); l->setMinimumSize(l->sizeHint()); gl->addWidget(l, 1, 1); l = new QLabel(i18n("Login Name:"), this); l->setMinimumSize(l->sizeHint()); gl->addWidget(l, 2, 0); usernameLEdit = new QLineEdit(login, this); usernameLEdit->setFixedHeight(usernameLEdit->sizeHint().height()); usernameLEdit->setMinimumWidth(usernameLEdit->sizeHint().width()); gl->addWidget(usernameLEdit, 2, 1); l = new QLabel(i18n("Password:"), this); l->setMinimumSize(l->sizeHint()); gl->addWidget(l, 3, 0); passwdLEdit = new QLineEdit(this,"NULL"); passwdLEdit->setEchoMode(QLineEdit::Password); passwdLEdit->setText(passwd); passwdLEdit->setFixedHeight(passwdLEdit->sizeHint().height()); passwdLEdit->setMinimumWidth(passwdLEdit->sizeHint().width()); gl->addWidget(passwdLEdit, 3, 1); connect(passwdLEdit, SIGNAL(returnPressed()), SLOT(slotOkPressed())); KButtonBox *bbox = new KButtonBox(this); bbox->addStretch(1); ok = bbox->addButton(i18n("OK")); ok->setDefault(true); cancel = bbox->addButton(i18n("Cancel")); bbox->layout(); gl->addMultiCellWidget(bbox, 4, 4, 0, 1); connect(ok, SIGNAL(pressed()), this, SLOT(slotOkPressed())); connect(cancel, SIGNAL(pressed()), this, SLOT(slotCancelPressed())); if(strlen(login) > 0) passwdLEdit->setFocus(); else usernameLEdit->setFocus(); gl->activate(); } //----------------------------------------------------------------------------- void KMImapPasswdDialog::slotOkPressed() { act->setLogin(usernameLEdit->text()); act->setPasswd(passwdLEdit->text(), act->storePasswd()); done(1); } //----------------------------------------------------------------------------- void KMImapPasswdDialog::slotCancelPressed() { done(0); }