[prev in list] [next in list] [prev in thread] [next in thread]
List: kmail-devel
Subject: custom header view
From: Klas Kalass <klas.kalass () gmx ! de>
Date: 2003-08-29 23:28:31
[Download RAW message or body]
I made a patch to make the visible header fields in the reader configurable.
The patch is attached and screenshots can be found at
http://www.kalass.de/kmail/index.html
The patch works with the current headerstyle and headerstrategy classes by
providing an extra interface for editing functionality.
I was pleasantly surprised when looking at the code to implement this
functionality, because it is so neatly designed now.
A headerstyle needs to be able to provide the user with an interface for
editing the strategy, this functionality is exposed by HeaderStyleEditor. A
strategy needs to be editable. This is exposed by HeaderStrategyEditor.
The changes to headerstyle and headerstrategy interfaces consist only of
adding an accessor to an editor implementation, constness is not changed
anywhere.
I introduced a new Menu Item View->Headers->Custom to enable the custom header
style.
This is implemented by FancyHeaderStyle and CustomHeaderStrategy, both
enhanced to provide the additional editor functionality.
I renamed the original "format" method of FancyHeaderStyle to "legacyFormat"
to provide the same behaviour as before for non-editable strategies, but I
would recommend to always use FancyEditor::format, because that function
actually shows all headers that are defined visible by the strategy, in the
order defined by the strategy. The old implementation only shows header
fields it knows about.
The icons I used are just copies of existing icons, especially the hide and
show icons need to be changed to something better.
I hope that my patch gets accepted and if it does, I will fix any issues with
it, should there be any.
Regards,
Klas Kalass
["headerstyleeditor.h" (text/x-chdr)]
/* -*- c++ -*-
headerstyleeditor.h
This file is part of KMail, the KDE mail client.
Copyright (c) 2003 Klas Kalass <klas@kde.org>
KMail is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
KMail is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef __KMAIL_HEADERSTYLEEDITOR_H__
#define __KMAIL_HEADERSTYLEEDITOR_H__
#include <kurl.h>
#include <qmap.h>
#include <qstring.h>
class KMMessage;
namespace KMail {
class HeaderStrategy;
class HeaderStrategyEditor;
class HeaderStyle;
/** Encapsulate editing functionality for a HeaderStyle. A subclass
allows the user to edit the behaviour of a
@ref HeaderStrategy, if the strategy supplies editing functionality.
An editor works such that the user is supplied with hyperlinks
which he might follow to change a setting.
@short Encapsulates editing functionality for visual appearance
of message headers.
@author Klas Kalass <klas@kde.org>
@see HeaderStrategy
@see HeaderStyle
**/
class HeaderStyleEditor {
protected:
HeaderStyleEditor(){}
virtual ~HeaderStyleEditor(){}
public:
// The base url to use for an edit url (the url a user follows when
// selecting to change settings), the editor will supply and analyze
// a query string.
void setBaseUrl( const KURL & baseUrl ) { mBaseUrl = baseUrl; }
const KURL & baseUrl() const { return mBaseUrl; }
// call this url to enable the editor
void setUrlEnableEditor( const KURL & urlEnable ) { mUrlEnable = urlEnable; }
const KURL & urlEnableEditor() const { return mUrlEnable; }
// call this url to disable the editor
void setUrlDisableEditor( const KURL & urlDisable ) { mUrlDisable=urlDisable; }
const KURL & urlDisableEditor() const { return mUrlDisable; }
//
// HeaderStyle interface:
//
// format Header as editable header, hyperlinks that consist of baseUrl()
// plus a query string will be inserted for the user to change settings
virtual QString formatAsEditor( const KMMessage * message,
const KMail::HeaderStrategy * strategy,
const QString & vCardName,
bool printing=false ) const = 0;
// properties is a (key, value) map as given by the query string of
// the hyperlink as generated by @ref formatEditor . This method
// sets values in strategy->editor() as specified by the parameter
// properties
virtual void setProperties( const QMap< QString, QString > & properties,
const HeaderStrategy * strategy ) const = 0;
// access the associated view style
virtual const HeaderStyle * view() const = 0;
private:
KURL mBaseUrl;
KURL mUrlEnable;
KURL mUrlDisable;
};
} // namespace KMail
#endif // __KMAIL_HEADERSTYLEEDITOR_H__
["headerstrategyeditor.h" (text/x-chdr)]
/* -*- c++ -*-
headerstrategyeditor.h
This file is part of KMail, the KDE mail client.
Copyright (c) 2003 Klas Kalass <klas@kde.org>
KMail is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
KMail is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef __KMAIL_HEADERSTRATEGYEDITOR_H__
#define __KMAIL_HEADERSTRATEGYEDITOR_H__
#include <qstringlist.h>
#include "headerstrategy.h"
class QString;
class QStringList;
namespace KMail {
class HeaderStrategyEditor {
protected:
HeaderStrategyEditor() {}
virtual ~HeaderStrategyEditor() {}
public:
enum DisplayPolicy { Visible, Hidden, Default };
virtual void setDefaultPolicy( HeaderStrategy::DefaultPolicy policy ) = 0;
virtual void setPolicy( const QString & header,
DisplayPolicy displayPolicy,
int index = -1 ) = 0;
virtual const HeaderStrategy * strategy() const = 0;
};
} // namespace KMail
#endif // __KMAIL_HEADERSTRATEGYEDITOR_H__
["visible-headers.diff" (text/x-diff)]
? headerstrategyeditor.h
? headerstyleeditor.h
? klas.diff
? visible-headers.diff
? pics/.xvpics
? pics/kmheaderfielddown.png
? pics/kmheaderfielddown_inactive.png
? pics/kmheaderfieldhide.png
? pics/kmheaderfieldshow.png
? pics/kmheaderfieldup.png
? pics/kmheaderfieldup_inactive.png
? pics/lmheaderfieldshow.png
Index: headerstrategy.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/headerstrategy.cpp,v
retrieving revision 1.8
diff -u -3 -p -r1.8 headerstrategy.cpp
--- headerstrategy.cpp 26 Jul 2003 14:51:49 -0000 1.8
+++ headerstrategy.cpp 29 Aug 2003 22:24:42 -0000
@@ -3,6 +3,7 @@
This file is part of KMail, the KDE mail client.
Copyright (c) 2003 Marc Mutz <mutz@kde.org>
+ Copyright (c) 2003 Klas Kalass <klas@kde.org>
KMail is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
@@ -30,6 +31,7 @@
*/
#include "headerstrategy.h"
+#include "headerstrategyeditor.h"
#include "kmkernel.h"
@@ -49,19 +51,19 @@ namespace KMail {
static const char * standardHeaders[] = {
- "subject", "from", "cc", "bcc", "to",
+ "subject", "from", "to", "cc", "bcc", "date"
};
static const int numStandardHeaders = sizeof standardHeaders / sizeof \
*standardHeaders;
static const char * richHeaders[] = {
- "subject", "date", "from", "cc", "bcc", "to",
+ "subject", "from", "to", "cc", "bcc", "date",
"organization", "organisation", "reply-to"
};
static const int numRichHeaders = sizeof richHeaders / sizeof *richHeaders;
//
- // Convenience function
+ // Convenience functions
//
static QStringList stringList( const char * headers[], int numHeaders ) {
@@ -71,6 +73,23 @@ namespace KMail {
return sl;
}
+ static void insertItemIntoList( QStringList & stringList,
+ const QString & item,
+ int index ) {
+
+ // remove the header if it is in the list
+ if ( stringList.find( item ) != stringList.end() ) {
+ stringList.remove( item );
+ }
+
+ // append or insert, depending on the index
+ if ( index < 0 || index >= stringList.size() ) {
+ stringList.append( item );
+ } else {
+ stringList.insert( stringList.at( index ), item );
+ }
+ }
+
//
// AllHeaderStrategy:
// show everything
@@ -92,6 +111,8 @@ namespace KMail {
bool showHeader( const QString & ) const {
return true; // more efficient than default impl
}
+
+ HeaderStrategyEditor * editor() const { return 0; }
};
//
@@ -115,6 +136,7 @@ namespace KMail {
QStringList headersToDisplay() const { return mHeadersToDisplay; }
DefaultPolicy defaultPolicy() const { return Hide; }
+ HeaderStrategyEditor * editor() const { return 0; }
private:
const QStringList mHeadersToDisplay;
};
@@ -140,6 +162,7 @@ namespace KMail {
QStringList headersToDisplay() const { return mHeadersToDisplay; }
DefaultPolicy defaultPolicy() const { return Hide; }
+ HeaderStrategyEditor * editor() const { return 0; }
private:
const QStringList mHeadersToDisplay;
};
@@ -165,10 +188,42 @@ namespace KMail {
QStringList headersToDisplay() const { return mHeadersToDisplay; }
DefaultPolicy defaultPolicy() const { return Hide; }
+ HeaderStrategyEditor * editor() const { return 0; }
private:
const QStringList mHeadersToDisplay;
};
+ //
+ // CustomEditableStrategy Declaration
+ // User-editable Strategy, used by CustomHeaderStrategy as backend
+ //
+
+ class CustomHeaderStrategy;
+ class CustomEditableStrategy : public HeaderStrategyEditor {
+ friend class CustomHeaderStrategy;
+ protected:
+ CustomEditableStrategy( CustomHeaderStrategy *strategy );
+ virtual ~CustomEditableStrategy() {}
+
+ public:
+ QStringList headersToDisplay() const { return mHeadersToDisplay; }
+ QStringList headersToHide() const { return mHeadersToHide; }
+ HeaderStrategy::DefaultPolicy defaultPolicy() const {
+ return mDefaultPolicy;
+ }
+
+ // editor interface
+ void setDefaultPolicy( HeaderStrategy::DefaultPolicy policy );
+ void setPolicy( const QString & header, DisplayPolicy displayPolicy,
+ int index );
+ const HeaderStrategy * strategy() const;
+
+ private:
+ QStringList mHeadersToDisplay;
+ QStringList mHeadersToHide;
+ HeaderStrategy::DefaultPolicy mDefaultPolicy;
+ CustomHeaderStrategy *mStrategy;
+ };
//
// CustomHeaderStrategy
@@ -186,35 +241,97 @@ namespace KMail {
const HeaderStrategy * next() const { return all(); }
const HeaderStrategy * prev() const { return brief(); }
- QStringList headersToDisplay() const { return mHeadersToDisplay; }
- QStringList headersToHide() const { return mHeadersToHide; }
- DefaultPolicy defaultPolicy() const { return mDefaultPolicy; }
+ QStringList headersToDisplay() const { return impl->headersToDisplay(); }
+ QStringList headersToHide() const { return impl->headersToHide(); }
+ DefaultPolicy defaultPolicy() const { return impl->defaultPolicy(); }
+
+ HeaderStrategyEditor * editor() const { return impl; }
private:
- QStringList mHeadersToDisplay;
- QStringList mHeadersToHide;
- DefaultPolicy mDefaultPolicy;
+ CustomEditableStrategy * impl;
};
-
CustomHeaderStrategy::CustomHeaderStrategy()
- : HeaderStrategy()
+ : HeaderStrategy()
{
+ impl = new CustomEditableStrategy(this);
+ }
+
+ //
+ // CustomEditableStrategy Implementation
+ //
+
+ CustomEditableStrategy::CustomEditableStrategy( CustomHeaderStrategy *strategy ) {
+ mStrategy = strategy;
KConfigGroup customHeader( KMKernel::config(), "Custom Headers" );
+
+ // headers to display
if ( customHeader.hasKey( "headers to display" ) ) {
mHeadersToDisplay = customHeader.readListEntry( "headers to display" );
- for ( QStringList::iterator it = mHeadersToDisplay.begin() ; it != \
mHeadersToDisplay.end() ; ++ it )
- *it = (*it).lower();
- } else
+ for ( QStringList::iterator it = mHeadersToDisplay.begin() ;
+ it != mHeadersToDisplay.end() ; ++ it ) {
+ *it = (*it).lower();
+ }
+ } else {
mHeadersToDisplay = stringList( standardHeaders, numStandardHeaders );
+ }
+ // headers to hide
if ( customHeader.hasKey( "headers to hide" ) ) {
mHeadersToHide = customHeader.readListEntry( "headers to hide" );
- for ( QStringList::iterator it = mHeadersToHide.begin() ; it != \
mHeadersToHide.end() ; ++ it )
- *it = (*it).lower();
+ for ( QStringList::iterator it = mHeadersToHide.begin() ;
+ it != mHeadersToHide.end() ; ++ it ) {
+ *it = (*it).lower();
+ }
+ }
+
+ // default policy
+ mDefaultPolicy =
+ customHeader.readEntry( "default policy", "hide" ) == "display"
+ ? HeaderStrategy::Display
+ : HeaderStrategy::Hide;
+
+ }
+
+ const HeaderStrategy * CustomEditableStrategy::strategy() const {
+ return mStrategy;
+ }
+
+ void CustomEditableStrategy::setDefaultPolicy( HeaderStrategy::DefaultPolicy \
policy ) { + KConfigGroup customHeader( KMKernel::config(), "Custom Headers" );
+ mDefaultPolicy = policy;
+
+ customHeader.writeEntry( "default policy",
+ mDefaultPolicy == HeaderStrategy::Display
+ ? "display"
+ : "hide" );
+ }
+
+ void CustomEditableStrategy::setPolicy ( const QString & header,
+ DisplayPolicy displayPolicy,
+ int index) {
+ QString h ( header.lower() );
+
+ // Show Header
+ if (displayPolicy == Visible) {
+ mHeadersToHide.remove( h );
+ insertItemIntoList( mHeadersToDisplay, h, index );
+
+ // Hide Header
+ } else if ( displayPolicy == Hidden ) {
+ mHeadersToDisplay.remove( h );
+ insertItemIntoList( mHeadersToHide, h, index );
+
+ // apply default behaviour
+ } else {
+ mHeadersToDisplay.remove( h );
+ mHeadersToHide.remove( h );
}
- mDefaultPolicy = customHeader.readEntry( "default policy", "hide" ) == "display" \
? Display : Hide ; + // store the configuration settings
+ KConfigGroup customHeaders( KMKernel::config(), "Custom Headers" );
+ customHeaders.writeEntry( "headers to display", mHeadersToDisplay );
+ customHeaders.writeEntry( "headers to hide", mHeadersToHide );
}
//
Index: headerstrategy.h
===================================================================
RCS file: /home/kde/kdepim/kmail/headerstrategy.h,v
retrieving revision 1.3
diff -u -3 -p -r1.3 headerstrategy.h
--- headerstrategy.h 26 Jul 2003 14:51:49 -0000 1.3
+++ headerstrategy.h 29 Aug 2003 22:24:42 -0000
@@ -36,6 +36,7 @@ class QString;
class QStringList;
namespace KMail {
+ class HeaderStrategyEditor;
class HeaderStrategy {
protected:
@@ -73,6 +74,7 @@ namespace KMail {
virtual QStringList headersToHide() const;
virtual DefaultPolicy defaultPolicy() const = 0;
virtual bool showHeader( const QString & header ) const;
+ virtual HeaderStrategyEditor * editor() const = 0;
};
} // namespace KMail
Index: headerstyle.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/headerstyle.cpp,v
retrieving revision 1.9
diff -u -3 -p -r1.9 headerstyle.cpp
--- headerstyle.cpp 26 Jul 2003 14:51:49 -0000 1.9
+++ headerstyle.cpp 29 Aug 2003 22:24:42 -0000
@@ -3,6 +3,7 @@
This file is part of KMail, the KDE mail client.
Copyright (c) 2003 Marc Mutz <mutz@kde.org>
+ Copyright (c) 2003 Klas Kalass <klas@kde.org>
KMail is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2, as
@@ -30,8 +31,10 @@
*/
#include "headerstyle.h"
+#include "headerstyleeditor.h"
#include "headerstrategy.h"
+#include "headerstrategyeditor.h"
#include "linklocator.h"
#include "kmmessage.h"
@@ -43,10 +46,16 @@
#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
+#include <kicontheme.h>
+#include <kiconloader.h>
+#include <kdialog.h>
#include <qdatetime.h>
#include <qapplication.h>
#include <qregexp.h>
+#include <qptrlist.h>
+#include <qmap.h>
+#include <qvaluelist.h>
namespace KMail {
@@ -94,6 +103,7 @@ namespace KMail {
QString format( const KMMessage * message, const HeaderStrategy * strategy,
const QString & vCardName, bool printing ) const;
+ HeaderStyleEditor * editor() const { return 0; }
};
QString BriefHeaderStyle::format( const KMMessage * message,
@@ -186,7 +196,7 @@ namespace KMail {
QString format( const KMMessage * message, const HeaderStrategy * strategy,
const QString & vCardName, bool printing ) const;
-
+ HeaderStyleEditor * editor() const { return 0; }
private:
QString formatAllMessageHeaders( const KMMessage * message ) const;
};
@@ -293,6 +303,65 @@ namespace KMail {
}
//
+ // FancyEditor: (Declaration)
+ // Backend for FancyHeaderStyle and Editor
+ //
+
+ /** @author klas@kde.org */
+ class FancyEditor : public HeaderStyleEditor {
+ friend class FancyHeaderStyle;
+
+ protected:
+ typedef QMap< QString, QPtrList< DwField > > FieldListMap;
+
+ FancyEditor( const HeaderStyle * view )
+ : HeaderStyleEditor(), mView(view) {}
+ virtual ~FancyEditor() {}
+
+ QString generateEditHtml( const HeaderStrategy * strategy,
+ QString header,
+ HeaderStrategyEditor::DisplayPolicy visibility,
+ bool isFirst, bool isLast ) const;
+
+ QString formatField( QString prependString,
+ int prependStringColumnWidth,
+ QString header,
+ QPtrList<DwField> & fields,
+ const KMMessage * message,
+ const QString & vCardName, bool printing ) const;
+
+ void categorizeFields( const QStringList & headersToDisplay,
+ const QStringList & headersToHide,
+ const DwHeaders & availableHeaders,
+ FieldListMap & visibleHeaderFields,
+ FieldListMap & hiddenHeaderFields,
+ FieldListMap & newHeaderFields ) const ;
+
+ QString prepareHeader( const KMMessage * message, bool showSubject ) const;
+
+ QString closeHeader( const KMMessage * message ) const;
+
+ public:
+ // simple formatting for viewing only
+ QString format( const KMMessage * message,
+ const HeaderStrategy * strategy,
+ const QString & vCardName, bool printing ) const;
+
+ // formatting as editable header
+ QString formatAsEditor( const KMMessage * message,
+ const HeaderStrategy * strategy,
+ const QString & vCardName, bool printing ) const;
+
+ void setProperties( const QMap< QString, QString > & properties,
+ const HeaderStrategy * strategy ) const;
+
+ HeaderStyle const * view() const { return mView; }
+
+ private:
+ HeaderStyle const * mView;
+ };
+
+ //
// FancyHeaderStyle:
// Like PlainHeaderStyle, but with slick frames and background colours.
//
@@ -300,21 +369,57 @@ namespace KMail {
class FancyHeaderStyle : public HeaderStyle {
friend class HeaderStyle;
protected:
- FancyHeaderStyle() : HeaderStyle() {}
+ FancyHeaderStyle() : HeaderStyle(),
+ mEditor(0) {}
virtual ~FancyHeaderStyle() {}
+ QString legacyFormat( const KMMessage * message,
+ const HeaderStrategy * strategy,
+ const QString & vCardName, bool printing ) const;
public:
const char * name() const { return "fancy"; }
const HeaderStyle * next() const { return brief(); }
const HeaderStyle * prev() const { return plain(); }
- QString format( const KMMessage * message, const HeaderStrategy * strategy,
+ QString format( const KMMessage * message,
+ const HeaderStrategy * strategy,
const QString & vCardName, bool printing ) const;
+ HeaderStyleEditor * editor() const;
+
+ private:
+ FancyEditor * fancyeditor() const;
+ mutable FancyEditor * mEditor;
};
+
+ HeaderStyleEditor * FancyHeaderStyle::editor() const{
+ return fancyeditor();
+ }
+
+ FancyEditor * FancyHeaderStyle::fancyeditor() const{
+ if (mEditor == 0)
+ mEditor = new FancyEditor(this);
+ return mEditor;
+ }
+
QString FancyHeaderStyle::format( const KMMessage * message,
const HeaderStrategy * strategy,
const QString & vCardName, bool printing ) const {
+
+ if ( strategy->editor() )
+ return fancyeditor()->format( message, strategy, vCardName, printing );
+
+ // this is only for compatibility, really. IMHO the fancyeditor() should
+ // be used for rendering always, because it actually renders all headers
+ // specified by the strategy and not only the ones known by the style,
+ // but legacyFormat preserves the old behaviour for non-editable strategies
+ return legacyFormat( message, strategy, vCardName, printing );
+ }
+
+ QString FancyHeaderStyle::legacyFormat( const KMMessage * message,
+ const HeaderStrategy * strategy,
+ const QString & vCardName,
+ bool printing ) const {
if ( !message ) return QString::null;
if ( !strategy )
strategy = HeaderStrategy::rich();
@@ -349,7 +454,7 @@ namespace KMail {
else {
dateString = message->dateStr();
}
-
+
//case HdrFancy:
// the subject line and box below for details
if ( strategy->showHeader( "subject" ) )
@@ -404,10 +509,572 @@ namespace KMail {
.arg(i18n("Date: "))
.arg( directionOf( message->dateStr() ) )
.arg(strToHtml(dateString)));
+
headerStr.append("</table>\n");
headerStr += "</div>\n\n";
+ return headerStr;
+ }
+
+ //
+ // FancyEditor: (Implementation)
+ // Backend for FancyHeaderStyle and Editor
+ //
+
+ // write the top of the header
+ QString FancyEditor::prepareHeader( const KMMessage * message,
+ bool showSubject ) const {
+
+ // ### from kmreaderwin begin
+ // The direction of the header is determined according to the direction
+ // of the application layout.
+ QString headerStr = QString( "<div class=\"fancy header\" dir=\"%1\">\n" )
+ .arg( QApplication::reverseLayout() ? "rtl" : "ltr" );
+
+ if ( showSubject ) {
+ // However, the direction of the message subject within the header is
+ // determined according to the contents of the subject itself. Since
+ // the "Re:" and "Fwd:" prefixes would always cause the subject to be
+ // considered left-to-right, they are ignored when determining its
+ // direction.
+ QString subjectDir;
+ if ( !message->subject().isEmpty() )
+ subjectDir = directionOf( message->cleanSubject() );
+ else
+ subjectDir = directionOf( i18n( "No Subject" ) );
+
+ // the subject line and box below for details
+ headerStr += QString( "<div dir=\"%1\">%2</div>\n" )
+ .arg( subjectDir )
+ .arg( message->subject().isEmpty()
+ ? i18n( "No Subject" )
+ : strToHtml( message->subject() ) );
+ }
+ headerStr += " <table>\n";
+
+ return headerStr;
+ }
+
+ // write the bottom of the header
+ QString FancyEditor::closeHeader( const KMMessage * message ) const {
+ return QString( " </table>\n"
+ "</div>\n\n" );
+ }
+
+ void FancyEditor::categorizeFields( const QStringList & headersToDisplay,
+ const QStringList & headersToHide,
+ const DwHeaders & availableHeaders,
+ FieldListMap & visibleHeaderFields,
+ FieldListMap & hiddenHeaderFields,
+ FieldListMap & newHeaderFields ) const {
+ DwField const * f;
+ for ( f = availableHeaders.FirstField(); f; f = f->Next() ) {
+ DwString const & fieldname = f->FieldNameStr();
+ QString fname(fieldname.c_str());
+ fname = fname.lower();
+
+ if (headersToDisplay.contains(fname)){
+ visibleHeaderFields[fname].append(f);
+ } else if (headersToHide.contains(fname)){
+ hiddenHeaderFields[fname].append(f);
+ }else{
+ newHeaderFields[fname].append(f);
+ }
+ }
+ }
+
+ QString FancyEditor::formatField( QString prependString,
+ int prependStringColumnWidth,
+ QString header,
+ QPtrList<DwField>& fields,
+ const KMMessage * message,
+ const QString & vCardName,
+ bool printing ) const {
+ QString prependStringPlaceholder;
+ if ( prependStringColumnWidth > 0 ) {
+ prependStringPlaceholder = QString ( "<td colspan=\"%3\"></td>" )
+ .arg( prependStringColumnWidth );
+ }
+
+ // from line
+ if ( header == "from" ) {
+
+ QString result = QString( "<tr>\n" + prependString +
+ "<th>%1</th>\n"
+ "<td>" )
+ .arg( i18n( "From: " ) );
+
+ // the mailto: URLs can contain %3 etc., therefore usage of multiple
+ // QString::arg is not possible
+ result.append( KMMessage::emailAddrAsAnchor( message->from(), FALSE ) );
+
+ if ( !vCardName.isEmpty() ) {
+ result.append( " "
+ "<a href=\""+ vCardName + "\">" +
+ i18n( "[vCard]" ) + "</a>" );
+ }
+
+ if (! message->headerField( "Organization" ).isEmpty() ) {
+ result.append( " (" +
+ strToHtml( message->headerField( "Organization" ) ) +
+ ")" );
+ }
+
+ result.append( "</td>\n</tr>\n" );
+ return result;
+
+ // to line
+ } else if ( header == "to" ) {
+ return QString( "<tr>" + prependString +
+ "<th>%1</th>\n"
+ "<td>%2</td>\n"
+ "</tr>\n" )
+ .arg( i18n( "To: " ) )
+ .arg( KMMessage::emailAddrAsAnchor( message->to(), FALSE ) );
+
+ // cc line
+ } else if ( header == "cc" ) {
+ if (message->cc().isEmpty()) {
+ return QString( "<tr>"+ prependString+
+ "<th>%1</th>\n"
+ "<td> </td>\n"
+ "</tr>\n" )
+ .arg( i18n( "CC: " ) );
+ } else {
+ return QString( "<tr>" + prependString +
+ "<th>%1</th>\n"
+ "<td>%2</td>\n"
+ "</tr>\n" )
+ .arg( i18n( "CC: " ) )
+ .arg( KMMessage::emailAddrAsAnchor( message->cc(), FALSE ) );
+ }
+
+ // bcc line
+ } else if ( header == "bcc" ) {
+ if (!message->bcc().isEmpty()){
+ return QString( "<tr>" + prependString +
+ "<th>%1</th>\n"
+ "<td> </td>\n"
+ "</tr>\n" )
+ .arg( i18n( "BCC: " ) );
+ }else{
+ return QString( "<tr>" + prependString +
+ "<th>%1</th>\n"
+ "<td>%2</td>\n"
+ "</tr>\n" )
+ .arg( i18n( "BCC: " ) )
+ .arg( KMMessage::emailAddrAsAnchor( message->bcc(), FALSE ) );
+ }
+
+ // date line
+ } else if ( header == "date" ) {
+ QString dateString;
+ if( printing ) {
+ QDateTime dateTime;
+ KLocale* locale = KGlobal::locale();
+ dateTime.setTime_t( message->date() );
+ dateString = locale->formatDateTime( dateTime );
+ } else {
+ dateString = message->dateStr();
+ }
+
+ return QString( "<tr>" + prependString +
+ "<th>%1</th>\n"
+ "<td dir=\"%2\">%3</td>\n"
+ "</tr>\n" )
+ .arg( i18n( "Date: " ) )
+ .arg( directionOf( message->dateStr() ) )
+ .arg( strToHtml( dateString ) );
+
+ }
+
+ // any header field
+ QString result;
+ DwField *f = fields.first();
+ result.append( QString( "<tr>"+
+ prependString +
+ "<th>%1: </th>\n"
+ "<td>%2</td>\n"
+ "</tr>\n" )
+ .arg( header )
+ .arg( f ? strToHtml( f->FieldBodyStr().c_str() ) : "" ) );
+
+ for( f = f?fields.next():0; f; f = fields.next() ) {
+ result.append( QString( "<tr>" +
+ prependStringPlaceholder +
+ "<th>%1:</th>\n"
+ "<td>%2</td>\n"
+ "</tr>\n" )
+ .arg( header )
+ .arg( strToHtml( f->FieldBodyStr().c_str() ) ) );
+ }
+ return result;
+ }
+
+ void FancyEditor::setProperties( const QMap< QString, QString > & properties,
+ const HeaderStrategy * strategy ) const {
+ HeaderStrategyEditor * editor = strategy->editor();
+
+ if ( !editor ) {
+kdWarning(5006) << "setProperties called for a strategy without editor! ";
+ return;
+ }
+
+ QStringList headersToDisplay = strategy->headersToDisplay();
+ QValueList<QString> keys = properties.keys();
+
+ // for each field
+ QValueList<QString>::iterator it;
+ for ( it = keys.begin(); it != keys.end(); ++it ) {
+ QString const & key = (*it);
+ QString value = properties[key];
+
+ // change default policy
+ if ( key == "defaultPolicy" ) {
+ if ( value == "display" ) {
+ editor->setDefaultPolicy(HeaderStrategy::Display);
+ } else {
+ editor->setDefaultPolicy(HeaderStrategy::Hide);
+ }
+
+ // show field
+ } else if ( value == "show" ){
+ editor->setPolicy( key, HeaderStrategyEditor::Visible );
+
+ // hide field
+ }else if ( value == "hide" ){
+ editor->setPolicy( key, HeaderStrategyEditor::Hidden );
+
+ // reset to default / new field
+ }else if ( value == "default" ){
+ editor->setPolicy( key, HeaderStrategyEditor::Default );
+
+ // move field up one
+ }else if ( value == "up" ) {
+ int current = headersToDisplay.findIndex( key );
+ if ( current > 0 ) {
+ editor->setPolicy( key, HeaderStrategyEditor::Visible, current - 1 );
+ }
+
+ // move field down one
+ }else if (value == "down"){
+ int current = headersToDisplay.findIndex(key);
+ if ( current < headersToDisplay.size() ) {
+ editor->setPolicy( key, HeaderStrategyEditor::Visible, current + 1 );
+ }
+ }
+ }
+ }
+
+ QString FancyEditor::generateEditHtml( const HeaderStrategy * strategy,
+ QString header,
+ HeaderStrategyEditor::DisplayPolicy \
visibility, + bool isFirst, bool isLast ) \
const { + int const spacing = KDialog::spacingHint();
+ int const halfSpacing = spacing/2;
+ // note: the width is set on the td to stop khtml from giving
+ // arbitrary sizes to the table cells. Hopefully khtml will never
+ // start to obey to this size exactly...
+ const QString emptyTD("<td style=\"width: 16px\"/>");
+ const QString imgTD = QString( "<td style=\"width: 16px\">"
+ "<img src=\"%1\" alt=\"\" "
+ " style=\"margin-left: %2px;margin-right: %3px\""
+ " border=\"0\"/>"
+ "</td>\n" );
+ const QString imgLinkTD = QString( "<td style=\"width: 16px\">"
+ "<a href=\"%1\">"
+ "<img src=\"%2\" title=\"%3\" alt=\"\" "
+ " style=\"margin-left: %4px;margin-right: %5px\""
+ " border=\"0\"/>"
+ "</a>"
+ "</td>\n" );
+ QString result;
+ if( !strategy->editor() )
+ return "";
+
+ // field is visible
+ if ( visibility == HeaderStrategyEditor::Visible ) {
+ result.append( imgLinkTD
+ .arg( baseUrl().url() + header + "=hide" )
+ .arg( KGlobal::iconLoader()->iconPath( "kmheaderfieldhide", \
KIcon::Small ) ) + .arg( i18n( "Hide field" ) )
+ .arg( spacing )
+ .arg( halfSpacing )
+ );
+
+ if ( isFirst ){
+ if ( isLast ) {
+ result.append( emptyTD );
+ } else {
+ result.append( imgTD
+ .arg( KGlobal::iconLoader()->iconPath( \
"kmheaderfieldup_inactive", KIcon::Small ) ) + .arg( \
halfSpacing ) + .arg( 0 )
+ );
+ }
+ } else {
+ result.append( imgLinkTD
+ .arg( baseUrl().url() + header + "=up" )
+ .arg( KGlobal::iconLoader()->iconPath( "kmheaderfieldup", \
KIcon::Small ) ) + .arg( i18n( "Move up" ) )
+ .arg( halfSpacing )
+ .arg( 0 )
+ );
+ }
+
+ if (isLast){
+ if ( isFirst ) {
+ result.append( emptyTD );
+ } else {
+ result.append( imgTD
+ .arg( KGlobal::iconLoader()->iconPath( \
"kmheaderfielddown_inactive", KIcon::Small ) ) + .arg( 0 )
+ .arg( spacing )
+ );
+ }
+ } else {
+ result.append( imgLinkTD
+ .arg( baseUrl().url() + header + "=down" )
+ .arg( KGlobal::iconLoader()->iconPath( "kmheaderfielddown", \
KIcon::Small ) ) + .arg( i18n( "Move down" ) )
+ .arg( 0 )
+ .arg( spacing )
+ );
+ }
+
+ // field is hidden
+ } else {
+ result.append( imgLinkTD
+ .arg( baseUrl().url() + header + "=show" )
+ .arg( KGlobal::iconLoader()->iconPath( "kmheaderfieldshow", \
KIcon::Small ) ) + .arg( i18n( "Show field" ) )
+ .arg( spacing )
+ .arg( 0 )
+ );
+ result.append( emptyTD );
+ result.append( emptyTD );
+ }
+
+ return result;
+ }
+
+ QString FancyEditor::format( const KMMessage * message,
+ const HeaderStrategy * strategy,
+ const QString & vCardName,
+ bool printing ) const {
+
+ if ( !message ) return QString::null;
+ if ( !strategy )
+ strategy = HeaderStrategy::rich();
+
+ QString headerStr = prepareHeader( message,
+ strategy->showHeader( "subject" ) );
+
+ // all headers that should be displayed
+ FieldListMap visibleHeaderFields;
+ // all headers to hide
+ FieldListMap hiddenHeaderFields;
+ // all new headers
+ FieldListMap newHeaderFields;
+
+ categorizeFields( strategy->headersToDisplay(),
+ strategy->headersToHide(),
+ message->headers(),
+ visibleHeaderFields,
+ hiddenHeaderFields,
+ newHeaderFields );
+
+ // remove subject from the list of headers to display
+ QStringList htd( strategy->headersToDisplay() );
+ htd.remove( "subject" );
+
+ // display visible headers
+ QStringList::const_iterator it;
+ for ( it = htd.begin(); !( it == htd.end() ); ++it ) {
+ if ( visibleHeaderFields.contains( (*it) ) ) {
+ headerStr.append( formatField( QString::null, 0, (*it),
+ visibleHeaderFields[(*it)],
+ message, vCardName, printing ) );
+ }
+ }
+
+ // display new headers
+ if ( strategy->defaultPolicy() == HeaderStrategy::Display
+ && !newHeaderFields.empty() )
+ {
+ QValueList<QString> const & headers = newHeaderFields.keys();
+ QValueList<QString>::const_iterator nit;
+ for ( nit = headers.begin(); nit != headers.end(); ++nit ) {
+ headerStr.append( formatField( QString::null, 0, (*nit),
+ newHeaderFields[(*nit)],
+ message, vCardName, printing ) );
+ }
+ }
+
+ // enter edit mode
+ if ( strategy->editor() ) {
+ headerStr.append( QString( "<tr >"
+ "<td colspan=\"2\">"
+ "<a href=\"%1\">%2</a></td></tr>\n" )
+ .arg( urlEnableEditor().url() )
+ .arg( i18n( "more..." ) ) );
+ }
+
+ headerStr.append( closeHeader( message ) );
+ return headerStr;
+ }
+
+ QString FancyEditor::formatAsEditor( const KMMessage * message,
+ const HeaderStrategy * strategy,
+ const QString & vCardName,
+ bool printing ) const {
+
+ if ( !message ) return QString::null;
+ if ( !strategy )
+ strategy = HeaderStrategy::rich();
+
+ if ( !strategy->editor() ){
+ return format(message, strategy, vCardName, printing);
+ }
+
+ QString headerStr = prepareHeader( message,
+ strategy->showHeader( "subject" ) );
+
+ const QStringList & headersToHide = strategy->headersToHide();
+
+ // all headers that should be displayed
+ FieldListMap visibleHeaderFields;
+ // all headers to hide
+ FieldListMap hiddenHeaderFields;
+ // all new headers
+ FieldListMap newHeaderFields;
+
+ categorizeFields( strategy->headersToDisplay(),
+ headersToHide,
+ message->headers(),
+ visibleHeaderFields,
+ hiddenHeaderFields,
+ newHeaderFields );
+
+ int columnsTotal = 5;
+
+ // remove subject from the list of headers to display
+ QStringList htd( strategy->headersToDisplay() );
+ htd.remove( "subject" );
+
+ // visible header fields
+
+ // Heading
+ headerStr.append(
+ QString( "<tr><td colspan=\"%1\"><h3>%2</h3></td></tr>\n" )
+ .arg( columnsTotal )
+ .arg( i18n( "Visible header fields" ) ) );
+
+ QStringList::const_iterator it;
+ int size = htd.size();
+ int i = 0;
+ for ( it = htd.begin(); !( it == htd.end() ); ++it ) {
+ headerStr.append( formatField(
+ generateEditHtml( strategy, (*it), HeaderStrategyEditor::Visible,
+ i == 0, i == size-1 ), columnsTotal - 2,
+ (*it), visibleHeaderFields[(*it)], message, vCardName, printing ) );
+ ++i;
+ }
+
+ // new header fields
+ if ( !newHeaderFields.empty()
+ && strategy->defaultPolicy() == HeaderStrategy::Display ) {
+
+ QValueList<QString> const & headers = newHeaderFields.keys();
+ QValueList<QString>::const_iterator oit;
+ for ( oit = headers.begin(); oit != headers.end(); ++oit ) {
+ headerStr.append( formatField(
+ generateEditHtml( strategy, (*oit),
+ strategy->defaultPolicy() == HeaderStrategy::Display
+ ? HeaderStrategyEditor::Visible
+ : HeaderStrategyEditor::Hidden,
+ true, true ),columnsTotal - 2,
+ (*oit), newHeaderFields[(*oit)], message, vCardName, printing ) );
+ }
+
+ }
+
+ // exit edit mode
+ headerStr.append( QString( "<tr >"
+ "<td colspan=\"%1\">"
+ "<a href=\"%2\">%3</a></td></tr>\n" )
+ .arg( columnsTotal )
+ .arg( urlDisableEditor().url() )
+ .arg( i18n( "go back" ) ) );
+
+
+ // hidden header fields
+ if ( headersToHide.begin() != headersToHide.end()
+ || ( !newHeaderFields.empty()
+ && strategy->defaultPolicy() == HeaderStrategy::Hide ) ) {
+ headerStr.append( QString( "<tr><td colspan=\"%1\"><hr></td></tr>\n" )
+ .arg( columnsTotal ) );
+ headerStr.append( QString( "<tr><td colspan=\"%1\"><h3>%2</h3></td>"
+ "</tr>\n")
+ .arg( columnsTotal )
+ .arg( i18n( "Hidden header fields" ) ) );
+
+ for ( it = headersToHide.begin(); it != headersToHide.end(); ++it ) {
+ headerStr.append( formatField(
+ generateEditHtml( strategy, (*it), HeaderStrategyEditor::Hidden,
+ false, false ),columnsTotal - 2,
+ (*it), hiddenHeaderFields[(*it)], message, vCardName, printing ) );
+ }
+
+ // new header fields
+ if (( !newHeaderFields.empty()
+ && strategy->defaultPolicy() == HeaderStrategy::Hide ) ) {
+ QValueList<QString> const & headers = newHeaderFields.keys();
+ QValueList<QString>::const_iterator oit;
+ for ( oit = headers.begin(); oit != headers.end(); ++oit ) {
+ headerStr.append( formatField(
+ generateEditHtml( strategy, (*oit),
+ strategy->defaultPolicy() == HeaderStrategy::Display
+ ? HeaderStrategyEditor::Visible
+ : HeaderStrategyEditor::Hidden,
+ true, true ),columnsTotal - 2,
+ (*oit), newHeaderFields[(*oit)], message, vCardName, printing ) );
+ }
+ }
+
+ // exit edit mode
+ headerStr.append( QString( "<tr >"
+ "<td colspan=\"%1\">"
+ "<a href=\"%2\">%3</a></td></tr>\n" )
+ .arg( columnsTotal )
+ .arg( urlDisableEditor().url() )
+ .arg( i18n( "go back" ) ) );
+ }
+
+/*
+ headerStr.append( QString( "<tr><td colspan=\"%1\"><hr></td></tr>\n" )
+ .arg( columnsTotal ) );
+ if ( strategy->defaultPolicy() == HeaderStrategy::Hide ) {
+ headerStr.append( QString( "<tr>"
+ "<td colspan=\"%1\">"
+ "<a href=\"%2\">%3</a></td></tr>\n" )
+ .arg( columnsTotal )
+ .arg( baseUrl().url()+"defaultPolicy=display" )
+ .arg( i18n( "Display new header fields by default." ) ) );
+
+ } else {
+ headerStr.append( QString( "<tr>"
+ "<td colspan=\"%1\">"
+ "<a href=\"%2\">%3</a></td></tr>\n" )
+ .arg( columnsTotal )
+ .arg( baseUrl().url()+"defaultPolicy=hide" )
+ .arg( i18n( "Hide new header fields by default." ) ) );
+
+ }
+*/
+ headerStr.append( closeHeader( message ) );
+//kdDebug(5006)<< headerStr;
return headerStr;
}
Index: headerstyle.h
===================================================================
RCS file: /home/kde/kdepim/kmail/headerstyle.h,v
retrieving revision 1.5
diff -u -3 -p -r1.5 headerstyle.h
--- headerstyle.h 26 Jul 2003 14:51:49 -0000 1.5
+++ headerstyle.h 29 Aug 2003 22:24:42 -0000
@@ -38,6 +38,7 @@ class KMMessage;
namespace KMail {
class HeaderStrategy;
+ class HeaderStyleEditor;
/** This class encapsulates the visual appearance of message
headers. Together with @ref HeaderStrategy, which determines
@@ -80,6 +81,7 @@ namespace KMail {
const KMail::HeaderStrategy * strategy,
const QString & vCardName,
bool printing=false ) const = 0;
+ virtual HeaderStyleEditor * editor() const = 0;
};
} // namespace KMail
Index: kmmainwidget.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmainwidget.cpp,v
retrieving revision 1.79
diff -u -3 -p -r1.79 kmmainwidget.cpp
--- kmmainwidget.cpp 28 Aug 2003 19:22:56 -0000 1.79
+++ kmmainwidget.cpp 29 Aug 2003 22:24:42 -0000
@@ -1209,6 +1209,11 @@ void KMMainWidget::slotFancyHeaders() {
HeaderStrategy::rich() );
}
+void KMMainWidget::slotCustomHeaders() {
+ mMsgView->setHeaderStyleAndStrategy( HeaderStyle::fancy(),
+ HeaderStrategy::custom() );
+}
+
void KMMainWidget::slotBriefHeaders() {
mMsgView->setHeaderStyleAndStrategy( HeaderStyle::brief(),
HeaderStrategy::brief() );
@@ -1235,8 +1240,13 @@ void KMMainWidget::slotCycleHeaderStyles
const char * actionName = 0;
if ( style == HeaderStyle::fancy() ) {
- slotBriefHeaders();
- actionName = "view_headers_brief";
+ if ( strategy == HeaderStrategy::rich() ) {
+ slotCustomHeaders();
+ actionName = "view_headers_custom";
+ } else if ( strategy == HeaderStrategy::custom() ) {
+ slotBriefHeaders();
+ actionName = "view_headers_brief";
+ }
} else if ( style == HeaderStyle::brief() ) {
slotStandardHeaders();
actionName = "view_headers_standard";
@@ -1721,9 +1731,12 @@ void KMMainWidget::getAccountMenu()
// little helper function
KRadioAction * KMMainWidget::actionForHeaderStyle( const HeaderStyle * style, const \
HeaderStrategy * strategy ) { const char * actionName = 0;
- if ( style == HeaderStyle::fancy() )
- actionName = "view_headers_fancy";
- else if ( style == HeaderStyle::brief() )
+ if ( style == HeaderStyle::fancy() ){
+ if (strategy == HeaderStrategy::custom() )
+ actionName = "view_headers_custom";
+ else
+ actionName = "view_headers_fancy";
+ }else if ( style == HeaderStyle::brief() )
actionName = "view_headers_brief";
else if ( style == HeaderStyle::plain() ) {
if ( strategy == HeaderStrategy::standard() )
@@ -2055,6 +2068,14 @@ void KMMainWidget::setupActions()
SLOT(slotFancyHeaders()),
actionCollection(), "view_headers_fancy" );
raction->setToolTip( i18n("Show the list of headers in a fancy format") );
+ raction->setExclusiveGroup( "view_headers_group" );
+ headerMenu->insert( raction );
+
+ raction = new KRadioAction( i18n("View->headers->", "&Custom Headers"), 0, this,
+ SLOT(slotCustomHeaders()),
+ actionCollection(), "view_headers_custom" );
+ raction->setToolTip( i18n("Show the list of headers in a fancy format and "
+ "allow customization of which headers are shown."));
raction->setExclusiveGroup( "view_headers_group" );
headerMenu->insert( raction );
Index: kmmainwidget.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmmainwidget.h,v
retrieving revision 1.26
diff -u -3 -p -r1.26 kmmainwidget.h
--- kmmainwidget.h 26 Aug 2003 23:50:33 -0000 1.26
+++ kmmainwidget.h 29 Aug 2003 22:24:42 -0000
@@ -247,6 +247,7 @@ protected slots:
void slotToggleTotalColumn();
void slotBriefHeaders();
void slotFancyHeaders();
+ void slotCustomHeaders();
void slotStandardHeaders();
void slotLongHeaders();
void slotAllHeaders();
Index: kmreaderwin.cpp
===================================================================
RCS file: /home/kde/kdepim/kmail/kmreaderwin.cpp,v
retrieving revision 1.693
diff -u -3 -p -r1.693 kmreaderwin.cpp
--- kmreaderwin.cpp 27 Aug 2003 23:20:57 -0000 1.693
+++ kmreaderwin.cpp 29 Aug 2003 22:24:42 -0000
@@ -36,8 +36,12 @@ using KMail::ObjectTreeParser;
using KMail::PartMetaData;
#include "attachmentstrategy.h"
using KMail::AttachmentStrategy;
+#include "headerstrategyeditor.h"
+using KMail::HeaderStrategyEditor;
#include "headerstrategy.h"
using KMail::HeaderStrategy;
+#include "headerstyleeditor.h"
+using KMail::HeaderStyleEditor;
#include "headerstyle.h"
using KMail::HeaderStyle;
#include "khtmlparthtmlwriter.h"
@@ -180,6 +184,16 @@ QByteArray& NewByteArray::qByteArray()
return *((QByteArray*)this);
}
+//-----------------------------------------------------------------------------
+// Utility functions
+
+/** @return true: base is base url for candidate */
+static bool isBaseUrl( const KURL & base, const KURL & candidate ) {
+ KURL candidateBase( candidate );
+ candidateBase.setQuery( "" );
+ return base.equals( candidateBase, true );
+}
+//-----------------------------------------------------------------------------
// This function returns the complete data that were in this
@@ -481,7 +495,10 @@ KMReaderWin::KMReaderWin(QWidget *aParen
mCSSHelper( 0 ),
mRootNode( 0 ),
mMainWindow( mainWindow ),
- mHtmlWriter( 0 )
+ mHtmlWriter( 0 ),
+ mStyleEditorBaseUrl( "kmailconfig://mail/header/display?" ),
+ mStyleEditorUrlEnable( "kmailconfig://mail/header/display?edit=true" ),
+ mStyleEditorUrlDisable( "kmailconfig://mail/header/display?edit=false" )
{
mSplitterSizes << 180 << 100;
mMimeTreeMode = 1;
@@ -501,6 +518,8 @@ KMReaderWin::KMReaderWin(QWidget *aParen
mHtmlOverride = false;
+ mEditMailDisplayInline = false;
+
connect( &updateReaderWinTimer, SIGNAL(timeout()),
this, SLOT(updateReaderWin()) );
connect( &mResizeTimer, SIGNAL(timeout()),
@@ -839,6 +858,14 @@ void KMReaderWin::setHeaderStyleAndStrat
const HeaderStrategy * strategy ) {
mHeaderStyle = style ? style : HeaderStyle::fancy() ;
mHeaderStrategy = strategy ? strategy : HeaderStrategy::rich() ;
+
+ HeaderStyleEditor * editor = mHeaderStyle->editor();
+ if (editor){
+ editor->setBaseUrl(mStyleEditorBaseUrl);
+ editor->setUrlEnableEditor(mStyleEditorUrlEnable);
+ editor->setUrlDisableEditor(mStyleEditorUrlDisable);
+ }
+
update( true );
}
@@ -860,6 +887,9 @@ void KMReaderWin::setMsg(KMMessage* aMsg
if (!force && aMsg && mLastSerNum != 0 && aMsg->getMsgSerNum() == mLastSerNum)
return;
+ // exit edit mode
+ mEditMailDisplayInline = false;
+
// (de)register as observer
if (mMessage)
mMessage->detach( this );
@@ -1332,6 +1362,11 @@ QString KMReaderWin::writeMsgHeader(KMMe
if (hasVCard)
href = QString("file:") + KURL::encode_string( mTempFiles.last() );
+ if ( mEditMailDisplayInline && headerStyle()->editor() ) {
+ return headerStyle()->editor()->formatAsEditor( aMsg, headerStrategy(),
+ href, mPrinting );
+ }
+
return headerStyle()->format( aMsg, headerStrategy(), href, mPrinting );
}
@@ -1535,6 +1570,22 @@ void KMReaderWin::slotUrlOn(const QStrin
emit statusMsg( i18n("Turn on HTML rendering for this message.") );
bOk = true;
}
+ else if( url == mStyleEditorUrlEnable )
+ {
+ emit statusMsg( i18n("Edit display of mail header.") );
+ bOk = true;
+ }
+ else if( url == mStyleEditorUrlDisable )
+ {
+ emit statusMsg( i18n("Leave editor mode.") );
+ bOk = true;
+ }
+ else if( isBaseUrl( mStyleEditorBaseUrl, url ) )
+ {
+ // a meaningfull statusbar message would need parsing of the url,
+ // so we do not show a message at all
+ bOk = true;
+ }
else if( foundSMIMEData( aUrl, dummyStr, dummyStr, keyId ) )
{
emit statusMsg(i18n("Show certificate 0x%1").arg(keyId));
@@ -2270,6 +2321,8 @@ void KMReaderWin::slotUrlCopy()
void KMReaderWin::slotPreUrlOpen()
{
mAtmCurrent = msgPartFromUrl( mUrlClicked );
+
+ // Open Attachment
if ( mAtmCurrent > 0 )
{
// these are needed for update( KMail::ISubject * )
@@ -2281,8 +2334,46 @@ void KMReaderWin::slotPreUrlOpen()
connect( command, SIGNAL( partsRetrieved() ),
this, SLOT( slotUrlOpen() ) );
command->start();
- } else
+
+ // Enable Editor Mode
+ } else if ( mUrlClicked == mStyleEditorUrlEnable ) {
+ if ( headerStrategy()->editor() && headerStyle()->editor() ) {
+ mEditMailDisplayInline = true;
+ } else {
+ mEditMailDisplayInline = false;
+ kdError( 5006 ) << "Tried to enable headerstyle editor, "
+ "but current headerstrategy or current headerstyle "
+ "does not provide an editor!";
+ }
+ updateReaderWin();
+
+ // Disable Editor Mode
+ } else if ( mUrlClicked == mStyleEditorUrlDisable ) {
+ mEditMailDisplayInline = false;
+ updateReaderWin();
+
+ // Edit requested
+ } else if ( isBaseUrl( mStyleEditorBaseUrl, mUrlClicked ) ) {
+ HeaderStrategyEditor * strategyEditor = headerStrategy()->editor();
+ if ( strategyEditor ) {
+ HeaderStyleEditor * styleEditor = headerStyle()->editor();
+ if ( styleEditor ) {
+ styleEditor->setProperties( mUrlClicked.queryItems(),
+ headerStrategy() );
+ } else {
+ kdError( 5006 ) << "Tried to edit style, but current"
+ " style does not supply an editor.";
+ }
+ } else {
+ kdError( 5006 ) << "Tried to edit strategy, but current"
+ " strategy does not supply an editor.";
+ }
+ updateReaderWin();
+
+ // Open Url
+ } else {
slotUrlOpen( mUrlClicked, KParts::URLArgs() );
+ }
}
//-----------------------------------------------------------------------------
Index: kmreaderwin.h
===================================================================
RCS file: /home/kde/kdepim/kmail/kmreaderwin.h,v
retrieving revision 1.176
diff -u -3 -p -r1.176 kmreaderwin.h
--- kmreaderwin.h 13 Aug 2003 11:35:36 -0000 1.176
+++ kmreaderwin.h 29 Aug 2003 22:24:42 -0000
@@ -441,6 +441,12 @@ private:
// an attachment should be updated
bool mAtmUpdate;
QPoint mPos;
+
+ // inline editing of mail display settings
+ bool mEditMailDisplayInline;
+ const KURL mStyleEditorBaseUrl;
+ const KURL mStyleEditorUrlEnable;
+ const KURL mStyleEditorUrlDisable;
};
Index: pics/Makefile.am
===================================================================
RCS file: /home/kde/kdepim/kmail/pics/Makefile.am,v
retrieving revision 1.33
diff -u -3 -p -r1.33 Makefile.am
--- pics/Makefile.am 6 Jul 2003 17:33:55 -0000 1.33
+++ pics/Makefile.am 29 Aug 2003 22:24:42 -0000
@@ -1,5 +1,8 @@
-pics_DATA = kmmsgdel.png kmmsgnew.png kmmsgunseen.png kmmsgread.png \
+pics_DATA = kmheaderfieldup.png kmheaderfielddown.png \
+ kmheaderfieldup_inactive.png kmheaderfielddown_inactive.png \
+ kmheaderfieldshow.png kmheaderfieldhide.png\
+ kmmsgdel.png kmmsgnew.png kmmsgunseen.png kmmsgread.png \
kmmsgreplied.png kmmsgforwarded.png kmmsgqueued.png kmmsgflag.png \
kmmsgsent.png kmmsgwatched.png kmmsgignored.png \
stopwatch.xbm stopwatchMask.xbm kdelogo.png \
["kmheaderfielddown.png" (image/png)]
["kmheaderfieldup.png" (image/png)]
["kmheaderfielddown_inactive.png" (image/png)]
["kmheaderfieldhide.png" (image/png)]
["kmheaderfieldshow.png" (image/png)]
["kmheaderfieldup_inactive.png" (image/png)]
_______________________________________________
KMail Developers mailing list
kmail@mail.kde.org
http://mail.kde.org/mailman/listinfo/kmail
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic