summaryrefslogtreecommitdiff
path: root/src/history.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-08 08:06:22 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-08 08:06:22 +0300
commitd6875fba63cc674d2d9cac64a66c3b4c9f3eaba1 (patch)
treea12111a19b594fc17792a7a851d1526597470121 /src/history.c
parent9abe27c63e088bf1e139d108cbc29ac39222d74c (diff)
Moved recent URLs history to DocumentWidget
App maintains the visited URLs database, but each DocumentWidget has its own stack of recent URLs for timeline navigation.
Diffstat (limited to 'src/history.c')
-rw-r--r--src/history.c111
1 files changed, 4 insertions, 107 deletions
diff --git a/src/history.c b/src/history.c
index a2c4271f..c009f484 100644
--- a/src/history.c
+++ b/src/history.c
@@ -3,10 +3,8 @@
3 3
4#include <the_Foundation/file.h> 4#include <the_Foundation/file.h>
5#include <the_Foundation/path.h> 5#include <the_Foundation/path.h>
6#include <the_Foundation/sortedarray.h>
7 6
8static const size_t maxStack_History_ = 50; /* back/forward navigable items */ 7static const size_t maxStack_History_ = 50; /* back/forward navigable items */
9static const size_t maxAgeVisited_History_ = 3600 * 24 * 30; /* one month */
10 8
11void init_RecentUrl(iRecentUrl *d) { 9void init_RecentUrl(iRecentUrl *d) {
12 init_String(&d->url); 10 init_String(&d->url);
@@ -19,30 +17,11 @@ void deinit_RecentUrl(iRecentUrl *d) {
19 delete_GmResponse(d->cachedResponse); 17 delete_GmResponse(d->cachedResponse);
20} 18}
21 19
22void init_VisitedUrl(iVisitedUrl *d) {
23 initCurrent_Time(&d->when);
24 init_String(&d->url);
25}
26
27void deinit_VisitedUrl(iVisitedUrl *d) {
28 deinit_String(&d->url);
29}
30
31static int cmpUrl_VisitedUrl_(const void *a, const void *b) {
32 return cmpString_String(&((const iVisitedUrl *) a)->url, &((const iVisitedUrl *) b)->url);
33}
34
35static int cmpNewer_VisitedUrl_(const void *insert, const void *existing) {
36 return seconds_Time(&((const iVisitedUrl *) insert )->when) >
37 seconds_Time(&((const iVisitedUrl *) existing)->when);
38}
39
40/*----------------------------------------------------------------------------------------------*/ 20/*----------------------------------------------------------------------------------------------*/
41 21
42struct Impl_History { 22struct Impl_History {
43 iArray recent; /* TODO: should be specific to a DocumentWidget */ 23 iArray recent; /* TODO: should be specific to a DocumentWidget */
44 size_t recentPos; /* zero at the latest item */ 24 size_t recentPos; /* zero at the latest item */
45 iSortedArray visited;
46}; 25};
47 26
48iDefineTypeConstruction(History) 27iDefineTypeConstruction(History)
@@ -50,13 +29,11 @@ iDefineTypeConstruction(History)
50void init_History(iHistory *d) { 29void init_History(iHistory *d) {
51 init_Array(&d->recent, sizeof(iRecentUrl)); 30 init_Array(&d->recent, sizeof(iRecentUrl));
52 d->recentPos = 0; 31 d->recentPos = 0;
53 init_SortedArray(&d->visited, sizeof(iVisitedUrl), cmpUrl_VisitedUrl_);
54} 32}
55 33
56void deinit_History(iHistory *d) { 34void deinit_History(iHistory *d) {
57 clear_History(d); 35 clear_History(d);
58 deinit_Array(&d->recent); 36 deinit_Array(&d->recent);
59 deinit_SortedArray(&d->visited);
60} 37}
61 38
62void save_History(const iHistory *d, const char *dirPath) { 39void save_History(const iHistory *d, const char *dirPath) {
@@ -70,25 +47,6 @@ void save_History(const iHistory *d, const char *dirPath) {
70 } 47 }
71 } 48 }
72 iRelease(f); 49 iRelease(f);
73 f = newCStr_File(concatPath_CStr(dirPath, "visited.txt"));
74 if (open_File(f, writeOnly_FileMode | text_FileMode)) {
75 iConstForEach(Array, i, &d->visited.values) {
76 const iVisitedUrl *item = i.value;
77 iDate date;
78 init_Date(&date, &item->when);
79 format_String(line,
80 "%04d-%02d-%02dT%02d:%02d:%02d %s\n",
81 date.year,
82 date.month,
83 date.day,
84 date.hour,
85 date.minute,
86 date.second,
87 cstr_String(&item->url));
88 writeData_File(f, cstr_String(line), size_String(line));
89 }
90 }
91 iRelease(f);
92 delete_String(line); 50 delete_String(line);
93} 51}
94 52
@@ -111,29 +69,6 @@ void load_History(iHistory *d, const char *dirPath) {
111 } 69 }
112 } 70 }
113 iRelease(f); 71 iRelease(f);
114 f = newCStr_File(concatPath_CStr(dirPath, "visited.txt"));
115 if (open_File(f, readOnly_FileMode | text_FileMode)) {
116 const iRangecc src = range_Block(collect_Block(readAll_File(f)));
117 iRangecc line = iNullRange;
118 iTime now;
119 initCurrent_Time(&now);
120 while (nextSplit_Rangecc(&src, "\n", &line)) {
121 int y, m, D, H, M, S;
122 sscanf(line.start, "%04d-%02d-%02dT%02d:%02d:%02d ", &y, &m, &D, &H, &M, &S);
123 if (!y) break;
124 iVisitedUrl item;
125 init_VisitedUrl(&item);
126 init_Time(
127 &item.when,
128 &(iDate){ .year = y, .month = m, .day = D, .hour = H, .minute = M, .second = S });
129 if (secondsSince_Time(&now, &item.when) > maxAgeVisited_History_) {
130 continue; /* Too old. */
131 }
132 initRange_String(&item.url, (iRangecc){ line.start + 20, line.end });
133 insert_SortedArray(&d->visited, &item);
134 }
135 }
136 iRelease(f);
137} 72}
138 73
139void clear_History(iHistory *d) { 74void clear_History(iHistory *d) {
@@ -141,10 +76,6 @@ void clear_History(iHistory *d) {
141 deinit_RecentUrl(s.value); 76 deinit_RecentUrl(s.value);
142 } 77 }
143 clear_Array(&d->recent); 78 clear_Array(&d->recent);
144 iForEach(Array, v, &d->visited.values) {
145 deinit_VisitedUrl(v.value);
146 }
147 clear_SortedArray(&d->visited);
148} 79}
149 80
150iRecentUrl *recentUrl_History(iHistory *d, size_t pos) { 81iRecentUrl *recentUrl_History(iHistory *d, size_t pos) {
@@ -173,32 +104,15 @@ const iString *url_History(const iHistory *d, size_t pos) {
173 return collectNew_String(); 104 return collectNew_String();
174} 105}
175 106
176static void addVisited_History_(iHistory *d, const iString *url) {
177 iVisitedUrl visit;
178 init_VisitedUrl(&visit);
179 set_String(&visit.url, url);
180 size_t pos;
181 if (locate_SortedArray(&d->visited, &visit, &pos)) {
182 iVisitedUrl *old = at_SortedArray(&d->visited, pos);
183 if (cmpNewer_VisitedUrl_(&visit, old)) {
184 old->when = visit.when;
185 deinit_VisitedUrl(&visit);
186 return;
187 }
188 }
189 insert_SortedArray(&d->visited, &visit);
190}
191
192void replace_History(iHistory *d, const iString *url) { 107void replace_History(iHistory *d, const iString *url) {
193 /* Update in the history. */ 108 /* Update in the history. */
194 iRecentUrl *item = mostRecentUrl_History(d); 109 iRecentUrl *item = mostRecentUrl_History(d);
195 if (item) { 110 if (item) {
196 set_String(&item->url, url); 111 set_String(&item->url, url);
197 } 112 }
198 addVisited_History_(d, url);
199} 113}
200 114
201void addUrl_History(iHistory *d, const iString *url ){ 115void add_History(iHistory *d, const iString *url ){
202 /* Cut the trailing history items. */ 116 /* Cut the trailing history items. */
203 if (d->recentPos > 0) { 117 if (d->recentPos > 0) {
204 for (size_t i = 0; i < d->recentPos - 1; i++) { 118 for (size_t i = 0; i < d->recentPos - 1; i++) {
@@ -220,11 +134,6 @@ void addUrl_History(iHistory *d, const iString *url ){
220 remove_Array(&d->recent, 0); 134 remove_Array(&d->recent, 0);
221 } 135 }
222 } 136 }
223 addVisited_History_(d, url);
224}
225
226void visitUrl_History(iHistory *d, const iString *url) {
227 addVisited_History_(d, url);
228} 137}
229 138
230iBool goBack_History(iHistory *d) { 139iBool goBack_History(iHistory *d) {
@@ -247,18 +156,6 @@ iBool goForward_History(iHistory *d) {
247 return iFalse; 156 return iFalse;
248} 157}
249 158
250iTime urlVisitTime_History(const iHistory *d, const iString *url) {
251 iVisitedUrl item;
252 size_t pos;
253 iZap(item);
254 initCopy_String(&item.url, url);
255 if (locate_SortedArray(&d->visited, &item, &pos)) {
256 item.when = ((const iVisitedUrl *) constAt_SortedArray(&d->visited, pos))->when;
257 }
258 deinit_String(&item.url);
259 return item.when;
260}
261
262const iGmResponse *cachedResponse_History(const iHistory *d) { 159const iGmResponse *cachedResponse_History(const iHistory *d) {
263 const iRecentUrl *item = constMostRecentUrl_History(d); 160 const iRecentUrl *item = constMostRecentUrl_History(d);
264 return item ? item->cachedResponse : NULL; 161 return item ? item->cachedResponse : NULL;