Strings corrections from Malcolm Parsons
[elinks.git] / src / viewer / text / marks.c
blob5770542fd149eff49bc962f68f52c96f64ced29f
1 /** Marks registry
2 * @file */
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
8 #include <stdlib.h>
9 #include <string.h>
11 #include "elinks.h"
13 #include "document/view.h"
14 #include "intl/gettext/libintl.h"
15 #include "main/module.h"
16 #include "protocol/uri.h"
17 #include "util/memory.h"
18 #include "util/string.h"
19 #include "viewer/text/form.h"
20 #include "viewer/text/link.h"
21 #include "viewer/text/marks.h"
22 #include "viewer/text/view.h"
23 #include "viewer/text/vs.h"
26 /* TODO list:
28 * * Make it possible to go at marks which are set in a different document than
29 * the active one. This will basically need some clever hacking in the
30 * KP_MARK_GOTO handler, which first needs to load the URL and *then* jump to
31 * the exact location and just overally restore the rest of view_state. Perhaps
32 * this could also be somehow nicely unified with session.goto_position? --pasky
34 * * The lower-case chars should have per-document scope, while the upper-case
35 * chars would have per-ELinks (over all instances as well) scope. The l-c marks
36 * should be stored either in {struct document} or {struct location}, that needs
37 * further investigation. Disappearing when document gets out of all caches
38 * and/or histories is not an issue from my POV. However, it must be ensured
39 * that all instances of the document (and only the document) share the same
40 * marks. If we are dealing with frames, I mean content of one frame by
41 * 'document' - each frame in the frameset gets own set of marks. --pasky
43 * * Number marks for last ten documents in session history. XXX: To be
44 * meaningful, it needs to support last n both history and unhistory items.
45 * --pasky
47 * * "''" support (jump to the last visited mark). (What if it was per-document
48 * mark and we are already in another document now?) --pasky
50 * * When pressing "'", list of already set marks should appear. The next
51 * pressed char, if letter, would still directly get stuff from the list.
52 * --pasky */
55 /** Number of possible mark characters: upper-case and lower-case
56 * ASCII letters. The ::marks array is indexed by ASCII code of the
57 * mark. */
58 #define MARKS_SIZE 26 * 2
59 static struct view_state *marks[MARKS_SIZE];
61 #define is_valid_mark_char(c) isasciialpha(c)
62 #define is_valid_mark_index(i) ((i) >= 0 && (i) < MARKS_SIZE)
64 static inline int
65 index_from_char(unsigned char mark)
67 assert(is_valid_mark_char(mark));
69 if (mark >= 'A' && mark <= 'Z')
70 return mark - 'A';
72 return mark - 'a' + 26;
75 void
76 goto_mark(unsigned char mark, struct view_state *vs)
78 int old_current_link;
79 #ifdef CONFIG_ECMASCRIPT
80 struct ecmascript_interpreter *ecmascript;
81 int ecmascript_fragile;
82 #endif
83 struct document_view *doc_view;
84 int i;
86 if (!is_valid_mark_char(mark))
87 return;
89 i = index_from_char(mark);
90 assert(is_valid_mark_index(i));
92 /* TODO: Support for cross-document marks. --pasky */
93 if (!marks[i] || !compare_uri(marks[i]->uri, vs->uri, 0))
94 return;
96 old_current_link = vs->current_link;
97 #ifdef CONFIG_ECMASCRIPT
98 ecmascript = vs->ecmascript;
99 ecmascript_fragile = vs->ecmascript_fragile;
100 #endif
101 doc_view = vs->doc_view;
103 destroy_vs(vs, 0);
104 copy_vs(vs, marks[i]);
106 vs->doc_view = doc_view;
107 vs->doc_view->vs = vs;
108 #ifdef CONFIG_ECMASCRIPT
109 vs->ecmascript = ecmascript;
110 vs->ecmascript_fragile = ecmascript_fragile;
111 #endif
112 vs->old_current_link = old_current_link;
115 static void
116 free_mark_by_index(int i)
118 assert(is_valid_mark_index(i));
120 if (!marks[i]) return;
122 destroy_vs(marks[i], 1);
123 mem_free_set(&marks[i], NULL);
126 void
127 set_mark(unsigned char mark, struct view_state *mark_vs)
129 struct view_state *vs;
130 int i;
132 if (!is_valid_mark_char(mark))
133 return;
135 i = index_from_char(mark);
136 free_mark_by_index(i);
138 if (!mark_vs) return;
140 vs = mem_calloc(1, sizeof(*vs));
141 if (!vs) return;
142 copy_vs(vs, mark_vs);
144 marks[i] = vs;
147 static void
148 done_marks(struct module *xxx)
150 int i;
152 for (i = 0; i < MARKS_SIZE; i++) {
153 free_mark_by_index(i);
157 struct module viewer_marks_module = struct_module(
158 /* name: */ N_("Marks"),
159 /* options: */ NULL,
160 /* hooks: */ NULL,
161 /* submodules: */ NULL,
162 /* data: */ NULL,
163 /* init: */ NULL,
164 /* done: */ done_marks