summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-06-11 12:39:28 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-06-11 12:39:28 +0300
commit31f7eafd9c6897cdf0ee7d6eeaade9dcc65cb006 (patch)
tree415707ca26c04ff1bee461c685e79c4302546cd4
parent703d2b41fa299a9f8e24a5f6064c3624c3dedbbb (diff)
iOS: Opening a file via document picker
Use a native file picker to open files. Declare support for .gmi/.gemini files so they can be opened via Files and share sheets.
-rw-r--r--po/en.po3
-rw-r--r--res/iOSBundleInfo.plist.in246
-rw-r--r--res/lang/de.binbin20949 -> 20976 bytes
-rw-r--r--res/lang/en.binbin19654 -> 19681 bytes
-rw-r--r--res/lang/es.binbin22028 -> 22055 bytes
-rw-r--r--res/lang/fi.binbin22151 -> 22178 bytes
-rw-r--r--res/lang/fr.binbin22561 -> 22588 bytes
-rw-r--r--res/lang/ia.binbin21859 -> 21886 bytes
-rw-r--r--res/lang/ie.binbin21417 -> 21444 bytes
-rw-r--r--res/lang/pl.binbin22665 -> 22692 bytes
-rw-r--r--res/lang/ru.binbin32896 -> 32923 bytes
-rw-r--r--res/lang/sr.binbin32301 -> 32328 bytes
-rw-r--r--res/lang/tok.binbin20042 -> 20069 bytes
-rw-r--r--res/lang/zh_Hans.binbin18818 -> 18845 bytes
-rw-r--r--res/lang/zh_Hant.binbin19003 -> 19030 bytes
-rw-r--r--src/app.c13
-rw-r--r--src/ios.h1
-rw-r--r--src/ios.m26
-rw-r--r--src/ui/root.c2
19 files changed, 182 insertions, 109 deletions
diff --git a/po/en.po b/po/en.po
index 5172977a..29eadd94 100644
--- a/po/en.po
+++ b/po/en.po
@@ -468,6 +468,9 @@ msgstr "Open in New Tab"
468msgid "menu.opentab.background" 468msgid "menu.opentab.background"
469msgstr "Open in Background Tab" 469msgstr "Open in Background Tab"
470 470
471msgid "menu.openfile"
472msgstr "Open File…"
473
471msgid "menu.edit" 474msgid "menu.edit"
472msgstr "Edit…" 475msgstr "Edit…"
473 476
diff --git a/res/iOSBundleInfo.plist.in b/res/iOSBundleInfo.plist.in
index 1cf0a303..f47df7cd 100644
--- a/res/iOSBundleInfo.plist.in
+++ b/res/iOSBundleInfo.plist.in
@@ -1,116 +1,148 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 2<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0"> 3<plist version="1.0">
4<dict> 4 <dict>
5 <key>CFBundleDevelopmentRegion</key> 5 <key>CFBundleDevelopmentRegion</key>
6 <string>English</string> 6 <string>English</string>
7 <key>CFBundleExecutable</key> 7 <key>CFBundleExecutable</key>
8 <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> 8 <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
9 <key>CFBundleGetInfoString</key> 9 <key>CFBundleGetInfoString</key>
10 <string>${MACOSX_BUNDLE_INFO_STRING}</string> 10 <string>${MACOSX_BUNDLE_INFO_STRING}</string>
11 <key>CFBundleIconName</key> 11 <key>CFBundleIconName</key>
12 <string>${MACOSX_BUNDLE_ICON_FILE}</string> 12 <string>${MACOSX_BUNDLE_ICON_FILE}</string>
13 <key>CFBundleIdentifier</key> 13 <key>CFBundleIdentifier</key>
14 <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> 14 <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
15 <key>CFBundleInfoDictionaryVersion</key> 15 <key>CFBundleInfoDictionaryVersion</key>
16 <string>6.0</string> 16 <string>6.0</string>
17 <key>CFBundleName</key> 17 <key>CFBundleName</key>
18 <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> 18 <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
19 <key>CFBundlePackageType</key> 19 <key>CFBundlePackageType</key>
20 <string>APPL</string> 20 <string>APPL</string>
21 <key>CFBundleVersion</key> 21 <key>CFBundleVersion</key>
22 <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> 22 <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
23 <key>CFBundleShortVersionString</key> 23 <key>CFBundleShortVersionString</key>
24 <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> 24 <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
25 <key>CFBundleSignature</key> 25 <key>CFBundleSignature</key>
26 <string>????</string> 26 <string>????</string>
27 <key>CSResourcesFileMapped</key> 27 <key>CSResourcesFileMapped</key>
28 <true/> 28 <true/>
29 <key>NSHumanReadableCopyright</key> 29 <key>NSHumanReadableCopyright</key>
30 <string>${MACOSX_BUNDLE_COPYRIGHT}</string> 30 <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
31 <key>NSHighResolutionCapable</key> 31 <key>NSHighResolutionCapable</key>
32 <true/> 32 <true/>
33 <key>NSRequiresAquaSystemAppearance</key> 33 <key>NSRequiresAquaSystemAppearance</key>
34 <false/> 34 <false/>
35 <key>NSSupportsAutomaticGraphicsSwitching</key> 35 <key>NSSupportsAutomaticGraphicsSwitching</key>
36 <true/> 36 <true/>
37 <key>UISupportedInterfaceOrientations</key> 37 <key>UISupportedInterfaceOrientations</key>
38 <array> 38 <array>
39 <string>UIInterfaceOrientationPortrait</string> 39 <string>UIInterfaceOrientationPortrait</string>
40 <string>UIInterfaceOrientationLandscapeLeft</string> 40 <string>UIInterfaceOrientationLandscapeLeft</string>
41 <string>UIInterfaceOrientationLandscapeRight</string> 41 <string>UIInterfaceOrientationLandscapeRight</string>
42 </array> 42 </array>
43 <key>UISupportedInterfaceOrientations~ipad</key> 43 <key>UISupportedInterfaceOrientations~ipad</key>
44 <array> 44 <array>
45 <string>UIInterfaceOrientationPortrait</string> 45 <string>UIInterfaceOrientationPortrait</string>
46 <string>UIInterfaceOrientationPortraitUpsideDown</string> 46 <string>UIInterfaceOrientationPortraitUpsideDown</string>
47 <string>UIInterfaceOrientationLandscapeLeft</string> 47 <string>UIInterfaceOrientationLandscapeLeft</string>
48 <string>UIInterfaceOrientationLandscapeRight</string> 48 <string>UIInterfaceOrientationLandscapeRight</string>
49 </array> 49 </array>
50 <key>UILaunchStoryboardName</key> 50 <key>UILaunchStoryboardName</key>
51 <string>LaunchScreen</string> 51 <string>LaunchScreen</string>
52 <key>UIBackgroundModes</key> 52 <key>UIBackgroundModes</key>
53 <array> 53 <array>
54 <string>audio</string> 54 <string>audio</string>
55 </array> 55 </array>
56 <key>ITSAppUsesNonExemptEncryption</key> 56 <key>ITSAppUsesNonExemptEncryption</key>
57 <false/> 57 <false/>
58 <key>LSSupportsOpeningDocumentsInPlace</key> 58 <key>LSSupportsOpeningDocumentsInPlace</key>
59 <false/> 59 <false/>
60 <key>CFBundleDocumentTypes</key> 60 <key>CFBundleDocumentTypes</key>
61 <array> 61 <array>
62 <dict> 62 <dict>
63 <key>CFBundleTypeExtensions</key> 63 <key>LSItemContentTypes</key>
64 <array> 64 <array>
65 <string>gmi</string> 65 <string>fi.skyjake.lagrange.gemini</string>
66 <string>gemini</string> 66 <string>public.plain-text</string>
67 </array> 67 </array>
68 <key>CFBundleTypeIconFile</key> 68 </dict>
69 <string>text-gemini.icns</string> 69 <dict>
70 <key>CFBundleTypeName</key> 70 <key>CFBundleTypeExtensions</key>
71 <string>Gemini Text File</string> 71 <array>
72 <key>CFBundleTypeRole</key> 72 <string>gmi</string>
73 <string>Viewer</string> 73 <string>gemini</string>
74 <key>LSHandlerRank</key> 74 </array>
75 <string>Default</string> 75 <key>CFBundleTypeIconFile</key>
76 <key>LSTypeIsPackage</key> 76 <string>text-gemini.icns</string>
77 <false/> 77 <key>CFBundleTypeName</key>
78 </dict> 78 <string>Gemini Text File</string>
79 <dict> 79 <key>CFBundleTypeRole</key>
80 <key>CFBundleTypeExtensions</key> 80 <string>Viewer</string>
81 <array> 81 <key>LSHandlerRank</key>
82 <string>gpub</string> 82 <string>Default</string>
83 </array> 83 <key>LSTypeIsPackage</key>
84 <key>CFBundleTypeIconFile</key> 84 <false/>
85 <string>gempub.icns</string> 85 </dict>
86 <key>CFBundleTypeName</key> 86 <dict>
87 <string>Gempub Book</string> 87 <key>CFBundleTypeExtensions</key>
88 <key>CFBundleTypeRole</key> 88 <array>
89 <string>Viewer</string> 89 <string>gpub</string>
90 <key>LSHandlerRank</key> 90 </array>
91 <string>Default</string> 91 <key>CFBundleTypeIconFile</key>
92 <key>LSTypeIsPackage</key> 92 <string>gempub.icns</string>
93 <false/> 93 <key>CFBundleTypeName</key>
94 </dict> 94 <string>Gempub Book</string>
95 </array> 95 <key>CFBundleTypeRole</key>
96 <key>CFBundleURLTypes</key> 96 <string>Viewer</string>
97 <array> 97 <key>LSHandlerRank</key>
98 <dict> 98 <string>Default</string>
99 <key>CFBundleURLName</key> 99 <key>LSTypeIsPackage</key>
100 <string>Gemini</string> 100 <false/>
101 <key>CFBundleURLSchemes</key> 101 </dict>
102 <array> 102 </array>
103 <string>gemini</string> 103 <key>CFBundleURLTypes</key>
104 </array> 104 <array>
105 </dict> 105 <dict>
106 <dict> 106 <key>CFBundleURLName</key>
107 <key>CFBundleURLName</key> 107 <string>Gemini</string>
108 <string>Gopher</string> 108 <key>CFBundleURLSchemes</key>
109 <key>CFBundleURLSchemes</key> 109 <array>
110 <array> 110 <string>gemini</string>
111 <string>gopher</string> 111 </array>
112 </array> 112 </dict>
113 </dict> 113 <dict>
114 </array> 114 <key>CFBundleURLName</key>
115</dict> 115 <string>Gopher</string>
116 <key>CFBundleURLSchemes</key>
117 <array>
118 <string>gopher</string>
119 </array>
120 </dict>
121 </array>
122 <key>UTExportedTypeDeclarations</key>
123 <array>
124 <dict>
125 <key>UTTypeIdentifier</key>
126 <string>fi.skyjake.lagrange.gemini</string>
127 <key>UTTypeReferenceURL</key>
128 <string>https://gemini.circumlunar.space/docs/specification.gmi</string>
129 <key>UTTypeDescription</key>
130 <string>Gemini Text Document</string>
131 <key>UTTypeConformsTo</key>
132 <array>
133 <string>public.plain-text</string>
134 </array>
135 <key>UTTypeTagSpecification</key>
136 <dict>
137 <key>public.filename-extension</key>
138 <array>
139 <string>gmi</string>
140 <string>gemini</string>
141 </array>
142 <key>public.mime-type</key>
143 <string>text/gemini</string>
144 </dict>
145 </dict>
146 </array>
147 </dict>
116</plist> 148</plist>
diff --git a/res/lang/de.bin b/res/lang/de.bin
index ad41666e..1738f4a7 100644
--- a/res/lang/de.bin
+++ b/res/lang/de.bin
Binary files differ
diff --git a/res/lang/en.bin b/res/lang/en.bin
index a107cec4..54bb4867 100644
--- a/res/lang/en.bin
+++ b/res/lang/en.bin
Binary files differ
diff --git a/res/lang/es.bin b/res/lang/es.bin
index 5ad57bc6..5e0ec4d0 100644
--- a/res/lang/es.bin
+++ b/res/lang/es.bin
Binary files differ
diff --git a/res/lang/fi.bin b/res/lang/fi.bin
index 5167bea1..a000d152 100644
--- a/res/lang/fi.bin
+++ b/res/lang/fi.bin
Binary files differ
diff --git a/res/lang/fr.bin b/res/lang/fr.bin
index dfa5f097..db440d19 100644
--- a/res/lang/fr.bin
+++ b/res/lang/fr.bin
Binary files differ
diff --git a/res/lang/ia.bin b/res/lang/ia.bin
index 91e5336c..c0fb91d9 100644
--- a/res/lang/ia.bin
+++ b/res/lang/ia.bin
Binary files differ
diff --git a/res/lang/ie.bin b/res/lang/ie.bin
index d1cdb189..96f5f2cb 100644
--- a/res/lang/ie.bin
+++ b/res/lang/ie.bin
Binary files differ
diff --git a/res/lang/pl.bin b/res/lang/pl.bin
index b65a2b52..99b6f1c4 100644
--- a/res/lang/pl.bin
+++ b/res/lang/pl.bin
Binary files differ
diff --git a/res/lang/ru.bin b/res/lang/ru.bin
index d962ec59..aec21b35 100644
--- a/res/lang/ru.bin
+++ b/res/lang/ru.bin
Binary files differ
diff --git a/res/lang/sr.bin b/res/lang/sr.bin
index bcd10900..ac4223ac 100644
--- a/res/lang/sr.bin
+++ b/res/lang/sr.bin
Binary files differ
diff --git a/res/lang/tok.bin b/res/lang/tok.bin
index 8d4963bd..760b3044 100644
--- a/res/lang/tok.bin
+++ b/res/lang/tok.bin
Binary files differ
diff --git a/res/lang/zh_Hans.bin b/res/lang/zh_Hans.bin
index 0a5bab01..cc8543b2 100644
--- a/res/lang/zh_Hans.bin
+++ b/res/lang/zh_Hans.bin
Binary files differ
diff --git a/res/lang/zh_Hant.bin b/res/lang/zh_Hant.bin
index 53b05911..2ef3b8a9 100644
--- a/res/lang/zh_Hant.bin
+++ b/res/lang/zh_Hant.bin
Binary files differ
diff --git a/src/app.c b/src/app.c
index 88d912ab..73908a09 100644
--- a/src/app.c
+++ b/src/app.c
@@ -2303,6 +2303,19 @@ iBool handleCommand_App(const char *cmd) {
2303 } 2303 }
2304 setCurrent_Root(oldRoot); 2304 setCurrent_Root(oldRoot);
2305 } 2305 }
2306 else if (equal_Command(cmd, "file.open")) {
2307 const char *path = suffixPtr_Command(cmd, "path");
2308 if (path) {
2309 postCommandf_App("open temp:%d url:%s",
2310 argLabel_Command(cmd, "temp"),
2311 makeFileUrl_CStr(path));
2312 return iTrue;
2313 }
2314#if defined (iPlatformAppleMobile)
2315 pickFileForOpening_iOS();
2316#endif
2317 return iTrue;
2318 }
2306 else if (equal_Command(cmd, "file.delete")) { 2319 else if (equal_Command(cmd, "file.delete")) {
2307 const char *path = suffixPtr_Command(cmd, "path"); 2320 const char *path = suffixPtr_Command(cmd, "path");
2308 if (argLabel_Command(cmd, "confirm")) { 2321 if (argLabel_Command(cmd, "confirm")) {
diff --git a/src/ios.h b/src/ios.h
index 578c85fe..64c0fad1 100644
--- a/src/ios.h
+++ b/src/ios.h
@@ -35,6 +35,7 @@ void setupWindow_iOS (iWindow *window);
35iBool processEvent_iOS (const SDL_Event *); 35iBool processEvent_iOS (const SDL_Event *);
36void playHapticEffect_iOS (enum iHapticEffect effect); 36void playHapticEffect_iOS (enum iHapticEffect effect);
37void exportDownloadedFile_iOS(const iString *path); 37void exportDownloadedFile_iOS(const iString *path);
38void pickFileForOpening_iOS (void);
38 39
39iBool isPhone_iOS (void); 40iBool isPhone_iOS (void);
40void safeAreaInsets_iOS (float *left, float *top, float *right, float *bottom); 41void safeAreaInsets_iOS (float *left, float *top, float *right, float *bottom);
diff --git a/src/ios.m b/src/ios.m
index a1654df2..e7288677 100644
--- a/src/ios.m
+++ b/src/ios.m
@@ -181,11 +181,22 @@ static AppState *appState_;
181 181
182- (void)documentPicker:(UIDocumentPickerViewController *)controller 182- (void)documentPicker:(UIDocumentPickerViewController *)controller
183didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls { 183didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
184 [self removeSavedFile]; 184 if (fileBeingSaved) {
185 [self removeSavedFile];
186 }
187 else {
188 /* A file is being opened. */
189 NSURL *url = [urls firstObject];
190 iString *path = localFilePathFromUrl_String(collectNewCStr_String([[url absoluteString]
191 UTF8String]));
192 postCommandf_App("file.open temp:1 path:%s", cstrCollect_String(path));
193 }
185} 194}
186 195
187- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller { 196- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
188 [self removeSavedFile]; 197 if (fileBeingSaved) {
198 [self removeSavedFile];
199 }
189} 200}
190 201
191-(void)keyboardOnScreen:(NSNotification *)notification { 202-(void)keyboardOnScreen:(NSNotification *)notification {
@@ -335,6 +346,17 @@ void exportDownloadedFile_iOS(const iString *path) {
335 [viewController_(get_Window()) presentViewController:picker animated:YES completion:nil]; 346 [viewController_(get_Window()) presentViewController:picker animated:YES completion:nil];
336} 347}
337 348
349void pickFileForOpening_iOS(void) {
350 UIDocumentPickerViewController *picker = [[UIDocumentPickerViewController alloc]
351 initWithDocumentTypes:@[@"fi.skyjake.lagrange.gemini",
352 @"public.text",
353 @"public.image",
354 @"public.audio"]
355 inMode:UIDocumentPickerModeImport];
356 picker.delegate = appState_;
357 [viewController_(get_Window()) presentViewController:picker animated:YES completion:nil];
358}
359
338/*----------------------------------------------------------------------------------------------*/ 360/*----------------------------------------------------------------------------------------------*/
339 361
340enum iAVFAudioPlayerState { 362enum iAVFAudioPlayerState {
diff --git a/src/ui/root.c b/src/ui/root.c
index 52b6829c..0ab969bf 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -90,6 +90,7 @@ static const iMenuItem navMenuItems_[] = {
90#if defined (iPlatformAppleMobile) 90#if defined (iPlatformAppleMobile)
91/* Tablet menu. */ 91/* Tablet menu. */
92static const iMenuItem tabletNavMenuItems_[] = { 92static const iMenuItem tabletNavMenuItems_[] = {
93 { folder_Icon " ${menu.openfile}", SDLK_o, KMOD_PRIMARY, "file.open" },
93 { add_Icon " ${menu.newtab}", 't', KMOD_PRIMARY, "tabs.new" }, 94 { add_Icon " ${menu.newtab}", 't', KMOD_PRIMARY, "tabs.new" },
94 { close_Icon " ${menu.closetab}", 'w', KMOD_PRIMARY, "tabs.close" }, 95 { close_Icon " ${menu.closetab}", 'w', KMOD_PRIMARY, "tabs.close" },
95 { "---", 0, 0, NULL }, 96 { "---", 0, 0, NULL },
@@ -110,6 +111,7 @@ static const iMenuItem tabletNavMenuItems_[] = {
110 111
111/* Phone menu. */ 112/* Phone menu. */
112static const iMenuItem phoneNavMenuItems_[] = { 113static const iMenuItem phoneNavMenuItems_[] = {
114 { folder_Icon " ${menu.openfile}", SDLK_o, KMOD_PRIMARY, "file.open" },
113 { add_Icon " ${menu.newtab}", 't', KMOD_PRIMARY, "tabs.new" }, 115 { add_Icon " ${menu.newtab}", 't', KMOD_PRIMARY, "tabs.new" },
114 { close_Icon " ${menu.closetab}", 'w', KMOD_PRIMARY, "tabs.close" }, 116 { close_Icon " ${menu.closetab}", 'w', KMOD_PRIMARY, "tabs.close" },
115 { "---", 0, 0, NULL }, 117 { "---", 0, 0, NULL },