├── QuickLocalization
├── en.lproj
│ └── InfoPlist.strings
├── icon.icns
├── QuickLocalization-Prefix.pch
├── QuickLocalization.h
├── QLMenuGenerator.h
├── OLSettingController.h
├── QLConstString.h
├── MenuItemData.plist
├── QLConstString.m
├── QuickLocalization-Info.plist
├── QLMenuGenerator.m
├── RCXcode.h
├── QLXcodeHelper.h
├── QLIDEHelper.h
├── RCXcode.m
├── QLXcodeHelper.m
├── OLSettingController.m
├── QLIDEHelper.m
├── QuickLocalization.m
└── OLSettingController.xib
├── Xcode_Quick_Localization_Settings.png
├── QuickLocalization.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── .gitignore
└── README.md
/QuickLocalization/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/QuickLocalization/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tappollo/Xcode-Quick-Localization/HEAD/QuickLocalization/icon.icns
--------------------------------------------------------------------------------
/Xcode_Quick_Localization_Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tappollo/Xcode-Quick-Localization/HEAD/Xcode_Quick_Localization_Settings.png
--------------------------------------------------------------------------------
/QuickLocalization.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/QuickLocalization/QuickLocalization-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'QuickLocalization' target in the 'QuickLocalization' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "QLConstString.h"
8 | #endif
9 |
--------------------------------------------------------------------------------
/QuickLocalization/QuickLocalization.h:
--------------------------------------------------------------------------------
1 | //
2 | // QuickLocalization.h
3 | // QuickLocalization
4 | //
5 | // Created by Zitao Xiong on 5/12/13.
6 | // Copyright (c) 2013 nanaimostudio. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface QuickLocalization : NSObject
12 |
13 | @end
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.mkm
2 | # Xcode
3 | #
4 | build/
5 | *.pbxuser
6 | !default.pbxuser
7 | *.mode1v3
8 | !default.mode1v3
9 | *.mode2v3
10 | !default.mode2v3
11 | *.perspectivev3
12 | !default.perspectivev3
13 | xcuserdata
14 | *.xccheckout
15 | *.moved-aside
16 | DerivedData
17 | *.hmap
18 | *.ipa
19 | *.xcuserstate
20 |
21 |
--------------------------------------------------------------------------------
/QuickLocalization/QLMenuGenerator.h:
--------------------------------------------------------------------------------
1 | //
2 | // AMMenuGenerator.h
3 | // AMMethod2Implement
4 | //
5 | // Created by JohnnyLiu on 15/4/1.
6 | // Copyright (c) 2015年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface QLMenuGenerator : NSObject
12 |
13 | + (void)generateMenuItems:(NSBundle *)bundle version:(NSString *)version target:(id)target;
14 | + (NSUInteger)getKeyEquivalentModifierMaskWithKey:(NSString *)key;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/QuickLocalization/OLSettingController.h:
--------------------------------------------------------------------------------
1 | //
2 | // OLSettingController.h
3 | // QuickLocalization
4 | //
5 | // Created by Zitao Xiong on 7/18/15.
6 | // Copyright (c) 2015 nanaimostudio. All rights reserved.
7 | //
8 |
9 | #import
10 | extern NSUInteger QL_CountOccurentOfStringWithSubString(NSString *str, NSString *subString);
11 |
12 | @interface OLSettingController : NSWindowController
13 | @property (nonatomic, weak) NSBundle *bundle;
14 | + (void)registerFormatStringDefaults;
15 | @end
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Xcode-Quick-Localization
2 | ========================
3 |
4 | Xcode Plugin to Convert `@"content"` to `NSLocalizedString(@"content", @"content")`
5 |
6 | Support Swift string, Convert `"content"` to `NSLocalizedString("content", comment:"content")`
7 |
8 | 
9 | How To Use
10 | ==========
11 |
12 | Select any line in xcode, press option + shift + d. String will be converted to localized string.
13 |
14 | You can also access it under Edit -> Quick Localization
15 |
16 |
--------------------------------------------------------------------------------
/QuickLocalization/QLConstString.h:
--------------------------------------------------------------------------------
1 | //
2 | // AMConstString.h
3 | // AMMethod2Implement
4 | //
5 | // Created by JohnnyLiu on 15/4/1.
6 | // Copyright (c) 2015年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | extern NSString * const kMenuRootMenuTitle;
13 | extern NSString * const kMenuPluginTitle;
14 | extern NSString * const kMenuSubMenuItems;
15 | extern NSString * const kMenuTitle;
16 | extern NSString * const kMenuSelector;
17 | extern NSString * const kMenuShortcut;
18 | extern NSString * const kMenuKeyMask;
19 | extern NSString * const kMenuKeyEquivalent;
20 |
21 | extern NSString * const kMenuActionTitle;
22 |
23 | extern NSString * const kQLFormatStringKey;
24 | extern NSString * const kQLFormatStringCommentSameKey;
25 | extern NSString * const kQLFormatStringSwiftSyntax;
26 |
27 | extern NSString * const kQLFormatStringCommentValueKey;
28 | extern NSString * const kQLFormatStringTableNameValueKey;
29 | extern NSString * const kQLFormatStringBundleValueKey;
30 | extern NSString * const kQLFormatStringValueValueKey;
31 |
32 |
--------------------------------------------------------------------------------
/QuickLocalization/MenuItemData.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | rootMenuTitle
6 | Edit
7 | pluginTitle
8 | Quick Localization
9 | subMenuItems
10 |
11 |
12 | title
13 | Quick Localization
14 | selector
15 | quickLocalization:
16 | shortcut
17 |
18 | keyMask
19 |
20 | shift
21 | alt
22 |
23 | keyEquivalent
24 | d
25 |
26 |
27 |
28 | title
29 | Setting
30 | selector
31 | showSettingWindow
32 |
33 |
34 | title
35 | Plugin version %@
36 | selector
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/QuickLocalization/QLConstString.m:
--------------------------------------------------------------------------------
1 | //
2 | // AMConstString.m
3 | // AMMethod2Implement
4 | //
5 | // Created by JohnnyLiu on 15/4/1.
6 | // Copyright (c) 2015年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import "QLConstString.h"
10 |
11 |
12 | NSString * const kMenuRootMenuTitle = @"rootMenuTitle";
13 | NSString * const kMenuPluginTitle = @"pluginTitle";
14 | NSString * const kMenuSubMenuItems = @"subMenuItems";
15 | NSString * const kMenuTitle = @"title";
16 | NSString * const kMenuSelector = @"selector";
17 | NSString * const kMenuShortcut = @"shortcut";
18 | NSString * const kMenuKeyMask = @"keyMask";
19 | NSString * const kMenuKeyEquivalent = @"keyEquivalent";
20 |
21 | NSString * const kMenuActionTitle = @"Implement Mehod";
22 |
23 | NSString * const kQLFormatStringKey = @"KQLFormatStringKey";
24 | NSString * const kQLFormatStringCommentSameKey = @"KQLFormatStringKey";
25 | NSString * const kQLFormatStringSwiftSyntax = @"kQLFormatStringSwiftSyntax";
26 |
27 |
28 |
29 | NSString * const kQLFormatStringCommentValueKey = @"kQLFormatStringCommentValueKey";
30 | NSString * const kQLFormatStringTableNameValueKey = @"kQLFormatStringTableNameValueKey";
31 | NSString * const kQLFormatStringBundleValueKey = @"kQLFormatStringBundleValueKey";
32 | NSString * const kQLFormatStringValueValueKey = @"kQLFormatStringValueValueKey";
--------------------------------------------------------------------------------
/QuickLocalization/QuickLocalization-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 | icon.icns
11 | CFBundleIdentifier
12 | com.nanaimostudio.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | CFPlugInDynamicRegisterFunction
26 |
27 | CFPlugInDynamicRegistration
28 | NO
29 | CFPlugInFactories
30 |
31 | 00000000-0000-0000-0000-000000000000
32 | MyFactoryFunction
33 |
34 | CFPlugInTypes
35 |
36 | 00000000-0000-0000-0000-000000000000
37 |
38 | 00000000-0000-0000-0000-000000000000
39 |
40 |
41 | CFPlugInUnloadFunction
42 |
43 | DVTPlugInCompatibilityUUIDs
44 |
45 | AD68E85B-441B-4301-B564-A45E4919A6AD
46 | A2E4D43F-41F4-4FB9-BB94-7177011C9AED
47 | 37B30044-3B14-46BA-ABAA-F01000C27B63
48 | 63FC1C47-140D-42B0-BB4D-A10B2D225574
49 | C4A681B0-4A26-480E-93EC-1218098B9AA0
50 | FEC992CC-CA4A-4CFD-8881-77300FCB848A
51 | 992275C1-432A-4CF7-B659-D84ED6D42D3F
52 | A16FF353-8441-459E-A50C-B071F53F51B7
53 | 9F75337B-21B4-4ADC-B558-F9CADF7073A7
54 | 8DC44374-2B35-4C57-A6FE-2AD66A36AAD9
55 | E969541F-E6F9-4D25-8158-72DC3545A6C6
56 | AABB7188-E14E-4433-AD3B-5CD791EAD9A3
57 | 7FDF5C7A-131F-4ABB-9EDC-8C5F8F0B8A90
58 | CC0D0F4F-05B3-431A-8F33-F84AFCB2C651
59 | 0420B86A-AA43-4792-9ED0-6FE0F2B16A13
60 | 7265231C-39B4-402C-89E1-16167C4CC990
61 | F41BD31E-2683-44B8-AE7F-5F09E919790E
62 | ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C
63 |
64 | XC4Compatible
65 |
66 | XCGCReady
67 |
68 | XCPluginHasUI
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/QuickLocalization/QLMenuGenerator.m:
--------------------------------------------------------------------------------
1 | //
2 | // AMMenuGenerator.m
3 | // AMMethod2Implement
4 | //
5 | // Created by JohnnyLiu on 15/4/1.
6 | // Copyright (c) 2015年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import "QLMenuGenerator.h"
10 | #import "RCXcode.h"
11 |
12 | @implementation QLMenuGenerator
13 |
14 | + (void)generateMenuItems:(NSBundle *)bundle version:(NSString *)version target:(id)target
15 | {
16 | NSString *dataPath = [bundle pathForResource:@"MenuItemData" ofType:@"plist"];
17 | NSDictionary *menuData = [NSDictionary dictionaryWithContentsOfFile:dataPath];
18 | NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:menuData[kMenuRootMenuTitle]];
19 |
20 | if (menuItem) {
21 |
22 | [[menuItem submenu] addItem:[NSMenuItem separatorItem]];
23 | NSString *title = menuData[kMenuPluginTitle];
24 | NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""];
25 | [[menuItem submenu] addItem:actionMenuItem];
26 | NSMenu* submenu = [[NSMenu alloc] init];
27 | [actionMenuItem setSubmenu:submenu];
28 | for (NSDictionary *item in menuData[kMenuSubMenuItems]) {
29 | NSString *subMenuTitle = item[kMenuTitle];
30 | if ([subMenuTitle rangeOfString:@"%@"].length > 0) {
31 | subMenuTitle = [NSString stringWithFormat:subMenuTitle, version];
32 | }
33 |
34 | NSString *selectorString = item[kMenuSelector];
35 | SEL selector = nil;
36 | if (selectorString != nil && selectorString.length > 0) {
37 | selector = NSSelectorFromString(selectorString);
38 | }
39 | NSString *keyEquivalent = @"";
40 | if (item[kMenuShortcut][kMenuKeyEquivalent] != nil) {
41 | keyEquivalent = item[kMenuShortcut][kMenuKeyEquivalent];
42 | }
43 |
44 | NSArray *maskArray = item[kMenuShortcut][kMenuKeyMask];
45 | NSDictionary *userMenu = [[NSUserDefaults standardUserDefaults] objectForKey:kMenuActionTitle];
46 | if (userMenu != nil) {
47 | keyEquivalent = userMenu[kMenuKeyEquivalent];
48 | maskArray = userMenu[kMenuShortcut];
49 | }
50 |
51 | NSMenuItem *subMenuItem = [[NSMenuItem alloc] initWithTitle:subMenuTitle action:selector keyEquivalent:keyEquivalent];
52 |
53 | if (maskArray.count == 1) {
54 | subMenuItem.keyEquivalentModifierMask = [QLMenuGenerator getKeyEquivalentModifierMaskWithKey:maskArray[0]];
55 | }else if(maskArray.count == 2) {
56 | subMenuItem.keyEquivalentModifierMask = [QLMenuGenerator getKeyEquivalentModifierMaskWithKey:maskArray[0]] |
57 | [QLMenuGenerator getKeyEquivalentModifierMaskWithKey:maskArray[1]];
58 | }
59 | subMenuItem.target = target;
60 | [submenu addItem:subMenuItem];
61 | }
62 |
63 | }
64 | }
65 |
66 | + (NSUInteger)getKeyEquivalentModifierMaskWithKey:(NSString *)key
67 | {
68 | NSDictionary *keyMaskMap = @{@"ctrl":@(NSControlKeyMask),
69 | @"shift":@(NSShiftKeyMask),
70 | @"command":@(NSCommandKeyMask),
71 | @"alt":@(NSAlternateKeyMask)};
72 | return [keyMaskMap[key] integerValue];
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/QuickLocalization/RCXcode.h:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Created by Zitao on 12/05/13.
4 | //
5 | //
6 |
7 | #import
8 |
9 | @interface DVTTextDocumentLocation : NSObject
10 | @property (readonly) NSRange characterRange;
11 | @property (readonly) NSRange lineRange;
12 | @end
13 |
14 | @interface DVTTextPreferences : NSObject
15 | + (id)preferences;
16 | @property BOOL trimWhitespaceOnlyLines;
17 | @property BOOL trimTrailingWhitespace;
18 | @property BOOL useSyntaxAwareIndenting;
19 | @end
20 |
21 | @interface DVTSourceTextStorage : NSTextStorage
22 | - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)string withUndoManager:(id)undoManager;
23 | - (NSRange)lineRangeForCharacterRange:(NSRange)range;
24 | - (NSRange)characterRangeForLineRange:(NSRange)range;
25 | - (void)indentCharacterRange:(NSRange)range undoManager:(id)undoManager;
26 | @end
27 |
28 | @interface DVTFileDataType : NSObject
29 | @property (readonly) NSString *identifier;
30 | @end
31 |
32 | @interface DVTFilePath : NSObject
33 | @property (readonly) NSURL *fileURL;
34 | @property (readonly) DVTFileDataType *fileDataTypePresumed;
35 | @end
36 |
37 | @interface IDEContainerItem : NSObject
38 | @property (readonly) DVTFilePath *resolvedFilePath;
39 | @end
40 |
41 | @interface IDEGroup : IDEContainerItem
42 |
43 | @end
44 |
45 | @interface IDEFileReference : IDEContainerItem
46 |
47 | @end
48 |
49 | @interface IDENavigableItem : NSObject
50 | @property (readonly) IDENavigableItem *parentItem;
51 | @property (readonly) id representedObject;
52 | @end
53 |
54 | @interface IDEFileNavigableItem : IDENavigableItem
55 | @property (readonly) DVTFileDataType *documentType;
56 | @property (readonly) NSURL *fileURL;
57 | @end
58 |
59 | @interface IDEStructureNavigator : NSObject
60 | @property (retain) NSArray *selectedObjects;
61 | @end
62 |
63 | @interface IDENavigableItemCoordinator : NSObject
64 | - (id)structureNavigableItemForDocumentURL:(id)arg1 inWorkspace:(id)arg2 error:(id *)arg3;
65 | @end
66 |
67 | @interface IDENavigatorArea : NSObject
68 | - (id)currentNavigator;
69 | @end
70 |
71 | @interface IDEWorkspaceTabController : NSObject
72 | @property (readonly) IDENavigatorArea *navigatorArea;
73 | @end
74 |
75 | @interface IDEDocumentController : NSDocumentController
76 | + (id)editorDocumentForNavigableItem:(id)arg1;
77 | + (id)retainedEditorDocumentForNavigableItem:(id)arg1 error:(id *)arg2;
78 | + (void)releaseEditorDocument:(id)arg1;
79 | @end
80 |
81 | @interface IDESourceCodeDocument : NSDocument
82 | - (DVTSourceTextStorage *)textStorage;
83 | - (NSUndoManager *)undoManager;
84 | @end
85 |
86 | @interface IDESourceCodeComparisonEditor : NSObject
87 | @property (readonly) NSTextView *keyTextView;
88 | @property (retain) NSDocument *primaryDocument;
89 | @end
90 |
91 | @interface IDESourceCodeEditor : NSObject
92 | @property (retain) NSTextView *textView;
93 | - (IDESourceCodeDocument *)sourceCodeDocument;
94 | @end
95 |
96 | @interface IDEEditorContext : NSObject
97 | - (id)editor; // returns the current editor. If the editor is the code editor, the class is `IDESourceCodeEditor`
98 | @end
99 |
100 | @interface IDEEditorArea : NSObject
101 | - (IDEEditorContext *)lastActiveEditorContext;
102 | @end
103 |
104 | @interface IDEWorkspaceWindowController : NSObject
105 | @property (readonly) IDEWorkspaceTabController *activeWorkspaceTabController;
106 | - (IDEEditorArea *)editorArea;
107 | @end
108 |
109 | @interface IDEWorkspace : NSObject
110 | @property (readonly) DVTFilePath *representingFilePath;
111 | @end
112 |
113 | @interface IDEWorkspaceDocument : NSDocument
114 | @property (readonly) IDEWorkspace *workspace;
115 | @end
116 |
117 | @interface RCXcode : NSObject
118 | + (IDEWorkspaceDocument *)currentWorkspaceDocument;
119 | + (IDESourceCodeDocument *)currentSourceCodeDocument;
120 | + (NSTextView *)currentSourceCodeTextView;
121 | + (NSArray *)selectedObjCFileNavigableItems;
122 | @end
123 |
--------------------------------------------------------------------------------
/QuickLocalization/QLXcodeHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // QLXcodeHelper.h
3 | //
4 | //
5 | // Created by Mellong on 14-4-13.
6 | // Copyright (c) 2014年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DVTTextDocumentLocation : NSObject
12 | @property (readonly) NSRange characterRange;
13 | @property (readonly) NSRange lineRange;
14 | @end
15 |
16 | @interface DVTTextPreferences : NSObject
17 | + (id)preferences;
18 | @property BOOL trimWhitespaceOnlyLines;
19 | @property BOOL trimTrailingWhitespace;
20 | @property BOOL useSyntaxAwareIndenting;
21 | @end
22 |
23 | @interface DVTSourceTextStorage : NSTextStorage
24 | - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)string withUndoManager:(id)undoManager;
25 | - (NSRange)lineRangeForCharacterRange:(NSRange)range;
26 | - (NSRange)characterRangeForLineRange:(NSRange)range;
27 | - (void)indentCharacterRange:(NSRange)range undoManager:(id)undoManager;
28 | @end
29 |
30 | @interface DVTFileDataType : NSObject
31 | @property (readonly) NSString *identifier;
32 | @end
33 |
34 | @interface DVTFilePath : NSObject
35 | @property (readonly) NSURL *fileURL;
36 | @property (readonly) DVTFileDataType *fileDataTypePresumed;
37 | @end
38 |
39 | @interface IDEContainerItem : NSObject
40 | @property (readonly) DVTFilePath *resolvedFilePath;
41 | @end
42 |
43 | @interface IDEGroup : IDEContainerItem
44 |
45 | @end
46 |
47 | @interface IDEFileReference : IDEContainerItem
48 |
49 | @end
50 |
51 | @interface IDENavigableItem : NSObject
52 | @property (readonly) IDENavigableItem *parentItem;
53 | @property (readonly) id representedObject;
54 | @end
55 |
56 | @interface IDEFileNavigableItem : IDENavigableItem
57 | @property (readonly) DVTFileDataType *documentType;
58 | @property (readonly) NSURL *fileURL;
59 | @end
60 |
61 | @interface IDEStructureNavigator : NSObject
62 | @property (retain) NSArray *selectedObjects;
63 | @end
64 |
65 | @interface IDENavigableItemCoordinator : NSObject
66 | - (id)structureNavigableItemForDocumentURL:(id)arg1 inWorkspace:(id)arg2 error:(id *)arg3;
67 | @end
68 |
69 | @interface IDENavigatorArea : NSObject
70 | - (id)currentNavigator;
71 | @end
72 |
73 | @interface IDEWorkspaceTabController : NSObject
74 | @property (readonly) IDENavigatorArea *navigatorArea;
75 | @end
76 |
77 | @interface IDEDocumentController : NSDocumentController
78 | + (id)editorDocumentForNavigableItem:(id)arg1;
79 | + (id)retainedEditorDocumentForNavigableItem:(id)arg1 error:(id *)arg2;
80 | + (void)releaseEditorDocument:(id)arg1;
81 | @end
82 |
83 | @interface IDESourceCodeDocument : NSDocument
84 | - (DVTSourceTextStorage *)textStorage;
85 | - (NSUndoManager *)undoManager;
86 | @end
87 |
88 | @interface IDESourceCodeComparisonEditor : NSObject
89 | @property (readonly) NSTextView *keyTextView;
90 | @property (retain) NSDocument *primaryDocument;
91 | @end
92 |
93 | @interface IDESourceCodeEditor : NSObject
94 | @property (retain) NSTextView *textView;
95 | - (IDESourceCodeDocument *)sourceCodeDocument;
96 | @end
97 |
98 | @interface IDEEditorContext : NSObject
99 | - (id)editor; // returns the current editor. If the editor is the code editor, the class is `IDESourceCodeEditor`
100 | @end
101 |
102 | @interface IDEEditorArea : NSObject
103 | - (IDEEditorContext *)lastActiveEditorContext;
104 | @end
105 |
106 | @interface IDEWorkspaceWindowController : NSObject
107 | @property (readonly) IDEWorkspaceTabController *activeWorkspaceTabController;
108 | - (IDEEditorArea *)editorArea;
109 | @end
110 |
111 | @interface IDEWorkspace : NSObject
112 | @property (readonly) DVTFilePath *representingFilePath;
113 | @end
114 |
115 | @interface IDEWorkspaceDocument : NSDocument
116 | @property (readonly) IDEWorkspace *workspace;
117 | @end
118 |
119 | @interface QLXcodeHelper : NSObject
120 | + (IDEWorkspaceDocument *)currentWorkspaceDocument;
121 | + (IDESourceCodeDocument *)currentSourceCodeDocument;
122 | + (NSTextView *)currentSourceCodeTextView;
123 | + (NSArray *)selectedObjCFileNavigableItems;
124 | @end
125 |
126 |
--------------------------------------------------------------------------------
/QuickLocalization/QLIDEHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // QLIDEHelper.h
3 | // QLMethod2Implement
4 | //
5 | // Created by Long on 14-4-15.
6 | // Copyright (c) 2014年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum {
12 | QLIDEFileTypeMFile = 0,
13 | QLIDEFileTypeHFile
14 | }QLIDEFileType;
15 |
16 | typedef enum {
17 | QLImplementTypeMethod = 0,
18 | QLImplementTypeConstString,
19 | QLImplementTypeSelector,
20 | QLImplementTypeInvocation,
21 | QLImplementTypeGetter
22 | }QLImplementType;
23 |
24 | @interface QLIDEHelper : NSObject
25 |
26 | /**
27 | * Open file in Xcode editor.
28 | *
29 | * @param filePath file path.
30 | *
31 | * @return return YES if open file success.
32 | */
33 | + (BOOL)openFile:(NSString *)filePath;
34 |
35 | /**
36 | * Get current edit file path.
37 | *
38 | * @return current edit file path
39 | */
40 | + (NSString *)getCurrentEditFilePath;
41 |
42 | /**
43 | * Get .m file of current edit file.
44 | *
45 | * @return .m file path.
46 | */
47 | + (NSString *)getMFilePathOfCurrentEditFile;
48 |
49 | /**
50 | * Get current class name by "Current Edit File Path"
51 | *
52 | * @return class name.
53 | */
54 | + (NSString *)getCurrentClassName;
55 |
56 | /**
57 | * Check current opened file is .h file.
58 | *
59 | * @return return YES if current fils is .h file.
60 | */
61 | + (BOOL)isHeaderFile;
62 |
63 | /**
64 | * Get .h file of current edit file.
65 | *
66 | * @return .h file path.
67 | */
68 | + (NSString *)getHFilePathOfCurrentEditFile;
69 |
70 | /**
71 | * Highlight text and scroll to visible in current edit file.
72 | *
73 | * @param target text.
74 | */
75 | + (void)selectText:(NSString *)text;
76 |
77 | /**
78 | * Search regex string and scroll to visible in current edit file.
79 | *
80 | * @param regex regex string.
81 | * @param text highlight text.
82 | */
83 | + (void)selectTextWithRegex:(NSString *)regex highlightText:(NSString *)text;
84 |
85 | /**
86 | * Replace text in current editor.
87 | *
88 | * @param text text to be replace.
89 | * @param newText new text.
90 | */
91 | + (void)replaceText:(NSString *)text withNewText:(NSString *)newText;
92 |
93 | /**
94 | * Get current selected range string.
95 | *
96 | * @return selected range string.
97 | */
98 | + (NSString *)getCurrentSelectMethod;
99 |
100 | /**
101 | * Get all class name by @interface or @implementation of .h file or .m file of the current edit file.
102 | *
103 | * @param fileType QLIDEFileTypeMFile or QLIDEFileTypeHFile
104 | *
105 | * @return class name.
106 | */
107 | + (NSArray *)getCurrentClassNameByCurrentSelectedRangeWithFileType:(QLIDEFileType)fileType;
108 |
109 | /**
110 | * Get target insert position for code generation.
111 | *
112 | * @param range content range: contentRange = [QLIDEHelper getClassImplementContentRangeWithClassNameItemList:currentClassName fileText:textView.textStorage.string fileType:QLIDEFileTypeMFile];
113 | *
114 | * @return target insert range.
115 | */
116 | + (NSRange)getInsertRangeWithClassImplementContentRange:(NSRange)range;
117 |
118 | /**
119 | * Get class @interface or @implementation code range(before @end) in .h or .m file.
120 | *
121 | * @param classNameItemList all class name by: NSArray *currentClassName = [QLIDEHelper getCurrentClassNameByCurrentSelectedRangeWithFileType:QLIDEFileTypeHFile];
122 | * @param fileText target string for match, should be .m (fileType should be QLIDEFileTypeMFile) or .h (fileType should be QLIDEFileTypeHFile) file content string.
123 | * @param fileType QLIDEFileTypeMFile or QLIDEFileTypeHFile
124 | *
125 | * @return range from @interface/@implementation to @end, not include @end.
126 | */
127 | + (NSRange)getClassImplementContentRangeWithClassNameItemList:(NSArray *)classNameItemList
128 | fileText:(NSString *)fileText
129 | fileType:(QLIDEFileType)fileType;
130 |
131 | @end
132 |
133 |
--------------------------------------------------------------------------------
/QuickLocalization/RCXcode.m:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Created by Zitao on 12/05/13.
4 | //
5 | //
6 |
7 | #import "RCXcode.h"
8 | @implementation RCXcode {}
9 |
10 | #pragma mark - Helpers
11 |
12 | + (id)currentEditor {
13 | NSWindowController *currentWindowController = [[NSApp keyWindow] windowController];
14 | if ([currentWindowController isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) {
15 | IDEWorkspaceWindowController *workspaceController = (IDEWorkspaceWindowController *)currentWindowController;
16 | IDEEditorArea *editorArea = [workspaceController editorArea];
17 | IDEEditorContext *editorContext = [editorArea lastActiveEditorContext];
18 | return [editorContext editor];
19 | }
20 | return nil;
21 | }
22 |
23 | + (IDEWorkspaceDocument *)currentWorkspaceDocument {
24 | NSWindowController *currentWindowController = [[NSApp keyWindow] windowController];
25 | id document = [currentWindowController document];
26 | if (currentWindowController && [document isKindOfClass:NSClassFromString(@"IDEWorkspaceDocument")]) {
27 | return (IDEWorkspaceDocument *)document;
28 | }
29 | return nil;
30 | }
31 |
32 | + (IDESourceCodeDocument *)currentSourceCodeDocument {
33 | if ([[RCXcode currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) {
34 | IDESourceCodeEditor *editor = [RCXcode currentEditor];
35 | return editor.sourceCodeDocument;
36 | }
37 |
38 | if ([[RCXcode currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeComparisonEditor")]) {
39 | IDESourceCodeComparisonEditor *editor = [RCXcode currentEditor];
40 | if ([[editor primaryDocument] isKindOfClass:NSClassFromString(@"IDESourceCodeDocument")]) {
41 | IDESourceCodeDocument *document = (IDESourceCodeDocument *)editor.primaryDocument;
42 | return document;
43 | }
44 | }
45 |
46 | return nil;
47 | }
48 |
49 | + (NSTextView *)currentSourceCodeTextView {
50 | if ([[RCXcode currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) {
51 | IDESourceCodeEditor *editor = [RCXcode currentEditor];
52 | return editor.textView;
53 | }
54 |
55 | if ([[RCXcode currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeComparisonEditor")]) {
56 | IDESourceCodeComparisonEditor *editor = [RCXcode currentEditor];
57 | return editor.keyTextView;
58 | }
59 |
60 | return nil;
61 | }
62 |
63 | + (NSArray *)selectedObjCFileNavigableItems {
64 | NSMutableArray *mutableArray = [NSMutableArray array];
65 |
66 | id currentWindowController = [[NSApp keyWindow] windowController];
67 | if ([currentWindowController isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) {
68 | IDEWorkspaceWindowController *workspaceController = currentWindowController;
69 | IDEWorkspaceTabController *workspaceTabController = [workspaceController activeWorkspaceTabController];
70 | IDENavigatorArea *navigatorArea = [workspaceTabController navigatorArea];
71 | id currentNavigator = [navigatorArea currentNavigator];
72 |
73 | if ([currentNavigator isKindOfClass:NSClassFromString(@"IDEStructureNavigator")]) {
74 | IDEStructureNavigator *structureNavigator = currentNavigator;
75 | for (id selectedObject in structureNavigator.selectedObjects) {
76 | if ([selectedObject isKindOfClass:NSClassFromString(@"IDEFileNavigableItem")]) {
77 | IDEFileNavigableItem *fileNavigableItem = selectedObject;
78 | NSString *uti = fileNavigableItem.documentType.identifier;
79 | if ([uti isEqualToString:(NSString *)kUTTypeObjectiveCSource] || [uti isEqualToString:(NSString *)kUTTypeCHeader]) {
80 | [mutableArray addObject:fileNavigableItem];
81 | }
82 | }
83 | }
84 | }
85 | }
86 |
87 | if (mutableArray.count) {
88 | return [NSArray arrayWithArray:mutableArray];
89 | }
90 | return nil;
91 | }
92 |
93 | + (NSArray *)containerFolderURLsForNavigableItem:(IDENavigableItem *)navigableItem {
94 | NSMutableArray *mArray = [NSMutableArray array];
95 |
96 | do {
97 | NSURL *folderURL = nil;
98 | id representedObject = navigableItem.representedObject;
99 | if ([navigableItem isKindOfClass:NSClassFromString(@"IDEGroupNavigableItem")]) {
100 | // IDE-GROUP (a folder in the navigator)
101 | IDEGroup *group = (IDEGroup *)representedObject;
102 | folderURL = group.resolvedFilePath.fileURL;
103 | } else if ([navigableItem isKindOfClass:NSClassFromString(@"IDEContainerFileReferenceNavigableItem")]) {
104 | // CONTAINER (an Xcode project)
105 | IDEFileReference *fileReference = representedObject;
106 | folderURL = [fileReference.resolvedFilePath.fileURL URLByDeletingLastPathComponent];
107 | } else if ([navigableItem isKindOfClass:NSClassFromString(@"IDEKeyDrivenNavigableItem")]) {
108 | // WORKSPACE (root: Xcode project or workspace)
109 | IDEWorkspace *workspace = representedObject;
110 | folderURL = [workspace.representingFilePath.fileURL URLByDeletingLastPathComponent];
111 | }
112 | if (folderURL && ![mArray containsObject:folderURL]) [mArray addObject:folderURL];
113 | navigableItem = [navigableItem parentItem];
114 | } while (navigableItem != nil);
115 |
116 | if (mArray.count > 0) return [NSArray arrayWithArray:mArray];
117 | return nil;
118 | }
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/QuickLocalization/QLXcodeHelper.m:
--------------------------------------------------------------------------------
1 | //
2 | // QLXcodeHelper.m
3 | //
4 | //
5 | // Created by Mellong on 14-4-13.
6 | // Copyright (c) 2014年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import "QLXcodeHelper.h"
10 |
11 | @implementation QLXcodeHelper
12 |
13 | #pragma mark - Helpers
14 |
15 | + (id)currentEditor {
16 | NSWindowController *currentWindowController = [[NSApp keyWindow] windowController];
17 | if ([currentWindowController isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) {
18 | IDEWorkspaceWindowController *workspaceController = (IDEWorkspaceWindowController *)currentWindowController;
19 | IDEEditorArea *editorArea = [workspaceController editorArea];
20 | IDEEditorContext *editorContext = [editorArea lastActiveEditorContext];
21 | return [editorContext editor];
22 | }
23 | return nil;
24 | }
25 |
26 | + (IDEWorkspaceDocument *)currentWorkspaceDocument {
27 | NSWindowController *currentWindowController = [[NSApp keyWindow] windowController];
28 | id document = [currentWindowController document];
29 | if (currentWindowController && [document isKindOfClass:NSClassFromString(@"IDEWorkspaceDocument")]) {
30 | return (IDEWorkspaceDocument *)document;
31 | }
32 | return nil;
33 | }
34 |
35 | + (IDESourceCodeDocument *)currentSourceCodeDocument {
36 | if ([[QLXcodeHelper currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) {
37 | IDESourceCodeEditor *editor = [QLXcodeHelper currentEditor];
38 | return editor.sourceCodeDocument;
39 | }
40 |
41 | if ([[QLXcodeHelper currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeComparisonEditor")]) {
42 | IDESourceCodeComparisonEditor *editor = [QLXcodeHelper currentEditor];
43 | if ([[editor primaryDocument] isKindOfClass:NSClassFromString(@"IDESourceCodeDocument")]) {
44 | IDESourceCodeDocument *document = (IDESourceCodeDocument *)editor.primaryDocument;
45 | return document;
46 | }
47 | }
48 |
49 | return nil;
50 | }
51 |
52 | + (NSTextView *)currentSourceCodeTextView {
53 | if ([[QLXcodeHelper currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeEditor")]) {
54 | IDESourceCodeEditor *editor = [QLXcodeHelper currentEditor];
55 | return editor.textView;
56 | }
57 |
58 | if ([[QLXcodeHelper currentEditor] isKindOfClass:NSClassFromString(@"IDESourceCodeComparisonEditor")]) {
59 | IDESourceCodeComparisonEditor *editor = [QLXcodeHelper currentEditor];
60 | return editor.keyTextView;
61 | }
62 |
63 | return nil;
64 | }
65 |
66 | + (NSArray *)selectedObjCFileNavigableItems {
67 | NSMutableArray *mutableArray = [NSMutableArray array];
68 |
69 | id currentWindowController = [[NSApp keyWindow] windowController];
70 | if ([currentWindowController isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) {
71 | IDEWorkspaceWindowController *workspaceController = currentWindowController;
72 | IDEWorkspaceTabController *workspaceTabController = [workspaceController activeWorkspaceTabController];
73 | IDENavigatorArea *navigatorArea = [workspaceTabController navigatorArea];
74 | id currentNavigator = [navigatorArea currentNavigator];
75 |
76 | if ([currentNavigator isKindOfClass:NSClassFromString(@"IDEStructureNavigator")]) {
77 | IDEStructureNavigator *structureNavigator = currentNavigator;
78 | for (id selectedObject in structureNavigator.selectedObjects) {
79 | if ([selectedObject isKindOfClass:NSClassFromString(@"IDEFileNavigableItem")]) {
80 | IDEFileNavigableItem *fileNavigableItem = selectedObject;
81 | NSString *uti = fileNavigableItem.documentType.identifier;
82 | if ([uti isEqualToString:(NSString *)kUTTypeObjectiveCSource] || [uti isEqualToString:(NSString *)kUTTypeCHeader]) {
83 | [mutableArray addObject:fileNavigableItem];
84 | }
85 | }
86 | }
87 | }
88 | }
89 |
90 | if (mutableArray.count) {
91 | return [NSArray arrayWithArray:mutableArray];
92 | }
93 | return nil;
94 | }
95 |
96 | + (NSArray *)containerFolderURLsForNavigableItem:(IDENavigableItem *)navigableItem {
97 | NSMutableArray *mArray = [NSMutableArray array];
98 |
99 | do {
100 | NSURL *folderURL = nil;
101 | id representedObject = navigableItem.representedObject;
102 | if ([navigableItem isKindOfClass:NSClassFromString(@"IDEGroupNavigableItem")]) {
103 | // IDE-GROUP (a folder in the navigator)
104 | IDEGroup *group = (IDEGroup *)representedObject;
105 | folderURL = group.resolvedFilePath.fileURL;
106 | } else if ([navigableItem isKindOfClass:NSClassFromString(@"IDEContainerFileReferenceNavigableItem")]) {
107 | // CONTAINER (an Xcode project)
108 | IDEFileReference *fileReference = representedObject;
109 | folderURL = [fileReference.resolvedFilePath.fileURL URLByDeletingLastPathComponent];
110 | } else if ([navigableItem isKindOfClass:NSClassFromString(@"IDEKeyDrivenNavigableItem")]) {
111 | // WORKSPACE (root: Xcode project or workspace)
112 | IDEWorkspace *workspace = representedObject;
113 | folderURL = [workspace.representingFilePath.fileURL URLByDeletingLastPathComponent];
114 | }
115 | if (folderURL && ![mArray containsObject:folderURL]) [mArray addObject:folderURL];
116 | navigableItem = [navigableItem parentItem];
117 | } while (navigableItem != nil);
118 |
119 | if (mArray.count > 0) return [NSArray arrayWithArray:mArray];
120 | return nil;
121 | }
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/QuickLocalization/OLSettingController.m:
--------------------------------------------------------------------------------
1 | //
2 | // OLSettingController.m
3 | // QuickLocalization
4 | //
5 | // Created by Zitao Xiong on 7/18/15.
6 | // Copyright (c) 2015 nanaimostudio. All rights reserved.
7 | //
8 |
9 | #import "OLSettingController.h"
10 |
11 | NSUInteger QL_CountOccurentOfStringWithSubString(NSString *str, NSString *subString) {
12 | NSUInteger count = 0, length = [str length];
13 | NSRange range = NSMakeRange(0, length);
14 | while(range.location != NSNotFound)
15 | {
16 | range = [str rangeOfString:subString options:0 range:range];
17 | if(range.location != NSNotFound)
18 | {
19 | range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
20 | count++;
21 | }
22 |
23 | }
24 |
25 | return count;
26 | }
27 | @interface OLSettingController ()
28 | @property (weak) IBOutlet NSTextField *commentTextField;
29 | @property (weak) IBOutlet NSTextField *tableNameTextField;
30 | @property (weak) IBOutlet NSTextField *bunldeTextField;
31 | @property (weak) IBOutlet NSButton *swiftCheckButton;
32 | @property (weak) IBOutlet NSButton *commentSameAsKeyCheckButton;
33 | @property (weak) IBOutlet NSComboBox *comboBox;
34 | @property (weak) IBOutlet NSTextField *previewLabel;
35 | @property (weak) IBOutlet NSButton *commentAsKeyButton;
36 | @property (weak) IBOutlet NSTextField *valueTextField;
37 | @property (weak) IBOutlet NSButton *swiftLocalizationPreviewButton;
38 |
39 | @end
40 |
41 | @implementation OLSettingController
42 |
43 | - (void)windowDidLoad {
44 | [super windowDidLoad];
45 | [self.comboBox selectItemAtIndex:0];
46 | [self updatePreviewText];
47 | [[NSUserDefaults standardUserDefaults] registerDefaults:@{
48 | kQLFormatStringCommentValueKey: @"<# comment #>",
49 | kQLFormatStringTableNameValueKey: @"nil",
50 | kQLFormatStringBundleValueKey: @"nil",
51 | kQLFormatStringValueValueKey: @"<# value #>",
52 | kQLFormatStringCommentSameKey: @YES,
53 | kQLFormatStringSwiftSyntax: @NO,
54 | }];
55 |
56 | self.commentTextField.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:kQLFormatStringCommentValueKey];
57 | self.tableNameTextField.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:kQLFormatStringTableNameValueKey];
58 | self.bunldeTextField.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:kQLFormatStringBundleValueKey];
59 | self.valueTextField.stringValue = [[NSUserDefaults standardUserDefaults] objectForKey:kQLFormatStringValueValueKey];
60 | if ([[NSUserDefaults standardUserDefaults] boolForKey:kQLFormatStringSwiftSyntax]) {
61 | self.swiftLocalizationPreviewButton.state = NSOnState;
62 | }
63 | else {
64 | self.swiftLocalizationPreviewButton.state = NSOffState;
65 | }
66 |
67 | if ([[NSUserDefaults standardUserDefaults] boolForKey:kQLFormatStringCommentSameKey]) {
68 | self.commentSameAsKeyCheckButton.state = NSOnState;
69 | }
70 | else {
71 | self.commentSameAsKeyCheckButton.state = NSOffState;
72 | }
73 | }
74 |
75 | - (IBAction)commentDidChange:(id)sender {
76 | [[NSUserDefaults standardUserDefaults] setObject:self.commentTextField.stringValue forKey:kQLFormatStringCommentValueKey];
77 | [self updatePreviewText];
78 | }
79 |
80 | - (IBAction)onTableNameChanged:(id)sender {
81 | [[NSUserDefaults standardUserDefaults] setObject:self.tableNameTextField.stringValue forKey:kQLFormatStringTableNameValueKey];
82 | [self updatePreviewText];
83 | }
84 |
85 | - (IBAction)onBunldeNameChanged:(id)sender {
86 | [[NSUserDefaults standardUserDefaults] setObject:self.bunldeTextField.stringValue forKey:kQLFormatStringBundleValueKey];
87 | [self updatePreviewText];
88 | }
89 |
90 | - (IBAction)onCommentAsKayButton:(id)sender {
91 | if (self.commentAsKeyButton.state == NSOnState) {
92 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kQLFormatStringCommentSameKey];
93 | }
94 | else {
95 | [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kQLFormatStringCommentSameKey];
96 | }
97 | [self updatePreviewText];
98 | }
99 |
100 | - (IBAction)onValueTextField:(id)sender {
101 | [[NSUserDefaults standardUserDefaults] setObject:self.valueTextField.stringValue forKey:kQLFormatStringValueValueKey];
102 | [self updatePreviewText];
103 | }
104 |
105 | - (IBAction)onSwiftLocalizationPreviewChanged:(id)sender {
106 | if (self.swiftLocalizationPreviewButton.state == NSOnState) {
107 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kQLFormatStringSwiftSyntax];
108 | }
109 | else {
110 | [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kQLFormatStringSwiftSyntax];
111 | }
112 | [self updatePreviewText];
113 | }
114 |
115 | - (IBAction)onComboBoxChanged:(id)sender {
116 | [self updatePreviewText];
117 | }
118 |
119 | - (NSString *)updatePreviewText {
120 | NSString *formatString = [self.comboBox objectValueOfSelectedItem];
121 | NSUInteger placeholderCount = QL_CountOccurentOfStringWithSubString(formatString, @"%@");
122 |
123 | NSString *value = @"\"Hello World\"";
124 | if (self.swiftLocalizationPreviewButton.state == NSOffState) {
125 | value = [NSString stringWithFormat:@"@%@", value];
126 | }
127 | NSString *comment;
128 | NSString *savedComment;
129 | if ([self.commentAsKeyButton state] == NSOnState) {
130 | comment = [value copy];
131 | savedComment = @"%@";
132 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kQLFormatStringCommentSameKey];
133 | }
134 | else {
135 | comment = self.commentTextField.stringValue;
136 | savedComment = comment.copy;
137 | [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kQLFormatStringCommentSameKey];
138 | }
139 |
140 | NSString *savedFormatString;
141 | if (placeholderCount == 2) {
142 | //swift or object-c
143 | [self.previewLabel setStringValue:[NSString stringWithFormat:formatString, value, comment]];
144 | savedFormatString = [NSString stringWithFormat:formatString, @"%@", savedComment];
145 | }
146 |
147 | else if (placeholderCount == 4) {
148 | //object-c from bundle
149 | [self.previewLabel setStringValue:[NSString stringWithFormat:formatString, value, comment, self.tableNameTextField.stringValue, self.bunldeTextField.stringValue]];
150 | savedFormatString = [NSString stringWithFormat:formatString, @"%@", savedComment, self.tableNameTextField.stringValue, self.bunldeTextField.stringValue];
151 | }
152 | else if (placeholderCount == 5) {
153 | [self.previewLabel setStringValue:[NSString stringWithFormat:formatString, value, self.tableNameTextField.stringValue, self.bunldeTextField.stringValue, self.valueTextField.stringValue, comment]];
154 | savedFormatString = [NSString stringWithFormat:formatString, @"%@", self.tableNameTextField.stringValue, self.bunldeTextField.stringValue, self.valueTextField.stringValue, savedComment];
155 | }
156 | else {
157 | [self.previewLabel setStringValue:@"%@ must be 2, 4, or 5"];
158 | return @"";
159 | }
160 |
161 | [[NSUserDefaults standardUserDefaults] setObject:savedFormatString forKey:kQLFormatStringKey];
162 |
163 | return savedFormatString;
164 | }
165 |
166 | + (void)registerFormatStringDefaults {
167 | [[NSUserDefaults standardUserDefaults] registerDefaults:@{kQLFormatStringKey: @"NSLocalizedString(%@, %@)"}];
168 | }
169 | @end
170 |
--------------------------------------------------------------------------------
/QuickLocalization/QLIDEHelper.m:
--------------------------------------------------------------------------------
1 | //
2 | // QLIDEHelper.m
3 | // QLMethod2Implement
4 | //
5 | // Created by Long on 14-4-15.
6 | // Copyright (c) 2014年 Tendencystudio. All rights reserved.
7 | //
8 |
9 | #import "QLIDEHelper.h"
10 | #import "QLXcodeHelper.h"
11 | #import
12 |
13 | @implementation QLIDEHelper
14 |
15 |
16 | + (BOOL)openFile:(NSString *)filePath
17 | {
18 | NSWindowController *currentWindowController = [[NSApp mainWindow] windowController];
19 | NSLog(@"currentWindowController %@",[currentWindowController description]);
20 | if ([currentWindowController isKindOfClass:NSClassFromString(@"IDEWorkspaceWindowController")]) {
21 | NSLog(@"Open in current Xocde");
22 | id appDelegate = (id)[NSApp delegate];
23 | if ([appDelegate application:NSApp openFile:filePath]) {
24 | return YES;
25 | }
26 | }
27 | return NO;
28 | }
29 |
30 | + (NSString *)getCurrentEditFilePath
31 | {
32 | IDESourceCodeDocument *currentSourceCodeDocument = [QLXcodeHelper currentSourceCodeDocument];
33 | NSString *filePath = [[currentSourceCodeDocument fileURL] path];
34 | return filePath;
35 | }
36 |
37 | + (BOOL)isHeaderFile
38 | {
39 | NSString *filePath = [QLIDEHelper getCurrentEditFilePath];
40 | if ([filePath rangeOfString:@".h"].length > 0) {
41 | return YES;
42 | }
43 | return NO;
44 | }
45 |
46 | + (NSString *)getHFilePathOfCurrentEditFile
47 | {
48 | NSString *filePath = [QLIDEHelper getCurrentEditFilePath];
49 | filePath = [filePath stringByDeletingPathExtension];
50 | filePath = [filePath stringByAppendingPathExtension:@"h"];
51 | return filePath;
52 | }
53 |
54 | + (NSString *)getMFilePathOfCurrentEditFile
55 | {
56 | NSString *filePath = [QLIDEHelper getCurrentEditFilePath];
57 | if ([filePath rangeOfString:@".h"].length > 0) {
58 | NSString *mFilePath = [filePath stringByReplacingOccurrencesOfString:@".h" withString:@".m"];
59 | if ([[NSFileManager defaultManager] fileExistsAtPath:mFilePath]) {
60 | return mFilePath;
61 | }
62 |
63 | mFilePath = [filePath stringByReplacingOccurrencesOfString:@".h" withString:@".mm"];
64 | if ([[NSFileManager defaultManager] fileExistsAtPath:mFilePath]) {
65 | return mFilePath;
66 | }
67 |
68 | }
69 | return filePath;
70 | }
71 |
72 | + (NSString *)getCurrentClassName
73 | {
74 | NSString *fileName = [[QLIDEHelper getCurrentEditFilePath] lastPathComponent];
75 | return [fileName stringByDeletingPathExtension];
76 | }
77 |
78 | + (void)selectText:(NSString *)text
79 | {
80 | NSTextView *textView = [QLXcodeHelper currentSourceCodeTextView];
81 | NSRange textRange = [textView.textStorage.string rangeOfString:text options:NSCaseInsensitiveSearch];
82 | if (textRange.location != NSNotFound)
83 | {
84 | [textView setSelectedRange:textRange];
85 | [textView scrollRangeToVisible:textRange];
86 | }
87 | }
88 |
89 | + (void)selectTextWithRegex:(NSString *)regex highlightText:(NSString *)text
90 | {
91 | NSTextView *textView = [QLXcodeHelper currentSourceCodeTextView];
92 | NSRegularExpression *regularExpression = [NSRegularExpression
93 | regularExpressionWithPattern:regex
94 | options:NSRegularExpressionAnchorsMatchLines
95 | error:NULL];
96 |
97 | NSRange range = [regularExpression rangeOfFirstMatchInString:textView.textStorage.string
98 | options:0
99 | range:NSMakeRange(0, [textView.textStorage.string length])];
100 | if (range.location == NSNotFound) {
101 | return;
102 | }
103 |
104 | NSString *string = [textView.textStorage.string substringWithRange:range];
105 | NSLog(@"selectTextWithRegex: %@", string);
106 | NSRange textRange = [string rangeOfString:text options:NSCaseInsensitiveSearch];
107 | if (textRange.location != NSNotFound) {
108 | range = NSMakeRange(range.location+textRange.location, textRange.length);
109 | }
110 | [textView setSelectedRange:range];
111 | [textView scrollRangeToVisible:range];
112 | }
113 |
114 | + (void)replaceText:(NSString *)text withNewText:(NSString *)newText
115 | {
116 | NSTextView *textView = [QLXcodeHelper currentSourceCodeTextView];
117 | NSRange textRange = [textView.textStorage.string rangeOfString:text options:NSCaseInsensitiveSearch];
118 | [textView scrollRangeToVisible:textRange];
119 | [textView insertText:newText replacementRange:textRange];
120 | }
121 |
122 | + (NSString *)getCurrentSelectMethod
123 | {
124 | NSTextView *textView = [QLXcodeHelper currentSourceCodeTextView];
125 | NSArray* selectedRanges = [textView selectedRanges];
126 | if (selectedRanges.count >= 1) {
127 | NSRange selectedRange = [[selectedRanges objectAtIndex:0] rangeValue];
128 | NSString *text = textView.textStorage.string;
129 | NSRange lineRange = [text lineRangeForRange:selectedRange];
130 | NSString *line = [text substringWithRange:lineRange];
131 | return line;
132 | }
133 | return nil;
134 | }
135 |
136 | + (NSArray *)getCurrentClassNameByCurrentSelectedRangeWithFileType:(QLIDEFileType)fileType
137 | {
138 | NSTextView *textView = [QLXcodeHelper currentSourceCodeTextView];
139 | NSArray* selectedRanges = [textView selectedRanges];
140 | if (selectedRanges.count >= 1) {
141 | NSRange selectedRange = [[selectedRanges objectAtIndex:0] rangeValue];
142 | NSString *text = textView.textStorage.string;
143 | NSRange lineRange = [text lineRangeForRange:selectedRange];
144 | NSString *regexString = nil;
145 | if (fileType == QLIDEFileTypeHFile) {
146 | regexString = @"(?<=@interface)\\s+(\\w+)\\s*\\(?(\\w*)\\)?";
147 | }else if (fileType == QLIDEFileTypeMFile) {
148 | regexString = @"(?<=@implementation)\\s+(\\w+)\\s*\\(?(\\w*)\\)?";
149 | }
150 | NSRegularExpression *regex = [NSRegularExpression
151 | regularExpressionWithPattern:regexString
152 | options:0
153 | error:NULL];
154 | NSArray *results = [regex matchesInString:textView.textStorage.string options:0 range:NSMakeRange(0, lineRange.location)];
155 | if (results.count > 0) {
156 | NSTextCheckingResult *textCheckingResult = results[results.count - 1];
157 | NSRange classNameRange = textCheckingResult.range;
158 | if (classNameRange.location != NSNotFound) {
159 | NSMutableArray *array = [NSMutableArray array];
160 | for (int i = 0; i < textCheckingResult.numberOfRanges; i++) {
161 | NSString *item = [text substringWithRange:[textCheckingResult rangeAtIndex:i]];
162 | if (item.length > 0) {
163 | [array addObject:item];
164 | NSLog(@"%@", item);
165 | }
166 | }
167 | return array;
168 | }
169 | }
170 | }
171 | return nil;
172 | }
173 |
174 | + (NSRange)getClassImplementContentRangeWithClassNameItemList:(NSArray *)classNameItemList fileText:(NSString *)fileText fileType:(QLIDEFileType)fileType
175 | {
176 | if (classNameItemList.count > 1) {
177 | NSString *normalImplementationFormatString = @"@implementation\\s+%@.+?(?=\\s{0,3000}@end)";
178 | if (fileType == QLIDEFileTypeHFile) {
179 | normalImplementationFormatString = @"@interface\\s+%@.+?(?=\\s{0,3000}@end)";
180 | }
181 |
182 | NSString *regexPattern = [NSString stringWithFormat:normalImplementationFormatString, classNameItemList[1]];
183 | if (classNameItemList.count == 3) {
184 | NSString *categoryImplementationFormatString = @"@implementation\\s+%@\\s+\\(%@\\).+?(?=\\s{0,3000}@end)";
185 | if (fileType == QLIDEFileTypeHFile) {
186 | categoryImplementationFormatString = @"@interface\\s+%@\\s+\\(%@\\).+?(?=\\s{0,3000}@end)";
187 | }
188 | regexPattern = [NSString stringWithFormat:categoryImplementationFormatString, classNameItemList[1], classNameItemList[2]];
189 | }
190 | NSLog(@"#%@",regexPattern);
191 |
192 | NSRegularExpression *regex = [NSRegularExpression
193 | regularExpressionWithPattern:regexPattern
194 | options:NSRegularExpressionDotMatchesLineSeparators
195 | error:NULL];
196 |
197 | NSTextCheckingResult *textCheckingResult = [regex firstMatchInString:fileText
198 | options:0
199 | range:NSMakeRange(0, fileText.length)];
200 |
201 | // NSLog(@"#%@", [fileText substringWithRange:textCheckingResult.range]);
202 | if (textCheckingResult.range.location != NSNotFound) {
203 | return textCheckingResult.range;
204 | }
205 |
206 | }
207 | return NSMakeRange(NSNotFound, 0);
208 | }
209 |
210 | + (NSRange)getInsertRangeWithClassImplementContentRange:(NSRange)range
211 | {
212 | if (range.location != NSNotFound) {
213 | return NSMakeRange(range.location+range.length, 1);
214 | }
215 |
216 | return NSMakeRange(NSNotFound, 0);
217 | }
218 |
219 | @end
220 |
221 |
--------------------------------------------------------------------------------
/QuickLocalization/QuickLocalization.m:
--------------------------------------------------------------------------------
1 | //
2 | // QuickLocalization.m
3 | // QuickLocalization
4 | //
5 | // Created by Zitao Xiong on 5/12/13.
6 | // Copyright (c) 2013 nanaimostudio. All rights reserved.
7 | //
8 |
9 | #import "QuickLocalization.h"
10 | #import "RCXcode.h"
11 | #import "OLSettingController.h"
12 | #import "QLMenuGenerator.h"
13 | #import "QLIDEHelper.h"
14 |
15 | static NSString *localizeRegexs[] = {
16 | @"NSLocalizedString\\s*\\(\\s*@\"(.*)\"\\s*,\\s*(.*)\\s*\\)",
17 | @"localizedStringForKey:\\s*@\"(.*)\"\\s*value:\\s*(.*)\\s*table:\\s*(.*)",
18 | @"NSLocalizedStringFromTable\\s*\\(\\s*@\"(.*)\"\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*\\)",
19 | @"NSLocalizedStringFromTableInBundle\\s*\\(\\s*@\"(.*)\"\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*\\)",
20 | @"NSLocalizedStringWithDefaultValue\\s*\\(\\s*@\"(.*)\"\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*\\)"
21 | };
22 |
23 | static NSString *objcStringRegexs = @"@([\"'])(?:(?=(\\\\?))\\2.)*?\\1";
24 | static NSString *swiftStringRegexs = @"([\"'])(?:(?=(\\\\?))\\2.)*?\\1";
25 |
26 | static NSString * const QLShouldUseNilForComment = @"QLShouldUseNilForComment";
27 | static NSString * const QLShouldUseSnippetForComment = @"QLShouldUseSnippetForComment";
28 | static NSString * const QLShouldUseSwiftSyntax = @"QLShouldUseSwiftSyntax";
29 | static NSString * const QLShouldUseNSLocalizedStringFromTableInBundle = @"QLShouldUseNSLocalizedStringFromTableInBundle";
30 |
31 | @interface QuickLocalization ()
32 |
33 | @property (nonatomic, assign) BOOL shouldUseNilForComment;
34 | @property (nonatomic, assign) BOOL shouldUseSnippetForComment;
35 | @property (nonatomic, assign) BOOL shouldUseSwiftSyntax;
36 | @property (nonatomic, assign) BOOL shouldUseStringFromTableInBundle;
37 | @property (nonatomic, strong) OLSettingController *settingControlelr;
38 | @property (nonatomic, strong) NSBundle *bundle;
39 | @end
40 |
41 | @implementation QuickLocalization
42 |
43 | static id sharedPlugin = nil;
44 |
45 |
46 | + (void)pluginDidLoad:(NSBundle *)plugin
47 | {
48 | static id sharedPlugin = nil;
49 | static dispatch_once_t onceToken;
50 | NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
51 | if ([currentApplicationName isEqual:@"Xcode"]) {
52 | dispatch_once(&onceToken, ^{
53 | sharedPlugin = [[self alloc] initWithBundle:plugin];
54 | });
55 | }
56 | }
57 |
58 | - (id)initWithBundle:(NSBundle *)plugin
59 | {
60 | if (self = [super init]) {
61 | // reference to plugin's bundle, for resource acccess
62 | self.bundle = plugin;
63 | [[NSNotificationCenter defaultCenter] addObserver:self
64 | selector:@selector(applicationDidFinishLaunching:)
65 | name:NSApplicationDidFinishLaunchingNotification
66 | object:nil];
67 |
68 |
69 | }
70 | return self;
71 | }
72 |
73 | - (void)applicationDidFinishLaunching:(NSNotification *)notification {
74 | [self createMenuItem];
75 | [OLSettingController registerFormatStringDefaults];
76 | }
77 |
78 | - (void)createMenuItem {
79 | [QLMenuGenerator generateMenuItems:self.bundle version:[self getBundleVersion] target:self];
80 | }
81 |
82 | // Sample Action, for menu item:
83 | - (void)quickLocalization:(id)sender {
84 | IDESourceCodeDocument *document = [RCXcode currentSourceCodeDocument];
85 | NSTextView *textView = [RCXcode currentSourceCodeTextView];
86 | if (!document || !textView) {
87 | return;
88 | }
89 |
90 | NSArray *selectedRanges = [textView selectedRanges];
91 | if ([selectedRanges count] > 0) {
92 | NSRange range = [[selectedRanges objectAtIndex:0] rangeValue];
93 | BOOL replaced = [self replaceTextInRange:range textView:textView];
94 | //if user selected text is not being replaced, try using line replacing
95 | if (!replaced) {
96 | NSRange lineRange = [textView.textStorage.string lineRangeForRange:range];
97 | [self replaceTextInRange:lineRange textView:textView];
98 | }
99 | }
100 | }
101 |
102 | - (BOOL)replaceTextInRange:(NSRange)range textView:(NSTextView *)textView {
103 | NSString *line = [textView.textStorage.string substringWithRange:range];
104 |
105 | NSRegularExpression *localizedRex = [[NSRegularExpression alloc] initWithPattern:localizeRegexs[0] options:NSRegularExpressionCaseInsensitive error:nil];
106 | NSArray *localizedMatches = [localizedRex matchesInString:line options:0 range:NSMakeRange(0, [line length])];
107 |
108 | NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:[self currentStringRegexs] options:NSRegularExpressionCaseInsensitive error:nil];
109 | NSArray *matches = [regex matchesInString:line options:0 range:NSMakeRange(0, [line length])];
110 | NSUInteger addedLength = 0;
111 | for (int i = 0; i < [matches count]; i++) {
112 | NSTextCheckingResult *result = [matches objectAtIndex:i];
113 | NSRange matchedRangeInLine = result.range;
114 | NSRange matchedRangeInDocument = NSMakeRange(range.location + matchedRangeInLine.location + addedLength, matchedRangeInLine.length);
115 | if ([self isRange:matchedRangeInLine inSkipedRanges:localizedMatches]) {
116 | continue;
117 | }
118 | NSString *string = [line substringWithRange:matchedRangeInLine];
119 | // NSLog(@"string index:%d, %@", i, string);
120 | NSString *outputString;
121 |
122 | NSString *savedFormatString = [[NSUserDefaults standardUserDefaults] objectForKey:kQLFormatStringKey];
123 |
124 | NSUInteger placeHolderCount = QL_CountOccurentOfStringWithSubString(savedFormatString, @"%@");
125 | if (placeHolderCount == 2) {
126 | outputString = [NSString stringWithFormat:savedFormatString, string, string];
127 | }
128 | else if (placeHolderCount == 1) {
129 | outputString = [NSString stringWithFormat:savedFormatString, string];
130 | }
131 | else {
132 | outputString = [NSString stringWithFormat:@"placeholder incorrect, format string is %@", savedFormatString];
133 | }
134 |
135 | addedLength = addedLength + outputString.length - string.length;
136 | if ([textView shouldChangeTextInRange:matchedRangeInDocument replacementString:outputString]) {
137 | [textView.textStorage replaceCharactersInRange:matchedRangeInDocument
138 | withAttributedString:[[NSAttributedString alloc] initWithString:outputString]];
139 | [textView didChangeText];
140 | }
141 |
142 | }
143 |
144 | if (matches.count) {
145 | return YES;
146 | }
147 | else {
148 | return NO;
149 | }
150 | }
151 |
152 | - (NSString *)currentStringRegexs {
153 | BOOL isSwiftSyntax = [[NSUserDefaults standardUserDefaults] boolForKey:kQLFormatStringSwiftSyntax];
154 | if (isSwiftSyntax) {
155 | return swiftStringRegexs;
156 | }
157 | else {
158 | return objcStringRegexs;
159 | }
160 | }
161 |
162 | - (BOOL)isRange:(NSRange)range inSkipedRanges:(NSArray *)ranges {
163 | for (int i = 0; i < [ranges count]; i++) {
164 | NSTextCheckingResult *result = [ranges objectAtIndex:i];
165 | NSRange skippedRange = result.range;
166 | if (skippedRange.location <= range.location && skippedRange.location + skippedRange.length > range.location + range.length) {
167 | return YES;
168 | }
169 | }
170 | return NO;
171 | }
172 |
173 | - (void)toggleNilOption {
174 | self.shouldUseNilForComment = !self.shouldUseNilForComment;
175 |
176 | if (self.shouldUseNilForComment) {
177 | self.shouldUseSnippetForComment = NO;
178 | }
179 | }
180 |
181 | - (void)toggleSnippetOption {
182 | self.shouldUseSnippetForComment = !self.shouldUseSnippetForComment;
183 | if (self.shouldUseSnippetForComment) {
184 | self.shouldUseNilForComment = NO;
185 | }
186 | }
187 |
188 | - (void)toggleSwiftOption {
189 | self.shouldUseSwiftSyntax = !self.shouldUseSwiftSyntax;
190 | }
191 |
192 | - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
193 | if ([menuItem action] == @selector(toggleNilOption)) {
194 | [menuItem setState:[self shouldUseNilForComment] ? NSOnState : NSOffState];
195 | }
196 | else if ([menuItem action] == @selector(toggleSnippetOption)) {
197 | [menuItem setState:[self shouldUseSnippetForComment] ? NSOnState : NSOffState];
198 | }
199 | else if ([menuItem action] == @selector(toggleSwiftOption)) {
200 | [menuItem setState:[self shouldUseSwiftSyntax] ? NSOnState : NSOffState];
201 | }
202 | return YES;
203 | }
204 |
205 | - (void)toggleStringFromTableInBundle {
206 | self.shouldUseStringFromTableInBundle = !self.shouldUseStringFromTableInBundle;
207 | }
208 |
209 | #pragma mark Preferences
210 | - (BOOL)shouldUseStringFromTableInBundle {
211 | return [[NSUserDefaults standardUserDefaults] boolForKey:QLShouldUseNSLocalizedStringFromTableInBundle];
212 | }
213 |
214 | - (void)setShouldUseStringFromTableInBundle:(BOOL)shouldUseStringFromTableInBundle {
215 | [[NSUserDefaults standardUserDefaults] setBool:shouldUseStringFromTableInBundle forKey:QLShouldUseNSLocalizedStringFromTableInBundle];
216 | }
217 |
218 | - (BOOL)shouldUseNilForComment {
219 | return [[NSUserDefaults standardUserDefaults] boolForKey:QLShouldUseNilForComment];
220 | }
221 |
222 | - (void)setShouldUseNilForComment:(BOOL)shouldUseNilForComment {
223 | [[NSUserDefaults standardUserDefaults] setBool:shouldUseNilForComment forKey:QLShouldUseNilForComment];
224 | }
225 |
226 | - (BOOL)shouldUseSnippetForComment {
227 | return [[NSUserDefaults standardUserDefaults] boolForKey:QLShouldUseSnippetForComment];
228 | }
229 |
230 | - (void)setShouldUseSnippetForComment:(BOOL)shouldUseSnippetForComment {
231 | [[NSUserDefaults standardUserDefaults] setBool:shouldUseSnippetForComment forKey:QLShouldUseSnippetForComment];
232 | }
233 |
234 | - (BOOL)shouldUseSwiftSyntax {
235 | return [[NSUserDefaults standardUserDefaults] boolForKey:QLShouldUseSwiftSyntax];
236 | }
237 |
238 | - (void)setShouldUseSwiftSyntax:(BOOL)shouldUseSwiftSyntax {
239 | [[NSUserDefaults standardUserDefaults] setBool:shouldUseSwiftSyntax forKey:QLShouldUseSwiftSyntax];
240 | }
241 |
242 | - (NSString *)getBundleVersion
243 | {
244 | NSString *bundleVersion = [[self.bundle infoDictionary] objectForKey:@"CFBundleShortVersionString"];
245 | return bundleVersion;
246 | }
247 |
248 | - (void)showSettingWindow
249 | {
250 | if (self.settingControlelr == nil) {
251 | self.settingControlelr = [[OLSettingController alloc] initWithWindowNibName:@"OLSettingController"];
252 | self.settingControlelr.bundle = self.bundle;
253 |
254 | }
255 |
256 | [self.settingControlelr showWindow:self.settingControlelr];
257 | }
258 | @end
259 |
--------------------------------------------------------------------------------
/QuickLocalization/OLSettingController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
87 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | NSLocalizedString(%@, %@)
107 | NSLocalizedStringFromTableInBundle(%@, %@, %@, %@)
108 | NSLocalizedString(%@, comment: %@)
109 | NSLocalizedString(%@, tableName: %@, bundle: %@, value: %@, comment: %@)
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/QuickLocalization.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0966970B1B5A20C200D29654 /* QLMenuGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 0966970A1B5A20C200D29654 /* QLMenuGenerator.m */; };
11 | 0966970D1B5A20C900D29654 /* MenuItemData.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0966970C1B5A20C900D29654 /* MenuItemData.plist */; };
12 | 096697101B5A214400D29654 /* QLConstString.m in Sources */ = {isa = PBXBuildFile; fileRef = 0966970F1B5A214400D29654 /* QLConstString.m */; };
13 | 098C633B1BFDB38E00A6398E /* QLIDEHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 098C633A1BFDB38E00A6398E /* QLIDEHelper.m */; };
14 | 098C633E1BFDB43100A6398E /* QLXcodeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 098C633D1BFDB43100A6398E /* QLXcodeHelper.m */; };
15 | 099474BA1B5A1F3000E39E3C /* OLSettingController.m in Sources */ = {isa = PBXBuildFile; fileRef = 099474B81B5A1F3000E39E3C /* OLSettingController.m */; };
16 | 099474BB1B5A1F3000E39E3C /* OLSettingController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 099474B91B5A1F3000E39E3C /* OLSettingController.xib */; };
17 | 09A343C6174068E600A713EE /* RCXcode.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A343C5174068E200A713EE /* RCXcode.m */; };
18 | 09EC581817E3B6E1002261C4 /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 09EC581717E3B6E1002261C4 /* icon.icns */; };
19 | 09F65636174041010000486B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09F65635174041010000486B /* AppKit.framework */; };
20 | 09F65638174041010000486B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09F65637174041010000486B /* Foundation.framework */; };
21 | 09F6563E174041010000486B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 09F6563C174041010000486B /* InfoPlist.strings */; };
22 | 09F65641174041010000486B /* QuickLocalization.m in Sources */ = {isa = PBXBuildFile; fileRef = 09F65640174041010000486B /* QuickLocalization.m */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXFileReference section */
26 | 096697091B5A20C200D29654 /* QLMenuGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLMenuGenerator.h; sourceTree = ""; };
27 | 0966970A1B5A20C200D29654 /* QLMenuGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLMenuGenerator.m; sourceTree = ""; };
28 | 0966970C1B5A20C900D29654 /* MenuItemData.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = MenuItemData.plist; sourceTree = ""; };
29 | 0966970E1B5A214400D29654 /* QLConstString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLConstString.h; sourceTree = ""; };
30 | 0966970F1B5A214400D29654 /* QLConstString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLConstString.m; sourceTree = ""; };
31 | 098C63391BFDB38E00A6398E /* QLIDEHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLIDEHelper.h; sourceTree = ""; };
32 | 098C633A1BFDB38E00A6398E /* QLIDEHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLIDEHelper.m; sourceTree = ""; };
33 | 098C633C1BFDB43100A6398E /* QLXcodeHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLXcodeHelper.h; sourceTree = ""; };
34 | 098C633D1BFDB43100A6398E /* QLXcodeHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLXcodeHelper.m; sourceTree = ""; };
35 | 099474B71B5A1F3000E39E3C /* OLSettingController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLSettingController.h; sourceTree = ""; };
36 | 099474B81B5A1F3000E39E3C /* OLSettingController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OLSettingController.m; sourceTree = ""; };
37 | 099474B91B5A1F3000E39E3C /* OLSettingController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OLSettingController.xib; sourceTree = ""; };
38 | 09A343C4174068E200A713EE /* RCXcode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCXcode.h; sourceTree = ""; };
39 | 09A343C5174068E200A713EE /* RCXcode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCXcode.m; sourceTree = ""; };
40 | 09EC581717E3B6E1002261C4 /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = ""; };
41 | 09F65632174041010000486B /* QuickLocalization.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QuickLocalization.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 09F65635174041010000486B /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
43 | 09F65637174041010000486B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
44 | 09F6563B174041010000486B /* QuickLocalization-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QuickLocalization-Info.plist"; sourceTree = ""; };
45 | 09F6563D174041010000486B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
46 | 09F6563F174041010000486B /* QuickLocalization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QuickLocalization.h; sourceTree = ""; };
47 | 09F65640174041010000486B /* QuickLocalization.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QuickLocalization.m; sourceTree = ""; };
48 | 09F65642174041010000486B /* QuickLocalization-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QuickLocalization-Prefix.pch"; sourceTree = ""; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | 09F6562F174041010000486B /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | 09F65636174041010000486B /* AppKit.framework in Frameworks */,
57 | 09F65638174041010000486B /* Foundation.framework in Frameworks */,
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | 09F65629174041010000486B = {
65 | isa = PBXGroup;
66 | children = (
67 | 09F65639174041010000486B /* QuickLocalization */,
68 | 09F65634174041010000486B /* Frameworks */,
69 | 09F65633174041010000486B /* Products */,
70 | );
71 | sourceTree = "";
72 | };
73 | 09F65633174041010000486B /* Products */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 09F65632174041010000486B /* QuickLocalization.xcplugin */,
77 | );
78 | name = Products;
79 | sourceTree = "";
80 | };
81 | 09F65634174041010000486B /* Frameworks */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 09F65635174041010000486B /* AppKit.framework */,
85 | 09F65637174041010000486B /* Foundation.framework */,
86 | );
87 | name = Frameworks;
88 | sourceTree = "";
89 | };
90 | 09F65639174041010000486B /* QuickLocalization */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 09F6563F174041010000486B /* QuickLocalization.h */,
94 | 09F65640174041010000486B /* QuickLocalization.m */,
95 | 09A343C4174068E200A713EE /* RCXcode.h */,
96 | 09A343C5174068E200A713EE /* RCXcode.m */,
97 | 0966970C1B5A20C900D29654 /* MenuItemData.plist */,
98 | 0966970E1B5A214400D29654 /* QLConstString.h */,
99 | 0966970F1B5A214400D29654 /* QLConstString.m */,
100 | 098C633C1BFDB43100A6398E /* QLXcodeHelper.h */,
101 | 098C633D1BFDB43100A6398E /* QLXcodeHelper.m */,
102 | 098C63391BFDB38E00A6398E /* QLIDEHelper.h */,
103 | 098C633A1BFDB38E00A6398E /* QLIDEHelper.m */,
104 | 096697091B5A20C200D29654 /* QLMenuGenerator.h */,
105 | 0966970A1B5A20C200D29654 /* QLMenuGenerator.m */,
106 | 09F6563A174041010000486B /* Supporting Files */,
107 | 099474B71B5A1F3000E39E3C /* OLSettingController.h */,
108 | 099474B81B5A1F3000E39E3C /* OLSettingController.m */,
109 | 099474B91B5A1F3000E39E3C /* OLSettingController.xib */,
110 | );
111 | path = QuickLocalization;
112 | sourceTree = "";
113 | };
114 | 09F6563A174041010000486B /* Supporting Files */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 09F6563B174041010000486B /* QuickLocalization-Info.plist */,
118 | 09EC581717E3B6E1002261C4 /* icon.icns */,
119 | 09F6563C174041010000486B /* InfoPlist.strings */,
120 | 09F65642174041010000486B /* QuickLocalization-Prefix.pch */,
121 | );
122 | name = "Supporting Files";
123 | sourceTree = "";
124 | };
125 | /* End PBXGroup section */
126 |
127 | /* Begin PBXNativeTarget section */
128 | 09F65631174041010000486B /* QuickLocalization */ = {
129 | isa = PBXNativeTarget;
130 | buildConfigurationList = 09F65645174041010000486B /* Build configuration list for PBXNativeTarget "QuickLocalization" */;
131 | buildPhases = (
132 | 09F6562E174041010000486B /* Sources */,
133 | 09F6562F174041010000486B /* Frameworks */,
134 | 09F65630174041010000486B /* Resources */,
135 | );
136 | buildRules = (
137 | );
138 | dependencies = (
139 | );
140 | name = QuickLocalization;
141 | productName = QuickLocalization;
142 | productReference = 09F65632174041010000486B /* QuickLocalization.xcplugin */;
143 | productType = "com.apple.product-type.bundle";
144 | };
145 | /* End PBXNativeTarget section */
146 |
147 | /* Begin PBXProject section */
148 | 09F6562A174041010000486B /* Project object */ = {
149 | isa = PBXProject;
150 | attributes = {
151 | LastUpgradeCheck = 0620;
152 | ORGANIZATIONNAME = nanaimostudio;
153 | };
154 | buildConfigurationList = 09F6562D174041010000486B /* Build configuration list for PBXProject "QuickLocalization" */;
155 | compatibilityVersion = "Xcode 3.2";
156 | developmentRegion = English;
157 | hasScannedForEncodings = 0;
158 | knownRegions = (
159 | en,
160 | );
161 | mainGroup = 09F65629174041010000486B;
162 | productRefGroup = 09F65633174041010000486B /* Products */;
163 | projectDirPath = "";
164 | projectRoot = "";
165 | targets = (
166 | 09F65631174041010000486B /* QuickLocalization */,
167 | );
168 | };
169 | /* End PBXProject section */
170 |
171 | /* Begin PBXResourcesBuildPhase section */
172 | 09F65630174041010000486B /* Resources */ = {
173 | isa = PBXResourcesBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | 099474BB1B5A1F3000E39E3C /* OLSettingController.xib in Resources */,
177 | 09F6563E174041010000486B /* InfoPlist.strings in Resources */,
178 | 0966970D1B5A20C900D29654 /* MenuItemData.plist in Resources */,
179 | 09EC581817E3B6E1002261C4 /* icon.icns in Resources */,
180 | );
181 | runOnlyForDeploymentPostprocessing = 0;
182 | };
183 | /* End PBXResourcesBuildPhase section */
184 |
185 | /* Begin PBXSourcesBuildPhase section */
186 | 09F6562E174041010000486B /* Sources */ = {
187 | isa = PBXSourcesBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | 09F65641174041010000486B /* QuickLocalization.m in Sources */,
191 | 096697101B5A214400D29654 /* QLConstString.m in Sources */,
192 | 098C633B1BFDB38E00A6398E /* QLIDEHelper.m in Sources */,
193 | 099474BA1B5A1F3000E39E3C /* OLSettingController.m in Sources */,
194 | 098C633E1BFDB43100A6398E /* QLXcodeHelper.m in Sources */,
195 | 0966970B1B5A20C200D29654 /* QLMenuGenerator.m in Sources */,
196 | 09A343C6174068E600A713EE /* RCXcode.m in Sources */,
197 | );
198 | runOnlyForDeploymentPostprocessing = 0;
199 | };
200 | /* End PBXSourcesBuildPhase section */
201 |
202 | /* Begin PBXVariantGroup section */
203 | 09F6563C174041010000486B /* InfoPlist.strings */ = {
204 | isa = PBXVariantGroup;
205 | children = (
206 | 09F6563D174041010000486B /* en */,
207 | );
208 | name = InfoPlist.strings;
209 | sourceTree = "";
210 | };
211 | /* End PBXVariantGroup section */
212 |
213 | /* Begin XCBuildConfiguration section */
214 | 09F65643174041010000486B /* Debug */ = {
215 | isa = XCBuildConfiguration;
216 | buildSettings = {
217 | ALWAYS_SEARCH_USER_PATHS = NO;
218 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
219 | CLANG_CXX_LIBRARY = "libc++";
220 | CLANG_WARN_CONSTANT_CONVERSION = YES;
221 | CLANG_WARN_EMPTY_BODY = YES;
222 | CLANG_WARN_ENUM_CONVERSION = YES;
223 | CLANG_WARN_INT_CONVERSION = YES;
224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
225 | COPY_PHASE_STRIP = NO;
226 | GCC_C_LANGUAGE_STANDARD = gnu99;
227 | GCC_DYNAMIC_NO_PIC = NO;
228 | GCC_ENABLE_OBJC_EXCEPTIONS = YES;
229 | GCC_OPTIMIZATION_LEVEL = 0;
230 | GCC_PREPROCESSOR_DEFINITIONS = (
231 | "DEBUG=1",
232 | "$(inherited)",
233 | );
234 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
235 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
236 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
237 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
238 | GCC_WARN_UNUSED_VARIABLE = YES;
239 | MACOSX_DEPLOYMENT_TARGET = 10.8;
240 | ONLY_ACTIVE_ARCH = YES;
241 | SDKROOT = macosx;
242 | };
243 | name = Debug;
244 | };
245 | 09F65644174041010000486B /* Release */ = {
246 | isa = XCBuildConfiguration;
247 | buildSettings = {
248 | ALWAYS_SEARCH_USER_PATHS = NO;
249 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
250 | CLANG_CXX_LIBRARY = "libc++";
251 | CLANG_WARN_CONSTANT_CONVERSION = YES;
252 | CLANG_WARN_EMPTY_BODY = YES;
253 | CLANG_WARN_ENUM_CONVERSION = YES;
254 | CLANG_WARN_INT_CONVERSION = YES;
255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
256 | COPY_PHASE_STRIP = YES;
257 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
258 | GCC_C_LANGUAGE_STANDARD = gnu99;
259 | GCC_ENABLE_OBJC_EXCEPTIONS = YES;
260 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
261 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
262 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
263 | GCC_WARN_UNUSED_VARIABLE = YES;
264 | MACOSX_DEPLOYMENT_TARGET = 10.8;
265 | SDKROOT = macosx;
266 | };
267 | name = Release;
268 | };
269 | 09F65646174041010000486B /* Debug */ = {
270 | isa = XCBuildConfiguration;
271 | buildSettings = {
272 | CLANG_ENABLE_OBJC_ARC = YES;
273 | COMBINE_HIDPI_IMAGES = YES;
274 | DEPLOYMENT_LOCATION = YES;
275 | DSTROOT = "$(HOME)";
276 | GCC_ENABLE_OBJC_GC = unsupported;
277 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
278 | GCC_PREFIX_HEADER = "QuickLocalization/QuickLocalization-Prefix.pch";
279 | INFOPLIST_FILE = "QuickLocalization/QuickLocalization-Info.plist";
280 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
281 | MACOSX_DEPLOYMENT_TARGET = 10.7;
282 | PRODUCT_NAME = "$(TARGET_NAME)";
283 | WRAPPER_EXTENSION = xcplugin;
284 | };
285 | name = Debug;
286 | };
287 | 09F65647174041010000486B /* Release */ = {
288 | isa = XCBuildConfiguration;
289 | buildSettings = {
290 | CLANG_ENABLE_OBJC_ARC = YES;
291 | COMBINE_HIDPI_IMAGES = YES;
292 | DEPLOYMENT_LOCATION = YES;
293 | DSTROOT = "$(HOME)";
294 | GCC_ENABLE_OBJC_GC = unsupported;
295 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
296 | GCC_PREFIX_HEADER = "QuickLocalization/QuickLocalization-Prefix.pch";
297 | INFOPLIST_FILE = "QuickLocalization/QuickLocalization-Info.plist";
298 | INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
299 | MACOSX_DEPLOYMENT_TARGET = 10.7;
300 | PRODUCT_NAME = "$(TARGET_NAME)";
301 | WRAPPER_EXTENSION = xcplugin;
302 | };
303 | name = Release;
304 | };
305 | /* End XCBuildConfiguration section */
306 |
307 | /* Begin XCConfigurationList section */
308 | 09F6562D174041010000486B /* Build configuration list for PBXProject "QuickLocalization" */ = {
309 | isa = XCConfigurationList;
310 | buildConfigurations = (
311 | 09F65643174041010000486B /* Debug */,
312 | 09F65644174041010000486B /* Release */,
313 | );
314 | defaultConfigurationIsVisible = 0;
315 | defaultConfigurationName = Release;
316 | };
317 | 09F65645174041010000486B /* Build configuration list for PBXNativeTarget "QuickLocalization" */ = {
318 | isa = XCConfigurationList;
319 | buildConfigurations = (
320 | 09F65646174041010000486B /* Debug */,
321 | 09F65647174041010000486B /* Release */,
322 | );
323 | defaultConfigurationIsVisible = 0;
324 | defaultConfigurationName = Release;
325 | };
326 | /* End XCConfigurationList section */
327 | };
328 | rootObject = 09F6562A174041010000486B /* Project object */;
329 | }
330 |
--------------------------------------------------------------------------------