From ae3aeb3d0ea2b21ff105dd6db13c3d9f1cbebe8e Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 3 May 2007 11:46:52 +0000 Subject: [PATCH 01/34] update version numbers svn path=/branches/kdepim/proko2/kdepim/; revision=660679 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 6a91c1c81..0a0fb84bb 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.7 (proko2 branch after 2.1.6)" +#define KMAIL_VERSION "1.7 (proko2 2.1.7)" #endif /*kmversion_h*/ From 17073260be98a5c68702dab65a788f0efb6187ec Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 3 May 2007 12:11:21 +0000 Subject: [PATCH 02/34] update version numbers svn path=/branches/kdepim/proko2/kdepim/; revision=660682 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 0a0fb84bb..21b57b1f4 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.7 (proko2 2.1.7)" +#define KMAIL_VERSION "1.7 (proko2 branch after 2.1.7)" #endif /*kmversion_h*/ From 20c0deec33c9fbcb51a322fc7543377d39766d89 Mon Sep 17 00:00:00 2001 From: Till Adam Date: Mon, 14 May 2007 16:01:34 +0000 Subject: [PATCH 03/34] Backport fixes for saving single messages from a standalone reader window and when opening from disk. (Kolab Issue 1672) svn path=/branches/kdepim/proko2/kdepim/; revision=664664 --- kmcommands.cpp | 63 +++++++++++++++++++++++++++++++++++--------------- kmcommands.h | 1 + 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index b6483a366..ad66ddec9 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -720,12 +720,24 @@ static KURL subjectToUrl( const QString & subject ) { KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) : KMCommand( parent ), mMsgListIndex( 0 ), + mStandAloneMessage( 0 ), mOffset( 0 ), mTotalSize( msg ? msg->msgSize() : 0 ) { if ( !msg ) return; setDeletesItself( true ); - mMsgList.append( msg->getMsgSerNum() ); + // If the mail has a serial number, operate on sernums, if it does not + // we need to work with the pointer, but can be reasonably sure it won't + // go away, since it'll be an encapsulated message or one that was opened + // from an .eml file. + if ( msg->getMsgSerNum() != 0 ) { + mMsgList.append( msg->getMsgSerNum() ); + if ( msg->parent() ) { + msg->parent()->open(); + } + } else { + mStandAloneMessage = msg; + } mUrl = subjectToUrl( msg->cleanSubject() ); } @@ -733,6 +745,7 @@ KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, const QPtrList &msgList ) : KMCommand( parent ), mMsgListIndex( 0 ), + mStandAloneMessage( 0 ), mOffset( 0 ), mTotalSize( 0 ) { @@ -799,27 +812,39 @@ void KMSaveMsgCommand::slotSaveDataReq() assert( idx >= 0 ); msg = p->getMsg(idx); - if (msg->transferInProgress()) { - QByteArray data = QByteArray(); - mJob->sendAsyncData( data ); - } - msg->setTransferInProgress( true ); - if (msg->isComplete() ) { - slotMessageRetrievedForSaving(msg); - } else { - // retrieve Message first - if (msg->parent() && !msg->isComplete() ) { - FolderJob *job = msg->parent()->createJob(msg); - job->setCancellable( false ); - connect(job, SIGNAL(messageRetrieved(KMMessage*)), - this, SLOT(slotMessageRetrievedForSaving(KMMessage*))); - job->start(); + if ( msg ) { + if (msg->transferInProgress()) { + QByteArray data = QByteArray(); + mJob->sendAsyncData( data ); } + msg->setTransferInProgress( true ); + if (msg->isComplete() ) { + slotMessageRetrievedForSaving(msg); + } else { + // retrieve Message first + if (msg->parent() && !msg->isComplete() ) { + FolderJob *job = msg->parent()->createJob(msg); + job->setCancellable( false ); + connect(job, SIGNAL(messageRetrieved(KMMessage*)), + this, SLOT(slotMessageRetrievedForSaving(KMMessage*))); + job->start(); + } + } + } else { + mJob->slotError( KIO::ERR_ABORTED, + i18n("The message was removed while saving it. " + "It has not been saved.") ); } } else { - // No more messages. Tell the putjob we are done. - QByteArray data = QByteArray(); - mJob->sendAsyncData( data ); + if ( mStandAloneMessage ) { + // do the special case of a standalone message + slotMessageRetrievedForSaving( mStandAloneMessage ); + mStandAloneMessage = 0; + } else { + // No more messages. Tell the putjob we are done. + QByteArray data = QByteArray(); + mJob->sendAsyncData( data ); + } } } diff --git a/kmcommands.h b/kmcommands.h index 25eec2c94..905ccd810 100644 --- a/kmcommands.h +++ b/kmcommands.h @@ -342,6 +342,7 @@ private: KURL mUrl; QValueList mMsgList; unsigned int mMsgListIndex; + KMMessage *mStandAloneMessage; QByteArray mData; int mOffset; size_t mTotalSize; From 1233235476ed24acc05ccc1946b0ff2c7469a6e3 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Tue, 10 Jul 2007 08:22:32 +0000 Subject: [PATCH 04/34] Allow all DIMAP folders as filter sources (Kolab issue 1715). svn path=/branches/kdepim/proko2/kdepim/; revision=685966 --- kmail.kcfg | 5 +++++ kmfoldercachedimap.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/kmail.kcfg b/kmail.kcfg index d3633e693..abf065774 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -217,6 +217,11 @@ "makes changing languages impossible. </p><p>So " "do not set this unless you have to.</p> + + + false + + diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index ba75cdffc..4cae394fa 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -386,7 +386,7 @@ int KMFolderCachedImap::addMsgInternal( KMMessage* msg, bool newMail, // Add the message int rc = KMFolderMaildir::addMsg(msg, index_return); - if( newMail && imapPath() == "/INBOX/" ) + if( newMail && (imapPath() == "/INBOX/" || !GlobalSettings::self()->filterOnlyDIMAPInbox()) ) // This is a new message. Filter it mAccount->processNewMsg( msg ); From 7c2ffb2a3fe72ee201c870c42e186a0892f9a55b Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Wed, 18 Jul 2007 11:22:00 +0000 Subject: [PATCH 05/34] Do not filter new message in groupware folders by default and folders with insufficient access rights (kolab issue 1858). svn path=/branches/kdepim/proko2/kdepim/; revision=689474 --- kmail.kcfg | 4 ++++ kmfoldercachedimap.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/kmail.kcfg b/kmail.kcfg index abf065774..1343ac48d 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -222,6 +222,10 @@ false + + false + + diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index 4cae394fa..6b9940c6d 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -386,7 +386,9 @@ int KMFolderCachedImap::addMsgInternal( KMMessage* msg, bool newMail, // Add the message int rc = KMFolderMaildir::addMsg(msg, index_return); - if( newMail && (imapPath() == "/INBOX/" || !GlobalSettings::self()->filterOnlyDIMAPInbox()) ) + if( newMail && ( imapPath() == "/INBOX/" || ( !GlobalSettings::self()->filterOnlyDIMAPInbox() + && (userRights() <= 0 || userRights() & ACLJobs::Administer ) + && (contentsType() == ContentsTypeMail || GlobalSettings::self()->filterGroupwareFolders()) ) ) ) // This is a new message. Filter it mAccount->processNewMsg( msg ); From 93fdcaa28792abf35ae29fe74eadde3d9e60732f Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Thu, 19 Jul 2007 17:48:16 +0000 Subject: [PATCH 06/34] version bumps for 2.1.8 svn path=/branches/kdepim/proko2/kdepim/; revision=689963 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 21b57b1f4..872f70124 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.7 (proko2 branch after 2.1.7)" +#define KMAIL_VERSION "1.7 (proko2 branch after 2.1.8)" #endif /*kmversion_h*/ From 975b8ad017b1cd935140a625a3544f565efe82ca Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 26 Jul 2007 09:06:05 +0000 Subject: [PATCH 07/34] change column header text svn path=/branches/kdepim/proko2/kdepim/; revision=692784 --- kmheaders.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmheaders.cpp b/kmheaders.cpp index ea8021941..97020b80c 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -1337,7 +1337,7 @@ void KMHeaders::setFolder( KMFolder *aFolder, bool forceJumpToUnread ) colText = i18n( "Date" ); if (mPaintInfo.orderOfArrival) - colText = i18n( "Date (Order of Arrival)" ); + colText = i18n( "Order of Arrival" ); setColumnText( mPaintInfo.dateCol, colText); colText = i18n( "Subject" ); @@ -2987,7 +2987,7 @@ void KMHeaders::setSorting( int column, bool ascending ) QString colText = i18n( "Date" ); if (mPaintInfo.orderOfArrival) - colText = i18n( "Date (Order of Arrival)" ); + colText = i18n( "Order of Arrival" ); setColumnText( mPaintInfo.dateCol, colText); colText = i18n( "Subject" ); From bebc0b47798d6139ff8b9cea1cdf6b68af0df28f Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Wed, 1 Aug 2007 10:00:56 +0000 Subject: [PATCH 08/34] Allow to select DIMAP folders on which filters should be applied. Kolab issue 1858. svn path=/branches/kdepim/proko2/kdepim/; revision=695066 --- Makefile.am | 5 +- antispamwizard.cpp | 3 +- antispamwizard.h | 4 +- foldersetselector.cpp | 88 +++++++++++++++++++++ foldersetselector.h | 45 +++++++++++ kmail.kcfg | 4 +- kmfilterdlg.cpp | 24 ++++++ kmfilterdlg.h | 2 + kmfoldercachedimap.cpp | 18 +++-- kmfolderseldlg.cpp | 147 +---------------------------------- kmfolderseldlg.h | 16 +--- simplefoldertree.h | 171 +++++++++++++++++++++++++++++++++++++++++ 12 files changed, 355 insertions(+), 172 deletions(-) create mode 100644 foldersetselector.cpp create mode 100644 foldersetselector.h create mode 100644 simplefoldertree.h diff --git a/Makefile.am b/Makefile.am index 64b3da54d..9a9c095ea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -100,8 +100,9 @@ libkmailprivate_la_SOURCES = kmmessage.cpp kmmainwin.cpp kmglobalns.cpp configur listjob.cpp renamejob.cpp copyfolderjob.cpp \ composercryptoconfiguration.ui \ warningconfiguration.ui smimeconfiguration.ui annotationjobs.cpp \ - accountcombobox.cpp quotajobs.cpp folderdiaquotatab.cpp \ - localsubscriptiondialog.cpp folderdiaquotatab_p.cpp + accountcombobox.cpp quotajobs.cpp folderdiaquotatab.cpp \ + localsubscriptiondialog.cpp folderdiaquotatab_p.cpp \ + foldersetselector.cpp kmail_SOURCES = main.cpp diff --git a/antispamwizard.cpp b/antispamwizard.cpp index a53d17737..c40a879ff 100644 --- a/antispamwizard.cpp +++ b/antispamwizard.cpp @@ -33,7 +33,6 @@ #include "kmfilteraction.h" #include "kmfiltermgr.h" #include "kmkernel.h" -#include "kmfolderseldlg.h" #include "kmfoldertree.h" #include "kmmainwin.h" @@ -359,7 +358,7 @@ void AntiSpamWizard::accept() /* Now that all the filters have been added to the list, tell * the filter manager about it. That will emit filterListUpdate - * which will result in the filter list in kmmainwidget being + * which will result in the filter list in kmmainwidget being * initialized. This should happend only once. */ KMKernel::self()->filterMgr()->appendFilters( filterList ); } diff --git a/antispamwizard.h b/antispamwizard.h index 1c378327e..89831e059 100644 --- a/antispamwizard.h +++ b/antispamwizard.h @@ -29,6 +29,8 @@ #ifndef KMAIL_ANTISPAMWIZARD_H #define KMAIL_ANTISPAMWIZARD_H +#include "simplefoldertree.h" + #include #include @@ -41,8 +43,6 @@ class QLabel; namespace KMail { - class SimpleFolderTree; - class ASWizInfoPage; class ASWizProgramsPage; class ASWizSpamRulesPage; diff --git a/foldersetselector.cpp b/foldersetselector.cpp new file mode 100644 index 000000000..54000c3f8 --- /dev/null +++ b/foldersetselector.cpp @@ -0,0 +1,88 @@ +/* + Copyright (c) 2007 Volker Krause + + 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; either version 2 of the License, or + (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "foldersetselector.h" + +#include "globalsettings.h" +#include "kmfoldertree.h" +#include "simplefoldertree.h" +#include "kmfoldercachedimap.h" + +#include + +using namespace KMail; + +FolderSetSelector::FolderSetSelector( KMFolderTree *ft, QWidget * parent ) + : KDialogBase( parent, "FolderSetSelector", true, QString(), Ok|Cancel, Ok, true ) +{ + assert( ft ); + + mTreeView = new KMail::SimpleFolderTreeBase( makeVBoxMainWidget(), ft, + GlobalSettings::self()->lastSelectedFolder(), false ); + mTreeView->setFocus(); + + QListViewItemIterator it( mTreeView ); + while ( it.current() ) { + SimpleFolderTreeItem *item = dynamic_cast*>( it.current() ); + ++it; + if ( !item ) + continue; + if ( !item->folder() ) { + item->setEnabled( false ); + continue; + } + if ( item->folder()->folderType() == KMFolderTypeCachedImap + && static_cast( item->folder()->storage() )->imapPath() == "/INBOX/" ) { + item->setOn( true ); + } + if ( item->folder()->folderType() != KMFolderTypeCachedImap ) { + item->setEnabled( false ); + } + } + +} + +QValueList< int > FolderSetSelector::selectedFolders() +{ + QValueList rv; + QListViewItemIterator it( mTreeView ); + while ( it.current() ) { + SimpleFolderTreeItem *item = dynamic_cast*>( it.current() ); + if ( item && item->isOn() && item->folder() ) + rv.append( item->folder()->id() ); + ++it; + } + return rv; +} + +void FolderSetSelector::setSelectedFolders(const QValueList< int > & folderIds) +{ + QListViewItemIterator it( mTreeView ); + while ( it.current() ) { + SimpleFolderTreeItem *item = dynamic_cast*>( it.current() ); + if ( item && item->folder() ) { + if ( folderIds.contains( item->folder()->id() ) ) + item->setOn( true ); + else + item->setOn( false ); + } + ++it; + } +} + +#include "foldersetselector.moc" diff --git a/foldersetselector.h b/foldersetselector.h new file mode 100644 index 000000000..3b7f99d00 --- /dev/null +++ b/foldersetselector.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2007 Volker Krause + + 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; either version 2 of the License, or + (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef KMAIL_FOLDERSETSELECTOR_H +#define KMAIL_FOLDERSETSELECTOR_H + +#include + +class KListView; +class KMFolderTree; + +namespace KMail { + +class FolderSetSelector : public KDialogBase +{ + Q_OBJECT + + public: + FolderSetSelector( KMFolderTree *ft, QWidget *parent = 0 ); + + QValueList selectedFolders(); + void setSelectedFolders( const QValueList &folderIds ); + + private: + KListView *mTreeView; +}; + +} + +#endif diff --git a/kmail.kcfg b/kmail.kcfg index 1343ac48d..b59891e4e 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -218,13 +218,15 @@ "do not set this unless you have to.</p> - + + diff --git a/kmfilterdlg.cpp b/kmfilterdlg.cpp index 6546f2a9f..ffc71ab6d 100644 --- a/kmfilterdlg.cpp +++ b/kmfilterdlg.cpp @@ -10,6 +10,9 @@ // other KMail headers: #include "kmsearchpatternedit.h" #include "kmfiltermgr.h" +#include "foldersetselector.h" +#include "kmmainwidget.h" +#include "globalsettings.h" // other KDE headers: #include @@ -36,6 +39,8 @@ // other headers: #include +using namespace KMail; + // What's this help texts const char * _wt_filterlist = @@ -431,6 +436,14 @@ KMFilterListBox::KMFilterListBox( const QString & title, QWidget *parent, const QWhatsThis::add( mBtnDelete, i18n(_wt_filterlist_delete) ); QWhatsThis::add( mBtnRename, i18n(_wt_filterlist_rename) ); + // third row + if ( !popFilter ) { + hb = new QHBox( this ); + hb->setSpacing( 4 ); + QPushButton *btn = new QPushButton( i18n("Select Source Folders"), hb ); + connect( btn, SIGNAL(clicked()), SLOT(slotSelectSourceFolders()) ); + } + //----------- now connect everything connect( mListBox, SIGNAL(highlighted(int)), @@ -706,6 +719,17 @@ void KMFilterListBox::slotRename() slotUpdateFilterName(); } +void KMFilterListBox::slotSelectSourceFolders() +{ + FolderSetSelector dlg( kmkernel->getKMMainWidget()->folderTree(), this ); + dlg.setCaption( i18n( "Select Folders to Filter" ) ); + if ( !GlobalSettings::filterSourceFolders().isEmpty() ) + dlg.setSelectedFolders( GlobalSettings::filterSourceFolders() ); + if ( dlg.exec() == QDialog::Accepted ) { + GlobalSettings::setFilterSourceFolders( dlg.selectedFolders() ); + } +} + void KMFilterListBox::enableControls() { bool theFirst = ( mIdxSelItem == 0 ); diff --git a/kmfilterdlg.h b/kmfilterdlg.h index 872fee9e6..461ed53a3 100644 --- a/kmfilterdlg.h +++ b/kmfilterdlg.h @@ -130,6 +130,8 @@ protected slots: dialog prompting to enter the new name. */ void slotRename(); + void slotSelectSourceFolders(); + protected: /** The deep copy of the filter list. */ QPtrList mFilterList; diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index 6b9940c6d..15b8560e4 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -386,11 +386,19 @@ int KMFolderCachedImap::addMsgInternal( KMMessage* msg, bool newMail, // Add the message int rc = KMFolderMaildir::addMsg(msg, index_return); - if( newMail && ( imapPath() == "/INBOX/" || ( !GlobalSettings::self()->filterOnlyDIMAPInbox() - && (userRights() <= 0 || userRights() & ACLJobs::Administer ) - && (contentsType() == ContentsTypeMail || GlobalSettings::self()->filterGroupwareFolders()) ) ) ) - // This is a new message. Filter it - mAccount->processNewMsg( msg ); + if ( newMail ) { + // This is a new message. Filter it - maybe + bool filter = false; + if ( GlobalSettings::filterSourceFolders().isEmpty() ) { + if ( imapPath() == "/INBOX/" ) + filter = true; + } else { + if ( GlobalSettings::filterSourceFolders().contains( folder()->id() ) ) + filter = true; + } + if ( filter ) + mAccount->processNewMsg( msg ); + } return rc; } diff --git a/kmfolderseldlg.cpp b/kmfolderseldlg.cpp index 55ebdd0ef..1a3b70e65 100644 --- a/kmfolderseldlg.cpp +++ b/kmfolderseldlg.cpp @@ -2,7 +2,7 @@ #include #include "kmfolderseldlg.h" -#include "kmfoldertree.h" +#include "kmfolder.h" #include "kmmainwidget.h" #include "globalsettings.h" @@ -11,148 +11,6 @@ #include -namespace KMail { - -class FolderItem : public KListViewItem -{ - public: - FolderItem( QListView * listView ); - FolderItem( QListView * listView, QListViewItem * afterListViewItem ); - FolderItem( QListViewItem * listViewItem ); - FolderItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ); - - void setFolder( KMFolder * folder ) { mFolder = folder; }; - const KMFolder * folder() { return mFolder; }; - - private: - KMFolder * mFolder; -}; - -//----------------------------------------------------------------------------- -FolderItem::FolderItem( QListView * listView ) - : KListViewItem( listView ), - mFolder( 0 ) -{} - -//----------------------------------------------------------------------------- -FolderItem::FolderItem( QListView * listView, QListViewItem * afterListViewItem ) - : KListViewItem( listView, afterListViewItem ), - mFolder( 0 ) -{} - -//----------------------------------------------------------------------------- -FolderItem::FolderItem( QListViewItem * listViewItem ) - : KListViewItem( listViewItem ), - mFolder( 0 ) -{} - -//----------------------------------------------------------------------------- -FolderItem::FolderItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) - : KListViewItem( listViewItem, afterListViewItem ), - mFolder( 0 ) -{} - - -//----------------------------------------------------------------------------- -SimpleFolderTree::SimpleFolderTree( QWidget * parent, - KMFolderTree * folderTree, - const QString & preSelection, - bool mustBeReadWrite ) - : KListView( parent ) -{ - assert( folderTree ); - - int columnIdx = addColumn( i18n( "Folder" ) ); - setRootIsDecorated( true ); - setSorting( -1 ); - - FolderItem * lastItem = 0; - FolderItem * lastTopItem = 0; - FolderItem * selectedItem = 0; - int lastDepth = 0; - - for ( QListViewItemIterator it( folderTree ) ; it.current() ; ++it ) { - KMFolderTreeItem * fti = static_cast( it.current() ); - - if ( !fti || fti->protocol() == KFolderTreeItem::Search ) - continue; - - int depth = fti->depth();// - 1; - //kdDebug( 5006 ) << "LastDepth=" << lastDepth << "\tdepth=" << depth - // << "\tname=" << fti->text( 0 ) << endl; - FolderItem * item = 0; - if ( depth <= 0 ) { - // top level - first top level item or after last existing top level item - if ( lastTopItem ) - item = new FolderItem( this, lastTopItem ); - else - item = new FolderItem( this ); - lastTopItem = item; - depth = 0; - } - else { - if ( depth > lastDepth ) { - // next lower level - parent node will get opened - item = new FolderItem( lastItem ); - lastItem->setOpen( true ); - } - else { - if ( depth == lastDepth ) - // same level - behind previous item - item = new FolderItem( lastItem->parent(), lastItem ); - else if ( depth < lastDepth ) { - // above previous level - might be more than one level difference - // but highest possibility is top level - while ( ( depth <= --lastDepth ) && lastItem->parent() ) { - lastItem = static_cast( lastItem->parent() ); - } - if ( lastItem->parent() ) - item = new FolderItem( lastItem->parent(), lastItem ); - else { - // chain somehow broken - what does cause this ??? - kdDebug( 5006 ) << "You shouldn't get here: depth=" << depth - << "folder name=" << fti->text( 0 ) << endl; - item = new FolderItem( this ); - lastTopItem = item; - } - } - } - } - - item->setText( columnIdx, fti->text( 0 ) ); - // Make items without folders and top level items unselectable - // (i.e. root item Local Folders and IMAP accounts) - if ( !fti->folder() || depth == 0 || ( mustBeReadWrite && fti->folder()->isReadOnly() ) ) { - item->setSelectable( false ); - } else { - item->setFolder( fti->folder() ); - if ( preSelection == item->folder()->idString() ) - selectedItem = item; - } - lastItem = item; - lastDepth = depth; - } - - if ( selectedItem ) { - setSelected( selectedItem, true ); - ensureItemVisible( selectedItem ); - } -} - -//----------------------------------------------------------------------------- -const KMFolder * SimpleFolderTree::folder() const -{ - QListViewItem * item = currentItem(); - if( item ) { - const KMFolder * folder = static_cast( item )->folder(); - if( folder ) return folder; - } - return 0; -} - -} // namespace KMail - - //----------------------------------------------------------------------------- KMFolderSelDlg::KMFolderSelDlg( KMMainWidget * parent, const QString& caption, bool mustBeReadWrite ) : KDialogBase( parent, "folder dialog", true, caption, @@ -162,8 +20,7 @@ KMFolderSelDlg::KMFolderSelDlg( KMMainWidget * parent, const QString& caption, b assert( ft ); mTreeView = new KMail::SimpleFolderTree( makeVBoxMainWidget(), ft, - GlobalSettings::self()->lastSelectedFolder(), - mustBeReadWrite ); + GlobalSettings::self()->lastSelectedFolder(), mustBeReadWrite ); mTreeView->setFocus(); connect( mTreeView, SIGNAL( doubleClicked( QListViewItem*, const QPoint&, int ) ), this, SLOT( slotSelect() ) ); diff --git a/kmfolderseldlg.h b/kmfolderseldlg.h index a87375c66..5a3490667 100644 --- a/kmfolderseldlg.h +++ b/kmfolderseldlg.h @@ -6,7 +6,7 @@ #define kmfolderseldlg_h #include -#include +#include #include #include @@ -14,20 +14,6 @@ class KMFolder; class KMFolderTree; class KMMainWidget; -namespace KMail { - - class SimpleFolderTree : public KListView - { - public: - SimpleFolderTree( QWidget * parent, KMFolderTree * folderTree, - const QString & preSelection, bool mustBeReadWrite ); - - const KMFolder * folder() const; - }; - -} - -//----------------------------------------------------------------------------- class KMFolderSelDlg: public KDialogBase { Q_OBJECT diff --git a/simplefoldertree.h b/simplefoldertree.h new file mode 100644 index 000000000..bd6cabc28 --- /dev/null +++ b/simplefoldertree.h @@ -0,0 +1,171 @@ +/* + Copyright (c) 2007 Volker Krause + Copyright (c) 2003 Andreas Gungl + Copyright (c) Stefan Taferner + + 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; either version 2 of the License, or + (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef KMAIL_SIMPLEFOLDERTREE_H +#define KMAIL_SIMPLEFOLDERTREE_H + +#include "kmfoldertree.h" + +#include +#include + +class KMFolder; +class KMFolderTree; + +namespace KMail { + +template class SimpleFolderTreeItem : public T +{ + public: + SimpleFolderTreeItem( QListView * listView ) : T( listView ), mFolder( 0 ) {} + SimpleFolderTreeItem( QListView * listView, QListViewItem * afterListViewItem ) : + T( listView, afterListViewItem ), mFolder( 0 ) {} + SimpleFolderTreeItem( QListViewItem * listViewItem ) : T( listViewItem ), mFolder( 0 ) {} + SimpleFolderTreeItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) : + T( listViewItem, afterListViewItem ), mFolder( 0 ) {} + + void setFolder( KMFolder * folder ) { mFolder = folder; }; + const KMFolder * folder() { return mFolder; }; + + private: + KMFolder * mFolder; +}; + +template <> class SimpleFolderTreeItem : public QCheckListItem +{ + public: + SimpleFolderTreeItem( QListView * listView ) : + QCheckListItem( listView, QString(), CheckBox ), mFolder( 0 ) {} + SimpleFolderTreeItem( QListView * listView, QListViewItem * afterListViewItem ) : + QCheckListItem( listView, afterListViewItem, QString(), CheckBox ), mFolder( 0 ) {} + SimpleFolderTreeItem( QListViewItem * listViewItem ) : + QCheckListItem( listViewItem, QString(), CheckBox ), mFolder( 0 ) {} + SimpleFolderTreeItem( QListViewItem * listViewItem, QListViewItem * afterListViewItem ) : + QCheckListItem( listViewItem, afterListViewItem, QString(), CheckBox ), mFolder( 0 ) {} + + void setFolder( KMFolder * folder ) { mFolder = folder; }; + const KMFolder * folder() { return mFolder; }; + + private: + KMFolder * mFolder; +}; + +template class SimpleFolderTreeBase : public KListView +{ + public: + inline SimpleFolderTreeBase( QWidget * parent, KMFolderTree *folderTree, + const QString &preSelection, bool mustBeReadWrite ) + : KListView( parent ) + { + assert( folderTree ); + int columnIdx = addColumn( i18n( "Folder" ) ); + setRootIsDecorated( true ); + setSorting( -1 ); + + SimpleFolderTreeItem * lastItem = 0; + SimpleFolderTreeItem * lastTopItem = 0; + SimpleFolderTreeItem * selectedItem = 0; + int lastDepth = 0; + + for ( QListViewItemIterator it( folderTree ) ; it.current() ; ++it ) { + KMFolderTreeItem * fti = static_cast( it.current() ); + + if ( !fti || fti->protocol() == KFolderTreeItem::Search ) + continue; + + int depth = fti->depth();// - 1; + //kdDebug( 5006 ) << "LastDepth=" << lastDepth << "\tdepth=" << depth + // << "\tname=" << fti->text( 0 ) << endl; + SimpleFolderTreeItem * item = 0; + if ( depth <= 0 ) { + // top level - first top level item or after last existing top level item + if ( lastTopItem ) + item = new SimpleFolderTreeItem( this, lastTopItem ); + else + item = new SimpleFolderTreeItem( this ); + lastTopItem = item; + depth = 0; + } + else { + if ( depth > lastDepth ) { + // next lower level - parent node will get opened + item = new SimpleFolderTreeItem( lastItem ); + lastItem->setOpen( true ); + } + else { + if ( depth == lastDepth ) + // same level - behind previous item + item = new SimpleFolderTreeItem( lastItem->parent(), lastItem ); + else if ( depth < lastDepth ) { + // above previous level - might be more than one level difference + // but highest possibility is top level + while ( ( depth <= --lastDepth ) && lastItem->parent() ) { + lastItem = static_cast *>( lastItem->parent() ); + } + if ( lastItem->parent() ) + item = new SimpleFolderTreeItem( lastItem->parent(), lastItem ); + else { + // chain somehow broken - what does cause this ??? + kdDebug( 5006 ) << "You shouldn't get here: depth=" << depth + << "folder name=" << fti->text( 0 ) << endl; + item = new SimpleFolderTreeItem( this ); + lastTopItem = item; + } + } + } + } + + item->setText( columnIdx, fti->text( 0 ) ); + // Make items without folders and top level items unselectable + // (i.e. root item Local Folders and IMAP accounts) + if ( !fti->folder() || depth == 0 || ( mustBeReadWrite && fti->folder()->isReadOnly() ) ) { + item->setSelectable( false ); + } else { + item->setFolder( fti->folder() ); + if ( preSelection == item->folder()->idString() ) + selectedItem = item; + } + lastItem = item; + lastDepth = depth; + } + + if ( selectedItem ) { + setSelected( selectedItem, true ); + ensureItemVisible( selectedItem ); + } + } + + inline const KMFolder * folder() const + { + QListViewItem * item = currentItem(); + if( item ) { + const KMFolder * folder = static_cast *>( item )->folder(); + return folder; + } + return 0; + } +}; + +typedef SimpleFolderTreeBase SimpleFolderTree; + +} + + +#endif From 343c480410bd344a644f9b952b708698710d935f Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Thu, 28 Feb 2008 14:09:13 +0000 Subject: [PATCH 09/34] Allow to set the state of several thread at a time. Fixes Intevation issue 2413. svn path=/branches/kdepim/enterprise/kdepim/; revision=780251 --- kmheaders.cpp | 31 ++++++++++++++++++++++++++++++- kmmainwidget.cpp | 7 +------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/kmheaders.cpp b/kmheaders.cpp index d2cb8d6f7..e2dd439d3 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -1218,7 +1218,36 @@ QPtrList KMHeaders::currentThread() const void KMHeaders::setThreadStatus(KMMsgStatus status, bool toggle) { - QPtrList curThread = currentThread(); + QPtrList curThread; + + if (mFolder) { + QPtrList topOfThreads; + + // for each selected item... + for (QListViewItem *item = firstChild(); item; item = item->itemBelow()) + if (item->isSelected() ) { + // ...find the top-level item: + QListViewItem *top = item; + while ( top->parent() ) + top = top->parent(); + if (!topOfThreads.contains(top)) { + topOfThreads.append(top); + } + } + + // for each thread found... + for ( QPtrListIterator it( topOfThreads ) ; + it.current() ; ++ it ) { + QListViewItem *top = *it; + + // collect the items in this thread: + QListViewItem *topOfNextThread = top->nextSibling(); + for ( QListViewItemIterator it( top ) ; + it.current() && it.current() != topOfNextThread ; ++it ) + curThread.append( it.current() ); + } + } + QPtrListIterator it( curThread ); SerNumList serNums; diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index e2a6d925b..e593d4d03 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -3298,15 +3298,10 @@ void KMMainWidget::updateMessageActions() bool allSelectedInCommonThread = false; if ( mHeaders->isThreaded() && count > 1 ) { allSelectedInCommonThread = true; - QListViewItem * curItemParent = mHeaders->currentItem(); - while ( curItemParent->parent() ) - curItemParent = curItemParent->parent(); for ( QPtrListIterator it( selectedItems ) ; it.current() ; ++ it ) { QListViewItem * item = *it; - while ( item->parent() ) - item = item->parent(); - if ( item != curItemParent ) { + if ( item->parent()==0 && item->childCount()==0 ) { allSelectedInCommonThread = false; break; } From 24eeb825249a5a133acade1cd4083899490d2f21 Mon Sep 17 00:00:00 2001 From: Thomas Moenicke Date: Thu, 28 Feb 2008 16:03:25 +0000 Subject: [PATCH 10/34] * enabled by default svn path=/branches/kdepim/enterprise/kdepim/; revision=780273 --- kmreaderwin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index f675f21b5..b146f5bc8 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -516,7 +516,8 @@ KMReaderWin::KMReaderWin(QWidget *aParent, mHtmlWriter( 0 ), mSavedRelativePosition( 0 ), mDecrytMessageOverwrite( false ), - mShowSignatureDetails( false ) + mShowSignatureDetails( false ), + mShowAttachmentQuicklist( true ) { mSplitterSizes << 180 << 100; mMimeTreeMode = 1; From 5aefc6906f72dc9f1d6c840e69935c43da907c25 Mon Sep 17 00:00:00 2001 From: Thomas Moenicke Date: Thu, 28 Feb 2008 20:33:21 +0000 Subject: [PATCH 11/34] * realigned and resized div, so text in the header is now click- and selectable BUG: 151150 svn path=/branches/kdepim/enterprise/kdepim/; revision=780333 --- headerstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/headerstyle.cpp b/headerstyle.cpp index d28934e73..fb7b358e9 100644 --- a/headerstyle.cpp +++ b/headerstyle.cpp @@ -894,7 +894,7 @@ namespace KMail { // kmail icon if(topLevel) { headerStr += - "
\n" + "
\n" "\n" "
\n"; From 6afecfd80befcfa4c5778203177f89aab7e2cc00 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Fri, 29 Feb 2008 10:10:05 +0000 Subject: [PATCH 12/34] -- Version bump. svn path=/branches/kdepim/enterprise/kdepim/; revision=780498 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 4d41c4baf..da2565dc1 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080222.778012)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080229.780496)" #endif /*kmversion_h*/ From ecd9196c7354a43531bbf254058fef8ac867605d Mon Sep 17 00:00:00 2001 From: Thomas Moenicke Date: Fri, 29 Feb 2008 11:38:11 +0000 Subject: [PATCH 13/34] * made attachment quick view a bit more pretty svn path=/branches/kdepim/enterprise/kdepim/; revision=780520 --- kmreaderwin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index b146f5bc8..2dcca0b33 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2731,7 +2731,7 @@ QString KMReaderWin::renderAttachments(partNode * node, const QColor &bgColor ) typeBlacklisted = typeBlacklisted || node == mRootNode; if ( !label.isEmpty() && !icon.isEmpty() && !typeBlacklisted ) { html += "
"; - html += ""; + html += QString::fromLatin1( "" ).arg( bgColor.name() ); html += QString::fromLatin1( "" ).arg( node->nodeId() ); html += " "; if ( headerStyle() == HeaderStyle::enterprise() ) { @@ -2744,7 +2744,7 @@ QString KMReaderWin::renderAttachments(partNode * node, const QColor &bgColor ) } } - html += renderAttachments( node->nextSibling(), bgColor ); + html += renderAttachments( node->nextSibling(), nextColor ( bgColor ) ); return html; } From c02cbe3a857dda82ae4c4aaebca1ae2e13e480f8 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Fri, 29 Feb 2008 12:08:49 +0000 Subject: [PATCH 14/34] -- This version is officially renamed to "Keep Volker Happy" version :). svn path=/branches/kdepim/enterprise/kdepim/; revision=780530 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index da2565dc1..cc8679134 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080229.780496)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080229.780520)" #endif /*kmversion_h*/ From f6ef6af8f59235069c7fac33249cb0514823286e Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Thu, 6 Mar 2008 17:31:59 +0000 Subject: [PATCH 15/34] Fix corruption of binary attachments introduced in revision 771698. The actual problem here is that EncodingDetector::decode(_const_ QByteArray &data) replaces all 0x00 bytes in data with 0x20 although being const. CCMAIL: ahartmetz@gmail.com svn path=/branches/kdepim/enterprise/kdepim/; revision=782964 --- kmcomposewin.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 97e7d038a..9b6366d2a 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -2758,7 +2758,10 @@ void KMComposeWin::slotAttachFileResult(KIO::Job *job) EncodingDetector ed; KLocale *loc = KGlobal::locale(); ed.setAutoDetectLanguage( EncodingDetector::scriptForLanguageCode ( loc->language() ) ); - ed.decode( ( *it ).data ); + // ### FIXME decode(_const_ QByteArray &) replaces 0x00 bytes by 0x20 in the parameter + // despite being const, which obviously breaks binary attachments. + QByteArray copy = (*it).data.copy(); + ed.decode( copy ); partCharset = ed.encoding(); if (partCharset.isEmpty()) //shouldn't happen partCharset = mCharset; From a935e3761ea057f56ac229dc02e31d0a0134e998 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Fri, 7 Mar 2008 15:20:33 +0000 Subject: [PATCH 16/34] - Version bump for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=783247 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index cc8679134..c1b76b674 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080229.780520)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080307.783246)" #endif /*kmversion_h*/ From 629fd5165a318ce7394281e26f135d69e8b07fb4 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Fri, 7 Mar 2008 19:15:37 +0000 Subject: [PATCH 17/34] Some mimelib voodoo to make attachment modification/deletion work with all kinds of multipart sturctures. Kolab issue 1770 svn path=/branches/kdepim/enterprise/kdepim/; revision=783303 --- kmcommands.cpp | 54 ++++++++++++++++++++++++++++++++++++++++---------- kmcommands.h | 4 ++++ kmmessage.cpp | 6 ------ kmmessage.h | 3 --- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 27353f8b2..2358387c6 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -3369,6 +3369,28 @@ void AttachmentModifyCommand::messageDeleteResult(KMCommand * cmd) deleteLater(); } +DwBodyPart * AttachmentModifyCommand::findPart(KMMessage* msg, int index) +{ + int accu = 0; + return findPartInternal( msg->getTopLevelPart(), index, accu ); +} + +DwBodyPart * AttachmentModifyCommand::findPartInternal(DwEntity * root, int index, int & accu) +{ + accu++; + if ( index < accu ) // should not happen + return 0; + DwBodyPart *current = dynamic_cast( root ); + if ( index == accu ) + return current; + DwBodyPart *rv = 0; + if ( root->Body().FirstBodyPart() ) + rv = findPartInternal( root->Body().FirstBodyPart(), index, accu ); + if ( !rv && current && current->Next() ) + rv = findPartInternal( current->Next(), index, accu ); + return rv; +} + KMDeleteAttachmentCommand::KMDeleteAttachmentCommand(partNode * node, KMMessage * msg, QWidget * parent) : AttachmentModifyCommand( node, msg, parent ) @@ -3385,14 +3407,17 @@ KMCommand::Result KMDeleteAttachmentCommand::doAttachmentModify() { KMMessage *msg = retrievedMessage(); KMMessagePart part; - // -2 because partNode counts root and body of the message as well - DwBodyPart *dwpart = msg->dwBodyPart( mPartIndex - 2 ); + DwBodyPart *dwpart = findPart( msg, mPartIndex ); if ( !dwpart ) return Failed; KMMessage::bodyPart( dwpart, &part, true ); if ( !part.isComplete() ) return Failed; - msg->removeBodyPart( dwpart ); + + DwBody *parentNode = dynamic_cast( dwpart->Parent() ); + if ( !parentNode ) + return Failed; + parentNode->RemoveBodyPart( dwpart ); // add dummy part to show that a attachment has been deleted KMMessagePart dummyPart; @@ -3409,7 +3434,9 @@ KMCommand::Result KMDeleteAttachmentCommand::doAttachmentModify() } else if ( cd.isEmpty() ) { dummyPart.setContentDisposition( "attachment" ); } - msg->addBodyPart( &dummyPart ); + DwBodyPart* newDwPart = msg->createDWBodyPart( &dummyPart ); + parentNode->AddBodyPart( newDwPart ); + msg->getTopLevelPart()->Assemble(); KMMessage *newMsg = new KMMessage(); newMsg->fromDwString( msg->asDwString() ); @@ -3435,14 +3462,16 @@ KMCommand::Result KMEditAttachmentCommand::doAttachmentModify() { KMMessage *msg = retrievedMessage(); KMMessagePart part; - // -2 because partNode counts root and body of the message as well - DwBodyPart *dwpart = msg->dwBodyPart( mPartIndex - 2 ); + DwBodyPart *dwpart = findPart( msg, mPartIndex ); if ( !dwpart ) return Failed; KMMessage::bodyPart( dwpart, &part, true ); if ( !part.isComplete() ) return Failed; + if( !dynamic_cast( dwpart->Parent() ) ) + return Failed; + mTempFile.file()->writeBlock( part.bodyDecodedBinary() ); mTempFile.file()->flush(); @@ -3472,15 +3501,20 @@ void KMEditAttachmentCommand::editDone(KMail::EditorWatcher * watcher) // build the new message KMMessage *msg = retrievedMessage(); KMMessagePart part; - // -2 because partNode counts root and body of the message as well - DwBodyPart *dwpart = msg->dwBodyPart( mPartIndex - 2 ); + DwBodyPart *dwpart = findPart( msg, mPartIndex ); KMMessage::bodyPart( dwpart, &part, true ); - msg->removeBodyPart( dwpart ); + + DwBody *parentNode = dynamic_cast( dwpart->Parent() ); + assert( parentNode ); + parentNode->RemoveBodyPart( dwpart ); KMMessagePart att; att.duplicate( part ); att.setBodyEncodedBinary( data ); - msg->addBodyPart( &att ); + + DwBodyPart* newDwPart = msg->createDWBodyPart( &att ); + parentNode->AddBodyPart( newDwPart ); + msg->getTopLevelPart()->Assemble(); KMMessage *newMsg = new KMMessage(); newMsg->fromDwString( msg->asDwString() ); diff --git a/kmcommands.h b/kmcommands.h index 6580ebe4a..02a48c4a0 100644 --- a/kmcommands.h +++ b/kmcommands.h @@ -32,6 +32,8 @@ class KMMessage; class KMMsgBase; class KMReaderWin; class partNode; +class DwBodyPart; +class DwEntity; namespace KIO { class Job; } namespace KMail { class Composer; @@ -1038,6 +1040,7 @@ class KDE_EXPORT AttachmentModifyCommand : public KMCommand protected: void storeChangedMessage( KMMessage* msg ); + DwBodyPart* findPart( KMMessage* msg, int index ); virtual Result doAttachmentModify() = 0; protected: @@ -1046,6 +1049,7 @@ class KDE_EXPORT AttachmentModifyCommand : public KMCommand private: Result execute(); + DwBodyPart* findPartInternal( DwEntity* root, int index, int &accu ); private slots: void messageStoreResult( KMFolderImap* folder, bool success ); diff --git a/kmmessage.cpp b/kmmessage.cpp index ef7e9f23e..613a882fb 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -3126,12 +3126,6 @@ void KMMessage::deleteBodyParts() mMsg->Body().DeleteBodyParts(); } -void KMMessage::removeBodyPart(DwBodyPart * dwPart) -{ - mMsg->Body().RemoveBodyPart( dwPart ); - mNeedsAssembly = true; -} - //----------------------------------------------------------------------------- DwBodyPart* KMMessage::createDWBodyPart(const KMMessagePart* aPart) { diff --git a/kmmessage.h b/kmmessage.h index a3ed19145..a19c9d510 100644 --- a/kmmessage.h +++ b/kmmessage.h @@ -627,9 +627,6 @@ public: /** Delete all body parts. */ void deleteBodyParts(); - /** Removes the given body part. */ - void removeBodyPart( DwBodyPart * dwPart ); - /** Set "Status" and "X-Status" fields of the message from the * internal message status. */ void setStatusFields(); From 78cf645ab79ee5d2a8cfc72cb014fa2dbfc7a923 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Sat, 8 Mar 2008 04:48:20 +0000 Subject: [PATCH 18/34] -- Add the missing virtual d'tors, there are pure virtual methods in the TreeBase class. svn path=/branches/kdepim/enterprise/kdepim/; revision=783478 --- treebase.h | 1 + 1 file changed, 1 insertion(+) diff --git a/treebase.h b/treebase.h index 1b358f525..fec491f3b 100644 --- a/treebase.h +++ b/treebase.h @@ -37,6 +37,7 @@ class TreeBase : public KListView TreeBase( QWidget * parent, KMFolderTree *folderTree, const QString &preSelection, bool mustBeReadWrite ); + virtual ~TreeBase() {} const KMFolder * folder() const; /** Set the current folder */ From 0a5ed6d612455d3bf8d7dfdcd261f408baa49ac0 Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Sat, 8 Mar 2008 18:21:35 +0000 Subject: [PATCH 19/34] Remove some of the weirder methods of EncodingDetector and make the one method public that we actually want: analyze(). analyze() also does not alter its input... svn path=/branches/kdepim/enterprise/kdepim/; revision=783567 --- encodingdetector.cpp | 135 +------------------------------------------ encodingdetector.h | 40 ++----------- kmcomposewin.cpp | 7 +-- 3 files changed, 10 insertions(+), 172 deletions(-) diff --git a/encodingdetector.cpp b/encodingdetector.cpp index 9c5c92f1f..e7ff1c9b2 100644 --- a/encodingdetector.cpp +++ b/encodingdetector.cpp @@ -809,34 +809,6 @@ static int findXMLEncoding(const QCString &str, int &encodingLength) return pos; } -bool EncodingDetector::processNull(char *data, int len) -{ - bool bin=false; - if(is16Bit(d->m_codec)) - { - for (int i=1; i < len; i+=2) - { - if ((data[i]=='\0') && (data[i-1]=='\0')) - { - bin=true; - data[i]=' '; - } - } - return bin; - } - // replace '\0' by spaces, for buggy pages - int i = len-1; - while(--i>=0) - { - if(data[i]==0) - { - bin=true; - data[i]=' '; - } - } - return bin; -} - bool EncodingDetector::errorsIfUtf8 (const char* data, int length) { @@ -902,7 +874,6 @@ static const unsigned char highest5Bits = 0xF8; return false; } - EncodingDetector::EncodingDetector() : d(new EncodingDetectorPrivate) { } @@ -1007,111 +978,9 @@ bool EncodingDetector::setEncoding(const char *_encoding, EncodingChoiceSource t return true; } -QString EncodingDetector::decode(const char *data, int len) -{ - processNull(const_cast(data),len); - if (!d->m_analyzeCalled) - { - analyze(data,len); - d->m_analyzeCalled=true; - } - - return d->m_decoder->toUnicode(data,len); -} - -QString EncodingDetector::decode(const QByteArray &data) -{ - processNull(const_cast(data.data()),data.size()); - if (!d->m_analyzeCalled) - { - analyze(data.data(),data.size()); - d->m_analyzeCalled=true; - } - - return d->m_decoder->toUnicode(data, data.size()); -} - -QString EncodingDetector::decodeWithBuffering(const char *data, int len) -{ -#ifdef DECODE_DEBUG - kWarning() << "EncodingDetector: decoding "<m_writtingHappened) - { -#ifdef DECODE_DEBUG - kWarning() << "EncodingDetector: d->m_writtingHappened "<< d->m_codec->name(); -#endif - processNull(const_cast(data),len); - return d->m_decoder->toUnicode(data, len); - } - else - { - if (d->m_bufferForDefferedEncDetection.isEmpty()) - { - if (analyze(data,len) - && (d->m_seenBody - || !(d->m_source==AutoDetectedEncoding - ||d->m_source==DefaultEncoding - ) - ) - )//dontWannaSeeHead() - { -#ifdef DECODE_DEBUG - kWarning() << "EncodingDetector: m_writtingHappened first time "<< d->m_codec->name(); -#endif - processNull(const_cast(data),len); - d->m_writtingHappened=true; - return d->m_decoder->toUnicode(data, len); - } - else - { -#ifdef DECODE_DEBUG - kWarning() << "EncodingDetector: begin deffer"; -#endif - d->m_bufferForDefferedEncDetection=data; - } - } - else - { - d->m_bufferForDefferedEncDetection+=data; - if ( (analyze(data,len) - && (d->m_seenBody - || !(d->m_source==AutoDetectedEncoding - ||d->m_source==DefaultEncoding - ) - ) - ) || d->m_bufferForDefferedEncDetection.length()>MAX_BUFFER - )//dontWannaSeeHead() - { - d->m_writtingHappened=true; - d->m_bufferForDefferedEncDetection.replace('\0',' '); - QString result(d->m_decoder->toUnicode(d->m_bufferForDefferedEncDetection, - d->m_bufferForDefferedEncDetection.size())); - d->m_bufferForDefferedEncDetection.resize(0); -#ifdef DECODE_DEBUG - kWarning() << "EncodingDetector: m_writtingHappened in the middle " << d->m_codec->name(); -#endif - return result; - } - } - } - - return QString(); -} - -QString EncodingDetector::flush() +bool EncodingDetector::analyze(const QByteArray &data) { - if (d->m_bufferForDefferedEncDetection.isEmpty()) - return QString(); - - d->m_bufferForDefferedEncDetection.replace('\0',' '); - QString result(d->m_decoder->toUnicode(d->m_bufferForDefferedEncDetection, - d->m_bufferForDefferedEncDetection.size())); - d->m_bufferForDefferedEncDetection.resize(0); -#ifdef DECODE_DEBUG - kWarning() << "EncodingDetector:flush() "<< d->m_bufferForDefferedEncDetection.length()<<" bytes "<< d->m_codec->name(); -#endif - return result; + return analyze( data.data(), data.size() ); } bool EncodingDetector::analyze(const char *data, int len) diff --git a/encodingdetector.h b/encodingdetector.h index 2d192e4c6..51ccb4695 100644 --- a/encodingdetector.h +++ b/encodingdetector.h @@ -125,32 +125,16 @@ public: EncodingChoiceSource encodingChoiceSource() const; /** - * The main class method - * - * Calls protected analyze() only the first time of the whole object life - * - * Replaces all null chars with spaces. - */ - QString decode(const char *data, int len); - QString decode(const QByteArray &data); - - //* You don't need to call analyze() if you use this method. - /** - * Convenience method that uses buffering. It waits for full html head to be buffered - * (i.e. calls analyze every time until it returns true). - * - * Replaces all null chars with spaces. - * - * @returns Decoded data, or empty string, if there was not enough data for accurate detection - * @see flush() + * Analyze text data. + * @returns true if there was enough data for accurate detection */ - QString decodeWithBuffering(const char *data, int len); + bool analyze( const char *data, int len ); /** - * Convenience method to be used with decodeForHtml. Flushes buffer. - * @see decodeForHtml() + * Analyze text data. + * @returns true if there was enough data for accurate detection */ - QString flush(); + bool analyze( const QByteArray &data ); /** * Takes lang name _after_ it were i18n()'ed @@ -161,12 +145,6 @@ public: static bool hasAutoDetectionForScript(AutoDetectScript); protected: - /** - * This nice method will kill all 0 bytes (or double bytes) - * and remember if this was a binary or not ;) - */ - bool processNull(char* data,int length); - /** * Check if we are really utf8. Taken from kate * @@ -176,12 +154,6 @@ protected: */ bool errorsIfUtf8 (const char* data, int length); - /** - * Analyze text data. - * @returns true if there was enough data for accurate detection - */ - bool analyze (const char *data, int len); - /** * @returns QTextDecoder for detected encoding */ diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 9b6366d2a..1c9a077ec 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -2758,12 +2758,9 @@ void KMComposeWin::slotAttachFileResult(KIO::Job *job) EncodingDetector ed; KLocale *loc = KGlobal::locale(); ed.setAutoDetectLanguage( EncodingDetector::scriptForLanguageCode ( loc->language() ) ); - // ### FIXME decode(_const_ QByteArray &) replaces 0x00 bytes by 0x20 in the parameter - // despite being const, which obviously breaks binary attachments. - QByteArray copy = (*it).data.copy(); - ed.decode( copy ); + ed.analyze( (*it).data ); partCharset = ed.encoding(); - if (partCharset.isEmpty()) //shouldn't happen + if ( partCharset.isEmpty() ) //shouldn't happen partCharset = mCharset; } From ec8bc75e945f094bd4a136bccf65c4f79c227ee1 Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Sun, 9 Mar 2008 19:22:17 +0000 Subject: [PATCH 20/34] fix return value of scriptForLanguageCode() if the language code is unknown svn path=/branches/kdepim/enterprise/kdepim/; revision=783847 --- encodingdetector.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/encodingdetector.cpp b/encodingdetector.cpp index e7ff1c9b2..e5881d6f7 100644 --- a/encodingdetector.cpp +++ b/encodingdetector.cpp @@ -1370,6 +1370,7 @@ EncodingDetector::AutoDetectScript EncodingDetector::scriptForLanguageCode(const if ( lc.startsWith( QString::fromAscii( langStr ) ) ) return pango_script_for_lang[i].scripts[0]; } + return None; } #undef DECODE_DEBUG From 951b6ef865a3bde262f79f4fb7b9701244050fdf Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Tue, 11 Mar 2008 17:38:06 +0000 Subject: [PATCH 21/34] Ensure the current folder is open here. KMFolderMaildir::addMsg() does the same and thus destorys the message object we are currently working on if the folder hasn't been open before. Kolab issue 2533 svn path=/branches/kdepim/enterprise/kdepim/; revision=784547 --- kmfoldercachedimap.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index d7f5fec77..163c94d07 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -484,8 +484,15 @@ int KMFolderCachedImap::addMsgInternal( KMMessage* msg, bool newMail, uidMapDirty = true; } + KMFolderOpener openThis(folder(), "KMFolderCachedImap::addMsgInternal"); + int rc = openThis.openResult(); + if ( rc ) { + kdDebug(5006) << k_funcinfo << "open: " << rc << " of folder: " << label() << endl; + return rc; + } + // Add the message - int rc = KMFolderMaildir::addMsg(msg, index_return); + rc = KMFolderMaildir::addMsg(msg, index_return); if( newMail && ( imapPath() == "/INBOX/" || ( !GlobalSettings::self()->filterOnlyDIMAPInbox() && (userRights() <= 0 || userRights() & ACLJobs::Administer ) From 0ac5c73839bfdeb94f09198b9add9b2310961967 Mon Sep 17 00:00:00 2001 From: Thomas Moenicke Date: Wed, 12 Mar 2008 09:16:37 +0000 Subject: [PATCH 22/34] * removed the white line of the foldable attachment view (kolab issue 2168) svn path=/branches/kdepim/enterprise/kdepim/; revision=784743 --- kmreaderwin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 2dcca0b33..357659727 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2680,7 +2680,7 @@ void KMReaderWin::injectAttachments() static_cast( injectionPoint ).setInnerHTML( html ); } else { QString html(""); - html += "
" + html += ""; static_cast( injectionPoint ).setInnerHTML( html ); } From b2a0472a41e1c2ff32cb12e243c22781038905e5 Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Thu, 13 Mar 2008 19:44:33 +0000 Subject: [PATCH 23/34] readability++ svn path=/branches/kdepim/enterprise/kdepim/; revision=785316 --- kmailicalifaceimpl.cpp | 4 ++-- kmkernel.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kmailicalifaceimpl.cpp b/kmailicalifaceimpl.cpp index 041a2c162..38eb426f4 100644 --- a/kmailicalifaceimpl.cpp +++ b/kmailicalifaceimpl.cpp @@ -1395,7 +1395,7 @@ void KMailICalIfaceImpl::folderContentsTypeChanged( KMFolder* folder, // Notify that the old folder resource is no longer available subresourceDeleted(folderContentsType( folder->storage()->contentsType() ), location ); - if ( contentsType == 0 ) { + if ( contentsType == KMail::ContentsTypeMail ) { // Delete the old entry, stop listening and stop here mExtraFolders.remove( location ); folder->disconnect( this ); @@ -1405,7 +1405,7 @@ void KMailICalIfaceImpl::folderContentsTypeChanged( KMFolder* folder, } else { if ( ef && !ef->folder ) // deleted folder, clean up mExtraFolders.remove( location ); - if ( contentsType == 0 ) + if ( contentsType == KMail::ContentsTypeMail ) return; //kdDebug(5006) << "registering " << location << " as extra folder" << endl; diff --git a/kmkernel.cpp b/kmkernel.cpp index a888b26b1..a686cffd6 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -1529,7 +1529,7 @@ void KMKernel::init() mBackgroundTasksTimer = new QTimer( this, "mBackgroundTasksTimer" ); connect( mBackgroundTasksTimer, SIGNAL( timeout() ), this, SLOT( slotRunBackgroundTasks() ) ); #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h - mBackgroundTasksTimer->start( 10000, true ); // 10s minute, singleshot + mBackgroundTasksTimer->start( 10000, true ); // 10s, singleshot #else mBackgroundTasksTimer->start( 5 * 60000, true ); // 5 minutes, singleshot #endif From f3d73ff64a1c363144f7b88edc59072e78d363f4 Mon Sep 17 00:00:00 2001 From: Thomas Moenicke Date: Fri, 14 Mar 2008 11:14:44 +0000 Subject: [PATCH 24/34] * dont jump to the top of the email when folding/unfolding the attachment quick view (kolab issue 2168) * show/hide attachment button is not shown when email has no attachments (kolab issue 2529) svn path=/branches/kdepim/enterprise/kdepim/; revision=785558 --- kmreaderwin.cpp | 36 ++++++++++++++++++++++++------------ urlhandlermanager.cpp | 2 ++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 357659727..b973f4e67 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2665,8 +2665,19 @@ void KMReaderWin::injectAttachments() return; QString imgpath( locate("data","kmail/pics/") ); - if( showAttachmentQuicklist() ){ - QString html = renderAttachments( mRootNode, QApplication::palette().active().background() ); + QString visibility; + QString urlHandle; + QString imgSrc; + if( !showAttachmentQuicklist() ) + { + urlHandle.append( "kmail:showAttachmentQuicklist" ); + imgSrc.append( "attachmentQuicklistClosed.png" ); + } else { + urlHandle.append( "kmail:hideAttachmentQuicklist" ); + imgSrc.append( "attachmentQuicklistOpened.png" ); + } + + QString html = renderAttachments( mRootNode, QApplication::palette().active().background() ); if ( html.isEmpty() ) return; @@ -2674,17 +2685,11 @@ void KMReaderWin::injectAttachments() html.prepend( QString::fromLatin1("
%1 
" ).arg(i18n("Attachments:")) ); QString link(""); - link += "
"; + link += "
"; html.prepend( link ); + assert( injectionPoint.tagName() == "div" ); - static_cast( injectionPoint ).setInnerHTML( html ); - } else { - QString html(""); - html += "
" - "
"; - static_cast( injectionPoint ).setInnerHTML( html ); - } - + static_cast( injectionPoint ).setInnerHTML( html ); } static QColor nextColor( const QColor & c ) @@ -2703,12 +2708,19 @@ QString KMReaderWin::renderAttachments(partNode * node, const QColor &bgColor ) if ( node->firstChild() ) { QString subHtml = renderAttachments( node->firstChild(), nextColor( bgColor ) ); if ( !subHtml.isEmpty() ) { + + QString visibility; + if( !showAttachmentQuicklist() ) + { + visibility.append( "display:none;" ); + } + QString margin; if ( node != mRootNode || headerStyle() != HeaderStyle::enterprise() ) margin = "padding:2px; margin:2px; "; if ( node->msgPart().typeStr() == "message" || node == mRootNode ) html += QString::fromLatin1("
").arg( bgColor.name() ).arg( margin ); + "vertical-align:middle; float:left; %3\">").arg( bgColor.name() ).arg( margin ).arg( visibility ); html += subHtml; if ( node->msgPart().typeStr() == "message" || node == mRootNode ) html += "
"; diff --git a/urlhandlermanager.cpp b/urlhandlermanager.cpp index e517600e4..cf5b92d62 100644 --- a/urlhandlermanager.cpp +++ b/urlhandlermanager.cpp @@ -392,12 +392,14 @@ namespace { } if ( url.path() == "showAttachmentQuicklist" ) { + w->saveRelativePosition(); w->setShowAttachmentQuicklist( true ); w->update( true ); return true; } if ( url.path() == "hideAttachmentQuicklist" ) { + w->saveRelativePosition(); w->setShowAttachmentQuicklist( false ); w->update( true ); return true; From 5c6cfda366f6e220ffd822fe94c1bbc5a312b8f5 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Fri, 14 Mar 2008 11:41:56 +0000 Subject: [PATCH 25/34] -- Update the version numbers. svn path=/branches/kdepim/enterprise/kdepim/; revision=785570 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index c1b76b674..b79ebe7f7 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080307.783246)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080314.785563)" #endif /*kmversion_h*/ From 9ea3ef5ff4bf6c2721ac8d19b33bc0e0c40880d0 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Mon, 17 Mar 2008 11:04:58 +0000 Subject: [PATCH 26/34] -- kolab/issue1826 - Default (New Mail) template needs 3 spaces between the top and the signature. svn path=/branches/kdepim/enterprise/kdepim/; revision=786543 --- templatesconfiguration.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templatesconfiguration.cpp b/templatesconfiguration.cpp index bc09eff44..cc5ff9697 100644 --- a/templatesconfiguration.cpp +++ b/templatesconfiguration.cpp @@ -509,7 +509,9 @@ void TemplatesConfiguration::slotInsertCommand( QString cmd, int adjustCursor ) QString TemplatesConfiguration::defaultNewMessage() { return i18n( "%REM=\"Default new message template\"%-\n" - "%BLANK" + "%BLANK\n" + "%BLANK\n" + "%BLANK\n" ); } From e028528bda3818b4445981e1235eb6aa0165f13a Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Wed, 19 Mar 2008 17:41:52 +0000 Subject: [PATCH 27/34] Recover from situations where multiple folders are marked as default groupware folder. Kolab issue 2290 svn path=/branches/kdepim/enterprise/kdepim/; revision=787716 --- kmailicalifaceimpl.cpp | 58 +++++++++++++++++++++++++++--------------- kmailicalifaceimpl.h | 3 +++ kmfoldercachedimap.cpp | 4 +-- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/kmailicalifaceimpl.cpp b/kmailicalifaceimpl.cpp index 38eb426f4..f405167dc 100644 --- a/kmailicalifaceimpl.cpp +++ b/kmailicalifaceimpl.cpp @@ -67,6 +67,7 @@ using KMail::AccountManager; #include #include +#include #include #include #include @@ -1804,8 +1805,9 @@ void KMailICalIfaceImpl::readConfig() for(QValueList >::iterator it = folderList.begin(); it != folderList.end(); ++it) { - FolderStorage* storage = (*it)->storage(); - if ( storage->contentsType() != 0 ) { + KMFolderCachedImap* storage = dynamic_cast( (*it)->storage() ); + if ( storage && storage->contentsType() != 0 ) { + storage->updateAnnotationFolderType(); folderContentsTypeChanged( *it, storage->contentsType() ); } } @@ -1930,6 +1932,19 @@ KMFolder* KMailICalIfaceImpl::initFolder( KMail::FolderContentsType contentsType // Find the folder StandardFolderSearchResult result = findStandardResourceFolder( mFolderParentDir, contentsType ); + + // deal with multiple default groupware folders + if ( result.folders.count() > 1 && result.found == StandardFolderSearchResult::FoundAndStandard ) { + QStringList labels; + for ( QValueList::ConstIterator it = result.folders.begin(); it != result.folders.end(); ++it ) + labels << (*it)->prettyURL(); + const QString selected = KInputDialog::getItem( i18n("Default folder"), + i18n("There are multiple %1 default folders, please choose one:") + .arg( localizedDefaultFolderName( contentsType ) ), labels ); + if ( !selected.isEmpty() ) + result.folder = result.folders[ labels.findIndex( selected ) ]; + } + KMFolder* folder = result.folder; if ( !folder ) { @@ -2125,21 +2140,22 @@ static void vPartMicroParser( const QString& str, QString& s ) } // Returns the first child folder having the given annotation -static KMFolder* findFolderByAnnotation( KMFolderDir* folderParentDir, const QString& annotation ) -{ - QPtrListIterator it( *folderParentDir ); - for ( ; it.current(); ++it ) { - if ( !it.current()->isDir() ) { - KMFolder* folder = static_cast( it.current() ); - if ( folder->folderType() == KMFolderTypeCachedImap ) { - QString folderAnnotation = static_cast( folder->storage() )->annotationFolderType(); - //kdDebug(5006) << "findStandardResourceFolder: " << folder->name() << " has annotation " << folderAnnotation << endl; - if ( folderAnnotation == annotation ) - return folder; - } +static QValueList findFolderByAnnotation( KMFolderDir* folderParentDir, const QString& annotation ) +{ + QValueList rv; + QPtrListIterator it( *folderParentDir ); + for ( ; it.current(); ++it ) { + if ( !it.current()->isDir() ) { + KMFolder* folder = static_cast( it.current() ); + if ( folder->folderType() == KMFolderTypeCachedImap ) { + QString folderAnnotation = static_cast( folder->storage() )->annotationFolderType(); + //kdDebug(5006) << "findStandardResourceFolder: " << folder->name() << " has annotation " << folderAnnotation << endl; + if ( folderAnnotation == annotation ) + rv.append( folder ); } } - return 0; + } + return rv; } KMailICalIfaceImpl::StandardFolderSearchResult KMailICalIfaceImpl::findStandardResourceFolder( KMFolderDir* folderParentDir, KMail::FolderContentsType contentsType ) @@ -2147,14 +2163,14 @@ KMailICalIfaceImpl::StandardFolderSearchResult KMailICalIfaceImpl::findStandardR if ( GlobalSettings::self()->theIMAPResourceStorageFormat() == GlobalSettings::EnumTheIMAPResourceStorageFormat::XML ) { // Look for a folder with an annotation like "event.default" - KMFolder* folder = findFolderByAnnotation( folderParentDir, QString( s_folderContentsType[contentsType].annotation ) + ".default" ); - if ( folder ) - return StandardFolderSearchResult( folder, StandardFolderSearchResult::FoundAndStandard ); + QValueList folders = findFolderByAnnotation( folderParentDir, QString( s_folderContentsType[contentsType].annotation ) + ".default" ); + if ( !folders.isEmpty() ) + return StandardFolderSearchResult( folders, StandardFolderSearchResult::FoundAndStandard ); // Fallback: look for a folder with an annotation like "event" - folder = findFolderByAnnotation( folderParentDir, QString( s_folderContentsType[contentsType].annotation ) ); - if ( folder ) - return StandardFolderSearchResult( folder, StandardFolderSearchResult::FoundByType ); + folders = findFolderByAnnotation( folderParentDir, QString( s_folderContentsType[contentsType].annotation ) ); + if ( !folders.isEmpty() ) + return StandardFolderSearchResult( folders, StandardFolderSearchResult::FoundByType ); // Fallback: look for the folder by name (we'll need to change its type) KMFolderNode* node = folderParentDir->hasNamedFolder( localizedDefaultFolderName( contentsType ) ); diff --git a/kmailicalifaceimpl.h b/kmailicalifaceimpl.h index 261774860..5f56e4fb1 100644 --- a/kmailicalifaceimpl.h +++ b/kmailicalifaceimpl.h @@ -259,7 +259,10 @@ private: enum FoundEnum { FoundAndStandard, NotFound, FoundByType, FoundByName }; StandardFolderSearchResult() : folder( 0 ) {} StandardFolderSearchResult( KMFolder* f, FoundEnum e ) : folder( f ), found( e ) {} + StandardFolderSearchResult( const QValueList &f, FoundEnum e ) : + folder( f.first() ), folders( f ), found( e ) {} KMFolder* folder; // NotFound implies folder==0 of course. + QValueList folders; // in case we found multiple default folders (which should not happen) FoundEnum found; }; diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index 163c94d07..0f70d7609 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -2490,8 +2490,8 @@ void KMFolderCachedImap::updateAnnotationFolderType() newType = KMailICalIfaceImpl::annotationForContentsType( mContentsType ); if ( kmkernel->iCalIface().isStandardResourceFolder( folder() ) ) newSubType = "default"; - else - newSubType = oldSubType; // preserve unknown subtypes, like drafts etc. And preserve ".default" too. + else if ( oldSubType != "default" ) + newSubType = oldSubType; // preserve unknown subtypes, like drafts etc. } //kdDebug(5006) << mImapPath << ": updateAnnotationFolderType: " << newType << " " << newSubType << endl; From 6b5a811e273d1bc5facdbdf355d8b1f173a503de Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Fri, 21 Mar 2008 06:47:48 +0000 Subject: [PATCH 28/34] version bumps svn path=/branches/kdepim/enterprise/kdepim/; revision=788244 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index b79ebe7f7..48889728b 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080314.785563)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080321.788243)" #endif /*kmversion_h*/ From b0f34a41aa0677d340cff2e2bd818e8fbc180ae8 Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz Date: Sat, 22 Mar 2008 00:40:19 +0000 Subject: [PATCH 29/34] Update the copyright years svn path=/branches/kdepim/enterprise/kdepim/; revision=788634 --- aboutdata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aboutdata.cpp b/aboutdata.cpp index 77dd842d7..e525fae49 100644 --- a/aboutdata.cpp +++ b/aboutdata.cpp @@ -211,7 +211,7 @@ namespace KMail { AboutData::AboutData() : KAboutData( "kmail", I18N_NOOP("KMail"),KMAIL_VERSION, I18N_NOOP("KDE Email Client"), License_GPL, - I18N_NOOP("(c) 1997-2005, The KMail developers"), 0, + I18N_NOOP("(c) 1997-2008, The KMail developers"), 0, "http://kontact.kde.org/kmail/" ) { using KMail::authors; From f8dc3562b84e87d32f4bdf8df09d5ff478cf54a2 Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Wed, 26 Mar 2008 16:08:28 +0000 Subject: [PATCH 30/34] No need for this extra open of the search folder. It's supposed to be already opened, and avoid one extra close in the SearchWindow dtor (was crashing kmail if the search folder was opened after being renamed). svn path=/branches/kdepim/enterprise/kdepim/; revision=790349 --- searchwindow.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/searchwindow.cpp b/searchwindow.cpp index 14dcd4712..052ad0362 100644 --- a/searchwindow.cpp +++ b/searchwindow.cpp @@ -527,10 +527,6 @@ void SearchWindow::slotSearch() mFolder->setSearch(search); enableGUI(); - if (mFolder && !mFolders.contains(mFolder.operator->()->folder())) { - mFolder->open("searchwindow"); - mFolders.append(mFolder.operator->()->folder()); - } mTimer->start(200); } From c0d124ece9ca5ca8e4d7cadbe822823f8471f5db Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Wed, 26 Mar 2008 16:28:20 +0000 Subject: [PATCH 31/34] Add an "Open Message" button, and the old open button is now "Open Search Folder". Removed the "Rename" button, now the search folder is renamed "as you type" (after a small delay). Fixes kolab/issue2217. svn path=/branches/kdepim/enterprise/kdepim/; revision=790352 --- searchwindow.cpp | 42 ++++++++++++++++++++++++++++++++++-------- searchwindow.h | 8 ++++++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/searchwindow.cpp b/searchwindow.cpp index 052ad0362..7b9ef5588 100644 --- a/searchwindow.cpp +++ b/searchwindow.cpp @@ -239,6 +239,8 @@ SearchWindow::SearchWindow(KMMainWidget* w, const char* name, connect(mLbxMatches, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(slotShowMsg(QListViewItem *))); + connect(mLbxMatches, SIGNAL(currentChanged(QListViewItem *)), + this, SLOT(slotCurrentChanged(QListViewItem *))); connect( mLbxMatches, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint &, int )), this, SLOT( slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); vbl->addWidget(mLbxMatches); @@ -254,18 +256,20 @@ SearchWindow::SearchWindow(KMMainWidget* w, const char* name, mSearchFolderLbl->setBuddy(mSearchFolderEdt); hbl2->addWidget(mSearchFolderEdt); - mSearchFolderBtn = new QPushButton(i18n("&Rename"), searchWidget); - mSearchFolderBtn->setEnabled(false); - hbl2->addWidget(mSearchFolderBtn); - mSearchFolderOpenBtn = new QPushButton(i18n("Op&en"), searchWidget); + mSearchFolderOpenBtn = new QPushButton(i18n("Op&en Search Folder"), searchWidget); mSearchFolderOpenBtn->setEnabled(false); hbl2->addWidget(mSearchFolderOpenBtn); connect( mSearchFolderEdt, SIGNAL( textChanged( const QString &)), - this, SLOT( updateCreateButton( const QString & ))); - connect( mSearchFolderBtn, SIGNAL( clicked() ), + this, SLOT( scheduleRename( const QString & ))); + connect( &mRenameTimer, SIGNAL( timeout() ), this, SLOT( renameSearchFolder() )); connect( mSearchFolderOpenBtn, SIGNAL( clicked() ), this, SLOT( openSearchFolder() )); + mSearchResultOpenBtn = new QPushButton(i18n("Open &Message"), searchWidget); + mSearchResultOpenBtn->setEnabled(false); + hbl2->addWidget(mSearchResultOpenBtn); + connect( mSearchResultOpenBtn, SIGNAL( clicked() ), + this, SLOT( slotShowSelectedMsg() )); mStatusBar = new KStatusBar(searchWidget); mStatusBar->insertFixedItem(i18n("AMiddleLengthText..."), 0, true); mStatusBar->changeItem(i18n("Ready."), 0); @@ -509,6 +513,7 @@ void SearchWindow::slotSearch() this, SLOT(slotAddMsg(int))); connect(mFolder, SIGNAL(msgRemoved(KMFolder*, Q_UINT32)), this, SLOT(slotRemoveMsg(KMFolder*, Q_UINT32))); + mSearchFolderEdt->setEnabled(false); KMSearch *search = new KMSearch(); connect(search, SIGNAL(finished(bool)), this, SLOT(searchDone())); @@ -544,6 +549,8 @@ void SearchWindow::searchDone() mLbxMatches->setSorting(mSortColumn, mSortOrder == Ascending); mLbxMatches->setShowSortIndicator(true); + + mSearchFolderEdt->setEnabled(true); } void SearchWindow::slotAddMsg(int idx) @@ -621,9 +628,15 @@ void SearchWindow::closeEvent(QCloseEvent *e) } //----------------------------------------------------------------------------- -void SearchWindow::updateCreateButton( const QString &s) +void SearchWindow::scheduleRename( const QString &s) { - mSearchFolderBtn->setEnabled(s != i18n("Last Search") && mSearchFolderOpenBtn->isEnabled()); + if (!s.isEmpty() && s != i18n("Last Search")) { + mRenameTimer.start(250, true); + mSearchFolderOpenBtn->setEnabled(false); + } else { + mRenameTimer.stop(); + mSearchFolderOpenBtn->setEnabled(true); + } } //----------------------------------------------------------------------------- @@ -643,6 +656,7 @@ void SearchWindow::renameSearchFolder() ++i; } } + mSearchFolderOpenBtn->setEnabled(true); } void SearchWindow::openSearchFolder() @@ -688,6 +702,18 @@ bool SearchWindow::slotShowMsg(QListViewItem *item) return true; } +//----------------------------------------------------------------------------- +void SearchWindow::slotShowSelectedMsg() +{ + slotShowMsg(mLbxMatches->currentItem()); +} + +//----------------------------------------------------------------------------- +void SearchWindow::slotCurrentChanged(QListViewItem *item) +{ + mSearchResultOpenBtn->setEnabled(item!=0); +} + //----------------------------------------------------------------------------- void SearchWindow::enableGUI() { diff --git a/searchwindow.h b/searchwindow.h index ce12fbb0e..62c6e6ce3 100644 --- a/searchwindow.h +++ b/searchwindow.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -108,11 +109,13 @@ protected slots: virtual void slotClose(); virtual void slotSearch(); virtual void slotStop(); - void updateCreateButton( const QString &); + void scheduleRename( const QString &); void renameSearchFolder(); void openSearchFolder(); void folderInvalidated(KMFolder *); virtual bool slotShowMsg(QListViewItem *); + void slotShowSelectedMsg(); + void slotCurrentChanged(QListViewItem *); virtual void updateContextMenuActions(); virtual void slotContextMenuRequested( QListViewItem*, const QPoint &, int ); virtual void copySelectedToFolder( int menuId ); @@ -167,8 +170,8 @@ protected: KListView* mLbxMatches; QLabel *mSearchFolderLbl; QLineEdit *mSearchFolderEdt; - QPushButton *mSearchFolderBtn; QPushButton *mSearchFolderOpenBtn; + QPushButton *mSearchResultOpenBtn; KStatusBar* mStatusBar; QWidget* mLastFocus; // to remember the position of the focus QMap mMenuToFolder; @@ -178,6 +181,7 @@ protected: *mCopyAction, *mCutAction; KActionMenu *mForwardActionMenu; QValueList > mFolders; + QTimer mRenameTimer; // not owned by us KMMainWidget* mKMMainWidget; From 9422d495cb25d1cc01e9a419968fec92f3c50a31 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Sat, 29 Mar 2008 15:18:54 +0000 Subject: [PATCH 32/34] SVN_SILENT update version numbers svn path=/branches/kdepim/enterprise/kdepim/; revision=791442 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 48889728b..1149241c0 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080321.788243)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080329.791441)" #endif /*kmversion_h*/ From 4c0bcbbdf6c29ddd6fe47b46dbd04eca7080ec70 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Mon, 31 Mar 2008 17:35:35 +0000 Subject: [PATCH 33/34] Send declined counter proposals back to the sender instead of to myself. Kolab issue 2581 svn path=/branches/kdepim/enterprise/kdepim/; revision=792230 --- callback.cpp | 5 +++++ callback.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/callback.cpp b/callback.cpp index 5bc0d5e2a..fa055393c 100644 --- a/callback.cpp +++ b/callback.cpp @@ -211,3 +211,8 @@ bool Callback::deleteInvitationAfterReply() const { return GlobalSettings::self()->deleteInvitationEmailsAfterSendingReply(); } + +QString Callback::sender() const +{ + return mMsg->from(); +} diff --git a/callback.h b/callback.h index 716b436dd..b66903bfc 100644 --- a/callback.h +++ b/callback.h @@ -69,6 +69,9 @@ public: /** Get the receiver of the mail */ QString receiver() const; + /** Returns the sender of the mail. */ + QString sender() const; + /** Close the main window showing this message, if it's a secondary window. */ void closeIfSecondaryWindow() const; From 8d8c56e6b047478105068e0c8c20330d085ef708 Mon Sep 17 00:00:00 2001 From: Pradeepto Bhattacharya Date: Fri, 4 Apr 2008 10:16:13 +0000 Subject: [PATCH 34/34] Update version numbers for - Happy Birthday Till Adam and Happy Anniversary Jesper release svn path=/branches/kdepim/enterprise/kdepim/; revision=793539 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 1149241c0..bc014471b 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.9 (enterprise 0.20080329.791441)" +#define KMAIL_VERSION "1.9.9 (enterprise 0.20080404.793538)" #endif /*kmversion_h*/