Q:
What is QAPI?A:
The Quantrix API (QAPI) enables developers to write rich extensions to Quantrix, Lighthouse Design's multi-dimensional spreadsheet. The QAPI was designed specifically for NEXTSTEP and OpenStep developers who have data analysis intensive projects with calculation and representation goals.The QAPI provides an extensive interface to Quantrix's internal protocols using Objective-C Protocols. This allows developers to treat Quantrix internal instances as "real" Objective-C Protocols that can be messaged, owned and handled in the same way as one handles their own instances.
By default, the QAPI package installs in ~/Library/QAPI. The Makefiles in the examples and in the Makefiles directory are dependent on this path. If you change the installation location, make sure to change the paths within the makefiles.
The following overview is designed to give pointers to Quantrix protocols. The protocol headers contain extensive documentation on context and usage. QAPI uses protocols to define several subsets to internal protocol interfaces. The interfaces specify the relationships between the different protocols.
The Primary protocols are the main protocols of the items within Quantrix.These are QAPIApp, QAPIModel, QAPITable, and QAPIView. The QAPI's central protocol is the QAPITable. Each QAPIModel can contain multiple instances of QAPITable, each of which contains a data space, a formula space and multiple views. The QAPITable also provides an extensive set of application event notifications.
Each QAPITable contains a tree of QAPINode instances. The tree defines the structure of the data space. The top-most level always defines Category items. Items below the first level are items or groups of items. Each QAPITable also has multiple QAPIView instances, each containing a window, a page view, a body view, and a selection. These correspond to the visual elements one sees within a Quantrix window. Each QAPIView has a single selection, QAPISelection. The selection enables one to set values and formats on cells within the model instance. The QAPISelection provides a cell iterations mechanism.
Some of the protocols are used to define a common functionality between a set of protocols. For example, QAPINamed specifies the attributes of items that appear in the browser. QAPIKey specifies an instance that can be uniquely identified within a model.
Finally, there are client protocols which are to be used and implemented by the QAPI client. QAPIPrincipal defines the bundle bootstrap method. There are also the delegate protocols: QAPIAppDelegate, QAPIModelDelegate, QAPITableDelegate.
There are several ways to connect to QAPI. The QAPIAlloc.h file contains a variable QAPI_BUNDLE that defines whether to use the API from a bundle or a client.
First, there are Distributed Object Clients that are used for communication between separate applications (even on remote hosts). These connections can be used to write applications that message Quantrix from other applications. For example, one could write support so that a graphing application messages Quantrix for its internal data and updates.
One can also connect as a Bundle. These are dynamically-loaded code segments that are loaded inside the Quantrix application at runtime. They are loaded from "blessed" paths including /LocalLibrary/Quantrix, ~/Library/Quantrix, the path to the application wrapper, and the application default (dwrite) "BundlePath".
Finally, one can define functions that can be used from within formulae. Functions can calculate some arbitrary set of data, and can populate data from the results of an external database. For example, one could define an "Environment_Variables" function that sets the values of a range to a user's environment variables. Functions are loaded as Bundles at runtime.
The QAPI documentation assumes that the developer is familiar with NEXTSTEP. In particular one should be comfortable with: Interface Builder, Project Builder, Objective-C, Objective-C Protocols, Distributed Objects, and NXBundle. See Digital Librarian and your NEXTSTEP Documentation for more information on those subjects. The best way start building a QAPI project is to look at the examples provided with the package. Find one that suits your basic needs, then copy it. Make a note of the Interface Builder (.nib) files, Project Builder (PB.project) file and the Makefiles. Each of those files should be closely examined.
In addition, examine the main class defined in each project. They contain comments on their implementation. One should be able to build a range of projects from the functionality exhibited in the examples. They should serve as a guide for understanding the related classes.
All of the QAPI methods that may have an execution error raise exceptions. The exceptions are always defined within the header files. (void) Return Type In order to comply with the upcoming OPENSTEP specifications, all methods return (void) unless otherwise noted. Protocol Pre-Declarations Since there is no support for pre-declarations of protocols, that is, an equivalent for the @class directive, some of the methods are not as typed as they should be. This version of QAPI will contain commented out #import lines where an import could not happen because of a circular dependency. When NeXT adds protocol pre-declaration support, all methods will be type rich.
For example, QAPISelection contains a method q_table which returns an instance conforming to the QAPITable protocol. However, this cannot be declared because the header could not be imported without causing a circular dependency.
Using DO presents several memory management problems because it allocates string arrays on the client side for return arguments and string arrays for arguments on the Quantrix side. The following functions enable QAPI to serve as an API for both DO clients, and Bundle projects.
char* qapiString(const char* string);
This function should be used for all QAPI methods that have (in char*) arguments. If QAPI_BUNDLE is defined, a newly malloced copy of string is returned. That way, when the QAPI method is called and frees the string argument, it won't free any of your project's strings.
Otherwise, string returned cast as a (char *). This is because the DO mechanism allocates a string on the application`s side for all string arguments. qapiFree void qapiFree(void* ptr);
This function should be used for all QAPI methods that return (char*). If QAPI_BUNDLE is defined, this function does not free ptr. This is because the returned string is owned by an internal instance.
Otherwise, it frees ptr. That way, when a QAPI method is called from a DO client, it will free the string allocated by the DO mechanism.
For additional information, see the NeXT Computer documentation: NEXTSTEP's Distributed Objects, NXConnection, NXProxy, NXBundle, Project Builder and Interface Builder Documentation. See also: the Quantrix API and User Documentation.