METHOD FOR ASSOCIATING DATA BEARING OBJECTS WITH USER INTERFACE OBJECTS

Abstract: The present method provides objects called association objects (350) that are interposed between a controlling object (340) and each user interface object (360). The association object for a particular kind of user interface object contains code that allows the association object to interact with the specific kind of user interface object. Each association object also presents a standard interface to a controlling object, regardless of the kind of user interface object with which the association object is associated. The association object takes care of any conversion or translation that must be performed to convert a data value sent by the controlling object into an appropriate value that can be displayed by the user interface object. Accordingly, instead of requiring different interface code for each kind of user interface object used (360), a controlling object (340) requires only a single block of interface code for communicating with all association objects (350).

Description: METHOD FOR ASSOCIATING DATA BEARING OBJECTS WITH USER INTERFACE OBJECTS BACKGROUND OF THE INVENTION 1. FIELD OF THE INVENTION The present invention relates to the field of object oriented programming languages. 2. BACKGROUND ART Object oriented programming languages are programming languages in which program elements are viewed as objects that can pass messages to each other. An object includes its own data and programming code and is internally self-reliant. The programming code of an object includes procedures or methods. The methods of an object are invoked by messages received from another object. Each object is an instance of an object class. The properties of the objects in a class are defined by a class definition. A class definition may utilize a hierarchical class structure in which objects in the class inherit properties of a parent class in addition to properties explicitly defined for the class. This inheritance property allows objects from to be reused from one program to another, facilitating the sharing of programming code between different programs. To write an application program in an object oriented programming language, a programmer identifies the real-world objects of a problem, the data and processing requirements of those objects, and the communications needed between the objects, and encapsulates these in class definitions. This process is simplified by taking advantage of the inheritance property of object classes by basing the class definitions to the extent possible on preexisting object classes. Objects are assembled in a modular fashion to create applications. Objects communicate with one another by means of messages. In order for meaningful communications to occur, the message sent from a sending object to a receiving object must be a message to which the receiving object can respond. The sending object must therefore know the type of message to which the receiving object will respond. Similarly, if the message is one that invokes a response from the receiving object, the sending object must be prepared to accept the response. Although objects are generally internally self-reliant, and can therefor be viewed as modules that can be assembled with other objects into a variety of application programs, the simple assembling of objects does not create a functional program. The objects must also be able to intercommunicate with each other. Although objects represent reusable code, additional code must be written to provide for the required communication between objects. For an object to communicate with a number of different objects, each of which send and receive different messages, the object must be provided with appropriate code for each of the different objects. An example is a controlling object that bears data and /or manages a number of data bearing objects and communicates with a number of user interface objects that display data provided by the controlling object to a user and accept input from a user. Figure 1 shows an example of the interactions between a prior art controller object 100 managing data bearing objects 105a to 105f and a graphical user interface 110. Graphical user interface 110 includes three kinds of user interface objects: a table object 120, two text field objects 130 and 140, respectively, and two check box objects 150 and 160, respectively. Each of these three kinds of user interface objects operates differently and responds to and generates different messages. Controller 100 therefore contains separate interface code for interfacing with each kind of object. Accordingly, controller 100 contains table object interface code 170, text field object interface code 180, and check box object interface code 190. Certain prior art object oriented programming environments provide user interfaces with a predefined structure. These predefined structures do not allow developers the freedom to easily assemble custom user interfaces. SUMMARY OF THE INVENTION The present invention comprises a method for allowing a controlling object to interface with any number of user interface objects without requiring separate interface code for each user interface object and without restricting the user interface to certain predetermined designs. The present method provides objects called association objects that are interposed between a controlling object and each user interface object. Each kind of user interface object has a corresponding association object. The association object for a particular kind of user interface object contains code that allows the association object to interact with the specific kind of user interface object with which it is associated. Each association object also presents a standard interface to a controlling object, regardless of the kind of user interface object with which the association object is associated. The association object takes care of any conversion or translation that must be performed to convert a data value sent by the controlling object into an appropriate value that can be displayed by the user interface object. Accordingly, instead of requiring different interface code for each kind of user interface object used, a controlling object requires only a single block of interface code for communicating with all association objects, which in turn provide the user interface specific code needed for each kind of user interface object. BRIEF DESCRIPTION OF THE DRAWINGS Figure 1 is a diagram of a controller object and user interface objects of the prior art. Figure 2 is a diagram of a controller object and user interface objects in one embodiment of the present invention. Figure 3 is a diagram of the architecture of an Enterprise Objects Framework application. Figure 4 is a diagram showing the relationship between data contained in a database and data contained in dictionary and enterprise objects in one embodiment of the present invention. Figure 5 is a flow chart for one embodiment of the present invention. Figure 6 A is a flow diagram illustrating "takeValuesFromDictionary". Figure 6B is a flow diagram illustrating "findMethod". Figure 6C is a flow diagram illustrating "findlnstance". Figure 7A is a flow diagram illustrating "valuesForKeys". Figure 7B is a flow diagram illustrating "returnMethod' Figure 7C is a flow diagram illustrating "returnlnstance" DETAILED DESCRIPTION OF THE INVENTION In the following description, numerous specific details are set forth in order to provide a thorough understanding of the present invention. It will be apparent to one skilled in the art, however, that the present invention may be practiced without these specific details. In other instances, well- known features have not been described in detail in order not to unnecessarily obscure the present invention. Figure 2 is a block diagram showing the relationship between a controlling object and user interface objects in one embodiment of the present invention. Figure 2 shows a controller object 100 that manages a number of data bearing objects 105a to 105f and a user interface 110 including a table object 120, two text field objects 130 and 140, respectively, and two check box objects 150 and 160 respectively. Controller 100 passes data between data bearing objects 105a to 105f and the various user interface objects 120, 130, 140, 150 and 160. However, instead of sending and receiving messages directly to and from the user interface objects as in the prior art system of Figure 1, in the embodiment of the present invention shown in Figure 2, controller 100 communicates indirectly with the user interface objects via "association" objects 210a, 210b, 210c, 220a, 220b, 230a and 230b that are interposed between controller 100 and each of user interface objects 205a, 205b, 205c, 130, 140, 150 and 160, respectively. Controller 100 sends and receives messages to and from the association objects, while the association objects send and receive messages to and from the user interface objects as well as to and from controller 100. The association objects present a consistent interface to controller 100. Accordingly, instead of having blocks o interface code for each of the three kinds of user interface objects contained in user interface 110 (i.e. table objects, text field objects, and check box objects), controller 100 needs only a single block of interface code with which it can communicate with any association object. The association objects in turn take care of any conversion or translation required between messages sent and received by controller 100 and messages sent and received by the various user interface objects. In the embodiment of the invention shown in Figure 2, a separate association object is utilized for each user interface object, even if there are several user interface objects of the same kind. Thus, in the embodiment of Figure 2, separate text field association objects 220a and 220b are used for each of text field objects 130 and 140, respectively. In the same manner, separate check box association objects 230a and 230b are used for each of check box objects 150 and 160, respectively, and separate table column association objects 210a, 210b and 210c are used for each column of table 205, which in this embodiment comprises table column objects 205a, 205b and 205c, respectively. In other embodiments, table 205 may comprise a single object and be associated with a single association. Association objects are objects provided by the present invention that can be utilized by a programmer to tie a controlling object to a variety of different kinds of user interface objects, without requiring the programmer to provide the controlling object with the code necessary to communicate with each type of user interface object. The controlling object need only be provided with the means to send and respond to standard messages. The association objects in turn take care of the message sending and receiving requirements specific to each kind of user interface object. The object oriented programming environment used with the embodiment of Figure 2 is particularly suited for the development of data base application programs. However, the method of the present invention can also be used for non-data base applications. The association objects of the present invention are useful particularly in a programming environment that provides a selection of user interface objects to a programmer. The present invention adds a pre-defined association for each user interface object provided by the programming environment. An application programmer wishing to display data from a controlling object can easily create an appropriate user interface by selecting the desired user interface object and linking it with the controlling object using the appropriate association object for the user interface object selected. A programmer may also develop custom user interface objects and corresponding association objects. The purpose of a user interface is to display data output to a user and to accept data input from a user. Although the specific mechanics of how data is displayed on a user interface or how it is received from a user varies depending upon the specific type of user interface object used, the basic underlying process is the same: a user interface object receives data from a controlling object and displays it, in some manner, on the user interface; if a change is made by the user on the user interface, that change is transmitted to the controlling object. The present invention allows the controlling object to deal with these basic underlying processes, while isolating the controlling object from any more complex control requirements of particular user interface objects. One embodiment of the present invention is used in "Enterprise Objects Framework (TM)", a set of tools and resources for the NEXTSTEP (TM) object oriented programming environment from NeXT Computer, Inc. Enterprise Objects Framework provides tools that enable program developers to design database applications that work with relational databases, that are easy to build and maintain, that communicate with other applications, and that utilize standard interface features. Enterprise Objects Framework is described in detail in Enterprise Objects Framework Developer's Guide (NeXT Computer, Inc., 1994) and Enterprise Objects Framework Reference (NeXT Computer, Inc., 1994), both of which are incorporated herein by reference. The architecture and data flow of an Enterprise Objects Framework application is shown in Figure 3. In the application shown in Figure 3, data flows from a relational database 300 to a user interface 360, and vice versa, via a number of intervening modules and levels. The flow of data from the relational database 300 to user interface 360 proceeds as follows. Data in the form of rows of data from relational database 300 are retrieved from relational database 300 to an adaptor level 310, using well-known relational database access techniques. At adaptor level 310, the raw data received from relational database 300 is packaged into "dictionary objects." Dictionary objects contain key-value pairs: each key typically represents the name of a database column, and the key's value corresponds to the data for the column of the particular row that was read from relational database 300. The key-value coding protocol used in Enterprise Objects Framework is described below in the section entitled Key- Value Coding Protocol. This key-value coding protocol is also described in co-pending U.S. Patent Application Serial No. 08/353,524 for "Dynamic Object Communication Protocol" filed on December 7, 1994, assigned to the assignee of the present invention, and incorporated herein by reference. As shown in Figure 3, data in the form of these dictionary objects is passed from adaptor level 310 to database level 320. Database level 320 creates "enterprise objects" from the dictionary objects. Enterprise objects are like other objects used in object oriented programming languages in that they couple data with methods for operating on that data. However, an enterprise object has certain characteristics that distinguish it from other object classes. An enterprise object has properties that map to stored data, and an instance of an enterprise object typically corresponds to a single row or record in a database. Further, an enterprise object knows how to interact with other parts of the Enterprise Object Framework to give and receive values for its properties. The ingredients tha make up an enterprise object are its class definition and the data values for the row or record to which it corresponds. The mechanism that enables an enterprise object to exchange its values with other objects is the Key Value Coding protocol referred to above and described below in the section entitled Key-Value Coding Protocol. The Key Value protocol also allows an object to set its values at runtime from a dictionary, as explained below. When an object is to be loaded with values from a dictionary, the methods and instance variables of the object are examined to determine if there is a match between keys in the dictionary and the object. This is accomplished by searching for the method "set (property)" where property is the column name or key in the dictionary. For example, with property named "lastName", the system looks for a method of the form "setLastName". If there is a match, the value of the property "lastName" can be loaded into the object using the setLastName method. If no methods produce a match, the system looks for an instance variable whose name is the same as the property's and sets is value directly. When a dictionary is to be loaded with values from an object, the properties of the dictionary are provided as an array. For each property, the methods of the object are examined to determine if they are of the form "property". If there is a match, the object's value for that method is returned to the dictionary. If there is no match, the instances of the object are examined. If an instance is found that matches the property, the value is returned to the dictionary. takeValuesFromDictionary The method for setting values in an object is implemented by "takeValuesFromDictionary". This method is implemented on the root object of the environment so that, in a class hierarchy system, every object inherits the method. In one embodiment, the default implementations of the key-value coding methods use the class definition as follows: 1. The key-value coding method looks for an accessor method based on the property name. For example, with a property named lastName, take ValuesFromDictionary: looks for a method of the form setLastName: (note that the first letter of the property name is made uppercase). If the key-value coding method doesn't find an accessor method, it looks for an instance variable whose name is the same as the property's and sets or retrieves its value directly. In setting an instance variable, takeValuesFromDictionary: retains the new value and releases the old one. The takeValuesFromDictionary method may be implemented as described in the pseudo code provided in the section entitled Pseudocode. The operation of takeValuesFromDictionary is illustrated in the flow diagrams of Figures 6A, 6B, and 6C. takeValuesFromDictionary Flow Referring first to Figure 6A takeValuesFromDictionary is illustrated. At decision block 602, the argument "All key-value pairs in dictionary processed?" is made. This step checks to see if the object has been examined for all dictionary pairs. If the argument at decision block 602 is true, the system ends at step 612. That means that all dictionary pairs have been processed for the object, and thus the method is completed. If the argument at decision block 602 is false, not all pairs have been processed. At step 604 th class description for the object is obtained and examined. At step 606, "findMethod" is executed to determine if the object has a set method with a name that matches a property of the key- value pair. This step is illustrated i more detail in Figure 6B. After findMethod has been executed at step 606, the system proceeds t decision block 608. At decision block 608, the argument "method found?" is made. This step is to determine whether there has been a match between th methods of the object and the property of the key-value pair. If the argumen at decision block 608 is true, a match has been found and the data can be loaded into the object. The routine of Figure 6 A ends at step 612. If the argument at decision block 608 is false, no methods match the property of th key-value pair and the system must then check the instances of the object. This is accomplished by invoking "findlnstance" at step 610. This step is illustrated in more detail in Figure 6C. After findlnstance has been executed, the system ends at step 612. findMethod Flow Step 606 of Figure 6A, "findMethod" is illustrated in more detail in Figure 6B. The process "findMethod" is used to examine the methods of the object being examined to determine if its methods match the properties of the key-value pairs being processed. At step 622, the method to be searched for is defined as being of the type "set" plus the property of the key being processed (e.g. if the property of the key-value pair is "lastName", then the system looks for "setLastName"). At step 624, the class description is examined for the method that is being searched. At decision block 626, the argument "method found?" is made. This is to determine if the object contains the method that is being searched. If the argument is false, findMethod ends at step 634 and returns to decision block 626 of Figure 6A. If the argument at decision block 626 is true, a match has been found. The system at 628 determines the argument type for the method. At step 630, the value of the key-value pair is converted to the argument type if necessary. At step 632, the method with the value as argument is called to load the data value into the object. At step 634, findMethod ends and returns to takeValuesFromDictionary of Figure 6 A. findlnstance Flow Step 610 of Figure 6 A, "findlnstance", is illustrated in Figure 6C. In the preferred embodiment of the present invention, the methods of an object are examined first when attempting to load data. If no suitable methods are found, the instance variables are examined using "findlnstance". At step 642, the class description of the object is examined to determine if there is an instance equal to the key property of the key-value pair being processed. At decision block 644, the argument "instance found?" is made. If the argument is false, that is if no instances match the property, the findlnstance process ends at step 644 and returns to step 612 of Figure 6A. If the argument at decision block 644 is true, a match between and instance variable and the key-value property has been found. The system then at step 646 determines the instance type. At step 648, the storage offset o the instance in the object is determined. At step 650, the value of the key- value pair being examined is converted to the object's instance type. At step 652, the value from the key-value pair is assigned to the instance in the objec using the previously determined instance offset. At step 654, findlnstance ends and returns to step 612 of Figure 6 A. valuesForKeys The method for loading a dictionary with values from an object is "valuesForKeys". The class definitions for valuesForKeys is as described above for "take ValuesFor Dictionary". The valuesForKeys method may be implemented as described in the pseudo code (see section entitled Pseudocode below). The operation of valuesForKeys is illustrated in the flo diagrams of Figures 7A, 7B, and 7C. valuesForKeys Flow Referring first to Figure 7A, valuesForKeys is illustrated. When valuesForKeys is invoked, it is to take data from an object and load it into a data destination (e.g. a relational database). The properties of the keys of the key-value dictionary of the data destination are put into a key array. At decision block 720, the argument "All keys in key array processed?" is made. If the argument is true, all array entries have been processed and the method is over, the process ends at step 714. If the argument is false, the next key in the key array is processed. At step 704, the system gets the class description for the object. At step 706, "returnMethod" is executed to determine if the object has any methods (e.g. set Value, get Value, etc.) that match the key property. This step is illustrated in more detail in Figure 7B. After returnMethod has been executed at step 706, the system returns to decision block 708. At decision block 708, the argument "method found?" is made. This step is to determine whether their was a match between any of the methods of the object and the key property. If the argument at decision block 708 is true, a match has been found and the data can be loaded into the data destination. The process then ends at step 714. If the argument at decision block 708 is false, no methods match the key property. The system then checks the instance variables for matches. This is accomplished by invoking "retumlnstance" at step 710. This step is illustrated in more detail in Figure 7C. After retumlnstance has been executed, the process stores the key and returned value as a key-value pair in the key-value dictionary. At step 714, valuesForKeys ends. returnMethod Flow Step 706 of Figure 7 A, "returnMethod", is illustrated in Figure 7B. The process "returnMethod" is used to examine the methods of the object to determine if cmy; of its methods match the property of the key property array value being processed. At step 722, the method to be searched for is made defined as one having the current key property. At step 724, the class description is examined for the defined method. At decision block 726, the argument "method found?" is made. If the argument is false, there is no match, returnMethod ends at step 734 and returns to valuesForKeys of Figure 7A. If the argument is true, at step 728, a match has been found. At step 728, the value type of the method is determined. At step 730, the method is called and returns the result as value. At step 732, the process converts the value to value type, if necessary, and the value can be loaded into the data destination. The process returnMethod ends at step 734. retumlnstance Flow Step 710 of Figure 7A, "retumlnstance" is illustrated in Figure 7C. In the preferred embodiment of the present invention, this process is invoked only when no matching methods have been found for a key property being processed. At step 742, the class description is examined to determine if there is an instance variable that matches the key property. At decision block 744, the argument "instance found?" is made. If the argument is false, no matches have been found, the retumlnstance process ends at step 752 and returns to valuesForKeys of Figure 6A. If the argument at decision block 744 is true, there is a match of an instance variable and the key property. At step 746, the type of the instance variable is determined. At 748, the storage offset of the instance variable in the object is determined. At step 750, the value of the instance is converted to instance type and can be loaded into key-value pair of the dictionary of the data destination. At step 752, retumlnstance ends and returns to valuesForKeys of Figure 7A. Returning to Figure 3, the enterprise objects created at database level 320 are passed from database level 320 to data source 330. Data source 330 is an object that has the ability to fetch, insert, update and delete enterprise objects. Changes made by data source 330 to an enterprise object are passed down via database level 320 and adaptor level 310 to relational database 300 so that a corresponding change is made to the database for a change made to an enterprise object. Data source 330 supplies enterprise objects created at database level 320 to controller 340. As shown in Figure 3, controller 340 transports data in the form of values from the enterprise objects to user interface 360 via association objects 350. Controller 340 coordinates the values displayed in the user interface with the corresponding enterprise object values. When enterprise objects are modified, controller 340 tells data source 330, which is responsible for propagating changes to relational database 300. A description of the controller object class provided by Enterprise Objects Framework is set forth below in the section entitled Controller Object Class. Movement of data in the architecture shown in figure 3 is bi¬ directional. Changes made by a user to data values displayed on user interface 360 propagate to relational database 300 in the opposite direction as data from database 300 propagates to user interface 360. As mentioned above, the mechanism by which data moves through an Enterprise Object Framework application is a key-value coding informal protocol. Regardless of their characteristics, objects that conform to the key- value coding protocol (such as enterprise objects) have a common characteristic: their data is accessed by other objects in the form of key-value pairs. Key-value coding methods enable an object to receive values for its keys and to give out its keys' values to other objects. By using key-value coding, different types of objects can pass their values to each other, thereby transporting data through the different layers shown in Figure 3. Figure 4 shows how the properties in an enterprise object 420 correspond to the key-value pairs in a dictionary 410, and how both in turn correspond to a row in a relational database 400. Enterprise object properties and dictionary keys (such as firstName and lastName shown in Figure 4) map to columns in the database; the value for each key (for example "Lesly" and "Oswald", respectively) matches the column's value for the corresponding row. User interface 360 of Figure 3 typically contains a number of user interface objects such as pop-up lists, forms, text fields, and tables. These use interface objects display the values of keys of enterprise objects, and, if the values are edited in the user interface, communicate the changes back to the enterprise objects. The interface between user interface objects and related enterprise objects is provided by controller object 340 and association objects 350 of Figure 3, which together may be viewed as an interface layer between enterprise objects and user interface objects. The primary actor in the interface layer is controller 340. Controller 340 uses association objects to mediate between enterprise objects and user interface 360. Each association object links a single user interface object to a class property name (key) in an enterprise object or objects managed by the controller. The property (key) value is displayed in the user interface object with which the association object is linked. Enterprise Objects Framework provides a number of pre-defined association objects and associated user interface objects to the developer. The section entitled Association Objects (below) contains descriptions of association objects provided by Enterprise Objects Framework. Specific association objects provided by Enterprise Objects Framework include EOAssociation (an abstract association object class) and the subclasses EOActionCellAssociation, EOColumnAssociation; EOControlAssociation; EOImageAssociation; EOMatrixAssociation, EOPopUpAssociation; EOQ alifiedAssociation; and EOTextAssociation. As described above, an association object ties a single user interface object (such as a text field) to a value corresponding to a key in an enterprise object or objects managed by the controller object. For example, a text field may display the value "Jun-19-1992" for the key "hireDate" of enterprise object 420 of Figure 4. An association object is provided with an appropriate key to enable it to obtain data from a data bearing object using a key-value coding protocol. By means of association objects and their keys and the key- value coding system, a controller can set data from data bearing objects to user interface objects and retrieve data from user interface objects into data bearing objects. The user interface objects, association objects, and keys can be assembled without data, and be archived for later use with an application program. By using the key-value coding protocol, these objects can be assembled and configured ahead of time and made to execute at run time with no compilation. One of the functions performed by association objects, if needed, is to convert values extracted by the controller from an enterprise object and passed to an association object to a type that can be displayed by the corresponding user interface object. In a similar manner, a data source converts edited values returned to the controller from an association object to an appropriate value class that can be applied by the data source to the corresponding enterprise object. A controller works closely with it's association objects to ensure that values displayed in the user interface remain synchronized with the corresponding enterprise object values. When an enterprise object value changes, the controller tells its association objects. Conversely, when an association object is notified of a change in a displayed value by its user interface object, the association object informs its controller of the change that occurred. Figure 5 shows the sequence of steps that occur when the value displayed by a user interface object has changed. The sequence starts when a user changes the value of a displayed user interface object at block 500. For example, a user may change the hire date of "Jun-19-1992" displayed in a text field object for enterprise object 420 of Figure 4 to a new date of "Jun-19-1991" by typing the new date in the text field object displayed on the user interface. In response to this change, at block 510 of Figure 5, the user interface object sends its association object (in this embodiment there is a one-to-one correspondence between user interface objects and association objects) a message that this user initiated change has occurred. The association object, in turn, at block 520, notifies its controller of the change by sending the controller a "associationDidEdit" message. An "associationDidEdit" message informs the controller that a change has occurred, but does not include the new value. To obtain the new value, the controller sends the notifying association object a "value" message at block 530, upon which the association object returns the new value at block 535. After receiving the new value, the controller sends its data source a "coerce Value:forKey;" message at block 540. This message causes the data source to convert the new value received from the association object to a value class type that can be used by the corresponding enterprise object. The controller then delivers the new, converted value to the enterprise object by means of a "takeValuesFromDictionary:" message at block 550. "takeValuesFromDictionary" is a standard message that is part of the key- value coding protocol used to transfer data between objects in the Enterprise Objects Framework. Next, the controller sends "updateObject:" and "saveObjects" messages to its data source at block 560. In response to these messages, the data source causes the data in the database to be updated and stored to reflect the new value. Although the above sequence of steps has been described as taking place in without buffering, buffering techniques that are well known in the art can be used at various steps along the sequence. For example, changes made in the user interface objects can be buffered before being sent to update the enterprise objects, or changes to the enterprise objects can be made without buffering while the sending of the changes to the data source is buffered. Since each user interface object has a corresponding association object, and since a user interface typically has a number of user interface objects, a controller will typically be associated with a number of association objects. Further, a number of different user interface objects may display a value for the same key of an enterprise object. As a result, if a value displayed by one user interface object is changed by a user, that change may be reflected in other user interface objects. Accordingly, after the value in an enterprise object has been changed in response to a new value entered by the user, the controller sends all of its association objects "contentsDidChange" messages at block 570. In addition, when the change in value also causes the selected enterprise object to change (a "selected" enterprise object is the current object for which values are displayed in the user interface, or, in the case where a user interface object displays values for multiple enterprise objects simultaneously, such as a table, the selected enterprise object is the object whose values are highlighted), the controller also sends all of its association objects a "selectionDidChange" message at block 580. This enables each association object to display values for the currently selected enterprise object, or highlight the values for the selected enterprise object if the user interface object associated with the association object displays values for multiple enterprise objects. A "contentsDidChange" message received by an association object constitutes a signal to the association object that the value displayed by its user interface object may have changed. To determine whether the change that occurred affects the value that an association object is displaying in its user interface object, at block 585, each association object sends the controller a "valuesForKeys" message to obtain the current value for the key that is displayed in the association object's user interface object. "valuesForKeys", like "takeValuesFromDictionary", is a standard message that is part of the key-value coding protocol used to transfer data between objects in the Enterprise Objects Framework. When an association object receives the current value for its user interface object, it compares the current value with the last value that it received (which ordinarily would also be the value being displayed by its user interface object) at block 590. If the current value is different from the last value, the association object sends a message to its user interface object to update the displayed value to the new value at block 595. From the point of view of the controller, all association objects look the same: the controller communicates with all association objects using the same set of standard messages. The process shown in Figure 5, particularly from block 520 onward, thus applies in general to any change in value made to any user interface object. The way in which a user interface object interacts with its association object, and the specific messages that are used for communications between an association object and its user interface object, however, will vary depending upon the characteristics specific to a particular user interface object. Accordingly, the particular manner in which the steps shown in blocks 500 and 510 are performed may vary from association object to association object. In addition to informing its association objects when its enterprise objects or currently selected enterprise object have changed, a controller in Enterprise Objects Framework uses a "endEditing" method to order its association objects to finish editing. Before a controller can perform certain operations (such as fetching, inserting a new enterprise object, or setting an undo mark) it must collect any new edits from its association objects. When the controller sends "endEditing" messages to its association objects, they finish editing, relinquish first responder status, and notify the controller of any changes with "associationDidEdit:". The protocol used by a controller to send notification messages to its association objects is described below in the section entitled Notification Protocol. In addition to providing a number of pre-defined user interface objects and association objects, Enterprise Objects Framework allows a developer to create custom user interface objects and associated custom association objects. The "EOAssociation" object described below in the section entitled Association Objects can be used by a developer as a basis for defining a custo association object. Thus a method for associating controlling and data bearing objects with user interface objects has been presented. Although the present invention has been described with respect to certain example embodiments, it will be apparent to those skilled in the art that the present invention is not limited to these specific embodiments. For example, instead of communicating with data bearing objects via a controller object, the association objects of the present invention may communicate directly with data bearing objects. Instead of using a separate association object for each user interface object, an association object may be associated with more than one user interface object. The specific messages sent and received by association objects and data bearing and data controlling objects can vary from the specific messages described herein. The specific steps and sequences of steps described herein may be configured by a user and may vary from one embodiment to another. Other embodiments incorporating the inventive features of the present invention will be apparent to those skilled in the art. type coβve oβ amoag abject claaaea. It's possible, for example, to paaa aa NSStriai to ktValueaFtremDIctiα-iiaryi •a ϋie value for a property the receiver expects to be aa NSOaie. The sender of a key-value coding message ia thus responsible for casuriai that the vaiuca an of the proper deal. Aa EOCoMroOcr, for example, oooveπi string value* from the uaer interface with ile data aourcc'i cvereeValaetrerKeyi method. If you're ueiag a data aouroe to manage yoir enterprise objects, you caα uae thia method aa welL Note that it you're using the Framework' i access layer you caa dctc mia* from aa EOModel which value elaaa ia aasoάaicd with each attribute — EODatabascDataSαurce uacs this iafαr aiioa ia ill imple-neatatioa of o-MreeVaiaetforKeyi. The key-vaJue oodiag methods haadle oae special ease with regard to value types. Numeric values must be transfer-red ia dictioαarics as NSNutnber objects, bin aπa't very efficient for caleulatioa or storage; most objects store αutneric properties as C scalar (numeric) types aad declare their acoeaa methods to haadle them ia thai form. Ia additioa to being represented as NSNumben ia dictionaries, numeric μiuμcuy values are haadled by aa EOCoøtroJ r as NSStriag objects. Because numeric properties are very common, the default implementations of the key-value coding methods convert an object value to the C scalar (mancric) type required by the enterprise object's ancrtanr method or inttanrr variable. For example, et-ppose your enterprise object defines these accessor methods: - (vαid)ae«S«ia-7t(unsigaed iΛXysaiar — (unsigned jot)— try For the aβS-dary: method. ta eValuenFroaaDictiβnaryt coovens the object value for the -salary ** key ia the dictionary to aa anal -pud int aad paaaes it as jα-αry. Similarly, velars Fes-Kcym eoavcru the return value of the salary method to aa NSNumber aad inserts Out into the dictionary that it return-*. The default iαφtancnutioαs support the following scalar types: char unsigned char short unsigned short int unsigned int long unsigned long float double Object values are converted to these types with the standard messages cfcarVnaM. to«Vnh*e. float Value, aad so on. Note that the key-value oodiag methoda don't check thai aa object value aαually responds to these messages: this can result in n nia-time error if the object doesn't respond to the aμ- i-μiiate message. Aa important issue to eooaidcr ia usiag C scalar types is that most relational daiabnaes allow the use of a NULL value distinct from aay numeric value, represented in the Enterprise Objecu Frame ork by the EONuII dass. Siaee the C scalar types can't accommodate a distinct NULL value, the def suit iπφiemeatatioas of the key- value oodiag methods raise NSInvnlldArguaneatExcepdαα oa encounlering aa EONuD object that aeeds to be converted You should cither design your database not to use NULL value* far numeric ootumns, or design your enterprise object dass to use NSNumber objects where NULL value* ate allowed. knptomontinfl Kay-Valu* Coding Mathcda Your own enterprise object class can cither rely on the default behavior of its superclass or override it. partially or completely. For example, a subclass of NSObject may have a few properties that it needs to handle in a special way. but the rest can all be haadled by the default iinplemeataiiαα. Ia this case, you might implement the methods of this category according to the following templates. laooUtekaValuaarro-BDlctlooe -yt (KSDlctionary • laOlctlonary HSMuubleOlctlonary *uutDict /♦ Make a suitable version ot Uw passed- In diet. '/ autDlet • I laOlctlonary autableCopy) autoralaaaal ι /• Take whatever valuaa you naad tron autDlctlonary. ra-aovtno than * troai autOlct as you do ae. •/ rat-jrn Inupar takeValuanPro-aOlctlonaryiautDlctl ■ takrVala-EsFrDmDtctienaryi here creates its own mutable copy of the dictionary passed ia. It handles the keys H eerds lo, removing ihem from the dictionary so that the superclass' iπpiemcaiatioa won't set them as well, and then passes the remaining key-value pairs to super. To compiciely override the superclass' implementation this method would have to handle every key-vahie pair ia the dictionary, returning YES if all key-value pairs were handled, and NO if any of them couldn't be processed. - (NSDlctlonary "IvaluesPorKay i INSArray *)keys ( HSHutableλrray --a-utKayt - l l keys -autableCopyl autorelaaeal ; NSXutabl. Dictionary - • a-utOict • INSMutablaOlctlonarγ dictionary! ; Int I: (or (1 • InutKeys count;] - 1; 1 >» 0; 1--I ( / * Sea 1( you can put tha value (or the key at 1 Into nutOlet. * K your object stores tha valua as a suitable object you * should create an lmutabla copy and autoraleasa It bβ(or« * putting It Into nutOlet. autOlct will rataln what you σlva * It as needed. • / if </* you put tha value (or tha key at 1 In tha diet */) ( InutKeya ranoveObJectΛtlndaxi11 ; ) I: InitOlct •ddEncrlasrro-aDletioσaryt 'super valuesForKeys ι*-utXay*| 1 ; return nutOlct; 1 vnlββnFnrKeysj creates a mutable copy of the key array passed in. and a mutable dicϋoaary ia which lo place the values requested. It haadle* the keys it needs to and removes them from the array, then passes the remaining keys to sanw and adds the i tunned values to the dictionary it's building. To conyleiely override the superdaas * implementation this method can simply omit the message to super after putting all the values k can find for the keys into the dicϋowry. CautfoiM Throe sirastions demand care with regard to the key-value oodiag mechanism, first, be awaro that the default implementation of iakeVnlucsFrotRDlctJofinryi doesn't guarantee the order that property values are set. Thus, your enterprise object's acceanur methods shouldn't assume that other properties' values have been established when they're invoked. Second, if your application is using the access layer, you should be careful in implementing accessor methods thai aet values (or ia overridiag taktVatacsFrona ietieiMryi) about sending messages to the value objects ia the dictionary. iakeVahs«sFnaιtOictiaαa--yt is oAen sent while a fetch is in progress, aad if your implementation sends a message to aa BOFauk object, it wiO try to fetch the object k stands ia far, causing a server error. See the Fr>r>MA.»<- ..- ^ ι-»l«.irιr-τi~B informal protocol spedficatioα for suggestions on how to work around this problem. Thάd. it's possible for a property's value ia a database to be NULL, ia which case your enterprise object receives an EONull object as the value. If you allow NULL values in your database, your eaterprise object* have to check whether the values they receive are EONuJla aad oral them appropriately. Method Type* Setting and getting values - lakeVahiesFrαmOictiooary: - valuesForKeys: Resetting key bindings - fhishKeyBindings Instance βthoda fluahKoyBlndlng* - <void)OulιKcyBlndlα f Invalidate* dm cached ksy-faiadiag iaformatioa for the receiver' t class. The Eaterprise Objecu Framework uses this iafαrmalion lo optimize the defauk implementations of the other methods of this protocol by caching method scle- * tαπ aad instnnee variable type iaformatioa. This method should be invoked whenever a class ia modified or removed from the runtime system. lakaValu-M From Dictionary: - (BOOL)takcValaesFϊr*s^)ietiαiMrr.(NSDictioαaιy •"aZJi donory Sets properties of the receiver with values from døicrionαry. Returns YES if the receiver read all values from the dictionary, NO if k couldn' I lake all values. Note: The access and interface layαrs of the Eaterprise Objecu Framework doa' t ooαsider a return vahie of NO to be aa error, aad take no special action based an such a return value. vnkjoaForKay-t: - (NSOicϋoaary •)valMsF*rKeyst(NSAπay •yufλmry Returns a dictionary providing as many values ss possible for the keys ia ktyΛrrσj. Not all values requested are guaranteed to be retrieved. R W ικ«o-t l laaM lac. AH Ri*hu Rβer-ai EOFault Inhurttn From: none (EOFault it a root clais) Dneiaπsd In: eoacoesa/EOFaulϋt Clasa Deecription Aa EOFauh is aa eaterprise object (or aa array of enterprise objects) whose data hasn't yet been fetched from the daiahaar, When aa EODaiabaacQiasael fetches aa object that has relationships, it creates EOFaults for the destinations of those relationships (unless, for to-one relationships, the corresponding objecu have already been fetched aad aniquedV By not fetching aa object uatil the application actually needs , the EODaubaacQiaaael prevetts aaacoeaaary interaction with the -*"• • *—— server. Aa EOFauh caa nμttauit oae object, ia which case it's called a si-glt-objcct fault, or k caa represent aa army of objecu dtsαibed by some qualifier, ia which case k's called an array fault. To-one relationships resuh ia eagle-object faults, while to-many relaiioaahipa result ia array faults. A single-object fauk fetches and loads the real object over kself the tint βme you send a message lo k (with some exceptions, listed below). Aa array fauk loads its objecu as soon as you send k any message thai requires accessing the content* of the array (objcctAlIadexi, eoaαt, aad so on). EOFanks of ckhcr type are called /<-»_( objte . The nbjeelFa t IthPriMwyKcyMndtyidαtaliMe -mnciαontt dasa method creates s single-object fault, and the arrsyFaartWhhQ— idu .fftchOi -In idntahaat Ch— tel-sooei dass method creates aa array fauk. You can't create a fauk object with aBac and hafc— messages. Your application caa explicitly create fauk objecu lo avoid fetch conflicts. This is a ouecaa for newly created enterprise objecu that need lo fetch objecu other than those given by their relationships ia their laheVssncsFrotniDictfomryi or aw * afceFarf>ntnhaa t C-»mιι»efa methods (described in the EOKeyValoeOxfing and EODntahnseChasad Notification protocol spe ficalions. respectively). Because the diaaael thai fetched the eaterprise abject is busy, the enterprise object can't use k to fetch other objects— aad must be careful not lo access any objecu tut arc actually fauk objects. An eaterprise object caa use a different channd lo fetch another object immediately, or k caa create a fauk object so that the iastsace variable at least contains a valid pointer. A newly created enterprise object must not access a fauh object while iu channel is busy fetching. Doing so causes the fault lo aαempt a fetch wiΛ thai channel, resulting in s fetch conflict. The enterprise object also caa'l replace a siaglc object fauk with aa object k fetches itself: the fsull has already been uniqued by the time the enterprise object gcu k. aad other eaterprise objecu may bold refereaoes lo k. Aa stray fault, however, caa be replaced; you might want to replace aa array fauk to change the qualifier or the fetch order that will be used to fetch iu targets. Maasagaa that Don't Cauno Fetching A fauk object responds lo some messages as if it were the target object, w-hhout causiag a fetch. For example, daaβ return* dte dnas of object that wiϋ be fetched, not tin; EOFault dass. The following instance methods neither cause a fauh object to fetch βor betray the true identity of a fauk object: dass oomorms ioProtoooi: description iaK ndOfOaas: iβ embetOf lasβ: IsPioxy (return* NO) print For Debugger. releas* respoadsToSelector. retain tetainCαual Forcing ■ Fault Object to Fateh You caa force a fauk object to fetch by sending it a message that it can't handle as a fauh. The messages listed ia the previous section nil work with generic run-time information, and so don't cause fetching, tat nay message that accesses dau (such a* the key-value oodiag method vakacsFerKey-m or a custom message such as hatNaunc) causes the fauk to fetch iu data w h s d tabase diaaacL EOFault also defines the self message so that k always causes the fault to fetch; this provides you with a method that has no effect on a normal objoo but that you caa always ase to cause a fault object to fetch. Remember that you shouldn't cause a fault to fetch itself if ks database channel is busy. With a tingle-object fauk. you caa conveniently use EODaiabascQtanael's rnfctd-øbjecΛi method to get the dau far the fault. This techniqun nDows you lo fetch the fsuk's dau even when s database channel is busy, by using s different dalabnne chnaanL refetchObjecti diedcs whether k's fetdύng for a fsnk abject, aad transforms the fauk into aa inttawe of ks enterprise object ass. Forcing a fetch oa aa array fauk is best dαae by repladag the anay fauk wkh one that has a different database duaael, sad thea causiag lbs sew (auk to fetch itself: Id array; /• λnsun-a this exists and la an array fault. */ BODatabaaaChennnl *>avallablaChanaal: d (orcβdreult- (orcadrault ■ (EOFault arrayPaultulthQualKlari (array quallClarl (atchOrdart (array (a tchOrda I databsaaøianaal iβvnllablβCΛanoβl toαβi larray tonal ) ι I array autoralaaaa) t array • ( ((oreadrault aaltl rαtalnl ; "nϋs code excerpt creates a new stray fauk whh the same iaformaiiαα u the one bring feldied, except thai it's using a database channd that isa't busy fe hiag. k thea scads sdf to the aew fauk to force k to fetch, aad assigas k to the origiaal variable. Inatanca Varlablea Qass aaa; A pointer to the instance's dass stmcture. Method Typaβ Creatiag a fault + -wayFaidtWithQualifierfetebOrder daubaaeChaaae|--Bone-. ♦ objβctF-uhWithPrimaryKry-eaϋt-r. databnieChsaaelanne: Getting iafαπnBiioa about a fauk 31 <* clearFaafe: ♦ daubatcChaanelForFault: ♦ cnlkyFαrFault: ♦ fetchOtderFαrFauk: ♦ isFaulv ♦ primary KeyForFault: ♦ quaJificrFαrFaull ♦ targetClassFαrFault: Special jnitt r methods — descriptioα -ιelf Ciaaa lyiethoda nmrFaun itf)Ouaf « :fotchOrdar:databaooChannol^ooα: + (NSArray *)wτ-«yFu-aMWkhQ-aaJiBef--<EθQuaIificr f*«d»Or-*eι-:(NSA-ι-ιy * _Fete Order dt*al» ar ιriι*aιιιιlι(EDDauba*eQunnel '(.Oβw sααe NSZone *)tene Returas aa array f-aill thai will have βOwsi fetch ks objecu according to aQualifier aad aFetdiOr er (aa array of EOAfttibuleOrdαiag objecu) when k's arrrssed for the first time. If aChar ei is fetchiag wfaea the array is arrrserd, a fetch conflict wϋl result, wkh t-sdeϋaed results. Son anno: ♦ abjcctFtankWllhPιiM 7 KcyιcαUtyιdι d-aar auft ♦ («oid)de«r-FanMιef<nι/r Turns efαuir into a freshly inkialiaed instance of the target class. Does nor fetch dau for the se ii N51»vnldAι g-aueutlException if invoked arkh an object dial isn't a fauh object. You should rarely louse this nartbod. Soo n*uo: ♦ ryHClaasFarFaaJt: daα * -baaoChanneiForFault * (EODaiΛnaeQiaanel *)ri at * ■ *■ a-sτCban-π « IForFnnhsaf en// Retro the EODaub aeChanod dial FauIt was seated with, or nil if aFauti isn't a fauh object nntftyForfβute ♦ (EOEssky *)«o t* FβcFanlt--jΛu // Reαsras the entity thai afauϋ was created with (or as determined by the qualifier for an array fauh). Returns nil if af —i isn't a fault object. tntcftOnterF r auit ♦ (NSArray *yι<cfc τ-4erFarFaaJlιαΛ-Bi-r Rcan-ns the array of EOAnributcOidcriag objecu that aFault was created with, or ail if aFauU isn' t aa array fault laFault ♦ (BOOL»F-mMa-afO «cf Returns YES itaaObjtet is a fauk object. NO otherwise. You should use this method, not IsKlndOfOnns-. if you need to know whether aa object is ia (act a fault object. objoctFaιιKW1BtPrimary ay:ontny databaoaChanno(3on«: ♦ akjaetFnukWWιfrtmnryKeyι(NSDicsionary *>-Kej eot»ty:(EOEntity •"xni&ery dntas-asιCaaπnrlι<Eθπ«lahascr taι>el »)αCtoifid ιeaet(NSZoae "feβie Returns a single-object fauk far an enterprise object with the specified primary key and entity. When acrrned. • hswirf (etches the actual object far the (auk. allocaliag k from to***-*. If αChαnnef is fetchiag when the fauh allempu lo fetch, a fetch conflict win result, arkh undefined results. Seo alαo: ♦ nrrnyFnoRWIlhQn^ner-J ehOHtndntabnsaOisaindssaeie prim aryKeyForf ault ♦ (NSDkώooary *)prioiM7K«yFn-rFnnXιafo--it Returns the primary key for a single-object fauk. afi for sa sπsy (ault or aoa-fauk object. quad ftorforf ault: ♦ (EOQualifier *)qnnllO«rFaτFnβiUβΛβ.Λ Remca* the qualifier ased to fetch the object or objects that aF uh was α-catcd for. For a siegl*-objec- fauk this is the qualifier of the eatky the (auk was created wkh. plus the primsry key spedfieaiion: for an array fauk this is simply the qualifier the fauh was created with. Returns aβ if (ault isa't a Fauli object. S-ne aiao: - qaaHBcr (EOEaϋty) targotClaaaForfaute ♦ (Pass )UrgrtCTanaFarfn«»t uf ault Rcnirns the dass thai will be iastaatialed whea -Fault is (etched. For a siagle-object (ault the ass is detcπniacd by the eatky the fauk waa created wkh; for aa army fauk die dass is NS utableArrey. Return* ail if aFauU in ' t a ( auk object. Seo aloo: - cotMy (EOQualfier) Iπβtanca Mβt o β - (NSSlriag *)dαscriptlno Reams a string object thai repceseau the ooaleau of the fsuh object, without causing it to fetch ks data. A •ingle-object fault's description αoouias the aame αf ks eatky aad the value of ks primary key. aa array fauk ' s description contains die qualifier need lo fetch ks objecu. - 33 - anlf -mtt Causes the fauk object lo fetch iu dau and mum *d£ You can use this message to fares a fauk object lo fetch iu dau inunediaiciy. CONTROLLER OBTECT CLASS EOController Class Description Mote: This approach doesa'l work for aa NXTabUVicw. Iu assodttioa class. EOCohimaΛsaoαaiioo. requires special handling. Sec Ihe EOColu aAasodaUoa dass rpeci/icaiioa for more iafo malioa. If you have a special association dass designed lo work with s user iaierfacc object, you caa explicitly create aa iastaacc of lhat class iastcad of asking the user interface object for ks default aasociaiioa dau. asanιAa6ooO*MS is simply a mediaaism for dynamically seleαiag aa appropriaie association for a gives user iau- face object. Aa aasoάat oa forms aa iaiimate liak with its user interface object, ll acvly always seu itself up as a control's target, aad often seu itself up as the text ddegale of its user iaierfacc object as welt You should assume thai a use- iaier ace object managed by aa assααatioa is off-limits with regard lo changing s stale, aad haadle all dau maaipulaύoo aad validation in Ihc controller's delegate or ia Ihe enterprise objects themselves (sole lhat a custom association αa also haadle validation). A slightly different type of association is t st between two EOCαatrollo-s. Aa EO uau iedΛuodaiioα link* two controller! in a master-detail relationship, to thai whea the object selected ia the master controller changes, the detail coatrollcr'i dau source is configured to provide objects related to the one selected ia ihe master. Uaatnr-d-atail Controll-sr* and tha Controllar Chain Coαlrolleπ linked in a master-detail relationship are treated specially. When aa EOCooiroller performs a fetch. aavcToObje-cta, saveToDataSoara, or r-t-tβsplay message, it checks the destination of each of iu associauoαs to see if thai object is also an EOCotjtroller. If so. it propagates the operatioo to them, thus syad-rααix ag Ihe suje aad display of all linked coπu-oHerx. If you don't want lo set iφ a pair of coat-rollers ia a master-detail relaiioαship, you cu still have ooe of them propagate the methods listed above by using the sctNextCαDU-aOer- message or ooaaeoiag the two coαβ-otlcn ia Interface Builder. Linking controllers together ia this maaacr allows ihe otherwise iadcpeadeat eoαtrofleπ. each managing their own seu of eaterprise objecu. lo remain syadwoaized with respect to all significant oper-uioαs. You can liak any number of ccαtrollcπ together in this fashion, but you should be aware thai the Tour actions are prop-af aiod dc-w-a the chain only; coot-rolleπ above the oae that receives the origins] message aren't notified (unless the chain is a loop, which ύ permitted). Buffering and Undo EOCoatroller offers two levds of change buff-sing and a powerful undo mechanism. Then: are two kinds of changes: edits lo Ihe values of eaterprise objects, aad σpenuiom oa the eaterprise objects is the data sourer Gaaertio-α. deletion. aad update with buffered ediu). Whea a controller is buffeting edits, it saves each dtaage sent by as assoάatioα objecu. It doesn't apply these changes lo ks eaterprise objecu ααtil k receives a aavcTa bjects message. Siαal-α-iy, operations on the objects held by the controller area'l applied lo die dau source usul the control ler receives a aaτtTaData5o-an*τ message. You caa remove buffering so that diaages are ππmediatdy saved by sending a controller a aelSaτeaToObJ»cls a-ta nadcallyt orsetSavesTaDalnSnaii lAaie-mabcaJyt message. This table shows how automatic saving affecu the stale of the controller's eaterprise objecu sad dau rourec : Save* automatically lo: Objocta Data Source Bahavlc-f YES YES All diaages arc immediately seat to the convener's data source. Thij is the default behavior for eontπ-Λcπ creaied is Interface Builder. YES NO Ediu immediately go to eater-prise objecu: you must send aa wTaData«i«arτ» to seed changes lo ihe dau snace. NO YES Ediu are buffered, bu when you send aavcTaOfe rcls changes are immediately set* lo Ihe dau source. NO NO You must scad navtTβObj-*-ru to effect ehaages lo enterprise objecu. then aead naveTaDeUSaarcr lo send the ehaages to Ihe dau source. This is the default behavior for controllen creaied programmaticaJly. la addition lo buffering changes, aa EOController maintains aa undo stsck lhat records those diaages after they've been applied. You caa send a controller a naarkUnde meuage al any lime to mark the current pant oa the aado stack. A later sad* meuage revms the changes is the undo stsck hack lo that poial: deleted objecu arc recovered, inserted objecu SI deleted, and all ediu— ending aad saved— are undone. You can configure aa EOControikr lo automatically mark aa αado point after every operation, or you can manually control undo marks to group operaiioaa together so thai they caa all be aadone with a single nndβ message. For more iaformatioa oa dau souπ-cs. ice the EODauSαirccs and EOQualiπablcDalaSourcea protocol spedTiotioas. Notifying tha Controll-nr'a Dai-agate As EOController notifies ks delegate of nearly every operation it performs. It confirms aay insertion, ddetioa. or update widi iu delegate before performing the opentioa. and notifies the delegate of undo aad save operations, sad of aay diaage ia selection. Fvrther. if a change to the dau soiree fails for aay reason, the delegsie has a chaaoe lo tell the controller whether to simply continue or to roll back changes (if the dau source supports rollback). All a delegate need do to receive a aotifiαlioα from iu controller is implement the appropriate methods. These methods are documented after EOCo-su-t-fler'i dau and insuncc methods, under "Methods Implemented by the Delegate.' the delegate doesn't implement a particular method, it isn't invoked. Instance Variable* None declared in this class. Method Types Inatance Method* •ddAaaodatton; - (votd>addAMαcUtiaαι(EθA-uo iaύoα • -**-ΛiJ<-cioft-«ι Adds tatλtiocύtioH 10 the set managed by ihe controller. S«-a aaao: - rrma-rtAaaodatiααi. - aaa allObjβcta - (NSArray *)- θbJ«la eo-ras all eaterprise objects accessible through the controller. Sao atoo: - seheUdObjecU -asaocistion DidEdlt - (void)s a » A adnpDιdEd :(EQ Association *)αιΛuociαftαn Infom the controller that anλ soeiatian has a pending edit The controller geu o-Λooci-saαπ's key aad value and adds the new vahie to iu edh buffer. If the controller is configured to uve diaages automatically thea the changes are immediately saved lo the objecu. If the controller doesn't save diasgα automatically, the changes don't take effect uatil the controller receives a »w-«ToOb)r*-U message. This method iavofces the delegate method coαtroller-.asBθόallβα:didEdhObjcct:kcyιvniα«-. Sa-a aaao: - key (EOAssociation). - -Λ»* (EOAsso ation), - sav«aToObicctaAata«utie-a0y, - aarrαsTaOnaaSaarotAataanabcnBy - (NSAπay ") Returns the controller's asso aύoαs. CM*arSaa-*-coon - (BOODdβ-rSefc-etioo Empties the controller' » selection. This method is a shortcut for sending sctSclecboti: with aa en^ty array. Doesn ' t ret&splay the αser itacrface objects. Returns YES if successful. NO if sou Sea alao: - rrdhptay data-Sou roe - (id <EθDaU Souroes>)da<jaSoαrττ Returaj the coαtrollα's dau sou-roe. Rcαra the coavoller'i delegate. delαta: — dde Ufl-a-fer This action method invokes dc tcSelrctJon 10 delete ail selected objecu. Returns seir if ddetcSalectian returns YES, nil if k returns NO. dal-ataObfoctΛUndax: - (BOOL)dalc4«Obi«ctAUs>-icsι(uasigned inl ndc Deletes the object at ι— Index, peadiag approval by Ihe delegsie. Returns YES if the ob j ect is actually deleted. NO otherwise. If Ihe dau source caa'l delete, this method opeas aa mention panel notifying the user and returns NO. If the data source caa delete, isvokes cndE-Utin aad aoti/ies the delegate wkh cootroncrτwiHDclcte-:Obj«ct:. If the delegate approves, deletes Ihe object sod notifies the delegate with ennU-alkndidDekicObjcct: aad the controller ' s usorialions with coπtentsDidCawi * and sckctisoDidQ-inDfc. Deletion is aa operatioa applied immediately lo the object; you doα't aced lo scad aavcTeOfej-rcta. If the controller is configured lo save to Ihe dau source automatically thea the diaages are immediately made to the data source u wcIL If the eoαβollcr doesn't save changes nuto aticnlly, Ihe ehaages don't lake cffeα in Ihc dau source uaul the controller receives a saτeToDa-laSeαι*n message. 3-s-a aiαo: - delete!. - e-tleteStt-reϋoo, - anvcsToDnlaSe-nreaAs-lomad-aaBy detateS ectton - (BOO )dcfcuSclecdao Deletes all objecu ia the selectioα ia the maaacr described for ddeteObj-rctAtlndexi (including invccaϋoa of delegate methods). Reims YES if all objecu ia ihe selectioα were successfully deleted (or if there were so objecu selected). NO otherwise. If this method returns NO k's possible lhat only some objecu ia the selection have been deleted. Deletiag ihe seleαioa is coasidcred a single operatioa for purposes of undo, even if the controller marts every operajjoα. So* alao: - dcietei etβcsrdEdltβ - (void)d»scs*dEdKs dears all ediu peadiag ia ihe controller, aad also ia user iaierfacc objecu (by sending aSscardEdlts to aj] of ihe coββoiler's association]). This method is oaly useful if the controller isa't eoαfigiaed to save to objecu auo-matically. So* also: - aaτcsToθ4>jt-ι-UAate-*naϋαJ)y d cβdEdlta: - a*cardEdMau< er This action method invokes sUacardEdila aad returns self. dtecardOpar-atfone - (void)diacwdOpet--ationβ Gears all pending operation!. This method u only useful if the controller isn't configured lo save to the dau seuree -aitαmalicajly. S-sα srao: - aavesToDnl>SoaR«AnlomalicaOy oacardOpα a DO nα : - diacar-dθperatiα---sueπα'er This action method invokes dk-cnrdOpcralians snd returns self. βnd tab Q - (roid)eodEdltJiJt Sends e-adEdHtng to each of Ihe conβ-oller' s assodations. This method is invoked whenever the controller needs to force aa cad to editing in the user interface objecu, which is whenever • The controller fetdtca. • The αono-oDer saves changes to iu objecu or to ks dau source. • As object is inserted or deleted. • The selection ehaages. • The oado stack is altered by a mm-kUndo. utnda. or nlawseUodcβ message. So* alao: - codEdta-af (EOAssociatioαNotϋicalion protocol) fatcfh -(Boour-ttcb Tttthes objecu from the coatrollcr's dau source, returning YES if successful. NO if not. Before fetdting. invokes eβdEditfaif aad confirms that pending changes can be discarded by invoking iaDtacardABa-wtd. Also confirm- that aay detail ooαtrolleπ can discard pending dunges. Abocu the feldl aad reams NO if laDisemrdAJlowad returns NO or if asy of the detail or linked controllers doα't allow discard. After coαfirming that diaages caa be discarded, proceeds to discard aD ediu aad operaiioαs aad clears the oado stsck. At Ibis point, the controller sends c**-ntroaVrWBFrleh* to iu delegate, aborting the fetch aad returning NO if the delegate retuπ NO. If ihe delegate returns YES, the controller sends fctdtObjecU to iu dau source aad resyadsronizes ks selection with the new objects. After fetdting objecu. the coo-jollcr sends controlVer-DidFetc-hObjccts: to iu delegate aad cαol*nuDMCh---nfe U> iu assoάatiou*. If the cousoller's selection changed u a resuh of fetching, also sends to the . Finally, the controller propagates the fetch message lo all detail and linked controller-'. Sea aaao: - dsscai-dEdKs. - rrleaβrUodoa. - arlecuFirstObjertAΛerFrtdi c- : — fetch tsmdrr This actioa method invokes frtch aad muπu self if fetch rettrns YES. nil if it returns NO. haeChangaaForOat-aS-Mtroa - (Bθθ )ha β -α»β»gβFβrDβ-αSβar n Rcturas YES if there are aay operaiioαs buffered for the data source, NO otherwise. So* -**: - savtaToDataSoαreαAatematkaJly, - huC3<anc«sFarθbjvcU. - aavaToObjrcts haeChangoaForObjαcta - (BOODhaarOi-mgesFβrObjecU Rcturas YES if aay object has beea edited dace the last saτ»ToObjecU message. NO otherwise. Son alao: - savcsTeObJαcUAatnmaϋcsdly. - ImnOuuigαForDntsLSoαrcc, - asacd rionPtdEdk:. - sctVnlacstfβrObjectt InltWU OaUSouroa: - biilVYlUiDa So-ai-ctifid EODauSαuroes> ' uC iαSc«rcr Initializes a newly allocated EOCoαtrollcr to get iu dau from objecu provided by aDaiaSauret. This is the designated initializer for Ihc EOCoatroller dass. Returns sdC Inαart - fasβertucπafrr This actioa method ases hserrtObJcctAUisdezi to iasen a new object after the adected object, or if nothing is selected, at the ead of the army. Returns ne or nfl if InaettOfeJectAtladcxi returns oft. InMrtObjαetAtlndαx: - h-a-crtObjectΛtlødcxi nsigned iat)oΛ/ικiex Inserts aad seleeu a new object, created by the controller'! dau source, st anlndex by invoking lnacrlObj*ct--atIs>dRt. Invokes eodEdldnc before performing the ias- ioα. Returns the object that was inserted, or nil oa failure. Note: You must set ihc new object's primary bey before uving to the dau source If die coααroller is coafigtved to save automatically to Ihe dau source you shouldn't use this method. Raises NSRug-cExerptie-o if anXndSez indicates n position past the ead of the controller' i array of objects. See also: - crraleObject (EODn Sources protocol of the access layer) Inαor ObjβctaUndβx: - lna*-rtOfe|«ctk-s*ι£0 allικtexι(uasigncd iat)arU-dex lascru a-EO at enlnda ia the array of enterprise objecu masagrd by the controller. Invokes -mdEdkbic b fo « τ performing Ihe insertion. Rrttaras ihe object that was inserted, or nil on failiac. Raises NSRangeEsc-r-ptJa-n if ader indicates a pockioa past Ihe cad of the controller's array of objects. Inscrtioa is aa operatioa applied immediately to the object: you doa'l aced to send sav-rTaObjects. If ihe eo β rcΛer is configured lo save lo Ihe dau source automatically thea the changes are immcdiaiely made to the dau aourcr as wclL If Ihe eoatroller doesn't save ehaages stuomalically, Ihe diaages don't uke effect in the dau source nnul the controller receives a a cTeDnaaSnoiu message. Note: You must set <n£ Tt primary key before uving to the data source. If the eoatroller is configured to save to the data source anEO must already hsve iu primary key set whea you insert it. After inserting the object the controller selecu k and sends cnntrtiuDldChanfC and adrτtlaoDldChang-- lo all of iu associations. This method invokes the delegsie methods tonlπιll«r:wlllln«ertθbjret:. centrnllendldl---aenObj-κt:, aad oonti-oOer-raflwfTolπs-trtObjt-ct:. See the desαiptions (or these methods for information oα how they affect insertion. Son also: - Insert:. - savcsTβDntaSaαrceAalomatJcnlly IβDiαcardAllow-sd - (BO0 )isDiscardAαowtd Verifies that discarding of ediu not saved lo objecu aad updates not saved lo ihe dau source is allowed. Returns YES if discarding of ediu asd updates is aDo-wcd. NO if not. A controller uses this method when fetching aad changing the selection, to make sure that aa operation doesn't inadvertently discard pending diaages. If the coββ-ollcr has aay pending ediu. it sends eontrαllcrVVπiDiacatndEdHsi to the delegate. If Ihe delegate returns NO. this method immediately ren-π-α NO. If the delegate returns YES. this method continues by checking whether αp-a-atiααs may be discarded. If the delegate doesn't implement contrnllcr a Discs rdEdl t. the eoatroller opens aa attention panel ukiag the user if it's okay lo discard edits. The panel offers the user the choice to uve the ediu (causing aavcTeObj-reu to be invoked), to cancel whatever operatioa invoked this method, or to allow edks to be discarded; if the user chooaei to uve ediu αr to cancel this method rctt-rns NO. Next, if there are aay operations not saved to the dau source the controller sends tuotπ-IWrVyiπDtacaHOpq-adcnsi to the delegate. Again, if the delegate doesn't implement this method ihc controller opens aa attention pnael ukiag the t-aer lo uve. cancel, cr allow discard of operations: if the user chooses to save operations or to cancel, this method returns NO. FtaaOy, if all of these conditions are paued, this method returns YES. Sae alao: - dfa-t-nHEdiU, - saveToOb j c . - aaveToDalaSoαr*** taUndoEnabUd - (BOOL aUodo Enabled Returns YES if undo is enabled. NO otherwise. Undo is by defsull not enabled for coo-rollers creaied proframmatically, though k is far oontroucrs created ia Interface Builder. - (NSArray *)kejι Reα-rai the keys used by the controller's associations (which aren't necessarily all the keys used by iu enterprise objecu). These keys are the names of properties of the controller's enterprise objecu. as used ia the EOKeyVahieCoding informal -a om-l defined by the access layer. There may be duplicate keys ia the ren-racd snrsy. So* asao: - kry (E Association) markUndo - (void aarkU->da Ends editing aad mar s the ctrreαi state of the undo suck as aa undo point. Aa αnda message reverts changes made siaor the last uado point martrd. This method does nothing if undo isn't enabled or if s mark is already set on Ihe lop of uado flack. So* alao: - iaUndoEnabled. - rel-aascUndoa, - «ndEdHlι aritUndo: — ma ttλidouenβVr This aclioa method invokes mark Undo aad returns self. ma rkaEvαryO o ration - (BOO !inriuEveryOperatlon Returns YES if aa undo point is marked upon every insertion, deletion, aad application of ediu to an enterprise object. NO otherwise. Controllers created prσgrammaiically by default doc 'I mark every operatioa. while thaac creaied ia Iaierfacc Builder do. Soo aiαo: - ddeUSdcctioα maxlmumUndoMarfca - (unsigned JatJa-aaiiin-αmUndoMar s Returns the maximum number of uado marks the controller will record. Marks added beyond this limit cause earlier marks to fall off the queue. This method is nscfiil for restricting memory ussge. The default maximum is zero, which actually indicates so limit. SM afato: - bUodoEnabkd MxtCon trailer - (EOController * ιcrtConlmO<r Returns the next eoatroller ia the controller chain. Sec the class description for information on the αootrofler chain. radiαptay - (voi jwrdbptay Scads rentrαUDidCbang* lo all the controller's associstioas. causing them to redisplay their user iaierfacc kerns as seeded. Also has the coαu-oller's detail coαuoHen and acxl controller redisplay. Soβ aino: - BcxtGofstπ er rsiαaMUndoα - (void)rτlιastUι»dos Clean all undo iaformatioa. No uado is passible until a sew undo point is esublished. either auiomaiicaJly or with B-er Ut-da. So* also: - marks EveryOperatloα remove Aaaoc-lαti on: - (void)r>mαv«Asnocsatioo:(EθAssociaiioa • -»-Λj oe-aoon Removes anλuo vmto- from the set managed by the controller. Sax also: - addAsaodatiαn: ToDa aSouroa Automatically - (BOODaav-aTaDntaSuarrtAtamadcsJly Rr-curns YES if saving to objecu. or inserting or deleting aa object, results in the controller performing saveTaDataSaαrct. NO if k doαa'l. Controllers seated programmatically by default don't save automatically, but those creaied ia later-face Builder do. See aiao: - saveTaObjecU. - aavesToObjc-t-UAαtofnaϋcally ToObjβc aAutomatJcattγ - (BθOL avαTaObj ctsAato ati-----I>y Rcαir-u YES if the co roflcr immediately performs savcTsObjecU when aa association notifies k of aa edit or when aa object is edited with aetValaes-fβrObjecl:. Returns NO otherwise. Conα-ollcrs created programmatically by default doa'l save auomaijcally, but those creaied in Interface Builder do. Soα aiao: - aaaudntJuuDMEdh:, - aavaaToO^aSoareeAatoaaadcsdly aa-voToDαt-sSou-*oa - (BOOl aavcToDa Sβe-rc-e Ends edkiag aad saves all pending operations for the coao-oller iuelf. for ks detail cootrotJeπ. aad for iu next controller. If none of the eoetrollers has saved ediu lo their objecu. this method has no effect: use navtToObjacts to make sure pending ediu are applied lo the objecu before invoking savtToDats£α rc-e. Returns YES if all dianges are successfully saved lo the dau source. NO if aay save operatioa fails or is refused by the delegate. If this method re-rur-u NO aad the controller' i dau source doesn't sufφo-rt rolling back operations, some changes may have been saved anyway. la saving aa object, the eoatroller sends it a prv-pa-r-tFαrOa Sa-srce message (if k responds). If the object returns NO Ihe controller scads iu delegate a cnntnl rtabjael^aβadTβPrrpareForDalaSoαrcc: message. If Ihc delegate icons EOCaa-dnseDat»Soαι-cτFa1αreRα(pn-nae the eoatroller eoαlinues saving the remaining objects. If Ihe delegate returns EORs(lba-kI>atnSa«rc<FailαrrRcspncsse or doesn't iπφlemenl the delegate method, the controller rolls back all operatioαi if the dau source suppαru follback— and returns NO. If the object icons YES from prepartForOntaSoaree. then Ihe controller checks with ks delegate for each operation 10 save aad aesds taaβ-tObjrrt:. detetrObjaet-. cr αpdalrOfejreti to the dau source depending an the change to be saved. If aay of these messages fails, this method informs Ihe delegsie. stops saving, and returns NO. This method may invoke aay of the delegate methods listed below, depending on the individual save operations being pe-rfcrmed. See the dc α-ipuoαs of the individual methods for more information oo how they interact wkh ecvroOα:ι-bjeα*faπeιπ'ol repareFerOauSource: coetroner ntSavcToOauSourcc: coβwΛet DidSa vcToDauSource : coαuoner--wniRollbackDsuSouι-ce: coαuoOcπdidRonbackOuaScaBer: RECTIFIED SHEET {RULE 91) eontrotlerwillIascπθbject:iaDauSour-oe: control IcndidlnscnObjectaaDauSourae: eoatrollcπfailedTolnae- * tθbject-iaOalaSouree: coMrolleπwillOeleleObjecl-iBOnuSource: coatrofleπdidDclctcObjeα-iaDauSoui-cc: ooetrolleπfailedToDeleteObjectanDal a Source: coatroller-rwillUpdateObjecuaDaiaSource: coatrellendidUpdaieObjeα-inOnuSouroe: cootrolleπfailedToUpdaιeObject:inOnuSource: &n« also: - tnacrtObjectAtliidex:, - delcttObjectAtlndex:, - mdEdilJnf aaveToDataSourc-a: — aavcToOat-aSoαrcesss-ndrr This action method invokes s-avcTnDα Soαrce, rctining self if ssvcTαDataSowce retuπis YES. -sal if it returns NO. βavαToObj-scta - (BOOUaavcTnObjecta Ends editing sad saves all ediu made to objecu as operations to apply to the controller's dau source. Returns YES if all ehaages are successfully ssved lo the cootroller's objecu, NO if aay save operation fails cr is refused by the delegate. If this method returns NO some changes may have been saved while others may not. la savisg a set of ediu lo aa eaterprise object, the eoatroller first confirms ihe scϋoa with ks delegate by seeding it s eaotreBcTTirillSawcEdilsrtoObJecti message; if Ihe delegate returas _t the eoatroller aborts the save operatioa aad returns NO. The ccαtrotler takes a aoo-nO return value from this message and eooveru ihe new values by sending Caere* Vala-r-forKryi lo ks dau source, h thea applies the coαvcncd values to the eaterprise objeci by sending the eaterprise object a takeVaJβesFpowiDietiaoaryi message (a method of the access layer's EOKeyVahtcCodiag informal protocol). After saviag each object the controller sends ceotroO«r-dIdSaτcToObj-rct: to iu delegate. If the eoatroller saves to Ihe dau source automatic-ally then the each saved edit is immediately applied to the data source. If the eoatroller doesn't save changes automatically, the ehaages doa'l affect the data source uaul ihe controller receives a s-sveToDαtaSoαrcc message. finally, after saving all ediu Ihe controller scads cooteαlsDidOianfv and daaαardEdits to s asso stic-u. If all of the changes were successfully saved, die eoatroller has iu detail ooso-oflen and next coαuolkr save to objecu as well. Son alao: - aanod-aϋoαPidEdte. - setValacs-JorObject:. - savtTeDα Soαrce, - eo EdJtiι*-c aavαToObjαcta: — saveTaObjcctsu-mαVr This actioα method invokes naveTsObjecls. returning sdf if βn*eTβObj«ls returns YES. nil if a renirαs NO. aalactWaxt - (BOODsdectNcst Selects the objeci after the eunenlly selected object. If no objecu are selected or if the last objeci is seleαed. then the farst objeci becomes selected. If multiple objecu are selected, this method selecu the object after the Can object ia the selection. This method rcsulu is a aetSd-rftlonlxadf-acs: message being scat, aad rma-as Ihe value renm-rd by that message. This method is useful for user interfaces thai display only one object st a time. S*n alao: - ar iNcxtt — ade-ctNcxtumder This action method invokes orlectNext, rcttrning sdf if aelectNcxt retunu YES. ail if it returns NO. aaanctPravlotia - (BOODsdedrrtvioαn Selects the object before the currently selected object. If ao objects are selected then ihe first object becomes selected. If the fast object is selected thes the last object becomes selected. If multiple objecu are selected, this method selects the object before Ihe fast objeci in the selection. This method resulu in a sctSelcctionlndcxα: message being scat, aad retina the value returned by that message. Thii method is useful for user interfaces thai display ααly ooe objeci at a tune. Sao alao: - sdcctPrrric-as: aaanctPi a v lottos - a«-h i tfu i la-aa -sender This action method iavekes seiedPrrrieαa. renming self if sckctPirvioαs reams YES. nil if k returns NO. - (NSArray • tt*<tedOb «ts Returns the sdected objecu. So* aiao: - seieedαulssdncs nα-tocooolndα- ** t * -α - (NSArray *)Bel*cdoalnd«xes Returns aa array of NSNumber objecu identifying the indexes of the selected objecu ia the controller's array of objecu. Soα -a o: - ae ctrdObjecU. - nBObjeets ails et r-ratObjactAnαrfatch - (BOOL actsF πtObj*ctAA«rFrtck Rcα-ma YES if ihe ooauoder selecu the fiπt of iu objecu after performing a fetch, NO if not. salOataSourcα: - (void c ( Oa Sα«recι0d <£ODauSouree-t-> ι0onι o>--rr Seu Ihe ooavoller's dau sourot: to aDataSourct. clean the selection aad the undo stack, and discards all pending changes. This method invokes the delegate method cαtπlroOcndidClianccDniaSoarec Sat alao: - relaaatUndoα, - dkcardEdits. - dcarSet dioα aatOolαgalα: - (void «tD«lrtβte---βt06'ecr Seu the controller's delegate to tnObjeel. Doesn't retain mObjea. aαtMar sEvαryOpαration: - (void>ctMariuEvci7θpcratioo:(BOOLyiαg Seu acoordiag to /log whether the eoatroller marks aa αodo point for every insertion, deletion, or edit of aa object. Controllers creaied progrnmmaϋcally doα't mark every operatioa by default, while those created ia Interface Builder do. Son aiao: - maHtUoda, - deteteSelecUoα aothbudmut-n UndoMartca: — (void etMa-dn»ι-aUndoMarfcss(uα--igacd ial>s-t/u Seu to a a/ the maximum number of uado marks lhat will be recorded. Marks added after the maximum amouat will causes earlier marks lo be discarded. This method is useful for restricting iimiiuy ussge. Setting the maximum 100 allows unlimited undo queueiag: this is the default. Use nctUodad-a-Mnli to disable undo. Soo aloo: - node s-atNαxtConb-olloπ - n- NextC«-αtr---llcr:(EOCoαtπ>ner •)aCβntrtiler Seu Ihe aext eoatroller ia the oonσoller chaia to aControtUr. See the class description for information on the eoe β oOer aatSavaaToOatsSourooAutomatical r - (BOOL c SavαtToDwlaSe«reeAalaaBadαaOy:(BOOLyiαf Seu according to /log whether c-pβatiαβs such as insert, delete, and update with edks automaticaJly re-wlt ia Ihe eoatroller performing savcTaDalaSoarca. Returns YES if successful. NO if Ihe eoatroller has any pending αpcraboas for a dau source. CoatroOcπ creaied pro-pajnmaιically doa'l save automatically by default, but those created ia Iaierfacc Builder do. Soa feo: - KtSaveaTeObj-rctaAaleaaatfcmflyi aαtSavaaToObfactsAutornatically: - (BOO etSavtsTaObjrctsABlomnlkafly:(BOO yi<ig Seu according to /log whether the coαu-oller immediately performs saveToObjee when aa object is edited. Returns YES if successful. NO if Ihe controller has any pending ediu for iu objects. ComroDen created pregnmmaiically doa'l save automatically by default but those creaied ia Iaierfacc Builder do. Soa aiao: - setSaTeaToOnts k Soαr R A B tomatically-. - assodatlonDidEdki. - p-rlVaraβ-.farObjecti aatSokoetlonlndaxea: - φOOL rtS«lrctiαnInd«xes:(NSArray ')aSrlecήσn Seu the selection as sa array of NSNumber objecu. Returns YES if Ihe selection is changed to Stltctiort. NO if ooC The controller recursively sends bDisα-s-dABowcd to sll of iu detail coatroUers. and if any of them rctin-ns NO the selection isn't dunged. If Ihe detail eoetrollcrs allow discard this method invokes tndEdiάng. seu the selection indexes, aad notifies iu associations with aek edooDid Qiigt. Finally, this method scads ca-ntr»B«rDidQιatιg-tS*lw.t>uot lo Ihc delegat If aa association allempu to dunge the selection of iu controller and fails. Ihe assodatioα should reset the selection of ks user iaierfacc objeci from the conn-oiler's selection. It can do this by simply sending ksdf a --deeώooDldChataa-e method. aotS-a cteFkvtOb^αctAftarFatch: - (void e<S«l*<uFlnK>bjcctAncrFt4f*:(BO Lyi-ir Seu according tojlβg whether the coαuoDcr selecu the first of iu objecu after performing a fetch. So* aiao: - s-rtSciretio-αlαdexeii aatUndo Enabled: - (void>rtUDdaEa-aUed:(BOO iog Enables or disables undo according ιo/fag. Undo is by default not enabled for controllers creaied programmatically, ■hough k is for t-oαtrollα-s creaied ia Interface Builder. This method doera't affect existiag tmdo marks. You caa temporarily disable undo, then rentable it aad perform aa uado: however, aay diaa-gee made while undo was disabled won't be reverted. aetValu«a:forOt>4ac - (void (iVa)aes:(NSDictionary * nrwValueι forObjecl a-πEO Applies nrwValma to anEO as if they were ediu made by aa assodation. If the eoniroller doesn't save automatically to objecu. the aew values are buffered as ediu thai will actually be sent lo anEO upon Ihe next savtTaObjecta message If ihe eoatroller saves automatically lo objecu then the changes are immediately saved to the objects. The conuoner's associations are MM notified when an edit is made with this method. You should send Ihe eoatroller a w bplej message after you fini-h editiag objecu programmatically u> update Ihc user interface. Soα a-koo: - aa- nϋ d jnDidEdhi. - aaveaTe-ObjectaAnlemaUcnBy undo - (void)αndo Reveπs dl ehaages ia ihe uado stack lo the last uado mark set; inserted objecu are removed, deleted objecu restored, aad aay ediu are reversed. If there are ao uado marks set. does nothing. This method Tint iavokes aavcToObjects lo accumulate all ehaages in Ihe operation buffer, from which they're reverted. If the user is editing a value and the eoatroller marks every operatioa. this resulu in the undo opcrsiioo nattnlly reverting just the edit ia progress. The controller notifies ks delegsie before reverting changes with a ot-nlnΛerVVππJndβi message; if the delegate returns NO the undo operation is aborted. Similarly, for each change reverted ihe ooβuolkr sends iu delegsie a enαts-sDerrwiπUndoObject! message; if Ihc delegate returns NO thea the uado for that objeci is skipped but the undo operatioa continues. After the dunge is reverted ihe eoatroller sends ceatrnllertdidTjDdeObject: to iu delegate. Finally, after all diaage) have been reverted, the controller scads eontrβflerOMUndoi lo s delegate and α-ntcnUDidCfca-nge lo iu asso-aations. If the controller'! selection changes k also sends s-rla-ctiαoDidChana-τ to iu assodauoαs. Sao also: - crtdEdiUnc. - redisplay, - mark Undo. - setMaduEveryOpentieα-. - s-riUndeEa-abled: undo: — a-odβuenαVr This action method iavokes aadα aad rctins self. Methods Implemented by the Delegate oonli uBαi .a— ociatioo:dldEdltObjoc :lt-»yrvaiuα: — (void)cβntι--»De-*-*<EθCoβt*-oller m co*troβer *iadβαι(EθAssocsatioα * s-iΛsτo --α-icπ dUEdHOb)«ctuai£0 kry:(NSString \aKey vahseidYO *- Seat from aaaockatiaαOidEdlt: to inform the delegate that enAj-ronαrien has performed aa edit. controDondldC angoOataSoureo: - (void)caotro »en(EOCcβtroller •)ca-troUer didαιaιγcDalaSoαrcc:(id <EOD*-S~-c t>t-DataSamrce Sent from sctDα Sβαrcei lo inform the delegate that eontrol r'i data source is now aDa—Source. centre BorMdCh an goSel action: - (void)cαsιt---sOcrO<dClMntcS<lccϋoo:(EOCoαuoller *)c*-roUtr Sent whenever controller * selection iaages lo inform Ihe delegate of Ihe change. oontrofcacdW αlβtβObjoct - (void)ean<raαen(EOCαs-roller • inUtr didBvlrteO jw-tt-w-TO Scat from aay of the delete methods lo inform the delegate thai c-vnller has deleted anEO. oontroftar.dtdC)αJoα»Ob}octlnDataSoιι--c-a: - (void)-, uuti u»n*-(EOCoo -roller ' / controller dldD eteObj-retumiO h-DalaSaapc-fiiftsnSoarcr Sent from sav«TβDa Sa-an-e lo iafor the delegate lhat controller has deleted anEO from aOαJαSeαree. oontrol ctΛdFβlch Objects: - (void notroOcr:(EOCoαD-olleτ • conιroller d)dFctd--θbj*cU:(NSArny 'yobjec Sent from fetch to inform the delegate lhat controller has fetched the enicrprise objecu iα objects from iu dau source. oonvoflαc OTCπt-sαa-ft bfαct: - (void)eeotroBen(EOCooeoller •)conιroUer cSdlnaertObjecl-øicTO Sent from aavcTeObJecU lo inform the delegsie thai conl roller has inserted twiEO. conboHαr.iiklhiαaitObjactlnDαt-aScΛiroα: - (vcώf>eae-trβ*«rt(BθCoβo-oller 'Controller dUIsmnObj-Ntu-nfO tnDataSaarn nCkmaSourct Seat from aavtTβDartaSoαsτe to iaform the delegate that controller has inserted anEO into aDataSource. eontronordidRoll aelt-DαtsSotifea: - (void)eaββPβ»er:(BOCooO*oller a )ccwroiterdidRαllha<ld>ntaSnαfτct(id <EODnuSouroes>)αOαlαSM-re Sent from aavcToDαtaSe-arce lo inform Ihe delegate thai controller has rolled back ehaages ia βftuαSowrcr. oontrottorOtdSavaToOataSotiTca: - (void)cae--UvBcrOlaSav«TaOatae > oanc:(EOControIler * control r Sent from aaveTaDα Soαrcc to iaform the ddegale lhat controller has finished saving all operations to iu data source. This method is only invoked if all operaiiααs were successfully saved. e-ontroSαcdidSavαToObjβct - (void)eMtrnβen(EOCoαff oiler ' contnller dldSaτcTnObject--mcTO Scot from aavcTaObjrcta to inform Ihe delegate thai eoniroller has saved ediu 10 tmEO. oonfroftαrOtdUndo: - (void)caMraaWri)WUtadai(EOCoauolleT *)conιroller Sent from aaie lo iaform die delegate lhat controller has performed aa uado oper β io β . conlrollαcdldUndoObjβcfc - (void)e β ntrafleπ<EOCooβt>ller * conlπHler dldUDdoObjectieMcO Seat from β odo to inform the delegate that controller has uadoαe diaages to anEO. oontreltondidUpdarle bjoctlnOatoSourea: - (void)eeαtmαcn<EOCoαtraπeτ ')ca-tr-iltr hDalnSnαrreKiDcS-tSounre Sent from aavcToDatmSoaπe to iaform Ihc ddegate that controller has updated anEO ia aDaiaSourct. oontroπortaπaκfToD-slαtβOb|βct:inD-rt*Sotjreα: - (E0DataSct-rccFailtαeRespoαse)c--ntroBer:(EOControαer 'Controller faOedToDdeteObject >on£0 biPala*;— r * rainf>iatiifin>rcc Seat from aaτ«ToDalaSaoι-ce lo inform the ddegate that controller has failed lo delete anEO from aDt-aSour-e. If the ddegate returns EOCandnaePal aSaa m FaflαreRtsyuust eoniroller continues saving other ehaages to the dau If Ihe delegate reams EORellbar It Datafinmi i, t FaflαraRcsponee controller sends rollback lo iu dau -ouroc if the dau source responds to lhat message. aavcTaOalaSoatrce then abαru aad icons a failure result. Ia rolliag back the dau source, the eoatroller iavokes Ihe delegate methods cααtraflcrswillRaObwdtD-ataSαai-cc: aad enolsoβendldRααbadkDaUkSonwNect. conb-ollontaflarfTotn-MftObjoc inDataSourc-i: - (EθDauScurceFuTureRespoαse)ee«trβl n(EθControOer 'Controller f«B«dTβlneertObjeetι-»ι£C> biOata < ii»-at * T--*nn«<iTimm * g Sent from aaveToDαiaSoαro to iaform the ddegate that controller has failed to insert ωtEO into aDaiaSauret. If ihe ddegate returns EOCaαdaαcDaaaSaαrecFdlαf-eRcspoαs-e eoniroller eoαliaues saving other diaages to the dau source. If the ddegste returns EORnflbac I)α«jaS«mrecFaaαsτReapαoβc controller scads rαilkack to s data source if the dau souroe responds lo that message aavtTβDa4*Sα-sr-t-e thea abocu aad returns a failure resuh. Is rollisg back the dau souroe, the eoatroller iavokes the delegate methods eβotroαerrwfilRoθ ackDataSβarre: and eoolm*cndldRnlhαrlrr>αtaSeorτrt. oontrotl-scfalladToUpdataObj*sct:lnDat Souroa: - (EODniaSragceFailuteRespoiise )cao4faaen(EOCoatroller 'Controller fafl«rTaUpdat«<H>*ctιβ.e:θ faDa-taSaa rrn iΛt siiTim irr Seat from savaTαDαlaSaarta lo iaform the delegate that controller has failed lo update m£0 ia aDai Sourte. If die delegate mures EOCa*nd-*»«Data«i«au i Fa-ll-ar*eRua*ana« controller eoαtiαues saviag other ehaages to the dau aαusee If Ihe delegate reairas EOReflbachData-iiasiTi FaflerrRas-paina-r controller sends rαifcaefc to ks data source if Ihc data souroe responds lo thai message. savaTαDslaSaan i ihea abαru aad retina a failure resuh. la rolling back the dau sovce. Ihc eoaoollcr iavokes the delegale methods caαtrnOcnwllIRnObad-Dn Sααmi aad eant-rαOcr-dld Rod adkDataSoαm-. oontrol r.ob^sctfallαdToPrapar-aForOataSourca: - (EθDnuSouroeFaihκRespoαse)eaαtrBl)cn(EθCoαB-ollcr 'Controller tbjuctienEO faa«dTefτ--pα***tFaι-DataSoαrce--ιf>rιl«ι7cHi-τr Sent from aaveToD-UaSo-ar-c* when anEO returns NO from a prtpar-rFor-DαtaSαof-ta message If Ihe ddegate returns EOCaodo-aaDαt-aSoarecFaifar-tRcspoαac controller continues aaviag other changes to Ihc dau souroe If the delegale reams fOR'-πiia- kPalaTaan - aflan ITi n»ιιιι controller scads rollback to iu dau source if Ihe dau source responds to that message aavcTeDataSoαrce then abcru aad returns a failure result. eonfroa naavoObiactaFaHodForOattaSouroa: - (void)cest«ralle----(EOCαavoller 'Controller ssrv«Obj(CtsFdledFarOaUSoαrcc--iDαta e«ι--cr Sent from naveTaDaaaSo-α-cc to inform the delegale that aDaiaSauret returned NO from a snvcObjects message. - (BθOL)cαotrd1*n(EθCoo-iroIl--r •)c«*- * roMer wiUDdcteObj-rctiøtcTO Sent from aay of the delete methods to inform the delegale that centnller will ddeie anEO. If the delegale returns NO Ihe βele oa isa't performed aad aaτ-*TβOfcj*cU is aborted; if the ddegate returns YES Ihc deletion proceeds. eonfroi-sr^dllD-aannsOtiHΛlnDαtaSouroβ*. - (BOOL)esαtralt*n(EθCovαoller 'Controller wtHD-rieteObj-retiαncO bιDaSaS«-αr*,ι iiPmnTomTf Sent from saveTnOαla-Soαrc-t to iafαrm the ddegate that controller will delete anEO from aDaiaSomrce. If the delegale icons NO the deletion isn't μ ifcrtind (though anvcTnDntaSoaurcc continues for other operations); if the delegale returns YES the dele-boo proceeds. eonb«l*arWniDUeaπlEtitn: - (BθOL)cαotr-dkrVrl * α>iacvdE<lhst(EOCootroller 'Controller Scat from WMaeardAJtowvd lo iaform the delegale thai controller is about to discard pending edits. If the delegate doesn't implement this method controUer opens an attention panel warning the user lhat ediu may be discarded. If the delegate returns NO then laDiscardAlew-rd returns NO; if the delegale returns YES then laOinαwdΛBawed proceeds. If the delegale warns to make sure ediu are preserved it caa explidtly seed anv*TnObj*ds 10 controller. eofitrokrWMDtoeardOpon-tio-nα: - (BOOL)esertι^krVyπD)(scardC p« «Unnαt(EθCoetroncr 'ControUer Sent from laOtacardAΛawid lo inform the delegsie thai controtlerw' about lo discard pending operations destined for ks dau sot-roe. If the delegsie doess'l implement this method controller opens aa aticatioa panel warning the user thai updates may be discarded. If the delegate returns NO thea IsOtscardAllαwnd returns NO, if the delegate rctt-ras YES thea bWsrαardA Iewvd proceeds. If Ihe delegate wants to maloe sure updates are preserved il caa expti lly send aaτ«TaDat*Soer--* to controller. contr πorWUIFαtch: - (BC DL)eefltr-d rVYlDFetd»t(EOContro<ler 'ControUer Invoked from fetch to iaform Ihe ddegate that eoniroller is about lo fetch. If the delegate returns NO the fetch is aborted: if the delegate returns YES ihe fetch proceeds. oontrollaTrarfπinaartObjocbatlndar: - (BOOL)cot»tre»lletn(EOCoetroner 'Controller wfUa-prrtObjctliαieTO atiβdexι(uasigacd inl'm/n ex Seat from lnacτtOfejecisatlBd«-χι to inform the delegale that controller will insert t iEO into ks array of objecu at anli— lex. If the delegate returns NO the iasenioα is aborted; if the delegale irons YES die insertion proαecds. The delegale Buy modify anEO, usually by setting ks primary key lo a unique value. contrel r*- liπnaartOb)αctloDαtaSc iroa: - (BOOL)eααrt-mOert(EOCoalroner 'ControUer wiBIsMertObJ«cti-n£0 kiDelnSeαrrs laDalaSour-e Sent from aavcTeDataSaam to iaform Ihe ddegate that ro-vi-e-flrrwill insert loiEO iaio oDataS urct. If the delegMe returas NO the iasenioa isa't pcrfumul (though savcToDaUSα-arcc coα sues for other opentioαs . if the dele-gate icons YES the iasenioa proceeds. oontroBocwlllRoflboc-fcDa aSouroa: - (void)e«aιtr<Λert(EOCootroller 'Controller wORooα-ac DαlaSoαree- -d <EθOn Souπx£>)αOαtαSewrrr Sent from s*avcTaOetaSnarc« to iaform the ddegate that controller will roil back changes is Da— ource. The delegate can't prevent this operatioa, but may take whatever acϋoa k seeds based oa this iaformatioa. eontroHo alllSavoEdllKtoObjoet: - (NSDictioaaηr *)eeα-tralcr>(EOCoαtπ>ner 'Controller wiOSa-xEdMsiCNSDictioαary *>ιeκ-Vαfsrs laObjectum TO Scat from aβveToObjects lo iaform the delegate lhat ceπiro/irrwiu save edict lo anEO. newValues is a dictionary of key-vahie pain whoae keys are the aames of properties beloagiag lo a*EO aad whose values are die ae-w values anEO will be gives for those properties. The ddegaie caa renn the vahies as they are, or caa return a substitute set of values to apply lo the object. If Ihe delegale returns oil the save isa't performed aad saveTaObjecU is aborted. oontrollerWlllSαvαTo D-ataSo-uroo: - (BOQUceotrol rWlDSavaTa-Das* aS ism i(EQCootroiler 'Controller Seat from savaTaOataSsaitt lo iaform Ihe delegate that controUer will saves duages lo iu data source. If the delegate reαns NO the save is aborted; if the delegate returns YES the save proceeds. eontroOarWHUndo - (BOOL MtrniWrrVl-nλ atι^OCoαDoner 'Controller Sent from tmdβ to iaform Ihe delegate thai controller will undo ehaages. If the delegate rcturas NO the αado operatioa is aborted; if the delegate trims YES the uado operatioa proceeds. - (BOOpt—OnOti .(EOCoag-oflcr 'Controller wimj-adaObj-KtusifO Seat from oado to iaform the delegale that conm ler will aa o diaages previously made to anEO. If the delegate rcαras NO tbe aado αpcnuάoa for «ι£0 oαly is aborted (the larger αado operation proceed)); if ihe dekgau teens YES the undo op-nioα for anEO proceeds. tJu<i t>Λt-*fτt-- * ιlRlρdakt-Objαc ϋnPt * rttittouroa: - (BOOQjitrsΛt π(EQCoeiroflcr 'Co-trol r wOUpdtd«Ob>n«tiei£0 Scat from aav.TeDαtaSewes to l afcno the delcfale lhat controUer will apdala anEO ia oDataSourct. If the ddegate reαa-as NO tbe update isa't pa f tamed (though aβveTaDataSβarea continues for other operations); if tbe delcgau reαras YES Ihe npdaic proceeds. /15852 - 55 - Enteφrtic Objecu Framework Release 1.0 Copyright OI994 by NeXT Computer. Inc. All Rights Reserved. EOAssociation Inherits From: NSObjcct Conforms To: EOAjjocialionNolificaiion Declared In: eαinlcrface EOAssocialion.h Class Description EOAssociation is an abstract class denning the link between an EOController, which manages a collection of data-bearing enterprise objecu. and a single user interface clement, such as a column in an NXTableView, or i control. An EOAssociation coordinates the display and editing of property vduct for its controller' s enterprise objects. EOAssoctations can dso link two controllers (see Ihe EOQualified Association class specification for more information). An EOAssociation links just one properly of the objects supplied by its EOController to iu user interface object This property is Identified by a key as used in the access layer's EOKeyVducCoding informal protocol. An associatioo for a user interface object capable of displaying multiple enterprise objects (such as an NXTableView) displays dau for all objecu in the controller, while an association for a user interface object capable of displaying only one enterprise object (such u a TexiFteld) displays data for Ihe Tint selected object in ihe controller. An EOAssociation it notified of changes in iu eoniroller through ihc EOAuoclationNoiiftcalion protocol. Upon receiving notice of a change, the association determine! which objecu il needs to display vdues for and sends each a valuesForKeys: message with an array containing Ihe key for the association's property. The association then update! the user interface object with ihe value relumed if It's different from ihc current vduc. If the EO Association' I user interface objeci changes, then Ihc EOAssociation must send thai change lo iu controller. EOAssoclations usudly set themselves up is the targets of control object so lhat they're notified of such changes. For example, when ■ user ediu a TexiFteld representing the name of an enterprise object and presses Return, ihe TcxtFicId sends iu association an action message. The EOAssociation then gets the new value in Ihe TexiFteld and informs its eoatroller that Ihe user interface object changed by sending the controller an associationDidEdit: message. In response lo this notification Ihe controller sends a value message lo the association lo get the new value for the enicrprise objeci. For more information on how EOAssociation) work with EOControllert and user interface objecu. see the EOController class specification and Ihe EOAssociationNotification protocol specification. For information on associations for a specific destination class, sec one of the following class specifications: Association Subclass Destination Object Class EOActionCellAssociation Any ActionCell subclass (such is TextFieldCell) EOBrowser Ass ciation NX Browser EODullonAssocialion Button EOColumn Association NXTableVector (in an NXTableView) EOControlAssocialion See below EOtmageAssociation NXImageVicw EOMalrixAisocialion Matrix {but see below) EOPopUpAstociation PopUpLiit EOQuαlificdΛssociation EOController EOTcxt Association Text EOControlAssocialion can be used with any "simple" control that manage! a single value, such as a Tc-u Field or a Slider. However, if a control has a dedicated association subclass, you should use lhat. For example. Buttons should be linked with instances of EOBullonAssociαlion. Note: EOMalrixAisocialion has very limited functionality. If you want to create associations with individual items in a matrix (especially with fields in i Form object), use EOActionCellAssociation. Although Ihc interface of any association contains only a few methods, their implementations are often highly dependent on one another and on the way lite destination objects act. Because of ϋiis. if you need lo create an association class for a custom user interface object clast. you should create it as an immediate subclass of EOAssociation. instance Variables None declared in this class. Adopted Protocols Instance Methods controller - (EOController -^controller Returns the EOController responsible for Ihc issocialion. destination - destination Returns the object lhat the association monitors. This is typically a user interface object, but doesn't have lo be. - 57 - lnilWllhController:key:destlnatlon: - liillWllliCoiilrollcr:(EOConlrollcr '^Controller key:(NSString ')aKey Initializes a newly allocated EOAssociation with aConiroller. αKcy is the name of the property represented by the association, and is used as the identifier for value transfers lo and from destination (typically a user interface objeci or another EOController). This is Ihc designated initializer for Ihc EOAssociation class. Returns self. See also: - addAssociallon: (EOConlrollcr) key - (NSString »)kcy Returns Ihe name of the property that Ihc association transfers to and from its destination. value - value Returns the value of Ihe association's destination as an instance of an appropriate value class (see "Mapping from Database lo Objects" in the access layer's EOAttnbule class specification). For example, the value class for a TexlFteld's value it NSString. For applications using the access layer, if the value class specified for an enterprise object's attribute in the EOModel isn't NSString or NSDau, it must match exactly the value class used by Ihe association. See also: - key, - takeValuesFromDictionary: (EOKeyValueCoding informal protocol) 5S Enlcr-xtsc Objecu Framework Rcleue 1.0 Copyrlcht OI994 by NeXT Computer, Inc. Alt Rl ( hu Reserved. EOActionCellAssociation Inherits From: EOConlrolAssocialion : EOAssociatio : NSObjcct Conlorms To: EOAssociationNotificaiion (EOAssociation) Declared In: eointcrface/EOConirolAssociaiton.h Class Description EOActionCellAssociation is an association lhat works with an Individual cell of a control such as a Matrix. A cell association Is needed because a control offers only a single lexl delegate for all of its cells, but an associatioo linked with a cell Deeds to know when iu own cell has finished editing. If you set up several EOAclionCellAstociationt with a Matrix, for example, only one can be the text delegate, making it difficult for another lo be notified when iu cell ends editing. To avert this problem, EOAcϋonCellAssociations register themselves globally according to their destination cells. When their control object ends editing, the luociition registered u the control's text delegate looks up (he association for the control's selected cell and propagates ihe notification to it. Although the interface of any association contains only i few methods, various implementations ire often highly dependent on one another and on the way the destination objects act. Because of this, if you need to create an association class for a custom subclass of ActionCell, you should create it at an immediate subclass of EOAssociation. Instance Variables None declared in this class. Instance Methods None declared in this class. RECTIFIED SHEET (RULt 91) Enie flK Objecu Frame wot k Release 1.0 Copjrrlf In CI9 -4 by NeXT Computer. Inc. All Rl.hu Rcierveϋ. EOColumnAssociation Inherits From: EOAssociation : NSObjcct Conforms To: EOAssociationNolificaiion (EOAssociation) Declared In: coinicrface/EOColumnAssociation.h Class Description An EOColumnAssociation displays and edits a column of an NXTableView containing the values for its key of al] enterprise objecu in iu eoniroller. You can hook up any number of column associations to i single NXTableView, as long as tbey all have the same controller. However, because an NXTableView expecu lo hive only a single object acting as its data source (not lo be confused with the controller's data source), one of ihe column associations must step forward to play that role. The column associations for a particular controller and NXTableView know lo rendezvous under this lead association, which uses iuelf and its cohorts as column identifiers and forwards requests for data access to the appropriate association. Although the interface of any association contains only a few methods, various implementations are often highly dependent on ooe another and on the way the destination objecu act. Because of this, if you need lo create an association class for a custom subclass of NXTableVector, you should create it as an immediate subclass of EOAssociation. Edit Buffering Because an NXTableView doesn't store data on its own, EOColumnAsiociaϋons have to cache their edited values (in other words, buffered ediu not yet sent lo ihe eoniroller). When asked lo gel a value for a particular index, the association asks iu controller for the enterprise object at that index and looks for a value cached under lhat object. Only if il doesn't find ooe does it ask Ihe enterprise object for iu value. When ihe controller saves to objecu. all of iu column associations (and any other associations that buffer ediu) are sent dlscardEdlU messages telling them to purge their cached values. Setting up an EOColumnAssociation When setting up an EOColumnAssociation programmatically, you must configure the newly initialized association by sending it a setTableVlew: message with Ihe NXTableView of the destination column as in argument. This method seu the association up as Ihe NXTabIc View's dau source and delegale if needed. Sec the method description for more information. Instance Variables None declared in this class. Enterprise Objecu Frame wo k Rel ue 1.0 Copyrltlil C 199-1 by NeXT Computer, Inc. Ml Rlfhli Reserved. EOControlAssociation Inherits From: EOAssociation : NSObject Conforms To: EOAstociaϋonNoϋfication (EOAssociation) Declared In: eoinierfacc/EOConuolAssociaiion.h Class Description EOControlAssociation is Ihe default issocialion for all subclasses of Control except Button, Form, Matrix, NXBrowser, and NXlmageView. It seu iu control's value with setSUlngVatue: and geu iu control's value by invoking slrlngValue. A control association thus work wells with any "simple" control that displays only a single value, such as a TcxtFicId or Slider. A control association seu iuelf up as Ihe target of its destination conuol, and, if thai conuol responds to the sclTextDelegate: message, as the conuol's text delegate. This allows a conuol associaϋon to notify iu controller of an edit whenever iu conuol sends an action message and whenever iu conuol ends editing (for example, by the user pressing Tab or Return, or selecting another text field). Although the interface of any usociation contains only a few methods, their implementations are often highly dependent on one another and on the way the destination objecu act. Because of this, if you oeed to create an association class for a custom subclass of Conuol, you should create it as an immediate subclass of EOAssociation. Instance Variables None declared in this class. Instance Methods None declared in this class. 61 - Enlerpriie Objecu Framework Release 1.0 Cofiyrli'it CI994 by NeXT Computer. Inc. All Rl j hli Reserved. EOImageAssociation Inherits From: EOAssociation : NSObjcci Conforms To: EOAssocialionNolificalion (EOAssociation) Declared In: eoinlcrfacc EOImageAssociαtion.h Class Description An EOlmageAssoeialion uses an NXImageView to display an NXlmage for the appropriate key of its conuoller's selected object, and seu a new image for lhat objeci when one is dragged over the NXImageView. Although the interface of any usociation contains only a few methods, various implemenuiions arc often highly dependent oα one another and on the way the deslinalion objecu act. Because of this, if you need to create an usociation clus for a custom subclus of NXImageView, you should create it as an immediate subclass of EOAssociation. Instance Variables Nooe declared In this class. Instance Methods None declared in this clus. 62 - Entci-fvrtu Objects Framework Relesse 1.0 Copvt1|lit ©1994 by NeXT Computer, Inc. All Rights Reserved. EOMatrixAssociation Inherits From: EOAssociation : NSObjcct Conforms To: EOAssociationNotification (EOAssociation) Declared In: coi crfice/EOMau- Aitociation h Class Description An EOMatrixAssociation manages a Matrix of BullonCells u a selection list, adding cells for every object in iu conuoller and displaying Ihe values for its key. To work properly with a matrix usociation, a Mauix should use BullooCel of type NX.ONOFF, have a mode of NX.RADIOMODE, and be contained in a Scroll tew. This configuration allows you to use the Mauix to select a tingle objeci at a time. EOBrowser ssociation offers a more flexible selection list than EOMatrixAssociation, since an NXBrowter can allow empty and multiple selections in addition to the usual one object al a lime. A browser-bued selection list is also easier to set up, since there's no exua configuration to do beyond connecting the usociation. Although the interface of any usociation contains only a few methods, various implementations are often highly dependent on one another and oo the way ihe destination objecu act. Because of this, if you need lo create an associatioo clus for a custom subclus of Mauix. you should create it u an inunediate tubclus of EOAssociaϋoα. Instance Variables None declared in this clus. Instance Methods None declared in this clus. 63 Eiiieipilsc Objects Frame wot k Release I.OCopyrlfbl CI994 by NeXT Computer. Inc. All Rl j hu Reserved. EOPopUpAssociation Inherits From: EOAssociation : NSObjcct Conforms To: EOAssocialionNotificalion (EOAssociation) Declared In: cointerfacc/EOPopUpAssociation.h Class Description An EOPopUpAssociation uses a popup list lo display the value of an enterprise object for its key, and notifies iu conuoller when the user chooses a new item in the popup list. To set up a popup usociation, you have to create the popup list in Interface Builder and manually populate il with items representing the possible values for ihc association's key. You then form Ihe usociation from the controller lo Ihe popup list's button. When the usociation is notified of a change by iu conuoller, it gets the value of the first selected enicrprise object and looks for a matching tiring value in ihe popup list's items. If it finds an item equal lo the enterprise object's value, it hu the popup list select that item. If it doesn't find an ilem with the value, it temporarily creates an exua ilem with thai value, adds il lo the bottom of the popup list, and hu Ihe popup list select it. The next time ihe usociation u notified of a change in selection or conlcnu by iu conuoller, il removes the temporary ''em from the popup list. By temporarily adding items lo its popup list Ihe usociation guarantees lhat ihe right thing it displayed even for a value outside use set of "legal" values. When the user selects an item in the popup lilt, ihc usociation simply sends an associationDidEdit: message lo iu controller. An EOPopUpAssoclatlon's value is Ihc string value of Ihe selected Ilem in the popup list, so this ilem will be used u Ihe new value for the enterprise objeci. Note lhal if a temporary ilem wu added to the popup list, it's immediately removed if ihe user chooses a di ferent one. Although the interface of any usociation contains only a few methods, various implc enudons are often highly dependent on one another and on the way ihe deslinalion objecu act. Because of this, if you need lo create an usociation clus for a custom subclus of PopUpLlst, you should create il as an immediate subclass of EOAssociation. Instance Variables None declared in this clus. Instance Methods None declared in this class. RECTIFIED SHEET (RULE 91} 6 Enterprise Objects Framewotk Release 1.0 Copytlthl 1994 by NeXT Computer, Inc. All Rlfhti Reserved. EOQualifiedAssociation Inherits From: EOAssociation : NSObjcct Conforms To: EOAssociationNotificaϋon (EOAssociation) Declared In: eoinιerfacc/EθQualifiedAstociaιion.h Class Description The EOQualifiedAstociation clus implemenu usociaiioni between EOConuollert. Often teveral elements in the user interface are linked through a muter-detail relationship. EOQualifiedAstocisiioni esublish these links. When an EOConuoller receives a saveToObJecU, saveToDataSourcc, or redisplay mettage. It not only propagates that action to iu next eoatroller. but il alto checks each usociation lo tee if iu destination can perform lhat action, in which case il alto propagate* the action lo the usociation'! destination. The destination doesα' t have lo be linked through an EOQuallfiedAtsoclalion, though; it merely hu to respond lo ihe appropriate meuaget and have tome kind of usociation that works properly with 11 When an EOQualifiedAssociation receives a contentsDidChange or sclectlonDldChange from iu conuoller (the muter), it needs to requalify iu destination controller (ihe detail). It does this by gelling the selected object from the muter controller and using qualify llhRelallonshlpKeytofObJect: (described in die EOQualifiableDalaSourccs protocol tpeclficalion) to qualify the data source of iu destination controller with ihe usociation key and tbe selected object, and then having the destination coαUoller fetch lo update iu display. A detail conuoller can meaningfully display values only when exactly one object it telectcd in Ihe muter, if Ihe muter conuoller doesn't have exactly one object telectcd. the association pastes nil as ihe object to qualify for. which disables the detail conuoller. It's possible for an EOQualiriedAttocialion lo be tet up with a detail conuoller that doesn't yet have a dau source. In this cue the usociation will gel a detail data tource from the muter by tending il a daUSourceQuallfledByKey: message (described in the EOMulerDataSources protocol specification). It then usigns ihe new data source to the detail conuoller by tending it a selDataSourct: mettage. Instance Variables None declared in this clus. Instance Methods None declared in this class. Instance Methods setTablβVlew: - (void)setTableVlew:(NXTablcView 'CTableView If aTableView doesn't already have a column association from Ihc same controller is its data source, sets up the receiver as Ihe data source and delegale, so that it acts on behalf of all other column usocittions lied io n Table View. You should ilwαys send this message to i column usociation lhat you create programmatically. tableVlew - (NXTableView 'JlableVlew Returns the NXTableView containing Ihe destination column of the usociation. Ealcjprise Objecu Fnmewof k Rclcaie 1.0 Copytljlil 01994 by NeXT Co pulα. lite. All Rights Reserved. EOTextAssociation Inherits From: EOAssociation Conforms To: EOAssocialionNoiification (EOAssociation) Declared In: cointerfacc EOTexlAstocialion.h Class Description An EOTextAssociation manages a Text object, and it capable of handling display of ASCII. RTF, and serialized RTF with attachments (RTFD). A text usociation monitors any editing done lo the Text object, and when Ihe Text objeci ends editing (for example. If the user presses Enter), ihc text usociation informs iu conuoller. When a text associatioo it notified of a change by iu conuoller, it gett the value of the first selected enterprise objeci u raw character dau and examines it for an RTF or RTFD signature. Tbe usociation then tends the appropriate mettage to iu Text object for the formal, allowing tbe Text object lo properly display ihe value regardless of the formal. When uked for iu value, however, a text usociation returns an NSString (NSDala for RTFD) containing tbe text in whatever format iu Text object uses: Text Capability Text Format Single font Plain text in an NSString object Multiple fonts allowed RTF in an NSString object Graphics allowed RTFD in an NSDau object This can cause problems if you usociale a key whose corresponding value it of one type (such u plain text) with a Text object configured to edit another type (such u RTF). In this cue the enterprise objects receive text in a formal they may not be able to handle. You should alwayt lake care to match the text formats of the values you intend to display with tbe configuration of the Text object. Although the interface of any usociation contains only a few methods, various implemenutions are often highly dependent oo one another and on the way the destination objecu act. Because of this, if you need to create an usociation clus for a custom subclass of Text, you should create it u an immediate tubclus of EOAssociation. Instance Variables None declared in this clus. Instance Methods None declared in this class. - 67 - NOTIFICATION PROTOCOL Enicrprise Objects Framework Relesse 1.0 Copyrt.hl CI994 by NeXT Cwnpulei. Inc. All Rl j Wi Reserved. EOAssociationNotification Adopted By: EOAssocistion Declared In: eointerfacc EOConlroller.h Protocol Description Tbe EOAssociadonNoUficilion protocol declares methods sent by an EOController to tell its EOAiiocaiions about changes lo iu enterprise objecu. Whenever an object is modified by a conuoller, whether by being inserted, deleted, or updated, tbe controller sends each of Its EOAuociationi t contentsDidChange message, allowing Ihe usocistion to display any new values. If Ihe change to the controller also involves a change of selection, it sends selecliαnDldChangc to each association, to lhat Ihe usociation can display values for the proper objeci. or highlight the selected objecu if its user interface object displays multiple values. The conuoller also informs iu usocistioni when an operation it't performing would invalidate any cached values for the user interface objects. When the controller saves or discards Its buffered ediu. it renders any edited values cached by iu associations Irrelevant — tnd so It sends each usociaUon a discard Ediu message. For example, ao NXTableView doesn't actually store the values it ditp ys, but geu them through another object, such u an EOColumnAssoctilioo. The usociation object actually stores toy edited values for the column, snd discardEdlU informs ihe association thai Ihe cached values il hu are no longer applicable. Any other operation the controller performs — fetching, inserting a new object, selling an undo mark— requires editing of a user Interface object lo end. In thU case, Ihc conuoller seodi endEdlllng to each of iu usocUiions, so lhat Ihey caa finish editing, reclaim any shared resources (such as a window's field editor), and notify the conuoller with associationDidEdit:. Implementing the EOAssociationNotification Protocol The descripdons in this specificstion provide all the delails of whst the methods should do, but there are a few issues io implementing them that you need lo be iware of. Because an as ocisilon not only receives messages from iu controller, but sends them to iu eoniroller u well, a recursive loop could result If your usociation subclass sends messages back to iu conuoller from one of Ihe notification methods of this protocol. For example, if your usociatioα needs lo alter Ihe controller's selection in its own selecllαnDldChance mcsssge. It will be sent another scleetlonDldChaπga message while still handling tha first. You should either implement your utoclaiion not to affect ihc controller's selection or values, or you should devise a mechanism for preventing the utoclaiion notification methods from being recursively invoked. Another slight consideration stems from the intimate relationship between in uiocialiαα and lu user interface object. An usociation It usually so simple, and its I plemenullon to lied to Ihe specific behavior of lu user Interface objeci clus, thai It's usually easier lo implement t new utoclaiion as t subclass of EOAssociation rstiier than one of Its subcluses. Method Types Synchroniung values - conlenuDidChangc - sclccuonDtdChangc Handling edits - discardEdi — cndEdtling Instance Methods contentsDidChange - (votd)contenUDldChange Sent to an EOAssociation by its eoniroller whenever the controller' t objects have changed; for example, when an objeci is edited, inserted, or deleted, or when Ihe eoniroller performs a fetch operation. The utociauon should determine whether any values It's responsible for hive changed, and if to thould update iu user interface objec An usociation may be sent both a contentsDidChange and a selecllonDldChanga method for a tingle change tn the controller. For example, if a selected objeci it deleted, both the contenli and the sclecuon change dlscardEdlts - (void»lscardEdlU An EOController sends this method to iu controllers before fetching, to notify them thai any edited values they cache for their user interface objects ihould be disposed of. endEdttlng - (voιd)endEdlllng Informs ihe EOAstociatioo that il ihould formally end any editing in iu user ioierface objeci and inform the eoniroller of any pending edit by tending asioclallonDldEdlt:. Thit also ututlly retulu in the user interfice object rettgoing first retpooder. See also: - endEdltlngFor: (Window clut of the Application Kit) MlectlonDldChange - (voidjselecllonDidChange Sent to an EOAssociation by its eoniroller whenever ihc controller' t selection indexes have changed. Tbe usociauon should have iu user interface object redisplay itself lo reflect the change in selection. For a user interface objeci lhat displays i single value, the usociation sets that object's value to the property value for the first selected objeci in the conuoller. For a uter interface objeci lhat displays mulltple values, ihe utociation hu the object highlight iu values in accordance with the selection An association may be tent both a conlcn DIdChanςe and a selecllonDldChange method for a tingle change in the conuoller. For example, if a telectcd object is deleted, both lite contents and Ihe sclecuon change FSEUPQCQPE // We provide a default implementation of the Key- Value Coding Protocol // on the root class in the NEXTSTEP object hierarchy, NSObject. All // classes inheriting from NSObject will automatically get this // implementation. However, classes may override this behavior by // implementing their own versions of takeValuesFromDictionary and/or // valuesForKeys. ©interface NSObject (KeyValueCoding) - takeValuesFromDictionary: (Dictionary *)valueDictionary; - (Dictionary *) valuesForKeys: (Array *)key Array; ©end ©implementation NSObject (KeyValueCoding) / / Aggregate versions added to the root object class - takeValuesFromDictionary:valueDictionary { for each key and value in dictionary do { [self takeValue:value forKey:key]; } } - (Dictionary *)valueForKeys:key Array { id resultDictionary = [Dictionary new]; for each key in key Array { value = [self valueForKey:key]; [resultDictionary setValue:value forKey:key]; } return resultDictionary; } // single value versions - takeValue:value forKey:key { classlnfo = [self getClassInfo]; // look if they have method of name "set<KeyName>" methodlnfo = [classlnfo lookupMethodNamed:"set"+key]; if (methodlnfo) { type = getArgumentType switch (type) { OBJECT: [self callMethodNamed:"set"+key withArgument:value]; FLOAT: [self callMethodNamed:"set"+key withArgument: [value floatValue]]; All other types... ) } else { // look for instance variable instanceVariablelnfo = [classlnfo lookupInstanceVariableNamed:key]; if (instanceVariablelnfo) { type = [instanceVariableType]; // perform assignment to instance variable offsetOfVariable = [instanceVariablelnfo offset]; switch (type) { OBJECT: *(id)(self + offsetOfVariable) = valueToAssign; break; FLOAT: *((float *)(self + offsetOfVariable)) = [value floatValue]; break; All other types... } } } } - valueForKey:key { // like takeValue:forKey except backwards.. ;-) I.e.: classlnfo = [self getClassInfo]; / / look if they have method with the same name as the key. // e.g. "firstName" methodlnfo = [classlnfo lookupMethodNamed:key]; if (methodlnfo) { type = get ArgumentType switch (type) { OBJECT: return [self callMethodNamed:key]; FLOAT: // this method actually returns a C scalar numeric type, not an // object, so we have to put an "object wrapper" around the value // returned. return [NSNumber number WithFloat: (float) [self callMethodNamed:key]; All other types... } } else { // look for instance variable instanceVariablelnfo = [classlnfo lookupInstanceVariableNamed:key]; if (instanceVariablelnfo) { type = [instance VariableType]; // perform assignment to instance variable offsetOfVariable = [instanceVariablelnfo offset]; switch (type) { OBJECT: return *(id)(self + offsetOfVariable); break; FLOAT: // this variable is actually a C scalar numeric type, not an // object, so we have to put an "object wrapper" it. return [NSNumber numberWithFloat: *((float *)(self + offsetOfVariable))]; break; All other types... } } } } The actual implementation of the above caches the state necessary to perform a get or set operation in a "binding" object; The actual scanning of class information only occurs the first time a get or set operation is performed for a particular key. ©end

Claims: CLAIMS We claim: 1. In an object oriented programming environment, a method for associating a controlling object managing one or more data bearing objects with one or more user interface objects comprising the steps of: defining a first association object for a first type of user interface object, said first association object being capable of sending messages specific to said first type of user interface object to and receiving messages specific to said first type of user interface object from said first type of user interface object, and further being capable of sending standard messages to and receiving standard messages from said controlling object; creating a first instance of said first type of user interface object; creating a first instance of said first association object; providing said first instance of said first association object with a key for obtaining data from a data bearing object; linking said first instance of said first association object with said first instance of said first type of user interface object and said controlling object such that in response to a standard message received from said controlling object said first instance of said first association object sends a message specific to said first type of user interface object to said first instance of said first type of user interface object and in response to receiving from said first instance of said first type of user interface object a message specific to said first type of user interface object said first instance of said first association object sends a standard message to said controlling object. 2. The method of claim 1 further comprising the steps of: defining a second association object for a second type of user interface object, said second association object being capable of sending messages specific to said second type of user interface object to and receiving messages specific to said second type of user interface object from said second type of user interface object, and further being capable of sending standard messages to and receiving standard messages from said controlling object; creating a first instance of said second type of user interface object; creating a first instance of said second association object; providing said first instance of said second association object with a key for obtaining data from a data bearing object; linking said first instance of said second association object with said first instance of said second type of user interface object and said controlling object such that in response to a standard message received from said controlling object said first instance of said second association object sends a message specific to said second type of user interface object to said first instance of said second type of user interface object and in response to receiving from said first instance of said second type of user interface object a message specific to said second type of user interface object said first instance of said second association object sends a standard message to said controlling object. 3. The method of claim 1 further comprising the steps of: creating a second instance of said first type of user interface object; creating a second instance of said first association object; providing said second instance of said first association object with a key for obtaining data from a data bearing object; linking said second instance of said first association object with said second instance of said first type of user interface object and said controlling object such that in response to a standard message received from said controlling object said second instance of said first association object sends a message specific to said first type of user interface object to said second instance of said first type of user interface object and in response to receiving from said second instance of said first type of user interface object a message specific to said first type of user interface object said second instance of said first association object sends a standard message to said controlling object. 4. The method of claim 1 wherein standard messages sent by said controller object to association objects comprise a message for conveying a current value of data contained in a data bearing object. 5. The method of claim 1 wherein standard messages sent by said controller object to association objects comprise a message for indicating that data contained in a data bearing object has changed. 6. The method of claim 1 wherein standard messages received by said controller object from association objects comprise a message for indicating that a data value displayed in a user interface object has been edited. 7. The method of claim 1 wherein standard messages received by said controller object from association objects comprise a message for conveying a current value of data displayed in user interface object. 8. The method of claim 1 wherein standard messages sent by said controller object to association objects comprise a message for requesting a current value of data displayed in a user interface object. 9. The method of claim 1 wherein standard messages received by said controller object from association objects comprise a message for requesting a current value of data contained in a data bearing object. 10. The method of claim 9 wherein data is stored in said data bearing object in the form of a key-value pair and said message for requesting a current value of data contained in a data bearing object comprises said key provided to said association object. 11. The method of claim 8 wherein data is stored in said user interface object in the form of a key-value pair and said message for requesting a current value of data displayed by a data bearing object comprises a key for identifying data contained in said user interface object. 12. A method for displaying data contained in data bearing objects on a user interface in an object oriented programming environment comprising the steps of: providing a controller object for managing a plurality of data bearing objects; providing a plurality of types of user interface objects for displaying data on a user interface; for each type of user interface object, providing a corresponding association object capable of sending messages specific to said type of user interface object to and receiving messages specific to said type of user interface object from said type of user interface object, and further being capable of sending standard messages to and receiving standard messages from said controlling object; providing means for providing an instance of an association object with a key for obtaining data from a data bearing object; providing means to link an instance of an association object with an instance of a corresponding type of user interface object and a controller object such that in response to a standard message received from said controlling object said instance of said association object sends a message specific to said corresponding type of user interface object to said instance of said corresponding type of user interface object and in response to receiving from said instance of said corresponding type of user interface object a message specific to said corresponding type of user interface object said instance of said association object sends a standard message to said controlling object. 13. The method of claim 12 wherein standard messages sent by said controller object to association objects comprise a message for conveying a current value of data contained in a data bearing object. 14. The method of claim 12 wherein standard messages sent by said controller object to association objects comprise a message for indicating that data contained in a data bearing object has changed. 15. The method of claim 12 wherein standard messages received by said controller object from association objects comprise a message for indicating that a data value displayed in a user interface object has been edited. 16. The method of claim 12 wherein standard messages received by said controller object from association objects comprise a message for conveying a current value of data displayed in user interface object. 17. The method of claim 12 wherein standard messages sent by said controller object to association objects comprise a message for requesting a current value of data displayed in a user interface object. 18. The method of claim 12 wherein standard messages received by said controller object from association objects comprise a message for requesting a current value of data contained in a data bearing object. 19. The method of claim 18 wherein data is stored in said data bearing object in the form of a key-value pair and said message for requesting a current value of data contained in a data bearing object comprises a key for identifying data contained in said data bearing object. 20. The method of claim 17 wherein data is stored in said user interface object in the form of a key-value pair and said message for requesting a current value of data displayed by a data bearing object comprises a key for identifying data contained in said user interface object. 21. The method of claim 12 wherein said plurality of types of user interface objects includes a table column type of user interface object.

Inventors: GREENFIELD JACK, UPSON LINUS, WILLHITE DANIEL, WILLIAMSON RICHARD, GREENFIELD, JACK, UPSON, LINUS, WILLHITE, DANIEL, WILLIAMSON, RICHARD
Applicants: NEXT SOFTWARE INC, NEXT SOFTWARE, INC.
Application year: 1995
Main classification: G06F9
IPC codes: G06F9