summaryrefslogtreecommitdiff
path: root/src/linux/MainWindow.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/linux/MainWindow.m')
-rw-r--r--src/linux/MainWindow.m997
1 files changed, 0 insertions, 997 deletions
diff --git a/src/linux/MainWindow.m b/src/linux/MainWindow.m
deleted file mode 100644
index ecaf1fa..0000000
--- a/src/linux/MainWindow.m
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * Copyright 2011 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 "MainWindow.h"
-
-#import <gtk/gtk.h>
-#import "gtkhelpers.h"
-#import "clipboard.h"
-
-#import "Configuration.h"
-#import "FileChooserDialog.h"
-#import "GraphInputHandler.h"
-#import "GraphRenderer.h"
-#import "Menu.h"
-#import "PreambleEditor.h"
-#import "Preambles.h"
-#import "Preambles+Storage.h"
-#ifdef HAVE_POPPLER
-#import "PreviewWindow.h"
-#endif
-#import "PropertyPane.h"
-#import "RecentManager.h"
-#import "StyleManager.h"
-#import "Shape.h"
-#import "StyleManager+Storage.h"
-#import "NodeStylesPalette.h"
-#import "SupportDir.h"
-#import "TikzDocument.h"
-#import "WidgetSurface.h"
-
-
-// {{{ Internal interfaces
-// {{{ Clipboard support
-
-static void clipboard_provide_data (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer clipboard_graph_data);
-static void clipboard_release_data (GtkClipboard *clipboard, gpointer clipboard_graph_data);
-static void clipboard_check_targets (GtkClipboard *clipboard,
- GdkAtom *atoms,
- gint n_atoms,
- gpointer action);
-static void clipboard_paste_contents (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- gpointer document);
-
-// }}}
-// {{{ Signals
-
-static void toolbox_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window);
-static void stylebox_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window);
-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 update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAction *action);
-
-// }}}
-
-@interface MainWindow (Notifications)
-- (void) toolboxWidthChanged:(int)newWidth;
-- (void) styleboxWidthChanged:(int)newWidth;
-- (void) tikzBufferChanged;
-- (void) windowSizeChangedWidth:(int)width height:(int)height;
-- (void) documentTikzChanged:(NSNotification*)notification;
-- (void) documentSelectionChanged:(NSNotification*)notification;
-- (void) undoStackChanged:(NSNotification*)notification;
-@end
-
-@interface MainWindow (InitHelpers)
-- (void) _loadConfig;
-- (void) _loadStyles;
-- (void) _loadPreambles;
-- (void) _loadUi;
-- (void) _restoreUiState;
-- (void) _connectSignals;
-@end
-
-@interface MainWindow (Private)
-- (BOOL) _confirmCloseDocumentTo:(NSString*)action;
-- (void) _forceLoadDocumentFromFile:(NSString*)path;
-- (void) _placeGraphOnClipboard:(Graph*)graph;
-- (void) _setHasParseError:(BOOL)hasError;
-/** Update the window title. */
-- (void) _updateTitle;
-/** Update the window status bar default text. */
-- (void) _updateStatus;
-/** Update the displayed tikz code to match the active document. */
-- (void) _updateTikz;
-/** 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
-
-- (id) init {
- self = [super init];
-
- if (self) {
- document = nil;
- preambleWindow = nil;
- previewWindow = 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];
-
- gtk_widget_show (GTK_WIDGET (mainWindow));
- }
-
- return self;
-}
-
-- (void) dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [configFile release];
- [styleManager release];
- [preambles release];
- [menu release];
- [renderer release];
- [inputHandler release];
- [stylesPalette release];
- [propertyPane release];
- [preambleWindow release];
- [previewWindow release];
- [surface release];
- [lastFolder release];
- [document release];
-
- g_object_unref (mainWindow);
- g_object_unref (tikzBuffer);
- g_object_unref (statusBar);
- g_object_unref (propsPane);
- g_object_unref (stylesPane);
- g_object_unref (graphPane);
- g_object_unref (tikzDisp);
-
- [super dealloc];
-}
-
-- (void) openFile {
- if (![self _confirmCloseDocumentTo:@"open a new document"]) {
- return;
- }
- FileChooserDialog *dialog = [FileChooserDialog openDialogWithParent:mainWindow];
- [dialog addStandardFilters];
- if (lastFolder) {
- [dialog setCurrentFolder:lastFolder];
- }
-
- if ([dialog showDialog]) {
- [self _forceLoadDocumentFromFile:[dialog filePath]];
- [self _setLastFolder:[dialog currentFolder]];
- }
- [dialog destroy];
-}
-
-- (void) saveActiveDocument {
- if ([document path] == nil) {
- [self saveActiveDocumentAs];
- } else {
- NSError *error = nil;
- if (![document save:&error]) {
- [self presentError:error];
- } else {
- [self _updateTitle];
- }
- }
-}
-
-- (void) saveActiveDocumentAs {
- FileChooserDialog *dialog = [FileChooserDialog saveDialogWithParent:mainWindow];
- [dialog addStandardFilters];
- if ([document path] != nil) {
- [dialog setCurrentFolder:[[document path] stringByDeletingLastPathComponent]];
- } else if (lastFolder != nil) {
- [dialog setCurrentFolder:lastFolder];
- }
- [dialog setSuggestedName:[document suggestedFileName]];
-
- if ([dialog showDialog]) {
- NSString *nfile = [dialog filePath];
-
- NSError *error = nil;
- if (![document saveToPath:nfile error:&error]) {
- [self presentError:error];
- } else {
- [self _updateTitle];
- [[RecentManager defaultManager] addRecentFile:nfile];
- [self _setLastFolder:[dialog currentFolder]];
- }
- }
- [dialog destroy];
-}
-
-- (void) saveActiveDocumentAsShape {
- GtkWidget *dialog = gtk_dialog_new_with_buttons (
- "Save as shape",
- mainWindow,
- GTK_DIALOG_MODAL,
- GTK_STOCK_OK,
- GTK_RESPONSE_ACCEPT,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_REJECT,
- NULL);
- GtkBox *content = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
- GtkWidget *label1 = gtk_label_new ("Please choose a name for the shape");
- GtkWidget *label2 = gtk_label_new ("Name:");
- GtkWidget *input = gtk_entry_new ();
- GtkBox *hbox = GTK_BOX (gtk_hbox_new (FALSE, 5));
- gtk_box_pack_start (hbox, label2, FALSE, TRUE, 0);
- gtk_box_pack_start (hbox, input, TRUE, TRUE, 0);
- gtk_box_pack_start (content, label1, TRUE, TRUE, 5);
- gtk_box_pack_start (content, GTK_WIDGET (hbox), TRUE, TRUE, 5);
- gtk_widget_show_all (GTK_WIDGET (content));
- gint response = gtk_dialog_run (GTK_DIALOG (dialog));
- while (response == GTK_RESPONSE_ACCEPT) {
- response = GTK_RESPONSE_NONE;
- NSDictionary *shapeDict = [Shape shapeDictionary];
- const gchar *dialogInput = gtk_entry_get_text (GTK_ENTRY (input));
- NSString *shapeName = [NSString stringWithUTF8String:dialogInput];
- BOOL doSave = NO;
- if ([shapeName isEqual:@""]) {
- GtkWidget *emptyStrDialog = gtk_message_dialog_new (mainWindow,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "You must specify a shape name");
- gtk_dialog_run (GTK_DIALOG (emptyStrDialog));
- gtk_widget_destroy (emptyStrDialog);
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- } else if ([shapeDict objectForKey:shapeName] != nil) {
- GtkWidget *overwriteDialog = gtk_message_dialog_new (mainWindow,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "Do you want to replace the existing shape named '%s'?",
- dialogInput);
- gint overwriteResp = gtk_dialog_run (GTK_DIALOG (overwriteDialog));
- gtk_widget_destroy (overwriteDialog);
-
- if (overwriteResp == GTK_RESPONSE_YES) {
- doSave = YES;
- } else {
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- }
- } else {
- doSave = YES;
- }
- if (doSave) {
- NSError *error = nil;
- NSString *userShapeDir = [[SupportDir userSupportDir] stringByAppendingPathComponent:@"shapes"];
- NSString *file = [NSString stringWithFormat:@"%@/%@.tikz", userShapeDir, shapeName];
- if (![[NSFileManager defaultManager] ensureDirectoryExists:userShapeDir error:&error]) {
- [self presentError:error withMessage:@"Could not create user shape directory"];
- } else {
- NSLog (@"Saving shape to %@", file);
- if (![document saveCopyToPath:file error:&error]) {
- [self presentError:error withMessage:@"Could not save shape file"];
- } else {
- [Shape refreshShapeDictionary];
- }
- }
- }
- }
- 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]];
- }
-}
-
-- (void) copy {
- if ([[[document pickSupport] selectedNodes] count] > 0) {
- [self _placeGraphOnClipboard:[document copySelection]];
- }
-}
-
-- (void) paste {
- gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
- tikzit_picture_atom,
- clipboard_paste_contents,
- document);
-}
-
-- (void) editPreambles {
- if (preambleWindow == nil) {
- preambleWindow = [[PreambleEditor alloc] initWithPreambles:preambles];
- [preambleWindow setParentWindow:mainWindow];
- }
- [preambleWindow show];
-}
-
-- (void) showPreview {
-#ifdef HAVE_POPPLER
- if (previewWindow == nil) {
- previewWindow = [[PreviewWindow alloc] initWithPreambles:preambles];
- [previewWindow setParentWindow:mainWindow];
- [previewWindow setDocument:document];
- }
- [previewWindow show];
-#endif
-}
-
-- (GraphInputHandler*) graphInputHandler {
- return inputHandler;
-}
-
-- (GtkWindow*) gtkWindow {
- return mainWindow;
-}
-
-- (Configuration*) mainConfiguration {
- return configFile;
-}
-
-- (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,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s",
- [[error localizedDescription] UTF8String]);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
-- (void) presentError:(NSError*)error withMessage:(NSString*)message {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s: %s",
- [message UTF8String],
- [[error localizedDescription] UTF8String]);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
-- (void) presentGError:(GError*)error {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s",
- error->message);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
-- (void) presentGError:(GError*)error withMessage:(NSString*)message {
- GtkWidget *dialog = gtk_message_dialog_new (mainWindow,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s: %s",
- [message UTF8String],
- error->message);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
-- (void) saveConfiguration {
- NSError *error = nil;
-
- if (preambles != nil) {
- NSString *preamblesDir = [[SupportDir userSupportDir] stringByAppendingPathComponent:@"preambles"];
- // NSFileManager is slightly dodgy on Windows
- g_mkdir_with_parents ([preamblesDir UTF8String], 700);
- [preambles storeToDirectory:preamblesDir];
- [configFile setStringEntry:@"selectedPreamble" inGroup:@"Preambles" value:[preambles selectedPreambleName]];
- }
-
- [styleManager saveStylesUsingConfigurationName:@"styles"];
- [propertyPane saveUiStateToConfig:configFile group:@"PropertyPane"];
-
- 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];
-}
-
-- (void) zoomOut {
- [surface zoomOut];
-}
-
-- (void) zoomReset {
- [surface zoomReset];
-}
-
-@end
-
-// }}}
-// {{{ Notifications
-
-@implementation MainWindow (Notifications)
-- (void) toolboxWidthChanged:(int)newWidth {
- [configFile setIntegerEntry:@"toolboxWidth" inGroup:@"mainWindow" value:newWidth];
-}
-
-- (void) styleboxWidthChanged:(int)newWidth {
- [configFile setIntegerEntry:@"styleboxWidth" inGroup:@"mainWindow" value:newWidth];
-}
-
-- (void) graphHeightChanged:(int)newHeight {
- [configFile setIntegerEntry:@"graphHeight" inGroup:@"mainWindow" value:newHeight];
-}
-
-- (void) tikzBufferChanged {
- if (!suppressTikzUpdates) {
- suppressTikzUpdates = TRUE;
-
- GtkTextIter start, end;
- gtk_text_buffer_get_bounds (tikzBuffer, &start, &end);
- gchar *text = gtk_text_buffer_get_text (tikzBuffer, &start, &end, FALSE);
-
- BOOL success = [document setTikz:[NSString stringWithUTF8String:text]];
- [self _setHasParseError:!success];
-
- g_free (text);
-
- suppressTikzUpdates = FALSE;
- }
-}
-
-- (void) windowSizeChangedWidth:(int)width height:(int)height {
- if (width > 0 && height > 0) {
- NSNumber *w = [NSNumber numberWithInt:width];
- NSNumber *h = [NSNumber numberWithInt:height];
- NSMutableArray *size = [NSMutableArray arrayWithCapacity:2];
- [size addObject:w];
- [size addObject:h];
- [configFile setIntegerListEntry:@"windowSize" inGroup:@"mainWindow" value:size];
- }
-}
-
-- (void) documentTikzChanged:(NSNotification*)notification {
- [self _updateTitle];
- [self _updateTikz];
-}
-
-- (void) documentSelectionChanged:(NSNotification*)notification {
- [self _updateStatus];
- [menu notifySelectionChanged:[document pickSupport]];
-}
-
-- (void) undoStackChanged:(NSNotification*)notification {
- [self _updateUndoActions];
-}
-@end
-
-// }}}
-// {{{ 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 {
- 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];
- }
-}
-
-- (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);
-
- GtkBox *mainLayout = GTK_BOX (gtk_vbox_new (FALSE, 0));
- gtk_widget_show (GTK_WIDGET (mainLayout));
- gtk_container_add (GTK_CONTAINER (mainWindow), GTK_WIDGET (mainLayout));
-
- menu = [[Menu alloc] initForMainWindow:self];
-
- GtkWidget *menubar = [menu menubar];
- gtk_box_pack_start (mainLayout, menubar, FALSE, TRUE, 0);
- gtk_box_reorder_child (mainLayout, menubar, 0);
- gtk_widget_show (menubar);
-
- GtkWidget *toolbarBox = gtk_handle_box_new ();
- gtk_box_pack_start (mainLayout, toolbarBox, FALSE, TRUE, 0);
- gtk_widget_show (toolbarBox);
- gtk_container_add (GTK_CONTAINER (toolbarBox), [menu toolbar]);
- gtk_widget_show ([menu toolbar]);
-
- propsPane = GTK_PANED (gtk_hpaned_new ());
- g_object_ref_sink (propsPane);
- gtk_widget_show (GTK_WIDGET (propsPane));
- gtk_box_pack_start (mainLayout, GTK_WIDGET (propsPane), TRUE, TRUE, 0);
-
- propertyPane = [[PropertyPane alloc] init];
- gtk_paned_pack1 (propsPane, [propertyPane widget], FALSE, TRUE);
- gtk_widget_show ([propertyPane widget]);
-
- stylesPane = GTK_PANED (gtk_hpaned_new ());
- g_object_ref_sink (stylesPane);
- gtk_widget_show (GTK_WIDGET (stylesPane));
- gtk_paned_pack2 (propsPane, GTK_WIDGET (stylesPane), TRUE, TRUE);
-
- stylesPalette = [[NodeStylesPalette alloc] initWithManager:styleManager];
- gtk_paned_pack2 (stylesPane, [stylesPalette widget], FALSE, TRUE);
- gtk_widget_show ([stylesPalette widget]);
-
- graphPane = GTK_PANED (gtk_vpaned_new ());
- g_object_ref_sink (graphPane);
- gtk_widget_show (GTK_WIDGET (graphPane));
- gtk_paned_pack1 (stylesPane, GTK_WIDGET (graphPane), TRUE, TRUE);
-
- surface = [[WidgetSurface alloc] init];
- gtk_widget_show ([surface widget]);
- gtk_paned_pack1 (graphPane, [surface widget], TRUE, TRUE);
- [surface setDefaultScale:50.0f];
- [surface setKeepCentered:YES];
- [surface setGrabsFocusOnClick:YES];
- renderer = [[GraphRenderer alloc] initWithSurface:surface document:document];
-
- inputHandler = [[GraphInputHandler alloc] initWithGraphRenderer:renderer];
- [surface setInputDelegate:inputHandler];
-
- tikzBuffer = gtk_text_buffer_new (NULL);
- g_object_ref_sink (tikzBuffer);
- GtkWidget *tikzScroller = gtk_scrolled_window_new (NULL, NULL);
- gtk_widget_show (tikzScroller);
-
- tikzDisp = gtk_text_view_new_with_buffer (tikzBuffer);
- g_object_ref_sink (tikzDisp);
- gtk_widget_show (tikzDisp);
- gtk_container_add (GTK_CONTAINER (tikzScroller), tikzDisp);
- gtk_paned_pack2 (graphPane, tikzScroller, FALSE, TRUE);
-
- statusBar = GTK_STATUSBAR (gtk_statusbar_new ());
- gtk_widget_show (GTK_WIDGET (statusBar));
- gtk_box_pack_start (mainLayout, GTK_WIDGET (statusBar), FALSE, TRUE, 0);
-
- GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- update_paste_action (clipboard, NULL, [menu pasteAction]);
-}
-
-- (void) _restoreUiState {
- NSArray *windowSize = [configFile integerListEntry:@"windowSize" inGroup:@"mainWindow"];
- 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);
- }
- }
- int panePos = [configFile integerEntry:@"toolboxWidth" inGroup:@"mainWindow"];
- if (panePos > 0) {
- gtk_paned_set_position (propsPane, panePos);
- }
- panePos = [configFile integerEntry:@"styleboxWidth" inGroup:@"mainWindow"];
- if (panePos > 0) {
- gtk_paned_set_position (stylesPane, panePos);
- }
- panePos = [configFile integerEntry:@"graphHeight" inGroup:@"mainWindow"];
- if (panePos > 0) {
- gtk_paned_set_position (graphPane, panePos);
- }
- [propertyPane restoreUiStateFromConfig:configFile group:@"PropertyPane"];
-}
-
-- (void) _connectSignals {
- GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- g_signal_connect (G_OBJECT (clipboard),
- "owner-change",
- G_CALLBACK (update_paste_action),
- [menu pasteAction]);
- g_signal_connect (G_OBJECT (mainWindow),
- "key-press-event",
- G_CALLBACK (tz_hijack_key_press),
- NULL);
- g_signal_connect (G_OBJECT (propsPane),
- "notify::position",
- G_CALLBACK (toolbox_divider_position_changed_cb),
- self);
- g_signal_connect (G_OBJECT (stylesPane),
- "notify::position",
- G_CALLBACK (stylebox_divider_position_changed_cb),
- self);
- g_signal_connect (G_OBJECT (graphPane),
- "notify::position",
- G_CALLBACK (graph_divider_position_changed_cb),
- self);
- g_signal_connect (G_OBJECT (tikzBuffer),
- "changed",
- G_CALLBACK (tikz_buffer_changed_cb),
- self);
- g_signal_connect (G_OBJECT (mainWindow),
- "delete-event",
- G_CALLBACK (main_window_delete_event_cb),
- self);
- g_signal_connect (G_OBJECT (mainWindow),
- "destroy",
- G_CALLBACK (main_window_destroy_cb),
- self);
- g_signal_connect (G_OBJECT (mainWindow),
- "configure-event",
- G_CALLBACK (main_window_configure_event_cb),
- self);
-}
-@end
-
-// }}}
-// {{{ Private
-
-@implementation MainWindow (Private)
-
-- (BOOL) _confirmCloseDocumentTo:(NSString*)action {
- BOOL proceed = YES;
- 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,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- [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);
- }
- return proceed;
-}
-
-- (void) _forceLoadDocumentFromFile:(NSString*)path {
- NSError *error = nil;
- TikzDocument *d = [TikzDocument documentFromFile:path styleManager:styleManager error:&error];
- if (d != nil) {
- [self _setActiveDocument:d];
- [[RecentManager defaultManager] addRecentFile:path];
- } else {
- [self presentError:error withMessage:@"Could not open file"];
- [[RecentManager defaultManager] removeRecentFile:path];
- }
-}
-
-- (void) _placeGraphOnClipboard:(Graph*)graph {
- GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- static const GtkTargetEntry targets[] = {
- { "TIKZITPICTURE", 0, TARGET_TIKZIT_PICTURE },
- { "UTF8_STRING", 0, TARGET_UTF8_STRING } };
-
- gtk_clipboard_set_with_data (clipboard,
- targets, G_N_ELEMENTS (targets),
- clipboard_provide_data,
- clipboard_release_data,
- clipboard_graph_data_new (graph));
-}
-
-- (void) _setHasParseError:(BOOL)hasError {
- if (hasError && !hasParseError) {
- gtk_statusbar_push (statusBar, 1, "Parse error");
- GdkColor color = {0, 65535, 61184, 61184};
- gtk_widget_modify_base (tikzDisp, GTK_STATE_NORMAL, &color);
- } else if (!hasError && hasParseError) {
- gtk_statusbar_pop (statusBar, 1);
- gtk_widget_modify_base (tikzDisp, GTK_STATE_NORMAL, NULL);
- }
- hasParseError = hasError;
-}
-
-- (void) _updateUndoActions {
- [menu setUndoActionEnabled:[document canUndo]];
- [menu setUndoActionDetail:[document undoName]];
-
- [menu setRedoActionEnabled:[document canRedo]];
- [menu setRedoActionDetail:[document redoName]];
-}
-
-- (void) _updateTitle {
- NSString *title = [NSString stringWithFormat:@"TikZiT - %@%s",
- [document name],
- ([document hasUnsavedChanges] ? "*" : "")];
- gtk_window_set_title(mainWindow, [title UTF8String]);
-}
-
-- (void) _updateStatus {
- GString *buffer = g_string_sized_new (30);
- gchar *nextNode = 0;
-
- for (Node *n in [[document pickSupport] selectedNodes]) {
- if (nextNode) {
- if (buffer->len == 0) {
- g_string_printf(buffer, "Nodes %s", nextNode);
- } else {
- g_string_append_printf(buffer, ", %s", nextNode);
- }
- }
- nextNode = (gchar *)[[n name] UTF8String];
- }
- if (nextNode) {
- if (buffer->len == 0) {
- g_string_printf(buffer, "Node %s is selected", nextNode);
- } else {
- g_string_append_printf(buffer, " and %s are selected", nextNode);
- }
- }
-
- if (buffer->len == 0) {
- int nrNodes = [[[document graph] nodes] count];
- int nrEdges = [[[document graph] edges] count];
- g_string_printf(buffer, "Graph has %d node%s and %d edge%s",
- nrNodes,
- nrNodes!=1 ? "s" : "",
- nrEdges,
- nrEdges!=1 ? "s" : "");
- }
- gtk_statusbar_pop(statusBar, 0);
- gtk_statusbar_push(statusBar, 0, buffer->str);
-
- g_string_free (buffer, TRUE);
-}
-
-- (void) _updateTikz {
- if (document != nil && !suppressTikzUpdates) {
- suppressTikzUpdates = TRUE;
-
- if (document != nil) {
- const char *tikzString = [[document tikz] UTF8String];
- gtk_text_buffer_set_text (tikzBuffer, tikzString, -1);
- } else {
- gtk_text_buffer_set_text (tikzBuffer, "", -1);
- }
- [self _setHasParseError:NO];
-
- suppressTikzUpdates = FALSE;
- }
-}
-
-- (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];
- [stylesPalette setDocument:document];
- [propertyPane 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 toolbox_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- gint position;
- g_object_get (gobject, "position", &position, NULL);
- [window toolboxWidthChanged:position];
- [pool drain];
-}
-
-static void stylebox_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- gint position;
- g_object_get (gobject, "position", &position, NULL);
- [window styleboxWidthChanged:position];
- [pool drain];
-}
-
-static void graph_divider_position_changed_cb (GObject *gobject, GParamSpec *pspec, MainWindow *window) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- gint position;
- g_object_get (gobject, "position", &position, NULL);
- [window graphHeightChanged:position];
- [pool drain];
-}
-
-static void tikz_buffer_changed_cb (GtkTextBuffer *buffer, MainWindow *window) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window tikzBufferChanged];
- [pool drain];
-}
-
-static gboolean main_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, MainWindow *window) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- return ![window askCanQuit];
- [pool drain];
-}
-
-static void main_window_destroy_cb (GtkWidget *widget, MainWindow *window) {
- gtk_main_quit();
-}
-
-static gboolean main_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, MainWindow *window) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [window windowSizeChangedWidth:event->width height:event->height];
- [pool drain];
- return FALSE;
-}
-
-static void clipboard_provide_data (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- guint info,
- gpointer clipboard_graph_data) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- ClipboardGraphData *data = (ClipboardGraphData*)clipboard_graph_data;
- if (info == TARGET_UTF8_STRING || info == TARGET_TIKZIT_PICTURE) {
- clipboard_graph_data_convert (data);
- GdkAtom target = (info == TARGET_UTF8_STRING) ? utf8_atom : tikzit_picture_atom;
- gtk_selection_data_set (selection_data,
- target,
- 8*sizeof(gchar),
- (guchar*)data->tikz,
- data->tikz_length);
- }
-
- [pool drain];
-}
-
-static void clipboard_release_data (GtkClipboard *clipboard, gpointer data) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- clipboard_graph_data_free ((ClipboardGraphData*)data);
- [pool drain];
-}
-
-static void clipboard_check_targets (GtkClipboard *clipboard,
- GdkAtom *atoms,
- gint n_atoms,
- gpointer action) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- gboolean found = FALSE;
- for (gint i = 0; i < n_atoms; ++i) {
- if (atoms[i] == tikzit_picture_atom) {
- found = TRUE;
- break;
- }
- }
- gtk_action_set_sensitive (GTK_ACTION (action), found);
-
- [pool drain];
-}
-
-static void update_paste_action (GtkClipboard *clipboard, GdkEvent *event, GtkAction *action) {
- gtk_action_set_sensitive (action, FALSE);
- gtk_clipboard_request_targets (clipboard, clipboard_check_targets, action);
-}
-
-static void clipboard_paste_contents (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- gpointer document) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- TikzDocument *doc = (TikzDocument*)document;
- gint length = gtk_selection_data_get_length (selection_data);
- if (length >= 0) {
- const guchar *raw_data = gtk_selection_data_get_data (selection_data);
- gchar *data = g_new (gchar, length+1);
- g_strlcpy (data, (const gchar *)raw_data, length+1);
- NSString *tikz = [NSString stringWithUTF8String:data];
- if (tikz != nil) {
- [doc pasteFromTikz:tikz];
- }
- g_free (data);
- }
-
- [pool drain];
-}
-
-// }}}
-
-// vim:ft=objc:ts=8:et:sts=4:sw=4:foldmethod=marker