summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Merry <alex.merry@cs.ox.ac.uk>2012-12-03 19:02:53 +0000
committerAlex Merry <alex.merry@cs.ox.ac.uk>2012-12-04 11:12:28 +0000
commit94ff07fc9d728d97dde159e0c3e6ab80e29e0855 (patch)
tree2e74ff3d709db87e2e2b27aa501ed46727c054d7
parent0d715a7f17b8e5570b42d7802c502e4aa234a3c1 (diff)
Refactor MainWindow into Application and Window
Basic multiple-window support, but no tools.
-rw-r--r--tikzit/src/Makefile.am5
-rw-r--r--tikzit/src/gtk/Application.h139
-rw-r--r--tikzit/src/gtk/Application.m268
-rw-r--r--tikzit/src/gtk/GraphInputHandler.h5
-rw-r--r--tikzit/src/gtk/GraphInputHandler.m55
-rw-r--r--tikzit/src/gtk/Menu.h33
-rw-r--r--tikzit/src/gtk/Menu.m156
-rw-r--r--tikzit/src/gtk/Window.h (renamed from tikzit/src/gtk/MainWindow.h)113
-rw-r--r--tikzit/src/gtk/Window.m (renamed from tikzit/src/gtk/MainWindow.m)463
-rw-r--r--tikzit/src/gtk/main.m43
10 files changed, 741 insertions, 539 deletions
diff --git a/tikzit/src/Makefile.am b/tikzit/src/Makefile.am
index 7b64bf8..30d9815 100644
--- a/tikzit/src/Makefile.am
+++ b/tikzit/src/Makefile.am
@@ -24,7 +24,8 @@ EDGEDECFILES = ../AH_*.png ../ED_*.png
bin_PROGRAMS = tikzit
BUILT_SOURCES = $(PARSERFILES)
-tikzit_SOURCES = gtk/CairoRenderContext.m \
+tikzit_SOURCES = gtk/Application.m \
+ gtk/CairoRenderContext.m \
gtk/ColorRGB+IntegerListStorage.m \
gtk/ColorRGB+Gtk.m \
gtk/Configuration.m \
@@ -37,7 +38,6 @@ tikzit_SOURCES = gtk/CairoRenderContext.m \
gtk/FileChooserDialog.m \
gtk/GraphInputHandler.m \
gtk/GraphRenderer.m \
- gtk/MainWindow.m \
gtk/Menu.m \
gtk/Node+Render.m \
gtk/NodeStyle+Gtk.m \
@@ -56,6 +56,7 @@ tikzit_SOURCES = gtk/CairoRenderContext.m \
gtk/StylesPane.m \
gtk/TikzDocument.m \
gtk/WidgetSurface.m \
+ gtk/Window.m \
gtk/cairo_helpers.m \
gtk/clipboard.m \
gtk/gtkhelpers.m \
diff --git a/tikzit/src/gtk/Application.h b/tikzit/src/gtk/Application.h
new file mode 100644
index 0000000..1967132
--- /dev/null
+++ b/tikzit/src/gtk/Application.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "TZFoundation.h"
+
+@class Application;
+@class Configuration;
+@class Preambles;
+@class PreambleEditor;
+@class PreviewWindow;
+@class SettingsDialog;
+@class StyleManager;
+@class TikzDocument;
+@class Window;
+
+extern Application* app;
+
+/**
+ * Manages the main application window
+ */
+@interface Application: NSObject {
+ // the main application configuration
+ Configuration *configFile;
+ // maintains the known (user-defined) styles
+ StyleManager *styleManager;
+ // maintains the preambles used for previews
+ Preambles *preambles;
+ // the last-accessed folders (for open and save dialogs)
+ NSString *lastOpenFolder;
+ NSString *lastSaveAsFolder;
+
+ // the open (active) document
+ TikzDocument *activeDocument;
+
+ PreambleEditor *preambleWindow;
+ PreviewWindow *previewWindow;
+ SettingsDialog *settingsDialog;
+
+ // the open windows (array of Window*)
+ NSMutableArray *openWindows;
+}
+
+/**
+ * The main application configuration file
+ */
+@property (readonly) Configuration *mainConfiguration;
+
+/**
+ * The app-wide style manager instance
+ */
+@property (readonly) StyleManager *styleManager;
+
+/**
+ * The app-wide preambles registry
+ */
+@property (readonly) Preambles *preambles;
+
+/**
+ * The document the user is currently editing
+ */
+@property (retain) TikzDocument *activeDocument;
+
+/**
+ * The folder last actively chosen by a user for opening a file
+ */
+@property (copy) NSString *lastOpenFolder;
+
+/**
+ * The folder last actively chosen by a user for saving a file
+ */
+@property (copy) NSString *lastSaveAsFolder;
+
+/**
+ * The application instance.
+ */
++ (Application*) app;
+
+/**
+ * Starts the application with a single window containing an empty file
+ */
+- (id) init;
+/**
+ * Starts the application with the given files open
+ */
+- (id) initWithFiles:(NSArray*)files;
+
+/**
+ * Loads a new, empty document in a new window
+ */
+- (void) newWindow;
+/**
+ * Loads an existing document from a file in a new window
+ *
+ * @param doc the document the new window should show
+ */
+- (void) newWindowWithDocument:(TikzDocument*)doc;
+/**
+ * Quit the application, confirming with the user if there are
+ * changes to any open documents.
+ */
+- (void) quit;
+
+/**
+ * Show the dialog for editing preambles.
+ */
+- (void) showPreamblesEditor;
+/**
+ * Show or update the preview window.
+ */
+- (void) showPreviewForDocument:(TikzDocument*)doc;
+/**
+ * Show the settings dialog.
+ */
+- (void) showSettingsDialog;
+
+/**
+ * Save the application configuration to permanent storage
+ *
+ * Should be called just before the application exits
+ */
+- (void) saveConfiguration;
+
+@end
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4
diff --git a/tikzit/src/gtk/Application.m b/tikzit/src/gtk/Application.m
new file mode 100644
index 0000000..2631bb3
--- /dev/null
+++ b/tikzit/src/gtk/Application.m
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2011-2012 Alex Merry <dev@randomguy3.me.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "Application.h"
+
+#import "Configuration.h"
+#import "PreambleEditor.h"
+#ifdef HAVE_POPPLER
+#import "Preambles.h"
+#import "Preambles+Storage.h"
+#import "PreviewWindow.h"
+#endif
+#ifdef HAVE_POPPLER
+#import "SettingsDialog.h"
+#endif
+#import "StyleManager.h"
+#import "StyleManager+Storage.h"
+#import "SupportDir.h"
+#import "TikzDocument.h"
+#import "Window.h"
+
+// used for args to g_mkdir_with_parents
+#import "stat.h"
+
+Application* app = nil;
+
+@interface Application (Notifications)
+- (void) windowClosed:(NSNotification*)notification;
+@end
+
+@implementation Application
+
+@synthesize mainConfiguration=configFile;
+@synthesize styleManager, preambles;
+@synthesize lastOpenFolder, lastSaveAsFolder;
+@synthesize activeDocument;
+
++ (Application*) app {
+ if (app == nil) {
+ [[[self alloc] init] release];
+ }
+ return app;
+}
+
+- (id) _initCommon {
+ if (app != nil) {
+ [self release];
+ self = app;
+ return app;
+ }
+ self = [super init];
+
+ if (self) {
+ NSError *error = nil;
+ configFile = [[Configuration alloc] initWithName:@"tikzit" loadError:&error];
+ if (error != nil) {
+ logError (error, @"WARNING: Failed to load configuration");
+ }
+
+ styleManager = [[StyleManager alloc] init];
+ [styleManager loadStylesUsingConfigurationName:@"styles"]; // FIXME: error message?
+
+#ifdef HAVE_POPPLER
+ NSString *preamblesDir = [[SupportDir userSupportDir] stringByAppendingPathComponent:@"preambles"];
+ preambles = [[Preambles alloc] initFromDirectory:preamblesDir]; // FIXME: error message?
+ [preambles setStyleManager:styleManager];
+ NSString *selectedPreamble = [configFile stringEntry:@"selectedPreamble" inGroup:@"Preambles"];
+ if (selectedPreamble != nil) {
+ [preambles setSelectedPreambleName:selectedPreamble];
+ }
+#endif
+
+ lastOpenFolder = [[configFile stringEntry:@"lastOpenFolder" inGroup:@"Paths"] retain];
+ if (lastOpenFolder == nil)
+ lastOpenFolder = [[configFile stringEntry:@"lastFolder" inGroup:@"Paths"] retain];
+ lastSaveAsFolder = [[configFile stringEntry:@"lastSaveAsFolder" inGroup:@"Paths"] retain];
+ if (lastSaveAsFolder == nil)
+ lastSaveAsFolder = [[configFile stringEntry:@"lastFolder" inGroup:@"Paths"] retain];
+
+ openWindows = [[NSMutableArray alloc] init];
+
+ // FIXME: toolboxes
+
+ app = [self retain];
+ }
+
+ return self;
+}
+
+- (id) init {
+ self = [self _initCommon];
+
+ if (self) {
+ [self newWindow];
+ }
+
+ return self;
+}
+
+- (id) initWithFiles:(NSArray*)files {
+ self = [self _initCommon];
+
+ if (self) {
+ int fileOpenCount = 0;
+ for (NSString *file in files) {
+ NSError *error = nil;
+ TikzDocument *doc = [TikzDocument documentFromFile:file styleManager:styleManager error:&error];
+ if (doc != nil) {
+ [self newWindowWithDocument:doc];
+ ++fileOpenCount;
+ } else {
+ logError(error, @"WARNING: failed to open file");
+ }
+ }
+ if (fileOpenCount == 0) {
+ [self newWindow];
+ }
+ }
+
+ return self;
+}
+
+- (void) dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [configFile release];
+ [styleManager release];
+ [preambles release];
+ [lastOpenFolder release];
+ [lastSaveAsFolder release];
+ [activeDocument release];
+ [preambleWindow release];
+ [previewWindow release];
+ [settingsDialog release];
+ [openWindows release];
+
+ [super dealloc];
+}
+
+- (void) newWindow {
+ [self newWindowWithDocument:nil];
+}
+
+- (void) newWindowWithDocument:(TikzDocument*)doc {
+ Window *window = (doc == nil)
+ ? [Window window]
+ : [Window windowWithDocument:doc];
+ [openWindows addObject:window];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(windowClosed:)
+ name:@"WindowClosed"
+ object:window];
+ // FIXME: focus?
+}
+
+- (void) quit {
+ NSMutableArray *unsavedDocs = [NSMutableArray arrayWithCapacity:[openWindows count]];
+ for (Window *window in openWindows) {
+ TikzDocument *doc = [window document];
+ if ([doc hasUnsavedChanges]) {
+ [unsavedDocs addObject:doc];
+ }
+ }
+ if ([unsavedDocs count] > 0) {
+ // FIXME: show a dialog
+ return;
+ }
+ gtk_main_quit();
+}
+
+- (void) showPreamblesEditor {
+#ifdef HAVE_POPPLER
+ if (preambleWindow == nil) {
+ preambleWindow = [[PreambleEditor alloc] initWithPreambles:preambles];
+ //[preambleWindow setParentWindow:mainWindow];
+ }
+ [preambleWindow show];
+#endif
+}
+
+- (void) showPreviewForDocument:(TikzDocument*)doc {
+#ifdef HAVE_POPPLER
+ if (previewWindow == nil) {
+ previewWindow = [[PreviewWindow alloc] initWithPreambles:preambles config:configFile];
+ //[previewWindow setParentWindow:mainWindow];
+ [previewWindow setDocument:doc];
+ }
+ [previewWindow show];
+#endif
+}
+
+- (void) showSettingsDialog {
+#ifdef HAVE_POPPLER
+ if (settingsDialog == nil) {
+ settingsDialog = [[SettingsDialog alloc] initWithConfiguration:configFile];
+ //[settingsDialog setParentWindow:mainWindow];
+ }
+ [settingsDialog show];
+#endif
+}
+
+- (Configuration*) mainConfiguration {
+ return configFile;
+}
+
+- (TikzDocument*) activeDocument {
+ return activeDocument;
+}
+
+- (void) saveConfiguration {
+ NSError *error = nil;
+
+#ifdef HAVE_POPPLER
+ if (preambles != nil) {
+ NSString *preamblesDir = [[SupportDir userSupportDir] stringByAppendingPathComponent:@"preambles"];
+ // NSFileManager is slightly dodgy on Windows
+ g_mkdir_with_parents ([preamblesDir UTF8String], S_IRUSR | S_IWUSR | S_IXUSR);
+ [preambles storeToDirectory:preamblesDir];
+ [configFile setStringEntry:@"selectedPreamble" inGroup:@"Preambles" value:[preambles selectedPreambleName]];
+ }
+#endif
+
+ [styleManager saveStylesUsingConfigurationName:@"styles"];
+
+ if (lastOpenFolder != nil) {
+ [configFile setStringEntry:@"lastOpenFolder" inGroup:@"Paths" value:lastOpenFolder];
+ }
+ if (lastSaveAsFolder != nil) {
+ [configFile setStringEntry:@"lastSaveAsFolder" inGroup:@"Paths" value:lastSaveAsFolder];
+ }
+
+ if (![configFile writeToStoreWithError:&error]) {
+ logError (error, @"Could not write config file");
+ }
+}
+
+@end
+
+@implementation Application (Notifications)
+- (void) windowClosed:(NSNotification*)notification {
+ Window *window = [notification object];
+ [openWindows removeObjectIdenticalTo:window];
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:nil
+ object:window];
+ if ([openWindows count] == 0) {
+ gtk_main_quit();
+ } else if ([[window document] isEqual:activeDocument]) {
+ [self setActiveDocument:[[openWindows objectAtIndex:0] document]];
+ }
+}
+@end
+
+// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker
diff --git a/tikzit/src/gtk/GraphInputHandler.h b/tikzit/src/gtk/GraphInputHandler.h
index 7277e82..caf1528 100644
--- a/tikzit/src/gtk/GraphInputHandler.h
+++ b/tikzit/src/gtk/GraphInputHandler.h
@@ -20,8 +20,6 @@
#import "InputDelegate.h"
#import "StyleManager.h"
-@class MainWindow;
-
typedef enum {
SelectMode,
CreateNodeMode,
@@ -43,7 +41,6 @@ typedef enum {
} MouseState;
@interface GraphInputHandler: NSObject {
- MainWindow *window;
GraphRenderer *renderer;
InputMode mode;
MouseState state;
@@ -60,7 +57,7 @@ typedef enum {
@property (assign) float edgeFuzz;
@property (assign) InputMode mode;
-- (id) initWithGraphRenderer:(GraphRenderer*)r window:(MainWindow*)w;
+- (id) initWithGraphRenderer:(GraphRenderer*)r;
- (void) resetState;
diff --git a/tikzit/src/gtk/GraphInputHandler.m b/tikzit/src/gtk/GraphInputHandler.m
index 02d39a1..788dfeb 100644
--- a/tikzit/src/gtk/GraphInputHandler.m
+++ b/tikzit/src/gtk/GraphInputHandler.m
@@ -18,25 +18,15 @@
#import "GraphInputHandler.h"
#import <gdk/gdkkeysyms.h>
-#import "MainWindow.h"
#import "Edge+Render.h"
static const InputMask unionSelectMask = ShiftMask;
-@interface GraphInputHandler (Notifications)
-- (void) nodeSelectionChanged:(NSNotification*)n;
-- (void) edgeSelectionChanged:(NSNotification*)n;
-@end
-
@implementation GraphInputHandler
- (id) initWithGraphRenderer:(GraphRenderer*)r {
- return [self initWithGraphRenderer:r window:nil];
-}
-- (id) initWithGraphRenderer:(GraphRenderer*)r window:(MainWindow*)w {
self = [super init];
if (self) {
- window = w;
renderer = r;
mode = SelectMode;
state = QuietState;
@@ -47,12 +37,6 @@ static const InputMask unionSelectMask = ShiftMask;
currentResizeHandle = NoHandle;
// FIXME: listen only to the doc's PickSupport
// (need to track document changes)
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(nodeSelectionChanged:)
- name:@"NodeSelectionChanged" object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(edgeSelectionChanged:)
- name:@"EdgeSelectionChanged" object:nil];
}
return self;
@@ -125,21 +109,6 @@ static const InputMask unionSelectMask = ShiftMask;
[self deselectAll];
if (mode == BoundingBoxMode) {
[renderer setBoundingBoxHandlesShown:YES];
- [window favourGraphControls];
- } else if (mode == CreateNodeMode) {
- [window favourNodeControls];
- } else if (mode == DrawEdgeMode) {
- [window favourEdgeControls];
- } else if (mode == HandMode) {
- [window favourGraphControls];
- } else if (mode == SelectMode) {
- // FIXME: also change on selection change
- if ([[[[self doc] pickSupport] selectedNodes] count])
- [window favourNodeControls];
- else if ([[[[self doc] pickSupport] selectedEdges] count])
- [window favourEdgeControls];
- else
- [window favourGraphControls];
}
}
}
@@ -497,28 +466,4 @@ static const InputMask unionSelectMask = ShiftMask;
@end
-@implementation GraphInputHandler (Notifications)
-- (void) nodeSelectionChanged:(NSNotification*)n {
- if (mode == SelectMode) {
- if ([[[[self doc] pickSupport] selectedNodes] count])
- [window favourNodeControls];
- else if ([[[[self doc] pickSupport] selectedEdges] count])
- [window favourEdgeControls];
- else
- [window favourGraphControls];
- }
-}
-
-- (void) edgeSelectionChanged:(NSNotification*)n {
- if (mode == SelectMode) {
- if ([[[[self doc] pickSupport] selectedNodes] count])
- [window favourNodeControls];
- else if ([[[[self doc] pickSupport] selectedEdges] count])
- [window favourEdgeControls];
- else
- [window favourGraphControls];
- }
-}
-@end
-
// vim:ft=objc:ts=8:et:sts=4:sw=4
diff --git a/tikzit/src/gtk/Menu.h b/tikzit/src/gtk/Menu.h
index 5a364e4..f195765 100644
--- a/tikzit/src/gtk/Menu.h
+++ b/tikzit/src/gtk/Menu.h
@@ -1,10 +1,6 @@
/*
* Copyright 2011 Alex Merry <alex.merry@kdemail.net>
*
- * Stuff stolen from glade-window.c in Glade:
- * Copyright (C) 2001 Ximian, Inc.
- * Copyright (C) 2007 Vincent Geddes.
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
@@ -22,14 +18,14 @@
#import "TZFoundation.h"
#import <gtk/gtk.h>
-@class MainWindow;
+@class Window;
@class PickSupport;
/**
- * Manages the menu and toolbar for the main window.
+ * Manages the menu
*/
@interface Menu: NSObject {
- MainWindow *mainWindow;
+ Window *window;
GtkUIManager *ui;
GtkActionGroup *staticActions;
GtkActionGroup *documentActions;
@@ -46,25 +42,20 @@
}
/**
- * Constructs the menu and toolbar for @p window
- *
- * @param window the mainwindow that will be acted upon by the various
- * menu items and toolbar buttons.
+ * The menubar widget, to be inserted into the window
*/
-- (id) initForMainWindow:(MainWindow*)window;
-
+@property (readonly) GtkWidget *menubar;
/**
- * The menubar widget, to be inserted into the main window
+ * The window object passed to initForWindow
*/
-- (GtkWidget*) menubar;
-/**
- * The toolbar widget, to be inserted into the main window
- */
-- (GtkWidget*) toolbar;
+@property (readonly) Window *window;
+
/**
- * The main window object passed to initForMainWindow
+ * Constructs the menu for @p window
+ *
+ * @param window the window that will be acted upon
*/
-- (MainWindow*) mainWindow;
+- (id) initForWindow:(Window*)window;
/**
* Enables or disables the undo action
diff --git a/tikzit/src/gtk/Menu.m b/tikzit/src/gtk/Menu.m
index b99336d..c6f2fde 100644
--- a/tikzit/src/gtk/Menu.m
+++ b/tikzit/src/gtk/Menu.m
@@ -21,7 +21,8 @@
#import "Menu.h"
-#import "MainWindow.h"
+#import "Application.h"
+#import "Window.h"
#import "GraphInputHandler.h"
#import "Configuration.h"
#import "PickSupport.h"
@@ -51,49 +52,49 @@
// {{{ Callbacks
-static void new_cb (GtkAction *action, MainWindow *window) {
+static void new_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window loadEmptyDocument];
+ [app newWindow];
[pool drain];
}
-static void open_cb (GtkAction *action, MainWindow *window) {
+static void open_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window openFile];
[pool drain];
}
-static void save_cb (GtkAction *action, MainWindow *window) {
+static void save_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window saveActiveDocument];
[pool drain];
}
-static void save_as_cb (GtkAction *action, MainWindow *window) {
+static void save_as_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window saveActiveDocumentAs];
[pool drain];
}
-static void save_as_shape_cb (GtkAction *action, MainWindow *window) {
+static void save_as_shape_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window saveActiveDocumentAsShape];
[pool drain];
}
-static void refresh_shapes_cb (GtkAction *action, MainWindow *window) {
+static void refresh_shapes_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[Shape refreshShapeDictionary];
[pool drain];
}
-static void quit_cb (GtkAction *action, MainWindow *window) {
+static void quit_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window quit];
+ [app quit];
[pool drain];
}
-static void help_cb (GtkAction *action, MainWindow *window) {
+static void help_cb (GtkAction *action, Window *window) {
GError *gerror = NULL;
gtk_show_uri (NULL, "http://tikzit.sourceforge.net/manual.html", GDK_CURRENT_TIME, &gerror);
if (gerror != NULL) {
@@ -103,7 +104,7 @@ static void help_cb (GtkAction *action, MainWindow *window) {
}
}
-static void about_cb (GtkAction *action, MainWindow *window) {
+static void about_cb (GtkAction *action, Window *window) {
static const gchar * const authors[] =
{ "Aleks Kissinger <aleks0@gmail.com>",
"Chris Heunen <chrisheunen@gmail.com>",
@@ -145,10 +146,10 @@ static void about_cb (GtkAction *action, MainWindow *window) {
g_object_unref (logo);
}
-static void undo_cb (GtkAction *action, MainWindow *window) {
+static void undo_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- TikzDocument *document = [window activeDocument];
+ TikzDocument *document = [window document];
if ([document canUndo]) {
[document undo];
} else {
@@ -159,10 +160,10 @@ static void undo_cb (GtkAction *action, MainWindow *window) {
[pool drain];
}
-static void redo_cb (GtkAction *action, MainWindow *window) {
+static void redo_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- TikzDocument *document = [window activeDocument];
+ TikzDocument *document = [window document];
if ([document canRedo]) {
[document redo];
} else {
@@ -173,132 +174,133 @@ static void redo_cb (GtkAction *action, MainWindow *window) {
[pool drain];
}
-static void cut_cb (GtkAction *action, MainWindow *window) {
+static void cut_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window cut];
[pool drain];
}
-static void copy_cb (GtkAction *action, MainWindow *window) {
+static void copy_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window copy];
[pool drain];
}
-static void paste_cb (GtkAction *action, MainWindow *window) {
+static void paste_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window paste];
[pool drain];
}
-static void delete_cb (GtkAction *action, MainWindow *window) {
+static void delete_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] removeSelected];
+ [[window document] removeSelected];
[pool drain];
}
-static void select_all_cb (GtkAction *action, MainWindow *window) {
+static void select_all_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- TikzDocument *document = [window activeDocument];
+ TikzDocument *document = [window document];
[[document pickSupport] selectAllNodes:[NSSet setWithArray:[[document graph] nodes]]];
[pool drain];
}
-static void deselect_all_cb (GtkAction *action, MainWindow *window) {
+static void deselect_all_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- TikzDocument *document = [window activeDocument];
+ TikzDocument *document = [window document];
[[document pickSupport] deselectAllNodes];
[[document pickSupport] deselectAllEdges];
[pool drain];
}
-static void flip_horiz_cb (GtkAction *action, MainWindow *window) {
+static void flip_horiz_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] flipSelectedNodesHorizontally];
+ [[window document] flipSelectedNodesHorizontally];
[pool drain];
}
-static void flip_vert_cb (GtkAction *action, MainWindow *window) {
+static void flip_vert_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] flipSelectedNodesVertically];
+ [[window document] flipSelectedNodesVertically];
[pool drain];
}
-static void reverse_edges_cb (GtkAction *action, MainWindow *window) {
+static void reverse_edges_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] reverseSelectedEdges];
+ [[window document] reverseSelectedEdges];
[pool drain];
}
-static void bring_forward_cb (GtkAction *action, MainWindow *window) {
+static void bring_forward_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] bringSelectionForward];
+ [[window document] bringSelectionForward];
[pool drain];
}
-static void send_backward_cb (GtkAction *action, MainWindow *window) {
+static void send_backward_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] sendSelectionBackward];
+ [[window document] sendSelectionBackward];
[pool drain];
}
-static void bring_to_front_cb (GtkAction *action, MainWindow *window) {
+static void bring_to_front_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] bringSelectionToFront];
+ [[window document] bringSelectionToFront];
[pool drain];
}
-static void send_to_back_cb (GtkAction *action, MainWindow *window) {
+static void send_to_back_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [[window activeDocument] sendSelectionToBack];
+ [[window document] sendSelectionToBack];
[pool drain];
}
#ifdef HAVE_POPPLER
-static void show_preferences_cb (GtkAction *action, MainWindow *window) {
+static void show_preferences_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window showSettingsDialog];
+ [app showSettingsDialog];
[pool drain];
}
-static void show_preamble_cb (GtkAction *action, MainWindow *window) {
+static void show_preamble_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window editPreambles];
+ [app showPreamblesEditor];
[pool drain];
}
-static void show_preview_cb (GtkAction *action, MainWindow *window) {
+static void show_preview_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window showPreview];
+ [app showPreviewForDocument:[window document]];
[pool drain];
}
#endif
-static void zoom_in_cb (GtkAction *action, MainWindow *window) {
+static void zoom_in_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window zoomIn];
[pool drain];
}
-static void zoom_out_cb (GtkAction *action, MainWindow *window) {
+static void zoom_out_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window zoomOut];
[pool drain];
}
-static void zoom_reset_cb (GtkAction *action, MainWindow *window) {
+static void zoom_reset_cb (GtkAction *action, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window zoomReset];
[pool drain];
}
-static void input_mode_change_cb (GtkRadioAction *action, GtkRadioAction *current, MainWindow *window) {
+static void input_mode_change_cb (GtkRadioAction *action, GtkRadioAction *current, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
InputMode mode = (InputMode)gtk_radio_action_get_current_value (action);
[[window graphInputHandler] setMode:mode];
[pool drain];
}
+/*
static void toolbar_style_change_cb (GtkRadioAction *action, GtkRadioAction *current, Menu *menu) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -308,8 +310,9 @@ static void toolbar_style_change_cb (GtkRadioAction *action, GtkRadioAction *cur
[pool drain];
}
+*/
-static void recent_chooser_item_activated_cb (GtkRecentChooser *chooser, MainWindow *window) {
+static void recent_chooser_item_activated_cb (GtkRecentChooser *chooser, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
gchar *uri, *path;
@@ -324,13 +327,7 @@ static void recent_chooser_item_activated_cb (GtkRecentChooser *chooser, MainWin
return;
}
- NSString *nspath = [NSString stringWithGlibFilename:path];
- if (error) {
- g_warning ("Could not convert filename \"%s\" to an NSString: %s", path, error->message);
- g_error_free (error);
- return;
- }
- [window loadDocumentFromFile:nspath];
+ [window openFileAtPath:[NSString stringWithGlibFilename:path]];
g_free (uri);
g_free (path);
@@ -396,12 +393,14 @@ static const gchar ui_info[] =
#endif
" </menu>"
" <menu action='ViewMenu'>"
+/*
" <menu action='ToolbarStyle'>"
" <menuitem action='ToolbarIconsOnly'/>"
" <menuitem action='ToolbarTextOnly'/>"
" <menuitem action='ToolbarTextIcons'/>"
" <menuitem action='ToolbarTextIconsHoriz'/>"
" </menu>"
+*/
/*
" <menuitem action='ToolbarVisible'/>"
" <menuitem action='StatusbarVisible'/>"
@@ -427,6 +426,7 @@ static const gchar ui_info[] =
" <menuitem action='About'/>"
" </menu>"
" </menubar>"
+/*
" <toolbar name='ToolBar'>"
" <toolitem action='New'/>"
" <toolitem action='Open'/>"
@@ -442,6 +442,7 @@ static const gchar ui_info[] =
" <toolitem action='BoundingBoxMode'/>"
" <toolitem action='HandMode'/>"
" </toolbar>"
+*/
"</ui>";
@@ -493,7 +494,7 @@ static GtkActionEntry static_entries[] = {
#endif
/* ViewMenu */
- { "ToolbarStyle", NULL, N_("_Toolbar style") },
+ //{ "ToolbarStyle", NULL, N_("_Toolbar style") },
#ifdef HAVE_POPPLER
{ "ShowPreamble", NULL, N_("_Edit Preambles..."), NULL,
@@ -694,14 +695,19 @@ create_recent_chooser_menu ()
@implementation Menu
-- (id) initForMainWindow:(MainWindow*)window
-{
+- (id) init {
+ [self release];
+ self = nil;
+ return nil;
+}
+
+- (id) initForWindow:(Window*)w {
self = [super init];
if (!self) {
return nil;
}
- mainWindow = window;
+ window = w;
GError *error = NULL;
@@ -715,11 +721,13 @@ create_recent_chooser_menu ()
gtk_action_group_add_radio_actions (staticActions, mode_entries,
n_mode_entries, (gint)SelectMode,
G_CALLBACK (input_mode_change_cb), window);
+ /*
GtkToolbarStyle style;
g_object_get (G_OBJECT (gtk_settings_get_default ()), "gtk-toolbar-style", &style, NULL);
gtk_action_group_add_radio_actions (staticActions, toolbar_style_entries,
n_toolbar_style_entries, style,
G_CALLBACK (toolbar_style_change_cb), self);
+ */
documentActions = gtk_action_group_new (ACTION_GROUP_DOCUMENT);
//gtk_action_group_set_translation_domain (documentActions, GETTEXT_PACKAGE);
@@ -752,11 +760,13 @@ create_recent_chooser_menu ()
}
/* Set custom images for tool mode buttons */
+ /*
set_tool_button_image (GTK_TOOL_BUTTON (gtk_ui_manager_get_widget (ui, "/ToolBar/SelectMode")), &select_rectangular);
set_tool_button_image (GTK_TOOL_BUTTON (gtk_ui_manager_get_widget (ui, "/ToolBar/CreateNodeMode")), &draw_ellipse);
set_tool_button_image (GTK_TOOL_BUTTON (gtk_ui_manager_get_widget (ui, "/ToolBar/DrawEdgeMode")), &draw_path);
set_tool_button_image (GTK_TOOL_BUTTON (gtk_ui_manager_get_widget (ui, "/ToolBar/BoundingBoxMode")), &transform_crop_and_resize);
set_tool_button_image (GTK_TOOL_BUTTON (gtk_ui_manager_get_widget (ui, "/ToolBar/HandMode")), &transform_move);
+ */
/* Save the undo and redo actions so they can be updated */
undoAction = gtk_action_group_get_action (documentActions, "Undo");
@@ -783,28 +793,37 @@ create_recent_chooser_menu ()
selBasedActions[0] = gtk_action_group_get_action (documentActions, "Delete");
selBasedActions[1] = gtk_action_group_get_action (documentActions, "DeselectAll");
- Configuration *configFile = [window mainConfiguration];
+ /*
+ Configuration *configFile = [app mainConfiguration];
if ([configFile hasKey:@"toolbarStyle" inGroup:@"UI"]) {
int value = [configFile integerEntry:@"toolbarStyle" inGroup:@"UI"];
gtk_radio_action_set_current_value (
GTK_RADIO_ACTION (gtk_action_group_get_action (staticActions, "ToolbarIconsOnly")),
value);
}
+ */
return self;
}
+- (void) dealloc {
+ g_free (nodeSelBasedActions);
+ g_free (selBasedActions);
+
+ [super dealloc];
+}
+
- (GtkWidget*) menubar {
return gtk_ui_manager_get_widget (ui, "/MenuBar");
}
+/*
- (GtkWidget*) toolbar {
return gtk_ui_manager_get_widget (ui, "/ToolBar");
}
+*/
-- (MainWindow*) mainWindow {
- return mainWindow;
-}
+@synthesize window;
- (void) setUndoActionEnabled:(BOOL)enabled {
gtk_action_set_sensitive (undoAction, enabled);
@@ -846,13 +865,6 @@ create_recent_chooser_menu ()
}
}
-- (void) dealloc {
- g_free (nodeSelBasedActions);
- g_free (selBasedActions);
-
- [super dealloc];
-}
-
@end
// }}}
diff --git a/tikzit/src/gtk/MainWindow.h b/tikzit/src/gtk/Window.h
index 3133d77..6aa710a 100644
--- a/tikzit/src/gtk/MainWindow.h
+++ b/tikzit/src/gtk/Window.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Alex Merry <dev@randomguy3.me.uk>
+ * Copyright 2011-2012 Alex Merry <dev@randomguy3.me.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -19,7 +19,6 @@
#import <gtk/gtk.h>
#import "WidgetSurface.h"
-@class Configuration;
@class GraphRenderer;
@class GraphInputHandler;
@class Menu;
@@ -33,79 +32,69 @@
@class TikzDocument;
/**
- * Manages the main application window
+ * Manages a document window
*/
-@interface MainWindow: NSObject {
- // the main application configuration
- Configuration *configFile;
- // maintains the known (user-defined) styles
- StyleManager *styleManager;
- // maintains the preambles used for previews
- Preambles *preambles;
-
+@interface Window: NSObject {
// GTK+ widgets
- GtkWindow *mainWindow;
+ GtkWindow *window;
GtkTextBuffer *tikzBuffer;
GtkStatusbar *statusBar;
GtkPaned *tikzPaneSplitter;
GtkWidget *tikzPane;
// Classes that manage parts of the window
- // (or other windows)
Menu *menu;
GraphRenderer *renderer;
GraphInputHandler *inputHandler;
- PreambleEditor *preambleWindow;
- PreviewWindow *previewWindow;
- SettingsDialog *settingsDialog;
WidgetSurface *surface;
// state variables
BOOL suppressTikzUpdates;
BOOL hasParseError;
- // the last-accessed folder (for open and save dialogs)
- NSString *lastFolder;
- // the open (active) document
+
+ // the document displayed by the window
TikzDocument *document;
}
/**
- * Create and show the main window.
+ * The document displayed by the window
+ */
+@property (retain) TikzDocument *document;
+
+/**
+ * Create a window with an empty document
*/
- (id) init;
++ (id) window;
+
+/**
+ * Create a window with the given document
+ */
+- (id) initWithDocument:(TikzDocument*)doc;
++ (id) windowWithDocument:(TikzDocument*)doc;
/**
* Open a file, asking the user which file to open
*/
- (void) openFile;
/**
+ * Open a file
+ */
+- (BOOL) openFileAtPath:(NSString*)path;
+/**
* Save the active document to the path it was opened from
* or last saved to, or ask the user where to save it.
*/
-- (void) saveActiveDocument;
+- (BOOL) saveActiveDocument;
/**
* Save the active document, asking the user where to save it.
*/
-- (void) saveActiveDocumentAs;
+- (BOOL) saveActiveDocumentAs;
/**
* Save the active document as a shape, asking the user what to name it.
*/
- (void) saveActiveDocumentAsShape;
-/**
- * Quit the application, confirming with the user if there are
- * changes to an open document.
- */
-- (void) quit;
-/**
- * If there are changes to an open document, ask the user if they
- * want to quit the application, discarding those changes.
- *
- * @result YES if there are no unsaved changes or the user is happy
- * to discard any unsaved changes, NO if the application
- * should not quit.
- */
-- (BOOL) askCanQuit;
/**
* Cut the current selection to the clipboard.
@@ -121,19 +110,6 @@
- (void) paste;
/**
- * Show the dialog for editing preambles.
- */
-- (void) editPreambles;
-/**
- * Show or update the preview window.
- */
-- (void) showPreview;
-/**
- * Show the settings dialog.
- */
-- (void) showSettingsDialog;
-
-/**
* The graph input handler
*/
- (GraphInputHandler*) graphInputHandler;
@@ -142,43 +118,19 @@
*/
- (GtkWindow*) gtkWindow;
/**
- * The main application configuration file
- */
-- (Configuration*) mainConfiguration;
-/**
* The menu for the window.
*/
- (Menu*) menu;
/**
- * The document the user is currently editing
- */
-- (TikzDocument*) activeDocument;
-
-/**
- * Loads a new, empty document as the active document
- */
-- (void) loadEmptyDocument;
-/**
- * Loads an existing document from a file as the active document
- *
- * @param path the path to the tikz file containing the document
- */
-- (void) loadDocumentFromFile:(NSString*)path;
-
-/**
* Present an error to the user
*
- * (currently just outputs it on the command line)
- *
* @param error the error to present
*/
- (void) presentError:(NSError*)error;
/**
* Present an error to the user
*
- * (currently just outputs it on the command line)
- *
* @param error the error to present
* @param message a message to display with the error
*/
@@ -186,36 +138,21 @@
/**
* Present an error to the user
*
- * (currently just outputs it on the command line)
- *
* @param error the error to present
*/
- (void) presentGError:(GError*)error;
/**
* Present an error to the user
*
- * (currently just outputs it on the command line)
- *
* @param error the error to present
* @param message a message to display with the error
*/
- (void) presentGError:(GError*)error withMessage:(NSString*)message;
-/**
- * Save the application configuration to disk
- *
- * Should be called just before the application exits
- */
-- (void) saveConfiguration;
-
- (void) zoomIn;
- (void) zoomOut;
- (void) zoomReset;
-- (void) favourGraphControls;
-- (void) favourNodeControls;
-- (void) favourEdgeControls;
-
@end
// vim:ft=objc:ts=8:et:sts=4:sw=4
diff --git a/tikzit/src/gtk/MainWindow.m b/tikzit/src/gtk/Window.m
index 6764bcf..f8e4aef 100644
--- a/tikzit/src/gtk/MainWindow.m
+++ b/tikzit/src/gtk/Window.m
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Alex Merry <dev@randomguy3.me.uk>
+ * Copyright 2011-2012 Alex Merry <dev@randomguy3.me.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,38 +15,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#import "MainWindow.h"
+#import "Window.h"
#import <gtk/gtk.h>
#import "gtkhelpers.h"
#import "clipboard.h"
+#import "Application.h"
#import "Configuration.h"
#import "FileChooserDialog.h"
#import "GraphInputHandler.h"
#import "GraphRenderer.h"
#import "Menu.h"
-#import "PreambleEditor.h"
-#ifdef HAVE_POPPLER
-#import "Preambles.h"
-#import "Preambles+Storage.h"
-#import "PreviewWindow.h"
-#endif
-#import "PropertyPane.h"
#import "RecentManager.h"
-#ifdef HAVE_POPPLER
-#import "SettingsDialog.h"
-#endif
#import "Shape.h"
-#import "StyleManager.h"
-#import "StyleManager+Storage.h"
-#import "StylesPane.h"
#import "SupportDir.h"
#import "TikzDocument.h"
#import "WidgetSurface.h"
-#import "stat.h"
-
// {{{ Internal interfaces
// {{{ Clipboard support
@@ -67,16 +53,16 @@ static void clipboard_paste_contents (GtkClipboard *clipboard,
// }}}
// {{{ Signals
-static void graph_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window);
-static void tikz_buffer_changed_cb (GtkTextBuffer *buffer, MainWindow *window);
-static gboolean main_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, MainWindow *window);
-static void main_window_destroy_cb (GtkWidget *widget, MainWindow *window);
-static gboolean main_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, MainWindow *window);
+static void graph_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, Window *window);
+static void tikz_buffer_changed_cb (GtkTextBuffer *buffer, Window *window);
+static gboolean main_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, Window *window);
+static void main_window_destroy_cb (GtkWidget *widget, Window *window);
+static gboolean main_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, Window *window);
static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAction *action);
// }}}
-@interface MainWindow (Notifications)
+@interface Window (Notifications)
- (void) tikzBufferChanged;
- (void) windowSizeChangedWidth:(int)width height:(int)height;
- (void) documentTikzChanged:(NSNotification*)notification;
@@ -84,18 +70,16 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
- (void) undoStackChanged:(NSNotification*)notification;
@end
-@interface MainWindow (InitHelpers)
-- (void) _loadConfig;
-- (void) _loadStyles;
-- (void) _loadPreambles;
+@interface Window (InitHelpers)
- (void) _loadUi;
- (void) _restoreUiState;
- (void) _connectSignals;
@end
-@interface MainWindow (Private)
-- (BOOL) _confirmCloseDocumentTo:(NSString*)action;
-- (void) _forceLoadDocumentFromFile:(NSString*)path;
+@interface Window (Private)
+- (BOOL) _askCanClose;
+/** Open a document, dealing with errors as necessary */
+- (TikzDocument*) _openDocument:(NSString*)path;
- (void) _placeGraphOnClipboard:(Graph*)graph;
- (void) _setHasParseError:(BOOL)hasError;
/** Update the window title. */
@@ -107,109 +91,149 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
/** Update the undo and redo actions to match the active document's
* undo stack. */
- (void) _updateUndoActions;
-/** Set the last-accessed folder */
-- (void) _setLastFolder:(NSString*)path;
-/** Set the active document */
-- (void) _setActiveDocument:(TikzDocument*)newDoc;
@end
// }}}
// {{{ API
-@implementation MainWindow
+@implementation Window
- (id) init {
+ return [self initWithDocument:[TikzDocument documentWithStyleManager:[app styleManager]]];
+}
++ (id) window {
+ return [[[self alloc] init] autorelease];
+}
+- (id) initWithDocument:(TikzDocument*)doc {
self = [super init];
if (self) {
- document = nil;
- preambles = nil;
- preambleWindow = nil;
- previewWindow = nil;
- settingsDialog = nil;
- suppressTikzUpdates = NO;
- hasParseError = NO;
-
- [self _loadConfig];
- [self _loadStyles];
- [self _loadPreambles];
- lastFolder = [[configFile stringEntry:@"lastFolder" inGroup:@"Paths"] retain];
[self _loadUi];
[self _restoreUiState];
[self _connectSignals];
- [self loadEmptyDocument];
+ [self setDocument:doc];
- gtk_widget_show (GTK_WIDGET (mainWindow));
+ gtk_widget_show (GTK_WIDGET (window));
}
return self;
}
++ (id) windowWithDocument:(TikzDocument*)doc {
+ return [[[self alloc] initWithDocument:doc] autorelease];
+}
- (void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
- [configFile release];
- [styleManager release];
- [preambles release];
+
[menu release];
[renderer release];
[inputHandler release];
- [preambleWindow release];
- [previewWindow release];
- [settingsDialog release];
[surface release];
- [lastFolder release];
[document release];
- g_object_unref (mainWindow);
g_object_unref (tikzBuffer);
- g_object_unref (statusBar);
- g_object_unref (tikzPaneSplitter);
g_object_unref (tikzPane);
+ g_object_unref (tikzPaneSplitter);
+ g_object_unref (statusBar);
+ g_object_unref (window);
[super dealloc];
}
-- (void) openFile {
- if (![self _confirmCloseDocumentTo:@"open a new document"]) {
- return;
+- (TikzDocument*) document {
+ return document;
+}
+- (void) setDocument:(TikzDocument*)newDoc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[document pickSupport]];
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:document];
+
+ [newDoc retain];
+ [document release];
+ document = newDoc;
+
+ [renderer setDocument:document];
+ [self _updateTikz];
+ [self _updateTitle];
+ [self _updateStatus];
+ [self _updateUndoActions];
+ [menu notifySelectionChanged:[document pickSupport]];
+ [inputHandler resetState];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(documentTikzChanged:)
+ name:@"TikzChanged" object:document];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(undoStackChanged:)
+ name:@"UndoStackChanged" object:document];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(documentSelectionChanged:)
+ name:@"NodeSelectionChanged" object:[document pickSupport]];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(documentSelectionChanged:)
+ name:@"EdgeSelectionChanged" object:[document pickSupport]];
+
+ if ([document path] != nil) {
+ [[RecentManager defaultManager] addRecentFile:[document path]];
}
- FileChooserDialog *dialog = [FileChooserDialog openDialogWithParent:mainWindow];
+}
+
+- (void) openFile {
+ FileChooserDialog *dialog = [FileChooserDialog openDialogWithParent:window];
[dialog addStandardFilters];
- if (lastFolder) {
- [dialog setCurrentFolder:lastFolder];
+ if ([document path]) {
+ [dialog setCurrentFolder:[document path]];
+ } else if ([app lastOpenFolder]) {
+ [dialog setCurrentFolder:[app lastOpenFolder]];
}
if ([dialog showDialog]) {
- [self _forceLoadDocumentFromFile:[dialog filePath]];
- [self _setLastFolder:[dialog currentFolder]];
+ if ([self openFileAtPath:[dialog filePath]]) {
+ [app setLastOpenFolder:[dialog currentFolder]];
+ }
}
[dialog destroy];
}
-- (void) saveActiveDocument {
+- (BOOL) openFileAtPath:(NSString*)path {
+ TikzDocument *doc = [self _openDocument:path];
+ if (doc != nil) {
+ if (![document hasUnsavedChanges] && [document path] == nil) {
+ // we just have a fresh, untitled document - replace it
+ [self setDocument:doc];
+ } else {
+ [app newWindowWithDocument:doc];
+ }
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL) saveActiveDocument {
if ([document path] == nil) {
- [self saveActiveDocumentAs];
+ return [self saveActiveDocumentAs];
} else {
NSError *error = nil;
if (![document save:&error]) {
[self presentError:error];
+ return NO;
} else {
[self _updateTitle];
+ return YES;
}
}
}
-- (void) saveActiveDocumentAs {
- FileChooserDialog *dialog = [FileChooserDialog saveDialogWithParent:mainWindow];
+- (BOOL) saveActiveDocumentAs {
+ FileChooserDialog *dialog = [FileChooserDialog saveDialogWithParent:window];
[dialog addStandardFilters];
if ([document path] != nil) {
[dialog setCurrentFolder:[[document path] stringByDeletingLastPathComponent]];
- } else if (lastFolder != nil) {
- [dialog setCurrentFolder:lastFolder];
+ } else if ([app lastSaveAsFolder] != nil) {
+ [dialog setCurrentFolder:[app lastSaveAsFolder]];
}
[dialog setSuggestedName:[document suggestedFileName]];
+ BOOL saved = NO;
if ([dialog showDialog]) {
NSString *nfile = [dialog filePath];
@@ -219,16 +243,18 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
} else {
[self _updateTitle];
[[RecentManager defaultManager] addRecentFile:nfile];
- [self _setLastFolder:[dialog currentFolder]];
+ [app setLastSaveAsFolder:[dialog currentFolder]];
+ saved = YES;
}
}
[dialog destroy];
+ return saved;
}
- (void) saveActiveDocumentAsShape {
GtkWidget *dialog = gtk_dialog_new_with_buttons (
"Save as shape",
- mainWindow,
+ window,
GTK_DIALOG_MODAL,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
@@ -253,7 +279,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
NSString *shapeName = [NSString stringWithUTF8String:dialogInput];
BOOL doSave = NO;
if ([shapeName isEqual:@""]) {
- GtkWidget *emptyStrDialog = gtk_message_dialog_new (mainWindow,
+ GtkWidget *emptyStrDialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -262,7 +288,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
gtk_widget_destroy (emptyStrDialog);
response = gtk_dialog_run (GTK_DIALOG (dialog));
} else if ([shapeDict objectForKey:shapeName] != nil) {
- GtkWidget *overwriteDialog = gtk_message_dialog_new (mainWindow,
+ GtkWidget *overwriteDialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
@@ -298,27 +324,6 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
gtk_widget_destroy (dialog);
}
-- (void) quit {
- if ([self askCanQuit]) {
- gtk_main_quit();
- }
-}
-
-- (BOOL) askCanQuit {
- if ([document hasUnsavedChanges]) {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "Are you sure you want to quit without saving the current file?");
- gint result = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- return (result == GTK_RESPONSE_YES) ? YES : NO;
- }
-
- return YES;
-}
-
- (void) cut {
if ([[[document pickSupport] selectedNodes] count] > 0) {
[self _placeGraphOnClipboard:[document cutSelection]];
@@ -338,73 +343,24 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
document);
}
-- (void) editPreambles {
-#ifdef HAVE_POPPLER
- if (preambleWindow == nil) {
- preambleWindow = [[PreambleEditor alloc] initWithPreambles:preambles];
- [preambleWindow setParentWindow:mainWindow];
- }
- [preambleWindow show];
-#endif
-}
-
-- (void) showPreview {
-#ifdef HAVE_POPPLER
- if (previewWindow == nil) {
- previewWindow = [[PreviewWindow alloc] initWithPreambles:preambles config:configFile];
- [previewWindow setParentWindow:mainWindow];
- [previewWindow setDocument:document];
- }
- [previewWindow show];
-#endif
-}
-
-- (void) showSettingsDialog {
-#ifdef HAVE_POPPLER
- if (settingsDialog == nil) {
- settingsDialog = [[SettingsDialog alloc] initWithConfiguration:configFile];
- [settingsDialog setParentWindow:mainWindow];
- }
- [settingsDialog show];
-#endif
-}
-
- (GraphInputHandler*) graphInputHandler {
return inputHandler;
}
- (GtkWindow*) gtkWindow {
- return mainWindow;
+ return window;
}
- (Configuration*) mainConfiguration {
- return configFile;
+ return [app mainConfiguration];
}
- (Menu*) menu {
return menu;
}
-- (TikzDocument*) activeDocument {
- return document;
-}
-
-- (void) loadEmptyDocument {
- if (![self _confirmCloseDocumentTo:@"start a new document"]) {
- return;
- }
- [self _setActiveDocument:[TikzDocument documentWithStyleManager:styleManager]];
-}
-
-- (void) loadDocumentFromFile:(NSString*)path {
- if (![self _confirmCloseDocumentTo:@"open a new document"]) {
- return;
- }
- [self _forceLoadDocumentFromFile:path];
-}
-
- (void) presentError:(NSError*)error {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
+ GtkWidget *dialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -415,7 +371,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
}
- (void) presentError:(NSError*)error withMessage:(NSString*)message {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
+ GtkWidget *dialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -427,7 +383,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
}
- (void) presentGError:(GError*)error {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
+ GtkWidget *dialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -438,7 +394,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
}
- (void) presentGError:(GError*)error withMessage:(NSString*)message {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
+ GtkWidget *dialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -449,30 +405,6 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
gtk_widget_destroy (dialog);
}
-- (void) saveConfiguration {
- NSError *error = nil;
-
-#ifdef HAVE_POPPLER
- if (preambles != nil) {
- NSString *preamblesDir = [[SupportDir userSupportDir] stringByAppendingPathComponent:@"preambles"];
- // NSFileManager is slightly dodgy on Windows
- g_mkdir_with_parents ([preamblesDir UTF8String], S_IRUSR | S_IWUSR | S_IXUSR);
- [preambles storeToDirectory:preamblesDir];
- [configFile setStringEntry:@"selectedPreamble" inGroup:@"Preambles" value:[preambles selectedPreambleName]];
- }
-#endif
-
- [styleManager saveStylesUsingConfigurationName:@"styles"];
-
- if (lastFolder != nil) {
- [configFile setStringEntry:@"lastFolder" inGroup:@"Paths" value:lastFolder];
- }
-
- if (![configFile writeToStoreWithError:&error]) {
- logError (error, @"Could not write config file");
- }
-}
-
- (void) zoomIn {
[surface zoomIn];
}
@@ -485,23 +417,16 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
[surface zoomReset];
}
-- (void) favourGraphControls {
-}
-
-- (void) favourNodeControls {
-}
-
-- (void) favourEdgeControls {
-}
-
@end
// }}}
// {{{ Notifications
-@implementation MainWindow (Notifications)
+@implementation Window (Notifications)
- (void) graphHeightChanged:(int)newHeight {
- [configFile setIntegerEntry:@"graphHeight" inGroup:@"mainWindow" value:newHeight];
+ [[app mainConfiguration] setIntegerEntry:@"graphHeight"
+ inGroup:@"window"
+ value:newHeight];
}
- (void) tikzBufferChanged {
@@ -528,7 +453,9 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
NSMutableArray *size = [NSMutableArray arrayWithCapacity:2];
[size addObject:w];
[size addObject:h];
- [configFile setIntegerListEntry:@"windowSize" inGroup:@"mainWindow" value:size];
+ [[app mainConfiguration] setIntegerListEntry:@"windowSize"
+ inGroup:@"window"
+ value:size];
}
}
@@ -550,45 +477,19 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
// }}}
// {{{ InitHelpers
-@implementation MainWindow (InitHelpers)
-
-- (void) _loadConfig {
- NSError *error = nil;
- configFile = [[Configuration alloc] initWithName:@"tikzit" loadError:&error];
- if (error != nil) {
- logError (error, @"WARNING: Failed to load configuration");
- }
-}
-
-- (void) _loadStyles {
- styleManager = [[StyleManager alloc] init];
- [styleManager loadStylesUsingConfigurationName:@"styles"];
-}
-
-// must happen after _loadStyles
-- (void) _loadPreambles {
-#ifdef HAVE_POPPLER
- NSString *preamblesDir = [[SupportDir userSupportDir] stringByAppendingPathComponent:@"preambles"];
- preambles = [[Preambles alloc] initFromDirectory:preamblesDir];
- [preambles setStyleManager:styleManager];
- NSString *selectedPreamble = [configFile stringEntry:@"selectedPreamble" inGroup:@"Preambles"];
- if (selectedPreamble != nil) {
- [preambles setSelectedPreambleName:selectedPreamble];
- }
-#endif
-}
+@implementation Window (InitHelpers)
- (void) _loadUi {
- mainWindow = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
- g_object_ref_sink (mainWindow);
- gtk_window_set_title (mainWindow, "TikZiT");
- gtk_window_set_default_size (mainWindow, 700, 400);
+ window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
+ g_object_ref_sink (window);
+ gtk_window_set_title (window, "TikZiT");
+ gtk_window_set_default_size (window, 700, 400);
GtkBox *mainLayout = GTK_BOX (gtk_vbox_new (FALSE, 0));
gtk_widget_show (GTK_WIDGET (mainLayout));
- gtk_container_add (GTK_CONTAINER (mainWindow), GTK_WIDGET (mainLayout));
+ gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (mainLayout));
- menu = [[Menu alloc] initForMainWindow:self];
+ menu = [[Menu alloc] initForWindow:self];
GtkWidget *menubar = [menu menubar];
gtk_box_pack_start (mainLayout, menubar, FALSE, TRUE, 0);
@@ -611,7 +512,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
[surface setGrabsFocusOnClick:YES];
renderer = [[GraphRenderer alloc] initWithSurface:surface document:document];
- inputHandler = [[GraphInputHandler alloc] initWithGraphRenderer:renderer window:self];
+ inputHandler = [[GraphInputHandler alloc] initWithGraphRenderer:renderer];
[surface setInputDelegate:inputHandler];
tikzBuffer = gtk_text_buffer_new (NULL);
@@ -631,6 +532,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
gtk_paned_pack2 (tikzPaneSplitter, tikzFrame, FALSE, TRUE);
statusBar = GTK_STATUSBAR (gtk_statusbar_new ());
+ g_object_ref_sink (statusBar);
gtk_widget_show (GTK_WIDGET (statusBar));
gtk_box_pack_start (mainLayout, GTK_WIDGET (statusBar), FALSE, TRUE, 0);
@@ -639,15 +541,18 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
}
- (void) _restoreUiState {
- NSArray *windowSize = [configFile integerListEntry:@"windowSize" inGroup:@"mainWindow"];
+ Configuration *config = [app mainConfiguration];
+ NSArray *windowSize = [config integerListEntry:@"windowSize"
+ inGroup:@"window"];
if (windowSize && [windowSize count] == 2) {
gint width = [[windowSize objectAtIndex:0] intValue];
gint height = [[windowSize objectAtIndex:1] intValue];
if (width > 0 && height > 0) {
- gtk_window_set_default_size (mainWindow, width, height);
+ gtk_window_set_default_size (window, width, height);
}
}
- int panePos = [configFile integerEntry:@"graphHeight" inGroup:@"mainWindow"];
+ int panePos = [config integerEntry:@"graphHeight"
+ inGroup:@"window"];
if (panePos > 0) {
gtk_paned_set_position (tikzPaneSplitter, panePos);
}
@@ -659,7 +564,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
"owner-change",
G_CALLBACK (update_paste_action),
[menu pasteAction]);
- g_signal_connect (G_OBJECT (mainWindow),
+ g_signal_connect (G_OBJECT (window),
"key-press-event",
G_CALLBACK (tz_hijack_key_press),
NULL);
@@ -671,15 +576,15 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
"changed",
G_CALLBACK (tikz_buffer_changed_cb),
self);
- g_signal_connect (G_OBJECT (mainWindow),
+ g_signal_connect (G_OBJECT (window),
"delete-event",
G_CALLBACK (main_window_delete_event_cb),
self);
- g_signal_connect (G_OBJECT (mainWindow),
+ g_signal_connect (G_OBJECT (window),
"destroy",
G_CALLBACK (main_window_destroy_cb),
self);
- g_signal_connect (G_OBJECT (mainWindow),
+ g_signal_connect (G_OBJECT (window),
"configure-event",
G_CALLBACK (main_window_configure_event_cb),
self);
@@ -689,32 +594,40 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
// }}}
// {{{ Private
-@implementation MainWindow (Private)
+@implementation Window (Private)
-- (BOOL) _confirmCloseDocumentTo:(NSString*)action {
- BOOL proceed = YES;
+- (BOOL) _askCanClose {
if ([document hasUnsavedChanges]) {
- NSString *message = [NSString stringWithFormat:@"You have unsaved changes to the current document, which will be lost if you %@. Are you sure you want to continue?", action];
- GtkWidget *dialog = gtk_message_dialog_new (NULL,
+ GtkWidget *dialog = gtk_message_dialog_new (window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "%s", [message UTF8String]);
- gtk_window_set_title(GTK_WINDOW(dialog), "Close current document?");
- proceed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
- gtk_widget_destroy (dialog);
+ GTK_BUTTONS_NONE,
+ "Save changes to the document \"%s\" before closing?",
+ [[document name] UTF8String]);
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ "Save", GTK_RESPONSE_YES,
+ "Don't save", GTK_RESPONSE_NO,
+ "Cancel", GTK_RESPONSE_CANCEL,
+ NULL);
+ gint result = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (result == GTK_RESPONSE_YES) {
+ return [self saveActiveDocument];
+ } else {
+ return result == GTK_RESPONSE_NO;
+ }
+ } else {
+ return YES;
}
- return proceed;
}
-- (void) _forceLoadDocumentFromFile:(NSString*)path {
+- (TikzDocument*) _openDocument:(NSString*)path {
NSError *error = nil;
TikzDocument *d = [TikzDocument documentFromFile:path
- styleManager:styleManager
+ styleManager:[app styleManager]
error:&error];
if (d != nil) {
- [self _setActiveDocument:d];
- [[RecentManager defaultManager] addRecentFile:path];
+ return d;
} else {
if ([error code] == TZ_ERR_PARSE) {
[self presentError:error withMessage:@"Invalid file"];
@@ -722,6 +635,7 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
[self presentError:error withMessage:@"Could not open file"];
}
[[RecentManager defaultManager] removeRecentFile:path];
+ return nil;
}
}
@@ -763,10 +677,11 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
NSString *title = [NSString stringWithFormat:@"TikZiT - %@%s",
[document name],
([document hasUnsavedChanges] ? "*" : "")];
- gtk_window_set_title(mainWindow, [title UTF8String]);
+ gtk_window_set_title(window, [title UTF8String]);
}
- (void) _updateStatus {
+ // FIXME: show tooltips or something instead
GString *buffer = g_string_sized_new (30);
gchar *nextNode = 0;
@@ -819,50 +734,12 @@ static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAc
}
}
-- (void) _setLastFolder:(NSString*)path {
- [path retain];
- [lastFolder release];
- lastFolder = path;
-}
-
-- (void) _setActiveDocument:(TikzDocument*)newDoc {
- [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[document pickSupport]];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:document];
-
- [newDoc retain];
- [document release];
- document = newDoc;
-
- [renderer setDocument:document];
-#ifdef HAVE_POPPLER
- [previewWindow setDocument:document];
-#endif
- [self _updateTikz];
- [self _updateTitle];
- [self _updateStatus];
- [self _updateUndoActions];
- [menu notifySelectionChanged:[document pickSupport]];
- [inputHandler resetState];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(documentTikzChanged:)
- name:@"TikzChanged" object:document];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(undoStackChanged:)
- name:@"UndoStackChanged" object:document];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(documentSelectionChanged:)
- name:@"NodeSelectionChanged" object:[document pickSupport]];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(documentSelectionChanged:)
- name:@"EdgeSelectionChanged" object:[document pickSupport]];
-}
-
@end
// }}}
// {{{ GTK+ callbacks
-static void graph_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window) {
+static void graph_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
gint position;
g_object_get (gobject, "position", &position, NULL);
@@ -870,23 +747,27 @@ static void graph_divider_position_changed_cb (GObject *gobject, GParamSpec *psp
[pool drain];
}
-static void tikz_buffer_changed_cb (GtkTextBuffer *buffer, MainWindow *window) {
+static void tikz_buffer_changed_cb (GtkTextBuffer *buffer, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window tikzBufferChanged];
[pool drain];
}
-static gboolean main_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, MainWindow *window) {
+static gboolean main_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- return ![window askCanQuit];
+ BOOL canClose = ![window _askCanClose];
[pool drain];
+ return canClose;
}
-static void main_window_destroy_cb (GtkWidget *widget, MainWindow *window) {
- gtk_main_quit();
+static void main_window_destroy_cb (GtkWidget *widget, Window *window) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"WindowClosed"
+ object:window];
+ [pool drain];
}
-static gboolean main_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, MainWindow *window) {
+static gboolean main_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, Window *window) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[window windowSizeChangedWidth:event->width height:event->height];
[pool drain];
diff --git a/tikzit/src/gtk/main.m b/tikzit/src/gtk/main.m
index 93aa9e4..9d179ab 100644
--- a/tikzit/src/gtk/main.m
+++ b/tikzit/src/gtk/main.m
@@ -26,9 +26,15 @@
#import "clipboard.h"
#import "logo.h"
-#import "MainWindow.h"
+#import "Application.h"
#import "TikzGraphAssembler.h"
+static GOptionEntry entries[] =
+{
+ //{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
+ { NULL }
+};
+
void onUncaughtException(NSException* exception)
{
NSLog(@"uncaught exception: %@", [exception description]);
@@ -39,9 +45,20 @@ int main (int argc, char *argv[]) {
[[NSAutoreleasePool alloc] init];
- gtk_init (&argc, &argv);
-
- NSAutoreleasePool *initPool = [[NSAutoreleasePool alloc] init];
+ GError *error = NULL;
+ GOptionContext *context;
+ context = g_option_context_new ("[FILES] - PGF/TikZ-based graph editor");
+ g_option_context_add_main_entries (context, entries, NULL);
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ if (error->domain == G_OPTION_ERROR) {
+ g_print ("%s\nUse --help to see available options\n", error->message);
+ } else {
+ g_print ("Unexpected error parsing options: %s\n", error->message);
+ }
+ exit (1);
+ }
#ifndef WINDOWS
GList *icon_list = NULL;
@@ -59,15 +76,29 @@ int main (int argc, char *argv[]) {
}
#endif
+ NSAutoreleasePool *initPool = [[NSAutoreleasePool alloc] init];
+
clipboard_init();
[TikzGraphAssembler setup];
- MainWindow *window = [[MainWindow alloc] init];
+
+ Application *app = nil;
+ if (argc > 1) {
+ NSMutableArray *files = [NSMutableArray arrayWithCapacity:argc-1];
+ for (int i = 1; i < argc; ++i) {
+ [files insertObject:[NSString stringWithGlibFilename:argv[i]]
+ atIndex:i-1];
+ }
+ NSLog(@"Files: %@", files);
+ app = [[Application alloc] initWithFiles:files];
+ } else {
+ app = [[Application alloc] init];
+ }
[initPool drain];
gtk_main ();
- [window saveConfiguration];
+ [app saveConfiguration];
return 0;
}