aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2010-07-04 23:58:29 +0000
committerrowanbeentje <rowan@beent.je>2010-07-04 23:58:29 +0000
commit1f17c71b8558565126b32a1d1d3da4e6b0565153 (patch)
treedcb0cc3e98b30db47158417c5c9cb2c796d409fe
parent5721108c443af0ed72341e68d61eb7be3380199a (diff)
downloadsequelpro-1f17c71b8558565126b32a1d1d3da4e6b0565153.tar.gz
sequelpro-1f17c71b8558565126b32a1d1d3da4e6b0565153.tar.bz2
sequelpro-1f17c71b8558565126b32a1d1d3da4e6b0565153.zip
Localisation support improvements:
- Add support for localizing table column header cell strings - Add support for automatically translating nibs loaded via the combination of [[NSNib alloc] init...] and [NSNib instantiateNibWithOwner:topLevelObjects:]. This loading method is required for various non-document based setups or dynamic loading.
-rw-r--r--Source/DMLocalizedNib.m135
-rw-r--r--Source/DMLocalizedNibBundle.m5
-rw-r--r--sequel-pro.xcodeproj/project.pbxproj4
3 files changed, 144 insertions, 0 deletions
diff --git a/Source/DMLocalizedNib.m b/Source/DMLocalizedNib.m
new file mode 100644
index 00000000..93c37bd5
--- /dev/null
+++ b/Source/DMLocalizedNib.m
@@ -0,0 +1,135 @@
+// DMLocalizedNib.m
+//
+// Created by Rowan Beentje on July 4, 2010
+// Copyright © 2010 Rowan Beentje. All rights reserved except as below:
+// This code is provided as-is, with no warranties or anything. You may use it in your projects as you wish, but you must leave this comment block (credits and copyright) intact. That's the only restriction -- Rowan Beentje otherwise grants you a fully-paid, worldwide, transferrable license to use this code as you see fit, including but not limited to making derivative works.
+
+
+#import <Cocoa/Cocoa.h>
+#import <objc/runtime.h>
+
+
+@interface NSNib (DMLocalizedNib)
+- (id)deliciousInitWithNibNamed:(NSString *)nibName bundle:(NSBundle *)bundle;
+- (id)deliciousInitWithContentsOfURL:(NSURL *)nibFileURL;
+- (BOOL)deliciousInstantiateNibWithOwner:(id)owner topLevelObjects:(NSArray **)topLevelObjects;
+- (void)setDeliciousNibName:(NSString *)nibName;
+- (NSString *)deliciousNibName;
+- (void)deliciousDealloc;
+@end
+
+static NSMutableDictionary *deliciousNibNames = nil;
+
+@implementation NSNib (DMLocalizedNib)
+
+#pragma mark NSObject
+
+/**
+ * On NSNib class load, swizzle in our overrides of the basic methods.
+ */
++ (void)load;
+{
+ NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init];
+ if (self == [NSNib class]) {
+ method_exchangeImplementations(class_getInstanceMethod(self, @selector(initWithNibNamed:bundle:)), class_getInstanceMethod(self, @selector(deliciousInitWithNibNamed:bundle:)));
+ method_exchangeImplementations(class_getInstanceMethod(self, @selector(initWithContentsOfURL:)), class_getInstanceMethod(self, @selector(deliciousInitWithContentsOfURL:)));
+ method_exchangeImplementations(class_getInstanceMethod(self, @selector(instantiateNibWithOwner:topLevelObjects:)), class_getInstanceMethod(self, @selector(deliciousInstantiateNibWithOwner:topLevelObjects:)));
+ method_exchangeImplementations(class_getInstanceMethod(self, @selector(dealloc)), class_getInstanceMethod(self, @selector(deliciousDealloc)));
+ }
+ [autoreleasePool release];
+}
+
+
+#pragma mark API
+
+/**
+ * An init method swizzled with the original method, storing the base
+ * name passed into the init method for later reuse.
+ */
+- (id)deliciousInitWithNibNamed:(NSString *)nibName bundle:(NSBundle *)bundle
+{
+
+ // Instantiate the nib using the original (swizzled) call
+ id nib = [self deliciousInitWithNibNamed:nibName bundle:bundle];
+ if (nib) {
+ [self setDeliciousNibName:nibName];
+ }
+
+ return nib;
+}
+
+/**
+ * An init method swizzled with the original method, extracting and
+ * storing the base name of the nib for later reuse.
+ */
+- (id)deliciousInitWithContentsOfURL:(NSURL *)nibFileURL
+{
+
+ // Instantiate the nib using the original (swizzled) call
+ id nib = [self deliciousInitWithContentsOfURL:nibFileURL];
+ if (nib) {
+
+ // Extract the filename from the URL
+ NSArray *urlParts = [[nibFileURL path] componentsSeparatedByString:@"/"];
+ NSString *nibName = [urlParts lastObject];
+ [self setDeliciousNibName:nibName];
+ }
+
+ return nib;
+}
+
+/**
+ * An instatiation method swizzled with the original method. Instantiates
+ * as before, and then if it can find a .strings file in a preferred language
+ * to localize the instantiated objects with, does so.
+ */
+- (BOOL)deliciousInstantiateNibWithOwner:(id)owner topLevelObjects:(NSArray **)topLevelObjects
+{
+ if ([self deliciousInstantiateNibWithOwner:owner topLevelObjects:topLevelObjects]) {
+
+ // Look for a localised strings table file based on the original nib name,
+ // translating only if one was found and it wasn't English
+ NSString *localizedStringsTablePath = [[NSBundle mainBundle] pathForResource:[self deliciousNibName] ofType:@"strings"];
+ if (localizedStringsTablePath && ![[[localizedStringsTablePath stringByDeletingLastPathComponent] lastPathComponent] isEqualToString:@"English.lproj"]) {
+ [NSBundle _localizeStringsInObject:*topLevelObjects table:[self deliciousNibName]];
+ }
+
+ return YES;
+ }
+
+ return NO;
+}
+
+/**
+ * Store the nib name that was used when setting up the nib, which will
+ * also be used to look up the .strings file name
+ */
+- (void)setDeliciousNibName:(NSString *)nibName
+{
+ if (!deliciousNibNames) {
+ deliciousNibNames = [[NSMutableDictionary alloc] init];
+ }
+ [deliciousNibNames setObject:nibName forKey:[NSValue valueWithPointer:self]];
+}
+
+/**
+ * Retrieve the nib name to look up the matching .strings file name
+ */
+- (NSString *)deliciousNibName
+{
+ return [deliciousNibNames objectForKey:[NSValue valueWithPointer:self]];
+}
+
+/**
+ * Swizzled deallocate to release custom stores.
+ */
+- (void)deliciousDealloc
+{
+ if (deliciousNibNames) {
+ [deliciousNibNames removeObjectForKey:[NSValue valueWithPointer:self]];
+ if (![deliciousNibNames count]) [deliciousNibNames release], deliciousNibNames = nil;
+ }
+ [self deliciousDealloc];
+}
+
+@end \ No newline at end of file
diff --git a/Source/DMLocalizedNibBundle.m b/Source/DMLocalizedNibBundle.m
index e9200bc0..428f8899 100644
--- a/Source/DMLocalizedNibBundle.m
+++ b/Source/DMLocalizedNibBundle.m
@@ -164,6 +164,11 @@
[self _localizeStringsInObject:[segmentedControl menuForSegment:segmentIndex] table:table];
}
+ } else if ([view isKindOfClass:[NSTableView class]]) {
+ for (NSTableColumn *column in [view tableColumns]) {
+ [self _localizeStringValueOfObject:[column headerCell] table:table];
+ }
+
} else
[self _localizeStringsInObject:[control cell] table:table];
diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj
index b45bdf0f..3748ca85 100644
--- a/sequel-pro.xcodeproj/project.pbxproj
+++ b/sequel-pro.xcodeproj/project.pbxproj
@@ -186,6 +186,7 @@
588B2CCA0FE5641E00EC5FC0 /* ssh-disconnected.png in Resources */ = {isa = PBXBuildFile; fileRef = 588B2CC70FE5641E00EC5FC0 /* ssh-disconnected.png */; };
589235321020C1230011DE00 /* SPHistoryController.m in Sources */ = {isa = PBXBuildFile; fileRef = 589235301020C1230011DE00 /* SPHistoryController.m */; };
589582151154F8F400EDCC28 /* SPMainThreadTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = 589582141154F8F400EDCC28 /* SPMainThreadTrampoline.m */; };
+ 589ED05B11E0ACD100C1DCEA /* DMLocalizedNib.m in Sources */ = {isa = PBXBuildFile; fileRef = 589ED05A11E0ACD100C1DCEA /* DMLocalizedNib.m */; };
58A8A72711A0149100B95749 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 58A8A72611A0149100B95749 /* MainWindow.xib */; };
58A8A79111A036C000B95749 /* SPWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 58A8A79011A036C000B95749 /* SPWindowController.m */; };
58B9074A11BD9B34000826E5 /* overflowImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 58B9070A11BD9B34000826E5 /* overflowImage.png */; };
@@ -719,6 +720,7 @@
589235311020C1230011DE00 /* SPHistoryController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPHistoryController.h; sourceTree = "<group>"; };
589582131154F8F400EDCC28 /* SPMainThreadTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPMainThreadTrampoline.h; sourceTree = "<group>"; };
589582141154F8F400EDCC28 /* SPMainThreadTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPMainThreadTrampoline.m; sourceTree = "<group>"; };
+ 589ED05A11E0ACD100C1DCEA /* DMLocalizedNib.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DMLocalizedNib.m; sourceTree = "<group>"; };
58A8A72411A0148400B95749 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainWindow.xib; sourceTree = "<group>"; };
58A8A78F11A036C000B95749 /* SPWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPWindowController.h; sourceTree = "<group>"; };
58A8A79011A036C000B95749 /* SPWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPWindowController.m; sourceTree = "<group>"; };
@@ -1916,6 +1918,7 @@
isa = PBXGroup;
children = (
58B909A411C3B919000826E5 /* DMLocalizedNibBundle.m */,
+ 589ED05A11E0ACD100C1DCEA /* DMLocalizedNib.m */,
58B9095B11C3A3EC000826E5 /* xibLocalizationPostprocessor.m */,
);
name = Localization;
@@ -2520,6 +2523,7 @@
173C839511AAD32A00B8B084 /* SPXMLExporterDelegate.m in Sources */,
58B909A511C3B919000826E5 /* DMLocalizedNibBundle.m in Sources */,
17A7773411C52D8E001E27B4 /* SPIndexesController.m in Sources */,
+ 589ED05B11E0ACD100C1DCEA /* DMLocalizedNib.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};