summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-29 07:17:45 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-29 07:17:45 +0300
commit23e31410556e9b4e22c3742b2b137bd5d96abac8 (patch)
treec42929118328d17f285a1b9c49730132ad3ede3c
parent18e590f1fd50397004113804bf1218656119d41f (diff)
Gempub: Fixed glitches in DocumentWidget
-rw-r--r--po/en.po3
-rw-r--r--res/lang/de.binbin20997 -> 21054 bytes
-rw-r--r--res/lang/en.binbin19702 -> 19759 bytes
-rw-r--r--res/lang/es.binbin22044 -> 22101 bytes
-rw-r--r--res/lang/fi.binbin21685 -> 21742 bytes
-rw-r--r--res/lang/fr.binbin22609 -> 22666 bytes
-rw-r--r--res/lang/ia.binbin21907 -> 21964 bytes
-rw-r--r--res/lang/ie.binbin21075 -> 21132 bytes
-rw-r--r--res/lang/pl.binbin22713 -> 22770 bytes
-rw-r--r--res/lang/ru.binbin32794 -> 32851 bytes
-rw-r--r--res/lang/sr.binbin31369 -> 31426 bytes
-rw-r--r--res/lang/tok.binbin20112 -> 20169 bytes
-rw-r--r--res/lang/zh_Hans.binbin18866 -> 18923 bytes
-rw-r--r--res/lang/zh_Hant.binbin19051 -> 19108 bytes
-rw-r--r--src/gempub.c19
-rw-r--r--src/gempub.h1
-rw-r--r--src/ui/documentwidget.c70
17 files changed, 67 insertions, 26 deletions
diff --git a/po/en.po b/po/en.po
index e32ba5c1..bbca83e5 100644
--- a/po/en.po
+++ b/po/en.po
@@ -191,6 +191,9 @@ msgstr "Save to Files"
191msgid "menu.save.downloads" 191msgid "menu.save.downloads"
192msgstr "Save to Downloads" 192msgstr "Save to Downloads"
193 193
194msgid "menu.save.downloads.open"
195msgstr "Save to Downloads and Open File"
196
194msgid "menu.sidebar" 197msgid "menu.sidebar"
195msgstr "Toggle Sidebar" 198msgstr "Toggle Sidebar"
196 199
diff --git a/res/lang/de.bin b/res/lang/de.bin
index a70f5f62..45260c31 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 19650c34..728c7ff8 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 e4d45e79..d6cdd974 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 06c815fa..b66badcb 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 e39abdfa..232338c9 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 0c0797eb..e460faf7 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 9aa66449..87e3c0e5 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 6df22643..0c021408 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 c6ea9e0a..17df17a8 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 a770ac48..74f897cb 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 6335c836..4d8259b3 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 8490d0d6..c5b6cede 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 b39feba1..56d7643d 100644
--- a/res/lang/zh_Hant.bin
+++ b/res/lang/zh_Hant.bin
Binary files differ
diff --git a/src/gempub.c b/src/gempub.c
index f3021add..1f5d58ce 100644
--- a/src/gempub.c
+++ b/src/gempub.c
@@ -94,6 +94,9 @@ static void parseNavigationLinks_Gempub_(const iGempub *d) {
94 set_String(&link.url, absoluteUrl_String(url_GmRequest(index), collectNewRange_String(url))); 94 set_String(&link.url, absoluteUrl_String(url_GmRequest(index), collectNewRange_String(url)));
95 setRange_String(&link.label, capturedRange_RegExpMatch(&m, 2)); 95 setRange_String(&link.label, capturedRange_RegExpMatch(&m, 2));
96 trim_String(&link.label); 96 trim_String(&link.label);
97 if (isEmpty_String(&link.label)) {
98 setRange_String(&link.label, url);
99 }
97 pushBack_Array(d->navLinks, &link); 100 pushBack_Array(d->navLinks, &link);
98 } 101 }
99 iEndCollect(); 102 iEndCollect();
@@ -280,7 +283,7 @@ static void appendProperty_Gempub_(const iGempub *d, const char *label,
280 } 283 }
281} 284}
282 285
283static iBool isRemote_Gempub_(const iGempub *d) { 286iBool isRemote_Gempub(const iGempub *d) {
284 return !equalCase_Rangecc(urlScheme_String(&d->baseUrl), "file"); 287 return !equalCase_Rangecc(urlScheme_String(&d->baseUrl), "file");
285} 288}
286 289
@@ -295,7 +298,7 @@ iString *coverPageSource_Gempub(const iGempub *d) {
295 } 298 }
296 appendCStr_String(out, "\n"); 299 appendCStr_String(out, "\n");
297 appendProperty_Gempub_(d, "${gempub.meta.author}:", author_GempubProperty, out); 300 appendProperty_Gempub_(d, "${gempub.meta.author}:", author_GempubProperty, out);
298 if (!isRemote_Gempub_(d)) { 301 if (!isRemote_Gempub(d)) {
299 appendFormat_String(out, "\n=> %s " book_Icon " ${gempub.cover.view}\n", 302 appendFormat_String(out, "\n=> %s " book_Icon " ${gempub.cover.view}\n",
300 cstr_String(indexPageUrl_Gempub(d))); 303 cstr_String(indexPageUrl_Gempub(d)));
301 if (hasProperty_Gempub_(d, cover_GempubProperty)) { 304 if (hasProperty_Gempub_(d, cover_GempubProperty)) {
@@ -306,12 +309,12 @@ iString *coverPageSource_Gempub(const iGempub *d) {
306 else { 309 else {
307 iString *key = collectNew_String(); /* TODO: add a helper for this */ 310 iString *key = collectNew_String(); /* TODO: add a helper for this */
308 toString_Sym(SDLK_s, KMOD_PRIMARY, key); 311 toString_Sym(SDLK_s, KMOD_PRIMARY, key);
309 appendCStr_String(out, "\n${gempub.cover.viewlocal} "); 312 appendCStr_String(out, "\n${gempub.cover.viewlocal}\n");
310 appendFormat_String(out, 313// appendFormat_String(out,
311 cstr_Lang("error.unsupported.suggestsave"), 314// cstr_Lang("error.unsupported.suggestsave"),
312 cstr_String(key), 315// cstr_String(key),
313 saveToDownloads_Label); 316// saveToDownloads_Label);
314 appendCStr_String(out, "\n"); 317// appendCStr_String(out, "\n");
315 } 318 }
316 appendCStr_String(out, "\n## ${gempub.cover.aboutbook}\n"); 319 appendCStr_String(out, "\n## ${gempub.cover.aboutbook}\n");
317 appendProperty_Gempub_(d, "${gempub.meta.version}:", version_GempubProperty, out); 320 appendProperty_Gempub_(d, "${gempub.meta.version}:", version_GempubProperty, out);
diff --git a/src/gempub.h b/src/gempub.h
index c03cabe6..e5f1b8eb 100644
--- a/src/gempub.h
+++ b/src/gempub.h
@@ -53,6 +53,7 @@ void close_Gempub (iGempub *);
53void setBaseUrl_Gempub (iGempub *, const iString *baseUrl); 53void setBaseUrl_Gempub (iGempub *, const iString *baseUrl);
54 54
55iBool isOpen_Gempub (const iGempub *); 55iBool isOpen_Gempub (const iGempub *);
56iBool isRemote_Gempub (const iGempub *);
56iString * coverPageSource_Gempub (const iGempub *); 57iString * coverPageSource_Gempub (const iGempub *);
57iBool preloadCoverImage_Gempub(const iGempub *, iGmDocument *doc); 58iBool preloadCoverImage_Gempub(const iGempub *, iGmDocument *doc);
58 59
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index c8aad02b..a02e0bca 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -820,6 +820,13 @@ static iRangecc currentHeading_DocumentWidget_(const iDocumentWidget *d) {
820 return heading; 820 return heading;
821} 821}
822 822
823static int updateScrollMax_DocumentWidget_(iDocumentWidget *d) {
824 arrange_Widget(d->footerButtons); /* scrollMax depends on footer height */
825 const int scrollMax = scrollMax_DocumentWidget_(d);
826 setMax_SmoothScroll(&d->scrollY, scrollMax);
827 return scrollMax;
828}
829
823static void updateVisible_DocumentWidget_(iDocumentWidget *d) { 830static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
824 iChangeFlags(d->flags, 831 iChangeFlags(d->flags,
825 centerVertically_DocumentWidgetFlag, 832 centerVertically_DocumentWidgetFlag,
@@ -827,7 +834,7 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
827 !isSuccess_GmStatusCode(d->sourceStatus)); 834 !isSuccess_GmStatusCode(d->sourceStatus));
828 const iRangei visRange = visibleRange_DocumentWidget_(d); 835 const iRangei visRange = visibleRange_DocumentWidget_(d);
829 const iRect bounds = bounds_Widget(as_Widget(d)); 836 const iRect bounds = bounds_Widget(as_Widget(d));
830 const int scrollMax = scrollMax_DocumentWidget_(d); 837 const int scrollMax = updateScrollMax_DocumentWidget_(d);
831 /* Reposition the footer buttons as appropriate. */ 838 /* Reposition the footer buttons as appropriate. */
832 /* TODO: You can just position `footerButtons` here completely without having to get 839 /* TODO: You can just position `footerButtons` here completely without having to get
833 `Widget` involved with the offset in any way. */ 840 `Widget` involved with the offset in any way. */
@@ -837,7 +844,6 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
837 const int hPad = (width_Rect(bounds) - iMin(120 * gap_UI, width_Rect(docBounds))) / 2; 844 const int hPad = (width_Rect(bounds) - iMin(120 * gap_UI, width_Rect(docBounds))) / 2;
838 const int vPad = 3 * gap_UI; 845 const int vPad = 3 * gap_UI;
839 setPadding_Widget(d->footerButtons, hPad, vPad, hPad, vPad); 846 setPadding_Widget(d->footerButtons, hPad, vPad, hPad, vPad);
840 arrange_Widget(d->footerButtons);
841 d->footerButtons->animOffsetRef = (scrollMax > 0 ? &d->scrollY.pos : NULL); 847 d->footerButtons->animOffsetRef = (scrollMax > 0 ? &d->scrollY.pos : NULL);
842 if (scrollMax <= 0) { 848 if (scrollMax <= 0) {
843 d->footerButtons->animOffsetRef = NULL; 849 d->footerButtons->animOffsetRef = NULL;
@@ -848,7 +854,6 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
848 d->footerButtons->rect.pos.y = size_GmDocument(d->doc).y + 2 * gap_UI * d->pageMargin; 854 d->footerButtons->rect.pos.y = size_GmDocument(d->doc).y + 2 * gap_UI * d->pageMargin;
849 } 855 }
850 } 856 }
851 setMax_SmoothScroll(&d->scrollY, scrollMax);
852 setRange_ScrollWidget(d->scroll, (iRangei){ 0, scrollMax }); 857 setRange_ScrollWidget(d->scroll, (iRangei){ 0, scrollMax });
853 const int docSize = size_GmDocument(d->doc).y; 858 const int docSize = size_GmDocument(d->doc).y;
854 setThumb_ScrollWidget(d->scroll, 859 setThumb_ScrollWidget(d->scroll,
@@ -1066,7 +1071,7 @@ static void makeFooterButtons_DocumentWidget_(iDocumentWidget *d, const iMenuIte
1066 resizeWidthOfChildren_WidgetFlag | arrangeHeight_WidgetFlag | 1071 resizeWidthOfChildren_WidgetFlag | arrangeHeight_WidgetFlag |
1067 fixedPosition_WidgetFlag | resizeToParentWidth_WidgetFlag, 1072 fixedPosition_WidgetFlag | resizeToParentWidth_WidgetFlag,
1068 iTrue); 1073 iTrue);
1069 setBackgroundColor_Widget(d->footerButtons, tmBackground_ColorId); 1074 //setBackgroundColor_Widget(d->footerButtons, tmBackground_ColorId);
1070 for (size_t i = 0; i < count; ++i) { 1075 for (size_t i = 0; i < count; ++i) {
1071 iLabelWidget *button = addChildFlags_Widget( 1076 iLabelWidget *button = addChildFlags_Widget(
1072 d->footerButtons, 1077 d->footerButtons,
@@ -1079,6 +1084,7 @@ static void makeFooterButtons_DocumentWidget_(iDocumentWidget *d, const iMenuIte
1079 addChild_Widget(as_Widget(d), iClob(d->footerButtons)); 1084 addChild_Widget(as_Widget(d), iClob(d->footerButtons));
1080 arrange_Widget(d->footerButtons); 1085 arrange_Widget(d->footerButtons);
1081 arrange_Widget(w); 1086 arrange_Widget(w);
1087 updateVisible_DocumentWidget_(d); /* final placement for the buttons */
1082} 1088}
1083 1089
1084static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode code, 1090static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode code,
@@ -1222,7 +1228,7 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool
1222 } 1228 }
1223 if (d->sourceGempub) { 1229 if (d->sourceGempub) {
1224 if (equal_String(d->mod.url, coverPageUrl_Gempub(d->sourceGempub))) { 1230 if (equal_String(d->mod.url, coverPageUrl_Gempub(d->sourceGempub))) {
1225 if (equalCase_Rangecc(urlScheme_String(d->mod.url), "file")) { 1231 if (!isRemote_Gempub(d->sourceGempub)) {
1226 iArray *items = collectNew_Array(sizeof(iMenuItem)); 1232 iArray *items = collectNew_Array(sizeof(iMenuItem));
1227 pushBack_Array( 1233 pushBack_Array(
1228 items, 1234 items,
@@ -1244,6 +1250,19 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool
1244 } 1250 }
1245 makeFooterButtons_DocumentWidget_(d, constData_Array(items), size_Array(items)); 1251 makeFooterButtons_DocumentWidget_(d, constData_Array(items), size_Array(items));
1246 } 1252 }
1253 else {
1254 makeFooterButtons_DocumentWidget_(
1255 d,
1256 (iMenuItem[]){ { book_Icon " ${menu.save.downloads.open}",
1257 SDLK_s,
1258 KMOD_PRIMARY | KMOD_SHIFT,
1259 "document.save open:1" },
1260 { download_Icon " " saveToDownloads_Label,
1261 SDLK_s,
1262 KMOD_PRIMARY,
1263 "document.save" } },
1264 2);
1265 }
1247 if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { 1266 if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) {
1248 redoLayout_GmDocument(d->doc); 1267 redoLayout_GmDocument(d->doc);
1249 updateVisible_DocumentWidget_(d); 1268 updateVisible_DocumentWidget_(d);
@@ -2048,7 +2067,8 @@ static iBool fetchNextUnfetchedImage_DocumentWidget_(iDocumentWidget *d) {
2048 return iFalse; 2067 return iFalse;
2049} 2068}
2050 2069
2051static void saveToDownloads_(const iString *url, const iString *mime, const iBlock *content) { 2070static const iString *saveToDownloads_(const iString *url, const iString *mime, const iBlock *content,
2071 iBool showDialog) {
2052 const iString *savePath = downloadPathForUrl_App(url, mime); 2072 const iString *savePath = downloadPathForUrl_App(url, mime);
2053 /* Write the file. */ { 2073 /* Write the file. */ {
2054 iFile *f = new_File(savePath); 2074 iFile *f = new_File(savePath);
@@ -2060,17 +2080,22 @@ static void saveToDownloads_(const iString *url, const iString *mime, const iBlo
2060#if defined (iPlatformAppleMobile) 2080#if defined (iPlatformAppleMobile)
2061 exportDownloadedFile_iOS(savePath); 2081 exportDownloadedFile_iOS(savePath);
2062#else 2082#else
2063 const iMenuItem items[2] = { 2083 if (showDialog) {
2064 { "${dlg.save.opendownload}", 0, 0, 2084 const iMenuItem items[2] = {
2065 format_CStr("!open url:%s", cstrCollect_String(makeFileUrl_String(savePath))) }, 2085 { "${dlg.save.opendownload}", 0, 0,
2066 { "${dlg.message.ok}", 0, 0, "message.ok" }, 2086 format_CStr("!open url:%s", cstrCollect_String(makeFileUrl_String(savePath))) },
2067 }; 2087 { "${dlg.message.ok}", 0, 0, "message.ok" },
2068 makeMessage_Widget(uiHeading_ColorEscape "${heading.save}", 2088 };
2069 format_CStr("%s\n${dlg.save.size} %.3f %s", cstr_String(path_File(f)), 2089 makeMessage_Widget(uiHeading_ColorEscape "${heading.save}",
2070 isMega ? size / 1.0e6f : (size / 1.0e3f), 2090 format_CStr("%s\n${dlg.save.size} %.3f %s",
2071 isMega ? "${mb}" : "${kb}"), 2091 cstr_String(path_File(f)),
2072 items, iElemCount(items)); 2092 isMega ? size / 1.0e6f : (size / 1.0e3f),
2093 isMega ? "${mb}" : "${kb}"),
2094 items,
2095 iElemCount(items));
2096 }
2073#endif 2097#endif
2098 return savePath;
2074 } 2099 }
2075 else { 2100 else {
2076 makeSimpleMessage_Widget(uiTextCaution_ColorEscape "${heading.save.error}", 2101 makeSimpleMessage_Widget(uiTextCaution_ColorEscape "${heading.save.error}",
@@ -2078,6 +2103,7 @@ static void saveToDownloads_(const iString *url, const iString *mime, const iBlo
2078 } 2103 }
2079 iRelease(f); 2104 iRelease(f);
2080 } 2105 }
2106 return collectNew_String();
2081} 2107}
2082 2108
2083static void addAllLinks_(void *context, const iGmRun *run) { 2109static void addAllLinks_(void *context, const iGmRun *run) {
@@ -2556,7 +2582,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2556 const iMediaRequest *media = findMediaRequest_DocumentWidget_(d, linkId); 2582 const iMediaRequest *media = findMediaRequest_DocumentWidget_(d, linkId);
2557 if (media) { 2583 if (media) {
2558 saveToDownloads_(url_GmRequest(media->req), meta_GmRequest(media->req), 2584 saveToDownloads_(url_GmRequest(media->req), meta_GmRequest(media->req),
2559 body_GmRequest(media->req)); 2585 body_GmRequest(media->req), iTrue);
2560 } 2586 }
2561 } 2587 }
2562 else if (equal_Command(cmd, "document.save") && document_App() == d) { 2588 else if (equal_Command(cmd, "document.save") && document_App() == d) {
@@ -2565,7 +2591,13 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2565 "${dlg.save.incomplete}"); 2591 "${dlg.save.incomplete}");
2566 } 2592 }
2567 else if (!isEmpty_Block(&d->sourceContent)) { 2593 else if (!isEmpty_Block(&d->sourceContent)) {
2568 saveToDownloads_(d->mod.url, &d->sourceMime, &d->sourceContent); 2594 const iBool doOpen = argLabel_Command(cmd, "open");
2595 const iString *savePath = saveToDownloads_(d->mod.url, &d->sourceMime,
2596 &d->sourceContent, !doOpen);
2597 if (!isEmpty_String(savePath) && doOpen) {
2598 postCommandf_Root(
2599 w->root, "!open url:%s", cstrCollect_String(makeFileUrl_String(savePath)));
2600 }
2569 } 2601 }
2570 return iTrue; 2602 return iTrue;
2571 } 2603 }
@@ -2675,6 +2707,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2675 return iTrue; 2707 return iTrue;
2676 } 2708 }
2677 else if (equal_Command(cmd, "scroll.bottom") && document_App() == d) { 2709 else if (equal_Command(cmd, "scroll.bottom") && document_App() == d) {
2710 updateScrollMax_DocumentWidget_(d); /* scrollY.max might not be fully updated */
2678 init_Anim(&d->scrollY.pos, d->scrollY.max); 2711 init_Anim(&d->scrollY.pos, d->scrollY.max);
2679 invalidate_VisBuf(d->visBuf); 2712 invalidate_VisBuf(d->visBuf);
2680 clampScroll_DocumentWidget_(d); 2713 clampScroll_DocumentWidget_(d);
@@ -3188,6 +3221,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
3188 iArray items; 3221 iArray items;
3189 init_Array(&items, sizeof(iMenuItem)); 3222 init_Array(&items, sizeof(iMenuItem));
3190 if (d->contextLink) { 3223 if (d->contextLink) {
3224 /* Context menu for a link. */
3191 const iString *linkUrl = linkUrl_GmDocument(d->doc, d->contextLink->linkId); 3225 const iString *linkUrl = linkUrl_GmDocument(d->doc, d->contextLink->linkId);
3192// const int linkFlags = linkFlags_GmDocument(d->doc, d->contextLink->linkId); 3226// const int linkFlags = linkFlags_GmDocument(d->doc, d->contextLink->linkId);
3193 const iRangecc scheme = urlScheme_String(linkUrl); 3227 const iRangecc scheme = urlScheme_String(linkUrl);