mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 03:04:00 +00:00
Switch to NSFileWrapper based documents
This commit is contained in:
parent
6f67b7df9e
commit
a970adcbc9
Binary file not shown.
|
@ -22,12 +22,13 @@
|
|||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>VLDocument</string>
|
||||
<key>NSExportableAs</key>
|
||||
<array>
|
||||
<string>VLLilypondType</string>
|
||||
<string>VLMusicXMLType</string>
|
||||
</array>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>XML</string>
|
||||
|
@ -50,6 +51,20 @@
|
|||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>xml</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>VLMusicXMLType</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>VocalEasel</string>
|
||||
|
|
BIN
Resources/VLPDFWindow.nib/keyedobjects.nib
generated
BIN
Resources/VLPDFWindow.nib/keyedobjects.nib
generated
Binary file not shown.
|
@ -67,14 +67,13 @@
|
|||
char line[1000];
|
||||
FILE * output = popen([command UTF8String], "r");
|
||||
if (fgets(line, 1000, output)) {
|
||||
fprintf(stderr, "Line %s", line);
|
||||
size_t len = strlen(line);
|
||||
if (len && line[len-1]=='\n') {
|
||||
line[len-1] = 0;
|
||||
return [NSString stringWithUTF8String:line];
|
||||
}
|
||||
} else
|
||||
NSLog(@"Failed command: %@ (%d)\n", command, errno);
|
||||
NSLog(@"Failed command: %@ %s (%d)\n", command, feof(output) ? "EOF" : "Error", errno);
|
||||
pclose(output);
|
||||
return nil;
|
||||
}
|
||||
|
@ -181,9 +180,4 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,21 +32,29 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) close
|
||||
{
|
||||
[logWin close];
|
||||
[pdfWin close];
|
||||
|
||||
[super close];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
delete song;
|
||||
|
||||
[lilypondTemplate release];
|
||||
[songTitle release];
|
||||
[songLyricist release];
|
||||
[songComposer release];
|
||||
[songArranger release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)removeWindowController:(NSWindowController *)win
|
||||
{
|
||||
if (win == logWin)
|
||||
logWin = nil;
|
||||
else if (win == pdfWin)
|
||||
pdfWin = nil;
|
||||
|
||||
[super removeWindowController:win];
|
||||
}
|
||||
|
||||
- (VLLogWindow *)logWin
|
||||
{
|
||||
if (!logWin) {
|
||||
|
@ -141,12 +149,14 @@
|
|||
[self updateChangeCount:NSChangeDone];
|
||||
}
|
||||
|
||||
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
|
||||
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
|
||||
{
|
||||
if ([typeName isEqual:@"VLNativeType"]) {
|
||||
return [self XMLDataWithError:outError];
|
||||
return [self XMLFileWrapperWithError:outError flat:NO];
|
||||
} else if ([typeName isEqual:@"VLMusicXMLType"]) {
|
||||
return [self XMLFileWrapperWithError:outError flat:YES];
|
||||
} else if ([typeName isEqual:@"VLLilypondType"]) {
|
||||
return [self lilypondDataWithError:outError];
|
||||
return [self lilypondFileWrapperWithError:outError];
|
||||
} else {
|
||||
if (outError)
|
||||
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
|
||||
|
@ -156,10 +166,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
|
||||
- (BOOL)readFromFileWrapper:(NSFileWrapper *)wrapper ofType:(NSString *)typeName error:(NSError **)outError
|
||||
{
|
||||
if ([typeName isEqual:@"VLNativeType"]) {
|
||||
return [self readFromXMLData:data error:outError];
|
||||
return [self readFromXMLFileWrapper:wrapper error:outError];
|
||||
} else {
|
||||
if (outError)
|
||||
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
|
||||
|
@ -169,14 +179,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction) engrave:(id)sender
|
||||
- (IBAction) performEngrave:(id)sender
|
||||
{
|
||||
NSTask * lilypondTask = [[NSTask alloc] init];
|
||||
NSString * path = [[self fileURL] path];
|
||||
NSString * root =
|
||||
[[path lastPathComponent] stringByDeletingPathExtension];
|
||||
NSString * tmpDir = @"/var/tmp";
|
||||
NSString * base = [[path lastPathComponent]
|
||||
stringByDeletingPathExtension];
|
||||
NSBundle * mainBundle = [NSBundle mainBundle];
|
||||
|
||||
//
|
||||
|
@ -184,21 +192,20 @@
|
|||
//
|
||||
NSError * err;
|
||||
[self writeToURL:
|
||||
[NSURL fileURLWithPath:
|
||||
[[tmpDir stringByAppendingPathComponent:root]
|
||||
stringByAppendingPathExtension:@"ly"]]
|
||||
[NSURL fileURLWithPath:[[path stringByAppendingPathComponent:base]
|
||||
stringByAppendingPathExtension:@"ly"]]
|
||||
ofType:@"VLLilypondType" error:&err];
|
||||
NSPipe * pipe = [NSPipe pipe];
|
||||
NSString * tool =
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"VLLilypondPath"];
|
||||
NSArray * arguments = [NSArray arrayWithObjects:tool, root, nil];
|
||||
NSArray * arguments = [NSArray arrayWithObjects:tool, base, nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self selector:@selector(engraveDone:)
|
||||
name:NSTaskDidTerminateNotification object:lilypondTask];
|
||||
|
||||
[lilypondTask setCurrentDirectoryPath:tmpDir];
|
||||
[lilypondTask setCurrentDirectoryPath:path];
|
||||
[lilypondTask setStandardOutput: pipe];
|
||||
[lilypondTask setStandardError: pipe];
|
||||
[lilypondTask setArguments: arguments];
|
||||
|
@ -216,24 +223,43 @@
|
|||
[[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];
|
||||
}
|
||||
} else {
|
||||
NSBeep();
|
||||
}
|
||||
}
|
||||
|
||||
- (void) engrave:(NSDocument *)doc didSave:(BOOL)didSave contextInfo:(void *)contextInfo
|
||||
{
|
||||
if (didSave)
|
||||
[self performEngrave:(id)contextInfo];
|
||||
}
|
||||
|
||||
- (void)engrave:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(id)sender
|
||||
{
|
||||
if (returnCode == NSAlertDefaultReturn) {
|
||||
[[alert window] orderOut:self];
|
||||
[self saveDocumentWithDelegate:self
|
||||
didSaveSelector:@selector(engrave:didSave:contextInfo:)
|
||||
contextInfo:sender];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) engrave:(id)sender
|
||||
{
|
||||
if ([self isDocumentEdited]) {
|
||||
NSAlert * alert =
|
||||
[NSAlert alertWithMessageText:@"Do you want to save your changes?"
|
||||
defaultButton:[self fileURL] ? @"Save" : @"Save..."
|
||||
alternateButton:@"Cancel" otherButton:nil
|
||||
informativeTextWithFormat:@"You need to save your document before typesetting."];
|
||||
[alert beginSheetModalForWindow:[sheetWin window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(engrave:returnCode:contextInfo:)
|
||||
contextInfo:sender];
|
||||
} else
|
||||
[self performEngrave:sender];
|
||||
}
|
||||
|
||||
- (IBAction) showOutput:(id)sender
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
|
||||
@interface VLDocument (Lilypond)
|
||||
|
||||
- (NSData *)lilypondDataWithError:(NSError **)outError;
|
||||
- (NSFileWrapper *)lilypondFileWrapperWithError:(NSError **)outError;
|
||||
|
||||
@end
|
||||
|
|
|
@ -131,4 +131,16 @@ const char * sKeyNames[] = {
|
|||
return [ly dataUsingEncoding:enc];
|
||||
}
|
||||
|
||||
- (NSFileWrapper *)lilypondFileWrapperWithError:(NSError **)outError
|
||||
{
|
||||
NSData * data = [self lilypondDataWithError:outError];
|
||||
|
||||
if (!data)
|
||||
return nil;
|
||||
else
|
||||
return [[[NSFileWrapper alloc]
|
||||
initRegularFileWithContents:data]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -36,13 +36,36 @@ static NSString* sZoomOutToolbarItemIdentifier = @"Zoom Out Toolbar Item Identif
|
|||
- (void)reloadPDF
|
||||
{
|
||||
if (pdfView) {
|
||||
NSString * inString = [[[self document] fileURL] path];
|
||||
NSString * baseString = [inString stringByDeletingPathExtension];
|
||||
NSString * outString = [baseString stringByAppendingPathExtension: @"pdf"];
|
||||
NSURL * pdfURL = [NSURL fileURLWithPath: outString];
|
||||
PDFDocument * pdfDoc = [[[PDFDocument alloc] initWithURL: pdfURL] autorelease];
|
||||
[(PDFView *)pdfView setDocument: pdfDoc];
|
||||
[pdfView setNeedsDisplay:YES];
|
||||
NSString * path = [[[self document] fileURL] path];
|
||||
if (!path)
|
||||
return;
|
||||
NSFileWrapper * wrapper =
|
||||
[[[NSFileWrapper alloc] initWithPath:path] autorelease];
|
||||
//
|
||||
// Find newest pdf file
|
||||
//
|
||||
NSEnumerator * w = [[wrapper fileWrappers] objectEnumerator];
|
||||
NSString * pdfPath = nil;
|
||||
NSDate * pdfDate = nil;
|
||||
while (wrapper = [w nextObject]) {
|
||||
NSString * path = [wrapper filename];
|
||||
if (![[path pathExtension] isEqual:@"pdf"])
|
||||
continue;
|
||||
NSDate * date = [[wrapper fileAttributes]
|
||||
objectForKey:NSFileModificationDate];
|
||||
if (!pdfPath || [date compare:pdfDate]==NSOrderedAscending) {
|
||||
pdfPath = path;
|
||||
pdfDate = date;
|
||||
}
|
||||
}
|
||||
if (pdfPath) {
|
||||
NSURL * pdfURL =
|
||||
[NSURL fileURLWithPath:[path stringByAppendingPathComponent:pdfPath]];
|
||||
PDFDocument * pdfDoc =
|
||||
[[[PDFDocument alloc] initWithURL:pdfURL] autorelease];
|
||||
[(PDFView *)pdfView setDocument: pdfDoc];
|
||||
[pdfView setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
@interface VLDocument (XML)
|
||||
|
||||
- (NSData *)XMLDataWithError:(NSError **)outError;
|
||||
- (BOOL)readFromXMLData:(NSData *)data error:(NSError **)outError;
|
||||
- (NSFileWrapper *)XMLFileWrapperWithError:(NSError **)outError flat:(BOOL)flat;
|
||||
- (BOOL)readFromXMLFileWrapper:(NSFileWrapper *)wrapper error:(NSError **)outError;
|
||||
|
||||
@end
|
||||
|
|
|
@ -283,6 +283,28 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB ";
|
|||
return [doc XMLDataWithOptions:NSXMLNodePrettyPrint|NSXMLNodeCompactEmptyElement];
|
||||
}
|
||||
|
||||
- (NSFileWrapper *)XMLFileWrapperWithError:(NSError **)outError flat:(BOOL)flat;
|
||||
{
|
||||
NSData * contents = [self XMLDataWithError:outError];
|
||||
|
||||
if (!contents) {
|
||||
return nil;
|
||||
} else if (flat) {
|
||||
return [[[NSFileWrapper alloc]
|
||||
initRegularFileWithContents:contents]
|
||||
autorelease];
|
||||
} else {
|
||||
NSFileWrapper * wrap = [[[NSFileWrapper alloc]
|
||||
initDirectoryWithFileWrappers:
|
||||
[NSDictionary dictionary]]
|
||||
autorelease];
|
||||
[wrap addRegularFileWithContents:contents
|
||||
preferredFilename:@"Song"];
|
||||
|
||||
return wrap;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)readPropsFromAttributes:(NSXMLElement*)attr error:(NSError **)outError
|
||||
{
|
||||
VLProperties & prop = song->fProperties.front();
|
||||
|
@ -432,4 +454,11 @@ int8_t sStepToPitch[] = {
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)readFromXMLFileWrapper:(NSFileWrapper *)wrapper error:(NSError **)outError
|
||||
{
|
||||
return [self readFromXMLData: [[[wrapper fileWrappers] objectForKey:@"Song"]
|
||||
regularFileContents]
|
||||
error:outError];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue
Block a user