From 163bdaf85303470e9d014a3242aae9548fa52268 Mon Sep 17 00:00:00 2001 From: helge Date: Sat, 2 Oct 2004 16:41:24 +0000 Subject: [PATCH] more work on mailer git-svn-id: http://svn.opengroupware.org/SOGo/trunk@340 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/UI/Mailer/GNUmakefile | 7 +- SOGo/UI/Mailer/Images/icon_mark_flagged.gif | Bin 0 -> 215 bytes SOGo/UI/Mailer/Images/icon_mark_read.gif | Bin 0 -> 552 bytes SOGo/UI/Mailer/Images/icon_mark_unflagged.gif | Bin 0 -> 368 bytes SOGo/UI/Mailer/Images/icon_mark_unread.gif | Bin 0 -> 538 bytes SOGo/UI/Mailer/Images/icon_read.gif | Bin 0 -> 79 bytes SOGo/UI/Mailer/Images/icon_unread.gif | Bin 0 -> 85 bytes SOGo/UI/Mailer/UIxMailFormatter.h | 13 +- SOGo/UI/Mailer/UIxMailFormatter.m | 79 ---------- SOGo/UI/Mailer/UIxMailListView.m | 40 +++++ SOGo/UI/Mailer/UIxMailListView.wox | 94 +++++++---- SOGo/UI/Mailer/UIxSubjectFormatter.m | 147 ++++++++++++++++++ SOGo/UI/Mailer/mailer.css | 84 +++++++++- SOGo/UI/Mailer/product.plist | 18 +++ 14 files changed, 368 insertions(+), 114 deletions(-) create mode 100644 SOGo/UI/Mailer/Images/icon_mark_flagged.gif create mode 100644 SOGo/UI/Mailer/Images/icon_mark_read.gif create mode 100644 SOGo/UI/Mailer/Images/icon_mark_unflagged.gif create mode 100644 SOGo/UI/Mailer/Images/icon_mark_unread.gif create mode 100644 SOGo/UI/Mailer/Images/icon_read.gif create mode 100644 SOGo/UI/Mailer/Images/icon_unread.gif create mode 100644 SOGo/UI/Mailer/UIxSubjectFormatter.m diff --git a/SOGo/UI/Mailer/GNUmakefile b/SOGo/UI/Mailer/GNUmakefile index 5de68bca..8b621200 100644 --- a/SOGo/UI/Mailer/GNUmakefile +++ b/SOGo/UI/Mailer/GNUmakefile @@ -11,11 +11,13 @@ MailerUI_LANGUAGES = English French MailerUI_OBJC_FILES += \ MailerUIProduct.m \ \ - UIxMailMainFrame.m \ - UIxMailTree.m \ UIxMailFormatter.m \ + UIxSubjectFormatter.m \ WOContext+UIxMailer.m \ \ + UIxMailMainFrame.m \ + UIxMailTree.m \ + \ UIxMailAccountsView.m \ UIxMailAccountView.m \ UIxMailListView.m \ @@ -43,6 +45,7 @@ MailerUI_RESOURCE_FILES += \ MailerUI_RESOURCE_FILES += \ screenshots/*.png \ Images/tbtv_*.gif \ + Images/icon_*.gif \ Images/tbtb_*.png \ MailerUI_LOCALIZED_RESOURCE_FILES += \ diff --git a/SOGo/UI/Mailer/Images/icon_mark_flagged.gif b/SOGo/UI/Mailer/Images/icon_mark_flagged.gif new file mode 100644 index 0000000000000000000000000000000000000000..c7bbd75e57321d732e65c133d508327293ad9c73 GIT binary patch literal 215 zcmZ?wbhEHb6l4%&IP#z2|NsAg7_@HQyt$V_J|`z9J3BioD=Q--BRxGmEiEl2B_%mI zIVmYAF)=YTG&CqE$lu@J$H&Lp+uO^_%hS`-!^6YP&CS)-)y2id#KeSwf#JY`13(fE z6o0ZXGB8Lp=zv5(b~>xvJk+ZGE`CU%zTpmfYzS0gKx5as@eSJAjr_P*J#q{z^>3_!f5N{Pl G25SI<98A~% literal 0 HcmV?d00001 diff --git a/SOGo/UI/Mailer/Images/icon_mark_read.gif b/SOGo/UI/Mailer/Images/icon_mark_read.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b0a47d63c8ef5bc1c0ec8dcf9fe8b9e0c5ec2d8 GIT binary patch literal 552 zcmZ?wbhEHb6l4%&xcZ;r|Ns9tZ{9q6_UzH4M-TkZTDNXpV`F2rEQ|~c`V2ZCT_8U>uuVKLy}(09Dt-+Y$JQhs7RFw;8Co*y51sEW zNZ4z_?40GQ#naY$`IG|Zj=NJ=1X`;ag{{8);qY5N4i zlXxZy@kF>Xvo=?=#FgrERH!%Cu++viXe-REj#W^p&`?p>=ElQX!4VM1w9tuFLzAPB zaeq&Snub(vejbx(se(G&OlL<1Yn*<9xZe}W{p_s`o=wdytu5Aeo^E<}jD7v4rfrj_ zICxrnxO;X^X_n&D;^yJy7m^m8)H=<@ZElmJldX;G>~&2_eR{igv2m_!k&=~FP*6Ii zrmjBMZq8f>UH3EV&d=Di+dsV-rp?C%&fDQTbobtb(5qf S58qM|QE`cHIh_)MMb%|xHvdC*x1+@7#I#5H~=Im2Z}#g7#SEe7<52J zf&Apa*6T2(z(YqWu($hQN|pc{6Q8?>k<9wWCd~s^7jbY*(o9j{;Z+uHViMh<-|Rhc zwyB`>8NpS4*Oe~Ggt?0-`N)WO{dBzpt;akB^VHx3`yo7qt8o( z9UC;~|MI3R@&dwGLHQ*%pen}eO64P#HQscHMfHd_Z>YdZ&Nl~qtsI;f_uzH#>28LK9))m?Y; v_;f29t1DNn+BWO;_Lws7YL;bY*4e?W%_n%jNm7%CZ?TA|xWubtjSSWR5eIx7 literal 0 HcmV?d00001 diff --git a/SOGo/UI/Mailer/Images/icon_read.gif b/SOGo/UI/Mailer/Images/icon_read.gif new file mode 100644 index 0000000000000000000000000000000000000000..364468629928d11f4c3bce6f669eda73b11a3d48 GIT binary patch literal 79 zcmZ?wbhEHb -@class NSString, NSCalendarDate, NSTimeZone; +/* + UIxMailFormatter + + Formatters which render various mail related fields. +*/ + +@class NSData, NSString, NSCalendarDate, NSTimeZone; @interface UIxMailFormatter : NSFormatter { @@ -68,6 +74,11 @@ - (NSString *)missingSubjectLabel; +/* specific formatters */ + +- (NSString *)stringForStringValue:(NSString *)_subject; +- (NSString *)stringForDataValue:(NSData *)_subject; + @end @interface UIxEnvelopeAddressFormatter : UIxMailFormatter diff --git a/SOGo/UI/Mailer/UIxMailFormatter.m b/SOGo/UI/Mailer/UIxMailFormatter.m index 79e77e2d..c5a13819 100644 --- a/SOGo/UI/Mailer/UIxMailFormatter.m +++ b/SOGo/UI/Mailer/UIxMailFormatter.m @@ -148,85 +148,6 @@ static BOOL debugOn = YES; @end /* UIxMailDateFormatter */ -@implementation UIxSubjectFormatter - -- (id)init { - if ((self = [super init])) { - self->maxLength = 64; - } - return self; -} - -/* configuration */ - -- (unsigned int)maxLength { - return self->maxLength; -} - -/* labels */ - -- (NSString *)missingSubjectLabel { - return [self labelForKey:@"no_subject"]; -} - -/* specific formatters */ - -- (NSString *)stringForStringValue:(NSString *)_subject { - NSString *s; - - if ([_subject hasPrefix:@"=?"]) { /* quoted printable */ -#warning TODO: work on QP decoding - /* =?iso-8859-1?q?Yannick=20DAmboise?= */ - if ((s = [_subject stringByDecodingQuotedPrintable])) - _subject = s; - } - - if ([_subject length] == 0) - return [self missingSubjectLabel]; - - if ([_subject length] <= [self maxLength]) - return _subject; - - s = [_subject substringToIndex:([self maxLength] - 3)]; - return [s stringByAppendingString:@"..."]; -} - -- (NSString *)stringForDataValue:(NSData *)_subject { - NSString *s, *r; - - if ([_subject length] == 0) - return [self missingSubjectLabel]; - - [self debugWithFormat:@"WARNING: NSData subject! (using UTF-8 to decode!)"]; - - // TODO: exception handler? - s = [[NSString alloc] initWithData:_subject encoding:NSUTF8StringEncoding]; - if (s == nil) { - [self logWithFormat:@"ERROR: could do not decode NSData subject!"]; - return [self labelForKey:@"Error_CouldNotDecodeSubject"]; - } - - r = [[self stringForStringValue:s] copy]; - [s release]; - return [r autorelease]; -} - -/* formatter entry function */ - -- (NSString *)stringForObjectValue:(id)_subject { - if (![_subject isNotNull]) - return [self missingSubjectLabel]; - - if ([_subject isKindOfClass:StrClass]) - return [self stringForStringValue:_subject]; - if ([_subject isKindOfClass:[NSData class]]) - return [self stringForDataValue:_subject]; - - return [self stringForStringValue:[_subject stringValue]]; -} - -@end /* UIxSubjectFormatter */ - #include @implementation UIxEnvelopeAddressFormatter diff --git a/SOGo/UI/Mailer/UIxMailListView.m b/SOGo/UI/Mailer/UIxMailListView.m index 11da482f..cc86c777 100644 --- a/SOGo/UI/Mailer/UIxMailListView.m +++ b/SOGo/UI/Mailer/UIxMailListView.m @@ -57,6 +57,11 @@ return self->message; } +- (BOOL)showToAddress { + // TODO: switch for Sent folder + return NO; +} + /* derived accessors */ - (BOOL)isMessageRead { @@ -65,6 +70,9 @@ flags = [[self message] valueForKey:@"flags"]; return [flags containsObject:@"seen"]; } +- (NSString *)messageUidString { + return [[[self message] valueForKey:@"uid"] stringValue]; +} - (NSArray *)messages { NSArray *uids; @@ -99,6 +107,29 @@ return [msgs valueForKey:@"fetch"]; } +/* URL processing */ + +- (NSString *)messageViewTarget { + return [@"SOGo_msg_" stringByAppendingString:[self messageUidString]]; +} +- (NSString *)messageViewURL { + // TODO: noframe only when view-target is empty + // TODO: markread only if the message is unread + NSString *s; + + s = [[self messageUidString] stringByAppendingString:@"/view?noframe=1"]; + if (![self isMessageRead]) s = [s stringByAppendingString:@"&markread=1"]; + return s; +} +- (NSString *)markReadURL { + return [@"markMessageRead?uid=" stringByAppendingString: + [self messageUidString]]; +} +- (NSString *)markUnreadURL { + return [@"markMessageUnread?uid=" stringByAppendingString: + [self messageUidString]]; +} + /* actions */ - (id)defaultAction { @@ -106,4 +137,13 @@ return self; } +- (id)markMessageUnreadAction { + [self logWithFormat:@"TODO: mark message unread!"]; + return [self redirectToLocation:@"view"]; +} +- (id)markMessageReadAction { + [self logWithFormat:@"TODO: mark message read!"]; + return [self redirectToLocation:@"view"]; +} + @end /* UIxMailListView */ diff --git a/SOGo/UI/Mailer/UIxMailListView.wox b/SOGo/UI/Mailer/UIxMailListView.wox index ab2195fe..53e2aa5f 100644 --- a/SOGo/UI/Mailer/UIxMailListView.wox +++ b/SOGo/UI/Mailer/UIxMailListView.wox @@ -10,12 +10,12 @@ title="name" >
- View: - - + Subject or Sender contains: @@ -23,50 +23,86 @@
- screenshot - - +
- - - - - + + + + + + - + + + -
DateSubjectFromToFlags + + + + + + + + + + + + + +
- - - - - +
+ + + +
- - - +
+ + + +
+
+
+ + + + + + - + +
+ +
+
+ +
+ +
+
- + + +
- Folder List
diff --git a/SOGo/UI/Mailer/UIxSubjectFormatter.m b/SOGo/UI/Mailer/UIxSubjectFormatter.m new file mode 100644 index 00000000..396d8b21 --- /dev/null +++ b/SOGo/UI/Mailer/UIxSubjectFormatter.m @@ -0,0 +1,147 @@ +/* + Copyright (C) 2004 SKYRIX Software AG + + This file is part of OpenGroupware.org. + + OGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + OGo 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include "UIxMailFormatter.h" +#include "common.h" + +#include + +@implementation UIxSubjectFormatter + +static Class StrClass = Nil; +static Class DataClass = Nil; + ++ (void)initialize { + StrClass = [NSString class]; + DataClass = [NSData class]; +} + +- (id)init { + if ((self = [super init])) { + self->maxLength = 64; + } + return self; +} + +/* configuration */ + +- (unsigned int)maxLength { + return self->maxLength; +} + +- (BOOL)shouldDecodeQP { + return YES; +} + +/* labels */ + +- (NSString *)missingSubjectLabel { + return [self labelForKey:@"no_subject"]; +} + +/* specific formatters */ + +- (NSString *)stringForStringValue:(NSString *)_subject { + NSString *s; + + /* quoted printable */ + if ([self shouldDecodeQP] && [_subject hasPrefix:@"=?"]) { + /* + Now this is interesting. An NSString should not contain QP markers since + it is already 'charset decoded'. This is also why the NGMime parser + expects an NSData. + + Sample: + =?iso-8859-1?q?Yannick=20DAmboise?= + + Note: -stringByDecodingQuotedPrintable only expands =D0 like charcodes! + */ + NSData *data; + + /* header field data should always be ASCII */ + data = [_subject dataUsingEncoding:NSUTF8StringEncoding]; + return [self stringForDataValue:data]; + } + + if ([_subject length] == 0) + return [self missingSubjectLabel]; + + if ([_subject length] <= [self maxLength]) + return _subject; + + s = [_subject substringToIndex:([self maxLength] - 3)]; + return [s stringByAppendingString:@"..."]; +} + +- (NSString *)stringForDataValue:(NSData *)_subject { + NSString *s, *r; + unsigned len; + + if ((len = [_subject length] == 0)) + return [self missingSubjectLabel]; + + /* check for quoted printable */ + + if (len > 6 && [self shouldDecodeQP]) { + const unsigned char *b; + + b = [_subject bytes]; + if (b[0] == '=' && b[1] == '?') { + /* eg: '=?iso-8859-1?q?Yannick=20DAmboise?=' */ + id t; + + t = [_subject decodeQuotedPrintableValueOfMIMEHeaderField:@"subject"]; + if ([t isNotNull]) + return [self stringForObjectValue:t]; + } + } + + /* continue NSData processing */ + + [self debugWithFormat:@"WARNING: NSData subject! (using UTF-8 to decode!)"]; + + // TODO: exception handler? + s = [[NSString alloc] initWithData:_subject encoding:NSUTF8StringEncoding]; + if (s == nil) { + [self logWithFormat:@"ERROR: could do not decode NSData subject!"]; + return [self labelForKey:@"Error_CouldNotDecodeSubject"]; + } + + r = [[self stringForStringValue:s] copy]; + [s release]; + return [r autorelease]; +} + +/* formatter entry function */ + +- (NSString *)stringForObjectValue:(id)_subject { + if (![_subject isNotNull]) + return [self missingSubjectLabel]; + + if ([_subject isKindOfClass:StrClass]) + return [self stringForStringValue:_subject]; + if ([_subject isKindOfClass:DataClass]) + return [self stringForDataValue:_subject]; + + return [self stringForStringValue:[_subject stringValue]]; +} + +@end /* UIxSubjectFormatter */ diff --git a/SOGo/UI/Mailer/mailer.css b/SOGo/UI/Mailer/mailer.css index 90646d7c..1275fb3e 100644 --- a/SOGo/UI/Mailer/mailer.css +++ b/SOGo/UI/Mailer/mailer.css @@ -139,10 +139,88 @@ td.tb_icon a { .tableview { font-size: 9pt; font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif; + vertical-align: top; } -span.readmailsubject { +td.tbtv_headercell { + border-width: 1; + border-style: solid; + border-top-color: white; + border-left-color: white; + border-bottom-color: #808080; + border-right-color: #808080; + padding-top: 4px; + padding-bottom: 3px; + padding-left: 4px; + padding-right: 4px; + + background-color: #D4D0C8; +} + +td.tbtv_headercell a { + margin: 0px auto; + display: block; + color: black; } -span.unreadmailsubject { - font-weight: bold; +td.tbtv_headercell a:hover { + margin: 0px auto; + display: block; + color: black; + text-decoration: none; + /* background-color: #C4C0B8; */ +} + +span.mailer_datefield { + white-space: nowrap; +} + +div.mailer_readmailsubject { + /* TODO: use proper read icon */ + background-image: url(tbtv_leaf_corner_17x17.gif); + background-repeat: no-repeat; + background-position: 0px 0px; + padding-top: 1px; + padding-left: 20px; +} +div.mailer_unreadmailsubject { + /* TODO: use proper unread icon */ + background-image: url(tbtv_leaf_corner_17x17.gif); + background-repeat: no-repeat; + background-position: 0px 0px; + padding-left: 20px; + padding-top: 1px; + font-weight: bold; +} +div.mailer_readmailsubject a { + color: black; + text-decoration: none; +} +div.mailer_unreadmailsubject a { + color: black; + text-decoration: none; +} + +div.mailer_readicon { + /* TODO: use Thunderbird icon */ + background-image: url(icon_read.gif); + background-repeat: no-repeat; + background-position: 0px 4px; +} +div.mailer_readicon a { + width: 17px; + height: 17px; + margin: 0px auto; + display: block; +} +div.mailer_unreadicon { + /* TODO: use Thunderbird icon */ + background-image: url(icon_unread.gif); + background-repeat: no-repeat; + background-position: 0px 4px; +} +div.mailer_unreadicon a { + width: 17px; + height: 17px; + margin: 0px auto; + display: block; } diff --git a/SOGo/UI/Mailer/product.plist b/SOGo/UI/Mailer/product.plist index 68a4b7ec..492458f9 100644 --- a/SOGo/UI/Mailer/product.plist +++ b/SOGo/UI/Mailer/product.plist @@ -34,6 +34,13 @@ "tbtb_replyall.png", "tbtb_search.png", "tbtb_trash.png", + + "icon_mark_flagged.gif", + "icon_mark_read.gif", + "icon_mark_unflagged.gif", + "icon_mark_unread.gif", + "icon_read.gif", + "icon_unread.gif", "tbird_073_accountview.png", "tbird_073_compose.png", @@ -56,6 +63,17 @@ protectedBy = "View"; pageName = "UIxMailListView"; }; + + markMessageUnread = { + protectedBy = "View"; + pageName = "UIxMailListView"; + actionName = "markMessageUnread"; + }; + markMessageRead = { + protectedBy = "View"; + pageName = "UIxMailListView"; + actionName = "markMessageRead"; + }; }; }; -- 2.39.5