aboutsummaryrefslogtreecommitdiff
path: root/AppKit/GTMUILocalizer.m
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-04-15 19:45:40 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-04-15 19:45:40 +0000
commitb8787b78e65a3b1ed18c406b0e2ea5232af7ac14 (patch)
tree91f8fdd516e97bec098e78081e8fd34e65eb432a /AppKit/GTMUILocalizer.m
parentf19d4cb3d479776d13e245009761d52841a09870 (diff)
[Author: dmaclach]
Added GTMUILocalizer for localizing UIs. 100% code coverage from tests. DELTA=1956 (1940 added, 8 deleted, 8 changed) R=thomasvl
Diffstat (limited to 'AppKit/GTMUILocalizer.m')
-rw-r--r--AppKit/GTMUILocalizer.m218
1 files changed, 218 insertions, 0 deletions
diff --git a/AppKit/GTMUILocalizer.m b/AppKit/GTMUILocalizer.m
new file mode 100644
index 0000000..cfeb401
--- /dev/null
+++ b/AppKit/GTMUILocalizer.m
@@ -0,0 +1,218 @@
+//
+// GTMUILocalizer.m
+//
+// Copyright 2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import "GTMDefines.h"
+#import "GTMUILocalizer.h"
+
+@implementation GTMUILocalizer
+- (id)initWithBundle:(NSBundle *)bundle {
+ if ((self = [super init])) {
+ bundle_ = [bundle retain];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [bundle_ release];
+ [super dealloc];
+}
+
+- (void)awakeFromNib {
+ if (owner_) {
+ NSBundle *newBundle = [self bundleForOwner:owner_];
+ bundle_ = [newBundle retain];
+ [self localizeObject:owner_ recursively:YES];
+ [self localizeObject:otherObjectToLocalize_ recursively:YES];
+ [self localizeObject:yetAnotherObjectToLocalize_ recursively:YES];
+ } else {
+ _GTMDevLog(@"Expected an owner_ set for %@", self);
+ }
+}
+
+- (NSBundle *)bundleForOwner:(id)owner {
+ NSBundle *newBundle = nil;
+ if (owner) {
+ Class class = NSClassFromString(@"NSViewController");
+ if ([owner isKindOfClass:class]) {
+ newBundle = [owner performSelector:@selector(nibBundle)];
+ } else {
+ class = [NSWindowController class];
+ if ([owner isKindOfClass:class]
+ && ![owner isMemberOfClass:class]) {
+ newBundle = [NSBundle bundleForClass:[owner class]];
+ }
+ }
+ if (!newBundle) {
+ newBundle = [NSBundle mainBundle];
+ }
+ }
+ return newBundle;
+}
+
+- (NSString *)localizedStringForString:(NSString *)string {
+ NSString *localized = nil;
+ if (bundle_ && [string hasPrefix:@"^"]) {
+ NSString *notFoundValue = @"__GTM_NOT_FOUND__";
+ NSString *key = [string substringFromIndex:1];
+ localized = [bundle_ localizedStringForKey:key
+ value:notFoundValue
+ table:nil];
+ if ([localized isEqualToString:notFoundValue]) {
+ localized = nil;
+ }
+ }
+ return localized;
+}
+
+- (void)localizeObject:(id)object recursively:(BOOL)recursive {
+ if (object) {
+ if ([object isKindOfClass:NSClassFromString(@"NSViewController")]) {
+ NSView *view = [object view];
+ [self localizeView:view recursively:recursive];
+ } else if ([object isKindOfClass:[NSWindowController class]]) {
+ NSWindow *window = [object window];
+ [self localizeWindow:window recursively:recursive];
+ } else if ([object isKindOfClass:[NSMenu class]]) {
+ [self localizeMenu:(NSMenu *)object recursively:recursive];
+ } else if ([object isKindOfClass:[NSWindow class]]) {
+ [self localizeWindow:(NSWindow *)object recursively:recursive];
+ } else if ([object isKindOfClass:[NSView class]]) {
+ [self localizeView:(NSView *)object recursively:recursive];
+ } else if ([object isKindOfClass:[NSApplication class]]) {
+ // Do the main menu
+ NSMenu *menu = [object mainMenu];
+ [self localizeMenu:menu recursively:recursive];
+ }
+ }
+}
+
+- (void)localizeWindow:(NSWindow *)window recursively:(BOOL)recursive {
+ NSString *title = [window title];
+ NSString *localizedTitle = [self localizedStringForString:title];
+ if (localizedTitle) {
+ [window setTitle:localizedTitle];
+ }
+ if (recursive) {
+ NSView *content = [window contentView];
+ [self localizeView:content recursively:recursive];
+ }
+}
+
+- (void)localizeView:(NSView *)view recursively:(BOOL)recursive {
+ if (view) {
+ // First do tooltips
+ NSString *toolTip = [view toolTip];
+ if (toolTip) {
+ NSString *localizedToolTip = [self localizedStringForString:toolTip];
+ if (localizedToolTip) {
+ [view setToolTip:localizedToolTip];
+ }
+ }
+
+ // Then do accessibility stuff
+ NSArray *supportedAttrs = [view accessibilityAttributeNames];
+ if ([supportedAttrs containsObject:NSAccessibilityHelpAttribute]) {
+ NSString *accessibilityHelp
+ = [view accessibilityAttributeValue:NSAccessibilityHelpAttribute];
+ if (accessibilityHelp) {
+ NSString *localizedAccessibilityHelp
+ = [self localizedStringForString:accessibilityHelp];
+ if (localizedAccessibilityHelp) {
+ [view accessibilitySetValue:localizedAccessibilityHelp
+ forAttribute:NSAccessibilityHelpAttribute];
+ }
+ }
+ }
+
+ if ([supportedAttrs containsObject:NSAccessibilityDescriptionAttribute]) {
+ NSString *accessibilityDesc
+ = [view accessibilityAttributeValue:NSAccessibilityDescriptionAttribute];
+ if (accessibilityDesc) {
+ NSString *localizedAccessibilityDesc
+ = [self localizedStringForString:accessibilityDesc];
+ if (localizedAccessibilityDesc) {
+ [view accessibilitySetValue:localizedAccessibilityDesc
+ forAttribute:NSAccessibilityDescriptionAttribute];
+ }
+ }
+ }
+
+ // Then do titles
+ if ([view isKindOfClass:[NSTextField class]]) {
+ NSString *title = [(NSTextField *)view stringValue];
+ NSString *localizedTitle = [self localizedStringForString:title];
+ if (localizedTitle) {
+ [(NSTextField *)view setStringValue:localizedTitle];
+ }
+ } else if ([view respondsToSelector:@selector(title)]
+ && [view respondsToSelector:@selector(setTitle:)]) {
+ NSString *title = [view performSelector:@selector(title)];
+ if (title) {
+ NSString *localizedTitle = [self localizedStringForString:title];
+ if (localizedTitle) {
+ [view performSelector:@selector(setTitle:) withObject:localizedTitle];
+ }
+ }
+ } else if ([view respondsToSelector:@selector(tabViewItems)]) {
+ NSArray *items = [view performSelector:@selector(tabViewItems)];
+ NSEnumerator *itemEnum = [items objectEnumerator];
+ NSTabViewItem *item = nil;
+ while ((item = [itemEnum nextObject])) {
+ NSString *label = [item label];
+ NSString *localizedLabel = [self localizedStringForString:label];
+ if (localizedLabel) {
+ [item setLabel:localizedLabel];
+ }
+ if (recursive) {
+ [self localizeView:[item view] recursively:recursive];
+ }
+ }
+ }
+ [self localizeMenu:[view menu] recursively:recursive];
+ if (recursive) {
+ NSArray *subviews = [view subviews];
+ NSView *subview = nil;
+ GTM_FOREACH_OBJECT(subview, subviews) {
+ [self localizeView:subview recursively:recursive];
+ }
+ }
+ }
+}
+
+- (void)localizeMenu:(NSMenu *)menu recursively:(BOOL)recursive {
+ if (menu) {
+ NSString *title = [menu title];
+ NSString *localizedTitle = [self localizedStringForString:title];
+ if (localizedTitle) {
+ [menu setTitle:localizedTitle];
+ }
+ NSArray *menuItems = [menu itemArray];
+ NSMenuItem *menuItem = nil;
+ GTM_FOREACH_OBJECT(menuItem, menuItems) {
+ title = [menuItem title];
+ localizedTitle = [self localizedStringForString:title];
+ if (localizedTitle) {
+ [menuItem setTitle:localizedTitle];
+ }
+ if (recursive) {
+ [self localizeMenu:[menuItem submenu] recursively:recursive];
+ }
+ }
+ }
+}
+@end