]> granicus.if.org Git - graphviz/commitdiff
export dialog with selectable format and render
authorglenlow <devnull@localhost>
Mon, 26 May 2008 06:09:46 +0000 (06:09 +0000)
committerglenlow <devnull@localhost>
Mon, 26 May 2008 06:09:46 +0000 (06:09 +0000)
macosx/GVExportViewController.m [new file with mode: 0644]
macosx/GVGraph.h
macosx/GVGraph.m

diff --git a/macosx/GVExportViewController.m b/macosx/GVExportViewController.m
new file mode 100644 (file)
index 0000000..b7c1ba8
--- /dev/null
@@ -0,0 +1,154 @@
+/* $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
index 8077113a54df69e46fdfc9400e1317b90a1ce4b4..c742e6cfc5b7f9daf9f3c7609e618f9ed994bb1b 100644 (file)
 @property(readonly) GVGraphDefaultAttributes *defaultEdgeAttributes;
 
 + (void)initialize;
++ (NSEnumerator *)devices;
 
-- (id)initWithURL:(NSURL*)URL error:(NSError**)outError;
+- (id)initWithURL:(NSURL *)URL error:(NSError **)outError;
 
-- (NSData*)renderWithFormat:(NSString*)format;
-- (void)renderWithFormat:(NSString*)format toURL:(NSURL*)URL;
+- (NSData *)renderWithFormat:(NSString *)format;
+- (void)renderWithFormat:(NSString*)format toURL:(NSURL *)URL;
 - (void)noteChanged:(BOOL)relayout;
 
-- (BOOL)writeToURL:(NSURL*)URL error:(NSError**)outError;
+- (BOOL)writeToURL:(NSURL *)URL error:(NSError **)outError;
 
 - (void)dealloc;
 
index 5c39332356df8a247de29fbc9909401510e2ace7..4175ee90d3f4f3548a60ad0ea8ae6194aacbeb55 100644 (file)
@@ -22,6 +22,73 @@ extern double PSinputscale;
 
 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;
@@ -35,7 +102,12 @@ static GVC_t *_graphContext = nil;
        _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]) {
@@ -76,7 +148,7 @@ static GVC_t *_graphContext = nil;
        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 */
@@ -127,7 +199,7 @@ static GVC_t *_graphContext = nil;
        [[NSNotificationCenter defaultCenter] postNotificationName: @"GVGraphDidChange" object:self];
 }
 
-- (NSData*)renderWithFormat:(NSString*)format
+- (NSData*)renderWithFormat:(NSString *)format
 {
        char *renderedData = NULL;
        unsigned int renderedLength = 0;
@@ -137,7 +209,7 @@ static GVC_t *_graphContext = nil;
 
 }
 
-- (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)