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