1 /*
2 * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
3 * Copyright 2005 James Bursa <bursa@users.sourceforge.net>
4 * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
5 * Copyright 2005 Richard Wilson <info@tinct.net>
6 * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk>
7 * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
8 * Copyright 2014 Stephen Fryatt <stevef@netsurf-browser.org>
9 *
10 * This file is part of NetSurf, http://www.netsurf-browser.org/
11 *
12 * NetSurf is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2 of the License.
15 *
16 * NetSurf is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "utils/config.h"
26
27 #include <assert.h>
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <oslib/colourtrans.h>
32 #include <oslib/osfile.h>
33 #include <oslib/osgbpb.h>
34 #include <oslib/osspriteop.h>
35 #include <oslib/wimp.h>
36
37 #include "utils/nsoption.h"
38 #include "utils/log.h"
39 #include "utils/messages.h"
40 #include "utils/nsurl.h"
41 #include "desktop/version.h"
42 #include "desktop/searchweb.h"
43 #include "netsurf/browser_window.h"
44
45 #include "riscos/configure.h"
46 #include "riscos/cookies.h"
47 #include "riscos/dialog.h"
48 #include "riscos/local_history.h"
49 #include "riscos/global_history.h"
50 #include "riscos/gui.h"
51 #include "riscos/window.h"
52 #include "riscos/hotlist.h"
53 #include "riscos/pageinfo.h"
54 #include "riscos/menus.h"
55 #include "riscos/save.h"
56 #include "riscos/toolbar.h"
57 #include "riscos/url_complete.h"
58 #include "riscos/url_suggest.h"
59 #include "riscos/wimp.h"
60 #include "riscos/wimp_event.h"
61 #include "riscos/wimputils.h"
62
63 #define ICON_ZOOM_VALUE 1
64 #define ICON_ZOOM_DEC 2
65 #define ICON_ZOOM_INC 3
66 #define ICON_ZOOM_FRAMES 5
67 #define ICON_ZOOM_CANCEL 7
68 #define ICON_ZOOM_OK 8
69
70 /* The maximum number of persistent dialogues
71 */
72 #define MAX_PERSISTENT 64
73
74
75 wimp_w dialog_info, dialog_saveas,
76 dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip,
77 dialog_warning,
78 dialog_folder, dialog_entry, dialog_search, dialog_print,
79 dialog_url_complete, dialog_openurl;
80
81 struct gui_window *ro_gui_current_zoom_gui;
82
83
84 /* A simple mapping of parent and child
85 */
86 static struct {
87 wimp_w dialog;
88 wimp_w parent;
89 } persistent_dialog[MAX_PERSISTENT];
90
91
92 static bool ro_gui_dialog_open_url_init(void);
93 static bool ro_gui_dialog_openurl_apply(wimp_w w);
94 static bool ro_gui_dialog_open_url_menu_prepare(wimp_w w, wimp_i i,
95 wimp_menu *menu, wimp_pointer *pointer);
96
97 static bool ro_gui_dialog_zoom_apply(wimp_w w);
98
99 /**
100 * Load and create dialogs from template file.
101 */
102
ro_gui_dialog_init(void)103 void ro_gui_dialog_init(void)
104 {
105 /* warning dialog */
106 dialog_warning = ro_gui_dialog_create("warning");
107 ro_gui_wimp_event_register_ok(dialog_warning, ICON_WARNING_CONTINUE,
108 NULL);
109 ro_gui_wimp_event_set_help_prefix(dialog_warning, "HelpWarning");
110
111 /* tooltip for history */
112 dialog_tooltip = ro_gui_dialog_create("tooltip");
113
114 /* configure window */
115 ro_gui_configure_initialise();
116
117 /* theme installation */
118 dialog_theme_install = ro_gui_dialog_create("theme_inst");
119 ro_gui_wimp_event_register_cancel(dialog_theme_install,
120 ICON_THEME_INSTALL_CANCEL);
121 ro_gui_wimp_event_register_ok(dialog_theme_install,
122 ICON_THEME_INSTALL_INSTALL,
123 ro_gui_theme_install_apply);
124 ro_gui_wimp_event_set_help_prefix(dialog_theme_install, "HelpThemeInst");
125
126 /* search */
127 ro_gui_search_init();
128
129 /* print */
130 ro_gui_print_init();
131
132 /* about us */
133 dialog_info = ro_gui_dialog_create("info");
134 ro_gui_set_icon_string(dialog_info, 4, netsurf_version, true);
135 ro_gui_wimp_event_set_help_prefix(dialog_info, "HelpAppInfo");
136
137 /* page info */
138 dialog_pageinfo = ro_gui_dialog_create("pageinfo");
139 ro_gui_wimp_event_set_help_prefix(dialog_pageinfo, "HelpPageInfo");
140
141 /* object info */
142 dialog_objinfo = ro_gui_dialog_create("objectinfo");
143 ro_gui_wimp_event_set_help_prefix(dialog_objinfo, "HelpObjInfo");
144
145 /* save as */
146 dialog_saveas = ro_gui_saveas_create("saveas");
147 ro_gui_wimp_event_register_button(dialog_saveas, ICON_SAVE_ICON,
148 ro_gui_save_start_drag);
149 ro_gui_wimp_event_register_text_field(dialog_saveas, ICON_SAVE_PATH);
150 ro_gui_wimp_event_register_cancel(dialog_saveas, ICON_SAVE_CANCEL);
151 ro_gui_wimp_event_register_ok(dialog_saveas, ICON_SAVE_OK,
152 ro_gui_save_ok);
153 ro_gui_wimp_event_set_help_prefix(dialog_saveas, "HelpSaveAs");
154
155 /* url suggestion */
156 dialog_url_complete = ro_gui_dialog_create("url_suggest");
157 ro_gui_wimp_event_register_mouse_click(dialog_url_complete,
158 ro_gui_url_complete_click);
159 ro_gui_wimp_event_register_pointer_entering_window(dialog_url_complete,
160 ro_gui_url_complete_entering);
161 ro_gui_wimp_event_register_redraw_window(dialog_url_complete,
162 ro_gui_url_complete_redraw);
163 ro_gui_wimp_event_set_help_prefix(dialog_url_complete, "HelpAutoURL");
164
165 /* open URL */
166 ro_gui_dialog_open_url_init();
167
168 /* scale view */
169 dialog_zoom = ro_gui_dialog_create("zoom");
170 ro_gui_wimp_event_register_numeric_field(dialog_zoom, ICON_ZOOM_VALUE,
171 ICON_ZOOM_INC, ICON_ZOOM_DEC, 10, 1600, 10, 0);
172 ro_gui_wimp_event_register_checkbox(dialog_zoom, ICON_ZOOM_FRAMES);
173 ro_gui_wimp_event_register_cancel(dialog_zoom, ICON_ZOOM_CANCEL);
174 ro_gui_wimp_event_register_ok(dialog_zoom, ICON_ZOOM_OK,
175 ro_gui_dialog_zoom_apply);
176 ro_gui_wimp_event_set_help_prefix(dialog_zoom, "HelpScaleView");
177
178 /* core window based initialisation done last to allow any
179 * associated dialogues to be set up first.
180 */
181
182 /* hotlist window */
183 ro_gui_hotlist_initialise();
184
185 /* local history window */
186 ro_gui_local_history_initialise();
187
188 /* global history window */
189 ro_gui_global_history_initialise();
190
191 /* cookies window */
192 ro_gui_cookies_initialise();
193
194 /* page info window */
195 ro_gui_pageinfo_initialise();
196 }
197
198
199 /**
200 * Create a window from a template.
201 *
202 * \param template_name name of template to load
203 * \return window handle
204 *
205 * Exits through die() on error.
206 */
207
ro_gui_dialog_create(const char * template_name)208 wimp_w ro_gui_dialog_create(const char *template_name)
209 {
210 wimp_window *window;
211 wimp_w w;
212 os_error *error;
213
214 window = ro_gui_dialog_load_template(template_name);
215
216 /* create window */
217 window->sprite_area = gui_sprites;
218 error = xwimp_create_window(window, &w);
219 if (error) {
220 NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
221 error->errnum, error->errmess);
222 xwimp_close_template();
223 die(error->errmess);
224 }
225
226 /* the window definition is copied by the wimp and may be freed */
227 free(window);
228
229 return w;
230 }
231
232
233 /**
234 * Load a template without creating a window.
235 *
236 * \param template_name name of template to load
237 * \return window block
238 *
239 * Exits through die() on error.
240 */
241
ro_gui_dialog_load_template(const char * template_name)242 wimp_window * ro_gui_dialog_load_template(const char *template_name)
243 {
244 char name[20];
245 int context, window_size, data_size;
246 char *data;
247 wimp_window *window;
248 os_error *error;
249
250 /* Template names must be <= 11 chars long */
251 assert(strlen(template_name) <= 11);
252
253 /* wimp_load_template won't accept a const char * */
254 strncpy(name, template_name, sizeof name);
255
256 /* find required buffer sizes */
257 error = xwimp_load_template(wimp_GET_SIZE, 0, 0, wimp_NO_FONTS,
258 name, 0, &window_size, &data_size, &context);
259 if (error) {
260 NSLOG(netsurf, INFO, "xwimp_load_template: 0x%x: %s",
261 error->errnum, error->errmess);
262 xwimp_close_template();
263 die(error->errmess);
264 }
265 if (!context) {
266 NSLOG(netsurf, INFO, "template '%s' missing", template_name);
267 xwimp_close_template();
268 die("Template");
269 }
270
271 /* allocate space for indirected data and temporary window buffer */
272 data = malloc(data_size);
273 window = malloc(window_size);
274 if (!data || !window) {
275 xwimp_close_template();
276 die("NoMemory");
277 }
278
279 /* load template */
280 error = xwimp_load_template(window, data, data + data_size,
281 wimp_NO_FONTS, name, 0, 0, 0, 0);
282 if (error) {
283 NSLOG(netsurf, INFO, "xwimp_load_template: 0x%x: %s",
284 error->errnum, error->errmess);
285 xwimp_close_template();
286 die(error->errmess);
287 }
288
289 return window;
290 }
291
292
293 /**
294 * Open a dialog box, centred on the screen.
295 */
296
ro_gui_dialog_open(wimp_w w)297 void ro_gui_dialog_open(wimp_w w)
298 {
299 int screen_x, screen_y, dx, dy;
300 wimp_window_state state;
301 os_error *error;
302
303 /* find screen centre in os units */
304 ro_gui_screen_size(&screen_x, &screen_y);
305 screen_x /= 2;
306 screen_y /= 2;
307
308 /* centre and open */
309 state.w = w;
310 error = xwimp_get_window_state(&state);
311 if (error) {
312 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
313 error->errnum, error->errmess);
314 ro_warn_user("WimpError", error->errmess);
315 return;
316 }
317 dx = (state.visible.x1 - state.visible.x0) / 2;
318 dy = (state.visible.y1 - state.visible.y0) / 2;
319 state.visible.x0 = screen_x - dx;
320 state.visible.x1 = screen_x + dx;
321 state.visible.y0 = screen_y - dy;
322 state.visible.y1 = screen_y + dy;
323 state.next = wimp_TOP;
324 ro_gui_open_window_request(PTR_WIMP_OPEN(&state));
325
326 /* Set the caret position */
327 ro_gui_set_caret_first(w);
328 }
329
330
331 /**
332 * Close a dialog box.
333 */
334
ro_gui_dialog_close(wimp_w close)335 void ro_gui_dialog_close(wimp_w close)
336 {
337 int i;
338 wimp_caret caret;
339 wimp_w parent = (wimp_w)-1;
340 os_error *error;
341
342 /* Check if we're a persistent window */
343 for (i = 0; i < MAX_PERSISTENT; i++) {
344 if (persistent_dialog[i].dialog == close) {
345 /* We are => invalidate record */
346 if (persistent_dialog[i].parent != NULL) {
347 parent = persistent_dialog[i].parent;
348 }
349 persistent_dialog[i].parent = NULL;
350 persistent_dialog[i].dialog = NULL;
351 break;
352 }
353 }
354
355 /* Close any child windows */
356 ro_gui_dialog_close_persistent(close);
357
358 /* Give the caret back to the parent window. This code relies on
359 the fact that only tree windows and browser windows open
360 persistent dialogues, as the caret gets placed to no icon.
361 */
362 error = xwimp_get_caret_position(&caret);
363 if (error) {
364 NSLOG(netsurf, INFO, "xwimp_get_caret_position: 0x%x: %s",
365 error->errnum, error->errmess);
366 ro_warn_user("WimpError", error->errmess);
367 } else if (caret.w == close) {
368 /* Check if we are a persistent window */
369 if (i < MAX_PERSISTENT) {
370 error = xwimp_set_caret_position(
371 parent,
372 wimp_ICON_WINDOW, -100, -100,
373 32, -1);
374 /* parent may have been closed first */
375 if ((error) && (error->errnum != 0x287)) {
376 NSLOG(netsurf, INFO,
377 "xwimp_set_caret_position: 0x%x: %s",
378 error->errnum,
379 error->errmess);
380 ro_warn_user("WimpError", error->errmess);
381 }
382 }
383 }
384
385 error = xwimp_close_window(close);
386 if (error) {
387 NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
388 error->errnum, error->errmess);
389 ro_warn_user("WimpError", error->errmess);
390 }
391 }
392
393
394 /**
395 * Moves a window to the top of the stack.
396 *
397 * If the window is currently closed then:
398 *
399 * * The window is opened in the centre of the screen (at the supplied size)
400 * * Any toolbar editing session is stopped
401 * * The scroll position is set to the top of the window
402 *
403 * If the window is currently open then:
404 *
405 * * The window is brought to the top of the stack
406 *
407 * \param w the window to show
408 * \param toolbar the toolbar to consider
409 * \param width the window width if it is currently closed (or 0 to retain)
410 * \param height the window height if it is currently closed (or 0 to retain)
411 * \return true if the window was previously open
412 */
ro_gui_dialog_open_top(wimp_w w,struct toolbar * toolbar,int width,int height)413 bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar,
414 int width, int height) {
415 os_error *error;
416 int screen_width, screen_height;
417 wimp_window_state state;
418 bool open;
419
420 state.w = w;
421 error = xwimp_get_window_state(&state);
422 if (error) {
423 ro_warn_user("WimpError", error->errmess);
424 return false;
425 }
426
427 /* if we're open we jump to the top of the stack, if not then we
428 * open in the centre of the screen. */
429 open = state.flags & wimp_WINDOW_OPEN;
430 if (!open) {
431 int dimension;
432 int scroll_width;
433 /* cancel any editing */
434 if (ro_toolbar_get_editing(toolbar))
435 ro_toolbar_toggle_edit(toolbar);
436
437 /* move to the centre */
438 ro_gui_screen_size(&screen_width, &screen_height);
439 dimension = ((width == 0) ?
440 (state.visible.x1 - state.visible.x0) : width);
441 scroll_width = ro_get_vscroll_width(w);
442 state.visible.x0 = (screen_width - (dimension + scroll_width)) / 2;
443 state.visible.x1 = state.visible.x0 + dimension;
444 dimension = ((height == 0) ?
445 (state.visible.y1 - state.visible.y0) : height);
446 state.visible.y0 = (screen_height - dimension) / 2;
447 state.visible.y1 = state.visible.y0 + dimension;
448 state.xscroll = 0;
449 state.yscroll = 0;
450 if (toolbar)
451 state.yscroll = ro_toolbar_height(toolbar);
452 }
453
454 /* open the window at the top of the stack */
455 state.next = wimp_TOP;
456 ro_gui_open_window_request(PTR_WIMP_OPEN(&state));
457 return open;
458 }
459
460
461 /**
462 * Open window at the location of the pointer.
463 */
464
ro_gui_dialog_open_at_pointer(wimp_w w)465 void ro_gui_dialog_open_at_pointer(wimp_w w)
466 {
467 wimp_pointer ptr;
468 os_error *error;
469
470 /* get the pointer position */
471 error = xwimp_get_pointer_info(&ptr);
472 if (error) {
473 NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
474 error->errnum, error->errmess);
475 ro_warn_user("WimpError", error->errmess);
476 return;
477 }
478
479 ro_gui_dialog_open_xy(w, ptr.pos.x - 64, ptr.pos.y);
480 }
481
482
483 /**
484 * Open window at a specified location.
485 */
486
ro_gui_dialog_open_xy(wimp_w w,int x,int y)487 void ro_gui_dialog_open_xy(wimp_w w, int x, int y)
488 {
489 wimp_window_state state;
490 os_error *error;
491 int dx, dy;
492
493 /* move the window */
494 state.w = w;
495 error = xwimp_get_window_state(&state);
496 if (error) {
497 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
498 error->errnum, error->errmess);
499 ro_warn_user("WimpError", error->errmess);
500 return;
501 }
502 dx = (state.visible.x1 - state.visible.x0);
503 dy = (state.visible.y1 - state.visible.y0);
504 state.visible.x0 = x;
505 state.visible.x1 = x + dx;
506 state.visible.y0 = y - dy;
507 state.visible.y1 = y;
508
509 /* if the window is already open, close it first so that it opens fully
510 * on screen */
511 error = xwimp_close_window(w);
512 if (error) {
513 NSLOG(netsurf, INFO, "xwimp_close_window: 0x%x: %s",
514 error->errnum, error->errmess);
515 ro_warn_user("WimpError", error->errmess);
516 return;
517 }
518
519 /* open the window at the top of the stack */
520 state.next = wimp_TOP;
521 ro_gui_open_window_request(PTR_WIMP_OPEN(&state));
522 }
523
524
525 /**
526 * Opens a window at the centre of either another window or the screen
527 *
528 * /param parent the parent window (NULL for centre of screen)
529 * /param child the child window
530 */
ro_gui_dialog_open_centre_parent(wimp_w parent,wimp_w child)531 static void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child)
532 {
533 os_error *error;
534 wimp_window_state state;
535 int mid_x, mid_y;
536 int dimension, scroll_width;
537
538 /* get the parent window state */
539 if (parent) {
540 state.w = parent;
541 error = xwimp_get_window_state(&state);
542 if (error) {
543 NSLOG(netsurf, INFO,
544 "xwimp_get_window_state: 0x%x: %s",
545 error->errnum,
546 error->errmess);
547 ro_warn_user("WimpError", error->errmess);
548 return;
549 }
550 scroll_width = ro_get_vscroll_width(parent);
551 mid_x = (state.visible.x0 + state.visible.x1 + scroll_width);
552 mid_y = (state.visible.y0 + state.visible.y1);
553 } else {
554 ro_gui_screen_size(&mid_x, &mid_y);
555 }
556 mid_x /= 2;
557 mid_y /= 2;
558
559 /* get the child window state */
560 state.w = child;
561 error = xwimp_get_window_state(&state);
562 if (error) {
563 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
564 error->errnum, error->errmess);
565 ro_warn_user("WimpError", error->errmess);
566 return;
567 }
568
569 /* move to the centre of the parent at the top of the stack */
570 dimension = state.visible.x1 - state.visible.x0;
571 scroll_width = ro_get_vscroll_width(parent);
572 state.visible.x0 = mid_x - (dimension + scroll_width) / 2;
573 state.visible.x1 = state.visible.x0 + dimension;
574 dimension = state.visible.y1 - state.visible.y0;
575 state.visible.y0 = mid_y - dimension / 2;
576 state.visible.y1 = state.visible.y0 + dimension;
577 state.next = wimp_TOP;
578 ro_gui_open_window_request(PTR_WIMP_OPEN(&state));
579 }
580
581
582 /**
583 * Open a persistent dialog box relative to the pointer.
584 *
585 * \param parent the owning window (NULL for no owner)
586 * \param w the dialog window
587 * \param pointer open the window at the pointer (centre of the parent
588 * otherwise)
589 */
590
ro_gui_dialog_open_persistent(wimp_w parent,wimp_w w,bool pointer)591 void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer) {
592
593 if (pointer) {
594 ro_gui_dialog_open_at_pointer(w);
595 } else {
596 ro_gui_dialog_open_centre_parent(parent, w);
597 }
598
599 /* todo: use wimp_event definitions rather than special cases */
600 if ((w == dialog_pageinfo) || (w == dialog_objinfo))
601 ro_gui_wimp_update_window_furniture(w, wimp_WINDOW_CLOSE_ICON,
602 wimp_WINDOW_CLOSE_ICON);
603 ro_gui_dialog_add_persistent(parent, w);
604 ro_gui_set_caret_first(w);
605 }
606
607
ro_gui_dialog_add_persistent(wimp_w parent,wimp_w w)608 void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w) {
609 int i;
610
611 /* all persistant windows have a back icon */
612 ro_gui_wimp_update_window_furniture(w, wimp_WINDOW_BACK_ICON,
613 wimp_WINDOW_BACK_ICON);
614
615 /* Add a mapping
616 */
617 if ((parent == NULL) || (parent == wimp_ICON_BAR))
618 return;
619 for (i = 0; i < MAX_PERSISTENT; i++) {
620 if (persistent_dialog[i].dialog == NULL ||
621 persistent_dialog[i].dialog == w) {
622 persistent_dialog[i].dialog = w;
623 persistent_dialog[i].parent = parent;
624 return;
625 }
626 }
627 NSLOG(netsurf, INFO, "Unable to map persistent dialog to parent.");
628 return;
629 }
630
631
632 /**
633 * Close persistent dialogs associated with a window.
634 *
635 * \param parent the window to close children of
636 */
637
ro_gui_dialog_close_persistent(wimp_w parent)638 void ro_gui_dialog_close_persistent(wimp_w parent) {
639 int i;
640 wimp_w w;
641
642 /* Check our mappings.
643 *
644 * The window handle is copied into w before proceeding, as
645 * ro_gui_dialog_close() will NULL persistent_dialog[i].dialog as
646 * part of the closing process. This would mean that the subsequent
647 * event dispatch would fail. (These events are logged to allow
648 * side effects to be investigated -- this code hasn't worked before).
649 */
650 for (i = 0; i < MAX_PERSISTENT; i++) {
651 if (persistent_dialog[i].parent == parent &&
652 persistent_dialog[i].dialog != NULL) {
653 w = persistent_dialog[i].dialog;
654 ro_gui_dialog_close(w);
655 if (ro_gui_wimp_event_close_window(w))
656 NSLOG(netsurf, INFO,
657 "Persistent dialog close event: 0x%x",
658 (unsigned)w);
659 persistent_dialog[i].parent = NULL;
660 persistent_dialog[i].dialog = NULL;
661 }
662 }
663 }
664
665
666 /**
667 * Save the current options.
668 */
669
ro_gui_save_options(void)670 void ro_gui_save_options(void)
671 {
672 nsoption_write("<NetSurf$ChoicesSave>", NULL, NULL);
673 }
674
ro_gui_dialog_zoom_apply(wimp_w w)675 bool ro_gui_dialog_zoom_apply(wimp_w w)
676 {
677 unsigned int scale;
678
679 scale = atoi(ro_gui_get_icon_string(w, ICON_ZOOM_VALUE));
680 ro_gui_window_set_scale(ro_gui_current_zoom_gui, scale * 0.01);
681 return true;
682 }
683
684
685 /**
686 * Prepares the Scale view dialog.
687 */
688
ro_gui_dialog_prepare_zoom(struct gui_window * g)689 void ro_gui_dialog_prepare_zoom(struct gui_window *g)
690 {
691 char scale_buffer[8];
692 sprintf(scale_buffer, "%.0f", browser_window_get_scale(g->bw) * 100);
693 ro_gui_set_icon_string(dialog_zoom, ICON_ZOOM_VALUE, scale_buffer, true);
694 ro_gui_set_icon_selected_state(dialog_zoom, ICON_ZOOM_FRAMES, true);
695 ro_gui_set_icon_shaded_state(dialog_zoom, ICON_ZOOM_FRAMES, true);
696 ro_gui_current_zoom_gui = g;
697 ro_gui_wimp_event_memorise(dialog_zoom);
698 }
699
700 /**
701 * Update the Scale View dialog to reflect the current window settings
702 *
703 * \param g the gui_window to update for
704 */
ro_gui_dialog_update_zoom(struct gui_window * g)705 void ro_gui_dialog_update_zoom(struct gui_window *g) {
706 if (g == ro_gui_current_zoom_gui)
707 ro_gui_dialog_prepare_zoom(g);
708 }
709
710
711 /**
712 * Create the Open URL dialogue, allocating storage for the URL field icon
713 * as we go.
714 *
715 * \return true on success; false on failure (although errors with
716 * the templates or memory allocation will exit via die()).
717 */
718
ro_gui_dialog_open_url_init(void)719 static bool ro_gui_dialog_open_url_init(void)
720 {
721 wimp_window *definition;
722 char *buffer;
723 os_error *error;
724
725 definition = ro_gui_dialog_load_template("open_url");
726
727 /* _load_template() should die on any error, so we trust its data. */
728
729 assert(definition != NULL);
730
731 /* Create the dialogue, with modifications. */
732
733 if ((definition->icons[ICON_OPENURL_URL].flags & wimp_ICON_INDIRECTED)
734 == 0) {
735 NSLOG(netsurf, INFO, "open_url URL icon not indirected");
736 xwimp_close_template();
737 die("Template");
738 }
739
740 buffer = malloc(RO_GUI_MAX_URL_SIZE);
741 if (buffer == NULL) {
742 xwimp_close_template();
743 die("NoMemory");
744 }
745
746 definition->icons[ICON_OPENURL_URL].data.indirected_text.text = buffer;
747 definition->icons[ICON_OPENURL_URL].data.indirected_text.size =
748 RO_GUI_MAX_URL_SIZE;
749 definition->sprite_area = gui_sprites;
750
751 error = xwimp_create_window(definition, &dialog_openurl);
752 if (error != NULL) {
753 NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
754 error->errnum, error->errmess);
755 xwimp_close_template();
756 die(error->errmess);
757 }
758
759 free(definition);
760
761 ro_gui_wimp_event_register_menu_gright(dialog_openurl, ICON_OPENURL_URL,
762 ICON_OPENURL_MENU, ro_gui_url_suggest_menu);
763 ro_gui_wimp_event_register_cancel(dialog_openurl, ICON_OPENURL_CANCEL);
764 ro_gui_wimp_event_register_ok(dialog_openurl, ICON_OPENURL_OPEN,
765 ro_gui_dialog_openurl_apply);
766 ro_gui_wimp_event_register_menu_prepare(dialog_openurl,
767 ro_gui_dialog_open_url_menu_prepare);
768 ro_gui_wimp_event_set_help_prefix(dialog_openurl, "HelpOpenURL");
769
770 return true;
771 }
772
773
774
ro_gui_dialog_openurl_apply(wimp_w w)775 bool ro_gui_dialog_openurl_apply(wimp_w w)
776 {
777 nserror res;
778 const char *url_s;
779 nsurl *url;
780
781 url_s = ro_gui_get_icon_string(w, ICON_OPENURL_URL);
782
783 res = search_web_omni(url_s, SEARCH_WEB_OMNI_NONE, &url);
784
785 if (res == NSERROR_OK) {
786 res = browser_window_create(BW_CREATE_HISTORY,
787 url,
788 NULL,
789 NULL,
790 NULL);
791 nsurl_unref(url);
792 }
793
794 if (res != NSERROR_OK) {
795 ro_warn_user(messages_get_errorcode(res), 0);
796 return false;
797 }
798
799 return true;
800 }
801
802
803 /**
804 * Prepares the Open URL dialog.
805 */
806
ro_gui_dialog_prepare_open_url(void)807 void ro_gui_dialog_prepare_open_url(void)
808 {
809 ro_gui_set_icon_string(dialog_openurl, ICON_OPENURL_URL, "", true);
810 ro_gui_set_icon_shaded_state(dialog_openurl,
811 ICON_OPENURL_MENU, !ro_gui_url_suggest_prepare_menu());
812 ro_gui_wimp_event_memorise(dialog_openurl);
813 }
814
815
816 /**
817 * Callback to prepare menus in the Open URL dialog. At present, this
818 * only has to handle the URL Suggestion pop-up.
819 *
820 * \param w The window handle owning the menu.
821 * \param i The icon handle owning the menu.
822 * \param *menu The menu to be prepared.
823 * \param *pointer The associated mouse click event block, or NULL
824 * on an Adjust-click re-opening.
825 * \return true if the event was handled; false if not.
826 */
827
ro_gui_dialog_open_url_menu_prepare(wimp_w w,wimp_i i,wimp_menu * menu,wimp_pointer * pointer)828 bool ro_gui_dialog_open_url_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
829 wimp_pointer *pointer)
830 {
831 if (menu != ro_gui_url_suggest_menu || i != ICON_OPENURL_MENU)
832 return false;
833
834 if (pointer != NULL)
835 return ro_gui_url_suggest_prepare_menu();
836
837 return true;
838 }
839