NetSurf
url_suggest.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/** \file
20 * URL Suggestion Menu (implementation).
21 */
22
23#include <assert.h>
24#include <string.h>
25#include <stdlib.h>
26#include <oslib/wimp.h>
27
28#include "utils/messages.h"
29#include "utils/nsurl.h"
30#include "netsurf/url_db.h"
31
32#include "riscos/menus.h"
33#include "riscos/url_suggest.h"
34
36 const char *url; /*< The URL being stored. */
37 unsigned int weight; /*< A weight assigned to the URL. */
38 struct url_suggest_item *next; /*< The next URL in the list. */
39};
40
42 const struct url_data *data);
43
44static int suggest_entries;
45static time_t suggest_time;
47
48static wimp_MENU(URL_SUGGEST_MAX_URLS) url_suggest_menu_block;
49wimp_menu *ro_gui_url_suggest_menu = (wimp_menu *) &url_suggest_menu_block;
50
51
52/**
53 * Initialise the URL suggestion menu. This MUST be called before anything
54 * tries to use the URL menu.
55 *
56 * \return true if initialisation was OK; else false.
57 */
58
60{
61 ro_gui_url_suggest_menu->title_data.indirected_text.text =
62 (char *) messages_get("URLSuggest");
65
67
68 return true;
69}
70
71
72/**
73 * Check if there is a URL suggestion menu available for use.
74 *
75 * \todo Ideally this should be able to decide if there's a menu
76 * available without actually having to build it all.
77 *
78 * \return true if the menu has entries; else false.
79 */
80
82{
84}
85
86
87/**
88 * Builds the URL suggestion menu. This is called by ro_gui_menu_create() when
89 * it is asked to display the url_suggest_menu.
90 *
91 * /return true if the menu has entries; else false.
92 */
93
95{
96 struct url_suggest_item *list, *next;
97
98 /* Fetch the URLs we want to include from URLdb. */
99
100 suggest_entries = 0;
101 suggest_list = NULL;
102 suggest_time = time(NULL);
103
105
106 /* If any menu entries were found, put them into the menu. The list
107 * is in reverse order, last to first, so the menu is filled backwards.
108 * Entries from the list are freed as we go.
109 */
110
112
113 if (suggest_entries > 0) {
114 int i = suggest_entries;
115
116 list = suggest_list;
117 suggest_list = NULL;
118
119 while (list != NULL && i > 0) {
120 i--;
121
122 ro_gui_url_suggest_menu->entries[i].menu_flags = 0;
124 entries[i].data.indirected_text.text =
125 (char *) list->url;
127 entries[i].data.indirected_text.size =
128 strlen(list->url) + 1;
129
130 next = list->next;
131 free(list);
132 list = next;
133 }
134
135 assert(i == 0);
136
137 ro_gui_url_suggest_menu->entries[0].menu_flags |=
138 wimp_MENU_TITLE_INDIRECTED;
140 entries[suggest_entries - 1].menu_flags |=
141 wimp_MENU_LAST;
142
143 return true;
144 }
145
146 return false;
147}
148
149
150/**
151 * Callback function for urldb_iterate_entries
152 *
153 * \param url URL which matches
154 * \param data Data associated with URL
155 * \return true to continue iteration, false otherwise
156 */
157
159{
160 int count;
161 unsigned int weight;
162 struct url_suggest_item **list, *new;
163
164 /* Ignore unvisited URLs, and those that don't apply to HTML or Text. */
165
166 if (data->visits == 0 || (data->type != CONTENT_HTML &&
167 data->type != CONTENT_TEXTPLAIN))
168 return true;
169
170 /* Calculate a weight for the URL. */
171
172 weight = (suggest_time - data->last_visit) / data->visits;
173
174 /* Hunt through those URLs already found to see if we want to add
175 * this one. Smaller weights carry higher priority.
176 *
177 * The list is sorted into reverse order, so that lowest weight
178 * items are nearest the head. Therefore, items are dropped from
179 * the head, making things simpler.
180 */
181
182 list = &suggest_list;
183 count = 0;
184
185 while (*list != NULL && weight < (*list)->weight) {
186 list = &((*list)->next);
187 count++;
188 }
189
191 new = (struct url_suggest_item *)
192 malloc(sizeof(struct url_suggest_item));
193
194 if (new != NULL) {
196 /* TODO: keeping pointers to URLdb data is bad.
197 * should be nsurl_ref(url) or
198 * take a copy of the string. */
199 new->url = nsurl_access(url);
200 new->weight = weight;
201 new->next = *list;
202
203 *list = new;
204 }
205 }
206
207 /* If adding the URL gave us too many menu items, drop the lowest
208 * priority ones until the list is the right length again.
209 */
210
212 struct url_suggest_item *old = suggest_list;
214
215 free(old);
217 }
218
219 return true;
220}
221
222
223/**
224 * Process a selection from the URL Suggest menu.
225 *
226 * \param *selection The menu selection.
227 * \return Pointer to the URL that was selected, or NULL for none.
228 */
229
230const char *ro_gui_url_suggest_get_selection(wimp_selection *selection)
231{
232 const char *url = NULL;
233
234 if (selection->items[0] >= 0)
235 url = ro_gui_url_suggest_menu->entries[selection->items[0]].
236 data.indirected_text.text;
237
238 return url;
239}
static uint32_t count(const http_directive *list, lwc_string *key)
@ CONTENT_HTML
content is HTML
Definition: content_type.h:58
@ CONTENT_TEXTPLAIN
content is plain text
Definition: content_type.h:61
void ro_gui_menu_init_structure(wimp_menu *menu, int entries)
Initialise the basic state of a menu structure so all entries are indirected text with no flags,...
Definition: menus.c:682
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
NetSurf URL handling (interface).
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Interface to utility string handling.
unsigned int visits
Visit count.
Definition: url_db.h:38
time_t last_visit
Last visit time.
Definition: url_db.h:39
content_type type
Type of resource.
Definition: url_db.h:40
const char * url
Definition: url_suggest.c:36
unsigned int weight
Definition: url_suggest.c:37
struct url_suggest_item * next
Definition: url_suggest.c:38
Unified URL information database public interface.
void urldb_iterate_entries(bool(*callback)(struct nsurl *url, const struct url_data *data))
Iterate over all entries in database.
const char * ro_gui_url_suggest_get_selection(wimp_selection *selection)
Process a selection from the URL Suggest menu.
Definition: url_suggest.c:230
static wimp_MENU(URL_SUGGEST_MAX_URLS)
Initialise the URL suggestion menu.
Definition: url_suggest.c:48
bool ro_gui_url_suggest_prepare_menu(void)
Builds the URL suggestion menu.
Definition: url_suggest.c:94
static struct url_suggest_item * suggest_list
Definition: url_suggest.c:46
static time_t suggest_time
Definition: url_suggest.c:45
static int suggest_entries
Definition: url_suggest.c:44
bool ro_gui_url_suggest_get_menu_available(void)
Check if there is a URL suggestion menu available for use.
Definition: url_suggest.c:81
static bool ro_gui_url_suggest_callback(nsurl *url, const struct url_data *data)
Callback function for urldb_iterate_entries.
Definition: url_suggest.c:158
URL Suggestion Menu (interface).
wimp_menu * ro_gui_url_suggest_menu
bool ro_gui_url_suggest_init(void)
#define URL_SUGGEST_MAX_URLS
Definition: url_suggest.h:28