From 9a293ca29f63f445b040ef78f15a6a7bc31a8aa1 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 13 Nov 2009 15:41:46 +0000 Subject: [PATCH 001/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1048598 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 015e957f1..443f145d5 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091107.1045967)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091113.1048596)" #endif /*kmversion_h*/ From ec0791a213a0e41e97861553846e943331c3ae70 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 13 Nov 2009 22:46:00 +0000 Subject: [PATCH 002/160] add "Archive Folder" to the context menu. svn path=/branches/kdepim/enterprise/kdepim/; revision=1048770 --- kmfoldertree.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmfoldertree.cpp b/kmfoldertree.cpp index de2d5d4fa..d6f71e461 100644 --- a/kmfoldertree.cpp +++ b/kmfoldertree.cpp @@ -1128,6 +1128,8 @@ void KMFolderTree::slotContextMenuRequested( QListViewItem *lvi, if ( !multiFolder ) mMainWidget->action("search_messages")->plug(folderMenu); + mMainWidget->action( "archive_folder" )->plug( folderMenu ); + mMainWidget->action("compact")->plug(folderMenu); if ( GlobalSettings::self()->enableFavoriteFolderView() ) { From f25ab1fae637677a46741c57bfc7e6859a986103 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 09:46:12 +0000 Subject: [PATCH 003/160] Don't use the 'cache' here for getting the message count, it is unreliable and has off-by-one errors. Use the size of the msgList instead, which is correct and just as fast. kolab/issue3747 svn path=/branches/kdepim/enterprise/kdepim/; revision=1050375 --- backupjob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backupjob.cpp b/backupjob.cpp index e6dc02821..4e7481975 100644 --- a/backupjob.cpp +++ b/backupjob.cpp @@ -403,7 +403,7 @@ void BackupJob::archiveNextFolder() return; } - for ( int i = 0; i < mCurrentFolder->count( true ); i++ ) { + for ( int i = 0; i < mCurrentFolder->count( false /* no cache */ ); i++ ) { unsigned long serNum = KMMsgDict::instance()->getMsgSerNum( mCurrentFolder, i ); if ( serNum == 0 ) { // Uh oh From e98484bc2e7e6e52814610e5740c210c8c2c8d46 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 09:52:19 +0000 Subject: [PATCH 004/160] Add some accelerators. svn path=/branches/kdepim/enterprise/kdepim/; revision=1050389 --- archivefolderdialog.cpp | 11 +++++++---- importarchivedialog.cpp | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 671fe746b..254d3a073 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -60,15 +60,17 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) // TODO: Explaination label // TODO: Use QFormLayout in KDE4 - QLabel *folderLabel = new QLabel( i18n( "Folder:" ), mainWidget ); + QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget ); mainLayout->addWidget( folderLabel, row, 0 ); mFolderRequester = new FolderRequester( mainWidget, kmkernel->getKMMainWidget()->folderTree() ); + folderLabel->setBuddy( mFolderRequester ); mainLayout->addWidget( mFolderRequester, row, 1 ); row++; - QLabel *formatLabel = new QLabel( i18n( "Format:" ), mainWidget ); + QLabel *formatLabel = new QLabel( i18n( "F&ormat:" ), mainWidget ); mainLayout->addWidget( formatLabel, row, 0 ); mFormatComboBox = new KComboBox( mainWidget ); + formatLabel->setBuddy( mFormatComboBox ); // These combobox values have to stay in sync with the ArchiveType enum from BackupJob! mFormatComboBox->insertItem( i18n( "Compressed Zip Archive (.zip)" ) ); @@ -81,18 +83,19 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) mainLayout->addWidget( mFormatComboBox, row, 1 ); row++; - QLabel *fileNameLabel = new QLabel( i18n( "Archive File:" ), mainWidget ); + QLabel *fileNameLabel = new QLabel( i18n( "&Archive File:" ), mainWidget ); mainLayout->addWidget( fileNameLabel, row, 0 ); mUrlRequester = new KURLRequester( mainWidget ); mUrlRequester->setMode( KFile::LocalOnly ); mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" ); + fileNameLabel->setBuddy( mUrlRequester ); connect( mUrlRequester, SIGNAL(urlSelected(const QString&)), this, SLOT(slotFixFileExtension()) ); mainLayout->addWidget( mUrlRequester, row, 1 ); row++; // TODO: Make this appear more dangerous! - mDeleteCheckBox = new QCheckBox( i18n( "Delete folders after completion" ), mainWidget ); + mDeleteCheckBox = new QCheckBox( i18n( "&Delete folders after completion" ), mainWidget ); mainLayout->addMultiCellWidget( mDeleteCheckBox, row, row, 0, 1, Qt::AlignLeft ); row++; diff --git a/importarchivedialog.cpp b/importarchivedialog.cpp index a1e1302c4..fdde1a1b7 100644 --- a/importarchivedialog.cpp +++ b/importarchivedialog.cpp @@ -51,17 +51,19 @@ ImportArchiveDialog::ImportArchiveDialog( QWidget *parent, Qt::WidgetFlags flags // TODO: Use QFormLayout in KDE4 // TODO: better label for "Ok" button - QLabel *folderLabel = new QLabel( i18n( "Folder:" ), mainWidget ); + QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget ); mainLayout->addWidget( folderLabel, row, 0 ); mFolderRequester = new FolderRequester( mainWidget, kmkernel->getKMMainWidget()->folderTree() ); + folderLabel->setBuddy( mFolderRequester ); mainLayout->addWidget( mFolderRequester, row, 1 ); row++; - QLabel *fileNameLabel = new QLabel( i18n( "Archive File:" ), mainWidget ); + QLabel *fileNameLabel = new QLabel( i18n( "&Archive File:" ), mainWidget ); mainLayout->addWidget( fileNameLabel, row, 0 ); mUrlRequester = new KURLRequester( mainWidget ); mUrlRequester->setMode( KFile::LocalOnly ); mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" ); + fileNameLabel->setBuddy( mUrlRequester ); mainLayout->addWidget( mUrlRequester, row, 1 ); row++; From d04063eaed1bd563843e29b4a20bb04aabf01c8f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 10:22:20 +0000 Subject: [PATCH 005/160] Don't insert superflous newlines when inserting the signature at the cursor position. kolab/issue3928 svn path=/branches/kdepim/enterprise/kdepim/; revision=1050431 --- kmcomposewin.cpp | 28 +++++++++++++++++----------- kmcomposewin.h | 4 +++- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index b82fe227c..8fdb4ba2b 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -4416,17 +4416,17 @@ void KMComposeWin::slotAppendSignature() //---------------------------------------------------------------------------- void KMComposeWin::slotPrependSignature() { - insertSignature( false ); + insertSignature( Prepend ); } //---------------------------------------------------------------------------- void KMComposeWin::slotInsertSignatureAtCursor() { - insertSignature( false, mEditor->currentLine() ); + insertSignature( AtCursor, mEditor->currentLine() ); } //---------------------------------------------------------------------------- -void KMComposeWin::insertSignature( bool append, int pos ) +void KMComposeWin::insertSignature( SignaturePlacement placement, int pos ) { bool mod = mEditor->isModified(); @@ -4438,12 +4438,18 @@ void KMComposeWin::insertSignature( bool append, int pos ) if( !mOldSigText.isEmpty() ) { - mEditor->sync(); - if ( append ) { - mEditor->setText( mEditor->text() + mOldSigText ); - } else { - mOldSigText = "\n\n"+mOldSigText+"\n"; - mEditor->insertAt(mOldSigText, pos, 0); + mEditor->sync(); + switch( placement ) { + case Append: + mEditor->setText( mEditor->text() + mOldSigText ); + break; + case Prepend: + mOldSigText = "\n\n" + mOldSigText + "\n"; + mEditor->insertAt( mOldSigText, pos, 0 ); + break; + case AtCursor: + mEditor->insertAt( mOldSigText, pos, 0 ); + break; } mEditor->update(); mEditor->setModified(mod); @@ -4459,7 +4465,7 @@ void KMComposeWin::insertSignature( bool append, int pos ) // for append and prepend, move the cursor to 0,0, for insertAt, // keep it in the same row, but move to first column mEditor->setCursorPosition( pos, 0 ); - if ( !append && pos == 0 ) + if ( placement == Prepend || placement == Append ) mEditor->setContentsPos( 0, 0 ); } mEditor->sync(); @@ -4840,7 +4846,7 @@ void KMComposeWin::slotIdentityChanged( uint uoid ) edtText = edtText.replace( pos, oldLength, mOldSigText ); mEditor->setText( edtText ); } else { - insertSignature( false ); + insertSignature( Append ); } } diff --git a/kmcomposewin.h b/kmcomposewin.h index b02cfdb98..5db3ac169 100644 --- a/kmcomposewin.h +++ b/kmcomposewin.h @@ -725,11 +725,13 @@ private: */ void setTransport( const QString & transport ); + enum SignaturePlacement { Append, Prepend, AtCursor }; + /** * Helper to insert the signature of the current identy at the * beginning or end of the editor. */ - void insertSignature( bool append = true, int pos = 0 ); + void insertSignature( SignaturePlacement placement = Append, int pos = 0 ); private slots: /** * Compress an attachemnt with the given index From 6434ee26e0f6089eaba3d187a85aa540bb8acf10 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 10:59:21 +0000 Subject: [PATCH 006/160] Work around a KFileDialog limitation that disallows using ':' in filenames, by replacing the : with _. svn path=/branches/kdepim/enterprise/kdepim/; revision=1050462 --- kmcommands.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 57bb2f665..d0061c924 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -757,10 +757,12 @@ KMCommand::Result KMShowMsgSrcCommand::execute() return OK; } -static KURL subjectToUrl( const QString & subject ) { - return KFileDialog::getSaveURL( subject.stripWhiteSpace() - .replace( QDir::separator(), '_' ), - "*.mbox" ); +static KURL subjectToUrl( const QString & subject ) +{ + return KFileDialog::getSaveURL( subject.stripWhiteSpace() + .replace( QDir::separator(), '_' ) + .replace( ':', '_' ), + "*.mbox" ); } KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) From 9298fb1e61e14badc4b9b7e4913744ff929e5f4f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 11:59:37 +0000 Subject: [PATCH 007/160] Use an async ImapJob instead of a fake sync addMsg() to upload message to the IMAP server. This fixes several aspects of importing messages to an online IMAP target folder. For example, the completion dialog is only shown when it is really finished, and less horrible crashes occur on failures. svn path=/branches/kdepim/enterprise/kdepim/; revision=1050480 --- importjob.cpp | 97 ++++++++++++++++++++++++++++++++++-------------- importjob.h | 10 +++++ kmfolderimap.cpp | 2 - 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/importjob.cpp b/importjob.cpp index 20bbf1cf1..6a0f46d38 100644 --- a/importjob.cpp +++ b/importjob.cpp @@ -21,6 +21,8 @@ #include "kmfolder.h" #include "folderutil.h" #include "kmfolderdir.h" +#include "kmfolderimap.h" +#include "imapjob.h" #include "progressmanager.h" @@ -44,6 +46,8 @@ ImportJob::ImportJob( QWidget *parentWidget ) mParentWidget( parentWidget ), mNumberOfImportedMessages( 0 ), mCurrentFolder( 0 ), + mCurrentMessage( 0 ), + mCurrentMessageFile( 0 ), mProgressItem( 0 ), mAborted( false ) { @@ -148,6 +152,31 @@ void ImportJob::enqueueMessages( const KArchiveDirectory *dir, KMFolder *folder } } +void ImportJob::messageAdded() +{ + mNumberOfImportedMessages++; + if ( mCurrentFolder->folderType() == KMFolderTypeMaildir || + mCurrentFolder->folderType() == KMFolderTypeCachedImap ) { + const QString messageFile = mCurrentFolder->location() + "/cur/" + mCurrentMessage->fileName(); + // TODO: what if the file is not in the "cur" subdirectory? + if ( QFile::exists( messageFile ) ) { + chmod( messageFile.latin1(), mCurrentMessageFile->permissions() ); + // TODO: changing user/group he requires a bit more work, requires converting the strings + // to uid_t and gid_t + //getpwnam() + //chown( messageFile, + } + else { + kdWarning(5006) << "Unable to change permissions for newly created file: " << messageFile << endl; + } + } + // TODO: Else? + + mCurrentMessage = 0; + mCurrentMessageFile = 0; + QTimer::singleShot( 0, this, SLOT( importNextMessage() ) ); +} + void ImportJob::importNextMessage() { if ( mAborted ) @@ -187,39 +216,53 @@ void ImportJob::importNextMessage() mProgressItem->setProgress( ( mProgressItem->progress() + 5 ) ); - const KArchiveFile *file = messages.files.first(); - Q_ASSERT( file ); + mCurrentMessageFile = messages.files.first(); + Q_ASSERT( mCurrentMessageFile ); messages.files.removeFirst(); - KMMessage *newMessage = new KMMessage(); - newMessage->fromByteArray( file->data(), true /* setStatus */ ); + mCurrentMessage = new KMMessage(); + mCurrentMessage->fromByteArray( mCurrentMessageFile->data(), true /* setStatus */ ); int retIndex; - if ( mCurrentFolder->addMsg( newMessage, &retIndex ) != 0 ) { - abort( i18n( "Failed to add a message to the folder '%1'." ).arg( mCurrentFolder->name() ) ); - return; + + // If this is not an IMAP folder, we can add the message directly. Otherwise, the whole thing is + // async, for online IMAP. While addMsg() fakes a sync call, we rather do it the async way here + // ourselves, as otherwise the whole thing gets pretty much messed up with regards to folder + // refcounting. Furthermore, the completion dialog would be shown before the messages are actually + // uploaded. + if ( mCurrentFolder->folderType() != KMFolderTypeImap ) { + if ( mCurrentFolder->addMsg( mCurrentMessage, &retIndex ) != 0 ) { + abort( i18n( "Failed to add a message to the folder '%1'." ).arg( mCurrentFolder->name() ) ); + return; + } + messageAdded(); } else { - mNumberOfImportedMessages++; - if ( mCurrentFolder->folderType() == KMFolderTypeMaildir || - mCurrentFolder->folderType() == KMFolderTypeCachedImap ) { - const QString messageFile = mCurrentFolder->location() + "/cur/" + newMessage->fileName(); - // TODO: what if the file is not in the "cur" subdirectory? - if ( QFile::exists( messageFile ) ) { - chmod( messageFile.latin1(), file->permissions() ); - // TODO: changing user/group he requires a bit more work, requires converting the strings - // to uid_t and gid_t - //getpwnam() - //chown( messageFile, - } - else { - kdWarning(5006) << "Unable to change permissions for newly created file: " << messageFile << endl; - } - } - // TODO: Else? - kdDebug(5006) << "Added message with subject " /*<< newMessage->subject()*/ // < this causes a pure virtual method to be called... - << " to folder " << mCurrentFolder->name() << " at index " << retIndex << endl; + ImapJob *imapJob = new ImapJob( mCurrentMessage, ImapJob::tPutMessage, + dynamic_cast( mCurrentFolder->storage() ) ); + connect( imapJob, SIGNAL(result(KMail::FolderJob*)), + SLOT(messagePutResult(KMail::FolderJob*)) ); + imapJob->start(); + } +} + +void ImportJob::messagePutResult( KMail::FolderJob *job ) +{ + if ( mAborted ) + return; + + if ( job->error() ) { + abort( i18n( "Failed to upload a message to the IMAP server." ) ); + return; + } else { + + KMFolderImap *imap = dynamic_cast( mCurrentFolder->storage() ); + Q_ASSERT( imap ); + + // Ok, we uploaded the message, but we still need to add it to the folder. Use addMsgQuiet(), + // otherwise it will be uploaded again. + imap->addMsgQuiet( mCurrentMessage ); + messageAdded(); } - QTimer::singleShot( 0, this, SLOT( importNextMessage() ) ); } // Input: .inbox.directory diff --git a/importjob.h b/importjob.h index 57e0a8fd4..43b8a9986 100644 --- a/importjob.h +++ b/importjob.h @@ -32,6 +32,7 @@ class KArchive; class KArchiveDirectory; class KArchiveFile; class KMFolder; +class KMMessage; namespace KPIM { @@ -40,6 +41,7 @@ namespace KPIM namespace KMail { + class FolderJob; /** * Imports an archive that was previously backed up with an BackupJob. @@ -63,6 +65,7 @@ class ImportJob : public QObject void importNextMessage(); void cancelJob(); + void messagePutResult( KMail::FolderJob *job ); private: @@ -86,6 +89,7 @@ class ImportJob : public QObject KMFolder* getOrCreateSubFolder( KMFolder *parentFolder, const QString &subFolderName, mode_t subFolderPermissions ); void enqueueMessages( const KArchiveDirectory *dir, KMFolder *folder ); + void messageAdded(); KArchive *mArchive; @@ -107,6 +111,12 @@ class ImportJob : public QObject // The folder to which we are currently importing messages KMFolder *mCurrentFolder; + // The message which is currently being added + KMMessage *mCurrentMessage; + + // The archive file of the current message that is being added + KArchiveFile *mCurrentMessageFile; + KPIM::ProgressItem *mProgressItem; bool mAborted; }; diff --git a/kmfolderimap.cpp b/kmfolderimap.cpp index 23829c9a2..61d10415d 100644 --- a/kmfolderimap.cpp +++ b/kmfolderimap.cpp @@ -335,8 +335,6 @@ void KMFolderImap::addMsgQuiet(KMMessage* aMsg) int idx = aFolder->find( aMsg ); assert( idx != -1 ); aFolder->take( idx ); - } else { - kdDebug(5006) << k_funcinfo << "no parent" << endl; } if ( !account()->hasCapability("uidplus") ) { // Remember the status with the MD5 as key From f8cfdddf0acd28a9215311f5c73fa63a9ffdee88 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 21:45:45 +0000 Subject: [PATCH 008/160] Fix potential index corruption - Don't let the fact that the last message's index string was synced correctly un-dirty the whole index. This fixes some scenarios where the index was not written at all. svn path=/branches/kdepim/enterprise/kdepim/; revision=1050678 --- kmfolderindex.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kmfolderindex.cpp b/kmfolderindex.cpp index a76b74f53..2f8ed7b53 100644 --- a/kmfolderindex.cpp +++ b/kmfolderindex.cpp @@ -110,9 +110,13 @@ int KMFolderIndex::updateIndex() return 0; bool dirty = mDirty; mDirtyTimer->stop(); - for (unsigned int i=0; !dirty && isyncIndexString(); + for ( unsigned int i = 0; !dirty && i < mMsgList.high(); i++ ) { + if ( mMsgList.at(i) ) { + if ( !mMsgList.at(i)->syncIndexString() ) { + dirty = true; + } + } + } if (!dirty) { // Update successful touchFolderIdsFile(); return 0; From c0808eb703eb82eb3f57bf617d4350ccfed77b09 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 17 Nov 2009 21:49:45 +0000 Subject: [PATCH 009/160] Revert r529696 - "hotfix for the messagelist corruption". No idea if that bug is still there, but this "hotfix" prevents the index from being written out. And an outdated index can lead to funny things, like messages that are empty and can not be deleted, as observed in kolab/issue3098. Fixes kolab/issue3098, together with the previous commit. svn path=/branches/kdepim/enterprise/kdepim/; revision=1050682 --- kmfolderimap.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/kmfolderimap.cpp b/kmfolderimap.cpp index 61d10415d..cee3cc250 100644 --- a/kmfolderimap.cpp +++ b/kmfolderimap.cpp @@ -109,12 +109,6 @@ KMFolderImap::~KMFolderImap() //----------------------------------------------------------------------------- void KMFolderImap::reallyDoClose(const char* owner) { - if (isSelected()) { - kdWarning(5006) << "Trying to close the selected folder " << label() << - " - ignoring!" << endl; - return; - } - // FIXME is this still needed? if (account()) account()->ignoreJobsForFolder( folder() ); From ed8d79656766c1f5fb59390a1a359b540f457702 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 26 Nov 2009 23:08:19 +0000 Subject: [PATCH 010/160] Don't show two offline warning windows that might overlap and block kolab/issue3969 MERGE: e4,trunk,4.3 svn path=/branches/kdepim/enterprise/kdepim/; revision=1054852 --- kmkernel.cpp | 8 ++++++++ kmmainwidget.cpp | 1 + 2 files changed, 9 insertions(+) diff --git a/kmkernel.cpp b/kmkernel.cpp index 8704c5b4a..9a509802e 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -93,6 +93,7 @@ using KWallet::Wallet; #include KMKernel *KMKernel::mySelf = 0; +static bool s_askingToGoOnline = false; /********************************************************************/ /* Constructor and destructor */ @@ -1276,7 +1277,13 @@ bool KMKernel::isOffline() bool KMKernel::askToGoOnline() { + // already asking means we are offline and need to wait anyhow + if ( s_askingToGoOnline ) { + return false; + } + if ( kmkernel->isOffline() ) { + s_askingToGoOnline = true; int rc = KMessageBox::questionYesNo( KMKernel::self()->mainWin(), i18n("KMail is currently in offline mode. " @@ -1285,6 +1292,7 @@ bool KMKernel::askToGoOnline() i18n("Work Online"), i18n("Work Offline")); + s_askingToGoOnline = false; if( rc == KMessageBox::No ) { return false; } else { diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index b9c896a8f..6f5b66c93 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -1884,6 +1884,7 @@ void KMMainWidget::slotOnlineStatus() kmkernel->stopNetworkJobs(); } else { kmkernel->resumeNetworkJobs(); + slotCheckVacation(); } } From a67b29642207f04c89738194ed967fbee77dce2a Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 18:02:48 +0000 Subject: [PATCH 011/160] Extract the code that RFC-2231-encodes a string with an autodetected charset, it was duplicated in a number of places. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055258 --- kmmessage.cpp | 10 ++-------- kmmsgbase.cpp | 10 ++++++++++ kmmsgbase.h | 7 +++++++ kmmsgpartdlg.cpp | 5 +---- messagecomposer.cpp | 7 ++----- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/kmmessage.cpp b/kmmessage.cpp index f4af91d28..8868dea15 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -3220,9 +3220,7 @@ DwBodyPart* KMMessage::createDWBodyPart(const KMMessagePart* aPart) QCString cte = aPart->cteStr(); QCString contDesc = aPart->contentDescriptionEncoded(); QCString contDisp = aPart->contentDisposition(); - QCString encoding = autoDetectCharset(charset, sPrefCharsets, aPart->name()); - if (encoding.isEmpty()) encoding = "utf-8"; - QCString name = KMMsgBase::encodeRFC2231String(aPart->name(), encoding); + QCString name = KMMsgBase::encodeRFC2231StringAutoDetectCharset( aPart->name(), charset ); bool RFC2231encoded = aPart->name() != QString(name); QCString paramAttr = aPart->parameterAttribute(); @@ -3299,12 +3297,8 @@ DwBodyPart* KMMessage::createDWBodyPart(const KMMessagePart* aPart) if (!paramAttr.isEmpty()) { - QCString encoding = autoDetectCharset(charset, sPrefCharsets, - aPart->parameterValue()); - if (encoding.isEmpty()) encoding = "utf-8"; QCString paramValue; - paramValue = KMMsgBase::encodeRFC2231String(aPart->parameterValue(), - encoding); + paramValue = KMMsgBase::encodeRFC2231StringAutoDetectCharset( aPart->parameterValue(), charset ); DwParameter *param = new DwParameter; if (aPart->parameterValue() != QString(paramValue)) { diff --git a/kmmsgbase.cpp b/kmmsgbase.cpp index 00c7e5761..e4ab7a152 100644 --- a/kmmsgbase.cpp +++ b/kmmsgbase.cpp @@ -917,6 +917,16 @@ QCString KMMsgBase::encodeRFC2231String( const QString& _str, return result; } +//----------------------------------------------------------------------------- +QCString KMMsgBase::encodeRFC2231StringAutoDetectCharset( const QString &str, + const QCString &defaultCharset ) +{ + QCString encoding = KMMsgBase::autoDetectCharset( defaultCharset, + KMMessage::preferredCharsets(), str ); + if ( encoding.isEmpty() ) + encoding = "utf-8"; + return KMMsgBase::encodeRFC2231String( str, encoding ); +} //----------------------------------------------------------------------------- QString KMMsgBase::decodeRFC2231String(const QCString& _str) diff --git a/kmmsgbase.h b/kmmsgbase.h index 355666823..ce8e5614f 100644 --- a/kmmsgbase.h +++ b/kmmsgbase.h @@ -353,6 +353,13 @@ public: static QCString encodeRFC2231String(const QString& aStr, const QCString& charset); + /** + * Just like encodeRFC2231String, only that the encoding is auto-detected. + * @param defaultCharset If given, this will be the prefered charset + */ + static QCString encodeRFC2231StringAutoDetectCharset( const QString &str, + const QCString &defaultCharset = "" ); + /** Decode given string as described in RFC2231 */ static QString decodeRFC2231String(const QCString& aStr); /** Extract a given param from the RFC2231-encoded header field, in particular diff --git a/kmmsgpartdlg.cpp b/kmmsgpartdlg.cpp index 63407aeeb..7e2b12230 100644 --- a/kmmsgpartdlg.cpp +++ b/kmmsgpartdlg.cpp @@ -390,10 +390,7 @@ void KMMsgPartDialogCompat::applyChanges() QString name = fileName(); if ( !name.isEmpty() || !mMsgPart->name().isEmpty()) { mMsgPart->setName( name ); - QCString encoding = KMMsgBase::autoDetectCharset( mMsgPart->charset(), - KMMessage::preferredCharsets(), name ); - if ( encoding.isEmpty() ) encoding = "utf-8"; - QCString encName = KMMsgBase::encodeRFC2231String( name, encoding ); + QCString encName = KMMsgBase::encodeRFC2231StringAutoDetectCharset( name, mMsgPart->charset() ); cDisp += "\n\tfilename"; if ( name != QString( encName ) ) diff --git a/messagecomposer.cpp b/messagecomposer.cpp index 17d5841af..485383e71 100644 --- a/messagecomposer.cpp +++ b/messagecomposer.cpp @@ -613,11 +613,8 @@ void MessageComposer::chiasmusEncryptAllAttachments() { part->setTypeStr( "application" ); part->setSubtypeStr( "vnd.de.bund.bsi.chiasmus" ); part->setName( filename + ".xia" ); - // this is taken from kmmsgpartdlg.cpp: - QCString encoding = KMMsgBase::autoDetectCharset( part->charset(), KMMessage::preferredCharsets(), filename ); - if ( encoding.isEmpty() ) - encoding = "utf-8"; - const QCString enc_name = KMMsgBase::encodeRFC2231String( filename + ".xia", encoding ); + const QCString enc_name = KMMsgBase::encodeRFC2231StringAutoDetectCharset( + filename + ".xia", part->charset() ); const QCString cDisp = "attachment;\n\tfilename" + ( QString( enc_name ) != filename + ".xia" ? "*=" + enc_name From 23609328f6466552fc1ac48958eeff7ea44b5a78 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 18:04:53 +0000 Subject: [PATCH 012/160] Always recognize attached messages as attachments, as some clients (Hello Microsoft) don't set the content disposition for this correctly. Part of kolab/issue3978 svn path=/branches/kdepim/enterprise/kdepim/; revision=1055261 --- partNode.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/partNode.cpp b/partNode.cpp index d46b03647..ac924e58d 100644 --- a/partNode.cpp +++ b/partNode.cpp @@ -590,6 +590,13 @@ bool partNode::isAttachment() const if ( !dwPart()->hasHeaders() ) return false; DwHeaders& headers = dwPart()->Headers(); + if ( headers.HasContentType() && + headers.ContentType().Type() == DwMime::kTypeMessage && + headers.ContentType().Subtype() == DwMime::kSubtypeRfc822 ) { + // Messages are always attachments. Normally message attachments created from KMail have a content + // disposition, but some mail clients omit that. + return true; + } if( !headers.HasContentDisposition() ) return false; return ( headers.ContentDisposition().DispositionType() From 02ef26ff1adf2e45698db99cec637862ef6c7333 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 18:05:49 +0000 Subject: [PATCH 013/160] When the attachment has no name, name it "Attachment %1", so that it does not appear empty in the composer. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055262 --- templateparser.cpp | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/templateparser.cpp b/templateparser.cpp index 7e6a4631b..c5798ff8a 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -46,10 +46,13 @@ #include "partNode.h" #include "attachmentcollector.h" #include "objecttreeparser.h" +#include "util.h" #include "templateparser.h" #include +using namespace KMail; + TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, const QString aselection, bool asmartQuote, bool anoQuote, @@ -870,7 +873,7 @@ partNode* TemplateParser::parsedObjectTree() return mOrigRoot; mOrigRoot = partNode::fromMessage( mOrigMsg ); - KMail::ObjectTreeParser otp; // all defaults are ok + ObjectTreeParser otp; // all defaults are ok otp.parseObjectTree( mOrigRoot ); return mOrigRoot; } @@ -888,7 +891,7 @@ void TemplateParser::addProcessedBodyToMessage( const QString &body ) // Get the attachments of the original mail partNode *root = parsedObjectTree(); - KMail::AttachmentCollector ac; + AttachmentCollector ac; ac.collectAttachmentsFrom( root ); // Now, delete the old content and set the new content, which @@ -929,8 +932,9 @@ void TemplateParser::addProcessedBodyToMessage( const QString &body ) mMsg->addDwBodyPart( mMsg->createDWBodyPart( &textPart ) ); mMsg->assembleIfNeeded(); + int attachmentNumber = 1; for ( std::vector::const_iterator it = ac.attachments().begin(); - it != ac.attachments().end(); ++it ) { + it != ac.attachments().end(); ++it, attachmentNumber++ ) { // When adding this body part, make sure to _not_ add the next bodypart // as well, which mimelib would do, therefore creating a mail with many @@ -938,7 +942,25 @@ void TemplateParser::addProcessedBodyToMessage( const QString &body ) // Body::AddBodyPart is very misleading here... ( *it )->dwPart()->SetNext( 0 ); - mMsg->addDwBodyPart( static_cast( ( *it )->dwPart()->Clone() ) ); + DwBodyPart *cloned = static_cast( ( *it )->dwPart()->Clone() ); + + // If the content type has no name or filename parameter, add one, since otherwise the name + // would be empty in the attachment view of the composer, which looks confusing + if ( cloned->Headers().HasContentType() ) { + DwMediaType &ct = cloned->Headers().ContentType(); + + // Converting to a string here, since DwMediaType does not have a HasParameter() function + QString ctStr = ct.AsString().c_str(); + if ( !ctStr.lower().contains( "name=" ) && !ctStr.lower().contains( "filename=" ) ) { + DwParameter *nameParameter = new DwParameter; + nameParameter->SetAttribute( "name" ); + nameParameter->SetValue( Util::dwString( KMMsgBase::encodeRFC2231StringAutoDetectCharset( + i18n( "Attachment %1" ).arg( attachmentNumber ) ) ) ); + ct.AddParameter( nameParameter ); + } + } + + mMsg->addDwBodyPart( cloned ); mMsg->assembleIfNeeded(); } } From 95846952147c3a0530bf1713aaa10f9b5412c0a7 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 18:11:31 +0000 Subject: [PATCH 014/160] Crossport r1013125 by tmcguire from trunk to the enterprise35 branch: Don't add the text of encapsulated messages to the textual content. This fixes a problem that editing a message with an encapsulated message would suddenly show the text of the embedded message in the editor. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055266 --- objecttreeparser.cpp | 15 +++++++++------ objecttreeparser.h | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/objecttreeparser.cpp b/objecttreeparser.cpp index b56f4d0d0..1e66b7c28 100644 --- a/objecttreeparser.cpp +++ b/objecttreeparser.cpp @@ -183,7 +183,7 @@ namespace KMail { void ObjectTreeParser::insertAndParseNewChildNode( partNode& startNode, const char* content, const char* cntDesc, - bool append ) + bool append, bool addToTextualContent ) { DwBodyPart* myBody = new DwBodyPart( DwString( content ), 0 ); myBody->Parse(); @@ -234,10 +234,12 @@ namespace KMail { kdDebug(5006) << "\n -----> Now parsing the MimePartTree\n" << endl; ObjectTreeParser otp( mReader, cryptoProtocol() ); otp.parseObjectTree( newNode ); - mRawReplyString += otp.rawReplyString(); - mTextualContent += otp.textualContent(); - if ( !otp.textualContentCharset().isEmpty() ) - mTextualContentCharset = otp.textualContentCharset(); + if ( addToTextualContent ) { + mRawReplyString += otp.rawReplyString(); + mTextualContent += otp.textualContent(); + if ( !otp.textualContentCharset().isEmpty() ) + mTextualContentCharset = otp.textualContentCharset(); + } kdDebug(5006) << "\n <----- Finished parsing the MimePartTree in insertAndParseNewChildNode()\n" << endl; } @@ -1486,7 +1488,8 @@ namespace KMail { // display the body of the encapsulated message insertAndParseNewChildNode( *node, &*rfc822messageStr, - "encapsulated message" ); + "encapsulated message", false /*append*/, + false /*add to textual content*/ ); node->setDisplayedEmbedded( true ); if ( mReader ) htmlWriter()->queue( writeSigstatFooter( messagePart ) ); diff --git a/objecttreeparser.h b/objecttreeparser.h index e923402d4..e6f7927e1 100644 --- a/objecttreeparser.h +++ b/objecttreeparser.h @@ -172,16 +172,24 @@ namespace KMail { void defaultHandling( partNode * node, ProcessResult & result ); - /** 1. Create a new partNode using 'content' data and Content-Description - found in 'cntDesc'. - 2. Make this node the child of 'node'. - 3. Insert the respective entries in the Mime Tree Viewer. - 3. Parse the 'node' to display the content. */ + /** + * 1. Create a new partNode using 'content' data and Content-Description + * found in 'cntDesc'. + * 2. Make this node the child of 'node'. + * 3. Insert the respective entries in the Mime Tree Viewer. + * 3. Parse the 'node' to display the content. + * + * @param addToTextualContent If true, this will add the textual content of the parsed node + * to the textual content of the current object tree parser. + * Setting this to false is useful for encapsulated messages, as we + * do not want the text in those to appear in the editor + */ // Function will be replaced once KMime is alive. void insertAndParseNewChildNode( partNode & node, const char * content, const char * cntDesc, - bool append=false ); + bool append=false, + bool addToTextualContent = true ); /** if data is 0: Feeds the HTML widget with the contents of the opaque signed data found in partNode 'sign'. From 52d34da039970e20bfefc38290553550987dd1b0 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 19:24:23 +0000 Subject: [PATCH 015/160] Use the nice function I just discovered in Util. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055283 --- archivefolderdialog.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 254d3a073..34be4f488 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -23,6 +23,7 @@ #include "kmfolder.h" #include "kmmainwidget.h" #include "folderrequester.h" +#include "util.h" #include #include @@ -119,14 +120,8 @@ void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) void ArchiveFolderDialog::slotOk() { - if ( QFile::exists( mUrlRequester->url() ) ) { - if ( KMessageBox::questionYesNo( this, i18n( "The specified file already exists. Do you want to overwrite it?" ), - i18n( "File already exists" ), KGuiItem( i18n( "Overwrite" ) ), - KGuiItem( i18n( "Cancel" ) ) ) != KMessageBox::Yes ) { - return; - } - - // TODO: Check if overwriting actually works! + if ( !Util::checkOverwrite( mUrlRequester->url(), this ) ) { + return; } if ( !mFolderRequester->folder() ) { From 5eea24692e7d1555b077f62c3dea1592d021bbee Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 19:52:01 +0000 Subject: [PATCH 016/160] Crossport r1054757 by coles from trunk to the enterprise35 branch: Proof-read the 54 new strings that have just appeared. One use of British rather than US English (cancelled vs canceled) and two plural form errors. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055299 --- backupjob.cpp | 7 ++++--- importjob.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backupjob.cpp b/backupjob.cpp index 4e7481975..620fc6acb 100644 --- a/backupjob.cpp +++ b/backupjob.cpp @@ -120,7 +120,7 @@ bool BackupJob::hasChildren( KMFolder *folder ) const void BackupJob::cancelJob() { - abort( i18n( "The operation was cancelled by the user." ) ); + abort( i18n( "The operation was canceled by the user." ) ); } void BackupJob::abort( const QString &errorMessage ) @@ -173,8 +173,9 @@ void BackupJob::finish() QString text = i18n( "Archiving folder '%1' successfully completed. " "The archive was written to the file '%2'." ) .arg( mRootFolder->name() ).arg( mMailArchivePath.path() ); - text += "\n" + i18n( "%1 messages with the total size of %2 were archived." ) - .arg( mArchivedMessages ).arg( KIO::convertSize( mArchivedSize ) ); + text += "\n" + i18n( "1 message of size %1 was archived.", + "%n messages with the total size of %1 were archived.", mArchivedMessages ) + .arg( KIO::convertSize( mArchivedSize ) ); text += "\n" + i18n( "The archive file has a size of %1." ) .arg( KIO::convertSize( archiveFileInfo.size() ) ); KMessageBox::information( mParentWidget, text, i18n( "Archiving finished." ) ); diff --git a/importjob.cpp b/importjob.cpp index 6a0f46d38..14332834a 100644 --- a/importjob.cpp +++ b/importjob.cpp @@ -79,14 +79,14 @@ void ImportJob::finish() mProgressItem = 0; QString text = i18n( "Importing the archive file '%1' into the folder '%2' succeeded." ) .arg( mArchiveFile.path() ).arg( mRootFolder->name() ); - text += "\n" + i18n( "%1 messages were imported." ).arg( mNumberOfImportedMessages ); + text += "\n" + i18n( "1 message was imported.", "%n messages were imported.", mNumberOfImportedMessages ); KMessageBox::information( mParentWidget, text, i18n( "Import finished." ) ); deleteLater(); } void ImportJob::cancelJob() { - abort( i18n( "The operation was cancelled by the user." ) ); + abort( i18n( "The operation was canceled by the user." ) ); } void ImportJob::abort( const QString &errorMessage ) From a6bc8561012fa5cc1176e98f3d8358fe98617c4b Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 20:26:08 +0000 Subject: [PATCH 017/160] Make copying URLs in the seperate reader window work again. Fixes kolab/issue3958. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055309 --- kmreadermainwin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmreadermainwin.cpp b/kmreadermainwin.cpp index 90f602c49..29524d2c4 100644 --- a/kmreadermainwin.cpp +++ b/kmreadermainwin.cpp @@ -439,7 +439,7 @@ void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoi } mReaderWin->addAddrBookAction()->plug( menu ); mReaderWin->openAddrBookAction()->plug( menu ); - mReaderWin->copyAction()->plug( menu ); + mReaderWin->copyURLAction()->plug( menu ); copyAdded = true; } else { // popup on a not-mailto URL From d7c330c1171d6e47165026007d35d3cc42feace7 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 20:39:30 +0000 Subject: [PATCH 018/160] Also create "cur" and "new" subdirectories, to be more maildir-compilant svn path=/branches/kdepim/enterprise/kdepim/; revision=1055314 --- backupjob.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backupjob.cpp b/backupjob.cpp index 620fc6acb..64f76bd92 100644 --- a/backupjob.cpp +++ b/backupjob.cpp @@ -398,6 +398,10 @@ void BackupJob::archiveNextFolder() success = false; if ( !writeDirHelper( mCurrentFolder->location() + "/cur", mCurrentFolder->location() ) ) success = false; + if ( !writeDirHelper( mCurrentFolder->location() + "/new", mCurrentFolder->location() ) ) + success = false; + if ( !writeDirHelper( mCurrentFolder->location() + "/tmp", mCurrentFolder->location() ) ) + success = false; if ( !success ) { abort( i18n( "Unable to create folder structure for folder '%1' within archive file." ) .arg( mCurrentFolder->name() ) ); From 0ac7013f4b7c535c986764e09d687a47ec5af783 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 27 Nov 2009 21:37:15 +0000 Subject: [PATCH 019/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1055369 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 443f145d5..980d8b60f 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091113.1048596)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091127.1055368)" #endif /*kmversion_h*/ From 807f618fe35a210ce0ad7820be6792ee774e3bf6 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 1 Dec 2009 10:14:23 +0000 Subject: [PATCH 020/160] When replacing the : with a _, remove the following space as well. kolab/issue3805 svn path=/branches/kdepim/enterprise/kdepim/; revision=1056938 --- kmcommands.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kmcommands.cpp b/kmcommands.cpp index d0061c924..fa02b6442 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -759,8 +759,14 @@ KMCommand::Result KMShowMsgSrcCommand::execute() static KURL subjectToUrl( const QString & subject ) { + // We need to replace colons with underscores since those cause problems with KFileDialog (bug + // in KFileDialog though) and also on Windows filesystems. + // We also look at the special case of ": ", since converting that to "_ " would look strange, + // simply "_" looks better. + // https://issues.kolab.org/issue3805 return KFileDialog::getSaveURL( subject.stripWhiteSpace() .replace( QDir::separator(), '_' ) + .replace( ": ", "_" ) .replace( ':', '_' ), "*.mbox" ); } From 7b0842b1e58b13c1059f6c490393b3d2733fcef8 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 1 Dec 2009 10:47:40 +0000 Subject: [PATCH 021/160] Fiddle around with newlines to statisfy kolab/issue3928 svn path=/branches/kdepim/enterprise/kdepim/; revision=1057006 --- kmcomposewin.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 8fdb4ba2b..4b502fdaa 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -4448,6 +4448,17 @@ void KMComposeWin::insertSignature( SignaturePlacement placement, int pos ) mEditor->insertAt( mOldSigText, pos, 0 ); break; case AtCursor: + + // If there is text in the same line, add a newline so that the stuff in + // the current line moves after the signature. Also remove a leading newline, it is not + // needed here. + int index, paragraph; + mEditor->getCursorPosition( ¶graph, &index ); + if ( mEditor->paragraphLength( paragraph ) > 0 ) + mOldSigText = mOldSigText + "\n"; + if ( mOldSigText.startsWith( "\n" ) ) + mOldSigText = mOldSigText.remove( 0, 1 ); + mEditor->insertAt( mOldSigText, pos, 0 ); break; } From 8e73c75f11013710e04de9c98e526ae5ca46cec1 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 1 Dec 2009 13:22:42 +0000 Subject: [PATCH 022/160] Remove a saftey check, archiving a folder without messages is actually valid. svn path=/branches/kdepim/enterprise/kdepim/; revision=1057088 --- backupjob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backupjob.cpp b/backupjob.cpp index 64f76bd92..e43e2fc53 100644 --- a/backupjob.cpp +++ b/backupjob.cpp @@ -182,7 +182,7 @@ void BackupJob::finish() if ( mDeleteFoldersAfterCompletion ) { // Some saftey checks first... - if ( archiveFileInfo.size() > 0 && mArchivedMessages > 0 && mArchivedSize > 0 ) { + if ( archiveFileInfo.size() > 0 && ( mArchivedSize > 0 || mArchivedMessages == 0 ) ) { // Sorry for any data loss! FolderUtil::deleteFolder( mRootFolder, mParentWidget ); } From 42077beb6115635deed56860cd5d9aed9b73c368 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 1 Dec 2009 17:04:35 +0000 Subject: [PATCH 023/160] use an information dialog with a "do-not-ask-again" option instead of an error dialog when notifying the user that the attachment will be un-editable. kolab/issue3971 svn path=/branches/kdepim/enterprise/kdepim/; revision=1057186 --- editorwatcher.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/editorwatcher.cpp b/editorwatcher.cpp index 62e410846..1718b6821 100644 --- a/editorwatcher.cpp +++ b/editorwatcher.cpp @@ -172,10 +172,13 @@ void EditorWatcher::checkEditDone() // nobody can edit that fast, we seem to be unable to detect // when the editor will be closed if ( mEditTime.elapsed() <= 3000 ) { - KMessageBox::error( mParentWidget, - i18n( "KMail is unable to detect when the choosen editor is closed. " - "To avoid data loss, editing the attachment will be aborted." ), - i18n( "Unable to edit attachment" ) ); + KMessageBox::information( + mParentWidget, + i18n( "KMail is unable to detect when the choosen editor is closed. " + "To avoid data loss, editing the attachment will be aborted." ), + i18n( "Unable to edit attachment" ), + "UnableToEditAttachment" ); + } emit editDone( this ); From 5036ca8fc798c2d07c85e6d5466306322be3aa04 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Wed, 2 Dec 2009 14:54:12 +0000 Subject: [PATCH 024/160] add "*.*" to the filter on the "Save As" dialog MERGE: e4,trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1057477 --- kmcommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index fa02b6442..6b7ccc62f 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -768,7 +768,7 @@ static KURL subjectToUrl( const QString & subject ) .replace( QDir::separator(), '_' ) .replace( ": ", "_" ) .replace( ':', '_' ), - "*.mbox" ); + "*.mbox\n*.*" ); } KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) From 69bfae43f6c6d33dfaf27467efffdc57da91c61c Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 4 Dec 2009 11:37:34 +0000 Subject: [PATCH 025/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1058388 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 980d8b60f..bfd2effbb 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091127.1055368)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091204.1058385)" #endif /*kmversion_h*/ From c0d4172145b1ec3fa1a4690fa46c084d31cdaaae Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 11 Dec 2009 17:43:50 +0000 Subject: [PATCH 026/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1061418 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index bfd2effbb..32bf7fc54 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091204.1058385)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091211.1061417)" #endif /*kmversion_h*/ From 10f019ddc194952f4ff19380f37c51dd4c70354b Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Wed, 16 Dec 2009 17:54:49 +0000 Subject: [PATCH 027/160] Make the smart quoting option work again. kolab/issue3934 svn path=/branches/kdepim/enterprise/kdepim/; revision=1063012 --- templateparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templateparser.cpp b/templateparser.cpp index c5798ff8a..47bdb245f 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -864,7 +864,7 @@ QString TemplateParser::messageText( bool allowSelectionOnly ) // No selection text, therefore we need to parse the object tree ourselves to get partNode *root = parsedObjectTree(); - return mOrigMsg->asPlainTextFromObjectTree( root, true, mAllowDecryption ); + return mOrigMsg->asPlainTextFromObjectTree( root, mSmartQuote, mAllowDecryption ); } partNode* TemplateParser::parsedObjectTree() From 3837a34ebcd561b0ee8e0497997795021da2eef5 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 17 Dec 2009 15:19:25 +0000 Subject: [PATCH 028/160] for the saveAs dialog prompt, use "*" instead of "*.*" for the all file filter. also use pretty names. MERGE: e4,trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1063249 --- kmcommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 6b7ccc62f..2dee97323 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -768,7 +768,7 @@ static KURL subjectToUrl( const QString & subject ) .replace( QDir::separator(), '_' ) .replace( ": ", "_" ) .replace( ':', '_' ), - "*.mbox\n*.*" ); + "*.mbox|email messages (*.mbox)\n*|all files (*)" ); } KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) From cee83685468725cb51d9483b161d7f880d21ac62 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 17 Dec 2009 15:26:14 +0000 Subject: [PATCH 029/160] add the word "non-hidden" to the saveAs dialog filter. MERGE: e4,trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1063250 --- kmcommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 2dee97323..dd6da0b70 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -768,7 +768,7 @@ static KURL subjectToUrl( const QString & subject ) .replace( QDir::separator(), '_' ) .replace( ": ", "_" ) .replace( ':', '_' ), - "*.mbox|email messages (*.mbox)\n*|all files (*)" ); + "*.mbox|email messages (*.mbox)\n*|all non-hidden files (*)" ); } KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) From aa588db9028f2da6c5d38750ad0439ab7db52d3f Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 17 Dec 2009 15:47:29 +0000 Subject: [PATCH 030/160] i18n the filter for the saveAs dialog. and don't use the word "non-hidden". MERGE: e4,4.5 (new i18n string) svn path=/branches/kdepim/enterprise/kdepim/; revision=1063257 --- kmcommands.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index dd6da0b70..079b2d2fb 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -764,11 +764,12 @@ static KURL subjectToUrl( const QString & subject ) // We also look at the special case of ": ", since converting that to "_ " would look strange, // simply "_" looks better. // https://issues.kolab.org/issue3805 + QString filter = i18n( "*.mbox|email messages (*.mbox)\n*|all files (*)" ); return KFileDialog::getSaveURL( subject.stripWhiteSpace() .replace( QDir::separator(), '_' ) .replace( ": ", "_" ) - .replace( ':', '_' ), - "*.mbox|email messages (*.mbox)\n*|all non-hidden files (*)" ); + .replace( ':', '_' ), + filter ); } KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) From 8dbae8e8f6c6deee5907ea514f47ec4092bc2f76 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 18 Dec 2009 14:17:27 +0000 Subject: [PATCH 031/160] in prettifyQuotaError, don't assert if the folder for the specified job is 0. simply return instead. this is how it's done in e4 and trunk. kolab/issue4003 MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1063418 --- imapaccountbase.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imapaccountbase.cpp b/imapaccountbase.cpp index c9e2f0a92..6a136f7df 100644 --- a/imapaccountbase.cpp +++ b/imapaccountbase.cpp @@ -895,17 +895,17 @@ namespace KMail { bool readOnly = false; if (it != mapJobData.end()) { const KMFolder * const folder = (*it).parent; - assert(folder); + if( !folder ) return error; const KMFolderCachedImap * const imap = dynamic_cast( folder->storage() ); if ( imap ) { - quotaAsString = imap->quotaInfo().toString(); + quotaAsString = imap->quotaInfo().toString(); } readOnly = folder->isReadOnly(); } error = i18n("The folder is too close to its quota limit. (%1)").arg( quotaAsString ); if ( readOnly ) { error += i18n("\nSince you do not have write privileges on this folder, " - "please ask the owner of the folder to free up some space in it."); + "please ask the owner of the folder to free up some space in it."); } return error; } From d11cac7abb0f98011b0734e0ee4a4f4a9bb8f787 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 18 Dec 2009 14:20:02 +0000 Subject: [PATCH 032/160] in prettifiyQuotaError, return _error instead of error if folder is 0 MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1063421 --- imapaccountbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imapaccountbase.cpp b/imapaccountbase.cpp index 6a136f7df..ccdbd9c93 100644 --- a/imapaccountbase.cpp +++ b/imapaccountbase.cpp @@ -895,7 +895,7 @@ namespace KMail { bool readOnly = false; if (it != mapJobData.end()) { const KMFolder * const folder = (*it).parent; - if( !folder ) return error; + if( !folder ) return _error; const KMFolderCachedImap * const imap = dynamic_cast( folder->storage() ); if ( imap ) { quotaAsString = imap->quotaInfo().toString(); From f0bada1fd754daf036d2a391802118dc723d9962 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 18 Dec 2009 15:40:56 +0000 Subject: [PATCH 033/160] When the subject starts with a dot, change it to an underscore, to avoid hidden files. kolab/issue3805 svn path=/branches/kdepim/enterprise/kdepim/; revision=1063451 --- kmcommands.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 079b2d2fb..94cfd4f6c 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -763,13 +763,18 @@ static KURL subjectToUrl( const QString & subject ) // in KFileDialog though) and also on Windows filesystems. // We also look at the special case of ": ", since converting that to "_ " would look strange, // simply "_" looks better. + // We also don't allow filenames starting with a dot, since then the file is hidden and the poor + // user can't find it anymore. // https://issues.kolab.org/issue3805 - QString filter = i18n( "*.mbox|email messages (*.mbox)\n*|all files (*)" ); - return KFileDialog::getSaveURL( subject.stripWhiteSpace() - .replace( QDir::separator(), '_' ) - .replace( ": ", "_" ) - .replace( ':', '_' ), - filter ); + const QString filter = i18n( "*.mbox|email messages (*.mbox)\n*|all files (*)" ); + QString cleanSubject = subject.stripWhiteSpace() + .replace( QDir::separator(), '_' ) + .replace( ": ", "_" ) + .replace( ':', '_' ); + if ( cleanSubject.startsWith( "." ) ) { + cleanSubject[0] = '_'; + } + return KFileDialog::getSaveURL( cleanSubject, filter ); } KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg ) From b7e755a39b1453a18593772a9cc6cce2247c403d Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 18 Dec 2009 17:39:39 +0000 Subject: [PATCH 034/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1063501 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 32bf7fc54..f2e08c2eb 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091211.1061417)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091218.1063500)" #endif /*kmversion_h*/ From bc0b5692da7372a9931fdfd837912990b3574a48 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Wed, 23 Dec 2009 13:16:00 +0000 Subject: [PATCH 035/160] Fix memory leak: we have to call ungetMsg() after getMsg(). What a noob error... svn path=/branches/kdepim/enterprise/kdepim/; revision=1065510 --- backupjob.cpp | 17 ++++++++++++----- backupjob.h | 5 +++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/backupjob.cpp b/backupjob.cpp index e43e2fc53..d80e11454 100644 --- a/backupjob.cpp +++ b/backupjob.cpp @@ -209,18 +209,20 @@ void BackupJob::archiveNextMessage() mPendingMessages.pop_front(); KMFolder *folder; - int index = -1; - KMMsgDict::instance()->getLocation( serNum, &folder, &index ); - if ( index == -1 ) { + mMessageIndex = -1; + KMMsgDict::instance()->getLocation( serNum, &folder, &mMessageIndex ); + if ( mMessageIndex == -1 ) { kdWarning(5006) << "Failed to get message location for sernum " << serNum << endl; abort( i18n( "Unable to retrieve a message for folder '%1'." ).arg( mCurrentFolder->name() ) ); return; } Q_ASSERT( folder == mCurrentFolder ); - KMMessage *message = mCurrentFolder->getMsg( index ); + const KMMsgBase *base = mCurrentFolder->getMsgBase( mMessageIndex ); + mUnget = base && !base->isMessage(); + KMMessage *message = mCurrentFolder->getMsg( mMessageIndex ); if ( !message ) { - kdWarning(5006) << "Failed to retrieve message with index " << index << endl; + kdWarning(5006) << "Failed to retrieve message with index " << mMessageIndex << endl; abort( i18n( "Unable to retrieve a message for folder '%1'." ).arg( mCurrentFolder->name() ) ); return; } @@ -320,6 +322,11 @@ void BackupJob::processCurrentMessage() return; } + if ( mUnget ) { + Q_ASSERT( mMessageIndex >= 0 ); + mCurrentFolder->unGetMsg( mMessageIndex ); + } + mArchivedMessages++; mArchivedSize += messageSize; } diff --git a/backupjob.h b/backupjob.h index cd5341fc9..931f009b0 100644 --- a/backupjob.h +++ b/backupjob.h @@ -92,6 +92,11 @@ class BackupJob : public QObject bool mAborted; bool mDeleteFoldersAfterCompletion; + // True if we obtained ownership of the kMMessage after calling getMsg(), since we need + // to call ungetMsg() then. For that, we also remember the original index. + bool mUnget; + int mMessageIndex; + QPtrList mPendingFolders; KMFolder *mCurrentFolder; QValueList mPendingMessages; From 9a0675dd6aa4e05e19f279b64302ffefc11717e4 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 29 Dec 2009 15:51:54 +0000 Subject: [PATCH 036/160] Make sure to update the reader window when deleting a attachment, that was not done when using a seperate reader window. svn path=/branches/kdepim/enterprise/kdepim/; revision=1067420 --- kmreaderwin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 9cf059f11..5827e873e 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2659,6 +2659,7 @@ void KMReaderWin::slotDeleteAttachment(partNode * node) if ( msg && nodeId != -1 ) { KMDeleteAttachmentCommand* command = new KMDeleteAttachmentCommand( nodeId, msg, this ); command->start(); + connect( command, SIGNAL(completed( KMCommand * ) ), this, SLOT( updateReaderWin() ) ); } // If we are operating on a copy of parts of the message, make sure to update the copy as well. From 4e321baeb87277bc5d07e869d11244d88b73b6c9 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 29 Dec 2009 17:54:44 +0000 Subject: [PATCH 037/160] Add _very_ nasty hack: After deleting an attachment, automatically select the next message that arrives in the message list, so the 'same' mail stays selected. This is needed because KMDeleteAttachmentCommand does an add+delete. kolab/issue3740 svn path=/branches/kdepim/enterprise/kdepim/; revision=1067503 --- kmreaderwin.cpp | 34 +++++++++++++++++++++++++++++++++- kmreaderwin.h | 6 ++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 5827e873e..39269d50a 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -52,6 +52,7 @@ using KMail::ISubject; using KMail::URLHandlerManager; #include "interfaces/observable.h" #include "util.h" +#include "kmheaders.h" #include "broadcaststatus.h" @@ -2659,7 +2660,19 @@ void KMReaderWin::slotDeleteAttachment(partNode * node) if ( msg && nodeId != -1 ) { KMDeleteAttachmentCommand* command = new KMDeleteAttachmentCommand( nodeId, msg, this ); command->start(); - connect( command, SIGNAL(completed( KMCommand * ) ), this, SLOT( updateReaderWin() ) ); + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SLOT( updateReaderWin() ) ); + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SLOT( disconnectMsgAdded() ) ); + + // ### HACK: Since the command will do delete + add, a new message will arrive. However, we don't + // want the selection to change. Therefore, as soon as a new message arrives, select it, and then + // disconnect. + // Of course the are races, another message can arrive before ours, but we take the risk. + // And it won't work properly with multiple main windows + const KMHeaders * const headers = KMKernel::self()->getKMMainWidget()->headers(); + connect( headers, SIGNAL( msgAddedToListView( QListViewItem* ) ), + this, SLOT( msgAdded( QListViewItem* ) ) ); } // If we are operating on a copy of parts of the message, make sure to update the copy as well. @@ -2669,6 +2682,25 @@ void KMReaderWin::slotDeleteAttachment(partNode * node) } } +void KMReaderWin::msgAdded( QListViewItem *item ) +{ + // A new message was added to the message list view. Select it. + // This is only connected right after we started a attachment delete command, so we expect a new + // message. Disconnect right afterwards, we only want this particular message to be selected. + disconnectMsgAdded(); + KMHeaders * const headers = KMKernel::self()->getKMMainWidget()->headers(); + headers->setCurrentItem( item ); + headers->clearSelection(); + headers->setSelected( item, true ); +} + +void KMReaderWin::disconnectMsgAdded() +{ + const KMHeaders *const headers = KMKernel::self()->getKMMainWidget()->headers(); + disconnect( headers, SIGNAL( msgAddedToListView( QListViewItem* ) ), + this, SLOT( msgAdded( QListViewItem* ) ) ); +} + void KMReaderWin::slotEditAttachment(partNode * node) { if ( KMessageBox::warningContinueCancel( this, diff --git a/kmreaderwin.h b/kmreaderwin.h index 276bc92c6..489fbaa60 100644 --- a/kmreaderwin.h +++ b/kmreaderwin.h @@ -454,6 +454,12 @@ protected slots: void slotDelayedResize(); void slotHandleAttachment( int ); + /** Helper functions used to change message selection in the message list after deleting + * an attachment, see slotDeleteAttachment() + */ + void disconnectMsgAdded(); + void msgAdded( QListViewItem *item ); + protected: /** reimplemented in order to update the frame width in case of a changed GUI style */ From 3244f41873f4dfae16451c9844ac07f699dab3bf Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 1 Jan 2010 17:30:47 +0000 Subject: [PATCH 038/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1068603 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index f2e08c2eb..2a9e10d54 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20091218.1063500)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1068602)" #endif /*kmversion_h*/ From 01a5a9e7d8b912234e71d4f996c35e7756fef914 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 7 Jan 2010 14:29:17 +0000 Subject: [PATCH 039/160] crash guard for the situation when switch the message while the GPG passphrase dialog is shown. backported from trunk for bug 53185 kolab/issue3790 MERGE: e4 (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1071090 --- kmreaderwin.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 39269d50a..36c5850ed 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -1537,6 +1537,11 @@ void KMReaderWin::parseMsg(KMMessage* aMsg) // - this can only be done *after* calling parseObjectTree() KMMsgEncryptionState encryptionState = mRootNode->overallEncryptionState(); KMMsgSignatureState signatureState = mRootNode->overallSignatureState(); + // Don't crash when switching message while GPG passphrase entry dialog is shown #53185 + if (aMsg != message()) { + displayMessage(); + return; + } aMsg->setEncryptionState( encryptionState ); // Don't reset the signature state to "not signed" (e.g. if one canceled the // decryption of a signed messages which has already been decrypted before). From b38cfeedd959bfd54bc69dcf3487400517fc6de0 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 7 Jan 2010 18:45:38 +0000 Subject: [PATCH 040/160] Make .tar.bz2 the default. Part of kolab/issue4014 svn path=/branches/kdepim/enterprise/kdepim/; revision=1071221 --- archivefolderdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 34be4f488..f1be862d5 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -40,7 +40,7 @@ static QString standardArchivePath( const QString &folderName ) { return KGlobalSettings::documentPath() + i18n( "Start of the filename for a mail archive file" , "Archive" ) + "_" + folderName + - "_" + QDate::currentDate().toString( Qt::ISODate ) + ".zip"; + "_" + QDate::currentDate().toString( Qt::ISODate ) + ".tar.bz2"; } ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) @@ -78,7 +78,7 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) mFormatComboBox->insertItem( i18n( "Uncompressed Archive (.tar)" ) ); mFormatComboBox->insertItem( i18n( "BZ2-Compressed Tar Archive (.tar.bz2)" ) ); mFormatComboBox->insertItem( i18n( "GZ-Compressed Tar Archive (.tar.gz)" ) ); - mFormatComboBox->setCurrentItem( 0 ); + mFormatComboBox->setCurrentItem( 2 ); connect( mFormatComboBox, SIGNAL(activated(int)), this, SLOT(slotFixFileExtension()) ); mainLayout->addWidget( mFormatComboBox, row, 1 ); From 78117e1d2aea1a7a5d58d5bf22a996d01861442c Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Fri, 8 Jan 2010 10:34:02 +0000 Subject: [PATCH 041/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1071574 --- kmail.notifyrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmail.notifyrc b/kmail.notifyrc index 72b009063..b5ac1ff41 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -83,6 +83,7 @@ Name[sv]=Fel vid kontroll av post Name[tr]=E-posta Kontrol Edilirken Hata Oluştu Name[uk]=Помилка під час спроби отримання пошти Name[x-test]=xxError While Checking Mailxx +Name[zh_CN]=检查邮件时出错 Name[zh_TW]=檢查郵件時發生錯誤 Comment=There was an error while checking for new mail Comment[ca]=S'ha produït un error en comprovar el coreu nou @@ -106,6 +107,7 @@ Comment[sv]=Ett fel uppstod vid kontroll av ny post Comment[tr]=Yeni e-postalar denetlenirken bir hata oluştu Comment[uk]=Під час спроби перевірки наявності нової пошти сталася помилка Comment[x-test]=xxThere was an error while checking for new mailxx +Comment[zh_CN]=检查新邮件时发生错误 Comment[zh_TW]=檢查郵件時發生錯誤 Action=Popup From ddd219e0802a3e39691e508dbfde5d6e53e8f8ac Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 8 Jan 2010 22:43:05 +0000 Subject: [PATCH 042/160] fix a possible crash in processNewMail when the namespace list for this folder is empty. MERGE: all svn path=/branches/kdepim/enterprise/kdepim/; revision=1071858 --- kmacctcachedimap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmacctcachedimap.cpp b/kmacctcachedimap.cpp index 7fe617f09..7c1ae1a6f 100644 --- a/kmacctcachedimap.cpp +++ b/kmacctcachedimap.cpp @@ -239,7 +239,7 @@ void KMAcctCachedImap::processNewMail( KMFolderCachedImap* folder, mNoopTimer.stop(); // reset namespace todo - if ( folder == mFolder ) { + if ( folder == mFolder && !namespaces().isEmpty() ) { QStringList nsToList = namespaces()[PersonalNS]; QStringList otherNSToCheck = namespaces()[OtherUsersNS]; otherNSToCheck += namespaces()[SharedNS]; From c765f5eef1a5e04066764389c86fb6a1d8472815 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Sat, 9 Jan 2010 13:11:12 +0000 Subject: [PATCH 043/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1072126 --- KMail.desktop | 2 +- kmail_config_accounts.desktop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/KMail.desktop b/KMail.desktop index c254fcd4f..e3780902a 100644 --- a/KMail.desktop +++ b/KMail.desktop @@ -92,7 +92,7 @@ GenericName[fy]=E-portclient GenericName[ga]=Cliant Ríomhphoist GenericName[gl]=Cliente de correo GenericName[he]=לקוח דוא"ל -GenericName[hr]=Program za čitanje elektronske pošte +GenericName[hr]=Program za elektronsku poštu GenericName[hu]=Levelezőprogram GenericName[is]=Póstforrit GenericName[it]=Programma di posta elettronica diff --git a/kmail_config_accounts.desktop b/kmail_config_accounts.desktop index 1031db05c..89a88251f 100644 --- a/kmail_config_accounts.desktop +++ b/kmail_config_accounts.desktop @@ -69,7 +69,7 @@ Name[ta]=கணக்குகள் Name[tg]=Қайдҳои баҳисобгирӣ Name[th]=บัญชีผู้ใช้ Name[tr]=Hesaplar -Name[uk]=Рахунки +Name[uk]=Облікові записи Name[uz]=Hisoblar Name[uz@cyrillic]=Ҳисоблар Name[x-test]=xxAccountsxx From d5e5f93819bb238d7c35ba5fd7dec24c6acfa04a Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Sun, 10 Jan 2010 10:49:55 +0000 Subject: [PATCH 044/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1072537 --- KMail.desktop | 2 ++ application_octetstream.desktop | 2 ++ dbusimap.desktop | 1 + dbusmail.desktop | 1 + kmail.notifyrc | 5 +++++ kmail_config_accounts.desktop | 2 ++ kmail_config_appearance.desktop | 2 ++ kmail_config_composer.desktop | 2 ++ kmail_config_identity.desktop | 2 ++ kmail_config_misc.desktop | 2 ++ kmail_config_security.desktop | 2 ++ kmail_view.desktop | 1 + 12 files changed, 24 insertions(+) diff --git a/KMail.desktop b/KMail.desktop index e3780902a..0580d9841 100644 --- a/KMail.desktop +++ b/KMail.desktop @@ -6,6 +6,7 @@ Name[be]=KMail Name[bg]=KMail Name[br]=KMail Name[ca]=KMail +Name[ca@valencia]=KMail Name[cs]=KMail Name[cy]=KMail Name[da]=KMail @@ -75,6 +76,7 @@ GenericName[be]=Паштовы кліент GenericName[bg]=Пощенски клиент GenericName[br]=Kliant postel GenericName[ca]=Client de correu +GenericName[ca@valencia]=Client de correu GenericName[cs]=Klient pro čtení elektronické pošty GenericName[cy]=Dibynnydd Ebost GenericName[da]=E-mail-klient diff --git a/application_octetstream.desktop b/application_octetstream.desktop index 4d288e3c8..c64a6b313 100644 --- a/application_octetstream.desktop +++ b/application_octetstream.desktop @@ -2,6 +2,7 @@ Name=Application Octet Stream Name[ar]=تطبيق ثماني الدفق Name[ca]=Aplicació Octet Stream +Name[ca@valencia]=Aplicació Byte Stream Name[cs]=Aplikace octetstream Name[da]=Programmet Octet Stream Name[de]=Application Octet Stream @@ -37,6 +38,7 @@ Comment[af]='n Inprop module wat die lyf gedeelte vir 'application/octet-stream' Comment[ar]=ملحق منسق جزء الجسم لتطبيق/دفق ثماني Comment[bg]=Приставка за форматиране на двоични данни Comment[ca]=Un connector formatador del cos per application/octet-stream +Comment[ca@valencia]=Un connector formatador del cos per application/byte-stream Comment[cs]=Modul formátovače těla pro application/octet-stream Comment[da]=Et bodypart formateringsplugin for application/octet-stream Comment[de]=Ein Bodypart-Formatiermodul für application/octet-stream diff --git a/dbusimap.desktop b/dbusimap.desktop index cd8785f8f..d47edcdba 100644 --- a/dbusimap.desktop +++ b/dbusimap.desktop @@ -4,6 +4,7 @@ X-KDE-ServiceType=DBUS/ResourceBackend/IMAP Comment=Mail program with a D-Bus interface Comment[ar]=برنامج البريد بواجهة D-Bus Comment[ca]=Un programa de correu amb una interfície D-Bus +Comment[ca@valencia]=Un programa de correu amb una interfície D-Bus Comment[cs]=Poštvní program s DBUS rozhraním Comment[da]=E-mail-program med en D-BUS-grænseflade Comment[de]=E-Mail-Programm mit D-Bus-Schnittstelle diff --git a/dbusmail.desktop b/dbusmail.desktop index f521ddcba..c8b21841f 100644 --- a/dbusmail.desktop +++ b/dbusmail.desktop @@ -4,6 +4,7 @@ X-KDE-ServiceType=DBUS/Mailer Comment=Mail program with a D-Bus interface Comment[ar]=برنامج البريد بواجهة D-Bus Comment[ca]=Un programa de correu amb una interfície D-Bus +Comment[ca@valencia]=Un programa de correu amb una interfície D-Bus Comment[cs]=Poštvní program s DBUS rozhraním Comment[da]=E-mail-program med en D-BUS-grænseflade Comment[de]=E-Mail-Programm mit D-Bus-Schnittstelle diff --git a/kmail.notifyrc b/kmail.notifyrc index b5ac1ff41..c94cb1dc9 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -6,6 +6,7 @@ Comment[ar]=برنامج البريد KMail Comment[bg]=KMail Comment[br]=KMail Comment[ca]=KMail +Comment[ca@valencia]=KMail Comment[cs]=KMail Comment[cy]=KMail Comment[da]=KMail @@ -63,6 +64,7 @@ Comment[zh_TW]=KMail 郵件軟體 [Event/mail-check-error] Name=Error While Checking Mail Name[ca]=Error en comprovar el correu +Name[ca@valencia]=Error en comprovar el correu Name[da]=Fejl under tjek af e-mail Name[de]=Fehler beim Sehen nach neuen Nachrichten Name[en_GB]=Error While Checking Mail @@ -87,6 +89,7 @@ Name[zh_CN]=检查邮件时出错 Name[zh_TW]=檢查郵件時發生錯誤 Comment=There was an error while checking for new mail Comment[ca]=S'ha produït un error en comprovar el coreu nou +Comment[ca@valencia]=S'ha produït un error en comprovar el coreu nou Comment[da]=Der opstod en fejl under tjek efter nye e-mails Comment[de]=Beim Sehen nach neuen Nachrichten ist ein Fehler aufgetreten Comment[en_GB]=There was an error while checking for new mail @@ -117,6 +120,7 @@ Name[af]=Nuwe pos het gearriveer Name[ar]=وصل بريد جديد Name[br]=Deuet eo ur postel nevez Name[ca]=Ha arribat correu nou +Name[ca@valencia]=Ha arribat correu nou Name[cs]=Přišla nová pošta Name[da]=Ny post ankommet Name[de]=Neue Nachrichten @@ -171,6 +175,7 @@ Comment[af]=Nuwe pos het gearriveer Comment[ar]=وصل بريد جديد Comment[br]=Deuet eo ur postel nevez Comment[ca]=Ha arribat correu nou +Comment[ca@valencia]=Ha arribat correu nou Comment[cs]=Přišla nová pošta Comment[cy]=Cyrhaeddodd ebost newydd Comment[da]=Ny post ankommet diff --git a/kmail_config_accounts.desktop b/kmail_config_accounts.desktop index 89a88251f..04556de70 100644 --- a/kmail_config_accounts.desktop +++ b/kmail_config_accounts.desktop @@ -20,6 +20,7 @@ Name[be]=Рахункі Name[bg]=Сметки Name[br]=Kontoù Name[ca]=Comptes +Name[ca@valencia]=Comptes Name[cs]=Účty Name[cy]=Cyfrifon Name[da]=Konti @@ -80,6 +81,7 @@ Comment[af]=Opstel vir die stuur en ontvang van boodskappe Comment[ar]=تهيئة إرسال و إستقبال الرسائل Comment[bg]=Настройки на мрежата, сървърите и сметките Comment[ca]=Configuració per enviar i rebre missatges +Comment[ca@valencia]=Configuració per enviar i rebre missatges Comment[cs]=Nastavení odesílání a přijímání zpráv Comment[da]=Opsætning til at sende og modtage breve Comment[de]=Einstellungen zum Senden und Empfangen von Nachrichten diff --git a/kmail_config_appearance.desktop b/kmail_config_appearance.desktop index 76debe5c9..984c323a5 100644 --- a/kmail_config_appearance.desktop +++ b/kmail_config_appearance.desktop @@ -20,6 +20,7 @@ Name[be]=Вонкавы выгляд Name[bg]=Външен вид Name[br]=Neuziadur Name[ca]=Aparença +Name[ca@valencia]=Aparença Name[cs]=Vzhled Name[cy]=Golwg Name[da]=Udseende @@ -81,6 +82,7 @@ Comment[af]=Pasmaak die visuele voorkoms Comment[ar]=تخصيص المظهر المرئي Comment[bg]=Настройки на външния вид Comment[ca]=Personalitza l'aparença visual +Comment[ca@valencia]=Personalitza l'aparença visual Comment[cs]=Nastavení vzhledu Comment[cy]=Addasu Golwg Comment[da]=Brugerindstil visuelt udseende diff --git a/kmail_config_composer.desktop b/kmail_config_composer.desktop index ddc89bbd8..9d81e5bc6 100644 --- a/kmail_config_composer.desktop +++ b/kmail_config_composer.desktop @@ -19,6 +19,7 @@ Name[ar]=المؤلف Name[bg]=Редактор Name[br]=Skridaozer Name[ca]=Editor +Name[ca@valencia]=Editor Name[cs]=Editor Name[cy]=Cyfansoddydd Name[da]=Brevskriver @@ -74,6 +75,7 @@ Name[zh_TW]=編寫器 Comment=Message Composer Settings Comment[ar]=إعدادات مؤلف الرسائل Comment[ca]=Arranjament de l'editor de missatges +Comment[ca@valencia]=Arranjament de l'editor de missatges Comment[cs]=Nastavení editoru zpráv Comment[da]=Indstiling af brevskriver Comment[de]=Einstellungen für den E-Mail-Editor diff --git a/kmail_config_identity.desktop b/kmail_config_identity.desktop index 07d55e420..a6fe2e450 100644 --- a/kmail_config_identity.desktop +++ b/kmail_config_identity.desktop @@ -20,6 +20,7 @@ Name[be]=Увасабленні Name[bg]=Самоличност Name[br]=Anvelezhioù Name[ca]=Identitats +Name[ca@valencia]=Identitats Name[cs]=Identity Name[da]=Identiteter Name[de]=Identitäten @@ -81,6 +82,7 @@ Comment[be]=Кіраванне увасабленнямі Comment[bg]=Настройки на самоличността Comment[br]=Merañ an anvelezhioù Comment[ca]=Gestiona les identitats +Comment[ca@valencia]=Gestiona les identitats Comment[cs]=Správa identit Comment[da]=Håndtering af identiteter Comment[de]=Identitäten verwalten diff --git a/kmail_config_misc.desktop b/kmail_config_misc.desktop index c83737562..1853c48fb 100644 --- a/kmail_config_misc.desktop +++ b/kmail_config_misc.desktop @@ -20,6 +20,7 @@ Name[be]=Рознае Name[bg]=Разни Name[br]=A bep seurt Name[ca]=Miscel·lània +Name[ca@valencia]=Miscel·lània Name[cs]=Různé Name[cy]=Amrywiol Name[da]=Diverse @@ -78,6 +79,7 @@ Comment[af]=Opstelling wat nêrens anders pas nie Comment[ar]=الإعدادات التي لا تندرج في أي مكان آخر Comment[bg]=Разни настройки Comment[ca]=Opcions que no van bé enlloc +Comment[ca@valencia]=Opcions que no van bé enlloc Comment[cs]=Nastavení nehodící se jinam Comment[da]=Indstillinger der ikke passer ind andre steder Comment[de]=Verschiedene Einstellungen diff --git a/kmail_config_security.desktop b/kmail_config_security.desktop index 3ca123a0b..f5ab88e88 100644 --- a/kmail_config_security.desktop +++ b/kmail_config_security.desktop @@ -20,6 +20,7 @@ Name[be]=Бяспека Name[bg]=Сигурност Name[br]=Surentez Name[ca]=Seguretat +Name[ca@valencia]=Seguretat Name[cs]=Bezpečnost Name[cy]=Diogelwch Name[da]=Sikkerhed @@ -83,6 +84,7 @@ Comment[be]=Настаўленні бяспекі і прыватнасці Comment[bg]=Настройки на сигурността Comment[br]=Kefluniadur surentez ar buhez prevez Comment[ca]=Arranjament de seguretat i privadesa +Comment[ca@valencia]=Arranjament de seguretat i privadesa Comment[cs]=Nastavení soukromí a zabezpečení Comment[da]=Sikkerheds- & Privathedsindstillinger Comment[de]=Sicherheit und Privatsphäre diff --git a/kmail_view.desktop b/kmail_view.desktop index 01407af28..63c716d29 100644 --- a/kmail_view.desktop +++ b/kmail_view.desktop @@ -2,6 +2,7 @@ Name=KMail view Name[ar]=عرض KMail Name[ca]=Vista del KMail +Name[ca@valencia]=Vista del KMail Name[cs]=KMail pohled Name[da]=KMail-visning Name[de]=KMail-Ansicht From 2a8f47e684c70b5ebc5da685fea2c1de80cad929 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Thu, 14 Jan 2010 17:52:57 +0000 Subject: [PATCH 045/160] Backport: Don't show expire setting when we can't delete message Otherwise it expire in local and re-load it when we connect to server (see bug on my kdab account). svn path=/branches/KDE/4.4/kdepim/; revision=1074756 --- folderview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/folderview.cpp b/folderview.cpp index 781a745bf..9ecbcfbbc 100644 --- a/folderview.cpp +++ b/folderview.cpp @@ -1489,7 +1489,7 @@ void FolderView::fillContextMenuFolderServiceRelatedActions( KMenu *menu, Folder if ( item->folderType() != FolderViewItem::Root ) // non account level folder { menu->addAction( mMainWidget->action( "folder_shortcut_command" ) ); - if ( !folder->noContent() ) + if ( !folder->noContent() && folder->canDeleteMessages()) menu->addAction( i18n("Expire..."), item, SLOT( slotShowExpiryProperties() ) ); // properties From 3f5d57722d452e8b48579daefca7e435e6b35196 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Thu, 14 Jan 2010 18:36:39 +0000 Subject: [PATCH 046/160] Backport: Don't try to remove folder after archive when we can't delete it. (Bug found on my kdab account) svn path=/branches/KDE/4.4/kdepim/; revision=1074774 --- archivefolderdialog.cpp | 9 ++++++++- archivefolderdialog.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 3f9a6f0be..35d9021ec 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -66,6 +66,7 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) mainLayout->addWidget( folderLabel, row, 0 ); mFolderRequester = new FolderRequester( mainWidget ); mFolderRequester->setFolderTree( kmkernel->getKMMainWidget()->mainFolderView() ); + connect( mFolderRequester, SIGNAL( folderChanged( KMFolder* ) ), SLOT( slotFolderChanged( KMFolder* ) ) ); folderLabel->setBuddy( mFolderRequester ); mainLayout->addWidget( mFolderRequester, row, 1 ); row++; @@ -113,11 +114,17 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) resize( 500, minimumSize().height() ); } +void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) +{ + mDeleteCheckBox->setEnabled( folder->canDeleteMessages() ); +} + void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) { mFolderRequester->setFolder( defaultFolder ); // TODO: what if the file already exists? mUrlRequester->setUrl( standardArchivePath( defaultFolder->name() ) ); + mDeleteCheckBox->setEnabled( defaultFolder->canDeleteMessages() ); } void ArchiveFolderDialog::slotButtonClicked( int button ) @@ -143,7 +150,7 @@ void ArchiveFolderDialog::slotButtonClicked( int button ) backupJob->setRootFolder( mFolderRequester->folder() ); backupJob->setSaveLocation( mUrlRequester->url() ); backupJob->setArchiveType( static_cast( mFormatComboBox->currentIndex() ) ); - backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() ); + backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() && mFolderRequester->folder()->canDeleteMessages()); backupJob->start(); accept(); } diff --git a/archivefolderdialog.h b/archivefolderdialog.h index e9aa9bb9f..c38a4c929 100644 --- a/archivefolderdialog.h +++ b/archivefolderdialog.h @@ -42,7 +42,7 @@ class ArchiveFolderDialog : public KDialog protected slots: void slotFixFileExtension(); - + void slotFolderChanged( KMFolder * ); /** reimp */ virtual void slotButtonClicked( int button ); From a1df2243bbbd2288736f257c3e027bc5d99e3d1b Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Thu, 14 Jan 2010 18:41:13 +0000 Subject: [PATCH 047/160] Backport: It's not a problem to select a readonly folder svn path=/branches/KDE/4.4/kdepim/; revision=1074776 --- archivefolderdialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 35d9021ec..c3e372a47 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -65,6 +65,7 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget ); mainLayout->addWidget( folderLabel, row, 0 ); mFolderRequester = new FolderRequester( mainWidget ); + mFolderRequester->setMustBeReadWrite( false ); mFolderRequester->setFolderTree( kmkernel->getKMMainWidget()->mainFolderView() ); connect( mFolderRequester, SIGNAL( folderChanged( KMFolder* ) ), SLOT( slotFolderChanged( KMFolder* ) ) ); folderLabel->setBuddy( mFolderRequester ); From 93a774d0db93be7a8f6b62cdc94ea7ddae1a0460 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Thu, 14 Jan 2010 19:07:22 +0000 Subject: [PATCH 048/160] Backport: Fix crash when url is empty TODO need to merge in akonadi-port svn path=/branches/KDE/4.4/kdepim/; revision=1074788 --- archivefolderdialog.cpp | 6 ++++++ archivefolderdialog.h | 1 + 2 files changed, 7 insertions(+) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index c3e372a47..b7a292455 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -94,6 +94,7 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) mUrlRequester->setMode( KFile::LocalOnly | KFile::File ); mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" ); fileNameLabel->setBuddy( mUrlRequester ); + connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT( slotUrlChanged(const QString&))); connect( mUrlRequester, SIGNAL(urlSelected(const KUrl&)), this, SLOT(slotFixFileExtension()) ); mainLayout->addWidget( mUrlRequester, row, 1 ); @@ -115,6 +116,11 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) resize( 500, minimumSize().height() ); } +void ArchiveFolderDialog::slotUrlChanged( const QString & text) +{ + enableButtonOk( !text.isEmpty() ); +} + void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) { mDeleteCheckBox->setEnabled( folder->canDeleteMessages() ); diff --git a/archivefolderdialog.h b/archivefolderdialog.h index c38a4c929..0862c600f 100644 --- a/archivefolderdialog.h +++ b/archivefolderdialog.h @@ -43,6 +43,7 @@ class ArchiveFolderDialog : public KDialog void slotFixFileExtension(); void slotFolderChanged( KMFolder * ); + void slotUrlChanged( const QString& ); /** reimp */ virtual void slotButtonClicked( int button ); From 7989609bc5a941936aacb901eff88401e4dc5d1f Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 15 Jan 2010 09:55:11 +0000 Subject: [PATCH 049/160] Backport: Don't autorize to move folder when we can't delete message (see on my kdab account) TODO: backport to akonadi-port svn path=/branches/KDE/4.4/kdepim/; revision=1074994 --- mainfolderview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mainfolderview.cpp b/mainfolderview.cpp index 7c6f294f4..20cdc6282 100644 --- a/mainfolderview.cpp +++ b/mainfolderview.cpp @@ -109,7 +109,7 @@ void MainFolderView::fillContextMenuTreeStructureRelatedActions( KMenu *menu, Fo folderToPopupMenu( CopyFolder, this, copyMenu ); // FIXME: if AT LEAST ONE folder is moveable - if ( folder && folder->isMoveable() ) + if ( folder && folder->isMoveable() && folder->canDeleteMessages()) { QMenu *moveMenu = menu->addMenu( KIcon( "go-jump" ), multiSelection ? i18n( "&Move Folders To" ) : From 2903d84e5666dce4f53d227dcb8108d2a1388bd3 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 15 Jan 2010 10:01:54 +0000 Subject: [PATCH 050/160] Backport: Fix enable/disable lineedit TODO need to backport to akonadi-port svn path=/branches/KDE/4.4/kdepim/; revision=1074998 --- vacationdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vacationdialog.cpp b/vacationdialog.cpp index 96712bd0e..05ddd81fb 100644 --- a/vacationdialog.cpp +++ b/vacationdialog.cpp @@ -207,7 +207,7 @@ namespace KMail { /* virtual*/ void KMail::VacationDialog::enableDomainAndSendForSpam( bool enable ) { mDomainCheck->setEnabled( enable ); - mDomainEdit->setEnabled( enable ); + mDomainEdit->setEnabled( enable && mDomainCheck->isChecked() ); mSpamCheck->setEnabled( enable ); } From b90fd226f2a085a20d40dd986a26234a73b1f319 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 15 Jan 2010 10:14:41 +0000 Subject: [PATCH 051/160] Crossport r1074594 by vkrause from trunk to the enterprise35 branch: Fix creation of mbox sub-folders. Not that I particularly like this feature, but I need it to actually create test data for the migration tool... MERGE: E4, 4.4 (not trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075003 --- folderutil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/folderutil.cpp b/folderutil.cpp index 2dbac6fba..4627a5901 100644 --- a/folderutil.cpp +++ b/folderutil.cpp @@ -74,7 +74,7 @@ KMFolder *KMail::FolderUtil::createSubFolder( KMFolder *parentFolder, KMFolderDi } else { // local folder Q_ASSERT( localFolderType == KMFolderTypeMaildir || localFolderType == KMFolderTypeMbox ); - newFolder = kmkernel->folderMgr()->createFolder( folderName, false, KMFolderTypeMaildir, + newFolder = kmkernel->folderMgr()->createFolder( folderName, false, localFolderType, parentDir ); return newFolder; } From 6b646eea7f253cd3b5097a688139b41c05ce6484 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 15 Jan 2010 10:20:52 +0000 Subject: [PATCH 052/160] Backport: Fix default value TODO: NEED TO MERGE IN AKONADI-PORT svn path=/branches/KDE/4.4/kdepim/; revision=1075005 --- vacation.cpp | 1 + vacationdialog.cpp | 8 ++++++++ vacationdialog.h | 3 +++ 3 files changed, 12 insertions(+) diff --git a/vacation.cpp b/vacation.cpp index 89a4593f5..bdc3c6d9a 100644 --- a/vacation.cpp +++ b/vacation.cpp @@ -676,6 +676,7 @@ namespace KMail { mDialog->setMailAliases( defaultMailAliases().join(", ") ); mDialog->setSendForSpam( defaultSendForSpam() ); mDialog->setDomainName( defaultDomainName() ); + mDialog->setDomainCheck( false ); } void Vacation::slotDialogOk() { diff --git a/vacationdialog.cpp b/vacationdialog.cpp index 05ddd81fb..83fcac81a 100644 --- a/vacationdialog.cpp +++ b/vacationdialog.cpp @@ -195,6 +195,14 @@ namespace KMail { } } + bool VacationDialog::domainCheck() const { + return mDomainCheck->isChecked(); + } + + void VacationDialog::setDomainCheck( bool check ) { + mDomainCheck->setChecked( check ); + } + bool VacationDialog::sendForSpam() const { return !mSpamCheck->isChecked(); } diff --git a/vacationdialog.h b/vacationdialog.h index 27e792ec2..632709500 100644 --- a/vacationdialog.h +++ b/vacationdialog.h @@ -46,6 +46,9 @@ namespace KMail { bool activateVacation() const; virtual void setActivateVacation( bool activate ); + bool domainCheck() const; + virtual void setDomainCheck( bool check ); + QString messageText() const; virtual void setMessageText( const QString & text ); From 695bd82cac3a2200dfb8f288a92d2b05f1f3e301 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 15 Jan 2010 13:07:06 +0000 Subject: [PATCH 053/160] Backport: Disable ok button when text is empty. TODO: NEED TO BACKPORT TO AKONADI-PORT svn path=/branches/KDE/4.4/kdepim/; revision=1075051 --- snippetdlg.cpp | 17 ++++++++++++++++- snippetdlg.h | 3 +++ ui/snippetdlgbase.ui | 16 ---------------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/snippetdlg.cpp b/snippetdlg.cpp index 0570f0b51..2c7929497 100644 --- a/snippetdlg.cpp +++ b/snippetdlg.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * snippet feature from kdevelop/plugins/snippet/ * - * * + * * * Copyright (C) 2007 by Robert Gruber * * rgruber@users.sourceforge.net * * * @@ -39,6 +39,9 @@ SnippetDlg::SnippetDlg( KActionCollection* ac, QWidget* parent, bool modal, setModal( modal ); keyWidget->setCheckActionCollections( QList() << ac ); + btnAdd->setEnabled( false ); + connect( snippetName, SIGNAL( textChanged( const QString& ) ), this, SLOT( slotTextChanged( const QString & ) ) ); + connect( snippetName, SIGNAL( returnPressed() ), this, SLOT( slotReturnPressed() ) ); } /* @@ -49,6 +52,18 @@ SnippetDlg::~SnippetDlg() // no need to delete child widgets, Qt does it all for us } +void SnippetDlg::slotTextChanged( const QString & text ) +{ + btnAdd->setEnabled( !text.isEmpty() ); +} + +void SnippetDlg::slotReturnPressed() +{ + if ( !snippetName->text().isEmpty() ) + accept(); +} + + void SnippetDlg::setGroupMode( bool groupMode ) { const bool full = !groupMode; diff --git a/snippetdlg.h b/snippetdlg.h index a4a2ee6fb..ec8a96b63 100644 --- a/snippetdlg.h +++ b/snippetdlg.h @@ -22,6 +22,9 @@ public: void setGroupMode( bool groupMode ); KActionCollection* actionCollection; +protected slots: + void slotTextChanged( const QString& ); + void slotReturnPressed(); }; #endif // SNIPPETDLG_H diff --git a/ui/snippetdlgbase.ui b/ui/snippetdlgbase.ui index 7ec65c112..ac65c4f38 100644 --- a/ui/snippetdlgbase.ui +++ b/ui/snippetdlgbase.ui @@ -213,21 +213,5 @@ - - snippetName - returnPressed() - SnippetDlgBase - accept() - - - 301 - 25 - - - 117 - 340 - - - From 494db09ebf7ce25358212e249a8511b16e91bfd2 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 15 Jan 2010 14:10:56 +0000 Subject: [PATCH 054/160] Keep the filename in the archive file selector. kolab/issue4015 MERGE: none (fixed in kdelibs4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075071 --- archivefolderdialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index f1be862d5..04d9e5899 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,7 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) mUrlRequester = new KURLRequester( mainWidget ); mUrlRequester->setMode( KFile::LocalOnly ); mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" ); + mUrlRequester->fileDialog()->setKeepLocation( true ); fileNameLabel->setBuddy( mUrlRequester ); connect( mUrlRequester, SIGNAL(urlSelected(const QString&)), this, SLOT(slotFixFileExtension()) ); From 9329687319f298accd08a17b77b8ec90b2f3f05e Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 14:35:38 +0000 Subject: [PATCH 055/160] backport SVN commit 1074773 by mlaurent: Don't try to remove folder after archive when we can't delete it. (Bug found on my kdab account) MERGE: e4 (already in akonadi-ports, trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075085 --- archivefolderdialog.cpp | 11 ++++++++++- archivefolderdialog.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 04d9e5899..29686839b 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -65,6 +65,8 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget ); mainLayout->addWidget( folderLabel, row, 0 ); mFolderRequester = new FolderRequester( mainWidget, kmkernel->getKMMainWidget()->folderTree() ); + connect( mFolderRequester, SIGNAL(folderChanged(KMFolder *)), + SLOT(slotFolderChanged(KMFolder *)) ); folderLabel->setBuddy( mFolderRequester ); mainLayout->addWidget( mFolderRequester, row, 1 ); row++; @@ -113,11 +115,17 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) resize( 500, minimumSize().height() ); } +void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) +{ + mDeleteCheckBox->setEnabled( folder->canDeleteMessages() ); +} + void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) { mFolderRequester->setFolder( defaultFolder ); // TODO: what if the file already exists? mUrlRequester->setURL( standardArchivePath( defaultFolder->name() ) ); + mDeleteCheckBox->setEnabled( defaultFolder->canDeleteMessages() ); } void ArchiveFolderDialog::slotOk() @@ -137,7 +145,8 @@ void ArchiveFolderDialog::slotOk() backupJob->setRootFolder( mFolderRequester->folder() ); backupJob->setSaveLocation( mUrlRequester->url() ); backupJob->setArchiveType( static_cast( mFormatComboBox->currentItem() ) ); - backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() ); + backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() && + mFolderRequester->folder()->canDeleteMessages() ); backupJob->start(); accept(); } diff --git a/archivefolderdialog.h b/archivefolderdialog.h index 70a6cd624..dba13dbe6 100644 --- a/archivefolderdialog.h +++ b/archivefolderdialog.h @@ -43,6 +43,8 @@ class ArchiveFolderDialog : public KDialogBase void slotFixFileExtension(); + void slotFolderChanged( KMFolder * ); + /** reimp */ virtual void slotOk(); From c9af9ad3b89be142c84bae9fd43d97e79b8164c5 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 14:40:06 +0000 Subject: [PATCH 056/160] backport SVN commit 1074775 by mlaurent: It's not a problem to select a readonly folder MERGE: e4 (already in akonadi-ports, trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075090 --- archivefolderdialog.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 29686839b..848796f78 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -65,8 +65,9 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget ); mainLayout->addWidget( folderLabel, row, 0 ); mFolderRequester = new FolderRequester( mainWidget, kmkernel->getKMMainWidget()->folderTree() ); - connect( mFolderRequester, SIGNAL(folderChanged(KMFolder *)), - SLOT(slotFolderChanged(KMFolder *)) ); + mFolderRequester->setMustBeReadWrite( false ); + connect( mFolderRequester, SIGNAL(folderChanged(KMFolder *)), + SLOT(slotFolderChanged(KMFolder *)) ); folderLabel->setBuddy( mFolderRequester ); mainLayout->addWidget( mFolderRequester, row, 1 ); row++; From 347fbb26ab1d779b055fc863ff747dc47bf361c6 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 14:48:27 +0000 Subject: [PATCH 057/160] backport SVN commit 1074787 by mlaurent: Fix crash when url is empty MERGE: e4,akonadi-ports (already in trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075095 --- archivefolderdialog.cpp | 7 +++++++ archivefolderdialog.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 848796f78..c8d9be098 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -95,6 +95,8 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" ); mUrlRequester->fileDialog()->setKeepLocation( true ); fileNameLabel->setBuddy( mUrlRequester ); + connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(const QString &)), + SLOT(slotUrlChanged(const QString &)) ); connect( mUrlRequester, SIGNAL(urlSelected(const QString&)), this, SLOT(slotFixFileExtension()) ); mainLayout->addWidget( mUrlRequester, row, 1 ); @@ -116,6 +118,11 @@ ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent ) resize( 500, minimumSize().height() ); } +void ArchiveFolderDialog::slotUrlChanged( const QString &text ) +{ + enableButton( Ok, !text.isEmpty() ); +} + void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) { mDeleteCheckBox->setEnabled( folder->canDeleteMessages() ); diff --git a/archivefolderdialog.h b/archivefolderdialog.h index dba13dbe6..f20a4d157 100644 --- a/archivefolderdialog.h +++ b/archivefolderdialog.h @@ -42,8 +42,8 @@ class ArchiveFolderDialog : public KDialogBase protected slots: void slotFixFileExtension(); - void slotFolderChanged( KMFolder * ); + void slotUrlChanged( const QString & ); /** reimp */ virtual void slotOk(); From aacf7be041d6f56002065a2706519d6b95de87cb Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 14:55:50 +0000 Subject: [PATCH 058/160] backport SVN commit 1074996 by mlaurent: Fix enable/disable lineedit svn path=/branches/kdepim/enterprise/kdepim/; revision=1075098 --- vacationdialog.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/vacationdialog.cpp b/vacationdialog.cpp index 8fc26f9ab..dfc232eb0 100644 --- a/vacationdialog.cpp +++ b/vacationdialog.cpp @@ -182,15 +182,14 @@ namespace KMail { mSpamCheck->setChecked( !enable ); } - /* virtual*/ - void KMail::VacationDialog::enableDomainAndSendForSpam( bool enable ) { - mDomainCheck->setEnabled( enable ); - mDomainEdit->setEnabled( enable ); - mSpamCheck->setEnabled( enable ); + void KMail::VacationDialog::enableDomainAndSendForSpam( bool enable ) + { + mDomainCheck->setEnabled( enable ); + mDomainEdit->setEnabled( enable && mDomainCheck->isChecked() ); + mSpamCheck->setEnabled( enable ); } - } // namespace KMail #include "vacationdialog.moc" From b8f1233388ac28648025c9cc1b88196126841e12 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 15:00:24 +0000 Subject: [PATCH 059/160] backport SVN commit 1075004 by mlaurent: Fix default value MERGE: e4,akonadi-ports (already in trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075106 --- vacation.cpp | 1 + vacationdialog.cpp | 16 ++++++++++++++-- vacationdialog.h | 7 +++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/vacation.cpp b/vacation.cpp index cae691a85..006aae77b 100644 --- a/vacation.cpp +++ b/vacation.cpp @@ -670,6 +670,7 @@ namespace KMail { mDialog->setMailAliases( defaultMailAliases().join(", ") ); mDialog->setSendForSpam( defaultSendForSpam() ); mDialog->setDomainName( defaultDomainName() ); + mDialog->setDomainCheck( false ); } void Vacation::slotDialogOk() { diff --git a/vacationdialog.cpp b/vacationdialog.cpp index dfc232eb0..fb3e072e3 100644 --- a/vacationdialog.cpp +++ b/vacationdialog.cpp @@ -174,11 +174,23 @@ namespace KMail { } } - bool VacationDialog::sendForSpam() const { + bool VacationDialog::domainCheck() const + { + return mDomainCheck->isChecked(); + } + + void VacationDialog::setDomainCheck( bool check ) + { + mDomainCheck->setChecked( check ); + } + + bool VacationDialog::sendForSpam() const + { return !mSpamCheck->isChecked(); } - void VacationDialog::setSendForSpam( bool enable ) { + void VacationDialog::setSendForSpam( bool enable ) + { mSpamCheck->setChecked( !enable ); } diff --git a/vacationdialog.h b/vacationdialog.h index f84ae6a76..b7b8b5228 100644 --- a/vacationdialog.h +++ b/vacationdialog.h @@ -46,6 +46,9 @@ namespace KMail { bool activateVacation() const; virtual void setActivateVacation( bool activate ); + bool domainCheck() const; + virtual void setDomainCheck( bool check ); + QString messageText() const; virtual void setMessageText( const QString & text ); @@ -55,14 +58,14 @@ namespace KMail { KMime::Types::AddrSpecList mailAliases() const; virtual void setMailAliases( const KMime::Types::AddrSpecList & aliases ); virtual void setMailAliases( const QString & aliases ); - + QString domainName() const; virtual void setDomainName( const QString & domain ); bool sendForSpam() const; virtual void setSendForSpam( bool enable ); - + private slots: void slotIntervalSpinChanged( int value ); From 48cf7d7c123adf81bae11981f919467ae4a117b1 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 15 Jan 2010 15:03:35 +0000 Subject: [PATCH 060/160] Crossport r830974 by tmcguire from trunk to the enterprise35 branch: Don't ignore a change in the header style when printing. Patch by Daniel Burrows , thanks and sorry for the delay. MERGE: 4.4 kolab/issue4026 svn path=/branches/kdepim/enterprise/kdepim/; revision=1075109 --- kmcommands.cpp | 14 ++++++++++---- kmcommands.h | 10 ++++++++-- kmmainwidget.cpp | 1 + kmreadermainwin.cpp | 1 + 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 94cfd4f6c..c53e11b84 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1580,10 +1580,14 @@ KMCommand::Result KMCustomForwardCommand::execute() } -KMPrintCommand::KMPrintCommand( QWidget *parent, - KMMessage *msg, bool htmlOverride, bool htmlLoadExtOverride, - bool useFixedFont, const QString & encoding ) - : KMCommand( parent, msg ), mHtmlOverride( htmlOverride ), +KMPrintCommand::KMPrintCommand( QWidget *parent, KMMessage *msg, + const KMail::HeaderStyle *headerStyle, + const KMail::HeaderStrategy *headerStrategy, + bool htmlOverride, bool htmlLoadExtOverride, + bool useFixedFont, const QString & encoding ) + : KMCommand( parent, msg ), + mHeaderStyle( headerStyle ), mHeaderStrategy( headerStrategy ), + mHtmlOverride( htmlOverride ), mHtmlLoadExtOverride( htmlLoadExtOverride ), mUseFixedFont( useFixedFont ), mEncoding( encoding ) { @@ -1601,6 +1605,8 @@ KMCommand::Result KMPrintCommand::execute() KMReaderWin printWin( 0, 0, 0 ); printWin.setPrinting( true ); printWin.readConfig(); + if ( mHeaderStyle != 0 && mHeaderStrategy != 0 ) + printWin.setHeaderStyleAndStrategy( mHeaderStyle, mHeaderStrategy ); printWin.setHtmlOverride( mHtmlOverride ); printWin.setHtmlLoadExtOverride( mHtmlLoadExtOverride ); printWin.setUseFixedFont( mUseFixedFont ); diff --git a/kmcommands.h b/kmcommands.h index caf671087..c82bede0b 100644 --- a/kmcommands.h +++ b/kmcommands.h @@ -39,6 +39,8 @@ namespace KMail { class Composer; class FolderJob; class EditorWatcher; + class HeaderStyle; + class HeaderStrategy; } namespace GpgME { class Error; } namespace Kleo { class SpecialJob; } @@ -601,8 +603,10 @@ class KDE_EXPORT KMPrintCommand : public KMCommand public: KMPrintCommand( QWidget *parent, KMMessage *msg, - bool htmlOverride=false, - bool htmlLoadExtOverride=false, + const KMail::HeaderStyle *headerStyle = 0, + const KMail::HeaderStrategy *headerStrategy = 0, + bool htmlOverride = false, + bool htmlLoadExtOverride = false, bool useFixedFont = false, const QString & encoding = QString() ); @@ -611,6 +615,8 @@ public: private: virtual Result execute(); + const KMail::HeaderStyle *mHeaderStyle; + const KMail::HeaderStrategy *mHeaderStrategy; bool mHtmlOverride; bool mHtmlLoadExtOverride; bool mUseFixedFont; diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index 6f5b66c93..5db088d8c 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -1803,6 +1803,7 @@ void KMMainWidget::slotPrintMsg() : reader.readBoolEntry( "useFixedFont", false ); KMCommand *command = new KMPrintCommand( this, mHeaders->currentMsg(), + mMsgView->headerStyle(), mMsgView->headerStrategy(), htmlOverride, htmlLoadExtOverride, useFixedFont, overrideEncoding() ); command->start(); diff --git a/kmreadermainwin.cpp b/kmreadermainwin.cpp index 29524d2c4..6d41af1cc 100644 --- a/kmreadermainwin.cpp +++ b/kmreadermainwin.cpp @@ -217,6 +217,7 @@ void KMReaderMainWin::slotMarkAll() void KMReaderMainWin::slotPrintMsg() { KMPrintCommand *command = new KMPrintCommand( this, mReaderWin->message(), + mReaderWin->headerStyle(), mReaderWin->headerStrategy(), mReaderWin->htmlOverride(), mReaderWin->htmlLoadExtOverride(), mReaderWin->isFixedFont(), mReaderWin->overrideEncoding() ); command->setOverrideFont( mReaderWin->cssHelper()->bodyFont( mReaderWin->isFixedFont(), true /*printing*/ ) ); From ddad90ff1e709fb486b2455f49a5db1c517cceb7 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 15:09:11 +0000 Subject: [PATCH 061/160] backport SVN commit 1074755 by mlaurent: Don't show expire setting when we can't delete message Otherwise it expire in local and re-load it when we connect to server (see bug on my kdab account). MERGE: e4,akonadi-ports (already in trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075114 --- kmfoldertree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmfoldertree.cpp b/kmfoldertree.cpp index d6f71e461..5602e3b0b 100644 --- a/kmfoldertree.cpp +++ b/kmfoldertree.cpp @@ -1186,7 +1186,7 @@ void KMFolderTree::slotContextMenuRequested( QListViewItem *lvi, fti, SLOT(assignShortcut())); - if ( !fti->folder()->noContent() ) { + if ( !fti->folder()->noContent() && fti->folder()->canDeleteMessages() ) { folderMenu->insertItem( i18n("Expire..."), fti, SLOT( slotShowExpiryProperties() ) ); } From 78c46b76236b13f3377af777296d3247bd1b7cb8 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 15:15:40 +0000 Subject: [PATCH 062/160] backport SVN commit 1074993 by mlaurent: Don't autorize to move folder when we can't delete message (see on my kdab account) MERGE: e4,akonadi-ports (already in trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075119 --- kmfoldertree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmfoldertree.cpp b/kmfoldertree.cpp index 5602e3b0b..ad1eb9f5e 100644 --- a/kmfoldertree.cpp +++ b/kmfoldertree.cpp @@ -1113,7 +1113,7 @@ void KMFolderTree::slotContextMenuRequested( QListViewItem *lvi, folderToPopupMenu( CopyFolder, this, &mMenuToFolder, copyMenu ); folderMenu->insertItem( i18n("&Copy Folder To"), copyMenu ); - if ( fti->folder()->isMoveable() ) + if ( fti->folder()->isMoveable() && fti->folder()->canDeleteMessages() ) { QPopupMenu *moveMenu = new QPopupMenu( folderMenu ); folderToPopupMenu( MoveFolder, this, &mMenuToFolder, moveMenu ); From 36f2d652bf0d0de37e11b647605d6c6bf76dc161 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 15 Jan 2010 15:19:51 +0000 Subject: [PATCH 063/160] Actually use the filename for the file dialog here kolab/issue4029 svn path=/branches/kdepim/enterprise/kdepim/; revision=1075124 --- kmcomposewin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 4b502fdaa..4dda7fce0 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -3525,7 +3525,7 @@ void KMComposeWin::slotAttachSave() pname = msgPart->name(); if (pname.isEmpty()) pname="unnamed"; - KURL url = KFileDialog::getSaveURL(QString::null, QString::null, 0, i18n("Save Attachment As")); + KURL url = KFileDialog::getSaveURL(pname, QString::null, 0, i18n("Save Attachment As")); if( url.isEmpty() ) return; From 02710d796b3661f0f057688f929cc931afca21a5 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 15:41:35 +0000 Subject: [PATCH 064/160] backport SVN commit 1075050 by mlaurent: Disable ok button when text is empty. MERGE: e4,akonadi-ports (already in trunk and 4.4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075139 --- snippetdlg.cpp | 21 ++++++++++++++++++++- snippetdlg.h | 11 ++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/snippetdlg.cpp b/snippetdlg.cpp index b526a08da..accb5322d 100644 --- a/snippetdlg.cpp +++ b/snippetdlg.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * snippet feature from kdevelop/plugins/snippet/ * - * * + * * * Copyright (C) 2007 by Robert Gruber * * rgruber@users.sourceforge.net * * * @@ -14,6 +14,7 @@ #include "snippetdlg.h" #include +#include #include #include @@ -42,6 +43,12 @@ SnippetDlg::SnippetDlg( KActionCollection* ac, QWidget* parent, const char* name connect( keyButton, SIGNAL( capturedShortcut( const KShortcut& ) ), this, SLOT( slotCapturedShortcut( const KShortcut& ) ) ); + btnAdd->setEnabled( false ); + connect( snippetName, SIGNAL(textChanged(const QString &)), + this, SLOT(slotTextChanged(const QString &)) ); + connect( snippetName, SIGNAL(returnPressed()), + this, SLOT(slotReturnPressed()) ); + layout3->addWidget( textLabel3, 7, 0 ); layout3->addWidget( keyButton, 7, 1 ); @@ -105,4 +112,16 @@ void SnippetDlg::setShowShortcut( bool show ) keyButton->setShown( show ); } +void SnippetDlg::slotTextChanged( const QString &text ) +{ + btnAdd->setEnabled( !text.isEmpty() ); +} + +void SnippetDlg::slotReturnPressed() +{ + if ( !snippetName->text().isEmpty() ) { + accept(); + } +} + #include "snippetdlg.moc" diff --git a/snippetdlg.h b/snippetdlg.h index 1a9a1f02f..65803d2ce 100644 --- a/snippetdlg.h +++ b/snippetdlg.h @@ -20,7 +20,7 @@ class SnippetDlg : public SnippetDlgBase { Q_OBJECT -public: + public: SnippetDlg( KActionCollection* ac, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); ~SnippetDlg(); @@ -31,12 +31,13 @@ public: KKeyButton* keyButton; KActionCollection* actionCollection; -private slots: - void slotCapturedShortcut( const KShortcut& ); - -protected slots: + protected slots: + void slotTextChanged( const QString& ); + void slotReturnPressed(); virtual void languageChange(); + private slots: + void slotCapturedShortcut( const KShortcut& ); }; #endif // SNIPPETDLG_H From 479b605a64867cbc85f580cfc6d4e9bb659ec1f9 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 15 Jan 2010 16:10:22 +0000 Subject: [PATCH 065/160] When reading the filename of a part, don't fallback to the message charset. This is wrong, and will especially fail on codecs that don't map their lower 7 bits to ascii, like utf16. kolab/issue4030 MERGE: e4, trunk (?, needs to be tested) svn path=/branches/kdepim/enterprise/kdepim/; revision=1075167 --- kmmsgpart.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmmsgpart.cpp b/kmmsgpart.cpp index efcc20886..3d6004363 100644 --- a/kmmsgpart.cpp +++ b/kmmsgpart.cpp @@ -588,7 +588,7 @@ QString KMMessagePart::fileName(void) const const QCString str = mContentDisposition.mid(startOfFilename, endOfFilename-startOfFilename+1) .stripWhiteSpace(); - return KMMsgBase::decodeRFC2047String(str, charset()); + return KMMsgBase::decodeRFC2047String(str); } return QString::null; From d1808827f74142a4191373d4064edabb5403637c Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 15 Jan 2010 16:12:18 +0000 Subject: [PATCH 066/160] have the snippet tree items pre-opened for ease of use. MERGE: all svn path=/branches/kdepim/enterprise/kdepim/; revision=1075168 --- snippetitem.cpp | 2 ++ snippetwidget.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/snippetitem.cpp b/snippetitem.cpp index efe95e27d..d821a3a5c 100644 --- a/snippetitem.cpp +++ b/snippetitem.cpp @@ -23,6 +23,7 @@ SnippetItem::SnippetItem(QListView * parent, QString name, QString text ) strName = name; strText = text; iParent = -1; + setOpen( true ); } SnippetItem::SnippetItem(QListViewItem * parent, QString name, QString text) @@ -31,6 +32,7 @@ SnippetItem::SnippetItem(QListViewItem * parent, QString name, QString text) strName = name; strText = text; iParent = ((SnippetGroup *)parent)->getId(); + setOpen( true ); } SnippetItem::~SnippetItem() diff --git a/snippetwidget.cpp b/snippetwidget.cpp index 5abcf365e..2990baf75 100644 --- a/snippetwidget.cpp +++ b/snippetwidget.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * snippet feature from kdevelop/plugins/snippet/ * - * * + * * * Copyright (C) 2007 by Robert Gruber * * rgruber@users.sourceforge.net * * * From 4927876aaf4e7227abab49314e0393fc3c5517fd Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 15 Jan 2010 16:21:54 +0000 Subject: [PATCH 067/160] Backport: Enable/disable find/findnext/replace action when we can launch function. MERGE: akonadi-ports svn path=/branches/KDE/4.4/kdepim/; revision=1075179 --- kmcomposewin.cpp | 16 ++++++++++++---- kmcomposewin.h | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index fccf720e9..0db4d959d 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -294,7 +294,7 @@ KMComposeWin::KMComposeWin( KMMessage *aMsg, Composer::TemplateContext context, } mEditor = new KMComposerEditor( this, editorAndCryptoStateIndicators ); - + connect( mEditor, SIGNAL( textChanged() ), this, SLOT( slotEditorTextChanged() ) ); vbox->addLayout( hbox ); vbox->addWidget( mEditor ); mSnippetSplitter->insertWidget( 0, editorAndCryptoStateIndicators ); @@ -437,6 +437,14 @@ QString KMComposeWin::dbusObjectPath() const return mdbusObjectPath; } +void KMComposeWin::slotEditorTextChanged() +{ + const bool textIsNotEmpty = !mEditor->document()->isEmpty(); + mFindText->setEnabled( textIsNotEmpty ); + mFindNextText->setEnabled( textIsNotEmpty ); + mReplaceText->setEnabled( textIsNotEmpty ); +} + //----------------------------------------------------------------------------- void KMComposeWin::send( int how ) { @@ -1196,10 +1204,10 @@ void KMComposeWin::setupActions( void ) KStandardAction::pasteText( this, SLOT(slotPaste()), actionCollection() ); KStandardAction::selectAll( this, SLOT(slotMarkAll()), actionCollection() ); - KStandardAction::find( mEditor, SLOT(slotFind()), actionCollection() ); - KStandardAction::findNext( mEditor, SLOT(slotFindNext()), actionCollection() ); + mFindText = KStandardAction::find( mEditor, SLOT(slotFind()), actionCollection() ); + mFindNextText = KStandardAction::findNext( mEditor, SLOT(slotFindNext()), actionCollection() ); - KStandardAction::replace( mEditor, SLOT(slotReplace()), actionCollection() ); + mReplaceText = KStandardAction::replace( mEditor, SLOT(slotReplace()), actionCollection() ); actionCollection()->addAction( KStandardAction::Spelling, "spellcheck", mEditor, SLOT( checkSpelling() ) ); diff --git a/kmcomposewin.h b/kmcomposewin.h index 50564131e..a048a73d4 100644 --- a/kmcomposewin.h +++ b/kmcomposewin.h @@ -348,6 +348,7 @@ class KMComposeWin : public KMail::Composer void slotEditDone( KMail::EditorWatcher* watcher ); void slotLanguageChanged( const QString &language ); + void slotEditorTextChanged(); public slots: // kmkernel /** Tell the composer to always send the message, even if the user @@ -792,6 +793,8 @@ class KMComposeWin : public KMail::Composer KSelectAction *mEncodingAction; KSelectAction *mCryptoModuleAction; + KAction * mFindText, *mFindNextText, *mReplaceText; + QByteArray mCharset; QByteArray mDefCharset; QStringList mCharsets; From 3dd60e08ec8334465b2c5ed79de6093268778d61 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 15 Jan 2010 17:33:16 +0000 Subject: [PATCH 068/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1075229 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 2a9e10d54..3c646cf09 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1068602)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1075228)" #endif /*kmversion_h*/ From 554e8f9e26b814319bed12c6400614202994e44b Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Sat, 16 Jan 2010 11:51:49 +0000 Subject: [PATCH 069/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1075612 --- kmail.notifyrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmail.notifyrc b/kmail.notifyrc index c94cb1dc9..cb80ec702 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -76,6 +76,7 @@ Name[it]=Errore durante il controllo della posta Name[ja]=メールのチェック中にエラー Name[nb]=Feil under sjekking av e-post Name[nds]=Fehler bi't Kieken na Nettpost +Name[nl]=Fout bij het controleren van e-mail Name[nn]=Feil ved e-postsjekk Name[pt]=Erro na Verificação do Correio Name[pt_BR]=Erro durante a verificação de e-mails @@ -101,6 +102,7 @@ Comment[it]=Si è verificato un errore durante il controllo dei nuovi messaggi d Comment[ja]=新着メールのチェック中にエラーが発生しました Comment[nb]=Det oppsto en feil mens det ble sett etter ny e-post Comment[nds]=Bi't Kieken na nieg Nettpost hett dat en Fehler geven +Comment[nl]=Er was een fout bij het controleren van nieuwe e-mail Comment[nn]=Det oppstod ein feil ved sjekking av ny e-post. Comment[pt]=Ocorreu um erro ao verificar o correio novo Comment[pt_BR]=Ocorreu um erro durante a verificação de novos e-mails From 98bdf41700b316fdbcad3e75e676d7e56ce040bb Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Mon, 18 Jan 2010 10:56:17 +0000 Subject: [PATCH 070/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1076558 --- kmail.notifyrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmail.notifyrc b/kmail.notifyrc index cb80ec702..3e66285fc 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -74,6 +74,7 @@ Name[fr]=Erreur lors de la vérification du courriel Name[gl]=Produciuse un erro ao comprobar o correo Name[it]=Errore durante il controllo della posta Name[ja]=メールのチェック中にエラー +Name[lv]=Kļūda pārbaudot pastu Name[nb]=Feil under sjekking av e-post Name[nds]=Fehler bi't Kieken na Nettpost Name[nl]=Fout bij het controleren van e-mail @@ -100,6 +101,7 @@ Comment[fr]=Il y a eu une erreur lors de la vérification du courriel Comment[gl]=Aconteceu un erro cando se comprobaba o correo novo Comment[it]=Si è verificato un errore durante il controllo dei nuovi messaggi di posta Comment[ja]=新着メールのチェック中にエラーが発生しました +Comment[lv]=Gadījās kļūda pārbaudot ienākošo pastu Comment[nb]=Det oppsto en feil mens det ble sett etter ny e-post Comment[nds]=Bi't Kieken na nieg Nettpost hett dat en Fehler geven Comment[nl]=Er was een fout bij het controleren van nieuwe e-mail From 2f13a9a97f57e4313e77ee2d6bc9124f474c6486 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 19 Jan 2010 00:18:46 +0000 Subject: [PATCH 071/160] Backport r1074594 by vkrause from trunk to the 4.4 branch: Fix creation of mbox sub-folders. Not that I particularly like this feature, but I need it to actually create test data for the migration tool... CCBUG: 223229 MERGE: 4.4 and possibly e35/e4 as well, seems to originate there svn path=/branches/KDE/4.4/kdepim/; revision=1076874 --- folderutil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/folderutil.cpp b/folderutil.cpp index c41864514..7f6e611b2 100644 --- a/folderutil.cpp +++ b/folderutil.cpp @@ -74,7 +74,7 @@ KMFolder *KMail::FolderUtil::createSubFolder( KMFolder *parentFolder, KMFolderDi } else { // local folder Q_ASSERT( localFolderType == KMFolderTypeMaildir || localFolderType == KMFolderTypeMbox ); - newFolder = kmkernel->folderMgr()->createFolder( folderName, false, KMFolderTypeMaildir, + newFolder = kmkernel->folderMgr()->createFolder( folderName, false, localFolderType, parentDir ); return newFolder; } From 289e6db31aa613dbee1a1825692cd68a497278ae Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 19 Jan 2010 09:44:17 +0000 Subject: [PATCH 072/160] Change the dot to a _ everywhere, not just at the start, otherwise it is inconsistent. Part of kolab/issue3805 svn path=/branches/kdepim/enterprise/kdepim/; revision=1076978 --- kmcommands.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index c53e11b84..177a12f25 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -770,10 +770,8 @@ static KURL subjectToUrl( const QString & subject ) QString cleanSubject = subject.stripWhiteSpace() .replace( QDir::separator(), '_' ) .replace( ": ", "_" ) - .replace( ':', '_' ); - if ( cleanSubject.startsWith( "." ) ) { - cleanSubject[0] = '_'; - } + .replace( ':', '_' ) + .replace( '.', '_' ); return KFileDialog::getSaveURL( cleanSubject, filter ); } From 9a4f6a93d7fe9f094dd17b7c2973f39287341c13 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 19 Jan 2010 10:09:45 +0000 Subject: [PATCH 073/160] It is apparently the expected behaviour of KShell::tildeExpand() to expand "~test" to the home dir, so work around that. Fixes kolab/issue3805 svn path=/branches/kdepim/enterprise/kdepim/; revision=1076994 --- kmcommands.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kmcommands.cpp b/kmcommands.cpp index 177a12f25..2ebb37853 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -772,6 +772,9 @@ static KURL subjectToUrl( const QString & subject ) .replace( ": ", "_" ) .replace( ':', '_' ) .replace( '.', '_' ); + if ( cleanSubject.startsWith( "~" ) ) { + cleanSubject[0] = '_'; + } return KFileDialog::getSaveURL( cleanSubject, filter ); } From efe0a4f59224d9a6e0b5d8c4d12978df24cbfc8f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 19 Jan 2010 10:10:27 +0000 Subject: [PATCH 074/160] SVN_SILENT document svn path=/branches/kdepim/enterprise/kdepim/; revision=1076996 --- kmcommands.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmcommands.cpp b/kmcommands.cpp index 2ebb37853..bc917c020 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -765,6 +765,8 @@ static KURL subjectToUrl( const QString & subject ) // simply "_" looks better. // We also don't allow filenames starting with a dot, since then the file is hidden and the poor // user can't find it anymore. + // Don't allow filenames starting with a tilde either, since that will cause the file dialog to + // discard the filename entirely. // https://issues.kolab.org/issue3805 const QString filter = i18n( "*.mbox|email messages (*.mbox)\n*|all files (*)" ); QString cleanSubject = subject.stripWhiteSpace() From a0161d6ae3e3957e7d5f19d99387a5c9eb183d10 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 19 Jan 2010 10:13:15 +0000 Subject: [PATCH 075/160] I can already hear the complaints of inconsistency, so better replace all tildes... svn path=/branches/kdepim/enterprise/kdepim/; revision=1076998 --- kmcommands.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index bc917c020..83f189fc4 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -773,10 +773,8 @@ static KURL subjectToUrl( const QString & subject ) .replace( QDir::separator(), '_' ) .replace( ": ", "_" ) .replace( ':', '_' ) - .replace( '.', '_' ); - if ( cleanSubject.startsWith( "~" ) ) { - cleanSubject[0] = '_'; - } + .replace( '.', '_' ) + .replace( '~', '_' ); return KFileDialog::getSaveURL( cleanSubject, filter ); } From f8c808f2b32924b6a561387d79a427e9f2d45881 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Wed, 20 Jan 2010 11:33:29 +0000 Subject: [PATCH 076/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1077558 --- dbusimap.desktop | 1 + dbusmail.desktop | 1 + kmail.notifyrc | 2 ++ kmail_config_misc.desktop | 1 + 4 files changed, 5 insertions(+) diff --git a/dbusimap.desktop b/dbusimap.desktop index d47edcdba..8b7689a26 100644 --- a/dbusimap.desktop +++ b/dbusimap.desktop @@ -24,6 +24,7 @@ Comment[nb]=E-postprogram med D-Bus-grensesnitt Comment[nds]=Nettpostprogramm mit en D-Bus-Koppelsteed Comment[nl]=E-mailprogramma met een D-Bus-interface Comment[nn]=E-postprogram med eit D-Bus-grensesnitt +Comment[pa]=ਇੱਕ ਡੀਬੱਸ ਇੰਟਰਫੇਸ ਨਾਲ ਮੇਲ ਪਰੋਗਰਾਮ Comment[pl]=Program pocztowy z interfejsem D-Bus Comment[pt]=Um programa de correio electrónico com uma interface D-Bus Comment[pt_BR]=Programa de e-mail com interface D-Bus diff --git a/dbusmail.desktop b/dbusmail.desktop index c8b21841f..632078077 100644 --- a/dbusmail.desktop +++ b/dbusmail.desktop @@ -24,6 +24,7 @@ Comment[nb]=E-postprogram med D-Bus-grensesnitt Comment[nds]=Nettpostprogramm mit en D-Bus-Koppelsteed Comment[nl]=E-mailprogramma met een D-Bus-interface Comment[nn]=E-postprogram med eit D-Bus-grensesnitt +Comment[pa]=ਇੱਕ ਡੀਬੱਸ ਇੰਟਰਫੇਸ ਨਾਲ ਮੇਲ ਪਰੋਗਰਾਮ Comment[pl]=Program pocztowy z interfejsem D-Bus Comment[pt]=Um programa de correio electrónico com uma interface D-Bus Comment[pt_BR]=Programa de e-mail com interface D-Bus diff --git a/kmail.notifyrc b/kmail.notifyrc index 3e66285fc..0cbc43130 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -79,6 +79,7 @@ Name[nb]=Feil under sjekking av e-post Name[nds]=Fehler bi't Kieken na Nettpost Name[nl]=Fout bij het controleren van e-mail Name[nn]=Feil ved e-postsjekk +Name[pa]=ਮੇਲ ਚੈੱਕ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ Name[pt]=Erro na Verificação do Correio Name[pt_BR]=Erro durante a verificação de e-mails Name[ro]=Eroare la verificarea poștei @@ -106,6 +107,7 @@ Comment[nb]=Det oppsto en feil mens det ble sett etter ny e-post Comment[nds]=Bi't Kieken na nieg Nettpost hett dat en Fehler geven Comment[nl]=Er was een fout bij het controleren van nieuwe e-mail Comment[nn]=Det oppstod ein feil ved sjekking av ny e-post. +Comment[pa]=ਨਵੀਂ ਮੇਲ ਚੈੱਕ ਕਰਨ ਦੇ ਦੌਰਾਨ ਗਲਤੀ ਆਈ ਹੈ Comment[pt]=Ocorreu um erro ao verificar o correio novo Comment[pt_BR]=Ocorreu um erro durante a verificação de novos e-mails Comment[ro]=A avut loc o eroare la verificarea pentru mesaje noi diff --git a/kmail_config_misc.desktop b/kmail_config_misc.desktop index 1853c48fb..7fb63159b 100644 --- a/kmail_config_misc.desktop +++ b/kmail_config_misc.desktop @@ -113,6 +113,7 @@ Comment[nds]=Verscheden Instellen Comment[ne]=कतै पनि नमिल्ने सेटिङ Comment[nl]=Instellingen die nergens echt passen Comment[nn]=Innstillingar som ikkje passar andre stader +Comment[pa]=ਸੈਟਿੰਗ, ਜੋ ਹੋਰ ਕਿਤੇ ਫਿੱਟ ਨਾ ਆਵੇ Comment[pl]=Ustawienia, które nie pasują gdzie indziej Comment[pt]=Outras configurações Comment[pt_BR]=Preferências que não se encaixam em outros lugares From 67eac675eccc764c1f7d9c606fa826cf68708309 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Wed, 20 Jan 2010 13:03:10 +0000 Subject: [PATCH 077/160] Handle malformed multiline headers correctly in this branch as well. http://reviewboard.kde.org/r/2644/ CCBUG: 86302 svn path=/branches/KDE/4.4/kdepim/; revision=1077597 --- kmfoldermaildir.cpp | 8 ++++++++ kmfoldermbox.cpp | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/kmfoldermaildir.cpp b/kmfoldermaildir.cpp index 5f7b40b2d..6ddba3bf9 100644 --- a/kmfoldermaildir.cpp +++ b/kmfoldermaildir.cpp @@ -723,6 +723,14 @@ void KMFolderMaildir::readFileHeaderIntern( const QString& dir, if (lastStr) *lastStr += line + i; } + else if ( inHeader && line[0] == '=' && + ( ( line[1] == '0' && line[2] == '9' ) || + ( line[1] == '2' && line[2] == '0' ) ) ) + { + // bug 86302 - workaround for malformed wrapped encoded-words + if (lastStr) + *lastStr += line + 3; + } else lastStr = 0; diff --git a/kmfoldermbox.cpp b/kmfoldermbox.cpp index 81365929d..b83c3ac29 100644 --- a/kmfoldermbox.cpp +++ b/kmfoldermbox.cpp @@ -793,6 +793,14 @@ int KMFolderMbox::createIndexFromContents() if (line [i] < ' ' && line [i]>0) inHeader = false; else if (lastStr) *lastStr += line + i; } + else if ( inHeader && line[0] == '=' && + ( ( line[1] == '0' && line[2] == '9' ) || + ( line[1] == '2' && line[2] == '0' ) ) ) + { + // bug 86302 - workaround for malformed wrapped encoded-words + if (lastStr) + *lastStr += line + 3; + } else lastStr = 0; if (inHeader && (line [0]=='\n' || line [0]=='\r')) From 71472375b529e7c96c05982433363a5968be1458 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 21 Jan 2010 15:13:45 +0000 Subject: [PATCH 078/160] Focus the Ok button by default in the POP filter dialog. Patch by Michael Gorven , thank you. http://reviewboard.kde.org/r/2663 svn path=/branches/KDE/4.4/kdepim/; revision=1078107 --- kmpopfiltercnfrmdlg.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/kmpopfiltercnfrmdlg.cpp b/kmpopfiltercnfrmdlg.cpp index 68577d7c9..d039d0922 100644 --- a/kmpopfiltercnfrmdlg.cpp +++ b/kmpopfiltercnfrmdlg.cpp @@ -294,6 +294,7 @@ KMPopFilterCnfrmDlg::KMPopFilterCnfrmDlg( const QList & headers, setUpdatesEnabled( false ); setCaption( i18nc("@title:window", "POP Filter") ); setButtons( Ok | Help | Cancel ); + setButtonFocus( Ok ); setHelp( "popfilters" ); unsigned int rulesetCount = 0; mShowLaterMsgs = showLaterMsgs; From bd25047023b99c543bf393393a08e5746f2ad734 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 22 Jan 2010 08:54:07 +0000 Subject: [PATCH 079/160] Fix crash when we select an nul folder (LocalFolder) and don't select folder which can't have content (as top level in imap account) MERGE: in trunk/e4/e5 and other if necessary (don't know) svn path=/branches/KDE/4.4/kdepim/; revision=1078375 --- archivefolderdialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index b7a292455..d89f2971a 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -123,7 +123,8 @@ void ArchiveFolderDialog::slotUrlChanged( const QString & text) void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) { - mDeleteCheckBox->setEnabled( folder->canDeleteMessages() ); + mDeleteCheckBox->setEnabled( folder && folder->canDeleteMessages() && !folder->noContent()); + enableButtonOk( folder && !folder->noContent()); } void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) From 77da0721eefd86426a844aaac668167b539f7cbd Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 22 Jan 2010 09:02:39 +0000 Subject: [PATCH 080/160] Remove this todo (done) svn path=/branches/KDE/4.4/kdepim/; revision=1078380 --- archivefolderdialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index d89f2971a..f72bdd802 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -153,7 +153,6 @@ void ArchiveFolderDialog::slotButtonClicked( int button ) return; } - // TODO: check if url is empty. or better yet, disable ok button until file is chosen KMail::BackupJob *backupJob = new KMail::BackupJob( mParentWidget ); backupJob->setRootFolder( mFolderRequester->folder() ); backupJob->setSaveLocation( mUrlRequester->url() ); From 29226929d85fe5956eca4f8e9c866ef604920178 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Fri, 22 Jan 2010 09:15:52 +0000 Subject: [PATCH 081/160] Readd standardArchivePath when url is empty and we change type of archive (avoid to create file as .tar.gz etc.) MERGE: e4/e5/trunk and other if necessary svn path=/branches/KDE/4.4/kdepim/; revision=1078389 --- archivefolderdialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index f72bdd802..09d585d84 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -175,6 +175,8 @@ void ArchiveFolderDialog::slotFixFileExtension() const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" }; QString fileName = mUrlRequester->url().path(); + if ( fileName.isEmpty() ) + fileName = standardArchivePath( mFolderRequester->folder() ? mFolderRequester->folder()->name() : "" ); // First, try to find the extension of the file name and remove it for( int i = 0; i < numExtensions; i++ ) { From 0a339fb93fde3111766e0e3ea04b5eddc68811d1 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 22 Jan 2010 14:14:11 +0000 Subject: [PATCH 082/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1078634 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 3c646cf09..c5389178c 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1075228)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1078631)" #endif /*kmversion_h*/ From 13add93e07a7921c167b1637cf46362718875bc4 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Sat, 23 Jan 2010 10:55:16 +0000 Subject: [PATCH 083/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1078968 --- kmail.notifyrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmail.notifyrc b/kmail.notifyrc index 0cbc43130..ffcb5387b 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -142,6 +142,7 @@ Name[fy]=Nije berjochten oankaam Name[ga]=Tháinig Ríomhphost Nua Name[gl]=Hai correo novo Name[he]=דוא"ל חדש הגיע +Name[hr]=Stigla je nova pošta Name[hu]=Új levél érkezett Name[is]=Nýr póstur Name[it]=Nuova posta ricevuta @@ -198,6 +199,7 @@ Comment[fy]=Nij berjocht oankaam Comment[ga]=Tháinig ríomhphost nua Comment[gl]=Hai correo novo Comment[he]=דוא"ל חדש הגיע +Comment[hr]=Stigla je nova pošta Comment[hu]=Új levél érkezett Comment[is]=Nýr póstur Comment[it]=Nuova posta ricevuta From eb387fbcaf40e75a0c4e0391092bcd8671723596 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Sat, 23 Jan 2010 10:56:11 +0000 Subject: [PATCH 084/160] Add warning when we select same folder as current. Can't add a kmessagebox because there is string freeze. Will backport to trunk svn path=/branches/KDE/4.4/kdepim/; revision=1078972 --- expirypropertiesdialog.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/expirypropertiesdialog.cpp b/expirypropertiesdialog.cpp index 3313b99b2..74c5b099d 100644 --- a/expirypropertiesdialog.cpp +++ b/expirypropertiesdialog.cpp @@ -158,11 +158,22 @@ ExpiryPropertiesDialog::~ExpiryPropertiesDialog() void ExpiryPropertiesDialog::accept() { bool enableGlobally = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked(); - if ( enableGlobally && moveToRB->isChecked() && !folderSelector->folder() ) { + KMFolder* expireToFolder = folderSelector->folder(); + if ( enableGlobally && moveToRB->isChecked() && !expireToFolder ) { KMessageBox::error( this, i18n("Please select a folder to expire messages into."), i18n( "No Folder Selected" ) ); return; } + if ( expireToFolder ) + { + if ( expireToFolder->idString() == mFolder->idString() ) + { + kWarning()<<" You selected same folder as current ! Select an other one please"; + return; + } + else + mFolder->setExpireToFolderId( expireToFolder->idString() ); + } mFolder->setAutoExpire( enableGlobally ); // we always write out days now @@ -175,10 +186,6 @@ void ExpiryPropertiesDialog::accept() 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*/); From e90386d018e2f1dc06f3d7d0b032303d21ccb1b4 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Mon, 25 Jan 2010 10:39:51 +0000 Subject: [PATCH 085/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1079970 --- kmail.notifyrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmail.notifyrc b/kmail.notifyrc index ffcb5387b..26bb98dd7 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -80,6 +80,7 @@ Name[nds]=Fehler bi't Kieken na Nettpost Name[nl]=Fout bij het controleren van e-mail Name[nn]=Feil ved e-postsjekk Name[pa]=ਮੇਲ ਚੈੱਕ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ +Name[pl]=Błąd podczas sprawdzania poczty Name[pt]=Erro na Verificação do Correio Name[pt_BR]=Erro durante a verificação de e-mails Name[ro]=Eroare la verificarea poștei @@ -108,6 +109,7 @@ Comment[nds]=Bi't Kieken na nieg Nettpost hett dat en Fehler geven Comment[nl]=Er was een fout bij het controleren van nieuwe e-mail Comment[nn]=Det oppstod ein feil ved sjekking av ny e-post. Comment[pa]=ਨਵੀਂ ਮੇਲ ਚੈੱਕ ਕਰਨ ਦੇ ਦੌਰਾਨ ਗਲਤੀ ਆਈ ਹੈ +Comment[pl]=Podczas sprawdzania poczty wystąpił błąd Comment[pt]=Ocorreu um erro ao verificar o correio novo Comment[pt_BR]=Ocorreu um erro durante a verificação de novos e-mails Comment[ro]=A avut loc o eroare la verificarea pentru mesaje noi From 1aab326969389231ab55a49aa9124deb2adc7e73 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Tue, 26 Jan 2010 08:33:30 +0000 Subject: [PATCH 086/160] Don't allow to delete system folder (see on my kdab account) svn path=/branches/KDE/4.4/kdepim/; revision=1080353 --- archivefolderdialog.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 09d585d84..765deee6e 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -121,9 +121,14 @@ void ArchiveFolderDialog::slotUrlChanged( const QString & text) enableButtonOk( !text.isEmpty() ); } +bool canRemoveFolder( KMFolder *folder ) +{ + return folder && folder->canDeleteMessages() && !folder->noContent() && !folder->isSystemFolder(); +} + void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) { - mDeleteCheckBox->setEnabled( folder && folder->canDeleteMessages() && !folder->noContent()); + mDeleteCheckBox->setEnabled( canRemoveFolder( folder )); enableButtonOk( folder && !folder->noContent()); } @@ -132,7 +137,7 @@ void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) mFolderRequester->setFolder( defaultFolder ); // TODO: what if the file already exists? mUrlRequester->setUrl( standardArchivePath( defaultFolder->name() ) ); - mDeleteCheckBox->setEnabled( defaultFolder->canDeleteMessages() ); + mDeleteCheckBox->setEnabled( canRemoveFolder( defaultFolder ) ); } void ArchiveFolderDialog::slotButtonClicked( int button ) @@ -157,7 +162,7 @@ void ArchiveFolderDialog::slotButtonClicked( int button ) backupJob->setRootFolder( mFolderRequester->folder() ); backupJob->setSaveLocation( mUrlRequester->url() ); backupJob->setArchiveType( static_cast( mFormatComboBox->currentIndex() ) ); - backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() && mFolderRequester->folder()->canDeleteMessages()); + backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isEnabled() && mDeleteCheckBox->isChecked() ); backupJob->start(); accept(); } From c909199ceea6f52f808b9280115bef14240aa048 Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Tue, 26 Jan 2010 08:44:38 +0000 Subject: [PATCH 087/160] Don't autorize to delete a folder which has not content svn path=/branches/KDE/4.4/kdepim/; revision=1080359 --- kmmainwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index d1c517516..1258b79d1 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -4403,7 +4403,7 @@ void KMMainWidget::updateFolderMenu() mEmptyFolderAction->setEnabled( folderWithContent && ( mFolder->count() > 0 ) && mFolder->canDeleteMessages() && !multiFolder ); mEmptyFolderAction->setText( (mFolder && kmkernel->folderIsTrash(mFolder)) ? i18n("E&mpty Trash") : i18n("&Move All Messages to Trash") ); - mRemoveFolderAction->setEnabled( mFolder && !mFolder->isSystemFolder() && mFolder->canDeleteMessages() && !multiFolder); + mRemoveFolderAction->setEnabled( mFolder && !mFolder->isSystemFolder() && mFolder->canDeleteMessages() && !multiFolder && !mFolder->noContent()); mRemoveFolderAction->setText( mFolder && mFolder->folderType() == KMFolderTypeSearch ? i18n("&Delete Search") : i18n("&Delete Folder") ); if ( mArchiveFolderAction ) mArchiveFolderAction->setEnabled( mFolder && !multiFolder ); From 6e2def8a4ff2a2d1eebc1a7e25b92ed80a4919d5 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 26 Jan 2010 10:53:31 +0000 Subject: [PATCH 088/160] Move function implementation to the cpp file. svn path=/branches/kdepim/enterprise/kdepim/; revision=1080482 --- messageactions.cpp | 10 ++++++++++ messageactions.h | 9 +-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/messageactions.cpp b/messageactions.cpp index 846b9ae7f..c09e649f4 100644 --- a/messageactions.cpp +++ b/messageactions.cpp @@ -168,6 +168,16 @@ void MessageActions::updateActions() mEditAction->setEnabled( singleMsg ); } +template void MessageActions::replyCommand() +{ + if ( !mCurrentMessage ) + return; + const QString text = mMessageView ? mMessageView->copyText() : ""; + KMCommand *command = new T( mParent, mCurrentMessage, text ); + command->start(); +} + + void MessageActions::slotCreateTodo() { if ( !mCurrentMessage ) diff --git a/messageactions.h b/messageactions.h index 6761a0667..07f32c247 100644 --- a/messageactions.h +++ b/messageactions.h @@ -60,14 +60,7 @@ class MessageActions : public QObject private: void updateActions(); - template void replyCommand() - { - if ( !mCurrentMessage ) - return; - const QString text = mMessageView ? mMessageView->copyText() : ""; - KMCommand *command = new T( mParent, mCurrentMessage, text ); - command->start(); - } + template void replyCommand(); void setMessageStatus( KMMsgStatus status, bool toggle = false ); private slots: From 7a2c8ac6e11cc7acc3a33a948de1575a63611be0 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 26 Jan 2010 10:54:50 +0000 Subject: [PATCH 089/160] Fix API doc svn path=/branches/kdepim/enterprise/kdepim/; revision=1080485 --- kmcommands.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kmcommands.h b/kmcommands.h index c82bede0b..b3a18e419 100644 --- a/kmcommands.h +++ b/kmcommands.h @@ -85,9 +85,11 @@ public slots: void slotProgress( unsigned long done, unsigned long total ); signals: + + /// @param result The status of the command. void messagesTransfered( KMCommand::Result result ); - /** Emitted when the command has completed. - * @param result The status of the command. */ + + /// Emitted when the command has completed. void completed( KMCommand *command ); protected: From f3de41974afd2dacbc78a14ce43b50afdc5e288f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 26 Jan 2010 11:07:50 +0000 Subject: [PATCH 090/160] Call a slot when a reply/foward is done in the seperate reader. Doesn't do anything meaningful yet. svn path=/branches/kdepim/enterprise/kdepim/; revision=1080495 --- kmreadermainwin.cpp | 16 ++++++++++++++++ kmreadermainwin.h | 4 ++++ messageactions.cpp | 2 ++ messageactions.h | 8 ++++++++ 4 files changed, 30 insertions(+) diff --git a/kmreadermainwin.cpp b/kmreadermainwin.cpp index 6d41af1cc..040624efc 100644 --- a/kmreadermainwin.cpp +++ b/kmreadermainwin.cpp @@ -168,6 +168,11 @@ void KMReaderMainWin::slotFolderRemoved( QObject* folderPtr ) mMsg->setParent( 0 ); } +void KMReaderMainWin::slotReplyOrForwardFinished() +{ + kdDebug(5006) << "Reply or forward done!" << endl; +} + //----------------------------------------------------------------------------- void KMReaderMainWin::slotTrashMsg() { @@ -234,6 +239,8 @@ void KMReaderMainWin::slotForwardInlineMsg() } else { command = new KMForwardInlineCommand( this, mReaderWin->message() ); } + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SLOT( slotReplyOrForwardFinished() ) ); command->start(); } @@ -247,6 +254,8 @@ void KMReaderMainWin::slotForwardAttachedMsg() } else { command = new KMForwardAttachedCommand( this, mReaderWin->message() ); } + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SLOT( slotReplyOrForwardFinished() ) ); command->start(); } @@ -260,6 +269,8 @@ void KMReaderMainWin::slotForwardDigestMsg() } else { command = new KMForwardDigestCommand( this, mReaderWin->message() ); } + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SLOT( slotReplyOrForwardFinished() ) ); command->start(); } @@ -267,6 +278,8 @@ void KMReaderMainWin::slotForwardDigestMsg() void KMReaderMainWin::slotRedirectMsg() { KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() ); + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SLOT( slotReplyOrForwardFinished() ) ); command->start(); } @@ -321,6 +334,9 @@ void KMReaderMainWin::setupAccel() mMsgActions = new KMail::MessageActions( actionCollection(), this ); mMsgActions->setMessageView( mReaderWin ); + connect( mMsgActions, SIGNAL( replyActionFinished() ), + this, SLOT( slotReplyOrForwardFinished() ) ); + //----- File Menu //mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ), // actionCollection() ); diff --git a/kmreadermainwin.h b/kmreadermainwin.h index ba0f925d4..f7302430f 100644 --- a/kmreadermainwin.h +++ b/kmreadermainwin.h @@ -78,6 +78,10 @@ private slots: void slotFolderRemoved( QObject* folderPtr ); + /// This closes the window if the setting to close the window after replying or + /// forwarding is set. + void slotReplyOrForwardFinished(); + private: void initKMReaderMainWin(); void setupAccel(); diff --git a/messageactions.cpp b/messageactions.cpp index c09e649f4..737f4808f 100644 --- a/messageactions.cpp +++ b/messageactions.cpp @@ -174,6 +174,8 @@ template void MessageActions::replyCommand() return; const QString text = mMessageView ? mMessageView->copyText() : ""; KMCommand *command = new T( mParent, mCurrentMessage, text ); + connect( command, SIGNAL( completed( KMCommand * ) ), + this, SIGNAL( replyActionFinished() ) ); command->start(); } diff --git a/messageactions.h b/messageactions.h index 07f32c247..6decc221a 100644 --- a/messageactions.h +++ b/messageactions.h @@ -55,6 +55,14 @@ class MessageActions : public QObject KAction* editAction() const { return mEditAction; } + signals: + + // This signal is emitted when a reply is triggered and the + // action has finished. + // This is useful for the stand-alone reader, it might want to close the window in + // that case. + void replyActionFinished(); + public slots: void editCurrentMessage(); From 02f21c5968849866fad2bbf8b390ec048c0a75a5 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 26 Jan 2010 11:21:11 +0000 Subject: [PATCH 091/160] Add config option to close the seperate reader window after replying/forwarding. No UI to change the config option yet, that will come next. svn path=/branches/kdepim/enterprise/kdepim/; revision=1080529 --- kmail.kcfg | 4 ++++ kmreadermainwin.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/kmail.kcfg b/kmail.kcfg index e1d6dc0fb..478d168ce 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -527,6 +527,10 @@ + + + false + true diff --git a/kmreadermainwin.cpp b/kmreadermainwin.cpp index 040624efc..e0042b9f4 100644 --- a/kmreadermainwin.cpp +++ b/kmreadermainwin.cpp @@ -170,7 +170,9 @@ void KMReaderMainWin::slotFolderRemoved( QObject* folderPtr ) void KMReaderMainWin::slotReplyOrForwardFinished() { - kdDebug(5006) << "Reply or forward done!" << endl; + if ( GlobalSettings::self()->closeAfterReplyOrForward() ) { + close(); + } } //----------------------------------------------------------------------------- From 078c796e78fb27b4bf398af9a6c5db2a2500ec48 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 26 Jan 2010 11:46:42 +0000 Subject: [PATCH 092/160] Add checkbox for the "Close window after replying or forwarding" option. I've added this to the apperance->message window config tab. I'm not too hapy about that, but I couldn't find a place that is better suited. svn path=/branches/kdepim/enterprise/kdepim/; revision=1080537 --- configuredialog.cpp | 16 ++++++++++++++++ configuredialog_p.h | 1 + 2 files changed, 17 insertions(+) diff --git a/configuredialog.cpp b/configuredialog.cpp index 0c172c9c7..c6885b3a4 100644 --- a/configuredialog.cpp +++ b/configuredialog.cpp @@ -2217,6 +2217,10 @@ void AppearancePage::HeadersTab::save() { // +static const BoolConfigEntry closeAfterReplyOrForward = { + "Reader", "CloseAfterReplyOrForward", I18N_NOOP("Close message window after replying or forwarding"), false +}; + static const BoolConfigEntry showColorbarMode = { "Reader", "showColorbar", I18N_NOOP("Show HTML stat&us bar"), false }; @@ -2248,6 +2252,15 @@ AppearancePageReaderTab::AppearancePageReaderTab( QWidget * parent, { QVBoxLayout *vlay = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() ); + // "close message window after replying or forwarding" checkbox + populateCheckBox( mCloseAfterReplyOrForwardCheck = new QCheckBox( this ), + closeAfterReplyOrForward ); + QToolTip::add( mCloseAfterReplyOrForwardCheck, + i18n( "Close the standalone message window after replying or forwarding the message" ) ); + vlay->addWidget( mCloseAfterReplyOrForwardCheck ); + connect( mCloseAfterReplyOrForwardCheck, SIGNAL ( stateChanged( int ) ), + this, SLOT( slotEmitChanged() ) ); + // "show colorbar" check box: populateCheckBox( mShowColorbarCheck = new QCheckBox( this ), showColorbarMode ); vlay->addWidget( mShowColorbarCheck ); @@ -2400,6 +2413,7 @@ void AppearancePage::ReaderTab::readCurrentOverrideCodec() void AppearancePage::ReaderTab::doLoadFromGlobalSettings() { + mCloseAfterReplyOrForwardCheck->setChecked( GlobalSettings::self()->closeAfterReplyOrForward() ); mShowEmoticonsCheck->setChecked( GlobalSettings::self()->showEmoticons() ); mShrinkQuotesCheck->setChecked( GlobalSettings::self()->shrinkQuotes() ); mShowExpandQuotesMark->setChecked( GlobalSettings::self()->showExpandQuotesMark() ); @@ -2420,6 +2434,7 @@ void AppearancePage::ReaderTab::save() { KConfigGroup reader( KMKernel::config(), "Reader" ); saveCheckBox( mShowColorbarCheck, reader, showColorbarMode ); saveCheckBox( mShowSpamStatusCheck, reader, showSpamStatusMode ); + GlobalSettings::self()->setCloseAfterReplyOrForward( mCloseAfterReplyOrForwardCheck->isChecked() ); GlobalSettings::self()->setShowEmoticons( mShowEmoticonsCheck->isChecked() ); GlobalSettings::self()->setShrinkQuotes( mShrinkQuotesCheck->isChecked() ); GlobalSettings::self()->setShowExpandQuotesMark( mShowExpandQuotesMark->isChecked() ); @@ -2436,6 +2451,7 @@ void AppearancePage::ReaderTab::save() { void AppearancePage::ReaderTab::installProfile( KConfig * /* profile */ ) { const KConfigGroup reader( KMKernel::config(), "Reader" ); + loadProfile( mCloseAfterReplyOrForwardCheck, reader, closeAfterReplyOrForward ); loadProfile( mShowColorbarCheck, reader, showColorbarMode ); loadProfile( mShowSpamStatusCheck, reader, showSpamStatusMode ); loadProfile( mShowEmoticonsCheck, reader, showEmoticons ); diff --git a/configuredialog_p.h b/configuredialog_p.h index 4ab34aa9f..78ab1e7b9 100644 --- a/configuredialog_p.h +++ b/configuredialog_p.h @@ -532,6 +532,7 @@ private: void readCurrentOverrideCodec(); private: // data + QCheckBox *mCloseAfterReplyOrForwardCheck; QCheckBox *mShowColorbarCheck; QCheckBox *mShowSpamStatusCheck; QCheckBox *mShowEmoticonsCheck; From af26d2c33168b02df15765c00b07f428433cbe9a Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Tue, 26 Jan 2010 13:05:18 +0000 Subject: [PATCH 093/160] Sync select all with menu svn path=/branches/KDE/4.4/kdepim/; revision=1080563 --- kmcomposewin.cpp | 3 ++- kmcomposewin.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 0db4d959d..b9dea6d4f 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -443,6 +443,7 @@ void KMComposeWin::slotEditorTextChanged() mFindText->setEnabled( textIsNotEmpty ); mFindNextText->setEnabled( textIsNotEmpty ); mReplaceText->setEnabled( textIsNotEmpty ); + mSelectAll->setEnabled( textIsNotEmpty ); } //----------------------------------------------------------------------------- @@ -1202,7 +1203,7 @@ void KMComposeWin::setupActions( void ) KStandardAction::cut( this, SLOT(slotCut()), actionCollection() ); KStandardAction::copy( this, SLOT(slotCopy()), actionCollection() ); KStandardAction::pasteText( this, SLOT(slotPaste()), actionCollection() ); - KStandardAction::selectAll( this, SLOT(slotMarkAll()), actionCollection() ); + mSelectAll = KStandardAction::selectAll( this, SLOT(slotMarkAll()), actionCollection() ); mFindText = KStandardAction::find( mEditor, SLOT(slotFind()), actionCollection() ); mFindNextText = KStandardAction::findNext( mEditor, SLOT(slotFindNext()), actionCollection() ); diff --git a/kmcomposewin.h b/kmcomposewin.h index a048a73d4..5a68824b4 100644 --- a/kmcomposewin.h +++ b/kmcomposewin.h @@ -793,7 +793,7 @@ class KMComposeWin : public KMail::Composer KSelectAction *mEncodingAction; KSelectAction *mCryptoModuleAction; - KAction * mFindText, *mFindNextText, *mReplaceText; + KAction * mFindText, *mFindNextText, *mReplaceText, *mSelectAll; QByteArray mCharset; QByteArray mDefCharset; From 021c31a8547a36a12a40979d772500b98f5d7c03 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 29 Jan 2010 13:26:41 +0000 Subject: [PATCH 094/160] Backport r1081964 by tmcguire from trunk to the 4.4 branch: Set a limit of 1 result for search jobs where we don't need more than 1 result anyway. Should help with bug 219687. CCBUG: 219687 svn path=/branches/KDE/4.4/kdepim/; revision=1081978 --- headerstyle.cpp | 1 + keyresolver.cpp | 2 ++ kmmainwidget.cpp | 1 + kmreadermainwin.cpp | 1 + kmsearchpattern.cpp | 2 ++ xfaceconfigurator.cpp | 1 + 6 files changed, 8 insertions(+) diff --git a/headerstyle.cpp b/headerstyle.cpp index 1449bb67b..99aae7127 100644 --- a/headerstyle.cpp +++ b/headerstyle.cpp @@ -486,6 +486,7 @@ namespace KMail { QString userHTML; Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, KPIMUtils::firstEmailAddress( message->from() ) ); job->exec(); const KABC::Addressee::List addresses = job->contacts(); diff --git a/keyresolver.cpp b/keyresolver.cpp index 57e79025e..3c5f2165e 100644 --- a/keyresolver.cpp +++ b/keyresolver.cpp @@ -1737,6 +1737,7 @@ Kleo::KeyResolver::ContactPreferences Kleo::KeyResolver::lookupContactPreference return it->second; Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, address ); job->exec(); @@ -1772,6 +1773,7 @@ void Kleo::KeyResolver::saveContactPreference( const QString& email, const Conta d->mContactPreferencesMap.insert( std::make_pair( email, pref ) ); Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, email ); job->exec(); diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index 1258b79d1..737c2acc5 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -3350,6 +3350,7 @@ void KMMainWidget::slotMsgPopup( KMMessage &msg, const KUrl &aUrl, const QPoint QString email = KPIMUtils::firstEmailAddress( aUrl.path() ); Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, email ); job->exec(); diff --git a/kmreadermainwin.cpp b/kmreadermainwin.cpp index 5ce3148b4..49f2dabcf 100644 --- a/kmreadermainwin.cpp +++ b/kmreadermainwin.cpp @@ -388,6 +388,7 @@ void KMReaderMainWin::slotMsgPopup( KMMessage &aMsg, const KUrl &aUrl, const QPo } QString email = KPIMUtils::firstEmailAddress( aUrl.path() ); Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob( this ); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, email ); job->exec(); diff --git a/kmsearchpattern.cpp b/kmsearchpattern.cpp index 1b50b5a86..ccdd8a7a0 100644 --- a/kmsearchpattern.cpp +++ b/kmsearchpattern.cpp @@ -458,6 +458,7 @@ bool KMSearchRuleString::matchesInternal( const QString & msgContents ) const const QStringList addressList = KPIMUtils::splitAddressList( msgContents.toLower() ); for ( QStringList::ConstIterator it = addressList.constBegin(); ( it != addressList.constEnd() ); ++it ) { Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, KPIMUtils::extractEmailAddress( *it ) ); job->exec(); @@ -471,6 +472,7 @@ bool KMSearchRuleString::matchesInternal( const QString & msgContents ) const const QStringList addressList = KPIMUtils::splitAddressList( msgContents.toLower() ); for ( QStringList::ConstIterator it = addressList.constBegin(); ( it != addressList.constEnd() ); ++it ) { Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(); + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, KPIMUtils::extractEmailAddress( *it ) ); job->exec(); diff --git a/xfaceconfigurator.cpp b/xfaceconfigurator.cpp index 31bba20fb..3559487bf 100644 --- a/xfaceconfigurator.cpp +++ b/xfaceconfigurator.cpp @@ -251,6 +251,7 @@ namespace KMail { const QString email = defaultIdentity.emailAddr(); Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob; + job->setLimit( 1 ); job->setQuery( Akonadi::ContactSearchJob::Email, email ); job->exec(); From 399ef2bcc94bc834d4cf00bb0c058bc4731d63fe Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 29 Jan 2010 14:22:17 +0000 Subject: [PATCH 095/160] Make those strings translatable kolab/issue4058 MERGE: none (it is handled in kdelibs in trunk, which has translatable strings) svn path=/branches/kdepim/enterprise/kdepim/; revision=1082001 --- kmedit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmedit.cpp b/kmedit.cpp index bc62e4b39..3afb280c0 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -454,7 +454,7 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) } else { - p.insertItem( QString::fromLatin1("No Suggestions"), -2 ); + p.insertItem( i18n( "No Suggestions" ), -2 ); } //Execute the popup inline From 22c588016a66f6aa582b88344efafe41eaae34d9 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 29 Jan 2010 14:56:27 +0000 Subject: [PATCH 096/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1082021 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index c5389178c..f21ceca96 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1078631)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1082020)" #endif /*kmversion_h*/ From 1052ea175ffad5ad71d79ca55d1bc736749107e0 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Mon, 1 Feb 2010 10:37:59 +0000 Subject: [PATCH 097/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1083482 --- application_octetstream.desktop | 2 +- kmail.notifyrc | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/application_octetstream.desktop b/application_octetstream.desktop index c64a6b313..3c7132dc2 100644 --- a/application_octetstream.desktop +++ b/application_octetstream.desktop @@ -42,7 +42,7 @@ Comment[ca@valencia]=Un connector formatador del cos per application/byte-stream Comment[cs]=Modul formátovače těla pro application/octet-stream Comment[da]=Et bodypart formateringsplugin for application/octet-stream Comment[de]=Ein Bodypart-Formatiermodul für application/octet-stream -Comment[el]=Ένας μορφοποιητής για application/octet-stream +Comment[el]=Πρόσθετο μορφοποίησης του κυρίως σώματος για application/octet-stream Comment[en_GB]=A bodypart formatter plugin for application/octet-stream Comment[es]=Un complemento de formateo para el cuerpo de application/octet-stream Comment[et]=Põhiosa vormindamisplugin (MIME tüübile application/octet-stream) diff --git a/kmail.notifyrc b/kmail.notifyrc index 26bb98dd7..e6bb57537 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -67,6 +67,7 @@ Name[ca]=Error en comprovar el correu Name[ca@valencia]=Error en comprovar el correu Name[da]=Fejl under tjek af e-mail Name[de]=Fehler beim Sehen nach neuen Nachrichten +Name[el]=Σφάλμα κατά τον έλεγχο νέας αλληλογραφίας Name[en_GB]=Error While Checking Mail Name[es]=Error al comprobar el correo Name[et]=Viga kirjade kontrollimisel @@ -96,6 +97,7 @@ Comment[ca]=S'ha produït un error en comprovar el coreu nou Comment[ca@valencia]=S'ha produït un error en comprovar el coreu nou Comment[da]=Der opstod en fejl under tjek efter nye e-mails Comment[de]=Beim Sehen nach neuen Nachrichten ist ein Fehler aufgetreten +Comment[el]=Παρουσιάστηκε ένα σφάλμα κατά τον έλεγχο νέας αλληλογραφίας Comment[en_GB]=There was an error while checking for new mail Comment[es]=Ha ocurrido un error mientras se comprobaba el correo nuevo Comment[et]=Uute kirjade kontrollimisel tekkis viga From 59653f3a543e79e0f4c65eddc4533660a07fd045 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Feb 2010 12:32:50 +0000 Subject: [PATCH 098/160] Don't reset the part charset to the message charset here, that is wrong in case the charsets differ, and in any case seems unneeded. kolab/issue4054 svn path=/branches/kdepim/enterprise/kdepim/; revision=1084067 --- kmcomposewin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 4dda7fce0..1db5a3bce 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -3187,7 +3187,6 @@ void KMComposeWin::slotAttachProperties() if (idx < 0) return; KMMessagePart* msgPart = mAtmList.at(idx); - msgPart->setCharset(mCharset); KMMsgPartDialogCompat dlg(mMainWidget); dlg.setMsgPart(msgPart); From 72e9c0802747002677aeba3cbb596016cc5018ce Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Feb 2010 14:03:51 +0000 Subject: [PATCH 099/160] Decode the body and the headers before searching in them, otherwise non-ascii characters can't be found. kolab/issue4076 svn path=/branches/kdepim/enterprise/kdepim/; revision=1084100 --- kmsearchpattern.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/kmsearchpattern.cpp b/kmsearchpattern.cpp index da1365e84..08607291f 100644 --- a/kmsearchpattern.cpp +++ b/kmsearchpattern.cpp @@ -27,6 +27,8 @@ using KMail::FilterLog; #include #include +#include +#include #include @@ -333,7 +335,19 @@ bool KMSearchRuleString::matches( const KMMessage * msg ) const bool logContents = true; if( field() == "" ) { - msgContents = msg->asString(); + + // When searching in the complete message, we can't simply use msg->asString() here, + // as that wouldn't decode the body. Therefore we use the decoded body and all decoded + // header fields and add all to the one big search string. + msgContents += msg->bodyToUnicode(); + const DwHeaders& headers = msg->headers(); + const DwField * dwField = headers.FirstField(); + while( dwField != 0 ) { + const char * const fieldName = dwField->FieldNameStr().c_str(); + const QString fieldValue = msg->headerFields( fieldName ).join( " " ); + msgContents += " " + fieldValue; + dwField = dwField->Next(); + } logContents = false; } else if ( field() == "" ) { msgContents = msg->bodyToUnicode(); From 7b65d370c8023dcf68802f082987ea7070fc336a Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Feb 2010 14:29:16 +0000 Subject: [PATCH 100/160] Add two new options to the "When entering a folder" action. They have no effect yet. svn path=/branches/kdepim/enterprise/kdepim/; revision=1084112 --- configuredialog.cpp | 6 +++++- kmail.kcfg | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configuredialog.cpp b/configuredialog.cpp index c6885b3a4..51d47a8ef 100644 --- a/configuredialog.cpp +++ b/configuredialog.cpp @@ -4566,7 +4566,11 @@ MiscPageFolderTab::MiscPageFolderTab( QWidget * parent, const char * name ) << i18n("continuation of \"When entering a folder:\"", "Jump to First Unread or New Message") << i18n("continuation of \"When entering a folder:\"", - "Jump to Last Selected Message")); + "Jump to Last Selected Message") + << i18n("continuation of \"When entering a folder:\"", + "Jump to Newest Message") + << i18n("continuation of \"When entering a folder:\"", + "Jump to Oldest Message") ); hlay->addWidget( label ); hlay->addWidget( mActionEnterFolder, 1 ); connect( mActionEnterFolder, SIGNAL( activated( int ) ), diff --git a/kmail.kcfg b/kmail.kcfg index 478d168ce..3af3202e3 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -24,6 +24,8 @@ + + SelectLastSelected From c415a60a58e648908fa78226bc114f87e93bce88 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 2 Feb 2010 15:26:03 +0000 Subject: [PATCH 101/160] backport SVN commit 1078389 by mlaurent: Readd standardArchivePath when url is empty and we change type of archive (avoid to create file as .tar.gz etc.) MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1084129 --- archivefolderdialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index c8d9be098..18f5bfe6e 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -172,6 +172,10 @@ void ArchiveFolderDialog::slotFixFileExtension() const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" }; QString fileName = mUrlRequester->url(); + if ( fileName.isEmpty() ) { + fileName = standardArchivePath( mFolderRequester->folder() ? + mFolderRequester->folder()->name() : "" ); + } // First, try to find the extension of the file name and remove it for( int i = 0; i < numExtensions; i++ ) { From b20f1cacd55df42ee9cace7c090ed03b7c78d049 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 2 Feb 2010 15:39:30 +0000 Subject: [PATCH 102/160] backport SVN commit 1078375 by mlaurent: Fix crash when we select an nul folder (LocalFolder) and don't select folder which can't have content (as top level in imap account) MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1084137 --- archivefolderdialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index 18f5bfe6e..b25b56cb4 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -125,7 +125,8 @@ void ArchiveFolderDialog::slotUrlChanged( const QString &text ) void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) { - mDeleteCheckBox->setEnabled( folder->canDeleteMessages() ); + mDeleteCheckBox->setEnabled( folder && folder->canDeleteMessages() && !folder->noContent()); + enableButton( Ok, folder && !folder->noContent()); } void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) From 5182e32d70b5151354917cce99da0acfbd07f808 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 2 Feb 2010 15:44:57 +0000 Subject: [PATCH 103/160] backport SVN commit 1080353 by mlaurent: Don't allow to delete system folder (see on my kdab account) MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1084142 --- archivefolderdialog.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/archivefolderdialog.cpp b/archivefolderdialog.cpp index b25b56cb4..54757b3c0 100644 --- a/archivefolderdialog.cpp +++ b/archivefolderdialog.cpp @@ -123,9 +123,18 @@ void ArchiveFolderDialog::slotUrlChanged( const QString &text ) enableButton( Ok, !text.isEmpty() ); } +bool canRemoveFolder( KMFolder *folder ) +{ + return + folder && + folder->canDeleteMessages() && + !folder->noContent() && + !folder->isSystemFolder(); +} + void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder ) { - mDeleteCheckBox->setEnabled( folder && folder->canDeleteMessages() && !folder->noContent()); + mDeleteCheckBox->setEnabled( canRemoveFolder( folder ) ); enableButton( Ok, folder && !folder->noContent()); } @@ -134,7 +143,7 @@ void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder ) mFolderRequester->setFolder( defaultFolder ); // TODO: what if the file already exists? mUrlRequester->setURL( standardArchivePath( defaultFolder->name() ) ); - mDeleteCheckBox->setEnabled( defaultFolder->canDeleteMessages() ); + mDeleteCheckBox->setEnabled( canRemoveFolder( defaultFolder ) ); } void ArchiveFolderDialog::slotOk() @@ -154,8 +163,8 @@ void ArchiveFolderDialog::slotOk() backupJob->setRootFolder( mFolderRequester->folder() ); backupJob->setSaveLocation( mUrlRequester->url() ); backupJob->setArchiveType( static_cast( mFormatComboBox->currentItem() ) ); - backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() && - mFolderRequester->folder()->canDeleteMessages() ); + backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isEnabled() && + mDeleteCheckBox->isChecked() ); backupJob->start(); accept(); } From 702cfd5a01e416d495e2cab3ef28b6187cc6815f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Feb 2010 15:45:06 +0000 Subject: [PATCH 104/160] Implement jumping to newest or oldest message when entering a folder. MERGE:trunk kolab/issue4076 svn path=/branches/kdepim/enterprise/kdepim/; revision=1084143 --- kmheaders.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/kmheaders.cpp b/kmheaders.cpp index 4ecc11ec6..1f48370e7 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -3044,6 +3044,8 @@ bool KMHeaders::readSortOrder( bool set_selection, bool forceJumpToUnread ) bool jumpToUnread = (GlobalSettings::self()->actionEnterFolder() == GlobalSettings::EnumActionEnterFolder::SelectFirstUnreadNew) || forceJumpToUnread; + HeaderItem *oldestItem = 0; + HeaderItem *newestItem = 0; QMemArray sortCache(mFolder->count()); bool error = false; @@ -3347,6 +3349,16 @@ bool KMHeaders::readSortOrder( bool set_selection, bool forceJumpToUnread ) { unread_exists = true; } + + if ( !oldestItem || mFolder->getMsgBase( oldestItem->msgId() )->date() > + mFolder->getMsgBase( new_kci->id() )->date() ) { + oldestItem = khi; + } + + if ( !newestItem || mFolder->getMsgBase( newestItem->msgId() )->date() < + mFolder->getMsgBase( new_kci->id() )->date() ) { + newestItem = khi; + } } // If we are sorting by date and ascending the top level items are sorted // ascending and the threads themselves are sorted descending. One wants @@ -3396,10 +3408,12 @@ bool KMHeaders::readSortOrder( bool set_selection, bool forceJumpToUnread ) } } - //show a message + // Select a message, depending on the "When entering a folder:" setting CREATE_TIMER(selection); START_TIMER(selection); if(set_selection) { + + // Search for the id of the first unread/new item, should there be any int first_unread = -1; if (unread_exists) { HeaderItem *item = static_cast(firstChild()); @@ -3418,19 +3432,33 @@ bool KMHeaders::readSortOrder( bool set_selection, bool forceJumpToUnread ) } } + // No unread message to select, so either select the newest, oldest or lastest selected if(first_unread == -1 ) { - setTopItemByIndex(mTopItem); - if ( mCurrentItem >= 0 ) + setTopItemByIndex( mTopItem ); + + if ( GlobalSettings::self()->actionEnterFolder() == + GlobalSettings::EnumActionEnterFolder::SelectNewest && newestItem != 0 ) { + setCurrentItemByIndex( newestItem->msgId() ); + } + else if ( GlobalSettings::self()->actionEnterFolder() == + GlobalSettings::EnumActionEnterFolder::SelectOldest && oldestItem != 0 ) { + setCurrentItemByIndex( oldestItem->msgId() ); + } + else if ( mCurrentItem >= 0 ) setCurrentItemByIndex( mCurrentItem ); else if ( mCurrentItemSerNum > 0 ) setCurrentItemBySerialNum( mCurrentItemSerNum ); else setCurrentItemByIndex( 0 ); + + // There is an unread item to select, so select it } else { setCurrentItemByIndex(first_unread); makeHeaderVisible(); center( contentsX(), itemPos(mItems[first_unread]), 0, 9.0 ); } + + // we are told to not change the selection } else { // only reset the selection if we have no current item if (mCurrentItem <= 0) { From 513ab41f1a79f41f32817ed992231825c30a26f3 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 2 Feb 2010 15:49:54 +0000 Subject: [PATCH 105/160] backport SVN commit 1080359 by mlaurent: Don't autorize to delete a folder which has not content MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1084147 --- kmmainwidget.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index 5db088d8c..cacdf8215 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -3419,12 +3419,23 @@ void KMMainWidget::updateFolderMenu() || ( cachedImap && knownImapPath ) ) && !multiFolder ); if ( mTroubleshootFolderAction ) mTroubleshootFolderAction->setEnabled( folderWithContent && ( cachedImap && knownImapPath ) && !multiFolder ); - mEmptyFolderAction->setEnabled( folderWithContent && ( mFolder->count() > 0 ) && mFolder->canDeleteMessages() && !multiFolder ); - mEmptyFolderAction->setText( (mFolder && kmkernel->folderIsTrash(mFolder)) - ? i18n("E&mpty Trash") : i18n("&Move All Messages to Trash") ); - mRemoveFolderAction->setEnabled( mFolder && !mFolder->isSystemFolder() && mFolder->canDeleteMessages() && !multiFolder); - mRemoveFolderAction->setText( mFolder && mFolder->folderType() == KMFolderTypeSearch - ? i18n("&Delete Search") : i18n("&Delete Folder") ); + + mEmptyFolderAction->setEnabled( folderWithContent && + ( mFolder->count() > 0 ) && mFolder->canDeleteMessages() && + !multiFolder ); + mEmptyFolderAction->setText( ( mFolder && kmkernel->folderIsTrash( mFolder ) ) ? + i18n( "E&mpty Trash" ) : + i18n( "&Move All Messages to Trash" ) ); + + mRemoveFolderAction->setEnabled( mFolder && + !mFolder->isSystemFolder() && + mFolder->canDeleteMessages() && + !multiFolder && !mFolder->noContent() ); + mRemoveFolderAction->setText( mFolder && + mFolder->folderType() == KMFolderTypeSearch ? + i18n( "&Delete Search" ) : + i18n( "&Delete Folder" ) ); + if ( mArchiveFolderAction ) mArchiveFolderAction->setEnabled( mFolder && !multiFolder ); mExpireFolderAction->setEnabled( mFolder && mFolder->isAutoExpire() && !multiFolder && mFolder->canDeleteMessages() ); From e6473a6f2dd29b61edfba4a63f3bf917faa26dfe Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 2 Feb 2010 16:03:38 +0000 Subject: [PATCH 106/160] backport SVN commit 1078972 by mlaurent: Add warning when we select same folder as current. MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1084153 --- expirypropertiesdialog.cpp | 51 ++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/expirypropertiesdialog.cpp b/expirypropertiesdialog.cpp index 62d9047fa..4b1befd1c 100644 --- a/expirypropertiesdialog.cpp +++ b/expirypropertiesdialog.cpp @@ -28,8 +28,8 @@ using namespace KMail; * */ ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* folder ) - : KDialogBase( tree, "expiry_properties", false, i18n( "Mail Expiry Properties" ), - KDialogBase::Ok|KDialogBase::Cancel, + : KDialogBase( tree, "expiry_properties", false, i18n( "Mail Expiry Properties" ), + KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true ), mFolder( folder ) { @@ -37,10 +37,10 @@ ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* fo QWidget* privateLayoutWidget = new QWidget( this, "globalVBox" ); setMainWidget( privateLayoutWidget ); privateLayoutWidget->setGeometry( QRect( 10, 20, 270, 138 ) ); - globalVBox = new QVBoxLayout( privateLayoutWidget, 11, 6, "globalVBox"); + globalVBox = new QVBoxLayout( privateLayoutWidget, 11, 6, "globalVBox"); globalVBox->setSpacing( 20 ); - readHBox = new QHBoxLayout( 0, 0, 6, "readHBox"); + readHBox = new QHBoxLayout( 0, 0, 6, "readHBox"); expireReadMailCB = new QCheckBox( privateLayoutWidget, "expireReadMailCB" ); expireReadMailCB->setText( i18n( "Expire read mails after" ) ); @@ -58,7 +58,7 @@ ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* fo readHBox->addWidget( labelDays ); globalVBox->addLayout( readHBox ); - unreadHBox = new QHBoxLayout( 0, 0, 6, "unreadHBox"); + unreadHBox = new QHBoxLayout( 0, 0, 6, "unreadHBox"); expireUnreadMailCB = new QCheckBox( privateLayoutWidget, "expireUnreadMailCB" ); expireUnreadMailCB->setText( i18n( "Expire unread mails after" ) ); @@ -77,18 +77,18 @@ ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* fo unreadHBox->addWidget( labelDays2 ); globalVBox->addLayout( unreadHBox ); - expiryActionHBox = new QHBoxLayout( 0, 0, 6, "expiryActionHBox"); + expiryActionHBox = new QHBoxLayout( 0, 0, 6, "expiryActionHBox"); expiryActionLabel = new QLabel( privateLayoutWidget, "expiryActionLabel" ); expiryActionLabel->setText( i18n( "Expiry action:" ) ); expiryActionLabel->setAlignment( int( QLabel::AlignVCenter ) ); expiryActionHBox->addWidget( expiryActionLabel ); - actionsHBox = new QVBoxLayout( 0, 0, 6, "actionsHBox"); + actionsHBox = new QVBoxLayout( 0, 0, 6, "actionsHBox"); actionsGroup = new QButtonGroup( this ); actionsGroup->hide(); // for mutual exclusion of the radio buttons - moveToHBox = new QHBoxLayout( 0, 0, 6, "moveToHBox"); + moveToHBox = new QHBoxLayout( 0, 0, 6, "moveToHBox"); moveToRB = new QRadioButton( privateLayoutWidget, "moveToRB" ); actionsGroup->insert( moveToRB ); @@ -119,14 +119,14 @@ ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* fo int daysToExpireRead, daysToExpireUnread; mFolder->daysToExpire( daysToExpireUnread, daysToExpireRead); - if ( expiryGloballyOn - && mFolder->getReadExpireUnits() != expireNever + if ( expiryGloballyOn + && mFolder->getReadExpireUnits() != expireNever && daysToExpireRead >= 0 ) { expireReadMailCB->setChecked( true ); expireReadMailSB->setValue( daysToExpireRead ); } if ( expiryGloballyOn - && mFolder->getUnreadExpireUnits() != expireNever + && mFolder->getUnreadExpireUnits() != expireNever && daysToExpireUnread >= 0 ) { expireUnreadMailCB->setChecked( true ); expireUnreadMailSB->setValue( daysToExpireUnread ); @@ -159,11 +159,29 @@ ExpiryPropertiesDialog::~ExpiryPropertiesDialog() 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" ) ); + + KMFolder *expireToFolder = folderSelector->folder(); + if ( enableGlobally && moveToRB->isChecked() && !expireToFolder ) { + KMessageBox::error( + this, + i18n( "Please select a folder to expire messages into." ), + i18n( "No Folder Selected" ) ); return; - } + } + + if ( expireToFolder ) { + if ( expireToFolder->idString() == mFolder->idString() ) { + KMessageBox::error( + this, + i18n( "Please select a different folder than the current folder " + "to expire message into." ), + i18n( "Wrong Folder Selected" ) ); + return; + } else { + mFolder->setExpireToFolderId( expireToFolder->idString() ); + } + } + mFolder->setAutoExpire( enableGlobally ); // we always write out days now mFolder->setReadExpireAge( expireReadMailSB->value() ); @@ -175,9 +193,6 @@ void ExpiryPropertiesDialog::slotOk() 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 ) From 485bad488f09d915132876e8d66fa6288e061018 Mon Sep 17 00:00:00 2001 From: Script Kiddy Date: Wed, 3 Feb 2010 11:03:43 +0000 Subject: [PATCH 107/160] SVN_SILENT made messages (.desktop file) svn path=/branches/KDE/4.4/kdepim/; revision=1084639 --- kmail.notifyrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmail.notifyrc b/kmail.notifyrc index e6bb57537..611ef1ef1 100644 --- a/kmail.notifyrc +++ b/kmail.notifyrc @@ -75,6 +75,7 @@ Name[fr]=Erreur lors de la vérification du courriel Name[gl]=Produciuse un erro ao comprobar o correo Name[it]=Errore durante il controllo della posta Name[ja]=メールのチェック中にエラー +Name[km]=កំហុស​ខណៈពេល​ពិនិត្យ​មើល​សំបុត្រ​ថ្មី Name[lv]=Kļūda pārbaudot pastu Name[nb]=Feil under sjekking av e-post Name[nds]=Fehler bi't Kieken na Nettpost @@ -105,6 +106,7 @@ Comment[fr]=Il y a eu une erreur lors de la vérification du courriel Comment[gl]=Aconteceu un erro cando se comprobaba o correo novo Comment[it]=Si è verificato un errore durante il controllo dei nuovi messaggi di posta Comment[ja]=新着メールのチェック中にエラーが発生しました +Comment[km]=មាន​កំហុស​ខណៈពេល​ពិនិត្យ​មើល​សំបុត្រ​ថ្មី Comment[lv]=Gadījās kļūda pārbaudot ienākošo pastu Comment[nb]=Det oppsto en feil mens det ble sett etter ny e-post Comment[nds]=Bi't Kieken na nieg Nettpost hett dat en Fehler geven From 6ceb387658d7164ac5cb0a89544e900c82dabe11 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 4 Feb 2010 13:54:24 +0000 Subject: [PATCH 108/160] possible fix for crash that can occur when using lots of kmail subwindows like the composer, search window. kolab/issue4081 MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1085170 --- kmcommands.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 83f189fc4..7320e0de9 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -243,13 +243,16 @@ void KMCommand::slotStart() return; } - for (KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next()) - if (!mb->parent()) { - emit messagesTransfered( Failed ); - return; - } else { - keepFolderOpen( mb->parent() ); + for ( KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next() ) { + if ( mb ) { + if ( !mb->parent() ) { + emit messagesTransfered( Failed ); + return; + } else { + keepFolderOpen( mb->parent() ); + } } + } // transfer the selected messages first transferSelectedMsgs(); @@ -446,7 +449,7 @@ void KMCommand::slotTransferCancelled() void KMCommand::keepFolderOpen( KMFolder *folder ) { - folder->open("kmcommand"); + folder->open( "kmcommand" ); mFolders.append( folder ); } From 6f1e9abf1c095579a7bdfb244b557e47f80b89cd Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 5 Feb 2010 18:22:01 +0000 Subject: [PATCH 109/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1085673 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index f21ceca96..381ee226b 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1082020)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1085672)" #endif /*kmversion_h*/ From a2af6b40b9c7aefac5ab368e93735431c2b2364c Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Mon, 8 Feb 2010 14:03:16 +0000 Subject: [PATCH 110/160] In the search window results list, make double-click on a message open that message in a separate reader window. also, make the [Open Message] button open the message in a separate reader window. kolab/issue4090 MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1087066 --- kmmainwidget.h | 8 ++++-- searchwindow.cpp | 75 +++++++++++++++++++++++++++++++----------------- searchwindow.h | 10 +++++-- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/kmmainwidget.h b/kmmainwidget.h index 911446b94..ab78c2375 100644 --- a/kmmainwidget.h +++ b/kmmainwidget.h @@ -201,7 +201,12 @@ public slots: /** Select the folder and jump to the next unread msg */ void folderSelectedUnread( KMFolder* ); - void slotMsgSelected(KMMessage*); + void slotMsgSelected( KMMessage * ); + /** + Open a separate viewer window containing the specified message. + */ + void slotMsgActivated( KMMessage * ); + void slotMsgChanged(); /** Change the current folder, select a message in the current folder */ @@ -361,7 +366,6 @@ protected slots: /** etc. */ void slotDisplayCurrentMessage(); - void slotMsgActivated( KMMessage* ); void slotShowNewFromTemplate(); void slotNewFromTemplate( int ); diff --git a/searchwindow.cpp b/searchwindow.cpp index aec9061ab..2767cc67c 100644 --- a/searchwindow.cpp +++ b/searchwindow.cpp @@ -237,13 +237,15 @@ SearchWindow::SearchWindow(KMMainWidget* w, const char* name, mLbxMatches->setDragEnabled( true ); - 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); + connect( mLbxMatches, SIGNAL(clicked(QListViewItem *)), + this, SLOT(slotShowMsg(QListViewItem *)) ); + connect( mLbxMatches, SIGNAL(doubleClicked(QListViewItem *)), + this, SLOT(slotViewMsg(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 ); QHBoxLayout *hbl2 = new QHBoxLayout( vbl, spacingHint(), "kmfs_hbl2" ); mSearchFolderLbl = new QLabel(i18n("Search folder &name:"), searchWidget); @@ -269,7 +271,7 @@ SearchWindow::SearchWindow(KMMainWidget* w, const char* name, mSearchResultOpenBtn->setEnabled(false); hbl2->addWidget(mSearchResultOpenBtn); connect( mSearchResultOpenBtn, SIGNAL( clicked() ), - this, SLOT( slotShowSelectedMsg() )); + this, SLOT( slotViewSelectedMsg() )); mStatusBar = new KStatusBar(searchWidget); mStatusBar->insertFixedItem(i18n("AMiddleLengthText..."), 0, true); mStatusBar->changeItem(i18n("Ready."), 0); @@ -472,9 +474,9 @@ void SearchWindow::slotSearch() mFetchingInProgress = 0; mSearchFolderOpenBtn->setEnabled(true); - if ( mSearchFolderEdt->text().isEmpty() ) { - mSearchFolderEdt->setText( i18n("Last Search") ); - } + if ( mSearchFolderEdt->text().isEmpty() ) { + mSearchFolderEdt->setText( i18n("Last Search") ); + } mBtnSearch->setEnabled(false); mBtnStop->setEnabled(true); @@ -683,32 +685,51 @@ void SearchWindow::folderInvalidated(KMFolder *folder) } //----------------------------------------------------------------------------- -bool SearchWindow::slotShowMsg(QListViewItem *item) +KMMessage *SearchWindow::indexToMessage( QListViewItem *item ) { - if(!item) - return false; + if( !item ) { + return 0; + } - KMFolder* folder; - int msgIndex; - KMMsgDict::instance()->getLocation(item->text(MSGID_COLUMN).toUInt(), - &folder, &msgIndex); + KMFolder *folder; + int msgIndex; + KMMsgDict::instance()->getLocation( item->text( MSGID_COLUMN ).toUInt(), + &folder, &msgIndex ); - if (!folder || msgIndex < 0) - return false; + if ( !folder || msgIndex < 0 ) { + return 0; + } - mKMMainWidget->slotSelectFolder(folder); - KMMessage* message = folder->getMsg(msgIndex); - if (!message) - return false; + mKMMainWidget->slotSelectFolder( folder ); + return folder->getMsg( msgIndex ); +} - mKMMainWidget->slotSelectMessage(message); +//----------------------------------------------------------------------------- +bool SearchWindow::slotShowMsg( QListViewItem *item ) +{ + KMMessage *message = indexToMessage( item ); + if ( message ) { + mKMMainWidget->slotSelectMessage( message ); return true; + } + return false; +} + +//----------------------------------------------------------------------------- +void SearchWindow::slotViewSelectedMsg() +{ + slotViewMsg( mLbxMatches->currentItem() ); } //----------------------------------------------------------------------------- -void SearchWindow::slotShowSelectedMsg() +bool SearchWindow::slotViewMsg( QListViewItem *item ) { - slotShowMsg(mLbxMatches->currentItem()); + KMMessage *message = indexToMessage( item ); + if ( message ) { + mKMMainWidget->slotMsgActivated( message ); + return true; + } + return false; } //----------------------------------------------------------------------------- diff --git a/searchwindow.h b/searchwindow.h index 62c6e6ce3..e90122eb5 100644 --- a/searchwindow.h +++ b/searchwindow.h @@ -113,9 +113,10 @@ protected slots: void renameSearchFolder(); void openSearchFolder(); void folderInvalidated(KMFolder *); - virtual bool slotShowMsg(QListViewItem *); - void slotShowSelectedMsg(); - void slotCurrentChanged(QListViewItem *); + virtual bool slotShowMsg( QListViewItem * ); + void slotViewSelectedMsg(); + virtual bool slotViewMsg( QListViewItem * ); + void slotCurrentChanged( QListViewItem * ); virtual void updateContextMenuActions(); virtual void slotContextMenuRequested( QListViewItem*, const QPoint &, int ); virtual void copySelectedToFolder( int menuId ); @@ -189,6 +190,9 @@ protected: KMSearchPattern *mSearchPattern; static const int MSGID_COLUMN; + +private: + KMMessage *indexToMessage( QListViewItem *item ); }; } // namespace KMail From 042b900284100b32d41ecb3bac9ee3cc7b7a3f79 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Mon, 8 Feb 2010 17:14:38 +0000 Subject: [PATCH 111/160] Change the "CloseToQuotaThreshold" default from 85 to 80. This is the threshold for when to warn the user that a folder is nearing its quota limit. kolab/issue4066 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087229 --- kmail.kcfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmail.kcfg b/kmail.kcfg index 3af3202e3..c5c16dd36 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -155,7 +155,7 @@ - 85 + 80 From 64977970dfdbe03fdcf2fdd1071bb26ad92a939b Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Tue, 9 Feb 2010 00:55:42 +0000 Subject: [PATCH 112/160] in slotAttachFile(), if the last used start dir has disappeared/moved since the last time the filedialog was created, then reset the start dir to the user's home directory. kolab/issue4057 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087423 --- kmcomposewin.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 1db5a3bce..101150675 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -2699,11 +2699,19 @@ void KMComposeWin::slotAttachFile() // We will not care about any permissions, existence or whatsoever in // this function. - KFileDialog fdlg(QString::null, QString::null, this, 0, true); + // Handle the case where the last savedir is gone. kolab/issue4057 + QString recent; + KURL recentURL = KFileDialog::getStartURL( QString::null, recent ); + if ( !recentURL.url().isEmpty() && + !KIO::NetAccess::exists( recentURL, true, this ) ) { + recentURL = KURL( QDir::homeDirPath() ); + } + + KFileDialog fdlg( recentURL.url(), QString::null, this, 0, true ); fdlg.setOperationMode( KFileDialog::Other ); - fdlg.setCaption(i18n("Attach File")); - fdlg.okButton()->setGuiItem(KGuiItem(i18n("&Attach"),"fileopen")); - fdlg.setMode(KFile::Files); + fdlg.setCaption( i18n( "Attach File" ) ); + fdlg.okButton()->setGuiItem( KGuiItem( i18n( "&Attach" ),"fileopen" ) ); + fdlg.setMode( KFile::Files ); fdlg.exec(); KURL::List files = fdlg.selectedURLs(); From 060e2cd8037f99eee90e2d6b9a765f879f3f6bd1 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 08:05:00 +0000 Subject: [PATCH 113/160] Remove the unused "selectionIsBody" parameter. MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087501 --- kmcommands.cpp | 8 ++++---- kmfilteraction.cpp | 1 - kmkernel.cpp | 12 ++++++------ kmmainwidget.cpp | 4 ++-- kmmessage.cpp | 5 ++--- kmmessage.h | 4 ++-- templateparser.cpp | 4 ++-- templateparser.h | 3 +-- 8 files changed, 19 insertions(+), 22 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 7320e0de9..0487032f9 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1248,7 +1248,7 @@ KMCommand::Result KMForwardInlineCommand::execute() for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { TemplateParser parser( fwdMsg, TemplateParser::Forward, - msg->body(), false, false, false, false); + msg->body(), false, false, false ); parser.process( msg, 0, true ); fwdMsg->link( msg, KMMsgStatusForwarded ); @@ -1476,7 +1476,7 @@ KMCommand::Result KMCustomReplyToCommand::execute() return Failed; } KMMessage *reply = msg->createReply( KMail::ReplySmart, mSelection, - false, true, false, mTemplate ); + false, true, mTemplate ); KMail::Composer * win = KMail::makeComposer( reply ); win->setCharset( msg->codec()->mimeName(), true ); win->setReplyFocus(); @@ -1501,7 +1501,7 @@ KMCommand::Result KMCustomReplyAllToCommand::execute() return Failed; } KMMessage *reply = msg->createReply( KMail::ReplyAll, mSelection, - false, true, false, mTemplate ); + false, true, mTemplate ); KMail::Composer * win = KMail::makeComposer( reply ); win->setCharset( msg->codec()->mimeName(), true ); win->setReplyFocus(); @@ -1551,7 +1551,7 @@ KMCommand::Result KMCustomForwardCommand::execute() for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { TemplateParser parser( fwdMsg, TemplateParser::Forward, - msg->body(), false, false, false, false); + msg->body(), false, false, false ); parser.process( msg, 0, true ); fwdMsg->link( msg, KMMsgStatusForwarded ); diff --git a/kmfilteraction.cpp b/kmfilteraction.cpp index 1fef78df7..8556a4510 100644 --- a/kmfilteraction.cpp +++ b/kmfilteraction.cpp @@ -29,7 +29,6 @@ using KPIM::CollectingProcess; #include "folderrequester.h" using KMail::FolderRequester; #include "kmmsgbase.h" -#include "templateparser.h" #include "messageproperty.h" #include "actionscheduler.h" using KMail::MessageProperty; diff --git a/kmkernel.cpp b/kmkernel.cpp index 9a509802e..da787e3d0 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -407,7 +407,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, msg->setBody( QString::fromLocal8Bit( str ).utf8() ); } else { TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, NULL ); } } @@ -418,7 +418,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, else { TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, NULL ); } @@ -524,7 +524,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, msg->setBody(body.utf8()); } else { TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, NULL ); } @@ -632,7 +632,7 @@ DCOPRef KMKernel::openComposer(const QString &to, const QString &cc, msg->setBody(body.utf8()); } else { TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, NULL ); } @@ -679,12 +679,12 @@ DCOPRef KMKernel::newMessage(const QString &to, if ( useFolderId ) { TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, folder ); win = makeComposer( msg, id ); } else { TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, folder ); win = makeComposer( msg ); } diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index cacdf8215..dfc3be1ac 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -992,13 +992,13 @@ void KMMainWidget::slotCompose() if ( mFolder ) { msg->initHeader( mFolder->identity() ); TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, mFolder ); win = KMail::makeComposer( msg, mFolder->identity() ); } else { msg->initHeader(); TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false, false ); + "", false, false, false ); parser.process( NULL, NULL ); win = KMail::makeComposer( msg ); } diff --git a/kmmessage.cpp b/kmmessage.cpp index 8868dea15..5f7c0c294 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -865,7 +865,6 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, QString selection /* = QString::null */, bool noQuote /* = false */, bool allowDecryption /* = true */, - bool selectionIsBody /* = false */, const QString &tmpl /* = QString::null */ ) { KMMessage* msg = new KMMessage; @@ -1070,7 +1069,7 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, formatString( GlobalSettings::self()->quoteString() ) ); if( !noQuote ) { TemplateParser parser( msg, (replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply), - selection, sSmartQuote, noQuote, allowDecryption, selectionIsBody ); + selection, sSmartQuote, noQuote, allowDecryption ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { @@ -1302,7 +1301,7 @@ KMMessage* KMMessage::createForward( const QString &tmpl /* = QString::null */ ) TemplateParser parser( msg, TemplateParser::Forward, QString(), - false, false, false, false); + false, false, false ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { diff --git a/kmmessage.h b/kmmessage.h index 9c152f1b9..90154bc17 100644 --- a/kmmessage.h +++ b/kmmessage.h @@ -162,8 +162,8 @@ public: required header fields with the proper values. The returned message is not stored in any folder. Marks this message as replied. */ KMMessage* createReply( KMail::ReplyStrategy replyStrategy = KMail::ReplySmart, - QString selection=QString::null, bool noQuote=false, - bool allowDecryption=true, bool selectionIsBody=false, + QString selection=QString::null, bool noQuote = false, + bool allowDecryption = true, const QString &tmpl = QString::null ); /** Create a new message that is a redirect to this message, filling all diff --git a/templateparser.cpp b/templateparser.cpp index 47bdb245f..4c55bc203 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -56,10 +56,10 @@ using namespace KMail; TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, const QString aselection, bool asmartQuote, bool anoQuote, - bool aallowDecryption, bool aselectionIsBody ) : + bool aallowDecryption ) : mMode( amode ), mFolder( 0 ), mIdentity( 0 ), mSelection( aselection ), mSmartQuote( asmartQuote ), mNoQuote( anoQuote ), - mAllowDecryption( aallowDecryption ), mSelectionIsBody( aselectionIsBody ), + mAllowDecryption( aallowDecryption ), mDebug( false ), mQuoteString( "> " ), mAppend( false ), mOrigRoot( 0 ) { mMsg = amsg; diff --git a/templateparser.h b/templateparser.h index 4e4fad011..beb0e3fed 100644 --- a/templateparser.h +++ b/templateparser.h @@ -45,8 +45,7 @@ class TemplateParser : public QObject public: TemplateParser( KMMessage *amsg, const Mode amode, const QString aselection, - bool aSmartQuote, bool anoQuote, bool aallowDecryption, - bool aselectionIsBody ); + bool aSmartQuote, bool anoQuote, bool aallowDecryption ); ~TemplateParser(); virtual void process( KMMessage *aorig_msg, KMFolder *afolder = 0, bool append = false ); From fe8419f3ee6d93fb14b67d7e3b6434885765f58b Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 08:27:17 +0000 Subject: [PATCH 114/160] Fight the monstor constructor: Use a function for the selection parameter. Also, document the template parser a bit, so that people can understand the difference between the two messages involved in processing. MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087505 --- kmcommands.cpp | 12 ++++++------ kmkernel.cpp | 18 ++++++------------ kmmainwidget.cpp | 6 ++---- kmmessage.cpp | 9 ++++----- templateparser.cpp | 8 ++++++-- templateparser.h | 32 +++++++++++++++++++++++++++++++- 6 files changed, 55 insertions(+), 30 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 0487032f9..38b7e8e8e 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1247,9 +1247,9 @@ KMCommand::Result KMForwardInlineCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, - msg->body(), false, false, false ); - parser.process( msg, 0, true ); + TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false, false ); + parser.setSelection( msg->body() ); + parser.process( msg, 0, true ); fwdMsg->link( msg, KMMsgStatusForwarded ); } @@ -1550,9 +1550,9 @@ KMCommand::Result KMCustomForwardCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, - msg->body(), false, false, false ); - parser.process( msg, 0, true ); + TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false, false ); + parser.setSelection( msg->body() ); + parser.process( msg, 0, true ); fwdMsg->link( msg, KMMsgStatusForwarded ); } diff --git a/kmkernel.cpp b/kmkernel.cpp index da787e3d0..6c788174c 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -406,8 +406,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if( !str.isEmpty() ) { msg->setBody( QString::fromLocal8Bit( str ).utf8() ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, NULL ); } } @@ -417,8 +416,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, } else { - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, NULL ); } @@ -523,8 +521,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if ( !body.isEmpty() ) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, NULL ); } @@ -631,8 +628,7 @@ DCOPRef KMKernel::openComposer(const QString &to, const QString &cc, if (!body.isEmpty()) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, NULL ); } @@ -678,13 +674,11 @@ DCOPRef KMKernel::newMessage(const QString &to, if (!bcc.isEmpty()) msg->setBcc(bcc); if ( useFolderId ) { - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, folder ); win = makeComposer( msg, id ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, folder ); win = makeComposer( msg ); } diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index dfc3be1ac..3c29c3053 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -991,14 +991,12 @@ void KMMainWidget::slotCompose() if ( mFolder ) { msg->initHeader( mFolder->identity() ); - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, mFolder ); win = KMail::makeComposer( msg, mFolder->identity() ); } else { msg->initHeader(); - TemplateParser parser( msg, TemplateParser::NewMessage, - "", false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); parser.process( NULL, NULL ); win = KMail::makeComposer( msg ); } diff --git a/kmmessage.cpp b/kmmessage.cpp index 5f7c0c294..727acf70a 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -1068,8 +1068,9 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, msg->setHeaderField( "X-KMail-QuotePrefix", formatString( GlobalSettings::self()->quoteString() ) ); if( !noQuote ) { - TemplateParser parser( msg, (replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply), - selection, sSmartQuote, noQuote, allowDecryption ); + TemplateParser parser( msg, ( replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply ), + sSmartQuote, noQuote, allowDecryption ); + parser.setSelection( selection ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { @@ -1299,9 +1300,7 @@ KMMessage* KMMessage::createForward( const QString &tmpl /* = QString::null */ ) msg->setSubject( forwardSubject() ); - TemplateParser parser( msg, TemplateParser::Forward, - QString(), - false, false, false ); + TemplateParser parser( msg, TemplateParser::Forward, false, false, false ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { diff --git a/templateparser.cpp b/templateparser.cpp index 4c55bc203..4963a0e8b 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -54,10 +54,9 @@ using namespace KMail; TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, - const QString aselection, bool asmartQuote, bool anoQuote, bool aallowDecryption ) : - mMode( amode ), mFolder( 0 ), mIdentity( 0 ), mSelection( aselection ), + mMode( amode ), mFolder( 0 ), mIdentity( 0 ), mSmartQuote( asmartQuote ), mNoQuote( anoQuote ), mAllowDecryption( aallowDecryption ), mDebug( false ), mQuoteString( "> " ), mAppend( false ), mOrigRoot( 0 ) @@ -65,6 +64,11 @@ TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, mMsg = amsg; } +void TemplateParser::setSelection( const QString &selection ) +{ + mSelection = selection; +} + TemplateParser::~TemplateParser() { delete mOrigRoot; diff --git a/templateparser.h b/templateparser.h index beb0e3fed..56a149ca1 100644 --- a/templateparser.h +++ b/templateparser.h @@ -29,6 +29,28 @@ class KMFolder; class QObject; class KProcess; +/** + * The TemplateParser transforms a message with a given template. + * + * A template contains text and commands, such as %QUOTE or %ODATE, which will be + * replaced with the real values in process(). + * + * The message given in the constructor is the message that is being transformed. + * The message text will be replaced by the processed text of the template, but other + * properties, such as the attachments or the subject, are preserved. + * + * There are two different kind of commands: Those that work on the message that is + * to be transformed and those that work on an 'original message'. + * Those that work on the message that is to be transformed have no special prefix, e.g. + * '%DATE'. Those that work on the original message have an 'O' prefix, for example + * '%ODATE'. + * This means that the %DATE command will take the date of the message passed in the + * constructor, the message which is to be transformed, whereas the %ODATE command will + * take the date of the message that is being passed in process(), the original message. + * + * TODO: What is the usecase of the commands that work on the message to be transformed? + * In general you only use the commands that work on the original message... + */ class TemplateParser : public QObject { Q_OBJECT @@ -44,10 +66,18 @@ class TemplateParser : public QObject static const int PipeTimeout = 15; public: - TemplateParser( KMMessage *amsg, const Mode amode, const QString aselection, + TemplateParser( KMMessage *amsg, const Mode amode, bool aSmartQuote, bool anoQuote, bool aallowDecryption ); ~TemplateParser(); + /** + * Sets the selection. If this is set, only the selection will be added to commands such + * as %QUOTE. Otherwise, the whole message is quoted. + * If this is not called at all, the whole message is quoted as well. + * Call this before calling process(). + */ + void setSelection( const QString &selection ); + virtual void process( KMMessage *aorig_msg, KMFolder *afolder = 0, bool append = false ); virtual void process( const QString &tmplName, KMMessage *aorig_msg, KMFolder *afolder = 0, bool append = false ); From daaea13e13401a7f1b8a65aaeea4a787ef12a82f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 08:34:20 +0000 Subject: [PATCH 115/160] Further fight the monster constructor: For the last parameter, use a function setAllowDecryption() instead. MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087506 --- kmcommands.cpp | 4 ++-- kmkernel.cpp | 12 ++++++------ kmmainwidget.cpp | 4 ++-- kmmessage.cpp | 5 +++-- templateparser.cpp | 10 +++++++--- templateparser.h | 12 +++++++++++- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index 38b7e8e8e..d6610d58c 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1247,7 +1247,7 @@ KMCommand::Result KMForwardInlineCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false, false ); + TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false ); parser.setSelection( msg->body() ); parser.process( msg, 0, true ); @@ -1550,7 +1550,7 @@ KMCommand::Result KMCustomForwardCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false, false ); + TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false ); parser.setSelection( msg->body() ); parser.process( msg, 0, true ); diff --git a/kmkernel.cpp b/kmkernel.cpp index 6c788174c..2f10918bb 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -406,7 +406,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if( !str.isEmpty() ) { msg->setBody( QString::fromLocal8Bit( str ).utf8() ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, NULL ); } } @@ -416,7 +416,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, NULL ); } @@ -521,7 +521,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if ( !body.isEmpty() ) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, NULL ); } @@ -628,7 +628,7 @@ DCOPRef KMKernel::openComposer(const QString &to, const QString &cc, if (!body.isEmpty()) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, NULL ); } @@ -674,11 +674,11 @@ DCOPRef KMKernel::newMessage(const QString &to, if (!bcc.isEmpty()) msg->setBcc(bcc); if ( useFolderId ) { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, folder ); win = makeComposer( msg, id ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, folder ); win = makeComposer( msg ); } diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index 3c29c3053..0367d9191 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -991,12 +991,12 @@ void KMMainWidget::slotCompose() if ( mFolder ) { msg->initHeader( mFolder->identity() ); - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, mFolder ); win = KMail::makeComposer( msg, mFolder->identity() ); } else { msg->initHeader(); - TemplateParser parser( msg, TemplateParser::NewMessage, false, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); parser.process( NULL, NULL ); win = KMail::makeComposer( msg ); } diff --git a/kmmessage.cpp b/kmmessage.cpp index 727acf70a..62495a93d 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -1069,7 +1069,8 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, formatString( GlobalSettings::self()->quoteString() ) ); if( !noQuote ) { TemplateParser parser( msg, ( replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply ), - sSmartQuote, noQuote, allowDecryption ); + sSmartQuote, noQuote ); + parser.setAllowDecryption( allowDecryption ); parser.setSelection( selection ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); @@ -1300,7 +1301,7 @@ KMMessage* KMMessage::createForward( const QString &tmpl /* = QString::null */ ) msg->setSubject( forwardSubject() ); - TemplateParser parser( msg, TemplateParser::Forward, false, false, false ); + TemplateParser parser( msg, TemplateParser::Forward, false, false ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { diff --git a/templateparser.cpp b/templateparser.cpp index 4963a0e8b..20320f5c3 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -54,11 +54,10 @@ using namespace KMail; TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, - bool asmartQuote, bool anoQuote, - bool aallowDecryption ) : + bool asmartQuote, bool anoQuote ) : mMode( amode ), mFolder( 0 ), mIdentity( 0 ), mSmartQuote( asmartQuote ), mNoQuote( anoQuote ), - mAllowDecryption( aallowDecryption ), + mAllowDecryption( false ), mDebug( false ), mQuoteString( "> " ), mAppend( false ), mOrigRoot( 0 ) { mMsg = amsg; @@ -69,6 +68,11 @@ void TemplateParser::setSelection( const QString &selection ) mSelection = selection; } +void TemplateParser::setAllowDecryption( const bool allowDecryption ) +{ + mAllowDecryption = allowDecryption; +} + TemplateParser::~TemplateParser() { delete mOrigRoot; diff --git a/templateparser.h b/templateparser.h index 56a149ca1..caf3b2cf5 100644 --- a/templateparser.h +++ b/templateparser.h @@ -67,7 +67,7 @@ class TemplateParser : public QObject public: TemplateParser( KMMessage *amsg, const Mode amode, - bool aSmartQuote, bool anoQuote, bool aallowDecryption ); + bool aSmartQuote, bool anoQuote ); ~TemplateParser(); /** @@ -78,6 +78,16 @@ class TemplateParser : public QObject */ void setSelection( const QString &selection ); + /** + * Sets whether the template parser is allowed to decrypt the original message when needing + * its message text, for example for the %QUOTE command. + * If true, it will tell the ObjectTreeParser it uses internally to decrypt the message, + * and that will possibly show a password request dialog to the user. + * + * The default is false. + */ + void setAllowDecryption( const bool allowDecryption ); + virtual void process( KMMessage *aorig_msg, KMFolder *afolder = 0, bool append = false ); virtual void process( const QString &tmplName, KMMessage *aorig_msg, KMFolder *afolder = 0, bool append = false ); From e4cc4e06404abaf19d853c328ff56b08421515da Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 08:41:20 +0000 Subject: [PATCH 116/160] Removed unused "NoQuote" parameter. MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1087507 --- kmcommands.cpp | 4 ++-- kmkernel.cpp | 12 ++++++------ kmmainwidget.cpp | 4 ++-- kmmessage.cpp | 4 ++-- templateparser.cpp | 12 ++++++------ templateparser.h | 5 +---- 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index d6610d58c..18cca59eb 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1247,7 +1247,7 @@ KMCommand::Result KMForwardInlineCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false ); + TemplateParser parser( fwdMsg, TemplateParser::Forward, false ); parser.setSelection( msg->body() ); parser.process( msg, 0, true ); @@ -1550,7 +1550,7 @@ KMCommand::Result KMCustomForwardCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, false, false ); + TemplateParser parser( fwdMsg, TemplateParser::Forward, false ); parser.setSelection( msg->body() ); parser.process( msg, 0, true ); diff --git a/kmkernel.cpp b/kmkernel.cpp index 2f10918bb..6ec9a7145 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -406,7 +406,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if( !str.isEmpty() ) { msg->setBody( QString::fromLocal8Bit( str ).utf8() ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, NULL ); } } @@ -416,7 +416,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, NULL ); } @@ -521,7 +521,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if ( !body.isEmpty() ) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, NULL ); } @@ -628,7 +628,7 @@ DCOPRef KMKernel::openComposer(const QString &to, const QString &cc, if (!body.isEmpty()) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, NULL ); } @@ -674,11 +674,11 @@ DCOPRef KMKernel::newMessage(const QString &to, if (!bcc.isEmpty()) msg->setBcc(bcc); if ( useFolderId ) { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, folder ); win = makeComposer( msg, id ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, folder ); win = makeComposer( msg ); } diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index 0367d9191..634867b47 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -991,12 +991,12 @@ void KMMainWidget::slotCompose() if ( mFolder ) { msg->initHeader( mFolder->identity() ); - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, mFolder ); win = KMail::makeComposer( msg, mFolder->identity() ); } else { msg->initHeader(); - TemplateParser parser( msg, TemplateParser::NewMessage, false, false ); + TemplateParser parser( msg, TemplateParser::NewMessage, false ); parser.process( NULL, NULL ); win = KMail::makeComposer( msg ); } diff --git a/kmmessage.cpp b/kmmessage.cpp index 62495a93d..a14897dc9 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -1069,7 +1069,7 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, formatString( GlobalSettings::self()->quoteString() ) ); if( !noQuote ) { TemplateParser parser( msg, ( replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply ), - sSmartQuote, noQuote ); + sSmartQuote ); parser.setAllowDecryption( allowDecryption ); parser.setSelection( selection ); if ( !tmpl.isEmpty() ) { @@ -1301,7 +1301,7 @@ KMMessage* KMMessage::createForward( const QString &tmpl /* = QString::null */ ) msg->setSubject( forwardSubject() ); - TemplateParser parser( msg, TemplateParser::Forward, false, false ); + TemplateParser parser( msg, TemplateParser::Forward, false ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { diff --git a/templateparser.cpp b/templateparser.cpp index 20320f5c3..8e368c364 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -54,9 +54,9 @@ using namespace KMail; TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, - bool asmartQuote, bool anoQuote ) : + bool asmartQuote ) : mMode( amode ), mFolder( 0 ), mIdentity( 0 ), - mSmartQuote( asmartQuote ), mNoQuote( anoQuote ), + mSmartQuote( asmartQuote ), mAllowDecryption( false ), mDebug( false ), mQuoteString( "> " ), mAppend( false ), mOrigRoot( 0 ) { @@ -300,7 +300,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) int len = parseQuotes( "QUOTEPIPE=", cmd, q ); i += len; QString pipe_cmd = q; - if ( mOrigMsg && !mNoQuote ) { + if ( mOrigMsg ) { QString str = pipe( pipe_cmd, messageText( false ) ); QString quote = mOrigMsg->asQuotedString( "", mQuoteString, str, mSmartQuote, mAllowDecryption ); @@ -310,7 +310,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) } else if ( cmd.startsWith( "QUOTE" ) ) { kdDebug() << "Command: QUOTE" << endl; i += strlen( "QUOTE" ); - if ( mOrigMsg && !mNoQuote ) { + if ( mOrigMsg ) { QString quote = mOrigMsg->asQuotedString( "", mQuoteString, messageText( true ), mSmartQuote, mAllowDecryption ); body.append( quote ); @@ -319,7 +319,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) } else if ( cmd.startsWith( "QHEADERS" ) ) { kdDebug() << "Command: QHEADERS" << endl; i += strlen( "QHEADERS" ); - if ( mOrigMsg && !mNoQuote ) { + if ( mOrigMsg ) { QString quote = mOrigMsg->asQuotedString( "", mQuoteString, mOrigMsg->headerAsSendableString(), mSmartQuote, false ); @@ -329,7 +329,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) } else if ( cmd.startsWith( "HEADERS" ) ) { kdDebug() << "Command: HEADERS" << endl; i += strlen( "HEADERS" ); - if ( mOrigMsg && !mNoQuote ) { + if ( mOrigMsg ) { QString str = mOrigMsg->headerAsSendableString(); body.append( str ); } diff --git a/templateparser.h b/templateparser.h index caf3b2cf5..a25e9b3f4 100644 --- a/templateparser.h +++ b/templateparser.h @@ -66,8 +66,7 @@ class TemplateParser : public QObject static const int PipeTimeout = 15; public: - TemplateParser( KMMessage *amsg, const Mode amode, - bool aSmartQuote, bool anoQuote ); + TemplateParser( KMMessage *amsg, const Mode amode, bool aSmartQuote ); ~TemplateParser(); /** @@ -117,9 +116,7 @@ class TemplateParser : public QObject KMMessage *mOrigMsg; QString mSelection; bool mSmartQuote; - bool mNoQuote; bool mAllowDecryption; - bool mSelectionIsBody; int mPipeRc; QString mPipeOut; QString mPipeErr; From d49067bb4fe7252ad66a645757d2020412b1f99d Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 09:31:39 +0000 Subject: [PATCH 117/160] Fix the confusion between smart quoting and stripping the signature: The template parser was using the variable "smartQuote" to determine whether to strip signatures. Remove that variable and the constructor parameter. Whether to smartQuote or not is determined by sSmartQuote in KMMessage anyway. For stripping the signature, don't do that when forwarding, and add an option to enable/disable signature stripping when replying. MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087515 --- kmail.kcfg | 4 ++++ kmcommands.cpp | 4 ++-- kmkernel.cpp | 12 ++++++------ kmmainwidget.cpp | 4 ++-- kmmessage.cpp | 5 ++--- templateparser.cpp | 18 +++++++++++------- templateparser.h | 9 +++++++-- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/kmail.kcfg b/kmail.kcfg index c5c16dd36..0e06c7949 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -450,6 +450,10 @@ true + + + true + diff --git a/kmcommands.cpp b/kmcommands.cpp index 18cca59eb..e84ec25f1 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1247,7 +1247,7 @@ KMCommand::Result KMForwardInlineCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, false ); + TemplateParser parser( fwdMsg, TemplateParser::Forward ); parser.setSelection( msg->body() ); parser.process( msg, 0, true ); @@ -1550,7 +1550,7 @@ KMCommand::Result KMCustomForwardCommand::execute() // fwdMsg->setBody( msgText ); for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { - TemplateParser parser( fwdMsg, TemplateParser::Forward, false ); + TemplateParser parser( fwdMsg, TemplateParser::Forward ); parser.setSelection( msg->body() ); parser.process( msg, 0, true ); diff --git a/kmkernel.cpp b/kmkernel.cpp index 6ec9a7145..9566b2d14 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -406,7 +406,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if( !str.isEmpty() ) { msg->setBody( QString::fromLocal8Bit( str ).utf8() ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, NULL ); } } @@ -416,7 +416,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, NULL ); } @@ -521,7 +521,7 @@ int KMKernel::openComposer (const QString &to, const QString &cc, if ( !body.isEmpty() ) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, NULL ); } @@ -628,7 +628,7 @@ DCOPRef KMKernel::openComposer(const QString &to, const QString &cc, if (!body.isEmpty()) { msg->setBody(body.utf8()); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, NULL ); } @@ -674,11 +674,11 @@ DCOPRef KMKernel::newMessage(const QString &to, if (!bcc.isEmpty()) msg->setBcc(bcc); if ( useFolderId ) { - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, folder ); win = makeComposer( msg, id ); } else { - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, folder ); win = makeComposer( msg ); } diff --git a/kmmainwidget.cpp b/kmmainwidget.cpp index 634867b47..34efd13e7 100644 --- a/kmmainwidget.cpp +++ b/kmmainwidget.cpp @@ -991,12 +991,12 @@ void KMMainWidget::slotCompose() if ( mFolder ) { msg->initHeader( mFolder->identity() ); - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, mFolder ); win = KMail::makeComposer( msg, mFolder->identity() ); } else { msg->initHeader(); - TemplateParser parser( msg, TemplateParser::NewMessage, false ); + TemplateParser parser( msg, TemplateParser::NewMessage ); parser.process( NULL, NULL ); win = KMail::makeComposer( msg ); } diff --git a/kmmessage.cpp b/kmmessage.cpp index a14897dc9..715f49736 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -1068,8 +1068,7 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, msg->setHeaderField( "X-KMail-QuotePrefix", formatString( GlobalSettings::self()->quoteString() ) ); if( !noQuote ) { - TemplateParser parser( msg, ( replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply ), - sSmartQuote ); + TemplateParser parser( msg, ( replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply ) ); parser.setAllowDecryption( allowDecryption ); parser.setSelection( selection ); if ( !tmpl.isEmpty() ) { @@ -1301,7 +1300,7 @@ KMMessage* KMMessage::createForward( const QString &tmpl /* = QString::null */ ) msg->setSubject( forwardSubject() ); - TemplateParser parser( msg, TemplateParser::Forward, false ); + TemplateParser parser( msg, TemplateParser::Forward ); if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { diff --git a/templateparser.cpp b/templateparser.cpp index 8e368c364..23055cbb0 100644 --- a/templateparser.cpp +++ b/templateparser.cpp @@ -53,10 +53,8 @@ using namespace KMail; -TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode, - bool asmartQuote ) : +TemplateParser::TemplateParser( KMMessage *amsg, const Mode amode ) : mMode( amode ), mFolder( 0 ), mIdentity( 0 ), - mSmartQuote( asmartQuote ), mAllowDecryption( false ), mDebug( false ), mQuoteString( "> " ), mAppend( false ), mOrigRoot( 0 ) { @@ -73,6 +71,12 @@ void TemplateParser::setAllowDecryption( const bool allowDecryption ) mAllowDecryption = allowDecryption; } +bool TemplateParser::shouldStripSignature() const +{ + // Only strip the signature when replying, it should be preserved when forwarding + return ( mMode == Reply || mMode == ReplyAll) && GlobalSettings::stripSignature(); +} + TemplateParser::~TemplateParser() { delete mOrigRoot; @@ -303,7 +307,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) if ( mOrigMsg ) { QString str = pipe( pipe_cmd, messageText( false ) ); QString quote = mOrigMsg->asQuotedString( "", mQuoteString, str, - mSmartQuote, mAllowDecryption ); + shouldStripSignature(), mAllowDecryption ); body.append( quote ); } @@ -312,7 +316,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) i += strlen( "QUOTE" ); if ( mOrigMsg ) { QString quote = mOrigMsg->asQuotedString( "", mQuoteString, messageText( true ), - mSmartQuote, mAllowDecryption ); + shouldStripSignature(), mAllowDecryption ); body.append( quote ); } @@ -322,7 +326,7 @@ void TemplateParser::processWithTemplate( const QString &tmpl ) if ( mOrigMsg ) { QString quote = mOrigMsg->asQuotedString( "", mQuoteString, mOrigMsg->headerAsSendableString(), - mSmartQuote, false ); + false, false ); body.append( quote ); } @@ -872,7 +876,7 @@ QString TemplateParser::messageText( bool allowSelectionOnly ) // No selection text, therefore we need to parse the object tree ourselves to get partNode *root = parsedObjectTree(); - return mOrigMsg->asPlainTextFromObjectTree( root, mSmartQuote, mAllowDecryption ); + return mOrigMsg->asPlainTextFromObjectTree( root, shouldStripSignature(), mAllowDecryption ); } partNode* TemplateParser::parsedObjectTree() diff --git a/templateparser.h b/templateparser.h index a25e9b3f4..d1cae8bdc 100644 --- a/templateparser.h +++ b/templateparser.h @@ -66,7 +66,7 @@ class TemplateParser : public QObject static const int PipeTimeout = 15; public: - TemplateParser( KMMessage *amsg, const Mode amode, bool aSmartQuote ); + TemplateParser( KMMessage *amsg, const Mode amode ); ~TemplateParser(); /** @@ -115,7 +115,6 @@ class TemplateParser : public QObject KMMessage *mMsg; KMMessage *mOrigMsg; QString mSelection; - bool mSmartQuote; bool mAllowDecryption; int mPipeRc; QString mPipeOut; @@ -153,6 +152,12 @@ class TemplateParser : public QObject */ void addProcessedBodyToMessage( const QString &body ); + /** + * Determines whether the signature should be stripped when getting the text of the original + * message, e.g. for commands such as %QUOTE + */ + bool shouldStripSignature() const; + int parseQuotes( const QString &prefix, const QString &str, QString "e ) const; From a3fe0f0d2b858bcc45d5ad96b44ec58440fd4a20 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 09:50:05 +0000 Subject: [PATCH 118/160] Add a tooltip for kolab/issue4097. MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087518 --- configuredialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configuredialog.cpp b/configuredialog.cpp index 51d47a8ef..1fd7c0464 100644 --- a/configuredialog.cpp +++ b/configuredialog.cpp @@ -2618,6 +2618,10 @@ ComposerPageGeneralTab::ComposerPageGeneralTab( QWidget * parent, const char * n mSmartQuoteCheck = new QCheckBox( GlobalSettings::self()->smartQuoteItem()->label(), this, "kcfg_SmartQuote" ); + QToolTip::add( mSmartQuoteCheck, + i18n( "When replying, add quote signs in front of all lines of the quoted text,\n" + "even when the line was created by adding an additional linebreak while\n" + "word-wrapping the text." ) ); vlay->addWidget( mSmartQuoteCheck ); connect( mSmartQuoteCheck, SIGNAL( stateChanged(int) ), this, SLOT( slotEmitChanged( void ) ) ); From 708a2fcc5dd18d4e5c6630e45e4814d47a0537eb Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 10:17:28 +0000 Subject: [PATCH 119/160] Add GUI setting for stripping the signature. Related to kolab/issue4097 svn path=/branches/kdepim/enterprise/kdepim/; revision=1087534 --- configuredialog.cpp | 10 ++++++++++ configuredialog_p.h | 1 + 2 files changed, 11 insertions(+) diff --git a/configuredialog.cpp b/configuredialog.cpp index 1fd7c0464..b9857a102 100644 --- a/configuredialog.cpp +++ b/configuredialog.cpp @@ -2626,6 +2626,12 @@ ComposerPageGeneralTab::ComposerPageGeneralTab( QWidget * parent, const char * n connect( mSmartQuoteCheck, SIGNAL( stateChanged(int) ), this, SLOT( slotEmitChanged( void ) ) ); + mStripSignatureCheck = new QCheckBox( GlobalSettings::self()->stripSignatureItem()->label(), + this, "kcfg_StripSignature" ); + vlay->addWidget( mStripSignatureCheck ); + connect( mStripSignatureCheck, SIGNAL( stateChanged(int) ), + this, SLOT( slotEmitChanged( void ) ) ); + mAutoRequestMDNCheck = new QCheckBox( GlobalSettings::self()->requestMDNItem()->label(), this, "kcfg_RequestMDN" ); @@ -2787,6 +2793,7 @@ void ComposerPage::GeneralTab::doLoadFromGlobalSettings() { GlobalSettings::self()->autoTextSignature()=="auto" ); mTopQuoteCheck->setChecked( GlobalSettings::self()->prependSignature() ); mSmartQuoteCheck->setChecked( GlobalSettings::self()->smartQuote() ); + mStripSignatureCheck->setChecked( GlobalSettings::self()->stripSignature() ); mAutoRequestMDNCheck->setChecked( GlobalSettings::self()->requestMDN() ); mWordWrapCheck->setChecked( GlobalSettings::self()->wordWrap() ); @@ -2816,6 +2823,8 @@ void ComposerPage::GeneralTab::installProfile( KConfig * profile ) { mTopQuoteCheck->setChecked( composer.readBoolEntry( "prepend-signature" ) ); if ( composer.hasKey( "smart-quote" ) ) mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote" ) ); + if ( composer.hasKey( "StripSignature" ) ) + mStripSignatureCheck->setChecked( composer.readBoolEntry( "StripSignature" ) ); if ( composer.hasKey( "request-mdn" ) ) mAutoRequestMDNCheck->setChecked( composer.readBoolEntry( "request-mdn" ) ); if ( composer.hasKey( "word-wrap" ) ) @@ -2841,6 +2850,7 @@ void ComposerPage::GeneralTab::save() { mAutoAppSignFileCheck->isChecked() ? "auto" : "manual" ); GlobalSettings::self()->setPrependSignature( mTopQuoteCheck->isChecked()); GlobalSettings::self()->setSmartQuote( mSmartQuoteCheck->isChecked() ); + GlobalSettings::self()->setStripSignature( mStripSignatureCheck->isChecked() ); GlobalSettings::self()->setRequestMDN( mAutoRequestMDNCheck->isChecked() ); GlobalSettings::self()->setWordWrap( mWordWrapCheck->isChecked() ); diff --git a/configuredialog_p.h b/configuredialog_p.h index 78ab1e7b9..d7fcb9727 100644 --- a/configuredialog_p.h +++ b/configuredialog_p.h @@ -611,6 +611,7 @@ private: QCheckBox *mAutoAppSignFileCheck; QCheckBox *mTopQuoteCheck; QCheckBox *mSmartQuoteCheck; + QCheckBox *mStripSignatureCheck; QCheckBox *mAutoRequestMDNCheck; QCheckBox *mShowRecentAddressesInComposer; QCheckBox *mWordWrapCheck; From 45da79d15e4555f980bdb1272835fe8d0d8cc85f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 10:22:52 +0000 Subject: [PATCH 120/160] Add fixme SVN_SILENT MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087535 --- kmcommands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmcommands.cpp b/kmcommands.cpp index e84ec25f1..865e69ef0 100644 --- a/kmcommands.cpp +++ b/kmcommands.cpp @@ -1248,7 +1248,7 @@ KMCommand::Result KMForwardInlineCommand::execute() for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { TemplateParser parser( fwdMsg, TemplateParser::Forward ); - parser.setSelection( msg->body() ); + parser.setSelection( msg->body() ); // FIXME: Why is this needed? parser.process( msg, 0, true ); fwdMsg->link( msg, KMMsgStatusForwarded ); @@ -1551,7 +1551,7 @@ KMCommand::Result KMCustomForwardCommand::execute() for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) { TemplateParser parser( fwdMsg, TemplateParser::Forward ); - parser.setSelection( msg->body() ); + parser.setSelection( msg->body() ); // FIXME: Why is this needed? parser.process( msg, 0, true ); fwdMsg->link( msg, KMMsgStatusForwarded ); From 2a26c11a45bf6dcfd16328438acd9c14c0181143 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 10:32:47 +0000 Subject: [PATCH 121/160] Add hidden option to disable quoting only the partial message when some text is selected. GUI option will follow in a minute. BUG: 218609 kolab/issue4097 svn path=/branches/kdepim/enterprise/kdepim/; revision=1087537 --- kmail.kcfg | 6 +++++- kmmessage.cpp | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/kmail.kcfg b/kmail.kcfg index 0e06c7949..3afcf05ec 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -451,7 +451,11 @@ true - + + true + + + true diff --git a/kmmessage.cpp b/kmmessage.cpp index 715f49736..f30c86167 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -1070,7 +1070,9 @@ KMMessage* KMMessage::createReply( KMail::ReplyStrategy replyStrategy, if( !noQuote ) { TemplateParser parser( msg, ( replyAll ? TemplateParser::ReplyAll : TemplateParser::Reply ) ); parser.setAllowDecryption( allowDecryption ); - parser.setSelection( selection ); + if ( GlobalSettings::quoteSelectionOnly() ) { + parser.setSelection( selection ); + } if ( !tmpl.isEmpty() ) { parser.process( tmpl, this ); } else { From a5fd16d0dfafa87eaa719b967bd5ba08b1aa6b11 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 10:43:24 +0000 Subject: [PATCH 122/160] Add GUI option to disable quoting only the selected text. kolab/issue4097 CCBUG: 218609 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1087540 --- configuredialog.cpp | 13 +++++++++++++ configuredialog_p.h | 1 + 2 files changed, 14 insertions(+) diff --git a/configuredialog.cpp b/configuredialog.cpp index b9857a102..b67bbf1ee 100644 --- a/configuredialog.cpp +++ b/configuredialog.cpp @@ -2626,6 +2626,15 @@ ComposerPageGeneralTab::ComposerPageGeneralTab( QWidget * parent, const char * n connect( mSmartQuoteCheck, SIGNAL( stateChanged(int) ), this, SLOT( slotEmitChanged( void ) ) ); + mQuoteSelectionOnlyCheck = new QCheckBox( GlobalSettings::self()->quoteSelectionOnlyItem()->label(), + this, "kcfg_QuoteSelectionOnly" ); + QToolTip::add( mQuoteSelectionOnlyCheck, + i18n( "When replying, only quote the selected text instead of the complete message " + "when there is text selected in the message window." ) ); + vlay->addWidget( mQuoteSelectionOnlyCheck ); + connect( mQuoteSelectionOnlyCheck, SIGNAL( stateChanged(int) ), + this, SLOT( slotEmitChanged(void) ) ); + mStripSignatureCheck = new QCheckBox( GlobalSettings::self()->stripSignatureItem()->label(), this, "kcfg_StripSignature" ); vlay->addWidget( mStripSignatureCheck ); @@ -2793,6 +2802,7 @@ void ComposerPage::GeneralTab::doLoadFromGlobalSettings() { GlobalSettings::self()->autoTextSignature()=="auto" ); mTopQuoteCheck->setChecked( GlobalSettings::self()->prependSignature() ); mSmartQuoteCheck->setChecked( GlobalSettings::self()->smartQuote() ); + mQuoteSelectionOnlyCheck->setChecked( GlobalSettings::self()->quoteSelectionOnly() ); mStripSignatureCheck->setChecked( GlobalSettings::self()->stripSignature() ); mAutoRequestMDNCheck->setChecked( GlobalSettings::self()->requestMDN() ); mWordWrapCheck->setChecked( GlobalSettings::self()->wordWrap() ); @@ -2825,6 +2835,8 @@ void ComposerPage::GeneralTab::installProfile( KConfig * profile ) { mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote" ) ); if ( composer.hasKey( "StripSignature" ) ) mStripSignatureCheck->setChecked( composer.readBoolEntry( "StripSignature" ) ); + if ( composer.hasKey( "QuoteSelectionOnly" ) ) + mQuoteSelectionOnlyCheck->setChecked( composer.readBoolEntry( "QuoteSelectionOnly" ) ); if ( composer.hasKey( "request-mdn" ) ) mAutoRequestMDNCheck->setChecked( composer.readBoolEntry( "request-mdn" ) ); if ( composer.hasKey( "word-wrap" ) ) @@ -2850,6 +2862,7 @@ void ComposerPage::GeneralTab::save() { mAutoAppSignFileCheck->isChecked() ? "auto" : "manual" ); GlobalSettings::self()->setPrependSignature( mTopQuoteCheck->isChecked()); GlobalSettings::self()->setSmartQuote( mSmartQuoteCheck->isChecked() ); + GlobalSettings::self()->setQuoteSelectionOnly( mQuoteSelectionOnlyCheck->isChecked() ); GlobalSettings::self()->setStripSignature( mStripSignatureCheck->isChecked() ); GlobalSettings::self()->setRequestMDN( mAutoRequestMDNCheck->isChecked() ); GlobalSettings::self()->setWordWrap( mWordWrapCheck->isChecked() ); diff --git a/configuredialog_p.h b/configuredialog_p.h index d7fcb9727..8a4d42af9 100644 --- a/configuredialog_p.h +++ b/configuredialog_p.h @@ -612,6 +612,7 @@ private: QCheckBox *mTopQuoteCheck; QCheckBox *mSmartQuoteCheck; QCheckBox *mStripSignatureCheck; + QCheckBox *mQuoteSelectionOnlyCheck; QCheckBox *mAutoRequestMDNCheck; QCheckBox *mShowRecentAddressesInComposer; QCheckBox *mWordWrapCheck; From 15f12ef3e49500f298455ada2a89714f1f0465d7 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Feb 2010 12:04:51 +0000 Subject: [PATCH 123/160] When double-clicking in the composer, only select the word under the cursor, and not any special chars like parenthesis. kolab/issue4089 MERGE: none (handled correctly be QTextEdit in Qt4) svn path=/branches/kdepim/enterprise/kdepim/; revision=1087635 --- kmedit.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ kmedit.h | 6 +++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/kmedit.cpp b/kmedit.cpp index 3afb280c0..63db5bfb7 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -621,6 +621,54 @@ void KMEdit::contentsMouseReleaseEvent( QMouseEvent * e ) mPasteMode = QClipboard::Clipboard; } +void KMEdit::contentsMouseDoubleClickEvent( QMouseEvent *e ) +{ + bool handled = false; + if ( e->button() == Qt::LeftButton ) { + + // Get the cursor position for the place where the user clicked to + int paragraphPos; + int charPos = charAt ( e->pos(), ¶graphPos ); + QString paraText = text( paragraphPos ); + + // Now select the word under the cursor + if ( charPos >= 0 && static_cast( charPos ) <= paraText.length() ) { + + // Start the selection where the user clicked + int start = charPos; + unsigned int end = charPos; + + // Extend the selection to the left, until we reach a non-letter and non-digit char + for (;;) { + if ( ( start - 1 ) < 0 ) + break; + QChar charToTheLeft = paraText.at( start - 1 ); + if ( charToTheLeft.isLetter() || charToTheLeft.isDigit() ) + start--; + else + break; + } + + // Extend the selection to the left, until we reach a non-letter and non-digit char + for (;;) { + if ( ( end + 1 ) >= paraText.length() ) + break; + QChar charToTheRight = paraText.at( end + 1 ); + if ( charToTheRight.isLetter() || charToTheRight.isDigit() ) + end++; + else + break; + } + + setSelection( paragraphPos, start, paragraphPos, end + 1 ); + handled = true; + } + } + + if ( !handled ) + return KEdit::contentsMouseDoubleClickEvent( e ); +} + void KMEdit::slotMisspelling(const QString &text, const QStringList &lst, unsigned int pos) { kdDebug(5006)<<"void KMEdit::slotMisspelling(const QString &text, const QStringList &lst, unsigned int pos) : "< Date: Tue, 9 Feb 2010 17:50:15 +0000 Subject: [PATCH 124/160] Remove the quotes and the backslash when displaying the email address in the reader. with the help of KPIM::getNameAndMail(). kolab/issue2524 svn path=/branches/kdepim/enterprise/kdepim/; revision=1087876 --- kmmessage.cpp | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/kmmessage.cpp b/kmmessage.cpp index f30c86167..1d1106f0d 100644 --- a/kmmessage.cpp +++ b/kmmessage.cpp @@ -3835,24 +3835,44 @@ QString KMMessage::emailAddrAsAnchor(const QString& aEmail, bool stripped, const return aEmail; QStringList addressList = KPIM::splitEmailAddrList( aEmail ); - QString result; for( QStringList::ConstIterator it = addressList.begin(); ( it != addressList.end() ); ++it ) { if( !(*it).isEmpty() ) { - QString address = *it; + + // Extract the name, mail and some pretty versions out of the mail address + QString name, mail; + KPIM::getNameAndMail( *it, name, mail ); + QString prettyAndQuoted; + QString pretty; + QString prettyStripped; + if ( name.stripWhiteSpace().isEmpty() ) { + prettyAndQuoted = mail; + pretty = mail; + prettyStripped = mail; + } else { + prettyAndQuoted = "\"" + name + "\" <" + mail + ">"; + pretty = name + " <" + mail + ">"; + prettyStripped = name; + } + if(aLink) { - result += ""; + result += ""; } - if( stripped ) - address = KMMessage::stripEmailAddr( address ); - result += KMMessage::quoteHtmlChars( address, true ); + + if ( stripped ) { + result += KMMessage::quoteHtmlChars( prettyStripped, true ); + } + else { + result += KMMessage::quoteHtmlChars( pretty, true ); + } + if(aLink) - result += ", "; + result += ", "; } } // cut of the trailing ", " @@ -3864,7 +3884,6 @@ QString KMMessage::emailAddrAsAnchor(const QString& aEmail, bool stripped, const return result; } - //----------------------------------------------------------------------------- //static QStringList KMMessage::stripAddressFromAddressList( const QString& address, From 1b5fa5e729522b89e08f4a54b7e15ed3eaee52a0 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 12 Feb 2010 11:41:11 +0000 Subject: [PATCH 125/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1089096 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 381ee226b..def69faf0 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1085672)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1089095)" #endif /*kmversion_h*/ From 418360f83b03e320d63861de1591f46a06e19244 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Sat, 13 Feb 2010 18:59:58 +0000 Subject: [PATCH 126/160] backport SVN commit 1089579 by coles: Corrected typo: repyl -> reply. MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1089694 --- kmail.kcfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmail.kcfg b/kmail.kcfg index 3afcf05ec..cb804d5ff 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -455,7 +455,7 @@ true - + true From e33b08fa8df2450b97dd4b07ca6f1936a21ea8b4 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Wed, 17 Feb 2010 13:46:58 +0000 Subject: [PATCH 127/160] merge SVN commit 1091742 by mlaurent: Fix bug #KONT-81 When we make a search and open search folder, and re make a search we don't want to rename it and lose previous search kolab/issue2079 MERGE: none (already in trunk) svn path=/branches/kdepim/enterprise/kdepim/; revision=1091758 --- searchwindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/searchwindow.cpp b/searchwindow.cpp index 2767cc67c..bb6306ad5 100644 --- a/searchwindow.cpp +++ b/searchwindow.cpp @@ -181,7 +181,6 @@ SearchWindow::SearchWindow(KMMainWidget* w, const char* name, } else { mChkbxAllFolders->setChecked(true); } - mFolder = searchFolder; } mPatternEdit->setSearchPattern( mSearchPattern ); QObjectList *list = mPatternEdit->queryList( 0, "mRuleField" ); From 44aa6800e650ca83f17979441ccad06c03d83509 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 19 Feb 2010 17:02:37 +0000 Subject: [PATCH 128/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1092866 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index def69faf0..d013eb0d9 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100101.1089095)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100219.1092865)" #endif /*kmversion_h*/ From bdeb7e05d91fb35ab34a18994d795c75bbdb5cd3 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 23 Feb 2010 08:14:59 +0000 Subject: [PATCH 129/160] Crossport r1093923 by tmcguire from the KDE 4.4 branch to the enterprise35 branch: Don't remove the autosave file after recovering. It will be properly cleaned up in cleanupAutoSave() anyway, which is only called after successful sending or saving as draft. This fixes mail loss when KMail crashes before the first autosave kicks in, after recovering a message. CCBUG: 159634 MERGE: 3.5, trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1094756 --- kmcomposewin.cpp | 3 --- kmkernel.cpp | 41 ++++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 101150675..909efb71d 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -5002,9 +5002,6 @@ void KMComposeWin::updateAutoSave() void KMComposeWin::setAutoSaveFilename( const QString & filename ) { - if ( !mAutoSaveFilename.isEmpty() ) - KMFolderMaildir::removeFile( KMKernel::localDataPath() + "autosave", - mAutoSaveFilename ); mAutoSaveFilename = filename; } diff --git a/kmkernel.cpp b/kmkernel.cpp index 9566b2d14..85bcb5b6f 100644 --- a/kmkernel.cpp +++ b/kmkernel.cpp @@ -1379,27 +1379,34 @@ void KMKernel::testDir(const char *_name) // Open a composer for each message found in the dead.letter folder void KMKernel::recoverDeadLetters() { - const QString pathName = localDataPath(); - QDir dir( pathName ); - if ( !dir.exists( "autosave" ) ) - return; - - KMFolder folder( 0, pathName + "autosave", KMFolderTypeMaildir, false /* no index */ ); - KMFolderOpener openFolder( &folder, "recover" ); - if ( !folder.isOpened() ) { - perror( "cannot open autosave folder" ); + QDir dir( localDataPath() + "autosave/cur" ); + if ( !dir.exists() ) { + kdWarning(5006) << "Autosave directory " << dir.path() << " not found!" << endl; return; } - const int num = folder.count(); - for ( int i = 0; i < num; i++ ) { - KMMessage *msg = folder.take( 0 ); - if ( msg ) { - KMail::Composer * win = KMail::makeComposer(); - win->setMsg( msg, false, false, true ); - win->setAutoSaveFilename( msg->fileName() ); - win->show(); + const QStringList entryList = dir.entryList( QDir::Files | QDir::NoSymLinks, QDir::Unsorted ); + for ( unsigned int i = 0; i < entryList.size(); i++ ) { + const QString fileName = entryList[i]; + QFile file( dir.path() + '/' + fileName ); + if ( !file.open( IO_ReadOnly ) ) { + kdWarning(5006) << "Unable to open autosave file " << fileName << endl; + continue; + } + const QByteArray msgData = file.readAll(); + file.close(); + + if ( msgData.isEmpty() ) { + kdWarning(5006) << "autosave file " << fileName << " is empty!" << endl; + continue; } + + KMMessage *msg = new KMMessage(); // Composer will take ownership + msg->fromByteArray( msgData ); + KMail::Composer * win = KMail::makeComposer(); + win->setMsg( msg, false, false, true ); + win->setAutoSaveFilename( fileName ); + win->show(); } } From 56a5352c96f72d211ad6bafc54635fe855d0da35 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 23 Feb 2010 16:58:22 +0000 Subject: [PATCH 130/160] Add "add to dictionary" and "ignore all" to the context menu of misspelled words. kolab/issue4060 svn path=/branches/kdepim/enterprise/kdepim/; revision=1095107 --- kmedit.cpp | 129 +++++++++++++++++++++++++++++++++++++++++------------ kmedit.h | 61 +++++++++++++++++++++++-- 2 files changed, 158 insertions(+), 32 deletions(-) diff --git a/kmedit.cpp b/kmedit.cpp index 63db5bfb7..e5c10e12c 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -214,7 +214,7 @@ KMEdit::KMEdit(QWidget *parent, KMComposeWin* composer, const char *name) : KEdit( parent, name ), mComposer( composer ), - mKSpell( 0 ), + mKSpellForDialog( 0 ), mSpellConfig( autoSpellConfig ), mSpellingFilter( 0 ), mExtEditorTempFile( 0 ), @@ -230,6 +230,9 @@ KMEdit::KMEdit(QWidget *parent, KMComposeWin* composer, installEventFilter(this); KCursor::setAutoHideCursor( this, true, true ); setOverwriteEnabled( true ); + mSpeller = new KMSpell( this, SLOT( spellerReady( KSpell * ) ) ); + connect( mSpeller, SIGNAL( death() ), + this, SLOT( spellerDied() ) ); } @@ -253,12 +256,12 @@ void KMEdit::initializeAutoSpellChecking() QColor col3 = readerConfig.readColorEntry( "QuotedText2", &defaultColor2 ); QColor col4 = readerConfig.readColorEntry( "QuotedText1", &defaultColor1 ); QColor misspelled = readerConfig.readColorEntry( "MisspelledColor", &c ); - mSpellChecker = new KDictSpellingHighlighter( this, /*active*/ true, - /*autoEnabled*/ false, - /*spellColor*/ misspelled, - /*colorQuoting*/ true, - col1, col2, col3, col4, - mSpellConfig ); + mSpellChecker = new KMSyntaxHighter( this, /*active*/ true, + /*autoEnabled*/ false, + /*spellColor*/ misspelled, + /*colorQuoting*/ true, + col1, col2, col3, col4, + mSpellConfig ); connect( mSpellChecker, SIGNAL(newSuggestions(const QString&, const QStringList&, unsigned int)), this, SLOT(addSuggestion(const QString&, const QStringList&, unsigned int)) ); @@ -301,10 +304,16 @@ KMEdit::~KMEdit() { removeEventFilter(this); - delete mKSpell; + if ( mSpeller ) { + // The speller needs some time to clean up, so trigger cleanup and let it delete itself + mSpeller->setAutoDelete( true ); + mSpeller->cleanUp(); + mSpeller = 0; + } + + delete mKSpellForDialog; delete mSpellChecker; mSpellChecker = 0; - } @@ -344,6 +353,50 @@ unsigned int KMEdit::lineBreakColumn() const return lineBreakColumn; } +KMSpell::KMSpell( QObject *receiver, const char *slot ) + : KSpell( 0, QString(), receiver, slot ) +{ +} + +KMSyntaxHighter::KMSyntaxHighter( QTextEdit *textEdit, + bool spellCheckingActive, + bool autoEnable, + const QColor& spellColor, + bool colorQuoting, + const QColor& QuoteColor0, + const QColor& QuoteColor1, + const QColor& QuoteColor2, + const QColor& QuoteColor3, + KSpellConfig *spellConfig ) + : KDictSpellingHighlighter( textEdit, spellCheckingActive, autoEnable, spellColor, colorQuoting, + QuoteColor0, QuoteColor1, QuoteColor2, QuoteColor3, spellConfig ) +{ +} + +bool KMSyntaxHighter::isMisspelled( const QString &word ) +{ + if ( mIgnoredWords.contains( word ) ) { + return false; + } + else { + return KDictSpellingHighlighter::isMisspelled( word ); + } +} + +void KMSyntaxHighter::ignoreWord( const QString &word ) +{ + mIgnoredWords << word; +} + +void KMEdit::spellerDied() +{ + mSpeller = 0; +} + +void KMEdit::spellerReady( KSpell *spell ) +{ + Q_ASSERT( mSpeller == spell ); +} bool KMEdit::eventFilter(QObject*o, QEvent* e) { @@ -440,7 +493,6 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) if( !word.isEmpty() && mReplacements.contains( word ) ) { KPopupMenu p; - p.insertTitle( i18n("Suggestions") ); //Add the suggestions to the popup menu QStringList reps = mReplacements[word]; @@ -454,13 +506,34 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) } else { - p.insertItem( i18n( "No Suggestions" ), -2 ); + p.setItemEnabled( p.insertItem( i18n( "No Suggestions" ), -2 ), false ); + } + + int addToDictionaryId = -42; + int ignoreId = -43; + if ( mSpeller && mSpeller->status() == KSpell::Running ) { + p.insertSeparator(); + addToDictionaryId = p.insertItem( i18n( "Add to Dictionary" ) ); + ignoreId = p.insertItem( i18n( "Ignore All" ) ); } //Execute the popup inline - int id = p.exec( mapToGlobal( event->pos() ) ); + const int id = p.exec( mapToGlobal( event->pos() ) ); - if( id > -1 ) + if ( id == ignoreId ) { + mSpellChecker->ignoreWord( word ); + mSpellChecker->rehighlight(); + } + if ( id == addToDictionaryId ) { + mSpeller->addPersonal( word ); + mSpeller->writePersonalDictionary(); + if ( mSpellChecker ) { + // Wait a bit until reloading the highlighter, the mSpeller first needs to finish saving + // the personal word list. + QTimer::singleShot( 200, mSpellChecker, SLOT( slotLocalSpellConfigChanged() ) ); + } + } + else if( id > -1 ) { //Save the cursor position int parIdx = 1, txtIdx = 1; @@ -552,32 +625,32 @@ bool KMEdit::checkExternalEditorFinished() { void KMEdit::spellcheck() { - if ( mKSpell ) + if ( mKSpellForDialog ) return; mWasModifiedBeforeSpellCheck = isModified(); mSpellLineEdit = !mSpellLineEdit; // maybe for later, for now plaintext is given to KSpell // if (textFormat() == Qt::RichText ) { // kdDebug(5006) << "KMEdit::spellcheck, spellchecking for RichText" << endl; -// mKSpell = new KSpell(this, i18n("Spellcheck - KMail"), this, +// mKSpellForDialog = new KSpell(this, i18n("Spellcheck - KMail"), this, // SLOT(slotSpellcheck2(KSpell*)),0,true,false,KSpell::HTML); // } // else { - mKSpell = new KSpell(this, i18n("Spellcheck - KMail"), this, + mKSpellForDialog = new KSpell(this, i18n("Spellcheck - KMail"), this, SLOT(slotSpellcheck2(KSpell*))); // } QStringList l = KSpellingHighlighter::personalWords(); for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) { - mKSpell->addPersonal( *it ); + mKSpellForDialog->addPersonal( *it ); } - connect (mKSpell, SIGNAL( death()), + connect (mKSpellForDialog, SIGNAL( death()), this, SLOT (slotSpellDone())); - connect (mKSpell, SIGNAL (misspelling (const QString &, const QStringList &, unsigned int)), + connect (mKSpellForDialog, SIGNAL (misspelling (const QString &, const QStringList &, unsigned int)), this, SLOT (slotMisspelling (const QString &, const QStringList &, unsigned int))); - connect (mKSpell, SIGNAL (corrected (const QString &, const QString &, unsigned int)), + connect (mKSpellForDialog, SIGNAL (corrected (const QString &, const QString &, unsigned int)), this, SLOT (slotCorrected (const QString &, const QString &, unsigned int))); - connect (mKSpell, SIGNAL (done(const QString &)), + connect (mKSpellForDialog, SIGNAL (done(const QString &)), this, SLOT (slotSpellResult (const QString&))); } @@ -731,10 +804,10 @@ void KMEdit::slotSpellcheck2(KSpell*) mSpellingFilter = new SpellingFilter(plaintext.text(), quotePrefix, SpellingFilter::FilterUrls, SpellingFilter::FilterEmailAddresses); - mKSpell->check(mSpellingFilter->filteredText()); + mKSpellForDialog->check(mSpellingFilter->filteredText()); } else if( mComposer ) - mKSpell->check( mComposer->sujectLineWidget()->text()); + mKSpellForDialog->check( mComposer->sujectLineWidget()->text()); } void KMEdit::slotSpellResult(const QString &s) @@ -742,7 +815,7 @@ void KMEdit::slotSpellResult(const QString &s) if( !mSpellLineEdit) spellcheck_stop(); - int dlgResult = mKSpell->dlgResult(); + int dlgResult = mKSpellForDialog->dlgResult(); if ( dlgResult == KS_CANCEL ) { if( mSpellLineEdit) @@ -760,7 +833,7 @@ void KMEdit::slotSpellResult(const QString &s) setModified(true); } } - mKSpell->cleanUp(); + mKSpellForDialog->cleanUp(); KDictSpellingHighlighter::dictionaryChanged(); emit spellcheck_done( dlgResult ); @@ -769,9 +842,9 @@ void KMEdit::slotSpellResult(const QString &s) void KMEdit::slotSpellDone() { kdDebug(5006)<<" void KMEdit::slotSpellDone()\n"; - KSpell::spellStatus status = mKSpell->status(); - delete mKSpell; - mKSpell = 0; + KSpell::spellStatus status = mKSpellForDialog->status(); + delete mKSpellForDialog; + mKSpellForDialog = 0; kdDebug(5006) << "spelling: delete SpellingFilter" << endl; delete mSpellingFilter; diff --git a/kmedit.h b/kmedit.h index 2d3b4aa15..49e80a55e 100644 --- a/kmedit.h +++ b/kmedit.h @@ -7,20 +7,59 @@ #include #include +#include +#include #include #include #include class KMComposeWin; class KSpellConfig; -class KSpell; class SpellingFilter; class KTempFile; -class KDictSpellingHighlighter; class KDirWatch; class KProcess; class QPopupMenu; +/** + * Reimplemented to make writePersonalDictionary() public, which we call everytime after + * adding a word to the dictionary (for safety's sake and because the highlighter needs to reload + * the personal word list, and for that, it needs to be written to disc) + */ +class KMSpell : public KSpell +{ + public: + + KMSpell( QObject *receiver, const char *slot ); + using KSpell::writePersonalDictionary; +}; + +/** + * Reimplemented to add support for ignored words + */ +class KMSyntaxHighter : public KDictSpellingHighlighter +{ + public: + + KMSyntaxHighter( QTextEdit *textEdit, + bool spellCheckingActive = true, + bool autoEnable = true, + const QColor& spellColor = red, + bool colorQuoting = false, + const QColor& QuoteColor0 = black, + const QColor& QuoteColor1 = QColor( 0x00, 0x80, 0x00 ), + const QColor& QuoteColor2 = QColor( 0x00, 0x70, 0x00 ), + const QColor& QuoteColor3 = QColor( 0x00, 0x60, 0x00 ), + KSpellConfig *spellConfig = 0 ); + + /** Reimplemented */ + virtual bool isMisspelled( const QString &word ); + + void ignoreWord( const QString &word ); + + private: + QStringList mIgnoredWords; +}; class KMEdit : public KEdit { Q_OBJECT @@ -115,13 +154,27 @@ private slots: emit selectionAvailable( !selectedText().isEmpty() ); } + /// Called when mSpeller is ready to rumble. Does nothing, but KSpell requires a slot as otherwise + /// it will show a dialog itself, which we want to avoid. + void spellerReady( KSpell *speller ); + + /// Called when mSpeller died for some reason. + void spellerDied(); + private: void killExternalEditor(); private: KMComposeWin* mComposer; - KSpell *mKSpell; + // This is the speller used for the spellcheck dialog. It is only active as long as the spellcheck + // dialog is shown + KSpell *mKSpellForDialog; + + // This is the speller used when right-clicking a word and choosing "add to dictionary". It lives + // as long as the composer lives. + KMSpell *mSpeller; + KSpellConfig *mSpellConfig; QMap mReplacements; SpellingFilter* mSpellingFilter; @@ -131,7 +184,7 @@ private: bool mUseExtEditor; QString mExtEditor; bool mWasModifiedBeforeSpellCheck; - KDictSpellingHighlighter *mSpellChecker; + KMSyntaxHighter *mSpellChecker; bool mSpellLineEdit; QClipboard::Mode mPasteMode; }; From 8f578e4087037f8cb962e6dc3b1bd82d5c0c8135 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 23 Feb 2010 17:05:32 +0000 Subject: [PATCH 131/160] Make sure the spell dialog does not check ignored words. svn path=/branches/kdepim/enterprise/kdepim/; revision=1095109 --- kmedit.cpp | 11 +++++++++++ kmedit.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/kmedit.cpp b/kmedit.cpp index e5c10e12c..b45d1d0bf 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -388,6 +388,11 @@ void KMSyntaxHighter::ignoreWord( const QString &word ) mIgnoredWords << word; } +QStringList KMSyntaxHighter::ignoredWords() const +{ + return mIgnoredWords; +} + void KMEdit::spellerDied() { mSpeller = 0; @@ -782,6 +787,12 @@ void KMEdit::slotCorrected (const QString &oldWord, const QString &newWord, unsi void KMEdit::slotSpellcheck2(KSpell*) { + // Make sure words ignored by the highlighter are ignored by KSpell as well + if ( mSpellChecker ) { + for ( int i = 0; i < mSpellChecker->ignoredWords().size(); i++ ) + mKSpellForDialog->ignore( mSpellChecker->ignoredWords()[i] ); + } + if( !mSpellLineEdit) { spellcheck_start(); diff --git a/kmedit.h b/kmedit.h index 49e80a55e..cd83ee9bf 100644 --- a/kmedit.h +++ b/kmedit.h @@ -57,6 +57,8 @@ class KMSyntaxHighter : public KDictSpellingHighlighter void ignoreWord( const QString &word ); + QStringList ignoredWords() const; + private: QStringList mIgnoredWords; }; From 774678caebc2eddd37c2a3f6d1ef36a29cf12225 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 23 Feb 2010 17:08:52 +0000 Subject: [PATCH 132/160] Give the variable a better name svn path=/branches/kdepim/enterprise/kdepim/; revision=1095111 --- kmedit.cpp | 52 ++++++++++++++++++++++++++-------------------------- kmedit.h | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/kmedit.cpp b/kmedit.cpp index b45d1d0bf..160c1686c 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -222,7 +222,7 @@ KMEdit::KMEdit(QWidget *parent, KMComposeWin* composer, mExtEditorProcess( 0 ), mUseExtEditor( false ), mWasModifiedBeforeSpellCheck( false ), - mSpellChecker( 0 ), + mHighlighter( 0 ), mSpellLineEdit( false ), mPasteMode( QClipboard::Clipboard ) { @@ -238,7 +238,7 @@ KMEdit::KMEdit(QWidget *parent, KMComposeWin* composer, void KMEdit::initializeAutoSpellChecking() { - if ( mSpellChecker ) + if ( mHighlighter ) return; // already initialized QColor defaultColor1( 0x00, 0x80, 0x00 ); // defaults from kmreaderwin.cpp QColor defaultColor2( 0x00, 0x70, 0x00 ); @@ -256,14 +256,14 @@ void KMEdit::initializeAutoSpellChecking() QColor col3 = readerConfig.readColorEntry( "QuotedText2", &defaultColor2 ); QColor col4 = readerConfig.readColorEntry( "QuotedText1", &defaultColor1 ); QColor misspelled = readerConfig.readColorEntry( "MisspelledColor", &c ); - mSpellChecker = new KMSyntaxHighter( this, /*active*/ true, + mHighlighter = new KMSyntaxHighter( this, /*active*/ true, /*autoEnabled*/ false, /*spellColor*/ misspelled, /*colorQuoting*/ true, col1, col2, col3, col4, mSpellConfig ); - connect( mSpellChecker, SIGNAL(newSuggestions(const QString&, const QStringList&, unsigned int)), + connect( mHighlighter, SIGNAL(newSuggestions(const QString&, const QStringList&, unsigned int)), this, SLOT(addSuggestion(const QString&, const QStringList&, unsigned int)) ); } @@ -283,8 +283,8 @@ QPopupMenu *KMEdit::createPopupMenu( const QPoint& pos ) void KMEdit::deleteAutoSpellChecking() { // because the highlighter doesn't support RichText, delete its instance. - delete mSpellChecker; - mSpellChecker =0; + delete mHighlighter; + mHighlighter =0; } void KMEdit::addSuggestion(const QString& text, const QStringList& lst, unsigned int ) @@ -294,8 +294,8 @@ void KMEdit::addSuggestion(const QString& text, const QStringList& lst, unsigned void KMEdit::setSpellCheckingActive(bool spellCheckingActive) { - if ( mSpellChecker ) { - mSpellChecker->setActive(spellCheckingActive); + if ( mHighlighter ) { + mHighlighter->setActive(spellCheckingActive); } } @@ -312,8 +312,8 @@ KMEdit::~KMEdit() } delete mKSpellForDialog; - delete mSpellChecker; - mSpellChecker = 0; + delete mHighlighter; + mHighlighter = 0; } @@ -526,16 +526,16 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) const int id = p.exec( mapToGlobal( event->pos() ) ); if ( id == ignoreId ) { - mSpellChecker->ignoreWord( word ); - mSpellChecker->rehighlight(); + mHighlighter->ignoreWord( word ); + mHighlighter->rehighlight(); } if ( id == addToDictionaryId ) { mSpeller->addPersonal( word ); mSpeller->writePersonalDictionary(); - if ( mSpellChecker ) { + if ( mHighlighter ) { // Wait a bit until reloading the highlighter, the mSpeller first needs to finish saving // the personal word list. - QTimer::singleShot( 200, mSpellChecker, SLOT( slotLocalSpellConfigChanged() ) ); + QTimer::singleShot( 200, mHighlighter, SLOT( slotLocalSpellConfigChanged() ) ); } } else if( id > -1 ) @@ -573,10 +573,10 @@ int KMEdit::autoSpellChecking( bool on ) KMessageBox::sorry(this, i18n("Automatic spellchecking is not possible on text with markup.")); return -1; } - if ( mSpellChecker ) { + if ( mHighlighter ) { // don't autoEnable spell checking if the user turned spell checking off - mSpellChecker->setAutomatic( on ); - mSpellChecker->setActive( on ); + mHighlighter->setAutomatic( on ); + mHighlighter->setActive( on ); } return 1; } @@ -662,22 +662,22 @@ void KMEdit::spellcheck() void KMEdit::cut() { KEdit::cut(); - if ( textFormat() != Qt::RichText && mSpellChecker ) - mSpellChecker->restartBackgroundSpellCheck(); + if ( textFormat() != Qt::RichText && mHighlighter ) + mHighlighter->restartBackgroundSpellCheck(); } void KMEdit::clear() { KEdit::clear(); - if ( textFormat() != Qt::RichText && mSpellChecker ) - mSpellChecker->restartBackgroundSpellCheck(); + if ( textFormat() != Qt::RichText && mHighlighter ) + mHighlighter->restartBackgroundSpellCheck(); } void KMEdit::del() { KEdit::del(); - if ( textFormat() != Qt::RichText && mSpellChecker ) - mSpellChecker->restartBackgroundSpellCheck(); + if ( textFormat() != Qt::RichText && mHighlighter ) + mHighlighter->restartBackgroundSpellCheck(); } void KMEdit::paste() @@ -788,9 +788,9 @@ void KMEdit::slotCorrected (const QString &oldWord, const QString &newWord, unsi void KMEdit::slotSpellcheck2(KSpell*) { // Make sure words ignored by the highlighter are ignored by KSpell as well - if ( mSpellChecker ) { - for ( int i = 0; i < mSpellChecker->ignoredWords().size(); i++ ) - mKSpellForDialog->ignore( mSpellChecker->ignoredWords()[i] ); + if ( mHighlighter ) { + for ( int i = 0; i < mHighlighter->ignoredWords().size(); i++ ) + mKSpellForDialog->ignore( mHighlighter->ignoredWords()[i] ); } if( !mSpellLineEdit) diff --git a/kmedit.h b/kmedit.h index cd83ee9bf..ff5a5c1e2 100644 --- a/kmedit.h +++ b/kmedit.h @@ -186,7 +186,7 @@ private: bool mUseExtEditor; QString mExtEditor; bool mWasModifiedBeforeSpellCheck; - KMSyntaxHighter *mSpellChecker; + KMSyntaxHighter *mHighlighter; bool mSpellLineEdit; QClipboard::Mode mPasteMode; }; From 1dd8df1be9e24330840c93d2725f821543fdfc8f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 26 Feb 2010 09:54:39 +0000 Subject: [PATCH 133/160] Don't show the misspelled context menu after a word has been corrected. MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1096215 --- kmedit.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kmedit.cpp b/kmedit.cpp index 160c1686c..1c2330b48 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -525,6 +525,11 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) //Execute the popup inline const int id = p.exec( mapToGlobal( event->pos() ) ); + if ( id != -1 ) { + // No longer misspelled: Either added to dictionary, ignored or replaced + mReplacements.remove( word ); + } + if ( id == ignoreId ) { mHighlighter->ignoreWord( word ); mHighlighter->rehighlight(); From 1d6a6200f190f07167caabd85e4d1ac695c72a5c Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 26 Feb 2010 12:45:48 +0000 Subject: [PATCH 134/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1096265 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index d013eb0d9..fcc937e2f 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100219.1092865)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100226.1096264)" #endif /*kmversion_h*/ From 527a9734432e0e4edb06572586a056a5069b8a86 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Sun, 28 Feb 2010 18:13:07 +0000 Subject: [PATCH 135/160] use splitEmailAddrList() to parse the the user entered Ids. this way, we support "last,first" note the double-quotes, just like when composing email messages. kolab/issue4149 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1097222 --- folderdiaacltab.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/folderdiaacltab.cpp b/folderdiaacltab.cpp index 6f36978f4..aff09e97a 100644 --- a/folderdiaacltab.cpp +++ b/folderdiaacltab.cpp @@ -178,12 +178,7 @@ QString KMail::ACLEntryDialog::userId() const QStringList KMail::ACLEntryDialog::userIds() const { - QStringList lst = QStringList::split( ",", mUserIdLineEdit->text() ); - for( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { - // Strip white space (in particular, due to ", ") - *it = (*it).stripWhiteSpace(); - } - return lst; + return KPIM::splitEmailAddrList( mUserIdLineEdit->text() ); } unsigned int KMail::ACLEntryDialog::permissions() const From ec20bb39914df084fec2b2a815e5a5a9a3e0c19e Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Mar 2010 08:07:37 +0000 Subject: [PATCH 136/160] Make the folder notice when the close to quota limit for subfolders changes. part of kolab/issue4066 MERGE: trunk (?, needs to be tested) svn path=/branches/kdepim/enterprise/kdepim/; revision=1097816 --- kmfoldercachedimap.cpp | 31 ++++++++++++++++++++++++------- kmfoldercachedimap.h | 17 +++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index 3c46df2ed..b460e44f0 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -201,7 +201,7 @@ KMFolderCachedImap::KMFolderCachedImap( KMFolder* folder, const char* aName ) mSharedSeenFlagsChanged( false ), mStatusChangedLocally( false ), mPersonalNamespacesCheckDone( true ), - mQuotaInfo(), mAlarmsBlocked( false ), + mQuotaInfo(), mCurrentSubFolderCloseToQuotaChanged( false ), mAlarmsBlocked( false ), mRescueCommandCount( 0 ), mPermanentFlags( 31 ) // assume standard flags by default (see imap4/imapinfo.h for bit fields values) { @@ -1305,10 +1305,9 @@ void KMFolderCachedImap::serverSyncInternal() // Carry on case SYNC_STATE_SYNC_SUBFOLDERS: { + mCurrentSubFolderCloseToQuotaChanged = false; if( mCurrentSubfolder ) { - disconnect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), - this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); - mCurrentSubfolder = 0; + disconnectSubFolderSignals(); } if( mSubfoldersForSync.isEmpty() ) { @@ -1321,6 +1320,8 @@ void KMFolderCachedImap::serverSyncInternal() mSubfoldersForSync.pop_front(); connect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); + connect( mCurrentSubfolder, SIGNAL( closeToQuotaChanged() ), + this, SLOT( slotSubFolderCloseToQuotaChanged() ) ); //kdDebug(5006) << "Sync'ing subfolder " << mCurrentSubfolder->imapPath() << endl; assert( !mCurrentSubfolder->imapPath().isEmpty() ); @@ -1337,6 +1338,15 @@ void KMFolderCachedImap::serverSyncInternal() } } +void KMFolderCachedImap::disconnectSubFolderSignals() +{ + disconnect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), + this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); + disconnect( mCurrentSubfolder, SIGNAL( closeToQuotaChanged() ), + this, SLOT( slotSubFolderCloseToQuotaChanged() ) ); + mCurrentSubfolder = 0; +} + /* Connected to the imap account's connectionResult signal. Emitted when the slave connected or failed to connect. */ @@ -2335,9 +2345,7 @@ void KMFolderCachedImap::slotSubFolderComplete(KMFolderCachedImap* sub, bool suc // success == false means the sync was aborted. if ( mCurrentSubfolder ) { Q_ASSERT( sub == mCurrentSubfolder ); - disconnect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), - this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); - mCurrentSubfolder = 0; + disconnectSubFolderSignals(); } mSubfoldersForSync.clear(); @@ -2347,6 +2355,11 @@ void KMFolderCachedImap::slotSubFolderComplete(KMFolderCachedImap* sub, bool suc } } +void KMFolderCachedImap::slotSubFolderCloseToQuotaChanged() +{ + mCurrentSubFolderCloseToQuotaChanged = true; +} + void KMFolderCachedImap::slotSimpleData(KIO::Job * job, const QByteArray & data) { KMAcctCachedImap::JobIterator it = mAccount->findJob(job); @@ -2430,8 +2443,12 @@ KMFolderCachedImap::slotStorageQuotaResult( const QuotaInfo& info ) void KMFolderCachedImap::setQuotaInfo( const QuotaInfo & info ) { if ( info != mQuotaInfo ) { + const bool wasCloseToQuota = isCloseToQuota(); mQuotaInfo = info; writeConfigKeysWhichShouldNotGetOverwrittenByReadConfig(); + if ( wasCloseToQuota != isCloseToQuota() ) { + emit closeToQuotaChanged(); + } emit folderSizeChanged(); } } diff --git a/kmfoldercachedimap.h b/kmfoldercachedimap.h index d5eb4256a..86573df53 100644 --- a/kmfoldercachedimap.h +++ b/kmfoldercachedimap.h @@ -342,6 +342,7 @@ protected slots: //virtual void slotCheckValidityResult(KIO::Job * job); void slotSubFolderComplete(KMFolderCachedImap*, bool); + void slotSubFolderCloseToQuotaChanged(); // Connected to the imap account void slotConnectionResult( int errorCode, const QString& errorMsg ); @@ -441,6 +442,11 @@ signals: void folderComplete(KMFolderCachedImap *folder, bool success); void listComplete( KMFolderCachedImap* ); + /** + * Emitted when isCloseToQuota() changes during syncing + */ + void closeToQuotaChanged(); + /** emitted when we enter the state "state" and have to process "number" items (for example messages */ @@ -458,6 +464,12 @@ private: /** Recursive helper function calling the above method. */ void rescueUnsyncedMessagesAndDeleteFolder( KMFolder *folder, bool root = true ); + /** + * Small helper function that disconnects the signals from the current subfolder, which where + * connected when starting the sync of that subfolder + */ + void disconnectSubFolderSignals(); + /** State variable for the synchronization mechanism */ enum { SYNC_STATE_INITIAL, @@ -578,6 +590,11 @@ private: QString mImapPathCreation; QuotaInfo mQuotaInfo; + + /// This is set during syncing of the current subfolder. If true, it means the closeToQuota info + /// for the current subfolder has changed during syncing + bool mCurrentSubFolderCloseToQuotaChanged; + QMap mDeletedUIDsSinceLastSync; bool mAlarmsBlocked; From ffad50e81f49e30940edfedd69b7611c63d7469b Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Mar 2010 08:33:19 +0000 Subject: [PATCH 137/160] Revert last commit, in favor of a much easier solution: Simply get the quota info after syncing the subfolders, so that it is up-to-date. https://issues.kolab.org/issue4066 svn path=/branches/kdepim/enterprise/kdepim/; revision=1097823 --- kmfoldercachedimap.cpp | 69 ++++++++++++++++++++---------------------- kmfoldercachedimap.h | 14 ++------- 2 files changed, 35 insertions(+), 48 deletions(-) diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index b460e44f0..801421016 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -201,7 +201,7 @@ KMFolderCachedImap::KMFolderCachedImap( KMFolder* folder, const char* aName ) mSharedSeenFlagsChanged( false ), mStatusChangedLocally( false ), mPersonalNamespacesCheckDone( true ), - mQuotaInfo(), mCurrentSubFolderCloseToQuotaChanged( false ), mAlarmsBlocked( false ), + mQuotaInfo(), mAlarmsBlocked( false ), mRescueCommandCount( 0 ), mPermanentFlags( 31 ) // assume standard flags by default (see imap4/imapinfo.h for bit fields values) { @@ -819,6 +819,7 @@ QString KMFolderCachedImap::state2String( int state ) const case SYNC_STATE_SYNC_SUBFOLDERS: return "SYNC_STATE_SYNC_SUBFOLDERS"; case SYNC_STATE_RENAME_FOLDER: return "SYNC_STATE_RENAME_FOLDER"; case SYNC_STATE_CHECK_UIDVALIDITY: return "SYNC_STATE_CHECK_UIDVALIDITY"; + case SYNC_STATE_CLOSE: return "SYNC_STATE_CLOSE"; default: return "Unknown state"; } } @@ -1239,7 +1240,7 @@ void KMFolderCachedImap::serverSyncInternal() } case SYNC_STATE_GET_ACLS: - mSyncState = SYNC_STATE_GET_QUOTA; + mSyncState = SYNC_STATE_FIND_SUBFOLDERS; if( !noContent() && mAccount->hasACLSupport() ) { newState( mProgress, i18n( "Retrieving permissions" ) ); @@ -1248,22 +1249,6 @@ void KMFolderCachedImap::serverSyncInternal() this, SLOT(slotReceivedACL( KMFolder*, KIO::Job*, const KMail::ACLList& )) ); break; } - case SYNC_STATE_GET_QUOTA: - // Continue with the subfolders - mSyncState = SYNC_STATE_FIND_SUBFOLDERS; - if( !noContent() && mAccount->hasQuotaSupport() ) { - newState( mProgress, i18n("Getting quota information")); - KURL url = mAccount->getUrl(); - url.setPath( imapPath() ); - KIO::Job* job = KMail::QuotaJobs::getStorageQuota( mAccount->slave(), url ); - ImapAccountBase::jobData jd( url.url(), folder() ); - mAccount->insertJob(job, jd); - connect( job, SIGNAL( storageQuotaResult( const QuotaInfo& ) ), - SLOT( slotStorageQuotaResult( const QuotaInfo& ) ) ); - connect( job, SIGNAL(result(KIO::Job *)), - SLOT(slotQuotaResult(KIO::Job *)) ); - break; - } case SYNC_STATE_FIND_SUBFOLDERS: { mProgress = 98; @@ -1305,23 +1290,21 @@ void KMFolderCachedImap::serverSyncInternal() // Carry on case SYNC_STATE_SYNC_SUBFOLDERS: { - mCurrentSubFolderCloseToQuotaChanged = false; if( mCurrentSubfolder ) { disconnectSubFolderSignals(); } if( mSubfoldersForSync.isEmpty() ) { - mSyncState = SYNC_STATE_INITIAL; - mAccount->addUnreadMsgCount( this, countUnread() ); // before closing - close("cachedimap"); - emit folderComplete( this, true ); + // Quota checking has to come after syncing subfolder, otherwise the quota information would + // be outdated, since the subfolders can change in size during the syncing. + // https://issues.kolab.org/issue4066 + mSyncState = SYNC_STATE_GET_QUOTA; + serverSyncInternal(); } else { mCurrentSubfolder = mSubfoldersForSync.front(); mSubfoldersForSync.pop_front(); connect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); - connect( mCurrentSubfolder, SIGNAL( closeToQuotaChanged() ), - this, SLOT( slotSubFolderCloseToQuotaChanged() ) ); //kdDebug(5006) << "Sync'ing subfolder " << mCurrentSubfolder->imapPath() << endl; assert( !mCurrentSubfolder->imapPath().isEmpty() ); @@ -1331,6 +1314,29 @@ void KMFolderCachedImap::serverSyncInternal() } } break; + case SYNC_STATE_GET_QUOTA: + mSyncState = SYNC_STATE_CLOSE; + if( !noContent() && mAccount->hasQuotaSupport() ) { + newState( mProgress, i18n("Getting quota information")); + KURL url = mAccount->getUrl(); + url.setPath( imapPath() ); + KIO::Job* job = KMail::QuotaJobs::getStorageQuota( mAccount->slave(), url ); + ImapAccountBase::jobData jd( url.url(), folder() ); + mAccount->insertJob(job, jd); + connect( job, SIGNAL( storageQuotaResult( const QuotaInfo& ) ), + SLOT( slotStorageQuotaResult( const QuotaInfo& ) ) ); + connect( job, SIGNAL(result(KIO::Job *)), + SLOT(slotQuotaResult(KIO::Job *)) ); + break; + } + case SYNC_STATE_CLOSE: + { + mSyncState = SYNC_STATE_INITIAL; + mAccount->addUnreadMsgCount( this, countUnread() ); // before closing + close( "cachedimap" ); + emit folderComplete( this, true ); + } + break; default: kdDebug(5006) << "KMFolderCachedImap::serverSyncInternal() WARNING: no such state " @@ -1342,8 +1348,6 @@ void KMFolderCachedImap::disconnectSubFolderSignals() { disconnect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); - disconnect( mCurrentSubfolder, SIGNAL( closeToQuotaChanged() ), - this, SLOT( slotSubFolderCloseToQuotaChanged() ) ); mCurrentSubfolder = 0; } @@ -2348,6 +2352,8 @@ void KMFolderCachedImap::slotSubFolderComplete(KMFolderCachedImap* sub, bool suc disconnectSubFolderSignals(); } + // Next step would be to check quota limits and then to close the folder, but don't bother with + // both and close the folder right here, since we aborted. mSubfoldersForSync.clear(); mSyncState = SYNC_STATE_INITIAL; close("cachedimap"); @@ -2355,11 +2361,6 @@ void KMFolderCachedImap::slotSubFolderComplete(KMFolderCachedImap* sub, bool suc } } -void KMFolderCachedImap::slotSubFolderCloseToQuotaChanged() -{ - mCurrentSubFolderCloseToQuotaChanged = true; -} - void KMFolderCachedImap::slotSimpleData(KIO::Job * job, const QByteArray & data) { KMAcctCachedImap::JobIterator it = mAccount->findJob(job); @@ -2443,12 +2444,8 @@ KMFolderCachedImap::slotStorageQuotaResult( const QuotaInfo& info ) void KMFolderCachedImap::setQuotaInfo( const QuotaInfo & info ) { if ( info != mQuotaInfo ) { - const bool wasCloseToQuota = isCloseToQuota(); mQuotaInfo = info; writeConfigKeysWhichShouldNotGetOverwrittenByReadConfig(); - if ( wasCloseToQuota != isCloseToQuota() ) { - emit closeToQuotaChanged(); - } emit folderSizeChanged(); } } diff --git a/kmfoldercachedimap.h b/kmfoldercachedimap.h index 86573df53..b7e32c530 100644 --- a/kmfoldercachedimap.h +++ b/kmfoldercachedimap.h @@ -342,7 +342,6 @@ protected slots: //virtual void slotCheckValidityResult(KIO::Job * job); void slotSubFolderComplete(KMFolderCachedImap*, bool); - void slotSubFolderCloseToQuotaChanged(); // Connected to the imap account void slotConnectionResult( int errorCode, const QString& errorMsg ); @@ -442,11 +441,6 @@ signals: void folderComplete(KMFolderCachedImap *folder, bool success); void listComplete( KMFolderCachedImap* ); - /** - * Emitted when isCloseToQuota() changes during syncing - */ - void closeToQuotaChanged(); - /** emitted when we enter the state "state" and have to process "number" items (for example messages */ @@ -495,7 +489,8 @@ private: SYNC_STATE_FIND_SUBFOLDERS, SYNC_STATE_SYNC_SUBFOLDERS, SYNC_STATE_CHECK_UIDVALIDITY, - SYNC_STATE_RENAME_FOLDER + SYNC_STATE_RENAME_FOLDER, + SYNC_STATE_CLOSE } mSyncState; int mProgress; @@ -590,11 +585,6 @@ private: QString mImapPathCreation; QuotaInfo mQuotaInfo; - - /// This is set during syncing of the current subfolder. If true, it means the closeToQuota info - /// for the current subfolder has changed during syncing - bool mCurrentSubFolderCloseToQuotaChanged; - QMap mDeletedUIDsSinceLastSync; bool mAlarmsBlocked; From fb4ab6ef89dc59716c7ac87e2b510c9da2856e48 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 2 Mar 2010 12:55:54 +0000 Subject: [PATCH 138/160] Don't allow to drag the envelope image in the enterprise header. For this, we use a custom URL handler. In addition, when clicking images, the hovered URL is set to the path of the image. kolab/issue2277 MERGE: trunk (once the lost commits are found and re-applied) svn path=/branches/kdepim/enterprise/kdepim/; revision=1097925 --- kmreaderwin.cpp | 25 ++++++++++++++++++++----- urlhandlermanager.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 36c5850ed..a71920a52 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2600,6 +2600,20 @@ bool KMReaderWin::eventFilter( QObject *, QEvent *e ) } if ( me->button() == LeftButton ) { + + // When the node under the mouse is an IMG node, set the hovered URL to the src of the + // image, so that special URL handlers can deal with it, for example the InternalImageURLHandler + const DOM::Node nodeUnderMouse = mViewer->nodeUnderMouse(); + if ( !nodeUnderMouse.isNull() ) { + const DOM::NamedNodeMap attributes = nodeUnderMouse.attributes(); + if ( !attributes.isNull() ) { + const DOM::Node src = attributes.getNamedItem( DOM::DOMString( "src" ) ); + if ( !src.isNull() ) { + mHoveredUrl = src.nodeValue().string(); + } + } + } + mCanStartDrag = URLHandlerManager::instance()->willHandleDrag( mHoveredUrl, this ); mLastClickPosition = me->pos(); } @@ -2613,11 +2627,12 @@ bool KMReaderWin::eventFilter( QObject *, QEvent *e ) QMouseEvent* me = static_cast( e ); if ( ( mLastClickPosition - me->pos() ).manhattanLength() > KGlobalSettings::dndEventDelay() ) { - if ( mCanStartDrag && !mHoveredUrl.isEmpty() && mHoveredUrl.protocol() == "attachment" ) { - mCanStartDrag = false; - URLHandlerManager::instance()->handleDrag( mHoveredUrl, this ); - slotUrlOn( QString() ); - return true; + if ( mCanStartDrag && !mHoveredUrl.isEmpty() ) { + if ( URLHandlerManager::instance()->handleDrag( mHoveredUrl, this ) ) { + mCanStartDrag = false; + slotUrlOn( QString() ); + return true; + } } } } diff --git a/urlhandlermanager.cpp b/urlhandlermanager.cpp index 780108f07..ed3d86cca 100644 --- a/urlhandlermanager.cpp +++ b/urlhandlermanager.cpp @@ -45,6 +45,7 @@ #include "callback.h" #include "stl_util.h" +#include #include #include #include @@ -144,6 +145,24 @@ namespace { QString statusBarMessage( const KURL &, KMReaderWin * ) const; }; + // Handler that prevents dragging of internal images added by KMail, such as the envelope image + // in the enterprise header + class InternalImageURLHandler : public KMail::URLHandler { + public: + InternalImageURLHandler() : KMail::URLHandler() + {} + ~InternalImageURLHandler() + {} + bool handleDrag( const KURL &url, KMReaderWin *window ) const; + bool willHandleDrag( const KURL &url, KMReaderWin *window ) const; + bool handleClick( const KURL &, KMReaderWin * ) const + { return false; } + bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const + { return false; } + QString statusBarMessage( const KURL &, KMReaderWin * ) const + { return QString(); } + }; + class FallBackURLHandler : public KMail::URLHandler { public: FallBackURLHandler() : KMail::URLHandler() {} @@ -281,6 +300,7 @@ KMail::URLHandlerManager::URLHandlerManager() { registerHandler( new AttachmentURLHandler() ); registerHandler( mBodyPartURLHandlerManager = new BodyPartURLHandlerManager() ); registerHandler( new ShowAuditLogURLHandler() ); + registerHandler( new InternalImageURLHandler ); registerHandler( new FallBackURLHandler() ); } @@ -691,6 +711,26 @@ namespace { } } +namespace { + bool InternalImageURLHandler::handleDrag( const KURL &url, KMReaderWin *window ) const + { + Q_UNUSED( window ); + const QString imagePath = locate( "data", "kmail/pics/" ); + if ( url.path().contains( imagePath ) ) { + // Do nothing, don't start a drag + return true; + } + return false; + } + + bool InternalImageURLHandler::willHandleDrag( const KURL &url, KMReaderWin *window ) const + { + Q_UNUSED( window ); + const QString imagePath = locate( "data", "kmail/pics/" ); + return url.path().contains( imagePath ); + } +} + namespace { bool FallBackURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { if ( w ) From 11e36e1eeea7c4f30a5383bb483dff3cf4e9d7a3 Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Wed, 3 Mar 2010 14:50:47 +0000 Subject: [PATCH 139/160] add Tooltips to the composer settings part of kolab/issue4142 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1098347 --- kmcomposewin.cpp | 29 +++++++++++++++++++++++++++++ recipientseditor.cpp | 2 ++ 2 files changed, 31 insertions(+) diff --git a/kmcomposewin.cpp b/kmcomposewin.cpp index 909efb71d..a053c639c 100644 --- a/kmcomposewin.cpp +++ b/kmcomposewin.cpp @@ -204,13 +204,29 @@ KMComposeWin::KMComposeWin( KMMessage *aMsg, uint id ) QVBoxLayout *v = new QVBoxLayout( mMainWidget ); v->addWidget( mHeadersToEditorSplitter ); mIdentity = new KPIM::IdentityCombo(kmkernel->identityManager(), mHeadersArea); + QToolTip::add( mIdentity, + i18n( "Select an identity for this message" ) ); + mDictionaryCombo = new DictionaryComboBox( mHeadersArea ); + QToolTip::add( mDictionaryCombo, + i18n( "Select the dictionary to use when spell-checking this message" ) ); + mFcc = new KMFolderComboBox(mHeadersArea); mFcc->showOutboxFolder( false ); + QToolTip::add( mFcc, + i18n( "Select the sent-mail folder where a copy of this message will be saved" ) ); + mTransport = new QComboBox(true, mHeadersArea); + QToolTip::add( mTransport, + i18n( "Select the outgoing account to use for sending this message" ) ); + mEdtFrom = new KMLineEdit(false,mHeadersArea, "fromLine"); + QToolTip::add( mEdtFrom, + i18n( "Set the \"From:\" email address for this message" ) ); mEdtReplyTo = new KMLineEdit(true,mHeadersArea, "replyToLine"); + QToolTip::add( mEdtReplyTo, + i18n( "Set the \"Reply-To:\" email address for this message" ) ); mLblReplyTo = new QLabel(mHeadersArea); connect(mEdtReplyTo,SIGNAL(completionModeChanged(KGlobalSettings::Completion)), SLOT(slotCompletionModeChanged(KGlobalSettings::Completion))); @@ -277,6 +293,9 @@ KMComposeWin::KMComposeWin( KMMessage *aMsg, uint id ) mRecipientsEditor->setFocus(); } mEdtSubject = new KMLineEditSpell(false,mHeadersArea, "subjectLine"); + QToolTip::add( mEdtSubject, + i18n( "Set a subject for this message" ) ); + mLblIdentity = new QLabel(mHeadersArea); mDictionaryLabel = new QLabel( mHeadersArea ); mLblFcc = new QLabel(mHeadersArea); @@ -285,8 +304,14 @@ KMComposeWin::KMComposeWin( KMMessage *aMsg, uint id ) mLblSubject = new QLabel(mHeadersArea); QString sticky = i18n("Sticky"); mBtnIdentity = new QCheckBox(sticky,mHeadersArea); + QToolTip::add( mBtnIdentity, + i18n( "Use the selected value as your identity for future messages" ) ); mBtnFcc = new QCheckBox(sticky,mHeadersArea); + QToolTip::add( mBtnFcc, + i18n( "Use the selected value as your sent-mail folder for future messages" ) ); mBtnTransport = new QCheckBox(sticky,mHeadersArea); + QToolTip::add( mBtnTransport, + i18n( "Use the selected value as your outgoing account for future messages" ) ); //setWFlags( WType_TopLevel | WStyle_Dialog ); mHtmlMarkup = GlobalSettings::self()->useHtmlMarkup(); @@ -1515,6 +1540,7 @@ void KMComposeWin::setupActions(void) actionCollection(), "options_select_crypto" ); mCryptoModuleAction->setItems( l ); mCryptoModuleAction->setCurrentItem( format2cb( ident.preferredCryptoMessageFormat() ) ); + mCryptoModuleAction->setToolTip( i18n( "Select a cryptographic format for this message" ) ); slotSelectCryptoModule( true /* initialize */ ); QStringList styleItems; @@ -1529,14 +1555,17 @@ void KMComposeWin::setupActions(void) listAction = new KSelectAction( i18n( "Select Style" ), 0, actionCollection(), "text_list" ); listAction->setItems( styleItems ); + listAction->setToolTip( i18n( "Select a list style" ) ); connect( listAction, SIGNAL( activated( const QString& ) ), SLOT( slotListAction( const QString& ) ) ); fontAction = new KFontAction( "Select Font", 0, actionCollection(), "text_font" ); + fontAction->setToolTip( i18n( "Select a font" ) ); connect( fontAction, SIGNAL( activated( const QString& ) ), SLOT( slotFontAction( const QString& ) ) ); fontSizeAction = new KFontSizeAction( "Select Size", 0, actionCollection(), "text_size" ); + fontSizeAction->setToolTip( i18n( "Select a font size" ) ); connect( fontSizeAction, SIGNAL( fontSizeChanged( int ) ), SLOT( slotSizeAction( int ) ) ); diff --git a/recipientseditor.cpp b/recipientseditor.cpp index 8cbd670d5..0e9ea4734 100644 --- a/recipientseditor.cpp +++ b/recipientseditor.cpp @@ -159,6 +159,8 @@ RecipientLine::RecipientLine( QWidget *parent ) QToolTip::add( mCombo, i18n("Select type of recipient") ); mEdit = new RecipientLineEdit( this ); + QToolTip::add( mEdit, + i18n( "Set the list of email addresses to receive this message" ) ); topLayout->addWidget( mEdit ); connect( mEdit, SIGNAL( returnPressed() ), SLOT( slotReturnPressed() ) ); connect( mEdit, SIGNAL( deleteMe() ), SLOT( slotPropagateDeletion() ) ); From a048224c8b76c5bb565874ca61bcb249907da1ed Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Thu, 4 Mar 2010 22:45:15 +0000 Subject: [PATCH 140/160] crash guard in setBodyPartMemento if the memento argument is 0. possible fix for kolab/issue4187 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1099019 --- kmreaderwin.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index a71920a52..faf6c778e 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2932,8 +2932,11 @@ void KMReaderWin::setBodyPartMemento( const partNode * node, const QCString & wh mBodyPartMementoMap.insert( it, std::make_pair( index, memento ) ); } - if ( Observable * o = memento ? memento->asObservable() : 0 ) - o->attach( this ); + if ( Observable * o = memento ? memento->asObservable() : 0 ) { + if ( o ) { + o->attach( this ); + } + } } BodyPartMemento * KMReaderWin::bodyPartMemento( const partNode * node, const QCString & which ) const From 4eac1d470a42bf02407a021b5b65ea6ed14f34e4 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 5 Mar 2010 10:39:16 +0000 Subject: [PATCH 141/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1099232 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index fcc937e2f..57bf4ec7a 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100226.1096264)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100305.1099231)" #endif /*kmversion_h*/ From 2e52fcc14a3cfe20e9df1fcd63f9c3306dcd947a Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 5 Mar 2010 10:44:41 +0000 Subject: [PATCH 142/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1099258 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 57bf4ec7a..49062b382 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100305.1099231)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100305.1099257)" #endif /*kmversion_h*/ From 8d52cb853339feade0fcc2ee7ff8cb29c7912045 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Mar 2010 16:42:55 +0000 Subject: [PATCH 143/160] When the close to quota state of a subfolder changed, re-sync the other subfolders, so that the information is updated also for them. kolab/issue4066 svn path=/branches/kdepim/enterprise/kdepim/; revision=1101219 --- kmfoldercachedimap.cpp | 206 ++++++++++++++++++++++++----------------- kmfoldercachedimap.h | 18 +++- 2 files changed, 139 insertions(+), 85 deletions(-) diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index 801421016..148c989ae 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -201,7 +201,7 @@ KMFolderCachedImap::KMFolderCachedImap( KMFolder* folder, const char* aName ) mSharedSeenFlagsChanged( false ), mStatusChangedLocally( false ), mPersonalNamespacesCheckDone( true ), - mQuotaInfo(), mAlarmsBlocked( false ), + mQuotaInfo(), mSomeSubFolderCloseToQuotaChanged( false ), mAlarmsBlocked( false ), mRescueCommandCount( 0 ), mPermanentFlags( 31 ) // assume standard flags by default (see imap4/imapinfo.h for bit fields values) { @@ -795,32 +795,33 @@ void KMFolderCachedImap::serverSync( bool recurse ) QString KMFolderCachedImap::state2String( int state ) const { switch( state ) { - case SYNC_STATE_INITIAL: return "SYNC_STATE_INITIAL"; - case SYNC_STATE_GET_USERRIGHTS: return "SYNC_STATE_GET_USERRIGHTS"; - case SYNC_STATE_PUT_MESSAGES: return "SYNC_STATE_PUT_MESSAGES"; - case SYNC_STATE_UPLOAD_FLAGS: return "SYNC_STATE_UPLOAD_FLAGS"; - case SYNC_STATE_CREATE_SUBFOLDERS: return "SYNC_STATE_CREATE_SUBFOLDERS"; - case SYNC_STATE_LIST_SUBFOLDERS: return "SYNC_STATE_LIST_SUBFOLDERS"; - case SYNC_STATE_LIST_NAMESPACES: return "SYNC_STATE_LIST_NAMESPACES"; - case SYNC_STATE_LIST_SUBFOLDERS2: return "SYNC_STATE_LIST_SUBFOLDERS2"; - case SYNC_STATE_DELETE_SUBFOLDERS: return "SYNC_STATE_DELETE_SUBFOLDERS"; - case SYNC_STATE_LIST_MESSAGES: return "SYNC_STATE_LIST_MESSAGES"; - case SYNC_STATE_DELETE_MESSAGES: return "SYNC_STATE_DELETE_MESSAGES"; - case SYNC_STATE_GET_MESSAGES: return "SYNC_STATE_GET_MESSAGES"; - case SYNC_STATE_EXPUNGE_MESSAGES: return "SYNC_STATE_EXPUNGE_MESSAGES"; - case SYNC_STATE_HANDLE_INBOX: return "SYNC_STATE_HANDLE_INBOX"; - case SYNC_STATE_TEST_ANNOTATIONS: return "SYNC_STATE_TEST_ANNOTATIONS"; - case SYNC_STATE_GET_ANNOTATIONS: return "SYNC_STATE_GET_ANNOTATIONS"; - case SYNC_STATE_SET_ANNOTATIONS: return "SYNC_STATE_SET_ANNOTATIONS"; - case SYNC_STATE_GET_ACLS: return "SYNC_STATE_GET_ACLS"; - case SYNC_STATE_SET_ACLS: return "SYNC_STATE_SET_ACLS"; - case SYNC_STATE_GET_QUOTA: return "SYNC_STATE_GET_QUOTA"; - case SYNC_STATE_FIND_SUBFOLDERS: return "SYNC_STATE_FIND_SUBFOLDERS"; - case SYNC_STATE_SYNC_SUBFOLDERS: return "SYNC_STATE_SYNC_SUBFOLDERS"; - case SYNC_STATE_RENAME_FOLDER: return "SYNC_STATE_RENAME_FOLDER"; - case SYNC_STATE_CHECK_UIDVALIDITY: return "SYNC_STATE_CHECK_UIDVALIDITY"; - case SYNC_STATE_CLOSE: return "SYNC_STATE_CLOSE"; - default: return "Unknown state"; + case SYNC_STATE_INITIAL: return "SYNC_STATE_INITIAL"; + case SYNC_STATE_GET_USERRIGHTS: return "SYNC_STATE_GET_USERRIGHTS"; + case SYNC_STATE_PUT_MESSAGES: return "SYNC_STATE_PUT_MESSAGES"; + case SYNC_STATE_UPLOAD_FLAGS: return "SYNC_STATE_UPLOAD_FLAGS"; + case SYNC_STATE_CREATE_SUBFOLDERS: return "SYNC_STATE_CREATE_SUBFOLDERS"; + case SYNC_STATE_LIST_SUBFOLDERS: return "SYNC_STATE_LIST_SUBFOLDERS"; + case SYNC_STATE_LIST_NAMESPACES: return "SYNC_STATE_LIST_NAMESPACES"; + case SYNC_STATE_LIST_SUBFOLDERS2: return "SYNC_STATE_LIST_SUBFOLDERS2"; + case SYNC_STATE_DELETE_SUBFOLDERS: return "SYNC_STATE_DELETE_SUBFOLDERS"; + case SYNC_STATE_LIST_MESSAGES: return "SYNC_STATE_LIST_MESSAGES"; + case SYNC_STATE_DELETE_MESSAGES: return "SYNC_STATE_DELETE_MESSAGES"; + case SYNC_STATE_GET_MESSAGES: return "SYNC_STATE_GET_MESSAGES"; + case SYNC_STATE_EXPUNGE_MESSAGES: return "SYNC_STATE_EXPUNGE_MESSAGES"; + case SYNC_STATE_HANDLE_INBOX: return "SYNC_STATE_HANDLE_INBOX"; + case SYNC_STATE_TEST_ANNOTATIONS: return "SYNC_STATE_TEST_ANNOTATIONS"; + case SYNC_STATE_GET_ANNOTATIONS: return "SYNC_STATE_GET_ANNOTATIONS"; + case SYNC_STATE_SET_ANNOTATIONS: return "SYNC_STATE_SET_ANNOTATIONS"; + case SYNC_STATE_GET_ACLS: return "SYNC_STATE_GET_ACLS"; + case SYNC_STATE_SET_ACLS: return "SYNC_STATE_SET_ACLS"; + case SYNC_STATE_GET_QUOTA: return "SYNC_STATE_GET_QUOTA"; + case SYNC_STATE_FIND_SUBFOLDERS: return "SYNC_STATE_FIND_SUBFOLDERS"; + case SYNC_STATE_SYNC_SUBFOLDERS: return "SYNC_STATE_SYNC_SUBFOLDERS"; + case SYNC_STATE_RENAME_FOLDER: return "SYNC_STATE_RENAME_FOLDER"; + case SYNC_STATE_CHECK_UIDVALIDITY: return "SYNC_STATE_CHECK_UIDVALIDITY"; + case SYNC_STATE_CLOSE: return "SYNC_STATE_CLOSE"; + case SYNC_STATE_GET_SUBFOLDER_QUOTA: return "SYNC_STATE_GET_SUBFOLDER_QUOTA"; + default: return "Unknown state"; } } @@ -1251,72 +1252,25 @@ void KMFolderCachedImap::serverSyncInternal() } case SYNC_STATE_FIND_SUBFOLDERS: { - mProgress = 98; - newState( mProgress, i18n("Updating cache file")); - mSyncState = SYNC_STATE_SYNC_SUBFOLDERS; - mSubfoldersForSync.clear(); - mCurrentSubfolder = 0; - if( folder() && folder()->child() ) { - KMFolderNode *node = folder()->child()->first(); - while( node ) { - if( !node->isDir() ) { - KMFolderCachedImap* storage = static_cast(static_cast(node)->storage()); - // Only sync folders that have been accepted by the server - if ( !storage->imapPath().isEmpty() - // and that were not just deleted from it - && !foldersForDeletionOnServer.contains( storage->imapPath() ) ) { - mSubfoldersForSync << storage; - } else { - kdDebug(5006) << "Do not add " << storage->label() - << " to synclist" << endl; - } - } - node = folder()->child()->next(); - } - } - - // All done for this folder. - mProgress = 100; // all done - newState( mProgress, i18n("Synchronization done")); - KURL url = mAccount->getUrl(); - url.setPath( imapPath() ); - kmkernel->iCalIface().folderSynced( folder(), url ); + mSomeSubFolderCloseToQuotaChanged = false; + buildSubFolderList(); } - if ( !mRecurse ) // "check mail for this folder" only - mSubfoldersForSync.clear(); - // Carry on case SYNC_STATE_SYNC_SUBFOLDERS: - { - if( mCurrentSubfolder ) { - disconnectSubFolderSignals(); - } + syncNextSubFolder( false ); + break; + case SYNC_STATE_GET_SUBFOLDER_QUOTA: - if( mSubfoldersForSync.isEmpty() ) { - // Quota checking has to come after syncing subfolder, otherwise the quota information would - // be outdated, since the subfolders can change in size during the syncing. - // https://issues.kolab.org/issue4066 - mSyncState = SYNC_STATE_GET_QUOTA; - serverSyncInternal(); - } else { - mCurrentSubfolder = mSubfoldersForSync.front(); - mSubfoldersForSync.pop_front(); - connect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), - this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); - - //kdDebug(5006) << "Sync'ing subfolder " << mCurrentSubfolder->imapPath() << endl; - assert( !mCurrentSubfolder->imapPath().isEmpty() ); - mCurrentSubfolder->setAccount( account() ); - bool recurse = mCurrentSubfolder->noChildren() ? false : true; - mCurrentSubfolder->serverSync( recurse ); - } - } + // Sync the subfolders again, so that the quota information is updated for all. This state is + // only entered if the close to quota property of one subfolder changed in the previous state. + syncNextSubFolder( true ); break; case SYNC_STATE_GET_QUOTA: mSyncState = SYNC_STATE_CLOSE; if( !noContent() && mAccount->hasQuotaSupport() ) { + mProgress = 98; newState( mProgress, i18n("Getting quota information")); KURL url = mAccount->getUrl(); url.setPath( imapPath() ); @@ -1331,6 +1285,12 @@ void KMFolderCachedImap::serverSyncInternal() } case SYNC_STATE_CLOSE: { + mProgress = 100; // all done + newState( mProgress, i18n("Synchronization done")); + KURL url = mAccount->getUrl(); + url.setPath( imapPath() ); + kmkernel->iCalIface().folderSynced( folder(), url ); + mSyncState = SYNC_STATE_INITIAL; mAccount->addUnreadMsgCount( this, countUnread() ); // before closing close( "cachedimap" ); @@ -1340,14 +1300,83 @@ void KMFolderCachedImap::serverSyncInternal() default: kdDebug(5006) << "KMFolderCachedImap::serverSyncInternal() WARNING: no such state " - << mSyncState << endl; + << mSyncState << endl; } } +void KMFolderCachedImap::syncNextSubFolder( bool secondSync ) +{ + if( mCurrentSubfolder ) { + disconnectSubFolderSignals(); + } + + if( mSubfoldersForSync.isEmpty() ) { + + // Sync finished, and a close to quota property of an subfolder changed, therefore go into + // the SYNC_STATE_GET_SUBFOLDER_QUOTA state and sync again + if ( mSomeSubFolderCloseToQuotaChanged && mRecurse && !secondSync ) { + buildSubFolderList(); + mSyncState = SYNC_STATE_GET_SUBFOLDER_QUOTA; + serverSyncInternal(); + } + + else { + + // Quota checking has to come after syncing subfolder, otherwise the quota information would + // be outdated, since the subfolders can change in size during the syncing. + // https://issues.kolab.org/issue4066 + mSyncState = SYNC_STATE_GET_QUOTA; + serverSyncInternal(); + } + } else { + mCurrentSubfolder = mSubfoldersForSync.front(); + mSubfoldersForSync.pop_front(); + connect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), + this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); + connect( mCurrentSubfolder, SIGNAL( closeToQuotaChanged() ), + this, SLOT( slotSubFolderCloseToQuotaChanged() ) ); + + //kdDebug(5006) << "Sync'ing subfolder " << mCurrentSubfolder->imapPath() << endl; + assert( !mCurrentSubfolder->imapPath().isEmpty() ); + mCurrentSubfolder->setAccount( account() ); + bool recurse = mCurrentSubfolder->noChildren() ? false : true; + mCurrentSubfolder->serverSync( recurse ); + } +} + +void KMFolderCachedImap::buildSubFolderList() +{ + mSubfoldersForSync.clear(); + mCurrentSubfolder = 0; + if( folder() && folder()->child() ) { + KMFolderNode *node = folder()->child()->first(); + while( node ) { + if( !node->isDir() ) { + KMFolderCachedImap* storage = static_cast(static_cast(node)->storage()); + // Only sync folders that have been accepted by the server + if ( !storage->imapPath().isEmpty() + // and that were not just deleted from it + && !foldersForDeletionOnServer.contains( storage->imapPath() ) ) { + mSubfoldersForSync << storage; + } else { + kdDebug(5006) << "Do not add " << storage->label() + << " to synclist" << endl; + } + } + node = folder()->child()->next(); + } + } + + if ( !mRecurse ) // "check mail for this folder" only + mSubfoldersForSync.clear(); +} + void KMFolderCachedImap::disconnectSubFolderSignals() { disconnect( mCurrentSubfolder, SIGNAL( folderComplete(KMFolderCachedImap*, bool) ), this, SLOT( slotSubFolderComplete(KMFolderCachedImap*, bool) ) ); + disconnect( mCurrentSubfolder, SIGNAL( closeToQuotaChanged() ), + this, SLOT( slotSubFolderCloseToQuotaChanged() ) ); mCurrentSubfolder = 0; } @@ -2361,6 +2390,11 @@ void KMFolderCachedImap::slotSubFolderComplete(KMFolderCachedImap* sub, bool suc } } +void KMFolderCachedImap::slotSubFolderCloseToQuotaChanged() +{ + mSomeSubFolderCloseToQuotaChanged = true; +} + void KMFolderCachedImap::slotSimpleData(KIO::Job * job, const QByteArray & data) { KMAcctCachedImap::JobIterator it = mAccount->findJob(job); @@ -2444,8 +2478,12 @@ KMFolderCachedImap::slotStorageQuotaResult( const QuotaInfo& info ) void KMFolderCachedImap::setQuotaInfo( const QuotaInfo & info ) { if ( info != mQuotaInfo ) { + const bool wasCloseToQuota = isCloseToQuota(); mQuotaInfo = info; writeConfigKeysWhichShouldNotGetOverwrittenByReadConfig(); + if ( wasCloseToQuota != isCloseToQuota() ) { + emit closeToQuotaChanged(); + } emit folderSizeChanged(); } } diff --git a/kmfoldercachedimap.h b/kmfoldercachedimap.h index b7e32c530..5e85c7a3c 100644 --- a/kmfoldercachedimap.h +++ b/kmfoldercachedimap.h @@ -342,6 +342,7 @@ protected slots: //virtual void slotCheckValidityResult(KIO::Job * job); void slotSubFolderComplete(KMFolderCachedImap*, bool); + void slotSubFolderCloseToQuotaChanged(); // Connected to the imap account void slotConnectionResult( int errorCode, const QString& errorMsg ); @@ -441,6 +442,11 @@ signals: void folderComplete(KMFolderCachedImap *folder, bool success); void listComplete( KMFolderCachedImap* ); + /** + * Emitted when isCloseToQuota() changes during syncing + */ + void closeToQuotaChanged(); + /** emitted when we enter the state "state" and have to process "number" items (for example messages */ @@ -464,6 +470,10 @@ private: */ void disconnectSubFolderSignals(); + void syncNextSubFolder( bool secondSync ); + + void buildSubFolderList(); + /** State variable for the synchronization mechanism */ enum { SYNC_STATE_INITIAL, @@ -490,7 +500,8 @@ private: SYNC_STATE_SYNC_SUBFOLDERS, SYNC_STATE_CHECK_UIDVALIDITY, SYNC_STATE_RENAME_FOLDER, - SYNC_STATE_CLOSE + SYNC_STATE_CLOSE, + SYNC_STATE_GET_SUBFOLDER_QUOTA } mSyncState; int mProgress; @@ -585,6 +596,11 @@ private: QString mImapPathCreation; QuotaInfo mQuotaInfo; + + /// This is set during syncing of the current subfolder. If true, it means the closeToQuota info + /// for the current subfolder has changed during syncing + bool mSomeSubFolderCloseToQuotaChanged; + QMap mDeletedUIDsSinceLastSync; bool mAlarmsBlocked; From 45a6dad17852ba9ada12d2929fa18554c2af67ee Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Mar 2010 17:06:35 +0000 Subject: [PATCH 144/160] Make re-checking the subfolders to update the quota info only check for quota, nothing else. kolab/issue4066 MERGE: trunk (like the other related fixes where I forgot the MERGE keyword) svn path=/branches/kdepim/enterprise/kdepim/; revision=1101227 --- kmfoldercachedimap.cpp | 69 ++++++++++++++++++++++++------------------ kmfoldercachedimap.h | 11 ++++++- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/kmfoldercachedimap.cpp b/kmfoldercachedimap.cpp index 148c989ae..bd4ebd877 100644 --- a/kmfoldercachedimap.cpp +++ b/kmfoldercachedimap.cpp @@ -196,6 +196,7 @@ KMFolderCachedImap::KMFolderCachedImap( KMFolder* folder, const char* aName ) /*mHoldSyncs( false ),*/ mFolderRemoved( false ), mRecurse( true ), + mQuotaOnly( false ), mAnnotationFolderTypeChanged( false ), mIncidencesForChanged( false ), mSharedSeenFlagsChanged( false ), @@ -758,7 +759,7 @@ void KMFolderCachedImap::slotTroubleshoot() } } -void KMFolderCachedImap::serverSync( bool recurse ) +void KMFolderCachedImap::serverSync( bool recurse, bool quotaOnly ) { if( mSyncState != SYNC_STATE_INITIAL ) { if( KMessageBox::warningYesNo( 0, i18n("Folder %1 is not in initial sync state (state was %2). Do you want to reset it to initial sync state and sync anyway?" ).arg( imapPath() ).arg( mSyncState ), QString::null, i18n("Reset && Sync"), KStdGuiItem::cancel() ) == KMessageBox::Yes ) { @@ -767,6 +768,7 @@ void KMFolderCachedImap::serverSync( bool recurse ) } mRecurse = recurse; + mQuotaOnly = quotaOnly; assert( account() ); ProgressItem *progressItem = mAccount->mailCheckProgressItem(); @@ -911,7 +913,7 @@ void KMFolderCachedImap::serverSyncInternal() mSyncState = SYNC_STATE_RENAME_FOLDER; - if( !noContent() && mAccount->hasACLSupport() ) { + if( !mQuotaOnly && !noContent() && mAccount->hasACLSupport() ) { // Check the user's own rights. We do this every time in case they changed. mOldUserRights = mUserRights; newState( mProgress, i18n("Checking permissions")); @@ -939,7 +941,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_CHECK_UIDVALIDITY: mSyncState = SYNC_STATE_CREATE_SUBFOLDERS; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { checkUidValidity(); break; } @@ -947,19 +949,21 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_CREATE_SUBFOLDERS: mSyncState = SYNC_STATE_PUT_MESSAGES; - createNewFolders(); - break; + if ( !mQuotaOnly ) { + createNewFolders(); + break; + } case SYNC_STATE_PUT_MESSAGES: mSyncState = SYNC_STATE_UPLOAD_FLAGS; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { uploadNewMessages(); break; } // Else carry on case SYNC_STATE_UPLOAD_FLAGS: mSyncState = SYNC_STATE_LIST_NAMESPACES; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { // We haven't downloaded messages yet, so we need to build the map. if( uidMapDirty ) reloadUidMap(); @@ -982,7 +986,7 @@ void KMFolderCachedImap::serverSyncInternal() // Else carry on case SYNC_STATE_LIST_NAMESPACES: - if ( this == mAccount->rootFolder() ) { + if ( !mQuotaOnly && this == mAccount->rootFolder() ) { listNamespaces(); break; } @@ -992,22 +996,26 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_LIST_SUBFOLDERS: newState( mProgress, i18n("Retrieving folderlist")); mSyncState = SYNC_STATE_LIST_SUBFOLDERS2; - if( !listDirectory() ) { - mSyncState = SYNC_STATE_INITIAL; - KMessageBox::error(0, i18n("Error while retrieving the folderlist")); + if ( !mQuotaOnly ) { + if( !listDirectory() ) { + mSyncState = SYNC_STATE_INITIAL; + KMessageBox::error(0, i18n("Error while retrieving the folderlist")); + } + break; } - break; case SYNC_STATE_LIST_SUBFOLDERS2: mSyncState = SYNC_STATE_DELETE_SUBFOLDERS; mProgress += 10; - newState( mProgress, i18n("Retrieving subfolders")); - listDirectory2(); - break; + if ( !mQuotaOnly ) { + newState( mProgress, i18n("Retrieving subfolders")); + listDirectory2(); + break; + } case SYNC_STATE_DELETE_SUBFOLDERS: mSyncState = SYNC_STATE_LIST_MESSAGES; - if( !foldersForDeletionOnServer.isEmpty() ) { + if( !mQuotaOnly && !foldersForDeletionOnServer.isEmpty() ) { newState( mProgress, i18n("Deleting folders from server")); CachedImapJob* job = new CachedImapJob( foldersForDeletionOnServer, CachedImapJob::tDeleteFolders, this ); @@ -1022,7 +1030,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_LIST_MESSAGES: mSyncState = SYNC_STATE_DELETE_MESSAGES; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { newState( mProgress, i18n("Retrieving message list")); listMessages(); break; @@ -1031,7 +1039,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_DELETE_MESSAGES: mSyncState = SYNC_STATE_EXPUNGE_MESSAGES; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { if( deleteMessages() ) { // Fine, we will continue with the next state } else { @@ -1046,7 +1054,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_EXPUNGE_MESSAGES: mSyncState = SYNC_STATE_GET_MESSAGES; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { newState( mProgress, i18n("Expunging deleted messages")); CachedImapJob *job = new CachedImapJob( QString::null, CachedImapJob::tExpungeFolder, this ); @@ -1059,7 +1067,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_GET_MESSAGES: mSyncState = SYNC_STATE_HANDLE_INBOX; - if( !noContent() ) { + if( !mQuotaOnly && !noContent() ) { if( !mMsgsForDownload.isEmpty() ) { newState( mProgress, i18n("Retrieving new messages")); CachedImapJob *job = new CachedImapJob( mMsgsForDownload, @@ -1102,7 +1110,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_TEST_ANNOTATIONS: mSyncState = SYNC_STATE_GET_ANNOTATIONS; // The first folder with user rights to write annotations - if( !mAccount->annotationCheckPassed() && + if( !mQuotaOnly && !mAccount->annotationCheckPassed() && ( mUserRights <= 0 || ( mUserRights & ACLJobs::Administer ) ) && !imapPath().isEmpty() && imapPath() != "/" ) { kdDebug(5006) << "Setting test attribute on folder: "<< folder()->prettyURL() << endl; @@ -1134,7 +1142,7 @@ void KMFolderCachedImap::serverSyncInternal() mSyncState = SYNC_STATE_SET_ANNOTATIONS; bool needToGetInitialAnnotations = false; - if ( !noContent() ) { + if ( !mQuotaOnly && !noContent() ) { // for a folder we didn't create ourselves: get annotation from server if ( mAnnotationFolderType == "FROMSERVER" ) { needToGetInitialAnnotations = true; @@ -1146,7 +1154,7 @@ void KMFolderCachedImap::serverSyncInternal() // First retrieve the annotation, so that we know we have to set it if it's not set. // On the other hand, if the user changed the contentstype, there's no need to get first. - if ( !noContent() && mAccount->hasAnnotationSupport() && + if ( !mQuotaOnly && !noContent() && mAccount->hasAnnotationSupport() && ( kmkernel->iCalIface().isEnabled() || needToGetInitialAnnotations ) ) { QStringList annotations; // list of annotations to be fetched if ( !mAnnotationFolderTypeChanged || mAnnotationFolderType.isEmpty() ) @@ -1176,7 +1184,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_SET_ANNOTATIONS: mSyncState = SYNC_STATE_SET_ACLS; - if ( !noContent() && mAccount->hasAnnotationSupport() && + if ( !mQuotaOnly && !noContent() && mAccount->hasAnnotationSupport() && ( mUserRights <= 0 || ( mUserRights & ACLJobs::Administer ) ) ) { newState( mProgress, i18n("Setting annotations")); KURL url = mAccount->getUrl(); @@ -1217,7 +1225,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_SET_ACLS: mSyncState = SYNC_STATE_GET_ACLS; - if( !noContent() && mAccount->hasACLSupport() && + if( !mQuotaOnly && !noContent() && mAccount->hasACLSupport() && ( mUserRights <= 0 || ( mUserRights & ACLJobs::Administer ) ) ) { bool hasChangedACLs = false; ACLList::ConstIterator it = mACLList.begin(); @@ -1243,7 +1251,7 @@ void KMFolderCachedImap::serverSyncInternal() case SYNC_STATE_GET_ACLS: mSyncState = SYNC_STATE_FIND_SUBFOLDERS; - if( !noContent() && mAccount->hasACLSupport() ) { + if( !mQuotaOnly && !noContent() && mAccount->hasACLSupport() ) { newState( mProgress, i18n( "Retrieving permissions" ) ); mAccount->getACL( folder(), mImapPath ); connect( mAccount, SIGNAL(receivedACL( KMFolder*, KIO::Job*, const KMail::ACLList& )), @@ -1339,8 +1347,9 @@ void KMFolderCachedImap::syncNextSubFolder( bool secondSync ) //kdDebug(5006) << "Sync'ing subfolder " << mCurrentSubfolder->imapPath() << endl; assert( !mCurrentSubfolder->imapPath().isEmpty() ); mCurrentSubfolder->setAccount( account() ); - bool recurse = mCurrentSubfolder->noChildren() ? false : true; - mCurrentSubfolder->serverSync( recurse ); + const bool recurse = mCurrentSubfolder->noChildren() ? false : true; + const bool quotaOnly = secondSync || mQuotaOnly; + mCurrentSubfolder->serverSync( recurse, quotaOnly ); } } @@ -2392,7 +2401,9 @@ void KMFolderCachedImap::slotSubFolderComplete(KMFolderCachedImap* sub, bool suc void KMFolderCachedImap::slotSubFolderCloseToQuotaChanged() { - mSomeSubFolderCloseToQuotaChanged = true; + if ( !mQuotaOnly ) { + mSomeSubFolderCloseToQuotaChanged = true; + } } void KMFolderCachedImap::slotSimpleData(KIO::Job * job, const QByteArray & data) diff --git a/kmfoldercachedimap.h b/kmfoldercachedimap.h index 5e85c7a3c..81e485f55 100644 --- a/kmfoldercachedimap.h +++ b/kmfoldercachedimap.h @@ -125,7 +125,7 @@ public: virtual void remove(); /** Synchronize this folder and it's subfolders with the server */ - virtual void serverSync( bool recurse ); + virtual void serverSync( bool recurse, bool quotaOnly = false ); /** Force the sync state to be done. */ void resetSyncState( ); @@ -470,8 +470,16 @@ private: */ void disconnectSubFolderSignals(); + /** + * Sync the next subfolder in the list of subfolders (mSubfoldersForSync). + * When finished, this will switch either to the state SYNC_STATE_GET_SUBFOLDER_QUOTA or + * to SYNC_STATE_GET_QUOTA. + */ void syncNextSubFolder( bool secondSync ); + /** + * Creates the mSubfoldersForSync list + */ void buildSubFolderList(); /** State variable for the synchronization mechanism */ @@ -568,6 +576,7 @@ private: bool mFolderRemoved; //bool mHoldSyncs; bool mRecurse; + bool mQuotaOnly; /// Set to true when the foldertype annotation needs to be set on the next sync bool mAnnotationFolderTypeChanged; From 8c5d178f4a64d3d9b529ce2bffa909cefbce6cb3 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Mar 2010 18:17:45 +0000 Subject: [PATCH 145/160] Make sure the subdirs always have the x attribute. https://issues.kolab.org/issue4098 svn path=/branches/kdepim/enterprise/kdepim/; revision=1101244 --- importjob.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/importjob.cpp b/importjob.cpp index 14332834a..3911e676c 100644 --- a/importjob.cpp +++ b/importjob.cpp @@ -118,8 +118,8 @@ KMFolder * ImportJob::createSubFolder( KMFolder *parent, const QString &folderNa newFolder->createChildFolder(); // TODO: Just creating a child folder here is wasteful, only do // that if really needed. We do it here so we can set the // permissions - chmod( newFolder->location().latin1(), permissions ); - chmod( newFolder->subdirLocation().latin1(), permissions ); + chmod( newFolder->location().latin1(), permissions | S_IXUSR ); + chmod( newFolder->subdirLocation().latin1(), permissions | S_IXUSR ); // TODO: chown? // TODO: what about subdirectories like "cur"? return newFolder; From 59172656afaf1c281b24f8164c85cf1a8e87f84e Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Mar 2010 20:18:28 +0000 Subject: [PATCH 146/160] When encountering a Toltec invitation, display a configurable explanation text instead of the raw Toltec garbage. First part of kolab/issue3596 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1101273 --- kmail.kcfg | 10 ++++++++++ kmreaderwin.cpp | 5 ++++- objecttreeparser.cpp | 15 +++++++++++++++ objecttreeparser.h | 11 +++++++++++ partNode.cpp | 27 +++++++++++++++++++++++++++ partNode.h | 2 ++ 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/kmail.kcfg b/kmail.kcfg index cb804d5ff..a36d1b150 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -215,6 +215,16 @@ true + + + true + + + + + This message is a <i>Toltec</i> Groupware object, it can only be viewed with Microsoft Outlook in combination with the Toltec connector. + + diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index faf6c778e..cd0a014f8 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -1526,7 +1526,10 @@ void KMReaderWin::parseMsg(KMMessage* aMsg) writeMessagePartToTempFile( &vCardNode->msgPart(), vCardNode->nodeId() ); } } - htmlWriter()->queue( writeMsgHeader(aMsg, hasVCard ? vCardNode : 0, true ) ); + + if ( !mRootNode || !mRootNode->isToltecMessage() ) { + htmlWriter()->queue( writeMsgHeader(aMsg, hasVCard ? vCardNode : 0, true ) ); + } // show message content ObjectTreeParser otp( this ); diff --git a/objecttreeparser.cpp b/objecttreeparser.cpp index 1e66b7c28..f35dab6b1 100644 --- a/objecttreeparser.cpp +++ b/objecttreeparser.cpp @@ -1212,7 +1212,22 @@ namespace KMail { mTextualContentCharset = otp.textualContentCharset(); } + bool ObjectTreeParser::processToltecMail( partNode *node ) + { + if ( !node || !mHtmlWriter || !GlobalSettings::self()->showToltecReplacementText() || + !node->isToltecMessage() ) + return false; + + htmlWriter()->queue( GlobalSettings::self()->toltecReplacementText() ); + return true; + } + bool ObjectTreeParser::processMultiPartMixedSubtype( partNode * node, ProcessResult & ) { + + if ( processToltecMail( node ) ) { + return true; + } + partNode * child = node->firstChild(); if ( !child ) return false; diff --git a/objecttreeparser.h b/objecttreeparser.h index e6f7927e1..20bbbf4d9 100644 --- a/objecttreeparser.h +++ b/objecttreeparser.h @@ -232,6 +232,17 @@ namespace KMail { bool processMailmanMessage( partNode * node ); + /** + * This is called for all multipart/mixed nodes. It checks if that belongs to a Toltec mail, + * by checking various criteria. + * If it is a toltec mail, a special text, instead of the confusing toltec text, will be + * displayed. + * + * @return true if the mail was indeed a toltec mail, in which case the node should not be + * processed further + */ + bool processToltecMail( partNode * node ); + /** Checks whether @p str contains external references. To be precise, we only check whether @p str contains 'xxx="http[s]:' where xxx is not href. Obfuscated external references are ignored on purpose. diff --git a/partNode.cpp b/partNode.cpp index ac924e58d..7a45caa3e 100644 --- a/partNode.cpp +++ b/partNode.cpp @@ -641,6 +641,33 @@ bool partNode::isFirstTextPart() const { return false; // make comiler happy } +bool partNode::isToltecMessage() const +{ + if ( type() != DwMime::kTypeMultipart || subType() != DwMime::kSubtypeMixed ) + return false; + + if ( childCount() != 3 ) + return false; + + const DwField* library = dwPart()->Headers().FindField( "X-Library" ); + if ( !library ) + return false; + + if ( !library->FieldBody() || + QString( library->FieldBody()->AsString().c_str() ) != QString( "Toltec" ) ) + return false; + + const DwField* kolabType = dwPart()->Headers().FindField( "X-Kolab-Type" ); + if ( !kolabType ) + return false; + + if ( !kolabType->FieldBody() || + !QString( kolabType->FieldBody()->AsString().c_str() ).startsWith( "application/x-vnd.kolab" ) ) + return false; + + return true; +} + bool partNode::hasContentDispositionInline() const { if( !dwPart() ) diff --git a/partNode.h b/partNode.h index 047c71df1..53ab4244f 100644 --- a/partNode.h +++ b/partNode.h @@ -226,6 +226,8 @@ public: */ bool isFirstTextPart() const; + bool isToltecMessage() const; + bool hasContentDispositionInline() const; QString contentTypeParameter( const char * name ) const; From 035b365ea8cdaf414e0333bb97b8812152a2ca7f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Mar 2010 20:40:15 +0000 Subject: [PATCH 147/160] When hiding the raw toltec mail, add a link to show the raw mail again. Part of kolab/issue3596 MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1101284 --- kmreaderwin.cpp | 7 +++++-- kmreaderwin.h | 6 ++++++ objecttreeparser.cpp | 4 +++- objecttreeparser.h | 6 ++++++ urlhandlermanager.cpp | 7 +++++++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index cd0a014f8..a2a0da997 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -439,7 +439,8 @@ KMReaderWin::KMReaderWin(QWidget *aParent, mSavedRelativePosition( 0 ), mDecrytMessageOverwrite( false ), mShowSignatureDetails( false ), - mShowAttachmentQuicklist( true ) + mShowAttachmentQuicklist( true ), + mShowRawToltecMail( false ) { mExternalWindow = (aParent == mainWindow ); mSplitterSizes << 180 << 100; @@ -1129,6 +1130,7 @@ void KMReaderWin::setMsg( KMMessage* aMsg, bool force ) // Reset message-transient state if (aMsg && aMsg->getMsgSerNum() != mLastSerNum ){ mLevelQuote = GlobalSettings::self()->collapseQuoteLevelSpin()-1; + mShowRawToltecMail = !GlobalSettings::self()->showToltecReplacementText(); clearBodyPartMementos(); } if ( mPrinting ) @@ -1527,13 +1529,14 @@ void KMReaderWin::parseMsg(KMMessage* aMsg) } } - if ( !mRootNode || !mRootNode->isToltecMessage() ) { + if ( !mRootNode || !mRootNode->isToltecMessage() || mShowRawToltecMail ) { htmlWriter()->queue( writeMsgHeader(aMsg, hasVCard ? vCardNode : 0, true ) ); } // show message content ObjectTreeParser otp( this ); otp.setAllowAsync( true ); + otp.setShowRawToltecMail( mShowRawToltecMail ); otp.parseObjectTree( mRootNode ); // store encrypted/signed status information in the KMMessage diff --git a/kmreaderwin.h b/kmreaderwin.h index 489fbaa60..91b272ec4 100644 --- a/kmreaderwin.h +++ b/kmreaderwin.h @@ -323,6 +323,11 @@ public: /* show or hide the list that points to the attachments */ void setShowAttachmentQuicklist( bool showAttachmentQuicklist = true ) { mShowAttachmentQuicklist = showAttachmentQuicklist; } + // This controls whether a Toltec invitation is shown in its raw form or as a replacement text. + // This can be toggled with the "kmail:showRawToltecMail" link. + bool showRawToltecMail() const { return mShowRawToltecMail; } + void setShowRawToltecMail( bool showRawToltecMail ) { mShowRawToltecMail = showRawToltecMail; } + /* retrieve BodyPartMemento of id \a which for partNode \a node */ KMail::Interface::BodyPartMemento * bodyPartMemento( const partNode * node, const QCString & which ) const; @@ -601,6 +606,7 @@ private: bool mDecrytMessageOverwrite; bool mShowSignatureDetails; bool mShowAttachmentQuicklist; + bool mShowRawToltecMail; bool mExternalWindow; }; diff --git a/objecttreeparser.cpp b/objecttreeparser.cpp index f35dab6b1..fee293c9d 100644 --- a/objecttreeparser.cpp +++ b/objecttreeparser.cpp @@ -150,6 +150,7 @@ namespace KMail { mIncludeSignatures( includeSignatures ), mHasPendingAsyncJobs( false ), mAllowAsync( false ), + mShowRawToltecMail( false ), mAttachmentStrategy( strategy ), mHtmlWriter( htmlWriter ), mCSSHelper( cssHelper ) @@ -1215,10 +1216,11 @@ namespace KMail { bool ObjectTreeParser::processToltecMail( partNode *node ) { if ( !node || !mHtmlWriter || !GlobalSettings::self()->showToltecReplacementText() || - !node->isToltecMessage() ) + !node->isToltecMessage() || mShowRawToltecMail ) return false; htmlWriter()->queue( GlobalSettings::self()->toltecReplacementText() ); + htmlWriter()->queue( "

Show Raw Message" ); return true; } diff --git a/objecttreeparser.h b/objecttreeparser.h index 20bbbf4d9..6b1670a1e 100644 --- a/objecttreeparser.h +++ b/objecttreeparser.h @@ -151,6 +151,11 @@ namespace KMail { mIncludeSignatures = include; } + // Controls whether Toltec invitations are displayed in their raw form or as a replacement text, + // which is used in processToltecMail(). + void setShowRawToltecMail( bool showRawToltecMail ) { mShowRawToltecMail = showRawToltecMail; } + bool showRawToltecMail() const { return mShowRawToltecMail; } + const KMail::AttachmentStrategy * attachmentStrategy() const { return mAttachmentStrategy; } @@ -329,6 +334,7 @@ namespace KMail { bool mIncludeSignatures; bool mHasPendingAsyncJobs; bool mAllowAsync; + bool mShowRawToltecMail; const KMail::AttachmentStrategy * mAttachmentStrategy; KMail::HtmlWriter * mHtmlWriter; KMail::CSSHelper * mCSSHelper; diff --git a/urlhandlermanager.cpp b/urlhandlermanager.cpp index ed3d86cca..cc3dc8a96 100644 --- a/urlhandlermanager.cpp +++ b/urlhandlermanager.cpp @@ -456,6 +456,13 @@ namespace { return true; } + if ( url.path() == "showRawToltecMail" ) { + w->saveRelativePosition(); + w->setShowRawToltecMail( true ); + w->update( true ); + return true; + } + // if ( url.path() == "startIMApp" ) // { // kmkernel->imProxy()->startPreferredApp(); From c495d54e95a4f561f8382ac53efd39a8d7e4c7de Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 9 Mar 2010 20:49:16 +0000 Subject: [PATCH 148/160] Repair level quoting and the "show raw mail" link when using the standalone viewer. MERGE: trunk (but with a bit of refactoring) svn path=/branches/kdepim/enterprise/kdepim/; revision=1101287 --- kmreaderwin.cpp | 6 +++--- kmreaderwin.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index a2a0da997..0544e7634 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -1121,14 +1121,14 @@ void KMReaderWin::setOriginalMsg( unsigned long serNumOfOriginalMessage, int nod } //----------------------------------------------------------------------------- -void KMReaderWin::setMsg( KMMessage* aMsg, bool force ) +void KMReaderWin::setMsg( KMMessage* aMsg, bool force, bool updateOnly ) { if (aMsg) kdDebug(5006) << "(" << aMsg->getMsgSerNum() << ", last " << mLastSerNum << ") " << aMsg->subject() << " " << aMsg->fromStrip() << ", readyToShow " << (aMsg->readyToShow()) << endl; // Reset message-transient state - if (aMsg && aMsg->getMsgSerNum() != mLastSerNum ){ + if ( aMsg && aMsg->getMsgSerNum() != mLastSerNum && !updateOnly ){ mLevelQuote = GlobalSettings::self()->collapseQuoteLevelSpin()-1; mShowRawToltecMail = !GlobalSettings::self()->showToltecReplacementText(); clearBodyPartMementos(); @@ -2416,7 +2416,7 @@ void KMReaderWin::update( bool force ) { KMMessage* msg = message(); if ( msg ) - setMsg( msg, force ); + setMsg( msg, force, true /* updateOnly */ ); } diff --git a/kmreaderwin.h b/kmreaderwin.h index 91b272ec4..2b35fcdf4 100644 --- a/kmreaderwin.h +++ b/kmreaderwin.h @@ -142,7 +142,7 @@ public: /** Set the message that shall be shown. If msg is 0, an empty page is displayed. */ - virtual void setMsg( KMMessage* msg, bool force = false ); + virtual void setMsg( KMMessage* msg, bool force = false, bool updateOnly = false ); /** * This should be called when setting a message that was constructed from another message, which From 4e46cffa0cfb2aa5421b3c47074d6cebf0eaefd3 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 11 Mar 2010 07:25:55 +0000 Subject: [PATCH 149/160] Remove the word from mReplacements only _after_ using mReplacements. Now replacing words works again. Patch by Sergio. kolab/issue4201 MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1101864 --- kmedit.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kmedit.cpp b/kmedit.cpp index 1c2330b48..0a250b843 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -525,11 +525,6 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) //Execute the popup inline const int id = p.exec( mapToGlobal( event->pos() ) ); - if ( id != -1 ) { - // No longer misspelled: Either added to dictionary, ignored or replaced - mReplacements.remove( word ); - } - if ( id == ignoreId ) { mHighlighter->ignoreWord( word ); mHighlighter->rehighlight(); @@ -556,6 +551,12 @@ bool KMEdit::eventFilter(QObject*o, QEvent* e) txtIdx += mReplacements[word][id].length() - word.length(); setCursorPosition(parIdx, txtIdx); } + + if ( id == addToDictionaryId || id == ignoreId ) { + // No longer misspelled: Either added to dictionary or ignored + mReplacements.remove( word ); + } + //Cancel original event return true; } From 4d26420734c009328decca6b74bc9a27a8f0b86d Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 11 Mar 2010 07:31:09 +0000 Subject: [PATCH 150/160] warning-- MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1101868 --- kmedit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmedit.cpp b/kmedit.cpp index 0a250b843..f4bf5a810 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -795,7 +795,7 @@ void KMEdit::slotSpellcheck2(KSpell*) { // Make sure words ignored by the highlighter are ignored by KSpell as well if ( mHighlighter ) { - for ( int i = 0; i < mHighlighter->ignoredWords().size(); i++ ) + for ( uint i = 0; i < mHighlighter->ignoredWords().size(); i++ ) mKSpellForDialog->ignore( mHighlighter->ignoredWords()[i] ); } From afe7f009288dcc6bb85eac9547b844c0ac152b62 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 11 Mar 2010 07:41:20 +0000 Subject: [PATCH 151/160] Make it translateable. MERGE: trunk svn path=/branches/kdepim/enterprise/kdepim/; revision=1101873 --- objecttreeparser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/objecttreeparser.cpp b/objecttreeparser.cpp index fee293c9d..57c8d6add 100644 --- a/objecttreeparser.cpp +++ b/objecttreeparser.cpp @@ -1220,7 +1220,8 @@ namespace KMail { return false; htmlWriter()->queue( GlobalSettings::self()->toltecReplacementText() ); - htmlWriter()->queue( "

Show Raw Message" ); + htmlWriter()->queue( "

" + + i18n( "Show Raw Message" ) + "" ); return true; } From b91a74564e85273204e758d6b06d882f6faeee20 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 11 Mar 2010 09:18:19 +0000 Subject: [PATCH 152/160] Git rid of some excessive debug that occurred on every message switch. MERGE: none (already in trunk, I think) svn path=/branches/kdepim/enterprise/kdepim/; revision=1101901 --- kmmimeparttree.cpp | 2 - kmreaderwin.cpp | 39 +++++------- objecttreeparser.cpp | 145 +++++++++++++++++++++---------------------- partNode.cpp | 30 ++------- 4 files changed, 92 insertions(+), 124 deletions(-) diff --git a/kmmimeparttree.cpp b/kmmimeparttree.cpp index 606b6891d..c14be2a02 100644 --- a/kmmimeparttree.cpp +++ b/kmmimeparttree.cpp @@ -129,8 +129,6 @@ void KMMimePartTree::itemRightClicked( QListViewItem* item, kdDebug(5006) << "Item was not a KMMimePartTreeItem!" << endl; } else { - kdDebug(5006) << "\n**\n** KMMimePartTree::itemRightClicked() **\n**" << endl; - QPopupMenu* popup = new QPopupMenu; if ( mCurrentContextMenuItem->node()->nodeId() > 2 && mCurrentContextMenuItem->node()->typeString() != "Multipart" ) { diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index 0544e7634..a4149486f 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -698,8 +698,6 @@ void KMReaderWin::slotAllHeaders() { void KMReaderWin::slotLevelQuote( int l ) { - kdDebug( 5006 ) << "Old Level: " << mLevelQuote << " New Level: " << l << endl; - mLevelQuote = l; saveRelativePosition(); update(true); @@ -781,7 +779,7 @@ void KMReaderWin::slotMessageArrived( KMMessage *msg ) if ( msg->getMsgSerNum() == mWaitingForSerNum ) { setMsg( msg, true ); } else { - kdDebug( 5006 ) << "KMReaderWin::slotMessageArrived - ignoring update" << endl; + //kdDebug( 5006 ) << "KMReaderWin::slotMessageArrived - ignoring update" << endl; } } } @@ -791,7 +789,7 @@ void KMReaderWin::update( KMail::Interface::Observable * observable ) { if ( !mAtmUpdate ) { // reparse the msg - kdDebug(5006) << "KMReaderWin::update - message" << endl; + //kdDebug(5006) << "KMReaderWin::update - message" << endl; updateReaderWin(); return; } @@ -1085,7 +1083,6 @@ void KMReaderWin::setPrintFont( const QFont& font ) //----------------------------------------------------------------------------- const QTextCodec * KMReaderWin::overrideCodec() const { - kdDebug(5006) << k_funcinfo << " mOverrideEncoding == '" << mOverrideEncoding << "'" << endl; if ( mOverrideEncoding.isEmpty() || mOverrideEncoding == "Auto" ) // Auto return 0; else @@ -1123,9 +1120,10 @@ void KMReaderWin::setOriginalMsg( unsigned long serNumOfOriginalMessage, int nod //----------------------------------------------------------------------------- void KMReaderWin::setMsg( KMMessage* aMsg, bool force, bool updateOnly ) { - if (aMsg) - kdDebug(5006) << "(" << aMsg->getMsgSerNum() << ", last " << mLastSerNum << ") " << aMsg->subject() << " " - << aMsg->fromStrip() << ", readyToShow " << (aMsg->readyToShow()) << endl; + if ( aMsg ) { + kdDebug(5006) << "(" << aMsg->getMsgSerNum() << ", last " << mLastSerNum << ") " << aMsg->subject() << " " + << aMsg->fromStrip() << ", readyToShow " << (aMsg->readyToShow()) << endl; + } // Reset message-transient state if ( aMsg && aMsg->getMsgSerNum() != mLastSerNum && !updateOnly ){ @@ -1466,20 +1464,13 @@ void KMReaderWin::displayMessage() { static bool message_was_saved_decrypted_before( const KMMessage * msg ) { if ( !msg ) return false; - kdDebug(5006) << "msgId = " << msg->msgId() << endl; + //kdDebug(5006) << "msgId = " << msg->msgId() << endl; return msg->msgId().stripWhiteSpace().startsWith( "msgPart(), vCardNode->nodeId() ); } } @@ -2928,14 +2918,17 @@ void KMReaderWin::setBodyPartMemento( const partNode * node, const QCString & wh delete it->second; - if ( memento ) + if ( memento ) { it->second = memento; - else + } + else { mBodyPartMementoMap.erase( it ); + } } else { - if ( memento ) + if ( memento ) { mBodyPartMementoMap.insert( it, std::make_pair( index, memento ) ); + } } if ( Observable * o = memento ? memento->asObservable() : 0 ) { @@ -2949,10 +2942,12 @@ BodyPartMemento * KMReaderWin::bodyPartMemento( const partNode * node, const QCS { const QCString index = node->path() + ':' + which.lower(); const std::map::const_iterator it = mBodyPartMementoMap.find( index ); - if ( it == mBodyPartMementoMap.end() ) + if ( it == mBodyPartMementoMap.end() ) { return 0; - else + } + else { return it->second; + } } void KMReaderWin::clearBodyPartMementos() diff --git a/objecttreeparser.cpp b/objecttreeparser.cpp index 57c8d6add..62a5c99ac 100644 --- a/objecttreeparser.cpp +++ b/objecttreeparser.cpp @@ -223,16 +223,11 @@ namespace KMail { parentNode->setFirstChild( newNode ); if ( startNode.mimePartTreeItem() ) { - kdDebug(5006) << "\n -----> Inserting items into MimePartTree\n" << endl; newNode->fillMimePartTree( startNode.mimePartTreeItem(), 0, QString::null, QString::null, QString::null, 0, append ); - kdDebug(5006) << "\n <----- Finished inserting items into MimePartTree\n" << endl; } else { - kdDebug(5006) << "\n ------ Sorry, node.mimePartTreeItem() returns ZERO so" - << "\n we cannot insert new lines into MimePartTree. :-(\n" << endl; } - kdDebug(5006) << "\n -----> Now parsing the MimePartTree\n" << endl; ObjectTreeParser otp( mReader, cryptoProtocol() ); otp.parseObjectTree( newNode ); if ( addToTextualContent ) { @@ -241,17 +236,16 @@ namespace KMail { if ( !otp.textualContentCharset().isEmpty() ) mTextualContentCharset = otp.textualContentCharset(); } - kdDebug(5006) << "\n <----- Finished parsing the MimePartTree in insertAndParseNewChildNode()\n" << endl; } //----------------------------------------------------------------------------- void ObjectTreeParser::parseObjectTree( partNode * node ) { - kdDebug(5006) << "ObjectTreeParser::parseObjectTree( " - << (node ? "node OK, " : "no node, ") - << "showOnlyOneMimePart: " << (showOnlyOneMimePart() ? "TRUE" : "FALSE") - << " )" << endl; + //kdDebug(5006) << "ObjectTreeParser::parseObjectTree( " + // << (node ? "node OK, " : "no node, ") + // << "showOnlyOneMimePart: " << (showOnlyOneMimePart() ? "TRUE" : "FALSE") + // << " )" << endl; if ( !node ) return; @@ -427,18 +421,22 @@ namespace KMail { } #ifndef NDEBUG - if ( !doCheck ) - kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: showing OpenPGP (Encrypted+Signed) data" << endl; - else - if ( data ) - kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: processing Multipart Signed data" << endl; - else - kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: processing Opaque Signed data" << endl; + if ( !doCheck ) { + //kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: showing OpenPGP (Encrypted+Signed) data" << endl; + } + else { + if ( data ) { + //kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: processing Multipart Signed data" << endl; + } + else { + //kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: processing Opaque Signed data" << endl; + } + } #endif if ( doCheck && cryptProto ) { - kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: going to call CRYPTPLUG " - << cryptPlugLibName << endl; + //kdDebug(5006) << "ObjectTreeParser::writeOpaqueOrMultipartSignedData: going to call CRYPTPLUG " + // << cryptPlugLibName << endl; } QCString cleartext; @@ -453,9 +451,9 @@ namespace KMail { // replace simple LFs by CRLSs // according to RfC 2633, 3.1.1 Canonicalization - kdDebug(5006) << "Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)" << endl; + //kdDebug(5006) << "Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)" << endl; cleartext = Util::lf2crlf( cleartext ); - kdDebug(5006) << " done." << endl; + //kdDebug(5006) << " done." << endl; } dumpToFile( "dat_02_reader_signedtext_after_canonicalization", @@ -563,16 +561,17 @@ namespace KMail { } std::stringstream ss; ss << result; - kdDebug(5006) << ss.str().c_str() << endl; + //kdDebug(5006) << ss.str().c_str() << endl; signatures = result.signatures(); } - if ( doCheck ) - kdDebug(5006) << "\nObjectTreeParser::writeOpaqueOrMultipartSignedData: returned from CRYPTPLUG" << endl; + if ( doCheck ) { + //kdDebug(5006) << "\nObjectTreeParser::writeOpaqueOrMultipartSignedData: returned from CRYPTPLUG" << endl; + } // ### only one signature supported if ( signatures.size() > 0 ) { - kdDebug(5006) << "\nObjectTreeParser::writeOpaqueOrMultipartSignedData: found signature" << endl; + //kdDebug(5006) << "\nObjectTreeParser::writeOpaqueOrMultipartSignedData: found signature" << endl; GpgME::Signature signature = signatures[0]; messagePart.status_code = signatureToStatus( signature ); @@ -626,9 +625,9 @@ namespace KMail { } } - kdDebug(5006) << "\n key id: " << messagePart.keyId - << "\n key trust: " << messagePart.keyTrust - << "\n signer: " << messagePart.signer << endl; + //kdDebug(5006) << "\n key id: " << messagePart.keyId + // << "\n key trust: " << messagePart.keyTrust + // << "\n signer: " << messagePart.signer << endl; } else { messagePart.creationTime = QDateTime(); @@ -714,13 +713,12 @@ namespace KMail { htmlWriter()->queue( writeSigstatFooter( messagePart ) ); } - kdDebug(5006) << "\nObjectTreeParser::writeOpaqueOrMultipartSignedData: done, returning " - << ( bIsOpaqueSigned ? "TRUE" : "FALSE" ) << endl; + //kdDebug(5006) << "\nObjectTreeParser::writeOpaqueOrMultipartSignedData: done, returning " + // << ( bIsOpaqueSigned ? "TRUE" : "FALSE" ) << endl; return bIsOpaqueSigned; } void ObjectTreeParser::writeDecryptionInProgressBlock() { - kdDebug(5006) << k_funcinfo << endl; assert( mReader ); // PENDING(marc) find an animated icon here: //const QString iconName = KGlobal::instance()->iconLoader()->iconPath( "decrypted", KIcon::Small ); @@ -738,7 +736,6 @@ void ObjectTreeParser::writeDecryptionInProgressBlock() { } void ObjectTreeParser::writeDeferredDecryptionBlock() { - kdDebug(5006) << k_funcinfo << endl; assert( mReader ); const QString iconName = KGlobal::instance()->iconLoader()->iconPath( "decrypted", KIcon::Small ); const QString decryptedData = @@ -815,8 +812,8 @@ bool ObjectTreeParser::okDecryptMIME( partNode& data, #endif - kdDebug(5006) << "ObjectTreeParser::decryptMIME: going to call CRYPTPLUG " - << cryptPlugLibName << endl; + //kdDebug(5006) << "ObjectTreeParser::decryptMIME: going to call CRYPTPLUG " + // << cryptPlugLibName << endl; if ( mReader ) emit mReader->noDrag(); // in case pineentry pops up, don't let kmheaders start a drag afterwards @@ -856,7 +853,7 @@ bool ObjectTreeParser::okDecryptMIME( partNode& data, const GpgME::VerificationResult & verifyResult = m->verifyResult(); std::stringstream ss; ss << decryptResult << '\n' << verifyResult; - kdDebug(5006) << ss.str().c_str() << endl; + //kdDebug(5006) << ss.str().c_str() << endl; signatureFound = verifyResult.signatures().size() > 0; signatures = verifyResult.signatures(); bDecryptionOk = !decryptResult.error(); @@ -867,8 +864,8 @@ bool ObjectTreeParser::okDecryptMIME( partNode& data, auditLogError = m->auditLogError(); auditLog = m->auditLogAsHtml(); - kdDebug(5006) << "ObjectTreeParser::decryptMIME: returned from CRYPTPLUG" - << endl; + //kdDebug(5006) << "ObjectTreeParser::decryptMIME: returned from CRYPTPLUG" + // << endl; if ( bDecryptionOk ) decryptedData = QCString( plainText.data(), plainText.size() + 1 ); else if ( mReader && showWarning ) { @@ -1056,7 +1053,7 @@ namespace KMail { if ( nextDelim < 0) return false; - kdDebug(5006) << " processing old style Mailman digest" << endl; + //kdDebug(5006) << " processing old style Mailman digest" << endl; //if ( curNode->mRoot ) // curNode = curNode->mRoot; @@ -1099,7 +1096,7 @@ namespace KMail { if ( -1 < thisEoL ) subject.truncate( thisEoL ); } - kdDebug(5006) << " embedded message found: \"" << subject << "\"" << endl; + //kdDebug(5006) << " embedded message found: \"" << subject << "\"" << endl; insertAndParseNewChildNode( *curNode, &*partStr, subject, true ); @@ -1368,9 +1365,9 @@ namespace KMail { CryptoProtocolSaver cpws( this, useThisCryptProto ); if ( partNode * dataChild = data->firstChild() ) { - kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; stdChildHandling( dataChild ); - kdDebug(5006) << "\n-----> Returning from parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n-----> Returning from parseObjectTree( curNode->mChild )\n" << endl; return true; } @@ -1382,7 +1379,7 @@ namespace KMail { return true; } - kdDebug(5006) << "\n-----> Initially processing encrypted data\n" << endl; + //kdDebug(5006) << "\n-----> Initially processing encrypted data\n" << endl; PartMetaData messagePart; QCString decryptedData; bool signatureFound; @@ -1467,17 +1464,17 @@ namespace KMail { return false; if ( partNode * child = node->firstChild() ) { - kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; ObjectTreeParser otp( mReader, cryptoProtocol() ); otp.parseObjectTree( child ); mRawReplyString += otp.rawReplyString(); mTextualContent += otp.textualContent(); if ( !otp.textualContentCharset().isEmpty() ) mTextualContentCharset = otp.textualContentCharset(); - kdDebug(5006) << "\n<----- Returning from parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n<----- Returning from parseObjectTree( curNode->mChild )\n" << endl; return true; } - kdDebug(5006) << "\n-----> Initially processing data of embedded RfC 822 message\n" << endl; + //kdDebug(5006) << "\n-----> Initially processing data of embedded RfC 822 message\n" << endl; // paint the frame PartMetaData messagePart; if ( mReader ) { @@ -1499,7 +1496,7 @@ namespace KMail { rfc822DwMessage->Parse(); KMMessage rfc822message( rfc822DwMessage ); node->setFromAddress( rfc822message.from() ); - kdDebug(5006) << "\n-----> Store RfC 822 message header \"From: " << rfc822message.from() << "\"\n" << endl; + //kdDebug(5006) << "\n-----> Store RfC 822 message header \"From: " << rfc822message.from() << "\"\n" << endl; if ( mReader ) htmlWriter()->queue( mReader->writeMsgHeader( &rfc822message ) ); //mReader->parseMsgHeader( &rfc822message ); @@ -1517,14 +1514,14 @@ namespace KMail { bool ObjectTreeParser::processApplicationOctetStreamSubtype( partNode * node, ProcessResult & result ) { if ( partNode * child = node->firstChild() ) { - kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; ObjectTreeParser otp( mReader, cryptoProtocol() ); otp.parseObjectTree( child ); mRawReplyString += otp.rawReplyString(); mTextualContent += otp.textualContent(); if ( !otp.textualContentCharset().isEmpty() ) mTextualContentCharset = otp.textualContentCharset(); - kdDebug(5006) << "\n<----- Returning from parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n<----- Returning from parseObjectTree( curNode->mChild )\n" << endl; return true; } @@ -1532,7 +1529,7 @@ namespace KMail { if ( node->parentNode() && DwMime::kTypeMultipart == node->parentNode()->type() && DwMime::kSubtypeEncrypted == node->parentNode()->subType() ) { - kdDebug(5006) << "\n-----> Initially processing encrypted data\n" << endl; + //kdDebug(5006) << "\n-----> Initially processing encrypted data\n" << endl; node->setEncryptionState( KMMsgFullyEncrypted ); if ( keepEncryptions() ) { const QCString cstr = node->msgPart().bodyDecoded(); @@ -1607,18 +1604,18 @@ namespace KMail { bool ObjectTreeParser::processApplicationPkcs7MimeSubtype( partNode * node, ProcessResult & result ) { if ( partNode * child = node->firstChild() ) { - kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n-----> Calling parseObjectTree( curNode->mChild )\n" << endl; ObjectTreeParser otp( mReader, cryptoProtocol() ); otp.parseObjectTree( child ); mRawReplyString += otp.rawReplyString(); mTextualContent += otp.textualContent(); if ( !otp.textualContentCharset().isEmpty() ) mTextualContentCharset = otp.textualContentCharset(); - kdDebug(5006) << "\n<----- Returning from parseObjectTree( curNode->mChild )\n" << endl; + //kdDebug(5006) << "\n<----- Returning from parseObjectTree( curNode->mChild )\n" << endl; return true; } - kdDebug(5006) << "\n-----> Initially processing signed and/or encrypted data\n" << endl; + //kdDebug(5006) << "\n-----> Initially processing signed and/or encrypted data\n" << endl; if ( !node->dwPart() || !node->dwPart()->hasHeaders() ) return false; @@ -1715,10 +1712,12 @@ namespace KMail { // if we either *know* that it is an encrypted message part // or there is neither signed nor encrypted parameter. if ( !isSigned ) { - if ( isEncrypted ) - kdDebug(5006) << "pkcs7 mime == S/MIME TYPE: enveloped (encrypted) data" << endl; - else - kdDebug(5006) << "pkcs7 mime - type unknown - enveloped (encrypted) data ?" << endl; + if ( isEncrypted ) { + //kdDebug(5006) << "pkcs7 mime == S/MIME TYPE: enveloped (encrypted) data" << endl; + } + else { + //kdDebug(5006) << "pkcs7 mime - type unknown - enveloped (encrypted) data ?" << endl; + } QCString decryptedData; PartMetaData messagePart; messagePart.isEncrypted = true; @@ -1750,7 +1749,7 @@ namespace KMail { return true; } if ( bOkDecrypt ) { - kdDebug(5006) << "pkcs7 mime - encryption found - enveloped (encrypted) data !" << endl; + //kdDebug(5006) << "pkcs7 mime - encryption found - enveloped (encrypted) data !" << endl; isEncrypted = true; node->setEncryptionState( KMMsgFullyEncrypted ); signTestNode = 0; @@ -1776,7 +1775,7 @@ namespace KMail { } if ( isEncrypted ) { - kdDebug(5006) << "pkcs7 mime - ERROR: COULD NOT DECRYPT enveloped data !" << endl; + //kdDebug(5006) << "pkcs7 mime - ERROR: COULD NOT DECRYPT enveloped data !" << endl; // paint the frame messagePart.isDecryptable = false; if ( mReader ) { @@ -1788,7 +1787,7 @@ namespace KMail { htmlWriter()->queue( writeSigstatFooter( messagePart ) ); } } else { - kdDebug(5006) << "pkcs7 mime - NO encryption found" << endl; + //kdDebug(5006) << "pkcs7 mime - NO encryption found" << endl; } } } @@ -1798,10 +1797,12 @@ namespace KMail { // We now try signature verification if necessarry. if ( signTestNode ) { - if ( isSigned ) - kdDebug(5006) << "pkcs7 mime == S/MIME TYPE: opaque signed data" << endl; - else - kdDebug(5006) << "pkcs7 mime - type unknown - opaque signed data ?" << endl; + if ( isSigned ) { + //kdDebug(5006) << "pkcs7 mime == S/MIME TYPE: opaque signed data" << endl; + } + else { + //kdDebug(5006) << "pkcs7 mime - type unknown - opaque signed data ?" << endl; + } bool sigFound = writeOpaqueOrMultipartSignedData( 0, *signTestNode, @@ -1812,14 +1813,14 @@ namespace KMail { isEncrypted ); if ( sigFound ) { if ( !isSigned ) { - kdDebug(5006) << "pkcs7 mime - signature found - opaque signed data !" << endl; + //kdDebug(5006) << "pkcs7 mime - signature found - opaque signed data !" << endl; isSigned = true; } signTestNode->setSignatureState( KMMsgFullySigned ); if ( signTestNode != node ) node->setSignatureState( KMMsgFullySigned ); } else { - kdDebug(5006) << "pkcs7 mime - NO signature found :-(" << endl; + //kdDebug(5006) << "pkcs7 mime - NO signature found :-(" << endl; } } @@ -2022,8 +2023,6 @@ bool ObjectTreeParser::processApplicationMsTnefSubtype( partNode *node, ProcessR if ( !mReader || !msgPart ) return; - kdDebug(5006) << "writePartIcon: PartNum: " << partNum << endl; - QString label = msgPart->fileName(); if( label.isEmpty() ) label = msgPart->name(); @@ -2284,10 +2283,10 @@ static QString beginVerboseSigstatHeader() static QString makeShowAuditLogLink( const GpgME::Error & err, const QString & auditLog ) { if ( const unsigned int code = err.code() ) { if ( code == GPG_ERR_NOT_IMPLEMENTED ) { - kdDebug(5006) << "makeShowAuditLogLink: not showing link (not implemented)" << endl; + //kdDebug(5006) << "makeShowAuditLogLink: not showing link (not implemented)" << endl; return QString(); } else if ( code == GPG_ERR_NO_DATA ) { - kdDebug(5006) << "makeShowAuditLogLink: not showing link (not available)" << endl; + //kdDebug(5006) << "makeShowAuditLogLink: not showing link (not available)" << endl; return i18n("No Audit Log available"); } else { return i18n("Error Retrieving Audit Log: %1").arg( QString::fromLocal8Bit( err.asString() ) ); @@ -2809,8 +2808,8 @@ void ObjectTreeParser::writeBodyStr( const QCString& aStr, const QTextCodec *aCo QCString str( *npbit ); if( !str.isEmpty() ) { htmlStr += quotedHTML( aCodec->toUnicode( str ), decorate ); - kdDebug( 5006 ) << "Non-empty Non-OpenPGP block found: '" << str - << "'" << endl; + //kdDebug( 5006 ) << "Non-empty Non-OpenPGP block found: '" << str + // << "'" << endl; // treat messages with empty lines before the first clearsigned // block as fully signed/encrypted if( firstNonPgpBlock ) { @@ -3083,10 +3082,6 @@ QString ObjectTreeParser::quotedHTML( const QString& s, bool decorate ) else htmlStr.append( quoteEnd ); - //kdDebug(5006) << "KMReaderWin::quotedHTML:\n" - // << "========================================\n" - // << htmlStr - // << "\n======================================\n"; return htmlStr; } diff --git a/partNode.cpp b/partNode.cpp index 7a45caa3e..0b39805e7 100644 --- a/partNode.cpp +++ b/partNode.cpp @@ -93,7 +93,6 @@ partNode::partNode( KMReaderWin * win, DwBodyPart* dwPart, int explicitType, int mType = explicitType; // this happens e.g. for the Root Node mSubType = explicitSubType; // representing the _whole_ message } else { -// kdDebug(5006) << "\n partNode::partNode() explicitType == DwMime::kTypeUnknown\n" << endl; if(dwPart && dwPart->hasHeaders() && dwPart->Headers().HasContentType()) { mType = (!dwPart->Headers().ContentType().Type())?DwMime::kTypeUnknown:dwPart->Headers().ContentType().Type(); mSubType = dwPart->Headers().ContentType().Subtype(); @@ -102,14 +101,6 @@ partNode::partNode( KMReaderWin * win, DwBodyPart* dwPart, int explicitType, int mSubType = DwMime::kSubtypeUnknown; } } -#ifdef DEBUG - { - DwString type, subType; - DwTypeEnumToStr( mType, type ); - DwSubtypeEnumToStr( mSubType, subType ); - kdDebug(5006) << "\npartNode::partNode() " << type.c_str() << "/" << subType.c_str() << "\n" << endl; - } -#endif } partNode * partNode::fromMessage( const KMMessage * msg, KMReaderWin * win ) { @@ -135,7 +126,7 @@ partNode * partNode::fromMessage( const KMMessage * msg, KMReaderWin * win ) { root->buildObjectTree(); root->setFromAddress( msg->from() ); - root->dump(); + //root->dump(); return root; } @@ -320,8 +311,6 @@ KMMsgEncryptionState partNode::overallEncryptionState() const } } -//kdDebug(5006) << "\n\n KMMsgEncryptionState: " << myState << endl; - return myState; } @@ -363,8 +352,6 @@ KMMsgSignatureState partNode::overallSignatureState() const } } -//kdDebug(5006) << "\n\n KMMsgSignatureState: " << myState << endl; - return myState; } @@ -435,13 +422,6 @@ int partNode::calcNodeIdOrFindNode( int &curId, const partNode* findNode, int fi partNode* partNode::findType( int type, int subType, bool deep, bool wide ) { -#ifndef NDEBUG - DwString typeStr, subTypeStr; - DwTypeEnumToStr( mType, typeStr ); - DwSubtypeEnumToStr( mSubType, subTypeStr ); - kdDebug(5006) << "partNode::findType() is looking at " << typeStr.c_str() - << "/" << subTypeStr.c_str() << endl; -#endif if( (mType != DwMime::kTypeUnknown) && ( (type == DwMime::kTypeUnknown) || (type == mType) ) @@ -537,8 +517,6 @@ void partNode::fillMimePartTree( KMMimePartTreeItem* parentItem, // remove linebreak+whitespace from folded Content-Description cntDesc.replace( QRegExp("\\n\\s*"), " " ); -kdDebug(5006) << " Inserting one item into MimePartTree" << endl; -kdDebug(5006) << " Content-Type: " << cntType << endl; if( parentItem ) mMimePartTreeItem = new KMMimePartTreeItem( parentItem, this, @@ -719,10 +697,12 @@ void partNode::internalSetBodyPartMemento( const QCString & which, KMail::Interf const std::map::iterator it = mBodyPartMementoMap.lower_bound( which.lower() ); if ( it != mBodyPartMementoMap.end() && it->first == which.lower() ) { delete it->second; - if ( memento ) + if ( memento ) { it->second = memento; - else + } + else { mBodyPartMementoMap.erase( it ); + } } else { mBodyPartMementoMap.insert( it, std::make_pair( which.lower(), memento ) ); } From ff7aed169841bd6fcd452c2749ff9c7f00de5195 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Thu, 11 Mar 2010 09:21:46 +0000 Subject: [PATCH 153/160] Detach the observers before deleting the mementos, otherwise deleting the mementos will trigger and update of the readerwin, which will crash, since the memento map is in an invalid state. kolab/issue4187 MERGE: trunk (afaik it is done with signals/slots there, needs to be adapted) svn path=/branches/kdepim/enterprise/kdepim/; revision=1101903 --- kmreaderwin.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index a4149486f..c81d83221 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2952,8 +2952,22 @@ BodyPartMemento * KMReaderWin::bodyPartMemento( const partNode * node, const QCS void KMReaderWin::clearBodyPartMementos() { - for ( std::map::const_iterator it = mBodyPartMementoMap.begin(), end = mBodyPartMementoMap.end() ; it != end ; ++it ) - delete it->second; + std::map::const_iterator it = mBodyPartMementoMap.begin(); + std::map::const_iterator end = mBodyPartMementoMap.end(); + for ( ; it != end ; ++it ) { + + // Detach the memento from the reader. When cancelling it, it might trigger an update of the + // reader, which we are not interested in, and which is dangerous, since half the mementos are + // already deleted. + // https://issues.kolab.org/issue4187 + BodyPartMemento *memento = it->second; + if ( Observable * o = memento ? memento->asObservable() : 0 ) { + if ( o ) { + o->detach( this ); + } + } + delete memento; + } mBodyPartMementoMap.clear(); } From a9d0e3efe394b12472786d071ba224c077c5010c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 11 Mar 2010 10:26:48 +0000 Subject: [PATCH 154/160] KMReaderWin: Minimize diff caused by 1101903; remove duplicated if(o) svn path=/branches/kdepim/enterprise/kdepim/; revision=1101911 --- kmreaderwin.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index c81d83221..de136032a 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2950,24 +2950,21 @@ BodyPartMemento * KMReaderWin::bodyPartMemento( const partNode * node, const QCS } } +static void detach_and_delete( BodyPartMemento * memento, KMReaderWin * obs ) { + if ( Observable * const o = memento ? memento->asObservable() : 0 ) + o->detach( obs ); + delete memento; +} + void KMReaderWin::clearBodyPartMementos() { - std::map::const_iterator it = mBodyPartMementoMap.begin(); - std::map::const_iterator end = mBodyPartMementoMap.end(); - for ( ; it != end ; ++it ) { - + for ( std::map::const_iterator it = mBodyPartMementoMap.begin(), end = mBodyPartMementoMap.end() ; it != end ; ++it ) // Detach the memento from the reader. When cancelling it, it might trigger an update of the // reader, which we are not interested in, and which is dangerous, since half the mementos are // already deleted. // https://issues.kolab.org/issue4187 - BodyPartMemento *memento = it->second; - if ( Observable * o = memento ? memento->asObservable() : 0 ) { - if ( o ) { - o->detach( this ); - } - } - delete memento; - } + detach_and_delete( it->second, this ); + mBodyPartMementoMap.clear(); } From b799b6aa13b7ee0692864d4d3c55552acdd3d9af Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 11 Mar 2010 10:28:02 +0000 Subject: [PATCH 155/160] kmail/kmreaderwin.cpp: Revert commit 1099019, which was a no-op svn path=/branches/kdepim/enterprise/kdepim/; revision=1101912 --- kmreaderwin.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kmreaderwin.cpp b/kmreaderwin.cpp index de136032a..b45b419ec 100644 --- a/kmreaderwin.cpp +++ b/kmreaderwin.cpp @@ -2931,11 +2931,8 @@ void KMReaderWin::setBodyPartMemento( const partNode * node, const QCString & wh } } - if ( Observable * o = memento ? memento->asObservable() : 0 ) { - if ( o ) { - o->attach( this ); - } - } + if ( Observable * o = memento ? memento->asObservable() : 0 ) + o->attach( this ); } BodyPartMemento * KMReaderWin::bodyPartMemento( const partNode * node, const QCString & which ) const From e8f33d7f3244485bb76e065edb8371c1ea80d5bd Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Fri, 12 Mar 2010 11:55:34 +0000 Subject: [PATCH 156/160] SVN_SILENT Update version numbers for today's release. svn path=/branches/kdepim/enterprise/kdepim/; revision=1102368 --- kmversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmversion.h b/kmversion.h index 49062b382..016b41310 100644 --- a/kmversion.h +++ b/kmversion.h @@ -3,6 +3,6 @@ #ifndef kmversion_h #define kmversion_h -#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100305.1099257)" +#define KMAIL_VERSION "1.9.10 (enterprise35 0.20100312.1102367)" #endif /*kmversion_h*/ From e5c910bf3b27a8e1691bde0053138df7e9f0282c Mon Sep 17 00:00:00 2001 From: Allen Winter Date: Fri, 12 Mar 2010 12:58:50 +0000 Subject: [PATCH 157/160] fix a crash when deleting a folder in the following test case: 1. Create a subfolder x2 of x1. 2. Copy all mails form x1 to x2. 3. Sync and while syncing delete folder x1 kolab/issue3902 MERGE: 4.4 (Thomas, can you check if this is needed in trunk?) svn path=/branches/kdepim/enterprise/kdepim/; revision=1102400 --- cachedimapjob.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/cachedimapjob.cpp b/cachedimapjob.cpp index 8c6339612..38088c964 100644 --- a/cachedimapjob.cpp +++ b/cachedimapjob.cpp @@ -452,18 +452,21 @@ void CachedImapJob::slotPutMessageDataReq(KIO::Job *job, QByteArray &data) } //---------------------------------------------------------------------------- -void CachedImapJob::slotPutMessageInfoData(KIO::Job *job, const QString &data) +void CachedImapJob::slotPutMessageInfoData( KIO::Job *job, const QString &data ) { - KMFolderCachedImap * imapFolder = static_cast(mDestFolder->storage()); - KMAcctCachedImap *account = imapFolder->account(); - ImapAccountBase::JobIterator it = account->findJob( job ); - if ( it == account->jobsEnd() ) return; - - if ( data.find("UID") != -1 && mMsg ) - { - int uid = (data.right(data.length()-4)).toInt(); - kdDebug( 5006 ) << k_funcinfo << "Server told us uid is: " << uid << endl; - mMsg->setUID( uid ); + KMFolderCachedImap *imapFolder = static_cast( mDestFolder->storage() ); + if ( imapFolder ) { + KMAcctCachedImap *account = imapFolder->account(); + ImapAccountBase::JobIterator it = account->findJob( job ); + if ( it == account->jobsEnd() ) { + return; + } + + if ( data.find( "UID" ) != -1 && mMsg ) { + int uid = ( data.right( data.length() - 4 ) ).toInt(); + kdDebug( 5006 ) << k_funcinfo << "Server told us uid is: " << uid << endl; + mMsg->setUID( uid ); + } } } From 5f375703be00830ce178c388055fef041d73ad1f Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 16 Mar 2010 09:46:19 +0000 Subject: [PATCH 158/160] Make the default toltec text translateable, default values in kcfgs are apparently not translated. svn path=/branches/kdepim/enterprise/kdepim/; revision=1103924 --- globalsettings_base.kcfgc | 2 +- kmail.kcfg | 2 +- objecttreeparser.cpp | 6 ++++++ objecttreeparser.h | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/globalsettings_base.kcfgc b/globalsettings_base.kcfgc index 7fbfbaf8a..3ca476056 100644 --- a/globalsettings_base.kcfgc +++ b/globalsettings_base.kcfgc @@ -4,4 +4,4 @@ Mutators=true Singleton=true ItemAccessors=true SetUserTexts=true -IncludeFiles=templatesconfiguration.h,kmglobal.h,templatesconfiguration_base.h +IncludeFiles=templatesconfiguration.h,kmglobal.h,templatesconfiguration_base.h,objecttreeparser.h diff --git a/kmail.kcfg b/kmail.kcfg index a36d1b150..e4aa6c1f1 100644 --- a/kmail.kcfg +++ b/kmail.kcfg @@ -222,7 +222,7 @@ - This message is a <i>Toltec</i> Groupware object, it can only be viewed with Microsoft Outlook in combination with the Toltec connector. + KMail::ObjectTreeParser::defaultToltecReplacementText() diff --git a/objecttreeparser.cpp b/objecttreeparser.cpp index 62a5c99ac..182c3a926 100644 --- a/objecttreeparser.cpp +++ b/objecttreeparser.cpp @@ -1210,6 +1210,12 @@ namespace KMail { mTextualContentCharset = otp.textualContentCharset(); } + QString ObjectTreeParser::defaultToltecReplacementText() + { + return i18n( "This message is a Toltec Groupware object, it can only be viewed with " + "Microsoft Outlook in combination with the Toltec connector." ); + } + bool ObjectTreeParser::processToltecMail( partNode *node ) { if ( !node || !mHtmlWriter || !GlobalSettings::self()->showToltecReplacementText() || diff --git a/objecttreeparser.h b/objecttreeparser.h index 6b1670a1e..b75e4c68e 100644 --- a/objecttreeparser.h +++ b/objecttreeparser.h @@ -156,6 +156,10 @@ namespace KMail { void setShowRawToltecMail( bool showRawToltecMail ) { mShowRawToltecMail = showRawToltecMail; } bool showRawToltecMail() const { return mShowRawToltecMail; } + /// default text for processToltecMail(), which is used in kmail.kcfg, therefore it + /// needs to be static here. + static QString defaultToltecReplacementText(); + const KMail::AttachmentStrategy * attachmentStrategy() const { return mAttachmentStrategy; } From 3f35231043f3de305af36894e070a5958861aa29 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 16 Mar 2010 11:05:02 +0000 Subject: [PATCH 159/160] - When changing the dictionary, make sure to change the speller used for the context menu - Set the correct dictionary initally. kolab/issue4060 MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1103945 --- dictionarycombobox.cpp | 1 + kmedit.cpp | 21 ++++++++++++++++----- kmedit.h | 5 ++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/dictionarycombobox.cpp b/dictionarycombobox.cpp index 59e0affd5..e688ad073 100644 --- a/dictionarycombobox.cpp +++ b/dictionarycombobox.cpp @@ -134,6 +134,7 @@ namespace KMail { mSpellConfig = new KSpellConfig( 0, 0, 0, false ); mSpellConfig->fillDicts( this, &mDictionaries ); mDefaultDictionary = currentItem(); + mSpellConfig->setDictionary( currentDictionary() ); } void DictionaryComboBox::slotDictionaryChanged( int idx ) diff --git a/kmedit.cpp b/kmedit.cpp index f4bf5a810..c74ac0ac3 100644 --- a/kmedit.cpp +++ b/kmedit.cpp @@ -215,6 +215,7 @@ KMEdit::KMEdit(QWidget *parent, KMComposeWin* composer, : KEdit( parent, name ), mComposer( composer ), mKSpellForDialog( 0 ), + mSpeller( 0 ), mSpellConfig( autoSpellConfig ), mSpellingFilter( 0 ), mExtEditorTempFile( 0 ), @@ -230,11 +231,18 @@ KMEdit::KMEdit(QWidget *parent, KMComposeWin* composer, installEventFilter(this); KCursor::setAutoHideCursor( this, true, true ); setOverwriteEnabled( true ); - mSpeller = new KMSpell( this, SLOT( spellerReady( KSpell * ) ) ); + createSpellers(); + connect( mSpellConfig, SIGNAL( configChanged() ), + this, SLOT( createSpellers() ) ); connect( mSpeller, SIGNAL( death() ), this, SLOT( spellerDied() ) ); } +void KMEdit::createSpellers() +{ + delete mSpeller; + mSpeller = new KMSpell( this, SLOT( spellerReady( KSpell * ) ), mSpellConfig ); +} void KMEdit::initializeAutoSpellChecking() { @@ -353,8 +361,8 @@ unsigned int KMEdit::lineBreakColumn() const return lineBreakColumn; } -KMSpell::KMSpell( QObject *receiver, const char *slot ) - : KSpell( 0, QString(), receiver, slot ) +KMSpell::KMSpell( QObject *receiver, const char *slot, KSpellConfig *spellConfig ) + : KSpell( 0, QString(), receiver, slot, spellConfig ) { } @@ -647,8 +655,11 @@ void KMEdit::spellcheck() // SLOT(slotSpellcheck2(KSpell*)),0,true,false,KSpell::HTML); // } // else { - mKSpellForDialog = new KSpell(this, i18n("Spellcheck - KMail"), this, - SLOT(slotSpellcheck2(KSpell*))); + + // Don't use mSpellConfig here. Reason is that the spell dialog, KSpellDlg, uses its own + // spell config, and therefore the two wouldn't be in sync. + mKSpellForDialog = new KSpell( this, i18n("Spellcheck - KMail"), this, + SLOT(slotSpellcheck2(KSpell*))/*, mSpellConfig*/ ); // } QStringList l = KSpellingHighlighter::personalWords(); diff --git a/kmedit.h b/kmedit.h index ff5a5c1e2..e9c42560f 100644 --- a/kmedit.h +++ b/kmedit.h @@ -30,7 +30,7 @@ class KMSpell : public KSpell { public: - KMSpell( QObject *receiver, const char *slot ); + KMSpell( QObject *receiver, const char *slot, KSpellConfig *spellConfig ); using KSpell::writePersonalDictionary; }; @@ -163,6 +163,9 @@ private slots: /// Called when mSpeller died for some reason. void spellerDied(); + /// Re-creates the spellers, called when the dictionary is changed + void createSpellers(); + private: void killExternalEditor(); From d13a56aa1c8dbb8af706d43cddd922e2e2d07c05 Mon Sep 17 00:00:00 2001 From: Sergio Luis Martins Date: Tue, 16 Mar 2010 18:27:21 +0000 Subject: [PATCH 160/160] Initialize dropItem to 0. MERGE: none svn path=/branches/kdepim/enterprise/kdepim/; revision=1104107 --- kmfoldertree.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/kmfoldertree.cpp b/kmfoldertree.cpp index ad1eb9f5e..a31fbfa8c 100644 --- a/kmfoldertree.cpp +++ b/kmfoldertree.cpp @@ -382,6 +382,7 @@ KMFolderTree::KMFolderTree( KMMainWidget *mainWidget, QWidget *parent, oldSelected = 0; oldCurrent = 0; mLastItem = 0; + dropItem = 0; mMainWidget = mainWidget; mReloading = false; mCutFolder = false;