]> err.no Git - sope/commitdiff
a lot of enh in the display-group
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Fri, 5 Aug 2005 10:30:39 +0000 (10:30 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Fri, 5 Aug 2005 10:30:39 +0000 (10:30 +0000)
create NSManagedObjectContext if no EOEditingContext is available
improved error handling in template parser

git-svn-id: http://svn.opengroupware.org/SOPE/trunk@976 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-appserver/NGObjWeb/ChangeLog
sope-appserver/NGObjWeb/DynamicElements/WOString.m
sope-appserver/NGObjWeb/NGObjWeb/WODisplayGroup.h
sope-appserver/NGObjWeb/Templates/WOHTMLParser.m
sope-appserver/NGObjWeb/Version
sope-appserver/NGObjWeb/WOApplication.m
sope-appserver/NGObjWeb/WOComponentDefinition.m
sope-appserver/NGObjWeb/WODisplayGroup.m

index 471dec46c327ba0d303d6eed08209ee241744f06..34643760ee680be48f0441b86b2288f5fdb1758f 100644 (file)
@@ -1,3 +1,17 @@
+2005-08-05  Helge Hess  <helge.hess@opengroupware.org>
+
+       * v4.5.183
+       
+       * Templates/WOHTMLParser.m: improved error handling for hash-closetag
+         typos (will warn when a slash follows a hash, eg "<#/blub>")
+       
+       * WODisplayGroup.m: implemented -setSelectedObject:/-selectedObject,
+         changes -selectObject: to replace the full selection with the given
+         object (correct?), added delete/insert operations
+       
+       * WOApplication.m: also check for CoreData NSManagedObjectContext
+         when trying to locate an EOEditingContext like class
+
 2005-08-04  Helge Hess  <helge.hess@opengroupware.org>
 
        * minor code cleanups (v4.5.182)
index 6a53f42763beee4750662c528de43ae7399b2635..25590cc61efa81e4aaeee534da527b8bd303ee4d 100644 (file)
@@ -80,6 +80,7 @@
   WOAssociation *insertBR;   // insert <BR> tags for newlines
   WOAssociation *nilString;  // string to use if value is nil - DEPRECATED!
   WOAssociation *style;      // insert surrounding <span class="style">
+  // TODO: also add 'id' for span? (JavaScript tagging?)
 }
 
 @end /* WOComplexString */
index 499cf7948eebb8b00d79cbd67c5ddc92f9583118..7280945351cd08c215951e088f1bb2956cbb5cb4 100644 (file)
 - (BOOL)selectObject:(id)_obj;
 - (BOOL)selectObjectsIdenticalTo:(NSArray *)_objs;
 - (BOOL)selectObjectsIdenticalTo:(NSArray *)_objs
-            selectFirstOnNoMatch:(BOOL)_flag;
+  selectFirstOnNoMatch:(BOOL)_flag;
 
 /* objects */
 
 - (void)qualifyDisplayGroup;
 - (void)qualifyDataSource;
 
+/* object creation */
+
+- (id)insert;
+- (id)insertObjectAtIndex:(unsigned)_idx;
+- (void)insertObject:(id)_object atIndex:(unsigned)_idx;
+
+/* object deletion */
+
+- (id)delete;
+- (BOOL)deleteSelection;
+- (BOOL)deleteObjectAtIndex:(unsigned)_idx;
+
 @end
 
+
 @interface NSObject(WODisplayGroupDelegate)
 
 - (void)displayGroup:(WODisplayGroup *)_dg
   createObjectFailedForDataSource:(EODataSource *)_ds;
 
 - (BOOL)displayGroupShouldFetch:(WODisplayGroup *)_dg;
-- (void)displayGroup:(WODisplayGroup *)_dg
-  didFetchObjects:(NSArray *)_objects;
+- (void)displayGroup:(WODisplayGroup *)_dg didFetchObjects:(NSArray *)_objects;
 
-- (BOOL)displayGroup:(WODisplayGroup *)_dg
-  shouldInsertObject:(id)_object
+- (BOOL)displayGroup:(WODisplayGroup *)_dg shouldInsertObject:(id)_object
   atIndex:(unsigned int)_idx;
-- (void)displayGroup:(WODisplayGroup *)_dg
-  didInsertObject:(id)_object;
+- (void)displayGroup:(WODisplayGroup *)_dg didInsertObject:(id)_object;
 
-- (BOOL)displayGroup:(WODisplayGroup *)_dg
-  shouldDeleteObject:(id)_object;
-- (void)displayGroup:(WODisplayGroup *)_dg
-  didDeleteObject:(id)_object;
+- (BOOL)displayGroup:(WODisplayGroup *)_dg shouldDeleteObject:(id)_object;
+- (void)displayGroup:(WODisplayGroup *)_dg didDeleteObject:(id)_object;
 
 - (void)displayGroup:(WODisplayGroup *)_dg
   didSetValue:(id)_value forObject:(id)_object key:(NSString *)_key;
index 356c407080046dc377c1bc71a1301dc6872825e8..d8c64aeb9c6633b3206fa5092314acd0722a23b1 100644 (file)
@@ -461,6 +461,7 @@ static WOElement *_parseHashElement(NSZone *_zone, const unichar *_buffer,
   NSMutableArray *children   = nil;
   NSString       *name;
   NSDictionary   *nameDict;
+  BOOL hadSlashAfterHash;
   
   if (*_idx >= _len) return nil; // EOF
   
@@ -469,12 +470,18 @@ static WOElement *_parseHashElement(NSZone *_zone, const unichar *_buffer,
   
   // skip '<#'
   *_idx += 2;
+  hadSlashAfterHash = (_buffer[*_idx] == '/') ? YES : NO;
+  
+  if (hadSlashAfterHash) {
+    /* a tag starting like this: "<#/", probably an type */
+    [self warnWithFormat:@"typo in hash close tag ('<#/' => '</#')."];
+  }
   
   if ((name = _parseStringValue(_zone, _buffer, _idx,_len,_exc,self)) == nil) {
 #if HEAVY_DEBUG
     [self errorWithFormat:@"got no name for hash tag '<#NAME>'"];
 #endif
-    if (_exc) // if there was an error ..
+    if (_exc != nil) // if there was an error ..
       return nil;
   }
   
index b14095bcd334312ce58ac99fb71406b8924315eb..5d06ea3d83d7ae786551c348fe678834e04d668b 100644 (file)
@@ -1,6 +1,6 @@
 # version file
 
-SUBMINOR_VERSION:=182
+SUBMINOR_VERSION:=183
 
 # v4.5.122 requires libNGExtensions v4.5.153
 # v4.5.91  requires libNGExtensions v4.5.134
index e7201e5debd381b0edfc53c7b6caef3c07517001..a0e86416012f478f3e0784eb292bdb56d6bf661d 100644 (file)
@@ -1287,7 +1287,8 @@ nbuckets, nindices, narrays, idxsize);
   static BOOL  lookedUpForEOEditingContextClass = NO;
   
   if (!lookedUpForEOEditingContextClass) {
-    eoEditingContextClass = NSClassFromString(@"EOEditingContext");
+    if ((eoEditingContextClass = NSClassFromString(@"EOEditingContext")) ==nil)
+      eoEditingContextClass = NSClassFromString(@"NSManagedObjectContext");
     lookedUpForEOEditingContextClass = YES;
   }
   return eoEditingContextClass;
index 6e109242c143356c83b8b17ca3bb4af36f35260b..765470bff2aa36363a33f8517e27fd534497aa8d 100644 (file)
@@ -367,6 +367,10 @@ static NSArray *woxExtensions = nil;
     
     object = [unarchiver decodeObjectForKey:key];
     [_component takeValue:object forKey:key];
+    
+#if DEBUG_WOO
+    [self logWithFormat:@"unarchived %@: %@", key, object];
+#endif
   }
   [unarchiver finishInitializationOfObjects];
   [unarchiver awakeObjects];
@@ -396,7 +400,7 @@ static NSArray *woxExtensions = nil;
 }
 
 - (void)_finishInitializingComponent:(WOComponent *)_component {
-  if (self->baseUrl)
+  if (self->baseUrl != nil)
     [_component setBaseURL:self->baseUrl];
 
   if (enableWOOFiles) {
index 04124f873c1f6e45c7c9f6233924c354d943e07c..b727b80b3f7d2bb80575718587d8188ef99d433c 100644 (file)
@@ -371,10 +371,31 @@ static NSArray  *uint0Array = nil;
 }
 
 - (void)setSelectedObject:(id)_obj {
-  [self warnWithFormat:@"%s not implemented.", __PRETTY_FUNCTION__];
+  unsigned idx;
+  NSNumber *idxNumber;
+  
+  // TODO: maybe we need to retain the selection array and just swap the first
+  
+  idx = [self->objects indexOfObject:_obj];
+  idxNumber = (idx != NSNotFound) ? [NSNumber numberWithUnsignedInt:idx] : nil;
+
+  if (idxNumber != nil)
+    [self setSelectionIndexes:[NSArray arrayWithObjects:&idxNumber count:1]];
+  else
+    [self setSelectionIndexes:nil];
 }
 - (id)selectedObject {
-  return nil;
+  unsigned int i, sCount;
+  
+  if ((sCount = [self->selectionIndexes count]) == 0)
+    return nil;
+  
+  i = [[self->selectionIndexes objectAtIndex:0] unsignedIntValue];
+  if (i >= [self->objects count])
+    return nil;
+  
+  // TODO: need to ensure selection is in displayedObjects?
+  return [self->objects objectAtIndex:i];
 }
 
 - (void)setSelectedObjects:(NSArray *)_objs {
@@ -389,7 +410,7 @@ static NSArray  *uint0Array = nil;
   oCount = [self->objects count];
   result = [NSMutableArray arrayWithCapacity:sCount];
   
-  for (i=0; i<sCount; i++) {
+  for (i = 0; i < sCount; i++) {
     unsigned int idx;
 
     idx = [[self->selectionIndexes objectAtIndex:i] unsignedIntValue];
@@ -399,27 +420,35 @@ static NSArray  *uint0Array = nil;
   return result;
 }
 
-/* returns YES if displayedObjects contains _obj otherwise NO */
 - (BOOL)selectObject:(id)_obj {
+  /* returns YES if displayedObjects contains _obj otherwise NO */
   NSNumber *idxNumber;
   unsigned idx;
   
   if (![self->displayObjects containsObject:_obj])
     return NO;
+  
+  idx = [self->objects indexOfObject:_obj];
+  idxNumber = (idx != NSNotFound) ? [NSNumber numberWithUnsignedInt:idx] : nil;
 
-  idx = [self->displayObjects indexOfObject:_obj];
-  idxNumber = [NSNumber numberWithUnsignedInt:idx];
+  // TODO: should we just exchange the first item and/or call
+  //       -setSelectedObject: ?
   
+#if 0 /* this was wrong? */
   if ([self->selectionIndexes containsObject:idxNumber])
+    /* already selected => could be many => move to top? */
     return YES;
-  else {
-    NSMutableArray *tmp;
-
-    tmp = [NSMutableArray arrayWithObjects:self->selectionIndexes];
-    [tmp addObject:idxNumber];
-    [self setSelectionIndexes:tmp];
-    return YES;
-  }
+  
+  tmp = [NSMutableArray arrayWithObjects:self->selectionIndexes];
+  [tmp addObject:idxNumber];
+  [self setSelectionIndexes:tmp];
+#else
+  if (idxNumber != nil)
+    [self setSelectionIndexes:[NSArray arrayWithObjects:&idxNumber count:1]];
+  else
+    [self setSelectionIndexes:nil];
+#endif
+  return YES;
 }
 
 
@@ -464,7 +493,7 @@ static NSArray  *uint0Array = nil;
 }
 
 - (BOOL)selectObjectsIdenticalTo:(NSArray *)_objs
-            selectFirstOnNoMatch:(BOOL)_flag
+  selectFirstOnNoMatch:(BOOL)_flag
 {
   if ([self selectObjectsIdenticalTo:_objs])
     return YES;
@@ -498,7 +527,7 @@ static NSArray  *uint0Array = nil;
 - (id)fetch {
   NSArray *objs;
   
-  if ([self->delegate respondsToSelector:@selector(displayGroupShouldFetch:)]) {
+  if ([self->delegate respondsToSelector:@selector(displayGroupShouldFetch:)]){
     if (![self->delegate displayGroupShouldFetch:self])
       /* delegate rejected fetch-request */
       return nil;
@@ -520,9 +549,11 @@ static NSArray  *uint0Array = nil;
     
     if ([objs count] > 0)
       [self setSelectedObject:[objs objectAtIndex:0]];
-  }  
-  return nil;
+  }
+  
+  return nil /* stay on page */;
 }
+
 - (void)updateDisplayedObjects {
   NSArray *darray; // display  objects
   NSArray *sarray; // selected objects
@@ -534,13 +565,11 @@ static NSArray  *uint0Array = nil;
     darray = [self->delegate displayGroup:self
                              displayArrayForObjects:[self allObjects]];
 
-    darray = [darray copy];
-    RELEASE(self->displayObjects);
-    self->displayObjects = darray;
-
+    ASSIGNCOPY(self->displayObjects, darray);
     return;
   }
-  else {
+  
+  {
 //    EOQualifier *q;
     NSArray     *so, *ao;
     
@@ -634,13 +663,13 @@ static NSArray  *uint0Array = nil;
                               operatorSelector:ops
                               value:value];
     [quals addObject:q];
-    RELEASE(q); q = nil;
+    [q release]; q = nil;
   }
   
   /* construct min qualifiers */
 
   keys = [qmin keyEnumerator];
-  while ((key = [keys nextObject])) {
+  while ((key = [keys nextObject]) != nil) {
     EOQualifier *q;
     id value;
     
@@ -651,13 +680,13 @@ static NSArray  *uint0Array = nil;
                               operatorSelector:EOQualifierOperatorGreaterThan
                               value:value];
     [quals addObject:q];
-    RELEASE(q);
+    [q release];
   }
 
   /* construct max qualifiers */
 
   keys = [qmax keyEnumerator];
-  while ((key = [keys nextObject])) {
+  while ((key = [keys nextObject]) != nil) {
     EOQualifier *q;
     id value;
     
@@ -668,51 +697,51 @@ static NSArray  *uint0Array = nil;
                               operatorSelector:EOQualifierOperatorLessThan
                               value:value];
     [quals addObject:q];
-    RELEASE(q);
+    [q release];
   }
 
   if ([quals count] == 0)
     return nil;
-  else if ([quals count] == 1)
+  if ([quals count] == 1)
     return [quals objectAtIndex:0];
-  else
-    return AUTORELEASE([[EOAndQualifier alloc] initWithQualifierArray:quals]);
+  
+  return [[[EOAndQualifier alloc] initWithQualifierArray:quals] autorelease];
 }
 
 - (NSMutableDictionary *)queryBindings {
   if (self->_queryBindings == nil)
-    self->_queryBindings = [[NSMutableDictionary alloc] init];
+    self->_queryBindings = [[NSMutableDictionary alloc] initWithCapacity:8];
   return self->_queryBindings;
 }
 - (NSMutableDictionary *)queryMatch {
   if (self->_queryMatch == nil)
-    self->_queryMatch = [[NSMutableDictionary alloc] init];
+    self->_queryMatch = [[NSMutableDictionary alloc] initWithCapacity:8];
   return self->_queryMatch;
 }
 - (NSMutableDictionary *)queryMin {
   if (self->_queryMin == nil)
-    self->_queryMin = [[NSMutableDictionary alloc] init];
+    self->_queryMin = [[NSMutableDictionary alloc] initWithCapacity:8];
   return self->_queryMin;
 }
 - (NSMutableDictionary *)queryMax {
   if (self->_queryMax == nil)
-    self->_queryMax = [[NSMutableDictionary alloc] init];
+    self->_queryMax = [[NSMutableDictionary alloc] initWithCapacity:8];
   return self->_queryMax;
 }
 - (NSMutableDictionary *)queryOperator {
   if (self->_queryOperator == nil)
-    self->_queryOperator = [[NSMutableDictionary alloc] init];
+    self->_queryOperator = [[NSMutableDictionary alloc] initWithCapacity:8];
   return self->_queryOperator;
 }
 
 - (void)setDefaultStringMatchFormat:(NSString *)_tmp {
-  ASSIGN(self->defaultStringMatchFormat, _tmp);
+  ASSIGNCOPY(self->defaultStringMatchFormat, _tmp);
 }
 - (NSString *)defaultStringMatchFormat {
   return self->defaultStringMatchFormat;
 }
 - (void)setDefaultStringMatchOperator:(NSString *)_tmp {
-  ASSIGN(self->defaultStringMatchOperator, _tmp);
+  ASSIGNCOPY(self->defaultStringMatchOperator, _tmp);
 }
 - (NSString *)defaultStringMatchOperator {
   return self->defaultStringMatchOperator;
@@ -768,7 +797,7 @@ static NSArray  *uint0Array = nil;
 - (void)qualifyDisplayGroup {
   EOQualifier *q;
 
-  if ((q = [self qualifierFromQueryValues]))
+  if ((q = [self qualifierFromQueryValues]) != nil)
     [self setQualifier:q];
   
   [self updateDisplayedObjects];
@@ -783,7 +812,7 @@ static NSArray  *uint0Array = nil;
 
   ds = [self dataSource];
   
-  if ((q = [self qualifierFromQueryValues]))
+  if ((q = [self qualifierFromQueryValues]) != nil)
     [self setQualifier:q];
 
   if ([ds respondsToSelector:@selector(setAuxiliaryQualifier:)])
@@ -803,6 +832,197 @@ static NSArray  *uint0Array = nil;
     [self setInQueryMode:NO];
 }
 
+
+/* object creation */
+
+- (id)insert {
+  unsigned idx;
+
+  idx = [self->selectionIndexes count] > 0
+    ? ([[self->selectionIndexes objectAtIndex:0] unsignedIntValue] + 1)
+    : [self->objects count];
+  
+  return [self insertObjectAtIndex:idx]; /* returns 'nil' */
+}
+
+- (id)insertObjectAtIndex:(unsigned)_idx {
+  id newObject;
+  
+  if ((newObject = [[self dataSource] createObject]) == nil) {
+    [self errorWithFormat:@"Failed to create new object in datasource: %@",
+           [self dataSource]];
+    
+    if ([self->delegate respondsToSelector:
+              @selector(displayGroup:createObjectFailedForDataSource:)]) {
+      [self->delegate displayGroup:self 
+                     createObjectFailedForDataSource:[self dataSource]];
+    }
+    return nil /* refresh page */;
+  }
+
+  /* apply default values */
+  
+  [newObject takeValuesFromDictionary:[self insertedObjectDefaultValues]];
+  
+  /* insert */
+
+  [self insertObject:newObject atIndex:_idx];
+  
+  return nil /* refresh page */;
+}
+
+- (void)insertObject:(id)_o atIndex:(unsigned)_idx {
+  NSMutableArray *ma;
+  
+  /* ask delegate whether we should insert */
+  if ([self->delegate respondsToSelector:
+            @selector(displayGroup:shouldInsertObject:atIndex:)]) {
+    if (![self->delegate displayGroup:self shouldInsertObject:_o atIndex:_idx])
+      return;
+  }
+  
+  /* insert in datasource */
+  
+  [[self dataSource] insertObject:_o];
+  
+  /* update object-array (ignores qualifier for new objects!) */
+  
+  ma = [self->objects mutableCopy];
+  if (_idx <= [ma count])
+    [ma insertObject:_o atIndex:_idx];
+  else
+    [ma addObject:_o];
+  
+  [self setObjectArray:ma];
+  [ma release]; ma = nil;
+  [self updateDisplayedObjects];
+
+  /* select object */
+  
+  [self selectObject:_o]; // TODO: or use setSelectedObject:?
+  
+  /* let delegate know */
+  if ([self->delegate respondsToSelector:
+            @selector(displayGroup:didInsertObject:)])
+    [self->delegate displayGroup:self didInsertObject:_o];
+}
+
+
+/* object deletion */
+
+- (id)delete {
+  [self deleteSelection];
+  return nil;
+}
+
+- (BOOL)deleteSelection {
+  NSArray  *objsToDelete;
+  unsigned i, count;
+  
+  objsToDelete = [[[self selectedObjects] shallowCopy] autorelease];
+
+  for (i = 0, count = [objsToDelete count]; i < count; i++) {
+    unsigned idx;
+    
+    idx = [self->objects indexOfObject:[objsToDelete objectAtIndex:i]];
+    if (idx == NSNotFound) {
+      [self errorWithFormat:@"Did not find object in selection: %@",
+             objsToDelete];
+      return NO;
+    }
+    
+    if (![self deleteObjectAtIndex:idx])
+      return NO;
+  }
+  return YES;
+}
+
+- (BOOL)deleteObjectAtIndex:(unsigned)_idx {
+  NSMutableArray *ma;
+  id   object;
+  BOOL ok;
+
+  /* find object */
+  
+  object = (_idx < [self->objects count])
+    ? [[[self->objects objectAtIndex:_idx] retain] autorelease]
+    : nil;
+  // TODO: check for nil?
+  
+  /* ask delegate */
+  
+  if ([self->delegate respondsToSelector:
+            @selector(displayGroup:shouldDeleteObject:)]) {
+    if (![self->delegate displayGroup:self shouldDeleteObject:object])
+      return NO;
+  }
+  
+  /* delete in datasource */
+  
+  ok = YES;
+  NS_DURING
+    [[self dataSource] deleteObject:object];
+  NS_HANDLER
+    *(&ok) = NO;
+  NS_ENDHANDLER;
+
+  if (!ok)
+    return NO;
+  
+  /* update array */
+  
+  ma = [self->objects mutableCopy];
+  [ma removeObject:object];
+  [self setObjectArray:ma];
+  [ma release]; ma = nil;
+  [self updateDisplayedObjects];
+  
+  /* notify delegate */
+
+  if ([self->delegate respondsToSelector:
+            @selector(displayGroup:didDeleteObject:)])
+    [self->delegate displayGroup:self didDeleteObject:object];
+  return YES;
+}
+
+
+/* master / detail */
+
+- (BOOL)hasDetailDataSource {
+  return [[self dataSource] isKindOfClass:[EODetailDataSource class]];
+}
+
+- (void)setDetailKey:(NSString *)_key {
+  // TODO: fix me, probably we want to store the key for later
+#if 0
+  EODataSource *ds;
+  
+  if ([(ds = [self dataSource]) respondsToSelector:_cmd])
+    [(EODetailDataSource *)ds setDetailKey:_key];
+#endif
+}
+- (NSString *)detailKey {
+  EODataSource *ds;
+  
+  return ([(ds = [self dataSource]) respondsToSelector:_cmd])
+    ? [(EODetailDataSource *)ds detailKey] : nil;
+}
+
+- (void)setMasterObject:(id)_object {
+  [[self dataSource] qualifyWithRelationshipKey:[self detailKey]
+                    ofObject:_object];
+  
+  if ([self fetchesOnLoad])
+    [self fetch];
+}
+- (id)masterObject {
+  EODataSource *ds;
+  
+  return ([(ds = [self dataSource]) respondsToSelector:_cmd])
+    ? [(EODetailDataSource *)ds masterObject] : nil;
+}
+
+
 /* KVC */
 
 - (void)takeValue:(id)_value forKeyPath:(NSString *)_keyPath {
@@ -870,14 +1090,6 @@ static NSArray  *uint0Array = nil;
   [self notImplemented:_cmd];
 }
 
-/* description */
-
-- (NSString *)description {
-  return [NSString stringWithFormat:@"<0x%08X %@: ds=%@>",
-                     self, NSStringFromClass([self class]),
-                     [self dataSource]];
-}
-
 /* KVCArchiving */
 
 - (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
@@ -914,6 +1126,11 @@ static NSArray  *uint0Array = nil;
              forKey:@"selectFirstAfterFetch"];
 }
 
+- (void)awakeFromKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
+  if ([self fetchesOnLoad])
+    [self fetch];
+}
+
 /* EOEditorsImpl */
 
 - (void)editingContextWillSaveChanges:(id)_ec {
@@ -937,4 +1154,12 @@ static NSArray  *uint0Array = nil;
   return NO;
 }
 
+/* description */
+
+- (NSString *)description {
+  return [NSString stringWithFormat:@"<0x%08X %@: ds=%@>",
+                     self, NSStringFromClass([self class]),
+                     [self dataSource]];
+}
+
 @end /* WODisplayGroup */