/* Copyright 1997 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /***************************************************/ /* File : Choices.c */ /* */ /* Purpose: Functions relating to the choices */ /* dialogue box and associated sub */ /* windows */ /* */ /* Author : D.T.A.Brown */ /* */ /* History: 23-Sep-97: Created. */ /***************************************************/ #include <stdlib.h> #include <string.h> #include "swis.h" #include "HTMLLib.h" /* HTML library API, Which will include html2_ext.h, tags.h and struct.h */ #include "wimp.h" #include "wimplib.h" #include "event.h" #include "toolbox.h" #include "window.h" #include "menu.h" #include "ColourDbox.h" #include "FontMenu.h" #include "svcprint.h" #include "Global.h" #include "FromROSLib.h" #include "Utils.h" #include "Encoding.h" #include "FetchPage.h" #include "FontManage.h" #include "History.h" #include "Limits.h" #include "Menus.h" #include "NestWimp.h" #include "Redraw.h" #include "Reformat.h" #include "Save.h" #include "URLutils.h" #include "Windows.h" #include "Choices.h" /* Local compile-time options */ #define CREATE_ONLY_ONCE /* Locals */ static char consonant[] = "bcdfghjklmnpqrstvwxyz"; static char vowel[] = "aeiou"; static int rubbish_seed; /* Used to prevent rounding errors when converting to/from font 16ths of a point to decimal */ static unsigned char todecimal [] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9}; static unsigned char fromdecimal[] = {0, 2, 4, 5, 7, 8, 10, 12, 13, 15}; static ObjectId * subwindows = NULL; static int current_subwindow = 0; static ObjectId colourdbox_id = 0; static int save_ticked = -1; static int disp_ticked = -1; static int plug_ticked = -1; static int time_ticked = -1; static int bord_ticked = -1; static int history_radio = 0; /* 0 - page history, 1 - image history */ static int expiry_age_greyed = 0; static int max_size_greyed = 0; static int image_expiry_age_greyed = 0; static int image_max_size_greyed = 0; static int image_expiry_units = -1; static int history_expiry_units = -1; static int choices_modechanged = 0; static fm_typeface * new_typefaces = NULL; #ifdef CREATE_ONLY_ONCE static int objects_created = 0; #endif /* Static function prototypes */ static _kernel_oserror * choices_show_subwindow (ObjectId choices_window, int subwindow); static _kernel_oserror * choices_set_contents (void); static _kernel_oserror * choices_get_contents (void); static void choices_set_expiry_age (ObjectId window); static void choices_set_expiry_age_greyed (ObjectId window, int state); static void choices_set_tables_greyed (int state, ObjectId window); static _kernel_oserror * choices_set_table_border_field (ObjectId obj, ComponentId comp, int state); static void choices_set_fonts_greyed (ObjectId window, int state); static void choices_set_max_size (ObjectId window); static void choices_set_max_size_greyed (ObjectId window, int state); static void choices_set_im_max_size (ObjectId window); static void choices_set_im_max_size_greyed (ObjectId window, int state); int choices_clip_to_min_max (int value, int min, int max); static void choices_set_im_expiry_age (ObjectId window); static void choices_set_im_expiry_age_greyed (ObjectId window, int state); _kernel_oserror * choices_set_timetype_tick (int timetype); _kernel_oserror * choices_set_timetype_field (int timetype, ComponentId comp); static void choices_modified_font (char * orig, char * mod, char * buffer); static int choices_radio_click_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_set_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_cancel_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_save_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_encoding_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_colour_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_colour_closed_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_colour_selected_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_display_m_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_save_m_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_display_m_click_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_save_m_click_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_option_state_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_font_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_font_closed_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_font_selected_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_redraw_fakepage_handler (int eventcode, WimpPollBlock * event, IdBlock * id_block, void * handle); static int choices_open_choice_window (int eventcode, WimpPollBlock * event, IdBlock * id_block, void * handle); static int choices_plug_m_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_plug_m_click_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_timetype_m_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_timetype_m_click_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_bord_m_button_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_bord_m_click_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int choices_history_radio_handler (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static _kernel_oserror * choices_colour_set_component (ObjectId window, ComponentId component, int colour); static _kernel_oserror * choices_set_save_field (ObjectId obj, ComponentId comp, int state); static _kernel_oserror * choices_set_display_field (ObjectId obj, ComponentId comp, int state); static ObjectId choices_find_component (ComponentId component); _kernel_oserror * choices_get_menu_entry_text (char * menuname, ComponentId compid, char ** tempstring); static _kernel_oserror * choices_displayfield_set_value (unsigned int flags, ObjectId window, ComponentId writable, char *text); static _kernel_oserror * choices_writablefield_set_value (unsigned int flags, ObjectId window, ComponentId writable, char *text); static _kernel_oserror * choices_button_set_validation (unsigned int flags, ObjectId window, ComponentId writable, char *text); static _kernel_oserror * choices_numberrange_set_value (unsigned int flags, ObjectId window, ComponentId writable, int value); static int choices_return_appropriate_timetype (int seconds); static int choices_seconds_to_typed_time (int secs, int timetype); static int choices_typed_time_to_seconds (int time, int timetype); static int choices_get_range_of_typed_time (int time); /*************************************************/ /* choices_show_subwindow() */ /* */ /* Shows a choice subwindow in the main choices */ /* window. � */ /* */ /* Parameters: the ObjectId of the main choices */ /* window */ /* */ /* the number of the subwindow to */ /* show. Defined in choices.h */ /* Use CDSubNone to remove */ /* the current subwindow. */ /* */ /* Returns: pointer to _kernel_oserror */ /*************************************************/ static _kernel_oserror * choices_show_subwindow(ObjectId choices_window, int subwindow) { _kernel_oserror * e; WindowShowObjectBlock show_block; WimpGetWindowStateBlock state; WimpGetWindowOutlineBlock outline; int window_handle; int vwidth, hheight; if (current_subwindow != CDSubNone && current_subwindow != subwindow) { /* remove the current subwindow */ RetError(toolbox_hide_object(0, subwindows[current_subwindow])); current_subwindow = CDSubNone; } if (subwindow == CDSubNone || !(subwindows[subwindow])) { /* Have not been asked to open a new subwindow */ return NULL; } RetError(window_get_wimp_handle(0, choices_window, &window_handle)); state.window_handle = window_handle; RetError(wimp_get_window_state(&state)); RetError(gadget_get_bbox(0, choices_window, CDPlaceHolder, &show_block.visible_area)); windows_return_tool_sizes(NULL, &hheight, &vwidth); show_block.visible_area.xmin = coords_x_toscreen(show_block.visible_area.xmin, (WimpRedrawWindowBlock *) &state); show_block.visible_area.xmax = coords_x_toscreen(show_block.visible_area.xmax, (WimpRedrawWindowBlock *) &state); show_block.visible_area.ymin = coords_y_toscreen(show_block.visible_area.ymin, (WimpRedrawWindowBlock *) &state); show_block.visible_area.ymax = coords_y_toscreen(show_block.visible_area.ymax, (WimpRedrawWindowBlock *) &state); /* Adjustments for different types of window */ #ifdef TRACE if (tl & (1u<<29)) Printf("choices_show_subwindow: Wimp flags = %x\n", state.flags); #endif RetError(window_get_wimp_handle(0, subwindows[subwindow], &state.window_handle)); RetError(wimp_get_window_state(&state)); if (state.flags & WimpWindow_VScroll) show_block.visible_area.xmax -= vwidth; else vwidth = 0; if (state.flags & WimpWindow_HScroll) show_block.visible_area.ymin += hheight; else hheight = 0; show_block.xscroll = 0; show_block.yscroll = 0; show_block.behind = -1; show_block.window_flags = 0; show_block.alignment_flags = 0; /* Requires wimp handle just to be awkward */ show_block.parent_window_handle = window_handle; RetError(toolbox_show_object(Toolbox_ShowObject_AsSubWindow, subwindows[subwindow], Toolbox_ShowObject_FullSpec, &show_block, choices_window, -1)); outline.window_handle = state.window_handle; wimp_get_window_outline(&outline); if (outline.outline.xmin < show_block.visible_area.xmin) { show_block.visible_area.xmin += (show_block.visible_area.xmin - outline.outline.xmin); } if (outline.outline.ymin < (show_block.visible_area.ymin - hheight)) { show_block.visible_area.ymin += (show_block.visible_area.ymin - outline.outline.ymin); } if (outline.outline.xmax > (show_block.visible_area.xmax + vwidth)) { show_block.visible_area.xmax -= (outline.outline.xmax - show_block.visible_area.xmax); } if (outline.outline.ymax > show_block.visible_area.ymax) { show_block.visible_area.ymax -= (outline.outline.ymax - show_block.visible_area.ymax); } e = toolbox_show_object(Toolbox_ShowObject_AsSubWindow, subwindows[subwindow], Toolbox_ShowObject_FullSpec, &show_block, choices_window, -1); if (!e) current_subwindow = subwindow; return e; } /*************************************************/ /* choices_to_be_shown() */ /* */ /* Called when the ECDToBeShown event is */ /* generated. */ /* */ /* Creates all the subwindow dialogues and fills */ /* them in with appropriate values. */ /* Registers all additional event handlers used */ /* while the choices dialogue is visible. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int choices_to_be_shown(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; ObjectId window; int subwindow_tobeshown; #ifdef TRACE if (tl & (1u<<29)) Printf("choices_to_be_shown: Called\n"); #endif /* In multiuser builds, need to be logged in - otherwise, close */ /* the dialogue! */ #ifndef SINGLE_USER if (!logged_in) { toolbox_hide_object(0, idb->self_id); return 1; } #endif if (choices_windowid) return 1; _swix(OS_ReadMonotonicTime, _OUT(0), &rubbish_seed); choices_windowid = idb->self_id; /* Allocate block for holding subwindows ObjectIds */ if (!subwindows) { subwindows = malloc(sizeof(ObjectId)*CDNoSubwindows); /* If hide object doesn't work, things are really screwed */ if (!subwindows) { ChkError(toolbox_hide_object(0, idb->self_id)); return 1; } } if (!new_choices) { new_choices = malloc(sizeof(global_choices)); if (!new_choices) { ChkError(toolbox_hide_object(0, idb->self_id)); return 1; } else { memcpy(new_choices, &choices, sizeof(global_choices)); } } if (!new_typefaces) { new_typefaces = calloc(sizeof(fm_typeface), 3); if (!new_typefaces) { free(new_choices); new_choices = NULL; free(subwindows); subwindows = NULL; } else { fm_typeface * tfptr; tfptr = fm_find_typeface("serif"); memcpy(&new_typefaces[0], tfptr, sizeof(fm_typeface)); tfptr = fm_find_typeface("sans"); memcpy(&new_typefaces[1], tfptr, sizeof(fm_typeface)); tfptr = fm_find_typeface("fixed"); memcpy(&new_typefaces[2], tfptr, sizeof(fm_typeface)); } } /* Create all choices subwindows. Set their ObjectIds to NULL if they cannot be created */ /* Might be worth changing this to a loop in the future */ #ifdef CREATE_ONLY_ONCE if (!objects_created) { #endif e = toolbox_create_object(0, "ChSub0", &subwindows[0]); if (e) subwindows[0] = NULL; e = toolbox_create_object(0, "ChSub1", &subwindows[1]); if (e) subwindows[1] = NULL; e = toolbox_create_object(0, "ChSub2", &subwindows[2]); if (e) subwindows[2] = NULL; e = toolbox_create_object(0, "ChSub3", &subwindows[3]); if (e) subwindows[3] = NULL; e = toolbox_create_object(0, "ChSub4", &subwindows[4]); if (e) subwindows[4] = NULL; e = toolbox_create_object(0, "ChSub5", &subwindows[5]); if (e) subwindows[5] = NULL; e = toolbox_create_object(0, "ChSub6", &subwindows[6]); if (e) subwindows[6] = NULL; e = toolbox_create_object(0, "ChSub7", &subwindows[7]); if (e) subwindows[7] = NULL; e = toolbox_create_object(0, "ChSub8", &subwindows[8]); if (e) subwindows[8] = NULL; #ifdef CREATE_ONLY_ONCE } #endif subwindow_tobeshown = current_subwindow; current_subwindow = CDSubNone; ChkError(choices_show_subwindow(idb->self_id, subwindow_tobeshown)); ChkError(radiobutton_set_state(0, idb->self_id, CDFirstSubRadio + subwindow_tobeshown, 1)); ChkError(choices_set_contents()); /* Register choices event handlers. Make sure any additions here */ /* are matched in the deregistration section below, and add to */ /* choices_hidden. */ #ifdef CREATE_ONLY_ONCE e = NULL; if (!objects_created) { #endif e = event_register_toolbox_handler(-1, ECDRG2, choices_radio_click_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, CDSet, choices_set_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, CDCancel, choices_cancel_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, CDSaveButton, choices_save_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_EncodingMenuBt, choices_encoding_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_ColourButton, choices_colour_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_HlDispBt, choices_display_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_HiDispBt, choices_display_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_HlSaveBt, choices_save_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_HiSaveBt, choices_save_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECDSaveMenuClick, choices_save_m_click_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECDDispMenuClick, choices_display_m_click_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECDHiRadioClick, choices_history_radio_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, OptionButton_StateChanged, choices_option_state_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_FontButton, choices_font_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_ObjPlugBt, choices_plug_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECDPlugMenuClick, choices_plug_m_click_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_HiAgeTypeBt, choices_timetype_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECDTimeMenuClick, choices_timetype_m_click_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_TabInnerBordBt, choices_bord_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECD_TabOuterBordBt, choices_bord_m_button_handler, NULL); if (!e) e = event_register_toolbox_handler(-1, ECDBordMenuClick, choices_bord_m_click_handler, NULL); if ((window = choices_find_component(CD_FakePage)) != 0) { if (!e) e = event_register_wimp_handler(window, Wimp_ERedrawWindow, choices_redraw_fakepage_handler, NULL); } if (!e) e = event_register_wimp_handler(idb->self_id, Wimp_EOpenWindow, choices_open_choice_window, NULL); #ifdef CREATE_ONLY_ONCE } #endif /* Deal with errors */ if (e) { event_deregister_toolbox_handler(-1, ECDRG2, choices_radio_click_handler, NULL); event_deregister_toolbox_handler(-1, CDSet, choices_set_button_handler, NULL); event_deregister_toolbox_handler(-1, CDCancel, choices_cancel_button_handler, NULL); event_deregister_toolbox_handler(-1, CDSaveButton, choices_save_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_EncodingMenuBt, choices_encoding_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_ColourButton, choices_colour_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HlDispBt, choices_display_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HiDispBt, choices_display_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HlSaveBt, choices_save_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HiSaveBt, choices_save_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDSaveMenuClick, choices_save_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECDDispMenuClick, choices_display_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECDHiRadioClick, choices_history_radio_handler, NULL); event_deregister_toolbox_handler(-1, OptionButton_StateChanged, choices_option_state_handler, NULL); event_deregister_toolbox_handler(-1, ECD_FontButton, choices_font_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_ObjPlugBt, choices_plug_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDPlugMenuClick, choices_plug_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HiAgeTypeBt, choices_timetype_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDTimeMenuClick, choices_timetype_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECD_TabInnerBordBt, choices_bord_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_TabOuterBordBt, choices_bord_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDBordMenuClick, choices_bord_m_click_handler, NULL); if ((window = choices_find_component(CD_FakePage)) != 0) { event_deregister_wimp_handler(window, Wimp_ERedrawWindow, choices_redraw_fakepage_handler, NULL); } event_deregister_wimp_handler(idb->self_id, Wimp_EOpenWindow, choices_open_choice_window, NULL); ChkError(e); } #ifdef CREATE_ONLY_ONCE objects_created = 1; #endif return 1; } #ifndef CREATE_ONLY_ONCE /*************************************************/ /* choices_delete_subwindows() */ /* */ /* Deletes all subwindows, reports any and all */ /* errors occuring while deleting them. */ /* Frees the structure holding the subwindows. */ /*************************************************/ static void choices_delete_subwindows(void) { _kernel_oserror *e; int count; for(count = 0; count < CDNoSubwindows; count++) { if (subwindows[count]) { e = toolbox_delete_object(0, subwindows[count]); if (e) show_error_ret(e); subwindows[count] = 0; } } free(subwindows); subwindows = NULL; } #endif /*************************************************/ /* choices_hidden() */ /* */ /* Called when the ECDHidden event is generated. */ /* Deletes all the subwindow dialogues. */ /* Deregisters all additional event handlers */ /* used while the choices dialogue is visible. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int choices_hidden(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror * e; #ifndef CREATE_ONLY_ONCE ObjectId window; #endif int temp; temp = current_subwindow; /* Close subwindow */ e = choices_show_subwindow(idb->self_id, CDSubNone); if (e) show_error_ret(e); #ifndef CREATE_ONLY_ONCE /* Delete all subwindow objects */ choices_delete_subwindows(); free(new_choices); new_choices = NULL; free(new_typefaces); new_typefaces = NULL; /* Deregister choices event handlers */ event_deregister_toolbox_handler(-1, ECDRG2, choices_radio_click_handler, NULL); event_deregister_toolbox_handler(-1, CDSet, choices_set_button_handler, NULL); event_deregister_toolbox_handler(-1, CDCancel, choices_cancel_button_handler, NULL); event_deregister_toolbox_handler(-1, CDSaveButton, choices_save_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_EncodingMenuBt, choices_encoding_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_ColourButton, choices_colour_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HlDispBt, choices_display_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HiDispBt, choices_display_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HlSaveBt, choices_save_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HiSaveBt, choices_save_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDSaveMenuClick, choices_save_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECDDispMenuClick, choices_display_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECDHiRadioClick, � choices_history_radio_handler, NULL); event_deregister_toolbox_handler(-1, OptionButton_StateChanged, choices_option_state_handler, NULL); event_deregister_toolbox_handler(-1, ECD_FontButton, choices_font_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_ObjPlugBt, choices_plug_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDPlugMenuClick, choices_plug_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECD_HiAgeTypeBt, choices_timetype_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDTimeMenuClick, choices_timetype_m_click_handler, NULL); event_deregister_toolbox_handler(-1, ECD_TabInnerBordBt, choices_bord_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECD_TabOuterBordBt, choices_bord_m_button_handler, NULL); event_deregister_toolbox_handler(-1, ECDBordMenuClick, choices_bord_m_click_handler, NULL); if ((window = choices_find_component(CD_FakePage)) != 0) { event_deregister_wimp_handler(window, Wimp_ERedrawWindow, choices_redraw_fakepage_handler, NULL); } event_deregister_wimp_handler(idb->self_id, Wimp_EOpenWindow, choices_open_choice_window, NULL); #endif choices_windowid = 0; current_subwindow = temp; return 1; } /*************************************************/ /* choices_radio_click_handler() */ /* */ /* Shows the appropriate subwindow when a radio */ /* button in the choices dialogue is clicked on */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int choices_radio_click_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { int window, state; radiobutton_get_state(0, idb->self_id, idb->self_component, &state, NULL); /* Is this a radiobutton selected event? */ if (state) { window = idb->self_component - CDFirstSubRadio; if (window > CDNoSubwindows) window = CDSubNone; choices_show_subwindow(idb->self_id, window); } return 1; } /*************************************************/ /* choices_set_contents() */ /* */ /* Sets the contents of all choices subwindows */ /* to reflect the current state of the global */ /* choices. */ /* */ /* Returns: pointer to _kernel_oserror. */ /*************************************************/ static _kernel_oserror * choices_set_contents(void) { ObjectId window; unsigned int temp, frac; /* No error handling here, as we want to allow items to be missing */ if ((window = choices_find_component(CD_Homepage)) != 0) choices_writablefield_set_value(0, window, CD_Homepage, new_choices->home_page); if ((window = choices_find_component(CD_UnderlineLinks)) != 0) optionbutton_set_state(0, window, CD_UnderlineLinks, new_choices->underline_links); if ((window = choices_find_component(CD_UseDocColours)) != 0) optionbutton_set_state(0, window, CD_UseDocColours, new_choices->use_source_cols); if ((window = choices_find_component(CD_ShowForeground)) != 0) optionbutton_set_state(0, window, CD_ShowForeground, new_choices->show_foreground); if ((window = choices_find_component(CD_ShowBackground)) != 0) optionbutton_set_state(0, window, CD_ShowBackground, new_choices->show_background); /* Get encoding name */ choices_set_encoding_field(); if ((window = choices_find_component(CD_URLBar)) != 0) optionbutton_set_state(0, window, CD_URLBar, new_choices->url_bar); if ((window = choices_find_component(CD_StatusBar)) != 0) optionbutton_set_state(0, window, CD_StatusBar, new_choices->status_bar); if ((window = choices_find_component(CD_ButtonBar)) != 0) optionbutton_set_state(0, window, CD_ButtonBar , new_choices->button_bar); if ((window = choices_find_component(CD_FullScreen)) != 0) optionbutton_set_state(0, window, CD_FullScreen, new_choices->full_screen); if ((window = choices_find_component(CD_BackColour)) != 0) choices_colour_set_component(window, CD_BackColour, new_choices->background_colour); if ((window = choices_find_component(CD_TextColour)) != 0) choices_colour_set_component(window, CD_TextColour, new_choices->text_colour); if ((window = choices_find_component(CD_LinkColour)) != 0) choices_colour_set_component(window, CD_LinkColour, new_choices->link_colour); if ((window = choices_find_component(CD_UsedColour)) != 0) choices_colour_set_component(window, CD_UsedColour, new_choices->used_colour); if ((window = choices_find_component(CD_FolwColour)) != 0) choices_colour_set_component(window, CD_FolwColour, new_choices->followed_colour); if ((window = choices_find_component(CD_SlctColour)) != 0) choices_colour_set_component(window, CD_SlctColour, new_choices->selected_colour); if ((window = choices_find_component(CD_HlAutoOpen)) != 0) choices_numberrange_set_value(0, window, CD_HlAutoOpen, new_choices->auto_open_delay); if ((window = choices_find_component(CD_HlAutoScroll)) != 0) choices_numberrange_set_value(0, window, CD_HlAutoScroll, new_choices->auto_scroll_delay); if ((window = choices_find_component(CD_HlDispDisp)) != 0) choices_set_display_field(window, CD_HlDispDisp, new_choices->hotlist_show); if ((window = choices_find_component(CD_HlSaveDisp)) != 0) choices_set_save_field( window, CD_HlSaveDisp, new_choices->save_hotlist); if ((window = choices_find_component(CD_HiExpiryAge)) != 0) choices_set_expiry_age(window); if ((window = choices_find_component(CD_HiMaxSize)) != 0) choices_set_max_size(window); if ((window = choices_find_component(CD_HiDispDisp)) != 0) choices_set_display_field(window, CD_HiDispDisp, new_choices->show_urls); if ((window = choices_find_component(CD_HiSaveDisp)) != 0) choices_set_save_field( window, CD_HiSaveDisp, new_choices->save_history); if ((window = choices_find_component(CD_HiImExpiryAge)) != 0) choices_set_im_expiry_age(window); if ((window = choices_find_component(CD_HiImMaxSize)) != 0) choices_set_im_max_size(window); if (history_radio) { if ((window = choices_find_component(CD_HiRadImage)) != 0) radiobutton_set_state(0, window, CD_HiRadImage, 1); } else { if ((window = choices_find_component(CD_HiRadPage)) != 0) radiobutton_set_state(0, window, CD_HiRadPage, 1); } if ((window = choices_find_component(CD_ClientPull)) != 0) optionbutton_set_state(0, window, CD_ClientPull, new_choices->client_pull); if ((window = choices_find_component(CD_NetscapeEmu)) != 0) optionbutton_set_state(0, window, CD_NetscapeEmu, new_choices->clone); if ((window = choices_find_component(CD_FramesSupport)) != 0) optionbutton_set_state(0, window, CD_FramesSupport, new_choices->support_frames); if ((window = choices_find_component(CD_FontsSystem)) != 0) { optionbutton_set_state(0, window, CD_FontsSystem, new_choices->system_font); choices_set_fonts_greyed(window, new_choices->system_font); /*set_gadget_state(window, CD_FontsGroup1, new_choices->system_font);*/ } if ((window = choices_find_component(CD_FontsTF1Disp)) != 0) choices_displayfield_set_value(0, window, CD_FontsTF1Disp, new_typefaces[0].fontnames[0]); if ((window = choices_find_component(CD_FontsTF2Disp)) != 0) choices_displayfield_set_value(0, window, CD_FontsTF2Disp, new_typefaces[1].fontnames[0]); if ((window = choices_find_component(CD_FontsTF3Disp)) != 0) choices_displayfield_set_value(0, window, CD_FontsTF3Disp, new_typefaces[2].fontnames[0]); temp = new_choices->font_size; frac = (temp & 0xf); temp = ((temp >> 4) * 10) + todecimal[frac]; if ((window = choices_find_component(CD_FontsSize)) != 0) choices_numberrange_set_value(0, window, CD_FontsSize, temp); if ((window = choices_find_component(CD_FontsAspect)) != 0) choices_numberrange_set_value(0, window, CD_FontsAspect, new_choices->tt_aspect); if ((window = choices_find_component(CD_ObjHandle)) != 0) optionbutton_set_state(0, window, CD_ObjHandle, new_choices->support_object); if ((window = choices_find_component(CD_ObjPlugDisp)) != 0) { set_gadget_state(window, CD_ObjPlugLabl, !new_choices->support_object); set_gadget_state(window, CD_ObjPlugBt, !new_choices->support_object); set_gadget_state(window, CD_ObjPlugDisp, !new_choices->support_object); choices_set_plugin_field(); } if ((window = choices_find_component(CD_TabSupport)) != 0) { optionbutton_set_state(0, window, CD_TabSupport, new_choices->support_tables); choices_set_tables_greyed(!new_choices->support_tables,window); } if ((window = choices_find_component(CD_TabInnerBordDisp)) != 0) { choices_set_table_border_field(window, CD_TabInnerBordDisp, new_choices->table_inner); } if ((window = choices_find_component(CD_TabOuterBordDisp)) != 0) { choices_set_table_border_field(window, CD_TabOuterBordDisp, new_choices->table_outer); } if ((window = choices_find_component(CD_NetUseProxy)) != 0) optionbutton_set_state(0, window, CD_NetUseProxy, new_choices->use_proxy); if ((window = choices_find_component(CD_NetProxyAddr)) != 0) { set_gadget_state(window, CD_NetProxyAddr, !new_choices->use_proxy); set_gadget_state(window, CD_NetProxyLabl, !new_choices->use_proxy); choices_writablefield_set_value(0, window, CD_NetProxyAddr, new_choices->proxy_address); } if ((window = choices_find_component(CD_NetLaunchProxy)) != 0) optionbutton_set_state(0, window, CD_NetLaunchProxy, new_choices->start_proxy); if ((window = choices_find_component(CD_NetMaxImageFetch)) != 0) choices_numberrange_set_value(0, window, CD_NetMaxImageFetch, new_choices->maximages); return NULL; } /*************************************************/ /* choices_get_contents() */ /* */ /* Sets the state of the global choices to */ /* reflect the contents of all the choices */ /* subwindows. */ /*************************************************/ static _kernel_oserror * choices_get_contents(void) { _kernel_oserror * e; WimpGetWindowStateBlock s; browser_data * b; ObjectId window; char * tempstring; int reqsize; fm_typeface * tfptr; int serif_changed = 0; int sans_changed = 0; int fixed_changed = 0; int needs_redraw = 0; int colours_changed = 0; int old_font_size, old_system_font, frac; int temp; /* The lack of error checking is to allow */ /* items to be missing from the dialogue. */ if ((window = choices_find_component(CD_Homepage)) != 0) { e = writablefield_get_value(0, window, CD_Homepage, NULL, 0, &reqsize); if (!e) { tempstring = malloc(reqsize + 1); if (tempstring) { e = writablefield_get_value(0, window, CD_Homepage, tempstring, reqsize, NULL); if (!e) { if (!strcmp(tempstring, new_choices->home_page)) { free(tempstring); } else { free(new_choices->home_page); new_choices->home_page = tempstring; } } } else { show_error_ret(make_no_memory_error(17)); } } } if ((window = choices_find_component(CD_HlAutoOpen)) != 0) numberrange_get_value(0, window, CD_HlAutoOpen, &new_choices->auto_open_delay); if ((window = choices_find_component(CD_HlAutoScroll)) != 0) numberrange_get_value(0, window, CD_HlAutoScroll, &new_choices->auto_scroll_delay); if (expiry_age_greyed) { if (history_radio) new_choices->image_expiry_age = 0; else new_choices->expiry_age = 0; } else { if ((window = choices_find_component(CD_HiExpiryAge)) != 0) { numberrange_get_value(0, window, CD_HiExpiryAge, &temp); if (history_radio) new_choices->image_expiry_age = choices_typed_time_to_seconds(temp, history_expiry_units); else new_choices->expiry_age = choices_typed_time_to_seconds(temp, history_expiry_units); } } if (max_size_greyed) { if (history_radio) new_choices->image_max_size = 0; else new_choices->max_size = 0; } else { if ((window = choices_find_component(CD_HiMaxSize)) != 0) { numberrange_get_value(0, window, CD_HiMaxSize, &temp); if (history_radio) new_choices->image_max_size = temp * 1024; else new_choices->max_size = temp * 1024; } } if (image_expiry_age_greyed) { new_choices->image_expiry_age = 0; } else { if ((window = choices_find_component(CD_HiImExpiryAge)) != 0) { numberrange_get_value(0, window, CD_HiImExpiryAge, &temp); new_choices->image_expiry_age = choices_typed_time_to_seconds(temp, image_expiry_units); } } if (image_max_size_greyed) { new_choices->image_max_size = 0; } else { if ((window = choices_find_component(CD_HiImMaxSize)) != 0) { numberrange_get_value(0, window, CD_HiImMaxSize, &temp); new_choices->image_max_size = temp * 1024; } } if ((window = choices_find_component(CD_NetProxyAddr)) != 0) { e = writablefield_get_value(0, window, CD_NetProxyAddr, NULL, 0, &reqsize); if (!e) { tempstring = malloc(reqsize + 1); if (tempstring) { e = writablefield_get_value(0, window, CD_NetProxyAddr, tempstring, reqsize, NULL); if (!e) { if (!strcmp(tempstring, new_choices->proxy_address)) { free(tempstring); } else { free(new_choices->proxy_address); new_choices->proxy_address = tempstring; } } } else { show_error_ret(make_no_memory_error(17)); } } } if ((window = choices_find_component(CD_NetMaxImageFetch)) != 0) { numberrange_get_value(0, window, CD_NetMaxImageFetch, &temp); new_choices->maximages = temp; } old_font_size = choices.font_size; old_system_font = choices.system_font; if ((window = choices_find_component(CD_FontsSize)) != 0) { numberrange_get_value(0, window, CD_FontsSize, &new_choices->font_size); frac = new_choices->font_size % 10; new_choices->font_size = ((new_choices->font_size / 10)<<4) + fromdecimal[frac]; } if ((window = choices_find_component(CD_FontsAspect)) != 0) { numberrange_get_value(0, window, CD_FontsAspect, &new_choices->tt_aspect); if (choices.tt_aspect != new_choices->tt_aspect) fixed_changed = 1; } /* Have the default document colours changed? */ if ( choices.background_colour != new_choices->background_colour || choices.text_colour != new_choices->text_colour || choices.link_colour != new_choices->link_colour || choices.used_colour != new_choices->used_colour || choices.followed_colour != new_choices->followed_colour || choices.selected_colour != new_choices->selected_colour ) { colours_changed = 1; } /* Do we need to redraw because certain special items have changed? */ if ( choices.table_inner != new_choices->table_inner || choices.table_outer != new_choices->table_outer ) needs_redraw = 1; /* Now start using the dialogue's new settings */ memcpy(&choices, new_choices, sizeof(global_choices)); /* Before we change fonts, we need to forget the basic */ /* typeface definitions. First find out which have */ /* changed, if any. */ tfptr = fm_find_typeface("serif"); if (tfptr) { if (memcmp(tfptr, &new_typefaces[0], sizeof(fm_typeface))) serif_changed = 1; } tfptr = fm_find_typeface("sans"); if (tfptr) { if (memcmp(tfptr, &new_typefaces[1], sizeof(fm_typeface))) sans_changed = 1; } tfptr = fm_find_typeface("fixed"); if (tfptr) { if (memcmp(tfptr, &new_typefaces[2], sizeof(fm_typeface))) fixed_changed = 1; } if (choices.system_font) choices.font_size = FM_Standard_Size; if (choices.font_size != old_font_size || choices.system_font != old_system_font) { serif_changed = 1; sans_changed = 1; fixed_changed = 1; fm_set_system_font(choices.system_font); fm_init_sizes(choices.font_size); } /* If fonts have changed, get ready to update them */ if (serif_changed || sans_changed || fixed_changed) { /* Dump *all* current fonts */ fm_shutdown(); /* Write the new typeface details into the existing structures */ tfptr = fm_find_typeface("serif"); if (tfptr) memcpy(tfptr, &new_typefaces[0], sizeof(fm_typeface)); tfptr = fm_find_typeface("sans"); if (tfptr) memcpy(tfptr, &new_typefaces[1], sizeof(fm_typeface)); tfptr = fm_find_typeface("fixed"); if (tfptr) memcpy(tfptr, &new_typefaces[2], sizeof(fm_typeface)); } /* Update browsers - *must* call fm_lose_fonts for all */ /* browsers if the above code called fm_shutdown. */ b = last_browser; while (b) { if (serif_changed || sans_changed || fixed_changed) { /* Get rid of the currently used fonts for this browser */ fm_lose_fonts(b); /* Only reformat page if it has no children */ if (!b->children) reformat_format_from(b, -1, 1, -1); } else { if (b->background_colour == -1) { b->antialias_colour = redraw_backcol(b); } /* The Choices are only used directly for browsers which are */ /* set to override document colours. Otherwise defaults will */ /* have been read locally and possibly overridden by HTML, */ /* and a reload will be needed to reflect the changes. */ /* */ /* Alternatively, it may be the case that all browsers need */ /* redrawing (e.g. if the table border types change). */ if ( needs_redraw || ( (!b->use_source_cols && colours_changed ) || ( b->background_colour == -1 && b->background_image == -1 ) ) ) { s.window_handle = b->window_handle; RetError(wimp_get_window_state(&s)); coords_box_toworkarea(&s.visible_area, (WimpRedrawWindowBlock *) &s); RetError(wimp_force_redraw(b->window_handle, s.visible_area.xmin, s.visible_area.ymin, s.visible_area.xmax, s.visible_area.ymax)); if (b->background_colour == -1) { b->antialias_colour = choices.background_colour; } } } b = b->previous; } if (serif_changed || sans_changed || fixed_changed) { /* Reclaim basic typefaces - remember to claim at the *new* */ /* font Choices size. */ fm_claim_basic_typefaces(choices.font_size); } return NULL; } /*************************************************/ /* choices_set_button_handler() */ /* */ /* Called when the set button in the main */ /* choices dialogue is clicked. */ /* Uses choices_get_contents to set the global */ /* choices to reflect the choices set in the */ /* choices subwindows */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int choices_set_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e = NULL; int buttons; ChkError(window_get_pointer_info(0, NULL, NULL, &buttons, NULL, NULL)); e = choices_get_contents(); if (e) show_error_ret(e); if (buttons != 1) { ChkError(toolbox_hide_object(0, choices_windowid)); } return 1; } /*************************************************/ /* choices_cancel_button_handler() */ /* */ /* Called when the cancel button in the main */ /* choices dialogue is clicked. */ /* Uses choices_set_contents to restore the */ /* subwindows to their previous state. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int choices_cancel_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { ObjectId window; int update_fake; fm_typeface * tfptr; int buttons; ChkError(window_get_pointer_info(0, NULL, NULL, &buttons, NULL, NULL)); if (buttons == 1) { if ((choices.background_colour != new_choices->background_colour) || (choices.text_colour != new_choices->text_colour) || (choices.link_colour != new_choices->link_colour) || (choices.used_colour != new_choices->used_colour) || (choices.followed_colour != new_choices->followed_colour) || (choices.selected_colour != new_choices->selected_colour) || (choices.underline_links != new_choices->underline_links)) { update_fake = 1; } else { update_fake = 0; } memcpy(new_choices, &choices, sizeof(global_choices)); tfptr = fm_find_typeface("serif"); memcpy(&new_typefaces[0], tfptr, sizeof(fm_typeface)); tfptr = fm_find_typeface("sans"); memcpy(&new_typefaces[1], tfptr, sizeof(fm_typeface)); tfptr = fm_find_typeface("fixed"); memcpy(&new_typefaces[2], tfptr, sizeof(fm_typeface)); choices_set_contents(); /* Attempt to redraw fake page display */ if (update_fake && (window = choices_find_component(CD_FakePage)) != 0) button_set_flags(0, window, CD_FakePage, 0, 0); } else { memcpy(new_choices, &choices, sizeof(global_choices)); ChkError(toolbox_hide_object(0, choices_windowid)); } return 1; } /*************************************************/ /* choices_close() */ /* */ /* Close the Choices dialogue as if the 'Cancel' */ /* button had been activated with Select. */ /*************************************************/ _kernel_oserror * choices_close(void) { if (new_choices) memcpy(new_choices, &choices, sizeof(global_choices)); if (choices_windowid) return toolbox_hide_object(0, choices_windowid); else return NULL; } /*************************************************/ /* choices_save_button_handler() */ /* */ /* Called when the set button in the main */ /* choices dialogue is clicked. */ /* Uses choices_get_contents to set the global */ /* choices to reflect the choices set in the */ /* choices subwindows and then saves the choices */ /* file. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int choices_save_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e = NULL; ObjectId window; int buttons; ChkError(window_get_pointer_info(0, NULL, NULL, &buttons, NULL, NULL)); e = choices_get_contents(); if (e) { show_error_ret(e); return 1; } /* Attempt to redraw fake page display */ if ((window = choices_find_component(CD_FakePage)) != 0) button_set_flags(0, window, CD_FakePage, 0, 0); e = save_save_choices(NULL); if (e) show_error_ret(e); if (buttons != 1) { ChkError(toolbox_hide_object(0, choices_windowid)); } return 1; } /*************************************************/ /* choices_set_encoding_field() */ /* */ /* Sets the encoding display field appropriately */ /* to reflect the current state of */ /* new_choices->encoding */ /*************************************************/ _kernel_oserror * choices_set_encoding_field(void) { _kernel_oserror * e; ObjectId objid, destwind; ComponentId compid; char * textptr; int sizereqd; /* Find which window the encoding display is in */ destwind = choices_find_component(CD_EncodingDisply); if (!destwind) return NULL; /* Find menu item which contains encoding name */ if (encoding_get_encoding_item(new_choices->encoding, &objid, &compid)) { RetError(menu_get_entry_text(0, objid, compid, NULL, 0, &sizereqd)); /* Add 1 to the buffer size just incase the sizereqd field is returned as string */ /* length rather than the buffer size required. Typical paranoid precautions */ /* when using the toolbox. */ textptr = malloc(sizereqd+1); if (textptr) { e = menu_get_entry_text(0, objid, compid, textptr, sizereqd+1, NULL); if (e) { free(textptr); return e; } e = choices_displayfield_set_value(0, destwind, CD_EncodingDisply, textptr); free(textptr); return e; } else { RetError(make_no_memory_error(18)); } } else { /* The encoding name could not be found in the menu structure */ RetError(choices_displayfield_set_value(0, destwind, CD_EncodingDisply, "Unknown encoding")); // } return NULL; } /*************************************************/ /* choices_encoding_button_handler() */ /* */ /* Opens the encoding window with appropriate */ /* values for the choices dialogue. */ /*************************************************/ static int choices_encoding_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; int position[2]; BBox box; WimpGetWindowStateBlock state; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of encoding menu to top left of encoding button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, encoding_get_menuid(), Toolbox_ShowObject_TopLeft, position, choices_windowid, NULL)); return 1; } /*************************************************/ /* choices_colour_button_handler() */ /* */ /* Opens a colour dialogue box with appropriate */ /* settings for the current colour. */ /*************************************************/ static int choices_colour_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; int position[2]; BBox box; WimpGetWindowStateBlock state; int colour[2]; /* Is the ColourDbox module in RMA? */ e = _swix(OS_Module, _INR(0,1), 18, "ColourDbox"); /* No, well try and load it from system */ if (e) { e = _swix(OS_Module, _INR(0,1), 1, "System:Modules.Toolbox.ColourDbox"); } /* That didn't work so try reinitialising it */ if (e) { e = _swix(OS_Module, _INR(0,1), 3, "ColourDbox"); } /* That didn't work either! So it's tough you can't change the colours */ if (e) { show_error_ret(e); return 1; } switch(idb->self_component) { case CD_BackColourBt: colour[0] = new_choices->background_colour; break; case CD_TextColourBt: colour[0] = new_choices->text_colour; break; case CD_LinkColourBt: colour[0] = new_choices->link_colour; break; case CD_UsedColourBt: colour[0] = new_choices->used_colour; break; case CD_FolwColourBt: colour[0] = new_choices->followed_colour; break; case CD_SlctColourBt: colour[0] = new_choices->selected_colour; break; default: return 1; break; } colour[1] = 0; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of encoding menu to top left of encoding button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); e = toolbox_create_object(0, "ColourDbox", &colourdbox_id); if (e) { show_error_ret(e); return 1; } e = colourdbox_set_colour(0, colourdbox_id, colour); if (e) { show_error_ret(e); return 1; } show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, colourdbox_id, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); e = event_register_toolbox_handler(colourdbox_id, ColourDbox_DialogueCompleted, choices_colour_closed_handler, NULL); if (e) {show_error_ret(e); return 1;} e = event_register_toolbox_handler(colourdbox_id, ColourDbox_ColourSelected, choices_colour_selected_handler, NULL); if (e) {show_error_ret(e); return 1;} return 1; } /*************************************************/ /* choices_colour_closed_handler() */ /* */ /* Called when the colour dialogue box is closed */ /* deregisters all events attached to it and */ /* deletes the dbox object. */ /*************************************************/ static int choices_colour_closed_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; e = event_deregister_toolbox_handler(idb->self_id, ColourDbox_DialogueCompleted, choices_colour_closed_handler, NULL); if (e) {show_error_ret(e); return 1;} e = event_deregister_toolbox_handler(colourdbox_id, ColourDbox_ColourSelected, choices_colour_selected_handler, NULL); if (e) {show_error_ret(e); return 1;} e = toolbox_delete_object(0, idb->self_id); if (e) {show_error_ret(e); return 1;} #ifdef TRACE if (tl & (1u<<29)) Printf("choices_colour_closed_handler: Colour DBox deleted\n"); #endif return 1; } /*************************************************/ /* choices_colour_selected_handler() */ /* */ /* Called when the a colour is selected in the */ /* colour dialogue box. */ /* Sets appropriate fields in the new_choices */ /* structure and updates the window to reflect */ /* the new colour chosen. */ /*************************************************/ static int choices_colour_selected_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { ColourDboxColourSelectedEvent *cevent = (ColourDboxColourSelectedEvent*)event; switch(idb->parent_component) { case CD_BackColourBt: new_choices->background_colour = cevent->colour_block[0]; break; case CD_TextColourBt: new_choices->text_colour = cevent->colour_block[0]; break; case CD_LinkColourBt: new_choices->link_colour = cevent->colour_block[0]; break; case CD_UsedColourBt: new_choices->used_colour = cevent->colour_block[0]; break; case CD_FolwColourBt: new_choices->followed_colour = cevent->colour_block[0]; break; case CD_SlctColourBt: new_choices->selected_colour = cevent->colour_block[0]; break; default: return 1; break; } /* Don't bother with errors as colour display field might not exist */ choices_colour_set_component(idb->parent_id, idb->parent_component-1, cevent->colour_block[0]); /* Don't bother with errors as fake page display might not exist */ button_set_flags(0, idb->parent_id, CD_FakePage, 0, 0); return 1; } /*************************************************/ /* choices_colour_set_component() */ /* */ /* Sets the validation string of a button to be */ /* slabbed in and have the background colour */ /* specified. */ /* */ /* Parameters: window ObjectId */ /* */ /* button ComponentId */ /* */ /* colour */ /*************************************************/ static _kernel_oserror *choices_colour_set_component(ObjectId window, ComponentId component, int colour) { char newvalidation[32]; unsigned char * newcol; newcol = (unsigned char*)&colour; sprintf(newvalidation, "R2;C/%02.2x%02.2x%02.2x", *(newcol + 3), *(newcol + 2), *(newcol + 1)); return choices_button_set_validation(0, window, component, newvalidation); } /*************************************************/ /* choices_display_button_handler() */ /* */ /* Opens the display menu with a value */ /* appropriate to either the hotlist or history. */ /*************************************************/ static int choices_display_m_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; int position[2]; BBox box; WimpGetWindowStateBlock state; ObjectId display; int new_tick; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of display menu to top left of display button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); e = toolbox_create_object(0, "ChDisplay", &display); if (e) { show_error_ret(e); return 1; } switch(idb->self_component) { case CD_HlDispBt: new_tick = new_choices->hotlist_show; break; case CD_HiDispBt: new_tick = new_choices->show_urls; break; default: new_tick = 0; break; } if (disp_ticked != new_tick) { if (disp_ticked != -1) menu_set_tick(0, display, disp_ticked, 0); menu_set_tick(0, display, new_tick, 1); disp_ticked = new_tick; } show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, display, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); return 1; } /*************************************************/ /* choices_save_m_button_handler() */ /* */ /* Opens the save menu with a value appropriate */ /* to either the hotlist or history. */ /*************************************************/ static int choices_save_m_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; int position[2]; BBox box; WimpGetWindowStateBlock state; ObjectId display; int new_tick; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of display menu to top left of display button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); e = toolbox_create_object(0, "ChSave", &display); if (e) { show_error_ret(e); return 1; } switch(idb->self_component) { case CD_HlSaveBt: new_tick = new_choices->save_hotlist; break; case CD_HiSaveBt: new_tick = new_choices->save_history; break; default: new_tick = 0; break; } if (save_ticked != new_tick) { if (save_ticked != -1) menu_set_tick(0, display, save_ticked, 0); menu_set_tick(0, display, new_tick, 1); save_ticked = new_tick; } show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, display, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); return 1; } /*************************************************/ /* choices_set_save_field() */ /* */ /* Sets the passed save display field */ /* appropriately to reflect the passed state. */ /*************************************************/ static _kernel_oserror * choices_set_save_field(ObjectId obj, ComponentId comp, int state) { _kernel_oserror *e; char *tempstring; #ifdef TRACE if (tl & (1u<<29)) Printf("choices_set_display_field: Called\n"); #endif RetError(choices_get_menu_entry_text("ChSave", state, &tempstring)); e = choices_displayfield_set_value(0, obj, comp, tempstring); free(tempstring); return e; } /*************************************************/ /* choices_set_display_field() */ /* */ /* Sets the passed display display field */ /* appropriately to reflect the passed state. */ /*************************************************/ static _kernel_oserror * choices_set_display_field(ObjectId obj, ComponentId comp, int state) { _kernel_oserror *e; char *tempstring; #ifdef TRACE if (tl & (1u<<29)) Printf("choices_set_display_field: Called\n"); #endif RetError(choices_get_menu_entry_text("ChDisplay", state, &tempstring)); e = choices_displayfield_set_value(0, obj, comp, tempstring); free(tempstring); return e; } /*************************************************/ /* choices_display_m_click_handler() */ /* */ /* Called when there is a selection in the */ /* display menu. Sets the selected menu item to */ /* be ticked, unticks the previously ticked */ /* entry sets appropriate new_choices field and */ /* updates the display field of the component */ /* with component number 1 less than the menus */ /* parent. */ /*************************************************/ static int choices_display_m_click_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { if (disp_ticked != idb->self_component) { if (disp_ticked != -1) menu_set_tick(0, idb->self_id, disp_ticked, 0); menu_set_tick(0, idb->self_id, idb->self_component, 1); disp_ticked = idb->self_component; } switch(idb->parent_component) { case CD_HlDispBt: new_choices->hotlist_show = idb->self_component; break; case CD_HiDispBt: new_choices->show_urls = idb->self_component; break; } choices_set_display_field(idb->parent_id, idb->parent_component - 1, idb->self_component); return 1; } /*************************************************/ /* choices_save_m_click_handler() */ /* */ /* Called when there is a selection in the save */ /* menu. Sets the selected menu item to be */ /* ticked, unticks the previously ticked entry */ /* sets appropriate new_choices field and */ /* updates the display field of the component */ /* with component number 1 less than the menus */ /* parent. */ /*************************************************/ static int choices_save_m_click_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { if (save_ticked != idb->self_component) { if (save_ticked != -1) menu_set_tick(0, idb->self_id, save_ticked, 0); menu_set_tick(0, idb->self_id, idb->self_component, 1); save_ticked = idb->self_component; } switch(idb->parent_component) { case CD_HlSaveBt: new_choices->save_hotlist = idb->self_component; break; case CD_HiSaveBt: new_choices->save_history = idb->self_component; break; } choices_set_save_field(idb->parent_id, idb->parent_component - 1, idb->self_component); return 1; } /*************************************************/ /* choices_draw_string() */ /* */ /* Writes a string on the screen using the */ /* passed font handle, it underlines the text if */ /* required. It also returns the position to */ /* paint the next string following this one. */ /* */ /* Parameters: font handle */ /* */ /* string to print */ /* */ /* xposition on screen (os coords) */ /* */ /* yposition on screen (os coords) */ /* */ /* 0 - don't underline */ /* non 0 - underline */ /* */ /* foreground colour */ /* */ /* background colour */ /* */ /* pointer to int to return x */ /* position in */ /*************************************************/ static _kernel_oserror * choices_draw_string(fm_face h, char *string, int xpos, int ypos, int underline, int forecolour, int backcolour, int *newxpos) { int width, nochars; fm_set_font_colour(h, forecolour, backcolour); fm_get_string_width(h, string, 0x1000000, strlen(string), -1, &nochars, &width); convert_to_os(width, &width); /* The next string must be plotted straight after this string */ *newxpos = xpos + width; fm_puts(h, xpos, ypos, string, 1, 0); if (underline) { redraw_set_colour(forecolour); bbc_move(xpos, ypos - 7); bbc_draw(*newxpos, ypos - 7); } return NULL; } /*************************************************/ /* choices_write_rubbish() */ /* */ /* Writes a string of readable rubbish on the */ /* screen using the passed font handle. It also */ /* returns the position to paint the next string */ /* following this one. */ /* */ /* Parameters: font handle */ /* */ /* xposition on screen (os coords) */ /* */ /* yposition on screen (os coords) */ /* */ /* Approximate x position to stop */ /* printing at (os coords) */ /* */ /* foreground colour */ /* */ /* background colour */ /* */ /* pointer to int to return x */ /* position in */ /* */ /* Random seed for string to print */ /* (If you pass the same seed the */ /* string should be the same) */ /*************************************************/ static _kernel_oserror * choices_write_rubbish(fm_face h, int xpos, int ypos, int maxxish, int forecolour, int backcolour, int *newxpos, int seed) { char ministring[5]; int chars = 0; int spcwidth, width, nochars; fm_set_font_colour(h, forecolour, backcolour); srand(seed); fm_get_string_width(h, " ", 0x1000000, 1, -1, &nochars, &width); convert_to_os(width, &spcwidth); xpos += spcwidth; while(xpos < maxxish) { ministring[0] = consonant[rand()%(sizeof(consonant)-1)]; ministring[1] = vowel[rand()%(sizeof(vowel)-1)]; if (rand()%2) { ministring[2] = consonant[rand()%(sizeof(consonant)-1)]; ministring[3] = vowel[rand()%(sizeof(vowel)-1)]; ministring[4] = 0; } else { ministring[2] = 0; } fm_puts(h, xpos, ypos, ministring, 1, 0); fm_get_string_width(h, ministring, 0x1000000, strlen(ministring), -1, &nochars, &width); convert_to_os(width, &width); xpos += width; chars++; if (chars > rand()%2 || xpos >= maxxish) { chars = 0; xpos += spcwidth; } } *newxpos = xpos; return NULL; } /*************************************************/ /* choices_redraw_fakepage_handler() */ /* */ /* Redraws the fake page in the colour selection */ /* dbox. */ /*************************************************/ static int choices_redraw_fakepage_handler(int eventcode, WimpPollBlock * event, IdBlock * idb, void * handle) { _kernel_oserror * e = NULL; WimpRedrawWindowBlock block; WimpGetWindowStateBlock state; int more, ypos, xtarget, ptsize, gadsize, xstart, nolines; int fontheight = 0; int gotfont = 0; BBox icon_coords, fbox; fm_face h = 0; char display_this[4]; block.window_handle = event->redraw_window_request.window_handle; state.window_handle = event->redraw_window_request.window_handle; e = wimp_get_window_state(&state); show_error_ret(e); if (!e) e = gadget_get_bbox(0, idb->self_id, CD_FakePage, &icon_coords); gadsize = icon_coords.ymax - icon_coords.ymin; xstart = gadsize / 8; if (e) { /* Gadget doesn't exist or something strange happened trying */ /* to get window state so just do a simple redraw loop to */ /* keep the wimp happy. */ ChkError(wimp_redraw_window(&block, &more)); while (more && !e) e = wimp_get_rectangle(&block, &more); return 1; } coords_box_toscreen(&icon_coords, (WimpRedrawWindowBlock *) &state); /* Find out which lines to draw */ for(nolines = 0; nolines < sizeof(display_this); nolines++) display_this[nolines] = 0; nolines = 1; /* Start with one line (half at top, half at bottom) */ if (choices_find_component(CD_LinkColourBt)) { nolines ++; display_this[0] = 1; } if (choices_find_component(CD_UsedColourBt)) { nolines ++; display_this[1] = 1; } if (choices_find_component(CD_FolwColourBt)) { nolines ++; display_this[2] = 1; } if (choices_find_component(CD_SlctColourBt)) { nolines ++; display_this[3] = 1; } /* Start the redraw loop */ ChkError(wimp_redraw_window(&block, &more)); while (more && !e) { /* Clip the redraw area to only take in the gadget */ if (set_graphics_intersection(&icon_coords, &block.redraw_area)) { /* Only claim the font if it is required */ if (!gotfont) { /* Find default browser font, the font manager will return system */ /* font if it is configured. */ /* Find a 1000 subpoint (big) version of default browser font to scale against */ h = fm_find_font(NULL, "serif", 1000, 1000, 0, 0); e = fm_font_box(h, &fbox); fm_lose_font(NULL, h); if (e) show_error_cont(e); fontheight = fbox.ymax - fbox.ymin; /* Find a version of the default browser font with a */ /* point size which will allow an appropriate number */ /* of lines in the fake page display. */ ptsize = ((gadsize * 1000 / nolines) / fontheight); h = fm_find_font(NULL, "serif", ptsize, ptsize, 0, 0); ChkError(fm_font_box(h, &fbox)); fontheight = fbox.ymax - fbox.ymin; gotfont = 1; } /* Fake browser drawing code is here */ /* Fill background with background colour */ redraw_set_colour(new_choices->background_colour); ChkError(bbc_rectanglefill(icon_coords.xmin, icon_coords.ymin, icon_coords.xmax - icon_coords.xmin, icon_coords.ymax - icon_coords.ymin)); xtarget = icon_coords.xmin - 32; ypos = icon_coords.ymax - fontheight / 3; /* Display the top line of the fake page display */ ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmax, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 1)); ypos -= fontheight; xtarget = icon_coords.xmin - 32; /* Display the new link line of the fake page display */ if (display_this[0]) { ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmin+xstart, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 2)); ChkError(choices_draw_string(h, "new", xtarget, ypos, new_choices->underline_links, new_choices->link_colour, new_choices->background_colour, &xtarget)); ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmax, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 3)); ypos -= fontheight; xtarget = icon_coords.xmin - 32; } /* Display the new followed line of the fake page display */ if (display_this[1]) { ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmin+xstart, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 4)); ChkError(choices_draw_string(h, "followed", xtarget, ypos, new_choices->underline_links, new_choices->used_colour, new_choices->background_colour, &xtarget)); ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmax, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 5)); ypos -= fontheight; xtarget = icon_coords.xmin - 32; } /* Display the highlighted link line of the fake page display */ if (display_this[2]) { ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmin+xstart, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 6)); ChkError(choices_draw_string(h, "highlighted", xtarget, ypos, new_choices->underline_links, new_choices->followed_colour, new_choices->background_colour, &xtarget)); ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmax, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 7)); ypos -= fontheight; xtarget = icon_coords.xmin - 32; } /* Display the selected link line of the fake page display */ if (display_this[3]) { ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmin+xstart, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 8)); ChkError(choices_draw_string(h, "selected", xtarget, ypos, new_choices->underline_links, new_choices->selected_colour, new_choices->background_colour, &xtarget)); ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmax, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 9)); ypos -= fontheight; xtarget = icon_coords.xmin - 32; } /* Display the bottom line of the fake page display */ ChkError(choices_write_rubbish(h, xtarget, ypos, icon_coords.xmax, new_choices->text_colour, new_choices->background_colour, &xtarget, rubbish_seed + 10)); } restore_graphics_intersection(&block.redraw_area); /* Get the next redraw rectangle */ if (!e) e = wimp_get_rectangle(&block, &more); } if (gotfont) fm_lose_font(NULL, h); return 1; } /*************************************************/ /* choices_option_state_handler() */ /* */ /* Called when an option button has its state */ /* changed by being clicked on. Sets or unsets */ /* the relevant flag in new_choices and causes */ /* redraws where necessary. */ /*************************************************/ static int choices_option_state_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { int state; ObjectId window; ChkError(optionbutton_get_state(0, idb->self_id, idb->self_component, &state)); switch(idb->self_component) { case CD_UnderlineLinks: { new_choices->underline_links = !!state; /* Attempt to redraw fake page display */ if ((window = choices_find_component(CD_FakePage)) != 0) button_set_flags(0, window, CD_FakePage, 0, 0); break; } case CD_UseDocColours: new_choices->use_source_cols = !!state; break; case CD_ShowForeground: new_choices->show_foreground = !!state; break; case CD_ShowBackground: new_choices->show_background = !!state; break; case CD_URLBar: new_choices->url_bar = !!state; break; case CD_StatusBar: new_choices->status_bar = !!state; break; case CD_ButtonBar: new_choices->button_bar = !!state; break; case CD_FullScreen: new_choices->full_screen = !!state; break; case CD_ClientPull: new_choices->client_pull = !!state; break; case CD_NetscapeEmu: new_choices->clone = !!state; break; case CD_FramesSupport: new_choices->support_frames = !!state; break; case CD_FontsSystem: new_choices->system_font = !!state; if ((window = choices_find_component(CD_FontsTF1Labl)) != 0) { choices_set_fonts_greyed(window, new_choices->system_font); /*set_gadget_state(window, CD_FontsGroup1, new_choices->system_font);*/ if ((window = choices_find_component(CD_FontsSize)) != 0) { if (new_choices->system_font) { int frac, temp; numberrange_get_value(0, window, CD_FontsSize, &new_choices->font_size); frac = new_choices->font_size % 10; new_choices->font_size = ((new_choices->font_size / 10)<<4) + fromdecimal[frac]; temp = FM_Standard_Size; frac = (temp & 0xf); temp = ((temp >> 4) * 10) + todecimal[frac]; choices_numberrange_set_value(0, window, CD_FontsSize, temp); choices_numberrange_set_value(0, window, CD_FontsAspect, 100); } else { int temp, frac; temp = new_choices->font_size; frac = (temp & 0xf); temp = ((temp >> 4) * 10) + todecimal[frac]; choices_numberrange_set_value(0, window, CD_FontsSize, temp); choices_numberrange_set_value(0, window, CD_FontsAspect, new_choices->tt_aspect); } } } break; case CD_ObjHandle: new_choices->support_object = !!state; if ((window = choices_find_component(CD_ObjPlugDisp)) != 0) { set_gadget_state(window, CD_ObjPlugLabl, !new_choices->support_object); set_gadget_state(window, CD_ObjPlugBt, !new_choices->support_object); set_gadget_state(window, CD_ObjPlugDisp, !new_choices->support_object); choices_set_plugin_field(); } break; case CD_NetUseProxy: new_choices->use_proxy = !!state; if ((window = choices_find_component(CD_NetProxyAddr)) != 0) { set_gadget_state(window, CD_NetProxyAddr, !new_choices->use_proxy); set_gadget_state(window, CD_NetProxyLabl, !new_choices->use_proxy); } break; case CD_NetLaunchProxy: new_choices->start_proxy = !!state; break; case CD_HiDontAge: choices_set_expiry_age_greyed(idb->self_id, !state); expiry_age_greyed = !state; break; case CD_HiDontSize: choices_set_max_size_greyed(idb->self_id, !state); max_size_greyed = !state; break; case CD_HiImDontAge: choices_set_im_expiry_age_greyed(idb->self_id, !state); image_expiry_age_greyed = !state; break; case CD_HiImDontSize: choices_set_im_max_size_greyed(idb->self_id, !state); image_max_size_greyed = !state; break; case CD_TabSupport: new_choices->support_tables = !!state; choices_set_tables_greyed(!new_choices->support_tables,idb->self_id); break; /* Haven't recognised this option button event so pass it on */ default: return 0; } return 1; } /*************************************************/ /* choices_mode_change() */ /* */ /* Called on every mode change event. Records */ /* that a mode change has taken place for use */ /* with the choices_open_choice_window function. */ /*************************************************/ _kernel_oserror * choices_mode_change(void) { choices_modechanged = 1; return NULL; } /*************************************************/ /* choices_open_choice_window() */ /* */ /* Called whenever the choices window needs to */ /* be moved and specifically on mode changes so */ /* the current sub window can be positioned */ /* correctly dealing with rounding errors */ /* between modes of different aspect ratio. */ /*************************************************/ static int choices_open_choice_window(int eventcode, WimpPollBlock * event, IdBlock * idb, void * handle) { toolbox_show_object(0, idb->self_id, Toolbox_ShowObject_FullSpec, &(event->open_window_request.visible_area), idb->parent_id, idb->parent_component); if (choices_modechanged) { /* Reshow the subwindow at possibly new location */ choices_show_subwindow(idb->self_id, current_subwindow); choices_modechanged = 0; } return 1; } /*************************************************/ /* choices_find_component() */ /* */ /* Scans all the choices subwindows for the */ /* requested component and returns the id of the */ /* first window in which it was seen. */ /* */ /* Parameters: The component to find. */ /* */ /* Returns: Where to return the object id to. */ /* 0 if the component was not found */ /*************************************************/ static ObjectId choices_find_component(ComponentId component) { int findwindow; unsigned int flags; /* Uses lazy evaluation to not call gadget_get_flags unless */ /* subwindows[findwindow] contains an objectid. */ for(findwindow = 0; findwindow < CDNoSubwindows; findwindow++) if (subwindows[findwindow] && !gadget_get_flags(0, subwindows[findwindow], component, &flags)) return subwindows[findwindow]; return 0; } /*************************************************/ /* choices_writablefield_set_value() */ /* */ /* Does as writablefield_set_value but will only */ /* update it if the text is different to that */ /* currently in the display field. */ /*************************************************/ static _kernel_oserror *choices_writablefield_set_value(unsigned int flags, ObjectId window, ComponentId writable, char *text) { int reqdsize; char * oldtext; _kernel_oserror * e = NULL; RetError(writablefield_get_value(0, window, writable, NULL, 0, &reqdsize)); oldtext = malloc(reqdsize+1); if (!oldtext) return make_no_memory_error(100); writablefield_get_value(0, window, writable, oldtext, reqdsize, NULL); if (strcmp(text, oldtext)) { e = writablefield_set_value(flags, window, writable, text); } free(oldtext); return e; } /*************************************************/ /* choices_displayfield_set_value() */ /* */ /* Does as displayfield_set_value but will only */ /* update it if the text is different to that */ /* currently in the display field. */ /*************************************************/ static _kernel_oserror *choices_displayfield_set_value(unsigned int flags, ObjectId window, ComponentId writable, char *text) { int reqdsize; char * oldtext; _kernel_oserror * e = NULL; RetError(displayfield_get_value(0, window, writable, NULL, 0, &reqdsize)); oldtext = malloc(reqdsize+1); if (!oldtext) return make_no_memory_error(100); displayfield_get_value(0, window, writable, oldtext, reqdsize, NULL); if (strcmp(text, oldtext)) { e = displayfield_set_value(flags, window, writable, text); } free(oldtext); return e; } /*************************************************/ /* choices_button_set_validation() */ /* */ /* Does as button_set_validation but will only */ /* update it if the text is different to that */ /* currently in the button. */ /*************************************************/ static _kernel_oserror *choices_button_set_validation(unsigned int flags, ObjectId window, ComponentId writable, char *text) { int reqdsize; char * oldtext; _kernel_oserror * e = NULL; RetError(button_get_validation(0, window, writable, NULL, 0, &reqdsize)); oldtext = malloc(reqdsize+1); if (!oldtext) return make_no_memory_error(100); button_get_validation(0, window, writable, oldtext, reqdsize, NULL); if (strcmp(text, oldtext)) { e = button_set_validation(flags, window, writable, text); } free(oldtext); return e; } /*************************************************/ /* choices_numberrange_set_value() */ /* */ /* Does as numberrange_set_value but will only */ /* update it if the number is different to that */ /* currently in the display. */ /*************************************************/ static _kernel_oserror *choices_numberrange_set_value(unsigned int flags, ObjectId window, ComponentId writable, int value) { int oldvalue; _kernel_oserror * e = NULL; RetError(numberrange_get_value(0, window, writable, &oldvalue)); if (oldvalue != value) { e = numberrange_set_value(flags, window, writable, value); } return e; } /*************************************************/ /* choices_modified_font() */ /* */ /* Finds a version of a font with a specified */ /* modification eg. bold or italic. */ /* */ /* Parameters: pointer to the original font name */ /* */ /* pointer to a space separated and */ /* null terminated list of */ /* modifications in order of */ /* preference */ /* */ /* pointer to a buffer to contain */ /* the name of the new font. */ /*************************************************/ static void choices_modified_font(char * orig, char * mod, char * buffer) { _kernel_oserror * e = NULL; char origname[Limits_FontName]; int f=-1; char * p, * p2; char * lastdot; BOOL found; /* Find the fontname field */ _swix(Font_FindField, _INR(1,2)|_OUTR(1,2), orig, 'F', &p, &found); /* If the field could not be found assume that the entire */ /* string is the font name. */ if (!found) p = orig; p2 = origname; /* Extract the font name. */ /* Copys the string pointed to by p to p2 until either a \ or a */ /* character with an ascii value less than 32 is encountered. */ while (*p > 32 && *p != '\\') *p2++ = *p++; /* NULL terminate the new string */ *p2 = '\0'; lastdot = strrchr(origname, '.'); /* Get first of possibly several possible modifications */ p = strtok(mod, " "); while (p) { sprintf(buffer, "%s.%s", origname, p); e=_swix(Font_FindFont, _INR(1,5)|_OUT(0), buffer, 12*16, 12*16, 90, 90, &f); /* If there was no error then the font must have been found */ if (!e) break; if (lastdot) { *lastdot = '\0'; sprintf(buffer, "%s.%s", origname, p); *lastdot = '.'; e=_swix(Font_FindFont, _INR(1,5)|_OUT(0), buffer, 12*16, 12*16, 90, 90, &f); if (e==NULL) break; } /* Get the next modification */ p=strtok(NULL, " "); } /* If a font has been 'found' we need to lose it again */ if (f >= 0) _swix(Font_LoseFont, _IN(0), f); /* If an error was encountered the best we can do is */ /* to return the original font. */ if (e) strcpy(buffer, orig); } /*************************************************/ /* choices_font_button_handler() */ /* */ /* Opens a font menu box with appropriate */ /* settings for the current font. */ /*************************************************/ static int choices_font_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; int position[2]; BBox box; WimpGetWindowStateBlock state; ObjectId fontmenu_id; int colour[2]; char * fontname; switch(idb->self_component) { case CD_FontsTF1Bt: break; case CD_FontsTF2Bt: break; case CD_FontsTF3Bt: break; default: return 1; break; } colour[1] = 0; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of encoding menu to top left of encoding button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); e = toolbox_create_object(0, "FontMenu", &fontmenu_id); if (e) { show_error_ret(e); return 1; } switch(idb->self_component) { case CD_FontsTF1Bt: fontname = new_typefaces[0].fontnames[0]; break; case CD_FontsTF2Bt: fontname = new_typefaces[1].fontnames[0]; break; case CD_FontsTF3Bt: fontname = new_typefaces[2].fontnames[0]; break; default: fontname = ""; break; } fontmenu_set_font(0, fontmenu_id, fontname); show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, fontmenu_id, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); e = event_register_toolbox_handler(fontmenu_id, FontMenu_HasBeenHidden, choices_font_closed_handler, NULL); if (e) {show_error_ret(e); return 1;} e = event_register_toolbox_handler(fontmenu_id, FontMenu_Selection, choices_font_selected_handler, NULL); if (e) {show_error_ret(e); return 1;} return 1; } /*************************************************/ /* choices_font_closed_handler() */ /* */ /* Called when the font menu is closed */ /* deregisters all events attached to it and */ /* deletes the menu object. */ /*************************************************/ static int choices_font_closed_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; e = event_register_toolbox_handler(idb->self_id, FontMenu_HasBeenHidden, choices_font_closed_handler, NULL); if (e) {show_error_ret(e); return 1;} e = event_register_toolbox_handler(idb->self_id, FontMenu_Selection, choices_font_selected_handler, NULL); if (e) {show_error_ret(e); return 1;} e = toolbox_delete_object(0, idb->self_id); if (e) {show_error_ret(e); return 1;} #ifdef TRACE if (tl & (1u<<29)) Printf("choices_font_closed_handler: FontMenu deleted\n"); #endif return 1; } /*************************************************/ /* choices_font_selected_handler() */ /* */ /* Called when the a font is selected in the */ /* font menu. */ /*************************************************/ static int choices_font_selected_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { char font[4] [Limits_FontName], *p, *p2; int found; fm_typeface * target; #ifdef TRACE if (tl & (1u<<29)) { Printf("choices_font_selected_handler: called\n"); Printf("Selected font = %s\n", ((FontMenuSelectionEvent*)event)->font_id); } #endif p2 = font[0]; /* Assume that the F field will be found because the fontmenu */ /* returns the font in the correct format. */ ChkError(_swix(Font_FindField, _INR(1,2)|_OUTR(1,2), ((FontMenuSelectionEvent*)event)->font_id, 'F', &p, &found)); /* Extract the font name */ while (*p > 32 && *p != '\\') *p2++ = *p++; *p2 = '\0'; choices_modified_font(font[0], getenv("Font$Italic"), font[1]); /* Get italic variant of base font */ choices_modified_font(font[0], getenv("Font$Bold"), font[2]); /* Get bold version of base font */ choices_modified_font(font[2], getenv("Font$Italic"), font[3]); /* Get italic version of bold font */ #ifdef TRACE if (tl & (1u<<29)) { Printf("Base font = %s\n", font[0]); Printf("Italic version = %s\n", font[1]); Printf("Bold version = %s\n", font[2]); Printf("Bold-Italic version = %s\n", font[3]); } #endif /* Set display field to name of new font */ /* Ignore error as the display isn't */ /* required. */ choices_displayfield_set_value(0, idb->parent_id, idb->parent_component - 1, font[0]); switch(idb->parent_component) { case CD_FontsTF1Bt: target = &new_typefaces[0]; break; case CD_FontsTF2Bt: target = &new_typefaces[1]; break; case CD_FontsTF3Bt: target = &new_typefaces[2]; break; default: return 1; break; } strcpy(target->fontnames[0], font[0]); strcpy(target->fontnames[1], font[1]); strcpy(target->fontnames[2], font[2]); strcpy(target->fontnames[3], font[3]); return 1; } /*************************************************/ /* choices_set_fonts_greyed() */ /* */ /* Sets the font name and font size gadgets to */ /* greyed/ungreyed. */ /* */ /* Parameters: ObjectId of the window which */ /* contains the icons. */ /* */ /* 0 to ungrey, any other value to */ /* to grey. */ /*************************************************/ static void choices_set_fonts_greyed(ObjectId window, int state) { set_gadget_state(window, CD_FontsTF1Labl, !!state); set_gadget_state(window, CD_FontsTF1Disp, !!state); set_gadget_state(window, CD_FontsTF1Bt, !!state); set_gadget_state(window, CD_FontsTF2Labl, !!state); set_gadget_state(window, CD_FontsTF2Disp, !!state); set_gadget_state(window, CD_FontsTF2Bt, !!state); set_gadget_state(window, CD_FontsTF3Labl, !!state); set_gadget_state(window, CD_FontsTF3Disp, !!state); set_gadget_state(window, CD_FontsTF3Bt, !!state); set_gadget_state(window, CD_FontsSize, !!state); set_gadget_state(window, CD_FontsSzLabl1, !!state); set_gadget_state(window, CD_FontsSzLabl2, !!state); set_gadget_state(window, CD_FontsAspect, !!state); set_gadget_state(window, CD_FontsAspectLabl1, !!state); set_gadget_state(window, CD_FontsAspectLabl2, !!state); } /*************************************************/ /* choices_set_plugin_field() */ /* */ /* Sets the plugin field appropriately to */ /* reflect the current state of */ /* new_choices->plugin_control */ /*************************************************/ _kernel_oserror * choices_set_plugin_field(void) { _kernel_oserror * e; ObjectId destwind; char * tempstring; #ifdef TRACE if (tl & (1u<<29)) Printf("choices_set_plugin_field: Called\n"); #endif /* Find which window the encoding display is in */ destwind = choices_find_component(CD_ObjPlugDisp); if (!destwind) return NULL; RetError(choices_get_menu_entry_text("ChPlugin", new_choices->plugin_control, &tempstring)); e = choices_displayfield_set_value(0, destwind, CD_ObjPlugDisp, tempstring); free(tempstring); return NULL; } /*************************************************/ /* choices_plug_m_click_handler() */ /* */ /* Called when there is a selection in the */ /* plugin menu. Sets the selected menu item to */ /* be ticked, unticks the previously ticked */ /* entry sets appropriate new_choices field and */ /* updates the display field of the component */ /* with component number 1 less than the menus */ /* parent. */ /*************************************************/ static int choices_plug_m_click_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { if (plug_ticked != idb->self_component) { if (plug_ticked != -1) menu_set_tick(0, idb->self_id, plug_ticked, 0); menu_set_tick(0, idb->self_id, idb->self_component, 1); plug_ticked = idb->self_component; } new_choices->plugin_control = idb->self_component; choices_set_plugin_field(); return 1; } /*************************************************/ /* choices_plug_m_button_handler() */ /* */ /* Opens the save menu with a value appropriate */ /* to either the hotlist or history. */ /*************************************************/ static int choices_plug_m_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror * e; int position[2]; BBox box; WimpGetWindowStateBlock state; ObjectId display; int new_tick; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of display menu to top left of display button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); e = toolbox_create_object(0, "ChPlugin", &display); if (e) { show_error_ret(e); return 1; } new_tick = new_choices->plugin_control; if (plug_ticked != new_tick) { if (plug_ticked != -1) menu_set_tick(0, display, plug_ticked, 0); menu_set_tick(0, display, new_tick, 1); plug_ticked = new_tick; } show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, display, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); return 1; } /*************************************************/ /* choices_history_radio_handler() */ /* */ /* Handles radio button state changes. Swaps */ /* between page and image history settings. */ /*************************************************/ static int choices_history_radio_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { int state, temp; ObjectId window; radiobutton_get_state(0, idb->self_id, idb->self_component, &state, NULL); /* Is this a radiobutton selected event? */ if (state) { if (expiry_age_greyed) { if (history_radio) new_choices->image_expiry_age = 0; else new_choices->expiry_age = 0; } else { if ((window = choices_find_component(CD_HiExpiryAge)) != 0) { numberrange_get_value(0, window, CD_HiExpiryAge, &temp); if (history_radio) new_choices->image_expiry_age = choices_typed_time_to_seconds(temp, history_expiry_units); else new_choices->expiry_age = choices_typed_time_to_seconds(temp, history_expiry_units); } } if (max_size_greyed) { if (history_radio) new_choices->image_max_size = 0; else new_choices->max_size = 0; } else { if ((window = choices_find_component(CD_HiMaxSize)) != 0) { numberrange_get_value(0, window, CD_HiMaxSize, &temp); if (history_radio) new_choices->image_max_size = temp * 1024; else new_choices->max_size = temp * 1024; } } switch(idb->self_component) { case CD_HiRadPage: history_radio = 0; if ((window = choices_find_component(CD_HiExpiryAge)) != 0) choices_set_expiry_age(window); if ((window = choices_find_component(CD_HiMaxSize)) != 0) choices_set_max_size(window); break; case CD_HiRadImage: history_radio = 1; if ((window = choices_find_component(CD_HiExpiryAge)) != 0) choices_set_expiry_age(window); if ((window = choices_find_component(CD_HiMaxSize)) != 0) choices_set_max_size(window); break; } } return 1; } /*************************************************/ /* choices_set_expiry_age() */ /* */ /* Sets up the expiry age fields and greys/ */ /* ungreys them as appropriate. */ /* */ /* Parameters: ObjectId of the window containing */ /* the gadgets. */ /*************************************************/ static void choices_set_expiry_age(ObjectId window) { int temp; int rangetop; int time_scale; int age; age = history_radio ? new_choices->image_expiry_age : new_choices->expiry_age; if (age == 0) { temp = 1; time_scale = CD_TimeDays; rangetop = 7; } else { time_scale = choices_return_appropriate_timetype(age); temp = choices_seconds_to_typed_time(age, time_scale); rangetop = choices_get_range_of_typed_time(time_scale); } expiry_age_greyed = !age; choices_set_expiry_age_greyed(window, !age); optionbutton_set_state(0, window, CD_HiDontAge, !!age); choices_numberrange_set_value(0, window, CD_HiExpiryAge, temp); choices_set_timetype_field(time_scale, CD_HiAgeTypeDisp); history_expiry_units = time_scale; numberrange_set_bounds(15, window, CD_HiExpiryAge, 1, rangetop, 1, 0); } /*************************************************/ /* choices_set_expiry_age_greyed() */ /* */ /* Sets the expiry age gadgets to greyed/ */ /* ungreyed. */ /* */ /* Parameters: ObjectId of the window which */ /* contains the icons. */ /* */ /* 0 to ungrey, any other value to */ /* to grey. */ /*************************************************/ static void choices_set_expiry_age_greyed(ObjectId window, int state) { set_gadget_state(window, CD_HiExpiryAgeLabl, !!state); set_gadget_state(window, CD_HiExpiryAge, !!state); set_gadget_state(window, CD_HiAgeTypeDisp, !!state); set_gadget_state(window, CD_HiAgeTypeBt, !!state); } /*************************************************/ /* choices_set_im_expiry_age() */ /* */ /* Sets up the image expiry age fields and greys */ /* /ungreys them as appropriate. */ /* */ /* Parameters: ObjectId of the window containing */ /* the gadgets. */ /*************************************************/ static void choices_set_im_expiry_age(ObjectId window) { int temp; int rangetop; int time_scale; if (new_choices->image_expiry_age == 0) { temp = 1; time_scale = CD_TimeDays; rangetop = 7; } else { time_scale = choices_return_appropriate_timetype(new_choices->image_expiry_age); temp = choices_seconds_to_typed_time(new_choices->image_expiry_age, time_scale); rangetop = choices_get_range_of_typed_time(time_scale); } image_expiry_age_greyed = !new_choices->image_expiry_age; choices_set_im_expiry_age_greyed(window, !new_choices->image_expiry_age); optionbutton_set_state(0, window, CD_HiImDontAge, !!new_choices->image_expiry_age); choices_numberrange_set_value(0, window, CD_HiImExpiryAge, temp); choices_set_timetype_field(time_scale, CD_HiImAgeTypeDisp); image_expiry_units = time_scale; numberrange_set_bounds(15, window, CD_HiImExpiryAge, 1, rangetop, 1, 0); } /*************************************************/ /* choices_set_im_expiry_age_greyed() */ /* */ /* Sets the image expiry age gadgets to greyed/ */ /* ungreyed. */ /* */ /* Parameters: ObjectId of the window which */ /* contains the icons. */ /* */ /* 0 to ungrey, any other value to */ /* to grey. */ /*************************************************/ static void choices_set_im_expiry_age_greyed(ObjectId window, int state) { set_gadget_state(window, CD_HiImExpiryAgeLabl, !!state); set_gadget_state(window, CD_HiImExpiryAge, !!state); set_gadget_state(window, CD_HiImAgeTypeDisp, !!state); set_gadget_state(window, CD_HiImAgeTypeBt, !!state); } /*************************************************/ /* choices_set_max_size() */ /* */ /* Sets up the max size field and greys or */ /* ungreys it as appropriate. */ /* */ /* Parameters: The ObjectId of the window which */ /* contains the gadgets. */ /*************************************************/ static void choices_set_max_size(ObjectId window) { int size; size = history_radio ? new_choices->image_max_size : new_choices->max_size; optionbutton_set_state(0, window, CD_HiDontSize, !!size); max_size_greyed = !size; choices_set_max_size_greyed(window, max_size_greyed); choices_numberrange_set_value(0, window, CD_HiMaxSize, !size ? 32 : size/1024); } /*************************************************/ /* choices_set_max_size_greyed() */ /* */ /* Sets the max size gadgets to greyed/ungreyed. */ /* */ /* Parameters: ObjectId of the window which */ /* contains the icons. */ /* */ /* 0 to ungrey, any other value to */ /* to grey. */ /*************************************************/ static void choices_set_max_size_greyed(ObjectId window, int state) { set_gadget_state(window, CD_HiMaxSizeLabl1, !!state); set_gadget_state(window, CD_HiMaxSizeLabl2, !!state); set_gadget_state(window, CD_HiMaxSize, !!state); } /*************************************************/ /* choices_set_im_max_size() */ /* */ /* Sets up the image max size field and greys or */ /* ungreys it as appropriate. */ /* */ /* Parameters: The ObjectId of the window which */ /* contains the gadgets. */ /*************************************************/ static void choices_set_im_max_size(ObjectId window) { optionbutton_set_state(0, window, CD_HiImDontSize, !!new_choices->image_max_size); image_max_size_greyed = !new_choices->image_max_size; choices_set_im_max_size_greyed(window, image_max_size_greyed); choices_numberrange_set_value(0, window, CD_HiImMaxSize, !new_choices->image_max_size ? 32 : new_choices->image_max_size/1024); } /*************************************************/ /* choices_set_im_max_size_greyed() */ /* */ /* Sets the image max size gadgets to greyed/ */ /* ungreyed. */ /* */ /* Parameters: ObjectId of the window which */ /* contains the icons. */ /* */ /* 0 to ungrey, any other value to */ /* to grey. */ /*************************************************/ static void choices_set_im_max_size_greyed(ObjectId window, int state) { set_gadget_state(window, CD_HiImMaxSizeLabl1, !!state); set_gadget_state(window, CD_HiImMaxSizeLabl2, !!state); set_gadget_state(window, CD_HiImMaxSize, !!state); } /*************************************************/ /* choices_set_timetype_field() */ /* */ /* Sets the time field appropriately to reflect */ /* the passed state. Also ticks the appropriate */ /* item in the menu. */ /* */ /* Parameters: timetype - see defined values in */ /* choices.h */ /*************************************************/ _kernel_oserror * choices_set_timetype_field(int timetype, ComponentId comp) { _kernel_oserror * e; ObjectId destwind; ObjectId menu_id; char * tempstring; #ifdef TRACE if (tl & (1u<<29)) Printf("choices_set_plugin_field: Called\n"); #endif /* Find which window the encoding display is in */ destwind = choices_find_component(comp); if (!destwind) return NULL; RetError(toolbox_create_object(0, "ChTime", &menu_id)); RetError(choices_get_menu_entry_text("ChTime", timetype, &tempstring)); RetError(choices_set_timetype_tick(timetype)); e = choices_displayfield_set_value(0, destwind, comp, tempstring); free(tempstring); return NULL; } /*************************************************/ /* choices_set_timetype_tick() */ /* */ /* Ticks the appropriate item in the ChTime menu */ /* */ /* Parameters: timetype - see defined values in */ /* choices.h */ /*************************************************/ _kernel_oserror * choices_set_timetype_tick(int timetype) { ObjectId menu_id; RetError(toolbox_create_object(0, "ChTime", &menu_id)); if (time_ticked != -1) { RetError(menu_set_tick(0, menu_id, time_ticked, 0)); } RetError(menu_set_tick(0, menu_id, timetype, 1)); time_ticked = timetype; return NULL; } /*************************************************/ /* choices_timetype_m_button_handler() */ /* */ /* Displays the time units menu when the */ /* appropriate toolaction button is pressed. */ /*************************************************/ static int choices_timetype_m_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror * e; int position[2]; BBox box; WimpGetWindowStateBlock state; ObjectId display; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of display menu to top left of display button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); switch(idb->self_component) { case CD_HiAgeTypeBt: choices_set_timetype_tick(history_expiry_units); break; case CD_HiImAgeTypeBt: choices_set_timetype_tick(image_expiry_units); break; } e = toolbox_create_object(0, "ChTime", &display); if (e) { show_error_ret(e); return 1; } show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, display, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); return 1; } /*************************************************/ /* choices_timetype_m_click_handler() */ /* */ /* Handles clicks in the time units menu. */ /* Translates the current expiry time to the new */ /* units and places the name of the units in the */ /* appropriate display field. */ /*************************************************/ static int choices_timetype_m_click_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { ObjectId window; int temptime; window = idb->parent_id; switch(idb->parent_component) { case CD_HiAgeTypeBt: { numberrange_get_value(0, window, CD_HiExpiryAge, &temptime); temptime = choices_typed_time_to_seconds(temptime, history_expiry_units); choices_set_timetype_field(idb->self_component, CD_HiAgeTypeDisp); history_expiry_units = idb->self_component; numberrange_set_value(0, window, CD_HiExpiryAge, choices_seconds_to_typed_time(temptime, history_expiry_units)); numberrange_set_bounds(15, window, CD_HiExpiryAge, 1, choices_get_range_of_typed_time(history_expiry_units), 1, 0); break; } case CD_HiImAgeTypeBt: { numberrange_get_value(0, window, CD_HiImExpiryAge, &temptime); temptime = choices_typed_time_to_seconds(temptime, image_expiry_units); choices_set_timetype_field(idb->self_component, CD_HiImAgeTypeDisp); image_expiry_units = idb->self_component; numberrange_set_value(0, window, CD_HiImExpiryAge, choices_seconds_to_typed_time(temptime, image_expiry_units)); numberrange_set_bounds(15, window, CD_HiImExpiryAge, 1, choices_get_range_of_typed_time(image_expiry_units), 1, 0); break; } } return 1; } /*************************************************/ /* choices_typed_time_to_seconds() */ /* */ /* Converts a time in the passed units to */ /* seconds. */ /* */ /* Parameters: Time in passed units; */ /* */ /* units which the time was passed */ /* as (defined in choices.h); */ /* */ /* Returns: time in seconds. */ /*************************************************/ static int choices_typed_time_to_seconds(int time, int timetype) { switch(timetype) { case CD_TimeMinutes: return time * 60; case CD_TimeHours: return time * 60*60; case CD_TimeDays: return time * 60*60*24; case CD_TimeWeeks: return time * 60*60*24*7; case CD_TimeMonths: return time * 60*60*24*7*4; default: return 0; } } /*************************************************/ /* choices_clip_to_min_max() */ /* */ /* Clips a number to a minimum and maximum value */ /* */ /* Parameters: initial value; */ /* */ /* minimum; */ /* */ /* maximum. */ /* */ /* Returns: clipped value. */ /*************************************************/ int choices_clip_to_min_max(int value, int min, int max) { return value > max ? max : (value < min ? min : value); } /*************************************************/ /* choices_seconds_to_typed_time() */ /* */ /* Converts a time in seconds to a time in the */ /* passed units. */ /* */ /* Parameters: time in seconds; */ /* */ /* the units to return time in as */ /* defined in choices.h; */ /* */ /* Returns: the time in the passed units. */ /*************************************************/ static int choices_seconds_to_typed_time(int secs, int timetype) { switch(timetype) { case CD_TimeMinutes: return choices_clip_to_min_max(secs/(60), 1, 60); case CD_TimeHours: return choices_clip_to_min_max(secs/(60*60), 1, 24); case CD_TimeDays: return choices_clip_to_min_max(secs/(60*60*24), 1, 7); case CD_TimeWeeks: return choices_clip_to_min_max(secs/(60*60*24*7), 1, 4); case CD_TimeMonths: return choices_clip_to_min_max(secs/(60*60*24*7*4), 1, 12); default: return 1; } } /*************************************************/ /* choices_return_appropriate_timetype() */ /* */ /* Given a time in seconds returns the most */ /* appropriate set of units to display that time */ /* in. */ /* */ /* Parameters: time in seconds. */ /* */ /* Returns: the type of the appropriate units */ /* as defined in choices.h */ /*************************************************/ static int choices_return_appropriate_timetype(int seconds) { if (seconds <= 60*60) return CD_TimeMinutes; if (seconds <= 60*60*24) return CD_TimeHours; if (seconds <= 60*60*24*7) return CD_TimeDays; if (seconds <= 60*60*24*7*4) return CD_TimeWeeks; return CD_TimeMonths; } /*************************************************/ /* choices_get_range_of_typed_time() */ /* */ /* Returns the max acceptable value of the */ /* passed time units type. */ /* */ /* Parameters: the type of time units. (defined */ /* in choices.h) */ /* */ /* Returns: the maximum acceptable value. */ /*************************************************/ static int choices_get_range_of_typed_time(int timetype) { switch(timetype) { case CD_TimeMinutes: return 60; case CD_TimeHours: return 24; case CD_TimeDays: return 7; case CD_TimeWeeks: return 4; case CD_TimeMonths: return 12; default: return 0; } } /*************************************************/ /* choices_set_tables_greyed() */ /* */ /* Sets the table border gadgets to greyed/ */ /* ungreyed. */ /* */ /* Parameters: ObjectId of the window which */ /* contains the icons. */ /* */ /* 0 to ungrey, any other value to */ /* to grey. */ /*************************************************/ static void choices_set_tables_greyed(int state, ObjectId window) { set_gadget_state(window, CD_TabInnerBordLabl, !!state); set_gadget_state(window, CD_TabInnerBordDisp, !!state); set_gadget_state(window, CD_TabInnerBordBt, !!state); set_gadget_state(window, CD_TabOuterBordLabl, !!state); set_gadget_state(window, CD_TabOuterBordDisp, !!state); set_gadget_state(window, CD_TabOuterBordBt, !!state); } /*************************************************/ /* choices_set_table_border_field() */ /* */ /* Sets the passed display display field */ /* appropriately to reflect the passed state. */ /*************************************************/ static _kernel_oserror * choices_set_table_border_field(ObjectId obj, ComponentId comp, int state) { _kernel_oserror *e; char *tempstring; #ifdef TRACE if (tl & (1u<<29)) Printf("choices_set_table_border_field: Called\n"); #endif RetError(choices_get_menu_entry_text("ChTabBord", state, &tempstring)); e = choices_displayfield_set_value(0, obj, comp, tempstring); free(tempstring); return e; } /*************************************************/ /* choices_bord_m_button_handler() */ /* */ /* Opens the bord menu with a value appropriate */ /* to either the inner or outer table border. */ /*************************************************/ static int choices_bord_m_button_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { _kernel_oserror *e; int position[2]; BBox box; WimpGetWindowStateBlock state; ObjectId display; int new_tick; e = gadget_get_bbox(0, idb->self_id, idb->self_component, &box); if (e) { show_error_ret(e); return 1; } e = window_get_wimp_handle(0, idb->self_id, &state.window_handle); if (e) { show_error_ret(e); return 1; } e = wimp_get_window_state(&state); if (e) { show_error_ret(e); return 1; } /* Set open coordinates of display menu to top left of display button */ position[0] = coords_x_toscreen(box.xmax, (WimpRedrawWindowBlock*)&state); position[1] = coords_y_toscreen(box.ymax, (WimpRedrawWindowBlock*)&state); e = toolbox_create_object(0, "ChTabBord", &display); if (e) { show_error_ret(e); return 1; } switch(idb->self_component) { case CD_TabInnerBordBt: new_tick = new_choices->table_inner; break; case CD_TabOuterBordBt: new_tick = new_choices->table_outer; break; default: new_tick = 0; break; } if (bord_ticked != new_tick) { if (bord_ticked != -1) menu_set_tick(0, display, bord_ticked, 0); menu_set_tick(0, display, new_tick, 1); bord_ticked = new_tick; } show_error_ret(toolbox_show_object(Toolbox_ShowObject_AsMenu, display, Toolbox_ShowObject_TopLeft, position, idb->self_id, idb->self_component)); return 1; } /*************************************************/ /* choices_bord_m_click_handler() */ /* */ /* Handles clicks in the border type menu. Sets */ /* the associated display field and field in the */ /* new_choices structure. */ /*************************************************/ static int choices_bord_m_click_handler(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { if (bord_ticked != idb->self_component) { if (bord_ticked != -1) menu_set_tick(0, idb->self_id, bord_ticked, 0); menu_set_tick(0, idb->self_id, idb->self_component, 1); bord_ticked = idb->self_component; } switch(idb->parent_component) { case CD_TabInnerBordBt: new_choices->table_inner = idb->self_component; break; case CD_TabOuterBordBt: new_choices->table_outer = idb->self_component; break; } choices_set_table_border_field(idb->parent_id, idb->parent_component - 1, idb->self_component); return 1; } /*************************************************/ /* choices_get_menu_entry_text() */ /* */ /* Gets a pointer to a piece of text acquired */ /* from a menu. The pointer is to a malloc */ /* block and so must be freed after use. */ /* */ /* Parameters: pointer to the menu name */ /* */ /* menu componentid */ /* */ /* pointer to char* to use for */ /* the malloc block */ /* */ /* Assumes: the menu is a shared object. */ /*************************************************/ _kernel_oserror * choices_get_menu_entry_text(char * menuname, ComponentId compid, char ** tempstring) { ObjectId menu_id; int reqdsize; RetError(toolbox_create_object(0, menuname, &menu_id)); RetError(menu_get_entry_text(0, menu_id, compid, NULL, 0, &reqdsize)); *tempstring = malloc(reqdsize+1); if (!*tempstring) return make_no_memory_error(20); RetError(menu_get_entry_text(0, menu_id, compid, *tempstring, reqdsize+1, NULL)); return NULL; }