diff options
-rw-r--r-- | src/ui/sidebarwidget.c | 72 | ||||
-rw-r--r-- | src/visited.c | 5 | ||||
-rw-r--r-- | src/visited.h | 1 |
3 files changed, 51 insertions, 27 deletions
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index 9477353b..38ffd02d 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -94,7 +94,7 @@ struct Impl_SidebarWidget { | |||
94 | iWidget * resizer; | 94 | iWidget * resizer; |
95 | SDL_Cursor * resizeCursor; | 95 | SDL_Cursor * resizeCursor; |
96 | iWidget * menu; | 96 | iWidget * menu; |
97 | iSidebarItem * menuItem; /* list item accessed in the context menu */ | 97 | iSidebarItem * contextItem; /* list item accessed in the context menu */ |
98 | }; | 98 | }; |
99 | 99 | ||
100 | iDefineObjectConstruction(SidebarWidget) | 100 | iDefineObjectConstruction(SidebarWidget) |
@@ -140,8 +140,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
140 | if (equal_String(docUrl, &entry->url)) { | 140 | if (equal_String(docUrl, &entry->url)) { |
141 | item->listItem.isSelected = iTrue; /* currently being viewed */ | 141 | item->listItem.isSelected = iTrue; /* currently being viewed */ |
142 | } | 142 | } |
143 | const iTime visitTime = urlVisitTime_Visited(visited_App(), &entry->url); | 143 | if (!containsUrl_Visited(visited_App(), &entry->url)) { |
144 | if (!isValid_Time(&visitTime)) { | ||
145 | item->indent = 1; /* unread */ | 144 | item->indent = 1; /* unread */ |
146 | } | 145 | } |
147 | set_String(&item->url, &entry->url); | 146 | set_String(&item->url, &entry->url); |
@@ -457,8 +456,8 @@ static const iGmIdentity *constHoverIdentity_SidebarWidget_(const iSidebarWidget | |||
457 | 456 | ||
458 | static iGmIdentity *menuIdentity_SidebarWidget_(const iSidebarWidget *d) { | 457 | static iGmIdentity *menuIdentity_SidebarWidget_(const iSidebarWidget *d) { |
459 | if (d->mode == identities_SidebarMode) { | 458 | if (d->mode == identities_SidebarMode) { |
460 | if (d->menuItem) { | 459 | if (d->contextItem) { |
461 | return identity_GmCerts(certs_App(), d->menuItem->id); | 460 | return identity_GmCerts(certs_App(), d->contextItem->id); |
462 | } | 461 | } |
463 | } | 462 | } |
464 | return NULL; | 463 | return NULL; |
@@ -642,14 +641,14 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
642 | scrollOffset_ListWidget(d->list, 0); | 641 | scrollOffset_ListWidget(d->list, 0); |
643 | } | 642 | } |
644 | else if (equal_Command(cmd, "bookmark.copy")) { | 643 | else if (equal_Command(cmd, "bookmark.copy")) { |
645 | const iSidebarItem *item = d->menuItem; | 644 | const iSidebarItem *item = d->contextItem; |
646 | if (d->mode == bookmarks_SidebarMode && item) { | 645 | if (d->mode == bookmarks_SidebarMode && item) { |
647 | SDL_SetClipboardText(cstr_String(&item->url)); | 646 | SDL_SetClipboardText(cstr_String(&item->url)); |
648 | } | 647 | } |
649 | return iTrue; | 648 | return iTrue; |
650 | } | 649 | } |
651 | else if (equal_Command(cmd, "bookmark.edit")) { | 650 | else if (equal_Command(cmd, "bookmark.edit")) { |
652 | const iSidebarItem *item = d->menuItem; | 651 | const iSidebarItem *item = d->contextItem; |
653 | if (d->mode == bookmarks_SidebarMode && item) { | 652 | if (d->mode == bookmarks_SidebarMode && item) { |
654 | setFlags_Widget(w, disabled_WidgetFlag, iTrue); | 653 | setFlags_Widget(w, disabled_WidgetFlag, iTrue); |
655 | iWidget *dlg = makeBookmarkEditor_Widget(); | 654 | iWidget *dlg = makeBookmarkEditor_Widget(); |
@@ -663,25 +662,22 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
663 | return iTrue; | 662 | return iTrue; |
664 | } | 663 | } |
665 | else if (equal_Command(cmd, "bookmark.tag")) { | 664 | else if (equal_Command(cmd, "bookmark.tag")) { |
666 | const iSidebarItem *item = d->menuItem; | 665 | const iSidebarItem *item = d->contextItem; |
667 | if (d->mode == bookmarks_SidebarMode && item) { | 666 | if (d->mode == bookmarks_SidebarMode && item) { |
668 | const char *tag = cstr_String(string_Command(cmd, "tag")); | 667 | const char *tag = cstr_String(string_Command(cmd, "tag")); |
669 | iBookmark *bm = get_Bookmarks(bookmarks_App(), item->id); | 668 | iBookmark *bm = get_Bookmarks(bookmarks_App(), item->id); |
670 | if (hasTag_Bookmark(bm, tag)) { | 669 | if (hasTag_Bookmark(bm, tag)) { |
671 | size_t pos = indexOfCStr_String(&bm->tags, tag); | 670 | removeTag_Bookmark(bm, tag); |
672 | remove_Block(&bm->tags.chars, pos, strlen(tag)); | ||
673 | trim_String(&bm->tags); | ||
674 | } | 671 | } |
675 | else { | 672 | else { |
676 | appendChar_String(&bm->tags, ' '); | 673 | addTag_Bookmark(bm, tag); |
677 | appendCStr_String(&bm->tags, tag); | ||
678 | } | 674 | } |
679 | postCommand_App("bookmarks.changed"); | 675 | postCommand_App("bookmarks.changed"); |
680 | } | 676 | } |
681 | return iTrue; | 677 | return iTrue; |
682 | } | 678 | } |
683 | else if (equal_Command(cmd, "bookmark.delete")) { | 679 | else if (equal_Command(cmd, "bookmark.delete")) { |
684 | const iSidebarItem *item = d->menuItem; | 680 | const iSidebarItem *item = d->contextItem; |
685 | if (d->mode == bookmarks_SidebarMode && item && remove_Bookmarks(bookmarks_App(), item->id)) { | 681 | if (d->mode == bookmarks_SidebarMode && item && remove_Bookmarks(bookmarks_App(), item->id)) { |
686 | postCommand_App("bookmarks.changed"); | 682 | postCommand_App("bookmarks.changed"); |
687 | } | 683 | } |
@@ -695,7 +691,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
695 | updateItems_SidebarWidget_(d); | 691 | updateItems_SidebarWidget_(d); |
696 | } | 692 | } |
697 | else if (startsWith_CStr(cmd, "feed.entry.") && d->mode == feeds_SidebarMode) { | 693 | else if (startsWith_CStr(cmd, "feed.entry.") && d->mode == feeds_SidebarMode) { |
698 | const iSidebarItem *item = d->menuItem; | 694 | const iSidebarItem *item = d->contextItem; |
699 | if (item) { | 695 | if (item) { |
700 | if (equal_Command(cmd, "feed.entry.opentab")) { | 696 | if (equal_Command(cmd, "feed.entry.opentab")) { |
701 | postCommandf_App("open newtab:1 url:%s", cstr_String(&item->url)); | 697 | postCommandf_App("open newtab:1 url:%s", cstr_String(&item->url)); |
@@ -703,8 +699,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
703 | } | 699 | } |
704 | if (equal_Command(cmd, "feed.entry.toggleread")) { | 700 | if (equal_Command(cmd, "feed.entry.toggleread")) { |
705 | iVisited *vis = visited_App(); | 701 | iVisited *vis = visited_App(); |
706 | const iTime visit = urlVisitTime_Visited(vis, &item->url); | 702 | if (containsUrl_Visited(vis, &item->url)) { |
707 | if (isValid_Time(&visit)) { | ||
708 | removeUrl_Visited(vis, &item->url); | 703 | removeUrl_Visited(vis, &item->url); |
709 | } | 704 | } |
710 | else { | 705 | else { |
@@ -713,12 +708,30 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
713 | postCommand_App("visited.changed"); | 708 | postCommand_App("visited.changed"); |
714 | return iTrue; | 709 | return iTrue; |
715 | } | 710 | } |
716 | const iBookmark *feedBookmark = get_Bookmarks(bookmarks_App(), item->id); | 711 | iBookmark *feedBookmark = get_Bookmarks(bookmarks_App(), item->id); |
717 | if (feedBookmark) { | 712 | if (feedBookmark) { |
718 | if (equal_Command(cmd, "feed.entry.openfeed")) { | 713 | if (equal_Command(cmd, "feed.entry.openfeed")) { |
719 | postCommandf_App("open url:%s", cstr_String(&feedBookmark->url)); | 714 | postCommandf_App("open url:%s", cstr_String(&feedBookmark->url)); |
720 | return iTrue; | 715 | return iTrue; |
721 | } | 716 | } |
717 | if (equal_Command(cmd, "feed.entry.unsubscribe")) { | ||
718 | if (arg_Command(cmd)) { | ||
719 | removeTag_Bookmark(feedBookmark, "subscribed"); | ||
720 | removeEntries_Feeds(id_Bookmark(feedBookmark)); | ||
721 | updateItems_SidebarWidget_(d); | ||
722 | return iTrue; | ||
723 | } | ||
724 | else { | ||
725 | makeQuestion_Widget( | ||
726 | uiTextCaution_ColorEscape "UNSUBSCRIBE", | ||
727 | format_CStr("Really unsubscribe from feed\n\"%s\"?", | ||
728 | cstr_String(&feedBookmark->title)), | ||
729 | (const char *[]){ "Cancel", | ||
730 | uiTextCaution_ColorEscape "Unsubscribe" }, | ||
731 | (const char *[]){ "cancel", "feed.entry.unsubscribe arg:1" }, | ||
732 | 2); | ||
733 | } | ||
734 | } | ||
722 | } | 735 | } |
723 | } | 736 | } |
724 | } | 737 | } |
@@ -787,7 +800,7 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
787 | return iTrue; | 800 | return iTrue; |
788 | } | 801 | } |
789 | else if (equal_Command(cmd, "ident.delete")) { | 802 | else if (equal_Command(cmd, "ident.delete")) { |
790 | iSidebarItem *item = d->menuItem; | 803 | iSidebarItem *item = d->contextItem; |
791 | if (argLabel_Command(cmd, "confirm")) { | 804 | if (argLabel_Command(cmd, "confirm")) { |
792 | makeQuestion_Widget(uiTextCaution_ColorEscape "DELETE IDENTITY", | 805 | makeQuestion_Widget(uiTextCaution_ColorEscape "DELETE IDENTITY", |
793 | format_CStr("Do you really want to delete the identity\n" | 806 | format_CStr("Do you really want to delete the identity\n" |
@@ -807,22 +820,22 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
807 | return iTrue; | 820 | return iTrue; |
808 | } | 821 | } |
809 | else if (equal_Command(cmd, "history.delete")) { | 822 | else if (equal_Command(cmd, "history.delete")) { |
810 | if (d->menuItem && !isEmpty_String(&d->menuItem->url)) { | 823 | if (d->contextItem && !isEmpty_String(&d->contextItem->url)) { |
811 | removeUrl_Visited(visited_App(), &d->menuItem->url); | 824 | removeUrl_Visited(visited_App(), &d->contextItem->url); |
812 | updateItems_SidebarWidget_(d); | 825 | updateItems_SidebarWidget_(d); |
813 | scrollOffset_ListWidget(d->list, 0); | 826 | scrollOffset_ListWidget(d->list, 0); |
814 | } | 827 | } |
815 | return iTrue; | 828 | return iTrue; |
816 | } | 829 | } |
817 | else if (equal_Command(cmd, "history.copy")) { | 830 | else if (equal_Command(cmd, "history.copy")) { |
818 | const iSidebarItem *item = d->menuItem; | 831 | const iSidebarItem *item = d->contextItem; |
819 | if (item && !isEmpty_String(&item->url)) { | 832 | if (item && !isEmpty_String(&item->url)) { |
820 | SDL_SetClipboardText(cstr_String(&item->url)); | 833 | SDL_SetClipboardText(cstr_String(&item->url)); |
821 | } | 834 | } |
822 | return iTrue; | 835 | return iTrue; |
823 | } | 836 | } |
824 | else if (equal_Command(cmd, "history.addbookmark")) { | 837 | else if (equal_Command(cmd, "history.addbookmark")) { |
825 | const iSidebarItem *item = d->menuItem; | 838 | const iSidebarItem *item = d->contextItem; |
826 | if (!isEmpty_String(&item->url)) { | 839 | if (!isEmpty_String(&item->url)) { |
827 | makeBookmarkCreation_Widget( | 840 | makeBookmarkCreation_Widget( |
828 | &item->url, | 841 | &item->url, |
@@ -872,12 +885,12 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
872 | updateMouseHover_ListWidget(d->list); | 885 | updateMouseHover_ListWidget(d->list); |
873 | } | 886 | } |
874 | if (constHoverItem_ListWidget(d->list) || isVisible_Widget(d->menu)) { | 887 | if (constHoverItem_ListWidget(d->list) || isVisible_Widget(d->menu)) { |
875 | d->menuItem = hoverItem_ListWidget(d->list); | 888 | d->contextItem = hoverItem_ListWidget(d->list); |
876 | /* Update menu items. */ | 889 | /* Update menu items. */ |
877 | /* TODO: Some callback-based mechanism would be nice for updating menus right | 890 | /* TODO: Some callback-based mechanism would be nice for updating menus right |
878 | before they open? */ | 891 | before they open? */ |
879 | if (d->mode == bookmarks_SidebarMode && d->menuItem) { | 892 | if (d->mode == bookmarks_SidebarMode && d->contextItem) { |
880 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), d->menuItem->id); | 893 | const iBookmark *bm = get_Bookmarks(bookmarks_App(), d->contextItem->id); |
881 | if (bm) { | 894 | if (bm) { |
882 | iLabelWidget *menuItem = findMenuItem_Widget(d->menu, | 895 | iLabelWidget *menuItem = findMenuItem_Widget(d->menu, |
883 | "bookmark.tag tag:homepage"); | 896 | "bookmark.tag tag:homepage"); |
@@ -896,6 +909,11 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) | |||
896 | } | 909 | } |
897 | } | 910 | } |
898 | } | 911 | } |
912 | else if (d->mode == feeds_SidebarMode && d->contextItem) { | ||
913 | iLabelWidget *menuItem = findMenuItem_Widget(d->menu, "feed.entry.toggleread"); | ||
914 | const iBool isRead = containsUrl_Visited(visited_App(), &d->contextItem->url); | ||
915 | setTextCStr_LabelWidget(menuItem, isRead ? "Mark as Unread" : "Mark as Read"); | ||
916 | } | ||
899 | else if (d->mode == identities_SidebarMode) { | 917 | else if (d->mode == identities_SidebarMode) { |
900 | const iGmIdentity *ident = constHoverIdentity_SidebarWidget_(d); | 918 | const iGmIdentity *ident = constHoverIdentity_SidebarWidget_(d); |
901 | const iString * docUrl = url_DocumentWidget(document_App()); | 919 | const iString * docUrl = url_DocumentWidget(document_App()); |
diff --git a/src/visited.c b/src/visited.c index a1dab6be..5d8a5676 100644 --- a/src/visited.c +++ b/src/visited.c | |||
@@ -200,6 +200,11 @@ iTime urlVisitTime_Visited(const iVisited *d, const iString *url) { | |||
200 | return item.when; | 200 | return item.when; |
201 | } | 201 | } |
202 | 202 | ||
203 | iBool containsUrl_Visited(const iVisited *d, const iString *url) { | ||
204 | const iTime time = urlVisitTime_Visited(d, url); | ||
205 | return isValid_Time(&time); | ||
206 | } | ||
207 | |||
203 | static int cmpWhenDescending_VisitedUrlPtr_(const void *a, const void *b) { | 208 | static int cmpWhenDescending_VisitedUrlPtr_(const void *a, const void *b) { |
204 | const iVisitedUrl *s = *(const void **) a, *t = *(const void **) b; | 209 | const iVisitedUrl *s = *(const void **) a, *t = *(const void **) b; |
205 | return -cmp_Time(&s->when, &t->when); | 210 | return -cmp_Time(&s->when, &t->when); |
diff --git a/src/visited.h b/src/visited.h index d9eb02b6..467bad40 100644 --- a/src/visited.h +++ b/src/visited.h | |||
@@ -51,5 +51,6 @@ void save_Visited (const iVisited *, const char *dirPath); | |||
51 | iTime urlVisitTime_Visited (const iVisited *, const iString *url); | 51 | iTime urlVisitTime_Visited (const iVisited *, const iString *url); |
52 | void visitUrl_Visited (iVisited *, const iString *url, uint16_t visitFlags); /* adds URL to the visited URLs set */ | 52 | void visitUrl_Visited (iVisited *, const iString *url, uint16_t visitFlags); /* adds URL to the visited URLs set */ |
53 | void removeUrl_Visited (iVisited *, const iString *url); | 53 | void removeUrl_Visited (iVisited *, const iString *url); |
54 | iBool containsUrl_Visited (const iVisited *, const iString *url); | ||
54 | 55 | ||
55 | const iPtrArray * list_Visited (const iVisited *, size_t count); /* returns collected */ | 56 | const iPtrArray * list_Visited (const iVisited *, size_t count); /* returns collected */ |