2005-07-20 Helge Hess <helge.hess@opengroupware.org>
+ * v0.9.160
+
+ * Toolbars/SOGoMailFolder.toolbar: added bulk-delete button, removed
+ expunge button
+
+ * UIxMailView.m: added fragile base class check, send a constant etag
+ for the mail viewer, do not deliver content in the defaultAction in
+ case the etag didn't change, added jsonly support to trashAction
+
+ * UIxMailToolbar.m: use -resourceLookupLanguages, use
+ pageResourceManager instead of the toolbar component resourcemanager
+ for evaluating labels
+
* product.plist: map getMail on the accounts folder to a noop action
(#1491) (v0.9.159)
--- /dev/null
+# compiler flags
+
+ADDITIONAL_CPPFLAGS += \
+ -Wall -DCOMPILE_FOR_GSTEP_MAKE=1 \
+ -DUIX_MAILER_MAJOR_VERSION=$(MAJOR_VERSION) \
+ -DUIX_MAILER_MINOR_VERSION=$(MINOR_VERSION) \
+ -DUIX_MAILER_SUBMINOR_VERSION=$(SUBMINOR_VERSION)
- SOGoMailAccount - just show the standard mail account (tree at Inbox!)
- SoApplication - stop at the application object (show all folders)
+SOGoDontUseETagsForMailViewer - YES|NO
+- when enable SOGo won't tag mail viewers with an entity-tag (HTTP etag)
+ - the etag ensures that the viewer will only get resend to the browser when
+ it changed. In the case of IMAP4 this is never because URLs are one-time
+ IDs in the IMAP4 server and messages cannot be edited in IMAP4
+ - use the default for debugging (otherwise you won't see changes ...)
+
Notes
=====
( /* the toolbar groups */
( /* first group */
- {
- link = "getMail";
- cssClass = "tbicon_getmail"; label = "Get Mail";
- },
- {
- link = "#"; // "compose"; // target = "_blank";
- isSafe = NO;
- onclick = "clickedCompose(this);return false;";
- cssClass = "tbicon_compose"; label = "Write";
- },
+ { link = "getMail";
+ cssClass = "tbicon_getmail"; label = "Get Mail"; },
+
+ { link = "#"; // "compose"; // target = "_blank";
+ isSafe = NO;
+ onclick = "clickedCompose(this);return false;";
+ cssClass = "tbicon_compose"; label = "Write"; },
),
+
( // second group
- { link = "#"; isSafe = NO;
- onclick="openMessageWindowsForSelection(this, 'reply'); return false;";
- cssClass = "tbicon_reply"; label = "Reply"; },
- { link = "#"; isSafe = NO;
- onclick="openMessageWindowsForSelection(this, 'replyall'); return false;";
- cssClass = "tbicon_replyall"; label = "Reply All"; },
- { link = "#"; isSafe = NO;
- onclick="openMessageWindowsForSelection(this, 'forward'); return false;";
- cssClass = "tbicon_forward"; label = "Forward"; },
+ { link = "#"; isSafe = NO;
+ onclick="openMessageWindowsForSelection(this, 'reply'); return false;";
+ cssClass = "tbicon_reply"; label = "Reply"; },
+
+ { link = "#"; isSafe = NO;
+ onclick="openMessageWindowsForSelection(this, 'replyall'); return false;";
+ cssClass = "tbicon_replyall"; label = "Reply All"; },
+
+ { link = "#"; isSafe = NO;
+ onclick="openMessageWindowsForSelection(this, 'forward'); return false;";
+ cssClass = "tbicon_forward"; label = "Forward"; },
),
+
( // third group
- { link = "expunge"; isSafe = NO;
- enabled = clientObject.isDeleteAndExpungeAllowed;
- cssClass = "tbicon_delete"; label = "Expunge"; },
-/* TODO: enable when implemented
-// TODO: enable when delete works (#1212)
- { link = "#"; isSafe = NO;
- cssClass = "tbicon_delete"; label = "Delete"; },
-// TODO: enable when we know how to mark junk (#971)
- { link = "#"; isSafe = NO;
- cssClass = "tbicon_junk"; label = "Junk"; },
-*/
+ /* TODO: maybe this should be a default or get enabled with no trash writes
+ { link = "expunge"; isSafe = NO;
+ enabled = clientObject.isDeleteAndExpungeAllowed;
+ cssClass = "tbicon_delete"; label = "Expunge"; },
+ */
+
+ // TODO: rename to uixTrashSelectedMessages, be more consistent with
+ // SOGoMailObject.toolbar (trash AND delete button)
+ { link = "#"; isSafe = NO;
+ onclick = "uixDeleteSelectedMessages(this); return false;";
+ enabled = clientObject.isDeleteAndExpungeAllowed;
+ cssClass = "tbicon_delete"; label = "Delete"; },
+
+ /* TODO: enable when implemented
+ // TODO: enable when we know how to mark junk (#971)
+ { link = "#"; isSafe = NO;
+ cssClass = "tbicon_junk"; label = "Junk"; },
+ */
),
+
( // fourth group (folders)
- { link = "#"; onclick="return ctxFolderAdd(this)";
- enabled = "clientObject.isCreateAllowed";
- isSafe = NO;
- cssClass = "tbicon_folderadd"; label = "Create"; },
- { link = "#"; onclick="return ctxFolderDelete(this)";
- enabled = "clientObject.isCreateAllowed"; // TODO: correct?
- isSafe = NO;
- cssClass = "tbicon_folderdel"; label = "Delete"; },
+ { link = "#"; onclick="return ctxFolderAdd(this)";
+ enabled = "clientObject.isCreateAllowed";
+ isSafe = NO;
+ cssClass = "tbicon_folderadd"; label = "Create"; },
+ { link = "#"; onclick="return ctxFolderDelete(this)";
+ enabled = "clientObject.isCreateAllowed"; // TODO: correct?
+ isSafe = NO;
+ cssClass = "tbicon_folderdel"; label = "Delete"; },
),
+
( /* fourth group */
-/* TODO: enable when we can print (#1207)
- { link = "#"; cssClass = "tbicon_print"; label = "Print"; },
-*/
- { link = "#"; cssClass = "tbicon_stop"; label = "Stop"; },
+ /* TODO: enable when we can print (#1207)
+ { link = "#"; cssClass = "tbicon_print"; label = "Print"; },
+ */
+
+ { link = "#"; cssClass = "tbicon_stop"; label = "Stop"; },
)
)
- (NSString *)buttonLabel {
WOResourceManager *rm;
- NSArray *languages;
- WOContext *ctx;
NSString *key, *label;
-
- key = [[self buttonInfo] valueForKey:@"label"];
- /* lookup languages */
+ key = [[self buttonInfo] valueForKey:@"label"];
- ctx = [self context];
- languages = [ctx hasSession]
- ? [[ctx session] languages]
- : [[ctx request] browserLanguages];
-
/* lookup resource manager */
- if ((rm = [self resourceManager]) == nil)
+ if ((rm = [self pageResourceManager]) == nil)
rm = [[WOApplication application] resourceManager];
if (rm == nil)
[self warnWithFormat:@"missing resource manager!"];
/* lookup string */
label = [rm stringForKey:key inTableNamed:nil withDefaultValue:key
- languages:languages];
+ languages:[[self context] resourceLookupLanguages]];
return label;
}
@implementation UIxMailView
+static NSString *mailETag = nil;
+
++ (int)version {
+ return [super version] + 0 /* v2 */;
+}
+
++ (void)initialize {
+ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+
+ NSAssert2([super version] == 2,
+ @"invalid superclass (%@) version %i !",
+ NSStringFromClass([self superclass]), [super version]);
+
+ if ([ud boolForKey:@"SOGoDontUseETagsForMailViewer"]) {
+ NSLog(@"Note: usage of constant etag for mailer viewer is disabled.");
+ }
+ else {
+ mailETag = [[NSString alloc] initWithFormat:@"\"imap4url_%d_%d_%03d\"",
+ UIX_MAILER_MAJOR_VERSION,
+ UIX_MAILER_MINOR_VERSION,
+ UIX_MAILER_SUBMINOR_VERSION];
+ NSLog(@"Note: using constant etag for mail viewer: '%@'", mailETag);
+ }
+}
+
- (void)dealloc {
[self->currentAddress release];
[super dealloc];
- (id)defaultAction {
if ([self message] == nil) {
+ // TODO: redirect to proper error
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
reason:@"did not find specified message!"];
}
+
+ /* check etag to see whether we really must rerender */
+
+ if (mailETag != nil ) {
+ NSString *s;
+
+ if ((s = [[[self context] request] headerForKey:@"if-none-match"])) {
+ if ([s rangeOfString:mailETag].length > 0) { /* not perfectly correct */
+ /* client already has the proper entity */
+ [self logWithFormat:@"MATCH: %@ (tag %@)", s, mailETag];
+ [[[self context] response] setStatus:304 /* Not Modified */];
+ return [[self context] response];
+ }
+ }
+ }
return self;
}
if ((ex = [[self clientObject] trashInContext:[self context]]) != nil) {
id url;
+ if ([[[[self context] request] formValueForKey:@"jsonly"] boolValue])
+ /* called using XMLHttpRequest */
+ return ex;
+
url = [[ex reason] stringByEscapingURL];
url = [@"view?error=" stringByAppendingString:url];
return [self redirectToLocation:url];
}
+
+ if ([[[[self context] request] formValueForKey:@"jsonly"] boolValue]) {
+ /* called using XMLHttpRequest */
+ [[[self context] response] setStatus:200 /* OK */];
+ return [[self context] response];
+ }
if (![self isInlineViewer]) {
// if everything is ok, close the window (send a JS closing the Window)
- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
UIxMailRenderingContext *mctx;
+ if (mailETag != nil)
+ [[_ctx response] setHeader:mailETag forKey:@"etag"];
+
mctx = [[NSClassFromString(@"UIxMailRenderingContext")
alloc] initWithViewer:self context:_ctx];
[_ctx pushMailRenderingContext:mctx];
# version file
-SUBMINOR_VERSION:=159
+SUBMINOR_VERSION:=160
# v0.9.140 requires SoObjects/Mailer v0.9.100
# v0.9.134 requires libSOGo v0.9.41