VocalEasel/Sources/VLDocument.mm

250 lines
5.7 KiB
Plaintext
Raw Normal View History

2006-09-11 02:49:56 +00:00
//
// VLDocument.mm
2006-09-11 02:49:56 +00:00
// Vocalese
//
// Created by Matthias Neeracher on 12/17/05.
// Copyright __MyCompanyName__ 2005 . All rights reserved.
//
#import "VLDocument.h"
2006-10-22 07:16:29 +00:00
#import "VLXMLDocument.h"
#import "VLLilypondDocument.h"
#import "VLPDFWindow.h"
#import "VLLogWindow.h"
#import "VLSheetWindow.h"
2006-09-11 02:49:56 +00:00
@implementation VLDocument
2006-10-03 17:52:54 +00:00
- (id)init
2006-10-03 17:52:54 +00:00
{
self = [super init];
if (self) {
song = new VLSong;
lilypondTemplate = @"default";
songTitle = @"";
songLyricist = @"";
songComposer = @"";
songArranger = @"";
sheetWin = nil;
pdfWin = nil;
logWin = nil;
}
return self;
2006-10-03 17:52:54 +00:00
}
- (void) close
2006-10-03 17:52:54 +00:00
{
[logWin close];
[pdfWin close];
2006-10-03 17:52:54 +00:00
[super close];
2006-10-03 17:52:54 +00:00
}
- (void) dealloc
{
delete song;
[super dealloc];
}
- (VLLogWindow *)logWin
{
if (!logWin) {
logWin = [[VLLogWindow alloc] initWithWindowNibName: @"VLLogWindow"];
[self addWindowController: logWin];
[logWin release];
}
return logWin;
}
- (VLPDFWindow *)pdfWin
{
if (!pdfWin) {
pdfWin = [[VLPDFWindow alloc] initWithWindowNibName: @"VLPDFWindow"];
[self addWindowController: pdfWin];
[pdfWin release];
}
return pdfWin;
}
- (void)makeWindowControllers
2006-09-11 02:49:56 +00:00
{
sheetWin = [[VLSheetWindow alloc] initWithWindowNibName: @"VLDocument"];
[self addWindowController: sheetWin];
[sheetWin setShouldCloseDocument:YES];
[sheetWin release];
2006-09-11 02:49:56 +00:00
}
- (void)showWindows
2006-09-11 02:49:56 +00:00
{
[sheetWin showWindow: self];
if ([pdfWin isWindowLoaded])
[pdfWin showWindow: self];
if ([logWin isWindowLoaded])
[logWin showWindow: self];
2006-09-11 02:49:56 +00:00
}
- (VLSong *) song
{
return song;
}
- (NSNumber *) songKey
{
const VLProperties & prop = song->fProperties.front();
return [NSNumber numberWithInt: (prop.fKey << 8) | (prop.fMode & 0xFF)];
}
- (void) setKey:(int)key transpose:(BOOL)transpose
{
VLProperties & prop = song->fProperties.front();
2006-10-14 10:10:19 +00:00
if (transpose)
song->Transpose((7*((key>>8)-prop.fKey) % 12));
2006-09-11 02:49:56 +00:00
prop.fKey = key >> 8;
prop.fMode= key & 0xFF;
2006-10-14 10:10:19 +00:00
[self updateChangeCount:NSChangeDone];
2006-09-11 02:49:56 +00:00
}
- (NSNumber *) songTime
{
const VLProperties & prop = song->fProperties.front();
return [NSNumber numberWithInt: (prop.fTime.fNum << 8) | prop.fTime.fDenom];
}
- (void) setTimeNum:(int)num denom:(int)denom
{
VLProperties & prop = song->fProperties.front();
prop.fTime = VLFraction(num, denom);
2006-10-14 10:10:19 +00:00
[self updateChangeCount:NSChangeDone];
2006-09-11 02:49:56 +00:00
}
- (NSNumber *) songDivisions
{
const VLProperties & prop = song->fProperties.front();
return [NSNumber numberWithInt: prop.fDivisions];
}
- (void) setDivisions:(int)divisions
{
VLProperties & prop = song->fProperties.front();
prop.fDivisions = divisions;
2006-10-14 10:10:19 +00:00
[self updateChangeCount:NSChangeDone];
2006-09-11 02:49:56 +00:00
}
2006-10-22 07:16:29 +00:00
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
2006-10-23 07:42:53 +00:00
if ([typeName isEqual:@"VLNativeType"]) {
2006-10-22 07:16:29 +00:00
return [self XMLDataWithError:outError];
2006-10-23 07:42:53 +00:00
} else if ([typeName isEqual:@"VLLilypondType"]) {
2006-10-22 07:16:29 +00:00
return [self lilypondDataWithError:outError];
2006-10-23 07:42:53 +00:00
} else {
if (outError)
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSPersistentStoreInvalidTypeError
userInfo:nil];
2006-10-22 07:16:29 +00:00
return nil;
2006-10-23 07:42:53 +00:00
}
2006-10-22 07:16:29 +00:00
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
2006-10-23 07:42:53 +00:00
if ([typeName isEqual:@"VLNativeType"]) {
2006-10-22 07:16:29 +00:00
return [self readFromXMLData:data error:outError];
2006-10-23 07:42:53 +00:00
} else {
if (outError)
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSPersistentStoreInvalidTypeError
userInfo:nil];
2006-10-22 07:16:29 +00:00
return NO;
2006-10-23 07:42:53 +00:00
}
2006-10-22 07:16:29 +00:00
}
- (IBAction) engrave:(id)sender
{
NSTask * lilypondTask = [[NSTask alloc] init];
NSString * path = [[self fileURL] path];
NSString * root =
[[path lastPathComponent] stringByDeletingPathExtension];
NSString * tmpDir = @"/var/tmp";
NSBundle * mainBundle = [NSBundle mainBundle];
//
// Convert to Lilypond format
//
NSError * err;
[self writeToURL:
[NSURL fileURLWithPath:
[[tmpDir stringByAppendingPathComponent:root]
stringByAppendingPathExtension:@"ly"]]
ofType:@"VLLilypondType" error:&err];
NSPipe * pipe = [NSPipe pipe];
NSString * tool =
[[NSUserDefaults standardUserDefaults]
stringForKey:@"VLLilypondPath"];
NSArray * arguments = [NSArray arrayWithObjects:tool, root, nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(engraveDone:)
name:NSTaskDidTerminateNotification object:lilypondTask];
[lilypondTask setCurrentDirectoryPath:tmpDir];
[lilypondTask setStandardOutput: pipe];
[lilypondTask setStandardError: pipe];
[lilypondTask setArguments: arguments];
[lilypondTask setLaunchPath:
[mainBundle pathForResource:@"lilyWrapper" ofType:@""]];
[lilypondTask launch];
[[self logWin] showWindow: self];
[NSThread detachNewThreadSelector:@selector(logFromFileHandle:) toTarget:logWin
withObject:[pipe fileHandleForReading]];
}
- (void)engraveDone:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] removeObserver: self];
int status = [[notification object] terminationStatus];
if (!status) {
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = [[self fileURL] path];
NSString * root =
[[path lastPathComponent] stringByDeletingPathExtension];
NSString * tmpDir = @"/var/tmp";
NSString * dstDir = [path stringByDeletingLastPathComponent];
NSString * pdf =
[root stringByAppendingPathExtension:@"pdf"];
[fileManager
removeFileAtPath:[dstDir stringByAppendingPathComponent:pdf]
handler:nil];
[fileManager
movePath:[tmpDir stringByAppendingPathComponent:pdf]
toPath:[dstDir stringByAppendingPathComponent:pdf]
handler:nil];
[[self pdfWin] showWindow: self];
[pdfWin reloadPDF];
}
}
- (IBAction) showOutput:(id)sender
{
[[self pdfWin] showWindow:sender];
}
- (IBAction) showLog:(id)sender
{
[[self logWin] showWindow:sender];
}
2006-09-11 02:49:56 +00:00
@end