]> err.no Git - scalable-opengroupware.org/commitdiff
first version which can store draft infos
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Mon, 25 Oct 2004 22:26:00 +0000 (22:26 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Mon, 25 Oct 2004 22:26:00 +0000 (22:26 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@422 d1b88da0-ebda-0310-925b-ed51d893ca5b

13 files changed:
SOGo/Main/GNUmakefile.preamble
SOGo/SoObjects/Mailer/ChangeLog
SOGo/SoObjects/Mailer/SOGoDraftObject.h
SOGo/SoObjects/Mailer/SOGoDraftObject.m
SOGo/SoObjects/Mailer/Version
SOGo/UI/Mailer/ChangeLog
SOGo/UI/Mailer/UIxMailAccountView.wox
SOGo/UI/Mailer/UIxMailEditor.m
SOGo/UI/Mailer/UIxMailEditor.wox
SOGo/UI/Mailer/Version
SOGo/UI/Mailer/mailer.js
SOGo/UI/Mailer/product.plist
SOGo/UI/Mailer/uix.css

index dcfdd9ed46b75bafffa8d10346b4f51a2adbe0ac..e70c8e01a811bd455505dcae9fe99ca4d3a8288c 100644 (file)
@@ -9,6 +9,7 @@ ADDITIONAL_LIB_DIRS += \
        -L../../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \
        -L../../SOGoLogic/$(GNUSTEP_OBJ_DIR)/   \
         -L/usr/local/lib -L/usr/lib
+# todo: use syslibs
 
 ADDITIONAL_TOOL_LIBS += \
        -lSOGo                  \
index a88df095d0e10041a4e763aa14437f0d14c05d1e..c2f57fbb52b55ddaf88146bc56877093aec90064 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-25  Helge Hess  <helge.hess@opengroupware.org>
+
+       * SOGoDraftObject.m: added ability to manage a draft object folder
+         (v0.9.37)
+
 2004-10-21  Helge Hess  <helge.hess@opengroupware.org>
 
        * SOGoMailBaseObject.m: extract IMAP4 password from HTTP basic
index 203986884ed800a320e0e86dc534e9bb01b7970c..6e4cda410344011b2600394db4ca94c8159041ab 100644 (file)
   folder are some kind of "mail creation transaction".
 */
 
+@class NSString, NSArray, NSDictionary;
+
 @interface SOGoDraftObject : SOGoMailBaseObject
 {
+  NSString *path;
 }
 
+/* contents */
+
+- (NSDictionary *)fetchInfo;
+- (BOOL)storeInfo:(NSDictionary *)_info;
+
+- (NSArray *)fetchAttachmentNames;
+
 @end
 
 #endif /* __Mailer_SOGoDraftObject_H__ */
index 3e6c967c2ec3cbe50e9d109a20e871fbed6ce62e..8b7f3365108cd09e1cc6f4fe9ba31157296eb308 100644 (file)
 */
 
 #include "SOGoDraftObject.h"
+#include <NGExtensions/NSFileManager+Extensions.h>
 #include "common.h"
 
 @implementation SOGoDraftObject
 
 - (void)dealloc {
+  [self->path release];
   [super dealloc];
 }
 
+/* draft folder functionality */
+
+- (NSFileManager *)spoolFileManager {
+  return [[self container] spoolFileManager];
+}
+- (NSString *)userSpoolFolderPath {
+  return [[self container] userSpoolFolderPath];
+}
+- (BOOL)_ensureUserSpoolFolderPath {
+  return [[self container] _ensureUserSpoolFolderPath];
+}
+
+/* draft object functionality */
+
+- (NSString *)draftFolderPath {
+  if (self->path != nil)
+    return self->path;
+  
+  self->path = [[[self userSpoolFolderPath] stringByAppendingPathComponent:
+                                             [self nameInContainer]] copy];
+  return self->path;
+}
+- (BOOL)_ensureDraftFolderPath {
+  NSFileManager *fm;
+  
+  if (![self _ensureUserSpoolFolderPath])
+    return NO;
+  
+  if ((fm = [self spoolFileManager]) == nil) {
+    [self logWithFormat:@"ERROR: missing spool file manager!"];
+    return NO;
+  }
+  return [fm createDirectoriesAtPath:[self draftFolderPath] attributes:nil];
+}
+
+- (NSString *)infoPath {
+  return [[self draftFolderPath] 
+               stringByAppendingPathComponent:@".info.plist"];
+}
+
+/* contents */
+
+- (BOOL)storeInfo:(NSDictionary *)_info {
+  if (_info == nil) {
+    [self logWithFormat:@"WARNING: got no info to write for draft!"];
+    return NO;
+  }
+  if (![self _ensureDraftFolderPath]) {
+    [self logWithFormat:@"ERROR: could not create folder for draft!"];
+    return NO;
+  }
+  if (![_info writeToFile:[self infoPath] atomically:YES]) {
+    [self logWithFormat:@"ERROR: could not write info %@", [self infoPath]];
+    return NO;
+  }
+  return YES;
+}
+- (NSDictionary *)fetchInfo {
+  NSDictionary *info;
+  NSString *p;
+  
+  p = [self infoPath];
+  if (![[self spoolFileManager] fileExistsAtPath:p]) {
+    [self debugWithFormat:@"Note: info object does not yet exist: %@", p];
+    return nil;
+  }
+  
+  if ((info = [NSDictionary dictionaryWithContentsOfFile:p]) == nil)
+    [self logWithFormat:@"ERROR: dictionary broken at path: %@", p];
+  
+  return info;
+}
+
+- (NSArray *)fetchAttachmentNames {
+  NSMutableArray *ma;
+  NSFileManager  *fm;
+  NSArray        *files;
+  unsigned i, count;
+  
+  fm = [self spoolFileManager];
+  if ((files = [fm directoryContentsAtPath:[self draftFolderPath]]) == nil)
+    return nil;
+  
+  count = [files count];
+  ma    = [NSMutableArray arrayWithCapacity:count];
+  for (i = 0; i < count; i++) {
+    NSString *filename;
+    
+    filename = [files objectAtIndex:i];
+    if ([filename hasPrefix:@"."])
+      continue;
+    
+    [ma addObject:filename];
+  }
+  return ma;
+}
+
+- (BOOL)isValidAttachmentName:(NSString *)_name {
+  NSRange r;
+
+  if (![_name isNotNull])     return NO;
+  if ([_name length] == 0)    return NO;
+  if ([_name hasPrefix:@"."]) return NO;
+  
+  r = [_name rangeOfString:@"/"];
+  if (r.length > 0) return NO;
+  r = [_name rangeOfString:@".."];
+  if (r.length > 0) return NO;
+  r = [_name rangeOfString:@"~"];
+  if (r.length > 0) return NO;
+  
+  return YES;
+}
+
+- (BOOL)saveAttachment:(NSData *)_attachment withName:(NSString *)_name {
+  NSString *p;
+
+  if (_attachment == nil)
+    return NO;
+  
+  if (![self _ensureDraftFolderPath]) {
+    [self logWithFormat:@"ERROR: could not create folder for draft!"];
+    return NO;
+  }
+  if (![self isValidAttachmentName:_name])
+    return NO;
+  
+  p = [[self draftFolderPath] stringByAppendingPathComponent:_name];
+  return [_attachment writeToFile:p atomically:YES];
+}
+
 @end /* SOGoDraftObject */
index 734431d7d47737fd4fef07c44a54d6742a6cdf11..68464731a0365ddc933e92ef6bef0ed196c7705f 100644 (file)
@@ -1,6 +1,6 @@
 # Version file
 
-SUBMINOR_VERSION:=36
+SUBMINOR_VERSION:=37
 
 # v0.9.35 requires SOGoLogic v0.9.24
 # v0.9.34 requires SOGoLogic v0.9.22
index c9999d70855e3d1d76d73480417c229a9d8acd34..75de65408958581b96f922451cc2d6853ec98908 100644 (file)
@@ -1,3 +1,12 @@
+2004-10-25  Helge Hess  <helge.hess@opengroupware.org>
+
+       * v0.9.45
+
+       * uix.css: replaced invalid "text-color" with "color"
+       
+       * UIxMailEditor.wox: bind subject/text, can load/save info object in
+         draft
+
 2004-10-22  Marcus Mueller  <znek@mulle-kybernetik.com>
 
         * v0.9.44
index 0d5e4055339bf256f01929aeb6124d5f1273b10f..b35b46c493b863d1d1b03ffea82a0b17a886c8bb 100644 (file)
       <br />
 
       <div class="whitesec_title">Email</div><br />
-      <li><a href="">Read messages</a></li>
-      <li><a href="">Write a new message</a></li>
+      <li><a href="">Read messages (TBD: link)</a></li>
+      <li><a href="">Write a new message (TBD: link)</a></li>
       <br />
       <br />
 
+<!--
       <div class="whitesec_title">Accounts</div><br />
       <li><a href="">View settings for this account</a></li>
       <li><a href="">Create a new account</a> [TBD: not in Agenor]</li>
@@ -37,6 +38,7 @@
       <li><a href="">Offline settings</a> [TBD: not in Agenor]</li>
       <br />
       <br />
+-->
 
       <div class="whitesec_title">Screenshot</div><br />
       <a rsrc:href="tbird_073_accountview.png">screenshot</a>
index 532149ff5d461a1b18fe841a5db10d09dd3cb37e..a280c94c87cc0f2f3944215188783bdde9b0b713 100644 (file)
 
 @end
 
+#include <SOGo/SoObjects/Mailer/SOGoDraftObject.h>
 #include "common.h"
 
 @implementation UIxMailEditor
 
+static NSArray *infoKeys = nil;
+
++ (void)initialize {
+  infoKeys = [[NSArray alloc] initWithObjects:
+                               @"subject", @"text", @"to", @"cc", @"bcc", 
+                               @"from", @"replyTo",
+                             nil];
+}
+
 - (void)dealloc {
   [self->text    release];
   [self->subject release];
 
 /* accessors */
 
+- (void)setFrom:(NSString *)_ignore {
+}
+- (NSString *)from {
+#warning TODO: retrieve email of account using SOGoUserManager, -emailForUID:
+  return @"hh@skyrix.com";
+}
+- (void)setReplyTo:(NSString *)_ignore {
+}
+- (NSString *)replyTo {
+  /* we are here for future extensibility */
+  return @"";
+}
+
 - (void)setSubject:(NSString *)_value {
   ASSIGNCOPY(self->subject, _value);
 }
 - (NSString *)subject {
-  return self->subject;
+  return self->subject ? self->subject : @"";
 }
 
 - (void)setText:(NSString *)_value {
   ASSIGNCOPY(self->text, _value);
 }
 - (NSString *)text {
-  return self->text;
+  return [self->text isNotNull] ? self->text : @"";
 }
 
 - (void)setTo:(NSArray *)_value {
   ASSIGNCOPY(self->to, _value);
 }
 - (NSArray *)to {
-  return self->to;
+  return [self->to isNotNull] ? self->to : [NSArray array];
 }
 
 - (void)setCc:(NSArray *)_value {
   ASSIGNCOPY(self->cc, _value);
 }
 - (NSArray *)cc {
-  return self->cc;
+  return [self->cc isNotNull] ? self->cc : [NSArray array];
 }
 
 - (void)setBcc:(NSArray *)_value {
   ASSIGNCOPY(self->bcc, _value);
 }
 - (NSArray *)bcc {
-  return self->bcc;
+  return [self->bcc isNotNull] ? self->bcc : [NSArray array];
+}
+
+/* info loading */
+
+- (void)loadInfo:(NSDictionary *)_info {
+  if (![_info isNotNull]) return;
+  [self debugWithFormat:@"loading info ..."];
+  [self takeValuesFromDictionary:_info];
+}
+- (NSDictionary *)storeInfo {
+  [self debugWithFormat:@"storing info ..."];
+  return [self valuesForKeys:infoKeys];
 }
 
 /* requests */
 
 /* actions */
 
-- (id)saveAction {
-#if 0
-  NSException *ex;
+- (id)editAction {
+  [self logWithFormat:@"edit action, load content from: %@",
+         [self clientObject]];
+  
+  [self loadInfo:[[self clientObject] fetchInfo]];
+  return self;
+}
 
-  ex = [[self clientObject] saveContentString:content];
-  if (ex != nil) {
-    [self setErrorText:[ex reason]];
-    return self;
+- (id)saveAction {
+  NSDictionary *info;
+  
+  if ((info = [self storeInfo]) != nil) {
+    if (![[self clientObject] storeInfo:info]) {
+      [self logWithFormat:@"ERROR: failed to store draft!"];
+      // TODO: improve error handling
+      return nil;
+    }
   }
   
-  return [self redirectToLocation:[self _completeURIForMethod:@".."]];
-#else
+  [self logWithFormat:@"save action, store content to: %@",
+       [self clientObject]];
+  return self;
+}
+
+- (id)sendAction {
+  [self logWithFormat:@"send action, store content, send mail, store: %@",
+       [self clientObject]];
+  // if everything is ok, close the window (send a JS closing the Window)
   return self;
-#endif
 }
 
 @end /* UIxMailEditor */
index 2bdf5bca00259c81fa6173594e429254396086bf..e23d3faf5d23ac4066ae8df02c0d629acbe2ba58 100644 (file)
           <a rsrc:href="tbird_073_compose.png">Subject:</a>
         </td>
         <td width="85%"><input name="subject" 
-                               id="compose_subject_input" type="text" /></td>
+                               id="compose_subject_input" type="text" 
+                              var:value="subject" /></td>
       </tr>
     </table>
   </div>
 
   <!-- separator line -->
   <div id="compose_text">
-    <textarea name="content" />
+    <textarea name="content" var:value="text" />
   </div>
 
   <!-- img rsrc:src="tbird_073_compose.png" alt="screenshot" / -->
index 5ddff4f0ac4430f6f42c0a60ebd8e8a04a39d156..cd774cc61a29ee5b45392c598b63d772adc8f47b 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
-SUBMINOR_VERSION:=44
+SUBMINOR_VERSION:=45
 
 # v0.9.43 requires NGObjWeb v4.3.73
 # v0.9.42 requires NGObjWeb v4.3.72
index 4b2fc1d17ff5f50516d4f5a2876d12f4aa1e6326..821b78e2f51676bfe9fa859d230474c1dfed610b 100644 (file)
@@ -65,17 +65,19 @@ function clickedEditorSend(sender) {
   if (!validateEditorInput(sender))
     return false;
   
-  alert("SEND");
+  document.pageform.action="send";
+  document.pageform.submit();
   // if everything is ok, close the window
+  return true;
 }
 
 function clickedEditorAttach(sender) {
-  alert("ATTACH");
+  document.pageform.action="save";
+  document.pageform.submit();
+  return true;
 }
-
 function clickedEditorSave(sender) {
-  //field = document.pageform[":method"];
-  document.pageform.action="edit";
+  document.pageform.action="save";
   document.pageform.submit();
   return true;
 }
index 78e4848520d1fbaaf0a86df60e677997c94a86ec..ec3fe7cb5b1bcd2745d439ecc45bb4f7f8ffde23 100644 (file)
         edit = {
           protectedBy = "View";
           pageName    = "UIxMailEditor"; 
+          actionName  = "edit";
+        };
+        save = {
+          protectedBy = "View";
+          pageName    = "UIxMailEditor"; 
+          actionName  = "save";
+        };
+        send = {
+          protectedBy = "View";
+          pageName    = "UIxMailEditor"; 
+          actionName  = "send";
         };
         addressbook = {
           protectedBy = "View";
index de9a4fb47374bb6abdb73ace626378a393d46fed..9f1a5f8ba9e28bc29f5018d31d25c7075b0de3e5 100644 (file)
@@ -123,7 +123,7 @@ a:hover {
   font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
   letter-spacing:   0pt;
   text-decoration:  none;
-  text-color:       #000000;
+  color:            #000000;
   text-align:       center;
   vertical-align:   middle;
   padding-left:     5px;
@@ -163,7 +163,7 @@ a:hover {
   font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
   letter-spacing:   0pt;
   text-decoration:  none;
-  text-color:       #000000;
+  color:            #000000;
   text-align:       center;
   vertical-align:   middle;
   padding-left:     5px;