Creating document based applications

From GNUstepWiki
Revision as of 06:17, 6 July 2005 by Quineska (talk | contribs)
Jump to navigation Jump to search

Note: this is a work in progress. Please bear with me as I add further information. --ChrisArmstrong 08:33, 5 Jul 2005 (CEST)


Introduction

OpenStep can provide your application a document-based model. It helps to simplify the process of creating such applications. GNUstep is compatible with this paridgm as well; this document aims to provide an overview of what is required in the creation and design of such an application.

It is assumed you are familiar with GNUstep, and have some understanding as how to create Gorm's nib files, as well as some understanding of how they work.

Importantly, such applications have certain components that are required, and should be considered as part of their design. At a programmatic level, classes that will be used as part of the AppKit are:

NSDocument

This class is central to the OpenStep document based model. Such an application declares a new instance of a subclass of NSDocument for each “document” that is opened. It will be necessary to subclass NSDocument to implement this.

Each instance of your NSDocument subclass may have one or more windows associated with it. These are used as an interface for loading and saving a representation of your document type. Each window will have an “NSWindowController” instance associated with it, where NSDocument maintains a list of these.

NSDocumentController

This class acts a controller. It maintains a list of documents (instances of your NSDocument subclass) and is responsible for loading and instantiating new documents. It is usually not necessary to implement a subclass of this, but often it may be useful to implement special functionality (especially related to open documents as a whole).

NSWindowController

As mentioned above, NSWindowController instances are individually associated with one NSWindow instance, in such a way that a document maintains a list of window controllers that are reponsible for rendering the views associated with a document.

You will most likely not have to subclass NSWindowController. Instead, you associate a nib file (the Gorm output) with the subclass of NSDocument, and NSDocumentController will load this nib file for each document that is created or loaded.

For example, a text based application that is used for the editing of plain text files, may subclass NSDocument with a TextDocument class. Each instance of this class would have an NSWindowController instance associated with it, which in turn manages a window instance that is instantiated from a nib file. The NSDocumentController instance, as managed and instatiated by GNUstep, would be responsible for loading and saving documents in your application. It even prompts the user to save their documents when they try to quit the application.

Components

In building your application you will need to create a number of components. From scratch, the following should be a rough guide to getting it working.

The Makefile

For this type of application, no special makefile is needed: it just has to be a normal application. Project Builder should be able to spit out the required makefile and Gorm files that are needed for a generic application. Otherwise use the following as a template:


GNUmakefile

include $(GNUSTEP_MAKEFILES)/common.make

APP_NAME = DocumentApp
DocumentApp_OBJC_FILES =
MyDocument.m
main.m

DocumentApp_RESOURCES = \
Resources/Info-gnustep.plist \
Resources/DocumentApp.gorm \
Resources/MyDocument.gorm

-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/application.make
-include GNUmakefile.postamble

For more information as to customising this file, as well as setting up compiler options for third party libraries and includes, see the GNUstep makefile manual.

The application dictionary - Info-gnustep.plist

For those that have edited this file in their project before, it is a dictionary with various values entered. For our purposes, we need an array within the main dictionary, called "NSTypes". This is a array of unnamed dictionaries, with one dictionary for each type.

An entire example of this file, for a "theoretical" TextEdit application (please note that such an application does exist as an example application from Next I think, and again on MacOS X but I have constructed a much simpler version, used only for plain text files).

Taking a look at the single dictionary entry in the NSTypes array, the following key-value pairs are needed:

  • NSDocumentClass: This is (string) the subclass name you use in your code, the "objective-c name" of your document subclass. This is used by NSDocumentController's default implementation to create instances of your document type.
  • NSName: The generic file type (string). This is completely arbitrary, and can be anything you like. For the purpose of conventions, it may be more appropriate not to use the "NS" or "GS" prefix (the latter of which I not sure), and instead use either your own, or no prefix at all.
  • NSHumanReadableName: The human readable name of your document type (string)? TODO: explain where this is used.
  • NSUnixExtensions: An array of strings, each containing a file extension connected to this document type on "unix" platforms. TODO: explain how "unix" is interpreted by GNUstep.
  • NSDOSExtensions: An array of strings, each containing a file extenstion connected to this document type on "DOS" platforms (could be loosely interpreted as any MS platforms GNUstep runs on, i.e. Windows 2000/XP).
  • NSRole: A string, either "Viewer" or "Editor", depending on how your document operates on this file type.
  • NSIcon: A icon name associated with this document type. TODO: Investigate how this works.

Info-gnustep.plist

{
    ApplicationDescription = "A simple text editor for GNUstep.";
    ApplicationName = TextEdit;
    ApplicationRelease = 0.10;
    Authors = ( "Christopher Armstrong <quineska@gamebox.net" );
    Copyright = "Copyright (C) 2005 Christopher Armstrong";
    CopyrightDescription = "Released under GPL.";
    FullVersionID = 0.10;
    NSExecutable = TextEdit;
    NSMainNibFile = TextEdit.gorm;
    NSPrincipalClass = NSApplication;
    NSRole = Application;
    NSTypes = (
        {
                NSDocumentClass = "TextDocument";
                NSName = "GSTextDocumentType";
                NSHumanReadableName = "Text Document";
                NSUnixExtensions = ( "txt", "" );
                NSDOSExtensions = ( "txt" );
                NSRole = Editor;
        }
    );
}