2006-09-11 02:49:56 +00:00
//
2007-04-27 06:41:34 +00:00
// File: VLDocument.mm - VocalEasel document
2006-09-11 02:49:56 +00:00
//
2007-04-27 06:41:34 +00:00
// Author(s):
//
// (MN) Matthias Neeracher
//
2011-07-24 03:32:13 +00:00
// Copyright © 2005-2011 Matthias Neeracher
2006-09-11 02:49:56 +00:00
//
#import "VLDocument.h"
2006-10-22 07:16:29 +00:00
#import "VLXMLDocument.h"
#import "VLLilypondDocument.h"
2006-11-04 08:15:34 +00:00
#import "VLMMADocument.h"
2006-11-12 11:37:36 +00:00
#import "VLMIDIDocument.h"
2008-05-29 18:54:30 +00:00
#import "VLAIFFDocument.h"
#import "VLMP3Document.h"
2007-04-18 08:25:43 +00:00
#import "VLPDFDocument.h"
2007-09-10 08:25:22 +00:00
#import "VLPListDocument.h"
2006-10-28 09:18:55 +00:00
#import "VLPDFWindow.h"
#import "VLLogWindow.h"
#import "VLSheetWindow.h"
2006-11-13 04:26:09 +00:00
#import "VLSoundOut.h"
2008-05-29 18:54:30 +00:00
#import "VLMIDIWriter.h"
2006-09-11 02:49:56 +00:00
2007-04-18 08:25:43 +00:00
#import <Quartz/Quartz.h>
@interface PDFDocument (PDFKitSecretsIKnow)
- (NSPrintOperation *)getPrintOperationForPrintInfo:(NSPrintInfo *)printInfo autoRotate:(BOOL)doRotate;
@end
2006-12-04 07:04:24 +00:00
@interface VLSongWrapper : NSObject {
VLSong * wrappedSong;
}
+ (VLSongWrapper *)wrapperWithSong:(VLSong *)song;
- (VLSong *)song;
@end
@implementation VLSongWrapper
- (id)initWithSong:(VLSong *)song
{
if (self = [super init])
wrappedSong = new VLSong(*song);
return self;
}
- (void) dealloc
{
delete wrappedSong;
[super dealloc];
}
+ (VLSongWrapper *)wrapperWithSong:(VLSong *)song
{
return [[[VLSongWrapper alloc] initWithSong:song] autorelease];
}
- (VLSong *)song
{
return wrappedSong;
}
@end
2006-10-28 09:18:55 +00:00
@implementation VLDocument
2006-10-03 17:52:54 +00:00
2011-09-04 00:00:26 +00:00
@synthesize playElements;
2011-08-28 21:05:19 +00:00
+ (BOOL)autosavesInPlace
{
return YES;
}
2006-10-28 09:18:55 +00:00
- (id)init
2006-10-03 17:52:54 +00:00
{
2006-10-28 09:18:55 +00:00
self = [super init];
if (self) {
song = new VLSong;
lilypondTemplate = @"default";
songTitle = @"";
songLyricist = @"";
songComposer = @"";
songArranger = @"";
2006-11-04 08:15:34 +00:00
songGroove = @"Swing";
2011-09-04 00:00:26 +00:00
playElements = kVLPlayAccompaniment|kVLPlayMelody|kVLPlayCountIn;
2008-01-26 16:38:30 +00:00
songTempo = [[NSNumber alloc] initWithInt:120];
2008-07-06 11:07:41 +00:00
baseTempo = 120.0f;
2008-01-26 16:38:30 +00:00
chordSize = 6.0f;
lyricSize = 0.0f;
staffSize = 20.0f;
2011-07-24 03:32:43 +00:00
topPadding = 2.0f;
titlePadding = 4.0f;
staffPadding = 3.0f;
chordPadding = 1.5f;
lyricPadding = 1.0f;
2006-10-28 09:18:55 +00:00
sheetWin = nil;
2011-09-03 20:34:53 +00:00
tmpURL = nil;
2006-11-17 08:57:29 +00:00
vcsWrapper = nil;
2006-12-30 09:57:40 +00:00
repeatVolta = 2;
2007-01-21 11:34:40 +00:00
brandNew = true;
2008-07-05 13:56:51 +00:00
hasMusicSequence = false;
2008-05-29 18:54:30 +00:00
playRate = 1.0;
2007-04-16 05:35:52 +00:00
observers = [[NSMutableArray alloc] init];
2007-04-18 07:05:04 +00:00
validTmpFiles = [[NSMutableDictionary alloc] initWithCapacity:10];
2006-12-04 07:04:24 +00:00
[self setHasUndoManager:YES];
undo =
[[VLKeyValueUndo alloc] initWithOwner:self
keysAndNames: [NSDictionary dictionaryWithObjectsAndKeys:
@"", @"songTitle",
@"", @"songLyricist",
@"", @"songComposer",
@"", @"songArranger",
@"", @"songGroove",
@"", @"songTempo",
nil]];
2006-10-28 09:18:55 +00:00
}
return self;
2006-10-03 17:52:54 +00:00
}
2007-04-18 07:05:04 +00:00
- (void)updateChangeCount:(NSDocumentChangeType)changeType
{
2008-07-05 13:57:12 +00:00
hasMusicSequence = false;
2007-04-18 07:05:04 +00:00
[validTmpFiles removeAllObjects];
[super updateChangeCount:changeType];
}
2007-04-16 05:35:52 +00:00
- (void) addObserver:(id)observer
{
[observers addObject:observer];
}
- (void) close
{
[observers makeObjectsPerformSelector:@selector(removeObservers:) withObject:self];
2007-04-20 05:33:58 +00:00
[observers removeAllObjects];
2007-04-16 05:35:52 +00:00
[super close];
}
2006-10-29 07:49:33 +00:00
- (void) dealloc
2006-10-03 17:52:54 +00:00
{
2011-09-04 01:00:38 +00:00
VLSoundOut::Instance()->Stop();
2006-10-29 07:49:33 +00:00
delete song;
2006-10-03 17:52:54 +00:00
2006-10-29 07:49:33 +00:00
[lilypondTemplate release];
[songTitle release];
[songLyricist release];
[songComposer release];
[songArranger release];
2006-11-17 08:57:29 +00:00
[vcsWrapper release];
2006-12-04 07:04:24 +00:00
[undo release];
2007-04-16 05:35:52 +00:00
[observers release];
2011-09-03 20:34:53 +00:00
if (tmpURL) {
[[NSFileManager defaultManager] removeItemAtURL:tmpURL error:nil];
[tmpURL release];
2006-11-10 08:09:18 +00:00
}
2006-10-29 07:49:33 +00:00
[super dealloc];
2006-10-03 17:52:54 +00:00
}
2006-10-28 09:18:55 +00:00
- (void)makeWindowControllers
2006-09-11 02:49:56 +00:00
{
2006-10-28 09:18:55 +00:00
sheetWin = [[VLSheetWindow alloc] initWithWindowNibName: @"VLDocument"];
[self addWindowController: sheetWin];
[sheetWin setShouldCloseDocument:YES];
[sheetWin release];
2006-09-11 02:49:56 +00:00
}
- (VLSong *) song
{
return song;
}
2008-03-30 19:13:17 +00:00
- (void) setSongTitle:(NSString *)newTitle
{
if (newTitle != songTitle) {
[songTitle release];
songTitle = [newTitle retain];
}
[[self windowControllers] makeObjectsPerformSelector:
@selector(synchronizeWindowTitleWithDocumentName)];
}
2006-09-11 02:49:56 +00:00
- (NSNumber *) songKey
{
const VLProperties & prop = song->fProperties.front();
return [NSNumber numberWithInt: (prop.fKey << 8) | (prop.fMode & 0xFF)];
}
2008-01-12 23:55:15 +00:00
- (void) setKey:(int)key transpose:(BOOL)transpose inSections:(NSRange)sections
2006-09-11 02:49:56 +00:00
{
2006-12-04 07:04:24 +00:00
[self willChangeSong];
2007-05-06 05:07:39 +00:00
[self willChangeValueForKey:@"songKey"];
2008-01-12 23:55:15 +00:00
while (sections.length-- > 0)
song->ChangeKey(sections.location++, key>>8, key & 0xFF, transpose);
2007-05-06 05:07:39 +00:00
[self didChangeValueForKey:@"songKey"];
[self didChangeSong];
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];
}
2008-01-12 23:55:15 +00:00
- (void) setTimeNum:(int)num denom:(int)denom inSections:(NSRange)sections
2006-09-11 02:49:56 +00:00
{
2006-12-04 07:04:24 +00:00
[self willChangeSong];
2007-05-06 05:07:39 +00:00
[self willChangeValueForKey:@"songTime"];
2008-01-12 23:55:15 +00:00
while (sections.length-- > 0)
song->ChangeTime(sections.location++, VLFraction(num, denom));
2007-05-06 05:07:39 +00:00
[self didChangeValueForKey:@"songTime"];
[self didChangeSong];
2006-09-11 02:49:56 +00:00
}
- (NSNumber *) songDivisions
{
const VLProperties & prop = song->fProperties.front();
return [NSNumber numberWithInt: prop.fDivisions];
}
2008-01-12 23:55:15 +00:00
- (void) setDivisions:(int)divisions inSections:(NSRange)sections
2006-09-11 02:49:56 +00:00
{
2006-12-04 07:04:24 +00:00
[self willChangeSong];
2007-05-06 05:07:39 +00:00
[self willChangeValueForKey:@"songDivisions"];
2008-01-12 23:55:15 +00:00
while (sections.length-- > 0)
song->ChangeDivisions(sections.location++, divisions);
2007-05-06 05:07:39 +00:00
[self didChangeValueForKey:@"songDivisions"];
[self didChangeSong];
2006-09-11 02:49:56 +00:00
}
2008-07-06 11:07:41 +00:00
- (void) setSongTempo:(int)tempo
{
2008-07-06 11:08:20 +00:00
if (tempo == [songTempo intValue])
return;
2008-07-06 11:07:41 +00:00
[songTempo autorelease];
songTempo = [[NSNumber numberWithInt:tempo] retain];
if (VLSoundOut::Instance()->Playing())
VLSoundOut::Instance()->SetPlayRate(playRate*tempo/baseTempo);
}
2008-01-23 01:20:09 +00:00
- (void) setGroove:(NSString *)groove inSections:(NSRange)sections
{
const char * grv = [groove UTF8String];
[self willChangeSong];
[self willChangeValueForKey:@"songGroove"];
while (sections.length-- > 0)
song->fProperties[sections.location++].fGroove = grv;
[self didChangeValueForKey:@"songGroove"];
[self didChangeSong];
}
2008-04-12 21:33:43 +00:00
- (void) changeOctave:(BOOL)up inSections:(NSRange)sections
{
[self willChangeSong];
while (sections.length-- > 0)
song->ChangeOctave(sections.location++, up);
[self didChangeSong];
}
2008-01-26 16:38:30 +00:00
- (void) setChordSize:(float)size
{
[[[self undoManager] prepareWithInvocationTarget:self] setChordSize:chordSize];
chordSize = size;
2008-01-27 21:59:51 +00:00
[validTmpFiles removeObjectForKey:@"ly"];
[validTmpFiles removeObjectForKey:@"pdf"];
2008-01-26 16:38:30 +00:00
}
- (void) setLyricSize:(float)size
{
[[[self undoManager] prepareWithInvocationTarget:self] setLyricSize:lyricSize];
lyricSize = size;
2008-01-27 21:59:51 +00:00
[validTmpFiles removeObjectForKey:@"ly"];
[validTmpFiles removeObjectForKey:@"pdf"];
2008-01-26 16:38:30 +00:00
}
- (void) setStaffSize:(float)size
{
[[[self undoManager] prepareWithInvocationTarget:self] setStaffSize:staffSize];
staffSize = size;
2008-01-27 21:59:51 +00:00
[validTmpFiles removeObjectForKey:@"ly"];
[validTmpFiles removeObjectForKey:@"pdf"];
2008-01-26 16:38:30 +00:00
}
2011-09-04 00:00:26 +00:00
- (void)setPlayElements:(int)elements
2007-12-03 17:45:56 +00:00
{
2011-09-04 00:00:26 +00:00
playElements = elements;
[validTmpFiles removeObjectForKey:@"mma"];
[validTmpFiles removeObjectForKey:@"mid"];
hasMusicSequence = false;
2007-12-03 17:45:56 +00:00
}
2011-09-04 00:00:26 +00:00
- (int) repeatVolta
{
return repeatVolta;
2007-12-03 17:45:56 +00:00
}
2007-01-21 11:34:40 +00:00
- (bool) brandNew
{
return brandNew && ![self isDocumentEdited];
}
2006-12-30 09:57:40 +00:00
- (void) setRepeatVolta:(int)volta
{
repeatVolta = volta;
}
2011-09-03 20:34:53 +00:00
- (NSURL *) tmpURL
2006-11-10 08:09:18 +00:00
{
2011-09-03 20:34:53 +00:00
if (!tmpURL) {
NSString * tmpPath = [NSString stringWithFormat:@"/var/tmp/VocalEasel.%08x", self];
tmpURL = [[NSURL alloc] initFileURLWithPath:tmpPath];
[[NSFileManager defaultManager] createDirectoryAtURL:tmpURL withIntermediateDirectories:NO attributes:nil error:nil];
2006-11-10 08:09:18 +00:00
}
2011-09-03 20:34:53 +00:00
return tmpURL;
2006-11-10 08:09:18 +00:00
}
2011-09-03 20:34:53 +00:00
- (NSURL *) workURL
2006-11-10 08:09:18 +00:00
{
2011-09-03 20:34:53 +00:00
if (NSURL * url = [self fileURL]) // Prefer our wrapper directory
return url;
2006-11-10 08:09:18 +00:00
else
2011-09-03 20:34:53 +00:00
return [self tmpURL];
2006-11-10 08:09:18 +00:00
}
- (NSString *) baseName
{
2011-09-03 20:34:53 +00:00
return [[[self workURL] lastPathComponent] stringByDeletingPathExtension];
2006-11-10 08:09:18 +00:00
}
- (NSURL *) fileURLWithExtension:(NSString*)extension
{
2011-09-03 20:34:53 +00:00
return [[[self workURL] URLByAppendingPathComponent:[self baseName]]
URLByAppendingPathExtension:extension];
2006-11-10 08:09:18 +00:00
}
2006-11-17 08:57:29 +00:00
- (BOOL)saveToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation error:(NSError **)outError
{
NSFileWrapper * preservedVCSWrapper = nil;
switch (saveOperation) {
case NSSaveToOperation:
case NSAutosaveOperation:
preservedVCSWrapper = vcsWrapper;
[preservedVCSWrapper retain];
// Fall through
case NSSaveAsOperation:
[vcsWrapper release];
vcsWrapper = nil;
// Fall through
case NSSaveOperation:
break;
}
BOOL res = [super saveToURL:absoluteURL ofType:typeName
forSaveOperation:saveOperation error:outError];
if (!vcsWrapper)
vcsWrapper = preservedVCSWrapper;
2011-07-24 03:32:13 +00:00
if ([typeName isEqual:VLNativeType])
2007-04-18 07:05:04 +00:00
[validTmpFiles removeAllObjects];
2006-11-17 08:57:29 +00:00
return res;
}
2006-10-29 07:49:33 +00:00
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
2006-10-22 07:16:29 +00:00
{
2011-07-24 03:32:13 +00:00
if ([typeName isEqual:VLNativeType]) {
2006-10-29 07:49:33 +00:00
return [self XMLFileWrapperWithError:outError flat:NO];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLMusicXMLType]) {
2006-10-29 07:49:33 +00:00
return [self XMLFileWrapperWithError:outError flat:YES];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLLilypondType]) {
2006-10-29 07:49:33 +00:00
return [self lilypondFileWrapperWithError:outError];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLMMAType]) {
2006-11-04 08:15:34 +00:00
return [self mmaFileWrapperWithError:outError];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLMIDIType]) {
2006-11-12 11:37:36 +00:00
return [self midiFileWrapperWithError:outError];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLAIFFType]) {
2008-05-29 18:54:30 +00:00
return [self aiffFileWrapperWithError:outError];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLMP3Type]) {
2008-05-29 18:54:30 +00:00
return [self mp3FileWrapperWithError:outError];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLPDFType]) {
2007-04-18 07:05:04 +00:00
return [self pdfFileWrapperWithError: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
}
2006-10-29 07:49:33 +00:00
- (BOOL)readFromFileWrapper:(NSFileWrapper *)wrapper ofType:(NSString *)typeName error:(NSError **)outError
2006-10-22 07:16:29 +00:00
{
2007-01-21 11:34:40 +00:00
brandNew = false;
//
// On opening a document, close all unchanged empty documents
//
NSEnumerator * docs = [[[NSDocumentController sharedDocumentController]
documents] objectEnumerator];
while (VLDocument * doc = [docs nextObject])
if ([doc brandNew])
[[doc windowControllers]
makeObjectsPerformSelector:@selector(close)];
2011-07-24 03:32:13 +00:00
if ([typeName isEqual:VLNativeType] || [typeName isEqual:VLMusicXMLType]) {
2006-10-29 07:49:33 +00:00
return [self readFromXMLFileWrapper:wrapper error:outError];
2011-07-24 03:32:13 +00:00
} else if ([typeName isEqual:VLLilypondType] || [typeName isEqual:VLBIABType]) {
2007-09-10 08:25:22 +00:00
if ([self readFromFileWrapper:wrapper withFilter:typeName error:outError]) {
[self setFileURL:nil];
return YES;
} else
return NO;
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
}
2007-01-12 09:01:19 +00:00
- (void) changedFileWrapper
{
2011-09-03 20:34:53 +00:00
if (NSURL * url = [self workURL]) {
NSDate * modDate;
if ([url getResourceValue:&modDate forKey:NSURLAttributeModificationDateKey error:nil])
[self setFileModificationDate:modDate];
}
2007-01-12 09:01:19 +00:00
}
2007-04-18 07:05:04 +00:00
- (void) createTmpFileWithExtension:(NSString*)ext ofType:(NSString*)type
{
if (![validTmpFiles objectForKey:ext]) {
NSError * err;
if ([self writeToURL:[self fileURLWithExtension:ext]
ofType:type error:&err]
) {
[validTmpFiles setObject:type forKey:ext];
[self changedFileWrapper];
}
}
}
2006-11-12 11:37:36 +00:00
- (NSTask *) taskWithLaunchPath:(NSString *)launch arguments:(NSArray *)args;
{
NSTask * task = [[NSTask alloc] init];
2011-09-03 20:34:53 +00:00
NSString * path = [[self workURL] path];
2006-11-12 11:37:36 +00:00
NSPipe * pipe = [NSPipe pipe];
[task setCurrentDirectoryPath: path];
[task setStandardOutput: pipe];
[task setStandardError: pipe];
[task setArguments: args];
[task setLaunchPath: launch];
2011-09-04 01:00:38 +00:00
[NSThread detachNewThreadSelector:@selector(logFromFileHandle:) toTarget:[sheetWin logWin]
2006-11-12 11:37:36 +00:00
withObject:[pipe fileHandleForReading]];
return task;
}
2006-11-13 04:26:09 +00:00
- (IBAction) play:(id)sender
{
2008-07-05 13:56:51 +00:00
if (hasMusicSequence) {
VLSoundOut::Instance()->PlaySequence(NULL);
} else {
2011-07-24 03:32:13 +00:00
[self createTmpFileWithExtension:@"mid" ofType:VLMIDIType];
2008-07-05 13:56:51 +00:00
MusicSequence music;
NewMusicSequence(&music);
2011-09-03 20:34:53 +00:00
MusicSequenceFileLoad(music, (CFURLRef)[self fileURLWithExtension:@"mid"],
0, kMusicSequenceLoadSMF_ChannelsToTracks);
2008-07-05 13:56:51 +00:00
size_t countIn = 0;
if (playElements & kVLPlayCountIn)
switch ([[self songTime] intValue]) {
case 0x404:
case 0x304:
case 0x608:
countIn = 2;
}
VLMIDIWriter annotate(music, countIn);
annotate.Visit(*song);
2008-05-29 18:54:30 +00:00
2008-07-06 11:07:41 +00:00
hasMusicSequence = true;
2008-07-05 13:56:51 +00:00
[sheetWin willPlaySequence:music];
2008-07-06 11:07:41 +00:00
baseTempo = [songTempo floatValue];
VLSoundOut::Instance()->SetPlayRate(playRate);
2008-07-05 13:56:51 +00:00
VLSoundOut::Instance()->PlaySequence(music);
}
2006-11-13 04:26:09 +00:00
}
2008-01-24 01:29:18 +00:00
- (void) playWithGroove:(NSString *)groove inSections:(NSRange)sections
2007-04-23 05:46:37 +00:00
{
NSString * savedGroove = songGroove;
[validTmpFiles removeObjectForKey:@"mma"];
[validTmpFiles removeObjectForKey:@"mid"];
2008-07-05 13:57:12 +00:00
hasMusicSequence = false;
2008-01-24 01:29:18 +00:00
songGroove = groove;
previewRange = sections;
playElements |= kVLPlayGroovePreview;
2007-04-23 05:46:37 +00:00
[self play:groove];
2008-01-24 01:29:18 +00:00
playElements &= ~kVLPlayGroovePreview;
songGroove = savedGroove;
2007-04-23 05:46:37 +00:00
[validTmpFiles removeObjectForKey:@"mma"];
[validTmpFiles removeObjectForKey:@"mid"];
2008-07-05 13:57:12 +00:00
hasMusicSequence = false;
2007-04-23 05:46:37 +00:00
}
2007-01-02 07:01:55 +00:00
- (IBAction) stop:(id)sender
{
VLSoundOut::Instance()->Stop();
}
2007-12-03 17:45:56 +00:00
- (IBAction) playStop:(id)sender
{
if (VLSoundOut::Instance()->Playing()) {
[self stop:sender];
2011-08-29 00:01:49 +00:00
if ([sender isKindOfClass:[NSMenuItem class]]) {
[sender setTitle:@"Play"];
} else {
[sender setLabel:@"Play"];
[sender setImage:[NSImage imageNamed:@"play.icns"]];
}
2007-12-03 17:45:56 +00:00
} else {
[self play:sender];
2011-08-29 00:01:49 +00:00
if ([sender isKindOfClass:[NSMenuItem class]]) {
[sender setTitle:@"Stop"];
} else {
[sender setLabel:@"Stop"];
[sender setImage:[NSImage imageNamed:@"stop.icns"]];
}
2007-12-03 17:45:56 +00:00
}
}
2008-05-29 18:54:30 +00:00
- (IBAction) playMusic:(id)sender
{
2011-09-03 20:34:53 +00:00
switch ([sender tag]) {
2008-05-29 18:54:30 +00:00
case 1: // Fwd
2011-08-29 00:41:04 +00:00
VLSoundOut::Instance()->Fwd();
break;
2008-05-29 18:54:30 +00:00
case -1: // Rew
2011-08-29 00:41:04 +00:00
VLSoundOut::Instance()->Bck();
2008-05-29 18:54:30 +00:00
break;
}
}
2008-07-06 11:08:39 +00:00
- (IBAction) adjustTempo:(id)sender
{
[self setSongTempo:[songTempo intValue]+[sender tag]];
}
2007-04-18 08:25:43 +00:00
- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)printSettings
error:(NSError **)outError
{
2011-07-24 03:32:13 +00:00
[self createTmpFileWithExtension:@"pdf" ofType:VLPDFType];
2011-09-04 00:06:12 +00:00
PDFDocument * printDoc = [[PDFDocument alloc] initWithURL:[self fileURLWithExtension:@"pdf"]];
[printDoc autorelease];
2007-04-18 08:25:43 +00:00
NSPrintOperation *printOperation = [printDoc getPrintOperationForPrintInfo:[self printInfo] autoRotate:NO];
// Specify that the print operation can run in a separate thread. This will cause the print progress panel to appear as a sheet on the document window.
[printOperation setCanSpawnSeparateThread:YES];
// Set any print settings that might have been specified in a Print Document Apple event.
[[[printOperation printInfo] dictionary] addEntriesFromDictionary:printSettings];
return printOperation;
}
2006-12-04 07:04:24 +00:00
- (void) willChangeSong
{
[self willChangeValueForKey:@"song"];
[[self undoManager] registerUndoWithTarget:self
selector:@selector(restoreSong:)
object:[VLSongWrapper wrapperWithSong:song]];
}
- (void) didChangeSong
{
[self didChangeValueForKey:@"song"];
[self updateChangeCount:NSChangeDone];
}
- (void) restoreSong:(VLSongWrapper *)savedSong
{
[self willChangeSong];
[self willChangeValueForKey:@"songKey"];
[self willChangeValueForKey:@"songTime"];
[self willChangeValueForKey:@"songDivisions"];
2007-04-19 18:23:33 +00:00
[self willChangeValueForKey:@"songGroove"];
2006-12-04 07:04:24 +00:00
song->swap(*[savedSong song]);
[self didChangeValueForKey:@"songKey"];
[self didChangeValueForKey:@"songTime"];
[self didChangeValueForKey:@"songDivisions"];
2007-04-19 18:23:33 +00:00
[self didChangeValueForKey:@"songGroove"];
2006-12-04 07:04:24 +00:00
[self didChangeSong];
}
2008-03-24 22:47:29 +00:00
- (NSString *) displayName
{
if ([songTitle isEqual:@""])
return [super displayName];
else
return songTitle;
}
2006-09-11 02:49:56 +00:00
@end
2008-07-05 14:04:01 +00:00