+2004-10-02 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoMailFolder.[hm]: removed ability to restrict UID fetch range,
+ need to fetch all (qualifier matching!) UIDs anyway (v0.9.19)
+
2004-10-01 Helge Hess <helge.hess@opengroupware.org>
* more work on fetching mails (v0.9.18)
/* messages */
-- (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so
- range:(NSRange)_r;
+- (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so;
- (NSArray *)fetchUIDs:(NSArray *)_uids parts:(NSArray *)_parts;
@end
/* messages */
-- (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so
- range:(NSRange)_r
-{
+- (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so {
return [[self mailManager] fetchUIDsInURL:[self imap4URL]
- qualifier:_q sortOrdering:_so range:_r
+ qualifier:_q sortOrdering:_so
+ range:NSMakeRange(0, 100000)
password:[self imap4Password]];
}
- (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url
parts:(NSArray *)_parts password:(NSString *)_pwd
{
+ /*
+ Allowed fetch keys:
+ UID
+ BODY.PEEK[<section>]<<partial>>
+ BODYSTRUCTURE
+ ENVELOPE [this is a parsed header, but does not include type]
+ FLAGS
+ INTERNALDATE
+ RFC822
+ RFC822.HEADER
+ RFC822.SIZE
+ RFC822.TEXT
+ */
NGImap4Client *client;
NSDictionary *result;
-
+
if (_uids == nil)
return nil;
if ([_uids count] == 0)
# $Id$
-SUBMINOR_VERSION:=18
+SUBMINOR_VERSION:=19
2004-10-02 Helge Hess <helge.hess@opengroupware.org>
+ * more work on UI (v0.9.9)
+
* added formatters for mail list (v0.9.8)
* v0.9.7
@interface UIxMailListView : UIxComponent
{
+ NSArray *sortedUIDs; /* we always need to retrieve all anyway! */
+ NSArray *messages;
id message;
}
@implementation UIxMailListView
- (void)dealloc {
- [self->message release];
+ [self->sortedUIDs release];
+ [self->messages release];
+ [self->message release];
[super dealloc];
}
/* notifications */
- (void)sleep {
- [self->message release]; self->message = nil;
+ [self->sortedUIDs release]; self->sortedUIDs = nil;
+ [self->messages release]; self->messages = nil;
+ [self->message release]; self->message = nil;
+ [self logWithFormat:@"SLEEP"];
[super sleep];
}
return [[[self message] valueForKey:@"uid"] stringValue];
}
-- (NSArray *)messages {
- NSArray *uids;
- NSArray *msgs;
+/* fetching messages */
+
+- (NSArray *)fetchKeys {
+ /* Note: see SOGoMailManager.m for allowed IMAP4 keys */
+ static NSArray *keys = nil;
+ if (keys == nil)
+ keys = [[NSArray alloc] initWithObjects:@"FLAGS", @"ENVELOPE", nil];
+ return keys;
+}
+
+- (id)qualifier {
+ return nil;
+}
+
+- (NSString *)imap4SortKey {
+ return @"SUBJECT";
+}
- uids = [[self clientObject] fetchUIDsMatchingQualifier:nil
- sortOrdering:@"SUBJECT"
- range:NSMakeRange(0, 50)];
+- (NSRange)fetchRange {
+ return NSMakeRange(0, 50);
+}
+
+- (NSArray *)sortedUIDs {
+ if (self->sortedUIDs != nil)
+ return self->sortedUIDs;
+
+ self->sortedUIDs
+ = [[[self clientObject] fetchUIDsMatchingQualifier:[self qualifier]
+ sortOrdering:[self imap4SortKey]] retain];
+ return self->sortedUIDs;
+}
+- (unsigned int)totalMessageCount {
+ return [self->sortedUIDs count];
+}
+- (BOOL)showsAllMessages {
+ return ([[self sortedUIDs] count] <= [self fetchRange].length) ? YES : NO;
+}
+
+- (NSRange)fetchBlock {
+ NSRange r;
+ unsigned len;
+ NSArray *uids;
+
+ r = [self fetchRange];
+ uids = [self sortedUIDs];
+
+ /* only need to restrict if we have a lot */
+ if ((len = [uids count]) <= r.length) {
+ r.location = 0;
+ r.length = len;
+ return r;
+ }
- [self logWithFormat:@"#UIDs: %d", [uids count]];
-
- /*
- Allowed fetch keys:
- UID
- BODY.PEEK[<section>]<<partial>>
- BODYSTRUCTURE
- ENVELOPE [this is a parsed header, but does not include type]
- FLAGS
- INTERNALDATE
- RFC822
- RFC822.HEADER
- RFC822.SIZE
- RFC822.TEXT
- */
+ if (len < r.location) {
+#warning CHECK CONDITION (< vs <=)
+ /* out of range, recover at first block */
+ r.location = 0;
+ return r;
+ }
- msgs = [[self clientObject] fetchUIDs:uids
- parts:[NSArray arrayWithObjects:
- @"FLAGS",
- @"ENVELOPE",
- nil]];
- [self logWithFormat:@" msg #%d", [[msgs valueForKey:@"fetch"] count]];
- return [msgs valueForKey:@"fetch"];
+ if (r.location + r.length > len)
+ r.length = len - r.location;
+ return r;
+}
+- (unsigned int)firstMessageNumber {
+ return [self fetchBlock].location + 1;
+}
+- (unsigned int)lastMessageNumber {
+ NSRange r;
+
+ r = [self fetchBlock];
+ return r.location + r.length;
+}
+- (BOOL)hasPrevious {
+ return [self fetchBlock].location == 0 ? NO : YES;
+}
+- (BOOL)hasNext {
+ NSRange r = [self fetchBlock];
+ return r.location + r.length >= [[self sortedUIDs] count] ? NO : YES;
+}
+
+- (NSArray *)messages {
+ NSArray *uids;
+ NSArray *msgs;
+ NSRange r;
+ unsigned len;
+
+ if (self->messages != nil)
+ return self->messages;
+
+ r = [self fetchBlock];
+ uids = [self sortedUIDs];
+ if ((len = [uids count]) > r.length)
+ /* only need to restrict if we have a lot */
+ uids = [uids subarrayWithRange:r];
+
+ msgs = [[self clientObject] fetchUIDs:uids parts:[self fetchKeys]];
+ self->messages = [[msgs valueForKey:@"fetch"] retain];
+ return self->messages;
}
/* URL processing */
return [self redirectToLocation:@"view"];
}
+- (id)getMailAction {
+ // TODO: we might want to flush the caches?
+ return [self redirectToLocation:@"view"];
+}
+
@end /* UIxMailListView */
<a href="?sort=date"><var:string label:value="Date" /></a>
</td>
</tr>
-
+ <tr class="tableview">
+ <td colspan="4" class="tbtv_navcell" align="right">
+ <var:if condition="showsAllMessages">
+ <var:string value="sortedUIDs.count" />
+ <var:string label:value="messages" />
+ </var:if>
+
+ <var:if condition="showsAllMessages" const:negate="YES">
+ <var:if condition="hasPrevious">
+ <a href="prevBlock">prev</a> |
+ </var:if>
+
+ <var:string value="firstMessageNumber"/>
+ <var:string label:value="to" />
+ <var:string value="lastMessageNumber"/>
+ <var:string label:value="of" />
+ <var:string value="sortedUIDs.count" />
+
+ <var:if condition="hasNext">
+ | <a href="nextBlock">next</a>
+ </var:if>
+ </var:if>
+ </td>
+ </tr>
+
<var:foreach list="messages" item="message">
<tr class="tableview">
<td>
NSString *title;
NSString *rootURL;
NSString *userRootURL;
- id item;
+ id item;
+ BOOL hideFolderTree;
}
- (NSString *)rootURL;
/* accessors */
+- (void)setHideFolderTree:(BOOL)_flag {
+ self->hideFolderTree = _flag;
+}
+- (BOOL)hideFolderTree {
+ return self->hideFolderTree;
+}
+
- (void)setTitle:(NSString *)_value {
ASSIGNCOPY(self->title, _value);
}
-->
<table border="0">
<tr>
- <td class="tb_icon"><a href="#" class="tbicon_getmail"> </a></td>
- <td class="tb_icon"><a href="#" class="tbicon_compose"> </a></td>
- <td class="tb_icon"><a href="#" class="tbicon_addressbook"> </a></td>
+ <td class="tb_icon"
+ ><a href="getMail" class="tbicon_getmail"> </a></td>
+ <td class="tb_icon"><a href="compose" target="_blank"
+ class="tbicon_compose"> </a></td>
+ <td class="tb_icon"><a href="addressbook" target="addressbook"
+ class="tbicon_addressbook"> </a></td>
<td class="tb_spacer"> </td>
+
+ <!-- TODO: should do a form submit? -->
<td class="tb_icon"><a href="#" class="tbicon_reply" > </a></td>
<td class="tb_icon"><a href="#" class="tbicon_replyall"> </a></td>
<td class="tb_icon"><a href="#" class="tbicon_forward" > </a></td>
<td class="tb_spacer"> </td>
+
<td class="tb_icon"><a href="#" class="tbicon_delete"> </a></td>
<td class="tb_icon"><a href="#" class="tbicon_junk" > </a></td>
<td class="tb_spacer"> </td>
+
<td class="tb_icon"><a href="#" class="tbicon_print"> </a></td>
<td class="tb_icon"><a href="#" class="tbicon_stop" > </a></td>
</tr>
</tr>
<tr class="vertframerow">
<td width="100%" valign="top" class="vertframerow" colspan="2">
- <table width="100%">
- <tr>
- <td width="25%" valign="top" class="foldercell">
- <div class="titlediv">Folders</div>
- <div style="height: 95%">
- <div class="embedwhite_out">
- <div class="embedwhite_in">
- <var:component className="UIxMailTree" />
+ <var:if condition="hideFolderTree">
+ <var:component-content/>
+ </var:if>
+
+ <var:if condition="hideFolderTree" const:negate="YES">
+ <table width="100%">
+ <tr>
+ <td width="25%" valign="top" class="foldercell">
+ <div class="titlediv">Folders</div>
+ <div style="height: 95%">
+ <div class="embedwhite_out">
+ <div class="embedwhite_in">
+ <var:component className="UIxMailTree" />
+ </div>
</div>
</div>
- </div>
- </td>
- <td style="width: 6px;"> </td>
- <td valign="top" class="contentcell">
- <var:component-content/>
- </td>
- </tr>
- </table>
+ </td>
+ <td style="width: 6px;"> </td>
+ <td valign="top" class="contentcell">
+ <var:component-content/>
+ </td>
+ </tr>
+ </table>
+ </var:if>
</td>
</tr>
</table>
return [self redirectToLocation:url];
}
+- (id)getMailAction {
+ // TODO: we might want to flush the caches?
+ return [self redirectToLocation:@"view"];
+}
+
@end /* UIxMailView */
xmlns:uix="OGo:uix"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label"
- className="UIxPageFrame"
+ className="UIxMailMainFrame"
title="name"
+ const:hideFolderTree="1"
>
- <h4>Mail View</h4>
+ <table class="mailer_fieldtable">
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
+ <td class="mailer_subjectfieldvalue">Re: Statuslist</td>
+ </tr>
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="From"/>:</td>
+ <td class="mailer_fieldvalue">
+ <!-- compose link? -->
+ <a href="#">Maxime Wacker [mwacker@linagora.com]</a>
+ </td>
+ </tr>
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="Date"/>:</td>
+ <td class="mailer_fieldvalue">08.09.2004 15:32</td>
+ </tr>
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="To"/>:</td>
+ <td class="mailer_fieldvalue">
+ <!-- compose link? -->
+ <a href="#">Helge Hess [helge.hess@skyrix.com]</a>
+ </td>
+ </tr>
+ </table>
+
+ <div class="mailer_mailcontent">
+ a b c<br />
+ <img rsrc:src="tbird_073_viewer.png" />
+ </div>
+<!--
<a rsrc:href="tbird_073_viewer.png">screenshot</a>
-
+-->
</var:component>
# $Id$
-SUBMINOR_VERSION:=8
+SUBMINOR_VERSION:=9
/* mail tableview */
.tableview {
- font-size: 9pt;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
+ font-size: 9pt;
+ font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
vertical-align: top;
}
+td.tbtv_navcell {
+ 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 {
border-width: 1;
border-style: solid;
margin: 0px auto;
display: block;
}
+
+/* fields (key/value UI), eg used in mail viewer */
+
+table.mailer_fieldtable {
+ width: 100%;
+
+ border-bottom-color: #808080;
+ border-bottom-width: 1;
+ border-bottom-style: solid;
+}
+tr.mailer_fieldrow {
+ font-size: 9pt;
+ font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
+}
+td.mailer_fieldname {
+ padding-left: 24px;
+ text-align: right;
+ font-weight: bold;
+}
+td.mailer_fieldvalue {
+ width: 95%;
+}
+td.mailer_subjectfieldvalue {
+ font-weight: bold;
+}
+td.mailer_fieldvalue a {
+ text-decoration: underline;
+}
+
+div.mailer_mailcontent {
+ border-top-color: white;
+ border-top-width: 1;
+ border-top-style: solid;
+ background-color: white;
+}
pageName = "UIxMailListView";
actionName = "markMessageRead";
};
+ getMail = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ actionName = "getMail";
+ };
};
};
protectedBy = "View";
pageName = "UIxMailView";
};
+
+ getMail = {
+ protectedBy = "View";
+ pageName = "UIxMailView";
+ actionName = "getMail";
+ };
+
delete = {
protectedBy = "View";
pageName = "UIxMailView";