diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/documentwidget.c | 47 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 30 | ||||
-rw-r--r-- | src/ui/util.c | 15 | ||||
-rw-r--r-- | src/ui/widget.c | 6 | ||||
-rw-r--r-- | src/ui/widget.h | 1 | ||||
-rw-r--r-- | src/ui/window.c | 24 |
6 files changed, 96 insertions, 27 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index ed38ad0b..5a5a4f84 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -298,10 +298,12 @@ struct Impl_DocumentWidget { | |||
298 | 298 | ||
299 | iDefineObjectConstruction(DocumentWidget) | 299 | iDefineObjectConstruction(DocumentWidget) |
300 | 300 | ||
301 | static int docEnum_ = 0; | ||
302 | |||
301 | void init_DocumentWidget(iDocumentWidget *d) { | 303 | void init_DocumentWidget(iDocumentWidget *d) { |
302 | iWidget *w = as_Widget(d); | 304 | iWidget *w = as_Widget(d); |
303 | init_Widget(w); | 305 | init_Widget(w); |
304 | setId_Widget(w, "document000"); | 306 | setId_Widget(w, format_CStr("document%03d", ++docEnum_)); |
305 | setFlags_Widget(w, hover_WidgetFlag, iTrue); | 307 | setFlags_Widget(w, hover_WidgetFlag, iTrue); |
306 | init_PersistentDocumentState(&d->mod); | 308 | init_PersistentDocumentState(&d->mod); |
307 | d->flags = 0; | 309 | d->flags = 0; |
@@ -880,7 +882,7 @@ static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { | |||
880 | } | 882 | } |
881 | /* Take away parts if it doesn't fit. */ | 883 | /* Take away parts if it doesn't fit. */ |
882 | const int avail = bounds_Widget(as_Widget(tabButton)).size.x - 3 * gap_UI; | 884 | const int avail = bounds_Widget(as_Widget(tabButton)).size.x - 3 * gap_UI; |
883 | iBool setWindow = (document_App() == d); | 885 | iBool setWindow = (document_App() == d && isUnderKeyRoot_Widget(d)); |
884 | for (;;) { | 886 | for (;;) { |
885 | iString *text = collect_String(joinCStr_StringArray(title, " \u2014 ")); | 887 | iString *text = collect_String(joinCStr_StringArray(title, " \u2014 ")); |
886 | if (setWindow) { | 888 | if (setWindow) { |
@@ -1094,6 +1096,7 @@ static const char *zipPageHeading_(const iRangecc mime) { | |||
1094 | } | 1096 | } |
1095 | 1097 | ||
1096 | static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) { | 1098 | static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) { |
1099 | iWidget *w = as_Widget(d); | ||
1097 | delete_Gempub(d->sourceGempub); | 1100 | delete_Gempub(d->sourceGempub); |
1098 | d->sourceGempub = NULL; | 1101 | d->sourceGempub = NULL; |
1099 | if (!cmpCase_String(&d->sourceMime, "application/octet-stream") || | 1102 | if (!cmpCase_String(&d->sourceMime, "application/octet-stream") || |
@@ -1111,20 +1114,27 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) { | |||
1111 | } | 1114 | } |
1112 | } | 1115 | } |
1113 | if (!d->sourceGempub) { | 1116 | if (!d->sourceGempub) { |
1114 | iString *localPath = localFilePathFromUrl_String(d->mod.url); | 1117 | const iString *localPath = collect_String(localFilePathFromUrl_String(d->mod.url)); |
1118 | iBool isInside = iFalse; | ||
1119 | if (localPath && !fileExists_FileInfo(localPath)) { | ||
1120 | /* This URL may refer to a file inside the archive. */ | ||
1121 | localPath = findContainerArchive_Path(localPath); | ||
1122 | isInside = iTrue; | ||
1123 | } | ||
1115 | if (localPath && equal_CStr(mediaType_Path(localPath), "application/gpub+zip")) { | 1124 | if (localPath && equal_CStr(mediaType_Path(localPath), "application/gpub+zip")) { |
1116 | iGempub *gempub = new_Gempub(); | 1125 | iGempub *gempub = new_Gempub(); |
1117 | if (openFile_Gempub(gempub, localPath)) { | 1126 | if (openFile_Gempub(gempub, localPath)) { |
1118 | setBaseUrl_Gempub(gempub, d->mod.url); | 1127 | setBaseUrl_Gempub(gempub, collect_String(makeFileUrl_String(localPath))); |
1119 | setSource_DocumentWidget(d, collect_String(coverPageSource_Gempub(gempub))); | 1128 | if (!isInside) { |
1120 | setCStr_String(&d->sourceMime, mimeType_Gempub); | 1129 | setSource_DocumentWidget(d, collect_String(coverPageSource_Gempub(gempub))); |
1130 | setCStr_String(&d->sourceMime, mimeType_Gempub); | ||
1131 | } | ||
1121 | d->sourceGempub = gempub; | 1132 | d->sourceGempub = gempub; |
1122 | } | 1133 | } |
1123 | else { | 1134 | else { |
1124 | delete_Gempub(gempub); | 1135 | delete_Gempub(gempub); |
1125 | } | 1136 | } |
1126 | } | 1137 | } |
1127 | delete_String(localPath); | ||
1128 | } | 1138 | } |
1129 | if (d->sourceGempub) { | 1139 | if (d->sourceGempub) { |
1130 | if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { | 1140 | if (preloadCoverImage_Gempub(d->sourceGempub, d->doc)) { |
@@ -1132,6 +1142,26 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d) { | |||
1132 | updateVisible_DocumentWidget_(d); | 1142 | updateVisible_DocumentWidget_(d); |
1133 | invalidate_DocumentWidget_(d); | 1143 | invalidate_DocumentWidget_(d); |
1134 | } | 1144 | } |
1145 | if (prefs_App()->pinSplit && equal_String(d->mod.url, indexPageUrl_Gempub(d->sourceGempub))) { | ||
1146 | const iString *navStart = navStartLinkUrl_Gempub(d->sourceGempub); | ||
1147 | if (navStart) { | ||
1148 | iWindow *win = get_Window(); | ||
1149 | /* Auto-split to show index and the first navigation link. */ | ||
1150 | if (numRoots_Window(win) == 2) { | ||
1151 | /* This document is showing the index page. */ | ||
1152 | iRoot *other = otherRoot_Window(win, w->root); | ||
1153 | postCommandf_Root(other, "open url:%s", cstr_String(navStart)); | ||
1154 | if (prefs_App()->pinSplit == 1 && w->root == win->roots[1]) { | ||
1155 | /* On the wrong side. */ | ||
1156 | postCommand_App("ui.split swap:1"); | ||
1157 | } | ||
1158 | } | ||
1159 | else { | ||
1160 | postCommandf_App( | ||
1161 | "open newtab:%d url:%s", otherRoot_OpenTabFlag, cstr_String(navStart)); | ||
1162 | } | ||
1163 | } | ||
1164 | } | ||
1135 | } | 1165 | } |
1136 | } | 1166 | } |
1137 | 1167 | ||
@@ -1925,7 +1955,8 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
1925 | } | 1955 | } |
1926 | return iTrue; | 1956 | return iTrue; |
1927 | } | 1957 | } |
1928 | else if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { | 1958 | else if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed") || |
1959 | equal_Command(cmd, "keyroot.changed")) { | ||
1929 | /* Alt/Option key may be involved in window size changes. */ | 1960 | /* Alt/Option key may be involved in window size changes. */ |
1930 | setLinkNumberMode_DocumentWidget_(d, iFalse); | 1961 | setLinkNumberMode_DocumentWidget_(d, iFalse); |
1931 | d->phoneToolbar = findWidget_App("toolbar"); | 1962 | d->phoneToolbar = findWidget_App("toolbar"); |
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index 245b76a3..eae0432f 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -265,9 +265,10 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
265 | break; | 265 | break; |
266 | } | 266 | } |
267 | case bookmarks_SidebarMode: { | 267 | case bookmarks_SidebarMode: { |
268 | iRegExp *homeTag = iClob(new_RegExp("\\bhomepage\\b", caseSensitive_RegExpOption)); | 268 | iRegExp *homeTag = iClob(new_RegExp("\\b" homepage_BookmarkTag "\\b", caseSensitive_RegExpOption)); |
269 | iRegExp *subTag = iClob(new_RegExp("\\bsubscribed\\b", caseSensitive_RegExpOption)); | 269 | iRegExp *subTag = iClob(new_RegExp("\\b" subscribed_BookmarkTag "\\b", caseSensitive_RegExpOption)); |
270 | iRegExp *remoteSourceTag = iClob(new_RegExp("\\bremotesource\\b", caseSensitive_RegExpOption)); | 270 | iRegExp *remoteSourceTag = iClob(new_RegExp("\\b" remoteSource_BookmarkTag "\\b", caseSensitive_RegExpOption)); |
271 | iRegExp *linkSplitTag = iClob(new_RegExp("\\b" linkSplit_BookmarkTag "\\b", caseSensitive_RegExpOption)); | ||
271 | iConstForEach(PtrArray, i, list_Bookmarks(bookmarks_App(), cmpTitle_Bookmark_, NULL, NULL)) { | 272 | iConstForEach(PtrArray, i, list_Bookmarks(bookmarks_App(), cmpTitle_Bookmark_, NULL, NULL)) { |
272 | const iBookmark *bm = i.ptr; | 273 | const iBookmark *bm = i.ptr; |
273 | iSidebarItem *item = new_SidebarItem(); | 274 | iSidebarItem *item = new_SidebarItem(); |
@@ -290,6 +291,10 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
290 | appendChar_String(&item->meta, 0x2913); | 291 | appendChar_String(&item->meta, 0x2913); |
291 | item->isBold = iTrue; | 292 | item->isBold = iTrue; |
292 | } | 293 | } |
294 | init_RegExpMatch(&m); | ||
295 | if (matchString_RegExp(linkSplitTag, &bm->tags, &m)) { | ||
296 | appendChar_String(&item->meta, 0x25e7); | ||
297 | } | ||
293 | } | 298 | } |
294 | addItem_ListWidget(d->list, item); | 299 | addItem_ListWidget(d->list, item); |
295 | iRelease(item); | 300 | iRelease(item); |
@@ -828,11 +833,15 @@ iBool handleBookmarkEditorCommands_SidebarWidget_(iWidget *editor, const char *c | |||
828 | bm->icon = 0; | 833 | bm->icon = 0; |
829 | } | 834 | } |
830 | else { | 835 | else { |
831 | if (!hasTag_Bookmark(bm, userIcon_BookmarkTag)) { | 836 | addTagIfMissing_Bookmark(bm, userIcon_BookmarkTag); |
832 | addTag_Bookmark(bm, userIcon_BookmarkTag); | ||
833 | } | ||
834 | bm->icon = first_String(icon); | 837 | bm->icon = first_String(icon); |
835 | } | 838 | } |
839 | addOrRemoveTag_Bookmark(bm, homepage_BookmarkTag, | ||
840 | isSelected_Widget(findChild_Widget(editor, "bmed.tag.home"))); | ||
841 | addOrRemoveTag_Bookmark(bm, remoteSource_BookmarkTag, | ||
842 | isSelected_Widget(findChild_Widget(editor, "bmed.tag.remote"))); | ||
843 | addOrRemoveTag_Bookmark(bm, linkSplit_BookmarkTag, | ||
844 | isSelected_Widget(findChild_Widget(editor, "bmed.tag.linksplit"))); | ||
836 | postCommand_App("bookmarks.changed"); | 845 | postCommand_App("bookmarks.changed"); |
837 | } | 846 | } |
838 | setFlags_Widget(as_Widget(d), disabled_WidgetFlag, iFalse); | 847 | setFlags_Widget(as_Widget(d), disabled_WidgetFlag, iFalse); |
@@ -1012,6 +1021,15 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1012 | setText_InputWidget(findChild_Widget(dlg, "bmed.icon"), | 1021 | setText_InputWidget(findChild_Widget(dlg, "bmed.icon"), |
1013 | collect_String(newUnicodeN_String(&bm->icon, 1))); | 1022 | collect_String(newUnicodeN_String(&bm->icon, 1))); |
1014 | } | 1023 | } |
1024 | setFlags_Widget(findChild_Widget(dlg, "bmed.tag.home"), | ||
1025 | selected_WidgetFlag, | ||
1026 | hasTag_Bookmark(bm, homepage_BookmarkTag)); | ||
1027 | setFlags_Widget(findChild_Widget(dlg, "bmed.tag.remote"), | ||
1028 | selected_WidgetFlag, | ||
1029 | hasTag_Bookmark(bm, remoteSource_BookmarkTag)); | ||
1030 | setFlags_Widget(findChild_Widget(dlg, "bmed.tag.linksplit"), | ||
1031 | selected_WidgetFlag, | ||
1032 | hasTag_Bookmark(bm, linkSplit_BookmarkTag)); | ||
1015 | setCommandHandler_Widget(dlg, handleBookmarkEditorCommands_SidebarWidget_); | 1033 | setCommandHandler_Widget(dlg, handleBookmarkEditorCommands_SidebarWidget_); |
1016 | setFocus_Widget(findChild_Widget(dlg, "bmed.title")); | 1034 | setFocus_Widget(findChild_Widget(dlg, "bmed.title")); |
1017 | } | 1035 | } |
diff --git a/src/ui/util.c b/src/ui/util.c index d2f27a8b..92cf85b7 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -2506,11 +2506,18 @@ static iBool handleBookmarkCreationCommands_SidebarWidget_(iWidget *editor, cons | |||
2506 | const iString *tags = text_InputWidget(findChild_Widget(editor, "bmed.tags")); | 2506 | const iString *tags = text_InputWidget(findChild_Widget(editor, "bmed.tags")); |
2507 | const iString *icon = collect_String(trimmed_String(text_InputWidget(findChild_Widget(editor, "bmed.icon")))); | 2507 | const iString *icon = collect_String(trimmed_String(text_InputWidget(findChild_Widget(editor, "bmed.icon")))); |
2508 | const uint32_t id = add_Bookmarks(bookmarks_App(), url, title, tags, first_String(icon)); | 2508 | const uint32_t id = add_Bookmarks(bookmarks_App(), url, title, tags, first_String(icon)); |
2509 | iBookmark * bm = get_Bookmarks(bookmarks_App(), id); | ||
2509 | if (!isEmpty_String(icon)) { | 2510 | if (!isEmpty_String(icon)) { |
2510 | iBookmark *bm = get_Bookmarks(bookmarks_App(), id); | 2511 | addTagIfMissing_Bookmark(bm, userIcon_BookmarkTag); |
2511 | if (!hasTag_Bookmark(bm, userIcon_BookmarkTag)) { | 2512 | } |
2512 | addTag_Bookmark(bm, userIcon_BookmarkTag); | 2513 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.home"))) { |
2513 | } | 2514 | addTag_Bookmark(bm, homepage_BookmarkTag); |
2515 | } | ||
2516 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.remote"))) { | ||
2517 | addTag_Bookmark(bm, remoteSource_BookmarkTag); | ||
2518 | } | ||
2519 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.linksplit"))) { | ||
2520 | addTag_Bookmark(bm, linkSplit_BookmarkTag); | ||
2514 | } | 2521 | } |
2515 | postCommand_App("bookmarks.changed"); | 2522 | postCommand_App("bookmarks.changed"); |
2516 | } | 2523 | } |
diff --git a/src/ui/widget.c b/src/ui/widget.c index 00fe0f5f..67ce1345 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -1346,6 +1346,12 @@ iBool isHover_Widget(const iAnyObject *d) { | |||
1346 | return get_Window()->hover == d; | 1346 | return get_Window()->hover == d; |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | iBool isUnderKeyRoot_Widget(const iAnyObject *d) { | ||
1350 | iAssert(isInstance_Object(d, &Class_Widget)); | ||
1351 | const iWidget *w = d; | ||
1352 | return w && get_Window() && w->root == get_Window()->keyRoot; | ||
1353 | } | ||
1354 | |||
1349 | iBool isSelected_Widget(const iAnyObject *d) { | 1355 | iBool isSelected_Widget(const iAnyObject *d) { |
1350 | if (d) { | 1356 | if (d) { |
1351 | iAssert(isInstance_Object(d, &Class_Widget)); | 1357 | iAssert(isInstance_Object(d, &Class_Widget)); |
diff --git a/src/ui/widget.h b/src/ui/widget.h index 36797210..5b6b18e1 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h | |||
@@ -232,6 +232,7 @@ iBool isDisabled_Widget (const iAnyObject *); | |||
232 | iBool isFocused_Widget (const iAnyObject *); | 232 | iBool isFocused_Widget (const iAnyObject *); |
233 | iBool isHover_Widget (const iAnyObject *); | 233 | iBool isHover_Widget (const iAnyObject *); |
234 | iBool isSelected_Widget (const iAnyObject *); | 234 | iBool isSelected_Widget (const iAnyObject *); |
235 | iBool isUnderKeyRoot_Widget (const iAnyObject *); | ||
235 | iBool isCommand_Widget (const iWidget *d, const SDL_Event *ev, const char *cmd); | 236 | iBool isCommand_Widget (const iWidget *d, const SDL_Event *ev, const char *cmd); |
236 | iBool hasParent_Widget (const iWidget *d, const iWidget *someParent); | 237 | iBool hasParent_Widget (const iWidget *d, const iWidget *someParent); |
237 | iBool isAffectedByVisualOffset_Widget | 238 | iBool isAffectedByVisualOffset_Widget |
diff --git a/src/ui/window.c b/src/ui/window.c index c4d06d75..a1df2609 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -1214,30 +1214,36 @@ void setSplitMode_Window(iWindow *d, int splitFlags) { | |||
1214 | /* Add a second root. */ | 1214 | /* Add a second root. */ |
1215 | iDocumentWidget *moved = document_Root(d->roots[0]); | 1215 | iDocumentWidget *moved = document_Root(d->roots[0]); |
1216 | iAssert(d->roots[1] == NULL); | 1216 | iAssert(d->roots[1] == NULL); |
1217 | d->roots[1] = new_Root(); | 1217 | const iBool addToLeft = (prefs_App()->pinSplit == 2); |
1218 | setCurrent_Root(d->roots[1]); | 1218 | size_t newRootIndex = 1; |
1219 | d->keyRoot = d->roots[1]; | 1219 | if (addToLeft) { |
1220 | createUserInterface_Root(d->roots[1]); | 1220 | iSwap(iRoot *, d->roots[0], d->roots[1]); |
1221 | newRootIndex = 0; | ||
1222 | } | ||
1223 | d->roots[newRootIndex] = new_Root(); | ||
1224 | d->keyRoot = d->roots[newRootIndex]; | ||
1225 | setCurrent_Root(d->roots[newRootIndex]); | ||
1226 | createUserInterface_Root(d->roots[newRootIndex]); | ||
1221 | if (!isEmpty_String(d->pendingSplitUrl)) { | 1227 | if (!isEmpty_String(d->pendingSplitUrl)) { |
1222 | postCommandf_Root(d->roots[1], "open url:%s", | 1228 | postCommandf_Root(d->roots[newRootIndex], "open url:%s", |
1223 | cstr_String(d->pendingSplitUrl)); | 1229 | cstr_String(d->pendingSplitUrl)); |
1224 | clear_String(d->pendingSplitUrl); | 1230 | clear_String(d->pendingSplitUrl); |
1225 | } | 1231 | } |
1226 | else if (~splitFlags & noEvents_WindowSplit) { | 1232 | else if (~splitFlags & noEvents_WindowSplit) { |
1227 | iWidget *docTabs0 = findChild_Widget(d->roots[0]->widget, "doctabs"); | 1233 | iWidget *docTabs0 = findChild_Widget(d->roots[newRootIndex ^ 1]->widget, "doctabs"); |
1228 | iWidget *docTabs1 = findChild_Widget(d->roots[1]->widget, "doctabs"); | 1234 | iWidget *docTabs1 = findChild_Widget(d->roots[newRootIndex]->widget, "doctabs"); |
1229 | /* If the old root has multiple tabs, move the current one to the new split. */ | 1235 | /* If the old root has multiple tabs, move the current one to the new split. */ |
1230 | if (tabCount_Widget(docTabs0) >= 2) { | 1236 | if (tabCount_Widget(docTabs0) >= 2) { |
1231 | int movedIndex = tabPageIndex_Widget(docTabs0, moved); | 1237 | int movedIndex = tabPageIndex_Widget(docTabs0, moved); |
1232 | removeTabPage_Widget(docTabs0, movedIndex); | 1238 | removeTabPage_Widget(docTabs0, movedIndex); |
1233 | showTabPage_Widget(docTabs0, tabPage_Widget(docTabs0, iMax(movedIndex - 1, 0))); | 1239 | showTabPage_Widget(docTabs0, tabPage_Widget(docTabs0, iMax(movedIndex - 1, 0))); |
1234 | iRelease(removeTabPage_Widget(docTabs1, 0)); /* delete the default tab */ | 1240 | iRelease(removeTabPage_Widget(docTabs1, 0)); /* delete the default tab */ |
1235 | setRoot_Widget(as_Widget(moved), d->roots[1]); | 1241 | setRoot_Widget(as_Widget(moved), d->roots[newRootIndex]); |
1236 | prependTabPage_Widget(docTabs1, iClob(moved), "", 0, 0); | 1242 | prependTabPage_Widget(docTabs1, iClob(moved), "", 0, 0); |
1237 | postCommandf_App("tabs.switch page:%p", moved); | 1243 | postCommandf_App("tabs.switch page:%p", moved); |
1238 | } | 1244 | } |
1239 | else { | 1245 | else { |
1240 | postCommand_Root(d->roots[1], "navigate.home"); | 1246 | postCommand_Root(d->roots[newRootIndex], "navigate.home"); |
1241 | } | 1247 | } |
1242 | } | 1248 | } |
1243 | setCurrent_Root(NULL); | 1249 | setCurrent_Root(NULL); |