Commit 617f7f5a authored by Laurent Montel's avatar Laurent Montel 😁

Allow to refresh attachment. Otherwise we can send outdated attachment

But reported by david

CCMAIL: faure@kde.org
parent 4b6d5803
......@@ -62,6 +62,7 @@
#include <messagecore/attachment/attachmentfrommimecontentjob.h>
#include <messagecore/attachment/attachmentfromurljob.h>
#include <messagecore/attachment/attachmentpropertiesdialog.h>
#include <messagecore/attachment/attachmentupdatejob.h>
#include <settings/messagecomposersettings.h>
#include <KIO/Job>
......@@ -92,6 +93,8 @@ public:
void addAttachmentPart( AttachmentPart::Ptr part );
void selectedAllAttachment();
void createOpenWithMenu( QMenu *topMenu, AttachmentPart::Ptr part );
void reloadAttachment();
void updateJobResult(KJob*);
AttachmentControllerBase *const q;
bool encryptEnabled;
......@@ -120,6 +123,7 @@ public:
QAction *selectAllAction;
KActionMenu *attachmentMenu;
QAction *addOwnVcardAction;
QAction *reloadAttachmentAction;
// If part p is compressed, uncompressedParts[p] is the uncompressed part.
QHash<AttachmentPart::Ptr, AttachmentPart::Ptr> uncompressedParts;
......@@ -277,6 +281,33 @@ void AttachmentControllerBase::Private::selectedAttachmentProperties()
q->attachmentProperties( selectedParts.first() );
}
void AttachmentControllerBase::Private::reloadAttachment()
{
Q_ASSERT( selectedParts.count() == 1 );
AttachmentUpdateJob *ajob = new AttachmentUpdateJob(selectedParts.first(), q);
connect( ajob, SIGNAL(result(KJob*)), q, SLOT(updateJobResult(KJob*)) );
ajob->start();
}
void AttachmentControllerBase::Private::updateJobResult(KJob *job)
{
if( job->error() ) {
KMessageBox::sorry( wParent, job->errorString(), i18n( "Failed to reload attachment" ) );
return;
}
Q_ASSERT( dynamic_cast<AttachmentUpdateJob*>( job ) );
AttachmentUpdateJob *ajob = static_cast<AttachmentUpdateJob*>( job );
AttachmentPart::Ptr originalPart = ajob->originalPart();
AttachmentPart::Ptr updatedPart = ajob->updatedPart();
attachmentRemoved( originalPart );
bool ok = model->replaceAttachment( originalPart, updatedPart );
if( !ok ) {
// The attachment was removed from the model while we were compressing.
kDebug() << "Updated a zombie.";
}
}
void AttachmentControllerBase::Private::editDone( MessageViewer::EditorWatcher *watcher )
{
AttachmentPart::Ptr part = editorPart.take( watcher );
......@@ -485,6 +516,11 @@ void AttachmentControllerBase::createActions()
connect( d->selectAllAction, SIGNAL(triggered(bool)),
this, SIGNAL(selectedAllAttachment()) );
d->reloadAttachmentAction = new KAction( i18n("Reload"), this);
connect( d->reloadAttachmentAction, SIGNAL(triggered(bool)),
this, SLOT(reloadAttachment()) );
// Insert the actions into the composer window's menu.
KActionCollection *collection = d->mActionCollection;
collection->addAction( QLatin1String( "attach_public_key" ), d->attachPublicKeyAction );
......@@ -571,6 +607,13 @@ void AttachmentControllerBase::showContextMenu()
menu->addSeparator();
menu->addAction(d->addContextAction);
}
if(numberOfParts == 1) {
if (!d->selectedParts.first()->url().isEmpty()) {
menu->addSeparator();
menu->addAction(d->reloadAttachmentAction);
}
}
menu->exec( QCursor::pos() );
delete menu;
}
......
......@@ -120,6 +120,8 @@ private:
Q_PRIVATE_SLOT( d, void editDone( MessageViewer::EditorWatcher* ) )
Q_PRIVATE_SLOT( d, void attachPublicKeyJobResult( KJob* ) )
Q_PRIVATE_SLOT( d, void slotAttachmentContentCreated( KJob * ) )
Q_PRIVATE_SLOT( d, void reloadAttachment() )
Q_PRIVATE_SLOT( d, void updateJobResult(KJob*) )
};
} //
......
......@@ -14,8 +14,14 @@
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "attachmentfromfolderjob.h"
#include "attachmentfromurlbasejob.h"
#include "attachmentfromurljob.h"
#include "attachmentupdatejob.h"
#include <KUrl>
#include <KMimeType>
#include <QDebug>
#include <QTimer>
using namespace MessageCore;
class MessageCore::AttachmentUpdateJob::Private
......@@ -23,6 +29,11 @@ class MessageCore::AttachmentUpdateJob::Private
public:
Private( AttachmentUpdateJob *qq );
void doStart(); // slot
void loadJobResult(KJob*);
MessageCore::AttachmentFromUrlBaseJob *createAttachmentJob(const KUrl &url);
AttachmentUpdateJob *const q;
AttachmentPart::Ptr mOriginalPart;
AttachmentPart::Ptr mUpdatedPart;
......@@ -33,6 +44,60 @@ AttachmentUpdateJob::Private::Private( AttachmentUpdateJob *qq )
{
}
void AttachmentUpdateJob::Private::doStart()
{
Q_ASSERT( mOriginalPart );
if (mOriginalPart->url().isEmpty()) {
qDebug()<< " url is empty. We can't update file";
q->setError( KJob::UserDefinedError );
//q->setErrorText( job->errorString() );
q->emitResult();
return;
}
MessageCore::AttachmentFromUrlBaseJob *job = createAttachmentJob(mOriginalPart->url());
connect( job, SIGNAL(result(KJob*)), q, SLOT(loadJobResult(KJob*)) );
job->start();
}
void AttachmentUpdateJob::Private::loadJobResult(KJob *job)
{
if( job->error() ) {
q->setError( KJob::UserDefinedError );
//q->setErrorText( i18n( "Could not initiate attachment compression." ) );
q->emitResult();
return;
}
Q_ASSERT( dynamic_cast<AttachmentLoadJob*>( job ) );
AttachmentLoadJob *ajob = static_cast<AttachmentLoadJob*>( job );
mUpdatedPart = ajob->attachmentPart();
mUpdatedPart->setName(q->originalPart()->name());
mUpdatedPart->setDescription(q->originalPart()->description());
mUpdatedPart->setSigned(q->originalPart()->isSigned());
mUpdatedPart->setEncrypted(q->originalPart()->isEncrypted());
mUpdatedPart->setEncoding(q->originalPart()->encoding());
mUpdatedPart->setMimeType(q->originalPart()->mimeType());
q->emitResult(); // Success.
}
MessageCore::AttachmentFromUrlBaseJob *AttachmentUpdateJob::Private::createAttachmentJob(const KUrl &url)
{
MessageCore::AttachmentFromUrlBaseJob *ajob = 0;
if( KMimeType::findByUrl( url )->name() == QLatin1String( "inode/directory" ) ) {
qDebug() << "Creating attachment from folder";
ajob = new AttachmentFromFolderJob ( url, q );
} else {
ajob = new AttachmentFromUrlJob( url, q );
qDebug() << "Creating attachment from file";
}
/*
if( MessageComposer::MessageComposerSettings::maximumAttachmentSize() > 0 ) {
ajob->setMaximumAllowedSize( MessageComposer::MessageComposerSettings::maximumAttachmentSize() );
}
*/
return ajob;
}
AttachmentUpdateJob::AttachmentUpdateJob(const AttachmentPart::Ptr &part, QObject *parent)
: KJob(parent),
......@@ -46,3 +111,20 @@ AttachmentUpdateJob::~AttachmentUpdateJob()
delete d;
}
void AttachmentUpdateJob::start()
{
QTimer::singleShot( 0, this, SLOT(doStart()) );
}
AttachmentPart::Ptr AttachmentUpdateJob::originalPart() const
{
return d->mOriginalPart;
}
AttachmentPart::Ptr AttachmentUpdateJob::updatedPart() const
{
return d->mUpdatedPart;
}
#include "moc_attachmentupdatejob.cpp"
......@@ -30,10 +30,15 @@ public:
AttachmentUpdateJob(const AttachmentPart::Ptr &part, QObject *parent = 0);
~AttachmentUpdateJob();
virtual void start();
AttachmentPart::Ptr originalPart() const;
AttachmentPart::Ptr updatedPart() const;
private:
//@cond PRIVATE
class Private;
Private *const d;
Q_PRIVATE_SLOT( d, void doStart() )
Q_PRIVATE_SLOT( d, void loadJobResult(KJob*) )
};
}
......
......@@ -19,6 +19,7 @@ add_messagecore_test( attachmentfrommimecontentjobtest.cpp )
add_messagecore_test( attachmentfromurljobtest.cpp )
add_messagecore_test( attachmentparttest.cpp )
add_messagecore_test( attachmentpropertiesdialogtest.cpp )
add_messagecore_test( attachmentupdatejobtest.cpp )
# Other tests
add_messagecore_test( stringutiltest.cpp )
......
/*
Copyright (c) 2014 Montel Laurent <montel@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "attachmentupdatejobtest.h"
#include <messagecore/attachment/attachmentupdatejob.h>
#include <messagecore/attachment/attachmentpart.h>
#include <qtest_kde.h>
#include "qtest_messagecore.h"
#define PATH_ATTACHMENTS QLatin1String( KDESRCDIR "/attachments/" )
AttachmentUpdateJobTest::AttachmentUpdateJobTest(QObject *parent)
: QObject(parent)
{
}
AttachmentUpdateJobTest::~AttachmentUpdateJobTest()
{
}
void AttachmentUpdateJobTest::shouldHaveDefaultValue()
{
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
QCOMPARE(origPart, job->originalPart());
QVERIFY(!job->updatedPart());
delete job;
}
void AttachmentUpdateJobTest::shouldUpdateAttachment()
{
const KUrl url = KUrl::fromPath( PATH_ATTACHMENTS + QString::fromLatin1( "file.txt" ) );
// Some data.
QByteArray data( "This is short enough that compressing it is not efficient." );
const QString name = QString::fromLatin1( "name.txt" );
const QString description = QString::fromLatin1( "description" );
// Create the original part.
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
origPart->setName( name );
origPart->setDescription( description );
origPart->setMimeType( "text/plain" );
origPart->setEncoding( KMime::Headers::CE7Bit );
origPart->setData( data );
origPart->setUrl(url);
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
VERIFYEXEC( job );
QVERIFY(origPart->size() != job->updatedPart()->size());
QVERIFY(origPart->data() != job->updatedPart()->data());
}
void AttachmentUpdateJobTest::shouldHaveSameNameDescriptionAfterUpdate()
{
const KUrl url = KUrl::fromPath( PATH_ATTACHMENTS + QString::fromLatin1( "file.txt" ) );
// Some data.
QByteArray data( "This is short enough that compressing it is not efficient." );
const QString name = QString::fromLatin1( "name.txt" );
const QString description = QString::fromLatin1( "description" );
// Create the original part.
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
origPart->setName( name );
origPart->setDescription( description );
origPart->setMimeType( "text/plain" );
origPart->setEncoding( KMime::Headers::CE7Bit );
origPart->setData( data );
origPart->setUrl(url);
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
VERIFYEXEC( job );
QCOMPARE(origPart->name(), job->updatedPart()->name());
QCOMPARE(origPart->description(), job->updatedPart()->description());
}
void AttachmentUpdateJobTest::shouldHaveSameCryptoSignStatusAfterUpdate()
{
const KUrl url = KUrl::fromPath( PATH_ATTACHMENTS + QString::fromLatin1( "file.txt" ) );
// Some data.
QByteArray data( "This is short enough that compressing it is not efficient." );
const QString name = QString::fromLatin1( "name.txt" );
const QString description = QString::fromLatin1( "description" );
// Create the original part.
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
origPart->setName( name );
origPart->setDescription( description );
origPart->setMimeType( "text/plain" );
origPart->setEncoding( KMime::Headers::CE7Bit );
origPart->setData( data );
origPart->setUrl(url);
origPart->setSigned(true);
origPart->setEncrypted(true);
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
VERIFYEXEC( job );
QCOMPARE(origPart->isSigned(), job->updatedPart()->isSigned());
QCOMPARE(origPart->isEncrypted(), job->updatedPart()->isEncrypted());
}
void AttachmentUpdateJobTest::shouldHaveSameEncodingAfterUpdate()
{
const KUrl url = KUrl::fromPath( PATH_ATTACHMENTS + QString::fromLatin1( "file.txt" ) );
// Some data.
QByteArray data( "This is short enough that compressing it is not efficient." );
const QString name = QString::fromLatin1( "name.txt" );
const QString description = QString::fromLatin1( "description" );
// Create the original part.
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
origPart->setName( name );
origPart->setDescription( description );
origPart->setMimeType( "text/pdf" );
origPart->setEncoding( KMime::Headers::CE8Bit );
origPart->setData( data );
origPart->setUrl(url);
origPart->setSigned(true);
origPart->setEncrypted(true);
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
VERIFYEXEC( job );
QCOMPARE(origPart->encoding(), job->updatedPart()->encoding());
}
void AttachmentUpdateJobTest::shouldHaveSameMimetypeAfterUpdate()
{
const KUrl url = KUrl::fromPath( PATH_ATTACHMENTS + QString::fromLatin1( "file.txt" ) );
// Some data.
QByteArray data( "This is short enough that compressing it is not efficient." );
const QString name = QString::fromLatin1( "name.txt" );
const QString description = QString::fromLatin1( "description" );
// Create the original part.
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
origPart->setName( name );
origPart->setDescription( description );
origPart->setMimeType( "text/pdf" );
origPart->setEncoding( KMime::Headers::CE8Bit );
origPart->setData( data );
origPart->setUrl(url);
origPart->setSigned(true);
origPart->setEncrypted(true);
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
VERIFYEXEC( job );
QCOMPARE(origPart->mimeType(), job->updatedPart()->mimeType());
}
void AttachmentUpdateJobTest::shouldNotUpdateWhenUrlIsEmpty()
{
QByteArray data( "This is short enough that compressing it is not efficient." );
const QString name = QString::fromLatin1( "name.txt" );
const QString description = QString::fromLatin1( "description" );
// Create the original part.
MessageCore::AttachmentPart::Ptr origPart = MessageCore::AttachmentPart::Ptr( new MessageCore::AttachmentPart );
origPart->setName( name );
origPart->setDescription( description );
origPart->setMimeType( "text/plain" );
origPart->setEncoding( KMime::Headers::CE7Bit );
origPart->setData( data );
MessageCore::AttachmentUpdateJob *job = new MessageCore::AttachmentUpdateJob(origPart, this);
job->exec();
QVERIFY(!job->updatedPart());
}
QTEST_KDEMAIN(AttachmentUpdateJobTest, NoGUI)
/*
Copyright (c) 2014 Montel Laurent <montel@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ATTACHMENTUPDATEJOBTEST_H
#define ATTACHMENTUPDATEJOBTEST_H
#include <QObject>
class AttachmentUpdateJobTest : public QObject
{
Q_OBJECT
public:
explicit AttachmentUpdateJobTest(QObject *parent=0);
~AttachmentUpdateJobTest();
private Q_SLOTS:
void shouldHaveDefaultValue();
void shouldUpdateAttachment();
void shouldHaveSameNameDescriptionAfterUpdate();
void shouldHaveSameCryptoSignStatusAfterUpdate();
void shouldHaveSameEncodingAfterUpdate();
void shouldHaveSameMimetypeAfterUpdate();
void shouldNotUpdateWhenUrlIsEmpty();
};
#endif // ATTACHMENTUPDATEJOBTEST_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment