diff options
-rw-r--r-- | src/app.c | 20 | ||||
-rw-r--r-- | src/history.c | 46 | ||||
-rw-r--r-- | src/history.h | 15 |
3 files changed, 55 insertions, 26 deletions
@@ -49,7 +49,7 @@ struct Impl_App { | |||
49 | iWindow * window; | 49 | iWindow * window; |
50 | iSortedArray tickers; | 50 | iSortedArray tickers; |
51 | iBool pendingRefresh; | 51 | iBool pendingRefresh; |
52 | iHistory history; | 52 | iHistory * history; |
53 | /* Preferences: */ | 53 | /* Preferences: */ |
54 | iBool retainWindowSize; | 54 | iBool retainWindowSize; |
55 | float uiScale; | 55 | float uiScale; |
@@ -146,9 +146,9 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
146 | d->window = NULL; | 146 | d->window = NULL; |
147 | d->retainWindowSize = iTrue; | 147 | d->retainWindowSize = iTrue; |
148 | d->pendingRefresh = iFalse; | 148 | d->pendingRefresh = iFalse; |
149 | init_History(&d->history); | 149 | d->history = new_History(); |
150 | loadPrefs_App_(d); | 150 | loadPrefs_App_(d); |
151 | load_History(&d->history, historyFileName_()); | 151 | load_History(d->history, historyFileName_()); |
152 | #if defined (iHaveLoadEmbed) | 152 | #if defined (iHaveLoadEmbed) |
153 | /* Load the resources from a file. */ { | 153 | /* Load the resources from a file. */ { |
154 | if (!load_Embed( | 154 | if (!load_Embed( |
@@ -166,8 +166,8 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
166 | 166 | ||
167 | static void deinit_App(iApp *d) { | 167 | static void deinit_App(iApp *d) { |
168 | savePrefs_App_(d); | 168 | savePrefs_App_(d); |
169 | save_History(&d->history, historyFileName_()); | 169 | save_History(d->history, historyFileName_()); |
170 | deinit_History(&d->history); | 170 | delete_History(d->history); |
171 | deinit_SortedArray(&d->tickers); | 171 | deinit_SortedArray(&d->tickers); |
172 | delete_Window(d->window); | 172 | delete_Window(d->window); |
173 | d->window = NULL; | 173 | d->window = NULL; |
@@ -328,16 +328,16 @@ iBool handleCommand_App(const char *cmd) { | |||
328 | if (!argLabel_Command(cmd, "history")) { | 328 | if (!argLabel_Command(cmd, "history")) { |
329 | if (argLabel_Command(cmd, "redirect")) { | 329 | if (argLabel_Command(cmd, "redirect")) { |
330 | /* Update in the history. */ | 330 | /* Update in the history. */ |
331 | iHistoryItem *item = item_History(&d->history); | 331 | iHistoryItem *item = item_History(d->history); |
332 | if (item) { | 332 | if (item) { |
333 | set_String(&item->url, url); | 333 | set_String(&item->url, url); |
334 | } | 334 | } |
335 | } | 335 | } |
336 | else { | 336 | else { |
337 | addUrl_History(&d->history, url); | 337 | addUrl_History(d->history, url); |
338 | } | 338 | } |
339 | } | 339 | } |
340 | print_History(&d->history); | 340 | print_History(d->history); |
341 | setUrl_DocumentWidget(findChild_Widget(root, "document"), url); | 341 | setUrl_DocumentWidget(findChild_Widget(root, "document"), url); |
342 | } | 342 | } |
343 | else if (equal_Command(cmd, "document.request.cancelled")) { | 343 | else if (equal_Command(cmd, "document.request.cancelled")) { |
@@ -379,11 +379,11 @@ iBool handleCommand_App(const char *cmd) { | |||
379 | return iFalse; | 379 | return iFalse; |
380 | } | 380 | } |
381 | else if (equal_Command(cmd, "navigate.back")) { | 381 | else if (equal_Command(cmd, "navigate.back")) { |
382 | goBack_History(&d->history); | 382 | goBack_History(d->history); |
383 | return iTrue; | 383 | return iTrue; |
384 | } | 384 | } |
385 | else if (equal_Command(cmd, "navigate.forward")) { | 385 | else if (equal_Command(cmd, "navigate.forward")) { |
386 | goForward_History(&d->history); | 386 | goForward_History(d->history); |
387 | return iTrue; | 387 | return iTrue; |
388 | } | 388 | } |
389 | else if (equal_Command(cmd, "navigate.home")) { | 389 | else if (equal_Command(cmd, "navigate.home")) { |
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) { |
diff --git a/src/history.h b/src/history.h index 15a179d6..786096f2 100644 --- a/src/history.h +++ b/src/history.h | |||
@@ -4,21 +4,15 @@ | |||
4 | #include <the_Foundation/string.h> | 4 | #include <the_Foundation/string.h> |
5 | #include <the_Foundation/time.h> | 5 | #include <the_Foundation/time.h> |
6 | 6 | ||
7 | iDeclareType(History) | ||
8 | iDeclareType(HistoryItem) | 7 | iDeclareType(HistoryItem) |
8 | iDeclareTypeConstruction(HistoryItem) | ||
9 | 9 | ||
10 | struct Impl_HistoryItem { | 10 | struct Impl_HistoryItem { |
11 | iTime when; | 11 | iTime when; |
12 | iString url; | 12 | iString url; |
13 | }; | 13 | }; |
14 | 14 | ||
15 | iDeclareTypeConstruction(HistoryItem) | 15 | iDeclareType(History) |
16 | |||
17 | struct Impl_History { | ||
18 | iArray history; | ||
19 | size_t historyPos; /* zero at the latest item */ | ||
20 | }; | ||
21 | |||
22 | iDeclareTypeConstruction(History) | 16 | iDeclareTypeConstruction(History) |
23 | 17 | ||
24 | void clear_History (iHistory *); | 18 | void clear_History (iHistory *); |
@@ -27,14 +21,11 @@ void load_History (iHistory *, const iString *path); | |||
27 | void save_History (const iHistory *, const iString *path); | 21 | void save_History (const iHistory *, const iString *path); |
28 | 22 | ||
29 | iHistoryItem * itemAtPos_History (iHistory *, size_t pos); | 23 | iHistoryItem * itemAtPos_History (iHistory *, size_t pos); |
24 | iHistoryItem * item_History (iHistory *); | ||
30 | const iString * url_History (iHistory *, size_t pos); | 25 | const iString * url_History (iHistory *, size_t pos); |
31 | iTime urlVisitTime_History(const iHistory *, const iString *url); | 26 | iTime urlVisitTime_History(const iHistory *, const iString *url); |
32 | void print_History (const iHistory *); | 27 | void print_History (const iHistory *); |
33 | 28 | ||
34 | iLocalDef iHistoryItem *item_History(iHistory *d) { | ||
35 | return itemAtPos_History(d, d->historyPos); | ||
36 | } | ||
37 | |||
38 | void addUrl_History (iHistory *, const iString *url); | 29 | void addUrl_History (iHistory *, const iString *url); |
39 | 30 | ||
40 | iBool goBack_History (iHistory *); | 31 | iBool goBack_History (iHistory *); |