Skip to content

Commit 36900fc

Browse files
committed
XML export/import support (NSPropertyListXMLFormat_v1_0)
1 parent 7925c7f commit 36900fc

File tree

7 files changed

+172
-47
lines changed

7 files changed

+172
-47
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
# SCStringsUtility
22

3-
SCStringsUtility is a simple OS X Application built for easing the way we deal with localizable strings. It started off as a simple to/from CSV utility but ended up being a little bit more than that.
3+
SCStringsUtility is an OS X Application built for easing the way we deal with localizable strings. It started off as a simple to/from CSV utility but ended up being a little bit more than that.
44

55
![SCStringsUtility](http://dl.dropbox.com/u/12748201/SCStringsUtility.png)
66

77
## Features
88
* Import from Xcode project using genstrings and its .string files (options for a different genstrings routine and positional parameters)
99

10-
* Console for displaying genstrings warnings
11-
12-
* Save back on top of the original files
10+
* Export to Localizable.strings/CSV/XML (with comments / key for missing translations)
1311

14-
* Export to CSV/Localizable.strings
12+
* Import from CSV/XML
1513

16-
* Import from CSV
14+
* Save back on top of the original files
1715

1816
* Search (filter all or just the keys)
1917

2018
* Editing & undo/redo support
2119

20+
* Console for displaying genstrings warnings
21+
2222
## How to use it
2323
Fire up the application and point it to an .xcodeproj
2424

2525
## ToDo
2626
- Individual cell selection
27+
- Better error handling
2728

2829
## License
2930
SCStringsUtility is released under the GNU GENERAL PUBLIC LICENSE (see the LICENSE file)

SCStringsUtility.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
1831CBE21628086A004B6DD4 /* SCRootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1831CBE01628086A004B6DD4 /* SCRootViewController.xib */; };
1212
1831CBE4162809E0004B6DD4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1831CBE3162809E0004B6DD4 /* QuartzCore.framework */; };
1313
1843F4501650EB9900CEDBEF /* icon-export.png in Resources */ = {isa = PBXBuildFile; fileRef = 1843F44C1650EB9900CEDBEF /* icon-export.png */; };
14-
1843F4511650EB9900CEDBEF /* icon-import.png in Resources */ = {isa = PBXBuildFile; fileRef = 1843F44D1650EB9900CEDBEF /* icon-import.png */; };
1514
1843F4521650EB9900CEDBEF /* icon-open.png in Resources */ = {isa = PBXBuildFile; fileRef = 1843F44E1650EB9900CEDBEF /* icon-open.png */; };
1615
1843F4531650EB9900CEDBEF /* icon-save.png in Resources */ = {isa = PBXBuildFile; fileRef = 1843F44F1650EB9900CEDBEF /* icon-save.png */; };
1716
186758CD1654C83F00BEE1E1 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 186758CC1654C83F00BEE1E1 /* MainMenu.xib */; };
@@ -53,7 +52,6 @@
5352
1831CBE01628086A004B6DD4 /* SCRootViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SCRootViewController.xib; sourceTree = "<group>"; };
5453
1831CBE3162809E0004B6DD4 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
5554
1843F44C1650EB9900CEDBEF /* icon-export.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-export.png"; sourceTree = "<group>"; };
56-
1843F44D1650EB9900CEDBEF /* icon-import.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-import.png"; sourceTree = "<group>"; };
5755
1843F44E1650EB9900CEDBEF /* icon-open.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-open.png"; sourceTree = "<group>"; };
5856
1843F44F1650EB9900CEDBEF /* icon-save.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-save.png"; sourceTree = "<group>"; };
5957
186758CC1654C83F00BEE1E1 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
@@ -109,7 +107,6 @@
109107
isa = PBXGroup;
110108
children = (
111109
1843F44C1650EB9900CEDBEF /* icon-export.png */,
112-
1843F44D1650EB9900CEDBEF /* icon-import.png */,
113110
1843F44E1650EB9900CEDBEF /* icon-open.png */,
114111
1843F44F1650EB9900CEDBEF /* icon-save.png */,
115112
);
@@ -272,7 +269,6 @@
272269
18D36760162772B600B6BACE /* Credits.rtf in Resources */,
273270
1831CBE21628086A004B6DD4 /* SCRootViewController.xib in Resources */,
274271
1843F4501650EB9900CEDBEF /* icon-export.png in Resources */,
275-
1843F4511650EB9900CEDBEF /* icon-import.png in Resources */,
276272
1843F4521650EB9900CEDBEF /* icon-open.png in Resources */,
277273
1843F4531650EB9900CEDBEF /* icon-save.png in Resources */,
278274
186758CD1654C83F00BEE1E1 /* MainMenu.xib in Resources */,

SCStringsUtility/Others/OrderedDictionary.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ - (void)setObject:(id)anObject forKey:(id)aKey
9696
if (![dictionary objectForKey:aKey])
9797
{
9898
[array addObject:aKey];
99+
array = [[array sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] mutableCopy];
99100
}
100101
[dictionary setObject:anObject forKey:aKey];
101102
}
-4.86 KB
Binary file not shown.

SCStringsUtility/SCRootViewController.m

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,9 @@ - (IBAction)onExportClick:(id)sender
132132
{
133133
case SCFileTypeXcodeProject:
134134
{
135-
[self.stringsController generateStringFilesAtPath:[[self.exportPanel URL] path] success:^{
136-
137-
} failure:^(NSError *error) {
138-
NSLog(@"Could not generate string files %@", error);
139-
}];
135+
[self.stringsController generateStringFilesAtPath:[[self.exportPanel URL] path]
136+
success:nil
137+
failure:nil];
140138

141139
break;
142140
}
@@ -145,16 +143,24 @@ - (IBAction)onExportClick:(id)sender
145143
BOOL includeComments = [self.exportPanelAccessoryView shouldIncludeComments];
146144
BOOL useKeyForMissingTranslations = [self.exportPanelAccessoryView shouldUseKeyForMissingTranslations];
147145

148-
[self.stringsController generateCSVAtPath:[[self.exportPanel URL] path] includeComments:includeComments useKeyForEmptyTranslations:useKeyForMissingTranslations success:^{
149-
150-
} failure:^(NSError *error) {
151-
NSLog(@"Could not generate CSV file %@", error);
152-
}];
146+
[self.stringsController generateCSVAtPath:[[self.exportPanel URL] path]
147+
includeComments:includeComments
148+
useKeyForEmptyTranslations:useKeyForMissingTranslations
149+
success:nil
150+
failure:nil];
153151

154152
break;
155153
}
156154
case SCFileTypeXML:
157155
{
156+
BOOL includeComments = [self.exportPanelAccessoryView shouldIncludeComments];
157+
BOOL useKeyForMissingTranslations = [self.exportPanelAccessoryView shouldUseKeyForMissingTranslations];
158+
159+
[self.stringsController generateXMLFileAtPath:[[self.exportPanel URL] path]
160+
includeComments:includeComments
161+
useKeyForEmptyTranslations:useKeyForMissingTranslations
162+
success:nil
163+
failure:nil];
158164
break;
159165
}
160166
default:
@@ -203,22 +209,9 @@ - (void)exportAccessoryView:(SCExportAccessoryView*)view didSelectFormatType:(SC
203209

204210
- (IBAction)onSaveClick:(id)sender
205211
{
206-
if(self.stringsController.sourceType == SCFileTypeInvalid) return;
207-
208-
if(self.stringsController.sourceType == SCFileTypeXcodeProject) {
209-
[self.stringsController generateStringFilesAtPath:nil success:^{
210-
211-
} failure:^(NSError *error) {
212-
NSLog(@"Could not generate string files %@", error);
213-
}];
214-
}
215-
else {
216-
[self.stringsController generateCSVAtPath:nil includeComments:YES useKeyForEmptyTranslations:NO success:^{
217-
218-
} failure:^(NSError *error) {
219-
NSLog(@"Could not generate CSV file %@", error);
220-
}];
221-
}
212+
[self.stringsController save:nil failure:^(NSError *error) {
213+
SCLog(@"Could not save data %@", error);
214+
}];
222215
}
223216

224217
- (IBAction)onOpenClick:(id)sender
@@ -230,7 +223,7 @@ - (IBAction)onOpenClick:(id)sender
230223
[openPanel setCanCreateDirectories:NO];
231224
[openPanel setAllowsMultipleSelection:NO];
232225

233-
[openPanel setAllowedFileTypes:@[@"xcodeproj", @"csv"]];
226+
[openPanel setAllowedFileTypes:@[@"xcodeproj", @"csv", @"xml"]];
234227

235228
NSInteger result = [openPanel runModal];
236229
if(result != NSOKButton) return;
@@ -254,19 +247,21 @@ - (IBAction)onOpenClick:(id)sender
254247
[self.stringsController importProjectAtPath:[[openPanel URL] path]
255248
positionalParameters:includePositionalParameters
256249
genstringsRoutine:routine success:^{ [self reloadData];}
257-
failure:^(NSError *error) { NSLog(@"Could not import Xcode project %@", error);}];
250+
failure:^(NSError *error) { SCLog(@"Could not import Xcode project %@", error);}];
258251
break;
259252
}
260253
case SCFileTypeCSV:
261254
{
262255
[self.stringsController importCSVFileAtPath:[[openPanel URL] path]
263256
success:^{ [self reloadData];}
264-
failure:^(NSError *error) { NSLog(@"Could not import CSV file %@",error);}];
257+
failure:^(NSError *error) { SCLog(@"Could not import CSV file %@",error);}];
265258
break;
266259
}
267260
case SCFileTypeXML:
268261
{
269-
262+
[self.stringsController importXMLFileAtPath:[[openPanel URL] path]
263+
success:^{ [self reloadData]; }
264+
failure:^(NSError *error) { SCLog(@"Could not import XML file %@",error);}];
270265
}
271266
default:
272267
{

SCStringsUtility/SCStringsController.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
- (void)reset;
2323

24+
- (void)save:(void (^)(void))success failure:(void (^)(NSError *error))failure;
25+
2426
- (void)importProjectAtPath:(NSString*)path
2527
positionalParameters:(BOOL)includePositionalParameters
2628
genstringsRoutine:(NSString*)genstringsRoutine
@@ -31,6 +33,10 @@
3133
success:(void (^)(void))success
3234
failure:(void(^)(NSError *error))failure;
3335

36+
- (void)importXMLFileAtPath:(NSString*)path
37+
success:(void (^)(void))success
38+
failure:(void(^)(NSError *error))failure;
39+
3440
- (void)generateCSVAtPath:(NSString *)path
3541
includeComments:(BOOL)includeComments
3642
useKeyForEmptyTranslations:(BOOL)useKeyForEmptyTranslations
@@ -41,6 +47,12 @@ useKeyForEmptyTranslations:(BOOL)useKeyForEmptyTranslations
4147
success:(void (^)(void))success
4248
failure:(void (^)(NSError *error))failure;
4349

50+
- (void)generateXMLFileAtPath:(NSString*)path
51+
includeComments:(BOOL)includeComments
52+
useKeyForEmptyTranslations:(BOOL)useKeyForEmptyTranslations
53+
success:(void (^)(void))success
54+
failure:(void (^)(NSError *error))failure;
55+
4456
- (void)filterEntriesWithSearchString:(NSString*)searchString onlyKeys:(BOOL)searchOnlyKeys;
4557

4658
@end

0 commit comments

Comments
 (0)