2
Copyright (c) 2010 Klar�lvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
4
This library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Library General Public
6
License as published by the Free Software Foundation; either
7
version 2 of the License, or (at your option) any later version.
9
This library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
Library General Public License for more details.
14
You should have received a copy of the GNU Library General Public License
15
along with this library; see the file COPYING.LIB. If not, write to
16
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17
Boston, MA 02110-1301, USA.
21
This file is part of the API for handling calendar data and provides
22
static functions for dealing with calendar incidence attachments.
25
vCalendar/iCalendar attachment handling.
27
@author Allen Winter \<winter@kde.org\>
29
#include "attachmenthandler.h"
30
#include "akonadicalendar.h"
31
#include "next/incidencesearchjob.h"
33
#include <KFileDialog>
35
#include <KMessageBox>
38
#include <KTemporaryFile>
39
#include <KToolInvocation>
40
#include <KIO/NetAccess>
46
using namespace KCalCore;
48
namespace CalendarSupport {
52
QString attachmentName;
55
class AttachmentHandler::Private
58
Private( QWidget *parent )
62
QMap<KJob*,ReceivedInfo> mJobToReceivedInfo;
63
QPointer<QWidget> mParent;
66
AttachmentHandler::AttachmentHandler( QWidget *parent ) : d( new Private( parent ) )
71
AttachmentHandler::~AttachmentHandler()
76
Attachment::Ptr AttachmentHandler::find( const QString &attachmentName,
77
const Incidence::Ptr &incidence )
80
return Attachment::Ptr();
83
// get the attachment by name from the incidence
84
const Attachment::List as = incidence->attachments();
86
if ( !as.isEmpty() ) {
87
Attachment::List::ConstIterator it;
88
for ( it = as.begin(); it != as.end(); ++it ) {
89
if ( (*it)->label() == attachmentName ) {
99
i18n( "No attachment named \"%1\" found in the incidence.", attachmentName ) );
100
return Attachment::Ptr();
104
if ( !KIO::NetAccess::exists( a->uri(), KIO::NetAccess::SourceSide, d->mParent ) ) {
107
i18n( "The attachment \"%1\" is a web link that is inaccessible from this computer. ",
108
KUrl::fromPercentEncoding( a->uri().toLatin1() ) ) );
109
return Attachment::Ptr();
116
Attachment::Ptr AttachmentHandler::find( const QString &attachmentName,
117
const ScheduleMessage::Ptr &message )
120
return Attachment::Ptr();
123
Incidence::Ptr incidence = message->event().dynamicCast<Incidence>();
127
i18n( "The calendar invitation stored in this email message is broken in some way. "
128
"Unable to continue." ) );
129
return Attachment::Ptr();
132
return find( attachmentName, incidence );
135
static KTemporaryFile *s_tempFile = 0;
137
static KUrl tempFileForAttachment( const Attachment::Ptr &attachment )
141
s_tempFile = new KTemporaryFile();
142
s_tempFile->setAutoRemove( false );
143
QStringList patterns = KMimeType::mimeType( attachment->mimeType() )->patterns();
144
if ( !patterns.empty() ) {
145
s_tempFile->setSuffix( QString( patterns.first() ).remove( '*' ) );
148
s_tempFile->setPermissions( QFile::ReadUser );
149
s_tempFile->write( QByteArray::fromBase64( attachment->data() ) );
151
QFile tf( s_tempFile->fileName() );
152
if ( tf.size() != attachment->size() ) {
153
//whoops. failed to write the entire attachment. return an invalid URL.
159
url.setPath( s_tempFile->fileName() );
163
bool AttachmentHandler::view( const Attachment::Ptr &attachment )
170
if ( attachment->isUri() ) {
171
KToolInvocation::invokeBrowser( attachment->uri() );
173
// put the attachment in a temporary file and launch it
174
KUrl tempUrl = tempFileForAttachment( attachment );
175
if ( tempUrl.isValid() ) {
176
stat = KRun::runUrl( tempUrl, attachment->mimeType(), 0, true );
181
i18n( "Unable to create a temporary file for the attachment." ) );
189
bool AttachmentHandler::view( const QString &attachmentName,
190
const Incidence::Ptr &incidence )
192
return view( find( attachmentName, incidence ) );
195
void AttachmentHandler::view( const QString &attachmentName, const QString &uid )
197
IncidenceSearchJob *job = new IncidenceSearchJob();
198
job->setQuery( CalendarSupport::IncidenceSearchJob::IncidenceUid, uid,
199
IncidenceSearchJob::ExactMatch );
200
connect( job, SIGNAL( result( KJob* ) ), this, SLOT( slotFinishView( KJob* ) ) );
202
info.attachmentName = attachmentName;
204
d->mJobToReceivedInfo[job] = info;
207
bool AttachmentHandler::view( const QString &attachmentName,
208
const ScheduleMessage::Ptr &message )
210
return view( find( attachmentName, message ) );
213
bool AttachmentHandler::saveAs( const Attachment::Ptr &attachment )
215
// get the saveas file name
216
QString saveAsFile = KFileDialog::getSaveFileName( attachment->label(), QString(), d->mParent,
217
i18n( "Save Attachment" ) );
218
if ( saveAsFile.isEmpty() ||
219
( QFile( saveAsFile ).exists() &&
220
( KMessageBox::warningYesNo(
222
i18n( "%1 already exists. Do you want to overwrite it?",
223
saveAsFile ) ) == KMessageBox::No ) ) ) {
228
if ( attachment->isUri() ) {
229
// save the attachment url
230
stat = KIO::NetAccess::file_copy( attachment->uri(), KUrl( saveAsFile ) );
232
// put the attachment in a temporary file and save it
233
KUrl tempUrl = tempFileForAttachment( attachment );
234
if ( tempUrl.isValid() ) {
235
stat = KIO::NetAccess::file_copy( tempUrl, KUrl( saveAsFile ) );
236
if ( !stat && KIO::NetAccess::lastError() ) {
237
KMessageBox::error( d->mParent, KIO::NetAccess::lastErrorString() );
243
i18n( "Unable to create a temporary file for the attachment." ) );
251
bool AttachmentHandler::saveAs( const QString &attachmentName,
252
const Incidence::Ptr &incidence )
254
return saveAs( find( attachmentName, incidence ) );
257
void AttachmentHandler::saveAs( const QString &attachmentName, const QString &uid )
259
IncidenceSearchJob *job = new IncidenceSearchJob();
260
job->setQuery( CalendarSupport::IncidenceSearchJob::IncidenceUid, uid,
261
IncidenceSearchJob::ExactMatch );
262
connect( job, SIGNAL( result( KJob* ) ), this, SLOT( slotFinishView( KJob* ) ) );
265
info.attachmentName = attachmentName;
267
d->mJobToReceivedInfo[job] = info;
270
bool AttachmentHandler::saveAs( const QString &attachmentName,
271
const ScheduleMessage::Ptr &message )
273
return saveAs( find( attachmentName, message ) );
276
void AttachmentHandler::slotFinishSaveAs( KJob *job )
278
IncidenceSearchJob *searchJob = qobject_cast<IncidenceSearchJob*>( job );
279
const KCalCore::Incidence::List incidences = searchJob->incidences();
280
ReceivedInfo info = d->mJobToReceivedInfo[job];
282
bool success = false;
283
if ( !incidences.isEmpty() ) {
284
if ( saveAs( info.attachmentName, incidences.first() ) ) {
289
emit saveAsFinished( info.uid, info.attachmentName, success );
290
d->mJobToReceivedInfo.remove( job );
293
void AttachmentHandler::slotFinishView( KJob *job )
295
IncidenceSearchJob *searchJob = qobject_cast<IncidenceSearchJob*>( job );
296
const KCalCore::Incidence::List incidences = searchJob->incidences();
297
ReceivedInfo info = d->mJobToReceivedInfo[job];
299
bool success = false;
300
if ( !incidences.isEmpty() ) {
301
if ( view( info.attachmentName, incidences.first() ) ) {
306
emit viewFinished( info.uid, info.attachmentName, success );
307
d->mJobToReceivedInfo.remove( job );
311
} // namespace CalendarSupport