kmail

kmmimeparttree.cpp

00001 /* -*- c++ -*-
00002     kmmimeparttree.h A MIME part tree viwer.
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (c) 2002-2004 Klarälvdalens Datakonsult AB
00006 
00007     KMail is free software; you can redistribute it and/or modify it
00008     under the terms of the GNU General Public License, version 2, as
00009     published by the Free Software Foundation.
00010 
00011     KMail is distributed in the hope that it will be useful, but
00012     WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020     In addition, as a special exception, the copyright holders give
00021     permission to link the code of this program with any edition of
00022     the Qt library by Trolltech AS, Norway (or with modified versions
00023     of Qt that use the same license as Qt), and distribute linked
00024     combinations including the two.  You must obey the GNU General
00025     Public License in all respects for all of the code used other than
00026     Qt.  If you modify this file, you may extend this exception to
00027     your version of the file, but you are not obligated to do so.  If
00028     you do not wish to do so, delete this exception statement from
00029     your version.
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 <qheader.h>
00050 #include <qpopupmenu.h>
00051 #include <qstyle.h>
00052 
00053 KMMimePartTree::KMMimePartTree( KMReaderWin* readerWin,
00054                                 QWidget* parent,
00055                                 const char* name )
00056     : KListView(  parent, name ),
00057       mReaderWin( readerWin ), mSizeColumn(0)
00058 {
00059     setStyleDependantFrameWidth();
00060     addColumn( i18n("Description") );
00061     addColumn( i18n("Type") );
00062     addColumn( i18n("Encoding") );
00063     mSizeColumn = addColumn( i18n("Size") );
00064     setColumnAlignment( 3, Qt::AlignRight );
00065 
00066     restoreLayoutIfPresent();
00067     connect( this, SIGNAL( clicked( QListViewItem* ) ),
00068              this, SLOT( itemClicked( QListViewItem* ) ) );
00069     connect( this, SIGNAL( contextMenuRequested( QListViewItem*,
00070                                                  const QPoint&, int ) ),
00071              this, SLOT( itemRightClicked( QListViewItem*, const QPoint& ) ) );
00072     setSelectionMode( QListView::Extended );
00073     setRootIsDecorated( false );
00074     setAllColumnsShowFocus( true );
00075     setShowToolTips( true );
00076     setSorting(-1);
00077 }
00078 
00079 
00080 static const char configGroup[] = "MimePartTree";
00081 
00082 KMMimePartTree::~KMMimePartTree() {
00083   saveLayout( KMKernel::config(), configGroup );
00084 }
00085 
00086 
00087 void KMMimePartTree::restoreLayoutIfPresent() {
00088   // first column: soaks up the rest of the space:
00089   setColumnWidthMode( 0, Manual );
00090   header()->setStretchEnabled( true, 0 );
00091   // rest of the columns:
00092   if ( KMKernel::config()->hasGroup( configGroup ) ) {
00093     // there is a saved layout. use it...
00094     restoreLayout( KMKernel::config(), configGroup );
00095     // and disable Maximum mode:
00096     for ( int i = 1 ; i < 4 ; ++i )
00097       setColumnWidthMode( i, Manual );
00098   } else {
00099     // columns grow with their contents:
00100     for ( int i = 1 ; i < 4 ; ++i )
00101       setColumnWidthMode( i, Maximum );
00102   }
00103 }
00104 
00105 
00106 void KMMimePartTree::itemClicked( QListViewItem* item )
00107 {
00108   if ( const KMMimePartTreeItem * i = dynamic_cast<KMMimePartTreeItem*>( item ) ) {
00109     if( mReaderWin->mRootNode == i->node() )
00110       mReaderWin->update( true ); // Force update
00111     else
00112       mReaderWin->setMsgPart( i->node() );
00113   } else
00114     kdWarning(5006) << "Item was not a KMMimePartTreeItem!" << endl;
00115 }
00116 
00117 
00118 void KMMimePartTree::itemRightClicked( QListViewItem* item,
00119                                        const QPoint& point )
00120 {
00121     // TODO: remove this member var?
00122     mCurrentContextMenuItem = dynamic_cast<KMMimePartTreeItem*>( item );
00123     if ( 0 == mCurrentContextMenuItem ) {
00124         kdDebug(5006) << "Item was not a KMMimePartTreeItem!" << endl;
00125     }
00126     else {
00127         kdDebug(5006) << "\n**\n** KMMimePartTree::itemRightClicked() **\n**" << endl;
00128 
00129         QPopupMenu* popup = new QPopupMenu;
00130         popup->insertItem( SmallIcon("filesaveas"),i18n( "Save &As..." ), this, SLOT( slotSaveAs() ) );
00131         popup->insertItem( i18n( "Save as &Encoded..." ), this,
00132                            SLOT( slotSaveAsEncoded() ) );
00133         popup->insertItem( i18n( "Save All Attachments..." ), this,
00134                            SLOT( slotSaveAll() ) );
00135         popup->exec( point );
00136         delete popup;
00137         mCurrentContextMenuItem = 0;
00138     }
00139 }
00140 
00141 //-----------------------------------------------------------------------------
00142 void KMMimePartTree::slotSaveAs()
00143 {
00144   saveSelectedBodyParts( false );
00145 }
00146 
00147 //-----------------------------------------------------------------------------
00148 void KMMimePartTree::slotSaveAsEncoded()
00149 {
00150   saveSelectedBodyParts( true );
00151 }
00152 
00153 //-----------------------------------------------------------------------------
00154 void KMMimePartTree::saveSelectedBodyParts( bool encoded )
00155 {
00156   QPtrList<QListViewItem> selected = selectedItems();
00157 
00158   Q_ASSERT( !selected.isEmpty() );
00159   if ( selected.isEmpty() )
00160     return;
00161 
00162   QPtrListIterator<QListViewItem> it( selected );
00163   QPtrList<partNode> parts;
00164   while ( it.current() ) {
00165     parts.append( static_cast<KMMimePartTreeItem *>(it.current())->node() );
00166     ++it;
00167   }
00168   mReaderWin->setUpdateAttachment();
00169   KMSaveAttachmentsCommand *command =
00170     new KMSaveAttachmentsCommand( this, parts, mReaderWin->message(), encoded );
00171   command->start();
00172 }
00173 
00174 //-----------------------------------------------------------------------------
00175 void KMMimePartTree::slotSaveAll()
00176 {
00177     if( childCount() == 0)
00178         return;
00179 
00180     mReaderWin->setUpdateAttachment();
00181     KMCommand *command =
00182       new KMSaveAttachmentsCommand( this, mReaderWin->message() );
00183     command->start();
00184 }
00185 
00186 //-----------------------------------------------------------------------------
00187 void KMMimePartTree::setStyleDependantFrameWidth()
00188 {
00189   // set the width of the frame to a reasonable value for the current GUI style
00190   int frameWidth;
00191   if( style().isA("KeramikStyle") )
00192     frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth ) - 1;
00193   else
00194     frameWidth = style().pixelMetric( QStyle::PM_DefaultFrameWidth );
00195   if ( frameWidth < 0 )
00196     frameWidth = 0;
00197   if ( frameWidth != lineWidth() )
00198     setLineWidth( frameWidth );
00199 }
00200 
00201 
00202 //-----------------------------------------------------------------------------
00203 void KMMimePartTree::styleChange( QStyle& oldStyle )
00204 {
00205   setStyleDependantFrameWidth();
00206   KListView::styleChange( oldStyle );
00207 }
00208 
00209 //-----------------------------------------------------------------------------
00210 void KMMimePartTree::correctSize( QListViewItem * item )
00211 {
00212   if (!item) return;
00213 
00214   KIO::filesize_t totalSize = 0;
00215   QListViewItem * myChild = item->firstChild();
00216   while ( myChild )
00217   {
00218     totalSize += static_cast<KMMimePartTreeItem*>(myChild)->origSize();
00219     myChild = myChild->nextSibling();
00220   }
00221   if ( totalSize > static_cast<KMMimePartTreeItem*>(item)->origSize() )
00222     item->setText( mSizeColumn, KIO::convertSize(totalSize) );
00223   if ( item->parent() )
00224     correctSize( item->parent() );
00225 }
00226 
00227 //=============================================================================
00228 KMMimePartTreeItem::KMMimePartTreeItem( KMMimePartTree * parent,
00229                                         partNode* node,
00230                                         const QString & description,
00231                                         const QString & mimetype,
00232                                         const QString & encoding,
00233                                         KIO::filesize_t size )
00234   : QListViewItem( parent, description,
00235            QString::null, // set by setIconAndTextForType()
00236            encoding,
00237            KIO::convertSize( size ) ),
00238     mPartNode( node ), mOrigSize(size)
00239 {
00240   if( node )
00241     node->setMimePartTreeItem( this );
00242   setIconAndTextForType( mimetype );
00243   if ( parent )
00244     parent->correctSize(this);
00245 }
00246 
00247 KMMimePartTreeItem::KMMimePartTreeItem( KMMimePartTreeItem * parent,
00248                                         partNode* node,
00249                                         const QString & description,
00250                                         const QString & mimetype,
00251                                         const QString & encoding,
00252                                         KIO::filesize_t size,
00253                                         bool revertOrder )
00254   : QListViewItem( parent, description,
00255            QString::null, // set by setIconAndTextForType()
00256            encoding,
00257            KIO::convertSize( size ) ),
00258     mPartNode( node ), mOrigSize(size)
00259 {
00260   if( revertOrder && nextSibling() ){
00261     QListViewItem* sib = nextSibling();
00262     while( sib->nextSibling() )
00263       sib = sib->nextSibling();
00264     moveItem( sib );
00265   }
00266   if( node )
00267     node->setMimePartTreeItem( this );
00268   setIconAndTextForType( mimetype );
00269   if ( listView() )
00270     static_cast<KMMimePartTree*>(listView())->correctSize(this);
00271 }
00272 
00273 void KMMimePartTreeItem::setIconAndTextForType( const QString & mime )
00274 {
00275   QString mimetype = mime.lower();
00276   if ( mimetype.startsWith( "multipart/" ) ) {
00277     setText( 1, mimetype );
00278     setPixmap( 0, SmallIcon("folder") );
00279   } else if ( mimetype == "application/octet-stream" ) {
00280     setText( 1, i18n("Unspecified Binary Data") ); // don't show "Unknown"...
00281     setPixmap( 0, SmallIcon("unknown") );
00282   } else {
00283     KMimeType::Ptr mtp = KMimeType::mimeType( mimetype );
00284     setText( 1, (mtp && !mtp->comment().isEmpty()) ? mtp->comment() : mimetype );
00285     setPixmap( 0, mtp ? mtp->pixmap( KIcon::Small) : SmallIcon("unknown") );
00286   }
00287 }
00288 
00289 
00290 #include "kmmimeparttree.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys