summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app.c6
-rw-r--r--src/prefs.c2
-rw-r--r--src/prefs.h2
-rw-r--r--src/ui/translation.c56
-rw-r--r--src/ui/util.c67
-rw-r--r--src/ui/util.h1
6 files changed, 80 insertions, 54 deletions
diff --git a/src/app.c b/src/app.c
index 6a6c5b7d..73eea762 100644
--- a/src/app.c
+++ b/src/app.c
@@ -232,6 +232,7 @@ static iString *serializePrefs_App_(const iApp *d) {
232 appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->prefs.httpProxy)); 232 appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->prefs.httpProxy));
233 appendFormat_String(str, "downloads path:%s\n", cstr_String(&d->prefs.downloadDir)); 233 appendFormat_String(str, "downloads path:%s\n", cstr_String(&d->prefs.downloadDir));
234 appendFormat_String(str, "searchurl address:%s\n", cstr_String(&d->prefs.searchUrl)); 234 appendFormat_String(str, "searchurl address:%s\n", cstr_String(&d->prefs.searchUrl));
235 appendFormat_String(str, "translation.languages from:%d to:%d\n", d->prefs.langFrom, d->prefs.langTo);
235 return str; 236 return str;
236} 237}
237 238
@@ -1455,6 +1456,11 @@ iBool handleCommand_App(const char *cmd) {
1455 d->prefs.dialogTab = arg_Command(cmd); 1456 d->prefs.dialogTab = arg_Command(cmd);
1456 return iTrue; 1457 return iTrue;
1457 } 1458 }
1459 else if (equal_Command(cmd, "translation.languages")) {
1460 d->prefs.langFrom = argLabel_Command(cmd, "from");
1461 d->prefs.langTo = argLabel_Command(cmd, "to");
1462 return iTrue;
1463 }
1458 else if (equal_Command(cmd, "window.retain")) { 1464 else if (equal_Command(cmd, "window.retain")) {
1459 d->prefs.retainWindowSize = arg_Command(cmd); 1465 d->prefs.retainWindowSize = arg_Command(cmd);
1460 return iTrue; 1466 return iTrue;
diff --git a/src/prefs.c b/src/prefs.c
index 5aba8359..b9b59836 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -26,6 +26,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26 26
27void init_Prefs(iPrefs *d) { 27void init_Prefs(iPrefs *d) {
28 d->dialogTab = 0; 28 d->dialogTab = 0;
29 d->langFrom = 3; /* fr */
30 d->langTo = 2; /* en */
29 d->useSystemTheme = iTrue; 31 d->useSystemTheme = iTrue;
30 d->theme = dark_ColorTheme; 32 d->theme = dark_ColorTheme;
31 d->accent = cyan_ColorAccent; 33 d->accent = cyan_ColorAccent;
diff --git a/src/prefs.h b/src/prefs.h
index 50dd1969..13b91568 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -35,6 +35,8 @@ iDeclareType(Prefs)
35struct Impl_Prefs { 35struct Impl_Prefs {
36 /* UI state */ 36 /* UI state */
37 int dialogTab; 37 int dialogTab;
38 int langFrom;
39 int langTo;
38 /* Window */ 40 /* Window */
39 iBool useSystemTheme; 41 iBool useSystemTheme;
40 enum iColorTheme theme; 42 enum iColorTheme theme;
diff --git a/src/ui/translation.c b/src/ui/translation.c
index e5059f38..bbc1763e 100644
--- a/src/ui/translation.c
+++ b/src/ui/translation.c
@@ -151,13 +151,6 @@ iDefineTypeConstructionArgs(Translation, (iDocumentWidget *doc), doc)
151static const char * translationServiceHost = "xlt.skyjake.fi"; 151static const char * translationServiceHost = "xlt.skyjake.fi";
152static const uint16_t translationServicePort = 443; 152static const uint16_t translationServicePort = 443;
153 153
154//static const char *doubleArrowSymbol = "\U0001f192"; //"\u20e2"; /* prevent getting mangled */
155//static const char *tripleBacktickSymbol = "\U0001f1a9"; //\u20e3";
156//static const char *h1Symbol = "\U0001f19d";
157//static const char *h2Symbol = "\U0001f19e";
158//static const char *h3Symbol = "\U0001f19f";
159//static const char *bulletSymbol = "\n\U0001f196";
160
161static iString *quote_String_(const iString *d) { 154static iString *quote_String_(const iString *d) {
162 iString *quot = new_String(); 155 iString *quot = new_String();
163 iConstForEach(String, i, d) { 156 iConstForEach(String, i, d) {
@@ -292,13 +285,19 @@ static uint32_t animate_Translation_(uint32_t interval, iAny *ptr) {
292} 285}
293 286
294void submit_Translation(iTranslation *d) { 287void submit_Translation(iTranslation *d) {
288 iAssert(status_TlsRequest(d->request) != submitted_TlsRequestStatus);
295 /* Check the selected languages from the dialog. */ 289 /* Check the selected languages from the dialog. */
296 const char *idFrom = languageId_String(text_LabelWidget(findChild_Widget(d->dlg, "xlt.from"))); 290 const char *idFrom = languageId_String(text_LabelWidget(findChild_Widget(d->dlg, "xlt.from")));
297 const char *idTo = languageId_String(text_LabelWidget(findChild_Widget(d->dlg, "xlt.to"))); 291 const char *idTo = languageId_String(text_LabelWidget(findChild_Widget(d->dlg, "xlt.to")));
298 iAssert(status_TlsRequest(d->request) != submitted_TlsRequestStatus); 292 /* Remember these in Preferences. */
299 iBlock *json = collect_Block(new_Block(0)); 293 postCommandf_App("translation.languages from:%d to:%d",
294 languageIndex_CStr(idFrom),
295 languageIndex_CStr(idTo));
296 iBlock * json = collect_Block(new_Block(0));
300 iString *docSrc = collectNew_String(); 297 iString *docSrc = collectNew_String();
301 /* TODO: Strip all markup and remember it. These are reapplied when reading response. */ { 298 /* The translation engine doesn't preserve Gemtext markup so we'll strip all of it and
299 remember each line's type. These are reapplied when reading the response. Newlines seem
300 to be preserved pretty well. */ {
302 iRangecc line = iNullRange; 301 iRangecc line = iNullRange;
303 while (nextSplit_Rangecc( 302 while (nextSplit_Rangecc(
304 range_String(source_GmDocument(document_DocumentWidget(d->doc))), "\n", &line)) { 303 range_String(source_GmDocument(document_DocumentWidget(d->doc))), "\n", &line)) {
@@ -317,28 +316,25 @@ void submit_Translation(iTranslation *d) {
317 appendRange_String(docSrc, cleanLine); 316 appendRange_String(docSrc, cleanLine);
318 } 317 }
319 } 318 }
320// replace_String(docSrc, "=>", doubleArrowSymbol);
321// replace_String(docSrc, "```", tripleBacktickSymbol);
322// replace_String(docSrc, "###", h3Symbol);
323// replace_String(docSrc, "##", h2Symbol);
324// replace_String(docSrc, "#", h1Symbol);
325// replace_String(docSrc, "\n*", bulletSymbol);
326 printf_Block(json, 319 printf_Block(json,
327 "{\"q\":\"%s\",\"source\":\"%s\",\"target\":\"%s\"}", 320 "{\"q\":\"%s\",\"source\":\"%s\",\"target\":\"%s\"}",
328 cstrCollect_String(quote_String_(docSrc)), 321 cstrCollect_String(quote_String_(docSrc)),
329 idFrom, 322 idFrom,
330 idTo); 323 idTo);
331 iBlock *msg = collect_Block(new_Block(0)); 324 iBlock *msg = collect_Block(new_Block(0));
332 printf_Block(msg, "POST /translate HTTP/1.1\r\n" 325 printf_Block(msg,
333 "Host: xlt.skyjake.fi\r\n" 326 "POST /translate HTTP/1.1\r\n"
334 "Connection: close\r\n" 327 "Host: %s\r\n"
335 "Content-Type: application/json; charset=utf-8\r\n" 328 "Connection: close\r\n"
336 "Content-Length: %zu\r\n\r\n", size_Block(json)); 329 "Content-Type: application/json; charset=utf-8\r\n"
330 "Content-Length: %zu\r\n\r\n",
331 translationServiceHost,
332 size_Block(json));
337 append_Block(msg, json); 333 append_Block(msg, json);
338 setContent_TlsRequest(d->request, msg); 334 setContent_TlsRequest(d->request, msg);
339 submit_TlsRequest(d->request); 335 submit_TlsRequest(d->request);
340 d->startTime = SDL_GetTicks(); 336 d->startTime = SDL_GetTicks();
341 d->timer = SDL_AddTimer(1000 / 30, animate_Translation_, d); 337 d->timer = SDL_AddTimer(1000 / 30, animate_Translation_, d);
342} 338}
343 339
344static void setFailed_Translation_(iTranslation *d, const char *msg) { 340static void setFailed_Translation_(iTranslation *d, const char *msg) {
@@ -356,8 +352,8 @@ static iBool processResult_Translation_(iTranslation *d) {
356 return iFalse; 352 return iFalse;
357 } 353 }
358 iBlock *resultData = collect_Block(readAll_TlsRequest(d->request)); 354 iBlock *resultData = collect_Block(readAll_TlsRequest(d->request));
359 printf("result(%zu):\n%s\n", size_Block(resultData), cstr_Block(resultData)); 355// printf("result(%zu):\n%s\n", size_Block(resultData), cstr_Block(resultData));
360 fflush(stdout); 356// fflush(stdout);
361 iRegExp *pattern = iClob(new_RegExp(".*translatedText\":\"(.*)\"\\}", caseSensitive_RegExpOption)); 357 iRegExp *pattern = iClob(new_RegExp(".*translatedText\":\"(.*)\"\\}", caseSensitive_RegExpOption));
362 iRegExpMatch m; 358 iRegExpMatch m;
363 init_RegExpMatch(&m); 359 init_RegExpMatch(&m);
@@ -401,12 +397,6 @@ static iBool processResult_Translation_(iTranslation *d) {
401 appendRange_String(marked, cleanLine); 397 appendRange_String(marked, cleanLine);
402 lineIndex++; 398 lineIndex++;
403 } 399 }
404// replace_String(translation, tripleBacktickSymbol, "```");
405// replace_String(translation, doubleArrowSymbol, "=>");
406// replace_String(translation, h3Symbol, "### ");
407// replace_String(translation, h2Symbol, "## ");
408// replace_String(translation, h1Symbol, "# ");
409// replace_String(translation, bulletSymbol, "\n* ");
410 setSource_DocumentWidget(d->doc, marked); 400 setSource_DocumentWidget(d->doc, marked);
411 postCommand_App("sidebar.update"); 401 postCommand_App("sidebar.update");
412 delete_String(translation); 402 delete_String(translation);
@@ -419,7 +409,11 @@ static iBool processResult_Translation_(iTranslation *d) {
419} 409}
420 410
421static iLabelWidget *acceptButton_Translation_(const iTranslation *d) { 411static iLabelWidget *acceptButton_Translation_(const iTranslation *d) {
422 return (iLabelWidget *) lastChild_Widget(findChild_Widget(d->dlg, "dialogbuttons")); 412 iWidget *buttonParent = findChild_Widget(d->dlg, "dialogbuttons");
413// if (!buttonParent) {
414// buttonParent = findChild_Widget(d->dlg, "panel.back");
415// }
416 return (iLabelWidget *) lastChild_Widget(buttonParent);
423} 417}
424 418
425iBool handleCommand_Translation(iTranslation *d, const char *cmd) { 419iBool handleCommand_Translation(iTranslation *d, const char *cmd) {
diff --git a/src/ui/util.c b/src/ui/util.c
index c1e27751..400e65d4 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1078,6 +1078,12 @@ static iWidget *makeValuePadding_(iWidget *value) {
1078} 1078}
1079 1079
1080void finalizeSheet_Widget(iWidget *sheet) { 1080void finalizeSheet_Widget(iWidget *sheet) {
1081 /* The sheet contents are completely rearranged and restyled on a phone.
1082 We'll set up a linear fullscreen arrangement of the widgets. Sheets are already
1083 scrollable so they can be taller than the display. In hindsight, it may have been
1084 easier to create phone versions of each dialog, but at least this works with any
1085 future changes to the UI (..."works"). At least this way it is possible to enforce
1086 a consistent styling. */
1081 if (deviceType_App() == phone_AppDeviceType && parent_Widget(sheet) == get_Window()->root) { 1087 if (deviceType_App() == phone_AppDeviceType && parent_Widget(sheet) == get_Window()->root) {
1082 if (~flags_Widget(sheet) & keepOnTop_WidgetFlag) { 1088 if (~flags_Widget(sheet) & keepOnTop_WidgetFlag) {
1083 /* Already finalized. */ 1089 /* Already finalized. */
@@ -1085,11 +1091,6 @@ void finalizeSheet_Widget(iWidget *sheet) {
1085 postRefresh_App(); 1091 postRefresh_App();
1086 return; 1092 return;
1087 } 1093 }
1088 /* The sheet contents are completely rearranged on a phone. We'll set up a linear
1089 fullscreen arrangement of the widgets. Sheets are already scrollable so they
1090 can be taller than the display. In hindsight, it may have been easier to
1091 create phone versions of each dialog, but at least this works with any future
1092 changes to the UI (..."works"). */
1093 setFlags_Widget(sheet, 1094 setFlags_Widget(sheet,
1094 keepOnTop_WidgetFlag | 1095 keepOnTop_WidgetFlag |
1095 parentCannotResize_WidgetFlag | 1096 parentCannotResize_WidgetFlag |
@@ -1366,6 +1367,9 @@ void finalizeSheet_Widget(iWidget *sheet) {
1366 /* Pick up the dialog buttons for the navbar. */ 1367 /* Pick up the dialog buttons for the navbar. */
1367 iWidget *buttons = findChild_Widget(sheet, "dialogbuttons"); 1368 iWidget *buttons = findChild_Widget(sheet, "dialogbuttons");
1368 iLabelWidget *cancel = findMenuItem_Widget(buttons, "cancel"); 1369 iLabelWidget *cancel = findMenuItem_Widget(buttons, "cancel");
1370// if (!cancel) {
1371// cancel = findMenuItem_Widget(buttons, "translation.cancel");
1372// }
1369 if (cancel) { 1373 if (cancel) {
1370 updateText_LabelWidget(back, text_LabelWidget(cancel)); 1374 updateText_LabelWidget(back, text_LabelWidget(cancel));
1371 setCommand_LabelWidget(back, command_LabelWidget(cancel)); 1375 setCommand_LabelWidget(back, command_LabelWidget(cancel));
@@ -2223,6 +2227,7 @@ static const iMenuItem languages[] = {
2223}; 2227};
2224 2228
2225static iBool translationHandler_(iWidget *dlg, const char *cmd) { 2229static iBool translationHandler_(iWidget *dlg, const char *cmd) {
2230 iUnused(dlg);
2226 if (equal_Command(cmd, "xlt.lang")) { 2231 if (equal_Command(cmd, "xlt.lang")) {
2227 iLabelWidget *menuItem = pointer_Command(cmd); 2232 iLabelWidget *menuItem = pointer_Command(cmd);
2228 iWidget *button = parent_Widget(parent_Widget(menuItem)); 2233 iWidget *button = parent_Widget(parent_Widget(menuItem));
@@ -2242,6 +2247,15 @@ const char *languageId_String(const iString *menuItemLabel) {
2242 return ""; 2247 return "";
2243} 2248}
2244 2249
2250int languageIndex_CStr(const char *langId) {
2251 iForIndices(i, languages) {
2252 if (equal_Rangecc(range_Command(languages[i].command, "id"), langId)) {
2253 return i;
2254 }
2255 }
2256 return -1;
2257}
2258
2245iWidget *makeTranslation_Widget(iWidget *parent) { 2259iWidget *makeTranslation_Widget(iWidget *parent) {
2246 iWidget *dlg = makeSheet_Widget("xlt"); 2260 iWidget *dlg = makeSheet_Widget("xlt");
2247 setFlags_Widget(dlg, keepOnTop_WidgetFlag, iFalse); 2261 setFlags_Widget(dlg, keepOnTop_WidgetFlag, iFalse);
@@ -2254,25 +2268,32 @@ iWidget *makeTranslation_Widget(iWidget *parent) {
2254 iWidget *page; 2268 iWidget *page;
2255 addChild_Widget(dlg, iClob(page = makeTwoColumnWidget_(&headings, &values))); 2269 addChild_Widget(dlg, iClob(page = makeTwoColumnWidget_(&headings, &values)));
2256 setId_Widget(page, "xlt.langs"); 2270 setId_Widget(page, "xlt.langs");
2257 addChild_Widget(headings, iClob(makeHeading_Widget("From:")));
2258 iLabelWidget *fromLang, *toLang; 2271 iLabelWidget *fromLang, *toLang;
2259 setId_Widget(addChildFlags_Widget(values, 2272 /* Source language. */ {
2260 iClob(fromLang = makeMenuButton_LabelWidget( 2273 addChild_Widget(headings, iClob(makeHeading_Widget("From:")));
2261 "Portuguese", languages, iElemCount(languages))), 2274 setId_Widget(
2262 alignLeft_WidgetFlag), 2275 addChildFlags_Widget(values,
2263 "xlt.from"); 2276 iClob(fromLang = makeMenuButton_LabelWidget(
2264 updateTextCStr_LabelWidget(fromLang, "French"); /* TODO: Check source media type; remember last use. */ 2277 "Portuguese", languages, iElemCount(languages))),
2265 setBackgroundColor_Widget(findChild_Widget(as_Widget(fromLang), "menu"), 2278 alignLeft_WidgetFlag),
2266 uiBackgroundMenu_ColorId); 2279 "xlt.from");
2267 addChild_Widget(headings, iClob(makeHeading_Widget("To:"))); 2280 iWidget *langMenu = findChild_Widget(as_Widget(fromLang), "menu");
2268 setId_Widget(addChildFlags_Widget(values, 2281 updateText_LabelWidget(fromLang,
2269 iClob(toLang = makeMenuButton_LabelWidget( 2282 text_LabelWidget(child_Widget(langMenu, prefs_App()->langFrom)));
2270 "Portuguese", languages, iElemCount(languages))), 2283 setBackgroundColor_Widget(langMenu, uiBackgroundMenu_ColorId);
2271 alignLeft_WidgetFlag), 2284 }
2272 "xlt.to"); 2285 /* Target language. */ {
2273 setBackgroundColor_Widget(findChild_Widget(as_Widget(toLang), "menu"), 2286 addChild_Widget(headings, iClob(makeHeading_Widget("To:")));
2274 uiBackgroundMenu_ColorId); 2287 setId_Widget(addChildFlags_Widget(values,
2275 updateTextCStr_LabelWidget(toLang, "English"); /* TODO: User preference. */ 2288 iClob(toLang = makeMenuButton_LabelWidget(
2289 "Portuguese", languages, iElemCount(languages))),
2290 alignLeft_WidgetFlag),
2291 "xlt.to");
2292 iWidget *langMenu = findChild_Widget(as_Widget(toLang), "menu");
2293 setBackgroundColor_Widget(langMenu, uiBackgroundMenu_ColorId);
2294 updateText_LabelWidget(toLang,
2295 text_LabelWidget(child_Widget(langMenu, prefs_App()->langTo)));
2296 }
2276 addChild_Widget(dlg, iClob(makePadding_Widget(lineHeight_Text(uiLabel_FontId)))); 2297 addChild_Widget(dlg, iClob(makePadding_Widget(lineHeight_Text(uiLabel_FontId))));
2277 addChild_Widget( 2298 addChild_Widget(
2278 dlg, 2299 dlg,
diff --git a/src/ui/util.h b/src/ui/util.h
index 251683f5..35e10c6f 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -226,3 +226,4 @@ iWidget * makeFeedSettings_Widget (uint32_t bookmarkId);
226iWidget * makeTranslation_Widget (iWidget *parent); 226iWidget * makeTranslation_Widget (iWidget *parent);
227 227
228const char * languageId_String (const iString *menuItemLabel); 228const char * languageId_String (const iString *menuItemLabel);
229int languageIndex_CStr (const char *langId);