--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2008 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#import "GVExportViewController.h"
+#import "GVGraph.h"
+
+NSMutableArray *_formatRenders = nil;
+
+@implementation GVExportViewController
+
+@synthesize filename = _filename;
+@synthesize render = _render;
+
++ (void)initialize
+{
+ if (!_formatRenders) {
+ _formatRenders = [[NSMutableArray alloc] init];
+
+ NSString *lastFormat = nil;
+ NSMutableArray *lastRenders = nil;
+ for (NSString *device in [GVGraph devices]) {
+ NSLog (@"%@", device);
+
+ NSArray *deviceComponents = [device componentsSeparatedByString:@":"];
+ NSUInteger componentCount = [deviceComponents count];
+
+ if (componentCount > 0) {
+ NSString *format = [deviceComponents objectAtIndex:0];
+ if (![lastFormat isEqualToString:format]) {
+ lastFormat = format;
+ lastRenders = [NSMutableArray array];
+ [_formatRenders addObject:[NSDictionary dictionaryWithObjectsAndKeys:lastFormat, @"format", lastRenders, @"renders", nil]];
+ }
+ }
+
+ if (componentCount > 1)
+ [lastRenders addObject:[deviceComponents objectAtIndex:1]];
+ }
+ }
+}
+
+- (id)init
+{
+ if (self = [super initWithNibName:@"Export" bundle:nil]) {
+ _panel = nil;
+ _filename = nil;
+
+ _formatRender = nil;
+ _render = nil;
+ for (NSDictionary *formatRender in _formatRenders)
+ if ([[formatRender objectForKey:@"format"] isEqualToString:@"pdf"]) {
+ _formatRender = formatRender;
+ if ([[formatRender objectForKey:@"renders"] containsObject:@"quartz"])
+ _render = @"quartz";
+ break;
+ }
+ }
+ return self;
+}
+
+- (NSArray *)formatRenders
+{
+ return _formatRenders;
+}
+
+- (NSString *)device
+{
+ NSString *format = [_formatRender objectForKey:@"format"];
+ return _render ? [NSString stringWithFormat:@"%@:%@", format, _render] : format;
+}
+
+- (NSDictionary *)formatRender
+{
+ return _formatRender;
+}
+
+- (void)setFormatRender:(NSDictionary *)formatRender
+{
+ if (_formatRender != formatRender) {
+ [_formatRender release];
+ _formatRender = [formatRender retain];
+
+ /* force save panel to use this file type */
+ [_panel setRequiredFileType:[_formatRender objectForKey:@"format"]];
+
+ /* remove existing render if it's not compatible with format */
+ if (![[_formatRender objectForKey:@"renders"] containsObject:_render])
+ [self setRender:nil];
+ }
+}
+
+- (void)beginSheetModalForWindow:(NSWindow *)window modalDelegate:(id)modalDelegate didEndSelector:(SEL)selector
+{
+ /* remember to invoke end selector on the modal delegate */
+ NSInvocation *endInvocation = [NSInvocation invocationWithMethodSignature:[modalDelegate methodSignatureForSelector:selector]];
+ [endInvocation setTarget:modalDelegate];
+ [endInvocation setSelector:selector];
+ [endInvocation setArgument:&self atIndex:2];
+ [endInvocation retain];
+
+ _panel = [NSSavePanel savePanel];
+ [_panel setAccessoryView:[self view]];
+ [_panel setRequiredFileType:[_formatRender objectForKey:@"format"]];
+ [_panel
+ beginSheetForDirectory:[_filename stringByDeletingLastPathComponent]
+ file:[_filename lastPathComponent]
+ modalForWindow:window
+ modalDelegate:self
+ didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:)
+ contextInfo:endInvocation];
+}
+
+- (void)savePanelDidEnd:(NSSavePanel *)savePanel returnCode:(int)returnCode contextInfo:(void *)contextInfo
+{
+ NSInvocation *endInvocation = (NSInvocation *)contextInfo;
+ if (returnCode == NSOKButton) {
+ NSString *filename = [savePanel filename];
+ if (_filename != filename) {
+ [_filename release];
+ _filename = [filename retain];
+ }
+
+ /* invoke the end selector on the modal delegate */
+ [endInvocation invoke];
+ }
+
+ [endInvocation release];
+ [_panel setAccessoryView:nil];
+ _panel = nil;
+}
+
+- (void)dealloc
+{
+ [_panel release];
+ [_filename release];
+ [_formatRender release];
+ [_render release];
+ [super dealloc];
+}
+
+@end
static GVC_t *_graphContext = nil;
+@interface GVGraphPluginEnumerator : NSEnumerator
+{
+ gvplugin_available_t *_plugin;
+ NSMutableSet *_distinctPlugins;
+}
+
+- (id)initWithAPI:(api_t)api;
+- (NSArray *)allObjects;
+- (id)nextObject;
+- (void)dealloc;
+
+@end
+
+@implementation GVGraphPluginEnumerator
+
+- (id)initWithAPI:(api_t)api
+{
+ if (self = [super init]) {
+ _plugin = gvFirstPlugin(_graphContext, api);
+ _distinctPlugins = [[NSMutableSet alloc] init];
+ }
+ return self;
+}
+
+- (NSArray *)allObjects
+{
+ NSMutableArray *allPlugins = [NSMutableArray array];
+ for (; _plugin; _plugin = gvNextPlugin(_plugin)) {
+ /* get the type */
+ char *pluginType = gvPluginType(_plugin);
+ NSString *nextPlugin = [[[NSString alloc] initWithBytesNoCopy:pluginType length:strlen(pluginType) encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease];
+
+ /* if distinct, add to the list */
+ if (![_distinctPlugins containsObject:nextPlugin]) {
+ [_distinctPlugins addObject:nextPlugin];
+ [allPlugins addObject:nextPlugin];
+ }
+ }
+ return allPlugins;
+}
+
+- (id)nextObject
+{
+ NSString *nextPlugin = nil;
+ BOOL plugging = YES;
+ for (; plugging && _plugin; _plugin = gvNextPlugin(_plugin)) {
+ /* get the type */
+ char *pluginType = gvPluginType(_plugin);
+ nextPlugin = [[[NSString alloc] initWithBytesNoCopy:pluginType length:strlen(pluginType) encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease];
+
+ /* if distinct, stop plugging away */
+ if (![_distinctPlugins containsObject:nextPlugin]) {
+ [_distinctPlugins addObject:nextPlugin];
+ plugging = NO;
+ }
+ }
+
+ return nextPlugin;
+}
+
+- (void)dealloc
+{
+ [_distinctPlugins release];
+ [super dealloc];
+}
+@end
+
@implementation GVGraph
@synthesize graph = _graph;
_graphContext = gvContext();
}
-- (id)initWithURL:(NSURL*)URL error:(NSError**)outError
++ (NSEnumerator *)devices
+{
+ return [[[GVGraphPluginEnumerator alloc] initWithAPI:API_device] autorelease];
+}
+
+- (id)initWithURL:(NSURL *)URL error:(NSError **)outError
{
if (self = [super init]) {
if ([URL isFileURL]) {
return self;
}
-- (BOOL)writeToURL:(NSURL*)URL error:(NSError**)outError
+- (BOOL)writeToURL:(NSURL *)URL error:(NSError **)outError
{
if ([URL isFileURL]) {
/* open a FILE* on the file URL */
[[NSNotificationCenter defaultCenter] postNotificationName: @"GVGraphDidChange" object:self];
}
-- (NSData*)renderWithFormat:(NSString*)format
+- (NSData*)renderWithFormat:(NSString *)format
{
char *renderedData = NULL;
unsigned int renderedLength = 0;
}
-- (void)renderWithFormat:(NSString*)format toURL:(NSURL*)URL
+- (void)renderWithFormat:(NSString *)format toURL:(NSURL *)URL
{
if ([URL isFileURL]) {
if (gvRenderFilename(_graphContext, _graph, (char*)[format UTF8String], (char*)[[URL path] UTF8String]) != 0)