~ubuntu-branches/ubuntu/vivid/kdepim/vivid

« back to all changes in this revision

Viewing changes to messagecomposer/attachmentcontrollerbase.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Jonathan Riddell, Rohan Garg, Scott Kitterman
  • Date: 2012-11-21 13:12:36 UTC
  • mfrom: (0.2.33)
  • Revision ID: package-import@ubuntu.com-20121121131236-32ijw9a2txrar80k
Tags: 4:4.9.80-0ubuntu1
[ Jonathan Riddell ]
* New upstream beta release

[ Rohan Garg ]
* Add nepomuk-core-dev to build-deps

[ Scott Kitterman ]
* Add new package, libpimcommon4
  - Add libpimcommon4.install
  - Add to debian/control, including kdepim-dbg and kdepim-dev depends
  - Add to kdepim-dev.install
* Remove usr/bin/backupmail and related files from kmail.install as they are
  not provided by upstream anymore
* Add usr/bin/pimsettingexporter and related files to kmail.install
* Add libnepomukwidgets-dev to build-depends

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "messagecomposer/globalpart.h"
30
30
#include "messageviewer/editorwatcher.h"
31
31
#include "messageviewer/nodehelper.h"
 
32
#include "messageviewer/util.h"
32
33
 
33
34
#include <akonadi/itemfetchjob.h>
34
35
#include <kio/jobuidelegate.h>
47
48
#include <KPushButton>
48
49
#include <KRun>
49
50
#include <KTemporaryFile>
 
51
#include <KFileItemActions>
 
52
#include <KActionMenu>
50
53
 
51
54
#include <kpimutils/kfileio.h>
52
55
 
86
89
    void attachPublicKeyJobResult( KJob *job ); // slot
87
90
    void slotAttachmentContentCreated( KJob *job ); // slot
88
91
    void addAttachmentPart( AttachmentPart::Ptr part );
 
92
    void selectedAllAttachment();
 
93
    void createOpenWithMenu( QMenu *topMenu, AttachmentPart::Ptr part );
89
94
 
90
95
    AttachmentControllerBase *const q;
91
96
    bool encryptEnabled;
95
100
    QHash<MessageViewer::EditorWatcher*,AttachmentPart::Ptr> editorPart;
96
101
    QHash<MessageViewer::EditorWatcher*,KTemporaryFile*> editorTempFile;
97
102
 
98
 
    QMenu *contextMenu;
99
103
    AttachmentPart::List selectedParts;
100
104
    KActionCollection *mActionCollection;
101
105
    QAction *attachPublicKeyAction;
112
116
    QAction *propertiesContextAction;
113
117
    QAction *addAction;
114
118
    QAction *addContextAction;
 
119
    QAction *selectAllAction;
 
120
    KActionMenu *attachmentMenu;
 
121
    QAction *addOwnVcardAction;
115
122
 
116
123
    // If part p is compressed, uncompressedParts[p] is the uncompressed part.
117
124
    QHash<AttachmentPart::Ptr, AttachmentPart::Ptr> uncompressedParts;
123
130
  , signEnabled( false )
124
131
  , model( 0 )
125
132
  , wParent( 0 )
126
 
  , contextMenu( 0 )
127
133
  , attachPublicKeyAction( 0 )
128
134
  , attachMyPublicKeyAction( 0 )
129
135
  , openContextAction( 0 )
138
144
  , propertiesContextAction( 0 )
139
145
  , addAction( 0 )
140
146
  , addContextAction( 0 )
 
147
  , selectAllAction( 0 )
 
148
  , attachmentMenu( 0 )
 
149
  , addOwnVcardAction( 0 )
141
150
{
142
151
}
143
152
 
289
298
  // The watcher deletes itself.
290
299
}
291
300
 
 
301
 
 
302
void AttachmentControllerBase::Private::createOpenWithMenu( QMenu *topMenu, AttachmentPart::Ptr part )
 
303
{
 
304
  const QString contentTypeStr = QString::fromLatin1(part->mimeType());
 
305
  const KService::List offers = KFileItemActions::associatedApplications(QStringList()<<contentTypeStr, QString() );
 
306
  if (!offers.isEmpty()) {
 
307
    QMenu* menu = topMenu;
 
308
    QActionGroup *actionGroup = new QActionGroup( menu );
 
309
    connect( actionGroup, SIGNAL(triggered(QAction*)), q, SLOT(slotOpenWithAction(QAction*)) );
 
310
 
 
311
    if (offers.count() > 1) { // submenu 'open with'
 
312
      menu = new QMenu(i18nc("@title:menu", "&Open With"), topMenu);
 
313
      menu->menuAction()->setObjectName(QLatin1String("openWith_submenu")); // for the unittest
 
314
      topMenu->addMenu(menu);
 
315
    }
 
316
    //kDebug() << offers.count() << "offers" << topMenu << menu;
 
317
 
 
318
    KService::List::ConstIterator it = offers.constBegin();
 
319
    KService::List::ConstIterator end = offers.constEnd();
 
320
    for(; it != end; ++it) {
 
321
      KAction* act = MessageViewer::Util::createAppAction(*it,
 
322
                                        // no submenu -> prefix single offer
 
323
                                        menu == topMenu, actionGroup,menu);
 
324
      menu->addAction(act);
 
325
    }
 
326
 
 
327
    QString openWithActionName;
 
328
    if (menu != topMenu) { // submenu
 
329
      menu->addSeparator();
 
330
      openWithActionName = i18nc("@action:inmenu Open With", "&Other...");
 
331
    } else {
 
332
      openWithActionName = i18nc("@title:menu", "&Open With...");
 
333
    }
 
334
    KAction *openWithAct = new KAction(menu);
 
335
    openWithAct->setText(openWithActionName);
 
336
    QObject::connect(openWithAct, SIGNAL(triggered()), q, SLOT(slotOpenWithDialog()));
 
337
    menu->addAction(openWithAct);
 
338
  }
 
339
  else { // no app offers -> Open With...
 
340
    KAction *act = new KAction(topMenu);
 
341
    act->setText(i18nc("@title:menu", "&Open With..."));
 
342
    QObject::connect(act, SIGNAL(triggered()), q, SLOT(slotOpenWithDialog()));
 
343
    topMenu->addAction(act);
 
344
  }
 
345
}
 
346
 
 
347
 
 
348
 
292
349
void AttachmentControllerBase::exportPublicKey( const QString &fingerprint )
293
350
{
294
351
  if( fingerprint.isEmpty() || !Kleo::CryptoBackendFactory::instance()->openpgp() ) {
318
375
  q->addAttachment( part );
319
376
}
320
377
 
 
378
 
321
379
static KTemporaryFile *dumpAttachmentToTempFile( const AttachmentPart::Ptr part ) // local
322
380
{
323
381
  KTemporaryFile *file = new KTemporaryFile;
369
427
  d->attachMyPublicKeyAction = new KAction( i18n( "Attach &My Public Key" ), this );
370
428
  connect( d->attachMyPublicKeyAction, SIGNAL(triggered(bool)), this, SLOT(attachMyPublicKey()) );
371
429
 
 
430
  d->attachmentMenu = new KActionMenu(i18n("Attach"),this);
 
431
  d->attachmentMenu->setDelayed(false);
 
432
 
372
433
  d->addAction = new KAction( KIcon( QLatin1String( "mail-attachment" ) ), i18n( "&Attach File..." ), this );
373
434
  d->addAction->setIconText( i18n( "Attach" ) );
374
435
  d->addContextAction = new KAction( KIcon( QLatin1String( "mail-attachment" ) ),
376
437
  connect( d->addAction, SIGNAL(triggered(bool)), this, SLOT(showAddAttachmentDialog()) );
377
438
  connect( d->addContextAction, SIGNAL(triggered(bool)), this, SLOT(showAddAttachmentDialog()) );
378
439
 
 
440
  d->addOwnVcardAction = new KAction( i18n("Attach Own Vcard"),this );
 
441
  d->addOwnVcardAction->setIconText( i18n( "Own Vcard" ) );
 
442
  d->addOwnVcardAction->setCheckable(true);
 
443
  connect(d->addOwnVcardAction, SIGNAL(triggered(bool)), this, SIGNAL(addOwnVcard(bool)));
 
444
 
 
445
  d->attachmentMenu->addAction(d->addAction);
 
446
  d->attachmentMenu->addSeparator();
 
447
  d->attachmentMenu->addAction(d->addOwnVcardAction);
 
448
 
379
449
  d->removeAction = new KAction( KIcon(QLatin1String("edit-delete")), i18n( "&Remove Attachment" ), this );
380
450
  d->removeContextAction = new KAction( KIcon(QLatin1String("edit-delete")), i18n( "Remove" ), this ); // FIXME need two texts. is there a better way?
381
451
  connect( d->removeAction, SIGNAL(triggered(bool)), this, SLOT(removeSelectedAttachments()) );
402
472
  connect( d->saveAsContextAction, SIGNAL(triggered(bool)),
403
473
      this, SLOT(saveSelectedAttachmentAs()) );
404
474
 
405
 
  d->propertiesAction = new KAction( i18n( "Attachment Pr&operties" ), this ); // TODO why no '...'?
 
475
  d->propertiesAction = new KAction( i18n( "Attachment Pr&operties..." ), this );
406
476
  d->propertiesContextAction = new KAction( i18n( "Properties" ), this );
407
477
  connect( d->propertiesAction, SIGNAL(triggered(bool)),
408
478
      this, SLOT(selectedAttachmentProperties()) );
409
479
  connect( d->propertiesContextAction, SIGNAL(triggered(bool)),
410
480
      this, SLOT(selectedAttachmentProperties()) );
411
481
 
412
 
  // Create a context menu for the attachment view.
413
 
  Q_ASSERT( d->contextMenu == 0 ); // Not called twice.
414
 
  d->contextMenu = new QMenu( d->wParent );
415
 
  d->contextMenu->addAction( d->openContextAction );
416
 
  d->contextMenu->addAction( d->viewContextAction );
417
 
  d->contextMenu->addAction( d->editContextAction );
418
 
  d->contextMenu->addAction( d->editWithContextAction );
419
 
  d->contextMenu->addAction( d->removeContextAction );
420
 
  d->contextMenu->addAction( d->saveAsContextAction );
421
 
  d->contextMenu->addAction( d->propertiesContextAction );
422
 
  d->contextMenu->addSeparator();
423
 
  d->contextMenu->addAction( d->addContextAction );
 
482
  d->selectAllAction = new KAction( i18n("Select All"), this);
 
483
  connect( d->selectAllAction, SIGNAL(triggered(bool)),
 
484
      this, SIGNAL(selectedAllAttachment()) );
424
485
 
425
486
  // Insert the actions into the composer window's menu.
426
487
  KActionCollection *collection = d->mActionCollection;
430
491
  collection->addAction( QLatin1String( "remove" ), d->removeAction );
431
492
  collection->addAction( QLatin1String( "attach_save" ), d->saveAsAction );
432
493
  collection->addAction( QLatin1String( "attach_properties" ), d->propertiesAction );
433
 
  
 
494
  collection->addAction( QLatin1String( "select_all_attachment"), d->selectAllAction);
 
495
  collection->addAction( QLatin1String( "attach_menu"), d->attachmentMenu );
 
496
  collection->addAction( QLatin1String( "attach_own_vcard"), d->addOwnVcardAction );
434
497
 
435
498
  setSelectedParts( AttachmentPart::List());
436
499
  emit actionsCreated();
469
532
void AttachmentControllerBase::showContextMenu()
470
533
{
471
534
  emit refreshSelection();
472
 
  d->contextMenu->popup( QCursor::pos() );
 
535
 
 
536
 
 
537
  const int numberOfParts(d->selectedParts.count());
 
538
  QMenu *menu = new QMenu;
 
539
 
 
540
  const bool enableEditAction = (numberOfParts == 1) &&
 
541
                                ( !d->selectedParts.first()->isMessageOrMessageCollection() );
 
542
 
 
543
  if(numberOfParts>0) {
 
544
    if(numberOfParts == 1)
 
545
      d->createOpenWithMenu(menu, d->selectedParts.first());
 
546
    else
 
547
      menu->addAction(d->openContextAction);
 
548
    menu->addAction(d->viewContextAction);
 
549
  }
 
550
  if(enableEditAction) {
 
551
    menu->addAction(d->editWithContextAction);
 
552
    menu->addAction(d->editContextAction);
 
553
  }
 
554
  if(numberOfParts>0) {
 
555
    menu->addAction(d->removeContextAction);
 
556
  }
 
557
  if(numberOfParts == 1) {
 
558
    menu->addAction(d->saveAsContextAction);
 
559
    menu->addAction(d->propertiesContextAction);
 
560
  }
 
561
 
 
562
  menu->addSeparator();
 
563
  menu->addAction(d->selectAllAction);
 
564
  menu->addSeparator();
 
565
  menu->addAction(d->addContextAction);
 
566
 
 
567
  menu->exec( QCursor::pos() );
 
568
  delete menu;
 
569
}
 
570
 
 
571
void AttachmentControllerBase::slotOpenWithDialog()
 
572
{
 
573
  openWith();
 
574
}
 
575
 
 
576
void AttachmentControllerBase::slotOpenWithAction(QAction*act)
 
577
{
 
578
  KService::Ptr app = act->data().value<KService::Ptr>();
 
579
  Q_ASSERT( d->selectedParts.count() == 1 );
 
580
 
 
581
  openWith(app);
 
582
}
 
583
 
 
584
void AttachmentControllerBase::openWith(KService::Ptr offer)
 
585
{
 
586
  KTemporaryFile *tempFile = dumpAttachmentToTempFile( d->selectedParts.first() );
 
587
  if( !tempFile ) {
 
588
    KMessageBox::sorry( d->wParent,
 
589
        i18n( "KMail was unable to write the attachment to a temporary file." ),
 
590
        i18n( "Unable to open attachment" ) );
 
591
    return;
 
592
  }
 
593
  KUrl::List lst;
 
594
  KUrl url = KUrl::fromPath(tempFile->fileName());
 
595
  lst.append( url );
 
596
  bool result = false;
 
597
  if(offer) {
 
598
    result = KRun::run( *offer, lst, d->wParent, false );
 
599
  } else {
 
600
    result = KRun::displayOpenWithDialog( lst, d->wParent, false );
 
601
  }
 
602
  if ( !result ) {
 
603
    delete tempFile;
 
604
    tempFile = 0;
 
605
  } else {
 
606
    // The file was opened.  Delete it only when the composer is closed
 
607
    // (and this object is destroyed).
 
608
    tempFile->setParent( this ); // Manages lifetime.
 
609
  }
473
610
}
474
611
 
475
612
void AttachmentControllerBase::openAttachment( AttachmentPart::Ptr part )
477
614
  KTemporaryFile *tempFile = dumpAttachmentToTempFile( part );
478
615
  if( !tempFile ) {
479
616
    KMessageBox::sorry( d->wParent,
480
 
         i18n( "KMail was unable to write the attachment to a temporary file." ),
481
 
         i18n( "Unable to open attachment" ) );
 
617
      i18n( "KMail was unable to write the attachment to a temporary file." ),
 
618
      i18n( "Unable to open attachment" ) );
482
619
    return;
483
620
  }
484
621
 
670
807
  part->setSigned( d->model->isSignSelected() );
671
808
  d->model->addAttachment( part );
672
809
 
673
 
  // TODO I can't find this setting in the config dialog. Has it been removed?
674
810
  if( MessageComposer::MessageComposerSettings::self()->showMessagePartDialogOnAttach() ) {
675
811
    attachmentProperties( part );
676
812
  }
677
813
}
678
814
 
679
 
void AttachmentControllerBase::addAttachment( const KUrl &url )
 
815
MessageCore::AttachmentFromUrlBaseJob * AttachmentControllerBase::createAttachmentJob(const KUrl &url)
680
816
{
681
 
  AttachmentFromUrlBaseJob *ajob = 0;
 
817
  MessageCore::AttachmentFromUrlBaseJob *ajob = 0;
682
818
  if( KMimeType::findByUrl( url )->name() == QLatin1String( "inode/directory" ) ) {
683
819
    kDebug() << "Creating attachment from folder";
684
 
     ajob = new AttachmentFromFolderJob ( url, this );
685
 
  }
686
 
  else{
 
820
    ajob = new AttachmentFromFolderJob ( url, this );
 
821
  } else {
687
822
    ajob = new AttachmentFromUrlJob( url, this );
688
823
    kDebug() << "Creating attachment from file";
689
824
  }
690
825
  if( MessageComposer::MessageComposerSettings::maximumAttachmentSize() > 0 ) {
691
 
    ajob->setMaximumAllowedSize( MessageComposer::MessageComposerSettings::maximumAttachmentSize() * 1024 * 1024 );
692
 
  }
 
826
    ajob->setMaximumAllowedSize( MessageComposer::MessageComposerSettings::maximumAttachmentSize() );
 
827
  }
 
828
  return ajob;
 
829
}
 
830
 
 
831
void AttachmentControllerBase::addAttachmentUrlSync(const KUrl &url)
 
832
{
 
833
  MessageCore::AttachmentFromUrlBaseJob *ajob = createAttachmentJob(url);
 
834
  if(ajob->exec()) {
 
835
    AttachmentPart::Ptr part = ajob->attachmentPart();
 
836
    addAttachment( part );
 
837
  } else {
 
838
    if( ajob->error() ) {
 
839
      KMessageBox::sorry( d->wParent, ajob->errorString(), i18n( "Failed to attach file" ) );
 
840
    }
 
841
  }
 
842
}
 
843
 
 
844
void AttachmentControllerBase::addAttachment( const KUrl &url )
 
845
{
 
846
  MessageCore::AttachmentFromUrlBaseJob *ajob = createAttachmentJob(url);
693
847
  connect( ajob, SIGNAL(result(KJob*)), this, SLOT(loadJobResult(KJob*)) );
694
848
  ajob->start();
695
849
}
729
883
  d->attachMyPublicKeyAction->setEnabled( enable );
730
884
}
731
885
 
 
886
void AttachmentControllerBase::setAttachOwnVcard(bool attachVcard)
 
887
{
 
888
  d->addOwnVcardAction->setChecked(attachVcard);
 
889
}
 
890
 
 
891
bool AttachmentControllerBase::attachOwnVcard() const
 
892
{
 
893
  return  d->addOwnVcardAction->isChecked();
 
894
}
 
895
 
 
896
void AttachmentControllerBase::setIdentityHasOwnVcard(bool state)
 
897
{
 
898
  d->addOwnVcardAction->setEnabled(state);
 
899
}
 
900
 
732
901
#include "attachmentcontrollerbase.moc"