summaryrefslogtreecommitdiffstats
path: root/korganizer/koeditorattachments.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'korganizer/koeditorattachments.cpp')
-rw-r--r--korganizer/koeditorattachments.cpp831
1 files changed, 627 insertions, 204 deletions
diff --git a/korganizer/koeditorattachments.cpp b/korganizer/koeditorattachments.cpp
index adcd871e..99d775e6 100644
--- a/korganizer/koeditorattachments.cpp
+++ b/korganizer/koeditorattachments.cpp
@@ -25,15 +25,19 @@
#include "koeditorattachments.h"
+#include <libkcal/attachmenthandler.h>
#include <libkcal/incidence.h>
#include <libkdepim/kpimurlrequesterdlg.h>
#include <libkdepim/kfileio.h>
+#include <libkdepim/kdepimprotocols.h>
+#include <libkdepim/maillistdrag.h>
+#include <libkdepim/kvcarddrag.h>
+#include <libkdepim/kdepimprotocols.h>
#include <klocale.h>
#include <kdebug.h>
#include <kmdcodec.h>
#include <kmessagebox.h>
-#include <kiconview.h>
#include <krun.h>
#include <kurldrag.h>
#include <ktempfile.h>
@@ -45,7 +49,13 @@
#include <kstdaction.h>
#include <kactioncollection.h>
#include <kpopupmenu.h>
+#include <kprotocolinfo.h>
+#include <klineedit.h>
+#include <kseparator.h>
+#include <kurlrequester.h>
+#include <libkmime/kmime_message.h>
+#include <tqcheckbox.h>
#include <tqfile.h>
#include <tqlabel.h>
#include <tqlayout.h>
@@ -58,7 +68,7 @@
#include <tqclipboard.h>
#include <cassert>
-#include <set>
+#include <cstdlib>
class AttachmentListItem : public KIconViewItem
{
@@ -69,7 +79,8 @@ class AttachmentListItem : public KIconViewItem
if ( att ) {
mAttachment = new KCal::Attachment( *att );
} else {
- mAttachment = new KCal::Attachment( TQString::null );
+ mAttachment = new KCal::Attachment( '\0' ); //use the non-uri constructor
+ //as we want inline by default
}
readAttachment();
setDragEnabled( true );
@@ -77,112 +88,364 @@ class AttachmentListItem : public KIconViewItem
~AttachmentListItem() { delete mAttachment; }
KCal::Attachment *attachment() const { return mAttachment; }
+ const TQString uri() const
+ {
+ return mAttachment->uri();
+ }
void setUri( const TQString &uri )
{
mAttachment->setUri( uri );
readAttachment();
}
- void setData( const char *base64 )
+ void setData( const TQByteArray data )
{
- mAttachment->setData( base64 );
+ mAttachment->setDecodedData( data );
readAttachment();
}
+ const TQString mimeType() const
+ {
+ return mAttachment->mimeType();
+ }
void setMimeType( const TQString &mime )
{
mAttachment->setMimeType( mime );
readAttachment();
}
+ const TQString label() const
+ {
+ return mAttachment->label();
+ }
void setLabel( const TQString &label )
{
mAttachment->setLabel( label );
readAttachment();
}
-
+ bool isBinary() const
+ {
+ return mAttachment->isBinary();
+ }
+ TQPixmap icon() const
+ {
+ return icon( KMimeType::mimeType( mAttachment->mimeType() ),
+ mAttachment->uri() );
+ }
+ static TQPixmap icon( KMimeType::Ptr mimeType, const TQString &uri )
+ {
+ TQString iconStr = mimeType->icon( uri, false );
+ return KGlobal::iconLoader()->loadIcon( iconStr, KIcon::Small );
+ }
void readAttachment()
{
- if ( mAttachment->isUri() )
- setText( mAttachment->uri() );
- else {
- if ( mAttachment->label().isEmpty() )
- setText( i18n("[Binary data]") );
- else
- setText( mAttachment->label() );
+ if ( mAttachment->label().isEmpty() ) {
+ if ( mAttachment->isUri() ) {
+ setText( mAttachment->uri() );
+ } else {
+ setText( i18n( "[Binary data]" ) );
+ }
+ } else {
+ setText( mAttachment->label() );
}
- KMimeType::Ptr mt = KMimeType::mimeType( mAttachment->mimeType() );
- if ( mt ) {
- const TQString iconName( mt->icon( TQString(), false ) );
- TQPixmap pix = KGlobal::iconLoader( )->loadIcon( iconName, KIcon::Small );
- if ( pix.isNull() )
- pix = KGlobal::iconLoader( )->loadIcon( "unknown", KIcon::Small );
- if ( !pix.isNull() )
- setPixmap( pix );
+ if ( mAttachment->mimeType().isEmpty() ||
+ !( KMimeType::mimeType( mAttachment->mimeType() ) ) ) {
+ KMimeType::Ptr mimeType;
+ if ( mAttachment->isUri() ) {
+ mimeType = KMimeType::findByURL( mAttachment->uri() );
+ } else {
+ mimeType = KMimeType::findByContent( mAttachment->decodedData() );
+ }
+ mAttachment->setMimeType( mimeType->name() );
}
+
+ setPixmap( icon() );
}
private:
KCal::Attachment *mAttachment;
};
-class AttachmentIconView : public KIconView
-{
- friend class KOEditorAttachments;
- public:
- AttachmentIconView( KOEditorAttachments* parent=0 )
- :KIconView( parent ),
- mParent( parent )
- {
- setAcceptDrops( true );
- setSelectionMode( TQIconView::Extended );
- setMode( KIconView::Select );
- setItemTextPos( TQIconView::Right );
- setArrangement( TQIconView::LeftToRight );
- setMaxItemWidth( QMAX(maxItemWidth(), 250) );
- setMinimumHeight( QMAX(fontMetrics().height(), 16) + 12 );
- }
- ~AttachmentIconView()
- {
- for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
- delete *it;
- }
- }
- protected:
- TQDragObject * dragObject()
- {
- KURL::List urls;
- for ( TQIconViewItem *it = firstItem( ); it; it = it->nextItem( ) ) {
- if ( !it->isSelected() ) continue;
- AttachmentListItem * item = dynamic_cast<AttachmentListItem*>( it );
- if ( !item ) return 0;
- KCal::Attachment * att = item->attachment();
- assert( att );
- KURL url;
- if ( att->isUri() ) {
- url.setPath( att->uri() );
- } else {
- KTempDir * tempDir = new KTempDir(); // will be deleted on editor close
- tempDir->setAutoDelete( true );
- mTempDirs.insert( tempDir );
- TQByteArray encoded;
- encoded.duplicate( att->data(), strlen(att->data()) );
- TQByteArray decoded;
- KCodecs::base64Decode( encoded, decoded );
- const TQString fileName = tempDir->name( ) + "/" + att->label();
- KPIM::kByteArrayToFile( decoded, fileName, false, false, false );
- url.setPath( fileName );
- }
- urls << url;
- }
- KURLDrag *drag = new KURLDrag( urls, this );
- return drag;
- }
- void contentsDropEvent( TQDropEvent* event )
- {
- mParent->handlePasteOrDrop( event );
+AttachmentEditDialog::AttachmentEditDialog( AttachmentListItem *item,
+ TQWidget *parent )
+ : KDialogBase ( Plain, i18n( "Add Attachment" ), Ok|Cancel, Ok, parent, 0, false, false ),
+ mItem( item ), mURLRequester( 0 )
+{
+ TQFrame *topFrame = plainPage();
+ TQVBoxLayout *vbl = new TQVBoxLayout( topFrame, 0, spacingHint() );
+
+ TQGridLayout *grid = new TQGridLayout();
+ grid->setColStretch( 0, 0 );
+ grid->setColStretch( 1, 0 );
+ grid->setColStretch( 2, 1 );
+ vbl->addLayout( grid );
+
+ mIcon = new TQLabel( topFrame );
+ mIcon->setPixmap( item->icon() );
+ grid->addWidget( mIcon, 0, 0 );
+
+ mLabelEdit = new KLineEdit( topFrame );
+ mLabelEdit->setText( item->label().isEmpty() ? item->uri() : item->label() );
+ mLabelEdit->setClickMessage( i18n( "Attachment name" ) );
+ TQToolTip::add( mLabelEdit, i18n( "Give the attachment a name" ) );
+ TQWhatsThis::add( mLabelEdit,
+ i18n( "Type any string you desire here for the name of the attachment" ) );
+ grid->addMultiCellWidget( mLabelEdit, 0, 0, 1, 2 );
+
+ KSeparator *sep = new KSeparator( TQt::Horizontal, topFrame );
+ grid->addMultiCellWidget( sep, 1, 1, 0, 2 );
+
+ TQLabel *label = new TQLabel( i18n( "Type:" ), topFrame );
+ grid->addWidget( label, 2, 0 );
+ TQString typecomment = item->mimeType().isEmpty() ?
+ i18n( "Unknown" ) :
+ KMimeType::mimeType( item->mimeType() )->comment();
+ mTypeLabel = new TQLabel( typecomment, topFrame );
+ grid->addWidget( mTypeLabel, 2, 1 );
+ mMimeType = KMimeType::mimeType( item->mimeType() );
+
+ mInline = new TQCheckBox( i18n( "Store attachment inline" ), topFrame );
+ grid->addMultiCellWidget( mInline, 3, 3, 0, 2 );
+ mInline->setChecked( item->isBinary() );
+ TQToolTip::add( mInline, i18n( "Store the attachment file inside the calendar" ) );
+ TQWhatsThis::add(
+ mInline,
+ i18n( "Checking this option will cause the attachment to be stored inside "
+ "your calendar, which can take a lot of space depending on the size "
+ "of the attachment. If this option is not checked, then only a link "
+ "pointing to the attachment will be stored. Do not use a link for "
+ "attachments that change often or may be moved (or removed) from "
+ "their current location." ) );
+
+ if ( item->attachment()->isUri() || !item->attachment()->data() ) {
+ label = new TQLabel( i18n( "Location:" ), topFrame );
+ grid->addWidget( label, 4, 0 );
+ mURLRequester = new KURLRequester( item->uri(), topFrame );
+ TQToolTip::add( mURLRequester, i18n( "Provide a location for the attachment file" ) );
+ TQWhatsThis::add(
+ mURLRequester,
+ i18n( "Enter the path to the attachment file or use the "
+ "file browser by pressing the adjacent button" ) );
+ grid->addMultiCellWidget( mURLRequester, 4, 4, 1, 2 );
+ connect( mURLRequester, TQT_SIGNAL(urlSelected(const TQString &)),
+ TQT_SLOT(urlSelected(const TQString &)) );
+ connect( mURLRequester, TQT_SIGNAL( textChanged( const TQString& ) ),
+ TQT_SLOT( urlChanged( const TQString& ) ) );
+ urlChanged( item->uri() );
+ } else {
+ uint size = item->attachment()->size();
+ grid->addWidget( new TQLabel( i18n( "Size:" ), topFrame ), 4, 0 );
+ grid->addWidget( new TQLabel( TQString::fromLatin1( "%1 (%2)" ).
+ arg( KIO::convertSize( size ) ).
+ arg( KGlobal::locale()->formatNumber(
+ size, 0 ) ), topFrame ), 4, 2 );
+ }
+ vbl->addStretch( 10 );
+}
+
+void AttachmentEditDialog::slotApply()
+{
+ if ( !mLabelEdit->text().isEmpty() ) {
+ mItem->setLabel( mLabelEdit->text() );
+ } else {
+ if ( mURLRequester ) {
+ KURL url( mURLRequester->url() );
+ if ( url.isLocalFile() ) {
+ mItem->setLabel( url.fileName() );
+ } else {
+ mItem->setLabel( url.url() );
+ }
+ }
+ }
+ if ( mItem->label().isEmpty() ) {
+ mItem->setLabel( i18n( "New attachment" ) );
+ }
+ mItem->setMimeType( mMimeType->name() );
+ if ( mURLRequester ) {
+ KURL url( mURLRequester->url() );
+
+ TQString correctedUrl = mURLRequester->url();
+ if ( !url.isValid() ) {
+ // If the user used KURLRequester's KURLCompletion
+ // (used the line edit instead of the file dialog)
+ // the returned url is not absolute and is always relative
+ // to the home directory (not pwd), so we must prepend home
+
+ correctedUrl = TQDir::home().filePath( mURLRequester->url() );
+ url = KURL( correctedUrl );
+ if ( url.isValid() ) {
+ urlSelected( correctedUrl );
+ mItem->setMimeType( mMimeType->name() );
+ }
+ }
+
+ if ( mInline->isChecked() ) {
+ TQString tmpFile;
+ if ( KIO::NetAccess::download( correctedUrl, tmpFile, this ) ) {
+ TQFile f( tmpFile );
+ if ( !f.open( IO_ReadOnly ) ) {
+ return;
}
- private:
- std::set<KTempDir*> mTempDirs;
- KOEditorAttachments* mParent;
-};
+ TQByteArray data = f.readAll();
+ f.close();
+ mItem->setData( data );
+ }
+ KIO::NetAccess::removeTempFile( tmpFile );
+ } else {
+ mItem->setUri( url.url() );
+ }
+ }
+}
+
+void AttachmentEditDialog::accept()
+{
+ slotApply();
+ KDialog::accept();
+}
+
+void AttachmentEditDialog::urlChanged( const TQString &url )
+{
+ enableButton( Ok, !url.isEmpty() );
+}
+
+void AttachmentEditDialog::urlSelected( const TQString &url )
+{
+ KURL kurl( url );
+ mMimeType = KMimeType::findByURL( kurl );
+ mTypeLabel->setText( mMimeType->comment() );
+ mIcon->setPixmap( AttachmentListItem::icon( mMimeType, kurl.path() ) );
+}
+
+AttachmentIconView::AttachmentIconView( KOEditorAttachments* parent )
+ : KIconView( parent ),
+ mParent( parent )
+{
+ setSelectionMode( TQIconView::Extended );
+ setMode( KIconView::Select );
+ setItemTextPos( TQIconView::Right );
+ setArrangement( TQIconView::LeftToRight );
+ setMaxItemWidth( QMAX(maxItemWidth(), 250) );
+ setMinimumHeight( QMAX(fontMetrics().height(), 16) + 12 );
+
+ connect( this, TQT_SIGNAL( dropped ( TQDropEvent *, const TQValueList<TQIconDragItem> & ) ),
+ this, TQT_SLOT( handleDrop( TQDropEvent *, const TQValueList<TQIconDragItem> & ) ) );
+}
+
+KURL AttachmentIconView::tempFileForAttachment( KCal::Attachment *attachment )
+{
+ if ( mTempFiles.contains( attachment ) ) {
+ return mTempFiles[attachment];
+ }
+ TQStringList patterns = KMimeType::mimeType( attachment->mimeType() )->patterns();
+
+ KTempFile *file;
+ if ( !patterns.empty() ) {
+ file = new KTempFile( TQString::null,
+ TQString( patterns.first() ).remove( '*' ),0600 );
+ } else {
+ file = new KTempFile( TQString::null, TQString::null, 0600 );
+ }
+ file->setAutoDelete( true );
+ file->file()->open( IO_WriteOnly );
+ TQTextStream stream( file->file() );
+ stream.writeRawBytes( attachment->decodedData().data(), attachment->size() );
+ KURL url( file->name() );
+ mTempFiles.insert( attachment, url );
+ file->close();
+ return mTempFiles[attachment];
+}
+
+TQDragObject *AttachmentIconView::mimeData()
+{
+ // create a list of the URL:s that we want to drag
+ KURL::List urls;
+ TQStringList labels;
+ for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
+ if ( it->isSelected() ) {
+ AttachmentListItem *item = static_cast<AttachmentListItem *>( it );
+ if ( item->isBinary() ) {
+ urls.append( tempFileForAttachment( item->attachment() ) );
+ } else {
+ urls.append( item->uri() );
+ }
+ labels.append( KURL::encode_string( item->label() ) );
+ }
+ }
+ if ( selectionMode() == TQIconView::NoSelection ) {
+ AttachmentListItem *item = static_cast<AttachmentListItem *>( currentItem() );
+ if ( item ) {
+ urls.append( item->uri() );
+ labels.append( KURL::encode_string( item->label() ) );
+ }
+ }
+
+ TQMap<TQString, TQString> metadata;
+ metadata["labels"] = labels.join( ":" );
+
+ KURLDrag *drag = new KURLDrag( urls, metadata );
+ return drag;
+}
+
+AttachmentIconView::~AttachmentIconView()
+{
+ for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
+ delete *it;
+ }
+}
+
+TQDragObject * AttachmentIconView::dragObject()
+{
+ KURL::List urls;
+ for ( TQIconViewItem *it = firstItem( ); it; it = it->nextItem( ) ) {
+ if ( !it->isSelected() ) continue;
+ AttachmentListItem * item = dynamic_cast<AttachmentListItem*>( it );
+ if ( !item ) return 0;
+ KCal::Attachment * att = item->attachment();
+ assert( att );
+ KURL url;
+ if ( att->isUri() ) {
+ url.setPath( att->uri() );
+ } else {
+ KTempDir *tempDir = new KTempDir(); // will be deleted on editor close
+ tempDir->setAutoDelete( true );
+ mTempDirs.insert( tempDir );
+ TQByteArray encoded;
+ encoded.duplicate( att->data(), strlen( att->data() ) );
+ TQByteArray decoded;
+ KCodecs::base64Decode( encoded, decoded );
+ const TQString fileName = tempDir->name( ) + '/' + att->label();
+ KPIM::kByteArrayToFile( decoded, fileName, false, false, false );
+ url.setPath( fileName );
+ }
+ urls << url;
+ }
+ KURLDrag *drag = new KURLDrag( urls, this );
+ return drag;
+}
+
+void AttachmentIconView::handleDrop( TQDropEvent *event, const TQValueList<TQIconDragItem> & list )
+{
+ Q_UNUSED( list );
+ mParent->handlePasteOrDrop( event );
+}
+
+
+void AttachmentIconView::dragMoveEvent( TQDragMoveEvent *event )
+{
+ mParent->dragMoveEvent( event );
+}
+
+void AttachmentIconView::contentsDragMoveEvent( TQDragMoveEvent *event )
+{
+ mParent->dragMoveEvent( event );
+}
+
+void AttachmentIconView::contentsDragEnterEvent( TQDragEnterEvent *event )
+{
+ mParent->dragMoveEvent( event );
+}
+
+void AttachmentIconView::dragEnterEvent( TQDragEnterEvent *event )
+{
+ mParent->dragEnterEvent( event );
+}
KOEditorAttachments::KOEditorAttachments( int spacing, TQWidget *parent,
const char *name )
@@ -206,44 +469,51 @@ KOEditorAttachments::KOEditorAttachments( int spacing, TQWidget *parent,
connect( mAttachments, TQT_SIGNAL(contextMenuRequested(TQIconViewItem*,const TQPoint&)),
TQT_SLOT(contextMenu(TQIconViewItem*,const TQPoint&)) );
- mAddMenu = new KPopupMenu( this );
+ TQPushButton *addButton = new TQPushButton( this );
+ addButton->setIconSet( SmallIconSet( "add" ) );
+ TQToolTip::add( addButton, i18n( "Add an attachment" ) );
+ TQWhatsThis::add( addButton,
+ i18n( "Shows a dialog used to select an attachment "
+ "to add to this event or to-do as link or as "
+ "inline data." ) );
+ topLayout->addWidget( addButton );
+ connect( addButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotAdd()) );
+
+ mRemoveBtn = new TQPushButton( this );
+ mRemoveBtn->setIconSet( SmallIconSet( "remove" ) );
+ TQToolTip::add( mRemoveBtn, i18n("&Remove") );
+ TQWhatsThis::add( mRemoveBtn,
+ i18n("Removes the attachment selected in the list above "
+ "from this event or to-do.") );
+ topLayout->addWidget( mRemoveBtn );
+ connect( mRemoveBtn, TQT_SIGNAL(clicked()), TQT_SLOT(slotRemove()) );
+
mContextMenu = new KPopupMenu( this );
KActionCollection* ac = new KActionCollection( this, this );
- mOpenAction = new KAction( i18n("View"), 0, this, TQT_SLOT(slotShow()), ac );
+ mOpenAction = new KAction( i18n("Open"), 0, this, TQT_SLOT(slotShow()), ac );
mOpenAction->plug( mContextMenu );
+
+ mSaveAsAction = new KAction( i18n( "Save As..." ), 0, this, TQT_SLOT(slotSaveAs()), ac );
+ mSaveAsAction->plug( mContextMenu );
mContextMenu->insertSeparator();
- mCopyAction = KStdAction::copy(this, TQT_SLOT(slotCopy( ) ), ac );
+ mCopyAction = KStdAction::copy(this, TQT_SLOT(slotCopy()), ac );
mCopyAction->plug( mContextMenu );
- mCutAction = KStdAction::cut(this, TQT_SLOT(slotCut( ) ), ac );
+ mCutAction = KStdAction::cut(this, TQT_SLOT(slotCut()), ac );
mCutAction->plug( mContextMenu );
- KAction *action = KStdAction::paste(this, TQT_SLOT(slotPaste( ) ), ac );
+ KAction *action = KStdAction::paste(this, TQT_SLOT(slotPaste()), ac );
action->plug( mContextMenu );
+ mContextMenu->insertSeparator();
- action = new KAction( i18n("&Attach File..."), 0, this, TQT_SLOT(slotAddData()), ac );
- action->setWhatsThis( i18n("Shows a dialog used to select an attachment "
- "to add to this event or to-do as link as inline data.") );
- action->plug( mAddMenu );
- action = new KAction( i18n("Attach &Link..."), 0, this, TQT_SLOT(slotAdd()), ac );
- action->setWhatsThis( i18n("Shows a dialog used to select an attachment "
- "to add to this event or to-do as link.") );
- action->plug( mAddMenu );
+ mDeleteAction = new KAction( i18n( "&Remove" ), 0, this, TQT_SLOT(slotRemove()), ac );
+ mDeleteAction->plug( mContextMenu );
+ mDeleteAction->setShortcut( Key_Delete );
+ mContextMenu->insertSeparator();
- TQPushButton *addButton = new TQPushButton( this );
- addButton->setIconSet( SmallIconSet( "add" ) );
- addButton->setPopup( mAddMenu );
- topLayout->addWidget( addButton );
-
- mRemoveBtn = new TQPushButton( this );
- mRemoveBtn->setIconSet( SmallIconSet( "remove" ) );
- TQToolTip::add( mRemoveBtn, i18n("&Remove") );
- TQWhatsThis::add( mRemoveBtn,
- i18n("Removes the attachment selected in the list above "
- "from this event or to-do.") );
- topLayout->addWidget( mRemoveBtn );
- connect( mRemoveBtn, TQT_SIGNAL( clicked() ), TQT_SLOT( slotRemove() ) );
+ mEditAction = new KAction( i18n( "&Properties..." ), 0, this, TQT_SLOT(slotEdit()), ac );
+ mEditAction->plug( mContextMenu );
selectionChanged();
setAcceptDrops( true );
@@ -258,26 +528,106 @@ bool KOEditorAttachments::hasAttachments()
return mAttachments->count() != 0;
}
+void KOEditorAttachments::dragMoveEvent( TQDragMoveEvent *event )
+{
+ event->accept( KURLDrag::canDecode( event ) ||
+ TQTextDrag::canDecode( event ) ||
+ KPIM::MailListDrag::canDecode( event ) ||
+ KVCardDrag::canDecode( event ) );
+}
+
void KOEditorAttachments::dragEnterEvent( TQDragEnterEvent* event )
{
- event->accept( KURLDrag::canDecode( event ) | TQTextDrag::canDecode( event ) );
+ dragMoveEvent( event );
}
void KOEditorAttachments::handlePasteOrDrop( TQMimeSource* source )
{
KURL::List urls;
- TQString text;
- if ( KURLDrag::decode( source, urls ) ) {
- const bool asUri = KMessageBox::questionYesNo( this,
- i18n("Do you want to link to the attachments, or include them in the event?"),
- i18n("Attach as link?"), i18n("As Link"), i18n("As File") ) == KMessageBox::Yes;
- for ( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) {
- addAttachment( (*it).url(), TQString::null, asUri );
- }
- } else if ( TQTextDrag::decode( source, text ) ) {
- TQStringList lst = TQStringList::split( '\n', text );
- for ( TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
- addAttachment( (*it) );
+ bool probablyWeHaveUris = false;
+ bool weCanCopy = true;
+ TQStringList labels;
+
+ if ( KVCardDrag::canDecode( source ) ) {
+ KABC::Addressee::List addressees;
+ KVCardDrag::decode( source, addressees );
+ for ( KABC::Addressee::List::ConstIterator it = addressees.constBegin();
+ it != addressees.constEnd(); ++it ) {
+ urls.append( KDEPIMPROTOCOL_CONTACT + ( *it ).uid() );
+ // there is some weirdness about realName(), hence fromUtf8
+ labels.append( TQString::fromUtf8( ( *it ).realName().latin1() ) );
+ }
+ probablyWeHaveUris = true;
+ } else if ( KURLDrag::canDecode( source ) ) {
+ TQMap<TQString,TQString> metadata;
+ if ( KURLDrag::decode( source, urls, metadata ) ) {
+ probablyWeHaveUris = true;
+ labels = TQStringList::split( ':', metadata["labels"], FALSE );
+ for ( TQStringList::Iterator it = labels.begin(); it != labels.end(); ++it ) {
+ *it = KURL::decode_string( (*it).latin1() );
+ }
+
+ }
+ } else if ( TQTextDrag::canDecode( source ) ) {
+ TQString text;
+ TQTextDrag::decode( source, text );
+ TQStringList lst = TQStringList::split( '\n', text, FALSE );
+ for ( TQStringList::ConstIterator it = lst.constBegin(); it != lst.constEnd(); ++it ) {
+ urls.append( *it );
+ labels.append( TQString::null );
+ }
+ probablyWeHaveUris = true;
+ }
+
+ KPopupMenu menu;
+ int items=0;
+ if ( probablyWeHaveUris ) {
+ menu.insertItem( i18n( "&Link here" ), DRAG_LINK, items++ );
+ // we need to check if we can reasonably expect to copy the objects
+ for ( KURL::List::ConstIterator it = urls.constBegin(); it != urls.constEnd(); ++it ) {
+ if ( !( weCanCopy = KProtocolInfo::supportsReading( *it ) ) ) {
+ break; // either we can copy them all, or no copying at all
+ }
+ }
+ if ( weCanCopy ) {
+ menu.insertItem( SmallIcon( "editcopy" ), i18n( "&Copy Here" ), DRAG_COPY, items++ );
+ }
+ } else {
+ menu.insertItem( SmallIcon( "editcopy" ), i18n( "&Copy Here" ), DRAG_COPY, items++ );
+ }
+
+ menu.insertSeparator();
+ items++;
+ menu.insertItem( SmallIcon( "cancel" ), i18n( "C&ancel" ), DRAG_CANCEL, items );
+ int action = menu.exec( TQCursor::pos(), 0 );
+
+ if ( action == DRAG_LINK ) {
+ TQStringList::ConstIterator jt = labels.constBegin();
+ for ( KURL::List::ConstIterator it = urls.constBegin();
+ it != urls.constEnd(); ++it ) {
+ TQString label = (*jt++);
+ if ( mAttachments->findItem( label ) ) {
+ label += '~' + randomString( 3 );
+ }
+ addUriAttachment( (*it).url(), TQString::null, label, true );
+ }
+ } else if ( action != DRAG_CANCEL ) {
+ if ( probablyWeHaveUris ) {
+ for ( KURL::List::ConstIterator it = urls.constBegin();
+ it != urls.constEnd(); ++it ) {
+ TQString label = (*it).fileName();
+ if ( label.isEmpty() ) {
+ label = (*it).prettyURL();
+ }
+ if ( mAttachments->findItem( label ) ) {
+ label += '~' + randomString( 3 );
+ }
+ addUriAttachment( (*it).url(), TQString::null, label, true );
+ }
+ } else { // we take anything
+ addDataAttachment( source->encodedData( source->format() ),
+ source->format(),
+ KMimeType::mimeType( source->format() )->name() );
}
}
}
@@ -293,95 +643,98 @@ void KOEditorAttachments::showAttachment( TQIconViewItem *item )
if ( !attitem || !attitem->attachment() ) return;
KCal::Attachment *att = attitem->attachment();
- if ( att->isUri() ) {
- emit openURL( att->uri() );
- } else {
- KTempFile f;
- if ( !f.file() )
- return;
- TQByteArray encoded;
- encoded.duplicate( att->data(), strlen(att->data()) );
- TQByteArray decoded;
- KCodecs::base64Decode( encoded, decoded );
- f.file()->writeBlock( decoded );
- f.file()->close();
- KRun::runURL( f.name(), att->mimeType(), true, false );
- }
+ KCal::AttachmentHandler::view( this, att );
+}
+
+void KOEditorAttachments::saveAttachment( TQIconViewItem *item )
+{
+ AttachmentListItem *attitem = static_cast<AttachmentListItem*>(item);
+ if ( !attitem || !attitem->attachment() ) return;
+
+ KCal::Attachment *att = attitem->attachment();
+ KCal::AttachmentHandler::saveAs( this, att );
}
void KOEditorAttachments::slotAdd()
{
- KURL uri = KPimURLRequesterDlg::getURL( TQString::null, i18n(
- "URL (e.g. a web page) or file to be attached (only "
- "the link will be attached, not the file itself):"), this,
- i18n("Add Attachment") );
- if ( !uri.isEmpty() ) {
- addAttachment( uri );
+ AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
+
+ AttachmentEditDialog *dlg = new AttachmentEditDialog( item, mAttachments )
+;
+ if ( dlg->exec() == KDialog::Rejected ) {
+ delete item;
}
+ delete dlg;
}
void KOEditorAttachments::slotAddData()
{
KURL uri = KFileDialog::getOpenFileName( TQString(), TQString(), this, i18n("Add Attachment") );
if ( !uri.isEmpty() ) {
- addAttachment( uri, TQString::null, false );
+ TQString label = uri.fileName();
+ if ( label.isEmpty() ) {
+ label = uri.prettyURL();
+ }
+ addUriAttachment( uri.url(), TQString::null, label, true );
}
}
void KOEditorAttachments::slotEdit()
{
- TQIconViewItem *item = mAttachments->currentItem();
- AttachmentListItem *attitem = static_cast<AttachmentListItem*>(item);
- if ( !attitem || !attitem->attachment() ) return;
-
- KCal::Attachment *att = attitem->attachment();
- if ( att->isUri() ) {
- KURL uri = KPimURLRequesterDlg::getURL( att->uri(), i18n(
- "URL (e.g. a web page) or file to be attached (only "
- "the link will be attached, not the file itself):"), this,
- i18n("Edit Attachment") );
-
- if ( !uri.isEmpty() )
- attitem->setUri( uri.url() );
- } else {
- KURL uri = KPimURLRequesterDlg::getURL( TQString::null, i18n(
- "File to be attached:"), this, i18n("Add Attachment") );
- if ( !uri.isEmpty() ) {
- TQString tmpFile;
- if ( KIO::NetAccess::download( uri, tmpFile, this ) ) {
- TQFile f( tmpFile );
- if ( !f.open( IO_ReadOnly ) )
- return;
- TQByteArray data = f.readAll();
- f.close();
- attitem->setData( KCodecs::base64Encode( data ) );
- attitem->setMimeType( KIO::NetAccess::mimetype( uri, this ) );
- TQString label = uri.fileName();
- if ( label.isEmpty() )
- label = uri.prettyURL();
- attitem->setLabel( label );
- KIO::NetAccess::removeTempFile( tmpFile );
+ for ( TQIconViewItem *item = mAttachments->firstItem(); item; item = item->nextItem() ) {
+ if ( item->isSelected() ) {
+ AttachmentListItem *attitem = static_cast<AttachmentListItem*>( item );
+ if ( !attitem || !attitem->attachment() ) {
+ return;
}
+
+ AttachmentEditDialog *dialog = new AttachmentEditDialog( attitem, mAttachments );
+ dialog->mInline->setEnabled( false );
+ dialog->setModal( false );
+ connect( dialog, TQT_SIGNAL(hidden()), dialog, TQT_SLOT(delayedDestruct()) );
+ dialog->show();
}
}
}
void KOEditorAttachments::slotRemove()
{
- TQValueList<TQIconViewItem*> selected;
- for ( TQIconViewItem *it = mAttachments->firstItem( ); it; it = it->nextItem( ) ) {
- if ( !it->isSelected() ) continue;
- selected << it;
- }
- if ( selected.isEmpty() || KMessageBox::warningContinueCancel(this,
- selected.count() == 1?i18n("This item will be permanently deleted."):
- i18n("The selected items will be permanently deleted."),
- i18n("KOrganizer Confirmation"),KStdGuiItem::del()) != KMessageBox::Continue )
- return;
+ TQValueList<TQIconViewItem*> selected;
+ TQStringList labels;
+ for ( TQIconViewItem *it = mAttachments->firstItem( ); it; it = it->nextItem( ) ) {
+ if ( !it->isSelected() ) continue;
+ selected << it;
+
+ AttachmentListItem *attitem = static_cast<AttachmentListItem*>(it);
+ KCal::Attachment *att = attitem->attachment();
+ labels << att->label();
+ }
- for ( TQValueList<TQIconViewItem*>::iterator it( selected.begin() ), end( selected.end() ); it != end ; ++it ) {
- delete *it;
+ if ( selected.isEmpty() ) {
+ return;
+ }
+
+ TQString labelsStr = labels.join( "<br>" );
+
+ if ( KMessageBox::questionYesNo(
+ this,
+ i18n( "<qt>Do you really want to remove these attachments?<p>%1</qt>" ).arg( labelsStr ),
+ i18n( "Remove Attachment?" ),
+ KStdGuiItem::yes(), KStdGuiItem::no(),
+ "calendarRemoveAttachments" ) != KMessageBox::Yes ) {
+ return;
+ }
+
+ for ( TQValueList<TQIconViewItem*>::iterator it( selected.begin() ), end( selected.end() );
+ it != end ; ++it ) {
+ if ( (*it)->nextItem() ) {
+ (*it)->nextItem()->setSelected( true );
+ } else if ( (*it)->prevItem() ) {
+ (*it)->prevItem()->setSelected( true );
}
+ delete *it;
+ }
+ mAttachments->slotUpdate();
}
void KOEditorAttachments::slotShow()
@@ -393,40 +746,98 @@ void KOEditorAttachments::slotShow()
}
}
+void KOEditorAttachments::slotSaveAs()
+{
+ for ( TQIconViewItem *it = mAttachments->firstItem(); it; it = it->nextItem() ) {
+ if ( !it->isSelected() )
+ continue;
+ saveAttachment( it );
+ }
+}
+
void KOEditorAttachments::setDefaults()
{
mAttachments->clear();
}
-void KOEditorAttachments::addAttachment( const KURL &uri,
- const TQString &mimeType, bool asUri )
+TQString KOEditorAttachments::randomString(int length) const
{
- AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
- if ( asUri ) {
- item->setUri( uri.url() );
- if ( !mimeType.isEmpty() ) item->setMimeType( mimeType );
+ if (length <=0 ) return TQString();
+
+ TQString str; str.setLength( length );
+ int i = 0;
+ while (length--)
+ {
+ int r=random() % 62;
+ r+=48;
+ if (r>57) r+=7;
+ if (r>90) r+=6;
+ str[i++] = char(r);
+ // so what if I work backwards?
+ }
+ return str;
+}
+
+void KOEditorAttachments::addUriAttachment( const TQString &uri,
+ const TQString &mimeType,
+ const TQString &label,
+ bool inLine )
+{
+ if ( !inLine ) {
+ AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
+ item->setUri( uri );
+ item->setLabel( label );
+ if ( mimeType.isEmpty() ) {
+ if ( uri.startsWith( KDEPIMPROTOCOL_CONTACT ) ) {
+ item->setMimeType( "text/directory" );
+ } else if ( uri.startsWith( KDEPIMPROTOCOL_EMAIL ) ) {
+ item->setMimeType( "message/rfc822" );
+ } else if ( uri.startsWith( KDEPIMPROTOCOL_INCIDENCE ) ) {
+ item->setMimeType( "text/calendar" );
+ } else if ( uri.startsWith( KDEPIMPROTOCOL_NEWSARTICLE ) ) {
+ item->setMimeType( "message/news" );
+ } else {
+ item->setMimeType( KMimeType::findByURL( uri )->name() );
+ }
+ }
} else {
TQString tmpFile;
if ( KIO::NetAccess::download( uri, tmpFile, this ) ) {
TQFile f( tmpFile );
- if ( !f.open( IO_ReadOnly ) )
+ if ( !f.open( IO_ReadOnly ) ) {
return;
- TQByteArray data = f.readAll();
+ }
+ const TQByteArray data = f.readAll();
f.close();
- item->setData( KCodecs::base64Encode( data ) );
- if ( !mimeType.isEmpty() )
- item->setMimeType( mimeType );
- else
- item->setMimeType( KIO::NetAccess::mimetype( uri, this ) );
- TQString label = uri.fileName();
- if ( label.isEmpty() )
- label = uri.prettyURL();
- item->setLabel( label );
- KIO::NetAccess::removeTempFile( tmpFile );
+ addDataAttachment( data, mimeType, label );
}
+ KIO::NetAccess::removeTempFile( tmpFile );
}
}
+void KOEditorAttachments::addDataAttachment( const TQByteArray &data,
+ const TQString &mimeType,
+ const TQString &label )
+{
+ AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
+
+ TQString nlabel = label;
+ if ( mimeType == "message/rfc822" ) {
+ // mail message. try to set the label from the mail Subject:
+ KMime::Message msg;
+ msg.setContent( data.data() );
+ msg.parse();
+ nlabel = msg.subject()->asUnicodeString();
+ }
+
+ item->setData( data );
+ item->setLabel( nlabel );
+ if ( mimeType.isEmpty() ) {
+ item->setMimeType( KMimeType::findByContent( data )->name() );
+ } else {
+ item->setMimeType( mimeType );
+ }
+}
void KOEditorAttachments::addAttachment( KCal::Attachment *attachment )
{
@@ -463,7 +874,7 @@ void KOEditorAttachments::writeIncidence( KCal::Incidence *i )
void KOEditorAttachments::slotCopy()
{
- TQApplication::clipboard()->setData( mAttachments->dragObject(), QClipboard::Clipboard );
+ TQApplication::clipboard()->setData( mAttachments->mimeData(), QClipboard::Clipboard );
}
void KOEditorAttachments::slotCut()
@@ -492,9 +903,21 @@ void KOEditorAttachments::selectionChanged()
void KOEditorAttachments::contextMenu(TQIconViewItem * item, const TQPoint & pos)
{
const bool enable = item != 0;
+
+ int numSelected = 0;
+ for ( TQIconViewItem *item = mAttachments->firstItem(); item; item = item->nextItem() ) {
+ if ( item->isSelected() ) {
+ numSelected++;
+ }
+ }
+
mOpenAction->setEnabled( enable );
- mCopyAction->setEnabled( enable );
- mCutAction->setEnabled( enable );
+ //TODO: support saving multiple attachments into a directory
+ mSaveAsAction->setEnabled( enable && numSelected == 1 );
+ mCopyAction->setEnabled( enable && numSelected == 1 );
+ mCutAction->setEnabled( enable && numSelected == 1 );
+ mDeleteAction->setEnabled( enable );
+ mEditAction->setEnabled( enable );
mContextMenu->exec( pos );
}