00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "koeditorattachments.h"
00027
00028 #include <libkcal/incidence.h>
00029 #include <libkdepim/kpimurlrequesterdlg.h>
00030 #include <libkdepim/kfileio.h>
00031 #include <libkdepim/kdepimprotocols.h>
00032 #include <libkdepim/maillistdrag.h>
00033 #include <libkdepim/kvcarddrag.h>
00034 #include <libkdepim/kdepimprotocols.h>
00035
00036 #include <klocale.h>
00037 #include <kdebug.h>
00038 #include <kmdcodec.h>
00039 #include <kmessagebox.h>
00040 #include <krun.h>
00041 #include <kurldrag.h>
00042 #include <ktempfile.h>
00043 #include <ktempdir.h>
00044 #include <kio/netaccess.h>
00045 #include <kmimetype.h>
00046 #include <kiconloader.h>
00047 #include <kfiledialog.h>
00048 #include <kstdaction.h>
00049 #include <kactioncollection.h>
00050 #include <kpopupmenu.h>
00051 #include <kprotocolinfo.h>
00052 #include <klineedit.h>
00053 #include <kseparator.h>
00054 #include <kurlrequester.h>
00055 #include <libkmime/kmime_message.h>
00056
00057 #include <qcheckbox.h>
00058 #include <qfile.h>
00059 #include <qlabel.h>
00060 #include <qlayout.h>
00061 #include <qlistview.h>
00062 #include <qpushbutton.h>
00063 #include <qdragobject.h>
00064 #include <qtooltip.h>
00065 #include <qwhatsthis.h>
00066 #include <qapplication.h>
00067 #include <qclipboard.h>
00068
00069 #include <cassert>
00070 #include <cstdlib>
00071
00072 class AttachmentListItem : public KIconViewItem
00073 {
00074 public:
00075 AttachmentListItem( KCal::Attachment*att, QIconView *parent ) :
00076 KIconViewItem( parent )
00077 {
00078 if ( att ) {
00079 mAttachment = new KCal::Attachment( *att );
00080 } else {
00081 mAttachment = new KCal::Attachment( QString::null );
00082 }
00083 readAttachment();
00084 setDragEnabled( true );
00085 }
00086 ~AttachmentListItem() { delete mAttachment; }
00087 KCal::Attachment *attachment() const { return mAttachment; }
00088
00089 const QString uri() const
00090 {
00091 return mAttachment->uri();
00092 }
00093 void setUri( const QString &uri )
00094 {
00095 mAttachment->setUri( uri );
00096 readAttachment();
00097 }
00098 void setData( const QByteArray data )
00099 {
00100 mAttachment->setDecodedData( data );
00101 readAttachment();
00102 }
00103 const QString mimeType() const
00104 {
00105 return mAttachment->mimeType();
00106 }
00107 void setMimeType( const QString &mime )
00108 {
00109 mAttachment->setMimeType( mime );
00110 readAttachment();
00111 }
00112 const QString label() const
00113 {
00114 return mAttachment->label();
00115 }
00116 void setLabel( const QString &label )
00117 {
00118 mAttachment->setLabel( label );
00119 readAttachment();
00120 }
00121 bool isBinary() const
00122 {
00123 return mAttachment->isBinary();
00124 }
00125 QPixmap icon() const
00126 {
00127 return icon( KMimeType::mimeType( mAttachment->mimeType() ),
00128 mAttachment->uri() );
00129 }
00130 static QPixmap icon( KMimeType::Ptr mimeType, const QString &uri )
00131 {
00132 QString iconStr = mimeType->icon( uri, false );
00133 return KGlobal::iconLoader()->loadIcon( iconStr, KIcon::Small );
00134 }
00135 void readAttachment()
00136 {
00137 if ( mAttachment->label().isEmpty() ) {
00138 if ( mAttachment->isUri() ) {
00139 setText( mAttachment->uri() );
00140 } else {
00141 setText( i18n( "[Binary data]" ) );
00142 }
00143 } else {
00144 setText( mAttachment->label() );
00145 }
00146 if ( mAttachment->mimeType().isEmpty() ||
00147 !( KMimeType::mimeType( mAttachment->mimeType() ) ) ) {
00148 KMimeType::Ptr mimeType;
00149 if ( mAttachment->isUri() ) {
00150 mimeType = KMimeType::findByURL( mAttachment->uri() );
00151 } else {
00152 mimeType = KMimeType::findByContent( mAttachment->decodedData() );
00153 }
00154 mAttachment->setMimeType( mimeType->name() );
00155 }
00156
00157 setPixmap( icon() );
00158 }
00159
00160 private:
00161 KCal::Attachment *mAttachment;
00162 };
00163
00164 AttachmentEditDialog::AttachmentEditDialog( AttachmentListItem *item,
00165 QWidget *parent )
00166 : KDialogBase ( Plain, i18n( "Add Attachment" ), Ok|Cancel, Ok, parent, 0, false, false ),
00167 mItem( item ), mURLRequester( 0 )
00168 {
00169 QFrame *topFrame = plainPage();
00170 QVBoxLayout *vbl = new QVBoxLayout( topFrame, 0, spacingHint() );
00171
00172 QGridLayout *grid = new QGridLayout();
00173 grid->setColStretch( 0, 0 );
00174 grid->setColStretch( 1, 0 );
00175 grid->setColStretch( 2, 1 );
00176 vbl->addLayout( grid );
00177
00178 mIcon = new QLabel( topFrame );
00179 mIcon->setPixmap( item->icon() );
00180 grid->addWidget( mIcon, 0, 0 );
00181
00182 mLabelEdit = new KLineEdit( topFrame );
00183 mLabelEdit->setClickMessage( i18n( "Attachment name" ) );
00184 if ( !item->uri().isEmpty() ) {
00185 KURL url( item->uri() );
00186 if ( url.isLocalFile() ) {
00187 mLabelEdit->setText( url.fileName() );
00188 } else {
00189 mLabelEdit->setText( url.url() );
00190 }
00191 }
00192 QToolTip::add( mLabelEdit, i18n( "Give the attachment a name" ) );
00193 QWhatsThis::add( mLabelEdit,
00194 i18n( "Type any string you desire here for the name of the attachment" ) );
00195 grid->addMultiCellWidget( mLabelEdit, 0, 0, 1, 2 );
00196
00197 KSeparator *sep = new KSeparator( Qt::Horizontal, topFrame );
00198 grid->addMultiCellWidget( sep, 1, 1, 0, 2 );
00199
00200 QLabel *label = new QLabel( i18n( "Type:" ), topFrame );
00201 grid->addWidget( label, 2, 0 );
00202 QString typecomment = item->mimeType().isEmpty() ?
00203 i18n( "Unknown" ) :
00204 KMimeType::mimeType( item->mimeType() )->comment();
00205 mTypeLabel = new QLabel( typecomment, topFrame );
00206 grid->addWidget( mTypeLabel, 2, 1 );
00207 mMimeType = KMimeType::mimeType( item->mimeType() );
00208
00209 mInline = new QCheckBox( i18n( "Store attachment inline" ), topFrame );
00210 grid->addMultiCellWidget( mInline, 3, 3, 0, 2 );
00211 mInline->setChecked( item->isBinary() );
00212 QToolTip::add( mInline, i18n( "Store the attachment file inside the calendar" ) );
00213 QWhatsThis::add(
00214 mInline,
00215 i18n( "Checking this option will cause the attachment to be stored inside "
00216 "your calendar, which can take a lot of space depending on the size "
00217 "of the attachment. If this option is not checked, then only a link "
00218 "pointing to the attachment will be stored. Do not use a link for "
00219 "attachments that change often or may be moved (or removed) from "
00220 "their current location." ) );
00221
00222 if ( item->attachment()->isUri() ) {
00223 label = new QLabel( i18n( "Location:" ), topFrame );
00224 grid->addWidget( label, 4, 0 );
00225 mURLRequester = new KURLRequester( item->uri(), topFrame );
00226 QToolTip::add( mURLRequester, i18n( "Provide a location for the attachment file" ) );
00227 QWhatsThis::add(
00228 mURLRequester,
00229 i18n( "Enter the path to the attachment file or use the "
00230 "file browser by pressing the adjacent button" ) );
00231 grid->addMultiCellWidget( mURLRequester, 4, 4, 1, 2 );
00232 connect( mURLRequester, SIGNAL(urlSelected(const QString &)),
00233 SLOT(urlSelected(const QString &)) );
00234 connect( mURLRequester, SIGNAL( textChanged( const QString& ) ),
00235 SLOT( urlChanged( const QString& ) ) );
00236 urlChanged( item->uri() );
00237 } else {
00238 uint size = QCString( item->attachment()->data() ).size();
00239 grid->addWidget( new QLabel( i18n( "Size:" ), topFrame ), 4, 0 );
00240 grid->addWidget( new QLabel( QString::fromLatin1( "%1 (%2)" ).
00241 arg( KIO::convertSize( size ) ).
00242 arg( KGlobal::locale()->formatNumber(
00243 size, 0 ) ), topFrame ), 4, 2 );
00244 }
00245 vbl->addStretch( 10 );
00246 }
00247
00248 void AttachmentEditDialog::slotApply()
00249 {
00250 KURL url( mURLRequester->url() );
00251 if ( mLabelEdit->text().isEmpty() ) {
00252 if ( url.isLocalFile() ) {
00253 mItem->setLabel( url.fileName() );
00254 } else {
00255 mItem->setLabel( url.url() );
00256 }
00257 } else {
00258 mItem->setLabel( mLabelEdit->text() );
00259 }
00260 if ( mItem->label().isEmpty() ) {
00261 mItem->setLabel( i18n( "New attachment" ) );
00262 }
00263 mItem->setMimeType( mMimeType->name() );
00264 if ( mURLRequester ) {
00265 if ( mInline->isChecked() ) {
00266 QString tmpFile;
00267 if ( KIO::NetAccess::download( mURLRequester->url(), tmpFile, this ) ) {
00268 QFile f( tmpFile );
00269 if ( !f.open( IO_ReadOnly ) ) {
00270 return;
00271 }
00272 QByteArray data = f.readAll();
00273 f.close();
00274 mItem->setData( data );
00275 }
00276 KIO::NetAccess::removeTempFile( tmpFile );
00277 } else {
00278 mItem->setUri( url.url() );
00279 }
00280 }
00281 }
00282
00283 void AttachmentEditDialog::accept()
00284 {
00285 slotApply();
00286 KDialog::accept();
00287 }
00288
00289 void AttachmentEditDialog::urlChanged( const QString &url )
00290 {
00291 enableButton( Ok, !url.isEmpty() );
00292 }
00293
00294 void AttachmentEditDialog::urlSelected( const QString &url )
00295 {
00296 KURL kurl( url );
00297 mMimeType = KMimeType::findByURL( kurl );
00298 mTypeLabel->setText( mMimeType->comment() );
00299 mIcon->setPixmap( AttachmentListItem::icon( mMimeType, kurl.path() ) );
00300 }
00301
00302 AttachmentIconView::AttachmentIconView( KOEditorAttachments* parent )
00303 : KIconView( parent ),
00304 mParent( parent )
00305 {
00306 setSelectionMode( QIconView::Extended );
00307 setMode( KIconView::Select );
00308 setItemTextPos( QIconView::Right );
00309 setArrangement( QIconView::LeftToRight );
00310 setMaxItemWidth( QMAX(maxItemWidth(), 250) );
00311 setMinimumHeight( QMAX(fontMetrics().height(), 16) + 12 );
00312
00313 connect( this, SIGNAL( dropped ( QDropEvent *, const QValueList<QIconDragItem> & ) ),
00314 this, SLOT( handleDrop( QDropEvent *, const QValueList<QIconDragItem> & ) ) );
00315 }
00316
00317 KURL AttachmentIconView::tempFileForAttachment( KCal::Attachment *attachment )
00318 {
00319 if ( mTempFiles.contains( attachment ) ) {
00320 return mTempFiles[attachment];
00321 }
00322 QStringList patterns = KMimeType::mimeType( attachment->mimeType() )->patterns();
00323
00324 KTempFile *file;
00325 if ( !patterns.empty() ) {
00326 file = new KTempFile( QString::null,
00327 QString( patterns.first() ).remove( '*' ),0600 );
00328 } else {
00329 file = new KTempFile( QString::null, QString::null, 0600 );
00330 }
00331 file->setAutoDelete( true );
00332 file->file()->open( IO_WriteOnly );
00333 QTextStream stream( file->file() );
00334 stream << attachment->decodedData().data();
00335 KURL url( file->name() );
00336 mTempFiles.insert( attachment, url );
00337 file->close();
00338 return mTempFiles[attachment];
00339 }
00340
00341 QDragObject *AttachmentIconView::mimeData()
00342 {
00343
00344 KURL::List urls;
00345 QStringList labels;
00346 for ( QIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
00347 if ( it->isSelected() ) {
00348 AttachmentListItem *item = static_cast<AttachmentListItem *>( it );
00349 if ( item->isBinary() ) {
00350 urls.append( tempFileForAttachment( item->attachment() ) );
00351 } else {
00352 urls.append( item->uri() );
00353 }
00354 labels.append( KURL::encode_string( item->label() ) );
00355 }
00356 }
00357 if ( selectionMode() == QIconView::NoSelection ) {
00358 AttachmentListItem *item = static_cast<AttachmentListItem *>( currentItem() );
00359 if ( item ) {
00360 urls.append( item->uri() );
00361 labels.append( KURL::encode_string( item->label() ) );
00362 }
00363 }
00364
00365 QMap<QString, QString> metadata;
00366 metadata["labels"] = labels.join( ":" );
00367
00368 KURLDrag *drag = new KURLDrag( urls, metadata );
00369 return drag;
00370 }
00371
00372 AttachmentIconView::~AttachmentIconView()
00373 {
00374 for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
00375 delete *it;
00376 }
00377 }
00378
00379 QDragObject * AttachmentIconView::dragObject()
00380 {
00381 KURL::List urls;
00382 for ( QIconViewItem *it = firstItem( ); it; it = it->nextItem( ) ) {
00383 if ( !it->isSelected() ) continue;
00384 AttachmentListItem * item = dynamic_cast<AttachmentListItem*>( it );
00385 if ( !item ) return 0;
00386 KCal::Attachment * att = item->attachment();
00387 assert( att );
00388 KURL url;
00389 if ( att->isUri() ) {
00390 url.setPath( att->uri() );
00391 } else {
00392 KTempDir * tempDir = new KTempDir();
00393 tempDir->setAutoDelete( true );
00394 mTempDirs.insert( tempDir );
00395 QByteArray encoded;
00396 encoded.duplicate( att->data(), strlen(att->data()) );
00397 QByteArray decoded;
00398 KCodecs::base64Decode( encoded, decoded );
00399 const QString fileName = tempDir->name( ) + "/" + att->label();
00400 KPIM::kByteArrayToFile( decoded, fileName, false, false, false );
00401 url.setPath( fileName );
00402 }
00403 urls << url;
00404 }
00405 KURLDrag *drag = new KURLDrag( urls, this );
00406 return drag;
00407 }
00408
00409 void AttachmentIconView::handleDrop( QDropEvent *event, const QValueList<QIconDragItem> & list )
00410 {
00411 Q_UNUSED( list );
00412 mParent->handlePasteOrDrop( event );
00413 }
00414
00415
00416 void AttachmentIconView::dragMoveEvent( QDragMoveEvent *event )
00417 {
00418 mParent->dragMoveEvent( event );
00419 }
00420
00421 void AttachmentIconView::contentsDragMoveEvent( QDragMoveEvent *event )
00422 {
00423 mParent->dragMoveEvent( event );
00424 }
00425
00426 void AttachmentIconView::contentsDragEnterEvent( QDragEnterEvent *event )
00427 {
00428 mParent->dragMoveEvent( event );
00429 }
00430
00431 void AttachmentIconView::dragEnterEvent( QDragEnterEvent *event )
00432 {
00433 mParent->dragEnterEvent( event );
00434 }
00435
00436 KOEditorAttachments::KOEditorAttachments( int spacing, QWidget *parent,
00437 const char *name )
00438 : QWidget( parent, name )
00439 {
00440 QBoxLayout *topLayout = new QHBoxLayout( this );
00441 topLayout->setSpacing( spacing );
00442
00443 QLabel *label = new QLabel( i18n("Attachments:"), this );
00444 topLayout->addWidget( label );
00445
00446 mAttachments = new AttachmentIconView( this );
00447 QWhatsThis::add( mAttachments,
00448 i18n("Displays a list of current items (files, mail, etc.) "
00449 "that have been associated with this event or to-do. ") );
00450 topLayout->addWidget( mAttachments );
00451 connect( mAttachments, SIGNAL( doubleClicked( QIconViewItem * ) ),
00452 SLOT( showAttachment( QIconViewItem * ) ) );
00453 connect( mAttachments, SIGNAL(selectionChanged()),
00454 SLOT(selectionChanged()) );
00455 connect( mAttachments, SIGNAL(contextMenuRequested(QIconViewItem*,const QPoint&)),
00456 SLOT(contextMenu(QIconViewItem*,const QPoint&)) );
00457
00458 QPushButton *addButton = new QPushButton( this );
00459 addButton->setIconSet( SmallIconSet( "add" ) );
00460 QToolTip::add( addButton, i18n( "Add an attachment" ) );
00461 QWhatsThis::add( addButton,
00462 i18n( "Shows a dialog used to select an attachment "
00463 "to add to this event or to-do as link or as "
00464 "inline data." ) );
00465 topLayout->addWidget( addButton );
00466 connect( addButton, SIGNAL(clicked()), SLOT(slotAdd()) );
00467
00468 mRemoveBtn = new QPushButton( this );
00469 mRemoveBtn->setIconSet( SmallIconSet( "remove" ) );
00470 QToolTip::add( mRemoveBtn, i18n("&Remove") );
00471 QWhatsThis::add( mRemoveBtn,
00472 i18n("Removes the attachment selected in the list above "
00473 "from this event or to-do.") );
00474 topLayout->addWidget( mRemoveBtn );
00475 connect( mRemoveBtn, SIGNAL(clicked()), SLOT(slotRemove()) );
00476
00477 mContextMenu = new KPopupMenu( this );
00478
00479 KActionCollection* ac = new KActionCollection( this, this );
00480
00481 mOpenAction = new KAction( i18n("Open"), 0, this, SLOT(slotShow()), ac );
00482 mOpenAction->plug( mContextMenu );
00483 mContextMenu->insertSeparator();
00484
00485 mCopyAction = KStdAction::copy(this, SLOT(slotCopy()), ac );
00486 mCopyAction->plug( mContextMenu );
00487 mCutAction = KStdAction::cut(this, SLOT(slotCut()), ac );
00488 mCutAction->plug( mContextMenu );
00489 KAction *action = KStdAction::paste(this, SLOT(slotPaste()), ac );
00490 action->plug( mContextMenu );
00491 mContextMenu->insertSeparator();
00492
00493 mDeleteAction = new KAction( i18n( "&Remove" ), 0, this, SLOT(slotRemove()), ac );
00494 mDeleteAction->plug( mContextMenu );
00495 mContextMenu->insertSeparator();
00496
00497 mEditAction = new KAction( i18n( "&Properties..." ), 0, this, SLOT(slotEdit()), ac );
00498 mEditAction->plug( mContextMenu );
00499
00500 selectionChanged();
00501 setAcceptDrops( true );
00502 }
00503
00504 KOEditorAttachments::~KOEditorAttachments()
00505 {
00506 }
00507
00508 bool KOEditorAttachments::hasAttachments()
00509 {
00510 return mAttachments->count() != 0;
00511 }
00512
00513 void KOEditorAttachments::dragMoveEvent( QDragMoveEvent *event )
00514 {
00515 event->accept( KURLDrag::canDecode( event ) ||
00516 QTextDrag::canDecode( event ) ||
00517 KPIM::MailListDrag::canDecode( event ) ||
00518 KVCardDrag::canDecode( event ) );
00519 }
00520
00521 void KOEditorAttachments::dragEnterEvent( QDragEnterEvent* event )
00522 {
00523 dragMoveEvent( event );
00524 }
00525
00526 void KOEditorAttachments::handlePasteOrDrop( QMimeSource* source )
00527 {
00528 KURL::List urls;
00529 bool probablyWeHaveUris = false;
00530 bool weCanCopy = true;
00531 QStringList labels;
00532
00533 if ( KVCardDrag::canDecode( source ) ) {
00534 KABC::Addressee::List addressees;
00535 KVCardDrag::decode( source, addressees );
00536 for ( KABC::Addressee::List::ConstIterator it = addressees.constBegin();
00537 it != addressees.constEnd(); ++it ) {
00538 urls.append( KDEPIMPROTOCOL_CONTACT + ( *it ).uid() );
00539
00540 labels.append( QString::fromUtf8( ( *it ).realName().latin1() ) );
00541 }
00542 probablyWeHaveUris = true;
00543 } else if ( KURLDrag::canDecode( source ) ) {
00544 QMap<QString,QString> metadata;
00545 if ( KURLDrag::decode( source, urls, metadata ) ) {
00546 probablyWeHaveUris = true;
00547 labels = QStringList::split( ':', metadata["labels"], FALSE );
00548 for ( QStringList::Iterator it = labels.begin(); it != labels.end(); ++it ) {
00549 *it = KURL::decode_string( (*it).latin1() );
00550 }
00551
00552 }
00553 } else if ( QTextDrag::canDecode( source ) ) {
00554 QString text;
00555 QTextDrag::decode( source, text );
00556 QStringList lst = QStringList::split( '\n', text, FALSE );
00557 for ( QStringList::ConstIterator it = lst.constBegin(); it != lst.constEnd(); ++it ) {
00558 urls.append( *it );
00559 labels.append( QString::null );
00560 }
00561 probablyWeHaveUris = true;
00562 }
00563
00564 KPopupMenu menu;
00565 int items=0;
00566 if ( probablyWeHaveUris ) {
00567 menu.insertItem( i18n( "&Link here" ), DRAG_LINK, items++ );
00568
00569 for ( KURL::List::ConstIterator it = urls.constBegin(); it != urls.constEnd(); ++it ) {
00570 if ( !( weCanCopy = KProtocolInfo::supportsReading( *it ) ) ) {
00571 break;
00572 }
00573 }
00574 if ( weCanCopy ) {
00575 menu.insertItem( SmallIcon( "editcopy" ), i18n( "&Copy Here" ), DRAG_COPY, items++ );
00576 }
00577 } else {
00578 menu.insertItem( SmallIcon( "editcopy" ), i18n( "&Copy Here" ), DRAG_COPY, items++ );
00579 }
00580
00581 menu.insertSeparator();
00582 items++;
00583 menu.insertItem( SmallIcon( "cancel" ), i18n( "C&ancel" ), DRAG_CANCEL, items );
00584 int action = menu.exec( QCursor::pos(), 0 );
00585
00586 if ( action == DRAG_LINK ) {
00587 QStringList::ConstIterator jt = labels.constBegin();
00588 for ( KURL::List::ConstIterator it = urls.constBegin();
00589 it != urls.constEnd(); ++it ) {
00590 QString label = (*jt++);
00591 if ( mAttachments->findItem( label ) ) {
00592 label += '~' + randomString( 3 );
00593 }
00594 addUriAttachment( (*it).url(), QString::null, label, true );
00595 }
00596 } else if ( action != DRAG_CANCEL ) {
00597 if ( probablyWeHaveUris ) {
00598 for ( KURL::List::ConstIterator it = urls.constBegin();
00599 it != urls.constEnd(); ++it ) {
00600 QString label = (*it).fileName();
00601 if ( label.isEmpty() ) {
00602 label = (*it).prettyURL();
00603 }
00604 if ( mAttachments->findItem( label ) ) {
00605 label += '~' + randomString( 3 );
00606 }
00607 addUriAttachment( (*it).url(), QString::null, label, true );
00608 }
00609 } else {
00610 addDataAttachment( source->encodedData( source->format() ),
00611 source->format(),
00612 KMimeType::mimeType( source->format() )->name() );
00613 }
00614 }
00615 }
00616
00617 void KOEditorAttachments::dropEvent( QDropEvent* event )
00618 {
00619 handlePasteOrDrop( event );
00620 }
00621
00622 void KOEditorAttachments::showAttachment( QIconViewItem *item )
00623 {
00624 AttachmentListItem *attitem = static_cast<AttachmentListItem*>(item);
00625 if ( !attitem || !attitem->attachment() ) return;
00626
00627 KCal::Attachment *att = attitem->attachment();
00628 if ( att->isUri() ) {
00629 emit openURL( att->uri() );
00630 } else {
00631 KRun::runURL( mAttachments->tempFileForAttachment( att ), att->mimeType(), 0, true );
00632 }
00633 }
00634
00635 void KOEditorAttachments::slotAdd()
00636 {
00637 AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
00638
00639 AttachmentEditDialog *dlg = new AttachmentEditDialog( item, mAttachments )
00640 ;
00641 if ( dlg->exec() == KDialog::Rejected ) {
00642 delete item;
00643 }
00644 delete dlg;
00645 }
00646
00647 void KOEditorAttachments::slotAddData()
00648 {
00649 KURL uri = KFileDialog::getOpenFileName( QString(), QString(), this, i18n("Add Attachment") );
00650 if ( !uri.isEmpty() ) {
00651 QString label = uri.fileName();
00652 if ( label.isEmpty() ) {
00653 label = uri.prettyURL();
00654 }
00655 addUriAttachment( uri.url(), QString::null, label, true );
00656 }
00657 }
00658
00659 void KOEditorAttachments::slotEdit()
00660 {
00661 for ( QIconViewItem *item = mAttachments->firstItem(); item; item = item->nextItem() ) {
00662 if ( item->isSelected() ) {
00663 AttachmentListItem *attitem = static_cast<AttachmentListItem*>( item );
00664 if ( !attitem || !attitem->attachment() ) {
00665 return;
00666 }
00667
00668 AttachmentEditDialog *dialog = new AttachmentEditDialog( attitem, mAttachments );
00669 dialog->mInline->setEnabled( false );
00670 dialog->setModal( false );
00671 connect( dialog, SIGNAL(hidden()), dialog, SLOT(delayedDestruct()) );
00672 dialog->show();
00673 }
00674 }
00675 }
00676
00677 void KOEditorAttachments::slotRemove()
00678 {
00679 QValueList<QIconViewItem*> selected;
00680 for ( QIconViewItem *it = mAttachments->firstItem( ); it; it = it->nextItem( ) ) {
00681 if ( !it->isSelected() ) continue;
00682 selected << it;
00683 }
00684 if ( selected.isEmpty() || KMessageBox::warningContinueCancel(this,
00685 selected.count() == 1?i18n("This item will be permanently deleted."):
00686 i18n("The selected items will be permanently deleted."),
00687 i18n("KOrganizer Confirmation"),KStdGuiItem::del()) != KMessageBox::Continue )
00688 return;
00689
00690 for ( QValueList<QIconViewItem*>::iterator it( selected.begin() ), end( selected.end() ); it != end ; ++it ) {
00691 delete *it;
00692 }
00693 }
00694
00695 void KOEditorAttachments::slotShow()
00696 {
00697 for ( QIconViewItem *it = mAttachments->firstItem(); it; it = it->nextItem() ) {
00698 if ( !it->isSelected() )
00699 continue;
00700 showAttachment( it );
00701 }
00702 }
00703
00704 void KOEditorAttachments::setDefaults()
00705 {
00706 mAttachments->clear();
00707 }
00708
00709 QString KOEditorAttachments::randomString(int length) const
00710 {
00711 if (length <=0 ) return QString();
00712
00713 QString str; str.setLength( length );
00714 int i = 0;
00715 while (length--)
00716 {
00717 int r=random() % 62;
00718 r+=48;
00719 if (r>57) r+=7;
00720 if (r>90) r+=6;
00721 str[i++] = char(r);
00722
00723 }
00724 return str;
00725 }
00726
00727 void KOEditorAttachments::addUriAttachment( const QString &uri,
00728 const QString &mimeType,
00729 const QString &label,
00730 bool inLine )
00731 {
00732 if ( !inLine ) {
00733 AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
00734 item->setUri( uri );
00735 item->setLabel( label );
00736 if ( mimeType.isEmpty() ) {
00737 if ( uri.startsWith( KDEPIMPROTOCOL_CONTACT ) ) {
00738 item->setMimeType( "text/directory" );
00739 } else if ( uri.startsWith( KDEPIMPROTOCOL_EMAIL ) ) {
00740 item->setMimeType( "message/rfc822" );
00741 } else if ( uri.startsWith( KDEPIMPROTOCOL_INCIDENCE ) ) {
00742 item->setMimeType( "text/calendar" );
00743 } else if ( uri.startsWith( KDEPIMPROTOCOL_NEWSARTICLE ) ) {
00744 item->setMimeType( "message/news" );
00745 } else {
00746 item->setMimeType( KMimeType::findByURL( uri )->name() );
00747 }
00748 }
00749 } else {
00750 QString tmpFile;
00751 if ( KIO::NetAccess::download( uri, tmpFile, this ) ) {
00752 QFile f( tmpFile );
00753 if ( !f.open( IO_ReadOnly ) ) {
00754 return;
00755 }
00756 const QByteArray data = f.readAll();
00757 f.close();
00758 addDataAttachment( data, mimeType, label );
00759 }
00760 KIO::NetAccess::removeTempFile( tmpFile );
00761 }
00762 }
00763
00764 void KOEditorAttachments::addDataAttachment( const QByteArray &data,
00765 const QString &mimeType,
00766 const QString &label )
00767 {
00768 AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
00769
00770 QString nlabel = label;
00771 if ( mimeType == "message/rfc822" ) {
00772
00773 KMime::Message msg;
00774 msg.setContent( data.data() );
00775 msg.parse();
00776 nlabel = msg.subject()->asUnicodeString();
00777 }
00778
00779 item->setData( data );
00780 item->setLabel( nlabel );
00781 if ( mimeType.isEmpty() ) {
00782 item->setMimeType( KMimeType::findByContent( data )->name() );
00783 } else {
00784 item->setMimeType( mimeType );
00785 }
00786 }
00787
00788 void KOEditorAttachments::addAttachment( KCal::Attachment *attachment )
00789 {
00790 new AttachmentListItem( attachment, mAttachments );
00791 }
00792
00793 void KOEditorAttachments::readIncidence( KCal::Incidence *i )
00794 {
00795 mAttachments->clear();
00796
00797 KCal::Attachment::List attachments = i->attachments();
00798 KCal::Attachment::List::ConstIterator it;
00799 for( it = attachments.begin(); it != attachments.end(); ++it ) {
00800 addAttachment( (*it) );
00801 }
00802 if ( mAttachments->count() > 0 ) {
00803 QTimer::singleShot( 0, mAttachments, SLOT(arrangeItemsInGrid()) );
00804 }
00805 }
00806
00807 void KOEditorAttachments::writeIncidence( KCal::Incidence *i )
00808 {
00809 i->clearAttachments();
00810
00811 QIconViewItem *item;
00812 AttachmentListItem *attitem;
00813 for( item = mAttachments->firstItem(); item; item = item->nextItem() ) {
00814 attitem = static_cast<AttachmentListItem*>(item);
00815 if ( attitem )
00816 i->addAttachment( new KCal::Attachment( *(attitem->attachment() ) ) );
00817 }
00818 }
00819
00820
00821 void KOEditorAttachments::slotCopy()
00822 {
00823 QApplication::clipboard()->setData( mAttachments->mimeData(), QClipboard::Clipboard );
00824 }
00825
00826 void KOEditorAttachments::slotCut()
00827 {
00828 slotCopy();
00829 slotRemove();
00830 }
00831
00832 void KOEditorAttachments::slotPaste()
00833 {
00834 handlePasteOrDrop( QApplication::clipboard()->data() );
00835 }
00836
00837 void KOEditorAttachments::selectionChanged()
00838 {
00839 bool selected = false;
00840 for ( QIconViewItem *item = mAttachments->firstItem(); item; item = item->nextItem() ) {
00841 if ( item->isSelected() ) {
00842 selected = true;
00843 break;
00844 }
00845 }
00846 mRemoveBtn->setEnabled( selected );
00847 }
00848
00849 void KOEditorAttachments::contextMenu(QIconViewItem * item, const QPoint & pos)
00850 {
00851 const bool enable = item != 0;
00852 mOpenAction->setEnabled( enable );
00853 mCopyAction->setEnabled( enable );
00854 mCutAction->setEnabled( enable );
00855 mDeleteAction->setEnabled( enable );
00856 mEditAction->setEnabled( enable );
00857 mContextMenu->exec( pos );
00858 }
00859
00860 #include "koeditorattachments.moc"