diff options
author | Alex Merry <alex.merry@cs.ox.ac.uk> | 2012-12-03 19:02:53 +0000 |
---|---|---|
committer | Alex Merry <alex.merry@cs.ox.ac.uk> | 2012-12-04 11:12:28 +0000 |
commit | 94ff07fc9d728d97dde159e0c3e6ab80e29e0855 (patch) | |
tree | 2e74ff3d709db87e2e2b27aa501ed46727c054d7 /tikzit/src/gtk/Application.m | |
parent | 0d715a7f17b8e5570b42d7802c502e4aa234a3c1 (diff) |
Refactor MainWindow into Application and Window
Basic multiple-window support, but no tools.
Diffstat (limited to 'tikzit/src/gtk/Application.m')
-rw-r--r-- | tikzit/src/gtk/Application.m | 268 |
1 files changed, 268 insertions, 0 deletions
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 |