diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0ccb6749 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +xcuserdata/ +project.xcworkspace/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b0878e36 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Libraries/MongoObjCDriver"] + path = Libraries/MongoObjCDriver + url = git@github.com:jeromelebel/MongoObjCDriver.git diff --git a/AddCollectionController.h b/AddCollectionController.h deleted file mode 100644 index 7b832e67..00000000 --- a/AddCollectionController.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// AddCollectionController.h -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import - - -@interface AddCollectionController : NSWindowController { - IBOutlet NSTextField *collectionname; - NSMutableString *dbname; - NSMutableDictionary *dbInfo; -} - -@property (nonatomic, retain) NSTextField *collectionname; -@property (nonatomic, retain) NSString *dbname; -@property (nonatomic, retain) NSMutableDictionary *dbInfo; - -- (IBAction)add:(id)sender; -- (IBAction)cancel:(id)sender; - -@end diff --git a/AddCollectionController.m b/AddCollectionController.m deleted file mode 100644 index 2aa813c9..00000000 --- a/AddCollectionController.m +++ /dev/null @@ -1,58 +0,0 @@ -// -// AddCollectionController.m -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "Configure.h" -#import "AddCollectionController.h" - - -@implementation AddCollectionController - -@synthesize dbname; -@synthesize collectionname; -@synthesize dbInfo; - -- (id)init { - if (![super initWithWindowNibName:@"NewCollection"]) return nil; - return self; -} - -- (void)dealloc { - [dbname release]; - [collectionname release]; - [dbInfo release]; - [super dealloc]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kNewCollectionWindowWillClose object:dbInfo]; - dbInfo = nil; -} - -- (IBAction)cancel:(id)sender { - dbInfo = nil; - [self close]; -} - -- (IBAction)add:(id)sender { - if ([ [collectionname stringValue] length] == 0) { - NSRunAlertPanel(@"Error", @"Collection name could not be empty", @"OK", nil, nil); - return; - } - NSArray *keys = [[NSArray alloc] initWithObjects:@"dbname", @"collectionname", nil]; - NSString *colname = [[NSString alloc] initWithString:[collectionname stringValue]]; - NSArray *objs = [[NSArray alloc] initWithObjects:dbname, colname, nil]; - [colname release]; - if (!dbInfo) { - dbInfo = [[NSMutableDictionary alloc] initWithCapacity:2]; - } - dbInfo = [NSMutableDictionary dictionaryWithObjects:objs forKeys:keys]; - [objs release]; - [keys release]; - [self close]; -} -@end diff --git a/AddConnectionController.h b/AddConnectionController.h deleted file mode 100644 index deaf1f14..00000000 --- a/AddConnectionController.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// AddConnectionController.h -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import -@class ConnectionsArrayController; - -@interface AddConnectionController : NSWindowController { - IBOutlet NSTextField *hostTextField; - IBOutlet NSTextField *hostportTextField; - IBOutlet NSButton *usereplCheckBox; - IBOutlet NSTextField *serversTextField; - IBOutlet NSTextField *replnameTextField; - IBOutlet NSTextField *aliasTextField; - IBOutlet NSTextField *adminuserTextField; - IBOutlet NSSecureTextField *adminpassTextField; - IBOutlet NSTextField *defaultdbTextField; - IBOutlet NSButton *usesshCheckBox; - IBOutlet NSTextField *bindaddressTextField; - IBOutlet NSTextField *bindportTextField; - IBOutlet NSTextField *sshhostTextField; - IBOutlet NSTextField *sshportTextField; - IBOutlet NSTextField *sshuserTextField; - IBOutlet NSSecureTextField *sshpasswordTextField; - IBOutlet NSTextField *sshkeyfileTextField; - IBOutlet ConnectionsArrayController *connectionsArrayController; - NSDictionary *connectionInfo; - NSManagedObjectContext *managedObjectContext; -} - -@property (nonatomic, retain) NSTextField *hostTextField; -@property (nonatomic, retain) NSTextField *hostportTextField; -@property (nonatomic, retain) NSButton *usereplCheckBox; -@property (nonatomic, retain) NSTextField *serversTextField; -@property (nonatomic, retain) NSTextField *replnameTextField; -@property (nonatomic, retain) NSTextField *aliasTextField; -@property (nonatomic, retain) NSTextField *adminuserTextField; -@property (nonatomic, retain) NSSecureTextField *adminpassTextField; -@property (nonatomic, retain) NSTextField *defaultdbTextField; -@property (nonatomic, retain) NSButton *usesshCheckBox; -@property (nonatomic, retain) NSTextField *bindaddressTextField; -@property (nonatomic, retain) NSTextField *bindportTextField; -@property (nonatomic, retain) NSTextField *sshhostTextField; -@property (nonatomic, retain) NSTextField *sshportTextField; -@property (nonatomic, retain) NSTextField *sshuserTextField; -@property (nonatomic, retain) NSSecureTextField *sshpasswordTextField; -@property (nonatomic, retain) NSTextField *sshkeyfileTextField; -@property (nonatomic, retain) NSDictionary *connectionInfo; -@property (nonatomic, retain) ConnectionsArrayController *connectionsArrayController; -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; - -- (IBAction)cancel:(id)sender; -- (IBAction)add:(id)sender; -- (IBAction)enableSSH:(id)sender; -- (IBAction)enableRepl:(id)sender; -- (BOOL)validateConnection; - -- (IBAction)chooseKeyPath:(id)sender; - -@end diff --git a/AddConnectionController.m b/AddConnectionController.m deleted file mode 100644 index e14a19da..00000000 --- a/AddConnectionController.m +++ /dev/null @@ -1,252 +0,0 @@ -// -// AddConnectionController.m -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "Configure.h" -#import "AddConnectionController.h" -#import "ConnectionsArrayController.h" - -@implementation AddConnectionController - -@synthesize hostTextField; -@synthesize hostportTextField; -@synthesize usereplCheckBox; -@synthesize serversTextField; -@synthesize replnameTextField; -@synthesize aliasTextField; -@synthesize adminuserTextField; -@synthesize adminpassTextField; -@synthesize defaultdbTextField; -@synthesize usesshCheckBox; -@synthesize bindaddressTextField; -@synthesize bindportTextField; -@synthesize sshhostTextField; -@synthesize sshportTextField; -@synthesize sshuserTextField; -@synthesize sshpasswordTextField; -@synthesize sshkeyfileTextField; -@synthesize connectionInfo; -@synthesize connectionsArrayController; -@synthesize managedObjectContext; - -- (id)init { - if (![super initWithWindowNibName:@"NewConnection"]) return nil; - return self; -} - -- (void)dealloc { - [hostTextField release]; - [hostportTextField release]; - [usereplCheckBox release]; - [serversTextField release]; - [replnameTextField release]; - [aliasTextField release]; - [adminuserTextField release]; - [adminpassTextField release]; - [defaultdbTextField release]; - [usesshCheckBox release]; - [bindaddressTextField release]; - [bindportTextField release]; - [sshhostTextField release]; - [sshportTextField release]; - [sshuserTextField release]; - [sshpasswordTextField release]; - [sshkeyfileTextField release]; - [connectionInfo release]; - [connectionsArrayController release]; - [managedObjectContext release]; - [super dealloc]; -} - -- (void)windowDidLoad { - //NSLog(@"New Connection Window Loaded"); - [super windowDidLoad]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kNewConnectionWindowWillClose object:connectionInfo]; -} - -- (IBAction)cancel:(id)sender { - connectionInfo = nil; - [self close]; -} - -- (IBAction)add:(id)sender { - NSString *host; - NSUInteger hostport; - NSString *servers; - NSString *repl_name; - NSUInteger userepl = 0; - NSString *alias; - NSString *adminuser = [adminuserTextField stringValue]; - NSString *adminpass = [adminpassTextField stringValue]; - NSString *defaultdb = [defaultdbTextField stringValue]; - NSUInteger usessh = 0; - NSString *bindaddress; - NSUInteger bindport; - NSString *sshhost; - NSUInteger sshport; - NSString *sshuser; - NSString *sshpassword; - NSString *sshkeyfile; - if ([ [hostTextField stringValue] length] == 0) { - host = [[NSString alloc] initWithString:@"localhost"]; - }else{ - host = [[NSString alloc] initWithString:[hostTextField stringValue]]; - } - if ([hostportTextField intValue] == 0) { - hostport = 27017; - }else{ - hostport = [hostportTextField intValue]; - } - - servers = [[NSString alloc] initWithString:[serversTextField stringValue]]; - repl_name = [[NSString alloc] initWithString:[replnameTextField stringValue]]; - if ([usereplCheckBox state]) - { - userepl = 1; - } - - if ([ [aliasTextField stringValue] length] == 0) { - alias = [[NSString alloc] initWithString:@"localhost"]; - }else{ - alias = [[NSString alloc] initWithString:[aliasTextField stringValue]]; - } - if ([ [bindaddressTextField stringValue] length] == 0) { - bindaddress = [[NSString alloc] initWithString:@"127.0.0.1"]; - }else{ - bindaddress = [[NSString alloc] initWithString:[bindaddressTextField stringValue]]; - } - if ([ [bindportTextField stringValue] length] == 0) { - bindport = 8888; - }else{ - bindport = [bindportTextField intValue]; - } - sshhost = [[NSString alloc] initWithString:[sshhostTextField stringValue]]; - if ([[sshportTextField stringValue] length] == 0) { - sshport = 22; - }else { - sshport = [sshportTextField intValue]; - } - - sshuser = [[NSString alloc] initWithString:[sshuserTextField stringValue]]; - sshpassword = [[NSString alloc] initWithString:[sshpasswordTextField stringValue]]; - sshkeyfile = [[NSString alloc] initWithString:[sshkeyfileTextField stringValue]]; - if ([usesshCheckBox state]) - { - usessh = 1; - - } - NSArray *keys = [[NSArray alloc] initWithObjects:@"host", @"hostport", @"userepl", @"servers", @"repl_name", @"alias", @"adminuser", @"adminpass", @"defaultdb", @"usessh", @"bindaddress", @"bindport", @"sshhost", @"sshport", @"sshuser", @"sshpassword", @"sshkeyfile", nil]; - NSArray *objs = [[NSArray alloc] initWithObjects:host, [NSNumber numberWithInt:hostport], [NSNumber numberWithInt:userepl], servers, repl_name, alias, adminuser, adminpass, defaultdb, [NSNumber numberWithInt:usessh], bindaddress, [NSNumber numberWithInt:bindport], sshhost, [NSNumber numberWithInt:sshport], sshuser, sshpassword, sshkeyfile, nil]; - if (!connectionInfo) { - connectionInfo = [[NSMutableDictionary alloc] initWithCapacity:13]; - } - connectionInfo = [NSMutableDictionary dictionaryWithObjects:objs forKeys:keys]; - [keys release]; - [objs release]; - [host release]; - [alias release]; - [servers release]; - [repl_name release]; - [sshhost release]; - [sshuser release]; - [sshpassword release]; - [sshkeyfile release]; - [bindaddress release]; - if ([self validateConnection]) { - [self close]; - } -} - -- (BOOL)validateConnection -{ - if ([[connectionInfo objectForKey:@"host"] length] == 0) { - NSRunAlertPanel(@"Error", @"Connection host should not be empty", @"OK", nil, nil); - return NO; - } - if ([[connectionInfo objectForKey:@"host"] isEqualToString:@"flame.mongohq.com"] && [[connectionInfo objectForKey:@"defaultdb"] length] == 0) { - NSRunAlertPanel(@"Error", @"DB should not be empty if you are using mongohq", @"OK", nil, nil); - return NO; - } - if ([[connectionInfo objectForKey:@"alias"] length]<3) { - NSRunAlertPanel(@"Error", @"Connection name should not be less than 3 charaters", @"OK", nil, nil); - return NO; - } - if ([connectionsArrayController checkDuplicate:[connectionInfo objectForKey:@"alias"]]) { - NSRunAlertPanel(@"Error", @"Connection alias name has been existed!", @"OK", nil, nil); - return NO; - } - if ([usesshCheckBox state] == 1 && ([[connectionInfo objectForKey:@"bindaddress"] length] == 0 || [[connectionInfo objectForKey:@"sshhost"] length] == 0)) { - NSRunAlertPanel(@"Error", @"Please full fill ssh information!", @"OK", nil, nil); - return NO; - } - if ([usereplCheckBox state] == 1 && ([[connectionInfo objectForKey:@"servers"] length] == 0 || [[connectionInfo objectForKey:@"repl_name"] length] == 0)) { - NSRunAlertPanel(@"Error", @"Please full fill replica-set information!", @"OK", nil, nil); - return NO; - } - return YES; -} - -- (IBAction)enableSSH:(id)sender -{ - if ([usesshCheckBox state] == 1) - { - [bindaddressTextField setEnabled:YES]; - [bindportTextField setEnabled:YES]; - [sshhostTextField setEnabled:YES]; - [sshuserTextField setEnabled:YES]; - [sshpasswordTextField setEnabled:YES]; - [sshportTextField setEnabled:YES]; - [sshkeyfileTextField setEnabled:YES]; - }else { - [bindaddressTextField setEnabled:NO]; - [bindportTextField setEnabled:NO]; - [sshhostTextField setEnabled:NO]; - [sshuserTextField setEnabled:NO]; - [sshpasswordTextField setEnabled:NO]; - [sshportTextField setEnabled:NO]; - [sshkeyfileTextField setEnabled:NO]; - } - -} - -- (IBAction)enableRepl:(id)sender -{ - if ([usereplCheckBox state] == 1) - { - [serversTextField setEnabled:YES]; - [replnameTextField setEnabled:YES]; - }else { - [serversTextField setEnabled:NO]; - [replnameTextField setEnabled:NO]; - } - -} - -- (IBAction)chooseKeyPath:(id)sender -{ - NSOpenPanel *tvarNSOpenPanelObj = [NSOpenPanel openPanel]; - NSInteger tvarNSInteger = [tvarNSOpenPanelObj runModalForTypes:nil]; - if(tvarNSInteger == NSOKButton){ - NSLog(@"doOpen we have an OK button"); - //NSString * tvarDirectory = [tvarNSOpenPanelObj directory]; - //NSLog(@"doOpen directory = %@",tvarDirectory); - NSString * tvarFilename = [tvarNSOpenPanelObj filename]; - NSLog(@"doOpen filename = %@",tvarFilename); - [sshkeyfileTextField setStringValue:tvarFilename]; - } else if(tvarNSInteger == NSCancelButton) { - NSLog(@"doOpen we have a Cancel button"); - return; - } else { - NSLog(@"doOpen tvarInt not equal 1 or zero = %3d",tvarNSInteger); - return; - } // end if -} - -@end diff --git a/AddDBController.h b/AddDBController.h deleted file mode 100644 index 9e06eb93..00000000 --- a/AddDBController.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// AddDBController.h -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import -@class DatabasesArrayController; -@class Connection; - -@interface AddDBController : NSWindowController { - IBOutlet NSTextField *dbname; - IBOutlet NSTextField *user; - IBOutlet NSSecureTextField *password; - NSMutableDictionary *dbInfo; - Connection *conn; - NSManagedObjectContext *managedObjectContext; - IBOutlet DatabasesArrayController *databasesArrayController; -} - -@property (nonatomic, retain) NSTextField *dbname; -@property (nonatomic, retain) NSTextField *user; -@property (nonatomic, retain) NSSecureTextField *password; -@property (nonatomic, retain) NSMutableDictionary *dbInfo; -@property (nonatomic, retain) Connection *conn; -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, retain) DatabasesArrayController *databasesArrayController; - -- (IBAction)add:(id)sender; -- (IBAction)cancel:(id)sender; -- (void)saveAction; -@end diff --git a/AddDBController.m b/AddDBController.m deleted file mode 100644 index 7daeaf3a..00000000 --- a/AddDBController.m +++ /dev/null @@ -1,97 +0,0 @@ -// -// AddDBController.m -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "Configure.h" -#import "AddDBController.h" -#import "DatabasesArrayController.h" -#import "Database.h" -#import "Connection.h" -#import "NSString+Extras.h" - -@implementation AddDBController - -@synthesize dbname; -@synthesize user; -@synthesize password; -@synthesize dbInfo; -@synthesize conn; -@synthesize managedObjectContext; -@synthesize databasesArrayController; - -- (id)init { - if (![super initWithWindowNibName:@"NewDB"]) return nil; - return self; -} - -- (void)dealloc { - [dbname release]; - [user release]; - [password release]; - [dbInfo release]; - [managedObjectContext release]; - [databasesArrayController release]; - [conn release]; - [super dealloc]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kNewDBWindowWillClose object:dbInfo]; - dbInfo = nil; -} - -- (IBAction)cancel:(id)sender { - dbInfo = nil; - [self close]; -} - -- (IBAction)add:(id)sender { - if ([ [dbname stringValue] length] == 0) { - NSRunAlertPanel(@"Error", @"Database name could not be empty", @"OK", nil, nil); - return; - } - NSArray *keys = [[NSArray alloc] initWithObjects:@"dbname", @"user", @"password", nil]; - NSString *dbstr = [[NSString alloc] initWithString:[dbname stringValue]]; - NSString *userStr = [[NSString alloc] initWithString:[user stringValue]]; - NSString *passStr = [[NSString alloc] initWithString:[password stringValue]]; - NSArray *objs = [[NSArray alloc] initWithObjects:dbstr, userStr, passStr, nil]; - [dbstr release]; - [userStr release]; - [passStr release]; - if (!dbInfo) { - dbInfo = [[NSMutableDictionary alloc] initWithCapacity:3]; - } - dbInfo = [NSMutableDictionary dictionaryWithObjects:objs forKeys:keys]; - [objs release]; - [keys release]; - if ([[dbInfo objectForKey:@"user"] isPresent] || [[dbInfo objectForKey:@"password"] isPresent]) { - Database *dbobj = [databasesArrayController dbInfo:conn name:[dbname stringValue]]; - if (dbobj==nil) { - //[dbobj release]; - dbobj = [databasesArrayController newObjectWithConn:conn name:[dbname stringValue] user:[dbInfo objectForKey:@"user"] password:[dbInfo objectForKey:@"password"]]; - [databasesArrayController addObject:dbobj]; - [dbobj release]; - } - [self saveAction]; - } - [self close]; -} - -- (void) saveAction { - - NSError *error = nil; - - if (![[self managedObjectContext] commitEditing]) { - NSLog(@"%@:%s unable to commit editing before saving", [self class], _cmd); - } - - if (![[self managedObjectContext] save:&error]) { - [[NSApplication sharedApplication] presentError:error]; - } -} - -@end diff --git a/Auth.xib b/Auth.xib deleted file mode 100644 index d0c2f6b3..00000000 --- a/Auth.xib +++ /dev/null @@ -1,1040 +0,0 @@ - - - - 1060 - 10D573 - 762 - 1038.29 - 460.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 762 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - AuthWindowController - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{196, 376}, {298, 134}} - 544735232 - Auth - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 268 - {{20, 92}, {258, 22}} - - YES - - -1804468671 - 272630784 - - - LucidaGrande - 13 - 1044 - - Username - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - - - - 268 - {{20, 60}, {258, 22}} - - YES - - 343014976 - 272630848 - - - Password - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{194, 18}, {84, 25}} - - YES - - -2080244224 - 134217728 - Save - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{95, 18}, {85, 25}} - - YES - - -2080244224 - 134217728 - Cancel - - - -2038152961 - 163 - - - 400 - 75 - - - - {298, 134} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - YES - - Database - - YES - YES - YES - YES - YES - YES - - - - - YES - - - window - - - - 3 - - - - delegate - - - - 4 - - - - userTextField - - - - 15 - - - - passwordTextField - - - - 16 - - - - save: - - - - 17 - - - - cancel: - - - - 18 - - - - title: self.dbname - - - - - - title: self.dbname - title - self.dbname - 2 - - - 20 - - - - databasesArrayController - - - - 22 - - - - managedObjectContext: managedObjectContext - - - - - - managedObjectContext: managedObjectContext - managedObjectContext - managedObjectContext - 2 - - - 23 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - - - 7 - - - YES - - - - - - 8 - - - - - 9 - - - YES - - - - - - 10 - - - - - 11 - - - YES - - - - - - 12 - - - - - 13 - - - YES - - - - - - 14 - - - - - 21 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 10.IBPluginDependency - 11.IBPluginDependency - 12.IBPluginDependency - 13.IBPluginDependency - 14.IBPluginDependency - 2.IBPluginDependency - 21.CustomClassName - 21.IBPluginDependency - 7.IBPluginDependency - 8.IBPluginDependency - 9.IBPluginDependency - - - YES - {{234, 416}, {298, 134}} - com.apple.InterfaceBuilder.CocoaPlugin - {{234, 416}, {298, 134}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - DatabasesArrayController - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 23 - - - - YES - - AuthWindowController - NSWindowController - - YES - - YES - cancel: - save: - - - YES - id - id - - - - YES - - YES - databasesArrayController - passwordTextField - userTextField - - - YES - DatabasesArrayController - NSTextField - NSTextField - - - - IBProjectSource - AuthWindowController.h - - - - DatabasesArrayController - NSArrayController - - IBProjectSource - DatabasesArrayController.h - - - - NSObject - - IBProjectSource - JSON/NSObject+SBJSON.h - - - - NSObject - - IBProjectSource - JSON/SBJsonWriter.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSSecureTextFieldCell - NSTextFieldCell - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - diff --git a/AuthWindowController.h b/AuthWindowController.h deleted file mode 100644 index 4f8aeeba..00000000 --- a/AuthWindowController.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// AuthWindowController.h -// MongoHub -// -// Created by Syd on 10-5-6. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import -@class DatabasesArrayController; -@class Connection; - -@interface AuthWindowController : NSWindowController { - IBOutlet NSTextField *userTextField; - IBOutlet NSTextField *passwordTextField; - Connection *conn; - NSManagedObjectContext *managedObjectContext; - NSString *dbname; - IBOutlet DatabasesArrayController *databasesArrayController; -} - -@property (nonatomic, retain) NSTextField *userTextField; -@property (nonatomic, retain) NSTextField *passwordTextField; -@property (nonatomic, retain) Connection *conn; -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, retain) NSString *dbname; -@property (nonatomic, retain) DatabasesArrayController *databasesArrayController; - -- (IBAction)save:(id)sender; -- (IBAction)cancel:(id)sender; -- (void) saveAction; -@end diff --git a/AuthWindowController.m b/AuthWindowController.m deleted file mode 100644 index 80f2564b..00000000 --- a/AuthWindowController.m +++ /dev/null @@ -1,81 +0,0 @@ -// -// AuthWindowController.m -// MongoHub -// -// Created by Syd on 10-5-6. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "Configure.h" -#import "AuthWindowController.h" -#import "DatabasesArrayController.h" -#import "Database.h" -#import "Connection.h" - -@implementation AuthWindowController - -@synthesize userTextField; -@synthesize passwordTextField; -@synthesize dbname; -@synthesize conn; -@synthesize managedObjectContext; -@synthesize databasesArrayController; - -- (id)init { - if (![super initWithWindowNibName:@"Auth"]) return nil; - return self; -} - -- (void)dealloc { - [userTextField release]; - [passwordTextField release]; - [dbname release]; - [managedObjectContext release]; - [databasesArrayController release]; - [conn release]; - [super dealloc]; -} - -- (void)windowDidLoad { - //NSLog(@"New Connection Window Loaded"); - [super windowDidLoad]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kAuthWindowWillClose object:nil]; - dbname = nil; -} - -- (IBAction)cancel:(id)sender { - dbname = nil; - [self close]; -} - -- (IBAction)save:(id)sender { - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - db.user = [userTextField stringValue]; - db.password = [passwordTextField stringValue]; - }else { - db = [databasesArrayController newObjectWithConn:conn name:dbname user:[userTextField stringValue] password:[passwordTextField stringValue]]; - [databasesArrayController addObject:db]; - [db release]; - } - [self saveAction]; - [self close]; -} - -- (void) saveAction { - - NSError *error = nil; - - if (![[self managedObjectContext] commitEditing]) { - NSLog(@"%@:%s unable to commit editing before saving", [self class], _cmd); - } - - if (![[self managedObjectContext] save:&error]) { - [[NSApplication sharedApplication] presentError:error]; - } -} - -@end diff --git a/Configure.h b/Configure.h deleted file mode 100644 index fade581f..00000000 --- a/Configure.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// Configure.h -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#define kNewConnectionWindowWillClose @"NewConnectionWindowWillClose" -#define kEditConnectionWindowWillClose @"EditConnectionWindowWillClose" -#define kNewDBWindowWillClose @"NewDBWindowWillClose" -#define kNewCollectionWindowWillClose @"NewCollectionWindowWillClose" -#define kAuthWindowWillClose @"AuthWindowWillClose" -#define kImportWindowWillClose @"ImportWindowWillClose" -#define kExportWindowWillClose @"ExportWindowWillClose" -#define kJsonWindowWillClose @"kJsonWindowWillClose" -#define kJsonWindowSaved @"kJsonWindowSaved" diff --git a/Connection.h b/Connection.h deleted file mode 100644 index 4c0405f4..00000000 --- a/Connection.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Database.h -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "Database.h" - -@interface Connection: NSManagedObject { - NSString *host; - NSNumber *hostport; - NSString *servers; - NSString *repl_name; - NSString *alias; - NSString *adminuser; - NSString *adminpass; - NSString *defaultdb; - NSString *sshhost; - NSNumber *sshport; - NSString *sshuser; - NSString *sshpassword; - NSString *sshkeyfile; - NSString *bindaddress; - NSNumber *bindport; - NSSet *databases; - NSNumber *usessh; - NSNumber *userepl; -} - -@property (nonatomic, retain) NSString *host; -@property (nonatomic, retain) NSNumber *hostport; -@property (nonatomic, retain) NSString *servers; -@property (nonatomic, retain) NSString *repl_name; -@property (nonatomic, retain) NSString *alias; -@property (nonatomic, retain) NSString *adminuser; -@property (nonatomic, retain) NSString *adminpass; -@property (nonatomic, retain) NSString *defaultdb; -@property (nonatomic, retain) NSSet *databases; -@property (nonatomic, retain) NSString *sshhost; -@property (nonatomic, retain) NSNumber *sshport; -@property (nonatomic, retain) NSString *sshuser; -@property (nonatomic, retain) NSString *sshpassword; -@property (nonatomic, retain) NSString *sshkeyfile; -@property (nonatomic, retain) NSString *bindaddress; -@property (nonatomic, retain) NSNumber *bindport; -@property (nonatomic, retain) NSNumber *usessh; -@property (nonatomic, retain) NSNumber *userepl; - -@end diff --git a/Connection.m b/Connection.m deleted file mode 100644 index 2391c20d..00000000 --- a/Connection.m +++ /dev/null @@ -1,34 +0,0 @@ -// -// Database.m -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "Connection.h" - - -@implementation Connection - -@dynamic host; -@dynamic hostport; -@dynamic servers; -@dynamic repl_name; -@dynamic alias; -@dynamic adminuser; -@dynamic adminpass; -@dynamic defaultdb; -@dynamic databases; -@dynamic userepl; - -@dynamic usessh; -@dynamic sshhost; -@dynamic sshport; -@dynamic sshuser; -@dynamic sshpassword; -@dynamic sshkeyfile; -@dynamic bindaddress; -@dynamic bindport; - -@end diff --git a/ConnectionWindow.xib b/ConnectionWindow.xib deleted file mode 100644 index 73034e21..00000000 --- a/ConnectionWindow.xib +++ /dev/null @@ -1,5050 +0,0 @@ - - - - 1060 - 10H574 - 804 - 1038.35 - 461.00 - - YES - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - - YES - 804 - 1.2.5 - - - - YES - - - - YES - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - ConnectionWindowController - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{196, 136}, {602, 374}} - 544735232 - Connection - NSWindow - - - 7EE2452B-3491-489A-B3C7-6BD8F3CBF202 - - - YES - YES - NO - NO - 1 - 1 - - YES - - YES - 21F03A7D-92DA-42FA-AAEA-D7B1EF834D11 - 3FEB340C-F054-493C-91C4-92418D962C79 - 4D4E3568-E902-4DC1-ABF9-F65CE1FF5413 - 7570D86F-BDDE-452B-AFBE-39E3FF3575EC - 895D0A60-1B01-483E-AD74-ACC9B8C8D993 - C119880A-AA1D-4455-B962-E5BDAEF3CE4A - E5F27936-36E8-4B49-BDE3-2B693E8F1265 - NSToolbarFlexibleSpaceItem - NSToolbarSeparatorItem - NSToolbarSpaceItem - - - YES - - - 21F03A7D-92DA-42FA-AAEA-D7B1EF834D11 - - Database stats - Database stats - - - - NSImage - dbmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 3FEB340C-F054-493C-91C4-92418D962C79 - - Server Status - Server Status - - - - NSImage - servermenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 4D4E3568-E902-4DC1-ABF9-F65CE1FF5413 - - Query - Query - - - - NSImage - querymenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 7570D86F-BDDE-452B-AFBE-39E3FF3575EC - - Collection Stats - Collection Stats - - - - NSImage - collectionmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 895D0A60-1B01-483E-AD74-ACC9B8C8D993 - - Support - Support - - - - NSImage - supportmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - C119880A-AA1D-4455-B962-E5BDAEF3CE4A - - Import(MySQL) - Import - - - - NSImage - importbox - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - E5F27936-36E8-4B49-BDE3-2B693E8F1265 - - Export(MySQL) - Export - - - - NSImage - exportbox - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - NSToolbarFlexibleSpaceItem - - Flexible Space - - - - - - {1, 5} - {20000, 32} - YES - YES - -1 - YES - 0 - - YES - YES - - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - - - - NSToolbarSeparatorItem - - Separator - - - - - - {12, 5} - {12, 1000} - YES - YES - -1 - YES - 0 - - YES - YES - - - 1048576 - 2147483647 - - - - - - NSToolbarSpaceItem - - Space - - - - - - {32, 5} - {32, 32} - YES - YES - -1 - YES - 0 - - YES - YES - - - 1048576 - 2147483647 - - - - - - - - YES - - - - - - - - - - - - - YES - - - - - - - - - - - YES - - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 274 - - YES - - - 256 - - YES - - - 290 - - YES - - - 268 - {{-1, -1}, {32, 24}} - - 2 - YES - - 67239424 - 134348800 - - - LucidaGrande - 11 - 3100 - - - -2033958657 - 163 - - NSImage - NSAddTemplate - - - - 200 - 25 - - - - - 268 - {{30, -1}, {32, 24}} - - 2 - YES - - 67239424 - 134348800 - - - - -2033958657 - 163 - - NSImage - NSRemoveTemplate - - - - 200 - 25 - - - - - 268 - {{61, -1}, {32, 24}} - - YES - - 67239424 - 134348800 - - - - -2033958657 - 163 - - NSImage - key - - - - 200 - 25 - - - - {145, 23} - - 2 - YES - YES - NO - 0 - - - - 4370 - - YES - - - 2304 - - YES - - - 4352 - {145, 354} - - 2 - YES - - - 256 - {{232, 0}, {16, 17}} - - - YES - - SidebarColumn - 142 - 16 - 1000 - - 75628096 - 2048 - - - - 3 - MC4zMzMzMzI5ODU2AA - - - 6 - System - headerTextColor - - 3 - MAA - - - - - 337772096 - 2048 - Text Cell - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlBackgroundColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - - - 3 - YES - YES - - - - 3 - 0.0 - - 6 - System - _sourceListBackgroundColor - - 1 - MC44MzkyMTU2OTU5IDAuODY2NjY2Njc0NiAwLjg5ODAzOTIyMTgAA - - - - 6 - System - gridColor - - 3 - MC41AA - - - 20 - -767557632 - - - 4 - 15 - 0 - YES - 1 - 1 - 14 - - - {145, 354} - - - 2 - - - 4 - - - - -2147483392 - {{232, 0}, {15, 368}} - - 2 - - _doScroller: - 0.99729001522064209 - - - - -2147483392 - {{0, 368}, {232, 15}} - - 2 - 1 - - _doScroller: - 0.99570822715759277 - - - {{0, 20}, {145, 354}} - - - 2 - 560 - - - - QSAAAEEgAABBoAAAQaAAAA - - - {145, 374} - - 2 - NSView - - - - 258 - - YES - - - 266 - - YES - - - 266 - {{26, 4}, {227, 17}} - - YES - - 68288064 - 272630784 - - - Explain - - - 6 - System - controlColor - - - - 1 - MC4yMDAwMDAwMDMgMC4yMDAwMDAwMDMgMC4yMDAwMDAwMDMAA - - - - - - 1292 - - {{5, 5}, {16, 16}} - - 20746 - 100 - - - - 265 - {{253, 4}, {101, 18}} - - YES - - -1543373312 - 134348800 - Stat Monitor - - - -2034482945 - 163 - - NSImage - NSSlideshowTemplate - - - - 400 - 75 - - - - - 265 - {{356, 4}, {83, 18}} - - YES - - -1543373312 - 134348800 - Reconnect - - - -2034482945 - 163 - - NSImage - NSRefreshTemplate - - - - 400 - 75 - - - - {{0, 347}, {447, 27}} - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 4370 - - YES - - - 2304 - - YES - - - 4352 - {447, 331} - - 2 - YES - - - 256 - {447, 17} - - 2 - - - - - -2147483392 - {{431, 0}, {16, 17}} - - 2 - - - YES - - name - 132 - 16 - 1000 - - 75628096 - 2048 - Name - - - 3 - MC4zMzMzMzI5ODU2AA - - - - - 337772032 - 0 - Text Cell - - LucidaGrande-Bold - 13 - 16 - - - - - - 3 - YES - - - - value - 226 - 40 - 1000 - - 75628096 - 2048 - Value - - - - - - 337772032 - 0 - Text Cell - - LucidaGrande - 11 - 16 - - - - - - 3 - YES - - - - type - 80 - 80 - 80 - - 75628096 - 2048 - Type - - - 6 - System - headerColor - - 3 - MQA - - - - - - 337772032 - 0 - Text Cell - - - - - - 3 - YES - - - - 3 - 0.0 - - 6 - System - _sourceListBackgroundColor - - 1 - MC44MzkyMTU2OTU5IDAuODY2NjY2Njc0NiAwLjg5ODAzOTIyMTgAA - - - - 20 - -759169024 - - - 1 - 2 - 15 - 0 - YES - 1 - 1 - 14 - - - {{0, 17}, {447, 331}} - - - 2 - - - 4 - - - - -2147483392 - {{431, 17}, {15, 341}} - - 2 - - _doScroller: - 0.95468276739120483 - - - - -2147483392 - {{0, 333}, {432, 15}} - - 2 - 1 - - _doScroller: - 0.9977678656578064 - - - - 2304 - - YES - - - {447, 17} - - - 2 - - - 4 - - - - {447, 348} - - - 2 - 560 - - - - - - QSAAAEEgAABBoAAAQaAAAA - - - {{155, 0}, {447, 374}} - - 2 - NSView - - - {602, 374} - - 2 - YES - 3 - - - {602, 374} - - 2 - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - - YES - YES - - Database - - YES - YES - YES - YES - YES - YES - YES - - - ResultsOutlineViewController - - - - - YES - - - - YES - - - - 17 - 2 - {{140, 283}, {331, 175}} - -1535639552 - Support Panel - NSPanel - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 266 - {{17, 133}, {297, 22}} - - YES - - 68288064 - 138413056 - MongoHub - - LucidaGrande-Bold - 18 - 16 - - - - - - - - - 266 - {{17, 111}, {297, 14}} - - YES - - 68288064 - 138413056 - version 2.1.0 - - - - - 1 - MC4yOTgwMzkyMjc3IDAuMjk4MDM5MjI3NyAwLjI5ODAzOTIyNzcAA - - - - - - 268 - {{17, 42}, {297, 61}} - - YES - - 67239424 - 138412032 - QXV0aG9yOiBwcm9mLnN5ZC54dUBnbWFpbC5jb20KV2Vic2l0ZTogaHR0cDovL21vbmdvaHViLnRvZGF5 -Y2xvc2UuY29tLwpUd2l0dGVyOiBodHRwOi8vdHdpdHRlci5jb20vYnVidWJhLw - - LucidaGrande - 12 - 16 - - - - - 1 - MC4wOTgwMzkyMTcyOSAwLjA5ODAzOTIxNzI5IDAuMDk4MDM5MjE3MjkAA - - - - - - 288 - {{128, 18}, {75, 25}} - - YES - - -2080244224 - 134217728 - Close - - - -2038152961 - 163 - - - 400 - 75 - - - - {331, 175} - - {{0, 0}, {1280, 778}} - {3.40282e+38, 3.40282e+38} - - - - - YES - - - - YES - - - - 8223 - 2 - {{131, 133}, {753, 296}} - 611844096 - Window - NSPanel - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 288 - {{275, -4}, {203, 28}} - - YES - - 67239424 - 134348800 - Close - - - -2038284033 - 129 - - - 200 - 25 - - - - - 4370 - - YES - - - 2304 - - YES - - - 4352 - {751, 247} - - YES - - - 256 - {751, 17} - - - - - - -2147483392 - {{-26, 0}, {16, 17}} - - - - YES - - insert - 53 - 40 - 1000 - - 75628096 - 2048 - insert/s - - - 3 - MC4zMzMzMzI5ODU2AA - - - - - 337772096 - -2147481600 - Text Cell - - LucidaGrande-Bold - 10 - 16 - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - YES - - - YES - - - - - 0 - 0 - YES - NO - 1 - AAAAAAAAAAAAAAAAAAAAAA - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - 6 - System - textBackgroundColor - - - - 1 - MSAxIDEAA - - - 3 - YES - - - - query - 50 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - query/s - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - update - 57 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - update/s - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - delete - 52 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - delete/s - - - - - - 604110336 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - getmore - 65 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - getmore/s - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - command - 43 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - cmd/s - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - mapped - 52 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - mapped - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - vsize - 35 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - vsize - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - res - 25 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - res - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - faults - 50 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - faults/s - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - locked - 54 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - locked % - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - lenient - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - - -∞ - - - +∞ - - - #,##0% - #,##0% - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - misses - 76 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - idx misses % - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0% - #,##0% - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - conn - 35 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - conn - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - - - - 3 - YES - - - - time - 62 - 10 - 3.4028234663852886e+38 - - 75628096 - 2048 - time - - - - - - 67239424 - -2147483648 - Field - - - - YES - - YES - dateFormat - dateStyle - formatterBehavior - timeStyle - - - YES - HH:mm:ss - - - - - - HH:mm:ss - NO - - - - - - 3 - YES - - - - 3 - 2 - - - 20 - -692027392 - - - 1 - 15 - 0 - YES - 0 - - - {{0, 17}, {751, 247}} - - - - - 4 - MSAwLjE0MDAwMDAwMDYAA - - 4 - - - - -2147483392 - {{-100, -100}, {15, 120}} - - 2 - - _doScroller: - 0.93560606241226196 - - - - -2147483392 - {{-100, -100}, {225, 15}} - - 1 - - _doScroller: - 0.57142859697341919 - - - - 2304 - - YES - - - {751, 17} - - - - - 4 - - - - {{1, 32}, {751, 264}} - - - 528 - - - - - - QSAAAEEgAABBsAAAQbAAAA - - - {753, 296} - - {{0, 0}, {1280, 778}} - {3.40282e+38, 3.40282e+38} - - - - - YES - - - window - - - - 3 - - - - delegate - - - - 4 - - - - title: self.conn - - - - - - title: self.conn - title - self.conn - - NSValueTransformerName - ConnectionWindowTitleTransformer - - 2 - - - 10 - - - - sidebar - - - - 78 - - - - managedObjectContext: managedObjectContext - - - - - - managedObjectContext: managedObjectContext - managedObjectContext - managedObjectContext - 2 - - - 88 - - - - resultsOutlineViewController - - - - 112 - - - - dataSource - - - - 114 - - - - delegate - - - - 115 - - - - myOutlineView - - - - 119 - - - - resultsTitle - - - - 128 - - - - dropDBorCollection: - - - - 130 - - - - createDBorCollection: - - - - 141 - - - - query: - - - - 143 - - - - showServerStatus: - - - - 147 - - - - showDBStats: - - - - 148 - - - - showCollStats: - - - - 149 - - - - openSheet: - - - - 152 - - - - sheet - - - - 155 - - - - parentWindow - - - - 156 - - - - closeSheet: - - - - 169 - - - - bundleVersion - - - - 174 - - - - showAuth: - - - - 179 - - - - importFromMySQL: - - - - 182 - - - - exportToMySQL: - - - - 183 - - - - loaderIndicator - - - - 185 - - - - parentWindow - - - - 189 - - - - sheet - - - - 193 - - - - monitorButton - - - - 194 - - - - stopMonitor: - - - - 202 - - - - monitorSheetController - - - - 203 - - - - startMonitor: - - - - 204 - - - - statMonitorTableController - - - - 261 - - - - dataSource - - - - 263 - - - - delegate - - - - 264 - - - - nsTableView - - - - 276 - - - - reconnect: - - - - 291 - - - - reconnectButton - - - - 292 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - 0D5950D1-D4A8-44C6-9DBC-251CFEF852E2 - - - - BAtzdHJlYW10eXBlZIHoA4QBQISEhAxOU0RpY3Rpb25hcnkAhIQITlNPYmplY3QAhYQBaQGShISECE5T -U3RyaW5nAZSEASskMEQ1OTUwRDEtRDRBOC00NEM2LTlEQkMtMjUxQ0ZFRjg1MkUyhpKEhIQHTlNWYWx1 -ZQCUhAEqhIQMe19OU1NpemU9ZmZ9moFaAoF2AYaGA - - 0D5950D1-D4A8-44C6-9DBC-251CFEF852E2 - - {602, 452} - NO - - - - - - - 2 - - - YES - - - - - - 12 - - - - - 29 - - - YES - - - - - - - 30 - - - YES - - - - - - - 31 - - - YES - - - - - - - 32 - - - YES - - - - - - - - 33 - - - YES - - - - - - 34 - - - - - 35 - - - YES - - - - - - 36 - - - - - 72 - - - YES - - - - - - - - 73 - - - YES - - - - - - 74 - - - - - 75 - - - - - 76 - - - YES - - - - - - 77 - - - - - 79 - - - YES - - - - - - - - - - - - - - - 82 - - - - - 84 - - - - - 85 - - - - - 87 - - - - - 101 - - - YES - - - - - - - - - 102 - - - - - 103 - - - - - 104 - - - YES - - - - - - - - 105 - - - - - 106 - - - YES - - - - - - 107 - - - YES - - - - - - 108 - - - - - 109 - - - - - 111 - - - - - 117 - - - YES - - - - - - 118 - - - - - 121 - - - YES - - - - - - - - - 122 - - - YES - - - - - - 123 - - - - - 142 - - - - - 144 - - - - - 145 - - - - - 146 - - - - - 150 - - - - - 151 - - - Help Sheet Controller - - - 153 - - - YES - - - - - - 154 - - - YES - - - - - - - - - 157 - - - YES - - - - - - 158 - - - - - 159 - - - YES - - - - - - 160 - - - - - 165 - - - YES - - - - - - 166 - - - - - 167 - - - YES - - - - - - 168 - - - - - 177 - - - YES - - - - - - 178 - - - - - 180 - - - - - 181 - - - - - 184 - - - - - 186 - - - YES - - - - - - 187 - - - - - 188 - - - Monitor Sheet Controller - - - 191 - - - YES - - - - - - 192 - - - YES - - - - - - - 197 - - - YES - - - - - - 198 - - - - - 205 - - - YES - - - - - - - - - 206 - - - - - 207 - - - - - 208 - - - YES - - - - - - - - - - - - - - - - - - - 209 - - - YES - - - - - - 210 - - - YES - - - - - - 211 - - - YES - - - - - - 213 - - - YES - - - - - - 215 - - - YES - - - - - - 217 - - - YES - - - - - - 219 - - - YES - - - - - - 221 - - - YES - - - - - - 223 - - - YES - - - - - - 225 - - - YES - - - - - - 227 - - - YES - - - - - - 229 - - - YES - - - - - - 231 - - - YES - - - - - - 233 - - - YES - - - - - - 235 - - - YES - - - - - - 237 - - - YES - - - - - - 238 - - - YES - - - - - - 239 - - - YES - - - - - - 240 - - - YES - - - - - - 241 - - - YES - - - - - - 242 - - - YES - - - - - - 243 - - - YES - - - - - - 244 - - - YES - - - - - - 245 - - - YES - - - - - - 246 - - - YES - - - - - - 247 - - - YES - - - - - - 248 - - - YES - - - - - - 249 - - - YES - - - - - - 250 - - - - - 251 - - - - - 252 - - - - - 253 - - - - - 260 - - - - - 266 - - - - - 267 - - - - - 268 - - - - - 269 - - - - - 270 - - - - - 271 - - - - - 272 - - - - - 273 - - - - - 274 - - - - - 275 - - - - - 277 - - - - - 289 - - - YES - - - - - - 290 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 101.IBPluginDependency - 101.IBViewBoundsToFrameTransform - 102.IBPluginDependency - 103.IBPluginDependency - 104.IBPluginDependency - 105.IBPluginDependency - 106.IBPluginDependency - 107.IBPluginDependency - 108.IBPluginDependency - 109.IBPluginDependency - 111.IBPluginDependency - 121.IBPluginDependency - 122.IBPluginDependency - 122.IBViewBoundsToFrameTransform - 122.IBViewIntegration.shadowBlurRadius - 122.IBViewIntegration.shadowColor - 122.IBViewIntegration.shadowOffsetHeight - 122.IBViewIntegration.shadowOffsetWidth - 123.IBPluginDependency - 142.IBPluginDependency - 144.IBPluginDependency - 145.IBPluginDependency - 146.IBPluginDependency - 150.IBPluginDependency - 151.IBPluginDependency - 153.IBEditorWindowLastContentRect - 153.IBPluginDependency - 153.IBWindowTemplateEditedContentRect - 153.NSWindowTemplate.visibleAtLaunch - 154.IBPluginDependency - 157.IBPluginDependency - 158.IBPluginDependency - 159.IBPluginDependency - 160.IBPluginDependency - 165.IBPluginDependency - 166.IBPluginDependency - 167.IBPluginDependency - 168.IBPluginDependency - 177.IBPluginDependency - 178.IBPluginDependency - 180.IBPluginDependency - 181.IBPluginDependency - 184.IBPluginDependency - 184.IBViewBoundsToFrameTransform - 186.IBPluginDependency - 186.IBViewBoundsToFrameTransform - 187.IBPluginDependency - 188.IBPluginDependency - 191.IBEditorWindowLastContentRect - 191.IBPluginDependency - 191.IBWindowTemplateEditedContentRect - 191.NSWindowTemplate.visibleAtLaunch - 191.windowTemplate.hasMaxSize - 191.windowTemplate.maxSize - 192.IBPluginDependency - 197.IBPluginDependency - 197.IBViewBoundsToFrameTransform - 198.IBPluginDependency - 2.IBPluginDependency - 205.IBPluginDependency - 205.IBViewBoundsToFrameTransform - 206.IBPluginDependency - 207.IBPluginDependency - 208.IBPluginDependency - 209.IBPluginDependency - 210.IBPluginDependency - 251.IBNumberFormatterBehaviorMetadataKey - 251.IBNumberFormatterLocalizesFormatMetadataKey - 251.IBPluginDependency - 252.IBNumberFormatterBehaviorMetadataKey - 252.IBNumberFormatterLocalizesFormatMetadataKey - 252.IBPluginDependency - 253.IBDateFormatterBehaviorMetadataKey - 253.IBPluginDependency - 260.CustomClassName - 260.IBPluginDependency - 266.IBNumberFormatterBehaviorMetadataKey - 266.IBNumberFormatterLocalizesFormatMetadataKey - 266.IBPluginDependency - 267.IBNumberFormatterBehaviorMetadataKey - 267.IBNumberFormatterLocalizesFormatMetadataKey - 267.IBPluginDependency - 268.IBNumberFormatterBehaviorMetadataKey - 268.IBNumberFormatterLocalizesFormatMetadataKey - 268.IBPluginDependency - 269.IBNumberFormatterBehaviorMetadataKey - 269.IBNumberFormatterLocalizesFormatMetadataKey - 269.IBPluginDependency - 270.IBNumberFormatterBehaviorMetadataKey - 270.IBNumberFormatterLocalizesFormatMetadataKey - 270.IBPluginDependency - 271.IBNumberFormatterBehaviorMetadataKey - 271.IBNumberFormatterLocalizesFormatMetadataKey - 271.IBPluginDependency - 272.IBNumberFormatterBehaviorMetadataKey - 272.IBNumberFormatterLocalizesFormatMetadataKey - 272.IBPluginDependency - 273.IBNumberFormatterBehaviorMetadataKey - 273.IBNumberFormatterLocalizesFormatMetadataKey - 273.IBPluginDependency - 274.IBNumberFormatterBehaviorMetadataKey - 274.IBNumberFormatterLocalizesFormatMetadataKey - 274.IBPluginDependency - 275.IBNumberFormatterBehaviorMetadataKey - 275.IBNumberFormatterLocalizesFormatMetadataKey - 275.IBPluginDependency - 277.IBNumberFormatterBehaviorMetadataKey - 277.IBNumberFormatterLocalizesFormatMetadataKey - 277.IBPluginDependency - 289.IBPluginDependency - 289.IBViewBoundsToFrameTransform - 29.IBPluginDependency - 290.IBPluginDependency - 30.IBPluginDependency - 31.IBPluginDependency - 32.IBPluginDependency - 33.IBPluginDependency - 34.IBPluginDependency - 35.IBPluginDependency - 36.IBPluginDependency - 72.IBPluginDependency - 73.CustomClassName - 73.IBPluginDependency - 74.IBPluginDependency - 75.IBPluginDependency - 76.IBPluginDependency - 77.CustomClassName - 77.IBPluginDependency - 79.IBEditorWindowLastContentRect - 79.IBPluginDependency - 82.IBPluginDependency - 84.IBPluginDependency - 85.IBPluginDependency - 87.CustomClassName - 87.IBPluginDependency - - - YES - {{47, 212}, {602, 374}} - com.apple.InterfaceBuilder.CocoaPlugin - {{47, 212}, {602, 374}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAAAAAAAAw60AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwZgAAA - - - - 1 - MCAwIDAAA - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - {{100, 482}, {331, 175}} - com.apple.InterfaceBuilder.CocoaPlugin - {{100, 482}, {331, 175}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAAAAAAAAwaAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDdwAAwaAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - {{46, 420}, {753, 296}} - com.apple.InterfaceBuilder.CocoaPlugin - {{46, 420}, {753, 296}} - - - {519, 301} - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - P4AAAL+AAABDmIAAwbAAAA - - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - P4AAAL+AAAA/gAAAw5WAAA - - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - StatMonitorTableController - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDcAAAwaAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - Sidebar - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - SidebarBadgeCell - com.apple.InterfaceBuilder.CocoaPlugin - {{42, 687}, {616, 0}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - DatabasesArrayController - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 292 - - - - YES - - ConnectionWindowController - NSWindowController - - YES - - YES - createDBorCollection: - dropDBorCollection: - exportToMySQL: - importFromMySQL: - query: - reconnect: - showAuth: - showCollStats: - showDBStats: - showServerStatus: - startMonitor: - stopMonitor: - useCollection: - useDB: - - - YES - id - id - id - id - id - id - id - id - id - id - id - id - id - id - - - - YES - - YES - createDBorCollection: - dropDBorCollection: - exportToMySQL: - importFromMySQL: - query: - reconnect: - showAuth: - showCollStats: - showDBStats: - showServerStatus: - startMonitor: - stopMonitor: - useCollection: - useDB: - - - YES - - createDBorCollection: - id - - - dropDBorCollection: - id - - - exportToMySQL: - id - - - importFromMySQL: - id - - - query: - id - - - reconnect: - id - - - showAuth: - id - - - showCollStats: - id - - - showDBStats: - id - - - showServerStatus: - id - - - startMonitor: - id - - - stopMonitor: - id - - - useCollection: - id - - - useDB: - id - - - - - YES - - YES - bundleVersion - databaseArrayController - loaderIndicator - monitorButton - monitorSheetController - reconnectButton - resultsOutlineViewController - resultsTitle - sidebar - statMonitorTableController - - - YES - NSTextField - DatabasesArrayController - NSProgressIndicator - NSButton - BWSheetController - NSButton - ResultsOutlineViewController - NSTextField - Sidebar - StatMonitorTableController - - - - YES - - YES - bundleVersion - databaseArrayController - loaderIndicator - monitorButton - monitorSheetController - reconnectButton - resultsOutlineViewController - resultsTitle - sidebar - statMonitorTableController - - - YES - - bundleVersion - NSTextField - - - databaseArrayController - DatabasesArrayController - - - loaderIndicator - NSProgressIndicator - - - monitorButton - NSButton - - - monitorSheetController - BWSheetController - - - reconnectButton - NSButton - - - resultsOutlineViewController - ResultsOutlineViewController - - - resultsTitle - NSTextField - - - sidebar - Sidebar - - - statMonitorTableController - StatMonitorTableController - - - - - IBProjectSource - ConnectionWindowController.h - - - - DatabasesArrayController - NSArrayController - - IBProjectSource - DatabasesArrayController.h - - - - NSObject - - IBProjectSource - JSON/NSObject+SBJSON.h - - - - NSObject - - IBProjectSource - JSON/SBJsonWriter.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - NSProgressIndicator - - IBProjectSource - NSProgressIndicator+Extras.h - - - - ResultsOutlineViewController - NSObject - - myOutlineView - NSOutlineView - - - myOutlineView - - myOutlineView - NSOutlineView - - - - IBProjectSource - ResultsOutlineViewController.h - - - - Sidebar - NSOutlineView - - IBProjectSource - Sidebar/Sidebar.h - - - - SidebarBadgeCell - NSTextFieldCell - - IBProjectSource - Sidebar/SidebarBadgeCell.h - - - - StatMonitorTableController - NSControl - - nsTableView - BWTransparentTableView - - - nsTableView - - nsTableView - BWTransparentTableView - - - - IBProjectSource - StatMonitorTableController.h - - - - - YES - - BWAnchoredButton - NSButton - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWAnchoredButton.h - - - - BWAnchoredButtonBar - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWAnchoredButtonBar.h - - - - BWAnchoredButtonCell - NSButtonCell - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWAnchoredButtonCell.h - - - - BWGradientBox - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWGradientBox.h - - - - BWSheetController - NSObject - - YES - - YES - closeSheet: - messageDelegateAndCloseSheet: - openSheet: - - - YES - id - id - id - - - - YES - - YES - closeSheet: - messageDelegateAndCloseSheet: - openSheet: - - - YES - - closeSheet: - id - - - messageDelegateAndCloseSheet: - id - - - openSheet: - id - - - - - YES - - YES - delegate - parentWindow - sheet - - - YES - id - NSWindow - NSWindow - - - - YES - - YES - delegate - parentWindow - sheet - - - YES - - delegate - id - - - parentWindow - NSWindow - - - sheet - NSWindow - - - - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWSheetController.h - - - - BWTransparentButton - NSButton - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTransparentButton.h - - - - BWTransparentButtonCell - NSButtonCell - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTransparentButtonCell.h - - - - BWTransparentScrollView - NSScrollView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTransparentScrollView.h - - - - BWTransparentScroller - NSScroller - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTransparentScroller.h - - - - BWTransparentTableView - NSTableView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTransparentTableView.h - - - - BWTransparentTableViewCell - NSTextFieldCell - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTransparentTableViewCell.h - - - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSDateFormatter - NSFormatter - - IBFrameworkSource - Foundation.framework/Headers/NSDateFormatter.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSNumberFormatter - NSFormatter - - IBFrameworkSource - Foundation.framework/Headers/NSNumberFormatter.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSOutlineView - NSTableView - - - - NSPanel - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSPanel.h - - - - NSProgressIndicator - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSProgressIndicator.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSScrollView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSScrollView.h - - - - NSScroller - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSScroller.h - - - - NSSplitView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSSplitView.h - - - - NSTableColumn - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableColumn.h - - - - NSTableHeaderView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSTableHeaderView.h - - - - NSTableView - NSControl - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSToolbar - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbar.h - - - - NSToolbarItem - NSObject - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - YES - - YES - NSAddTemplate - NSMenuCheckmark - NSMenuMixedState - NSRefreshTemplate - NSRemoveTemplate - NSSlideshowTemplate - collectionmenu - dbmenu - exportbox - importbox - key - querymenu - servermenu - supportmenu - - - YES - {8, 8} - {9, 8} - {7, 2} - {10, 12} - {8, 8} - {17, 14} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - {24, 24} - {32, 32} - {32, 32} - {32, 32} - - - - diff --git a/ConnectionWindowController.h b/ConnectionWindowController.h deleted file mode 100644 index 5e58aef5..00000000 --- a/ConnectionWindowController.h +++ /dev/null @@ -1,104 +0,0 @@ -// -// ConnectionWindowController.h -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import -#import "Tunnel.h" -@class BWSheetController; -@class DatabasesArrayController; -@class StatMonitorTableController; -@class AddDBController; -@class AddCollectionController; -@class AuthWindowController; -@class ImportWindowController; -@class ExportWindowController; -@class ResultsOutlineViewController; -@class Connection; -@class Sidebar; -@class SidebarNode; -@class MongoDB; - -@interface ConnectionWindowController : NSWindowController { - NSManagedObjectContext *managedObjectContext; - IBOutlet DatabasesArrayController *databaseArrayController; - IBOutlet ResultsOutlineViewController *resultsOutlineViewController; - Connection *conn; - MongoDB *mongoDB; - IBOutlet Sidebar *sidebar; - IBOutlet NSTextField *resultsTitle; - IBOutlet NSProgressIndicator *loaderIndicator; - IBOutlet NSButton *reconnectButton; - IBOutlet NSButton *monitorButton; - IBOutlet BWSheetController *monitorSheetController; - IBOutlet StatMonitorTableController *statMonitorTableController; - NSMutableArray *databases; - NSMutableArray *collections; - SidebarNode *selectedDB; - SidebarNode *selectedCollection; - Tunnel *sshTunnel; - AddDBController *addDBController; - AddCollectionController *addCollectionController; - AuthWindowController *authWindowController; - ImportWindowController *importWindowController; - ExportWindowController *exportWindowController; - IBOutlet NSTextField *bundleVersion; - BOOL exitThread; - BOOL monitorStopped; -} - -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, retain) DatabasesArrayController *databaseArrayController; -@property (nonatomic, retain) ResultsOutlineViewController *resultsOutlineViewController; -@property (nonatomic, retain) Connection *conn; -@property (nonatomic, retain) MongoDB *mongoDB; -@property (nonatomic, retain) Sidebar *sidebar; -@property (nonatomic, retain) NSMutableArray *databases; -@property (nonatomic, retain) NSMutableArray *collections; -@property (nonatomic, retain) SidebarNode *selectedDB; -@property (nonatomic, retain) SidebarNode *selectedCollection; -@property (nonatomic, retain) Tunnel *sshTunnel; -@property (nonatomic, retain) NSTextField *resultsTitle; -@property (nonatomic, retain) NSProgressIndicator *loaderIndicator; -@property (nonatomic, retain) NSButton *monitorButton; -@property (nonatomic, retain) NSButton *reconnectButton; -@property (nonatomic, retain) BWSheetController *monitorSheetController; -@property (nonatomic, retain) StatMonitorTableController *statMonitorTableController; -@property (nonatomic, retain) AddDBController *addDBController; -@property (nonatomic, retain) AddCollectionController *addCollectionController; -@property (nonatomic, retain) NSTextField *bundleVersion; -@property (nonatomic, retain) AuthWindowController *authWindowController; -@property (nonatomic, retain) ImportWindowController *importWindowController; -@property (nonatomic, retain) ExportWindowController *exportWindowController; - -- (void)reloadSidebar; -- (void)reloadDBList; -- (void)useDB:(id)sender; -- (void)useCollection:(id)sender; -- (IBAction)reconnect:(id)sender; -- (IBAction)showServerStatus:(id)sender; -- (IBAction)showDBStats:(id)sender; -- (IBAction)showCollStats:(id)sender; -- (IBAction)createDBorCollection:(id)sender; -- (IBAction)importFromMySQL:(id)sender; -- (IBAction)exportToMySQL:(id)sender; -- (void)dropCollection:(NSString *)collectionname - ForDB:(NSString *)dbname; -- (void)createDB; -- (void)createCollectionForDB:(NSString *)dbname; -- (IBAction)dropDBorCollection:(id)sender; -- (void)dropDB; -- (IBAction)query:(id)sender; -- (IBAction)showAuth:(id)sender; --(void) checkTunnel; -- (void) connect:(BOOL)haveHostAddress; -- (void) tunnelStatusChanged: (Tunnel*) tunnel status: (NSString*) status; -- (void)dropWarning:(NSString *)msg; - -- (IBAction)startMonitor:(id)sender; -- (IBAction)stopMonitor:(id)sender; -- (void)updateMonitor; -@end diff --git a/ConnectionWindowController.mm b/ConnectionWindowController.mm deleted file mode 100644 index b16162a0..00000000 --- a/ConnectionWindowController.mm +++ /dev/null @@ -1,644 +0,0 @@ -// -// ConnectionWindowController.m -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "Configure.h" -#import "NSString+Extras.h" -#import "NSProgressIndicator+Extras.h" -#import -#import "ConnectionWindowController.h" -#import "QueryWindowController.h" -#import "AddDBController.h"; -#import "AddCollectionController.h" -#import "AuthWindowController.h" -#import "ImportWindowController.h" -#import "ExportWindowController.h" -#import "ResultsOutlineViewController.h" -#import "DatabasesArrayController.h" -#import "StatMonitorTableController.h" -#import "Connection.h" -#import "Sidebar.h" -#import "SidebarNode.h" -#import "MongoDB.h" -#import "Tunnel.h" - -@implementation ConnectionWindowController - -@synthesize managedObjectContext; -@synthesize databaseArrayController; -@synthesize resultsOutlineViewController; -@synthesize conn; -@synthesize mongoDB; -@synthesize sidebar; -@synthesize loaderIndicator; -@synthesize monitorButton; -@synthesize reconnectButton; -@synthesize monitorSheetController; -@synthesize statMonitorTableController; -@synthesize databases; -@synthesize collections; -@synthesize selectedDB; -@synthesize selectedCollection; -@synthesize sshTunnel; -@synthesize addDBController; -@synthesize addCollectionController; -@synthesize resultsTitle; -@synthesize bundleVersion; -@synthesize authWindowController; -@synthesize importWindowController; -@synthesize exportWindowController; - - -- (id)init { - if (![super initWithWindowNibName:@"ConnectionWindow"]) return nil; - return self; -} - -- (void) tunnelStatusChanged: (Tunnel*) tunnel status: (NSString*) status { - NSLog(@"SSH TUNNEL STATUS: %@", status); - if( [status isEqualToString: @"CONNECTED"] ){ - exitThread = YES; - [self connect:YES]; - } -} - -- (void) connect:(BOOL)haveHostAddress { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [loaderIndicator start]; - [reconnectButton setEnabled:NO]; - [monitorButton setEnabled:NO]; - bool connected; - NSString *hostaddress = [[[NSString alloc] init] autorelease]; - if (!haveHostAddress && [conn.usessh intValue]==1) { - NSString *portForward = [[NSString alloc] initWithFormat:@"L:%@:%@:%@:%@", conn.hostport, conn.host, conn.sshhost, conn.bindport]; - NSMutableArray *portForwardings = [[NSMutableArray alloc] initWithObjects:portForward, nil]; - [portForward release]; - if (!sshTunnel) - sshTunnel =[[Tunnel alloc] init]; - [sshTunnel setDelegate:self]; - [sshTunnel setUser:conn.sshuser]; - [sshTunnel setHost:conn.sshhost]; - [sshTunnel setPassword:conn.sshpassword]; - [sshTunnel setKeyfile:conn.sshkeyfile]; - [sshTunnel setPort:[conn.sshport intValue]]; - [sshTunnel setPortForwardings:portForwardings]; - [sshTunnel setAliveCountMax:3]; - [sshTunnel setAliveInterval:30]; - [sshTunnel setTcpKeepAlive:YES]; - [sshTunnel setCompression:YES]; - //[sshTunnel start]; - [portForwardings release]; - return; - }else if (!haveHostAddress && [conn.host isEqualToString:@"flame.mongohq.com"]) { - hostaddress = [NSString stringWithFormat:@"%@:%@/%@", conn.host, conn.hostport, conn.defaultdb]; - connected = mongoDB = [[MongoDB alloc] initWithConn:hostaddress]; - }else { - if ([conn.userepl intValue] == 1) { - hostaddress = conn.repl_name; - NSArray *tmp = [conn.servers componentsSeparatedByString:@","]; - NSMutableArray *hosts = [[NSMutableArray alloc] initWithCapacity:[tmp count]]; - for (NSString *h in tmp) { - NSString *host = [h stringByTrimmingWhitespace]; - if ([host length] == 0) { - continue; - } - [hosts addObject:host]; - } - connected = mongoDB = [[MongoDB alloc] initWithConn:conn.repl_name hosts:hosts]; - [hosts release]; - }else{ - hostaddress = [NSString stringWithFormat:@"%@:%@", conn.host, conn.hostport]; - connected = mongoDB = [[MongoDB alloc] initWithConn:hostaddress]; - } - } - [loaderIndicator stop]; - if (connected) { - if ([conn.adminuser isPresent]) { - [mongoDB authUser:conn.adminuser pass:conn.adminpass database:conn.defaultdb]; - } - - if (![conn.defaultdb isPresent]) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addDB:) name:kNewDBWindowWillClose object:nil]; - } - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addCollection:) name:kNewCollectionWindowWillClose object:nil]; - [reconnectButton setEnabled:YES]; - [monitorButton setEnabled:YES]; - [self reloadSidebar]; - [self showServerStatus:nil]; - } - [pool release]; -} - -- (void)windowDidLoad { - [super windowDidLoad]; - exitThread = NO; - NSString *appVersion = [[NSString alloc] initWithFormat:@"version(%@[%@])", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey] ]; - [bundleVersion setStringValue: appVersion]; - [appVersion release]; - [self connect:NO]; - if ([conn.usessh intValue]==1) { - [NSThread detachNewThreadSelector: @selector(checkTunnel) toTarget:self withObject:nil ]; - } -} - -- (IBAction)reconnect:(id)sender -{ - [self connect:NO]; - if ([conn.usessh intValue]==1) { - [NSThread detachNewThreadSelector: @selector(checkTunnel) toTarget:self withObject:nil ]; - } -} - -- (void)checkTunnel { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - while(!exitThread){ - @synchronized(self){ - if ([sshTunnel running] == NO){ - [sshTunnel start]; - }else if( [sshTunnel running] == YES && [sshTunnel checkProcess] == NO ){ - [sshTunnel stop]; - [NSThread sleepForTimeInterval:2]; - [sshTunnel start]; - } - [sshTunnel readStatus]; - } - [NSThread sleepForTimeInterval:3]; - } - [NSThread exit]; - [pool release]; -} - -- (void)dealloc { - [managedObjectContext release]; - [databaseArrayController release]; - [resultsOutlineViewController release]; - [conn release]; - [mongoDB release]; - [sidebar release]; - [databases release]; - [collections release]; - [selectedDB release]; - [selectedCollection release]; - [sshTunnel release]; - [addDBController release]; - [addCollectionController release]; - [resultsTitle release]; - [loaderIndicator release]; - [reconnectButton release]; - [monitorButton release]; - [monitorSheetController release]; - [statMonitorTableController release]; - [bundleVersion release]; - [authWindowController release]; - [importWindowController release]; - [exportWindowController release]; - [super dealloc]; -} - -- (void)windowWillClose:(NSNotification *)notification { - if ([sshTunnel running]) { - [sshTunnel stop]; - } - //exitThread = YES; - resultsOutlineViewController = nil; - selectedDB = nil; - selectedCollection = nil; - [super release]; -} - -- (void)reloadSidebar { - [loaderIndicator start]; - [sidebar addSection:@"1" caption:@"DATABASES"]; - [self reloadDBList]; - [sidebar reloadData]; - [loaderIndicator stop]; -} - -- (void)reloadDBList { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [loaderIndicator start]; - //[selectedDB release]; - selectedDB = nil; - //[selectedCollection release]; - selectedCollection = nil; - [collections release]; - collections = [[NSMutableArray alloc] init]; - [databases release]; - if ([conn.defaultdb isPresent]) { - databases = [[NSMutableArray alloc] initWithObjects:conn.defaultdb, nil]; - }else { - databases = [[NSMutableArray alloc ] initWithArray:[mongoDB listDatabases]]; - } - - [databaseArrayController clean:conn databases:databases]; - [sidebar removeItem:@"2"]; - unsigned int i=1; - for (NSString *db in databases) { - [sidebar addChild:@"1" key:[NSString stringWithFormat:@"1.%d", i] caption:db icon:[NSImage imageNamed:@"dbicon.png"] action:@selector(useDB:) target:self]; - i ++ ; - } - [sidebar reloadData]; - [sidebar expandItem:@"1"]; - [loaderIndicator stop]; - [pool release]; -} - -- (void)useDB:(id)sender { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *dbname = [[NSString alloc] initWithFormat:@"%@", [sender caption]]; - if (![[selectedDB caption] isEqualToString:dbname]) { - //[selectedDB release]; - selectedDB = (SidebarNode *)sender; - } - //[selectedCollection release]; - selectedCollection = nil; - NSString *user=nil; - NSString *password=nil; - Database *db = [databaseArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - [collections release]; - [loaderIndicator start]; - collections = [[NSMutableArray alloc] initWithArray:[mongoDB listCollections:dbname user:user password:password]]; - if ([collections count] == 0) { - [collections addObject:@"test"]; - } - [loaderIndicator stop]; - [dbname release]; - - [sidebar removeItem:@"2"]; - [sidebar addSection:@"2" caption:[[selectedDB caption] uppercaseString]]; - unsigned int i = 1; - for (NSString *collection in collections) { - [sidebar addChild:@"2" key:[NSString stringWithFormat:@"2.%d", i] caption:collection icon:[NSImage imageNamed:@"collectionicon.png"] action:@selector(useCollection:) target:self]; - i ++ ; - } - [sidebar reloadData]; - [sidebar setBadge:[selectedDB nodeKey] count:[collections count]]; - [sidebar expandItem:@"2"]; - [self showDBStats:nil]; - [pool release]; -} - -- (void)useCollection:(id)sender -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *collectionname = [[NSString alloc] initWithFormat:@"%@", [sender caption] ]; - if ([collectionname isPresent]) { - //[selectedCollection release]; - selectedCollection = (SidebarNode *)sender; - [self showCollStats:nil]; - } - [collectionname release]; - [pool release]; -} - -- (IBAction)showServerStatus:(id)sender -{ - [loaderIndicator start]; - [resultsTitle setStringValue:[NSString stringWithFormat:@"Server %@:%@ stats", conn.host, conn.hostport]]; - NSArray *serverStats = [[NSArray alloc] initWithArray:[mongoDB serverStatus]]; - NSMutableArray *results = [[NSMutableArray alloc] initWithArray:serverStats]; - [serverStats release]; - resultsOutlineViewController.results = results; - [resultsOutlineViewController.myOutlineView reloadData]; - [results release]; - [loaderIndicator stop]; - -} - -- (IBAction)showDBStats:(id)sender -{ - if (selectedDB==nil) { - NSRunAlertPanel(@"Error", @"Please specify a database!", @"OK", nil, nil); - return; - } - [loaderIndicator start]; - [resultsTitle setStringValue:[NSString stringWithFormat:@"Database %@ stats", [selectedDB caption]]]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databaseArrayController dbInfo:conn name:[selectedDB caption]]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSMutableArray *results = [[NSMutableArray alloc] initWithArray:[mongoDB dbStats:[selectedDB caption] - user:user - password:password]]; - resultsOutlineViewController.results = results; - [resultsOutlineViewController.myOutlineView reloadData]; - [results release]; - [loaderIndicator stop]; - //NSLog(@"STATUS: %@", results); -} - -- (IBAction)showCollStats:(id)sender -{NSLog(@"showCollStats"); - if (selectedDB==nil || selectedCollection==nil) { - NSRunAlertPanel(@"Error", @"Please specify a collection!", @"OK", nil, nil); - return; - } - [loaderIndicator start]; - [resultsTitle setStringValue:[NSString stringWithFormat:@"Collection %@.%@ stats", [selectedDB caption], [selectedCollection caption]]]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databaseArrayController dbInfo:conn name:[selectedDB caption] ]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSMutableArray *results = [[NSMutableArray alloc] initWithArray:[mongoDB collStats:[selectedCollection caption] - forDB:[selectedDB caption] - user:user - password:password] ]; - //NSLog(@"STATUS: %@", results); - resultsOutlineViewController.results = results; - [resultsOutlineViewController.myOutlineView reloadData]; - [results release]; - [loaderIndicator stop]; -} - -- (IBAction)createDBorCollection:(id)sender -{ - if (selectedCollection) { - [self createCollectionForDB:[selectedDB caption]]; - }else { - [self createDB]; - } -} - -- (void)createCollectionForDB:(NSString *)dbname -{ - if (!addCollectionController) - { - addCollectionController = [[AddCollectionController alloc] init]; - } - addCollectionController.dbname = dbname; - [addCollectionController showWindow:self]; -} - -- (void)createDB -{ - if ([conn.defaultdb isPresent]) { - NSRunAlertPanel(@"Error", @"Could not create database!", @"OK", nil, nil); - return; - } - if (!addDBController) - { - addDBController = [[AddDBController alloc] init]; - } - addDBController.managedObjectContext = self.managedObjectContext; - addDBController.conn = self.conn; - [addDBController showWindow:self]; -} - -- (void)addDB:(id)sender -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (![sender object]) { - return; - } - NSString *dbname = [[NSString alloc] initWithString:[[sender object] objectForKey:@"dbname"]]; - NSString *user = [[NSString alloc] initWithString:[[sender object] objectForKey:@"user"]]; - NSString *password = [[NSString alloc] initWithString:[[sender object] objectForKey:@"password"]]; - [mongoDB dbStats:dbname - user:user - password:password]; - [dbname release]; - [user release]; - [password release]; - [self reloadSidebar]; - [pool release]; -} - -- (void)addCollection:(id)sender -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if (![sender object]) { - return; - } - NSString *dbname = [[NSString alloc] initWithString:[[sender object] objectForKey:@"dbname"]]; - NSString *collectionname = [[NSString alloc] initWithString:[[sender object] objectForKey:@"collectionname"]]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databaseArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - [mongoDB createCollection:collectionname - forDB:dbname - user:user - password:password]; - if ([[selectedDB caption] isEqualToString:dbname]) { - [sidebar selectItem:[selectedDB nodeKey]]; - } - [dbname release]; - [collectionname release]; - [pool release]; -} - -- (IBAction)dropDBorCollection:(id)sender -{ - if (selectedCollection) { - [self dropWarning:[NSString stringWithFormat:@"COLLECTION:%@", [selectedCollection caption]]]; - }else { - [self dropWarning:[NSString stringWithFormat:@"DB:%@", [selectedDB caption]]]; - } -} - -- (void)dropCollection:(NSString *)collectionname ForDB:(NSString *)dbname -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databaseArrayController dbInfo:conn name:[selectedDB caption]]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - [loaderIndicator start]; - [mongoDB dropCollection:collectionname - forDB:dbname - user:user - password:password]; - [loaderIndicator stop]; - if ([[selectedDB caption] isEqualToString:dbname]) { - [sidebar selectItem:[selectedDB nodeKey]]; - } - [pool release]; -} - -- (void)dropDB -{ - if ([conn.defaultdb isPresent]) { - NSRunAlertPanel(@"Error", @"Could not drop database!", @"OK", nil, nil); - return; - } - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databaseArrayController dbInfo:conn name:[selectedDB caption]]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - [loaderIndicator start]; - [mongoDB dropDB:[selectedDB caption] - user:user - password:password]; - [loaderIndicator stop]; - [self reloadSidebar]; - [pool release]; -} - -- (IBAction)query:(id)sender -{ - if (!selectedCollection) { - NSRunAlertPanel(@"Error", @"Please choose a collection!", @"OK", nil, nil); - return; - } - - QueryWindowController *queryWindowController = [[QueryWindowController alloc] init]; - queryWindowController.managedObjectContext = self.managedObjectContext; - queryWindowController.conn = conn; - queryWindowController.dbname = [selectedDB caption]; - queryWindowController.collectionname = [selectedCollection caption]; - queryWindowController.mongoDB = mongoDB; - [queryWindowController showWindow:sender]; -} - -- (IBAction)showAuth:(id)sender -{ - if ([conn.defaultdb isPresent]) { - NSRunAlertPanel(@"Error", @"Could not auth for database!", @"OK", nil, nil); - return; - } - - if (!selectedDB) - { - NSRunAlertPanel(@"Error", @"Please choose a database!", @"OK", nil, nil); - return; - } - if (!authWindowController) - { - authWindowController = [[AuthWindowController alloc] init]; - } - Database *db = [databaseArrayController dbInfo:conn name:[selectedDB caption]]; - if (db) { - [authWindowController.userTextField setStringValue:db.user]; - [authWindowController.passwordTextField setStringValue:db.password]; - }else { - [authWindowController.userTextField setStringValue:@""]; - [authWindowController.passwordTextField setStringValue:@""]; - } - authWindowController.managedObjectContext = self.managedObjectContext; - authWindowController.conn = self.conn; - authWindowController.dbname = [selectedDB caption]; - [authWindowController showWindow:self]; -} - -- (IBAction)importFromMySQL:(id)sender -{ - if (selectedDB==nil) { - NSRunAlertPanel(@"Error", @"Please specify a database!", @"OK", nil, nil); - return; - } - if (!importWindowController) - { - importWindowController = [[ImportWindowController alloc] init]; - } - importWindowController.managedObjectContext = self.managedObjectContext; - importWindowController.conn = self.conn; - importWindowController.mongoDB = mongoDB; - importWindowController.dbname = [selectedDB caption]; - [importWindowController showWindow:self]; -} - -- (IBAction)exportToMySQL:(id)sender -{ - if (selectedDB==nil) { - NSRunAlertPanel(@"Error", @"Please specify a database!", @"OK", nil, nil); - return; - } - if (!exportWindowController) - { - exportWindowController = [[ExportWindowController alloc] init]; - } - exportWindowController.managedObjectContext = self.managedObjectContext; - exportWindowController.conn = self.conn; - exportWindowController.mongoDB = mongoDB; - exportWindowController.dbname = [selectedDB caption]; - [exportWindowController showWindow:self]; -} - -- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo -{ - if (returnCode == NSAlertFirstButtonReturn) - { - if (selectedCollection) { - [self dropCollection:[selectedCollection caption] ForDB:[selectedDB caption]]; - }else { - [self dropDB]; - } - } -} - -- (void)dropWarning:(NSString *)msg -{ - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; - [alert addButtonWithTitle:@"OK"]; - [alert addButtonWithTitle:@"Cancel"]; - [alert setMessageText:[NSString stringWithFormat:@"Drop this %@?", msg]]; - [alert setInformativeText:[NSString stringWithFormat:@"Dropped %@ cannot be restored.", msg]]; - [alert setAlertStyle:NSWarningAlertStyle]; - [alert beginSheetModalForWindow:[self window] modalDelegate:self - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:nil]; -} - -- (IBAction)startMonitor:(id)sender { - monitorStopped = NO; - [NSThread detachNewThreadSelector: @selector(updateMonitor) toTarget:self withObject:nil ]; - [monitorSheetController openSheet:sender]; - NSLog(@"startMonitor"); -} - -- (IBAction)stopMonitor:(id)sender { - [monitorSheetController closeSheet:sender]; - monitorStopped = YES; - NSLog(@"stopMonitor"); -} - -- (void)updateMonitor { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSDate *prev = [NSDate date]; - mongo::BSONObj a = [mongoDB serverStat]; - while (!monitorStopped) { - [NSThread sleepForTimeInterval:1]; - NSDate *now = [NSDate date]; - mongo::BSONObj b = [mongoDB serverStat]; - NSDictionary *item = [mongoDB serverMonitor:a second:b currentDate:now previousDate:prev]; - a = b; - prev = now; - [statMonitorTableController addObject:item]; - - } - [NSThread exit]; - [pool release]; -} - -@end diff --git a/ConnectionWindowTitleTransformer.h b/ConnectionWindowTitleTransformer.h deleted file mode 100644 index 4275de07..00000000 --- a/ConnectionWindowTitleTransformer.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ConnectionWindowTitleTransformer.h -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import - - -@interface ConnectionWindowTitleTransformer : NSValueTransformer { - -} - -@end diff --git a/ConnectionWindowTitleTransformer.m b/ConnectionWindowTitleTransformer.m deleted file mode 100644 index 7333630b..00000000 --- a/ConnectionWindowTitleTransformer.m +++ /dev/null @@ -1,34 +0,0 @@ -// -// ConnectionWindowTitleTransformer.m -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "ConnectionWindowTitleTransformer.h" -#import "Connection.h" - -@implementation ConnectionWindowTitleTransformer - -+ (Class)transformedValueClass { - return [NSString class]; -} -+ (BOOL)allowsReverseTransformation { - return NO; -} -- (id)transformedValue:(id)value -{ - if (value) - { - if ([[value userepl] intValue] == 1) { - return [NSString stringWithFormat:@"%@ [%@]", [value alias], [value repl_name] ]; - }else { - return [NSString stringWithFormat:@"%@ [%@:%@]", [value alias], [value host], [value hostport] ]; - } - - } - return nil; -} - -@end diff --git a/ConnectionsCollectionView/ConnectionsCollectionView.h b/ConnectionsCollectionView/ConnectionsCollectionView.h deleted file mode 100644 index 3794f608..00000000 --- a/ConnectionsCollectionView/ConnectionsCollectionView.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ProjectsCollectionView.h -// SEOBox -// -// Created by Syd on 10-2-28. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import - - -@interface ConnectionsCollectionView : NSCollectionView { - -} --(void)setSubviewSize:(CGFloat)theSubviewSize; -@end diff --git a/ConnectionsCollectionView/ConnectionsCollectionView.m b/ConnectionsCollectionView/ConnectionsCollectionView.m deleted file mode 100644 index 15caf072..00000000 --- a/ConnectionsCollectionView/ConnectionsCollectionView.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// ProjectsCollectionView.m -// SEOBox -// -// Created by Syd on 10-2-28. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "ConnectionsCollectionView.h" - - -@implementation ConnectionsCollectionView - --(void)setSubviewSize:(CGFloat)theSubviewSize { - [self setMaxItemSize:NSMakeSize(theSubviewSize,theSubviewSize)]; - [self setMinItemSize:NSMakeSize(theSubviewSize,theSubviewSize)]; -} - --(void)drawRect:(NSRect)rect { - [[NSColor colorWithCalibratedHue: 0 saturation: 0 brightness: 0.13 alpha: 1.0] set]; - NSRectFill([self frame]); -} -@end diff --git a/ConnectionsCollectionView/IconCollectionItem.h b/ConnectionsCollectionView/IconCollectionItem.h deleted file mode 100644 index 56296e48..00000000 --- a/ConnectionsCollectionView/IconCollectionItem.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// IconCollectionItem.h -// SEOBox -// -// Created by Syd on 10-2-28. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import - - -@interface IconCollectionItem : NSCollectionViewItem { - -} - -- (void)doubleClick:(id)sender; - -@end diff --git a/ConnectionsCollectionView/IconCollectionItem.m b/ConnectionsCollectionView/IconCollectionItem.m deleted file mode 100644 index 88af045c..00000000 --- a/ConnectionsCollectionView/IconCollectionItem.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// IconCollectionItem.m -// SEOBox -// -// Created by Syd on 10-2-28. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "IconCollectionItem.h" -#import "IconViewBox.h" - -@implementation IconCollectionItem - --(void)setSelected:(BOOL)flag { - [super setSelected:flag]; - - // tell the view that it has been selected - IconViewBox* theView = (IconViewBox* )[self view]; - if([theView isKindOfClass:[IconViewBox class]]) { - [theView setSelected:flag]; - [theView setNeedsDisplay:YES]; - } -} - -- (void)doubleClick:(id)sender { - if([self collectionView] && [[self collectionView] delegate] && [[[self collectionView] delegate] respondsToSelector:@selector(doubleClick:)]) { - [[[self collectionView] delegate] performSelector:@selector(doubleClick:) withObject:self]; - } -} -@end diff --git a/ConnectionsCollectionView/IconViewBox.h b/ConnectionsCollectionView/IconViewBox.h deleted file mode 100644 index 5f215c60..00000000 --- a/ConnectionsCollectionView/IconViewBox.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// IconViewBox.h -// SEOBox -// -// Created by Syd on 10-2-28. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import - - -@interface IconViewBox : NSBox -{ - BOOL selectedFlag; - IBOutlet id delegate; -} - -@property (nonatomic, assign) id delegate; -@property (nonatomic, assign) BOOL selectedFlag; - --(void)setSelected:(BOOL)flag; --(BOOL)selected; -@end diff --git a/ConnectionsCollectionView/IconViewBox.m b/ConnectionsCollectionView/IconViewBox.m deleted file mode 100644 index 76df8035..00000000 --- a/ConnectionsCollectionView/IconViewBox.m +++ /dev/null @@ -1,92 +0,0 @@ -// -// IconViewBox.m -// SEOBox -// -// Created by Syd on 10-2-28. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "IconViewBox.h" - - -@implementation IconViewBox -@synthesize delegate; -@synthesize selectedFlag; - - --(void)setSelected:(BOOL)flag { - selectedFlag = flag; -} - --(BOOL)selected { - return selectedFlag; -} - --(void)drawRect:(NSRect)rect { - if([self selected]) { - NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.35]; - NSRect bgRect = rect; - int minX = NSMinX(bgRect); - int midX = NSMidX(bgRect); - int maxX = NSMaxX(bgRect); - int minY = NSMinY(bgRect); - int midY = NSMidY(bgRect); - int maxY = NSMaxY(bgRect); - float radius = 25.0; // correct value to duplicate Panther's App Switcher - NSBezierPath *bgPath = [NSBezierPath bezierPath]; - - // Bottom edge and bottom-right curve - [bgPath moveToPoint:NSMakePoint(midX, minY)]; - [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, minY) - toPoint:NSMakePoint(maxX, midY) - radius:radius]; - - // Right edge and top-right curve - [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(maxX, maxY) - toPoint:NSMakePoint(midX, maxY) - radius:radius]; - - // Top edge and top-left curve - [bgPath appendBezierPathWithArcFromPoint:NSMakePoint(minX, maxY) - toPoint:NSMakePoint(minX, midY) - radius:radius]; - - // Left edge and bottom-left curve - [bgPath appendBezierPathWithArcFromPoint:bgRect.origin - toPoint:NSMakePoint(midX, minY) - radius:radius]; - [bgPath closePath]; - - [bgColor set]; - [bgPath fill]; - }else { - [self setWantsLayer:NO]; - } - - [super drawRect:rect]; -} - -// ------------------------------------------------------------------------------- -// hitTest:aPoint -// ------------------------------------------------------------------------------- -- (NSView *)hitTest:(NSPoint)aPoint -{ - // don't allow any mouse clicks for subviews in this view - if(NSPointInRect(aPoint,[self convertRect:[self bounds] toView:[self superview]])) { - return self; - } else { - return nil; - } -} - --(void)mouseDown:(NSEvent *)theEvent { - [super mouseDown:theEvent]; - // check for click count above one, which we assume means it's a double click - if([theEvent clickCount] > 1) { - if(delegate && [delegate respondsToSelector:@selector(doubleClick:)]) { - [delegate performSelector:@selector(doubleClick:) withObject:self]; - } - } -} - -@end diff --git a/Database.h b/Database.h deleted file mode 100644 index 7040c300..00000000 --- a/Database.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Database.h -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -@class Connection; - -@interface Database : NSManagedObject { - NSString *name; - NSString *user; - NSString *password; - Connection *connection; -} -@property (nonatomic, retain) NSString *name; -@property (nonatomic, retain) NSString *user; -@property (nonatomic, retain) NSString *password; -@property (nonatomic, retain) Connection *connection; - -@end diff --git a/Database.m b/Database.m deleted file mode 100644 index 5e64f6be..00000000 --- a/Database.m +++ /dev/null @@ -1,19 +0,0 @@ -// -// Database.m -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "Database.h" - - -@implementation Database - -@dynamic name; -@dynamic user; -@dynamic password; -@dynamic connection; - -@end diff --git a/DatabasesArrayController.h b/DatabasesArrayController.h deleted file mode 100644 index a0fe412c..00000000 --- a/DatabasesArrayController.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// DatabasesArrayCollection.h -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import -@class Connection; -@class Database; - -@interface DatabasesArrayController : NSArrayController { - -} - -- (id)newObjectWithConn:(Connection *)conn name:(NSString *)name user:(NSString *)user password:(NSString *)password; -- (void)clean:(Connection *)conn databases:(NSArray *)databases; -- (BOOL)checkDuplicate:(Connection *) conn name:(NSString *)name; -- (NSArray *)itemsUsingFetchPredicate:(NSPredicate *)fetchPredicate; -- (Database *)dbInfo:(Connection *) conn name:(NSString *)name; -@end diff --git a/DatabasesArrayController.m b/DatabasesArrayController.m deleted file mode 100644 index 5f08292f..00000000 --- a/DatabasesArrayController.m +++ /dev/null @@ -1,85 +0,0 @@ -// -// DatabasesArrayCollection.m -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "DatabasesArrayController.h" -#import "Connection.h" -#import "Database.h" - -@implementation DatabasesArrayController - -- (void)awakeFromNib -{ - if ([NSArrayController instancesRespondToSelector:@selector(awakeFromNib)]) - { - [super awakeFromNib]; - } - [self setClearsFilterPredicateOnInsertion:NO]; -} - -- (id)newObjectWithConn:(Connection *) conn name:(NSString *)name user:(NSString *)user password:(NSString *)password -{ - id newObj = [super newObject]; - [newObj setValue:conn forKey:@"connection"]; - [newObj setValue:name forKey:@"name"]; - [newObj setValue:user forKey:@"user"]; - [newObj setValue:password forKey:@"password"]; - return newObj; -} - -- (void)clean:(Connection *)conn databases:(NSArray *)databases -{ - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"connection=%@", conn]; - NSArray *dblist = [self itemsUsingFetchPredicate:predicate]; - for (Database *db in dblist) { - bool exist = false; - for (NSString *d in databases) { - if (db.name == d) { - exist = true; - break; - } - } - if (!exist) { - [super remove:db]; - } - } -} - -- (Database *)dbInfo:(Connection *) conn name:(NSString *)name -{ - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"connection=%@ AND name=%@", conn, name]; - if ([[self itemsUsingFetchPredicate:predicate] count]>0) { - return [[self itemsUsingFetchPredicate:predicate] objectAtIndex:0]; - } - return nil; -} - -- (BOOL)checkDuplicate:(Connection *) conn name:(NSString *)name -{ - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"connection=%@ AND name=%@", conn, name]; - if ([[self itemsUsingFetchPredicate:predicate] count]>0) { - return YES; - }else { - return NO; - } -} - -- (NSArray *)itemsUsingFetchPredicate:(NSPredicate *)fetchPredicate -{ - NSError *error = nil; - NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; - [request setEntity:[NSEntityDescription entityForName:[self entityName] - inManagedObjectContext:[self managedObjectContext]]]; - NSArray *objects = [[self managedObjectContext] - executeFetchRequest:request error:&error]; - if (error) { - NSLog(@"Fetch error! In AWViewPositionArrayController:itemsUseingFetchPredicate"); - } - return [objects filteredArrayUsingPredicate:fetchPredicate]; -} - -@end diff --git a/EditConnection.xib b/EditConnection.xib deleted file mode 100644 index 5e0e8723..00000000 --- a/EditConnection.xib +++ /dev/null @@ -1,2733 +0,0 @@ - - - - 1060 - 10J869 - 823 - 1038.35 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 823 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - EditConnectionController - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{196, 123}, {353, 562}} - 544735232 - Edit Connection - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 268 - {{65, 481}, {166, 22}} - - YES - - -1804468671 - 272630784 - - - LucidaGrande - 13 - 1044 - - localhost - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - - - - 268 - {{22, 486}, {61, 17}} - - YES - - 68288064 - 272630784 - Host - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - - - - - - 268 - {{22, 525}, {38, 17}} - - YES - - 68288064 - 272630784 - Alias - - - - - - - - - 268 - {{267, 18}, {66, 25}} - - YES - - -2080244224 - 134217728 - Save - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{185, 18}, {67, 25}} - - YES - - -2080244224 - 134217728 - Cancel - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{65, 520}, {273, 22}} - - YES - - -1804468671 - 272630784 - - - localhost - - YES - - - - - - - 268 - {{236, 486}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{279, 481}, {59, 22}} - - YES - - -1804468671 - 272630784 - - - 27017 - - YES - - - - - - - 268 - {{18, 273}, {128, 18}} - - YES - - 67239424 - 0 - Use SSH Tunnel - - - -936623617 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 12 - {{20, 264}, {313, 5}} - - {0, 0} - - 67239424 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 268 - {{17, 241}, {92, 17}} - - YES - - 68288064 - 272630784 - Bind Address - - - - - - - - - 268 - {{114, 236}, {112, 22}} - - YES - - -1804468671 - 272630784 - - - 127.0.0.1 - - YES - - - - - - - 268 - {{231, 241}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{274, 236}, {59, 22}} - - YES - - -1804468671 - 272630784 - - - 27017 - - YES - - - - - - - 268 - {{17, 196}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH Host - - - - - - - - - 268 - {{114, 194}, {112, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 268 - {{17, 160}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH Username - - - - - - - - - 268 - {{114, 155}, {219, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 268 - {{17, 120}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH Password - - - - - - - - - 268 - {{114, 115}, {219, 22}} - - YES - - 343014976 - 272630848 - - - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{231, 196}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{274, 194}, {59, 22}} - - YES - - -1804468671 - 272630784 - - - 22 - - YES - - - - - - - 268 - {{65, 443}, {117, 22}} - - YES - - -1804468671 - 272630784 - - - Admin Username - - YES - - - - - - - 268 - {{22, 446}, {38, 17}} - - YES - - 68288064 - 272630784 - User - - - - - - - - - 268 - {{187, 445}, {50, 17}} - - YES - - 68288064 - 272630784 - Passwd - - - - - - - - - 268 - {{242, 443}, {96, 22}} - - YES - - 343014976 - 272630848 - - - Admin Password - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{22, 413}, {38, 17}} - - YES - - 68288064 - 272630784 - DB - - - - - - - - - 268 - {{65, 410}, {273, 22}} - - YES - - -1804468671 - 272630784 - - - Database - - YES - - - - - - - 268 - {{18, 379}, {128, 18}} - - YES - - 67239424 - 0 - Use Replica Set - - - 1210864127 - 2 - - - - - 200 - 25 - - - - - 12 - {{20, 370}, {313, 5}} - - {0, 0} - - 67239424 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 268 - {{17, 347}, {61, 17}} - - YES - - 68288064 - 272630784 - Servers - - - - - - - - - 268 - {{96, 344}, {237, 22}} - - YES - - -1267597759 - 272630784 - - - host1:port1,host2:port2,host3:port3 - - YES - - - - - - - 268 - {{17, 312}, {74, 17}} - - YES - - 68288064 - 272630784 - Set Name - - - - - - - - - 268 - {{96, 309}, {237, 22}} - - YES - - -1267597759 - 272630784 - - - demo_repl - - YES - - - - - - - 268 - {{17, 81}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH KEY FILE - - - - - - - - - 268 - {{114, 76}, {152, 22}} - - YES - - -1804468671 - 272630784 - - - ~/.ssh/id_rsa - - YES - - - - - - - 268 - {{274, 74}, {59, 25}} - - YES - - -2080244224 - 134217728 - Select - - - -2038152961 - 163 - - - 400 - 75 - - - - {353, 562} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - YES - YES - - Connection - - YES - YES - YES - YES - YES - YES - YES - - - - - YES - - - managedObjectContext: managedObjectContext - - - - - - managedObjectContext: managedObjectContext - managedObjectContext - managedObjectContext - 2 - - - 21 - - - - connectionsArrayController - - - - 22 - - - - window - - - - 23 - - - - delegate - - - - 24 - - - - aliasTextField - - - - 64 - - - - hostTextField - - - - 65 - - - - hostportTextField - - - - 66 - - - - usesshCheckBox - - - - 67 - - - - bindaddressTextField - - - - 68 - - - - bindportTextField - - - - 69 - - - - sshhostTextField - - - - 70 - - - - sshuserTextField - - - - 71 - - - - cancel: - - - - 73 - - - - save: - - - - 74 - - - - enableSSH: - - - - 75 - - - - sshpasswordTextField - - - - 78 - - - - sshportTextField - - - - 83 - - - - adminuserTextField - - - - 92 - - - - adminpassTextField - - - - 93 - - - - defaultdbTextField - - - - 98 - - - - usereplCheckBox - - - - 110 - - - - serversTextField - - - - 111 - - - - replnameTextField - - - - 112 - - - - enableRepl: - - - - 113 - - - - sshkeyfileTextField - - - - 120 - - - - chooseKeyPath: - - - - 121 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 20 - - - - - 25 - - - YES - - - - - - 26 - - - YES - - - - - - 27 - - - YES - - - - - - 28 - - - YES - - - - - - 29 - - - YES - - - - - - 30 - - - YES - - - - - - 31 - - - YES - - - - - - 32 - - - YES - - - - - - 33 - - - YES - - - - - - 34 - - - - - 35 - - - YES - - - - - - 36 - - - YES - - - - - - 37 - - - YES - - - - - - 38 - - - YES - - - - - - 39 - - - YES - - - - - - 40 - - - YES - - - - - - 41 - - - YES - - - - - - 42 - - - YES - - - - - - 43 - - - YES - - - - - - 46 - - - - - 47 - - - - - 48 - - - - - 49 - - - - - 50 - - - - - 51 - - - - - 52 - - - - - 53 - - - - - 54 - - - - - 55 - - - - - 56 - - - - - 57 - - - - - 58 - - - - - 59 - - - - - 60 - - - - - 61 - - - - - 62 - - - - - 63 - - - - - 76 - - - YES - - - - - - 77 - - - - - 79 - - - YES - - - - - - 80 - - - - - 81 - - - YES - - - - - - 82 - - - - - 84 - - - YES - - - - - - 85 - - - YES - - - - - - 86 - - - YES - - - - - - 87 - - - YES - - - - - - 88 - - - - - 89 - - - - - 90 - - - - - 91 - - - - - 94 - - - YES - - - - - - 95 - - - - - 96 - - - YES - - - - - - 97 - - - - - 99 - - - YES - - - - - - 100 - - - - - 101 - - - YES - - - - - - 102 - - - YES - - - - - - 103 - - - YES - - - - - - 104 - - - YES - - - - - - 105 - - - - - 106 - - - - - 107 - - - - - 108 - - - - - 109 - - - - - 114 - - - YES - - - - - - 115 - - - YES - - - - - - 116 - - - YES - - - - - - 117 - - - - - 118 - - - - - 119 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 100.IBPluginDependency - 100.IBViewBoundsToFrameTransform - 101.IBPluginDependency - 101.IBViewBoundsToFrameTransform - 102.IBPluginDependency - 102.IBViewBoundsToFrameTransform - 103.IBPluginDependency - 103.IBViewBoundsToFrameTransform - 104.IBPluginDependency - 104.IBViewBoundsToFrameTransform - 105.IBPluginDependency - 106.IBPluginDependency - 107.IBPluginDependency - 108.IBPluginDependency - 109.IBPluginDependency - 114.IBPluginDependency - 114.IBViewBoundsToFrameTransform - 115.IBPluginDependency - 115.IBViewBoundsToFrameTransform - 116.IBPluginDependency - 116.IBViewBoundsToFrameTransform - 117.IBPluginDependency - 118.IBPluginDependency - 119.IBPluginDependency - 2.IBPluginDependency - 20.CustomClassName - 20.IBPluginDependency - 25.IBPluginDependency - 25.IBViewBoundsToFrameTransform - 26.IBPluginDependency - 26.IBViewBoundsToFrameTransform - 27.IBPluginDependency - 27.IBViewBoundsToFrameTransform - 28.IBPluginDependency - 28.IBViewBoundsToFrameTransform - 29.IBPluginDependency - 29.IBViewBoundsToFrameTransform - 30.IBPluginDependency - 30.IBViewBoundsToFrameTransform - 31.IBPluginDependency - 31.IBViewBoundsToFrameTransform - 32.IBPluginDependency - 32.IBViewBoundsToFrameTransform - 33.IBPluginDependency - 33.IBViewBoundsToFrameTransform - 34.IBPluginDependency - 34.IBViewBoundsToFrameTransform - 35.IBPluginDependency - 35.IBViewBoundsToFrameTransform - 36.IBPluginDependency - 36.IBViewBoundsToFrameTransform - 37.IBPluginDependency - 37.IBViewBoundsToFrameTransform - 38.IBPluginDependency - 38.IBViewBoundsToFrameTransform - 39.IBPluginDependency - 39.IBViewBoundsToFrameTransform - 40.IBPluginDependency - 40.IBViewBoundsToFrameTransform - 41.IBPluginDependency - 41.IBViewBoundsToFrameTransform - 42.IBPluginDependency - 42.IBViewBoundsToFrameTransform - 43.IBPluginDependency - 43.IBViewBoundsToFrameTransform - 46.IBPluginDependency - 47.IBPluginDependency - 48.IBPluginDependency - 49.IBPluginDependency - 50.IBPluginDependency - 51.IBPluginDependency - 52.IBPluginDependency - 53.IBPluginDependency - 54.IBPluginDependency - 55.IBPluginDependency - 56.IBPluginDependency - 57.IBPluginDependency - 58.IBPluginDependency - 59.IBPluginDependency - 60.IBPluginDependency - 61.IBPluginDependency - 62.IBPluginDependency - 63.IBPluginDependency - 76.IBPluginDependency - 76.IBViewBoundsToFrameTransform - 77.IBPluginDependency - 79.IBPluginDependency - 79.IBViewBoundsToFrameTransform - 80.IBPluginDependency - 81.IBPluginDependency - 81.IBViewBoundsToFrameTransform - 82.IBPluginDependency - 84.IBPluginDependency - 84.IBViewBoundsToFrameTransform - 85.IBPluginDependency - 85.IBViewBoundsToFrameTransform - 86.IBPluginDependency - 86.IBViewBoundsToFrameTransform - 87.IBPluginDependency - 87.IBViewBoundsToFrameTransform - 88.IBPluginDependency - 89.IBPluginDependency - 90.IBPluginDependency - 91.IBPluginDependency - 94.IBPluginDependency - 94.IBViewBoundsToFrameTransform - 95.IBPluginDependency - 96.IBPluginDependency - 96.IBViewBoundsToFrameTransform - 97.IBPluginDependency - 99.IBPluginDependency - 99.IBViewBoundsToFrameTransform - - - YES - {{68, 185}, {353, 562}} - com.apple.InterfaceBuilder.CocoaPlugin - {{68, 185}, {353, 562}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - - AUGgAABDoYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw52AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCwAAAw56AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw4wAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCwAAAw40AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw4UAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAw4UAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiQAAw4WAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ConnectionsArrayController - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCggAAw+MAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBsAAAw+MAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBsAAAw/aAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDhYAAwrAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDOQAAwrAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCggAAw/aAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDbAAAw+MAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDi4AAw+MAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBkAAAw3IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - AUGgAABDWQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDZwAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiQAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwyQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAwycAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwwAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAwwAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwrAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAwrAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDZwAAwyQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiQAAwycAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCggAAw9AAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBsAAAw88AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDOwAAw86AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDcgAAw9AAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBsAAAw76AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCggAAw7+AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBkAAAw64AAA - - - - - YES - - - YES - - - - - YES - - - YES - - - - 121 - - - - YES - - ConnectionsArrayController - NSArrayController - - IBProjectSource - ConnectionsArrayController.h - - - - EditConnectionController - NSWindowController - - YES - - YES - cancel: - chooseKeyPath: - enableRepl: - enableSSH: - save: - - - YES - id - id - id - id - id - - - - YES - - YES - cancel: - chooseKeyPath: - enableRepl: - enableSSH: - save: - - - YES - - cancel: - id - - - chooseKeyPath: - id - - - enableRepl: - id - - - enableSSH: - id - - - save: - id - - - - - YES - - YES - adminpassTextField - adminuserTextField - aliasTextField - bindaddressTextField - bindportTextField - connectionsArrayController - defaultdbTextField - hostTextField - hostportTextField - replnameTextField - serversTextField - sshhostTextField - sshkeyfileTextField - sshpasswordTextField - sshportTextField - sshuserTextField - usereplCheckBox - usesshCheckBox - - - YES - NSSecureTextField - NSTextField - NSTextField - NSTextField - NSTextField - ConnectionsArrayController - NSTextField - NSTextField - NSTextField - NSTextField - NSTextField - NSTextField - NSTextField - NSSecureTextField - NSTextField - NSTextField - NSButton - NSButton - - - - YES - - YES - adminpassTextField - adminuserTextField - aliasTextField - bindaddressTextField - bindportTextField - connectionsArrayController - defaultdbTextField - hostTextField - hostportTextField - replnameTextField - serversTextField - sshhostTextField - sshkeyfileTextField - sshpasswordTextField - sshportTextField - sshuserTextField - usereplCheckBox - usesshCheckBox - - - YES - - adminpassTextField - NSSecureTextField - - - adminuserTextField - NSTextField - - - aliasTextField - NSTextField - - - bindaddressTextField - NSTextField - - - bindportTextField - NSTextField - - - connectionsArrayController - ConnectionsArrayController - - - defaultdbTextField - NSTextField - - - hostTextField - NSTextField - - - hostportTextField - NSTextField - - - replnameTextField - NSTextField - - - serversTextField - NSTextField - - - sshhostTextField - NSTextField - - - sshkeyfileTextField - NSTextField - - - sshpasswordTextField - NSSecureTextField - - - sshportTextField - NSTextField - - - sshuserTextField - NSTextField - - - usereplCheckBox - NSButton - - - usesshCheckBox - NSButton - - - - - IBProjectSource - EditConnectionController.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - RegexKit.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSSecureTextFieldCell - NSTextFieldCell - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - NSSwitch - {15, 15} - - - diff --git a/EditConnectionController.h b/EditConnectionController.h deleted file mode 100644 index e6b42545..00000000 --- a/EditConnectionController.h +++ /dev/null @@ -1,65 +0,0 @@ -// -// EditConnectionController.h -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import -@class ConnectionsArrayController; -@class Connection; - -@interface EditConnectionController : NSWindowController { - IBOutlet NSTextField *hostTextField; - IBOutlet NSTextField *hostportTextField; - IBOutlet NSButton *usereplCheckBox; - IBOutlet NSTextField *serversTextField; - IBOutlet NSTextField *replnameTextField; - IBOutlet NSTextField *aliasTextField; - IBOutlet NSTextField *adminuserTextField; - IBOutlet NSSecureTextField *adminpassTextField; - IBOutlet NSTextField *defaultdbTextField; - IBOutlet NSButton *usesshCheckBox; - IBOutlet NSTextField *bindaddressTextField; - IBOutlet NSTextField *bindportTextField; - IBOutlet NSTextField *sshhostTextField; - IBOutlet NSTextField *sshportTextField; - IBOutlet NSTextField *sshuserTextField; - IBOutlet NSSecureTextField *sshpasswordTextField; - IBOutlet NSTextField *sshkeyfileTextField; - IBOutlet ConnectionsArrayController *connectionsArrayController; - Connection *connection; - NSManagedObjectContext *managedObjectContext; -} - -@property (nonatomic, retain) NSTextField *hostTextField; -@property (nonatomic, retain) NSTextField *hostportTextField; -@property (nonatomic, retain) NSButton *usereplCheckBox; -@property (nonatomic, retain) NSTextField *serversTextField; -@property (nonatomic, retain) NSTextField *replnameTextField; -@property (nonatomic, retain) NSTextField *aliasTextField; -@property (nonatomic, retain) NSTextField *adminuserTextField; -@property (nonatomic, retain) NSSecureTextField *adminpassTextField; -@property (nonatomic, retain) NSTextField *defaultdbTextField; -@property (nonatomic, retain) NSButton *usesshCheckBox; -@property (nonatomic, retain) NSTextField *bindaddressTextField; -@property (nonatomic, retain) NSTextField *bindportTextField; -@property (nonatomic, retain) NSTextField *sshhostTextField; -@property (nonatomic, retain) NSTextField *sshportTextField; -@property (nonatomic, retain) NSTextField *sshuserTextField; -@property (nonatomic, retain) NSSecureTextField *sshpasswordTextField; -@property (nonatomic, retain) NSTextField *sshkeyfileTextField; -@property (nonatomic, retain) Connection *connection; -@property (nonatomic, retain) ConnectionsArrayController *connectionsArrayController; -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; - -- (IBAction)cancel:(id)sender; -- (IBAction)save:(id)sender; -- (IBAction)enableSSH:(id)sender; -- (IBAction)enableRepl:(id)sender; -- (BOOL)validateConnection:(NSDictionary *)connectionInfo; - -- (IBAction)chooseKeyPath:(id)sender; - -@end diff --git a/EditConnectionController.m b/EditConnectionController.m deleted file mode 100644 index 9bb7188d..00000000 --- a/EditConnectionController.m +++ /dev/null @@ -1,290 +0,0 @@ -// -// EditConnectionController.m -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "Configure.h" -#import "EditConnectionController.h" -#import "ConnectionsArrayController.h" -#import "Connection.h" - - -@implementation EditConnectionController - -@synthesize hostTextField; -@synthesize hostportTextField; -@synthesize usereplCheckBox; -@synthesize serversTextField; -@synthesize replnameTextField; -@synthesize aliasTextField; -@synthesize adminuserTextField; -@synthesize adminpassTextField; -@synthesize defaultdbTextField; -@synthesize usesshCheckBox; -@synthesize bindaddressTextField; -@synthesize bindportTextField; -@synthesize sshhostTextField; -@synthesize sshportTextField; -@synthesize sshuserTextField; -@synthesize sshpasswordTextField; -@synthesize sshkeyfileTextField; -@synthesize connection; -@synthesize connectionsArrayController; -@synthesize managedObjectContext; - -- (id)init { - if (![super initWithWindowNibName:@"EditConnection"]) return nil; - return self; -} - -- (void)dealloc { - [hostTextField release]; - [hostportTextField release]; - [usereplCheckBox release]; - [serversTextField release]; - [replnameTextField release]; - [aliasTextField release]; - [adminuserTextField release]; - [adminpassTextField release]; - [defaultdbTextField release]; - [usesshCheckBox release]; - [bindaddressTextField release]; - [bindportTextField release]; - [sshhostTextField release]; - [sshportTextField release]; - [sshuserTextField release]; - [sshpasswordTextField release]; - [sshkeyfileTextField release]; - [connection release]; - [connectionsArrayController release]; - [managedObjectContext release]; - [super dealloc]; -} - -- (void)windowDidLoad { - [super windowDidLoad]; -} - -- (IBAction)showWindow:(id)sender { - [super showWindow:sender]; - [hostTextField bind:@"value" toObject:connection withKeyPath:@"host" options:nil]; - [hostportTextField bind:@"value" toObject:connection withKeyPath:@"hostport" options:nil]; - [serversTextField bind:@"value" toObject:connection withKeyPath:@"servers" options:nil]; - [replnameTextField bind:@"value" toObject:connection withKeyPath:@"repl_name" options:nil]; - [usereplCheckBox bind:@"value" toObject:connection withKeyPath:@"userepl" options:nil]; - [aliasTextField bind:@"value" toObject:connection withKeyPath:@"alias" options:nil]; - [adminuserTextField bind:@"value" toObject:connection withKeyPath:@"adminuser" options:nil]; - [adminpassTextField bind:@"value" toObject:connection withKeyPath:@"adminpass" options:nil]; - [defaultdbTextField bind:@"value" toObject:connection withKeyPath:@"defaultdb" options:nil]; - [bindaddressTextField bind:@"value" toObject:connection withKeyPath:@"bindaddress" options:nil]; - [bindportTextField bind:@"value" toObject:connection withKeyPath:@"bindport" options:nil]; - [sshhostTextField bind:@"value" toObject:connection withKeyPath:@"sshhost" options:nil]; - [sshportTextField bind:@"value" toObject:connection withKeyPath:@"sshport" options:nil]; - [sshuserTextField bind:@"value" toObject:connection withKeyPath:@"sshuser" options:nil]; - [sshpasswordTextField bind:@"value" toObject:connection withKeyPath:@"sshpassword" options:nil]; - [sshkeyfileTextField bind:@"value" toObject:connection withKeyPath:@"sshkeyfile" options:nil]; - [usesshCheckBox bind:@"value" toObject:connection withKeyPath:@"usessh" options:nil]; - [self enableSSH:nil]; - [self enableRepl:nil]; -} - -- (IBAction)cancel:(id)sender { - [self close]; -} - -- (IBAction)save:(id)sender { - NSString *host; - NSUInteger hostport; - NSString *servers; - NSString *repl_name; - NSUInteger userepl = 0; - NSString *alias; - NSString *adminuser = [[NSString alloc] initWithString:[adminuserTextField stringValue]]; - NSString *adminpass = [[NSString alloc] initWithString:[adminpassTextField stringValue]]; - NSString *defaultdb = [[NSString alloc] initWithString:[defaultdbTextField stringValue]]; - NSUInteger usessh = 0; - NSString *bindaddress; - NSUInteger bindport; - NSString *sshhost; - NSUInteger sshport; - NSString *sshuser; - NSString *sshpassword; - NSString *sshkeyfile; - if ([ [hostTextField stringValue] length] == 0) { - host = [[NSString alloc] initWithString:@"localhost"]; - }else{ - host = [[NSString alloc] initWithString:[hostTextField stringValue]]; - } - if ([hostportTextField intValue] == 0) { - hostport = 27017; - }else{ - hostport = [hostportTextField intValue]; - } - - servers = [[NSString alloc] initWithString:[serversTextField stringValue]]; - repl_name = [[NSString alloc] initWithString:[replnameTextField stringValue]]; - if ([usereplCheckBox state]) - { - userepl = 1; - } - - if ([ [aliasTextField stringValue] length] == 0) { - alias = [[NSString alloc] initWithString:@"localhost"]; - }else{ - alias = [[NSString alloc] initWithString:[aliasTextField stringValue]]; - } - if ([ [bindaddressTextField stringValue] length] == 0) { - bindaddress = [[NSString alloc] initWithString:@"127.0.0.1"]; - }else{ - bindaddress = [[NSString alloc] initWithString:[bindaddressTextField stringValue]]; - } - if ([ [bindportTextField stringValue] length] == 0) { - bindport = 8888; - }else{ - bindport = [bindportTextField intValue]; - } - sshhost = [[NSString alloc] initWithString:[sshhostTextField stringValue]]; - if ([ [sshportTextField stringValue] length] == 0) { - sshport = 22; - }else{ - sshport = [sshportTextField intValue]; - } - sshuser = [[NSString alloc] initWithString:[sshuserTextField stringValue]]; - sshpassword = [[NSString alloc] initWithString:[sshpasswordTextField stringValue]]; - sshkeyfile = [[NSString alloc] initWithString:[sshkeyfileTextField stringValue]]; - if ([usesshCheckBox state]) - { - usessh = 1; - - } - NSArray *keys = [[NSArray alloc] initWithObjects:@"host", @"hostport", @"userepl", @"servers", @"repl_name", @"alias", @"adminuser", @"adminpass", @"defaultdb", @"usessh", @"bindaddress", @"bindport", @"sshhost", @"sshport", @"sshuser", @"sshpassword", @"sshkeyfile", nil]; - NSArray *objs = [[NSArray alloc] initWithObjects:host, [NSNumber numberWithInt:hostport], [NSNumber numberWithInt:userepl], servers, repl_name, alias, adminuser, adminpass, defaultdb, [NSNumber numberWithInt:usessh], bindaddress, [NSNumber numberWithInt:bindport], sshhost, [NSNumber numberWithInt:sshport], sshuser, sshpassword, sshkeyfile, nil]; - NSDictionary *connectionInfo = [[NSDictionary alloc] initWithObjects:objs forKeys:keys]; - [keys release]; - [objs release]; - [host release]; - [servers release]; - [repl_name release]; - [alias release]; - [adminuser release]; - [adminpass release]; - [defaultdb release]; - [sshhost release]; - [sshuser release]; - [sshpassword release]; - [sshkeyfile release]; - [bindaddress release]; - - if ([self validateConnection:connectionInfo]) { - connection.host = [connectionInfo objectForKey:@"host"]; - connection.hostport = [connectionInfo objectForKey:@"hostport"]; - connection.servers = [connectionInfo objectForKey:@"servers"]; - connection.repl_name = [connectionInfo objectForKey:@"repl_name"]; - connection.userepl = [connectionInfo objectForKey:@"userepl"]; - connection.alias = [connectionInfo objectForKey:@"alias"]; - connection.adminuser = [connectionInfo objectForKey:@"adminuser"]; - connection.adminpass = [connectionInfo objectForKey:@"adminpass"]; - connection.defaultdb = [connectionInfo objectForKey:@"defaultdb"]; - connection.usessh = [connectionInfo objectForKey:@"usessh"]; - connection.bindaddress = [connectionInfo objectForKey:@"bindaddress"]; - connection.bindport = [connectionInfo objectForKey:@"bindport"]; - connection.sshhost = [connectionInfo objectForKey:@"sshhost"]; - connection.sshport = [connectionInfo objectForKey:@"sshport"]; - connection.sshuser = [connectionInfo objectForKey:@"sshuser"]; - connection.sshpassword = [connectionInfo objectForKey:@"sshpassword"]; - connection.sshkeyfile = [connectionInfo objectForKey:@"sshkeyfile"]; - [self close]; - } - [connectionInfo release]; -} - -- (BOOL)validateConnection:(NSDictionary *)connectionInfo -{ - if ([[connectionInfo objectForKey:@"host"] length] == 0) { - NSRunAlertPanel(@"Error", @"Connection host should not be empty", @"OK", nil, nil); - return NO; - } - if ([[connectionInfo objectForKey:@"host"] isEqualToString:@"flame.mongohq.com"] && [[connectionInfo objectForKey:@"defaultdb"] length] == 0) { - NSRunAlertPanel(@"Error", @"DB should not be empty if you are using mongohq", @"OK", nil, nil); - return NO; - } - if ([[connectionInfo objectForKey:@"alias"] length]<3) { - NSRunAlertPanel(@"Error", @"Connection name should not be less than 3 charaters", @"OK", nil, nil); - return NO; - } - if (![[connectionInfo objectForKey:@"alias"] isEqualToString:connection.alias] && [connectionsArrayController checkDuplicate:[connectionInfo objectForKey:@"alias"]]) { - NSRunAlertPanel(@"Error", @"Connection alias name has been existed!", @"OK", nil, nil); - return NO; - } - if ([usesshCheckBox state] == 1 && ([[connectionInfo objectForKey:@"bindaddress"] length] == 0 || [[connectionInfo objectForKey:@"sshhost"] length] == 0)) { - NSRunAlertPanel(@"Error", @"Please full fill ssh information!", @"OK", nil, nil); - return NO; - } - if ([usereplCheckBox state] == 1 && ([[connectionInfo objectForKey:@"servers"] length] == 0 || [[connectionInfo objectForKey:@"repl_name"] length] == 0)) { - NSRunAlertPanel(@"Error", @"Please full fill replica-set information!", @"OK", nil, nil); - return NO; - } - return YES; -} - -- (IBAction)enableSSH:(id)sender -{ - - if ([usesshCheckBox state] == 1) - { - [bindaddressTextField setEnabled:YES]; - [bindportTextField setEnabled:YES]; - [sshhostTextField setEnabled:YES]; - [sshuserTextField setEnabled:YES]; - [sshportTextField setEnabled:YES]; - [sshpasswordTextField setEnabled:YES]; - [sshkeyfileTextField setEnabled:YES]; - }else { - [bindaddressTextField setEnabled:NO]; - [bindportTextField setEnabled:NO]; - [sshhostTextField setEnabled:NO]; - [sshportTextField setEnabled:NO]; - [sshuserTextField setEnabled:NO]; - [sshpasswordTextField setEnabled:NO]; - [sshkeyfileTextField setEnabled:NO]; - } - -} - -- (IBAction)enableRepl:(id)sender -{ - if ([usereplCheckBox state] == 1) - { - [serversTextField setEnabled:YES]; - [replnameTextField setEnabled:YES]; - }else { - [serversTextField setEnabled:NO]; - [replnameTextField setEnabled:NO]; - } - -} - -- (IBAction)chooseKeyPath:(id)sender -{ - NSOpenPanel *tvarNSOpenPanelObj = [NSOpenPanel openPanel]; - NSInteger tvarNSInteger = [tvarNSOpenPanelObj runModalForTypes:nil]; - if(tvarNSInteger == NSOKButton){ - NSLog(@"doOpen we have an OK button"); - //NSString * tvarDirectory = [tvarNSOpenPanelObj directory]; - //NSLog(@"doOpen directory = %@",tvarDirectory); - NSString * tvarFilename = [tvarNSOpenPanelObj filename]; - NSLog(@"doOpen filename = %@",tvarFilename); - [sshkeyfileTextField setStringValue:tvarFilename]; - } else if(tvarNSInteger == NSCancelButton) { - NSLog(@"doOpen we have a Cancel button"); - return; - } else { - NSLog(@"doOpen tvarInt not equal 1 or zero = %3d",tvarNSInteger); - return; - } // end if -} - -@end diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib deleted file mode 100644 index e1da2d26..00000000 --- a/English.lproj/MainMenu.xib +++ /dev/null @@ -1,4203 +0,0 @@ - - - - 1060 - 10H574 - 804 - 1038.35 - 461.00 - - YES - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - - YES - 804 - 1.2.5 - - - - YES - - - - - - YES - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - YES - - - NSApplication - - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{6, 671}, {600, 282}} - 1886912512 - MongoHub - NSWindow - - View - - {3.40282e+38, 3.40282e+38} - {213, 107} - - - 256 - - YES - - - 268 - {{419, 4}, {46, 46}} - - - - - 274 - - YES - - - 2304 - - YES - - - 274 - {600, 250} - - {0, 0} - {0, 0} - 0 - 0 - - YES - - 6 - System - controlBackgroundColor - - 3 - MC42NjY2NjY2ODY1AA - - - - YES - -1 - 0 - - - {600, 250} - - - - - 6 - System - controlColor - - - 4 - - - - -2147483392 - {{234, 1}, {15, 143}} - - - _doScroller: - 1 - 0.89655172824859619 - - - - -2147483392 - {{1, 144}, {233, 15}} - - 1 - - _doScroller: - 0.63157892227172852 - - - {{0, 32}, {600, 250}} - - - 560 - - - - - - - 292 - {{20, 3}, {29, 25}} - - YES - - -2080244224 - 134217728 - - - LucidaGrande - 13 - 1044 - - - -2033434369 - 163 - - NSImage - NSAddOnTexture - - - - 400 - 75 - - - - - 292 - {{57, 3}, {29, 25}} - - YES - - -2080244224 - 134217728 - - - - -2033434369 - 163 - - NSImage - NSRemoveOnTexture - - - - 400 - 75 - - - - - 292 - {{94, 3}, {29, 25}} - - YES - - -2080244224 - 134217728 - - - - -2033958657 - 163 - - NSImage - editicon - - - - 400 - 75 - - - - - 292 - {{131, 3}, {29, 25}} - - YES - - -2080244224 - 134217728 - - - - -2034482945 - 163 - - NSImage - connecticon - - - - 400 - 75 - - - - - 289 - - YES - - - 256 - {{6, 3}, {16, 13}} - - -1 - YES - - 67239424 - 134217728 - Button - - LucidaGrande - 12 - 16 - - - setSliderToMinimum - - -2143010561 - 0 - - 12582912 - - YES - - YES - - - - TU0AKgAAALiAACBQOCQWDQeEQmFQuGQ2HQ+IRGJROKQobxd/xWDv+ORqDjWQP8lyNAx4ALaUH+TQQbS1 -/sqYAGCGyaP9XzcAFudABFT2ZQOWjaMyuBRcbv9k0mfwKRkt/ryoAAh1OTyilgCg0OiDmuP9j1+rnSxP -9OWUAG20ABB2urji3VqV0akUpD3V/o28AB9XsAAa/ABA4EAGvCAGs0SBDrFXCOXCI43EQJAZNAZHLZfM -ZmFQEAAOAQAAAwAAAAEAEAAAAQEAAwAAAAEADQAAAQIAAwAAAAQAAAFmAQMAAwAAAAEABQAAAQYAAwAA -AAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAAAAEADQAAARcABAAA -AAEAAACwARwAAwAAAAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAFuAAAAAAAI -AAgACAAIAAEAAQABAAE - - - - - - 3 - MCAwAA - - - - 400 - 75 - - - - - 256 - {{125, 3}, {16, 13}} - - -1 - YES - - 67239424 - 134217728 - Button - - - setSliderToMaximum - - -2143010561 - 0 - - 12582912 - - YES - - YES - - - - TU0AKgAAAV6AC+BP8AQUAAGEAB/wuFQyDQ+IRGIwgAw2CRSLRAYRt/lCPIGJSGRSOSRJXyc/xsYP9oS2 -KyWDG+ZP9WzWIFOcABIzuXzAASp/jKhP9nUWeyI+Ul/ztIgB+U+IAOpACZG8AIWsUeQjGuP+BC9/tGxV -qJGKzTSbA21RB520ATgpgBPXOyREW3evQOxNG6xAz39/ydXgAF4WIPXEW+cpfGX2Hi7IP+gS1oY6DJPM -P9QZsAO3PRAJ6EAGDSAA26fLQXIC682C96kAIDZIBqbU/sncRAbbsAXcWoHZoCS75/6t/tLkX2qv9u80 -AOLoAB99OIATrAAP9kACPuTqeSHiZOXQ86+V/qz0AABesAAr3er2Q9/fMAPb7AD5v4AFL+ABGv+o6vsk -jjKQCgYDQQAACwWg6EoWgiSn1CQAQkfQAOQaUDLAoCQoxB6fIND6MRAjLgxJE8UJEgIADgEAAAMAAAAB -ABAAAAEBAAMAAAABAA0AAAECAAMAAAAEAAACDAEDAAMAAAABAAUAAAEGAAMAAAABAAIAAAERAAQAAAAB -AAAACAESAAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAA0AAAEXAAQAAAABAAABVgEcAAMAAAAB -AAEAAAE9AAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAAEAAACFAAAAAAACAAIAAgACAABAAEAAQAB -A - - - - - - - - 400 - 75 - - - - {{439, 5}, {146, 21}} - - YES - - -2080244224 - 0 - - - - 100 - 0.0 - 50 - 0.0 - 0 - 1 - NO - NO - NO - - 2 - - - - - {600, 282} - - - {{0, 0}, {1680, 1028}} - {213, 129} - {3.40282e+38, 3.40282e+38} - - - MainMenu - - YES - - - MongoHub - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - MongoHub - - YES - - - About MongoHub - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Check for updates - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - - Services - - - YES - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide MongoHub - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit MongoHub - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - Connection - - 1048576 - 2147483647 - - - submenuAction: - - Connection - - YES - - - Add Connection - s - 1048576 - 2147483647 - - - - - - Delete Connection - - 2147483647 - - - - - - Edit Connection - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Connect - - 2147483647 - - - - - - - - - Edit - - 2147483647 - - - submenuAction: - - Edit - - YES - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Find - - 2147483647 - - - submenuAction: - - Find - - YES - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1048576 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 2147483647 - - - submenuAction: - - Spelling - - YES - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 2147483647 - - - - - - Check Grammar With Spelling - - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 2147483647 - - - submenuAction: - - Substitutions - - YES - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - - 2147483647 - - - - - - Smart Quotes - - 2147483647 - - - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - - 2147483647 - - - - - - Data Detectors - - 2147483647 - - - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - YES - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 2147483647 - - - submenuAction: - - Speech - - YES - - - Start Speaking - - 2147483647 - - - - - - Stop Speaking - - 2147483647 - - - - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - - Window - - - YES - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - YES - - - MongoHub Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - SUUpdater - - - MongoHub_AppDelegate - - - NSFontManager - - - - - 256 - - YES - - - 274 - - YES - - YES - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - NSFilenamesPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT TIFF v4.0 pasteboard type - - - {{17, 35}, {142, 105}} - - - YES - - - 3 - {{400, 600}, {150, 0}} - - - 3 - {{200, 200}, {0, 0}} - - - - - 1 - 1 - 1 - 1 - - YES - - - YES - - 130560 - 33554432 - - NSImage - database - - 0 - 0 - 0 - NO - - YES - - - - 258 - {{14, 17}, {145, 17}} - - YES - - 68288064 - 138413056 - Label - - - - - 1 - MSAxIDEAA - - - - - {179, 157} - - - - YES - @count - - YES - YES - - Connection - - YES - YES - YES - YES - YES - YES - YES - - - - - YES - - - - YES - - - - 17 - 2 - {{140, 273}, {331, 175}} - -1535639552 - Support Panel - NSPanel - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 266 - {{17, 133}, {297, 22}} - - YES - - 68288064 - 138413056 - MongoHub - - LucidaGrande-Bold - 18 - 16 - - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 266 - {{17, 111}, {297, 14}} - - YES - - 68288064 - 138413056 - version 2.0 beta - - LucidaGrande - 11 - 16 - - - - - 1 - MC4yOTgwMzkyMjc3IDAuMjk4MDM5MjI3NyAwLjI5ODAzOTIyNzcAA - - - - - - 268 - {{17, 42}, {297, 61}} - - YES - - 67239424 - 138412032 - QXV0aG9yOiBwcm9mLnN5ZC54dUBnbWFpbC5jb20KV2Vic2l0ZTogaHR0cDovL21vbmdvaHViLnRvZGF5 -Y2xvc2UuY29tLwpUd2l0dGVyOiBodHRwOi8vdHdpdHRlci5jb20vYnVidWJhLw - - - - - 1 - MC4wOTgwMzkyMTcyOSAwLjA5ODAzOTIxNzI5IDAuMDk4MDM5MjE3MjkAA - - - - - - 288 - {{128, 18}, {75, 25}} - - YES - - -2080244224 - 134217728 - Close - - - -2038152961 - 163 - - - 400 - 75 - - - - {331, 175} - - - {{0, 0}, {1280, 778}} - {3.40282e+38, 3.40282e+38} - - - - - YES - - - terminate: - - - - 139 - - - - hideOtherApplications: - - - - 146 - - - - hide: - - - - 152 - - - - unhideAllApplications: - - - - 153 - - - - delegate - - - - 206 - - - - delegate - - - - 207 - - - - window - - - - 208 - - - - performMiniaturize: - - - - 247 - - - - performZoom: - - - - 248 - - - - arrangeInFront: - - - - 249 - - - - itemPrototype - - - - 533 - - - - view - - - - 534 - - - - delegate - - - - 537 - - - - managedObjectContext: managedObjectContext - - - - - - managedObjectContext: managedObjectContext - managedObjectContext - managedObjectContext - 2 - - - 543 - - - - value: representedObject.alias - - - - - - value: representedObject.alias - value - representedObject.alias - 2 - - - 549 - - - - content: arrangedObjects - - - - - - content: arrangedObjects - content - arrangedObjects - 2 - - - 551 - - - - connectionsArrayController - - - - 565 - - - - connectionsCollectionView - - - - 566 - - - - delegate - - - - 567 - - - - showAddConnectionPanel: - - - - 568 - - - - resizeConnectionItemView: - - - - 569 - - - - deleteConnection: - - - - 570 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 574 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 577 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 580 - - - - enabled: arrangedObjects.@count - - - - - - enabled: arrangedObjects.@count - enabled - arrangedObjects.@count - 2 - - - 583 - - - - selectionIndexes: selectionIndexes - - - - - - selectionIndexes: selectionIndexes - selectionIndexes - selectionIndexes - - 2 - - - 584 - - - - showEditConnectionPanel: - - - - 585 - - - - showConnectionWindow: - - - - 586 - - - - performClick: - - - - 590 - - - - performClick: - - - - 591 - - - - performClick: - - - - 592 - - - - performClick: - - - - 593 - - - - parentWindow - - - - 596 - - - - openSheet: - - - - 597 - - - - openSheet: - - - - 598 - - - - sheet - - - - 601 - - - - closeSheet: - - - - 610 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 613 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 616 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 619 - - - - bundleVersion - - - - 620 - - - - checkForUpdates: - - - - 624 - - - - cut: - - - - 678 - - - - paste: - - - - 679 - - - - toggleAutomaticSpellingCorrection: - - - - 680 - - - - toggleSmartInsertDelete: - - - - 681 - - - - toggleAutomaticQuoteSubstitution: - - - - 682 - - - - redo: - - - - 683 - - - - toggleAutomaticDashSubstitution: - - - - 684 - - - - toggleContinuousSpellChecking: - - - - 685 - - - - toggleAutomaticDataDetection: - - - - 686 - - - - capitalizeWord: - - - - 687 - - - - undo: - - - - 688 - - - - toggleGrammarChecking: - - - - 689 - - - - startSpeaking: - - - - 690 - - - - showGuessPanel: - - - - 691 - - - - checkSpelling: - - - - 692 - - - - pasteAsPlainText: - - - - 693 - - - - copy: - - - - 694 - - - - uppercaseWord: - - - - 695 - - - - delete: - - - - 696 - - - - lowercaseWord: - - - - 697 - - - - selectAll: - - - - 698 - - - - stopSpeaking: - - - - 699 - - - - orderFrontSubstitutionsPanel: - - - - 700 - - - - toggleAutomaticTextReplacement: - - - - 701 - - - - toggleAutomaticLinkDetection: - - - - 702 - - - - performFindPanelAction: - - - - 703 - - - - performFindPanelAction: - - - - 704 - - - - performFindPanelAction: - - - - 705 - - - - centerSelectionInVisibleArea: - - - - 706 - - - - performFindPanelAction: - - - - 707 - - - - - YES - - 0 - - YES - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 21 - - - YES - - - - Window - - - 2 - - - YES - - - - - - - - - - - - 29 - - - YES - - - - - - - - MainMenu - - - 56 - - - YES - - - - - - 57 - - - YES - - - - - - - - - - - - - - - - 58 - - - - - 131 - - - YES - - - - - - 130 - - - - - 134 - - - - - 136 - - - - - 144 - - - - - 145 - - - - - 149 - - - - - 150 - - - - - 196 - - - - - 83 - - - YES - - - - - - 81 - - - YES - - - - - - - - - - 75 - - - - - 241 - - - YES - - - - - - 205 - - - MongoHub_AppDelegate - - - 392 - - - - - 518 - - - YES - - - - - - 519 - - - YES - - - - - - 520 - - - - - 526 - - - - - 527 - - - YES - - - - - - - - 528 - - - - - 529 - - - - - 530 - - - - - 531 - - - - - 532 - - - YES - - - - - - - 538 - - - YES - - - - - - 539 - - - - - 540 - - - YES - - - - - - 541 - - - - - 542 - - - - - 554 - - - YES - - - - - - 555 - - - - - 556 - - - YES - - - - - - 557 - - - - - 558 - - - YES - - - - - - 559 - - - - - 560 - - - YES - - - - - - 561 - - - - - 562 - - - YES - - - - - - 563 - - - - - 587 - - - - - 588 - - - - - 589 - - - - - 594 - - - - - 595 - - - - - 599 - - - YES - - - - - - 600 - - - YES - - - - - - - - - 602 - - - YES - - - - - - 603 - - - YES - - - - - - 604 - - - YES - - - - - - 605 - - - YES - - - - - - 606 - - - - - 607 - - - - - 608 - - - - - 609 - - - - - 621 - - - - - 622 - - - - - 623 - - - - - 242 - - - YES - - - - - - - - - 246 - - - - - 245 - - - - - 244 - - - - - 243 - - - - - 632 - - - YES - - - - - - 633 - - - YES - - - - - - - - - - - - - - - - - - - - 634 - - - - - 635 - - - - - 636 - - - - - 637 - - - - - 638 - - - - - 639 - - - - - 640 - - - - - 641 - - - - - 642 - - - - - 643 - - - - - 644 - - - YES - - - - - - 645 - - - YES - - - - - - 646 - - - YES - - - - - - 647 - - - YES - - - - - - 648 - - - YES - - - - - - 649 - - - YES - - - - - - - 650 - - - - - 651 - - - - - 652 - - - YES - - - - - - - - 653 - - - - - 654 - - - - - 655 - - - - - 656 - - - YES - - - - - - - - - - - - - 657 - - - - - 658 - - - - - 659 - - - - - 660 - - - - - 661 - - - - - 662 - - - - - 663 - - - - - 664 - - - - - 665 - - - YES - - - - - - - - - - - 666 - - - - - 667 - - - - - 668 - - - - - 669 - - - - - 670 - - - - - 671 - - - - - 672 - - - YES - - - - - - - - - - 673 - - - - - 674 - - - - - 675 - - - - - 676 - - - - - 677 - - - - - - - YES - - YES - -3.IBPluginDependency - -3.ImportedFromIB2 - 130.IBEditorWindowLastContentRect - 130.IBPluginDependency - 130.ImportedFromIB2 - 131.IBPluginDependency - 131.ImportedFromIB2 - 134.IBPluginDependency - 134.ImportedFromIB2 - 136.IBPluginDependency - 136.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 196.IBPluginDependency - 196.ImportedFromIB2 - 2.IBPluginDependency - 2.ImportedFromIB2 - 205.ImportedFromIB2 - 21.IBEditorWindowLastContentRect - 21.IBPluginDependency - 21.IBWindowTemplateEditedContentRect - 21.ImportedFromIB2 - 21.NSWindowTemplate.visibleAtLaunch - 21.windowTemplate.hasMinSize - 21.windowTemplate.minSize - 241.IBPluginDependency - 241.ImportedFromIB2 - 242.IBEditorWindowLastContentRect - 242.IBPluginDependency - 242.ImportedFromIB2 - 243.IBPluginDependency - 243.ImportedFromIB2 - 244.IBPluginDependency - 244.ImportedFromIB2 - 245.IBPluginDependency - 245.ImportedFromIB2 - 246.IBPluginDependency - 246.ImportedFromIB2 - 29.IBEditorWindowLastContentRect - 29.IBPluginDependency - 29.ImportedFromIB2 - 518.IBPluginDependency - 519.IBEditorWindowLastContentRect - 519.IBPluginDependency - 520.IBPluginDependency - 526.IBPluginDependency - 527.IBPluginDependency - 528.IBPluginDependency - 529.IBPluginDependency - 530.CustomClassName - 530.IBPluginDependency - 531.CustomClassName - 531.IBPluginDependency - 532.CustomClassName - 532.IBEditorWindowLastContentRect - 532.IBPluginDependency - 538.IBPluginDependency - 539.IBPluginDependency - 540.IBPluginDependency - 541.IBPluginDependency - 542.CustomClassName - 542.IBPluginDependency - 554.IBPluginDependency - 555.IBPluginDependency - 556.IBPluginDependency - 557.IBPluginDependency - 558.IBPluginDependency - 559.IBPluginDependency - 56.IBPluginDependency - 56.ImportedFromIB2 - 560.IBPluginDependency - 561.IBPluginDependency - 562.IBPluginDependency - 563.IBPluginDependency - 57.IBEditorWindowLastContentRect - 57.IBPluginDependency - 57.ImportedFromIB2 - 58.IBPluginDependency - 58.ImportedFromIB2 - 587.IBPluginDependency - 588.IBPluginDependency - 589.IBPluginDependency - 594.IBPluginDependency - 595.IBPluginDependency - 599.IBEditorWindowLastContentRect - 599.IBPluginDependency - 599.IBWindowTemplateEditedContentRect - 599.NSWindowTemplate.visibleAtLaunch - 600.IBPluginDependency - 602.IBPluginDependency - 603.IBPluginDependency - 604.IBPluginDependency - 605.IBPluginDependency - 606.IBPluginDependency - 607.IBPluginDependency - 608.IBPluginDependency - 609.IBPluginDependency - 622.IBPluginDependency - 623.IBPluginDependency - 632.IBPluginDependency - 633.IBEditorWindowLastContentRect - 633.IBPluginDependency - 634.IBPluginDependency - 635.IBPluginDependency - 636.IBPluginDependency - 637.IBPluginDependency - 638.IBPluginDependency - 639.IBPluginDependency - 640.IBPluginDependency - 641.IBPluginDependency - 642.IBPluginDependency - 643.IBPluginDependency - 644.IBPluginDependency - 645.IBPluginDependency - 646.IBPluginDependency - 647.IBPluginDependency - 648.IBPluginDependency - 649.IBPluginDependency - 650.IBPluginDependency - 651.IBPluginDependency - 652.IBPluginDependency - 653.IBPluginDependency - 654.IBPluginDependency - 655.IBPluginDependency - 656.IBPluginDependency - 657.IBPluginDependency - 658.IBPluginDependency - 659.IBPluginDependency - 660.IBPluginDependency - 661.IBPluginDependency - 662.IBPluginDependency - 663.IBPluginDependency - 664.IBPluginDependency - 665.IBPluginDependency - 666.IBPluginDependency - 667.IBPluginDependency - 668.IBPluginDependency - 669.IBPluginDependency - 670.IBPluginDependency - 671.IBPluginDependency - 672.IBPluginDependency - 673.IBPluginDependency - 674.IBPluginDependency - 675.IBPluginDependency - 676.IBPluginDependency - 677.IBPluginDependency - 75.IBPluginDependency - 75.ImportedFromIB2 - 81.IBEditorWindowLastContentRect - 81.IBPluginDependency - 81.ImportedFromIB2 - 83.IBPluginDependency - 83.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - {{370, 880}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - {{59, 386}, {600, 282}} - com.apple.InterfaceBuilder.CocoaPlugin - {{59, 386}, {600, 282}} - - - - {213, 107} - com.apple.InterfaceBuilder.CocoaPlugin - - {{278, 663}, {194, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{73, 736}, {381, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - {{393, 713}, {181, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ConnectionsCollectionView - com.apple.InterfaceBuilder.CocoaPlugin - IconCollectionItem - com.apple.InterfaceBuilder.CocoaPlugin - IconViewBox - {{247, 549}, {179, 157}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ConnectionsArrayController - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - {{85, 553}, {214, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - {{190, 479}, {331, 175}} - com.apple.InterfaceBuilder.CocoaPlugin - {{190, 479}, {331, 175}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{278, 453}, {254, 283}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{182, 643}, {198, 93}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 707 - - - - YES - - ConnectionsArrayController - NSArrayController - - IBProjectSource - ConnectionsArrayController.h - - - - ConnectionsCollectionView - NSCollectionView - - IBProjectSource - ConnectionsCollectionView/ConnectionsCollectionView.h - - - - IconCollectionItem - NSCollectionViewItem - - doubleClick: - id - - - doubleClick: - - doubleClick: - id - - - - IBProjectSource - ConnectionsCollectionView/IconCollectionItem.h - - - - IconViewBox - NSBox - - delegate - id - - - delegate - - delegate - id - - - - IBProjectSource - ConnectionsCollectionView/IconViewBox.h - - - - MongoHub_AppDelegate - NSObject - - YES - - YES - addConection: - deleteConnection: - doubleClick: - editConnection: - resizeConnectionItemView: - saveAction: - showAddConnectionPanel: - showConnectionWindow: - showEditConnectionPanel: - - - YES - id - id - id - id - id - id - id - id - id - - - - YES - - YES - addConection: - deleteConnection: - doubleClick: - editConnection: - resizeConnectionItemView: - saveAction: - showAddConnectionPanel: - showConnectionWindow: - showEditConnectionPanel: - - - YES - - addConection: - id - - - deleteConnection: - id - - - doubleClick: - id - - - editConnection: - id - - - resizeConnectionItemView: - id - - - saveAction: - id - - - showAddConnectionPanel: - id - - - showConnectionWindow: - id - - - showEditConnectionPanel: - id - - - - - YES - - YES - bundleVersion - connectionsArrayController - connectionsCollectionView - window - - - YES - NSTextField - ConnectionsArrayController - ConnectionsCollectionView - NSWindow - - - - YES - - YES - bundleVersion - connectionsArrayController - connectionsCollectionView - window - - - YES - - bundleVersion - NSTextField - - - connectionsArrayController - ConnectionsArrayController - - - connectionsCollectionView - ConnectionsCollectionView - - - window - NSWindow - - - - - IBProjectSource - MongoHub_AppDelegate.h - - - - MongoHub_AppDelegate - NSObject - - IBUserSource - - - - - NSObject - - IBProjectSource - JSON/NSObject+SBJSON.h - - - - NSObject - - IBProjectSource - JSON/SBJsonWriter.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - - YES - - BWSheetController - NSObject - - YES - - YES - closeSheet: - messageDelegateAndCloseSheet: - openSheet: - - - YES - id - id - id - - - - YES - - YES - closeSheet: - messageDelegateAndCloseSheet: - openSheet: - - - YES - - closeSheet: - id - - - messageDelegateAndCloseSheet: - id - - - openSheet: - id - - - - - YES - - YES - delegate - parentWindow - sheet - - - YES - id - NSWindow - NSWindow - - - - YES - - YES - delegate - parentWindow - sheet - - - YES - - delegate - id - - - parentWindow - NSWindow - - - sheet - NSWindow - - - - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWSheetController.h - - - - BWTexturedSlider - NSSlider - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTexturedSlider.h - - - - BWTexturedSliderCell - NSSliderCell - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWTexturedSliderCell.h - - - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSBrowser - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSBrowser.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSCollectionView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSCollectionView.h - - - - NSCollectionViewItem - NSViewController - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFontManager - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSImageCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSImageCell.h - - - - NSImageView - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSImageView.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMatrix - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSMatrix.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMovieView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMovieView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSPanel - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSPanel.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSScrollView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSScrollView.h - - - - NSScroller - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSScroller.h - - - - NSSlider - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSSlider.h - - - - NSSliderCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSSliderCell.h - - - - NSTableView - NSControl - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSViewController - NSResponder - - view - NSView - - - view - - view - NSView - - - - IBFrameworkSource - AppKit.framework/Headers/NSViewController.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - SUUpdater - NSObject - - checkForUpdates: - id - - - checkForUpdates: - - checkForUpdates: - id - - - - delegate - id - - - delegate - - delegate - id - - - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../MongoHub.xcodeproj - 3 - - YES - - YES - NSAddOnTexture - NSMenuCheckmark - NSMenuMixedState - NSRemoveOnTexture - connecticon - database - editicon - - - YES - {11, 11} - {9, 8} - {7, 2} - {11, 11} - {32, 32} - {512, 512} - {32, 32} - - - - diff --git a/Export.xib b/Export.xib deleted file mode 100644 index e880b1c5..00000000 --- a/Export.xib +++ /dev/null @@ -1,2412 +0,0 @@ - - - - 1060 - 10J567 - 823 - 1038.35 - 462.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 823 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - ExportWindowController - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{196, 124}, {581, 386}} - 544735232 - Export To MySQL Database - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 36 - - YES - - - 256 - - YES - - - 268 - {{274, 47}, {38, 17}} - - YES - - 68288064 - 272630784 - User - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 268 - {{410, 12}, {118, 25}} - - YES - - -2080244224 - 134217728 - Connect - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{310, 44}, {56, 22}} - - YES - - -1804468671 - 272630784 - - - root - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - - - - 268 - {{371, 47}, {57, 17}} - - YES - - 68288064 - 272630784 - Passwd - - - - - - - - - 268 - {{15, 47}, {38, 17}} - - YES - - 68288064 - 272630784 - Host - - - - - - - - - 268 - {{181, 47}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{216, 44}, {53, 22}} - - YES - - -1804468671 - 272630784 - - - 3306 - - YES - - - - - - - 268 - {{58, 44}, {118, 22}} - - YES - - -1804468671 - 272630784 - - - localhost - - YES - - - - - - - 268 - {{432, 44}, {96, 22}} - - YES - - 343014976 - 272630848 - - - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{15, 15}, {164, 26}} - - YES - - -1539178944 - 2048 - - - 109199615 - 129 - - - 400 - 75 - - - Choose Database - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - - 1 - YES - YES - 2 - - - - {{1, 1}, {546, 76}} - - - - {{17, 274}, {548, 92}} - - {0, 0} - - 67239424 - 0 - Connect to MySQL Database - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 36 - - YES - - - 256 - - YES - - - 268 - {{15, 192}, {80, 17}} - - YES - - 68288064 - 272630784 - Collection - - - - - - - - - 268 - {{409, 12}, {118, 25}} - - YES - - -1543373312 - 134217728 - Export - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{90, 187}, {167, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 5388 - - {{16, 13}, {387, 20}} - - 16392 - 1 - - - - 268 - {{308, 186}, {222, 26}} - - YES - - -1539178944 - 2048 - - - 109199615 - 129 - - - 400 - 75 - - - Choose a table - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - - 1 - YES - YES - 2 - - - - - 268 - - YES - - - 2304 - - YES - - - 256 - {507, 117} - - YES - - - 256 - {507, 17} - - - - - - -2147483392 - {{224, 0}, {16, 17}} - - - - YES - - Col_ID1 - 244 - 40 - 1000 - - 75628096 - 2048 - MySQL Table Fields - - - 3 - MC4zMzMzMzI5ODU2AA - - - 6 - System - headerTextColor - - - - - 337772096 - 2048 - Text Cell - - - - 6 - System - controlBackgroundColor - - - - - 3 - YES - - - - Col_ID2 - 257 - 40 - 1000 - - 75628096 - 2048 - MongoDB Keys - - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 17 - -692060160 - - - 1 - 2 - 15 - 0 - YES - 0 - - - {{1, 17}, {507, 117}} - - - - - 4 - - - - -2147483392 - {{224, 17}, {15, 102}} - - - _doScroller: - 37 - 0.1947367936372757 - - - - -2147483392 - {{-100, -100}, {223, 15}} - - 1 - - _doScroller: - 0.57142859697341919 - - - - 2304 - - YES - - - {{1, 0}, {507, 17}} - - - - - 4 - - - - {{18, 44}, {509, 135}} - - - 562 - - - - - - QSAAAEEgAABBmAAAQZgAAA - - - {{1, 1}, {545, 221}} - - - - {{17, 16}, {547, 237}} - - {0, 0} - - 67239424 - 0 - Export to MongoDB Collection - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {581, 386} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - - YES - value - name - @count - - YES - - YES - YES - YES - YES - YES - - - - YES - value - name - @count - - YES - - YES - YES - YES - YES - YES - - - FieldMapTableController - - - - - YES - - - window - - - - 3 - - - - delegate - - - - 4 - - - - hostTextField - - - - 45 - - - - portTextField - - - - 46 - - - - userTextField - - - - 47 - - - - passwdTextField - - - - 48 - - - - collectionTextField - - - - 50 - - - - progressIndicator - - - - 51 - - - - dbsArrayController - - - - 54 - - - - tablesArrayController - - - - 56 - - - - content: arrangedObjects - - - - - - content: arrangedObjects - content - arrangedObjects - 2 - - - 57 - - - - contentObjects: arrangedObjects.value - - - - - - contentObjects: arrangedObjects.value - contentObjects - arrangedObjects.value - - 2 - - - 60 - - - - contentValues: arrangedObjects.name - - - - - - contentValues: arrangedObjects.name - contentValues - arrangedObjects.name - - 2 - - - 62 - - - - enabled: arrangedObjects.@count - - - - - - enabled: arrangedObjects.@count - enabled - arrangedObjects.@count - 2 - - - 67 - - - - content: arrangedObjects - - - - - - content: arrangedObjects - content - arrangedObjects - 2 - - - 68 - - - - contentObjects: arrangedObjects.value - - - - - - contentObjects: arrangedObjects.value - contentObjects - arrangedObjects.value - - 2 - - - 72 - - - - contentValues: arrangedObjects.name - - - - - - contentValues: arrangedObjects.name - contentValues - arrangedObjects.name - - 2 - - - 74 - - - - enabled: arrangedObjects.@count - - - - - - enabled: arrangedObjects.@count - enabled - arrangedObjects.@count - 2 - - - 77 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 81 - - - - connect: - - - - 82 - - - - export: - - - - 83 - - - - showTables: - - - - 84 - - - - showFields: - - - - 94 - - - - delegate - - - - 108 - - - - dataSource - - - - 109 - - - - idTableView - - - - 110 - - - - fieldMapTableController - - - - 111 - - - - tablesPopUpButton - - - - 112 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - 5 - - - YES - - - - - - - - - - - - - - - 6 - - - YES - - - - - - - - - - - 7 - - - YES - - - - - - 8 - - - - - 9 - - - YES - - - - - - 10 - - - YES - - - - - - 11 - - - YES - - - - - - 17 - - - - - 18 - - - - - 19 - - - - - 20 - - - YES - - - - - - 21 - - - YES - - - - - - 22 - - - - - 23 - - - YES - - - - - - 24 - - - YES - - - - - - 25 - - - YES - - - - - - 26 - - - YES - - - - - - 27 - - - YES - - - - - - 28 - - - YES - - - - - - 29 - - - YES - - - - - - 30 - - - YES - - - - - - 31 - - - YES - - - - - - 32 - - - YES - - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - 37 - - - - - 38 - - - - - 39 - - - - - 40 - - - - - 41 - - - - - 42 - - - YES - - - - - - 43 - - - YES - - - - - - 44 - - - - - 53 - - - dbsArrayController - - - 55 - - - tablesArrayController - - - 85 - - - YES - - - - - - - - - 86 - - - - - 87 - - - - - 88 - - - YES - - - - - - - 89 - - - - - 90 - - - YES - - - - - - 91 - - - YES - - - - - - 92 - - - - - 93 - - - - - 107 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 10.IBPluginDependency - 107.IBPluginDependency - 11.IBPluginDependency - 17.IBPluginDependency - 18.IBPluginDependency - 19.IBPluginDependency - 2.IBPluginDependency - 20.IBPluginDependency - 21.IBEditorWindowLastContentRect - 21.IBPluginDependency - 22.IBPluginDependency - 23.IBPluginDependency - 24.IBPluginDependency - 25.IBPluginDependency - 26.IBPluginDependency - 27.IBPluginDependency - 28.IBPluginDependency - 29.IBPluginDependency - 30.IBPluginDependency - 31.IBPluginDependency - 32.IBPluginDependency - 33.IBPluginDependency - 34.IBPluginDependency - 35.IBPluginDependency - 36.IBPluginDependency - 37.IBPluginDependency - 38.IBPluginDependency - 39.IBPluginDependency - 40.IBPluginDependency - 41.IBPluginDependency - 42.IBPluginDependency - 43.IBEditorWindowLastContentRect - 43.IBPluginDependency - 44.IBPluginDependency - 53.IBPluginDependency - 55.IBPluginDependency - 7.IBPluginDependency - 8.IBPluginDependency - 85.IBPluginDependency - 86.IBPluginDependency - 87.IBPluginDependency - 88.IBPluginDependency - 89.IBPluginDependency - 9.IBPluginDependency - 90.IBPluginDependency - 91.IBPluginDependency - 92.IBPluginDependency - 93.IBPluginDependency - - - YES - {{46, 314}, {581, 386}} - com.apple.InterfaceBuilder.CocoaPlugin - {{46, 314}, {581, 386}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{437, 522}, {167, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{75, 609}, {184, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 112 - - - - YES - - ExportWindowController - NSWindowController - - YES - - YES - connect: - export: - showFields: - showTables: - - - YES - id - id - id - id - - - - YES - - YES - connect: - export: - showFields: - showTables: - - - YES - - connect: - id - - - export: - id - - - showFields: - id - - - showTables: - id - - - - - YES - - YES - collectionTextField - dbsArrayController - fieldMapTableController - hostTextField - passwdTextField - portTextField - progressIndicator - tablesArrayController - tablesPopUpButton - userTextField - - - YES - NSTextField - NSArrayController - FieldMapTableController - NSTextField - NSSecureTextField - NSTextField - NSProgressIndicator - NSArrayController - NSPopUpButton - NSTextField - - - - YES - - YES - collectionTextField - dbsArrayController - fieldMapTableController - hostTextField - passwdTextField - portTextField - progressIndicator - tablesArrayController - tablesPopUpButton - userTextField - - - YES - - collectionTextField - NSTextField - - - dbsArrayController - NSArrayController - - - fieldMapTableController - FieldMapTableController - - - hostTextField - NSTextField - - - passwdTextField - NSSecureTextField - - - portTextField - NSTextField - - - progressIndicator - NSProgressIndicator - - - tablesArrayController - NSArrayController - - - tablesPopUpButton - NSPopUpButton - - - userTextField - NSTextField - - - - - IBProjectSource - ExportWindowController.h - - - - FieldMapTableController - NSControl - - YES - - YES - addAtSelectedRow: - deleteSelectedRow: - - - YES - id - id - - - - YES - - YES - addAtSelectedRow: - deleteSelectedRow: - - - YES - - addAtSelectedRow: - id - - - deleteSelectedRow: - id - - - - - idTableView - NSTableView - - - idTableView - - idTableView - NSTableView - - - - IBProjectSource - FieldMapTableController.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - NSProgressIndicator - - IBProjectSource - NSProgressIndicator+Extras.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - RegexKit.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSProgressIndicator - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSProgressIndicator.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSScrollView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSScrollView.h - - - - NSScroller - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSScroller.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSSecureTextFieldCell - NSTextFieldCell - - - - NSTableColumn - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableColumn.h - - - - NSTableHeaderView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSTableHeaderView.h - - - - NSTableView - NSControl - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - - - YES - {9, 8} - {7, 2} - - - - diff --git a/Frameworks/MCPKit.framework/Headers b/Frameworks/MCPKit.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/Frameworks/MCPKit.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Frameworks/MCPKit.framework/MCPKit b/Frameworks/MCPKit.framework/MCPKit new file mode 120000 index 00000000..3632e678 --- /dev/null +++ b/Frameworks/MCPKit.framework/MCPKit @@ -0,0 +1 @@ +Versions/Current/MCPKit \ No newline at end of file diff --git a/Frameworks/MCPKit.framework/Resources b/Frameworks/MCPKit.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/Frameworks/MCPKit.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnection.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnection.h new file mode 100644 index 00000000..9c4c81cd --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnection.h @@ -0,0 +1,281 @@ +// +// $Id: MCPConnection.h 3231 2011-03-08 01:08:32Z rowanb $ +// +// MCPConnection.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 08/12/2001. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import +#import + +#import "MCPConstants.h" +#import "mysql.h" + +typedef struct { + MYSQL *mySQLConnection; + BOOL *pingActivePointer; + BOOL *lastPingSuccessPointer; +} MCPConnectionPingDetails; + +@class MCPResult, MCPStreamingResult; +@protocol MCPConnectionProxy, MCPConnectionDelegate; + +@interface MCPConnection : NSObject +{ + MYSQL *mConnection; + BOOL mConnected; + NSStringEncoding mEncoding; + NSTimeZone *mTimeZone; + NSUInteger mConnectionFlags; + + id delegate; + + // Anything that performs a mysql_net_read is not thread-safe: mysql queries, pings + // Always lock the connection first. Don't use this lock directly, use the lockConnection method! + NSConditionLock *connectionLock; + + BOOL useKeepAlive; + BOOL isDisconnecting; + BOOL isReconnecting; + BOOL userTriggeredDisconnect; + NSInteger connectionTimeout; + CGFloat keepAliveInterval; + + NSObject *connectionProxy; + NSString *connectionLogin; + NSString *connectionPassword; + NSString *connectionHost; + NSUInteger connectionPort; + NSString *connectionSocket; + NSUInteger maxAllowedPacketSize; + unsigned long connectionThreadId; + + BOOL useSSL; + NSString *sslKeyFilePath; + NSString *sslCertificatePath; + NSString *sslCACertificatePath; + + NSString *encoding, *previousEncoding; + NSStringEncoding stringEncoding; + BOOL encodingUsesLatin1Transport, previousEncodingUsesLatin1Transport; + + NSInteger currentProxyState; + + double lastQueryExecutionTime; + double lastQueryExecutedAtTime; + NSString *lastQueryErrorMessage; + NSUInteger lastQueryErrorId; + my_ulonglong lastQueryAffectedRows; + MCPConnectionCheck lastDelegateDecisionForLostConnection; + + BOOL isMaxAllowedPacketEditable; + + NSString *serverVersionString; + NSMutableDictionary *structure; + NSMutableArray *allKeysofDbStructure; + + pthread_t pingThread; + NSInteger pingFailureCount; + BOOL pingThreadActive; + BOOL lastPingSuccess; + BOOL lastPingBlocked; + NSTimer *keepAliveTimer; + double lastKeepAliveTime; + uint64_t connectionStartTime; + + BOOL retryAllowed; + BOOL queryCancelled; + BOOL queryCancelUsedReconnect; + BOOL delegateQueryLogging; + BOOL delegateResponseToWillQueryString; + BOOL delegateSupportsConnectionLostDecisions; + NSInteger isQueryingDbStructure; + BOOL cancelQueryingDbStructure; + BOOL lockQuerying; + NSInteger automaticReconnectAttempts; + + // Pointers + IMP cStringPtr; + IMP willQueryStringPtr; + IMP timeConnectedPtr; + + // Selectors + SEL cStringSEL; + SEL willQueryStringSEL; + SEL timeConnectedSEL; +} + +// Readonly properties +@property (readonly) double lastQueryExecutionTime; + +// Read/write properties +@property (readwrite, assign) BOOL useKeepAlive; +@property (readwrite, assign) BOOL delegateQueryLogging; +@property (readwrite, assign) NSInteger connectionTimeout; +@property (readwrite, assign) CGFloat keepAliveInterval; + +// Initialisation +- (id)initToHost:(NSString *)host withLogin:(NSString *)login usingPort:(NSUInteger)port; +- (id)initToSocket:(NSString *)socket withLogin:(NSString *)login; + +// Delegate +- (id)delegate; +- (void)setDelegate:(id)connectionDelegate; +- (MCPConnectionCheck)delegateDecisionForLostConnection; + +// Connection details +- (BOOL)setPort:(NSUInteger)thePort; +- (BOOL)setPassword:(NSString *)thePassword; +- (void) setSSL:(BOOL)shouldUseSSL usingKeyFilePath:(NSString *)keyFilePath certificatePath:(NSString *)certificatePath certificateAuthorityCertificatePath:(NSString *)caCertificatePath; + +// Proxy +- (BOOL)setConnectionProxy:(id )proxy; +- (void)connectionProxyStateChange:(id )proxy; + +// Connection +- (BOOL)connect; +- (void)disconnect; +- (BOOL)reconnect; +- (BOOL)isConnected; +- (BOOL)isConnectedViaSSL; +- (BOOL)userTriggeredDisconnect; +- (BOOL)checkConnection; +- (void)restoreConnectionDetails; +- (void)setAllowQueryRetries:(BOOL)allow; +- (double)timeConnected; + +// Pinging and keepalive +- (BOOL)pingConnectionUsingLoopDelay:(NSUInteger)loopDelay; +void backgroundPingTask(void *ptr); +void forceThreadExit(int signalNumber); +void pingThreadCleanup(void *pingDetails); +- (void)keepAlive:(NSTimer *)theTimer; +- (void)threadedKeepAlive; + +// Server versions +- (NSString *)serverVersionString; +- (NSInteger)serverMajorVersion; +- (NSInteger)serverMinorVersion; +- (NSInteger)serverReleaseVersion; + +// MySQL defaults ++ (NSDictionary *)getMySQLLocales; ++ (NSStringEncoding)encodingForMySQLEncoding:(const char *)mysqlEncoding; ++ (NSString *) mySQLEncodingForStringEncoding:(NSStringEncoding)stringEncoding; ++ (NSStringEncoding)defaultMySQLEncoding; ++ (BOOL)isErrorNumberConnectionError:(NSInteger)theErrorNumber; + +// Class maintenance ++ (void)setTruncateLongFieldInLogs:(BOOL)iTruncFlag; ++ (BOOL)truncateLongField; +- (BOOL)setConnectionOption:(NSInteger)option toValue:(BOOL)value; +- (BOOL)connectWithLogin:(NSString *)login password:(NSString *)pass host:(NSString *)host port:(NSUInteger)port socket:(NSString *)socket; + +- (BOOL)selectDB:(NSString *)dbName; + +// Error information +- (BOOL)queryErrored; +- (NSString *)getLastErrorMessage; +- (void)setLastErrorMessage:(NSString *)theErrorMessage; +- (NSUInteger)getLastErrorID; +- (void)updateErrorStatuses; + +// Queries +- (NSString *)prepareBinaryData:(NSData *)theData; +- (NSString *)prepareString:(NSString *)theString; +- (NSString *)quoteObject:(id)theObject; +- (MCPResult *)queryString:(NSString *)query; +- (MCPStreamingResult *)streamingQueryString:(NSString *)query; +- (MCPStreamingResult *)streamingQueryString:(NSString *)query useLowMemoryBlockingStreaming:(BOOL)fullStream; +- (id)queryString:(NSString *)query usingEncoding:(NSStringEncoding)encoding streamingResult:(NSInteger)streamResult; +- (my_ulonglong)affectedRows; +- (my_ulonglong)insertId; +- (void)cancelCurrentQuery; +- (BOOL)queryCancelled; +- (BOOL)queryCancellationUsedReconnect; +- (void)flushMultiResults; + +// Locking +- (void)lockConnection; +- (BOOL)tryLockConnection; +- (void)unlockConnection; + +// Database structure +- (MCPResult *)listDBs; +- (MCPResult *)listDBsLike:(NSString *)dbsName; +- (MCPResult *)listTables; +- (MCPResult *)listTablesLike:(NSString *)tablesName; +- (NSArray *)listTablesFromDB:(NSString *)dbName; +- (NSArray *)listTablesFromDB:(NSString *)dbName like:(NSString *)tablesName; +- (MCPResult *)listFieldsFromTable:(NSString *)tableName; +- (MCPResult *)listFieldsFromTable:(NSString *)tableName like:(NSString *)fieldsName; + +// Structure querying +- (void)queryDbStructureWithUserInfo:(NSDictionary*)userInfo; +- (NSDictionary *)getDbStructure; +- (NSArray *)getAllKeysOfDbStructure; +- (BOOL)isQueryingDatabaseStructure; +- (void)incrementQueryingDbStructure; +- (void)decrementQueryingDbStructure; +- (void)lockQuerying; +- (void)unlockQuerying; +- (void)updateGlobalVariablesWith:(NSDictionary*)object; + +// Server information +- (NSString *)clientInfo; +- (NSString *)hostInfo; +- (NSString *)serverInfo; +- (NSNumber *)protoInfo; +- (MCPResult *)listProcesses; +- (BOOL)killProcess:(unsigned long)pid; +- (NSString *)findSocketPath; + +// Encoding +- (BOOL)setEncoding:(NSString *)theEncoding; +- (NSString *)encoding; +- (NSStringEncoding)stringEncoding; +- (BOOL)setEncodingUsesLatin1Transport:(BOOL)useLatin1; +- (BOOL)encodingUsesLatin1Transport; +- (void)storeEncodingForRestoration; +- (void)restoreStoredEncoding; + +// Time zone +- (void)setTimeZone:(NSTimeZone *)iTimeZone; +- (NSTimeZone *)timeZone; + +// Packet size +- (BOOL)fetchMaxAllowedPacket; +- (NSUInteger)getMaxAllowedPacket; +- (BOOL)isMaxAllowedPacketEditable; +- (NSUInteger)setMaxAllowedPacketTo:(NSUInteger)newSize resetSize:(BOOL)reset; + +// Data conversion +- (const char *)cStringFromString:(NSString *)theString; +- (const char *)cStringFromString:(NSString *)theString usingEncoding:(NSStringEncoding)encoding; +- (NSString *)stringWithCString:(const char *)theCString; +- (NSString *)stringWithCString:(const char *)theCString usingEncoding:(NSStringEncoding)encoding; +- (NSString *)stringWithText:(NSData *)theTextData; +- (NSString *)stringWithUTF8CString:(const char *)theCString; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnectionDelegate.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnectionDelegate.h new file mode 100644 index 00000000..2d10675f --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnectionDelegate.h @@ -0,0 +1,81 @@ +// +// $Id: MCPConnectionDelegate.h 3212 2011-03-02 02:25:08Z rowanb $ +// +// MCPConnectionDelegate.h +// MCPKit +// +// Created by Stuart Connolly (stuconnolly.com) on October 20, 2010. +// Copyright (c) 2010 Stuart Connolly. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +@protocol MCPConnectionDelegate + +/** + * + * @param query + * @param connection + */ +- (void)willQueryString:(NSString *)query connection:(id)connection; + +/** + * + * @param error + * @param connection + */ +- (void)queryGaveError:(NSString *)error connection:(id)connection; + +/** + * + * + * @param error + * @param message + */ +- (void)showErrorWithTitle:(NSString *)error message:(NSString *)message; + +/** + * + * + * @param connection + */ +- (NSString *)keychainPasswordForConnection:(id)connection; + +/** + * + * + * @param connection + */ +- (NSString *)onReconnectShouldSelectDatabase:(id)connection; + +/** + * + * + * @param connection + */ +- (void)noConnectionAvailable:(id)connection; + +/** + * + * + * @param connection + */ +- (MCPConnectionCheck)connectionLost:(id)connection; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnectionProxy.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnectionProxy.h new file mode 100644 index 00000000..8c88302f --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConnectionProxy.h @@ -0,0 +1,70 @@ +// +// $Id: MCPConnectionProxy.h 3212 2011-03-02 02:25:08Z rowanb $ +// +// MCPConnectionProxy.h +// MCPKit +// +// Created by Stuart Connolly (stuconnolly.com) on July 2, 2009. +// Copyright (c) 2009 Stuart Connolly. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +/** + * Connection proxy state constants. + */ +enum PROXY_TUNNEL_STATES +{ + PROXY_STATE_IDLE = 0, + PROXY_STATE_CONNECTING = 1, + PROXY_STATE_WAITING_FOR_AUTH = 2, + PROXY_STATE_CONNECTED = 3, + PROXY_STATE_FORWARDING_FAILED = 4 +}; + +@protocol MCPConnectionProxy + +/** + * Connect the proxy. + */ +- (void)connect; + +/** + * Disconnect the proxy. + */ +- (void)disconnect; + +/** + * Get the current state of the proxy. + */ +- (NSInteger)state; + +/** + * Get the local port being used by the proxy. + */ +- (NSUInteger)localPort; + +/** + * Sets the method the proxy should call whenever the state of the connection changes. + */ +- (BOOL)setConnectionStateChangeSelector:(SEL)theStateChangeSelector delegate:(id)theDelegate; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConstants.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConstants.h new file mode 100644 index 00000000..7c644b92 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPConstants.h @@ -0,0 +1,82 @@ +// +// $Id: MCPConstants.h 2123 2010-04-16 17:18:54Z jabakobob $ +// +// MCPConstants.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 03/06/2001. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +// Result type constants +enum { + MCPTypeArray = 1, + MCPTypeDictionary = 2, + MCPTypeFlippedArray = 3, + MCPTypeFlippedDictionary = 4 +}; +typedef NSUInteger MCPReturnType; + +// Connection check constants +enum { + MCPConnectionCheckRetry = 0, + MCPConnectionCheckReconnect = 1, + MCPConnectionCheckDisconnect = 2 +}; +typedef NSUInteger MCPConnectionCheck; + +// Streaming result set constants +enum +{ + MCPStreamingNone = 0, + MCPStreamingFast = 1, + MCPStreamingLowMem = 2 +}; +typedef NSUInteger MCPQueryStreamingType; + +// Connection state +// This is used internally by MCPConnection to prevent simultaneous execution of different queries +enum { + MCPConnectionIdle = 0, + MCPConnectionBusy = 1 +}; + +// Charcater set mapping constants +typedef struct _OUR_CHARSET +{ + NSUInteger nr; + const char *name; + const char *collation; + NSUInteger char_minlen; + NSUInteger char_maxlen; +} OUR_CHARSET; + +// Deafult connection option +extern const NSUInteger kMCPConnectionDefaultOption; + +// Default socket (from the mysql.h used at compile time) +extern const char *kMCPConnectionDefaultSocket; + +// Added to MySQL error code +extern const NSUInteger kMCPConnectionNotInited; + +// The length of the truncation if required +extern const NSUInteger kLengthOfTruncationForLog; diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPFastQueries.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPFastQueries.h new file mode 100644 index 00000000..76263af3 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPFastQueries.h @@ -0,0 +1,46 @@ +// +// $Id: MCPFastQueries.h 1269 2009-08-26 21:18:28Z stuart02 $ +// +// MCPFastQueries.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 03/06/2002. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +#import "MCPConnection.h" + +@interface MCPConnection (MCPFastQueries) + +// For insert queries, get directly the Id of the newly inserted row. +- (my_ulonglong)insertQuery:(NSString *)query; +- (my_ulonglong)updateQuery:(NSString *)query; + +// Returns directly a proper NS object, or a collection (NSArray, NSDictionary...). +- (id)getFirstFieldFromQuery:(NSString *)query; +- (id)getFirstRowFromQuery:(NSString *)query asType:(MCPReturnType)type; +- (id)getAllRowsFromQuery:(NSString *)query asType:(MCPReturnType)type; +- (NSArray *)getQuery:(NSString *)query colWithIndex:(NSUInteger)col; +- (NSArray *)getQuery:(NSString *)query colWithName:(NSString *)colName; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPGeometryData.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPGeometryData.h new file mode 100644 index 00000000..f19d8b14 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPGeometryData.h @@ -0,0 +1,65 @@ +// +// $Id: MCPGeometryData.h 3212 2011-03-02 02:25:08Z rowanb $ +// +// MCPGeometryData.h +// sequel-pro +// +// Created by Hans-Jörg Bibiko on October 07, 2010 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import +#import + +enum wkbType +{ + wkb_point = 1, + wkb_linestring = 2, + wkb_polygon = 3, + wkb_multipoint = 4, + wkb_multilinestring = 5, + wkb_multipolygon = 6, + wkb_geometrycollection = 7 +}; + +typedef struct st_point_2d_ +{ + double x; + double y; +} st_point_2d; + +@interface MCPGeometryData : NSObject +{ + // Holds the WKB bytes coming from SQL server + Byte *geoBuffer; + + // Holds the buffer length + NSUInteger bufferLength; + +} + +- (id)initWithBytes:(const void *)geoData length:(NSUInteger)length; ++ (id)dataWithBytes:(const void *)geoData length:(NSUInteger)length; +- (NSString*)description; +- (NSUInteger)length; +- (NSData*)data; +- (NSString*)wktString; +- (NSDictionary*)coordinates; +- (NSInteger)wkbType; +- (NSString*)wktType; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPKit.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPKit.h new file mode 100644 index 00000000..b4a86723 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPKit.h @@ -0,0 +1,44 @@ +// +// $Id: MCPKit.h 2785 2010-10-20 20:08:08Z stuart02 $ +// +// MCPKit.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 08/12/2001. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import +#import + +#import "mysql.h" diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPNull.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPNull.h new file mode 100644 index 00000000..f31186dc --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPNull.h @@ -0,0 +1,35 @@ +// +// $Id: MCPNull.h 1179 2009-08-08 02:49:40Z stuart02 $ +// +// MCPNull.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 02/06/2002. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +@interface NSObject (MCPNSNullTest) + +- (BOOL)isNSNull; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPNumber.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPNumber.h new file mode 100644 index 00000000..7f593585 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPNumber.h @@ -0,0 +1,83 @@ +// +// $Id: MCPNumber.h 1179 2009-08-08 02:49:40Z stuart02 $ +// +// MCPNumber.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 08/12/2002. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +@interface MCPNumber : NSNumber +{ + const char *typeCode; + NSNumber *number; +} + ++ (MCPNumber *)numberWithChar:(char)value; ++ (MCPNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (MCPNumber *)numberWithShort:(short)value; ++ (MCPNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (MCPNumber *)numberWithInt:(int)value; ++ (MCPNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (MCPNumber *)numberWithLong:(long)value; ++ (MCPNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (MCPNumber *)numberWithLongLong:(long long)value; ++ (MCPNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (MCPNumber *)numberWithFloat:(float)value; ++ (MCPNumber *)numberWithDouble:(double)value; ++ (MCPNumber *)numberWithBool:(BOOL)value; + +- (id)initWithChar:(char)value; +- (id)initWithUnsignedChar:(unsigned char)value; +- (id)initWithShort:(short)value; +- (id)initWithUnsignedShort:(unsigned short)value; +- (id)initWithInt:(int)value; +- (id)initWithUnsignedInt:(unsigned int)value; +- (id)initWithLong:(long)value; +- (id)initWithUnsignedLong:(unsigned long)value; +- (id)initWithLongLong:(long long)value; +- (id)initWithUnsignedLongLong:(unsigned long long)value; +- (id)initWithFloat:(float)value; +- (id)initWithDouble:(double)value; +- (id)initWithBool:(BOOL)value; + +// Important NSNumber primitive methods +- (const char *)objCType; +- (void)getValue:(void *)buffer; + +- (char)charValue; +- (unsigned char)unsignedCharValue; +- (short)shortValue; +- (unsigned short)unsignedShortValue; +- (int)intValue; +- (unsigned int)unsignedIntValue; +- (long)longValue; +- (unsigned long)unsignedLongValue; +- (long long)longLongValue; +- (unsigned long long)unsignedLongLongValue; +- (float)floatValue; +- (double)doubleValue; +- (BOOL)boolValue; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPResult.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPResult.h new file mode 100644 index 00000000..793970a7 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPResult.h @@ -0,0 +1,86 @@ +// +// $Id: MCPResult.h 2006 2010-03-26 13:14:54Z stuart02 $ +// +// MCPResult.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 08/12/2002. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +#import "MCPConstants.h" +#import "mysql.h" + +#define MAGIC_BINARY_CHARSET_NR 63 + +@interface MCPResult : NSObject +{ + MYSQL_RES *mResult; /* The MYSQL_RES structure of the C API. */ + NSArray *mNames; /* An NSArray holding the name of the columns. */ + NSStringEncoding mEncoding; /* The encoding used by MySQL server, to ISO-1 default. */ + NSUInteger mNumOfFields; /* The number of fields in the result. */ + NSTimeZone *mTimeZone; /* The time zone of the connection when the query was made. */ + BOOL mReturnDataAsStrings; /* Whether to return data types as strings */ +} + +// Initialization +- (id)initWithMySQLPtr:(MYSQL *)mySQLPtr encoding:(NSStringEncoding)theEncoding timeZone:(NSTimeZone *)iTimeZone; +- (id)initWithResPtr:(MYSQL_RES *)mySQLResPtr encoding:(NSStringEncoding)theEncoding timeZone:(NSTimeZone *)iTimeZone; + +// Result info +- (my_ulonglong)numOfRows; +- (NSUInteger)numOfFields; + +// Rows +- (void)dataSeek:(my_ulonglong)row; +- (id)fetchRowAsType:(MCPReturnType) aType; +- (NSArray *)fetchRowAsArray; +- (NSDictionary *)fetchRowAsDictionary; + +// Columns +- (NSArray *)fetchFieldNames; +- (id)fetchTypesAsType:(MCPReturnType)aType; +- (NSArray *)fetchTypesAsArray; +- (NSDictionary *)fetchTypesAsDictionary; +- (NSArray *)fetchResultFieldsStructure; + +- (NSUInteger)fetchFlagsAtIndex:(NSUInteger)index; +- (NSUInteger)fetchFlagsForKey:(NSString *)key; + +- (BOOL)isBlobAtIndex:(NSUInteger)index; +- (BOOL)isBlobForKey:(NSString *)key; + +// Conversion +- (void) setReturnDataAsStrings:(BOOL)alwaysConvertData; +- (NSString *)stringWithText:(NSData *)theTextData; +- (const char *)cStringFromString:(NSString *)theString; +- (NSString *)stringWithCString:(const char *)theCString; + +// Other +- (NSString *)mysqlTypeToStringForType:(NSUInteger)type withCharsetNr:(NSUInteger)charsetnr withFlags:(NSUInteger)flags withLength:(unsigned long long)length; +- (NSString *)mysqlTypeToGroupForType:(NSUInteger)type withCharsetNr:(NSUInteger)charsetnr withFlags:(NSUInteger)flags; +- (NSString *)findCharsetName:(NSUInteger)charsetnr; +- (NSString *)findCharsetCollation:(NSUInteger)charsetnr; +- (NSUInteger)findCharsetMaxByteLengthPerChar:(NSUInteger)charsetnr; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPResultPlus.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPResultPlus.h new file mode 100644 index 00000000..71b872b8 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPResultPlus.h @@ -0,0 +1,42 @@ +// +// $Id: MCPResultPlus.h 1269 2009-08-26 21:18:28Z stuart02 $ +// +// MCPResultPlus.h +// MCPKit +// +// Created by Serge Cohen (serge.cohen@m4x.org) on 03/06/2002. +// Copyright (c) 2001 Serge Cohen. All rights reserved. +// +// Forked by the Sequel Pro team (sequelpro.com), April 2009 +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at +// More info at + +#import + +#import "MCPResult.h" + +@interface MCPResult (MCPResultPlus) + +// Getting a complete column as an array +- (NSArray *)fetchColAtIndex:(NSUInteger)col; +- (NSArray *)fetchColWithName:(NSString *)colName; + +// Getting the complete result as 2D array +- (id)fetch2DResultAsType:(MCPReturnType)type; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/MCPStreamingResult.h b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPStreamingResult.h new file mode 100644 index 00000000..150a3e76 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/MCPStreamingResult.h @@ -0,0 +1,74 @@ +// +// $Id: MCPStreamingResult.h 2171 2010-04-26 15:16:43Z stuart02 $ +// +// MCPStreamingResult.h +// sequel-pro +// +// Created by Rowan Beentje on Aug 16, 2009 +// Copyright 2009 Rowan Beentje. All rights reserved. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import + +#import "MCPResult.h" +#import "mysql.h" + +@class MCPConnection; + +typedef struct SP_MYSQL_ROWS { + char *data; + unsigned long *dataLengths; + struct SP_MYSQL_ROWS *nextRow; +} LOCAL_ROW_DATA; + +@interface MCPStreamingResult : MCPResult +{ + MCPConnection *parentConnection; + + MYSQL_FIELD *fieldDefinitions; + + BOOL fullyStreaming; + BOOL connectionUnlocked; + BOOL dataDownloaded; + BOOL dataFreed; + + LOCAL_ROW_DATA *localDataStore; + LOCAL_ROW_DATA *currentDataStoreEntry; + LOCAL_ROW_DATA *localDataStoreLastEntry; + + unsigned long localDataRows; + unsigned long localDataAllocated; + unsigned long downloadedRowCount; + unsigned long processedRowCount; + unsigned long freedRowCount; + + pthread_mutex_t dataCreationLock; + pthread_mutex_t dataFreeLock; + + IMP isConnectedPtr; + SEL isConnectedSEL; +} + +- (id)initWithMySQLPtr:(MYSQL *)mySQLPtr encoding:(NSStringEncoding)theEncoding timeZone:(NSTimeZone *)theTimeZone connection:(MCPConnection *)theConnection; +- (id)initWithMySQLPtr:(MYSQL *)mySQLPtr encoding:(NSStringEncoding)theEncoding timeZone:(NSTimeZone *)theTimeZone connection:(MCPConnection *)theConnection withFullStreaming:(BOOL)useFullStreaming; + +// Results fetching +- (NSArray *)fetchNextRowAsArray; +- (void) cancelResultLoad; + +@end diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/my_alloc.h b/Frameworks/MCPKit.framework/Versions/A/Headers/my_alloc.h new file mode 100644 index 00000000..93b7438a --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/my_alloc.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2000 MySQL AB + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Data structures for mysys/my_alloc.c (root memory allocator) +*/ + +#ifndef _my_alloc_h +#define _my_alloc_h + +#define ALLOC_MAX_BLOCK_TO_DROP 4096 +#define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 + +typedef struct st_used_mem +{ /* struct for once_alloc (block) */ + struct st_used_mem *next; /* Next block in use */ + unsigned int left; /* memory left in block */ + unsigned int size; /* size of block */ +} USED_MEM; + + +typedef struct st_mem_root +{ + USED_MEM *free; /* blocks with free memory in it */ + USED_MEM *used; /* blocks almost without free memory */ + USED_MEM *pre_alloc; /* preallocated block */ + /* if block have less memory it will be put in 'used' list */ + size_t min_malloc; + size_t block_size; /* initial block size */ + unsigned int block_num; /* allocated blocks counter */ + /* + first free block in queue test counter (if it exceed + MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) + */ + unsigned int first_block_usage; + + void (*error_handler)(void); +} MEM_ROOT; +#endif diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/my_list.h b/Frameworks/MCPKit.framework/Versions/A/Headers/my_list.h new file mode 100644 index 00000000..775b5658 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/my_list.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2000 MySQL AB + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _list_h_ +#define _list_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct st_list { + struct st_list *prev,*next; + void *data; +} LIST; + +typedef int (*list_walk_action)(void *,void *); + +extern LIST *list_add(LIST *root,LIST *element); +extern LIST *list_delete(LIST *root,LIST *element); +extern LIST *list_cons(void *data,LIST *root); +extern LIST *list_reverse(LIST *root); +extern void list_free(LIST *root,unsigned int free_data); +extern unsigned int list_length(LIST *); +extern int list_walk(LIST *,list_walk_action action,unsigned char * argument); + +#define list_rest(a) ((a)->next) +#define list_push(a,b) (a)=list_cons((b),(a)) +#define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old) ; my_free((unsigned char *) old,MYF(MY_FAE)); } + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/mysql.h b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql.h new file mode 100644 index 00000000..699bd1f1 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql.h @@ -0,0 +1,870 @@ +/* Copyright (C) 2000-2003 MySQL AB + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + This file defines the client API to MySQL and also the ABI of the + dynamically linked libmysqlclient. + + The ABI should never be changed in a released product of MySQL + thus you need to take great care when changing the file. In case + the file is changed so the ABI is broken, you must also + update the SHAREDLIB_MAJOR_VERSION in configure.in . + +*/ + +#ifndef _mysql_h +#define _mysql_h + +#ifdef _AIX /* large-file support will break without this */ +#include +#endif + +#ifdef __CYGWIN__ /* CYGWIN implements a UNIX API */ +#undef WIN +#undef _WIN +#undef _WIN32 +#undef _WIN64 +#undef __WIN__ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _global_h /* If not standard header */ +#ifndef MYSQL_ABI_CHECK +#include +#endif +#ifdef __LCC__ +#include /* For windows */ +#endif +typedef char my_bool; +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__) +#define __WIN__ +#endif +#if !defined(__WIN__) +#define STDCALL +#else +#define STDCALL __stdcall +#endif + +#ifndef my_socket_defined +#ifdef __WIN__ +#define my_socket SOCKET +#else +typedef int my_socket; +#endif /* __WIN__ */ +#endif /* my_socket_defined */ +#endif /* _global_h */ + +#include "mysql_version.h" +#include "mysql_com.h" +#include "mysql_time.h" + +#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */ + +extern unsigned int mysql_port; +extern char *mysql_unix_port; + +#define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */ +#define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */ + +#ifdef __NETWARE__ +#pragma pack(push, 8) /* 8 byte alignment */ +#endif + +#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG) +#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG) +#define IS_BLOB(n) ((n) & BLOB_FLAG) +#define IS_NUM(t) ((t) <= MYSQL_TYPE_INT24 || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) +#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG) +#define INTERNAL_NUM_FIELD(f) (((f)->type <= MYSQL_TYPE_INT24 && ((f)->type != MYSQL_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == MYSQL_TYPE_YEAR) +#define IS_LONGDATA(t) ((t) >= MYSQL_TYPE_TINY_BLOB && (t) <= MYSQL_TYPE_STRING) + + +typedef struct st_mysql_field { + char *name; /* Name of column */ + char *org_name; /* Original column name, if an alias */ + char *table; /* Table of column if column was a field */ + char *org_table; /* Org table name, if table was an alias */ + char *db; /* Database for table */ + char *catalog; /* Catalog for table */ + char *def; /* Default value (set by mysql_list_fields) */ + unsigned long length; /* Width of column (create length) */ + unsigned long max_length; /* Max width for selected set */ + unsigned int name_length; + unsigned int org_name_length; + unsigned int table_length; + unsigned int org_table_length; + unsigned int db_length; + unsigned int catalog_length; + unsigned int def_length; + unsigned int flags; /* Div flags */ + unsigned int decimals; /* Number of decimals in field */ + unsigned int charsetnr; /* Character set */ + enum enum_field_types type; /* Type of field. See mysql_com.h for types */ + void *extension; +} MYSQL_FIELD; + +typedef char **MYSQL_ROW; /* return data as array of strings */ +typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */ + +#ifndef _global_h +#if defined(NO_CLIENT_LONG_LONG) +typedef unsigned long my_ulonglong; +#elif defined (__WIN__) +typedef unsigned __int64 my_ulonglong; +#else +typedef unsigned long long my_ulonglong; +#endif +#endif + +#include "typelib.h" + +#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0) + +/* backward compatibility define - to be removed eventually */ +#define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED + +typedef struct st_mysql_rows { + struct st_mysql_rows *next; /* list of rows */ + MYSQL_ROW data; + unsigned long length; +} MYSQL_ROWS; + +typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ + +#include "my_alloc.h" + +typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; +typedef struct st_mysql_data { + MYSQL_ROWS *data; + struct embedded_query_result *embedded_info; + MEM_ROOT alloc; + my_ulonglong rows; + unsigned int fields; + /* extra info for embedded library */ + void *extension; +} MYSQL_DATA; + +enum mysql_option +{ + MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE, + MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, + MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE, + MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT, + MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT, + MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, + MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, + MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, + MYSQL_OPT_SSL_VERIFY_SERVER_CERT +}; + +struct st_mysql_options { + unsigned int connect_timeout, read_timeout, write_timeout; + unsigned int port, protocol; + unsigned long client_flag; + char *host,*user,*password,*unix_socket,*db; + struct st_dynamic_array *init_commands; + char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name; + char *ssl_key; /* PEM key file */ + char *ssl_cert; /* PEM cert file */ + char *ssl_ca; /* PEM CA file */ + char *ssl_capath; /* PEM directory of CA-s? */ + char *ssl_cipher; /* cipher to use */ + char *shared_memory_base_name; + unsigned long max_allowed_packet; + my_bool use_ssl; /* if to use SSL or not */ + my_bool compress,named_pipe; + /* + On connect, find out the replication role of the server, and + establish connections to all the peers + */ + my_bool rpl_probe; + /* + Each call to mysql_real_query() will parse it to tell if it is a read + or a write, and direct it to the slave or the master + */ + my_bool rpl_parse; + /* + If set, never read from a master, only from slave, when doing + a read that is replication-aware + */ + my_bool no_master_reads; +#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) + my_bool separate_thread; +#endif + enum mysql_option methods_to_use; + char *client_ip; + /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ + my_bool secure_auth; + /* 0 - never report, 1 - always report (default) */ + my_bool report_data_truncation; + + /* function pointers for local infile support */ + int (*local_infile_init)(void **, const char *, void *); + int (*local_infile_read)(void *, char *, unsigned int); + void (*local_infile_end)(void *); + int (*local_infile_error)(void *, char *, unsigned int); + void *local_infile_userdata; + void *extension; +}; + +enum mysql_status +{ + MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT, + MYSQL_STATUS_STATEMENT_GET_RESULT +}; + +enum mysql_protocol_type +{ + MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, + MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY +}; +/* + There are three types of queries - the ones that have to go to + the master, the ones that go to a slave, and the adminstrative + type which must happen on the pivot connectioin +*/ +enum mysql_rpl_type +{ + MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN +}; + +typedef struct character_set +{ + unsigned int number; /* character set number */ + unsigned int state; /* character set state */ + const char *csname; /* collation name */ + const char *name; /* character set name */ + const char *comment; /* comment */ + const char *dir; /* character set directory */ + unsigned int mbminlen; /* min. length for multibyte strings */ + unsigned int mbmaxlen; /* max. length for multibyte strings */ +} MY_CHARSET_INFO; + +struct st_mysql_methods; +struct st_mysql_stmt; + +typedef struct st_mysql +{ + NET net; /* Communication parameters */ + unsigned char *connector_fd; /* ConnectorFd for SSL */ + char *host,*user,*passwd,*unix_socket,*server_version,*host_info; + char *info, *db; + struct charset_info_st *charset; + MYSQL_FIELD *fields; + MEM_ROOT field_alloc; + my_ulonglong affected_rows; + my_ulonglong insert_id; /* id if insert on table with NEXTNR */ + my_ulonglong extra_info; /* Not used */ + unsigned long thread_id; /* Id for connection in server */ + unsigned long packet_length; + unsigned int port; + unsigned long client_flag,server_capabilities; + unsigned int protocol_version; + unsigned int field_count; + unsigned int server_status; + unsigned int server_language; + unsigned int warning_count; + struct st_mysql_options options; + enum mysql_status status; + my_bool free_me; /* If free in mysql_close */ + my_bool reconnect; /* set to 1 if automatic reconnect */ + + /* session-wide random string */ + char scramble[SCRAMBLE_LENGTH+1]; + + /* + Set if this is the original connection, not a master or a slave we have + added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() + */ + my_bool rpl_pivot; + /* + Pointers to the master, and the next slave connections, points to + itself if lone connection. + */ + struct st_mysql* master, *next_slave; + + struct st_mysql* last_used_slave; /* needed for round-robin slave pick */ + /* needed for send/read/store/use result to work correctly with replication */ + struct st_mysql* last_used_con; + + LIST *stmts; /* list of all statements */ + const struct st_mysql_methods *methods; + void *thd; + /* + Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag + from mysql_stmt_close if close had to cancel result set of this object. + */ + my_bool *unbuffered_fetch_owner; + /* needed for embedded server - no net buffer to store the 'info' */ + char *info_buffer; + void *extension; +} MYSQL; + + +typedef struct st_mysql_res { + my_ulonglong row_count; + MYSQL_FIELD *fields; + MYSQL_DATA *data; + MYSQL_ROWS *data_cursor; + unsigned long *lengths; /* column lengths of current row */ + MYSQL *handle; /* for unbuffered reads */ + const struct st_mysql_methods *methods; + MYSQL_ROW row; /* If unbuffered read */ + MYSQL_ROW current_row; /* buffer to current row */ + MEM_ROOT field_alloc; + unsigned int field_count, current_field; + my_bool eof; /* Used by mysql_fetch_row */ + /* mysql_stmt_close() had to cancel this result */ + my_bool unbuffered_fetch_cancelled; + void *extension; +} MYSQL_RES; + +#define MAX_MYSQL_MANAGER_ERR 256 +#define MAX_MYSQL_MANAGER_MSG 256 + +#define MANAGER_OK 200 +#define MANAGER_INFO 250 +#define MANAGER_ACCESS 401 +#define MANAGER_CLIENT_ERR 450 +#define MANAGER_INTERNAL_ERR 500 + +#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) +#define MYSQL_CLIENT +#endif + + +typedef struct st_mysql_manager +{ + NET net; + char *host, *user, *passwd; + char *net_buf, *net_buf_pos, *net_data_end; + unsigned int port; + int cmd_status; + int last_errno; + int net_buf_size; + my_bool free_me; + my_bool eof; + char last_error[MAX_MYSQL_MANAGER_ERR]; + void *extension; +} MYSQL_MANAGER; + +typedef struct st_mysql_parameters +{ + unsigned long *p_max_allowed_packet; + unsigned long *p_net_buffer_length; + void *extension; +} MYSQL_PARAMETERS; + +#if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) +#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) +#define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) +#endif + +/* + Set up and bring down the server; to ensure that applications will + work when linked against either the standard client library or the + embedded server library, these functions should be called. +*/ +int STDCALL mysql_server_init(int argc, char **argv, char **groups); +void STDCALL mysql_server_end(void); + +/* + mysql_server_init/end need to be called when using libmysqld or + libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so + you don't need to call it explicitely; but you need to call + mysql_server_end() to free memory). The names are a bit misleading + (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general + names which suit well whether you're using libmysqld or libmysqlclient. We + intend to promote these aliases over the mysql_server* ones. +*/ +#define mysql_library_init mysql_server_init +#define mysql_library_end mysql_server_end + +MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void); + +/* + Set up and bring down a thread; these function should be called + for each thread in an application which opens at least one MySQL + connection. All uses of the connection(s) should be between these + function calls. +*/ +my_bool STDCALL mysql_thread_init(void); +void STDCALL mysql_thread_end(void); + +/* + Functions to get information from the MYSQL and MYSQL_RES structures + Should definitely be used if one uses shared libraries. +*/ + +my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res); +unsigned int STDCALL mysql_num_fields(MYSQL_RES *res); +my_bool STDCALL mysql_eof(MYSQL_RES *res); +MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res, + unsigned int fieldnr); +MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res); +MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res); +MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res); + +unsigned int STDCALL mysql_field_count(MYSQL *mysql); +my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql); +my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql); +unsigned int STDCALL mysql_errno(MYSQL *mysql); +const char * STDCALL mysql_error(MYSQL *mysql); +const char *STDCALL mysql_sqlstate(MYSQL *mysql); +unsigned int STDCALL mysql_warning_count(MYSQL *mysql); +const char * STDCALL mysql_info(MYSQL *mysql); +unsigned long STDCALL mysql_thread_id(MYSQL *mysql); +const char * STDCALL mysql_character_set_name(MYSQL *mysql); +int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname); + +MYSQL * STDCALL mysql_init(MYSQL *mysql); +my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, + const char *cert, const char *ca, + const char *capath, const char *cipher); +const char * STDCALL mysql_get_ssl_cipher(MYSQL *mysql); +my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, + const char *passwd, const char *db); +MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, + const char *passwd, + const char *db, + unsigned int port, + const char *unix_socket, + unsigned long clientflag); +int STDCALL mysql_select_db(MYSQL *mysql, const char *db); +int STDCALL mysql_query(MYSQL *mysql, const char *q); +int STDCALL mysql_send_query(MYSQL *mysql, const char *q, + unsigned long length); +int STDCALL mysql_real_query(MYSQL *mysql, const char *q, + unsigned long length); +MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); + +/* perform query on master */ +my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, + unsigned long length); +my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, + unsigned long length); +/* perform query on slave */ +my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, + unsigned long length); +my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, + unsigned long length); +void STDCALL mysql_get_character_set_info(MYSQL *mysql, + MY_CHARSET_INFO *charset); + +/* local infile support */ + +#define LOCAL_INFILE_ERROR_LEN 512 + +void +mysql_set_local_infile_handler(MYSQL *mysql, + int (*local_infile_init)(void **, const char *, + void *), + int (*local_infile_read)(void *, char *, + unsigned int), + void (*local_infile_end)(void *), + int (*local_infile_error)(void *, char*, + unsigned int), + void *); + +void +mysql_set_local_infile_default(MYSQL *mysql); + + +/* + enable/disable parsing of all queries to decide if they go on master or + slave +*/ +void STDCALL mysql_enable_rpl_parse(MYSQL* mysql); +void STDCALL mysql_disable_rpl_parse(MYSQL* mysql); +/* get the value of the parse flag */ +int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql); + +/* enable/disable reads from master */ +void STDCALL mysql_enable_reads_from_master(MYSQL* mysql); +void STDCALL mysql_disable_reads_from_master(MYSQL* mysql); +/* get the value of the master read flag */ +my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql); + +enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len); + +/* discover the master and its slaves */ +my_bool STDCALL mysql_rpl_probe(MYSQL* mysql); + +/* set the master, close/free the old one, if it is not a pivot */ +int STDCALL mysql_set_master(MYSQL* mysql, const char* host, + unsigned int port, + const char* user, + const char* passwd); +int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, + unsigned int port, + const char* user, + const char* passwd); + +int STDCALL mysql_shutdown(MYSQL *mysql, + enum mysql_enum_shutdown_level + shutdown_level); +int STDCALL mysql_dump_debug_info(MYSQL *mysql); +int STDCALL mysql_refresh(MYSQL *mysql, + unsigned int refresh_options); +int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid); +int STDCALL mysql_set_server_option(MYSQL *mysql, + enum enum_mysql_set_option + option); +int STDCALL mysql_ping(MYSQL *mysql); +const char * STDCALL mysql_stat(MYSQL *mysql); +const char * STDCALL mysql_get_server_info(MYSQL *mysql); +const char * STDCALL mysql_get_client_info(void); +unsigned long STDCALL mysql_get_client_version(void); +const char * STDCALL mysql_get_host_info(MYSQL *mysql); +unsigned long STDCALL mysql_get_server_version(MYSQL *mysql); +unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql); +MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild); +MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild); +MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql); +int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option, + const void *arg); +void STDCALL mysql_free_result(MYSQL_RES *result); +void STDCALL mysql_data_seek(MYSQL_RES *result, + my_ulonglong offset); +MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, + MYSQL_ROW_OFFSET offset); +MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result, + MYSQL_FIELD_OFFSET offset); +MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); +unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); +MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); +MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, + const char *wild); +unsigned long STDCALL mysql_escape_string(char *to,const char *from, + unsigned long from_length); +unsigned long STDCALL mysql_hex_string(char *to,const char *from, + unsigned long from_length); +unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, + char *to,const char *from, + unsigned long length); +void STDCALL mysql_debug(const char *debug); +void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); +unsigned int STDCALL mysql_thread_safe(void); +my_bool STDCALL mysql_embedded(void); +MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con); +MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, + const char* host, + const char* user, + const char* passwd, + unsigned int port); +void STDCALL mysql_manager_close(MYSQL_MANAGER* con); +int STDCALL mysql_manager_command(MYSQL_MANAGER* con, + const char* cmd, int cmd_len); +int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, + char* res_buf, + int res_buf_size); +my_bool STDCALL mysql_read_query_result(MYSQL *mysql); + + +/* + The following definitions are added for the enhanced + client-server protocol +*/ + +/* statement state */ +enum enum_mysql_stmt_state +{ + MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE, + MYSQL_STMT_FETCH_DONE +}; + + +/* + This structure is used to define bind information, and + internally by the client library. + Public members with their descriptions are listed below + (conventionally `On input' refers to the binds given to + mysql_stmt_bind_param, `On output' refers to the binds given + to mysql_stmt_bind_result): + + buffer_type - One of the MYSQL_* types, used to describe + the host language type of buffer. + On output: if column type is different from + buffer_type, column value is automatically converted + to buffer_type before it is stored in the buffer. + buffer - On input: points to the buffer with input data. + On output: points to the buffer capable to store + output data. + The type of memory pointed by buffer must correspond + to buffer_type. See the correspondence table in + the comment to mysql_stmt_bind_param. + + The two above members are mandatory for any kind of bind. + + buffer_length - the length of the buffer. You don't have to set + it for any fixed length buffer: float, double, + int, etc. It must be set however for variable-length + types, such as BLOBs or STRINGs. + + length - On input: in case when lengths of input values + are different for each execute, you can set this to + point at a variable containining value length. This + way the value length can be different in each execute. + If length is not NULL, buffer_length is not used. + Note, length can even point at buffer_length if + you keep bind structures around while fetching: + this way you can change buffer_length before + each execution, everything will work ok. + On output: if length is set, mysql_stmt_fetch will + write column length into it. + + is_null - On input: points to a boolean variable that should + be set to TRUE for NULL values. + This member is useful only if your data may be + NULL in some but not all cases. + If your data is never NULL, is_null should be set to 0. + If your data is always NULL, set buffer_type + to MYSQL_TYPE_NULL, and is_null will not be used. + + is_unsigned - On input: used to signify that values provided for one + of numeric types are unsigned. + On output describes signedness of the output buffer. + If, taking into account is_unsigned flag, column data + is out of range of the output buffer, data for this column + is regarded truncated. Note that this has no correspondence + to the sign of result set column, if you need to find it out + use mysql_stmt_result_metadata. + error - where to write a truncation error if it is present. + possible error value is: + 0 no truncation + 1 value is out of range or buffer is too small + + Please note that MYSQL_BIND also has internals members. +*/ + +typedef struct st_mysql_bind +{ + unsigned long *length; /* output length pointer */ + my_bool *is_null; /* Pointer to null indicator */ + void *buffer; /* buffer to get/put data */ + /* set this if you want to track data truncations happened during fetch */ + my_bool *error; + unsigned char *row_ptr; /* for the current data position */ + void (*store_param_func)(NET *net, struct st_mysql_bind *param); + void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); + void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, + unsigned char **row); + /* output buffer length, must be set when fetching str/binary */ + unsigned long buffer_length; + unsigned long offset; /* offset position for char/binary fetch */ + unsigned long length_value; /* Used if length is 0 */ + unsigned int param_number; /* For null count and error messages */ + unsigned int pack_length; /* Internal length for packed data */ + enum enum_field_types buffer_type; /* buffer type */ + my_bool error_value; /* used if error is 0 */ + my_bool is_unsigned; /* set if integer type is unsigned */ + my_bool long_data_used; /* If used with mysql_send_long_data */ + my_bool is_null_value; /* Used if is_null is 0 */ + void *extension; +} MYSQL_BIND; + + +/* statement handler */ +typedef struct st_mysql_stmt +{ + MEM_ROOT mem_root; /* root allocations */ + LIST list; /* list to keep track of all stmts */ + MYSQL *mysql; /* connection handle */ + MYSQL_BIND *params; /* input parameters */ + MYSQL_BIND *bind; /* output parameters */ + MYSQL_FIELD *fields; /* result set metadata */ + MYSQL_DATA result; /* cached result set */ + MYSQL_ROWS *data_cursor; /* current row in cached result */ + /* + mysql_stmt_fetch() calls this function to fetch one row (it's different + for buffered, unbuffered and cursor fetch). + */ + int (*read_row_func)(struct st_mysql_stmt *stmt, + unsigned char **row); + /* copy of mysql->affected_rows after statement execution */ + my_ulonglong affected_rows; + my_ulonglong insert_id; /* copy of mysql->insert_id */ + unsigned long stmt_id; /* Id for prepared statement */ + unsigned long flags; /* i.e. type of cursor to open */ + unsigned long prefetch_rows; /* number of rows per one COM_FETCH */ + /* + Copied from mysql->server_status after execute/fetch to know + server-side cursor status for this statement. + */ + unsigned int server_status; + unsigned int last_errno; /* error code */ + unsigned int param_count; /* input parameter count */ + unsigned int field_count; /* number of columns in result set */ + enum enum_mysql_stmt_state state; /* statement state */ + char last_error[MYSQL_ERRMSG_SIZE]; /* error message */ + char sqlstate[SQLSTATE_LENGTH+1]; + /* Types of input parameters should be sent to server */ + my_bool send_types_to_server; + my_bool bind_param_done; /* input buffers were supplied */ + unsigned char bind_result_done; /* output buffers were supplied */ + /* mysql_stmt_close() had to cancel this result */ + my_bool unbuffered_fetch_cancelled; + /* + Is set to true if we need to calculate field->max_length for + metadata fields when doing mysql_stmt_store_result. + */ + my_bool update_max_length; + void *extension; +} MYSQL_STMT; + +enum enum_stmt_attr_type +{ + /* + When doing mysql_stmt_store_result calculate max_length attribute + of statement metadata. This is to be consistent with the old API, + where this was done automatically. + In the new API we do that only by request because it slows down + mysql_stmt_store_result sufficiently. + */ + STMT_ATTR_UPDATE_MAX_LENGTH, + /* + unsigned long with combination of cursor flags (read only, for update, + etc) + */ + STMT_ATTR_CURSOR_TYPE, + /* + Amount of rows to retrieve from server per one fetch if using cursors. + Accepts unsigned long attribute in the range 1 - ulong_max + */ + STMT_ATTR_PREFETCH_ROWS +}; + + +typedef struct st_mysql_methods +{ + my_bool (*read_query_result)(MYSQL *mysql); + my_bool (*advanced_command)(MYSQL *mysql, + enum enum_server_command command, + const unsigned char *header, + unsigned long header_length, + const unsigned char *arg, + unsigned long arg_length, + my_bool skip_check, + MYSQL_STMT *stmt); + MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, + unsigned int fields); + MYSQL_RES * (*use_result)(MYSQL *mysql); + void (*fetch_lengths)(unsigned long *to, + MYSQL_ROW column, unsigned int field_count); + void (*flush_use_result)(MYSQL *mysql); +#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) + MYSQL_FIELD * (*list_fields)(MYSQL *mysql); + my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); + int (*stmt_execute)(MYSQL_STMT *stmt); + int (*read_binary_rows)(MYSQL_STMT *stmt); + int (*unbuffered_fetch)(MYSQL *mysql, char **row); + void (*free_embedded_thd)(MYSQL *mysql); + const char *(*read_statistics)(MYSQL *mysql); + my_bool (*next_result)(MYSQL *mysql); + int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd); + int (*read_rows_from_cursor)(MYSQL_STMT *stmt); +#endif +} MYSQL_METHODS; + + +MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql); +int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, + unsigned long length); +int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt); +int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt); +int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, + unsigned int column, + unsigned long offset); +int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt); +unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt); +my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt, + enum enum_stmt_attr_type attr_type, + const void *attr); +my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, + enum enum_stmt_attr_type attr_type, + void *attr); +my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt); +my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt); +my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt); +my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, + unsigned int param_number, + const char *data, + unsigned long length); +MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt); +MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt); +unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt); +const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt); +const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt); +MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, + MYSQL_ROW_OFFSET offset); +MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt); +void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset); +my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt); +my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt); +my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt); +unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt); + +my_bool STDCALL mysql_commit(MYSQL * mysql); +my_bool STDCALL mysql_rollback(MYSQL * mysql); +my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode); +my_bool STDCALL mysql_more_results(MYSQL *mysql); +int STDCALL mysql_next_result(MYSQL *mysql); +void STDCALL mysql_close(MYSQL *sock); + + +/* status return codes */ +#define MYSQL_NO_DATA 100 +#define MYSQL_DATA_TRUNCATED 101 + +#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) + +#ifdef USE_OLD_FUNCTIONS +MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, + const char *user, const char *passwd); +int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); +int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); +#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) +#endif +#define HAVE_MYSQL_REAL_CONNECT + +/* + The following functions are mainly exported because of mysqlbinlog; + They are not for general usage +*/ + +#define simple_command(mysql, command, arg, length, skip_check) \ + (*(mysql)->methods->advanced_command)(mysql, command, 0, \ + 0, arg, length, skip_check, NULL) +#define stmt_command(mysql, command, arg, length, stmt) \ + (*(mysql)->methods->advanced_command)(mysql, command, 0, \ + 0, arg, length, 1, stmt) + +#ifdef __NETWARE__ +#pragma pack(pop) /* restore alignment */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _mysql_h */ diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_com.h b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_com.h new file mode 100644 index 00000000..357519d5 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_com.h @@ -0,0 +1,532 @@ +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* +** Common definition between mysql server & client +*/ + +#ifndef _mysql_com_h +#define _mysql_com_h + +#define HOSTNAME_LENGTH 60 +#define SYSTEM_CHARSET_MBMAXLEN 3 +#define NAME_CHAR_LEN 64 /* Field/table name length */ +#define USERNAME_CHAR_LENGTH 16 +#define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) +#define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN) + +#define SERVER_VERSION_LENGTH 60 +#define SQLSTATE_LENGTH 5 + +/* + USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain + username and hostname parts of the user identifier with trailing zero in + MySQL standard format: + user_name_part@host_name_part\0 +*/ +#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 + +#define LOCAL_HOST "localhost" +#define LOCAL_HOST_NAMEDPIPE "." + + +#if defined(__WIN__) && !defined( _CUSTOMCONFIG_) +#define MYSQL_NAMEDPIPE "MySQL" +#define MYSQL_SERVICENAME "MySQL" +#endif /* __WIN__ */ + +/* + You should add new commands to the end of this list, otherwise old + servers won't be able to handle them as 'unsupported'. +*/ + +enum enum_server_command +{ + COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST, + COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS, + COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING, + COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP, + COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, + COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, + COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, + /* don't forget to update const char *command_name[] in sql_parse.cc */ + + /* Must be last */ + COM_END +}; + + +/* + Length of random string sent by server on handshake; this is also length of + obfuscated password, recieved from client +*/ +#define SCRAMBLE_LENGTH 20 +#define SCRAMBLE_LENGTH_323 8 +/* length of password stored in the db: new passwords are preceeded with '*' */ +#define SCRAMBLED_PASSWORD_CHAR_LENGTH (SCRAMBLE_LENGTH*2+1) +#define SCRAMBLED_PASSWORD_CHAR_LENGTH_323 (SCRAMBLE_LENGTH_323*2) + + +#define NOT_NULL_FLAG 1 /* Field can't be NULL */ +#define PRI_KEY_FLAG 2 /* Field is part of a primary key */ +#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */ +#define MULTIPLE_KEY_FLAG 8 /* Field is part of a key */ +#define BLOB_FLAG 16 /* Field is a blob */ +#define UNSIGNED_FLAG 32 /* Field is unsigned */ +#define ZEROFILL_FLAG 64 /* Field is zerofill */ +#define BINARY_FLAG 128 /* Field is binary */ + +/* The following are only sent to new clients */ +#define ENUM_FLAG 256 /* field is an enum */ +#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */ +#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */ +#define SET_FLAG 2048 /* field is a set */ +#define NO_DEFAULT_VALUE_FLAG 4096 /* Field doesn't have default value */ +#define ON_UPDATE_NOW_FLAG 8192 /* Field is set to NOW on UPDATE */ +#define NUM_FLAG 32768 /* Field is num (for clients) */ +#define PART_KEY_FLAG 16384 /* Intern; Part of some key */ +#define GROUP_FLAG 32768 /* Intern: Group field */ +#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */ +#define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */ +#define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */ +#define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ +#define FIELD_IN_ADD_INDEX (1<< 20) /* Intern: Field used in ADD INDEX */ +#define FIELD_IS_RENAMED (1<< 21) /* Intern: Field is being renamed */ + +#define REFRESH_GRANT 1 /* Refresh grant tables */ +#define REFRESH_LOG 2 /* Start on new log file */ +#define REFRESH_TABLES 4 /* close all tables */ +#define REFRESH_HOSTS 8 /* Flush host cache */ +#define REFRESH_STATUS 16 /* Flush status variables */ +#define REFRESH_THREADS 32 /* Flush thread cache */ +#define REFRESH_SLAVE 64 /* Reset master info and restart slave + thread */ +#define REFRESH_MASTER 128 /* Remove all bin logs in the index + and truncate the index */ + +/* The following can't be set with mysql_refresh() */ +#define REFRESH_READ_LOCK 16384 /* Lock tables for read */ +#define REFRESH_FAST 32768 /* Intern flag */ + +/* RESET (remove all queries) from query cache */ +#define REFRESH_QUERY_CACHE 65536 +#define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ +#define REFRESH_DES_KEY_FILE 0x40000L +#define REFRESH_USER_RESOURCES 0x80000L + +#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ +#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ +#define CLIENT_LONG_FLAG 4 /* Get all column flags */ +#define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ +#define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */ +#define CLIENT_COMPRESS 32 /* Can use compression protocol */ +#define CLIENT_ODBC 64 /* Odbc client */ +#define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */ +#define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ +#define CLIENT_PROTOCOL_41 512 /* New 4.1 protocol */ +#define CLIENT_INTERACTIVE 1024 /* This is an interactive client */ +#define CLIENT_SSL 2048 /* Switch to SSL after handshake */ +#define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ +#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ +#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */ +#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ +#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ +#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ + +#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) +#define CLIENT_REMEMBER_OPTIONS (1UL << 31) + +/* Gather all possible capabilites (flags) supported by the server */ +#define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \ + CLIENT_FOUND_ROWS | \ + CLIENT_LONG_FLAG | \ + CLIENT_CONNECT_WITH_DB | \ + CLIENT_NO_SCHEMA | \ + CLIENT_COMPRESS | \ + CLIENT_ODBC | \ + CLIENT_LOCAL_FILES | \ + CLIENT_IGNORE_SPACE | \ + CLIENT_PROTOCOL_41 | \ + CLIENT_INTERACTIVE | \ + CLIENT_SSL | \ + CLIENT_IGNORE_SIGPIPE | \ + CLIENT_TRANSACTIONS | \ + CLIENT_RESERVED | \ + CLIENT_SECURE_CONNECTION | \ + CLIENT_MULTI_STATEMENTS | \ + CLIENT_MULTI_RESULTS | \ + CLIENT_SSL_VERIFY_SERVER_CERT | \ + CLIENT_REMEMBER_OPTIONS) + +/* + Switch off the flags that are optional and depending on build flags + If any of the optional flags is supported by the build it will be switched + on before sending to the client during the connection handshake. +*/ +#define CLIENT_BASIC_FLAGS (((CLIENT_ALL_FLAGS & ~CLIENT_SSL) \ + & ~CLIENT_COMPRESS) \ + & ~CLIENT_SSL_VERIFY_SERVER_CERT) + +#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ +#define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ +#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ +#define SERVER_QUERY_NO_GOOD_INDEX_USED 16 +#define SERVER_QUERY_NO_INDEX_USED 32 +/** + The server was able to fulfill the clients request and opened a + read-only non-scrollable cursor for a query. This flag comes + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. +*/ +#define SERVER_STATUS_CURSOR_EXISTS 64 +/** + This flag is sent when a read-only cursor is exhausted, in reply to + COM_STMT_FETCH command. +*/ +#define SERVER_STATUS_LAST_ROW_SENT 128 +#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */ +#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512 +/** + Sent to the client if after a prepared statement reprepare + we discovered that the new statement returns a different + number of result set columns. +*/ +#define SERVER_STATUS_METADATA_CHANGED 1024 + +/** + Server status flags that must be cleared when starting + execution of a new SQL statement. + Flags from this set are only added to the + current server status by the execution engine, but + never removed -- the execution engine expects them + to disappear automagically by the next command. +*/ +#define SERVER_STATUS_CLEAR_SET (SERVER_QUERY_NO_GOOD_INDEX_USED| \ + SERVER_QUERY_NO_INDEX_USED|\ + SERVER_MORE_RESULTS_EXISTS|\ + SERVER_STATUS_METADATA_CHANGED) + +#define MYSQL_ERRMSG_SIZE 512 +#define NET_READ_TIMEOUT 30 /* Timeout on read */ +#define NET_WRITE_TIMEOUT 60 /* Timeout on write */ +#define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ + +#define ONLY_KILL_QUERY 1 + + +struct st_vio; /* Only C */ +typedef struct st_vio Vio; + +#define MAX_TINYINT_WIDTH 3 /* Max width for a TINY w.o. sign */ +#define MAX_SMALLINT_WIDTH 5 /* Max width for a SHORT w.o. sign */ +#define MAX_MEDIUMINT_WIDTH 8 /* Max width for a INT24 w.o. sign */ +#define MAX_INT_WIDTH 10 /* Max width for a LONG w.o. sign */ +#define MAX_BIGINT_WIDTH 20 /* Max width for a LONGLONG */ +#define MAX_CHAR_WIDTH 255 /* Max length for a CHAR colum */ +#define MAX_BLOB_WIDTH 16777216 /* Default width for blob */ + +typedef struct st_net { +#if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY) + Vio *vio; + unsigned char *buff,*buff_end,*write_pos,*read_pos; + my_socket fd; /* For Perl DBI/dbd */ + /* + The following variable is set if we are doing several queries in one + command ( as in LOAD TABLE ... FROM MASTER ), + and do not want to confuse the client with OK at the wrong time + */ + unsigned long remain_in_buf,length, buf_length, where_b; + unsigned long max_packet,max_packet_size; + unsigned int pkt_nr,compress_pkt_nr; + unsigned int write_timeout, read_timeout, retry_count; + int fcntl; + unsigned int *return_status; + unsigned char reading_or_writing; + char save_char; + my_bool unused0; /* Please remove with the next incompatible ABI change. */ + my_bool unused; /* Please remove with the next incompatible ABI change */ + my_bool compress; + my_bool unused1; /* Please remove with the next incompatible ABI change. */ + /* + Pointer to query object in query cache, do not equal NULL (0) for + queries in cache that have not stored its results yet + */ +#endif + /* + 'query_cache_query' should be accessed only via query cache + functions and methods to maintain proper locking. + */ + unsigned char *query_cache_query; + unsigned int last_errno; + unsigned char error; + my_bool unused2; /* Please remove with the next incompatible ABI change. */ + my_bool return_errno; + /** Client library error message buffer. Actually belongs to struct MYSQL. */ + char last_error[MYSQL_ERRMSG_SIZE]; + /** Client library sqlstate buffer. Set along with the error message. */ + char sqlstate[SQLSTATE_LENGTH+1]; + void *extension; +#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) + /* + Controls whether a big packet should be skipped. + + Initially set to FALSE by default. Unauthenticated sessions must have + this set to FALSE so that the server can't be tricked to read packets + indefinitely. + */ + my_bool skip_big_packet; +#endif +} NET; + + +#define packet_error (~(unsigned long) 0) + +enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, + MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, + MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, + MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, + MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24, + MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, + MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, + MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, + MYSQL_TYPE_BIT, + MYSQL_TYPE_NEWDECIMAL=246, + MYSQL_TYPE_ENUM=247, + MYSQL_TYPE_SET=248, + MYSQL_TYPE_TINY_BLOB=249, + MYSQL_TYPE_MEDIUM_BLOB=250, + MYSQL_TYPE_LONG_BLOB=251, + MYSQL_TYPE_BLOB=252, + MYSQL_TYPE_VAR_STRING=253, + MYSQL_TYPE_STRING=254, + MYSQL_TYPE_GEOMETRY=255 + +}; + +/* For backward compatibility */ +#define CLIENT_MULTI_QUERIES CLIENT_MULTI_STATEMENTS +#define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL +#define FIELD_TYPE_NEWDECIMAL MYSQL_TYPE_NEWDECIMAL +#define FIELD_TYPE_TINY MYSQL_TYPE_TINY +#define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT +#define FIELD_TYPE_LONG MYSQL_TYPE_LONG +#define FIELD_TYPE_FLOAT MYSQL_TYPE_FLOAT +#define FIELD_TYPE_DOUBLE MYSQL_TYPE_DOUBLE +#define FIELD_TYPE_NULL MYSQL_TYPE_NULL +#define FIELD_TYPE_TIMESTAMP MYSQL_TYPE_TIMESTAMP +#define FIELD_TYPE_LONGLONG MYSQL_TYPE_LONGLONG +#define FIELD_TYPE_INT24 MYSQL_TYPE_INT24 +#define FIELD_TYPE_DATE MYSQL_TYPE_DATE +#define FIELD_TYPE_TIME MYSQL_TYPE_TIME +#define FIELD_TYPE_DATETIME MYSQL_TYPE_DATETIME +#define FIELD_TYPE_YEAR MYSQL_TYPE_YEAR +#define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE +#define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM +#define FIELD_TYPE_SET MYSQL_TYPE_SET +#define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB +#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB +#define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB +#define FIELD_TYPE_BLOB MYSQL_TYPE_BLOB +#define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING +#define FIELD_TYPE_STRING MYSQL_TYPE_STRING +#define FIELD_TYPE_CHAR MYSQL_TYPE_TINY +#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM +#define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY +#define FIELD_TYPE_BIT MYSQL_TYPE_BIT + + +/* Shutdown/kill enums and constants */ + +/* Bits for THD::killable. */ +#define MYSQL_SHUTDOWN_KILLABLE_CONNECT (unsigned char)(1 << 0) +#define MYSQL_SHUTDOWN_KILLABLE_TRANS (unsigned char)(1 << 1) +#define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) +#define MYSQL_SHUTDOWN_KILLABLE_UPDATE (unsigned char)(1 << 3) + +enum mysql_enum_shutdown_level { + /* + We want levels to be in growing order of hardness (because we use number + comparisons). Note that DEFAULT does not respect the growing property, but + it's ok. + */ + SHUTDOWN_DEFAULT = 0, + /* wait for existing connections to finish */ + SHUTDOWN_WAIT_CONNECTIONS= MYSQL_SHUTDOWN_KILLABLE_CONNECT, + /* wait for existing trans to finish */ + SHUTDOWN_WAIT_TRANSACTIONS= MYSQL_SHUTDOWN_KILLABLE_TRANS, + /* wait for existing updates to finish (=> no partial MyISAM update) */ + SHUTDOWN_WAIT_UPDATES= MYSQL_SHUTDOWN_KILLABLE_UPDATE, + /* flush InnoDB buffers and other storage engines' buffers*/ + SHUTDOWN_WAIT_ALL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1), + /* don't flush InnoDB buffers, flush other storage engines' buffers*/ + SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1, + /* Now the 2 levels of the KILL command */ +#if MYSQL_VERSION_ID >= 50000 + KILL_QUERY= 254, +#endif + KILL_CONNECTION= 255 +}; + + +enum enum_cursor_type +{ + CURSOR_TYPE_NO_CURSOR= 0, + CURSOR_TYPE_READ_ONLY= 1, + CURSOR_TYPE_FOR_UPDATE= 2, + CURSOR_TYPE_SCROLLABLE= 4 +}; + + +/* options for mysql_set_option */ +enum enum_mysql_set_option +{ + MYSQL_OPTION_MULTI_STATEMENTS_ON, + MYSQL_OPTION_MULTI_STATEMENTS_OFF +}; + +#define net_new_transaction(net) ((net)->pkt_nr=0) + +#ifdef __cplusplus +extern "C" { +#endif + +my_bool my_net_init(NET *net, Vio* vio); +void my_net_local_init(NET *net); +void net_end(NET *net); + void net_clear(NET *net, my_bool clear_buffer); +my_bool net_realloc(NET *net, size_t length); +my_bool net_flush(NET *net); +my_bool my_net_write(NET *net,const unsigned char *packet, size_t len); +my_bool net_write_command(NET *net,unsigned char command, + const unsigned char *header, size_t head_len, + const unsigned char *packet, size_t len); +int net_real_write(NET *net,const unsigned char *packet, size_t len); +unsigned long my_net_read(NET *net); + +#ifdef _global_h +void my_net_set_write_timeout(NET *net, uint timeout); +void my_net_set_read_timeout(NET *net, uint timeout); +#endif + +/* + The following function is not meant for normal usage + Currently it's used internally by manager.c +*/ +struct sockaddr; +int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, + unsigned int timeout); + +struct rand_struct { + unsigned long seed1,seed2,max_value; + double max_value_dbl; +}; + +#ifdef __cplusplus +} +#endif + + /* The following is for user defined functions */ + +enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, + DECIMAL_RESULT}; + +typedef struct st_udf_args +{ + unsigned int arg_count; /* Number of arguments */ + enum Item_result *arg_type; /* Pointer to item_results */ + char **args; /* Pointer to argument */ + unsigned long *lengths; /* Length of string arguments */ + char *maybe_null; /* Set to 1 for all maybe_null args */ + char **attributes; /* Pointer to attribute name */ + unsigned long *attribute_lengths; /* Length of attribute arguments */ + void *extension; +} UDF_ARGS; + + /* This holds information about the result */ + +typedef struct st_udf_init +{ + my_bool maybe_null; /* 1 if function can return NULL */ + unsigned int decimals; /* for real functions */ + unsigned long max_length; /* For string functions */ + char *ptr; /* free pointer for function data */ + my_bool const_item; /* 1 if function always returns the same value */ + void *extension; +} UDF_INIT; +/* + TODO: add a notion for determinism of the UDF. + See Item_udf_func::update_used_tables () +*/ + + /* Constants when using compression */ +#define NET_HEADER_SIZE 4 /* standard header size */ +#define COMP_HEADER_SIZE 3 /* compression header extra size */ + + /* Prototypes to password functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + These functions are used for authentication by client and server and + implemented in sql/password.c +*/ + +void randominit(struct rand_struct *, unsigned long seed1, + unsigned long seed2); +double my_rnd(struct rand_struct *); +void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st); + +void hash_password(unsigned long *to, const char *password, unsigned int password_len); +void make_scrambled_password_323(char *to, const char *password); +void scramble_323(char *to, const char *message, const char *password); +my_bool check_scramble_323(const char *, const char *message, + unsigned long *salt); +void get_salt_from_password_323(unsigned long *res, const char *password); +void make_password_from_salt_323(char *to, const unsigned long *salt); + +void make_scrambled_password(char *to, const char *password); +void scramble(char *to, const char *message, const char *password); +my_bool check_scramble(const char *reply, const char *message, + const unsigned char *hash_stage2); +void get_salt_from_password(unsigned char *res, const char *password); +void make_password_from_salt(char *to, const unsigned char *hash_stage2); +char *octet2hex(char *to, const char *str, unsigned int len); + +/* end of password.c */ + +char *get_tty_password(const char *opt_message); +const char *mysql_errno_to_sqlstate(unsigned int mysql_errno); + +/* Some other useful functions */ + +my_bool my_thread_init(void); +void my_thread_end(void); + +#ifdef _global_h +ulong STDCALL net_field_length(uchar **packet); +my_ulonglong net_field_length_ll(uchar **packet); +uchar *net_store_length(uchar *pkg, ulonglong length); +#endif + +#ifdef __cplusplus +} +#endif + +#define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ +#define MYSQL_STMT_HEADER 4 +#define MYSQL_LONG_DATA_HEADER 6 + +#endif diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_embed.h b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_embed.h new file mode 100644 index 00000000..a7d6e610 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_embed.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2000 MySQL AB + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Defines that are unique to the embedded version of MySQL */ + +#ifdef EMBEDDED_LIBRARY + +/* Things we don't need in the embedded version of MySQL */ +/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */ + +#undef HAVE_OPENSSL +#undef HAVE_SMEM /* No shared memory */ +#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */ + +#define DONT_USE_RAID + +#endif /* EMBEDDED_LIBRARY */ diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_time.h b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_time.h new file mode 100644 index 00000000..0a3f17a8 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_time.h @@ -0,0 +1,55 @@ +/* Copyright (C) 2004 MySQL AB + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _mysql_time_h_ +#define _mysql_time_h_ + +/* + Time declarations shared between the server and client API: + you should not add anything to this header unless it's used + (and hence should be visible) in mysql.h. + If you're looking for a place to add new time-related declaration, + it's most likely my_time.h. See also "C API Handling of Date + and Time Values" chapter in documentation. +*/ + +enum enum_mysql_timestamp_type +{ + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2 +}; + + +/* + Structure which is used to represent datetime values inside MySQL. + + We assume that values in this structure are normalized, i.e. year <= 9999, + month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions + in server such as my_system_gmt_sec() or make_time() family of functions + rely on this (actually now usage of make_*() family relies on a bit weaker + restriction). Also functions that produce MYSQL_TIME as result ensure this. + There is one exception to this rule though if this structure holds time + value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold + bigger values. +*/ +typedef struct st_mysql_time +{ + unsigned int year, month, day, hour, minute, second; + unsigned long second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; +} MYSQL_TIME; + +#endif /* _mysql_time_h_ */ diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_version.h b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_version.h new file mode 100644 index 00000000..1eba2ede --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/mysql_version.h @@ -0,0 +1,30 @@ +/* Copyright Abandoned 1996, 1999, 2001 MySQL AB + This file is public domain and comes with NO WARRANTY of any kind */ + +/* Version numbers for protocol & mysqld */ + +#ifndef _mysql_version_h +#define _mysql_version_h +#ifdef _CUSTOMCONFIG_ +#include +#else +#define PROTOCOL_VERSION 10 +#define MYSQL_SERVER_VERSION "5.1.57" +#define MYSQL_BASE_VERSION "mysqld-5.1" +#define MYSQL_SERVER_SUFFIX_DEF "" +#define FRM_VER 6 +#define MYSQL_VERSION_ID 50157 +#define MYSQL_PORT 3306 +#define MYSQL_PORT_DEFAULT 0 +#define MYSQL_UNIX_ADDR "/tmp/mysql.sock" +#define MYSQL_CONFIG_NAME "my" +#define MYSQL_COMPILATION_COMMENT "Source distribution" + +/* mysqld compile time options */ +#endif /* _CUSTOMCONFIG_ */ + +#ifndef LICENSE +#define LICENSE GPL +#endif /* LICENSE */ + +#endif /* _mysql_version_h */ diff --git a/Frameworks/MCPKit.framework/Versions/A/Headers/typelib.h b/Frameworks/MCPKit.framework/Versions/A/Headers/typelib.h new file mode 100644 index 00000000..46106d1b --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Headers/typelib.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2000 MySQL AB + + 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; version 2 of the License. + + 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +#ifndef _typelib_h +#define _typelib_h + +#include "my_alloc.h" + +typedef struct st_typelib { /* Different types saved here */ + unsigned int count; /* How many types */ + const char *name; /* Name of typelib */ + const char **type_names; + unsigned int *type_lengths; +} TYPELIB; + +extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position); +extern int find_type_or_exit(const char *x, TYPELIB *typelib, + const char *option); +extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name); +extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); +extern const char *get_type(TYPELIB *typelib,unsigned int nr); +extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); + +extern TYPELIB sql_protocol_typelib; + +#endif /* _typelib_h */ diff --git a/Frameworks/MCPKit.framework/Versions/A/MCPKit b/Frameworks/MCPKit.framework/Versions/A/MCPKit new file mode 100755 index 00000000..3d7b4a2f Binary files /dev/null and b/Frameworks/MCPKit.framework/Versions/A/MCPKit differ diff --git a/Frameworks/MCPKit.framework/Versions/A/Resources/Info.plist b/Frameworks/MCPKit.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..893f6c38 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,38 @@ + + + + + BuildMachineOSBuild + 10K540 + CFBundleDevelopmentRegion + English + CFBundleExecutable + MCPKit + CFBundleIdentifier + com.google.code.sequel-pro.mcpkit + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 4C114 + DTPlatformVersion + GM + DTSDKBuild + 10K540 + DTSDKName + + DTXcode + 0420 + DTXcodeBuild + 4C114 + + diff --git a/Frameworks/MCPKit.framework/Versions/Current b/Frameworks/MCPKit.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/Frameworks/MCPKit.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Frameworks/RegexKit.framework/Headers b/Frameworks/RegexKit.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/Frameworks/RegexKit.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Frameworks/RegexKit.framework/RegexKit b/Frameworks/RegexKit.framework/RegexKit new file mode 120000 index 00000000..2b831b2e --- /dev/null +++ b/Frameworks/RegexKit.framework/RegexKit @@ -0,0 +1 @@ +Versions/Current/RegexKit \ No newline at end of file diff --git a/Frameworks/RegexKit.framework/Resources b/Frameworks/RegexKit.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/Frameworks/RegexKit.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/NSArray.h b/Frameworks/RegexKit.framework/Versions/A/Headers/NSArray.h new file mode 100644 index 00000000..fcf533ac --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/NSArray.h @@ -0,0 +1,74 @@ +// +// NSArray.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_NSARRAY_H_ +#define _REGEXKIT_NSARRAY_H_ 1 + +#import +#import + +@interface NSArray (RegexKitAdditions) +-(NSArray *)arrayByMatchingObjectsWithRegex:(id)aRegex; +-(NSArray *)arrayByMatchingObjectsWithRegex:(id)aRegex inRange:(const NSRange)range; +-(BOOL)containsObjectMatchingRegex:(id)aRegex; +-(BOOL)containsObjectMatchingRegex:(id)aRegex inRange:(const NSRange)range; +-(RKUInteger)countOfObjectsMatchingRegex:(id)aRegex; +-(RKUInteger)countOfObjectsMatchingRegex:(id)aRegex inRange:(const NSRange)range; +-(RKUInteger)indexOfObjectMatchingRegex:(id)aRegex; +-(RKUInteger)indexOfObjectMatchingRegex:(id)aRegex inRange:(const NSRange)range; +-(NSIndexSet *)indexSetOfObjectsMatchingRegex:(id)aRegex; +-(NSIndexSet *)indexSetOfObjectsMatchingRegex:(id)aRegex inRange:(const NSRange)range; + +@end + + @interface NSMutableArray (RegexKitAdditions) +- (void)addObjectsFromArray:(NSArray *)otherArray matchingRegex:(id)aRegex; +-(void)removeObjectsMatchingRegex:(id)aRegex; +-(void)removeObjectsMatchingRegex:(id)aRegex inRange:(const NSRange)range; + +@end + +#endif // _REGEXKIT_NSARRAY_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/NSData.h b/Frameworks/RegexKit.framework/Versions/A/Headers/NSData.h new file mode 100644 index 00000000..81dec475 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/NSData.h @@ -0,0 +1,66 @@ +// +// NSData.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_NSDATA_H_ +#define _REGEXKIT_NSDATA_H_ 1 + +#import +#import +#import + +@interface NSData (RegexKitAdditions) +- (BOOL)isMatchedByRegex:(id)aRegex; +- (BOOL)isMatchedByRegex:(id)aRegex inRange:(const NSRange)range; +- (NSRange)rangeOfRegex:(id)aRegex; +- (NSRange)rangeOfRegex:(id)aRegex inRange:(const NSRange)range capture:(const RKUInteger)capture; +- (NSRange *)rangesOfRegex:(id)aRegex; +- (NSRange *)rangesOfRegex:(id)aRegex inRange:(const NSRange)range; +- (NSData *)subdataByMatching:(id)aRegex; +- (NSData *)subdataByMatching:(id)aRegex inRange:(const NSRange)range; + +@end + +#endif // _REGEXKIT_NSDATA_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/NSDictionary.h b/Frameworks/RegexKit.framework/Versions/A/Headers/NSDictionary.h new file mode 100644 index 00000000..10044363 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/NSDictionary.h @@ -0,0 +1,74 @@ +// +// NSDictionary.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_NSDICTIONARY_H_ +#define _REGEXKIT_NSDICTIONARY_H_ 1 + +#import +#import + + @interface NSDictionary (RegexKitAdditions) +- (NSDictionary *)dictionaryByMatchingKeysWithRegex:(id)aRegex; +- (NSDictionary *)dictionaryByMatchingObjectsWithRegex:(id)aRegex; +- (BOOL)containsKeyMatchingRegex:(id)aRegex; +- (BOOL)containsObjectMatchingRegex:(id)aRegex; +- (NSArray *)keysMatchingRegex:(id)aRegex; +- (NSArray *)keysForObjectsMatchingRegex:(id)aRegex; +- (NSArray *)objectsForKeysMatchingRegex:(id)aRegex; +- (NSArray *)objectsMatchingRegex:(id)regexObject; + + @end + + @interface NSMutableDictionary (RegexKitAdditions) +- (void)addEntriesFromDictionary:(id)otherDictionary withKeysMatchingRegex:(id)aRegex; +- (void)addEntriesFromDictionary:(id)otherDictionary withObjectsMatchingRegex:(id)aRegex; +- (void)removeObjectsMatchingRegex:(id)aRegex; +- (void)removeObjectsForKeysMatchingRegex:(id)aRegex; + + +@end + +#endif // _REGEXKIT_NSDICTIONARY_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/NSObject.h b/Frameworks/RegexKit.framework/Versions/A/Headers/NSObject.h new file mode 100644 index 00000000..70b26573 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/NSObject.h @@ -0,0 +1,68 @@ +// +// NSObject.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_NSOBJECT_H_ +#define _REGEXKIT_NSOBJECT_H_ 1 + +#import +#import + +@interface NSObject (RegexKitAdditions) +- (BOOL)isMatchedByRegex:(id)aRegex; +- (BOOL)isMatchedByAnyRegexInArray:(NSArray *)regexArray; +- (RKRegex *)anyMatchingRegexInArray:(NSArray *)regexArray; +- (RKRegex *)firstMatchingRegexInArray:(NSArray *)regexArray; +- (BOOL)isMatchedByAnyRegexInArray:(NSArray *)regexArray library:(NSString *)library options:(RKCompileOption)libraryOptions error:(NSError **)error; +- (RKRegex *)anyMatchingRegexInArray:(NSArray *)regexArray library:(NSString *)library options:(RKCompileOption)libraryOptions error:(NSError **)error; +- (RKRegex *)firstMatchingRegexInArray:(NSArray *)regexArray library:(NSString *)library options:(RKCompileOption)libraryOptions error:(NSError **)error; +- (BOOL)isMatchedByAnyRegexInSet:(NSSet *)regexSet; +- (RKRegex *)anyMatchingRegexInSet:(NSSet *)regexSet; +- (BOOL)isMatchedByAnyRegexInSet:(NSSet *)regexSet library:(NSString *)library options:(RKCompileOption)libraryOptions error:(NSError **)error; +- (RKRegex *)anyMatchingRegexInSet:(NSSet *)regexSet library:(NSString *)library options:(RKCompileOption)libraryOptions error:(NSError **)error; + +@end + +#endif // _REGEXKIT_NSOBJECT_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/NSSet.h b/Frameworks/RegexKit.framework/Versions/A/Headers/NSSet.h new file mode 100644 index 00000000..f4cdf8fa --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/NSSet.h @@ -0,0 +1,70 @@ +// +// NSSet.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_NSSET_H_ +#define _REGEXKIT_NSSET_H_ 1 + +#import +#import +#import + + @interface NSSet (RegexKitAdditions) +-(id)anyObjectMatchingRegex:(id)aRegex; +-(BOOL)containsObjectMatchingRegex:(id)aRegex; +-(RKUInteger)countOfObjectsMatchingRegex:(id)aRegex; +-(NSSet *)setByMatchingObjectsWithRegex:(id)aRegex; + + +@end + + @interface NSMutableSet (RegexKitAdditions) +-(void)removeObjectsMatchingRegex:(id)aRegex; +- (void)addObjectsFromArray:(NSArray *)otherArray matchingRegex:(id)aRegex; +- (void)addObjectsFromSet:(NSSet *)otherSet matchingRegex:(id)aRegex; + +@end + +#endif // _REGEXKIT_NSSET_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/NSString.h b/Frameworks/RegexKit.framework/Versions/A/Headers/NSString.h new file mode 100644 index 00000000..9a343b45 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/NSString.h @@ -0,0 +1,103 @@ +// +// NSString.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_NSSTRING_H_ +#define _REGEXKIT_NSSTRING_H_ 1 + +#import +#import +#import +REGEXKIT_EXTERN NSRange RKConvertUTF8ToUTF16RangeForString(NSString *string, NSRange range); +REGEXKIT_EXTERN NSRange RKConvertUTF16ToUTF8RangeForString(NSString *string, NSRange range); + +@interface NSString (RegexKitAdditions) +- (BOOL)getCapturesWithRegexAndReferences:(id)aRegex, ... RK_REQUIRES_NIL_TERMINATION; +- (BOOL)getCapturesWithRegex:(id)aRegex inRange:(const NSRange)range references:(NSString * const)firstReference, ... RK_REQUIRES_NIL_TERMINATION; +- (NSRange *)rangesOfRegex:(id)aRegex; +- (NSRange *)rangesOfRegex:(id)aRegex inRange:(const NSRange)range; +- (NSRange)rangeOfRegex:(id)aRegex; +- (NSRange)rangeOfRegex:(id)aRegex inRange:(const NSRange)range capture:(const RKUInteger)capture; +- (BOOL)isMatchedByRegex:(id)aRegex; +- (BOOL)isMatchedByRegex:(id)aRegex inRange:(const NSRange)range; +- (RKEnumerator *)matchEnumeratorWithRegex:(id)aRegex; +- (RKEnumerator *)matchEnumeratorWithRegex:(id)aRegex inRange:(const NSRange)range; +- (NSString *)stringByMatching:(id)aRegex withReferenceString:(NSString * const)referenceString; +- (NSString *)stringByMatching:(id)aRegex inRange:(const NSRange)range withReferenceString:(NSString * const)referenceString; +//- (NSString *)stringByMatching:(id)aRegex fromIndex:(const RKUInteger)anIndex withReferenceString:(NSString * const)referenceString; +//- (NSString *)stringByMatching:(id)aRegex toIndex:(const RKUInteger)anIndex withReferenceString:(NSString * const)referenceString; +- (NSString *)stringByMatching:(id)aRegex withReferenceFormat:(NSString * const)referenceFormatString, ...; +- (NSString *)stringByMatching:(id)aRegex inRange:(const NSRange)range withReferenceFormat:(NSString * const)referenceFormatString, ...; +- (NSString *)stringByMatching:(id)aRegex inRange:(const NSRange)range withReferenceFormat:(NSString * const)referenceFormatString arguments:(va_list)argList; +//- (NSString *)stringByMatching:(id)aRegex fromIndex:(const RKUInteger)anIndex withReferenceFormat:(NSString * const)referenceFormatString, ...; +//- (NSString *)stringByMatching:(id)aRegex toIndex:(const RKUInteger)anIndex withReferenceFormat:(NSString * const)referenceFormatString, ...; +- (NSString *)stringByMatching:(id)aRegex replace:(const RKUInteger)count withReferenceString:(NSString * const)referenceString; +- (NSString *)stringByMatching:(id)aRegex inRange:(const NSRange)range replace:(const RKUInteger)count withReferenceString:(NSString * const)referenceString; +//- (NSString *)stringByMatching:(id)aRegex fromIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withReferenceString:(NSString * const)referenceString; +//- (NSString *)stringByMatching:(id)aRegex toIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withReferenceString:(NSString * const)referenceString; +- (NSString *)stringByMatching:(id)aRegex replace:(const RKUInteger)count withReferenceFormat:(NSString * const)referenceFormatString, ...; +- (NSString *)stringByMatching:(id)aRegex inRange:(const NSRange)range replace:(const RKUInteger)count withReferenceFormat:(NSString * const)referenceFormatString, ...; +//- (NSString *)stringByMatching:(id)aRegex fromIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withReferenceFormat:(NSString * const)referenceFormatString, ...; +//- (NSString *)stringByMatching:(id)aRegex toIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withReferenceFormat:(NSString * const)referenceFormatString, ...; + +- (NSString *)stringByMatching:(id)aRegex inRange:(const NSRange)range replace:(const RKUInteger)count withReferenceFormat:(NSString * const)referenceFormatString arguments:(va_list)argList; + +@end + +@interface NSMutableString (RegexKitAdditions) +- (RKUInteger)match:(id)aRegex replace:(const RKUInteger)count withString:(NSString * const)replacementString; +- (RKUInteger)match:(id)aRegex inRange:(const NSRange)range replace:(const RKUInteger)count withString:(NSString * const)replacementString; +//- (RKUInteger)match:(id)aRegex fromIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withString:(NSString * const)replacementString; +//- (RKUInteger)match:(id)aRegex toIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withString:(NSString * const)replacementString; + +- (RKUInteger)match:(id)aRegex replace:(const RKUInteger)count withFormat:(NSString * const)formatString, ...; +- (RKUInteger)match:(id)aRegex inRange:(const NSRange)range replace:(const RKUInteger)count withFormat:(NSString * const)formatString, ...; +- (RKUInteger)match:(id)aRegex inRange:(const NSRange)range replace:(const RKUInteger)count withFormat:(NSString * const)formatString arguments:(va_list)argList; +//- (RKUInteger)match:(id)aRegex fromIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withFormat:(NSString * const)formatString, ...; +//- (RKUInteger)match:(id)aRegex toIndex:(const RKUInteger)anIndex replace:(const RKUInteger)count withFormat:(NSString * const)formatString, ...; + +@end + +#endif // _REGEXKIT_NSSTRING_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RKCache.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RKCache.h new file mode 100644 index 00000000..ec9b529f --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RKCache.h @@ -0,0 +1,110 @@ +// +// RKCache.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_RKCACHE_H_ +#define _REGEXKIT_RKCACHE_H_ 1 + +#import +#import +#import +#import + +@class RKReadWriteLock; + +@interface RKCache : NSObject { + RK_STRONG_REF RKReadWriteLock *cacheRWLock; + RK_STRONG_REF NSMapTable *cacheMapTable; + RK_STRONG_REF NSString *cacheDescriptionString; + RKUInteger cacheHits; + RKUInteger cacheMisses; + RKUInteger cacheClearedCount; + int cacheInitialized; + int cacheIsEnabled; + int cacheAddingIsEnabled; // Used during debugging + int cacheLookupIsEnabled; // Used during debugging + RK_STRONG_REF char *cacheDescriptionUTF8String; +} +- (id)initWithDescription:(NSString * const)descriptionString; +- (void)setDescription:(NSString * const)descriptionString; +- (NSString *)status; +- (NSString *)description; +- (id)objectForHash:(const RKUInteger)objectHash description:(NSString * const)descriptionString; +- (id)objectForHash:(const RKUInteger)objectHash description:(NSString * const)descriptionString autorelease:(const BOOL)shouldAutorelease; +- (BOOL)addObjectToCache:(id)object; +- (BOOL)addObjectToCache:(id)object withHash:(const RKUInteger)objectHash; +- (id)removeObjectFromCache:(id)object; +- (id)removeObjectWithHash:(const RKUInteger)objectHash; +- (BOOL)clearCache; +- (NSSet *)cacheSet; +- (BOOL)isCacheEnabled; +- (BOOL)setCacheEnabled:(const BOOL)enableCache; +- (RKUInteger)cacheCount; + +@end + + +@interface RKCache (CacheDebugging) + +- (BOOL)isCacheAddingEnabled; +- (BOOL)setCacheAddingEnabled:(const BOOL)enableCacheAdding; +- (BOOL)isCacheLookupEnabled; +- (BOOL)setCacheLookupEnabled:(const BOOL)enableCacheLookup; + +@end + +@interface RKCache (CountersDebugging) + +- (void)setDebug:(const BOOL)enableDebugging; +- (void)clearCounters; +- (RKUInteger)cacheClearedCount; +- (RKUInteger)readBusyCount; +- (RKUInteger)readSpinCount; +- (RKUInteger)writeBusyCount; +- (RKUInteger)writeSpinCount; + +@end + +#endif // _REGEXKIT_RKCACHE_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RKEnumerator.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RKEnumerator.h new file mode 100644 index 00000000..39277d55 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RKEnumerator.h @@ -0,0 +1,91 @@ +// +// RKEnumerator.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_RKENUMERATOR_H_ +#define _REGEXKIT_RKENUMERATOR_H_ 1 + +@class RKRegex; + +#import +#import +#import + +@interface RKEnumerator : NSEnumerator { + RKRegex *regex; + NSString *string; + RKUInteger atBufferLocation; + RKUInteger regexCaptureCount; + NSRange searchByteRange; + NSRange searchUTF16Range; + RK_STRONG_REF NSRange *resultUTF8Ranges; + RK_STRONG_REF NSRange *resultUTF16Ranges; + RKUInteger hasPerformedMatch:1; +} ++ (id)enumeratorWithRegex:(id)aRegex string:(NSString * const)string; ++ (id)enumeratorWithRegex:(id)aRegex string:(NSString * const)string inRange:(const NSRange)range; ++ (id)enumeratorWithRegex:(id)initRegex string:(NSString * const)initString inRange:(const NSRange)initRange error:(NSError **)error; +- (id)initWithRegex:(id)initRegex string:(NSString * const)initString; +- (id)initWithRegex:(id)initRegex string:(NSString * const)initString inRange:(const NSRange)initRange; +- (id)initWithRegex:(id)initRegex string:(NSString * const)initString inRange:(const NSRange)initRange error:(NSError **)error; +- (RKRegex *)regex; +- (NSString *)string; +- (NSRange)currentRange; +- (NSRange)currentRangeForCapture:(const RKUInteger)capture; +- (NSRange)currentRangeForCaptureName:(NSString * const)captureNameString; +- (NSRange *)currentRanges; +- (id)nextObject; +- (NSRange)nextRange; +- (NSRange)nextRangeForCapture:(const RKUInteger)capture; +- (NSRange)nextRangeForCaptureName:(NSString * const)captureNameString; +- (NSRange *)nextRanges; +- (BOOL)getCapturesWithReferences:(NSString * const)firstReference, ... RK_REQUIRES_NIL_TERMINATION; +- (NSString *)stringWithReferenceString:(NSString * const)referenceString; +- (NSString *)stringWithReferenceFormat:(NSString * const)referenceFormatString, ...; +- (NSString *)stringWithReferenceFormat:(NSString * const)referenceFormatString arguments:(va_list)argList; + +@end + +#endif // _REGEXKIT_RKENUMERATOR_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RKRegex.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RKRegex.h new file mode 100644 index 00000000..35773b08 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RKRegex.h @@ -0,0 +1,104 @@ +// +// RKRegex.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_RKREGEX_H_ +#define _REGEXKIT_RKREGEX_H_ 1 + +#import +#import +#import +#import + +@interface RKRegex : NSObject { + RK_STRONG_REF pcre *_compiledPCRE; // Pointer to pcre library type pcre. + RK_STRONG_REF pcre_extra *_extraPCRE; // Pointer to pcre library type pcre_extra. + + NSString *compiledRegexString; // A copy of the regex string that was compiled. + RKCompileOption compileOption; // The options used to compile this regex. + RKUInteger captureCount; // The number of captures in the compiled regex string. + RK_STRONG_REF char *captureNameTable; // Pointer to capture names structure. + RKUInteger captureNameTableLength; // Number of entries in the capture name structure + RKUInteger captureNameLength; // The length of a capture name entry. + NSArray *captureNameArray; // An array that maps capture index values to capture names. nil if no named captures. + + RKInteger referenceCountMinusOne; // Keep track of the reference count ourselves. + RKUInteger hash; // Hash value for this object. + + RK_STRONG_REF char *compiledRegexUTF8String; + RK_STRONG_REF char *compiledOptionUTF8String; +} + ++ (RKCache *)regexCache; + ++ (NSString *)PCREVersionString; ++ (int32_t)PCREMajorVersion; ++ (int32_t)PCREMinorVersion; ++ (RKBuildConfig)PCREBuildConfig; + ++ (BOOL)isValidRegexString:(NSString * const)regexString options:(const RKCompileOption)options; ++ (id)regexWithRegexString:(NSString * const)regexString options:(const RKCompileOption)options; ++ (id)regexWithRegexString:(NSString * const RK_C99(restrict))regexString library:(NSString * const RK_C99(restrict))libraryString options:(const RKCompileOption)libraryOptions error:(NSError **)error; +- (id)initWithRegexString:(NSString * const RK_C99(restrict))regexString options:(const RKCompileOption)options; +- (id)initWithRegexString:(NSString * const RK_C99(restrict))regexString library:(NSString * const RK_C99(restrict))library options:(const RKCompileOption)libraryOptions error:(NSError **)error; +- (NSString *)regexString; +- (RKCompileOption)compileOption; + +- (RKUInteger)captureCount; +- (NSArray *)captureNameArray; +- (BOOL)isValidCaptureName:(NSString * const)captureNameString; +- (RKUInteger)captureIndexForCaptureName:(NSString * const)captureNameString; +- (NSString *)captureNameForCaptureIndex:(const RKUInteger)captureIndex; +- (RKUInteger)captureIndexForCaptureName:(NSString * const RK_C99(restrict))captureNameString inMatchedRanges:(const NSRange * const RK_C99(restrict))matchedRanges; +- (RKUInteger)captureIndexForCaptureName:(NSString * const RK_C99(restrict))captureNameString inMatchedRanges:(const NSRange * const RK_C99(restrict))matchedRanges error:(NSError **)error; + +- (BOOL)matchesCharacters:(const void * const RK_C99(restrict))matchCharacters length:(const RKUInteger)length inRange:(const NSRange)searchRange options:(const RKMatchOption)options; +- (NSRange)rangeForCharacters:(const void * const RK_C99(restrict))matchCharacters length:(const RKUInteger)length inRange:(const NSRange)searchRange captureIndex:(const RKUInteger)captureIndex options:(const RKMatchOption)options; +- (NSRange *)rangesForCharacters:(const void * const RK_C99(restrict))matchCharacters length:(const RKUInteger)length inRange:(const NSRange)searchRange options:(const RKMatchOption)options; +- (RKMatchErrorCode)getRanges:(NSRange * const RK_C99(restrict))ranges withCharacters:(const void * const RK_C99(restrict))charactersBuffer length:(const RKUInteger)length inRange:(const NSRange)searchRange options:(const RKMatchOption)options; + +@end + +#endif // _REGEXKIT_RKREGEX_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RKUtility.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RKUtility.h new file mode 100644 index 00000000..76005fa9 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RKUtility.h @@ -0,0 +1,60 @@ +// +// RKUtility.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_RKUTILITY_H_ +#define _REGEXKIT_RKUTILITY_H_ 1 + +#import +#import +#import +REGEXKIT_EXTERN NSString *RKStringFromNewlineOption(const int decodeNewlineOption, NSString *prefixString) RK_ATTRIBUTES(nonnull (2), used); +REGEXKIT_EXTERN NSArray *RKArrayFromMatchOption(const RKMatchOption decodeMatchOption) RK_ATTRIBUTES(used); +REGEXKIT_EXTERN NSArray *RKArrayFromCompileOption(const RKCompileOption decodeCompileOption) RK_ATTRIBUTES(used); +REGEXKIT_EXTERN NSArray *RKArrayFromBuildConfig(const RKBuildConfig decodeBuildConfig) RK_ATTRIBUTES(used); +REGEXKIT_EXTERN NSString *RKStringFromCompileErrorCode(const RKCompileErrorCode decodeErrorCode) RK_ATTRIBUTES(used); +REGEXKIT_EXTERN NSString *RKStringFromMatchErrorCode(const RKMatchErrorCode decodeErrorCode) RK_ATTRIBUTES(used); + +#endif // _REGEXKIT_RKUTILITY_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKit.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKit.h new file mode 100644 index 00000000..b87cd717 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKit.h @@ -0,0 +1,86 @@ +// +// RegexKit.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_REGEXKIT_H_ +#define _REGEXKIT_REGEXKIT_H_ 1 + +#import +#import + +// Include primary header for the runtime environment +#ifdef __MACOSX_RUNTIME__ +#import +#else // Using GNUstep run time +#import +#import +#endif //__MACOSX_RUNTIME__ defined in RegexKitDefines + +// RKLock and RKReadWriteLock are private classes +@class RKRegex, RKCache, RKEnumerator, RKLock, RKReadWriteLock; + +#ifdef USE_AUTORELEASED_MALLOC +@class RKAutoreleasedMemory; +#endif + +#ifdef USE_PLACEHOLDER +@class RKRegexPlaceholder; +#endif + +#import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + + +#endif // _REGEXKIT_REGEXKIT_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKitDefines.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKitDefines.h new file mode 100644 index 00000000..0c9dd747 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKitDefines.h @@ -0,0 +1,175 @@ +// +// RegexKitDefines.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_REGEXKITDEFINES_H_ +#define _REGEXKIT_REGEXKITDEFINES_H_ 1 + +#import + +#define __REGEXKIT__ + + +// Determine runtime environment +#if !defined(__MACOSX_RUNTIME__) && !defined(__GNUSTEP_RUNTIME__) + +#if defined(__APPLE__) && defined(__MACH__) && !defined(GNUSTEP) +#define __MACOSX_RUNTIME__ +#endif // If not Mac OS X, GNUstep? + +#if defined(GNUSTEP) && !defined(__MACOSX_RUNTIME__) +#define __GNUSTEP_RUNTIME__ +#endif // Not Mac OS X or GNUstep, that's a problem. + +#endif // !defined(__MACOSX_RUNTIME__) && !defined(__GNUSTEP_RUNTIME__) + + +// If the above did not set the run time environment, error out. +#if !defined(__MACOSX_RUNTIME__) && !defined(__GNUSTEP_RUNTIME__) +#error Unable to determine run time environment, automatic Mac OS X and GNUstep detection failed +#endif + +#if defined(NSINTEGER_DEFINED) +#define RKInteger NSInteger +#define RKUInteger NSUInteger +#define RKIntegerMax NSIntegerMax +#define RKIntegerMin NSIntegerMin +#define RKUIntegerMax NSUIntegerMax +#else +#define RKInteger int +#define RKUInteger unsigned int +#define RKIntegerMax INT_MAX +#define RKIntegerMin INT_MIN +#define RKUIntegerMax UINT_MAX +#endif + +#if defined (__GNUC__) && (__GNUC__ >= 4) +#define RKREGEX_STATIC_INLINE static __inline__ __attribute__((always_inline)) +#define RKREGEX_STATIC_PURE_INLINE static __inline__ __attribute__((always_inline, pure)) +#define RK_EXPECTED(cond, expect) __builtin_expect(cond, expect) +#define RK_ATTRIBUTES(attr, ...) __attribute__((attr, ##__VA_ARGS__)) +#else +#define RKREGEX_STATIC_INLINE static __inline__ +#define RKREGEX_STATIC_PURE_INLINE static __inline__ +#define RK_EXPECTED(cond, expect) cond +#define RK_ATTRIBUTES(attr, ...) +#endif + +#if defined(__MACOSX_RUNTIME__) && defined(MAC_OS_X_VERSION_10_5) && defined(NS_REQUIRES_NIL_TERMINATION) +#define RK_REQUIRES_NIL_TERMINATION NS_REQUIRES_NIL_TERMINATION +#else +#define RK_REQUIRES_NIL_TERMINATION +#endif + +// Other compilers and platforms may be able to use the following: +// +// #define RK_REQUIRES_NIL_TERMINATION RK_ATTRIBUTES(sentinel) + +#if __STDC_VERSION__ >= 199901L +#define RK_C99(keyword) keyword +#else +#define RK_C99(keyword) +#endif + +#ifdef __cplusplus +#define REGEXKIT_EXTERN extern "C" +#define REGEXKIT_PRIVATE_EXTERN __private_extern__ +#else +#define REGEXKIT_EXTERN extern +#define REGEXKIT_PRIVATE_EXTERN __private_extern__ +#endif +#define RKReplaceAll RKIntegerMax + +// Used to size/check buffers when calling private RKRegex getRanges:count:withCharacters:length:inRange:options: +#define RK_PRESIZE_CAPTURE_COUNT(x) (256 + x + (x >> 1)) +#define RK_MINIMUM_CAPTURE_COUNT(x) (x + ((x / 3) + ((3 - (x % 3)) % 3))) + +/*************** Feature and config knobs ***************/ + +// Default enabled +#define USE_PLACEHOLDER + +#if OBJC_API_VERSION < 2 && !defined (MAC_OS_X_VERSION_10_5) +#define USE_AUTORELEASED_MALLOC +#endif // Not enabled on Objective-C 2.0 (Mac OS X 10.5) + +#ifdef __COREFOUNDATION__ +#define USE_CORE_FOUNDATION +#endif + +#ifdef __MACOSX_RUNTIME__ +#define HAVE_NSNUMBERFORMATTER_CONVERSIONS +#endif + +#if defined(HAVE_NSNUMBERFORMATTER_CONVERSIONS) +#define RK_ENABLE_THREAD_LOCAL_STORAGE +#endif + +#if defined(__MACOSX_RUNTIME__) && defined(MAC_OS_X_VERSION_10_5) && defined(__OBJC_GC__) +#define ENABLE_MACOSX_GARBAGE_COLLECTION +#define RK_STRONG_REF __strong +#define RK_WEAK_REF __weak +#else +#define RK_STRONG_REF +#define RK_WEAK_REF +#endif + +#if defined(ENABLE_MACOSX_GARBAGE_COLLECTION) && !defined(MAC_OS_X_VERSION_10_5) +#error The Mac OS X Garbage Collection feature requires at least Mac OS X 10.5 +#endif + +#if defined(__MACOSX_RUNTIME__) && defined(MAC_OS_X_VERSION_10_5) && defined(S_DTRACE_DOF) +#define ENABLE_DTRACE_INSTRUMENTATION +#endif + +// AFAIK, only the GCC 3.3+ Mac OSX objc runtime has -fobjc-exception support +#if (!defined(__MACOSX_RUNTIME__)) || (!defined(__GNUC__)) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) || (!defined(MAC_OS_X_VERSION_10_3)) +// Otherwise, use NS_DURING / NS_HANDLER and friends +#define USE_MACRO_EXCEPTIONS +#endif + +/*************** END Feature and config knobs ***************/ + +#endif //_REGEXKIT_REGEXKITDEFINES_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKitTypes.h b/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKitTypes.h new file mode 100644 index 00000000..b77a5ce1 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/RegexKitTypes.h @@ -0,0 +1,226 @@ +// +// RegexKitTypes.h +// RegexKit +// http://regexkit.sourceforge.net/ +// + +/* + Copyright © 2007-2008, John Engelhart + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the Zang Industries nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _REGEXKIT_REGEXKITTYPES_H_ +#define _REGEXKIT_REGEXKITTYPES_H_ 1 + +@class NSString; + +// Defined in RKRegex.m Constants added here MUST be included in 'exports_list' to be visible! +extern NSString * const RKRegexSyntaxErrorException; +extern NSString * const RKRegexUnsupportedException; +extern NSString * const RKRegexCaptureReferenceException; +extern NSString * const RKRegexPCRELibrary; +extern NSString * const RKRegexPCRELibraryErrorDomain; +extern NSString * const RKRegexErrorDomain; +extern NSString * const RKRegexLibraryErrorKey; +extern NSString * const RKRegexLibraryErrorStringErrorKey; +extern NSString * const RKRegexStringErrorKey; +extern NSString * const RKRegexStringErrorRangeErrorKey; +extern NSString * const RKAttributedRegexStringErrorKey; +extern NSString * const RKAbreviatedRegexStringErrorKey; +extern NSString * const RKAbreviatedRegexStringErrorRangeErrorKey; +extern NSString * const RKAbreviatedAttributedRegexStringErrorKey; +extern NSString * const RKCompileOptionErrorKey; +extern NSString * const RKCompileOptionArrayErrorKey; +extern NSString * const RKCompileOptionArrayStringErrorKey; +extern NSString * const RKCompileErrorCodeErrorKey; +extern NSString * const RKCompileErrorCodeStringErrorKey; +extern NSString * const RKArrayIndexErrorKey; +extern NSString * const RKObjectErrorKey; +extern NSString * const RKCollectionErrorKey; + +typedef enum { + RKMatchErrorNoError = 0, + RKMatchErrorNoMatch = -1, + RKMatchErrorNull = -2, + RKMatchErrorBadOption = -3, + RKMatchErrorBadMagic = -4, + RKMatchErrorUnknownOpcode = -5, + RKMatchErrorNoMemory = -6, + RKMatchErrorNoSubstring = -7, + RKMatchErrorMatchLimit = -8, + RKMatchErrorCallout = -9, + RKMatchErrorBadUTF8 = -10, + RKMatchErrorBadUTF8Offset = -11, + RKMatchErrorPartial = -12, + RKMatchErrorBadPartial = -13, + RKMatchErrorInternal = -14, + RKMatchErrorBadCount = -15, + RKMatchErrorRecursionLimit = -21, + RKMatchErrorNullWorkSpaceLimit = -22, + RKMatchErrorBadNewline = -23 +} RKMatchErrorCode; + +typedef enum { + RKCompileErrorNoError = 0, + RKCompileErrorEscapeAtEndOfPattern = 1, + RKCompileErrorByteEscapeAtEndOfPattern = 2, + RKCompileErrorUnrecognizedCharacterFollowingEscape = 3, + RKCompileErrorNumbersOutOfOrder = 4, + RKCompileErrorNumbersToBig = 5, + RKCompileErrorMissingTerminatorForCharacterClass = 6, + RKCompileErrorInvalidEscapeInCharacterClass = 7, + RKCompileErrorRangeOutOfOrderInCharacterClass = 8, + RKCompileErrorNothingToRepeat = 9, + RKCompileErrorInternalErrorUnexpectedRepeat = 11, + RKCompileErrorUnrecognizedCharacterAfterOption = 12, + RKCompileErrorPOSIXNamedClassOutsideOfClass = 13, + RKCompileErrorMissingParentheses = 14, + RKCompileErrorReferenceToNonExistentSubpattern = 15, + RKCompileErrorErrorOffsetPassedAsNull = 16, + RKCompileErrorUnknownOptionBits = 17, + RKCompileErrorMissingParenthesesAfterComment = 18, + RKCompileErrorRegexTooLarge = 20, + RKCompileErrorNoMemory = 21, + RKCompileErrorUnmatchedParentheses = 22, + RKCompileErrorInternalCodeOverflow = 23, + RKCompileErrorUnrecognizedCharacterAfterNamedSubppatern = 24, + RKCompileErrorLookbehindAssertionNotFixedLength = 25, + RKCompileErrorMalformedNameOrNumberAfterSubpattern = 26, + RKCompileErrorConditionalGroupContainsMoreThanTwoBranches = 27, + RKCompileErrorAssertionExpectedAfterCondition = 28, + RKCompileErrorMissingEndParentheses = 29, + RKCompileErrorUnknownPOSIXClassName = 30, + RKCompileErrorPOSIXCollatingNotSupported = 31, + RKCompileErrorMissingUTF8Support = 32, + RKCompileErrorHexCharacterValueTooLarge = 34, + RKCompileErrorInvalidCondition = 35, + RKCompileErrorNotAllowedInLookbehindAssertion = 36, + RKCompileErrorNotSupported = 37, + RKCompileErrorCalloutExceedsMaximumAllowed = 38, + RKCompileErrorMissingParenthesesAfterCallout = 39, + RKCompileErrorRecursiveInfinitLoop = 40, + RKCompileErrorUnrecognizedCharacterAfterNamedPattern = 41, + RKCompileErrorSubpatternNameMissingTerminator = 42, + RKCompileErrorDuplicateSubpatternNames = 43, + RKCompileErrorInvalidUTF8String = 44, + RKCompileErrorMissingUnicodeSupport = 45, + RKCompileErrorMalformedUnicodeProperty = 46, + RKCompileErrorUnknownPropertyAfterUnicodeCharacter = 47, + RKCompileErrorSubpatternNameTooLong = 48, + RKCompileErrorTooManySubpatterns = 49, + RKCompileErrorRepeatedSubpatternTooLong = 50, + RKCompileErrorIllegalOctalValueOutsideUTF8 = 51, + RKCompileErrorInternalOverranCompilingWorkspace = 52, + RKCompileErrorInternalReferencedSubpatternNotFound = 53, + RKCompileErrorDEFINEGroupContainsMoreThanOneBranch = 54, + RKCompileErrorRepeatingDEFINEGroupNotAllowed = 55, + RKCompileErrorInconsistentNewlineOptions = 56, + RKCompileErrorReferenceMustBeNonZeroNumberOrBraced = 57, + RKCompileErrorRelativeSubpatternNumberMustNotBeZero = 58 +} RKCompileErrorCode; + + +typedef enum { + RKMatchNoOptions = 0, + RKMatchAnchored = 1 << 4, + RKMatchNotBeginningOfLine = 1 << 7, + RKMatchNotEndOfLine = 1 << 8, + RKMatchNotEmpty = 1 << 10, + RKMatchNoUTF8Check = 1 << 13, + RKMatchPartial = 1 << 15, + RKMatchNewlineDefault = 0x00000000, + RKMatchNewlineCR = 0x00100000, + RKMatchNewlineLF = 0x00200000, + RKMatchNewlineCRLF = 0x00300000, + RKMatchNewlineAny = 0x00400000, + RKMatchNewlineAnyCRLF = 0x00500000, + RKMatchNewlineMask = 0x00700000, + RKMatchBackslashRAnyCRLR = 1 << 23, + RKMatchBackslashRUnicode = 1 << 24 +} RKMatchOption; + +typedef enum { + RKCompileNoOptions = 0, + RKCompileCaseless = 1 << 0, + RKCompileMultiline = 1 << 1, + RKCompileDotAll = 1 << 2, + RKCompileExtended = 1 << 3, + RKCompileAnchored = 1 << 4, + RKCompileDollarEndOnly = 1 << 5, + RKCompileExtra = 1 << 6, + RKCompileUngreedy = 1 << 9, + RKCompileUTF8 = 1 << 11, + RKCompileNoAutoCapture = 1 << 12, + RKCompileNoUTF8Check = 1 << 13, + RKCompileAutoCallout = 1 << 14, + RKCompileFirstLine = 1 << 18, + RKCompileDupNames = 1 << 19, + RKCompileBackslashRAnyCRLR = 1 << 23, + RKCompileBackslashRUnicode = 1 << 24, + RKCompileAllOptions = (RKCompileCaseless | RKCompileMultiline | RKCompileDotAll | RKCompileExtended | RKCompileAnchored | + RKCompileDollarEndOnly | RKCompileExtra | RKCompileUngreedy | RKCompileUTF8 | RKCompileNoAutoCapture | + RKCompileNoUTF8Check | RKCompileAutoCallout | RKCompileFirstLine | RKCompileDupNames | RKCompileBackslashRAnyCRLR | + RKCompileBackslashRUnicode + ), + RKCompileUnsupported = (RKCompileAutoCallout), + RKCompileNewlineDefault = 0x00000000, + RKCompileNewlineCR = 0x00100000, + RKCompileNewlineLF = 0x00200000, + RKCompileNewlineCRLF = 0x00300000, + RKCompileNewlineAny = 0x00400000, + RKCompileNewlineAnyCRLF = 0x00500000, + RKCompileNewlineMask = 0x00700000, + RKCompileNewlineShift = 20 +} RKCompileOption; + +typedef enum { + RKBuildConfigNoOptions = 0, + RKBuildConfigUTF8 = 1 << 0, + RKBuildConfigUnicodeProperties = 1 << 1, + RKBuildConfigNewlineDefault = 0x00000000, + RKBuildConfigNewlineCR = 0x00100000, + RKBuildConfigNewlineLF = 0x00200000, + RKBuildConfigNewlineCRLF = 0x00300000, + RKBuildConfigNewlineAny = 0x00400000, + RKBuildConfigNewlineAnyCRLF = 0x00500000, + RKBuildConfigNewlineMask = 0x00700000, + RKBuildConfigBackslashRAnyCRLR = 1 << 23, + RKBuildConfigBackslashRUnicode = 1 << 24 +} RKBuildConfig; + +#endif // _REGEXKIT_REGEXKITTYPES_H_ + +#ifdef __cplusplus + } /* extern "C" */ +#endif diff --git a/Frameworks/RegexKit.framework/Versions/A/Headers/pcre.h b/Frameworks/RegexKit.framework/Versions/A/Headers/pcre.h new file mode 100644 index 00000000..c85c32ea --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Headers/pcre.h @@ -0,0 +1,303 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* This is the public header file for the PCRE library, to be #included by +applications that call the PCRE functions. + + Copyright (c) 1997-2008 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#ifndef _PCRE_H +#define _PCRE_H + +/* The current PCRE version information. */ + +#define PCRE_MAJOR 7 +#define PCRE_MINOR 6 +#define PCRE_PRERELEASE +#define PCRE_DATE 2008-01-28 + +/* When an application links to a PCRE DLL in Windows, the symbols that are +imported have to be identified as such. When building PCRE, the appropriate +export setting is defined in pcre_internal.h, which includes this file. So we +don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ + +#if defined(_WIN32) && !defined(PCRE_STATIC) +# ifndef PCRE_EXP_DECL +# define PCRE_EXP_DECL extern __declspec(dllimport) +# endif +# ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern __declspec(dllimport) +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN __declspec(dllimport) +# endif +# endif +#endif + +/* By default, we use the standard "extern" declarations. */ + +#ifndef PCRE_EXP_DECL +# ifdef __cplusplus +# define PCRE_EXP_DECL extern "C" +# else +# define PCRE_EXP_DECL extern +# endif +#endif + +#ifdef __cplusplus +# ifndef PCRECPP_EXP_DECL +# define PCRECPP_EXP_DECL extern +# endif +# ifndef PCRECPP_EXP_DEFN +# define PCRECPP_EXP_DEFN +# endif +#endif + +/* Have to include stdlib.h in order to ensure that size_t is defined; +it is needed here for malloc. */ + +#include + +/* Allow for C++ users */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Options */ + +#define PCRE_CASELESS 0x00000001 +#define PCRE_MULTILINE 0x00000002 +#define PCRE_DOTALL 0x00000004 +#define PCRE_EXTENDED 0x00000008 +#define PCRE_ANCHORED 0x00000010 +#define PCRE_DOLLAR_ENDONLY 0x00000020 +#define PCRE_EXTRA 0x00000040 +#define PCRE_NOTBOL 0x00000080 +#define PCRE_NOTEOL 0x00000100 +#define PCRE_UNGREEDY 0x00000200 +#define PCRE_NOTEMPTY 0x00000400 +#define PCRE_UTF8 0x00000800 +#define PCRE_NO_AUTO_CAPTURE 0x00001000 +#define PCRE_NO_UTF8_CHECK 0x00002000 +#define PCRE_AUTO_CALLOUT 0x00004000 +#define PCRE_PARTIAL 0x00008000 +#define PCRE_DFA_SHORTEST 0x00010000 +#define PCRE_DFA_RESTART 0x00020000 +#define PCRE_FIRSTLINE 0x00040000 +#define PCRE_DUPNAMES 0x00080000 +#define PCRE_NEWLINE_CR 0x00100000 +#define PCRE_NEWLINE_LF 0x00200000 +#define PCRE_NEWLINE_CRLF 0x00300000 +#define PCRE_NEWLINE_ANY 0x00400000 +#define PCRE_NEWLINE_ANYCRLF 0x00500000 +#define PCRE_BSR_ANYCRLF 0x00800000 +#define PCRE_BSR_UNICODE 0x01000000 + +/* Exec-time and get/set-time error codes */ + +#define PCRE_ERROR_NOMATCH (-1) +#define PCRE_ERROR_NULL (-2) +#define PCRE_ERROR_BADOPTION (-3) +#define PCRE_ERROR_BADMAGIC (-4) +#define PCRE_ERROR_UNKNOWN_OPCODE (-5) +#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ +#define PCRE_ERROR_NOMEMORY (-6) +#define PCRE_ERROR_NOSUBSTRING (-7) +#define PCRE_ERROR_MATCHLIMIT (-8) +#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ +#define PCRE_ERROR_BADUTF8 (-10) +#define PCRE_ERROR_BADUTF8_OFFSET (-11) +#define PCRE_ERROR_PARTIAL (-12) +#define PCRE_ERROR_BADPARTIAL (-13) +#define PCRE_ERROR_INTERNAL (-14) +#define PCRE_ERROR_BADCOUNT (-15) +#define PCRE_ERROR_DFA_UITEM (-16) +#define PCRE_ERROR_DFA_UCOND (-17) +#define PCRE_ERROR_DFA_UMLIMIT (-18) +#define PCRE_ERROR_DFA_WSSIZE (-19) +#define PCRE_ERROR_DFA_RECURSE (-20) +#define PCRE_ERROR_RECURSIONLIMIT (-21) +#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ +#define PCRE_ERROR_BADNEWLINE (-23) + +/* Request types for pcre_fullinfo() */ + +#define PCRE_INFO_OPTIONS 0 +#define PCRE_INFO_SIZE 1 +#define PCRE_INFO_CAPTURECOUNT 2 +#define PCRE_INFO_BACKREFMAX 3 +#define PCRE_INFO_FIRSTBYTE 4 +#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ +#define PCRE_INFO_FIRSTTABLE 5 +#define PCRE_INFO_LASTLITERAL 6 +#define PCRE_INFO_NAMEENTRYSIZE 7 +#define PCRE_INFO_NAMECOUNT 8 +#define PCRE_INFO_NAMETABLE 9 +#define PCRE_INFO_STUDYSIZE 10 +#define PCRE_INFO_DEFAULT_TABLES 11 +#define PCRE_INFO_OKPARTIAL 12 +#define PCRE_INFO_JCHANGED 13 +#define PCRE_INFO_HASCRORLF 14 + +/* Request types for pcre_config(). Do not re-arrange, in order to remain +compatible. */ + +#define PCRE_CONFIG_UTF8 0 +#define PCRE_CONFIG_NEWLINE 1 +#define PCRE_CONFIG_LINK_SIZE 2 +#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 +#define PCRE_CONFIG_MATCH_LIMIT 4 +#define PCRE_CONFIG_STACKRECURSE 5 +#define PCRE_CONFIG_UNICODE_PROPERTIES 6 +#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 +#define PCRE_CONFIG_BSR 8 + +/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine +these bits, just add new ones on the end, in order to remain compatible. */ + +#define PCRE_EXTRA_STUDY_DATA 0x0001 +#define PCRE_EXTRA_MATCH_LIMIT 0x0002 +#define PCRE_EXTRA_CALLOUT_DATA 0x0004 +#define PCRE_EXTRA_TABLES 0x0008 +#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 + +/* Types */ + +struct real_pcre; /* declaration; the definition is private */ +typedef struct real_pcre pcre; + +/* When PCRE is compiled as a C++ library, the subject pointer type can be +replaced with a custom type. For conventional use, the public interface is a +const char *. */ + +#ifndef PCRE_SPTR +#define PCRE_SPTR const char * +#endif + +/* The structure for passing additional data to pcre_exec(). This is defined in +such as way as to be extensible. Always add new fields at the end, in order to +remain compatible. */ + +typedef struct pcre_extra { + unsigned long int flags; /* Bits for which fields are set */ + void *study_data; /* Opaque data from pcre_study() */ + unsigned long int match_limit; /* Maximum number of calls to match() */ + void *callout_data; /* Data passed back in callouts */ + const unsigned char *tables; /* Pointer to character tables */ + unsigned long int match_limit_recursion; /* Max recursive calls to match() */ +} pcre_extra; + +/* The structure for passing out data via the pcre_callout_function. We use a +structure so that new fields can be added on the end in future versions, +without changing the API of the function, thereby allowing old clients to work +without modification. */ + +typedef struct pcre_callout_block { + int version; /* Identifies version of block */ + /* ------------------------ Version 0 ------------------------------- */ + int callout_number; /* Number compiled into pattern */ + int *offset_vector; /* The offset vector */ + PCRE_SPTR subject; /* The subject being matched */ + int subject_length; /* The length of the subject */ + int start_match; /* Offset to start of this match attempt */ + int current_position; /* Where we currently are in the subject */ + int capture_top; /* Max current capture */ + int capture_last; /* Most recently closed capture */ + void *callout_data; /* Data passed in with the call */ + /* ------------------- Added for Version 1 -------------------------- */ + int pattern_position; /* Offset to next item in the pattern */ + int next_item_length; /* Length of next item in the pattern */ + /* ------------------------------------------------------------------ */ +} pcre_callout_block; + +/* Indirection for store get and free functions. These can be set to +alternative malloc/free functions if required. Special ones are used in the +non-recursive case for "frames". There is also an optional callout function +that is triggered by the (?) regex item. For Virtual Pascal, these definitions +have to take another form. */ + +#ifndef VPCOMPAT +PCRE_EXP_DECL void *(*pcre_malloc)(size_t); +PCRE_EXP_DECL void (*pcre_free)(void *); +PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); +PCRE_EXP_DECL void (*pcre_stack_free)(void *); +PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); +#else /* VPCOMPAT */ +PCRE_EXP_DECL void *pcre_malloc(size_t); +PCRE_EXP_DECL void pcre_free(void *); +PCRE_EXP_DECL void *pcre_stack_malloc(size_t); +PCRE_EXP_DECL void pcre_stack_free(void *); +PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); +#endif /* VPCOMPAT */ + +/* Exported PCRE functions */ + +PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, + const unsigned char *); +PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, + int *, const unsigned char *); +PCRE_EXP_DECL int pcre_config(int, void *); +PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, + int *, int, const char *, char *, int); +PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, + int); +PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, + const char *, int, int, int, int *, int , int *, int); +PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, + int, int, int, int *, int); +PCRE_EXP_DECL void pcre_free_substring(const char *); +PCRE_EXP_DECL void pcre_free_substring_list(const char **); +PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, + void *); +PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, + int *, int, const char *, const char **); +PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); +PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, + char **, char **); +PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, + const char **); +PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, + const char ***); +PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *); +PCRE_EXP_DECL const unsigned char *pcre_maketables(void); +PCRE_EXP_DECL int pcre_refcount(pcre *, int); +PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); +PCRE_EXP_DECL const char *pcre_version(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* End of pcre.h */ diff --git a/Frameworks/RegexKit.framework/Versions/A/RegexKit b/Frameworks/RegexKit.framework/Versions/A/RegexKit new file mode 100755 index 00000000..5d780d4a Binary files /dev/null and b/Frameworks/RegexKit.framework/Versions/A/RegexKit differ diff --git a/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/InfoPlist.strings b/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..0c22849c Binary files /dev/null and b/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/InfoPlist.strings differ diff --git a/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/Localizable.strings b/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/Localizable.strings new file mode 100644 index 00000000..5371640b Binary files /dev/null and b/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/Localizable.strings differ diff --git a/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/pcre.strings b/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/pcre.strings new file mode 100644 index 00000000..64252e1a Binary files /dev/null and b/Frameworks/RegexKit.framework/Versions/A/Resources/English.lproj/pcre.strings differ diff --git a/Frameworks/RegexKit.framework/Versions/A/Resources/Info.plist b/Frameworks/RegexKit.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..384f29e2 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,41 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + RegexKit + CFBundleIdentifier + com.zang.RegexKit + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + RegexKit + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.6.0 + CFBundleSignature + ZanG + CFBundleVersion + 0.6.0 + LSMinimumSystemVersion + 10.4.0 + LSMinimumSystemVersionByArchitecture + + i386 + 10.4.4 + ppc + 10.4.0 + ppc64 + 10.5.0 + x86_64 + 10.5.0 + + NSHumanReadableCopyright + Copyright © 2007-2008, John Engelhart + NSPrincipalClass + RKRegex + + diff --git a/Frameworks/RegexKit.framework/Versions/A/Resources/LICENSE b/Frameworks/RegexKit.framework/Versions/A/Resources/LICENSE new file mode 100644 index 00000000..ff337eca --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/A/Resources/LICENSE @@ -0,0 +1,79 @@ + +Important Information +--------------------- + +RegexKit uses the PCRE library, written by Philip Hazel and +Copyright © 1997-2008 University of Cambridge, as its regular expression +pattern matching engine. Therefore, RegexKit requires and incorporates the +PCRE library in to the framework executable. Because of this, you should be +aware of the PCRE library licensing requirements. + +Website: http://www.pcre.org/ +License: http://www.pcre.org/license.txt +Type : BSD License (at time of publication) + +The RegexKit BSD License +------------------------ + +Copyright © 2007-2008, John Engelhart + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +* Neither the name of the Zang Industries nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The PCRE BSD License +------------------------ + +Copyright (c) 1997-2008 University of Cambridge +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the name of Google + Inc. nor the names of their contributors may be used to endorse or + promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/Frameworks/RegexKit.framework/Versions/Current b/Frameworks/RegexKit.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/Frameworks/RegexKit.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Headers b/Frameworks/Sparkle.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/Frameworks/Sparkle.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Resources b/Frameworks/Sparkle.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/Frameworks/Sparkle.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Sparkle b/Frameworks/Sparkle.framework/Sparkle new file mode 120000 index 00000000..b2c52731 --- /dev/null +++ b/Frameworks/Sparkle.framework/Sparkle @@ -0,0 +1 @@ +Versions/Current/Sparkle \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h b/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h new file mode 100644 index 00000000..171148a4 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcast.h @@ -0,0 +1,33 @@ +// +// SUAppcast.h +// Sparkle +// +// Created by Andy Matuschak on 3/12/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUAPPCAST_H +#define SUAPPCAST_H + +@class SUAppcastItem; +@interface SUAppcast : NSObject { + NSArray *items; + NSString *userAgentString; + id delegate; + NSMutableData *incrementalData; +} + +- (void)fetchAppcastFromURL:(NSURL *)url; +- (void)setDelegate:delegate; +- (void)setUserAgentString:(NSString *)userAgentString; + +- (NSArray *)items; + +@end + +@interface NSObject (SUAppcastDelegate) +- (void)appcastDidFinishLoading:(SUAppcast *)appcast; +- (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; +@end + +#endif diff --git a/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h b/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h new file mode 100644 index 00000000..7f1ca65c --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h @@ -0,0 +1,47 @@ +// +// SUAppcastItem.h +// Sparkle +// +// Created by Andy Matuschak on 3/12/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUAPPCASTITEM_H +#define SUAPPCASTITEM_H + +@interface SUAppcastItem : NSObject { + NSString *title; + NSDate *date; + NSString *itemDescription; + + NSURL *releaseNotesURL; + + NSString *DSASignature; + NSString *minimumSystemVersion; + + NSURL *fileURL; + NSString *versionString; + NSString *displayVersionString; + + NSDictionary *propertiesDictionary; +} + +// Initializes with data from a dictionary provided by the RSS class. +- initWithDictionary:(NSDictionary *)dict; + +- (NSString *)title; +- (NSString *)versionString; +- (NSString *)displayVersionString; +- (NSDate *)date; +- (NSString *)itemDescription; +- (NSURL *)releaseNotesURL; +- (NSURL *)fileURL; +- (NSString *)DSASignature; +- (NSString *)minimumSystemVersion; + +// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. +- (NSDictionary *)propertiesDictionary; + +@end + +#endif diff --git a/Frameworks/Sparkle.framework/Versions/A/Headers/SUUpdater.h b/Frameworks/Sparkle.framework/Versions/A/Headers/SUUpdater.h new file mode 100644 index 00000000..e78c4d35 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Headers/SUUpdater.h @@ -0,0 +1,118 @@ +// +// SUUpdater.h +// Sparkle +// +// Created by Andy Matuschak on 1/4/06. +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SUUPDATER_H +#define SUUPDATER_H + +#import + +@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; +@interface SUUpdater : NSObject { + NSTimer *checkTimer; + SUUpdateDriver *driver; + + SUHost *host; + IBOutlet id delegate; +} + ++ (SUUpdater *)sharedUpdater; ++ (SUUpdater *)updaterForBundle:(NSBundle *)bundle; +- (NSBundle *)hostBundle; + +- (void)setDelegate:(id)delegate; +- delegate; + +- (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; +- (BOOL)automaticallyChecksForUpdates; + +- (void)setUpdateCheckInterval:(NSTimeInterval)interval; +- (NSTimeInterval)updateCheckInterval; + +- (void)setFeedURL:(NSURL *)feedURL; +- (NSURL *)feedURL; + +- (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; +- (BOOL)sendsSystemProfile; + +- (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; +- (BOOL)automaticallyDownloadsUpdates; + +// This IBAction is meant for a main menu item. Hook up any menu item to this action, +// and Sparkle will check for updates and report back its findings verbosely. +- (IBAction)checkForUpdates:sender; + +// This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update, +// in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an +// update is found, it will be downloaded and prepped for installation. +- (void)checkForUpdatesInBackground; + +// Date of last update check. Returns null if no check has been performed. +- (NSDate*)lastUpdateCheckDate; + +// This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though, +// (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. +- (void)checkForUpdateInformation; + +// Call this to appropriately schedule or cancel the update checking timer according to the preferences for time interval and automatic checks. This call does not change the date of the next check, but only the internal NSTimer. +- (void)resetUpdateCycle; + +- (BOOL)updateInProgress; +@end + +@interface NSObject (SUUpdaterDelegateInformalProtocol) +// This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. +- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; + +// Use this to override the default behavior for Sparkle prompting the user about automatic update checks. +- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; + +// Implement this if you want to do some special handling with the appcast once it finishes loading. +- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; + +// If you're using special logic or extensions in your appcast, implement this to use your own logic for finding +// a valid update, if any, in the given appcast. +- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle; + +// Sent when a valid update is found by the update driver. +- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; + +// Sent when a valid update is not found. +- (void)updaterDidNotFindUpdate:(SUUpdater *)update; + +// Sent immediately before installing the specified update. +- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; + +// Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. +- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; + +// Called immediately before relaunching. +- (void)updaterWillRelaunchApplication:(SUUpdater *)updater; + +// This method allows you to provide a custom version comparator. +// If you don't implement this method or return nil, the standard version comparator will be used. +- (id )versionComparatorForUpdater:(SUUpdater *)updater; + +// Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle. +- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; + +@end + +// Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. +#ifdef DEBUG +#define SU_MIN_CHECK_INTERVAL 60 +#else +#define SU_MIN_CHECK_INTERVAL 60*60 +#endif + +#ifdef DEBUG +#define SU_DEFAULT_CHECK_INTERVAL 60 +#else +#define SU_DEFAULT_CHECK_INTERVAL 60*60*24 +#endif + +#endif diff --git a/Frameworks/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h b/Frameworks/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h new file mode 100644 index 00000000..3d11ae87 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h @@ -0,0 +1,27 @@ +// +// SUVersionComparisonProtocol.h +// Sparkle +// +// Created by Andy Matuschak on 12/21/07. +// Copyright 2007 Andy Matuschak. All rights reserved. +// + +#ifndef SUVERSIONCOMPARISONPROTOCOL_H +#define SUVERSIONCOMPARISONPROTOCOL_H + +/*! + @protocol + @abstract Implement this protocol to provide version comparison facilities for Sparkle. +*/ +@protocol SUVersionComparison + +/*! + @method + @abstract An abstract method to compare two version strings. + @discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent. +*/ +- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; + +@end + +#endif diff --git a/Frameworks/Sparkle.framework/Versions/A/Headers/Sparkle.h b/Frameworks/Sparkle.framework/Versions/A/Headers/Sparkle.h new file mode 100644 index 00000000..08dd5777 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Headers/Sparkle.h @@ -0,0 +1,21 @@ +// +// Sparkle.h +// Sparkle +// +// Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) +// Copyright 2006 Andy Matuschak. All rights reserved. +// + +#ifndef SPARKLE_H +#define SPARKLE_H + +// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless +// there are name-space collisions) so we can list all of them to start with: + +#import + +#import +#import +#import + +#endif diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist b/Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..c7f277d0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + Sparkle + CFBundleIdentifier + org.andymatuschak.Sparkle + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Sparkle + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.5 Beta 6 + CFBundleSignature + ???? + CFBundleVersion + 313 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/License.txt b/Frameworks/Sparkle.framework/Versions/A/Resources/License.txt new file mode 100644 index 00000000..20466c41 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/License.txt @@ -0,0 +1,7 @@ +Copyright (c) 2006 Andy Matuschak + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist b/Frameworks/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist new file mode 100644 index 00000000..92ef9471 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist @@ -0,0 +1,174 @@ + + + + + ADP2,1 + Developer Transition Kit + MacBook1,1 + MacBook (Core Duo) + MacBook2,1 + MacBook (Core 2 Duo) + MacBook4,1 + MacBook (Core 2 Duo Feb 2008) + MacBookAir1,1 + MacBook Air (January 2008) + MacBookPro1,1 + MacBook Pro Core Duo (15-inch) + MacBookPro1,2 + MacBook Pro Core Duo (17-inch) + MacBookPro2,1 + MacBook Pro Core 2 Duo (17-inch) + MacBookPro2,2 + MacBook Pro Core 2 Duo (15-inch) + MacBookPro3,1 + MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) + MacBookPro3,2 + MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) + MacBookPro4,1 + MacBook Pro (Core 2 Duo Feb 2008) + MacPro1,1 + Mac Pro (four-core) + MacPro2,1 + Mac Pro (eight-core) + MacPro3,1 + Mac Pro (January 2008 4- or 8- core "Harpertown") + Macmini1,1 + Mac Mini (Core Solo/Duo) + PowerBook1,1 + PowerBook G3 + PowerBook2,1 + iBook G3 + PowerBook2,2 + iBook G3 (FireWire) + PowerBook2,3 + iBook G3 + PowerBook2,4 + iBook G3 + PowerBook3,1 + PowerBook G3 (FireWire) + PowerBook3,2 + PowerBook G4 + PowerBook3,3 + PowerBook G4 (Gigabit Ethernet) + PowerBook3,4 + PowerBook G4 (DVI) + PowerBook3,5 + PowerBook G4 (1GHz / 867MHz) + PowerBook4,1 + iBook G3 (Dual USB, Late 2001) + PowerBook4,2 + iBook G3 (16MB VRAM) + PowerBook4,3 + iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) + PowerBook5,1 + PowerBook G4 (17 inch) + PowerBook5,2 + PowerBook G4 (15 inch FW 800) + PowerBook5,3 + PowerBook G4 (17-inch 1.33GHz) + PowerBook5,4 + PowerBook G4 (15 inch 1.5/1.33GHz) + PowerBook5,5 + PowerBook G4 (17-inch 1.5GHz) + PowerBook5,6 + PowerBook G4 (15 inch 1.67GHz/1.5GHz) + PowerBook5,7 + PowerBook G4 (17-inch 1.67GHz) + PowerBook5,8 + PowerBook G4 (Double layer SD, 15 inch) + PowerBook5,9 + PowerBook G4 (Double layer SD, 17 inch) + PowerBook6,1 + PowerBook G4 (12 inch) + PowerBook6,2 + PowerBook G4 (12 inch, DVI) + PowerBook6,3 + iBook G4 + PowerBook6,4 + PowerBook G4 (12 inch 1.33GHz) + PowerBook6,5 + iBook G4 (Early-Late 2004) + PowerBook6,7 + iBook G4 (Mid 2005) + PowerBook6,8 + PowerBook G4 (12 inch 1.5GHz) + PowerMac1,1 + Power Macintosh G3 (Blue & White) + PowerMac1,2 + Power Macintosh G4 (PCI Graphics) + PowerMac10,1 + Mac Mini G4 + PowerMac10,2 + Mac Mini (Late 2005) + PowerMac11,2 + Power Macintosh G5 (Late 2005) + PowerMac12,1 + iMac G5 (iSight) + PowerMac2,1 + iMac G3 (Slot-loading CD-ROM) + PowerMac2,2 + iMac G3 (Summer 2000) + PowerMac3,1 + Power Macintosh G4 (AGP Graphics) + PowerMac3,2 + Power Macintosh G4 (AGP Graphics) + PowerMac3,3 + Power Macintosh G4 (Gigabit Ethernet) + PowerMac3,4 + Power Macintosh G4 (Digital Audio) + PowerMac3,5 + Power Macintosh G4 (Quick Silver) + PowerMac3,6 + Power Macintosh G4 (Mirrored Drive Door) + PowerMac4,1 + iMac G3 (Early/Summer 2001) + PowerMac4,2 + iMac G4 (Flat Panel) + PowerMac4,4 + eMac + PowerMac4,5 + iMac G4 (17-inch Flat Panel) + PowerMac5,1 + Power Macintosh G4 Cube + PowerMac6,1 + iMac G4 (USB 2.0) + PowerMac6,3 + iMac G4 (20-inch Flat Panel) + PowerMac6,4 + eMac (USB 2.0, 2005) + PowerMac7,2 + Power Macintosh G5 + PowerMac7,3 + Power Macintosh G5 + PowerMac8,1 + iMac G5 + PowerMac8,2 + iMac G5 (Ambient Light Sensor) + PowerMac9,1 + Power Macintosh G5 (Late 2005) + RackMac1,1 + Xserve G4 + RackMac1,2 + Xserve G4 (slot-loading, cluster node) + RackMac3,1 + Xserve G5 + Xserve1,1 + Xserve (Intel Xeon) + Xserve2,1 + Xserve (January 2008 quad-core) + iMac1,1 + iMac G3 (Rev A-D) + iMac4,1 + iMac (Core Duo) + iMac4,2 + iMac for Education (17-inch, Core Duo) + iMac5,1 + iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) + iMac5,2 + iMac (Core 2 Duo, 17 inch, Combo Drive) + iMac6,1 + iMac (Core 2 Duo, 24 inch, SuperDrive) + iMac8,1 + iMac (April 2008) + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib new file mode 100644 index 00000000..22f13f8b --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib @@ -0,0 +1,56 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + CLASS + SUStatusController + LANGUAGE + ObjC + OUTLETS + + actionButton + NSButton + progressBar + NSProgressIndicator + + SUPERCLASS + SUWindowController + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib new file mode 100644 index 00000000..a9ac8673 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 10A96 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib new file mode 100644 index 00000000..4f1d5981 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..6b926302 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..b4353d2f Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..b403a3e4 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings new file mode 100644 index 00000000..b31f928f Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..ab36d310 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 658 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9C7010 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..7630390c Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2fb8a837 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 18 + + IBSystem Version + 10A96 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..e7e7497d Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..b1cd28ed --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + 41 + + IBSystem Version + 10A96 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..e8dc5b88 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings new file mode 100644 index 00000000..16e0787b Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..6b2f938f Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..c9b1e7d8 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..3eb7f818 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..8c54c217 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings new file mode 100644 index 00000000..f83ea23c Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..33a60200 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBFramework Version + 629 + IBOldestOS + 5 + IBOpenObjects + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..4cd529a5 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..d2586ea2 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBFramework Version + 629 + IBOldestOS + 5 + IBOpenObjects + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..65dfc95e Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..d2586ea2 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBFramework Version + 629 + IBOldestOS + 5 + IBOpenObjects + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..4b7cc905 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings new file mode 100644 index 00000000..ea175ae7 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/fr.lproj b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/fr.lproj new file mode 120000 index 00000000..88614fe2 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr.lproj/fr.lproj @@ -0,0 +1 @@ +/Users/andym/Development/Build Products/Release/Sparkle.framework/Resources/fr.lproj \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj b/Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj new file mode 120000 index 00000000..88614fe2 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/fr_CA.lproj @@ -0,0 +1 @@ +/Users/andym/Development/Build Products/Release/Sparkle.framework/Resources/fr.lproj \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..15ba8f4c Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2e04cfa0 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..29840645 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..c4934850 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 667 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 5 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..55cc2c27 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings new file mode 100644 index 00000000..5c410d07 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..3f097908 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,18 @@ + + + + + IBFramework Version + 629 + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..aa38f86b Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..d2586ea2 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBFramework Version + 629 + IBOldestOS + 5 + IBOpenObjects + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..c82d3581 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..d2586ea2 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBFramework Version + 629 + IBOldestOS + 5 + IBOpenObjects + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..ac298ce7 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings new file mode 100644 index 00000000..67cf535e Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/relaunch b/Frameworks/Sparkle.framework/Versions/A/Resources/relaunch new file mode 100755 index 00000000..e7b96d61 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/relaunch differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2b3d4257 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..1d4655c5 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..994d4c36 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,67 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + CLASS + NSApplication + LANGUAGE + ObjC + SUPERCLASS + NSResponder + + + ACTIONS + + installUpdate + id + remindMeLater + id + skipThisVersion + id + + CLASS + SUUpdateAlert + LANGUAGE + ObjC + OUTLETS + + delegate + id + description + NSTextField + releaseNotesView + WebView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..2b3d4257 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..103b1cf8 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..0f776c89 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + NSObject + LANGUAGE + ObjC + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..5132e29f --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,18 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + IBSystem Version + 9E17 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..c09d9e70 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings new file mode 100644 index 00000000..f3ff9d86 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..4b1ab30e --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib @@ -0,0 +1,50 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + doNotInstall + id + installLater + id + installNow + id + + CLASS + SUAutomaticUpdateAlert + LANGUAGE + ObjC + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib new file mode 100644 index 00000000..c5a067e8 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 10A96 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..53cb91a9 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib new file mode 100644 index 00000000..018710af --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib @@ -0,0 +1,39 @@ +{ + IBClasses = ( + { + CLASS = FirstResponder; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + }, + { + CLASS = NSApplication; + LANGUAGE = ObjC; + SUPERCLASS = NSResponder; + }, + { + CLASS = NSObject; + LANGUAGE = ObjC; + }, + { + ACTIONS = { + installUpdate = id; + remindMeLater = id; + skipThisVersion = id; + }; + CLASS = SUUpdateAlert; + LANGUAGE = ObjC; + OUTLETS = { + delegate = id; + description = NSTextField; + releaseNotesView = WebView; + }; + SUPERCLASS = SUWindowController; + }, + { + CLASS = SUWindowController; + LANGUAGE = ObjC; + SUPERCLASS = NSWindowController; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib new file mode 100644 index 00000000..6b787d4b --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib @@ -0,0 +1,18 @@ + + + + + IBDocumentLocation + 69 14 356 240 0 0 1280 778 + IBFramework Version + 489.0 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBSystem Version + 9D34 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib new file mode 100644 index 00000000..7e6d490e Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib new file mode 100644 index 00000000..5220a221 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib @@ -0,0 +1,59 @@ + + + + + IBClasses + + + CLASS + SUWindowController + LANGUAGE + ObjC + SUPERCLASS + NSWindowController + + + ACTIONS + + finishPrompt + id + toggleMoreInfo + id + + CLASS + SUUpdatePermissionPrompt + LANGUAGE + ObjC + OUTLETS + + delegate + id + descriptionTextField + NSTextField + moreInfoButton + NSButton + moreInfoView + NSView + + SUPERCLASS + SUWindowController + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + NSObject + LANGUAGE + ObjC + + + IBVersion + 1 + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib new file mode 100644 index 00000000..c5a067e8 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 670 + IBLastKnownRelativeProjectPath + ../Sparkle.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 6 + + IBSystem Version + 10A96 + targetFramework + IBCocoaFramework + + diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib new file mode 100644 index 00000000..64babac1 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings new file mode 100644 index 00000000..b676a4f5 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings differ diff --git a/Frameworks/Sparkle.framework/Versions/A/Sparkle b/Frameworks/Sparkle.framework/Versions/A/Sparkle new file mode 100755 index 00000000..0db0a8f0 Binary files /dev/null and b/Frameworks/Sparkle.framework/Versions/A/Sparkle differ diff --git a/Frameworks/Sparkle.framework/Versions/Current b/Frameworks/Sparkle.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/Frameworks/Sparkle.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Import.xib b/Import.xib deleted file mode 100644 index bf0ccc01..00000000 --- a/Import.xib +++ /dev/null @@ -1,2174 +0,0 @@ - - - - 1060 - 10J567 - 823 - 1038.35 - 462.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 823 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - ImportWindowController - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{196, 267}, {581, 243}} - 544735232 - Import From MySQL Database - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 36 - - YES - - - 256 - - YES - - - 268 - {{274, 47}, {38, 17}} - - YES - - 68288064 - 272630784 - User - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 268 - {{410, 12}, {118, 25}} - - YES - - -2080244224 - 134217728 - Connect - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{310, 44}, {56, 22}} - - YES - - -1804468671 - 272630784 - - - root - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - - - - 268 - {{371, 47}, {57, 17}} - - YES - - 68288064 - 272630784 - Passwd - - - - - - - - - 268 - {{15, 47}, {38, 17}} - - YES - - 68288064 - 272630784 - Host - - - - - - - - - 268 - {{181, 47}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{216, 44}, {53, 22}} - - YES - - -1804468671 - 272630784 - - - 3306 - - YES - - - - - - - 268 - {{58, 44}, {118, 22}} - - YES - - -1804468671 - 272630784 - - - localhost - - YES - - - - - - - 268 - {{432, 44}, {96, 22}} - - YES - - 343014976 - 272630848 - - - password - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{15, 15}, {164, 26}} - - YES - - -1539178944 - 2048 - - - 109199615 - 129 - - - 400 - 75 - - - Choose Database - - 1048576 - 2147483647 - 1 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - - 1 - YES - YES - 2 - - - - {{1, 1}, {546, 76}} - - - - {{17, 131}, {548, 92}} - - {0, 0} - - 67239424 - 0 - Connect to MySQL Database - - LucidaGrande - 11 - 3100 - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - - 36 - - YES - - - 256 - - YES - - - 268 - {{186, 49}, {84, 17}} - - YES - - 68288064 - 272630784 - Chunk Size - - - - - - - - - 268 - {{266, 44}, {50, 22}} - - YES - - -1804468671 - 272630784 - - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - YES - - - YES - - - - - 0 - 0 - YES - NO - 1 - AAAAAAAAAAAAAAAAAAAAAA - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - 500 - - YES - - - - - - - 268 - {{330, 49}, {80, 17}} - - YES - - 68288064 - 272630784 - Collection - - - - - - - - - 268 - {{409, 12}, {118, 25}} - - YES - - -1543373312 - 134217728 - Import - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{405, 44}, {122, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 5388 - - {{16, 13}, {387, 20}} - - 16392 - 1 - - - - 268 - {{15, 44}, {153, 26}} - - YES - - -1539178944 - 2048 - - - 109199615 - 129 - - - 400 - 75 - - - Choose a table - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - - 1 - YES - YES - 2 - - - - {{1, 1}, {545, 78}} - - - - {{17, 16}, {547, 94}} - - {0, 0} - - 67239424 - 0 - Import to MongoDB Collection - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - - - {581, 243} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - - YES - @count - - YES - - YES - YES - YES - YES - YES - - - - YES - value - name - @count - - YES - - YES - YES - YES - YES - YES - - - - - YES - - - window - - - - 3 - - - - delegate - - - - 4 - - - - hostTextField - - - - 51 - - - - portTextField - - - - 52 - - - - userTextField - - - - 53 - - - - passwdTextField - - - - 54 - - - - connect: - - - - 55 - - - - import: - - - - 56 - - - - chunkSizeTextField - - - - 57 - - - - collectionTextField - - - - 58 - - - - progressIndicator - - - - 59 - - - - dbsArrayController - - - - 108 - - - - tablesArrayController - - - - 118 - - - - content: arrangedObjects - - - - - - content: arrangedObjects - content - arrangedObjects - 2 - - - 120 - - - - contentObjects: arrangedObjects.value - - - - - - contentObjects: arrangedObjects.value - contentObjects - arrangedObjects.value - - 2 - - - 123 - - - - contentValues: arrangedObjects.name - - - - - - contentValues: arrangedObjects.name - contentValues - arrangedObjects.name - - 2 - - - 125 - - - - content: arrangedObjects - - - - - - content: arrangedObjects - content - arrangedObjects - 2 - - - 147 - - - - contentObjects: arrangedObjects.value - - - - - - contentObjects: arrangedObjects.value - contentObjects - arrangedObjects.value - - 2 - - - 148 - - - - contentValues: arrangedObjects.name - - - - - - contentValues: arrangedObjects.name - contentValues - arrangedObjects.name - - 2 - - - 150 - - - - enabled: arrangedObjects.@count - - - - - - enabled: arrangedObjects.@count - enabled - arrangedObjects.@count - 2 - - - 151 - - - - enabled: arrangedObjects.@count - - - - - - enabled: arrangedObjects.@count - enabled - arrangedObjects.@count - 2 - - - 152 - - - - enabled: selectedObjects.@count - - - - - - enabled: selectedObjects.@count - enabled - selectedObjects.@count - 2 - - - 154 - - - - showTables: - - - - 156 - - - - tablesPopUpButton - - - - 158 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - 27 - - - YES - - - - - - - - - - - - - - - 15 - - - YES - - - - - - 16 - - - - - 25 - - - YES - - - - - - 26 - - - - - 17 - - - YES - - - - - - 18 - - - - - 19 - - - YES - - - - - - 20 - - - - - 7 - - - YES - - - - - - 8 - - - - - 11 - - - YES - - - - - - 12 - - - - - 13 - - - YES - - - - - - 14 - - - - - 9 - - - YES - - - - - - 10 - - - - - 21 - - - YES - - - - - - 22 - - - - - 48 - - - YES - - - - - - - - - - - - 34 - - - YES - - - - - - 35 - - - - - 36 - - - YES - - - - - - 37 - - - YES - - - - - - 38 - - - - - 39 - - - YES - - - - - - 40 - - - - - 43 - - - YES - - - - - - 44 - - - - - 41 - - - YES - - - - - - 42 - - - - - 45 - - - - - 28 - - - YES - - - - - - 29 - - - YES - - - - - - 30 - - - YES - - - - - - 31 - - - - - 60 - - - YES - - - - - - 61 - - - YES - - - - - - 62 - - - YES - - - - - - 63 - - - - - 79 - - - dbsArrayController - - - 117 - - - tablesArrayController - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 10.IBPluginDependency - 11.IBPluginDependency - 117.IBPluginDependency - 12.IBPluginDependency - 13.IBPluginDependency - 14.IBPluginDependency - 15.IBPluginDependency - 16.IBPluginDependency - 17.IBPluginDependency - 18.IBPluginDependency - 19.IBPluginDependency - 2.IBPluginDependency - 20.IBPluginDependency - 21.IBPluginDependency - 22.IBPluginDependency - 25.IBPluginDependency - 26.IBPluginDependency - 28.IBPluginDependency - 29.IBPluginDependency - 30.IBEditorWindowLastContentRect - 30.IBPluginDependency - 31.IBPluginDependency - 34.IBPluginDependency - 35.IBPluginDependency - 36.IBPluginDependency - 37.IBPluginDependency - 38.IBNumberFormatterBehaviorMetadataKey - 38.IBNumberFormatterLocalizesFormatMetadataKey - 38.IBPluginDependency - 39.IBPluginDependency - 40.IBPluginDependency - 41.IBPluginDependency - 42.IBPluginDependency - 43.IBPluginDependency - 44.IBPluginDependency - 45.IBPluginDependency - 60.IBPluginDependency - 61.IBPluginDependency - 62.IBEditorWindowLastContentRect - 62.IBPluginDependency - 63.IBPluginDependency - 7.IBPluginDependency - 79.IBPluginDependency - 8.IBPluginDependency - 9.IBPluginDependency - - - YES - {{61, 502}, {581, 243}} - com.apple.InterfaceBuilder.CocoaPlugin - {{61, 502}, {581, 243}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{83, 566}, {167, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{83, 652}, {191, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 165 - - - - YES - - ImportWindowController - NSWindowController - - YES - - YES - connect: - import: - showTables: - - - YES - id - id - id - - - - YES - - YES - connect: - import: - showTables: - - - YES - - connect: - id - - - import: - id - - - showTables: - id - - - - - YES - - YES - chunkSizeTextField - collectionTextField - dbsArrayController - hostTextField - passwdTextField - portTextField - progressIndicator - tablesArrayController - tablesPopUpButton - userTextField - - - YES - NSTextField - NSTextField - NSArrayController - NSTextField - NSSecureTextField - NSTextField - NSProgressIndicator - NSArrayController - NSPopUpButton - NSTextField - - - - YES - - YES - chunkSizeTextField - collectionTextField - dbsArrayController - hostTextField - passwdTextField - portTextField - progressIndicator - tablesArrayController - tablesPopUpButton - userTextField - - - YES - - chunkSizeTextField - NSTextField - - - collectionTextField - NSTextField - - - dbsArrayController - NSArrayController - - - hostTextField - NSTextField - - - passwdTextField - NSSecureTextField - - - portTextField - NSTextField - - - progressIndicator - NSProgressIndicator - - - tablesArrayController - NSArrayController - - - tablesPopUpButton - NSPopUpButton - - - userTextField - NSTextField - - - - - IBProjectSource - ImportWindowController.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - NSProgressIndicator - - IBProjectSource - NSProgressIndicator+Extras.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSNumberFormatter - NSFormatter - - IBFrameworkSource - Foundation.framework/Headers/NSNumberFormatter.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - RegexKit.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSProgressIndicator - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSProgressIndicator.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSSecureTextFieldCell - NSTextFieldCell - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - - - YES - {9, 8} - {7, 2} - - - - diff --git a/ImportWindowController.mm b/ImportWindowController.mm deleted file mode 100644 index fe9b2895..00000000 --- a/ImportWindowController.mm +++ /dev/null @@ -1,201 +0,0 @@ -// -// ImportWindowController.m -// MongoHub -// -// Created by Syd on 10-6-16. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "ImportWindowController.h" -#import "Configure.h" -#import "DatabasesArrayController.h" -#import "Database.h" -#import "Connection.h" -#import "NSString+Extras.h" -#import "MongoDB.h" -#import - -@implementation ImportWindowController -@synthesize dbname; -@synthesize conn; -@synthesize db; -@synthesize mongoDB; -@synthesize databasesArrayController; -@synthesize managedObjectContext; -@synthesize dbsArrayController; -@synthesize tablesArrayController; -@synthesize hostTextField; -@synthesize portTextField; -@synthesize userTextField; -@synthesize passwdTextField; -@synthesize chunkSizeTextField; -@synthesize collectionTextField; -@synthesize progressIndicator; -@synthesize tablesPopUpButton; - -- (id)init { - if (![super initWithWindowNibName:@"Import"]) return nil; - return self; -} - -- (void)dealloc { - [dbname release]; - [managedObjectContext release]; - [databasesArrayController release]; - [conn release]; - [db release]; - [mongoDB release]; - [dbsArrayController release]; - [tablesArrayController release]; - [hostTextField release]; - [portTextField release]; - [userTextField release]; - [passwdTextField release]; - [chunkSizeTextField release]; - [collectionTextField release]; - [progressIndicator release]; - [tablesPopUpButton release]; - [super dealloc]; -} - -- (void)windowDidLoad { - //NSLog(@"New Connection Window Loaded"); - [super windowDidLoad]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kImportWindowWillClose object:dbname]; - dbname = nil; - db = nil; - [dbsArrayController setContent:nil]; - [tablesArrayController setContent:nil]; - [progressIndicator setDoubleValue:0.0]; -} - -- (IBAction)import:(id)sender { - [progressIndicator setUsesThreadedAnimation:YES]; - [progressIndicator startAnimation: self]; - [progressIndicator setDoubleValue:0]; - NSString *collection = [[NSString alloc] initWithString:[collectionTextField stringValue]]; - int chunkSize = [chunkSizeTextField intValue]; - if (![collection isPresent]) { - NSRunAlertPanel(@"Error", @"Collection name could not be empty!", @"OK", nil, nil); - return; - } - if (chunkSize == 0) { - NSRunAlertPanel(@"Error", @"Chunk Size could not be 0!", @"OK", nil, nil); - return; - } - NSString *tablename = [[NSString alloc] initWithString:[tablesPopUpButton titleOfSelectedItem]]; - int total = [self importCount:tablename]; - NSString *user=nil; - NSString *password=nil; - Database *mongodb = [databasesArrayController dbInfo:conn name:dbname]; - if (mongodb) { - user = mongodb.user; - password = mongodb.password; - } - [mongodb release]; - [self doImportFromTable:tablename toCollection:collection withChunkSize:chunkSize fromId:0 totalResults:total user:user password:password]; - [progressIndicator stopAnimation: self]; - [tablename release]; - [collection release]; -} - -- (long long int)importCount:(NSString *)tableName -{ - NSString *query = [[NSString alloc] initWithFormat:@"select count(*) counter from %@", tableName]; - MCPResult *theResult = [db queryString:query]; - [query release]; - NSArray *row = [theResult fetchRowAsArray]; - NSLog(@"count: %@", [row objectAtIndex:0]); - return [[row objectAtIndex:0] intValue]; -} - -- (void)doImportFromTable:(NSString *)tableName toCollection:(NSString *)collection withChunkSize:(int)chunkSize fromId:(int)fromId totalResults:(int)total user:(NSString *)user password:(NSString *)password -{ - if (total == 0) return; - NSString *query = [[NSString alloc] initWithFormat:@"select * from %@ limit %d, %d", tableName, fromId, chunkSize]; - NSLog(@"query: %@", query); - MCPResult *theResult = [db queryString:query]; - [query release]; - if ([theResult numOfRows] == 0) { - return; - } - NSArray *theFields = [theResult fetchFieldNames]; - NSDictionary *fieldTypes = [theResult fetchTypesAsDictionary]; - int i = 1; - while (NSDictionary *row = [theResult fetchRowAsDictionary]) { - [progressIndicator setDoubleValue:(double)(fromId+i)/total]; - [mongoDB insertInDB:dbname - collection:collection - user:user - password:password - data:row - fields:theFields - fieldTypes:(NSDictionary *)fieldTypes]; - i++; - } - if ([theResult numOfRows] < chunkSize) { - return; - } - [self doImportFromTable:tableName toCollection:collection withChunkSize:chunkSize fromId:(fromId + chunkSize) totalResults:total user:user password:password]; -} - -- (IBAction)connect:(id)sender { - if (db) { - [dbsArrayController setContent:nil]; - [tablesArrayController setContent:nil]; - [progressIndicator setDoubleValue:0.0]; - [db release]; - } - db = [[MCPConnection alloc] initToHost:[hostTextField stringValue] withLogin:[userTextField stringValue] password:[passwdTextField stringValue] usingPort:[portTextField intValue] ]; - NSLog(@"Connect: %d", [db isConnected]); - if (![db isConnected]) - { - NSRunAlertPanel(@"Error", @"Could not connect to the mysql server!", @"OK", nil, nil); - } - [db queryString:@"SET NAMES utf8"]; - [db queryString:@"SET CHARACTER SET utf8"]; - [db queryString:@"SET COLLATION_CONNECTION='utf8_general_ci'"]; - [db setEncoding:NSUTF8StringEncoding]; - MCPResult *dbs = [db listDBs]; - NSArray *row; - NSMutableArray *databases = [[NSMutableArray alloc] initWithCapacity:[dbs numOfRows]]; - while (row = [dbs fetchRowAsArray]) { - NSDictionary *database = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil]; - [databases addObject:database]; - [database release]; - } - [dbsArrayController setContent:databases]; - [databases release]; -} - -- (IBAction)showTables:(id)sender -{ - NSString *dbn; - if (sender == nil && [[dbsArrayController arrangedObjects] count] > 0) { - dbn = [[[dbsArrayController arrangedObjects] objectAtIndex:0] objectForKey:@"name"]; - }else { - NSPopUpButton *pb = sender; - dbn = [[NSString alloc] initWithString:[pb titleOfSelectedItem]]; - } - if (![dbn isPresent]) { - [dbn release]; - return; - } - [db selectDB:dbn]; - [dbn release]; - MCPResult *tbs = [db listTables]; - NSArray *row; - NSMutableArray *tables = [[NSMutableArray alloc] initWithCapacity:[tbs numOfRows]]; - while (row = [tbs fetchRowAsArray]) { - NSDictionary *table = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil]; - [tables addObject:table]; - [table release]; - } - [tablesArrayController setContent:tables]; - [tables release]; -} - -@end diff --git a/Importer/GetMetadataForFile.c b/Importer/GetMetadataForFile.c deleted file mode 100644 index 542f90e0..00000000 --- a/Importer/GetMetadataForFile.c +++ /dev/null @@ -1,83 +0,0 @@ -// -// GetMetadataForFile.c -// MongoHub Spotlight Importer -// -// Created by Syd on 10-4-24. -// Copyright (c) 2010 MusicPeace.ORG. All rights reserved. -// - -#include -#import - -#import "MySpotlightImporter.h" - - -//============================================================================== -// -// Get metadata attributes from document files -// -// The purpose of this function is to extract useful information from the -// file formats for your document, and set the values into the attribute -// dictionary for Spotlight to include. -// -//============================================================================== - - -Boolean GetMetadataForFile(void* thisInterface, - CFMutableDictionaryRef attributes, - CFStringRef contentTypeUTI, - CFStringRef pathToFile) -{ - /* Pull any available metadata from the file at the specified path */ - /* Return the attribute keys and attribute values in the dict */ - /* Return TRUE if successful, FALSE if there was no data provided */ - /* The path could point to either a Core Data store file in which */ - /* case we import the store's metadata, or it could point to a Core */ - /* Data external record file for a specific record instances */ - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSError *error = nil; - Boolean ok = FALSE; - - if ([(NSString *)contentTypeUTI isEqualToString:@"YOUR_STORE_FILE_UTI"]) { - - // import from store file metadata - - // Create the URL, then attempt to get the meta-data from the store - NSURL *url = [NSURL fileURLWithPath: (NSString *)pathToFile]; - NSDictionary *metadata = [NSPersistentStoreCoordinator - metadataForPersistentStoreOfType:nil URL:url error:&error]; - - // If there is no error, add the info - if ( error == NULL ) { - - // Get the information you are interested in from the dictionary - // "YOUR_INFO" should be replaced by key(s) you are interested in - - NSObject *contentToIndex = [metadata objectForKey: @"YOUR_INFO"]; - if ( contentToIndex != nil ) { - - // Add the metadata to the text content for indexing - [(NSMutableDictionary *)attributes setObject:contentToIndex - forKey:(NSString *)kMDItemTextContent]; - ok = TRUE; - } - } - - } else if ([(NSString *)contentTypeUTI isEqualToString:@"YOUR_EXTERNAL_RECORD_UTI"]) { - - // import from an external record file - - MySpotlightImporter *importer = [[MySpotlightImporter alloc] init]; - - ok = [importer importFileAtPath:(NSString *)pathToFile attributes:(NSMutableDictionary *)attributes error:&error]; - [importer release]; - - } - - - // Return the status - [pool drain]; - - return ok; -} diff --git a/Importer/Importer Read Me.txt b/Importer/Importer Read Me.txt deleted file mode 100644 index e4d47eec..00000000 --- a/Importer/Importer Read Me.txt +++ /dev/null @@ -1,64 +0,0 @@ - -//============================================================================== -// Core Data Application Spotlight Importer -//============================================================================== - -Spotlight importers should be provided by all applications that support custom -document formats. A Spotlight importer parses your document format for relevant -information and assigning that information to the appropriate metadata keys. - -The bundle target in this project creates a Spotlight importer bundle installed -inside of the wrapper of the application target. This bundle includes all of -the code necessary to import two types of information into Spotlight: - -1) The metadata information from Core Data stores. - -The only default metadata for a Core Data store is the store ID and store type, -neither of which is imported. To have metadata from your stores imported, you -must first add the information you are interested to the metadata for your -store (see the NSPersistentStoreCoordinator setMetadataForPersistentStore: API) -and then pull the information for import in the GetMetadataForFile function in -the 'GetMetadataForFile.c' file. - -2) Instance Level indexing information - - For each instance of an entity that contains properties indexed by Spotlight -(defined in your Core Data Model), the importer will extract the values. This -extraction is done in MySpotlightImporter.m - -Additionally, the importer must contain a list of the Uniform Type Identifiers -(UTI) for your application in order to import the data. (The UTI information is -used by Spotlight to know which importer to invoke for a given file.) If the -UTI is not already registered by your application, you will need to register it -in the importer bundle. (For more information on registering UTIs for -applications, consult the documentation at http://developer.apple.com) - ------------------------------------------------------------------------------ - -To configure this project - -Search for all occurrences of the string YOUR_ and replace with the appropriate - values - -When importing store file metadata - -YOUR_STORE_FILE_UTI - UTI of your store file -YOUR_INFO - metadata information you want Spotlight to have for - your store file - -when importing record level information - -YOUR_EXTERNAL_RECORD_UTI - UTI of the Core Data Spotlight external record file -YOUR_EXTERNAL_RECORD_EXTENSION - extension of the Core Data external record file -YOUR_STORE_TYPE - type of your persistent store - -Replace occurences of the above strings in the following files - - -GetMetadataForFile.c -MySpotlightImporter.m -Importer-Info.plist -Info.plist - - ------------------------------------------------------------------------------ diff --git a/Importer/Importer-Info.plist b/Importer/Importer-Info.plist deleted file mode 100644 index 5b47a376..00000000 --- a/Importer/Importer-Info.plist +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - UTExportedTypeDeclarations - - - UTTypeIdentifier - YOUR_EXTERNAL_RECORD_UTI - UTTypeReferenceURL - http://www.company.com/yourproduct - UTTypeDescription - Your Document Kind String - UTTypeConformsTo - - public.data - public.content - - UTTypeTagSpecification - - com.apple.ostype - XXXX - public.filename-extension - - YOUR_EXTERNAL_RECORD_EXTENSION - - - - - - - - CFBundleDevelopmentRegion - English - CFBundleDocumentTypes - - - CFBundleTypeRole - MDImporter - LSItemContentTypes - - YOUR_EXTERNAL_RECORD_UTI - - - - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleName - ${PRODUCT_NAME} - CFBundleIconFile - - CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:rfc1034identifier}.spotlightimporter - CFBundleInfoDictionaryVersion - 6.0 - CFBundleVersion - 1.0 - CFPlugInDynamicRegisterFunction - - CFPlugInDynamicRegistration - NO - CFPlugInFactories - - E0C38F20-64C0-4B5E-98E5-834069A86AD4 - MetadataImporterPluginFactory - - CFPlugInTypes - - 8B08C4BF-415B-11D8-B3F9-0003936726FC - - E0C38F20-64C0-4B5E-98E5-834069A86AD4 - - - CFPlugInUnloadFunction - - LSMinimumSystemVersion - ${MACOSX_DEPLOYMENT_TARGET} - - diff --git a/Importer/MySpotlightImporter.h b/Importer/MySpotlightImporter.h deleted file mode 100644 index fb6f2f00..00000000 --- a/Importer/MySpotlightImporter.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// MySpotlightImporter.h -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright MusicPeace.ORG 2010 . All rights reserved. -// - -#import - - -@interface MySpotlightImporter : NSObject { - - NSPersistentStoreCoordinator *persistentStoreCoordinator; - NSManagedObjectModel *managedObjectModel; - NSManagedObjectContext *managedObjectContext; - - NSURL *modelURL; - NSURL *storeURL; -} - -@property (nonatomic, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; -@property (nonatomic, readonly) NSManagedObjectModel *managedObjectModel; -@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext; - -- (BOOL)importFileAtPath:(NSString *)filePath attributes:(NSMutableDictionary *)attributes error:(NSError **)error; - -@end diff --git a/Importer/MySpotlightImporter.m b/Importer/MySpotlightImporter.m deleted file mode 100644 index 176f26ff..00000000 --- a/Importer/MySpotlightImporter.m +++ /dev/null @@ -1,169 +0,0 @@ -// -// MySpotlightImporter.m -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright MusicPeace.ORG 2010 . All rights reserved. -// - -#import "MySpotlightImporter.h" - -#define YOUR_STORE_TYPE NSXMLStoreType - -@interface MySpotlightImporter () -@property (nonatomic, retain) NSURL *modelURL; -@property (nonatomic, retain) NSURL *storeURL; -@end - -@implementation MySpotlightImporter - -@synthesize modelURL, storeURL; - -- (BOOL)importFileAtPath:(NSString *)filePath attributes:(NSMutableDictionary *)spotlightData error:(NSError **)error { - - NSDictionary *pathInfo = [NSPersistentStoreCoordinator elementsDerivedFromExternalRecordURL:[NSURL fileURLWithPath:filePath]]; - - self.modelURL = [NSURL fileURLWithPath:[pathInfo valueForKey:NSModelPathKey]]; - self.storeURL = [NSURL fileURLWithPath:[pathInfo valueForKey:NSStorePathKey]]; - - - NSURL *objectURI = [pathInfo valueForKey:NSObjectURIKey]; - NSManagedObjectID *oid = [[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:objectURI]; - - if (!oid) { - NSLog(@"%@:%s to find object id from path %@", [self class], _cmd, filePath); - return NO; - } - - NSManagedObject *instance = [[self managedObjectContext] objectWithID:oid]; - - // how you process each instance will depend on the entity that the instance belongs to - - if ([[[instance entity] name] isEqualToString:@"YOUR_ENTITY_NAME"]) { - - // set the display name for Spotlight search result - - NSString *yourDisplayString = [NSString stringWithFormat:@"YOUR_DISPLAY_STRING %@",[instance valueForKey:@"SOME_KEY"]]; - [spotlightData setObject: yourDisplayString forKey:(NSString *)kMDItemDisplayName]; - - /* - Determine how you want to store the instance information in 'spotlightData' dictionary. - For each property, pick the key kMDItem... from MDItem.h that best fits its content. - If appropriate, aggregate the values of multiple properties before setting them in the dictionary. - For relationships, you may want to flatten values. - - id YOUR_FIELD_VALUE = [instance valueForKey: ATTRIBUTE_NAME]; - [spotlightData setObject: YOUR_FIELD_VALUE forKey: (NSString *) kMDItem...]; - ... more property values; - To determine if a property should be indexed, call isIndexedBySpotlight - - */ - - } - - return YES; -} - -- (void)dealloc { - - [managedObjectContext release]; - [persistentStoreCoordinator release]; - [managedObjectModel release]; - [modelURL release]; - [storeURL release]; - - [super dealloc]; -} - -/** - Returns the managed object model. - The last read model is cached in a global variable and reused - if the URL and modification date are identical - */ -static NSURL *cachedModelURL = nil; -static NSManagedObjectModel *cachedModel = nil; -static NSDate *cachedModelModificationDate =nil; - -- (NSManagedObjectModel *)managedObjectModel { - - if (managedObjectModel != nil) return managedObjectModel; - - NSDictionary *modelFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[modelURL path] error:nil]; - NSDate *modelModificationDate = [modelFileAttributes objectForKey:NSFileModificationDate]; - - if ([cachedModelURL isEqual:modelURL] && [modelModificationDate isEqualToDate:cachedModelModificationDate]) { - managedObjectModel = [cachedModel retain]; - } - - if (!managedObjectModel) { - managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; - - if (!managedObjectModel) { - NSLog(@"%@:%s unable to load model at URL %@", [self class], _cmd, modelURL); - return nil; - } - - // Clear out all custom classes used by the model to avoid having to link them - // with the importer. Remove this code if you need to access your custom logic. - NSString *managedObjectClassName = [NSManagedObject className]; - for (NSEntityDescription *entity in managedObjectModel) { - [entity setManagedObjectClassName:managedObjectClassName]; - } - - // cache last loaded model - - [cachedModelURL release]; - cachedModelURL = [modelURL retain]; - [cachedModel release]; - cachedModel = [managedObjectModel retain]; - [cachedModelModificationDate release]; - cachedModelModificationDate = [modelModificationDate retain]; - } - - return managedObjectModel; -} - -/** - Returns the persistent store coordinator for the importer. - */ - -- (NSPersistentStoreCoordinator *) persistentStoreCoordinator { - - if (persistentStoreCoordinator) return persistentStoreCoordinator; - - NSError *error = nil; - - persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; - if (![persistentStoreCoordinator addPersistentStoreWithType:YOUR_STORE_TYPE - configuration:nil - URL:storeURL - options:nil - error:&error]){ - NSLog(@"%@:%s unable to add persistent store coordinator - %@", [self class], _cmd, error); - } - - return persistentStoreCoordinator; -} - -/** - Returns the managed object context for the importer; already - bound to the persistent store coordinator. - */ - -- (NSManagedObjectContext *) managedObjectContext { - - if (managedObjectContext) return managedObjectContext; - - NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; - if (!coordinator) { - NSLog(@"%@:%s unable to get persistent store coordinator", [self class], _cmd); - return nil; - } - - managedObjectContext = [[NSManagedObjectContext alloc] init]; - [managedObjectContext setPersistentStoreCoordinator: coordinator]; - - return managedObjectContext; -} - -@end diff --git a/Importer/main.c b/Importer/main.c deleted file mode 100644 index c2837c8d..00000000 --- a/Importer/main.c +++ /dev/null @@ -1,224 +0,0 @@ -// -// main.c -// MongoHub Spotlight Importer -// -// Created by Syd on 10-4-24. -// Copyright (c) 2010 MusicPeace.ORG. All rights reserved. -// - - - - - -//============================================================================== -// -// DO NO MODIFY THE CONTENT OF THIS FILE -// -// This file contains the generic CFPlug-in code necessary for your importer -// To complete your importer implement the function in GetMetadataForFile.c -// -//============================================================================== - - - - - -#import -#import -#import - -// ----------------------------------------------------------------------------- -// constants -// ----------------------------------------------------------------------------- - - -#define PLUGIN_ID "E0C38F20-64C0-4B5E-98E5-834069A86AD4" - -// -// Below is the generic glue code for all plug-ins. -// -// You should not have to modify this code aside from changing -// names if you decide to change the names defined in the Info.plist -// - - -// ----------------------------------------------------------------------------- -// typedefs -// ----------------------------------------------------------------------------- - -// The import function to be implemented in GetMetadataForFile.c -Boolean GetMetadataForFile(void *thisInterface, - CFMutableDictionaryRef attributes, - CFStringRef contentTypeUTI, - CFStringRef pathToFile); - -// The layout for an instance of MetaDataImporterPlugIn -typedef struct __MetadataImporterPluginType -{ - MDImporterInterfaceStruct *conduitInterface; - CFUUIDRef factoryID; - UInt32 refCount; -} MetadataImporterPluginType; - -// ----------------------------------------------------------------------------- -// prototypes -// ----------------------------------------------------------------------------- -// Forward declaration for the IUnknown implementation. -// - -MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID); -void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance); -HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); -void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); -ULONG MetadataImporterPluginAddRef(void *thisInstance); -ULONG MetadataImporterPluginRelease(void *thisInstance); -// ----------------------------------------------------------------------------- -// testInterfaceFtbl definition -// ----------------------------------------------------------------------------- -// The TestInterface function table. -// - -static MDImporterInterfaceStruct testInterfaceFtbl = { - NULL, - MetadataImporterQueryInterface, - MetadataImporterPluginAddRef, - MetadataImporterPluginRelease, - GetMetadataForFile -}; - - -// ----------------------------------------------------------------------------- -// AllocMetadataImporterPluginType -// ----------------------------------------------------------------------------- -// Utility function that allocates a new instance. -// You can do some initial setup for the importer here if you wish -// like allocating globals etc... -// -MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID) -{ - MetadataImporterPluginType *theNewInstance; - - theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType)); - memset(theNewInstance,0,sizeof(MetadataImporterPluginType)); - - /* Point to the function table */ - theNewInstance->conduitInterface = &testInterfaceFtbl; - - /* Retain and keep an open instance refcount for each factory. */ - theNewInstance->factoryID = CFRetain(inFactoryID); - CFPlugInAddInstanceForFactory(inFactoryID); - - /* This function returns the IUnknown interface so set the refCount to one. */ - theNewInstance->refCount = 1; - return theNewInstance; -} - -// ----------------------------------------------------------------------------- -// DeallocMongoHubMDImporterPluginType -// ----------------------------------------------------------------------------- -// Utility function that deallocates the instance when -// the refCount goes to zero. -// In the current implementation importer interfaces are never deallocated -// but implement this as this might change in the future -// -void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance) -{ - CFUUIDRef theFactoryID; - - theFactoryID = thisInstance->factoryID; - free(thisInstance); - if (theFactoryID){ - CFPlugInRemoveInstanceForFactory(theFactoryID); - CFRelease(theFactoryID); - } -} - -// ----------------------------------------------------------------------------- -// MetadataImporterQueryInterface -// ----------------------------------------------------------------------------- -// Implementation of the IUnknown QueryInterface function. -// -HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) -{ - CFUUIDRef interfaceID; - - interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); - - if (CFEqual(interfaceID,kMDImporterInterfaceID)){ - /* If the Right interface was requested, bump the ref count, - * set the ppv parameter equal to the instance, and - * return good status. - */ - ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance); - *ppv = thisInstance; - CFRelease(interfaceID); - return S_OK; - }else{ - if (CFEqual(interfaceID,IUnknownUUID)){ - /* If the IUnknown interface was requested, same as above. */ - ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance); - *ppv = thisInstance; - CFRelease(interfaceID); - return S_OK; - }else{ - /* Requested interface unknown, bail with error. */ - *ppv = NULL; - CFRelease(interfaceID); - return E_NOINTERFACE; - } - } -} - -// ----------------------------------------------------------------------------- -// MetadataImporterPluginAddRef -// ----------------------------------------------------------------------------- -// Implementation of reference counting for this type. Whenever an interface -// is requested, bump the refCount for the instance. NOTE: returning the -// refcount is a convention but is not required so don't rely on it. -// -ULONG MetadataImporterPluginAddRef(void *thisInstance) -{ - ((MetadataImporterPluginType *)thisInstance )->refCount += 1; - return ((MetadataImporterPluginType*) thisInstance)->refCount; -} - -// ----------------------------------------------------------------------------- -// SampleCMPluginRelease -// ----------------------------------------------------------------------------- -// When an interface is released, decrement the refCount. -// If the refCount goes to zero, deallocate the instance. -// -ULONG MetadataImporterPluginRelease(void *thisInstance) -{ - ((MetadataImporterPluginType*)thisInstance)->refCount -= 1; - if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){ - DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance ); - return 0; - }else{ - return ((MetadataImporterPluginType*) thisInstance )->refCount; - } -} - -// ----------------------------------------------------------------------------- -// MongoHubMDImporterPluginFactory -// ----------------------------------------------------------------------------- -// Implementation of the factory function for this type. -// -void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) -{ - MetadataImporterPluginType *result; - CFUUIDRef uuid; - - /* If correct type is being requested, allocate an - * instance of TestType and return the IUnknown interface. - */ - if (CFEqual(typeID,kMDImporterTypeID)){ - uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); - result = AllocMetadataImporterPluginType(uuid); - CFRelease(uuid); - return result; - } - /* If the requested type is incorrect, return NULL. */ - return NULL; -} - diff --git a/JSON/JsonWindowController.h b/JSON/JsonWindowController.h deleted file mode 100644 index 30a67c4f..00000000 --- a/JSON/JsonWindowController.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// JsonWindowController.h -// MongoHub -// -// Created by Syd on 10-12-27. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import -#import "UKSyntaxColoredTextViewController.h" -@class DatabasesArrayController; -@class Connection; -@class MongoDB; - -#ifndef UKSCTD_DEFAULT_TEXTENCODING -#define UKSCTD_DEFAULT_TEXTENCODING NSUTF8StringEncoding -#endif - -@interface JsonWindowController : NSWindowController { - NSManagedObjectContext *managedObjectContext; - DatabasesArrayController *databaseArrayController; - Connection *conn; - MongoDB *mongoDB; - NSString *dbname; - NSString *collectionname; - NSDictionary *jsonDict; - IBOutlet NSTextView *myTextView; - IBOutlet NSProgressIndicator *progress; - IBOutlet NSTextField *status; - UKSyntaxColoredTextViewController *syntaxColoringController; -} - -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, retain) DatabasesArrayController *databasesArrayController; -@property (nonatomic, retain) MongoDB *mongoDB; -@property (nonatomic, retain) NSString *dbname; -@property (nonatomic, retain) NSString *collectionname; -@property (nonatomic, retain) Connection *conn; -@property (nonatomic, retain) NSDictionary *jsonDict; -@property (nonatomic, retain) NSTextView *myTextView; - --(IBAction) save:(id)sender; --(void) doSave; --(IBAction) recolorCompleteFile: (id)sender; - -@end diff --git a/JSON/JsonWindowController.mm b/JSON/JsonWindowController.mm deleted file mode 100644 index 1e266d6f..00000000 --- a/JSON/JsonWindowController.mm +++ /dev/null @@ -1,153 +0,0 @@ -// -// JsonWindowController.m -// MongoHub -// -// Created by Syd on 10-12-27. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "JsonWindowController.h" -#import "Configure.h" -#import "NSProgressIndicator+Extras.h" -#import "DatabasesArrayController.h" -#import "Connection.h" -#import "MongoDB.h" -#import "NSString+Extras.h" - -@implementation JsonWindowController -@synthesize managedObjectContext; -@synthesize databasesArrayController; -@synthesize mongoDB; -@synthesize conn; -@synthesize dbname; -@synthesize collectionname; -@synthesize jsonDict; -@synthesize myTextView; - -- (id)init { - if (![super initWithWindowNibName:@"JsonWindow"]) return nil; - return self; -} - -- (void)dealloc { - [managedObjectContext release]; - [databasesArrayController release]; - [conn release]; - [mongoDB release]; - [dbname release]; - [collectionname release]; - [jsonDict release]; - [myTextView release]; - [syntaxColoringController setDelegate: nil]; - [syntaxColoringController release]; - syntaxColoringController = nil; - [progress release]; - [super dealloc]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kJsonWindowWillClose object:nil]; - [super release]; -} - -- (void)windowDidLoad { - [super windowDidLoad]; - NSString *title = [[NSString alloc] initWithFormat:@"%@.%@ _id:%@", dbname, collectionname, [jsonDict objectForKey:@"value"]]; - [self.window setTitle:title]; - [title release]; - [myTextView setString:[jsonDict objectForKey:@"beautified"]]; - syntaxColoringController = [[UKSyntaxColoredTextViewController alloc] init]; - [syntaxColoringController setDelegate: self]; - [syntaxColoringController setView: myTextView]; -} - - --(void) textViewControllerWillStartSyntaxRecoloring: (UKSyntaxColoredTextViewController*)sender -{ - // Show your progress indicator. - [progress startAnimation: self]; - [progress display]; -} - - --(void) textViewControllerDidFinishSyntaxRecoloring: (UKSyntaxColoredTextViewController*)sender -{ - // Hide your progress indicator. - [progress stopAnimation: self]; - [progress display]; -} - --(NSString *)syntaxDefinitionFilenameForTextViewController: (UKSyntaxColoredTextViewController*)sender -{ - return @"JSON"; -} - --(void) selectionInTextViewController: (UKSyntaxColoredTextViewController*)sender // Update any selection status display. - changedToStartCharacter: (NSUInteger)startCharInLine endCharacter: (NSUInteger)endCharInLine - inLine: (NSUInteger)lineInDoc startCharacterInDocument: (NSUInteger)startCharInDoc - endCharacterInDocument: (NSUInteger)endCharInDoc; -{ - NSString* statusMsg = nil; - - if( startCharInDoc < endCharInDoc ) - { - statusMsg = NSLocalizedString(@"character %lu to %lu of line %lu (%lu to %lu in document).",@"selection description in syntax colored text documents."); - statusMsg = [NSString stringWithFormat: statusMsg, startCharInLine +1, endCharInLine +1, lineInDoc +1, startCharInDoc +1, endCharInDoc +1]; - } - else - { - statusMsg = NSLocalizedString(@"character %lu of line %lu (%lu in document).",@"insertion mark description in syntax colored text documents."); - statusMsg = [NSString stringWithFormat: statusMsg, startCharInLine +1, lineInDoc +1, startCharInDoc +1]; - } - - [status setStringValue: statusMsg]; - [status display]; -} - -/* ----------------------------------------------------------------------------- - recolorCompleteFile: - IBAction to do a complete recolor of the whole friggin' document. - -------------------------------------------------------------------------- */ - --(IBAction) recolorCompleteFile: (id)sender -{ - [syntaxColoringController recolorCompleteFile: sender]; -} - --(IBAction) save:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doSave) toTarget:self withObject:nil]; -} - --(void) doSave -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [status setStringValue: @"Saving..."]; - [status display]; - [progress startAnimation: self]; - [progress display]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *_id = nil; - if ([[jsonDict objectForKey:@"type"] isEqualToString:@"ObjectId"]) { - _id = [NSString stringWithFormat:@"ObjectId(\"%@\")", [jsonDict objectForKey:@"value"]]; - }else { - _id = [NSString stringWithFormat:@"\"%@\"", [jsonDict objectForKey:@"value"]]; - } - NSMutableString *json = [[NSMutableString alloc] initWithString:[myTextView string]]; - [mongoDB saveInDB:dbname collection:collectionname user:user password:password jsonString:json _id:_id]; - [json release]; - [progress stopAnimation: self]; - [progress display]; - [status setStringValue: @"Saved"]; - [status display]; - [[NSNotificationCenter defaultCenter] postNotificationName:kJsonWindowSaved object:nil]; - [pool release]; -} -@end diff --git a/JsonWindow.xib b/JsonWindow.xib deleted file mode 100644 index 14dd9c31..00000000 --- a/JsonWindow.xib +++ /dev/null @@ -1,1332 +0,0 @@ - - - - 1060 - 10H574 - 804 - 1038.35 - 461.00 - - YES - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - - YES - 804 - 1.2.5 - - - - YES - - - - YES - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - JsonWindowController - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{196, 159}, {490, 351}} - 544735232 - Window - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 274 - - YES - - - 2304 - - YES - - - 2322 - - YES - - YES - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - Apple URL pasteboard type - CorePasteboardFlavorType 0x6D6F6F76 - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - NeXT font pasteboard type - NeXT ruler pasteboard type - WebURLsWithTitlesPboardType - public.url - - - {490, 319} - - 2 - - - - - - - - - - YES - - - 134 - - - - 490 - 1 - - - 33828675 - 0 - - - 3 - MCAwAA - - - YES - - YES - NSBackgroundColor - NSColor - - - YES - - 6 - System - selectedTextBackgroundColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - selectedTextColor - - 3 - MAA - - - - - - 3 - MQA - - - YES - - YES - NSColor - NSCursor - NSUnderline - - - YES - - 1 - MCAwIDEAA - - - {8, -8} - 13 - - - - - - - 6 - {490, 1e+07} - {223, 319} - - - - {490, 319} - - - 2 - - - - {4, -5} - 1 - - 4 - - - - -2147483392 - {{-100, -100}, {15, 302}} - - 2 - - _doScroller: - 0.99248123168945312 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - 2 - 1 - - _doScroller: - 1 - 0.94565218687057495 - - - {{0, -1}, {490, 319}} - - - 2 - 528 - - - - - - - 266 - - YES - - - 268 - {{20, 4}, {61, 25}} - - 2 - YES - - -2080244224 - 134217728 - Save - - LucidaGrande - 13 - 1044 - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{89, 4}, {63, 25}} - - 2 - YES - - -2080244224 - 134217728 - Cancel - - - -2038152961 - 163 - - - 400 - 75 - - - - - -2147482359 - - {{454, 8}, {16, 16}} - - 2 - 20746 - 100 - - - - -2147483380 - {{157, 8}, {292, 16}} - - 2 - YES - - 68288064 - 71304192 - Label - - LucidaGrande - 12 - 16 - - - - 6 - System - controlColor - - - - 1 - MC4yMDAwMDAwMDMgMC4yMDAwMDAwMDMgMC4yMDAwMDAwMDMAA - - - - - {{0, 318}, {490, 33}} - - 2 - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - {490, 351} - - 2 - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - - - YES - - - window - - - - 3 - - - - myTextView - - - - 10 - - - - delegate - - - - 18 - - - - initialFirstResponder - - - - 19 - - - - progress - - - - 21 - - - - performClose: - - - - 22 - - - - status - - - - 25 - - - - save: - - - - 26 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - 6 - - - YES - - - - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 11 - - - YES - - - - - - - - - 12 - - - YES - - - - - - 13 - - - - - 16 - - - YES - - - - - - 17 - - - - - 20 - - - - - 23 - - - YES - - - - - - 24 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 11.IBPluginDependency - 12.IBPluginDependency - 13.IBPluginDependency - 16.IBPluginDependency - 16.IBViewBoundsToFrameTransform - 17.IBPluginDependency - 2.IBPluginDependency - 20.IBPluginDependency - 20.IBViewBoundsToFrameTransform - 23.IBPluginDependency - 23.IBViewBoundsToFrameTransform - 24.IBPluginDependency - 6.IBPluginDependency - 6.IBViewBoundsToFrameTransform - 7.IBPluginDependency - 8.IBPluginDependency - 9.IBPluginDependency - 9.IBViewIntegration.shadowColor - - - YES - {{122, 389}, {490, 351}} - com.apple.InterfaceBuilder.CocoaPlugin - {{122, 389}, {490, 351}} - - {196, 240} - {{202, 428}, {480, 270}} - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDEgAAwdgAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABD4wAAwcgAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDHQAAwagAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABAoAAAw5yAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 42 - - - - YES - - JsonWindowController - NSWindowController - - YES - - YES - recolorCompleteFile: - save: - - - YES - id - id - - - - YES - - YES - recolorCompleteFile: - save: - - - YES - - recolorCompleteFile: - id - - - save: - id - - - - - YES - - YES - myTextView - progress - status - - - YES - NSTextView - NSProgressIndicator - NSTextField - - - - YES - - YES - myTextView - progress - status - - - YES - - myTextView - NSTextView - - - progress - NSProgressIndicator - - - status - NSTextField - - - - - IBProjectSource - JSON/JsonWindowController.h - - - - NSObject - - IBProjectSource - JSON/NSObject+SBJSON.h - - - - NSObject - - IBProjectSource - JSON/SBJsonWriter.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - NSProgressIndicator - - IBProjectSource - NSProgressIndicator+Extras.h - - - - - YES - - BWGradientBox - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWGradientBox.h - - - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSProgressIndicator - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSProgressIndicator.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSScrollView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSScrollView.h - - - - NSScroller - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSScroller.h - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - diff --git a/Libraries/MongoObjCDriver b/Libraries/MongoObjCDriver new file mode 160000 index 00000000..1901c907 --- /dev/null +++ b/Libraries/MongoObjCDriver @@ -0,0 +1 @@ +Subproject commit 1901c9079f2d4c14c588da30061fc0793db037c7 diff --git a/Libraries/MongoObjCDriver.sha1 b/Libraries/MongoObjCDriver.sha1 new file mode 100644 index 00000000..c85dc9f5 --- /dev/null +++ b/Libraries/MongoObjCDriver.sha1 @@ -0,0 +1 @@ +2b1b836a95507622fafabfcc1c8c700b8de5076f diff --git a/MongoDB.h b/MongoDB.h deleted file mode 100644 index 8ec83813..00000000 --- a/MongoDB.h +++ /dev/null @@ -1,141 +0,0 @@ -// -// Mongo.h -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import -#import - -@interface MongoDB : NSObject { - mongo::DBClientConnection *conn; - mongo::DBClientReplicaSet::DBClientReplicaSet *repl_conn; - BOOL isRepl; -} -- (mongo::DBClientConnection *)mongoConnection; -- (mongo::DBClientReplicaSet::DBClientReplicaSet *)mongoReplConnection; - -- (id)initWithConn:(NSString *)host; -- (id)initWithConn:(NSString *)name - hosts:(NSArray *)hosts; -- (bool)connect:(NSString *)host; -- (bool)connect:(NSString *)name - hosts:(NSArray *)hosts; -- (bool)authUser:(NSString *)user - pass:(NSString *)pass - database:(NSString *)db; -- (NSArray *)listDatabases; -- (NSArray *)listCollections:(NSString *)db - user:(NSString *)user - password:(NSString *)password; -- (NSMutableArray *) serverStatus; -- (NSMutableArray *) dbStats:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password; -- (void) dropDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password; -- (NSMutableArray *) collStats:(NSString *)collectionname - forDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password; -- (void) createCollection:(NSString *)collectionname - forDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password; -- (void) dropCollection:(NSString *)collectionname - forDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password; -- (NSMutableArray *) findInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical - fields:(NSString *)fields - skip:(NSNumber *)skip - limit:(NSNumber *)limit - sort:(NSString *)sort; -- (void) saveInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - jsonString:(NSString *)jsonString - _id:(NSString *)_id; -- (void) updateInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical - fields:(NSString *)fields - upset:(NSNumber *)upset; -- (void) removeInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical; -- (void) insertInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - insertData:(NSString *)insertData; -- (void) insertInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - data:(NSDictionary *)insertData - fields:(NSArray *)fields - fieldTypes:(NSDictionary *)fieldTypes; -- (NSMutableArray *) indexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password; -- (void) ensureIndexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - indexData:(NSString *)indexData; -- (void) reIndexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password; -- (void) dropIndexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - indexName:(NSString *)indexName; -- (long long int) countInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical; -- (NSMutableArray *)mapReduceInDB:dbname - collection:collectionname - user:user - password:password - mapJs:mapFunction - reduceJs:reduceFunction - critical:critical - output:output; -- (NSMutableArray *) bsonDictWrapper:(mongo::BSONObj)retval; -- (NSMutableArray *) bsonArrayWrapper:(mongo::BSONObj)retval; - -- (std::auto_ptr) findAllCursorInDB:(NSString *)dbname collection:(NSString *)collectionname user:(NSString *)user password:(NSString *)password fields:(mongo::BSONObj) fields; - -- (std::auto_ptr) findCursorInDB:(NSString *)dbname collection:(NSString *)collectionname user:(NSString *)user password:(NSString *)password critical:(NSString *)critical fields:(NSString *)fields skip:(NSNumber *)skip limit:(NSNumber *)limit sort:(NSString *)sort; - -- (void) updateBSONInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(mongo::Query)critical - fields:(mongo::BSONObj)fields - upset:(bool)upset; - -- (mongo::BSONObj) serverStat; -- (NSDictionary *) serverMonitor:(mongo::BSONObj)a second:(mongo::BSONObj)b currentDate:(NSDate *)now previousDate:(NSDate *)previous; -- (double) diff:(NSString *)aName first:(mongo::BSONObj)a second:(mongo::BSONObj)b timeInterval:(NSTimeInterval)interval; -- (double) percent:(NSString *)aOut value:(NSString *)aVal first:(mongo::BSONObj)a second:(mongo::BSONObj)b; -@end diff --git a/MongoDB.mm b/MongoDB.mm deleted file mode 100644 index 36d84c20..00000000 --- a/MongoDB.mm +++ /dev/null @@ -1,1229 +0,0 @@ -// -// Mongo.mm -// MongoHub -// -// Created by Syd on 10-4-25. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "MongoDB.h" -#import "NSString+Extras.h" -#import -#import - -@implementation MongoDB - -- (id)init { - self = [super init]; - return self; -} - -- (mongo::DBClientConnection *)mongoConnection -{ - return conn; -} - -- (mongo::DBClientReplicaSet::DBClientReplicaSet *)mongoReplConnection -{ - return repl_conn; -} - -- (id)initWithConn:(NSString *)host { - self = [super init]; - isRepl = NO; - [self connect:host]; - return self; -} - -- (id)initWithConn:(NSString *)name hosts:(NSArray *)hosts { - self = [super init]; - isRepl = YES; - [self connect:name hosts:hosts]; - return self; -} - -- (void)dealloc { - [super dealloc]; -} - -- (bool)connect:(NSString *)host { - conn = new mongo::DBClientConnection; - try { - conn->connect([host UTF8String]); - NSLog(@"Connected to: %@", host); - return true; - }catch( mongo::DBException &e ) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return false; - } - return false; -} - -- (bool)connect:(NSString *)name hosts:(NSArray *)hosts { - try { - std::vector servers;NSLog(@"%@", hosts); - for (NSString *h in hosts) { - mongo::HostAndPort server([h UTF8String]); - servers.push_back(server); - } - repl_conn = new mongo::DBClientReplicaSet::DBClientReplicaSet([name UTF8String], servers); - bool ok = repl_conn->connect(); - if (!ok) { - NSRunAlertPanel(@"Error", @"Connection Failed", @"OK", nil, nil); - return false; - } - NSLog(@"Connected to: %@", hosts); - return true; - }catch( mongo::DBException &e ) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return false; - } - return false; -} - -- (bool)authUser:(NSString *)user - pass:(NSString *)pass - database:(NSString *)db -{ - try { - std::string errmsg; - std::string dbname; - if ([db isPresent]) { - dbname = [db UTF8String]; - }else { - dbname = "admin"; - } - bool ok; - if (isRepl) { - ok = repl_conn->auth(dbname, std::string([user UTF8String]), std::string([pass UTF8String]), errmsg); - }else { - ok = conn->auth(dbname, std::string([user UTF8String]), std::string([pass UTF8String]), errmsg); - } - - if (!ok) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:errmsg.c_str()], @"OK", nil, nil); - } - NSLog(@"authUser: %@, %@, %@", user, pass, db); - return ok; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return false; -} - -- (NSArray *)listDatabases { - try { - std::list dbs; - if (isRepl) { - dbs = repl_conn->getDatabaseNames(); - }else { - dbs = conn->getDatabaseNames(); - } - NSMutableArray *dblist = [[NSMutableArray alloc] initWithCapacity:dbs.size() ]; - for (std::list::iterator it=dbs.begin();it!=dbs.end();++it) - { - NSString *db = [[NSString alloc] initWithUTF8String:(*it).c_str()]; - [dblist addObject:db]; - [db release]; - } - NSArray *response = [NSArray arrayWithArray:dblist]; - [dblist release]; - NSLog(@"List Databases"); - return response; - }catch( mongo::DBException &e ) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (NSArray *)listCollections:(NSString *)db - user:(NSString *)user - password:(NSString *)password { - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:db]; - if (!ok) { - return nil; - } - } - - std::list collections; - if (isRepl) { - collections = repl_conn->getCollectionNames([db UTF8String]); - }else { - collections = conn->getCollectionNames([db UTF8String]); - } - - NSMutableArray *clist = [[NSMutableArray alloc] initWithCapacity:collections.size() ]; - unsigned int istartp = [db length] + 1; - for (std::list::iterator it=collections.begin();it!=collections.end();++it) - { - NSString *collection = [[NSString alloc] initWithUTF8String:(*it).c_str()]; - [clist addObject:[collection substringWithRange:NSMakeRange( istartp, [collection length]-istartp )] ]; - [collection release]; - } - NSArray *response = [NSArray arrayWithArray:clist]; - [clist release]; - NSLog(@"List Collections"); - return response; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (NSMutableArray *) serverStatus -{ - try { - mongo::BSONObj retval; - if (isRepl) { - repl_conn->runCommand("admin", BSON("serverStatus"<<1), retval); - }else { - conn->runCommand("admin", BSON("serverStatus"<<1), retval); - } - NSLog(@"Show Server Status"); - return [self bsonDictWrapper:retval]; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return [NSMutableArray arrayWithArray:nil]; -} - -- (NSMutableArray *) dbStats:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return nil; - } - } - mongo::BSONObj retval; - if (isRepl) { - repl_conn->runCommand([dbname UTF8String], BSON("dbstats"<<1), retval); - }else { - conn->runCommand([dbname UTF8String], BSON("dbstats"<<1), retval); - } - NSLog(@"Show DB Stats"); - return [self bsonDictWrapper:retval]; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (void) dropDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - if (isRepl) { - repl_conn->dropDatabase([dbname UTF8String]); - }else { - conn->dropDatabase([dbname UTF8String]); - } - NSLog(@"Drop DB: %@", dbname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (NSMutableArray *) collStats:(NSString *)collectionname - forDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return nil; - } - } - mongo::BSONObj retval; - if (isRepl) { - repl_conn->runCommand([dbname UTF8String], BSON("collstats"<<[collectionname UTF8String]), retval); - }else { - conn->runCommand([dbname UTF8String], BSON("collstats"<<[collectionname UTF8String]), retval); - } - NSLog(@"Show collection stats: %@.%@", dbname, collectionname); - return [self bsonDictWrapper:retval]; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (void) createCollection:(NSString *)collectionname - forDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - if (isRepl) { - repl_conn->createCollection([col UTF8String]); - }else { - conn->createCollection([col UTF8String]); - } - NSLog(@"Creation collection: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) dropCollection:(NSString *)collectionname - forDB:(NSString *)dbname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - if (isRepl) { - repl_conn->dropCollection([col UTF8String]); - }else { - conn->dropCollection([col UTF8String]); - } - NSLog(@"Drop collection: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (NSMutableArray *) findInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical - fields:(NSString *)fields - skip:(NSNumber *)skip - limit:(NSNumber *)limit - sort:(NSString *)sort -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return nil; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj criticalBSON = mongo::fromjson([critical UTF8String]); - mongo::BSONObj sortBSON = mongo::fromjson([sort UTF8String]); - mongo::BSONObj fieldsToReturn; - if ([fields isPresent]) { - NSArray *keys = [[NSArray alloc] initWithArray:[fields componentsSeparatedByString:@","]]; - mongo::BSONObjBuilder builder; - for (NSString *str in keys) { - builder.append([str UTF8String], 1); - } - fieldsToReturn = builder.obj(); - /*try{ - fieldsToReturn = mongo::fromjson([jsFields UTF8String]); - }catch (mongo::MsgAssertionException &e) { - [keys release]; - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return nil; - }*/ - [keys release]; - } - - std::auto_ptr cursor; - if (isRepl) { - cursor = repl_conn->query(std::string([col UTF8String]), mongo::Query(criticalBSON).sort(sortBSON), [limit intValue], [skip intValue], &fieldsToReturn); - }else { - cursor = conn->query(std::string([col UTF8String]), mongo::Query(criticalBSON).sort(sortBSON), [limit intValue], [skip intValue], &fieldsToReturn); - } - NSMutableArray *response = [[NSMutableArray alloc] initWithCapacity:[limit intValue]]; - while( cursor->more() ) - { - mongo::BSONObj b = cursor->next(); - mongo::BSONElement e; - b.getObjectID (e); - NSString *oid; - NSString *oidType; - if (e.type() == mongo::jstOID) - { - oidType = [[NSString alloc] initWithString:@"ObjectId"]; - oid = [[NSString alloc] initWithUTF8String:e.__oid().str().c_str()]; - }else { - oidType = [[NSString alloc] initWithString:@"String"]; - oid = [[NSString alloc] initWithUTF8String:e.str().c_str()]; - } - NSString *jsonString = [[NSString alloc] initWithUTF8String:b.jsonString(mongo::TenGen).c_str()]; - NSMutableString *jsonStringb = [[NSMutableString alloc] initWithUTF8String:b.jsonString(mongo::TenGen, 1).c_str()]; - if (jsonString == nil) { - jsonString = @""; - } - if (jsonStringb == nil) { - jsonStringb = [NSMutableString stringWithString:@""]; - } - NSMutableArray *repArr = [[NSMutableArray alloc] initWithCapacity:4]; - id regx2 = [RKRegex regexWithRegexString:@"(Date\\(\\s\\d+\\s\\))" options:RKCompileCaseless]; - RKEnumerator *matchEnumerator2 = [jsonString matchEnumeratorWithRegex:regx2]; - while([matchEnumerator2 nextRanges] != NULL) { - NSString *enumeratedStr=NULL; - [matchEnumerator2 getCapturesWithReferences:@"$1", &enumeratedStr, nil]; - [repArr addObject:enumeratedStr]; - } - NSMutableArray *oriArr = [[NSMutableArray alloc] initWithCapacity:4]; - id regx = [RKRegex regexWithRegexString:@"(Date\\(\\s+\"[^^]*?\"\\s+\\))" options:RKCompileCaseless]; - RKEnumerator *matchEnumerator = [jsonStringb matchEnumeratorWithRegex:regx]; - while([matchEnumerator nextRanges] != NULL) { - NSString *enumeratedStr=NULL; - [matchEnumerator getCapturesWithReferences:@"$1", &enumeratedStr, nil]; - [oriArr addObject:enumeratedStr]; - } - for (unsigned int i=0; i<[repArr count]; i++) { - jsonStringb = [NSMutableString stringWithString:[jsonStringb stringByReplacingOccurrencesOfString:[oriArr objectAtIndex:i] withString:[repArr objectAtIndex:i]]]; - } - [oriArr release]; - [repArr release]; - NSMutableDictionary *item = [[NSMutableDictionary alloc] initWithCapacity:4]; - [item setObject:@"_id" forKey:@"name"]; - [item setObject:oidType forKey:@"type"]; - [item setObject:oid forKey:@"value"]; - [item setObject:jsonString forKey:@"raw"]; - [item setObject:jsonStringb forKey:@"beautified"]; - [item setObject:[self bsonDictWrapper:b] forKey:@"child"]; - [response addObject:item]; - [jsonString release]; - [oid release]; - [oidType release]; - [item release]; - } - NSLog(@"Find in db: %@.%@", dbname, collectionname); - return response; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (void) saveInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - jsonString:(NSString *)jsonString - _id:(NSString *)_id -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname];NSLog(@"%@", jsonString);NSLog(@"%@", _id); - mongo::BSONObj fields = mongo::fromjson([jsonString UTF8String]); - mongo::BSONObj critical = mongo::fromjson([[NSString stringWithFormat:@"{\"_id\":%@}", _id] UTF8String]); - - if (isRepl) { - repl_conn->update(std::string([col UTF8String]), critical, fields, false); - }else { - conn->update(std::string([col UTF8String]), critical, fields, false); - } - NSLog(@"save in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) updateInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical - fields:(NSString *)fields - upset:(NSNumber *)upset -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj criticalBSON = mongo::fromjson([critical UTF8String]); - mongo::BSONObj fieldsBSON = mongo::fromjson([[NSString stringWithFormat:@"{$set:%@}", fields] UTF8String]); - if (isRepl) { - repl_conn->update(std::string([col UTF8String]), criticalBSON, fieldsBSON, (bool)[upset intValue]); - }else { - conn->update(std::string([col UTF8String]), criticalBSON, fieldsBSON, (bool)[upset intValue]); - } - NSLog(@"Update in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) removeInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj criticalBSON; - if ([critical isPresent]) { - try{ - criticalBSON = mongo::fromjson([critical UTF8String]); - }catch (mongo::MsgAssertionException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return; - } - if (isRepl) { - repl_conn->remove(std::string([col UTF8String]), criticalBSON); - }else { - conn->remove(std::string([col UTF8String]), criticalBSON); - } - - } - NSLog(@"Remove in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) insertInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - insertData:(NSString *)insertData -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj insertDataBSON; - if ([insertData isPresent]) { - try{ - insertDataBSON = mongo::fromjson([insertData UTF8String]); - }catch (mongo::MsgAssertionException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return; - } - if (isRepl) { - repl_conn->insert(std::string([col UTF8String]), insertDataBSON); - }else { - conn->insert(std::string([col UTF8String]), insertDataBSON); - } - - } - NSLog(@"Insert into db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) insertInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - data:(NSDictionary *)insertData - fields:(NSArray *)fields - fieldTypes:(NSDictionary *)fieldTypes -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObjBuilder b; - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - for (int i=0; i<[fields count]; i++) { - NSString *fieldName = [fields objectAtIndex:i]; - NSString *ft = [fieldTypes objectForKey:fieldName]; - id aValue = [insertData objectForKey:fieldName]; - if (aValue == [NSString nullValue]) - b.appendNull([fieldName UTF8String]); - else if ([ft isEqualToString:@"varstring"] || [ft isEqualToString:@"string"]) - b.append([fieldName UTF8String], [aValue UTF8String]); - else if ([ft isEqualToString:@"float"]) - b.append([fieldName UTF8String], [aValue floatValue]); - else if ([ft isEqualToString:@"double"] || [ft isEqualToString:@"decimal"]) - b.append([fieldName UTF8String], [aValue doubleValue]); - else if ([ft isEqualToString:@"longlong"]) - b.append([fieldName UTF8String], [aValue longLongValue]); - else if ([ft isEqualToString:@"bool"]) - b.append([fieldName UTF8String], [aValue boolValue]); - else if ([ft isEqualToString:@"int24"] || [ft isEqualToString:@"long"]) - b.append([fieldName UTF8String], [aValue intValue]); - else if ([ft isEqualToString:@"tiny"] || [ft isEqualToString:@"short"]) - b.append([fieldName UTF8String], [aValue shortValue]); - else if ([ft isEqualToString:@"date"]) { - time_t timestamp = [aValue timeIntervalSince1970]; - b.appendDate([fieldName UTF8String], timestamp); - }else if ([ft isEqualToString:@"datetime"] || [ft isEqualToString:@"timestamp"] || [ft isEqualToString:@"year"]) { - time_t timestamp = [aValue timeIntervalSince1970]; - b.appendTimeT([fieldName UTF8String], timestamp); - }else if ([ft isEqualToString:@"time"]) { - [dateFormatter setDateFormat:@"HH:mm:ss"]; - NSDate *dateFromString = [dateFormatter dateFromString:aValue]; - time_t timestamp = [dateFromString timeIntervalSince1970]; - b.appendTimeT([fieldName UTF8String], timestamp); - }else if ([ft isEqualToString:@"blob"]) { - if ([aValue isKindOfClass:[NSString class]]) { - b.append([fieldName UTF8String], [aValue UTF8String]); - }else { - int bLen = [aValue length]; - mongo::BinDataType binType = (mongo::BinDataType)0; - const char *bData = (char *)[aValue bytes]; - b.appendBinData([fieldName UTF8String], bLen, binType, bData); - } - } - } - [dateFormatter release]; - mongo::BSONObj insertDataBSON = b.obj(); - mongo::BSONObj emptyBSON; - if (insertDataBSON == emptyBSON) { - return; - } - if (isRepl) { - repl_conn->insert(std::string([col UTF8String]), insertDataBSON); - }else { - conn->insert(std::string([col UTF8String]), insertDataBSON); - } - NSLog(@"Find in db with filetype: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (NSMutableArray *) indexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return nil; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - std::auto_ptr cursor; - if (isRepl) { - cursor = repl_conn->getIndexes(std::string([col UTF8String])); - }else { - cursor = conn->getIndexes(std::string([col UTF8String])); - } - NSMutableArray *response = [[NSMutableArray alloc] init]; - while( cursor->more() ) - { - mongo::BSONObj b = cursor->next(); - NSString *name = [[NSString alloc] initWithUTF8String:b.getStringField("name")]; - NSMutableDictionary *item = [[NSMutableDictionary alloc] initWithCapacity:4]; - [item setObject:@"name" forKey:@"name"]; - [item setObject:@"String" forKey:@"type"]; - [item setObject:name forKey:@"value"]; - [item setObject:[self bsonDictWrapper:b] forKey:@"child"]; - [response addObject:item]; - [name release]; - [item release]; - } - NSLog(@"Show indexes in db: %@.%@", dbname, collectionname); - return response; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (void) ensureIndexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - indexData:(NSString *)indexData -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj indexDataBSON; - if ([indexData isPresent]) { - try{ - indexDataBSON = mongo::fromjson([indexData UTF8String]); - }catch (mongo::MsgAssertionException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return; - } - } - if (isRepl) { - repl_conn->ensureIndex(std::string([col UTF8String]), indexDataBSON); - }else { - conn->ensureIndex(std::string([col UTF8String]), indexDataBSON); - } - NSLog(@"Ensure index in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) reIndexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - if (isRepl) { - repl_conn->reIndex(std::string([col UTF8String])); - }else { - conn->reIndex(std::string([col UTF8String])); - } - NSLog(@"Reindex in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (void) dropIndexInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - indexName:(NSString *)indexName -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - if (isRepl) { - repl_conn->dropIndex(std::string([col UTF8String]), [indexName UTF8String]); - }else { - conn->dropIndex(std::string([col UTF8String]), [indexName UTF8String]); - } - NSLog(@"Drop index in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (long long int) countInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return 0; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj criticalBSON = mongo::fromjson([critical UTF8String]); - long long int counter; - if (isRepl) { - counter = repl_conn->count(std::string([col UTF8String]), criticalBSON); - }else { - counter = conn->count(std::string([col UTF8String]), criticalBSON); - } - NSLog(@"Count in db: %@.%@", dbname, collectionname); - return counter; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return 0; -} - -- (NSMutableArray *)mapReduceInDB:dbname - collection:collectionname - user:user - password:password - mapJs:mapJs - reduceJs:reduceJs - critical:critical - output:output -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return nil; - } - } - if (![mapJs isPresent] || ![reduceJs isPresent]) { - return nil; - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj criticalBSON = mongo::fromjson([critical UTF8String]); - mongo::BSONObj retval; - if (isRepl) { - retval = repl_conn->mapreduce(std::string([col UTF8String]), std::string([mapJs UTF8String]), std::string([reduceJs UTF8String]), criticalBSON, std::string([output UTF8String])); - }else { - retval = conn->mapreduce(std::string([col UTF8String]), std::string([mapJs UTF8String]), std::string([reduceJs UTF8String]), criticalBSON, std::string([output UTF8String])); - } - NSLog(@"Map reduce in db: %@.%@", dbname, collectionname); - return [self bsonDictWrapper:retval]; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return nil; -} - -- (mongo::BSONObj) serverStat{ - try { - mongo::BSONObj retval; - if (isRepl) { - repl_conn->runCommand("admin", BSON("serverStatus"<<1), retval); - }else { - conn->runCommand("admin", BSON("serverStatus"<<1), retval); - } - return retval; - }catch (mongo::DBException &e) { - //NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - return mongo::BSONObj(); - } - /* - mongo::BSONObj out; - if ( ! conn->simpleCommand( "admin" , &out , "serverStatus" ) ){ - return mongo::BSONObj(); - } - return out.getOwned(); - */ -} - -- (NSDictionary *) serverMonitor:(mongo::BSONObj)a second:(mongo::BSONObj)b currentDate:(NSDate *)now previousDate:(NSDate *)previous{ - NSMutableDictionary *res = [[NSMutableDictionary alloc] initWithCapacity:14]; - [res setObject:now forKey:@"time"]; - NSTimeInterval interval = [now timeIntervalSinceDate:previous]; - if ( b["opcounters"].type() == mongo::Object ) { - mongo::BSONObj ax = a["opcounters"].embeddedObject(); - mongo::BSONObj bx = b["opcounters"].embeddedObject(); - mongo::BSONObjIterator i( bx ); - while ( i.more() ){ - mongo::BSONElement e = i.next(); - NSString *key = [NSString stringWithUTF8String:e.fieldName()]; - [res setObject:[NSNumber numberWithInt:[self diff:key first:ax second:bx timeInterval:interval]] forKey:key]; - } - } - if ( b["backgroundFlushing"].type() == mongo::Object ){ - mongo::BSONObj ax = a["backgroundFlushing"].embeddedObject(); - mongo::BSONObj bx = b["backgroundFlushing"].embeddedObject(); - [res setObject:[NSNumber numberWithInt:[self diff:@"flushes" first:ax second:bx timeInterval:interval]] forKey:@"flushes"]; - } - if ( b.getFieldDotted("mem.supported").trueValue() ){ - mongo::BSONObj bx = b["mem"].embeddedObject(); - [res setObject:[NSNumber numberWithInt:bx["mapped"].numberInt()] forKey:@"mapped"]; - [res setObject:[NSNumber numberWithInt:bx["virtual"].numberInt()] forKey:@"vsize"]; - [res setObject:[NSNumber numberWithInt:bx["resident"].numberInt()] forKey:@"res"]; - } - if ( b["extra_info"].type() == mongo::Object ){ - mongo::BSONObj ax = a["extra_info"].embeddedObject(); - mongo::BSONObj bx = b["extra_info"].embeddedObject(); - if ( ax["page_faults"].type() || ax["page_faults"].type() ) - [res setObject:[NSNumber numberWithInt:[self diff:@"page_faults" first:ax second:bx timeInterval:interval]] forKey:@"faults"]; - } - [res setObject:[NSNumber numberWithInt:[self percent:@"globalLock.totalTime" value:@"globalLock.lockTime" first:a second:b]] forKey:@"locked"]; - [res setObject:[NSNumber numberWithInt:[self percent:@"indexCounters.btree.accesses" value:@"indexCounters.btree.misses" first:a second:b]] forKey:@"misses"]; - [res setObject:[NSNumber numberWithInt:b.getFieldDotted( "connections.current" ).numberInt()] forKey:@"conn"]; - return (NSDictionary *)res; -} - -#pragma mark BSON to NSMutableArray -- (NSMutableArray *) bsonDictWrapper:(mongo::BSONObj)retval -{ - if (!retval.isEmpty()) - { - std::set fieldNames; - retval.getFieldNames(fieldNames); - NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:fieldNames.size()]; - for(std::set::iterator it=fieldNames.begin();it!=fieldNames.end();++it) - { - mongo::BSONElement e = retval.getField((*it)); - NSString *fieldName = [[NSString alloc] initWithUTF8String:(*it).c_str()]; - NSMutableArray *child = [[NSMutableArray alloc] init]; - NSString *value; - NSString *fieldType; - if (e.type() == mongo::Array) { - mongo::BSONObj b = e.embeddedObject(); - NSMutableArray *tmp = [self bsonArrayWrapper:b]; - if (tmp!=nil) { - child = tmp; - value = @""; - }else { - value = @"[ ]"; - } - - fieldType = @"Array"; - }else if (e.type() == mongo::Object) { - mongo::BSONObj b = e.embeddedObject(); - NSMutableArray *tmp = [self bsonDictWrapper:b]; - if (tmp!=nil) { - child = tmp; - value = @""; - }else { - value = @"{ }"; - } - - fieldType = @"Object"; - }else{ - if (e.type() == mongo::jstNULL) { - fieldType = @"NULL"; - value = @"NULL"; - }else if (e.type() == mongo::Bool) { - fieldType = @"Bool"; - if (e.boolean()) { - value = @"YES"; - }else { - value = @"NO"; - } - }else if (e.type() == mongo::NumberDouble) { - fieldType = @"Double"; - value = [NSString stringWithFormat:@"%f", e.numberDouble()]; - }else if (e.type() == mongo::NumberInt) { - fieldType = @"Int"; - value = [NSString stringWithFormat:@"%d", (int)(e.numberInt())]; - }else if (e.type() == mongo::Date) { - fieldType = @"Date"; - mongo::Date_t dt = (time_t)e.date(); - time_t timestamp = dt / 1000; - NSDate *someDate = [NSDate dateWithTimeIntervalSince1970:timestamp]; - value = [someDate description]; - }else if (e.type() == mongo::Timestamp) { - fieldType = @"Timestamp"; - time_t timestamp = (time_t)e.timestampTime(); - NSDate *someDate = [NSDate dateWithTimeIntervalSince1970:timestamp]; - value = [someDate description]; - }else if (e.type() == mongo::BinData) { - //int binlen; - fieldType = @"BinData"; - //value = [NSString stringWithUTF8String:e.binData(binlen)]; - value = @"binary"; - }else if (e.type() == mongo::NumberLong) { - fieldType = @"Long"; - value = [NSString stringWithFormat:@"%qi", e.numberLong()]; - }else if ([fieldName isEqualToString:@"_id" ]) { - if (e.type() == mongo::jstOID) - { - fieldType = @"ObjectId"; - value = [NSString stringWithUTF8String:e.__oid().str().c_str()]; - }else { - fieldType = @"String"; - value = [NSString stringWithUTF8String:e.str().c_str()]; - } - }else if (e.type() == mongo::jstOID) { - fieldType = @"ObjectId"; - value = [NSString stringWithUTF8String:e.__oid().str().c_str()]; - }else { - fieldType = @"String"; - value = [NSString stringWithUTF8String:e.str().c_str()]; - } - } - NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:4]; - [dict setObject:fieldName forKey:@"name"]; - [dict setObject:fieldType forKey:@"type"]; - [dict setObject:value forKey:@"value"]; - [dict setObject:child forKey:@"child"]; - [arr addObject:dict]; - [dict release]; - [fieldName release]; - [child release]; - } - return arr; - } - return nil; -} - -- (NSMutableArray *) bsonArrayWrapper:(mongo::BSONObj)retval -{ - if (!retval.isEmpty()) - { - NSMutableArray *arr = [[NSMutableArray alloc] init]; - mongo::BSONElement idElm; - bool hasId = retval.getObjectID(idElm); - mongo::BSONObjIterator it (retval); - unsigned int i=0; - while(it.more()) - { - mongo::BSONElement e = it.next(); - NSString *fieldName = [[NSString alloc] initWithFormat:@"%d", i]; - NSString *value; - NSString *fieldType; - NSMutableArray *child = [[NSMutableArray alloc] init]; - if (e.type() == mongo::Array) { - mongo::BSONObj b = e.embeddedObject(); - NSMutableArray *tmp = [self bsonArrayWrapper:b]; - if (tmp == nil) { - value = @"[ ]"; - if (hasId) { - [arr addObject:@"[ ]"]; - } - }else { - child = tmp; - value = @""; - if (hasId) { - [arr addObject:tmp]; - } - } - fieldType = @"Array"; - }else if (e.type() == mongo::Object) { - mongo::BSONObj b = e.embeddedObject(); - NSMutableArray *tmp = [self bsonDictWrapper:b]; - if (tmp == nil) { - value = @""; - if (hasId) { - [arr addObject:@"{ }"]; - } - }else { - child = tmp; - value = @"{ }"; - if (hasId) { - [arr addObject:tmp]; - } - } - fieldType = @"Object"; - }else{ - if (e.type() == mongo::jstNULL) { - fieldType = @"NULL"; - value = @"NULL"; - }else if (e.type() == mongo::Bool) { - fieldType = @"Bool"; - if (e.boolean()) { - value = @"YES"; - }else { - value = @"NO"; - } - if (hasId) { - [arr addObject:[NSNumber numberWithBool:e.boolean()]]; - } - }else if (e.type() == mongo::NumberDouble) { - fieldType = @"Double"; - value = [NSString stringWithFormat:@"%f", e.numberDouble()]; - if (hasId) { - [arr addObject:[NSNumber numberWithDouble:e.numberDouble()]]; - } - }else if (e.type() == mongo::NumberInt) { - fieldType = @"Int"; - value = [NSString stringWithFormat:@"%d", (int)(e.numberInt())]; - if (hasId) { - [arr addObject:[NSNumber numberWithInt:e.numberInt()]]; - } - }else if (e.type() == mongo::Date) { - fieldType = @"Date"; - mongo::Date_t dt = (time_t)e.date(); - time_t timestamp = dt / 1000; - NSDate *someDate = [NSDate dateWithTimeIntervalSince1970:timestamp]; - value = [someDate description]; - if (hasId) { - [arr addObject:[someDate description]]; - } - }else if (e.type() == mongo::Timestamp) { - fieldType = @"Timestamp"; - time_t timestamp = (time_t)e.timestampTime(); - NSDate *someDate = [NSDate dateWithTimeIntervalSince1970:timestamp]; - value = [someDate description]; - if (hasId) { - [arr addObject:[someDate description]]; - } - }else if (e.type() == mongo::BinData) { - fieldType = @"BinData"; - //int binlen; - //value = [NSString stringWithUTF8String:e.binData(binlen)]; - value = @"binary"; - if (hasId) { - //[arr addObject:[NSString stringWithUTF8String:e.binData(binlen)]]; - [arr addObject:@"binary"]; - } - }else if (e.type() == mongo::NumberLong) { - fieldType = @"Long"; - value = [NSString stringWithFormat:@"%qi", e.numberLong()]; - if (hasId) { - [arr addObject:[NSString stringWithFormat:@"%qi", e.numberLong()]]; - } - }else if (e.type() == mongo::jstOID) { - fieldType = @"ObjectId"; - value = [NSString stringWithUTF8String:e.__oid().str().c_str()]; - }else { - fieldType = @"String"; - value = [NSString stringWithUTF8String:e.str().c_str()]; - if (hasId) { - [arr addObject:[NSString stringWithUTF8String:e.str().c_str()]]; - } - } - } - if (!hasId) { - NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:4]; - [dict setObject:fieldName forKey:@"name"]; - [dict setObject:fieldType forKey:@"type"]; - [dict setObject:value forKey:@"value"]; - [dict setObject:child forKey:@"child"]; - [arr addObject:dict]; - [dict release]; - } - [fieldName release]; - [child release]; - i ++; - } - return arr; - } - return nil; -} - -- (std::auto_ptr) findAllCursorInDB:(NSString *)dbname collection:(NSString *)collectionname user:(NSString *)user password:(NSString *)password fields:(mongo::BSONObj) fields -{ - std::auto_ptr cursor; - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return cursor; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - if (isRepl) { - cursor = repl_conn->query(std::string([col UTF8String]), mongo::Query(), 0, 0, &fields, mongo::QueryOption_SlaveOk | mongo::QueryOption_NoCursorTimeout); - }else { - cursor = conn->query(std::string([col UTF8String]), mongo::Query(), 0, 0, &fields, mongo::QueryOption_SlaveOk | mongo::QueryOption_NoCursorTimeout); - } - return cursor; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return cursor; -} - -- (std::auto_ptr) findCursorInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(NSString *)critical - fields:(NSString *)fields - skip:(NSNumber *)skip - limit:(NSNumber *)limit - sort:(NSString *)sort -{ - std::auto_ptr cursor; - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return cursor; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - mongo::BSONObj criticalBSON = mongo::fromjson([critical UTF8String]); - mongo::BSONObj sortBSON = mongo::fromjson([sort UTF8String]); - mongo::BSONObj fieldsToReturn; - if ([fields isPresent]) { - NSArray *keys = [[NSArray alloc] initWithArray:[fields componentsSeparatedByString:@","]]; - mongo::BSONObjBuilder builder; - for (NSString *str in keys) { - builder.append([str UTF8String], 1); - } - fieldsToReturn = builder.obj(); - [keys release]; - } - if (isRepl) { - cursor = repl_conn->query(std::string([col UTF8String]), mongo::Query(criticalBSON).sort(sortBSON), [limit intValue], [skip intValue], &fieldsToReturn, mongo::QueryOption_SlaveOk | mongo::QueryOption_NoCursorTimeout); - }else { - cursor = conn->query(std::string([col UTF8String]), mongo::Query(criticalBSON).sort(sortBSON), [limit intValue], [skip intValue], &fieldsToReturn, mongo::QueryOption_SlaveOk | mongo::QueryOption_NoCursorTimeout); - } - return cursor; - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } - return cursor; -} - -- (void) updateBSONInDB:(NSString *)dbname - collection:(NSString *)collectionname - user:(NSString *)user - password:(NSString *)password - critical:(mongo::Query)critical - fields:(mongo::BSONObj)fields - upset:(bool)upset -{ - try { - if ([user length]>0 && [password length]>0) { - bool ok = [self authUser:user pass:password database:dbname]; - if (!ok) { - return; - } - } - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - if (isRepl) { - repl_conn->update(std::string([col UTF8String]), critical, fields, upset); - }else { - conn->update(std::string([col UTF8String]), critical, fields, upset); - } - NSLog(@"Update in db: %@.%@", dbname, collectionname); - }catch (mongo::DBException &e) { - NSRunAlertPanel(@"Error", [NSString stringWithUTF8String:e.what()], @"OK", nil, nil); - } -} - -- (double) diff:(NSString *)aName first:(mongo::BSONObj)a second:(mongo::BSONObj)b timeInterval:(NSTimeInterval)interval{ - std::string name = std::string([aName UTF8String]); - mongo::BSONElement x = a.getFieldDotted( name.c_str() ); - mongo::BSONElement y = b.getFieldDotted( name.c_str() ); - if ( ! x.isNumber() || ! y.isNumber() ) - return -1; - return ( y.number() - x.number() ) / interval; -} - -- (double) percent:(NSString *)aOut value:(NSString *)aVal first:(mongo::BSONObj)a second:(mongo::BSONObj)b { - const char * outof = [aOut UTF8String]; - const char * val = [aVal UTF8String]; - double x = ( b.getFieldDotted( val ).number() - a.getFieldDotted( val ).number() ); - double y = ( b.getFieldDotted( outof ).number() - a.getFieldDotted( outof ).number() ); - if ( y == 0 ) - return 0; - double p = x / y; - p = (double)((int)(p * 1000)) / 10; - return p; -} - -@end diff --git a/MongoHub.entitlements b/MongoHub.entitlements new file mode 100644 index 00000000..0c67376e --- /dev/null +++ b/MongoHub.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/MongoHub.xcodeproj/project.pbxproj b/MongoHub.xcodeproj/project.pbxproj index 40cc7640..38de15b2 100644 --- a/MongoHub.xcodeproj/project.pbxproj +++ b/MongoHub.xcodeproj/project.pbxproj @@ -6,7 +6,115 @@ objectVersion = 46; objects = { +/* Begin PBXAggregateTarget section */ + 02216F201412D54600789BD1 /* Submodules */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 02216F221412D54600789BD1 /* Build configuration list for PBXAggregateTarget "Submodules" */; + buildPhases = ( + 02D5A7F41442019100C7768C /* Update submodules */, + ); + dependencies = ( + ); + name = Submodules; + productName = Submodules; + }; +/* End PBXAggregateTarget section */ + /* Begin PBXBuildFile section */ + 020F511A14896DE700D4B54B /* MHTabViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 020F511814896DE700D4B54B /* MHTabViewController.m */; }; + 020F511B14896DE700D4B54B /* MHTabView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 020F511914896DE700D4B54B /* MHTabView.xib */; }; + 020F5128148973BA00D4B54B /* MHStatusViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 020F5126148973BA00D4B54B /* MHStatusViewController.m */; }; + 020F5129148973BA00D4B54B /* MHStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 020F5127148973BA00D4B54B /* MHStatusView.xib */; }; + 021315AE198ABF41006378C5 /* MHMongoHubMigration7to8.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 021315AD198ABF41006378C5 /* MHMongoHubMigration7to8.xcmappingmodel */; }; + 021BEA681463709A0091C2EA /* MongoHub_DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 021BEA641463709A0091C2EA /* MongoHub_DataModel.xcdatamodeld */; }; + 022F33731AD7192300324917 /* MHConnectionListWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 022F33721AD7192300324917 /* MHConnectionListWindowController.m */; }; + 0230662719E7FD07006F5C8C /* querymenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0230662619E7FD07006F5C8C /* querymenu@2x.png */; }; + 023230AE15E051300075498C /* MHConnectionEditorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 023230AD15E051300075498C /* MHConnectionEditorWindowController.m */; }; + 0242F11A198922B900C73FEC /* MHMongoHubMigration6to7.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 0242F119198922B800C73FEC /* MHMongoHubMigration6to7.xcmappingmodel */; }; + 0242F138198ABE3E00C73FEC /* MHMongoHubMigration7to8.m in Sources */ = {isa = PBXBuildFile; fileRef = 0242F137198ABE3E00C73FEC /* MHMongoHubMigration7to8.m */; }; + 0243B79019EC222300D06BFE /* MHConnectionWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C3D01183690E003216F7 /* MHConnectionWindow.xib */; }; + 0243B79219EC357700D06BFE /* MHQueryUpdateOperatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0243B79119EC357700D06BFE /* MHQueryUpdateOperatorView.xib */; }; + 024F67901427F3DE00956BF6 /* MODHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 024F678F1427F3DE00956BF6 /* MODHelper.m */; }; + 0252361218FECEE700286EC9 /* MHExporterImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0252361118FECEE700286EC9 /* MHExporterImporter.m */; }; + 0255B568181A9A210019739D /* MHKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 0255B567181A9A210019739D /* MHKeychain.m */; }; + 0259EAFE19AF5CF000181E08 /* MHLogWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0259EAFD19AF5CF000181E08 /* MHLogWindow.xib */; }; + 0259EB0519AF5D6600181E08 /* MHLogWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0259EB0419AF5D6600181E08 /* MHLogWindowController.m */; }; + 0259EB6519B01E7800181E08 /* MHJsonColorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0259EB6419B01E7800181E08 /* MHJsonColorManager.m */; }; + 025B8F0C1531C76E00849A71 /* MHTabTitleContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 025B8F0B1531C76E00849A71 /* MHTabTitleContainerView.m */; }; + 025B8F911531FC7500849A71 /* unselected-tab-border.png in Resources */ = {isa = PBXBuildFile; fileRef = 025B8F901531FC7500849A71 /* unselected-tab-border.png */; }; + 025CBC6E1982AE4E00C8E272 /* MHMongoHubMigration6to7.m in Sources */ = {isa = PBXBuildFile; fileRef = 025CBC6D1982AE4E00C8E272 /* MHMongoHubMigration6to7.m */; }; + 025F635215AE21F300CD0EB4 /* NSViewHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 025F635115AE21F300CD0EB4 /* NSViewHelpers.m */; }; + 0262CA3C148C14A8009033F9 /* MHTabItemViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0262CA3A148C14A8009033F9 /* MHTabItemViewController.m */; }; + 0262CA3F148C1838009033F9 /* MHConnectionWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0262CA3E148C1838009033F9 /* MHConnectionWindowController.m */; }; + 026B2DE513BB6FB8009BEA7B /* RegexKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 026B2DE413BB6FB8009BEA7B /* RegexKit.framework */; }; + 027062B519DF803600E6C36A /* unselected-tab-border@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062A719DF803600E6C36A /* unselected-tab-border@2x.png */; }; + 027062B619DF803600E6C36A /* unselected-tab-background@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062A819DF803600E6C36A /* unselected-tab-background@2x.png */; }; + 027062B719DF803600E6C36A /* overlay_close_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062A919DF803600E6C36A /* overlay_close_button@2x.png */; }; + 027062B819DF803600E6C36A /* grip_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062AA19DF803600E6C36A /* grip_button@2x.png */; }; + 027062B919DF803600E6C36A /* close_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062AB19DF803600E6C36A /* close_button@2x.png */; }; + 027062BA19DF803600E6C36A /* button_ArrowRight_overlay@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062AC19DF803600E6C36A /* button_ArrowRight_overlay@2x.png */; }; + 027062BB19DF803600E6C36A /* button_ArrowRight_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062AD19DF803600E6C36A /* button_ArrowRight_default@2x.png */; }; + 027062BC19DF803600E6C36A /* background-grey_right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062AE19DF803600E6C36A /* background-grey_right@2x.png */; }; + 027062BD19DF803600E6C36A /* background-grey_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062AF19DF803600E6C36A /* background-grey_left@2x.png */; }; + 027062BE19DF803600E6C36A /* background-grey_center@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062B019DF803600E6C36A /* background-grey_center@2x.png */; }; + 027062BF19DF803600E6C36A /* background_blue_right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062B119DF803600E6C36A /* background_blue_right@2x.png */; }; + 027062C019DF803600E6C36A /* background_blue_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062B219DF803600E6C36A /* background_blue_left@2x.png */; }; + 027062C119DF803600E6C36A /* background_blue_center@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062B319DF803600E6C36A /* background_blue_center@2x.png */; }; + 027062C219DF803600E6C36A /* background_blue_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062B419DF803600E6C36A /* background_blue_arrow@2x.png */; }; + 027062D119DF822600E6C36A /* removemenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062CB19DF822600E6C36A /* removemenu@2x.png */; }; + 027062D219DF822600E6C36A /* mapreducemenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062CC19DF822600E6C36A /* mapreducemenu@2x.png */; }; + 027062D319DF822600E6C36A /* insertmenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062CD19DF822600E6C36A /* insertmenu@2x.png */; }; + 027062D419DF822600E6C36A /* indexmenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062CE19DF822600E6C36A /* indexmenu@2x.png */; }; + 027062D519DF822600E6C36A /* findmenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062CF19DF822600E6C36A /* findmenu@2x.png */; }; + 027062D619DF822600E6C36A /* editmenu@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 027062D019DF822600E6C36A /* editmenu@2x.png */; }; + 0279C090189C02F600F8BACB /* MHImportExportFeedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0279C08F189C02F600F8BACB /* MHImportExportFeedback.xib */; }; + 0279C093189C03E000F8BACB /* MHImportExportFeedback.m in Sources */ = {isa = PBXBuildFile; fileRef = 0279C092189C03E000F8BACB /* MHImportExportFeedback.m */; }; + 028C6DF019F874D60014B4C0 /* ALIterativeMigrator.m in Sources */ = {isa = PBXBuildFile; fileRef = 028C6DEF19F874D60014B4C0 /* ALIterativeMigrator.m */; }; + 029464DC19F588B900E1B1E6 /* MHActivityMonitorTab.xib in Resources */ = {isa = PBXBuildFile; fileRef = 029464DB19F588B900E1B1E6 /* MHActivityMonitorTab.xib */; }; + 029464DF19F5899F00E1B1E6 /* MHActivityMonitorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 029464DE19F5899F00E1B1E6 /* MHActivityMonitorViewController.m */; }; + 029464E119F58C4500E1B1E6 /* ActivityMonitor.icns in Resources */ = {isa = PBXBuildFile; fileRef = 029464E019F58C4400E1B1E6 /* ActivityMonitor.icns */; }; + 029CAA731946028800FD44B4 /* NSTextView+MongoHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 029CAA721946028800FD44B4 /* NSTextView+MongoHub.m */; }; + 029D30A5145613420021B9C9 /* MHDatabaseItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 029D30A4145613420021B9C9 /* MHDatabaseItem.m */; }; + 029D30A9145613580021B9C9 /* MHCollectionItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 029D30A8145613580021B9C9 /* MHCollectionItem.m */; }; + 029D30AC145613C30021B9C9 /* MHClientItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 029D30AB145613C30021B9C9 /* MHClientItem.m */; }; + 02A7C40A1482DEDD0099CDD1 /* MHMysqlImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 02A7C4091482DEDD0099CDD1 /* MHMysqlImporter.m */; }; + 02A7C40E1482DF080099CDD1 /* MHMysqlExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 02A7C40D1482DF080099CDD1 /* MHMysqlExporter.m */; }; + 02AA29931477F8BD0041865F /* MHFileExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 02AA29921477F8BD0041865F /* MHFileExporter.m */; }; + 02ABF65F19E09C76009F4766 /* MHDatabaseCollectionOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 02ABF65E19E09C76009F4766 /* MHDatabaseCollectionOutlineView.m */; }; + 02B143DC147C720D005AB320 /* MHFileImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 02B143DB147C720D005AB320 /* MHFileImporter.m */; }; + 02C3452A1A423C85004F0D2C /* MHIndexEditor.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02C345291A423C85004F0D2C /* MHIndexEditor.xib */; }; + 02C345321A436A18004F0D2C /* MHIndexEditorController.m in Sources */ = {isa = PBXBuildFile; fileRef = 02C345311A436A18004F0D2C /* MHIndexEditorController.m */; }; + 02C4C1C819A231090002FBD8 /* MongoObjCDriver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02C4C1C519A230BE0002FBD8 /* MongoObjCDriver.framework */; }; + 02C4C1CA19A231600002FBD8 /* MongoObjCDriver.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 02C4C1C519A230BE0002FBD8 /* MongoObjCDriver.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 02CEE9BE1486DD7A00E488DA /* MHTabTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 02CEE9BD1486DD7A00E488DA /* MHTabTitleView.m */; }; + 02CF9CC919AA9E8A00EEF76B /* MHMongoHubMigration9to10.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = 02CF9CC819AA9E8A00EEF76B /* MHMongoHubMigration9to10.xcmappingmodel */; }; + 02D3D9A11AAA4DD000FE5566 /* MHDocumentOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 02D3D9A01AAA4DD000FE5566 /* MHDocumentOutlineViewController.m */; }; + 02D3D9A81AAA512B00FE5566 /* MHDocumentOutlineView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02D3D9A71AAA512B00FE5566 /* MHDocumentOutlineView.xib */; }; + 02D83E0219A4A28F007AB2F2 /* NSDictionary+MongoHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 02D83E0119A4A28F007AB2F2 /* NSDictionary+MongoHub.m */; }; + 02E0FE36151DE2420094C1CD /* background-grey_center.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE29151DE2420094C1CD /* background-grey_center.png */; }; + 02E0FE37151DE2420094C1CD /* background-grey_left.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE2A151DE2420094C1CD /* background-grey_left.png */; }; + 02E0FE38151DE2420094C1CD /* background-grey_right.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE2B151DE2420094C1CD /* background-grey_right.png */; }; + 02E0FE39151DE2420094C1CD /* background_blue_arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE2C151DE2420094C1CD /* background_blue_arrow.png */; }; + 02E0FE3A151DE2420094C1CD /* background_blue_center.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE2D151DE2420094C1CD /* background_blue_center.png */; }; + 02E0FE3B151DE2420094C1CD /* background_blue_left.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE2E151DE2420094C1CD /* background_blue_left.png */; }; + 02E0FE3C151DE2420094C1CD /* background_blue_right.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE2F151DE2420094C1CD /* background_blue_right.png */; }; + 02E0FE3D151DE2420094C1CD /* unselected-tab-background.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE30151DE2420094C1CD /* unselected-tab-background.png */; }; + 02E0FE3E151DE2420094C1CD /* grip_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE31151DE2420094C1CD /* grip_button.png */; }; + 02E0FE3F151DE2420094C1CD /* button_ArrowRight_default.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE32151DE2420094C1CD /* button_ArrowRight_default.png */; }; + 02E0FE40151DE2420094C1CD /* button_ArrowRight_overlay.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE33151DE2420094C1CD /* button_ArrowRight_overlay.png */; }; + 02E0FE41151DE2420094C1CD /* close_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE34151DE2420094C1CD /* close_button.png */; }; + 02E0FE42151DE2420094C1CD /* overlay_close_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 02E0FE35151DE2420094C1CD /* overlay_close_button.png */; }; + 02E79EA41993E7950016B4C9 /* MHConnectionIconView.m in Sources */ = {isa = PBXBuildFile; fileRef = 02E79EA31993E7950016B4C9 /* MHConnectionIconView.m */; }; + 02E79EA71993F3F90016B4C9 /* MHConnectionViewItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 02E79EA61993F3F90016B4C9 /* MHConnectionViewItem.m */; }; + 02E79EAA199418400016B4C9 /* MHConnectionCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 02E79EA9199418400016B4C9 /* MHConnectionCollectionView.m */; }; + 02F2A1F71817E48B0053CB20 /* MHPreferenceWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02F2A1F61817E48B0053CB20 /* MHPreferenceWindow.xib */; }; + 02F2A1FA1817E4BC0053CB20 /* MHPreferenceWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 02F2A1F91817E4BC0053CB20 /* MHPreferenceWindowController.m */; }; + 02F4F02E19AA9F6D00A9B836 /* MHMongoHubMigration9to10.m in Sources */ = {isa = PBXBuildFile; fileRef = 02F4F02D19AA9F6D00A9B836 /* MHMongoHubMigration9to10.m */; }; + 02FCD3CF13BB9EA400316A9F /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02FCD3CE13BB9EA400316A9F /* Sparkle.framework */; }; + 02FCD3D813BBA4A300316A9F /* MCPKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02FCD3D713BBA4A300316A9F /* MCPKit.framework */; }; + 02FCD3D913BCC7D200316A9F /* RegexKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 026B2DE413BB6FB8009BEA7B /* RegexKit.framework */; }; + 02FCD3DA13BCC81700316A9F /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 02FCD3CE13BB9EA400316A9F /* Sparkle.framework */; }; + 02FCD3DB13BCC83200316A9F /* MCPKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 02FCD3D713BBA4A300316A9F /* MCPKit.framework */; }; 1D1D65541189C5E000582917 /* collectionmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D1D65501189C5E000582917 /* collectionmenu.png */; }; 1D1D65551189C5E000582917 /* dbmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D1D65511189C5E000582917 /* dbmenu.png */; }; 1D1D65561189C5E000582917 /* querymenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D1D65521189C5E000582917 /* querymenu.png */; }; @@ -14,376 +122,517 @@ 1D1D65651189C93400582917 /* supportmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D1D65641189C93400582917 /* supportmenu.png */; }; 1D1D65A31189F05600582917 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D1D65A21189F05600582917 /* Icon.icns */; }; 1D210BFB1192FF06000EF41C /* key.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D210BFA1192FF06000EF41C /* key.png */; }; - 1D210BFE119301BA000EF41C /* AuthWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D210BFD119301BA000EF41C /* AuthWindowController.m */; }; - 1D210C0011930E18000EF41C /* Auth.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D210BFF11930E18000EF41C /* Auth.xib */; }; - 1D26614E11CFC47C0092C6B5 /* ExportWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D26614D11CFC47C0092C6B5 /* ExportWindowController.mm */; }; - 1D26615211CFC5BE0092C6B5 /* Export.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D26615111CFC5BE0092C6B5 /* Export.xib */; }; + 1D26614E11CFC47C0092C6B5 /* MHMysqlExportWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D26614D11CFC47C0092C6B5 /* MHMysqlExportWindowController.m */; }; + 1D26615211CFC5BE0092C6B5 /* MysqlExport.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D26615111CFC5BE0092C6B5 /* MysqlExport.xib */; }; 1D26619111CFD1640092C6B5 /* FieldMapDataObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D26619011CFD1640092C6B5 /* FieldMapDataObject.m */; }; 1D26619411CFD2560092C6B5 /* FieldMapTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D26619311CFD2560092C6B5 /* FieldMapTableController.m */; }; - 1D317EEC12F0A88900255AF7 /* RegexKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D317EEB12F0A88900255AF7 /* RegexKit.framework */; }; - 1D317F0512F0A8AE00255AF7 /* RegexKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D317EEB12F0A88900255AF7 /* RegexKit.framework */; }; 1D58BE0B118ED8D20045A044 /* mapreducemenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D58BE0A118ED8D20045A044 /* mapreducemenu.png */; }; - 1D58BE37118EFF810045A044 /* BWToolkitFramework.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D93C24A118334F6003216F7 /* BWToolkitFramework.framework */; }; 1D601B3811C8E13000C86274 /* importmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D601B3611C8E13000C86274 /* importmenu.png */; }; 1D601B3911C8E13000C86274 /* exportmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D601B3711C8E13000C86274 /* exportmenu.png */; }; 1D601B3D11C8E7F900C86274 /* exportbox.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D601B3B11C8E7F900C86274 /* exportbox.png */; }; 1D601B3E11C8E7F900C86274 /* importbox.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D601B3C11C8E7F900C86274 /* importbox.png */; }; - 1D601B5211C8F08C00C86274 /* ImportWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D601B5111C8F08C00C86274 /* ImportWindowController.mm */; }; - 1D601B5611C8F24300C86274 /* Import.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D601B5511C8F24300C86274 /* Import.xib */; }; - 1D64100212C8E16C0030AA4C /* NSArray+Color.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D64100112C8E16C0030AA4C /* NSArray+Color.m */; }; + 1D601B5211C8F08C00C86274 /* MHMysqlImportWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D601B5111C8F08C00C86274 /* MHMysqlImportWindowController.m */; }; + 1D601B5611C8F24300C86274 /* MysqlImport.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D601B5511C8F24300C86274 /* MysqlImport.xib */; }; 1D64100512C8E1C00030AA4C /* NSScanner+SkipUpToCharset.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D64100412C8E1C00030AA4C /* NSScanner+SkipUpToCharset.m */; }; 1D64100812C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D64100712C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m */; }; - 1D64100D12C8E3D90030AA4C /* JsonWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D64100C12C8E3D90030AA4C /* JsonWindowController.mm */; }; - 1D64100F12C8E6BE0030AA4C /* JsonWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D64100E12C8E6BE0030AA4C /* JsonWindow.xib */; }; - 1D799455118755EE009C187F /* AddDBController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D799454118755EE009C187F /* AddDBController.m */; }; - 1D79945711875E7A009C187F /* NewDB.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D79945611875E7A009C187F /* NewDB.xib */; }; + 1D64100D12C8E3D90030AA4C /* MHJsonWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D64100C12C8E3D90030AA4C /* MHJsonWindowController.m */; }; + 1D64100F12C8E6BE0030AA4C /* MHJsonWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D64100E12C8E6BE0030AA4C /* MHJsonWindow.xib */; }; 1D8A624E11897C6800D55937 /* indexmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D8A624D11897C6800D55937 /* indexmenu.png */; }; - 1D93C1AE11832A71003216F7 /* libmongoclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C1AD11832A71003216F7 /* libmongoclient.a */; }; - 1D93C1DA11832C1D003216F7 /* Connection.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C1D911832C1D003216F7 /* Connection.m */; }; - 1D93C1E411833342003216F7 /* ConnectionsCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C1DF11833342003216F7 /* ConnectionsCollectionView.m */; }; - 1D93C1E511833342003216F7 /* IconCollectionItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C1E111833342003216F7 /* IconCollectionItem.m */; }; - 1D93C1E611833342003216F7 /* IconViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C1E311833342003216F7 /* IconViewBox.m */; }; - 1D93C24B118334F6003216F7 /* BWToolkitFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C24A118334F6003216F7 /* BWToolkitFramework.framework */; }; + 1D93C1DA11832C1D003216F7 /* MHConnectionStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C1D911832C1D003216F7 /* MHConnectionStore.m */; }; 1D93C24F11833599003216F7 /* ConnectionsArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C24E11833599003216F7 /* ConnectionsArrayController.m */; }; 1D93C27211833A19003216F7 /* database.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C27111833A19003216F7 /* database.png */; }; - 1D93C29A11833F26003216F7 /* Database.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C29911833F26003216F7 /* Database.m */; }; - 1D93C29E118341D4003216F7 /* AddConnectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C29D118341D4003216F7 /* AddConnectionController.m */; }; - 1D93C2A0118343EF003216F7 /* NewConnection.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C29F118343EF003216F7 /* NewConnection.xib */; }; + 1D93C2A0118343EF003216F7 /* MHConnectionEditorWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C29F118343EF003216F7 /* MHConnectionEditorWindow.xib */; }; 1D93C37C11835BB4003216F7 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C37B11835BB4003216F7 /* QuartzCore.framework */; }; - 1D93C38711835D2A003216F7 /* EditConnectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C38611835D2A003216F7 /* EditConnectionController.m */; }; - 1D93C38A11835FB8003216F7 /* EditConnection.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C38911835FB8003216F7 /* EditConnection.xib */; }; 1D93C3B111836510003216F7 /* connecticon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C3AF11836510003216F7 /* connecticon.png */; }; - 1D93C3B211836510003216F7 /* editicon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C3B011836510003216F7 /* editicon.png */; }; - 1D93C3CF11836863003216F7 /* ConnectionWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C3CE11836863003216F7 /* ConnectionWindowController.mm */; }; - 1D93C3D11183690E003216F7 /* ConnectionWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C3D01183690E003216F7 /* ConnectionWindow.xib */; }; - 1D93C40211836DC2003216F7 /* ConnectionWindowTitleTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C40111836DC2003216F7 /* ConnectionWindowTitleTransformer.m */; }; + 1D93C3B211836510003216F7 /* editmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C3B011836510003216F7 /* editmenu.png */; }; 1D93C42C1183744D003216F7 /* collectionicon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C42A1183744D003216F7 /* collectionicon.png */; }; 1D93C42D1183744D003216F7 /* dbicon.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D93C42B1183744D003216F7 /* dbicon.png */; }; - 1D93C45311837668003216F7 /* Sidebar.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C44E11837668003216F7 /* Sidebar.m */; }; 1D93C45411837668003216F7 /* SidebarBadgeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C45011837668003216F7 /* SidebarBadgeCell.m */; }; - 1D93C45511837668003216F7 /* SidebarNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C45211837668003216F7 /* SidebarNode.m */; }; - 1D93C5F01183992E003216F7 /* libboost_system.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C5EF1183992E003216F7 /* libboost_system.a */; }; - 1D93C5F211839940003216F7 /* libboost_thread.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C5F111839940003216F7 /* libboost_thread.a */; }; - 1D93C5F411839959003216F7 /* libboost_filesystem.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C5F311839959003216F7 /* libboost_filesystem.a */; }; - 1D93C5F611839970003216F7 /* libboost_program_options.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D93C5F511839970003216F7 /* libboost_program_options.a */; }; - 1D93C60B11841865003216F7 /* MongoDB.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C60A11841865003216F7 /* MongoDB.mm */; }; - 1D93C7491184369D003216F7 /* DatabasesArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93C7481184369D003216F7 /* DatabasesArrayController.m */; }; - 1D93CB5C1184C243003216F7 /* ResultsOutlineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D93CB5B1184C243003216F7 /* ResultsOutlineViewController.m */; }; 1DA68047118875B300DFDD29 /* findmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DA68042118875B300DFDD29 /* findmenu.png */; }; 1DA68048118875B300DFDD29 /* insertmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DA68043118875B300DFDD29 /* insertmenu.png */; }; 1DA68049118875B300DFDD29 /* removemenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DA68044118875B300DFDD29 /* removemenu.png */; }; 1DA6804A118875B300DFDD29 /* runmenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DA68045118875B300DFDD29 /* runmenu.png */; }; - 1DA6804B118875B300DFDD29 /* updatemenu.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DA68046118875B300DFDD29 /* updatemenu.png */; }; - 1DA6806C11888BDD00DFDD29 /* NSString+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DA6806B11888BDD00DFDD29 /* NSString+Extras.m */; }; - 1DBFFAF512C1FDF200B643CA /* NSProgressIndicator+Extras.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DBFFAF412C1FDF200B643CA /* NSProgressIndicator+Extras.m */; }; - 1DCB3CFF12C63CD400423160 /* MongoHub_DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1DCB3CFE12C63CD400423160 /* MongoHub_DataModel.xcdatamodeld */; }; - 1DCC562912C264600025F181 /* StatMonitorTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DCC562812C264600025F181 /* StatMonitorTableController.m */; }; - 1DD1CA8312C8EFD4007F2909 /* SyntaxDefinition.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD1CA8112C8EFD4007F2909 /* SyntaxDefinition.plist */; }; - 1DD1CA8412C8EFD4007F2909 /* SyntaxColorDefaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD1CA8212C8EFD4007F2909 /* SyntaxColorDefaults.plist */; }; - 1DD1CA8912C8F004007F2909 /* CSS 1.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD1CA8612C8F004007F2909 /* CSS 1.plist */; }; - 1DD1CA8A12C8F004007F2909 /* HTML.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD1CA8712C8F004007F2909 /* HTML.plist */; }; - 1DD1CA8B12C8F004007F2909 /* Objective C.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD1CA8812C8F004007F2909 /* Objective C.plist */; }; - 1DDC486912CB7758009924A1 /* JSON.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DDC486812CB7758009924A1 /* JSON.plist */; }; - 1DEC7F3B12B7ECAD00FC804E /* Tunnel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEC7F3A12B7ECAC00FC804E /* Tunnel.m */; }; + 1DA6806C11888BDD00DFDD29 /* NSString+MongoHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DA6806B11888BDD00DFDD29 /* NSString+MongoHub.m */; }; + 1DDC486912CB7758009924A1 /* SyntaxDefinition.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DDC486812CB7758009924A1 /* SyntaxDefinition.plist */; }; + 1DEC7F3B12B7ECAD00FC804E /* MHTunnel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEC7F3A12B7ECAC00FC804E /* MHTunnel.m */; }; 1DEC7FF112B7EDB900FC804E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DEC7FF012B7EDB900FC804E /* Security.framework */; }; 1DEC803512B7EE2100FC804E /* SSHCommand.sh in Resources */ = {isa = PBXBuildFile; fileRef = 1DEC803412B7EE2100FC804E /* SSHCommand.sh */; }; - 1DF865D811C8FEF000DF7493 /* MCPKit_bundled.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF865D711C8FEF000DF7493 /* MCPKit_bundled.framework */; }; - 1DF8660F11C8FF1D00DF7493 /* MCPKit_bundled.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DF865D711C8FEF000DF7493 /* MCPKit_bundled.framework */; }; - 1DF96E3B11881AED00C35AB8 /* AddCollectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF96E3A11881AED00C35AB8 /* AddCollectionController.m */; }; - 1DF96E3D11881EB400C35AB8 /* NewCollection.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DF96E3C11881EB400C35AB8 /* NewCollection.xib */; }; - 1DF96F9211883B3800C35AB8 /* QueryWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1DF96F9111883B3800C35AB8 /* QueryWindowController.mm */; }; - 1DF96F9411883D5E00C35AB8 /* QueryWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DF96F9311883D5E00C35AB8 /* QueryWindow.xib */; }; - 1DFC2A7C11970A1E006AA167 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DFC2A7B11970A1E006AA167 /* Sparkle.framework */; }; - 1DFC2A8211970A35006AA167 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DFC2A7B11970A1E006AA167 /* Sparkle.framework */; }; - 1DFC2A8D11970BD0006AA167 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 1DFC2A8C11970BD0006AA167 /* dsa_pub.pem */; }; - 2F7446990DB6B7EA00F9684A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F7446970DB6B7EA00F9684A /* MainMenu.xib */; }; - 77C8280E06725ACE000B614F /* MongoHub_AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 77C8280C06725ACE000B614F /* MongoHub_AppDelegate.m */; }; - 797A78450DDCFB3E0050D0C2 /* GetMetadataForFile.c in Sources */ = {isa = PBXBuildFile; fileRef = 797A783F0DDCFB3E0050D0C2 /* GetMetadataForFile.c */; }; - 797A78480DDCFB3E0050D0C2 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 797A78420DDCFB3E0050D0C2 /* main.c */; }; - 797A78490DDCFB3E0050D0C2 /* MySpotlightImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 797A78440DDCFB3E0050D0C2 /* MySpotlightImporter.m */; }; - 797A784A0DDCFC070050D0C2 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77C82804067257F0000B614F /* CoreData.framework */; }; - 797A784B0DDCFC090050D0C2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29B97325FDCFA39411CA2CEA /* Foundation.framework */; }; - 797A7AE20DDCFCE80050D0C2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 797A7AE10DDCFCE80050D0C2 /* CoreFoundation.framework */; }; - 797A7AE40DDCFCF40050D0C2 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 797A7AE30DDCFCF40050D0C2 /* CoreServices.framework */; }; - 799CAA890DDE04C70030CB95 /* MongoHub.mdimporter in CopyFiles */ = {isa = PBXBuildFile; fileRef = 797A78390DDCFADE0050D0C2 /* MongoHub.mdimporter */; }; + 1DF96E3B11881AED00C35AB8 /* MHEditNameWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF96E3A11881AED00C35AB8 /* MHEditNameWindowController.m */; }; + 1DF96E3D11881EB400C35AB8 /* MHEditNameWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DF96E3C11881EB400C35AB8 /* MHEditNameWindow.xib */; }; + 1DF96F9211883B3800C35AB8 /* MHQueryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF96F9111883B3800C35AB8 /* MHQueryViewController.m */; }; + 1DF96F9411883D5E00C35AB8 /* MHQueryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DF96F9311883D5E00C35AB8 /* MHQueryView.xib */; }; + 2F7446990DB6B7EA00F9684A /* MHMainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F7446970DB6B7EA00F9684A /* MHMainMenu.xib */; }; + 77C8280E06725ACE000B614F /* MHApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 77C8280C06725ACE000B614F /* MHApplicationDelegate.m */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 790512FB0DDD0A100070760D /* PBXContainerItemProxy */ = { + 02216F631412D6F000789BD1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; proxyType = 1; - remoteGlobalIDString = 797A78380DDCFADE0050D0C2; - remoteInfo = "MongoHub Spotlight Importer"; + remoteGlobalIDString = 02216F201412D54600789BD1; + remoteInfo = Submodules; + }; + 027062C719DF803600E6C36A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 02C4C15F19A230BE0002FBD8 /* MongoObjCDriver.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 02E6400C19DB68F900FEFEFC; + remoteInfo = "MongoObjCDriver Tests"; + }; + 029464D919F57AF700E1B1E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 02C4C15F19A230BE0002FBD8 /* MongoObjCDriver.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 02F4EA7A19F1ABF400BE9695; + remoteInfo = test; + }; + 02C4C1C419A230BE0002FBD8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 02C4C15F19A230BE0002FBD8 /* MongoObjCDriver.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 02ABA1C014103B37000417F4; + remoteInfo = MongoObjCDriver; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 1D317F0A12F0A8C600255AF7 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 1D317F0512F0A8AE00255AF7 /* RegexKit.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 1D58BE3A118EFF840045A044 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 1D58BE37118EFF810045A044 /* BWToolkitFramework.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1DF8661511C8FF2600DF7493 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 1DF8660F11C8FF1D00DF7493 /* MCPKit_bundled.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 1DFC2A8B11970A4A006AA167 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 1DFC2A8211970A35006AA167 /* Sparkle.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 7905130A0DDD0A660070760D /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ../Library/Spotlight; - dstSubfolderSpec = 7; - files = ( - 799CAA890DDE04C70030CB95 /* MongoHub.mdimporter in CopyFiles */, + 02C4C1CA19A231600002FBD8 /* MongoObjCDriver.framework in CopyFiles */, + 02FCD3D913BCC7D200316A9F /* RegexKit.framework in CopyFiles */, + 02FCD3DA13BCC81700316A9F /* Sparkle.framework in CopyFiles */, + 02FCD3DB13BCC83200316A9F /* MCPKit.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 020F511714896DE700D4B54B /* MHTabViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTabViewController.h; sourceTree = ""; }; + 020F511814896DE700D4B54B /* MHTabViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHTabViewController.m; sourceTree = ""; }; + 020F511914896DE700D4B54B /* MHTabView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHTabView.xib; sourceTree = ""; }; + 020F5125148973BA00D4B54B /* MHStatusViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHStatusViewController.h; sourceTree = ""; }; + 020F5126148973BA00D4B54B /* MHStatusViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHStatusViewController.m; sourceTree = ""; }; + 020F5127148973BA00D4B54B /* MHStatusView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHStatusView.xib; sourceTree = ""; }; + 021315AD198ABF41006378C5 /* MHMongoHubMigration7to8.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = MHMongoHubMigration7to8.xcmappingmodel; sourceTree = ""; }; + 0213CAF31431FEF50027795D /* mongohub_su_feed.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = mongohub_su_feed.xml; sourceTree = ""; }; + 021BEA651463709A0091C2EA /* MongoHub_DataModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel.xcdatamodel; sourceTree = ""; }; + 021BEA661463709A0091C2EA /* MongoHub_DataModel1.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel1.0.xcdatamodel; sourceTree = ""; }; + 021BEA671463709A0091C2EA /* MongoHub_DataModel2.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel2.0.xcdatamodel; sourceTree = ""; }; + 022F33711AD7192300324917 /* MHConnectionListWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionListWindowController.h; sourceTree = ""; }; + 022F33721AD7192300324917 /* MHConnectionListWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionListWindowController.m; sourceTree = ""; }; + 0230662619E7FD07006F5C8C /* querymenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "querymenu@2x.png"; sourceTree = ""; }; + 023230AC15E051300075498C /* MHConnectionEditorWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionEditorWindowController.h; sourceTree = ""; }; + 023230AD15E051300075498C /* MHConnectionEditorWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionEditorWindowController.m; sourceTree = ""; }; + 0242F119198922B800C73FEC /* MHMongoHubMigration6to7.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = MHMongoHubMigration6to7.xcmappingmodel; sourceTree = ""; }; + 0242F11B1989475F00C73FEC /* MongoHub.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = MongoHub.entitlements; sourceTree = ""; }; + 0242F133198ABAA900C73FEC /* MongoHub_DataModel8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel8.xcdatamodel; sourceTree = ""; }; + 0242F136198ABE3E00C73FEC /* MHMongoHubMigration7to8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMongoHubMigration7to8.h; sourceTree = ""; }; + 0242F137198ABE3E00C73FEC /* MHMongoHubMigration7to8.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMongoHubMigration7to8.m; sourceTree = ""; }; + 0243B79119EC357700D06BFE /* MHQueryUpdateOperatorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHQueryUpdateOperatorView.xib; sourceTree = ""; }; + 024F678E1427F3DE00956BF6 /* MODHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MODHelper.h; sourceTree = ""; }; + 024F678F1427F3DE00956BF6 /* MODHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MODHelper.m; sourceTree = ""; }; + 0252361018FEC2E100286EC9 /* MHExporterImporter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MHExporterImporter.h; sourceTree = ""; }; + 0252361118FECEE700286EC9 /* MHExporterImporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHExporterImporter.m; sourceTree = ""; }; + 025410A119AA687C00CF437E /* MongoHub_DataModel10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel10.xcdatamodel; sourceTree = ""; }; + 0255B566181A9A210019739D /* MHKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHKeychain.h; sourceTree = ""; }; + 0255B567181A9A210019739D /* MHKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHKeychain.m; sourceTree = ""; }; + 0258606A19BD3E2A001EDF8A /* MongoHub_DataModel12.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel12.xcdatamodel; sourceTree = ""; }; + 0259EAFD19AF5CF000181E08 /* MHLogWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHLogWindow.xib; sourceTree = ""; }; + 0259EB0319AF5D6600181E08 /* MHLogWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHLogWindowController.h; sourceTree = ""; }; + 0259EB0419AF5D6600181E08 /* MHLogWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHLogWindowController.m; sourceTree = ""; }; + 0259EB6319B01E7800181E08 /* MHJsonColorManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHJsonColorManager.h; sourceTree = ""; }; + 0259EB6419B01E7800181E08 /* MHJsonColorManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHJsonColorManager.m; sourceTree = ""; }; + 025B8F0A1531C76E00849A71 /* MHTabTitleContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTabTitleContainerView.h; sourceTree = ""; }; + 025B8F0B1531C76E00849A71 /* MHTabTitleContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHTabTitleContainerView.m; sourceTree = ""; }; + 025B8F901531FC7500849A71 /* unselected-tab-border.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unselected-tab-border.png"; sourceTree = ""; }; + 025CBC6C1982AE4E00C8E272 /* MHMongoHubMigration6to7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMongoHubMigration6to7.h; sourceTree = ""; }; + 025CBC6D1982AE4E00C8E272 /* MHMongoHubMigration6to7.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMongoHubMigration6to7.m; sourceTree = ""; }; + 025F635015AE21F300CD0EB4 /* NSViewHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSViewHelpers.h; sourceTree = ""; }; + 025F635115AE21F300CD0EB4 /* NSViewHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSViewHelpers.m; sourceTree = ""; }; + 0260B93F19B3A4AB00940188 /* MongoHub_DataModel11.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel11.xcdatamodel; sourceTree = ""; }; + 0262CA39148C14A8009033F9 /* MHTabItemViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTabItemViewController.h; sourceTree = ""; }; + 0262CA3A148C14A8009033F9 /* MHTabItemViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHTabItemViewController.m; sourceTree = ""; }; + 0262CA3E148C1838009033F9 /* MHConnectionWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionWindowController.m; sourceTree = ""; }; + 0262CA40148C1852009033F9 /* MHQueryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHQueryViewController.h; sourceTree = ""; }; + 02683D5D1442759100467EBE /* README.markdown */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.markdown; path = ../README.markdown; sourceTree = ""; }; + 026B2DE413BB6FB8009BEA7B /* RegexKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RegexKit.framework; sourceTree = ""; }; + 027062A719DF803600E6C36A /* unselected-tab-border@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unselected-tab-border@2x.png"; sourceTree = ""; }; + 027062A819DF803600E6C36A /* unselected-tab-background@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unselected-tab-background@2x.png"; sourceTree = ""; }; + 027062A919DF803600E6C36A /* overlay_close_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "overlay_close_button@2x.png"; sourceTree = ""; }; + 027062AA19DF803600E6C36A /* grip_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "grip_button@2x.png"; sourceTree = ""; }; + 027062AB19DF803600E6C36A /* close_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "close_button@2x.png"; sourceTree = ""; }; + 027062AC19DF803600E6C36A /* button_ArrowRight_overlay@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_ArrowRight_overlay@2x.png"; sourceTree = ""; }; + 027062AD19DF803600E6C36A /* button_ArrowRight_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button_ArrowRight_default@2x.png"; sourceTree = ""; }; + 027062AE19DF803600E6C36A /* background-grey_right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-grey_right@2x.png"; sourceTree = ""; }; + 027062AF19DF803600E6C36A /* background-grey_left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-grey_left@2x.png"; sourceTree = ""; }; + 027062B019DF803600E6C36A /* background-grey_center@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-grey_center@2x.png"; sourceTree = ""; }; + 027062B119DF803600E6C36A /* background_blue_right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background_blue_right@2x.png"; sourceTree = ""; }; + 027062B219DF803600E6C36A /* background_blue_left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background_blue_left@2x.png"; sourceTree = ""; }; + 027062B319DF803600E6C36A /* background_blue_center@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background_blue_center@2x.png"; sourceTree = ""; }; + 027062B419DF803600E6C36A /* background_blue_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background_blue_arrow@2x.png"; sourceTree = ""; }; + 027062CB19DF822600E6C36A /* removemenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "removemenu@2x.png"; sourceTree = ""; }; + 027062CC19DF822600E6C36A /* mapreducemenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "mapreducemenu@2x.png"; sourceTree = ""; }; + 027062CD19DF822600E6C36A /* insertmenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "insertmenu@2x.png"; sourceTree = ""; }; + 027062CE19DF822600E6C36A /* indexmenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "indexmenu@2x.png"; sourceTree = ""; }; + 027062CF19DF822600E6C36A /* findmenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "findmenu@2x.png"; sourceTree = ""; }; + 027062D019DF822600E6C36A /* editmenu@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "editmenu@2x.png"; sourceTree = ""; }; + 0279C08F189C02F600F8BACB /* MHImportExportFeedback.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHImportExportFeedback.xib; sourceTree = ""; }; + 0279C091189C03E000F8BACB /* MHImportExportFeedback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHImportExportFeedback.h; sourceTree = ""; }; + 0279C092189C03E000F8BACB /* MHImportExportFeedback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHImportExportFeedback.m; sourceTree = ""; }; + 028C6DEE19F874D60014B4C0 /* ALIterativeMigrator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ALIterativeMigrator.h; sourceTree = ""; }; + 028C6DEF19F874D60014B4C0 /* ALIterativeMigrator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ALIterativeMigrator.m; sourceTree = ""; }; + 02940E021982A17A005AF3C1 /* MongoHub_DataModel7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel7.xcdatamodel; sourceTree = ""; }; + 029464DB19F588B900E1B1E6 /* MHActivityMonitorTab.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHActivityMonitorTab.xib; sourceTree = ""; }; + 029464DD19F5899F00E1B1E6 /* MHActivityMonitorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHActivityMonitorViewController.h; sourceTree = ""; }; + 029464DE19F5899F00E1B1E6 /* MHActivityMonitorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHActivityMonitorViewController.m; sourceTree = ""; }; + 029464E019F58C4400E1B1E6 /* ActivityMonitor.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = ActivityMonitor.icns; sourceTree = ""; }; + 029CAA711946028800FD44B4 /* NSTextView+MongoHub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTextView+MongoHub.h"; sourceTree = ""; }; + 029CAA721946028800FD44B4 /* NSTextView+MongoHub.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTextView+MongoHub.m"; sourceTree = ""; }; + 029D30A3145613420021B9C9 /* MHDatabaseItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHDatabaseItem.h; sourceTree = ""; }; + 029D30A4145613420021B9C9 /* MHDatabaseItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHDatabaseItem.m; sourceTree = ""; }; + 029D30A7145613580021B9C9 /* MHCollectionItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHCollectionItem.h; sourceTree = ""; }; + 029D30A8145613580021B9C9 /* MHCollectionItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHCollectionItem.m; sourceTree = ""; }; + 029D30AA145613C30021B9C9 /* MHClientItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHClientItem.h; sourceTree = ""; }; + 029D30AB145613C30021B9C9 /* MHClientItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHClientItem.m; sourceTree = ""; }; + 02A7C4081482DEDD0099CDD1 /* MHMysqlImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMysqlImporter.h; sourceTree = ""; }; + 02A7C4091482DEDD0099CDD1 /* MHMysqlImporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMysqlImporter.m; sourceTree = ""; }; + 02A7C40C1482DF080099CDD1 /* MHMysqlExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMysqlExporter.h; sourceTree = ""; }; + 02A7C40D1482DF080099CDD1 /* MHMysqlExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMysqlExporter.m; sourceTree = ""; }; + 02A9B23D19E716FE002A73E4 /* MongoHub_DataModel13.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel13.xcdatamodel; sourceTree = ""; }; + 02AA29911477F8BD0041865F /* MHFileExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHFileExporter.h; sourceTree = ""; }; + 02AA29921477F8BD0041865F /* MHFileExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHFileExporter.m; sourceTree = ""; }; + 02AB33A6194850BD008C06B9 /* MongoHub_DataModel3.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel3.0.xcdatamodel; sourceTree = ""; }; + 02AB33AF194880AB008C06B9 /* MongoHub_DataModel4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel4.xcdatamodel; sourceTree = ""; }; + 02ABF65D19E09C76009F4766 /* MHDatabaseCollectionOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHDatabaseCollectionOutlineView.h; sourceTree = ""; }; + 02ABF65E19E09C76009F4766 /* MHDatabaseCollectionOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHDatabaseCollectionOutlineView.m; sourceTree = ""; }; + 02AF1BEC1962B4F000926F75 /* MongoHub_DataModel5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel5.xcdatamodel; sourceTree = ""; }; + 02B143DA147C720D005AB320 /* MHFileImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHFileImporter.h; sourceTree = ""; }; + 02B143DB147C720D005AB320 /* MHFileImporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHFileImporter.m; sourceTree = ""; }; + 02B7CCE4197AA07D0031A57A /* MongoHub_DataModel6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel6.xcdatamodel; sourceTree = ""; }; + 02C345291A423C85004F0D2C /* MHIndexEditor.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHIndexEditor.xib; sourceTree = ""; }; + 02C345301A436A18004F0D2C /* MHIndexEditorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHIndexEditorController.h; sourceTree = ""; }; + 02C345311A436A18004F0D2C /* MHIndexEditorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHIndexEditorController.m; sourceTree = ""; }; + 02C4C15F19A230BE0002FBD8 /* MongoObjCDriver.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = MongoObjCDriver.xcodeproj; sourceTree = ""; }; + 02CEE9BC1486DD7A00E488DA /* MHTabTitleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTabTitleView.h; sourceTree = ""; }; + 02CEE9BD1486DD7A00E488DA /* MHTabTitleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHTabTitleView.m; sourceTree = ""; }; + 02CF9CC819AA9E8A00EEF76B /* MHMongoHubMigration9to10.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = MHMongoHubMigration9to10.xcmappingmodel; sourceTree = ""; }; + 02D3D99F1AAA4DD000FE5566 /* MHDocumentOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHDocumentOutlineViewController.h; sourceTree = ""; }; + 02D3D9A01AAA4DD000FE5566 /* MHDocumentOutlineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHDocumentOutlineViewController.m; sourceTree = ""; }; + 02D3D9A71AAA512B00FE5566 /* MHDocumentOutlineView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHDocumentOutlineView.xib; sourceTree = ""; }; + 02D83DFF19A4A1A9007AB2F2 /* NSDictionary+MongoHub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MongoHub.h"; sourceTree = ""; }; + 02D83E0119A4A28F007AB2F2 /* NSDictionary+MongoHub.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+MongoHub.m"; sourceTree = ""; }; + 02E0FE29151DE2420094C1CD /* background-grey_center.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-grey_center.png"; sourceTree = ""; }; + 02E0FE2A151DE2420094C1CD /* background-grey_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-grey_left.png"; sourceTree = ""; }; + 02E0FE2B151DE2420094C1CD /* background-grey_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "background-grey_right.png"; sourceTree = ""; }; + 02E0FE2C151DE2420094C1CD /* background_blue_arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background_blue_arrow.png; sourceTree = ""; }; + 02E0FE2D151DE2420094C1CD /* background_blue_center.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background_blue_center.png; sourceTree = ""; }; + 02E0FE2E151DE2420094C1CD /* background_blue_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background_blue_left.png; sourceTree = ""; }; + 02E0FE2F151DE2420094C1CD /* background_blue_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background_blue_right.png; sourceTree = ""; }; + 02E0FE30151DE2420094C1CD /* unselected-tab-background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unselected-tab-background.png"; sourceTree = ""; }; + 02E0FE31151DE2420094C1CD /* grip_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = grip_button.png; sourceTree = ""; }; + 02E0FE32151DE2420094C1CD /* button_ArrowRight_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = button_ArrowRight_default.png; sourceTree = ""; }; + 02E0FE33151DE2420094C1CD /* button_ArrowRight_overlay.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = button_ArrowRight_overlay.png; sourceTree = ""; }; + 02E0FE34151DE2420094C1CD /* close_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = close_button.png; sourceTree = ""; }; + 02E0FE35151DE2420094C1CD /* overlay_close_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = overlay_close_button.png; sourceTree = ""; }; + 02E79E9C199275A60016B4C9 /* MongoHub_DataModel9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel9.xcdatamodel; sourceTree = ""; }; + 02E79EA21993E7950016B4C9 /* MHConnectionIconView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionIconView.h; sourceTree = ""; }; + 02E79EA31993E7950016B4C9 /* MHConnectionIconView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionIconView.m; sourceTree = ""; }; + 02E79EA51993F3F90016B4C9 /* MHConnectionViewItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionViewItem.h; sourceTree = ""; }; + 02E79EA61993F3F90016B4C9 /* MHConnectionViewItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionViewItem.m; sourceTree = ""; }; + 02E79EA8199418400016B4C9 /* MHConnectionCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionCollectionView.h; sourceTree = ""; }; + 02E79EA9199418400016B4C9 /* MHConnectionCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionCollectionView.m; sourceTree = ""; }; + 02F2A1F61817E48B0053CB20 /* MHPreferenceWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MHPreferenceWindow.xib; sourceTree = ""; }; + 02F2A1F81817E4BC0053CB20 /* MHPreferenceWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHPreferenceWindowController.h; sourceTree = ""; }; + 02F2A1F91817E4BC0053CB20 /* MHPreferenceWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHPreferenceWindowController.m; sourceTree = ""; }; + 02F4F02C19AA9F6D00A9B836 /* MHMongoHubMigration9to10.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMongoHubMigration9to10.h; sourceTree = ""; }; + 02F4F02D19AA9F6D00A9B836 /* MHMongoHubMigration9to10.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMongoHubMigration9to10.m; sourceTree = ""; }; + 02FCD3CE13BB9EA400316A9F /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = ""; }; + 02FCD3D713BBA4A300316A9F /* MCPKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MCPKit.framework; sourceTree = ""; }; 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 1D1D65501189C5E000582917 /* collectionmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = collectionmenu.png; path = Resourses/images/collectionmenu.png; sourceTree = SOURCE_ROOT; }; - 1D1D65511189C5E000582917 /* dbmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dbmenu.png; path = Resourses/images/dbmenu.png; sourceTree = SOURCE_ROOT; }; - 1D1D65521189C5E000582917 /* querymenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = querymenu.png; path = Resourses/images/querymenu.png; sourceTree = SOURCE_ROOT; }; - 1D1D65531189C5E000582917 /* servermenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = servermenu.png; path = Resourses/images/servermenu.png; sourceTree = SOURCE_ROOT; }; - 1D1D65641189C93400582917 /* supportmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = supportmenu.png; path = Resourses/images/supportmenu.png; sourceTree = SOURCE_ROOT; }; - 1D1D65A21189F05600582917 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Icon.icns; path = Resourses/images/Icon.icns; sourceTree = SOURCE_ROOT; }; - 1D210BFA1192FF06000EF41C /* key.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = key.png; path = Resourses/images/key.png; sourceTree = SOURCE_ROOT; }; - 1D210BFC119301BA000EF41C /* AuthWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthWindowController.h; sourceTree = ""; }; - 1D210BFD119301BA000EF41C /* AuthWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthWindowController.m; sourceTree = ""; }; - 1D210BFF11930E18000EF41C /* Auth.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Auth.xib; sourceTree = ""; }; - 1D26614C11CFC47C0092C6B5 /* ExportWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExportWindowController.h; sourceTree = ""; }; - 1D26614D11CFC47C0092C6B5 /* ExportWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ExportWindowController.mm; sourceTree = ""; }; - 1D26615111CFC5BE0092C6B5 /* Export.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Export.xib; sourceTree = ""; }; + 1D1D65501189C5E000582917 /* collectionmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = collectionmenu.png; path = Resources/images/collectionmenu.png; sourceTree = SOURCE_ROOT; }; + 1D1D65511189C5E000582917 /* dbmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dbmenu.png; path = Resources/images/dbmenu.png; sourceTree = SOURCE_ROOT; }; + 1D1D65521189C5E000582917 /* querymenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = querymenu.png; path = Resources/images/querymenu.png; sourceTree = SOURCE_ROOT; }; + 1D1D65531189C5E000582917 /* servermenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = servermenu.png; path = Resources/images/servermenu.png; sourceTree = SOURCE_ROOT; }; + 1D1D65641189C93400582917 /* supportmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = supportmenu.png; path = Resources/images/supportmenu.png; sourceTree = SOURCE_ROOT; }; + 1D1D65A21189F05600582917 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Icon.icns; path = Resources/images/Icon.icns; sourceTree = SOURCE_ROOT; }; + 1D210BFA1192FF06000EF41C /* key.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = key.png; path = Resources/images/key.png; sourceTree = SOURCE_ROOT; }; + 1D26614C11CFC47C0092C6B5 /* MHMysqlExportWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMysqlExportWindowController.h; sourceTree = ""; }; + 1D26614D11CFC47C0092C6B5 /* MHMysqlExportWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMysqlExportWindowController.m; sourceTree = ""; }; + 1D26615111CFC5BE0092C6B5 /* MysqlExport.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MysqlExport.xib; sourceTree = ""; }; 1D26618F11CFD1640092C6B5 /* FieldMapDataObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FieldMapDataObject.h; sourceTree = ""; }; 1D26619011CFD1640092C6B5 /* FieldMapDataObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FieldMapDataObject.m; sourceTree = ""; }; 1D26619211CFD2560092C6B5 /* FieldMapTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FieldMapTableController.h; sourceTree = ""; }; 1D26619311CFD2560092C6B5 /* FieldMapTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FieldMapTableController.m; sourceTree = ""; }; - 1D317EEB12F0A88900255AF7 /* RegexKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RegexKit.framework; path = Library/Frameworks/RegexKit.framework; sourceTree = SDKROOT; }; - 1D58BE0A118ED8D20045A044 /* mapreducemenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = mapreducemenu.png; path = Resourses/images/mapreducemenu.png; sourceTree = SOURCE_ROOT; }; + 1D58BE0A118ED8D20045A044 /* mapreducemenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = mapreducemenu.png; path = Resources/images/mapreducemenu.png; sourceTree = SOURCE_ROOT; }; 1D601B3611C8E13000C86274 /* importmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = importmenu.png; sourceTree = ""; }; 1D601B3711C8E13000C86274 /* exportmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = exportmenu.png; sourceTree = ""; }; - 1D601B3B11C8E7F900C86274 /* exportbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = exportbox.png; path = Resourses/images/exportbox.png; sourceTree = SOURCE_ROOT; }; - 1D601B3C11C8E7F900C86274 /* importbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = importbox.png; path = Resourses/images/importbox.png; sourceTree = SOURCE_ROOT; }; - 1D601B5011C8F08C00C86274 /* ImportWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImportWindowController.h; sourceTree = ""; }; - 1D601B5111C8F08C00C86274 /* ImportWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ImportWindowController.mm; sourceTree = ""; }; - 1D601B5511C8F24300C86274 /* Import.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Import.xib; sourceTree = ""; }; - 1D64100012C8E16C0030AA4C /* NSArray+Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Color.h"; sourceTree = ""; }; - 1D64100112C8E16C0030AA4C /* NSArray+Color.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Color.m"; sourceTree = ""; }; + 1D601B3B11C8E7F900C86274 /* exportbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = exportbox.png; path = Resources/images/exportbox.png; sourceTree = SOURCE_ROOT; }; + 1D601B3C11C8E7F900C86274 /* importbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = importbox.png; path = Resources/images/importbox.png; sourceTree = SOURCE_ROOT; }; + 1D601B5011C8F08C00C86274 /* MHMysqlImportWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHMysqlImportWindowController.h; sourceTree = ""; }; + 1D601B5111C8F08C00C86274 /* MHMysqlImportWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHMysqlImportWindowController.m; sourceTree = ""; }; + 1D601B5511C8F24300C86274 /* MysqlImport.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MysqlImport.xib; sourceTree = ""; }; 1D64100312C8E1C00030AA4C /* NSScanner+SkipUpToCharset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSScanner+SkipUpToCharset.h"; sourceTree = ""; }; 1D64100412C8E1C00030AA4C /* NSScanner+SkipUpToCharset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSScanner+SkipUpToCharset.m"; sourceTree = ""; }; - 1D64100612C8E21C0030AA4C /* UKSyntaxColoredTextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UKSyntaxColoredTextViewController.h; path = ../UKSyntaxColoredTextViewController.h; sourceTree = ""; }; - 1D64100712C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UKSyntaxColoredTextViewController.m; path = ../UKSyntaxColoredTextViewController.m; sourceTree = ""; }; - 1D64100B12C8E3D90030AA4C /* JsonWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JsonWindowController.h; sourceTree = ""; }; - 1D64100C12C8E3D90030AA4C /* JsonWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JsonWindowController.mm; sourceTree = ""; }; - 1D64100E12C8E6BE0030AA4C /* JsonWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = JsonWindow.xib; sourceTree = ""; }; - 1D799453118755EE009C187F /* AddDBController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddDBController.h; sourceTree = ""; }; - 1D799454118755EE009C187F /* AddDBController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddDBController.m; sourceTree = ""; }; - 1D79945611875E7A009C187F /* NewDB.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NewDB.xib; sourceTree = ""; }; - 1D8A624D11897C6800D55937 /* indexmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = indexmenu.png; path = Resourses/images/indexmenu.png; sourceTree = SOURCE_ROOT; }; - 1D93C1AD11832A71003216F7 /* libmongoclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmongoclient.a; path = /usr/local/lib/libmongoclient.a; sourceTree = ""; }; - 1D93C1D811832C1D003216F7 /* Connection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Connection.h; sourceTree = ""; }; - 1D93C1D911832C1D003216F7 /* Connection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Connection.m; sourceTree = ""; }; - 1D93C1DE11833342003216F7 /* ConnectionsCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionsCollectionView.h; sourceTree = ""; }; - 1D93C1DF11833342003216F7 /* ConnectionsCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnectionsCollectionView.m; sourceTree = ""; }; - 1D93C1E011833342003216F7 /* IconCollectionItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IconCollectionItem.h; sourceTree = ""; }; - 1D93C1E111833342003216F7 /* IconCollectionItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IconCollectionItem.m; sourceTree = ""; }; - 1D93C1E211833342003216F7 /* IconViewBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IconViewBox.h; sourceTree = ""; }; - 1D93C1E311833342003216F7 /* IconViewBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IconViewBox.m; sourceTree = ""; }; - 1D93C24A118334F6003216F7 /* BWToolkitFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BWToolkitFramework.framework; path = /Library/PrivateFrameWorks/BWToolkitFramework.framework; sourceTree = ""; }; + 1D64100612C8E21C0030AA4C /* UKSyntaxColoredTextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UKSyntaxColoredTextViewController.h; sourceTree = ""; }; + 1D64100712C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UKSyntaxColoredTextViewController.m; sourceTree = ""; }; + 1D64100B12C8E3D90030AA4C /* MHJsonWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHJsonWindowController.h; sourceTree = ""; }; + 1D64100C12C8E3D90030AA4C /* MHJsonWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHJsonWindowController.m; sourceTree = ""; }; + 1D64100E12C8E6BE0030AA4C /* MHJsonWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MHJsonWindow.xib; sourceTree = ""; }; + 1D8A624D11897C6800D55937 /* indexmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = indexmenu.png; path = Resources/images/indexmenu.png; sourceTree = SOURCE_ROOT; }; + 1D93C1D811832C1D003216F7 /* MHConnectionStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionStore.h; sourceTree = ""; }; + 1D93C1D911832C1D003216F7 /* MHConnectionStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHConnectionStore.m; sourceTree = ""; }; 1D93C24D11833599003216F7 /* ConnectionsArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionsArrayController.h; sourceTree = ""; }; 1D93C24E11833599003216F7 /* ConnectionsArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnectionsArrayController.m; sourceTree = ""; }; - 1D93C27111833A19003216F7 /* database.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = database.png; path = Resourses/images/database.png; sourceTree = SOURCE_ROOT; }; - 1D93C27411833C2A003216F7 /* Configure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Configure.h; sourceTree = ""; }; - 1D93C29811833F26003216F7 /* Database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Database.h; sourceTree = ""; }; - 1D93C29911833F26003216F7 /* Database.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Database.m; sourceTree = ""; }; - 1D93C29C118341D4003216F7 /* AddConnectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddConnectionController.h; sourceTree = ""; }; - 1D93C29D118341D4003216F7 /* AddConnectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddConnectionController.m; sourceTree = ""; }; - 1D93C29F118343EF003216F7 /* NewConnection.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NewConnection.xib; sourceTree = ""; }; + 1D93C27111833A19003216F7 /* database.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = database.png; path = Resources/images/database.png; sourceTree = SOURCE_ROOT; }; + 1D93C29F118343EF003216F7 /* MHConnectionEditorWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MHConnectionEditorWindow.xib; sourceTree = ""; }; 1D93C37B11835BB4003216F7 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 1D93C38511835D2A003216F7 /* EditConnectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditConnectionController.h; sourceTree = ""; }; - 1D93C38611835D2A003216F7 /* EditConnectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditConnectionController.m; sourceTree = ""; }; - 1D93C38911835FB8003216F7 /* EditConnection.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditConnection.xib; sourceTree = ""; }; - 1D93C3AF11836510003216F7 /* connecticon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = connecticon.png; path = Resourses/images/connecticon.png; sourceTree = SOURCE_ROOT; }; - 1D93C3B011836510003216F7 /* editicon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = editicon.png; path = Resourses/images/editicon.png; sourceTree = SOURCE_ROOT; }; - 1D93C3CD11836863003216F7 /* ConnectionWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionWindowController.h; sourceTree = ""; }; - 1D93C3CE11836863003216F7 /* ConnectionWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConnectionWindowController.mm; sourceTree = ""; }; - 1D93C3D01183690E003216F7 /* ConnectionWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConnectionWindow.xib; sourceTree = ""; }; - 1D93C40011836DC2003216F7 /* ConnectionWindowTitleTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionWindowTitleTransformer.h; sourceTree = ""; }; - 1D93C40111836DC2003216F7 /* ConnectionWindowTitleTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnectionWindowTitleTransformer.m; sourceTree = ""; }; - 1D93C42A1183744D003216F7 /* collectionicon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = collectionicon.png; path = Resourses/images/collectionicon.png; sourceTree = SOURCE_ROOT; }; - 1D93C42B1183744D003216F7 /* dbicon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dbicon.png; path = Resourses/images/dbicon.png; sourceTree = SOURCE_ROOT; }; - 1D93C44D11837668003216F7 /* Sidebar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sidebar.h; path = Sidebar/Sidebar.h; sourceTree = SOURCE_ROOT; }; - 1D93C44E11837668003216F7 /* Sidebar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Sidebar.m; path = Sidebar/Sidebar.m; sourceTree = SOURCE_ROOT; }; - 1D93C44F11837668003216F7 /* SidebarBadgeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SidebarBadgeCell.h; path = Sidebar/SidebarBadgeCell.h; sourceTree = SOURCE_ROOT; }; - 1D93C45011837668003216F7 /* SidebarBadgeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SidebarBadgeCell.m; path = Sidebar/SidebarBadgeCell.m; sourceTree = SOURCE_ROOT; }; - 1D93C45111837668003216F7 /* SidebarNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SidebarNode.h; path = Sidebar/SidebarNode.h; sourceTree = SOURCE_ROOT; }; - 1D93C45211837668003216F7 /* SidebarNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SidebarNode.m; path = Sidebar/SidebarNode.m; sourceTree = SOURCE_ROOT; }; - 1D93C5EF1183992E003216F7 /* libboost_system.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_system.a; path = /usr/local/lib/libboost_system.a; sourceTree = ""; }; - 1D93C5F111839940003216F7 /* libboost_thread.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_thread.a; path = /usr/local/lib/libboost_thread.a; sourceTree = ""; }; - 1D93C5F311839959003216F7 /* libboost_filesystem.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_filesystem.a; path = /usr/local/lib/libboost_filesystem.a; sourceTree = ""; }; - 1D93C5F511839970003216F7 /* libboost_program_options.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_program_options.a; path = /usr/local/lib/libboost_program_options.a; sourceTree = ""; }; - 1D93C60911841865003216F7 /* MongoDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MongoDB.h; sourceTree = ""; }; - 1D93C60A11841865003216F7 /* MongoDB.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MongoDB.mm; sourceTree = ""; }; - 1D93C7471184369D003216F7 /* DatabasesArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabasesArrayController.h; sourceTree = ""; }; - 1D93C7481184369D003216F7 /* DatabasesArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DatabasesArrayController.m; sourceTree = ""; }; - 1D93CB5A1184C243003216F7 /* ResultsOutlineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultsOutlineViewController.h; sourceTree = ""; }; - 1D93CB5B1184C243003216F7 /* ResultsOutlineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResultsOutlineViewController.m; sourceTree = ""; }; - 1DA68042118875B300DFDD29 /* findmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = findmenu.png; path = Resourses/images/findmenu.png; sourceTree = SOURCE_ROOT; }; - 1DA68043118875B300DFDD29 /* insertmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = insertmenu.png; path = Resourses/images/insertmenu.png; sourceTree = SOURCE_ROOT; }; - 1DA68044118875B300DFDD29 /* removemenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = removemenu.png; path = Resourses/images/removemenu.png; sourceTree = SOURCE_ROOT; }; - 1DA68045118875B300DFDD29 /* runmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = runmenu.png; path = Resourses/images/runmenu.png; sourceTree = SOURCE_ROOT; }; - 1DA68046118875B300DFDD29 /* updatemenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = updatemenu.png; path = Resourses/images/updatemenu.png; sourceTree = SOURCE_ROOT; }; - 1DA6806A11888BDD00DFDD29 /* NSString+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Extras.h"; sourceTree = ""; }; - 1DA6806B11888BDD00DFDD29 /* NSString+Extras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Extras.m"; sourceTree = ""; }; - 1DBFFAF312C1FDF200B643CA /* NSProgressIndicator+Extras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSProgressIndicator+Extras.h"; sourceTree = ""; }; - 1DBFFAF412C1FDF200B643CA /* NSProgressIndicator+Extras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSProgressIndicator+Extras.m"; sourceTree = ""; }; - 1DCB3D0012C63CD400423160 /* MongoHub_DataModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel.xcdatamodel; sourceTree = ""; }; - 1DCC562712C264600025F181 /* StatMonitorTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatMonitorTableController.h; sourceTree = ""; }; - 1DCC562812C264600025F181 /* StatMonitorTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatMonitorTableController.m; sourceTree = ""; }; - 1DD1CA8112C8EFD4007F2909 /* SyntaxDefinition.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SyntaxDefinition.plist; sourceTree = ""; }; - 1DD1CA8212C8EFD4007F2909 /* SyntaxColorDefaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SyntaxColorDefaults.plist; sourceTree = ""; }; - 1DD1CA8612C8F004007F2909 /* CSS 1.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "CSS 1.plist"; sourceTree = ""; }; - 1DD1CA8712C8F004007F2909 /* HTML.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = HTML.plist; sourceTree = ""; }; - 1DD1CA8812C8F004007F2909 /* Objective C.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Objective C.plist"; sourceTree = ""; }; - 1DDC486812CB7758009924A1 /* JSON.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = JSON.plist; sourceTree = ""; }; - 1DDC5E0513A673AE00D0E4D2 /* MongoHub_DataModel2.0.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel2.0.xcdatamodel; sourceTree = ""; }; - 1DEC7F3912B7ECAC00FC804E /* Tunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tunnel.h; sourceTree = ""; }; - 1DEC7F3A12B7ECAC00FC804E /* Tunnel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tunnel.m; sourceTree = ""; }; + 1D93C3AF11836510003216F7 /* connecticon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = connecticon.png; path = Resources/images/connecticon.png; sourceTree = SOURCE_ROOT; }; + 1D93C3B011836510003216F7 /* editmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = editmenu.png; path = Resources/images/editmenu.png; sourceTree = SOURCE_ROOT; }; + 1D93C3CD11836863003216F7 /* MHConnectionWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHConnectionWindowController.h; sourceTree = ""; }; + 1D93C3D01183690E003216F7 /* MHConnectionWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MHConnectionWindow.xib; sourceTree = ""; }; + 1D93C42A1183744D003216F7 /* collectionicon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = collectionicon.png; path = Resources/images/collectionicon.png; sourceTree = SOURCE_ROOT; }; + 1D93C42B1183744D003216F7 /* dbicon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dbicon.png; path = Resources/images/dbicon.png; sourceTree = SOURCE_ROOT; }; + 1D93C44F11837668003216F7 /* SidebarBadgeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SidebarBadgeCell.h; sourceTree = ""; }; + 1D93C45011837668003216F7 /* SidebarBadgeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SidebarBadgeCell.m; sourceTree = ""; }; + 1DA68042118875B300DFDD29 /* findmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = findmenu.png; path = Resources/images/findmenu.png; sourceTree = SOURCE_ROOT; }; + 1DA68043118875B300DFDD29 /* insertmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = insertmenu.png; path = Resources/images/insertmenu.png; sourceTree = SOURCE_ROOT; }; + 1DA68044118875B300DFDD29 /* removemenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = removemenu.png; path = Resources/images/removemenu.png; sourceTree = SOURCE_ROOT; }; + 1DA68045118875B300DFDD29 /* runmenu.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = runmenu.png; path = Resources/images/runmenu.png; sourceTree = SOURCE_ROOT; }; + 1DA6806A11888BDD00DFDD29 /* NSString+MongoHub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MongoHub.h"; sourceTree = ""; }; + 1DA6806B11888BDD00DFDD29 /* NSString+MongoHub.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MongoHub.m"; sourceTree = ""; }; + 1DDC486812CB7758009924A1 /* SyntaxDefinition.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SyntaxDefinition.plist; sourceTree = ""; }; + 1DEC7F3912B7ECAC00FC804E /* MHTunnel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTunnel.h; sourceTree = ""; }; + 1DEC7F3A12B7ECAC00FC804E /* MHTunnel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHTunnel.m; sourceTree = ""; }; 1DEC7FF012B7EDB900FC804E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; 1DEC803412B7EE2100FC804E /* SSHCommand.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = SSHCommand.sh; sourceTree = ""; }; - 1DF865D711C8FEF000DF7493 /* MCPKit_bundled.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MCPKit_bundled.framework; path = /Library/PrivateFrameWorks/MCPKit_bundled.framework; sourceTree = ""; }; - 1DF96E3911881AED00C35AB8 /* AddCollectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddCollectionController.h; sourceTree = ""; }; - 1DF96E3A11881AED00C35AB8 /* AddCollectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddCollectionController.m; sourceTree = ""; }; - 1DF96E3C11881EB400C35AB8 /* NewCollection.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NewCollection.xib; sourceTree = ""; }; - 1DF96F9011883B3800C35AB8 /* QueryWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QueryWindowController.h; sourceTree = ""; }; - 1DF96F9111883B3800C35AB8 /* QueryWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QueryWindowController.mm; sourceTree = ""; }; - 1DF96F9311883D5E00C35AB8 /* QueryWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QueryWindow.xib; sourceTree = ""; }; - 1DFC2A7B11970A1E006AA167 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/PrivateFrameWorks/Sparkle.framework; sourceTree = ""; }; - 1DFC2A8C11970BD0006AA167 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = Resourses/dsa_pub.pem; sourceTree = SOURCE_ROOT; }; + 1DF96E3911881AED00C35AB8 /* MHEditNameWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHEditNameWindowController.h; sourceTree = ""; }; + 1DF96E3A11881AED00C35AB8 /* MHEditNameWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHEditNameWindowController.m; sourceTree = ""; }; + 1DF96E3C11881EB400C35AB8 /* MHEditNameWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MHEditNameWindow.xib; sourceTree = ""; }; + 1DF96F9111883B3800C35AB8 /* MHQueryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHQueryViewController.m; sourceTree = ""; }; + 1DF96F9311883D5E00C35AB8 /* MHQueryView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MHQueryView.xib; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 2F7446980DB6B7EA00F9684A /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; - 32CA4F630368D1EE00C91783 /* MongoHub_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MongoHub_Prefix.pch; sourceTree = ""; }; - 770B37EC0679A11B001EADE2 /* MongoHub_DataModel1.0.xcdatamodel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.xcdatamodel; path = MongoHub_DataModel1.0.xcdatamodel; sourceTree = ""; }; + 2F7446980DB6B7EA00F9684A /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MHMainMenu.xib; sourceTree = ""; }; 77C82804067257F0000B614F /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 77C8280B06725ACE000B614F /* MongoHub_AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MongoHub_AppDelegate.h; sourceTree = ""; }; - 77C8280C06725ACE000B614F /* MongoHub_AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MongoHub_AppDelegate.m; sourceTree = ""; }; - 797A78390DDCFADE0050D0C2 /* MongoHub.mdimporter */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MongoHub.mdimporter; sourceTree = BUILT_PRODUCTS_DIR; }; - 797A783F0DDCFB3E0050D0C2 /* GetMetadataForFile.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = GetMetadataForFile.c; sourceTree = ""; }; - 797A78410DDCFB3E0050D0C2 /* Importer-Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; name = "Importer-Info.plist"; path = "Importer/Importer-Info.plist"; sourceTree = ""; }; - 797A78420DDCFB3E0050D0C2 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; - 797A78430DDCFB3E0050D0C2 /* MySpotlightImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MySpotlightImporter.h; sourceTree = ""; }; - 797A78440DDCFB3E0050D0C2 /* MySpotlightImporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MySpotlightImporter.m; sourceTree = ""; }; + 77C8280B06725ACE000B614F /* MHApplicationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHApplicationDelegate.h; sourceTree = ""; }; + 77C8280C06725ACE000B614F /* MHApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MHApplicationDelegate.m; sourceTree = ""; }; 797A7AE10DDCFCE80050D0C2 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = ../../../../../../../../../../../../System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 797A7AE30DDCFCF40050D0C2 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = ../../../../../../../../../../../../System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; - 797A7AE70DDCFD2A0050D0C2 /* Importer Read Me.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "Importer Read Me.txt"; path = "Importer/Importer Read Me.txt"; sourceTree = ""; }; 8D1107310486CEB800E47090 /* MongoHub-Info.plist */ = {isa = PBXFileReference; explicitFileType = text.plist.xml; fileEncoding = 4; path = "MongoHub-Info.plist"; sourceTree = ""; }; 8D1107320486CEB800E47090 /* MongoHub.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MongoHub.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 797A78370DDCFADE0050D0C2 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 797A784A0DDCFC070050D0C2 /* CoreData.framework in Frameworks */, - 797A784B0DDCFC090050D0C2 /* Foundation.framework in Frameworks */, - 797A7AE20DDCFCE80050D0C2 /* CoreFoundation.framework in Frameworks */, - 797A7AE40DDCFCF40050D0C2 /* CoreServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 8D11072E0486CEB800E47090 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 026B2DE513BB6FB8009BEA7B /* RegexKit.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - 1D93C1AE11832A71003216F7 /* libmongoclient.a in Frameworks */, - 1D93C24B118334F6003216F7 /* BWToolkitFramework.framework in Frameworks */, 1D93C37C11835BB4003216F7 /* QuartzCore.framework in Frameworks */, - 1D93C5F01183992E003216F7 /* libboost_system.a in Frameworks */, - 1D93C5F211839940003216F7 /* libboost_thread.a in Frameworks */, - 1D93C5F411839959003216F7 /* libboost_filesystem.a in Frameworks */, - 1D93C5F611839970003216F7 /* libboost_program_options.a in Frameworks */, - 1DFC2A7C11970A1E006AA167 /* Sparkle.framework in Frameworks */, - 1DF865D811C8FEF000DF7493 /* MCPKit_bundled.framework in Frameworks */, 1DEC7FF112B7EDB900FC804E /* Security.framework in Frameworks */, - 1D317EEC12F0A88900255AF7 /* RegexKit.framework in Frameworks */, + 02FCD3CF13BB9EA400316A9F /* Sparkle.framework in Frameworks */, + 02FCD3D813BBA4A300316A9F /* MCPKit.framework in Frameworks */, + 02C4C1C819A231090002FBD8 /* MongoObjCDriver.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 080E96DDFE201D6D7F000001 /* Classes */ = { + 02216E5F14128CBF00789BD1 /* Libraries */ = { + isa = PBXGroup; + children = ( + 02C4C15719A230BE0002FBD8 /* MongoObjCDriver */, + ); + path = Libraries; + sourceTree = ""; + }; + 0262CA37148C1201009033F9 /* TabViews */ = { + isa = PBXGroup; + children = ( + 02CEE9BC1486DD7A00E488DA /* MHTabTitleView.h */, + 02CEE9BD1486DD7A00E488DA /* MHTabTitleView.m */, + 025B8F0A1531C76E00849A71 /* MHTabTitleContainerView.h */, + 025B8F0B1531C76E00849A71 /* MHTabTitleContainerView.m */, + 020F511714896DE700D4B54B /* MHTabViewController.h */, + 020F511814896DE700D4B54B /* MHTabViewController.m */, + 0262CA39148C14A8009033F9 /* MHTabItemViewController.h */, + 0262CA3A148C14A8009033F9 /* MHTabItemViewController.m */, + ); + path = TabViews; + sourceTree = ""; + }; + 02C4C15719A230BE0002FBD8 /* MongoObjCDriver */ = { + isa = PBXGroup; + children = ( + 02C4C15F19A230BE0002FBD8 /* MongoObjCDriver.xcodeproj */, + ); + path = MongoObjCDriver; + sourceTree = ""; + }; + 02C4C16019A230BE0002FBD8 /* Products */ = { + isa = PBXGroup; + children = ( + 02C4C1C519A230BE0002FBD8 /* MongoObjCDriver.framework */, + 027062C819DF803600E6C36A /* MongoObjCDriver Tests.xctest */, + 029464DA19F57AF700E1B1E6 /* test */, + ); + name = Products; + sourceTree = ""; + }; + 02CC2266146485D500A38AC9 /* ConnectionWindow */ = { isa = PBXGroup; children = ( - 1D64100A12C8E39F0030AA4C /* JSONEditor */, + 1D93C3CD11836863003216F7 /* MHConnectionWindowController.h */, + 0262CA3E148C1838009033F9 /* MHConnectionWindowController.m */, + 0262CA40148C1852009033F9 /* MHQueryViewController.h */, + 1DF96F9111883B3800C35AB8 /* MHQueryViewController.m */, + 020F5125148973BA00D4B54B /* MHStatusViewController.h */, + 020F5126148973BA00D4B54B /* MHStatusViewController.m */, + 02ABF65D19E09C76009F4766 /* MHDatabaseCollectionOutlineView.h */, + 02ABF65E19E09C76009F4766 /* MHDatabaseCollectionOutlineView.m */, + 029464DD19F5899F00E1B1E6 /* MHActivityMonitorViewController.h */, + 029464DE19F5899F00E1B1E6 /* MHActivityMonitorViewController.m */, + 02C345301A436A18004F0D2C /* MHIndexEditorController.h */, + 02C345311A436A18004F0D2C /* MHIndexEditorController.m */, + 02D3D99F1AAA4DD000FE5566 /* MHDocumentOutlineViewController.h */, + 02D3D9A01AAA4DD000FE5566 /* MHDocumentOutlineViewController.m */, + ); + path = ConnectionWindow; + sourceTree = ""; + }; + 02CC22671464895800A38AC9 /* JSONEditor */ = { + isa = PBXGroup; + children = ( + 1D64100612C8E21C0030AA4C /* UKSyntaxColoredTextViewController.h */, + 1D64100712C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m */, + 1D64100B12C8E3D90030AA4C /* MHJsonWindowController.h */, + 1D64100C12C8E3D90030AA4C /* MHJsonWindowController.m */, + 0259EB6319B01E7800181E08 /* MHJsonColorManager.h */, + 0259EB6419B01E7800181E08 /* MHJsonColorManager.m */, + ); + path = JSONEditor; + sourceTree = ""; + }; + 02D1872F14636F1300D49ED1 /* Sources */ = { + isa = PBXGroup; + children = ( + 0262CA37148C1201009033F9 /* TabViews */, + 02CC22671464895800A38AC9 /* JSONEditor */, 1D93C608118417D5003216F7 /* Helpers */, - 1D93C44C11837668003216F7 /* Sidebar */, - 1D93C3FF11836D98003216F7 /* Transformers */, - 1D93C3CC11836849003216F7 /* ConnectionWindow */, + 1D93C44C11837668003216F7 /* DatabaseCollectionOutlineView */, 1D93C29B118341BD003216F7 /* ConnectionControllers */, + 02CC2266146485D500A38AC9 /* ConnectionWindow */, 1D93C24C1183357D003216F7 /* ArrayControllers */, 1D93C1DD11833342003216F7 /* ConnectionsCollectionView */, - 77C8280B06725ACE000B614F /* MongoHub_AppDelegate.h */, - 77C8280C06725ACE000B614F /* MongoHub_AppDelegate.m */, - 797A783E0DDCFB3E0050D0C2 /* Importer */, - 1D93C27411833C2A003216F7 /* Configure.h */, + 02D1873014636F2D00D49ED1 /* Model */, + 02D345E414770616001083E7 /* Exporter-Importer */, + 77C8280B06725ACE000B614F /* MHApplicationDelegate.h */, + 77C8280C06725ACE000B614F /* MHApplicationDelegate.m */, + 02F2A1F81817E4BC0053CB20 /* MHPreferenceWindowController.h */, + 02F2A1F91817E4BC0053CB20 /* MHPreferenceWindowController.m */, + 0259EB0319AF5D6600181E08 /* MHLogWindowController.h */, + 0259EB0419AF5D6600181E08 /* MHLogWindowController.m */, + 29B97316FDCFA39411CA2CEA /* main.m */, ); - name = Classes; + path = Sources; + sourceTree = ""; + }; + 02D1873014636F2D00D49ED1 /* Model */ = { + isa = PBXGroup; + children = ( + 021BEA641463709A0091C2EA /* MongoHub_DataModel.xcdatamodeld */, + 1D93C1D811832C1D003216F7 /* MHConnectionStore.h */, + 1D93C1D911832C1D003216F7 /* MHConnectionStore.m */, + 0242F119198922B800C73FEC /* MHMongoHubMigration6to7.xcmappingmodel */, + 025CBC6C1982AE4E00C8E272 /* MHMongoHubMigration6to7.h */, + 025CBC6D1982AE4E00C8E272 /* MHMongoHubMigration6to7.m */, + 021315AD198ABF41006378C5 /* MHMongoHubMigration7to8.xcmappingmodel */, + 0242F136198ABE3E00C73FEC /* MHMongoHubMigration7to8.h */, + 0242F137198ABE3E00C73FEC /* MHMongoHubMigration7to8.m */, + 02CF9CC819AA9E8A00EEF76B /* MHMongoHubMigration9to10.xcmappingmodel */, + 02F4F02C19AA9F6D00A9B836 /* MHMongoHubMigration9to10.h */, + 02F4F02D19AA9F6D00A9B836 /* MHMongoHubMigration9to10.m */, + 028C6DEE19F874D60014B4C0 /* ALIterativeMigrator.h */, + 028C6DEF19F874D60014B4C0 /* ALIterativeMigrator.m */, + ); + path = Model; + sourceTree = ""; + }; + 02D345E414770616001083E7 /* Exporter-Importer */ = { + isa = PBXGroup; + children = ( + 1D601B5011C8F08C00C86274 /* MHMysqlImportWindowController.h */, + 1D601B5111C8F08C00C86274 /* MHMysqlImportWindowController.m */, + 1D26614C11CFC47C0092C6B5 /* MHMysqlExportWindowController.h */, + 1D26614D11CFC47C0092C6B5 /* MHMysqlExportWindowController.m */, + 02A7C4081482DEDD0099CDD1 /* MHMysqlImporter.h */, + 02A7C4091482DEDD0099CDD1 /* MHMysqlImporter.m */, + 02A7C40C1482DF080099CDD1 /* MHMysqlExporter.h */, + 02A7C40D1482DF080099CDD1 /* MHMysqlExporter.m */, + 02AA29911477F8BD0041865F /* MHFileExporter.h */, + 02AA29921477F8BD0041865F /* MHFileExporter.m */, + 02B143DA147C720D005AB320 /* MHFileImporter.h */, + 02B143DB147C720D005AB320 /* MHFileImporter.m */, + 0279C091189C03E000F8BACB /* MHImportExportFeedback.h */, + 0279C092189C03E000F8BACB /* MHImportExportFeedback.m */, + 0252361018FEC2E100286EC9 /* MHExporterImporter.h */, + 0252361118FECEE700286EC9 /* MHExporterImporter.m */, + ); + path = "Exporter-Importer"; + sourceTree = ""; + }; + 02E0FE28151DE2420094C1CD /* tabs */ = { + isa = PBXGroup; + children = ( + 02E0FE2C151DE2420094C1CD /* background_blue_arrow.png */, + 027062B419DF803600E6C36A /* background_blue_arrow@2x.png */, + 02E0FE2D151DE2420094C1CD /* background_blue_center.png */, + 027062B319DF803600E6C36A /* background_blue_center@2x.png */, + 02E0FE2E151DE2420094C1CD /* background_blue_left.png */, + 027062B219DF803600E6C36A /* background_blue_left@2x.png */, + 02E0FE2F151DE2420094C1CD /* background_blue_right.png */, + 027062B119DF803600E6C36A /* background_blue_right@2x.png */, + 02E0FE29151DE2420094C1CD /* background-grey_center.png */, + 027062B019DF803600E6C36A /* background-grey_center@2x.png */, + 02E0FE2A151DE2420094C1CD /* background-grey_left.png */, + 027062AF19DF803600E6C36A /* background-grey_left@2x.png */, + 02E0FE2B151DE2420094C1CD /* background-grey_right.png */, + 027062AE19DF803600E6C36A /* background-grey_right@2x.png */, + 02E0FE32151DE2420094C1CD /* button_ArrowRight_default.png */, + 027062AD19DF803600E6C36A /* button_ArrowRight_default@2x.png */, + 02E0FE33151DE2420094C1CD /* button_ArrowRight_overlay.png */, + 027062AC19DF803600E6C36A /* button_ArrowRight_overlay@2x.png */, + 02E0FE34151DE2420094C1CD /* close_button.png */, + 027062AB19DF803600E6C36A /* close_button@2x.png */, + 02E0FE31151DE2420094C1CD /* grip_button.png */, + 027062AA19DF803600E6C36A /* grip_button@2x.png */, + 02E0FE35151DE2420094C1CD /* overlay_close_button.png */, + 027062A919DF803600E6C36A /* overlay_close_button@2x.png */, + 02E0FE30151DE2420094C1CD /* unselected-tab-background.png */, + 027062A819DF803600E6C36A /* unselected-tab-background@2x.png */, + 025B8F901531FC7500849A71 /* unselected-tab-border.png */, + 027062A719DF803600E6C36A /* unselected-tab-border@2x.png */, + ); + path = tabs; sourceTree = ""; }; 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( - 1D317EEB12F0A88900255AF7 /* RegexKit.framework */, - 1D93C5F511839970003216F7 /* libboost_program_options.a */, - 1D93C5F311839959003216F7 /* libboost_filesystem.a */, - 1D93C5F111839940003216F7 /* libboost_thread.a */, - 1D93C5EF1183992E003216F7 /* libboost_system.a */, - 1D93C1AD11832A71003216F7 /* libmongoclient.a */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - 1D93C24A118334F6003216F7 /* BWToolkitFramework.framework */, - 1DFC2A7B11970A1E006AA167 /* Sparkle.framework */, - 1DF865D711C8FEF000DF7493 /* MCPKit_bundled.framework */, ); name = "Linked Frameworks"; sourceTree = ""; @@ -406,32 +655,21 @@ isa = PBXGroup; children = ( 8D1107320486CEB800E47090 /* MongoHub.app */, - 797A78390DDCFADE0050D0C2 /* MongoHub.mdimporter */, ); name = Products; sourceTree = ""; }; - 1D64100A12C8E39F0030AA4C /* JSONEditor */ = { - isa = PBXGroup; - children = ( - 1D64100612C8E21C0030AA4C /* UKSyntaxColoredTextViewController.h */, - 1D64100712C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m */, - 1D64100B12C8E3D90030AA4C /* JsonWindowController.h */, - 1D64100C12C8E3D90030AA4C /* JsonWindowController.mm */, - ); - name = JSONEditor; - path = JSON; - sourceTree = ""; - }; 1D93C1DD11833342003216F7 /* ConnectionsCollectionView */ = { isa = PBXGroup; children = ( - 1D93C1DE11833342003216F7 /* ConnectionsCollectionView.h */, - 1D93C1DF11833342003216F7 /* ConnectionsCollectionView.m */, - 1D93C1E011833342003216F7 /* IconCollectionItem.h */, - 1D93C1E111833342003216F7 /* IconCollectionItem.m */, - 1D93C1E211833342003216F7 /* IconViewBox.h */, - 1D93C1E311833342003216F7 /* IconViewBox.m */, + 022F33711AD7192300324917 /* MHConnectionListWindowController.h */, + 022F33721AD7192300324917 /* MHConnectionListWindowController.m */, + 02E79EA21993E7950016B4C9 /* MHConnectionIconView.h */, + 02E79EA31993E7950016B4C9 /* MHConnectionIconView.m */, + 02E79EA51993F3F90016B4C9 /* MHConnectionViewItem.h */, + 02E79EA61993F3F90016B4C9 /* MHConnectionViewItem.m */, + 02E79EA8199418400016B4C9 /* MHConnectionCollectionView.h */, + 02E79EA9199418400016B4C9 /* MHConnectionCollectionView.m */, ); path = ConnectionsCollectionView; sourceTree = ""; @@ -441,131 +679,106 @@ children = ( 1D93C24D11833599003216F7 /* ConnectionsArrayController.h */, 1D93C24E11833599003216F7 /* ConnectionsArrayController.m */, - 1D93C7471184369D003216F7 /* DatabasesArrayController.h */, - 1D93C7481184369D003216F7 /* DatabasesArrayController.m */, 1D26619211CFD2560092C6B5 /* FieldMapTableController.h */, 1D26619311CFD2560092C6B5 /* FieldMapTableController.m */, - 1DCC562712C264600025F181 /* StatMonitorTableController.h */, - 1DCC562812C264600025F181 /* StatMonitorTableController.m */, ); - name = ArrayControllers; + path = ArrayControllers; sourceTree = ""; }; 1D93C27011833A19003216F7 /* images */ = { isa = PBXGroup; children = ( + 029464E019F58C4400E1B1E6 /* ActivityMonitor.icns */, 1D601B3B11C8E7F900C86274 /* exportbox.png */, 1D601B3C11C8E7F900C86274 /* importbox.png */, 1D601B3611C8E13000C86274 /* importmenu.png */, 1D601B3711C8E13000C86274 /* exportmenu.png */, 1D210BFA1192FF06000EF41C /* key.png */, 1D58BE0A118ED8D20045A044 /* mapreducemenu.png */, + 027062CC19DF822600E6C36A /* mapreducemenu@2x.png */, 1D1D65A21189F05600582917 /* Icon.icns */, 1D1D65641189C93400582917 /* supportmenu.png */, 1D1D65501189C5E000582917 /* collectionmenu.png */, 1D1D65511189C5E000582917 /* dbmenu.png */, 1D1D65521189C5E000582917 /* querymenu.png */, + 0230662619E7FD07006F5C8C /* querymenu@2x.png */, 1D1D65531189C5E000582917 /* servermenu.png */, 1D8A624D11897C6800D55937 /* indexmenu.png */, + 027062CE19DF822600E6C36A /* indexmenu@2x.png */, 1DA68042118875B300DFDD29 /* findmenu.png */, + 027062CF19DF822600E6C36A /* findmenu@2x.png */, 1DA68043118875B300DFDD29 /* insertmenu.png */, + 027062CD19DF822600E6C36A /* insertmenu@2x.png */, 1DA68044118875B300DFDD29 /* removemenu.png */, + 027062CB19DF822600E6C36A /* removemenu@2x.png */, 1DA68045118875B300DFDD29 /* runmenu.png */, - 1DA68046118875B300DFDD29 /* updatemenu.png */, 1D93C42A1183744D003216F7 /* collectionicon.png */, 1D93C42B1183744D003216F7 /* dbicon.png */, 1D93C3AF11836510003216F7 /* connecticon.png */, - 1D93C3B011836510003216F7 /* editicon.png */, + 1D93C3B011836510003216F7 /* editmenu.png */, + 027062D019DF822600E6C36A /* editmenu@2x.png */, 1D93C27111833A19003216F7 /* database.png */, + 02E0FE28151DE2420094C1CD /* tabs */, ); name = images; - path = Resourses/images; + path = Resources/images; sourceTree = SOURCE_ROOT; }; 1D93C29B118341BD003216F7 /* ConnectionControllers */ = { isa = PBXGroup; children = ( - 1D93C29C118341D4003216F7 /* AddConnectionController.h */, - 1D93C29D118341D4003216F7 /* AddConnectionController.m */, - 1D93C38511835D2A003216F7 /* EditConnectionController.h */, - 1D93C38611835D2A003216F7 /* EditConnectionController.m */, - 1D799453118755EE009C187F /* AddDBController.h */, - 1D799454118755EE009C187F /* AddDBController.m */, - 1DF96E3911881AED00C35AB8 /* AddCollectionController.h */, - 1DF96E3A11881AED00C35AB8 /* AddCollectionController.m */, - ); - name = ConnectionControllers; - sourceTree = ""; - }; - 1D93C3CC11836849003216F7 /* ConnectionWindow */ = { - isa = PBXGroup; - children = ( - 1D93C3CD11836863003216F7 /* ConnectionWindowController.h */, - 1D93C3CE11836863003216F7 /* ConnectionWindowController.mm */, - 1D93CB5A1184C243003216F7 /* ResultsOutlineViewController.h */, - 1D93CB5B1184C243003216F7 /* ResultsOutlineViewController.m */, - 1DF96F9011883B3800C35AB8 /* QueryWindowController.h */, - 1DF96F9111883B3800C35AB8 /* QueryWindowController.mm */, - 1D210BFC119301BA000EF41C /* AuthWindowController.h */, - 1D210BFD119301BA000EF41C /* AuthWindowController.m */, - 1D601B5011C8F08C00C86274 /* ImportWindowController.h */, - 1D601B5111C8F08C00C86274 /* ImportWindowController.mm */, - 1D26614C11CFC47C0092C6B5 /* ExportWindowController.h */, - 1D26614D11CFC47C0092C6B5 /* ExportWindowController.mm */, + 023230AC15E051300075498C /* MHConnectionEditorWindowController.h */, + 023230AD15E051300075498C /* MHConnectionEditorWindowController.m */, + 1DF96E3911881AED00C35AB8 /* MHEditNameWindowController.h */, + 1DF96E3A11881AED00C35AB8 /* MHEditNameWindowController.m */, ); - name = ConnectionWindow; + path = ConnectionControllers; sourceTree = ""; }; - 1D93C3FF11836D98003216F7 /* Transformers */ = { + 1D93C44C11837668003216F7 /* DatabaseCollectionOutlineView */ = { isa = PBXGroup; children = ( - 1D93C40011836DC2003216F7 /* ConnectionWindowTitleTransformer.h */, - 1D93C40111836DC2003216F7 /* ConnectionWindowTitleTransformer.m */, - ); - name = Transformers; - sourceTree = ""; - }; - 1D93C44C11837668003216F7 /* Sidebar */ = { - isa = PBXGroup; - children = ( - 1D93C44D11837668003216F7 /* Sidebar.h */, - 1D93C44E11837668003216F7 /* Sidebar.m */, 1D93C44F11837668003216F7 /* SidebarBadgeCell.h */, 1D93C45011837668003216F7 /* SidebarBadgeCell.m */, - 1D93C45111837668003216F7 /* SidebarNode.h */, - 1D93C45211837668003216F7 /* SidebarNode.m */, + 029D30AA145613C30021B9C9 /* MHClientItem.h */, + 029D30AB145613C30021B9C9 /* MHClientItem.m */, + 029D30A3145613420021B9C9 /* MHDatabaseItem.h */, + 029D30A4145613420021B9C9 /* MHDatabaseItem.m */, + 029D30A7145613580021B9C9 /* MHCollectionItem.h */, + 029D30A8145613580021B9C9 /* MHCollectionItem.m */, ); - path = Sidebar; - sourceTree = SOURCE_ROOT; + path = DatabaseCollectionOutlineView; + sourceTree = ""; }; 1D93C608118417D5003216F7 /* Helpers */ = { isa = PBXGroup; children = ( - 1D93C60911841865003216F7 /* MongoDB.h */, - 1D93C60A11841865003216F7 /* MongoDB.mm */, - 1DA6806A11888BDD00DFDD29 /* NSString+Extras.h */, - 1DA6806B11888BDD00DFDD29 /* NSString+Extras.m */, + 0255B566181A9A210019739D /* MHKeychain.h */, + 0255B567181A9A210019739D /* MHKeychain.m */, + 1DA6806A11888BDD00DFDD29 /* NSString+MongoHub.h */, + 1DA6806B11888BDD00DFDD29 /* NSString+MongoHub.m */, 1D26618F11CFD1640092C6B5 /* FieldMapDataObject.h */, 1D26619011CFD1640092C6B5 /* FieldMapDataObject.m */, - 1DEC7F3912B7ECAC00FC804E /* Tunnel.h */, - 1DEC7F3A12B7ECAC00FC804E /* Tunnel.m */, - 1DBFFAF312C1FDF200B643CA /* NSProgressIndicator+Extras.h */, - 1DBFFAF412C1FDF200B643CA /* NSProgressIndicator+Extras.m */, - 1D64100012C8E16C0030AA4C /* NSArray+Color.h */, - 1D64100112C8E16C0030AA4C /* NSArray+Color.m */, + 1DEC7F3912B7ECAC00FC804E /* MHTunnel.h */, + 1DEC7F3A12B7ECAC00FC804E /* MHTunnel.m */, 1D64100312C8E1C00030AA4C /* NSScanner+SkipUpToCharset.h */, 1D64100412C8E1C00030AA4C /* NSScanner+SkipUpToCharset.m */, + 024F678E1427F3DE00956BF6 /* MODHelper.h */, + 024F678F1427F3DE00956BF6 /* MODHelper.m */, + 025F635015AE21F300CD0EB4 /* NSViewHelpers.h */, + 025F635115AE21F300CD0EB4 /* NSViewHelpers.m */, + 029CAA711946028800FD44B4 /* NSTextView+MongoHub.h */, + 029CAA721946028800FD44B4 /* NSTextView+MongoHub.m */, + 02D83DFF19A4A1A9007AB2F2 /* NSDictionary+MongoHub.h */, + 02D83E0119A4A28F007AB2F2 /* NSDictionary+MongoHub.m */, ); - name = Helpers; + path = Helpers; sourceTree = ""; }; 1DD1CA8512C8F004007F2909 /* Syntax Definitions */ = { isa = PBXGroup; children = ( - 1DD1CA8612C8F004007F2909 /* CSS 1.plist */, - 1DD1CA8712C8F004007F2909 /* HTML.plist */, - 1DD1CA8812C8F004007F2909 /* Objective C.plist */, - 1DDC486812CB7758009924A1 /* JSON.plist */, + 1DDC486812CB7758009924A1 /* SyntaxDefinition.plist */, ); path = "Syntax Definitions"; sourceTree = ""; @@ -573,105 +786,64 @@ 29B97314FDCFA39411CA2CEA /* MongoHub */ = { isa = PBXGroup; children = ( - 7756732906782D8800D1FEB8 /* Models */, - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, + 0242F11B1989475F00C73FEC /* MongoHub.entitlements */, + 02D1872F14636F1300D49ED1 /* Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, + 02216E5F14128CBF00789BD1 /* Libraries */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, - 797A7AE70DDCFD2A0050D0C2 /* Importer Read Me.txt */, ); + indentWidth = 4; name = MongoHub; sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Other Sources */ = { - isa = PBXGroup; - children = ( - 32CA4F630368D1EE00C91783 /* MongoHub_Prefix.pch */, - 29B97316FDCFA39411CA2CEA /* main.m */, - ); - name = "Other Sources"; - sourceTree = ""; + tabWidth = 4; }; 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 02683D5D1442759100467EBE /* README.markdown */, + 0213CAF31431FEF50027795D /* mongohub_su_feed.xml */, 1DD1CA8512C8F004007F2909 /* Syntax Definitions */, - 1DD1CA8112C8EFD4007F2909 /* SyntaxDefinition.plist */, - 1DD1CA8212C8EFD4007F2909 /* SyntaxColorDefaults.plist */, - 1DFC2A8C11970BD0006AA167 /* dsa_pub.pem */, 1DEC803412B7EE2100FC804E /* SSHCommand.sh */, 1D93C27011833A19003216F7 /* images */, 8D1107310486CEB800E47090 /* MongoHub-Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - 2F7446970DB6B7EA00F9684A /* MainMenu.xib */, - 797A78410DDCFB3E0050D0C2 /* Importer-Info.plist */, - 1D93C29F118343EF003216F7 /* NewConnection.xib */, - 1D93C38911835FB8003216F7 /* EditConnection.xib */, - 1D93C3D01183690E003216F7 /* ConnectionWindow.xib */, - 1D79945611875E7A009C187F /* NewDB.xib */, - 1DF96E3C11881EB400C35AB8 /* NewCollection.xib */, - 1DF96F9311883D5E00C35AB8 /* QueryWindow.xib */, - 1D210BFF11930E18000EF41C /* Auth.xib */, - 1D601B5511C8F24300C86274 /* Import.xib */, - 1D26615111CFC5BE0092C6B5 /* Export.xib */, - 1D64100E12C8E6BE0030AA4C /* JsonWindow.xib */, + 020F511914896DE700D4B54B /* MHTabView.xib */, + 020F5127148973BA00D4B54B /* MHStatusView.xib */, + 2F7446970DB6B7EA00F9684A /* MHMainMenu.xib */, + 02F2A1F61817E48B0053CB20 /* MHPreferenceWindow.xib */, + 1D93C29F118343EF003216F7 /* MHConnectionEditorWindow.xib */, + 1D93C3D01183690E003216F7 /* MHConnectionWindow.xib */, + 1DF96E3C11881EB400C35AB8 /* MHEditNameWindow.xib */, + 0243B79119EC357700D06BFE /* MHQueryUpdateOperatorView.xib */, + 1DF96F9311883D5E00C35AB8 /* MHQueryView.xib */, + 029464DB19F588B900E1B1E6 /* MHActivityMonitorTab.xib */, + 02C345291A423C85004F0D2C /* MHIndexEditor.xib */, + 1D601B5511C8F24300C86274 /* MysqlImport.xib */, + 1D26615111CFC5BE0092C6B5 /* MysqlExport.xib */, + 1D64100E12C8E6BE0030AA4C /* MHJsonWindow.xib */, + 0279C08F189C02F600F8BACB /* MHImportExportFeedback.xib */, + 0259EAFD19AF5CF000181E08 /* MHLogWindow.xib */, + 02D3D9A71AAA512B00FE5566 /* MHDocumentOutlineView.xib */, ); - name = Resources; + path = Resources; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( + 02FCD3D713BBA4A300316A9F /* MCPKit.framework */, + 02FCD3CE13BB9EA400316A9F /* Sparkle.framework */, + 026B2DE413BB6FB8009BEA7B /* RegexKit.framework */, 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, ); - name = Frameworks; - sourceTree = ""; - }; - 7756732906782D8800D1FEB8 /* Models */ = { - isa = PBXGroup; - children = ( - 1DCB3CFE12C63CD400423160 /* MongoHub_DataModel.xcdatamodeld */, - 1D93C1D811832C1D003216F7 /* Connection.h */, - 1D93C1D911832C1D003216F7 /* Connection.m */, - 1D93C29811833F26003216F7 /* Database.h */, - 1D93C29911833F26003216F7 /* Database.m */, - ); - name = Models; - sourceTree = ""; - }; - 797A783E0DDCFB3E0050D0C2 /* Importer */ = { - isa = PBXGroup; - children = ( - 797A78420DDCFB3E0050D0C2 /* main.c */, - 797A783F0DDCFB3E0050D0C2 /* GetMetadataForFile.c */, - 797A78430DDCFB3E0050D0C2 /* MySpotlightImporter.h */, - 797A78440DDCFB3E0050D0C2 /* MySpotlightImporter.m */, - ); - path = Importer; + path = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 797A78380DDCFADE0050D0C2 /* MongoHub Spotlight Importer */ = { - isa = PBXNativeTarget; - buildConfigurationList = 797A783D0DDCFADE0050D0C2 /* Build configuration list for PBXNativeTarget "MongoHub Spotlight Importer" */; - buildPhases = ( - 797A78350DDCFADE0050D0C2 /* Resources */, - 797A78360DDCFADE0050D0C2 /* Sources */, - 797A78370DDCFADE0050D0C2 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "MongoHub Spotlight Importer"; - productName = "MongoHub Spotlight Importer"; - productReference = 797A78390DDCFADE0050D0C2 /* MongoHub.mdimporter */; - productType = "com.apple.product-type.bundle"; - }; 8D1107260486CEB800E47090 /* MongoHub */ = { isa = PBXNativeTarget; buildConfigurationList = 26FC0A840875C7B200E6366F /* Build configuration list for PBXNativeTarget "MongoHub" */; @@ -679,16 +851,12 @@ 8D1107290486CEB800E47090 /* Resources */, 8D11072C0486CEB800E47090 /* Sources */, 8D11072E0486CEB800E47090 /* Frameworks */, - 7905130A0DDD0A660070760D /* CopyFiles */, 1D58BE3A118EFF840045A044 /* CopyFiles */, - 1DFC2A8B11970A4A006AA167 /* CopyFiles */, - 1DF8661511C8FF2600DF7493 /* CopyFiles */, - 1D317F0A12F0A8C600255AF7 /* CopyFiles */, ); buildRules = ( ); dependencies = ( - 790512FC0DDD0A100070760D /* PBXTargetDependency */, + 02216F641412D6F000789BD1 /* PBXTargetDependency */, ); name = MongoHub; productInstallPath = "$(HOME)/Applications"; @@ -702,7 +870,17 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - ORGANIZATIONNAME = ThePeppersStudio.COM; + LastUpgradeCheck = 0430; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 8D1107260486CEB800E47090 = { + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 0; + }; + }; + }; + }; }; buildConfigurationList = 26FC0A880875C7B200E6366F /* Build configuration list for PBXProject "MongoHub" */; compatibilityVersion = "Xcode 3.2"; @@ -713,137 +891,224 @@ Japanese, French, German, + en, ); mainGroup = 29B97314FDCFA39411CA2CEA /* MongoHub */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 02C4C16019A230BE0002FBD8 /* Products */; + ProjectRef = 02C4C15F19A230BE0002FBD8 /* MongoObjCDriver.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 8D1107260486CEB800E47090 /* MongoHub */, - 797A78380DDCFADE0050D0C2 /* MongoHub Spotlight Importer */, + 02216F201412D54600789BD1 /* Submodules */, ); }; /* End PBXProject section */ -/* Begin PBXResourcesBuildPhase section */ - 797A78350DDCFADE0050D0C2 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; +/* Begin PBXReferenceProxy section */ + 027062C819DF803600E6C36A /* MongoObjCDriver Tests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "MongoObjCDriver Tests.xctest"; + remoteRef = 027062C719DF803600E6C36A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; }; + 029464DA19F57AF700E1B1E6 /* test */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = test; + remoteRef = 029464D919F57AF700E1B1E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 02C4C1C519A230BE0002FBD8 /* MongoObjCDriver.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = MongoObjCDriver.framework; + remoteRef = 02C4C1C419A230BE0002FBD8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ 8D1107290486CEB800E47090 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, - 2F7446990DB6B7EA00F9684A /* MainMenu.xib in Resources */, + 029464DC19F588B900E1B1E6 /* MHActivityMonitorTab.xib in Resources */, + 2F7446990DB6B7EA00F9684A /* MHMainMenu.xib in Resources */, 1D93C27211833A19003216F7 /* database.png in Resources */, - 1D93C2A0118343EF003216F7 /* NewConnection.xib in Resources */, - 1D93C38A11835FB8003216F7 /* EditConnection.xib in Resources */, + 1D93C2A0118343EF003216F7 /* MHConnectionEditorWindow.xib in Resources */, + 027062B619DF803600E6C36A /* unselected-tab-background@2x.png in Resources */, 1D93C3B111836510003216F7 /* connecticon.png in Resources */, - 1D93C3B211836510003216F7 /* editicon.png in Resources */, - 1D93C3D11183690E003216F7 /* ConnectionWindow.xib in Resources */, + 027062BF19DF803600E6C36A /* background_blue_right@2x.png in Resources */, + 1D93C3B211836510003216F7 /* editmenu.png in Resources */, 1D93C42C1183744D003216F7 /* collectionicon.png in Resources */, 1D93C42D1183744D003216F7 /* dbicon.png in Resources */, - 1D79945711875E7A009C187F /* NewDB.xib in Resources */, - 1DF96E3D11881EB400C35AB8 /* NewCollection.xib in Resources */, - 1DF96F9411883D5E00C35AB8 /* QueryWindow.xib in Resources */, + 02D3D9A81AAA512B00FE5566 /* MHDocumentOutlineView.xib in Resources */, + 0279C090189C02F600F8BACB /* MHImportExportFeedback.xib in Resources */, + 1DF96E3D11881EB400C35AB8 /* MHEditNameWindow.xib in Resources */, + 1DF96F9411883D5E00C35AB8 /* MHQueryView.xib in Resources */, + 027062B519DF803600E6C36A /* unselected-tab-border@2x.png in Resources */, 1DA68047118875B300DFDD29 /* findmenu.png in Resources */, + 02F2A1F71817E48B0053CB20 /* MHPreferenceWindow.xib in Resources */, + 027062C119DF803600E6C36A /* background_blue_center@2x.png in Resources */, 1DA68048118875B300DFDD29 /* insertmenu.png in Resources */, + 0243B79019EC222300D06BFE /* MHConnectionWindow.xib in Resources */, 1DA68049118875B300DFDD29 /* removemenu.png in Resources */, 1DA6804A118875B300DFDD29 /* runmenu.png in Resources */, - 1DA6804B118875B300DFDD29 /* updatemenu.png in Resources */, + 027062D219DF822600E6C36A /* mapreducemenu@2x.png in Resources */, + 027062BB19DF803600E6C36A /* button_ArrowRight_default@2x.png in Resources */, + 027062BD19DF803600E6C36A /* background-grey_left@2x.png in Resources */, 1D8A624E11897C6800D55937 /* indexmenu.png in Resources */, 1D1D65541189C5E000582917 /* collectionmenu.png in Resources */, 1D1D65551189C5E000582917 /* dbmenu.png in Resources */, 1D1D65561189C5E000582917 /* querymenu.png in Resources */, 1D1D65571189C5E000582917 /* servermenu.png in Resources */, 1D1D65651189C93400582917 /* supportmenu.png in Resources */, + 02C3452A1A423C85004F0D2C /* MHIndexEditor.xib in Resources */, 1D1D65A31189F05600582917 /* Icon.icns in Resources */, + 0243B79219EC357700D06BFE /* MHQueryUpdateOperatorView.xib in Resources */, + 027062BE19DF803600E6C36A /* background-grey_center@2x.png in Resources */, 1D58BE0B118ED8D20045A044 /* mapreducemenu.png in Resources */, + 027062B919DF803600E6C36A /* close_button@2x.png in Resources */, 1D210BFB1192FF06000EF41C /* key.png in Resources */, - 1D210C0011930E18000EF41C /* Auth.xib in Resources */, - 1DFC2A8D11970BD0006AA167 /* dsa_pub.pem in Resources */, 1D601B3811C8E13000C86274 /* importmenu.png in Resources */, 1D601B3911C8E13000C86274 /* exportmenu.png in Resources */, + 027062C219DF803600E6C36A /* background_blue_arrow@2x.png in Resources */, + 029464E119F58C4500E1B1E6 /* ActivityMonitor.icns in Resources */, 1D601B3D11C8E7F900C86274 /* exportbox.png in Resources */, + 027062D119DF822600E6C36A /* removemenu@2x.png in Resources */, 1D601B3E11C8E7F900C86274 /* importbox.png in Resources */, - 1D601B5611C8F24300C86274 /* Import.xib in Resources */, - 1D26615211CFC5BE0092C6B5 /* Export.xib in Resources */, + 027062C019DF803600E6C36A /* background_blue_left@2x.png in Resources */, + 027062B819DF803600E6C36A /* grip_button@2x.png in Resources */, + 1D601B5611C8F24300C86274 /* MysqlImport.xib in Resources */, + 027062BC19DF803600E6C36A /* background-grey_right@2x.png in Resources */, + 0230662719E7FD07006F5C8C /* querymenu@2x.png in Resources */, + 1D26615211CFC5BE0092C6B5 /* MysqlExport.xib in Resources */, + 027062D519DF822600E6C36A /* findmenu@2x.png in Resources */, 1DEC803512B7EE2100FC804E /* SSHCommand.sh in Resources */, - 1D64100F12C8E6BE0030AA4C /* JsonWindow.xib in Resources */, - 1DD1CA8312C8EFD4007F2909 /* SyntaxDefinition.plist in Resources */, - 1DD1CA8412C8EFD4007F2909 /* SyntaxColorDefaults.plist in Resources */, - 1DD1CA8912C8F004007F2909 /* CSS 1.plist in Resources */, - 1DD1CA8A12C8F004007F2909 /* HTML.plist in Resources */, - 1DD1CA8B12C8F004007F2909 /* Objective C.plist in Resources */, - 1DDC486912CB7758009924A1 /* JSON.plist in Resources */, + 1D64100F12C8E6BE0030AA4C /* MHJsonWindow.xib in Resources */, + 1DDC486912CB7758009924A1 /* SyntaxDefinition.plist in Resources */, + 020F511B14896DE700D4B54B /* MHTabView.xib in Resources */, + 027062D319DF822600E6C36A /* insertmenu@2x.png in Resources */, + 020F5129148973BA00D4B54B /* MHStatusView.xib in Resources */, + 02E0FE36151DE2420094C1CD /* background-grey_center.png in Resources */, + 02E0FE37151DE2420094C1CD /* background-grey_left.png in Resources */, + 02E0FE38151DE2420094C1CD /* background-grey_right.png in Resources */, + 027062B719DF803600E6C36A /* overlay_close_button@2x.png in Resources */, + 02E0FE39151DE2420094C1CD /* background_blue_arrow.png in Resources */, + 02E0FE3A151DE2420094C1CD /* background_blue_center.png in Resources */, + 0259EAFE19AF5CF000181E08 /* MHLogWindow.xib in Resources */, + 02E0FE3B151DE2420094C1CD /* background_blue_left.png in Resources */, + 02E0FE3C151DE2420094C1CD /* background_blue_right.png in Resources */, + 02E0FE3D151DE2420094C1CD /* unselected-tab-background.png in Resources */, + 02E0FE3E151DE2420094C1CD /* grip_button.png in Resources */, + 02E0FE3F151DE2420094C1CD /* button_ArrowRight_default.png in Resources */, + 027062D419DF822600E6C36A /* indexmenu@2x.png in Resources */, + 02E0FE40151DE2420094C1CD /* button_ArrowRight_overlay.png in Resources */, + 027062BA19DF803600E6C36A /* button_ArrowRight_overlay@2x.png in Resources */, + 02E0FE41151DE2420094C1CD /* close_button.png in Resources */, + 02E0FE42151DE2420094C1CD /* overlay_close_button.png in Resources */, + 025B8F911531FC7500849A71 /* unselected-tab-border.png in Resources */, + 027062D619DF822600E6C36A /* editmenu@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXSourcesBuildPhase section */ - 797A78360DDCFADE0050D0C2 /* Sources */ = { - isa = PBXSourcesBuildPhase; +/* Begin PBXShellScriptBuildPhase section */ + 02D5A7F41442019100C7768C /* Update submodules */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 797A78450DDCFB3E0050D0C2 /* GetMetadataForFile.c in Sources */, - 797A78480DDCFB3E0050D0C2 /* main.c in Sources */, - 797A78490DDCFB3E0050D0C2 /* MySpotlightImporter.m in Sources */, + ); + inputPaths = ( + ); + name = "Update submodules"; + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "./scripts/update_submodule.sh jeromelebel mongo-objc-driver master Libraries/MongoObjCDriver\n"; }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ 8D11072C0486CEB800E47090 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 02F2A1FA1817E4BC0053CB20 /* MHPreferenceWindowController.m in Sources */, + 0255B568181A9A210019739D /* MHKeychain.m in Sources */, 8D11072D0486CEB800E47090 /* main.m in Sources */, - 77C8280E06725ACE000B614F /* MongoHub_AppDelegate.m in Sources */, - 1DCB3CFF12C63CD400423160 /* MongoHub_DataModel.xcdatamodeld in Sources */, - 1D93C1DA11832C1D003216F7 /* Connection.m in Sources */, - 1D93C1E411833342003216F7 /* ConnectionsCollectionView.m in Sources */, - 1D93C1E511833342003216F7 /* IconCollectionItem.m in Sources */, - 1D93C1E611833342003216F7 /* IconViewBox.m in Sources */, + 77C8280E06725ACE000B614F /* MHApplicationDelegate.m in Sources */, + 02F4F02E19AA9F6D00A9B836 /* MHMongoHubMigration9to10.m in Sources */, + 0259EB0519AF5D6600181E08 /* MHLogWindowController.m in Sources */, + 1D93C1DA11832C1D003216F7 /* MHConnectionStore.m in Sources */, + 02E79EAA199418400016B4C9 /* MHConnectionCollectionView.m in Sources */, + 029CAA731946028800FD44B4 /* NSTextView+MongoHub.m in Sources */, + 021315AE198ABF41006378C5 /* MHMongoHubMigration7to8.xcmappingmodel in Sources */, 1D93C24F11833599003216F7 /* ConnectionsArrayController.m in Sources */, - 1D93C29A11833F26003216F7 /* Database.m in Sources */, - 1D93C29E118341D4003216F7 /* AddConnectionController.m in Sources */, - 1D93C38711835D2A003216F7 /* EditConnectionController.m in Sources */, - 1D93C3CF11836863003216F7 /* ConnectionWindowController.mm in Sources */, - 1D93C40211836DC2003216F7 /* ConnectionWindowTitleTransformer.m in Sources */, - 1D93C45311837668003216F7 /* Sidebar.m in Sources */, + 02D3D9A11AAA4DD000FE5566 /* MHDocumentOutlineViewController.m in Sources */, 1D93C45411837668003216F7 /* SidebarBadgeCell.m in Sources */, - 1D93C45511837668003216F7 /* SidebarNode.m in Sources */, - 1D93C60B11841865003216F7 /* MongoDB.mm in Sources */, - 1D93C7491184369D003216F7 /* DatabasesArrayController.m in Sources */, - 1D93CB5C1184C243003216F7 /* ResultsOutlineViewController.m in Sources */, - 1D799455118755EE009C187F /* AddDBController.m in Sources */, - 1DF96E3B11881AED00C35AB8 /* AddCollectionController.m in Sources */, - 1DF96F9211883B3800C35AB8 /* QueryWindowController.mm in Sources */, - 1DA6806C11888BDD00DFDD29 /* NSString+Extras.m in Sources */, - 1D210BFE119301BA000EF41C /* AuthWindowController.m in Sources */, - 1D601B5211C8F08C00C86274 /* ImportWindowController.mm in Sources */, - 1D26614E11CFC47C0092C6B5 /* ExportWindowController.mm in Sources */, + 1DF96E3B11881AED00C35AB8 /* MHEditNameWindowController.m in Sources */, + 1DF96F9211883B3800C35AB8 /* MHQueryViewController.m in Sources */, + 1DA6806C11888BDD00DFDD29 /* NSString+MongoHub.m in Sources */, + 1D601B5211C8F08C00C86274 /* MHMysqlImportWindowController.m in Sources */, + 1D26614E11CFC47C0092C6B5 /* MHMysqlExportWindowController.m in Sources */, + 022F33731AD7192300324917 /* MHConnectionListWindowController.m in Sources */, 1D26619111CFD1640092C6B5 /* FieldMapDataObject.m in Sources */, 1D26619411CFD2560092C6B5 /* FieldMapTableController.m in Sources */, - 1DEC7F3B12B7ECAD00FC804E /* Tunnel.m in Sources */, - 1DBFFAF512C1FDF200B643CA /* NSProgressIndicator+Extras.m in Sources */, - 1DCC562912C264600025F181 /* StatMonitorTableController.m in Sources */, - 1D64100212C8E16C0030AA4C /* NSArray+Color.m in Sources */, + 1DEC7F3B12B7ECAD00FC804E /* MHTunnel.m in Sources */, + 028C6DF019F874D60014B4C0 /* ALIterativeMigrator.m in Sources */, + 02D83E0219A4A28F007AB2F2 /* NSDictionary+MongoHub.m in Sources */, + 0279C093189C03E000F8BACB /* MHImportExportFeedback.m in Sources */, + 02C345321A436A18004F0D2C /* MHIndexEditorController.m in Sources */, 1D64100512C8E1C00030AA4C /* NSScanner+SkipUpToCharset.m in Sources */, + 029464DF19F5899F00E1B1E6 /* MHActivityMonitorViewController.m in Sources */, 1D64100812C8E21C0030AA4C /* UKSyntaxColoredTextViewController.m in Sources */, - 1D64100D12C8E3D90030AA4C /* JsonWindowController.mm in Sources */, + 02E79EA71993F3F90016B4C9 /* MHConnectionViewItem.m in Sources */, + 1D64100D12C8E3D90030AA4C /* MHJsonWindowController.m in Sources */, + 024F67901427F3DE00956BF6 /* MODHelper.m in Sources */, + 029D30A5145613420021B9C9 /* MHDatabaseItem.m in Sources */, + 02ABF65F19E09C76009F4766 /* MHDatabaseCollectionOutlineView.m in Sources */, + 029D30A9145613580021B9C9 /* MHCollectionItem.m in Sources */, + 029D30AC145613C30021B9C9 /* MHClientItem.m in Sources */, + 02CF9CC919AA9E8A00EEF76B /* MHMongoHubMigration9to10.xcmappingmodel in Sources */, + 0242F11A198922B900C73FEC /* MHMongoHubMigration6to7.xcmappingmodel in Sources */, + 021BEA681463709A0091C2EA /* MongoHub_DataModel.xcdatamodeld in Sources */, + 02AA29931477F8BD0041865F /* MHFileExporter.m in Sources */, + 02B143DC147C720D005AB320 /* MHFileImporter.m in Sources */, + 0252361218FECEE700286EC9 /* MHExporterImporter.m in Sources */, + 02A7C40A1482DEDD0099CDD1 /* MHMysqlImporter.m in Sources */, + 02A7C40E1482DF080099CDD1 /* MHMysqlExporter.m in Sources */, + 02CEE9BE1486DD7A00E488DA /* MHTabTitleView.m in Sources */, + 020F511A14896DE700D4B54B /* MHTabViewController.m in Sources */, + 020F5128148973BA00D4B54B /* MHStatusViewController.m in Sources */, + 0262CA3C148C14A8009033F9 /* MHTabItemViewController.m in Sources */, + 0262CA3F148C1838009033F9 /* MHConnectionWindowController.m in Sources */, + 0242F138198ABE3E00C73FEC /* MHMongoHubMigration7to8.m in Sources */, + 025B8F0C1531C76E00849A71 /* MHTabTitleContainerView.m in Sources */, + 0259EB6519B01E7800181E08 /* MHJsonColorManager.m in Sources */, + 025F635215AE21F300CD0EB4 /* NSViewHelpers.m in Sources */, + 025CBC6E1982AE4E00C8E272 /* MHMongoHubMigration6to7.m in Sources */, + 023230AE15E051300075498C /* MHConnectionEditorWindowController.m in Sources */, + 02E79EA41993E7950016B4C9 /* MHConnectionIconView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 790512FC0DDD0A100070760D /* PBXTargetDependency */ = { + 02216F641412D6F000789BD1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 797A78380DDCFADE0050D0C2 /* MongoHub Spotlight Importer */; - targetProxy = 790512FB0DDD0A100070760D /* PBXContainerItemProxy */; + target = 02216F201412D54600789BD1 /* Submodules */; + targetProxy = 02216F631412D6F000789BD1 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -856,188 +1121,131 @@ name = InfoPlist.strings; sourceTree = ""; }; - 2F7446970DB6B7EA00F9684A /* MainMenu.xib */ = { + 2F7446970DB6B7EA00F9684A /* MHMainMenu.xib */ = { isa = PBXVariantGroup; children = ( 2F7446980DB6B7EA00F9684A /* English */, ); - name = MainMenu.xib; + name = MHMainMenu.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 02216F231412D54600789BD1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 02216F241412D54600789BD1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 26FC0A850875C7B200E6366F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "\"$(LOCAL_LIBRARY_DIR)/PrivateFrameWorks\"", + "\"$(SRCROOT)\"/Frameworks", ); - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = MongoHub_Prefix.pch; - HEADER_SEARCH_PATHS = /usr/local/include/; - INFOPLIST_FILE = "MongoHub-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/gcc/i686-apple-darwin10/4.0.1\"", - ); - OTHER_LDFLAGS = "-licucore"; + INFOPLIST_FILE = "Resources/MongoHub-Info.plist"; PRODUCT_NAME = MongoHub; - SDKROOT = macosx10.6; - STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic; - WRAPPER_EXTENSION = app; }; name = Debug; }; 26FC0A860875C7B200E6366F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "\"$(LOCAL_LIBRARY_DIR)/PrivateFrameWorks\"", - ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = MongoHub_Prefix.pch; - HEADER_SEARCH_PATHS = /usr/local/include/; - INFOPLIST_FILE = "MongoHub-Info.plist"; - INSTALL_PATH = "$(HOME)/Applications"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/gcc/i686-apple-darwin10/4.0.1\"", + "\"$(SRCROOT)\"/Frameworks", ); - OTHER_LDFLAGS = "-licucore"; + INFOPLIST_FILE = "Resources/MongoHub-Info.plist"; PRODUCT_NAME = MongoHub; - SDKROOT = macosx10.6; - STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic; - WRAPPER_EXTENSION = app; }; name = Release; }; 26FC0A890875C7B200E6366F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = /usr/local/include/; - ONLY_ACTIVE_ARCH = NO; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = "-licucore"; - PREBINDING = NO; - SDKROOT = macosx10.6; - STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic; - USER_HEADER_SEARCH_PATHS = ""; - VALID_ARCHS = x86_64; + MACOSX_DEPLOYMENT_TARGET = 10.8; + SDKROOT = macosx; }; name = Debug; }; 26FC0A8A0875C7B200E6366F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = /usr/local/include/; - OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; - OTHER_LDFLAGS = "-licucore"; - PREBINDING = NO; - SDKROOT = macosx10.6; - STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic; - USER_HEADER_SEARCH_PATHS = ""; - VALID_ARCHS = "i386 x86_64"; - }; - name = Release; - }; - 797A783B0DDCFADE0050D0C2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - INFOPLIST_FILE = "Importer/Importer-Info.plist"; - INSTALL_PATH = "@executable_path/../Contents/Library/Spotlight"; - LIBRARY_STYLE = BUNDLE; - OTHER_LDFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = MongoHub; - SDKROOT = macosx10.6; - SKIP_INSTALL = YES; - VALID_ARCHS = "i386 x86_64"; - WRAPPER_EXTENSION = mdimporter; - }; - name = Debug; - }; - 797A783C0DDCFADE0050D0C2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - INFOPLIST_FILE = "Importer/Importer-Info.plist"; - INSTALL_PATH = "@executable_path/../Contents/Library/Spotlight"; - LIBRARY_STYLE = BUNDLE; - OTHER_LDFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = MongoHub; - SDKROOT = macosx10.6; - SKIP_INSTALL = YES; - VALID_ARCHS = "i386 x86_64"; - WRAPPER_EXTENSION = mdimporter; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + SDKROOT = macosx; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 26FC0A840875C7B200E6366F /* Build configuration list for PBXNativeTarget "MongoHub" */ = { + 02216F221412D54600789BD1 /* Build configuration list for PBXAggregateTarget "Submodules" */ = { isa = XCConfigurationList; buildConfigurations = ( - 26FC0A850875C7B200E6366F /* Debug */, - 26FC0A860875C7B200E6366F /* Release */, + 02216F231412D54600789BD1 /* Debug */, + 02216F241412D54600789BD1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 26FC0A880875C7B200E6366F /* Build configuration list for PBXProject "MongoHub" */ = { + 26FC0A840875C7B200E6366F /* Build configuration list for PBXNativeTarget "MongoHub" */ = { isa = XCConfigurationList; buildConfigurations = ( - 26FC0A890875C7B200E6366F /* Debug */, - 26FC0A8A0875C7B200E6366F /* Release */, + 26FC0A850875C7B200E6366F /* Debug */, + 26FC0A860875C7B200E6366F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 797A783D0DDCFADE0050D0C2 /* Build configuration list for PBXNativeTarget "MongoHub Spotlight Importer" */ = { + 26FC0A880875C7B200E6366F /* Build configuration list for PBXProject "MongoHub" */ = { isa = XCConfigurationList; buildConfigurations = ( - 797A783B0DDCFADE0050D0C2 /* Debug */, - 797A783C0DDCFADE0050D0C2 /* Release */, + 26FC0A890875C7B200E6366F /* Debug */, + 26FC0A8A0875C7B200E6366F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1045,14 +1253,25 @@ /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ - 1DCB3CFE12C63CD400423160 /* MongoHub_DataModel.xcdatamodeld */ = { + 021BEA641463709A0091C2EA /* MongoHub_DataModel.xcdatamodeld */ = { isa = XCVersionGroup; children = ( - 770B37EC0679A11B001EADE2 /* MongoHub_DataModel1.0.xcdatamodel */, - 1DCB3D0012C63CD400423160 /* MongoHub_DataModel.xcdatamodel */, - 1DDC5E0513A673AE00D0E4D2 /* MongoHub_DataModel2.0.xcdatamodel */, + 02A9B23D19E716FE002A73E4 /* MongoHub_DataModel13.xcdatamodel */, + 0258606A19BD3E2A001EDF8A /* MongoHub_DataModel12.xcdatamodel */, + 0260B93F19B3A4AB00940188 /* MongoHub_DataModel11.xcdatamodel */, + 02E79E9C199275A60016B4C9 /* MongoHub_DataModel9.xcdatamodel */, + 025410A119AA687C00CF437E /* MongoHub_DataModel10.xcdatamodel */, + 02AB33AF194880AB008C06B9 /* MongoHub_DataModel4.xcdatamodel */, + 02AF1BEC1962B4F000926F75 /* MongoHub_DataModel5.xcdatamodel */, + 02B7CCE4197AA07D0031A57A /* MongoHub_DataModel6.xcdatamodel */, + 02940E021982A17A005AF3C1 /* MongoHub_DataModel7.xcdatamodel */, + 0242F133198ABAA900C73FEC /* MongoHub_DataModel8.xcdatamodel */, + 02AB33A6194850BD008C06B9 /* MongoHub_DataModel3.0.xcdatamodel */, + 021BEA651463709A0091C2EA /* MongoHub_DataModel.xcdatamodel */, + 021BEA661463709A0091C2EA /* MongoHub_DataModel1.0.xcdatamodel */, + 021BEA671463709A0091C2EA /* MongoHub_DataModel2.0.xcdatamodel */, ); - currentVersion = 1DCB3D0012C63CD400423160 /* MongoHub_DataModel.xcdatamodel */; + currentVersion = 02A9B23D19E716FE002A73E4 /* MongoHub_DataModel13.xcdatamodel */; path = MongoHub_DataModel.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; diff --git a/MongoHub.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/MongoHub.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..2dfa669f --- /dev/null +++ b/MongoHub.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/MongoHub.xcodeproj/xcshareddata/xcschemes/MongoHub.xcscheme b/MongoHub.xcodeproj/xcshareddata/xcschemes/MongoHub.xcscheme new file mode 100644 index 00000000..3e8b1153 --- /dev/null +++ b/MongoHub.xcodeproj/xcshareddata/xcschemes/MongoHub.xcscheme @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MongoHub.xcodeproj/xcshareddata/xcschemes/Submodules.xcscheme b/MongoHub.xcodeproj/xcshareddata/xcschemes/Submodules.xcscheme new file mode 100644 index 00000000..5f525b5b --- /dev/null +++ b/MongoHub.xcodeproj/xcshareddata/xcschemes/Submodules.xcscheme @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MongoHub_AppDelegate.h b/MongoHub_AppDelegate.h deleted file mode 100644 index f3f7c1db..00000000 --- a/MongoHub_AppDelegate.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// MongoHub_AppDelegate.h -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright MusicPeace.ORG 2010 . All rights reserved. -// - -#import -@class ConnectionsCollectionView; -@class ConnectionsArrayController; -@class Connection; -@class AddConnectionController; -@class EditConnectionController; - -@interface MongoHub_AppDelegate : NSObject -{ - NSWindow *window; - - NSPersistentStoreCoordinator *persistentStoreCoordinator; - NSManagedObjectModel *managedObjectModel; - NSManagedObjectContext *managedObjectContext; - - IBOutlet ConnectionsCollectionView *connectionsCollectionView; - IBOutlet ConnectionsArrayController *connectionsArrayController; - AddConnectionController *addConnectionController; - EditConnectionController *editConnectionController; - IBOutlet NSTextField *bundleVersion; -} - -@property (nonatomic, retain) IBOutlet NSWindow *window; - -@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; -@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; -@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; - -@property (nonatomic, retain) ConnectionsCollectionView *connectionsCollectionView; -@property (nonatomic, retain) ConnectionsArrayController *connectionsArrayController; -@property (nonatomic, retain) AddConnectionController *addConnectionController; -@property (nonatomic, retain) EditConnectionController *editConnectionController; -@property (nonatomic, retain) NSTextField *bundleVersion; - -- (IBAction)saveAction:sender; -- (IBAction)showAddConnectionPanel:(id)sender; -- (IBAction)addConection:(id)sender; -- (IBAction)showEditConnectionPanel:(id)sender; -- (IBAction)editConnection:(id)sender; -- (IBAction)deleteConnection:(id)sender; -- (IBAction)resizeConnectionItemView:(id)sender; -- (IBAction)showConnectionWindow:(id)sender; -- (BOOL)isOpenedConnection:(Connection *)aConnection; -- (void)doubleClick:(id)sender; -@end diff --git a/MongoHub_AppDelegate.m b/MongoHub_AppDelegate.m deleted file mode 100644 index 8d31cb97..00000000 --- a/MongoHub_AppDelegate.m +++ /dev/null @@ -1,394 +0,0 @@ -// -// MongoHub_AppDelegate.m -// MongoHub -// -// Created by Syd on 10-4-24. -// Copyright MusicPeace.ORG 2010 . All rights reserved. -// - -#import "Configure.h" -#import "MongoHub_AppDelegate.h" -#import "AddConnectionController.h" -#import "EditConnectionController.h" -#import "ConnectionsArrayController.h" -#import "ConnectionsCollectionView.h" -#import "ConnectionWindowController.h" -#import "Connection.h" - -#define YOUR_EXTERNAL_RECORD_EXTENSION @"mgo" -#define YOUR_STORE_TYPE NSXMLStoreType - -@implementation MongoHub_AppDelegate - -@synthesize window; -@synthesize connectionsCollectionView; -@synthesize connectionsArrayController; -@synthesize addConnectionController; -@synthesize editConnectionController; -@synthesize bundleVersion; - -/** - Returns the support directory for the application, used to store the Core Data - store file. This code uses a directory named "MongoHub" for - the content, either in the NSApplicationSupportDirectory location or (if the - former cannot be found), the system's temporary directory. - */ - -- (NSString *)applicationSupportDirectory { - - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory(); - return [basePath stringByAppendingPathComponent:@"MongoHub"]; -} - -/** - Returns the external records directory for the application. - This code uses a directory named "MongoHub" for the content, - either in the ~/Library/Caches/Metadata/CoreData location or (if the - former cannot be found), the system's temporary directory. - */ - -- (NSString *)externalRecordsDirectory { - - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory(); - return [basePath stringByAppendingPathComponent:@"Metadata/CoreData/MongoHub"]; -} - -/** - Creates, retains, and returns the managed object model for the application - by merging all of the models found in the application bundle. - */ - -- (NSManagedObjectModel *)managedObjectModel { - - if (managedObjectModel) return managedObjectModel; - - managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; - return managedObjectModel; -} - - -/** - Returns the persistent store coordinator for the application. This - implementation will create and return a coordinator, having added the - store for the application to it. (The directory for the store is created, - if necessary.) - */ - -- (NSPersistentStoreCoordinator *) persistentStoreCoordinator { - - if (persistentStoreCoordinator) return persistentStoreCoordinator; - - NSManagedObjectModel *mom = [self managedObjectModel]; - if (!mom) { - NSAssert(NO, @"Managed object model is nil"); - NSLog(@"%@:%s No model to generate a store from", [self class], _cmd); - return nil; - } - - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *applicationSupportDirectory = [self applicationSupportDirectory]; - NSError *error = nil; - - if ( ![fileManager fileExistsAtPath:applicationSupportDirectory isDirectory:NULL] ) { - if (![fileManager createDirectoryAtPath:applicationSupportDirectory withIntermediateDirectories:NO attributes:nil error:&error]) { - NSAssert(NO, ([NSString stringWithFormat:@"Failed to create App Support directory %@ : %@", applicationSupportDirectory,error])); - NSLog(@"Error creating application support directory at %@ : %@",applicationSupportDirectory,error); - return nil; - } - } - - NSString *externalRecordsDirectory = [self externalRecordsDirectory]; - if ( ![fileManager fileExistsAtPath:externalRecordsDirectory isDirectory:NULL] ) { - if (![fileManager createDirectoryAtPath:externalRecordsDirectory withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"Error creating external records directory at %@ : %@",externalRecordsDirectory,error); - NSAssert(NO, ([NSString stringWithFormat:@"Failed to create external records directory %@ : %@", externalRecordsDirectory,error])); - NSLog(@"Error creating external records directory at %@ : %@",externalRecordsDirectory,error); - return nil; - }; - } - - NSURL *url = [NSURL fileURLWithPath: [applicationSupportDirectory stringByAppendingPathComponent: @"storedata"]]; - // set store options to enable spotlight indexing - NSMutableDictionary *storeOptions = [NSMutableDictionary dictionary]; - [storeOptions setObject:YOUR_EXTERNAL_RECORD_EXTENSION forKey:NSExternalRecordExtensionOption]; - [storeOptions setObject:externalRecordsDirectory forKey:NSExternalRecordsDirectoryOption]; - [storeOptions setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; - [storeOptions setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption]; - - persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: mom]; - if (![persistentStoreCoordinator addPersistentStoreWithType:YOUR_STORE_TYPE - configuration:nil - URL:url - options:storeOptions - error:&error]){ - [[NSApplication sharedApplication] presentError:error]; - [persistentStoreCoordinator release], persistentStoreCoordinator = nil; - return nil; - } - - return persistentStoreCoordinator; -} - -/** - Returns the managed object context for the application (which is already - bound to the persistent store coordinator for the application.) - */ - -- (NSManagedObjectContext *) managedObjectContext { - - if (managedObjectContext) return managedObjectContext; - - NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; - - if (!coordinator) { - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey]; - [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey]; - NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; - [[NSApplication sharedApplication] presentError:error]; - return nil; - } - managedObjectContext = [[NSManagedObjectContext alloc] init]; - [managedObjectContext setPersistentStoreCoordinator: coordinator]; - - return managedObjectContext; -} - -/** - Returns the NSUndoManager for the application. In this case, the manager - returned is that of the managed object context for the application. - */ - -- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window { - return [[self managedObjectContext] undoManager]; -} - --(BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication -{ - return YES; -} - -/** - Performs the save action for the application, which is to send the save: - message to the application's managed object context. Any encountered errors - are presented to the user. - */ - -- (IBAction) saveAction:(id)sender { - - NSError *error = nil; - - if (![[self managedObjectContext] commitEditing]) { - NSLog(@"%@:%s unable to commit editing before saving", [self class], _cmd); - } - - if (![[self managedObjectContext] save:&error]) { - [[NSApplication sharedApplication] presentError:error]; - } -} - - -/** - Implementation of the applicationShouldTerminate: method, used here to - handle the saving of changes in the application managed object context - before the application terminates. - */ - -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - - if (!managedObjectContext) return NSTerminateNow; - - if (![managedObjectContext commitEditing]) { - NSLog(@"%@:%s unable to commit editing to terminate", [self class], _cmd); - return NSTerminateCancel; - } - - if (![managedObjectContext hasChanges]) return NSTerminateNow; - - NSError *error = nil; - if (![managedObjectContext save:&error]) { - - // This error handling simply presents error information in a panel with an - // "Ok" button, which does not include any attempt at error recovery (meaning, - // attempting to fix the error.) As a result, this implementation will - // present the information to the user and then follow up with a panel asking - // if the user wishes to "Quit Anyway", without saving the changes. - - // Typically, this process should be altered to include application-specific - // recovery steps. - - BOOL result = [sender presentError:error]; - if (result) return NSTerminateCancel; - - NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message"); - NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info"); - NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title"); - NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title"); - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:question]; - [alert setInformativeText:info]; - [alert addButtonWithTitle:quitButton]; - [alert addButtonWithTitle:cancelButton]; - - NSInteger answer = [alert runModal]; - [alert release]; - alert = nil; - - if (answer == NSAlertAlternateReturn) return NSTerminateCancel; - - } - - return NSTerminateNow; -} - -/** - Implementation of application:openFiles:, to respond to an open file request from an external record file - */ -- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)files { - - NSString *aPath = [files lastObject]; // just an example to get at one of the paths - - if (aPath && [aPath hasSuffix:YOUR_EXTERNAL_RECORD_EXTENSION]) { - // decode URI from path - NSURL *objectURI = [[NSPersistentStoreCoordinator elementsDerivedFromExternalRecordURL:[NSURL fileURLWithPath:aPath]] objectForKey:NSObjectURIKey]; - if (objectURI) { - NSManagedObjectID *moid = [[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:objectURI]; - if (moid) { - NSManagedObject *mo = [[self managedObjectContext] objectWithID:moid]; - NSLog(@"The record for path %@ is %@",moid,mo); - - // your code to select the object in your application's UI - } - - } - } - -} - -/** - Implementation of dealloc, to release the retained variables. - */ - -- (void)dealloc { - - [window release]; - [managedObjectContext release]; - [persistentStoreCoordinator release]; - [managedObjectModel release]; - - [connectionsCollectionView release]; - [connectionsArrayController release]; - [addConnectionController release]; - [editConnectionController release]; - - [bundleVersion release]; - - [super dealloc]; -} - - -- (void)applicationDidFinishLaunching:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addConection:) name:kNewConnectionWindowWillClose object:nil]; - NSString *appVersion = [[NSString alloc] initWithFormat:@"version(%@[%@])", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey] ]; - [bundleVersion setStringValue: appVersion]; - [appVersion release]; -} - -#pragma mark connections related method -- (IBAction)showAddConnectionPanel:(id)sender { - if (!addConnectionController) { - addConnectionController = [[AddConnectionController alloc] init]; - } - addConnectionController.managedObjectContext = self.managedObjectContext; - [addConnectionController showWindow:self]; -} - -- (IBAction)addConection:(id)sender { - if (![sender object]) { - return; - } - Connection *newObj = [[connectionsArrayController newObject] autorelease]; - [newObj setValue:[[sender object] objectForKey:@"host"] forKey:@"host"]; - [newObj setValue:[[sender object] objectForKey:@"hostport"] forKey:@"hostport"]; - [newObj setValue:[[sender object] objectForKey:@"alias"] forKey:@"alias"]; - [newObj setValue:[[sender object] objectForKey:@"adminuser"] forKey:@"adminuser"]; - [newObj setValue:[[sender object] objectForKey:@"adminpass"] forKey:@"adminpass"]; - [newObj setValue:[[sender object] objectForKey:@"defaultdb"] forKey:@"defaultdb"]; - [newObj setValue:[[sender object] objectForKey:@"usessh"] forKey:@"usessh"]; - [newObj setValue:[[sender object] objectForKey:@"bindaddress"] forKey:@"bindaddress"]; - [newObj setValue:[[sender object] objectForKey:@"bindport"] forKey:@"bindport"]; - [newObj setValue:[[sender object] objectForKey:@"sshhost"] forKey:@"sshhost"]; - [newObj setValue:[[sender object] objectForKey:@"sshport"] forKey:@"sshport"]; - [newObj setValue:[[sender object] objectForKey:@"sshkeyfile"] forKey:@"sshkeyfile"]; - [newObj setValue:[[sender object] objectForKey:@"sshuser"] forKey:@"sshuser"]; - [newObj setValue:[[sender object] objectForKey:@"sshpassword"] forKey:@"sshpassword"]; - [connectionsArrayController addObject:newObj]; - [self saveAction:sender]; -} - -- (IBAction)deleteConnection:(id)sender { - [connectionsArrayController remove:sender]; - [self saveAction:sender]; -} - -- (IBAction)showEditConnectionPanel:(id)sender { - if (![connectionsArrayController selectedObjects]) { - return; - } - Connection *connection = [[connectionsArrayController selectedObjects] objectAtIndex:0]; - if (!editConnectionController) { - editConnectionController = [[EditConnectionController alloc] init]; - } - editConnectionController.connection = connection; - editConnectionController.managedObjectContext = self.managedObjectContext; - [editConnectionController showWindow:self]; -} - -- (IBAction)editConnection:(id)sender { - if (![sender object]) { - return; - } - [self saveAction:sender]; -} - -- (IBAction)resizeConnectionItemView:(id)sender { - CGFloat theSize = [sender floatValue]/100.0f*360.0f; - [connectionsCollectionView setSubviewSize:theSize]; -} - -- (IBAction)showConnectionWindow:(id)sender { - if (![connectionsArrayController selectedObjects]) { - return; - } - [self doubleClick:[[connectionsArrayController selectedObjects] objectAtIndex:0]]; -} - -- (void)doubleClick:(id)sender { - if (![sender isKindOfClass:[Connection class]]) { - sender = [[connectionsArrayController selectedObjects] objectAtIndex:0]; - } - if ([self isOpenedConnection:sender]) { - return; - } - ConnectionWindowController *connectionWindowController = [[ConnectionWindowController alloc] init]; - connectionWindowController.managedObjectContext = self.managedObjectContext; - connectionWindowController.conn = sender; - [connectionWindowController showWindow:sender]; -} - -- (BOOL)isOpenedConnection:(Connection *)aConnection { - NSWindow *aWindow; - for (aWindow in [[NSApplication sharedApplication] windows]) - { - id aDelegate = [aWindow delegate]; - if ([aDelegate isKindOfClass:[ConnectionWindowController class]] && [aDelegate conn] == aConnection) { - [aWindow makeKeyAndOrderFront:nil]; - return YES; - } - } - return NO; -} - -@end diff --git a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/elements b/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/elements deleted file mode 100644 index 85efd33f..00000000 Binary files a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/elements and /dev/null differ diff --git a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/layout b/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/layout deleted file mode 100644 index 4b73e683..00000000 Binary files a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/layout and /dev/null differ diff --git a/MongoHub_Prefix.pch b/MongoHub_Prefix.pch deleted file mode 100644 index 4f768001..00000000 --- a/MongoHub_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'MongoHub' target in the 'MongoHub' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/NSArray+Color.h b/NSArray+Color.h deleted file mode 100644 index 5598cbb1..00000000 --- a/NSArray+Color.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// NSArray+Color.h -// CocoaTADS -// -// Created by Uli Kusterer on Mon Jun 02 2003. -// Copyright (c) 2003 Uli Kusterer. -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// - -// ----------------------------------------------------------------------------- -// Headers: -// ----------------------------------------------------------------------------- - -#import - - -// ----------------------------------------------------------------------------- -// Category: -// ----------------------------------------------------------------------------- - -// Methods to treat an NSArray with three/four elements as an RGB/RGBA color. -// Useful for storing colors in NSUserDefaults and other Property Lists. -// Note that this isn't quite the same as storing an NSData of the color, as -// some colors can't be correctly represented in RGB, but this makes for more -// readable property lists than NSData. -// If we wanted to get fancy, we could use an NSDictionary instead and save -// different color types in different ways. - -@interface NSArray (UKColor) - -+(NSArray*) arrayWithColor: (NSColor*) col; --(NSColor*) colorValue; - -@end \ No newline at end of file diff --git a/NSArray+Color.m b/NSArray+Color.m deleted file mode 100644 index 007c361a..00000000 --- a/NSArray+Color.m +++ /dev/null @@ -1,83 +0,0 @@ -// -// NSArray+Color.m -// CocoaTADS -// -// Created by Uli Kusterer on Mon Jun 02 2003. -// Copyright (c) 2003 Uli Kusterer. -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// - -// ----------------------------------------------------------------------------- -// Headers: -// ----------------------------------------------------------------------------- - -#import "NSArray+Color.h" - - -@implementation NSArray (UKColor) - -// ----------------------------------------------------------------------------- -// arrayWithColor: -// Converts the color to an RGB color if needed, and then creates an array -// with its red, green, blue and alpha components (in that order). -// -// REVISIONS: -// 2004-05-18 witness documented. -// ----------------------------------------------------------------------------- - -+(NSArray*) arrayWithColor: (NSColor*) col -{ - CGFloat fRed = 1, fGreen = 1, fBlue = 1, fAlpha = 1.0; - - col = [col colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; - [col getRed: &fRed green: &fGreen blue: &fBlue alpha: &fAlpha]; - - return [self arrayWithObjects: [NSNumber numberWithFloat:fRed], [NSNumber numberWithFloat:fGreen], - [NSNumber numberWithFloat:fBlue], [NSNumber numberWithFloat:fAlpha], nil]; -} - - -// ----------------------------------------------------------------------------- -// colorValue: -// Converts an NSArray with three (or four) NSValues into an RGB Color -// (plus alpha, if specified). -// -// REVISIONS: -// 2004-05-18 witness documented. -// ----------------------------------------------------------------------------- - --(NSColor*) colorValue -{ - float fRed = 1, fGreen = 1, fBlue = 1, fAlpha = 1.0; - - if( [self count] >= 3 ) - { - fRed = [[self objectAtIndex:0] floatValue]; - fGreen = [[self objectAtIndex:1] floatValue]; - fBlue = [[self objectAtIndex:2] floatValue]; - } - if( [self count] > 3 ) // Have alpha info? - fAlpha = [[self objectAtIndex:3] floatValue]; - - return [NSColor colorWithCalibratedRed: fRed green: fGreen blue: fBlue alpha: fAlpha]; -} - -@end diff --git a/NSProgressIndicator+Extras.h b/NSProgressIndicator+Extras.h deleted file mode 100644 index 3651024e..00000000 --- a/NSProgressIndicator+Extras.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// NSProgressIndicator+Extras.h -// MongoHub -// -// Created by Syd on 10-12-22. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import - - -@interface NSProgressIndicator (Extras) - -- (void)start; -- (void)stop; - -@end diff --git a/NSProgressIndicator+Extras.m b/NSProgressIndicator+Extras.m deleted file mode 100644 index f9392b08..00000000 --- a/NSProgressIndicator+Extras.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// NSProgressIndicator+Extras.m -// MongoHub -// -// Created by Syd on 10-12-22. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "NSProgressIndicator+Extras.h" - - -@implementation NSProgressIndicator (Extras) - -- (void)start { - [self startAnimation:self]; - [self setHidden:NO]; -} - -- (void)stop { - [self setHidden:YES]; - [self stopAnimation:self]; -} - -@end diff --git a/NSString+Extras.h b/NSString+Extras.h deleted file mode 100644 index 8ac779a6..00000000 --- a/NSString+Extras.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// NSString+Extras.h -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import - - -@interface NSString (Extras) - -+ (NSString*)stringFromResource:(NSString*)resourceName; -- (BOOL)startsWithString:(NSString*)otherString; -- (BOOL)endsWithString:(NSString*)otherString; -- (BOOL)isPresent; -- (NSComparisonResult)compareCaseInsensitive:(NSString*)other; -- (NSString*)stringByPercentEscapingCharacters:(NSString*)characters; -- (NSString*)stringByEscapingURL; -- (NSString*)stringByUnescapingURL; -- (BOOL) containsString:(NSString *)aString; -- (BOOL) containsString:(NSString *)aString ignoringCase:(BOOL)flag; -- (int)countSubstring:(NSString *)aString ignoringCase:(BOOL)flag; -- (NSString *)stringByTrimmingWhitespace; - -+ (NSNull *)nullValue; -+ (NSString*)UUIDString; - -@end diff --git a/NSString+Extras.m b/NSString+Extras.m deleted file mode 100644 index 963eefbc..00000000 --- a/NSString+Extras.m +++ /dev/null @@ -1,84 +0,0 @@ -// -// NSString+Extras.m -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "NSString+Extras.h" - - -@implementation NSString (Extras) - - -+ (NSString*)stringFromResource:(NSString*)resourceName { - NSString *path = [[NSBundle mainBundle] pathForResource:resourceName ofType:nil]; - return [NSString stringWithContentsOfFile:path usedEncoding:nil error:nil]; -} - -# pragma Comparing - -- (BOOL)startsWithString:(NSString*)otherString { - return [self rangeOfString:otherString].location == 0; -} - -- (BOOL)endsWithString:(NSString*)otherString { - return [self rangeOfString:otherString].location == [self length]-[otherString length]; -} - -- (BOOL)isPresent { - return ![self isEqualToString:@""]; -} - -- (NSComparisonResult)compareCaseInsensitive:(NSString*)other { - NSString *selfString = [self lowercaseString]; - NSString *otherString = [other lowercaseString]; - return [selfString compare:otherString]; -} - -- (NSString*)stringByPercentEscapingCharacters:(NSString*)characters { - return [(NSString*)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)characters, kCFStringEncodingUTF8) autorelease]; -} - -- (NSString*)stringByEscapingURL { - return [self stringByPercentEscapingCharacters:@";/?:@&=+$,"]; -} - -- (NSString*)stringByUnescapingURL { - return [(NSString*)CFURLCreateStringByReplacingPercentEscapes(NULL, (CFStringRef)self, CFSTR("")) autorelease]; -} - -- (BOOL)containsString:(NSString *)aString { - return [self containsString:aString ignoringCase:NO]; -} - -- (BOOL)containsString:(NSString *)aString ignoringCase:(BOOL)flag { - unsigned mask = (flag ? NSCaseInsensitiveSearch : 0); - return [self rangeOfString:aString options:mask].length > 0; -} - -- (int)countSubstring:(NSString *)aString ignoringCase:(BOOL)flag { - unsigned mask = (flag ? NSCaseInsensitiveSearch : 0); - return [self rangeOfString:aString options:mask].length; -} - -- (NSString *)stringByTrimmingWhitespace -{ - return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; -} - -+ (NSNull *)nullValue -{ - return [NSNull null]; -} - -+ (NSString*)UUIDString { - CFUUIDRef theUUID = CFUUIDCreate(NULL); - CFStringRef string = CFUUIDCreateString(NULL, theUUID); - CFRelease(theUUID); - return [(NSString *)string autorelease]; -} - - -@end diff --git a/NewCollection.xib b/NewCollection.xib deleted file mode 100644 index 5e6f28fa..00000000 --- a/NewCollection.xib +++ /dev/null @@ -1,899 +0,0 @@ - - - - 1060 - 10D573 - 762 - 1038.29 - 460.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 762 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - AddCollectionController - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{196, 424}, {328, 86}} - 544735232 - Add New Collection - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 268 - {{140, 51}, {168, 22}} - - YES - - -1804468671 - 272630784 - - - LucidaGrande - 13 - 1044 - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - - - - 268 - {{17, 53}, {113, 17}} - - YES - - 68288064 - 272630784 - Collection Name - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - - - - - - 268 - {{250, 18}, {58, 25}} - - YES - - -2080244224 - 134217728 - Add - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{177, 18}, {65, 25}} - - YES - - -2080244224 - 134217728 - Cancel - - - -2038152961 - 163 - - - 400 - 75 - - - - {328, 86} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - - - YES - - - window - - - - 11 - - - - delegate - - - - 12 - - - - collectionname - - - - 13 - - - - cancel: - - - - 15 - - - - add: - - - - 16 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - - - 3 - - - YES - - - - - - 4 - - - - - 5 - - - YES - - - - - - 6 - - - - - 7 - - - YES - - - - - - 8 - - - - - 9 - - - YES - - - - - - 10 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 10.IBPluginDependency - 2.IBPluginDependency - 3.IBPluginDependency - 4.IBPluginDependency - 5.IBPluginDependency - 6.IBPluginDependency - 7.IBPluginDependency - 8.IBPluginDependency - 9.IBPluginDependency - - - YES - {{163, 662}, {328, 86}} - com.apple.InterfaceBuilder.CocoaPlugin - {{163, 662}, {328, 86}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 16 - - - - YES - - AddCollectionController - NSWindowController - - YES - - YES - add: - cancel: - - - YES - id - id - - - - collectionname - NSTextField - - - IBProjectSource - AddCollectionController.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - diff --git a/NewConnection.xib b/NewConnection.xib deleted file mode 100644 index 8c963fde..00000000 --- a/NewConnection.xib +++ /dev/null @@ -1,2733 +0,0 @@ - - - - 1060 - 10J869 - 823 - 1038.35 - 461.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 823 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - AddConnectionController - - - FirstResponder - - - NSApplication - - - 7 - 2 - {{196, -46}, {353, 556}} - 544735232 - Add New Connection - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 268 - {{60, 475}, {166, 22}} - - YES - - -1805517311 - 272630016 - - - LucidaGrande - 13 - 1044 - - localhost - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - 3 - MAA - - - - - - - 268 - {{17, 480}, {61, 17}} - - YES - - 68288064 - 272630784 - Host - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - - - - - - 268 - {{17, 519}, {38, 17}} - - YES - - 68288064 - 272630784 - Alias - - - - - - - - - 268 - {{267, 18}, {66, 25}} - - YES - - -2080244224 - 134217728 - Save - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{185, 18}, {67, 25}} - - YES - - -2080244224 - 134217728 - Cancel - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{60, 514}, {273, 22}} - - YES - - -1805517311 - 272630016 - - - localhost - - YES - - - - - - - 268 - {{231, 480}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{274, 475}, {59, 22}} - - YES - - -1804468671 - 272630784 - - - 27017 - - YES - - - - - - - 268 - {{18, 268}, {128, 18}} - - YES - - 67239424 - 0 - Use SSH Tunnel - - - -936623617 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 12 - {{20, 259}, {313, 5}} - - {0, 0} - - 67239424 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 268 - {{17, 236}, {92, 17}} - - YES - - 68288064 - 272630784 - Bind Address - - - - - - - - - 268 - {{114, 231}, {112, 22}} - - YES - - -1268646399 - 272630016 - - - 127.0.0.1 - - YES - - - - - - - 268 - {{231, 236}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{274, 231}, {59, 22}} - - YES - - -1267597759 - 272630784 - - - 27017 - - YES - - - - - - - 268 - {{17, 191}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH Host - - - - - - - - - 268 - {{114, 189}, {112, 22}} - - YES - - -1268646399 - 272630016 - - - - YES - - - - - - - 268 - {{17, 155}, {100, 17}} - - YES - - 68288064 - 272630784 - SSH Username - - - - - - - - - 268 - {{114, 150}, {219, 22}} - - YES - - -1267597759 - 272630784 - - - - YES - - - - - - - 268 - {{17, 115}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH Password - - - - - - - - - 268 - {{114, 110}, {219, 22}} - - YES - - 879885888 - 272630848 - - - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{231, 191}, {38, 17}} - - YES - - 68288064 - 272630784 - Port - - - - - - - - - 268 - {{274, 188}, {59, 22}} - - YES - - -1804468671 - 272630784 - - - 22 - - YES - - - - - - - 268 - {{60, 442}, {117, 22}} - - YES - - -1805517311 - 272630016 - - - Admin Username - - YES - - - - - - - 268 - {{17, 445}, {38, 17}} - - YES - - 68288064 - 272630784 - User - - - - - - - - - 268 - {{182, 444}, {56, 17}} - - YES - - 68288064 - 272630784 - Passwd - - - - - - - - - 268 - {{237, 442}, {96, 22}} - - YES - - 341966336 - 272630080 - - - Admin Password - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - - 268 - {{17, 408}, {38, 17}} - - YES - - 68288064 - 272630784 - DB - - - - - - - - - 268 - {{60, 406}, {273, 22}} - - YES - - -1804468671 - 272630784 - - - Database Name - - YES - - - - - - - 268 - {{18, 374}, {128, 18}} - - YES - - 67239424 - 0 - Use Replica Set - - - 1210864127 - 2 - - - - - 200 - 25 - - - - - 12 - {{20, 365}, {313, 5}} - - {0, 0} - - 67239424 - 0 - Box - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - 3 - 2 - 0 - NO - - - - 268 - {{17, 342}, {61, 17}} - - YES - - 68288064 - 272630784 - Servers - - - - - - - - - 268 - {{99, 339}, {234, 22}} - - YES - - -1268646399 - 272630016 - - - host1:port1,host2:port2,host3:port3 - - YES - - - - - - - 268 - {{17, 307}, {77, 17}} - - YES - - 68288064 - 272630784 - Set Name - - - - - - - - - 268 - {{99, 304}, {234, 22}} - - YES - - -1267597759 - 272630784 - - - demo_repl - - YES - - - - - - - 268 - {{17, 76}, {92, 17}} - - YES - - 68288064 - 272630784 - SSH KEY FILE - - - - - - - - - 268 - {{114, 71}, {152, 22}} - - YES - - -1804468671 - 272630784 - - - ~/.ssh/id_rsa - - YES - - - - - - - 268 - {{274, 69}, {59, 25}} - - YES - - -2080244224 - 134217728 - Select - - - -2038152961 - 163 - - - 400 - 75 - - - - {353, 556} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - YES - YES - - Connection - - YES - YES - YES - YES - YES - YES - YES - - - - - YES - - - hostTextField - - - - 15 - - - - cancel: - - - - 18 - - - - window - - - - 19 - - - - delegate - - - - 20 - - - - connectionsArrayController - - - - 22 - - - - managedObjectContext: managedObjectContext - - - - - - managedObjectContext: managedObjectContext - managedObjectContext - managedObjectContext - 2 - - - 23 - - - - initialFirstResponder - - - - 25 - - - - add: - - - - 26 - - - - aliasTextField - - - - 29 - - - - hostportTextField - - - - 57 - - - - usesshCheckBox - - - - 58 - - - - bindaddressTextField - - - - 59 - - - - bindportTextField - - - - 60 - - - - sshhostTextField - - - - 61 - - - - sshuserTextField - - - - 64 - - - - enableSSH: - - - - 70 - - - - sshpasswordTextField - - - - 73 - - - - sshportTextField - - - - 78 - - - - adminuserTextField - - - - 87 - - - - adminpassTextField - - - - 88 - - - - defaultdbTextField - - - - 93 - - - - usereplCheckBox - - - - 96 - - - - serversTextField - - - - 102 - - - - replnameTextField - - - - 107 - - - - enableRepl: - - - - 108 - - - - sshkeyfileTextField - - - - 113 - - - - chooseKeyPath: - - - - 116 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - YES - - - - - - 4 - - - - - 7 - - - YES - - - - - - 8 - - - - - 9 - - - YES - - - - - - 10 - - - - - 11 - - - YES - - - - - - 12 - - - - - 13 - - - YES - - - - - - 14 - - - - - 21 - - - - - 27 - - - YES - - - - - - 28 - - - - - 30 - - - YES - - - - - - 31 - - - - - 32 - - - YES - - - - - - 33 - - - - - 34 - - - YES - - - - - - 35 - - - - - 36 - - - - - 37 - - - YES - - - - - - 38 - - - - - 39 - - - YES - - - - - - 40 - - - - - 41 - - - YES - - - - - - 42 - - - - - 43 - - - YES - - - - - - 44 - - - - - 45 - - - YES - - - - - - 46 - - - - - 47 - - - YES - - - - - - 48 - - - - - 49 - - - YES - - - - - - 50 - - - - - 51 - - - YES - - - - - - 52 - - - - - 53 - - - YES - - - - - - 54 - - - - - 71 - - - YES - - - - - - 72 - - - - - 74 - - - YES - - - - - - 75 - - - - - 76 - - - YES - - - - - - 77 - - - - - 79 - - - YES - - - - - - 80 - - - - - 81 - - - YES - - - - - - 82 - - - - - 83 - - - YES - - - - - - 84 - - - - - 85 - - - YES - - - - - - 86 - - - - - 89 - - - YES - - - - - - 90 - - - - - 91 - - - YES - - - - - - 92 - - - - - 94 - - - YES - - - - - - 95 - - - - - 97 - - - - - 98 - - - YES - - - - - - 99 - - - - - 100 - - - YES - - - - - - 101 - - - - - 103 - - - YES - - - - - - 104 - - - - - 105 - - - YES - - - - - - 106 - - - - - 109 - - - YES - - - - - - 110 - - - - - 111 - - - YES - - - - - - 112 - - - - - 114 - - - YES - - - - - - 115 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 10.IBPluginDependency - 100.IBPluginDependency - 100.IBViewBoundsToFrameTransform - 101.IBPluginDependency - 103.IBPluginDependency - 103.IBViewBoundsToFrameTransform - 104.IBPluginDependency - 105.IBPluginDependency - 105.IBViewBoundsToFrameTransform - 106.IBPluginDependency - 109.IBPluginDependency - 109.IBViewBoundsToFrameTransform - 11.IBPluginDependency - 11.IBViewBoundsToFrameTransform - 110.IBPluginDependency - 111.IBPluginDependency - 112.IBPluginDependency - 114.IBPluginDependency - 115.IBPluginDependency - 12.IBPluginDependency - 13.IBPluginDependency - 13.IBViewBoundsToFrameTransform - 14.IBPluginDependency - 2.IBPluginDependency - 21.CustomClassName - 21.IBPluginDependency - 27.IBPluginDependency - 27.IBViewBoundsToFrameTransform - 28.IBPluginDependency - 3.IBPluginDependency - 3.IBViewBoundsToFrameTransform - 30.IBPluginDependency - 30.IBViewBoundsToFrameTransform - 31.IBPluginDependency - 32.IBPluginDependency - 32.IBViewBoundsToFrameTransform - 33.IBPluginDependency - 34.IBPluginDependency - 34.IBViewBoundsToFrameTransform - 35.IBPluginDependency - 36.IBPluginDependency - 36.IBViewBoundsToFrameTransform - 37.IBPluginDependency - 37.IBViewBoundsToFrameTransform - 38.IBPluginDependency - 39.IBPluginDependency - 39.IBViewBoundsToFrameTransform - 4.IBPluginDependency - 40.IBPluginDependency - 41.IBPluginDependency - 41.IBViewBoundsToFrameTransform - 42.IBPluginDependency - 43.IBPluginDependency - 43.IBViewBoundsToFrameTransform - 44.IBPluginDependency - 45.IBPluginDependency - 45.IBViewBoundsToFrameTransform - 46.IBPluginDependency - 47.IBPluginDependency - 47.IBViewBoundsToFrameTransform - 48.IBPluginDependency - 49.IBPluginDependency - 49.IBViewBoundsToFrameTransform - 50.IBPluginDependency - 51.IBPluginDependency - 51.IBViewBoundsToFrameTransform - 52.IBPluginDependency - 53.IBPluginDependency - 53.IBViewBoundsToFrameTransform - 54.IBPluginDependency - 7.IBPluginDependency - 7.IBViewBoundsToFrameTransform - 71.IBPluginDependency - 71.IBViewBoundsToFrameTransform - 72.IBPluginDependency - 74.IBPluginDependency - 74.IBViewBoundsToFrameTransform - 75.IBPluginDependency - 76.IBPluginDependency - 76.IBViewBoundsToFrameTransform - 77.IBPluginDependency - 79.IBPluginDependency - 79.IBViewBoundsToFrameTransform - 8.IBPluginDependency - 80.IBPluginDependency - 81.IBPluginDependency - 81.IBViewBoundsToFrameTransform - 82.IBPluginDependency - 83.IBPluginDependency - 83.IBViewBoundsToFrameTransform - 84.IBPluginDependency - 85.IBPluginDependency - 85.IBViewBoundsToFrameTransform - 86.IBPluginDependency - 89.IBPluginDependency - 89.IBViewBoundsToFrameTransform - 9.IBPluginDependency - 9.IBViewBoundsToFrameTransform - 90.IBPluginDependency - 91.IBPluginDependency - 91.IBViewBoundsToFrameTransform - 92.IBPluginDependency - 94.IBPluginDependency - 94.IBViewBoundsToFrameTransform - 95.IBPluginDependency - 97.IBPluginDependency - 97.IBViewBoundsToFrameTransform - 98.IBPluginDependency - 98.IBViewBoundsToFrameTransform - 99.IBPluginDependency - - - YES - {{112, 191}, {353, 556}} - com.apple.InterfaceBuilder.CocoaPlugin - {{112, 191}, {353, 556}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCxgAAw56AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw4wAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCxgAAw40AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwp4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDhYAAwqYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDOQAAwqYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - ConnectionsArrayController - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCcAAAw/YAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCcAAAw+KAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDZwAAw+KAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiQAAw+KAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBkAAAw3IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - AUGgAABDWQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDZwAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiQAAw1EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwyQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAwycAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwwAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAwwAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwwIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw+KAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABC5AAAwwIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDZwAAwyQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDiQAAwyYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCcAAAw9IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw9EAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDNgAAw9CAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDbQAAw9IAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw76AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw/YAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCcAAAw8AAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBkAAAw64AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - AUGgAABDoYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAw52AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 116 - - - - YES - - AddConnectionController - NSWindowController - - YES - - YES - add: - cancel: - chooseKeyPath: - enableRepl: - enableSSH: - - - YES - id - id - id - id - id - - - - YES - - YES - add: - cancel: - chooseKeyPath: - enableRepl: - enableSSH: - - - YES - - add: - id - - - cancel: - id - - - chooseKeyPath: - id - - - enableRepl: - id - - - enableSSH: - id - - - - - YES - - YES - adminpassTextField - adminuserTextField - aliasTextField - bindaddressTextField - bindportTextField - connectionsArrayController - defaultdbTextField - hostTextField - hostportTextField - replnameTextField - serversTextField - sshhostTextField - sshkeyfileTextField - sshpasswordTextField - sshportTextField - sshuserTextField - usereplCheckBox - usesshCheckBox - - - YES - NSSecureTextField - NSTextField - NSTextField - NSTextField - NSTextField - ConnectionsArrayController - NSTextField - NSTextField - NSTextField - NSTextField - NSTextField - NSTextField - NSTextField - NSSecureTextField - NSTextField - NSTextField - NSButton - NSButton - - - - YES - - YES - adminpassTextField - adminuserTextField - aliasTextField - bindaddressTextField - bindportTextField - connectionsArrayController - defaultdbTextField - hostTextField - hostportTextField - replnameTextField - serversTextField - sshhostTextField - sshkeyfileTextField - sshpasswordTextField - sshportTextField - sshuserTextField - usereplCheckBox - usesshCheckBox - - - YES - - adminpassTextField - NSSecureTextField - - - adminuserTextField - NSTextField - - - aliasTextField - NSTextField - - - bindaddressTextField - NSTextField - - - bindportTextField - NSTextField - - - connectionsArrayController - ConnectionsArrayController - - - defaultdbTextField - NSTextField - - - hostTextField - NSTextField - - - hostportTextField - NSTextField - - - replnameTextField - NSTextField - - - serversTextField - NSTextField - - - sshhostTextField - NSTextField - - - sshkeyfileTextField - NSTextField - - - sshpasswordTextField - NSSecureTextField - - - sshportTextField - NSTextField - - - sshuserTextField - NSTextField - - - usereplCheckBox - NSButton - - - usesshCheckBox - NSButton - - - - - IBProjectSource - AddConnectionController.h - - - - ConnectionsArrayController - NSArrayController - - IBProjectSource - ConnectionsArrayController.h - - - - NSObject - - IBProjectSource - Tunnel.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSBox - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSBox.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - RegexKit.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSSecureTextFieldCell - NSTextFieldCell - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - NSSwitch - {15, 15} - - - diff --git a/NewDB.xib b/NewDB.xib deleted file mode 100644 index a60b7810..00000000 --- a/NewDB.xib +++ /dev/null @@ -1,1186 +0,0 @@ - - - - 1060 - 10D573 - 762 - 1038.29 - 460.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 762 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - AddDBController - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{196, 367}, {377, 143}} - 544735232 - Add New Database - NSWindow - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 268 - {{17, 106}, {38, 17}} - - YES - - 68288064 - 272630784 - Name - - LucidaGrande - 13 - 1044 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 268 - {{75, 103}, {282, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - - - - 268 - {{17, 70}, {38, 17}} - - YES - - 68288064 - 272630784 - User - - - - - - - - - 268 - {{75, 65}, {96, 22}} - - YES - - -1804468671 - 272630784 - - - - YES - - - - - - - 268 - {{186, 70}, {70, 17}} - - YES - - 68288064 - 272630784 - Password - - - - - - - - - 268 - {{286, 18}, {71, 25}} - - YES - - -2080244224 - 134217728 - Create - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{201, 18}, {74, 25}} - - YES - - -2080244224 - 134217728 - Cancel - - - -2038152961 - 163 - - - 400 - 75 - - - - - 268 - {{261, 67}, {96, 22}} - - YES - - 343014976 - 272630848 - - - - YES - - - - YES - NSAllRomanInputSourcesLocaleIdentifier - - - - - {377, 143} - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - YES - - Database - - YES - YES - YES - YES - YES - YES - - - - - YES - - - window - - - - 3 - - - - delegate - - - - 4 - - - - dbname - - - - 21 - - - - user - - - - 23 - - - - password - - - - 27 - - - - cancel: - - - - 28 - - - - add: - - - - 29 - - - - managedObjectContext: managedObjectContext - - - - - - managedObjectContext: managedObjectContext - managedObjectContext - managedObjectContext - 2 - - - 31 - - - - databasesArrayController - - - - 32 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - 2 - - - YES - - - - - - - - - - - - - 5 - - - YES - - - - - - 6 - - - - - 7 - - - YES - - - - - - 8 - - - - - 9 - - - YES - - - - - - 10 - - - - - 11 - - - YES - - - - - - 12 - - - - - 13 - - - YES - - - - - - 14 - - - - - 17 - - - YES - - - - - - 18 - - - - - 19 - - - YES - - - - - - 20 - - - - - 25 - - - YES - - - - - - 26 - - - - - 30 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 10.IBPluginDependency - 11.IBPluginDependency - 12.IBPluginDependency - 13.IBPluginDependency - 14.IBPluginDependency - 17.IBPluginDependency - 18.IBPluginDependency - 19.IBPluginDependency - 2.IBPluginDependency - 20.IBPluginDependency - 25.IBPluginDependency - 26.IBPluginDependency - 30.CustomClassName - 30.IBPluginDependency - 5.IBPluginDependency - 6.IBPluginDependency - 7.IBPluginDependency - 8.IBPluginDependency - 9.IBPluginDependency - - - YES - {{170, 599}, {377, 143}} - com.apple.InterfaceBuilder.CocoaPlugin - {{170, 599}, {377, 143}} - - {196, 240} - {{202, 428}, {480, 270}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - DatabasesArrayController - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 32 - - - - YES - - AddDBController - NSWindowController - - YES - - YES - add: - cancel: - - - YES - id - id - - - - YES - - YES - databasesArrayController - dbname - password - user - - - YES - DatabasesArrayController - NSTextField - NSSecureTextField - NSTextField - - - - IBProjectSource - AddDBController.h - - - - DatabasesArrayController - NSArrayController - - IBProjectSource - DatabasesArrayController.h - - - - NSObject - - IBProjectSource - JSON/NSObject+SBJSON.h - - - - NSObject - - IBProjectSource - JSON/SBJsonWriter.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSArrayController - NSObjectController - - IBFrameworkSource - AppKit.framework/Headers/NSArrayController.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSController - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSController.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSManagedObjectContext - NSObject - - IBFrameworkSource - CoreData.framework/Headers/NSManagedObjectContext.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObjectController - NSController - - IBFrameworkSource - AppKit.framework/Headers/NSObjectController.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSecureTextField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSSecureTextField.h - - - - NSSecureTextFieldCell - NSTextFieldCell - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - diff --git a/QueryWindow.xib b/QueryWindow.xib deleted file mode 100644 index b8ccc77a..00000000 --- a/QueryWindow.xib +++ /dev/null @@ -1,8783 +0,0 @@ - - - - 1060 - 10J869 - 823 - 1038.35 - 461.00 - - YES - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - - YES - 823 - 1.2.5 - - - - YES - - - - YES - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - QueryWindowController - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{196, 106}, {564, 404}} - 544735232 - Query Window - NSWindow - - - 1A2E632D-6D5F-4FC9-99F2-F98547542279 - - - YES - YES - YES - NO - 1 - 2 - - YES - - YES - 0A7EA678-8ECC-4FCF-80E2-AE260A745E2F - 13717649-03C3-4CAB-9B73-9550440C3A80 - 6000916F-1E4E-4C9D-ABF3-DE4B58273D1E - 73AA96E0-2204-4179-B215-FB9E19A47700 - ADE7AE73-9D9F-48D0-A1F8-ED0283631362 - C13205AC-9974-4C5D-BC5A-D526F7E90D72 - CE0D3850-6F3B-456E-BB68-305457298245 - F2C6F823-BB06-4F23-B9C7-D15D66EDDB04 - NSToolbarFlexibleSpaceItem - NSToolbarSeparatorItem - NSToolbarSpaceItem - - - YES - - - 0A7EA678-8ECC-4FCF-80E2-AE260A745E2F - - Index - Index - - - - NSImage - indexmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 13717649-03C3-4CAB-9B73-9550440C3A80 - - Insert - Insery - - - - NSImage - insertmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 6000916F-1E4E-4C9D-ABF3-DE4B58273D1E - - Import - Import - - - - NSImage - importmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - 73AA96E0-2204-4179-B215-FB9E19A47700 - - Update - Update - - - - NSImage - updatemenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - ADE7AE73-9D9F-48D0-A1F8-ED0283631362 - - MapReduce - MapReduce - - - - NSImage - mapreducemenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - C13205AC-9974-4C5D-BC5A-D526F7E90D72 - - Remove - Remove - - - - NSImage - removemenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - CE0D3850-6F3B-456E-BB68-305457298245 - - Find - Find - - - - NSImage - findmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - - F2C6F823-BB06-4F23-B9C7-D15D66EDDB04 - - Export - Export - - - - NSImage - exportmenu - - - - {0, 0} - {0, 0} - YES - YES - -1 - YES - 0 - - - NSToolbarFlexibleSpaceItem - - Flexible Space - - - - - - {1, 5} - {20000, 32} - YES - YES - -1 - YES - 0 - - YES - YES - - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - - - - NSToolbarSeparatorItem - - Separator - - - - - - {12, 5} - {12, 1000} - YES - YES - -1 - YES - 0 - - YES - YES - - - 1048576 - 2147483647 - - - - - - NSToolbarSpaceItem - - Space - - - - - - {32, 5} - {32, 32} - YES - YES - -1 - YES - 0 - - YES - YES - - - 1048576 - 2147483647 - - - - - - - - YES - - - - - - - - - - - - - - YES - - - - - - - - - - - YES - - - - - YES - - YES - 0A7EA678-8ECC-4FCF-80E2-AE260A745E2F - 0D5950D1-D4A8-44C6-9DBC-251CFEF852E2 - 13717649-03C3-4CAB-9B73-9550440C3A80 - 6000916F-1E4E-4C9D-ABF3-DE4B58273D1E - 73AA96E0-2204-4179-B215-FB9E19A47700 - ADE7AE73-9D9F-48D0-A1F8-ED0283631362 - C13205AC-9974-4C5D-BC5A-D526F7E90D72 - CE0D3850-6F3B-456E-BB68-305457298245 - F0592071-DE5B-4557-A104-123CFE141B7E - F2C6F823-BB06-4F23-B9C7-D15D66EDDB04 - - - YES - - - 256 - - YES - - - 266 - - YES - - - 268 - {{17, 10}, {41, 14}} - - - YES - - 68288064 - 272761856 - Index - - LucidaGrande - 11 - 3100 - - - - 6 - System - controlColor - - 3 - MC42NjY2NjY2ODY1AA - - - - 6 - System - controlTextColor - - 3 - MAA - - - - - - - 264 - {{292, 35}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Ensure Index - - LucidaGrande - 13 - 1044 - - - -2034482945 - 163 - - NSImage - NSAddTemplate - - - - 400 - 75 - - - - - 266 - {{57, 6}, {463, 22}} - - - YES - - -1804468671 - 272630784 - - - - YES - - 6 - System - textBackgroundColor - - 3 - MQA - - - - 6 - System - textColor - - - - - - - 268 - {{20, 35}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Get Indexes - - - -2034482945 - 163 - - NSImage - NSListViewTemplate - - - - 400 - 75 - - - - - 264 - {{154, 35}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Drop Index - - - -2034482945 - 163 - - NSImage - NSStopProgressTemplate - - - - 400 - 75 - - - - - 264 - {{426, 35}, {118, 25}} - - - YES - - -2080244224 - 134217728 - ReIndex - - - -2034482945 - 163 - - NSImage - NSRefreshTemplate - - - - 400 - 75 - - - - - -2147482359 - - {{528, 9}, {16, 16}} - - - 20746 - 100 - - - {{0, 275}, {564, 70}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 274 - - YES - - - 2304 - - YES - - - 256 - {562, 233} - - - YES - - - 256 - {562, 17} - - - - - - - -2147483392 - {{548, 0}, {16, 17}} - - - - - YES - - name - 101 - 16 - 1000 - - 75628096 - 2048 - Name - - - 3 - MC4zMzMzMzI5ODU2AA - - - 6 - System - headerTextColor - - - - - 337772096 - 2048 - Text Cell - - LucidaGrande-Bold - 13 - 16 - - - - 6 - System - controlBackgroundColor - - - - - 3 - YES - - - - value - 372 - 40 - 1000 - - 75628096 - 2048 - Value - - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - - - - type - 80 - 80 - 80 - - 75628096 - 2048 - Type - - - 6 - System - headerColor - - - - - - 337772096 - 2048 - Text Cell - - LucidaGrande - 11 - 16 - - - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 17 - -759169024 - - - 1 - 2 - 15 - 0 - YES - 0 - - - {{1, 17}, {562, 233}} - - - - - 4 - - - - -2147483392 - {{548, 17}, {15, 194}} - - - - _doScroller: - 0.9282296895980835 - - - - -2147483392 - {{1, 211}, {562, 15}} - - - 1 - - _doScroller: - 0.99822378158569336 - - - - 2304 - - YES - - - {{1, 0}, {562, 17}} - - - - - 4 - - - - {{0, 24}, {564, 251}} - - - 562 - - - - - - QSAAAEEgAABBmAAAQZgAAA - - - - 268 - {{529, -8}, {46, 46}} - - - - - {564, 345} - - - - 256 - - YES - - - 268 - {{478, 15}, {46, 46}} - - - - {564, 402} - - - - 256 - - YES - - - 266 - - YES - - - 268 - {{17, 10}, {41, 14}} - - - YES - - 68288064 - 272761856 - Query - - - - - - - - - 265 - {{426, 155}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Insert - - - -2034482945 - 163 - - NSImage - runmenu - - - - 400 - 75 - - - - - 4370 - - YES - - - 2304 - - YES - - - 2322 - {479, 108} - - - - - - - - - - - - YES - - - 134 - - - - 479 - 1 - - - 12263 - 0 - - - - YES - - YES - NSBackgroundColor - NSColor - - - YES - - 6 - System - selectedTextBackgroundColor - - - - 6 - System - selectedTextColor - - - - - - - YES - - YES - NSColor - NSCursor - NSUnderline - - - YES - - 1 - MCAwIDEAA - - - {8, -8} - 13 - - - - - - - 6 - {479, 1e+07} - {223, 108} - - - - {{1, 1}, {479, 136}} - - - - - - {4, -5} - 1 - - 4 - - - - -2147483392 - {{465, 1}, {15, 136}} - - - - _doScroller: - 1 - 0.85256409645080566 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - - 1 - - _doScroller: - 1 - 0.94565218687057495 - - - {{63, 10}, {481, 138}} - - - 530 - - - - - - - -2147482359 - - {{402, 162}, {16, 16}} - - - 20746 - 100 - - - {{0, 82}, {564, 186}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 268 - {{17, 41}, {530, 22}} - - - YES - - 68288064 - 138544128 - - - LucidaGrande - 18 - 16 - - Insert Result - - - - - - - - 268 - {{498, -34}, {46, 46}} - - - - - {564, 268} - - - - 256 - - YES - - - 266 - {{0, 183}, {564, 24}} - - - NO - NO - NO - 2 - - - - 266 - - YES - - - 268 - {{17, 8}, {49, 14}} - - - YES - - 68288064 - 272761856 - Fields - - - - - - - - - 266 - - YES - - YES - NSStringPboardType - - - {{62, 5}, {482, 22}} - - - YES - - 341966336 - 131072 - - All Fields - - YES - - - - 0.0 - 0 - - 2 - - - - 265 - {{461, 60}, {83, 25}} - - - YES - - -2080244224 - 134217728 - Import - - - -2034482945 - 163 - - - - 400 - 75 - - - - - 265 - {{432, 38}, {38, 14}} - - - YES - - 68288064 - 272761856 - Type - - - - - - - - - 265 - {{466, 35}, {81, 22}} - - - YES - - -2076049856 - 133120 - - - 109199615 - 129 - - - 400 - 75 - - - JSON - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - CSV - - 1048576 - 2147483647 - - - _popUpItemAction: - 1 - - - - - TSV - - 1048576 - 2147483647 - - - _popUpItemAction: - 3 - - - - - - 1 - YES - YES - 2 - - - - - 268 - {{17, 39}, {38, 14}} - - - YES - - 68288064 - 272761856 - Path - - - - - - - - - 266 - {{62, 35}, {271, 19}} - - - YES - - -1804468671 - 272761856 - - - Export path - - YES - - - - - - - 268 - {{18, 63}, {96, 18}} - - - YES - - 67239424 - 131072 - Ignore Blanks - - - 1211912703 - 2 - - NSImage - NSSwitch - - - NSSwitch - - - - 200 - 25 - - - - - 268 - {{121, 56}, {63, 32}} - - - YES - - 67239424 - 131072 - Drop - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 268 - {{178, 63}, {83, 18}} - - - YES - - 67239424 - 131072 - Headerline - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 268 - {{264, 63}, {83, 18}} - - - YES - - 67239424 - 131072 - jsonArray - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 268 - {{350, 63}, {87, 18}} - - - YES - - 67239424 - 131072 - stopOnError - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 268 - {{341, 37}, {76, 18}} - - YES - - -2080244224 - 134348800 - Choose File - - - -2035007233 - 163 - - - 400 - 75 - - - - {{0, 92}, {564, 91}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 1290 - - {{-2, 72}, {568, 20}} - - - 16392 - 100 - - - - 266 - {{22, 41}, {530, 22}} - - - YES - - 68288064 - 138544128 - - - Import Result - - - - - - - {564, 207} - - - - 256 - - YES - - - 266 - - YES - - - 266 - {{17, 6}, {530, 14}} - - - YES - - 70385217 - 272761856 - - - Query - - - - 1 - MC40MDAwMDAwMDYgMC40MDAwMDAwMDYgMC40MDAwMDAwMDYAA - - - - - - -2147482359 - - {{528, 4}, {16, 16}} - - - 20746 - 100 - - - {{0, 163}, {564, 24}} - - - NO - NO - NO - 2 - - - - 266 - - YES - - - 268 - {{17, 10}, {41, 14}} - - - YES - - 68288064 - 272761856 - Query - - - - - - - - - 266 - {{63, 7}, {481, 19}} - - - YES - - -1804468671 - 272761856 - - - { } - - YES - - - - - - - 268 - {{17, 35}, {38, 14}} - - - YES - - 68288064 - 272761856 - Action - - - - - - - - - 266 - {{63, 32}, {481, 19}} - - - YES - - -1804468671 - 272761856 - - - { } - - YES - - - - - - - 268 - {{17, 63}, {63, 18}} - - - YES - - 67239424 - 131072 - Upset - - - 1210864127 - 2 - - - - - 200 - 25 - - - - - 265 - {{426, 60}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Update - - - -2034482945 - 163 - - - - 400 - 75 - - - - {{0, 73}, {564, 90}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 266 - {{17, 38}, {530, 22}} - - - YES - - 68288064 - 138544128 - - - Update Result - - - - - - - - 268 - {{489, 0}, {46, 46}} - - - - - {564, 187} - - - - 256 - - YES - - - 266 - - YES - - - 282 - - YES - - - 256 - - YES - - - 4370 - - YES - - - 2304 - - YES - - - 2322 - {202, 12} - - - - - - - - - - - - YES - - - 134 - - - - 202 - 1 - - - 12263 - 0 - - - - YES - - YES - NSBackgroundColor - NSColor - - - YES - - - - - - - YES - - YES - NSColor - NSCursor - NSUnderline - - - YES - - - - - - - - 6 - {549, 1e+07} - {175, 0} - - - - {{1, 1}, {202, 127}} - - - - - - 4 - - - - -2147483392 - {{465, 1}, {15, 136}} - - - - _doScroller: - 1 - 0.85256409645080566 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - - 1 - - _doScroller: - 1 - 0.94565218687057495 - - - {{63, 8}, {204, 129}} - - - 530 - - - - - - - 268 - {{17, 123}, {41, 14}} - - - YES - - 68288064 - 272761856 - Map - - - - - - - - {285, 148} - - - NSView - - - - 256 - - YES - - - 274 - - YES - - - 2304 - - YES - - - 2322 - {{0, 4}, {210, 45}} - - - - - - - - - - - - YES - - - 134 - - - - 210 - 1 - - - 12263 - 0 - - - - YES - - YES - NSBackgroundColor - NSColor - - - YES - - - - - - - YES - - YES - NSColor - NSCursor - NSUnderline - - - YES - - - - - - - - 6 - {463, 1e+07} - {161, 45} - - - - {{1, 1}, {210, 128}} - - - - - - 4 - - - - -2147483392 - {{190, 1}, {15, 124}} - - - - _doScroller: - 0.984375 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - - 1 - - _doScroller: - 1 - 0.94565218687057495 - - - {{53, 9}, {212, 130}} - - - 530 - - - - - - - 268 - {{5, 125}, {51, 14}} - - - YES - - 68288064 - 272761856 - Reduce - - - - - - - - {{286, 0}, {278, 148}} - - - NSView - - - {564, 148} - - - YES - 2 - - - - 265 - {{426, 172}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Run - - - -2034482945 - 163 - - - - 400 - 75 - - - - - 268 - {{17, 150}, {42, 14}} - - - YES - - 68288064 - 272761856 - Query - - - - - - - - - 266 - {{63, 146}, {481, 19}} - - - YES - - -1804468671 - 272761856 - - - - YES - - - - - - - 268 - {{17, 175}, {42, 14}} - - - YES - - 68288064 - 272761856 - Output - - - - - - - - - 268 - {{64, 172}, {210, 19}} - - - YES - - -1804468671 - 272761856 - - - - YES - - - - - - - -2147482359 - - {{402, 176}, {16, 16}} - - - 20746 - 100 - - - {{0, 145}, {564, 200}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 274 - - YES - - - 2304 - - YES - - - 256 - {563, 104} - - - YES - - - 256 - {563, 17} - - - - - - - -2147483392 - {{549, 0}, {16, 17}} - - - - - YES - - 150 - 16 - 1000 - - 75628096 - 2048 - Name - - - 3 - MC4zMzMzMzI5ODU2AA - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - - - - 324 - 40 - 1000 - - 75628096 - 2048 - Value - - - - - - 337772096 - 2048 - Text Cell - - LucidaGrande - 12 - 16 - - - - - - 3 - YES - - - - 80 - 80 - 80 - - 75628096 - 2048 - Type - - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 17 - -759169024 - - - 1 - 2 - 15 - 0 - YES - 0 - - - {{1, 17}, {563, 104}} - - - - - 4 - - - - -2147483392 - {{549, 17}, {15, 66}} - - - - _doScroller: - 0.81481480598449707 - - - - -2147483392 - {{1, 83}, {563, 15}} - - - 1 - - _doScroller: - 0.99822694063186646 - - - - 2304 - - YES - - - {{1, 0}, {563, 17}} - - - - - 4 - - - - {{-1, 23}, {565, 122}} - - - 562 - - - - - - QSAAAEEgAABBmAAAQZgAAA - - - {564, 345} - - - - 256 - - YES - - - 266 - - YES - - - 266 - {{17, 6}, {530, 14}} - - - YES - - 70385217 - 272761856 - - - Query - - - - 1 - MC40MDAwMDAwMDYgMC40MDAwMDAwMDYgMC40MDAwMDAwMDYAA - - - - - - -2147482359 - - {{528, 4}, {16, 16}} - - - 20746 - 100 - - - {{0, 145}, {564, 24}} - - - NO - NO - NO - 2 - - - - 266 - - YES - - - 268 - {{17, 10}, {41, 14}} - - - YES - - 68288064 - 272761856 - Query - - - - - - - - - 266 - {{63, 7}, {481, 19}} - - - YES - - -1804468671 - 272761856 - - - { } - - YES - - - - - - - 268 - {{426, 33}, {118, 25}} - - - YES - - -2080244224 - 134217728 - Remove - - - -2034482945 - 163 - - - - 400 - 75 - - - - {{0, 80}, {564, 65}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 268 - {{17, 41}, {530, 22}} - - - YES - - 68288064 - 138544128 - - - Remove Result - - - - - - - - 268 - {{518, 0}, {46, 46}} - - - - - {564, 169} - - - - 256 - {564, 404} - - - - 256 - {564, 345} - - - - 256 - - YES - - - 266 - - YES - - - 266 - {{17, 6}, {530, 14}} - - - YES - - 70385217 - 272761856 - - - Query - - - - 1 - MC40MDAwMDAwMDYgMC40MDAwMDAwMDYgMC40MDAwMDAwMDYAA - - - - - {{0, 173}, {564, 24}} - - - NO - NO - NO - 2 - - - - 266 - - YES - - - 268 - {{17, 7}, {49, 14}} - - - YES - - 68288064 - 272761856 - Query - - - - - - - - - 266 - {{62, 4}, {302, 19}} - - - YES - - -1804468671 - 272761856 - - - Find All - - YES - - - - - - - 268 - {{17, 34}, {49, 14}} - - - YES - - 68288064 - 272761856 - Fields - - - - - - - - - 266 - - YES - - YES - NSStringPboardType - - - {{62, 30}, {302, 22}} - - - YES - - 341966336 - 131072 - - All Fields - - YES - - - - 0.0 - 0 - - 2 - - - - 265 - {{374, 34}, {32, 14}} - - - YES - - 68288064 - 272761856 - Skip - - - - - - - - - 265 - {{407, 31}, {45, 19}} - - - YES - - -1804468671 - 71435264 - - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - YES - - - YES - - - - - 0 - 0 - YES - NO - 1 - AAAAAAAAAAAAAAAAAAAAAA - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - YES - - - - - - - 265 - {{476, 33}, {38, 14}} - - - YES - - 68288064 - 272761856 - Limit - - - - - - - - - 265 - {{510, 31}, {45, 19}} - - - YES - - -1804468671 - 71435264 - - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - YES - - - - - - - 265 - {{468, 56}, {87, 25}} - - - YES - - -2080244224 - 134217728 - Export - - - -2034482945 - 163 - - - - 400 - 75 - - - - - 265 - {{374, 7}, {38, 14}} - - - YES - - 68288064 - 272761856 - Sort - - - - - - - - - 265 - {{407, 4}, {148, 19}} - - - YES - - -1804468671 - 272761856 - - - {"_id":1} - - YES - - - - - - - 265 - {{294, 61}, {38, 14}} - - - YES - - 68288064 - 272761856 - Type - - - - - - - - - 265 - {{325, 58}, {62, 22}} - - - YES - - -2076049856 - 133120 - - - 109199615 - 129 - - - 400 - 75 - - - JSON - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - CSV - - 1048576 - 2147483647 - - - _popUpItemAction: - 1 - - - - - - 1 - YES - YES - 2 - - - - - 268 - {{17, 61}, {38, 14}} - - - YES - - 68288064 - 272761856 - Path - - - - - - - - - 266 - {{62, 57}, {143, 19}} - - - YES - - -1804468671 - 272761856 - - - Export path - - YES - - - - - - - 265 - {{389, 59}, {73, 18}} - - - YES - - 67239424 - 131072 - JsonArray - - - 1211912703 - 2 - - - - - 200 - 25 - - - - - 268 - {{213, 59}, {76, 18}} - - YES - - -2080244224 - 134348800 - Choose File - - - -2035007233 - 163 - - - 400 - 75 - - - - {{0, 90}, {564, 83}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 1290 - - {{-2, 70}, {568, 20}} - - - 16392 - 100 - - - - 266 - {{22, 39}, {530, 22}} - - - YES - - 68288064 - 138544128 - - - Export Result - - - - - - - {564, 197} - - - - - BAtzdHJlYW10eXBlZIHoA4QBQISEhAxOU0RpY3Rpb25hcnkAhIQITlNPYmplY3QAhYQBaQqShISECE5T -U3RyaW5nAZSEASskMEQ1OTUwRDEtRDRBOC00NEM2LTlEQkMtMjUxQ0ZFRjg1MkUyhpKEhIQHTlNWYWx1 -ZQCUhAEqhIQMe19OU1NpemU9ZmZ9moE0AoHXAYaShJaXJENFMEQzODUwLTZGM0ItNDU2RS1CQjY4LTMw -NTQ1NzI5ODI0NYaShJiZmZqBNAKB2QGGkoSWlyQ3M0FBOTZFMC0yMjA0LTQxNzktQjIxNS1GQjlFMTlB -NDc3MDCGkoSYmZmagTQCgQABhpKElpckMEE3RUE2NzgtOEVDQy00RkNGLTgwRTItQUUyNjBBNzQ1RTJG -hpKEmJmZmoE0AoGeAYaShJaXJDEzNzE3NjQ5LTAzQzMtNENBQi05QjczLTk1NTA0NDBDM0E4MIaShJiZ -mZqBNAKBUQGGkoSWlyRGMkM2RjgyMy1CQjA2LTRGMjMtQjlDNy1EMTVENjZFRERCMDSGkoSYmZmagTQC -gQoBhpKElpckQzEzMjA1QUMtOTk3NC00QzVELUJDNUEtRDUyNkY3RTkwRDcyhpKEmJmZmoE0AoHuAIaS -hJaXJEFERTdBRTczLTlEOUYtNDhEMC1BMUY4LUVEMDI4MzYzMTM2MoaShJiZmZqBNAKBngGGkoSWlyQ2 -MDAwOTE2Ri0xRTRFLTRDOUQtQUJGMy1ERTRCNTgyNzNEMUWGkoSYmZmagTQCgRQBhpKElpckRjA1OTIw -NzEtREU1Qi00NTU3LUExMDQtMTIzQ0ZFMTQxQjdFhpKEmJmZmoE0AoGeAYaGA - - CE0D3850-6F3B-456E-BB68-305457298245 - - {564, 414} - NO - - NO - - YES - - - YES - - - - {3.40282e+38, 3.40282e+38} - - - 256 - - YES - - - 266 - - YES - - - 266 - {{17, 6}, {530, 14}} - - - YES - - 70385217 - 272761856 - - - Query - - - - 1 - MC40MDAwMDAwMDYgMC40MDAwMDAwMDYgMC40MDAwMDAwMDYAA - - - - - - -2147482359 - - {{528, 4}, {16, 16}} - - - 20746 - 100 - - - {{0, 380}, {564, 24}} - - - NO - NO - NO - 2 - - - - 266 - - YES - - - 268 - {{17, 7}, {49, 14}} - - - YES - - 68288064 - 272761856 - Query - - - - - - - - - 266 - {{62, 4}, {302, 19}} - - - YES - - -1804468671 - 272761856 - - - Find All - - YES - - - - - - - 268 - {{17, 34}, {49, 14}} - - - YES - - 68288064 - 272761856 - Fields - - - - - - - - - 266 - - YES - - YES - NSStringPboardType - - - {{62, 30}, {207, 22}} - - - YES - - 341966336 - 131072 - - All Fields - - YES - - - - 0.0 - 0 - - 2 - - - - 265 - {{289, 34}, {32, 14}} - - - YES - - 68288064 - 272761856 - Skip - - - - - - - - - 265 - {{319, 31}, {45, 19}} - - - YES - - -1804468671 - 71435264 - - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - YES - - - - - - - 265 - {{374, 33}, {38, 14}} - - - YES - - 68288064 - 272761856 - Limit - - - - - - - - - 265 - {{407, 31}, {45, 19}} - - - YES - - -1804468671 - 71435264 - - - - - YES - - YES - allowsFloats - formatterBehavior - locale - negativeInfinitySymbol - nilSymbol - numberStyle - positiveInfinitySymbol - - - YES - - - - -∞ - - - +∞ - - - #,##0.### - #,##0.### - - - - - - - - NaN - - - - - - 3 - YES - YES - YES - - . - , - YES - NO - YES - - - YES - - - - - - - 265 - {{473, 29}, {82, 25}} - - - YES - - -2080244224 - 134217728 - Run - - - -2034482945 - 163 - - - - 400 - 75 - - - - - 265 - {{374, 7}, {38, 14}} - - - YES - - 68288064 - 272761856 - Sort - - - - - - - - - 265 - {{407, 4}, {148, 19}} - - - YES - - -1804468671 - 272761856 - - - {"_id":1} - - YES - - - - - - {{0, 322}, {564, 58}} - - - - 1 - MC42NzU3Njg0OTQ2IDAuNzIxOTQ4MTQ2OCAwLjc2NTMwNjExNTIAA - - - 1 - MC41MTM3NjcxODI4IDAuNTY4NDkwNTA1MiAwLjYxNzM0Njk0MjQAA - - - 1 - MC42MTk2MDA4MzI1IDAuNjYxMTkxOTk5OSAwLjcxOTM4Nzc2OTcAA - - - 1 - MC41NTc2NjQ2OTI0IDAuNTk4ODkyNTA5OSAwLjY0Mjg1NzEzNDMAA - - - 1 - MC40Mjc4NDM2NjAxIDAuNDc5NDI1MTYyMSAwLjUyMDQwODE1MzUAA - - YES - YES - YES - NO - 0.30000001192092896 - 0.0 - - - - 4370 - - YES - - - 2304 - - YES - - - 256 - {564, 282} - - - YES - - - 256 - {564, 17} - - - - - - - -2147483392 - {{549, 0}, {16, 17}} - - - - - YES - - name - 135 - 16 - 1000 - - 75628096 - 2048 - Name - - - 3 - MC4zMzMzMzI5ODU2AA - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - - - - value - 320 - 40 - 1000 - - 75628096 - 2048 - Value - - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - - - - type - 100 - 100 - 100 - - 75628096 - 2048 - Type - - - - - - 337772096 - 2048 - Text Cell - - - - - - 3 - YES - - - - 3 - 2 - - - 17 - -759169024 - - - 1 - 2 - 15 - 0 - YES - 0 - - - {{0, 17}, {564, 282}} - - - - - 4 - - - - -2147483392 - {{549, 17}, {15, 267}} - - - - _doScroller: - 0.94680851697921753 - - - - -2147483392 - {{0, 284}, {564, 15}} - - - 1 - - _doScroller: - 0.99823009967803955 - - - - 2304 - - YES - - - {564, 17} - - - - - 4 - - - - {{0, 24}, {564, 299}} - - - 560 - - - - - - QSAAAEEgAABBmAAAQZgAAA - - - - 292 - {{17, 4}, {193, 14}} - - - YES - - 68288064 - 272761856 - - - Query Results - - - - - - - - 268 - {{526, -12}, {46, 46}} - - - - - - 289 - {{387, 2}, {74, 18}} - - - YES - - 67239424 - 134348800 - Expand - - - -2034482945 - 163 - - NSImage - NSPathTemplate - - - - 400 - 75 - - - - - 289 - {{469, 2}, {75, 18}} - - - YES - - -2080244224 - 134348800 - Collapse - - - -2034482945 - 163 - - - - 400 - 75 - - - - - 268 - {{311, 2}, {68, 18}} - - YES - - -2080244224 - 134348800 - Remove - - - -2034482945 - 163 - - NSImage - NSRemoveTemplate - - - - 400 - 75 - - - - {564, 404} - - - - {{0, 0}, {1680, 1028}} - {3.40282e+38, 3.40282e+38} - - - ResultsOutlineViewController - - - ResultsOutlineViewController - - - ResultsOutlineViewController - - - - - YES - - - window - - - - 3 - - - - delegate - - - - 4 - - - - criticalTextField - - - - 105 - - - - fieldsTextField - - - - 106 - - - - skipTextField - - - - 107 - - - - limitTextField - - - - 108 - - - - findResultsViewController - - - - 113 - - - - myOutlineView - - - - 114 - - - - findQuery: - - - - 115 - - - - dataSource - - - - 118 - - - - delegate - - - - 119 - - - - totalResultsTextField - - - - 120 - - - - sortTextField - - - - 125 - - - - updateCriticalTextField - - - - 150 - - - - updateSetTextField - - - - 151 - - - - upsetCheckBox - - - - 152 - - - - updateQuery: - - - - 154 - - - - insertDataTextView - - - - 205 - - - - insertQuery: - - - - 207 - - - - removeQuery: - - - - 209 - - - - removeCriticalTextField - - - - 211 - - - - indexesOutlineViewController - - - - 259 - - - - myOutlineView - - - - 260 - - - - dataSource - - - - 262 - - - - delegate - - - - 263 - - - - insertResultsTextField - - - - 265 - - - - removeResultsTextField - - - - 267 - - - - updateResultsTextField - - - - 269 - - - - indexTextField - - - - 273 - - - - ensureIndex: - - - - 287 - - - - indexQuery: - - - - 288 - - - - reIndex: - - - - 289 - - - - dropIndex: - - - - 290 - - - - mapFunctionTextView - - - - 344 - - - - reduceFunctionTextView - - - - 345 - - - - mrcriticalTextField - - - - 346 - - - - mroutputTextField - - - - 347 - - - - mrOutlineViewController - - - - 349 - - - - myOutlineView - - - - 350 - - - - dataSource - - - - 351 - - - - delegate - - - - 352 - - - - delegate - - - - 364 - - - - delegate - - - - 365 - - - - delegate - - - - 366 - - - - delegate - - - - 367 - - - - delegate - - - - 368 - - - - findQueryTextField - - - - 369 - - - - updateQueryTextField - - - - 371 - - - - updateQueryComposer: - - - - 372 - - - - delegate - - - - 373 - - - - delegate - - - - 374 - - - - removeQueryTextField - - - - 376 - - - - delegate - - - - 377 - - - - mapReduce: - - - - 384 - - - - findResultsOutlineView - - - - 469 - - - - expandFindResults: - - - - 474 - - - - collapseFindResults: - - - - 477 - - - - findQueryLoaderIndicator - - - - 485 - - - - updateQueryLoaderIndicator - - - - 488 - - - - removeQueryLoaderIndicator - - - - 493 - - - - insertLoaderIndicator - - - - 496 - - - - indexLoaderIndicator - - - - 499 - - - - mrLoaderIndicator - - - - 502 - - - - doubleClickTarget: self - - - - - - doubleClickTarget: self - doubleClickTarget - self - - NSSelectorName - showEditWindow: - - 2 - - - 511 - - - - delegate - - - - 545 - - - - delegate - - - - 546 - - - - delegate - - - - 547 - - - - delegate - - - - 548 - - - - delegate - - - - 549 - - - - expCriticalTextField - - - - 575 - - - - expQueryTextField - - - - 576 - - - - expSortTextField - - - - 577 - - - - expFieldsTextField - - - - 578 - - - - expSkipTextField - - - - 579 - - - - expLimitTextField - - - - 580 - - - - expPathTextField - - - - 581 - - - - expTypePopUpButton - - - - 582 - - - - expProgressIndicator - - - - 583 - - - - expResultsTextField - - - - 584 - - - - export: - - - - 586 - - - - delegate - - - - 639 - - - - impFieldsTextField - - - - 650 - - - - impPathTextField - - - - 651 - - - - impTypePopUpButton - - - - 652 - - - - impIgnoreBlanksCheckBox - - - - 653 - - - - impDropCheckBox - - - - 654 - - - - impHeaderlineCheckBox - - - - 655 - - - - impProgressIndicator - - - - 656 - - - - impResultsTextField - - - - 657 - - - - import: - - - - 658 - - - - expJsonArrayCheckBox - - - - 667 - - - - impStopOnErrorCheckBox - - - - 673 - - - - impJsonArrayCheckBox - - - - 674 - - - - chooseExportPath: - - - - 679 - - - - chooseImportPath: - - - - 684 - - - - enabled: self.myOutlineView.selectedRow - - - - - - enabled: self.myOutlineView.selectedRow - enabled - self.myOutlineView.selectedRow - 2 - - - 692 - - - - removeRecord: - - - - 693 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - YES - - - - - - - - - - - - - - - - - 2 - - - YES - - - - - - - - - - - - - 13 - - - YES - - - - - - - - - - - - - - - - 14 - - - - - 19 - - - - - 20 - - - - - 21 - - - - - 23 - - - - - 24 - - - - - 25 - - - - - 26 - - - - - 64 - - - YES - - - - - - 63 - - - - - 112 - - - findResultsViewController - - - 215 - - - - - 258 - - - indexesOutlineViewController - - - 292 - - - - - 348 - - - mrOutlineViewController - - - 468 - - - - - 508 - - - YES - - - - - - - - 231 - - - YES - - - - - - - - - - - - 498 - - - - - 233 - - - YES - - - - - - 277 - - - YES - - - - - - 279 - - - YES - - - - - - 275 - - - YES - - - - - - 271 - - - YES - - - - - - 234 - - - YES - - - - - - 235 - - - - - 272 - - - - - 276 - - - - - 280 - - - - - 278 - - - - - 236 - - - - - 247 - - - YES - - - - - - - - - 251 - - - - - 250 - - - YES - - - - - - - - 249 - - - - - 248 - - - - - 256 - - - YES - - - - - - 253 - - - YES - - - - - - 252 - - - YES - - - - - - 255 - - - - - 254 - - - - - 257 - - - - - 274 - - - - - 509 - - - YES - - - - - - - 297 - - - YES - - - - - - - - - - - - 501 - - - - - 393 - - - YES - - - - - - - 333 - - - YES - - - - - - 331 - - - YES - - - - - - 321 - - - YES - - - - - - 319 - - - YES - - - - - - 299 - - - YES - - - - - - 302 - - - - - 320 - - - - - 322 - - - - - 332 - - - - - 334 - - - - - 395 - - - YES - - - - - - - 394 - - - YES - - - - - - - 300 - - - YES - - - - - - 298 - - - YES - - - - - - - - 305 - - - - - 304 - - - - - 303 - - - - - 301 - - - - - 315 - - - YES - - - - - - - - 311 - - - YES - - - - - - 312 - - - - - 316 - - - - - 317 - - - - - 318 - - - - - 335 - - - YES - - - - - - - - - 339 - - - - - 338 - - - YES - - - - - - - - 337 - - - - - 336 - - - - - 353 - - - YES - - - - - - 341 - - - YES - - - - - - 340 - - - YES - - - - - - 343 - - - - - 342 - - - - - 354 - - - - - 512 - - - - - 513 - - - - - 570 - - - YES - - - - - - - - - 158 - - - YES - - - - - - - 492 - - - - - 172 - - - YES - - - - - - 173 - - - - - 159 - - - YES - - - - - - - - 160 - - - YES - - - - - - 165 - - - YES - - - - - - 164 - - - YES - - - - - - 167 - - - - - 166 - - - - - 171 - - - - - 179 - - - YES - - - - - - 180 - - - - - 181 - - - - - 590 - - - YES - - - - - - - - 190 - - - YES - - - - - - - - - 495 - - - - - 201 - - - YES - - - - - - - - 193 - - - YES - - - - - - 194 - - - YES - - - - - - 197 - - - - - 198 - - - - - 204 - - - - - 203 - - - - - 202 - - - - - 191 - - - YES - - - - - - 192 - - - - - 381 - - - - - 680 - - - YES - - - - - - - - - 515 - - - YES - - - - - - 542 - - - YES - - - - - - 543 - - - - - 516 - - - YES - - - - - - - - - - - - - - - - - - - - - - 677 - - - YES - - - - - - 665 - - - YES - - - - - - 557 - - - YES - - - - - - 555 - - - YES - - - - - - 565 - - - YES - - - - - - 563 - - - YES - - - - - - 520 - - - YES - - - - - - 522 - - - YES - - - - - - 521 - - - YES - - - - - - 519 - - - YES - - - - - - 523 - - - YES - - - - - - 527 - - - YES - - - - - - 526 - - - YES - - - - - - 525 - - - YES - - - - - - 524 - - - YES - - - - - - 518 - - - YES - - - - - - 517 - - - YES - - - - - - 540 - - - - - 539 - - - - - 531 - - - - - 530 - - - - - 529 - - - - - 528 - - - - - 532 - - - - - 537 - - - YES - - - - - - 538 - - - - - 534 - - - YES - - - - - - 535 - - - - - 533 - - - - - 536 - - - - - 564 - - - - - 566 - - - - - 556 - - - - - 558 - - - YES - - - - - - 559 - - - YES - - - - - - - 561 - - - - - 560 - - - - - 666 - - - - - 678 - - - - - 550 - - - - - 571 - - - YES - - - - - - 572 - - - - - 685 - - - YES - - - - - - - - - 595 - - - - - 596 - - - YES - - - - - - - - - - - - - - - - - - 681 - - - YES - - - - - - 671 - - - YES - - - - - - 669 - - - YES - - - - - - 648 - - - YES - - - - - - 646 - - - YES - - - - - - 644 - - - YES - - - - - - 604 - - - YES - - - - - - 602 - - - YES - - - - - - 603 - - - YES - - - - - - 600 - - - YES - - - - - - 601 - - - YES - - - - - - 609 - - - YES - - - - - - 610 - - - YES - - - - - - 619 - - - - - 620 - - - - - 633 - - - - - 634 - - - - - 628 - - - - - 629 - - - YES - - - - - - 630 - - - YES - - - - - - - - 662 - - - - - 632 - - - - - 631 - - - - - 627 - - - - - 645 - - - - - 647 - - - - - 649 - - - - - 670 - - - - - 672 - - - - - 682 - - - - - 597 - - - - - 598 - - - YES - - - - - - 599 - - - - - 687 - - - YES - - - - - - - - - 134 - - - YES - - - - - - - 487 - - - - - 135 - - - YES - - - - - - 136 - - - - - 137 - - - YES - - - - - - - - - - - 148 - - - YES - - - - - - 146 - - - YES - - - - - - 144 - - - YES - - - - - - 142 - - - YES - - - - - - 140 - - - YES - - - - - - 138 - - - YES - - - - - - 139 - - - - - 141 - - - - - 143 - - - - - 145 - - - - - 147 - - - - - 149 - - - - - 155 - - - YES - - - - - - 156 - - - - - 183 - - - - - 65 - - - YES - - - - - - - 94 - - - YES - - - - - - 484 - - - - - 95 - - - - - 66 - - - YES - - - - - - - - - - - - - - - - 80 - - - YES - - - - - - 81 - - - YES - - - - - - 82 - - - YES - - - - - - 83 - - - YES - - - - - - 77 - - - YES - - - - - - 78 - - - YES - - - - - - 79 - - - YES - - - - - - 103 - - - YES - - - - - - 76 - - - YES - - - - - - 123 - - - YES - - - - - - 121 - - - YES - - - - - - 122 - - - - - 124 - - - - - 92 - - - YES - - - - - - 93 - - - - - 104 - - - - - 88 - - - YES - - - - - - 89 - - - - - 90 - - - - - 91 - - - - - 84 - - - - - 85 - - - - - 86 - - - - - 87 - - - - - 67 - - - YES - - - - - - - - - 68 - - - - - 69 - - - YES - - - - - - - - 70 - - - - - 71 - - - - - 72 - - - YES - - - - - - 73 - - - YES - - - - - - 116 - - - YES - - - - - - 117 - - - - - 74 - - - - - 75 - - - - - 98 - - - YES - - - - - - 99 - - - - - 102 - - - - - 470 - - - YES - - - - - - 471 - - - - - 475 - - - YES - - - - - - 476 - - - - - 689 - - - YES - - - - - - 690 - - - - - - - YES - - YES - 1.IBEditorWindowLastContentRect - 1.IBPluginDependency - 1.IBWindowTemplateEditedContentRect - 1.NSWindowTemplate.visibleAtLaunch - 1.WindowOrigin - 1.editorWindowContentRectSynchronizationRect - 102.IBPluginDependency - 103.IBPluginDependency - 104.IBPluginDependency - 112.IBPluginDependency - 121.IBPluginDependency - 122.IBPluginDependency - 123.IBPluginDependency - 124.IBPluginDependency - 13.IBEditorWindowLastContentRect - 13.IBPluginDependency - 134.IBPluginDependency - 135.IBPluginDependency - 136.IBPluginDependency - 137.IBPluginDependency - 138.IBPluginDependency - 139.IBPluginDependency - 140.IBPluginDependency - 141.IBPluginDependency - 142.IBPluginDependency - 143.IBPluginDependency - 144.IBPluginDependency - 145.IBPluginDependency - 146.IBPluginDependency - 147.IBPluginDependency - 148.IBPluginDependency - 149.IBPluginDependency - 155.IBPluginDependency - 156.IBPluginDependency - 158.IBPluginDependency - 159.IBPluginDependency - 160.IBPluginDependency - 164.IBPluginDependency - 165.IBPluginDependency - 166.IBPluginDependency - 167.IBPluginDependency - 171.IBPluginDependency - 172.IBPluginDependency - 173.IBPluginDependency - 179.IBPluginDependency - 179.IBViewBoundsToFrameTransform - 180.IBPluginDependency - 181.IBPluginDependency - 183.IBPluginDependency - 19.IBPluginDependency - 190.IBPluginDependency - 191.IBPluginDependency - 192.IBPluginDependency - 193.IBPluginDependency - 194.IBPluginDependency - 197.IBPluginDependency - 198.IBPluginDependency - 2.IBPluginDependency - 20.IBPluginDependency - 201.IBPluginDependency - 202.IBPluginDependency - 203.IBPluginDependency - 204.IBPluginDependency - 21.IBPluginDependency - 215.IBPluginDependency - 23.IBPluginDependency - 231.IBPluginDependency - 233.IBPluginDependency - 234.IBPluginDependency - 235.IBPluginDependency - 236.IBPluginDependency - 24.IBPluginDependency - 247.IBPluginDependency - 248.IBPluginDependency - 249.IBPluginDependency - 25.IBPluginDependency - 250.IBPluginDependency - 251.IBPluginDependency - 252.IBPluginDependency - 253.IBPluginDependency - 254.IBPluginDependency - 255.IBPluginDependency - 258.IBPluginDependency - 26.IBPluginDependency - 271.IBPluginDependency - 272.IBPluginDependency - 274.IBPluginDependency - 275.IBPluginDependency - 276.IBPluginDependency - 277.IBPluginDependency - 278.IBPluginDependency - 279.IBPluginDependency - 280.IBPluginDependency - 292.IBPluginDependency - 297.IBPluginDependency - 298.IBPluginDependency - 299.IBPluginDependency - 300.IBPluginDependency - 301.IBPluginDependency - 302.IBPluginDependency - 303.IBPluginDependency - 304.IBPluginDependency - 305.IBPluginDependency - 311.IBPluginDependency - 312.IBPluginDependency - 315.IBPluginDependency - 316.IBPluginDependency - 317.IBPluginDependency - 318.IBPluginDependency - 319.IBPluginDependency - 320.IBPluginDependency - 321.IBPluginDependency - 322.IBPluginDependency - 331.IBPluginDependency - 332.IBPluginDependency - 333.IBPluginDependency - 334.IBPluginDependency - 335.IBPluginDependency - 336.IBPluginDependency - 337.IBPluginDependency - 338.IBPluginDependency - 339.IBPluginDependency - 340.IBPluginDependency - 341.IBPluginDependency - 342.IBPluginDependency - 343.IBPluginDependency - 348.IBPluginDependency - 381.IBPluginDependency - 393.IBPluginDependency - 394.IBPluginDependency - 395.IBPluginDependency - 470.IBPluginDependency - 471.IBPluginDependency - 475.IBPluginDependency - 476.IBPluginDependency - 484.IBPluginDependency - 487.IBPluginDependency - 492.IBPluginDependency - 495.IBPluginDependency - 498.IBPluginDependency - 501.IBPluginDependency - 512.IBPluginDependency - 513.IBPluginDependency - 515.IBPluginDependency - 515.IBViewBoundsToFrameTransform - 516.IBPluginDependency - 516.IBViewBoundsToFrameTransform - 517.IBPluginDependency - 518.IBPluginDependency - 519.IBPluginDependency - 519.IBViewBoundsToFrameTransform - 520.IBPluginDependency - 520.IBViewBoundsToFrameTransform - 521.IBPluginDependency - 521.IBViewBoundsToFrameTransform - 522.IBPluginDependency - 522.IBViewBoundsToFrameTransform - 523.IBPluginDependency - 523.IBViewBoundsToFrameTransform - 524.IBPluginDependency - 525.IBPluginDependency - 526.IBPluginDependency - 527.IBPluginDependency - 528.IBPluginDependency - 529.IBPluginDependency - 530.IBPluginDependency - 531.IBPluginDependency - 532.IBPluginDependency - 533.IBPluginDependency - 534.IBPluginDependency - 535.IBNumberFormatterBehaviorMetadataKey - 535.IBNumberFormatterLocalizesFormatMetadataKey - 535.IBPluginDependency - 536.IBPluginDependency - 537.IBPluginDependency - 538.IBNumberFormatterBehaviorMetadataKey - 538.IBNumberFormatterLocalizesFormatMetadataKey - 538.IBPluginDependency - 539.IBPluginDependency - 540.IBPluginDependency - 542.IBPluginDependency - 543.IBPluginDependency - 550.IBPluginDependency - 550.IBViewBoundsToFrameTransform - 555.IBPluginDependency - 555.IBViewBoundsToFrameTransform - 556.IBPluginDependency - 557.IBPluginDependency - 557.IBViewBoundsToFrameTransform - 558.IBPluginDependency - 559.IBEditorWindowLastContentRect - 559.IBPluginDependency - 560.IBPluginDependency - 561.IBPluginDependency - 563.IBPluginDependency - 563.IBViewBoundsToFrameTransform - 564.IBPluginDependency - 565.IBPluginDependency - 566.IBPluginDependency - 571.IBPluginDependency - 571.IBViewBoundsToFrameTransform - 572.IBPluginDependency - 595.IBPluginDependency - 595.IBViewBoundsToFrameTransform - 596.IBPluginDependency - 596.IBViewBoundsToFrameTransform - 597.IBPluginDependency - 597.IBViewBoundsToFrameTransform - 598.IBPluginDependency - 598.IBViewBoundsToFrameTransform - 599.IBPluginDependency - 600.IBPluginDependency - 600.IBViewBoundsToFrameTransform - 601.IBPluginDependency - 601.IBViewBoundsToFrameTransform - 602.IBPluginDependency - 602.IBViewBoundsToFrameTransform - 603.IBPluginDependency - 603.IBViewBoundsToFrameTransform - 604.IBPluginDependency - 604.IBViewBoundsToFrameTransform - 609.IBPluginDependency - 609.IBViewBoundsToFrameTransform - 610.IBPluginDependency - 610.IBViewBoundsToFrameTransform - 619.IBPluginDependency - 620.IBPluginDependency - 627.IBPluginDependency - 628.IBPluginDependency - 629.IBPluginDependency - 63.IBPluginDependency - 630.IBEditorWindowLastContentRect - 630.IBPluginDependency - 631.IBPluginDependency - 632.IBPluginDependency - 633.IBPluginDependency - 634.IBPluginDependency - 644.IBPluginDependency - 644.IBViewBoundsToFrameTransform - 645.IBPluginDependency - 646.IBPluginDependency - 646.IBViewBoundsToFrameTransform - 647.IBPluginDependency - 648.IBPluginDependency - 648.IBViewBoundsToFrameTransform - 649.IBPluginDependency - 65.IBPluginDependency - 65.IBViewBoundsToFrameTransform - 66.IBPluginDependency - 66.IBViewBoundsToFrameTransform - 662.IBPluginDependency - 665.IBPluginDependency - 665.IBViewBoundsToFrameTransform - 666.IBPluginDependency - 669.IBPluginDependency - 669.IBViewBoundsToFrameTransform - 67.IBPluginDependency - 670.IBPluginDependency - 671.IBPluginDependency - 671.IBViewBoundsToFrameTransform - 672.IBPluginDependency - 677.IBPluginDependency - 677.IBViewBoundsToFrameTransform - 678.IBPluginDependency - 68.IBPluginDependency - 681.IBPluginDependency - 681.IBViewBoundsToFrameTransform - 682.IBPluginDependency - 689.IBPluginDependency - 69.IBPluginDependency - 690.IBPluginDependency - 70.IBPluginDependency - 71.IBPluginDependency - 72.IBPluginDependency - 73.IBPluginDependency - 74.IBPluginDependency - 75.IBPluginDependency - 76.IBPluginDependency - 77.IBPluginDependency - 78.IBPluginDependency - 79.IBPluginDependency - 80.IBPluginDependency - 81.IBPluginDependency - 82.IBPluginDependency - 83.IBPluginDependency - 84.IBPluginDependency - 85.IBPluginDependency - 86.IBPluginDependency - 87.IBPluginDependency - 88.IBPluginDependency - 89.IBNumberFormatterBehaviorMetadataKey - 89.IBNumberFormatterLocalizesFormatMetadataKey - 89.IBPluginDependency - 90.IBPluginDependency - 91.IBPluginDependency - 92.IBPluginDependency - 93.IBNumberFormatterBehaviorMetadataKey - 93.IBNumberFormatterLocalizesFormatMetadataKey - 93.IBPluginDependency - 94.IBPluginDependency - 95.IBPluginDependency - 98.IBPluginDependency - 99.IBPluginDependency - - - YES - {{96, 86}, {564, 404}} - com.apple.InterfaceBuilder.CocoaPlugin - {{96, 86}, {564, 404}} - - {196, 240} - {{202, 428}, {480, 270}} - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{76, 693}, {616, 0}} - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - P4AAAL+AAABBiAAAwnQAAA - - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - AQAAAABDLQAAA - - com.brandonwalkin.BWToolkit - - P4AAAL+AAAAAAAAAwysAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDygAAwkAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABD5oAAwpYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABD94AAwkAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABD5wAAwjQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkIAAwjgAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAADAAAAAwrAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkwAAwpIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDpwAAwpwAAA - - com.apple.InterfaceBuilder.CocoaPlugin - {{465, 574}, {86, 37}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwo4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - P4AAAL+AAABBsAAAwmwAAA - - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - - AUJkAABDqoAAA - - com.brandonwalkin.BWToolkit - - P4AAAL+AAABCZAAAw6mAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAADAAAAAw2wAAA - - com.brandonwalkin.BWToolkit - - P4AAAL+AAABBsAAAw08AAA - - com.brandonwalkin.BWToolkit - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCeAAAwpQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwpIAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDuwAAwmAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDqgAAwkwAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABD5oAAwp4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCeAAAwkgAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBiAAAwjgAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - {{557, 580}, {86, 54}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBkAAAwqYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDAgAAwqwAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDOwAAwp4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - - AQAAAABDvgAAA - - com.brandonwalkin.BWToolkit - - P4AAAL+AAAAAAAAAw70AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDxwAAwpYAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDkYAAwp4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDvQAAwp4AAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - AUNVAABCbAAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDqoAAwlQAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.brandonwalkin.BWToolkit - com.brandonwalkin.BWToolkit - - - - YES - - - YES - - - - - YES - - - YES - - - - 693 - - - - YES - - NSObject - - IBProjectSource - Tunnel.h - - - - NSProgressIndicator - - IBProjectSource - NSProgressIndicator+Extras.h - - - - QueryWindowController - NSWindowController - - YES - - YES - chooseExportPath: - chooseImportPath: - collapseFindResults: - dropIndex: - ensureIndex: - expandFindResults: - export: - exportQueryComposer: - findQuery: - findQueryComposer: - import: - indexQuery: - insertQuery: - jsonWindowWillClose: - mapReduce: - reIndex: - removeQuery: - removeQueryComposer: - removeRecord: - showEditWindow: - updateQuery: - updateQueryComposer: - - - YES - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - - - - YES - - YES - chooseExportPath: - chooseImportPath: - collapseFindResults: - dropIndex: - ensureIndex: - expandFindResults: - export: - exportQueryComposer: - findQuery: - findQueryComposer: - import: - indexQuery: - insertQuery: - jsonWindowWillClose: - mapReduce: - reIndex: - removeQuery: - removeQueryComposer: - removeRecord: - showEditWindow: - updateQuery: - updateQueryComposer: - - - YES - - chooseExportPath: - id - - - chooseImportPath: - id - - - collapseFindResults: - id - - - dropIndex: - id - - - ensureIndex: - id - - - expandFindResults: - id - - - export: - id - - - exportQueryComposer: - id - - - findQuery: - id - - - findQueryComposer: - id - - - import: - id - - - indexQuery: - id - - - insertQuery: - id - - - jsonWindowWillClose: - id - - - mapReduce: - id - - - reIndex: - id - - - removeQuery: - id - - - removeQueryComposer: - id - - - removeRecord: - id - - - showEditWindow: - id - - - updateQuery: - id - - - updateQueryComposer: - id - - - - - YES - - YES - criticalTextField - expCriticalTextField - expFieldsTextField - expJsonArrayCheckBox - expLimitTextField - expPathTextField - expProgressIndicator - expQueryTextField - expResultsTextField - expSkipTextField - expSortTextField - expTypePopUpButton - fieldsTextField - findQueryLoaderIndicator - findQueryTextField - findResultsOutlineView - findResultsViewController - impDropCheckBox - impFieldsTextField - impHeaderlineCheckBox - impIgnoreBlanksCheckBox - impJsonArrayCheckBox - impPathTextField - impProgressIndicator - impResultsTextField - impStopOnErrorCheckBox - impTypePopUpButton - indexLoaderIndicator - indexTextField - indexesOutlineViewController - insertDataTextView - insertLoaderIndicator - insertResultsTextField - limitTextField - mapFunctionTextView - mrLoaderIndicator - mrOutlineViewController - mrcriticalTextField - mroutputTextField - reduceFunctionTextView - removeCriticalTextField - removeQueryLoaderIndicator - removeQueryTextField - removeResultsTextField - skipTextField - sortTextField - totalResultsTextField - updateCriticalTextField - updateQueryLoaderIndicator - updateQueryTextField - updateResultsTextField - updateSetTextField - upsetCheckBox - - - YES - NSTextField - NSTextField - NSTokenField - NSButton - NSTextField - NSTextField - NSProgressIndicator - NSTextField - BWInsetTextField - NSTextField - NSTextField - NSPopUpButton - NSTokenField - NSProgressIndicator - NSTextField - NSOutlineView - ResultsOutlineViewController - NSButton - NSTokenField - NSButton - NSButton - NSButton - NSTextField - NSProgressIndicator - BWInsetTextField - NSButton - NSPopUpButton - NSProgressIndicator - NSTextField - ResultsOutlineViewController - NSTextView - NSProgressIndicator - BWInsetTextField - NSTextField - NSTextView - NSProgressIndicator - ResultsOutlineViewController - NSTextField - NSTextField - NSTextView - NSTextField - NSProgressIndicator - NSTextField - BWInsetTextField - NSTextField - NSTextField - BWInsetTextField - NSTextField - NSProgressIndicator - NSTextField - BWInsetTextField - NSTextField - NSButton - - - - YES - - YES - criticalTextField - expCriticalTextField - expFieldsTextField - expJsonArrayCheckBox - expLimitTextField - expPathTextField - expProgressIndicator - expQueryTextField - expResultsTextField - expSkipTextField - expSortTextField - expTypePopUpButton - fieldsTextField - findQueryLoaderIndicator - findQueryTextField - findResultsOutlineView - findResultsViewController - impDropCheckBox - impFieldsTextField - impHeaderlineCheckBox - impIgnoreBlanksCheckBox - impJsonArrayCheckBox - impPathTextField - impProgressIndicator - impResultsTextField - impStopOnErrorCheckBox - impTypePopUpButton - indexLoaderIndicator - indexTextField - indexesOutlineViewController - insertDataTextView - insertLoaderIndicator - insertResultsTextField - limitTextField - mapFunctionTextView - mrLoaderIndicator - mrOutlineViewController - mrcriticalTextField - mroutputTextField - reduceFunctionTextView - removeCriticalTextField - removeQueryLoaderIndicator - removeQueryTextField - removeResultsTextField - skipTextField - sortTextField - totalResultsTextField - updateCriticalTextField - updateQueryLoaderIndicator - updateQueryTextField - updateResultsTextField - updateSetTextField - upsetCheckBox - - - YES - - criticalTextField - NSTextField - - - expCriticalTextField - NSTextField - - - expFieldsTextField - NSTokenField - - - expJsonArrayCheckBox - NSButton - - - expLimitTextField - NSTextField - - - expPathTextField - NSTextField - - - expProgressIndicator - NSProgressIndicator - - - expQueryTextField - NSTextField - - - expResultsTextField - BWInsetTextField - - - expSkipTextField - NSTextField - - - expSortTextField - NSTextField - - - expTypePopUpButton - NSPopUpButton - - - fieldsTextField - NSTokenField - - - findQueryLoaderIndicator - NSProgressIndicator - - - findQueryTextField - NSTextField - - - findResultsOutlineView - NSOutlineView - - - findResultsViewController - ResultsOutlineViewController - - - impDropCheckBox - NSButton - - - impFieldsTextField - NSTokenField - - - impHeaderlineCheckBox - NSButton - - - impIgnoreBlanksCheckBox - NSButton - - - impJsonArrayCheckBox - NSButton - - - impPathTextField - NSTextField - - - impProgressIndicator - NSProgressIndicator - - - impResultsTextField - BWInsetTextField - - - impStopOnErrorCheckBox - NSButton - - - impTypePopUpButton - NSPopUpButton - - - indexLoaderIndicator - NSProgressIndicator - - - indexTextField - NSTextField - - - indexesOutlineViewController - ResultsOutlineViewController - - - insertDataTextView - NSTextView - - - insertLoaderIndicator - NSProgressIndicator - - - insertResultsTextField - BWInsetTextField - - - limitTextField - NSTextField - - - mapFunctionTextView - NSTextView - - - mrLoaderIndicator - NSProgressIndicator - - - mrOutlineViewController - ResultsOutlineViewController - - - mrcriticalTextField - NSTextField - - - mroutputTextField - NSTextField - - - reduceFunctionTextView - NSTextView - - - removeCriticalTextField - NSTextField - - - removeQueryLoaderIndicator - NSProgressIndicator - - - removeQueryTextField - NSTextField - - - removeResultsTextField - BWInsetTextField - - - skipTextField - NSTextField - - - sortTextField - NSTextField - - - totalResultsTextField - BWInsetTextField - - - updateCriticalTextField - NSTextField - - - updateQueryLoaderIndicator - NSProgressIndicator - - - updateQueryTextField - NSTextField - - - updateResultsTextField - BWInsetTextField - - - updateSetTextField - NSTextField - - - upsetCheckBox - NSButton - - - - - IBProjectSource - QueryWindowController.h - - - - ResultsOutlineViewController - NSObject - - myOutlineView - NSOutlineView - - - myOutlineView - - myOutlineView - NSOutlineView - - - - IBProjectSource - ResultsOutlineViewController.h - - - - - YES - - BWAnchoredButtonBar - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWAnchoredButtonBar.h - - - - BWGradientBox - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWGradientBox.h - - - - BWInsetTextField - NSTextField - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWInsetTextField.h - - - - BWSelectableToolbar - NSToolbar - - IBFrameworkSource - BWToolkitFramework.framework/Headers/BWSelectableToolbar.h - - - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSApplication - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSApplication+BWAdditions.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSNumberFormatter - NSFormatter - - IBFrameworkSource - Foundation.framework/Headers/NSNumberFormatter.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - MCPKit_bundled.framework/Headers/MCPNull.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSObject - - IBFrameworkSource - RegexKit.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUAppcast.h - - - - NSObject - - IBFrameworkSource - Sparkle.framework/Headers/SUUpdater.h - - - - NSOutlineView - NSTableView - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSProgressIndicator - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSProgressIndicator.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSScrollView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSScrollView.h - - - - NSScroller - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSScroller.h - - - - NSSplitView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSSplitView.h - - - - NSTableColumn - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableColumn.h - - - - NSTableHeaderView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSTableHeaderView.h - - - - NSTableView - NSControl - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - - - NSTokenField - NSTextField - - IBFrameworkSource - AppKit.framework/Headers/NSTokenField.h - - - - NSTokenFieldCell - NSTextFieldCell - - IBFrameworkSource - AppKit.framework/Headers/NSTokenFieldCell.h - - - - NSToolbar - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbar.h - - - - NSToolbarItem - NSObject - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSView - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSView+BWAdditions.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindow - - IBFrameworkSource - BWToolkitFramework.framework/Headers/NSWindow+BWAdditions.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - MongoHub.xcodeproj - 3 - - YES - - YES - NSAddTemplate - NSListViewTemplate - NSMenuCheckmark - NSMenuMixedState - NSPathTemplate - NSRefreshTemplate - NSRemoveTemplate - NSStopProgressTemplate - NSSwitch - exportmenu - findmenu - importmenu - indexmenu - insertmenu - mapreducemenu - removemenu - runmenu - updatemenu - - - YES - {8, 8} - {11, 10} - {9, 8} - {7, 2} - {16, 9} - {10, 12} - {8, 8} - {11, 11} - {15, 15} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - {32, 32} - - - - diff --git a/QueryWindowController.h b/QueryWindowController.h deleted file mode 100644 index 3c65d4e4..00000000 --- a/QueryWindowController.h +++ /dev/null @@ -1,193 +0,0 @@ -// -// QueryWindowController.h -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import -#import -#import -@class DatabasesArrayController; -@class ResultsOutlineViewController; -@class Connection; -@class MongoDB; - -@interface QueryWindowController : NSWindowController { - NSManagedObjectContext *managedObjectContext; - DatabasesArrayController *databasesArrayController; - IBOutlet ResultsOutlineViewController *findResultsViewController; - IBOutlet NSOutlineView *findResultsOutlineView; - MongoDB *mongoDB; - NSString *dbname; - NSString *collectionname; - Connection *conn; - - IBOutlet NSTextField *criticalTextField; - IBOutlet NSTokenField *fieldsTextField; - IBOutlet NSTextField *skipTextField; - IBOutlet NSTextField *limitTextField; - IBOutlet NSTextField *sortTextField; - IBOutlet BWInsetTextField *totalResultsTextField; - IBOutlet NSTextField *findQueryTextField; - IBOutlet NSProgressIndicator *findQueryLoaderIndicator; - - IBOutlet NSTextField *updateCriticalTextField; - IBOutlet NSTextField *updateSetTextField; - IBOutlet NSButton *upsetCheckBox; - IBOutlet BWInsetTextField *updateResultsTextField; - IBOutlet NSTextField *updateQueryTextField; - IBOutlet NSProgressIndicator *updateQueryLoaderIndicator; - - IBOutlet NSTextField *removeCriticalTextField; - IBOutlet BWInsetTextField *removeResultsTextField; - IBOutlet NSTextField *removeQueryTextField; - IBOutlet NSProgressIndicator *removeQueryLoaderIndicator; - - IBOutlet NSTextView *insertDataTextView; - IBOutlet BWInsetTextField *insertResultsTextField; - IBOutlet NSProgressIndicator *insertLoaderIndicator; - - IBOutlet NSTextField *indexTextField; - IBOutlet ResultsOutlineViewController *indexesOutlineViewController; - IBOutlet NSProgressIndicator *indexLoaderIndicator; - - IBOutlet NSTextView *mapFunctionTextView; - IBOutlet NSTextView *reduceFunctionTextView; - IBOutlet NSTextField *mrcriticalTextField; - IBOutlet NSTextField *mroutputTextField; - IBOutlet NSProgressIndicator *mrLoaderIndicator; - IBOutlet ResultsOutlineViewController *mrOutlineViewController; - - IBOutlet NSTextField *expCriticalTextField; - IBOutlet NSTokenField *expFieldsTextField; - IBOutlet NSTextField *expSkipTextField; - IBOutlet NSTextField *expLimitTextField; - IBOutlet NSTextField *expSortTextField; - IBOutlet BWInsetTextField *expResultsTextField; - IBOutlet NSTextField *expPathTextField; - IBOutlet NSPopUpButton *expTypePopUpButton; - IBOutlet NSTextField *expQueryTextField; - IBOutlet NSButton *expJsonArrayCheckBox; - IBOutlet NSProgressIndicator *expProgressIndicator; - - IBOutlet NSButton *impIgnoreBlanksCheckBox; - IBOutlet NSButton *impDropCheckBox; - IBOutlet NSButton *impHeaderlineCheckBox; - IBOutlet NSTokenField *impFieldsTextField; - IBOutlet BWInsetTextField *impResultsTextField; - IBOutlet NSTextField *impPathTextField; - IBOutlet NSPopUpButton *impTypePopUpButton; - IBOutlet NSButton *impJsonArrayCheckBox; - IBOutlet NSButton *impStopOnErrorCheckBox; - IBOutlet NSProgressIndicator *impProgressIndicator; -} - -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, retain) DatabasesArrayController *databasesArrayController; -@property (nonatomic, retain) ResultsOutlineViewController *findResultsViewController; -@property (nonatomic, retain) MongoDB *mongoDB; -@property (nonatomic, retain) NSString *dbname; -@property (nonatomic, retain) NSString *collectionname; -@property (nonatomic, retain) Connection *conn; - -@property (nonatomic, retain) NSTextField *criticalTextField; -@property (nonatomic, retain) NSTokenField *fieldsTextField; -@property (nonatomic, retain) NSTextField *skipTextField; -@property (nonatomic, retain) NSTextField *limitTextField; -@property (nonatomic, retain) NSTextField *sortTextField; -@property (nonatomic, retain) BWInsetTextField *totalResultsTextField; -@property (nonatomic, retain) NSTextField *findQueryTextField; -@property (nonatomic, retain) NSOutlineView *findResultsOutlineView; -@property (nonatomic, retain) NSProgressIndicator *findQueryLoaderIndicator; - -@property (nonatomic, retain) NSTextField *updateCriticalTextField; -@property (nonatomic, retain) NSTextField *updateSetTextField; -@property (nonatomic, retain) NSButton *upsetCheckBox; -@property (nonatomic, retain) BWInsetTextField *updateResultsTextField; -@property (nonatomic, retain) NSTextField *updateQueryTextField; -@property (nonatomic, retain) NSProgressIndicator *updateQueryLoaderIndicator; - -@property (nonatomic, retain) NSTextField *removeCriticalTextField; -@property (nonatomic, retain) BWInsetTextField *removeResultsTextField; -@property (nonatomic, retain) NSTextField *removeQueryTextField; -@property (nonatomic, retain) NSProgressIndicator *removeQueryLoaderIndicator; - -@property (nonatomic, retain) NSTextView *insertDataTextView; -@property (nonatomic, retain) BWInsetTextField *insertResultsTextField; -@property (nonatomic, retain) NSProgressIndicator *insertLoaderIndicator; - -@property (nonatomic, retain) NSTextField *indexTextField; -@property (nonatomic, retain) ResultsOutlineViewController *indexesOutlineViewController; -@property (nonatomic, retain) NSProgressIndicator *indexLoaderIndicator; - -@property (nonatomic, retain) NSTextView *mapFunctionTextView; -@property (nonatomic, retain) NSTextView *reduceFunctionTextView; -@property (nonatomic, retain) NSTextField *mrcriticalTextField; -@property (nonatomic, retain) NSTextField *mroutputTextField; -@property (nonatomic, retain) ResultsOutlineViewController *mrOutlineViewController; -@property (nonatomic, retain) NSProgressIndicator *mrLoaderIndicator; - -@property (nonatomic, retain) NSTextField *expCriticalTextField; -@property (nonatomic, retain) NSTokenField *expFieldsTextField; -@property (nonatomic, retain) NSTextField *expSkipTextField; -@property (nonatomic, retain) NSTextField *expLimitTextField; -@property (nonatomic, retain) NSTextField *expSortTextField; -@property (nonatomic, retain) BWInsetTextField *expResultsTextField; -@property (nonatomic, retain) NSTextField *expPathTextField; -@property (nonatomic, retain) NSPopUpButton *expTypePopUpButton; -@property (nonatomic, retain) NSTextField *expQueryTextField; -@property (nonatomic, retain) NSButton *expJsonArrayCheckBox; -@property (nonatomic, retain) NSProgressIndicator *expProgressIndicator; - -@property (nonatomic, retain) NSButton *impIgnoreBlanksCheckBox; -@property (nonatomic, retain) NSButton *impDropCheckBox; -@property (nonatomic, retain) NSButton *impHeaderlineCheckBox; -@property (nonatomic, retain) NSTokenField *impFieldsTextField; -@property (nonatomic, retain) BWInsetTextField *impResultsTextField; -@property (nonatomic, retain) NSTextField *impPathTextField; -@property (nonatomic, retain) NSPopUpButton *impTypePopUpButton; -@property (nonatomic, retain) NSButton *impJsonArrayCheckBox; -@property (nonatomic, retain) NSButton *impStopOnErrorCheckBox; -@property (nonatomic, retain) NSProgressIndicator *impProgressIndicator; - -- (IBAction)findQuery:(id)sender; -- (void)doFindQuery; -- (IBAction)expandFindResults:(id)sender; -- (IBAction)collapseFindResults:(id)sender; -- (IBAction)updateQuery:(id)sender; -- (void)doUpdateQuery; -- (IBAction)removeQuery:(id)sender; -- (void)doRemoveQuery; -- (IBAction)insertQuery:(id)sender; -- (void)doInsertQuery; -- (IBAction)indexQuery:(id)sender; -- (void)doIndexQuery; -- (IBAction)ensureIndex:(id)sender; -- (void)doEnsureIndex; -- (IBAction)reIndex:(id)sender; -- (void)doReIndex; -- (IBAction)dropIndex:(id)sender; -- (void)doDropIndex; -- (IBAction) mapReduce:(id)sender; -- (void)doMapReduce; -- (IBAction) export:(id)sender; -- (void)doExport; -- (IBAction) import:(id)sender; -- (void)doImport; -- (IBAction)removeRecord:(id)sender; -- (void)doRemoveRecord; - -- (IBAction)findQueryComposer:(id)sender; -- (IBAction)updateQueryComposer:(id)sender; -- (IBAction)removeQueryComposer:(id)sender; -- (IBAction) exportQueryComposer:(id)sender; - -- (void)showEditWindow:(id)sender; -- (void)jsonWindowWillClose:(id)sender; - -- (IBAction)chooseExportPath:(id)sender; -- (IBAction)chooseImportPath:(id)sender; -- (mongo::BSONObj)parseCSVLine:(char *)line type:(int)_type sep:(const char *)_sep headerLine:(bool)_headerLine ignoreBlanks:(bool)_ignoreBlanks fields:(std::vector &)_fields; -@end diff --git a/QueryWindowController.mm b/QueryWindowController.mm deleted file mode 100644 index 1a861632..00000000 --- a/QueryWindowController.mm +++ /dev/null @@ -1,1109 +0,0 @@ -// -// QueryWindowController.m -// MongoHub -// -// Created by Syd on 10-4-28. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "Configure.h" -#import "NSProgressIndicator+Extras.h" -#import "QueryWindowController.h" -#import "DatabasesArrayController.h" -#import "ResultsOutlineViewController.h" -#import "Connection.h" -#import "MongoDB.h" -#import -#import "NSString+Extras.h" -#import "JsonWindowController.h" -#include -#include -#include - -@implementation QueryWindowController - -@synthesize managedObjectContext; -@synthesize databasesArrayController; -@synthesize findResultsViewController; -@synthesize mongoDB; -@synthesize conn; -@synthesize dbname; -@synthesize collectionname; - -@synthesize criticalTextField; -@synthesize fieldsTextField; -@synthesize skipTextField; -@synthesize limitTextField; -@synthesize sortTextField; -@synthesize totalResultsTextField; -@synthesize findQueryTextField; -@synthesize findResultsOutlineView; -@synthesize findQueryLoaderIndicator; - -@synthesize updateCriticalTextField; -@synthesize updateSetTextField; -@synthesize upsetCheckBox; -@synthesize updateResultsTextField; -@synthesize updateQueryTextField; -@synthesize updateQueryLoaderIndicator; - -@synthesize removeCriticalTextField; -@synthesize removeResultsTextField; -@synthesize removeQueryTextField; -@synthesize removeQueryLoaderIndicator; - -@synthesize insertDataTextView; -@synthesize insertResultsTextField; -@synthesize insertLoaderIndicator; - -@synthesize indexTextField; -@synthesize indexesOutlineViewController; -@synthesize indexLoaderIndicator; - -@synthesize mapFunctionTextView; -@synthesize reduceFunctionTextView; -@synthesize mrcriticalTextField; -@synthesize mroutputTextField; -@synthesize mrOutlineViewController; -@synthesize mrLoaderIndicator; - -@synthesize expCriticalTextField; -@synthesize expFieldsTextField; -@synthesize expSkipTextField; -@synthesize expLimitTextField; -@synthesize expSortTextField; -@synthesize expResultsTextField; -@synthesize expPathTextField; -@synthesize expTypePopUpButton; -@synthesize expQueryTextField; -@synthesize expJsonArrayCheckBox; -@synthesize expProgressIndicator; - -@synthesize impIgnoreBlanksCheckBox; -@synthesize impDropCheckBox; -@synthesize impHeaderlineCheckBox; -@synthesize impFieldsTextField; -@synthesize impResultsTextField; -@synthesize impPathTextField; -@synthesize impTypePopUpButton; -@synthesize impJsonArrayCheckBox; -@synthesize impStopOnErrorCheckBox; -@synthesize impProgressIndicator; - - -- (id)init { - if (![super initWithWindowNibName:@"QueryWindow"]) return nil; - return self; -} - -- (void)dealloc { - [managedObjectContext release]; - [databasesArrayController release]; - [findResultsViewController release]; - [conn release]; - [mongoDB release]; - [dbname release]; - [collectionname release]; - - [criticalTextField release]; - [fieldsTextField release]; - [skipTextField release]; - [limitTextField release]; - [sortTextField release]; - [totalResultsTextField release]; - [findQueryTextField release]; - [findResultsOutlineView release]; - [findQueryLoaderIndicator release]; - - [updateCriticalTextField release]; - [updateSetTextField release]; - [upsetCheckBox release]; - [updateResultsTextField release]; - [updateQueryTextField release]; - [updateQueryLoaderIndicator release]; - - [removeCriticalTextField release]; - [removeResultsTextField release]; - [removeQueryTextField release]; - [removeQueryLoaderIndicator release]; - - [insertDataTextView release]; - [insertResultsTextField release]; - [insertLoaderIndicator release]; - - [indexTextField release]; - [indexesOutlineViewController release]; - [indexLoaderIndicator release]; - - [mapFunctionTextView release]; - [reduceFunctionTextView release]; - [mrcriticalTextField release]; - [mroutputTextField release]; - [mrOutlineViewController release]; - [mrLoaderIndicator release]; - - [expCriticalTextField release]; - [expFieldsTextField release]; - [expSkipTextField release]; - [expLimitTextField release]; - [expSortTextField release]; - [expResultsTextField release]; - [expPathTextField release]; - [expTypePopUpButton release]; - [expQueryTextField release]; - [expJsonArrayCheckBox release]; - [expProgressIndicator release]; - - [impIgnoreBlanksCheckBox release]; - [impDropCheckBox release]; - [impHeaderlineCheckBox release]; - [impFieldsTextField release]; - [impResultsTextField release]; - [impPathTextField release]; - [impTypePopUpButton release]; - [impJsonArrayCheckBox release]; - [impStopOnErrorCheckBox release]; - [impProgressIndicator release]; - - [super dealloc]; -} - -- (void)windowDidLoad { - [super windowDidLoad]; - NSString *title = [[NSString alloc] initWithFormat:@"Query in %@.%@", dbname, collectionname]; - [self.window setTitle:title]; - [title release]; -} - -- (void)windowWillClose:(NSNotification *)notification { - [self release]; -} - -- (IBAction)findQuery:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doFindQuery) toTarget:self withObject:nil]; -} - -- (void)doFindQuery { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSTimeInterval speed = [NSDate timeIntervalSinceReferenceDate]; - [findQueryLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *critical = [criticalTextField stringValue]; - NSString *fields = [fieldsTextField stringValue]; - NSString *sort = [sortTextField stringValue]; - NSNumber *skip = [NSNumber numberWithInt:[skipTextField intValue]]; - NSNumber *limit; - if ([limitTextField intValue] == 0) { - limit = [NSNumber numberWithInt:30]; - }else { - limit = [NSNumber numberWithInt:[limitTextField intValue]]; - } - NSMutableArray *results = [[NSMutableArray alloc] initWithArray:[mongoDB findInDB:dbname - collection:collectionname - user:user - password:password - critical:critical - fields:fields - skip:skip - limit:limit - sort:sort]]; - long long int total = [mongoDB countInDB:dbname - collection:collectionname - user:user - password:password - critical:critical]; - [totalResultsTextField setStringValue:[NSString stringWithFormat:@"Total Results: %d (%0.2fs)", total, [NSDate timeIntervalSinceReferenceDate]-speed]]; - findResultsViewController.results = results; - [findResultsViewController.myOutlineView reloadData]; - [results release]; - [findQueryLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction)expandFindResults:(id)sender -{ - [findResultsOutlineView expandItem:nil expandChildren:YES]; -} - -- (IBAction)collapseFindResults:(id)sender -{ - [findResultsOutlineView collapseItem:nil collapseChildren:YES]; -} - -- (IBAction)updateQuery:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doUpdateQuery) toTarget:self withObject:nil]; -} - -- (void)doUpdateQuery { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [updateQueryLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *critical = [updateCriticalTextField stringValue]; - NSString *fields = [updateSetTextField stringValue]; - NSNumber *upset = [NSNumber numberWithInt:[upsetCheckBox state]]; - int total = [mongoDB countInDB:dbname - collection:collectionname - user:user - password:password - critical:critical]; - [mongoDB updateInDB:dbname - collection:collectionname - user:user - password:password - critical:critical - fields:fields - upset:upset]; - [updateResultsTextField setStringValue:[NSString stringWithFormat:@"Affected Rows: %d", total]]; - [updateQueryLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction)removeQuery:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doRemoveQuery) toTarget:self withObject:nil]; -} - -- (IBAction)doRemoveQuery { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [removeQueryLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *critical = [removeCriticalTextField stringValue]; - int total = [mongoDB countInDB:dbname - collection:collectionname - user:user - password:password - critical:critical]; - [mongoDB removeInDB:dbname - collection:collectionname - user:user - password:password - critical:critical]; - [removeResultsTextField setStringValue:[NSString stringWithFormat:@"Affected Rows: %d", total]]; - [removeQueryLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction) insertQuery:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doInsertQuery) toTarget:self withObject:nil]; -} - -- (void)doInsertQuery { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [insertLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *insertData = [insertDataTextView string]; - [mongoDB insertInDB:dbname - collection:collectionname - user:user - password:password - insertData:insertData]; - [insertResultsTextField setStringValue:@"Completed!"]; - [insertLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction) indexQuery:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doIndexQuery) toTarget:self withObject:nil]; -} - -- (void)doIndexQuery { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [indexLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSMutableArray *results = [[NSMutableArray alloc] initWithArray:[mongoDB indexInDB:dbname - collection:collectionname - user:user - password:password]]; - indexesOutlineViewController.results = results; - [indexesOutlineViewController.myOutlineView reloadData]; - [results release]; - [indexLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction) ensureIndex:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doEnsureIndex) toTarget:self withObject:nil]; -} - -- (void) doEnsureIndex { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [indexLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *indexData = [indexTextField stringValue]; - [mongoDB ensureIndexInDB:dbname - collection:collectionname - user:user - password:password - indexData:indexData]; - [self indexQuery:nil]; - [indexLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - - -- (IBAction) reIndex:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doReIndex) toTarget:self withObject:nil]; -} - -- (void) doReIndex { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [indexLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - [mongoDB reIndexInDB:dbname - collection:collectionname - user:user - password:password]; - [self indexQuery:nil]; - [indexLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - - -- (IBAction) dropIndex:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doDropIndex) toTarget:self withObject:nil]; -} - -- (void) doDropIndex { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [indexLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *indexName = [indexTextField stringValue]; - [mongoDB dropIndexInDB:dbname - collection:collectionname - user:user - password:password - indexName:indexName]; - [self indexQuery:nil]; - [indexLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction) mapReduce:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doMapReduce) toTarget:self withObject:nil]; -} - -- (void)doMapReduce { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [mrLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *mapFunction = [mapFunctionTextView string]; - NSString *reduceFunction = [reduceFunctionTextView string]; - NSString *critical = [mrcriticalTextField stringValue]; - NSString *output = [mroutputTextField stringValue]; - NSMutableArray *results = [[NSMutableArray alloc] initWithArray:[mongoDB mapReduceInDB:dbname - collection:collectionname - user:user - password:password - mapJs:mapFunction - reduceJs:reduceFunction - critical:critical - output:output]]; - mrOutlineViewController.results = results; - [mrOutlineViewController.myOutlineView reloadData]; - [results release]; - [mrLoaderIndicator stop]; - [NSThread exit]; - [pool release]; -} - -- (IBAction) export:(id)sender -{ - if (![[expPathTextField stringValue] isPresent]) { - NSRunAlertPanel(@"Error", @"Please choose export path", @"OK", nil, nil); - return; - } - if (![[expFieldsTextField stringValue] isPresent] && [[expTypePopUpButton selectedItem] tag]==1) - { - NSRunAlertPanel(@"Error", @"You need to specify fields", @"OK", nil, nil); - return; - } - [NSThread detachNewThreadSelector:@selector(doExport) toTarget:self withObject:nil]; -} - -- (void)doExport -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - std::auto_ptr fileStream; - std::ofstream * s = new std::ofstream( [[expPathTextField stringValue] UTF8String] , std::ios_base::out ); - fileStream.reset( s ); - ostream *outPtr = &std::cout; - outPtr = s; - if ( ! s->good() ) { - NSRunAlertPanel(@"Error", [NSString stringWithFormat:@"Couldn't open [%@]", [expPathTextField stringValue]], @"OK", nil, nil); - } - std::ostream &out = *outPtr; - bool _jsonArray = false; - if ([expJsonArrayCheckBox state] == 1) { - _jsonArray = true; - } - unsigned int exportType = [[expTypePopUpButton selectedItem] tag]; - [expResultsTextField setStringValue:@"Start exporting"]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *critical = [expCriticalTextField stringValue]; - NSString *fields = [expFieldsTextField stringValue]; - NSString *sort = [expSortTextField stringValue]; - NSNumber *skip = [NSNumber numberWithInt:[expSkipTextField intValue]]; - NSNumber *limit = [NSNumber numberWithInt:[expLimitTextField intValue]]; - long long int total = [mongoDB countInDB:dbname - collection:collectionname - user:user - password:password - critical:critical]; - if (total == 0) { - [expResultsTextField setStringValue:@"No data to export!"]; - return; - } - - if ( exportType == 1 ) { - out << [fields UTF8String] << std::endl; - }else if (_jsonArray) { - out << '['; - } - - - [expProgressIndicator setUsesThreadedAnimation:YES]; - [expProgressIndicator startAnimation: self]; - [expProgressIndicator setDoubleValue:0]; - std::auto_ptr cursor = [mongoDB findCursorInDB:dbname - collection:collectionname - user:user - password:password - critical:critical - fields:fields - skip:skip - limit:limit - sort:sort]; - unsigned int i = 1; - while( cursor->more() ) - { - mongo::BSONObj obj = cursor->next(); - if ( exportType == 1 ) { - NSArray *keys = [[NSArray alloc] initWithArray:[fields componentsSeparatedByString:@","]]; - unsigned int fieldIndex = 0; - for (NSString *str in keys) { - if (fieldIndex > 0) { - out << ","; - } - const mongo::BSONElement & e = obj.getFieldDotted([str UTF8String]); - if ( ! e.eoo() ) { - out << e.jsonString( mongo::TenGen , false ); - } - fieldIndex ++; - } - [keys release]; - out << std::endl; - }else { - if (_jsonArray && i != 1) - out << ','; - out << obj.jsonString(); - if (!_jsonArray) - { - out << std::endl; - } - } - [expProgressIndicator setDoubleValue:(double)i/total*100]; - i ++; - } - if ( exportType == 1 && _jsonArray) - out << ']' << endl; - [expProgressIndicator stopAnimation: self]; - [expResultsTextField setStringValue:[NSString stringWithFormat:@"Exported %d records.", total]]; - [NSThread exit]; - [pool release]; -} - -- (IBAction) import:(id)sender -{ - if (![[impPathTextField stringValue] isPresent]) { - NSRunAlertPanel(@"Error", @"Please choose import file", @"OK", nil, nil); - return; - } - if (![[expFieldsTextField stringValue] isPresent] && [[expTypePopUpButton selectedItem] tag]==1) - { - NSRunAlertPanel(@"Error", @"You need to specify fields", @"OK", nil, nil); - return; - } - [NSThread detachNewThreadSelector:@selector(doImport) toTarget:self withObject:nil]; -} - -- (void)doImport -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [impProgressIndicator setUsesThreadedAnimation:YES]; - [impProgressIndicator startAnimation: self]; - [impProgressIndicator setDoubleValue:0]; - - long long fileSize = 0; - std::istream * in = &std::cin; - std::ifstream file( [[impPathTextField stringValue] UTF8String] , std::ios_base::in); - in = &file; - fileSize = boost::filesystem::file_size( [[impPathTextField stringValue] UTF8String] ); - bool _ignoreBlanks = false; - bool _headerLine = false; - bool _jsonArray = false; - bool _stopOnError = false; - if ([impHeaderlineCheckBox state] == 1) - { - _headerLine = true; - } - if ([impJsonArrayCheckBox state] == 1) { - _jsonArray = true; - } - if ([impStopOnErrorCheckBox state] == 1) { - _stopOnError = true; - } - unsigned int _type = [[impTypePopUpButton selectedItem] tag]; - std::string _sep; - if (_type == 1) - { - _sep = ","; - }else if(_type == 2){ - _sep = "\t"; - } - std::vector _fields; - if (!_headerLine && [[impFieldsTextField stringValue] isPresent]) - { - - NSArray *keys = [[NSArray alloc] initWithArray:[[impFieldsTextField stringValue] componentsSeparatedByString:@","]]; - for (NSString *str in keys) { - _fields.push_back([str UTF8String]); - } - [keys release]; - } - - if (_type!=0 && !_headerLine && _fields.empty()) - { - NSRunAlertPanel(@"Error", @"Please check headerline", @"OK", nil, nil); - return; - } - - - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - - if ([impDropCheckBox state] == 1) - { - [mongoDB dropCollection:collectionname forDB:dbname user:user password:password]; - } - - if ([impIgnoreBlanksCheckBox state] == 1) - { - _ignoreBlanks = true; - } - - int errors = 0; - int num = 0; - const int BUF_SIZE = 1024 * 1024 * 4; - boost::scoped_array line(new char[BUF_SIZE+2]); - char * buf = line.get(); - while ( _jsonArray || in->rdstate() == 0 ) { - if (_jsonArray) { - if (buf == line.get()) { //first pass - in->read(buf, BUF_SIZE); - if (!(in->rdstate() & std::ios_base::eofbit)) - { - NSRunAlertPanel(@"Error", @"JSONArray file too large", @"OK", nil, nil); - return; - } - buf[ in->gcount() ] = '\0'; - } - }else { - buf = line.get(); - in->getline( buf , BUF_SIZE ); - } - if (!((!(in->rdstate() & std::ios_base::badbit)) && (!(in->rdstate() & std::ios_base::failbit) || (in->rdstate() & std::ios_base::eofbit)))) - { - NSRunAlertPanel(@"Error", @"unknown error reading file", @"OK", nil, nil); - return; - } - - int len = 0; - if (strncmp("\xEF\xBB\xBF", buf, 3) == 0) { // UTF-8 BOM (notepad is stupid) - buf += 3; - len += 3; - } - - if (_jsonArray) { - while (buf[0] != '{' && buf[0] != '\0') { - len++; - buf++; - } - if (buf[0] == '\0') - break; - }else { - while (std::isspace( buf[0] )) { - len++; - buf++; - } - if (buf[0] == '\0') - continue; - len += strlen( buf ); - } - - try { - mongo::BSONObj o; - if (_jsonArray) { - int jslen; - o = mongo::fromjson(buf, &jslen); - len += jslen; - buf += jslen; - }else { - o = [self parseCSVLine:buf type:_type sep:_sep.c_str() headerLine:_headerLine ignoreBlanks:_ignoreBlanks fields:_fields];NSLog(@"%@", [NSString stringWithUTF8String:o.jsonString( mongo::TenGen , false ).c_str()]); - } - if ( _headerLine ) { - _headerLine = false; - }else{ - [mongoDB insertInDB:dbname - collection:collectionname - user:user - password:password - insertData:[NSString stringWithUTF8String:o.jsonString( mongo::TenGen , false ).c_str()] - ]; - } - - num++; - }catch ( std::exception& e ) { - std::cout << "exception:" << e.what() << std::endl; - std::cout << buf << std::endl; - errors++; - - if (_stopOnError || _jsonArray) - break; - } - } - - [impProgressIndicator stopAnimation: self]; - [impResultsTextField setStringValue:[NSString stringWithFormat:@"Imported %d records, %d failed", num, errors]]; - [NSThread exit]; - [pool release]; -} - -- (IBAction)removeRecord:(id)sender -{ - [NSThread detachNewThreadSelector:@selector(doRemoveRecord) toTarget:self withObject:nil]; -} - -- (void)doRemoveRecord -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - if ([findResultsViewController.myOutlineView selectedRow] != -1) - { - id currentItem = [findResultsViewController.myOutlineView itemAtRow:[findResultsViewController.myOutlineView selectedRow]]; - //NSLog(@"%@", [findResultsViewController rootForItem:currentItem]); - [removeQueryLoaderIndicator start]; - NSString *user=nil; - NSString *password=nil; - Database *db = [databasesArrayController dbInfo:conn name:dbname]; - if (db) { - user = db.user; - password = db.password; - } - [db release]; - NSString *critical; - if ([[currentItem objectForKey:@"type"] isEqualToString:@"ObjectId"]) { - critical = [NSString stringWithFormat:@"{_id:ObjectId(\"%@\")}", [currentItem objectForKey:@"value"]]; - }else if ([[currentItem objectForKey:@"type"] isEqualToString:@"String"]) { - critical = [NSString stringWithFormat:@"{_id:\"%@\"}", [currentItem objectForKey:@"value"]]; - }else { - critical = [NSString stringWithFormat:@"{_id:%@}", [currentItem objectForKey:@"value"]]; - }NSLog(@"%@", critical); - [mongoDB removeInDB:dbname - collection:collectionname - user:user - password:password - critical:critical]; - [removeQueryLoaderIndicator stop]; - [self findQuery:nil]; - } - [NSThread exit]; - [pool release]; -} - -- (void)controlTextDidChange:(NSNotification *)nd -{ - NSTextField *ed = [nd object]; - - if (ed == criticalTextField || ed == fieldsTextField || ed == sortTextField || ed == skipTextField || ed == limitTextField) - { - [self findQueryComposer:nil]; - }else if (ed == updateCriticalTextField || ed == updateSetTextField) { - [self updateQueryComposer:nil]; - }else if (ed == removeCriticalTextField) { - [self removeQueryComposer:nil]; - }else if (ed == expCriticalTextField || ed == expFieldsTextField || ed == expSortTextField || ed == expSkipTextField || ed == expLimitTextField) - { - [self exportQueryComposer:nil]; - } - -} - -- (IBAction) findQueryComposer:(id)sender -{ - NSString *critical; - if ([[criticalTextField stringValue] isPresent]) { - critical = [[NSString alloc] initWithString:[criticalTextField stringValue]]; - }else { - critical = [[NSString alloc] initWithString:@""]; - } - - NSString *jsFields; - if ([[fieldsTextField stringValue] isPresent]) { - NSArray *keys = [[NSArray alloc] initWithArray:[[fieldsTextField stringValue] componentsSeparatedByString:@","]]; - NSMutableArray *tmpstr = [[NSMutableArray alloc] initWithCapacity:[keys count]]; - for (NSString *str in keys) { - [tmpstr addObject:[NSString stringWithFormat:@"%@:1", str]]; - } - jsFields = [[NSString alloc] initWithFormat:@", {%@}", [tmpstr componentsJoinedByString:@","] ]; - [keys release]; - [tmpstr release]; - }else { - jsFields = [[NSString alloc] initWithString:@""]; - } - - NSString *sort; - if ([[sortTextField stringValue] isPresent]) { - sort = [[NSString alloc] initWithFormat:@".sort(%@)"]; - }else { - sort = [[NSString alloc] initWithString:@""]; - } - - NSString *skip = [[NSString alloc] initWithFormat:@".skip(%d)", [skipTextField intValue]]; - NSString *limit = [[NSString alloc] initWithFormat:@".limit(%d)", [limitTextField intValue]]; - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - - NSString *query = [NSString stringWithFormat:@"db.%@.find(%@%@)%@%@%@", col, critical, jsFields, sort, skip, limit]; - [critical release]; - [jsFields release]; - [sort release]; - [skip release]; - [limit release]; - [findQueryTextField setStringValue:query]; -} - -- (IBAction)updateQueryComposer:(id)sender -{ - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - NSString *critical; - if ([[updateCriticalTextField stringValue] isPresent]) { - critical = [[NSString alloc] initWithString:[updateCriticalTextField stringValue]]; - }else { - critical = [[NSString alloc] initWithString:@""]; - } - NSString *sets; - if ([[updateSetTextField stringValue] isPresent]) { - //sets = [[NSString alloc] initWithFormat:@", {$set:%@}", [updateSetTextField stringValue]]; - sets = [[NSString alloc] initWithFormat:@", %@", [updateSetTextField stringValue]]; - }else { - sets = [[NSString alloc] initWithString:@""]; - } - NSString *upset; - if ([upsetCheckBox state] == 1) { - upset = [[NSString alloc] initWithString:@", true"]; - }else { - upset = [[NSString alloc] initWithString:@", false"]; - } - - NSString *query = [NSString stringWithFormat:@"db.%@.update(%@%@%@)", col, critical, sets, upset]; - [critical release]; - [sets release]; - [upset release]; - [updateQueryTextField setStringValue:query]; -} - -- (IBAction)removeQueryComposer:(id)sender -{ - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - NSString *critical; - if ([[removeCriticalTextField stringValue] isPresent]) { - critical = [[NSString alloc] initWithString:[removeCriticalTextField stringValue]]; - }else { - critical = [[NSString alloc] initWithString:@""]; - } - NSString *query = [NSString stringWithFormat:@"db.%@.remove(%@)", col, critical]; - [critical release]; - [removeQueryTextField setStringValue:query]; -} - -- (IBAction) exportQueryComposer:(id)sender -{ - NSString *critical; - if ([[expCriticalTextField stringValue] isPresent]) { - critical = [[NSString alloc] initWithString:[expCriticalTextField stringValue]]; - }else { - critical = [[NSString alloc] initWithString:@""]; - } - - NSString *jsFields; - if ([[expFieldsTextField stringValue] isPresent]) { - NSArray *keys = [[NSArray alloc] initWithArray:[[expFieldsTextField stringValue] componentsSeparatedByString:@","]]; - NSMutableArray *tmpstr = [[NSMutableArray alloc] initWithCapacity:[keys count]]; - for (NSString *str in keys) { - [tmpstr addObject:[NSString stringWithFormat:@"%@:1", str]]; - } - jsFields = [[NSString alloc] initWithFormat:@", {%@}", [tmpstr componentsJoinedByString:@","] ]; - [keys release]; - [tmpstr release]; - }else { - jsFields = [[NSString alloc] initWithString:@""]; - } - - NSString *sort; - if ([[expSortTextField stringValue] isPresent]) { - sort = [[NSString alloc] initWithFormat:@".sort(%@)"]; - }else { - sort = [[NSString alloc] initWithString:@""]; - } - - NSString *skip = [[NSString alloc] initWithFormat:@".skip(%d)", [expSkipTextField intValue]]; - NSString *limit = [[NSString alloc] initWithFormat:@".limit(%d)", [expLimitTextField intValue]]; - NSString *col = [NSString stringWithFormat:@"%@.%@", dbname, collectionname]; - - NSString *query = [NSString stringWithFormat:@"db.%@.find(%@%@)%@%@%@", col, critical, jsFields, sort, skip, limit]; - [critical release]; - [jsFields release]; - [sort release]; - [skip release]; - [limit release]; - [expQueryTextField setStringValue:query]; -} - -- (void)showEditWindow:(id)sender -{ - switch([findResultsViewController.myOutlineView selectedRow]) - { - case -1: - break; - default:{ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(findQuery:) name:kJsonWindowSaved object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jsonWindowWillClose:) name:kJsonWindowWillClose object:nil]; - id currentItem = [findResultsViewController.myOutlineView itemAtRow:[findResultsViewController.myOutlineView selectedRow]]; - //NSLog(@"%@", [findResultsViewController rootForItem:currentItem]); - JsonWindowController *jsonWindowController = [[JsonWindowController alloc] init]; - jsonWindowController.managedObjectContext = self.managedObjectContext; - jsonWindowController.conn = conn; - jsonWindowController.dbname = dbname; - jsonWindowController.collectionname = collectionname; - jsonWindowController.mongoDB = mongoDB; - jsonWindowController.jsonDict = [findResultsViewController rootForItem:currentItem]; - [jsonWindowController showWindow:sender]; - break; - } - } -} - -- (void)jsonWindowWillClose:(id)sender -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (IBAction)chooseExportPath:(id)sender -{ - NSSavePanel *tvarNSSavePanelObj = [NSSavePanel savePanel]; - int tvarInt = [tvarNSSavePanelObj runModal]; - if(tvarInt == NSOKButton){ - NSLog(@"doSaveAs we have an OK button"); - //NSString * tvarDirectory = [tvarNSSavePanelObj directory]; - //NSLog(@"doSaveAs directory = %@",tvarDirectory); - NSString * tvarFilename = [tvarNSSavePanelObj filename]; - NSLog(@"doSaveAs filename = %@",tvarFilename); - [expPathTextField setStringValue:tvarFilename]; - } else if(tvarInt == NSCancelButton) { - NSLog(@"doSaveAs we have a Cancel button"); - return; - } else { - NSLog(@"doSaveAs tvarInt not equal 1 or zero = %3d",tvarInt); - return; - } // end if -} - -- (IBAction)chooseImportPath:(id)sender -{ - NSOpenPanel *tvarNSOpenPanelObj = [NSOpenPanel openPanel]; - NSInteger tvarNSInteger = [tvarNSOpenPanelObj runModalForTypes:nil]; - if(tvarNSInteger == NSOKButton){ - NSLog(@"doOpen we have an OK button"); - //NSString * tvarDirectory = [tvarNSOpenPanelObj directory]; - //NSLog(@"doOpen directory = %@",tvarDirectory); - NSString * tvarFilename = [tvarNSOpenPanelObj filename]; - NSLog(@"doOpen filename = %@",tvarFilename); - [impPathTextField setStringValue:tvarFilename]; - } else if(tvarNSInteger == NSCancelButton) { - NSLog(@"doOpen we have a Cancel button"); - return; - } else { - NSLog(@"doOpen tvarInt not equal 1 or zero = %3d",tvarNSInteger); - return; - } // end if -} - -- (mongo::BSONObj)parseCSVLine:(char *) line type:(int)_type sep:(const char *)_sep headerLine:(bool)_headerLine ignoreBlanks:(bool)_ignoreBlanks fields:(std::vector&)_fields -{ - if ( _type == 0 ) { - char * end = ( line + strlen( line ) ) - 1; - while ( std::isspace(*end) ) { - *end = 0; - end--; - } - return mongo::fromjson( line ); - } - mongo::BSONObjBuilder b; - - unsigned int pos=0; - while ( line[0] ) { - std::string name; - if ( pos < _fields.size() ) { - name = _fields[pos]; - }else { - std::stringstream ss; - ss << "field" << pos; - name = ss.str(); - } - pos++; - - bool done = false; - std::string data; - char * end; - if ( _type == 1 && line[0] == '"' ) { - line++; //skip first '"' - - while (true) { - end = strchr( line , '"' );NSLog(@"%s", line); - if (!end) { - data += line; - done = true; - break; - } else if (end[1] == '"') { - // two '"'s get appended as one - data.append(line, end-line+1); //include '"' - line = end+2; //skip both '"'s - } else if (end[-1] == '\\') { - // "\\\"" gets appended as '"' - data.append(line, end-line-1); //exclude '\\' - data.append("\""); - line = end+1; //skip the '"' - } else { - data.append(line, end-line); - line = end+2; //skip '"' and ',' - break; - } - } - } else { - end = strstr( line , _sep );NSLog(@"end: %s", end); - if ( ! end ) { - done = true; - data = std::string( line ); - } else { - data = std::string( line , end - line ); - line = end+1; - } - } - - if ( _headerLine ) { - while ( std::isspace( data[0] ) ) - data = data.substr( 1 ); - _fields.push_back( data ); - }else{ - if ( !b.appendAsNumber( name , data ) && !(_ignoreBlanks && data.size() == 0) ){ - b.append( name , data ); - } - } - - if ( done ) - break; - } - return b.obj(); -} - -@end diff --git a/README.markdown b/README.markdown index 0823b173..237aa659 100644 --- a/README.markdown +++ b/README.markdown @@ -1,118 +1,661 @@ -# MongoHub [![stillmaintained](http://stillmaintained.com/bububa/MongoHub-Mac.png)](http://stillmaintained.com/bububa/MongoHub-Mac) - -## What is MongoHub -**[MongoHub](http://mongohub.todayclose.com/)** is a **[mongodb](http://mongodb.org)** GUI application. -This repository is a mac native version of MongoHub. If you are using windows or linux please download use the source from [http://github.com/bububa/MongoHub](http://github.com/bububa/MongoHub) which is made by Titanium Desktop. - -![mongohub splash](https://github.com/downloads/bububa/MongoHub-Mac/MongoHubWall.png) - ## System Requirements -Mac OS X(10.6.x), intel(64bit) based. +Mac OS X (10.8.x, 10.9.x, 10.10.x), intel 64bit based. -## Installation +## Download -You can either download the compiled executable file from [here](https://github.com/downloads/bububa/MongoHub-Mac/MongoHub.zip) -or clone the source code and compile it on your own system. +[HERE](https://mongohub.s3.amazonaws.com/MongoHub.zip) +Or you can compile it yourself using Xcode ## Build -Before builing ensure the following frameworks are present: - /Library/PrivateFrameworks - BWToolkitFramework.framework - Sparkle.framework - MCPKit_bundled.framework - RegexKit.framework +Just build it, it should work (but let me know if you have an errors or warnings). -The project also expects Boost libraries and the MongoDB client libraries. +## Contributors -The following Xcode project settings were changed from the master project: - Header Search Paths: /usr/local/include/ - Library Search Paths: /opt/local/lib ~/source/mongo (path to mongo source) - User Header Search Paths: /opt/local/include ~/source (path to source projects) +List of all [contributions](https://github.com/jeromelebel/MongoHub-Mac/graphs/contributors). -Thanks [HybridDBA](https://github.com/HybridDBA) add this build guide. +- [Alex Shteinikov](https://github.com/idooo), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=idooo) +- [Anthony Williams](https://github.com/abitgone), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=abitgone) +- [Chris Faulkner](https://github.com/faulkner), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=faulkner) +- [Joseph Price](https://github.com/joprice), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=joprice) +- [Lukas Benes](https://github.com/falsecz), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=falsecz) +- [Olivier Hardy](https://github.com/ohardy), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=ohardy) +- [Philipp Krenn](https://github.com/xeraa), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=xeraa) +- [Prof Syd Xu](https://github.com/bububa), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=bububa) +- [Steve Steiner](https://github.com/ssteinerx), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=ssteinerx) +- [Tom Bocklisch](https://github.com/tmbo), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=tmbo) +- [Travis Choma](https://github.com/travischoma), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=travis@emphatic.co) +- [魏涛](https://github.com/undancer), list of [commits](https://github.com/jeromelebel/MongoHub-Mac/commits?author=undancer) + +Please send me a [pull request](https://github.com/jeromelebel/MongoHub-Mac/pull/new/master)! ## Current Status -This project is very new. Any issues or bug reports are welcome. And I still don't have time to write a **usage guide**. +**To do list** + +- Create a document editor to edit using an outline view (like the plist editor in Xcode) + +**Current** + +- mongo-c-driver 1.1.4 +- Adding a menu "Add Connection With URL…" [issue #108](https://github.com/jeromelebel/MongoHub-Mac/issues/108) +- Making sure all menu items are disabled when they should not be used +- Issue to get the document count in the aggregation result +- Can copy documents with OS X 10.8 and 10.9 thanks to [Sergey Basmanov](https://github.com/sbasmanov) + +**Beta** ## History -** [Last Update 2.3.2] ** - - - Fixed a bug in jsoneditor related to Date() object; - - Add import/export to JSON/CSV functions; - - Add support for ssh access use public key; - - Add a function to remove single record in find query window; - - Fixed a bug to create collection in a database which doesn't have collection; - -** [Last Update 2.3.1] ** - - - Fixed a bug in jsoneditor related to Date() object; - - Add execution time in find panel; - - Add reconnect support; - - Fixed a bug in remove function. +**3.1.5b1 - april 13, 2015** -** [2.3.0] ** - - - Add mongo stat monitor; - - Add replica set connection support; - - Add reconnect support; - - Add an JSON editor for found results with syntax highlight; - - More flexible query style in find window; - - Fixed long long int value overflow; - - Fixed application crash during open/close connection window. - -** [2.2.0] ** +- mongo-c-driver 1.1.4 +- Adding a menu "Add Connection With URL…" [issue #108](https://github.com/jeromelebel/MongoHub-Mac/issues/108) +- Making sure all menu items are disabled when they should not be used +- Issue to get the document count in the aggregation result +- Can copy documents with OS X 10.8 and 10.9 thanks to [Sergey Basmanov](https://github.com/sbasmanov) + +**3.1.4 - march 28, 2015** + +- Fixing issue to get indexes with Mongodb 3.0 [issue #199](https://github.com/jeromelebel/MongoHub-Mac/issues/199) + +**3.1.3 - march 28, 2015** + +- Issue with 10.9 to double click on a document, thanks to [Sergey Basmanov](https://github.com/sbasmanov) + +**3.1.2 - march 28, 2015** + +- Fix issue to edit only selected documents in the Find tab + +**3.1.1 - march 28, 2015** + +- Make aggregation tab be the default + +**3.1 - march 28, 2015** + +- Can copy documents in the Find tab +- Adding support for full screen in a connection window [issue #175](https://github.com/jeromelebel/MongoHub-Mac/issues/175) +- Adding a preference for the default sort order in the Find tab [issue #129](https://github.com/jeromelebel/MongoHub-Mac/issues/129) +- Adding a preference to present keys sorted in the Find tab [issue #77](https://github.com/jeromelebel/MongoHub-Mac/issues/77) +- Display errors from import/export +- Can import more than 200 documents [issue #172](https://github.com/jeromelebel/MongoHub-Mac/issues/172) +- Fix for a crash when the ssh drops [issue #171](https://github.com/jeromelebel/MongoHub-Mac/issues/171) +- New UI to create/drop indexes [issue #178](https://github.com/jeromelebel/MongoHub-Mac/issues/178) +- Removed duplicate collection name when generating displayed query in the find tab [pul #184](https://github.com/jeromelebel/MongoHub-Mac/pull/184), thanks to [Steve Steiner](https://github.com/ssteinerx) +- Showing dates in the outline view in local time zone [issue #174](https://github.com/jeromelebel/MongoHub-Mac/issues/174) +- Fix to export to mysql +- Can insert multiple documents in the insert tab with [ { document1 }, { document2 }, ... ] +- Dropping support for 10.7 +- Dropping support for 32bits +- Don't open a contextual menu if a sheet is opened [issue #183](https://github.com/jeromelebel/MongoHub-Mac/issues/183) +- Crash fixed to parse wrong regexp in a json [issue #191](https://github.com/jeromelebel/MongoHub-Mac/issues/191) +- Documents are copied inside an array (using the pasteboard) [issue #195](https://github.com/jeromelebel/MongoHub-Mac/issues/195) +- Fix for a crash when the server is not valid [issue #196](https://github.com/jeromelebel/MongoHub-Mac/issues/196) +- Fix for a crash when changingn the collection name [issue #193](https://github.com/jeromelebel/MongoHub-Mac/issues/193) +- Fix for a crash when editing a document [issue #198](https://github.com/jeromelebel/MongoHub-Mac/issues/198) +- Crash fix for [issue #200](https://github.com/jeromelebel/MongoHub-Mac/issues/200) +- Fix to create a new database with mongodb 3.0 [issue #203](https://github.com/jeromelebel/MongoHub-Mac/issues/203) +- Better json editor feedback, when saving a document [issue #201](https://github.com/jeromelebel/MongoHub-Mac/issues/201) +- Copying documents are now in a json array (using the pasteboard) [issue #195](https://github.com/jeromelebel/MongoHub-Mac/issues/195) +- Support for Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NaN [issue #206](https://github.com/jeromelebel/MongoHub-Mac/issues/206) +- Parse correctly keys in a document (now, accepts numbers without quotes) +- Mongo C Driver 1.1.2 +- Fix to make MongoHub usable again for services like Compose.io/MongoHQ, thanks to [Travis Choma](https://github.com/travischoma) + +**3.1 beta 4 - march 6, 2015** + +- Crash fix for [issue #200](https://github.com/jeromelebel/MongoHub-Mac/issues/200) +- Fix to create a new database with mongodb 3.0 [issue #203](https://github.com/jeromelebel/MongoHub-Mac/issues/203) +- Better json editor feedback, when saving a document [issue #201](https://github.com/jeromelebel/MongoHub-Mac/issues/201) +- Support for Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NaN [issue #206](https://github.com/jeromelebel/MongoHub-Mac/issues/206) +- Parse correctly keys in a document (now, accepts numbers without quotes) +- Fix for SCRAM authentification in Mongo 3.0 [issue #200](https://github.com/jeromelebel/MongoHub-Mac/issues/200) + +**3.1 beta 3 - february 19, 2015** + +- Copying documents are now in a json array (using the pasteboard) [issue #195](https://github.com/jeromelebel/MongoHub-Mac/issues/195) +- Fix for a crash when the server is not valid [issue #196](https://github.com/jeromelebel/MongoHub-Mac/issues/196) +- Fix for a crash when changingn the collection name [issue #193](https://github.com/jeromelebel/MongoHub-Mac/issues/193) +- Fix for a crash when editing a document [issue #198](https://github.com/jeromelebel/MongoHub-Mac/issues/198) + +**3.1 beta 2 - february 4, 2015** + +- Better parsing errors in the aggregation tab +- Avoiding some crashes in the aggregation tab + +**3.1 beta 1 - january 19, 2015** + +- Can copy documents in the Find tab +- Adding support for full screen in a connection window [issue #175](https://github.com/jeromelebel/MongoHub-Mac/issues/175) +- Adding a preference for the default sort order in the Find tab [issue #129](https://github.com/jeromelebel/MongoHub-Mac/issues/129) +- Adding a preference to present keys sorted in the Find tab [issue #77](https://github.com/jeromelebel/MongoHub-Mac/issues/77) +- Display errors from import/export +- Can import more than 200 documents [issue #172](https://github.com/jeromelebel/MongoHub-Mac/issues/172) +- Fix for a crash when the ssh drops [issue #171](https://github.com/jeromelebel/MongoHub-Mac/issues/171) +- New UI to create/drop indexes [issue #178](https://github.com/jeromelebel/MongoHub-Mac/issues/178) +- Removed duplicate collection name when generating displayed query in the find tab [pul #184](https://github.com/jeromelebel/MongoHub-Mac/pull/184), thanks to [Steve Steiner](https://github.com/ssteinerx) +- Showing dates in the outline view in local time zone [issue #174](https://github.com/jeromelebel/MongoHub-Mac/issues/174) +- Fix to export to mysql +- Can insert multiple documents in the insert tab with [ { document1 }, { document2 }, ... ] +- Dropping support for 10.7 +- Dropping support for 32bits +- Don't open a contextual menu if a sheet is opened [issue #183](https://github.com/jeromelebel/MongoHub-Mac/issues/183) +- Crash fixed to parse wrong regexp in a json [issue #191](https://github.com/jeromelebel/MongoHub-Mac/issues/191) + +**3.0.8 - november 5, 2014** + +- Fixing bugs related to DBRef and $ref [issue #148](https://github.com/jeromelebel/MongoHub-Mac/issues/148) + +**3.0.7 - november 5, 2014** + +- Better support for DBRef(), the collection should be an absolute collection [issue #148](https://github.com/jeromelebel/MongoHub-Mac/issues/148) +- Better display of name connections in the main window [issue #72](https://github.com/jeromelebel/MongoHub-Mac/issues/72) +- Reopen the main window when coming back to the application (if closed) [issue #76](https://github.com/jeromelebel/MongoHub-Mac/issues/76) +- Add a dock menu (with all the connections) +- Can use return key to start a search in the find tab [issue #100](https://github.com/jeromelebel/MongoHub-Mac/issues/100) + +**3.0.6 - october 30, 2014** + +- Autoreconnect the ssh tunnel when it is down +- Changing the shortcut from ⌘→ and ⌘← to ⌥⌘→ and ⌥⌘← to get next and previous results in the find tab [issue #162](https://github.com/jeromelebel/MongoHub-Mac/issues/162) +- Issue to upgrade from old version (2.3.2) [issue #166](https://github.com/jeromelebel/MongoHub-Mac/issues/166) + +**3.0.5 - october 23, 2014** + +- Issue to edit 2 connections, one after the other +- Problem to migrate data store from 2.6.x to 3.0.x [issue #153](https://github.com/jeromelebel/MongoHub-Mac/issues/153) + +**3.0.4 - october 22, 2014** + +- Crash in the Monitor Activity [issue #155](https://github.com/jeromelebel/MongoHub-Mac/issues/155) +- Adding Next and Previous buttons [issue #149](https://github.com/jeromelebel/MongoHub-Mac/issues/149) +- Adding auto expand popup button to view results +- Crash closing the connection editor window while it is not a sheet +- Field filter now uses json (example : { field_to_see: 1, field_to_filter_out: 0 }) [issue #116](https://github.com/jeromelebel/MongoHub-Mac/issues/116) +- Don't show twice the collection name in the query (in the update tab) [issue #158](https://github.com/jeromelebel/MongoHub-Mac/issues/158) +- Avoiding a crash on 10.7 [issue #157](https://github.com/jeromelebel/MongoHub-Mac/issues/157) (I will drop the support of 10.7 soon) + +**3.0.2 - october 21, 2014** + +- Adding back the activity monitor (in the toolbar) [issue #152](https://github.com/jeromelebel/MongoHub-Mac/issues/152) +- Display correctly errors (if any) while saving a document +- Fixing few issues while editing the criteria in the remove tab [issue #151](https://github.com/jeromelebel/MongoHub-Mac/issues/151) +- Better support for DBRef +- Problem to autosave the toolbar in the connection window +- Maybe a fix for ssh problems [issue #146](https://github.com/jeromelebel/MongoHub-Mac/issues/146) +- Issue with default filename when doing file export + +**3.0.1 - october 17, 2014** + +- Fixing issue with passwords that contain some specific characters [issue #147](https://github.com/jeromelebel/MongoHub-Mac/issues/147) + +**3.0 - october 17, 2014** + +- SSL Working +- Fix for a crash when having problem to parse a json [issue #125](https://github.com/jeromelebel/MongoHub-Mac/issues/125) +- Support for functions and scope functions [issue #120](https://github.com/jeromelebel/MongoHub-Mac/issues/120) +- Fix to connect to mongoHQ [issue #124](https://github.com/jeromelebel/MongoHub-Mac/issues/124) +- Better support for primary and secondary in replica set +- Migrate SSH password into the keychain [issue #106](https://github.com/jeromelebel/MongoHub-Mac/issues/106) +- Migrate database password into the keychain [issue #106](https://github.com/jeromelebel/MongoHub-Mac/issues/106) +- Fix for adding a database with more than one server connected (the database was created on all servers) +- Fix for adding a collection with more than one server connected (the collection was created on all servers) +- Adding contextual menu in the main window +- Display glitch fixed in the connection window +- Adding a log window +- Accept connecting to secondary server [issue #113](https://github.com/jeromelebel/MongoHub-Mac/issues/113) +- Can change font and colors in the json editor and font [issue #135](https://github.com/jeromelebel/MongoHub-Mac/issues/135) +- cmd-w should close the current tab [issue #119](https://github.com/jeromelebel/MongoHub-Mac/issues/119) +- Better support for tunneling with replica set/sharding +- Can copy/paste mongodb URI [issue #108](https://github.com/jeromelebel/MongoHub-Mac/issues/108) +- Adding support for timeout parameter in URL +- Update some images to be high resolution [issue #54](https://github.com/jeromelebel/MongoHub-Mac/issues/54) +- Adding contextual menu in the database/collection list +- Can renaming a collection +- Closing tabs when dropping a collection/database +- Nicer update panel [issue #142](https://github.com/jeromelebel/MongoHub-Mac/issues/142) +- Workaround for corrupted bson +- Always check for debug updates on a debug version +- Fixing memory leaks +- A little faster to display a thousand collections in a database + +**2.7 beta 21 - october 15, 2014** + +- Workaround for corrupted bson + +**2.7 beta 20 - october 15, 2014** + +- Disable the remove operator button when needed + +**2.7 beta 19 - october 15, 2014** + +- Adding more update operator in the update tab +- Workaround for corrupted bson +- Always check for debug updates on a debug version + +**2.7 beta 18 - october 14, 2014** + +- Fixing memory leaks +- Better UI for dropping collections/databases +- Moving the timeout in the application preference +- Nicer update panel + +**2.7 beta 17 - october 8, 2014** + +- Display (in the log window) the correct error number if the connection failed +- Can renaming a collection +- Closing tabs when dropping a collection/database +- Connection issues fixed [issue #126](https://github.com/jeromelebel/MongoHub-Mac/issues/126) + +**2.7 beta 16 - october 5, 2014** + +- Adding back the edit icon in the main window +- Adding contextual menu in the database/collection list +- Workaround for connection problem + +**2.7 beta 15 - october 4, 2014** + +- Fix for ssl [issue #140](https://github.com/jeromelebel/MongoHub-Mac/issues/140) +- Update some images to be high resolution [issue #54](https://github.com/jeromelebel/MongoHub-Mac/issues/54) + +**2.7 beta 14 - october 4, 2014** + +- Fix to display a lot of collections [issue #139](https://github.com/jeromelebel/MongoHub-Mac/issues/139) + +**2.7 beta 13 - september 29, 2014** + +- Support for URI pasted in the main window +- Adding support for timeout parameter in URL + +**2.7 beta 12 - september 2, 2014** + +- Fix in the close button of a connection window + +**2.7 beta 11 - september 2, 2014** + +- Adding a log window +- Accept connecting to secondary server [issue #113](https://github.com/jeromelebel/MongoHub-Mac/issues/113) +- Can change font and colors in the json editor and font [issue #135](https://github.com/jeromelebel/MongoHub-Mac/issues/135) +- cmd-w should close the current tab [issue #119](https://github.com/jeromelebel/MongoHub-Mac/issues/119) +- Better support for tunneling with replica set/sharding + +**2.7 beta 10 - august 27, 2014** + +- Display glitch fixed in the connection window + +**2.7 beta 9 - august 26, 2014** + +- SSL fix + +**2.7 beta 8 - august 25, 2014** + +- Migrate SSH password into the keychain [issue #106](https://github.com/jeromelebel/MongoHub-Mac/issues/106) +- Migrate database password into the keychain [issue #106](https://github.com/jeromelebel/MongoHub-Mac/issues/106) +- Fix for adding a database with more than one server connected (the database was created on all servers) +- Fix for adding a collection with more than one server connected (the collection was created on all servers) +- Adding contextual menu in the main window +- Can copy mongodb URI +- Adding the option for weak SSL certificate + +**2.7 beta 7 - july 23, 2014** + +- Fix for a problem to parse json (bug introduced in 2.7) + +**2.7 beta 6 - july 21, 2014** + +- SSL was activated for all connections + +**2.7 beta 5 - july 19, 2014** + +- Fix for ports higher than 32767 (bug introduced in 2.7) + +**2.7 beta 4 - july 18, 2014** + +- SSL Working + +**2.7 beta 3 - june 13, 2014** + +- Support for functions and scope functions [issue #120](https://github.com/jeromelebel/MongoHub-Mac/issues/120) +- Fix to connect to mongoHQ [issue #124](https://github.com/jeromelebel/MongoHub-Mac/issues/124) + +**2.6.2 - june 12, 2014** + +- Be able to downgrade from 2.7 beta +- Avoid automatic correction from Mac OS X while typing a new document [issue #121](https://github.com/jeromelebel/MongoHub-Mac/issues/121) (Thanks to Anthony Williams with [pull request #122](https://github.com/jeromelebel/MongoHub-Mac/pull/122)) +- Avoid automatic correction from Mac OS X while typing map/reduce functions + +**2.7 beta 1 and 2 - june 11, 2014** + +- Avoid automatic correction from Mac OS X while typing a new document [issue #121](https://github.com/jeromelebel/MongoHub-Mac/issues/121) (Thanks to Anthony Williams with [pull request #122](https://github.com/jeromelebel/MongoHub-Mac/pull/122)) +- Avoid automatic correction from Mac OS X while typing map/reduce functions +- Better support for primary and secondary + +**2.6 - april 17, 2014** + +- Support for tengen json +- Progress bar while importing/exporting to/from file +- A lot of fix to convert dates with milliseconds into json and parse dates with milliseconds +- Using more sheets instead of modal panels +- Few crashes fixed +- More checks to make sure a document is parsed correctly (and therefore there is no modification while converting a document into json and parsing again the json) +- Better support for long integer vs integer + +**2.6 beta 6 - january 16, 2014** + +- Using a sheet to remove a connection +- Removing a crash when trying to remove some documents (with the tab) +- Better way to make sure we don't modify a document, and better way to notify it to the user +- Using sheet to add a database or a collection + +**2.6 beta 5 - december 15, 2013** + +- Fixing connection icon display at launch +- Json export/import working +- A better test to make sure no data are corrupted while editing a document + +**2.6 beta 4 - november 21, 2013** + +- Make sure we don't mixup double and integer type (while editing a document) +- Trying to explain to the user if a document might be changed while editing it + +**2.6 beta 3 - november 21, 2013** + +- Correct support for integer and long integer type (no more mix up) + +**2.5.15 - november 17, 2013** + +- Removing an assert (while editing a document) with too much false positive +- Connection editor window is displayed as a sheet +- Can duplication a connection [issue #75](https://github.com/jeromelebel/MongoHub-Mac/issues/75) +- Short cut to delete a connection (command-backspace) [issue #69](https://github.com/jeromelebel/MongoHub-Mac/issues/69) + +**2.5.14 - november 16, 2013** + +- Using the ssh-agent when having passphrase [issue #93](https://github.com/jeromelebel/MongoHub-Mac/issues/93) (thanks for Nick Brook's help) +- Fix from a bug introduced in 2.5.13(107), problem to tab away the document outline view to the delete button [issue #97](https://github.com/jeromelebel/MongoHub-Mac/issues/97) +- Better error reporting for find, update or delete (thanks to Johannes Schriewer) +- Fix for database with no name [issue #101](https://github.com/jeromelebel/MongoHub-Mac/issues/101) +- Fix for generating/parsing json with a date with milliseconds [issue #102](https://github.com/jeromelebel/MongoHub-Mac/issues/102) +- Adding a preference panel to choose to get beta version (this will support tengen json) +- Dropping support for Mac OS X 10.6.x + +**2.5.13(107) - october 19, 2013** + +- Can type any value without double quote in the search field, it will be replaced by { "_id": "" } +- Adding support for retina display (thanks to Patryk Kasperski) +- Following the strict json for undefined value according to [extended json](http://docs.mongodb.org/manual/reference/mongodb-extended-json/) (now, exporting and parsing undefined as { "$undefined": true } +- Fixing a crash when trying to save an invalid json document + +**2.5.12(106) - september 8, 2013** + +- New build to fix the font problem in the query window [issue #91](https://github.com/jeromelebel/MongoHub-Mac/issues/91) + +**2.5.11(105) - september 7, 2013** + +- Default port was not set (thanks to undancer) [issue #89](https://github.com/jeromelebel/MongoHub-Mac/issues/89) + +**2.5.10(104) - june 11, 2013** + +- Problem to convert a double from bson to json and back to bson (bis) +- Adding support to minKey and maxKey (thanks for castiel's help) + +**2.5.9(103) - june 11, 2013** + +- Problem to convert a double from bson to json and back to bson + +**2.5.8(102) - june 11, 2013** + +- Crash while opening a collection that contains a data (introduced in 2.5.6) + +**2.5.7(101) - june 6, 2013** + +- Drop database/collection default action must be "No" [issue #65](https://github.com/jeromelebel/MongoHub-Mac/issues/65) +- New Connection window doesn't use 127.0.0.1:27017 by default [issue #60](https://github.com/jeromelebel/MongoHub-Mac/issues/60) +- Double values are truncated while being edited + +**2.5.6(100) - may 19, 2013** + +- Unable to reopen connection window after it is closed [issue #63](https://github.com/jeromelebel/MongoHub-Mac/issues/63) +- Horizontal and vertical paddings between "New connection" button and window border must be equal [issue #68](https://github.com/jeromelebel/MongoHub-Mac/issues/68) +- Binary should be imported and exported as base64 (instead of hexa) +- Accept queries with objectid between double quotes +- Bug fix when the mongo host port was left with the default value (while using ssh tunneling) [issue #78](https://github.com/jeromelebel/MongoHub-Mac/issues/78) +- ssh tunnel is a lot faster to open the connection now + +**2.5.5(99) - march 3, 2013** + +- Problem to modify ssh parameters while editing an existing connection (fields were disabled) +- Multi update checkbox added for updates (thanks to Tom Bocklisch) +- Bug fix to export mongo to sql: crash while exporting [issue #58](https://github.com/jeromelebel/MongoHub-Mac/issues/58) +- ObjectId should be in lower case [issue #55](https://github.com/jeromelebel/MongoHub-Mac/issues/55) +- Confirm dialog before connection delete (thanks to falsecz) https://github.com/jeromelebel/MongoHub-Mac/pull/57 + +**2.5.4(98) - november 1, 2012** + +- Fix to display Undefined values [issue #49](https://github.com/jeromelebel/MongoHub-Mac/issues/49) +- Fix to avoid a crasher with disconnecting from a server while using ssh tunneling [issue #48](https://github.com/jeromelebel/MongoHub-Mac/issues/48) +- Use ⌘ to avoid the confirmation panel in the remove tab (either while clicking or pressing the return key) + +**2.5.3(97) - september 4, 2012** + +- No more setting for bind address and bind port (bind address is 127.0.0.1 and bind port will be choosen automatically from 40000 or higher) [issue #19](https://github.com/jeromelebel/MongoHub-Mac/issues/19) +- Fix for a crasher when the network goes down [issue #42](https://github.com/jeromelebel/MongoHub-Mac/issues/42) +- Changing from red to green (except for remove) [issue #44](https://github.com/jeromelebel/MongoHub-Mac/issues/44) +- Adding a confirmation dialog correctly when removing all documents [issue #33](https://github.com/jeromelebel/MongoHub-Mac/issues/33) +- Some cleanup for the connection editor, thanks to Alex Shteinikov (idooo) + +**2.5.2(96) - july 15, 2012** + +- Fix: Some UTF8 characters became invisible while editing a document +- Fix: Some problems with updating colors while editing +- Open only one document window for each document +- Close all document windows when close a collection +- Fix: Making sure the collection outline selection always match the collection tab selection (to make sure Fred doesn't make any mistake) +- Fix: a blank query will not remove documents anymore. Please use at least '{}' +- Fix: problem to import documents with array in it [issue #39](https://github.com/jeromelebel/MongoHub-Mac/issues/39) +- Adding multiple document selection +- Adding document drag + +**2.5.1(95) - june 21, 2012** + +- Fix for [issue #36](https://github.com/jeromelebel/MongoHub-Mac/issues/36) (open a second time the same database tab) +- Trying to make sure we don't make a mistake between the tab opened and the selection in the database outline view (special for fred) + +**2.5(94) - may 27, 2012** + +- Fix for the limit and skip field (limited to 9999) [issue #30](https://github.com/jeromelebel/MongoHub-Mac/issues/30) +- Adding tabs + +**2.4.19(93) - may 23, 2012** + +- Trying to keep type (integer and float) the same as much as possible (when editing a document) [issue #35](https://github.com/jeromelebel/MongoHub-Mac/issues/35) +- Crash fixed when opening a collection with documents that has no "_id" and "name" [issue #24](https://github.com/jeromelebel/MongoHub-Mac/issues/24) + +**2.4.18(92) - may 10, 2012** + +- Fix crasher when error [issue #31](https://github.com/jeromelebel/MongoHub-Mac/issues/31) +- Fix to use an authenticated database + +**2.4.17(91) - may 5, 2012** + +- Fix to parse binary values +- Fix to parse an hash with $type +- Changing "upset" to "upsert" +- Fix from billybobuk to get the database list when having auth +- Adding header in the data outline view +- Fix to add a document with structures inside an array [issue #28](https://github.com/jeromelebel/MongoHub-Mac/issues/28) + +**2.4.16(90) - jan 29, 2012** + +- Adding autosave for the connection list window +- Adding back the index icon +- Better error message when not having the authorization to get the server status +- Crash fixed when not having the authorization to get the server status + +**2.4.15(89) - dec 30, 2011** + +- Crash fixed when remove all documents : [issue #18](https://github.com/jeromelebel/MongoHub-Mac/issues/18) +- Change minimum size of MainMenu window to avoid display bug (thanks ohardy) +- Bug fixes (thanks ohardy) +- Double click on database name collapse or expand item (thanks ohardy) + +**2.4.14(88) - dec 23, 2011** + +- Adding full-screen support (lion only), thanks callumj +- Fix when you don't have the right to get the database list (you need to set the database you want to use in the connection panel) + +**2.4.13(87) - nov 30, 2011** + + - Key order is preserved in a document +- Support for UTF-8 +- Fix for Mysql import/export +- Support for symbol type +- fix for the UI selection in the connection window + +**2.4.12(86) - nov 22, 2011** + +- Problem to update document with boolean values and regexp values + +**2.4.11(85) - nov 22, 2011** + +- Toolbar items are enabled/disabled according to the selection +- Connecting to localhost is not an issue anymore +- Bug to parse json with arrays + +**2.4.10(84) - nov 19, 2011** + +- Bug to add a new connection + +**2.4.9(83) - nov 18, 2011** + +- Changing the NSBundle application id +- Database stats works again +- History combo-box for the criteria +- Fix to use database with an admin user/password + +**2.4.8(82) - nov 1, 2011** + +- Problem to display and parse date types + +**2.4.7(81) - nov 1, 2011** + +- Connections are sorted after being loaded (still not sorted after being updated) +- Adding short cuts to delete a document or an index (Command+delete) +- Adding tooltips for the buttons with short cuts +- Queries are sorted by default +- Problem to display regex and timestamp values in documents + +**2.4.6(80) - oct 28, 2011** + +- Can insert an array of documents +- MapReduce feature working +- Fix for parsing: "$oid":"4E9321AF3768CF514A00000C"} +- Crash when getting stats for some servers +- New outline view for the databases and collections + +**2.4.5(79) - oct 22, 2011** + +- Fix to parse { "empty_array": [], "zob": 1} +- Fix to parse { "empty_hash": {}, "zob": 1} +- Implementing reIndex + +**2.4.4(78) - oct 20, 2011** + +- Can create indexes with the UI +- Can remove indexes with the UI +- Fix to parse { "_id": { "$oid" : "4E9807F88157F608B4000002" }, "_type": "Activity" } +- Fix to edit a document when "_id" is an objectid + +**2.4.3(77) - oct 17, 2011** + +- Fix to parse { "toto" : [ { "1" : 2 }, { "2" : 3 } ] } +- Display errors (if any) when inserting a document +- Display errors (if any) when removing a document +- Fix to remove a document +- Search for updates at each launch + +**2.4.2(76) - oct 15, 2011** + +- Crash fixed when using an authenticated database +- Show all the databases when using authentication +- Use "admin" database when there is no database set for the authentication +- Crash fixed when searching for mongo document with "{ "$oid" : "4E40C5111F85DD1BE9FAF825" }" +- Adding the error message when the search criteria is invalid +- Trying to be nice to complete your criteria. To search for an id, you can either type: + - 123 + - "abc" + - "$oid" : "123" + - {"$oid" : "123"} +- Adding Command-R in the index view to reload the index list + + +**[Update 2.4.1(75)]** + +- Can do export and import (mysql) + +**[Update 2.3.2]** - - SSH Tunnel connection support; - - Fixed a bug in display ObjectID type fields; - - Fixed some UI bugs; - - Fixed some memory leaks and random crashes; - - Add confirm panel before drop database or collection; - - Run queries in a seperate thread so that won't block the UI; - - Fixed a bug to install on some 10.6.x(64bit) system. - -** [2.1.0] ** +- Fixed a bug in jsoneditor related to Date() object; +- Add import/export to JSON/CSV functions; +- Add support for ssh access use public key; +- Add a function to remove single record in find query window; +- Fixed a bug to create collection in a database which doesn't have collection; - - Auto expand and collaspe finding results; - - Display Date_t or Timestamp as GMT time format; - - Fixed a bug in display ObjectIds in Array element; - - Import data from mysql database to mongodb; - - Export data from mongodb to mysql database. +**[Update 2.3.1]** -** [2.0.9] ** - - - Add support for mongohq.com; - - Changed update behavior; - - Fixed a bug to detect NumberLong type of BSONElement; - - Fixed a bug in Array type of BSONElement. +- Fixed a bug in jsoneditor related to Date() object; +- Add execution time in find panel; +- Add reconnect support; +- Fixed a bug in remove function. -** [2.0.8] ** - - - Fix several UI bugs in Query Window; - - Fix bugs in Find Query and Update Query; - - Fix bugs related to ObjectId; - - Fix copy&paste bugs. +**[2.3.0]** -** [2.0.7] ** - - - Add sparkle framework to check application updates. +- Add mongo stat monitor; +- Add replica set connection support; +- Add reconnect support; +- Add an JSON editor for found results with syntax highlight; +- More flexible query style in find window; +- Fixed long long int value overflow; +- Fixed application crash during open/close connection window. -** [2.0.6] ** - - - fixed some UI bugs; - - add admin auth support. +**[2.2.0]** + +- SSH Tunnel connection support; +- Fixed a bug in display ObjectID type fields; +- Fixed some UI bugs; +- Fixed some memory leaks and random crashes; +- Add confirm panel before drop database or collection; +- Run queries in a seperate thread so that won't block the UI; +- Fixed a bug to install on some 10.6.x(64bit) system. + +**[2.1.0]** + +- Auto expand and collaspe finding results; +- Display Date_t or Timestamp as GMT time format; +- Fixed a bug in display ObjectIds in Array element; +- Import data from mysql database to mongodb; +- Export data from mongodb to mysql database. + +**[2.0.9]** + +- Add support for mongohq.com; +- Changed update behavior; +- Fixed a bug to detect NumberLong type of BSONElement; +- Fixed a bug in Array type of BSONElement. + +**[2.0.8]** -## Contribute +- Fix several UI bugs in Query Window; +- Fix bugs in Find Query and Update Query; +- Fix bugs related to ObjectId; +- Fix copy&paste bugs. -I'd love to include your contributions, friend. Make sure your methods are -[TomDoc](http://tomdoc.org)'d properly, that existing tests pass, and -that any new functionality includes appropriate tests. +**[2.0.7]** -Then [send me a pull request](https://github.com/bububa/MongoHub-Mac/pull/new/master)! +- Add sparkle framework to check application updates. -## Contact Me +**[2.0.6]** -[Syd](mailto:prof.syd.xu@gmail.com) made this. Ping me on Twitter —[@bububa](http://twitter.com/bububa) — or [email](mailto:prof.syd.xu@gmail.com) me if you're having issues, or want me to merge in your pull request. \ No newline at end of file +- fixed some UI bugs; +- add admin auth support. diff --git a/English.lproj/InfoPlist.strings b/Resources/English.lproj/InfoPlist.strings similarity index 100% rename from English.lproj/InfoPlist.strings rename to Resources/English.lproj/InfoPlist.strings diff --git a/Resources/English.lproj/MHMainMenu.xib b/Resources/English.lproj/MHMainMenu.xib new file mode 100644 index 00000000..0bb1fbbb --- /dev/null +++ b/Resources/English.lproj/MHMainMenu.xib @@ -0,0 +1,600 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CA + + + + + + + + +DQ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @count + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +https://github.com/jeromelebel/MongoHub-Mac + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHActivityMonitorTab.xib b/Resources/MHActivityMonitorTab.xib new file mode 100644 index 00000000..f809cc4c --- /dev/null +++ b/Resources/MHActivityMonitorTab.xib @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHConnectionEditorWindow.xib b/Resources/MHConnectionEditorWindow.xib new file mode 100644 index 00000000..c876d23f --- /dev/null +++ b/Resources/MHConnectionEditorWindow.xib @@ -0,0 +1,558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHConnectionWindow.xib b/Resources/MHConnectionWindow.xib new file mode 100644 index 00000000..59bf9d92 --- /dev/null +++ b/Resources/MHConnectionWindow.xib @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHDocumentOutlineView.xib b/Resources/MHDocumentOutlineView.xib new file mode 100644 index 00000000..1878db8b --- /dev/null +++ b/Resources/MHDocumentOutlineView.xib @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHEditNameWindow.xib b/Resources/MHEditNameWindow.xib new file mode 100644 index 00000000..444a7ceb --- /dev/null +++ b/Resources/MHEditNameWindow.xib @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHImportExportFeedback.xib b/Resources/MHImportExportFeedback.xib new file mode 100644 index 00000000..cea0c65b --- /dev/null +++ b/Resources/MHImportExportFeedback.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHIndexEditor.xib b/Resources/MHIndexEditor.xib new file mode 100644 index 00000000..9f3a6d6c --- /dev/null +++ b/Resources/MHIndexEditor.xib @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHJsonWindow.xib b/Resources/MHJsonWindow.xib new file mode 100644 index 00000000..1c3255d2 --- /dev/null +++ b/Resources/MHJsonWindow.xib @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHLogWindow.xib b/Resources/MHLogWindow.xib new file mode 100644 index 00000000..6442dfbc --- /dev/null +++ b/Resources/MHLogWindow.xib @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + date + log + domain + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHPreferenceWindow.xib b/Resources/MHPreferenceWindow.xib new file mode 100644 index 00000000..04228482 --- /dev/null +++ b/Resources/MHPreferenceWindow.xib @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + After checking this checkbox, you will be asked to update MongoHub with a beta version (if available). Once running a beta version, you cannot downgrade automatically. You will have to download the release version yourself. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHQueryUpdateOperatorView.xib b/Resources/MHQueryUpdateOperatorView.xib new file mode 100644 index 00000000..d366f22a --- /dev/null +++ b/Resources/MHQueryUpdateOperatorView.xib @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHQueryView.xib b/Resources/MHQueryView.xib new file mode 100644 index 00000000..053d35fd --- /dev/null +++ b/Resources/MHQueryView.xib @@ -0,0 +1,1133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHStatusView.xib b/Resources/MHStatusView.xib new file mode 100644 index 00000000..ae0302de --- /dev/null +++ b/Resources/MHStatusView.xib @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/MHTabView.xib b/Resources/MHTabView.xib new file mode 100644 index 00000000..c9c50143 --- /dev/null +++ b/Resources/MHTabView.xib @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/MongoHub-Info.plist b/Resources/MongoHub-Info.plist similarity index 59% rename from MongoHub-Info.plist rename to Resources/MongoHub-Info.plist index 1d4e5d56..80e91850 100644 --- a/MongoHub-Info.plist +++ b/Resources/MongoHub-Info.plist @@ -4,33 +4,12 @@ CFBundleDevelopmentRegion English - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - YOUR_EXTERNAL_RECORD_EXTENSION - - CFBundleTypeName - External Record Support - CFBundleTypeRole - Editor - LSItemContentTypes - - YOUR_EXTERNAL_RECORD_UTI - - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile Icon.icns CFBundleIdentifier - com.thepeppersstudio.${PRODUCT_NAME:rfc1034identifier} + com.fotonauts.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -38,22 +17,35 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.3.2 + 3.1.5b1 CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleURLName + com.mongohub.mongodb + CFBundleURLSchemes + + mongodb + + + CFBundleVersion - 73 + 3.1.5b1 + LSApplicationCategoryType + public.app-category.developer-tools LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} + NSHighResolutionCapable + + NSHumanReadableCopyright + © 2010, The Peppers Studio NSMainNibFile - MainMenu + MHMainMenu NSPrincipalClass NSApplication - NSHumanReadableCopyright - © 2010, The Peppers Studio - SUPublicDSAKeyFile - dsa_pub.pem SUFeedURL - http://mongohub.todayclose.com/appcast.xml + https://mongohub.s3.amazonaws.com/mongohub_su_feed.xml diff --git a/Resources/MysqlExport.xib b/Resources/MysqlExport.xib new file mode 100644 index 00000000..d0c47619 --- /dev/null +++ b/Resources/MysqlExport.xib @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + value + name + @count + + + + + value + name + @count + + + + + + + + + diff --git a/Resources/MysqlImport.xib b/Resources/MysqlImport.xib new file mode 100644 index 00000000..833bfd54 --- /dev/null +++ b/Resources/MysqlImport.xib @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @count + + + + + value + name + @count + + + + diff --git a/SSHCommand.sh b/Resources/SSHCommand.sh similarity index 53% rename from SSHCommand.sh rename to Resources/SSHCommand.sh index 91871a8e..4ede8615 100755 --- a/SSHCommand.sh +++ b/Resources/SSHCommand.sh @@ -1,4 +1,3 @@ -#!/usr/bin/expect -f #!/bin/sh # Copyright (C) 2008 Antoine Mercadal @@ -17,29 +16,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -set arguments [lindex $argv 0] -set password [lindex $argv 1] - -eval spawn $arguments - -match_max 100000 - -set timeout 1 -#expect "*yes/no*" {send "yes\r"; exp_continue}; - -set timeout 30 -expect { - "?sh: Error*" {puts "CONNECTION_ERROR"; exit}; - "*yes/no*" {send "yes\r"; exp_continue}; - "*Could not resolve hostname*" {puts "CONNECTION_REFUSED"; exit}; - "*Operation timed out*" {puts "CONNECTION_REFUSED"; exit}; - "*Connection refused*" {puts "CONNECTION_REFUSED"; exit}; - "*?assword:*" { send "$password\r"; set timeout 4; - expect "*?assword:*" {puts "WRONG_PASSWORD"; exit;} - }; -} - -puts "CONNECTED"; -set timeout -1 -expect eof; - +date >> /tmp/test +echo "$SSHPASSWORD" \ No newline at end of file diff --git a/Resources/Syntax Definitions/SyntaxDefinition.plist b/Resources/Syntax Definitions/SyntaxDefinition.plist new file mode 100644 index 00000000..a2066149 --- /dev/null +++ b/Resources/Syntax Definitions/SyntaxDefinition.plist @@ -0,0 +1,247 @@ + + + + + Components + + Timestamp + + Color + + 1 + 0.5647058823529412 + 0 + + End + ) + Name + Timestamp + Start + Timestamp( + Type + String + + SingleQuoteStringsValue + + Color + + 1 + 1 + 1 + + End + ' + EscapeChar + \ + Name + Quoted String + Start + ' + Type + String + + DoubleQuoteStringsValue + + Color + + 1 + 1 + 1 + + End + " + EscapeChar + + Name + Quoted String + Start + " + Type + String + + BooleanValues + + Color + + 0 + 1 + 0 + + Keywords + + true + false + + Name + Boolean Values + Type + Keywords + + Null + + Color + + 1 + 0 + 0 + + Keywords + + null + + Name + Null + Type + Keywords + + JsonStructure + + Color + + 1 + 1 + 0 + + Keywords + + { + } + [ + ] + " + , + : + + Name + { } [ ] , : + Type + Keywords + + NumberKeyWords + + Name + Number + Type + Keywords + Keywords + + NumberLong + Number.POSITIVE_INFINITY + Number.NEGATIVE_INFINITY + Number.NaN + + Color + + 1 + 0.5647058823529412 + 0 + + + IdKey + + Color + + 0.2627450980392157 + 0.6666666666666666 + 1 + + Keywords + + "_id" + + Name + Json Key + Type + Keywords + + JsonKey + + Color + + 0.2627450980392157 + 0.6666666666666666 + 1 + + End + " + Name + Json Key + Start + "$ + Type + String + + Date + + Color + + 1 + 0.5647058823529412 + 0 + + End + ) + Name + Date + Start + Date( + Type + String + + ObjectId + + Color + + 1 + 0.5647058823529412 + 0 + + End + ) + Name + ObjectId + Start + ObjectId( + Type + String + + + TextField + + Text + + Font + + name + Monaco + size + 10 + + Color + + 1 + 1 + 1 + + + Background + + Color + + 0 + 0 + 0 + + + InsertionPoint + + Color + + 1 + 1 + 1 + + + + + diff --git a/Resources/images/ActivityMonitor.icns b/Resources/images/ActivityMonitor.icns new file mode 100644 index 00000000..fa041cc4 Binary files /dev/null and b/Resources/images/ActivityMonitor.icns differ diff --git a/Resourses/images/Icon.icns b/Resources/images/Icon.icns similarity index 100% rename from Resourses/images/Icon.icns rename to Resources/images/Icon.icns diff --git a/Resourses/images/collectionicon.png b/Resources/images/collectionicon.png similarity index 100% rename from Resourses/images/collectionicon.png rename to Resources/images/collectionicon.png diff --git a/Resourses/images/collectionmenu.png b/Resources/images/collectionmenu.png similarity index 100% rename from Resourses/images/collectionmenu.png rename to Resources/images/collectionmenu.png diff --git a/Resourses/images/connecticon.png b/Resources/images/connecticon.png similarity index 100% rename from Resourses/images/connecticon.png rename to Resources/images/connecticon.png diff --git a/Resourses/images/database.png b/Resources/images/database.png similarity index 100% rename from Resourses/images/database.png rename to Resources/images/database.png diff --git a/Resourses/images/dbicon.png b/Resources/images/dbicon.png similarity index 100% rename from Resourses/images/dbicon.png rename to Resources/images/dbicon.png diff --git a/Resourses/images/dbmenu.png b/Resources/images/dbmenu.png similarity index 100% rename from Resourses/images/dbmenu.png rename to Resources/images/dbmenu.png diff --git a/Resources/images/editmenu.png b/Resources/images/editmenu.png new file mode 100644 index 00000000..85885418 Binary files /dev/null and b/Resources/images/editmenu.png differ diff --git a/Resources/images/editmenu@2x.png b/Resources/images/editmenu@2x.png new file mode 100644 index 00000000..7b345ced Binary files /dev/null and b/Resources/images/editmenu@2x.png differ diff --git a/Resourses/images/exportbox.png b/Resources/images/exportbox.png similarity index 100% rename from Resourses/images/exportbox.png rename to Resources/images/exportbox.png diff --git a/Resourses/images/exportmenu.png b/Resources/images/exportmenu.png similarity index 100% rename from Resourses/images/exportmenu.png rename to Resources/images/exportmenu.png diff --git a/Resources/images/findmenu.png b/Resources/images/findmenu.png new file mode 100644 index 00000000..e33e866f Binary files /dev/null and b/Resources/images/findmenu.png differ diff --git a/Resources/images/findmenu@2x.png b/Resources/images/findmenu@2x.png new file mode 100644 index 00000000..67371748 Binary files /dev/null and b/Resources/images/findmenu@2x.png differ diff --git a/Resourses/images/importbox.png b/Resources/images/importbox.png similarity index 100% rename from Resourses/images/importbox.png rename to Resources/images/importbox.png diff --git a/Resourses/images/importmenu.png b/Resources/images/importmenu.png similarity index 100% rename from Resourses/images/importmenu.png rename to Resources/images/importmenu.png diff --git a/Resources/images/indexmenu.png b/Resources/images/indexmenu.png new file mode 100644 index 00000000..fc6014ca Binary files /dev/null and b/Resources/images/indexmenu.png differ diff --git a/Resources/images/indexmenu@2x.png b/Resources/images/indexmenu@2x.png new file mode 100644 index 00000000..75add64b Binary files /dev/null and b/Resources/images/indexmenu@2x.png differ diff --git a/Resources/images/insertmenu.png b/Resources/images/insertmenu.png new file mode 100644 index 00000000..3e119853 Binary files /dev/null and b/Resources/images/insertmenu.png differ diff --git a/Resources/images/insertmenu@2x.png b/Resources/images/insertmenu@2x.png new file mode 100644 index 00000000..fd7fe8e3 Binary files /dev/null and b/Resources/images/insertmenu@2x.png differ diff --git a/Resourses/images/key.png b/Resources/images/key.png similarity index 100% rename from Resourses/images/key.png rename to Resources/images/key.png diff --git a/Resources/images/mapreducemenu.png b/Resources/images/mapreducemenu.png new file mode 100644 index 00000000..66403640 Binary files /dev/null and b/Resources/images/mapreducemenu.png differ diff --git a/Resources/images/mapreducemenu@2x.png b/Resources/images/mapreducemenu@2x.png new file mode 100644 index 00000000..f0cf61d5 Binary files /dev/null and b/Resources/images/mapreducemenu@2x.png differ diff --git a/Resourses/images/mongohub.ai b/Resources/images/mongohub.ai similarity index 100% rename from Resourses/images/mongohub.ai rename to Resources/images/mongohub.ai diff --git a/Resources/images/querymenu.png b/Resources/images/querymenu.png new file mode 100644 index 00000000..aa873472 Binary files /dev/null and b/Resources/images/querymenu.png differ diff --git a/Resources/images/querymenu@2x.png b/Resources/images/querymenu@2x.png new file mode 100644 index 00000000..95df3056 Binary files /dev/null and b/Resources/images/querymenu@2x.png differ diff --git a/Resources/images/removemenu.png b/Resources/images/removemenu.png new file mode 100644 index 00000000..2854d97f Binary files /dev/null and b/Resources/images/removemenu.png differ diff --git a/Resources/images/removemenu@2x.png b/Resources/images/removemenu@2x.png new file mode 100644 index 00000000..afed8845 Binary files /dev/null and b/Resources/images/removemenu@2x.png differ diff --git a/Resourses/images/runmenu.png b/Resources/images/runmenu.png similarity index 100% rename from Resourses/images/runmenu.png rename to Resources/images/runmenu.png diff --git a/Resourses/images/servermenu.png b/Resources/images/servermenu.png similarity index 100% rename from Resourses/images/servermenu.png rename to Resources/images/servermenu.png diff --git a/Resourses/images/supportmenu.png b/Resources/images/supportmenu.png similarity index 100% rename from Resourses/images/supportmenu.png rename to Resources/images/supportmenu.png diff --git a/Resources/images/tabs/background-grey_center.png b/Resources/images/tabs/background-grey_center.png new file mode 100644 index 00000000..015603fc Binary files /dev/null and b/Resources/images/tabs/background-grey_center.png differ diff --git a/Resources/images/tabs/background-grey_center@2x.png b/Resources/images/tabs/background-grey_center@2x.png new file mode 100644 index 00000000..3872e3d9 Binary files /dev/null and b/Resources/images/tabs/background-grey_center@2x.png differ diff --git a/Resources/images/tabs/background-grey_left.png b/Resources/images/tabs/background-grey_left.png new file mode 100644 index 00000000..7b037336 Binary files /dev/null and b/Resources/images/tabs/background-grey_left.png differ diff --git a/Resources/images/tabs/background-grey_left@2x.png b/Resources/images/tabs/background-grey_left@2x.png new file mode 100644 index 00000000..e89409aa Binary files /dev/null and b/Resources/images/tabs/background-grey_left@2x.png differ diff --git a/Resources/images/tabs/background-grey_right.png b/Resources/images/tabs/background-grey_right.png new file mode 100644 index 00000000..da36bd45 Binary files /dev/null and b/Resources/images/tabs/background-grey_right.png differ diff --git a/Resources/images/tabs/background-grey_right@2x.png b/Resources/images/tabs/background-grey_right@2x.png new file mode 100644 index 00000000..071a333e Binary files /dev/null and b/Resources/images/tabs/background-grey_right@2x.png differ diff --git a/Resources/images/tabs/background_blue_arrow.png b/Resources/images/tabs/background_blue_arrow.png new file mode 100644 index 00000000..059db95a Binary files /dev/null and b/Resources/images/tabs/background_blue_arrow.png differ diff --git a/Resources/images/tabs/background_blue_arrow@2x.png b/Resources/images/tabs/background_blue_arrow@2x.png new file mode 100644 index 00000000..4fe934a9 Binary files /dev/null and b/Resources/images/tabs/background_blue_arrow@2x.png differ diff --git a/Resources/images/tabs/background_blue_center.png b/Resources/images/tabs/background_blue_center.png new file mode 100644 index 00000000..a267ecbc Binary files /dev/null and b/Resources/images/tabs/background_blue_center.png differ diff --git a/Resources/images/tabs/background_blue_center@2x.png b/Resources/images/tabs/background_blue_center@2x.png new file mode 100644 index 00000000..3dd2daaa Binary files /dev/null and b/Resources/images/tabs/background_blue_center@2x.png differ diff --git a/Resources/images/tabs/background_blue_left.png b/Resources/images/tabs/background_blue_left.png new file mode 100644 index 00000000..fbbc732d Binary files /dev/null and b/Resources/images/tabs/background_blue_left.png differ diff --git a/Resources/images/tabs/background_blue_left@2x.png b/Resources/images/tabs/background_blue_left@2x.png new file mode 100644 index 00000000..c5a050e8 Binary files /dev/null and b/Resources/images/tabs/background_blue_left@2x.png differ diff --git a/Resources/images/tabs/background_blue_right.png b/Resources/images/tabs/background_blue_right.png new file mode 100644 index 00000000..852fdfe5 Binary files /dev/null and b/Resources/images/tabs/background_blue_right.png differ diff --git a/Resources/images/tabs/background_blue_right@2x.png b/Resources/images/tabs/background_blue_right@2x.png new file mode 100644 index 00000000..a18b1376 Binary files /dev/null and b/Resources/images/tabs/background_blue_right@2x.png differ diff --git a/Resources/images/tabs/button_ArrowRight_default.png b/Resources/images/tabs/button_ArrowRight_default.png new file mode 100644 index 00000000..124efe89 Binary files /dev/null and b/Resources/images/tabs/button_ArrowRight_default.png differ diff --git a/Resources/images/tabs/button_ArrowRight_default@2x.png b/Resources/images/tabs/button_ArrowRight_default@2x.png new file mode 100644 index 00000000..20041b17 Binary files /dev/null and b/Resources/images/tabs/button_ArrowRight_default@2x.png differ diff --git a/Resources/images/tabs/button_ArrowRight_overlay.png b/Resources/images/tabs/button_ArrowRight_overlay.png new file mode 100644 index 00000000..45bd4199 Binary files /dev/null and b/Resources/images/tabs/button_ArrowRight_overlay.png differ diff --git a/Resources/images/tabs/button_ArrowRight_overlay@2x.png b/Resources/images/tabs/button_ArrowRight_overlay@2x.png new file mode 100644 index 00000000..acc5aa8d Binary files /dev/null and b/Resources/images/tabs/button_ArrowRight_overlay@2x.png differ diff --git a/Resources/images/tabs/close_button.png b/Resources/images/tabs/close_button.png new file mode 100644 index 00000000..098c4836 Binary files /dev/null and b/Resources/images/tabs/close_button.png differ diff --git a/Resources/images/tabs/close_button@2x.png b/Resources/images/tabs/close_button@2x.png new file mode 100644 index 00000000..66c27c9b Binary files /dev/null and b/Resources/images/tabs/close_button@2x.png differ diff --git a/Resources/images/tabs/grip_button.png b/Resources/images/tabs/grip_button.png new file mode 100644 index 00000000..a1efa7ba Binary files /dev/null and b/Resources/images/tabs/grip_button.png differ diff --git a/Resources/images/tabs/grip_button@2x.png b/Resources/images/tabs/grip_button@2x.png new file mode 100644 index 00000000..d1d02869 Binary files /dev/null and b/Resources/images/tabs/grip_button@2x.png differ diff --git a/Resources/images/tabs/overlay_close_button.png b/Resources/images/tabs/overlay_close_button.png new file mode 100644 index 00000000..60170cd2 Binary files /dev/null and b/Resources/images/tabs/overlay_close_button.png differ diff --git a/Resources/images/tabs/overlay_close_button@2x.png b/Resources/images/tabs/overlay_close_button@2x.png new file mode 100644 index 00000000..41b524f2 Binary files /dev/null and b/Resources/images/tabs/overlay_close_button@2x.png differ diff --git a/Resources/images/tabs/unselected-tab-background.png b/Resources/images/tabs/unselected-tab-background.png new file mode 100644 index 00000000..8c4adfc4 Binary files /dev/null and b/Resources/images/tabs/unselected-tab-background.png differ diff --git a/Resources/images/tabs/unselected-tab-background@2x.png b/Resources/images/tabs/unselected-tab-background@2x.png new file mode 100644 index 00000000..32fea3b3 Binary files /dev/null and b/Resources/images/tabs/unselected-tab-background@2x.png differ diff --git a/Resources/images/tabs/unselected-tab-border.png b/Resources/images/tabs/unselected-tab-border.png new file mode 100644 index 00000000..acb25acc Binary files /dev/null and b/Resources/images/tabs/unselected-tab-border.png differ diff --git a/Resources/images/tabs/unselected-tab-border@2x.png b/Resources/images/tabs/unselected-tab-border@2x.png new file mode 100644 index 00000000..a7964bb0 Binary files /dev/null and b/Resources/images/tabs/unselected-tab-border@2x.png differ diff --git a/Resources/mongohub_su_feed.xml b/Resources/mongohub_su_feed.xml new file mode 100644 index 00000000..4bbb8858 --- /dev/null +++ b/Resources/mongohub_su_feed.xml @@ -0,0 +1,87 @@ + + + + MongoHub + https://mongohub.s3.amazonaws.com/mongohub_su_feed.xml + Most recent changes with links to updates. + en + + Version 3.1.4 + + 3.1.4 +
    +
  • Fixing issue to get indexes with Mongodb 3.0 issue #199
  • +
+

3.1.3

+
    +
  • Issue with 10.9 to double click on a document, thanks to Sergey Basmanov
  • +
+

3.1.2

+
    +
  • Fix issue to edit only selected documents in the Find tab
  • +
+

3.1.1

+
    +
  • Make aggregation tab be the default
  • +
+

3.1

+
    +
  • Crash fix for issue #200
  • +
  • Fix to create a new database with mongodb 3.0 issue #203
  • +
  • Better json editor feedback, when saving a document issue #201
  • +
  • Support for Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NaN issue #206
  • +
  • Parse correctly keys in a document (now, accepts numbers without quotes)
  • +
  • Fix for SCRAM authentification in Mongo 3.0 issue #200
  • +
  • Documents are copied inside an array (using the pasteboard) issue #195
  • +
  • Fix for a crash when the server is not valid issue #196
  • +
  • Fix for a crash when changingn the collection name issue #193
  • +
  • Fix for a crash when editing a document issue #198
  • +
  • Better parsing errors in the aggregation tab
  • +
  • Avoiding some crashes in the aggregation tab
  • +
  • Can copy documents in the Find tab
  • +
  • Adding support for full screen in a connection window issue #175
  • +
  • Adding a preference for the default sort order in the Find tab issue #129
  • +
  • Adding a preference to present keys sorted in the Find tab issue #77
  • +
  • Display errors from import/export
  • +
  • Can import more than 200 documents issue #172
  • +
  • Fix for a crash when the ssh drops issue #171
  • +
  • New UI to create/drop indexes issue #178
  • +
  • Removed duplicate collection name when generating displayed query in the find tab [pul #184](https://github.com/jeromelebel/MongoHub-Mac/pull/184, thanks to Steve Steiner
  • +
  • Showing dates in the outline view in local time zone issue #174
  • +
  • Fix to export to mysql
  • +
  • Can insert multiple documents in the insert tab with [ { document1 }, { document2 }, ... ]
  • +
  • Dropping support for 10.7
  • +
  • Dropping support for 32bits
  • +
  • Don't open a contextual menu if a sheet is opened issue #183
  • +
  • Crash fixed to parse wrong regexp in a json issue #191
  • +
  • Mongo C Driver 1.1.2
  • +
  • Fix to make MongoHub usable again for services like Compose.io/MongoHQ, thanks to Travis Choma
  • +
+ ]]> +
+
+
+ + MongoHub Beta + https://mongohub.s3.amazonaws.com/mongohub_su_feed.xml + Beta updates. + en + + 1 + Version 3.1.5 beta 1 + + 3.1.5 beta 1 +
    +
  • mongo-c-driver 1.1.4
  • +
  • Adding a menu "Add Connection With URL…" issue #108
  • +
  • Making sure all menu items are disabled when they should not be used
  • +
  • Issue to get the document count in the aggregation result
  • +
  • Can copy documents with OS X 10.8 and 10.9 thanks to Sergey Basmanov
  • +
+ ]]> +
+
+
+
\ No newline at end of file diff --git a/Resourses/images/editicon.png b/Resourses/images/editicon.png deleted file mode 100644 index c06454f6..00000000 Binary files a/Resourses/images/editicon.png and /dev/null differ diff --git a/Resourses/images/findmenu.png b/Resourses/images/findmenu.png deleted file mode 100644 index acb5a1c3..00000000 Binary files a/Resourses/images/findmenu.png and /dev/null differ diff --git a/Resourses/images/indexmenu.png b/Resourses/images/indexmenu.png deleted file mode 100644 index 1dca45da..00000000 Binary files a/Resourses/images/indexmenu.png and /dev/null differ diff --git a/Resourses/images/insertmenu.png b/Resourses/images/insertmenu.png deleted file mode 100644 index 6dec06e1..00000000 Binary files a/Resourses/images/insertmenu.png and /dev/null differ diff --git a/Resourses/images/mapreducemenu.png b/Resourses/images/mapreducemenu.png deleted file mode 100644 index dcfc33e0..00000000 Binary files a/Resourses/images/mapreducemenu.png and /dev/null differ diff --git a/Resourses/images/querymenu.png b/Resourses/images/querymenu.png deleted file mode 100644 index f2a4c746..00000000 Binary files a/Resourses/images/querymenu.png and /dev/null differ diff --git a/Resourses/images/removemenu.png b/Resourses/images/removemenu.png deleted file mode 100644 index 0050f49c..00000000 Binary files a/Resourses/images/removemenu.png and /dev/null differ diff --git a/Resourses/images/updatemenu.png b/Resourses/images/updatemenu.png deleted file mode 100644 index 9303ae33..00000000 Binary files a/Resourses/images/updatemenu.png and /dev/null differ diff --git a/ResultsOutlineViewController.h b/ResultsOutlineViewController.h deleted file mode 100644 index 3f946e8f..00000000 --- a/ResultsOutlineViewController.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// ResultsOutlineViewController.h -// MongoHub -// -// Created by Syd on 10-4-26. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import - - -@interface ResultsOutlineViewController : NSObject{ - IBOutlet NSOutlineView *myOutlineView; - NSMutableArray *results; -} - -@property (nonatomic, retain) NSOutlineView *myOutlineView; -@property (nonatomic, retain) NSMutableArray *results; - -- (id)rootForItem:(id)item; - -@end diff --git a/ResultsOutlineViewController.m b/ResultsOutlineViewController.m deleted file mode 100644 index f4a1131c..00000000 --- a/ResultsOutlineViewController.m +++ /dev/null @@ -1,151 +0,0 @@ -// -// ResultsOutlineViewController.m -// MongoHub -// -// Created by Syd on 10-4-26. -// Copyright 2010 MusicPeace.ORG. All rights reserved. -// - -#import "ResultsOutlineViewController.h" - -@implementation ResultsOutlineViewController - -@synthesize myOutlineView; -@synthesize results; - -- (id)init -{ - if (self = [super init]) { - results = [[NSMutableArray alloc] init]; - } - - return self; -} - -- (void)dealloc { - [myOutlineView deselectAll:nil]; - [myOutlineView release]; - [results release]; - [super dealloc]; -} - -- (void)awakeFromNib -{ - [myOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; -} - -#pragma mark - -#pragma mark NSOutlineView dataSource methods - -// Returns the child item at the specified index of a given item. -- (id)outlineView:(NSOutlineView *)outlineView - child:(int)index - ofItem:(id)item -{ - // If the item is the root item, return the corresponding mailbox object - if([outlineView levelForItem:item] == -1) - { - return [results objectAtIndex:index]; - } - - // If the item is a root-level item (ie mailbox) - return [[item objectForKey:@"child" ] objectAtIndex:index]; -} - -// Returns a Boolean value that indicates wheter a given item is expandable. -- (BOOL)outlineView:(NSOutlineView *)outlineView - isItemExpandable:(id)item -{ - // If the item is a root-level item (ie mailbox) and it has emails in it, return true - if(([[item objectForKey:@"child"] count] != 0)) - return true; - - else - return false; -} - -// Returns the number of child items encompassed by a given item. -- (int)outlineView:(NSOutlineView *)outlineView -numberOfChildrenOfItem:(id)item -{ - // If the item is the root item, return the number of mailboxes - if([outlineView levelForItem:item] == -1) - { - return [results count]; - } - // If the item is a root-level item (ie mailbox) - return [[item objectForKey:@"child" ] count]; -} - -// Return the data object associated with the specified item. -- (id)outlineView:(NSOutlineView *)outlineView -objectValueForTableColumn:(NSTableColumn *)tableColumn - byItem:(id)item -{ - if([[tableColumn identifier] isEqualToString:@"name"]) - { - return [item objectForKey:@"name"]; - } - - else if([[tableColumn identifier] isEqualToString:@"value"]) - return [item objectForKey:@"value"]; - else if([[tableColumn identifier] isEqualToString:@"type"]) - return [item objectForKey:@"type"]; - /*switch([outlineView levelForItem:item]) - { - // If the item is a root-level item - case 0: - if([[tableColumn identifier] isEqualToString:@"name"]) - return [item objectForKey:@"name" ]; - break; - - case 1: - if([[tableColumn identifier] isEqualToString:@"name"]) - { - return [item objectForKey:@"name"]; - } - - else if([[tableColumn identifier] isEqualToString:@"value"]) - return [item objectForKey:@"value"]; - else if([[tableColumn identifier] isEqualToString:@"type"]) - return [item objectForKey:@"type"]; - break; - }*/ - - return nil; -} - -#pragma mark - -#pragma mark NSOutlineView delegate methods -- (void)outlineViewSelectionDidChange:(NSNotification *)notification -{ - switch([myOutlineView selectedRow]) - { - case -1: - break; - default:{ - id currentItem = [myOutlineView itemAtRow:[myOutlineView selectedRow]]; - if ([myOutlineView isItemExpanded:currentItem]) { - [myOutlineView collapseItem:currentItem collapseChildren:YES]; - }else { - [myOutlineView expandItem:currentItem expandChildren:YES]; - } - break; - } - } -} - - -#pragma mark helper methods -- (id)rootForItem:(id)item -{ - id parentItem = [myOutlineView parentForItem:item]; - if (parentItem) { - return [self rootForItem:parentItem]; - }else { - return item; - } - -} - -@end diff --git a/Sidebar/Sidebar.h b/Sidebar/Sidebar.h deleted file mode 100644 index 92fa2e4e..00000000 --- a/Sidebar/Sidebar.h +++ /dev/null @@ -1,117 +0,0 @@ -// -// SidebarNode.m -// Sidebar -// -// Created by Matteo Bertozzi on 3/8/09. -// Copyright 2009 Matteo Bertozzi. All rights reserved. -// - -#import - -@interface Sidebar : NSOutlineView -{ - @private - NSArray *dragNodesArray; - - id _defaultActionTarget; - SEL _defaultAction; - - NSMutableDictionary *_contents; - NSMutableArray *_roots; -} - -// Set Default Item Clicked Handler -- (void)setDefaultAction:(SEL)action target:(id)target; - - -// Add Root Folder Methods -- (void)addSection:(id)key - caption:(NSString *)folderCaption; - -// Add Child Methods -- (void)addChild:(id)parentKey - key:(id)key - url:(NSString *)url; - -- (void)addChild:(id)parentKey - key:(id)key - url:(NSString *)url - action:(SEL)aSelector - target:(id)target; - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon; - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - action:(SEL)aSelector - target:(id)target; - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - data:(id)data; - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - data:(id)data - action:(SEL)aSelector - target:(id)target; - -// Insert Child Methods -- (void)insertChild:(id)parentKey - key:(id)key - atIndex:(NSUInteger)index - url:(NSString *)url - action:(SEL)aSelector - target:(id)target; - -- (void)insertChild:(id)parentKey - key:(id)key - atIndex:(NSUInteger)index - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - action:(SEL)aSelector - target:(id)target; - -- (void)insertChild:(id)parentKey - key:(id)key - atIndex:(NSUInteger)index - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - data:(id)data - action:(SEL)aSelector - target:(id)target; - -// Remove Methods -- (void)removeItem:(id)key; -- (void)removeChild:(id)key; -- (void)removeFolder:(id)key; -- (void)removeSection:(id)key; - -// Selection Methods -- (void)selectItem:(id)key; -- (void)unselectItem; - -// Expand/Collapse Metods -- (void)expandAll; -- (void)expandItem:(id)key; -- (void)expandItem:(id)key expandChildren:(BOOL)expandChildren; - -- (void)collapseAll; -- (void)collapseItem:(id)key; -- (void)collapseItem:(id)key expandChildren:(BOOL)collapseChildren; - -// Set Badge -- (void)setBadge:(id)key count:(NSInteger)badgeValue; -- (void)unsetBadge:(id)key; - -@end - diff --git a/Sidebar/Sidebar.m b/Sidebar/Sidebar.m deleted file mode 100644 index ae5a6b15..00000000 --- a/Sidebar/Sidebar.m +++ /dev/null @@ -1,551 +0,0 @@ -// -// SidebarNode.m -// Sidebar -// -// Created by Matteo Bertozzi on 3/8/09. -// Copyright 2009 Matteo Bertozzi. All rights reserved. -// - -#import "SidebarBadgeCell.h" -#import "SidebarNode.h" -#import "Sidebar.h" - -#define kSidebarPBoardType @"SidebarNodePBoardType" - -@implementation Sidebar - -/* ============================================================================ - * PUBLIC Constructors/Distructors - */ -- (void)dealloc { - [_contents release]; - [_roots release]; - - [super dealloc]; -} - -- (void)awakeFromNib { - _contents = [[NSMutableDictionary alloc] init]; - _roots = [[NSMutableArray alloc] init]; - _defaultActionTarget = nil; - _defaultAction = NULL; - - // Scroll to the top in case the outline contents is very long - [[[self enclosingScrollView] verticalScroller] setFloatValue:0.0]; - [[[self enclosingScrollView] contentView] scrollToPoint:NSMakePoint(0, 0)]; - [self setBackgroundColor:[NSColor colorWithCalibratedRed:0.72 green:0.74 blue:0.79 alpha:1.0]]; - - // Make outline view appear with gradient selection, and behave like the Finder, iTunes, etc. - [self setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList]; - - // drag and drop support - [self registerForDraggedTypes:[NSArray arrayWithObjects:kSidebarPBoardType, nil]]; - - // Sup Delegates & Data Source - [self setDataSource:self]; - [self setDelegate:self]; -} - -- (void)setDefaultAction:(SEL)action target:(id)target { - _defaultAction = action; - _defaultActionTarget = target; -} - -/* ============================================================================ - * PUBLIC Methods (Add Root Folder) - */ -- (void)addSection:(id)key - caption:(NSString *)folderCaption -{ - if ([_contents objectForKey:key] != nil) - [self removeItem:key]; - - // Create and Setup Node - SidebarNode *node = [[SidebarNode alloc] init]; - [node setNodeType:kSidebarNodeTypeSection]; - [node setCaption:folderCaption]; - [node setNodeKey:key]; - - // Add Object to List - [_contents setObject:node forKey:key]; - [_roots addObject:node]; - [node release]; -} - -/* ============================================================================ - * PUBLIC Methods (Add Child) - */ - - (void)addChild:(id)parentKey - key:(id)key - url:(NSString *)url -{ - [self addChild:parentKey key:key url:url action:NULL target:nil]; -} - -- (void)addChild:(id)parentKey - key:(id)key - url:(NSString *)url - action:(SEL)aSelector - target:(id)target -{ - NSString *caption = [[NSFileManager defaultManager] displayNameAtPath:url]; - NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:url]; - - [self addChild:parentKey - key:key - caption:caption - icon:icon - data:url - action:aSelector target:target]; -} - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon -{ - [self addChild:parentKey - key:key - caption:childCaption - icon:childIcon - data:nil - action:NULL target:nil]; -} - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - action:(SEL)aSelector - target:(id)target -{ - [self addChild:parentKey - key:key - caption:childCaption - icon:childIcon - data:nil - action:aSelector target:target]; -} - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - data:(id)data -{ - [self addChild:parentKey - key:key - caption:childCaption - icon:childIcon - data:data - action:NULL target:nil]; -} - -- (void)addChild:(id)parentKey - key:(id)key - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - data:(id)data - action:(SEL)aSelector - target:(id)target -{ - // Create and Setup Node - SidebarNode *node = [[SidebarNode alloc] init]; - [node setAction:aSelector target:target]; - [node setNodeType:kSidebarNodeTypeItem]; - [node setCaption:childCaption]; - [node setParentKey:parentKey]; - [node setIcon:childIcon]; - [node setNodeKey:key]; - - // Add Node as Child of Root Node - SidebarNode *rootNode = [_contents objectForKey:parentKey]; - if (rootNode != nil) - [rootNode addChild:node]; - else - [_roots addObject:node]; - - // Add Object to List - [_contents setObject:node forKey:key]; - [node release]; -} - -/* ============================================================================ - * PUBLIC Methods (Insert Child) - */ -- (void)insertChild:(id)parentKey - key:(id)key - atIndex:(NSUInteger)index - url:(NSString *)url - action:(SEL)aSelector - target:(id)target -{ - NSString *caption = [[NSFileManager defaultManager] displayNameAtPath:url]; - NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:url]; - - [self insertChild:parentKey - key:key - atIndex:index - caption:caption - icon:icon - data:url - action:aSelector target:target]; -} - -- (void)insertChild:(id)parentKey - key:(id)key - atIndex:(NSUInteger)index - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - action:(SEL)aSelector - target:(id)target -{ - [self insertChild:parentKey - key:key - atIndex:index - caption:childCaption - icon:childIcon - data:nil - action:aSelector target:target]; -} - -- (void)insertChild:(id)parentKey - key:(id)key - atIndex:(NSUInteger)index - caption:(NSString *)childCaption - icon:(NSImage *)childIcon - data:(id)data - action:(SEL)aSelector - target:(id)target -{ - // Create and Setup Node - SidebarNode *node = [[SidebarNode alloc] init]; - [node setAction:aSelector target:target]; - [node setNodeType:kSidebarNodeTypeItem]; - [node setCaption:childCaption]; - [node setParentKey:parentKey]; - [node setIcon:childIcon]; - [node setNodeKey:key]; - - // Add Node as Child of Root Node - SidebarNode *rootNode = [_contents objectForKey:parentKey]; - if (rootNode != nil) - [rootNode insertChild:node atIndex:index]; - else - [_roots addObject:node]; - - // Add Object to List - [_contents setObject:node forKey:key]; - [node release]; -} - -/* ============================================================================ - * PUBLIC Methods (Remove Items) - */ -- (void)removeItem:(id)key { - SidebarNode *node = [_contents objectForKey:key]; - if (node == nil) return; - - id parentKey = [node parentKey]; - if (parentKey != nil) { - SidebarNode *parentNode = [_contents objectForKey:parentKey]; - [parentNode removeChild:node]; - } else { - [_roots removeObject:node]; - } - - [_contents removeObjectForKey:key]; -} - -- (void)removeChild:(id)key { - [self removeItem:key]; -} - -- (void)removeFolder:(id)key { - [self removeItem:key]; -} - -- (void)removeSection:(id)key { - [self removeItem:key]; -} - -/* ============================================================================ - * PUBLIC Methods (Selection) - */ -- (SidebarNode *)selectedNode { - return([self itemAtRow:[self selectedRow]]); -} - -- (void)selectItem:(id)key { - SidebarNode *node = [_contents objectForKey:key]; - if (node != nil && [node nodeType] != kSidebarNodeTypeSection) { - NSInteger rowIndex = [self rowForItem:node]; - if (rowIndex >= 0) [self selectRowIndexes:[NSIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO]; - } -} - -- (void)unselectItem { -} - -/* ============================================================================ - * PUBLIC Methods (Expand/Collapse) - */ -- (void)expandAll { - [super expandItem:nil expandChildren:YES]; -} - -- (void)expandItem:(id)key { - if (key == nil || [key isKindOfClass:[SidebarNode class]]) { - [super expandItem:key]; - } else { - SidebarNode *node = [_contents objectForKey:key]; - if (node != nil && [node nodeType] != kSidebarNodeTypeItem) - [super expandItem:node expandChildren:NO]; - } -} - -- (void)expandItem:(id)key expandChildren:(BOOL)expandChildren { - if (key == nil || [key isKindOfClass:[SidebarNode class]]) { - [super expandItem:key expandChildren:expandChildren]; - } else { - SidebarNode *node = [_contents objectForKey:key]; - if (node != nil && [node nodeType] != kSidebarNodeTypeItem) - [super expandItem:node expandChildren:expandChildren]; - } -} - -- (void)collapseAll { - [super collapseItem:nil collapseChildren:YES]; -} - -- (void)collapseItem:(id)key { - if (key == nil || [key isKindOfClass:[SidebarNode class]]) { - [super collapseItem:key]; - } else { - SidebarNode *node = [_contents objectForKey:key]; - if (node != nil && [node nodeType] != kSidebarNodeTypeItem) - [super collapseItem:node collapseChildren:NO]; - } -} - -- (void)collapseItem:(id)key expandChildren:(BOOL)collapseChildren { - if (key == nil || [key isKindOfClass:[SidebarNode class]]) { - [super collapseItem:key collapseChildren:collapseChildren]; - } else { - SidebarNode *node = [_contents objectForKey:key]; - if (node != nil && [node nodeType] != kSidebarNodeTypeItem) - [super collapseItem:node collapseChildren:collapseChildren]; - } -} - -/* ============================================================================ - * PUBLIC Methods (Badges) - */ -- (void)setBadge:(id)key count:(NSInteger)badgeValue { - SidebarNode *node = [_contents objectForKey:key]; - [node setBadgeValue:badgeValue]; -} - -- (void)unsetBadge:(id)key { - SidebarNode *node = [_contents objectForKey:key]; - [node unsetBadgeValue]; -} - -/* ============================================================================ - * PRIVATE Data Source Delegates - */ - -// The child item at index of a item. -// If item is nil, returns the appropriate child item of the root object. -- (id)outlineView:(NSOutlineView *)outlineView - child:(NSInteger)index - ofItem:(id)item -{ - if (item == nil) - return [_roots objectAtIndex:index]; - return [(SidebarNode *)item childAtIndex:index]; -} - -// Returns a Boolean value that indicates whether in a given item is expandable. -- (BOOL)outlineView:(NSOutlineView *)outlineView - isItemExpandable:(id)item -{ - return((item == nil) ? NO : [item nodeType] != kSidebarNodeTypeItem); -} - -// Returns the number of child items encompassed by a given item. -- (NSInteger)outlineView:(NSOutlineView *)outlineView - numberOfChildrenOfItem:(id)item -{ - return((item == nil) ? [_roots count] : [item numberOfChildren]); -} - -// Invoked by outlineView to return the data object -// associated with the specified item. -- (id)outlineView:(NSOutlineView *)outlineView - objectValueForTableColumn:(NSTableColumn *)tableColumn - byItem:(id)item -{ - return [item caption]; -} - -/* ============================================================================ - * PRIVATE Delegates - */ -- (BOOL)outlineView:(NSOutlineView *)outlineView - shouldSelectItem:(id)item -{ - return([item nodeType] != kSidebarNodeTypeSection); -} - -- (NSCell *)outlineView:(NSOutlineView *)outlineView - dataCellForTableColumn:(NSTableColumn *)tableColumn - item:(id)item -{ - return [tableColumn dataCell]; -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView - shouldEditTableColumn:(NSTableColumn *)tableColumn - item:(id)item -{ - return NO; -} - --(BOOL)outlineView:(NSOutlineView*)outlineView - isGroupItem:(id)item -{ - return([item nodeType] != kSidebarNodeTypeItem); -} - -- (void)outlineView:(NSOutlineView *)outlineView - willDisplayCell:(NSCell*)cell - forTableColumn:(NSTableColumn *)tableColumn - item:(id)item -{ - if ([cell isKindOfClass:[SidebarBadgeCell class]]) { - SidebarBadgeCell *badgeCell = (SidebarBadgeCell *) cell; - [badgeCell setBadgeCount:[item badgeValue]]; - [badgeCell setHasBadge:[item hasBadge]]; - [badgeCell setIcon:[item icon]]; - } -} - -- (void)outlineViewSelectionDidChange:(NSNotification *)notification { - SidebarNode *selectedNode = [self selectedNode]; - if (selectedNode == nil) return; - - SEL action = NULL; - id target = nil; - - if ([selectedNode hasAction]) { - action = [selectedNode action]; - target = [selectedNode actionTarget]; - } else { - action = _defaultAction; - target = _defaultActionTarget; - } - - // Run Thread with selected Action - if (action != NULL) - [NSThread detachNewThreadSelector:action toTarget:target withObject:selectedNode]; -} - -- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { - return([[fieldEditor string] length] > 0); -} - -/* ============================================================================ - * PRIVATE Delegates (Drag & Drop) - */ -- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { - return NSDragOperationMove; -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView - writeItems:(NSArray *)items - toPasteboard:(NSPasteboard *)pboard -{ - [pboard declareTypes:[NSArray arrayWithObjects:kSidebarPBoardType, nil] owner:self]; - - // keep track of this nodes for drag feedback in "validateDrop" - dragNodesArray = items; - - return YES; -} - -- (NSDragOperation)outlineView:(NSOutlineView *)outlineView - validateDrop:(id)info - proposedItem:(id)item - proposedChildIndex:(NSInteger)index -{ - if (item == nil) - return NSDragOperationGeneric; - - if (![item isDraggable] && index >= 0) - return NSDragOperationMove; - - return NSDragOperationNone; -} - -- (BOOL)outlineView:(NSOutlineView*)outlineView - acceptDrop:(id)info - item:(id)targetItem - childIndex:(NSInteger)index -{ - NSPasteboard *pboard = [info draggingPasteboard]; // get the pasteboard - - // user is doing an intra-app drag within the outline view - if ([pboard availableTypeFromArray:[NSArray arrayWithObject:kSidebarPBoardType]]) { - id targetKey = (targetItem != nil) ? [targetItem nodeKey] : nil; - - for (NSInteger i = 0; i < [dragNodesArray count]; ++i) { - SidebarNode *node = [dragNodesArray objectAtIndex:i]; - - // Get Adjust Index Value - NSInteger adjIdx = 0; - if (targetKey != nil && [node parentKey] == targetKey && [targetItem indexOfChild:node] < index) - adjIdx = -1; - - // Remove From Current Position - if ([node parentKey] != nil) { - SidebarNode *parentNode = [_contents objectForKey:[node parentKey]]; - [parentNode removeChild:node]; - } else { - [_roots removeObject:node]; - } - - // Update Parent Key && Insert Item at New Location - [node setParentKey:targetKey]; - if (targetKey != nil) { - [((SidebarNode *)targetItem) insertChild:node atIndex:(index + i + adjIdx)]; - } else if (index < 0) { - [_roots addObject:node]; - } else { - [_roots insertObject:node atIndex:index]; - } - } - - [self reloadData]; - return YES; - } - - return NO; -} - -- (NSUInteger)hitTestForEvent:(NSEvent *)event - inRect:(NSRect)cellFrame - ofView:(NSView *)controlView -{ - if ([controlView isKindOfClass:[Sidebar class]]) { - Sidebar *sidebar = (Sidebar *) controlView; - SidebarNode *node = [sidebar selectedNode]; - if (![node isDraggable]) - return NSCellHitTrackableArea; - } - - return NSCellHitContentArea; -} - -@end - diff --git a/Sidebar/SidebarBadgeCell.m b/Sidebar/SidebarBadgeCell.m deleted file mode 100644 index 558f5a15..00000000 --- a/Sidebar/SidebarBadgeCell.m +++ /dev/null @@ -1,147 +0,0 @@ -// -// TSBadgeCell.m -// Tahsis -// -// Created by Matteo Bertozzi on 11/29/08. -// Copyright 2008 Matteo Bertozzi. All rights reserved. -// - -#import "SidebarBadgeCell.h" - -@interface SidebarBadgeCell (Private) -- (CGFloat)drawBadge:(NSRect)cellFrame; -@end - -@implementation SidebarBadgeCell - -#define TSBADGECELL_BUFFER_LEFT_SMALL 2 -#define TSBADGECELL_BUFFER_LEFT 4 -#define TSBADGECELL_BUFFER_SIDE 3 -#define TSBADGECELL_BUFFER_TOP 3 -#define TSBADGECELL_PADDING 6 - -#define TSBADGECELL_CIRCLE_BUFFER_RIGHT 5 - -#define TSBADGECELL_RADIUS_X 7 -#define TSBADGECELL_RADIUS_Y 8 - -#define TSBADGECELL_TEXT_HEIGHT 14 -#define TSBADGECELL_TEXT_MINI 8 -#define TSBADGECELL_TEXT_SMALL 20 - -#define TSBADGECELL_ICON_SIZE 16 -#define TSBADGECELL_ICON_HEIGHT_OFFSET 2 - -@synthesize badgeCount = _badgeCount; -@synthesize hasBadge = _hasBadge; -@synthesize icon = _icon; - -- (void)dealloc { - [_icon release]; - [super dealloc]; -} - -- (void)awakeFromNib { - [self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - _badgeCount = 0; - _hasBadge = NO; - _icon = nil; -} - -- (id)copyWithZone:(NSZone*)zone { - SidebarBadgeCell *cell = [super copyWithZone:zone]; - cell->_icon = [_icon retain]; - return cell; -} - -- (void)setIcon:(NSImage *)icon { - if (_icon != icon) { - [_icon release]; - _icon = [icon retain]; - [_icon setFlipped:YES]; - [_icon setSize:NSMakeSize(TSBADGECELL_ICON_SIZE, TSBADGECELL_ICON_SIZE)]; - } -} - -- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { - bool drawBadge = (_hasBadge && cellFrame.size.width > TSBADGECELL_TEXT_SMALL * 3); - CGFloat badgeWidth = (drawBadge ? [self drawBadge:cellFrame] : 0); - - if (_icon != nil) { - // Draw Icon - NSRect iconRect = cellFrame; - iconRect.origin.y += TSBADGECELL_ICON_HEIGHT_OFFSET; - iconRect.size.height = TSBADGECELL_ICON_SIZE; - iconRect.size.width = TSBADGECELL_ICON_SIZE; - [_icon drawInRect:iconRect fromRect:NSZeroRect - operation:NSCompositeSourceOver fraction:1.0]; - - // Draw Rect - NSRect labelRect = cellFrame; - labelRect.origin.x += TSBADGECELL_ICON_SIZE + TSBADGECELL_BUFFER_LEFT; - labelRect.size.width -= (badgeWidth + TSBADGECELL_ICON_SIZE + TSBADGECELL_BUFFER_LEFT); - [super drawInteriorWithFrame:labelRect inView:controlView]; - } else { - NSRect labelRect = cellFrame; - labelRect.size.width -= badgeWidth; - [super drawInteriorWithFrame:labelRect inView:controlView]; - } -} - -- (CGFloat)drawBadge:(NSRect)cellFrame { - // Setup Badge String and Size - NSString *badge = [[NSString alloc] initWithFormat:@"%d", _badgeCount]; - NSSize badgeNumSize = [badge sizeWithAttributes:nil]; - NSFont *badgeFont = [self font]; - - // Calculate the Badge's coordinate - CGFloat badgeWidth = badgeNumSize.width + TSBADGECELL_BUFFER_SIDE * 2; - if (badgeNumSize.width < TSBADGECELL_TEXT_MINI) - badgeWidth = TSBADGECELL_TEXT_SMALL; - - CGFloat badgeY = cellFrame.origin.y + TSBADGECELL_BUFFER_TOP; - CGFloat badgeX = cellFrame.origin.x + cellFrame.size.width - - TSBADGECELL_CIRCLE_BUFFER_RIGHT - badgeWidth; - CGFloat badgeNumX = badgeX + TSBADGECELL_BUFFER_LEFT; - if (badgeNumSize.width < TSBADGECELL_TEXT_MINI) - badgeNumX += TSBADGECELL_BUFFER_LEFT_SMALL; - - // Draw the badge and number - NSRect badgeRect = NSMakeRect(badgeX, badgeY, badgeWidth, TSBADGECELL_TEXT_HEIGHT); - NSBezierPath *badgePath = [NSBezierPath bezierPathWithRoundedRect:badgeRect - xRadius:TSBADGECELL_RADIUS_X - yRadius:TSBADGECELL_RADIUS_Y]; - - BOOL isWindowFront = [[NSApp mainWindow] isVisible]; - BOOL isViewInFocus = [[[[self controlView] window] firstResponder] isEqual:[self controlView]]; - BOOL isCellHighlighted = [self isHighlighted]; - - NSDictionary *dict = [[NSMutableDictionary alloc] init]; - [dict setValue:badgeFont forKey:NSFontAttributeName]; - - if (isWindowFront && isViewInFocus && isCellHighlighted) { - [[NSColor whiteColor] set]; - [dict setValue:[NSColor alternateSelectedControlColor] forKey:NSForegroundColorAttributeName]; - } else if (isWindowFront && isViewInFocus && !isCellHighlighted) { - [[NSColor colorWithCalibratedRed:0.53 green:0.60 blue:0.74 alpha:1.0] set]; - [dict setValue:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; - } else if (isWindowFront && isCellHighlighted) { - [[NSColor whiteColor] set]; - [dict setValue:[NSColor colorWithCalibratedRed:0.51 green:0.58 blue:0.72 alpha:1.0] forKey:NSForegroundColorAttributeName]; - } else if (!isWindowFront && isCellHighlighted) { - [[NSColor whiteColor] set]; - [dict setValue:[NSColor disabledControlTextColor] forKey:NSForegroundColorAttributeName]; - } else { - [[NSColor disabledControlTextColor] set]; - [dict setValue:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; - } - - [badgePath fill]; - [badge drawAtPoint:NSMakePoint(badgeNumX, badgeY) withAttributes:dict]; - - [badge release]; - [dict release]; - return badgeWidth + TSBADGECELL_PADDING; -} - -@end diff --git a/Sidebar/SidebarNode.h b/Sidebar/SidebarNode.h deleted file mode 100644 index 0740ef88..00000000 --- a/Sidebar/SidebarNode.h +++ /dev/null @@ -1,62 +0,0 @@ -// -// SidebarNode.h -// Sidebar -// -// Created by Matteo Bertozzi on 3/8/09. -// Copyright 2009 Matteo Bertozzi. All rights reserved. -// - -#import - -#define kSidebarNodeTypeSection 0x01 -#define kSidebarNodeTypeFolder 0x02 -#define kSidebarNodeTypeItem 0x03 - -@interface SidebarNode : NSObject { - NSMutableArray *children; - id parentKey; - id nodeKey; - - NSString *caption; - NSImage *icon; - int nodeType; - id data; - - NSInteger badgeValue; - BOOL hasBadge; - - id actionTarget; - SEL action; -} - -@property (assign, readonly) id actionTarget; -@property (assign, readonly) SEL action; - -@property (assign, readonly) NSInteger badgeValue; -@property (assign, readonly) BOOL hasBadge; - -@property (retain) NSString *caption; -@property (retain) NSImage *icon; -@property (assign) id parentKey; -@property (assign) int nodeType; -@property (assign) id nodeKey; -@property (retain) id data; - -- (void)setAction:(SEL)aSelector target:(id)target; -- (BOOL)hasAction; - -- (void)setBadgeValue:(NSInteger)value; -- (void)unsetBadgeValue; - -- (void)addChild:(SidebarNode *)node; -- (void)insertChild:(SidebarNode *)node atIndex:(NSUInteger)index; -- (void)removeChild:(SidebarNode *)node; -- (NSInteger)indexOfChild:(SidebarNode *)node; - -- (SidebarNode *)childAtIndex:(int)index; - -- (NSUInteger)numberOfChildren; - -- (BOOL)isDraggable; - -@end diff --git a/Sidebar/SidebarNode.m b/Sidebar/SidebarNode.m deleted file mode 100644 index a8c252fb..00000000 --- a/Sidebar/SidebarNode.m +++ /dev/null @@ -1,91 +0,0 @@ -// -// SidebarNode.m -// Sidebar -// -// Created by Matteo Bertozzi on 3/8/09. -// Copyright 2009 Matteo Bertozzi. All rights reserved. -// - -#import "SidebarNode.h" - -@implementation SidebarNode - -@synthesize actionTarget; -@synthesize action; - -@synthesize badgeValue; -@synthesize hasBadge; - -@synthesize parentKey; -@synthesize nodeType; -@synthesize nodeKey; -@synthesize caption; -@synthesize icon; -@synthesize data; - -- (id)init { - if ((self = [super init])) { - children = [[NSMutableArray alloc] init]; - hasBadge = NO; - } - - return self; -} - -- (void)dealloc { - [children release]; - - [caption release]; - [icon release]; - [data release]; - - [super dealloc]; -} - -- (void)setAction:(SEL)aSelector target:(id)target { - actionTarget = target; - action = aSelector; -} - -- (BOOL)hasAction { - return(action != NULL); -} - -- (void)setBadgeValue:(NSInteger)value { - hasBadge = YES; - badgeValue = value; -} - -- (void)unsetBadgeValue { - hasBadge = NO; -} - -- (void)addChild:(SidebarNode *)node { - [children addObject:node]; -} - -- (void)insertChild:(SidebarNode *)node atIndex:(NSUInteger)index { - [children insertObject:node atIndex:index]; -} - -- (void)removeChild:(SidebarNode *)node { - [children removeObject:node]; -} - -- (NSInteger)indexOfChild:(SidebarNode *)node { - return [children indexOfObject:node]; -} - -- (SidebarNode *)childAtIndex:(int)index { - return([children objectAtIndex:index]); -} - -- (NSUInteger)numberOfChildren { - return([children count]); -} - -- (BOOL)isDraggable { - return(nodeType != kSidebarNodeTypeSection); -} - -@end diff --git a/ConnectionsArrayController.h b/Sources/ArrayControllers/ConnectionsArrayController.h similarity index 90% rename from ConnectionsArrayController.h rename to Sources/ArrayControllers/ConnectionsArrayController.h index e5b264ab..d8e909df 100644 --- a/ConnectionsArrayController.h +++ b/Sources/ArrayControllers/ConnectionsArrayController.h @@ -1,5 +1,5 @@ // -// DatabasesArrayController.h +// ConnectionsArrayController.h // MongoHub // // Created by Syd on 10-4-24. diff --git a/ConnectionsArrayController.m b/Sources/ArrayControllers/ConnectionsArrayController.m similarity index 77% rename from ConnectionsArrayController.m rename to Sources/ArrayControllers/ConnectionsArrayController.m index 0fc6c610..a479c1af 100644 --- a/ConnectionsArrayController.m +++ b/Sources/ArrayControllers/ConnectionsArrayController.m @@ -1,5 +1,5 @@ // -// DatabasesArrayController.m +// ConnectionsArrayController.m // MongoHub // // Created by Syd on 10-4-24. @@ -13,19 +13,10 @@ @implementation ConnectionsArrayController - (void)awakeFromNib { - if ([NSArrayController instancesRespondToSelector:@selector(awakeFromNib)]) - { - [super awakeFromNib]; - } - [self setClearsFilterPredicateOnInsertion:NO]; -} - -- (id)newObject -{ - id newObj = [super newObject]; - //NSDate *now = [NSDate date]; - //[newObj setValue:now forKey:@"createdDatetime"]; - return newObj; + if ([NSArrayController instancesRespondToSelector:@selector(awakeFromNib)]) { + [super awakeFromNib]; + } + [self setClearsFilterPredicateOnInsertion:NO]; } - (void)remove:(id)sender diff --git a/FieldMapTableController.h b/Sources/ArrayControllers/FieldMapTableController.h similarity index 92% rename from FieldMapTableController.h rename to Sources/ArrayControllers/FieldMapTableController.h index deb9c985..e8e9cc25 100644 --- a/FieldMapTableController.h +++ b/Sources/ArrayControllers/FieldMapTableController.h @@ -22,7 +22,7 @@ - (void)addRow:(FieldMapDataObject *)pDataObj; -- (int)numberOfRowsInTableView:(NSTableView *)pTableViewObj; +- (NSUInteger)numberOfRowsInTableView:(NSTableView *)pTableViewObj; - (id) tableView:(NSTableView *)pTableViewObj objectValueForTableColumn:(NSTableColumn *)pTableColumn diff --git a/FieldMapTableController.m b/Sources/ArrayControllers/FieldMapTableController.m similarity index 97% rename from FieldMapTableController.m rename to Sources/ArrayControllers/FieldMapTableController.m index f50f6dbd..97e3ef84 100644 --- a/FieldMapTableController.m +++ b/Sources/ArrayControllers/FieldMapTableController.m @@ -48,7 +48,7 @@ - (void)addRow:(FieldMapDataObject *)pDataObj { } // end addRow -- (int)numberOfRowsInTableView:(NSTableView *)pTableViewObj { +- (NSUInteger)numberOfRowsInTableView:(NSTableView *)pTableViewObj { return [self.nsMutaryDataObj count]; } // end numberOfRowsInTableView diff --git a/Sources/ConnectionControllers/MHConnectionEditorWindowController.h b/Sources/ConnectionControllers/MHConnectionEditorWindowController.h new file mode 100644 index 00000000..096f5ddf --- /dev/null +++ b/Sources/ConnectionControllers/MHConnectionEditorWindowController.h @@ -0,0 +1,70 @@ +// +// MHConnectionEditorWindowController.h +// MongoHub +// +// Created by Jérôme Lebel on 19/08/2012. +// + +#import +@class MHConnectionStore; +@class MHConnectionEditorWindowController; +@class ConnectionsArrayController; + +@protocol MHConnectionEditorWindowControllerDelegate +@property (nonatomic, strong, readonly) NSManagedObjectContext *managedObjectContext; +@property (nonatomic, strong, readonly) ConnectionsArrayController *connectionsArrayController; + +- (void)connectionWindowControllerDidCancel:(MHConnectionEditorWindowController *)controller; +- (void)connectionWindowControllerDidValidate:(MHConnectionEditorWindowController *)controller; +- (MHConnectionStore *)connectionWindowController:(MHConnectionEditorWindowController *)controller connectionStoreWithAlias:(NSString *)alias; + +@end + +@interface MHConnectionEditorWindowController : NSWindowController +{ + NSTextField *_aliasTextField; + + NSPopUpButton *_singleReplicaSetPopUpButton; + NSTabView *_singleReplicaSetTabView; + + // single server + NSTextField *_hostTextField; + NSTextField *_hostportTextField; + NSButton *_slaveOkButton; + + // replica set + NSTextField *_replicaSetNameTextField; + NSTextField *_replicaSetServersTextField; + NSPopUpButton *_defaultReadModePopUpButton; + + // sharded cluster + NSTextField *_shardedClusterServersTextField; + + NSTextField *_adminUserTextField; + NSSecureTextField *_adminPasswordTextField; + NSTextField *_defaultDatabaseTextField; + + NSButton *_useSSLCheckbox; + NSButton *_weakCertificateCheckbox; + + NSButton *_useSSHCheckBox; + NSTextField *_sshHostTextField; + NSTextField *_sshPortTextField; + NSTextField *_sshUserTextField; + NSSecureTextField *_sshPasswordTextField; + NSTextField *_sshKeyfileTextField; + + NSButton *_selectKeyFileButton; + NSButton *_addSaveButton; + + id _delegate; +} +@property (nonatomic, readwrite, strong) MHConnectionStore *editedConnectionStore; +@property (nonatomic, readwrite, strong) MHConnectionStore *connectionStoreDefaultValue; +@property (nonatomic, readwrite, weak) id delegate; +@property (nonatomic, readonly, assign, getter=isNewConnetion) BOOL newConnection; + +- (void)modalForWindow:(NSWindow *)window; +- (NSManagedObjectContext *)managedObjectContext; + +@end diff --git a/Sources/ConnectionControllers/MHConnectionEditorWindowController.m b/Sources/ConnectionControllers/MHConnectionEditorWindowController.m new file mode 100644 index 00000000..2bebfb88 --- /dev/null +++ b/Sources/ConnectionControllers/MHConnectionEditorWindowController.m @@ -0,0 +1,536 @@ +// +// MHConnectionEditorWindowControllerDelegate.m +// MongoHub +// +// Created by Jérôme Lebel on 19/08/2012. +// + +#import "MHConnectionEditorWindowController.h" +#import "MHConnectionStore.h" +#import "ConnectionsArrayController.h" +#import "MHKeychain.h" +#import + +#define COPY_ALIAS_SUFFIX @" - Copy" +#define SINGLESERVER_TAB_IDENTIER @"singleserver" +#define REPLICASET_TAB_IDENTIER @"replicaset" +#define SHARDEDCLUSTER_TAB_IDENTIER @"shardedcluster" + +@interface MHConnectionEditorWindowController () +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *aliasTextField; + +@property (nonatomic, readwrite, weak) IBOutlet NSPopUpButton *singleReplicaSetPopUpButton; +@property (nonatomic, readwrite, weak) IBOutlet NSTabView *singleReplicaSetTabView; + +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *hostTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *hostportTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *slaveOkButton; + +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *replicaSetServersTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *replicaSetNameTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSPopUpButton *defaultReadModePopUpButton; + +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *shardedClusterServersTextField; + +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *adminUserTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSSecureTextField *adminPasswordTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *defaultDatabaseTextField; + +@property (nonatomic, readwrite, weak) IBOutlet NSButton *useSSLCheckbox; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *weakCertificateCheckbox; + +@property (nonatomic, readwrite, weak) IBOutlet NSButton *useSSHCheckBox; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *sshHostTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *sshPortTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *sshUserTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSSecureTextField *sshPasswordTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *sshKeyfileTextField; + +@property (nonatomic, readwrite, weak) IBOutlet NSButton *selectKeyFileButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *addSaveButton; + +@property (nonatomic, readwrite, assign, getter=isNewConnetion) BOOL newConnection; + +@end + +static NSInteger tagFromPreferenceReadMode(MODReadPreferencesReadMode readMode) +{ + switch (readMode) { + case MODReadPreferencesReadPrimaryMode: + return 0; + break; + case MODReadPreferencesReadSecondaryMode: + return 1; + break; + case MODReadPreferencesReadPrimaryPreferredMode: + return 2; + break; + case MODReadPreferencesReadSecondaryPreferredMode: + return 3; + break; + case MODReadPreferencesReadNearestMode: + return 4; + break; + } + return 0; +} + +static MODReadPreferencesReadMode preferenceReadModeFromTag(NSInteger tag) +{ + switch (tag) { + default: + case 0: + return MODReadPreferencesReadPrimaryMode; + break; + case 1: + return MODReadPreferencesReadSecondaryMode; + break; + case 2: + return MODReadPreferencesReadPrimaryPreferredMode; + break; + case 3: + return MODReadPreferencesReadSecondaryPreferredMode; + break; + case 4: + return MODReadPreferencesReadNearestMode; + break; + } +} + +@implementation MHConnectionEditorWindowController + +@synthesize delegate = _delegate; + +@synthesize aliasTextField = _aliasTextField; + +@synthesize singleReplicaSetPopUpButton = _singleReplicaSetPopUpButton; +@synthesize singleReplicaSetTabView = _singleReplicaSetTabView; + +@synthesize hostTextField = _hostTextField; +@synthesize hostportTextField = _hostportTextField; +@synthesize slaveOkButton = _slaveOkButton; + +@synthesize replicaSetServersTextField = _replicaSetServersTextField; +@synthesize replicaSetNameTextField = _replicaSetNameTextField; +@synthesize defaultReadModePopUpButton = _defaultReadModePopUpButton; + +@synthesize shardedClusterServersTextField = _shardedClusterServersTextField; + +@synthesize adminUserTextField = _adminUserTextField; +@synthesize adminPasswordTextField = _adminPasswordTextField; +@synthesize defaultDatabaseTextField = _defaultDatabaseTextField; +@synthesize useSSLCheckbox = _useSSLCheckbox; +@synthesize weakCertificateCheckbox = _weakCertificateCheckbox; + +@synthesize useSSHCheckBox = _useSSHCheckBox; +@synthesize sshHostTextField = _sshHostTextField; +@synthesize sshPortTextField = _sshPortTextField; +@synthesize sshUserTextField = _sshUserTextField; +@synthesize sshPasswordTextField = _sshPasswordTextField; +@synthesize sshKeyfileTextField = _sshKeyfileTextField; + +@synthesize selectKeyFileButton = _selectKeyFileButton; +@synthesize addSaveButton = _addSaveButton; + +- (instancetype)init +{ + self = [super initWithWindowNibName:@"MHConnectionEditorWindow"]; + return self; +} + +- (void)dealloc +{ + self.connectionStoreDefaultValue = nil; + self.editedConnectionStore = nil; + [super dealloc]; +} + +- (void)windowDidLoad +{ + MHConnectionStore *defaultValue = (self.editedConnectionStore == nil)?self.connectionStoreDefaultValue:self.editedConnectionStore; + + [self.hostportTextField.cell setPlaceholderString:[NSString stringWithFormat:@"%d", MODClient.defaultPort]]; + [self.sshUserTextField.cell setPlaceholderString:[NSProcessInfo.processInfo.environment objectForKey:@"USER"]]; + if (self.editedConnectionStore) { + self.addSaveButton.title = NSLocalizedString(@"Save", @"Save connection (after updating)"); + self.newConnection = NO; + } else { + self.newConnection = YES; + self.addSaveButton.title = NSLocalizedString(@"Add", @"Add connection"); + } + if (defaultValue) { + if (self.newConnection && defaultValue.alias.length > 0) { + NSCharacterSet *numberOrWhiteSpace = [NSCharacterSet characterSetWithCharactersInString:@"1234567890 "]; + NSString *baseAlias = defaultValue.alias; + NSString *alias; + NSUInteger index = 1; + + while ([numberOrWhiteSpace characterIsMember:[baseAlias characterAtIndex:baseAlias.length - 1]]) { + baseAlias = [baseAlias substringToIndex:baseAlias.length - 1]; + } + if ([baseAlias hasSuffix:COPY_ALIAS_SUFFIX]) { + baseAlias = [baseAlias substringToIndex:baseAlias.length - COPY_ALIAS_SUFFIX.length]; + alias = [NSString stringWithFormat:@"%@%@ %lu", baseAlias, COPY_ALIAS_SUFFIX, (unsigned long)index]; + index++; + } else { + baseAlias = defaultValue.alias; + alias = [NSString stringWithFormat:@"%@%@", defaultValue.alias, COPY_ALIAS_SUFFIX]; + } + while ([self.delegate connectionWindowController:self connectionStoreWithAlias:alias] != nil) { + alias = [NSString stringWithFormat:@"%@%@ %lu", baseAlias, COPY_ALIAS_SUFFIX, (unsigned long)index]; + index++; + } + self.aliasTextField.stringValue = alias; + } else if (defaultValue.alias) { + self.aliasTextField.stringValue = defaultValue.alias; + } + self.window.title = self.aliasTextField.stringValue; + if (defaultValue.replicaSetName.length > 0) { + [self.singleReplicaSetPopUpButton selectItemAtIndex:1]; + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:REPLICASET_TAB_IDENTIER]; + if (defaultValue.servers) self.replicaSetServersTextField.stringValue = defaultValue.servers; + if (defaultValue.replicaSetName) self.replicaSetNameTextField.stringValue = defaultValue.replicaSetName; + } else if ([MHConnectionStore splitServers:defaultValue.servers].count > 1) { + [self.singleReplicaSetPopUpButton selectItemAtIndex:2]; + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:SHARDEDCLUSTER_TAB_IDENTIER]; + self.shardedClusterServersTextField.stringValue = defaultValue.servers; + } else { + NSInteger port; + + [self.singleReplicaSetPopUpButton selectItemAtIndex:0]; + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:SINGLESERVER_TAB_IDENTIER]; + self.hostTextField.stringValue = [MHConnectionStore hostnameFromServer:defaultValue.servers withPort:&port]; + if (port != 0) { + self.hostportTextField.stringValue = [NSString stringWithFormat:@"%ld", (long)port]; + } + } + self.slaveOkButton.state = defaultValue.slaveOK.boolValue?NSOnState:NSOffState; + if (defaultValue.adminUser) self.adminUserTextField.stringValue = defaultValue.adminUser; + if (defaultValue.adminPassword) self.adminPasswordTextField.stringValue = defaultValue.adminPassword; + if (defaultValue.defaultDatabase) self.defaultDatabaseTextField.stringValue = defaultValue.defaultDatabase; + if (defaultValue.sshHost) self.sshHostTextField.stringValue = defaultValue.sshHost; + if (defaultValue.sshPort.stringValue.longLongValue == 0) { + self.sshPortTextField.stringValue = @""; + } else { + self.sshPortTextField.stringValue = defaultValue.sshPort.stringValue; + } + if (defaultValue.sshUser) self.sshUserTextField.stringValue = defaultValue.sshUser; + if (defaultValue.useSSH.boolValue && defaultValue.sshPassword) { + // there is no need to fetch for the ssh password if ssh is turned off + // let's fetch for it, when the user will turn on ssh + // (we keep the ssh settings even if it is turned off) + self.sshPasswordTextField.stringValue = defaultValue.sshPassword; + } + if (defaultValue.sshKeyFileName) self.sshKeyfileTextField.stringValue = defaultValue.sshKeyFileName; + self.useSSHCheckBox.state = defaultValue.useSSH.boolValue?NSOnState:NSOffState; + [self.defaultReadModePopUpButton selectItemWithTag:tagFromPreferenceReadMode(defaultValue.defaultReadMode)]; + self.useSSLCheckbox.state = defaultValue.useSSL.boolValue?NSOnState:NSOffState; + self.weakCertificateCheckbox.state = defaultValue.weakCertificate.boolValue?NSOnState:NSOffState; + } else { + self.window.title = NSLocalizedString(@"New Connection", @"New Connection"); + self.hostTextField.stringValue = @""; + self.hostportTextField.stringValue = @""; + self.slaveOkButton.state = NSOffState; + self.replicaSetServersTextField.stringValue = @""; + self.replicaSetNameTextField.stringValue = @""; + self.aliasTextField.stringValue = @""; + self.adminUserTextField.stringValue = @""; + self.adminPasswordTextField.stringValue = @""; + self.defaultDatabaseTextField.stringValue = @""; + self.sshHostTextField.stringValue = @""; + self.sshPortTextField.stringValue = @""; + self.sshUserTextField.stringValue = @""; + self.sshPasswordTextField.stringValue = @""; + self.sshKeyfileTextField.stringValue = @""; + self.useSSLCheckbox.state = NSOffState; + self.weakCertificateCheckbox.state = NSOffState; + self.useSSHCheckBox.state = NSOffState; + [self.defaultReadModePopUpButton selectItemWithTag:0]; + [self.singleReplicaSetPopUpButton selectItemAtIndex:0]; + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:SINGLESERVER_TAB_IDENTIER]; + } + [self _updateSSLFields]; + [self _updateSSHFields]; + [self _updateServerFields]; + [super windowDidLoad]; +} + +- (void)modalForWindow:(NSWindow *)window +{ + [NSApp beginSheet:self.window modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) contextInfo:nil]; +} + +- (void)didEndSheet:(NSWindow *)window returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + [self.window orderOut:self]; +} + +- (NSManagedObjectContext *)managedObjectContext +{ + return self.delegate.managedObjectContext; +} + +- (ConnectionsArrayController *)connectionsArrayController +{ + return self.delegate.connectionsArrayController; +} + +- (IBAction)cancelAction:(id)sender +{ + [self.delegate connectionWindowControllerDidCancel:self]; + if (self.window.isSheet) { + [NSApp endSheet:self.window]; + } else { + [self.window close]; + } +} + +- (IBAction)singleServerReplicaSetChoiceAction:(id)sender +{ + if ([self.singleReplicaSetTabView.selectedTabViewItem.identifier isEqualTo:SHARDEDCLUSTER_TAB_IDENTIER] + && self.shardedClusterServersTextField.stringValue) { + self.replicaSetServersTextField.stringValue = self.shardedClusterServersTextField.stringValue; + } else if ([self.singleReplicaSetTabView.selectedTabViewItem.identifier isEqualTo:REPLICASET_TAB_IDENTIER] + && self.replicaSetServersTextField.stringValue) { + self.shardedClusterServersTextField.stringValue = self.replicaSetServersTextField.stringValue; + } + if (self.singleReplicaSetPopUpButton.selectedTag == 0) { + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:SINGLESERVER_TAB_IDENTIER]; + } else if (self.singleReplicaSetPopUpButton.selectedTag == 1) { + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:REPLICASET_TAB_IDENTIER]; + } else if (self.singleReplicaSetPopUpButton.selectedTag == 2) { + [self.singleReplicaSetTabView selectTabViewItemWithIdentifier:SHARDEDCLUSTER_TAB_IDENTIER]; + } else { + NSAssert(NO, @"unknown value %ld", (long)self.singleReplicaSetPopUpButton.selectedTag); + } + [self _updateServerFields]; +} + +- (NSString *)servers +{ + NSString *hostName; + NSInteger hostPort; + NSString *result; + + hostName = [self.hostTextField.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + hostPort = self.hostportTextField.stringValue.integerValue; + if (self.singleReplicaSetPopUpButton.selectedTag == 1 || self.singleReplicaSetPopUpButton.selectedTag == 2) { + result = [MHConnectionStore cleanupServers:self.replicaSetServersTextField.stringValue]; + } else if (hostPort == 0) { + result = hostName; + } else if (hostPort > 0 && hostPort <= 65535) { + result = [NSString stringWithFormat:@"%@:%ld", hostName, (long)hostPort]; + } else { + result = nil; + } + return result; +} + +- (IBAction)addSaveAction:(id)sender +{ + NSInteger hostPort; + NSInteger sshPort; + NSString *defaultDatabase; + NSString *alias; + NSString *sshHost; + NSString *replicaServers; + NSString *replicaName; + BOOL useSSH; + BOOL useReplicaSet; + + hostPort = self.hostportTextField.stringValue.integerValue; + defaultDatabase = [self.defaultDatabaseTextField.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + alias = [self.aliasTextField.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + sshHost = [self.sshHostTextField.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + useSSH = self.useSSHCheckBox.state == NSOnState; + useReplicaSet = self.singleReplicaSetPopUpButton.selectedTag == 1; + replicaServers = [MHConnectionStore cleanupServers:self.replicaSetServersTextField.stringValue]; + replicaName = [self.replicaSetNameTextField.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + sshPort = self.sshPortTextField.stringValue.integerValue; + + if (hostPort < 0 || hostPort > 65535) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"Host port should be between 1 and 65535 (or empty)", @"")); + [self.hostportTextField becomeFirstResponder]; + return; + } + if (alias.length == 0) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"Name should not be less than 1 charaters", @"")); + [self.aliasTextField becomeFirstResponder]; + return; + } + if (useSSH && sshHost.length == 0) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"Tunneling requires SSH Host!", @"")); + [self.sshHostTextField becomeFirstResponder]; + return; + } + if (useSSH && (sshPort < 0 || sshPort > 65535)) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"ssh port should be between 1 and 65535 (or empty)", @"")); + [self.sshPortTextField becomeFirstResponder]; + return; + } + if (useReplicaSet && [replicaServers componentsSeparatedByString:@","].count <= 1) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"You need to set more than one server", @"")); + [self.replicaSetServersTextField becomeFirstResponder]; + return; + } + if (useReplicaSet && replicaName.length == 0) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"You need to set a replica set name", @"")); + [self.replicaSetNameTextField becomeFirstResponder]; + return; + } + if (self.adminPasswordTextField.stringValue.length > 0 && self.adminUserTextField.stringValue == 0) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"You need set a user name if you enter a password", @"")); + [self.adminUserTextField becomeFirstResponder]; + return; + } + MHConnectionStore *sameAliasConnection = [self.delegate connectionWindowController:self connectionStoreWithAlias:alias]; + if (sameAliasConnection && sameAliasConnection != self.editedConnectionStore) { + NSBeginAlertSheet(NSLocalizedString(@"Error", @"Error"), NSLocalizedString(@"OK", @"OK"), nil, nil, self.window, nil, nil, nil, nil, NSLocalizedString(@"Name already in use!", @"")); + [self.aliasTextField becomeFirstResponder]; + return; + } + if (!self.editedConnectionStore) { + self.editedConnectionStore = [self.connectionsArrayController.newObject autorelease]; + } + if (useReplicaSet) { + self.editedConnectionStore.replicaSetName = replicaName; + } else { + self.editedConnectionStore.replicaSetName = nil; + } + self.editedConnectionStore.alias = alias; + self.editedConnectionStore.servers = self.servers; + self.editedConnectionStore.slaveOK = (self.slaveOkButton.state == NSOnState)?@YES:@NO; + self.editedConnectionStore.adminUser = self.adminUserTextField.stringValue; + self.editedConnectionStore.adminPassword = self.adminPasswordTextField.stringValue; + self.editedConnectionStore.defaultDatabase = defaultDatabase; + self.editedConnectionStore.useSSL = @(self.useSSLCheckbox.state == NSOnState); + self.editedConnectionStore.weakCertificate = @(self.weakCertificateCheckbox.state == NSOnState); + self.editedConnectionStore.useSSH = @(useSSH); + self.editedConnectionStore.sshHost = sshHost; + self.editedConnectionStore.sshPort = @(sshPort); + self.editedConnectionStore.sshUser = self.sshUserTextField.stringValue; + self.editedConnectionStore.sshPassword = self.sshPasswordTextField.stringValue; + self.editedConnectionStore.sshKeyFileName = self.sshKeyfileTextField.stringValue; + self.editedConnectionStore.defaultReadMode = preferenceReadModeFromTag(self.defaultReadModePopUpButton.selectedTag); + + NSString *urlString; + MODClient *client; + urlString = [self.editedConnectionStore stringURLWithSSHMapping:nil]; + client = [MODClient clientWihtURLString:urlString]; + if (client == nil) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"Invalid URL %@", urlString); + return; + } + + if (self.newConnection) { + [self.connectionsArrayController addObject:self.editedConnectionStore]; + } + [self.delegate connectionWindowControllerDidValidate:self]; + if (self.window.isSheet) { + [NSApp endSheet:self.window]; + } else { + [self.window close]; + } +} + +- (IBAction)enableSSLAction:(id)sender +{ + [self _updateSSLFields]; +} + +- (IBAction)enableSSHAction:(id)sender +{ + [self _updateSSHFields]; +} + +- (IBAction)chooseKeyPathAction:(id)sender +{ + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + + if (openPanel.runModal == NSOKButton) { + self.sshKeyfileTextField.stringValue = openPanel.URL.path; + } +} + +- (void)_updateServerFields +{ + if (self.singleReplicaSetPopUpButton.selectedTag == 2) { + self.singleReplicaSetPopUpButton.nextKeyView = self.shardedClusterServersTextField; + self.shardedClusterServersTextField.nextKeyView = self.adminUserTextField; + } else if (self.singleReplicaSetPopUpButton.selectedTag == 1) { + self.singleReplicaSetPopUpButton.nextKeyView = self.replicaSetNameTextField; + self.defaultReadModePopUpButton.nextKeyView = self.adminUserTextField; + } else if (self.singleReplicaSetPopUpButton.selectedTag == 0) { + self.singleReplicaSetPopUpButton.nextKeyView = self.hostTextField; + self.slaveOkButton.nextKeyView = self.adminUserTextField; + } else { + NSAssert(NO, @"unknown value %ld", (long)self.singleReplicaSetPopUpButton.selectedTag);; + } +} + +- (void)_updateSSLFields +{ + self.weakCertificateCheckbox.enabled = self.useSSLCheckbox.state == NSOnState; +} + +- (void)_updateSSHFields +{ + BOOL useSSH; + + useSSH = self.useSSHCheckBox.state == NSOnState; + self.sshHostTextField.enabled = useSSH; + self.sshUserTextField.enabled = useSSH; + self.sshPortTextField.enabled = useSSH; + self.sshPasswordTextField.enabled = useSSH; + self.sshKeyfileTextField.enabled = useSSH; + self.selectKeyFileButton.enabled = useSSH; + if (useSSH && self.adminPasswordTextField.stringValue.length == 0) { + // if we turn on ssh for the first time, let's try to search in the keychain to get a password + // no need to do it before if the guy doesn't use ssh + // (we keep the ssh settings even if it is disabled) + [self updateSSHPassword]; + } +} + +- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor +{ + if (control == self.sshUserTextField) { + [self updateSSHPassword]; + } else if (control == self.adminUserTextField) { + NSString *password = nil; + + if (self.adminUserTextField.stringValue.length > 0) { + password = [MHConnectionStore passwordForServers:self.servers username:self.adminUserTextField.stringValue]; + } + if (password) { + self.adminPasswordTextField.stringValue = password; + } else { + self.adminPasswordTextField.stringValue = @""; + } + } else if (control == self.replicaSetServersTextField) { + if ([self.replicaSetServersTextField.stringValue hasPrefix:MONGODB_SCHEME]) { + self.replicaSetServersTextField.stringValue = [self.replicaSetServersTextField.stringValue substringFromIndex:MONGODB_SCHEME.length]; + } + } else if (control == self.shardedClusterServersTextField) { + if ([self.shardedClusterServersTextField.stringValue hasPrefix:MONGODB_SCHEME]) { + self.shardedClusterServersTextField.stringValue = [self.shardedClusterServersTextField.stringValue substringFromIndex:MONGODB_SCHEME.length]; + } + } + return YES; +} + +- (void)updateSSHPassword +{ + NSString *password = nil; + + if (self.sshHostTextField.stringValue.length > 0) { + password = [MHKeychain internetPasswordProtocol:kSecAttrProtocolSSH host:self.sshHostTextField.stringValue port:self.sshPortTextField.integerValue account:self.sshUserTextField.stringValue]; + } + if (password) { + self.sshPasswordTextField.stringValue = password; + } else { + self.sshPasswordTextField.stringValue = @""; + } +} + +@end diff --git a/Sources/ConnectionControllers/MHEditNameWindowController.h b/Sources/ConnectionControllers/MHEditNameWindowController.h new file mode 100644 index 00000000..f053fac6 --- /dev/null +++ b/Sources/ConnectionControllers/MHEditNameWindowController.h @@ -0,0 +1,34 @@ +// +// MHEditNameWindowController.h +// MongoHub +// +// Created by Syd on 10-4-28. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import + +@class MHEditNameWindowController; + +@protocol MHEditNameWindowControllerDelegate +- (void)editNameWindowControllerDidSucceed:(MHEditNameWindowController *)controller; +@end + +@interface MHEditNameWindowController : NSWindowController +{ + NSTextField *_editedValueTextField; + NSTextField *_labelTextField; + + NSString *_label; + NSString *_editedValue; + void (^_callback)(MHEditNameWindowController *controller); +} + +@property (nonatomic, readonly, copy) NSString *editedValue; +@property (nonatomic, readwrite, copy) void (^callback)(MHEditNameWindowController *controller); +@property (nonatomic, readwrite, copy) BOOL (^validateValueCallback)(MHEditNameWindowController *controller); + +- (instancetype)initWithLabel:(NSString *)label editedValue:(NSString *)editedValue placeHolder:(NSString *)placeHolder; +- (void)modalForWindow:(NSWindow *)window; + +@end diff --git a/Sources/ConnectionControllers/MHEditNameWindowController.m b/Sources/ConnectionControllers/MHEditNameWindowController.m new file mode 100644 index 00000000..27e3cc7c --- /dev/null +++ b/Sources/ConnectionControllers/MHEditNameWindowController.m @@ -0,0 +1,96 @@ +// +// MHEditNameWindowController.m +// MongoHub +// +// Created by Syd on 10-4-28. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import "MHEditNameWindowController.h" + + +@interface MHEditNameWindowController () +@property (nonatomic, readwrite, assign) IBOutlet NSTextField *editedValueTextField; +@property (nonatomic, readwrite, assign) IBOutlet NSTextField *labelTextField; + +@property (nonatomic, readwrite, copy) NSString *editedValue; +@property (nonatomic, readwrite, copy) NSString *placeHolder; +@property (nonatomic, readwrite, copy) NSString *label; + +@end + +@implementation MHEditNameWindowController + +@synthesize editedValueTextField = _editedValueTextField; +@synthesize labelTextField = _labelTextField; +@synthesize editedValue = _editedValue; +@synthesize label = _label; +@synthesize callback = _callback; + +- (instancetype)initWithLabel:(NSString *)label editedValue:(NSString *)editedValue placeHolder:(NSString *)placeHolder +{ + self = [self init]; + if (self) { + self.label = label; + self.editedValue = editedValue; + self.placeHolder = placeHolder; + } + return self; +} + +- (void)dealloc +{ + self.label = nil; + self.editedValue = nil; + self.callback = nil; + [super dealloc]; +} + +- (NSString *)windowNibName +{ + return @"MHEditNameWindow"; +} + +- (void)awakeFromNib +{ + self.labelTextField.stringValue = self.label; + if (self.editedValue) { + self.editedValueTextField.stringValue = self.editedValue; + } + if (self.placeHolder) { + self.editedValueTextField.placeholderString = self.placeHolder; + } +} + +- (IBAction)cancelAction:(id)sender +{ + [NSApp endSheet:self.window]; +} + +- (IBAction)validateAction:(id)sender +{ + self.editedValue = [self.editedValueTextField.stringValue stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]; + + if (self.validateValueCallback == nil || self.validateValueCallback(self)) { + [self retain]; + [NSApp endSheet:self.window]; + // the delegate will release this instance after the call, + // so we need to make sure we keep ourself around to close the window + if (self.callback) { + self.callback(self); + } + [self autorelease]; + } +} + +- (void)modalForWindow:(NSWindow *)window +{ + [NSApp beginSheet:self.window modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) contextInfo:nil]; +} + +- (void)didEndSheet:(NSWindow *)window returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + [self.window orderOut:self]; +} + +@end diff --git a/Sources/ConnectionWindow/MHActivityMonitorViewController.h b/Sources/ConnectionWindow/MHActivityMonitorViewController.h new file mode 100644 index 00000000..8691984c --- /dev/null +++ b/Sources/ConnectionWindow/MHActivityMonitorViewController.h @@ -0,0 +1,28 @@ +// +// MHActivityMonitorViewController.h +// MongoHub +// +// Created by Jérôme Lebel on 20/10/2014. +// +// + +#import "MHTabItemViewController.h" + +@class MODClient; +@class MODSortedDictionary; +@class MODQuery; + +@interface MHActivityMonitorViewController : MHTabItemViewController +{ + MODClient *_client; + NSTimer *_timer; + MODSortedDictionary *_previousServerStatusForDelta; + NSMutableArray *_data; + MODQuery *_query; + + NSTableView *_tableView; +} + +- (id)initWithClient:(MODClient *)client; + +@end diff --git a/Sources/ConnectionWindow/MHActivityMonitorViewController.m b/Sources/ConnectionWindow/MHActivityMonitorViewController.m new file mode 100644 index 00000000..851288fc --- /dev/null +++ b/Sources/ConnectionWindow/MHActivityMonitorViewController.m @@ -0,0 +1,146 @@ +// +// MHActivityMonitorViewController.m +// MongoHub +// +// Created by Jérôme Lebel on 20/10/2014. +// +// + +#import "MHActivityMonitorViewController.h" +#import + +@interface MHActivityMonitorViewController () +@property (nonatomic, readwrite, strong) MODClient *client; +@property (nonatomic, readwrite, strong) NSTimer *timer; +@property (nonatomic, readwrite, strong) NSMutableArray *data; +@property (nonatomic, readwrite, strong) MODQuery *query; + +@property (nonatomic, readwrite, weak) IBOutlet NSTableView *tableView; + +@end + +@implementation MHActivityMonitorViewController + +@synthesize client = _client; +@synthesize timer = _timer; +@synthesize data = _data; +@synthesize query = _query; + +@synthesize tableView = _tableView; + +- (id)initWithClient:(MODClient *)client +{ + if (self = [self init]) { + self.client = client; + self.data = [NSMutableArray array]; + } + return self; +} + +- (void)dealloc +{ + self.client = nil; + self.timer = nil; + self.data = nil; + self.query = nil; + [super dealloc]; +} + +- (NSString *)nibName +{ + return @"MHActivityMonitorTab"; +} + +- (void)awakeFromNib +{ + [self fetchServerStatusDelta]; + self.title = @"Activity Monitor"; +} + +- (void)willRemoveFromTabViewController +{ + [self.query cancel]; + [self.timer invalidate]; + self.timer = nil; +} + +static int percentage(NSNumber *previousValue, NSNumber *previousOutOfValue, NSNumber *value, NSNumber *outOfValue) +{ + double valueDiff = [value doubleValue] - [previousValue doubleValue]; + double outOfValueDiff = [outOfValue doubleValue] - [previousOutOfValue doubleValue]; + return (outOfValueDiff == 0) ? 0.0 : (valueDiff * 100.0 / outOfValueDiff); +} + +static void addObjectForKeyWithDefault(NSMutableDictionary *dictionary, id value, NSString *key, id defaultValue) +{ + if (value) { + dictionary[key] = value; + } else { + dictionary[key] = defaultValue; + } +} + +- (void)fetchServerStatusDelta +{ + self.query = [self.client serverStatusWithReadPreferences:nil callback:^(MODSortedDictionary *serverStatus, MODQuery *mongoQuery) { + NSMutableDictionary *diff = [[NSMutableDictionary alloc] init]; + + if (_previousServerStatusForDelta) { + NSNumber *number; + NSDate *date; + + for (NSString *key in [[serverStatus objectForKey:@"opcounters"] allKeys]) { + number = [[NSNumber alloc] initWithInteger:[[[serverStatus objectForKey:@"opcounters"] objectForKey:key] integerValue] - [[[_previousServerStatusForDelta objectForKey:@"opcounters"] objectForKey:key] integerValue]]; + [diff setObject:number forKey:key]; + [number release]; + } + if ([[serverStatus objectForKey:@"mem"] objectForKey:@"mapped"]) { + [diff setObject:[[serverStatus objectForKey:@"mem"] objectForKey:@"mapped"] forKey:@"mapped"]; + } + addObjectForKeyWithDefault(diff, [[serverStatus objectForKey:@"mem"] objectForKey:@"virtual"], @"vsize", @"-"); + addObjectForKeyWithDefault(diff, [[serverStatus objectForKey:@"mem"] objectForKey:@"resident"], @"res", @"-"); + number = [[NSNumber alloc] initWithInteger:[[[serverStatus objectForKey:@"extra_info"] objectForKey:@"page_faults"] integerValue] - [[[_previousServerStatusForDelta objectForKey:@"extra_info"] objectForKey:@"page_faults"] integerValue]]; + [diff setObject:number forKey:@"faults"]; + [number release]; + number = [[NSNumber alloc] initWithInteger:percentage([[_previousServerStatusForDelta objectForKey:@"globalLock"] objectForKey:@"lockTime"], + [[_previousServerStatusForDelta objectForKey:@"globalLock"] objectForKey:@"totalTime"], + [[serverStatus objectForKey:@"globalLock"] objectForKey:@"lockTime"], + [[serverStatus objectForKey:@"globalLock"] objectForKey:@"totalTime"])]; + [diff setObject:number forKey:@"locked"]; + [number release]; + number = [[NSNumber alloc] initWithInteger:percentage([[[_previousServerStatusForDelta objectForKey:@"indexCounters"] objectForKey:@"btree"] objectForKey:@"misses"], + [[[_previousServerStatusForDelta objectForKey:@"indexCounters"] objectForKey:@"btree"] objectForKey:@"accesses"], + [[[serverStatus objectForKey:@"indexCounters"] objectForKey:@"btree"] objectForKey:@"misses"], + [[[serverStatus objectForKey:@"indexCounters"] objectForKey:@"btree"] objectForKey:@"accesses"])]; + [diff setObject:number forKey:@"misses"]; + [number release]; + date = [[NSDate alloc] init]; + addObjectForKeyWithDefault(diff, [[serverStatus objectForKey:@"connections"] objectForKey:@"current"], @"conn", @"-"); + [diff setObject:date forKey:@"time"]; + [date release]; + [self.data addObject:diff]; + [self.tableView reloadData]; + [self.tableView scrollRowToVisible:self.data.count - 1]; + } + if (_previousServerStatusForDelta) { + [_previousServerStatusForDelta release]; + } + _previousServerStatusForDelta = [serverStatus retain]; + [diff release]; + self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(fetchServerStatusDelta) userInfo:nil repeats:NO]; + }]; +} + +- (NSUInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + return self.data.count; +} + +- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)index { + NSDictionary *row = self.data[index]; + + return row[tableColumn.identifier]; + +} + +@end diff --git a/Sources/ConnectionWindow/MHConnectionWindowController.h b/Sources/ConnectionWindow/MHConnectionWindowController.h new file mode 100644 index 00000000..24b5e60c --- /dev/null +++ b/Sources/ConnectionWindow/MHConnectionWindowController.h @@ -0,0 +1,89 @@ +// +// MHConnectionWindowController.h +// MongoHub +// +// Created by Syd on 10-4-25. +// Copyright 2010 MusicPeace.ORG. All rights reserved. +// + +#import +#import "MHClientItem.h" +#import "MHTunnel.h" +#import "MHTabViewController.h" + +@class BWSheetController; +@class MHMysqlImportWindowController; +@class MHMysqlExportWindowController; +@class MHConnectionStore; +@class MODClient; +@class MODDatabase; +@class MODCollection; +@class MODSortedDictionary; +@class MHTabTitleView; +@class MHStatusViewController; +@class MHImportExportFeedback; +@class MHConnectionWindowController; +@class MHActivityMonitorViewController; + +@protocol MHImporterExporter; + +@protocol MHConnectionWindowControllerDelegate +- (void)connectionWindowControllerWillClose:(MHConnectionWindowController *)controller; +- (BOOL)connectionWindowControllerSSHVerbose:(MHConnectionWindowController *)controller; +- (void)connectionWindowControllerLogMessage:(NSString *)message domain:(NSString *)domain level:(NSString *)level; +@end + +@interface MHConnectionWindowController : NSWindowController +{ + id_delegate; + NSMenu *_createCollectionOrDatabaseMenu; + + MHTabViewController *_tabViewController; + NSSplitView *_splitView; + + NSTimer *_serverMonitorTimer; + NSOutlineView *_databaseCollectionOutlineView; + NSProgressIndicator *_loaderIndicator; + NSToolbar *_toolbar; + + NSView *_mainTabView; + MHTabTitleView *_tabTitleView; +} + +@property (nonatomic, readwrite, assign) id delegate; +@property (nonatomic, readwrite, strong) MHConnectionStore *connectionStore; +@property (nonatomic, readwrite, strong) MODClient *client; +@property (nonatomic, readwrite, strong) MHMysqlImportWindowController *mysqlImportWindowController; +@property (nonatomic, readwrite, strong) MHMysqlExportWindowController *mysqlExportWindowController; + +@property (nonatomic, readonly, weak) IBOutlet MHTabViewController *tabViewController; + +- (IBAction)showServerStatus:(id)sender; +- (IBAction)showCollStats:(id)sender; +- (IBAction)createDatabase:(id)sender; +- (IBAction)createCollection:(id)sender; +- (IBAction)dropDatabaseOrCollection:(id)sender; +- (IBAction)query:(id)sender; +- (void)connectToServer; +- (void)dropWarning:(NSString *)msg; +- (NSManagedObjectContext *)managedObjectContext; + +@end + +@interface MHConnectionWindowController(ImportExport) +- (IBAction)importFromMySQLAction:(id)sender; +- (IBAction)exportToMySQLAction:(id)sender; +- (IBAction)importFromFileAction:(id)sender; +- (IBAction)exportToFileAction:(id)sender; + +@end + +@interface MHConnectionWindowController(NSOutlineViewDataSource) +@end + +@interface MHConnectionWindowController(MHTabViewControllerDelegate) +@end + +@interface MHConnectionWindowController(MHTunnelDelegate) +@end + diff --git a/Sources/ConnectionWindow/MHConnectionWindowController.m b/Sources/ConnectionWindow/MHConnectionWindowController.m new file mode 100644 index 00000000..88010d66 --- /dev/null +++ b/Sources/ConnectionWindow/MHConnectionWindowController.m @@ -0,0 +1,898 @@ +// +// MHConnectionWindowController.m +// MongoHub +// +// Created by Syd on 10-4-25. +// Copyright 2010 MusicPeace.ORG. All rights reserved. +// + +#import "NSString+MongoHub.h" +#import "MHConnectionWindowController.h" +#import "MHQueryViewController.h" +#import "MHEditNameWindowController.h" +#import "MHMysqlImportWindowController.h" +#import "MHMysqlExportWindowController.h" +#import "MHTunnel.h" +#import "MHClientItem.h" +#import "MHDatabaseItem.h" +#import "MHCollectionItem.h" +#import "SidebarBadgeCell.h" +#import "MHConnectionStore.h" +#import "MHFileExporter.h" +#import "MHFileImporter.h" +#import "MODHelper.h" +#import +#import "MHStatusViewController.h" +#import "MHTabViewController.h" +#import "MHImportExportFeedback.h" +#import "MHDatabaseCollectionOutlineView.h" +#import "MHActivityMonitorViewController.h" + +#define SERVER_STATUS_TOOLBAR_ITEM_TAG 0 +#define DATABASE_STATUS_TOOLBAR_ITEM_TAG 1 +#define COLLECTION_STATUS_TOOLBAR_ITEM_TAG 2 +#define QUERY_TOOLBAR_ITEM_TAG 3 +#define MYSQL_IMPORT_TOOLBAR_ITEM_TAG 4 +#define MYSQL_EXPORT_TOOLBAR_ITEM_TAG 5 +#define FILE_IMPORT_TOOLBAR_ITEM_TAG 6 +#define FILE_EXPORT_TOOLBAR_ITEM_TAG 7 + +@interface MHConnectionWindowController () +@property (nonatomic, readwrite, strong) MHClientItem *clientItem; +@property (nonatomic, readwrite, strong) NSMutableDictionary *tabItemControllers; +@property (nonatomic, readwrite, strong) MHStatusViewController *statusViewController; +@property (nonatomic, readwrite, strong) MHActivityMonitorViewController *activityMonitorViewController; +@property (nonatomic, readwrite, weak) IBOutlet MHTabViewController *tabViewController; +@property (nonatomic, readwrite, strong) MHTunnel *sshTunnel; +@property (nonatomic, readwrite, strong) NSMutableDictionary *sshBindedPortMapping; + +@property (nonatomic, readwrite, strong) MHImportExportFeedback *importExportFeedback; +@property (nonatomic, readwrite, strong) id importerExporter; + +@property (nonatomic, readwrite, weak) IBOutlet NSMenu *createCollectionOrDatabaseMenu; +@property (nonatomic, readwrite, weak) IBOutlet NSSplitView *splitView; +@property (nonatomic, readwrite, weak) IBOutlet NSOutlineView *databaseCollectionOutlineView; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *loaderIndicator; +@property (nonatomic, readwrite, weak) IBOutlet NSToolbar *toolbar; + +- (void)updateToolbarItems; + +- (MHDatabaseItem *)selectedDatabaseItem; +- (MHCollectionItem *)selectedCollectionItem; + +- (MODQuery *)getDatabaseList; +- (MODQuery *)getCollectionListForDatabaseItem:(MHDatabaseItem *)databaseItem; + +- (void)showDatabaseStatusWithDatabaseItem:(MHDatabaseItem *)databaseItem; +- (void)showCollectionStatusWithCollectionItem:(MHCollectionItem *)collectionItem; +@end + +@implementation MHConnectionWindowController + +@synthesize delegate = _delegate; +@synthesize loaderIndicator = _loaderIndicator; +@synthesize tabViewController = _tabViewController; + +- (NSString *)windowNibName +{ + return @"MHConnectionWindow"; +} + +- (void)dealloc +{ + [self.window removeObserver:self forKeyPath:@"firstResponder"]; + [self.tabViewController removeObserver:self forKeyPath:@"selectedTabIndex"]; + self.tabItemControllers = nil; + self.clientItem = nil; + [_serverMonitorTimer invalidate]; + [_serverMonitorTimer release]; + _serverMonitorTimer = nil; + self.connectionStore = nil; + self.sshTunnel = nil; + self.sshBindedPortMapping = nil; + self.loaderIndicator = nil; + self.mysqlImportWindowController = nil; + self.mysqlExportWindowController = nil; + self.statusViewController = nil; + self.client = nil; + self.importerExporter = nil; + [super dealloc]; +} + +- (void)awakeFromNib +{ + NSView *tabView = self.tabViewController.view; + + self.tabItemControllers = [NSMutableDictionary dictionary]; + + [[self.splitView.subviews objectAtIndex:1] addSubview:tabView]; + tabView.frame = tabView.superview.bounds; + [self.databaseCollectionOutlineView setDoubleAction:@selector(outlineViewDoubleClickAction:)]; + [self updateToolbarItems]; + + self.window.title = [NSString stringWithFormat:@"%@, Connecting…", self.connectionStore.alias]; + [self.tabViewController addObserver:self forKeyPath:@"selectedTabIndex" options:NSKeyValueObservingOptionNew context:nil]; + [self.window addObserver:self forKeyPath:@"firstResponder" options:NSKeyValueObservingOptionNew context:nil]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ((object == self.tabViewController && [keyPath isEqualToString:@"selectedTabIndex"]) + || (object == self.window && [keyPath isEqualToString:@"firstResponder"] && self.window.firstResponder != self.databaseCollectionOutlineView && self.window.firstResponder != self.window)) { +// update the outline view selection if the tab changed, or if the first responder changed +// don't do it if the first responder is the outline view or the windw, other we will lose the new user selection + id selectedTab = self.tabViewController.selectedTabItemViewController; + + if ([selectedTab isKindOfClass:[MHQueryViewController class]]) { + NSIndexSet *indexes = nil; + MHDatabaseItem *databaseOutlineViewItem; + MHCollectionItem *collectionOutlineViewItem; + + databaseOutlineViewItem = [self.clientItem databaseItemWithName:[(MHQueryViewController *)selectedTab collection].database.name]; + collectionOutlineViewItem = [databaseOutlineViewItem collectionItemWithName:[(MHQueryViewController *)selectedTab collection].name]; + if (collectionOutlineViewItem) { + [self.databaseCollectionOutlineView expandItem:databaseOutlineViewItem]; + indexes = [[NSIndexSet alloc] initWithIndex:[self.databaseCollectionOutlineView rowForItem:collectionOutlineViewItem]]; + } else if (databaseOutlineViewItem) { + indexes = [[NSIndexSet alloc] initWithIndex:[self.databaseCollectionOutlineView rowForItem:databaseOutlineViewItem]]; + } + if (indexes) { + [self.databaseCollectionOutlineView selectRowIndexes:indexes byExtendingSelection:NO]; + [indexes release]; + } + } else if ([selectedTab isKindOfClass:[MHStatusViewController class]]) { + + } + } +} + +- (void)connectToServer +{ + [self.loaderIndicator startAnimation:nil]; + if (self.sshTunnel == nil && self.connectionStore.useSSH.boolValue) { + self.sshBindedPortMapping = [NSMutableDictionary dictionary]; + self.sshTunnel = [[[MHTunnel alloc] init] autorelease]; + self.sshTunnel.verbose = [self.delegate connectionWindowControllerSSHVerbose:self]; + self.sshTunnel.delegate = self; + self.sshTunnel.user = self.connectionStore.sshUser; + self.sshTunnel.host = self.connectionStore.sshHost; + self.sshTunnel.password = self.connectionStore.sshPassword; + self.sshTunnel.keyfile = self.connectionStore.sshKeyFileName.stringByExpandingTildeInPath; + self.sshTunnel.port = self.connectionStore.sshPort.intValue; + self.sshTunnel.aliveCountMax = 3; + self.sshTunnel.aliveInterval = 30; + self.sshTunnel.tcpKeepAlive = YES; + self.sshTunnel.compression = YES; + for (NSString *hostnameAndPort in self.connectionStore.arrayServers) { + NSInteger hostPort, sshBindedPort; + NSString *hostAddress; + NSString *hostAndPortString; + + sshBindedPort = [MHTunnel findFreeTCPPort]; + hostAddress = [MHConnectionStore hostnameFromServer:hostnameAndPort withPort:&hostPort]; + if (hostPort == 0) { + hostPort = MODClient.defaultPort; + } + if (hostAddress.length == 0) { + hostAddress = @"127.0.0.1"; + } + [self.sshTunnel addForwardingPortWithBindAddress:nil bindPort:sshBindedPort hostAddress:hostAddress hostPort:hostPort reverseForwarding:NO]; + hostAndPortString = [NSString stringWithFormat:@"%@:%ld", hostAddress, (long)hostPort]; + [self.sshBindedPortMapping setObject:[NSNumber numberWithInteger:sshBindedPort] forKey:hostAndPortString]; + [self.delegate connectionWindowControllerLogMessage:[NSString stringWithFormat:@"mapping 127.0.0.1:%ld => %@", (long)sshBindedPort, hostAndPortString] domain:[NSString stringWithFormat:@"%@.url", self.connectionStore.alias] level:@"debug"]; + } + [self.sshTunnel start]; + return; + } else if (self.client == nil) { + // we are connecting for the first time, let's create a client + // otherwise we are just doing a reconnect, we can keep everything that we already have + + NSString *urlString; + + urlString = [self.connectionStore stringURLWithSSHMapping:nil]; + [self.delegate connectionWindowControllerLogMessage:urlString domain:[NSString stringWithFormat:@"%@.url", self.connectionStore.alias] level:@"debug"]; + self.client = [MODClient clientWihtURLString:urlString]; + if (self.client == nil) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"Invalid URL %@", urlString); + } else { + self.client.sshMapping = self.sshBindedPortMapping; + if (self.connectionStore.useSSL) { + self.client.sslOptions = [[[MODSSLOptions alloc] initWithPemFileName:nil pemPassword:nil caFileName:nil caDirectory:nil crlFileName:nil weakCertificate:self.connectionStore.weakCertificate.boolValue] autorelease]; + } + self.client.readPreferences = [MODReadPreferences readPreferencesWithReadMode:self.connectionStore.defaultReadMode]; + [self.loaderIndicator stopAnimation:nil]; + + self.clientItem = [[[MHClientItem alloc] initWithClient:self.client] autorelease]; + [self showServerStatus:nil]; + } + } +} + +- (void)windowDidLoad +{ + [super windowDidLoad]; + [self connectToServer]; + [self.databaseCollectionOutlineView setDoubleAction:@selector(sidebarDoubleAction:)]; +} + +// REMOVE when 10.9 is not supported anymore +- (BOOL)validateUserInterfaceItem:(id )anItem +{ + return [self.tabViewController.selectedTabItemViewController respondsToSelector:@selector(canPerformCopy)] + && [(id)self.tabViewController.selectedTabItemViewController canPerformCopy]; +} + +// REMOVE when 10.9 is not supported anymore +- (void)copy:(id)sender +{ + if ([self.tabViewController.selectedTabItemViewController respondsToSelector:@selector(canPerformCopy)] + && [(id)self.tabViewController.selectedTabItemViewController canPerformCopy] + && [self.tabViewController.selectedTabItemViewController respondsToSelector:@selector(performCopy)]) { + [(id)self.tabViewController.selectedTabItemViewController performCopy]; + } +} + +- (void)sidebarDoubleAction:(id)sender +{ + [self query:sender]; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + if (notification.object == self.window) { + [self.sshTunnel stop]; + [self.client cancelAllOperations]; + self.client = nil; + [self.delegate connectionWindowControllerWillClose:self]; + } +} + +- (MODQuery *)getDatabaseList +{ + MODQuery *result; + + [self.loaderIndicator startAnimation:nil]; + result = [self.client databaseNamesWithCallback:^(NSArray *list, MODQuery *mongoQuery) { + [self.loaderIndicator stopAnimation:nil]; + self.window.title = self.connectionStore.alias; + if (list != nil && list.count > 0) { + if ([self.clientItem updateChildrenWithList:list]) { + [self.databaseCollectionOutlineView reloadData]; + } + } else if (self.connectionStore.defaultDatabase.length > 0) { + if ([self.clientItem updateChildrenWithList:[NSArray arrayWithObject:self.connectionStore.defaultDatabase]]) { + [self.databaseCollectionOutlineView reloadData]; + } + } else if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + } + }]; + return result; +} + +- (void)getCollectionListForDatabaseName:(NSString *)databaseName +{ + MHDatabaseItem *databaseItem; + + databaseItem = [self.clientItem databaseItemWithName:databaseName]; + if (databaseItem) { + [self getCollectionListForDatabaseItem:databaseItem]; + } +} + +- (MODQuery *)getCollectionListForDatabaseItem:(MHDatabaseItem *)databaseItem +{ + MODDatabase *mongoDatabase; + MODQuery *result; + + mongoDatabase = databaseItem.database; + [self.loaderIndicator startAnimation:nil]; + result = [mongoDatabase collectionNamesWithCallback:^(NSArray *collectionList, MODQuery *mongoQuery) { + MHDatabaseItem *newDatabaseItem; + + [self.loaderIndicator stopAnimation:nil]; + newDatabaseItem = [self.clientItem databaseItemWithName:mongoDatabase.name]; + if (collectionList && newDatabaseItem) { + if ([newDatabaseItem updateChildrenWithList:collectionList]) { + [self.databaseCollectionOutlineView reloadData]; + } + } else if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + } + }]; + return result; +} + +- (void)showDatabaseStatusWithDatabaseItem:(MHDatabaseItem *)databaseItem +{ + if (self.statusViewController == nil) { + self.statusViewController = [[[MHStatusViewController alloc] initWithClient:self.client connectionStore:self.connectionStore] autorelease]; + [self.tabViewController addTabItemViewController:self.statusViewController]; + } + [self.statusViewController showDatabaseStatusWithDatabaseItem:databaseItem]; +} + +- (void)showCollectionStatusWithCollectionItem:(MHCollectionItem *)collectionItem +{ + if (self.statusViewController == nil) { + self.statusViewController = [[[MHStatusViewController alloc] initWithClient:self.client connectionStore:self.connectionStore] autorelease]; + [self.tabViewController addTabItemViewController:self.statusViewController]; + } + [self.statusViewController showCollectionStatusWithCollectionItem:collectionItem]; +} + +- (IBAction)showServerStatus:(id)sender +{ + if (self.statusViewController == nil) { + self.statusViewController = [[[MHStatusViewController alloc] initWithClient:self.client connectionStore:self.connectionStore] autorelease]; + [self.tabViewController addTabItemViewController:self.statusViewController]; + } + [self.statusViewController showServerStatus]; + [self.statusViewController select]; + [self getDatabaseList]; +} + +- (IBAction)showDatabaseStatus:(id)sender +{ + [self showDatabaseStatusWithDatabaseItem:self.selectedDatabaseItem]; + [self.statusViewController select]; +} + +- (IBAction)showCollStats:(id)sender +{ + [self showCollectionStatusWithCollectionItem:self.selectedCollectionItem]; + [self.statusViewController select]; +} + +- (IBAction)showActivityMonitorAction:(id)sender +{ + if (!self.activityMonitorViewController) { + self.activityMonitorViewController = [[[MHActivityMonitorViewController alloc] initWithClient:self.client] autorelease]; + [self.tabViewController addTabItemViewController:self.activityMonitorViewController]; + } + [self.activityMonitorViewController select]; +} + +- (void)outlineViewDoubleClickAction:(id)sender +{ +} + +- (void)menuWillOpen:(NSMenu *)menu +{ + if (menu == self.createCollectionOrDatabaseMenu) { + [menu itemWithTag:2].enabled = self.selectedDatabaseItem != nil; + } +} + +- (IBAction)createDatabase:(id)sender +{ + MHEditNameWindowController *editNameWindowController; + + editNameWindowController = [[[MHEditNameWindowController alloc] initWithLabel:@"New Database Name:" editedValue:nil placeHolder:@"Database Name"] autorelease]; + editNameWindowController.callback = ^(MHEditNameWindowController *controller) { + [self.clientItem addExtraDatabaseName:editNameWindowController.editedValue]; + [self getDatabaseList]; + }; + editNameWindowController.validateValueCallback = ^(MHEditNameWindowController *controller) { + if (controller.editedValue.length != 0) { + return YES; + } else { + NSRunAlertPanel(@"Error", @"Database name can not be empty", @"OK", nil, nil); + return NO; + } + }; + [editNameWindowController modalForWindow:self.window]; +} + +- (IBAction)createCollection:(id)sender +{ + MHDatabaseItem *databaseItem = self.selectedDatabaseItem; + MODDatabase *database = databaseItem.database; + + NSParameterAssert(databaseItem != nil); + NSParameterAssert(database != nil); + if (database) { + MHEditNameWindowController *editNameWindowController; + + editNameWindowController = [[[MHEditNameWindowController alloc] initWithLabel:@"New Collection Name:" editedValue:nil placeHolder:@"Collection Name"] autorelease]; + editNameWindowController.callback = ^(MHEditNameWindowController *controller) { + [database createCollectionWithName:editNameWindowController.editedValue callback:^(MODQuery *mongoQuery) { + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + } + [self.databaseCollectionOutlineView expandItem:databaseItem]; + [self getCollectionListForDatabaseName:database.name]; + }]; + }; + editNameWindowController.validateValueCallback = ^(MHEditNameWindowController *controller) { + if (controller.editedValue.length != 0) { + return YES; + } else { + NSRunAlertPanel(@"Error", @"Collection name can not be empty", @"OK", nil, nil); + return NO; + } + }; + [editNameWindowController modalForWindow:self.window]; + } +} + +- (IBAction)renameCollection:(id)sender +{ + MODCollection *collection = self.selectedCollectionItem.collection; + NSString *oldCollectionName = collection.absoluteName; + + if (collection) { + MHEditNameWindowController *editNameWindowController; + + NSAssert(collection != nil, @"collection should not be nil 1"); + NSAssert(collection.absoluteName, @"collection name should not be nil 1"); + editNameWindowController = [[[MHEditNameWindowController alloc] initWithLabel:[NSString stringWithFormat:@"Rename %@:", collection.absoluteName] editedValue:collection.name placeHolder:collection.name] autorelease]; + editNameWindowController.callback = ^(MHEditNameWindowController *controller) { + [collection renameWithNewDatabase:nil newCollectionName:editNameWindowController.editedValue dropTargetBeforeRenaming:NO callback:^(MODQuery *mongoQuery) { + if (collection.absoluteName != oldCollectionName) { + MHTabItemViewController *tabItemController; + + NSAssert(collection != nil, @"collection should not be nil 2"); + NSAssert(collection.absoluteName, @"collection name should not be nil 2"); + tabItemController = self.tabItemControllers[oldCollectionName]; + if (tabItemController != nil) { + // the tab is opened, let's update the with the new name + [tabItemController retain]; + [self.tabItemControllers removeObjectForKey:oldCollectionName]; + self.tabItemControllers[collection.absoluteName] = tabItemController; + tabItemController.title = collection.absoluteName; + [tabItemController release]; + } + } + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + } + [self getCollectionListForDatabaseName:collection.database.name]; + }]; + }; + editNameWindowController.validateValueCallback = ^(MHEditNameWindowController *controller) { + if (controller.editedValue.length != 0) { + return YES; + } else { + NSRunAlertPanel(@"Error", @"Collection name can not be empty", @"OK", nil, nil); + return NO; + } + }; + [editNameWindowController modalForWindow:self.window]; + } +} + +- (IBAction)dropDatabaseOrCollection:(id)sender +{ + if (self.selectedCollectionItem) { + [self dropWarning:self.selectedCollectionItem.collection.absoluteName]; + } else { + [self dropWarning:self.selectedDatabaseItem.database.name]; + } +} + +- (void)dropCollection:(MODCollection *)collection +{ + if (collection) { + NSString *databaseName = collection.database.name; + + [self.loaderIndicator startAnimation:nil]; + [collection dropWithCallback:^(MODQuery *mongoQuery) { + [self.loaderIndicator stopAnimation:nil]; + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + } else { + MHTabItemViewController *tabItemViewController = self.tabItemControllers[collection.absoluteName]; + + if (tabItemViewController) { + [self.tabViewController removeTabItemViewController:tabItemViewController]; + } + [self getCollectionListForDatabaseName:databaseName]; + } + }]; + } +} + +- (void)dropDatabase +{ + MHDatabaseItem *databaseItem = self.selectedDatabaseItem; + MODDatabase *database = databaseItem.database; + + NSParameterAssert(databaseItem != nil); + NSParameterAssert(database != nil); + if (databaseItem.temporary) { + [self.clientItem removeExtraDatabaseName:database.name]; + [self getDatabaseList]; + } else { + [self.loaderIndicator startAnimation:nil]; + [database dropWithCallback:^(MODQuery *mongoQuery) { + [self.loaderIndicator stopAnimation:nil]; + [self getDatabaseList]; + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + } + }]; + } +} + +- (IBAction)query:(id)sender +{ + if (!self.selectedCollectionItem) { + if (![self.databaseCollectionOutlineView isItemExpanded:[self.databaseCollectionOutlineView itemAtRow:[self.databaseCollectionOutlineView selectedRow]]]) { + [self.databaseCollectionOutlineView expandItem:[self.databaseCollectionOutlineView itemAtRow:[self.databaseCollectionOutlineView selectedRow]] expandChildren:NO]; + } else { + [self.databaseCollectionOutlineView collapseItem:[self.databaseCollectionOutlineView itemAtRow:[self.databaseCollectionOutlineView selectedRow]]]; + } + } else { + MHQueryViewController *queryWindowController; + + queryWindowController = self.tabItemControllers[self.selectedCollectionItem.collection.absoluteName]; + if (queryWindowController == nil) { + queryWindowController = [[[MHQueryViewController alloc] initWithCollection:self.selectedCollectionItem.collection connectionStore:self.connectionStore] autorelease]; + self.tabItemControllers[self.selectedCollectionItem.collection.absoluteName] = queryWindowController; + [self.tabViewController addTabItemViewController:queryWindowController]; + } + [queryWindowController select]; + } +} + +- (void)dropWarningDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + if (returnCode == NSAlertSecondButtonReturn) + { + if (self.selectedCollectionItem) { + [self dropCollection:self.selectedCollectionItem.collection]; + }else { + [self dropDatabase]; + } + } +} + +- (void)dropWarning:(NSString *)msg +{ + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + [alert addButtonWithTitle:@"Cancel"]; + [alert addButtonWithTitle:@"OK"]; + [alert setMessageText:[NSString stringWithFormat:@"Drop \"%@\"?", msg]]; + [alert setInformativeText:[NSString stringWithFormat:@"Dropping \"%@\" cannot be restored.", msg]]; + [alert setAlertStyle:NSWarningAlertStyle]; + [alert beginSheetModalForWindow:[self window] modalDelegate:self + didEndSelector:@selector(dropWarningDidEnd:returnCode:contextInfo:) + contextInfo:nil]; +} + +- (MHDatabaseItem *)selectedDatabaseItem +{ + MHDatabaseItem *result = nil; + NSInteger index; + + index = [self.databaseCollectionOutlineView selectedRow]; + if (index != -1) { + id item; + + item = [self.databaseCollectionOutlineView itemAtRow:index]; + if ([item isKindOfClass:[MHDatabaseItem class]]) { + result = item; + } else if ([item isKindOfClass:[MHCollectionItem class]]) { + result = [item databaseItem]; + } + } + return result; +} + +- (MHCollectionItem *)selectedCollectionItem +{ + MHCollectionItem *result = nil; + NSInteger index; + + index = [self.databaseCollectionOutlineView selectedRow]; + if (index != -1) { + id item; + + item = [self.databaseCollectionOutlineView itemAtRow:index]; + if ([item isKindOfClass:[MHCollectionItem class]]) { + result = item; + } + } + return result; +} + +- (NSManagedObjectContext *)managedObjectContext +{ + return self.connectionStore.managedObjectContext; +} + +- (void)updateToolbarItems +{ + for (NSToolbarItem *item in [self.toolbar items]) { + switch ([item tag]) { + case DATABASE_STATUS_TOOLBAR_ITEM_TAG: + item.enabled = self.selectedDatabaseItem != nil; + break; + + case COLLECTION_STATUS_TOOLBAR_ITEM_TAG: + case QUERY_TOOLBAR_ITEM_TAG: + case MYSQL_IMPORT_TOOLBAR_ITEM_TAG: + case MYSQL_EXPORT_TOOLBAR_ITEM_TAG: + case FILE_IMPORT_TOOLBAR_ITEM_TAG: + case FILE_EXPORT_TOOLBAR_ITEM_TAG: + item.enabled = self.selectedCollectionItem != nil; + break; + + default: + break; + } + } +} + +- (BOOL)windowShouldClose:(id)sender +{ + // only close tabs when using cmd-w, if the current is event is not a key down + // (probably mouse down), just close the window + if (NSApplication.sharedApplication.currentEvent.type != NSKeyDown) { + return YES; + } else if (self.tabViewController.tabCount <= 1) { + return YES; + } else { + [self.tabViewController removeTabItemViewController:self.tabViewController.selectedTabItemViewController]; + return NO; + } +} + +@end + +@implementation MHConnectionWindowController (ImportExport) + +- (void)importerExporterStopNotification:(NSNotification *)notification +{ + [self.importExportFeedback close]; + self.importExportFeedback = nil; + if (self.importerExporter.error) { + [self.delegate connectionWindowControllerLogMessage:self.importerExporter.error.localizedDescription domain:[NSString stringWithFormat:@"%@.%@", self.connectionStore.alias, self.importerExporter.identifier] level:@"error"]; + NSBeginAlertSheet(self.importerExporter.name, @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", self.importerExporter.error.localizedDescription); + } else { + [self.delegate connectionWindowControllerLogMessage:[NSString stringWithFormat:@"%lu documents processed", (unsigned long)self.importerExporter.documentProcessedCount] domain:[NSString stringWithFormat:@"%@.importexport", self.connectionStore.alias] level:@"info"]; + } + [NSNotificationCenter.defaultCenter removeObserver:self name:nil object:self.importerExporter]; + self.importerExporter = nil; +} + +- (void)exportSelectedCollectionToFilePath:(NSString *)filePath +{ + MHFileExporter *exporter; + + exporter = [[[MHFileExporter alloc] initWithCollection:self.selectedCollectionItem.collection exportPath:filePath] autorelease]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(importerExporterStopNotification:) name:MHImporterExporterStopNotification object:exporter]; + self.importExportFeedback = [[[MHImportExportFeedback alloc] initWithImporterExporter:exporter] autorelease]; + self.importExportFeedback.label = [NSString stringWithFormat:@"Exporting %@ to %@…", self.selectedCollectionItem.collection.absoluteName, [filePath lastPathComponent]]; + [self.importExportFeedback start]; + [self.importExportFeedback displayForWindow:self.window]; + [exporter export]; + self.importerExporter = exporter; +} + +- (void)importIntoSelectedCollectionFromFilePath:(NSString *)filePath +{ + MHFileImporter *importer; + + NSAssert(self.importExportFeedback == nil, @"we should have no more feedback controller"); + importer = [[[MHFileImporter alloc] initWithCollection:self.selectedCollectionItem.collection importPath:filePath] autorelease]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(importerExporterStopNotification:) name:MHImporterExporterStopNotification object:importer]; + self.importExportFeedback = [[[MHImportExportFeedback alloc] initWithImporterExporter:importer] autorelease]; + self.importExportFeedback.label = [NSString stringWithFormat:@"Importing %@ into %@…", [filePath lastPathComponent], self.selectedCollectionItem.collection.absoluteName]; + [self.importExportFeedback start]; + [self.importExportFeedback displayForWindow:self.window]; + [importer import]; + self.importerExporter = importer; +} + +- (IBAction)importFromMySQLAction:(id)sender +{ + if (self.selectedDatabaseItem == nil) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, NULL, NULL, nil, @"Please specify a database!"); + return; + } + if (!self.mysqlImportWindowController) { + self.mysqlImportWindowController = [[MHMysqlImportWindowController alloc] init]; + } + self.mysqlImportWindowController.database = self.selectedDatabaseItem.database; + if (self.selectedCollectionItem) { + [self.mysqlExportWindowController.collectionTextField setStringValue:[self.selectedCollectionItem.collection name]]; + } + [self.mysqlImportWindowController showWindow:self]; +} + +- (IBAction)exportToMySQLAction:(id)sender +{ + if (self.selectedCollectionItem == nil) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, NULL, NULL, nil, @"Please specify a collection!"); + return; + } + if (!self.mysqlExportWindowController) { + self.mysqlExportWindowController = [[MHMysqlExportWindowController alloc] init]; + } + self.mysqlExportWindowController.mongoDatabase = self.selectedDatabaseItem.database; + self.mysqlExportWindowController.dbname = self.selectedDatabaseItem.database.name; + if (self.selectedCollectionItem) { + [self.mysqlExportWindowController.collectionTextField setStringValue:[self.selectedCollectionItem.collection name]]; + } + [self.mysqlExportWindowController showWindow:self]; +} + +- (IBAction)importFromFileAction:(id)sender +{ + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + + [openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { + if (result == NSOKButton) { + // wait until the panel is closed to open the import feedback window + [self performSelectorOnMainThread:@selector(importIntoSelectedCollectionFromFilePath:) withObject:[[openPanel URL] path] waitUntilDone:NO]; + } + }]; +} + +- (IBAction)exportToFileAction:(id)sender +{ + NSSavePanel *savePanel = [NSSavePanel savePanel]; + + savePanel.nameFieldStringValue = [NSString stringWithFormat:@"%@-%@", self.selectedDatabaseItem.database.name, self.selectedCollectionItem.collection.name]; + [savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) { + if (result == NSOKButton) { + // wait until the panel is closed to open the import feedback window + [self performSelectorOnMainThread:@selector(exportSelectedCollectionToFilePath:) withObject:savePanel.URL.path waitUntilDone:NO]; + } + }]; +} + +@end + +@implementation MHConnectionWindowController(NSOutlineViewDataSource) + +- (NSMenu *)databaseCollectionOutlineView:(MHDatabaseCollectionOutlineView *)outlineView contextualMenuWithEvent:(NSEvent *)event +{ + NSMenu *result; + id item; + NSInteger index; + + result = [[[NSMenu alloc] init] autorelease]; + index = self.databaseCollectionOutlineView.selectedRow; + item = [self.databaseCollectionOutlineView itemAtRow:index]; + if (self.databaseCollectionOutlineView.selectedRowIndexes.count == 0) { + [result addItemWithTitle:@"New Database…" action:@selector(createDatabase:) keyEquivalent:@""].target = self; + } else if ([item isKindOfClass:[MHDatabaseItem class]]) { + [result addItemWithTitle:[NSString stringWithFormat:@"%@ Stats", [item name]] action:@selector(showDatabaseStatus:) keyEquivalent:@""].target = self; + [result addItemWithTitle:[NSString stringWithFormat:@"Drop %@…", [item name]] action:@selector(dropDatabaseOrCollection:) keyEquivalent:@""].target = self; + [result addItem:[NSMenuItem separatorItem]]; + [result addItemWithTitle:@"New Database…" action:@selector(createDatabase:) keyEquivalent:@""].target = self; + [result addItemWithTitle:@"New Collection…" action:@selector(createCollection:) keyEquivalent:@""].target = self; + } else if ([item isKindOfClass:[MHCollectionItem class]]) { + [result addItemWithTitle:[NSString stringWithFormat:@"Open %@", [item name]] action:@selector(query:) keyEquivalent:@""].target = self; + [result addItemWithTitle:[NSString stringWithFormat:@"%@ Stats", [item name]] action:@selector(showCollStats:) keyEquivalent:@""].target = self; + [result addItemWithTitle:[NSString stringWithFormat:@"Rename %@…", [item name]] action:@selector(renameCollection:) keyEquivalent:@""].target = self; + [result addItemWithTitle:[NSString stringWithFormat:@"Drop %@…", [item name]] action:@selector(dropDatabaseOrCollection:) keyEquivalent:@""].target = self; + [result addItem:[NSMenuItem separatorItem]]; + [result addItemWithTitle:@"New Database…" action:@selector(createDatabase:) keyEquivalent:@""].target = self; + [result addItemWithTitle:@"New Collection…" action:@selector(createCollection:) keyEquivalent:@""].target = self; + } + return result; +} + +- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item +{ + NSInteger result = 0; + + if (!item) { + result = self.clientItem.databaseItems.count; + } else if ([item isKindOfClass:[MHDatabaseItem class]]) { + result = [item sortedCollectionNames].count; + } + return result; +} + +- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item +{ + id result = nil; + + if (!item) { + result = [self.clientItem.databaseItems objectAtIndex:index]; + } else if ([item isKindOfClass:[MHDatabaseItem class]]) { + NSString *collectionName = [item sortedCollectionNames][index]; + + result = [item collectionItems][collectionName]; + } + return result; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item +{ + return !item || [item isKindOfClass:[MHDatabaseItem class]]; +} + +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item +{ + return [item name]; +} + +- (void)outlineViewSelectionDidChange:(NSNotification *)notification +{ + MHCollectionItem *collectionItem = self.selectedCollectionItem; + MHDatabaseItem *databaseItem = self.selectedDatabaseItem; + + if (collectionItem && !collectionItem.collection.dropped) { + [self getCollectionListForDatabaseItem:collectionItem.databaseItem]; + [self showCollectionStatusWithCollectionItem:collectionItem]; + if (self.tabItemControllers[collectionItem.collection.absoluteName]) { + [self.tabItemControllers[collectionItem.collection.absoluteName] select]; + } else { + [self.statusViewController select]; + } + } else if (databaseItem && !databaseItem.database.dropped) { + [self getCollectionListForDatabaseItem:databaseItem]; + [self showDatabaseStatusWithDatabaseItem:databaseItem]; + } else { + [self.statusViewController showServerStatus]; + } + [self updateToolbarItems]; + [self getDatabaseList]; +} + +- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + [cell setHasBadge:NO]; + [cell setIcon:nil]; + if ([item isKindOfClass:[MHCollectionItem class]]) { + [cell setIcon:[NSImage imageNamed:@"collectionicon"]]; + } else if ([item isKindOfClass:[MHDatabaseItem class]]) { + [cell setIcon:[NSImage imageNamed:@"dbicon"]]; + [cell setHasBadge:[item collectionItems].count > 0]; + [cell setBadgeCount:[item collectionItems].count]; + } +} + +- (void)outlineViewItemWillExpand:(NSNotification *)notification +{ + [self getCollectionListForDatabaseItem:[[notification userInfo] objectForKey:@"NSObject"]]; +} + +@end + +@implementation MHConnectionWindowController(MHTabViewControllerDelegate) + +- (void)tabViewController:(MHTabViewController *)tabViewController didRemoveTabItem:(MHTabItemViewController *)tabItemViewController +{ + if (tabItemViewController == self.statusViewController) { + self.statusViewController = nil; + } else if (tabItemViewController == self.activityMonitorViewController) { + self.activityMonitorViewController = nil; + } else { + [self.tabItemControllers removeObjectForKey:[(MHQueryViewController *)tabItemViewController collection].absoluteName]; + } +} + +@end + +@implementation MHConnectionWindowController(MHTunnelDelegate) + +- (void)tunnelDidConnect:(MHTunnel *)tunnel +{ + [self.delegate connectionWindowControllerLogMessage:@"connected" domain:[NSString stringWithFormat:@"%@.ssh", self.connectionStore.alias] level:@"info"]; + [self connectToServer]; +} + +- (void)tunnelDidFailToConnect:(MHTunnel *)tunnel withError:(NSError *)error; +{ + [self.delegate connectionWindowControllerLogMessage:error.description domain:[NSString stringWithFormat:@"%@.ssh", self.connectionStore.alias] level:@"error"]; + if (!tunnel.connected) { + // after being connected, we don't really care about errors + [self.loaderIndicator stopAnimation:nil]; + self.statusViewController.title = [NSString stringWithFormat:@"Error: %@", error.localizedDescription]; + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", error.localizedDescription); + } +} + +- (void)tunnelLogMessage:(NSString *)message +{ + [self.delegate connectionWindowControllerLogMessage:message domain:[NSString stringWithFormat:@"%@.ssh", self.connectionStore.alias] level:@"debug"]; +} + +@end diff --git a/Sources/ConnectionWindow/MHDatabaseCollectionOutlineView.h b/Sources/ConnectionWindow/MHDatabaseCollectionOutlineView.h new file mode 100644 index 00000000..19243ac0 --- /dev/null +++ b/Sources/ConnectionWindow/MHDatabaseCollectionOutlineView.h @@ -0,0 +1,20 @@ +// +// MHDatabaseCollectionOutlineView.h +// MongoHub +// +// Created by Jérôme Lebel on 04/10/2014. +// +// + +#import + +@class MHDatabaseCollectionOutlineView; + +@protocol MHDatabaseCollectionOutlineViewDelegate +- (NSMenu *)databaseCollectionOutlineView:(MHDatabaseCollectionOutlineView *)outlineView contextualMenuWithEvent:(NSEvent *)event; + +@end + +@interface MHDatabaseCollectionOutlineView : NSOutlineView + +@end diff --git a/Sources/ConnectionWindow/MHDatabaseCollectionOutlineView.m b/Sources/ConnectionWindow/MHDatabaseCollectionOutlineView.m new file mode 100644 index 00000000..59e8948a --- /dev/null +++ b/Sources/ConnectionWindow/MHDatabaseCollectionOutlineView.m @@ -0,0 +1,47 @@ +// +// MHDatabaseCollectionOutlineView.m +// MongoHub +// +// Created by Jérôme Lebel on 04/10/2014. +// +// + +#import "MHDatabaseCollectionOutlineView.h" + +@implementation MHDatabaseCollectionOutlineView + +- (void)openContextualMenuWithEvent:(NSEvent *)event +{ + if ([self.delegate respondsToSelector:@selector(databaseCollectionOutlineView:contextualMenuWithEvent:)]) { + NSMenu *menu; + NSInteger index; + + index = [self rowAtPoint:[self convertPoint:event.locationInWindow fromView:nil]]; + if (index != -1) { + [self selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:NO]; + } else { + [self selectRowIndexes:[NSIndexSet indexSet] byExtendingSelection:NO]; + } + menu = [(id)self.delegate databaseCollectionOutlineView:self contextualMenuWithEvent:event]; + [NSMenu popUpContextMenu:menu withEvent:event forView:self]; + } +} + +- (void)mouseDown:(NSEvent *)event +{ + [super mouseDown:event]; + if ((event.modifierFlags & NSControlKeyMask) == NSControlKeyMask) { + [self openContextualMenuWithEvent:event]; + } +} + +- (void)rightMouseDown:(NSEvent *)event +{ + if (self.window.attachedSheet) { + [super rightMouseDown:event]; + } else { + [self openContextualMenuWithEvent:event]; + } +} + +@end diff --git a/Sources/ConnectionWindow/MHDocumentOutlineViewController.h b/Sources/ConnectionWindow/MHDocumentOutlineViewController.h new file mode 100644 index 00000000..11acb995 --- /dev/null +++ b/Sources/ConnectionWindow/MHDocumentOutlineViewController.h @@ -0,0 +1,59 @@ +// +// MHDocumentOutlineViewController.h +// MongoHub +// +// Created by Jérôme Lebel on 06/03/2015. +// +// + +#import + +@class MODCursor; +@class MHDocumentOutlineViewController; +@class MODSortedDictionary; + +@protocol MHDocumentOutlineViewDelegate +- (void)documentOutlineViewController:(MHDocumentOutlineViewController *)controller shouldDeleteDocumentIds:(NSArray *)documentIds; +- (void)documentOutlineViewControllerBackButton:(MHDocumentOutlineViewController *)controller; +- (void)documentOutlineViewControllerNextButton:(MHDocumentOutlineViewController *)controller; +- (void)documentOutlineViewController:(MHDocumentOutlineViewController *)controller doubleClickOnDocuments:(NSArray *)documents; + +@optional +- (void)documentOutlineViewControllerSelectionDidChange:(MHDocumentOutlineViewController *)controller; +@end + +@interface MHDocumentOutlineViewController : NSViewController +{ + NSScrollView *_outlineViewScrollView; + NSOutlineView *_outlineView; + NSTextField *_feedbackLabel; + NSButton *_expandPopUpButton; + NSButton *_removeButton; + NSButton *_backButton; + NSButton *_nextButton; + + BOOL _footerViewHidden; + BOOL _removeButtonHidden; + BOOL _nextBackButtonsHidden; + BOOL _disallowsMultipleSelection; + + id _delegate; + NSArray *_documents; +} + +@property (nonatomic, readwrite, weak) IBOutlet id delegate; +@property (nonatomic, readonly, copy) NSArray *documents; + ++ (void)addDocumentOutlineViewController:(MHDocumentOutlineViewController *)controller intoView:(NSView *)view; + +- (void)displayDocuments:(NSArray *)documents withLabel:(NSString *)label; +- (void)displayErrorLabel:(NSString *)label; +- (void)displayLabel:(NSString *)label; +- (NSArray *)selectedDocuments; +- (NSInteger)selectedDocumentCount; +- (void)setBackButtonEnabled:(BOOL)enabled; +- (void)removeDocumentsWithIds:(NSArray *)documentIds; +- (BOOL)canCopyDocuments; +- (void)copyDocuments; + +@end diff --git a/Sources/ConnectionWindow/MHDocumentOutlineViewController.m b/Sources/ConnectionWindow/MHDocumentOutlineViewController.m new file mode 100644 index 00000000..50637fd7 --- /dev/null +++ b/Sources/ConnectionWindow/MHDocumentOutlineViewController.m @@ -0,0 +1,414 @@ +// +// MHDocumentOutlineViewController.m +// MongoHub +// +// Created by Jérôme Lebel on 06/03/2015. +// +// + +#import "MHDocumentOutlineViewController.h" +#import +#import "NSViewHelpers.h" + +@interface MHDocumentOutlineViewController () + +@property (nonatomic, readwrite, weak) IBOutlet NSScrollView *outlineViewScrollView; +@property (nonatomic, readwrite, weak) IBOutlet NSOutlineView *outlineView; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *feedbackLabel; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *expandPopUpButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *removeButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *backButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *nextButton; + +@property (nonatomic, readwrite, assign) BOOL footerViewHidden; +@property (nonatomic, readwrite, assign) BOOL removeButtonHidden; +@property (nonatomic, readwrite, assign) BOOL nextBackButtonsHidden; +@property (nonatomic, readwrite, assign) BOOL disallowsMultipleSelection; + +@property (nonatomic, readwrite, copy) NSArray *documents; + +@end + +@interface MHDocumentOutlineViewController (NSOutlineViewDataSource) +@end + +@implementation MHDocumentOutlineViewController + +@synthesize outlineViewScrollView = _outlineViewScrollView; +@synthesize outlineView = _outlineView; +@synthesize feedbackLabel = _feedbackLabel; +@synthesize expandPopUpButton = _expandPopUpButton; +@synthesize removeButton = _removeButton; +@synthesize backButton = _backButton; +@synthesize nextButton = _nextButton; + +@synthesize footerViewHidden = _footerViewHidden; +@synthesize removeButtonHidden = _removeButtonHidden; +@synthesize nextBackButtonsHidden = _nextBackButtonsHidden; +@synthesize disallowsMultipleSelection = _disallowsMultipleSelection; +@synthesize documents = _documents; +@synthesize delegate = _delegate; + ++ (void)addDocumentOutlineViewController:(MHDocumentOutlineViewController *)controller intoView:(NSView *)view +{ + NSAssert(view != nil, @"should have a view where to put the outlineview"); + NSAssert(controller != nil, @"should have a controller"); + NSAssert(controller.view != nil, @"should have a controller view"); + [view addSubview:controller.view]; + controller.view.frame = view.bounds; + [view addConstraint:[NSLayoutConstraint constraintWithItem:controller.view + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:view + attribute:NSLayoutAttributeTop + multiplier:1.0 + constant:0]]; + [view addConstraint:[NSLayoutConstraint constraintWithItem:controller.view + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationEqual + toItem:view + attribute:NSLayoutAttributeBottom + multiplier:1.0 + constant:0]]; + [view addConstraint:[NSLayoutConstraint constraintWithItem:controller.view + attribute:NSLayoutAttributeLeading + relatedBy:NSLayoutRelationEqual + toItem:view + attribute:NSLayoutAttributeLeading + multiplier:1.0 + constant:0]]; + [view addConstraint:[NSLayoutConstraint constraintWithItem:controller.view + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:view + attribute:NSLayoutAttributeTrailing + multiplier:1.0 + constant:0]]; +} + +- (void)dealloc +{ + [NSNotificationCenter.defaultCenter removeObserver:self name:nil object:nil]; + [super dealloc]; +} + +- (NSString *)nibName +{ + return @"MHDocumentOutlineView"; +} + +- (void)loadView +{ + [super loadView]; + [self.outlineView setTarget:self]; + [self.outlineView setDoubleAction:@selector(doubleClickAction:)]; + self.backButton.enabled = NO; + if (self.footerViewHidden) { + [self.removeButton removeFromSuperview]; + self.removeButton = nil; // not on ARC yet + [self.backButton removeFromSuperview]; + self.backButton = nil; // not on ARC yet + [self.nextButton removeFromSuperview]; + self.nextButton = nil; // not on ARC yet + [self.feedbackLabel removeFromSuperview]; + self.feedbackLabel = nil; // not on ARC yet + [self.expandPopUpButton removeFromSuperview]; + self.expandPopUpButton = nil; + [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationEqual + toItem:self.outlineViewScrollView + attribute:NSLayoutAttributeBottom + multiplier:1.0 + constant:0.0]]; + } else { + if (self.removeButtonHidden) { + [self.removeButton removeFromSuperview]; + self.removeButton = nil; // not on ARC yet + [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.expandPopUpButton + attribute:NSLayoutAttributeLeading + relatedBy:NSLayoutRelationEqual + toItem:self.feedbackLabel + attribute:NSLayoutAttributeTrailing + multiplier:1.0 + constant:8.0]]; + } + if (self.nextBackButtonsHidden) { + [self.backButton removeFromSuperview]; + self.backButton = nil; // not on ARC yet + [self.nextButton removeFromSuperview]; + self.nextButton = nil; // not on ARC yet + [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.expandPopUpButton + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:self.view + attribute:NSLayoutAttributeTrailing + multiplier:1.0 + constant:0.0]]; + } + } + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(outlineViewSelectionDidChangeNotification:) name:NSOutlineViewSelectionDidChangeNotification object:self.outlineView]; + self.outlineView.allowsMultipleSelection = !self.disallowsMultipleSelection; +} + +- (void)removeDocumentsWithIds:(NSArray *)documentIds +{ + NSMutableArray *newDocumentList = [NSMutableArray array]; + + for (NSDictionary *document in self.documents) { + if (![documentIds containsObject:document[@"objectvalueid"]]) { + [newDocumentList addObject:document]; + } + } + if (self.documents.count != newDocumentList.count) { + self.documents = newDocumentList; + [self.outlineView reloadData]; + if (documentIds.count == 1) { + [self displayLabel:@"1 document removed"]; + } else { + [self displayLabel:[NSString stringWithFormat:@"%ld documents removed", documentIds.count]]; + } + } +} + +- (void)displayDocuments:(NSArray *)newDocuments withLabel:(NSString *)label +{ + if (!label) { + self.feedbackLabel.stringValue = @""; + } else { + [self displayLabel:label]; + } + self.documents = newDocuments; + [self.outlineView reloadData]; + [self _expandDocuments]; +} + +- (void)displayErrorLabel:(NSString *)label +{ + [NSViewHelpers cancelColorForTarget:self.feedbackLabel selector:@selector(setTextColor:)]; + self.feedbackLabel.stringValue = label; + [NSViewHelpers setColor:self.feedbackLabel.textColor + fromColor:[NSColor redColor] + toTarget:self.feedbackLabel + withSelector:@selector(setTextColor:) + delay:1]; + self.documents = nil; + [self.outlineView reloadData]; +} + +- (void)displayLabel:(NSString *)label +{ + [NSViewHelpers cancelColorForTarget:self.feedbackLabel selector:@selector(setTextColor:)]; + self.feedbackLabel.stringValue = label; + [NSViewHelpers setColor:self.feedbackLabel.textColor + fromColor:[NSColor greenColor] + toTarget:self.feedbackLabel + withSelector:@selector(setTextColor:) + delay:1]; +} + +- (void)setBackButtonEnabled:(BOOL)enabled +{ + self.backButton.enabled = enabled; +} + +- (void)_expandDocuments +{ + NSInteger expandValue; + + expandValue = self.expandPopUpButton.selectedTag; + if (expandValue == 0) { + [self.outlineView collapseItem:nil collapseChildren:YES]; + } else if (expandValue == 100) { + [self.outlineView collapseItem:nil collapseChildren:NO]; + [self.outlineView expandItem:nil expandChildren:YES]; + } else if (expandValue > 0) { + NSInteger index = 0; + id item;; + NSOutlineView *outlineView = self.outlineView; + + while ((item = [outlineView itemAtRow:index])) { + if ([outlineView levelForItem:item] < expandValue) { + [outlineView expandItem:item]; + } else { + [outlineView collapseItem:item]; + } + index++; + } + } +} + +- (void)outlineViewSelectionDidChangeNotification:(NSNotification *)notification +{ + self.removeButton.enabled = self.outlineView.selectedRowIndexes.count != 0; + if ([self.delegate respondsToSelector:@selector(documentOutlineViewControllerSelectionDidChange:)]) { + [self.delegate documentOutlineViewControllerSelectionDidChange:self]; + } +} + +- (BOOL)canCopyDocuments +{ + return (id)self.view.window.firstResponder == self.outlineView && self.selectedDocumentCount > 0; +} + +- (void)copyDocuments +{ + if ((id)self.view.window.firstResponder == self.outlineView && self.selectedDocumentCount > 0) { + NSPasteboard *pasteboard; + + pasteboard = NSPasteboard.generalPasteboard; + [pasteboard clearContents]; + [self outlineView:self.outlineView writeItems:self.selectedDocuments toPasteboard:pasteboard]; + } +} + +- (BOOL)validateUserInterfaceItem:(id )anItem +{ + if (anItem.action == @selector(copy:)) { + return [self canCopyDocuments]; + } + return [self respondsToSelector:anItem.action]; +} + +- (void)copy:(id)sender +{ + if ([self canCopyDocuments]) { + [self copyDocuments]; + } +} + +- (NSArray *)selectedDocuments +{ + NSMutableArray *documents; + + documents = [NSMutableArray array]; + [self.outlineView.selectedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + id currentItem = [self.outlineView itemAtRow:idx]; + + [documents addObject:[self rootForItem:currentItem]]; + }]; + return documents; +} + +- (NSArray *)selectedDocumentIds +{ + NSMutableArray *documentIds; + + documentIds = [NSMutableArray array]; + [self.outlineView.selectedRowIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + id currentItem = [self.outlineView itemAtRow:idx]; + + [documentIds addObject:[[self rootForItem:currentItem] objectForKey:@"objectvalueid"]]; + }]; + return documentIds; +} + +- (NSInteger)selectedDocumentCount +{ + return self.outlineView.selectedRowIndexes.count; +} + +- (id)rootForItem:(id)item +{ + id parentItem = [self.outlineView parentForItem:item]; + + if (parentItem) { + return [self rootForItem:parentItem]; + } else { + return item; + } + +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard +{ + NSMutableString *string = [NSMutableString stringWithString:@"[\n"]; + BOOL firstDocument = YES; + + for (NSDictionary *item in items) { + if (firstDocument) { + firstDocument = NO; + } else { + [string appendString:@",\n"]; + } + [string appendString:[MODClient convertObjectToJson:[[self rootForItem:item] objectForKey:@"objectvalue"] pretty:YES strictJson:NO jsonKeySortOrder:MODJsonKeySortOrderDocument]]; + } + [string appendString:@"\n]\n"]; + [pasteboard setString:string forType:NSStringPboardType]; + return YES; +} + +- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)index +{ + return NSDragOperationNone; +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id )info item:(id)item childIndex:(NSInteger)index +{ + return NO; +} + +- (IBAction)doubleClickAction:(id)sender +{ + [self.delegate documentOutlineViewController:self doubleClickOnDocuments:self.selectedDocuments]; +} + +@end + +@implementation MHDocumentOutlineViewController (NSOutlineViewDataSource) + +- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item +{ + if (item == nil) { + return [self.documents count]; + } else { + return [[item objectForKey:@"child"] count]; + } +} + +- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item +{ + if (item == nil) { + return self.documents[index]; + } else { + return [[item objectForKey:@"child" ] objectAtIndex:index]; + } +} + +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item +{ + return [[item objectForKey:@"child"] count] != 0; +} + +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item +{ + return [item objectForKey:tableColumn.identifier]; +} + +@end + +@implementation MHDocumentOutlineViewController (UI) + +- (IBAction)nextButtonAction:(id)sender +{ + [self.delegate documentOutlineViewControllerNextButton:self]; +} + +- (IBAction)backButtonAction:(id)sender +{ + [self.delegate documentOutlineViewControllerBackButton:self]; +} + +- (IBAction)removeButtonAction:(id)sender +{ + NSArray *selectedDocumentIds = [self selectedDocumentIds]; + + [self.delegate documentOutlineViewController:self shouldDeleteDocumentIds:selectedDocumentIds]; +} + +- (IBAction)expandPopUpButtonAction:(id)sender +{ + [self _expandDocuments]; +} + +@end diff --git a/Sources/ConnectionWindow/MHIndexEditorController.h b/Sources/ConnectionWindow/MHIndexEditorController.h new file mode 100644 index 00000000..43ca0c9c --- /dev/null +++ b/Sources/ConnectionWindow/MHIndexEditorController.h @@ -0,0 +1,48 @@ +// +// MHIndexEditorController.h +// MongoHub +// +// Created by Jérôme Lebel on 18/12/2014. +// +// + +#import + +@class MODSortedDictionary; +@class MHIndexEditorController; +@class MODIndexOpt; + +@protocol MHIndexEditorControllerDelegate +- (void)indexEditorControllerDidCancel:(MHIndexEditorController *)controller; +- (void)indexEditorControllerDidValidate:(MHIndexEditorController *)controller; + +@end + +@interface MHIndexEditorController : NSWindowController +{ + NSTextField *_nameTextField; + NSButton *_backgroundButton; + NSButton *_dropDuplicatesButton; + NSButton *_isInitializedButton; + NSButton *_sparseButton; + NSButton *_uniqueButton; + NSTableView *_keyTableView; + + NSButton *_addKeyButton; + NSButton *_removeKeyButton; + NSButton *_cancelButton; + NSButton *_okButton; + + MODSortedDictionary *_editedIndex; + NSMutableArray *_indexKeys; + + id _delegate; +} +@property (nonatomic, readwrite, weak) id delegate; +@property (nonatomic, readonly, assign) MODIndexOpt *indexOptions; +@property (nonatomic, readonly, assign) MODSortedDictionary *keys; + +- (id)initWithEditedIndex:(MODSortedDictionary *)index; +- (void)modalForWindow:(NSWindow *)window; + +@end diff --git a/Sources/ConnectionWindow/MHIndexEditorController.m b/Sources/ConnectionWindow/MHIndexEditorController.m new file mode 100644 index 00000000..2a9ad998 --- /dev/null +++ b/Sources/ConnectionWindow/MHIndexEditorController.m @@ -0,0 +1,273 @@ +// +// MHIndexEditorController.m +// MongoHub +// +// Created by Jérôme Lebel on 18/12/2014. +// +// + +#import "MHIndexEditorController.h" +#import + +#define POPUP_BUTTON_ASCENDING_SORTING 0 +#define POPUP_BUTTON_DESCENDING_SORTING 1 +#define POPUP_BUTTON_HASHED_SORTING 2 + + +@interface MHIndexEditorController () +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *nameTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *backgroundButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *dropDuplicatesButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *isInitializedButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *sparseButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *uniqueButton; +@property (nonatomic, readwrite, weak) IBOutlet NSTableView *keyTableView; + +@property (nonatomic, readwrite, weak) IBOutlet NSButton *addKeyButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *removeKeyButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *cancelButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *okButton; + +@property (nonatomic, readwrite, strong) MODSortedDictionary *editedIndex; +@property (nonatomic, readwrite, strong) NSMutableArray *indexKeys; + +@end + +@interface MHIndexEditorController (NSTableViewDataSource) +@end + +@interface MHIndexEditorController (NSTableViewDelegate) +@end + +@implementation MHIndexEditorController +@synthesize nameTextField = _nameTextField; +@synthesize backgroundButton = _backgroundButton; +@synthesize dropDuplicatesButton = _dropDuplicatesButton; +@synthesize isInitializedButton = _isInitializedButton; +@synthesize sparseButton = _sparseButton; +@synthesize uniqueButton = _uniqueButton; +@synthesize keyTableView = _keyTableView; + +@synthesize addKeyButton = _addKeyButton; +@synthesize removeKeyButton = _removeKeyButton; +@synthesize cancelButton = _cancelButton; +@synthesize okButton = _okButton; + +@synthesize editedIndex = _editedIndex; +@synthesize indexKeys = _indexKeys; + +@synthesize delegate = _delegate; + +- (id)init +{ + if (self = [super init]) { + self.indexKeys = [NSMutableArray array]; + } + return self; +} + +- (id)initWithEditedIndex:(MODSortedDictionary *)index +{ + if (self = [self init]) { + MODSortedDictionary *keys; + + self.editedIndex = index; + keys = [index objectForKey:@"key"]; + for (NSString *keyName in keys) { + NSNumber *value; + + if ([[keys objectForKey:keyName] isEqual:@"hashed"]) { + value = @POPUP_BUTTON_HASHED_SORTING; + } else if ([[keys objectForKey:keyName] integerValue] == 1) { + value = @POPUP_BUTTON_ASCENDING_SORTING; + } else { + value = @POPUP_BUTTON_DESCENDING_SORTING; + } + [self.indexKeys addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:keyName, @"name", value, @"sorting", nil]]; + } + } + return self; +} + +- (void)dealloc +{ + self.indexKeys = nil; + self.editedIndex = nil; + // the table be still be around longer than the controller + // make sure it will not call the controller after its dealloc + self.keyTableView.delegate = nil; + self.keyTableView.dataSource = nil; + [super dealloc]; +} + +- (void)awakeFromNib +{ + [super awakeFromNib]; + if (self.editedIndex) { + if ([self.editedIndex objectForKey:@"name"]) { + self.nameTextField.stringValue = [self.editedIndex objectForKey:@"name"]; + } + self.backgroundButton.state = ([[self.editedIndex objectForKey:@"background"] integerValue] == 1?NSOnState:NSOffState); + self.dropDuplicatesButton.state = ([[self.editedIndex objectForKey:@"dropDups"] integerValue] == 1?NSOnState:NSOffState); + self.sparseButton.state = ([[self.editedIndex objectForKey:@"sparse"] integerValue] == 1?NSOnState:NSOffState); + self.uniqueButton.state = ([[self.editedIndex objectForKey:@"unique"] integerValue] == 1?NSOnState:NSOffState); + } else { + self.backgroundButton.state = NSOffState; + self.dropDuplicatesButton.state = NSOffState; + self.isInitializedButton.state = NSOffState; + self.sparseButton.state = NSOffState; + self.uniqueButton.state = NSOffState; + } + [self updateViews]; +} + +- (void)menuNeedsUpdate:(NSMenu*)menu +{ + [menu itemAtIndex:0].enabled = YES; + [menu itemAtIndex:1].enabled = YES; + [menu itemAtIndex:2].enabled = (self.indexKeys.count == 1); +} + +- (IBAction)flagButtonAction:(id)sender +{ + [self updateViews]; +} + +- (void)updateViews +{ + self.dropDuplicatesButton.enabled = self.uniqueButton.state == NSOnState; + if (self.uniqueButton.state == NSOffState) { + self.dropDuplicatesButton.state = NSOffState; + } + self.okButton.enabled = self.indexKeys.count > 0; + self.removeKeyButton.enabled = self.keyTableView.numberOfSelectedRows > 0; + self.addKeyButton.enabled = (self.indexKeys.count != 1) || ([[self.indexKeys[0] objectForKey:@"sorting"] integerValue] != 2); +} + +- (void)windowDidLoad +{ + [super windowDidLoad]; +} + +- (NSString *)windowNibName +{ + return @"MHIndexEditor"; +} + +- (void)modalForWindow:(NSWindow *)window +{ + [NSApp beginSheet:self.window modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) contextInfo:nil]; +} + +- (IBAction)addIndexKey:(id)sender +{ + [self.indexKeys addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:@"", @"name", @0, @"sorting", nil]]; + [self.keyTableView reloadData]; + [self updateViews]; + [self.keyTableView editColumn:0 row:self.indexKeys.count - 1 withEvent:nil select:YES]; +} + +- (IBAction)removeIndexKey:(id)sender +{ + if (self.keyTableView.numberOfSelectedRows == 1) { + [self.indexKeys removeObjectAtIndex:self.keyTableView.selectedRow]; + [self.keyTableView reloadData]; + [self updateViews]; + } +} + +- (IBAction)cancelAction:(id)sender +{ + [self.window makeFirstResponder:nil]; + [NSApp endSheet:self.window returnCode:0]; +} + + +- (IBAction)okAction:(id)sender +{ + [self.window makeFirstResponder:nil]; + [NSApp endSheet:self.window returnCode:1]; +} + +- (void)didEndSheet:(NSWindow *)window returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + [self.window orderOut:self]; + if (returnCode == 1) { + [self.delegate indexEditorControllerDidValidate:self]; + } else { + [self.delegate indexEditorControllerDidCancel:self]; + } +} + +- (MODIndexOpt *)indexOptions +{ + MODIndexOpt *result; + + result = [[[MODIndexOpt alloc] init] autorelease]; + if (self.nameTextField.stringValue.length > 0) { + result.name = self.nameTextField.stringValue; + } + result.background = self.backgroundButton.state == NSOnState; + result.dropDups = self.dropDuplicatesButton.state == NSOnState; + result.isInitialized = self.isInitializedButton.state == NSOnState; + result.sparse = self.sparseButton.state == NSOnState; + result.unique = self.uniqueButton.state == NSOnState; + return result; +} + +- (MODSortedDictionary *)keys +{ + MODSortedMutableDictionary *result; + + result = [MODSortedMutableDictionary sortedDictionary]; + for (NSDictionary *key in self.indexKeys) { + id value = nil; + + switch ([key[@"sorting"] integerValue]) { + case POPUP_BUTTON_ASCENDING_SORTING: + value = @1; + break; + case POPUP_BUTTON_HASHED_SORTING: + value = @"hashed"; + break; + case POPUP_BUTTON_DESCENDING_SORTING: + value = @-1; + break; + } + NSAssert(value != nil, @"weird value %@", key[@"sorting"]); + [result setObject:value forKey:key[@"name"]]; + } + return result; +} + +@end + + +@implementation MHIndexEditorController (NSTableViewDataSource) + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + return self.indexKeys.count; +} + +- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + return [self.indexKeys[row] objectForKey:tableColumn.identifier]; +} + +- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + [self.indexKeys[row] setObject:object forKey:tableColumn.identifier]; + [self updateViews]; +} + +@end + +@implementation MHIndexEditorController (NSTableViewDelegate) + +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + [self updateViews]; +} + +@end diff --git a/Sources/ConnectionWindow/MHQueryViewController.h b/Sources/ConnectionWindow/MHQueryViewController.h new file mode 100644 index 00000000..6cf2a307 --- /dev/null +++ b/Sources/ConnectionWindow/MHQueryViewController.h @@ -0,0 +1,107 @@ +// +// MHQueryViewController.h +// MongoHub +// +// Created by Syd on 10-4-28. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import "MHTabItemViewController.h" +#import "UKSyntaxColoredTextViewController.h" +#import "MHDocumentOutlineViewController.h" + +@class MODCollection; +@class MHConnectionStore; +@class MHIndexEditorController; +@class MHDocumentOutlineViewController; + +@interface MHQueryViewController : MHTabItemViewController +{ + NSTabView *_tabView; + NSSegmentedControl *_segmentedControl; + + NSComboBox *_findCriteriaComboBox; + NSTextField *_findFieldFilterTextField; + NSTextField *_findSkipTextField; + NSTextField *_findLimitTextField; + NSTextField *_findSortTextField; + NSTextField *_findTotalResultsTextField; + NSTextField *_findQueryTextField; + NSProgressIndicator *_findQueryLoaderIndicator; + NSView *_findResultView; + + NSButton *_insertButton; + NSTextView *_insertDataTextView; + NSTextField *_insertResultsTextField; + NSProgressIndicator *_insertLoaderIndicator; + + NSView *_updateTabView; + NSButton *_updateButton; + NSTextField *_updateCriteriaTextField; + NSButton *_updateUpsetCheckBox; + NSButton *_updateMultiCheckBox; + NSTextField *_updateResultsTextField; + NSTextField *_updateQueryTextField; + NSProgressIndicator *_updateQueryLoaderIndicator; + + NSButton *_removeButton; + NSTextField *_removeCriteriaTextField; + NSTextField *_removeResultsTextField; + NSTextField *_removeQueryTextField; + NSProgressIndicator *_removeQueryLoaderIndicator; + + NSOutlineView *_indexOutlineView; + NSProgressIndicator *_indexLoaderIndicator; + NSButton *_indexDropButton; + NSButton *_indexCreateButton; + NSView *_indexResultView; + + NSTextView *_aggregationPipeline; + NSTextView *_aggregationOptions; + NSProgressIndicator *_aggregationLoaderIndicator; + NSView *_aggregationResultView; + + NSTextView *_mrMapFunctionTextView; + NSTextView *_mrReduceFunctionTextView; + NSTextField *_mrCriteriaTextField; + NSTextField *_mrOutputTextField; + NSProgressIndicator *_mrLoaderIndicator; + NSOutlineView *_mrOutlineView; + NSView *_mrResultView; +} + +@property (nonatomic, readonly, strong) MODCollection *collection; +@property (nonatomic, readonly, strong) MHConnectionStore *connectionStore; + +- (instancetype)initWithCollection:(MODCollection *)collection connectionStore:(MHConnectionStore *)connectionStore; + +- (IBAction)segmentedControlAction:(id)sender; + +- (void)jsonWindowWillClose:(id)sender; +- (BOOL)canPerformCopy; +- (void)performCopy; + +@end + +@interface MHQueryViewController (InsertTab) +- (IBAction)insertQuery:(id)sender; + +@end + +@interface MHQueryViewController (RemoveTab) +- (IBAction)removeQuery:(id)sender; +- (void)removeQueryComposer:(id)sender; + +@end + +@interface MHQueryViewController (mrTab) +- (IBAction)mapReduce:(id)sender; + +@end + +@interface MHQueryViewController (UKSyntaxColoredTextViewDelegate) +@end + +@interface MHQueryViewController (MHDocumentOutlineViewDelegate) + +@end diff --git a/Sources/ConnectionWindow/MHQueryViewController.m b/Sources/ConnectionWindow/MHQueryViewController.m new file mode 100644 index 00000000..d1ab9423 --- /dev/null +++ b/Sources/ConnectionWindow/MHQueryViewController.m @@ -0,0 +1,1353 @@ +// +// MHQueryViewController.m +// MongoHub +// +// Created by Syd on 10-4-28. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import "MHQueryViewController.h" + +#import "MHDocumentOutlineViewController.h" +#import "NSString+MongoHub.h" +#import "MHJsonWindowController.h" +#import +#import "MODHelper.h" +#import "MHConnectionStore.h" +#import "NSViewHelpers.h" +#import "NSTextView+MongoHub.h" +#import "UKSyntaxColoredTextViewController.h" +#import "MHTabViewController.h" +#import "MHIndexEditorController.h" +#import "MHApplicationDelegate.h" + +#define IS_OBJECT_ID(value) ([value length] == 24 && [[value stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"1234567890abcdefABCDEF"]] length] == 0) + +@interface MHQueryViewController () +@property (nonatomic, readwrite, strong) NSMutableDictionary *jsonWindowControllers; + +@property (nonatomic, readwrite, weak) IBOutlet NSSegmentedControl *segmentedControl; +@property (nonatomic, readwrite, weak) IBOutlet NSTabView *tabView; + +@property (nonatomic, readwrite, strong) MODCollection *collection; +@property (nonatomic, readwrite, strong) MHConnectionStore *connectionStore; + +@property (nonatomic, readwrite, weak) IBOutlet NSComboBox *findCriteriaComboBox; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *findFieldFilterTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *findSkipTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *findLimitTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *findSortTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *findQueryTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *findQueryLoaderIndicator; +@property (nonatomic, readwrite, strong) IBOutlet MHDocumentOutlineViewController *findDocumentOutlineViewController; +@property (nonatomic, readwrite, weak) IBOutlet NSView *findResultView; + +@property (nonatomic, readwrite, weak) IBOutlet NSButton *insertButton; +@property (nonatomic, readwrite, weak) IBOutlet NSTextView *insertDataTextView; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *insertResultsTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *insertLoaderIndicator; +@property (nonatomic, readwrite, strong) UKSyntaxColoredTextViewController *insertSyntaxColoringController; + +@property (nonatomic, readwrite, weak) IBOutlet NSView *updateTabView; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *updateButton; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *updateCriteriaTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *updateUpsetCheckBox; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *updateMultiCheckBox; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *updateResultsTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *updateQueryTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *updateQueryLoaderIndicator; +@property (nonatomic, readwrite, strong) NSMutableArray *updateOperatorViews; +@property (nonatomic, readwrite, strong) NSArray *updateOperatorList; + +@property (nonatomic, readwrite, weak) IBOutlet NSButton *removeButton; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *removeCriteriaTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *removeResultsTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *removeQueryTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *removeQueryLoaderIndicator; + +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *indexLoaderIndicator; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *indexDropButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *indexCreateButton; +@property (nonatomic, readwrite, weak) IBOutlet NSView *indexResultView; +@property (nonatomic, readwrite, strong) IBOutlet MHDocumentOutlineViewController *indexDocumentOutlineViewController; +@property (nonatomic, readwrite, strong) MHIndexEditorController * indexEditorController; + +@property (nonatomic, readwrite, weak) IBOutlet NSTextView *aggregationPipeline; +@property (nonatomic, readwrite, weak) IBOutlet NSTextView *aggregationOptions; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *aggregationLoaderIndicator; +@property (nonatomic, readwrite, weak) IBOutlet NSView *aggregationResultView; +@property (nonatomic, readwrite, strong) IBOutlet MHDocumentOutlineViewController *aggregationDocumentOutlineViewController; +@property (nonatomic, readwrite, strong) UKSyntaxColoredTextViewController *aggregationPipelineSyntaxColoringController; +@property (nonatomic, readwrite, strong) UKSyntaxColoredTextViewController *aggregationOptionsSyntaxColoringController; + +@property (nonatomic, readwrite, weak) IBOutlet NSView *mrResultView; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *mrLoaderIndicator; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *mrOutputTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *mrCriteriaTextField; +@property (nonatomic, readwrite, weak) IBOutlet NSTextView *mrMapFunctionTextView; +@property (nonatomic, readwrite, weak) IBOutlet NSTextView *mrReduceFunctionTextView; +@property (nonatomic, readwrite, strong) IBOutlet MHDocumentOutlineViewController *mrDocumentOutlineViewController; + +- (void)selectBestTextField; + +@end + +@interface MHQueryViewController (FindTab) +- (IBAction)findQuery:(id)sender; +- (void)findQueryComposer; +- (void)defaultSortOrderChangedNotification:(NSNotification *)notification; + +@end + +@interface MHQueryViewController (UpdateTab) +- (IBAction)updateAddOperatorAction:(id)sender; +- (IBAction)updateQueryComposer:(id)sender; + +@end + +@interface MHQueryViewController (IndexTab) +- (IBAction)indexQueryAction:(id)sender; +- (IBAction)createIndexAction:(id)sender; +- (IBAction)dropIndexAction:(id)sender; + +@end + +static NSString *defaultSortOrder(MHDefaultSortOrder defaultSortOrder) +{ + NSString *result; + + if (MHPreferenceWindowController.defaultSortOrder == MHDefaultSortOrderAscending) { + result = @"{ \"_id\": 1}"; + } else { + result = @"{ \"_id\": -1}"; + } + return result; +} + +@implementation MHQueryViewController + +@synthesize tabView = _tabView, segmentedControl = _segmentedControl; + +@synthesize findCriteriaComboBox = _findCriteriaComboBox; +@synthesize findFieldFilterTextField = _findFieldFilterTextField; +@synthesize findSkipTextField = _findSkipTextField; +@synthesize findLimitTextField = _findLimitTextField; +@synthesize findSortTextField = _findSortTextField; +@synthesize findQueryTextField = _findQueryTextField; +@synthesize findQueryLoaderIndicator = _findQueryLoaderIndicator; +@synthesize findResultView = _findResultView; + +@synthesize insertDataTextView = _insertDataTextView; +@synthesize insertResultsTextField = _insertResultsTextField; +@synthesize insertLoaderIndicator = _insertLoaderIndicator; +@synthesize insertButton = _insertButton; + +@synthesize updateTabView = _updateTabView; +@synthesize updateButton = _updateButton; +@synthesize updateCriteriaTextField = _updateCriteriaTextField; +@synthesize updateUpsetCheckBox = _updateUpsetCheckBox; +@synthesize updateMultiCheckBox = _updateMultiCheckBox; +@synthesize updateResultsTextField = _updateResultsTextField; +@synthesize updateQueryTextField = _updateQueryTextField; +@synthesize updateQueryLoaderIndicator = _updateQueryLoaderIndicator; + +@synthesize removeButton = _removeButton; +@synthesize removeCriteriaTextField = _removeCriteriaTextField; +@synthesize removeResultsTextField = _removeResultsTextField; +@synthesize removeQueryTextField = _removeQueryTextField; +@synthesize removeQueryLoaderIndicator = _removeQueryLoaderIndicator; + +@synthesize indexLoaderIndicator = _indexLoaderIndicator; +@synthesize indexDropButton = _indexDropButton; +@synthesize indexCreateButton = _indexCreateButton; +@synthesize indexResultView = _indexResultView; + +@synthesize aggregationPipeline = _aggregationPipeline; +@synthesize aggregationOptions = _aggregationOptions; +@synthesize aggregationLoaderIndicator = _aggregationLoaderIndicator; +@synthesize aggregationResultView = _aggregationResultView; + +@synthesize mrResultView = _mrResultView; +@synthesize mrLoaderIndicator = _mrLoaderIndicator; +@synthesize mrOutputTextField = _mrOutputTextField; +@synthesize mrCriteriaTextField = _mrCriteriaTextField; +@synthesize mrMapFunctionTextView = _mrMapFunctionTextView; +@synthesize mrReduceFunctionTextView = _mrReduceFunctionTextView; + +- (instancetype)initWithCollection:(MODCollection *)collection connectionStore:(MHConnectionStore *)connectionStore +{ + self = [self init]; + if (self) { + self.collection = collection; + self.connectionStore = connectionStore; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(droppedNotification:) name:MODCollection_Dropped_Notification object:self.collection]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(droppedNotification:) name:MODDatabase_Dropped_Notification object:self.collection.database]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(defaultSortOrderChangedNotification:) name:MHDefaultSortOrderPreferenceChangedNotification object:nil]; + [self.collection addObserver:self forKeyPath:@"database" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil]; + [self.collection addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil]; + self.updateOperatorList = @[ + @{ @"title": @"Current Date", @"key": @"$currentDate" }, + @{ @"title": @"Increment", @"key": @"$inc" }, + @{ @"title": @"Max", @"key": @"$max" }, + @{ @"title": @"Min", @"key": @"$min" }, + @{ @"title": @"Multiply", @"key": @"$mul" }, + @{ @"title": @"Rename", @"key": @"$rename" }, + @{ @"title": @"Set On Insert", @"key": @"$setOnInsert" }, + @{ @"title": @"Set", @"key": @"$set" }, + @{ @"title": @"Unset", @"key": @"$unset" }, + @{}, + @{ @"title": @"Add To Set", @"key": @"$addToSet" }, + @{ @"title": @"Pop", @"key": @"$pop" }, + @{ @"title": @"Pull All", @"key": @"$pullAll" }, + @{ @"title": @"Pull", @"key": @"$pull" }, + @{ @"title": @"Push All", @"key": @"$pushAll" }, + @{ @"title": @"Push", @"key": @"$push" }, + @{}, + @{ @"title": @"Bit", @"key": @"$bit" }, + ]; + } + return self; +} + + +- (void)dealloc +{ + [NSNotificationCenter.defaultCenter removeObserver:self name:nil object:nil]; + [self.collection removeObserver:self forKeyPath:@"database"]; + [self.collection removeObserver:self forKeyPath:@"name"]; + + self.insertSyntaxColoringController = nil; + self.findDocumentOutlineViewController = nil; + self.indexDocumentOutlineViewController = nil; + self.indexEditorController = nil; + + self.mrDocumentOutlineViewController = nil; + self.collection = nil; + self.connectionStore = nil; + self.updateOperatorViews = nil; + self.updateOperatorList = nil; + + self.aggregationDocumentOutlineViewController = nil; + self.aggregationPipelineSyntaxColoringController = nil; + self.aggregationOptionsSyntaxColoringController = nil; + + self.jsonWindowControllers = nil; + + [super dealloc]; +} + +- (void)droppedNotification:(NSNotification *)notification +{ + NSParameterAssert(notification.object == self.collection || notification.object == self.collection.database); + if (notification.object == self.collection || notification.object == self.collection.database) { + [self.tabViewController removeTabItemViewController:self]; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (self.collection == object) { + if ([keyPath isEqualToString:@"name"]) { + self.title = self.collection.absoluteName; + } else if ([keyPath isEqualToString:@"database"]) { + self.title = self.collection.absoluteName; + [NSNotificationCenter.defaultCenter removeObserver:self name:nil object:change[NSKeyValueChangeOldKey]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(droppedNotification:) name:MODDatabase_Dropped_Notification object:self.collection.database]; + } + } +} + +- (NSString *)nibName +{ + return @"MHQueryView"; +} + +- (void)awakeFromNib +{ + MHApplicationDelegate *appDelegate = (MHApplicationDelegate *)NSApplication.sharedApplication.delegate; + + self.updateOperatorViews = [NSMutableArray array]; + [self updateAddOperatorAction:nil]; + + [MHDocumentOutlineViewController addDocumentOutlineViewController:self.findDocumentOutlineViewController intoView:self.findResultView]; + + self.insertSyntaxColoringController = MOD_AUTORELEASE([[UKSyntaxColoredTextViewController alloc] init]); + self.insertSyntaxColoringController.delegate = self; + self.insertSyntaxColoringController.view = self.insertDataTextView; + + [MHDocumentOutlineViewController addDocumentOutlineViewController:self.indexDocumentOutlineViewController intoView:self.indexResultView]; + + [MHDocumentOutlineViewController addDocumentOutlineViewController:self.mrDocumentOutlineViewController intoView:self.mrResultView]; + + self.title = self.collection.absoluteName; + self.jsonWindowControllers = [NSMutableDictionary dictionary]; + [self defaultSortOrderChangedNotification:nil]; // this will call findQueryComposer + [self updateQueryComposer:nil]; + [self removeQueryComposer:nil]; + + self.aggregationPipelineSyntaxColoringController = MOD_AUTORELEASE([[UKSyntaxColoredTextViewController alloc] init]); + self.aggregationPipelineSyntaxColoringController.delegate = self; + self.aggregationPipelineSyntaxColoringController.view = self.aggregationPipeline; + self.aggregationOptionsSyntaxColoringController = MOD_AUTORELEASE([[UKSyntaxColoredTextViewController alloc] init]); + self.aggregationOptionsSyntaxColoringController.delegate = self; + self.aggregationOptionsSyntaxColoringController.view = self.aggregationOptions; + [MHDocumentOutlineViewController addDocumentOutlineViewController:self.aggregationDocumentOutlineViewController intoView:self.aggregationResultView]; + + [self.insertDataTextView mh_jsonSetup]; + [self.mrReduceFunctionTextView mh_jsonSetup]; + [self.mrMapFunctionTextView mh_jsonSetup]; + + if (!appDelegate.hasCollectionMapReduceTab) { + // remove map/reduce + self.segmentedControl.segmentCount = 6; + [self.tabView removeTabViewItem:[self.tabView tabViewItemAtIndex:6]]; + } + if (!appDelegate.hasCollectionAggregationTab) { + // remove aggregation + [self.segmentedControl setImage:[self.segmentedControl imageForSegment:6] forSegment:5]; + [self.segmentedControl setImageScaling:[self.segmentedControl imageScalingForSegment:6] forSegment:5]; + [self.segmentedControl setLabel:[self.segmentedControl labelForSegment:6] forSegment:5]; + [self.segmentedControl setMenu:[self.segmentedControl menuForSegment:6] forSegment:5]; + [self.segmentedControl setSelected:[self.segmentedControl isSelectedForSegment:6] forSegment:5]; + [self.segmentedControl setEnabled:[self.segmentedControl isEnabledForSegment:6] forSegment:5]; + [self.segmentedControl setWidth:[self.segmentedControl widthForSegment:6] forSegment:5]; + self.segmentedControl.segmentCount = 6; + [self.tabView removeTabViewItem:[self.tabView tabViewItemAtIndex:5]]; + } +} + +- (NSString *)formatedJsonWithTextField:(NSTextField *)textField replace:(BOOL)replace emptyValid:(BOOL)emptyValid +{ + NSString *query = @""; + NSString *value; + NSString *valueWithoutDoubleQuotes = nil; + + value = [textField.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if ([value hasPrefix:@"\""] && [value hasSuffix:@"\""] && ![value isEqualToString:@"\""]) { + valueWithoutDoubleQuotes = [value substringWithRange:NSMakeRange(1, value.length - 2)]; + } + if (IS_OBJECT_ID(value) || IS_OBJECT_ID(valueWithoutDoubleQuotes)) { + // 24 char length and only hex char... it must be an objectid + if (valueWithoutDoubleQuotes) { + query = [NSString stringWithFormat:@"{\"_id\": ObjectId(\"%@\")}", valueWithoutDoubleQuotes]; + } else { + query = [NSString stringWithFormat:@"{\"_id\": ObjectId(\"%@\")}", value]; + } + } else if ([value length] > 0) { + if ([value hasPrefix:@"{"]) { + NSString *innerValue; + + innerValue = [[value substringFromIndex:1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if ([innerValue hasPrefix:@"\"$oid\""] || [innerValue hasPrefix:@"'$iod'"]) { + query = [NSString stringWithFormat:@"{\"_id\": %@ }",value]; + } else { + query = value; + } + } else if ([value hasPrefix:@"ObjectId"]) { + query = [NSString stringWithFormat:@"{\"_id\": %@}",value]; + } else if ([value hasPrefix:@"\"$oid\""] || [value hasPrefix:@"'$iod'"]) { + query = [NSString stringWithFormat:@"{\"_id\": {%@}}",value]; + } else if ([value rangeOfString:@":"].location != NSNotFound) { + query = [NSString stringWithFormat:@"{ %@ }", value]; + } else if ([value hasPrefix:@"\""]) { + query = [NSString stringWithFormat:@"{\"_id\": %@}", value]; + } else { + query = [NSString stringWithFormat:@"{\"_id\": \"%@\"}", value]; + } + } + if (replace) { + textField.stringValue = query; + [textField selectText:nil]; + } + if (!emptyValid && [query isEqualToString:@""]) { + query = @"{}"; + } + return query; +} + +- (void)select +{ + [super select]; + [self selectBestTextField]; +} + +- (void)_removeQueryWithCriteria:(MODSortedDictionary *)criteria +{ + [self.removeQueryLoaderIndicator startAnimation:nil]; + [self.collection countWithCriteria:criteria readPreferences:nil callback:^(int64_t count, MODQuery *mongoQuery) { + [self.collection removeWithCriteria:criteria callback:^(MODQuery *removeQuery) { + NSColor *flashColor; + + if (removeQuery.error) { + self.removeResultsTextField.stringValue = @"Error!"; + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", removeQuery.error.localizedDescription); + flashColor = NSColor.redColor; + } else { + self.removeResultsTextField.stringValue = [NSString stringWithFormat:@"Removed Documents: %lld", count]; + flashColor = NSColor.greenColor; + } + [self.removeQueryLoaderIndicator stopAnimation:nil]; + [NSViewHelpers cancelColorForTarget:self.removeResultsTextField selector:@selector(setTextColor:)]; + [NSViewHelpers setColor:self.removeResultsTextField.textColor fromColor:flashColor toTarget:self.removeResultsTextField withSelector:@selector(setTextColor:) delay:1]; + }]; + }]; +} + +- (void)removeAllDocumentsPanelDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(MODSortedDictionary *)criteria +{ + switch (returnCode) { + case NSAlertAlternateReturn: + [self _removeQueryWithCriteria:criteria]; + break; + + default: + break; + } + [criteria release]; +} + +- (void)controlTextDidChange:(NSNotification *)notification +{ + NSTextField *textField = notification.object; + + if (textField == self.findCriteriaComboBox || textField == self.findFieldFilterTextField || textField == self.findSortTextField || textField == self.findSkipTextField || textField == self.findLimitTextField) { + [self findQueryComposer]; + } else if (textField == self.updateCriteriaTextField || textField.superview.superview == self.updateTabView) { + [self updateQueryComposer:nil]; + } else if (textField == self.removeCriteriaTextField) { + [self removeQueryComposer:nil]; + } + +} + +-(void)controlTextDidEndEditing:(NSNotification *)notification +{ + NSTextField *textField = notification.object; + + if ((textField == self.findCriteriaComboBox || textField == self.findFieldFilterTextField || textField == self.findSortTextField || textField == self.findSkipTextField || textField == self.findLimitTextField) && [notification.userInfo[@"NSTextMovement"] intValue] == NSReturnTextMovement ) { + [self findQuery:nil]; + } +} + +- (void)jsonWindowWillClose:(NSNotification *)notification +{ + MHJsonWindowController *jsonWindowController = notification.object; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:kJsonWindowSaved object:notification.object]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:kJsonWindowWillClose object:notification.object]; + [self.jsonWindowControllers removeObjectForKey:jsonWindowController.windowControllerId]; +} + +- (IBAction)segmentedControlAction:(id)sender +{ + [self.tabView selectTabViewItemAtIndex:self.segmentedControl.selectedSegment]; + [self selectBestTextField]; +} + +- (void)selectBestTextField +{ + [self.findQueryTextField.window makeFirstResponder:self.tabView.selectedTabViewItem.initialFirstResponder ]; +} + +// REMOVE when 10.9 is not supported anymore +- (BOOL)canPerformCopy +{ + if ([[self.tabView selectedTabViewItem].identifier isEqualToString:@"find"]) { + return self.findDocumentOutlineViewController.canCopyDocuments; + } else if ([[self.tabView selectedTabViewItem].identifier isEqualToString:@"aggregation"]) { + return self.aggregationDocumentOutlineViewController.canCopyDocuments; + } else if ([[self.tabView selectedTabViewItem].identifier isEqualToString:@"mapreduce"]) { + return self.mrDocumentOutlineViewController.canCopyDocuments; + } + return NO; +} + +// REMOVE when 10.9 is not supported anymore +- (void)performCopy +{ + if ([[self.tabView selectedTabViewItem].identifier isEqualToString:@"find"] && self.findDocumentOutlineViewController.canCopyDocuments) { + [self.findDocumentOutlineViewController copyDocuments]; + } else if ([[self.tabView selectedTabViewItem].identifier isEqualToString:@"aggregation"] && self.aggregationDocumentOutlineViewController.canCopyDocuments) { + [self.aggregationDocumentOutlineViewController copyDocuments]; + } else if ([[self.tabView selectedTabViewItem].identifier isEqualToString:@"mapreduce"] && self.mrDocumentOutlineViewController.canCopyDocuments) { + [self.mrDocumentOutlineViewController copyDocuments]; + } +} + +@end + +@implementation MHQueryViewController (FindTab) + +- (NSString *)formatedQuerySort +{ + NSString *result; + + result = [self formatedJsonWithTextField:self.findSortTextField replace:NO emptyValid:YES]; + if ([result length] == 0) { + result = defaultSortOrder(MHPreferenceWindowController.defaultSortOrder); + } + return result; +} + +- (IBAction)findQuery:(id)sender +{ + int limit = self.findLimitTextField.intValue; + NSString *criteriaJson; + NSString *fieldFilterJson; + NSString *sortJson = self.formatedQuerySort; + NSString *queryTitle = self.findCriteriaComboBox.stringValue; + MODSortedDictionary *criteria = nil; + MODSortedDictionary *fieldFilter = nil; + MODSortedDictionary *sort = nil; + id fieldWithError = nil; + NSError *error = nil; + + [self findQueryComposer]; + if (limit <= 0) { + limit = 30; + } + criteriaJson = [self formatedJsonWithTextField:self.findCriteriaComboBox replace:YES emptyValid:NO]; + fieldFilterJson = [self formatedJsonWithTextField:self.findFieldFilterTextField replace:YES emptyValid:NO]; + [self.findQueryLoaderIndicator startAnimation:nil]; + + criteria = [MODRagelJsonParser objectsFromJson:criteriaJson withError:&error]; + fieldWithError = self.findCriteriaComboBox; + if (!error) { + sort = [MODRagelJsonParser objectsFromJson:sortJson withError:&error]; + fieldWithError = self.findSortTextField; + } + if (!error) { + fieldFilter = [MODRagelJsonParser objectsFromJson:fieldFilterJson withError:&error]; + fieldWithError = self.findFieldFilterTextField; + } + if (error) { + NSString *errorMessage = [NSString stringWithFormat:@"Error: %@", error.localizedDescription]; + + [self.findDocumentOutlineViewController displayErrorLabel:errorMessage]; + self.findQueryTextField.stringValue = errorMessage; + [self.findQueryLoaderIndicator stopAnimation:nil]; + [fieldWithError becomeFirstResponder]; + } else { + [self.collection findWithCriteria:criteria + fields:fieldFilter + skip:self.findSkipTextField.intValue + limit:limit + sort:sort + callback:^(NSArray *documents, NSArray *bsonData, MODQuery *mongoQuery) { + if (mongoQuery.error) { + NSString *errorMessage = [NSString stringWithFormat:@"Error: %@", [mongoQuery.error localizedDescription]]; + [self.findDocumentOutlineViewController displayErrorLabel:errorMessage]; + self.findQueryTextField.stringValue = errorMessage; + } else { + NSArray *convertedDocuments = nil; + + if ([queryTitle length] > 0) { + [self.connectionStore addNewQuery:@{ + @"title": queryTitle, + @"sort": self.findSortTextField.stringValue, + @"fields": self.findFieldFilterTextField.stringValue, + @"limit": self.findLimitTextField.stringValue, + @"skip": self.findSkipTextField.stringValue + } + withDatabaseName:@"" + collectionName:self.collection.name]; + } + convertedDocuments = [MODHelper convertForOutlineWithObjects:documents bsonData:bsonData jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch]; + [self.findDocumentOutlineViewController displayDocuments:convertedDocuments withLabel:nil]; + [self.findDocumentOutlineViewController setBackButtonEnabled:self.findSkipTextField.stringValue.integerValue != 0]; + [self.collection countWithCriteria:criteria readPreferences:nil callback:^(int64_t count, MODQuery *countQuery) { + [self.findDocumentOutlineViewController displayLabel:[NSString stringWithFormat:@"Total Results: %lld (%0.2fs)", count, [[countQuery.userInfo objectForKey:@"timequery"] duration]]]; + }]; + } + [self.findQueryLoaderIndicator stopAnimation:nil]; + }]; + } +} + +- (void)findQueryComposer +{ + NSString *criteria = [self formatedJsonWithTextField:self.findCriteriaComboBox replace:NO emptyValid:YES]; + NSString *fieldFilterJson = [self formatedJsonWithTextField:self.findFieldFilterTextField replace:NO emptyValid:YES]; + NSString *sortValue = [self formatedQuerySort]; + NSString *sort; + + if (fieldFilterJson.length > 0) { + fieldFilterJson = [NSString stringWithFormat:@", %@", fieldFilterJson]; + } + + if ([sortValue length] > 0) { + sort = [[NSString alloc] initWithFormat:@".sort(%@)", sortValue]; + }else { + sort = [[NSString alloc] initWithString:@""]; + } + + NSString *skip = [[NSString alloc] initWithFormat:@".skip(%d)", self.findSkipTextField.intValue]; + NSString *limit = [[NSString alloc] initWithFormat:@".limit(%d)", self.findLimitTextField.intValue]; + NSString *col = [NSString stringWithFormat:@"%@", self.collection.name]; + + NSString *query = [NSString stringWithFormat:@"db.%@.find(%@%@)%@%@%@", col, criteria, fieldFilterJson, sort, skip, limit]; + [sort release]; + [skip release]; + [limit release]; + self.findQueryTextField.stringValue = query; +} + +- (void)defaultSortOrderChangedNotification:(NSNotification *)notification +{ + [self.findSortTextField.cell setPlaceholderString:defaultSortOrder([MHPreferenceWindowController defaultSortOrder])]; + [self findQueryComposer]; +} + +@end + +@implementation MHQueryViewController (InsertTab) + +- (IBAction)insertQuery:(id)sender +{ + id objects; + NSError *error; + NSString *json; + + [self.insertLoaderIndicator startAnimation:nil]; + if ([[self.insertDataTextView.string stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet] characterAtIndex:0] == '[') { + json = self.insertDataTextView.string; + } else { + json = [NSString stringWithFormat:@"[ %@ ]", self.insertDataTextView.string]; + } + objects = [MODRagelJsonParser objectsFromJson:json withError:&error]; + if (error) { + NSColor *currentColor; + + [self.insertLoaderIndicator stopAnimation:nil]; + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", error.localizedDescription); + self.insertResultsTextField.stringValue = @"Parsing error"; + [NSViewHelpers cancelColorForTarget:self.insertResultsTextField selector:@selector(setTextColor:)]; + currentColor = self.insertResultsTextField.textColor; + self.insertResultsTextField.textColor = [NSColor redColor]; + [NSViewHelpers setColor:currentColor fromColor:[NSColor redColor] toTarget:self.insertResultsTextField withSelector:@selector(setTextColor:) delay:1]; + } else { + if ([objects isKindOfClass:[MODSortedDictionary class]]) { + objects = [NSArray arrayWithObject:objects]; + } + [self.collection insertWithDocuments:objects writeConcern:nil callback:^(MODQuery *mongoQuery) { + NSColor *currentColor; + NSColor *flashColor; + + [self.insertLoaderIndicator stopAnimation:nil]; + if (mongoQuery.error) { + flashColor = [NSColor redColor]; + [self.insertResultsTextField setStringValue:@"Error!"]; + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", mongoQuery.error.localizedDescription); + } else { + flashColor = [NSColor greenColor]; + [self.insertResultsTextField setStringValue:@"Completed!"]; + } + [NSViewHelpers cancelColorForTarget:self.insertResultsTextField selector:@selector(setTextColor:)]; + currentColor = self.insertResultsTextField.textColor; + self.insertResultsTextField.textColor = flashColor; + [NSViewHelpers setColor:currentColor fromColor:flashColor toTarget:self.insertResultsTextField withSelector:@selector(setTextColor:) delay:1]; + }]; + } +} + +@end + +@implementation MHQueryViewController (UpdateTab) + +- (void)_updatePrint +{ + NSUInteger ii = 0; + + for (NSDictionary *views in self.updateOperatorViews) { + NSLog(@"%lu %@ %@", (unsigned long)ii, [views[@"popup"] titleOfSelectedItem], views[@"main"]); + ii++; + } +} + +- (NSString *)_updateStringOperatorWithPopUpButton:(NSPopUpButton *)button +{ + NSUInteger index = button.indexOfSelectedItem; + NSDictionary *item; + + NSAssert(index < self.updateOperatorList.count, @"index too high %lu %lu", (unsigned long)index, (unsigned long)self.updateOperatorList.count); + item = self.updateOperatorList[index]; + NSAssert(item.count == 2, @"it should be a regular item %@", item); + return item[@"key"]; +} + +- (void)_updatePopUpButtonSetup:(NSPopUpButton *)button +{ + NSMenu *menu = button.menu; + NSUInteger index = 0, ii; + + [menu removeAllItems]; + ii = 0; + for (NSDictionary *item in self.updateOperatorList) { + if (item.count == 0) { + [menu addItem:[NSMenuItem separatorItem]]; + } else { + [menu addItemWithTitle:item[@"title"] action:nil keyEquivalent:@""]; + if ([item[@"key"] isEqualToString:@"$set"]) { + index = ii; + } + } + ii++; + } + [button selectItemAtIndex:-1]; + if (self.updateOperatorViews.count == 0) { + // the first NSPopUpButton should be set to "Set" + // it is probably the most common operator used + [button selectItemAtIndex:index]; + } +} + +- (NSUInteger)_updateIndexOfOperatorWithView:(NSView *)view +{ + NSUInteger index = NSNotFound, ii; + + ii = 0; + for (NSDictionary *views in self.updateOperatorViews) { + if ([views.allValues containsObject:view]) { + index = ii; + break; + } + ii++; + } + return index; +} + +- (void)_updateCreateLayoutConstraintsWithOperatorMainView:(NSView *)mainView previousView:(NSView *)previousView +{ + for (NSLayoutConstraint *constraint in self.updateTabView.constraints) { + if (constraint.firstItem == mainView) { + [self.updateTabView removeConstraint:constraint]; + } + } + [self.updateTabView addConstraint:[NSLayoutConstraint constraintWithItem:mainView + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:previousView + attribute:NSLayoutAttributeBottom + multiplier:1.0 + constant:8.0]]; + [self.updateTabView addConstraint:[NSLayoutConstraint constraintWithItem:mainView + attribute:NSLayoutAttributeLeading + relatedBy:NSLayoutRelationEqual + toItem:self.updateTabView + attribute:NSLayoutAttributeLeading + multiplier:1.0 + constant:0.0]]; + [self.updateTabView addConstraint:[NSLayoutConstraint constraintWithItem:mainView + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:self.updateTabView + attribute:NSLayoutAttributeTrailing + multiplier:1.0 + constant:0.0]]; +} + +- (IBAction)updateAddOperatorAction:(id)sender +{ + NSMutableDictionary *line = [NSMutableDictionary dictionary]; + NSView *mainView = nil; + NSView *previousView; + NSUInteger previousViewIndex; + NSViewController *viewController = [[[NSViewController alloc] init] autorelease]; + + [NSBundle.mainBundle loadNibNamed:@"MHQueryUpdateOperatorView" owner:viewController topLevelObjects:nil]; + mainView = viewController.view; + NSAssert(mainView != nil, @"Should have found one top level object"); + line[@"main"] = mainView; + line[@"popup"] = [mainView viewWithTag:1]; + line[@"textfield"] = [mainView viewWithTag:2]; + line[@"+"] = [mainView viewWithTag:3]; + line[@"-"] = [mainView viewWithTag:4]; + [(NSTextField *)line[@"textfield"] setDelegate:self]; + [line[@"+"] setTarget:self]; + [line[@"+"] setAction:@selector(updateAddOperatorAction:)]; + [line[@"-"] setTarget:self]; + [line[@"-"] setAction:@selector(updateRemoveOperatorAction:)]; + [line[@"-"] setTarget:self]; + [line[@"popup"] setAction:@selector(updateOperatorPopButtonAction:)]; + [self _updatePopUpButtonSetup:line[@"popup"]]; + [line[@"popup"] menu].autoenablesItems = NO; + for (NSMenuItem *item in [line[@"popup"] menu].itemArray) { + item.target = self; + item.action = @selector(updateOperatorPopButtonAction:); + } + [self.updateTabView addSubview:mainView]; + + if (sender) { + previousView = [sender superview]; + previousViewIndex = [self _updateIndexOfOperatorWithView:previousView]; + } else { + previousView = self.updateCriteriaTextField; + previousViewIndex = NSNotFound; + } + [self _updateCreateLayoutConstraintsWithOperatorMainView:mainView previousView:previousView]; + + if (sender) { + [self.updateOperatorViews insertObject:line atIndex:previousViewIndex + 1]; + if (self.updateOperatorViews.count > previousViewIndex + 2) { + [self _updateCreateLayoutConstraintsWithOperatorMainView:[[self.updateOperatorViews objectAtIndex:previousViewIndex + 2] objectForKey:@"main"] previousView:mainView]; + } + } else { + [self.updateOperatorViews addObject:line]; + } + + if (!sender) { + [line[@"-"] setNextKeyView:self.updateCriteriaTextField.nextKeyView]; + self.updateCriteriaTextField.nextKeyView = line[@"popup"]; + } else { + [line[@"-"] setNextKeyView:[[self.updateOperatorViews[previousViewIndex] objectForKey:@"-"] nextKeyView]]; + [[self.updateOperatorViews[previousViewIndex] objectForKey:@"-"] setNextKeyView:line[@"popup"]]; + } + + [self updateOperatorPopButtonAction:nil]; +} + +- (IBAction)updateRemoveOperatorAction:(id)sender +{ + NSView *mainView = [sender superview]; + NSUInteger index = [self _updateIndexOfOperatorWithView:mainView]; + + if (index == 0) { + self.updateCriteriaTextField.nextKeyView = [[self.updateOperatorViews[index] objectForKey:@"-"] nextKeyView]; + } else { + [[self.updateOperatorViews[index - 1] objectForKey:@"-"] setNextKeyView:[[self.updateOperatorViews[index] objectForKey:@"-"] nextKeyView]]; + } + [mainView removeFromSuperview]; + [self.updateOperatorViews removeObjectAtIndex:index]; + if (index == 0) { + [self _updateCreateLayoutConstraintsWithOperatorMainView:[[self.updateOperatorViews objectAtIndex:index] objectForKey:@"main"] previousView:self.updateCriteriaTextField]; + } else if (self.updateOperatorViews.count > index) { + [self _updateCreateLayoutConstraintsWithOperatorMainView:[[self.updateOperatorViews objectAtIndex:index] objectForKey:@"main"] previousView:[[self.updateOperatorViews objectAtIndex:index - 1] objectForKey:@"main"]]; + } + + [self updateOperatorPopButtonAction:nil]; +} + +- (IBAction)updateOperatorPopButtonAction:(id)sender +{ + NSMutableIndexSet *usedIndexes = [NSMutableIndexSet indexSet]; + NSMutableIndexSet *unusedIndexes = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.updateOperatorList.count)]; + NSMutableArray *shouldBeUpdated = [NSMutableArray array]; + + [self.updateOperatorList enumerateObjectsUsingBlock:^(NSDictionary *item, NSUInteger index, BOOL *stop) { + if (item.count == 0) { + [usedIndexes addIndex:index]; + [unusedIndexes removeIndex:index]; + } + }]; + for (NSDictionary *lineViews in self.updateOperatorViews) { + NSPopUpButton *popupButton = lineViews[@"popup"]; + NSInteger selectedItem = [popupButton indexOfSelectedItem]; + + if (selectedItem == -1 || [usedIndexes containsIndex:selectedItem]) { + [shouldBeUpdated addObject:popupButton]; + } else { + [usedIndexes addIndex:selectedItem]; + [unusedIndexes removeIndex:selectedItem]; + } + } + for (NSPopUpButton *button in shouldBeUpdated) { + NSUInteger index = [unusedIndexes firstIndex]; + + [button.menu itemAtIndex:index].enabled = YES; + [button selectItemAtIndex:index]; + [unusedIndexes removeIndex:index]; + [usedIndexes addIndex:index]; + } + for (NSDictionary *lineViews in self.updateOperatorViews) { + NSUInteger ii, selectedItemIndex; + NSMenu *menu; + + [lineViews[@"+"] setEnabled:(usedIndexes.count != self.updateOperatorList.count)]; + [lineViews[@"-"] setEnabled:(self.updateOperatorViews.count > 1)]; + menu = lineViews[@"popup"]; + selectedItemIndex = [lineViews[@"popup"] indexOfSelectedItem]; + for (ii = 0; ii < self.updateOperatorList.count; ii++) { + if (ii != selectedItemIndex) { + [menu itemAtIndex:ii].enabled = [unusedIndexes containsIndex:ii]; + } + } + } + [self updateQueryComposer:nil]; +} + +- (IBAction)updateQuery:(id)sender +{ + MODSortedDictionary *query = nil; + MODSortedMutableDictionary *update = [MODSortedMutableDictionary sortedDictionary]; + NSError *error = nil; + + [self.updateQueryLoaderIndicator startAnimation:nil]; + query = [MODRagelJsonParser objectsFromJson:[self formatedJsonWithTextField:self.updateCriteriaTextField replace:NO emptyValid:NO] withError:&error]; + if (error) { + NSBeginAlertSheet(@"Error In Query", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", error.localizedDescription); + [NSViewHelpers cancelColorForTarget:self.updateResultsTextField selector:@selector(setTextColor:)]; + [NSViewHelpers setColor:self.updateResultsTextField.textColor + fromColor:NSColor.redColor + toTarget:self.updateResultsTextField + withSelector:@selector(setTextColor:) + delay:1]; + [self.updateCriteriaTextField becomeFirstResponder]; + return; + } + for (NSDictionary *views in self.updateOperatorViews) { + NSTextField *textField = views[@"textfield"]; + NSPopUpButton *popUpButton = views[@"popup"]; + MODSortedDictionary *value; + NSString *key = popUpButton.titleOfSelectedItem; + + value = [MODRagelJsonParser objectsFromJson:[self formatedJsonWithTextField:textField replace:NO emptyValid:NO] withError:&error]; + if (error) { + NSBeginAlertSheet([NSString stringWithFormat:@"Error In %@", key], @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", error.localizedDescription); + [NSViewHelpers cancelColorForTarget:self.updateResultsTextField selector:@selector(setTextColor:)]; + [NSViewHelpers setColor:self.updateResultsTextField.textColor + fromColor:NSColor.redColor + toTarget:self.updateResultsTextField + withSelector:@selector(setTextColor:) + delay:1]; + [textField becomeFirstResponder]; + return; + } + key = [self _updateStringOperatorWithPopUpButton:popUpButton]; + [update setObject:value forKey:key]; + } + [self.collection countWithCriteria:query readPreferences:nil callback:^(int64_t count, MODQuery *mongoQuery) { + if (self.updateMultiCheckBox.state == 0 && count > 0) { + count = 1; + } + + [self.collection updateWithCriteria:query + update:update + upsert:self.updateUpsetCheckBox.state + multiUpdate:self.updateMultiCheckBox.state + writeConcern:nil + callback:^(MODQuery *updateQuery) { + NSColor *flashColor; + + if (updateQuery.error) { + self.updateResultsTextField.stringValue = @"Error!"; + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", updateQuery.error.localizedDescription); + flashColor = NSColor.redColor; + } else { + self.updateResultsTextField.stringValue = [NSString stringWithFormat:@"Updated Documents: %lld", count]; + flashColor = NSColor.greenColor; + } + [self.updateQueryLoaderIndicator stopAnimation:nil]; + [NSViewHelpers cancelColorForTarget:self.updateResultsTextField selector:@selector(setTextColor:)]; + [NSViewHelpers setColor:self.updateResultsTextField.textColor + fromColor:flashColor + toTarget:self.updateResultsTextField + withSelector:@selector(setTextColor:) + delay:1]; + }]; + }]; +} + +- (IBAction)updateQueryComposer:(id)sender +{ + NSUInteger ii; + NSString *critical; + NSMutableString *sets; + NSMutableString *options = [NSMutableString string]; + + critical = [self formatedJsonWithTextField:self.updateCriteriaTextField replace:NO emptyValid:NO]; + sets = [NSMutableString stringWithString:@", {"]; + ii = 0; + for (NSDictionary *views in self.updateOperatorViews) { + if (ii > 0) { + [sets appendString:@", "]; + } + [sets appendString:[self _updateStringOperatorWithPopUpButton:views[@"popup"]]]; + [sets appendString:@": "]; + [sets appendString:[self formatedJsonWithTextField:views[@"textfield"] replace:NO emptyValid:NO]]; + ii++; + } + [sets appendString:@"}"]; + + if (self.updateUpsetCheckBox.state == 1) { + [options appendString:@", { upset: true"]; + } + + if (self.updateMultiCheckBox.state == 1) { + if (options.length == 0) { + [options appendString:@", { "]; + } else { + [options appendString:@", "]; + } + [options appendString:@"multi: true "]; + } + if (options.length != 0) { + [options appendString:@"}"]; + } + + self.updateQueryTextField.stringValue = [NSString stringWithFormat:@"db.%@.update(%@%@%@)", self.collection.name, critical, sets, options]; +} + +@end + +@implementation MHQueryViewController (RemoveTab) + +- (IBAction)removeQuery:(id)sender +{ + MODSortedDictionary *criteria; + NSError *error; + + criteria = [MODRagelJsonParser objectsFromJson:[self formatedJsonWithTextField:self.removeCriteriaTextField replace:NO emptyValid:NO] withError:&error]; + if (error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, @"%@", @"%@", error.localizedDescription); + } else if ([criteria count] == 0 && ((self.view.window.currentEvent.modifierFlags & NSCommandKeyMask) != NSCommandKeyMask)) { + NSAlert *alert; + + alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:@"Are you sure you want to remove all documents in %@", self.collection.absoluteName] defaultButton:@"Cancel" alternateButton:@"Remove All" otherButton:nil informativeTextWithFormat:@"This action cannot be undone"]; + [alert setAlertStyle:NSCriticalAlertStyle]; + [alert beginSheetModalForWindow:self.view.window modalDelegate:self didEndSelector:@selector(removeAllDocumentsPanelDidEnd:returnCode:contextInfo:) contextInfo:[criteria retain]]; + } else { + [self _removeQueryWithCriteria:criteria]; + } +} + +- (IBAction)removeQueryComposer:(id)sender +{ + NSString *criteria = [self formatedJsonWithTextField:self.removeCriteriaTextField replace:NO emptyValid:NO]; + + self.removeQueryTextField.stringValue = [NSString stringWithFormat:@"db.%@.remove(%@)", self.collection.name, criteria]; +} + +@end + +@implementation MHQueryViewController (IndexTab) + +- (IBAction)indexQueryAction:(id)sender +{ + [self.indexLoaderIndicator startAnimation:nil]; + [self.collection findIndexesWithCallback:^(NSArray *indexes, MODQuery *mongoQuery) { + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", mongoQuery.error.localizedDescription); + } else { + [self.indexDocumentOutlineViewController displayDocuments:[MODHelper convertForOutlineWithObjects:indexes bsonData:nil jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch] withLabel:nil]; + } + [self.indexLoaderIndicator stopAnimation:nil]; + }]; +} + +- (IBAction)createIndexAction:(id)sender +{ + NSAssert(self.indexEditorController == nil, @"should have no index editor"); + self.indexEditorController = [[[MHIndexEditorController alloc] init] autorelease]; + [self.indexEditorController modalForWindow:self.view.window]; + self.indexEditorController.delegate = self; +} + +- (IBAction)dropIndexAction:(id)sender +{ + NSArray *indexes; + + indexes = self.indexDocumentOutlineViewController.selectedDocuments; + if (indexes.count == 1) { + [self.indexLoaderIndicator startAnimation:nil]; + [self.collection dropIndexName:[[[indexes objectAtIndex:0] objectForKey:@"objectvalue"] objectForKey:@"name"] callback:^(MODQuery *mongoQuery) { + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", mongoQuery.error.localizedDescription); + } else { + NSArray *objectIds = @[ [[indexes objectAtIndex:0] objectForKey:@"objectvalueid"] ]; + [self.indexDocumentOutlineViewController removeDocumentsWithIds:objectIds]; + } + [self.indexLoaderIndicator stopAnimation:nil]; + }]; + } +} + +- (void)indexEditorControllerDidCancel:(MHIndexEditorController *)controller +{ + self.indexEditorController = nil; +} + +- (void)indexEditorControllerDidValidate:(MHIndexEditorController *)controller +{ + [self.indexLoaderIndicator startAnimation:nil]; + [self.collection createIndexWithKeys:controller.keys indexOptions:controller.indexOptions callback:^(MODQuery *mongoQuery) { + [self indexQueryAction:nil]; + }]; + self.indexEditorController = nil; +} + +@end + +@implementation MHQueryViewController (Aggregation) + +- (IBAction)aggregationRunAction:(id)sender +{ + NSArray *pipeline = nil; + MODSortedDictionary *options = nil; + NSError *error = nil; + + if ([self.aggregationPipeline.string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length > 0) { + pipeline = [MODRagelJsonParser objectsFromJson:self.aggregationPipeline.string withError:&error]; + if (error) { + NSBeginAlertSheet(@"Error in Pipeline", @"OK", nil, nil, self.view.window, nil, nil, nil, @"%@", @"%@", error.localizedDescription); + return; + } + if ([pipeline isKindOfClass:[MODSortedDictionary class]]) { + // just make it easier for the user if he omits [] + pipeline = @[ pipeline ]; + } + } + if ([self.aggregationOptions.string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length > 0) { + options = [MODRagelJsonParser objectsFromJson:self.aggregationOptions.string withError:&error]; + if (error) { + NSBeginAlertSheet(@"Error in Options", @"OK", nil, nil, self.view.window, nil, nil, nil, @"%@", @"%@", error.localizedDescription); + return; + } + } + [self.aggregationLoaderIndicator startAnimation:nil]; + [self.collection aggregateWithFlags:MODQueryFlagsNone pipeline:pipeline options:options readPreferences:nil callback:^(MODQuery *mongoQuery, MODCursor *cursor) { + [self.aggregationLoaderIndicator stopAnimation:nil]; + + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", mongoQuery.error.localizedDescription); + [self.aggregationDocumentOutlineViewController displayDocuments:nil withLabel:nil]; + } else { + NSMutableArray *documents = [NSMutableArray array]; + NSMutableArray *allData = [NSMutableArray array]; + + [cursor forEachDocumentWithCallbackDocumentCallback:^(uint64_t index, MODSortedDictionary *document, NSData *documentData) { + [documents addObject:document]; + [allData addObject:documentData]; + return YES; + } + endCallback:^(uint64_t documentCounts, BOOL cursorStopped, MODQuery *forEachQuery) { + NSString *label = [NSString stringWithFormat:@"%lld documents", documentCounts]; + NSArray *displayedDocuments = [MODHelper convertForOutlineWithObjects:documents bsonData:allData jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch]; + [self.aggregationDocumentOutlineViewController displayDocuments:displayedDocuments withLabel:label]; + }]; + } + }]; +} + +@end + +@implementation MHQueryViewController (mrTab) + +- (IBAction)mapReduce:(id)sender +{ + NSString *stringQuery = self.mrCriteriaTextField.stringValue; + MODSortedDictionary *query = nil; + NSString *stringOutput = self.mrOutputTextField.stringValue; + MODSortedDictionary *output = nil; + NSError *error = nil; + + if (stringQuery.length > 0) { + query = [MODRagelJsonParser objectsFromJson:stringQuery withError:&error]; + } + if (!error && stringOutput.length > 0) { + output = [MODRagelJsonParser objectsFromJson:stringOutput withError:&error]; + } + if (error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", error.localizedDescription); + } else { + [self.mrLoaderIndicator startAnimation:nil]; + [self.collection mapReduceWithMapFunction:self.mrMapFunctionTextView.string + reduceFunction:self.mrReduceFunctionTextView.string + query:query + sort:nil + limit:-1 + output:output + keepTemp:NO + finalizeFunction:nil + scope:nil + jsmode:NO + verbose:NO + readPreferences:nil + callback:^(MODQuery *mongoQuery, MODSortedDictionary *documents) { + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", mongoQuery.error.localizedDescription); + } else { + NSArray *convertedDocuments; + + convertedDocuments = [MODHelper convertForOutlineWithObjects:@[ documents ] bsonData:nil jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch]; + [self.mrDocumentOutlineViewController displayDocuments:convertedDocuments withLabel:[NSString stringWithFormat:@"%0.2fs", [[mongoQuery.userInfo objectForKey:@"timequery"] duration]]]; + } + [self.mrLoaderIndicator stopAnimation:nil]; + }]; + } +} + +@end + +@implementation MHQueryViewController(NSComboBox) + +- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox +{ + return [self.connectionStore queryHistoryWithDatabaseName:@"" collectionName:self.collection.name].count; +} + +- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index +{ + return [[[self.connectionStore queryHistoryWithDatabaseName:@"" collectionName:self.collection.name] objectAtIndex:index] objectForKey:@"title"]; +} + +- (void)comboBoxSelectionDidChange:(NSNotification *)notification +{ + NSArray *queries; + NSUInteger index; + + index = self.findCriteriaComboBox.indexOfSelectedItem; + queries = [self.connectionStore queryHistoryWithDatabaseName:@"" collectionName:self.collection.name]; + if (index < [queries count]) { + NSDictionary *query; + + query = [queries objectAtIndex:self.findCriteriaComboBox.indexOfSelectedItem]; + if ([query objectForKey:@"fields"]) { + self.findFieldFilterTextField.stringValue = [query objectForKey:@"fields"]; + } else { + self.findFieldFilterTextField.stringValue = @""; + } + if ([query objectForKey:@"sort"]) { + self.findSortTextField.stringValue = [query objectForKey:@"sort"]; + } else { + self.findSortTextField.stringValue = @""; + } + if ([query objectForKey:@"skip"]) { + self.findSkipTextField.stringValue = [query objectForKey:@"skip"]; + } else { + self.findSkipTextField.stringValue = @""; + } + if ([query objectForKey:@"limit"]) { + self.findLimitTextField.stringValue = [query objectForKey:@"limit"]; + } else { + self.findLimitTextField.stringValue = @""; + } + } +} + +- (NSUInteger)comboBox:(NSComboBox *)aComboBox indexOfItemWithStringValue:(NSString *)string +{ + NSUInteger result = NSNotFound; + NSUInteger index = 0; + + for (NSDictionary *history in [self.connectionStore queryHistoryWithDatabaseName:@"" collectionName:self.collection.name]) { + if ([[history objectForKey:@"title"] isEqualToString:string]) { + result = index; + [self comboBoxSelectionDidChange:nil]; + break; + } + index++; + } + return result; +} + +- (NSString *)comboBox:(NSComboBox *)aComboBox completedString:(NSString *)string +{ + NSString *result = nil; + + for (NSDictionary *history in [self.connectionStore queryHistoryWithDatabaseName:@"" collectionName:self.collection.name]) { + if ([[history objectForKey:@"title"] hasPrefix:string]) { + result = [history objectForKey:@"title"]; + break; + } + } + return result; +} + +@end + +@implementation MHQueryViewController (UKSyntaxColoredTextViewDelegate) + +@end + +@implementation MHQueryViewController (MHDocumentOutlineViewDelegate) + +- (void)documentOutlineViewController:(MHDocumentOutlineViewController *)controller shouldDeleteDocumentIds:(NSArray *)documentIds +{ + [self.removeQueryLoaderIndicator startAnimation:nil]; + if (documentIds.count > 0) { + MODSortedDictionary *criteria; + MODSortedDictionary *inCriteria; + + inCriteria = [MODSortedDictionary sortedDictionaryWithObjectsAndKeys:documentIds, @"$in", nil]; + criteria = [MODSortedDictionary sortedDictionaryWithObjectsAndKeys:inCriteria, @"_id", nil]; + [self.collection removeWithCriteria:criteria callback:^(MODQuery *mongoQuery) { + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.view.window, nil, nil, nil, NULL, @"%@", mongoQuery.error.localizedDescription); + } else { + [controller removeDocumentsWithIds:documentIds]; + } + [self.removeQueryLoaderIndicator stopAnimation:nil]; + }]; + } +} + +- (void)documentOutlineViewControllerBackButton:(MHDocumentOutlineViewController *)controller +{ + if (controller == self.findDocumentOutlineViewController) { + NSInteger skipValue; + + skipValue = self.findSkipTextField.stringValue.integerValue; + if (skipValue > 0) { + NSInteger limitValue; + + limitValue = self.findLimitTextField.stringValue.integerValue; + skipValue -= limitValue; + if (skipValue < 0) { + skipValue = 0; + } + self.findSkipTextField.stringValue = [NSString stringWithFormat:@"%ld", (long)skipValue]; + [self findQuery:nil]; + } + } +} + +- (void)documentOutlineViewControllerNextButton:(MHDocumentOutlineViewController *)controller +{ + if (controller == self.findDocumentOutlineViewController) { + NSInteger skipValue; + NSInteger limitValue; + + skipValue = self.findSkipTextField.stringValue.integerValue; + limitValue = self.findLimitTextField.stringValue.integerValue; + skipValue += limitValue; + self.findSkipTextField.stringValue = [NSString stringWithFormat:@"%ld", (long)skipValue]; + [self findQuery:nil]; + } +} + +- (void)documentOutlineViewController:(MHDocumentOutlineViewController *)controller doubleClickOnDocuments:(NSArray *)documents +{ + if (controller == self.findDocumentOutlineViewController) { + for (NSDictionary *document in documents) { + id idValue; + MHJsonWindowController *jsonWindowController; + + idValue = [document objectForKey:@"objectvalueid"]; + jsonWindowController = self.jsonWindowControllers[idValue]; + NSAssert(idValue != nil, @"No idValue for %@", document); + if (!jsonWindowController) { + jsonWindowController = [[MHJsonWindowController alloc] init]; + jsonWindowController.collection = self.collection; + jsonWindowController.windowControllerId = idValue; + jsonWindowController.jsonDocument = document[@"objectvalue"]; + jsonWindowController.bsonData = document[@"bsondata"]; + [jsonWindowController showWindow:nil]; + self.jsonWindowControllers[idValue] = jsonWindowController; + [jsonWindowController release]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(findQuery:) name:kJsonWindowSaved object:jsonWindowController]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jsonWindowWillClose:) name:kJsonWindowWillClose object:jsonWindowController]; + } else { + [jsonWindowController showWindow:self]; + } + } + } +} + +- (void)documentOutlineViewControllerSelectionDidChange:(MHDocumentOutlineViewController *)controller +{ + if (controller == self.indexDocumentOutlineViewController) { + self.indexDropButton.enabled = self.indexDocumentOutlineViewController.selectedDocumentCount > 0; + } +} + +@end diff --git a/Sources/ConnectionWindow/MHStatusViewController.h b/Sources/ConnectionWindow/MHStatusViewController.h new file mode 100644 index 00000000..10a8b4a3 --- /dev/null +++ b/Sources/ConnectionWindow/MHStatusViewController.h @@ -0,0 +1,33 @@ +// +// MHStatusViewController.h +// MongoHub +// +// Created by Jérôme Lebel on 02/12/2011. +// + +#import "MHTabItemViewController.h" + +@class MHDocumentOutlineViewController; +@class MODClient; +@class MHDatabaseItem; +@class MHCollectionItem; +@class MODQuery; +@class MHConnectionStore; + +@interface MHStatusViewController : MHTabItemViewController +{ + MODClient *_client; + MHConnectionStore *_connectionStore; + MHDocumentOutlineViewController *_documentOutlineViewController; +} + +@property (nonatomic, readonly, strong) MODClient *client; +@property (nonatomic, readonly, strong) MHConnectionStore *connectionStore; + +- (instancetype)initWithClient:(MODClient *)client connectionStore:(MHConnectionStore *)connectionStore; + +- (MODQuery *)showServerStatus; +- (MODQuery *)showDatabaseStatusWithDatabaseItem:(MHDatabaseItem *)databaseItem; +- (MODQuery *)showCollectionStatusWithCollectionItem:(MHCollectionItem *)collectionItem; + +@end diff --git a/Sources/ConnectionWindow/MHStatusViewController.m b/Sources/ConnectionWindow/MHStatusViewController.m new file mode 100644 index 00000000..01dca2be --- /dev/null +++ b/Sources/ConnectionWindow/MHStatusViewController.m @@ -0,0 +1,135 @@ +// +// MHStatusViewController.m +// MongoHub +// +// Created by Jérôme Lebel on 02/12/2011. +// + +#import "MHStatusViewController.h" +#import "MHDatabaseItem.h" +#import "MHCollectionItem.h" +#import +#import "MODHelper.h" +#import "MHConnectionStore.h" +#import "MHDocumentOutlineViewController.h" + +@interface MHStatusViewController () +@property (nonatomic, readwrite, strong) MODClient *client; +@property (nonatomic, readwrite, strong) MHConnectionStore *connectionStore; +@property (nonatomic, readwrite, weak) IBOutlet MHDocumentOutlineViewController *documentOutlineViewController; + +@end + +@implementation MHStatusViewController + +@synthesize client = _client; +@synthesize connectionStore = _connectionStore; +@synthesize documentOutlineViewController = _documentOutlineViewController; + +- (instancetype)initWithClient:(MODClient *)client connectionStore:(MHConnectionStore *)connectionStore +{ + self = [super init]; + if (self) { + self.client = client; + self.connectionStore = connectionStore; + } + return self; +} + +- (void)dealloc +{ + self.client = nil; + self.connectionStore = nil; + [super dealloc]; +} + +- (NSString *)nibName +{ + return @"MHStatusView"; +} + +- (void)awakeFromNib +{ + [MHDocumentOutlineViewController addDocumentOutlineViewController:self.documentOutlineViewController intoView:self.view]; +} + +- (MODQuery *)showServerStatus +{ + MODQuery *result; + + self.title = @"Server Stats"; + result = [self.client serverStatusWithReadPreferences:nil callback:^(MODSortedDictionary *serverStatus, MODQuery *mongoQuery) { + if (self.client == mongoQuery.owner) { + NSArray *documents = nil; + + if (mongoQuery.error) { + documents = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:[mongoQuery.error localizedDescription], @"value", @"error", @"name", nil]]; + } else if (serverStatus) { + documents = [MODHelper convertForOutlineWithObject:serverStatus jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch]; + } else { + documents = [NSArray array]; + } + [self.documentOutlineViewController displayDocuments:documents withLabel:nil]; + } + }]; + return result; +} + +- (MODQuery *)showDatabaseStatusWithDatabaseItem:(MHDatabaseItem *)databaseItem +{ + MODQuery *result = nil; + + if (databaseItem) { + self.title = [NSString stringWithFormat:@"%@ Stats", databaseItem.name]; + + result = [databaseItem.database statsWithReadPreferences:nil callback:^(MODSortedDictionary *databaseStats, MODQuery *mongoQuery) { + NSArray *documents = nil; + + if (databaseStats) { + documents = [MODHelper convertForOutlineWithObject:databaseStats jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch]; + } else if (mongoQuery.error) { + documents = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:[mongoQuery.error localizedDescription], @"value", @"error", @"name", nil]]; + } else { + documents = [NSArray array]; + } + [self.documentOutlineViewController displayDocuments:documents withLabel:nil]; + }]; + } + return result; +} + +- (MODQuery *)showCollectionStatusWithCollectionItem:(MHCollectionItem *)collectionItem +{ + MODQuery *result = nil; + + if (collectionItem) { + self.title = [NSString stringWithFormat:@"%@ Stats", collectionItem.collection.absoluteName]; + result = [collectionItem.collection statsWithCallback:^(MODSortedDictionary *stats, MODQuery *mongoQuery) { + NSArray *documents = nil; + + if (stats) { + documents = [MODHelper convertForOutlineWithObject:stats jsonKeySortOrder:self.connectionStore.jsonKeySortOrderInSearch]; + } else if (mongoQuery.error) { + documents = [NSArray arrayWithObject:[NSDictionary dictionaryWithObjectsAndKeys:[mongoQuery.error localizedDescription], @"value", @"error", @"name", nil]]; + } else { + documents = [NSArray array]; + } + [self.documentOutlineViewController displayDocuments:documents withLabel:nil]; + }]; + } + return result; +} + +// REMOVE when 10.9 is not supported anymore +- (BOOL)canPerformCopy +{ + return self.documentOutlineViewController.canCopyDocuments; +} + +// REMOVE when 10.9 is not supported anymore +- (void)performCopy +{ + [self.documentOutlineViewController copyDocuments]; +} + +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionCollectionView.h b/Sources/ConnectionsCollectionView/MHConnectionCollectionView.h new file mode 100644 index 00000000..234874f2 --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionCollectionView.h @@ -0,0 +1,34 @@ +// +// MHConnectionCollectionView.h +// MongoHub +// +// Created by Jérôme Lebel on 07/08/2014. +// +// + +#import + +@class MHConnectionCollectionView; +@class MHConnectionViewItem; + +@protocol MHConnectionCollectionViewDelegate +- (void)connectionViewItemDelegateNewItem:(MHConnectionCollectionView *)connectionCollectionView; +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView openItem:(MHConnectionViewItem *)connectionViewItem; +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView editItem:(MHConnectionViewItem *)connectionViewItem; +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView duplicateItem:(MHConnectionViewItem *)connectionViewItem; +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView copyURLItem:(MHConnectionViewItem *)connectionViewItem; +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView deleteItem:(MHConnectionViewItem *)connectionViewItem; + +@end + +@interface MHConnectionCollectionView : NSCollectionView +@property (nonatomic, readwrite, assign) NSSize itemSize; + +- (void)newItem; +- (void)openItem:(MHConnectionViewItem *)item; +- (void)editItem:(MHConnectionViewItem *)item; +- (void)duplicateItem:(MHConnectionViewItem *)item; +- (void)copyURLItem:(MHConnectionViewItem *)item; +- (void)deleteItem:(MHConnectionViewItem *)item; + +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionCollectionView.m b/Sources/ConnectionsCollectionView/MHConnectionCollectionView.m new file mode 100644 index 00000000..bb08a7a6 --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionCollectionView.m @@ -0,0 +1,85 @@ +// +// MHConnectionCollectionView.m +// MongoHub +// +// Created by Jérôme Lebel on 07/08/2014. +// +// + +#import "MHConnectionCollectionView.h" + +@implementation MHConnectionCollectionView + +- (void)setItemSize:(NSSize)itemSize +{ + self.maxItemSize = itemSize; + self.minItemSize = itemSize; +} + +- (NSSize)itemSize +{ + return self.maxItemSize; +} + +- (void)newItem +{ + [(id)self.delegate connectionViewItemDelegateNewItem:self]; +} + +- (void)openItem:(MHConnectionViewItem *)item +{ + [(id)self.delegate connectionViewItemDelegate:self openItem:item]; +} + +- (void)editItem:(MHConnectionViewItem *)item +{ + [(id)self.delegate connectionViewItemDelegate:self editItem:item]; +} + +- (void)duplicateItem:(MHConnectionViewItem *)item +{ + [(id)self.delegate connectionViewItemDelegate:self duplicateItem:item]; +} + +- (void)copyURLItem:(MHConnectionViewItem *)item +{ + [(id)self.delegate connectionViewItemDelegate:self copyURLItem:item]; +} + +- (void)deleteItem:(MHConnectionViewItem *)item +{ + [(id)self.delegate connectionViewItemDelegate:self deleteItem:item]; +} + +- (void)openContextualMenuWithEvent:(NSEvent *)event +{ + NSMenu *menu; + + menu = [[[NSMenu alloc] init] autorelease]; + [menu addItemWithTitle:@"New Connection…" action:@selector(newItemAction:) keyEquivalent:@""].target = self; + [NSMenu popUpContextMenu:menu withEvent:event forView:self]; +} + +- (void)mouseDown:(NSEvent *)event +{ + [super mouseDown:event]; + if ((event.modifierFlags & NSControlKeyMask) == NSControlKeyMask) { + [self openContextualMenuWithEvent:event]; + } +} + +- (void)rightMouseDown:(NSEvent *)event +{ + if (self.window.attachedSheet) { + [super rightMouseDown:event]; + } else { + [self openContextualMenuWithEvent:event]; + } +} + +- (void)newItemAction:(id)sender +{ + [(id)self.delegate connectionViewItemDelegateNewItem:self]; +} + +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionIconView.h b/Sources/ConnectionsCollectionView/MHConnectionIconView.h new file mode 100644 index 00000000..88bee623 --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionIconView.h @@ -0,0 +1,27 @@ +// +// MHConnectionIconView.h +// MongoHub +// +// Created by Jérôme Lebel on 07/08/2014. +// +// + +#import + +@class MHConnectionIconView; + +@protocol MHConnectionIconViewDelegate +@property (nonatomic, readwrite, assign, getter = isSelected) BOOL selected; + +- (void)connectionIconViewDoubleClick:(MHConnectionIconView *)connectionIconView; +- (void)connectionIconViewOpenContextualMenu:(MHConnectionIconView *)connectionIconView withEvent:(NSEvent *)event; + +@end + +@interface MHConnectionIconView : NSView +{ + id _delegate; +} +@property (nonatomic, readwrite, weak) IBOutlet id delegate; + +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionIconView.m b/Sources/ConnectionsCollectionView/MHConnectionIconView.m new file mode 100644 index 00000000..95c0618a --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionIconView.m @@ -0,0 +1,118 @@ +// +// MHConnectionIconView.m +// MongoHub +// +// Created by Jérôme Lebel on 07/08/2014. +// +// + +#import "MHConnectionIconView.h" + +@interface MHConnectionIconView () +@property (nonatomic, readonly, weak) NSTextField *connectionLabel; +@property (nonatomic, readonly, weak) NSImageView *connectionIcon; + +@end + +@implementation MHConnectionIconView + +@synthesize delegate = _delegate; + +- (void)drawRect:(NSRect)dirtyRect +{ + [super drawRect:dirtyRect]; + + if (self.delegate.isSelected) { + NSRect rect = self.bounds; + CGFloat x[3], y[3], radius; + NSBezierPath *bezierPath; + + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.4] set]; + bezierPath = NSBezierPath.bezierPath; + radius = rect.size.height / 10.0; + + x[0] = NSMinX(rect); + x[1] = NSMidX(rect); + x[2] = NSMaxX(rect); + y[0] = NSMinY(rect); + y[1] = NSMidY(rect); + y[2] = NSMaxY(rect); + + [bezierPath moveToPoint:NSMakePoint(x[0], y[1])]; + [bezierPath appendBezierPathWithArcFromPoint:NSMakePoint(x[0], y[2]) toPoint:NSMakePoint(x[1], y[2]) radius:radius]; + [bezierPath appendBezierPathWithArcFromPoint:NSMakePoint(x[2], y[2]) toPoint:NSMakePoint(x[2], y[1]) radius:radius]; + [bezierPath appendBezierPathWithArcFromPoint:NSMakePoint(x[2], y[0]) toPoint:NSMakePoint(x[1], y[0]) radius:radius]; + [bezierPath appendBezierPathWithArcFromPoint:NSMakePoint(x[0], y[0]) toPoint:NSMakePoint(x[0], y[1]) radius:radius]; + [bezierPath closePath]; + [bezierPath fill]; + } +} + +- (NSTextField *)connectionLabel +{ + return [self viewWithTag:1]; +} + +- (NSImageView *)connectionIcon +{ + return [self viewWithTag:2]; +} + +- (void)setFrameSize:(NSSize)newSize +{ + NSFont *font = nil; + NSRect frame; + NSRect selfBounds = self.bounds; + NSTextField *connectionLabel = self.connectionLabel; + NSImageView *connectionIcon = self.connectionIcon; + + [super setFrameSize:newSize]; + if (newSize.width < 90) { + font = [NSFont systemFontOfSize:8.0]; + } else if (newSize.width < 100) { + font = [NSFont systemFontOfSize:9.0]; + } else if (newSize.width < 110) { + font = [NSFont systemFontOfSize:10.0]; + } else if (newSize.width < 130) { + font = [NSFont systemFontOfSize:11.0]; + } else if (newSize.width < 150) { + font = [NSFont systemFontOfSize:12.0]; + } else { + font = [NSFont systemFontOfSize:13.0]; + } + connectionLabel.font = font; + + [connectionLabel sizeToFit]; + frame = connectionLabel.frame; + frame.origin.x = selfBounds.size.height / 10.0; + frame.size.width = selfBounds.size.width - frame.origin.x * 2; + frame.origin.y = selfBounds.size.height / 10.0; + connectionLabel.frame = frame; + + frame = NSMakeRect(0, frame.origin.y + frame.size.height, selfBounds.size.width, selfBounds.size.height - frame.origin.y - frame.size.height - selfBounds.size.height / 10.0); + connectionIcon.frame = frame; +} + +- (void)mouseDown:(NSEvent *)event +{ + if (event.modifierFlags & NSControlKeyMask) { + self.delegate.selected = YES; + [self.delegate connectionIconViewOpenContextualMenu:self withEvent:event]; + } else if (event.clickCount == 2) { + [self.delegate connectionIconViewDoubleClick:self]; + } else { + [super mouseDown:event]; + } +} + +- (void)rightMouseDown:(NSEvent *)event +{ + if (self.window.attachedSheet) { + [super rightMouseDown:event]; + } else { + self.delegate.selected = YES; + [self.delegate connectionIconViewOpenContextualMenu:self withEvent:event]; + } +} + +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionListWindowController.h b/Sources/ConnectionsCollectionView/MHConnectionListWindowController.h new file mode 100644 index 00000000..ca42eab9 --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionListWindowController.h @@ -0,0 +1,21 @@ +// +// MHConnectionListWindowController.h +// MongoHub +// +// Created by Jérôme Lebel on 09/04/2015. +// +// + +#import +#import "MHConnectionCollectionView.h" +#import "MHConnectionEditorWindowController.h" + +@interface MHConnectionListWindowController : NSWindowController + +@end + +@interface MHConnectionListWindowController (MHConnectionViewItemDelegate) +@end + +@interface MHConnectionListWindowController (MHConnectionEditorWindowControllerDelegate) +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionListWindowController.m b/Sources/ConnectionsCollectionView/MHConnectionListWindowController.m new file mode 100644 index 00000000..7c446b54 --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionListWindowController.m @@ -0,0 +1,301 @@ +// +// MHConnectionListWindowController.m +// MongoHub +// +// Created by Jérôme Lebel on 09/04/2015. +// +// + +#import "MHConnectionListWindowController.h" + +#import "ConnectionsArrayController.h" +#import "MHConnectionStore.h" +#import "MHEditNameWindowController.h" +#import "MHApplicationDelegate.h" +#import "MHConnectionViewItem.h" + +@interface MHConnectionListWindowController () +@property (nonatomic, readwrite, strong) MHConnectionEditorWindowController *connectionEditorWindowController; + +@property (nonatomic, readwrite, strong) IBOutlet MHConnectionCollectionView *connectionCollectionView; + +@end + +@interface MHConnectionListWindowController (Action) + +@end + +@implementation MHConnectionListWindowController + +- (void)windowDidLoad { + [super windowDidLoad]; +} + +- (void)editConnection:(MHConnectionStore *)connection +{ + self.connectionEditorWindowController = [[[MHConnectionEditorWindowController alloc] init] autorelease]; + self.connectionEditorWindowController.delegate = self; + self.connectionEditorWindowController.editedConnectionStore = connection; + [self.connectionEditorWindowController modalForWindow:self.window]; +} + +- (void)duplicateConnection:(MHConnectionStore *)connection +{ + if (!self.connectionEditorWindowController) { + self.connectionEditorWindowController = [[[MHConnectionEditorWindowController alloc] init] autorelease]; + self.connectionEditorWindowController.delegate = self; + self.connectionEditorWindowController.connectionStoreDefaultValue = connection; + [self.connectionEditorWindowController modalForWindow:self.window]; + } +} + +- (void)openConnection:(MHConnectionStore *)connection +{ + [(MHApplicationDelegate *)[NSApp delegate] openConnection:connection]; +} + +- (void)deleteConnection:(MHConnectionStore *)connection +{ + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + [alert addButtonWithTitle:@"Cancel"]; + [alert addButtonWithTitle:@"Delete"]; + [alert setMessageText:[NSString stringWithFormat:@"Delete \"%@\"?", connection.alias]]; + [alert setInformativeText:@"Deleted connections cannot be restored."]; + [alert setAlertStyle:NSWarningAlertStyle]; + + [alert beginSheetModalForWindow:self.window modalDelegate:self didEndSelector:@selector(deleteConnectionAlertDidEnd:returnCode:contextInfo:) contextInfo:connection]; +} + +@end + +@implementation MHConnectionListWindowController (Action) + +- (BOOL)validateUserInterfaceItem:(id )anItem +{ + if (anItem.action == @selector(copy:)) { + return self.window.isKeyWindow && self.connectionsArrayController.selectedObjects.count == 1; + } else if (anItem.action == @selector(paste:)) { + return self.window.isKeyWindow && [[[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString] hasPrefix:@"mongodb://"]; + } else if (anItem.action == @selector(editConnectionAction:)) { + return self.window.isKeyWindow && self.connectionsArrayController.selectedObjects.count > 0; + } else if (anItem.action == @selector(duplicateConnectionAction:)) { + return self.window.isKeyWindow && self.connectionsArrayController.selectedObjects.count > 0; + } else if (anItem.action == @selector(deleteConnectionAction:)) { + return self.window.isKeyWindow && self.connectionsArrayController.selectedObjects.count > 0; + } else if (anItem.action == @selector(openConnectionAction:)) { + return self.window.isKeyWindow && self.connectionsArrayController.selectedObjects.count > 0; + } else { + return [self respondsToSelector:anItem.action]; + } +} + +- (IBAction)copy:(id)sender +{ + if (self.connectionsArrayController.selectedObjects.count == 1 && !self.connectionEditorWindowController) { + [self copyURLConnection:self.connectionsArrayController.selectedObjects[0]]; + } +} + +- (IBAction)paste:(id)sender +{ + NSString *stringURL; + + stringURL = [[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]; + if (![stringURL hasPrefix:@"mongodb://"]) { + [[NSAlert alertWithMessageText:@"No URL found" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@""] runModal]; + } else { + NSEntityDescription *entity; + MHConnectionStore *connectionStore; + NSString *errorMessage; + + entity = [NSEntityDescription entityForName:@"Connection" inManagedObjectContext:self.managedObjectContext]; + connectionStore = [[[MHConnectionStore alloc] initWithEntity:entity insertIntoManagedObjectContext:nil] autorelease]; + if (![connectionStore setValuesFromStringURL:stringURL errorMessage:&errorMessage]) { + [[NSAlert alertWithMessageText:errorMessage defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", stringURL] runModal]; + return; + } + self.connectionEditorWindowController = [[[MHConnectionEditorWindowController alloc] init] autorelease]; + self.connectionEditorWindowController.delegate = self; + self.connectionEditorWindowController.connectionStoreDefaultValue = connectionStore; + [self.connectionEditorWindowController modalForWindow:self.window]; + } +} + +- (IBAction)addNewConnectionAction:(id)sender +{ + if (!self.connectionEditorWindowController) { + self.connectionEditorWindowController = [[[MHConnectionEditorWindowController alloc] init] autorelease]; + self.connectionEditorWindowController.delegate = self; + [self.connectionEditorWindowController modalForWindow:self.window]; + } +} + +- (IBAction)addNewConnectionWithURLAction:(id)sender +{ + if (!self.connectionEditorWindowController) { + MHEditNameWindowController *editNameWindowController = nil; + + editNameWindowController = [[MHEditNameWindowController alloc] initWithLabel:@"New Connection With URL:" editedValue:nil placeHolder:@"MongoDB URL"]; + editNameWindowController.callback = ^(MHEditNameWindowController *controller) { + MHConnectionStore *connectionStore; + NSEntityDescription *entity; + NSString *errorMessage = nil; + NSString *stringURL = controller.editedValue; + + entity = [NSEntityDescription entityForName:@"Connection" inManagedObjectContext:self.managedObjectContext]; + connectionStore = [[[MHConnectionStore alloc] initWithEntity:entity insertIntoManagedObjectContext:nil] autorelease]; + if (![connectionStore setValuesFromStringURL:stringURL errorMessage:&errorMessage]) { + [[NSAlert alertWithMessageText:errorMessage defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", stringURL] runModal]; + return; + } + + self.connectionEditorWindowController = [[[MHConnectionEditorWindowController alloc] init] autorelease]; + self.connectionEditorWindowController.delegate = self; + self.connectionEditorWindowController.connectionStoreDefaultValue = connectionStore; + self.connectionEditorWindowController.window.title = stringURL; + [self.connectionEditorWindowController modalForWindow:self.window]; + [controller release]; + }; + editNameWindowController.validateValueCallback = ^(MHEditNameWindowController *controller) { + MHConnectionStore *connectionStore; + NSString *stringURL = controller.editedValue; + NSString *errorMessage = nil; + NSEntityDescription *entity; + + entity = [NSEntityDescription entityForName:@"Connection" inManagedObjectContext:self.managedObjectContext]; + connectionStore = [[[MHConnectionStore alloc] initWithEntity:entity insertIntoManagedObjectContext:nil] autorelease]; + if ([connectionStore setValuesFromStringURL:stringURL errorMessage:&errorMessage]) { + return YES; + } else { + [[NSAlert alertWithMessageText:errorMessage defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", stringURL] runModal]; + return NO; + } + }; + [editNameWindowController modalForWindow:self.window]; + } +} + +- (void)deleteConnectionAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + if (returnCode == NSAlertSecondButtonReturn) { + [(MHApplicationDelegate *)[NSApp delegate] deleteConnection:contextInfo]; + } +} + +- (IBAction)openConnectionAction:(id)sender +{ + if (!self.connectionsArrayController.selectedObjects) { + return; + } + [self openConnection:[self.connectionsArrayController.selectedObjects objectAtIndex:0]]; +} + +- (IBAction)editConnectionAction:(id)sender +{ + if (self.connectionsArrayController.selectedObjects.count == 1 && !self.connectionEditorWindowController) { + [self editConnection:[self.connectionsArrayController.selectedObjects objectAtIndex:0]]; + } +} + +- (IBAction)duplicateConnectionAction:(id)sender +{ + if (self.connectionsArrayController.selectedObjects.count == 1 && !self.connectionEditorWindowController) { + [self duplicateConnection:[self.connectionsArrayController.selectedObjects objectAtIndex:0]]; + } +} + +- (IBAction)deleteConnectionAction:(id)sender +{ + if (self.connectionsArrayController.selectedObjects.count == 1) { + [self deleteConnection:[self.connectionsArrayController.selectedObjects objectAtIndex:0]]; + } +} + +- (IBAction)resizeConnectionItemView:(id)sender +{ + CGFloat value = [sender floatValue]/100.0f*360.0f; + + self.connectionCollectionView.itemSize = NSMakeSize(value, value * 0.8); +} + +- (void)copyURLConnection:(MHConnectionStore *)connection +{ + NSPasteboard *pasteboard = NSPasteboard.generalPasteboard; + NSString *stringURL = [connection stringURLWithSSHMapping:nil]; + + [pasteboard declareTypes:@[ NSStringPboardType, NSURLPboardType ] owner:nil]; + [pasteboard setString:stringURL forType:NSStringPboardType]; + [pasteboard setString:stringURL forType:NSURLPboardType]; +} + +@end + +@implementation MHConnectionListWindowController (MHConnectionEditorWindowControllerDelegate) + +- (NSManagedObjectContext *)managedObjectContext +{ + return [(MHApplicationDelegate *)[NSApp delegate] managedObjectContext]; +} + +- (ConnectionsArrayController *)connectionsArrayController +{ + return [(MHApplicationDelegate *)[NSApp delegate] connectionsArrayController]; +} + +- (void)connectionWindowControllerDidCancel:(MHConnectionEditorWindowController *)controller +{ + if (self.connectionEditorWindowController == controller) { + self.connectionEditorWindowController = nil; + } +} + +- (void)connectionWindowControllerDidValidate:(MHConnectionEditorWindowController *)controller +{ + [(MHApplicationDelegate *)[NSApp delegate] saveConnections]; + self.connectionCollectionView.needsDisplay = YES; + if (self.connectionEditorWindowController == controller) { + self.connectionEditorWindowController = nil; + } +} + +- (MHConnectionStore *)connectionWindowController:(MHConnectionEditorWindowController *)controller connectionStoreWithAlias:(NSString *)alias +{ + return [(MHApplicationDelegate *)[NSApp delegate] connectionStoreWithAlias:alias]; +} + +@end + + +@implementation MHConnectionListWindowController (MHConnectionViewItemDelegate) + +- (void)connectionViewItemDelegateNewItem:(MHConnectionCollectionView *)connectionCollectionView +{ + [self addNewConnectionAction:nil]; +} + +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView openItem:(MHConnectionViewItem *)connectionViewItem +{ + [self openConnection:connectionViewItem.representedObject]; +} + +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView editItem:(MHConnectionViewItem *)connectionViewItem +{ + [self editConnection:connectionViewItem.representedObject]; +} + +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView duplicateItem:(MHConnectionViewItem *)connectionViewItem +{ + [self duplicateConnection:connectionViewItem.representedObject]; +} + +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView copyURLItem:(MHConnectionViewItem *)connectionViewItem +{ + [self copyURLConnection:connectionViewItem.representedObject]; +} + +- (void)connectionViewItemDelegate:(MHConnectionCollectionView *)connectionCollectionView deleteItem:(MHConnectionViewItem *)connectionViewItem +{ + [self deleteConnection:connectionViewItem.representedObject]; +} + +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionViewItem.h b/Sources/ConnectionsCollectionView/MHConnectionViewItem.h new file mode 100644 index 00000000..4af95f03 --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionViewItem.h @@ -0,0 +1,18 @@ +// +// MHConnectionViewItem.h +// MongoHub +// +// Created by Jérôme Lebel on 07/08/2014. +// +// + +#import +#import "MHConnectionIconView.h" + +@interface MHConnectionViewItem : NSCollectionViewItem +{ +} +@end + +@interface MHConnectionViewItem (MHConnectionIconViewDelegate) +@end diff --git a/Sources/ConnectionsCollectionView/MHConnectionViewItem.m b/Sources/ConnectionsCollectionView/MHConnectionViewItem.m new file mode 100644 index 00000000..b8278cdb --- /dev/null +++ b/Sources/ConnectionsCollectionView/MHConnectionViewItem.m @@ -0,0 +1,81 @@ +// +// MHConnectionViewItem.m +// MongoHub +// +// Created by Jérôme Lebel on 07/08/2014. +// +// + +#import "MHConnectionViewItem.h" +#import "MHConnectionCollectionView.h" + +@interface MHConnectionViewItem () + +@end + +@implementation MHConnectionViewItem + +-(void)setSelected:(BOOL)flag +{ + [super setSelected:flag]; + + MHConnectionIconView* connectionIconView = (MHConnectionIconView* )self.view; + connectionIconView.needsDisplay = YES; +} + +- (void)menuNewAction:(id)sender +{ + [(MHConnectionCollectionView *)self.collectionView newItem]; +} + +- (void)menuOpenAction:(id)sender +{ + [(MHConnectionCollectionView *)self.collectionView openItem:self]; +} + +- (void)menuEditAction:(id)sender +{ + [(MHConnectionCollectionView *)self.collectionView editItem:self]; +} + +- (void)menuDuplicateAction:(id)sender +{ + [(MHConnectionCollectionView *)self.collectionView duplicateItem:self]; +} + +- (void)menuCopyURLAction:(id)sender +{ + [(MHConnectionCollectionView *)self.collectionView copyURLItem:self]; +} + +- (void)menuDeleteAction:(id)sender +{ + [(MHConnectionCollectionView *)self.collectionView deleteItem:self]; +} + +@end + +@implementation MHConnectionViewItem (MHConnectionIconViewDelegate) + +- (void)connectionIconViewDoubleClick:(MHConnectionIconView *)connectionIconView +{ + [self menuOpenAction:nil]; +} + +- (void)connectionIconViewOpenContextualMenu:(MHConnectionIconView *)connectionIconView withEvent:(NSEvent *)event +{ + NSMenu *menu; + + menu = [[[NSMenu alloc] init] autorelease]; + [menu addItemWithTitle:@"Open Connection" action:@selector(menuOpenAction:) keyEquivalent:@""].target = self; + [menu addItemWithTitle:@"Edit Connection…" action:@selector(menuEditAction:) keyEquivalent:@""].target = self; + [menu addItemWithTitle:@"Duplicate Connection…" action:@selector(menuDuplicateAction:) keyEquivalent:@""].target = self; + [menu addItemWithTitle:@"Copy URL" action:@selector(menuCopyURLAction:) keyEquivalent:@""].target = self; + [menu addItem:[NSMenuItem separatorItem]]; + [menu addItemWithTitle:@"Delete Connection…" action:@selector(menuDeleteAction:) keyEquivalent:@""].target = self; + [menu addItem:[NSMenuItem separatorItem]]; + [menu addItemWithTitle:@"New Connection…" action:@selector(menuNewAction:) keyEquivalent:@""].target = self; + [NSMenu popUpContextMenu:menu withEvent:event forView:connectionIconView]; +} + +@end diff --git a/Sources/DatabaseCollectionOutlineView/MHClientItem.h b/Sources/DatabaseCollectionOutlineView/MHClientItem.h new file mode 100644 index 00000000..922c925f --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/MHClientItem.h @@ -0,0 +1,33 @@ +// +// MHClientItem.h +// MongoHub +// +// Created by Jérôme Lebel on 24/10/2011. +// + +#import + +@class MODClient; +@class MHDatabaseItem; +@class MHCollectionItem; +@class MODDatabase; +@class MODCollection; + +@interface MHClientItem : NSObject +{ + MODClient *_client; + NSMutableArray *_databaseItems; + // database created but empty (so not yet in the server) + NSMutableArray *_extraDatabaseNames; +} + +@property (nonatomic, readonly, strong) MODClient *client; +@property (nonatomic, readonly, strong) NSArray *databaseItems; + +- (instancetype)initWithClient:(MODClient *)client; +- (MHDatabaseItem *)databaseItemWithName:(NSString *)databaseName; +- (BOOL)updateChildrenWithList:(NSArray *)list; +- (void)addExtraDatabaseName:(NSString *)databaseName; +- (void)removeExtraDatabaseName:(NSString *)databaseName; + +@end diff --git a/Sources/DatabaseCollectionOutlineView/MHClientItem.m b/Sources/DatabaseCollectionOutlineView/MHClientItem.m new file mode 100644 index 00000000..db8137db --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/MHClientItem.m @@ -0,0 +1,135 @@ +// +// MHClientItem.m +// MongoHub +// +// Created by Jérôme Lebel on 24/10/2011. +// + +#import "MHClientItem.h" +#import "MHDatabaseItem.h" +#import + +@interface MHClientItem () + +@property (nonatomic, readwrite, strong) MODClient *client; +@property (nonatomic, readwrite, strong) NSMutableArray *databaseItems; +@property (nonatomic, readwrite, strong) NSMutableArray *extraDatabaseNames; + +@end + +@implementation MHClientItem + +@synthesize client = _client, databaseItems = _databaseItems; + +- (instancetype)initWithClient:(MODClient *)client +{ + NSParameterAssert(client); + if (self = [self init]) { + self.client = client; + self.databaseItems = [NSMutableArray array]; + self.extraDatabaseNames = [NSMutableArray array]; + } + return self; +} + +- (void)dealloc +{ + self.client = nil; + self.databaseItems = nil; + self.extraDatabaseNames = nil; + [super dealloc]; +} + +- (MHDatabaseItem *)databaseItemWithName:(NSString *)databaseName +{ + MHDatabaseItem *result = nil; + + for (MHDatabaseItem *databaseItem in self.databaseItems) { + if ([[databaseItem name] isEqualToString:databaseName]) { + result = databaseItem; + break; + } + } + return result; +} + +- (void)_removeDatabaseItemWithName:(NSString *)databaseName +{ + NSInteger ii = 0; + + for (MHDatabaseItem *databaseItem in self.databaseItems) { + if ([[databaseItem name] isEqualToString:databaseName]) { + [(NSMutableArray *)self.databaseItems removeObjectAtIndex:ii]; + break; + } + ii++; + } + [self.extraDatabaseNames removeObject:databaseName]; +} + +static NSInteger databaseItemSortFunction(id element1, id element2, void *context) +{ + return [[element1 name] compare:[element2 name] options:0]; +} + +- (MHDatabaseItem *)_addNewDatabaseWithName:(NSString *)databaseName +{ + MHDatabaseItem *databaseItem; + + databaseItem = [[MHDatabaseItem alloc] initWithClientItem:self database:[self.client databaseForName:databaseName]]; + [(NSMutableArray *)self.databaseItems addObject:databaseItem]; + [databaseItem release]; + return databaseItem; +} + +- (BOOL)updateChildrenWithList:(NSArray *)list +{ + NSArray *oldDatabases; + BOOL databaseListUpdated = NO; + + oldDatabases = [self.databaseItems copy]; + for (NSString *databaseName in list) { + MHDatabaseItem *databaseItem; + + databaseItem = [self databaseItemWithName:databaseName]; + if (databaseItem != nil) { + databaseItem.temporary = NO; + } else { + [self _addNewDatabaseWithName:databaseName]; + databaseListUpdated = YES; + } + [self.extraDatabaseNames removeObject:databaseName]; + } + for (NSString *databaseName in self.extraDatabaseNames) { + if ([self databaseItemWithName:databaseName] == nil) { + MHDatabaseItem *databaseItem; + + databaseItem = [self _addNewDatabaseWithName:databaseName]; + databaseItem.temporary = YES; + databaseListUpdated = YES; + } + } + for (MHDatabaseItem *databaseItem in oldDatabases) { + if ([list indexOfObject:databaseItem.name] == NSNotFound && [self.extraDatabaseNames indexOfObject:databaseItem.name] == NSNotFound) { + [self _removeDatabaseItemWithName:databaseItem.name]; + databaseListUpdated = YES; + } + } + [(NSMutableArray *)self.databaseItems sortUsingFunction:databaseItemSortFunction context:NULL]; + [oldDatabases release]; + return databaseListUpdated; +} + +- (void)addExtraDatabaseName:(NSString *)databaseName +{ + if (![self.extraDatabaseNames containsObject:databaseName]) { + [self.extraDatabaseNames addObject:databaseName]; + } +} + +- (void)removeExtraDatabaseName:(NSString *)databaseName +{ + [self.extraDatabaseNames removeObject:databaseName]; +} + +@end diff --git a/Sources/DatabaseCollectionOutlineView/MHCollectionItem.h b/Sources/DatabaseCollectionOutlineView/MHCollectionItem.h new file mode 100644 index 00000000..ebcc9751 --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/MHCollectionItem.h @@ -0,0 +1,25 @@ +// +// MHCollectionItem.h +// MongoHub +// +// Created by Jérôme Lebel on 24/10/2011. +// + +#import + +@class MHDatabaseItem; +@class MODCollection; + +@interface MHCollectionItem : NSObject +{ + MODCollection *_collection; + MHDatabaseItem *_databaseItem; +} + +@property (nonatomic, readonly, retain) NSString *name; +@property (nonatomic, readonly, assign) MHDatabaseItem *databaseItem; +@property (nonatomic, readonly, strong) MODCollection *collection; + +- (instancetype)initWithDatabaseItem:(MHDatabaseItem *)databaseItem collection:(MODCollection *)collection; + +@end diff --git a/Sources/DatabaseCollectionOutlineView/MHCollectionItem.m b/Sources/DatabaseCollectionOutlineView/MHCollectionItem.m new file mode 100644 index 00000000..ec7ae23f --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/MHCollectionItem.m @@ -0,0 +1,47 @@ +// +// MHCollectionItem.m +// MongoHub +// +// Created by Jérôme Lebel on 24/10/2011. +// + +#import "MHCollectionItem.h" +#import "MHDatabaseItem.h" +#import "MHClientItem.h" +#import + +@interface MHCollectionItem () +@property (nonatomic, readwrite, strong) MODCollection *collection; +@property (nonatomic, readwrite, assign) MHDatabaseItem *databaseItem; + +@end + +@implementation MHCollectionItem + +@synthesize collection = _collection; +@synthesize databaseItem = _databaseItem; + +- (instancetype)initWithDatabaseItem:(MHDatabaseItem *)databaseItem collection:(MODCollection *)collection +{ + NSParameterAssert(databaseItem); + NSParameterAssert(collection); + if (self = [self init]) { + self.collection = collection; + self.databaseItem = databaseItem; + } + return self; +} + +- (void)dealloc +{ + self.collection = nil; + self.databaseItem = nil; + [super dealloc]; +} + +- (NSString *)name +{ + return self.collection.name; +} + +@end diff --git a/Sources/DatabaseCollectionOutlineView/MHDatabaseItem.h b/Sources/DatabaseCollectionOutlineView/MHDatabaseItem.h new file mode 100644 index 00000000..4f28e9a2 --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/MHDatabaseItem.h @@ -0,0 +1,35 @@ +// +// MHDatabaseItem.h +// MongoHub +// +// Created by Jérôme Lebel on 24/10/2011. +// + +#import + +@class MHClientItem; +@class MHCollectionItem; +@class MODDatabase; + +@interface MHDatabaseItem : NSObject +{ + MHClientItem *_clientItem; + MODDatabase *_database; + NSMutableDictionary *_collectionItems; + NSMutableArray *_sortedCollectionNames; +} + +@property (nonatomic, readonly, strong) NSString *name; +@property (nonatomic, readonly, weak) MHClientItem *clientItem; +@property (nonatomic, readonly, strong) MODDatabase *database; +@property (nonatomic, readonly, strong) NSArray *sortedCollectionNames; +@property (nonatomic, readonly, strong) NSDictionary *collectionItems; +// mongodb doesn't really create a database, so this will be YES until mongodb knows about it +@property (nonatomic, readwrite, assign) BOOL temporary; + +- (instancetype)initWithClientItem:(MHClientItem *)serverItem database:(MODDatabase *)database; +- (BOOL)updateChildrenWithList:(NSArray *)list; +- (MHCollectionItem *)collectionItemWithName:(NSString *)databaseName; +- (void)removeCollectionItemWithName:(NSString *)name; + +@end diff --git a/Sources/DatabaseCollectionOutlineView/MHDatabaseItem.m b/Sources/DatabaseCollectionOutlineView/MHDatabaseItem.m new file mode 100644 index 00000000..056f15f5 --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/MHDatabaseItem.m @@ -0,0 +1,97 @@ +// +// MHDatabaseItem.m +// MongoHub +// +// Created by Jérôme Lebel on 24/10/2011. +// + +#import "MHDatabaseItem.h" +#import "MHClientItem.h" +#import "MHCollectionItem.h" +#import + +@interface MHDatabaseItem () +@property (nonatomic, readwrite, weak) MHClientItem *clientItem; +@property (nonatomic, readwrite, strong) MODDatabase *database; +@property (nonatomic, readwrite, strong) NSMutableArray *sortedCollectionNames; +@property (nonatomic, readwrite, strong) NSMutableDictionary *collectionItems; + +@end + +@implementation MHDatabaseItem + +@synthesize clientItem = _clientItem; +@synthesize database = _database; +@synthesize collectionItems = _collectionItems; +@synthesize sortedCollectionNames = _sortedCollectionNames; + +- (instancetype)initWithClientItem:(MHClientItem *)clientItem database:(MODDatabase *)database +{ + NSParameterAssert(clientItem); + NSParameterAssert(database); + if (self = [self init]) { + self.clientItem = clientItem; + self.database = database; + self.collectionItems = [NSMutableDictionary dictionary]; + self.sortedCollectionNames = [NSMutableArray array]; + } + return self; +} + +- (void)dealloc +{ + self.database = nil; + self.clientItem = nil; + self.sortedCollectionNames = nil; + self.collectionItems = nil; + [super dealloc]; +} + +- (NSString *)name +{ + return self.database.name; +} + +- (void)removeCollectionItemWithName:(NSString *)name +{ + [(NSMutableDictionary *)self.collectionItems removeObjectForKey:name]; + [(NSMutableArray *)self.sortedCollectionNames removeObjectIdenticalTo:name]; +} + +- (MHCollectionItem *)collectionItemWithName:(NSString *)name +{ + return self.collectionItems[name]; +} + +- (BOOL)updateChildrenWithList:(NSArray *)list +{ + BOOL result = NO; + NSArray *oldCollectionList; + + oldCollectionList = [_collectionItems copy]; + if (!self.database.dropped) { + for (NSString *collectionName in list) { + MHCollectionItem *collectionItem; + + collectionItem = [self collectionItemWithName:collectionName]; + if (!collectionItem) { + collectionItem = [[MHCollectionItem alloc] initWithDatabaseItem:self collection:[self.database collectionForName:collectionName]]; + [(NSMutableDictionary *)self.collectionItems setObject:collectionItem forKey:collectionName]; + [(NSMutableArray *)self.sortedCollectionNames addObject:collectionName]; + [collectionItem release]; + result = YES; + } + } + } + for (NSString *oldCollectionName in oldCollectionList) { + if ([list indexOfObject:oldCollectionName] == NSNotFound) { + [self removeCollectionItemWithName:oldCollectionName]; + result = YES; + } + } + [(NSMutableArray *)self.sortedCollectionNames sortUsingSelector:@selector(compare:)]; + [oldCollectionList release]; + return result; +} + +@end diff --git a/Sidebar/SidebarBadgeCell.h b/Sources/DatabaseCollectionOutlineView/SidebarBadgeCell.h similarity index 73% rename from Sidebar/SidebarBadgeCell.h rename to Sources/DatabaseCollectionOutlineView/SidebarBadgeCell.h index 8d58d0b0..f49ba659 100644 --- a/Sidebar/SidebarBadgeCell.h +++ b/Sources/DatabaseCollectionOutlineView/SidebarBadgeCell.h @@ -8,11 +8,11 @@ #import -@interface SidebarBadgeCell : NSTextFieldCell { - @private - NSUInteger _badgeCount; - NSImage *_icon; - BOOL _hasBadge; +@interface SidebarBadgeCell : NSTextFieldCell +{ + NSUInteger _badgeCount; + NSImage *_icon; + BOOL _hasBadge; } @property (readwrite) NSUInteger badgeCount; diff --git a/Sources/DatabaseCollectionOutlineView/SidebarBadgeCell.m b/Sources/DatabaseCollectionOutlineView/SidebarBadgeCell.m new file mode 100644 index 00000000..38d5c7ab --- /dev/null +++ b/Sources/DatabaseCollectionOutlineView/SidebarBadgeCell.m @@ -0,0 +1,154 @@ +// +// TSBadgeCell.m +// Tahsis +// +// Created by Matteo Bertozzi on 11/29/08. +// Copyright 2008 Matteo Bertozzi. All rights reserved. +// + +#import "SidebarBadgeCell.h" + +@interface SidebarBadgeCell (Private) +- (CGFloat)drawBadge:(NSRect)cellFrame; +@end + +@implementation SidebarBadgeCell + +#define TSBADGECELL_BUFFER_LEFT_SMALL 2 +#define TSBADGECELL_BUFFER_LEFT 4 +#define TSBADGECELL_BUFFER_SIDE 3 +#define TSBADGECELL_BUFFER_TOP 3 +#define TSBADGECELL_PADDING 6 + +#define TSBADGECELL_CIRCLE_BUFFER_RIGHT 5 + +#define TSBADGECELL_RADIUS_X 7 +#define TSBADGECELL_RADIUS_Y 8 + +#define TSBADGECELL_TEXT_HEIGHT 14 +#define TSBADGECELL_TEXT_MINI 8 +#define TSBADGECELL_TEXT_SMALL 20 + +#define TSBADGECELL_ICON_SIZE 16 +#define TSBADGECELL_ICON_HEIGHT_OFFSET 2 + +@synthesize badgeCount = _badgeCount; +@synthesize hasBadge = _hasBadge; +@synthesize icon = _icon; + +- (id)copyWithZone:(NSZone*)zone +{ + SidebarBadgeCell *cell = [super copyWithZone:zone]; + cell->_icon = [_icon retain]; + return cell; +} + +- (void)dealloc +{ + [_icon release]; + [super dealloc]; +} + +- (void)awakeFromNib +{ + _badgeCount = 0; + _hasBadge = NO; + _icon = nil; +} + +- (void)setIcon:(NSImage *)icon +{ + if (_icon != icon) { + [_icon release]; + _icon = [icon retain]; +// [_icon setFlipped:YES]; + [_icon setSize:NSMakeSize(TSBADGECELL_ICON_SIZE, TSBADGECELL_ICON_SIZE)]; + } +} + +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView +{ + bool drawBadge = (_hasBadge && cellFrame.size.width > TSBADGECELL_TEXT_SMALL * 3); + CGFloat badgeWidth = (drawBadge ? [self drawBadge:cellFrame] : 0); + + if (_icon != nil) { + // Draw Icon + NSRect iconRect = cellFrame; + iconRect.origin.y += (cellFrame.size.height - TSBADGECELL_ICON_SIZE) / 2.0; + iconRect.size.height = TSBADGECELL_ICON_SIZE; + iconRect.size.width = TSBADGECELL_ICON_SIZE; + [_icon drawInRect:iconRect fromRect:NSZeroRect + operation:NSCompositeSourceOver fraction:1.0]; + + // Draw Rect + NSRect labelRect = cellFrame; + labelRect.origin.x += TSBADGECELL_ICON_SIZE + TSBADGECELL_BUFFER_LEFT; + labelRect.size.width -= (badgeWidth + TSBADGECELL_ICON_SIZE + TSBADGECELL_BUFFER_LEFT); + [super drawInteriorWithFrame:labelRect inView:controlView]; + } else { + NSRect labelRect = cellFrame; + labelRect.size.width -= badgeWidth; + [super drawInteriorWithFrame:labelRect inView:controlView]; + } +} + +- (CGFloat)drawBadge:(NSRect)cellFrame +{ + // Setup Badge String and Size + NSString *badge = [[NSString alloc] initWithFormat:@"%ld", (long)_badgeCount]; + NSSize badgeNumSize = [badge sizeWithAttributes:nil]; + NSFont *badgeFont = [self font]; + + // Calculate the Badge's coordinate + CGFloat badgeWidth = badgeNumSize.width + TSBADGECELL_BUFFER_SIDE * 2; + if (badgeNumSize.width < TSBADGECELL_TEXT_MINI) { + badgeWidth = TSBADGECELL_TEXT_SMALL; + } + + CGFloat badgeY = cellFrame.origin.y + ((cellFrame.size.height - TSBADGECELL_TEXT_HEIGHT) / 2.0); + CGFloat badgeX = cellFrame.origin.x + cellFrame.size.width - + TSBADGECELL_CIRCLE_BUFFER_RIGHT - badgeWidth; + CGFloat badgeNumX = badgeX + TSBADGECELL_BUFFER_LEFT; + if (badgeNumSize.width < TSBADGECELL_TEXT_MINI) { + badgeNumX += TSBADGECELL_BUFFER_LEFT_SMALL; + } + + // Draw the badge and number + NSRect badgeRect = NSMakeRect(badgeX, badgeY, badgeWidth, TSBADGECELL_TEXT_HEIGHT); + NSBezierPath *badgePath = [NSBezierPath bezierPathWithRoundedRect:badgeRect + xRadius:TSBADGECELL_RADIUS_X + yRadius:TSBADGECELL_RADIUS_Y]; + + BOOL isWindowFront = [[NSApp mainWindow] isVisible]; + BOOL isViewInFocus = [[[[self controlView] window] firstResponder] isEqual:[self controlView]]; + BOOL isCellHighlighted = [self isHighlighted]; + + NSDictionary *dict = [[NSMutableDictionary alloc] init]; + [dict setValue:badgeFont forKey:NSFontAttributeName]; + + if (isWindowFront && isViewInFocus && isCellHighlighted) { + [[NSColor whiteColor] set]; + [dict setValue:[NSColor alternateSelectedControlColor] forKey:NSForegroundColorAttributeName]; + } else if (isWindowFront && isViewInFocus && !isCellHighlighted) { + [[NSColor colorWithCalibratedRed:0.53 green:0.60 blue:0.74 alpha:1.0] set]; + [dict setValue:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; + } else if (isWindowFront && isCellHighlighted) { + [[NSColor whiteColor] set]; + [dict setValue:[NSColor colorWithCalibratedRed:0.51 green:0.58 blue:0.72 alpha:1.0] forKey:NSForegroundColorAttributeName]; + } else if (!isWindowFront && isCellHighlighted) { + [[NSColor whiteColor] set]; + [dict setValue:[NSColor disabledControlTextColor] forKey:NSForegroundColorAttributeName]; + } else { + [[NSColor disabledControlTextColor] set]; + [dict setValue:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; + } + + [badgePath fill]; + [badge drawAtPoint:NSMakePoint(badgeNumX, badgeY) withAttributes:dict]; + + [badge release]; + [dict release]; + return badgeWidth + TSBADGECELL_PADDING; +} + +@end diff --git a/Sources/Exporter-Importer/MHExporterImporter.h b/Sources/Exporter-Importer/MHExporterImporter.h new file mode 100644 index 00000000..13823ad9 --- /dev/null +++ b/Sources/Exporter-Importer/MHExporterImporter.h @@ -0,0 +1,21 @@ +// +// MHExporterImporter.h +// MongoHub +// +// Created by Jérôme Lebel on 16/04/14. +// + +#import + +extern NSString *MHImporterExporterStartNotification; +extern NSString *MHImporterExporterStopNotification; +extern NSString *MHImporterExporterProgressNotification; +extern NSString *MHImporterExporterNotificationProgressKey; + +@protocol MHImporterExporter +@property (nonatomic, readonly, strong) NSError *error; +@property (nonatomic, readonly, assign) NSUInteger documentProcessedCount; +@property (nonatomic, readonly, weak) NSString *name; +@property (nonatomic, readonly, weak) NSString *identifier; + +@end diff --git a/Sources/Exporter-Importer/MHExporterImporter.m b/Sources/Exporter-Importer/MHExporterImporter.m new file mode 100644 index 00000000..04608432 --- /dev/null +++ b/Sources/Exporter-Importer/MHExporterImporter.m @@ -0,0 +1,13 @@ +// +// MHExporterImporter.m +// MongoHub +// +// Created by Jérôme Lebel on 16/04/14. +// + +#import "MHExporterImporter.h" + +NSString *MHImporterExporterStartNotification = @"MHImporterExporterStartNotification"; +NSString *MHImporterExporterStopNotification = @"MHImporterExporterStopNotification"; +NSString *MHImporterExporterProgressNotification = @"MHImporterExporterProgressNotification"; +NSString *MHImporterExporterNotificationProgressKey = @"MHImporterExporterNotificationProgressKey"; \ No newline at end of file diff --git a/Sources/Exporter-Importer/MHFileExporter.h b/Sources/Exporter-Importer/MHFileExporter.h new file mode 100644 index 00000000..25cd6ea3 --- /dev/null +++ b/Sources/Exporter-Importer/MHFileExporter.h @@ -0,0 +1,31 @@ +// +// MHFileExporter.h +// MongoHub +// +// Created by Jérôme Lebel on 19/11/2011. +// + +#import +#import +#import "MHExporterImporter.h" + +@class MODCollection; + +@interface MHFileExporter : NSObject +{ + NSString *_exportPath; + MODCollection *_collection; + int64_t _ii; + NSError *_error; + MODJsonKeySortOrder _jsonKeySortOrder; + NSUInteger _documentProcessedCount; +} + +- (instancetype)initWithCollection:(MODCollection *)collection exportPath:(NSString *)exportPath; +- (void)export; + +@property (nonatomic, readonly, strong) NSString *exportPath; +@property (nonatomic, readonly, strong) MODCollection *collection; +@property (nonatomic, readwrite, assign) MODJsonKeySortOrder jsonKeySortOrder; + +@end diff --git a/Sources/Exporter-Importer/MHFileExporter.m b/Sources/Exporter-Importer/MHFileExporter.m new file mode 100644 index 00000000..abd559f5 --- /dev/null +++ b/Sources/Exporter-Importer/MHFileExporter.m @@ -0,0 +1,97 @@ +// +// MHFileExporter.m +// MongoHub +// +// Created by Jérôme Lebel on 19/11/2011. +// + +#import "MHFileExporter.h" + +@interface MHFileExporter () +@property (nonatomic, readwrite, strong) NSError *error; +@property (nonatomic, readwrite, assign) NSUInteger documentProcessedCount; + +@end + +@implementation MHFileExporter + +@synthesize collection = _collection; +@synthesize exportPath = _exportPath; +@synthesize error = _error; +@synthesize jsonKeySortOrder = _jsonKeySortOrder; +@synthesize documentProcessedCount = _documentProcessedCount; + +- (instancetype)initWithCollection:(MODCollection *)collection exportPath:(NSString *)exportPath +{ + if (self = [self init]) { + _collection = [collection retain]; + _exportPath = [exportPath retain]; + self.jsonKeySortOrder = MODJsonKeySortOrderDocument; + } + return self; +} + +- (void)dealloc +{ + [_collection release]; + [_exportPath release]; + self.error = nil; + [super dealloc]; +} + +- (void)export +{ + int fileDescriptor; + + [NSNotificationCenter.defaultCenter postNotificationName:MHImporterExporterStartNotification object:self userInfo:nil]; + fileDescriptor = open([_exportPath fileSystemRepresentation], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fileDescriptor < 0) { + printf("error %d\n", errno); + perror("fichier"); + self.error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]; + [NSNotificationCenter.defaultCenter postNotificationName:MHImporterExporterStopNotification object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self.error, @"error", nil]]; + } else { + [_collection countWithCriteria:nil readPreferences:nil callback:^(int64_t count, MODQuery *mongoQuery) { + MODCursor *cursor; + int64_t step; + + step = count / 200; + if (step == 0) { + step = 1; + } + self.documentProcessedCount = 0; + + cursor = [_collection cursorWithCriteria:nil fields:nil skip:0 limit:0 sort:nil]; + [cursor forEachDocumentWithCallbackDocumentCallback:^(uint64_t index, MODSortedDictionary *document, NSData *documentData) { + NSString *jsonDocument; + const char *cString; + + jsonDocument = [MODClient convertObjectToJson:document pretty:NO strictJson:YES jsonKeySortOrder:self.jsonKeySortOrder]; + cString = [jsonDocument UTF8String]; + write(fileDescriptor, cString, strlen(cString)); + write(fileDescriptor, "\n", 1); + self.documentProcessedCount++; + if (self.documentProcessedCount % step) { + [NSNotificationCenter.defaultCenter postNotificationName:MHImporterExporterProgressNotification object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:(double)self.documentProcessedCount / count], MHImporterExporterNotificationProgressKey, nil]]; + } + return YES; + } endCallback:^(uint64_t documentCounts, BOOL cursorStopped, MODQuery *forEachQuery) { + close(fileDescriptor); + [NSNotificationCenter.defaultCenter postNotificationName:MHImporterExporterStopNotification object:self userInfo:nil]; + }]; + }]; + + } +} + +- (NSString *)identifier +{ + return @"fileexport"; +} + +- (NSString *)name +{ + return @"File Export"; +} + +@end diff --git a/Sources/Exporter-Importer/MHFileImporter.h b/Sources/Exporter-Importer/MHFileImporter.h new file mode 100644 index 00000000..e72e83ed --- /dev/null +++ b/Sources/Exporter-Importer/MHFileImporter.h @@ -0,0 +1,36 @@ +// +// MHFileImporter.h +// MongoHub +// +// Created by Jérôme Lebel on 23/11/2011. +// + +#import +#import "MHExporterImporter.h" + +@class MODCollection, MODQuery, MODRagelJsonParser; + +@interface MHFileImporter : NSObject +{ + NSString *_importPath; + MODCollection *_collection; + MODQuery *_latestQuery; + NSUInteger _fileRead; + + NSMutableArray *_pendingDocuments; + void *_fileDescriptor; + NSError *_error; + unsigned long long _fileSize; + unsigned long long _dataRead; + unsigned long long _dataProcessed; + NSUInteger _documentProcessedCount; +} + +- (instancetype)initWithCollection:(MODCollection *)collection importPath:(NSString *)importPath; +- (void)import; + +@property (nonatomic, readonly, strong) NSString *importPath; +@property (nonatomic, readonly, strong) MODCollection *collection; +@property (nonatomic, readonly, assign) NSUInteger fileRead; + +@end diff --git a/Sources/Exporter-Importer/MHFileImporter.m b/Sources/Exporter-Importer/MHFileImporter.m new file mode 100644 index 00000000..56795fde --- /dev/null +++ b/Sources/Exporter-Importer/MHFileImporter.m @@ -0,0 +1,137 @@ +// +// MHFileImporter.m +// MongoHub +// +// Created by Jérôme Lebel on 23/11/2011. +// + +#import "MHFileImporter.h" +#import +#import "MHExporterImporter.h" + +@interface MHFileImporter() +@property (nonatomic, readwrite, strong) NSError *error; +@property (nonatomic, readwrite, assign) NSUInteger documentProcessedCount; +@property (nonatomic, readwrite, assign) NSUInteger fileRead; + +@property (nonatomic, readwrite, strong) NSMutableArray *pendingDocuments; +@property (nonatomic, readwrite, assign) FILE *fileDescriptor; +@end + +@implementation MHFileImporter + +@synthesize collection = _collection; +@synthesize importPath = _importPath; +@synthesize documentProcessedCount = _documentProcessedCount; +@synthesize fileRead = _fileRead; +@synthesize pendingDocuments = _pendingDocuments; +@synthesize fileDescriptor = _fileDescriptor; +@synthesize error = _error; + +- (instancetype)initWithCollection:(MODCollection *)collection importPath:(NSString *)importPath +{ + if (self = [self init]) { + _collection = [collection retain]; + _importPath = [importPath retain]; + } + return self; +} + +- (void)dealloc +{ + [_collection release]; + [_importPath release]; + [_latestQuery release]; + self.error = nil; + [super dealloc]; +} + +- (void)_appendDocumentToParse:(NSString *)stringDocument flush:(BOOL)flush +{ + if (stringDocument.length > 0) { + [self.pendingDocuments addObject:stringDocument]; + } + if (self.pendingDocuments.count >= 100 || (flush && self.pendingDocuments.count > 0)) { + NSUInteger documentProcessedCount = self.documentProcessedCount; + + [_latestQuery waitUntilFinished]; + [_latestQuery release]; + _dataProcessed = _dataRead; + _latestQuery = [[_collection insertWithDocuments:self.pendingDocuments writeConcern:nil callback:^(MODQuery *query) { + if (query.error && !self.error) { + NSMutableDictionary *userInfo; + + userInfo = [query.error.userInfo.mutableCopy autorelease]; + [userInfo setObject:[NSNumber numberWithUnsignedInteger:[[userInfo objectForKey:@"documentIndex"] unsignedIntegerValue] + documentProcessedCount] forKey:@"documentIndex"]; + self.error = [NSError errorWithDomain:query.error.domain code:query.error.code userInfo:userInfo]; + } + [self performSelectorOnMainThread:@selector(sendNotification:) withObject:@{ @"name" :MHImporterExporterProgressNotification, @"userinfo": @{ MHImporterExporterNotificationProgressKey: @(_dataProcessed / _fileSize) } } waitUntilDone:NO]; + }] retain]; + self.documentProcessedCount += self.pendingDocuments.count; + // to avoid changing the content of the array while trying to import all the documents + // it is better to create a new one (instead of remove all its content) + self.pendingDocuments = [NSMutableArray array]; + } +} + +- (void)import +{ + [NSThread detachNewThreadSelector:@selector(_threadImport) toTarget:self withObject:nil]; +} + +- (void)sendNotification:(NSDictionary *)info +{ + [NSNotificationCenter.defaultCenter postNotificationName:[info objectForKey:@"name"] object:self userInfo:[info objectForKey:@"userinfo"]]; +} + +- (void)_threadImport +{ + [self performSelectorOnMainThread:@selector(sendNotification:) withObject:@{ @"name" :MHImporterExporterStartNotification } waitUntilDone:NO]; + _dataRead = 0; + _fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:_importPath error:nil] fileSize]; + self.fileDescriptor = fopen([_importPath fileSystemRepresentation], "r"); + if (self.fileDescriptor == NULL) { + printf("error %d\n", errno); + perror("fichier"); + self.error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil]; + } else { + self.pendingDocuments = [NSMutableArray array]; + [self _doImport]; + self.pendingDocuments = nil; + fclose(self.fileDescriptor); + [_latestQuery waitUntilFinished]; + } + if (self.error) { + [self performSelectorOnMainThread:@selector(sendNotification:) withObject:@{ @"name" :MHImporterExporterStopNotification, @"userinfo": @{ @"error": self.error } } waitUntilDone:NO]; + } else { + [self performSelectorOnMainThread:@selector(sendNotification:) withObject:@{ @"name" :MHImporterExporterStopNotification } waitUntilDone:NO]; + } +} + +- (void)_doImport +{ + size_t length; + char *line; + + while ((line = fgetln(self.fileDescriptor, &length)) && self.error == nil) { + NSString *result; + + _dataRead += length; + result = [[NSString alloc] initWithBytes:line length:length encoding:NSUTF8StringEncoding]; + [self _appendDocumentToParse:result flush:NO]; + [result release]; + } + [self _appendDocumentToParse:nil flush:YES]; +} + +- (NSString *)identifier +{ + return @"fileimport"; +} + +- (NSString *)name +{ + return @"File Import"; +} + +@end diff --git a/Sources/Exporter-Importer/MHImportExportFeedback.h b/Sources/Exporter-Importer/MHImportExportFeedback.h new file mode 100644 index 00000000..6fa8cac8 --- /dev/null +++ b/Sources/Exporter-Importer/MHImportExportFeedback.h @@ -0,0 +1,25 @@ +// +// MHImportExportFeedback.h +// MongoHub +// +// Created by Jérôme Lebel on 31/01/2014. +// + +#import +#import "MHExporterImporter.h" + +@interface MHImportExportFeedback : NSObject +{ + IBOutlet NSWindow *_window; + IBOutlet NSTextField *_label; + IBOutlet NSProgressIndicator *_progressIndicator; + id _importerExporter; +} +@property (nonatomic, readwrite, retain) NSString *label; + +- (instancetype)initWithImporterExporter:(id)importerExporter; +- (void)displayForWindow:(NSWindow *)window; +- (void)start; +- (void)close; + +@end diff --git a/Sources/Exporter-Importer/MHImportExportFeedback.m b/Sources/Exporter-Importer/MHImportExportFeedback.m new file mode 100644 index 00000000..04f7673c --- /dev/null +++ b/Sources/Exporter-Importer/MHImportExportFeedback.m @@ -0,0 +1,88 @@ +// +// MHImportExportFeedback.m +// MongoHub +// +// Created by Jérôme Lebel on 31/01/2014. +// + +#import "MHImportExportFeedback.h" + +@implementation MHImportExportFeedback + +- (instancetype)initWithImporterExporter:(id)importerExporter +{ + self = [self init]; + if (self) { + [NSBundle.mainBundle loadNibNamed:@"MHImportExportFeedback" owner:self topLevelObjects:nil]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(importerExporterNotification:) name:MHImporterExporterProgressNotification object:importerExporter]; + } + return self; +} + +- (void)dealloc +{ + [NSNotificationCenter.defaultCenter removeObserver:self name:nil object:nil]; + [super dealloc]; +} + +- (void)displayForWindow:(NSWindow *)window +{ + [NSApp beginSheet:_window modalForWindow:window modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:nil]; +} + +- (void)start +{ + _progressIndicator.indeterminate = YES; + [_progressIndicator startAnimation:self]; +} + +- (void)close +{ + [NSApp endSheet:_window]; +} + +- (void)sheetDidEnd:(NSWindow *)window returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + [_window orderOut:self]; +} + +- (void)setLabel:(NSString *)label +{ + _label.stringValue = label; +} + +- (NSString *)label +{ + return _label.stringValue; +} + +- (void)setMaxValue:(double)maxValue +{ + _progressIndicator.maxValue = maxValue; +} + +- (double)maxValue +{ + return _progressIndicator.maxValue; +} + +- (void)setProgressValue:(double)progressValue +{ + _progressIndicator.doubleValue = progressValue; +} + +- (double)progressValue +{ + return _progressIndicator.doubleValue; +} + +- (void)importerExporterNotification:(NSNotification *)notification +{ + if (_progressIndicator.isIndeterminate) { + _progressIndicator.indeterminate = NO; + _progressIndicator.maxValue = 1.0; + } + self.progressValue = [[notification.userInfo objectForKey:MHImporterExporterNotificationProgressKey] floatValue]; +} + +@end diff --git a/ExportWindowController.h b/Sources/Exporter-Importer/MHMysqlExportWindowController.h similarity index 65% rename from ExportWindowController.h rename to Sources/Exporter-Importer/MHMysqlExportWindowController.h index f4681b44..35f1ac77 100644 --- a/ExportWindowController.h +++ b/Sources/Exporter-Importer/MHMysqlExportWindowController.h @@ -1,5 +1,5 @@ // -// ExportWindowController.h +// MHMysqlExportWindowController.h // MongoHub // // Created by Syd on 10-6-22. @@ -7,19 +7,14 @@ // #import -#import -@class Connection; -@class DatabasesArrayController; @class MCPConnection; -@class MongoDB; +@class MODCollection; +@class MODDatabase; @class FieldMapTableController; -@interface ExportWindowController : NSWindowController { - NSManagedObjectContext *managedObjectContext; - DatabasesArrayController *databasesArrayController; +@interface MHMysqlExportWindowController : NSWindowController { NSString *dbname; - Connection *conn; - MongoDB *mongoDB; + MODDatabase *mongoDatabase; MCPConnection *db; IBOutlet NSArrayController *dbsArrayController; IBOutlet NSArrayController *tablesArrayController; @@ -33,11 +28,7 @@ IBOutlet FieldMapTableController *fieldMapTableController; } -@property (nonatomic, retain) Connection *conn; -@property (nonatomic, retain) MCPConnection *db; -@property (nonatomic, retain) MongoDB *mongoDB; -@property (nonatomic, retain) DatabasesArrayController *databasesArrayController; -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; +@property (nonatomic, retain) MODDatabase *mongoDatabase; @property (nonatomic, retain) NSString *dbname; @property (nonatomic, retain) NSArrayController *dbsArrayController; @property (nonatomic, retain) NSArrayController *tablesArrayController; @@ -55,6 +46,6 @@ - (IBAction)export:(id)sender; - (IBAction)showTables:(id)sender; - (IBAction)showFields:(id)sender; -- (long long int)exportCount:(NSString *)collection user:(NSString *)user password:(NSString *)password; -- (void)doExportToTable:(NSString *)tableName data:(mongo::BSONObj) bsonObj fieldTypes:(NSDictionary *)fieldTypes; +- (int64_t)exportCount:(MODCollection *)collection; +- (void)doExportToTable:(NSString *)tableName data:(id) bsonObj fieldTypes:(NSDictionary *)fieldTypes fieldMapping:(NSArray *)fieldMapping; @end diff --git a/ExportWindowController.mm b/Sources/Exporter-Importer/MHMysqlExportWindowController.m similarity index 50% rename from ExportWindowController.mm rename to Sources/Exporter-Importer/MHMysqlExportWindowController.m index ba35e409..b306400a 100644 --- a/ExportWindowController.mm +++ b/Sources/Exporter-Importer/MHMysqlExportWindowController.m @@ -1,30 +1,22 @@ // -// ExportWindowController.m +// MHMysqlExportWindowController.m // MongoHub // // Created by Syd on 10-6-22. // Copyright 2010 ThePeppersStudio.COM. All rights reserved. // -#import "ExportWindowController.h" -#import "Configure.h" -#import "DatabasesArrayController.h" -#import "Database.h" -#import "Connection.h" -#import "NSString+Extras.h" -#import "MongoDB.h" -#import +#import "MHMysqlExportWindowController.h" +#import "NSString+MongoHub.h" +#import +#import #import "FieldMapTableController.h" #import "FieldMapDataObject.h" -@implementation ExportWindowController +@implementation MHMysqlExportWindowController @synthesize dbname; -@synthesize conn; -@synthesize db; -@synthesize mongoDB; -@synthesize databasesArrayController; -@synthesize managedObjectContext; +@synthesize mongoDatabase; @synthesize dbsArrayController; @synthesize tablesArrayController; @synthesize hostTextField; @@ -36,18 +28,15 @@ @implementation ExportWindowController @synthesize tablesPopUpButton; @synthesize fieldMapTableController; -- (id)init { - if (![super initWithWindowNibName:@"Export"]) return nil; +- (instancetype)init { + self = [super initWithWindowNibName:@"MysqlExport"]; return self; } - (void)dealloc { [dbname release]; - [managedObjectContext release]; - [databasesArrayController release]; - [conn release]; [db release]; - [mongoDB release]; + [mongoDatabase release]; [dbsArrayController release]; [tablesArrayController release]; [hostTextField release]; @@ -67,134 +56,102 @@ - (void)windowDidLoad { } - (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:kExportWindowWillClose object:dbname]; dbname = nil; db = nil; [self initInterface]; } - (IBAction)export:(id)sender { + MODClient *copyServer; + MODCollection *mongoCollection; + + copyServer = [[mongoDatabase.client copy] autorelease]; [progressIndicator setUsesThreadedAnimation:YES]; [progressIndicator startAnimation: self]; [progressIndicator setDoubleValue:0]; - NSString *collection = [[NSString alloc] initWithString:[collectionTextField stringValue]]; - if (![collection isPresent]) { - NSRunAlertPanel(@"Error", @"Collection name could not be empty!", @"OK", nil, nil); + NSString *collection = [collectionTextField stringValue]; + if ([collection length] == 0) { + NSRunAlertPanel(@"Error", @"Collection name can not be empty!", @"OK", nil, nil); return; } - NSString *tablename = [[NSString alloc] initWithString:[tablesPopUpButton titleOfSelectedItem]]; + mongoCollection = [[copyServer databaseForName:mongoDatabase.name] collectionForName:collection]; + NSString *tablename = [tablesPopUpButton titleOfSelectedItem]; - NSString *user=nil; - NSString *password=nil; - Database *mongodb = [databasesArrayController dbInfo:conn name:dbname]; - if (mongodb) { - user = mongodb.user; - password = mongodb.password; - } - [mongodb release]; - long long int total = [self exportCount:collection user:user password:password]; + int64_t total = [self exportCount:mongoCollection]; if (total == 0) { return; } NSString *query = [[NSString alloc] initWithFormat:@"select * from %@ limit 1", tablename]; MCPResult *theResult = [db queryString:query]; - [query release]; NSDictionary *fieldTypes = [theResult fetchTypesAsDictionary]; + NSArray *fieldMapping = [fieldMapTableController.nsMutaryDataObj copy]; - mongo::BSONObjBuilder fieldsBSONBuilder; - for(FieldMapDataObject *field in fieldMapTableController.nsMutaryDataObj) - { - fieldsBSONBuilder.append([field.mongoKey UTF8String], 1); - } - mongo::BSONObj fieldsBSONObj = fieldsBSONBuilder.obj(); - std::auto_ptr cursor = [mongoDB findAllCursorInDB:dbname collection:collection user:user password:password fields:fieldsBSONObj]; - int i = 1; - while( cursor->more() ) - { - mongo::BSONObj b = cursor->next(); - [self doExportToTable:tablename data:b fieldTypes:fieldTypes]; - [progressIndicator setDoubleValue:(double)i/total]; - i ++; - } - [progressIndicator stopAnimation: self]; - [tablename release]; - [collection release]; + MODCursor *cursor; + cursor = [mongoCollection cursorWithCriteria:nil fields:nil skip:0 limit:0 sort:nil]; + [cursor forEachDocumentWithCallbackDocumentCallback:^(uint64_t index, MODSortedDictionary *document, NSData *documentData) { + [self doExportToTable:tablename data:document fieldTypes:fieldTypes fieldMapping:fieldMapping]; + [progressIndicator setDoubleValue:(double)index/total]; + return YES; + } endCallback:^(uint64_t documentCounts, BOOL cursorStopped, MODQuery *mongoQuery) { + [progressIndicator stopAnimation: self]; + }]; + [query release]; + [fieldMapping release]; } -- (long long int)exportCount:(NSString *)collection user:(NSString *)user password:(NSString *)password +- (int64_t)exportCount:(MODCollection *)collection { - long long int result = [mongoDB countInDB:dbname collection:collection user:user password:password critical:nil]; - return result; + MODQuery *query; + + query = [collection countWithCriteria:nil readPreferences:nil callback:nil]; + [query waitUntilFinished]; + return [query.result longLongValue]; } -- (void)doExportToTable:(NSString *)tableName data:(mongo::BSONObj) bsonObj fieldTypes:(NSDictionary *)fieldTypes +- (void)doExportToTable:(NSString *)tableName data:(id)mongoDocument fieldTypes:(NSDictionary *)fieldTypes fieldMapping:(NSArray *)fieldMapping { - int fieldsCount = [fieldMapTableController.nsMutaryDataObj count]; + NSUInteger fieldsCount = fieldMapping.count; NSMutableArray *fields = [[NSMutableArray alloc] initWithCapacity:fieldsCount]; NSMutableArray *values = [[NSMutableArray alloc] initWithCapacity:fieldsCount]; - for(FieldMapDataObject *field in fieldMapTableController.nsMutaryDataObj) + for(FieldMapDataObject *field in fieldMapping) { id value; - mongo::BSONElement e = bsonObj.getFieldDotted([field.mongoKey UTF8String]); - if (e.eoo() == true) { + id mongoValue = [mongoDocument objectForKey:field.mongoKey]; + if (mongoValue == nil) { continue; - } - if (e.type() == mongo::jstNULL) { + } else if ([mongoValue isKindOfClass:[NSArray class]]) { continue; - }else if (e.type() == mongo::Array) { + } else if ([mongoValue isKindOfClass:[MODSortedDictionary class]]) { continue; - }else if (e.type() == mongo::Object) { - continue; - }else if (e.type() == mongo::Bool) { - if (e.boolean()) { + } else if ([mongoValue isKindOfClass:[NSNumber class]] && strcmp([mongoValue objCType], @encode(BOOL)) == 0) { + if ([mongoValue boolValue]) { value = [[NSString alloc] initWithString:@"1" ]; }else { value = [[NSString alloc] initWithString:@"0"]; } - }else if (e.type() == mongo::NumberDouble) { - value = [[NSNumber alloc] initWithDouble: e.numberDouble()]; - }else if (e.type() == mongo::NumberInt) { - NSString *ft = [fieldTypes objectForKey:field.sqlKey]; - if ([ft isEqualToString:@"date"] || [ft isEqualToString:@"datetime"]) { - value = [[NSDate alloc] initWithTimeIntervalSince1970:e.numberInt()]; - }else { - value = [[NSNumber alloc] initWithInt: e.numberInt()]; - } - }else if (e.type() == mongo::Date) { - mongo::Date_t dt = (time_t)e.date(); - time_t timestamp = dt / 1000; - value = [[NSDate alloc] initWithTimeIntervalSince1970:timestamp]; - }else if (e.type() == mongo::Timestamp) { - time_t timestamp = (time_t)e.timestampTime(); - value = [[NSDate alloc] initWithTimeIntervalSince1970:timestamp]; - }else if (e.type() == mongo::BinData) { - int binlen; - const char* data = e.binData(binlen); - value = [[NSData alloc] initWithBytes:data length:binlen]; - }else if (e.type() == mongo::NumberLong) { + } else if ([mongoValue isKindOfClass:[NSNumber class]]) { NSString *ft = [fieldTypes objectForKey:field.sqlKey]; if ([ft isEqualToString:@"date"] || [ft isEqualToString:@"datetime"]) { - value = [[NSDate alloc] initWithTimeIntervalSince1970:e.numberLong()]; + value = [[NSDate alloc] initWithTimeIntervalSince1970:[mongoValue doubleValue]]; }else { - value = [[NSNumber alloc] initWithLong: e.numberLong()]; + value = [mongoValue retain]; } - }else if ([field.mongoKey isEqualToString:@"_id" ]) { - if (e.type() == mongo::jstOID) - { - value = [[NSString alloc] initWithUTF8String: e.__oid().str().c_str()]; - }else { - value = [[NSString alloc] initWithUTF8String: e.str().c_str()]; - } - }else { - value = [[NSString alloc] initWithUTF8String:e.str().c_str()]; + } else if ([mongoValue isKindOfClass:[MODTimestamp class]]) { + value = [[mongoValue dateValue] retain]; + } else if ([mongoValue isKindOfClass:[MODBinary class]]) { + value = [[mongoValue data] retain]; + } else if ([mongoValue isKindOfClass:[MODObjectId class]]) { + value = [[mongoValue stringValue] retain]; + } else if ([mongoValue isKindOfClass:[NSString class]] || [mongoValue isKindOfClass:[NSData class]] || [mongoValue isKindOfClass:[NSDate class]]) { + value = [mongoValue retain]; + } else { + value = [[mongoValue description] retain]; } - NSString *sqlKey = [[NSString alloc] initWithString:field.sqlKey]; - NSString *quotedValue = [[NSString alloc] initWithString:[db quoteObject:value]]; + NSString *sqlKey = field.sqlKey; + NSString *quotedValue = [db quoteObject:value]; [value release]; [fields addObject:sqlKey]; [values addObject:quotedValue]; - [quotedValue release]; - [sqlKey release]; } if ([fields count] > 0) { NSString *query = [[NSString alloc] initWithFormat:@"INSERT INTO %@ (%@) values (%@)", tableName, [fields componentsJoinedByString:@","], [values componentsJoinedByString:@","]]; @@ -207,11 +164,29 @@ - (void)doExportToTable:(NSString *)tableName data:(mongo::BSONObj) bsonObj fiel } - (IBAction)connect:(id)sender { + NSString *mysqlHostname; + NSString *userName; + NSUInteger port; + if (db) { [self initInterface]; [db release]; } - db = [[MCPConnection alloc] initToHost:[hostTextField stringValue] withLogin:[userTextField stringValue] password:[passwdTextField stringValue] usingPort:[portTextField intValue] ]; + mysqlHostname = hostTextField.stringValue.mh_stringByTrimmingWhitespace; + if ([mysqlHostname length] == 0) { + mysqlHostname = [[hostTextField cell] placeholderString]; + } + userName = userTextField.stringValue.mh_stringByTrimmingWhitespace; + if ([userName length] == 0) { + userName = [[userTextField cell] placeholderString]; + } + port = [portTextField intValue]; + if (port == 0) { + port = [[[portTextField cell] placeholderString] intValue]; + } + db = [[MCPConnection alloc] initToHost:mysqlHostname withLogin:userName usingPort:port]; + [db setPassword:[passwdTextField stringValue]]; + [db connect]; NSLog(@"Connect: %d", [db isConnected]); if (![db isConnected]) { @@ -220,11 +195,11 @@ - (IBAction)connect:(id)sender { [db queryString:@"SET NAMES utf8"]; [db queryString:@"SET CHARACTER SET utf8"]; [db queryString:@"SET COLLATION_CONNECTION='utf8_general_ci'"]; - [db setEncoding:NSUTF8StringEncoding]; + [db setEncoding:@"utf8"]; MCPResult *dbs = [db listDBs]; NSArray *row; - NSMutableArray *databases = [[NSMutableArray alloc] initWithCapacity:[dbs numOfRows]]; - while (row = [dbs fetchRowAsArray]) { + NSMutableArray *databases = [[NSMutableArray alloc] initWithCapacity:(NSUInteger)[dbs numOfRows]]; + while ((row = [dbs fetchRowAsArray])) { NSDictionary *database = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil]; [databases addObject:database]; [database release]; @@ -241,18 +216,16 @@ - (IBAction)showTables:(id)sender dbn = [[[dbsArrayController arrangedObjects] objectAtIndex:0] objectForKey:@"name"]; }else { NSPopUpButton *pb = sender; - dbn = [[NSString alloc] initWithString:[pb titleOfSelectedItem]]; + dbn = [NSString stringWithString:[pb titleOfSelectedItem]]; } - if (![dbn isPresent]) { - [dbn release]; + if ([dbn length] == 0) { return; } [db selectDB:dbn]; - [dbn release]; MCPResult *tbs = [db listTables]; NSArray *row; - NSMutableArray *tables = [[NSMutableArray alloc] initWithCapacity:[tbs numOfRows]]; - while (row = [tbs fetchRowAsArray]) { + NSMutableArray *tables = [[NSMutableArray alloc] initWithCapacity:(NSUInteger)[tbs numOfRows]]; + while ((row = [tbs fetchRowAsArray])) { NSDictionary *table = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil]; [tables addObject:table]; [table release]; diff --git a/Sources/Exporter-Importer/MHMysqlExporter.h b/Sources/Exporter-Importer/MHMysqlExporter.h new file mode 100644 index 00000000..8ecd36e5 --- /dev/null +++ b/Sources/Exporter-Importer/MHMysqlExporter.h @@ -0,0 +1,20 @@ +// +// MHMysqlExporter.h +// MongoHub +// +// Created by Jérôme Lebel on 27/11/2011. +// + +#import + +@class MODCollection; + +@interface MHMysqlExporter : NSObject +{ + MODCollection *_collection; +} + +- (instancetype)initWithCollection:(MODCollection *)collection; +- (BOOL)exportWithError:(NSError **)error; + +@end diff --git a/Sources/Exporter-Importer/MHMysqlExporter.m b/Sources/Exporter-Importer/MHMysqlExporter.m new file mode 100644 index 00000000..efd4e06c --- /dev/null +++ b/Sources/Exporter-Importer/MHMysqlExporter.m @@ -0,0 +1,22 @@ +// +// MHMysqlExporter.m +// MongoHub +// +// Created by Jérôme Lebel on 27/11/2011. +// + +#import "MHMysqlExporter.h" + +@implementation MHMysqlExporter + +- (instancetype)initWithCollection:(MODCollection *)collection +{ + return [self init]; +} + +- (BOOL)exportWithError:(NSError **)error +{ + return NO; +} + +@end diff --git a/ImportWindowController.h b/Sources/Exporter-Importer/MHMysqlImportWindowController.h similarity index 63% rename from ImportWindowController.h rename to Sources/Exporter-Importer/MHMysqlImportWindowController.h index b017f9bc..40c4c5da 100644 --- a/ImportWindowController.h +++ b/Sources/Exporter-Importer/MHMysqlImportWindowController.h @@ -1,5 +1,5 @@ // -// ImportWindowController.h +// MHMysqlImportWindowController.h // MongoHub // // Created by Syd on 10-6-16. @@ -7,18 +7,12 @@ // #import -@class Connection; -@class DatabasesArrayController; @class MCPConnection; -@class MongoDB; +@class MODDatabase; -@interface ImportWindowController : NSWindowController { - NSManagedObjectContext *managedObjectContext; - DatabasesArrayController *databasesArrayController; - NSString *dbname; - Connection *conn; - MongoDB *mongoDB; - MCPConnection *db; +@interface MHMysqlImportWindowController : NSWindowController { + MODDatabase *_database; + MCPConnection *_mysqlConnection; IBOutlet NSArrayController *dbsArrayController; IBOutlet NSArrayController *tablesArrayController; IBOutlet NSTextField *hostTextField; @@ -31,12 +25,7 @@ IBOutlet NSPopUpButton *tablesPopUpButton; } -@property (nonatomic, retain) Connection *conn; -@property (nonatomic, retain) MCPConnection *db; -@property (nonatomic, retain) MongoDB *mongoDB; -@property (nonatomic, retain) DatabasesArrayController *databasesArrayController; -@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, retain) NSString *dbname; +@property (nonatomic, retain) MODDatabase *database; @property (nonatomic, retain) NSArrayController *dbsArrayController; @property (nonatomic, retain) NSArrayController *tablesArrayController; @property (nonatomic, retain) NSTextField *hostTextField; @@ -52,7 +41,7 @@ - (IBAction)import:(id)sender; - (IBAction)showTables:(id)sender; - (long long int)importCount:(NSString *)tableName; -- (void)doImportFromTable:(NSString *)tableName toCollection:(NSString *)collection withChunkSize:(int)chunkSize fromId:(int)fromId totalResults:(int)total user:(NSString *)user password:(NSString *)password; +- (void)doImportFromTable:(NSString *)tableName toCollection:(NSString *)collection withChundSize:(int)chunkSize; @end diff --git a/Sources/Exporter-Importer/MHMysqlImportWindowController.m b/Sources/Exporter-Importer/MHMysqlImportWindowController.m new file mode 100644 index 00000000..5ea7ed26 --- /dev/null +++ b/Sources/Exporter-Importer/MHMysqlImportWindowController.m @@ -0,0 +1,236 @@ +// +// MHMysqlImportWindowController.m +// MongoHub +// +// Created by Syd on 10-6-16. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import "MHMysqlImportWindowController.h" +#import "NSString+MongoHub.h" +#import +#import + +@interface MHMysqlImportWindowController () + +@property (nonatomic, readwrite, retain) MCPConnection *mysqlConnection; + +@end + +@implementation MHMysqlImportWindowController + +@synthesize database = _database, mysqlConnection = _mysqlConnection; +@synthesize dbsArrayController; +@synthesize tablesArrayController; +@synthesize hostTextField; +@synthesize portTextField; +@synthesize userTextField; +@synthesize passwdTextField; +@synthesize chunkSizeTextField; +@synthesize collectionTextField; +@synthesize progressIndicator; +@synthesize tablesPopUpButton; + +- (instancetype)init +{ + self = [super initWithWindowNibName:@"MysqlImport"]; + return self; +} + +- (void)dealloc +{ + self.mysqlConnection = nil; + self.database = nil; + self.dbsArrayController = nil; + self.tablesArrayController = nil; + self.hostTextField = nil; + self.portTextField = nil; + self.userTextField = nil; + self.passwdTextField = nil; + self.chunkSizeTextField = nil; + self.collectionTextField = nil; + self.progressIndicator = nil; + self.tablesPopUpButton = nil; + [super dealloc]; +} + +- (void)windowDidLoad +{ + //NSLog(@"New Connection Window Loaded"); + [super windowDidLoad]; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + [dbsArrayController setContent:nil]; + [tablesArrayController setContent:nil]; + [progressIndicator setDoubleValue:0.0]; +} + +- (IBAction)import:(id)sender +{ + [progressIndicator setUsesThreadedAnimation:YES]; + [progressIndicator startAnimation: self]; + [progressIndicator setDoubleValue:0]; + NSString *collection = [collectionTextField stringValue]; + int chunkSize = [chunkSizeTextField intValue]; + if ([collection length] == 0) { + NSRunAlertPanel(@"Error", @"Collection name can not be empty!", @"OK", nil, nil); + return; + } + if (chunkSize == 0) { + NSRunAlertPanel(@"Error", @"Chunk Size can not be 0!", @"OK", nil, nil); + return; + } + [self doImportFromTable:[tablesPopUpButton titleOfSelectedItem] toCollection:collection withChundSize:chunkSize]; +} + +- (long long int)importCount:(NSString *)tableName +{ + NSString *query = [[NSString alloc] initWithFormat:@"select count(*) counter from %@", tableName]; + MCPResult *theResult = [self.mysqlConnection queryString:query]; + [query release]; + NSArray *row = [theResult fetchRowAsArray]; + NSLog(@"count: %@", [row objectAtIndex:0]); + return [[row objectAtIndex:0] intValue]; +} + +- (void)updateProgressIndicatorWithNumber:(NSNumber *)number +{ + [progressIndicator setDoubleValue:[number doubleValue]]; +} + +- (void)importDone:(id)unused +{ + [progressIndicator setDoubleValue:1.0]; + [progressIndicator stopAnimation:nil]; +} + +- (void)doImportFromTable:(NSString *)tableName toCollection:(NSString *)collectionName withChundSize:(int)chunkSize +{ + MODClient *copyServer; + MODCollection *copyCollection; + + copyServer = [[self.database.client copy] autorelease]; + + copyCollection = [[copyServer databaseForName:self.database.name] collectionForName:collectionName]; + if (!copyServer) { + NSRunAlertPanel(@"Error", @"Can not create a second connection to the mongo server.", @"OK", nil, nil); + return; + } + dispatch_queue_t myQueue = dispatch_queue_create("com.mongohub.mysql", 0); + + dispatch_async(myQueue, ^ { + long long total = [self importCount:tableName]; + long long ii = 0; + + while (ii < total) { + NSString *query = [[NSString alloc] initWithFormat:@"select * from %@ limit %lld, %d", tableName, ii, chunkSize]; + MCPResult *theResult = [self.mysqlConnection queryString:query]; + NSDictionary *row; + NSMutableArray *documents; + + [query release]; + if ([theResult numOfRows] == 0) { + return; + } + while ((row = [theResult fetchRowAsDictionary])) { + void (^callback)(MODQuery *mongoQuery); + MODSortedDictionary *document; + + ii++; + document = [[MODSortedDictionary alloc] initWithDictionary:row]; + documents = [[NSMutableArray alloc] initWithObjects:document, nil]; + [document release]; + if (ii == total) { + callback = ^(MODQuery *mongoQuery) { + [self importDone:nil]; + }; + } else if (ii % 10 == 0) { + callback = ^(MODQuery *mongoQuery) { + [progressIndicator setDoubleValue:(double)ii/(double)total]; + }; + } else { + callback = nil; + } + [copyCollection insertWithDocuments:documents writeConcern:nil callback:callback]; + [documents release]; + } + } + }); +} + +- (IBAction)connect:(id)sender +{ + NSString *mysqlHostname; + NSString *userName; + NSUInteger port; + + if (self.mysqlConnection) { + [dbsArrayController setContent:nil]; + [tablesArrayController setContent:nil]; + [progressIndicator setDoubleValue:0.0]; + self.mysqlConnection = nil; + } + mysqlHostname = hostTextField.stringValue.mh_stringByTrimmingWhitespace; + if ([mysqlHostname length] == 0) { + mysqlHostname = [[hostTextField cell] placeholderString]; + } + userName = userTextField.stringValue.mh_stringByTrimmingWhitespace; + if ([userName length] == 0) { + userName = [[userTextField cell] placeholderString]; + } + port = [portTextField intValue]; + if (port == 0) { + port = [[[portTextField cell] placeholderString] intValue]; + } + self.mysqlConnection = [[[MCPConnection alloc] initToHost:mysqlHostname withLogin:userName usingPort:port] autorelease]; + [self.mysqlConnection setPassword:[passwdTextField stringValue]]; + [self.mysqlConnection connect]; + NSLog(@"Connect: %d", self.mysqlConnection.isConnected); + if (!self.mysqlConnection.isConnected) + { + NSRunAlertPanel(@"Error", @"Could not connect to the mysql server!", @"OK", nil, nil); + } + [self.mysqlConnection queryString:@"SET NAMES utf8"]; + [self.mysqlConnection queryString:@"SET CHARACTER SET utf8"]; + [self.mysqlConnection queryString:@"SET COLLATION_CONNECTION='utf8_general_ci'"]; + [self.mysqlConnection setEncoding:@"utf8"]; + MCPResult *dbs = self.mysqlConnection.listDBs; + NSArray *row; + NSMutableArray *databases = [[NSMutableArray alloc] initWithCapacity:(NSUInteger)[dbs numOfRows]]; + while ((row = [dbs fetchRowAsArray])) { + NSDictionary *database = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil]; + [databases addObject:database]; + [database release]; + } + [dbsArrayController setContent:databases]; + [databases release]; +} + +- (IBAction)showTables:(id)sender +{ + NSString *dbn; + if (sender == nil && [[dbsArrayController arrangedObjects] count] > 0) { + dbn = [[[dbsArrayController arrangedObjects] objectAtIndex:0] objectForKey:@"name"]; + }else { + NSPopUpButton *pb = sender; + dbn = [NSString stringWithString:[pb titleOfSelectedItem]]; + } + if ([dbn length] == 0) { + return; + } + [self.mysqlConnection selectDB:dbn]; + MCPResult *tbs = self.mysqlConnection.listTables; + NSArray *row; + NSMutableArray *tables = [[NSMutableArray alloc] initWithCapacity:(NSUInteger)[tbs numOfRows]]; + while ((row = [tbs fetchRowAsArray])) { + NSDictionary *table = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil]; + [tables addObject:table]; + [table release]; + } + [tablesArrayController setContent:tables]; + [tables release]; +} + +@end diff --git a/Sources/Exporter-Importer/MHMysqlImporter.h b/Sources/Exporter-Importer/MHMysqlImporter.h new file mode 100644 index 00000000..91fac2b7 --- /dev/null +++ b/Sources/Exporter-Importer/MHMysqlImporter.h @@ -0,0 +1,12 @@ +// +// MHMysqlImporter.h +// MongoHub +// +// Created by Jérôme Lebel on 27/11/2011. +// + +#import + +@interface MHMysqlImporter : NSObject + +@end diff --git a/Sources/Exporter-Importer/MHMysqlImporter.m b/Sources/Exporter-Importer/MHMysqlImporter.m new file mode 100644 index 00000000..082e9a53 --- /dev/null +++ b/Sources/Exporter-Importer/MHMysqlImporter.m @@ -0,0 +1,12 @@ +// +// MHMysqlImporter.m +// MongoHub +// +// Created by Jérôme Lebel on 27/11/2011. +// + +#import "MHMysqlImporter.h" + +@implementation MHMysqlImporter + +@end diff --git a/FieldMapDataObject.h b/Sources/Helpers/FieldMapDataObject.h similarity index 81% rename from FieldMapDataObject.h rename to Sources/Helpers/FieldMapDataObject.h index 6fa9dcc1..df4d1fc0 100644 --- a/FieldMapDataObject.h +++ b/Sources/Helpers/FieldMapDataObject.h @@ -17,6 +17,6 @@ @property (nonatomic, retain) NSString *sqlKey; @property (nonatomic, retain) NSString *mongoKey; -- (id)initWithSqlKey:(NSString *)pStr1 andMongoKey:(NSString *)pStr2; +- (instancetype)initWithSqlKey:(NSString *)pStr1 andMongoKey:(NSString *)pStr2; @end diff --git a/FieldMapDataObject.m b/Sources/Helpers/FieldMapDataObject.m similarity index 87% rename from FieldMapDataObject.m rename to Sources/Helpers/FieldMapDataObject.m index 5a00687c..3cdbe32a 100644 --- a/FieldMapDataObject.m +++ b/Sources/Helpers/FieldMapDataObject.m @@ -14,7 +14,7 @@ @implementation FieldMapDataObject @synthesize sqlKey; @synthesize mongoKey; -- (id)initWithSqlKey:(NSString *)pStr1 andMongoKey:(NSString *)pStr2 { +- (instancetype)initWithSqlKey:(NSString *)pStr1 andMongoKey:(NSString *)pStr2 { if (! (self = [super init])) { NSLog(@"MyDataObject **** ERROR : [super init] failed ***"); return self; diff --git a/Sources/Helpers/MHKeychain.h b/Sources/Helpers/MHKeychain.h new file mode 100644 index 00000000..f37138ee --- /dev/null +++ b/Sources/Helpers/MHKeychain.h @@ -0,0 +1,30 @@ +// +// MHKeychain.h +// MongoHub +// +// Created by Jérôme Lebel on 25/10/2013. +// + +#import + +@interface MHKeychain : NSObject + +@end + +@interface MHKeychain (InternetPassword) ++ (BOOL)addInternetPasswordWithProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account password:(NSString *)password; ++ (BOOL)updateInternetPasswordProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account password:(NSString *)password; ++ (BOOL)addOrUpdateInternetPasswordWithProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account password:(NSString *)password; ++ (NSString *)internetPasswordProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account; ++ (BOOL)deleteInternetPasswordProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account; + +@end + +@interface MHKeychain (GenericPassword) ++ (BOOL)addItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password; ++ (BOOL)updateItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password; ++ (BOOL)addOrUpdateItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password; ++ (NSString *)passwordWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description; ++ (BOOL)deleteItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description; + +@end \ No newline at end of file diff --git a/Sources/Helpers/MHKeychain.m b/Sources/Helpers/MHKeychain.m new file mode 100644 index 00000000..9c8dece4 --- /dev/null +++ b/Sources/Helpers/MHKeychain.m @@ -0,0 +1,227 @@ +// +// MHKeychain.m +// MongoHub +// +// Created by Jérôme Lebel on 25/10/2013. +// + +#import "MHKeychain.h" +#import + +@implementation MHKeychain +// errSecNoAccessForItem + ++ (NSMutableDictionary *)queryForClass:(CFTypeRef)itemClass label:(NSString *)label protocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password +{ + NSMutableDictionary *query = [NSMutableDictionary dictionary]; + + [query setObject:itemClass forKey:(id)kSecClass]; + if (service) { + [query setObject:service forKey:kSecAttrService]; + } + if (description) { + [query setObject:description forKey:(id)kSecAttrDescription]; + } + if (account) { + [query setObject:account forKey:(id)kSecAttrAccount]; + } + if (protocol) { + [query setObject:protocol forKey:(id)kSecAttrProtocol]; + } + if (host) { + [query setObject:host forKey:(id)kSecAttrServer]; + } + if (port) { + [query setObject:[NSNumber numberWithUnsignedInteger:port] forKey:(id)kSecAttrPort]; + } + if (password) { + [query setObject:[password dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData]; + if (label) { + [query setObject:label forKey:(id)kSecAttrLabel]; + } else if (host && account) { + [query setObject:[NSString stringWithFormat:@"%@ (%@)", host, account] forKey:(id)kSecAttrLabel]; + } else if (host) { + [query setObject:host forKey:(id)kSecAttrLabel]; + } + } + + return query; +} +@end + +@implementation MHKeychain (InternetPassword) + ++ (BOOL)addInternetPasswordWithProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account password:(NSString *)password +{ + NSDictionary *query; + OSErr status = noErr; + + query = [self queryForClass:kSecClassInternetPassword label:nil protocol:protocol host:host port:port account:account service:nil description:nil password:password]; + status = SecItemAdd((CFDictionaryRef)query, NULL); + if (status != noErr) { + NSLog(@"Error adding internet password: %d for %@ %@ %@\n", (int)status, host, account, account); + } + + return status == noErr; +} + ++ (BOOL)updateInternetPasswordProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account password:(NSString *)password +{ + NSDictionary *update; + NSDictionary *query; + OSErr status; + + query = [self queryForClass:kSecClassInternetPassword label:nil protocol:protocol host:host port:port account:account service:nil description:nil password:nil]; + update = [self queryForClass:kSecClassInternetPassword label:nil protocol:protocol host:host port:port account:account service:nil description:nil password:password]; + status = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)update); + if (status != noErr) { + NSLog(@"Error updating internet password: %d for %@ %@ %@\n", (int)status, host, account, account); + } + + return status == noErr; +} + ++ (BOOL)addOrUpdateInternetPasswordWithProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account password:(NSString *)password +{ + BOOL result; + NSString *oldPassword; + + oldPassword = [self internetPasswordProtocol:protocol host:host port:port account:account]; + if (oldPassword == nil) { + result = [self addInternetPasswordWithProtocol:protocol host:host port:port account:account password:password]; + } else if (![oldPassword isEqualToString:password]){ + result = [self updateInternetPasswordProtocol:protocol host:host port:port account:account password:password]; + } else { + // the password already exists, and is the same. No need to update + result = YES; + } + return result; +} + ++ (NSString *)internetPasswordProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account +{ + NSMutableDictionary *query; + CFTypeRef result; + OSErr status; + NSString *stringToReturn; + + query = [self queryForClass:kSecClassInternetPassword label:nil protocol:protocol host:host port:port account:account service:nil description:nil password:nil]; + [query setObject:(id)kCFBooleanTrue forKey:kSecReturnData]; + [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; + + status = SecItemCopyMatching((CFDictionaryRef)query, &result); + if (status == errSecItemNotFound) { + stringToReturn = nil; + } else if (status != noErr) { + NSLog(@"Error searching internet password: %d for %@ %@ %@\n", (int)status, host, account, account); + stringToReturn = nil; + } else { + stringToReturn = [[[NSString alloc] initWithBytes:[(NSData *)result bytes] length:[(NSData *)result length] encoding:NSUTF8StringEncoding] autorelease]; + } + if (result) CFRelease(result); + return stringToReturn; +} + ++ (BOOL)deleteInternetPasswordProtocol:(CFTypeRef)protocol host:(NSString *)host port:(NSUInteger)port account:(NSString *)account +{ + NSDictionary *query; + OSErr status; + + query = [self queryForClass:kSecClassInternetPassword label:nil protocol:protocol host:host port:port account:account service:nil description:nil password:nil]; + + status = SecItemDelete((CFDictionaryRef)query); + if (status != noErr) { + NSLog(@"Error deleting internet password: %d for %@ %@ %@\n", (int)status, host, account, account); + } + + return status == noErr; +} + +@end + +@implementation MHKeychain (GenericPassword) + ++ (BOOL)addItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password +{ + NSMutableDictionary *query; + OSErr status = noErr; + + query = [self queryForClass:kSecClassGenericPassword label:label protocol:nil host:nil port:0 account:account service:service description:description password:password]; + status = SecItemAdd((CFDictionaryRef)query, NULL); + if (status != noErr) { + NSLog(@"Error adding item: %d for %@ %@ %@\n", (int)status, label, account, description); + } + + return status == noErr; +} + ++ (BOOL)updateItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password +{ + NSDictionary *update; + NSDictionary *query; + OSErr status; + + query = [self queryForClass:kSecClassGenericPassword label:label protocol:nil host:nil port:0 account:account service:service description:description password:nil]; + update = [self queryForClass:kSecClassGenericPassword label:label protocol:nil host:nil port:0 account:account service:service description:description password:password]; + status = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)update); + if (status != noErr) { + NSLog(@"Error updating item: %d for %@ %@ %@\n", (int)status, label, account, description); + } + + return status == noErr; +} + ++ (BOOL)addOrUpdateItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description password:(NSString *)password +{ + BOOL result; + NSString *oldPassword; + + oldPassword = [self passwordWithLabel:label account:account service:service description:description]; + if (oldPassword == nil) { + result = [self addItemWithLabel:label account:account service:service description:description password:password]; + } else if (![oldPassword isEqualToString:password]){ + result = [self updateItemWithLabel:label account:account service:service description:description password:password]; + } else { + // the password already exists, and is the same. No need to update + result = YES; + } + return result; +} + ++ (NSString *)passwordWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description +{ + NSMutableDictionary *query; + CFTypeRef result; + OSErr status; + + query = [self queryForClass:kSecClassGenericPassword label:label protocol:nil host:nil port:0 account:account service:service description:description password:nil]; + [query setObject:(id)kCFBooleanTrue forKey:kSecReturnData]; + [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; + + status = SecItemCopyMatching((CFDictionaryRef)query, &result); + if (status == errSecItemNotFound) { + return nil; + } else if (status != noErr) { + NSLog(@"Error searching item: %d for %@ %@ %@\n", (int)status, label, account, description); + return nil; + } else { + return [[[NSString alloc] initWithBytes:[(NSData *)result bytes] length:[(NSData *)result length] encoding:NSUTF8StringEncoding] autorelease]; + } +} + ++ (BOOL)deleteItemWithLabel:(NSString *)label account:(NSString *)account service:(NSString *)service description:(NSString *)description +{ + NSDictionary *query; + OSErr status; + + query = [self queryForClass:kSecClassGenericPassword label:label protocol:nil host:nil port:0 account:account service:service description:description password:nil]; + + status = SecItemDelete((CFDictionaryRef)query); + if (status != noErr) { + NSLog(@"Error deleting item: %d for %@ %@ %@\n", (int)status, label, account, description); + } + + return status == noErr; +} + +@end diff --git a/Sources/Helpers/MHTunnel.h b/Sources/Helpers/MHTunnel.h new file mode 100644 index 00000000..cdb4a255 --- /dev/null +++ b/Sources/Helpers/MHTunnel.h @@ -0,0 +1,86 @@ +// +// Tunnel.h +// MongoHub +// +// Created by Jerome Lebel on 07/08/2014. +// + +#import + +@class MHTunnel; + +#define MHTunnelDomain @"MHTunnelDomain" + +typedef enum { + MHNoTunnelError = 0, + MHConnectionRefusedTunnelError, + MHConnectionTimedOutTunnelError, + MHUnknownErrorTunnelError, + MHBadHostnameTunnelError, + MHHostKeyErrorTunnelError, + MHWrongPasswordTunnelError, + MHHostIdentificationChangedTunnelError, +} MHTunnelError; + +@protocol MHTunnelDelegate +@optional +- (void)tunnelDidStart:(MHTunnel *)tunnel; +- (void)tunnelDidConnect:(MHTunnel *)tunnel; +- (void)tunnelReconnecting:(MHTunnel *)tunnel; +- (void)tunnelDidStop:(MHTunnel *)tunnel; +- (void)tunnelDidFailToConnect:(MHTunnel *)tunnel withError:(NSError *)error; +- (void)tunnelLogMessage:(NSString *)message; +@end + +@interface MHTunnel : NSObject +{ + id _delegate; + + NSTask *_task; + NSFileHandle *_errorFileHandle; + MHTunnelError _tunnelError; + BOOL _running; + BOOL _connected; + BOOL _verbose; + + NSString *_name; + NSString *_host; + int _port; + NSString *_user; + NSString *_password; + NSString *_keyfile; + int _aliveInterval; + int _aliveCountMax; + BOOL _tcpKeepAlive; + BOOL _compression; + NSArray *_additionalArgs; + NSMutableArray *_portForwardings; +} + +@property (nonatomic, retain, readwrite) NSString* name; +@property (nonatomic, retain, readwrite) NSString* host; +@property (nonatomic, assign, readwrite) int port; +@property (nonatomic, retain, readwrite) NSString* user; +@property (nonatomic, retain, readwrite) NSString* password; +@property (nonatomic, retain, readwrite) NSString* keyfile; +@property (nonatomic, assign, readwrite) int aliveInterval; +@property (nonatomic, assign, readwrite) int aliveCountMax; +@property (nonatomic, assign, readwrite) BOOL tcpKeepAlive; +@property (nonatomic, assign, readwrite) BOOL compression; +@property (nonatomic, retain, readwrite) NSArray* additionalArgs; +@property (nonatomic, retain, readwrite) NSMutableArray* portForwardings; +@property (nonatomic, assign, readwrite) id delegate; +@property (nonatomic, assign, readonly, getter = isRunning) BOOL running; +@property (nonatomic, assign, readonly, getter = isConnected) BOOL connected; +@property (nonatomic, assign, readwrite) BOOL verbose; +@property (nonatomic, assign, readonly) MHTunnelError tunnelError; + ++ (unsigned short)findFreeTCPPort; ++ (NSString *)errorMessageForTunnelError:(MHTunnelError)error; + +- (void)start; +- (void)stop; + +- (void)addForwardingPortWithBindAddress:(NSString *)bindAddress bindPort:(unsigned short)bindPort hostAddress:(NSString *)hostAddress hostPort:(unsigned short)hostPort reverseForwarding:(BOOL)reverseForwarding; + +@end diff --git a/Sources/Helpers/MHTunnel.m b/Sources/Helpers/MHTunnel.m new file mode 100644 index 00000000..eba01f71 --- /dev/null +++ b/Sources/Helpers/MHTunnel.m @@ -0,0 +1,361 @@ +// +// MHTunnel.m +// MongoHub +// +// Created by Jerome Lebel on 07/08/2014. +// + +#import "MHTunnel.h" +#import +#import +#import +#import +#import +#import +#import + +#define SSH_PATH @"/usr/bin/ssh" + +@interface MHTunnel () +@property(nonatomic, assign, readwrite) MHTunnelError tunnelError; +@property(nonatomic, assign, readwrite, getter = isRunning) BOOL running; +@property(nonatomic, assign, readwrite, getter = isConnected) BOOL connected; +@end + +@implementation MHTunnel + +@synthesize name = _name; +@synthesize host = _host; +@synthesize port = _port; +@synthesize user = _user; +@synthesize password = _password; +@synthesize keyfile = _keyfile; +@synthesize aliveInterval = _aliveInterval; +@synthesize aliveCountMax = _aliveCountMax; +@synthesize tcpKeepAlive = _tcpKeepAlive; +@synthesize compression = _compression; +@synthesize additionalArgs = _additionalArgs; +@synthesize portForwardings = _portForwardings; +@synthesize delegate = _delegate; +@synthesize running = _running; +@synthesize tunnelError = _tunnelError; +@synthesize connected = _connected; +@synthesize verbose = _verbose; + +static BOOL testLocalPortAvailable(unsigned short port) +{ + CFSocketRef socket; + struct sockaddr_in addr4; + CFDataRef addressData; + BOOL freePort; + + CFSocketContext socketCtxt = {0, [MHTunnel class], (const void*(*)(const void*))&CFRetain, (void(*)(const void*))&CFRelease, (CFStringRef(*)(const void *))&CFCopyDescription }; + socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAcceptCallBack, (CFSocketCallBack)NULL, &socketCtxt); + + memset(&addr4, 0, sizeof(addr4)); + addr4.sin_len = sizeof(addr4); + addr4.sin_family = AF_INET; + addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr4.sin_port = htons(port); + addressData = CFDataCreateWithBytesNoCopy(NULL, (const UInt8*)&addr4, sizeof(addr4), kCFAllocatorNull); + freePort = CFSocketSetAddress(socket, addressData) == kCFSocketSuccess; + CFRelease(addressData); + + if (socket) { + CFSocketInvalidate(socket); + CFRelease(socket); + } + + return freePort; +} + ++ (unsigned short)findFreeTCPPort +{ + static unsigned short port = 40000; + BOOL freePort = NO; + + while (port != 0 && !freePort) { + port++; + freePort = testLocalPortAvailable(port); + } + return port; +} + ++ (NSString *)errorMessageForTunnelError:(MHTunnelError)error +{ + NSString *result = nil; + + switch (error) { + case MHNoTunnelError: + result = @"No error"; + break; + case MHConnectionRefusedTunnelError: + result = @"The ssh server refused the connection"; + break; + case MHBadHostnameTunnelError: + result = @"The host name cannot be resolved"; + break; + case MHConnectionTimedOutTunnelError: + result = @"The ssh server did not answer"; + break; + case MHUnknownErrorTunnelError: + result = @"Unknown error"; + break; + case MHHostKeyErrorTunnelError: + result = @"Host key verification failed"; + break; + case MHWrongPasswordTunnelError: + result = @"Wrong password"; + break; + case MHHostIdentificationChangedTunnelError: + result = @"REMOTE HOST IDENTIFICATION HAS CHANGED"; + } + return result; +} + +- (instancetype)init +{ + if (self = [super init]) { + self.portForwardings = [NSMutableArray array]; + } + + return (self); +} + +- (void)dealloc +{ + [self stop]; + self.name = nil; + self.host = nil; + self.user = nil; + self.password = nil; + self.keyfile = nil; + self.additionalArgs = nil; + self.portForwardings = nil; + [super dealloc]; +} + +- (void)_connected +{ + if (!_connected) { + self.connected = YES; + if ([self.delegate respondsToSelector:@selector(tunnelDidConnect:)]) [self.delegate tunnelDidConnect:self]; + } +} + +- (NSDictionary *)environment +{ + NSMutableDictionary *result; + + result = [[NSMutableDictionary alloc] init]; + if (self.password.length > 0) { + result[@"SSH_ASKPASS"] = [[NSBundle mainBundle] pathForResource:@"SSHCommand" ofType:@"sh"]; + result[@"SSHPASSWORD"] = self.password; + } + result[@"DISPLAY"] = @":0"; + if (NSProcessInfo.processInfo.environment[@"SSH_AUTH_SOCK"]) { + result[@"SSH_AUTH_SOCK"] = NSProcessInfo.processInfo.environment[@"SSH_AUTH_SOCK"]; + } + return [result autorelease]; +} + +- (void)_start +{ + NSPipe *errorPipe = [NSPipe pipe]; + + _task = [[NSTask alloc] init]; + _errorFileHandle = [[errorPipe fileHandleForReading] retain]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fileHandleDataAvailableNotification:) name:NSFileHandleDataAvailableNotification object:_errorFileHandle]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidTerminateNotification:) name:NSTaskDidTerminateNotification object:_task]; + [_errorFileHandle waitForDataInBackgroundAndNotify]; + [_task setLaunchPath:SSH_PATH]; + [_task setArguments:[self prepareSSHCommandArgs]]; + [_task setEnvironment:[self environment]]; + [_task setStandardError:errorPipe]; + + [self logMessage:[NSString stringWithFormat:@"%@ %@", _task.launchPath, [_task.arguments componentsJoinedByString:@" "]]]; + + [_task launch]; +} + +- (void)start +{ + if (!self.isRunning) { + self.tunnelError = MHNoTunnelError; + self.running = YES; + + [self _start]; + if ([self.delegate respondsToSelector:@selector(tunnelDidStart:)]) [self.delegate tunnelDidStart:self]; + } +} + + + +- (void)_releaseFileHandleAndTask +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleDataAvailableNotification object:_errorFileHandle]; + [_errorFileHandle release]; + _errorFileHandle = nil; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSTaskDidTerminateNotification object:_task]; + [_task terminate]; + [_task release]; + _task = nil; + if (self.connected) { + self.connected = NO; + if ([self.delegate respondsToSelector:@selector(tunnelDidStop:)]) [self.delegate tunnelDidStop:self]; + } +} + +- (void)stop +{ + if (self.running) { + self.running = NO; + [self _releaseFileHandleAndTask]; + } +} + +- (void)fileHandleDataAvailableNotification:(NSNotification *)notification +{ + if ([notification.name isEqualToString:NSFileHandleDataAvailableNotification] && notification.object == _errorFileHandle) { + [self readStatusFromErrorPipe]; + [_errorFileHandle waitForDataInBackgroundAndNotify]; + } +} + +- (void)taskDidTerminateNotification:(NSNotification *)notification +{ + [self readStatusFromErrorPipe]; + if (self.running) { + [self _releaseFileHandleAndTask]; + [self _start]; + if ([self.delegate respondsToSelector:@selector(tunnelReconnecting:)]) [self.delegate tunnelDidStop:self]; + } else { + self.connected = NO; + if ([self.delegate respondsToSelector:@selector(tunnelDidStop:)]) [self.delegate tunnelDidStop:self]; + } +} + +- (void)readStatusFromErrorPipe +{ + if (_running && self.tunnelError == MHNoTunnelError) { + NSString *string = [[[NSString alloc] initWithData:_errorFileHandle.availableData encoding:NSASCIIStringEncoding] autorelease]; + + [self logMessage:string]; + if ([string rangeOfString:@"Entering interactive session"].location != NSNotFound) { + [self _connected]; + return; + } else if ([string rangeOfString:@"Host key verification failed"].location != NSNotFound) { + self.tunnelError = MHHostKeyErrorTunnelError; + } else if ([string rangeOfString:@"Connection refused"].location != NSNotFound) { + self.tunnelError = MHConnectionRefusedTunnelError; + } else if ([string rangeOfString:@"Operation timed out"].location != NSNotFound) { + self.tunnelError = MHConnectionTimedOutTunnelError; + } else if ([string rangeOfString:@"Could not resolve hostname"].location != NSNotFound) { + self.tunnelError = MHBadHostnameTunnelError; + } else if ([string rangeOfString:@"Permission denied"].location != NSNotFound) { + self.tunnelError = MHWrongPasswordTunnelError; + } else if ([string rangeOfString:@"REMOTE HOST IDENTIFICATION HAS CHANGED"].location != NSNotFound) { + self.tunnelError = MHHostIdentificationChangedTunnelError; + } + + if (self.tunnelError != MHNoTunnelError) { + if ([self.delegate respondsToSelector:@selector(tunnelDidFailToConnect:withError:)]) { + [self.delegate tunnelDidFailToConnect:self withError:[NSError errorWithDomain:MHTunnelDomain code:self.tunnelError userInfo:@{ NSLocalizedDescriptionKey: [self.class errorMessageForTunnelError:self.tunnelError] }]]; + } + } + } +} + +- (NSArray *)prepareSSHCommandArgs +{ + NSMutableArray *result; + + result = [NSMutableArray array]; + for (NSString *pf in self.portForwardings) { + NSArray* pfa = [pf componentsSeparatedByString:@":"]; + + [result addObject:[NSString stringWithFormat:@"-%@", [pfa objectAtIndex:0]]]; + if (pfa.count == 4) { + [result addObject:[NSString stringWithFormat:@"%@:%@:%@", [pfa objectAtIndex:1], [pfa objectAtIndex:2], [pfa objectAtIndex:3]]]; + } else if ([[pfa objectAtIndex:1] length] == 0) { + [result addObject:[NSString stringWithFormat:@"%@:%@:%@", [pfa objectAtIndex:2], [pfa objectAtIndex:3], [pfa objectAtIndex:4]]]; + } else { + [result addObject:[NSString stringWithFormat:@"%@:%@:%@:%@", [pfa objectAtIndex:1], [pfa objectAtIndex:2], [pfa objectAtIndex:3], [pfa objectAtIndex:4]]]; + } + } + + [result addObject:@"-v"]; + [result addObject:@"-N"]; + [result addObject:@"-o"]; + [result addObject:@"ConnectTimeout=28"]; + [result addObject:@"-o"]; + [result addObject:@"NumberOfPasswordPrompts=1"]; + [result addObject:@"-o"]; + [result addObject:@"ConnectionAttempts=1"]; + [result addObject:@"-o"]; + [result addObject:@"ExitOnForwardFailure=yes"]; + [result addObject:@"-o"]; + [result addObject:@"StrictHostKeyChecking=no"]; + if (self.additionalArgs) { + [result addObjectsFromArray:self.additionalArgs]; + } + if (_aliveInterval > 0) { + [result addObject:@"-o"]; + [result addObject:[NSString stringWithFormat:@"ServerAliveInterval=%d",_aliveInterval]]; + } + if (_aliveCountMax > 0) { + [result addObject:@"-o"]; + [result addObject:[NSString stringWithFormat:@"ServerAliveCountMax=%d",_aliveCountMax]]; + } + if (self.tcpKeepAlive) { + [result addObject:@"-o"]; + [result addObject:@"TCPKeepAlive=yes"]; + } + if (self.compression) { + [result addObject:@"-C"]; + } + if (_port > 0) { + [result addObject:@"-p"]; + [result addObject:[NSString stringWithFormat:@"%d", _port]]; + } + if (_user.length > 0) { + [result addObject:@"-l"]; + [result addObject:_user]; + } + [result addObject:[NSString stringWithFormat:@"%@", _host]]; + if (![_keyfile isEqualToString:@""]) { + [result addObject:@"-i"]; + [result addObject:_keyfile]; + } + + return result; +} + +- (void)addForwardingPortWithBindAddress:(NSString *)bindAddress bindPort:(unsigned short)bindPort hostAddress:(NSString *)hostAddress hostPort:(unsigned short)hostPort reverseForwarding:(BOOL)reverseForwarding +{ + NSString *forwardPort; + + forwardPort = [[NSString alloc] initWithFormat:@"%@%@%@:%d:%@:%d", reverseForwarding?@"R":@"L", bindAddress?bindAddress:@"", bindAddress?@":":@"", (int)bindPort, hostAddress, (int)hostPort]; + [self.portForwardings addObject:forwardPort]; + [forwardPort release]; +} + +- (void)logMessage:(NSString *)message +{ + NSArray *lines; + + lines = [message componentsSeparatedByString:@"\n"]; + for (NSString *line in lines) { + line = [line stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]; + if (line.length > 0) { + if (self.verbose) { + NSLog(@"%@", line); + } + if ([self.delegate respondsToSelector:@selector(tunnelLogMessage:)]) { + [self.delegate tunnelLogMessage:line]; + } + } + } +} + +@end diff --git a/Sources/Helpers/MODHelper.h b/Sources/Helpers/MODHelper.h new file mode 100644 index 00000000..6b14cc2c --- /dev/null +++ b/Sources/Helpers/MODHelper.h @@ -0,0 +1,18 @@ +// +// MODHelper.h +// MongoHub +// +// Created by Jérôme Lebel on 20/09/2011. +// + +#import +#import + +@class MODSortedDictionary; + +@interface MODHelper : NSObject + ++ (NSArray *)convertForOutlineWithObjects:(NSArray *)mongoObjects bsonData:(NSArray *)allData jsonKeySortOrder:(MODJsonKeySortOrder)jsonKeySortOrder; ++ (NSArray *)convertForOutlineWithObject:(MODSortedDictionary *)mongoObject jsonKeySortOrder:(MODJsonKeySortOrder)jsonKeySortOrder; + +@end diff --git a/Sources/Helpers/MODHelper.m b/Sources/Helpers/MODHelper.m new file mode 100644 index 00000000..b410c011 --- /dev/null +++ b/Sources/Helpers/MODHelper.m @@ -0,0 +1,202 @@ +// +// MODHelper.m +// MongoHub +// +// Created by Jérôme Lebel on 20/09/2011. +// + +#import "MODHelper.h" +#import +#import + +@interface MODHelper() ++ (NSMutableDictionary *)convertForOutlineWithValue:(id)dataValue dataKey:(NSString *)dataKey jsonKeySortOrder:(MODJsonKeySortOrder)jsonKeySortOrder; +@end + +@implementation MODHelper + ++ (NSArray *)convertForOutlineWithObjects:(NSArray *)mongoObjects bsonData:(NSArray *)allData jsonKeySortOrder:(MODJsonKeySortOrder)jsonKeySortOrder +{ + NSMutableArray *result; + NSUInteger index = 0; + + result = [NSMutableArray arrayWithCapacity:[mongoObjects count]]; + for (MODSortedDictionary *object in mongoObjects) { + id idValue = nil; + NSString *idValueName = nil; + NSMutableDictionary *dict = nil; + + idValue = [object objectForKey:@"_id"]; + idValueName = @"_id"; + if (!idValue) { + idValue = [object objectForKey:@"name"]; + idValueName = @"name"; + } + if (!idValue && [object count] > 0) { + idValueName = [[object sortedKeys] objectAtIndex:0]; + idValue = [object objectForKey:idValueName]; + } + if (idValue) { + dict = [self convertForOutlineWithValue:idValue dataKey:idValueName jsonKeySortOrder:jsonKeySortOrder]; + } + if (dict == nil) { + dict = [NSMutableDictionary dictionary]; + } + [dict setObject:[self convertForOutlineWithObject:object jsonKeySortOrder:jsonKeySortOrder] forKey:@"child" ]; + [dict setObject:[MODClient convertObjectToJson:object pretty:YES strictJson:NO jsonKeySortOrder:MODJsonKeySortOrderDocument] forKey:@"beautified"]; + [dict setObject:object forKey:@"objectvalue"]; + if (allData) { + [dict setObject:[allData objectAtIndex:index] forKey:@"bsondata"]; + } + [result addObject:dict]; + index++; + } + return result; +} + ++ (NSArray *)convertForOutlineWithObject:(MODSortedDictionary *)mongoObject jsonKeySortOrder:(MODJsonKeySortOrder)jsonKeySortOrder +{ + NSMutableArray *result; + NSArray *keys; + + keys = [MODClient sortKeys:mongoObject.sortedKeys withJsonKeySortOrder:jsonKeySortOrder]; + result = [NSMutableArray array]; + for (NSString *dataKey in keys) { + NSMutableDictionary *value; + + value = [self convertForOutlineWithValue:[mongoObject objectForKey:dataKey] dataKey:dataKey jsonKeySortOrder:jsonKeySortOrder]; + if (value) { + [result addObject:value]; + } + } + return result; +} + ++ (NSMutableDictionary *)convertForOutlineWithValue:(id)dataValue dataKey:(NSString *)dataKey jsonKeySortOrder:(MODJsonKeySortOrder)jsonKeySortOrder +{ + NSArray *child = nil; + NSString *value = @""; + NSString *type = @""; + NSMutableDictionary *result = nil; + + if ([dataValue isKindOfClass:[NSNumber class]]) { + if (strcmp([dataValue objCType], @encode(double)) == 0 || strcmp([dataValue objCType], @encode(float)) == 0) { + type = @"Double"; + if ([dataValue doubleValue] == INFINITY) { + value = @"Number.POSITIVE_INFINITY"; + } else if ([dataValue doubleValue] == -INFINITY) { + value = @"Number.NEGATIVE_INFINITY"; + } else if (isnan([dataValue doubleValue])) { + value = @"Number.NaN"; + } else { + value = [dataValue description]; + } + } else if (strcmp([dataValue objCType], @encode(int)) == 0) { + type = @"Integer"; + value = [dataValue description]; + } else if (strcmp([dataValue objCType], @encode(long long)) == 0) { + type = @"Long Integer"; + value = [dataValue description]; + } else if (strcmp([dataValue objCType], @encode(BOOL)) == 0) { + type = @"Boolean"; + if ([dataValue boolValue]) { + value = @"true"; + } else { + value = @"false"; + } + } else { + NSLog(@"%s %@ %@", [dataValue objCType], dataValue, dataKey); + } + } else if ([dataValue isKindOfClass:[NSDate class]]) { + type = @"Date"; + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ssZZZ"]; + value = [formatter stringFromDate:dataValue]; + } else if ([dataValue isKindOfClass:[MODObjectId class]]) { + type = @"Object id"; + value = [dataValue jsonValueWithPretty:YES strictJSON:NO]; + } else if ([dataValue isKindOfClass:[MODRegex class]]) { + type = @"Regex"; + value = [dataValue jsonValueWithPretty:YES strictJSON:NO]; + } else if ([dataValue isKindOfClass:[MODTimestamp class]]) { + type = @"Timestamp"; + value = [dataValue jsonValueWithPretty:YES strictJSON:NO]; + } else if ([dataValue isKindOfClass:[MODBinary class]]) { + type = @"Binary"; + value = [dataValue jsonValueWithPretty:YES strictJSON:NO]; + } else if ([dataValue isKindOfClass:[MODDBPointer class]]) { + type = @"DBPointer deprecated"; + value = [dataValue jsonValueWithPretty:YES strictJSON:NO]; + } else if ([dataValue isKindOfClass:[NSString class]]) { + type = @"String"; + value = dataValue; + } else if ([dataValue isKindOfClass:[NSNull class]]) { + type = @"NULL"; + value = @"NULL"; + } else if ([dataValue isKindOfClass:[MODSortedDictionary class]]) { + NSUInteger count = [dataValue count]; + + if ([dataValue objectForKey:@"$ref"]) { + if ([dataValue objectForKey:@"$db"]) { + type = [NSString stringWithFormat:@"Ref(%@.%@)", [dataValue objectForKey:@"$db"], [dataValue objectForKey:@"$ref"]]; + } else { + type = [NSString stringWithFormat:@"Ref(%@)", [dataValue objectForKey:@"$ref"]]; + } + } else if (count == 0) { + type = NSLocalizedString(@"Object, no item", @"about an dictionary"); + } else if (count == 1) { + type = NSLocalizedString(@"Object, 1 item", @"about an dictionary"); + } else { + type = [NSString stringWithFormat:NSLocalizedString(@"Object, %d items", @"about an dictionary"), count]; + } + child = [self convertForOutlineWithObject:dataValue jsonKeySortOrder:jsonKeySortOrder]; + } else if ([dataValue isKindOfClass:[MODSymbol class]]) { + type = @"Symbol"; + value = [dataValue value]; + } else if ([dataValue isKindOfClass:[NSArray class]]) { + NSUInteger ii, count = [dataValue count]; + + if (count == 0) { + type = NSLocalizedString(@"Array, no item", @"about an array"); + } else if (count == 1) { + type = NSLocalizedString(@"Array, 1 item", @"about an array"); + } else { + type = [NSString stringWithFormat:NSLocalizedString(@"Array, %d items", @"about an array"), count]; + } + child = [NSMutableArray arrayWithCapacity:[dataValue count]]; + for (ii = 0; ii < count; ii++) { + NSString *arrayDataKey; + id arrayDataValue; + + arrayDataValue = [dataValue objectAtIndex:ii]; + arrayDataKey = [[NSString alloc] initWithFormat:@"%ld", (long)ii]; + [(NSMutableArray *)child addObject:[self convertForOutlineWithValue:arrayDataValue dataKey:arrayDataKey jsonKeySortOrder:jsonKeySortOrder]]; + [arrayDataKey release]; + } + } else if ([dataValue isKindOfClass:[MODUndefined class]]) { + type = @"Undefined"; + value = [dataValue jsonValueWithPretty:YES strictJSON:NO]; + } else if ([dataValue isKindOfClass:[MODFunction class]]) { + type = @"Function"; + value = [dataValue function]; + } else if ([dataValue isKindOfClass:[MODScopeFunction class]]) { + type = @"ScopeFunction"; + value = [dataValue function]; + } else { + NSLog(@"type %@ value %@", [dataValue class], dataValue); + NSAssert(NO, @"unknown type %@ value %@", [dataValue class], dataValue); + } + if (value) { + result = [NSMutableDictionary dictionaryWithCapacity:4]; + [result setObject:value forKey:@"value"]; + [result setObject:dataKey forKey:@"name"]; + [result setObject:type forKey:@"type"]; + [result setObject:dataValue forKey:@"objectvalueid"]; + if (child) { + [result setValue:child forKey:@"child"]; + } + } + return result; +} + +@end diff --git a/Sources/Helpers/NSDictionary+MongoHub.h b/Sources/Helpers/NSDictionary+MongoHub.h new file mode 100644 index 00000000..020e04c0 --- /dev/null +++ b/Sources/Helpers/NSDictionary+MongoHub.h @@ -0,0 +1,17 @@ +// +// NSDictionary+MongoHub.h +// MongoHub +// +// Created by Jérôme Lebel on 20/08/2014. +// +// + +#import + +@interface NSDictionary (MongoHub) + ++ (instancetype)mh_dictionaryFromURLParameters:(NSString *)parameters; + +- (NSDictionary *)mh_setKeysToLowerCase; + +@end diff --git a/Sources/Helpers/NSDictionary+MongoHub.m b/Sources/Helpers/NSDictionary+MongoHub.m new file mode 100644 index 00000000..c88bf1df --- /dev/null +++ b/Sources/Helpers/NSDictionary+MongoHub.m @@ -0,0 +1,41 @@ +// +// NSDictionary+MongoHub.h +// MongoHub +// +// Created by Jérôme Lebel on 20/08/2014. +// +// + +#import "NSDictionary+MongoHub.h" + +@implementation NSDictionary (MongoHub) + ++ (instancetype)mh_dictionaryFromURLParameters:(NSString *)parameters +{ + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + + for (NSString *keyValue in [parameters componentsSeparatedByString:@"&"]) { + NSArray *components = [keyValue componentsSeparatedByString:@"="]; + + if (components.count == 1) { + [result setObject:@"" forKey:[components objectAtIndex:0]]; + } else if (components.count == 2) { + [result setObject:[components objectAtIndex:1] forKey:[components objectAtIndex:0]]; + } + } + return result; +} + +- (NSDictionary *)mh_setKeysToLowerCase +{ + NSMutableDictionary *result; + + result = [NSMutableDictionary dictionary]; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + *stop = NO; + result[[key lowercaseString]] = obj; + }]; + return result; +} + +@end diff --git a/NSScanner+SkipUpToCharset.h b/Sources/Helpers/NSScanner+SkipUpToCharset.h similarity index 100% rename from NSScanner+SkipUpToCharset.h rename to Sources/Helpers/NSScanner+SkipUpToCharset.h diff --git a/NSScanner+SkipUpToCharset.m b/Sources/Helpers/NSScanner+SkipUpToCharset.m similarity index 93% rename from NSScanner+SkipUpToCharset.m rename to Sources/Helpers/NSScanner+SkipUpToCharset.m index c66e966e..fa3d59c2 100644 --- a/NSScanner+SkipUpToCharset.m +++ b/Sources/Helpers/NSScanner+SkipUpToCharset.m @@ -14,7 +14,7 @@ @implementation NSScanner (UKSkipUpToCharset) -(BOOL) skipUpToCharactersFromSet:(NSCharacterSet*)set { NSString* vString = [self string]; - int x = [self scanLocation]; + NSUInteger x = [self scanLocation]; while( x < [vString length] ) { diff --git a/Sources/Helpers/NSString+MongoHub.h b/Sources/Helpers/NSString+MongoHub.h new file mode 100644 index 00000000..2f6f7df1 --- /dev/null +++ b/Sources/Helpers/NSString+MongoHub.h @@ -0,0 +1,16 @@ +// +// NSString+MongoHub.h +// MongoHub +// +// Created by Jerome on 07/08/2014. +// + +#import + + +@interface NSString (MongoHub) + +- (NSString *)mh_stringByEscapingURL; +- (NSString *)mh_stringByTrimmingWhitespace; + +@end diff --git a/Sources/Helpers/NSString+MongoHub.m b/Sources/Helpers/NSString+MongoHub.m new file mode 100644 index 00000000..6bd2b5ae --- /dev/null +++ b/Sources/Helpers/NSString+MongoHub.m @@ -0,0 +1,23 @@ +// +// NSString+MongoHub.h +// MongoHub +// +// Created by Jerome on 07/08/2014. +// + +#import "NSString+MongoHub.h" + + +@implementation NSString (MongoHub) + +- (NSString*)mh_stringByEscapingURL +{ + return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8)); +} + +- (NSString *)mh_stringByTrimmingWhitespace +{ + return [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; +} + +@end diff --git a/Sources/Helpers/NSTextView+MongoHub.h b/Sources/Helpers/NSTextView+MongoHub.h new file mode 100644 index 00000000..d8e29f56 --- /dev/null +++ b/Sources/Helpers/NSTextView+MongoHub.h @@ -0,0 +1,16 @@ +// +// NSTextView+MongoHub.h +// MongoHub +// +// Created by Jérôme Lebel on 09/06/2014. +// +// + +#import + +@interface NSTextView (MongoHub) + +// this method setup the text view to have a good font and not automatic correction +- (void)mh_jsonSetup; + +@end diff --git a/Sources/Helpers/NSTextView+MongoHub.m b/Sources/Helpers/NSTextView+MongoHub.m new file mode 100644 index 00000000..e728b958 --- /dev/null +++ b/Sources/Helpers/NSTextView+MongoHub.m @@ -0,0 +1,25 @@ +// +// NSTextView+MongoHub.m +// MongoHub +// +// Created by Jérôme Lebel on 09/06/2014. +// +// + +#import "NSTextView+MongoHub.h" + +@implementation NSTextView (MongoHub) + +- (void)mh_jsonSetup +{ + // Disable spell checking and substitutions. + // When dealing with JavaScript objects, switching regular double quotes into smart quotes isn't helpful. + [self setAutomaticDashSubstitutionEnabled:NO]; + [self setAutomaticDataDetectionEnabled:NO]; + [self setAutomaticLinkDetectionEnabled:NO]; + [self setAutomaticQuoteSubstitutionEnabled:NO]; + [self setAutomaticSpellingCorrectionEnabled:NO]; + [self setAutomaticTextReplacementEnabled:NO]; +} + +@end diff --git a/Sources/Helpers/NSViewHelpers.h b/Sources/Helpers/NSViewHelpers.h new file mode 100644 index 00000000..6bf61f74 --- /dev/null +++ b/Sources/Helpers/NSViewHelpers.h @@ -0,0 +1,17 @@ +// +// NSViewHelpers.h +// MongoHub +// +// Created by Jérôme Lebel on 11/07/2012. +// + +#import + +@interface NSViewHelpers : NSObject +{ +} + ++ (void)setColor:(NSColor *)destinationColor fromColor:(NSColor *)originColor toTarget:(id)target withSelector:(SEL)selector delay:(NSInteger)delay; ++ (void)cancelColorForTarget:(id)target selector:(SEL)selector; + +@end diff --git a/Sources/Helpers/NSViewHelpers.m b/Sources/Helpers/NSViewHelpers.m new file mode 100644 index 00000000..a1b7aa15 --- /dev/null +++ b/Sources/Helpers/NSViewHelpers.m @@ -0,0 +1,93 @@ +// +// NSViewHelpers.m +// MongoHub +// +// Created by Jérôme Lebel on 11/07/2012. +// + +#import "NSViewHelpers.h" + +#define TIME_STEP 0.1 + +static NSMutableDictionary *colorInfo = nil; + +@implementation NSViewHelpers + +static NSString *keyForTargetAndSelector(id target, NSString *selector) +{ + return [NSString stringWithFormat:@"%p%@", target, selector]; +} + ++ (void)updateColor:(NSMutableDictionary *)info +{ + NSColor *newColor; + BOOL shouldContinue = NO; + + shouldContinue = [[info objectForKey:@"datedestination"] timeIntervalSinceNow] > 0; + if (![[info objectForKey:@"cancel"] boolValue]) { + if (shouldContinue) { + NSColor *currentColor; + + currentColor = [info objectForKey:@"currentcolor"]; + [self performSelector:@selector(updateColor:) withObject:info afterDelay:TIME_STEP]; + + CGFloat currentColorComponents[4]; + [currentColor getComponents:currentColorComponents]; + + newColor = [NSColor colorWithDeviceRed:currentColorComponents[0] + [[info objectForKey:@"deltared"] floatValue] green:currentColorComponents[1] + [[info objectForKey:@"deltagreen"] floatValue] blue:currentColorComponents[2] + [[info objectForKey:@"deltablue"] floatValue] alpha:currentColorComponents[3] + [[info objectForKey:@"deltaalpha"] floatValue]]; + [info setObject:newColor forKey:@"currentcolor"]; + } else { + newColor = [info objectForKey:@"destinationcolor"]; + [colorInfo removeObjectForKey:keyForTargetAndSelector([info objectForKey:@"target"], [info objectForKey:@"selector"])]; + } + [[info objectForKey:@"target"] performSelector:NSSelectorFromString([info objectForKey:@"selector"]) withObject:newColor]; + } +} + ++ (void)cancelColorForTarget:(id)target selector:(SEL)selector +{ + NSMutableDictionary *info; + NSString *infoKey; + + infoKey = keyForTargetAndSelector(target, NSStringFromSelector(selector)); + info = [colorInfo objectForKey:infoKey]; + if (info) { + [info setObject:[NSNumber numberWithBool:YES] forKey:@"cancel"]; + [target performSelector:selector withObject:[info objectForKey:@"destinationcolor"]]; + [colorInfo removeObjectForKey:infoKey]; + } +} + ++ (void)setColor:(NSColor *)destinationColor fromColor:(NSColor *)originColor toTarget:(id)target withSelector:(SEL)selector delay:(NSInteger)delay +{ + NSDictionary *info; + NSNumber *red, *green, *blue, *alpha; + NSString *stringSelector; + + if (!colorInfo) { + colorInfo = [[NSMutableDictionary alloc] init]; + } + stringSelector = NSStringFromSelector(selector); + destinationColor = [destinationColor colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]]; + originColor = [originColor colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]]; + + CGFloat destComponents[4]; + CGFloat originComponents[4]; + [destinationColor getComponents:destComponents]; + [originColor getComponents:originComponents]; + + red = [[NSNumber alloc] initWithFloat:(destComponents[0] - originComponents[0]) * TIME_STEP / delay]; + green = [[NSNumber alloc] initWithFloat:(destComponents[1] - originComponents[1]) * TIME_STEP / delay]; + blue = [[NSNumber alloc] initWithFloat:(destComponents[2] - originComponents[2]) * TIME_STEP / delay]; + alpha = [[NSNumber alloc] initWithFloat:(destComponents[3] - originComponents[3]) * TIME_STEP / delay]; + info = [[NSMutableDictionary alloc] initWithObjectsAndKeys:destinationColor, @"destinationcolor", originColor, @"currentcolor", red, @"deltared", blue, @"deltablue", green, @"deltagreen", alpha, @"deltaalpha", target, @"target", stringSelector, @"selector", [NSDate dateWithTimeIntervalSinceNow:delay], @"datedestination", nil]; + [self performSelector:@selector(updateColor:) withObject:info afterDelay:TIME_STEP]; + [colorInfo setObject:info forKey:keyForTargetAndSelector(target, stringSelector)]; + [info release]; + [red release]; + [green release]; + [blue release]; + [alpha release]; +} + +@end diff --git a/Sources/JSONEditor/MHJsonColorManager.h b/Sources/JSONEditor/MHJsonColorManager.h new file mode 100644 index 00000000..bfd456d0 --- /dev/null +++ b/Sources/JSONEditor/MHJsonColorManager.h @@ -0,0 +1,26 @@ +// +// MHJsonColorManager.h +// MongoHub +// +// Created by Jérôme Lebel on 29/08/2014. +// +// + +#import + +#define MHJsonColorManagerHasBeenUpdatedNotification @"MHJsonColorManagerHasBeenUpdatedNotification" + +@interface MHJsonColorManager : NSObject +{ + NSMutableDictionary *_values; +} + +@property (nonatomic, readonly, strong) NSDictionary *values; + ++ (instancetype)sharedManager; + +- (void)resetValues; +- (void)valueUpdated; +- (void)save; + +@end diff --git a/Sources/JSONEditor/MHJsonColorManager.m b/Sources/JSONEditor/MHJsonColorManager.m new file mode 100644 index 00000000..47cc9103 --- /dev/null +++ b/Sources/JSONEditor/MHJsonColorManager.m @@ -0,0 +1,223 @@ +// +// MHJsonColorManager.m +// MongoHub +// +// Created by Jérôme Lebel on 29/08/2014. +// +// + +#import "MHJsonColorManager.h" + +#define MHJsonColorManagerUserDefaultKey @"MHJsonColorManagerUserDefaultKey" +static MHJsonColorManager *jsonColorManager = nil; + +@interface MHJsonColorManager () +@property (nonatomic, readwrite, strong) NSMutableDictionary *values; +@end + +@interface MHJsonColorManager (Convert) ++ (id)valuesFromPlistValues:(id)plistValues; ++ (id)plistValuesFromValues:(id)values; +@end + +@implementation MHJsonColorManager + +@synthesize values = _values; + ++ (instancetype)sharedManager +{ + if (!jsonColorManager) { + jsonColorManager = [[MHJsonColorManager alloc] init]; + } + return jsonColorManager; +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + [self loadPlist]; + } + return self; +} + +- (void)loadPlist +{ + NSDictionary *rowValues; + + rowValues = [NSDictionary dictionaryWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"SyntaxDefinition" ofType:@"plist"]]; + self.values = [self.class valuesFromPlistValues:rowValues]; + rowValues = [[NSUserDefaults standardUserDefaults] objectForKey:MHJsonColorManagerUserDefaultKey]; + if (rowValues) { + NSDictionary *userValues; + + userValues = [self.class valuesFromPlistValues:rowValues]; + for (NSString *category in @[ @"Components", @"TextField"]) { + for (NSString *key in [self.values[category] allKeys]) { + if (userValues[category][key]) { + self.values[category][key] = userValues[category][key]; + } + } + } + } +} + +- (void)resetValues +{ + NSDictionary *rowValues; + + rowValues = [NSDictionary dictionaryWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"SyntaxDefinition" ofType:@"plist"]]; + self.values = [self.class valuesFromPlistValues:rowValues]; + [self valueUpdated]; +} + +- (void)valueUpdated +{ + NSDictionary *rowValues; + + [[NSNotificationCenter defaultCenter] postNotificationName:MHJsonColorManagerHasBeenUpdatedNotification object:self]; + rowValues = [self.class plistValuesFromValues:self.values]; + [[NSUserDefaults standardUserDefaults] setObject:rowValues forKey:MHJsonColorManagerUserDefaultKey]; +} + +- (void)save +{ + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end + +@implementation MHJsonColorManager (Convert) + ++ (id)valuesFromPlistValues:(id)plistValues +{ + if ([plistValues isKindOfClass:NSDictionary.class]) { + return [self dictionaryValueFromPlistValue:plistValues]; + } else if ([plistValues isKindOfClass:NSArray.class]) { + return [self arrayValueFromPlistValue:plistValues]; + } else { + return plistValues; + } +} + ++ (NSMutableDictionary *)dictionaryValueFromPlistValue:(NSDictionary *)plistValue +{ + NSMutableDictionary *result; + + result = [NSMutableDictionary dictionary]; + for (NSString *key in plistValue.allKeys) { + id value; + + if ([key isEqualToString:@"Color"]) { + value = [self colorValueFromPlistValue:plistValue[key]]; + } else if ([key isEqualToString:@"Font"]) { + value = [self fontValueFromPlistValue:plistValue[key]]; + } else { + value = [self valuesFromPlistValues:plistValue[key]]; + } + result[key] = value; + } + return result; +} + ++ (NSMutableArray *)arrayValueFromPlistValue:(NSArray *)plistValue +{ + NSMutableArray *result; + + result = [NSMutableArray array]; + for (id value in plistValue) { + [result addObject:[self valuesFromPlistValues:value]]; + } + return result; +} + ++ (NSColor *)colorValueFromPlistValue:(NSArray *)plistValue +{ + NSColor *result; + CGFloat red = 0, green = 0, blue = 0, alpha = 1; + + if (plistValue.count >= 3) { + red = [plistValue[0] floatValue]; + green = [plistValue[1] floatValue]; + blue = [plistValue[2] floatValue]; + } else { + NSLog(@"problem"); + } + if (plistValue.count >= 4) { + alpha = [plistValue[3] floatValue]; + } + result = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha]; + return result; +} + ++ (NSFont *)fontValueFromPlistValue:(NSDictionary *)plistValue +{ + return [NSFont fontWithName:plistValue[@"name"] size:[plistValue[@"size"] floatValue]]; +} + ++ (id)plistValuesFromValues:(id)values +{ + if ([values isKindOfClass:NSDictionary.class]) { + return [self plistDictionaryFromValue:values]; + } else if ([values isKindOfClass:NSArray.class]) { + return [self plistArrayFromValue:values]; + } else { + return values; + } +} + ++ (NSMutableDictionary *)plistDictionaryFromValue:(NSDictionary *)plistValue +{ + NSMutableDictionary *result; + + result = [NSMutableDictionary dictionary]; + for (NSString *key in plistValue.allKeys) { + id value; + + if ([key isEqualToString:@"Color"]) { + value = [self arrayValueFromColorValue:plistValue[key]]; + } else if ([key isEqualToString:@"Font"]) { + value = [self dictionaryValueFromFontValue:plistValue[key]]; + } else { + value = [self plistValuesFromValues:plistValue[key]]; + } + result[key] = value; + } + return result; +} + ++ (NSMutableArray *)plistArrayFromValue:(NSArray *)plistValue +{ + NSMutableArray *result; + + result = [NSMutableArray array]; + for (id value in plistValue) { + [result addObject:[self plistValuesFromValues:value]]; + } + return result; +} + ++ (NSArray *)arrayValueFromColorValue:(NSColor *)color +{ + NSMutableArray *result; + + color = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + result = [NSMutableArray array]; + [result addObject:[NSNumber numberWithFloat:color.redComponent]]; + [result addObject:[NSNumber numberWithFloat:color.greenComponent]]; + [result addObject:[NSNumber numberWithFloat:color.blueComponent]]; + [result addObject:[NSNumber numberWithFloat:color.alphaComponent]]; + return result; +} + ++ (NSDictionary *)dictionaryValueFromFontValue:(NSFont *)font +{ + NSMutableDictionary *result; + + result = [NSMutableDictionary dictionary]; + [result setObject:font.fontName forKey:@"name"]; + [result setObject:[NSNumber numberWithFloat:font.pointSize] forKey:@"size"]; + return result; +} + +@end \ No newline at end of file diff --git a/Sources/JSONEditor/MHJsonWindowController.h b/Sources/JSONEditor/MHJsonWindowController.h new file mode 100644 index 00000000..33ceea45 --- /dev/null +++ b/Sources/JSONEditor/MHJsonWindowController.h @@ -0,0 +1,45 @@ +// +// MHJsonWindowController.h +// MongoHub +// +// Created by Syd on 10-12-27. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import +#import +#import "UKSyntaxColoredTextViewController.h" +#import "MHPreferenceWindowController.h" + +@class MODClient; +@class MODCollection; + +#ifndef UKSCTD_DEFAULT_TEXTENCODING +#define UKSCTD_DEFAULT_TEXTENCODING NSUTF8StringEncoding +#endif + +#define kJsonWindowWillClose @"kJsonWindowWillClose" +#define kJsonWindowSaved @"kJsonWindowSaved" + +@interface MHJsonWindowController : NSWindowController +{ + id _windowControllerId; + MODCollection *_collection; + MODSortedDictionary *_jsonDocument; + NSData *_bsonData; + + NSTextView *_jsonTextView; + NSProgressIndicator *_progressIndicator; + NSTextField *_status; + UKSyntaxColoredTextViewController *_syntaxColoringController; + NSButton *_saveButton; + NSButton *_cancelButton; +} + +// just a data to store (used by the user of this class +@property (nonatomic, readwrite, strong) id windowControllerId; +@property (nonatomic, readwrite, strong) MODSortedDictionary *jsonDocument; +@property (nonatomic, readwrite, strong) NSData *bsonData; +@property (nonatomic, readwrite, strong) MODCollection *collection; + +@end diff --git a/Sources/JSONEditor/MHJsonWindowController.m b/Sources/JSONEditor/MHJsonWindowController.m new file mode 100644 index 00000000..205a1b7f --- /dev/null +++ b/Sources/JSONEditor/MHJsonWindowController.m @@ -0,0 +1,225 @@ +// +// MHJsonWindowController.m +// MongoHub +// +// Created by Syd on 10-12-27. +// Copyright 2010 ThePeppersStudio.COM. All rights reserved. +// + +#import "MHJsonWindowController.h" +#import + +@interface MHJsonWindowController () +@property (nonatomic, readwrite, strong) UKSyntaxColoredTextViewController *syntaxColoringController; +@property (nonatomic, readwrite, weak) IBOutlet NSTextView *jsonTextView; +@property (nonatomic, readwrite, weak) IBOutlet NSProgressIndicator *progressIndicator; +@property (nonatomic, readwrite, weak) IBOutlet NSTextField *status; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *saveButton; +@property (nonatomic, readwrite, weak) IBOutlet NSButton *cancelButton; + +@end + +@implementation MHJsonWindowController +@synthesize collection = _collection; +@synthesize windowControllerId = _windowControllerId; +@synthesize jsonDocument = _jsonDocument; +@synthesize bsonData = _bsonData; + +@synthesize jsonTextView = _jsonTextView; +@synthesize progressIndicator = _progressIndicator; +@synthesize syntaxColoringController = _syntaxColoringController; +@synthesize status = _status; +@synthesize saveButton = _saveButton; +@synthesize cancelButton = _cancelButton; + +- (void)dealloc +{ + [self.syntaxColoringController removeObserver:self forKeyPath:@"unsaved"]; + self.collection = nil; + self.windowControllerId = nil; + self.jsonDocument = nil; + self.bsonData = nil; + self.syntaxColoringController.delegate = nil; + self.syntaxColoringController = nil; + [super dealloc]; +} + +- (NSString *)windowNibName +{ + return @"MHJsonWindow"; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + [[NSNotificationCenter defaultCenter] postNotificationName:kJsonWindowWillClose object:self]; +} + +- (BOOL)windowShouldClose:(id)sender +{ + if (!self.window.isDocumentEdited) { + return YES; + } else { + NSBeginAlertSheet(@"Unsaved Document", @"Save", @"Don't Save", @"Cancel", self.window, self, @selector(sheetDidEnd:returnCode:contextInfo:), @selector(sheetDidDismiss:returnCode:contextInfo:), nil, @"Do you want to save the current document?"); + return NO; + } +} + +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ +} + +- (void)sheetDidDismiss:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + switch (returnCode) { + case 0: + [self.window close]; + break; + + case -1: + break; + + case 1: + self.jsonTextView.editable = NO; + self.saveButton.enabled = NO; + self.cancelButton.enabled = NO; + [self.progressIndicator startAnimation:self]; + [self saveWithCallback:^(NSError *error) { + self.jsonTextView.editable = YES; + self.saveButton.enabled = YES; + self.cancelButton.enabled = YES; + if (error == nil) { + [self.window close]; + } + }]; + break; + + default: + break; + } +} + + +- (NSString *)jsonDocumentIdString +{ + id value; + + value = [self.jsonDocument objectForKey:@"_id"]; + if (!value) { + value = [self.jsonDocument objectForKey:@"name"]; + } + return nil; +} + +- (void)windowDidLoad +{ + NSDictionary *info = nil; + NSString *jsonString; + NSString *jsonDocumentIdString = self.jsonDocumentIdString; + + [super windowDidLoad]; + jsonString = [MODClient convertObjectToJson:self.jsonDocument pretty:YES strictJson:NO jsonKeySortOrder:MODJsonKeySortOrderDocument]; + if (jsonDocumentIdString) { + self.window.title = [NSString stringWithFormat:@"%@ _id:%@", self.collection.absoluteName, jsonDocumentIdString]; + } else { + self.window.title = self.collection.absoluteName; + } + self.jsonTextView.string = jsonString; + self.syntaxColoringController = [[[UKSyntaxColoredTextViewController alloc] init] autorelease]; + self.syntaxColoringController.delegate = self; + self.syntaxColoringController.view = self.jsonTextView; + [self.syntaxColoringController addObserver:self forKeyPath:@"unsaved" options:NSKeyValueObservingOptionNew context:nil]; + + if (self.bsonData) { + if (![MODClient isEqualWithJson:jsonString toBsonData:self.bsonData info:&info]) { + NSLog(@"%@", info); + NSLog(@"%@", self.bsonData); + NSLog(@"%@", jsonString); + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, self, nil, nil, nil, @"There is a problem to generate the json. If you save the current json, those values might modified:\n%@\n\nPlease open an issue at https://github.com/jeromelebel/mongohub-mac/issues", [[info objectForKey:@"differences"] componentsJoinedByString:@"\n"]); + } + } else if (![MODClient isEqualWithJson:jsonString toDocument:self.jsonDocument info:nil]) { + NSLog(@"%@", info); + NSLog(@"%@", jsonString); + NSLog(@"%@", self.jsonDocument); + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, self, nil, nil, nil, @"There is a problem to generate the json. If you save the current json, those values might modified:\n%@\n\nPlease open an issue at https://github.com/jeromelebel/mongohub-mac/issues", [[info objectForKey:@"differences"] componentsJoinedByString:@"\n"]); + } +} + +- (void)textViewControllerWillStartSyntaxRecoloring:(UKSyntaxColoredTextViewController *)sender +{ + [self.progressIndicator startAnimation:self]; +} + + +- (void)textViewControllerDidFinishSyntaxRecoloring:(UKSyntaxColoredTextViewController *)sender +{ + [self.progressIndicator stopAnimation: self]; +} + +- (void)selectionInTextViewController:(UKSyntaxColoredTextViewController *)sender // Update any selection status display. + changedToStartCharacter:(NSUInteger)startCharInLine endCharacter:(NSUInteger)endCharInLine + inLine:(NSUInteger)lineInDoc startCharacterInDocument:(NSUInteger)startCharInDoc + endCharacterInDocument:(NSUInteger)endCharInDoc; +{ + NSString *statusMsg = nil; + + if( startCharInDoc < endCharInDoc ) { + statusMsg = NSLocalizedString(@"character %lu to %lu of line %lu (%lu to %lu in document).",@"selection description in syntax colored text documents."); + statusMsg = [NSString stringWithFormat: statusMsg, startCharInLine +1, endCharInLine +1, lineInDoc +1, startCharInDoc +1, endCharInDoc +1]; + } else { + statusMsg = NSLocalizedString(@"character %lu of line %lu (%lu in document).",@"insertion mark description in syntax colored text documents."); + statusMsg = [NSString stringWithFormat: statusMsg, startCharInLine +1, lineInDoc +1, startCharInDoc +1]; + } + statusMsg = @""; + [self.status setStringValue:statusMsg]; + [self.status display]; +} + +- (IBAction)save:(id)sender +{ + [self saveWithCallback:nil]; +} + +- (void)saveWithCallback:(void (^)(NSError *error))callback +{ + MODSortedDictionary *document; + NSError *error; + + self.status.stringValue = @"Saving..."; + [self.progressIndicator startAnimation: self]; + document = [MODRagelJsonParser objectsFromJson:self.jsonTextView.string withError:&error]; + if (error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", error.localizedDescription); + [self.progressIndicator stopAnimation: self]; + self.status.stringValue = [error.localizedDescription stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; + if (callback) callback(error); + } else { + callback = [callback copy]; + [self.collection saveWithDocument:document callback:^(MODQuery *mongoQuery) { + [self.progressIndicator stopAnimation:self]; + if (mongoQuery.error) { + NSBeginAlertSheet(@"Error", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"%@", mongoQuery.error.localizedDescription); + self.status.stringValue = mongoQuery.error.localizedDescription; + } else { + self.syntaxColoringController.originalString = self.jsonTextView.string; + self.status.stringValue = @"Saved"; + [NSNotificationCenter.defaultCenter postNotificationName:kJsonWindowSaved object:nil]; + } + if (callback) callback(mongoQuery.error); + [callback release]; + }]; + } +} + +- (void)mongoQueryDidFinish:(MODQuery *)mongoQuery +{ + +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ([keyPath isEqualToString:@"unsaved"]) { + [self.window setDocumentEdited:self.syntaxColoringController.unsaved]; + } +} + +@end diff --git a/UKSyntaxColoredTextViewController.h b/Sources/JSONEditor/UKSyntaxColoredTextViewController.h similarity index 87% rename from UKSyntaxColoredTextViewController.h rename to Sources/JSONEditor/UKSyntaxColoredTextViewController.h index a05049f9..3014e29f 100644 --- a/UKSyntaxColoredTextViewController.h +++ b/Sources/JSONEditor/UKSyntaxColoredTextViewController.h @@ -54,9 +54,6 @@ inLine: (NSUInteger)lineInDoc startCharacterInDocument: (NSUInteger)startCharInDoc endCharacterInDocument: (NSUInteger)endCharInDoc; --(NSString*) syntaxDefinitionFilenameForTextViewController: (UKSyntaxColoredTextViewController*)sender; --(NSDictionary*) syntaxDefinitionDictionaryForTextViewController: (UKSyntaxColoredTextViewController*)sender; - @end @@ -73,13 +70,13 @@ BOOL syntaxColoringBusy; // Set while recolorRange is busy, so we don't recursively call recolorRange. NSRange affectedCharRange; NSString* replacementString; - id delegate; + id _delegate; + BOOL _unsaved; + NSString *_originalString; } - -+(void) makeSurePrefsAreInited; // No need to call this. - --(void) setDelegate: (id)delegate; --(id) delegate; +@property (nonatomic, readwrite, assign) id delegate; +@property (nonatomic, readwrite, assign) BOOL unsaved; +@property (nonatomic, readwrite, copy) NSString *originalString; -(IBAction) recolorCompleteFile: (id)sender; -(IBAction) toggleAutoSyntaxColoring: (id)sender; @@ -98,10 +95,6 @@ -(void) goToCharacter: (int)charNum; -(void) goToRangeFrom: (int)startCh toChar: (int)endCh; -// Override any of the following in one of your subclasses to customize this object further: --(NSString*) syntaxDefinitionFilename; // Defaults to "SyntaxDefinition.plist" in the app bundle's "Resources" directory. --(NSDictionary*) syntaxDefinitionDictionary; // Defaults to loading from -syntaxDefinitionFilename. - -(NSDictionary*) defaultTextAttributes; // Style attributes dictionary for an NSAttributedString. // Private: diff --git a/UKSyntaxColoredTextViewController.m b/Sources/JSONEditor/UKSyntaxColoredTextViewController.m similarity index 84% rename from UKSyntaxColoredTextViewController.m rename to Sources/JSONEditor/UKSyntaxColoredTextViewController.m index 9eedcd94..e8be485d 100644 --- a/UKSyntaxColoredTextViewController.m +++ b/Sources/JSONEditor/UKSyntaxColoredTextViewController.m @@ -30,15 +30,8 @@ // ----------------------------------------------------------------------------- #import "UKSyntaxColoredTextViewController.h" -#import "NSArray+Color.h" #import "NSScanner+SkipUpToCharset.h" - - -// ----------------------------------------------------------------------------- -// Globals: -// ----------------------------------------------------------------------------- - -static BOOL sSyntaxColoredTextDocPrefsInited = NO; +#import "MHJsonColorManager.h" // ----------------------------------------------------------------------------- @@ -50,39 +43,21 @@ @implementation UKSyntaxColoredTextViewController -+(void) makeSurePrefsAreInited -{ - if( !sSyntaxColoredTextDocPrefsInited ) - { - NSUserDefaults* prefs = [NSUserDefaults standardUserDefaults]; - [prefs registerDefaults: [NSDictionary dictionaryWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"SyntaxColorDefaults" ofType: @"plist"]]]; - - sSyntaxColoredTextDocPrefsInited = YES; - } -} - - -/* ----------------------------------------------------------------------------- - init: - Constructor that inits sourceCode member variable as a flag. It's - storage for the text until the NIB's been loaded. - -------------------------------------------------------------------------- */ +@synthesize delegate = _delegate; +@synthesize unsaved = _unsaved; --(id) initWithNibName: (NSString*)inNibName bundle: (NSBundle*)inBundle +- (instancetype)init { - self = [super initWithNibName: inNibName bundle: inBundle]; - if( self ) - { - autoSyntaxColoring = YES; - maintainIndentation = YES; - recolorTimer = nil; - syntaxColoringBusy = NO; - } + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jsonColorManagerChanged:) name:MHJsonColorManagerHasBeenUpdatedNotification object:MHJsonColorManager.sharedManager]; + autoSyntaxColoring = YES; + maintainIndentation = YES; + } return self; } --(void) dealloc +- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver: self]; @@ -96,11 +71,29 @@ -(void) dealloc [super dealloc]; } +- (void)jsonColorManagerChanged:(id)sender +{ + [self setUpSyntaxColoring]; +} -(void) setUpSyntaxColoring { - // Set up some sensible defaults for syntax coloring: - [[self class] makeSurePrefsAreInited]; + NSDictionary *textFieldSettings = MHJsonColorManager.sharedManager.values[@"TextField"]; + + if (textFieldSettings[@"Background"][@"Color"]) { + TEXTVIEW.backgroundColor = textFieldSettings[@"Background"][@"Color"]; + } + if (textFieldSettings[@"InsertionPoint"][@"Color"]) { + TEXTVIEW.insertionPointColor = textFieldSettings[@"InsertionPoint"][@"Color"]; + } + if (textFieldSettings[@"Text"]) { + if (textFieldSettings[@"Text"][@"Color"]) { + TEXTVIEW.textColor = textFieldSettings[@"Text"][@"Color"]; + } + if (textFieldSettings[@"Text"][@"Font"]) { + TEXTVIEW.font = textFieldSettings[@"Text"][@"Font"]; + } + } // Register for "text changed" notifications of our text storage: [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(processEditing:) @@ -116,8 +109,7 @@ -(void) setUpSyntaxColoring // Put selection at top like Project Builder has it, so user sees it: [TEXTVIEW setSelectedRange: NSMakeRange(0,0)]; - [self textView: TEXTVIEW willChangeSelectionFromCharacterRange: NSMakeRange(0,0) - toCharacterRange: NSMakeRange(0,0)]; + [self textView: TEXTVIEW willChangeSelectionFromCharacterRange: NSMakeRange(0,0) toCharacterRange: NSMakeRange(0,0)]; // Make sure we can use "find" if we're on 10.3: if( [TEXTVIEW respondsToSelector: @selector(setUsesFindPanel:)] ) @@ -125,18 +117,6 @@ -(void) setUpSyntaxColoring } --(void) setDelegate: (id)inDelegate -{ - delegate = inDelegate; -} - - --(id) delegate -{ - return delegate; -} - - /* ----------------------------------------------------------------------------- setView: We've just been given a view! Apply initial syntax coloring. @@ -146,10 +126,24 @@ -(void) setView: (NSView*)theView { [super setView: theView]; - [(NSTextView*)theView setDelegate: self]; + TEXTVIEW.delegate = self; + self.originalString = TEXTVIEW.string; [self setUpSyntaxColoring]; // +++ If someone calls this twice, we should only call part of this twice! } +- (void)setOriginalString:(NSString *)originalString +{ + if (![originalString isEqualToString:_originalString]) { + [_originalString release]; + _originalString = [originalString copy]; + self.unsaved = ![self.originalString isEqualToString:TEXTVIEW.string]; + } +} + +- (NSString *)originalString +{ + return _originalString; +} /* ----------------------------------------------------------------------------- processEditing: @@ -160,7 +154,7 @@ -(void) processEditing: (NSNotification*)notification { NSTextStorage *textStorage = [notification object]; NSRange range = [textStorage editedRange]; - int changeInLen = [textStorage changeInLength]; + NSInteger changeInLen = [textStorage changeInLength]; BOOL wasInUndoRedo = [[self undoManager] isUndoing] || [[self undoManager] isRedoing]; BOOL textLengthMayHaveChanged = NO; @@ -197,7 +191,7 @@ -(void) processEditing: (NSNotification*)notification atIndex: currRange.location effectiveRange: &effectiveRange]; - unsigned int x = range.location; + NSUInteger x = range.location; /* TODO: If we're in a multi-line comment and we're typing a comment-end character, or we're in a string and we're typing a quote character, @@ -263,16 +257,16 @@ -(BOOL) textView:(NSTextView *)tv shouldChangeTextInRange:(NSRange)afcr replacem -(void) didChangeText // This actually does what we want to do in textView:shouldChangeTextInRange: { + self.unsaved = ![self.originalString isEqualToString:TEXTVIEW.string]; if( maintainIndentation && replacementString && ([replacementString isEqualToString:@"\n"] - || [replacementString isEqualToString:@"\r"]) ) - { + || [replacementString isEqualToString:@"\r"]) ) { NSMutableAttributedString* textStore = [TEXTVIEW textStorage]; BOOL hadSpaces = NO; - unsigned int lastSpace = affectedCharRange.location, + NSUInteger lastSpace = affectedCharRange.location, prevLineBreak = 0; NSRange spacesRange = { 0, 0 }; unichar theChar = 0; - unsigned int x = (affectedCharRange.location == 0) ? 0 : affectedCharRange.location -1; + NSUInteger x = (affectedCharRange.location == 0) ? 0 : affectedCharRange.location -1; NSString* tsString = [textStore string]; while( YES ) @@ -525,7 +519,7 @@ -(IBAction) indentSelection: (id)sender NSRange selRange = [TEXTVIEW selectedRange], nuSelRange = selRange; - unsigned x; + NSInteger x; NSMutableString* str = [[TEXTVIEW textStorage] mutableString]; // Unselect any trailing returns so we don't indent the next line after a full-line selection. @@ -563,8 +557,8 @@ -(IBAction) unindentSelection: (id)sender { NSRange selRange = [TEXTVIEW selectedRange], nuSelRange = selRange; - unsigned x, n; - unsigned lastIndex = selRange.location +selRange.length -1; + NSInteger x, n; + NSInteger lastIndex = selRange.location +selRange.length -1; NSMutableString* str = [[TEXTVIEW textStorage] mutableString]; // Unselect any trailing returns so we don't indent the next line after a full-line selection. @@ -637,7 +631,7 @@ -(IBAction) unindentSelection: (id)sender -(IBAction) toggleCommentForSelection: (id)sender { NSRange selRange = [TEXTVIEW selectedRange]; - unsigned x; + NSInteger x; NSMutableString* str = [[TEXTVIEW textStorage] mutableString]; if( selRange.length == 0 ) @@ -684,8 +678,8 @@ -(IBAction) toggleCommentForSelection: (id)sender [[self undoManager] registerUndoWithTarget: self selector: @selector(restoreText:) object: prevText]; // Unselect any trailing returns so we don't comment the next line after a full-line selection. - while( [str characterAtIndex: selRange.location +selRange.length -1] == '\n' || - [str characterAtIndex: selRange.location +selRange.length -1] == '\r' + while( ([str characterAtIndex: selRange.location +selRange.length -1] == '\n' || + [str characterAtIndex: selRange.location +selRange.length -1] == '\r') && selRange.length > 0 ) { selRange.length--; @@ -694,7 +688,7 @@ -(IBAction) toggleCommentForSelection: (id)sender NSRange nuSelRange = selRange; - NSString* commentPrefix = [[self syntaxDefinitionDictionary] objectForKey: @"OneLineCommentPrefix"]; + NSString* commentPrefix = MHJsonColorManager.sharedManager.values[@"OneLineCommentPrefix"]; if( !commentPrefix || [commentPrefix length] == 0 ) commentPrefix = @"# "; NSInteger commentPrefixLength = [commentPrefix length]; @@ -804,18 +798,28 @@ -(void) recolorRange: (NSRange)range if( syntaxColoringBusy ) // Prevent endless loop when recoloring's replacement of text causes processEditing to fire again. return; + [self performSelector:@selector(recolorAfterDelayWithRange:) withObject:NSStringFromRange(range) afterDelay:0]; +} + +- (void)recolorAfterDelayWithRange:(NSString *)string +{ + NSRange range; + NSArray *selectedRanges; + + range = NSRangeFromString(string); if( TEXTVIEW == nil || range.length == 0 // Don't like doing useless stuff. || recolorTimer ) // And don't like recoloring partially if a full recolorization is pending. return; + selectedRanges = [TEXTVIEW selectedRanges]; @try { syntaxColoringBusy = YES; - if( [delegate respondsToSelector: @selector(textViewControllerWillStartSyntaxRecoloring:)] ) - [delegate textViewControllerWillStartSyntaxRecoloring: self]; + if( [self.delegate respondsToSelector: @selector(textViewControllerWillStartSyntaxRecoloring:)] ) + [self.delegate textViewControllerWillStartSyntaxRecoloring: self]; // Kludge fix for case where we sometimes exceed text length:ra - int diff = [[TEXTVIEW textStorage] length] -(range.location +range.length); + NSInteger diff = [[TEXTVIEW textStorage] length] -(range.location +range.length); if( diff < 0 ) range.length += diff; @@ -825,8 +829,7 @@ -(void) recolorRange: (NSRange)range // Load colors and fonts to use from preferences: // Load our dictionary which contains info on coloring this language: - NSDictionary* vSyntaxDefinition = [self syntaxDefinitionDictionary]; - NSEnumerator* vComponentsEnny = [[vSyntaxDefinition objectForKey: @"Components"] objectEnumerator]; + NSEnumerator* vComponentsEnny = [MHJsonColorManager.sharedManager.values[@"Components"] objectEnumerator]; if( vComponentsEnny == nil ) // No new-style list of components to colorize? { @@ -837,7 +840,6 @@ -(void) recolorRange: (NSRange)range // Loop over all available components: NSDictionary* vCurrComponent = nil; NSDictionary* vStyles = [self defaultTextAttributes]; - NSUserDefaults* vPrefs = [NSUserDefaults standardUserDefaults]; NSDictionary* dStyles = [NSDictionary dictionaryWithObjectsAndKeys: [NSColor whiteColor], NSForegroundColorAttributeName, @@ -850,11 +852,7 @@ -(void) recolorRange: (NSRange)range { NSString* vComponentType = [vCurrComponent objectForKey: @"Type"]; NSString* vComponentName = [vCurrComponent objectForKey: @"Name"]; - NSString* vColorKeyName = [@"SyntaxColoring:Color:" stringByAppendingString: vComponentName]; - NSColor* vColor = [[vPrefs arrayForKey: vColorKeyName] colorValue]; - - if( !vColor ) - vColor = [[vCurrComponent objectForKey: @"Color"] colorValue]; + NSColor* vColor = vCurrComponent[@"Color"]; if( [vComponentType isEqualToString: @"BlockComment"] ) { @@ -884,10 +882,6 @@ -(void) recolorRange: (NSRange)range else if( [vComponentType isEqualToString: @"Keywords"] ) { NSArray* vIdents = [vCurrComponent objectForKey: @"Keywords"]; - if( !vIdents ) - vIdents = [[NSUserDefaults standardUserDefaults] objectForKey: [@"SyntaxColoring:Keywords:" stringByAppendingString: vComponentName]]; - if( !vIdents && [vComponentName isEqualToString: @"UserIdentifiers"] ) - vIdents = [[NSUserDefaults standardUserDefaults] objectForKey: TD_USER_DEFINED_IDENTIFIERS]; if( vIdents ) { NSCharacterSet* vIdentCharset = nil; @@ -910,11 +904,10 @@ -(void) recolorRange: (NSRange)range } @finally { - if( [delegate respondsToSelector: @selector(textViewControllerDidFinishSyntaxRecoloring:)] ) - [delegate textViewControllerDidFinishSyntaxRecoloring: self]; + if( [self.delegate respondsToSelector: @selector(textViewControllerDidFinishSyntaxRecoloring:)] ) + [self.delegate textViewControllerDidFinishSyntaxRecoloring: self]; syntaxColoringBusy = NO; - [self textView: TEXTVIEW willChangeSelectionFromCharacterRange: [TEXTVIEW selectedRange] - toCharacterRange: [TEXTVIEW selectedRange]]; + [TEXTVIEW setSelectedRanges:selectedRanges]; } } @@ -928,14 +921,14 @@ -(void) recolorRange: (NSRange)range -(NSRange) textView: (NSTextView*)theTextView willChangeSelectionFromCharacterRange: (NSRange)oldSelectedCharRange toCharacterRange: (NSRange)newSelectedCharRange { - unsigned startCh = newSelectedCharRange.location, + NSUInteger startCh = newSelectedCharRange.location, endCh = newSelectedCharRange.location +newSelectedCharRange.length; - unsigned lineNo = 0, + NSUInteger lineNo = 0, lastLineStart = 0, x = 0; - unsigned startChLine = 0, endChLine = 0; + NSUInteger startChLine = 0, endChLine = 0; unichar lastBreakChar = 0; - unsigned lastBreakOffs = 0; + NSUInteger lastBreakOffs = 0; // Calc line number: for( x = 0; (x < startCh) && (x < [[theTextView string] length]); x++ ) @@ -965,8 +958,8 @@ -(NSRange) textView: (NSTextView*)theTextView willChangeSelectionFromCharacterR endChLine = (newSelectedCharRange.location -lastLineStart) +newSelectedCharRange.length; // Let delegate know what to display: - if( [delegate respondsToSelector: @selector(selectionInTextViewController:changedToStartCharacter:endCharacter:inLine:startCharacterInDocument:endCharacterInDocument:)] ) - [delegate selectionInTextViewController: self + if( [self.delegate respondsToSelector: @selector(selectionInTextViewController:changedToStartCharacter:endCharacter:inLine:startCharacterInDocument:endCharacterInDocument:)] ) + [self.delegate selectionInTextViewController: self changedToStartCharacter: startChLine endCharacter: endChLine inLine: lineNo startCharacterInDocument: startCh endCharacterInDocument: endCh]; @@ -975,60 +968,6 @@ -(NSRange) textView: (NSTextView*)theTextView willChangeSelectionFromCharacterR } -/* ----------------------------------------------------------------------------- - syntaxDefinitionFilename: - Like nibName, this should return the name of the syntax - definition file to use. Advanced users may use this to allow different - coloring to take place depending on the file extension by returning - different file names here. - - Note that the ".plist" extension is automatically appended to the file - name. - -------------------------------------------------------------------------- */ - --(NSString*) syntaxDefinitionFilename -{ - NSString* syntaxDefFN = nil; - if( [delegate respondsToSelector: @selector(syntaxDefinitionFilenameForTextViewController:)] ) - syntaxDefFN = [delegate syntaxDefinitionFilenameForTextViewController: self]; - - if( !syntaxDefFN ) - syntaxDefFN = @"SyntaxDefinition"; - - return syntaxDefFN; -} - - -/* ----------------------------------------------------------------------------- - syntaxDefinitionDictionary: - This returns the syntax definition dictionary to use, which indicates - what ranges of text to colorize. Advanced users may use this to allow - different coloring to take place depending on the file extension by - returning different dictionaries here. - - By default, this simply reads a dictionary from the .plist file - indicated by -syntaxDefinitionFilename. - -------------------------------------------------------------------------- */ - --(NSDictionary*) syntaxDefinitionDictionary -{ - NSDictionary* theDict = nil; - - if( [delegate respondsToSelector: @selector(syntaxDefinitionDictionaryForTextViewController:)] ) - theDict = [delegate syntaxDefinitionDictionaryForTextViewController: self]; - - if( !theDict ) - { - NSBundle* theBundle = [self nibBundle]; - if( !theBundle ) - theBundle = [NSBundle bundleForClass: [self class]]; // Usually the main bundle, but be nice to plugins. - theDict = [NSDictionary dictionaryWithContentsOfFile: [theBundle pathForResource: [self syntaxDefinitionFilename] ofType: @"plist"]]; - } - - return theDict; -} - - /* ----------------------------------------------------------------------------- colorStringsFrom: Apply syntax coloring to all strings. This is basically the same code @@ -1047,7 +986,7 @@ -(void) colorStringsFrom: (NSString*) startCh to: (NSString*) endCh inString: (N nil]; BOOL vIsEndChar = NO; unichar vEscChar = '\\'; - BOOL vDelegateHandlesProgress = [delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; + BOOL vDelegateHandlesProgress = [self.delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; if( vStringEscapeCharacter ) { @@ -1057,12 +996,12 @@ -(void) colorStringsFrom: (NSString*) startCh to: (NSString*) endCh inString: (N while( ![vScanner isAtEnd] ) { - int vStartOffs, + NSInteger vStartOffs, vEndOffs; vIsEndChar = NO; if( vDelegateHandlesProgress ) - [delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; + [self.delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; // Look for start of string: [vScanner scanUpToString: startCh intoString: nil]; @@ -1079,7 +1018,7 @@ -(void) colorStringsFrom: (NSString*) startCh to: (NSString*) endCh inString: (N return; if( vDelegateHandlesProgress ) - [delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; + [self.delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; } vEndOffs = [vScanner scanLocation]; @@ -1111,11 +1050,11 @@ -(void) colorCommentsFrom: (NSString*) startCh to: (NSString*) endCh inString: ( col, NSForegroundColorAttributeName, attr, TD_SYNTAX_COLORING_MODE_ATTR, nil]; - BOOL vDelegateHandlesProgress = [delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; + BOOL vDelegateHandlesProgress = [self.delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; while( ![vScanner isAtEnd] ) { - int vStartOffs, + NSInteger vStartOffs, vEndOffs; // Look for start of multi-line comment: @@ -1126,15 +1065,16 @@ -(void) colorCommentsFrom: (NSString*) startCh to: (NSString*) endCh inString: ( // Look for associated end-of-comment marker: [vScanner scanUpToString: endCh intoString: nil]; - if( ![vScanner scanString: endCh intoString: nil] ) + if( ![vScanner scanString: endCh intoString: nil] ) { /*return*/; // Don't exit. If user forgot trailing marker, indicate this by "bleeding" until end of string. + } vEndOffs = [vScanner scanLocation]; // Now mess with the string's styles: [s setAttributes: vStyles range: NSMakeRange( vStartOffs, vEndOffs -vStartOffs )]; if( vDelegateHandlesProgress ) - [delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; + [self.delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; } } @catch( ... ) @@ -1162,11 +1102,11 @@ -(void) colorOneLineComment: (NSString*) startCh inString: (NSMutableAttributedS col, NSForegroundColorAttributeName, attr, TD_SYNTAX_COLORING_MODE_ATTR, nil]; - BOOL vDelegateHandlesProgress = [delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; + BOOL vDelegateHandlesProgress = [self.delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; while( ![vScanner isAtEnd] ) { - int vStartOffs, + NSInteger vStartOffs, vEndOffs; // Look for start of one-line comment: @@ -1176,8 +1116,9 @@ -(void) colorOneLineComment: (NSString*) startCh inString: (NSMutableAttributedS return; // Look for associated line break: - if( ![vScanner skipUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString: @"\n\r"]] ) + if( ![vScanner skipUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString: @"\n\r"]] ) { ; + } vEndOffs = [vScanner scanLocation]; @@ -1185,7 +1126,7 @@ -(void) colorOneLineComment: (NSString*) startCh inString: (NSMutableAttributedS [s setAttributes: vStyles range: NSMakeRange( vStartOffs, vEndOffs -vStartOffs )]; if( vDelegateHandlesProgress ) - [delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; + [self.delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; } } @catch( ... ) @@ -1213,8 +1154,8 @@ -(void) colorIdentifier: (NSString*) ident inString: (NSMutableAttributedString* col, NSForegroundColorAttributeName, attr, TD_SYNTAX_COLORING_MODE_ATTR, nil]; - int vStartOffs = 0; - BOOL vDelegateHandlesProgress = [delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; + NSInteger vStartOffs = 0; + BOOL vDelegateHandlesProgress = [self.delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; // Skip any leading whitespace chars, somehow NSScanner doesn't do that: if( cset ) @@ -1233,9 +1174,9 @@ -(void) colorIdentifier: (NSString*) ident inString: (NSMutableAttributedString* { // Look for start of identifier: [vScanner scanUpToString: ident intoString: nil]; - vStartOffs = [vScanner scanLocation]; if( ![vScanner scanString:ident intoString:nil] ) return; + vStartOffs = [vScanner scanLocation] - ident.length; if( vStartOffs > 0 ) // Check that we're not in the middle of an identifier: { @@ -1255,7 +1196,7 @@ -(void) colorIdentifier: (NSString*) ident inString: (NSMutableAttributedString* [s setAttributes: vStyles range: NSMakeRange( vStartOffs, [ident length] )]; if( vDelegateHandlesProgress ) - [delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; + [self.delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; } } @catch( ... ) @@ -1283,11 +1224,11 @@ -(void) colorTagFrom: (NSString*) startCh to: (NSString*)endCh inString: (NSMuta col, NSForegroundColorAttributeName, attr, TD_SYNTAX_COLORING_MODE_ATTR, nil]; - BOOL vDelegateHandlesProgress = [delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; + BOOL vDelegateHandlesProgress = [self.delegate respondsToSelector: @selector(textViewControllerProgressedWhileSyntaxRecoloring:)]; while( ![vScanner isAtEnd] ) { - int vStartOffs, + NSInteger vStartOffs, vEndOffs; // Look for start of one-line comment: @@ -1307,7 +1248,7 @@ -(void) colorTagFrom: (NSString*) startCh to: (NSString*)endCh inString: (NSMuta while( ![vScanner isAtEnd] ) { // Scan up to the next occurence of the terminating sequence: - (BOOL) [vScanner scanUpToString: endCh intoString:nil]; + [vScanner scanUpToString: endCh intoString:nil]; // Now, if the mode of the end marker is not the mode we were told to ignore, // we're finished now and we can exit the inner loop: @@ -1326,7 +1267,7 @@ -(void) colorTagFrom: (NSString*) startCh to: (NSString*)endCh inString: (NSMuta vEndOffs = [vScanner scanLocation]; if( vDelegateHandlesProgress ) - [delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; + [self.delegate textViewControllerProgressedWhileSyntaxRecoloring: self]; // Now mess with the string's styles: [s setAttributes: vStyles range: NSMakeRange( vStartOffs, vEndOffs -vStartOffs )]; @@ -1349,7 +1290,7 @@ -(void) colorTagFrom: (NSString*) startCh to: (NSString*)endCh inString: (NSMuta -(NSDictionary*) defaultTextAttributes { - return [NSDictionary dictionaryWithObjectsAndKeys: [NSFont userFixedPitchFontOfSize: 10.0], NSFontAttributeName, nil]; + return [NSDictionary dictionaryWithObjectsAndKeys:TEXTVIEW.font, NSFontAttributeName, nil]; } @end diff --git a/Sources/MHApplicationDelegate.h b/Sources/MHApplicationDelegate.h new file mode 100644 index 00000000..abb3ff19 --- /dev/null +++ b/Sources/MHApplicationDelegate.h @@ -0,0 +1,60 @@ +// +// MHApplicationDelegate.h +// MongoHub +// +// Created by Syd on 10-4-24. +// Copyright MusicPeace.ORG 2010 . All rights reserved. +// + +#import +#import "MHConnectionEditorWindowController.h" +#import "MHConnectionCollectionView.h" +#import "MHConnectionWindowController.h" + +@class MHConnectionCollectionView; +@class MHConnectionStore; +@class MHConnectionEditorWindowController; +@class SUUpdater; +@class MHPreferenceWindowController; +@class MHLogWindowController; + +typedef enum { + MHSoftwareUpdateChannelDefault, + MHSoftwareUpdateChannelBeta +} MHSoftwareUpdateChannel; + +@interface MHApplicationDelegate : NSObject + +@property (nonatomic, readonly, strong) NSWindow *window; + +@property (nonatomic, readonly, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator; +@property (nonatomic, readonly, strong) NSManagedObjectModel *managedObjectModel; +@property (nonatomic, readonly, strong) NSManagedObjectContext *managedObjectContext; +@property (nonatomic, readwrite, assign) MHSoftwareUpdateChannel softwareUpdateChannel; +@property (nonatomic, readonly, assign) uint32_t defaultConnectTimeout; +@property (nonatomic, readwrite, assign) uint32_t connectTimeout; +@property (nonatomic, readonly, assign) uint32_t defaultSocketTimeout; +@property (nonatomic, readwrite, assign) uint32_t socketTimeout; + +@end + +@interface MHApplicationDelegate (MHConnectionEditorWindowControllerDelegate) +@end + +@interface MHApplicationDelegate (ConnexionManager) +- (void)saveConnections; +- (MHConnectionStore *)connectionStoreWithAlias:(NSString *)alias; +- (void)openConnection:(MHConnectionStore *)connection; +- (void)deleteConnection:(MHConnectionStore *)connection; +@end + +@interface MHApplicationDelegate (MHConnectionWindowControllerDelegate) +@end + +@interface MHApplicationDelegate (Preferences) +- (BOOL)hasCollectionMapReduceTab; +- (void)setCollectionMapReduceTab:(BOOL)value; +- (BOOL)hasCollectionAggregationTab; +- (void)setCollectionAggregationTab:(BOOL)value; + +@end \ No newline at end of file diff --git a/Sources/MHApplicationDelegate.m b/Sources/MHApplicationDelegate.m new file mode 100644 index 00000000..41082ad6 --- /dev/null +++ b/Sources/MHApplicationDelegate.m @@ -0,0 +1,795 @@ +// +// MHApplicationDelegate.m +// MongoHub +// +// Created by Syd on 10-4-24. +// Copyright MusicPeace.ORG 2010 . All rights reserved. +// + +#import "MHApplicationDelegate.h" + +#import + +#import "MHConnectionWindowController.h" +#import "ConnectionsArrayController.h" +#import "MHConnectionEditorWindowController.h" +#import "MHConnectionStore.h" +#import "MHPreferenceWindowController.h" +#import "MHConnectionViewItem.h" +#import "MHLogWindowController.h" +#import "ALIterativeMigrator.h" +#import "MHEditNameWindowController.h" + +#define YOUR_EXTERNAL_RECORD_EXTENSION @"mgo" +#define YOUR_STORE_TYPE NSXMLStoreType + +#define MHSofwareUpdateChannelKey @"MHSofwareUpdateChannel" +#define MHConnectTimeoutKey @"MHConnectTimeoutKey" +#define MHSocketTimeoutKey @"MHSocketTimeoutKey" + +@interface MHApplicationDelegate() +@property (nonatomic, readwrite, strong) SUUpdater *updater; +@property (nonatomic, readwrite, strong) MHPreferenceWindowController *preferenceWindowController; +@property (nonatomic, readwrite, strong) NSMutableArray *urlConnectionEditorWindowControllers; +@property (nonatomic, readwrite, strong) NSMutableArray *connectionWindowControllers; +@property (nonatomic, readwrite, strong) MHLogWindowController *logWindowController; + +@property (nonatomic, readwrite, strong) IBOutlet ConnectionsArrayController *connectionsArrayController; +@property (nonatomic, readwrite, strong) IBOutlet NSTextField *bundleVersion; +@property (nonatomic, readwrite, strong) IBOutlet NSPanel *supportPanel; + +- (NSURL *)dataStoreURL; + +@end + +@interface MHApplicationDelegate (MHLogWindowControllerDelegate) + +@end + +@implementation MHApplicationDelegate +{ + NSPersistentStoreCoordinator *_persistentStoreCoordinator; + NSManagedObjectModel *_managedObjectModel; + NSManagedObjectContext *_managedObjectContext; +} + +- (void)awakeFromNib +{ + if ([[NSProcessInfo processInfo].environment[@"MONGOC_VERBOSE"] integerValue] != 0) { + [MODClient setLogCallback:^(MODLogLevel level, const char *domain, const char *message) { + NSLog(@"%@ %s %s", [MODClient logLevelStringForLogLevel:level], domain, message); + }]; + } + self.connectionWindowControllers = [NSMutableArray array]; + self.urlConnectionEditorWindowControllers = [NSMutableArray array]; + [self.connectionsArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"alias" ascending:YES selector:@selector(caseInsensitiveCompare:)]]]; +} + +- (void)dealloc +{ + self.connectionWindowControllers = nil; + [_managedObjectContext release]; + [_persistentStoreCoordinator release]; + [_managedObjectModel release]; + + self.urlConnectionEditorWindowControllers = nil; + self.preferenceWindowController = nil; + self.updater = nil; + self.connectionsArrayController = nil; + self.bundleVersion = nil; + + [super dealloc]; +} + +- (NSURL *)dataStoreURL +{ + return [NSURL fileURLWithPath:[self.applicationSupportDirectory stringByAppendingPathComponent:@"storedata"]]; +} + +/** + Returns the support directory for the application, used to store the Core Data + store file. This code uses a directory named "MongoHub" for + the content, either in the NSApplicationSupportDirectory location or (if the + former cannot be found), the system's temporary directory. + */ + +- (NSString *)applicationSupportDirectory +{ + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory(); + return [basePath stringByAppendingPathComponent:@"MongoHub"]; +} + +/** + Returns the external records directory for the application. + This code uses a directory named "MongoHub" for the content, + either in the ~/Library/Caches/Metadata/CoreData location or (if the + former cannot be found), the system's temporary directory. + */ + +- (NSString *)externalRecordsDirectory +{ + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory(); + return [basePath stringByAppendingPathComponent:@"Metadata/CoreData/MongoHub"]; +} + +/** + Creates, retains, and returns the managed object model for the application + by merging all of the models found in the application bundle. + */ + +- (NSManagedObjectModel *)managedObjectModel +{ + if (_managedObjectModel) { + return _managedObjectModel; + } + + _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; + return _managedObjectModel; +} + + +/** + Returns the persistent store coordinator for the application. This + implementation will create and return a coordinator, having added the + store for the application to it. (The directory for the store is created, + if necessary.) + */ + +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator +{ + if (_persistentStoreCoordinator) return _persistentStoreCoordinator; + + NSManagedObjectModel *mom = self.managedObjectModel; + if (!mom) { + NSAssert(NO, @"Managed object model is nil"); + NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd)); + return nil; + } + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *applicationSupportDirectory = [self applicationSupportDirectory]; + NSError *error = nil; + + if (![fileManager fileExistsAtPath:applicationSupportDirectory isDirectory:NULL]) { + if (![fileManager createDirectoryAtPath:applicationSupportDirectory withIntermediateDirectories:NO attributes:nil error:&error]) { + NSAssert2(NO, @"Failed to create App Support directory %@ : %@", applicationSupportDirectory, error); + NSLog(@"Error creating application support directory at %@ : %@",applicationSupportDirectory,error); + return nil; + } + } + + NSString *externalRecordsDirectory = [self externalRecordsDirectory]; + if (![fileManager fileExistsAtPath:externalRecordsDirectory isDirectory:NULL]) { + if (![fileManager createDirectoryAtPath:externalRecordsDirectory withIntermediateDirectories:YES attributes:nil error:&error]) { + NSLog(@"Error creating external records directory at %@ : %@",externalRecordsDirectory,error); + NSAssert2(NO, @"Failed to create external records directory %@ : %@", externalRecordsDirectory, error); + NSLog(@"Error creating external records directory at %@ : %@",externalRecordsDirectory,error); + return nil; + }; + } + + // set store options to enable spotlight indexing + NSMutableDictionary *storeOptions = [NSMutableDictionary dictionary]; + storeOptions[NSExternalRecordExtensionOption] = YOUR_EXTERNAL_RECORD_EXTENSION; + storeOptions[NSExternalRecordsDirectoryOption] = externalRecordsDirectory; + storeOptions[NSMigratePersistentStoresAutomaticallyOption] = @(YES); + storeOptions[NSInferMappingModelAutomaticallyOption] = @(YES); + storeOptions[NSMigratePersistentStoresAutomaticallyOption] = @(YES); + + _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: mom]; + NSArray* modelNames = @[ + @"MongoHub_DataModel", + @"MongoHub_DataModel3.0", + @"MongoHub_DataModel4", + @"MongoHub_DataModel5", + @"MongoHub_DataModel6", + @"MongoHub_DataModel7", + @"MongoHub_DataModel8", + @"MongoHub_DataModel9", + @"MongoHub_DataModel10", + @"MongoHub_DataModel11", + @"MongoHub_DataModel12", + @"MongoHub_DataModel13", + ]; + if (![ALIterativeMigrator iterativeMigrateURL:self.dataStoreURL + ofType:YOUR_STORE_TYPE + toModel:[self managedObjectModel] + orderedModelNames:modelNames + error:&error]) { + NSLog(@"Error migrating to latest model: %@\n %@", error, [error userInfo]); + } + if (![_persistentStoreCoordinator addPersistentStoreWithType:YOUR_STORE_TYPE + configuration:nil + URL:self.dataStoreURL + options:storeOptions + error:&error]) { + [[NSApplication sharedApplication] presentError:error]; + [_persistentStoreCoordinator release]; + _persistentStoreCoordinator = nil; + return nil; + } + + return _persistentStoreCoordinator; +} + +/** + Returns the managed object context for the application (which is already + bound to the persistent store coordinator for the application.) + */ + +- (NSManagedObjectContext *)managedObjectContext +{ + if (_managedObjectContext) return _managedObjectContext; + + NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator; + + if (!coordinator) { + NSError *error = nil; + NSAlert *alert; + + alert = [NSAlert alertWithMessageText:@"Failed to load the store database" defaultButton:@"Reset" alternateButton:@"Cancel" otherButton:nil informativeTextWithFormat:@"By clicking on reset you will loose the connection information"]; + alert.alertStyle = NSCriticalAlertStyle; + switch ([alert runModal]) { + case 0: + return nil; + break; + case 1: + + if ([[NSFileManager defaultManager] removeItemAtURL:self.dataStoreURL error:&error]) { + coordinator = self.persistentStoreCoordinator; + if (!coordinator) { + return nil; + } + } else { + [[NSApplication sharedApplication] presentError:error]; + return nil; + } + break; + + default: + return nil; + break; + }; + } + _managedObjectContext = [[NSManagedObjectContext alloc] init]; + [_managedObjectContext setPersistentStoreCoordinator:coordinator]; + + return _managedObjectContext; +} + +/** + Returns the NSUndoManager for the application. In this case, the manager + returned is that of the managed object context for the application. + */ + +- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window +{ + return self.managedObjectContext.undoManager; +} + +- (void)dockOpenConnectionAction:(NSMenuItem *)menuItem +{ + MHConnectionStore *connectionStore; + + connectionStore = [self connectionStoreWithAlias:menuItem.title]; + if (connectionStore) { + [self openConnection:connectionStore]; + } +} + +- (void)checkForUpdatesEveryDay:(id)sender +{ + [self.updater checkForUpdatesInBackground]; + [self performSelector:@selector(checkForUpdatesEveryDay:) withObject:nil afterDelay:3600 * 24]; +} + +- (MHConnectionWindowController *)connectionWindowControllerForConnectionStore:(MHConnectionStore *)connection +{ + for (MHConnectionWindowController *controller in self.connectionWindowControllers) { + if (controller.connectionStore == connection) { + return controller; + } + } + return nil; +} + +- (void)closingWindowPreferenceController:(NSNotification *)notification +{ + if (notification.object == self.preferenceWindowController) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:notification.object]; + self.preferenceWindowController = nil; + } +} + +- (MHSoftwareUpdateChannel)softwareUpdateChannel +{ + NSString *value; + MHSoftwareUpdateChannel result = MHSoftwareUpdateChannelDefault; + + value = [NSUserDefaults.standardUserDefaults objectForKey:MHSofwareUpdateChannelKey]; + if ([value isEqualToString:@"beta"]) { + result = MHSoftwareUpdateChannelBeta; + } + return result; +} + +- (void)setSoftwareUpdateChannel:(MHSoftwareUpdateChannel)value +{ + switch (value) { + case MHSoftwareUpdateChannelDefault: + [NSUserDefaults.standardUserDefaults removeObjectForKey:MHSofwareUpdateChannelKey]; + break; + + case MHSoftwareUpdateChannelBeta: + [NSUserDefaults.standardUserDefaults setObject:@"beta" forKey:MHSofwareUpdateChannelKey]; + break; + } + [NSUserDefaults.standardUserDefaults synchronize]; + [self.updater checkForUpdatesInBackground]; +} + +- (uint32_t)defaultConnectTimeout +{ + return MODClient.defaultConnectTimeout; +} + +- (void)setConnectTimeout:(uint32_t)connectTimeout +{ + if (connectTimeout == 0 || connectTimeout == MODClient.defaultConnectTimeout) { + [NSUserDefaults.standardUserDefaults removeObjectForKey:MHConnectTimeoutKey]; + } else { + [NSUserDefaults.standardUserDefaults setInteger:connectTimeout forKey:MHConnectTimeoutKey]; + } +} + +- (uint32_t)connectTimeout +{ + return (uint32_t)[NSUserDefaults.standardUserDefaults integerForKey:MHConnectTimeoutKey]; +} + +- (uint32_t)defaultSocketTimeout +{ + return MODClient.defaultSocketTimeout; +} + +- (void)setSocketTimeout:(uint32_t)socketTimeout +{ + if (socketTimeout == 0 || socketTimeout == MODClient.defaultSocketTimeout) { + [NSUserDefaults.standardUserDefaults removeObjectForKey:MHSocketTimeoutKey]; + } else { + [NSUserDefaults.standardUserDefaults setInteger:socketTimeout forKey:MHSocketTimeoutKey]; + } +} + +- (uint32_t)socketTimeout +{ + return (uint32_t)[NSUserDefaults.standardUserDefaults integerForKey:MHSocketTimeoutKey]; +} + +@end + +@implementation MHApplicationDelegate (NSApplicationDelegate) + +-(void)applicationWillFinishLaunching:(NSNotification *)aNotification +{ + NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; + [appleEventManager setEventHandler:self + andSelector:@selector(handleGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass andEventID:kAEGetURL]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + self.bundleVersion.stringValue = [NSString stringWithFormat:@"version: %@", [NSBundle.mainBundle.infoDictionary objectForKey:@"CFBundleShortVersionString"]]; + + self.updater = [[[SUUpdater alloc] init] autorelease]; + self.updater.sendsSystemProfile = YES; + self.updater.delegate = self; + [self checkForUpdatesEveryDay:nil]; +} + +- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender +{ + BOOL windowVisible = NO; + + for (NSWindow *window in [NSApp windows]) { + windowVisible = windowVisible || window.isVisible; + } + if (!windowVisible) { + [self.window makeKeyAndOrderFront:nil]; + } + return NO; +} + +- (void)applicationDidBecomeActive:(NSNotification *)notification +{ + BOOL windowVisible = NO; + + for (NSWindow *window in [NSApp windows]) { + windowVisible = windowVisible || window.isVisible; + } + if (!windowVisible) { + [self.window makeKeyAndOrderFront:nil]; + } +} + +- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)files +{ + NSString *aPath = [files lastObject]; // just an example to get at one of the paths + + if (aPath && [aPath hasSuffix:YOUR_EXTERNAL_RECORD_EXTENSION]) { + // decode URI from path + NSURL *objectURI = [[NSPersistentStoreCoordinator elementsDerivedFromExternalRecordURL:[NSURL fileURLWithPath:aPath]] objectForKey:NSObjectURIKey]; + if (objectURI) { + NSManagedObjectID *moid = [[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:objectURI]; + if (moid) { + NSManagedObject *mo = [[self managedObjectContext] objectWithID:moid]; + NSLog(@"The record for path %@ is %@",moid,mo); + + // your code to select the object in your application's UI + } + + } + } + +} + +- (NSMenu *)applicationDockMenu:(NSApplication *)sender +{ + NSMenu *menu; + NSMenu *subMenu; + NSMenuItem *menuItem; + + menu = [[NSMenu alloc] init]; + subMenu = [[NSMenu alloc] init]; + menuItem = [menu addItemWithTitle:@"Connections" action:nil keyEquivalent:@""]; + + [menu setSubmenu:subMenu forItem:menuItem]; + for (MHConnectionStore *connectionStore in self.connectionsArrayController.arrangedObjects) { + menuItem = [subMenu addItemWithTitle:connectionStore.alias action:nil keyEquivalent:@""]; + menuItem.target = self; + menuItem.action = @selector(dockOpenConnectionAction:); + } + [subMenu release]; + return [menu autorelease]; +} + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication +{ + return NO; +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + if (!_managedObjectContext) return NSTerminateNow; + + if (![_managedObjectContext commitEditing]) { + NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd)); + return NSTerminateCancel; + } + + if (![_managedObjectContext hasChanges]) return NSTerminateNow; + + NSError *error = nil; + if (![_managedObjectContext save:&error]) { + + // This error handling simply presents error information in a panel with an + // "Ok" button, which does not include any attempt at error recovery (meaning, + // attempting to fix the error.) As a result, this implementation will + // present the information to the user and then follow up with a panel asking + // if the user wishes to "Quit Anyway", without saving the changes. + + // Typically, this process should be altered to include application-specific + // recovery steps. + + BOOL result = [sender presentError:error]; + if (result) return NSTerminateCancel; + + NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message"); + NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info"); + NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title"); + NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title"); + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:question]; + [alert setInformativeText:info]; + [alert addButtonWithTitle:quitButton]; + [alert addButtonWithTitle:cancelButton]; + + NSInteger answer = [alert runModal]; + [alert release]; + alert = nil; + + if (answer == NSAlertAlternateReturn) return NSTerminateCancel; + + } + + return NSTerminateNow; +} + +@end + +@implementation MHApplicationDelegate (Action) + +- (IBAction)checkForUpdatesAction:(id)sender +{ + [self.updater checkForUpdates:sender]; +} + +- (IBAction)openSupportPanel:(id)sender +{ + [NSApp beginSheet:self.supportPanel modalForWindow:self.window modalDelegate:self didEndSelector:@selector(supportPanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; +} + +- (void)supportPanelDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo +{ + [sheet close]; +} + +- (IBAction)closeSupportPanel:(id)sender +{ + [NSApp endSheet:self.supportPanel]; +} + +- (IBAction)openFeatureRequestBugReport:(id)sender +{ + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/jeromelebel/MongoHub-Mac/issues"]]; +} + +- (IBAction)openConnectionWindow:(id)sender +{ + [self.window makeKeyAndOrderFront:sender]; +} + +- (IBAction)openPreferenceWindow:(id)sender +{ + if (!self.preferenceWindowController) { + self.preferenceWindowController = [MHPreferenceWindowController preferenceWindowController]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closingWindowPreferenceController:) name:MHPreferenceWindowControllerClosing object:self.preferenceWindowController]; + } + [self.preferenceWindowController showWindow:sender]; +} + +- (IBAction)openLogWindow:(id)sender +{ + if (!self.logWindowController) { + self.logWindowController = [MHLogWindowController logWindowController]; + self.logWindowController.delegate = self; + [MODClient setLogCallback:^(MODLogLevel level, const char *domain, const char *message) { + [self.logWindowController addLogLine:[NSString stringWithUTF8String:message] domain:[NSString stringWithFormat:@"mongoc.%s", domain] level:[MODClient logLevelStringForLogLevel:level]]; + }]; + } + [self.logWindowController showWindow:self]; +} + +@end + +@implementation MHApplicationDelegate (ConnexionManager) + +- (void)saveConnections +{ + NSError *error = nil; + + if (![[self managedObjectContext] commitEditing]) { + NSLog(@"%@:%@ unable to commit editing before saving", [self class], NSStringFromSelector(_cmd)); + } + + if (![[self managedObjectContext] save:&error]) { + [[NSApplication sharedApplication] presentError:error]; + } +} + +- (MHConnectionStore *)connectionStoreWithAlias:(NSString *)alias +{ + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"alias=%@", alias]; + NSArray *items = [self.connectionsArrayController itemsUsingFetchPredicate:predicate]; + return (items.count == 1)?[items objectAtIndex:0]:nil; +} + +- (void)openConnection:(MHConnectionStore *)connection +{ + MHConnectionWindowController *connectionWindowController; + + connectionWindowController = [self connectionWindowControllerForConnectionStore:connection]; + if (connectionWindowController) { + [connectionWindowController showWindow:nil]; + } else { + connectionWindowController = [[MHConnectionWindowController alloc] init]; + connectionWindowController.delegate = self; + connectionWindowController.connectionStore = connection; + [connectionWindowController showWindow:self]; + [self.connectionWindowControllers addObject:connectionWindowController]; + [connectionWindowController release]; + } +} + +- (void)deleteConnection:(MHConnectionStore *)connection +{ + [self.connectionsArrayController removeObject:connection]; + [self saveConnections]; + [self.connectionsArrayController setSelectedObjects:@[]]; +} + +@end + +@implementation MHApplicationDelegate (SUUpdate) + ++ (NSString *)systemVersionString +{ + return [[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"]; +} + ++ (id)defaultComparator +{ + id comparator = [NSClassFromString(@"SUStandardVersionComparator") performSelector:@selector(defaultComparator)]; + + NSAssert(comparator != nil, @"cannot get an instance of 'SUStandardVersionComparator'"); + return comparator; +} + +- (BOOL)hostSupportsItem:(SUAppcastItem *)ui +{ + if ([ui minimumSystemVersion] == nil || [[ui minimumSystemVersion] isEqualToString:@""]) { return YES; } + + BOOL minimumVersionOK = TRUE; + + // Check minimum and maximum System Version + if ([ui minimumSystemVersion] != nil && ![[ui minimumSystemVersion] isEqualToString:@""]) { + minimumVersionOK = [[MHApplicationDelegate defaultComparator] compareVersion:[ui minimumSystemVersion] toVersion:[MHApplicationDelegate systemVersionString]] != NSOrderedDescending; + } + + return minimumVersionOK; +} + +- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle +{ + SUAppcastItem *result = nil; + BOOL shouldUseBeta; + id comparator = [MHApplicationDelegate defaultComparator]; + + // use beta if the user wants to use beta, or if we are using a beta version right now + shouldUseBeta = self.softwareUpdateChannel == MHSoftwareUpdateChannelBeta + || [NSBundle.mainBundle.infoDictionary[@"CFBundleShortVersionString"] rangeOfString:@"b"].location != NSNotFound; + for (SUAppcastItem *item in appcast.items) { + if ([self hostSupportsItem:item] && (shouldUseBeta || ![[item.propertiesDictionary objectForKey:@"beta"] isEqualToString:@"1"])) { + if (result == nil) { + result = item; + } else if ([comparator compareVersion:result.versionString toVersion:item.versionString] != NSOrderedDescending) { + result = item; + } + } + } + return result; +} + +- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent +{ + MHConnectionStore *connectionStore; + NSEntityDescription *entity; + NSString *errorMessage; + NSString *stringURL; + MHConnectionEditorWindowController *controller; + + entity = [NSEntityDescription entityForName:@"Connection" inManagedObjectContext:self.managedObjectContext]; + stringURL = [event paramDescriptorForKeyword:keyDirectObject].stringValue; + connectionStore = [[[MHConnectionStore alloc] initWithEntity:entity insertIntoManagedObjectContext:nil] autorelease]; + if (![connectionStore setValuesFromStringURL:stringURL errorMessage:&errorMessage]) { + [[NSAlert alertWithMessageText:errorMessage defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", stringURL] runModal]; + return; + } + + controller = [[[MHConnectionEditorWindowController alloc] init] autorelease]; + controller.delegate = self; + controller.connectionStoreDefaultValue = connectionStore; + controller.window.title = stringURL; + [controller showWindow:nil]; + [self.urlConnectionEditorWindowControllers addObject:controller]; +} + +@end + +@implementation MHApplicationDelegate(MHConnectionEditorWindowControllerDelegate) + +- (void)connectionWindowControllerDidCancel:(MHConnectionEditorWindowController *)controller +{ + [self.urlConnectionEditorWindowControllers removeObject:controller]; +} + +- (void)connectionWindowControllerDidValidate:(MHConnectionEditorWindowController *)controller +{ + [self saveConnections]; + [self.urlConnectionEditorWindowControllers removeObject:controller]; +} + +- (MHConnectionStore *)connectionWindowController:(MHConnectionEditorWindowController *)controller connectionStoreWithAlias:(NSString *)alias +{ + return [self connectionStoreWithAlias:alias]; +} + +@end + +@implementation MHApplicationDelegate (MHConnectionWindowControllerDelegate) + +- (void)connectionWindowControllerWillClose:(MHConnectionWindowController *)controller +{ + [self.connectionWindowControllers removeObject:controller]; +} + +- (BOOL)connectionWindowControllerSSHVerbose:(MHConnectionWindowController *)controller +{ + return [[NSProcessInfo processInfo].environment[@"SSH_VERBOSE"] integerValue] != 0; +} + +- (void)connectionWindowControllerLogMessage:(NSString *)message domain:(NSString *)domain level:(NSString *)level +{ + [self.logWindowController addLogLine:message domain:domain level:level]; +} + +@end + + +@implementation MHApplicationDelegate (MHLogWindowControllerDelegate) + +- (void)logWindowControllerWillClose:(MHLogWindowController *)logWindowController +{ + if (logWindowController == self.logWindowController) { + self.logWindowController = nil; + [MODClient setLogCallback:nil]; + } +} + +@end + +#define CollectionTabsKey @"CollectionTabs" +#define MapReduceTabKey @"MapReduceTab" +#define AggregationKey @"Aggregation" + +@implementation MHApplicationDelegate (Preferences) + +- (BOOL)hasCollectionMapReduceTab +{ + if ([[NSUserDefaults standardUserDefaults] dictionaryForKey:CollectionTabsKey][MapReduceTabKey]) { + return [[[NSUserDefaults standardUserDefaults] dictionaryForKey:CollectionTabsKey][MapReduceTabKey] boolValue]; + } else { + return NO; + } +} + +- (void)setCollectionMapReduceTab:(BOOL)value +{ + NSMutableDictionary *values = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:CollectionTabsKey] mutableCopy]; + + if (!values) { + values = [[NSMutableDictionary alloc] init]; + } + values[MapReduceTabKey] = @(value); + [[NSUserDefaults standardUserDefaults] setObject:values forKey:CollectionTabsKey]; + MOD_RELEASE(values); + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (BOOL)hasCollectionAggregationTab +{ + if ([[NSUserDefaults standardUserDefaults] dictionaryForKey:CollectionTabsKey][AggregationKey]) { + return [[[NSUserDefaults standardUserDefaults] dictionaryForKey:CollectionTabsKey][AggregationKey] boolValue]; + } else { + return YES; + } +} + +- (void)setCollectionAggregationTab:(BOOL)value +{ + NSMutableDictionary *values = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:CollectionTabsKey] mutableCopy]; + + if (!values) { + values = [[NSMutableDictionary alloc] init]; + } + values[AggregationKey] = @(value); + [[NSUserDefaults standardUserDefaults] setObject:values forKey:CollectionTabsKey]; + MOD_RELEASE(values); + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end diff --git a/Sources/MHLogWindowController.h b/Sources/MHLogWindowController.h new file mode 100644 index 00000000..b75ee019 --- /dev/null +++ b/Sources/MHLogWindowController.h @@ -0,0 +1,29 @@ +// +// MHLogWindowController.h +// MongoHub +// +// Created by Jérôme Lebel on 28/08/2014. +// +// + +#import + +@class MHLogWindowController; + +@protocol MHLogWindowControllerDelegate +- (void)logWindowControllerWillClose:(MHLogWindowController *)logWindowController; +@end + +@interface MHLogWindowController : NSWindowController +{ + NSTableView *_logTableView; + id _delegate; +} + +@property (nonatomic, readwrite, weak) id delegate; + ++ (instancetype)logWindowController; + +- (void)addLogLine:(NSString *)line domain:(NSString *)domain level:(NSString *)level; + +@end diff --git a/Sources/MHLogWindowController.m b/Sources/MHLogWindowController.m new file mode 100644 index 00000000..18b14c4e --- /dev/null +++ b/Sources/MHLogWindowController.m @@ -0,0 +1,93 @@ +// +// MHLogWindowController.m +// MongoHub +// +// Created by Jérôme Lebel on 28/08/2014. +// +// + +#import "MHLogWindowController.h" + +@interface MHLogWindowController () +@property (nonatomic, readwrite, strong) NSMutableArray *logs; +@property (nonatomic, readwrite, weak) IBOutlet NSTableView *logTableView; + +@end + +@implementation MHLogWindowController + +@synthesize logTableView = _logTableView; +@synthesize delegate = _delegate; + ++ (instancetype)logWindowController +{ + return [[[MHLogWindowController alloc] initWithWindowNibName:@"MHLogWindow"] autorelease]; +} + +- (instancetype)initWithWindowNibName:(NSString *)windowNibName +{ + self = [super initWithWindowNibName:windowNibName]; + if (self) { + self.logs = [NSMutableArray array]; + } + return self; +} + +- (void)dealloc +{ + self.logs = nil; + [super dealloc]; +} + +- (void)addLogLine:(NSString *)line domain:(NSString *)domain level:(NSString *)level +{ + if (!NSThread.isMainThread) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self addLogLine:line domain:domain level:level]; + }); + } else { + if (!domain) { + domain = @""; + } + if (!level) { + level = @""; + } + [self willChangeValueForKey:@"logs"]; + [self.logs addObject:@{ @"log": line, @"domain": domain, @"level": level, @"date": [NSDate date] }]; + [self didChangeValueForKey:@"logs"]; + } +} + +- (void)windowWillClose:(NSNotification *)notification +{ + [self.delegate logWindowControllerWillClose:self]; +} + +- (BOOL)validateUserInterfaceItem:(id )anItem +{ + if (anItem.action == @selector(copy:)) { + return self.window.isKeyWindow && self.logTableView.selectedRow > 0; + } else { + return [self respondsToSelector:anItem.action]; + } +} + +- (void)copy:(id)sender +{ + NSIndexSet *selectedRowIndexes = [self.logTableView selectedRowIndexes]; + NSMutableString *result; + + result = [NSMutableString string]; + [selectedRowIndexes enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) { + for (NSUInteger index = range.location; index < range.location + range.length; index++) { + NSDictionary *log = self.logs[index]; + [result appendFormat:@"%@ %@ %@ %@\n", log[@"date"], log[@"domain"], log[@"level"], log[@"log"]]; + } + }]; + NSPasteboard *pasteboard = NSPasteboard.generalPasteboard; + + [pasteboard declareTypes:@[ NSStringPboardType ] owner:nil]; + [pasteboard setString:result forType:NSStringPboardType]; +} + +@end diff --git a/Sources/MHPreferenceWindowController.h b/Sources/MHPreferenceWindowController.h new file mode 100644 index 00000000..53ee9e8b --- /dev/null +++ b/Sources/MHPreferenceWindowController.h @@ -0,0 +1,30 @@ +// +// MHPreferenceWindowController +// MongoHub +// +// Created by Jérôme Lebel on 23/10/2013. +// + +#import +#import + +#define MHPreferenceWindowControllerClosing @"MHPreferenceWindowControllerClosing" +#define MHDefaultSortOrderPreferenceChangedNotification @"MHDefaultSortOrderPreferenceChanged" + +typedef enum { + MHDefaultSortOrderAscending, + MHDefaultSortOrderDescending, +} MHDefaultSortOrder; + +@interface MHPreferenceWindowController : NSWindowController + ++ (instancetype)preferenceWindowController; + +@end + +@interface MHPreferenceWindowController (Preferences) + ++ (MHDefaultSortOrder)defaultSortOrder; ++ (MODJsonKeySortOrder)jsonKeySortOrderInSearch; + +@end \ No newline at end of file diff --git a/Sources/MHPreferenceWindowController.m b/Sources/MHPreferenceWindowController.m new file mode 100644 index 00000000..b42df6ae --- /dev/null +++ b/Sources/MHPreferenceWindowController.m @@ -0,0 +1,336 @@ +// +// MHPreferenceWindowController.m +// MongoHub +// +// Created by Jérôme Lebel on 23/10/2013. +// + +#import "MHPreferenceWindowController.h" +#import "MHApplicationDelegate.h" +#import "MHJsonColorManager.h" + +#define MHDefaultSortOrderPreferenceKey @"MHDefaultSortOrderPreferenceKey" +#define MODJsonKeySortOrderInSearchPreferenceKey @"MODJsonKeySortOrderInSearchPreferenceKey" + +@interface MHPreferenceWindowController () + +@property (nonatomic, weak, readwrite) IBOutlet NSButton *betaSoftwareButton; +@property (nonatomic, weak, readwrite) IBOutlet NSColorWell *textBackgroundColorWell; +@property (nonatomic, weak, readwrite) IBOutlet NSTableView *jsonColorTableView; +@property (nonatomic, weak, readwrite) IBOutlet NSTextField *jsonTextLabelView; +@property (nonatomic, weak, readwrite) IBOutlet NSColorWell *jsonTextColorWell; + +@property (nonatomic, strong, readwrite) NSMutableArray *jsonComponents; + +@property (nonatomic, weak, readwrite) IBOutlet NSTextField *connectTimeoutTextField; +@property (nonatomic, weak, readwrite) IBOutlet NSTextField *socketTimeoutTextField; + +@property (nonatomic, weak, readwrite) IBOutlet NSPopUpButton *defaultSortOrder; +@property (nonatomic, weak, readwrite) IBOutlet NSPopUpButton *jsonKeySortOrderInSearch; +@property (nonatomic, weak, readwrite) IBOutlet NSPopUpButton *collectionTabPopUpButton; + +@end + +@interface MHPreferenceWindowController (NSTableView) +@end + +@implementation MHPreferenceWindowController +{ + NSButton *_betaSoftwareButton; + NSColorWell *_textBackgroundColorWell; + NSTableView *_jsonColorTableView; + NSTextField *_jsonTextLabelView; + NSColorWell *_jsonTextColorWell; + + NSPopUpButton *_defaultSortOrder; + NSPopUpButton *_jsonKeySortOrderInSearch; + + NSTextField *_connectTimeoutTextField; + NSTextField *_socketTimeoutTextField; + NSPopUpButton *_collectionTabPopUpButton; +} + +@synthesize betaSoftwareButton = _betaSoftwareButton; +@synthesize textBackgroundColorWell = _textBackgroundColorWell; +@synthesize jsonColorTableView = _jsonColorTableView; +@synthesize jsonTextLabelView = _jsonTextLabelView; +@synthesize jsonTextColorWell = _jsonTextColorWell; + +@synthesize connectTimeoutTextField = _connectTimeoutTextField; +@synthesize socketTimeoutTextField = _socketTimeoutTextField; + +@synthesize defaultSortOrder = _defaultSortOrder; +@synthesize jsonKeySortOrderInSearch = _jsonKeySortOrderInSearch; +@synthesize collectionTabPopUpButton = _collectionTabPopUpButton; + ++ (MHPreferenceWindowController *)preferenceWindowController +{ + MHPreferenceWindowController *result; + result = [[[MHPreferenceWindowController alloc] initWithWindowNibName:@"MHPreferenceWindow"] autorelease]; + return result; +} + +- (void)awakeFromNib +{ + NSMutableSet *componentNames = [NSMutableSet set]; + uint32_t value; + MHApplicationDelegate *appDelegate = (MHApplicationDelegate *)NSApplication.sharedApplication.delegate; + + if ([appDelegate softwareUpdateChannel] == MHSoftwareUpdateChannelBeta) { + self.betaSoftwareButton.state = NSOnState; + } else { + self.betaSoftwareButton.state = NSOffState; + } + self.textBackgroundColorWell.color = MHJsonColorManager.sharedManager.values[@"TextField"][@"Background"][@"Color"]; + + self.jsonComponents = [NSMutableArray array]; + for (NSDictionary *component in [MHJsonColorManager.sharedManager.values[@"Components"] allValues]) { + if (![componentNames containsObject:component[@"Name"]]) { + NSMutableDictionary *newComponent = [component mutableCopy]; + + [self.jsonComponents addObject:newComponent]; + [componentNames addObject:newComponent[@"Name"]]; + [newComponent release]; + } + } + [self.jsonComponents sortUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) { + return [obj1[@"Name"] compare:obj2[@"Name"]]; + }]; + self.jsonColorTableView.backgroundColor = self.textBackgroundColorWell.color; + [self updateRowSize]; + + self.jsonTextLabelView.font = MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"]; + self.jsonTextLabelView.stringValue = @" "; + [self.jsonTextLabelView sizeToFit]; + + [self.socketTimeoutTextField.cell setPlaceholderString:[NSString stringWithFormat:@"%u", [(MHApplicationDelegate *)[NSApp delegate] defaultSocketTimeout]]]; + value = [(MHApplicationDelegate *)[NSApp delegate] socketTimeout]; + if (value != 0) { + self.socketTimeoutTextField.stringValue = [NSString stringWithFormat:@"%u", value]; + } + [self.connectTimeoutTextField.cell setPlaceholderString:[NSString stringWithFormat:@"%u", [(MHApplicationDelegate *)[NSApp delegate] defaultConnectTimeout]]]; + value = [(MHApplicationDelegate *)[NSApp delegate ] connectTimeout]; + if (value != 0) { + self.connectTimeoutTextField.stringValue = [NSString stringWithFormat:@"%u", value]; + } + [self.defaultSortOrder selectItemAtIndex:[self.class defaultSortOrder]]; + [self.jsonKeySortOrderInSearch selectItemAtIndex:[self.class jsonKeySortOrderInSearch]]; + + if (appDelegate.hasCollectionAggregationTab && appDelegate.hasCollectionMapReduceTab) { + [self.collectionTabPopUpButton selectItemWithTag:2]; + } else if (appDelegate.hasCollectionMapReduceTab) { + [self.collectionTabPopUpButton selectItemWithTag:1]; + } else { + [self.collectionTabPopUpButton selectItemWithTag:0]; + } + +} + +- (IBAction)betaSoftwareAction:(id)sender +{ + if (self.betaSoftwareButton.state == NSOffState) { + [(MHApplicationDelegate *)NSApplication.sharedApplication.delegate setSoftwareUpdateChannel:MHSoftwareUpdateChannelDefault]; + } else { + [(MHApplicationDelegate *)NSApplication.sharedApplication.delegate setSoftwareUpdateChannel:MHSoftwareUpdateChannelBeta]; + } +} + +- (IBAction)openFontPanelForJsonAction:(id)sender +{ + [NSFontManager sharedFontManager].delegate = self; + [NSFontManager sharedFontManager].action = @selector(changeJsonFont:); + [[[NSFontManager sharedFontManager] fontPanel:YES] setPanelFont:MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"] isMultiple:NO]; + [[NSFontManager sharedFontManager] orderFrontFontPanel:nil]; +} + +- (IBAction)changeDefaultSortOrderAction:(id)sender +{ + [[NSUserDefaults standardUserDefaults] setInteger:self.defaultSortOrder.indexOfSelectedItem forKey:MHDefaultSortOrderPreferenceKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + [[NSNotificationCenter defaultCenter] postNotificationName:MHDefaultSortOrderPreferenceChangedNotification object:self]; +} + +- (IBAction)changeJsonKeySortOrderInSearchAction:(id)sender +{ + [[NSUserDefaults standardUserDefaults] setInteger:self.jsonKeySortOrderInSearch.indexOfSelectedItem forKey:MODJsonKeySortOrderInSearchPreferenceKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (void)changeJsonFont:(NSFontManager *)fontManager +{ + MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"] = [fontManager convertFont:MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"]]; + self.jsonTextLabelView.font = MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"]; + [self.jsonTextLabelView sizeToFit]; + [MHJsonColorManager.sharedManager valueUpdated]; + [self updateRowSize]; + [self.jsonColorTableView reloadData]; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + [[NSNotificationCenter defaultCenter] postNotificationName:MHPreferenceWindowControllerClosing object:self]; + [MHJsonColorManager.sharedManager save]; +} + +- (IBAction)jsonBackgroundColorWellAction:(id)sender +{ + self.jsonColorTableView.backgroundColor = self.textBackgroundColorWell.color; + MHJsonColorManager.sharedManager.values[@"TextField"][@"Background"][@"Color"] = self.textBackgroundColorWell.color; + [MHJsonColorManager.sharedManager valueUpdated]; +} + +- (IBAction)jsonTextColorWellAction:(id)sender +{ + if (self.jsonColorTableView.selectedRowIndexes.count > 0) { + NSUInteger index; + NSIndexSet *selectedRows; + + selectedRows = [self.jsonColorTableView.selectedRowIndexes mutableCopy]; + index = selectedRows.firstIndex; + if (index == 0) { + MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Color"] = self.jsonTextColorWell.color; + MHJsonColorManager.sharedManager.values[@"TextField"][@"InsertPoint"][@"Color"] = self.jsonTextColorWell.color; + } else { + self.jsonComponents[index - 1][@"Color"] = self.jsonTextColorWell.color; + for (NSMutableDictionary *component in [MHJsonColorManager.sharedManager.values[@"Components"] allValues]) { + if ([component[@"Name"] isEqualToString:self.jsonComponents[index - 1][@"Name"]]) { + component[@"Color"] = self.jsonTextColorWell.color; + } + } + } + [MHJsonColorManager.sharedManager valueUpdated]; + [self.jsonColorTableView reloadData]; + [self.jsonColorTableView selectRowIndexes:selectedRows byExtendingSelection:NO]; + [selectedRows release]; + } +} + +- (NSTextField *)jsonColorTableViewTextField +{ + NSTextField *result; + + result = [[[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 10, 10)] autorelease]; + result.identifier = @"MyView"; + result.font = MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"]; + result.enabled = YES; + result.editable = NO; + result.bordered = NO; + result.drawsBackground = NO; + return result; +} + +- (void)updateRowSize +{ + NSTextField *textField; + + textField = [self jsonColorTableViewTextField]; + textField.stringValue = @"ASFWBHDfqlahbjiu"; + [textField sizeToFit]; + self.jsonColorTableView.rowHeight = textField.bounds.size.height; +} + +@end + +@implementation MHPreferenceWindowController (AdvancedTab) + +- (IBAction)timeoutTextFieldChanged:(id)sender +{ + uint32_t value; + + value = (uint32_t)[sender stringValue].integerValue; + if (value < 500 && value != 0) { + NSBeginAlertSheet(@"Invalid Value", @"OK", nil, nil, self.window, nil, nil, nil, nil, @"The timeout should be greater than 500"); + } else if (sender == self.connectTimeoutTextField) { + [(MHApplicationDelegate *)[NSApp delegate] setConnectTimeout:value]; + if ([(MHApplicationDelegate *)[NSApp delegate] connectTimeout] == 0) { + self.connectTimeoutTextField.stringValue = @""; + } + } else if (sender == self.socketTimeoutTextField) { + [(MHApplicationDelegate *)[NSApp delegate] setSocketTimeout:value]; + if ([(MHApplicationDelegate *)[NSApp delegate] socketTimeout] == 0) { + self.socketTimeoutTextField.stringValue = @""; + } + } +} + +- (IBAction)collectionTabAction:(id)sender +{ + MHApplicationDelegate *appDelegate = (MHApplicationDelegate *)NSApplication.sharedApplication.delegate; + + switch (self.collectionTabPopUpButton.selectedTag) { + case 0: + [appDelegate setCollectionAggregationTab:YES]; + [appDelegate setCollectionMapReduceTab:NO]; + break; + case 1: + [appDelegate setCollectionAggregationTab:NO]; + [appDelegate setCollectionMapReduceTab:YES]; + break; + case 2: + [appDelegate setCollectionAggregationTab:YES]; + [appDelegate setCollectionMapReduceTab:YES]; + break; + + default: + NSAssert(NO, @"unknown tag %ld", (long)self.collectionTabPopUpButton.selectedTag); + break; + } +} + +@end + +@implementation MHPreferenceWindowController (NSTableView) + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + return self.jsonComponents.count + 1; +} + +- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + NSTextField *result; + + result = [tableView makeViewWithIdentifier:@"MyView" owner:nil]; + if (!result) { + result = [self jsonColorTableViewTextField]; + } + result.font = MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Font"]; + if (row == 0) { + result.stringValue = @"Regular Text"; + result.textColor = MHJsonColorManager.sharedManager.values[@"TextField"][@"Text"][@"Color"]; + } else { + result.stringValue = self.jsonComponents[row - 1][@"Name"]; + result.textColor = self.jsonComponents[row - 1][@"Color"]; + } + return result; +} + +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + if (self.jsonColorTableView.selectedRowIndexes.count > 0) { + NSTextField *cellView; + + cellView = (NSTextField *)[self tableView:self.jsonColorTableView viewForTableColumn:self.jsonColorTableView.tableColumns[0] row:self.jsonColorTableView.selectedRowIndexes.firstIndex]; + self.jsonTextLabelView.stringValue = cellView.stringValue; + self.jsonTextColorWell.color = cellView.textColor; + } else { + self.jsonTextLabelView.stringValue = @" "; + } +} + +@end + + +@implementation MHPreferenceWindowController (Preferences) + ++ (MHDefaultSortOrder)defaultSortOrder +{ + return (MHDefaultSortOrder)[[NSUserDefaults standardUserDefaults] integerForKey:MHDefaultSortOrderPreferenceKey]; +} + ++ (MODJsonKeySortOrder)jsonKeySortOrderInSearch +{ + return (MODJsonKeySortOrder)[[NSUserDefaults standardUserDefaults] integerForKey:MODJsonKeySortOrderInSearchPreferenceKey]; +} + +@end diff --git a/Sources/Model/ALIterativeMigrator.h b/Sources/Model/ALIterativeMigrator.h new file mode 100644 index 00000000..f18c2105 --- /dev/null +++ b/Sources/Model/ALIterativeMigrator.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2013, Art & Logic + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are those + of the authors and should not be interpreted as representing official policies, + either expressed or implied, of the FreeBSD Project. + */ + +#import +#import + +/** + * Iteratively migrates a persistent Core Data store along a series of ordered + * managed object models. Allows for easily mixing inferred migrations + * with mapping models and custom migrations. + */ +@interface ALIterativeMigrator : NSObject + +/** + * Iteratively migrates the store at the given URL from its current model + * to the given finalModel in order through the list of modelNames. + * + * Does nothing (returns YES) if the persistent store does not yet exist + * at the given sourceStoreURL. + * + * @param sourceStoreURL The file URL to the persistent store file. + * @param sourceStoreType The type of store at sourceStoreURL + * (see NSPersistentStoreCoordinator for possible values). + * @param finalModel The final target managed object model for the migration manager. + * At the end of the migration, the persistent store should be migrated + * to this model. + * @param modelNames *.mom file names for each of the managed object models + * through which the persistent store might need to be migrated. + * The model names should be ordered in such a way that migration + * from one to the next can occur either using a custom mapping model + * or an inferred mapping model. + * The *.mom files should be stored in the top level of the main bundle. + * @param error If an error occurs during the migration, upon return contains + * an NSError object that describes the problem. + * + * @return YES if the migration proceeds without errors, otherwise NO. + */ ++ (BOOL)iterativeMigrateURL:(NSURL*)sourceStoreURL + ofType:(NSString*)sourceStoreType + toModel:(NSManagedObjectModel*)finalModel + orderedModelNames:(NSArray*)modelNames + error:(NSError**)error; + +/** + * Migrates the store at the given URL from one object model to another + * using the given mapping model. Writes the store to a temporary file + * during migration so that if migration fails, the original store is left intact. + * + * @param sourceStoreURL The file URL to the persistent store file. + * @param sourceStoreType The type of store at sourceStoreURL + * (see NSPersistentStoreCoordinator for possible values). + * @param sourceModel The source managed object model for the migration manager. + * @param targetModel The target managed object model for the migration manager. + * @param mappingModel The mapping model to use to effect the migration. + * @param error If an error occurs during the migration, upon return contains + * an NSError object that describes the problem. + * + * @return YES if the migration proceeds without errors, otherwise NO. + */ ++ (BOOL)migrateURL:(NSURL*)sourceStoreURL + ofType:(NSString*)sourceStoreType + fromModel:(NSManagedObjectModel*)sourceModel + toModel:(NSManagedObjectModel*)targetModel + mappingModel:(NSMappingModel*)mappingModel + error:(NSError**)error; + +/** + * Returns the error domain used in NSErrors created by this class. + */ ++ (NSString*)errorDomain; + +@end \ No newline at end of file diff --git a/Sources/Model/ALIterativeMigrator.m b/Sources/Model/ALIterativeMigrator.m new file mode 100644 index 00000000..085e7338 --- /dev/null +++ b/Sources/Model/ALIterativeMigrator.m @@ -0,0 +1,364 @@ +/* + Copyright (c) 2013, Art & Logic + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are those + of the authors and should not be interpreted as representing official policies, + either expressed or implied, of the FreeBSD Project. + */ + +#import "ALIterativeMigrator.h" + +@implementation ALIterativeMigrator + ++ (BOOL)iterativeMigrateURL:(NSURL*)sourceStoreURL + ofType:(NSString*)sourceStoreType + toModel:(NSManagedObjectModel*)finalModel + orderedModelNames:(NSArray*)modelNames + error:(NSError**)error +{ + // If the persistent store does not exist at the given URL, + // assume that it hasn't yet been created and return success immediately. + if (NO == [[NSFileManager defaultManager] fileExistsAtPath:[sourceStoreURL path]]) + { + return YES; + } + + // Get the persistent store's metadata. The metadata is used to + // get information about the store's managed object model. + NSDictionary* sourceMetadata = + [self metadataForPersistentStoreOfType:sourceStoreType + URL:sourceStoreURL + error:error]; + if (nil == sourceMetadata) + { + return NO; + } + + // Check whether the final model is already compatible with the store. + // If it is, no migration is necessary. + if ([finalModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata]) + { + return YES; + } + + // Find the current model used by the store. + NSManagedObjectModel* sourceModel = + [self modelForStoreMetadata:sourceMetadata error:error]; + if (nil == sourceModel) + { + return NO; + } + + // Get NSManagedObjectModels for each of the model names given. + NSArray* models = [self modelsNamed:modelNames error:error]; + if (nil == models) + { + return NO; + } + + // Build an inclusive list of models between the source and final models. + NSMutableArray* relevantModels = [NSMutableArray array]; + BOOL firstFound = NO; + BOOL lastFound = NO; + BOOL reverse = NO; + for (NSManagedObjectModel* model in models) + { + if ([model isEqual:sourceModel] || [model isEqual:finalModel]) + { + if (firstFound) + { + lastFound = YES; + // In case a reverse migration is being performed (descending through the + // ordered array of models), check whether the source model is found + // after the final model. + reverse = [model isEqual:sourceModel]; + } + else + { + firstFound = YES; + } + } + + if (firstFound) + { + [relevantModels addObject:model]; + } + + if (lastFound) + { + break; + } + } + + // Ensure that the source model is at the start of the list. + if (reverse) + { + relevantModels = + [[[relevantModels reverseObjectEnumerator] allObjects] mutableCopy]; + } + + // Migrate through the list + for (int i = 0; i < ([relevantModels count] - 1); i++) + { + NSManagedObjectModel* modelA = [relevantModels objectAtIndex:i]; + NSManagedObjectModel* modelB = [relevantModels objectAtIndex:(i + 1)]; + + // Check whether a custom mapping model exists. + NSMappingModel* mappingModel = [NSMappingModel mappingModelFromBundles:nil + forSourceModel:modelA + destinationModel:modelB]; + + // If there is no custom mapping model, try to infer one. + if (nil == mappingModel) + { + mappingModel = [NSMappingModel inferredMappingModelForSourceModel:modelA + destinationModel:modelB + error:error]; + if (nil == mappingModel) + { + return NO; + } + } + + if (![self migrateURL:sourceStoreURL + ofType:sourceStoreType + fromModel:modelA + toModel:modelB + mappingModel:mappingModel + error:error]) + { + return NO; + } + } + + return YES; +} + ++ (BOOL)migrateURL:(NSURL*)sourceStoreURL + ofType:(NSString*)sourceStoreType + fromModel:(NSManagedObjectModel*)sourceModel + toModel:(NSManagedObjectModel*)targetModel + mappingModel:(NSMappingModel*)mappingModel + error:(NSError**)error +{ + // Build a temporary path to write the migrated store. + NSURL* tempDestinationStoreURL = + [NSURL fileURLWithPath:[[sourceStoreURL path] stringByAppendingPathExtension:@"tmp"]]; + + // Migrate from the source model to the target model using the mapping, + // and store the resulting data at the temporary path. + NSMigrationManager* migrator = [[NSMigrationManager alloc] + initWithSourceModel:sourceModel + destinationModel:targetModel]; + + if (![migrator migrateStoreFromURL:sourceStoreURL + type:sourceStoreType + options:nil + withMappingModel:mappingModel + toDestinationURL:tempDestinationStoreURL + destinationType:sourceStoreType + destinationOptions:nil + error:error]) + { + return NO; + } + + // Move the original source store to a backup location. + NSString* backupPath = [[sourceStoreURL path] stringByAppendingPathExtension:@"bak"]; + NSFileManager* fileManager = [NSFileManager defaultManager]; + if (![fileManager moveItemAtPath:[sourceStoreURL path] + toPath:backupPath + error:error]) + { + // If the move fails, delete the migrated destination store. + [fileManager moveItemAtPath:[tempDestinationStoreURL path] + toPath:[sourceStoreURL path] + error:NULL]; + return NO; + } + + // Move the destination store to the original source location. + if ([fileManager moveItemAtPath:[tempDestinationStoreURL path] + toPath:[sourceStoreURL path] + error:error]) + { + // If the move succeeds, delete the backup of the original store. + [fileManager removeItemAtPath:backupPath error:NULL]; + } + else + { + // If the move fails, restore the original store to its original location. + [fileManager moveItemAtPath:backupPath + toPath:[sourceStoreURL path] + error:NULL]; + return NO; + } + + return YES; +} + ++ (NSString*)errorDomain +{ + return @"com.artlogic.IterativeMigrator"; +} + +#pragma mark - Private methods + +// Returns an NSError with the give code and localized description, +// and this class' error domain. ++ (NSError*)errorWithCode:(NSInteger)code description:(NSString*)description +{ + NSDictionary* userInfo = @{ + NSLocalizedDescriptionKey: description + }; + + return [NSError errorWithDomain:[ALIterativeMigrator errorDomain] + code:code + userInfo:userInfo]; + + return NO; +} + +// Gets the metadata for the given persistent store. ++ (NSDictionary*)metadataForPersistentStoreOfType:(NSString*)storeType + URL:(NSURL*)url + error:(NSError **)error +{ + NSDictionary* sourceMetadata = + [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:storeType + URL:url + error:error]; + if (nil == sourceMetadata && NULL != error) + { + NSString* errorDesc = [NSString stringWithFormat: + @"Failed to find source metadata for store: %@", + url]; + *error = [self errorWithCode:102 description:errorDesc]; + } + + return sourceMetadata; +} + +// Finds the source model for the store described by the given metadata. ++ (NSManagedObjectModel*)modelForStoreMetadata:(NSDictionary*)metadata + error:(NSError**)error +{ + NSManagedObjectModel* sourceModel = [NSManagedObjectModel + mergedModelFromBundles:nil + forStoreMetadata:metadata]; + if (nil == sourceModel && NULL != error) + { + NSString* errorDesc = [NSString stringWithFormat: + @"Failed to find source model for metadata: %@", + metadata]; + *error = [self errorWithCode:100 description:errorDesc]; + } + + return sourceModel; +} + +// Returns an array of NSManagedObjectModels loaded from mom files with the given names. +// Returns nil if any model files could not be found. ++ (NSArray*)modelsNamed:(NSArray*)modelNames + error:(NSError**)error +{ + NSMutableArray* models = [NSMutableArray array]; + for (NSString* modelName in modelNames) + { + NSURL* modelUrl = [self urlForModelName:modelName inDirectory:nil]; + NSManagedObjectModel* model = + [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl]; + + if (nil == model) + { + if (NULL != error) + { + NSString* errorDesc = + [NSString stringWithFormat:@"No model found for %@ at URL %@", modelName, modelUrl]; + *error = [self errorWithCode:110 description:errorDesc]; + } + return nil; + } + + [models addObject:model]; + } + return models; +} + +// Returns an array of paths to .mom model files in the given directory. +// Recurses into .momd directories to look for .mom files. +// @param directory The name of the bundle directory to search. If nil, +// searches default paths. ++ (NSArray*)modelPathsInDirectory:(NSString*)directory +{ + NSMutableArray* modelPaths = [NSMutableArray array]; + + // Get top level mom file paths. + [modelPaths addObjectsFromArray: + [[NSBundle mainBundle] pathsForResourcesOfType:@"mom" + inDirectory:directory]]; + + // Get mom file paths from momd directories. + NSArray* momdPaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"momd" + inDirectory:directory]; + for (NSString* momdPath in momdPaths) + { + NSString* resourceSubpath = [momdPath lastPathComponent]; + + [modelPaths addObjectsFromArray: + [[NSBundle mainBundle] + pathsForResourcesOfType:@"mom" + inDirectory:resourceSubpath]]; + } + + return modelPaths; +} + +// Returns the URL for a model file with the given name in the given directory. +// @param directory The name of the bundle directory to search. If nil, +// searches default paths. ++ (NSURL*)urlForModelName:(NSString*)modelName + inDirectory:(NSString*)directory +{ + NSBundle* bundle = [NSBundle mainBundle]; + NSURL* url = [bundle URLForResource:modelName + withExtension:@"mom" + subdirectory:directory]; + if (nil == url) + { + // Get mom file paths from momd directories. + NSArray* momdPaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"momd" + inDirectory:directory]; + for (NSString* momdPath in momdPaths) + { + url = [bundle URLForResource:modelName + withExtension:@"mom" + subdirectory:[momdPath lastPathComponent]]; + } + } + + return url; +} + +@end \ No newline at end of file diff --git a/Sources/Model/MHConnectionStore.h b/Sources/Model/MHConnectionStore.h new file mode 100644 index 00000000..92917890 --- /dev/null +++ b/Sources/Model/MHConnectionStore.h @@ -0,0 +1,60 @@ +// +// MHConnectionStore.h +// MongoHub +// +// Created by Syd on 10-4-24. +// Copyright 2010 MusicPeace.ORG. All rights reserved. +// + +#import +#import +#import "MHPreferenceWindowController.h" + +#define DEFAULT_MONGO_IP @"127.0.0.1" +#define MONGODB_SCHEME @"mongodb://" + +@interface MHConnectionStore : NSManagedObject +{ + NSString *_adminPassword; + NSString *_sshPassword; +} ++ (NSString *)hostnameFromServer:(NSString *)server withPort:(NSInteger *)port; ++ (NSString *)cleanupServers:(NSString *)servers; ++ (NSString *)passwordForServers:(NSString *)servers username:(NSString *)username; ++ (NSString *)sortedServers:(NSString *)servers; ++ (NSMutableArray *)splitServers:(NSString *)servers; + +- (BOOL)setValuesFromStringURL:(NSString *)stringURL errorMessage:(NSString **)errorMessage; +- (NSArray *)queryHistoryWithDatabaseName:(NSString *)databaseName collectionName:(NSString *)collectionName; +- (void)addNewQuery:(NSDictionary *)query withDatabaseName:(NSString *)databaseName collectionName:(NSString *)collectionName; +- (NSString *)stringURLWithSSHMapping:(NSDictionary *)sshMapping; + +@property (nonatomic, strong) NSString *alias; +@property (nonatomic, strong) NSString *servers; +@property (nonatomic, strong) NSString *replicaSetName; +@property (nonatomic, strong) NSNumber *slaveOK; +@property (nonatomic, strong) NSString *adminUser; +@property (nonatomic, strong) NSString *adminPassword; +@property (nonatomic, strong) NSString *defaultDatabase; + +@property (nonatomic, strong) NSNumber *useSSL; +@property (nonatomic, strong) NSNumber *weakCertificate; + +@property (nonatomic, strong) NSNumber *useSSH; +@property (nonatomic, strong) NSString *sshHost; +@property (nonatomic, strong) NSNumber *sshPort; +@property (nonatomic, strong) NSString *sshUser; +@property (nonatomic, strong) NSString *sshPassword; +@property (nonatomic, strong) NSString *sshKeyFileName; +@property (nonatomic, assign) MODReadPreferencesReadMode defaultReadMode; + +@property (nonatomic, readonly, assign) NSArray *arrayServers; + +@end + +@interface MHConnectionStore (Preferences) + +- (MHDefaultSortOrder)defaultSortOrder; +- (MODJsonKeySortOrder)jsonKeySortOrderInSearch; + +@end \ No newline at end of file diff --git a/Sources/Model/MHConnectionStore.m b/Sources/Model/MHConnectionStore.m new file mode 100644 index 00000000..e3697e33 --- /dev/null +++ b/Sources/Model/MHConnectionStore.m @@ -0,0 +1,389 @@ +// +// MHConnectionStore.m +// MongoHub +// +// Created by Syd on 10-4-24. +// Copyright 2010 MusicPeace.ORG. All rights reserved. +// + +#import "MHConnectionStore.h" +#import "MHKeychain.h" +#import "NSString+MongoHub.h" +#import "NSDictionary+MongoHub.h" +#import "MHApplicationDelegate.h" + +#define MAX_QUERY_PER_COLLECTION 20 +#define QUERY_HISTORY_KEY @"query_history" +#define SORTED_TITLE_KEY @"sorted_titles" +#define QUERY_KEY @"queries" + +@implementation MHConnectionStore + +@dynamic alias; +@dynamic servers; +@dynamic replicaSetName; +@dynamic slaveOK; +@dynamic adminUser; +@dynamic defaultDatabase; + +@dynamic useSSL; +@dynamic weakCertificate; + +@dynamic useSSH; +@dynamic sshHost; +@dynamic sshPort; +@dynamic sshUser; +@dynamic sshKeyFileName; +@dynamic defaultReadMode; + +@synthesize adminPassword = _adminPassword; +@synthesize sshPassword = _sshPassword; + ++ (NSString *)hostnameFromServer:(NSString *)server withPort:(NSInteger *)port +{ + NSArray *components; + + // just in case we have nil + if (!server) { + server = @""; + } + components = [server componentsSeparatedByString:@":"]; + if (port) { + if (components.count > 1) { + *port = [[components objectAtIndex:1] integerValue]; + } else { + *port = 0; + } + } + return [components objectAtIndex:0]; +} + ++ (NSString *)sortedServers:(NSString *)servers +{ + NSMutableArray *array; + + if (servers.length == 0) { + servers = DEFAULT_MONGO_IP; + } + array = [self splitServers:servers]; + [array sortedArrayUsingSelector:@selector(compare:)]; + return [array componentsJoinedByString:@","]; +} + ++ (NSString *)cleanupServers:(NSString *)servers +{ + return [[self splitServers:servers] componentsJoinedByString:@","]; +} + ++ (NSString *)passwordForServers:(NSString *)servers username:(NSString *)username +{ + NSString *keychainServers; + + NSParameterAssert(username.length > 0); + keychainServers = [self sortedServers:servers]; + return [MHKeychain passwordWithLabel:[NSString stringWithFormat:@"%@ (%@)", keychainServers, username] account:username service:keychainServers description:nil]; +} + ++ (NSMutableArray *)splitServers:(NSString *)servers +{ + NSMutableArray *array = [NSMutableArray array]; + + for (NSString *host in [servers componentsSeparatedByString:@","]) { + host = [host stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; + if (host.length > 0) { + [array addObject:host]; + } + } + if (array.count == 0) { + [array addObject:@""]; + } + return array; +} + + +- (void)dealloc +{ + self.adminPassword = nil; + self.sshPassword = nil; + [super dealloc]; +} + +- (NSArray *)queryHistoryWithDatabaseName:(NSString *)databaseName collectionName:(NSString *)collectionName +{ + NSString *absolute; + NSMutableArray *result; + NSDictionary *queries; + + absolute = [NSString stringWithFormat:@"%@.%@", databaseName, collectionName]; + result = [NSMutableArray array]; + @try { + queries = [[[[NSUserDefaults standardUserDefaults] dictionaryForKey:QUERY_HISTORY_KEY] objectForKey:absolute] objectForKey:QUERY_KEY]; + for (NSString *title in [[[[NSUserDefaults standardUserDefaults] dictionaryForKey:QUERY_HISTORY_KEY] objectForKey:absolute] objectForKey:SORTED_TITLE_KEY]) { + [result addObject:[queries objectForKey:title]]; + } + } + @catch (NSException *exception) { + } + return result; +} + +- (void)addNewQuery:(NSDictionary *)query withDatabaseName:(NSString *)databaseName collectionName:(NSString *)collectionName +{ + NSString *absolute; + NSMutableDictionary *allHistory; + NSMutableDictionary *queriesAndTitles; + NSMutableArray *sortedTitles; + NSMutableDictionary *allQueries; + + absolute = [[NSString alloc] initWithFormat:@"%@.%@", databaseName, collectionName]; + allHistory = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:QUERY_HISTORY_KEY] mutableCopy]; + if (allHistory == nil) { + allHistory = [[NSMutableDictionary alloc] init]; + } + queriesAndTitles = [[allHistory objectForKey:absolute] mutableCopy]; + if (queriesAndTitles == nil || ![queriesAndTitles isKindOfClass:[NSDictionary class]]) { + [queriesAndTitles release]; + queriesAndTitles = [[NSMutableDictionary alloc] init]; + } + sortedTitles = [[queriesAndTitles objectForKey:SORTED_TITLE_KEY] mutableCopy]; + allQueries = [[queriesAndTitles objectForKey:QUERY_KEY] mutableCopy]; + if (sortedTitles == nil || ![sortedTitles isKindOfClass:[NSArray class]] || allQueries == nil || ![allQueries isKindOfClass:[NSMutableDictionary class]]) { + [sortedTitles release]; + [allQueries release]; + sortedTitles = [[NSMutableArray alloc] init]; + allQueries = [[NSMutableDictionary alloc] init]; + } + + while ([sortedTitles count] >= MAX_QUERY_PER_COLLECTION) { + [allQueries removeObjectForKey:[sortedTitles lastObject]]; + [sortedTitles removeLastObject]; + } + if ([allQueries objectForKey:[query objectForKey:@"title"]]) { + [sortedTitles removeObject:[query objectForKey:@"title"]]; + } + [sortedTitles insertObject:[query objectForKey:@"title"] atIndex:0]; + [allQueries setObject:query forKey:[query objectForKey:@"title"]]; + + [queriesAndTitles setObject:sortedTitles forKey:SORTED_TITLE_KEY]; + [queriesAndTitles setObject:allQueries forKey:QUERY_KEY]; + [allHistory setObject:queriesAndTitles forKey:absolute]; + [[NSUserDefaults standardUserDefaults] setObject:allHistory forKey:QUERY_HISTORY_KEY]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + [absolute release]; + [allHistory release]; + [queriesAndTitles release]; + [sortedTitles release]; + [allQueries release]; +} + +- (BOOL)setValuesFromStringURL:(NSString *)stringURL errorMessage:(NSString **)errorMessage +{ + NSString *user = nil; + NSString *password = nil; + NSString *servers = nil; + NSString *databaseName = nil; + + NSArray *components; + NSArray *pathComponents; + NSArray *serverComponents; + NSDictionary *parameterComponents = nil; + + if (![stringURL hasPrefix:MONGODB_SCHEME]) { + if (errorMessage) { + *errorMessage = @"Unknown scheme"; + } + return NO; + } + + stringURL = [stringURL substringFromIndex:MONGODB_SCHEME.length]; + if (stringURL.length == 0) { + if (errorMessage) { + *errorMessage = @"Empty URL"; + } + return NO; + } + + /* first try to find the parameters */ + components = [stringURL componentsSeparatedByString:@"?"]; + if (components.count > 2) { + if (errorMessage) { + *errorMessage = @"More than one \"?\" in the URL"; + } + return NO; + } else if (components.count == 2) { + // remove the parameters from the url + + parameterComponents = [[NSDictionary mh_dictionaryFromURLParameters:[components objectAtIndex:1]] mh_setKeysToLowerCase]; + stringURL = [components objectAtIndex:0]; + } + + pathComponents = [stringURL componentsSeparatedByString:@"/"]; + + serverComponents = [[pathComponents objectAtIndex:0] componentsSeparatedByString:@"@"]; + if (serverComponents.count == 1) { + servers = [serverComponents objectAtIndex:0]; + } else if (serverComponents.count == 2) { + servers = [serverComponents objectAtIndex:1]; + if ([[serverComponents objectAtIndex:0] length] > 0) { + NSArray *userComponents = [[serverComponents objectAtIndex:0] componentsSeparatedByString:@":"]; + + if (userComponents.count == 1) { + user = [userComponents objectAtIndex:0]; + } else if (userComponents.count == 2) { + user = [userComponents objectAtIndex:0]; + password = [userComponents objectAtIndex:1]; + } else { + if (errorMessage) { + *errorMessage = @"Unable to parse user and password"; + } + return NO; + } + } + } else { + if (errorMessage) { + *errorMessage = @"Unable to parse host name(s) and user"; + } + return NO; + } + + + + if (user.length == 0 && password.length != 0) { + NSLog(@"no user found while having a password in URL: %@", stringURL); + if (errorMessage) { + *errorMessage = @"User name required when having a password"; + } + return NO; + } + + self.adminUser = user; + self.servers = servers; + self.defaultDatabase = databaseName; + self.adminPassword = password; + if ([parameterComponents[@"replicaset"] length] > 0) { + self.replicaSetName = [parameterComponents objectForKey:@"replicaset"]; + } + if ([parameterComponents[@"slaveok"] isEqualToString:@"true"]) { + self.slaveOK = @YES; + } + if ([parameterComponents[@"ssl"] isEqualToString:@"true"]) { + self.useSSL = @YES; + } + + if (errorMessage) { + *errorMessage = nil; + } + return YES; +} + +- (NSString *)sshPassword +{ + if (_sshPassword) { + return _sshPassword; + } else if (self.sshHost.length > 0 && self.sshUser > 0) { + return [MHKeychain internetPasswordProtocol:kSecAttrProtocolSSH host:self.sshHost port:self.sshPort.unsignedIntegerValue account:self.sshUser]; + } else { + return nil; + } +} + +- (NSString *)adminPassword +{ + if (_adminPassword) { + return _adminPassword; + } else if (self.adminUser.length > 0) { + return [self.class passwordForServers:[self.class sortedServers:self.servers] username:self.adminUser]; + } else { + return nil; + } +} + +- (NSArray *)arrayServers +{ + return [self.class splitServers:self.servers]; +} + +- (void)didSave +{ + if (_sshPassword.length > 0 && self.useSSH && self.sshUser.length > 0 && self.sshHost.length > 0) { + [MHKeychain addOrUpdateInternetPasswordWithProtocol:kSecAttrProtocolSSH host:self.sshHost port:self.sshPort.unsignedIntegerValue account:self.sshUser password:_sshPassword]; + } + if (_adminPassword.length > 0 && self.adminUser.length > 0) { + NSString *keychainServers; + + keychainServers = [self.class sortedServers:self.servers]; + [MHKeychain addOrUpdateItemWithLabel:[NSString stringWithFormat:@"%@ (%@)", keychainServers, self.adminUser] account:self.adminUser service:keychainServers description:nil password:_adminPassword]; + } + self.adminPassword = nil; + self.sshPassword = nil; +} + +- (NSString *)stringURLWithSSHMapping:(NSDictionary *)sshMapping +{ + NSString *auth = @""; + NSString *uri; + NSString *servers; + NSMutableArray *options = [NSMutableArray array]; + + if (self.adminUser.length > 0) { + if (self.adminPassword.length > 0) { + auth = [NSString stringWithFormat:@"%@:%@@", self.adminUser.mh_stringByEscapingURL, self.adminPassword.mh_stringByEscapingURL]; + } else { + auth = [NSString stringWithFormat:@"%@@", self.adminUser.mh_stringByEscapingURL]; + } + } + if (!self.useSSH.boolValue || !sshMapping) { + servers = self.servers; + } else { + NSMutableString *mappedIps; + + mappedIps = [NSMutableString string]; + for (NSString *hostnameAndPort in self.arrayServers) { + NSNumber *bindedPort = [sshMapping objectForKey:hostnameAndPort]; + + if (mappedIps.length > 0) { + [mappedIps appendFormat:@",127.0.0.1:%ld", (long)bindedPort.integerValue]; + } else { + [mappedIps appendFormat:@"127.0.0.1:%ld", (long)bindedPort.integerValue]; + } + } + servers = mappedIps; + } + if (servers.length == 0) { + servers = DEFAULT_MONGO_IP; + } + if (self.useSSL.boolValue) { + [options addObject:@"ssl=true"]; + } + if ([(MHApplicationDelegate *)[NSApp delegate] connectTimeout] != 0) { + [options addObject:[NSString stringWithFormat:@"connecttimeoutms=%u", [(MHApplicationDelegate *)[NSApp delegate] connectTimeout]]]; + } + if ([(MHApplicationDelegate *)[NSApp delegate] socketTimeout]) { + [options addObject:[NSString stringWithFormat:@"sockettimeoutms=%u", [(MHApplicationDelegate *)[NSApp delegate] socketTimeout]]]; + } + if (self.replicaSetName.length > 0) { + [options addObject:[NSString stringWithFormat:@"replicaSet=%@", self.replicaSetName.mh_stringByEscapingURL]]; + } + if (self.slaveOK.boolValue) { + [options addObject:@"slaveok=true"]; + } + uri = [NSString stringWithFormat:@"%@%@%@/%@?%@", MONGODB_SCHEME, auth, servers, self.defaultDatabase.mh_stringByEscapingURL, [options componentsJoinedByString:@"&"]]; + return uri; +} + +@end + +@implementation MHConnectionStore (Preferences) + +- (MHDefaultSortOrder)defaultSortOrder +{ + return MHPreferenceWindowController.defaultSortOrder; +} + +- (MODJsonKeySortOrder)jsonKeySortOrderInSearch +{ + return MHPreferenceWindowController.jsonKeySortOrderInSearch; +} + +@end \ No newline at end of file diff --git a/Sources/Model/MHMongoHubMigration6to7.h b/Sources/Model/MHMongoHubMigration6to7.h new file mode 100644 index 00000000..1375a77d --- /dev/null +++ b/Sources/Model/MHMongoHubMigration6to7.h @@ -0,0 +1,13 @@ +// +// MHMongoHubMigration6to7.h +// MongoHub +// +// Created by Jérôme Lebel on 25/07/2014. +// +// + +#import + +@interface MHMongoHubMigration6to7 : NSEntityMigrationPolicy + +@end diff --git a/Sources/Model/MHMongoHubMigration6to7.m b/Sources/Model/MHMongoHubMigration6to7.m new file mode 100644 index 00000000..8baf1e91 --- /dev/null +++ b/Sources/Model/MHMongoHubMigration6to7.m @@ -0,0 +1,46 @@ +// +// MHMongoHubMigration6to7.m +// MongoHub +// +// Created by Jérôme Lebel on 25/07/2014. +// +// + +#import "MHMongoHubMigration6to7.h" +#import "MHKeychain.h" +#import "MHConnectionStore.h" + +@implementation MHMongoHubMigration6to7 + +- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sourceInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError *__autoreleasing *)error +{ + NSManagedObjectContext *destMOC = manager.destinationContext; + NSManagedObject *newConnection; + NSString *password = [sourceInstance valueForKey:@"sshpassword"]; + NSString *user = [sourceInstance valueForKey:@"sshuser"]; + NSString *host; + NSString *hostAndPort = nil; + + host = [sourceInstance valueForKey:@"sshhost"]; + if ([[sourceInstance valueForKey:@"sshport"] integerValue] != 0) { + hostAndPort = [NSString stringWithFormat:@"%@:%@", [sourceInstance valueForKey:@"sshhost"], [sourceInstance valueForKey:@"sshport"]]; + } + if (password && password.length > 0) { + BOOL result; + + result = [MHKeychain addOrUpdateInternetPasswordWithProtocol:kSecAttrProtocolSSH host:host port:[[sourceInstance valueForKey:@"sshport"] unsignedIntegerValue] account:user password:password]; + if (!result) { + NSLog(@"can't save password for %@@%@", user, hostAndPort); + } + } + newConnection = [NSEntityDescription insertNewObjectForEntityForName:@"Connection" inManagedObjectContext:destMOC]; + NSArray *keys = sourceInstance.entity.attributesByName.allKeys; + NSMutableDictionary *values = [[sourceInstance dictionaryWithValuesForKeys:keys] mutableCopy]; + [values removeObjectForKey:@"sshpassword"]; + [newConnection setValuesForKeysWithDictionary:values]; + [manager associateSourceInstance:sourceInstance withDestinationInstance:newConnection forEntityMapping:mapping]; + [values release]; + return YES; +} + +@end diff --git a/Sources/Model/MHMongoHubMigration6to7.xcmappingmodel/xcmapping.xml b/Sources/Model/MHMongoHubMigration6to7.xcmappingmodel/xcmapping.xml new file mode 100644 index 00000000..03a93fc5 --- /dev/null +++ b/Sources/Model/MHMongoHubMigration6to7.xcmappingmodel/xcmapping.xml @@ -0,0 +1,173 @@ + + + + + + 134481920 + 488A9A23-C4E9-4D35-9ED4-F6F0A135E1B8 + 127 + + + + NSPersistenceFrameworkVersion + 481 + NSStoreModelVersionHashes + + XDDevAttributeMapping + + 0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc= + + XDDevEntityMapping + + qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI= + + XDDevMappingModel + + EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ= + + XDDevPropertyMapping + + XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA= + + XDDevRelationshipMapping + + akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs= + + + NSStoreModelVersionHashesVersion + 3 + NSStoreModelVersionIdentifiers + + + + + + + + + repl_name + + + + bindaddress + + + + sshuser + + + + defaultReadMode + + + + servers + + + + host + + + + user + + + + Database + Undefined + 2 + Database + 1 + + + + + + password + + + + 1 + connection + + + + sshport + + + + adminpass + + + + Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel + YnBsaXN0MDDUAAEAAgADAAQABQAGId4h31gkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv +cBIAAYagrxECyAAHAAgAFwAYADQANQA2AEAAQQBCAF0AXgBfAGUAZgByAIYAhwCIAIkAigCLAIwAjQCOAKcAsAC/AM4A3QDgAOQAXAD0AQMBCQEKAQsBDwEeASQBJQEtATwBPQFGAVIBUwFUAVUBVgFrAWwBdAF1AXYBggGWAZcBmAGZAZoBmwGcAZ0BngGtAbwBywHTAdQB3AHdAd4B3wHgAe8B/gH/Ag4CHQIsAjgCSgJLAkwCTQJOAk8CUAJRAmACbwJ+Ao0CjgKdAqwCuwLDAtgC2QLhAu0DAQMQAx8DLgM2Az4DTQNcA2sDegOJA5UDpwO2A8UD1APjA/IEAQQQBCUEJgQuBC8EOwRPBF4EbQR8BIQEjASbBKoEuQTIBNcE4wT1BPYE9wT4BPkE+gT7BPwFCwUMBRsFHAUrBToFVAVVBVsFZwV7BYoFmQWoBbcFugXJBdgF3gXtBfwF/QYpBioGKwYsBi0GLgYvBjAGMQYyBjMGNAY1BjYGNwY4BjkGOgY7BjwGPQZSBlMGWwZnBnsGigaZBqgGrAa7BsoG2QboBvcHAwcVByQHMwdCB1EHUgdhB3AHfweUB5UHnQepB70HzAfbB+oH8gf6CAkIGAgnCDYIRQhRCGMIcgiBCJAInwiuCL0IzAjhCOII6gj2CQoJGQkoCTcJPwlHCVYJZQl0CYMJkgmeCbAJvwnOCd0J7An7CgoKGQouCi8KNwpDClcKZgp1CoQKjAqUCqMKsgrBCtAK3wrrCv0LDAsbCyoLOQtIC1cLZgt7C3wLhAuQC6QLswvCC9EL2QvhC/AL/wwODB0MLAw4DEoMWQxoDHcMhgyVDKQMswzIDMkM0QzdDPENAA0PDR4NJg0uDT0NTA1bDWoNeQ2FDZcNpg21DcQN0w3iDfEOAA4VDhYOHg4qDj4OTQ5cDmsOcw57DooOmQ6oDrcOxg7SDuQO8w8CDxEPIA8vDz4PTQ9iD2MPaw93D4sPmg+pD7gPwA/ID9cP5g/1EAQQExAfEDEQQBBPEF4QbRB8EIsQmhCvELAQuBDEENgQ5xD2EQURDREVESQRMxFCEVERYBFsEX4RjRGOEZ0RrBG7EcoR2RHoEf0R/hIGEhISJhI1EkQSUxJbEmMSchKBEpASnxKuEroSzBLbEuoS+RMIExcTJhM1E0oTSxNTE18TcxOCE5EToBOoE7ATvxPOE90T7BP7FAcUGQAuFCgUNxRGFFUUZBRzFIIUihSfFKAUqBS0FMgU1xTmFPUU/RUFFRQVIxUyFUEVUBVcFW4VfRWMFZsVqhW5FcgV1xXsFe0V9RYBFhUWJBYzFkIWShZSFmEWcBZ/Fo4WnRapFrsWyhbZFugW9xcGFxUXJBc5FzoXQhdOF2IXcReAF48XlxefF64XvRfMF9sX6hf2GAgYFxgmGDUYRBhTGGIYcRiGGIcYjxibGK8YvhjNGNwY5BjsGPsZChkZGSgZNxlDGVUZZBlzGYIZkRmSGaEZsBm/GdQZ1RndGekZ/RoMGhsaKhoyGjoaSRpYGmcadhqFGpEaoxqyGsEa0BrfGu4a/RsMGyEbIhsqGzYbShtZG2gbdxt/G4cblhulG7QbwxvSG94b8Bv/HA4cHRwsHDscShxZHG4cbxx3HIMclxymHLUcxBzIHNcc5hz1HQQdEx0fHTEdQB1PHV4dbR18HYsdmh2vHbAduB3EHdgd5x32HgUeDR4VHiQeMx5CHlEeYB5sHn4ejR6cHqseuh7JHtge5x78Hv0fBR8RHyUfNB9DH1IfWh9iH3EfgB+PH54frR+5H8sf2h/pH/ggByAWICUgNCA1IDggQSBQIF8gbiCDIIQgjCCYIKwguyDKINkg4SDpIPghByEWISUhNCFAIVIhYSFwIX8hjiGdIawhuyG+IcIhxiHKIdIh1SHZVSRudWxs1wAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABNfEA9feGRfcm9vdFBhY2thZ2VWJGNsYXNzXF94ZF9jb21tZW50c18QEF94ZF9tb2RlbE1hbmFnZXJfEBVfY29uZmlndXJhdGlvbnNCeU5hbWVdX3hkX21vZGVsTmFtZV8QF19tb2RlbFZlcnNpb25JZGVudGlmaWVygAOBAseBAsWAAIECxoACgABfEBR1bnRpdGxlZC54Y2RhdGFtb2RlbN4AGQAaABsAHAAdAB4AHwAKACAAIQAiACMAJAAlACYAJwAoACkAJgATACwALQAuAC8AMAAmACYAE18QHFhEQnVja2V0Rm9yQ2xhc3Nlc3dhc0VuY29kZWRfEBpYREJ1Y2tldEZvclBhY2thZ2Vzc3RvcmFnZV8QHFhEQnVja2V0Rm9ySW50ZXJmYWNlc3N0b3JhZ2VfEA9feGRfb3duaW5nTW9kZWxfEB1YREJ1Y2tldEZvclBhY2thZ2Vzd2FzRW5jb2RlZFZfb3duZXJfEBtYREJ1Y2tldEZvckRhdGFUeXBlc3N0b3JhZ2VbX3Zpc2liaWxpdHlfEBlYREJ1Y2tldEZvckNsYXNzZXNzdG9yYWdlVV9uYW1lXxAfWERCdWNrZXRGb3JJbnRlcmZhY2Vzd2FzRW5jb2RlZF8QHlhEQnVja2V0Rm9yRGF0YVR5cGVzd2FzRW5jb2RlZF8QEF91bmlxdWVFbGVtZW50SUSABYECw4ECwYABgAWAAIECwoECxBAAgAaABIAFgAWAAFBTWUVT0wA3ADgACgA5ADwAP1dOUy5rZXlzWk5TLm9iamVjdHOiADoAO4AHgAiiAD0APoAJgJqAJVhEYXRhYmFzZVpDb25uZWN0aW9u3xAQAEMARABFAEYAHgBHAEgAIABJAEoACgAiAEsATAAlAE0ATgBPACYAJgAQAFMAVAAuACYATgBXADoATgBaAFsAXF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzc3RvcmFnZV8QIFhEQnVja2V0Rm9yU3RlcmVvdHlwZXN3YXNFbmNvZGVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc3N0b3JhZ2VfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc2R1cGxpY2F0ZXNfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zc3RvcmFnZVtfaXNBYnN0cmFjdIALgC2ABYAFgAOADIECooAFgAuBAqSAB4ALgQLAgAoIEhGDqHtXb3JkZXJlZNMANwA4AAoAYABiAD+hAGGADaEAY4AOgCVeWERfUFN0ZXJlb3R5cGXZAB4AIgBnAAoAJQBoACAATQBpAD0AYQBOAG0AEwAmAC4AXABxXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmR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CFUQVRhVHFUgVShVLFYoVjBWOFZAVkhWTFZQVlRWWFZgVmhWbFZwVnhWfFd4V4BXiFeQV5hXnFegV6RXqFewV7hXvFfAV8hXzFgAWBRYHFgkWDhYQFhIWFBZHFlQWWRZbFl0WYhZkFmYWaBZ+FpAWlBaaFtkW2xbdFt8W4RbiFuMW5BblFucW6RbqFusW7RbuFy0XLxcxFzMXNRc2FzcXOBc5FzsXPRc+Fz8XQRdCF0MXgheEF4YXiBeKF4sXjBeNF44XkBeSF5MXlBeWF5cX1hfYF9oX3BfeF98X4BfhF+IX5BfmF+cX6BfqF+sYKhgsGC4YMBgyGDMYNBg1GDYYOBg6GDsYPBg+GD8YZBiIGK8Y0xjVGNcY2RjbGN0Y3xjgGOIY7xj+GQAZAhkEGQYZCBkKGQwZGxkdGR8ZIRkjGSUZJxkpGSsZSxl2GZAZqRnDGeMaBhpFGkcaSRpLGk0aThpPGlAaURpTGlUaVhpXGlkaWhqZGpsanRqfGqEaohqjGqQapRqnGqkaqhqrGq0arhrtGu8a8RrzGvUa9hr3Gvga+Rr7Gv0a/hr/GwEbAhtBG0MbRRtHG0kbShtLG0wbTRtPG1EbUhtTG1UbVhtZG5gbmhucG54boBuhG6IboxukG6YbqBupG6obrButG+wb7hvwG/Ib9Bv1G/Yb9xv4G/ob/Bv9G/4cABwBHEAcQhxEHEYcSBxJHEocSxxMHE4cUBxRHFIcVBxVHF4cbBx5HIcclBynHL4c0B0bHT4dXh1+HYAdgh2EHYYdiB2JHYodjB2NHY8dkB2SHZQdlR2WHZgdmR2eHasdsB2yHbQduR27Hb0dvx3kHggeLx5THlUeVx5ZHlseXR5fHmAeYh5vHoAegh6EHoYeiB6KHowejh6QHqEeox6lHqceqR6rHq0erx6xHrMe8h70HvYe+B76Hvse/B79Hv4fAB8CHwMfBB8GHwcfRh9IH0ofTB9OH08fUB9RH1IfVB9WH1cfWB9aH1sfmh+cH54foB+iH6MfpB+lH6YfqB+qH6sfrB+uH68fvB/BH8MfxR/KH8wfzh/QH90f4h/kH+Yf6x/tH+8f8SAwIDIgNCA2IDggOSA6IDsgPCA+IEAgQSBCIEQgRSCEIIYgiCCKIIwgjSCOII8gkCCSIJQglSCWIJggmSDYINog3CDeIOAg4SDiIOMg5CDmIOgg6SD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xODI4Mzg0ODU4Nzg5ODo4Ozg9OD44YziHOK440jjUONY42DjaONw43jjfOOE47jj9OP85ATkDOQU5BzkJOQs5GjkcOR45IDkiOSQ5JjkoOSo5aTlrOW05bzlxOXI5czl0OXU5dzl5OXo5ezl9OX45vTm/OcE5wznFOcY5xznIOck5yznNOc45zznROdI6EToTOhU6FzoZOho6GzocOh06HzohOiI6IzolOiY6ZTpnOmk6azptOm46bzpwOnE6czp1OnY6dzp5Ono6fDq7Or06vzrBOsM6xDrFOsY6xzrJOss6zDrNOs860DsPOxE7EzsVOxc7GDsZOxo7GzsdOx87IDshOyM7JDtjO2U7ZztpO2s7bDttO247bztxO3M7dDt1O3c7eDvDO+Y8BjwmPCg8KjwsPC48MDwxPDI8NDw1PDc8ODw6PDw8PTw+PEA8QTxKPFc8XDxePGA8ZTxnPGk8azyQPLQ82zz/PQE9Az0FPQc9CT0LPQw9Dj0bPSw9Lj0wPTI9ND02PTg9Oj08PU09Tz1RPVM9VT1XPVk9Wz1dPV89nj2gPaI9pD2mPac9qD2pPao9rD2uPa89sD2yPbM98j30PfY9+D36Pfs9/D39Pf4+AD4CPgM+BD4GPgc+Rj5IPko+TD5OPk8+UD5RPlI+VD5WPlc+WD5aPls+aD5tPm8+cT52Png+ej58Pok+jj6QPpI+lz6ZPps+nT7cPt4+4D7iPuQ+5T7mPuc+6D7qPuw+7T7uPvA+8T8wPzI/ND82Pzg/OT86Pzs/PD8+P0A/QT9CP0Q/RT+EP4Y/iD+KP4w/jT+OP48/kD+SP5Q/lT+WP5g/mT/YP9o/3D/eP+A/4T/iP+M/5D/mP+g/6T/qP+w/7UAsQC5AMEAyQDRANUA2QDdAOEA6QDxAPUA+QEBAQUBmQIpAsUDVQNdA2UDbQN1A30DhQOJA5EDxQQBBAkEEQQZBCEEKQQxBDkEdQR9BIUEjQSVBJ0EpQStBLUFsQW5BcEFyQXRBdUF2QXdBeEF6QXxBfUF+QYBBgUHAQcJBxEHGQchByUHKQctBzEHOQdBB0UHSQdRB1UIUQhZCGEIaQhxCHUIeQh9CIEIiQiRCJUImQihCKUJoQmpCbEJuQnBCcUJyQnNCdEJ2QnhCeUJ6QnxCfUK8Qr5CwELCQsRCxULGQsdCyELKQsxCzULOQtBC0UMQQxJDFEMWQxhDGUMaQxtDHEMeQyBDIUMiQyRDJUNkQ2ZDaENqQ2xDbUNuQ29DcENyQ3RDdUN2Q3hDeUPEQ+dEB0QnRClEK0QtRC9EMUQyRDNENUQ2RDhEOUQ7RD1EPkQ/REFEQkRLRFhEXURfRGFEZkRoRGpEbESRRLVE3EUARQJFBEUGRQhFCkUMRQ1FD0UcRS1FL0UxRTNFNUU3RTlFO0U9RU5FUEVSRVRFVkVYRVpFXEVeRWBFn0WhRaNFpUWnRahFqUWqRatFrUWvRbBFsUWzRbRF80X1RfdF+UX7RfxF/UX+Rf9GAUYDRgRGBUYHRghGR0ZJRktGTUZPRlBGUUZSRlNGVUZXRlhGWUZbRlxGaUZuRnBGckZ3RnlGe0Z9RopGj0aRRpNGmEaaRpxGnkbdRt9G4UbjRuVG5kbnRuhG6UbrRu1G7kbvRvFG8kcxRzNHNUc3RzlHOkc7RzxHPUc/R0FHQkdDR0VHRkeFR4dHiUeLR41HjkePR5BHkUeTR5VHlkeXR5lHmkfZR9tH3UffR+FH4kfjR+RH5UfnR+lH6kfrR+1H7kgtSC9IMUgzSDVINkg3SDhIOUg7SD1IPkg/SEFIQkhnSItIskjWSNhI2kjcSN5I4EjiSONI5UjySQFJA0kFSQdJCUkLSQ1JD0keSSFJJEknSSpJLUkwSTNJNUl0SXZJeEl6SXxJfUl+SX9JgEmCSYRJhUmGSYhJiUnIScpJzEnOSdBJ0UnSSdNJ1EnWSdhJ2UnaSdxJ3UocSh5KIEoiSiRKJUomSidKKEoqSixKLUouSjBKMUpwSnJKdEp2SnhKeUp6SntKfEp+SoBKgUqCSoRKhUrESsZKyErKSsxKzUrOSs9K0ErSStRK1UrWSthK2UsYSxpLHEseSyBLIUsiSyNLJEsmSyhLKUsqSyxLLUtsS25LcEtyS3RLdUt2S3dLeEt6S3xLfUt+S4BLgUvMS+9MD0wvTDFMM0w1TDdMOUw6TDtMPkw/TEFMQkxETEZMR0xITEtMTExRTF5MY0xlTGdMbExvTHJMdEyZTL1M5E0ITQtNDU0PTRFNE00VTRZNGU0mTTdNOU07TT1NP01BTUNNRU1HTVhNW01eTWFNZE1nTWpNbU1wTXJNsU2zTbVNt026TbtNvE29Tb5NwE3CTcNNxE3GTcdOBk4ITgpODE4PThBOEU4SThNOFU4XThhOGU4bThxOW05dTmBOYk5lTmZOZ05oTmlOa05tTm5Ob05xTnJOf06EToZOiE6NTo9Okk6UTqFOpk6oTqpOr06xTrNOtU70TvZO+E76Tv1O/k7/TwBPAU8DTwVPBk8HTwlPCk9JT0tPTU9PT1JPU09UT1VPVk9YT1pPW09cT15PX0+eT6BPok+kT6dPqE+pT6pPq0+tT69PsE+xT7NPtE/zT/VP90/5T/xP/U/+T/9QAFACUARQBVAGUAhQCVBIUEpQTFBOUFFQUlBTUFRQVVBXUFlQWlBbUF1QXlCDUKdQzlDyUPVQ91D5UPtQ/VD/UQBRA1EQUR9RIVEjUSVRJ1EpUStRLVE8UT9RQlFFUUhRS1FOUVFRU1GSUZRRllGYUZtRnFGdUZ5Rn1GhUaNRpFGlUadRqFHnUelR61HtUfBR8VHyUfNR9FH2UfhR+VH6UfxR/VI8Uj5SQFJCUkVSRlJHUkhSSVJLUk1STlJPUlFSUlKRUpNSlVKXUppSm1KcUp1SnlKgUqJSo1KkUqZSp1LmUuhS6lLsUu9S8FLxUvJS81L1UvdS+FL5UvtS/FM7Uz1TP1NBU0RTRVNGU0dTSFNKU0xTTVNOU1BTUVOQU5JTlFOWU5lTmlObU5xTnVOfU6FTolOjU6VTplPxVBRUNFRUVFZUWFRaVFxUXlRfVGBUY1RkVGZUZ1RpVGtUbFRtVHBUcVR6VIdUjFSOVJBUlVSYVJtUnVTCVOZVDVUxVTRVNlU4VTpVPFU+VT9VQlVPVWBVYlVkVWZVaFVqVWxVblVwVYFVhFWHVYpVjVWQVZNVllWZVZtV2lXcVd5V4FXjVeRV5VXmVedV6VXrVexV7VXvVfBWL1YxVjNWNVY4VjlWOlY7VjxWPlZAVkFWQlZEVkVWhFaGVolWi1aOVo9WkFaRVpJWlFaWVpdWmFaaVptWqFatVq9WsVa2VrhWu1a9VspWz1bRVtNW2FbaVtxW3lcdVx9XIVcjVyZXJ1coVylXKlcsVy5XL1cwVzJXM1dyV3RXdld4V3tXfFd9V35Xf1eBV4NXhFeFV4dXiFfHV8lXy1fNV9BX0VfSV9NX1FfWV9hX2VfaV9xX3VgcWB5YIFgiWCVYJlgnWChYKVgrWC1YLlgvWDFYMlhxWHNYdVh3WHpYe1h8WH1YfliAWIJYg1iEWIZYh1isWNBY91kbWR5ZIFkiWSRZJlkoWSlZLFk5WUhZSllMWU5ZUFlSWVRZVlllWWhZa1luWXFZdFl3WXpZfFm7Wb1Zv1nBWcRZxVnGWcdZyFnKWcxZzVnOWdBZ0VoQWhJaFFoWWhlaGlobWhxaHVofWiFaIlojWiVaJlplWmdaaVprWm5ab1pwWnFaclp0WnZad1p4Wnpae1q6WrxavlrAWsNaxFrFWsZax1rJWstazFrNWs9a0FsPWxFbE1sVWxhbGVsaWxtbHFseWyBbIVsiWyRbJVtkW2ZbaFtqW21bbltvW3BbcVtzW3Vbdlt3W3lbelu5W7tbvVu/W8Jbw1vEW8VbxlvIW8pby1vMW85bz1waXD1cXVx9XH9cgVyDXIVch1yIXIlcjFyNXI9ckFySXJRclVyWXJlcmlyfXKxcsVyzXLVculy9XMBcwlznXQtdMl1WXVldW11dXV9dYV1jXWRdZ110XYVdh12JXYtdjV2PXZFdk12VXaZdqV2sXa9dsl21Xbhdu12+XcBd/14BXgNeBV4IXgleCl4LXgxeDl4QXhFeEl4UXhVeVF5WXlheWl5dXl5eX15gXmFeY15lXmZeZ15pXmpeqV6rXq5esF6zXrRetV62XrdeuV67XrxevV6/XsBezV7SXtRe1l7bXt1e4F7iXu9e9F72Xvhe/V7/XwFfA19CX0RfRl9IX0tfTF9NX05fT19RX1NfVF9VX1dfWF+XX5lfm1+dX6BfoV+iX6NfpF+mX6hfqV+qX6xfrV/sX+5f8F/yX/Vf9l/3X/hf+V/7X/1f/l//YAFgAmBBYENgRWBHYEpgS2BMYE1gTmBQYFJgU2BUYFZgV2CWYJhgmmCcYJ9goGChYKJgo2ClYKdgqGCpYKtgrGDRYPVhHGFAYUNhRWFHYUlhS2FNYU5hUWFeYW1hb2FxYXNhdWF3YXlhe2GKYY1hkGGTYZZhmWGcYZ9hoWHgYeJh5GHmYelh6mHrYexh7WHvYfFh8mHzYfVh9mI1YjdiOWI7Yj5iP2JAYkFiQmJEYkZiR2JIYkpiS2KKYoxijmKQYpNilGKVYpZil2KZYptinGKdYp9ioGLfYuFi42LlYuhi6WLqYuti7GLuYvBi8WLyYvRi9WM0YzZjOGM6Yz1jPmM/Y0BjQWNDY0VjRmNHY0ljSmOJY4tjjWOPY5Jjk2OUY5VjlmOYY5pjm2OcY55jn2PeY+Bj4mPkY+dj6GPpY+pj62PtY+9j8GPxY/Nj9GQ/ZGJkgmSiZKRkpmSoZKpkrGStZK5ksWSyZLRktWS3ZLlkumS7ZL5kv2TEZNFk1mTYZNpk32TiZOVk52UMZTBlV2V7ZX5lgGWCZYRlhmWIZYlljGWZZaplrGWuZbBlsmW0ZbZluGW6ZctlzmXRZdRl12XaZd1l4GXjZeVmJGYmZihmKmYtZi5mL2YwZjFmM2Y1ZjZmN2Y5ZjpmeWZ7Zn1mf2aCZoNmhGaFZoZmiGaKZotmjGaOZo9mzmbQZtNm1WbYZtlm2mbbZtxm3mbgZuFm4mbkZuVm8mb3Zvlm+2cAZwJnBWcHZxRnGWcbZx1nImckZyZnKGdnZ2lna2dtZ3BncWdyZ3NndGd2Z3hneWd6Z3xnfWe8Z75nwGfCZ8VnxmfHZ8hnyWfLZ81nzmfPZ9Fn0mgRaBNoFWgXaBpoG2gcaB1oHmggaCJoI2gkaCZoJ2hmaGhoamhsaG9ocGhxaHJoc2h1aHdoeGh5aHtofGi7aL1ov2jBaMRoxWjGaMdoyGjKaMxozWjOaNBo0Wj2aRppQWllaWhpamlsaW5pcGlyaXNpdmmDaZJplGmWaZhpmmmcaZ5poGmvabJptWm4abtpvmnBacRpxmoFagdqCWoLag5qD2oQahFqEmoUahZqF2oYahpqG2paalxqXmpgamNqZGplamZqZ2ppamtqbGptam9qcGqvarFqs2q1arhquWq6artqvGq+asBqwWrCasRqxWsEawZrCGsKaw1rDmsPaxBrEWsTaxVrFmsXaxlrGmtZa1trXWtfa2JrY2tka2VrZmtoa2pra2tsa25rb2uua7Brsmu0a7druGu5a7pru2u9a79rwGvBa8NrxGwDbAVsB2wJbAxsDWwObA9sEGwSbBRsFWwWbBhsGWxkbIdsp2zHbMlsy2zNbM9s0WzSbNNs1mzXbNls2mzcbN5s32zgbONs5GzpbPZs+2z9bP9tBG0HbQptDG0xbVVtfG2gbaNtpW2nbaltq22tba5tsW2+bc9t0W3TbdVt123Zbdtt3W3fbfBt8232bflt/G3/bgJuBW4IbgpuSW5Lbk1uT25SblNuVG5VblZuWG5abltuXG5ebl9unm6gbqJupG6nbqhuqW6qbqturW6vbrBusW6zbrRu8271bvhu+m79bv5u/28AbwFvA28FbwZvB28JbwpvF28cbx5vIG8lbydvKm8sbzlvPm9Ab0JvR29Jb0tvTW+Mb45vkG+Sb5Vvlm+Xb5hvmW+bb51vnm+fb6Fvom/hb+Nv5W/nb+pv62/sb+1v7m/wb/Jv82/0b/Zv93A2cDhwOnA8cD9wQHBBcEJwQ3BFcEdwSHBJcEtwTHCLcI1wj3CRcJRwlXCWcJdwmHCacJxwnXCecKBwoXDgcOJw5HDmcOlw6nDrcOxw7XDvcPFw8nDzcPVw9nEbcT9xZnGKcY1xj3GRcZNxlXGXcZhxm3GocbdxuXG7cb1xv3HBccNxxXHUcddx2nHdceBx43Hmcelx63IqcixyLnIwcjNyNHI1cjZyN3I5cjtyPHI9cj9yQHJ/coFyg3KFcohyiXKKcotyjHKOcpBykXKScpRylXLUctZy2HLact1y3nLfcuBy4XLjcuVy5nLnculy6nMpcytzLXMvczJzM3M0czVzNnM4czpzO3M8cz5zP3N+c4BzgnOEc4dziHOJc4pzi3ONc49zkHORc5NzlHPTc9Vz13PZc9xz3XPec99z4HPic+Rz5XPmc+hz6XQodCp0LHQudDF0MnQzdDR0NXQ3dDl0OnQ7dD10PnSJdKx0zHTsdO508HTydPR09nT3dPh0+3T8dP50/3UBdQN1BHUFdQh1CXUSdR91JHUmdSh1LXUwdTN1NXVadX51pXXJdcx1znXQddJ11HXWddd12nXndfh1+nX8df52AHYCdgR2BnYIdhl2HHYfdiJ2JXYodit2LnYxdjN2cnZ0dnZ2eHZ7dnx2fXZ+dn92gXaDdoR2hXaHdoh2x3bJdst2zXbQdtF20nbTdtR21nbYdtl22nbcdt13HHcedyF3I3cmdyd3KHcpdyp3LHcudy93MHcydzN3QHdFd0d3SXdOd1B3U3dVd2J3Z3dpd2t3cHdyd3R3dne1d7d3uXe7d753v3fAd8F3wnfEd8Z3x3fId8p3y3gKeAx4DngQeBN4FHgVeBZ4F3gZeBt4HHgdeB94IHhfeGF4Y3hleGh4aXhqeGt4bHhueHB4cXhyeHR4dXi0eLZ4uHi6eL14vni/eMB4wXjDeMV4xnjHeMl4ynkJeQt5DXkPeRJ5E3kUeRV5FnkYeRp5G3kceR55H3lEeWh5j3mzebZ5uHm6ebx5vnnAecF5xHnReeB54nnkeeZ56Hnqeex57nn9egB6A3oGegl6DHoPehJ6FHpTelV6WHpael16XnpfemB6YXpjemV6Znpneml6anpseqt6rXqverF6tHq1erZ6t3q4erp6vHq9er56wHrBewB7AnsEewZ7CXsKewt7DHsNew97EXsSexN7FXsWe1V7V3tZe1t7Xntfe2B7YXtie2R7Zntne2h7antre6p7rHuue7B7s3u0e7V7tnu3e7l7u3u8e717v3vAe/98AXwDfAV8CHwJfAp8C3wMfA58EHwRfBJ8FHwVfFR8VnxYfFp8XXxefF98YHxhfGN8ZXxmfGd8aXxqfLV82Hz4fRh9Gn0cfR59IH0ifSN9JH0nfSh9Kn0rfS19L30wfTF9NH01fT59S31QfVJ9VH1ZfVx9X31hfYZ9qn3RffV9+H36ffx9/n4AfgJ+A34GfhN+JH4mfih+Kn4sfi5+MH4yfjR+RX5Ifkt+Tn5RflR+V35afl1+X36efqB+on6kfqd+qH6pfqp+q36tfq9+sH6xfrN+tH7zfvV+9375fvx+/X7+fv9/AH8CfwR/BX8Gfwh/CX9If0p/TX9Pf1J/U39Uf1V/Vn9Yf1p/W39cf15/X39sf3F/c391f3p/fH9/f4F/jn+Tf5V/l3+cf55/oH+if+F/43/lf+d/6n/rf+x/7X/uf/B/8n/zf/R/9n/3gDaAOIA6gDyAP4BAgEGAQoBDgEWAR4BIgEmAS4BMgIuAjYCPgJGAlICVgJaAl4CYgJqAnICdgJ6AoIChgOCA4oDkgOaA6YDqgOuA7IDtgO+A8YDygPOA9YD2gTWBN4E5gTuBPoE/gUCBQYFCgUSBRoFHgUiBSoFLgXCBlIG7gd+B4oHkgeaB6IHqgeyB7YHwgf2CDIIOghCCEoIUghaCGIIagimCLIIvgjKCNYI4gjuCPoJAgn+CgYKDgoWCiIKJgoqCi4KMgo6CkIKRgpKClIKVgtSC1oLYgtqC3YLegt+C4ILhguOC5YLmgueC6YLqgymDK4Mtgy+DMoMzgzSDNYM2gziDOoM7gzyDPoM/g36DgIOCg4SDh4OIg4mDioOLg42Dj4OQg5GDk4OUg9OD1YPXg9mD3IPdg96D34Pgg+KD5IPlg+aD6IPphCiEKoQshC6EMYQyhDOENIQ1hDeEOYQ6hDuEPYQ+hH2Ef4SBhIOEhoSHhIiEiYSKhIyEjoSPhJCEkoSThN6FAYUhhUGFQ4VFhUeFSYVLhUyFTYVQhVGFU4VUhVeFWYVahVuFXoVfhWSFcYV2hXiFeoV/hYKFhYWHhayF0IX3hhuGHoYghiKGJIYmhiiGKYYshjmGSoZMhk6GUIZShlSGVoZYhlqGa4ZuhnGGdIZ3hnqGfYaAhoOGhYbEhsaGyIbKhs2GzobPhtCG0YbThtWG1obXhtmG2ocZhxuHHYcfhyKHI4ckhyWHJocohyqHK4cshy6HL4duh3CHc4d1h3iHeYd6h3uHfId+h4CHgYeCh4SHhYeSh5eHmYebh6CHooelh6eHtIe5h7uHvYfCh8SHxofIiAeICYgLiA2IEIgRiBKIE4gUiBaIGIgZiBqIHIgdiFyIXohgiGKIZYhmiGeIaIhpiGuIbYhuiG+IcYhyiLGIs4i1iLeIuoi7iLyIvYi+iMCIwojDiMSIxojHiQaJCIkKiQyJD4kQiRGJEokTiRWJF4kYiRmJG4kciVuJXYlfiWGJZIlliWaJZ4loiWqJbIltiW6JcIlxiZaJuonhigWKCIoKigyKDooQihKKE4oWiiOKMoo0ijaKOIo6ijyKPopAik+KUopViliKW4peimGKZIpmiqWKp4qqiqyKr4qwirGKsoqzirWKt4q4irmKu4q8ivuK/Yr/iwGLBIsFiwaLB4sIiwqLDIsNiw6LEIsRi1CLUotVi1eLWotbi1yLXYtei2CLYotji2SLZotni6aLqIuqi6yLr4uwi7GLsouzi7WLt4u4i7mLu4u8i/uL/Yv/jAGMBIwFjAaMB4wIjAqMDIwNjA6MEIwRjFCMUoxUjFaMWYxajFuMXIxdjF+MYYxijGOMZYxmjKWMp4ypjKuMroyvjLCMsYyyjLSMtoy3jLiMuoy7jMSM14zkjPeNBI0XjS6NQI2Lja6Nzo3ujfCN8o30jfaN+I35jfqN/Y3+jgCOAY4DjgWOBo4HjgqOC44UjiGOJo4ojiqOL44yjjWON45cjoCOp47Ljs6O0I7SjtSO1o7YjtmO3I7pjvqO/I7+jwCPAo8EjwaPCI8KjxuPHo8hjySPJ48qjy2PMI8zjzWPdI92j3iPeo99j36Pf4+Aj4GPg4+Fj4aPh4+Jj4qPyY/Lj82Pz4/Sj9OP1I/Vj9aP2I/aj9uP3I/ej9+QHpAgkCOQJZAokCmQKpArkCyQLpAwkDGQMpA0kDWQQpBHkEmQS5BQkFKQVZBXkGSQaZBrkG2QcpB0kHaQeJC3kLmQu5C9kMCQwZDCkMOQxJDGkMiQyZDKkMyQzZEMkQ6REJESkRWRFpEXkRiRGZEbkR2RHpEfkSGRIpFhkWORZZFnkWqRa5FskW2RbpFwkXKRc5F0kXaRd5G2kbiRupG8kb+RwJHBkcKRw5HFkceRyJHJkcuRzJILkg2SD5IRkhSSFZIWkheSGJIakhySHZIekiCSIZJGkmqSkZK1kriSupK8kr6SwJLCksOSxpLTkuKS5JLmkuiS6pLsku6S8JL/kwKTBZMIkwuTDpMRkxSTFpNVk1eTWZNbk16TX5Ngk2GTYpNkk2aTZ5Nok2qTa5Oqk6yTrpOwk7OTtJO1k7aTt5O5k7uTvJO9k7+TwJP/lAGUA5QFlAiUCZQKlAuUDJQOlBCUEZQSlBSUFZRUlFaUWJRalF2UXpRflGCUYZRjlGWUZpRnlGmUapSplKuUrZSvlLKUs5S0lLWUtpS4lLqUu5S8lL6Uv5T+lQCVApUElQeVCJUJlQqVC5UNlQ+VEJURlROVFJVTlVWVV5VZlVyVXZVelV+VYJVilWSVZZVmlWiVaZW0ldeV95YXlhmWG5Ydlh+WIZYiliOWJpYnlimWKpYsli6WL5YwljOWNJY9lkqWT5ZRllOWWJZbll6WYJaFlqmW0Jb0lveW+Zb7lv2W/5cBlwKXBZcSlyOXJZcnlymXK5ctly+XMZczl0SXR5dKl02XUJdTl1aXWZdcl16XnZefl6GXo5eml6eXqJepl6qXrJeul6+XsJeyl7OX8pf0l/aX+Jf7l/yX/Zf+l/+YAZgDmASYBZgHmAiYR5hJmEyYTphRmFKYU5hUmFWYV5hZmFqYW5hdmF6Ya5hwmHKYdJh5mHuYfpiAmI2YkpiUmJaYm5idmJ+YoZjgmOKY5JjmmOmY6pjrmOyY7ZjvmPGY8pjzmPWY9pk1mTeZOZk7mT6ZP5lAmUGZQplEmUaZR5lImUqZS5mKmYyZjpmQmZOZlJmVmZaZl5mZmZuZnJmdmZ+ZoJnfmeGZ45nlmeiZ6ZnqmeuZ7JnumfCZ8ZnymfSZ9Zo0mjaaOJo6mj2aPpo/mkCaQZpDmkWaRppHmkmaSppvmpOaupremuGa45rlmuea6Zrrmuya75r8mwubDZsPmxGbE5sVmxebGZsomyubLpsxmzSbN5s6mz2bP5t+m4CbgpuEm4ebiJuJm4qbi5uNm4+bkJuRm5OblJvTm9Wb15vZm9yb3Zvem9+b4Jvim+Sb5Zvmm+ib6ZwonCqcLJwunDGcMpwznDScNZw3nDmcOpw7nD2cPpx9nH+cgZyDnIach5yInImcipyMnI6cj5yQnJKck5zSnNSc1pzYnNuc3JzdnN6c35zhnOOc5JzlnOec6J0nnSmdK50tnTCdMZ0ynTOdNJ02nTidOZ06nTydPZ18nX6dgJ2CnYWdhp2HnYidiZ2LnY2djp2PnZGdkp3dngCeIJ5AnkKeRJ5GnkieSp5LnkyeT55QnlKeU55VnleeWJ5ZnlyeXZ5mnnOeeJ56nnyegZ6EnoeeiZ6untKe+Z8dnyCfIp8knyafKJ8qnyufLp87n0yfTp9Qn1KfVJ9Wn1ifWp9cn22fcJ9zn3afeZ98n3+fgp+Fn4efxp/In8qfzJ/Pn9Cf0Z/Sn9Of1Z/Xn9if2Z/bn9ygG6AdoB+gIaAkoCWgJqAnoCigKqAsoC2gLqAwoDGgcKByoHWgd6B6oHugfKB9oH6ggKCCoIOghKCGoIeglKCZoJugnaCioKSgp6CpoLagu6C9oL+gxKDGoMigyqEJoQuhDaEPoRKhE6EUoRWhFqEYoRqhG6EcoR6hH6FeoWChYqFkoWehaKFpoWqha6FtoW+hcKFxoXOhdKGzobWht6G5obyhvaG+ob+hwKHCocShxaHGocihyaIIogqiDKIOohGiEqITohSiFaIXohmiGqIboh2iHqJdol+iYaJjomaiZ6JoommiaqJsom6ib6JwonKic6KYoryi46MHowqjDKMOoxCjEqMUoxWjGKMlozSjNqM4ozqjPKM+o0CjQqNRo1SjV6Nao12jYKNjo2ajaKOno6mjq6Oto7CjsaOyo7OjtKO2o7ijuaO6o7yjvaP8o/6kAKQCpAWkBqQHpAikCaQLpA2kDqQPpBGkEqRRpFOkVaRXpFqkW6RcpF2kXqRgpGKkY6RkpGakZ6SmpKikqqSspK+ksKSxpLKks6S1pLekuKS5pLukvKT7pP2k/6UBpQSlBaUGpQelCKUKpQylDaUOpRClEaVQpVKlVKVWpVmlWqVbpVylXaVfpWGlYqVjpWWlZqWlpaelqaWrpa6lr6WwpbGlsqW0pbalt6W4pbqlu6YGpimmSaZppmumbaZvpnGmc6Z0pnWmeKZ5pnumfKZ+poCmgaaCpoWmhqaPppymoaajpqWmqqatprCmsqbXpvunIqdGp0mnS6dNp0+nUadTp1SnV6dkp3Wnd6d5p3unfad/p4Gng6eFp5anmaecp5+noqelp6inq6eup7Cn76fxp/On9af4p/mn+qf7p/yn/qgAqAGoAqgEqAWoRKhGqEioSqhNqE6oT6hQqFGoU6hVqFaoV6hZqFqomaibqJ6ooKijqKSopaimqKeoqairqKyoraivqLCovajCqMSoxqjLqM2o0KjSqN+o5KjmqOio7ajvqPGo86kyqTSpNqk4qTupPKk9qT6pP6lBqUOpRKlFqUepSKmHqYmpi6mNqZCpkamSqZOplKmWqZipmamaqZypnancqd6p4KniqeWp5qnnqeip6anrqe2p7qnvqfGp8qoxqjOqNao3qjqqO6o8qj2qPqpAqkKqQ6pEqkaqR6qGqoiqiqqMqo+qkKqRqpKqk6qVqpeqmKqZqpuqnKrBquWrDKswqzOrNas3qzmrO6s9qz6rQatOq12rX6thq2OrZatnq2mra6t6q32rgKuDq4ariauMq4+rkavQq9Kr1avXq9qr26vcq92r3qvgq+Kr46vkq+ar56wmrCisKqwsrC+sMKwxrDKsM6w1rDesOKw5rDusPKx7rH2sf6yBrISshayGrIesiKyKrIysjayOrJCskazQrNKs1azXrNqs26zcrN2s3qzgrOKs46zkrOas56zqrSmtK60trS+tMq0zrTStNa02rTitOq07rTytPq0/rX6tgK2CrYSth62IrYmtiq2LrY2tj62QrZGtk62UrdOt1a3Xrdmt3K3drd6t363greKt5K3lreat6K3prjSuV653rpeuma6brp2un66hrqKuo66mrqeuqa6qrqyurq6vrrCus660rr2uyq7PrtGu067Yrtuu3q7grwWvKa9Qr3Svd695r3uvfa9/r4Gvgq+Fr5Kvo6+lr6evqa+rr62vr6+xr7OvxK/Hr8qvza/Qr9Ov1q/Zr9yv3rAdsB+wIbAjsCawJ7AosCmwKrAssC6wL7AwsDKwM7BysHSwdrB4sHuwfLB9sH6wf7CBsIOwhLCFsIewiLDHsMmwzLDOsNGw0rDTsNSw1bDXsNmw2rDbsN2w3rDrsPCw8rD0sPmw+7D+sQCxDbESsRSxFrEbsR2xH7EhsWCxYrFksWaxabFqsWuxbLFtsW+xcbFysXOxdbF2sbWxt7G5sbuxvrG/scCxwbHCscSxxrHHscixyrHLsgqyDLIOshCyE7IUshWyFrIXshmyG7Icsh2yH7Igsl+yYbJjsmWyaLJpsmqya7Jssm6ycLJxsnKydLJ1srSytrK4srqyvbK+sr+ywLLBssOyxbLGsseyybLKsu+zE7M6s16zYbNjs2WzZ7Nps2uzbLNvs3yzi7ONs4+zkbOTs5Wzl7OZs6izq7Ous7GztLO3s7qzvbO/s/60ALQDtAW0CLQJtAq0C7QMtA60ELQRtBK0FLQVtFS0VrRYtFq0XbRetF+0YLRhtGO0ZbRmtGe0abRqtKm0q7SttK+0srSztLS0tbS2tLi0urS7tLy0vrS/tP61ALUCtQS1B7UItQm1CrULtQ21D7UQtRG1E7UUtVO1VbVXtVm1XLVdtV61X7VgtWK1ZLVltWa1aLVptai1qrWsta61sbWytbO1tLW1tbe1ubW6tbu1vbW+tf21/7YBtgO2BrYHtgi2CbYKtgy2DrYPthC2ErYTtl62gbahtsG2w7bFtse2ybbLtsy2zbbQttG207bUtta22LbZttq23bbetuO28Lb1tve2+bb+twG3BLcGtyu3T7d2t5q3nbeft6G3o7elt6e3qLert7i3ybfLt823z7fRt9O31bfXt9m36rftt/C387f2t/m3/Lf/uAK4BLhDuEW4R7hJuEy4TbhOuE+4ULhSuFS4VbhWuFi4WbiYuJq4nLieuKG4orijuKS4pbinuKm4qriruK24rrjtuO+48rj0uPe4+Lj5uPq4+7j9uP+5ALkBuQO5BLkRuRa5GLkauR+5IbkkuSa5M7k4uTq5PLlBuUO5RblHuYa5iLmKuYy5j7mQuZG5krmTuZW5l7mYuZm5m7mcudu53bnfueG55Lnluea557noueq57Lntue658LnxujC6Mro0uja6Obo6uju6PLo9uj+6QbpCukO6RbpGuoW6h7qJuou6jrqPupC6kbqSupS6lrqXupi6mrqbutq63LreuuC647rkuuW65rrnuum667rsuu2677rwuxW7Obtgu4S7h7uJu4u7jbuPu5G7kruVu6K7sbuzu7W7t7u5u7u7vbu/u8670bvUu9e72rvdu+C747vlvCS8JrwpvCu8LrwvvDC8MbwyvDS8Nrw3vDi8Orw7vHq8fLx+vIC8g7yEvIW8hryHvIm8i7yMvI28j7yQvM+80bzTvNW82LzZvNq827zcvN684LzhvOK85LzlvSS9Jr0pvSu9Lr0vvTC9Mb0yvTS9Nr03vTi9Or07vXq9fL1+vYC9g72EvYW9hr2HvYm9i72MvY29j72Qvc+90b3TvdW92L3Zvdq9273cvd694L3hveK95L3lviS+Jr4oviq+Lb4uvi++ML4xvjO+Nb42vje+Ob46voW+qL7Ivui+6r7svu6+8L7yvvO+9L73vvi++r77vv2+/78AvwG/BL8Fvwq/F78cvx6/IL8lvyi/K78tv1K/dr+dv8G/xL/Gv8i/yr/Mv86/z7/Sv9+/8L/yv/S/9r/4v/q//L/+wADAEcAUwBfAGsAdwCDAI8AmwCnAK8BqwGzAbsBwwHPAdMB1wHbAd8B5wHvAfMB9wH/AgMC/wMHAw8DFwMjAycDKwMvAzMDOwNDA0cDSwNTA1cEUwRbBGcEbwR7BH8EgwSHBIsEkwSbBJ8EowSrBK8E4wTnBOsE8wXvBfcF/wYHBhMGFwYbBh8GIwYrBjMGNwY7BkMGRwdDB0sHUwdbB2cHawdvB3MHdwd/B4cHiwePB5cHmwiXCJ8IpwivCLsIvwjDCMcIywjTCNsI3wjjCOsI7wnrCfMJ+woDCg8KEwoXChsKHwonCi8KMwo3Cj8KQws/C0cLTwtXC2MLZwtrC28Lcwt7C4MLhwuLC5MLlwwrDLsNVw3nDfMN+w4DDgsOEw4bDh8OKw5fDpsOow6rDrMOuw7DDssO0w8PDxsPJw8zDz8PSw9XD2MPaxBnEG8QdxB/EIsQjxCTEJcQmxCjEKsQrxCzELsQvxG7EcMRyxHTEd8R4xHnEesR7xH3Ef8SAxIHEg8SExMPExcTHxMnEzMTNxM7Ez8TQxNLE1MTVxNbE2MTZxRjFGsUdxR/FIsUjxSTFJcUmxSjFKsUrxSzFLsUvxW7FcMVyxXTFd8V4xXnFesV7xX3Ff8WAxYHFg8WExcPFxcXHxcnFzMXNxc7Fz8XQxdLF1MXVxdbF2MXZxhjGGsYcxh7GIcYixiPGJMYlxifGKcYqxivGLcYuxnnGnMa8xtzG3sbgxuLG5MbmxufG6MbrxuzG7sbvxvHG88b0xvXG+Mb5xwLHD8cUxxbHGMcdxyDHI8clx0rHbseVx7nHvMe+x8DHwsfEx8bHx8fKx9fH6Mfqx+zH7sfwx/LH9Mf2x/jICcgMyA/IEsgVyBjIG8geyCHII8hiyGTIZshoyGvIbMhtyG7Ib8hxyHPIdMh1yHfIeMi3yLnIu8i9yMDIwcjCyMPIxMjGyMjIycjKyMzIzckMyQ7JEckTyRbJF8kYyRnJGskcyR7JH8kgySLJI8kwyTXJN8k5yT7JQMlDyUXJUslXyVnJW8lgyWLJZMlmyaXJp8mpyavJrsmvybDJscmyybTJtsm3ybjJusm7yfrJ/Mn+ygDKA8oEygXKBsoHygnKC8oMyg3KD8oQyk/KUcpTylXKWMpZylrKW8pcyl7KYMphymLKZMplyqTKpsqoyqrKrcquyq/KsMqxyrPKtcq2yrfKucq6yvnK+8r9yv/LAssDywTLBcsGywjLCssLywzLDssPyzTLWMt/y6PLpsuoy6rLrMuuy7DLscu0y8HL0MvSy9TL1svYy9rL3Mvey+3L8Mvzy/bL+cv8y//MAswEzEPMRcxHzEnMTMxNzE7MT8xQzFLMVMxVzFbMWMxZzJjMmsyczJ7MocyizKPMpMylzKfMqcyqzKvMrcyuzO3M78zxzPPM9sz3zPjM+cz6zPzM/sz/zQDNAs0DzULNRM1GzUjNS81MzU3NTs1PzVHNU81UzVXNV81YzZfNmc2bzZ3NoM2hzaLNo82kzabNqM2pzarNrM2tzezN7s3wzfLN9c32zffN+M35zfvN/c3+zf/OAc4CzkHOQ85FzkfOSs5LzkzOTc5OzlDOUs5TzlTOVs5XzqLOxc7lzwXPB88JzwvPDc8PzxDPEc8UzxXPF88YzxrPHM8dzx7PIc8izyfPNM85zzvPPc9Cz0XPSM9Kz2/Pk8+6z97P4c/jz+XP58/pz+vP7M/vz/zQDdAP0BHQE9AV0BfQGdAb0B3QLtAx0DTQN9A60D3QQNBD0EbQSNCH0InQi9CN0JDQkdCS0JPQlNCW0JjQmdCa0JzQndDc0N7Q4NDi0OXQ5tDn0OjQ6dDr0O3Q7tDv0PHQ8tEx0TPRNtE40TvRPNE90T7RP9FB0UPRRNFF0UfRSNFV0VrRXNFe0WPRZdFo0WrRd9F80X7RgNGF0YfRidGL0crRzNHO0dDR09HU0dXR1tHX0dnR29Hc0d3R39Hg0h/SIdIj0iXSKNIp0irSK9Is0i7SMNIx0jLSNNI10nTSdtJ40nrSfdJ+0n/SgNKB0oPShdKG0ofSidKK0snSy9LN0s/S0tLT0tTS1dLW0tjS2tLb0tzS3tLf0x7TINMi0yTTJ9Mo0ynTKtMr0y3TL9Mw0zHTM9M001nTfdOk08jTy9PN08/T0dPT09XT1tPZ0+bT9dP30/nT+9P90//UAdQD1BLUFdQY1BvUHtQh1CTUJ9Qp1GjUatRt1G/UctRz1HTUddR21HjUetR71HzUftR/1L7UwNTC1MTUx9TI1MnUytTL1M3Uz9TQ1NHU09TU1RPVFdUX1RnVHNUd1R7VH9Ug1SLVJNUl1SbVKNUp1WjVatVs1W7VcdVy1XPVdNV11XfVedV61XvVfdV+1b3Vv9XB1cPVxtXH1cjVydXK1czVztXP1dDV0tXT1hLWFNYW1hjWG9Yc1h3WHtYf1iHWI9Yk1iXWJ9Yo1mfWadZr1m3WcNZx1nLWc9Z01nbWeNZ51nrWfNZ91ojWkdaS1pTWndao1rfWwtbQ1uXW+dcQ1yLXYddj12XXZ9dp12rXa9ds123Xb9dx13LXc9d113bXtde317nXu9e9177Xv9fA18HXw9fF18bXx9fJ18rYCdgL2A7YENgS2BPYFNgV2BbYGNga2BvYHNge2B/YatiN2K3YzdjP2NHY09jV2NfY2NjZ2NzY3djf2ODY4tjk2OXY5tjp2OrY79j82QHZA9kF2QrZDdkQ2RLZN9lb2YLZptmp2avZrdmv2bHZs9m02bfZxNnV2dfZ2dnb2d3Z39nh2ePZ5dn22fnZ/Nn/2gLaBdoI2gvaDtoQ2k/aUdpT2lXaWNpZ2lraW9pc2l7aYNph2mLaZNpl2qTaptqo2qrardqu2q/asNqx2rPatdq22rfaudq62vna+9r+2wDbA9sE2wXbBtsH2wnbC9sM2w3bD9sQ2x3bItsk2ybbK9st2zDbMts/20TbRttI203bT9tR21PbktuU25bbmNub25zbndue25/boduj26Tbpdun26jb59vp2+vb7dvw2/Hb8tvz2/Tb9tv42/nb+tv82/3cPNw+3EDcQtxF3EbcR9xI3EncS9xN3E7cT9xR3FLckdyT3JXcl9ya3JvcnNyd3J7coNyi3KPcpNym3Kfc5tzo3Orc7Nzv3PDc8dzy3PPc9dz33Pjc+dz73PzdId1F3WzdkN2T3ZXdl92Z3Zvdnd2e3aHdrt293b/dwd3D3cXdx93J3cvd2t3d3eDd493m3end7N3v3fHeMN4y3jTeNt453jreO9483j3eP95B3kLeQ95F3kbehd6H3onei96O3o/ekN6R3pLelN6W3pfemN6a3pve2t7c3t7e4N7j3uTe5d7m3ufe6d7r3uze7d7v3vDfL98x3zPfNd843znfOt873zzfPt9A30HfQt9E30XfhN+G34jfit+N347fj9+Q35Hfk9+V35bfl9+Z35rf2d/b393f39/i3+Pf5N/l3+bf6N/q3+vf7N/u3+/gLuAw4DLgNOA34DjgOeA64DvgPeA/4EDgQeBD4ETgTeBO4FDgXeBe4F/gYeBu4G/gcOBy4H/ggOCB4IPgjOCb4Kjgt+DJ4N3g9OEG4Q/hEOES4R/hIOEh4SPhLOE24T3hR+FP4WHhZuFrAAAAAAAAAgIAAAAAAAAh4gAAAAAAAAAAAAAAAAAA4W0= + + Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel + YnBsaXN0MDDUAAEAAgADAAQABQAGICIgI1gkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv +cBIAAYagrxECpgAHAAgAFwAYADQANQA2AEAAQQBCAF0AXgBfAGUAZgByAIYAhwCIAIkAigCLAIwAjQCOAKcAsAC/AM4A3QDgAOQAXAD0AQMBCQEKAQsBDwEeASQBJQEtATwBPQFGAVIBUwFUAVUBVgFrAWwBdAF1AXYBggGWAZcBmAGZAZoBmwGcAZ0BngGtAbwBywHTAdQB3AHdAd4B3wHgAe8B/gH/Ag4CHQIsAjgCSgJLAkwCTQJOAk8CUAJRAmACbwJ+Ao0CjgKdAqwCuwLDAtgC2QLhAu0DAQMQAx8DLgM2Az4DTQNcA2sDegOJA5UDpwO2A8UD1APjA/IEAQQQBCUEJgQuBC8EOwRPBF4EbQR8BIQEjASbBKoEuQTIBNcE4wT1BPYE9wT4BPkE+gT7BPwFCwUMBRsFHAUrBToFVAVVBVsFZwV7BYoFmQWoBbcFugXJBdgF3gXtBfwF/QYnBigGKQYqBisGLAYtBi4GLwYwBjEGMgYzBjQGNQY2BjcGOAY5BjoGTwZQBlgGZAZ4BocGlgalBq0GtQbEBtMG4gbxBwAHDAceBy0HPAdLB1oHaQd4B4cHnAedB6UHsQfFB9QH4wfyB/oIAggRCCAILwg+CE0IWQhrCHoIewiKCJkIqAipCLgIxwjWCOsI7Aj0CQAJFAkjCTIJQQlFCVQJYwlyCYEJkAmcCa4JvQnMCdsJ6gnrCfoKCQoYCi0KLgo2CkIKVgplCnQKgwqHCpYKpQq0CsMK0greCvAK/wsOCx0LLAs7C0oLWQtuC28LdwuDC5cLpgu1C8QLzAvUC+ML8gwBDBAMHwwrDD0MTAxbDGoMeQyIDJcMpgy7DLwMxAzQDOQM8w0CDRENFQ0kDTMNQg1RDWANbA1+DY0NnA2rDboNyQ3YDecN/A39DgUOEQ4lDjQOQw5SDlYOZQ50DoMOkg6hDq0Ovw7ODt0O7A77DwoPGQ8oDz0PPg9GD1IPZg91D4QPkw+XD6YPtQ/ED9MP4g/uEAAQDxAeEC0QPBBLEFoQaRB+EH8QhxCTEKcQthDFENQQ2BDnEPYRBREUESMRLxFBEVARXxFuEX0RjBGbEaoRvxHAEcgR1BHoEfcSBhIVEh0SJRI0EkMSUhJhEnASfBKOAC4SnRKsErsSyhLZEugS9xL/ExQTFRMdEykTPRNME1sTahNyE3oTiROYE6cTthPFE9ET4xPyFAEUEBQfFC4UPRRMFGEUYhRqFHYUihSZFKgUtxS7FMoU2RToFPcVBhUSFSQVMxVCFVEVYBVvFX4VjRWiFaMVqxW3FcsV2hXpFfgV/BYLFhoWKRY4FkcWUxZlFnQWgxaSFqEWsBa/Fs4W4xbkFuwW+BcMFxsXKhc5Fz0XTBdbF2oXeReIF5QXphe1F8QX0xfiF/EYABgPGCQYJRgtGDkYTRhcGGsYehiCGIoYmRioGLcYxhjVGOEY8xkCGREZIBkvGT4ZTRlcGXEZchl6GYYZmhmpGbgZxxnPGdcZ5hn1GgQaExoiGi4aQBpPGl4abRp8GosamhqpGr4avxrHGtMa5xr2GwUbFBsYGycbNhtFG1QbYxtvG4EbkBufG64bvRvMG9sb6hv/HAAcCBwUHCgcNxxGHFUcXRxlHHQcgxySHKEcsBy8HM4c3RzsHPsdCh0ZHSgdNx1MHU0dVR1hHXUdhB2THaIdph21HcQd0x3iHfEd/R4PHh4eLR48HkseWh5pHngeeR58HoUelB6jHrIexx7IHtAe3B7wHv8fDh8dHyUfLR88H0sfWh9pH3gfhB+WH6UftB/DH9If4R/wH/8gAiAGIAogDiAWIBkgHVUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAFQATXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoADgQKlgQKjgACBAqSAAoAAXxAUdW50aXRsZWQueGNkYXRhbW9kZWzeABkAGgAbABwAHQAeAB8ACgAgACEAIgAjACQAJQAmACcAKAApACYAEwAsAC0ALgAvADAAJgAmABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgAWBAqGBAp+AAYAFgACBAqCBAqIQAIAGgASABYAFgABQU1lFU9MANwA4AAoAOQA8AD9XTlMua2V5c1pOUy5vYmplY3RzogA6ADuAB4AIogA9AD6ACYCagCVYRGF0YWJhc2VaQ29ubmVjdGlvbt8QEABDAEQARQBGAB4ARwBIACAASQBKAAoAIgBLAEwAJQBNAE4ATwAmACYAEABTAFQALgAmAE4AVwA6AE4AWgBbAFxfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2VfECBYREJ1Y2tldEZvclN0ZXJlb3R5cGVzd2FzRW5jb2RlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNzdG9yYWdlXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNkdXBsaWNhdGVzXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3N0b3JhZ2VbX2lzQWJzdHJhY3SAC4AtgAWABYADgAyBAoCABYALgQKCgAeAC4ECnoAKCBIRg6h7V29yZGVyZWTTADcAOAAKAGAAYgA/oQBhgA2hAGOADoAlXlhEX1BTdGVyZW90eXBl2QAeACIAZwAKACUAaAAgAE0AaQA9AGEATgBtABMAJgAuAFwAcV8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ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UACAAlQAKACIAlgCXACUAmAATABMAEwQrAFwAXABcAC4AXAChAYUAXABcABMAXIAAgACAAIB/CAgICIAZgDoICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATBG8AEwQrAFwAXABcAC4AXAChAYYAXABcABMAXIAAgISAAIB/CAgICIAZgDsICIAACNMANwA4AAoEfQSAAD+iAQUBzoAjgEWiAQcEgoAkgIWAJdMANwA4AAoEhQSIAD+iAdYB14BHgEiiAdkB2oBJgEqAJd8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAfEAEwQrAFwAXABcAC4AXAChAYcAXABcABMAXIAAgE2AAIB/CAgICIAZgDwICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAfEAEwQrAFwAXABcAC4AXAChAYgAXABcABMAXIAAgE2AAIB/CAgICIAZgD0ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwQrAFwAXABcAC4AXAChAYkAXABcABMAXIAAgCCAAIB/CAgICIAZgD4ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwQrAFwAXABcAC4AXAChAYoAXABcABMAXIAAgACAAIB/CAgICIAZgD8ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwQrAFwAXABcAC4AXAChAYsAXABcABMAXIAAgCCAAIB/CAgICIAZgEAICIAACNkAHgAiBNgACgAlBNkAIABNBNoBTwQpAE4AbQATACYALgBcBOJfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAe4B+gAuALIAAgAUIgIzTADcAOAAKBOQE7AA/pwTlBOYE5wToBOkE6gTrgI2AjoCPgJCAkYCSgJOnBO0E7gTvBPAE8QTyBPOAlICWgJiAmYECg4EChIEChYAlXxAPWERfUFJLX21pbkNvdW50XxARWER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AXIAAgCCAAIDzCAgICIAZgDwICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAfEAEwjxAFwAXABcAC4AXAChAYgAXABcABMAXIAAgE2AAIDzCAgICIAZgD0ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwjxAFwAXABcAC4AXAChAYkAXABcABMAXIAAgCCAAIDzCAgICIAZgD4ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwjxAFwAXABcAC4AXAChAYoAXABcABMAXIAAgACAAIDzCAgICIAZgD8ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwjxAFwAXABcAC4AXAChAYsAXABcABMAXIAAgCCAAIDzCAgICIAZgEAICIAACNkAHgAiCZEACgAlCZIAIABNCZMGFQFvAE4AbQATACYALgBcCZtfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WA8IA2gAuALIAAgAUIgP/TADcAOAAKCZ0JpQA/pwI6AjsCPAI9Aj4CPwJAgFOAVIBVgFaAV4BYgFmnCaYJpwmoCakJqgmrCayBAQCBAQGBAQKBAQOBAQWBAQaBAQeAJd8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwjyAFwAXABcAC4AXAChAjoAXABcABMAXIAAgACAAID+CAgICIAZgFMICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwjyAFwAXABcAC4AXAChAjsAXABcABMAXIAAgCCAAID+CAgICIAZgFQICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwjyAFwAXABcAC4AXAChAjwAXABcABMAXIAAgACAAID+CAgICIAZgFUICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATCd0AEwjyAFwAXAB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T0RPiE+QT5hPoE+oT7BPuE/AT8hP0FBIUMBRDFFcUbBSJFJ0UsxTyFPQU9hT4FPoU+xT8FP0U/hUAFQIVAxUEFQYVBxVGFUgVShVMFU4VTxVQFVEVUhVUFVYVVxVYFVoVWxWaFZwVnhWgFaIVoxWkFaUVphWoFaoVqxWsFa4VrxW8FcEVwxXFFcoVzBXOFdAWAxYQFhUWFxYZFh4WIBYiFiQWOhZMFlAWVhaVFpcWmRabFp0WnhafFqAWoRajFqUWphanFqkWqhbpFusW7RbvFvEW8hbzFvQW9Rb3FvkW+hb7Fv0W/hb/Fz4XQBdCF0QXRhdHF0gXSRdKF0wXThdPF1AXUhdTF5IXlBeWF5gXmhebF5wXnReeF6AXohejF6QXphenF+YX6BfqF+wX7hfvF/AX8RfyF/QX9hf3F/gX+hf7GCAYRBhrGI8YkRiTGJUYlxiZGJsYnBieGKsYuhi8GL4YwBjCGMQYxhjIGNcY2RjbGN0Y3xjhGOMY5RjnGQcZMhlMGWUZfxmfGcIaARoDGgUaBxoJGgoaCxoMGg0aDxoRGhIaExoVGhYaVRpXGlkaWxpdGl4aXxpgGmEaYxplGmYaZxppGmoaqRqrGq0arxqxGrIasxq0GrUatxq5Groauxq9Gr4a/Rr/GwEbAxsFGwYbBxsIGwkbCxsNGw4bDxsRGxIbFRtUG1YbWBtaG1wbXRteG18bYBtiG2QbZRtmG2gbaRuoG6obrBuuG7AbsRuyG7MbtBu2G7gbuRu6G7wbvRv8G/4cABwCHAQcBRwGHAccCBwKHAwcDRwOHBAcERwaHCgcNRxDHFAcYxx6HIwc1xz6HRodOh08HT4dQB1CHUQdRR1GHUgdSR1LHUwdTh1QHVEdUh1UHVUdWh1nHWwdbh1wHXUddx15HXsdoB3EHeseDx4RHhMeFR4XHhkeGx4cHh4eKx48Hj4eQB5CHkQeRh5IHkoeTB5dHl8eYR5jHmUeZx5pHmsebR5vHq4esB6yHrQeth63HrgeuR66Hrwevh6/HsAewh7DHwIfBB8GHwgfCh8LHwwfDR8OHxAfEh8THxQfFh8XH1YfWB9aH1wfXh9fH2AfYR9iH2QfZh9nH2gfah9rH3gffR9/H4Efhh+IH4ofjB+ZH54foB+iH6cfqR+rH60f7B/uH/Af8h/0H/Uf9h/3H/gf+h/8H/0f/iAAIAEgQCBCIEQgRiBIIEkgSiBLIEwgTiBQIFEgUiBUIFUglCCWIJggmiCcIJ0gniCfIKAgoiCkIKUgpiCoIKkg6CDqIOwg7iDwIPEg8iDzIPQg9iD4IPkg+iD8IP0hPCE+IUAhQiFEIUUhRiFHIUghSiFMIU0hTiFQIVEhdiGaIcEh5SHnIekh6yHtIe8h8SHyIfQiASIQIhIiFCIWIhgiGiIcIh4iLSIvIjEiMyI1IjciOSI7Ij0ifCJ+IoAigiKEIoUihiKHIogiiiKMIo0ijiKQIpEi0CLSItQi1iLYItki2iLbItwi3iLgIuEi4iLkIuUjJCMmIygjKiMsIy0jLiMvIzAjMiM0IzUjNiM4IzkjeCN6I3wjfiOAI4EjgiODI4QjhiOII4kjiiOMI40jzCPOI9Aj0iPUI9Uj1iPXI9gj2iPcI90j3iPgI+EkICQiJCQkJiQoJCkkKiQrJCwkLiQwJDEkMiQ0JDUkdCR2JHgkeiR8JH0kfiR/JIAkgiSEJIUkhiSIJIkk1CT3JRclNyU5JTslPSU/JUElQiVDJUUlRiVIJUklTCVOJU8lUCVSJVMlWCVlJWolbCVuJXMldSV3JXkljCWxJdUl/CYgJiImJCYmJigmKiYsJi0mLyY8Jk0mTyZRJlMmVSZXJlkmWyZdJm4mcCZyJnQmdiZ4JnomfCZ+JoAmvybBJsMmxSbHJsgmySbKJssmzSbPJtAm0SbTJtQnEycVJxcnGScbJxwnHSceJx8nIScjJyQnJScnJygnZydpJ2snbSdvJ3AncSdyJ3MndSd3J3gneSd7J3wniSeOJ5AnkieXJ5knmyedJ6onryexJ7MnuCe6J7wnvif9J/8oASgDKAUoBigHKAgoCSgLKA0oDigPKBEoEihRKFMoVShXKFkoWihbKFwoXShfKGEoYihjKGUoZiilKKcoqSirKK0oriivKLAosSizKLUotii3KLkouij5KPso/Sj/KQEpAikDKQQpBSkHKQkpCikLKQ0pDilNKU8pUSlTKVUpVilXKVgpWSlbKV0pXilfKWEpYimHKasp0in2Kfgp+in8Kf4qACoCKgMqBSoSKiEqIyolKicqKSorKi0qLyo+KkAqQipEKkYqSSpMKk8qUSpjKncqiSqeKrAqvyrcKxsrHSsfKyErIyskKyUrJisnKykrKyssKy0rLyswKzIrcStzK3Urdyt5K3oreyt8K30rfyuBK4IrgyuFK4YriCvHK8kryyvNK88r0CvRK9Ir0yvVK9cr2CvZK9sr3CwbLB0sHywhLCMsJCwlLCYsJywpLCssLCwtLC8sMCxzLJcsuyzeLQUtJS1MLXMtky23Ldst3S3fLeEt4y3lLect6i3sLe4t8S3zLfUt+C36LfsuAC4NLhAuEi4VLhcuGS4+LmIuiS6tLq8usS6zLrUuty65LrouvC7JLtou3C7eLuAu4i7kLuYu6C7qLvsu/S7/LwEvAy8FLwcvCS8LLw0vTC9OL1AvUi9UL1UvVi9XL1gvWi9cL10vXi9gL2EvoC+iL6Qvpi+oL6kvqi+rL6wvri+wL7Evsi+0L7Uv9C/2L/gv+i/8L/0v/i//MAAwAjAEMAUwBjAIMAkwSDBKMEwwTjBQMFEwUjBTMFQwVjBYMFkwWjBcMF0wZjBnMGkwqDCqMKwwrjCwMLEwsjCzMLQwtjC4MLkwujC8ML0w/DD+MQAxAjEEMQUxBjEHMQgxCjEMMQ0xDjEQMRExHjEhMSMxJjEoMSoxaTFrMW0xbzFxMXIxczF0MXUxdzF5MXoxezF9MX4xvTG/McExwzHFMcYxxzHIMckxyzHNMc4xzzHRMdIx5jHzMhwyHjIgMiIyJDImMigyKjIsMi4yMDIyMjQyNjI4MjoyPDI+MkAyQjJrMm0ybzJxMnQydzJ6Mn0ygDKDMoYyiTKMMo8ykjKVMpgymzKeMqEyozKtMrUyvDLGMtEy2jLmMvAy9TL/MwUzDzMYMyAzKDMvM0EzSTNRM5wzvzPfM/80ATQDNAU0BzQJNAo0CzQNNA40EDQRNBM0FTQWNBc0GTQaNCM0MDQ1NDc0OTQ+NEA0QjRENGk0jTS0NNg02jTcNN404DTiNOQ05TTnNPQ1BTUHNQk1CzUNNQ81ETUTNRU1JjUoNSo1LDUuNTA1MjU0NTY1ODV3NXk1ezV9NX81gDWBNYI1gzWFNYc1iDWJNYs1jDXLNc01zzXRNdM11DXVNdY11zXZNds13DXdNd814DYfNiE2IzYlNic2KDYpNio2KzYtNi82MDYxNjM2NDZBNkY2SDZKNk82UTZTNlU2YjZnNmk2azZwNnI2dDZ2NrU2tza5Nrs2vTa+Nr82wDbBNsM2xTbGNsc2yTbKNwk3CzcNNw83ETcSNxM3FDcVNxc3GTcaNxs3HTceN103XzdhN2M3ZTdmN2c3aDdpN2s3bTduN283cTdyN7E3sze1N7c3uTe6N7s3vDe9N783wTfCN8M3xTfGOAU4BzgJOAs4DTgOOA84EDgROBM4FTgWOBc4GTgaOD84YziKOK44sDiyOLQ4tji4OLo4uzi9OMo42TjbON043zjhOOM45TjnOPY4+Dj6OPw4/jkAOQI5BDkGOUU5RzlJOUs5TTlOOU85UDlROVM5VTlWOVc5WTlaOZk5mzmdOZ85oTmiOaM5pDmlOac5qTmqOas5rTmuOe057znxOfM59Tn2Ofc5+Dn5Ofs5/Tn+Of86AToCOkE6QzpFOkc6STpKOks6TDpNOk86UTpSOlM6VTpWOpU6lzqZOps6nTqeOp86oDqhOqM6pTqmOqc6qTqqOuk66zrtOu868TryOvM69Dr1Ovc6+Tr6Ovs6/Tr+Oz07PztBO0M7RTtGO0c7SDtJO0s7TTtOO087UTtSO507wDvgPAA8AjwEPAY8CDwKPAs8DDwOPA88ETwSPBQ8FjwXPBg8GjwbPCQ8MTw2PDg8Ojw/PEE8QzxFPGo8jjy1PNk82zzdPN884TzjPOU85jzoPPU9Bj0IPQo9DD0OPRA9Ej0UPRY9Jz0pPSs9LT0vPTE9Mz01PTc9OT14PXo9fD1+PYA9gT2CPYM9hD2GPYg9iT2KPYw9jT3MPc490D3SPdQ91T3WPdc92D3aPdw93T3ePeA94T4gPiI+JD4mPig+KT4qPis+LD4uPjA+MT4yPjQ+NT5CPkc+ST5LPlA+Uj5UPlY+Yz5oPmo+bD5xPnM+dT53PrY+uD66Prw+vj6/PsA+wT7CPsQ+xj7HPsg+yj7LPwo/DD8OPxA/Ej8TPxQ/FT8WPxg/Gj8bPxw/Hj8fP14/YD9iP2Q/Zj9nP2g/aT9qP2w/bj9vP3A/cj9zP7I/tD+2P7g/uj+7P7w/vT++P8A/wj/DP8Q/xj/HQAZACEAKQAxADkAPQBBAEUASQBRAFkAXQBhAGkAbQEBAZECLQK9AsUCzQLVAt0C5QLtAvEC+QMtA2kDcQN5A4EDiQORA5kDoQPdA+UD7QP1A/0EBQQNBBUEHQUZBSEFKQUxBTkFPQVBBUUFSQVRBVkFXQVhBWkFbQV1BnEGeQaBBokGkQaVBpkGnQahBqkGsQa1BrkGwQbFB8EHyQfRB9kH4QflB+kH7QfxB/kIAQgFCAkIEQgVCREJGQkhCSkJMQk1CTkJPQlBCUkJUQlVCVkJYQllCW0KaQpxCnkKgQqJCo0KkQqVCpkKoQqpCq0KsQq5Cr0LuQvBC8kL0QvZC90L4QvlC+kL8Qv5C/0MAQwJDA0NCQ0RDRkNIQ0pDS0NMQ01DTkNQQ1JDU0NUQ1ZDV0OiQ8VD5UQFRAdECUQLRA1ED0QQRBFEE0QURBZEF0QZRBtEHEQdRB9EIEQpRDZEO0Q9RD9ERERGREhESkRvRJNEukTeROBE4kTkROZE6ETqROtE7UT6RQtFDUUPRRFFE0UVRRdFGUUbRSxFLkUwRTJFNEU2RThFOkU8RT5FfUV/RYFFg0WFRYZFh0WIRYlFi0WNRY5Fj0WRRZJF0UXTRdVF10XZRdpF20XcRd1F30XhReJF40XlReZGJUYnRilGK0YtRi5GL0YwRjFGM0Y1RjZGN0Y5RjpGR0ZIRklGS0aKRoxGjkaQRpJGk0aURpVGlkaYRppGm0acRp5Gn0beRuBG4kbkRuZG50boRulG6kbsRu5G70bwRvJG80cyRzRHNkc4RzpHO0c8Rz1HPkdAR0JHQ0dER0ZHR0eGR4hHikeMR45Hj0eQR5FHkkeUR5ZHl0eYR5pHm0faR9xH3kfgR+JH40fkR+VH5kfoR+pH60fsR+5H70gUSDhIX0iDSIVIh0iJSItIjUiPSJBIkkifSK5IsEiySLRItki4SLpIvEjLSM5I0UjUSNdI2kjdSOBI4kkhSSNJJUknSSlJKkkrSSxJLUkvSTFJMkkzSTVJNkl1SXdJeUl7SX1Jfkl/SYBJgUmDSYVJhkmHSYlJiknJSctJzUnPSdFJ0knTSdRJ1UnXSdlJ2knbSd1J3kodSh9KIkokSiZKJ0ooSilKKkosSi5KL0owSjJKM0o2SnVKd0p5SntKfUp+Sn9KgEqBSoNKhUqGSodKiUqKSslKy0rNSs9K0UrSStNK1ErVStdK2UraSttK3UreSx1LH0shSyNLJUsmSydLKEspSytLLUsuSy9LMUsyS31LoEvAS+BL4kvkS+ZL6EvqS+tL7EvvS/BL8kvzS/VL90v4S/lL/Ev9TAJMD0wUTBZMGEwdTCBMI0wlTEpMbkyVTLlMvEy+TMBMwkzETMZMx0zKTNdM6EzqTOxM7kzwTPJM9Ez2TPhNCU0MTQ9NEk0VTRhNG00eTSFNI01iTWRNZk1oTWtNbE1tTW5Nb01xTXNNdE11TXdNeE23TblNu029TcBNwU3CTcNNxE3GTchNyU3KTcxNzU4MTg5OEU4TThZOF04YThlOGk4cTh5OH04gTiJOI04wTjFOMk40TnNOdU53TnlOfE59Tn5Of06AToJOhE6FToZOiE6JTshOyk7MTs5O0U7STtNO1E7VTtdO2U7aTttO3U7eTx1PH08hTyNPJk8nTyhPKU8qTyxPLk8vTzBPMk8zT3JPdE92T3hPe098T31Pfk9/T4FPg0+ET4VPh0+IT8dPyU/LT81P0E/RT9JP00/UT9ZP2E/ZT9pP3E/dUAJQJlBNUHFQdFB2UHhQelB8UH5Qf1CCUI9QnlCgUKJQpFCmUKhQqlCsULtQvlDBUMRQx1DKUM1Q0FDSURFRE1EVURdRGlEbURxRHVEeUSBRIlEjUSRRJlEnUWZRaFFqUWxRb1FwUXFRclFzUXVRd1F4UXlRe1F8UbtRvVG/UcFRxFHFUcZRx1HIUcpRzFHNUc5R0FHRUhBSElIUUhZSGVIaUhtSHFIdUh9SIVIiUiNSJVImUmVSZ1JpUmtSblJvUnBScVJyUnRSdlJ3UnhSelJ7UrpSvFK+UsBSw1LEUsVSxlLHUslSy1LMUs1Sz1LQUw9TEVMTUxVTGFMZUxpTG1McUx5TIFMhUyJTJFMlU3BTk1OzU9NT1VPXU9lT21PdU95T31PiU+NT5VPmU+hT6lPrU+xT71PwU/lUBlQLVA1UD1QUVBdUGlQcVEFUZVSMVLBUs1S1VLdUuVS7VL1UvlTBVM5U31ThVONU5VTnVOlU61TtVO9VAFUDVQZVCVUMVQ9VElUVVRhVGlVZVVtVXVVfVWJVY1VkVWVVZlVoVWpVa1VsVW5Vb1WuVbBVslW0VbdVuFW5VbpVu1W9Vb9VwFXBVcNVxFYDVgVWCFYKVg1WDlYPVhBWEVYTVhVWFlYXVhlWGlYnVixWLlYwVjVWN1Y6VjxWSVZOVlBWUlZXVllWW1ZdVpxWnlagVqJWpVamVqdWqFapVqtWrVauVq9WsVayVvFW81b1VvdW+lb7VvxW/Vb+VwBXAlcDVwRXBlcHV0ZXSFdKV0xXT1dQV1FXUldTV1VXV1dYV1lXW1dcV5tXnVefV6FXpFelV6ZXp1eoV6pXrFetV65XsFexV/BX8lf0V/ZX+Vf6V/tX/Ff9V/9YAVgCWANYBVgGWCtYT1h2WJpYnVifWKFYo1ilWKdYqFirWLhYx1jJWMtYzVjPWNFY01jVWORY51jqWO1Y8FjzWPZY+Vj7WTpZPFk+WUBZQ1lEWUVZRllHWUlZS1lMWU1ZT1lQWY9ZkVmTWZVZmFmZWZpZm1mcWZ5ZoFmhWaJZpFmlWeRZ5lnoWepZ7VnuWe9Z8FnxWfNZ9Vn2WfdZ+Vn6WjlaO1o9Wj9aQlpDWkRaRVpGWkhaSlpLWkxaTlpPWo5akFqSWpRal1qYWplamlqbWp1an1qgWqFao1qkWuNa5VrnWula7FrtWu5a71rwWvJa9Fr1WvZa+Fr5WzhbOls8Wz5bQVtCW0NbRFtFW0dbSVtKW0tbTVtOW5lbvFvcW/xb/lwAXAJcBFwGXAdcCFwLXAxcDlwPXBFcE1wUXBVcGFwZXB5cK1wwXDJcNFw5XDxcP1xBXGZcilyxXNVc2FzaXNxc3lzgXOJc41zmXPNdBF0GXQhdCl0MXQ5dEF0SXRRdJV0oXStdLl0xXTRdN106XT1dP11+XYBdgl2EXYddiF2JXYpdi12NXY9dkF2RXZNdlF3TXdVd113ZXdxd3V3eXd9d4F3iXeRd5V3mXehd6V4oXipeLV4vXjJeM140XjVeNl44XjpeO148Xj5eP15MXk1eTl5QXo9ekV6TXpVemF6ZXppem16cXp5eoF6hXqJepF6lXuRe5l7oXupe7V7uXu9e8F7xXvNe9V72Xvde+V76XzlfO189Xz9fQl9DX0RfRV9GX0hfSl9LX0xfTl9PX45fkF+SX5Rfl1+YX5lfml+bX51fn1+gX6Ffo1+kX+Nf5V/nX+lf7F/tX+5f71/wX/Jf9F/1X/Zf+F/5YB5gQmBpYI1gkGCSYJRglmCYYJpgm2CeYKtgumC8YL5gwGDCYMRgxmDIYNdg2mDdYOBg42DmYOlg7GDuYS1hL2ExYTNhNmE3YThhOWE6YTxhPmE/YUBhQmFDYYJhhGGGYYhhi2GMYY1hjmGPYZFhk2GUYZVhl2GYYddh2WHbYd1h4GHhYeJh42HkYeZh6GHpYeph7GHtYixiLmIwYjJiNWI2YjdiOGI5YjtiPWI+Yj9iQWJCYoFig2KFYodiimKLYoxijWKOYpBikmKTYpRilmKXYtZi2GLaYtxi32LgYuFi4mLjYuVi52LoYuli62LsYytjLWMvYzFjNGM1YzZjN2M4YzpjPGM9Yz5jQGNBY4xjr2PPY+9j8WPzY/Vj92P5Y/pj+2P+Y/9kAWQCZARkBmQHZAhkC2QMZBFkHmQjZCVkJ2QsZC9kMmQ0ZFlkfWSkZMhky2TNZM9k0WTTZNVk1mTZZOZk92T5ZPtk/WT/ZQFlA2UFZQdlGGUbZR5lIWUkZSdlKmUtZTBlMmVxZXNldWV3ZXple2V8ZX1lfmWAZYJlg2WEZYZlh2XGZchlymXMZc9l0GXRZdJl02XVZddl2GXZZdtl3GYbZh1mIGYiZiVmJmYnZihmKWYrZi1mLmYvZjFmMmY/ZkBmQWZDZoJmhGaGZohmi2aMZo1mjmaPZpFmk2aUZpVml2aYZtdm2WbbZt1m4GbhZuJm42bkZuZm6GbpZupm7GbtZyxnLmcwZzJnNWc2ZzdnOGc5ZztnPWc+Zz9nQWdCZ4Fng2eFZ4dnimeLZ4xnjWeOZ5BnkmeTZ5RnlmeXZ9Zn2GfaZ9xn32fgZ+Fn4mfjZ+Vn52foZ+ln62fsaBFoNWhcaIBog2iFaIdoiWiLaI1ojmiRaJ5orWivaLFos2i1aLdouWi7aMpozWjQaNNo1mjZaNxo32jhaSBpImkkaSZpKWkqaStpLGktaS9pMWkyaTNpNWk2aXVpd2l5aXtpfml/aYBpgWmCaYRphmmHaYhpimmLacppzGnOadBp02nUadVp1mnXadlp22ncad1p32ngah9qIWojaiVqKGopaipqK2osai5qMGoxajJqNGo1anRqdmp4anpqfWp+an9qgGqBaoNqhWqGaodqiWqKaslqy2rNas9q0mrTatRq1WrWathq2mrbatxq3mrfax5rIGsiayRrJ2soaylrKmsray1rL2swazFrM2s0a39romvCa+Jr5Gvma+hr6mvsa+1r7mvxa/Jr9Gv1a/dr+Wv6a/tr/mv/bARsEWwWbBhsGmwfbCJsJWwnbExscGyXbLtsvmzAbMJsxGzGbMhsyWzMbNls6mzsbO5s8GzybPRs9mz4bPptC20ObRFtFG0XbRptHW0gbSNtJW1kbWZtaG1qbW1tbm1vbXBtcW1zbXVtdm13bXltem25bbttvW2/bcJtw23EbcVtxm3Ibcpty23Mbc5tz24ObhBuE24VbhhuGW4abhtuHG4ebiBuIW4ibiRuJW4ybjNuNG42bnVud255bntufm5/boBugW6CboRuhm6Hbohuim6LbspuzG7ObtBu027UbtVu1m7Xbtlu227cbt1u327gbx9vIW8jbyVvKG8pbypvK28sby5vMG8xbzJvNG81b3Rvdm94b3pvfW9+b39vgG+Bb4NvhW+Gb4dviW+Kb8lvy2/Nb89v0m/Tb9Rv1W/Wb9hv2m/bb9xv3m/fcARwKHBPcHNwdnB4cHpwfHB+cIBwgXCEcJFwoHCicKRwpnCocKpwrHCucL1wwHDDcMZwyXDMcM9w0nDUcRNxFXEXcRlxHHEdcR5xH3EgcSJxJHElcSZxKHEpcWhxanFscW5xcXFycXNxdHF1cXdxeXF6cXtxfXF+cb1xv3HBccNxxnHHcchxyXHKccxxznHPcdBx0nHTchJyFHIWchhyG3Icch1yHnIfciFyI3IkciVyJ3IocmdyaXJrcm1ycHJxcnJyc3J0cnZyeHJ5cnpyfHJ9crxyvnLAcsJyxXLGcsdyyHLJcstyzXLOcs9y0XLScxFzE3MVcxdzGnMbcxxzHXMecyBzInMjcyRzJnMnc3JzlXO1c9Vz13PZc9tz3XPfc+Bz4XPkc+Vz53Poc+pz7HPtc+5z8XPyc/d0BHQJdAt0DXQSdBV0GHQadD90Y3SKdK50sXSzdLV0t3S5dLt0vHS/dMx03XTfdOF043TldOd06XTrdO10/nUBdQR1B3UKdQ11EHUTdRZ1GHVXdVl1W3VddWB1YXVidWN1ZHVmdWh1aXVqdWx1bXWsda51sHWydbV1tnW3dbh1uXW7db11vnW/dcF1wnYBdgN2BnYIdgt2DHYNdg52D3YRdhN2FHYVdhd2GHYldiZ2J3Ypdmh2anZsdm52cXZydnN2dHZ1dnd2eXZ6dnt2fXZ+dr12v3bBdsN2xnbHdsh2yXbKdsx2znbPdtB20nbTdxJ3FHcWdxh3G3ccdx13HncfdyF3I3ckdyV3J3cod2d3aXdrd213cHdxd3J3c3d0d3Z3eHd5d3p3fHd9d7x3vnfAd8J3xXfGd8d3yHfJd8t3zXfOd8930XfSd/d4G3hCeGZ4aXhreG14b3hxeHN4dHh3eIR4k3iVeJd4mXibeJ14n3iheLB4s3i2eLl4vHi/eMJ4xXjHeQZ5CHkKeQx5D3kQeRF5EnkTeRV5F3kYeRl5G3kceVt5XXlfeWF5ZHlleWZ5Z3loeWp5bHlteW55cHlxebB5snm0ebZ5uXm6ebt5vHm9eb95wXnCecN5xXnGegV6B3oJegt6DnoPehB6EXoSehR6FnoXehh6Gnobelp6XHpeemB6Y3pkemV6Znpneml6a3psem16b3pweq96sXqzerV6uHq5erp6u3q8er56wHrBesJ6xHrFewR7BnsIewp7DXsOew97EHsRexN7FXsWexd7GXsae2V7iHuoe8h7ynvMe8570HvSe9N71HvXe9h72nvbe9574Hvhe+J75Xvme+t7+Hv9e/98AXwGfAl8DHwOfDN8V3x+fKJ8pXynfKl8q3ytfK98sHyzfMB80XzTfNV813zZfNt83XzffOF88nz1fPh8+3z+fQF9BH0HfQp9DH1LfU19T31RfVR9VX1WfVd9WH1afVx9XX1efWB9YX2gfaJ9pH2mfal9qn2rfax9rX2vfbF9sn2zfbV9tn31ffd9+n38ff9+AH4BfgJ+A34Ffgd+CH4Jfgt+DH4Zfh5+IH4ifid+KX4sfi5+O35AfkJ+RH5Jfkt+TX5Pfo5+kH6SfpR+l36Yfpl+mn6bfp1+n36gfqF+o36kfuN+5X7nful+7H7tfu5+737wfvJ+9H71fvZ++H75fzh/On88fz5/QX9Cf0N/RH9Ff0d/SX9Kf0t/TX9Of41/j3+Rf5N/ln+Xf5h/mX+af5x/nn+ff6B/on+jf+J/5H/mf+h/63/sf+1/7n/vf/F/83/0f/V/93/4gB2AQYBogIyAj4CRgJOAlYCXgJmAmoCdgKqAuYC7gL2Av4DBgMOAxYDHgNaA2YDcgN+A4oDlgOiA64DtgSyBLoExgTOBNoE3gTiBOYE6gTyBPoE/gUCBQoFDgYKBhIGGgYiBi4GMgY2BjoGPgZGBk4GUgZWBl4GYgdeB2YHcgd6B4YHigeOB5IHlgeeB6YHqgeuB7YHugi2CL4IxgjOCNoI3gjiCOYI6gjyCPoI/gkCCQoJDgoKChIKGgoiCi4KMgo2CjoKPgpGCk4KUgpWCl4KYgteC2YLbgt2C4ILhguKC44LkguaC6ILpguqC7ILtgyyDLoMwgzKDNYM2gzeDOIM5gzuDPYM+gz+DQYNCg0uDXoNrg36Di4Oeg7WDx4QShDWEVYR1hHeEeYR7hH2Ef4SAhIGEhISFhIeEiISKhIyEjYSOhJGEkoSbhKiErYSvhLGEtoS5hLyEvoTjhQeFLoVShVWFV4VZhVuFXYVfhWCFY4VwhYGFg4WFhYeFiYWLhY2Fj4WRhaKFpYWohauFroWxhbSFt4W6hbyF+4X9hf+GAYYEhgWGBoYHhgiGCoYMhg2GDoYQhhGGUIZShlSGVoZZhlqGW4Zchl2GX4ZhhmKGY4ZlhmaGpYanhqqGrIavhrCGsYayhrOGtYa3hriGuYa7hryGyYbOhtCG0obXhtmG3IbehuuG8IbyhvSG+Yb7hv2G/4c+h0CHQodEh0eHSIdJh0qHS4dNh0+HUIdRh1OHVIeTh5WHl4eZh5yHnYeeh5+HoIeih6SHpYemh6iHqYfoh+qH7Ifuh/GH8ofzh/SH9Yf3h/mH+of7h/2H/og9iD+IQYhDiEaIR4hIiEmISohMiE6IT4hQiFKIU4iSiJSIloiYiJuInIidiJ6In4ihiKOIpIiliKeIqIjNiPGJGIk8iT+JQYlDiUWJR4lJiUqJTYlaiWmJa4ltiW+JcYlziXWJd4mGiYmJjImPiZKJlYmYiZuJnYncid6J4IniieWJ5onnieiJ6Ynrie2J7onvifGJ8ooxijOKNYo3ijqKO4o8ij2KPopAikKKQ4pEikaKR4qGioiKioqMio+KkIqRipKKk4qVipeKmIqZipuKnIrbit2K34rhiuSK5YrmiueK6IrqiuyK7YruivCK8YswizKLNIs2izmLOos7izyLPYs/i0GLQotDi0WLRouFi4eLiYuLi46Lj4uQi5GLkouUi5aLl4uYi5qLm4vai9yL3ovgi+OL5Ivli+aL54vpi+uL7Ivti++L8Iw7jF6MfoyejKCMooykjKaMqIypjKqMrYyujLCMsYyzjLWMtoy3jLqMu4zAjM2M0ozUjNaM24zejOGM440IjSyNU413jXqNfI1+jYCNgo2EjYWNiI2VjaaNqI2qjayNro2wjbKNtI22jceNyo3NjdCN043WjdmN3I3fjeGOII4ijiSOJo4pjiqOK44sji2OL44xjjKOM441jjaOdY53jnmOe45+jn+OgI6BjoKOhI6GjoeOiI6KjouOyo7Mjs+O0Y7UjtWO1o7XjtiO2o7cjt2O3o7gjuGO7o7vjvCO8o8xjzOPNY83jzqPO488jz2PPo9Aj0KPQ49Ej0aPR4+Gj4iPio+Mj4+PkI+Rj5KPk4+Vj5ePmI+Zj5uPnI/bj92P34/hj+SP5Y/mj+eP6I/qj+yP7Y/uj/CP8ZAwkDKQNJA2kDmQOpA7kDyQPZA/kEGQQpBDkEWQRpCFkIeQiZCLkI6Qj5CQkJGQkpCUkJaQl5CYkJqQm5DAkOSRC5EvkTKRNJE2kTiROpE8kT2RQJFNkVyRXpFgkWKRZJFmkWiRapF5kXyRf5GCkYWRiJGLkY6RkJHPkdGR05HVkdiR2ZHakduR3JHekeCR4ZHikeSR5ZIkkiaSKJIqki2SLpIvkjCSMZIzkjWSNpI3kjmSOpJ5knuSfZJ/koKSg5KEkoWShpKIkoqSi5KMko6Sj5LOktCS0pLUkteS2JLZktqS25Ldkt+S4JLhkuOS5JMjkyWTJ5MpkyyTLZMuky+TMJMykzSTNZM2kziTOZN4k3qTfJN+k4GTgpODk4SThZOHk4mTipOLk42TjpPNk8+T0ZPTk9aT15PYk9mT2pPck96T35Pgk+KT45QulFGUcZSRlJOUlZSXlJmUm5SclJ2UoJShlKOUpJSmlKiUqZSqlK2UrpSzlMCUxZTHlMmUzpTRlNSU1pT7lR+VRpVqlW2Vb5VxlXOVdZV3lXiVe5WIlZmVm5WdlZ+VoZWjlaWVp5WplbqVvZXAlcOVxpXJlcyVz5XSldSWE5YVlheWGZYclh2WHpYfliCWIpYkliWWJpYolimWaJZqlmyWbpZxlnKWc5Z0lnWWd5Z5lnqWe5Z9ln6WvZa/lsKWxJbHlsiWyZbKlsuWzZbPltCW0ZbTltSW4ZbiluOW5ZcklyaXKJcqly2XLpcvlzCXMZczlzWXNpc3lzmXOpd5l3uXfZd/l4KXg5eEl4WXhpeIl4qXi5eMl46Xj5fOl9CX0pfUl9eX2JfZl9qX25fdl9+X4Jfhl+OX5JgjmCWYJ5gpmCyYLZgumC+YMJgymDSYNZg2mDiYOZh4mHqYfJh+mIGYgpiDmISYhZiHmImYipiLmI2YjpizmNeY/pkimSWZJ5kpmSuZLZkvmTCZM5lAmU+ZUZlTmVWZV5lZmVuZXZlsmW+Zcpl1mXiZe5l+mYGZg5nCmcSZxpnImcuZzJnNmc6Zz5nRmdOZ1JnVmdeZ2JoXmhmaG5odmiCaIZoimiOaJJommiiaKZoqmiyaLZpsmm6acJpymnWadpp3mniaeZp7mn2afpp/moGagprBmsOaxZrHmsqay5rMms2azprQmtKa05rUmtaa15sWmxibGpscmx+bIJshmyKbI5slmyebKJspmyubLJtrm22bb5txm3SbdZt2m3ebeJt6m3ybfZt+m4CbgZvAm8KbxJvGm8mbypvLm8ybzZvPm9Gb0pvTm9Wb1pwhnEScZJyEnIaciJyKnIycjpyPnJCck5yUnJacl5yZnJucnJydnKCcoZymnLOcuJy6nLycwZzEnMecyZzunRKdOZ1dnWCdYp1knWadaJ1qnWudbp17nYydjp2QnZKdlJ2WnZidmp2cna2dsJ2znbaduZ28nb+dwp3FnceeBp4IngqeDJ4PnhCeEZ4SnhOeFZ4XnhieGZ4bnhyeW55dnl+eYZ5knmWeZp5nnmieap5snm2ebp5wnnGesJ6ynrWet566nruevJ69nr6ewJ7CnsOexJ7Gnsee1J7Vntae2J8XnxmfG58dnyCfIZ8inyOfJJ8mnyifKZ8qnyyfLZ9sn26fcJ9yn3Wfdp93n3ifeZ97n32ffp9/n4Gfgp/Bn8OfxZ/Hn8qfy5/Mn82fzp/Qn9Kf05/Un9af16AWoBigGqAcoB+gIKAhoCKgI6AloCegKKApoCugLKBroG2gb6BxoHSgdaB2oHegeKB6oHygfaB+oICggaCmoMqg8aEVoRihGqEcoR6hIKEioSOhJqEzoUKhRKFGoUihSqFMoU6hUKFfoWKhZaFooWuhbqFxoXShdqG1obehuaG7ob6hv6HAocGhwqHEocahx6HIocqhy6IKogyiDqIQohOiFKIVohaiF6IZohuiHKIdoh+iIKJfomGiY6JlomiiaaJqomuibKJuonCicaJyonSidaK0oraiuKK6or2ivqK/osCiwaLDosWixqLHosmiyqMJowujDaMPoxKjE6MUoxWjFqMYoxqjG6Mcox6jH6Neo2CjYqNko2ejaKNpo2qja6Nto2+jcKNxo3OjdKOzo7Wjt6O5o7yjvaO+o7+jwKPCo8SjxaPGo8ijyaQUpDekV6R3pHmke6R9pH+kgaSCpIOkhqSHpImkiqSMpI6kj6SQpJOklKSZpKakq6StpK+ktKS3pLqkvKThpQWlLKVQpVOlVaVXpVmlW6VdpV6lYaVupX+lgaWDpYWlh6WJpYuljaWPpaClo6WmpamlrKWvpbKltaW4pbql+aX7pf2l/6YCpgOmBKYFpgamCKYKpgumDKYOpg+mTqZQplKmVKZXplimWaZaplumXaZfpmCmYaZjpmSmo6alpqimqqatpq6mr6awprGms6a1pramt6a5prqmx6bMps6m0KbVptem2qbcpumm7qbwpvKm96b5pvum/ac8pz6nQKdCp0WnRqdHp0inSadLp02nTqdPp1GnUqeRp5OnlaeXp5qnm6ecp52nnqegp6Kno6ekp6anp6fmp+in6qfsp++n8Kfxp/Kn86f1p/en+Kf5p/un/Kg7qD2oP6hBqESoRahGqEeoSKhKqEyoTahOqFCoUaiQqJKolKiWqJmomqibqJyonaifqKGooqijqKWopqjLqO+pFqk6qT2pP6lBqUOpRalHqUipS6lYqWepaalrqW2pb6lxqXOpdamEqYepiqmNqZCpk6mWqZmpm6naqdyp3qngqeOp5Knlqeap56npqeup7Kntqe+p8KovqjGqM6o1qjiqOao6qjuqPKo+qkCqQapCqkSqRaqEqoaqiKqKqo2qjqqPqpCqkaqTqpWqlqqXqpmqmqrZqtuq3arfquKq46rkquWq5qroquqq66rsqu6q76suqzCrMqs0qzerOKs5qzqrO6s9qz+rQKtBq0OrRKuDq4Wrh6uJq4yrjauOq4+rkKuSq5SrlauWq5irmavYq9qr3Kveq+Gr4qvjq+Sr5avnq+mr6qvrq+2r7qw5rFysfKycrJ6soKyirKSspqynrKisq6ysrK6sr6yxrLOstKy1rLisuazCrM+s1KzWrNis3azgrOOs5a0KrS6tVa15rXytfq2ArYKthK2GrYetiq2Xraitqq2sra6tsK2yrbSttq24rcmtzK3PrdKt1a3Yrdut3q3hreOuIq4kriauKK4rriyuLa4uri+uMa4zrjSuNa43rjiud655rnuufa6AroGugq6DroSuhq6Iromuiq6Mro2uzK7OrtGu067Wrteu2K7Zrtqu3K7ert+u4K7iruOu8K71rveu+a7+rwCvA68FrxKvF68ZrxuvIK8irySvJq9lr2evaa9rr26vb69wr3Gvcq90r3avd694r3qve6+6r7yvvq/Ar8OvxK/Fr8avx6/Jr8uvzK/Nr8+v0LAPsBGwE7AVsBiwGbAasBuwHLAesCCwIbAisCSwJbBksGawaLBqsG2wbrBvsHCwcbBzsHWwdrB3sHmwerC5sLuwvbC/sMKww7DEsMWwxrDIsMqwy7DMsM6wz7D0sRixP7FjsWaxaLFqsWyxbrFwsXGxdLGBsZCxkrGUsZaxmLGasZyxnrGtsbCxs7G2sbmxvLG/scKxxLIDsgWyB7IJsgyyDbIOsg+yELISshSyFbIWshiyGbJYslqyXLJesmGyYrJjsmSyZbJnsmmyarJrsm2ybrKtsq+ysbKzsrayt7K4srmyurK8sr6yv7LAssKyw7MCswSzB7MJswyzDbMOsw+zELMSsxSzFbMWsxizGbNYs1qzXLNes2GzYrNjs2SzZbNns2mzarNrs22zbrOts6+zsbOzs7azt7O4s7mzurO8s76zv7PAs8Kzw7QCtAS0BrQItAu0DLQNtA60D7QRtBO0FLQVtBe0GLRjtIa0prTGtMi0yrTMtM600LTRtNK01bTWtNi02bTbtN203rTftOK047TotPW0+rT8tP61A7UGtQm1C7UwtVS1e7WftaK1pLWmtai1qrWsta21sLW9tc610LXStdS11rXYtdq13LXete+18rX1tfi1+7X+tgG2BLYHtgm2SLZKtky2TrZRtlK2U7ZUtlW2V7ZZtlq2W7Zdtl62nbaftqG2o7amtqe2qLaptqq2rLautq+2sLaytrO28rb0tve2+bb8tv22/rb/twC3ArcEtwW3BrcItwm3FrcXtxi3GrdZt1u3Xbdft2K3Y7dkt2W3Zrdot2q3a7dst263b7eut7C3sre0t7e3uLe5t7q3u7e9t7+3wLfBt8O3xLgDuAW4B7gJuAy4DbgOuA+4ELgSuBS4FbgWuBi4GbhYuFq4XLheuGG4YrhjuGS4ZbhnuGm4arhruG24brituK+4sbizuLa4t7i4uLm4uri8uL64v7jAuMK4w7jouQy5M7lXuVq5XLleuWC5YrlkuWW5aLl1uYS5hrmIuYq5jLmOuZC5krmhuaS5p7mqua25sLmzuba5uLn3ufm5+7n9ugC6AboCugO6BLoGugi6CboKugy6DbpMuk66ULpSulW6VrpXuli6Wbpbul26XrpfumG6YrqhuqO6pbqnuqq6q7qsuq26rrqwurK6s7q0ura6t7r2uvi6+rr8uv+7ALsBuwK7A7sFuwe7CLsJuwu7DLtLu027T7tRu1S7VbtWu1e7WLtau1y7Xbteu2C7Ybugu6K7pLumu6m7qruru6y7rbuvu7G7sruzu7W7trv1u/e7+bv7u/67/7wAvAG8ArwEvAa8B7wIvAq8C7xWvHm8mby5vLu8vby/vMG8w7zEvMW8yLzJvMu8zLzOvNC80bzSvNW81rzfvOy88bzzvPW8+rz9vQC9Ar0nvUu9cr2WvZm9m72dvZ+9ob2jvaS9p720vcW9x73Jvcu9zb3PvdG9073Vvea96b3sve+98r31vfi9+73+vgC+P75BvkO+Rb5Ivkm+Sr5Lvky+Tr5QvlG+Ur5UvlW+lL6Wvpi+mr6dvp6+n76gvqG+o76lvqa+p76pvqq+6b7rvu6+8L7zvvS+9b72vve++b77vvy+/b7/vwC/Db8SvxS/Fr8bvx2/IL8ivy+/NL82vzi/Pb8/v0G/Q7+Cv4S/hr+Iv4u/jL+Nv46/j7+Rv5O/lL+Vv5e/mL/Xv9m/27/dv+C/4b/iv+O/5L/mv+i/6b/qv+y/7cAswC7AMMAywDXANsA3wDjAOcA7wD3APsA/wEHAQsCBwIPAhcCHwIrAi8CMwI3AjsCQwJLAk8CUwJbAl8DWwNjA2sDcwN/A4MDhwOLA48DlwOfA6MDpwOvA7MERwTXBXMGAwYPBhcGHwYnBi8GNwY7BkcGewa3Br8GxwbPBtcG3wbnBu8HKwc3B0MHTwdbB2cHcwd/B4cIgwiLCJMImwinCKsIrwizCLcIvwjHCMsIzwjXCNsJ1wnfCecJ7wn7Cf8KAwoHCgsKEwobCh8KIworCi8LKwszCzsLQwtPC1MLVwtbC18LZwtvC3MLdwt/C4MMfwyHDI8MlwyjDKcMqwyvDLMMuwzDDMcMywzTDNcN0w3bDeMN6w33DfsN/w4DDgcODw4XDhsOHw4nDisPJw8vDzcPPw9LD08PUw9XD1sPYw9rD28Pcw97D38QexCDEIsQkxCfEKMQpxCrEK8QtxC/EMMQxxDPENMR/xKLEwsTixOTE5sToxOrE7MTtxO7E8cTyxPTE9cT3xPnE+sT7xP7E/8UExRHFFsUYxRrFH8UixSXFJ8VMxXDFl8W7xb7FwMXCxcTFxsXIxcnFzMXZxerF7MXuxfDF8sX0xfbF+MX6xgvGDsYRxhTGF8Yaxh3GIMYjxiXGZMZmxmjGasZtxm7Gb8ZwxnHGc8Z1xnbGd8Z5xnrGuca7xr3Gv8bCxsPGxMbFxsbGyMbKxsvGzMbOxs/HDscQxxPHFccYxxnHGscbxxzHHscgxyHHIsckxyXHMsczxzTHNsd1x3fHecd7x37Hf8eAx4HHgseEx4bHh8eIx4rHi8fKx8zHzsfQx9PH1MfVx9bH18fZx9vH3Mfdx9/H4MgfyCHII8glyCjIKcgqyCvILMguyDDIMcgyyDTINch0yHbIeMh6yH3Ifsh/yIDIgciDyIXIhsiHyInIisjJyMvIzcjPyNLI08jUyNXI1sjYyNrI28jcyN7I38kEySjJT8lzyXbJeMl6yXzJfsmAyYHJhMmRyaDJosmkyabJqMmqyazJrsm9ycDJw8nGycnJzMnPydLJ1MoTyhXKF8oZyhzKHcoeyh/KIMoiyiTKJcomyijKKcpoymrKbMpuynHKcspzynTKdcp3ynnKesp7yn3Kfsq9yr/KwcrDysbKx8rIysnKysrMys7Kz8rQytLK08sSyxTLF8sZyxzLHcseyx/LIMsiyyTLJcsmyyjLKctoy2rLbMtuy3HLcstzy3TLdct3y3nLest7y33Lfsu9y7/LwcvDy8bLx8vIy8nLysvMy87Lz8vQy9LL08wSzBTMFswYzBvMHMwdzB7MH8whzCPMJMwlzCfMKMwzzDzMPcw/zEjMU8xizG3Me8yQzKTMu8zNzQzNDs0QzRLNFM0VzRbNF80YzRrNHM0dzR7NIM0hzWDNYs1kzWbNaM1pzWrNa81szW7NcM1xzXLNdM11zbTNts25zbvNvc2+zb/NwM3BzcPNxc3GzcfNyc3KzhXOOM5YznjOes58zn7OgM6CzoPOhM6HzojOis6Lzo3Oj86QzpHOlM6VzprOp86szq7OsM61zrjOu869zuLPBs8tz1HPVM9Wz1jPWs9cz17PX89iz2/PgM+Cz4TPhs+Iz4rPjM+Oz5DPoc+kz6fPqs+tz7DPs8+2z7nPu8/6z/zP/tAA0APQBNAF0AbQB9AJ0AvQDNAN0A/QENBP0FHQU9BV0FjQWdBa0FvQXNBe0GDQYdBi0GTQZdCk0KbQqdCr0K7Qr9Cw0LHQstC00LbQt9C40LrQu9DI0M3Qz9DR0NbQ2NDb0N3Q6tDv0PHQ89D40PrQ/ND+0T3RP9FB0UPRRtFH0UjRSdFK0UzRTtFP0VDRUtFT0ZLRlNGW0ZjRm9Gc0Z3RntGf0aHRo9Gk0aXRp9Go0efR6dHr0e3R8NHx0fLR89H00fbR+NH50frR/NH90jzSPtJA0kLSRdJG0kfSSNJJ0kvSTdJO0k/SUdJS0pHSk9KV0pfSmtKb0pzSndKe0qDSotKj0qTSptKn0szS8NMX0zvTPtNA00LTRNNG00jTSdNM01nTaNNq02zTbtNw03LTdNN204XTiNOL047TkdOU05fTmtOc09vT3dPf0+HT5NPl0+bT59Po0+rT7NPt0+7T8NPx1DDUMtQ01DbUOdQ61DvUPNQ91D/UQdRC1EPURdRG1IXUh9SJ1IvUjtSP1JDUkdSS1JTUltSX1JjUmtSb1NrU3NTe1ODU49Tk1OXU5tTn1OnU69Ts1O3U79Tw1S/VMdUz1TXVONU51TrVO9U81T7VQNVB1ULVRNVF1YTVhtWI1YrVjdWO1Y/VkNWR1ZPVldWW1ZfVmdWa1dnV29Xd1d/V4tXj1eTV5dXm1ejV6tXr1ezV7tXv1fjV+dX71gjWCdYK1gzWGdYa1hvWHdYq1ivWLNYu1jfWRtZT1mLWdNaI1p/Wsda61rvWvdbK1svWzNbO1tfW4dbo1vLW+tcM1xHXFgAAAAAAAAICAAAAAAAAICYAAAAAAAAAAAAAAAAAANcY + + + + + alias + + + + usessh + + + + sshhost + + + + usessl + + + + hostport + + + + defaultdb + + + + adminuser + + + + sshkeyfile + + + + userepl + + + + 1 + databases + + + + name + + + + MHMongoHubMigration6to7 + Connection + Undefined + 1 + Connection + 1 + + + + + + bindport + + + \ No newline at end of file diff --git a/Sources/Model/MHMongoHubMigration7to8.h b/Sources/Model/MHMongoHubMigration7to8.h new file mode 100644 index 00000000..1d94dc1a --- /dev/null +++ b/Sources/Model/MHMongoHubMigration7to8.h @@ -0,0 +1,13 @@ +// +// MHMongoHubMigration7to8.h +// MongoHub +// +// Created by Jérôme Lebel on 31/07/2014. +// +// + +#import + +@interface MHMongoHubMigration7to8 : NSEntityMigrationPolicy + +@end diff --git a/Sources/Model/MHMongoHubMigration7to8.m b/Sources/Model/MHMongoHubMigration7to8.m new file mode 100644 index 00000000..3371c125 --- /dev/null +++ b/Sources/Model/MHMongoHubMigration7to8.m @@ -0,0 +1,60 @@ +// +// MHMongoHubMigration7to8.m +// MongoHub +// +// Created by Jérôme Lebel on 31/07/2014. +// +// + +#import "MHMongoHubMigration7to8.h" +#import "MHKeychain.h" + +@implementation MHMongoHubMigration7to8 + +- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sourceInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError *__autoreleasing *)error +{ + NSManagedObjectContext *destMOC = manager.destinationContext; + NSManagedObject *newConnection; + NSString *mainHost = [sourceInstance valueForKey:@"host"]; + NSNumber *mainHostPort = [sourceInstance valueForKey:@"hostport"]; + NSString *servers = [sourceInstance valueForKey:@"servers"]; + NSString *user = [sourceInstance valueForKey:@"adminuser"]; + NSString *password = [sourceInstance valueForKey:@"adminpass"]; + NSMutableArray *allServersArray; + NSString *newServersValue; + + if (mainHostPort.integerValue != 0) { + allServersArray = [NSMutableArray arrayWithObjects:[NSString stringWithFormat:@"%@:%@", mainHost, mainHostPort], nil]; + } else { + allServersArray = [NSMutableArray arrayWithObjects:[NSString stringWithFormat:@"%@", mainHost], nil]; + } + if (servers.length > 0) { + for (NSString *host in [servers componentsSeparatedByString:@","]) { + [allServersArray addObject:[host stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]]; + } + } + [allServersArray sortUsingSelector:@selector(compare:)]; + if (user.length == 0) { + newServersValue = [allServersArray componentsJoinedByString:@","]; + } else { + newServersValue = [allServersArray componentsJoinedByString:@","]; + if (password.length > 0) { + [MHKeychain addOrUpdateItemWithLabel:[NSString stringWithFormat:@"%@ (%@)", newServersValue, user] account:user service:newServersValue description:nil password:password]; + } + } + + newConnection = [NSEntityDescription insertNewObjectForEntityForName:@"Connection" inManagedObjectContext:destMOC]; + NSArray *keys = sourceInstance.entity.attributesByName.allKeys; + NSMutableDictionary *values = [[sourceInstance dictionaryWithValuesForKeys:keys] mutableCopy]; + [values removeObjectForKey:@"host"]; + [values removeObjectForKey:@"hostport"]; + [values removeObjectForKey:@"servers"]; + [values removeObjectForKey:@"adminpass"]; + [values setObject:newServersValue forKey:@"servers"]; + [newConnection setValuesForKeysWithDictionary:values]; + [manager associateSourceInstance:sourceInstance withDestinationInstance:newConnection forEntityMapping:mapping]; + [values release]; + return YES; +} + +@end diff --git a/Sources/Model/MHMongoHubMigration7to8.xcmappingmodel/xcmapping.xml b/Sources/Model/MHMongoHubMigration7to8.xcmappingmodel/xcmapping.xml new file mode 100644 index 00000000..91c9136e --- /dev/null +++ b/Sources/Model/MHMongoHubMigration7to8.xcmappingmodel/xcmapping.xml @@ -0,0 +1,129 @@ + + + + + + 134481920 + 2109032B-9223-4F27-8465-C00EC05DCFAD + 118 + + + + NSPersistenceFrameworkVersion + 481 + NSStoreModelVersionHashes + + XDDevAttributeMapping + + 0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc= + + XDDevEntityMapping + + qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI= + + XDDevMappingModel + + EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ= + + XDDevPropertyMapping + + XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA= + + XDDevRelationshipMapping + + akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs= + + + NSStoreModelVersionHashesVersion + 3 + NSStoreModelVersionIdentifiers + + + + + + + + + defaultdb + + + + bindport + + + + MHMongoHubMigration7to8 + Connection + Undefined + 1 + Connection + 1 + + + + + + usessh + + + + bindaddress + + + + Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel + YnBsaXN0MDDUAAEAAgADAAQABQAGICIgI1gkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv +cBIAAYagrxECpgAHAAgAFwAYADQANQA2AEAAQQBCAF0AXgBfAGUAZgByAIYAhwCIAIkAigCLAIwAjQCOAKcAsAC/AM4A3QDgAOQAXAD0AQMBCQEKAQsBDwEeASQBJQEtATwBPQFGAVIBUwFUAVUBVgFrAWwBdAF1AXYBggGWAZcBmAGZAZoBmwGcAZ0BngGtAbwBywHTAdQB3AHdAd4B3wHgAe8B/gH/Ag4CHQIsAjgCSgJLAkwCTQJOAk8CUAJRAmACbwJ+Ao0CjgKdAqwCuwLDAtgC2QLhAu0DAQMQAx8DLgM2Az4DTQNcA2sDegOJA5UDpwO2A8UD1APjA/IEAQQQBCUEJgQuBC8EOwRPBF4EbQR8BIQEjASbBKoEuQTIBNcE4wT1BPYE9wT4BPkE+gT7BPwFCwUMBRsFHAUrBToFVAVVBVsFZwV7BYoFmQWoBbcFugXJBdgF3gXtBfwF/QYnBigGKQYqBisGLAYtBi4GLwYwBjEGMgYzBjQGNQY2BjcGOAY5BjoGTwZQBlgGZAZ4BocGlgalBq0GtQbEBtMG4gbxBwAHDAceBy0HPAdLB1oHaQd4B4cHnAedB6UHsQfFB9QH4wfyB/oIAggRCCAILwg+CE0IWQhrCHoIewiKCJkIqAipCLgIxwjWCOsI7Aj0CQAJFAkjCTIJQQlFCVQJYwlyCYEJkAmcCa4JvQnMCdsJ6gnrCfoKCQoYCi0KLgo2CkIKVgplCnQKgwqHCpYKpQq0CsMK0greCvAK/wsOCx0LLAs7C0oLWQtuC28LdwuDC5cLpgu1C8QLzAvUC+ML8gwBDBAMHwwrDD0MTAxbDGoMeQyIDJcMpgy7DLwMxAzQDOQM8w0CDRENFQ0kDTMNQg1RDWANbA1+DY0NnA2rDboNyQ3YDecN/A39DgUOEQ4lDjQOQw5SDlYOZQ50DoMOkg6hDq0Ovw7ODt0O7A77DwoPGQ8oDz0PPg9GD1IPZg91D4QPkw+XD6YPtQ/ED9MP4g/uEAAQDxAeEC0QPBBLEFoQaRB+EH8QhxCTEKcQthDFENQQ2BDnEPYRBREUESMRLxFBEVARXxFuEX0RjBGbEaoRvxHAEcgR1BHoEfcSBhIVEh0SJRI0EkMSUhJhEnASfBKOAC4SnRKsErsSyhLZEugS9xL/ExQTFRMdEykTPRNME1sTahNyE3oTiROYE6cTthPFE9ET4xPyFAEUEBQfFC4UPRRMFGEUYhRqFHYUihSZFKgUtxS7FMoU2RToFPcVBhUSFSQVMxVCFVEVYBVvFX4VjRWiFaMVqxW3FcsV2hXpFfgV/BYLFhoWKRY4FkcWUxZlFnQWgxaSFqEWsBa/Fs4W4xbkFuwW+BcMFxsXKhc5Fz0XTBdbF2oXeReIF5QXphe1F8QX0xfiF/EYABgPGCQYJRgtGDkYTRhcGGsYehiCGIoYmRioGLcYxhjVGOEY8xkCGREZIBkvGT4ZTRlcGXEZchl6GYYZmhmpGbgZxxnPGdcZ5hn1GgQaExoiGi4aQBpPGl4abRp8GosamhqpGr4avxrHGtMa5xr2GwUbFBsYGycbNhtFG1QbYxtvG4EbkBufG64bvRvMG9sb6hv/HAAcCBwUHCgcNxxGHFUcXRxlHHQcgxySHKEcsBy8HM4c3RzsHPsdCh0ZHSgdNx1MHU0dVR1hHXUdhB2THaIdph21HcQd0x3iHfEd/R4PHh4eLR48HkseWh5pHngeeR58HoUelB6jHrIexx7IHtAe3B7wHv8fDh8dHyUfLR88H0sfWh9pH3gfhB+WH6UftB/DH9If4R/wH/8gAiAGIAogDiAWIBkgHVUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAFQATXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoADgQKlgQKjgACBAqSAAoAAXxAUdW50aXRsZWQueGNkYXRhbW9kZWzeABkAGgAbABwAHQAeAB8ACgAgACEAIgAjACQAJQAmACcAKAApACYAEwAsAC0ALgAvADAAJgAmABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgAWBAqGBAp+AAYAFgACBAqCBAqIQAIAGgASABYAFgABQU1lFU9MANwA4AAoAOQA8AD9XTlMua2V5c1pOUy5vYmplY3RzogA6ADuAB4AIogA9AD6ACYCagCVYRGF0YWJhc2VaQ29ubmVjdGlvbt8QEABDAEQARQBGAB4ARwBIACAASQBKAAoAIgBLAEwAJQBNAE4ATwAmACYAEABTAFQALgAmAE4AVwA6AE4AWgBbAFxfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2VfECBYREJ1Y2tldEZvclN0ZXJlb3R5cGVzd2FzRW5jb2RlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNzdG9yYWdlXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNkdXBsaWNhdGVzXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3N0b3JhZ2VbX2lzQWJzdHJhY3SAC4AtgAWABYADgAyBAoCABYALgQKCgAeAC4ECnoAKCBIRg6h7V29yZGVyZWTTADcAOAAKAGAAYgA/oQBhgA2hAGOADoAlXlhEX1BTdGVyZW90eXBl2QAeACIAZwAKACUAaAAgAE0AaQA9AGEATgBtABMAJgAuAFwAcV8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ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UACAAlQAKACIAlgCXACUAmAATABMAEwQrAFwAXABcAC4AXAChAYUAXABcABMAXIAAgACAAIB/CAgICIAZgDoICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATBG8AEwQrAFwAXABcAC4AXAChAYYAXABcABMAXIAAgISAAIB/CAgICIAZgDsICIAACNMANwA4AAoEfQSAAD+iAQUBzoAjgEWiAQcEgoAkgIWAJdMANwA4AAoEhQSIAD+iAdYB14BHgEiiAdkB2oBJgEqAJd8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAfEAEwQrAFwAXABcAC4AXAChAYcAXABcABMAXIAAgE2AAIB/CAgICIAZgDwICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAfEAEwQrAFwAXABcAC4AXAChAYgAXABcABMAXIAAgE2AAIB/CAgICIAZgD0ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwQrAFwAXABcAC4AXAChAYkAXABcABMAXIAAgCCAAIB/CAgICIAZgD4ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwQrAFwAXABcAC4AXAChAYoAXABcABMAXIAAgACAAIB/CAgICIAZgD8ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwQrAFwAXABcAC4AXAChAYsAXABcABMAXIAAgCCAAIB/CAgICIAZgEAICIAACNkAHgAiBNgACgAlBNkAIABNBNoBTwQpAE4AbQATACYALgBcBOJfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAe4B+gAuALIAAgAUIgIzTADcAOAAKBOQE7AA/pwTlBOYE5wToBOkE6gTrgI2AjoCPgJCAkYCSgJOnBO0E7gTvBPAE8QTyBPOAlICWgJiAmYECg4EChIEChYAlXxAPWERfUFJLX21pbkNvdW50XxARWER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AXIAAgCCAAIDzCAgICIAZgDwICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAfEAEwjxAFwAXABcAC4AXAChAYgAXABcABMAXIAAgE2AAIDzCAgICIAZgD0ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwjxAFwAXABcAC4AXAChAYkAXABcABMAXIAAgCCAAIDzCAgICIAZgD4ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwjxAFwAXABcAC4AXAChAYoAXABcABMAXIAAgACAAIDzCAgICIAZgD8ICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwjxAFwAXABcAC4AXAChAYsAXABcABMAXIAAgCCAAIDzCAgICIAZgEAICIAACNkAHgAiCZEACgAlCZIAIABNCZMGFQFvAE4AbQATACYALgBcCZtfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WA8IA2gAuALIAAgAUIgP/TADcAOAAKCZ0JpQA/pwI6AjsCPAI9Aj4CPwJAgFOAVIBVgFaAV4BYgFmnCaYJpwmoCakJqgmrCayBAQCBAQGBAQKBAQOBAQWBAQaBAQeAJd8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwjyAFwAXABcAC4AXAChAjoAXABcABMAXIAAgACAAID+CAgICIAZgFMICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATAOYAEwjyAFwAXABcAC4AXAChAjsAXABcABMAXIAAgCCAAID+CAgICIAZgFQICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATABMAEwjyAFwAXABcAC4AXAChAjwAXABcABMAXIAAgACAAID+CAgICIAZgFUICIAACN8QDwCPAJAAkQAeAJIAkwCUACAAlQAKACIAlgCXACUAmAATCd0AEwjyAFwAXAB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T0RPiE+QT5hPoE+oT7BPuE/AT8hP0FBIUMBRDFFcUbBSJFJ0UsxTyFPQU9hT4FPoU+xT8FP0U/hUAFQIVAxUEFQYVBxVGFUgVShVMFU4VTxVQFVEVUhVUFVYVVxVYFVoVWxWaFZwVnhWgFaIVoxWkFaUVphWoFaoVqxWsFa4VrxW8FcEVwxXFFcoVzBXOFdAWAxYQFhUWFxYZFh4WIBYiFiQWOhZMFlAWVhaVFpcWmRabFp0WnhafFqAWoRajFqUWphanFqkWqhbpFusW7RbvFvEW8hbzFvQW9Rb3FvkW+hb7Fv0W/hb/Fz4XQBdCF0QXRhdHF0gXSRdKF0wXThdPF1AXUhdTF5IXlBeWF5gXmhebF5wXnReeF6AXohejF6QXphenF+YX6BfqF+wX7hfvF/AX8RfyF/QX9hf3F/gX+hf7GCAYRBhrGI8YkRiTGJUYlxiZGJsYnBieGKsYuhi8GL4YwBjCGMQYxhjIGNcY2RjbGN0Y3xjhGOMY5RjnGQcZMhlMGWUZfxmfGcIaARoDGgUaBxoJGgoaCxoMGg0aDxoRGhIaExoVGhYaVRpXGlkaWxpdGl4aXxpgGmEaYxplGmYaZxppGmoaqRqrGq0arxqxGrIasxq0GrUatxq5Groauxq9Gr4a/Rr/GwEbAxsFGwYbBxsIGwkbCxsNGw4bDxsRGxIbFRtUG1YbWBtaG1wbXRteG18bYBtiG2QbZRtmG2gbaRuoG6obrBuuG7AbsRuyG7MbtBu2G7gbuRu6G7wbvRv8G/4cABwCHAQcBRwGHAccCBwKHAwcDRwOHBAcERwaHCgcNRxDHFAcYxx6HIwc1xz6HRodOh08HT4dQB1CHUQdRR1GHUgdSR1LHUwdTh1QHVEdUh1UHVUdWh1nHWwdbh1wHXUddx15HXsdoB3EHeseDx4RHhMeFR4XHhkeGx4cHh4eKx48Hj4eQB5CHkQeRh5IHkoeTB5dHl8eYR5jHmUeZx5pHmsebR5vHq4esB6yHrQeth63HrgeuR66Hrwevh6/HsAewh7DHwIfBB8GHwgfCh8LHwwfDR8OHxAfEh8THxQfFh8XH1YfWB9aH1wfXh9fH2AfYR9iH2QfZh9nH2gfah9rH3gffR9/H4Efhh+IH4ofjB+ZH54foB+iH6cfqR+rH60f7B/uH/Af8h/0H/Uf9h/3H/gf+h/8H/0f/iAAIAE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3HTceN103XzdhN2M3ZTdmN2c3aDdpN2s3bTduN283cTdyN7E3sze1N7c3uTe6N7s3vDe9N783wTfCN8M3xTfGOAU4BzgJOAs4DTgOOA84EDgROBM4FTgWOBc4GTgaOD84YziKOK44sDiyOLQ4tji4OLo4uzi9OMo42TjbON043zjhOOM45TjnOPY4+Dj6OPw4/jkAOQI5BDkGOUU5RzlJOUs5TTlOOU85UDlROVM5VTlWOVc5WTlaOZk5mzmdOZ85oTmiOaM5pDmlOac5qTmqOas5rTmuOe057znxOfM59Tn2Ofc5+Dn5Ofs5/Tn+Of86AToCOkE6QzpFOkc6STpKOks6TDpNOk86UTpSOlM6VTpWOpU6lzqZOps6nTqeOp86oDqhOqM6pTqmOqc6qTqqOuk66zrtOu868TryOvM69Dr1Ovc6+Tr6Ovs6/Tr+Oz07PztBO0M7RTtGO0c7SDtJO0s7TTtOO087UTtSO507wDvgPAA8AjwEPAY8CDwKPAs8DDwOPA88ETwSPBQ8FjwXPBg8GjwbPCQ8MTw2PDg8Ojw/PEE8QzxFPGo8jjy1PNk82zzdPN884TzjPOU85jzoPPU9Bj0IPQo9DD0OPRA9Ej0UPRY9Jz0pPSs9LT0vPTE9Mz01PTc9OT14PXo9fD1+PYA9gT2CPYM9hD2GPYg9iT2KPYw9jT3MPc490D3SPdQ91T3WPdc92D3aPdw93T3ePeA94T4gPiI+JD4mPig+KT4qPis+LD4uPjA+MT4yPjQ+NT5CPkc+ST5LPlA+Uj5UPlY+Yz5oPmo+bD5xPnM+dT53PrY+uD66Prw+vj6/PsA+wT7CPsQ+xj7HPsg+yj7LPwo/DD8OPxA/Ej8TPxQ/FT8WPxg/Gj8bPxw/Hj8fP14/YD9iP2Q/Zj9nP2g/aT9qP2w/bj9vP3A/cj9zP7I/tD+2P7g/uj+7P7w/vT++P8A/wj/DP8Q/xj/HQAZACEAKQAxADkAPQBBAEUASQBRAFkAXQBhAGkAbQEBAZECLQK9AsUCzQLVAt0C5QLtAvEC+QMtA2kDcQN5A4EDiQORA5kDoQPdA+UD7QP1A/0EBQQNBBUEHQUZBSEFKQUxBTkFPQVBBUUFSQVRBVkFXQVhBWkFbQV1BnEGeQaBBokGkQaVBpkGnQahBqkGsQa1BrkGwQbFB8EHyQfRB9kH4QflB+kH7QfxB/kIAQgFCAkIEQgVCREJGQkhCSkJMQk1CTkJPQlBCUkJUQlVCVkJYQllCW0KaQpxCnkKgQqJCo0KkQqVCpkKoQqpCq0KsQq5Cr0LuQvBC8kL0QvZC90L4QvlC+kL8Qv5C/0MAQwJDA0NCQ0RDRkNIQ0pDS0NMQ01DTkNQQ1JDU0NUQ1ZDV0OiQ8VD5UQFRAdECUQLRA1ED0QQRBFEE0QURBZEF0QZRBtEHEQdRB9EIEQpRDZEO0Q9RD9ERERGREhESkRvRJNEukTeROBE4kTkROZE6ETqROtE7UT6RQtFDUUPRRFFE0UVRRdFGUUbRSxFLkUwRTJFNEU2RThFOkU8RT5FfUV/RYFFg0WFRYZFh0WIRYlFi0WNRY5Fj0WRRZJF0UXTRdVF10XZRdpF20XcRd1F30XhReJF40XlReZGJUYnRilGK0YtRi5GL0YwRjFGM0Y1RjZGN0Y5RjpGR0ZIRklGS0aKRoxGjkaQRpJGk0aURpVGlkaYRppGm0acRp5Gn0beRuBG4kbkRuZG50boRulG6kbsRu5G70bwRvJG80cyRzRHNkc4RzpHO0c8Rz1HPkdAR0JHQ0dER0ZHR0eGR4hHikeMR45Hj0eQR5FHkkeUR5ZHl0eYR5pHm0faR9xH3kfgR+JH40fkR+VH5kfoR+pH60fsR+5H70gUSDhIX0iDSIVIh0iJSItIjUiPSJBIkkifSK5IsEiySLRItki4SLpIvEjLSM5I0UjUSNdI2kjdSOBI4kkhSSNJJUknSSlJKkkrSSxJLUkvSTFJMkkzSTVJNkl1SXdJeUl7SX1Jfkl/SYBJgUmDSYVJhkmHSYlJiknJSctJzUnPSdFJ0knTSdRJ1UnXSdlJ2knbSd1J3kodSh9KIkokSiZKJ0ooSilKKkosSi5KL0owSjJKM0o2SnVKd0p5SntKfUp+Sn9KgEqBSoNKhUqGSodKiUqKSslKy0rNSs9K0UrSStNK1ErVStdK2UraSttK3UreSx1LH0shSyNLJUsmSydLKEspSytLLUsuSy9LMUsyS31LoEvAS+BL4kvkS+ZL6EvqS+tL7EvvS/BL8kvzS/VL90v4S/lL/Ev9TAJMD0wUTBZMGEwdTCBMI0wlTEpMbkyVTLlMvEy+TMBMwkzETMZMx0zKTNdM6EzqTOxM7kzwTPJM9Ez2TPhNCU0MTQ9NEk0VTRhNG00eTSFNI01iTWRNZk1oTWtNbE1tTW5Nb01xTXNNdE11TXdNeE23TblNu029TcBNwU3CTcNNxE3GTchNyU3KTcxNzU4MTg5OEU4TThZOF04YThlOGk4cTh5OH04gTiJOI04wTjFOMk40TnNOdU53TnlOfE59Tn5Of06AToJOhE6FToZOiE6JTshOyk7MTs5O0U7STtNO1E7VTtdO2U7aTttO3U7eTx1PH08hTyNPJk8nTyhPKU8qTyxPLk8vTzBPMk8zT3JPdE92T3hPe098T31Pfk9/T4FPg0+ET4VPh0+IT8dPyU/LT81P0E/RT9JP00/UT9ZP2E/ZT9pP3E/dUAJQJlBNUHFQdFB2UHhQelB8UH5Qf1CCUI9QnlCgUKJQpFCmUKhQqlCsULtQvlDBUMRQx1DKUM1Q0FDSURFRE1EVURdRGlEbURxRHVEeUSBRIlEjUSRRJlEnUWZRaFFqUWxRb1FwUXFRclFzUXVRd1F4UXlRe1F8UbtRvVG/UcFRxFHFUcZRx1HIUcpRzFHNUc5R0FHRUhBSElIUUhZSGVIaUhtSHFIdUh9SIVIiUiNSJVImUmVSZ1JpUmtSblJvUnBScVJyUnRSdlJ3UnhSelJ7UrpSvFK+UsBSw1LEUsVSxlLHUslSy1LMUs1Sz1LQUw9TEVMTUxVTGFMZUxpTG1McUx5TIFMhUyJTJFMlU3BTk1OzU9NT1VPXU9lT21PdU95T31PiU+NT5VPmU+hT6lPrU+xT71PwU/lUBlQLVA1UD1QUVBdUGlQcVEFUZVSMVLBUs1S1VLdUuVS7VL1UvlTBVM5U31ThVONU5VTnVOlU61TtVO9VAFUDVQZVCVUMVQ9VElUVVRhVGlVZVVtVXVVfVWJVY1VkVWVVZlVoVWpVa1VsVW5Vb1WuVbBVslW0VbdVuFW5VbpVu1W9Vb9VwFXBVcNVxFYDVgVWCFYKVg1WDlYPVhBWEVYTVhVWFlYXVhlWGlYnVixWLlYwVjVWN1Y6VjxWSVZOVlBWUlZXVllWW1ZdVpxWnlagVqJWpVamVqdWqFapVqtWrVauVq9WsVayVvFW81b1VvdW+lb7VvxW/Vb+VwBXAlcDVwRXBlcHV0ZXSFdKV0xXT1dQV1FXUldTV1VXV1dYV1lXW1dcV5tXnVefV6FXpFelV6ZXp1eoV6pXrFetV65XsFexV/BX8lf0V/ZX+Vf6V/tX/Ff9V/9YAVgCWANYBVgGWCtYT1h2WJpYnVifWKFYo1ilWKdYqFirWLhYx1jJWMtYzVjPWNFY01jVWORY51jqWO1Y8FjzWPZY+Vj7WTpZPFk+WUBZQ1lEWUVZRllHWUlZS1lMWU1ZT1lQWY9ZkVmTWZVZmFmZWZpZm1mcWZ5ZoFmhWaJZpFmlWeRZ5lnoWepZ7VnuWe9Z8FnxWfNZ9Vn2WfdZ+Vn6WjlaO1o9Wj9aQlpDWkRaRVpGWkhaSlpLWkxaTlpPWo5akFqSWpRal1qYWplamlqbWp1an1qgWqFao1qkWuNa5VrnWula7FrtWu5a71rwWvJa9Fr1WvZa+Fr5WzhbOls8Wz5bQVtCW0NbRFtFW0dbSVtKW0tbTVtOW5lbvFvcW/xb/lwAXAJcBFwGXAdcCFwLXAxcDlwPXBFcE1wUXBVcGFwZXB5cK1wwXDJcNFw5XDxcP1xBXGZcilyxXNVc2FzaXNxc3lzgXOJc41zmXPNdBF0GXQhdCl0MXQ5dEF0SXRRdJV0oXStdLl0xXTRdN106XT1dP11+XYBdgl2EXYddiF2JXYpdi12NXY9dkF2RXZNdlF3TXdVd113ZXdxd3V3eXd9d4F3iXeRd5V3mXehd6V4oXipeLV4vXjJeM140XjVeNl44XjpeO148Xj5eP15MXk1eTl5QXo9ekV6TXpVemF6ZXppem16cXp5eoF6hXqJepF6lXuRe5l7oXupe7V7uXu9e8F7xXvNe9V72Xvde+V76XzlfO189Xz9fQl9DX0RfRV9GX0hfSl9LX0xfTl9PX45fkF+SX5Rfl1+YX5lfml+bX51fn1+gX6Ffo1+kX+Nf5V/nX+lf7F/tX+5f71/wX/Jf9F/1X/Zf+F/5YB5gQmBpYI1gkGCSYJRglmCYYJpgm2CeYKtgumC8YL5gwGDCYMRgxmDIYNdg2mDdYOBg42DmYOlg7GDuYS1hL2ExYTNhNmE3YThhOWE6YTxhPmE/YUBhQmFDYYJhhGGGYYhhi2GMYY1hjmGPYZFhk2GUYZVhl2GYYddh2WHbYd1h4GHhYeJh42HkYeZh6GHpYeph7GHtYixiLmIwYjJiNWI2YjdiOGI5YjtiPWI+Yj9iQWJCYoFig2KFYodiimKLYoxijWKOYpBikmKTYpRilmKXYtZi2GLaYtxi32LgYuFi4mLjYuVi52LoYuli62LsYytjLWMvYzFjNGM1YzZjN2M4YzpjPGM9Yz5jQGNBY4xjr2PPY+9j8WPzY/Vj92P5Y/pj+2P+Y/9kAWQCZARkBmQHZAhkC2QMZBFkHmQjZCVkJ2QsZC9kMmQ0ZFlkfWSkZMhky2TNZM9k0WTTZNVk1mTZZOZk92T5ZPtk/WT/ZQFlA2UFZQdlGGUbZR5lIWUkZSdlKmUtZTBlMmVxZXNldWV3ZXple2V8ZX1lfmWAZYJlg2WEZYZlh2XGZchlymXMZc9l0GXRZdJl02XVZddl2GXZZdtl3GYbZh1mIGYiZiVmJmYnZihmKWYrZi1mLmYvZjFmMmY/ZkBmQWZDZoJmhGaGZohmi2aMZo1mjmaPZpFmk2aUZpVml2aYZtdm2WbbZt1m4GbhZuJm42bkZuZm6GbpZupm7GbtZyxnLmcwZzJnNWc2ZzdnOGc5ZztnPWc+Zz9nQWdCZ4Fng2eFZ4dnimeLZ4xnjWeOZ5BnkmeTZ5RnlmeXZ9Zn2GfaZ9xn32fgZ+Fn4mfjZ+Vn52foZ+ln62fsaBFoNWhcaIBog2iFaIdoiWiLaI1ojmiRaJ5orWivaLFos2i1aLdouWi7aMpozWjQaNNo1mjZaNxo32jhaSBpImkkaSZpKWkqaStpLGktaS9pMWkyaTNpNWk2aXVpd2l5aXtpfml/aYBpgWmCaYRphmmHaYhpimmLacppzGnOadBp02nUadVp1mnXadlp22ncad1p32ngah9qIWojaiVqKGopaipqK2osai5qMGoxajJqNGo1anRqdmp4anpqfWp+an9qgGqBaoNqhWqGaodqiWqKaslqy2rNas9q0mrTatRq1WrWathq2mrbatxq3mrfax5rIGsiayRrJ2soaylrKmsray1rL2swazFrM2s0a39romvCa+Jr5Gvma+hr6mvsa+1r7mvxa/Jr9Gv1a/dr+Wv6a/tr/mv/bARsEWwWbBhsGmwfbCJsJWwnbExscGyXbLtsvmzAbMJsxGzGbMhsyWzMbNls6mzsbO5s8GzybPRs9mz4bPptC20ObRFtFG0XbRptHW0gbSNtJW1kbWZtaG1qbW1tbm1vbXBtcW1zbXVtdm13bXltem25bbttvW2/bcJtw23EbcVtxm3Ibcpty23Mbc5tz24ObhBuE24VbhhuGW4abhtuHG4ebiBuIW4ibiRuJW4ybjNuNG42bnVud255bntufm5/boBugW6CboRuhm6Hbohuim6LbspuzG7ObtBu027UbtVu1m7Xbtlu227cbt1u327gbx9vIW8jbyVvKG8pbypvK28sby5vMG8xbzJvNG81b3Rvdm94b3pvfW9+b39vgG+Bb4NvhW+Gb4dviW+Kb8lvy2/Nb89v0m/Tb9Rv1W/Wb9hv2m/bb9xv3m/fcARwKHBPcHNwdnB4cHpwfHB+cIBwgXCEcJFwoHCicKRwpnCocKpwrHCucL1wwHDDcMZwyXDMcM9w0nDUcRNxFXEXcRlxHHEdcR5xH3EgcSJxJHElcSZxKHEpcWhxanFscW5xcXFycXNxdHF1cXdxeXF6cXtxfXF+cb1xv3HBccNxxnHHcchxyXHKccxxznHPcdBx0nHTchJyFHIWchhyG3Icch1yHnIfciFyI3IkciVyJ3IocmdyaXJrcm1ycHJxcnJyc3J0cnZyeHJ5cnpyfHJ9crxyvnLAcsJyxXLGcsdyyHLJcstyzXLOcs9y0XLScxFzE3MVcxdzGnMbcxxzHXMecyBzInMjcyRzJnMnc3JzlXO1c9Vz13PZc9tz3XPfc+Bz4XPkc+Vz53Poc+pz7HPtc+5z8XPyc/d0BHQJdAt0DXQSdBV0GHQadD90Y3SKdK50sXSzdLV0t3S5dLt0vHS/dMx03XTfdOF043TldOd06XTrdO10/nUBdQR1B3UKdQ11EHUTdRZ1GHVXdVl1W3VddWB1YXVidWN1ZHVmdWh1aXVqdWx1bXWsda51sHWydbV1tnW3dbh1uXW7db11vnW/dcF1wnYBdgN2BnYIdgt2DHYNdg52D3YRdhN2FHYVdhd2GHYldiZ2J3Ypdmh2anZsdm52cXZydnN2dHZ1dnd2eXZ6dnt2fXZ+dr12v3bBdsN2xnbHdsh2yXbKdsx2znbPdtB20nbTdxJ3FHcWdxh3G3ccdx13HncfdyF3I3ckdyV3J3cod2d3aXdrd213cHdxd3J3c3d0d3Z3eHd5d3p3fHd9d7x3vnfAd8J3xXfGd8d3yHfJd8t3zXfOd8930XfSd/d4G3hCeGZ4aXhreG14b3hxeHN4dHh3eIR4k3iVeJd4mXibeJ14n3iheLB4s3i2eLl4vHi/eMJ4xXjHeQZ5CHkKeQx5D3kQeRF5EnkTeRV5F3kYeRl5G3kceVt5XXlfeWF5ZHlleWZ5Z3loeWp5bHlteW55cHlxebB5snm0ebZ5uXm6ebt5vHm9eb95wXnCecN5xXnGegV6B3oJegt6DnoPehB6EXoSehR6FnoXehh6Gnobelp6XHpeemB6Y3pkemV6Znpneml6a3psem16b3pweq96sXqzerV6uHq5erp6u3q8er56wHrBesJ6xHrFewR7BnsIewp7DXsOew97EHsRexN7FXsWexd7GXsae2V7iHuoe8h7ynvMe8570HvSe9N71HvXe9h72nvbe9574Hvhe+J75Xvme+t7+Hv9e/98AXwGfAl8DHwOfDN8V3x+fKJ8pXynfKl8q3ytfK98sHyzfMB80XzTfNV813zZfNt83XzffOF88nz1fPh8+3z+fQF9BH0HfQp9DH1LfU19T31RfVR9VX1WfVd9WH1afVx9XX1efWB9YX2gfaJ9pH2mfal9qn2rfax9rX2vfbF9sn2zfbV9tn31ffd9+n38ff9+AH4BfgJ+A34Ffgd+CH4Jfgt+DH4Zfh5+IH4ifid+KX4sfi5+O35AfkJ+RH5Jfkt+TX5Pfo5+kH6SfpR+l36Yfpl+mn6bfp1+n36gfqF+o36kfuN+5X7nful+7H7tfu5+737wfvJ+9H71fvZ++H75fzh/On88fz5/QX9Cf0N/RH9Ff0d/SX9Kf0t/TX9Of41/j3+Rf5N/ln+Xf5h/mX+af5x/nn+ff6B/on+jf+J/5H/mf+h/63/sf+1/7n/vf/F/83/0f/V/93/4gB2AQYBogIyAj4CRgJOAlYCXgJmAmoCdgKqAuYC7gL2Av4DBgMOAxYDHgNaA2YDcgN+A4oDlgOiA64DtgSyBLoExgTOBNoE3gTiBOYE6gTyBPoE/gUCBQoFDgYKBhIGGgYiBi4GMgY2BjoGPgZGBk4GUgZWBl4GYgdeB2YHcgd6B4YHigeOB5IHlgeeB6YHqgeuB7YHugi2CL4IxgjOCNoI3gjiCOYI6gjyCPoI/gkCCQoJDgoKChIKGgoiCi4KMgo2CjoKPgpGCk4KUgpWCl4KYgteC2YLbgt2C4ILhguKC44LkguaC6ILpguqC7ILtgyyDLoMwgzKDNYM2gzeDOIM5gzuDPYM+gz+DQYNCg0uDXoNrg36Di4Oeg7WDx4QShDWEVYR1hHeEeYR7hH2Ef4SAhIGEhISFhIeEiISKhIyEjYSOhJGEkoSbhKiErYSvhLGEtoS5hLyEvoTjhQeFLoVShVWFV4VZhVuFXYVfhWCFY4VwhYGFg4WFhYeFiYWLhY2Fj4WRhaKFpYWohauFroWxhbSFt4W6hbyF+4X9hf+GAYYEhgWGBoYHhgiGCoYMhg2GDoYQhhGGUIZShlSGVoZZhlqGW4Zchl2GX4ZhhmKGY4ZlhmaGpYanhqqGrIavhrCGsYayhrOGtYa3hriGuYa7hryGyYbOhtCG0obXhtmG3IbehuuG8IbyhvSG+Yb7hv2G/4c+h0CHQodEh0eHSIdJh0qHS4dNh0+HUIdRh1OHVIeTh5WHl4eZh5yHnYeeh5+HoIeih6SHpYemh6iHqYfoh+qH7Ifuh/GH8ofzh/SH9Yf3h/mH+of7h/2H/og9iD+IQYhDiEaIR4hIiEmISohMiE6IT4hQiFKIU4iSiJSIloiYiJuInIidiJ6In4ihiKOIpIiliKeIqIjNiPGJGIk8iT+JQYlDiUWJR4lJiUqJTYlaiWmJa4ltiW+JcYlziXWJd4mGiYmJjImPiZKJlYmYiZuJnYncid6J4IniieWJ5onnieiJ6Ynrie2J7onvifGJ8ooxijOKNYo3ijqKO4o8ij2KPopAikKKQ4pEikaKR4qGioiKioqMio+KkIqRipKKk4qVipeKmIqZipuKnIrbit2K34rhiuSK5YrmiueK6IrqiuyK7YruivCK8YswizKLNIs2izmLOos7izyLPYs/i0GLQotDi0WLRouFi4eLiYuLi46Lj4uQi5GLkouUi5aLl4uYi5qLm4vai9yL3ovgi+OL5Ivli+aL54vpi+uL7Ivti++L8Iw7jF6MfoyejKCMooykjKaMqIypjKqMrYyujLCMsYyzjLWMtoy3jLqMu4zAjM2M0ozUjNaM24zejOGM440IjSyNU413jXqNfI1+jYCNgo2EjYWNiI2VjaaNqI2qjayNro2wjbKNtI22jceNyo3NjdCN043WjdmN3I3fjeGOII4ijiSOJo4pjiqOK44sji2OL44xjjKOM441jjaOdY53jnmOe45+jn+OgI6BjoKOhI6GjoeOiI6KjouOyo7Mjs+O0Y7UjtWO1o7XjtiO2o7cjt2O3o7gjuGO7o7vjvCO8o8xjzOPNY83jzqPO488jz2PPo9Aj0KPQ49Ej0aPR4+Gj4iPio+Mj4+PkI+Rj5KPk4+Vj5ePmI+Zj5uPnI/bj92P34/hj+SP5Y/mj+eP6I/qj+yP7Y/uj/CP8ZAwkDKQNJA2kDmQOpA7kDyQPZA/kEGQQpBDkEWQRpCFkIeQiZCLkI6Qj5CQkJGQkpCUkJaQl5CYkJqQm5DAkOSRC5EvkTKRNJE2kTiROpE8kT2RQJFNkVyRXpFgkWKRZJFmkWiRapF5kXyRf5GCkYWRiJGLkY6RkJHPkdGR05HVkdiR2ZHakduR3JHekeCR4ZHikeSR5ZIkkiaSKJIqki2SLpIvkjCSMZIzkjWSNpI3kjmSOpJ5knuSfZJ/koKSg5KEkoWShpKIkoqSi5KMko6Sj5LOktCS0pLUkteS2JLZktqS25Ldkt+S4JLhkuOS5JMjkyWTJ5MpkyyTLZMuky+TMJMykzSTNZM2kziTOZN4k3qTfJN+k4GTgpODk4SThZOHk4mTipOLk42TjpPNk8+T0ZPTk9aT15PYk9mT2pPck96T35Pgk+KT45QulFGUcZSRlJOUlZSXlJmUm5SclJ2UoJShlKOUpJSmlKiUqZSqlK2UrpSzlMCUxZTHlMmUzpTRlNSU1pT7lR+VRpVqlW2Vb5VxlXOVdZV3lXiVe5WIlZmVm5WdlZ+VoZWjlaWVp5WplbqVvZXAlcOVxpXJlcyVz5XSldSWE5YVlheWGZYclh2WHpYfliCWIpYkliWWJpYolimWaJZqlmyWbpZxlnKWc5Z0lnWWd5Z5lnqWe5Z9ln6WvZa/lsKWxJbHlsiWyZbKlsuWzZbPltCW0ZbTltSW4ZbiluOW5ZcklyaXKJcqly2XLpcvlzCXMZczlzWXNpc3lzmXOpd5l3uXfZd/l4KXg5eEl4WXhpeIl4qXi5eMl46Xj5fOl9CX0pfUl9eX2JfZl9qX25fdl9+X4Jfhl+OX5JgjmCWYJ5gpmCyYLZgumC+YMJgymDSYNZg2mDiYOZh4mHqYfJh+mIGYgpiDmISYhZiHmImYipiLmI2YjpizmNeY/pkimSWZJ5kpmSuZLZkvmTCZM5lAmU+ZUZlTmVWZV5lZmVuZXZlsmW+Zcpl1mXiZe5l+mYGZg5nCmcSZxpnImcuZzJnNmc6Zz5nRmdOZ1JnVmdeZ2JoXmhmaG5odmiCaIZoimiOaJJommiiaKZoqmiyaLZpsmm6acJpymnWadpp3mniaeZp7mn2afpp/moGagprBmsOaxZrHmsqay5rMms2azprQmtKa05rUmtaa15sWmxibGpscmx+bIJshmyKbI5slmyebKJspmyubLJtrm22bb5txm3SbdZt2m3ebeJt6m3ybfZt+m4CbgZvAm8KbxJvGm8mbypvLm8ybzZvPm9Gb0pvTm9Wb1pwhnEScZJyEnIaciJyKnIycjpyPnJCck5yUnJacl5yZnJucnJydnKCcoZymnLOcuJy6nLycwZzEnMecyZzunRKdOZ1dnWCdYp1knWadaJ1qnWudbp17nYydjp2QnZKdlJ2WnZidmp2cna2dsJ2znbaduZ28nb+dwp3FnceeBp4IngqeDJ4PnhCeEZ4SnhOeFZ4XnhieGZ4bnhyeW55dnl+eYZ5knmWeZp5nnmieap5snm2ebp5wnnGesJ6ynrWet566nruevJ69nr6ewJ7CnsOexJ7Gnsee1J7Vntae2J8XnxmfG58dnyCfIZ8inyOfJJ8mnyifKZ8qnyyfLZ9sn26fcJ9yn3Wfdp93n3ifeZ97n32ffp9/n4Gfgp/Bn8OfxZ/Hn8qfy5/Mn82fzp/Qn9Kf05/Un9af16AWoBigGqAcoB+gIKAhoCKgI6AloCegKKApoCugLKBroG2gb6BxoHSgdaB2oHegeKB6oHygfaB+oICggaCmoMqg8aEVoRihGqEcoR6hIKEioSOhJqEzoUKhRKFGoUihSqFMoU6hUKFfoWKhZaFooWuhbqFxoXShdqG1obehuaG7ob6hv6HAocGhwqHEocahx6HIocqhy6IKogyiDqIQohOiFKIVohaiF6IZohuiHKIdoh+iIKJfomGiY6JlomiiaaJqomuibKJuonCicaJyonSidaK0oraiuKK6or2ivqK/osCiwaLDosWixqLHosmiyqMJowujDaMPoxKjE6MUoxWjFqMYoxqjG6Mcox6jH6Neo2CjYqNko2ejaKNpo2qja6Nto2+jcKNxo3OjdKOzo7Wjt6O5o7yjvaO+o7+jwKPCo8SjxaPGo8ijyaQUpDekV6R3pHmke6R9pH+kgaSCpIOkhqSHpImkiqSMpI6kj6SQpJOklKSZpKakq6StpK+ktKS3pLqkvKThpQWlLKVQpVOlVaVXpVmlW6VdpV6lYaVupX+lgaWDpYWlh6WJpYuljaWPpaClo6WmpamlrKWvpbKltaW4pbql+aX7pf2l/6YCpgOmBKYFpgamCKYKpgumDKYOpg+mTqZQplKmVKZXplimWaZaplumXaZfpmCmYaZjpmSmo6alpqimqqatpq6mr6awprGms6a1pramt6a5prqmx6bMps6m0KbVptem2qbcpumm7qbwpvKm96b5pvum/ac8pz6nQKdCp0WnRqdHp0inSadLp02nTqdPp1GnUqeRp5OnlaeXp5qnm6ecp52nnqegp6Kno6ekp6anp6fmp+in6qfsp++n8Kfxp/Kn86f1p/en+Kf5p/un/Kg7qD2oP6hBqESoRahGqEeoSKhKqEyoTahOqFCoUaiQqJKolKiWqJmomqibqJyonaifqKGooqijqKWopqjLqO+pFqk6qT2pP6lBqUOpRalHqUipS6lYqWepaalrqW2pb6lxqXOpdamEqYepiqmNqZCpk6mWqZmpm6naqdyp3qngqeOp5Knlqeap56npqeup7Kntqe+p8KovqjGqM6o1qjiqOao6qjuqPKo+qkCqQapCqkSqRaqEqoaqiKqKqo2qjqqPqpCqkaqTqpWqlqqXqpmqmqrZqtuq3arfquKq46rkquWq5qroquqq66rsqu6q76suqzCrMqs0qzerOKs5qzqrO6s9qz+rQKtBq0OrRKuDq4Wrh6uJq4yrjauOq4+rkKuSq5SrlauWq5irmavYq9qr3Kveq+Gr4qvjq+Sr5avnq+mr6qvrq+2r7qw5rFysfKycrJ6soKyirKSspqynrKisq6ysrK6sr6yxrLOstKy1rLisuazCrM+s1KzWrNis3azgrOOs5a0KrS6tVa15rXytfq2ArYKthK2GrYetiq2Xraitqq2sra6tsK2yrbSttq24rcmtzK3PrdKt1a3Yrdut3q3hreOuIq4kriauKK4rriyuLa4uri+uMa4zrjSuNa43rjiud655rnuufa6AroGugq6DroSuhq6Iromuiq6Mro2uzK7OrtGu067Wrteu2K7Zrtqu3K7ert+u4K7iruOu8K71rveu+a7+rwCvA68FrxKvF68ZrxuvIK8irySvJq9lr2evaa9rr26vb69wr3Gvcq90r3avd694r3qve6+6r7yvvq/Ar8OvxK/Fr8avx6/Jr8uvzK/Nr8+v0LAPsBGwE7AVsBiwGbAasBuwHLAesCCwIbAisCSwJbBksGawaLBqsG2wbrBvsHCwcbBzsHWwdrB3sHmwerC5sLuwvbC/sMKww7DEsMWwxrDIsMqwy7DMsM6wz7D0sRixP7FjsWaxaLFqsWyxbrFwsXGxdLGBsZCxkrGUsZaxmLGasZyxnrGtsbCxs7G2sbmxvLG/scKxxLIDsgWyB7IJsgyyDbIOsg+yELISshSyFbIWshiyGbJYslqyXLJesmGyYrJjsmSyZbJnsmmyarJrsm2ybrKtsq+ysbKzsrayt7K4srmyurK8sr6yv7LAssKyw7MCswSzB7MJswyzDbMOsw+zELMSsxSzFbMWsxizGbNYs1qzXLNes2GzYrNjs2SzZbNns2mzarNrs22zbrOts6+zsbOzs7azt7O4s7mzurO8s76zv7PAs8Kzw7QCtAS0BrQItAu0DLQNtA60D7QRtBO0FLQVtBe0GLRjtIa0prTGtMi0yrTMtM600LTRtNK01bTWtNi02bTbtN203rTftOK047TotPW0+rT8tP61A7UGtQm1C7UwtVS1e7WftaK1pLWmtai1qrWsta21sLW9tc610LXStdS11rXYtdq13LXete+18rX1tfi1+7X+tgG2BLYHtgm2SLZKtky2TrZRtlK2U7ZUtlW2V7ZZtlq2W7Zdtl62nbaftqG2o7amtqe2qLaptqq2rLautq+2sLaytrO28rb0tve2+bb8tv22/rb/twC3ArcEtwW3BrcItwm3FrcXtxi3GrdZt1u3Xbdft2K3Y7dkt2W3Zrdot2q3a7dst263b7eut7C3sre0t7e3uLe5t7q3u7e9t7+3wLfBt8O3xLgDuAW4B7gJuAy4DbgOuA+4ELgSuBS4FbgWuBi4GbhYuFq4XLheuGG4YrhjuGS4ZbhnuGm4arhruG24brituK+4sbizuLa4t7i4uLm4uri8uL64v7jAuMK4w7jouQy5M7lXuVq5XLleuWC5YrlkuWW5aLl1uYS5hrmIuYq5jLmOuZC5krmhuaS5p7mqua25sLmzuba5uLn3ufm5+7n9ugC6AboCugO6BLoGugi6CboKugy6DbpMuk66ULpSulW6VrpXuli6Wbpbul26XrpfumG6YrqhuqO6pbqnuqq6q7qsuq26rrqwurK6s7q0ura6t7r2uvi6+rr8uv+7ALsBuwK7A7sFuwe7CLsJuwu7DLtLu027T7tRu1S7VbtWu1e7WLtau1y7Xbteu2C7Ybugu6K7pLumu6m7qruru6y7rbuvu7G7sruzu7W7trv1u/e7+bv7u/67/7wAvAG8ArwEvAa8B7wIvAq8C7xWvHm8mby5vLu8vby/vMG8w7zEvMW8yLzJvMu8zLzOvNC80bzSvNW81rzfvOy88bzzvPW8+rz9vQC9Ar0nvUu9cr2WvZm9m72dvZ+9ob2jvaS9p720vcW9x73Jvcu9zb3PvdG9073Vvea96b3sve+98r31vfi9+73+vgC+P75BvkO+Rb5Ivkm+Sr5Lvky+Tr5QvlG+Ur5UvlW+lL6Wvpi+mr6dvp6+n76gvqG+o76lvqa+p76pvqq+6b7rvu6+8L7zvvS+9b72vve++b77vvy+/b7/vwC/Db8SvxS/Fr8bvx2/IL8ivy+/NL82vzi/Pb8/v0G/Q7+Cv4S/hr+Iv4u/jL+Nv46/j7+Rv5O/lL+Vv5e/mL/Xv9m/27/dv+C/4b/iv+O/5L/mv+i/6b/qv+y/7cAswC7AMMAywDXANsA3wDjAOcA7wD3APsA/wEHAQsCBwIPAhcCHwIrAi8CMwI3AjsCQwJLAk8CUwJbAl8DWwNjA2sDcwN/A4MDhwOLA48DlwOfA6MDpwOvA7MERwTXBXMGAwYPBhcGHwYnBi8GNwY7BkcGewa3Br8GxwbPBtcG3wbnBu8HKwc3B0MHTwdbB2cHcwd/B4cIgwiLCJMImwinCKsIrwizCLcIvwjHCMsIzwjXCNsJ1wnfCecJ7wn7Cf8KAwoHCgsKEwobCh8KIworCi8LKwszCzsLQwtPC1MLVwtbC18LZwtvC3MLdwt/C4MMfwyHDI8MlwyjDKcMqwyvDLMMuwzDDMcMywzTDNcN0w3bDeMN6w33DfsN/w4DDgcODw4XDhsOHw4nDisPJw8vDzcPPw9LD08PUw9XD1sPYw9rD28Pcw97D38QexCDEIsQkxCfEKMQpxCrEK8QtxC/EMMQxxDPENMR/xKLEwsTixOTE5sToxOrE7MTtxO7E8cTyxPTE9cT3xPnE+sT7xP7E/8UExRHFFsUYxRrFH8UixSXFJ8VMxXDFl8W7xb7FwMXCxcTFxsXIxcnFzMXZxerF7MXuxfDF8sX0xfbF+MX6xgvGDsYRxhTGF8Yaxh3GIMYjxiXGZMZmxmjGasZtxm7Gb8ZwxnHGc8Z1xnbGd8Z5xnrGuca7xr3Gv8bCxsPGxMbFxsbGyMbKxsvGzMbOxs/HDscQxxPHFccYxxnHGscbxxzHHscgxyHHIsckxyXHMsczxzTHNsd1x3fHecd7x37Hf8eAx4HHgseEx4bHh8eIx4rHi8fKx8zHzsfQx9PH1MfVx9bH18fZx9vH3Mfdx9/H4MgfyCHII8glyCjIKcgqyCvILMguyDDIMcgyyDTINch0yHbIeMh6yH3Ifsh/yIDIgciDyIXIhsiHyInIisjJyMvIzcjPyNLI08jUyNXI1sjYyNrI28jcyN7I38kEySjJT8lzyXbJeMl6yXzJfsmAyYHJhMmRyaDJosmkyabJqMmqyazJrsm9ycDJw8nGycnJzMnPydLJ1MoTyhXKF8oZyhzKHcoeyh/KIMoiyiTKJcomyijKKcpoymrKbMpuynHKcspzynTKdcp3ynnKesp7yn3Kfsq9yr/KwcrDysbKx8rIysnKysrMys7Kz8rQytLK08sSyxTLF8sZyxzLHcseyx/LIMsiyyTLJcsmyyjLKctoy2rLbMtuy3HLcstzy3TLdct3y3nLest7y33Lfsu9y7/LwcvDy8bLx8vIy8nLysvMy87Lz8vQy9LL08wSzBTMFswYzBvMHMwdzB7MH8whzCPMJMwlzCfMKMwzzDzMPcw/zEjMU8xizG3Me8yQzKTMu8zNzQzNDs0QzRLNFM0VzRbNF80YzRrNHM0dzR7NIM0hzWDNYs1kzWbNaM1pzWrNa81szW7NcM1xzXLNdM11zbTNts25zbvNvc2+zb/NwM3BzcPNxc3GzcfNyc3KzhXOOM5YznjOes58zn7OgM6CzoPOhM6HzojOis6Lzo3Oj86QzpHOlM6VzprOp86szq7OsM61zrjOu869zuLPBs8tz1HPVM9Wz1jPWs9cz17PX89iz2/PgM+Cz4TPhs+Iz4rPjM+Oz5DPoc+kz6fPqs+tz7DPs8+2z7nPu8/6z/zP/tAA0APQBNAF0AbQB9AJ0AvQDNAN0A/QENBP0FHQU9BV0FjQWdBa0FvQXNBe0GDQYdBi0GTQZdCk0KbQqdCr0K7Qr9Cw0LHQstC00LbQt9C40LrQu9DI0M3Qz9DR0NbQ2NDb0N3Q6tDv0PHQ89D40PrQ/ND+0T3RP9FB0UPRRtFH0UjRSdFK0UzRTtFP0VDRUtFT0ZLRlNGW0ZjRm9Gc0Z3RntGf0aHRo9Gk0aXRp9Go0efR6dHr0e3R8NHx0fLR89H00fbR+NH50frR/NH90jzSPtJA0kLSRdJG0kfSSNJJ0kvSTdJO0k/SUdJS0pHSk9KV0pfSmtKb0pzSndKe0qDSotKj0qTSptKn0szS8NMX0zvTPtNA00LTRNNG00jTSdNM01nTaNNq02zTbtNw03LTdNN204XTiNOL047TkdOU05fTmtOc09vT3dPf0+HT5NPl0+bT59Po0+rT7NPt0+7T8NPx1DDUMtQ01DbUOdQ61DvUPNQ91D/UQdRC1EPURdRG1IXUh9SJ1IvUjtSP1JDUkdSS1JTUltSX1JjUmtSb1NrU3NTe1ODU49Tk1OXU5tTn1OnU69Ts1O3U79Tw1S/VMdUz1TXVONU51TrVO9U81T7VQNVB1ULVRNVF1YTVhtWI1YrVjdWO1Y/VkNWR1ZPVldWW1ZfVmdWa1dnV29Xd1d/V4tXj1eTV5dXm1ejV6tXr1ezV7tXv1fjV+dX71gjWCdYK1gzWGdYa1hvWHdYq1ivWLNYu1jfWRtZT1mLWdNaI1p/Wsda61rvWvdbK1svWzNbO1tfW4dbo1vLW+tcM1xHXFgAAAAAAAAICAAAAAAAAICYAAAAAAAAAAAAAAAAAANcY + + Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel + YnBsaXN0MDDUAAEAAgADAAQABQAGFOcU6FgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv +cBIAAYagrxEBwgAHAAgAFwAYADQANQA2AD4APwBaAFsAXABiAGMAbwCDAIQAhQCGAIcAiACJAIoAiwCkAK0AvADLANoA3QDhAFkA8QEAAQYBBwEIAQwBGwEhASIBKgE5AToBQwFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AYkBigGSAZMBlAGgAbQBtQG2AbcBuAG5AboBuwG8AcsB2gHpAfEB8gH6AfsB/AH9Af4CDQIcAh0CLAI7AkoCVgJoAmkCagJrAmwCbQJuAm8CfgKNApwCqwKsArsCygLZAuEC9gL3Av8DCwMfAy4DPQNMA1QDXANrA3oDiQOYA6cDswPFA9QD1QPkA/MEAgQDBBIEIQQwBEUERgROBFoEbgR9BIwEmwSfBK4EvQTMBNsE6gT2BQgFFwUmBTUFRAVFBVQFYwVyBYcFiAWQBZwFsAW/Bc4F3QXhBfAF/wYOBh0GLAY4BkoGWQZoBncGhgaVBqQGswbIBskG0QbdBvEHAAcPBx4HJgcuBz0HTAdbB2oHeQeFB5cHpge1B8QH0wfiB/EIAAgVCBYIHggqCD4ITQhcCGsIbwh+CI0InAirCLoIxgjYCOcI9gkFCRQJIwkyCUEJVglXCV8Jawl/CY4JnQmsCbAJvwnOCd0J7An7CgcKGQooCjcKRgpVCmQKcwqCCpcKmAqgCqwKwArPCt4K7Qr1Cv0LDAsbCyoLOQtIC1QLZgt1C4QLkwuiC7ELwAvPC+QL5QvtC/kMDQwcDCsMOgw+DE0MXAxrDHoMiQyVDKcMtgzFDNQM4wzyDQENEA0lDSYNLg06DU4NXQ1sDXsNfw2ODZ0NrA27DcoN1g3oDfcOBg4VDiQOMw5CDlEOZg5nDm8Oew6PDp4OrQ68DsQOzA7bDuoO+Q8IDxcPIw81D0QPUw9iD3EPgA+PD54Psw+0D7wPyA/cD+sP+hAJEBEQGRAoEDcQRhBVEGQQcBCCEJEQoBCvEL4QzRDcEOsRABEBEQkRFREpETgRRxFWEVoRaRF4EYcRlhGlEbERwxHSEeER8BH/Eg4SHRIsEkESQhJKElYSahJ5EogSlxKfEqcSthLFEtQS4xLyEv4TEBMfEy4TPRNME1sTahN5E44TjxOXE6MTtxPGE9UT5BPoE/cUBhQVFCQUMxQ/FFEUYBRvFH4UjRScFKsUuhS7FL4UxxTLFM8U0xTbFN4U4lUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAFQATXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoADgQHBgQG/gACBAcCAAoAAXxAUdW50aXRsZWQueGNkYXRhbW9kZWzeABkAGgAbABwAHQAeAB8ACgAgACEAIgAjACQAJQAmACcAKAApACYAEwAsAC0ALgAvADAAJgAmABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgAWBAb2BAbuAAYAFgACBAbyBAb4QAIAGgASABYAFgABQU1lFU9MANwA4AAoAOQA7AD1XTlMua2V5c1pOUy5vYmplY3RzoQA6gAehADyACIAkWkNvbm5lY3Rpb27fEBAAQABBAEIAQwAeAEQARQAgAEYARwAKACIASABJACUASgBLAEwAJgAmABAAUABRAC4AJgBLAFQAOgBLAFcAWABZXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAqALIAFgAWAA4ALgQG4gAWACoEBuoAHgAqBAbmACQgSEYXAg1dvcmRlcmVk0wA3ADgACgBdAF8APaEAXoAMoQBggA2AJF5YRF9QU3RlcmVvdHlwZdkAHgAiAGQACgAlAGUAIABKAGYAPABeAEsAagATACYALgBZAG5fECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WACIAMgAqAK4AAgAUIgA7TADcAOAAKAHAAeQA9qABxAHIAcwB0AHUAdgB3AHiAD4AQgBGAEoATgBSAFYAWqAB6AHsAfAB9AH4AfwCAAIGAF4AZgBqAG4AegCCAJYApgCRfEBNYRFBNQ29tcG91bmRJbmRleGVzXxAQWERfUFNLX2VsZW1lbnRJRF8QGlhEX1BTS192ZXJzaW9uSGFzaE1vZGlmaWVyXxAZWERfUFNLX2ZldGNoUmVxdWVzdHNBcnJheV8QEVhEX1BTS19pc0Fic3RyYWN0XxAPWERfUFNLX3VzZXJJbmZvXxATWERfUFNLX2NsYXNzTWFwcGluZ18QFlhEX1BTS19lbnRpdHlDbGFzc05hbWXfEA8AjACNAI4AHgCPAJAAkQAgAJIACgAiAJMAlAAlAJUAEwATABMAYABZAFkAWQAuAFkAngBxAFkAWQATAFlVX3R5cGVYX2RlZmF1bHRcX2Fzc29jaWF0aW9uW19pc1JlYWRPbmx5WV9pc1N0YXRpY1lfaXNVbmlxdWVaX2lzRGVyaXZlZFpfaXNPcmRlcmVkXF9pc0NvbXBvc2l0ZVdfaXNMZWFmgACAAIAAgA0ICAgIgBiADwgIgAAI0gClAKYApwCoWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBYRFVNTFByb3BlcnR5SW1wpACpAKoAqwCsXxAQWERVTUxQcm9wZXJ0eUltcF8QFFhEVU1MTmFtZWRFbGVtZW50SW1wXxAPWERVTUxFbGVtZW50SW1wWE5TT2JqZWN03xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMAEwATAGAAWQBZAFkALgBZAJ4AcgBZAFkAEwBZgACAAIAAgA0ICAgIgBiAEAgIgAAI3xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMAEwATAGAAWQBZAFkALgBZAJ4AcwBZAFkAEwBZgACAAIAAgA0ICAgIgBiAEQgIgAAI3xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMAzQATAGAAWQBZAFkALgBZAJ4AdABZAFkAEwBZgACAHIAAgA0ICAgIgBiAEggIgAAI0gA4AAoA2wDcoIAd0gClAKYA3gDfXk5TTXV0YWJsZUFycmF5owDeAOAArFdOU0FycmF53xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMA4wATAGAAWQBZAFkALgBZAJ4AdQBZAFkAEwBZgACAH4AAgA0ICAgIgBiAEwgIgAAICN8QDwCMAI0AjgAeAI8AkACRACAAkgAKACIAkwCUACUAlQATAPMAEwBgAFkAWQBZAC4AWQCeAHYAWQBZABMAWYAAgCGAAIANCAgICIAYgBQICIAACNMANwA4AAoBAQEDAD2hAQKAIqEBBIAjgCRfEDFjb20uYXBwbGUuc3luY3NlcnZpY2VzLkV4Y2x1ZGVGcm9tRGF0YUNoYW5nZUFsZXJ0Uk5P0gClAKYBCQEKXxATTlNNdXRhYmxlRGljdGlvbmFyeaMBCQELAKxcTlNEaWN0aW9uYXJ53xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMBDgATAGAAWQBZAFkALgBZAJ4AdwBZAFkAEwBZgACAJoAAgA0ICAgIgBiAFQgIgAAI1gAiAAoAJQBKAB4AIAEcAR0AEwBZABMALoAngCiAAAiAAF8QFFhER2VuZXJpY1JlY29yZENsYXNz0gClAKYBIwEkXVhEVU1MQ2xhc3NJbXCmASUBJgEnASgBKQCsXVhEVU1MQ2xhc3NJbXBfEBJYRFVNTENsYXNzaWZpZXJJbXBfEBFYRFVNTE5hbWVzcGFjZUltcF8QFFhEVU1MTmFtZWRFbGVtZW50SW1wXxAPWERVTUxFbGVtZW50SW1w3xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMBLAATAGAAWQBZAFkALgBZAJ4AeABZAFkAEwBZgACAKoAAgA0ICAgIgBiAFggIgAAIXxARTUhDb25uZWN0aW9uU3RvcmXSAKUApgE7ATxfEBJYRFVNTFN0ZXJlb3R5cGVJbXCnAT0BPgE/AUABQQFCAKxfEBJYRFVNTFN0ZXJlb3R5cGVJbXBdWERVTUxDbGFzc0ltcF8QElhEVU1MQ2xhc3NpZmllckltcF8QEVhEVU1MTmFtZXNwYWNlSW1wXxAUWERVTUxOYW1lZEVsZW1lbnRJbXBfEA9YRFVNTEVsZW1lbnRJbXDTADcAOAAKAUQBVAA9rxAPAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTgC2ALoAvgDCAMYAygDOANIA1gDaAN4A4gDmAOoA7rxAPAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEBYgFjgDyAbYCHgJ+AtoDOgOWA/IEBFIEBK4EBQoEBWoEBcoEBiYEBoYAkWWRlZmF1bHRkYldzc2hwb3J0VnVzZXNzbFlhZG1pbnVzZXJac3Noa2V5ZmlsZVhiaW5kcG9ydFtiaW5kYWRkcmVzc1VhbGlhc1lyZXBsX25hbWVXc2VydmVyc1dzc2hob3N0VnVzZXNzaF8QD2RlZmF1bHRSZWFkTW9kZVdzc2h1c2VyV3VzZXJlcGzfEBIAjACNAI4BdQAeAJAAkQF2ACAAjwF3AJIACgAiAJMAlAAlAJUAEwATABMAJgA8AFkAWQF/AC4AWQBLAFkBgwFFAFkAWQGHAFlfECBYREJ1Y2tldEZvclN0ZXJlb3R5cGVzd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNzdG9yYWdlXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc29yZGVyZWSAAIAAgACABYAICAiAPgiACgiAbIAtCAiAPQgT/////8KHxrXTADcAOAAKAYsBjgA9ogGMAY2AP4BAogGPAZCAQYB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sE+sT7RPvE/ET8xP0E/UT9hP3E/kT+xP8E/0T/xQAFD8UQRRDFEUURxRIFEkUShRLFE0UTxRQFFEUUxRUFJMUlRSXFJkUmxScFJ0UnhSfFKEUoxSkFKUUpxSoFLUUuhS8FL4UwxTFFMcUyRT8FQkVDhUQFRIVFxUZFRsVHRUzFUUVSRVPFY4VkBWSFZQVlhWXFZgVmRWaFZwVnhWfFaAVohWjFeIV5BXmFegV6hXrFewV7RXuFfAV8hXzFfQV9hX3FfgWNxY5FjsWPRY/FkAWQRZCFkMWRRZHFkgWSRZLFkwWixaNFo8WkRaTFpQWlRaWFpcWmRabFpwWnRafFqAW3xbhFuMW5RbnFugW6RbqFusW7RbvFvAW8RbzFvQXGRc9F2QXiBeKF4wXjheQF5IXlBeVF5cXpBezF7UXtxe5F7sXvRe/F8EX0BfSF9QX1hfYF9oX3BfeF+AYABgrGEUYXhh4GJgYuxj6GPwY/hkAGQIZAxkEGQUZBhkIGQoZCxkMGQ4ZDxlOGVAZUhlUGVYZVxlYGVkZWhlcGV4ZXxlgGWIZYxmiGaQZphmoGaoZqxmsGa0ZrhmwGbIZsxm0GbYZtxn2GfgZ+hn8Gf4Z/xoAGgEaAhoEGgYaBxoIGgoaCxoOGk0aTxpRGlMaVRpWGlcaWBpZGlsaXRpeGl8aYRpiGqEaoxqlGqcaqRqqGqsarBqtGq8asRqyGrMatRq2GvUa9xr5Gvsa/Rr+Gv8bABsBGwMbBRsGGwcbCRsKGxMbIRsuGzwbSRtcG3MbhRvQG/McExwzHDUcNxw5HDscPRw+HD8cQRxCHEQcRRxHHEkcShxLHE0cThxXHGQcaRxrHG0cchx0HHYceBydHMEc6B0MHQ4dEB0SHRQdFh0YHRkdGx0oHTkdOx09HT8dQR1DHUUdRx1JHVodXB1eHWAdYh1kHWYdaB1qHWwdqx2tHa8dsR2zHbQdtR22HbcduR27HbwdvR2/HcAd/x4BHgMeBR4HHggeCR4KHgseDR4PHhAeER4THhQeUx5VHlceWR5bHlweXR5eHl8eYR5jHmQeZR5nHmgedR56Hnwefh6DHoUehx6JHpYemx6dHp8epB6mHqgeqh7pHuse7R7vHvEe8h7zHvQe9R73Hvke+h77Hv0e/h89Hz8fQR9DH0UfRh9HH0gfSR9LH00fTh9PH1EfUh+RH5MflR+XH5kfmh+bH5wfnR+fH6Efoh+jH6Ufph/lH+cf6R/rH+0f7h/vH/Af8R/zH/Uf9h/3H/kf+iA5IDsgPSA/IEEgQiBDIEQgRSBHIEkgSiBLIE0gTiBzIJcgviDiIOQg5iDoIOog7CDuIO8g8SD+IQ0hDyERIRMhFSEXIRkhGyEqISwhLiEwITIhNCE2ITghOiF5IXshfSF/IYEhgiGDIYQhhSGHIYkhiiGLIY0hjiGQIc8h0SHTIdUh1yHYIdkh2iHbId0h3yHgIeEh4yHkIiMiJSInIikiKyIsIi0iLiIvIjEiMyI0IjUiNyI4IncieSJ7In0ifyKAIoEigiKDIoUihyKIIokiiyKMIo4izSLPItEi0yLVItYi1yLYItki2yLdIt4i3yLhIuIjISMjIyUjJyMpIyojKyMsIy0jLyMxIzIjMyM1IzYjdSN3I3kjeyN9I34jfyOAI4EjgyOFI4YjhyOJI4oj1SP4JBgkOCQ6JDwkPiRAJEIkQyREJEYkRyRJJEokTCROJE8kUCRSJFMkXCRpJG4kcCRyJHckeSR7JH0koiTGJO0lESUTJRUlFyUZJRslHSUeJSAlLSU+JUAlQiVEJUYlSCVKJUwlTiVfJWElYyVlJWclaSVrJW0lbyVxJbAlsiW0JbYluCW5JboluyW8Jb4lwCXBJcIlxCXFJgQmBiYIJgomDCYNJg4mDyYQJhImFCYVJhYmGCYZJlgmWiZcJl4mYCZhJmImYyZkJmYmaCZpJmombCZtJnomeyZ8Jn4mvSa/JsEmwybFJsYmxybIJskmyybNJs4mzybRJtInEScTJxUnFycZJxonGyccJx0nHychJyInIyclJyYnZSdnJ2knaydtJ24nbydwJ3Encyd1J3Yndyd5J3onuSe7J70nvyfBJ8InwyfEJ8UnxyfJJ8onyyfNJ84oDSgPKBEoEygVKBYoFygYKBkoGygdKB4oHyghKCIoRyhrKJIotii4KLoovCi+KMAowijDKMUo0ijhKOMo5SjnKOko6yjtKO8o/ikAKQIpBCkGKQgpCikMKQ4pTSlPKVEpUylVKVYpVylYKVkpWyldKV4pXylhKWIpoSmjKaUppympKaopqymsKa0prymxKbIpsym1KbYp9Sn3Kfkp+yn9Kf4p/yoAKgEqAyoFKgYqByoJKgoqSSpLKk0qTypRKlIqUypUKlUqVypZKloqWypdKl4qYSqgKqIqpCqmKqgqqSqqKqsqrCquKrAqsSqyKrQqtSr0KvYq+Cr6Kvwq/Sr+Kv8rACsCKwQrBSsGKwgrCStIK0orTCtOK1ArUStSK1MrVCtWK1grWStaK1wrXSuoK8sr6ywLLA0sDywRLBMsFSwWLBcsGSwaLBwsHSwfLCEsIiwjLCUsJiwrLDgsPSw/LEEsRixILEosTCxxLJUsvCzgLOIs5CzmLOgs6izsLO0s7yz8LQ0tDy0RLRMtFS0XLRktGy0dLS4tMC0yLTQtNi04LTotPC0+LUAtfy2BLYMthS2HLYgtiS2KLYstjS2PLZAtkS2TLZQt0y3VLdct2S3bLdwt3S3eLd8t4S3jLeQt5S3nLeguJy4pLisuLS4vLjAuMS4yLjMuNS43LjguOS47LjwuSS5KLksuTS6MLo4ukC6SLpQulS6WLpcumC6aLpwunS6eLqAuoS7gLuIu5C7mLugu6S7qLusu7C7uLvAu8S7yLvQu9S80LzYvOC86LzwvPS8+Lz8vQC9CL0QvRS9GL0gvSS+IL4ovjC+OL5AvkS+SL5MvlC+WL5gvmS+aL5wvnS/cL94v4C/iL+Qv5S/mL+cv6C/qL+wv7S/uL/Av8TAWMDowYTCFMIcwiTCLMI0wjzCRMJIwlDChMLAwsjC0MLYwuDC6MLwwvjDNMM8w0TDTMNUw1zDZMNsw3TEcMR4xIDEiMSQxJTEmMScxKDEqMSwxLTEuMTAxMTFwMXIxdDF2MXgxeTF6MXsxfDF+MYAxgTGCMYQxhTHEMcYxyDHKMcwxzTHOMc8x0DHSMdQx1THWMdgx2TIYMhoyHDIeMiAyITIiMiMyJDImMigyKTIqMiwyLTJsMm4ycDJyMnQydTJ2MncyeDJ6MnwyfTJ+MoAygTLAMsIyxDLGMsgyyTLKMssyzDLOMtAy0TLSMtQy1TMUMxYzGDMaMxwzHTMeMx8zIDMiMyQzJTMmMygzKTN0M5cztzPXM9kz2zPdM98z4TPiM+Mz5TPmM+gz6TPrM+0z7jPvM/Ez8jP7NAg0DTQPNBE0FjQYNBo0HDRBNGU0jDSwNLI0tDS2NLg0ujS8NL00vzTMNN003zThNOM05TTnNOk06zTtNP41ADUCNQQ1BjUINQo1DDUONRA1TzVRNVM1VTVXNVg1WTVaNVs1XTVfNWA1YTVjNWQ1ozW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uVjBWMVYyVjRWNVZ0VnZWeFZ6Vn1WflZ/VoBWgVaDVoVWhlaHVolWilbJVstWzVbPVtJW01bUVtVW1lbYVtpW21bcVt5W31ceVyBXIlckVydXKFcpVypXK1ctVy9XMFcxVzNXNFdzV3VXd1d5V3xXfVd+V39XgFeCV4RXhVeGV4hXiVeuV9JX+VgdWCBYIlgkWCZYKFgqWCtYLlg7WEpYTFhOWFBYUlhUWFZYWFhnWGpYbVhwWHNYdlh5WHxYfli9WL9YwVjDWMZYx1jIWMlYyljMWM5Yz1jQWNJY01kSWRRZFlkYWRtZHFkdWR5ZH1khWSNZJFklWSdZKFlnWWlZa1ltWXBZcVlyWXNZdFl2WXhZeVl6WXxZfVm8Wb5ZwFnCWcVZxlnHWchZyVnLWc1ZzlnPWdFZ0loRWhNaFVoXWhpaG1ocWh1aHlogWiJaI1okWiZaJ1pmWmhaalpsWm9acFpxWnJac1p1WndaeFp5WntafFq7Wr1av1rBWsRaxVrGWsdayFrKWsxazVrOWtBa0VscWz9bX1t/W4Fbg1uFW4dbiVuKW4tbjluPW5FbkluUW5Zbl1uYW5tbnFuhW65bs1u1W7dbvFu/W8JbxFvpXA1cNFxYXFtcXVxfXGFcY1xlXGZcaVx2XIdciVyLXI1cj1yRXJNclVyXXKhcq1yuXLFctFy3XLpcvVzAXMJdAV0DXQVdB10KXQtdDF0NXQ5dEF0SXRNdFF0WXRddVl1YXVpdXF1fXWBdYV1iXWNdZV1nXWhdaV1rXWxdq12tXbBdsl21XbZdt124Xbldu129Xb5dv13BXcJdz13QXdFd014SXhReFl4YXhteHF4dXh5eH14hXiNeJF4lXideKF5nXmlea15tXnBecV5yXnNedF52XnheeV56XnxefV68Xr5ewF7CXsVexl7HXsheyV7LXs1ezl7PXtFe0l8RXxNfFV8XXxpfG18cXx1fHl8gXyJfI18kXyZfJ19mX2hfal9sX29fcF9xX3Jfc191X3dfeF95X3tffF+hX8Vf7GAQYBNgFWAXYBlgG2AdYB5gIWAuYD1gP2BBYENgRWBHYElgS2BaYF1gYGBjYGZgaWBsYG9gcWCwYLJgtGC2YLlgumC7YLxgvWC/YMFgwmDDYMVgxmEFYQdhCWELYQ5hD2EQYRFhEmEUYRZhF2EYYRphG2FaYVxhXmFgYWNhZGFlYWZhZ2FpYWthbGFtYW9hcGGvYbFhs2G1YbhhuWG6YbthvGG+YcBhwWHCYcRhxWIEYgZiCGIKYg1iDmIPYhBiEWITYhViFmIXYhliGmJZYltiXWJfYmJiY2JkYmViZmJoYmpia2JsYm5ib2KuYrBismK0YrdiuGK5Yrpiu2K9Yr9iwGLBYsNixGMPYzJjUmNyY3RjdmN4Y3pjfGN9Y35jgWOCY4RjhWOHY4ljimOLY45jj2OUY6FjpmOoY6pjr2OyY7Vjt2PcZABkJ2RLZE5kUGRSZFRkVmRYZFlkXGRpZHpkfGR+ZIBkgmSEZIZkiGSKZJtknmShZKRkp2SqZK1ksGSzZLVk9GT2ZPhk+mT9ZP5k/2UAZQFlA2UFZQZlB2UJZQplSWVLZU1lT2VSZVNlVGVVZVZlWGVaZVtlXGVeZV9lnmWgZaNlpWWoZallqmWrZaxlrmWwZbFlsmW0ZbVlwmXHZclly2XQZdJl1WXXZeRl6WXrZe1l8mX0ZfZl+GY3ZjlmO2Y9ZkBmQWZCZkNmRGZGZkhmSWZKZkxmTWaMZo5mkGaSZpVmlmaXZphmmWabZp1mnmafZqFmombhZuNm5WbnZupm62bsZu1m7mbwZvJm82b0ZvZm92c2ZzhnOmc8Zz9nQGdBZ0JnQ2dFZ0dnSGdJZ0tnTGeLZ41nj2eRZ5RnlWeWZ5dnmGeaZ5xnnWeeZ6BnoWfGZ+poEWg1aDhoOmg8aD5oQGhCaENoRmhTaGJoZGhmaGhoamhsaG5ocGh/aIJohWiIaItojmiRaJRolmjVaNdo2WjbaN5o32jgaOFo4mjkaOZo52joaOpo62kqaSxpLmkwaTNpNGk1aTZpN2k5aTtpPGk9aT9pQGl/aYFpg2mFaYhpiWmKaYtpjGmOaZBpkWmSaZRplWnUadZp2Gnaad1p3mnfaeBp4WnjaeVp5mnnaelp6mopaitqLWovajJqM2o0ajVqNmo4ajpqO2o8aj5qP2p+aoBqgmqEaodqiGqJaopqi2qNao9qkGqRapNqlGrTatVq12rZatxq3Wreat9q4GriauRq5Wrmauhq6Ws0a1drd2uXa5lrm2uda59roWuia6Nrpmuna6lrqmusa65rr2uwa7NrtGu9a8prz2vRa9Nr2Gvba95r4GwFbClsUGx0bHdseWx7bH1sf2yBbIJshWySbKNspWynbKlsq2ytbK9ssWyzbMRsx2zKbM1s0GzTbNZs2WzcbN5tHW0fbSFtI20mbSdtKG0pbSptLG0ubS9tMG0ybTNtcm10bXZteG17bXxtfW1+bX9tgW2DbYRthW2HbYhtx23Jbcxtzm3RbdJt023UbdVt123Zbdpt223dbd5t623wbfJt9G35bftt/m4Abg1uEm4UbhZuG24dbh9uIW5gbmJuZG5mbmluam5rbmxubW5vbnFucm5zbnVudm61brduuW67br5uv27AbsFuwm7EbsZux27Ibspuy28KbwxvDm8QbxNvFG8VbxZvF28ZbxtvHG8dbx9vIG9fb2FvY29lb2hvaW9qb2tvbG9ub3BvcW9yb3RvdW+0b7ZvuG+6b71vvm+/b8BvwW/Db8Vvxm/Hb8lvym/vcBNwOnBecGFwY3BlcGdwaXBrcGxwb3B8cItwjXCPcJFwk3CVcJdwmXCocKtwrnCxcLRwt3C6cL1wv3D+cQBxAnEEcQdxCHEJcQpxC3ENcQ9xEHERcRNxFHFTcVVxV3FZcVxxXXFecV9xYHFicWRxZXFmcWhxaXGocapxrHGucbFxsnGzcbRxtXG3cblxunG7cb1xvnH9cf9yAXIDcgZyB3IIcglyCnIMcg5yD3IQchJyE3JSclRyVnJYcltyXHJdcl5yX3JhcmNyZHJlcmdyaHKncqlyq3KtcrBysXKycrNytHK2crhyuXK6crxyvXL8cv5zAHMCcwVzBnMHcwhzCXMLcw1zDnMPcxFzEnNdc4BzoHPAc8JzxHPGc8hzynPLc8xzz3PQc9Jz03PVc9dz2HPZc9xz3XPic+9z9HP2c/hz/XQAdAN0BXQqdE50dXSZdJx0nnSgdKJ0pHSmdKd0qnS3dMh0ynTMdM500HTSdNR01nTYdOl07HTvdPJ09XT4dPt0/nUBdQN1QnVEdUZ1SHVLdUx1TXVOdU91UXVTdVR1VXVXdVh1l3WZdZt1nXWgdaF1onWjdaR1pnWodal1qnWsda117HXudfF183X2dfd1+HX5dfp1/HX+df92AHYCdgN2EHYRdhJ2FHZTdlV2V3ZZdlx2XXZedl92YHZidmR2ZXZmdmh2aXaodqp2rHaudrF2snazdrR2tXa3drl2una7dr12vnb9dv93AXcDdwZ3B3cIdwl3CncMdw53D3cQdxJ3E3dSd1R3VndYd1t3XHddd153X3dhd2N3ZHdld2d3aHend6l3q3etd7B3sXeyd7N3tHe2d7h3uXe6d7x3vXfieAZ4LXhReFR4VnhYeFp4XHheeF94YnhveH54gHiCeIR4hniIeIp4jHibeJ54oXikeKd4qniteLB4snjxePN49Xj3ePp4+3j8eP14/nkAeQJ5A3kEeQZ5B3lGeUh5SnlMeU95UHlReVJ5U3lVeVd5WHlZeVt5XHmbeZ15n3mheaR5pXmmead5qHmqeax5rXmuebB5sXnwefJ59Hn2efl5+nn7efx5/Xn/egF6AnoDegV6BnpFekd6SXpLek56T3pQelF6UnpUelZ6V3pYelp6W3qaepx6nnqgeqN6pHqleqZ6p3qpeqt6rHqteq96sHrvevF683r1evh6+Xr6evt6/Hr+ewB7AXsCewR7BXtQe3N7k3uze7V7t3u5e7t7vXu+e797wnvDe8V7xnvIe8p7y3vMe8970HvZe+Z763vte+979Hv3e/p7/HwhfEV8bHyQfJN8lXyXfJl8m3ydfJ58oXyufL98wXzDfMV8x3zJfMt8zXzPfOB843zmfOl87HzvfPJ89Xz4fPp9OX07fT19P31CfUN9RH1FfUZ9SH1KfUt9TH1OfU99jn2QfZJ9lH2XfZh9mX2afZt9nX2ffaB9oX2jfaR9433lfeh96n3tfe59733wffF98331ffZ99335ffp+B34Mfg5+EH4Vfhd+Gn4cfil+Ln4wfjJ+N345fjt+PX58fn5+gH6CfoV+hn6Hfoh+iX6Lfo1+jn6PfpF+kn7RftN+1X7Xftp+237cft1+3n7gfuJ+437kfuZ+538mfyh/Kn8sfy9/MH8xfzJ/M381fzd/OH85fzt/PH97f31/f3+Bf4R/hX+Gf4d/iH+Kf4x/jX+Of5B/kX/Qf9J/1H/Wf9l/2n/bf9x/3X/ff+F/4n/jf+V/5oALgC+AVoB6gH2Af4CBgIOAhYCHgIiAi4CYgKeAqYCrgK2Ar4CxgLOAtYDEgMeAyoDNgNCA04DWgNmA24EagRyBHoEggSOBJIElgSaBJ4EpgSuBLIEtgS+BMIFvgXGBc4F1gXiBeYF6gXuBfIF+gYCBgYGCgYSBhYHEgcaByIHKgc2BzoHPgdCB0YHTgdWB1oHXgdmB2oIZghuCHYIfgiKCI4IkgiWCJoIogiqCK4Isgi6CL4JugnCCcoJ0gneCeIJ5gnqCe4J9gn+CgIKBgoOChILDgsWCx4LJgsyCzYLOgs+C0ILSgtSC1YLWgtiC2YMYgxqDHIMegyGDIoMjgySDJYMngymDKoMrgy2DLoN5g5yDvIPcg96D4IPig+SD5oPng+iD64Psg+6D74Pxg/OD9IP1g/iD+YP+hAuEEIQShBSEGYQchB+EIYRGhGqEkYS1hLiEuoS8hL6EwITChMOExoTThOSE5oTohOqE7ITuhPCE8oT0hQWFCIULhQ6FEYUUhReFGoUdhR+FXoVghWKFZIVnhWiFaYVqhWuFbYVvhXCFcYVzhXSFs4W1hbeFuYW8hb2FvoW/hcCFwoXEhcWFxoXIhcmGCIYKhg2GD4YShhOGFIYVhhaGGIYahhuGHIYehh+GLIYthi6GMIZvhnGGc4Z1hniGeYZ6hnuGfIZ+hoCGgYaChoSGhYbEhsaGyIbKhs2GzobPhtCG0YbThtWG1obXhtmG2ocZhxuHHYcfhyKHI4ckhyWHJocohyqHK4cshy6HL4duh3CHcod0h3eHeId5h3qHe4d9h3+HgIeBh4OHhIfDh8WHx4fJh8yHzYfOh8+H0IfSh9SH1YfWh9iH2Yf+iCKISYhtiHCIcoh0iHaIeIh6iHuIfoiLiJqInIieiKCIooikiKaIqIi3iLqIvYjAiMOIxojJiMyIzokNiQ+JEYkTiRaJF4kYiRmJGokciR6JH4kgiSKJI4liiWSJZoloiWuJbIltiW6Jb4lxiXOJdIl1iXeJeIm3ibmJu4m9icCJwYnCicOJxInGiciJyYnKicyJzYoMig6KEIoSihWKFooXihiKGYobih2KHoofiiGKIophimOKZYpnimqKa4psim2KbopwinKKc4p0inaKd4q2iriKuoq8ir+KwIrBisKKw4rFiseKyIrJisuKzIsLiw2LD4sRixSLFYsWixeLGIsaixyLHYseiyCLIYssizWLNos4i0GLTItbi2aLdIuJi52LtIvGi9OL1IvVi9eL5Ivli+aL6Iv1i/aL94v5jAKMEYwejC2MP4xTjGqMfIyFjIaMiIyVjJaMl4yZjKKMrIyzjL2MxYzXjNyM4QAAAAAAAAICAAAAAAAAFOsAAAAAAAAAAAAAAAAAAIzj + + + + + alias + + + + repl_name + + + + adminuser + + + + sshport + + + + servers + + + + sshhost + + + + usessl + + + + sshkeyfile + + + + defaultReadMode + + + + sshuser + + + + userepl + + + \ No newline at end of file diff --git a/Sources/Model/MHMongoHubMigration9to10.h b/Sources/Model/MHMongoHubMigration9to10.h new file mode 100644 index 00000000..55f19b69 --- /dev/null +++ b/Sources/Model/MHMongoHubMigration9to10.h @@ -0,0 +1,13 @@ +// +// MHMongoHubMigration9to10.h +// MongoHub +// +// Created by Jérôme Lebel on 25/08/2014. +// +// + +#import + +@interface MHMongoHubMigration9to10 : NSEntityMigrationPolicy + +@end diff --git a/Sources/Model/MHMongoHubMigration9to10.m b/Sources/Model/MHMongoHubMigration9to10.m new file mode 100644 index 00000000..68d70e16 --- /dev/null +++ b/Sources/Model/MHMongoHubMigration9to10.m @@ -0,0 +1,45 @@ +// +// MHMongoHubMigration9to10.m +// MongoHub +// +// Created by Jérôme Lebel on 25/08/2014. +// +// + +#import "MHMongoHubMigration9to10.h" + +@implementation MHMongoHubMigration9to10 + +- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sourceInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError *__autoreleasing *)error +{ + NSManagedObjectContext *destMOC = manager.destinationContext; + NSManagedObject *newConnection; + NSDictionary *convertKeys = @{ @"adminuser": @"adminUser", + @"defaultdb": @"defaultDatabase", + @"repl_name": @"replicaSetName", + @"sshhost": @"sshHost", + @"sshport": @"sshPort", + @"sshuser": @"sshUser", + @"usessl": @"useSSL", + @"usessh": @"useSSH", + @"sshkeyfile": @"sshKeyFileName" }; + + newConnection = [NSEntityDescription insertNewObjectForEntityForName:@"Connection" inManagedObjectContext:destMOC]; + NSArray *keys = sourceInstance.entity.attributesByName.allKeys; + NSMutableDictionary *values = [[sourceInstance dictionaryWithValuesForKeys:keys] mutableCopy]; + + for (NSString *key in convertKeys.allKeys) { + if (values[key]) { + values[convertKeys[key]] = values[key]; + [values removeObjectForKey:key]; + } + } + [values removeObjectForKey:@"bindport"]; + [values removeObjectForKey:@"bindaddress"]; + [newConnection setValuesForKeysWithDictionary:values]; + [manager associateSourceInstance:sourceInstance withDestinationInstance:newConnection forEntityMapping:mapping]; + [values release]; + return YES; +} + +@end diff --git a/Sources/Model/MHMongoHubMigration9to10.xcmappingmodel/xcmapping.xml b/Sources/Model/MHMongoHubMigration9to10.xcmappingmodel/xcmapping.xml new file mode 100644 index 00000000..b066a6c6 --- /dev/null +++ b/Sources/Model/MHMongoHubMigration9to10.xcmappingmodel/xcmapping.xml @@ -0,0 +1,121 @@ + + + + + + 134481920 + F9E34390-D985-43E8-956D-9AEC210AC041 + 116 + + + + NSPersistenceFrameworkVersion + 481 + NSStoreModelVersionHashes + + XDDevAttributeMapping + + 0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc= + + XDDevEntityMapping + + qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI= + + XDDevMappingModel + + EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ= + + XDDevPropertyMapping + + XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA= + + XDDevRelationshipMapping + + akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs= + + + NSStoreModelVersionHashesVersion + 3 + NSStoreModelVersionIdentifiers + + + + + + + + + weakCertificate + + + + alias + + + + useSSH + + + + servers + + + + sshUser + + + + defaultReadMode + + + + Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel + YnBsaXN0MDDUAAEAAgADAAQABQAGE6MTpFgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv +cBIAAYagrxEBqgAHAAgAFwAYADQANQA2AD4APwBaAFsAXABiAGMAbwCDAIQAhQCGAIcAiACJAIoAiwCkAK0AvADLANoA3QDhAFkA8QEAAQYBBwEIAQwBGwEhASIBKgE5AToBQwFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQGGAYcBjwGQAZEBnQGxAbIBswG0AbUBtgG3AbgBuQHIAdcB5gHuAe8B9wH4AfkB+gH7AgoCGQIaAikCOAJHAlMCZQJmAmcCaAJpAmoCawJsAnsCigKZAqgCqQK4AscC1gLeAvMC9AL8AwgDHAMrAzoDSQNRA1kDaAN3A4YDlQOkA7ADwgPRA9ID4QPwA/8EAAQPBB4ELQRCBEMESwRXBGsEegSJBJgEnASrBLoEyQTYBOcE8wUFBRQFIwUyBUEFQgVRBWAFbwWEBYUFjQWZBa0FvAXLBdoF3gXtBfwGCwYaBikGNQZHBlYGZQZ0BoMGkgahBrAGxQbGBs4G2gbuBv0HDAcbByMHKwc6B0kHWAdnB3YHggeUB6MHsgfBB9AH3wfuB/0IEggTCBsIJwg7CEoIWQhoCGwIewiKCJkIqAi3CMMI1QjkCPMJAgkRCSAJLwk+CVMJVAlcCWgJfAmLCZoJqQmtCbwJywnaCekJ+AoEChYKJQo0CkMKUgphCnAKfwqUCpUKnQqpCr0KzArbCuoK8gr6CwkLGAsnCzYLRQtRC2MLcguBC5ALnwuuC70LzAvhC+IL6gv2DAoMGQwoDDcMOwxKDFkMaAx3DIYMkgykDLMMwgzRDOAM7wz+DQ0NIg0jDSsNNw1LDVoNaQ14DXwNiw2aDakNuA3HDdMN5Q30DgMOEg4hDjAOPw5ODmMOZA5sDngOjA6bDqoOuQ7BDskO2A7nDvYPBQ8UDyAPMg9BD1APXw9uD30PjA+bD7APsQ+5D8UP2Q/oD/cQBhAOEBYQJRA0EEMQUhBhEG0QfxCOEJ0QrBC7EMoQ2RDoEP0Q/hEGERIRJhE1EUQRUxFXEWYRdRGEEZMRohGuEcARzxHeEe0R/BILEhoSKRI+Ej8SRxJTEmcSdhKFEpQSnBKkErMSwhLREuAS7xL7Ew0THBMrEzoTSRNYE2cTdhN3E3oTgxOHE4sTjxOXE5oTnlUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAFQATXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoADgQGpgQGngACBAaiAAoAAXxAUdW50aXRsZWQueGNkYXRhbW9kZWzeABkAGgAbABwAHQAeAB8ACgAgACEAIgAjACQAJQAmACcAKAApACYAEwAsAC0ALgAvADAAJgAmABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgAWBAaWBAaOAAYAFgACBAaSBAaYQAIAGgASABYAFgABQU1lFU9MANwA4AAoAOQA7AD1XTlMua2V5c1pOUy5vYmplY3RzoQA6gAehADyACIAkWkNvbm5lY3Rpb27fEBAAQABBAEIAQwAeAEQARQAgAEYARwAKACIASABJACUASgBLAEwAJgAmABAAUABRAC4AJgBLAFQAOgBLAFcAWABZXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAqALIAFgAWAA4ALgQGggAWACoEBooAHgAqBAaGACQgSEYXAg1dvcmRlcmVk0wA3ADgACgBdAF8APaEAXoAMoQBggA2AJF5YRF9QU3RlcmVvdHlwZdkAHgAiAGQACgAlAGUAIABKAGYAPABeAEsAagATACYALgBZAG5fECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WACIAMgAqAK4AAgAUIgA7TADcAOAAKAHAAeQA9qABxAHIAcwB0AHUAdgB3AHiAD4AQgBGAEoATgBSAFYAWqAB6AHsAfAB9AH4AfwCAAIGAF4AZgBqAG4AegCCAJYApgCRfEBNYRFBNQ29tcG91bmRJbmRleGVzXxAQWERfUFNLX2VsZW1lbnRJRF8QGlhEX1BTS192ZXJzaW9uSGFzaE1vZGlmaWVyXxAZWERfUFNLX2ZldGNoUmVxdWVzdHNBcnJheV8QEVhEX1BTS19pc0Fic3RyYWN0XxAPWERfUFNLX3VzZXJJbmZvXxATWERfUFNLX2NsYXNzTWFwcGluZ18QFlhEX1BTS19lbnRpdHlDbGFzc05hbWXfEA8AjACNAI4AHgCPAJAAkQAgAJIACgAiAJMAlAAlAJUAEwATABMAYABZAFkAWQAuAFkAngBxAFkAWQATAFlVX3R5cGVYX2RlZmF1bHRcX2Fzc29jaWF0aW9uW19pc1JlYWRPbmx5WV9pc1N0YXRpY1lfaXNVbmlxdWVaX2lzRGVyaXZlZFpfaXNPcmRlcmVkXF9pc0NvbXBvc2l0ZVdfaXNMZWFmgACAAIAAgA0ICAgIgBiADwgIgAAI0gClAKYApwCoWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBYRFVNTFByb3BlcnR5SW1wpACpAKoAqwCsXxAQWERVTUxQcm9wZXJ0eUltcF8QFFhEVU1MTmFtZWRFbGVtZW50SW1wXxAPWERVTUxFbGVtZW50SW1wWE5TT2JqZWN03xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMAEwATAGAAWQBZAFkALgBZAJ4AcgBZAFkAEwBZgACAAIAAgA0ICAgIgBiAEAgIgAAI3xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMAEwATAGAAWQBZAFkALgBZAJ4AcwBZAFkAEwBZgACAAIAAgA0ICAgIgBiAEQgIgAAI3xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMAzQATAGAAWQBZAFkALgBZAJ4AdABZAFkAEwBZgACAHIAAgA0ICAgIgBiAEggIgAAI0gA4AAoA2wDcoIAd0gClAKYA3gDfXk5TTXV0YWJsZUFycmF5owDeAOAArFdOU0FycmF53xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMA4wATAGAAWQBZAFkALgBZAJ4AdQBZAFkAEwBZgACAH4AAgA0ICAgIgBiAEwgIgAAICN8QDwCMAI0AjgAeAI8AkACRACAAkgAKACIAkwCUACUAlQATAPMAEwBgAFkAWQBZAC4AWQCeAHYAWQBZABMAWYAAgCGAAIANCAgICIAYgBQICIAACNMANwA4AAoBAQEDAD2hAQKAIqEBBIAjgCRfEDFjb20uYXBwbGUuc3luY3NlcnZpY2VzLkV4Y2x1ZGVGcm9tRGF0YUNoYW5nZUFsZXJ0Uk5P0gClAKYBCQEKXxATTlNNdXRhYmxlRGljdGlvbmFyeaMBCQELAKxcTlNEaWN0aW9uYXJ53xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMBDgATAGAAWQBZAFkALgBZAJ4AdwBZAFkAEwBZgACAJoAAgA0ICAgIgBiAFQgIgAAI1gAiAAoAJQBKAB4AIAEcAR0AEwBZABMALoAngCiAAAiAAF8QFFhER2VuZXJpY1JlY29yZENsYXNz0gClAKYBIwEkXVhEVU1MQ2xhc3NJbXCmASUBJgEnASgBKQCsXVhEVU1MQ2xhc3NJbXBfEBJYRFVNTENsYXNzaWZpZXJJbXBfEBFYRFVNTE5hbWVzcGFjZUltcF8QFFhEVU1MTmFtZWRFbGVtZW50SW1wXxAPWERVTUxFbGVtZW50SW1w3xAPAIwAjQCOAB4AjwCQAJEAIACSAAoAIgCTAJQAJQCVABMBLAATAGAAWQBZAFkALgBZAJ4AeABZAFkAEwBZgACAKoAAgA0ICAgIgBiAFggIgAAIXxARTUhDb25uZWN0aW9uU3RvcmXSAKUApgE7ATxfEBJYRFVNTFN0ZXJlb3R5cGVJbXCnAT0BPgE/AUABQQFCAKxfEBJYRFVNTFN0ZXJlb3R5cGVJbXBdWERVTUxDbGFzc0ltcF8QElhEVU1MQ2xhc3NpZmllckltcF8QEVhEVU1MTmFtZXNwYWNlSW1wXxAUWERVTUxOYW1lZEVsZW1lbnRJbXBfEA9YRFVNTEVsZW1lbnRJbXDTADcAOAAKAUQBUwA9rgFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVKALYAugC+AMIAxgDKAM4A0gDWANoA3gDiAOYA6rgFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWGAO4BsgIaAnoC1gM2A5ID7gQETgQEqgQFBgQFZgQFxgQGIgCRZZGVmYXVsdGRiV3NzaHBvcnRWdXNlc3NsWWFkbWludXNlclpzc2hrZXlmaWxlWGJpbmRwb3J0W2JpbmRhZGRyZXNzVWFsaWFzWXJlcGxfbmFtZVdzZXJ2ZXJzV3NzaGhvc3RWdXNlc3NoXxAPZGVmYXVsdFJlYWRNb2RlV3NzaHVzZXLfEBIAjACNAI4BcgAeAJAAkQFzACAAjwF0AJIACgAiAJMAlAAlAJUAEwATABMAJgA8AFkAWQF8AC4AWQBLAFkBgAFFAFkAWQGEAFlfECBYREJ1Y2tldEZvclN0ZXJlb3R5cGVzd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNzdG9yYWdlXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc29yZGVyZWSAAIAAgACABYAICAiAPQiACgiAa4AtCAiAPAgT/////8KHxrXTADcAOAAKAYgBiwA9ogGJAYqAPoA/ogGMAY2AQIBagCRfEBJYRF9QUHJvcFN0ZXJlb3R5cGVfEBJYRF9QQXR0X1N0ZXJlb3R5cGXZAB4AIgGSAAoAJQGTACAASgGUAVQBiQB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XbhdwF3IXdBd2F3gXehd8F4sXjRePF5EXkxeVF5cXmRebF7sX5hgAGBkYMxhTGHYYtRi3GLkYuxi9GL4YvxjAGMEYwxjFGMYYxxjJGMoZCRkLGQ0ZDxkRGRIZExkUGRUZFxkZGRoZGxkdGR4ZXRlfGWEZYxllGWYZZxloGWkZaxltGW4ZbxlxGXIZsRmzGbUZtxm5GboZuxm8Gb0ZvxnBGcIZwxnFGcYZyRoIGgoaDBoOGhAaERoSGhMaFBoWGhgaGRoaGhwaHRpcGl4aYBpiGmQaZRpmGmcaaBpqGmwabRpuGnAacRqwGrIatBq2GrgauRq6GrsavBq+GsAawRrCGsQaxRrOGtwa6Rr3GwQbFxsuG0AbixuuG84b7hvwG/Ib9Bv2G/gb+Rv6G/wb/Rv/HAAcAhwEHAUcBhwIHAkcEhwfHCQcJhwoHC0cLxwxHDMcWBx8HKMcxxzJHMsczRzPHNEc0xzUHNYc4xz0HPYc+Bz6HPwc/h0AHQIdBB0VHRcdGR0bHR0dHx0hHSMdJR0nHWYdaB1qHWwdbh1vHXAdcR1yHXQddh13HXgdeh17HbodvB2+HcAdwh3DHcQdxR3GHcgdyh3LHcwdzh3PHg4eEB4SHhQeFh4XHhgeGR4aHhweHh4fHiAeIh4jHjAeNR43HjkePh5AHkIeRB5RHlYeWB5aHl8eYR5jHmUepB6mHqgeqh6sHq0erh6vHrAesh60HrUeth64Hrke+B76Hvwe/h8AHwEfAh8DHwQfBh8IHwkfCh8MHw0fTB9OH1AfUh9UH1UfVh9XH1gfWh9cH10fXh9gH2EfoB+iH6Qfph+oH6kfqh+rH6wfrh+wH7Efsh+0H7Uf9B/2H/gf+h/8H/0f/h//IAAgAiAEIAUgBiAIIAkgLiBSIHkgnSCfIKEgoyClIKcgqSCqIKwguSDIIMogzCDOINAg0iDUINYg5SDnIOkg6yDtIO8g8SDzIPUhNCE2ITghOiE8IT0hPiE/IUAhQiFEIUUhRiFIIUkhSyGKIYwhjiGQIZIhkyGUIZUhliGYIZohmyGcIZ4hnyHeIeAh4iHkIeYh5yHoIekh6iHsIe4h7yHwIfIh8yIyIjQiNiI4IjoiOyI8Ij0iPiJAIkIiQyJEIkYiRyJJIogiiiKMIo4ikCKRIpIikyKUIpYimCKZIpoinCKdItwi3iLgIuIi5CLlIuY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Onk6fTqBOok6kTqVOpk6oTqlO6E7qTuxO7k7wTvFO8k7zTvRO9k74TvlO+k78Tv1PPE8+T0BPQk9ET0VPRk9HT0hPSk9MT01PTk9QT1FPdk+aT8FP5U/nT+lP60/tT+9P8U/yT/VQAlARUBNQFVAXUBlQG1AdUB9QLlAxUDRQN1A6UD1QQFBDUEVQhFCGUIhQilCNUI5Qj1CQUJFQk1CVUJZQl1CZUJpQ2VDbUN1Q31DiUONQ5FDlUOZQ6FDqUOtQ7FDuUO9RLlEwUTJRNFE3UThROVE6UTtRPVE/UUBRQVFDUURRg1GFUYdRiVGMUY1RjlGPUZBRklGUUZVRllGYUZlR2FHaUdxR3lHhUeJR41HkUeVR51HpUepR61HtUe5SLVIvUjFSM1I2UjdSOFI5UjpSPFI+Uj9SQFJCUkNSglKEUoZSiFKLUoxSjVKOUo9SkVKTUpRSlVKXUphS41MGUyZTRlNIU0pTTFNOU1BTUVNSU1VTVlNYU1lTW1NdU15TX1NiU2NTaFN1U3pTfFN+U4NThlOJU4tTsFPUU/tUH1QiVCRUJlQoVCpULFQtVDBUPVROVFBUUlRUVFZUWFRaVFxUXlRvVHJUdVR4VHtUflSBVIRUh1SJVMhUylTMVM5U0VTSVNNU1FTVVNdU2VTaVNtU3VTeVR1VH1UhVSNVJlUnVShVKVUqVSxVLlUvVTBVMlUzVXJVdFV3VXlVfFV9VX5Vf1WAVYJVhFWFVYZViFWJVZZVl1WYVZpV2VXbVd1V31XiVeNV5FXlVeZV6FXqVetV7FXuVe9WLlYwVjJWNFY3VjhWOVY6VjtWPVY/VkBWQVZDVkRWg1aFVodWiVaMVo1WjlaPVpBWklaUVpVWllaYVplW2FbaVtxW3lbhVuJW41bkVuVW51bpVupW61btVu5XLVcvVzFXM1c2VzdXOFc5VzpXPFc+Vz9XQFdCV0NXaFeMV7NX11faV9xX3lfgV+JX5FflV+hX9VgEWAZYCFgKWAxYDlgQWBJYIVgkWCdYKlgtWDBYM1g2WDhYd1h5WHtYfViAWIFYgliDWIRYhliIWIlYiliMWI1YzFjOWNBY0ljVWNZY11jYWNlY21jdWN5Y31jhWOJZIVkjWSVZJ1kqWStZLFktWS5ZMFkyWTNZNFk2WTdZdll4WXpZfFl/WYBZgVmCWYNZhVmHWYhZiVmLWYxZy1nNWc9Z0VnUWdVZ1lnXWdhZ2lncWd1Z3lngWeFaIFoiWiRaJlopWipaK1osWi1aL1oxWjJaM1o1WjZadVp3Wnlae1p+Wn9agFqBWoJahFqGWodaiFqKWota1lr5WxlbOVs7Wz1bP1tBW0NbRFtFW0hbSVtLW0xbTltQW1FbUltVW1ZbW1toW21bb1txW3ZbeVt8W35bo1vHW+5cElwVXBdcGVwbXB1cH1wgXCNcMFxBXENcRVxHXElcS1xNXE9cUVxiXGVcaFxrXG5ccVx0XHdcelx8XLtcvVy/XMFcxFzFXMZcx1zIXMpczFzNXM5c0FzRXRBdEl0UXRZdGV0aXRtdHF0dXR9dIV0iXSNdJV0mXWVdZ11qXWxdb11wXXFdcl1zXXVdd114XXlde118XYldil2LXY1dzF3OXdBd0l3VXdZd113YXdld213dXd5d313hXeJeIV4jXiVeJ14qXiteLF4tXi5eMF4yXjNeNF42Xjdedl54XnpefF5/XoBegV6CXoNehV6HXoheiV6LXoxey17NXs9e0V7UXtVe1l7XXthe2l7cXt1e3l7gXuFfIF8iXyRfJl8pXypfK18sXy1fL18xXzJfM181XzZfW19/X6Zfyl/NX89f0V/TX9Vf11/YX9tf6F/3X/lf+1/9X/9gAWADYAVgFGAXYBpgHWAgYCNgJmApYCtgamBsYG5gcGBzYHRgdWB2YHdgeWB7YHxgfWB/YIBgv2DBYMNgxWDIYMlgymDLYMxgzmDQYNFg0mDUYNVhFGEWYRhhGmEdYR5hH2EgYSFhI2ElYSZhJ2EpYSphaWFrYW1hb2FyYXNhdGF1YXZheGF6YXthfGF+YX9hvmHAYcJhxGHHYchhyWHKYcthzWHPYdBh0WHTYdRiE2IVYhdiGWIcYh1iHmIfYiBiImIkYiViJmIoYiliaGJqYmxibmJxYnJic2J0YnVid2J5Ynpie2J9Yn5iyWLsYwxjLGMuYzBjMmM0YzZjN2M4YztjPGM+Yz9jQWNDY0RjRWNIY0ljTmNbY2BjYmNkY2ljbGNvY3FjlmO6Y+FkBWQIZApkDGQOZBBkEmQTZBZkI2Q0ZDZkOGQ6ZDxkPmRAZEJkRGRVZFhkW2ReZGFkZGRnZGpkbWRvZK5ksGSyZLRkt2S4ZLlkumS7ZL1kv2TAZMFkw2TEZQNlBWUHZQllDGUNZQ5lD2UQZRJlFGUVZRZlGGUZZVhlWmVdZV9lYmVjZWRlZWVmZWhlamVrZWxlbmVvZXxlgWWDZYVlimWMZY9lkWWeZaNlpWWnZaxlrmWwZbJl8WXzZfVl92X6Zftl/GX9Zf5mAGYCZgNmBGYGZgdmRmZIZkpmTGZPZlBmUWZSZlNmVWZXZlhmWWZbZlxmm2adZp9moWakZqVmpmanZqhmqmasZq1mrmawZrFm8GbyZvRm9mb5Zvpm+2b8Zv1m/2cBZwJnA2cFZwZnRWdHZ0lnS2dOZ09nUGdRZ1JnVGdWZ1dnWGdaZ1tngGekZ8tn72fyZ/Rn9mf4Z/pn/Gf9aABoDWgcaB5oIGgiaCRoJmgoaCpoOWg8aD9oQmhFaEhoS2hOaFBoj2iRaJNolWiYaJlommibaJxonmigaKFoomikaKVo5GjmaOho6mjtaO5o72jwaPFo82j1aPZo92j5aPppOWk7aT1pP2lCaUNpRGlFaUZpSGlKaUtpTGlOaU9pjmmQaZJplGmXaZhpmWmaaZtpnWmfaaBpoWmjaaRp42nlaedp6Wnsae1p7mnvafBp8mn0afVp9mn4aflqOGo6ajxqPmpBakJqQ2pEakVqR2pJakpqS2pNak5qjWqPapFqk2qWapdqmGqZappqnGqeap9qoGqiaqNq7msRazFrUWtTa1VrV2tZa1trXGtda2BrYWtja2RrZmtoa2lramtta25rd2uEa4lri2uNa5JrlWuYa5prv2vjbApsLmwxbDNsNWw3bDlsO2w8bD9sTGxdbF9sYWxjbGVsZ2xpbGtsbWx+bIFshGyHbIpsjWyQbJNslmyYbNds2WzbbN1s4GzhbOJs42zkbOZs6GzpbOps7GztbSxtLm0wbTJtNW02bTdtOG05bTttPW0+bT9tQW1CbYFtg22GbYhti22MbY1tjm2PbZFtk22UbZVtl22YbaVtqm2sba5ts221bbhtum3Hbcxtzm3QbdVt123ZbdtuGm4cbh5uIG4jbiRuJW4mbiduKW4rbixuLW4vbjBub25xbnNudW54bnluem57bnxufm6AboFugm6EboVuxG7Gbshuym7Nbs5uz27QbtFu027VbtZu127ZbtpvGW8bbx1vH28ibyNvJG8lbyZvKG8qbytvLG8uby9vbm9wb3JvdG93b3hveW96b3tvfW9/b4BvgW+Db4RvqW/Nb/RwGHAbcB1wH3AhcCNwJXAmcClwNnBFcEdwSXBLcE1wT3BRcFNwYnBlcGhwa3BucHFwdHB3cHlwuHC6cLxwvnDBcMJww3DEcMVwx3DJcMpwy3DNcM5xDXEPcRFxE3EWcRdxGHEZcRpxHHEecR9xIHEicSNxYnFkcWZxaHFrcWxxbXFucW9xcXFzcXRxdXF3cXhxt3G5cbtxvXHAccFxwnHDccRxxnHIcclxynHMcc1yDHIOchByEnIVchZyF3IYchlyG3Idch5yH3IhciJyYXJjcmVyZ3JqcmtybHJtcm5ycHJycnNydHJ2cndytnK4crpyvHK/csBywXLCcsNyxXLHcshyyXLLcsxzF3M6c1pzenN8c35zgHOCc4RzhXOGc4lzinOMc41zj3ORc5Jzk3OWc5dznHOpc65zsHOyc7dzunO9c79z5HQIdC90U3RWdFh0WnRcdF50YHRhdGR0cXSCdIR0hnSIdIp0jHSOdJB0knSjdKZ0qXSsdK90snS1dLh0u3S9dPx0/nUAdQJ1BXUGdQd1CHUJdQt1DXUOdQ91EXUSdVF1U3VVdVd1WnVbdVx1XXVedWB1YnVjdWR1ZnVndaZ1qHWrda11sHWxdbJ1s3W0dbZ1uHW5dbp1vHW9dcp1y3XMdc52DXYPdhF2E3YWdhd2GHYZdhp2HHYedh92IHYidiN2YnZkdmZ2aHZrdmx2bXZudm92cXZzdnR2dXZ3dnh2t3a5drt2vXbAdsF2wnbDdsR2xnbIdsl2ynbMds13DHcOdxB3EncVdxZ3F3cYdxl3G3cddx53H3chdyJ3YXdjd2V3Z3dqd2t3bHdtd253cHdyd3N3dHd2d3d3nHfAd+d4C3gOeBB4EngUeBZ4GHgZeBx4KXg4eDp4PHg+eEB4QnhEeEZ4VXhYeFt4XnhheGR4Z3hqeGx4q3iteK94sXi0eLV4tni3eLh4uni8eL14vnjAeMF5AHkCeQR5BnkJeQp5C3kMeQ15D3kReRJ5E3kVeRZ5VXlXeVl5W3leeV95YHlheWJ5ZHlmeWd5aHlqeWt5qnmsea55sHmzebR5tXm2ebd5uXm7ebx5vXm/ecB5/3oBegN6BXoIegl6CnoLegx6DnoQehF6EnoUehV6VHpWelh6Wnpdel56X3pgemF6Y3plemZ6Z3ppemp6qXqreq16r3qyerN6tHq1erZ6uHq6ert6vHq+er97Cnste017bXtve3F7c3t1e3d7eHt5e3x7fXt/e4B7gnuEe4V7hnuJe4p7k3uge6V7p3upe657sXu0e7Z723v/fCZ8SnxNfE98UXxTfFV8V3xYfFt8aHx5fHt8fXx/fIF8g3yFfId8iXyafJ18oHyjfKZ8qXysfK98sny0fPN89Xz3fPl8/Hz9fP58/30AfQJ9BH0FfQZ9CH0JfUh9Sn1MfU59UX1SfVN9VH1VfVd9WX1afVt9XX1efZ19n32ifaR9p32ofal9qn2rfa19r32wfbF9s320fcF9xn3Ifcp9z33RfdR91n3jfeh96n3sffF98331ffd+Nn44fjp+PH4/fkB+QX5CfkN+RX5Hfkh+SX5Lfkx+i36Nfo9+kX6UfpV+ln6Xfph+mn6cfp1+nn6gfqF+4H7ifuR+5n7pfup+637sfu1+737xfvJ+8371fvZ/NX83fzl/O38+fz9/QH9Bf0J/RH9Gf0d/SH9Kf0t/in+Mf45/kH+Tf5R/lX+Wf5d/mX+bf5x/nX+ff6B/xX/pgBCANIA3gDmAO4A9gD+AQYBCgEWAUoBhgGOAZYBngGmAa4BtgG+AfoCBgISAh4CKgI2AkICTgJWA1IDWgNiA2oDdgN6A34DggOGA44DlgOaA54DpgOqBKYErgS2BL4EygTOBNIE1gTaBOIE6gTuBPIE+gT+BfoGAgYKBhIGHgYiBiYGKgYuBjYGPgZCBkYGTgZSB04HVgdeB2YHcgd2B3oHfgeCB4oHkgeWB5oHogemCKIIqgiyCLoIxgjKCM4I0gjWCN4I5gjqCO4I9gj6CfYJ/goGCg4KGgoeCiIKJgoqCjIKOgo+CkIKSgpOC0oLUgtaC2ILbgtyC3YLegt+C4YLjguSC5YLnguiC84L8gv2C/4MIgxODIoMtgzuDUINkg3uDjYOag5uDnIOeg6uDrIOtg6+DvIO9g76DwIPJg9iD5YP0hAaEGoQxhEOETIRNhE+EXIRdhF6EYIRphHOEeoSEhIyEnoSjhKgAAAAAAAACAgAAAAAAABOnAAAAAAAAAAAAAAAAAACEqg== + + Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel + YnBsaXN0MDDUAAEAAgADAAQABQAGEl8SYFgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv +cBIAAYagrxEBkgAHAAgAFwAYADQANQA2AD4APwBaAFsAXABiAGMAbwCDAIQAhQCGAIcAiACJAIoAiwCkAK0AvADLANoA3QDhAFkA8QEAAQYBBwEIAQwBGwEhASIBKgE5AToBQwFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BgwGEAYwBjQGOAZoBrgGvAbABsQGyAbMBtAG1AbYBxQHUAeMB5wH2AgUCBgIVAiQCMwI/AlECUgJTAlQCVQJWAlcCWAJnAnYChQKUApUCpAKzAsICygLfAuAC6AL0AwgDFwMmAzUDPQM+A0YDRwNIA0kDSgNZA2gDdwOGA5UDoQOzA8ID0QPgA+8D8AP/BA4EHQQyBDMEOwRHBFsEagR5BIgEjASbBKoEuQTIBNcE4wT1BQQFEwUiBTEFQAVPBV4FcwV0BXwFiAWcBasFugXJBdEF2QXoBfcGBgYVBiQGMAZCBlEGYAZvBn4GjQacBqsGwAbBBskG1QbpBvgHBwcWBx4HJgc1B0QHUwdiB3EHfQePB54HrQe8B8sH2gfpB/gIDQgOCBYIIgg2CEUIVAhjCGsIcwiCCJEIoAivCL4IygjcCOsI7Aj7CQoJGQkaCSkJOAlHCVwJXQllCXEJhQmUCaMJsgm6CcIJ0QngCe8J/goNChkKKwo6CkkKWApnCnYKhQqUCqkKqgqyCr4K0grhCvAK/wsHCw8LHgstCzwLSwtaC2YLeAuHC5YLpQu0C8ML0gvhC/YL9wv/DAsMHwwuDD0MTAxQDF8Mbgx9DIwMmwynDLkMyAzXDOYM9Q0EDRMNIg03DTgNQA1MDWANbw1+DY0NlQ2dDawNuw3KDdkN6A30DgYOFQ4kDjMOQg5RDmAObw6EDoUOjQ6ZDq0OvA7LDtoO3g7tDvwPCw8aDykPNQ9HD1YPZQ90D4MPkg+hD7APxQ/GD84P2g/uD/0QDBAbEB8QLhA9EEwQWxBqEHYQiBCXEKYQtRDEENMQ4hDxEQYRBxEPERsRLxE+EU0RXBFgEW8RfhGNEZwRqxG3EckR2BHnEfYSBRIUEiMSMhIzEjYSPxJDEkcSSxJTElYSWlUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAFQATXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoADgQGRgQGPgACBAZCAAoAAXxAUdW50aXRsZWQueGNkYXRhbW9kZWzeABkAGgAbABwAHQAeAB8ACgAgACEAIgAjACQAJQAmACcAKAApACYAEwAsAC0ALgAvADAAJgAmABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgAWBAY2BAYuAAYAFgACBAYyBAY4QAIAGgASABYAFgABQU1lFU9MANwA4AAoAOQA7AD1XTlMua2V5c1pOUy5vYmplY3RzoQA6gAehADyACIAkWkNvbm5lY3Rpb27fEBAAQABBAEIAQwAeAEQARQAgAEYARwAKACIASABJACUASgBLAEwAJgAmABAAUABRAC4AJgBLAFQAOgBLAFcAWABZXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAqALIAFgAWAA4ALgQGIgAWACoEBioAHgAqBAYmACQgSEYXAg1dvcmRlcmVk0wA3ADgACgBdAF8APaEAXoAMoQBggA2AJF5YRF9QU3RlcmVvdHlwZdkAHgAiAGQACgAlAGUAIABKAGYAPABeAEsAagATACYALgBZAG5fECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WACIAMgAqAK4AAgAUIgA7TADcAOAAKAHAAeQA9qABxAHIAcwB0AHUAdgB3AHiAD4AQgBGAEoATgBSAFYAWqAB6AHsAfAB9AH4AfwCAAIGAF4AZgBqAG4AegCCAJYApgCRfEBNYRFBNQ29tcG91bmRJbmRleGVzXxAQWERfUFNLX2VsZW1lbnRJRF8QGlhEX1BTS192ZXJzaW9uSGFzaE1vZGlmaWVyXxAZWERfUFNLX2ZldGNoUmVxdWVzdHNBcnJheV8QEVhEX1BTS19pc0Fic3RyYWN0XxAPWERfUFNLX3VzZXJJbmZvXxATWERfUFNLX2NsYXNzTWFwcGluZ18QFlhEX1BTS19lbnRpdHlDbGFzc05hbWXfEA8AjACNAI4AHgCPAJAAkQAgAJIACgAiAJMAlAAlAJUAEwATABMAYABZAFkAWQAuAFkAngBxAFkAWQATAFlVX3R5cGVYX2RlZmF1bHRcX2Fzc29jaWF0aW9uW19pc1JlYWRPbmx5WV9pc1N0YXRpY1lfaXNVbmlxdWVaX2lzRGVyaXZlZFpfaXNPcmRlcmVkXF9pc0NvbXBvc2l0ZVdfaXNMZWFmgACAAIAAgA0ICAgIgBiADwgIgAAI0gClAKYApwCoWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBYRFVNTFByb3BlcnR5SW1wpACpAKoAqwCsXxAQWERVTUxQcm9wZXJ0eUltcF8QFFhEVU1MTmFtZWRFbGV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NG1obXxthG2MbaBtqG2wbbhuTG7cb3hwCHAQcBhwIHAocDBwOHA8cERweHC8cMRwzHDUcNxw5HDscPRw/HFAcUhxUHFYcWBxaHFwcXhxgHGIcoRyjHKUcpxypHKocqxysHK0crxyxHLIcsxy1HLYc9Rz3HPkc+xz9HP4c/x0AHQEdAx0FHQYdBx0JHQodSR1LHU0dTx1RHVIdUx1UHVUdVx1ZHVodWx1dHV4dax1wHXIddB15HXsdfR1/HbIdvx3EHcYdyB3NHc8d0R3THekd+x3/HgUeRB5GHkgeSh5MHk0eTh5PHlAeUh5UHlUeVh5YHlkemB6aHpwenh6gHqEeoh6jHqQeph6oHqkeqh6sHq0e7B7uHvAe8h70HvUe9h73Hvge+h78Hv0e/h8AHwEfQB9CH0QfRh9IH0kfSh9LH0wfTh9QH1EfUh9UH1UflB+WH5gfmh+cH50fnh+fH6Afoh+kH6Ufph+oH6kfzh/yIBkgPSA/IEEgQyBFIEcgSSBKIEwgWSBoIGogbCBuIHAgciB0IHYghSCHIIkgiyCNII8gkSCTIJUg1CDWINgg2iDcIN0g3iDfIOAg4iDkIOUg5iDoIOkhKCEqISwhLiEwITEhMiEzITQhNiE4ITkhOiE8IT0hfCF+IYAhgiGEIYUhhiGHIYghiiGMIY0hjiGQIZEh0CHSIdQh1iHYIdkh2iHbIdwh3iHgIeEh4iHkIeUh6CInIikiKyItIi8iMCIxIjIiMyI1IjciOCI5IjsiPCJ7In0ifyKBIoMihCKFIoYihyKJIosijCKNIo8ikCLPItEi0yLVItci2CLZItoi2yLdIt8i4CLhIuMi5CMvI1IjciOSI5QjliOYI5ojnCOdI54joCOhI6MjpCOmI6gjqSOqI6wjrSOyI78jxCPGI8gjzSPPI9Ej0yP4JBwkQyRnJGkkayRtJG8kcSRzJHQkdiSDJJQkliSYJJoknCSeJKAkoiSkJLUktyS5JLskvSS/JMEkwyTFJMclBiUIJQolDCUOJQ8lECURJRIlFCUWJRclGCUaJRslWiVcJV4lYCViJWMlZCVlJWYlaCVqJWslbCVuJW8lriWwJbIltCW2JbcluCW5JbolvCW+Jb8lwCXCJcMl0CXRJdIl1CYTJhUmFyYZJhsmHCYdJh4mHyYhJiMmJCYlJicmKCZnJmkmayZtJm8mcCZxJnImcyZ1JncmeCZ5JnsmfCa7Jr0mvybBJsMmxCbFJsYmxybJJssmzCbNJs8m0CcPJxEnEycVJxcnGCcZJxonGycdJx8nICchJyMnJCdjJ2UnZydpJ2snbCdtJ24nbydxJ3MndCd1J3cneCedJ8En6CgMKA4oECgSKBQoFigYKBkoGygoKDcoOSg7KD0oPyhBKEMoRShUKFYoWChaKFwoXihgKGIoZCijKKUopyipKKsorCitKK4oryixKLMotCi1KLcouCj3KPko+yj9KP8pACkBKQIpAykFKQcpCCkJKQspDClLKU0pTylRKVMpVClVKVYpVylZKVspXCldKV8pYCmfKaEpoymlKacpqCmpKaopqymtKa8psCmxKbMptCnzKfUp9yn5Kfsp/Cn9Kf4p/yoBKgMqBCoFKgcqCCpHKkkqSypNKk8qUCpRKlIqUypVKlcqWCpZKlsqXCqbKp0qnyqhKqMqpCqlKqYqpyqpKqsqrCqtKq8qsCr7Kx4rPiteK2ArYitkK2YraCtpK2orbCttK28rcCtyK3QrdSt2K3greSuCK48rlCuWK5grnSufK6EroyvIK+wsEyw3LDksOyw9LD8sQSxDLEQsRixTLGQsZixoLGosbCxuLHAscix0LIUshyyJLIssjSyPLJEskyyVLJcs1izYLNos3CzeLN8s4CzhLOIs5CzmLOcs6CzqLOstKi0sLS4tMC0yLTMtNC01LTYtOC06LTstPC0+LT8tfi2ALYIthC2GLYctiC2JLYotjC2OLY8tkC2SLZMtoC2lLactqS2uLbAtsi20LcEtxi3ILcotzy3RLdMt1S4ULhYuGC4aLhwuHS4eLh8uIC4iLiQuJS4mLiguKS5oLmoubC5uLnAucS5yLnMudC52LngueS56LnwufS68Lr4uwC7CLsQuxS7GLscuyC7KLswuzS7OLtAu0S8QLxIvFC8WLxgvGS8aLxsvHC8eLyAvIS8iLyQvJS9kL2YvaC9qL2wvbS9uL28vcC9yL3QvdS92L3gveS+eL8Iv6TANMA8wETATMBUwFzAZMBowHDApMDgwOjA8MD4wQDBCMEQwRjBVMFcwWTBbMF0wXzBhMGMwZTCkMKYwqDCqMKwwrTCuMK8wsDCyMLQwtTC2MLgwuTD4MPow/DD+MQAxATECMQMxBDEGMQgxCTEKMQwxDTFMMU4xUDFSMVQxVTFWMVcxWDFaMVwxXTFeMWAxYTGgMaIxpDGmMagxqTGqMasxrDGuMbAxsTGyMbQxtTH0MfYx+DH6Mfwx/TH+Mf8yADICMgQyBTIGMggyCTJIMkoyTDJOMlAyUTJSMlMyVDJWMlgyWTJaMlwyXTKcMp4yoDKiMqQypTKmMqcyqDKqMqwyrTKuMrAysTL8Mx8zPzNfM2EzYzNlM2czaTNqM2szbTNuM3AzcTNzM3UzdjN3M3kzejODM5AzlTOXM5kznjOgM6IzpDPJM+00FDQ4NDo0PDQ+NEA0QjRENEU0RzRUNGU0ZzRpNGs0bTRvNHE0czR1NIY0iDSKNIw0jjSQNJI0lDSWNJg01zTZNNs03TTfNOA04TTiNOM05TTnNOg06TTrNOw1KzUtNS81MTUzNTQ1NTU2NTc1OTU7NTw1PTU/NUA1fzWBNYM1hTWHNYg1iTWKNYs1jTWPNZA1kTWTNZQ1oTWmNag1qjWvNbE1szW1NcI1xzXJNcs10DXSNdQ11jYVNhc2GTYbNh02HjYfNiA2ITYjNiU2JjYnNik2KjZpNms2bTZvNnE2cjZzNnQ2dTZ3Nnk2ejZ7Nn02fja9Nr82wTbDNsU2xjbHNsg2yTbLNs02zjbPNtE20jcRNxM3FTcXNxk3GjcbNxw3HTcfNyE3IjcjNyU3JjdlN2c3aTdrN203bjdvN3A3cTdzN3U3djd3N3k3ejefN8M36jgOOBA4EjgUOBY4GDgaOBs4HTgqODk4Ozg9OD84QThDOEU4RzhWOFg4WjhcOF44YDhiOGQ4ZjilOKc4qTirOK04rjivOLA4sTizOLU4tji3OLk4ujj5OPs4/Tj/OQE5AjkDOQQ5BTkHOQk5CjkLOQ05DjlNOU85UTlTOVU5VjlXOVg5WTlbOV05XjlfOWE5YjmhOaM5pTmnOak5qjmrOaw5rTmvObE5sjmzObU5tjn1Ofc5+Tn7Of05/jn/OgA6AToDOgU6BjoHOgk6CjpJOks6TTpPOlE6UjpTOlQ6VTpXOlk6WjpbOl06XjqdOp86oTqjOqU6pjqnOqg6qTqrOq06rjqvOrE6sjr9OyA7QDtgO2I7ZDtmO2g7ajtrO2w7bjtvO3E7cjt0O3Y7dzt4O3o7ezuEO5E7ljuYO5o7nzuhO6M7pTvKO+48FTw5PDs8PTw/PEE8QzxFPEY8SDxVPGY8aDxqPGw8bjxwPHI8dDx2PIc8iTyLPI08jzyRPJM8lTyXPJk82DzaPNw83jzgPOE84jzjPOQ85jzoPOk86jzsPO09LD0uPTA9Mj00PTU9Nj03PTg9Oj08PT09Pj1APUE9gD2CPYQ9hj2IPYk9ij2LPYw9jj2QPZE9kj2UPZU9oj2nPak9qz2wPbI9tD22PcM9yD3KPcw90T3TPdU91z4WPhg+Gj4cPh4+Hz4gPiE+Ij4kPiY+Jz4oPio+Kz5qPmw+bj5wPnI+cz50PnU+dj54Pno+ez58Pn4+fz6+PsA+wj7EPsY+xz7IPsk+yj7MPs4+zz7QPtI+0z8SPxQ/Fj8YPxo/Gz8cPx0/Hj8gPyI/Iz8kPyY/Jz9mP2g/aj9sP24/bz9wP3E/cj90P3Y/dz94P3o/ez+gP8Q/60APQBFAE0AVQBdAGUAbQBxAHkArQDpAPEA+QEBAQkBEQEZASEBXQFlAW0BdQF9AYUBjQGVAZ0CmQKhAqkCsQK5Ar0CwQLFAskC0QLZAt0C4QLpAu0C9QPxA/kEAQQJBBEEFQQZBB0EIQQpBDEENQQ5BEEERQVBBUkFUQVZBWEFZQVpBW0FcQV5BYEFhQWJBZEFlQaRBpkGoQapBrEGtQa5Br0GwQbJBtEG1QbZBuEG5QbtB+kH8Qf5CAEICQgNCBEIFQgZCCEIKQgtCDEIOQg9CTkJQQlJCVEJWQldCWEJZQlpCXEJeQl9CYEJiQmNCokKkQqZCqEKqQqtCrEKtQq5CsEKyQrNCtEK2QrdDAkMlQ0VDZUNnQ2lDa0NtQ29DcENxQ3NDdEN2Q3dDeUN7Q3xDfUN/Q4BDiUOWQ5tDnUOfQ6RDpkOoQ6pDz0PzRBpEPkRAREJERERGREhESkRLRE1EWkRrRG1Eb0RxRHNEdUR3RHlEe0SMRI5EkESSRJRElkSYRJpEnESeRN1E30ThRONE5UTmROdE6ETpROtE7UTuRO9E8UTyRTFFM0U1RTdFOUU6RTtFPEU9RT9FQUVCRUNFRUVGRYVFh0WJRYtFjUWORY9FkEWRRZNFlUWWRZdFmUWaRadFrEWuRbBFtUW3RblFu0XIRc1Fz0XRRdZF2EXaRdxGG0YdRh9GIUYjRiRGJUYmRidGKUYrRixGLUYvRjBGb0ZxRnNGdUZ3RnhGeUZ6RntGfUZ/RoBGgUaDRoRGw0bFRsdGyUbLRsxGzUbORs9G0UbTRtRG1UbXRthHF0cZRxtHHUcfRyBHIUciRyNHJUcnRyhHKUcrRyxHa0dtR29HcUdzR3RHdUd2R3dHeUd7R3xHfUd/R4BHpUfJR/BIFEgWSBhIGkgcSB5IIEghSCNIMEg/SEFIQ0hFSEdISUhLSE1IXEheSGBIYkhkSGZIaEhqSGxIq0itSK9IsUizSLRItUi2SLdIuUi7SLxIvUi/SMBI/0kBSQNJBUkHSQhJCUkKSQtJDUkPSRBJEUkTSRRJU0lVSVdJWUlbSVxJXUleSV9JYUljSWRJZUlnSWhJp0mpSatJrUmvSbBJsUmySbNJtUm3SbhJuUm7SbxJ+0n9Sf9KAUoDSgRKBUoGSgdKCUoLSgxKDUoPShBKT0pRSlNKVUpXSlhKWUpaSltKXUpfSmBKYUpjSmRKo0qlSqdKqUqrSqxKrUquSq9KsUqzSrRKtUq3SrhLA0smS0ZLZktoS2pLbEtuS3BLcUtyS3RLdUt3S3hLekt8S31LfkuAS4FLikuXS5xLnkugS6VLp0uqS6xL0Uv1TBxMQExCTERMRkxITEpMTExNTFBMXUxuTHBMckx0THZMeEx6THxMfkyPTJJMlUyYTJtMnkyhTKRMp0ypTOhM6kzsTO5M8EzxTPJM80z0TPZM+Ez5TPpM/Ez9TTxNPk1ATUJNRE1FTUZNR01ITUpNTE1NTU5NUE1RTZBNkk2VTZdNmU2aTZtNnE2dTZ9NoU2iTaNNpU2mTbNNuE26TbxNwU3DTcZNyE3VTdpN3E3eTeNN5U3nTelOKE4qTixOLk4wTjFOMk4zTjRONk44TjlOOk48Tj1OfE5+ToBOgk6EToVOhk6HTohOik6MTo1Ojk6QTpFO0E7STtRO1k7YTtlO2k7bTtxO3k7gTuFO4k7kTuVPJE8mTyhPKk8sTy1PLk8vTzBPMk80TzVPNk84TzlPeE96T3xPfk+AT4FPgk+DT4RPhk+IT4lPik+MT41Psk/WT/1QIVAjUCVQJ1ApUCtQLVAuUDFQPlBNUE9QUVBTUFVQV1BZUFtQalBtUHBQc1B2UHlQfFB/UIFQwFDCUMRQxlDJUMpQy1DMUM1Qz1DRUNJQ01DVUNZRFVEXURlRG1EeUR9RIFEhUSJRJFEmUSdRKFEqUStRalFsUW5RcFFzUXRRdVF2UXdReVF7UXxRfVF/UYBRv1HBUcNRxVHIUclRylHLUcxRzlHQUdFR0lHUUdVSFFIWUhhSGlIdUh5SH1IgUiFSI1IlUiZSJ1IpUipSaVJrUm1Sb1JyUnNSdFJ1UnZSeFJ6UntSfFJ+Un9SvlLAUsJSxFLHUshSyVLKUstSzVLPUtBS0VLTUtRTH1NCU2JTglOEU4ZTiFOKU4xTjVOOU5FTklOUU5VTl1OZU5pTm1OeU59TpFOxU7ZTuFO6U79TwlPFU8dT7FQQVDdUW1ReVGBUYlRkVGZUaFRpVGxUeVSKVIxUjlSQVJJUlFSWVJhUmlSrVK5UsVS0VLdUulS9VMBUw1TFVQRVBlUIVQpVDVUOVQ9VEFURVRNVFVUWVRdVGVUaVVlVW1VdVV9VYlVjVWRVZVVmVWhValVrVWxVblVvVa5VsFWzVbVVuFW5VbpVu1W8Vb5VwFXBVcJVxFXFVdJV01XUVdZWFVYXVhlWG1YeVh9WIFYhViJWJFYmVidWKFYqVitWalZsVm5WcFZzVnRWdVZ2VndWeVZ7VnxWfVZ/VoBWv1bBVsNWxVbIVslWylbLVsxWzlbQVtFW0lbUVtVXFFcWVxhXGlcdVx5XH1cgVyFXI1clVyZXJ1cpVypXaVdrV21Xb1dyV3NXdFd1V3ZXeFd6V3tXfFd+V39XpFfIV+9YE1gWWBhYGlgcWB5YIFghWCRYMVhAWEJYRFhGWEhYSlhMWE5YXVhgWGNYZlhpWGxYb1hyWHRYs1i1WLdYuVi8WL1Yvli/WMBYwljEWMVYxljIWMlZCFkKWQxZDlkRWRJZE1kUWRVZF1kZWRpZG1kdWR5ZXVlfWWFZY1lmWWdZaFlpWWpZbFluWW9ZcFlyWXNZslm0WbZZuFm7WbxZvVm+Wb9ZwVnDWcRZxVnHWchaB1oJWgtaDVoQWhFaEloTWhRaFloYWhlaGlocWh1aXFpeWmBaYlplWmZaZ1poWmlaa1ptWm5ab1pxWnJasVqzWrVat1q6WrtavFq9Wr5awFrCWsNaxFrGWsdbEls1W1VbdVt3W3lbe1t9W39bgFuBW4RbhVuHW4hbiluMW41bjluRW5Jbm1uoW61br1uxW7ZbuVu8W75b41wHXC5cUlxVXFdcWVxbXF1cX1xgXGNccFyBXINchVyHXIlci1yNXI9ckVyiXKVcqFyrXK5csVy0XLdculy8XPtc/Vz/XQFdBF0FXQZdB10IXQpdDF0NXQ5dEF0RXVBdUl1UXVZdWV1aXVtdXF1dXV9dYV1iXWNdZV1mXaVdp12qXaxdr12wXbFdsl2zXbVdt124Xbldu128Xcldzl3QXdJd113ZXdxd3l3rXfBd8l30Xfld+139Xf9ePl5AXkJeRF5HXkheSV5KXkteTV5PXlBeUV5TXlRek16VXpdemV6cXp1enl6fXqBeol6kXqVepl6oXqle6F7qXuxe7l7xXvJe8170XvVe9175Xvpe+179Xv5fPV8/X0FfQ19GX0dfSF9JX0pfTF9OX09fUF9SX1Nfkl+UX5ZfmF+bX5xfnV+eX59foV+jX6RfpV+nX6hfzV/xYBhgPGA/YEFgQ2BFYEdgSWBKYE1gWmBpYGtgbWBvYHFgc2B1YHdghmCJYIxgj2CSYJVgmGCbYJ1g3GDeYOBg4mDlYOZg52DoYOlg62DtYO5g72DxYPJhMWEzYTVhN2E6YTthPGE9YT5hQGFCYUNhRGFGYUdhhmGIYYphjGGPYZBhkWGSYZNhlWGXYZhhmWGbYZxh22HdYd9h4WHkYeVh5mHnYehh6mHsYe1h7mHwYfFiMGIyYjRiNmI5YjpiO2I8Yj1iP2JBYkJiQ2JFYkZihWKHYolii2KOYo9ikGKRYpJilGKWYpdimGKaYpti2mLcYt5i4GLjYuRi5WLmYudi6WLrYuxi7WLvYvBjO2NeY35jnmOgY6JjpGOmY6hjqWOqY61jrmOwY7Fjs2O1Y7Zjt2O6Y7tjwGPNY9Jj1GPWY9tj3mPhY+NkCGQsZFNkd2R6ZHxkfmSAZIJkhGSFZIhklWSmZKhkqmSsZK5ksGSyZLRktmTHZMpkzWTQZNNk1mTZZNxk32ThZSBlImUkZSZlKWUqZStlLGUtZS9lMWUyZTNlNWU2ZXVld2V5ZXtlfmV/ZYBlgWWCZYRlhmWHZYhlimWLZcplzGXPZdFl1GXVZdZl12XYZdpl3GXdZd5l4GXhZe5l72XwZfJmMWYzZjVmN2Y6ZjtmPGY9Zj5mQGZCZkNmRGZGZkdmhmaIZopmjGaPZpBmkWaSZpNmlWaXZphmmWabZpxm22bdZt9m4WbkZuVm5mbnZuhm6mbsZu1m7mbwZvFnMGcyZzRnNmc5ZzpnO2c8Zz1nP2dBZ0JnQ2dFZ0ZnhWeHZ4lni2eOZ49nkGeRZ5JnlGeWZ5dnmGeaZ5tnwGfkaAtoL2gyaDRoNmg4aDpoPGg9aEBoTWhcaF5oYGhiaGRoZmhoaGpoeWh8aH9ogmiFaIhoi2iOaJBoz2jRaNNo1WjYaNlo2mjbaNxo3mjgaOFo4mjkaOVpJGkmaShpKmktaS5pL2kwaTFpM2k1aTZpN2k5aTppeWl7aX1pf2mCaYNphGmFaYZpiGmKaYtpjGmOaY9pzmnQadJp1GnXadhp2Wnaadtp3WnfaeBp4WnjaeRqI2olaidqKWosai1qLmovajBqMmo0ajVqNmo4ajlqeGp6anxqfmqBaoJqg2qEaoVqh2qJaopqi2qNao5qzWrPatFq02rWatdq2GrZatpq3Great9q4GriauNrLmtRa3FrkWuTa5Vrl2uZa5trnGuda6BroWuja6Rrpmuoa6lrqmuta65rs2vAa8Vrx2vJa85r0WvUa9Zr+2wfbEZsamxtbG9scWxzbHVsd2x4bHtsiGyZbJtsnWyfbKFso2ylbKdsqWy6bL1swGzDbMZsyWzMbM9s0mzUbRNtFW0XbRltHG0dbR5tH20gbSJtJG0lbSZtKG0pbWhtam1sbW5tcW1ybXNtdG11bXdteW16bXttfW1+bb1tv23CbcRtx23Ibcltym3Lbc1tz23QbdFt023UbeFt4m3jbeVuJG4mbihuKm4tbi5uL24wbjFuM241bjZuN245bjpueW57bn1uf26CboNuhG6FboZuiG6KbotujG6Obo9uzm7QbtJu1G7Xbthu2W7abttu3W7fbuBu4W7jbuRvI28lbydvKW8sby1vLm8vbzBvMm80bzVvNm84bzlveG96b3xvfm+Bb4Jvg2+Eb4Vvh2+Jb4pvi2+Nb45vs2/Xb/5wInAlcCdwKXArcC1wL3AwcDNwQHBPcFFwU3BVcFdwWXBbcF1wbHBvcHJwdXB4cHtwfnCBcINwwnDEcMZwyHDLcMxwzXDOcM9w0XDTcNRw1XDXcNhxF3EZcRtxHXEgcSFxInEjcSRxJnEocSlxKnEscS1xbHFucXBxcnF1cXZxd3F4cXlxe3F9cX5xf3GBcYJxwXHDccVxx3HKcctxzHHNcc5x0HHScdNx1HHWcddyFnIYchpyHHIfciByIXIiciNyJXIncihyKXIrcixya3Jtcm9ycXJ0cnVydnJ3cnhyenJ8cn1yfnKAcoFywHLCcsRyxnLJcspyy3LMcs1yz3LRctJy03LVctZzIXNEc2RzhHOGc4hzinOMc45zj3OQc5NzlHOWc5dzmXObc5xznXOgc6FzpnOzc7hzunO8c8FzxHPHc8lz7nQSdDl0XXRgdGJ0ZHRmdGh0anRrdG50e3SMdI50kHSSdJR0lnSYdJp0nHStdLB0s3S2dLl0vHS/dMJ0xXTHdQZ1CHUKdQx1D3UQdRF1EnUTdRV1F3UYdRl1G3UcdVt1XXVfdWF1ZHVldWZ1Z3VodWp1bHVtdW51cHVxdbB1snW1dbd1unW7dbx1vXW+dcB1wnXDdcR1xnXHddR11XXWddh2F3YZdht2HXYgdiF2InYjdiR2JnYodil2KnYsdi12bHZudnB2cnZ1dnZ2d3Z4dnl2e3Z9dn52f3aBdoJ2wXbDdsV2x3bKdst2zHbNds520HbSdtN21HbWdtd3FncYdxp3HHcfdyB3IXcidyN3JXcndyh3KXcrdyx3a3dtd293cXd0d3V3dnd3d3h3end8d313fneAd4F3pnfKd/F4FXgYeBp4HHgeeCB4IngjeCZ4M3hCeER4RnhIeEp4THhOeFB4X3hieGV4aHhreG54cXh0eHZ4tXi3eLl4u3i+eL94wHjBeMJ4xHjGeMd4yHjKeMt5CnkMeQ55EHkTeRR5FXkWeRd5GXkbeRx5HXkfeSB5X3lheWN5ZXloeWl5anlreWx5bnlweXF5cnl0eXV5tHm2ebh5unm9eb55v3nAecF5w3nFecZ5x3nJecp6CXoLeg16D3oSehN6FHoVehZ6GHoaeht6HHoeeh96XnpgemJ6ZHpnemh6aXpqemt6bXpvenB6cXpzenR6s3q1erd6uXq8er16vnq/esB6wnrEesV6xnrIesl61Hrdet564HrpevR7A3sOexx7MXtFe1x7bnt7e3x7fXt/e4x7jXuOe5B7nXuee597oXuqe7l7xnvVe+d7+3wSfCR8LXwufDB8PXw+fD98QXxKfFR8W3xlfG18f3yEfIkAAAAAAAACAgAAAAAAABJjAAAAAAAAAAAAAAAAAAB8iw== + + + + + sshPort + + + + sshKeyFileName + + + + MHMongoHubMigration9to10 + Connection + Undefined + 1 + Connection + 1 + + + + + + defaultDatabase + + + + sshHost + + + + useSSL + + + + adminUser + + + + replicaSetName + + + \ No newline at end of file diff --git a/MongoHub_DataModel.xcdatamodeld/.xccurrentversion b/Sources/Model/MongoHub_DataModel.xcdatamodeld/.xccurrentversion similarity index 81% rename from MongoHub_DataModel.xcdatamodeld/.xccurrentversion rename to Sources/Model/MongoHub_DataModel.xcdatamodeld/.xccurrentversion index befd7065..d5c419ae 100644 --- a/MongoHub_DataModel.xcdatamodeld/.xccurrentversion +++ b/Sources/Model/MongoHub_DataModel.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - MongoHub_DataModel.xcdatamodel + MongoHub_DataModel13.xcdatamodel diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/elements new file mode 100644 index 00000000..c32c0288 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/layout new file mode 100644 index 00000000..446005fb Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel.xcdatamodel/layout differ diff --git a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/elements similarity index 100% rename from MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/elements rename to Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/elements diff --git a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/layout similarity index 100% rename from MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/layout rename to Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel1.0.xcdatamodel/layout diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel/elements new file mode 100644 index 00000000..f6693c93 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel/layout new file mode 100644 index 00000000..48935116 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel10.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel11.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel11.xcdatamodel/elements new file mode 100644 index 00000000..87629224 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel11.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel11.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel11.xcdatamodel/layout new file mode 100644 index 00000000..5b1bd96f Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel11.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel12.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel12.xcdatamodel/elements new file mode 100644 index 00000000..f3dd0be1 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel12.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel12.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel12.xcdatamodel/layout new file mode 100644 index 00000000..f90ba1dc Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel12.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel13.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel13.xcdatamodel/elements new file mode 100644 index 00000000..87629224 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel13.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel13.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel13.xcdatamodel/layout new file mode 100644 index 00000000..fdd682bf Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel13.xcdatamodel/layout differ diff --git a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/elements similarity index 100% rename from MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/elements rename to Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/elements diff --git a/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/layout similarity index 100% rename from MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/layout rename to Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel2.0.xcdatamodel/layout diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel3.0.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel3.0.xcdatamodel/elements new file mode 100644 index 00000000..410d44ea Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel3.0.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel3.0.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel3.0.xcdatamodel/layout new file mode 100644 index 00000000..61beb56e Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel3.0.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel4.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel4.xcdatamodel/elements new file mode 100644 index 00000000..9014b882 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel4.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel4.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel4.xcdatamodel/layout new file mode 100644 index 00000000..6c06b81f Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel4.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel5.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel5.xcdatamodel/elements new file mode 100644 index 00000000..76141edf Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel5.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel5.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel5.xcdatamodel/layout new file mode 100644 index 00000000..5e35e731 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel5.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel/elements new file mode 100644 index 00000000..d1cfeeb5 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel/layout new file mode 100644 index 00000000..673af78b Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel6.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel/elements new file mode 100644 index 00000000..e70a71ee Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel/layout new file mode 100644 index 00000000..21fe2c23 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel7.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel/elements new file mode 100644 index 00000000..6d048eee Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel/layout new file mode 100644 index 00000000..d66e2841 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel8.xcdatamodel/layout differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel/elements b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel/elements new file mode 100644 index 00000000..e8ad2c24 Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel/elements differ diff --git a/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel/layout b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel/layout new file mode 100644 index 00000000..5b1bd96f Binary files /dev/null and b/Sources/Model/MongoHub_DataModel.xcdatamodeld/MongoHub_DataModel9.xcdatamodel/layout differ diff --git a/Sources/TabViews/MHTabItemViewController.h b/Sources/TabViews/MHTabItemViewController.h new file mode 100644 index 00000000..57f48f62 --- /dev/null +++ b/Sources/TabViews/MHTabItemViewController.h @@ -0,0 +1,23 @@ +// +// MHTabItemViewController.h +// MongoHub +// +// Created by Jérôme Lebel on 04/12/2011. +// + +#import + +@class MHTabViewController; + +@interface MHTabItemViewController : NSViewController +{ + MHTabViewController *_tabViewController; +} + +@property (nonatomic, readwrite, weak) MHTabViewController *tabViewController; +@property (nonatomic, readonly, assign) BOOL isSelected; + +- (void)select; +- (void)willRemoveFromTabViewController; + +@end diff --git a/Sources/TabViews/MHTabItemViewController.m b/Sources/TabViews/MHTabItemViewController.m new file mode 100644 index 00000000..9d2d6977 --- /dev/null +++ b/Sources/TabViews/MHTabItemViewController.m @@ -0,0 +1,30 @@ +// +// MHTabItemViewController.m +// MongoHub +// +// Created by Jérôme Lebel on 04/12/2011. +// + +#import "MHTabItemViewController.h" +#import "MHTabViewController.h" + +@implementation MHTabItemViewController + +@synthesize tabViewController = _tabViewController; + +- (void)select +{ + [_tabViewController selectTabItemViewController:self]; +} + +- (BOOL)isSelected +{ + return self.tabViewController.selectedTabItemViewController == self; +} + +- (void)willRemoveFromTabViewController +{ + +} + +@end diff --git a/Sources/TabViews/MHTabTitleContainerView.h b/Sources/TabViews/MHTabTitleContainerView.h new file mode 100644 index 00000000..74241c8d --- /dev/null +++ b/Sources/TabViews/MHTabTitleContainerView.h @@ -0,0 +1,12 @@ +// +// MHTabTitleContainerView.h +// MongoHub +// +// Created by Jérôme Lebel on 08/04/2012. +// + +#import + +@interface MHTabTitleContainerView : NSView + +@end diff --git a/Sources/TabViews/MHTabTitleContainerView.m b/Sources/TabViews/MHTabTitleContainerView.m new file mode 100644 index 00000000..a7e77290 --- /dev/null +++ b/Sources/TabViews/MHTabTitleContainerView.m @@ -0,0 +1,48 @@ +// +// MHTabTitleContainerView.m +// MongoHub +// +// Created by Jérôme Lebel on 08/04/2012. +// + +#import "MHTabTitleContainerView.h" + +static NSMutableArray *_backgroundImages = nil; + +@implementation MHTabTitleContainerView + +- (instancetype)initWithFrame:(NSRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + if (!_backgroundImages) { + _backgroundImages = [[NSMutableArray alloc] init]; + [_backgroundImages addObject:[NSImage imageNamed:@"background-grey_left"]]; + [_backgroundImages addObject:[NSImage imageNamed:@"background-grey_center"]]; + [_backgroundImages addObject:[NSImage imageNamed:@"background-grey_right"]]; + } + } + + return self; +} + +- (void)drawRect:(NSRect)dirtyRect +{ + NSImage *image; + NSRect centerRect; + + image = [_backgroundImages objectAtIndex:0]; + [image drawAtPoint:NSMakePoint(0, self.bounds.size.height - image.size.height) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; + centerRect.origin.x = image.size.width; + centerRect.origin.y = self.bounds.size.height - image.size.height; + centerRect.size.height = image.size.height; + + image = [_backgroundImages objectAtIndex:2]; + [image drawAtPoint:NSMakePoint(self.bounds.size.width - image.size.width, self.bounds.size.height - image.size.height) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; + centerRect.size.width = self.bounds.size.width - centerRect.origin.x - image.size.width; + + image = [_backgroundImages objectAtIndex:1]; + [image drawInRect:centerRect fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; +} + +@end diff --git a/Sources/TabViews/MHTabTitleView.h b/Sources/TabViews/MHTabTitleView.h new file mode 100644 index 00000000..150d5318 --- /dev/null +++ b/Sources/TabViews/MHTabTitleView.h @@ -0,0 +1,20 @@ +// +// MHTabTitleView.h +// MongoHub +// +// Created by Jérôme Lebel on 30/11/2011. +// + +#import + +@class MHTabViewController; + +@interface MHTabTitleView : NSControl +{ + MHTabViewController *_tabViewController; +} + +@property(nonatomic, readwrite, assign) BOOL selected; +@property(nonatomic, readwrite, weak) MHTabViewController *tabViewController; + +@end diff --git a/Sources/TabViews/MHTabTitleView.m b/Sources/TabViews/MHTabTitleView.m new file mode 100644 index 00000000..1600cc0b --- /dev/null +++ b/Sources/TabViews/MHTabTitleView.m @@ -0,0 +1,305 @@ +// +// MHTabTitleView.m +// MongoHub +// +// Created by Jérôme Lebel on 30/11/2011. +// + +#import "MHTabTitleView.h" +#import "MHTabViewController.h" + +#define CLOSE_BUTTON_MARGIN 20.0 + +static NSMutableDictionary *_drawingObjects = nil; + +static void initializeImages(void) +{ + if (!_drawingObjects) { + _drawingObjects = [[NSMutableDictionary alloc] init]; + [_drawingObjects setObject:[NSArray arrayWithObjects:[NSImage imageNamed:@"background_blue_left"], [NSImage imageNamed:@"background_blue_center"], [NSImage imageNamed:@"background_blue_right"], nil] forKey:@"selected_tab"]; + [_drawingObjects setObject:[NSImage imageNamed:@"unselected-tab-background"] forKey:@"unselected-tab-background"]; + [_drawingObjects setObject:[NSImage imageNamed:@"unselected-tab-border"] forKey:@"unselected-tab-border"]; + [_drawingObjects setObject:[NSImage imageNamed:@"background_blue_arrow"] forKey:@"selected_tab_arrow"]; + [_drawingObjects setObject:[NSImage imageNamed:@"close_button"] forKey:@"close_button"]; + [_drawingObjects setObject:[NSImage imageNamed:@"overlay_close_button"] forKey:@"overlay_close_button"]; + [_drawingObjects setObject:[NSImage imageNamed:@"grip_button"] forKey:@"grip_button"]; + } +} + +@interface MHTabTitleView () + +@property (nonatomic, readwrite, assign) BOOL showCloseButton; +@property (nonatomic, readwrite, assign) BOOL closeButtonHit; +@property (nonatomic, readwrite, assign) BOOL titleHit; +@property (nonatomic, readwrite, assign) NSTrackingRectTag trakingTag; + +@property (nonatomic, readwrite, strong) NSMutableAttributedString *attributedTitle; +@property (nonatomic, readwrite, strong) NSMutableDictionary *titleAttributes; +@property (nonatomic, readwrite, strong) NSCell *titleCell; + +@end + +@implementation MHTabTitleView + +- (instancetype)initWithFrame:(NSRect)frame +{ + initializeImages(); + self = [super initWithFrame:frame]; + if (self) { + NSMutableParagraphStyle *mutParaStyle = [[NSMutableParagraphStyle alloc] init]; + + [mutParaStyle setAlignment:NSCenterTextAlignment]; + [mutParaStyle setLineBreakMode:NSLineBreakByTruncatingMiddle]; + self.titleAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:mutParaStyle, NSParagraphStyleAttributeName, nil]; + [self.titleAttributes setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; + self.attributedTitle = [[[NSMutableAttributedString alloc] initWithString:@"Loading…" attributes:self.titleAttributes] autorelease]; + self.titleCell = [[[NSCell alloc] init] autorelease]; + self.titleCell.attributedStringValue = self.attributedTitle; + + [mutParaStyle release]; +} + + return self; +} + +- (void)dealloc +{ + self.titleAttributes = nil; + self.titleCell = nil; + self.attributedTitle = nil; + self.tabViewController = nil; + [super dealloc]; +} + +- (NSRect)_closeButtonRect +{ + NSRect result; + + result = self.bounds; + result.origin.x += 5.0; + result.origin.y = ceil(result.size.height - [[_drawingObjects objectForKey:@"unselected-tab-background"] size].height + (([[_drawingObjects objectForKey:@"unselected-tab-background"] size].height - [[_drawingObjects objectForKey:@"close_button"] size].height) / 2.0) - (([[_drawingObjects objectForKey:@"close_button"] size].height - [[_drawingObjects objectForKey:@"close_button"] size].height) / 2.0)); + result.size.width = result.size.height = [[_drawingObjects objectForKey:@"close_button"] size].height; + return result; +} + +- (NSRect)_gripButtonRect +{ + NSRect result; + + result = self.bounds; + result.origin.x = result.size.width - 5.0 - [[_drawingObjects objectForKey:@"grip_button"] size].width; + result.origin.y = ceil(result.size.height - [[_drawingObjects objectForKey:@"unselected-tab-background"] size].height + (([[_drawingObjects objectForKey:@"unselected-tab-background"] size].height - [[_drawingObjects objectForKey:@"grip_button"] size].height) / 2.0) - (([[_drawingObjects objectForKey:@"grip_button"] size].height - [[_drawingObjects objectForKey:@"grip_button"] size].height) / 2.0)); + result.size.width = result.size.height = [[_drawingObjects objectForKey:@"grip_button"] size].height; + return result; +} + +- (void)viewDidMoveToSuperview +{ + self.trakingTag = [self addTrackingRect:self.bounds owner:self userData:nil assumeInside:NO]; + [super viewDidMoveToSuperview]; +} + +- (void)removeFromSuperview +{ + [self removeTrackingRect:self.trakingTag]; + [super removeFromSuperview]; +} + +- (void)mouseEntered:(NSEvent *)theEvent +{ + self.showCloseButton = YES; + [self setNeedsDisplayInRect:[self _closeButtonRect]]; + [self setNeedsDisplayInRect:[self _gripButtonRect]]; +} + +- (void)mouseExited:(NSEvent *)theEvent +{ + self.showCloseButton = NO; + [self setNeedsDisplayInRect:[self _closeButtonRect]]; + [self setNeedsDisplayInRect:[self _gripButtonRect]]; +} + +- (void)setFrame:(NSRect)frameRect +{ + [self removeTrackingRect:self.trakingTag]; + [super setFrame:frameRect]; + self.trakingTag = [self addTrackingRect:self.bounds owner:self userData:nil assumeInside:NO]; + self.showCloseButton = [self mouse:[self convertPoint:[self convertPoint:[NSEvent mouseLocation] fromView:nil] fromView:nil] inRect:self.bounds]; +} + +- (void)drawRect:(NSRect)dirtyRect +{ + NSRect titleRect = self.bounds; + NSRect imageDisplayRect; + NSRect mainRect; + NSImage *image; + + if (_selected || self.titleHit) { + NSArray *images = [_drawingObjects objectForKey:@"selected_tab"]; + + image = [images objectAtIndex:1]; + mainRect = self.bounds; + mainRect.origin.y = mainRect.size.height - image.size.height; + mainRect.size.height = image.size.height; + [image drawInRect:mainRect fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; + + image = [images objectAtIndex:0]; + [image drawAtPoint:NSMakePoint(0, self.bounds.size.height - image.size.height) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; + mainRect.origin.x = image.size.width; + mainRect.origin.y = self.bounds.size.height - image.size.height; + mainRect.size.height = image.size.height; + + image = [images objectAtIndex:2]; + [image drawAtPoint:NSMakePoint(self.bounds.size.width - image.size.width, self.bounds.size.height - image.size.height) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; + mainRect.size.width = self.bounds.size.width - mainRect.origin.x - image.size.width; + + if (_selected) { + image = [_drawingObjects objectForKey:@"selected_tab_arrow"]; + [image drawAtPoint:NSMakePoint(round((self.bounds.size.width / 2.0) + (image.size.width / 2.0)), 0) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeSourceOver fraction:1.0]; + } + [self.titleAttributes setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName]; + } else { + image = [_drawingObjects objectForKey:@"unselected-tab-background"]; + [image drawInRect:NSMakeRect(0, self.bounds.size.height - image.size.height, self.bounds.size.width, image.size.height) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1.0]; + + image = [_drawingObjects objectForKey:@"unselected-tab-border"]; + [image drawInRect:NSMakeRect(0, self.bounds.size.height - image.size.height, 1, image.size.height) fromRect:NSMakeRect(1, 0, 1, image.size.height) operation:NSCompositeCopy fraction:1.0]; + [image drawInRect:NSMakeRect(self.bounds.size.width - 1, self.bounds.size.height - image.size.height, 1, image.size.height) fromRect:NSMakeRect(0, 0, 1, image.size.height) operation:NSCompositeCopy fraction:1.0]; + + [self.titleAttributes setObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]; + + } + [self.attributedTitle setAttributes:self.titleAttributes range:NSMakeRange(0, self.attributedTitle.length)]; + self.titleCell.attributedStringValue = self.attributedTitle; + + titleRect.size.height -= 7; + titleRect.origin.x += CLOSE_BUTTON_MARGIN; + titleRect.size.width -= CLOSE_BUTTON_MARGIN * 2.0; + [self.titleCell drawInteriorWithFrame:titleRect inView:self]; + imageDisplayRect = [self _closeButtonRect]; + if (self.showCloseButton && NSIntersectsRect(dirtyRect, imageDisplayRect)) { + if (self.closeButtonHit) { + image = [_drawingObjects objectForKey:@"overlay_close_button"]; + } else { + image = [_drawingObjects objectForKey:@"close_button"]; + } + + [image drawInRect:imageDisplayRect fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeSourceOver fraction:1.0]; + } + + imageDisplayRect = [self _gripButtonRect]; + if (self.showCloseButton && NSIntersectsRect(dirtyRect, imageDisplayRect)) { + image = [_drawingObjects objectForKey:@"grip_button"]; + [image drawInRect:imageDisplayRect fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeSourceOver fraction:1.0]; + } +} + +static NSComparisonResult orderFromView(id view1, id view2, void *current) +{ + if (view1 == current) { + return NSOrderedDescending; + } else if (view2 == current) { + return NSOrderedAscending; + } else { + return NSOrderedSame; + } +} + +- (void)mouseDown:(NSEvent *)theEvent +{ + BOOL keepOn = YES; + BOOL titleHit = YES; + BOOL closeButtonHit; + NSPoint locationInView; + NSPoint locationInWindow; + NSPoint firstLocationInView; + NSRect closeButtonRect = [self _closeButtonRect]; + BOOL startToDrag = NO; + BOOL firstClickInCloseButton; + NSRect originalFrame = self.frame; + + [self.superview sortSubviewsUsingFunction:orderFromView context:self]; + locationInWindow = [theEvent locationInWindow]; + firstLocationInView = locationInView = [self convertPoint:locationInWindow fromView:nil]; + firstClickInCloseButton = [self mouse:firstLocationInView inRect:closeButtonRect]; + while (keepOn) { + locationInWindow = [theEvent locationInWindow]; + if (!startToDrag && !firstClickInCloseButton && pow(firstLocationInView.x - locationInView.x, 2) >= 100) { + startToDrag = YES; + self.alphaValue = 0.8; + } + locationInView = [self convertPoint:locationInWindow fromView:nil]; + titleHit = [self mouse:locationInView inRect:self.bounds]; + closeButtonHit = !startToDrag && [self mouse:locationInView inRect:closeButtonRect]; + + if (closeButtonHit != self.closeButtonHit || (titleHit || startToDrag) != self.titleHit) { + self.closeButtonHit = closeButtonHit; + self.titleHit = titleHit || startToDrag; + [self setNeedsDisplay]; + } + switch ([theEvent type]) { + case NSLeftMouseDragged: + if (startToDrag) { + NSRect newFrame; + NSPoint locationInSuperview; + + newFrame = self.frame; + newFrame.origin.x += locationInView.x - firstLocationInView.x; + locationInSuperview = [self.superview convertPoint:locationInWindow fromView:nil]; + if (locationInSuperview.x < originalFrame.origin.x && self.tag > 0) { + [self.tabViewController moveTabItemFromIndex:self.tag toIndex:self.tag - 1]; + originalFrame = self.frame; + } else if (locationInSuperview.x > originalFrame.origin.x + originalFrame.size.width && self.tag < self.tabViewController.tabCount - 1) { + [self.tabViewController moveTabItemFromIndex:self.tag toIndex:self.tag + 1]; + originalFrame = self.frame; + } + if (newFrame.origin.x < 0) { + newFrame.origin.x = 0; + } else if (newFrame.origin.x + newFrame.size.width > self.superview.bounds.origin.x + self.superview.bounds.size.width) { + newFrame.origin.x = self.superview.bounds.origin.x + self.superview.bounds.size.width - newFrame.size.width; + } + self.frame = newFrame; + } + break; + case NSLeftMouseUp: + self.showCloseButton = NO; + if (closeButtonHit) { + [self.tabViewController removeTabItemViewController:[self.tabViewController tabItemViewControlletAtIndex:self.tag]]; + } else if (titleHit) { + self.tabViewController.selectedTabIndex = self.tag; + [self setNeedsDisplay]; + } else { + [self setNeedsDisplay]; + } + keepOn = NO; + break; + default: + /* Ignore any other kind of event. */ + break; + } + if (keepOn) { + theEvent = [[self window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask]; + } + }; + if (startToDrag) { + self.alphaValue = 1.0; + } + self.frame = originalFrame; + self.titleHit = NO; +} + +- (void)setStringValue:(NSString *)aString +{ + if (aString) { + [self.attributedTitle.mutableString setString:aString]; + self.titleCell.attributedStringValue = self.attributedTitle; + [self setNeedsDisplay]; + } +} + +- (NSString *)stringValue +{ + return self.titleCell.attributedStringValue.string; +} + +@end diff --git a/Sources/TabViews/MHTabViewController.h b/Sources/TabViews/MHTabViewController.h new file mode 100644 index 00000000..936c4b66 --- /dev/null +++ b/Sources/TabViews/MHTabViewController.h @@ -0,0 +1,37 @@ +// +// MHTabViewController.h +// MongoHub +// +// Created by Jérôme Lebel on 02/12/2011. +// + +#import + +@class MHTabTitleView, MHTabItemViewController, MHTabViewController, MHTabTitleContainerView; + +@protocol MHTabViewControllerDelegate +- (void)tabViewController:(MHTabViewController *)tabViewController didRemoveTabItem:(MHTabItemViewController *)tabItemViewController; +@end + +@interface MHTabViewController : NSViewController +{ + NSView *_selectedTabView; + NSUInteger _selectedTabIndex; + id _delegate; +} + +@property (nonatomic, readwrite, weak) IBOutlet id delegate; + +- (void)addTabItemViewController:(MHTabItemViewController *)tabItemViewController; +- (void)removeTabItemViewController:(MHTabItemViewController *)tabItemViewController; +- (void)selectTabItemViewController:(MHTabItemViewController *)tabItemViewController; +- (MHTabItemViewController *)tabItemViewControlletAtIndex:(NSInteger)index; +- (void)moveTabItemFromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex; + +- (NSUInteger)tabCount; +- (MHTabItemViewController *)selectedTabItemViewController; +- (NSUInteger)selectedTabIndex; +- (void)setSelectedTabIndex:(NSUInteger)index; +- (NSArray *)tabControllers; + +@end diff --git a/Sources/TabViews/MHTabViewController.m b/Sources/TabViews/MHTabViewController.m new file mode 100644 index 00000000..23b4dfcd --- /dev/null +++ b/Sources/TabViews/MHTabViewController.m @@ -0,0 +1,243 @@ +// +// MHTabViewController.m +// MongoHub +// +// Created by Jérôme Lebel on 02/12/2011. +// + +#import "MHTabViewController.h" +#import "MHTabTitleView.h" +#import "MHTabItemViewController.h" +#import "MHTabTitleContainerView.h" + +#define TAB_HEIGHT 35.0 + +@interface MHTabViewController() + +@property (nonatomic, readwrite, strong) NSMutableArray *mutableTabControllers; +@property (nonatomic, readwrite, strong) NSMutableArray *tabTitleViewes; +@property (nonatomic, readwrite, strong) MHTabTitleContainerView *tabContainerView; +@property (nonatomic, readwrite, weak) NSView *selectedTabView; + +@end + +@implementation MHTabViewController + +@synthesize delegate = _delegate; +@synthesize selectedTabView = _selectedTabView; + +- (void)dealloc +{ + for (MHTabItemViewController *controller in self.mutableTabControllers) { + [controller removeObserver:self forKeyPath:@"title"]; + } + self.mutableTabControllers = nil; + self.tabTitleViewes = nil; + self.tabContainerView = nil; + [self.view removeObserver:self forKeyPath:@"frame"]; + [super dealloc]; +} + +- (NSString *)nibName +{ + return @"MHTabView"; +} + +- (void)awakeFromNib +{ + if (self.mutableTabControllers == nil) { + _selectedTabIndex = NSNotFound; + self.mutableTabControllers = [NSMutableArray array]; + self.tabTitleViewes = [NSMutableArray array]; + self.tabContainerView = [[[MHTabTitleContainerView alloc] initWithFrame:NSMakeRect(0, self.view.bounds.size.height - TAB_HEIGHT, self.view.bounds.size.width, TAB_HEIGHT)] autorelease]; + [self.view addSubview:self.tabContainerView]; + [self.view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; + [self.tabContainerView setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; + } +} + +- (NSRect)_rectForTabTitleAtIndex:(NSUInteger)index +{ + NSRect result; + NSUInteger count; + + count = [self.mutableTabControllers count]; + result = self.tabContainerView.bounds; + result.origin.y += result.size.height - TAB_HEIGHT; + result.size.height = TAB_HEIGHT; + result.size.width = round(result.size.width / count); + result.origin.x = result.size.width * index; + return result; +} + +- (void)_removeCurrentTabItemViewController +{ + [self.selectedTabView removeFromSuperview]; + self.selectedTabView = nil; +} + +- (void)_tabItemViewControllerWithIndex:(NSInteger)index +{ + if (_selectedTabIndex != NSNotFound && _selectedTabIndex < [self.tabTitleViewes count]) { + [[self.tabTitleViewes objectAtIndex:_selectedTabIndex] setNeedsDisplay:YES]; + [[self.tabTitleViewes objectAtIndex:_selectedTabIndex] setSelected:NO]; + } + _selectedTabIndex = index; + if (_selectedTabIndex != NSNotFound) { + NSRect rect; + + [[self.tabTitleViewes objectAtIndex:_selectedTabIndex] setNeedsDisplay:YES]; + rect = self.view.bounds; + self.selectedTabView = [[self.mutableTabControllers objectAtIndex:_selectedTabIndex] view]; + [self.view addSubview:self.selectedTabView]; + rect.size.height -= TAB_HEIGHT; + self.selectedTabView.frame = rect; + [[self.tabTitleViewes objectAtIndex:_selectedTabIndex] setSelected:YES]; + } +} + +- (void)_updateTitleViewesWithAnimation:(BOOL)animation exceptView:(MHTabTitleView *)exceptView +{ + NSUInteger ii = 0; + + for (MHTabTitleView *titleView in self.tabTitleViewes) { + if (animation && exceptView != titleView) { + [[titleView animator] setFrame:[self _rectForTabTitleAtIndex:ii]]; + } else { + [titleView setFrame:[self _rectForTabTitleAtIndex:ii]]; + } + titleView.selected = self.selectedTabIndex == ii; + titleView.tag = ii; + ii++; + } +} + +- (void)addTabItemViewController:(MHTabItemViewController *)tabItemViewController +{ + NSParameterAssert(tabItemViewController); + if ([self.mutableTabControllers indexOfObject:tabItemViewController] == NSNotFound) { + MHTabTitleView *titleView; + + tabItemViewController.tabViewController = self; + [self.mutableTabControllers addObject:tabItemViewController]; + tabItemViewController.view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + titleView = [[MHTabTitleView alloc] initWithFrame:self.tabContainerView.bounds]; + titleView.tabViewController = self; + titleView.stringValue = tabItemViewController.title; + [self.tabTitleViewes addObject:titleView]; + [self.tabContainerView addSubview:titleView]; + [titleView release]; + [tabItemViewController addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; + + self.selectedTabIndex = [self.mutableTabControllers count] - 1; + [self _updateTitleViewesWithAnimation:NO exceptView:nil]; + } +} + +- (void)removeTabItemViewController:(MHTabItemViewController *)tabItemViewController +{ + NSUInteger index; + + index = [self.mutableTabControllers indexOfObject:tabItemViewController]; + if (index != NSNotFound) { + [tabItemViewController willRemoveFromTabViewController]; + [tabItemViewController retain]; + [self willChangeValueForKey:@"selectedTabIndex"]; + [self _removeCurrentTabItemViewController]; + [tabItemViewController removeObserver:self forKeyPath:@"title"]; + [self.mutableTabControllers removeObjectAtIndex:index]; + [[self.tabTitleViewes objectAtIndex:index] removeFromSuperview]; + [self.tabTitleViewes removeObjectAtIndex:index]; + if ([self.mutableTabControllers count] == 0) { + [self _tabItemViewControllerWithIndex:NSNotFound]; + } else if (_selectedTabIndex == 0) { + [self _tabItemViewControllerWithIndex:0]; + } else { + NSUInteger newIndex = index > _selectedTabIndex ? _selectedTabIndex : _selectedTabIndex - 1; + [self _tabItemViewControllerWithIndex: newIndex]; + } + [self _updateTitleViewesWithAnimation:NO exceptView:nil]; + [self didChangeValueForKey:@"selectedTabIndex"]; + [_delegate tabViewController:self didRemoveTabItem:tabItemViewController]; + [tabItemViewController release]; + } +} + +- (NSUInteger)tabCount +{ + return [self.mutableTabControllers count]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (object == self.view) { + [self _updateTitleViewesWithAnimation:NO exceptView:nil]; + } else if ([object isKindOfClass:[MHTabItemViewController class]]) { + NSUInteger index; + + index = [self.mutableTabControllers indexOfObject:object]; + NSAssert(index != NSNotFound, @"unknown tab"); + [[self.tabTitleViewes objectAtIndex:index] setStringValue:[object title]]; + [[self.tabTitleViewes objectAtIndex:index] setNeedsDisplay:YES]; + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +- (NSUInteger)selectedTabIndex +{ + return _selectedTabIndex; +} + +- (void)setSelectedTabIndex:(NSUInteger)index +{ + if (index != _selectedTabIndex) { + [self willChangeValueForKey:@"selectedTabIndex"]; + [self _removeCurrentTabItemViewController]; + [self _tabItemViewControllerWithIndex:index]; + [self didChangeValueForKey:@"selectedTabIndex"]; + } +} + +- (void)selectTabItemViewController:(MHTabItemViewController *)tabItemViewController +{ + NSInteger index; + + index = [self.mutableTabControllers indexOfObject:tabItemViewController]; + if (index != NSNotFound) { + self.selectedTabIndex = index; + } +} + +- (MHTabItemViewController *)selectedTabItemViewController +{ + if (self.selectedTabIndex == NSNotFound) { + return nil; + } else { + return [self.mutableTabControllers objectAtIndex:self.selectedTabIndex]; + } +} + +- (MHTabItemViewController *)tabItemViewControlletAtIndex:(NSInteger)index +{ + return [self.mutableTabControllers objectAtIndex:index]; +} + +- (void)moveTabItemFromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex +{ + [self.mutableTabControllers exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex]; + [self.tabTitleViewes exchangeObjectAtIndex:fromIndex withObjectAtIndex:toIndex]; + if (fromIndex == _selectedTabIndex) { + _selectedTabIndex = toIndex; + } else if (toIndex == _selectedTabIndex) { + _selectedTabIndex = fromIndex; + } + [self _updateTitleViewesWithAnimation:YES exceptView:[self.tabTitleViewes objectAtIndex:toIndex]]; +} + +- (NSArray *)tabControllers +{ + return self.mutableTabControllers; +} + +@end diff --git a/main.m b/Sources/main.m similarity index 65% rename from main.m rename to Sources/main.m index 6748e305..65ce46e4 100644 --- a/main.m +++ b/Sources/main.m @@ -8,6 +8,10 @@ #import +#if MAC_OS_X_VERSION_MIN_REQUIRED != MAC_OS_X_VERSION_10_8 +#error You need to set to <10.8> +#endif + int main(int argc, char *argv[]) { return NSApplicationMain(argc, (const char **) argv); diff --git a/StatMonitorTableController.h b/StatMonitorTableController.h deleted file mode 100644 index 92bba566..00000000 --- a/StatMonitorTableController.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// statMonitorArrayController.h -// MongoHub -// -// Created by Syd on 10-12-23. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import -@class BWTransparentTableView; - -@interface StatMonitorTableController : NSControl { - NSMutableArray * nsMutaryDataObj; - IBOutlet BWTransparentTableView *nsTableView; -} - -@property (nonatomic, retain) NSMutableArray * nsMutaryDataObj; -@property (nonatomic, retain) BWTransparentTableView *nsTableView; - -- (void)addObject:(NSDictionary *)item; -- (int)numberOfRowsInTableView:(NSTableView *)pTableViewObj; - -- (id) tableView:(NSTableView *)pTableViewObj -objectValueForTableColumn:(NSTableColumn *)pTableColumn - row:(int)pRowIndex; - - -@end diff --git a/StatMonitorTableController.m b/StatMonitorTableController.m deleted file mode 100644 index e20646f7..00000000 --- a/StatMonitorTableController.m +++ /dev/null @@ -1,53 +0,0 @@ -// -// statMonitorArrayController.m -// MongoHub -// -// Created by Syd on 10-12-23. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "StatMonitorTableController.h" -#import - -@implementation StatMonitorTableController -@synthesize nsMutaryDataObj; -@synthesize nsTableView; - - -- (void)dealloc { - [nsMutaryDataObj release]; - [nsTableView release]; - [super dealloc]; -} - -- (void)addObject:(NSDictionary *)item { - if (!nsMutaryDataObj) - nsMutaryDataObj = [[NSMutableArray alloc] initWithObjects:item, nil]; - else - [nsMutaryDataObj addObject:item]; - [nsTableView reloadData]; - NSInteger numberOfRows = [nsTableView numberOfRows]; - - if (numberOfRows > 0) - [nsTableView scrollRowToVisible:numberOfRows - 1]; -} - -- (int)numberOfRowsInTableView:(NSTableView *)pTableViewObj { - return [self.nsMutaryDataObj count]; -} // end numberOfRowsInTableView - - -- (id) tableView:(NSTableView *)pTableViewObj -objectValueForTableColumn:(NSTableColumn *)pTableColumn - row:(int)pRowIndex { - NSDictionary * zDataObject = [self.nsMutaryDataObj objectAtIndex:pRowIndex]; - if (! zDataObject) { - NSLog(@"tableView: objectAtIndex:%d = NULL",pRowIndex); - return NULL; - } // end if - return [zDataObject objectForKey:[pTableColumn identifier]]; - -} // end tableView:objectValueForTableColumn:row: - - -@end diff --git a/Syntax Definitions/CSS 1.plist b/Syntax Definitions/CSS 1.plist deleted file mode 100644 index 9658d5f1..00000000 --- a/Syntax Definitions/CSS 1.plist +++ /dev/null @@ -1 +0,0 @@ - Components Color 0.349020 0.521569 0.784314 Start { End } IgnoredComponent Strings Name Tags Type Tag Color 0.349020 0.521569 0.784314 Start " End " EscapeChar Name Strings Type String Color 0.894118 0.015686 0.015686 Keywords background: background-attachment: background-color: background-image: background-position: background-repeat: border: border-bottom: border-bottom-color: border-bottom-style: border-bottom-width: border-color: border-left: border-left-color: border-left-style: border-left-width: border-right: border-right-color: border-right-style: border-right-width: border-style: border-top: border-top-color: border-top-style: border-top-width: border-width: clear: cursor: display: float: position: visibility: height: line-height: max-height: min-height: min-width: width: font: font-family: font-size: font-size-adjust: font-strech: font-style: font-variant: font-weight: content: counter-increment: counter-reset: quotes: list-style: list-style-image: list-style-position: list-style-type: marker-offset: margin: margin-bottom: margin-left: margin-right: margin-top: outline: outline-color: outline-style: outline-width: padding: padding-bottom: padding-left: padding-right: padding-top: bottom: clip: left: overflow: right: top: vertical-align: z-index: border-collapse: border-spacing: caption-side: empty-cells: table-layout: color: direction: letter-spacing: text-align: text-decoration: text-indent: text-shadow: text-transform: unicode-bidi: white-space: word-spacing: Name Identifiers Type Keywords Color 0.137255 0.431373 0.145098 Start /* End */ Name Comments Type BlockComment FileNameSuffixes css \ No newline at end of file diff --git a/Syntax Definitions/HTML.plist b/Syntax Definitions/HTML.plist deleted file mode 100644 index df93b163..00000000 --- a/Syntax Definitions/HTML.plist +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Components - - - Color - - 1 - 1 - 1 - - End - " - EscapeChar - - Name - Strings - Start - " - Type - String - - - Color - - 0 - 0 - 1 - - End - > - IgnoredComponent - Strings - Name - Tags - Start - < - Type - Tag - - - Color - - 0.29999999999999999 - 0.29999999999999999 - 0.29999999999999999 - - End - " - EscapeChar - - Name - Strings - Start - " - Type - String - - - Color - - 0.20000000000000001 - 0.5 - 0.20000000000000001 - - Keywords - - &lt; - &gt; - &amp; - &auml; - &uuml; - &ouml; - - Name - Identifiers - Type - Keywords - - - Color - - 1 - 0 - 0 - - End - --> - Name - Comments - Start - <!-- - Type - BlockComment - - - FileNameSuffixes - - htm - html - phtm - phtml - - - diff --git a/Syntax Definitions/JSON.plist b/Syntax Definitions/JSON.plist deleted file mode 100644 index a7c7d4eb..00000000 --- a/Syntax Definitions/JSON.plist +++ /dev/null @@ -1,165 +0,0 @@ - - - - - Components - - - Color - - 1 - 1 - 1 - - End - " - EscapeChar - - Name - QuoteStringsValue - Start - " - Type - String - - - Color - - 0 - 1 - 0 - - Keywords - - :true - : true - - Name - IdentifiersTrue - Type - Keywords - - - Color - - 1 - 0 - 0 - - Keywords - - :null - : null - :false - : false - - Name - IdentifiersFalse - Type - Keywords - - - Color - - 1 - 1 - 0 - - Keywords - - { - } - [ - ] - " - , - : - - Name - IdentifiersMark - Type - Keywords - - - Color - - 0.2627450980392157 - 0.66666666666666663 - 1 - - Keywords - - "_id" - - Name - IdentifiersID - Type - Keywords - - - Color - - 0.2627450980392157 - 0.66666666666666663 - 1 - - End - " - Name - Operator - Start - "$ - Type - String - - - Color - - 1 - 0.56470588235294117 - 0 - - End - ) - Name - JSONObj - Start - Date( - Type - String - - - Color - - 1 - 0.56470588235294117 - 0 - - End - ) - Name - JSONObj - Start - ObjectId( - Type - String - - - Color - - 1 - 0.56470588235294117 - 0 - - End - ) - Name - JSONObj - Start - Def( - Type - String - - - - diff --git a/Syntax Definitions/Objective C.plist b/Syntax Definitions/Objective C.plist deleted file mode 100644 index b61cd3d9..00000000 --- a/Syntax Definitions/Objective C.plist +++ /dev/null @@ -1,218 +0,0 @@ - - - - - OneLineCommentPrefix - // - Components - - - Color - - 1 - 1 - 1 - - End - " - EscapeChar - \ - Name - Strings - Start - " - Type - String - - - Charset - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@_1234567890 - Color - - 0.2 - 0.5 - 0.2 - - Keywords - - super - id - void - self - return - @selector - @encode - @interface - @implementation - @protocol - @end - @property - @synthesize - @synchronized - @class - @try - @catch - @finally - @private - @protected - @required - @optional - enum - in - typedef - unsigned - signed - char - unichar - long - int - short - float - double - nil - else - if - do - while - for - break - case - default - continue - goto - switch - const - static - volatile - extern - IBAction - IBOutlet - BOOL - YES - NO - NS_DURING - NS_HANDLER - NS_ENDHANDLER - NS_VOIDRETURN - NS_VALUERETURN - Class - SEL - - Name - Identifiers - Type - Keywords - - - Charset - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@_1234567890 - Name - UserIdentifiers - Type - Keywords - - - Name - Preprocessor - Start - #define - Type - OneLineComment - - - Name - Preprocessor - Start - #include - Type - OneLineComment - - - Name - Preprocessor - Start - #import - Type - OneLineComment - - - Name - Preprocessor - Start - #if - Type - OneLineComment - - - Name - Preprocessor - Start - #else - Type - OneLineComment - - - Name - Preprocessor - Start - #elif - Type - OneLineComment - - - Name - Preprocessor - Start - #endif - Type - OneLineComment - - - Name - Preprocessor - Start - #undef - Type - OneLineComment - - - Name - Preprocessor - Start - #pragma - Type - OneLineComment - - - Name - Comments - Start - // - Type - OneLineComment - - - Color - - 1 - 0 - 0 - - End - */ - Name - Comments - Start - /* - Type - BlockComment - - - FileNameSuffixes - - m - mm - h - - - diff --git a/SyntaxColorDefaults.plist b/SyntaxColorDefaults.plist deleted file mode 100644 index 5012fdb4..00000000 --- a/SyntaxColorDefaults.plist +++ /dev/null @@ -1,54 +0,0 @@ - - - - - SyntaxColoring:Color:Comments - - 1 - 0 - 0 - - SyntaxColoring:Color:Comments2 - - 0.80000000000000004 - 0 - 0 - - SyntaxColoring:Color:Identifiers - - 0 - 0 - 1 - - SyntaxColoring:Color:Identifiers2 - - 0.0 - 0.25097999999999998 - 0.50196099999999999 - - SyntaxColoring:Color:Preprocessor - - 0 - 0.40000000000000002 - 0 - - SyntaxColoring:Color:Strings - - 0.40000000596046448 - 0.40000000596046448 - 0.40000000596046448 - - SyntaxColoring:Color:Tags - - 0 - 0 - 0.59999999999999998 - - SyntaxColoring:Color:UserIdentifiers - - 1.0 - 0.95097999999999998 - 0.50196099999999999 - - - diff --git a/SyntaxDefinition.plist b/SyntaxDefinition.plist deleted file mode 100644 index adf19e94..00000000 --- a/SyntaxDefinition.plist +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Components - - - Color - - 1 - 1 - 1 - - End - " - EscapeChar - - Name - Strings - Start - " - Type - String - - - Color - - 0 - 0 - 1 - - End - > - IgnoredComponent - Strings - Name - Tags - Start - < - Type - Tag - - - Color - - 0.29999999999999999 - 0.29999999999999999 - 0.29999999999999999 - - End - " - EscapeChar - - Name - Strings - Start - " - Type - String - - - Color - - 0.20000000000000001 - 0.5 - 0.20000000000000001 - - Keywords - - &lt; - &gt; - &amp; - &auml; - &uuml; - &ouml; - - Name - Identifiers - Type - Keywords - - - Color - - 1 - 0 - 0 - - End - --> - Name - Comments - Start - <!-- - Type - BlockComment - - - - diff --git a/Tunnel.h b/Tunnel.h deleted file mode 100644 index c7e842d0..00000000 --- a/Tunnel.h +++ /dev/null @@ -1,78 +0,0 @@ -// -// Tunnel.h -// MongoHub -// -// Created by Syd on 10-12-15. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import - -@interface Tunnel : NSObject { - id delegate; - - NSLock* lock; - NSTask* task; - NSPipe* pipe; - NSString* pipeData; - NSDate* startDate; - NSString* retStatus; - BOOL isRunning; - - NSString* uid; - NSString* name; - NSString* host; - int port; - NSString* user; - NSString* password; - NSString* keyfile; - int aliveInterval; - int aliveCountMax; - BOOL tcpKeepAlive; - BOOL compression; - NSString* additionalArgs; - NSMutableArray* portForwardings; -} - -@property(retain) NSString* uid; -@property(retain) NSString* name; -@property(retain) NSString* host; -@property(assign) int port; -@property(retain) NSString* user; -@property(retain) NSString* password; -@property(retain) NSString* keyfile; -@property(assign) int aliveInterval; -@property(assign) int aliveCountMax; -@property(assign) BOOL tcpKeepAlive; -@property(assign) BOOL compression; -@property(retain) NSString* additionalArgs; -@property(retain) NSMutableArray* portForwardings; - -- (void)setDelegate:(id)val; -- (id)delegate; - --(BOOL) running; --(BOOL) checkProcess; --(void) start; --(void) stop; --(void) readStatus; --(NSArray*) prepareSSHCommandArgs; - --(void) tunnelLoaded; --(void) tunnelSaved; --(void) tunnelRemoved; - --(BOOL) keychainItemExists; --(BOOL) keychainAddItem; --(BOOL) keychainModifyItem; --(BOOL) keychainDeleteItem; --(NSString*) keychainGetPassword; --(NSString*) keychainGetPasswordFromItemRef: (SecKeychainItemRef)item; - -@end - -@interface NSObject (Tunnel) - -- (void) tunnelStatusChanged: (Tunnel*) tunnel status: (NSString*) status; - -@end \ No newline at end of file diff --git a/Tunnel.m b/Tunnel.m deleted file mode 100644 index 2b0e8c4b..00000000 --- a/Tunnel.m +++ /dev/null @@ -1,670 +0,0 @@ -// -// Tunnel.m -// MongoHub -// -// Created by Syd on 10-12-15. -// Copyright 2010 ThePeppersStudio.COM. All rights reserved. -// - -#import "Tunnel.h" -#import -#import "NSString+Extras.h" - -#include -#include -#include -#include -#include -#include - -typedef struct kinfo_proc kinfo_proc; - -static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount) -// Returns a list of all BSD processes on the system. This routine -// allocates the list and puts it in *procList and a count of the -// number of entries in *procCount. You are responsible for freeing -// this list (use "free" from System framework). -// On success, the function returns 0. -// On error, the function returns a BSD errno value. -{ - int err; - kinfo_proc * result; - bool done; - static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; - // Declaring name as const requires us to cast it when passing it to - // sysctl because the prototype doesn't include the const modifier. - size_t length; - - assert( procList != NULL); - assert(*procList == NULL); - assert(procCount != NULL); - - *procCount = 0; - - // We start by calling sysctl with result == NULL and length == 0. - // That will succeed, and set length to the appropriate length. - // We then allocate a buffer of that size and call sysctl again - // with that buffer. If that succeeds, we're done. If that fails - // with ENOMEM, we have to throw away our buffer and loop. Note - // that the loop causes use to call sysctl with NULL again; this - // is necessary because the ENOMEM failure case sets length to - // the amount of data returned, not the amount of data that - // could have been returned. - - result = NULL; - done = false; - do { - assert(result == NULL); - - // Call sysctl with a NULL buffer. - - length = 0; - err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, - NULL, &length, - NULL, 0); - if (err == -1) { - err = errno; - } - - // Allocate an appropriately sized buffer based on the results - // from the previous call. - - if (err == 0) { - result = malloc(length); - if (result == NULL) { - err = ENOMEM; - } - } - - // Call sysctl again with the new buffer. If we get an ENOMEM - // error, toss away our buffer and start again. - - if (err == 0) { - err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, - result, &length, - NULL, 0); - if (err == -1) { - err = errno; - } - if (err == 0) { - done = true; - } else if (err == ENOMEM) { - assert(result != NULL); - free(result); - result = NULL; - err = 0; - } - } - } while (err == 0 && ! done); - - // Clean up and establish post conditions. - - if (err != 0 && result != NULL) { - free(result); - result = NULL; - } - *procList = result; - if (err == 0) { - *procCount = length / sizeof(kinfo_proc); - } - - assert( (err == 0) == (*procList != NULL) ); - - return err; -} - - -static int GetFirstChildPID(int pid) -/*" Returns the parent process id - for the given process id (pid). "*/ -{ - int pidFound = -1; - - kinfo_proc* plist = nil; - size_t len = 0; - GetBSDProcessList(&plist,&len); - - if(plist != nil){ - for(int i = 0;i 30 ){ - retStatus = @"TIME_OUT"; - - if ( [delegate respondsToSelector:@selector(tunnelStatusChanged: status:)] ) { - [delegate tunnelStatusChanged: self status: retStatus]; - } - - return; - }*/ - } - [lock unlock]; -} - --(BOOL) checkProcess { - BOOL ret = NO; - [lock lock]; - ret = isRunning; - if( ret ) - ret = GetFirstChildPID( [task processIdentifier] ) != -1; - [lock unlock]; - - return ret; -} - --(NSArray*) prepareSSHCommandArgs { - - NSString* pfs = @""; - for(NSString* pf in portForwardings){ - NSArray* pfa = [pf componentsSeparatedByString: @":"]; - pfs = [NSString stringWithFormat: @"%@ -%@ %@:%@:%@:%@", pfs, [pfa objectAtIndex: 0], [pfa objectAtIndex: 2], [pfa objectAtIndex: 1], [pfa objectAtIndex: 3], [pfa objectAtIndex: 4] ]; - } - - NSString* cmd; - if ([password isNotEqualTo:@""]|| [keyfile isEqualToString:@""]) { - cmd = [NSString stringWithFormat: @"ssh -N -o ConnectTimeout=28 %@%@%@%@%@%@-p %d %@@%@", - [additionalArgs length] > 0 ? [NSString stringWithFormat: @"%@ ", additionalArgs] : @"", - [pfs length] > 0 ? [NSString stringWithFormat: @"%@ ",pfs] : @"", - aliveInterval > 0 ? [NSString stringWithFormat: @"-o ServerAliveInterval=%d ",aliveInterval] : @"", - aliveCountMax > 0 ? [NSString stringWithFormat: @"-o ServerAliveCountMax=%d ",aliveCountMax] : @"", - tcpKeepAlive == YES ? @"-o TCPKeepAlive=yes " : @"", - compression == YES ? @"-C " : @"", - port,user,host]; - }else { - cmd = [NSString stringWithFormat: @"ssh -N -o ConnectTimeout=28 %@%@%@%@%@%@-p %d -i %@ %@@%@", - [additionalArgs length] > 0 ? [NSString stringWithFormat: @"%@ ", additionalArgs] : @"", - [pfs length] > 0 ? [NSString stringWithFormat: @"%@ ",pfs] : @"", - aliveInterval > 0 ? [NSString stringWithFormat: @"-o ServerAliveInterval=%d ",aliveInterval] : @"", - aliveCountMax > 0 ? [NSString stringWithFormat: @"-o ServerAliveCountMax=%d ",aliveCountMax] : @"", - tcpKeepAlive == YES ? @"-o TCPKeepAlive=yes " : @"", - compression == YES ? @"-C " : @"", - port,keyfile,user,host]; - } - - - NSLog(@"cmd: %@", cmd); - return [NSArray arrayWithObjects: cmd, password, nil]; -} - --(void) tunnelLoaded { - - if(uid == nil || [uid length] == 0){ - CFUUIDRef uidref = CFUUIDCreate(nil); - uid = (NSString*)CFUUIDCreateString(nil, uidref); - CFRelease(uidref); - } - - if([self keychainItemExists]){ - password = [self keychainGetPassword]; - }else{ - password = @""; - } -} - --(void) tunnelSaved{ - if([self keychainItemExists]){ - [self keychainModifyItem]; - }else{ - [self keychainAddItem]; - } -} - --(void) tunnelRemoved { - if([self keychainItemExists]) - [self keychainDeleteItem]; -} - --(BOOL) keychainItemExists { - - SecKeychainSearchRef search; - SecKeychainAttributeList list; - SecKeychainAttribute attributes[3]; - - NSString* keychainItemName = [NSString stringWithFormat: @"SSHTunnel <%@>", uid]; - NSString* keychainItemKind = @"application password"; - - attributes[0].tag = kSecAccountItemAttr; - attributes[0].data = (void *)[uid UTF8String]; - attributes[0].length = [uid length]; - - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keychainItemKind UTF8String]; - attributes[1].length = [keychainItemKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keychainItemName UTF8String]; - attributes[2].length = [keychainItemName length]; - - list.count = 3; - list.attr = attributes; - - OSErr result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &list, &search); - - if (result != noErr) { - NSLog (@"Error status %d from SecKeychainSearchCreateFromAttributes\n", result); - return FALSE; - } - - uint itemsFound = 0; - SecKeychainItemRef item; - - while (SecKeychainSearchCopyNext (search, &item) == noErr) { - CFRelease (item); - itemsFound++; - } - - CFRelease (search); - return itemsFound > 0; -} - --(BOOL) keychainAddItem { - - SecKeychainItemRef item; - SecKeychainAttributeList list; - SecKeychainAttribute attributes[3]; - - NSString* keychainItemName = [NSString stringWithFormat: @"SSHTunnel <%@>", uid]; - NSString* keychainItemKind = @"application password"; - - attributes[0].tag = kSecAccountItemAttr; - attributes[0].data = (void *)[uid UTF8String]; - attributes[0].length = [uid length]; - - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keychainItemKind UTF8String]; - attributes[1].length = [keychainItemKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keychainItemName UTF8String]; - attributes[2].length = [keychainItemName length]; - - list.count = 3; - list.attr = attributes; - - OSStatus status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &list, [password length], [password UTF8String], NULL,NULL,&item); - if (status != 0) { - NSLog(@"Error creating new item: %d for %@\n", (int)status, keychainItemName); - } - - return !status; -} - --(BOOL) keychainModifyItem { - - SecKeychainItemRef item; - SecKeychainSearchRef search; - OSStatus status; - OSErr result; - SecKeychainAttributeList list; - SecKeychainAttribute attributes[3]; - - NSString* keychainItemName = [NSString stringWithFormat: @"SSHTunnel <%@>", uid]; - NSString* keychainItemKind = @"application password"; - - attributes[0].tag = kSecAccountItemAttr; - attributes[0].data = (void *)[uid UTF8String]; - attributes[0].length = [uid length]; - - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keychainItemKind UTF8String]; - attributes[1].length = [keychainItemKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keychainItemName UTF8String]; - attributes[2].length = [keychainItemName length]; - - list.count = 3; - list.attr = attributes; - - result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &list, &search); - NSLog(@"%@", result); - SecKeychainSearchCopyNext (search, &item); - status = SecKeychainItemModifyContent(item, &list, [password length], [password UTF8String]); - - if (status != 0) { - NSLog(@"Error modifying item: %d", (int)status); - } - - CFRelease (item); - CFRelease(search); - - return !status; -} - --(BOOL) keychainDeleteItem { - - SecKeychainItemRef item; - SecKeychainSearchRef search; - OSStatus status = 0; - OSErr result; - SecKeychainAttributeList list; - SecKeychainAttribute attributes[3]; - uint itemsFound = 0; - - NSString* keychainItemName = [NSString stringWithFormat: @"SSHTunnel <%@>", uid]; - NSString* keychainItemKind = @"application password"; - - attributes[0].tag = kSecAccountItemAttr; - attributes[0].data = (void *)[uid UTF8String]; - attributes[0].length = [uid length]; - - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keychainItemKind UTF8String]; - attributes[1].length = [keychainItemKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keychainItemName UTF8String]; - attributes[2].length = [keychainItemName length]; - - list.count = 3; - list.attr = attributes; - - result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &list, &search); - NSLog(@"%@", result); - while (SecKeychainSearchCopyNext (search, &item) == noErr) { - itemsFound++; - } - if (itemsFound) { - status = SecKeychainItemDelete(item); - } - - if (status != 0) { - NSLog(@"Error deleting item: %d\n", (int)status); - } - CFRelease (item); - CFRelease (search); - - return !status; -} - --(NSString*) keychainGetPassword { - - SecKeychainItemRef item; - SecKeychainSearchRef search; - OSErr result; - SecKeychainAttributeList list; - SecKeychainAttribute attributes[3]; - - NSString* keychainItemName = [NSString stringWithFormat: @"SSHTunnel <%@>", uid]; - NSString* keychainItemKind = @"application password"; - - attributes[0].tag = kSecAccountItemAttr; - attributes[0].data = (void *)[uid UTF8String]; - attributes[0].length = [uid length]; - - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keychainItemKind UTF8String]; - attributes[1].length = [keychainItemKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keychainItemName UTF8String]; - attributes[2].length = [keychainItemName length]; - - - list.count = 3; - list.attr = attributes; - - result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &list, &search); - - if (result != noErr) { - NSLog (@"status %d from SecKeychainSearchCreateFromAttributes\n", result); - } - - NSString *pass = @""; - if (SecKeychainSearchCopyNext (search, &item) == noErr) { - pass = [self keychainGetPasswordFromItemRef:item]; - if(!pass) { - pass = @""; - } - CFRelease (item); - CFRelease (search); - } - - return pass; -} - --(NSString*) keychainGetPasswordFromItemRef: (SecKeychainItemRef)item { - - NSString* retPass = nil; - - UInt32 length; - char *pass; - SecKeychainAttribute attributes[8]; - SecKeychainAttributeList list; - OSStatus status; - - attributes[0].tag = kSecAccountItemAttr; - attributes[1].tag = kSecDescriptionItemAttr; - attributes[2].tag = kSecLabelItemAttr; - attributes[3].tag = kSecModDateItemAttr; - - list.count = 4; - list.attr = attributes; - - status = SecKeychainItemCopyContent (item, NULL, &list, &length, (void **)&pass); - - if (status == noErr) { - if (pass != NULL) { - - // copy the password into a buffer so we can attach a - // trailing zero byte in order to be able to print - // it out with printf - char passwordBuffer[1024]; - - if (length > 1023) { - length = 1023; // save room for trailing \0 - } - strncpy (passwordBuffer, pass, length); - - passwordBuffer[length] = '\0'; - - retPass = [NSString stringWithUTF8String:passwordBuffer]; - } - - SecKeychainItemFreeContent (&list, pass); - - return retPass; - } else { - printf("Error getting password = %d\n", (int)status); - return @""; - } -} - -- (void)encodeWithCoder:(NSCoder *)coder { - - [coder encodeObject: uid forKey: @"uid"]; - [coder encodeObject: name forKey: @"name"]; - [coder encodeObject: host forKey: @"host"]; - [coder encodeInt: port forKey: @"port"]; - [coder encodeObject: user forKey: @"user"]; - [coder encodeObject: password forKey: @"password"]; - [coder encodeObject: keyfile forKey: @"keyfile"]; - [coder encodeInt: aliveInterval forKey: @"aliveInterval"]; - [coder encodeInt: aliveCountMax forKey: @"aliveCountMax"]; - [coder encodeBool: tcpKeepAlive forKey: @"tcpKeepAlive"]; - [coder encodeBool: compression forKey: @"compression"]; - [coder encodeObject: additionalArgs forKey: @"additionalArgs"]; - [coder encodeObject: portForwardings forKey: @"portForwardings"]; - - [self tunnelSaved]; -} - -- (id)initWithCoder:(NSCoder *)coder { - - uid = [coder decodeObjectForKey: @"uid"]; - name = [coder decodeObjectForKey: @"name"]; - host = [coder decodeObjectForKey: @"host"]; - port = [coder decodeIntForKey: @"port"]; - user = [coder decodeObjectForKey: @"user"]; - password = [coder decodeObjectForKey: @"password"]; - keyfile = [coder decodeObjectForKey: @"keyfile"]; - aliveInterval = [coder decodeIntForKey: @"aliveInterval"]; - aliveCountMax = [coder decodeIntForKey: @"aliveCountMax"]; - tcpKeepAlive = [coder decodeBoolForKey: @"tcpKeepAlive"]; - compression = [coder decodeBoolForKey: @"compression"]; - additionalArgs = [coder decodeObjectForKey: @"additionalArgs"]; - portForwardings = [coder decodeObjectForKey: @"portForwardings"]; - - [self tunnelLoaded]; - - return (self); -} - -@end diff --git a/create_version.sh b/create_version.sh new file mode 100755 index 00000000..588619e2 --- /dev/null +++ b/create_version.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -eux + +VERSION="$1" +if [ "$VERSION" = "" ] ; then + echo "Usage: $(basename $0) VERSION" + exit 1 +fi + +cd Libraries/MongoObjCDriver +./scripts/create_version.sh "MongoHub-$VERSION" +cd ../.. + +git submodule status | sed 's/^.//' | awk '{ print $1 }' > Libraries/MongoObjCDriver.sha1 +git commit -m "software update $VERSION" . || true +git push +git tag -a "$VERSION" -m "software update $VERSION" +git push --tags diff --git a/scripts/commit_libraries.sh b/scripts/commit_libraries.sh new file mode 100755 index 00000000..9978e945 --- /dev/null +++ b/scripts/commit_libraries.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -eux + +COMMENT="$1" +if [ "${COMMENT}" = "" ] ; then + echo "Usage: $(basename $0) COMMENT" + exit 1 +fi + +cd Libraries/MongoObjCDriver +./scripts/commit_libraries.sh "${COMMENT}" +cd ../.. + +git submodule status | sed 's/^.//' | awk '{ print $1 }' > Libraries/MongoObjCDriver.sha1 +git commit -m "${COMMENT}" . diff --git a/scripts/crash_test.py b/scripts/crash_test.py new file mode 100755 index 00000000..d3ce5c46 --- /dev/null +++ b/scripts/crash_test.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +import subprocess +import os +import pprint +import time +import signal + +def launch(): + my_env = os.environ.copy() + my_env["MallocGuardEdges"] = "" + my_env["MALLOC_PERMIT_INSANE_REQUESTS"] = "1" + my_env["MallocNanoZone"] = "1" + my_env["MallocScribble"] = "" +# my_env["MallocStackLogging"] = "" + my_env["NSZombieEnabled"] = "YES" + out = open('/dev/null', 'w') +# out = None + + p = subprocess.Popen(["/Users/jerome/Library/Developer/Xcode/DerivedData/MongoHub-ghkunjdpnsennughboosbmnhkecd/Build/Products/Debug/MongoHub.app/Contents/MacOS/MongoHub" ], env = my_env, stdout = out, stderr = out) + + return p + +crashed = 0 +processes = [] +while True: + for x in range(2): + processes.append(launch()) + time.sleep(8) + start_time = time.time() + while len(processes): + for p in processes: + if p.poll() is not None: + processes.remove(p) + if p.returncode != 0: + crashed += 1 + if time.time() - start_time > 4: + break + + for p in processes: + pprint.pprint(p.pid) + os.killpg(p.pid, signal.SIGTERM) + p.kill() + processes.remove(p) + + print(crashed) diff --git a/scripts/git_fetch.sh b/scripts/git_fetch.sh new file mode 100755 index 00000000..7d3951f3 --- /dev/null +++ b/scripts/git_fetch.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +submodule_scheme="$1" +submodule_owner="$2" +submodule_name="$3" +submodule_branch="$4" +submodule_path="$5" + +rm -fr "${submodule_path}" +if [ "$submodule_scheme" = "ssh" ] ; then + git clone "git@github.com:${submodule_owner}/${submodule_name}.git" "${submodule_path}" +elif [ "$submodule_scheme" = "https" ]; then + git clone "https://github.com/${submodule_owner}/${submodule_name}.git" "${submodule_path}" + if [ "${submodule_branch}" != "master" ] ; then + cd "${submodule_path}" + git branch "${submodule_branch}" "origin/${submodule_branch}" + git checkout "${submodule_branch}" + fi +else + mkdir "${submodule_path}" + cd "${submodule_path}" + curl -o "${submodule_name}.zip" -L "https://github.com/${submodule_owner}/${submodule_name}/archive/${submodule_branch}.zip" + unzip "${submodule_name}.zip" + rm "${submodule_name}.zip" + submodule_unzip_dir=`ls` + cd "${submodule_unzip_dir}" + mv * .. + cd .. + rm -fr "${submodule_unzip_dir}" +fi diff --git a/scripts/git_test.sh b/scripts/git_test.sh new file mode 100755 index 00000000..62ca44e7 --- /dev/null +++ b/scripts/git_test.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +./git_fetch.sh ssh fotonauts MongoHub-Mac master mongohub + +cd mongohub +../update_submodule.sh fotonauts mongo-objc-driver ragel Libraries/mongo-objc-driver diff --git a/scripts/update_submodule.sh b/scripts/update_submodule.sh new file mode 100755 index 00000000..f12f3964 --- /dev/null +++ b/scripts/update_submodule.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -xeu + +submodule_owner="$1" +submodule_name="$2" +submodule_branch="$3" +submodule_path="$4" + +pwd +origin_url=`git config --get remote.origin.url` || true +if [ "${origin_url:0:8}" = "https://" ] ; then + protocol="http" + tmp=`dirname "${origin_url}"` + github_url=`dirname "${tmp}"` + github_url="${github_url}/" +elif [ "${origin_url:0:7}" = "http://" ] ; then + protocol="http" + tmp=`dirname "${origin_url}"` + github_url=`dirname "${tmp}"` + github_url="${github_url}/" +elif [ "${origin_url}" != "" ] ; then + protocol="ssh" + github_url=`echo "${origin_url}" | awk -F: '{ print $1 }'` + github_url="${github_url}:" +else + protocol="file" + github_url="" +fi +sha1=`cat "${submodule_path}.sha1"` + +echo $github_url +echo $sha1 + +if [ "${protocol}" = "ssh" ] ; then + git submodule update --init +elif [ "${protocol}" = "http" ] ; then + if [ -d "${submodule_path}/.git" ] ; then + cd "${submodule_path}" + git fetch + else + rmdir "${submodule_path}" + git clone "${github_url}/${submodule_owner}/${submodule_name}" "${submodule_path}" + cd "${submodule_path}" + git checkout "${sha1}" + fi + git checkout "${sha1}" +else + cd "${submodule_path}" + pwd + if [ ! -f "${submodule_name}.zip" ] ; then + curl -o "${submodule_name}.zip" -L "https://codeload.github.com/jeromelebel/${submodule_name}/zip/${sha1}" + + unzip "${submodule_name}.zip" + rm "${submodule_name}.zip" + submodule_unzip_dir=`ls` + cd "${submodule_unzip_dir}" + mv * .. + cd .. + rm -fr "${submodule_unzip_dir}" + touch "${submodule_name}.zip" + fi +fi