1 /* Information about current document and current link */
16 #include "bfu/dialog.h"
17 #include "cache/cache.h"
18 #include "dialogs/document.h"
19 #include "document/document.h"
20 #include "document/view.h"
21 #include "globhist/globhist.h"
22 #include "intl/gettext/libintl.h"
23 #include "protocol/header.h"
24 #include "protocol/uri.h"
25 #include "session/location.h"
26 #include "session/session.h"
27 #include "terminal/terminal.h"
28 #include "terminal/window.h"
29 #include "util/conv.h"
30 #include "util/memory.h"
31 #include "util/string.h"
32 #include "viewer/text/link.h"
33 #include "viewer/text/view.h"
36 nowhere_box(struct terminal
*term
, unsigned char *title
)
39 if_assert_failed
return;
41 if (!title
|| !*title
)
44 info_box(term
, 0, title
, ALIGN_CENTER
,
45 N_("You are nowhere!"));
49 add_link_info_to_string(struct string
*msg
, struct session
*ses
)
51 struct document_view
*doc_view
= current_frame(ses
);
52 struct terminal
*term
= ses
->tab
->term
;
56 if (!doc_view
) return;
58 add_char_to_string(msg
, '\n');
60 a
= get_current_link_info(ses
, doc_view
);
62 add_format_to_string(msg
, "\n%s: %s",
67 a
= get_current_link_title(doc_view
);
69 add_format_to_string(msg
, "\n%s: %s",
70 _("Link title", term
), a
);
74 link
= get_current_link_in_view(doc_view
);
77 #ifdef CONFIG_GLOBHIST
78 struct global_history_item
*historyitem
;
81 if (link
->where_img
&& init_string(&img
)) {
82 add_string_uri_to_string(&img
, link
->where_img
,
84 decode_uri_string_for_display(&img
);
86 add_format_to_string(msg
, "\n%s: %s",
87 _("Link image", term
),
92 #ifdef CONFIG_GLOBHIST
93 historyitem
= get_global_history_item(link
->where
);
95 unsigned char *last_visit
;
97 last_visit
= ctime(&historyitem
->last_visit
);
100 add_format_to_string(msg
,
102 _("Link last visit time",
106 if (*historyitem
->title
)
107 add_format_to_string(msg
, "\n%s: %s",
108 _("Link title (from history)",
116 /* Link info message box. */
118 link_info_dialog(struct session
*ses
)
120 struct terminal
*term
= ses
->tab
->term
;
121 struct location
*location
= cur_loc(ses
);
125 nowhere_box(term
, NULL
);
129 if (!init_string(&msg
)) return;
131 add_link_info_to_string(&msg
, ses
);
133 info_box(term
, MSGBOX_FREE_TEXT
| MSGBOX_SCROLLABLE
,
134 N_("Info"), ALIGN_LEFT
, msg
.source
);
138 /* Location info. message box. */
140 document_info_dialog(struct session
*ses
)
142 struct terminal
*term
= ses
->tab
->term
;
143 struct location
*location
= cur_loc(ses
);
144 struct document_view
*doc_view
;
148 nowhere_box(term
, NULL
);
152 doc_view
= current_frame(ses
);
154 if (!init_string(&msg
)) return;
156 add_to_string(&msg
, _("URL", term
));
157 add_to_string(&msg
, ": ");
159 /* Add the uri with password and post info stripped */
160 add_uri_to_string(&msg
, location
->vs
.uri
, URI_PUBLIC
);
162 add_char_to_string(&msg
, '\n');
164 if (doc_view
&& doc_view
->document
->title
) {
165 add_format_to_string(&msg
, "%s: %s", _("Title", term
),
166 doc_view
->document
->title
);
169 add_char_to_string(&msg
, '\n');
171 if (doc_view
&& doc_view
->document
->cached
) {
172 struct cache_entry
*cached
= doc_view
->document
->cached
;
175 add_format_to_string(&msg
, "\n%s: %" OFF_PRINT_FORMAT
,
177 (off_print_T
) cached
->length
);
179 if (cached
->incomplete
) {
180 add_format_to_string(&msg
, " (%s)", _("incomplete", term
));
184 add_format_to_string(&msg
, "\n%s: %s", _("Codepage", term
),
185 get_cp_name(doc_view
->document
->cp
));
187 if (doc_view
->document
->cp_status
== CP_STATUS_ASSUMED
) {
188 add_format_to_string(&msg
, " (%s)", _("assumed", term
));
189 } else if (doc_view
->document
->cp_status
== CP_STATUS_IGNORED
) {
190 add_format_to_string(&msg
, " (%s)",
191 _("ignoring server setting", term
));
195 a
= parse_header(cached
->head
, "Server", NULL
);
197 add_format_to_string(&msg
, "\n%s: %s",
198 _("Server", term
), a
);
202 if (cached
->ssl_info
) {
203 add_format_to_string(&msg
, "\n%s: %s",
204 _("SSL Cipher", term
),
207 if (cached
->encoding_info
) {
208 add_format_to_string(&msg
, "\n%s: %s",
210 cached
->encoding_info
);
213 a
= parse_header(cached
->head
, "Date", NULL
);
215 add_format_to_string(&msg
, "\n%s: %s",
220 if (cached
->last_modified
) {
221 add_format_to_string(&msg
, "\n%s: %s",
222 _("Last modified", term
),
223 cached
->last_modified
);
226 if (!cached
->incomplete
) {
227 add_format_to_string(&msg
, "\n%s: ",
228 _("Time since loading", term
));
229 add_duration_to_string(&msg
,
230 time(NULL
) - cached
->seconds
);
235 #ifdef CONFIG_GLOBHIST
237 unsigned char *last_visit
= NULL
;
238 struct global_history_item
*historyitem
;
240 add_format_to_string(&msg
, "\n%s: ",
241 _("Last visit time", term
));
243 historyitem
= get_global_history_item(struri(location
->vs
.uri
));
245 if (historyitem
) last_visit
= ctime(&historyitem
->last_visit
);
247 /* GNU's documentation says that ctime() can return NULL.
248 * The Open Group Base Specifications Issue 6 implies
249 * otherwise, but is ambiguous. Let's be safe. -- Miciah
252 /* The string returned by ctime() includes a newline,
253 * and we don't want that, so we use add_bytes_to_str.
254 * The string always has exactly 25 characters, so add
255 * 24 bytes: The length of the string, minus one for
256 * the newline. -- Miciah
258 add_bytes_to_string(&msg
, last_visit
, 24);
260 add_to_string(&msg
, _("Unknown", term
));
265 add_link_info_to_string(&msg
, ses
);
267 info_box(term
, MSGBOX_FREE_TEXT
| MSGBOX_SCROLLABLE
,
268 N_("Info"), ALIGN_LEFT
, msg
.source
);
272 cached_header_dialog(struct session
*ses
, struct cache_entry
*cached
)
274 int msgbox_flags
= 0;
275 unsigned char *title
= N_("Header info");
276 unsigned char *headers
= NULL
;
279 if (!cached
|| !cached
->head
|| !*cached
->head
)
280 goto display_headers
;
283 /* If |cached->head| starts with a newline, it has been
284 * internally generated, usually to give ELinks-generated
285 * documents (e.g., file:// directory listings) a MIME type
287 if (*cached
->head
== '\r')
288 title
= N_("Internal header info");
291 headers
= mem_alloc(strlen(cached
->head
) + 1);
292 if (!headers
) return;
294 /* Sanitize headers string. */
295 /* XXX: Do we need to check length and limit
296 * it to something reasonable? */
298 while (cached
->head
[i
]) {
299 /* Check for control chars. */
300 if (cached
->head
[i
] < ' '
301 && cached
->head
[i
] != '\n') {
302 /* Ignore '\r' but replace
303 * other control chars with
305 if (cached
->head
[i
] != '\r') {
310 headers
[j
] = cached
->head
[i
];
316 /* Ensure null termination. */
319 /* Remove any trailing newlines. */
320 while (j
&& headers
[--j
] == '\n')
324 mem_free_set(&headers
, NULL
);
329 headers
= N_("No header info.");
331 msgbox_flags
= MSGBOX_FREE_TEXT
| MSGBOX_SCROLLABLE
;
334 /* Headers info message box. */
335 info_box(ses
->tab
->term
, msgbox_flags
,
336 title
, ALIGN_LEFT
, headers
);
339 /* Headers info. message box. */
341 protocol_header_dialog(struct session
*ses
)
343 if (!have_location(ses
)) {
344 nowhere_box(ses
->tab
->term
, N_("Header info"));
348 if (ses
->doc_view
&& ses
->doc_view
->document
)
349 cached_header_dialog(ses
, ses
->doc_view
->document
->cached
);