diff options
Diffstat (limited to 'src/history.c')
-rw-r--r-- | src/history.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/src/history.c b/src/history.c index 94b88677..0bd23149 100644 --- a/src/history.c +++ b/src/history.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include "app.h" | 2 | #include "app.h" |
3 | 3 | ||
4 | #include <the_Foundation/file.h> | 4 | #include <the_Foundation/file.h> |
5 | #include <the_Foundation/sortedarray.h> | ||
5 | 6 | ||
6 | static const size_t maxSize_History_ = 5000; | 7 | static const size_t maxSize_History_ = 5000; |
7 | 8 | ||
@@ -14,12 +15,40 @@ void deinit_HistoryItem(iHistoryItem *d) { | |||
14 | deinit_String(&d->url); | 15 | deinit_String(&d->url); |
15 | } | 16 | } |
16 | 17 | ||
18 | struct Impl_History { | ||
19 | iArray history; | ||
20 | size_t historyPos; /* zero at the latest item */ | ||
21 | iSortedArray visitedUrls; | ||
22 | }; | ||
23 | |||
24 | iDefineTypeConstruction(History) | ||
25 | |||
26 | static int cmp_VisitedUrls_(const void *a, const void *b) { | ||
27 | const iHistoryItem *elem[2] = { a, b }; | ||
28 | return cmpString_String(&elem[0]->url, &elem[1]->url); | ||
29 | } | ||
30 | |||
31 | static int cmpWhen_HistoryItem_(const void *old, const void *ins) { | ||
32 | const iHistoryItem *elem[2] = { old, ins }; | ||
33 | const double tOld = seconds_Time(&elem[0]->when), tIns = seconds_Time(&elem[1]->when); | ||
34 | return tIns > tOld; | ||
35 | } | ||
36 | |||
37 | static void updateVisitedUrls_History_(iHistory *d) { | ||
38 | clear_SortedArray(&d->visitedUrls); | ||
39 | iConstForEach(Array, i, &d->history) { | ||
40 | insertIf_SortedArray(&d->visitedUrls, &i.value, cmpWhen_HistoryItem_); | ||
41 | } | ||
42 | } | ||
43 | |||
17 | void init_History(iHistory *d) { | 44 | void init_History(iHistory *d) { |
18 | init_Array(&d->history, sizeof(iHistoryItem)); | 45 | init_Array(&d->history, sizeof(iHistoryItem)); |
19 | d->historyPos = 0; | 46 | d->historyPos = 0; |
47 | init_SortedArray(&d->visitedUrls, sizeof(const iHistoryItem *), cmp_VisitedUrls_); | ||
20 | } | 48 | } |
21 | 49 | ||
22 | void deinit_History(iHistory *d) { | 50 | void deinit_History(iHistory *d) { |
51 | deinit_SortedArray(&d->visitedUrls); | ||
23 | clear_History(d); | 52 | clear_History(d); |
24 | deinit_Array(&d->history); | 53 | deinit_Array(&d->history); |
25 | } | 54 | } |
@@ -83,6 +112,10 @@ iHistoryItem *itemAtPos_History(iHistory *d, size_t pos) { | |||
83 | return &value_Array(&d->history, size_Array(&d->history) - 1 - pos, iHistoryItem); | 112 | return &value_Array(&d->history, size_Array(&d->history) - 1 - pos, iHistoryItem); |
84 | } | 113 | } |
85 | 114 | ||
115 | iHistoryItem *item_History(iHistory *d) { | ||
116 | return itemAtPos_History(d, d->historyPos); | ||
117 | } | ||
118 | |||
86 | const iString *url_History(iHistory *d, size_t pos) { | 119 | const iString *url_History(iHistory *d, size_t pos) { |
87 | const iHistoryItem *item = itemAtPos_History(d, pos); | 120 | const iHistoryItem *item = itemAtPos_History(d, pos); |
88 | if (item) { | 121 | if (item) { |
@@ -137,10 +170,15 @@ iBool goForward_History(iHistory *d) { | |||
137 | } | 170 | } |
138 | 171 | ||
139 | iTime urlVisitTime_History(const iHistory *d, const iString *url) { | 172 | iTime urlVisitTime_History(const iHistory *d, const iString *url) { |
140 | iTime when; | 173 | iHistoryItem item; |
141 | iZap(when); | 174 | size_t pos; |
142 | 175 | iZap(item); | |
143 | return when; | 176 | initCopy_String(&item.url, url); |
177 | if (locate_SortedArray(&d->visitedUrls, &(const void *){ &item }, &pos)) { | ||
178 | item.when = ((const iHistoryItem *) constAt_SortedArray(&d->visitedUrls, pos))->when; | ||
179 | } | ||
180 | deinit_String(&item.url); | ||
181 | return item.when; | ||
144 | } | 182 | } |
145 | 183 | ||
146 | void print_History(const iHistory *d) { | 184 | void print_History(const iHistory *d) { |