• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

calendarsupport

  • sources
  • kde-4.14
  • kdepim
  • calendarsupport
attachmenthandler.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010 Klarlvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
3  Author: Allen Winter <allen.winter@kdab.com>
4  Copyright (C) 2014 Sergio Martins <iamsergio@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
31 #include "attachmenthandler.h"
32 #include "calendarsupport/utils.h"
33 
34 #include <Akonadi/ItemFetchJob>
35 #include <KFileDialog>
36 #include <KLocalizedString>
37 #include <KMessageBox>
38 #include <KMimeType>
39 #include <KRun>
40 #include <KTemporaryFile>
41 #include <KToolInvocation>
42 #include <KIO/NetAccess>
43 #include <KJob>
44 
45 #include <QFile>
46 #include <QPointer>
47 
48 using namespace KCalCore;
49 using namespace Akonadi;
50 
51 namespace CalendarSupport {
52 
53 struct ReceivedInfo {
54  QString uid;
55  QString attachmentName;
56 };
57 
58 class AttachmentHandler::Private
59 {
60  public:
61  Private( QWidget *parent )
62  {
63  mParent = parent;
64  }
65  QMap<KJob *,ReceivedInfo> mJobToReceivedInfo;
66  QPointer<QWidget> mParent;
67 };
68 
69 AttachmentHandler::AttachmentHandler( QWidget *parent ) : QObject( parent ), d( new Private( parent ) )
70 {
71 
72 }
73 
74 AttachmentHandler::~AttachmentHandler()
75 {
76  delete d;
77 }
78 
79 Attachment::Ptr AttachmentHandler::find( const QString &attachmentName,
80  const Incidence::Ptr &incidence )
81 {
82  if ( !incidence ) {
83  return Attachment::Ptr();
84  }
85 
86  // get the attachment by name from the incidence
87  const Attachment::List as = incidence->attachments();
88  Attachment::Ptr a;
89  if ( !as.isEmpty() ) {
90  Attachment::List::ConstIterator it;
91  Attachment::List::ConstIterator end( as.constEnd() );
92 
93  for ( it = as.constBegin(); it != end; ++it ) {
94  if ( (*it)->label() == attachmentName ) {
95  a = *it;
96  break;
97  }
98  }
99  }
100 
101  if ( !a ) {
102  KMessageBox::error(
103  d->mParent,
104  i18n( "No attachment named \"%1\" found in the incidence.", attachmentName ) );
105  return Attachment::Ptr();
106  }
107 
108  if ( a->isUri() ) {
109  if ( !KIO::NetAccess::exists( a->uri(), KIO::NetAccess::SourceSide, d->mParent ) ) {
110  KMessageBox::sorry(
111  d->mParent,
112  i18n( "The attachment \"%1\" is a web link that is inaccessible from this computer. ",
113  KUrl::fromPercentEncoding( a->uri().toLatin1() ) ) );
114  return Attachment::Ptr();
115  }
116  }
117  return a;
118 }
119 
120 Attachment::Ptr AttachmentHandler::find( const QString &attachmentName,
121  const ScheduleMessage::Ptr &message )
122 {
123  if ( !message ) {
124  return Attachment::Ptr();
125  }
126 
127  Incidence::Ptr incidence = message->event().dynamicCast<Incidence>();
128  if ( !incidence ) {
129  KMessageBox::error(
130  d->mParent,
131  i18n( "The calendar invitation stored in this email message is broken in some way. "
132  "Unable to continue." ) );
133  return Attachment::Ptr();
134  }
135 
136  return find( attachmentName, incidence );
137 }
138 
139 static KTemporaryFile *s_tempFile = 0;
140 
141 static KUrl tempFileForAttachment( const Attachment::Ptr &attachment )
142 {
143  KUrl url;
144 
145  s_tempFile = new KTemporaryFile();
146  s_tempFile->setAutoRemove( false );
147  QStringList patterns = KMimeType::mimeType( attachment->mimeType() )->patterns();
148  if ( !patterns.empty() ) {
149  s_tempFile->setSuffix( QString( patterns.first() ).remove( QLatin1Char('*') ) );
150  }
151  s_tempFile->open();
152  s_tempFile->setPermissions( QFile::ReadUser );
153  s_tempFile->write( QByteArray::fromBase64( attachment->data() ) );
154  s_tempFile->close();
155  QFile tf( s_tempFile->fileName() );
156  if ( tf.size() != attachment->size() ) {
157  //whoops. failed to write the entire attachment. return an invalid URL.
158  delete s_tempFile;
159  s_tempFile = 0;
160  return url;
161  }
162 
163  url.setPath( s_tempFile->fileName() );
164  return url;
165 }
166 
167 bool AttachmentHandler::view( const Attachment::Ptr &attachment )
168 {
169  if ( !attachment ) {
170  return false;
171  }
172 
173  bool stat = true;
174  if ( attachment->isUri() ) {
175  KToolInvocation::invokeBrowser( attachment->uri() );
176  } else {
177  // put the attachment in a temporary file and launch it
178  KUrl tempUrl = tempFileForAttachment( attachment );
179  if ( tempUrl.isValid() ) {
180  stat = KRun::runUrl( tempUrl, attachment->mimeType(), 0, true );
181  } else {
182  stat = false;
183  KMessageBox::error(
184  d->mParent,
185  i18n( "Unable to create a temporary file for the attachment." ) );
186  }
187  delete s_tempFile;
188  s_tempFile = 0;
189  }
190  return stat;
191 }
192 
193 bool AttachmentHandler::view( const QString &attachmentName,
194  const Incidence::Ptr &incidence )
195 {
196  return view( find( attachmentName, incidence ) );
197 }
198 
199 void AttachmentHandler::view( const QString &attachmentName, const QString &uid )
200 {
201  Item item;
202  item.setGid(uid);
203  ItemFetchJob *job = new ItemFetchJob(item);
204  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotFinishView(KJob*)) );
205  ReceivedInfo info;
206  info.attachmentName = attachmentName;
207  info.uid = uid;
208  d->mJobToReceivedInfo[job] = info;
209 }
210 
211 bool AttachmentHandler::view( const QString &attachmentName,
212  const ScheduleMessage::Ptr &message )
213 {
214  return view( find( attachmentName, message ) );
215 }
216 
217 bool AttachmentHandler::saveAs( const Attachment::Ptr &attachment )
218 {
219  // get the saveas file name
220  QString saveAsFile = KFileDialog::getSaveFileName( attachment->label(), QString(), d->mParent,
221  i18n( "Save Attachment" ), KFileDialog::ConfirmOverwrite );
222  if ( saveAsFile.isEmpty() ||
223  ( QFile( saveAsFile ).exists() &&
224  ( KMessageBox::warningYesNo(
225  d->mParent,
226  i18n( "%1 already exists. Do you want to overwrite it?",
227  saveAsFile ) ) == KMessageBox::No ) ) ) {
228  return false;
229  }
230 
231  bool stat = false;
232  if ( attachment->isUri() ) {
233  // save the attachment url
234  stat = KIO::NetAccess::file_copy( attachment->uri(), KUrl( saveAsFile ) );
235  } else {
236  // put the attachment in a temporary file and save it
237  KUrl tempUrl = tempFileForAttachment( attachment );
238  if ( tempUrl.isValid() ) {
239  stat = KIO::NetAccess::file_copy( tempUrl, KUrl( saveAsFile ) );
240  if ( !stat && KIO::NetAccess::lastError() ) {
241  KMessageBox::error( d->mParent, KIO::NetAccess::lastErrorString() );
242  }
243  } else {
244  stat = false;
245  KMessageBox::error(
246  d->mParent,
247  i18n( "Unable to create a temporary file for the attachment." ) );
248  }
249  delete s_tempFile;
250  s_tempFile = 0;
251  }
252  return stat;
253 }
254 
255 bool AttachmentHandler::saveAs( const QString &attachmentName,
256  const Incidence::Ptr &incidence )
257 {
258  return saveAs( find( attachmentName, incidence ) );
259 }
260 
261 void AttachmentHandler::saveAs( const QString &attachmentName, const QString &uid )
262 {
263  Item item;
264  item.setGid(uid);
265  ItemFetchJob *job = new ItemFetchJob(item);
266  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotFinishView(KJob*)) );
267 
268  ReceivedInfo info;
269  info.attachmentName = attachmentName;
270  info.uid = uid;
271  d->mJobToReceivedInfo[job] = info;
272 }
273 
274 bool AttachmentHandler::saveAs( const QString &attachmentName,
275  const ScheduleMessage::Ptr &message )
276 {
277  return saveAs( find( attachmentName, message ) );
278 }
279 
280 void AttachmentHandler::slotFinishSaveAs( KJob *job )
281 {
282  ReceivedInfo info = d->mJobToReceivedInfo[job];
283  bool success = false;
284 
285  if ( job->error() != 0 ) {
286  ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob*>( job );
287  const Item::List items = fetchJob->items();
288  if ( !items.isEmpty() ) {
289  Incidence::Ptr incidence = CalendarSupport::incidence( items.first() );
290  success = incidence && saveAs( info.attachmentName, incidence );
291  } else {
292  kWarning() << Q_FUNC_INFO << "No item found";
293  }
294  } else {
295  kWarning() << Q_FUNC_INFO << "Job error:" << job->errorString();
296  }
297 
298  emit saveAsFinished( info.uid, info.attachmentName, success );
299  d->mJobToReceivedInfo.remove( job );
300 }
301 
302 void AttachmentHandler::slotFinishView( KJob *job )
303 {
304  ReceivedInfo info = d->mJobToReceivedInfo[job];
305  bool success = false;
306 
307  if ( job->error() != 0 ) {
308  ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob*>( job );
309  const Item::List items = fetchJob->items();
310  if ( !items.isEmpty() ) {
311  Incidence::Ptr incidence = CalendarSupport::incidence( items.first() );
312  success = incidence && view( info.attachmentName, incidence );
313  } else {
314  kWarning() << Q_FUNC_INFO << "No item found";
315  }
316  } else {
317  kWarning() << Q_FUNC_INFO << "Job error:" << job->errorString();
318  }
319 
320  emit viewFinished( info.uid, info.attachmentName, success );
321  d->mJobToReceivedInfo.remove( job );
322 }
323 
324 } // namespace CalendarSupport
325 
QWidget
CalendarSupport::tempFileForAttachment
static KUrl tempFileForAttachment(const Attachment::Ptr &attachment)
Definition: attachmenthandler.cpp:141
QMap< KJob *, ReceivedInfo >
QPointer< QWidget >
CalendarSupport::AttachmentHandler::find
KCalCore::Attachment::Ptr find(const QString &attachmentName, const KCalCore::Incidence::Ptr &incidence)
Finds the attachment in the user's calendar, by attachmentName and incidence.
QFile::exists
bool exists() const
CalendarSupport::incidence
CALENDARSUPPORT_EXPORT KCalCore::Incidence::Ptr incidence(const Akonadi::Item &item)
returns the incidence from an akonadi item, or a null pointer if the item has no such payload ...
Definition: utils.cpp:78
QFile
CalendarSupport::s_tempFile
static KTemporaryFile * s_tempFile
Definition: attachmenthandler.cpp:139
utils.h
QList::empty
bool empty() const
CalendarSupport::AttachmentHandler::saveAs
bool saveAs(const KCalCore::Attachment::Ptr &attachment)
Saves the specified attachment to a file of the user's choice.
QObject
QString::isEmpty
bool isEmpty() const
QList::first
T & first()
QString
attachmenthandler.h
This file is part of the API for handling calendar data and provides static functions for dealing wit...
QStringList
CalendarSupport::AttachmentHandler::view
bool view(const KCalCore::Attachment::Ptr &attachment)
Launches a viewer on the specified attachment.
QLatin1Char
QByteArray::fromBase64
QByteArray fromBase64(const QByteArray &base64)
CalendarSupport::AttachmentHandler::~AttachmentHandler
~AttachmentHandler()
Definition: attachmenthandler.cpp:74
CalendarSupport::AttachmentHandler::viewFinished
void viewFinished(const QString &uid, const QString &attachmentName, bool success)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
CalendarSupport::AttachmentHandler::saveAsFinished
void saveAsFinished(const QString &uid, const QString &attachmentName, bool success)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:31:15 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

calendarsupport

Skip menu "calendarsupport"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal