home *** CD-ROM | disk | FTP | other *** search
/ OpenStep (Enterprise) / OpenStepENTCD.toast / OEDEV / EODEV.Z / EODisplayGroup.h < prev    next >
Encoding:
Text File  |  1996-09-09  |  15.9 KB  |  367 lines

  1. // EODisplayGroup.h
  2. // Enterprise Objects Framework
  3. // Copyright (c)1993, NeXT Software, Inc. All rights reserved.
  4.  
  5. #import    <EOControl/EOControl.h>
  6.  
  7. @class EOAssociation;
  8.  
  9.  
  10. // EODisplayGroup holds a set of objects and a selection for display and
  11. // editing in the user interface.  EOAssociations "observe" displayGroups
  12. // and push the values of the displayGroups objects into UI controls.
  13.  
  14. @interface EODisplayGroup : NSObject <NSCoding>
  15. {
  16. @private    
  17.     EODataSource *_dataSource;
  18.     NSMutableArray *_allObjects;
  19.     NSMutableArray *_displayedObjects;
  20.     id _delegate;
  21.     NSArray *_selection;
  22.     struct {
  23.        unsigned selectsFirstObjectAfterFetch:1;
  24.         unsigned didChangeContents:1;
  25.         unsigned didChangeSelection:1;
  26.         unsigned autoFetch:1;
  27.         unsigned haveFetched:1;
  28.         unsigned validateImmediately:1;
  29.         unsigned optimisticRefresh:1;
  30.     unsigned _reserved:25;
  31.     } _flags;
  32.  
  33.     // Used for debugging.
  34.     NSArray *_sortOrdering;
  35.     EOQualifier *_qualifier;
  36.     NSArray *_localKeys;  // For IB inspector
  37.     NSMutableArray *_selectedObjects;
  38.     EOAssociation *_editingAssociation;
  39.     id _observerNotificationBeginProxy;
  40.     id _observerNotificationEndProxy;
  41.     int _updatedObjectIndex;
  42.     void *_reserved;
  43. }
  44.  
  45. - init;
  46.     // primitive initializer
  47.  
  48. - (void)setDataSource:(EODataSource *)dataSource;
  49. - (EODataSource *)dataSource;
  50.     // get/set the displayGroup's dataSource.
  51.  
  52. - (id)delegate;
  53. - (void)setDelegate:(id)aDelegate;
  54.     // get/set the displayGroup's delegate.
  55.  
  56. - (NSArray *)allObjects;
  57.     // Returns all data-bearing objects accessible through the displayGroup.
  58. - (NSArray *)displayedObjects;
  59.     // Sorted and filtered subset of allObjects that are displayed by the associations
  60.     // for this DisplayGroup.
  61. - (void)setObjectArray:(NSArray *)array;
  62.     // Set "allObjects" array for this DisplayGroup.
  63.     // Attempts to maintain the same set of selected objects from before the set.
  64.     // The array is automatically sorted and filtered via updateDisplayedObjects.
  65.     // The associations for the DisplayGroup are notified of the change in objects to
  66.     // update the UI.
  67.     // Note that adding and removing objects via setObjectArray: does not result in a
  68.     // insert or delete operation being sent to the dataSource; the set merely affects the UI.
  69.  
  70.  
  71. // selection is always in terms of the displayedObjects, not allObjects
  72. - (NSArray *)selectionIndexes;
  73.     // Returns the selection as an array of NSNumbers.
  74.  
  75. - (BOOL)setSelectionIndexes:(NSArray *)selection;
  76.     // Sets the selection as an array of NSNumbers.  The displayGroup sends
  77.     // -isDiscardAllowed to all its detail displayGroups, as a change in
  78.     // selection will cause detail displayGroups to change their data source.
  79.     // If any displayGroup returns NO the selection is NOT changed and NO is
  80.     // returned.  If an association attempts to change the selection and
  81.     // fails, the association should reset its selection by asking the
  82.     // displayGroup for the current selection.  Returns YES on success, NO on
  83.     // failure.
  84.  
  85. - (NSArray *)selectedObjects;
  86.     // Returns the selected objects.
  87. - (id)selectedObject;
  88.     // the first selected object, or nil if no selection
  89.  
  90. - (BOOL)selectObjectsIdenticalTo:(NSArray *)objectSelection;
  91.     // selects matching objects if any, or clears selection
  92.  
  93. - (BOOL)selectObjectsIdenticalTo:(NSArray *)objectSelection selectFirstOnNoMatch:(BOOL)selectFirstOnNoMatch;
  94.     // if selectFirstOnNoMatch==NO, will attempt to maintain
  95.     // previous selection indexes if no match.
  96.  
  97. - (BOOL)selectNext;
  98.     // This convenience method increments the selection.  If incrementing
  99.     // the selection would set the selection beyond the end of the array
  100.     // then the selection is set to 0.  If the previous selection was a
  101.     // multiple selection then the selection is set to the next record
  102.     // after the first item in the previous selection.  This method (and
  103.     // it's cover selectNext:) are useful for user interfaces that don't
  104.     // have widgets to directly control the selection.  Does not redisplay.
  105.     
  106. - (BOOL)selectPrevious;
  107.     // This convenience method decrements the selection.  If decrementing
  108.     // the selection would set the selection before the start of the array
  109.     // then the selection is set to the last object.  If the previous
  110.     // selection was a multiple selection then the selection is set to the
  111.     // previous record before the first item in the previous selection.
  112.     // This method (and it's cover selectPrevious:) are useful for user
  113.     // interfaces that don't have widgets to directly control the selection.
  114.     // Does not redisplay.
  115.     
  116. - (BOOL)clearSelection;
  117.     // Clears the selection.  Shortcut for sending -setSelection:with an
  118.     // empty array. Doesn't redisplay.
  119.  
  120. - (void)redisplay;
  121.     // Sends -contentsDidChange to all the associations.
  122.  
  123. - (BOOL)fetch;
  124.     // Sends -endEditing to the the editing association.  Sends -displayGroupWillFetch:
  125.     // to the delegate.  If the delegate agrees, sends fetchObjects calls [self setObjectArray:]
  126.     // with the results, sends -displayGroupDidFetch:to the delegate.
  127.     // Returns YES on success, NO on failure.
  128.  
  129. - (BOOL)deleteObjectAtIndex:(unsigned)anIndex;
  130.     // Sends -displayGroup:willDeleteObject:to the delegate.  If the delegate
  131.     // agrees, deletes the object, then sends -displayGroup:didDeleteObject:to
  132.     // the delegate.  If the selection can change -selectionDidChange is sent
  133.     // to the associations.  Finally -contentsDidChange is always sent to the
  134.     // associations.  Returns YES on success, NO on failure.
  135.  
  136. - (BOOL)deleteSelection;
  137.     // Iterates over the selection, sending -deleteObjectAtIndex:to self for
  138.     // each object in the selection.  Aborts the delete and return NO if
  139.     // any -deleteObjectAtIndex:message returns NO.  Returns YES if all
  140.     // objects are successfully deleted.
  141.  
  142. - (id)insertObjectAtIndex:(unsigned)anIndex;
  143.     // Asks the data source to create a new object using the createObject
  144.     // method.  The calls insertObject:atIndex:.
  145.  
  146. - (void)insertObject:newObject atIndex:(unsigned)anIndex;
  147.     // The newObject should be of an appropriate class for the displayGroup's
  148.     // data source.  A new object can be allocated using the data source's
  149.     // createObject method.
  150.  
  151. - (EOAssociation *)editingAssociation;
  152.     // the association, if any, currently editing a value vended by this displayGroup
  153.  
  154. - (NSArray *)observingAssociations;
  155.     // returns an array of all EOAssociations observing this DisplayGroup.
  156.     // (just filters the result of [EOObserverCenter observersForObject:self];
  157.  
  158. - (BOOL)endEditing;
  159.     // This method is invoked whenever the displayGroup needs to force an end
  160.     // to text editing.  It's invoked from -saveToObjects.
  161.     // Returnd no if the editingAssociation refuses to end editing (e.g.
  162.     // validation failure).
  163.  
  164. - (void)setSortOrdering:(NSArray *)keySortOrderArray;
  165. - (NSArray *)sortOrdering;
  166.     // an EOSortOrder array to be applied to all records upon fetch.
  167.     // [displayGroup updateDisplayedObjects] must be called after
  168.     // calling setSortOrdering: in order to apply the sort.
  169.  
  170. - (void)setQualifier:(EOQualifier *)qualifier;
  171. - (EOQualifier *)qualifier;
  172.     // an EOQualifier use to filter allObjects to the displayedObjects subset.
  173.     // [displayGroup updateDisplayedObjects] must be called after
  174.     // calling setQualifier: in order to apply the filter.
  175.  
  176. - (void)updateDisplayedObjects;
  177.     // resorts and filters the allObjects array to created an updated displayedObjects
  178.     // subset.  Updates the display accordingly.
  179.  
  180. - (void)setSelectsFirstObjectAfterFetch:(BOOL)yn;
  181. - (BOOL)selectsFirstObjectAfterFetch;
  182.     // Set/return the selection policy after fetching.  If YES and nothing
  183.     // was selected before the fetch then the first object will be selected.
  184.     // If YES and there was a previous selection the displayGroup will attempt
  185.     // to maintain that selection after the fetch.  If NO the displayGroup will
  186.     // not alter the selection.  The default is YES.
  187.  
  188. - (void)setValidatesChangesImmediately:(BOOL)yn;
  189. - (BOOL)validatesChangesImmediately;
  190.  
  191. - (void)setFetchesOnLoad:(BOOL)yn;
  192. - (BOOL)fetchesOnLoad;
  193.  
  194. - (void)setUsesOptimisticRefresh:(BOOL)yn;
  195. - (BOOL)usesOptimisticRefresh;
  196.     // When objects change in the EOEditingContext for an EODisplayGroup,
  197.     // by default the DisplayGroup refreshes all associations, even if
  198.     // none of its objects are in the EOEditingContext's notification change list.
  199.     // This "pessimistic" refresh is sometimes necessary because associations may
  200.     // display derived values (via key paths or business methods) that depend on
  201.     // objects other than those being displayed.  However, if for a particular UI,
  202.     // no such derived data is being displayed, usesOptimisticRefresh can be set
  203.     // to instruct the EODisplayGroup to refresh only if one of its objects
  204.     // were updated.  The default is NO.
  205.  
  206. - (NSArray *)localKeys;
  207. - (void)setLocalKeys:(NSArray *)newKeySet;
  208.     // Keys declared by the user in the inspector in IB.
  209.  
  210. @end
  211.  
  212.  
  213. @interface EODisplayGroup (EOAssociationInteraction)
  214.  
  215. // find out what changed
  216. - (BOOL)selectionChanged;
  217. - (BOOL)contentsChanged;
  218. - (int)updatedObjectIndex;
  219.     // When contentsChanged is set, if only one object was changed,
  220.     // the index of the changed object is returned.  If more than
  221.     // one object was changed, -1 is returned.  Associations can use this
  222.     // information to optimize redisplay.
  223.  
  224. // get values from the displayGroup for display
  225. - (id)valueForKey:(NSString *)key object:(id)object;
  226.     // the primitive for the following two methods.  This could
  227.     // call the edit context to get buffered edits (?) or call a
  228.     // delegate to allow displayGroup computed values.
  229.  
  230. - (id)selectedObjectValueForKey:(NSString *)key;
  231. - (id)valueForObjectAtIndex:(unsigned)index key:(NSString *)key;
  232.  
  233. // push user changes to the displayGroup.
  234. - (BOOL)setValue:(id)value forObject:(id)eo key:(NSString *)key;
  235.     // the primitive for the following three methods.  This could call
  236.     // the EC to push buffered edits, or allow the delegate to save special
  237.     // values for special keys.
  238.     // The method will invoke all available validation protocols, and present
  239.     // errors according to the displayGroups error handling policy.
  240.     // A return value of YES indicates, in a UI context, that the user
  241.     // can leave the field.
  242. - (BOOL)setSelectedObjectValue:value forKey:(NSString *)key;
  243. - (BOOL)setValue:(id)value forObjectAtIndex:(unsigned)index key:(NSString *)key;
  244.     // returns YES if the user can leave the field
  245.  
  246. // Allow displayGroup to handle local validation failures
  247. - (BOOL)association:(EOAssociation *)association failedToValidateValue:(NSString *)value forKey:(NSString *)key object:(id)eo errorDescription:(NSString *)errorDescription;
  248.     // returns YES if association should allow user to leave the field.
  249.     // DisplayGroup will decide how to handle error and how to present message.
  250.  
  251. - (void)associationDidBeginEditing:(EOAssociation *)association;
  252.     // called by association to tell displayGroup of pending UI changes. (e.g. dirty the
  253.     // document).
  254. - (void)associationDidEndEditing:(EOAssociation *)association;
  255.  
  256. @end
  257.  
  258. // EOEditingContext EOEditors methods
  259. @interface EODisplayGroup (EOEditors)
  260. - (BOOL)editorHasChangesForEditingContext:(EOEditingContext *)editingContext;
  261.     // Called by the EOEditingContext to determine if we have uncommitted edits.
  262.     // Returns YES if [self editingAssociation] != nil
  263.  
  264. - (void)editingContextWillSaveChanges:(EOEditingContext *)editingContext;
  265.     // If [self endEditing] returns NO, raise an exception.
  266.  
  267. @end
  268.  
  269.  
  270. // EOEditingContext EOMessageHandler methods
  271. @interface EODisplayGroup (EOMessageHandlers)
  272. - (void)editingContext:(EOEditingContext *)editingContext presentErrorMessage:(NSString *)message;
  273.     // Presents alert panel
  274.  
  275. @end
  276.  
  277.  
  278.  
  279. // These methods are simple convienience methods to facilitate target/action
  280. // connections in InterfaceBuilder.
  281. @interface EODisplayGroup (EODisplayGroupTargetAction)
  282.  
  283. - (void)selectNext:sender;
  284.     // This is a target-action cover for -selectNext.  Also sends
  285.     // -redisplay after changing the selection.
  286.  
  287. - (void)selectPrevious:sender;
  288.     // This is a target-action cover for -selectPrevious.  Also sends
  289.     // -redisplay after changing the selection.
  290.  
  291. - (void)fetch:sender;
  292.     // This is a target-action cover for -fetch.
  293.  
  294. - (void)insert:sender;
  295.     // Inserts an object after the selected object, or, if nothing is
  296.     // selected, at the end of the array.
  297.  
  298. - (void)delete:(id)sender;
  299.     // This is a target-action cover for -deleteObjectAtIndex:.  Deletes the
  300.     // first selected object, or, if nothing is selected the last object.
  301.  
  302. @end
  303.  
  304.  
  305. // This optional protocol describes the methods a delegate of the
  306. // EODisplayGroup may implement.
  307. @interface NSObject (EODisplayGroupDelegate)
  308.  
  309. - (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldRedisplayForEditingContextChangeNotification:(NSNotification *)notification;
  310.     // Sent when the EODisplayGroup receives an EOObjectsChangedInEditingContextNotification.
  311.     // By default, all associations are refreshed (i.e. a redisplay is performed).
  312.     // Delegate can override by looking at changes in notification userInfo and decide
  313.     // whether to refresh.
  314.  
  315. - (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldRefetchForInvalidatedAllObjectsNotification:(NSNotification *)notification;
  316.     // Sent when the EODisplayGroup receives an EOInvalidatedAllObjectsInStoreNotification
  317.     // from its EOEditingContext. By default, the DisplayGroup discards any pending
  318.     // changes from its associations and refetches its data from the dataSource.
  319.     // Delegate can override and prevent the refetch.
  320.  
  321. - (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldChangeSelectionToIndexes:(NSArray *)newIndexes;
  322. - (void)displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup;
  323.     // Sent when the selection changes.
  324.     
  325. - (BOOL)displayGroupShouldFetch:(EODisplayGroup *)displayGroup;
  326.     // Informs the delegate that the displayGroup is about to fetch.  If the
  327.     // delegate returns no the fetch fails; if the delegate returns YES
  328.     // the fetch proceeds.
  329.  
  330. - (void)displayGroup:(EODisplayGroup *)displayGroup didFetchObjects:(NSArray *)objects;
  331.     // Informs the delegate that the displayGroup has fetched object.
  332.  
  333. - (NSArray *)displayGroup:(EODisplayGroup *)displayGroup displayArrayForObjects:(NSArray *)objects;
  334.     // If the delegate implements this method, it is responsible returning a sorted and
  335.     // filtered version of the given array.  If the delegate does not implement this method
  336.     // and a sortOrdering and/or qualifier has been on the DisplayGroup, the displayGroup
  337.     // will filter the object using [objects filteredArrayUsingQualifier:[self qualifier]]
  338.     // and then sort them using [objects sortedArrayUsingKeyOrderArray:[self sortOrdering]];
  339.  
  340. - (void)displayGroup:(EODisplayGroup *)displayGroup didSetValue:(id)value forObject:(id)eo key:(NSString *)key;
  341.  
  342. - (void)displayGroup:(EODisplayGroup *)displayGroup createObjectFailedForDataSource:dataSource;
  343.  
  344. - (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldInsertObject:object atIndex:(unsigned)newIndex;
  345.     // If the delegate returns NO object is released and not inserted.
  346.  
  347. - (void)displayGroup:(EODisplayGroup *)displayGroup didInsertObject:object;
  348.     // Informs the delegate that the displayGroup has inserted object.
  349.  
  350.  
  351. - (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldDeleteObject:object;
  352.     // If the delegate returns NO object is not deleted.
  353.  
  354. - (void)displayGroup:(EODisplayGroup *)displayGroup didDeleteObject:object;
  355.     // Informs the delegate that the displayGroup has deleted object.
  356.  
  357. - (void)displayGroupDidChangeDataSource:(EODisplayGroup *)displayGroup;
  358.     // indicates that setDataSource: was called and the current dataSource
  359.     // has been changed.
  360.  
  361. - (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldDisplayAlertWithTitle:(NSString *)title message:(NSString *)message;
  362.     // Called before the DisplayGroup will call NSRunAlertPanel().  Delegate can intercept
  363.     // and supress alert or present it in another way.
  364.  
  365. @end
  366.  
  367.