Skip to content

Commit a0658ce

Browse files
authored
initial i18n support and add ES language (#264)
1 parent 0a935cc commit a0658ce

14 files changed

+688
-34
lines changed

README.md

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,22 +117,22 @@ See also [#185](https://github.com/syncthing/syncthing-macos/issues/185) and the
117117

118118
## Uninstallation
119119

120-
On Mac OS X you drop the application from the Application folder to your Trash.
121-
But there are some user specific files are kept elsewhere, which are located under
120+
On Mac OS X you drop the application from the Application folder to your Trash.
121+
But there are some user specific files are kept elsewhere, which are located under
122122
`$HOME/Library/Application Support/Syncthing`. The files in this folder are the configuration,
123123
encryption/profile files and the database cache. For more information see
124124
[docs.syncthing.net/users/config.html](https://docs.syncthing.net/users/config.html#description).
125125

126126
## Disable automatic update checker
127127

128-
By default the Syncthing macOS application checks automatically for updates. To disable (or re-enable) the
128+
By default the Syncthing macOS application checks automatically for updates. To disable (or re-enable) the
129129
auto update check one must set the Sparkle updater parameter from the commandline:
130130

131131
```
132132
defaults write com.github.xor-gate.syncthing-macosx SUEnableAutomaticChecks 0
133133
```
134134

135-
This setting is un-adviced and therefor only available from the commandline. When your system is not
135+
This setting is un-adviced and therefor only available from the commandline. When your system is not
136136
supported anymore and don't want to get notified of unsupported updates disabling then is recommended.
137137

138138
# Prerequisites for building/using everything in this repository
@@ -198,7 +198,7 @@ jerry@Jerrys-iMac ~ % defaults read com.github.xor-gate.syncthing-macosx
198198
### Override Syncthing Daeomon `Executable` property (power-users only)
199199

200200
If you want to use the nice GUI but have your own executable located outside the `Syncthing.app` bundle,
201-
then the `Executable` configuration parameter can be manually overwritten with the `defaults` commandline
201+
then the `Executable` configuration parameter can be manually overwritten with the `defaults` commandline
202202
tool using builtin Terminal or iTerm2. The last arguments should be changed to the syncthing daemon golang
203203
application.
204204

@@ -276,3 +276,35 @@ basicly these steps automatically:
276276
* Manually download the release `.dmg` from [github.com actions](https://github.com/syncthing/syncthing-macos/actions/workflows/build-syncthing-macos.yml) which is correctly signed and notarized
277277
* Manually [create a new Github release](https://github.com/syncthing/syncthing-macos/releases/new) with tag `v<major>.<minor>.<patch>-<bundle index>`
278278
* Run deployment of Sparkle updater [appcast.xml](https://github.com/syncthing/syncthing-macos/actions/workflows/generate-appcast.yml). Which turns [GitHub Releases JSON into a Sparkle appcast.xml file](https://github.com/syncthing/syncthing-macos/tree/develop/cmd/ghreleases2appcast). (See also [Sparkle documentation](https://sparkle-project.org/documentation/)) to push to users.
279+
280+
## Support for additional languages
281+
282+
### 1. Add Language in Xcode
283+
284+
1. Open `syncthing.xcworkspace`
285+
2. Select project root -> **Project -> Info -> Localizations**
286+
3. Click **+** and select target language
287+
4. Select all files when prompted
288+
289+
### 2. Translate
290+
291+
Edit files in `syncthing/[language_code].lproj/`:
292+
293+
```
294+
/* Keep key, translate value */
295+
"Up to date" = "Actualizado";
296+
```
297+
298+
### 3. Update Info.plist
299+
300+
Add language code to `CFBundleLocalizations`:
301+
```xml
302+
<string>es</string> <!-- New language -->
303+
```
304+
305+
### 4. Test
306+
307+
```bash
308+
make debug
309+
open ./Build/Products/Debug/Syncthing.app --args -AppleLanguages '(language_code)'
310+
```

syncthing.xcodeproj/project.pbxproj

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@
2727
29AF1BA3210F11BF004212DE /* DaemonProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29AFA4CD210F10FA00071E5E /* DaemonProcess.swift */; };
2828
BD71E04946BAD5B0A9FACC3D /* libPods-syncthing.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 014971905AAC00CB5291E063 /* libPods-syncthing.a */; };
2929
C4460A801D0DD2D500200C21 /* STPreferencesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4460A7D1D0DD2D500200C21 /* STPreferencesWindowController.m */; };
30-
C4460A831D0DD38F00200C21 /* STPreferencesWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4460A821D0DD38F00200C21 /* STPreferencesWindow.xib */; };
30+
C4460A831D0DD38F00200C21 /* STPreferencesWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = D4A1B57A1E2A3F4900C8E2AA /* STPreferencesWindow.xib */; };
3131
C469AFEB25D7E76900904DD7 /* STLoginItem.m in Sources */ = {isa = PBXBuildFile; fileRef = C469AFEA25D7E76900904DD7 /* STLoginItem.m */; };
32-
C4946B011D5877F2008447A2 /* STAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4946B001D5877F2008447A2 /* STAboutWindow.xib */; };
32+
C4946B011D5877F2008447A2 /* STAboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = D4A1B5791E2A3F4900C8E2A9 /* STAboutWindow.xib */; };
3333
C4946B031D587878008447A2 /* STAboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4946B021D587878008447A2 /* STAboutWindowController.m */; };
3434
C4A415651D0D579D00DC6018 /* STApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = C4A415641D0D579D00DC6018 /* STApplication.m */; };
3535
C4A415681D0D579D00DC6018 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C4A415671D0D579D00DC6018 /* main.m */; };
3636
C4A4156A1D0D579D00DC6018 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C4A415691D0D579D00DC6018 /* Assets.xcassets */; };
3737
C4A4156D1D0D579D00DC6018 /* STApplication.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4A4156B1D0D579D00DC6018 /* STApplication.xib */; };
3838
C4F0E82E1DA1B9CF00435310 /* STPreferencesWindowGeneralViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F0E82C1DA1B9CF00435310 /* STPreferencesWindowGeneralViewController.m */; };
39-
C4F0E82F1DA1B9CF00435310 /* STPreferencesWindowGeneralView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4F0E82D1DA1B9CF00435310 /* STPreferencesWindowGeneralView.xib */; };
39+
C4F0E82F1DA1B9CF00435310 /* STPreferencesWindowGeneralView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D4A1B57C1E2A3F4900C8E2AC /* STPreferencesWindowGeneralView.xib */; };
4040
C4FFB0661D0D7F870015D14A /* XGSyncthing.m in Sources */ = {isa = PBXBuildFile; fileRef = C4FFB0641D0D7E4C0015D14A /* XGSyncthing.m */; };
41+
D4A1B5701E2A3F4900C8E2A1 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4A1B5721E2A3F4900C8E2A2 /* Localizable.strings */; };
4142
/* End PBXBuildFile section */
4243

4344
/* Begin PBXContainerItemProxy section */
@@ -71,18 +72,22 @@
7172
298A5C44210DA6C40034B89F /* LocalhostTLSDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalhostTLSDelegate.h; sourceTree = "<group>"; };
7273
29AFA4CD210F10FA00071E5E /* DaemonProcess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DaemonProcess.swift; sourceTree = "<group>"; };
7374
29CC334D4211142108D2F82C /* Pods-syncthing.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-syncthing.release.xcconfig"; path = "Pods/Target Support Files/Pods-syncthing/Pods-syncthing.release.xcconfig"; sourceTree = "<group>"; };
75+
9A38F85F2E80F1B600100A57 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/STApplication.strings; sourceTree = "<group>"; };
76+
9A38F8602E80F1B600100A57 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/STAboutWindow.strings; sourceTree = "<group>"; };
77+
9A38F8612E80F1B600100A57 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/STPreferencesWindow.strings; sourceTree = "<group>"; };
78+
9A38F8622E80F1B600100A57 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/STPreferencesWindowGeneralView.strings; sourceTree = "<group>"; };
79+
9A38F8632E80F1B700100A57 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
7480
C44262761D0DEF9F005340C2 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
7581
C4460A7C1D0DD2D500200C21 /* STPreferencesWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STPreferencesWindowController.h; path = Controllers/STPreferencesWindowController.h; sourceTree = "<group>"; };
7682
C4460A7D1D0DD2D500200C21 /* STPreferencesWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = STPreferencesWindowController.m; path = Controllers/STPreferencesWindowController.m; sourceTree = "<group>"; };
77-
C4460A821D0DD38F00200C21 /* STPreferencesWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = STPreferencesWindow.xib; path = UI/STPreferencesWindow.xib; sourceTree = "<group>"; };
7883
C4576BD51D11E3210031BCFD /* create-dmg.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "create-dmg.sh"; path = "syncthing/Scripts/create-dmg.sh"; sourceTree = "<group>"; };
7984
C4576BE51D11E79F0031BCFD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
8085
C4576BE71D11E7C00031BCFD /* libobjc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libobjc.tbd; path = usr/lib/libobjc.tbd; sourceTree = SDKROOT; };
8186
C4576BE91D11E7E10031BCFD /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
8287
C469AFE325D7CFE400904DD7 /* syncthing-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "syncthing-Bridging-Header.h"; sourceTree = "<group>"; };
8388
C469AFE925D7E76900904DD7 /* STLoginItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STLoginItem.h; sourceTree = "<group>"; };
8489
C469AFEA25D7E76900904DD7 /* STLoginItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STLoginItem.m; sourceTree = "<group>"; };
85-
C4946B001D5877F2008447A2 /* STAboutWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = STAboutWindow.xib; path = UI/STAboutWindow.xib; sourceTree = "<group>"; };
90+
C4946B001D5877F2008447A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/STAboutWindow.xib; sourceTree = "<group>"; };
8691
C4946B021D587878008447A2 /* STAboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = STAboutWindowController.m; path = Controllers/STAboutWindowController.m; sourceTree = "<group>"; };
8792
C4946B041D587907008447A2 /* STAboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STAboutWindowController.h; path = Controllers/STAboutWindowController.h; sourceTree = "<group>"; };
8893
C4A415601D0D579D00DC6018 /* Syncthing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Syncthing.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -96,9 +101,11 @@
96101
C4D896121D0DF90900D42F73 /* syncthing-resource.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "syncthing-resource.sh"; path = "syncthing/Scripts/syncthing-resource.sh"; sourceTree = "<group>"; };
97102
C4F0E82B1DA1B9CF00435310 /* STPreferencesWindowGeneralViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPreferencesWindowGeneralViewController.h; sourceTree = "<group>"; };
98103
C4F0E82C1DA1B9CF00435310 /* STPreferencesWindowGeneralViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPreferencesWindowGeneralViewController.m; sourceTree = "<group>"; };
99-
C4F0E82D1DA1B9CF00435310 /* STPreferencesWindowGeneralView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = STPreferencesWindowGeneralView.xib; sourceTree = "<group>"; };
100104
C4FFB0631D0D7E440015D14A /* XGSyncthing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XGSyncthing.h; path = syncthing/XGSyncthing.h; sourceTree = SOURCE_ROOT; };
101105
C4FFB0641D0D7E4C0015D14A /* XGSyncthing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XGSyncthing.m; path = syncthing/XGSyncthing.m; sourceTree = SOURCE_ROOT; };
106+
D4A1B5731E2A3F4900C8E2A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
107+
D4A1B57B1E2A3F4900C8E2AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/STPreferencesWindow.xib; sourceTree = "<group>"; };
108+
D4A1B57D1E2A3F4900C8E2AD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/STPreferencesWindowGeneralView.xib; sourceTree = "<group>"; };
102109
FB3E4EE48CFC608AD4FBDE77 /* Pods-syncthing.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-syncthing.debug.xcconfig"; path = "Pods/Target Support Files/Pods-syncthing/Pods-syncthing.debug.xcconfig"; sourceTree = "<group>"; };
103110
/* End PBXFileReference section */
104111

@@ -229,9 +236,10 @@
229236
isa = PBXGroup;
230237
children = (
231238
C4A4156B1D0D579D00DC6018 /* STApplication.xib */,
232-
C4946B001D5877F2008447A2 /* STAboutWindow.xib */,
233-
C4460A821D0DD38F00200C21 /* STPreferencesWindow.xib */,
234-
C4F0E82D1DA1B9CF00435310 /* STPreferencesWindowGeneralView.xib */,
239+
D4A1B5791E2A3F4900C8E2A9 /* STAboutWindow.xib */,
240+
D4A1B57A1E2A3F4900C8E2AA /* STPreferencesWindow.xib */,
241+
D4A1B57C1E2A3F4900C8E2AC /* STPreferencesWindowGeneralView.xib */,
242+
D4A1B5721E2A3F4900C8E2A2 /* Localizable.strings */,
235243
);
236244
name = UI;
237245
sourceTree = "<group>";
@@ -297,6 +305,7 @@
297305
knownRegions = (
298306
en,
299307
Base,
308+
es,
300309
);
301310
mainGroup = C4A415571D0D579D00DC6018;
302311
productRefGroup = C4A415611D0D579D00DC6018 /* Products */;
@@ -319,6 +328,7 @@
319328
C4460A831D0DD38F00200C21 /* STPreferencesWindow.xib in Resources */,
320329
C4946B011D5877F2008447A2 /* STAboutWindow.xib in Resources */,
321330
C4F0E82F1DA1B9CF00435310 /* STPreferencesWindowGeneralView.xib in Resources */,
331+
D4A1B5701E2A3F4900C8E2A1 /* Localizable.strings in Resources */,
322332
);
323333
runOnlyForDeploymentPostprocessing = 0;
324334
};
@@ -423,10 +433,47 @@
423433
isa = PBXVariantGroup;
424434
children = (
425435
C4A4156C1D0D579D00DC6018 /* Base */,
436+
9A38F85F2E80F1B600100A57 /* es */,
426437
);
427438
name = STApplication.xib;
428439
sourceTree = "<group>";
429440
};
441+
D4A1B5721E2A3F4900C8E2A2 /* Localizable.strings */ = {
442+
isa = PBXVariantGroup;
443+
children = (
444+
D4A1B5731E2A3F4900C8E2A3 /* Base */,
445+
9A38F8632E80F1B700100A57 /* es */,
446+
);
447+
name = Localizable.strings;
448+
sourceTree = "<group>";
449+
};
450+
D4A1B5791E2A3F4900C8E2A9 /* STAboutWindow.xib */ = {
451+
isa = PBXVariantGroup;
452+
children = (
453+
C4946B001D5877F2008447A2 /* Base */,
454+
9A38F8602E80F1B600100A57 /* es */,
455+
);
456+
name = STAboutWindow.xib;
457+
sourceTree = "<group>";
458+
};
459+
D4A1B57A1E2A3F4900C8E2AA /* STPreferencesWindow.xib */ = {
460+
isa = PBXVariantGroup;
461+
children = (
462+
D4A1B57B1E2A3F4900C8E2AB /* Base */,
463+
9A38F8612E80F1B600100A57 /* es */,
464+
);
465+
name = STPreferencesWindow.xib;
466+
sourceTree = "<group>";
467+
};
468+
D4A1B57C1E2A3F4900C8E2AC /* STPreferencesWindowGeneralView.xib */ = {
469+
isa = PBXVariantGroup;
470+
children = (
471+
D4A1B57D1E2A3F4900C8E2AD /* Base */,
472+
9A38F8622E80F1B600100A57 /* es */,
473+
);
474+
name = STPreferencesWindowGeneralView.xib;
475+
sourceTree = "<group>";
476+
};
430477
/* End PBXVariantGroup section */
431478

432479
/* Begin XCBuildConfiguration section */
@@ -448,6 +495,7 @@
448495
isa = XCBuildConfiguration;
449496
buildSettings = {
450497
ALWAYS_SEARCH_USER_PATHS = YES;
498+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
451499
CLANG_ANALYZER_NONNULL = YES;
452500
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
453501
CLANG_CXX_LIBRARY = "libc++";
@@ -506,6 +554,7 @@
506554
isa = XCBuildConfiguration;
507555
buildSettings = {
508556
ALWAYS_SEARCH_USER_PATHS = YES;
557+
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
509558
CLANG_ANALYZER_NONNULL = YES;
510559
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
511560
CLANG_CXX_LIBRARY = "libc++";
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Localizable.strings
3+
syncthing
4+
5+
Base localization (English)
6+
*/
7+
8+
/* Notification title */
9+
"Syncthing" = "Syncthing";
10+
11+
/* Status tooltips */
12+
"Up to date" = "Up to date";
13+
"Synchronising" = "Synchronising";
14+
"Pause" = "Pause";
15+
"Not running" = "Not running";
16+
"Error" = "Error";
17+
18+
/* Device menu items */
19+
"Resume All Devices" = "Resume All Devices";
20+
"Pause All Devices" = "Pause All Devices";
21+
22+
/* Daemon status */
23+
"Syncthing Service (Running)" = "Syncthing Service (Running)";
24+
"Syncthing Service (Stopped)" = "Syncthing Service (Stopped)";
25+
26+
/* API status */
27+
"API (Online)" = "API (Online)";
28+
"API (Offline)" = "API (Offline)";
29+
30+
/* Connection status */
31+
"Online" = "Online";
32+
"Running (Offline)" = "Running (Offline)";
33+
"Unknown (Online)" = "Unknown (Online)";
34+
"Unavailable" = "Unavailable";
35+
36+
/* Menu titles */
37+
"Folders" = "Folders";
38+
39+
/* Tooltip template (version %@ and status %@) */
40+
"Syncthing %@\n%@" = "Syncthing %@\n%@";

0 commit comments

Comments
 (0)