diff options
Diffstat (limited to 'src/ui/uploadwidget.c')
-rw-r--r-- | src/ui/uploadwidget.c | 388 |
1 files changed, 283 insertions, 105 deletions
diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c index 5e1ee493..ba7545fd 100644 --- a/src/ui/uploadwidget.c +++ b/src/ui/uploadwidget.c | |||
@@ -29,12 +29,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
29 | #include "command.h" | 29 | #include "command.h" |
30 | #include "gmrequest.h" | 30 | #include "gmrequest.h" |
31 | #include "sitespec.h" | 31 | #include "sitespec.h" |
32 | #include "window.h" | ||
33 | #include "gmcerts.h" | ||
32 | #include "app.h" | 34 | #include "app.h" |
33 | 35 | ||
36 | #if defined (iPlatformAppleMobile) | ||
37 | # include "ios.h" | ||
38 | #endif | ||
39 | |||
34 | #include <the_Foundation/file.h> | 40 | #include <the_Foundation/file.h> |
35 | #include <the_Foundation/fileinfo.h> | 41 | #include <the_Foundation/fileinfo.h> |
42 | #include <the_Foundation/path.h> | ||
36 | 43 | ||
37 | iDefineObjectConstruction(UploadWidget) | 44 | iDefineObjectConstruction(UploadWidget) |
45 | |||
46 | enum iUploadIdentity { | ||
47 | none_UploadIdentity, | ||
48 | defaultForUrl_UploadIdentity, | ||
49 | dropdown_UploadIdentity, | ||
50 | }; | ||
38 | 51 | ||
39 | struct Impl_UploadWidget { | 52 | struct Impl_UploadWidget { |
40 | iWidget widget; | 53 | iWidget widget; |
@@ -51,9 +64,21 @@ struct Impl_UploadWidget { | |||
51 | iLabelWidget * counter; | 64 | iLabelWidget * counter; |
52 | iString filePath; | 65 | iString filePath; |
53 | size_t fileSize; | 66 | size_t fileSize; |
67 | enum iUploadIdentity idMode; | ||
68 | iBlock idFingerprint; | ||
54 | iAtomicInt isRequestUpdated; | 69 | iAtomicInt isRequestUpdated; |
55 | }; | 70 | }; |
56 | 71 | ||
72 | static void releaseFile_UploadWidget_(iUploadWidget *d) { | ||
73 | #if defined (iPlatformAppleMobile) | ||
74 | if (!isEmpty_String(&d->filePath)) { | ||
75 | /* Delete the temporary file that was copied for uploading. */ | ||
76 | remove(cstr_String(&d->filePath)); | ||
77 | } | ||
78 | #endif | ||
79 | clear_String(&d->filePath); | ||
80 | } | ||
81 | |||
57 | static void updateProgress_UploadWidget_(iGmRequest *request, size_t current, size_t total) { | 82 | static void updateProgress_UploadWidget_(iGmRequest *request, size_t current, size_t total) { |
58 | iUploadWidget *d = userData_Object(request); | 83 | iUploadWidget *d = userData_Object(request); |
59 | postCommand_Widget(d, | 84 | postCommand_Widget(d, |
@@ -67,116 +92,202 @@ static void updateInputMaxHeight_UploadWidget_(iUploadWidget *d) { | |||
67 | iWidget *w = as_Widget(d); | 92 | iWidget *w = as_Widget(d); |
68 | /* Calculate how many lines fits vertically in the view. */ | 93 | /* Calculate how many lines fits vertically in the view. */ |
69 | const iInt2 inputPos = topLeft_Rect(bounds_Widget(as_Widget(d->input))); | 94 | const iInt2 inputPos = topLeft_Rect(bounds_Widget(as_Widget(d->input))); |
70 | const int footerHeight = height_Widget(d->token) + | 95 | const int footerHeight = isUsingPanelLayout_Mobile() ? 0 : |
71 | height_Widget(findChild_Widget(w, "dialogbuttons")) + | 96 | (height_Widget(d->token) + |
72 | 6 * gap_UI; | 97 | height_Widget(findChild_Widget(w, "dialogbuttons")) + |
73 | const int avail = bottom_Rect(safeRect_Root(w->root)) - footerHeight; | 98 | 12 * gap_UI); |
99 | const int avail = bottom_Rect(safeRect_Root(w->root)) - footerHeight - | ||
100 | get_MainWindow()->keyboardHeight; | ||
74 | setLineLimits_InputWidget(d->input, | 101 | setLineLimits_InputWidget(d->input, |
75 | minLines_InputWidget(d->input), | 102 | minLines_InputWidget(d->input), |
76 | iMaxi(minLines_InputWidget(d->input), | 103 | iMaxi(minLines_InputWidget(d->input), |
77 | (avail - inputPos.y) / lineHeight_Text(monospace_FontId))); | 104 | (avail - inputPos.y) / lineHeight_Text(font_InputWidget(d->input)))); |
105 | } | ||
106 | |||
107 | static const iArray *makeIdentityItems_UploadWidget_(const iUploadWidget *d) { | ||
108 | iArray *items = collectNew_Array(sizeof(iMenuItem)); | ||
109 | const iGmIdentity *urlId = identityForUrl_GmCerts(certs_App(), &d->url); | ||
110 | pushBack_Array(items, | ||
111 | &(iMenuItem){ format_CStr("${dlg.upload.id.default} (%s)", | ||
112 | urlId ? cstr_String(name_GmIdentity(urlId)) | ||
113 | : "${dlg.upload.id.none}"), | ||
114 | 0, 0, "upload.setid arg:1" }); | ||
115 | pushBack_Array(items, &(iMenuItem){ "${dlg.upload.id.none}", 0, 0, "upload.setid arg:0" }); | ||
116 | pushBack_Array(items, &(iMenuItem){ "---" }); | ||
117 | iConstForEach(PtrArray, i, listIdentities_GmCerts(certs_App(), NULL, NULL)) { | ||
118 | const iGmIdentity *id = i.ptr; | ||
119 | pushBack_Array( | ||
120 | items, | ||
121 | &(iMenuItem){ cstr_String(name_GmIdentity(id)), 0, 0, | ||
122 | format_CStr("upload.setid fp:%s", | ||
123 | cstrCollect_String(hexEncode_Block(&id->fingerprint))) }); | ||
124 | } | ||
125 | pushBack_Array(items, &(iMenuItem){ NULL }); | ||
126 | return items; | ||
78 | } | 127 | } |
79 | 128 | ||
80 | void init_UploadWidget(iUploadWidget *d) { | 129 | void init_UploadWidget(iUploadWidget *d) { |
81 | iWidget *w = as_Widget(d); | 130 | iWidget *w = as_Widget(d); |
82 | init_Widget(w); | 131 | init_Widget(w); |
83 | setId_Widget(w, "upload"); | 132 | setId_Widget(w, "upload"); |
84 | useSheetStyle_Widget(w); | ||
85 | init_String(&d->originalUrl); | 133 | init_String(&d->originalUrl); |
86 | init_String(&d->url); | 134 | init_String(&d->url); |
87 | d->viewer = NULL; | 135 | d->viewer = NULL; |
88 | d->request = NULL; | 136 | d->request = NULL; |
89 | init_String(&d->filePath); | 137 | init_String(&d->filePath); |
90 | d->fileSize = 0; | 138 | d->fileSize = 0; |
91 | addChildFlags_Widget(w, | 139 | d->idMode = defaultForUrl_UploadIdentity; |
92 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), | 140 | init_Block(&d->idFingerprint, 0); |
93 | frameless_WidgetFlag); | 141 | const iMenuItem actions[] = { |
94 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)), | 142 | { "${upload.port}", 0, 0, "upload.setport" }, |
95 | frameless_WidgetFlag | resizeToParentWidth_WidgetFlag | | 143 | { "---" }, |
96 | fixedHeight_WidgetFlag); | 144 | { "${close}", SDLK_ESCAPE, 0, "upload.cancel" }, |
97 | setWrap_LabelWidget(d->info, iTrue); | 145 | { uiTextAction_ColorEscape "${dlg.upload.send}", SDLK_RETURN, KMOD_PRIMARY, "upload.accept" } |
98 | /* Tabs for input data. */ | 146 | }; |
99 | iWidget *tabs = makeTabs_Widget(w); | 147 | if (isUsingPanelLayout_Mobile()) { |
100 | /* Make the tabs support vertical expansion based on content. */ { | 148 | const iMenuItem textItems[] = { |
101 | setFlags_Widget(tabs, resizeHeightOfChildren_WidgetFlag, iFalse); | 149 | { "title id:heading.upload.text" }, |
102 | setFlags_Widget(tabs, arrangeHeight_WidgetFlag, iTrue); | 150 | { "input id:upload.text noheading:1" }, |
103 | iWidget *tabPages = findChild_Widget(tabs, "tabs.pages"); | 151 | { NULL } |
104 | setFlags_Widget(tabPages, resizeHeightOfChildren_WidgetFlag, iFalse); | 152 | }; |
105 | setFlags_Widget(tabPages, arrangeHeight_WidgetFlag, iTrue); | 153 | const iMenuItem fileItems[] = { |
106 | } | 154 | { "title id:heading.upload.file" }, |
107 | iWidget *headings, *values; | 155 | { "button text:" uiTextAction_ColorEscape "${dlg.upload.pickfile}", 0, 0, "upload.pickfile" }, |
108 | setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId); | 156 | { "heading id:upload.file.name" }, |
109 | setId_Widget(tabs, "upload.tabs"); | 157 | { "label id:upload.filepathlabel text:\u2014" }, |
110 | // const int bigGap = lineHeight_Text(uiLabel_FontId) * 3 / 4; | 158 | { "heading id:upload.file.size" }, |
111 | /* Text input. */ { | 159 | { "label id:upload.filesizelabel text:\u2014" }, |
112 | //appendTwoColumnTabPage_Widget(tabs, "${heading.upload.text}", '1', &headings, &values); | 160 | { "padding" }, |
113 | iWidget *page = new_Widget(); | 161 | { "input id:upload.mime" }, |
114 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); | 162 | { "label id:upload.counter text:" }, |
115 | d->input = new_InputWidget(0); | 163 | { NULL } |
116 | setId_Widget(as_Widget(d->input), "upload.text"); | 164 | }; |
117 | setFont_InputWidget(d->input, monospace_FontId); | 165 | initPanels_Mobile(w, NULL, (iMenuItem[]){ |
118 | setLineLimits_InputWidget(d->input, 7, 20); | 166 | { "title id:heading.upload" }, |
119 | setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */ | 167 | { "label id:upload.info" }, |
120 | setHint_InputWidget(d->input, "${hint.upload.text}"); | 168 | { "panel id:dlg.upload.text icon:0x1f5b9", 0, 0, (const void *) textItems }, |
121 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); | 169 | { "panel id:dlg.upload.file icon:0x1f4c1", 0, 0, (const void *) fileItems }, |
122 | addChild_Widget(page, iClob(d->input)); | 170 | { "padding" }, |
123 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); | 171 | { "dropdown id:upload.id icon:0x1f464", 0, 0, constData_Array(makeIdentityItems_UploadWidget_(d)) }, |
124 | } | 172 | { "input id:upload.token hint:hint.upload.token icon:0x1f511" }, |
125 | /* File content. */ { | 173 | { NULL } |
126 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); | 174 | }, actions, iElemCount(actions)); |
127 | // iWidget *pad = addChild_Widget(headings, iClob(makePadding_Widget(0))); | 175 | d->info = findChild_Widget(w, "upload.info"); |
128 | // iWidget *hint = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophint}", NULL))); | 176 | d->input = findChild_Widget(w, "upload.text"); |
129 | // pad->sizeRef = hint; | 177 | d->filePathLabel = findChild_Widget(w, "upload.filepathlabel"); |
130 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag); | 178 | d->fileSizeLabel = findChild_Widget(w, "upload.filesizelabel"); |
131 | d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag); | 179 | d->mime = findChild_Widget(w, "upload.mime"); |
132 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL)), frameless_WidgetFlag); | 180 | d->token = findChild_Widget(w, "upload.token"); |
133 | d->fileSizeLabel = addChildFlags_Widget(values, iClob(new_LabelWidget("\u2014", NULL)), frameless_WidgetFlag); | 181 | d->counter = findChild_Widget(w, "upload.counter"); |
134 | d->mime = new_InputWidget(0); | ||
135 | setFixedSize_Widget(as_Widget(d->mime), init_I2(70 * gap_UI, -1)); | ||
136 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); | ||
137 | } | ||
138 | /* Token. */ { | ||
139 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
140 | iWidget *page = makeTwoColumns_Widget(&headings, &values); | ||
141 | d->token = addTwoColumnDialogInputField_Widget( | ||
142 | headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0))); | ||
143 | setHint_InputWidget(d->token, "${hint.upload.token}"); | ||
144 | setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1)); | ||
145 | addChild_Widget(w, iClob(page)); | ||
146 | } | 182 | } |
147 | /* Buttons. */ { | 183 | else { |
148 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | 184 | useSheetStyle_Widget(w); |
149 | iWidget *buttons = | 185 | setFlags_Widget(w, overflowScrollable_WidgetFlag, iFalse); |
150 | makeDialogButtons_Widget((iMenuItem[]){ { "${upload.port}", 0, 0, "upload.setport" }, | 186 | addChildFlags_Widget(w, |
151 | { "---", 0, 0, NULL }, | 187 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), |
152 | { "${close}", SDLK_ESCAPE, 0, "upload.cancel" }, | 188 | frameless_WidgetFlag); |
153 | { uiTextAction_ColorEscape "${dlg.upload.send}", | 189 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)), |
154 | SDLK_RETURN, | 190 | frameless_WidgetFlag | resizeToParentWidth_WidgetFlag | |
155 | KMOD_PRIMARY, | 191 | fixedHeight_WidgetFlag); |
156 | "upload.accept" } }, | 192 | setWrap_LabelWidget(d->info, iTrue); |
157 | 4); | 193 | /* Tabs for input data. */ |
158 | setId_Widget(insertChildAfterFlags_Widget(buttons, | 194 | iWidget *tabs = makeTabs_Widget(w); |
159 | iClob(d->counter = new_LabelWidget("", NULL)), | 195 | /* Make the tabs support vertical expansion based on content. */ { |
160 | 0, frameless_WidgetFlag), | 196 | setFlags_Widget(tabs, resizeHeightOfChildren_WidgetFlag, iFalse); |
161 | "upload.counter"); | 197 | setFlags_Widget(tabs, arrangeHeight_WidgetFlag, iTrue); |
162 | addChild_Widget(w, iClob(buttons)); | 198 | iWidget *tabPages = findChild_Widget(tabs, "tabs.pages"); |
199 | setFlags_Widget(tabPages, resizeHeightOfChildren_WidgetFlag, iFalse); | ||
200 | setFlags_Widget(tabPages, arrangeHeight_WidgetFlag, iTrue); | ||
201 | } | ||
202 | iWidget *headings, *values; | ||
203 | setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId); | ||
204 | setId_Widget(tabs, "upload.tabs"); | ||
205 | /* Text input. */ { | ||
206 | iWidget *page = new_Widget(); | ||
207 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); | ||
208 | d->input = new_InputWidget(0); | ||
209 | setId_Widget(as_Widget(d->input), "upload.text"); | ||
210 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); | ||
211 | addChild_Widget(page, iClob(d->input)); | ||
212 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); | ||
213 | } | ||
214 | /* File content. */ { | ||
215 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); | ||
216 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag); | ||
217 | d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag); | ||
218 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL)), frameless_WidgetFlag); | ||
219 | d->fileSizeLabel = addChildFlags_Widget(values, iClob(new_LabelWidget("\u2014", NULL)), frameless_WidgetFlag); | ||
220 | d->mime = new_InputWidget(0); | ||
221 | setFixedSize_Widget(as_Widget(d->mime), init_I2(70 * gap_UI, -1)); | ||
222 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); | ||
223 | } | ||
224 | /* Identity and Token. */ { | ||
225 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
226 | iWidget *page = makeTwoColumns_Widget(&headings, &values); | ||
227 | /* Token. */ | ||
228 | d->token = addTwoColumnDialogInputField_Widget( | ||
229 | headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0))); | ||
230 | setHint_InputWidget(d->token, "${hint.upload.token}"); | ||
231 | setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1)); | ||
232 | /* Identity. */ | ||
233 | const iArray * identItems = makeIdentityItems_UploadWidget_(d); | ||
234 | const iMenuItem *items = constData_Array(identItems); | ||
235 | const size_t numItems = size_Array(identItems); | ||
236 | iLabelWidget * ident = makeMenuButton_LabelWidget("${upload.id}", items, numItems); | ||
237 | setTextCStr_LabelWidget(ident, items[findWidestLabel_MenuItem(items, numItems)].label); | ||
238 | addChild_Widget(headings, iClob(makeHeading_Widget("${upload.id}"))); | ||
239 | setId_Widget(addChildFlags_Widget(values, iClob(ident), alignLeft_WidgetFlag), "upload.id"); | ||
240 | addChild_Widget(w, iClob(page)); | ||
241 | } | ||
242 | /* Buttons. */ { | ||
243 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
244 | iWidget *buttons = makeDialogButtons_Widget(actions, iElemCount(actions)); | ||
245 | setId_Widget(insertChildAfterFlags_Widget(buttons, | ||
246 | iClob(d->counter = new_LabelWidget("", NULL)), | ||
247 | 0, | ||
248 | frameless_WidgetFlag), | ||
249 | "upload.counter"); | ||
250 | addChild_Widget(w, iClob(buttons)); | ||
251 | } | ||
252 | resizeToLargestPage_Widget(tabs); | ||
253 | arrange_Widget(w); | ||
254 | setFixedSize_Widget(as_Widget(d->token), init_I2(width_Widget(tabs) - left_Rect(parent_Widget(d->token)->rect), -1)); | ||
255 | setFlags_Widget(as_Widget(d->token), expand_WidgetFlag, iTrue); | ||
256 | setFocus_Widget(as_Widget(d->input)); | ||
163 | } | 257 | } |
164 | resizeToLargestPage_Widget(tabs); | 258 | setFont_InputWidget(d->input, iosevka_FontId); |
165 | arrange_Widget(w); | 259 | setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */ |
166 | setFixedSize_Widget(as_Widget(d->token), init_I2(width_Widget(tabs) - left_Rect(parent_Widget(d->token)->rect), -1)); | 260 | setLineLimits_InputWidget(d->input, 7, 20); |
167 | setFlags_Widget(as_Widget(d->token), expand_WidgetFlag, iTrue); | 261 | setHint_InputWidget(d->input, "${hint.upload.text}"); |
168 | setFocus_Widget(as_Widget(d->input)); | ||
169 | setBackupFileName_InputWidget(d->input, "uploadbackup.txt"); | 262 | setBackupFileName_InputWidget(d->input, "uploadbackup.txt"); |
170 | updateInputMaxHeight_UploadWidget_(d); | 263 | updateInputMaxHeight_UploadWidget_(d); |
171 | } | 264 | } |
172 | 265 | ||
173 | void deinit_UploadWidget(iUploadWidget *d) { | 266 | void deinit_UploadWidget(iUploadWidget *d) { |
267 | releaseFile_UploadWidget_(d); | ||
268 | deinit_Block(&d->idFingerprint); | ||
174 | deinit_String(&d->filePath); | 269 | deinit_String(&d->filePath); |
175 | deinit_String(&d->url); | 270 | deinit_String(&d->url); |
176 | deinit_String(&d->originalUrl); | 271 | deinit_String(&d->originalUrl); |
177 | iRelease(d->request); | 272 | iRelease(d->request); |
178 | } | 273 | } |
179 | 274 | ||
275 | static void remakeIdentityItems_UploadWidget_(iUploadWidget *d) { | ||
276 | iWidget *dropMenu = findChild_Widget(findChild_Widget(as_Widget(d), "upload.id"), "menu"); | ||
277 | releaseChildren_Widget(dropMenu); | ||
278 | const iArray *items = makeIdentityItems_UploadWidget_(d); | ||
279 | makeMenuItems_Widget(dropMenu, constData_Array(items), size_Array(items)); | ||
280 | } | ||
281 | |||
282 | static void updateIdentityDropdown_UploadWidget_(iUploadWidget *d) { | ||
283 | updateDropdownSelection_LabelWidget( | ||
284 | findChild_Widget(as_Widget(d), "upload.id"), | ||
285 | d->idMode == none_UploadIdentity ? " arg:0" | ||
286 | : d->idMode == defaultForUrl_UploadIdentity | ||
287 | ? " arg:1" | ||
288 | : format_CStr(" fp:%s", cstrCollect_String(hexEncode_Block(&d->idFingerprint)))); | ||
289 | } | ||
290 | |||
180 | static uint16_t titanPortForUrl_(const iString *url) { | 291 | static uint16_t titanPortForUrl_(const iString *url) { |
181 | uint16_t port = 0; | 292 | uint16_t port = 0; |
182 | const iString *root = collectNewRange_String(urlRoot_String(url)); | 293 | const iString *root = collectNewRange_String(urlRoot_String(url)); |
@@ -201,10 +312,13 @@ static void setUrlPort_UploadWidget_(iUploadWidget *d, const iString *url, uint1 | |||
201 | appendFormat_String(&d->url, ":%u", overridePort ? overridePort : titanPortForUrl_(url)); | 312 | appendFormat_String(&d->url, ":%u", overridePort ? overridePort : titanPortForUrl_(url)); |
202 | appendRange_String(&d->url, (iRangecc){ parts.path.start, constEnd_String(url) }); | 313 | appendRange_String(&d->url, (iRangecc){ parts.path.start, constEnd_String(url) }); |
203 | setText_LabelWidget(d->info, &d->url); | 314 | setText_LabelWidget(d->info, &d->url); |
315 | arrange_Widget(as_Widget(d)); | ||
204 | } | 316 | } |
205 | 317 | ||
206 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { | 318 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { |
207 | setUrlPort_UploadWidget_(d, url, 0); | 319 | setUrlPort_UploadWidget_(d, url, 0); |
320 | remakeIdentityItems_UploadWidget_(d); | ||
321 | updateIdentityDropdown_UploadWidget_(d); | ||
208 | } | 322 | } |
209 | 323 | ||
210 | void setResponseViewer_UploadWidget(iUploadWidget *d, iDocumentWidget *doc) { | 324 | void setResponseViewer_UploadWidget(iUploadWidget *d, iDocumentWidget *doc) { |
@@ -227,13 +341,33 @@ static void requestFinished_UploadWidget_(iUploadWidget *d, iGmRequest *req) { | |||
227 | postCommand_Widget(d, "upload.request.finished reqid:%u", id_GmRequest(req)); | 341 | postCommand_Widget(d, "upload.request.finished reqid:%u", id_GmRequest(req)); |
228 | } | 342 | } |
229 | 343 | ||
344 | static void updateFileInfo_UploadWidget_(iUploadWidget *d) { | ||
345 | iFileInfo *info = iClob(new_FileInfo(&d->filePath)); | ||
346 | if (isDirectory_FileInfo(info)) { | ||
347 | makeMessage_Widget("${heading.upload.error.file}", | ||
348 | "${upload.error.directory}", | ||
349 | (iMenuItem[]){ "${dlg.message.ok}", 0, 0, "message.ok" }, 1); | ||
350 | clear_String(&d->filePath); | ||
351 | d->fileSize = 0; | ||
352 | return; | ||
353 | } | ||
354 | d->fileSize = size_FileInfo(info); | ||
355 | #if defined (iPlatformMobile) | ||
356 | setTextCStr_LabelWidget(d->filePathLabel, cstr_Rangecc(baseName_Path(&d->filePath))); | ||
357 | #else | ||
358 | setText_LabelWidget(d->filePathLabel, &d->filePath); | ||
359 | #endif | ||
360 | setTextCStr_LabelWidget(d->fileSizeLabel, formatCStrs_Lang("num.bytes.n", d->fileSize)); | ||
361 | setTextCStr_InputWidget(d->mime, mediaType_Path(&d->filePath)); | ||
362 | } | ||
363 | |||
230 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | 364 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { |
231 | iWidget *w = as_Widget(d); | 365 | iWidget *w = as_Widget(d); |
232 | const char *cmd = command_UserEvent(ev); | 366 | const char *cmd = command_UserEvent(ev); |
233 | if (isResize_UserEvent(ev)) { | 367 | if (isResize_UserEvent(ev) || equal_Command(cmd, "keyboard.changed")) { |
234 | updateInputMaxHeight_UploadWidget_(d); | 368 | updateInputMaxHeight_UploadWidget_(d); |
235 | } | 369 | } |
236 | if (isCommand_Widget(w, ev, "upload.cancel")) { | 370 | if (equal_Command(cmd, "upload.cancel")) { |
237 | setupSheetTransition_Mobile(w, iFalse); | 371 | setupSheetTransition_Mobile(w, iFalse); |
238 | destroy_Widget(w); | 372 | destroy_Widget(w); |
239 | return iTrue; | 373 | return iTrue; |
@@ -254,9 +388,36 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
254 | } | 388 | } |
255 | return iTrue; | 389 | return iTrue; |
256 | } | 390 | } |
391 | if (isCommand_Widget(w, ev, "upload.setid")) { | ||
392 | if (hasLabel_Command(cmd, "fp")) { | ||
393 | set_Block(&d->idFingerprint, collect_Block(hexDecode_Rangecc(range_Command(cmd, "fp")))); | ||
394 | d->idMode = dropdown_UploadIdentity; | ||
395 | } | ||
396 | else if (arg_Command(cmd)) { | ||
397 | clear_Block(&d->idFingerprint); | ||
398 | d->idMode = defaultForUrl_UploadIdentity; | ||
399 | } | ||
400 | else { | ||
401 | clear_Block(&d->idFingerprint); | ||
402 | d->idMode = none_UploadIdentity; | ||
403 | } | ||
404 | updateIdentityDropdown_UploadWidget_(d); | ||
405 | return iTrue; | ||
406 | } | ||
257 | if (isCommand_Widget(w, ev, "upload.accept")) { | 407 | if (isCommand_Widget(w, ev, "upload.accept")) { |
258 | iWidget * tabs = findChild_Widget(w, "upload.tabs"); | 408 | iBool isText; |
259 | const int tabIndex = tabPageIndex_Widget(tabs, currentTabPage_Widget(tabs)); | 409 | iWidget *tabs = findChild_Widget(w, "upload.tabs"); |
410 | if (tabs) { | ||
411 | const size_t tabIndex = tabPageIndex_Widget(tabs, currentTabPage_Widget(tabs)); | ||
412 | isText = (tabIndex == 0); | ||
413 | } | ||
414 | else { | ||
415 | const size_t panelIndex = currentPanelIndex_Mobile(w); | ||
416 | if (panelIndex == iInvalidPos) { | ||
417 | return iTrue; | ||
418 | } | ||
419 | isText = (currentPanelIndex_Mobile(w) == 0); | ||
420 | } | ||
260 | /* Make a GmRequest and send the data. */ | 421 | /* Make a GmRequest and send the data. */ |
261 | iAssert(d->request == NULL); | 422 | iAssert(d->request == NULL); |
262 | iAssert(!isEmpty_String(&d->url)); | 423 | iAssert(!isEmpty_String(&d->url)); |
@@ -264,7 +425,21 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
264 | setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); | 425 | setSendProgressFunc_GmRequest(d->request, updateProgress_UploadWidget_); |
265 | setUserData_Object(d->request, d); | 426 | setUserData_Object(d->request, d); |
266 | setUrl_GmRequest(d->request, &d->url); | 427 | setUrl_GmRequest(d->request, &d->url); |
267 | if (tabIndex == 0) { | 428 | switch (d->idMode) { |
429 | case defaultForUrl_UploadIdentity: | ||
430 | break; /* GmRequest handles it */ | ||
431 | case none_UploadIdentity: | ||
432 | setIdentity_GmRequest(d->request, NULL); | ||
433 | signOut_GmCerts(certs_App(), url_GmRequest(d->request)); | ||
434 | break; | ||
435 | case dropdown_UploadIdentity: { | ||
436 | iGmIdentity *ident = findIdentity_GmCerts(certs_App(), &d->idFingerprint); | ||
437 | setIdentity_GmRequest(d->request, ident); | ||
438 | signIn_GmCerts(certs_App(), ident, url_GmRequest(d->request)); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | if (isText) { | ||
268 | /* Uploading text. */ | 443 | /* Uploading text. */ |
269 | setTitanData_GmRequest(d->request, | 444 | setTitanData_GmRequest(d->request, |
270 | collectNewCStr_String("text/plain"), | 445 | collectNewCStr_String("text/plain"), |
@@ -312,6 +487,7 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
312 | d->request = NULL; /* DocumentWidget has it now. */ | 487 | d->request = NULL; /* DocumentWidget has it now. */ |
313 | } | 488 | } |
314 | setupSheetTransition_Mobile(w, iFalse); | 489 | setupSheetTransition_Mobile(w, iFalse); |
490 | releaseFile_UploadWidget_(d); | ||
315 | destroy_Widget(w); | 491 | destroy_Widget(w); |
316 | return iTrue; | 492 | return iTrue; |
317 | } | 493 | } |
@@ -321,34 +497,36 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
321 | refresh_Widget(w); | 497 | refresh_Widget(w); |
322 | return iTrue; | 498 | return iTrue; |
323 | } | 499 | } |
500 | else if (isCommand_Widget(w, ev, "upload.pickfile")) { | ||
501 | #if defined (iPlatformAppleMobile) | ||
502 | if (hasLabel_Command(cmd, "path")) { | ||
503 | releaseFile_UploadWidget_(d); | ||
504 | set_String(&d->filePath, collect_String(suffix_Command(cmd, "path"))); | ||
505 | updateFileInfo_UploadWidget_(d); | ||
506 | } | ||
507 | else { | ||
508 | pickFile_iOS(format_CStr("upload.pickfile ptr:%p", d)); | ||
509 | } | ||
510 | #endif | ||
511 | return iTrue; | ||
512 | } | ||
324 | if (ev->type == SDL_DROPFILE) { | 513 | if (ev->type == SDL_DROPFILE) { |
325 | /* Switch to File tab. */ | 514 | /* Switch to File tab. */ |
326 | iWidget *tabs = findChild_Widget(w, "upload.tabs"); | 515 | iWidget *tabs = findChild_Widget(w, "upload.tabs"); |
327 | showTabPage_Widget(tabs, tabPage_Widget(tabs, 1)); | 516 | showTabPage_Widget(tabs, tabPage_Widget(tabs, 1)); |
517 | releaseFile_UploadWidget_(d); | ||
328 | setCStr_String(&d->filePath, ev->drop.file); | 518 | setCStr_String(&d->filePath, ev->drop.file); |
329 | iFileInfo *info = iClob(new_FileInfo(&d->filePath)); | 519 | updateFileInfo_UploadWidget_(d); |
330 | if (isDirectory_FileInfo(info)) { | ||
331 | makeMessage_Widget("${heading.upload.error.file}", | ||
332 | "${upload.error.directory}", | ||
333 | (iMenuItem[]){ "${dlg.message.ok}", 0, 0, "message.ok" }, 1); | ||
334 | clear_String(&d->filePath); | ||
335 | d->fileSize = 0; | ||
336 | return iTrue; | ||
337 | } | ||
338 | d->fileSize = size_FileInfo(info); | ||
339 | setText_LabelWidget(d->filePathLabel, &d->filePath); | ||
340 | setTextCStr_LabelWidget(d->fileSizeLabel, formatCStrs_Lang("num.bytes.n", d->fileSize)); | ||
341 | setTextCStr_InputWidget(d->mime, mediaType_Path(&d->filePath)); | ||
342 | return iTrue; | 520 | return iTrue; |
343 | } | 521 | } |
344 | return processEvent_Widget(w, ev); | 522 | return processEvent_Widget(w, ev); |
345 | } | 523 | } |
346 | 524 | ||
347 | static void draw_UploadWidget_(const iUploadWidget *d) { | 525 | //static void draw_UploadWidget_(const iUploadWidget *d) { |
348 | draw_Widget(constAs_Widget(d)); | 526 | // draw_Widget(constAs_Widget(d)); |
349 | } | 527 | //} |
350 | 528 | ||
351 | iBeginDefineSubclass(UploadWidget, Widget) | 529 | iBeginDefineSubclass(UploadWidget, Widget) |
352 | .processEvent = (iAny *) processEvent_UploadWidget_, | 530 | .processEvent = (iAny *) processEvent_UploadWidget_, |
353 | .draw = (iAny *) draw_UploadWidget_, | 531 | .draw = draw_Widget, |
354 | iEndDefineSubclass(UploadWidget) | 532 | iEndDefineSubclass(UploadWidget) |