VocalEasel/Sources/VLPListDocument.mm

227 lines
6.9 KiB
Plaintext
Raw Normal View History

2007-08-12 19:40:44 +00:00
//
// File: VLPListDocument.h - Convert document from and to Cocoa plist
//
// Author(s):
//
// (MN) Matthias Neeracher
//
// Copyright © 2007 Matthias Neeracher
//
#import "VLPListDocument.h"
2007-08-12 20:45:25 +00:00
#import "VLModel.h"
2007-08-12 19:40:44 +00:00
//
// To convert from and to complex file formats, we use ruby scripts operating
// on the XML representation of a Cocoa property list. The property list
// representation is strictly intended as an intermediate representation,
// subject to change as necessary.
//
@implementation VLDocument (Plist)
class VLPlistVisitor : public VLSongVisitor {
public:
2007-08-12 20:45:25 +00:00
VLPlistVisitor(NSMutableDictionary * plist, bool performanceOrder)
2007-08-12 19:40:44 +00:00
: fPlist(plist), fPerfOrder(performanceOrder) {}
virtual void Visit(VLSong & song);
protected:
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas);
virtual void VisitNote(VLLyricsNote & n);
virtual void VisitChord(VLChord & c);
2007-08-12 20:45:25 +00:00
NSArray * EncodeProperties(const std::vector<VLProperties> & properties);
NSDictionary * EncodeProperties(const VLProperties & properties);
NSArray * EncodeRepeats(const std::vector<VLRepeat> & repeats);
NSDictionary * EncodeRepeat(const VLRepeat & repeat);
NSMutableDictionary * fPlist;
NSMutableArray * fMeasures;
NSMutableArray * fNotes;
NSMutableArray * fChords;
bool fPerfOrder;
const VLSong * fSong;
2007-08-12 19:40:44 +00:00
};
2007-08-12 20:45:25 +00:00
NSArray * VLPlistVisitor::EncodeProperties(const std::vector<VLProperties> & properties)
{
NSMutableArray * pa = [NSMutableArray arrayWithCapacity:properties.size()];
for (std::vector<VLProperties>::const_iterator i = properties.begin();
i != properties.end(); ++i)
[pa addObject:EncodeProperties(*i)];
return pa;
}
NSDictionary * VLPlistVisitor::EncodeProperties(const VLProperties & properties)
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: properties.fTime.fNum], @"timeNum",
[NSNumber numberWithInt: properties.fTime.fDenom], @"timeDenom",
[NSNumber numberWithInt: properties.fKey], @"key",
[NSNumber numberWithInt: properties.fMode], @"mode",
2007-08-12 21:30:40 +00:00
[NSNumber numberWithInt: properties.fDivisions], @"divisions",
nil];
2007-08-12 20:45:25 +00:00
}
NSArray * VLPlistVisitor::EncodeRepeats(const std::vector<VLRepeat> & repeats)
{
NSMutableArray * ra = [NSMutableArray arrayWithCapacity:repeats.size()];
for (std::vector<VLRepeat>::const_iterator i = repeats.begin();
i != repeats.end(); ++i)
[ra addObject:EncodeRepeat(*i)];
return ra;
}
NSDictionary * VLPlistVisitor::EncodeRepeat(const VLRepeat & repeat)
{
NSMutableArray * ea = [NSMutableArray arrayWithCapacity:repeat.fEndings.size()];
for (std::vector<VLRepeat::Ending>::const_iterator i = repeat.fEndings.begin();
i != repeat.fEndings.end(); ++i)
[ea addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: i->fBegin], @"begin",
[NSNumber numberWithInt: i->fEnd], @"end",
2007-08-12 21:30:40 +00:00
[NSNumber numberWithInt: i->fVolta], @"volta",
nil]];
2007-08-12 20:45:25 +00:00
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: repeat.fTimes], @"times",
2007-08-12 21:30:40 +00:00
ea, @"endings",
nil];
2007-08-12 20:45:25 +00:00
}
2007-08-12 19:40:44 +00:00
void VLPlistVisitor::Visit(VLSong & song)
{
fSong = &song;
fMeasures = [NSMutableArray arrayWithCapacity:32];
VisitMeasures(song, fPerfOrder);
[fPlist setObject:EncodeProperties(song.fProperties) forKey:@"properties"];
[fPlist setObject:EncodeRepeats(song.fRepeats) forKey:@"repeats"];
[fPlist setObject:fMeasures forKey:@"measures"];
}
void VLPlistVisitor::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
{
fNotes = [NSMutableArray arrayWithCapacity:1];
fChords= [NSMutableArray arrayWithCapacity:1];
VisitNotes(meas, p, true);
VisitChords(meas);
NSDictionary * md =
2007-08-12 20:45:25 +00:00
[NSDictionary dictionaryWithObjectsAndKeys:
2007-08-12 19:40:44 +00:00
[NSNumber numberWithInt:m], @"measure",
[NSNumber numberWithInt:meas.fPropIdx], @"properties",
2007-08-12 21:30:40 +00:00
fNotes, @"melody", fChords, @"chords",
nil];
2007-08-12 19:40:44 +00:00
[fMeasures addObject:md];
}
void VLPlistVisitor::VisitNote(VLLyricsNote & n)
{
2007-08-18 23:17:27 +00:00
NSMutableArray * ly = [NSMutableArray arrayWithCapacity:0];
for (size_t i = 0; i<n.fLyrics.size(); ++i)
[ly addObject:n.fLyrics[i].fText.size()
? [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithUTF8String:n.fLyrics[i].fText.c_str()], @"text",
[NSNumber numberWithInt:n.fLyrics[i].fKind], @"kind",
nil]
: [NSDictionary dictionary]];
2007-08-12 19:40:44 +00:00
NSDictionary * nd =
2007-08-12 20:45:25 +00:00
[NSDictionary dictionaryWithObjectsAndKeys:
2007-08-12 19:40:44 +00:00
[NSNumber numberWithInt:n.fDuration.fNum], @"durNum",
[NSNumber numberWithInt:n.fDuration.fDenom], @"durDenom",
[NSNumber numberWithInt:n.fPitch], @"pitch",
[NSNumber numberWithInt:n.fTied], @"tied",
2007-08-12 21:30:40 +00:00
[NSNumber numberWithInt:n.fVisual], @"visual",
2007-08-18 23:17:27 +00:00
ly, @"lyrics",
2007-08-12 21:30:40 +00:00
nil];
2007-08-12 19:40:44 +00:00
[fNotes addObject:nd];
}
void VLPlistVisitor::VisitChord(VLChord & c)
{
NSDictionary * cd =
2007-08-12 20:45:25 +00:00
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:c.fDuration.fNum], @"durNum",
[NSNumber numberWithInt:c.fDuration.fDenom], @"durDenom",
[NSNumber numberWithInt:c.fPitch], @"pitch",
[NSNumber numberWithInt:c.fSteps], @"steps",
2007-08-12 21:30:40 +00:00
[NSNumber numberWithInt:c.fRootPitch], @"root",
nil];
2007-08-12 19:40:44 +00:00
[fChords addObject: cd];
}
- (id)plistInPerformanceOrder:(BOOL)performanceOrder
{
NSMutableDictionary * plist =
[NSMutableDictionary dictionaryWithCapacity:20];
2007-08-19 21:09:25 +00:00
[plist setObject:songTitle forKey:@"title"];
[plist setObject:songGroove forKey:@"groove"];
[plist setObject:songTempo forKey:@"tempo"];
2007-08-12 19:40:44 +00:00
[plist setObject:songComposer forKey:@"composer"];
[plist setObject:songLyricist forKey:@"lyricist"];
2007-08-18 23:17:27 +00:00
[plist setObject:[NSDate date] forKey:@"saved"];
2007-08-12 19:40:44 +00:00
[plist setObject:
[NSString stringWithFormat:@"VocalEasel %@",
[[NSBundle mainBundle]
objectForInfoDictionaryKey:@"CFBundleVersion"]]
forKey:@"software"];
VLPlistVisitor songWriter(plist, performanceOrder);
songWriter.Visit(*song);
return plist;
}
2007-08-12 21:30:40 +00:00
- (IBAction)dump:(id)sender
2007-08-18 23:17:27 +00:00
{
id plist = [self plistInPerformanceOrder:NO];
if ([sender tag])
plist = [[[NSString alloc] initWithData:
[NSPropertyListSerialization dataFromPropertyList:plist format:NSPropertyListXMLFormat_v1_0 errorDescription:nil]
encoding:NSUTF8StringEncoding] autorelease];
NSLog(@"%@\n", plist);
2007-08-12 21:30:40 +00:00
}
2007-08-12 19:40:44 +00:00
- (BOOL)readFromPlist:(id)plist error:(NSError **)outError
{
2007-08-12 20:45:25 +00:00
return NO;
2007-08-12 19:40:44 +00:00
}
2007-08-12 20:45:25 +00:00
- (NSData *)runFilter:(NSString *)filterName withContents:(NSData *)contents
2007-08-12 19:40:44 +00:00
{
2007-08-12 20:45:25 +00:00
return nil;
2007-08-12 19:40:44 +00:00
}
- (NSFileWrapper *)fileWrapperWithFilter:(NSString *)filterName
error:(NSError **)outError
{
NSBundle * mainBundle = [NSBundle mainBundle];
BOOL perfOrder = [mainBundle pathForResource:filterName
2007-08-12 20:45:25 +00:00
ofType:@"pwriter" inDirectory:@"Filters"] != nil;
2007-08-12 19:40:44 +00:00
filterName = [filterName stringByAppendingPathExtension:
perfOrder ? @"pwriter" : @"writer"];
NSData * inData = [self plistInPerformanceOrder:perfOrder];
NSData * outData= [self runFilter:filterName withContents:inData];
return [[[NSFileWrapper alloc] initRegularFileWithContents:outData]
autorelease];
}
- (BOOL)readFromFileWrapper:(NSFileWrapper *)wrapper
withFilter:(NSString *)filterName
error:(NSError **)outError
{
2007-08-12 20:45:25 +00:00
return NO;
2007-08-12 19:40:44 +00:00
}
@end