kmail

attachmentstrategy.cpp
00001 /*  -*- c++ -*-
00002     attachmentstrategy.cpp
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (c) 2003 Marc Mutz <mutz@kde.org>
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 TQt library by Trolltech AS, Norway (or with modified versions
00023     of TQt that use the same license as TQt), 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     TQt.  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 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include "attachmentstrategy.h"
00037 
00038 #include "partNode.h"
00039 #include "kmmsgpart.h"
00040 
00041 #include <tqstring.h>
00042 
00043 #include <kdebug.h>
00044 
00045 
00046 namespace KMail {
00047 
00048 static AttachmentStrategy::Display smartDisplay( const partNode *node )
00049 {
00050   if ( node->hasContentDispositionInline() )
00051     // explict "inline" disposition:
00052     return AttachmentStrategy::Inline;
00053   if ( node->isAttachment() )
00054     // explicit "attachment" disposition:
00055     return AttachmentStrategy::AsIcon;
00056   if ( node->type() == DwMime::kTypeText &&
00057        node->msgPart().fileName().stripWhiteSpace().isEmpty() &&
00058        node->msgPart().name().stripWhiteSpace().isEmpty() )
00059     // text/* w/o filename parameter:
00060     return AttachmentStrategy::Inline;
00061   return AttachmentStrategy::AsIcon;
00062 }
00063 
00064   //
00065   // IconicAttachmentStrategy:
00066   //   show everything but the first text/plain body as icons
00067   //
00068 
00069   class IconicAttachmentStrategy : public AttachmentStrategy {
00070     friend class ::KMail::AttachmentStrategy;
00071   protected:
00072     IconicAttachmentStrategy() : AttachmentStrategy() {}
00073     virtual ~IconicAttachmentStrategy() {}
00074     
00075   public:
00076     const char * name() const { return "iconic"; }
00077     const AttachmentStrategy * next() const { return smart(); }
00078     const AttachmentStrategy * prev() const { return headerOnly(); }
00079 
00080     bool inlineNestedMessages() const { return false; }
00081     Display defaultDisplay( const partNode * ) const { return AsIcon; }
00082   };
00083 
00084   //
00085   // SmartAttachmentStrategy:
00086   //   in addition to Iconic, show all body parts
00087   //   with content-disposition == "inline" and
00088   //   all text parts without a filename or name parameter inline
00089   //
00090 
00091   class SmartAttachmentStrategy : public AttachmentStrategy {
00092     friend class ::KMail::AttachmentStrategy;
00093   protected:
00094     SmartAttachmentStrategy() : AttachmentStrategy() {}
00095     virtual ~SmartAttachmentStrategy() {}
00096     
00097   public:
00098     const char * name() const { return "smart"; }
00099     const AttachmentStrategy * next() const { return inlined(); }
00100     const AttachmentStrategy * prev() const { return iconic(); }
00101 
00102     bool inlineNestedMessages() const { return true; }
00103     Display defaultDisplay( const partNode * node ) const {
00104       return smartDisplay( node );
00105     }
00106   };
00107 
00108   //
00109   // InlinedAttachmentStrategy:
00110   //   show everything possible inline
00111   //
00112 
00113   class InlinedAttachmentStrategy : public AttachmentStrategy {
00114     friend class ::KMail::AttachmentStrategy;
00115   protected:
00116     InlinedAttachmentStrategy() : AttachmentStrategy() {}
00117     virtual ~InlinedAttachmentStrategy() {}
00118     
00119   public:
00120     const char * name() const { return "inlined"; }
00121     const AttachmentStrategy * next() const { return hidden(); }
00122     const AttachmentStrategy * prev() const { return smart(); }
00123 
00124     bool inlineNestedMessages() const { return true; }
00125     Display defaultDisplay( const partNode * ) const { return Inline; }
00126   };
00127 
00128   //
00129   // HiddenAttachmentStrategy
00130   //   show nothing except the first text/plain body part _at all_
00131   //
00132 
00133   class HiddenAttachmentStrategy : public AttachmentStrategy {
00134     friend class ::KMail::AttachmentStrategy;
00135   protected:
00136     HiddenAttachmentStrategy() : AttachmentStrategy() {}
00137     virtual ~HiddenAttachmentStrategy() {}
00138     
00139   public:
00140     const char * name() const { return "hidden"; }
00141     const AttachmentStrategy * next() const { return headerOnly(); }
00142     const AttachmentStrategy * prev() const { return inlined(); }
00143 
00144     bool inlineNestedMessages() const { return false; }
00145     Display defaultDisplay( const partNode * ) const { return None; }
00146   };
00147 
00148   class HeaderOnlyAttachmentStrategy : public AttachmentStrategy {
00149     friend class ::KMail::AttachmentStrategy;
00150   protected:
00151     HeaderOnlyAttachmentStrategy() : AttachmentStrategy() {}
00152     virtual ~HeaderOnlyAttachmentStrategy() {}
00153 
00154   public:
00155     const char * name() const { return "headerOnly"; }
00156     const AttachmentStrategy * next() const { return iconic(); }
00157     const AttachmentStrategy * prev() const { return hidden(); }
00158 
00159     bool inlineNestedMessages() const {
00160       return true;
00161     }
00162 
00163     Display defaultDisplay( const partNode *node ) const {
00164       if ( node->isInEncapsulatedMessage() ) {
00165         return smartDisplay( node );
00166       }
00167 
00168       partNode::AttachmentDisplayInfo info = node->attachmentDisplayInfo();
00169       if ( info.displayInHeader ) {
00170         // The entire point about this attachment strategy: Hide attachments in the body that are
00171         // already displayed in the attachment quick list
00172         return None;
00173       } else {
00174         return smartDisplay( node );
00175       }
00176     }
00177   };
00178 
00179 
00180 
00181   //
00182   // AttachmentStrategy abstract base:
00183   //
00184 
00185   AttachmentStrategy::AttachmentStrategy() {
00186 
00187   }
00188 
00189   AttachmentStrategy::~AttachmentStrategy() {
00190 
00191   }
00192 
00193   const AttachmentStrategy * AttachmentStrategy::create( Type type ) {
00194     switch ( type ) {
00195     case Iconic:     return iconic();
00196     case Smart:      return smart();
00197     case Inlined:    return inlined();
00198     case Hidden:     return hidden();
00199     case HeaderOnly: return headerOnly();
00200     }
00201     kdFatal( 5006 ) << "AttachmentStrategy::create(): Unknown attachment startegy ( type == "
00202             << (int)type << " ) requested!" << endl;
00203     return 0; // make compiler happy
00204   }
00205 
00206   const AttachmentStrategy * AttachmentStrategy::create( const TQString & type ) {
00207     TQString lowerType = type.lower();
00208     if ( lowerType == "iconic" )     return iconic();
00209     //if ( lowerType == "smart" )   return smart(); // not needed, see below
00210     if ( lowerType == "inlined" )    return inlined();
00211     if ( lowerType == "hidden" )     return hidden();
00212     if ( lowerType == "headeronly" ) return headerOnly();
00213     // don't kdFatal here, b/c the strings are user-provided
00214     // (KConfig), so fail gracefully to the default:
00215     return smart();
00216   }
00217 
00218   static const AttachmentStrategy * iconicStrategy = 0;
00219   static const AttachmentStrategy * smartStrategy = 0;
00220   static const AttachmentStrategy * inlinedStrategy = 0;
00221   static const AttachmentStrategy * hiddenStrategy = 0;
00222   static const AttachmentStrategy * headerOnlyStrategy = 0;
00223 
00224   const AttachmentStrategy * AttachmentStrategy::iconic() {
00225     if ( !iconicStrategy )
00226       iconicStrategy = new IconicAttachmentStrategy();
00227     return iconicStrategy;
00228   }
00229 
00230   const AttachmentStrategy * AttachmentStrategy::smart() {
00231     if ( !smartStrategy )
00232       smartStrategy = new SmartAttachmentStrategy();
00233     return smartStrategy;
00234   }
00235 
00236   const AttachmentStrategy * AttachmentStrategy::inlined() {
00237     if ( !inlinedStrategy )
00238       inlinedStrategy = new InlinedAttachmentStrategy();
00239     return inlinedStrategy;
00240   }
00241 
00242   const AttachmentStrategy * AttachmentStrategy::hidden() {
00243     if ( !hiddenStrategy )
00244       hiddenStrategy = new HiddenAttachmentStrategy();
00245     return hiddenStrategy;
00246   }
00247 
00248   const AttachmentStrategy * AttachmentStrategy::headerOnly() {
00249     if ( !headerOnlyStrategy )
00250       headerOnlyStrategy = new HeaderOnlyAttachmentStrategy();
00251     return headerOnlyStrategy;
00252   }
00253 
00254 } // namespace KMail