예제 #1
0
//-----------------------------------------------------------------------------
KMFolder* KMFolderDir::createFolder(const QString& aFolderName, bool aSysFldr, KMFolderType aFolderType)
{
  KMFolder* fld;

  assert(!aFolderName.isEmpty());
  // FIXME urgs, is this still needed
  if (mDirType == KMImapDir)
    fld = new KMFolder( this, aFolderName, KMFolderTypeImap );
  else
    fld = new KMFolder( this, aFolderName, aFolderType );

  assert(fld != 0);
  fld->setSystemFolder(aSysFldr);

  KMFolderNode* fNode;
  int index = 0;
  for (fNode=first(); fNode; fNode=next()) {
    if (fNode->name().lower() > fld->name().lower()) {
      insert( index, fld );
      break;
    }
    ++index;
  }

  if (!fNode)
    append(fld);

  fld->correctUnreadMsgsCount();
  return fld;
}
예제 #2
0
void ExpiryPropertiesDialog::slotOk()
{
  bool enableGlobally = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
  if ( enableGlobally && moveToRB->isChecked() && !folderSelector->folder() ) {
    KMessageBox::error( this, i18n("Please select a folder to expire messages into."),
        i18n( "No Folder Selected" ) );
    return;
  } 
  mFolder->setAutoExpire( enableGlobally );
  // we always write out days now
  mFolder->setReadExpireAge( expireReadMailSB->value() );
  mFolder->setUnreadExpireAge( expireUnreadMailSB->value() );
  mFolder->setReadExpireUnits( expireReadMailCB->isChecked()? expireDays : expireNever );
  mFolder->setUnreadExpireUnits( expireUnreadMailCB->isChecked()? expireDays : expireNever );

  if ( deletePermanentlyRB->isChecked() )
    mFolder->setExpireAction( KMFolder::ExpireDelete );
  else
    mFolder->setExpireAction( KMFolder::ExpireMove );
  KMFolder* expireToFolder = folderSelector->folder();
  if ( expireToFolder )
    mFolder->setExpireToFolderId( expireToFolder->idString() );

  // trigger immediate expiry if there is something to do
  if ( enableGlobally )
    mFolder->expireOldMessages( true /*immediate*/);
  KDialogBase::slotOk();
}
예제 #3
0
void KMSearch::start()
{
  //close all referenced folders
  QList<QPointer<KMFolder> >::Iterator fit;
  for ( fit = mOpenedFolders.begin(); fit != mOpenedFolders.end(); ++fit ) {
    if ( !(*fit) ) {
      continue;
    }
    (*fit)->close( "kmsearch" );
  }
  mOpenedFolders.clear();
  mFolders.clear();

  if ( running() ) {
    return;
  }

  if ( !mSearchPattern ) {
    emit finished( true );
    return;
  }

  mFoundCount = 0;
  mSearchCount = 0;
  mRunning = true;

  mFolders.append( mRoot );
  if ( recursive() ) {
    //Append all descendants to folders
    KMFolder *folder;
    for ( int i = 0; i < mFolders.size(); i++ ) {
      folder = mFolders[i];
      KMFolderDir *dir = 0;
      if ( folder ) {
        dir = folder->child();
      } else {
        dir = &kmkernel->folderMgr()->dir();
      }
      if ( !dir ) {
        continue;
      }

      QListIterator<KMFolderNode*> it( *dir );
      while ( it.hasNext() ) {
        KMFolderNode *node = it.next();
        if ( !node->isDir() ) {
          KMFolder* kmf = dynamic_cast<KMFolder*>( node );
          if ( kmf ) {
            mFolders.append( kmf );
          }
        }
      }
    }
  }

  mRemainingFolders = mFolders.count();
  mLastFolder.clear();
  mProcessNextBatchTimer->start( 0 );
}
예제 #4
0
void KMFolder::slotFolderSizeChanged()
{
  emit folderSizeChanged( this );
  KMFolder* papa = parent()->manager()->parentFolder( this );
  if ( papa && papa != this ) {
    papa->slotFolderSizeChanged();
  }
}
예제 #5
0
void FavoriteFolderView::addFolder()
{
    KMFolderSelDlg dlg(mainWidget(), i18n("Add Favorite Folder"), false);
    if(dlg.exec() != QDialog::Accepted)
        return;
    KMFolder *folder = dlg.folder();
    if(!folder)
        return;
    KMFolderTreeItem *fti = findFolderTreeItem(folder);
    addFolder(folder, fti ? prettyName(fti) : folder->label());
}
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;
}
예제 #7
0
int KMFilterMgr::process(Q_UINT32 serNum, const KMFilter *filter)
{
    bool stopIt = false;
    int result = 1;

    if(!filter)
        return 1;

    if(isMatching(serNum, filter))
    {
        KMFolder *folder = 0;
        int idx = -1;
        // get the message with the serNum
        KMMsgDict::instance()->getLocation(serNum, &folder, &idx);
        if(!folder || (idx == -1) || (idx >= folder->count()))
        {
            return 1;
        }
        KMFolderOpener openFolder(folder, "filtermgr");
        KMMsgBase *msgBase = folder->getMsgBase(idx);
        bool unGet = !msgBase->isMessage();
        KMMessage *msg = folder->getMsg(idx);
        // do the actual filtering stuff
        if(!msg || !beginFiltering(msg))
        {
            if(unGet)
                folder->unGetMsg(idx);
            return 1;
        }
        if(filter->execActions(msg, stopIt) == KMFilter::CriticalError)
        {
            if(unGet)
                folder->unGetMsg(idx);
            return 2;
        }

        KMFolder *targetFolder = MessageProperty::filterFolder(msg);

        endFiltering(msg);
        if(targetFolder)
        {
            tempOpenFolder(targetFolder);
            msg->setTransferInProgress(false);
            result = targetFolder->moveMsg(msg);
            msg->setTransferInProgress(true);
        }
        if(unGet)
            folder->unGetMsg(idx);
    }
    else
    {
        result = 1;
    }
    return result;
}
예제 #8
0
int KMFolder::countUnreadRecursive()
{
  KMFolder *folder;
  int count = countUnread();
  KMFolderDir *dir = child();
  if (!dir)
    return count;

  QList<KMFolderNode*>::const_iterator it;
  for ( it = dir->constBegin(); it != dir->constEnd(); ++it )
    if ( !( (*it)->isDir() ) ) {
      folder = static_cast<KMFolder*>( (*it) );
      count += folder->countUnreadRecursive();
    }

  return count;
}
예제 #9
0
/**
 * Refreshes the list of folders we are monitoring.  This is called on
 * startup and is also connected to the 'changed' signal on the KMFolderMgr.
 */
void KMSystemTray::foldersChanged()
{
  /**
   * Hide and remove all unread mappings to cover the case where the only
   * unread message was in a folder that was just removed.
   */
  mFoldersWithUnread.clear();
  mCount = 0;

  if ( mMode == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) {
    hide();
  }

  /** Disconnect all previous connections */
  disconnect(this, SLOT(updateNewMessageNotification(KMFolder *)));

  QStringList folderNames;
  QValueList<QGuardedPtr<KMFolder> > folderList;
  kmkernel->folderMgr()->createFolderList(&folderNames, &folderList);
  kmkernel->imapFolderMgr()->createFolderList(&folderNames, &folderList);
  kmkernel->dimapFolderMgr()->createFolderList(&folderNames, &folderList);
  kmkernel->searchFolderMgr()->createFolderList(&folderNames, &folderList);

  QStringList::iterator strIt = folderNames.begin();

  for(QValueList<QGuardedPtr<KMFolder> >::iterator it = folderList.begin();
     it != folderList.end() && strIt != folderNames.end(); ++it, ++strIt)
  {
    KMFolder * currentFolder = *it;
    QString currentName = *strIt;

    if ( ((!currentFolder->isSystemFolder() || (currentFolder->name().lower() == "inbox")) ||
         (currentFolder->folderType() == KMFolderTypeImap)) &&
         !currentFolder->ignoreNewMail() )
    {
      /** If this is a new folder, start listening for messages */
      connect(currentFolder, SIGNAL(numUnreadMsgsChanged(KMFolder *)),
              this, SLOT(updateNewMessageNotification(KMFolder *)));

      /** Check all new folders to see if we started with any new messages */
      updateNewMessageNotification(currentFolder);
    }
  }
예제 #10
0
int KMFilterMgr::process(KMMessage *msg, const KMFilter *filter)
{
    if(!msg || !filter || !beginFiltering(msg))
        return 1;
    bool stopIt = false;
    int result = 1;

    if(FilterLog::instance()->isLogging())
    {
        QString logText(i18n("<b>Evaluating filter rules:</b> "));
        logText.append(filter->pattern()->asString());
        FilterLog::instance()->add(logText, FilterLog::patternDesc);
    }

    if(filter->pattern()->matches(msg))
    {
        if(FilterLog::instance()->isLogging())
        {
            FilterLog::instance()->add(i18n("<b>Filter rules have matched.</b>"),
                                       FilterLog::patternResult);
        }
        if(filter->execActions(msg, stopIt) == KMFilter::CriticalError)
            return 2;

        KMFolder *folder = MessageProperty::filterFolder(msg);

        endFiltering(msg);
        if(folder)
        {
            tempOpenFolder(folder);
            result = folder->moveMsg(msg);
        }
    }
    else
    {
        endFiltering(msg);
        result = 1;
    }
    return result;
}
예제 #11
0
void KMSearch::stop()
{
  if ( !running() ) {
    return;
  }

  mIncompleteFolders.clear();
  QList<QPointer<KMFolder> >::ConstIterator jt;
  for ( jt = mOpenedFolders.constBegin(); jt != mOpenedFolders.constEnd(); ++jt ) {
    KMFolder *folder = *jt;
    if ( !folder ) {
      continue;
    }
    // explicitly stop jobs for this folder as it will not be closed below
    // when the folder is currently selected
    if ( folder->folderType() == KMFolderTypeImap ) {
      KMAcctImap *account =
        static_cast<KMFolderImap*>( folder->storage() )->account();
      account->ignoreJobsForFolder( folder );
    }
    folder->storage()->search( 0 );
    mSearchCount += folder->count();
    folder->close( "kmsearch" );
  }
  mRemainingFolders = -1;
  mOpenedFolders.clear();
  mFolders.clear();
  mLastFolder.clear();
  mRunning = false;
  emit finished(false);
}
MessageCopyHelper::MessageCopyHelper( const QList<quint32> & msgs,
                                      KMFolder * dest, bool move, QObject * parent ) :
    QObject( parent )
{
  if ( msgs.isEmpty() || !dest )
    return;

  KMFolder *f = 0;
  int index;
  QList<KMMsgBase*> list;

  for ( QList<quint32>::ConstIterator it = msgs.constBegin(); it != msgs.constEnd(); ++it ) {
    KMMsgDict::instance()->getLocation( *it, &f, &index );
    if ( !f ) // not found
      continue;
    if ( f == dest )
      continue; // already there
    if ( !mOpenFolders.contains( f ) ) {// not yet opened
      f->open( "messagecopy" );
      mOpenFolders.insert( f, 0 );
    }
    KMMsgBase *msgBase = f->getMsgBase( index );
    if ( msgBase )
      list.append( msgBase );
  }

  if ( list.isEmpty() )
    return; // nothing to do

  KMCommand *command;
  if ( move ) {
    command = new KMMoveCommand( dest, list );
  } else {
    command = new KMCopyCommand( dest, list );
  }

  connect( command, SIGNAL(completed(KMCommand*)), SLOT(copyCompleted(KMCommand*)) );
  command->start();
}
예제 #13
0
//-----------------------------------------------------------------------------
int KMFolder::moveMsg(KMMessage* aMsg, int* aIndex_ret)
{
  KMFolder* msgParent;
  int rc;

  assert(aMsg != NULL);
  msgParent = aMsg->parent();

  if (msgParent)
  {
    msgParent->open();
    aMsg = msgParent->take(msgParent->find(aMsg));
    msgParent->close();
  }

  open();
  rc = addMsg(aMsg, aIndex_ret);
  close();

  // debug("KMFolder::moveMsg() rc=%i",rc);
  return rc;
}
예제 #14
0
void KMSearch::slotProcessNextBatch()
{
  if ( !running() ) {
    return;
  }

  if ( mFolders.count() != 0 ) {
    KMFolder *folder = *( mFolders.begin() );
    mFolders.erase( mFolders.begin() );
    if ( folder ) {
      mLastFolder = folder->label();
      folder->open( "kmsearch" );
      mOpenedFolders.append( folder );
      connect( folder->storage(),
               SIGNAL( searchResult( KMFolder*, QList<quint32>,
                                     const KMSearchPattern*, bool ) ),
               this,
               SLOT( slotSearchFolderResult( KMFolder*, QList<quint32>,
                                             const KMSearchPattern*, bool ) ) );
      folder->storage()->search( mSearchPattern );
    } else {
      --mRemainingFolders;
예제 #15
0
void KMFilterMgr::endFiltering(KMMsgBase *msgBase) const
{
    KMFolder *parent = msgBase->parent();
    if(parent)
    {
        if(parent == MessageProperty::filterFolder(msgBase))
        {
            parent->take(parent->find(msgBase));
        }
        else if(! MessageProperty::filterFolder(msgBase))
        {
            int index = parent->find(msgBase);
            KMMessage *msg = parent->getMsg(index);
            parent->take(index);
            parent->addMsgKeepUID(msg);
        }
    }
    MessageProperty::setFiltering(msgBase, false);
}
예제 #16
0
//-----------------------------------------------------------------------------
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;
    }
예제 #17
0
void MailManagerImpl::Register( const QDBusObjectPath &registrarPath, uint lastModseq )
{
  Q_UNUSED( lastModseq );
  registrars.append( registrarPath );

  QDBusMessage m = QDBusMessage::createMethodCall( message().service(),
                     registrarPath.path(),
                     "org.freedesktop.email.metadata.Registrar", "Cleanup" );
  QList<QVariant> args;
  args.append ( static_cast<uint> ( time( 0 ) ) );
  m.setArguments( args );
  QDBusConnection::sessionBus().send( m );

  QList< QPointer< KMFolder > > folders = kmkernel->allFolders();
  QList< QPointer< KMFolder > >::Iterator it = folders.begin();

  while ( it != folders.end() ) {
    uint i = 0;

    KMFolder *folder = (*it);
    ++it;

    folder->open("DBus");

    uint fcount = folder->count();

    while ( i < fcount ) {

      QVector<QStringList> predicatesArray;
      QVector<QStringList> valuesArray;
      QStringList subjects;

      uint processed = 0;

      for ( ; i < fcount; ++i ) {
        const KMMsgBase *msg = folder->getMsgBase( i );

        processMsgBase( msg, subjects, predicatesArray, valuesArray );
        processed++;

        if ( processed >= max_per_dbus_call )
          break;
      }

      if (!subjects.isEmpty()) {
        QDBusMessage m = QDBusMessage::createMethodCall( message().service(),
                                registrarPath.path(),
                                "org.freedesktop.email.metadata.Registrar", "SetMany" );
        QList<QVariant> args;

        args.append( subjects );
        args.append( qVariantFromValue( predicatesArray ) );
        args.append( qVariantFromValue( valuesArray ) );
        args.append( static_cast<uint> ( time( 0 ) ) );

        m.setArguments( args );

        QDBusConnection::sessionBus().send( m );
      }
    }

    folder->close( "DBus", false );
  }
}
예제 #18
0
//-----------------------------------------------------------------------------
int KMFolder::compact(void)
{
  KMFolder* tempFolder;
  KMMessage* msg;
  QString tempName, msgStr;
  int openCount = mOpenCount;
  int num, numStatus;


  if (!needsCompact)
  {
    //debug ("Not compacting %s; it's clean", name().data());
    return 0;
  }
  
  debug ("Compacting %s ", name().data());
  
  tempName = "." + name();
  tempName.detach();
  tempName += ".compacted";
  unlink(tempName);
  //tempFolder = parent()->createFolder(tempName); //sven: shouldn't be in list
  tempFolder = new KMFolder(parent(), tempName);   //sven: we create it
  if(tempFolder->create()) {
    debug("KMFolder::compact() Creating tempFolder failed!\n");
    delete tempFolder;                             //sven: and we delete it
    return 0;
  }

  quiet(TRUE);
  tempFolder->open();
  open();

  for(num=1,numStatus=9; count() > 0; num++, numStatus--)
  {
    if (numStatus <= 0)
    {
      msgStr.sprintf(i18n("Compacting folder: %d messages done"), num);
      emit statusMsg(msgStr);
      numStatus = 10;
    }

    msg = getMsg(0);
    if(msg)
      tempFolder->moveMsg(msg);
  }
  tempName = tempFolder->location();
  tempFolder->close(TRUE);
  close(TRUE);
  mMsgList.clear(TRUE);

  _rename(tempName, location());
  _rename(tempFolder->indexLocation(), indexLocation());

  // Now really free all memory
  delete tempFolder;                //sven: we delete it, not the manager

  if (openCount > 0)
  {
    open();
    mOpenCount = openCount;
  }
  quiet(FALSE);

  if (!mQuiet) emit changed();
  needsCompact = false;             // We are clean now
  return 0;
}
예제 #19
0
//-----------------------------------------------------------------------------
int KMFolder::addMsg(KMMessage* aMsg, int* aIndex_ret)
{
  long offs, size, len;
  bool opened = FALSE;
  QString msgText;
  char endStr[3];
  int idx, rc;
  KMFolder* msgParent;
  bool editing = false;

  if (!mStream)
  {
    opened = TRUE;
    rc = open();
    debug("addMsg-open: %d", rc);
    if (rc) return rc;
  }

  // take message out of the folder it is currently in, if any
  msgParent = aMsg->parent();
  if (msgParent)
  {
    if (msgParent==this)
    {
      if (name() == "outbox") //special case for Edit message.
      {
        // debug ("Editing message in outbox");
        editing = true;
      }
      else
        return 0;
    }
    idx = msgParent->find(aMsg);
    if (idx >= 0) msgParent->take(idx);
  }

  aMsg->setStatusFields();
  msgText = aMsg->asString();
  len = msgText.length();

  if (aMsg->status()==KMMsgStatusUnread ||
	  aMsg->status()==KMMsgStatusNew) {
	++unreadMsgs;
	emit numUnreadMsgsChanged( this );
  }

  assert(mStream != NULL);
  if (len <= 0)
  {
    debug("Message added to folder `%s' contains no data. Ignoring it.",
	  (const char*)name());
    if (opened) close();
    return 0;
  }

  // write message to folder file
  fseek(mStream, -2, SEEK_END);
  fread(endStr, 1, 2, mStream); // ensure separating empty line
  if (ftell(mStream) > 0 && endStr[0]!='\n') 
  {
    if (endStr[1]!='\n')
    {
      //printf ("****endStr[1]=%c\n", endStr[1]);
      fwrite("\n\n", 1, 2, mStream);
    }
    else fwrite("\n", 1, 1, mStream);
  }
  fseek(mStream,0,SEEK_END); // this is needed on solaris and others
  fwrite("From aaa@aaa Mon Jan 01 00:00:00 1997\n", 38, 1, mStream);
  offs = ftell(mStream);
  fwrite(msgText, len, 1, mStream);
  if (msgText[len-1]!='\n') fwrite("\n\n", 1, 2, mStream);
  fflush(mStream);
  size = ftell(mStream) - offs;

  // store information about the position in the folder file in the message
  aMsg->setParent(this);
  aMsg->setFolderOffset(offs);
  aMsg->setMsgSize(size);
  idx = mMsgList.append(aMsg);

  // write index entry if desired
  if (mAutoCreateIndex)
  {
    assert(mIndexStream != NULL);
    fseek(mIndexStream, 0, SEEK_END);
    fprintf(mIndexStream, "%s\n", (const char*)aMsg->asIndexString()); 
    fflush(mIndexStream);
  }

  // some "paper work"
  if (aIndex_ret) *aIndex_ret = idx;
  if (!mQuiet) emit msgAdded(idx);
  if (opened) close();

  return 0;
} 
예제 #20
0
int KMFilterMgr::process(KMMessage *msg, FilterSet set,
                         bool account, uint accountId)
{
    if(bPopFilter)
        return processPop(msg);

    if(set == NoSet)
    {
        kdDebug(5006) << "KMFilterMgr: process() called with not filter set selected"
                      << endl;
        return 1;
    }

    bool stopIt = false;
    bool atLeastOneRuleMatched = false;

    if(!beginFiltering(msg))
        return 1;
    for(QValueListConstIterator<KMFilter *> it = mFilters.constBegin();
            !stopIt && it != mFilters.constEnd() ; ++it)
    {

        if((((set & Inbound) && (*it)->applyOnInbound()) &&
                (!account ||
                 (account && (*it)->applyOnAccount(accountId)))) ||
                ((set & Outbound)  && (*it)->applyOnOutbound()) ||
                ((set & Explicit) && (*it)->applyOnExplicit()))
        {
            // filter is applicable

            if(FilterLog::instance()->isLogging())
            {
                QString logText(i18n("<b>Evaluating filter rules:</b> "));
                logText.append((*it)->pattern()->asString());
                FilterLog::instance()->add(logText, FilterLog::patternDesc);
            }
            if((*it)->pattern()->matches(msg))
            {
                // filter matches
                if(FilterLog::instance()->isLogging())
                {
                    FilterLog::instance()->add(i18n("<b>Filter rules have matched.</b>"),
                                               FilterLog::patternResult);
                }
                atLeastOneRuleMatched = true;
                // execute actions:
                if((*it)->execActions(msg, stopIt) == KMFilter::CriticalError)
                    return 2;
            }
        }
    }

    KMFolder *folder = MessageProperty::filterFolder(msg);
    /* endFilter does a take() and addButKeepUID() to ensure the changed
     * message is on disk. This is unnessecary if nothing matched, so just
     * reset state and don't update the listview at all. */
    if(atLeastOneRuleMatched)
        endFiltering(msg);
    else
        MessageProperty::setFiltering(msg, false);
    if(folder)
    {
        tempOpenFolder(folder);
        folder->moveMsg(msg);
        return 0;
    }
    return 1;
}
예제 #21
0
//-----------------------------------------------------------------------------
bool KMFolderDir::reload(void)
{
  QDir               dir;
  KMFolder*          folder;
  QFileInfo*         fileInfo;
  QStringList        diList;
  QPtrList<KMFolder> folderList;

  clear();

  const QString fldPath = path();
  dir.setFilter(QDir::Files | QDir::Dirs | QDir::Hidden);
  dir.setNameFilter("*");

  if (!dir.cd(fldPath, TRUE))
  {
    QString msg = i18n("<qt>Cannot enter folder <b>%1</b>.</qt>").arg(fldPath);
    KMessageBox::information(0, msg);
    return FALSE;
  }

  QFileInfoList* fiList=(QFileInfoList*)dir.entryInfoList();
  if (!fiList)
  {
    QString msg = i18n("<qt>Folder <b>%1</b> is unreadable.</qt>").arg(fldPath);
    KMessageBox::information(0, msg);
    return FALSE;
  }

  for (fileInfo=fiList->first(); fileInfo; fileInfo=fiList->next())
  {
    const QString fname = fileInfo->fileName();
    if( ( fname[0] == '.' ) && !fname.endsWith( ".directory" ) ) {
      // ignore all hidden files except our subfolder containers
      continue;
    }
    if( fname == ".directory" ) {
      // ignore .directory files (not created by us)
      continue;
    }
    // Collect subdirectories.
    if ( fileInfo->isDir() &&
         fname.startsWith( "." ) && fname.endsWith( ".directory" ) ) {
       diList.append(fname);
       continue;
    }

    if ( mDirType == KMImapDir
      && path().startsWith( KMFolderImap::cacheLocation() ) )
    {
       // Is the below needed for dimap as well?
       if ( KMFolderImap::encodeFileName(
                KMFolderImap::decodeFileName( fname ) ) == fname )
       {
          folder = new KMFolder(  this, KMFolderImap::decodeFileName( fname ),
                                  KMFolderTypeImap );
          append(folder);
          folderList.append(folder);
       }
    }
    else if ( mDirType == KMDImapDir
           && path().startsWith( KMFolderCachedImap::cacheLocation() ) )
    {
       if (fileInfo->isDir()) // a directory
       {
          // For this to be a cached IMAP folder, it must be in the KMail dimap
          // subdir and must be have a uidcache file or be a maildir folder
          QString maildir(fname + "/new");
          QString imapcachefile = QString::fromLatin1(".%1.uidcache").arg(fname);
          if ( dir.exists( imapcachefile) || dir.exists( maildir ) )
          {
             folder = new KMFolder( this, fname, KMFolderTypeCachedImap );
             append(folder);
             folderList.append(folder);
          }
       }
    }
    else if ( mDirType == KMSearchDir)
    {
       folder = new KMFolder( this, fname, KMFolderTypeSearch );
       append(folder);
       folderList.append(folder);
    }
    else if ( mDirType == KMStandardDir )
    {
       // This is neither an imap, dimap nor a search folder. Can be either
       // mbox or maildir.
       if (fileInfo->isDir())
       {
          // Maildir folder
          if( dir.exists( fname + "/new" ) )
          {
             folder = new KMFolder( this, fname, KMFolderTypeMaildir );
             append(folder);
             folderList.append(folder);
          }
       }
       else
       {
          // all other files are folders (at the moment ;-)
          folder = new KMFolder( this, fname, KMFolderTypeMbox );
          append(folder);
          folderList.append(folder);
       }
    }
  }

  for (folder=folderList.first(); folder; folder=folderList.next())
  {
    for(QStringList::Iterator it = diList.begin();
        it != diList.end();
        ++it)
      if (*it == "." + folder->fileName() + ".directory")
      {
        KMFolderDir* folderDir = new KMFolderDir( folder, this, *it, mDirType);
        folderDir->reload();
        append(folderDir);
        folder->setChild(folderDir);
        break;
      }
  }
  return TRUE;
}
예제 #22
0
void NewFolderDialog::slotOk()
{
  const QString fldName = mNameLineEdit->text();
  if ( fldName.isEmpty() ) {
     KMessageBox::error( this, i18n("Please specify a name for the new folder."),
        i18n( "No Name Specified" ) );
     return;
  }

  QString msg;
  if ( mFolder && !KMFolder::isValidName( mFolder, fldName, msg ) ) {
    KMessageBox::error( this, msg );
    return;
  }

  // default parent is Top Level local folders
  KMFolderDir * selectedFolderDir = &(kmkernel->folderMgr()->dir());
  // we got a parent, let's use that
  if ( mFolder )
    selectedFolderDir = mFolder->createChildFolder();

  // check if the folder already exists
  if( selectedFolderDir->hasNamedFolder( fldName )
      && ( !( mFolder
          && ( selectedFolderDir == mFolder->parent() )
          && ( mFolder->storage()->objectName() == fldName ) ) ) )
  {
    const QString message = i18n( "<qt>Failed to create folder <b>%1</b>, folder already exists.</qt>", fldName);
    KMessageBox::error( this, message );
    return;
  }

  /* Ok, obvious errors caught, let's try creating it for real. */
  const QString message = i18n( "<qt>Failed to create folder <b>%1</b>."
            "</qt> ", fldName);

  QString namespaceName;
  if ( mNamespacesComboBox ) {
    namespaceName = mNamespacesComboBox->currentText();
  }

  KMFolderType folderType = KMFolderTypeUnknown;
  if ( mFormatComboBox && mFormatComboBox->currentIndex() == 1 )
    folderType = KMFolderTypeMaildir;
  else if ( mFormatComboBox )
    folderType = KMFolderTypeMbox;

  KMFolder *newFolder = KMail::FolderUtil::createSubFolder( mFolder, selectedFolderDir, fldName,
                                                            namespaceName, folderType );
  if ( !newFolder ) {
    KMessageBox::error( this, message );
    return;
  }

  // Set type field
  if ( kmkernel->iCalIface().isEnabled() && mContentsComboBox ) {
    KMail::FolderContentsType type =
      static_cast<KMail::FolderContentsType>( mContentsComboBox->currentIndex() );
    newFolder->storage()->setContentsType( type );
    newFolder->storage()->writeConfig(); // connected slots will read it
  }
}
void KMail::FolderDialogACLTab::load()
{
  if ( mDlg->folder() ) {
    // existing folder
    initializeWithValuesFromFolder( mDlg->folder() );
  } else if ( mDlg->parentFolder() ) {
    // new folder
    initializeWithValuesFromFolder( mDlg->parentFolder() );
    mChanged = true; // ensure that saving happens
  }

  // KABC knows email addresses.
  // We want LDAP userids.
  // Depending on the IMAP server setup, the userid can be the full email address,
  // or just the username part of it.
  // To know which one it is, we currently have a hidden config option,
  // but the default value is determined from the current user's own id.
  QString defaultFormat = "fullemail";
  // warning mImapAccount can be 0 if creating a subsubsubfolder with dimap...  (bug?)
  if ( mImapAccount && !mImapAccount->login().contains('@') )
    defaultFormat = "username"; // no @ found, so we assume it's just the username
  KConfigGroup configGroup( kmkernel->config(), "IMAP" );
  QString str = configGroup.readEntry( "UserIdFormat", defaultFormat );
  mUserIdFormat = FullEmail;
  if ( str == "username" )
    mUserIdFormat = UserName;

  if ( mFolderType == KMFolderTypeCachedImap ) {
    KMFolder* folder = mDlg->folder() ? mDlg->folder() : mDlg->parentFolder();
    KMFolderCachedImap* folderImap = static_cast<KMFolderCachedImap*>( folder->storage() );
    if ( mUserRights == -1 ) { // error
      mLabel->setText( i18n( "Error retrieving user permissions." ) );
    } else if ( mUserRights == 0 /* can't happen anymore*/ || folderImap->aclList().isEmpty() ) {
      /* We either synced, or we read user rights from the config, so we can
         assume the server supports acls and an empty list means we haven't
         synced yet. */
      mLabel->setText( i18n( "Information not retrieved from server, you need to use \"Check Mail\" "
                             "and have administrative privileges on the folder.") );
    } else {
      loadFinished( folderImap->aclList() );
    }
    return;
  }

  // Loading, for online IMAP, consists of four steps:
  // 1) connect
  // 2) get user rights
  // 3) load ACLs

  // First ensure we are connected
  mStack->setCurrentWidget( mLabel );
  if ( !mImapAccount ) { // hmmm?
    mLabel->setText( i18n( "Error: no IMAP account defined for this folder" ) );
    return;
  }
  KMFolder* folder = mDlg->folder() ? mDlg->folder() : mDlg->parentFolder();
  if ( folder && folder->storage() == mImapAccount->rootFolder() )
    return; // nothing to be done for the (virtual) account folder
  mLabel->setText( i18n( "Connecting to server %1, please wait...", mImapAccount->host() ) );
  ImapAccountBase::ConnectionState state = mImapAccount->makeConnection();
  if ( state == ImapAccountBase::Error ) { // Cancelled by user, or slave can't start
    slotConnectionResult( -1, QString() );
  } else if ( state == ImapAccountBase::Connecting ) {
    connect( mImapAccount, SIGNAL( connectionResult(int, const QString&) ),
             this, SLOT( slotConnectionResult(int, const QString&) ) );
  } else { // Connected