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
00027
00028
00029
00030
00031
00032
00033 #include <config.h>
00034
00035 #include "kmmimeparttree.h"
00036
00037 #include "kmreaderwin.h"
00038 #include "partNode.h"
00039 #include "kmmsgpart.h"
00040 #include "kmkernel.h"
00041 #include "kmcommands.h"
00042
00043 #include <kdebug.h>
00044 #include <klocale.h>
00045 #include <kfiledialog.h>
00046 #include <kmessagebox.h>
00047 #include <kiconloader.h>
00048
00049 #include <qclipboard.h>
00050 #include <qheader.h>
00051 #include <qpopupmenu.h>
00052 #include <qstyle.h>
00053 #include <kurldrag.h>
00054 #include <kurl.h>
00055
00056
00057 KMMimePartTree::KMMimePartTree( KMReaderWin* readerWin,
00058 QWidget* parent,
00059 const char* name )
00060 : KListView( parent, name ),
00061 mReaderWin( readerWin ), mSizeColumn(0)
00062 {
00063 setStyleDependantFrameWidth();
00064 addColumn( i18n("Description") );
00065 addColumn( i18n("Type") );
00066 addColumn( i18n("Encoding") );
00067 mSizeColumn = addColumn( i18n("Size") );
00068 setColumnAlignment( 3, Qt::AlignRight );
00069
00070 restoreLayoutIfPresent();
00071 connect( this, SIGNAL( clicked( QListViewItem* ) ),
00072 this, SLOT( itemClicked( QListViewItem* ) ) );
00073 connect( this, SIGNAL( contextMenuRequested( QListViewItem*,
00074 const QPoint&, int ) ),
00075 this, SLOT( itemRightClicked( QListViewItem*, const QPoint& ) ) );
00076 setSelectionMode( QListView::Extended );
00077 setRootIsDecorated( false );
00078 setAllColumnsShowFocus( true );
00079 setShowToolTips( true );
00080 setSorting(-1);
00081 setDragEnabled( true );
00082 }
00083
00084
00085 static const char configGroup[] = "MimePartTree";
00086
00087 KMMimePartTree::~KMMimePartTree() {
00088 saveLayout( KMKernel::config(), configGroup );
00089 }
00090
00091
00092 void KMMimePartTree::restoreLayoutIfPresent() {
00093
00094 setColumnWidthMode( 0, Manual );
00095 header()->setStretchEnabled( true, 0 );
00096
00097 if ( KMKernel::config()->hasGroup( configGroup ) ) {
00098
00099 restoreLayout( KMKernel::config(), configGroup );
00100
00101 for ( int i = 1 ; i < 4 ; ++i )
00102 setColumnWidthMode( i, Manual );
00103 } else {
00104
00105 for ( int i = 1 ; i < 4 ; ++i )
00106 setColumnWidthMode( i, Maximum );
00107 }
00108 }
00109
00110
00111 void KMMimePartTree::itemClicked( QListViewItem* item )
00112 {
00113 if ( const KMMimePartTreeItem * i = dynamic_cast<KMMimePartTreeItem*>( item ) ) {
00114 if( mReaderWin->mRootNode == i->node() )
00115 mReaderWin->update( true );
00116 else
00117 mReaderWin->setMsgPart( i->node() );
00118 } else
00119 kdWarning(5006) << "Item was not a KMMimePartTreeItem!" << endl;
00120 }
00121
00122
00123 void KMMimePartTree::itemRightClicked( QListViewItem* item,
00124 const QPoint& point )
00125 {
00126
00127 mCurrentContextMenuItem = dynamic_cast<KMMimePartTreeItem*>( item );
00128 if ( 0 == mCurrentContextMenuItem ) {
00129 kdDebug(5006) << "Item was not a KMMimePartTreeItem!" << endl;
00130 }
00131 else {
00132 kdDebug(5006) << "\n**\n** KMMimePartTree::itemRightClicked() **\n**" << endl;
00133
00134 QPopupMenu* popup = new QPopupMenu;
00135 if ( mCurrentContextMenuItem->node()->nodeId() > 2 &&
00136 mCurrentContextMenuItem->node()->typeString() != "Multipart" ) {
00137 popup->insertItem( SmallIcon("fileopen"), i18n("to open", "Open"), this, SLOT(slotOpen()) );
00138 popup->insertItem( i18n("Open With..."), this, SLOT(slotOpenWith()) );
00139 popup->insertItem( i18n("to view something", "View"), this, SLOT(slotView()) );
00140 }
00141 popup->insertItem( SmallIcon("filesaveas"),i18n( "Save &As..." ), this, SLOT( slotSaveAs() ) );
00142
00143
00144
00145
00146
00147 popup->insertItem( i18n( "Save All Attachments..." ), this,
00148 SLOT( slotSaveAll() ) );
00149
00150 if ( mCurrentContextMenuItem->node()->nodeId() > 2 &&
00151 mCurrentContextMenuItem->node()->typeString() != "Multipart" ) {
00152 popup->insertItem( SmallIcon("editcopy"), i18n("Copy"), this, SLOT(slotCopy()) );
00153 if ( GlobalSettings::self()->allowAttachmentDeletion() )
00154 popup->insertItem( SmallIcon("editdelete"), i18n( "Delete Attachment" ),
00155 this, SLOT( slotDelete() ) );
00156 if ( GlobalSettings::self()->allowAttachmentEditing() )
00157 popup->insertItem( SmallIcon( "edit" ), i18n( "Edit Attachment" ),
00158 this, SLOT( slotEdit() ) );
00159 }
00160 if ( mCurrentContextMenuItem->node()->nodeId() > 0 )
00161 popup->insertItem( i18n("Properties"), this, SLOT(slotProperties()) );
00162 popup->exec( point );
00163 delete popup;
00164 mCurrentContextMenuItem = 0;
00165 }
00166 }
00167
00168
00169 void KMMimePartTree::slotSaveAs()
00170 {
00171 saveSelectedBodyParts( false );
00172 }
00173
00174
00175 void KMMimePartTree::slotSaveAsEncoded()
00176 {
00177 saveSelectedBodyParts( true );
00178 }
00179
00180
00181 void KMMimePartTree::saveSelectedBodyParts( bool encoded )
00182 {
00183 QPtrList<QListViewItem> selected = selectedItems();
00184
00185 Q_ASSERT( !selected.isEmpty() );
00186 if ( selected.isEmpty() )
00187 return;
00188
00189 QPtrListIterator<QListViewItem> it( selected );
00190 QPtrList<partNode> parts;
00191 while ( it.current() ) {
00192 parts.append( static_cast<KMMimePartTreeItem *>(it.current())->node() );
00193 ++it;
00194 }
00195 mReaderWin->setUpdateAttachment();
00196 KMSaveAttachmentsCommand *command =
00197 new KMSaveAttachmentsCommand( this, parts, mReaderWin->message(), encoded );
00198 command->start();
00199 }
00200
00201
00202 void KMMimePartTree::slotSaveAll()
00203 {
00204 if( childCount() == 0)
00205 return;
00206
00207 mReaderWin->setUpdateAttachment();
00208 KMCommand *command =
00209 new KMSaveAttachmentsCommand( this, mReaderWin->message() );
00210 command->start();
00211 }
00212
00213
00214 void KMMimePartTree::setStyleDependantFrameWidth()
00215 {
00216
00217 int frameWidth;
00218 if( style().isA("KeramikStyle") )
00219 frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth ) - 1;
00220 else
00221 frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth );
00222 if ( frameWidth < 0 )
00223 frameWidth = 0;
00224 if ( frameWidth != lineWidth() )
00225 setLineWidth( frameWidth );
00226 }
00227
00228
00229
00230 void KMMimePartTree::styleChange( QStyle& oldStyle )
00231 {
00232 setStyleDependantFrameWidth();
00233 KListView::styleChange( oldStyle );
00234 }
00235
00236
00237 void KMMimePartTree::correctSize( QListViewItem * item )
00238 {
00239 if (!item) return;
00240
00241 KIO::filesize_t totalSize = 0;
00242 QListViewItem * myChild = item->firstChild();
00243 while ( myChild )
00244 {
00245 totalSize += static_cast<KMMimePartTreeItem*>(myChild)->origSize();
00246 myChild = myChild->nextSibling();
00247 }
00248 if ( totalSize > static_cast<KMMimePartTreeItem*>(item)->origSize() )
00249 item->setText( mSizeColumn, KIO::convertSize(totalSize) );
00250 if ( item->parent() )
00251 correctSize( item->parent() );
00252 }
00253
00254 void KMMimePartTree::slotDelete()
00255 {
00256 QPtrList<QListViewItem> selected = selectedItems();
00257 if ( selected.count() != 1 )
00258 return;
00259 mReaderWin->slotDeleteAttachment( static_cast<KMMimePartTreeItem*>( selected.first() )->node() );
00260 }
00261
00262 void KMMimePartTree::slotEdit()
00263 {
00264 QPtrList<QListViewItem> selected = selectedItems();
00265 if ( selected.count() != 1 )
00266 return;
00267 mReaderWin->slotEditAttachment( static_cast<KMMimePartTreeItem*>( selected.first() )->node() );
00268 }
00269
00270 void KMMimePartTree::slotOpen()
00271 {
00272 startHandleAttachmentCommand( KMHandleAttachmentCommand::Open );
00273 }
00274
00275 void KMMimePartTree::slotOpenWith()
00276 {
00277 startHandleAttachmentCommand( KMHandleAttachmentCommand::OpenWith );
00278 }
00279
00280 void KMMimePartTree::slotView()
00281 {
00282 startHandleAttachmentCommand( KMHandleAttachmentCommand::View );
00283 }
00284
00285 void KMMimePartTree::slotProperties()
00286 {
00287 startHandleAttachmentCommand( KMHandleAttachmentCommand::Properties );
00288 }
00289
00290 void KMMimePartTree::startHandleAttachmentCommand(int type)
00291 {
00292 QPtrList<QListViewItem> selected = selectedItems();
00293 if ( selected.count() != 1 )
00294 return;
00295 partNode* node = static_cast<KMMimePartTreeItem*>( selected.first() )->node();
00296 QString name = mReaderWin->tempFileUrlFromPartNode( node ).path();
00297 KMHandleAttachmentCommand* command = new KMHandleAttachmentCommand(
00298 node, mReaderWin->message(), node->nodeId(), name,
00299 KMHandleAttachmentCommand::AttachmentAction( type ), 0, this );
00300 connect( command, SIGNAL( showAttachment( int, const QString& ) ),
00301 mReaderWin, SLOT( slotAtmView( int, const QString& ) ) );
00302 command->start();
00303 }
00304
00305 void KMMimePartTree::slotCopy()
00306 {
00307 KURL::List urls;
00308 KMMimePartTreeItem *item = static_cast<KMMimePartTreeItem*>( currentItem() );
00309 if ( !item ) return;
00310 KURL url = mReaderWin->tempFileUrlFromPartNode( item->node() );
00311 if ( !url.isValid() ) return;
00312 urls.append( url );
00313 KURLDrag* drag = new KURLDrag( urls, this );
00314 QApplication::clipboard()->setData( drag, QClipboard::Clipboard );
00315 }
00316
00317
00318 KMMimePartTreeItem::KMMimePartTreeItem( KMMimePartTree * parent,
00319 partNode* node,
00320 const QString & description,
00321 const QString & mimetype,
00322 const QString & encoding,
00323 KIO::filesize_t size )
00324 : QListViewItem( parent, description,
00325 QString::null,
00326 encoding,
00327 KIO::convertSize( size ) ),
00328 mPartNode( node ), mOrigSize(size)
00329 {
00330 if( node )
00331 node->setMimePartTreeItem( this );
00332 setIconAndTextForType( mimetype );
00333 if ( parent )
00334 parent->correctSize(this);
00335 }
00336
00337 KMMimePartTreeItem::KMMimePartTreeItem( KMMimePartTreeItem * parent,
00338 partNode* node,
00339 const QString & description,
00340 const QString & mimetype,
00341 const QString & encoding,
00342 KIO::filesize_t size,
00343 bool revertOrder )
00344 : QListViewItem( parent, description,
00345 QString::null,
00346 encoding,
00347 KIO::convertSize( size ) ),
00348 mPartNode( node ), mOrigSize(size)
00349 {
00350 if( revertOrder && nextSibling() ){
00351 QListViewItem* sib = nextSibling();
00352 while( sib->nextSibling() )
00353 sib = sib->nextSibling();
00354 moveItem( sib );
00355 }
00356 if( node )
00357 node->setMimePartTreeItem( this );
00358 setIconAndTextForType( mimetype );
00359 if ( listView() )
00360 static_cast<KMMimePartTree*>(listView())->correctSize(this);
00361 }
00362
00363 void KMMimePartTreeItem::setIconAndTextForType( const QString & mime )
00364 {
00365 QString mimetype = mime.lower();
00366 if ( mimetype.startsWith( "multipart/" ) ) {
00367 setText( 1, mimetype );
00368 setPixmap( 0, SmallIcon("folder") );
00369 } else if ( mimetype == "application/octet-stream" ) {
00370 setText( 1, i18n("Unspecified Binary Data") );
00371 setPixmap( 0, SmallIcon("unknown") );
00372 } else {
00373 KMimeType::Ptr mtp = KMimeType::mimeType( mimetype );
00374 setText( 1, (mtp && !mtp->comment().isEmpty()) ? mtp->comment() : mimetype );
00375 setPixmap( 0, mtp ? mtp->pixmap( KIcon::Small) : SmallIcon("unknown") );
00376 }
00377 }
00378
00379
00380 void KMMimePartTree::startDrag()
00381 {
00382 KURL::List urls;
00383 KMMimePartTreeItem *item = static_cast<KMMimePartTreeItem*>( currentItem() );
00384 if ( !item ) return;
00385 partNode *node = item->node();
00386 if ( !node ) return;
00387 KURL url = mReaderWin->tempFileUrlFromPartNode( node );
00388 if (!url.isValid() ) return;
00389 urls.append( url );
00390 KURLDrag* drag = new KURLDrag( urls, this );
00391 drag->drag();
00392 }
00393
00394 #include "kmmimeparttree.moc"
00395