diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-11-28 14:03:33 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-11-28 14:03:33 +0200 |
commit | 1efe2aab4fdc811c1dd37c76d1f5d37063745649 (patch) | |
tree | 410df70002df7256343a993fc91a9b1dcbb3dbca | |
parent | ab44b19cf747c348099c5aa86fcaf8bf0be628c9 (diff) |
Bookmarks: Internal tags have a dot prefix
Internal behavior tags are now written in bookmarks.ini with a dot prefix (like hidden files on Unix), and at runtime they are removed from the tags string.
This makes things more efficient as it isn't necessary to compile regular expressions all the time.
TODO: Add "Edit Feed..." into the Bookmarks context menu, and a new menu item for listing all subscriptions.
IssueID #331
-rw-r--r-- | src/app.c | 4 | ||||
-rw-r--r-- | src/bookmarks.c | 135 | ||||
-rw-r--r-- | src/bookmarks.h | 77 | ||||
-rw-r--r-- | src/feeds.c | 12 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 4 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 85 | ||||
-rw-r--r-- | src/ui/util.c | 18 |
7 files changed, 204 insertions, 131 deletions
@@ -2980,10 +2980,8 @@ iBool handleCommand_App(const char *cmd) { | |||
2980 | } | 2980 | } |
2981 | else if (equal_Command(cmd, "navigate.home")) { | 2981 | else if (equal_Command(cmd, "navigate.home")) { |
2982 | /* Look for bookmarks tagged "homepage". */ | 2982 | /* Look for bookmarks tagged "homepage". */ |
2983 | iRegExp *pattern = iClob(new_RegExp("\\b" homepage_BookmarkTag "\\b", | ||
2984 | caseInsensitive_RegExpOption)); | ||
2985 | const iPtrArray *homepages = | 2983 | const iPtrArray *homepages = |
2986 | list_Bookmarks(d->bookmarks, NULL, filterTagsRegExp_Bookmarks, pattern); | 2984 | list_Bookmarks(d->bookmarks, NULL, filterHomepage_Bookmark, NULL); |
2987 | if (isEmpty_PtrArray(homepages)) { | 2985 | if (isEmpty_PtrArray(homepages)) { |
2988 | postCommand_Root(get_Root(), "open url:about:lagrange"); | 2986 | postCommand_Root(get_Root(), "open url:about:lagrange"); |
2989 | } | 2987 | } |
diff --git a/src/bookmarks.c b/src/bookmarks.c index d4b20162..2606d975 100644 --- a/src/bookmarks.c +++ b/src/bookmarks.c | |||
@@ -37,6 +37,7 @@ void init_Bookmark(iBookmark *d) { | |||
37 | init_String(&d->url); | 37 | init_String(&d->url); |
38 | init_String(&d->title); | 38 | init_String(&d->title); |
39 | init_String(&d->tags); | 39 | init_String(&d->tags); |
40 | iZap(d->flags); | ||
40 | iZap(d->when); | 41 | iZap(d->when); |
41 | d->parentId = 0; | 42 | d->parentId = 0; |
42 | d->order = 0; | 43 | d->order = 0; |
@@ -48,6 +49,7 @@ void deinit_Bookmark(iBookmark *d) { | |||
48 | deinit_String(&d->url); | 49 | deinit_String(&d->url); |
49 | } | 50 | } |
50 | 51 | ||
52 | #if 0 | ||
51 | iBool hasTag_Bookmark(const iBookmark *d, const char *tag) { | 53 | iBool hasTag_Bookmark(const iBookmark *d, const char *tag) { |
52 | if (!d) return iFalse; | 54 | if (!d) return iFalse; |
53 | iRegExp *pattern = new_RegExp(format_CStr("\\b%s\\b", tag), caseSensitive_RegExpOption); | 55 | iRegExp *pattern = new_RegExp(format_CStr("\\b%s\\b", tag), caseSensitive_RegExpOption); |
@@ -60,7 +62,7 @@ iBool hasTag_Bookmark(const iBookmark *d, const char *tag) { | |||
60 | 62 | ||
61 | void addTag_Bookmark(iBookmark *d, const char *tag) { | 63 | void addTag_Bookmark(iBookmark *d, const char *tag) { |
62 | if (!isEmpty_String(&d->tags)) { | 64 | if (!isEmpty_String(&d->tags)) { |
63 | appendChar_String(&d->tags, ' '); | 65 | appendCStr_String(&d->tags, " "); |
64 | } | 66 | } |
65 | appendCStr_String(&d->tags, tag); | 67 | appendCStr_String(&d->tags, tag); |
66 | } | 68 | } |
@@ -72,6 +74,93 @@ void removeTag_Bookmark(iBookmark *d, const char *tag) { | |||
72 | trim_String(&d->tags); | 74 | trim_String(&d->tags); |
73 | } | 75 | } |
74 | } | 76 | } |
77 | #endif | ||
78 | |||
79 | static struct { | ||
80 | uint32_t bit; | ||
81 | const char *tag; | ||
82 | iRegExp * pattern; | ||
83 | iRegExp * oldPattern; | ||
84 | } | ||
85 | specialTags_[] = { | ||
86 | { homepage_BookmarkFlag, ".homepage" }, | ||
87 | { remoteSource_BookmarkFlag, ".remotesource" }, | ||
88 | { linkSplit_BookmarkFlag, ".linksplit" }, | ||
89 | { userIcon_BookmarkFlag, ".usericon" }, | ||
90 | { subscribed_BookmarkFlag, ".subscribed" }, | ||
91 | { headings_BookmarkFlag, ".headings" }, | ||
92 | { ignoreWeb_BookmarkFlag, ".ignoreweb" }, | ||
93 | /* `remote_BookmarkFlag` not included because it's runtime only */ | ||
94 | }; | ||
95 | |||
96 | static void updatePatterns_(size_t index) { | ||
97 | if (!specialTags_[index].pattern) { | ||
98 | specialTags_[index].pattern = new_RegExp(format_CStr("(?<!\\w)\\%s\\b(?!\\w)", | ||
99 | specialTags_[index].tag), | ||
100 | caseSensitive_RegExpOption); /* never released */ | ||
101 | } | ||
102 | if (!specialTags_[index].oldPattern) { | ||
103 | /* TODO: Get rid of these when compatibility with v1.9 or older is not important. */ | ||
104 | specialTags_[index].oldPattern = | ||
105 | new_RegExp(format_CStr("\\b%s\\b", specialTags_[index].tag + 1), /* dotless */ | ||
106 | caseSensitive_RegExpOption); /* never released */ | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static void normalizeSpacesInTags_(iString *tags) { | ||
111 | iBool wasSpace = iFalse; | ||
112 | iString out; | ||
113 | init_String(&out); | ||
114 | for (const char *ch = constBegin_String(tags); ch != constEnd_String(tags); ch++) { | ||
115 | if (*ch == ' ') { | ||
116 | if (!wasSpace) { | ||
117 | wasSpace = iTrue; | ||
118 | } | ||
119 | else { | ||
120 | continue; | ||
121 | } | ||
122 | } | ||
123 | else { | ||
124 | wasSpace = iFalse; | ||
125 | } | ||
126 | appendData_Block(&out.chars, ch, 1); | ||
127 | } | ||
128 | trim_String(&out); | ||
129 | set_String(tags, &out); | ||
130 | deinit_String(&out); | ||
131 | } | ||
132 | |||
133 | static void unpackDotTags_Bookmark_(iBookmark *d) { | ||
134 | iZap(d->flags); | ||
135 | iForIndices(i, specialTags_) { | ||
136 | updatePatterns_(i); | ||
137 | iRegExpMatch m; | ||
138 | init_RegExpMatch(&m); | ||
139 | iBool isSet = matchString_RegExp(specialTags_[i].pattern, &d->tags, &m); | ||
140 | if (!isSet) { | ||
141 | init_RegExpMatch(&m); | ||
142 | isSet = matchString_RegExp(specialTags_[i].oldPattern, &d->tags, &m); | ||
143 | } | ||
144 | iChangeFlags(d->flags, specialTags_[i].bit, isSet); | ||
145 | if (isSet) { | ||
146 | remove_Block(&d->tags.chars, m.range.start, size_Range(&m.range)); | ||
147 | } | ||
148 | } | ||
149 | normalizeSpacesInTags_(&d->tags); | ||
150 | } | ||
151 | |||
152 | static iString *packedDotTags_Bookmark_(const iBookmark *d) { | ||
153 | iString *withDot = copy_String(&d->tags); | ||
154 | iForIndices(i, specialTags_) { | ||
155 | if (d->flags & specialTags_[i].bit) { | ||
156 | if (!isEmpty_String(withDot)) { | ||
157 | appendCStr_String(withDot, " "); | ||
158 | } | ||
159 | appendCStr_String(withDot, specialTags_[i].tag); | ||
160 | } | ||
161 | } | ||
162 | return withDot; | ||
163 | } | ||
75 | 164 | ||
76 | iDefineTypeConstruction(Bookmark) | 165 | iDefineTypeConstruction(Bookmark) |
77 | 166 | ||
@@ -176,6 +265,7 @@ static void loadOldFormat_Bookmarks(iBookmarks *d, const char *dirPath) { | |||
176 | setRange_String(&bm->title, line); | 265 | setRange_String(&bm->title, line); |
177 | nextSplit_Rangecc(src, "\n", &line); | 266 | nextSplit_Rangecc(src, "\n", &line); |
178 | setRange_String(&bm->tags, line); | 267 | setRange_String(&bm->tags, line); |
268 | unpackDotTags_Bookmark_(bm); | ||
179 | insert_Bookmarks_(d, bm); | 269 | insert_Bookmarks_(d, bm); |
180 | } | 270 | } |
181 | } | 271 | } |
@@ -220,6 +310,10 @@ static void handleKeyValue_BookmarkLoader_(void *context, const iString *table, | |||
220 | } | 310 | } |
221 | else if (!cmp_String(key, "tags") && tv->type == string_TomlType) { | 311 | else if (!cmp_String(key, "tags") && tv->type == string_TomlType) { |
222 | set_String(&bm->tags, tv->value.string); | 312 | set_String(&bm->tags, tv->value.string); |
313 | if (strstr(cstr_String(&bm->tags), "subscribed")) { | ||
314 | printf("a\n"); | ||
315 | } | ||
316 | unpackDotTags_Bookmark_(bm); | ||
223 | } | 317 | } |
224 | else if (!cmp_String(key, "icon") && tv->type == int64_TomlType) { | 318 | else if (!cmp_String(key, "icon") && tv->type == int64_TomlType) { |
225 | bm->icon = (iChar) tv->value.int64; | 319 | bm->icon = (iChar) tv->value.int64; |
@@ -292,7 +386,6 @@ void load_Bookmarks(iBookmarks *d, const char *dirPath) { | |||
292 | 386 | ||
293 | void save_Bookmarks(const iBookmarks *d, const char *dirPath) { | 387 | void save_Bookmarks(const iBookmarks *d, const char *dirPath) { |
294 | lock_Mutex(d->mtx); | 388 | lock_Mutex(d->mtx); |
295 | iRegExp *remotePattern = iClob(new_RegExp("\\bremote\\b", caseSensitive_RegExpOption)); | ||
296 | iFile *f = newCStr_File(concatPath_CStr(dirPath, fileName_Bookmarks_)); | 389 | iFile *f = newCStr_File(concatPath_CStr(dirPath, fileName_Bookmarks_)); |
297 | if (open_File(f, writeOnly_FileMode | text_FileMode)) { | 390 | if (open_File(f, writeOnly_FileMode | text_FileMode)) { |
298 | iString *str = collectNew_String(); | 391 | iString *str = collectNew_String(); |
@@ -300,13 +393,12 @@ void save_Bookmarks(const iBookmarks *d, const char *dirPath) { | |||
300 | writeData_File(f, cstr_String(str), size_String(str)); | 393 | writeData_File(f, cstr_String(str), size_String(str)); |
301 | iConstForEach(Hash, i, &d->bookmarks) { | 394 | iConstForEach(Hash, i, &d->bookmarks) { |
302 | const iBookmark *bm = (const iBookmark *) i.value; | 395 | const iBookmark *bm = (const iBookmark *) i.value; |
303 | iRegExpMatch m; | 396 | if (bm->flags & remote_BookmarkFlag) { |
304 | init_RegExpMatch(&m); | ||
305 | if (matchString_RegExp(remotePattern, &bm->tags, &m)) { | ||
306 | /* Remote bookmarks are not saved. */ | 397 | /* Remote bookmarks are not saved. */ |
307 | continue; | 398 | continue; |
308 | } | 399 | } |
309 | iBeginCollect(); | 400 | iBeginCollect(); |
401 | const iString *packedTags = collect_String(packedDotTags_Bookmark_(bm)); | ||
310 | format_String(str, | 402 | format_String(str, |
311 | "[%d]\n" | 403 | "[%d]\n" |
312 | "url = \"%s\"\n" | 404 | "url = \"%s\"\n" |
@@ -317,7 +409,7 @@ void save_Bookmarks(const iBookmarks *d, const char *dirPath) { | |||
317 | id_Bookmark(bm), | 409 | id_Bookmark(bm), |
318 | cstrCollect_String(quote_String(&bm->url, iFalse)), | 410 | cstrCollect_String(quote_String(&bm->url, iFalse)), |
319 | cstrCollect_String(quote_String(&bm->title, iFalse)), | 411 | cstrCollect_String(quote_String(&bm->title, iFalse)), |
320 | cstrCollect_String(quote_String(&bm->tags, iFalse)), | 412 | cstrCollect_String(quote_String(packedTags, iFalse)), |
321 | bm->icon, | 413 | bm->icon, |
322 | seconds_Time(&bm->when), | 414 | seconds_Time(&bm->when), |
323 | cstrCollect_String(format_Time(&bm->when, "%Y-%m-%d"))); | 415 | cstrCollect_String(format_Time(&bm->when, "%Y-%m-%d"))); |
@@ -397,7 +489,7 @@ iBool updateBookmarkIcon_Bookmarks(iBookmarks *d, const iString *url, iChar icon | |||
397 | const uint32_t id = findUrl_Bookmarks(d, url); | 489 | const uint32_t id = findUrl_Bookmarks(d, url); |
398 | if (id) { | 490 | if (id) { |
399 | iBookmark *bm = get_Bookmarks(d, id); | 491 | iBookmark *bm = get_Bookmarks(d, id); |
400 | if (!hasTag_Bookmark(bm, remote_BookmarkTag) && !hasTag_Bookmark(bm, userIcon_BookmarkTag)) { | 492 | if (~bm->flags & remote_BookmarkFlag && ~bm->flags & userIcon_BookmarkFlag) { |
401 | if (icon != bm->icon) { | 493 | if (icon != bm->icon) { |
402 | bm->icon = icon; | 494 | bm->icon = icon; |
403 | changed = iTrue; | 495 | changed = iTrue; |
@@ -422,19 +514,13 @@ iChar siteIcon_Bookmarks(const iBookmarks *d, const iString *url) { | |||
422 | if (isEmpty_String(url)) { | 514 | if (isEmpty_String(url)) { |
423 | return 0; | 515 | return 0; |
424 | } | 516 | } |
425 | static iRegExp *tagPattern_; | ||
426 | if (!tagPattern_) { | ||
427 | tagPattern_ = new_RegExp("\\b" userIcon_BookmarkTag "\\b", caseSensitive_RegExpOption); | ||
428 | } | ||
429 | const iRangecc urlRoot = urlRoot_String(url); | 517 | const iRangecc urlRoot = urlRoot_String(url); |
430 | size_t matchingSize = iInvalidSize; /* we'll pick the shortest matching */ | 518 | size_t matchingSize = iInvalidSize; /* we'll pick the shortest matching */ |
431 | iChar icon = 0; | 519 | iChar icon = 0; |
432 | lock_Mutex(d->mtx); | 520 | lock_Mutex(d->mtx); |
433 | iConstForEach(Hash, i, &d->bookmarks) { | 521 | iConstForEach(Hash, i, &d->bookmarks) { |
434 | const iBookmark *bm = (const iBookmark *) i.value; | 522 | const iBookmark *bm = (const iBookmark *) i.value; |
435 | iRegExpMatch m; | 523 | if (bm->icon && bm->flags & userIcon_BookmarkFlag) { |
436 | init_RegExpMatch(&m); | ||
437 | if (bm->icon && matchString_RegExp(tagPattern_, &bm->tags, &m)) { | ||
438 | const iRangecc bmRoot = urlRoot_String(&bm->url); | 524 | const iRangecc bmRoot = urlRoot_String(&bm->url); |
439 | if (equalRangeCase_Rangecc(urlRoot, bmRoot)) { | 525 | if (equalRangeCase_Rangecc(urlRoot, bmRoot)) { |
440 | const size_t n = size_String(&bm->url); | 526 | const size_t n = size_String(&bm->url); |
@@ -467,10 +553,15 @@ void reorder_Bookmarks(iBookmarks *d, uint32_t id, int newOrder) { | |||
467 | unlock_Mutex(d->mtx); | 553 | unlock_Mutex(d->mtx); |
468 | } | 554 | } |
469 | 555 | ||
470 | iBool filterTagsRegExp_Bookmarks(void *regExp, const iBookmark *bm) { | 556 | //iBool filterTagsRegExp_Bookmarks(void *regExp, const iBookmark *bm) { |
471 | iRegExpMatch m; | 557 | // iRegExpMatch m; |
472 | init_RegExpMatch(&m); | 558 | // init_RegExpMatch(&m); |
473 | return matchString_RegExp(regExp, &bm->tags, &m); | 559 | // return matchString_RegExp(regExp, &bm->tags, &m); |
560 | //} | ||
561 | |||
562 | iBool filterHomepage_Bookmark(void *d, const iBookmark *bm) { | ||
563 | iUnused(d); | ||
564 | return (bm->flags & homepage_BookmarkFlag) != 0; | ||
474 | } | 565 | } |
475 | 566 | ||
476 | static iBool matchUrl_(void *url, const iBookmark *bm) { | 567 | static iBool matchUrl_(void *url, const iBookmark *bm) { |
@@ -618,7 +709,7 @@ const iString *bookmarkListPage_Bookmarks(const iBookmarks *d, enum iBookmarkLis | |||
618 | 709 | ||
619 | static iBool isRemoteSource_Bookmark_(void *context, const iBookmark *d) { | 710 | static iBool isRemoteSource_Bookmark_(void *context, const iBookmark *d) { |
620 | iUnused(context); | 711 | iUnused(context); |
621 | return hasTag_Bookmark(d, remoteSource_BookmarkTag); | 712 | return (d->flags & remoteSource_BookmarkFlag) != 0; |
622 | } | 713 | } |
623 | 714 | ||
624 | void remoteRequestFinished_Bookmarks_(iBookmarks *d, iGmRequest *req) { | 715 | void remoteRequestFinished_Bookmarks_(iBookmarks *d, iGmRequest *req) { |
@@ -642,7 +733,6 @@ void requestFinished_Bookmarks(iBookmarks *d, iGmRequest *req) { | |||
642 | initCurrent_Time(&now); | 733 | initCurrent_Time(&now); |
643 | iRegExp *linkPattern = new_RegExp("^=>\\s*([^\\s]+)(\\s+(.*))?", 0); | 734 | iRegExp *linkPattern = new_RegExp("^=>\\s*([^\\s]+)(\\s+(.*))?", 0); |
644 | iString src; | 735 | iString src; |
645 | const iString *remoteTag = collectNewCStr_String("remote"); | ||
646 | initBlock_String(&src, body_GmRequest(req)); | 736 | initBlock_String(&src, body_GmRequest(req)); |
647 | iRangecc srcLine = iNullRange; | 737 | iRangecc srcLine = iNullRange; |
648 | while (nextSplit_Rangecc(range_String(&src), "\n", &srcLine)) { | 738 | while (nextSplit_Rangecc(range_String(&src), "\n", &srcLine)) { |
@@ -660,8 +750,9 @@ void requestFinished_Bookmarks(iBookmarks *d, iGmRequest *req) { | |||
660 | if (isEmpty_String(titleStr)) { | 750 | if (isEmpty_String(titleStr)) { |
661 | setRange_String(titleStr, urlHost_String(urlStr)); | 751 | setRange_String(titleStr, urlHost_String(urlStr)); |
662 | } | 752 | } |
663 | const uint32_t bmId = add_Bookmarks(d, absUrl, titleStr, remoteTag, 0x2913); | 753 | const uint32_t bmId = add_Bookmarks(d, absUrl, titleStr, NULL, 0x2913); |
664 | iBookmark *bm = get_Bookmarks(d, bmId); | 754 | iBookmark *bm = get_Bookmarks(d, bmId); |
755 | bm->flags |= remote_BookmarkFlag; | ||
665 | bm->parentId = *(uint32_t *) userData_Object(req); | 756 | bm->parentId = *(uint32_t *) userData_Object(req); |
666 | delete_String(titleStr); | 757 | delete_String(titleStr); |
667 | } | 758 | } |
@@ -690,7 +781,7 @@ void fetchRemote_Bookmarks(iBookmarks *d) { | |||
690 | size_t numRemoved = 0; | 781 | size_t numRemoved = 0; |
691 | iForEach(Hash, i, &d->bookmarks) { | 782 | iForEach(Hash, i, &d->bookmarks) { |
692 | iBookmark *bm = (iBookmark *) i.value; | 783 | iBookmark *bm = (iBookmark *) i.value; |
693 | if (hasTag_Bookmark(bm, remote_BookmarkTag)) { | 784 | if (bm->flags & remote_BookmarkFlag) { |
694 | remove_HashIterator(&i); | 785 | remove_HashIterator(&i); |
695 | delete_Bookmark(bm); | 786 | delete_Bookmark(bm); |
696 | numRemoved++; | 787 | numRemoved++; |
diff --git a/src/bookmarks.h b/src/bookmarks.h index 6cb5c8a9..08afdd8b 100644 --- a/src/bookmarks.h +++ b/src/bookmarks.h | |||
@@ -31,27 +31,30 @@ iDeclareType(GmRequest) | |||
31 | 31 | ||
32 | iDeclareType(Bookmark) | 32 | iDeclareType(Bookmark) |
33 | iDeclareTypeConstruction(Bookmark) | 33 | iDeclareTypeConstruction(Bookmark) |
34 | 34 | ||
35 | /* TODO: Make the special internal tags a bitfield, separate from user's tags. */ | 35 | /* These values are not serialized as-is in bookmarks.ini. Instead, they are included in `tags` |
36 | 36 | with a dot prefix. This helps retain backwards and forwards compatibility. */ | |
37 | #define headings_BookmarkTag "headings" | 37 | enum iBookmarkFlags { |
38 | #define ignoreWeb_BookmarkTag "ignoreweb" | 38 | homepage_BookmarkFlag = iBit(1), |
39 | #define homepage_BookmarkTag "homepage" | 39 | remoteSource_BookmarkFlag = iBit(2), |
40 | #define linkSplit_BookmarkTag "linksplit" | 40 | linkSplit_BookmarkFlag = iBit(3), |
41 | #define remote_BookmarkTag "remote" | 41 | userIcon_BookmarkFlag = iBit(4), |
42 | #define remoteSource_BookmarkTag "remotesource" | 42 | subscribed_BookmarkFlag = iBit(17), |
43 | #define subscribed_BookmarkTag "subscribed" | 43 | headings_BookmarkFlag = iBit(18), |
44 | #define userIcon_BookmarkTag "usericon" | 44 | ignoreWeb_BookmarkFlag = iBit(19), |
45 | remote_BookmarkFlag = iBit(31), | ||
46 | }; | ||
45 | 47 | ||
46 | struct Impl_Bookmark { | 48 | struct Impl_Bookmark { |
47 | iHashNode node; | 49 | iHashNode node; |
48 | iString url; | 50 | iString url; |
49 | iString title; | 51 | iString title; |
50 | iString tags; | 52 | iString tags; |
51 | iChar icon; | 53 | uint32_t flags; |
52 | iTime when; | 54 | iChar icon; |
53 | uint32_t parentId; /* remote source or folder */ | 55 | iTime when; |
54 | int order; /* sort order */ | 56 | uint32_t parentId; /* remote source or folder */ |
57 | int order; /* sort order */ | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | iLocalDef uint32_t id_Bookmark (const iBookmark *d) { return d->node.key; } | 60 | iLocalDef uint32_t id_Bookmark (const iBookmark *d) { return d->node.key; } |
@@ -59,23 +62,24 @@ iLocalDef iBool isFolder_Bookmark (const iBookmark *d) { return isEmpty_St | |||
59 | 62 | ||
60 | iBool hasParent_Bookmark (const iBookmark *, uint32_t parentId); | 63 | iBool hasParent_Bookmark (const iBookmark *, uint32_t parentId); |
61 | int depth_Bookmark (const iBookmark *); | 64 | int depth_Bookmark (const iBookmark *); |
62 | iBool hasTag_Bookmark (const iBookmark *, const char *tag); | 65 | |
63 | void addTag_Bookmark (iBookmark *, const char *tag); | 66 | //iBool hasTag_Bookmark (const iBookmark *, const char *tag); |
64 | void removeTag_Bookmark (iBookmark *, const char *tag); | 67 | //void addTag_Bookmark (iBookmark *, const char *tag); |
65 | 68 | //void removeTag_Bookmark (iBookmark *, const char *tag); | |
66 | iLocalDef void addTagIfMissing_Bookmark(iBookmark *d, const char *tag) { | 69 | |
67 | if (!hasTag_Bookmark(d, tag)) { | 70 | //iLocalDef void addTagIfMissing_Bookmark(iBookmark *d, const char *tag) { |
68 | addTag_Bookmark(d, tag); | 71 | // if (!hasTag_Bookmark(d, tag)) { |
69 | } | 72 | // addTag_Bookmark(d, tag); |
70 | } | 73 | // } |
71 | iLocalDef void addOrRemoveTag_Bookmark(iBookmark *d, const char *tag, iBool add) { | 74 | //} |
72 | if (add) { | 75 | //iLocalDef void addOrRemoveTag_Bookmark(iBookmark *d, const char *tag, iBool add) { |
73 | addTagIfMissing_Bookmark(d, tag); | 76 | // if (add) { |
74 | } | 77 | // addTagIfMissing_Bookmark(d, tag); |
75 | else { | 78 | // } |
76 | removeTag_Bookmark(d, tag); | 79 | // else { |
77 | } | 80 | // removeTag_Bookmark(d, tag); |
78 | } | 81 | // } |
82 | //} | ||
79 | 83 | ||
80 | int cmpTitleAscending_Bookmark (const iBookmark **, const iBookmark **); | 84 | int cmpTitleAscending_Bookmark (const iBookmark **, const iBookmark **); |
81 | int cmpTree_Bookmark (const iBookmark **, const iBookmark **); | 85 | int cmpTree_Bookmark (const iBookmark **, const iBookmark **); |
@@ -109,7 +113,8 @@ iChar siteIcon_Bookmarks (const iBookmarks *, const iString *url) | |||
109 | uint32_t findUrl_Bookmarks (const iBookmarks *, const iString *url); /* O(n) */ | 113 | uint32_t findUrl_Bookmarks (const iBookmarks *, const iString *url); /* O(n) */ |
110 | uint32_t recentFolder_Bookmarks (const iBookmarks *); | 114 | uint32_t recentFolder_Bookmarks (const iBookmarks *); |
111 | 115 | ||
112 | iBool filterTagsRegExp_Bookmarks (void *regExp, const iBookmark *); | 116 | //iBool filterTagsRegExp_Bookmarks (void *regExp, const iBookmark *); |
117 | iBool filterHomepage_Bookmark (void *, const iBookmark *); | ||
113 | 118 | ||
114 | /** | 119 | /** |
115 | * Lists all or a subset of the bookmarks in a sorted array of Bookmark pointers. | 120 | * Lists all or a subset of the bookmarks in a sorted array of Bookmark pointers. |
diff --git a/src/feeds.c b/src/feeds.c index 26b3d6db..b7ce739b 100644 --- a/src/feeds.c +++ b/src/feeds.c | |||
@@ -97,8 +97,8 @@ static void init_FeedJob(iFeedJob *d, const iBookmark *bookmark) { | |||
97 | init_PtrArray(&d->results); | 97 | init_PtrArray(&d->results); |
98 | iZap(d->startTime); | 98 | iZap(d->startTime); |
99 | d->isFirstUpdate = iFalse; | 99 | d->isFirstUpdate = iFalse; |
100 | d->checkHeadings = hasTag_Bookmark(bookmark, headings_BookmarkTag); | 100 | d->checkHeadings = (bookmark->flags & headings_BookmarkFlag) != 0; |
101 | d->ignoreWeb = hasTag_Bookmark(bookmark, ignoreWeb_BookmarkTag); | 101 | d->ignoreWeb = (bookmark->flags & ignoreWeb_BookmarkFlag) != 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void deinit_FeedJob(iFeedJob *d) { | 104 | static void deinit_FeedJob(iFeedJob *d) { |
@@ -146,13 +146,7 @@ static void submit_FeedJob_(iFeedJob *d) { | |||
146 | 146 | ||
147 | static iBool isSubscribed_(void *context, const iBookmark *bm) { | 147 | static iBool isSubscribed_(void *context, const iBookmark *bm) { |
148 | iUnused(context); | 148 | iUnused(context); |
149 | static iRegExp *pattern_ = NULL; | 149 | return (bm->flags & subscribed_BookmarkFlag) != 0; |
150 | if (!pattern_) { | ||
151 | pattern_ = new_RegExp("\\bsubscribed\\b", caseSensitive_RegExpOption); | ||
152 | } | ||
153 | iRegExpMatch m; | ||
154 | init_RegExpMatch(&m); | ||
155 | return matchString_RegExp(pattern_, &bm->tags, &m); | ||
156 | } | 150 | } |
157 | 151 | ||
158 | static const iPtrArray *listSubscriptions_(void) { | 152 | static const iPtrArray *listSubscriptions_(void) { |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index aac77572..39dd3aab 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -1108,7 +1108,7 @@ static void documentWasChanged_DocumentWidget_(iDocumentWidget *d) { | |||
1108 | const uint16_t bmid = findUrl_Bookmarks(bookmarks_App(), d->mod.url); | 1108 | const uint16_t bmid = findUrl_Bookmarks(bookmarks_App(), d->mod.url); |
1109 | if (bmid) { | 1109 | if (bmid) { |
1110 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), bmid); | 1110 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), bmid); |
1111 | if (hasTag_Bookmark(bm, linkSplit_BookmarkTag)) { | 1111 | if (bm->flags & linkSplit_BookmarkFlag) { |
1112 | d->flags |= otherRootByDefault_DocumentWidgetFlag; | 1112 | d->flags |= otherRootByDefault_DocumentWidgetFlag; |
1113 | } | 1113 | } |
1114 | } | 1114 | } |
@@ -3383,7 +3383,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
3383 | linkUrl_GmDocument(d->doc, run->linkId))) != 0) { | 3383 | linkUrl_GmDocument(d->doc, run->linkId))) != 0) { |
3384 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), bmid); | 3384 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), bmid); |
3385 | /* We can import local copies of remote bookmarks. */ | 3385 | /* We can import local copies of remote bookmarks. */ |
3386 | if (!hasTag_Bookmark(bm, remote_BookmarkTag)) { | 3386 | if (~bm->flags & remote_BookmarkFlag) { |
3387 | remove_PtrArrayIterator(&i); | 3387 | remove_PtrArrayIterator(&i); |
3388 | } | 3388 | } |
3389 | } | 3389 | } |
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index 550fccde..b6aa06b1 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -407,11 +407,6 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
407 | break; | 407 | break; |
408 | } | 408 | } |
409 | case bookmarks_SidebarMode: { | 409 | case bookmarks_SidebarMode: { |
410 | iRegExp *homeTag = iClob(new_RegExp("\\b" homepage_BookmarkTag "\\b", caseSensitive_RegExpOption)); | ||
411 | iRegExp *subTag = iClob(new_RegExp("\\b" subscribed_BookmarkTag "\\b", caseSensitive_RegExpOption)); | ||
412 | iRegExp *remoteSourceTag = iClob(new_RegExp("\\b" remoteSource_BookmarkTag "\\b", caseSensitive_RegExpOption)); | ||
413 | iRegExp *remoteTag = iClob(new_RegExp("\\b" remote_BookmarkTag "\\b", caseSensitive_RegExpOption)); | ||
414 | iRegExp *linkSplitTag = iClob(new_RegExp("\\b" linkSplit_BookmarkTag "\\b", caseSensitive_RegExpOption)); | ||
415 | iConstForEach(PtrArray, i, list_Bookmarks(bookmarks_App(), cmpTree_Bookmark, NULL, NULL)) { | 410 | iConstForEach(PtrArray, i, list_Bookmarks(bookmarks_App(), cmpTree_Bookmark, NULL, NULL)) { |
416 | const iBookmark *bm = i.ptr; | 411 | const iBookmark *bm = i.ptr; |
417 | if (isBookmarkFolded_SidebarWidget_(d, bm)) { | 412 | if (isBookmarkFolded_SidebarWidget_(d, bm)) { |
@@ -430,27 +425,21 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
430 | } | 425 | } |
431 | set_String(&item->url, &bm->url); | 426 | set_String(&item->url, &bm->url); |
432 | set_String(&item->label, &bm->title); | 427 | set_String(&item->label, &bm->title); |
433 | /* Icons for special tags. */ { | 428 | /* Icons for special behaviors. */ { |
434 | iRegExpMatch m; | 429 | if (bm->flags & subscribed_BookmarkFlag) { |
435 | init_RegExpMatch(&m); | ||
436 | if (matchString_RegExp(subTag, &bm->tags, &m)) { | ||
437 | appendChar_String(&item->meta, 0x2605); | 430 | appendChar_String(&item->meta, 0x2605); |
438 | } | 431 | } |
439 | init_RegExpMatch(&m); | 432 | if (bm->flags & homepage_BookmarkFlag) { |
440 | if (matchString_RegExp(homeTag, &bm->tags, &m)) { | ||
441 | appendChar_String(&item->meta, 0x1f3e0); | 433 | appendChar_String(&item->meta, 0x1f3e0); |
442 | } | 434 | } |
443 | init_RegExpMatch(&m); | 435 | if (bm->flags & remote_BookmarkFlag) { |
444 | if (matchString_RegExp(remoteTag, &bm->tags, &m)) { | ||
445 | item->listItem.isDraggable = iFalse; | 436 | item->listItem.isDraggable = iFalse; |
446 | } | 437 | } |
447 | init_RegExpMatch(&m); | 438 | if (bm->flags & remoteSource_BookmarkFlag) { |
448 | if (matchString_RegExp(remoteSourceTag, &bm->tags, &m)) { | ||
449 | appendChar_String(&item->meta, 0x2913); | 439 | appendChar_String(&item->meta, 0x2913); |
450 | item->isBold = iTrue; | 440 | item->isBold = iTrue; |
451 | } | 441 | } |
452 | init_RegExpMatch(&m); | 442 | if (bm->flags & linkSplit_BookmarkFlag) { |
453 | if (matchString_RegExp(linkSplitTag, &bm->tags, &m)) { | ||
454 | appendChar_String(&item->meta, 0x25e7); | 443 | appendChar_String(&item->meta, 0x25e7); |
455 | } | 444 | } |
456 | } | 445 | } |
@@ -1042,19 +1031,16 @@ iBool handleBookmarkEditorCommands_SidebarWidget_(iWidget *editor, const char *c | |||
1042 | set_String(&bm->url, url); | 1031 | set_String(&bm->url, url); |
1043 | set_String(&bm->tags, tags); | 1032 | set_String(&bm->tags, tags); |
1044 | if (isEmpty_String(icon)) { | 1033 | if (isEmpty_String(icon)) { |
1045 | removeTag_Bookmark(bm, userIcon_BookmarkTag); | 1034 | bm->flags &= ~userIcon_BookmarkFlag; |
1046 | bm->icon = 0; | 1035 | bm->icon = 0; |
1047 | } | 1036 | } |
1048 | else { | 1037 | else { |
1049 | addTagIfMissing_Bookmark(bm, userIcon_BookmarkTag); | 1038 | bm->flags |= userIcon_BookmarkFlag; |
1050 | bm->icon = first_String(icon); | 1039 | bm->icon = first_String(icon); |
1051 | } | 1040 | } |
1052 | addOrRemoveTag_Bookmark(bm, homepage_BookmarkTag, | 1041 | iChangeFlags(bm->flags, homepage_BookmarkFlag, isSelected_Widget(findChild_Widget(editor, "bmed.tag.home"))); |
1053 | isSelected_Widget(findChild_Widget(editor, "bmed.tag.home"))); | 1042 | iChangeFlags(bm->flags, remoteSource_BookmarkFlag, isSelected_Widget(findChild_Widget(editor, "bmed.tag.remote"))); |
1054 | addOrRemoveTag_Bookmark(bm, remoteSource_BookmarkTag, | 1043 | iChangeFlags(bm->flags, linkSplit_BookmarkFlag, isSelected_Widget(findChild_Widget(editor, "bmed.tag.linksplit"))); |
1055 | isSelected_Widget(findChild_Widget(editor, "bmed.tag.remote"))); | ||
1056 | addOrRemoveTag_Bookmark(bm, linkSplit_BookmarkTag, | ||
1057 | isSelected_Widget(findChild_Widget(editor, "bmed.tag.linksplit"))); | ||
1058 | } | 1044 | } |
1059 | const iBookmark *folder = userData_Object(findChild_Widget(editor, "bmed.folder")); | 1045 | const iBookmark *folder = userData_Object(findChild_Widget(editor, "bmed.folder")); |
1060 | if (!folder || !hasParent_Bookmark(folder, id_Bookmark(bm))) { | 1046 | if (!folder || !hasParent_Bookmark(folder, id_Bookmark(bm))) { |
@@ -1152,7 +1138,7 @@ static void bookmarkMoved_SidebarWidget_(iSidebarWidget *d, size_t index, size_t | |||
1152 | : dstIndex); | 1138 | : dstIndex); |
1153 | if (isLast && isBefore) isBefore = iFalse; | 1139 | if (isLast && isBefore) isBefore = iFalse; |
1154 | const iBookmark *dst = get_Bookmarks(bookmarks_App(), dstItem->id); | 1140 | const iBookmark *dst = get_Bookmarks(bookmarks_App(), dstItem->id); |
1155 | if (hasParent_Bookmark(dst, movingItem->id) || hasTag_Bookmark(dst, remote_BookmarkTag)) { | 1141 | if (hasParent_Bookmark(dst, movingItem->id) || dst->flags & remote_BookmarkFlag) { |
1156 | /* Can't move a folder inside itself, and remote bookmarks cannot be reordered. */ | 1142 | /* Can't move a folder inside itself, and remote bookmarks cannot be reordered. */ |
1157 | return; | 1143 | return; |
1158 | } | 1144 | } |
@@ -1176,7 +1162,8 @@ static void bookmarkMovedOntoFolder_SidebarWidget_(iSidebarWidget *d, size_t ind | |||
1176 | static size_t numBookmarks_(const iPtrArray *bmList) { | 1162 | static size_t numBookmarks_(const iPtrArray *bmList) { |
1177 | size_t num = 0; | 1163 | size_t num = 0; |
1178 | iConstForEach(PtrArray, i, bmList) { | 1164 | iConstForEach(PtrArray, i, bmList) { |
1179 | if (!isFolder_Bookmark(i.ptr) && !hasTag_Bookmark(i.ptr, remote_BookmarkTag)) { | 1165 | const iBookmark *bm = i.ptr; |
1166 | if (!isFolder_Bookmark(bm) && ~bm->flags & remote_BookmarkFlag) { | ||
1180 | num++; | 1167 | num++; |
1181 | } | 1168 | } |
1182 | } | 1169 | } |
@@ -1349,13 +1336,13 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1349 | if (!isFolder_Bookmark(bm)) { | 1336 | if (!isFolder_Bookmark(bm)) { |
1350 | setText_InputWidget(urlInput, &bm->url); | 1337 | setText_InputWidget(urlInput, &bm->url); |
1351 | setText_InputWidget(tagsInput, &bm->tags); | 1338 | setText_InputWidget(tagsInput, &bm->tags); |
1352 | if (hasTag_Bookmark(bm, userIcon_BookmarkTag)) { | 1339 | if (bm->flags & userIcon_BookmarkFlag) { |
1353 | setText_InputWidget(iconInput, | 1340 | setText_InputWidget(iconInput, |
1354 | collect_String(newUnicodeN_String(&bm->icon, 1))); | 1341 | collect_String(newUnicodeN_String(&bm->icon, 1))); |
1355 | } | 1342 | } |
1356 | setToggle_Widget(homeTag, hasTag_Bookmark(bm, homepage_BookmarkTag)); | 1343 | setToggle_Widget(homeTag, bm->flags & homepage_BookmarkFlag); |
1357 | setToggle_Widget(remoteSourceTag, hasTag_Bookmark(bm, remoteSource_BookmarkTag)); | 1344 | setToggle_Widget(remoteSourceTag, bm->flags & remoteSource_BookmarkFlag); |
1358 | setToggle_Widget(linkSplitTag, hasTag_Bookmark(bm, linkSplit_BookmarkTag)); | 1345 | setToggle_Widget(linkSplitTag, bm->flags & linkSplit_BookmarkFlag); |
1359 | } | 1346 | } |
1360 | else { | 1347 | else { |
1361 | setFlags_Widget(findChild_Widget(dlg, "bmed.special"), | 1348 | setFlags_Widget(findChild_Widget(dlg, "bmed.special"), |
@@ -1376,7 +1363,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1376 | const iSidebarItem *item = d->contextItem; | 1363 | const iSidebarItem *item = d->contextItem; |
1377 | if (d->mode == bookmarks_SidebarMode && item) { | 1364 | if (d->mode == bookmarks_SidebarMode && item) { |
1378 | iBookmark *bm = get_Bookmarks(bookmarks_App(), item->id); | 1365 | iBookmark *bm = get_Bookmarks(bookmarks_App(), item->id); |
1379 | const iBool isRemote = hasTag_Bookmark(bm, remote_BookmarkTag); | 1366 | const iBool isRemote = (bm->flags & remote_BookmarkFlag) != 0; |
1380 | iChar icon = isRemote ? 0x1f588 : bm->icon; | 1367 | iChar icon = isRemote ? 0x1f588 : bm->icon; |
1381 | iWidget *dlg = makeBookmarkCreation_Widget(&bm->url, &bm->title, icon); | 1368 | iWidget *dlg = makeBookmarkCreation_Widget(&bm->url, &bm->title, icon); |
1382 | setId_Widget(dlg, format_CStr("bmed.%s", cstr_String(id_Widget(w)))); | 1369 | setId_Widget(dlg, format_CStr("bmed.%s", cstr_String(id_Widget(w)))); |
@@ -1390,17 +1377,16 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1390 | else if (isCommand_Widget(w, ev, "bookmark.tag")) { | 1377 | else if (isCommand_Widget(w, ev, "bookmark.tag")) { |
1391 | const iSidebarItem *item = d->contextItem; | 1378 | const iSidebarItem *item = d->contextItem; |
1392 | if (d->mode == bookmarks_SidebarMode && item) { | 1379 | if (d->mode == bookmarks_SidebarMode && item) { |
1393 | const char *tag = cstr_String(string_Command(cmd, "tag")); | 1380 | const iRangecc tag = range_Command(cmd, "tag"); |
1381 | const int flag = | ||
1382 | (equal_Rangecc(tag, "homepage") ? homepage_BookmarkFlag : 0) | | ||
1383 | (equal_Rangecc(tag, "subscribed") ? subscribed_BookmarkFlag : 0) | | ||
1384 | (equal_Rangecc(tag, "remotesource") ? remoteSource_BookmarkFlag : 0); | ||
1394 | iBookmark *bm = get_Bookmarks(bookmarks_App(), item->id); | 1385 | iBookmark *bm = get_Bookmarks(bookmarks_App(), item->id); |
1395 | if (hasTag_Bookmark(bm, tag)) { | 1386 | if (flag == subscribed_BookmarkFlag && (bm->flags & flag)) { |
1396 | removeTag_Bookmark(bm, tag); | 1387 | removeEntries_Feeds(item->id); /* get rid of unsubscribed entries */ |
1397 | if (!iCmpStr(tag, subscribed_BookmarkTag)) { | ||
1398 | removeEntries_Feeds(item->id); | ||
1399 | } | ||
1400 | } | ||
1401 | else { | ||
1402 | addTag_Bookmark(bm, tag); | ||
1403 | } | 1388 | } |
1389 | bm->flags ^= flag; | ||
1404 | postCommand_App("bookmarks.changed"); | 1390 | postCommand_App("bookmarks.changed"); |
1405 | } | 1391 | } |
1406 | return iTrue; | 1392 | return iTrue; |
@@ -1525,7 +1511,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1525 | } | 1511 | } |
1526 | if (isCommand_Widget(w, ev, "feed.entry.unsubscribe")) { | 1512 | if (isCommand_Widget(w, ev, "feed.entry.unsubscribe")) { |
1527 | if (arg_Command(cmd)) { | 1513 | if (arg_Command(cmd)) { |
1528 | removeTag_Bookmark(feedBookmark, subscribed_BookmarkTag); | 1514 | feedBookmark->flags &= ~subscribed_BookmarkFlag; |
1529 | removeEntries_Feeds(id_Bookmark(feedBookmark)); | 1515 | removeEntries_Feeds(id_Bookmark(feedBookmark)); |
1530 | updateItems_SidebarWidget_(d); | 1516 | updateItems_SidebarWidget_(d); |
1531 | } | 1517 | } |
@@ -1733,17 +1719,17 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1733 | if (bm) { | 1719 | if (bm) { |
1734 | setMenuItemLabel_Widget(d->menu, | 1720 | setMenuItemLabel_Widget(d->menu, |
1735 | "bookmark.tag tag:homepage", | 1721 | "bookmark.tag tag:homepage", |
1736 | hasTag_Bookmark(bm, homepage_BookmarkTag) | 1722 | bm->flags & homepage_BookmarkFlag |
1737 | ? home_Icon " ${bookmark.untag.home}" | 1723 | ? home_Icon " ${bookmark.untag.home}" |
1738 | : home_Icon " ${bookmark.tag.home}"); | 1724 | : home_Icon " ${bookmark.tag.home}"); |
1739 | setMenuItemLabel_Widget(d->menu, | 1725 | setMenuItemLabel_Widget(d->menu, |
1740 | "bookmark.tag tag:subscribed", | 1726 | "bookmark.tag tag:subscribed", |
1741 | hasTag_Bookmark(bm, subscribed_BookmarkTag) | 1727 | bm->flags & subscribed_BookmarkFlag |
1742 | ? star_Icon " ${bookmark.untag.sub}" | 1728 | ? star_Icon " ${bookmark.untag.sub}" |
1743 | : star_Icon " ${bookmark.tag.sub}"); | 1729 | : star_Icon " ${bookmark.tag.sub}"); |
1744 | setMenuItemLabel_Widget(d->menu, | 1730 | setMenuItemLabel_Widget(d->menu, |
1745 | "bookmark.tag tag:remotesource", | 1731 | "bookmark.tag tag:remotesource", |
1746 | hasTag_Bookmark(bm, remoteSource_BookmarkTag) | 1732 | bm->flags & remoteSource_BookmarkFlag |
1747 | ? downArrowBar_Icon " ${bookmark.untag.remote}" | 1733 | ? downArrowBar_Icon " ${bookmark.untag.remote}" |
1748 | : downArrowBar_Icon " ${bookmark.tag.remote}"); | 1734 | : downArrowBar_Icon " ${bookmark.tag.remote}"); |
1749 | } | 1735 | } |
@@ -1797,13 +1783,12 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
1797 | const iSidebarItem *hoverItem = hoverItem_ListWidget(d->list); | 1783 | const iSidebarItem *hoverItem = hoverItem_ListWidget(d->list); |
1798 | iAssert(hoverItem); | 1784 | iAssert(hoverItem); |
1799 | const iBookmark * bm = get_Bookmarks(bookmarks_App(), hoverItem->id); | 1785 | const iBookmark * bm = get_Bookmarks(bookmarks_App(), hoverItem->id); |
1800 | const iBool isRemote = hasTag_Bookmark(bm, remote_BookmarkTag); | 1786 | const iBool isRemote = (bm->flags & remote_BookmarkFlag) != 0; |
1801 | static const char *localOnlyCmds[] = { "bookmark.edit", | 1787 | static const char *localOnlyCmds[] = { "bookmark.edit", |
1802 | "bookmark.delete", | 1788 | "bookmark.delete", |
1803 | "bookmark.tag tag:" subscribed_BookmarkTag, | 1789 | "bookmark.tag tag:subscribed", |
1804 | "bookmark.tag tag:" homepage_BookmarkTag, | 1790 | "bookmark.tag tag:homepage", |
1805 | "bookmark.tag tag:" remoteSource_BookmarkTag, | 1791 | "bookmark.tag tag:remotesource" }; |
1806 | "bookmark.tag tag:" subscribed_BookmarkTag }; | ||
1807 | iForIndices(i, localOnlyCmds) { | 1792 | iForIndices(i, localOnlyCmds) { |
1808 | setFlags_Widget(as_Widget(findMenuItem_Widget(d->menu, localOnlyCmds[i])), | 1793 | setFlags_Widget(as_Widget(findMenuItem_Widget(d->menu, localOnlyCmds[i])), |
1809 | disabled_WidgetFlag, | 1794 | disabled_WidgetFlag, |
diff --git a/src/ui/util.c b/src/ui/util.c index baa05082..6f5eced3 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -2908,16 +2908,16 @@ static iBool handleBookmarkCreationCommands_SidebarWidget_(iWidget *editor, cons | |||
2908 | const uint32_t id = add_Bookmarks(bookmarks_App(), url, title, tags, first_String(icon)); | 2908 | const uint32_t id = add_Bookmarks(bookmarks_App(), url, title, tags, first_String(icon)); |
2909 | iBookmark * bm = get_Bookmarks(bookmarks_App(), id); | 2909 | iBookmark * bm = get_Bookmarks(bookmarks_App(), id); |
2910 | if (!isEmpty_String(icon)) { | 2910 | if (!isEmpty_String(icon)) { |
2911 | addTagIfMissing_Bookmark(bm, userIcon_BookmarkTag); | 2911 | bm->flags |= userIcon_BookmarkFlag; |
2912 | } | 2912 | } |
2913 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.home"))) { | 2913 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.home"))) { |
2914 | addTag_Bookmark(bm, homepage_BookmarkTag); | 2914 | bm->flags |= homepage_BookmarkFlag; |
2915 | } | 2915 | } |
2916 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.remote"))) { | 2916 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.remote"))) { |
2917 | addTag_Bookmark(bm, remoteSource_BookmarkTag); | 2917 | bm->flags |= remoteSource_BookmarkFlag; |
2918 | } | 2918 | } |
2919 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.linksplit"))) { | 2919 | if (isSelected_Widget(findChild_Widget(editor, "bmed.tag.linksplit"))) { |
2920 | addTag_Bookmark(bm, linkSplit_BookmarkTag); | 2920 | bm->flags |= linkSplit_BookmarkFlag; |
2921 | } | 2921 | } |
2922 | bm->parentId = folder ? id_Bookmark(folder) : 0; | 2922 | bm->parentId = folder ? id_Bookmark(folder) : 0; |
2923 | setRecentFolder_Bookmarks(bookmarks_App(), bm->parentId); | 2923 | setRecentFolder_Bookmarks(bookmarks_App(), bm->parentId); |
@@ -2983,9 +2983,9 @@ static iBool handleFeedSettingCommands_(iWidget *dlg, const char *cmd) { | |||
2983 | iBookmark *bm = get_Bookmarks(bookmarks_App(), id); | 2983 | iBookmark *bm = get_Bookmarks(bookmarks_App(), id); |
2984 | iAssert(bm); | 2984 | iAssert(bm); |
2985 | set_String(&bm->title, feedTitle); | 2985 | set_String(&bm->title, feedTitle); |
2986 | addOrRemoveTag_Bookmark(bm, subscribed_BookmarkTag, iTrue); | 2986 | bm->flags |= subscribed_BookmarkFlag; |
2987 | addOrRemoveTag_Bookmark(bm, headings_BookmarkTag, headings); | 2987 | iChangeFlags(bm->flags, headings_BookmarkFlag, headings); |
2988 | addOrRemoveTag_Bookmark(bm, ignoreWeb_BookmarkTag, ignoreWeb); | 2988 | iChangeFlags(bm->flags, ignoreWeb_BookmarkFlag, ignoreWeb); |
2989 | postCommand_App("bookmarks.changed"); | 2989 | postCommand_App("bookmarks.changed"); |
2990 | setupSheetTransition_Mobile(dlg, iFalse); | 2990 | setupSheetTransition_Mobile(dlg, iFalse); |
2991 | destroy_Widget(dlg); | 2991 | destroy_Widget(dlg); |
@@ -3048,13 +3048,13 @@ iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) { | |||
3048 | setText_InputWidget(findChild_Widget(dlg, "feedcfg.title"), | 3048 | setText_InputWidget(findChild_Widget(dlg, "feedcfg.title"), |
3049 | bm ? &bm->title : feedTitle_DocumentWidget(document_App())); | 3049 | bm ? &bm->title : feedTitle_DocumentWidget(document_App())); |
3050 | setFlags_Widget(findChild_Widget(dlg, | 3050 | setFlags_Widget(findChild_Widget(dlg, |
3051 | hasTag_Bookmark(bm, headings_BookmarkTag) | 3051 | bm->flags & headings_BookmarkFlag |
3052 | ? "feedcfg.type.headings" | 3052 | ? "feedcfg.type.headings" |
3053 | : "feedcfg.type.gemini"), | 3053 | : "feedcfg.type.gemini"), |
3054 | selected_WidgetFlag, | 3054 | selected_WidgetFlag, |
3055 | iTrue); | 3055 | iTrue); |
3056 | setToggle_Widget(findChild_Widget(dlg, "feedcfg.ignoreweb"), | 3056 | setToggle_Widget(findChild_Widget(dlg, "feedcfg.ignoreweb"), |
3057 | hasTag_Bookmark(bm, ignoreWeb_BookmarkTag)); | 3057 | bm->flags & ignoreWeb_BookmarkFlag); |
3058 | setCommandHandler_Widget(dlg, handleFeedSettingCommands_); | 3058 | setCommandHandler_Widget(dlg, handleFeedSettingCommands_); |
3059 | } | 3059 | } |
3060 | setupSheetTransition_Mobile(dlg, incoming_TransitionFlag); | 3060 | setupSheetTransition_Mobile(dlg, incoming_TransitionFlag); |