[Previous] [Class List] [Next]
Inherits
from: NSObject
Conforms to: NSObject
(NSObject)
Declared in: AppKit/NSDocument.h
Class at a Glance
NSDocument. is an abstract class that defines the
interface for documents, objects that can internally represent data
displayed in windows and that can read data from and write data
to files. Documents create and manage one or more window controllers,
and are in turn managed by a document controller. Documents respond
to first-responder action messages to save, revert, and print their
data.
Principal Attributes
- window controllers
- filename
- document type
- print information
Creation
Commonly Used Methods
Class Description
NSDocument is an abstract class that defines the interface
for documents. In a functional sense, a document is a repeatable
container for a unique body of information identified by a name
under which it is stored. In the context of the Application Kit,
a document is an instance of an NSDocument subclass that knows how
to represent internally, in one or more formats, the persistent
data displayed in windows. A document can read that data from files
and write it to files. It is also the first-responder target for
many menu commands related to documents, such as Save Document,
Revert Document, and Print Document. (When going up the responder
chain, the Application Kit queries a window's NSDocument, if it
exists, just after it queries the window delegate, if that is different
from the NSDocument.) A document manages its window's edited status
and is set up to perform undo and redo operations. When a window
is closing, the document is asked before the window delegate to
approve the closing.
To create a useful NSDocument subclass you must override some
primitive methods and might want to override others. The NSDocument
class itself knows how to handle document data as undifferentiated
"lumps"; although it understands that these lumps are
typed, it knows nothing about particular types. In their overrides
of the data-based primitive methods, subclasses must add the knowledge
of particular types and how data of the document's native type
is structured internally and represented in document windows. Subclasses
are also responsible for the creation of the window controllers
that manage document windows, and for the implementation of undo
and redo. NSDocument takes care of much of the rest, including running
Open and Save panels, and generally managing the state of the document.
See ""Creating a Subclass of NSDocument"" for more
on creating subclasses of NSDocument, particularly the required
and optional overridden primitive methods.
NSDocument is one of the triad of Application Kit classes
that establish an architectural basis for document-based applications
(the others being NSDocumentController and NSWindowController).
Read the following section, ""Document-Based Application
Architecture"," for the concepts behind this architecture.
Following that, ""Implementing a Document-Based Application"" gives
the procedure for implementing it.
Document-Based Application Architecture
A document-based application is one of the more common types
of applications developed today. They provide a framework for generating
identically contained but uniquely composed sets of data that can
be stored in files. Word processors and spreadsheet applications
are two well-known examples of document-based applications. Before
investigating how document-based applications are structured, let's
consider exactly what such an application does. It:
- Creates new documents
- Opens existing documents that are stored in files
- Saves documents under user-designated names and locations
- Reverts to saved documents
- Closes documents (usually after prompting the user to save
edited documents)
- Prints documents and allows the page layout to be modified
- Represents data of different types internally
- Monitors and sets the document's edited status and validates
menu items
- Manages document windows, including setting the window titles
- Handles application and window delegation methods (such as
when the application terminates)
Three Application Kit classes provide an architecture for
document-based application that simplifies the work developers have
to do to implement the features listed above. These classes are
NSDocumentController, NSDocument, and NSWindowController.
Objects of these classes divide and orchestrate the work of
creating, saving, opening, and managing the documents of an application.
They are in tiered one-to-many relationship, as depicted in Figure
0-1. An application can have only one NSDocumentController, which
creates and manages potentially many NSDocument objects (one for
each New or Open operation). In turn, an NSDocument object creates
and manages one or more NSWindowController objects, one for each
of the windows displayed for a document. In addition, some of these
objects have responsibilities analogous to NSApplication and NSWindow delegates.
Relationships between NSDocument, NSDocumentController,
and NSWindowController
How do these objects divide the work among themselves? The
place to start this discussion is not with any of the classes, but
with a property list that specifies important details about the
application's documents.
The Document Types Info Property List
Each document-based application must include an NSTypes property
in its custom info property list (CustomInfo.plist).
This property specifies information about data types supported
by its documents. When the NSDocumentController object creates a
new document or opens an existing document, it searches this property
list for such items as document class, file extension, whether
the type is native or external, and whether external types can be
only read or written.
Developers must hand-craft this property list for the current
release. In future releases, Project Builder will assist in the
creation of this property list.
The following code shows a sample CustomInfo.plist;
the NSType property is the part specific to documents:
{
NSInfoPlistVersion = "5.0";
NSAppVersion = "1.0";
NSHumanReadableShortName = "SimpleTextEdit";
NSHumanReadableCompleteName = "Simple Text Edit
Sample";
NSHumanReadableCopyright = "Copyright (c) 1998,
Apple Computer, Inc.";
NSTypes = (
{
NSName = "rtf";
NSHumanReadableName = "RTF Document";
NSUnixExtensions = ("rtf");
NSDOSExtensions = ("rtf");
NSRole = Editor;
NSDocumentClass = Document;
}
);
}
This property list tells the NSDocumentController for the
SimpleTextEdit application that the application has one native type
("rtf"), meaning a type of document that, in its role
as Editor, it can read and write. The human-readable type name is
shown in a pop-up list in the Save Panel's accessory view (but
only if there are multiple types). The extensions are used to filter
the files shown in Open and Save panels on various platforms; the
first extension in each list is automatically added to file names
specified in the Save panel. Most important is the document class;
NSDocumentController uses this to create an instance of the NSDocument subclass
appropriate to a data type. You never have to allocate and initialize
your NSDocument explictly in your code; it is done for you.
NSType is a dictionary with key/value pairs defined as follows:
- NSName
- The abstract name of this data type. This name is used
in pasteboard operations. It must be present for the type to be
valid, and it must be unique.
- NSHumanReadableName
- The name of the document type as it appears in the human
interface. This name can be localized; the name that appears here
is used as the key to extract the localized name from the InfoPlist.strings file.
- NSIcon
- The name of the image file for the icon to represent
this type in the human interface. This image file is assumed to
reside in the application's Resources directory. It cannot be
localized.
- NSUnixExtensions
- An array of file suffixes used to encode this type on
UNIX file systems. The items in the array are interpreted in a case-insensitive
manner. The first extension is the one used for newly created files.
- NSDOSExtensions
- An array of file suffixes used to encode this type on
DOS file systems. The array items in the array are interpreted in
a case-insensitive manner. The first extension is the one used for
newly created files.
- NSMacOSTypes
- An array of 4-byte MacOS codes used to encode this type.
The first extension is the one used for newly created files.
- NSMIMETypes
- An array of the MIME types used to encode this type.
- NSRole
- A string that indicates the role of the application
for documents of this type: "Editor" (reads, manipulates,
displays, and writes), "Viewer" (reads and displays),
or "None" (cannot read or write, but is declaring information
about the type, such as an icon). If this key is absent, "Editor"
is assumed.
- NSDocumentClass
- The name of the NSDocument subclass used at runtime
for loading this document type.
The Role of NSDocumentController
The primary job of an application's NSDocumentController
object is to create and open documents, and to track and manage
these documents. When a user choses New from the File menu, an NSDocumentController
gets the appropriate NSDocument subclass from the NSTypes property,
allocates an instance of this class, and initializes this instance
by invoking NSDocument's init method. When the user chooses Open
from the File menu, NSDocumentController displays the Open panel,
gets the user's selection, finds the NSDocument subclass for the
file (based on its extension), allocates an instance of this class,
and initializes the object and loads document data by invoking NSDocument's initWithContentsOfFile:ofType:.
In both cases, the NSDocumentController adds a reference to the
document object to an internal list to facilitate the management
of its documents. It has a notion of the current document as the document
whose window is currently key.
NSDocumentController is hard-wired to respond appropriately
to certain application events, such as when the application starts
up, when it terminates, when the system powers off, and when documents
are opened or printed from the Workspace. If you wish, you can make
a custom object the application delegate and implement the delegate
methods invoked as a result of the same events, and these methods
will be invoked instead. However, the default NSDocumentController
object is an adequate application controller for most situations,
and you should not need to subclass it. If you require additional behavior,
such as displaying About panels and handling application preferences, it
is recommended that a custom controller object perform these duties
rather than a subclass of NSDocumentController.
The Role of NSDocument
The primary job of an NSDocument object is to represent, manipulate,
store, and load the persistent data associated with a document.
Based on the document types it claims to understand (as specified
in the NSTypes property of the info property list), a document must
be prepared to:
- Provide the data displayed in windows (and represented
internally) in a supported document type.
- Given data of a supported type, load it into internal data
structures and display it in windows.
- Store document data in a file at a specified location in the
file system.
- Read document data stored in a file.
With the assistance of its window controllers, an NSDocument
manages the display and capture of the data in its windows. By some
special hard-wiring of the Application Kit, the NSDocument associated
with the key window is the recipient of first-responder action messages
when users save, print, revert, and close documents. In response
to the appropriate action, it knows how to run and manage the Save
panel and the Page Layout panel.
A fully implemented NSDocument knows how to track its edited
status, print document data, and perform undo and redo operations.
Although these behaviors aren't completely provided by default,
NSDocument does assist the developer in implementing each. For edited-status
tracking, NSDocument provides API for updating a change counter.
For undo/redo operations, NSDocument by default lazily creates an
NSUndoManager when one is requested, responds appropriately to Undo
and Redo menu commands, and updates the change counter when undo and
redo operations are performed. For printing, NSDocument facilitates
the display of the Page Layout panel and the subsequent modification
of the NSPrintInfo object used in printing.
Creating a Subclass of NSDocument
Every application that takes advantage of the Application
Kit's architecture for document-based applications must create
at least one subclass of NSDocument. This architecture requires
that you override some NSDocument methods in an either/or scenario,
and recommends overriding several others in certain situations.
- Data-based primitivesThe dataRepresentationOfType: method has
to be implemented to create and return document data (packaged as
an NSData object) of a supported type, usually in preparation for
writing that data to a file. The loadDataRepresentation:ofType: method
must be implemented to convert an NSData object containing document
data of a certain type into the document's internal data structures
and display that data in a document window; the NSData object usually
results from the document reading a document file. Subclasses must
override these methods.
- Location-based primitivesBy default the writeToFile:ofType: method
writes data to a file after obtaining the data from the fileWrapperRepresentationOfType:,
which gets it from the dataRepresentationOfType: method.
The readFromFile:ofType: method
reads data from a file, creates an NSFileWrapper object from it,
and gives this object to loadFileWrapperRepresentation:ofType:;
if this object represents a simple file, it is passed to the loadDataRepresentation:ofType: method
for processing; otherwise (that is, the object represents a directory),
the loadFileWrapperRepresentation:ofType: method
is overriden to handle the situation. Subclasses can override any
of these methods instead of the data-based primitives if the way
NSDocument reads and writes document data is not sufficient; their
override implementations, however, must also assume the loading
duties of the data-based primitives.
- Window controller creationNSDocument subclasses must
also create their window controllers. They can do this indirectly
or directly. If a document has only one nib file (with one window
in it), the subclass can override windowNibName to return the name of
the window nib file; as a consequence, a default NSWindowController instance
is created for the document, with the document as the nib file's
owner. If a document has multiple windows, or if an instance of
a custom NSWindowController subclass is to be used, the NSDocument
subclass must override makeWindowControllers to
create these objects.
- Printing and page layoutNormally, a document-based application
can change the information it uses to define how document data is
printed (an NSPrintInfo object). Subclasses can override shouldChangePrintInfo: to
disallow this change. If an application is to print document data,
subclasses of NSDocument must override printShowingPrintPanel:.
- Backup filesWhen it saves a document, NSDocument creates
a backup of the old file before it writes data to the new one (backup
files have the same name as the new file, but with a tilde just
before the extension). Normally, if the write operation is successful,
it deletes the backup file. Subclasses can override keepBackupFile to return YES,
and thus retain the most recent backup file.
- Save panel accessory viewBy default, when NSDocument
runs the Save panel, and the document has multiple writable document
types, it inserts an accessory view near the bottom of the panel.
This view contains a pop-up list of the writable types. If you don't want
this pop-up list, override shouldRunSavePanelWithAccessoryView to
return NO.
- Menu itemsNSDocument implements validateMenuItem: to manage the enabled
state of the Revert and Save As menu items. If you want to validate
other menu items, you can override this method, but be sure to invoke
super
's implementation.
For more information on menu item validation, see the description
of the NSMenuValidation informal protocol.
The initializers of NSDocument are another issue for subclassers.
The init method is the primary initializer, and it is invoked by
the other initializer initWithContentsOfFile:ofType:. The init method
is directly invoked when a new document is created; the initWithContentsOfFile:ofType: method
is directly invoked when a document is opened. Therefore if you
have any initializations that apply only to documents that are opened,
you should override initWithContentsOfFile:ofType:;
if you have general initializations, you should, of course, override init.
In both cases, be sure to invoke super
's implementation
as the first thing.
The Role of NSWindowController
An NSWindowController manages one window associated with a
document, which is usually stored in a nib file. If a document had
multiple windows, each window would have its own window controller.
For example, a document might have a main data-entry window and
a window listing records for selection; each window would have its
own NSWindow Controller. When requested by its owning NSDocument,
an NSWindowController loads the nib file containing a window and
displays it. It also assumes responsibility for properly closing windows
(after ensuring that they are saved).
The NSWindowController offers additional behavior to document-based applications.
It can store the size and location of windows in the user defaults database
(this may not be desired behavior for most document-based applications, because
it could quickly overpopulate the defaults database with document window-frame
entries). It also cascades document windows in relation to each other,
so they don't completely obstruct one another.
Subclasses of NSWindowController are optional. Applications
can often use the default instance. Subclasses can augment NSWindowControllers
to perform different nib-loading and setup tasks or to customize
the titles of windows.
Implementing a Document-Based Application
It is possible to put together a document-based application
without having to write much code. If your requirements are minimal,
the Application Kit provides you with a default NSWindowController
instance and a default NSDocumentController instance. You just have
to create a document project, compose the human interface, implement
a subclass of NSDocument, and add any other custom classes or behavior
required by your application.
The following procedures step you through the tasks you must
do, and might want to do, when implementing a document-based application.
Where something is described in detail elsewhere, such as overridden
methods in NSDocument subclasses, you are referred there.
As for the three classes behind document-based applications,
two likely concerns are the number of required objects and whether
subclassing is necessary. The following table summarizes this information:
Class |
How Many Objects? |
Subclass? |
NSDocumentController |
1 per application |
Optional (but unlikely) |
NSDocument |
1 per saved file |
Required |
NSWindowController |
1 per document nib file |
Optional (but likely) |
The Document-Based Application Package
The Yellow Box development environment provides a Document-Based Application
project type to expedite the development of these kinds of applications.
This project type provides the following things:
- A nib file for the application's documentA
subclass of NSDocument named "Document" is made File's
Owner of the nib file. It has an outlet to its window. The window
is "blank" (that is, without object on it).
- The application's main nib fileThis nib file contains
an application menu with a File menu (with all of its associated
document commands) and Undo and Redo menu items in the Edit menu.
These menu items, as well as all of the menu items of the File menu,
are connected to the appropriate first-responder action methods.
The About MyApp menu item of the Apple (or Info) menu is connected
to the action method for loading the nib file containing the About
panel.
- A nib file for the About panelThis nib file contains
a conventional About dialog with placeholder text for application
name, version string, and so on. The custom NSWindowController object
(see below) is File's Owner of this nib file.
- A skeletal NSDocument subclass implementationThe project
includes
Document.h
and Document.m
,
which are derived from the definition of the NSDocument subclass
in the document nib file. The latter file includes empty but commented
blocks for the dataRepresentationOfType:, loadDataRepresentation:ofType:,
and windowControllerDidLoadNib: methods.
It also includes a fully implemented windowNibName method.
- A custom NSWindowController subclass for the About panel
- A custom info property list templateIn the Other Resources
category of the project is a CustomInfo.plist file
that contains placeholder values for global application keys as
well as NSTypes keys.
The following procedure describes what you must do to create
a document-based application when you use the project type developed
for it. If this project type is absent on your system, you will
have to complete the tasks listed above yourself. For this eventuality,
the following table lists the appropriate first-responder action connections
to make (that is, in Interface Builder connect the menu command
to the "1" icon in the nib file window):
File Menu Command |
First-Responder Action |
New |
newDocument: |
Open |
openDocument: |
Save |
saveDocument: |
Save As |
saveAsDocument: |
Save To |
saveToDocument: |
Save All |
saveAllDocuments: |
Close |
closeDocument: |
Revert |
revertDocument: |
Print |
printDocument: |
Page Layout |
runPageLayout: |
Also, if you have added Undo and Redo menu items in the Edit
menu, connect them to the first-responder undo: and redo: methods.
Create the Project and Compose the Interface
- Launch Project Builder and choose New from the
Project.In the New Project panel, see if the pop-up menu of
project types includes "Document Based Application." If
it doesn't, you will have to load this project type, located in /System/Developer/ProjectTypes (on
Yellow Box for Windows platforms, prepend the value of NEXT_ROOT
to this path).
- Create a project of type Document Based Application.
- Double-click the Document.nib file
in Project Builder's Interfaces category to open this file in
Interface Builder.If you want the nib file to be named something
else, you can save it under another name in Interface Builder and
add it to the project. If you do this, you must also modify the
string returned by the windowNibName method
in the NSDocument subclass implementation.
- Create the human interface of the document window.
- If the objects on the document window require further outlets
or actions, add these to the Document subclass of NSDocument. Connect
these actions and outlets via the File's Owner icon on the Instances
display of the nib file window.Do not generate an instance
of Document to make these connections.If you want your
NSDocument subclass named something other than "Document,"
change the name in Interface Builder and wherever it occurs in the
Document header and implementation (.m)
files.
- If your document objects interacts with other custom objects,
such as model objects that perform specialized computations, define
those objects in Interface Builder and make any necessary connections
to them.
Complete the Custom Info Property List
- In Project Builder, select CustomInfo.plist in
the Other Resources category.
- Replace the placeholder or default values in the NSType property
list with those specific to your document. If your document has
more than one document type, duplicate the given NSType property
and fill it in with the appropriate values.See ""The
Document Types Info Property List"" for information on the
key/value pairs specific to documents.
- For the global application properties enter your application's
names, version, and copyright information.
Implement the NSDocument Subclass
The following procedure just gives general guidelines. For
details see the complete NSDocument specification and especially
""Creating a Subclass of NSDocument"." You might
also want to read the class specifications of NSUndoManager, NSPasteboard,
and the print classes.
- In Project Builder, open the header file of
your NSDocument subclass located in the Headers category.
- If you added outlets or actions to your NSDocument subclass
in Inteface Builder, add them to the subclass' header file. Also
any other required instance variables and include the declarations
of new methods that you wish to be public, such as accessor methods.Of
course, you can specify additional outlets in actions in the existing
header file and then import them into the nib file by using Interface
Builder's Classes>Read File command.
- Open the subclass implementation file (.m)
in Project Builder's Classes category.
- Although it's not usually necessary, you can override the
primary initializer ( init)
and perhaps the document-opening initializer initWithContentsOfFile:ofType: to
perform initializations specific to you subclass; be sure to invoke super's
implementations. You can also implement awakeFromNib to
initialize objects unarchived from the document's window nib files.
- Override the data-based primitives (null implementations of
these methods provided by the project type).In almost all
cases, you should implement dataRepresentationOfType: (to provide
document data of a certain type) and loadDataRepresentation:ofType: (to
load document data of a certain type).Example:
// -----------------------------------------------------------------------------
- (NSData *)dataRepresentationOfType:(NSString *)aType
{
NSAssert([aType isEqualToString:@"rtf"],
@"Unknown type");
return [textView RTFFromRange:NSMakeRange(0, [[textView
textStorage] length])];
}
// -----------------------------------------------------------------------------
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString
*)aType {
NSAssert([aType isEqualToString:@"rtf"],
@"Unknown type");
fileContents = [data copyWithZone:[self zone]];
return YES;
}
- If you need to read or write document data in a special way
(because, for example, document data is stored in a file package),
you can override readFromFile:ofType: and writeToFile:ofType:
to not only read and write data, but load and provide data in a
given type.Example:
// -----------------------------------------------------------------------------
- (BOOL)writeToFile:(NSString *)fileName ofType:(NSString
*)type {
return [[textView string] writeToFile:fileName atomically:YES];
}
// -----------------------------------------------------------------------------
- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString
*)type {
fileContents = [[NSString alloc] initWithContentsOfFile:fileName];
return fileContents != nil;
}
- Create the window controllers for the NSDocument object.If
your document has only window, the project types provides a default implementation
:
- (NSString *)windowNibName
{
return @"Document";
}
If your document
has more than one window, or if you have a custom subclass of NSWindowController,
override makeWindowControllers.
Make sure you add each created window controller to the list of
such objects managed by the document ( addWindowController:).
- You can implement windowControllerWillLoadNib: and windowControllerDidLoadNib: to
perform any necessary tasks related to the window before and after
it is loaded from the nib file.Example:
- (void)windowControllerDidLoadWindowNib:(NSWindowController *)windowController
{
[super windowControllerDidLoadWindowNib:windowController];
[textView setAllowsUndo:YES];
if (fileContents != nil) {
[textView setString:fileContents];
[fileContents release]; // Don't need it anymore
fileContents = nil;
}
}
- Mark the document's "dirty" flag when it is edited.The
flag returned by isDocumentEdited indicates
whether the document has unsaved changes. Although NSDocument clears
this flag when it saves or reverts a document, you must set this
flag in your code, unless you are using NSDocument's default undo/redo
mechanism. Normally, you respond to the appropriate delegation or
notification messages sent when users edit a document, then invoke updateChangeCount: with
an argument of NSChangeDone to set the "dirty" flag.
- Write the code that prints the document's data.If
you want users to be able to print a document, you must override printShowingPrintPanel:,
possibly providing a modified NSPrintInfo object.
- Register undo and redo groups in your code. See the class
description of NSUndoManager for details.
And of course, you implement any methods that are special
to your NSDocument subclass.
Implement Additional Controller Classes
If the default NSWindowController instance provided by the
application kit does not meet the needs of your document-based application,
you can create a custom subclass of it. If you do so, you must override
NSDocument's makeWindowControllers to
instantiate this custom class and add the created object to the
document's list of window controllers.
If the default NSDocumentController object somehow does not
meet all of your requirements for an application controller, such
as handling user preferences or responding to uncommon application
delegate messages, you should create a separate controller object
(instead of subclassing NSDocumentController). For information
on implementing NSDocumentController and NSWindowController subclasses,
refer to the appropriate class specifications.
Method Types
- Initializing an NSDocument
- - init
- - initWithContentsOfFile:ofType:
- Loading and representing
document data
- - dataRepresentationOfType:
- - loadDataRepresentation:ofType:
- - fileWrapperRepresentationOfType:
- - loadFileWrapperRepresentation:ofType:
- Creating and managing
window controllers
- - makeWindowControllers
- - windowNibName
- - windowControllerDidLoadNib:
- - windowControllerWillLoadNib:
- - windowControllers
- - addWindowController:
- - shouldCloseWindowController:
- Showing document windows
- - showWindows
- - displayName
- Reading from and writing
to files
- - readFromFile:ofType:
- - writeToFile:ofType:
- - fileNameFromRunningSavePanelForSaveOperation:
- - fileName
- - setFileName:
- - runModalSavePanel:withAccessoryView:
- - shouldRunSavePanelWithAccessoryView
- - keepBackupFile
- Managing document edited
status
- - isDocumentEdited
- - updateChangeCount:
- Responding to user actions
- - closeDocument:
- - printDocument:
- - runPageLayout:
- - revertDocumentToSaved:
- - saveDocument:
- - saveDocumentAs:
- - saveDocumentTo:
- Closing documents
- - canCloseDocument
- - close
- Reverting documents
- - revertToSavedFromFile:ofType:
- Printing documents
- - printShowingPrintPanel:
- - printInfo
- - setPrintInfo:
- - runModalPageLayoutWithPrintInfo:
- - shouldChangePrintInfo:
- Managing file types
- - setFileType:
- - fileType
- + isNativeType:
- + readableTypes
- + writableTypes
- Managing menu commands
- - validateMenuItem:
Class
Methods
+ (BOOL)isNativeType:(NSString *)aType
Returns whether document data
of type aType is a native type-one
a document can both read and write.See
Also: + readableTypes, + writableTypes
+ (NSArray *)readableTypes
Returns the types of data a
document can read natively and any types filterable to that native
type.See Also: + isNativeType:, + writableTypes
+ (NSArray *)writableTypes
Returns the types of data a
document can write natively and any types filterable to that native
type.See Also: + isNativeType:, + readableTypes
Instance Methods
- (void)addWindowController:(NSWindowController
*)aController
Adds the window controller
aController to the list of window controllers associated with the
receiver. An NSDocument uses this list when it
displays all document windows, sets window edited status upon a
undo or redo operation, and modifies window titles. The method also
sets the document outlet of the window controller to self if
it is not already set. If you create window controllers by overriding windowNibName,
this method is invoked automatically. If you create window controllers
in makeWindowControllers or in any other
context, such as in response to a user event, you should invoke
this method for each created window controller. To remove a window
controller from the list of active controllers, send it an (NSWindowController) close message.See
Also: - setDocument: (NSWindowController)
- (BOOL)canCloseDocument
Returns whether the receiver
can be closed. If the document has unsaved changes,
the method displays an attention panel asking users if they want
to save the document. It returns NO only if the user clicks the
Cancel button or if the document attempts to save itself but was
somehow unsuccessful. Otherwise-if the document has no unsaved
changes, if the document was successfully saved, or if the user
clicks Don't Save-it returns YES. In most situations, you should
receive YES from this method before closing the document.See
Also: - close, - saveDocument:, - shouldCloseWindowController:
- (void)close
Closes all windows owned by
the document and removes the receiver from the list of documents
maintained by the document controller, which consequently releases
it. This method closes the document immediately,
without asking users if they want to save the document.See
Also: - canCloseDocument, - closeDocument:, - shouldCloseWindowController:
- (IBAction)closeDocument:(id)sender
The action invoked in the receiver
when the user choses the Close Document menu command. The
target of the action message must be set to nil
so
the receiver can respond to it as first responder. The default implementation
of this method closes the document only if canCloseDocument returns YES.See
Also: - close
- (NSData *)dataRepresentationOfType:(NSString
*)aType
A primitive method overriden
by sublcasses to return a data object that represents the data of
the receiver in a given type (aType). The
default implementation raises an NSInternalInconsistencyException.
This method is invoked by the default implementation of fileWrapperRepresentationOfType:.
Here is a typical implementation:
- (NSData *)dataRepresentationOfType:(NSString *)aType
{
NSAssert([aType isEqualToString:@"rtf"],
@"Unknown type");
return [textView RTFFromRange:NSMakeRange(0, [[textView
textStorage] length])];
}
See
Also: - loadDataRepresentation:ofType:
- (NSString *)displayName
Returns the name of the document
as displayed in the title bars of the document's windows and in
attention panels related to the document. Returns
an empty string if the document is new and hasn't been saved.
If the document has been saved, the display name is the last component
of the directory location of the saved file (for example, "MyDocument"
if the path is "/tmp/MyDocument.rtf"). If the document
is new, NSDocument makes the display name "Untitled-n"
where n is a number in a sequence of new and unsaved documents.
Subclasses of NSWindowController can override windowTitleForDisplayName: to
modify the display name as it appears in window titles.
- (NSString *)fileName
Returns the filename (as a
fully qualified path) under which the document has been saved. See
Also: - fileNameFromRunningSavePanelForSaveOperation:, - setFileName:
- (NSString *)fileNameFromRunningSavePanelForSaveOperation:(NSSaveOperationType)saveOperation
Runs the modal Save panel and
returns the filename (as a fully qualified path) selected for the
document. saveOperation determines
the title of the Save panel (Save, Save As, Save To). It also affects
whether the Save Panel includes an accessory view with a pop-up
list containing the document's native or writable types. If saveOperation is
NSSaveOperation or NSSaveAsOperation, the accessory pop-up list
contains only those document types the application can read and
write. If saveOperation is NSSaveToOperation,
the pop-up lists additionally includes the document types that the
application can write (but can't read). If there is only one type
the document can be written to, or if shouldRunSavePanelWithAccessoryView returns NO,
the accessory view isn't shown. The default extension for saved
documents is the first extension assigned for the document's native
type or, if there is no native type, the extension for the first
writable type specified in the NSTypes property. File packages are treated
as files.See Also: - fileName, - runModalSavePanel:withAccessoryView:
- (NSString *)fileType
Returns the document type under
which the document is saved. When a document is
saved, the type is determined by the file extension, as defined
in the custom info dictionary (specified in CustomInfo.plist)
.See
Also: - setFileType:
- (NSFileWrapper *)fileWrapperRepresentationOfType:(NSString
*)aType
Returns an NSFileWrapper object
that represents the data of the receiver in a given type (aType). This
method invokes dataRepresentationOfType: to get the data object
from which to create a plain-file file wrapper. Subclasses can override
this method if dataRepresentationOfType: is not adequate for their needs.
This method is invoked by the default implementation of writeToFile:ofType:. See
Also: - loadFileWrapperRepresentation:ofType:
- (BOOL)hasUndoManager
Returns whether the receiver
owns or should own an NSUndoManager.See
Also: - setHasUndoManager:
- (id)init
Initializes and returns an
NSDocument object. This initializer (the designated initializer)
is typically invoked by NSDocumentController's makeUntitledDocumentOfType:.
- (id)initWithContentsOfFile:(NSString *)fileName
ofType:(NSString *)docType
Initializes and returns an
NSDocument object of document type docType containing
data stored in the file fileName. If
the file cannot be opened, displays an attention panel informing
the user, and then returns nil
. In
opening the file, invokes the readFromFile:ofType: method. If it
successfully opens the file, it "remembers" fileName and docType (through setFileName: and setFileType:).
This initializer is typically invoked by NSDocumentController's makeDocumentWithContentsOfFile:ofType:.
- (BOOL)isDocumentEdited
Returns YES if the document
has been edited since it was last saved or if the document is new;
otherwise, returns NO. The edited status of each
document window reflects the document's edited status.See
Also: - updateChangeCount:, - setDocumentEdited: (NSWindow)
- (BOOL)keepBackupFile
Returns whether the receiver
should keep the backup files created before document data is written
to a file (NO by default). Override this method
if you want different behavior.See Also: - writeToFile:ofType:
- (BOOL)loadDataRepresentation:(NSData *)docData
ofType:(NSString *)docType
Overridden by subclasses to
load document data (docData) of type docType into
the document, display it in windows, and return whether the operation
was successful. This method is typically invoked
by loadFileWrapperRepresentation:ofType: after an NSData object
is created from the contents of the file wrapper (which can include
directories). The default implementation raises an NSInternalInconsistencyException and
returns NO. Subclasses must override this method unless they override readFromFile:ofType: or loadFileWrapperRepresentation:ofType: to
do specialized reading and loading of document data.Here is
an example implementation:
-
(BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType {
NSAssert([aType isEqualToString:@"rtf"],
@"Unknown type");
fileContents = [data copyWithZone:[self zone]];
return YES;
}
See
Also: - dataRepresentationOfType:
- (BOOL)loadFileWrapperRepresentation:(NSFileWrapper
*)wrapper
ofType:(NSString *)docType
Loads document data in file
wrapper wrapper of type docType into
the document, displays it in windows, and returns whether the operation
was successful. If wrapper is
a simple file, it invokes loadDataRepresentation:ofType: load the
data. If wrapper is a directory,
it returns NO by default; subclasses can override to handle file
wrappers that are directories. This method is typically invoked
by readFromFile:ofType: after it creates an NSData object from the
contents of the file. See Also: - fileWrapperRepresentationOfType:
- (NSArray *)makeWindowControllers
Overridden by subclasses to
create and return multiple window controllers (NSWindowController
objects) or a single window controller derived from a custom subclass
of NSWindowController. A document-based application
must have one window controller per document nib file (each of which
must contain a primary window controlled by the window controller).
You usually should add each created window controller to the document's
list of such objects by invoking addWindowController:. If
subclasses do not override this method, they must override windowNibName,
but they should do so only if the following two conditions apply:
- The document has a single nib file (with its one window).
- The default NSWindowController instance is sufficient to manage
this window.
If you override this method, windowControllerDidLoadNib: and windowControllerWillLoadNib: are
invoked, as they are when windowNibName is implemented.
The
default implementation raises NSInternalInconsistencyException and returns nil
.
See
Also: - windowControllers
- (void)printDocument:(id)sender
Prints the document in response
to the user choosing the Print menu command. An
NSDocument receives this action message as it travels up the responder
chain. The default implementation invokes printShowingPrintPanel: with
an argument of YES.See Also: - printInfo, - runPageLayout:, - setPrintInfo:, - shouldChangePrintInfo:
- (NSPrintInfo *)printInfo
Returns the document's customized
NSPrintInfo object or the default NSPrintInfo instance. The
document's copy of the NSPrintInfo object can either be directly
set, or set as a result of running the Page Layout panel. A subclass
can override this method to always return the shared NSPrintInfo
instance if it does not want its own copy.See
Also: - runPageLayout:, - setPrintInfo:, - shouldChangePrintInfo:
- (void)printShowingPrintPanel:(BOOL)flag
Overridden by subclasses to
print the current document's (the receiver's) data; if flag is YES,
the implementation should first display the Print panel. This
method is typically invoked by printDocument: with an argument of YES.
The default implementation does nothing. If there is any printing
information other than that encoded in the receiver's NSPrintInfo
object, sublcasses should get it here.See
Also: - printInfo
- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString
*)docType
Reads and loads document data
of type docType from the file fileName, returning
whether the operation was successful. This method
invokes loadDataRepresentation:ofType: and is invoked when the receiver
is first created and initialized by initWithContentsOfFile:ofType:.
It uses NSData's initWithContentsOfFile: to
get the document data.This method is one of the location-based
primitives. Subclasses can override this method instead of overriding loadDataRepresentation:ofType: to
read and load document data. Subclasses that handle file packages
such as RTFD or that treat locations of files as anything other
than paths should override this method. Override implementations
of this method can filter the document data using NSPasteboard's
or other filtering services.
See Also: - dataRepresentationOfType:, - writeToFile:ofType:
- (void)revertDocumentToSaved:(id)sender
The action method invoked in
the receiver as first responder when the user chooses the Revert
menu command. The default implementation displays
an attention panel to confirm the user's intentions. If the user
confirms the command, the method reverts the document to the data
saved in the file system by invoking revertDocumentToSaved:. If
the operation is successful, it clears the update count.See
Also: - updateChangeCount:
- (BOOL)revertToSavedFromFile:(NSString *)fileName
ofType:(NSString *)type
Reverts the receiver to the
data stored in the file system. Invokes readFromFile:ofType: and
returns whether that method successfully read the file and processed
the document data.See Also: - revertDocumentToSaved:
- (int)runModalPageLayoutWithPrintInfo:(NSPrintInfo
*)printInfo
Runs the Page Layout modal
panel with the document's printing information object (printInfo)
as argument and returns the result constant (indicating the key
pressed by the user). Invoked by runPageLayout:.See
Also: - shouldChangePrintInfo:, - runModalWithPrintInfo: (NSPageLayout)
- (int)runModalSavePanel:(NSSavePanel *)savePanel
withAccessoryView:(NSView *)accessoryView
Runs the modal Save panel savePanel
with accessory view accessoryView and returns
the result constant (indicating the button clicked by the user). The accessory
view is usually a pop-list containing the document's native types
and its supported writable types. Invoked by fileNameFromRunningSavePanelForSaveOperation:. See
Also: - shouldRunSavePanelWithAccessoryView
- (void)runPageLayout:(id)sender
The action method invoked in
the receiver as first responder when the user chooses the Page Layout
menu command. The default implementation invokes runModalPageLayoutWithPrintInfo: with
the document's current NSPrintInfo object as argument; if the
user presses the OK button, and the document authorizes changes
to its printing information (shouldChangePrintInfo:), the method
sets the document's new NSPrintInfo object and increments the
document's change count.See Also: - setPrintInfo:, - updateChangeCount:
- (void)saveDocument:(id)sender
The action method invoked in
the receiver as first responder when the user chooses the Save menu
command. The default implement saves the document
in two different ways, depending on whether the document has a file
path and a document type assigned. If path and type are assigned,
it simply writes the document under it's current file path and
type after making a backup copy of the previous file. If the document
is new (no file path and type), it runs the modal Save panel to
get the file location under which to save the document. It writes
the document to this file, sets the document's file location and
document type (if a native type), and clears the document's edited
status.See Also: - fileNameFromRunningSavePanelForSaveOperation:, - setFileName:, - setFileType:, - updateChangeCount:
- (void)saveDocumentAs:(id)sender
The action method invoked in
the receiver as first responder when the user chooses the Save As
menu command. The default implementation runs
the modal Save panel to get the file location under which to save
the document. It writes the document to this file, sets the document's
file location and document type (if a native type), and clears the
document's edited status.See Also: - fileNameFromRunningSavePanelForSaveOperation:, - setFileName:, - setFileType:, - updateChangeCount:
- (void)saveDocumentTo:(id)sender
The action method invoked in
the receiver as first responder when the user chooses the Save To
menu command. The default implementation is identical
to saveDocumentAs:, except that this method doesn't clear the
document's edited status and doesn't reset file location and
document type if the document is a native type.See
Also: - fileNameFromRunningSavePanelForSaveOperation:
- (void)setFileName:(NSString *)fileName
Sets the file (filename and
directory path) under which document data is saved to fileName. As
a side effect, synchronizes the titles of the document's windows with
the new name or location. Under normal circumstances, the receiver's filename
is set when it saved as a new document (Save) or when an existing document
is saved under a different filename or path (Save As). See
Also: - fileName
- (void)setFileType:(NSString *)docType
Sets the document type under
which the file is saved to docType. The
document type affects how the data is filtered when it is written
to or read from a file.See Also: - fileType
- (void)setHasUndoManager:(BOOL)flag
Sets whether the receiver has
its own NSUndoManager. If flag is NO and
the receiver currently owns an NSUndoManager, the NSUndoManager
is released after being removed as an observer of undo-related notifications.See
Also: - hasUndoManager
- (void)setPrintInfo:(NSPrintInfo *)printInfo
Sets the document's NSPrintInfo
object to printInfo; this object
is used in laying out the document for printing.See
Also: - printInfo
- (void)setUndoManager:(NSUndoManager
*)undoManager
Sets the undo manager owned
by the receiver to undoManager and
releases any undo manager currently owned by the receiver. If undoManager is nil
,
it turns off the hasUndoManager flag. If undoManager is non-nil
,
it adds the receiver as an observer of NSUndoManagerDidUndoChangeNotification, NSUndoManagerDidRedoChangeNotification,
and NSUndoManagerWillCloseUndoGroupNotification.See
Also: - undoManager, NSUndoManager (class)
- (BOOL)shouldChangePrintInfo:(NSPrintInfo *)newPrintInfo
Returns whether the receiver
should allow changes to the default NSPrintInfo object used in printing
the document. The default implementation returns YES. Subclasses
can override this method to return NO. This method is invoked by
the runPageLayout: method, which sets a new NSPrintInfo for the
document only if this method returns YES.
- (BOOL)shouldCloseWindowController:(NSWindowController *)windowController
If closing the windowController would
cause the receiver to be closed, invokes canCloseDocument to display a Save
panel and give the user an opportunity to save the document. Returns
the return value of canCloseDocument .
Note that the receiver doesn't close until its window controller
closes.See Also: - close, - shouldCloseDocument (NSWindowController)
- (BOOL)shouldRunSavePanelWithAccessoryView
Returns YES by default; as
a result, when NSDocument displays the Save panel, it includes an
accessory view containing a pop-up list of supported writable document
types. Subclasses can override to return NO, thus
excluding the accessory view from the Save panel.Here is an
example implementation:
- (BOOL)shouldRunSavePanelWithAccessoryView
{
return [self fileName] == nil;
}
See
Also: - runModalSavePanel:withAccessoryView:
- (void)showWindows
Displays all windows of the
document, bringing them to the front and making them main or key,
as necessary.
- (NSUndoManager *)undoManager
Returns the NSUndoManager used
by the document or nil
if the receiver should
not own one. If the undo manager doesn't exist
and hasUndoManager returns YES, it creates one and invokes setUndoManager: with
the NSUndoManager as argument.
- (void)updateChangeCount:(NSDocumentChangeType)changeType
Updates the document's change
count according to changeType. The
change count indicates the document's edited status; if the change
count is zero, the document has no changes to save, and if the change
count is greater than zero, the document has been edited and is
unsaved. changeType can increment (NSChangeDone),
decrement (NSChangeUndone) , or set to zero (NSChangeClear) the
change count. If you are implementing undo and redo in an application,
you should increment the change count every time you create an undo group,
and decrement the change count when an undo or redo operation is performed.Note
that if you are using NSDocument's default undo/redo features,
setting the document's edited status by updating the change count
happens automatically. You only need to invoke this method when
you are not using these features.
See
Also: NSUndoManager
- (BOOL)validateMenuItem:(NSMenuItem *)anItem
Validates the Revert menu item
and items selected from the Save panel's pop-up list of writable
document types items. Returns YES if anItem should
be enabled, NO otherwise. Returns YES for Revert if the document
has been edited and a file exists for the document. Returns YES for
an item representing a writable type if, during a Save or Save As
operation, it is a native type for the document. Subclasses can
override this method to perform additional validations.
- (void)windowControllerDidLoadNib:(NSWindowController *)windowController
Overridden by subclass to perform
any tasks after the document's window controller (windowController)
loads the nib file containing the document window.
The default implementation does nothing.See
Also: - windowControllerWillLoadNib:, - windowControllers
- (void)windowControllerWillLoadNib:(NSWindowController *)windowController
Overridden by subclass to perform
any tasks before the document's window controller (windowController)
loads the nib file containing the document window.
The default implementation does nothing.See
Also: - windowControllerDidLoadNib:, - windowControllers
- (NSArray *)windowControllers
Returns the document's current
window controllers. If there are no window controllers,
returns an empty NSArray.See Also: - makeWindowControllers, - windowControllerDidLoadNib:, - windowControllerWillLoadNib:, - windowNibName
- (NSString *)windowNibName
Overridden by subclasses to
return the name of the document's sole nib file. Using
this name, NSDocument creates and instantiates a default instance
of NSWindowController to manage the window. If your document has
multiple nib files, each with its own single window, or if the default
NSWindowController instance is not adequate for your purposes, you
should override makeWindowControllers. The default implementation
returns nil.
See
Also: - windowControllers
- (BOOL)writeToFile:(NSString *)fileName ofType:(NSString
*)type
Writes document data of type docType to
the file fileName, returning whether the
operation was successful. This method invokes dataRepresentationOfType: and
is indirectly invoked whenever the document file is saved. It uses
NSData's writeToFile:atomically: method
to write to the file.This method is one of the location-based
primitives. Subclasses can override this method instead of overriding dataRepresentationOfType: to
write document data to the file system as an NSData object after
creating that object from internal data structures. Subclasses that
handle file packages such as RTFD or that treat locations of files
as anything other than paths should override this method. Override
implementations of this method should ensure that they filter document data
appropriately using NSPasteboard's filtering services.
See
Also: - loadDataRepresentation:ofType:, - readFromFile:ofType:
[Previous] [Next]