diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib index 4d563ef..f1c65c1 100644 --- a/English.lproj/MainMenu.nib/info.nib +++ b/English.lproj/MainMenu.nib/info.nib @@ -7,16 +7,16 @@ IBEditorPositions 29 - 150 476 301 44 0 0 1024 746 + 214 402 301 44 0 0 1024 746 IBFramework Version - 452.0 + 453.0 IBOpenObjects 29 217 IBSystem Version - 9A283 + 9A294 diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib index 8a1fe5f..70a5b89 100644 Binary files a/English.lproj/MainMenu.nib/keyedobjects.nib and b/English.lproj/MainMenu.nib/keyedobjects.nib differ diff --git a/English.lproj/VLDocument.nib/classes.nib b/English.lproj/VLDocument.nib/classes.nib index 28b8ef2..5bb4969 100644 --- a/English.lproj/VLDocument.nib/classes.nib +++ b/English.lproj/VLDocument.nib/classes.nib @@ -1,14 +1,37 @@ { IBClasses = ( - {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + ACTIONS = {engrave = id; showLog = id; showOutput = id; }; + CLASS = FirstResponder; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + }, {CLASS = VLDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; }, {CLASS = VLEditable; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + CLASS = VLPDFWindow; + LANGUAGE = ObjC; + OUTLETS = { + nextPageItem = id; + pdfView = id; + prevPageItem = id; + zoomInItem = id; + zoomOutItem = id; + }; + SUPERCLASS = NSWindowController; + }, { ACTIONS = {hideFieldEditor = id; setDivisions = id; setKey = id; setTime = id; }; CLASS = VLSheetView; LANGUAGE = ObjC; OUTLETS = {fFieldEditor = id; }; SUPERCLASS = NSView; + }, + { + CLASS = VLSheetWindow; + LANGUAGE = ObjC; + OUTLETS = {logToolItem = id; outputToolItem = id; runToolItem = id; }; + SUPERCLASS = NSWindowController; } ); IBVersion = 1; diff --git a/English.lproj/VLDocument.nib/info.nib b/English.lproj/VLDocument.nib/info.nib index fa0cb16..9ce18dc 100644 --- a/English.lproj/VLDocument.nib/info.nib +++ b/English.lproj/VLDocument.nib/info.nib @@ -3,14 +3,15 @@ IBDocumentLocation - 36 103 356 240 0 0 1024 746 + 31 27 356 240 0 0 1024 746 IBFramework Version - 452.0 + 453.0 IBOpenObjects + 144 5 IBSystem Version - 9A283 + 9A294 diff --git a/English.lproj/VLDocument.nib/keyedobjects.nib b/English.lproj/VLDocument.nib/keyedobjects.nib index 4191aa7..bc635eb 100644 Binary files a/English.lproj/VLDocument.nib/keyedobjects.nib and b/English.lproj/VLDocument.nib/keyedobjects.nib differ diff --git a/Resources/VLLogWindow.nib/info.nib b/Resources/VLLogWindow.nib/info.nib index b61433b..3d79bd0 100644 --- a/Resources/VLLogWindow.nib/info.nib +++ b/Resources/VLLogWindow.nib/info.nib @@ -5,12 +5,12 @@ IBDocumentLocation 210 57 356 240 0 0 1024 746 IBFramework Version - 452.0 + 453.0 IBOpenObjects 5 IBSystem Version - 9A283 + 9A294 diff --git a/Resources/VLLogWindow.nib/keyedobjects.nib b/Resources/VLLogWindow.nib/keyedobjects.nib index 7f1eb1c..2a25b42 100644 Binary files a/Resources/VLLogWindow.nib/keyedobjects.nib and b/Resources/VLLogWindow.nib/keyedobjects.nib differ diff --git a/Resources/VLPDFWindow.nib/classes.nib b/Resources/VLPDFWindow.nib/classes.nib index 905a33c..3f0835d 100644 --- a/Resources/VLPDFWindow.nib/classes.nib +++ b/Resources/VLPDFWindow.nib/classes.nib @@ -19,12 +19,13 @@ SUPERCLASS = NSWindowController; }, {CLASS = LilypondPDFView; LANGUAGE = ObjC; SUPERCLASS = PDFView; }, + {CLASS = VLPDFView; LANGUAGE = ObjC; SUPERCLASS = PDFView; }, { CLASS = VLPDFWindow; LANGUAGE = ObjC; OUTLETS = { - PDFView = id; nextPageItem = id; + pdfView = id; prevPageItem = id; zoomInItem = id; zoomOutItem = id; diff --git a/Resources/VLPDFWindow.nib/info.nib b/Resources/VLPDFWindow.nib/info.nib index 6d5ff79..d614701 100644 --- a/Resources/VLPDFWindow.nib/info.nib +++ b/Resources/VLPDFWindow.nib/info.nib @@ -3,14 +3,15 @@ IBDocumentLocation - 122 105 356 240 0 0 1024 746 + 57 42 356 240 0 0 1024 746 IBFramework Version - 452.0 + 453.0 IBOpenObjects 11 + 5 IBSystem Version - 9A283 + 9A294 diff --git a/Resources/VLPDFWindow.nib/keyedobjects.nib b/Resources/VLPDFWindow.nib/keyedobjects.nib index 0a2a528..34d87ee 100644 Binary files a/Resources/VLPDFWindow.nib/keyedobjects.nib and b/Resources/VLPDFWindow.nib/keyedobjects.nib differ diff --git a/Resources/lilyWrapper b/Resources/lilyWrapper new file mode 100755 index 0000000..8284470 --- /dev/null +++ b/Resources/lilyWrapper @@ -0,0 +1,8 @@ +#!/bin/bash -l + +export PATH=`dirname $1`:$PATH +echo PATH=$PATH +$* + + + diff --git a/Sources/VLAppController.mm b/Sources/VLAppController.mm index 238a44a..750299e 100644 --- a/Sources/VLAppController.mm +++ b/Sources/VLAppController.mm @@ -59,6 +59,7 @@ toolPath = nil; appPath = nil; } + return self; } - (NSString*)getLineFromCommand:(NSString*)command @@ -82,7 +83,7 @@ { NSString * cmd = [NSString stringWithFormat: - @"%@ --version | awk '{ print $3 }'", + @"%@ --version | head -1 | awk '{ print $3 }'", path]; return [self getLineFromCommand:cmd]; } diff --git a/Sources/VLDocument.h b/Sources/VLDocument.h index 62049d4..19d6197 100644 --- a/Sources/VLDocument.h +++ b/Sources/VLDocument.h @@ -9,28 +9,22 @@ #import "VLModel.h" #import -@interface VLEditable : NSObject -{ -} - -- (NSString *) stringValue; -- (void) setStringValue:(NSString*)val; -- (BOOL) validValue:(NSString*)val; -- (void) moveToNext; -- (void) moveToPrev; -- (void) highlightCursor; - -@end +@class VLSheetWindow; +@class VLPDFWindow; +@class VLLogWindow; @interface VLDocument : NSDocument { - VLSong * song; - VLEditable *editTarget; - NSString * lilypondTemplate; - NSString * songTitle; - NSString * songLyricist; - NSString * songComposer; - NSString * songArranger; + VLSong * song; + NSString * lilypondTemplate; + NSString * songTitle; + NSString * songLyricist; + NSString * songComposer; + NSString * songArranger; + + VLSheetWindow * sheetWin; + VLLogWindow * logWin; + VLPDFWindow * pdfWin; } - (VLSong *) song; @@ -42,4 +36,8 @@ - (void) setTimeNum:(int)num denom:(int)denom; - (void) setDivisions:(int)divisions; +- (IBAction) engrave:(id)sender; +- (IBAction) showOutput:(id)sender; +- (IBAction) showLog:(id)sender; + @end diff --git a/Sources/VLDocument.mm b/Sources/VLDocument.mm index 1a55fa2..89d805c 100644 --- a/Sources/VLDocument.mm +++ b/Sources/VLDocument.mm @@ -1,5 +1,5 @@ // -// MyDocument.m +// VLDocument.mm // Vocalese // // Created by Matthias Neeracher on 12/17/05. @@ -9,36 +9,9 @@ #import "VLDocument.h" #import "VLXMLDocument.h" #import "VLLilypondDocument.h" - -@implementation VLEditable - -- (NSString *) stringValue -{ - return @""; -} - -- (void) setStringValue:(NSString*)val -{ -} - -- (BOOL) validValue:(NSString*)val -{ - return YES; -} - -- (void) moveToNext -{ -} - -- (void) moveToPrev -{ -} - -- (void) highlightCursor -{ -} - -@end +#import "VLPDFWindow.h" +#import "VLLogWindow.h" +#import "VLSheetWindow.h" @implementation VLDocument @@ -46,27 +19,71 @@ { self = [super init]; if (self) { - - // Add your subclass-specific initialization here. - // If an error occurs here, send a [self release] message and return nil. - song = new VLSong; - editTarget = nil; lilypondTemplate = @"default"; songTitle = @""; songLyricist = @""; songComposer = @""; songArranger = @""; + sheetWin = nil; + pdfWin = nil; + logWin = nil; } return self; } +- (void) close +{ + [logWin close]; + [pdfWin close]; + + [super close]; +} + - (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 +{ + sheetWin = [[VLSheetWindow alloc] initWithWindowNibName: @"VLDocument"]; + [self addWindowController: sheetWin]; + [sheetWin setShouldCloseDocument:YES]; + [sheetWin release]; +} + +- (void)showWindows +{ + [sheetWin showWindow: self]; + if ([pdfWin isWindowLoaded]) + [pdfWin showWindow: self]; + if ([logWin isWindowLoaded]) + [logWin showWindow: self]; +} + - (VLSong *) song { return song; @@ -124,17 +141,6 @@ [self updateChangeCount:NSChangeDone]; } -- (NSString *)windowNibName -{ - return @"VLDocument"; -} - -- (void)windowControllerDidLoadNib:(NSWindowController *) controller -{ - [super windowControllerDidLoadNib:controller]; - [controller setShouldCloseDocument:YES]; -} - - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError { if ([typeName isEqual:@"VLNativeType"]) { @@ -163,4 +169,81 @@ } } + +- (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]; +} + @end diff --git a/Sources/VLModel.h b/Sources/VLModel.h index 14cdd35..f9a15f8 100644 --- a/Sources/VLModel.h +++ b/Sources/VLModel.h @@ -14,8 +14,8 @@ const int kVLSharpChar = 0x266F; const int kVLFlatChar = 0x266D; -const char *kVLSharpStr = "\xE2\x99\xAF"; -const char *kVLFlatStr = "\xE2\x99\xAD"; +#define kVLSharpStr "\xE2\x99\xAF" +#define kVLFlatStr "\xE2\x99\xAD" struct VLFract { uint16_t fNum; // Numerator diff --git a/Sources/VLPDFWindow.mm b/Sources/VLPDFWindow.mm index 14499c8..0402545 100644 --- a/Sources/VLPDFWindow.mm +++ b/Sources/VLPDFWindow.mm @@ -28,6 +28,11 @@ static NSString* sZoomOutToolbarItemIdentifier = @"Zoom Out Toolbar Item Identif [self reloadPDF]; } +- (IBAction)showWindow:(id)sender +{ + [super showWindow:sender]; +} + - (void)reloadPDF { if (pdfView) { @@ -37,6 +42,7 @@ static NSString* sZoomOutToolbarItemIdentifier = @"Zoom Out Toolbar Item Identif NSURL * pdfURL = [NSURL fileURLWithPath: outString]; PDFDocument * pdfDoc = [[[PDFDocument alloc] initWithURL: pdfURL] autorelease]; [(PDFView *)pdfView setDocument: pdfDoc]; + [pdfView setNeedsDisplay:YES]; } } diff --git a/Sources/VLSheetView.h b/Sources/VLSheetView.h index bd7c7dd..d7a102b 100644 --- a/Sources/VLSheetView.h +++ b/Sources/VLSheetView.h @@ -52,6 +52,8 @@ enum VLRecalc { kFirstRecalc }; +@class VLEditable; + @interface VLSheetView : NSView { VLRecalc fNeedsRecalc; char fClickMode; @@ -99,6 +101,9 @@ enum VLRecalc { - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor; +- (VLEditable *) editTarget; +- (void) setEditTarget:(VLEditable *)editable; + @end // Local Variables: diff --git a/Sources/VLSheetView.mm b/Sources/VLSheetView.mm index a45ec63..2db8842 100644 --- a/Sources/VLSheetView.mm +++ b/Sources/VLSheetView.mm @@ -102,6 +102,16 @@ static float sFlatPos[] = { return [[[self window] windowController] document]; } +- (VLEditable *) editTarget +{ + return [[[self window] windowController] editTarget]; +} + +- (void) setEditTarget:(VLEditable *)editable +{ + [[[self window] windowController] setEditTarget:editable]; +} + - (VLSong *) song { return [[self document] song]; @@ -210,7 +220,7 @@ VLMusicElement sSemi2Accidental[12][12] = { fCursorTracking = [self addTrackingRect:r owner:self userData:nil assumeInside:within]; [[self window] setAcceptsMouseMovedEvents:within]; - if (within && ![[self document] valueForKey: @"editTarget"]) + if (within && ![self editTarget]) [[self window] makeFirstResponder:self]; } @@ -390,8 +400,7 @@ VLMusicElement sSemi2Accidental[12][12] = { [self drawNotesForSystem:system]; [self drawChordsForSystem:system]; } - VLEditable * editable = [[self document] valueForKey: @"editTarget"]; - [editable highlightCursor]; + [[self editTarget] highlightCursor]; } - (IBAction) setKey:(id)sender @@ -675,13 +684,12 @@ static int8_t sSharpAcc[] = { - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { - VLEditable * editable = [[self document] valueForKey: @"editTarget"]; - return [editable validValue:[fFieldEditor stringValue]]; + return [[self editTarget] validValue:[fFieldEditor stringValue]]; } - (void)controlTextDidEndEditing:(NSNotification *)note { - VLEditable * editable = [[self document] valueForKey: @"editTarget"]; + VLEditable * editable = [self editTarget]; switch ([[[note userInfo] objectForKey:@"NSTextMovement"] intValue]) { case NSTabTextMovement: [editable moveToNext]; @@ -693,7 +701,7 @@ static int8_t sSharpAcc[] = { [editable autorelease]; editable = nil; } - [[self document] setValue:editable forKey: @"editTarget"]; + [self setEditTarget:editable]; if (editable) [fFieldEditor selectText:self]; [[self window] performSelectorOnMainThread:@selector(makeFirstResponder:) diff --git a/Sources/VLSheetViewChords.h b/Sources/VLSheetViewChords.h index 70d1e53..35efc1a 100644 --- a/Sources/VLSheetViewChords.h +++ b/Sources/VLSheetViewChords.h @@ -6,8 +6,7 @@ // Copyright 2006 __MyCompanyName__. All rights reserved. // -#import "VLDocument.h" - +#import "VLSheetWindow.h" @interface VLChordEditable : VLEditable { VLSheetView * fView; diff --git a/Sources/VLSheetViewChords.mm b/Sources/VLSheetViewChords.mm index f316463..38c2e3e 100644 --- a/Sources/VLSheetViewChords.mm +++ b/Sources/VLSheetViewChords.mm @@ -242,14 +242,13 @@ std::string NormalizeName(NSString* rawName) - (void) editChord { - VLDocument * doc= [self document]; VLEditable * e = [[VLChordEditable alloc] initWithView:self song:[self song] measure:fCursorMeasure at:fCursorAt]; - [doc setValue:e forKey:@"editTarget"]; + [self setEditTarget:e]; [fFieldEditor selectText:self]; } diff --git a/Sources/VLSheetViewNotes.mm b/Sources/VLSheetViewNotes.mm index a92ad0d..7896939 100644 --- a/Sources/VLSheetViewNotes.mm +++ b/Sources/VLSheetViewNotes.mm @@ -247,9 +247,6 @@ { const VLSong * song = [self song]; const VLProperties & prop = song->fProperties.front(); - BOOL swing= !(prop.fDivisions % 3); // In swing mode? - VLFraction swung(3, prop.fDivisions*8, true); // Which notes to swing - VLFraction swingGrid(2*swung); // Alignment of swing notes float kSystemY = [self systemY:system]; for (int m = 0; m + +@interface VLEditable : NSObject +{ +} + +- (NSString *) stringValue; +- (void) setStringValue:(NSString*)val; +- (BOOL) validValue:(NSString*)val; +- (void) moveToNext; +- (void) moveToPrev; +- (void) highlightCursor; + +@end + +@interface VLSheetWindow : NSWindowController { + VLEditable * editTarget; + + IBOutlet id runToolItem; + IBOutlet id outputToolItem; + IBOutlet id logToolItem; +} + +- (VLEditable *) editTarget; +- (void) setEditTarget:(VLEditable *)editable; + +@end diff --git a/Sources/VLSheetWindow.mm b/Sources/VLSheetWindow.mm new file mode 100644 index 0000000..cb31518 --- /dev/null +++ b/Sources/VLSheetWindow.mm @@ -0,0 +1,125 @@ +// +// LilypondInputWin.m +// Lilypond +// +// Created by Matthias Neeracher on 5/29/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "VLSheetWindow.h" +#import "VLDocument.h" + + +@implementation VLEditable + +- (NSString *) stringValue +{ + return @""; +} + +- (void) setStringValue:(NSString*)val +{ +} + +- (BOOL) validValue:(NSString*)val +{ + return YES; +} + +- (void) moveToNext +{ +} + +- (void) moveToPrev +{ +} + +- (void) highlightCursor +{ +} + +@end + +@implementation VLSheetWindow + +static NSString* sInputToolbarIdentifier = @"Vocalese Sheet Window Toolbar Identifier"; +static NSString* sOutputToolbarItemIdentifier = @"Output Toolbar Item Identifier"; +static NSString* sLogToolbarItemIdentifier = @"Log Toolbar Item Identifier"; +static NSString* sRunToolbarItemIdentifier = @"Run Toolbar Item Identifier"; + +- (id)initWithWindow:(NSWindow *)window +{ + if (self = [super initWithWindow:window]) { + editTarget = nil; + } + return self; +} + +- (VLEditable *)editTarget +{ + return editTarget; +} + +- (void)setEditTarget:(VLEditable *)editable +{ + editTarget = editable; +} + +- (void)windowDidLoad +{ + NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier: sInputToolbarIdentifier] autorelease]; + + [toolbar setAllowsUserCustomization: YES]; + [toolbar setAutosavesConfiguration: YES]; + [toolbar setDelegate: self]; + + [[self window] setToolbar: toolbar]; +} + + +- (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier: (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted { + NSToolbarItem * toolbarItem = nil; + id prototype = nil; + + if ([itemIdent isEqual: sOutputToolbarItemIdentifier]) + prototype = outputToolItem; + else if ([itemIdent isEqual: sLogToolbarItemIdentifier]) + prototype = logToolItem; + else if ([itemIdent isEqual: sRunToolbarItemIdentifier]) + prototype = runToolItem; + + if (prototype) { + toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease]; + + [toolbarItem setLabel: [prototype title]]; + [toolbarItem setPaletteLabel: [prototype alternateTitle]]; + [toolbarItem setToolTip: [prototype toolTip]]; + [toolbarItem setImage: [prototype image]]; + [toolbarItem setTarget: [prototype target]]; + [toolbarItem setAction: [prototype action]]; + } else { + toolbarItem = nil; + } + return toolbarItem; +} + +- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar { + return [NSArray arrayWithObjects: + sRunToolbarItemIdentifier, + NSToolbarFlexibleSpaceItemIdentifier, + sOutputToolbarItemIdentifier, + sLogToolbarItemIdentifier, nil]; +} + +- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar { + return [NSArray arrayWithObjects: + sRunToolbarItemIdentifier, + sOutputToolbarItemIdentifier, + sLogToolbarItemIdentifier, + NSToolbarCustomizeToolbarItemIdentifier, + NSToolbarFlexibleSpaceItemIdentifier, + NSToolbarSpaceItemIdentifier, + NSToolbarSeparatorItemIdentifier, nil]; +} + +@end diff --git a/Sources/VLXMLDocument.mm b/Sources/VLXMLDocument.mm index 2239b3d..9d5813e 100644 --- a/Sources/VLXMLDocument.mm +++ b/Sources/VLXMLDocument.mm @@ -194,8 +194,45 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB "; } } +- (NSXMLElement *) identificationElement +{ + NSXMLElement * identification = [NSXMLNode elementWithName:@"identification"]; + NSXMLElement * composer = [NSXMLNode elementWithName:@"creator" + stringValue:songComposer]; + [composer addAttribute: [NSXMLNode attributeWithName:@"type" + stringValue:@"composer"]]; + [identification addChild:composer]; + NSXMLElement * poet = [NSXMLNode elementWithName:@"creator" + stringValue:songLyricist]; + [poet addAttribute: [NSXMLNode attributeWithName:@"type" + stringValue:@"poet"]]; + [identification addChild:poet]; + + NSXMLElement * encoding = [NSXMLNode elementWithName:@"encoding"]; + [encoding addChild: + [NSXMLNode elementWithName:@"encoding-date" + stringValue: + [[NSDate date] + descriptionWithCalendarFormat:@"%Y-%m-%d" + timeZone:nil locale:nil]]]; + [encoding addChild: + [NSXMLNode elementWithName:@"software" + stringValue: [NSString stringWithFormat:@"VocalEasel %@", + [[NSBundle mainBundle] + objectForInfoDictionaryKey:@"CFBundleVersion"]]]]; + [identification addChild:encoding]; + + return identification; +} + - (NSData *)XMLDataWithError:(NSError **)outError { + NSXMLElement * work = [NSXMLNode elementWithName:@"work"]; + [work addChild: [NSXMLNode elementWithName:@"work-title" + stringValue:songTitle]]; + + NSXMLElement * identification = [self identificationElement]; + NSXMLElement * partList = [NSXMLNode elementWithName:@"part-list"]; [partList addChild: [self scorePartWithID:@"HARM" name:@"Chords"]]; [partList addChild: [self scorePartWithID:@"MELO" name:@"Melody"]]; @@ -230,8 +267,8 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB "; NSXMLElement * score = [NSXMLNode elementWithName:@"score-partwise" - children:[NSArray arrayWithObjects: - partList, chords, melody, nil] + children:[NSArray arrayWithObjects: work, identification, + partList, chords, melody, nil] attributes:[NSArray arrayWithObject: [NSXMLNode attributeWithName:@"version" stringValue:@"1.1"]]]; @@ -368,6 +405,12 @@ int8_t sStepToPitch[] = { // For now, in gross violation of MusicXML spirit, we're only reading // our own input. // + songTitle = [[doc stringForXPath:@".//work-title" error:outError] retain]; + songComposer= [[doc stringForXPath:@".//creator[@type=\"composer\"]" + error: outError] retain]; + songLyricist= [[doc stringForXPath:@".//creator[@type=\"poet\"]" + error: outError] retain]; + NSXMLElement * chords = [doc nodeForXPath:@".//part[@id=\"HARM\"]" error:outError]; NSXMLElement * melody = [doc nodeForXPath:@".//part[@id=\"MELO\"]" diff --git a/Vocalese.xcodeproj/project.pbxproj b/Vocalese.xcodeproj/project.pbxproj index 9db1099..e45010a 100644 --- a/Vocalese.xcodeproj/project.pbxproj +++ b/Vocalese.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ 9593E4E90AE0ED1F00035816 /* vocalese.icns in Resources */ = {isa = PBXBuildFile; fileRef = 9593E4E70AE0ED1F00035816 /* vocalese.icns */; }; 959408AD096922EA007CCCF8 /* TVLEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959408AC096922EA007CCCF8 /* TVLEdit.cpp */; }; 959408AE096922F7007CCCF8 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; }; + 95A1C37C0AF1D4370076597D /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95A1C37B0AF1D4370076597D /* Quartz.framework */; }; + 95A1C3860AF2ACE20076597D /* VLSheetWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */; }; 95B3E1A70960E58B000E9C0D /* Music in Resources */ = {isa = PBXBuildFile; fileRef = 95B3E1980960E58B000E9C0D /* Music */; }; 95B66658096BCA1F00FE18C9 /* VLSheetViewNotes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */; }; 95BDA15909540BF1009F9D65 /* VLSheetView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95BDA15809540BF1009F9D65 /* VLSheetView.mm */; }; @@ -44,6 +46,7 @@ 95E04DAB0AEB4886006F30A0 /* VLXMLDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */; }; 95E04DC70AEB4B57006F30A0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; }; 95E04DCE0AEB4D9B006F30A0 /* Templates in Resources */ = {isa = PBXBuildFile; fileRef = 95E04DCA0AEB4D9B006F30A0 /* Templates */; }; + 95ECE6590AF3324300FE3E98 /* lilyWrapper in Resources */ = {isa = PBXBuildFile; fileRef = 95ECE6580AF3324300FE3E98 /* lilyWrapper */; }; 95F5F50F0ADCC433003980B2 /* VLXMLDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */; }; 95F5F5340ADCCFBB003980B2 /* DTD in Resources */ = {isa = PBXBuildFile; fileRef = 95F5F51E0ADCCFBB003980B2 /* DTD */; }; 95FC668F0AF0A08C003D9C11 /* VLLogWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95FC668E0AF0A08C003D9C11 /* VLLogWindow.mm */; }; @@ -99,6 +102,9 @@ 9593E4E70AE0ED1F00035816 /* vocalese.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = vocalese.icns; path = Resources/vocalese.icns; sourceTree = ""; }; 959408A0096922CA007CCCF8 /* TVLEdit */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLEdit; sourceTree = BUILT_PRODUCTS_DIR; }; 959408AC096922EA007CCCF8 /* TVLEdit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TVLEdit.cpp; path = Tests/TVLEdit.cpp; sourceTree = ""; }; + 95A1C37B0AF1D4370076597D /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = /System/Library/Frameworks/Quartz.framework; sourceTree = ""; }; + 95A1C3840AF2ACE20076597D /* VLSheetWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSheetWindow.h; path = Sources/VLSheetWindow.h; sourceTree = ""; }; + 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLSheetWindow.mm; path = Sources/VLSheetWindow.mm; sourceTree = ""; }; 95B3E1980960E58B000E9C0D /* Music */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Music; path = Resources/Music; sourceTree = ""; }; 95B66653096BC6A100FE18C9 /* VLSheetViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSheetViewInternal.h; path = Sources/VLSheetViewInternal.h; sourceTree = ""; }; 95B66656096BCA1F00FE18C9 /* VLSheetViewNotes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLSheetViewNotes.h; path = Sources/VLSheetViewNotes.h; sourceTree = ""; }; @@ -108,6 +114,7 @@ 95E04DA00AEB4837006F30A0 /* TVLLilypond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLLilypond; sourceTree = BUILT_PRODUCTS_DIR; }; 95E04DA60AEB486E006F30A0 /* TVLLilypond.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = TVLLilypond.mm; path = Tests/TVLLilypond.mm; sourceTree = ""; }; 95E04DCA0AEB4D9B006F30A0 /* Templates */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Templates; path = Resources/Templates; sourceTree = ""; }; + 95ECE6580AF3324300FE3E98 /* lilyWrapper */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; name = lilyWrapper; path = Resources/lilyWrapper; sourceTree = ""; }; 95F5F50D0ADCC433003980B2 /* VLXMLDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLXMLDocument.h; path = Sources/VLXMLDocument.h; sourceTree = ""; }; 95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLXMLDocument.mm; path = Sources/VLXMLDocument.mm; sourceTree = ""; }; 95F5F51E0ADCCFBB003980B2 /* DTD */ = {isa = PBXFileReference; lastKnownFileType = folder; name = DTD; path = Resources/DTD; sourceTree = ""; }; @@ -136,6 +143,7 @@ 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */, 95932B91096527700008B0DB /* AudioUnit.framework in Frameworks */, 95932B92096527710008B0DB /* AudioToolbox.framework in Frameworks */, + 95A1C37C0AF1D4370076597D /* Quartz.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -176,6 +184,7 @@ 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( + 95A1C37B0AF1D4370076597D /* Quartz.framework */, 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */, 952CBBB2095FD34F00434E43 /* AudioToolbox.framework */, 952CBBB3095FD34F00434E43 /* AudioUnit.framework */, @@ -221,6 +230,8 @@ 2A37F4ABFDCFA73011CA2CEA /* Classes */ = { isa = PBXGroup; children = ( + 95A1C3840AF2ACE20076597D /* VLSheetWindow.h */, + 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */, 95FC66CC0AF0A591003D9C11 /* VLPDFView.mm */, 95FC66CD0AF0A591003D9C11 /* VLPDFView.h */, 95FC66A40AF0A24C003D9C11 /* VLPDFWindow.h */, @@ -266,6 +277,7 @@ 2A37F4B8FDCFA73011CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 95ECE6580AF3324300FE3E98 /* lilyWrapper */, 95FC66BC0AF0A4D4003D9C11 /* console.icns */, 95FC66BD0AF0A4D4003D9C11 /* music.tiff */, 95FC66BE0AF0A4D4003D9C11 /* nextpage.tiff */, @@ -439,6 +451,7 @@ 95FC66C70AF0A4D5003D9C11 /* run.icns in Resources */, 95FC66C80AF0A4D5003D9C11 /* zoomin.tiff in Resources */, 95FC66C90AF0A4D5003D9C11 /* zoomout.tiff in Resources */, + 95ECE6590AF3324300FE3E98 /* lilyWrapper in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -464,6 +477,7 @@ 95FC668F0AF0A08C003D9C11 /* VLLogWindow.mm in Sources */, 95FC66A60AF0A24C003D9C11 /* VLPDFWindow.mm in Sources */, 95FC66CE0AF0A591003D9C11 /* VLPDFView.mm in Sources */, + 95A1C3860AF2ACE20076597D /* VLSheetWindow.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };