diff --git a/English.lproj/VLDocument.nib/classes.nib b/English.lproj/VLDocument.nib/classes.nib index 9be966e..63e5f46 100644 --- a/English.lproj/VLDocument.nib/classes.nib +++ b/English.lproj/VLDocument.nib/classes.nib @@ -31,6 +31,7 @@ ACTIONS = { endRepeatSheet = id; hideFieldEditor = id; + selectGroove = id; setDivisions = id; setKey = id; setTime = id; @@ -41,6 +42,7 @@ fEndingMsg = id; fEndingSheet = id; fFieldEditor = id; + fGrooveMenu = id; fRepeatMsg = id; fRepeatSheet = id; }; diff --git a/English.lproj/VLDocument.nib/info.nib b/English.lproj/VLDocument.nib/info.nib index 5be6fa2..b5503af 100644 --- a/English.lproj/VLDocument.nib/info.nib +++ b/English.lproj/VLDocument.nib/info.nib @@ -1,17 +1,19 @@ - + IBDocumentLocation 427 29 356 240 0 0 1280 778 IBFramework Version - 454.0 + 460.0 IBOpenObjects 5 144 + 196 + 216 IBSystem Version - 9A321 + 9A412 diff --git a/English.lproj/VLDocument.nib/keyedobjects.nib b/English.lproj/VLDocument.nib/keyedobjects.nib index 1f58fe1..3318d61 100644 Binary files a/English.lproj/VLDocument.nib/keyedobjects.nib and b/English.lproj/VLDocument.nib/keyedobjects.nib differ diff --git a/English.lproj/VLGroove.nib/classes.nib b/English.lproj/VLGroove.nib/classes.nib new file mode 100644 index 0000000..917f133 --- /dev/null +++ b/English.lproj/VLGroove.nib/classes.nib @@ -0,0 +1,13 @@ +{ + IBClasses = ( + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + ACTIONS = {endSheet = id; updateDescription = id; }; + CLASS = VLGrooveController; + LANGUAGE = ObjC; + OUTLETS = {fBrowser = NSBrowser; fDescription = NSTextField; fOKButton = NSButton; }; + SUPERCLASS = NSWindowController; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/English.lproj/VLGroove.nib/info.nib b/English.lproj/VLGroove.nib/info.nib new file mode 100644 index 0000000..b053b83 --- /dev/null +++ b/English.lproj/VLGroove.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBDocumentLocation + 59 9 356 240 0 0 1280 778 + IBFramework Version + 460.0 + IBOpenObjects + + 13 + + IBSystem Version + 9A412 + + diff --git a/English.lproj/VLGroove.nib/keyedobjects.nib b/English.lproj/VLGroove.nib/keyedobjects.nib new file mode 100644 index 0000000..2fd578f Binary files /dev/null and b/English.lproj/VLGroove.nib/keyedobjects.nib differ diff --git a/Sources/VLGrooveController.h b/Sources/VLGrooveController.h new file mode 100644 index 0000000..779d7a4 --- /dev/null +++ b/Sources/VLGrooveController.h @@ -0,0 +1,32 @@ +// +// VLGrooveController.h +// Vocalese +// +// Created by Matthias Neeracher on 2/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import + +@class VLSheetView; + +@interface VLGrooveController : NSWindowController { + NSDictionary * fGrooves; + IBOutlet NSBrowser * fBrowser; + IBOutlet NSTextField * fDescription; + IBOutlet NSButton * fOKButton; + NSString * fStyle; + NSDictionary * fSubStyles; + NSArray * fSubStyleList; + NSPredicate * fSubStyleFilter; +} + +- (id) initWithSheetView:(VLSheetView *)view; +- (IBAction)endSheet:(id)sender; +- (IBAction)updateDescription:(id)sender; + +@end + +// Local Variables: +// mode:ObjC +// End: diff --git a/Sources/VLGrooveController.mm b/Sources/VLGrooveController.mm new file mode 100644 index 0000000..de3be91 --- /dev/null +++ b/Sources/VLGrooveController.mm @@ -0,0 +1,111 @@ +// +// VLGrooveController.mm +// Vocalese +// +// Created by Matthias Neeracher on 2/1/07. +// Copyright 2007 __MyCompanyName__. All rights reserved. +// + +#import "VLGrooveController.h" +#import "VLSheetView.h" + +@implementation VLGrooveController + +- (id) initWithSheetView:(VLSheetView *)view; +{ + self = [super initWithWindowNibName:@"VLGroove"]; + fGrooves = [[NSDictionary alloc] initWithContentsOfFile: + [[NSBundle mainBundle] pathForResource:@"Grooves" ofType:@"plist"]]; + fSubStyleFilter = + [[NSPredicate predicateWithFormat: + @"!(SELF like[c] '.DESC') AND !(SELF matches[c] '.*(Intro|End)\\\\d*$')"] + retain]; + + [NSApp beginSheet: [self window] + modalForWindow: [view window] + modalDelegate: self + didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) + contextInfo: view]; + + return self; +} + +- (void) dealloc +{ + [fGrooves release]; + [super dealloc]; +} + +- (IBAction)endSheet:(id)sender +{ + [NSApp endSheet:[self window] returnCode:[sender tag]]; +} + +- (void)didEndSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + if (returnCode == NSAlertFirstButtonReturn) + [(VLSheetView *)contextInfo setGroove:[[fBrowser selectedCellInColumn:1] stringValue]]; + + [[self window] orderOut:self]; +} + +- (NSString *)browser:(NSBrowser *)sender titleOfColumn:(NSInteger)column +{ + if (!column) + return @"Style"; + else + return @"Substyle"; +} + +- (void)updateStyle +{ + [fStyle autorelease]; + [fSubStyleList release]; + fStyle = [[[fBrowser selectedCellInColumn:0] stringValue] retain]; + fSubStyles = [fGrooves objectForKey:fStyle]; + fSubStyleList = [[[fSubStyles allKeys] + filteredArrayUsingPredicate:fSubStyleFilter] + retain]; +} + +- (NSInteger)browser:(NSBrowser *)sender numberOfRowsInColumn:(NSInteger)column +{ + [fBrowser setTakesTitleFromPreviousColumn:NO]; + [fBrowser setDoubleAction:@selector(endSheet:)]; + + if (!column) { + return [fGrooves count]; + } else { + [self updateStyle]; + return [fSubStyleList count]; + } +} + +- (void)browser:(NSBrowser *)sender willDisplayCell:(id)cell atRow:(NSInteger)row column:(NSInteger)column +{ + if (!column) { + [cell setStringValue: + [[[fGrooves allKeys] + sortedArrayUsingSelector:@selector(compare:)] + objectAtIndex:row]]; + } else { + [cell setStringValue:[fSubStyleList objectAtIndex:row]]; + [cell setLeaf:YES]; + } +} + +- (IBAction)updateDescription:(id)sender +{ + BOOL validStyle = [fBrowser selectedColumn]; + [fOKButton setEnabled:validStyle]; + if (validStyle) + [fDescription setStringValue: + [NSString stringWithFormat:@"%@\n\n%@", + [fSubStyles objectForKey:@".DESC"], + [fSubStyles objectForKey: + [[fBrowser selectedCellInColumn:1] stringValue]]]]; + else + [fDescription setStringValue:[fSubStyles objectForKey:@".DESC"]]; +} + +@end diff --git a/Sources/VLSheetView.h b/Sources/VLSheetView.h index 75d34e8..b256187 100644 --- a/Sources/VLSheetView.h +++ b/Sources/VLSheetView.h @@ -87,6 +87,7 @@ enum VLRecalc { IBOutlet id fEndingSheet; IBOutlet id fRepeatMsg; IBOutlet id fEndingMsg; + IBOutlet id fGrooveMenu; } - (IBAction) setKey:(id)sender; @@ -94,6 +95,7 @@ enum VLRecalc { - (IBAction) setDivisions:(id)sender; - (IBAction) hideFieldEditor:(id)sender; - (IBAction) endRepeatSheet:(id)sender; +- (IBAction) selectGroove:(id)sender; - (VLDocument *) document; - (VLSong *) song; @@ -118,6 +120,8 @@ enum VLRecalc { - (void) setEditTarget:(VLEditable *)editable; - (VLRegion) findRegionForEvent:(NSEvent *) event; +- (void) setGroove:(NSString *)groove; + @end // Local Variables: diff --git a/Sources/VLSheetView.mm b/Sources/VLSheetView.mm index 75e016a..8d1f0a5 100644 --- a/Sources/VLSheetView.mm +++ b/Sources/VLSheetView.mm @@ -13,6 +13,7 @@ #import "VLSheetViewLyrics.h" #import "VLSheetViewSelection.h" #import "VLSoundOut.h" +#import "VLGrooveController.h" #import "VLDocument.h" @@ -521,6 +522,17 @@ VLMusicElement sSemi2Accidental[12][12] = { [[self editTarget] highlightCursor]; } +- (void)setKey:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(id)sender +{ + if (returnCode == NSAlertAlternateReturn) + return; + + int key = [[sender selectedItem] tag]; + [[self document] setKey:key transpose:returnCode==NSAlertDefaultReturn]; + fNeedsRecalc = kRecalc; + [self setNeedsDisplay: YES]; +} + - (IBAction) setKey:(id)sender { if ([self song]->IsNonEmpty()) @@ -538,17 +550,6 @@ VLMusicElement sSemi2Accidental[12][12] = { [self setKey:nil returnCode:NSAlertOtherReturn contextInfo:sender]; } -- (void)setKey:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(id)sender -{ - if (returnCode == NSAlertAlternateReturn) - return; - - int key = [[sender selectedItem] tag]; - [[self document] setKey:key transpose:returnCode==NSAlertDefaultReturn]; - fNeedsRecalc = kRecalc; - [self setNeedsDisplay: YES]; -} - - (IBAction) setTime:(id)sender { int time = [[sender selectedItem] tag]; @@ -892,6 +893,7 @@ static int8_t sSharpAcc[] = { { [[self document] addObserver:self forKeyPath:@"song" options:0 context:nil]; [[self document] addObserver:self forKeyPath:@"songKey" options:0 context:nil]; + [self setGroove:[[self document] valueForKey:@"songGroove"]]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)o change:(NSDictionary *)c context:(id)ctx @@ -906,4 +908,28 @@ static int8_t sSharpAcc[] = { [NSApp endSheet:[sender window] returnCode:[sender tag]]; } +- (IBAction)selectGroove:(id)sender +{ + if ([sender tag]) + [[VLGrooveController alloc] initWithSheetView:self]; + else + [self setGroove:[sender title]]; +} + +- (void)setGroove:(NSString *)groove +{ + [[self document] setValue:groove forKey:@"songGroove"]; + int removeIndex = [fGrooveMenu indexOfItemWithTitle:groove]; + if (removeIndex < 0 && [fGrooveMenu numberOfItems] > 11) + removeIndex = 11; + if (removeIndex >= 0) + [fGrooveMenu removeItemAtIndex:removeIndex]; + [[[fGrooveMenu menu] insertItemWithTitle:groove action:@selector(selectGroove:) + keyEquivalent:@"" atIndex:2] setTarget:self]; + [fGrooveMenu selectItemAtIndex:2]; + NSArray * grooves = [fGrooveMenu itemTitles]; + grooves = [grooves subarrayWithRange:NSMakeRange(2, [grooves count]-2)]; + [[NSUserDefaults standardUserDefaults] setObject:grooves forKey:@"VLGrooves"]; +} + @end diff --git a/Sources/VLXMLDocument.mm b/Sources/VLXMLDocument.mm index d67999d..6865230 100644 --- a/Sources/VLXMLDocument.mm +++ b/Sources/VLXMLDocument.mm @@ -260,6 +260,14 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB "; objectForInfoDictionaryKey:@"CFBundleVersion"]]]]; [identification addChild:encoding]; + NSXMLElement * misc = [NSXMLNode elementWithName:@"miscellaneous"]; + NSXMLElement * groove = [NSXMLNode elementWithName:@"miscellaneous-field" + stringValue:songGroove]; + [groove addAttribute: [NSXMLNode attributeWithName:@"name" + stringValue:@"VocalEasel-groove"]]; + [misc addChild: groove]; + [identification addChild: misc]; + return identification; } @@ -674,6 +682,12 @@ int8_t sStepToPitch[] = { error: outError] retain]; songLyricist= [[doc stringForXPath:@".//creator[@type=\"poet\"]" error: outError] retain]; + id groove = [doc stringForXPath:@".//miscellaneous-field[@name=\"VocalEasel-groove\"]" + error: outError]; + if (groove) { + [songGroove autorelease]; + songGroove = [groove retain]; + } NSXMLElement * chords = [doc nodeForXPath:@".//part[@id=\"HARM\"]" error:outError]; diff --git a/Tools/rebuildGrooves b/Tools/rebuildGrooves new file mode 100755 index 0000000..904f2ae --- /dev/null +++ b/Tools/rebuildGrooves @@ -0,0 +1,83 @@ +#!/usr/bin/ruby +# +# rebuildGrooves +# Vocalese +# +# Created by Matthias Neeracher on 2/5/07. +# Copyright (c) 2007 __MyCompanyName__. All rights reserved. +# + +require 'find' + +grooves = {} +Find.find(ARGV[0]) do |f| + if File.directory?(f) + Find.prune if File.exist?("f/MMAIGNORE") + elsif f =~ %r|.*/(\S+?).mma$| + style = $1 + g = {} + doc = "" + groove= "" + File.open(f) do |file| + inDoc = false + inCont= false + file.each do |line| + if line =~ /^\s*Begin\s+Doc\s*$/ + inDoc = true + elsif inDoc + if line =~ /^\s*End\s*$/ + inDoc = false + else + doc = doc+" "+line.strip + end + elsif line =~ /^\s*DefGroove\s+(\S+)\s+(.+?)\s*$/ + groove = $1 + gdoc = $2 + if gdoc =~ /(.*?)\s+\\\s*$/ + gdoc = $1 + inCont = true + end + g[groove] = gdoc + elsif inCont + if line =~ /^\s*(.*?)\s*(\\)?\s*$/ + g[groove] = g[groove] + " " + $1 + inCont = $2 != nil + else + inCont = false + end + end + end + end + unless g.empty? + g[".DESC"] = doc.lstrip + grooves[style] = g + end + end +end + +OUT = File.new(ARGV[1], "w") + +OUT.print <<'END_HEADER' + + + + +END_HEADER + +def xmlesc(s) + s.gsub('&', '&').gsub('<', '<').gsub('>', '&rt;') +end + +grooves.each do |style,grooves| + OUT.puts "\t#{xmlesc(style)}" + OUT.puts "\t" + grooves.each do |name,desc| + OUT.puts "\t\t#{xmlesc(name)}" + OUT.puts "\t\t#{xmlesc(desc)}" + end + OUT.puts "\t" +end + +OUT.puts "" +OUT.puts "" + diff --git a/Vocalese.xcodeproj/project.pbxproj b/Vocalese.xcodeproj/project.pbxproj index 76d0110..32cc674 100644 --- a/Vocalese.xcodeproj/project.pbxproj +++ b/Vocalese.xcodeproj/project.pbxproj @@ -46,6 +46,9 @@ 959408AE096922F7007CCCF8 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; }; 959420EB0B44E769006BC62C /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 954DD4DA0B44E6000056C504 /* MainMenu.nib */; }; 959420EC0B44E77A006BC62C /* VLDocument.nib in Resources */ = {isa = PBXBuildFile; fileRef = 954DD4DF0B44E61E0056C504 /* VLDocument.nib */; }; + 9599ED960B73185800A6A2F7 /* VLGroove.nib in Resources */ = {isa = PBXBuildFile; fileRef = 9599ED940B73185800A6A2F7 /* VLGroove.nib */; }; + 9599ED9C0B731CC500A6A2F7 /* VLGrooveController.h in Copy MMA Library */ = {isa = PBXBuildFile; fileRef = 9599ED9A0B731CC500A6A2F7 /* VLGrooveController.h */; }; + 9599ED9D0B731CC500A6A2F7 /* VLGrooveController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9599ED9B0B731CC500A6A2F7 /* VLGrooveController.mm */; }; 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 */; }; @@ -57,6 +60,7 @@ 95C461FE0B04432700649F92 /* MMA in Copy MMA Library */ = {isa = PBXBuildFile; fileRef = 95C461DD0B04430F00649F92 /* MMA */; }; 95C462000B04472E00649F92 /* mmaWrapper in Copy Tools */ = {isa = PBXBuildFile; fileRef = 95C461FF0B04472900649F92 /* mmaWrapper */; }; 95C462830B045CB700649F92 /* lilyWrapper in Copy Tools */ = {isa = PBXBuildFile; fileRef = 95C4627A0B045C8E00649F92 /* lilyWrapper */; }; + 95D0C2FC0B785D020061080E /* rebuildGrooves in Copy Tools */ = {isa = PBXBuildFile; fileRef = 95D0C2FB0B785D020061080E /* rebuildGrooves */; }; 95E04DA70AEB486E006F30A0 /* TVLLilypond.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95E04DA60AEB486E006F30A0 /* TVLLilypond.mm */; }; 95E04DA80AEB4878006F30A0 /* VLDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* VLDocument.mm */; }; 95E04DA90AEB487A006F30A0 /* VLLilypondDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953722660AE9F0E100B6E483 /* VLLilypondDocument.mm */; }; @@ -93,6 +97,7 @@ 95C461FE0B04432700649F92 /* MMA in Copy MMA Library */, 95C461C40B043E8900649F92 /* includes in Copy MMA Library */, 95C461C50B043E8900649F92 /* lib in Copy MMA Library */, + 9599ED9C0B731CC500A6A2F7 /* VLGrooveController.h in Copy MMA Library */, ); name = "Copy MMA Library"; runOnlyForDeploymentPostprocessing = 0; @@ -103,6 +108,7 @@ dstPath = bin; dstSubfolderSpec = 7; files = ( + 95D0C2FC0B785D020061080E /* rebuildGrooves in Copy Tools */, 95C462830B045CB700649F92 /* lilyWrapper in Copy Tools */, 95C462000B04472E00649F92 /* mmaWrapper in Copy Tools */, 95C461D80B0440A300649F92 /* mma.py in Copy Tools */, @@ -167,6 +173,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 = ""; }; + 9599ED950B73185800A6A2F7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/VLGroove.nib; sourceTree = ""; }; + 9599ED9A0B731CC500A6A2F7 /* VLGrooveController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLGrooveController.h; path = Sources/VLGrooveController.h; sourceTree = ""; }; + 9599ED9B0B731CC500A6A2F7 /* VLGrooveController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLGrooveController.mm; path = Sources/VLGrooveController.mm; 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 = ""; }; @@ -182,6 +191,7 @@ 95C461DD0B04430F00649F92 /* MMA */ = {isa = PBXFileReference; lastKnownFileType = folder; name = MMA; path = mma/MMA; sourceTree = ""; }; 95C461FF0B04472900649F92 /* mmaWrapper */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; name = mmaWrapper; path = Tools/mmaWrapper; sourceTree = ""; }; 95C4627A0B045C8E00649F92 /* lilyWrapper */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; name = lilyWrapper; path = Tools/lilyWrapper; sourceTree = ""; }; + 95D0C2FB0B785D020061080E /* rebuildGrooves */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; name = rebuildGrooves; path = Tools/rebuildGrooves; sourceTree = ""; }; 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 = ""; }; @@ -352,6 +362,8 @@ 955CBA4D0B2366DD001CF4A1 /* VLKeyValueUndo.mm */, 954DD4B70B444B220056C504 /* VLSheetViewSelection.h */, 954DD4E50B44E67F0056C504 /* VLSheetViewSelection.mm */, + 9599ED9A0B731CC500A6A2F7 /* VLGrooveController.h */, + 9599ED9B0B731CC500A6A2F7 /* VLGrooveController.mm */, ); name = Classes; sourceTree = ""; @@ -388,6 +400,7 @@ 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */, 8D15AC360486D014006FF6A4 /* Info.plist */, 089C165FFE840EACC02AAC07 /* InfoPlist.strings */, + 9599ED940B73185800A6A2F7 /* VLGroove.nib */, ); name = Resources; sourceTree = ""; @@ -435,6 +448,7 @@ 95C4627A0B045C8E00649F92 /* lilyWrapper */, 95C461FF0B04472900649F92 /* mmaWrapper */, 95C461D50B04406300649F92 /* mma.py */, + 95D0C2FB0B785D020061080E /* rebuildGrooves */, ); name = Tools; sourceTree = ""; @@ -583,6 +597,7 @@ 959420EB0B44E769006BC62C /* MainMenu.nib in Resources */, 959420EC0B44E77A006BC62C /* VLDocument.nib in Resources */, 950795E10B4A34D9008911A6 /* stop.tiff in Resources */, + 9599ED960B73185800A6A2F7 /* VLGroove.nib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -600,7 +615,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "$BUILT_PRODUCTS_DIR/VocalEasel.app/Contents/Resources/bin/mmaWrapper -g\n"; + shellScript = "$BUILT_PRODUCTS_DIR/VocalEasel.app/Contents/Resources/bin/mmaWrapper -g\n$SRCROOT/Tools/rebuildGrooves $BUILT_PRODUCTS_DIR/VocalEasel.app/Contents/Resources/share/mma/lib $BUILT_PRODUCTS_DIR/VocalEasel.app/Contents/Resources/Grooves.plist\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -634,6 +649,7 @@ 95E299C00B2006F5001977D2 /* VLSheetViewLyrics.mm in Sources */, 955CBA4F0B2366DD001CF4A1 /* VLKeyValueUndo.mm in Sources */, 954DD4E60B44E67F0056C504 /* VLSheetViewSelection.mm in Sources */, + 9599ED9D0B731CC500A6A2F7 /* VLGrooveController.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -700,6 +716,14 @@ name = Credits.rtf; sourceTree = ""; }; + 9599ED940B73185800A6A2F7 /* VLGroove.nib */ = { + isa = PBXVariantGroup; + children = ( + 9599ED950B73185800A6A2F7 /* English */, + ); + name = VLGroove.nib; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */