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