2001-12-17 16:51:51 +00:00
|
|
|
/** <title>NSDocument</title>
|
2000-06-10 16:18:24 +00:00
|
|
|
|
2001-12-17 16:51:51 +00:00
|
|
|
<abstract>The abstract document class</abstract>
|
2000-06-10 16:18:24 +00:00
|
|
|
|
|
|
|
Copyright (C) 1999 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
Author: Carl Lindberg <Carl.Lindberg@hbo.com>
|
|
|
|
Date: 1999
|
|
|
|
Modifications: Fred Kiefer <FredKiefer@gmx.de>
|
|
|
|
Date: June 2000
|
|
|
|
|
|
|
|
This file is part of the GNUstep GUI Library.
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
License along with this library; see the file COPYING.LIB.
|
|
|
|
If not, write to the Free Software Foundation,
|
|
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Foundation/NSData.h>
|
2003-06-13 15:01:12 +00:00
|
|
|
#include "AppKit/NSDocument.h"
|
|
|
|
#include "AppKit/NSFileWrapper.h"
|
|
|
|
#include "AppKit/NSSavePanel.h"
|
|
|
|
#include "AppKit/NSPrintInfo.h"
|
|
|
|
#include "AppKit/NSPageLayout.h"
|
|
|
|
#include "AppKit/NSView.h"
|
|
|
|
#include "AppKit/NSPopUpButton.h"
|
|
|
|
#include "AppKit/NSDocumentFrameworkPrivate.h"
|
|
|
|
|
2003-07-31 23:52:10 +00:00
|
|
|
#include "GSGuiPrivate.h"
|
1999-09-11 00:52:04 +00:00
|
|
|
|
|
|
|
@implementation NSDocument
|
|
|
|
|
|
|
|
+ (NSArray *)readableTypes
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return [[NSDocumentController sharedDocumentController]
|
2003-07-21 11:59:47 +00:00
|
|
|
_editorAndViewerTypesForClass: self];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *)writableTypes
|
|
|
|
{
|
2002-10-12 03:14:22 +00:00
|
|
|
return [[NSDocumentController sharedDocumentController]
|
2003-07-21 11:59:47 +00:00
|
|
|
_editorTypesForClass: self];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
+ (BOOL)isNativeType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
return ([[self readableTypes] containsObject: type] &&
|
|
|
|
[[self writableTypes] containsObject: type]);
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (id) init
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
static int untitledCount = 1;
|
2003-08-16 17:12:34 +00:00
|
|
|
NSArray *fileTypes;
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
self = [super init];
|
|
|
|
if (self != nil)
|
|
|
|
{
|
|
|
|
_documentIndex = untitledCount++;
|
|
|
|
_windowControllers = [[NSMutableArray alloc] init];
|
2003-08-16 17:12:34 +00:00
|
|
|
fileTypes = [[self class] readableTypes];
|
2002-10-20 01:48:55 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
/* Set our default type */
|
2003-08-16 17:12:34 +00:00
|
|
|
if ([fileTypes count])
|
|
|
|
{
|
|
|
|
[self setFileType: [fileTypes objectAtIndex: 0]];
|
|
|
|
}
|
2003-07-21 11:59:47 +00:00
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
return self;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
/**
|
|
|
|
* Initialises the receiver with the contents of the document at fileName
|
|
|
|
* assuming that the type of data is as specified by fileType.<br />
|
|
|
|
* Destroys the receiver and returns nil on failure.
|
|
|
|
*/
|
|
|
|
- (id) initWithContentsOfFile: (NSString*)fileName ofType: (NSString*)fileType
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
self = [self init];
|
|
|
|
if (self != nil)
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([self readFromFile: fileName ofType: fileType])
|
|
|
|
{
|
|
|
|
[self setFileType: fileType];
|
|
|
|
[self setFileName: fileName];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSRunAlertPanel (_(@"Load failed"),
|
|
|
|
_(@"Could not load file %@."),
|
|
|
|
nil, nil, nil, fileName);
|
|
|
|
DESTROY(self);
|
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
|
|
|
return self;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
/**
|
|
|
|
* Initialises the receiver with the contents of the document at url
|
|
|
|
* assuming that the type of data is as specified by fileType.<br />
|
|
|
|
* Destroys the receiver and returns nil on failure.
|
|
|
|
*/
|
|
|
|
- (id) initWithContentsOfURL: (NSURL*)url ofType: (NSString*)fileType
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
self = [self init];
|
|
|
|
if (self != nil)
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([self readFromURL: url ofType: fileType])
|
|
|
|
{
|
|
|
|
[self setFileType: fileType];
|
|
|
|
[self setFileName:[url path]];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSRunAlertPanel(_(@"Load failed"),
|
|
|
|
_(@"Could not load URL %@."),
|
|
|
|
nil, nil, nil, [url absoluteString]);
|
|
|
|
DESTROY(self);
|
|
|
|
}
|
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
return self;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) dealloc
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
2000-06-10 16:18:24 +00:00
|
|
|
RELEASE(_undoManager);
|
|
|
|
RELEASE(_fileName);
|
|
|
|
RELEASE(_fileType);
|
|
|
|
RELEASE(_windowControllers);
|
|
|
|
RELEASE(_window);
|
|
|
|
RELEASE(_printInfo);
|
|
|
|
RELEASE(savePanelAccessory);
|
|
|
|
RELEASE(spaButton);
|
1999-09-12 03:19:36 +00:00
|
|
|
[super dealloc];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)fileName
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return _fileName;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)setFileName: (NSString *)fileName
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
ASSIGN(_fileName, fileName);
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
[_windowControllers makeObjectsPerformSelector:
|
2001-11-26 20:27:47 +00:00
|
|
|
@selector(synchronizeWindowTitleWithDocumentName)];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)fileType
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return _fileType;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)setFileType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
ASSIGN(_fileType, type);
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *)windowControllers
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return _windowControllers;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)addWindowController: (NSWindowController *)windowController
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[_windowControllers addObject: windowController];
|
1999-09-12 03:19:36 +00:00
|
|
|
if ([windowController document] != self)
|
2003-07-21 11:59:47 +00:00
|
|
|
{
|
|
|
|
[windowController setDocument: self];
|
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)removeWindowController: (NSWindowController *)windowController
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([_windowControllers containsObject: windowController])
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[windowController setDocument: nil];
|
|
|
|
[_windowControllers removeObject: windowController];
|
2001-07-28 22:38:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-11 00:52:04 +00:00
|
|
|
- (NSString *)windowNibName
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return nil;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
// private; called during nib load.
|
|
|
|
// we do not retain the window, since it should
|
1999-09-11 00:52:04 +00:00
|
|
|
// already have a retain from the nib.
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)setWindow: (NSWindow *)aWindow
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2002-04-03 16:59:43 +00:00
|
|
|
_window = aWindow;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2001-07-28 22:38:48 +00:00
|
|
|
//FIXME: In the later specification this method has a different return type!!
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) makeWindowControllers
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
NSString *name = [self windowNibName];
|
1999-09-11 00:52:04 +00:00
|
|
|
|
2000-06-10 16:18:24 +00:00
|
|
|
if (name != nil && [name length] > 0)
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
|
|
|
NSWindowController *controller;
|
2003-07-21 11:59:47 +00:00
|
|
|
|
|
|
|
controller = [[NSWindowController alloc] initWithWindowNibName: name
|
|
|
|
owner: self];
|
|
|
|
[self addWindowController: controller];
|
2000-06-10 16:18:24 +00:00
|
|
|
RELEASE(controller);
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
format: @"%@ must override either -windowNibName "
|
|
|
|
@"or -makeWindowControllers", NSStringFromClass([self class])];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
/**
|
|
|
|
* Makes all the documents windows visible by ordering them to the
|
|
|
|
* front and making them main or key.<br />
|
|
|
|
* If the document has no windows, this method has no effect.
|
|
|
|
*/
|
|
|
|
- (void) showWindows
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[_windowControllers makeObjectsPerformSelector: @selector(showWindow:)
|
|
|
|
withObject: self];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL) isDocumentEdited
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return _changeCount != 0;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)updateChangeCount: (NSDocumentChangeType)change
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
int i, count = [_windowControllers count];
|
|
|
|
BOOL isEdited;
|
|
|
|
|
|
|
|
switch (change)
|
|
|
|
{
|
|
|
|
case NSChangeDone: _changeCount++; break;
|
|
|
|
case NSChangeUndone: _changeCount--; break;
|
|
|
|
case NSChangeCleared: _changeCount = 0; break;
|
|
|
|
}
|
|
|
|
|
1999-09-11 00:52:04 +00:00
|
|
|
/*
|
|
|
|
* NOTE: Apple's implementation seems to not call -isDocumentEdited
|
|
|
|
* here but directly checks to see if _changeCount == 0. It seems it
|
|
|
|
* would be better to call the method in case it's overridden by a
|
|
|
|
* subclass, but we may want to keep Apple's behavior.
|
|
|
|
*/
|
1999-09-12 03:19:36 +00:00
|
|
|
isEdited = [self isDocumentEdited];
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
for (i=0; i<count; i++)
|
|
|
|
{
|
2001-11-26 20:27:47 +00:00
|
|
|
[[_windowControllers objectAtIndex: i] setDocumentEdited: isEdited];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)canCloseDocument
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
int result;
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
if (![self isDocumentEdited])
|
|
|
|
return YES;
|
1999-09-11 00:52:04 +00:00
|
|
|
|
2002-09-25 01:52:05 +00:00
|
|
|
result = NSRunAlertPanel (_(@"Close"),
|
|
|
|
_(@"%@ has changed. Save?"),
|
|
|
|
_(@"Save"), _(@"Cancel"), _(@"Don't Save"),
|
|
|
|
[self displayName]);
|
1999-09-12 03:19:36 +00:00
|
|
|
|
1999-09-11 00:52:04 +00:00
|
|
|
#define Save NSAlertDefaultReturn
|
|
|
|
#define Cancel NSAlertAlternateReturn
|
|
|
|
#define DontSave NSAlertOtherReturn
|
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
switch (result)
|
|
|
|
{
|
|
|
|
// return NO if save failed
|
2002-09-25 01:52:05 +00:00
|
|
|
case Save:
|
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self saveDocument: nil];
|
2002-09-25 01:52:05 +00:00
|
|
|
return ![self isDocumentEdited];
|
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
case DontSave: return YES;
|
|
|
|
case Cancel:
|
|
|
|
default: return NO;
|
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)canCloseDocumentWithDelegate: (id)delegate
|
|
|
|
shouldCloseSelector: (SEL)shouldCloseSelector
|
|
|
|
contextInfo: (void *)contextInfo
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
|
|
|
BOOL result = [self canCloseDocument];
|
|
|
|
|
|
|
|
if (delegate != nil && shouldCloseSelector != NULL)
|
|
|
|
{
|
|
|
|
void (*meth)(id, SEL, id, BOOL, void*);
|
|
|
|
meth = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
|
|
|
|
shouldCloseSelector];
|
|
|
|
if (meth)
|
|
|
|
meth(delegate, shouldCloseSelector, self, result, contextInfo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)shouldCloseWindowController: (NSWindowController *)windowController
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
if (![_windowControllers containsObject: windowController]) return YES;
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
/* If it's the last window controller, pop up a warning */
|
|
|
|
/* maybe we should count only loaded window controllers (or visible windows). */
|
|
|
|
if ([windowController shouldCloseDocument]
|
|
|
|
|| [_windowControllers count] == 1)
|
|
|
|
{
|
|
|
|
return [self canCloseDocument];
|
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
return YES;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)shouldCloseWindowController: (NSWindowController *)windowController
|
|
|
|
delegate: (id)delegate
|
|
|
|
shouldCloseSelector: (SEL)callback
|
|
|
|
contextInfo: (void *)contextInfo
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
|
|
|
BOOL result = [self shouldCloseWindowController: windowController];
|
|
|
|
|
|
|
|
if (delegate != nil && callback != NULL)
|
|
|
|
{
|
|
|
|
void (*meth)(id, SEL, id, BOOL, void*);
|
|
|
|
meth = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
|
|
|
|
callback];
|
|
|
|
|
|
|
|
if (meth)
|
|
|
|
meth(delegate, callback, self, result, contextInfo);
|
|
|
|
}
|
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
|
|
|
|
- (NSString *)displayName
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
if ([self fileName] != nil)
|
|
|
|
{
|
|
|
|
return [[[self fileName] lastPathComponent] stringByDeletingPathExtension];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-09-25 01:52:05 +00:00
|
|
|
return [NSString stringWithFormat: _(@"Untitled-%d"), _documentIndex];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)keepBackupFile
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return NO;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (NSData *)dataRepresentationOfType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[NSException raise: NSInternalInconsistencyException format:@"%@ must implement %@",
|
1999-09-12 03:19:36 +00:00
|
|
|
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
|
|
|
return nil;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)loadDataRepresentation: (NSData *)data ofType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[NSException raise: NSInternalInconsistencyException format:@"%@ must implement %@",
|
1999-09-12 03:19:36 +00:00
|
|
|
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
|
|
|
return NO;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (NSFileWrapper *)fileWrapperRepresentationOfType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
NSData *data = [self dataRepresentationOfType: type];
|
1999-09-12 03:19:36 +00:00
|
|
|
|
|
|
|
if (data == nil)
|
|
|
|
return nil;
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
return AUTORELEASE([[NSFileWrapper alloc] initRegularFileWithContents: data]);
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)loadFileWrapperRepresentation: (NSFileWrapper *)wrapper ofType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
if ([wrapper isRegularFile])
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
return [self loadDataRepresentation:[wrapper regularFileContents] ofType: type];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
|
|
|
|
1999-09-11 00:52:04 +00:00
|
|
|
/*
|
|
|
|
* This even happens on a symlink. May want to use
|
|
|
|
* -stringByResolvingAllSymlinksInPath somewhere, but Apple doesn't.
|
|
|
|
*/
|
1999-09-12 03:19:36 +00:00
|
|
|
NSLog(@"%@ must be overridden if your document deals with file packages.",
|
|
|
|
NSStringFromSelector(_cmd));
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
return NO;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)writeToFile: (NSString *)fileName ofType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
return [[self fileWrapperRepresentationOfType: type]
|
|
|
|
writeToFile: fileName atomically: YES updateFilenames: YES];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)readFromFile: (NSString *)fileName ofType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
NSFileWrapper *wrapper = AUTORELEASE([[NSFileWrapper alloc] initWithPath: fileName]);
|
|
|
|
return [self loadFileWrapperRepresentation: wrapper ofType: type];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)revertToSavedFromFile: (NSString *)fileName ofType: (NSString *)type
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
return [self readFromFile: fileName ofType: type];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)writeToURL: (NSURL *)url ofType: (NSString *)type
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
NSData *data = [self dataRepresentationOfType: type];
|
2000-06-10 16:18:24 +00:00
|
|
|
|
|
|
|
if (data == nil)
|
|
|
|
return NO;
|
|
|
|
|
|
|
|
return [url setResourceData: data];
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)readFromURL: (NSURL *)url ofType: (NSString *)type
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
|
|
|
NSData *data = [url resourceDataUsingCache: YES];
|
|
|
|
|
|
|
|
if (data == nil)
|
|
|
|
return NO;
|
|
|
|
|
|
|
|
return [self loadDataRepresentation: data ofType: type];
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)revertToSavedFromURL: (NSURL *)url ofType: (NSString *)type
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
|
|
|
return [self readFromURL: url ofType: type];
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)changeSaveType: (id)sender
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
|
|
|
//FIXME if we have accessory -- store the desired save type somewhere.
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (int)runModalSavePanel: (NSSavePanel *)savePanel
|
|
|
|
withAccessoryView: (NSView *)accessoryView
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[savePanel setAccessoryView: accessoryView];
|
1999-09-12 03:19:36 +00:00
|
|
|
return [savePanel runModal];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)shouldRunSavePanelWithAccessoryView
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return YES;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) _loadPanelAccessoryNib
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
|
|
|
// FIXME. We need to load the pop-up button
|
|
|
|
}
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) _addItemsToSpaButtonFromArray: (NSArray *)types
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
|
|
|
// FIXME. Add types to popup.
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (NSString *)fileNameFromRunningSavePanelForSaveOperation: (NSSaveOperationType)saveOperation
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
NSView *accessory = nil;
|
2002-10-26 02:38:34 +00:00
|
|
|
NSString *title;
|
|
|
|
NSString *directory;
|
|
|
|
NSArray *extensions;
|
|
|
|
NSDocumentController *controller;
|
1999-09-12 03:19:36 +00:00
|
|
|
NSSavePanel *savePanel = [NSSavePanel savePanel];
|
2002-10-26 02:38:34 +00:00
|
|
|
|
|
|
|
controller = [NSDocumentController sharedDocumentController];
|
|
|
|
extensions = [controller fileExtensionsFromType:[self fileType]];
|
1999-09-12 03:19:36 +00:00
|
|
|
|
|
|
|
if ([self shouldRunSavePanelWithAccessoryView])
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
if (savePanelAccessory == nil)
|
|
|
|
[self _loadPanelAccessoryNib];
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
[self _addItemsToSpaButtonFromArray: extensions];
|
1999-09-12 03:19:36 +00:00
|
|
|
|
|
|
|
accessory = savePanelAccessory;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
if ([extensions count] > 0)
|
|
|
|
[savePanel setRequiredFileType:[extensions objectAtIndex:0]];
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
switch (saveOperation)
|
|
|
|
{
|
2002-09-25 01:52:05 +00:00
|
|
|
case NSSaveAsOperation: title = _(@"Save As"); break;
|
2002-10-26 02:38:34 +00:00
|
|
|
case NSSaveToOperation: title = _(@"Save To"); break;
|
|
|
|
case NSSaveOperation:
|
|
|
|
default:
|
|
|
|
title = _(@"Save");
|
|
|
|
break;
|
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
[savePanel setTitle: title];
|
2002-10-26 02:38:34 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
if ([self fileName])
|
2002-10-26 02:38:34 +00:00
|
|
|
directory = [[self fileName] stringByDeletingLastPathComponent];
|
|
|
|
else
|
|
|
|
directory = [controller currentDirectory];
|
|
|
|
[savePanel setDirectory: directory];
|
1999-09-11 00:52:04 +00:00
|
|
|
|
2004-05-08 13:40:40 +00:00
|
|
|
if (![self prepareSavePanel: savePanel])
|
|
|
|
{
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([self runModalSavePanel: savePanel withAccessoryView: accessory])
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
|
|
|
return [savePanel filename];
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)shouldChangePrintInfo: (NSPrintInfo *)newPrintInfo
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return YES;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPrintInfo *)printInfo
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return _printInfo? _printInfo : [NSPrintInfo sharedPrintInfo];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)setPrintInfo: (NSPrintInfo *)printInfo
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
ASSIGN(_printInfo, printInfo);
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
// Page layout panel (Page Setup)
|
1999-09-11 00:52:04 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (int)runModalPageLayoutWithPrintInfo: (NSPrintInfo *)printInfo
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
return [[NSPageLayout pageLayout] runModalWithPrintInfo: printInfo];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)runPageLayout: (id)sender
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
NSPrintInfo *printInfo = [self printInfo];
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([self runModalPageLayoutWithPrintInfo: printInfo]
|
|
|
|
&& [self shouldChangePrintInfo: printInfo])
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self setPrintInfo: printInfo];
|
|
|
|
[self updateChangeCount: NSChangeDone];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This is overridden by subclassers; the default implementation does nothing. */
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)printShowingPrintPanel: (BOOL)flag
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)printDocument: (id)sender
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self printShowingPrintPanel: YES];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)validateMenuItem: (NSMenuItem *)anItem
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
if ([anItem action] == @selector(revertDocumentToSaved:))
|
|
|
|
return ([self fileName] != nil && [self isDocumentEdited]);
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
// FIXME should validate spa popup items; return YES if it's a native type.
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
return YES;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>)anItem
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
|
|
|
if ([anItem action] == @selector(revertDocumentToSaved:))
|
|
|
|
return ([self fileName] != nil);
|
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2000-06-10 16:18:24 +00:00
|
|
|
- (NSString *)fileTypeFromLastRunSavePanel
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
// FIXME this should return type picked on save accessory
|
|
|
|
// return [spaPopupButton title];
|
|
|
|
return [self fileType];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2002-10-26 03:35:11 +00:00
|
|
|
- (NSDictionary *)fileAttributesToWriteToFile: (NSString *)fullDocumentPath
|
|
|
|
ofType: (NSString *)docType
|
|
|
|
saveOperation: (NSSaveOperationType)saveOperationType
|
|
|
|
{
|
|
|
|
// FIXME: Implement.
|
|
|
|
return [NSDictionary dictionary];
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)writeToFile: (NSString *)fileName
|
|
|
|
ofType: (NSString *)type
|
|
|
|
originalFile: (NSString *)origFileName
|
|
|
|
saveOperation: (NSSaveOperationType)saveOp
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
|
|
|
return [self writeToFile: fileName ofType: type];
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)writeWithBackupToFile: (NSString *)fileName
|
|
|
|
ofType: (NSString *)fileType
|
|
|
|
saveOperation: (NSSaveOperationType)saveOp
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
NSString *backupFilename = nil;
|
2000-06-10 16:18:24 +00:00
|
|
|
|
|
|
|
if (fileName)
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([fileManager fileExistsAtPath: fileName])
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
NSString *extension = [fileName pathExtension];
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2000-06-10 16:18:24 +00:00
|
|
|
backupFilename = [fileName stringByDeletingPathExtension];
|
1999-09-12 03:19:36 +00:00
|
|
|
backupFilename = [backupFilename stringByAppendingString:@"~"];
|
2003-07-21 11:59:47 +00:00
|
|
|
backupFilename = [backupFilename stringByAppendingPathExtension: extension];
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
/* Save panel has already asked if the user wants to replace it */
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
/* NSFileManager movePath: will fail if destination exists */
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([fileManager fileExistsAtPath: backupFilename])
|
|
|
|
[fileManager removeFileAtPath: backupFilename handler: nil];
|
1999-09-11 00:52:04 +00:00
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
// Move or copy?
|
2003-07-21 11:59:47 +00:00
|
|
|
if (![fileManager movePath: fileName toPath: backupFilename handler: nil] &&
|
1999-09-12 03:19:36 +00:00
|
|
|
[self keepBackupFile])
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2002-09-25 01:52:05 +00:00
|
|
|
int result = NSRunAlertPanel(_(@"File Error"),
|
|
|
|
_(@"Can't create backup file. Save anyways?"),
|
|
|
|
_(@"Save"), _(@"Cancel"), nil);
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2000-06-10 16:18:24 +00:00
|
|
|
if (result != NSAlertDefaultReturn) return NO;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
}
|
2000-06-10 16:18:24 +00:00
|
|
|
if ([self writeToFile: fileName
|
|
|
|
ofType: fileType
|
|
|
|
originalFile: backupFilename
|
|
|
|
saveOperation: saveOp])
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
if (saveOp != NSSaveToOperation)
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self setFileName: fileName];
|
2000-06-10 16:18:24 +00:00
|
|
|
[self setFileType: fileType];
|
2003-07-21 11:59:47 +00:00
|
|
|
[self updateChangeCount: NSChangeCleared];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
2004-05-08 13:40:40 +00:00
|
|
|
|
|
|
|
// FIXME: Should set the file attributes
|
|
|
|
|
1999-09-12 03:19:36 +00:00
|
|
|
if (backupFilename && ![self keepBackupFile])
|
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[fileManager removeFileAtPath: backupFilename handler: nil];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
2000-06-10 16:18:24 +00:00
|
|
|
|
|
|
|
return YES;
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
|
|
|
}
|
2000-06-10 16:18:24 +00:00
|
|
|
|
|
|
|
return NO;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)saveDocument: (id)sender
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
NSString *filename = [self fileName];
|
|
|
|
|
|
|
|
if (filename == nil)
|
|
|
|
{
|
|
|
|
[self saveDocumentAs: sender];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
[self writeWithBackupToFile: filename
|
|
|
|
ofType: [self fileType]
|
|
|
|
saveOperation: NSSaveOperation];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)saveDocumentAs: (id)sender
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
NSString *filename =
|
|
|
|
[self fileNameFromRunningSavePanelForSaveOperation:
|
|
|
|
NSSaveAsOperation];
|
|
|
|
|
|
|
|
[self writeWithBackupToFile: filename
|
|
|
|
ofType: [self fileTypeFromLastRunSavePanel]
|
|
|
|
saveOperation: NSSaveAsOperation];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)saveDocumentTo: (id)sender
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
NSString *filename =
|
|
|
|
[self fileNameFromRunningSavePanelForSaveOperation:
|
|
|
|
NSSaveToOperation];
|
|
|
|
|
|
|
|
[self writeWithBackupToFile: filename
|
|
|
|
ofType: [self fileTypeFromLastRunSavePanel]
|
|
|
|
saveOperation: NSSaveToOperation];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)saveDocumentWithDelegate: (id)delegate
|
|
|
|
didSaveSelector: (SEL)didSaveSelector
|
|
|
|
contextInfo: (void *)contextInfo
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
2004-05-08 13:40:40 +00:00
|
|
|
[self runModalSavePanelForSaveOperation: NSSaveOperation
|
|
|
|
delegate: delegate
|
|
|
|
didSaveSelector: didSaveSelector
|
|
|
|
contextInfo: contextInfo];
|
2001-07-28 22:38:48 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)saveToFile: (NSString *)fileName
|
|
|
|
saveOperation: (NSSaveOperationType)saveOperation
|
|
|
|
delegate: (id)delegate
|
|
|
|
didSaveSelector: (SEL)didSaveSelector
|
|
|
|
contextInfo: (void *)contextInfo
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
2004-05-08 13:40:40 +00:00
|
|
|
BOOL saved = NO;
|
|
|
|
|
|
|
|
if (fileName != nil)
|
|
|
|
{
|
|
|
|
saved = [self writeWithBackupToFile: fileName
|
|
|
|
ofType: [self fileTypeFromLastRunSavePanel]
|
|
|
|
saveOperation: saveOperation];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delegate != nil && didSaveSelector != NULL)
|
|
|
|
{
|
|
|
|
void (*meth)(id, SEL, id, BOOL, void*);
|
|
|
|
meth = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
|
|
|
|
didSaveSelector];
|
|
|
|
if (meth)
|
|
|
|
meth(delegate, didSaveSelector, self, saved, contextInfo);
|
|
|
|
}
|
2001-07-28 22:38:48 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (BOOL)prepareSavePanel: (NSSavePanel *)savePanel
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)runModalSavePanelForSaveOperation: (NSSaveOperationType)saveOperation
|
|
|
|
delegate: (id)delegate
|
|
|
|
didSaveSelector: (SEL)didSaveSelector
|
|
|
|
contextInfo: (void *)contextInfo
|
2001-07-28 22:38:48 +00:00
|
|
|
{
|
2004-05-08 13:40:40 +00:00
|
|
|
NSString *fileName;
|
|
|
|
|
|
|
|
// FIXME: Setting of the delegate of the save panel is missing
|
|
|
|
fileName = [self fileNameFromRunningSavePanelForSaveOperation: saveOperation];
|
|
|
|
[self saveToFile: fileName
|
|
|
|
saveOperation: saveOperation
|
|
|
|
delegate: delegate
|
|
|
|
didSaveSelector: didSaveSelector
|
|
|
|
contextInfo: contextInfo];
|
2001-07-28 22:38:48 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (IBAction)revertDocumentToSaved: (id)sender
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
int result;
|
1999-09-11 00:52:04 +00:00
|
|
|
|
2002-09-25 01:52:05 +00:00
|
|
|
result = NSRunAlertPanel
|
|
|
|
(_(@"Revert"),
|
|
|
|
_(@"%@ has been edited. Are you sure you want to undo changes?"),
|
|
|
|
_(@"Revert"), _(@"Cancel"), nil,
|
|
|
|
[self displayName]);
|
1999-09-12 03:19:36 +00:00
|
|
|
|
|
|
|
if (result == NSAlertDefaultReturn &&
|
|
|
|
[self revertToSavedFromFile:[self fileName] ofType:[self fileType]])
|
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self updateChangeCount: NSChangeCleared];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2002-11-01 22:42:52 +00:00
|
|
|
/** Closes all the windows owned by the document, then removes itself
|
|
|
|
from the list of documents known by the NSDocumentController. This
|
|
|
|
method does not ask the user if they want to save the document before
|
|
|
|
closing. It is closed without saving any information.
|
|
|
|
*/
|
1999-09-11 00:52:04 +00:00
|
|
|
- (void)close
|
|
|
|
{
|
2002-11-01 22:42:52 +00:00
|
|
|
if (_docFlags.inClose == NO)
|
|
|
|
{
|
|
|
|
int count = [_windowControllers count];
|
|
|
|
/* Closing a windowController will also send us a close, so make
|
|
|
|
sure we don't go recursive */
|
|
|
|
_docFlags.inClose = YES;
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
NSWindowController *array[count];
|
|
|
|
[_windowControllers getObjects: array];
|
|
|
|
while (count-- > 0)
|
|
|
|
[array[count] close];
|
|
|
|
}
|
2003-07-21 11:59:47 +00:00
|
|
|
[[NSDocumentController sharedDocumentController] removeDocument: self];
|
2002-11-01 22:42:52 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)windowControllerWillLoadNib: (NSWindowController *)windowController {}
|
|
|
|
- (void)windowControllerDidLoadNib: (NSWindowController *)windowController {}
|
1999-09-11 00:52:04 +00:00
|
|
|
|
|
|
|
- (NSUndoManager *)undoManager
|
|
|
|
{
|
2005-01-14 10:50:06 +00:00
|
|
|
if (_undoManager == nil && [self hasUndoManager] == NO)
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2000-06-10 16:18:24 +00:00
|
|
|
[self setUndoManager: AUTORELEASE([[NSUndoManager alloc] init])];
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return _undoManager;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)setUndoManager: (NSUndoManager *)undoManager
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
if (undoManager != _undoManager)
|
|
|
|
{
|
|
|
|
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
|
|
|
|
|
|
|
if (_undoManager)
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[center removeObserver: self
|
|
|
|
name: NSUndoManagerWillCloseUndoGroupNotification
|
1999-09-12 03:19:36 +00:00
|
|
|
object:_undoManager];
|
2003-07-21 11:59:47 +00:00
|
|
|
[center removeObserver: self
|
|
|
|
name: NSUndoManagerDidUndoChangeNotification
|
1999-09-12 03:19:36 +00:00
|
|
|
object:_undoManager];
|
2003-07-21 11:59:47 +00:00
|
|
|
[center removeObserver: self
|
|
|
|
name: NSUndoManagerDidRedoChangeNotification
|
1999-09-12 03:19:36 +00:00
|
|
|
object:_undoManager];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2000-06-10 16:18:24 +00:00
|
|
|
ASSIGN(_undoManager, undoManager);
|
1999-09-12 03:19:36 +00:00
|
|
|
|
|
|
|
if (_undoManager == nil)
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self setHasUndoManager: NO];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
else
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[center addObserver: self
|
1999-09-12 03:19:36 +00:00
|
|
|
selector:@selector(_changeWasDone:)
|
2003-07-21 11:59:47 +00:00
|
|
|
name: NSUndoManagerWillCloseUndoGroupNotification
|
1999-09-12 03:19:36 +00:00
|
|
|
object:_undoManager];
|
2003-07-21 11:59:47 +00:00
|
|
|
[center addObserver: self
|
1999-09-12 03:19:36 +00:00
|
|
|
selector:@selector(_changeWasUndone:)
|
2003-07-21 11:59:47 +00:00
|
|
|
name: NSUndoManagerDidUndoChangeNotification
|
1999-09-12 03:19:36 +00:00
|
|
|
object:_undoManager];
|
|
|
|
[[NSNotificationCenter defaultCenter]
|
2003-07-21 11:59:47 +00:00
|
|
|
addObserver: self
|
1999-09-12 03:19:36 +00:00
|
|
|
selector:@selector(_changeWasRedone:)
|
2003-07-21 11:59:47 +00:00
|
|
|
name: NSUndoManagerDidRedoChangeNotification
|
1999-09-12 03:19:36 +00:00
|
|
|
object:_undoManager];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)hasUndoManager
|
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
return _docFlags.hasUndoManager;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void)setHasUndoManager: (BOOL)flag
|
1999-09-11 00:52:04 +00:00
|
|
|
{
|
1999-09-12 03:19:36 +00:00
|
|
|
if (_undoManager && !flag)
|
2003-07-21 11:59:47 +00:00
|
|
|
[self setUndoManager: nil];
|
1999-09-12 03:19:36 +00:00
|
|
|
|
|
|
|
_docFlags.hasUndoManager = flag;
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
2000-06-10 16:18:24 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSDocument(Private)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This private method is used to transfer window ownership to the
|
|
|
|
* NSWindowController in situations (such as the default) where the
|
|
|
|
* document is set to the nib owner, and thus owns the window immediately
|
|
|
|
* following the loading of the nib.
|
|
|
|
*/
|
2003-07-21 11:59:47 +00:00
|
|
|
- (NSWindow *) _transferWindowOwnership
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
|
|
|
NSWindow *window = _window;
|
|
|
|
_window = nil;
|
|
|
|
return AUTORELEASE(window);
|
|
|
|
}
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) _removeWindowController: (NSWindowController *)windowController
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
if ([_windowControllers containsObject: windowController])
|
2000-06-10 16:18:24 +00:00
|
|
|
{
|
|
|
|
BOOL autoClose = [windowController shouldCloseDocument];
|
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
[windowController setDocument: nil];
|
|
|
|
[_windowControllers removeObject: windowController];
|
2000-06-10 16:18:24 +00:00
|
|
|
|
|
|
|
if (autoClose || [_windowControllers count] == 0)
|
|
|
|
{
|
|
|
|
[self close];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-09-11 00:52:04 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) _changeWasDone: (NSNotification *)notification
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self updateChangeCount: NSChangeDone];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) _changeWasUndone: (NSNotification *)notification
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self updateChangeCount: NSChangeUndone];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
1999-09-12 03:19:36 +00:00
|
|
|
|
2003-07-21 11:59:47 +00:00
|
|
|
- (void) _changeWasRedone: (NSNotification *)notification
|
1999-09-12 03:19:36 +00:00
|
|
|
{
|
2003-07-21 11:59:47 +00:00
|
|
|
[self updateChangeCount: NSChangeDone];
|
1999-09-11 00:52:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|