/* 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 : Menus.c */ /* */ /* Purpose: Handle browser menus. */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 20-Nov-96: Created */ /***************************************************/ #include <stdlib.h> #include <string.h> #include "swis.h" #include "wimp.h" #include "wimplib.h" #include "event.h" #include "toolbox.h" #include "window.h" #include "menu.h" #include "svcprint.h" #include "Global.h" #include "FromROSLib.h" #include "MiscDefs.h" #include "Utils.h" #include "Browser.h" #include "Choices.h" #include "Fetch.h" /* (For ISLINK macro) */ #include "FetchPage.h" #include "Frames.h" #include "Handlers.h" #include "History.h" #include "Hotlist.h" #include "Images.h" #include "ImgHistory.h" #include "Multiuser.h" #include "Object.h" #include "OpenURL.h" #include "Reformat.h" #include "Save.h" /* (For menu component IDs) */ #include "Toolbars.h" #include "URLutils.h" #include "Windows.h" #include "Menus.h" /* Local statics */ static browser_data * document_menu_browser = NULL; static HStream * document_menu_opened_over = NULL; /* Static function prototypes */ static void menus_toggle_bars (IdBlock * idb); static void menus_toggle_look (IdBlock * idb); static void menus_choices_bars (IdBlock * idb); static void menus_choices_other (IdBlock * idb); static void menus_history_selection (IdBlock * idb); static void menus_main_selection (IdBlock * idb); /*************************************************/ /* menus_item_selected() */ /* */ /* Following a Menu_Selection event from the */ /* toolbox, work out what to do with it. */ /* */ /* Parameters are as for a standard Toolbox */ /* event handler. */ /*************************************************/ int menus_item_selected(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { #ifdef TRACE if (tl & (1u<<4)) Printf("menus_item_selected: Called\n"); #endif switch (idb->self_component) { case UtilsURLBar: case UtilsButtonBar: case UtilsStatusBar: menus_toggle_bars(idb); break; case UtilsFullScreen: case UtilsUnderlineLinks: case UtilsUseDocumentColours: case UtilsShowForegroundImages: case UtilsShowBackgroundImages: menus_toggle_look(idb); break; case ChoicesURLBar: case ChoicesButtonBar: case ChoicesStatusBar: menus_choices_bars(idb); break; case ChoicesFullScreen: case ChoicesUnderlineLinks: case ChoicesUseDocumentColours: case ChoicesShowForegroundImages: case ChoicesShowBackgroundImages: menus_choices_other(idb); break; case ChoicesSave: ChkError(save_save_choices(NULL)); break; case HistoryEmptyLocal: case HistoryEmptyGlobal: case HistoryEmptyImage: menus_history_selection(idb); break; case MainLogOut: case MainCache: menus_main_selection(idb); break; default: return 0; } #ifdef TRACE if (tl & (1u<<4)) Printf("menus_item_selected: Successful\n"); #endif return 1; } /*************************************************/ /* menus_toggle_tick() */ /* */ /* Toggles the state of a given tick in a menu. */ /* */ /* Parameters: The object ID of the menu; */ /* */ /* The component ID to alter. */ /* */ /* Returns: 1 if item is now ticked, else 0. */ /*************************************************/ int menus_toggle_tick(ObjectId o, ComponentId c) { int t = 0; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_tick: Called\n"); #endif menu_get_tick(0,o,c,&t); t ? (t = 0) : (t = 1); menu_set_tick(0,o,c,t); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_tick: Successful\n"); #endif return t; } /*************************************************/ /* menus_show_main() */ /* */ /* Called before the main menu is showed from */ /* from the icon bar. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_show_main(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { unsigned int task_handle = 0; utils_get_task_handle(lookup_token("ProxyName:Acorn WebServe",0,0), &task_handle); if (!task_handle) menu_set_fade(0, idb->self_id, MainCache, 1); else menu_set_fade(0, idb->self_id, MainCache, 0); #ifndef SINGLE_USER if (!logged_in) { menu_set_fade(0, idb->self_id, MainChoices, 1); menu_set_fade(0, idb->self_id, MainOpenURL, 1); menu_set_fade(0, idb->self_id, MainShowHotlist, 1); menu_set_fade(0, idb->self_id, MainHelp, 1); menu_set_fade(0, idb->self_id, MainLogOut, 1); } else { menu_set_fade(0, idb->self_id, MainChoices, 0); menu_set_fade(0, idb->self_id, MainOpenURL, 0); menu_set_fade(0, idb->self_id, MainShowHotlist, 0); menu_set_fade(0, idb->self_id, MainHelp, 0); menu_set_fade(0, idb->self_id, MainLogOut, 0); } #endif return 1; } /*************************************************/ /* menus_show_utils() */ /* */ /* Called when the utils menu is about to be */ /* opened from a main menu in a browser window. */ /* Handles turning ticks on and off in items. */ /* Parameters are as standard for a Toolbox */ /* event handler */ /*************************************************/ int menus_show_utils(int eventcode, ToolboxEvent * event, IdBlock * idb, void *handle) { browser_data * b; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_utils: Called\n"); #endif /* Find the browser_data structure for the browser (ancestor) window */ ChkError(toolbox_get_client_handle(0,idb->ancestor_id,(void *) &b)); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_utils: For ancestor client handle %p\n",(void *) b); #endif /* Set ticks according to the current toolbar status. */ /* This should be for an ancestor window, and not for */ /* any child frames. Similarly, the Full Screen */ /* state comes from the ancestor browser. */ { browser_data * ancestor = utils_ancestor(b); menu_set_tick(0, idb->self_id, UtilsURLBar, ancestor->url_bar); menu_set_tick(0, idb->self_id, UtilsButtonBar, ancestor->button_bar); menu_set_tick(0, idb->self_id, UtilsStatusBar, ancestor->status_bar); menu_set_tick(0, idb->self_id, UtilsFullScreen, ancestor->full_screen); } /* Set ticks according to general options. These are specific */ /* to each window. */ menu_set_tick(0, idb->self_id, UtilsUnderlineLinks, b->underline_links); menu_set_tick(0, idb->self_id, UtilsUseDocumentColours, b->use_source_cols); menu_set_tick(0, idb->self_id, UtilsShowForegroundImages, b->show_foreground); menu_set_tick(0, idb->self_id, UtilsShowBackgroundImages, b->show_background); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_utils: Successful\n"); #endif return 1; } /*************************************************/ /* menus_show_file() */ /* */ /* Called when the File submenu is about to be */ /* opened from a browser window's main menu. */ /* Deals with greying of entries as appropriate. */ /*************************************************/ int menus_show_file(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; browser_data * parent; browser_data * ancestor; char * url; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_file: Called\n"); #endif /* Find the browser_data structure for the browser (ancestor) window */ ChkError(toolbox_get_client_handle(0,idb->ancestor_id,(void *) &b)); if (!b) return 1; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_file: For ancestor client handle %p\n",(void *) b); #endif parent = utils_parent(b); ancestor = utils_ancestor(b); if (ancestor == b) ancestor = NULL; /* If there is HTML source present, unfade the Save entry - else fade it out */ if (b->source) menu_set_fade(0, idb->self_id, FileSaveFrame, 0); else menu_set_fade(0, idb->self_id, FileSaveFrame, 1); /* Similarly, for a parent */ if (parent && parent->source) menu_set_fade(0, idb->self_id, FileSaveParent, 0); else menu_set_fade(0, idb->self_id, FileSaveParent, 1); /* Lastly, the ancestor */ if (ancestor && ancestor->source) menu_set_fade(0, idb->self_id, FileSaveAncestor, 0); else menu_set_fade(0, idb->self_id, FileSaveAncestor, 1); /* If the browser has children or no line list, you can't print from it */ if (b->nchildren || !b->cell || !b->cell->nlines) menu_set_fade(0, idb->self_id, FilePrint, 1); else menu_set_fade(0, idb->self_id, FilePrint, 0); /* Do we have a current location? */ url = browser_current_url(b); if (url && *url) menu_set_fade(0, idb->self_id, FileSaveFrameLocation, 0); else menu_set_fade(0, idb->self_id, FileSaveFrameLocation, 1); /* Does the parent have a current location? */ url = parent ? browser_current_url(parent) : NULL; if (url && *url) menu_set_fade(0, idb->self_id, FileSaveParentLocation, 0); else menu_set_fade(0, idb->self_id, FileSaveParentLocation, 1); /* Does the ancestor have a current location? */ url = ancestor ? browser_current_url(ancestor) : NULL; if (url && *url) menu_set_fade(0, idb->self_id, FileSaveAncestorLocation, 0); else menu_set_fade(0, idb->self_id, FileSaveAncestorLocation, 1); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_file: Successful\n"); #endif return 1; } /*************************************************/ /* menus_show_navigate() */ /* */ /* Called when the Navigate submenu is about to */ /* be opened from a browser window's main menu. */ /* Deals with greying of entries as appropriate. */ /*************************************************/ int menus_show_navigate(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_navigate: Called\n"); #endif /* Find the browser_data structure for the browser (ancestor) window */ ChkError(toolbox_get_client_handle(0,idb->ancestor_id,(void *) &b)); if (!b) return 1; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_navigate: For ancestor client handle %p\n",(void *) b); #endif /* Can only stop if there's activity of some sort */ if ( (b->anim_handler && !b->anim_drift) || (b->meta_refresh_at && b->meta_refresh_url) ) menu_set_fade(0, idb->self_id, NavigateStopAllFetches, 0); else menu_set_fade(0, idb->self_id, NavigateStopAllFetches, 1); /* Can only go back if we're not at the start of the history */ /* and there's a history to go into. */ if (!history_can_go_backwards(b)) menu_set_fade(0, idb->self_id, NavigateBack, 1); else menu_set_fade(0, idb->self_id, NavigateBack, 0); /* Can only go forward if we're in the history somewhere */ if (!history_can_go_forwards(b)) menu_set_fade(0, idb->self_id, NavigateForward, 1); else menu_set_fade(0, idb->self_id, NavigateForward, 0); /* Only need to load images if delayed image loading is set */ /* in the local browser flags, or plain backgrounds are set. */ if ( ( !b->show_foreground && b->displayed != Display_External_Image ) || !b->show_background ) menu_set_fade(0, idb->self_id, NavigateLoadAllImages, 0); else menu_set_fade(0, idb->self_id, NavigateLoadAllImages, 1); /* Finished */ return 1; } /*************************************************/ /* menus_show_export() */ /* */ /* Called before the Export menu is showed. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_show_export(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; HStream * over; ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); if (!is_known_browser(b)) { #ifdef TRACE erb.errnum = Utils_Error_Custom_Normal; sprintf(erb.errmess, "Browser %p is unknown in menus_show_export", b); ChkError(&erb); #endif return 0; } /* The rest are supported, but may not be valid depending on */ /* what the menu was opened over. */ over = menus_document_opened_over(); /* Export a link */ if (!over || !ISLINK(over)) menu_set_fade(0, idb->self_id, ExportLink, 1); else menu_set_fade(0, idb->self_id, ExportLink, 0); /* Export a foreground image */ if ( !over || ! ( (over->style & IMG) || ( over->tagno == TAG_INPUT && HtmlINPUTtype(over) == inputtype_IMAGE ) || ( ISOBJECT(over) && object_token_is_image(b, over) ) ) ) menu_set_fade(0, idb->self_id, ExportPicture, 1); else { if (image_token_can_be_saved_as_sprite(b, over)) menu_set_fade(0, idb->self_id, ExportPicture, 0); else menu_set_fade(0, idb->self_id, ExportPicture, 1); } /* Export a background image */ if (b && b->background_image < 0) menu_set_fade(0, idb->self_id, ExportBackground, 1); else { if (image_token_can_be_saved_as_sprite(b, NULL)) menu_set_fade(0, idb->self_id, ExportBackground, 0); else menu_set_fade(0, idb->self_id, ExportBackground, 1); } /* Export page as Draw or a text file */ if (b && !b->nchildren && b->cell && b->cell->nlines) { menu_set_fade(0, idb->self_id, ExportAsText, 0); menu_set_fade(0, idb->self_id, ExportAsDraw, 0); } else { menu_set_fade(0, idb->self_id, ExportAsText, 1); menu_set_fade(0, idb->self_id, ExportAsDraw, 1); } /* Finished */ return 1; } /*************************************************/ /* menus_show_choices() */ /* */ /* Called when the choices menu is about to be */ /* opened from the icon bar menu. Handles */ /* turning ticks on and off depending on the */ /* Messages file's choices entries. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_show_choices(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_choices: Called\n"); #endif menu_set_tick(0, idb->self_id, ChoicesURLBar, choices.url_bar); menu_set_tick(0, idb->self_id, ChoicesButtonBar, choices.button_bar); menu_set_tick(0, idb->self_id, ChoicesStatusBar, choices.status_bar); menu_set_tick(0, idb->self_id, ChoicesUnderlineLinks, choices.underline_links); menu_set_tick(0, idb->self_id, ChoicesUseDocumentColours, choices.use_source_cols); menu_set_tick(0, idb->self_id, ChoicesShowForegroundImages, choices.show_foreground); menu_set_tick(0, idb->self_id, ChoicesShowBackgroundImages, choices.show_background); menu_set_tick(0, idb->self_id, ChoicesFullScreen, choices.full_screen); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_show_choices: Successful\n"); #endif return 1; } /*************************************************/ /* menus_show_document() */ /* */ /* Called before the document menu is showed */ /* from a browser window. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_show_document(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { WimpGetPointerInfoBlock info; browser_data * b; ChkError(wimp_get_pointer_info(&info)); ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); if (!is_known_browser(b)) return 0; document_menu_browser = b; document_menu_opened_over = browser_get_pointer_token(b, &info, NULL, NULL); return 1; } /*************************************************/ /* menus_show_history() */ /* */ /* Called before the History menu is displayed. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_show_history(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); if (!is_known_browser(b) || history_empty(b)) { menu_set_fade(0, idb->self_id, HistorySaveLocal, 1); menu_set_fade(0, idb->self_id, HistoryEmptyLocal, 1); } else { menu_set_fade(0, idb->self_id, HistorySaveLocal, 0); menu_set_fade(0, idb->self_id, HistoryEmptyLocal, 0); } if (history_empty(NULL)) { menu_set_fade(0, idb->self_id, HistorySaveGlobal, 1); menu_set_fade(0, idb->self_id, HistoryEmptyGlobal, 1); } else { menu_set_fade(0, idb->self_id, HistorySaveGlobal, 0); menu_set_fade(0, idb->self_id, HistoryEmptyGlobal, 0); } if (imghistory_empty()) menu_set_fade(0, idb->self_id, HistoryEmptyImage, 1); else menu_set_fade(0, idb->self_id, HistoryEmptyImage, 0); return 1; } /*************************************************/ /* menus_hide_document() */ /* */ /* Called before the document menu is hidden. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_hide_document(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { document_menu_opened_over = NULL; document_menu_browser = NULL; /* Pass on - others (eg Encoding.c) may be interested */ return 0; } /*************************************************/ /* menus_close_document_if_mine() */ /* */ /* If a document menu is open and its origin was */ /* the given browser, close it. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* relevant to the menu. */ /* */ /* Returns: 1 if the menu was closed, else 0. */ /*************************************************/ int menus_close_document_if_mine(browser_data * b) { if (b && b == document_menu_browser) { _swix(Wimp_CreateMenu, _IN(1), -1); return 1; } return 0; } /*************************************************/ /* menus_toggle_bars() */ /* */ /* Called when one of the Utils menu items that */ /* turns info/toolbars on and off is selected. */ /* */ /* The item is ticked or unticked as necessary */ /* and the relevant toolbar turned on or off. */ /* */ /* Parameters: Pointer to an ID block, as given */ /* by the Toolbox when it raises an */ /* event. */ /*************************************************/ static void menus_toggle_bars(IdBlock * idb) { int t = 0, height; browser_data * b; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_bars: Called\n"); #endif /* Find the browser_data structure for the browser (ancestor) window */ ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); /* Bars are only attached to the ancestor browser_data struct, */ /* not to any child frames. So want to point b to this. */ b = utils_ancestor(b); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_bars: For ancestor client handle %p\n",(void *) b); #endif /* Swap the menu's tick state */ t = menus_toggle_tick(idb->self_id, idb->self_component); /* Remember height of top toolbar */ if (!controls.swap_bars) height = toolbars_button_height(b) + toolbars_url_height(b); else height = toolbars_status_height(b); /* For URL and Button bars, need to move the page contents up and down, */ /* so remember the total bar height before removing or adding one of */ /* those bars. For the status bar it doesn't matter. */ switch (idb->self_component) { case UtilsURLBar: b->url_bar = t, toolbars_set_presence(b, InternalTopLeft); break; case UtilsButtonBar: b->button_bar = t, toolbars_set_presence(b, InternalTopLeft); break; case UtilsStatusBar: b->status_bar = t, toolbars_set_presence(b, InternalBottomLeft); break; #ifdef TRACE default: { _kernel_oserror e; e.errnum = Utils_Error_Custom_Normal; strncpy(e.errmess,"Toolbar toggle handle not understood in menus_toggle_bars.",252); show_error_cont(&e); } #endif } /* Move any data inside the page as necessary */ if (!controls.swap_bars) { ChkError(reformat_shift_vertically(b, 0, b->cell->nlines - 1, height - toolbars_url_height(b) - toolbars_button_height(b))); } else { ChkError(reformat_shift_vertically(b, 0, b->cell->nlines - 1, height - toolbars_status_height(b))); } ChkError(reformat_check_extent(b)); /* If there are any frames on the page, resize them */ if (b->nchildren) { WimpGetWindowStateBlock state; state.window_handle = b->window_handle; ChkError(wimp_get_window_state(&state)); frames_resize_frameset(b, &state.visible_area); } #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_bars: Successful\n"); #endif } /*************************************************/ /* menus_toggle_look() */ /* */ /* Called when one of the Utils menu items not */ /* related to toolbars is selected. */ /* */ /* The item is ticked or unticked as necessary */ /* and the relevant visual aspect of the browser */ /* window turned on or off. */ /* */ /* Any child frames at this frame level or */ /* higher will inherit the new characteristics. */ /* */ /* Parameters: Pointer to an ID block, as given */ /* by the Toolbox when it raises an */ /* event. */ /*************************************************/ static void menus_toggle_look(IdBlock * idb) { int t = 0; ObjectId browser; browser_data * b; browser_data * ancestor; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_look: Called\n"); #endif /* Find the browser_data structure for the browser (ancestor) window */ browser = idb->ancestor_id; ChkError(toolbox_get_client_handle(0, browser, (void *) &b)); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_look: For ancestor client handle %p\n",(void *) b); #endif ancestor = utils_ancestor(b); /* Swap the menu's tick state */ t = menus_toggle_tick(idb->self_id, idb->self_component); /* Reflect changes in ancestor and children */ /* (Un)Set the relevant flag inside the browser_data structure */ switch (idb->self_component) { case UtilsUnderlineLinks: ChkError(browser_set_look(b, idb->self_id, t, -1, -1, -1)); break; case UtilsUseDocumentColours: ChkError(browser_set_look(b, idb->self_id, -1, t, -1, -1)); break; case UtilsShowForegroundImages: ChkError(browser_set_look(b, idb->self_id, -1, -1, t, -1)); break; case UtilsShowBackgroundImages: ChkError(browser_set_look(b, idb->self_id, -1, -1, -1, t)); break; case UtilsFullScreen: { browser_data * ancestor = utils_ancestor(b); /* Can only go Full Screen for ancestor objects */ ancestor->full_screen = t; /* This opens full screen, remembering the previous window size */ ChkError(windows_open_full_screen(ancestor, t, !t, choices.v_scroll, choices.h_scroll)); /* Reformat the page */ ChkError(reformat_format_from(ancestor, -1, 1, -1)); } break; /* Report error for default case in TRACE builds as a warning */ /* to the programmer only. */ #ifdef TRACE default: { _kernel_oserror e; if (b->ancestor) return; /* Avoid giving error for all the child windows */ e.errnum = Utils_Error_Custom_Normal; strncpy(e.errmess,"Menu selection not understood in menus_toggle_look.",252); show_error_cont(&e); } #endif } /* Update the ancestor buttons */ ChkError(toolbars_set_button_states(ancestor)); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_toggle_look: Successful\n"); #endif } /*************************************************/ /* menus_choices_bars() */ /* */ /* Called when one of the Choices menu items */ /* relating to toolbars is selected. Toggles the */ /* menu item's tick and (un)sets the relevant */ /* bit in the global Choices. */ /* */ /* Parameters: Pointer to an ID block, as given */ /* by the Toolbox when it raises an */ /* event. */ /*************************************************/ static void menus_choices_bars(IdBlock * idb) { int t; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_choices_bars: Called\n"); #endif t = menus_toggle_tick(idb->self_id,idb->self_component); switch (idb->self_component) { case ChoicesURLBar: choices.url_bar = t; break; case ChoicesButtonBar: choices.button_bar = t; break; case ChoicesStatusBar: choices.status_bar = t; break; #ifdef TRACE default: { _kernel_oserror e; e.errnum = Utils_Error_Custom_Normal; strncpy(e.errmess,"Toolbar toggle handle not understood in menus_choices_bars.",252); show_error_cont(&e); } #endif } #ifdef TRACE if (tl & (1u<<4)) Printf("menus_choices_bars: Successful\n"); #endif } /*************************************************/ /* menus_choices_other() */ /* */ /* Called when one of the Choices menu items */ /* relating to something other than toolbars is */ /* selected. Toggles the menu item's tick and */ /* (un)sets the relevant bit in the global */ /* Choices. */ /* */ /* Parameters: Pointer to an ID block, as given */ /* by the Toolbox when it raises an */ /* event. */ /*************************************************/ static void menus_choices_other(IdBlock * idb) { int t; #ifdef TRACE if (tl & (1u<<4)) Printf("menus_choices_other: Called\n"); #endif t = menus_toggle_tick(idb->self_id,idb->self_component); switch (idb->self_component) { case ChoicesUnderlineLinks: choices.underline_links = t; break; case ChoicesUseDocumentColours: choices.use_source_cols = t; break; case ChoicesShowForegroundImages: choices.show_foreground = t; break; case ChoicesShowBackgroundImages: choices.show_background = t; break; case ChoicesFullScreen: choices.full_screen = t; break; #ifdef TRACE default: { _kernel_oserror e; e.errnum = Utils_Error_Custom_Normal; strncpy(e.errmess,"Menu selection item not understood in menus_choices_other.",252); show_error_cont(&e); } #endif } toolbars_set_all_button_states(); #ifdef TRACE if (tl & (1u<<4)) Printf("menus_choices_other: Successful\n"); #endif } /*************************************************/ /* menus_history_selection() */ /* */ /* Called when one of the History menu items */ /* is selected. */ /* */ /* Parameters: Pointer to an ID block, as given */ /* by the Toolbox when it raises an */ /* event. */ /*************************************************/ static void menus_history_selection(IdBlock * idb) { browser_data * b; if (toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)) b = NULL; if (!is_known_browser(b)) b = NULL; switch (idb->self_component) { // Not really that useful? Amount of memory tied up in local //�histories is typically pretty small. case HistoryEmptyLocal: { if (!b) return; history_remove(b, NULL); toolbars_set_all_button_states(); } break; // Yikes! Perhaps we should have some confirmation here... case HistoryEmptyGlobal: { history_limit(0); toolbars_set_all_button_states(); } break; case HistoryEmptyImage: { imghistory_limit(0); } break; } return; } /*************************************************/ /* menus_main_selection() */ /* */ /* Called when one of the main menu items is */ /* selected. */ /* */ /* Parameters: Pointer to an ID block, as given */ /* by the Toolbox when it raises an */ /* event. */ /*************************************************/ static void menus_main_selection(IdBlock * idb) { switch (idb->self_component) { case MainCache: { unsigned int handle = 0; WimpMessage msg; /* First, get WebServe's task handle */ utils_get_task_handle(lookup_token("ProxyName:Acorn WebServe",0,0), &handle); #ifdef TRACE if (!handle) { /* Didn't find WebServe, so complain and exit */ erb.errnum = Utils_Error_Custom_Message; StrNCpy0(erb.errmess, "WebServe is not present"); show_error_ret(&erb); } #else if (!handle) { /* Didn't find WebServe, so exit */ return; } #endif /* If WebServe is present, send the message */ msg.hdr.size = 32; msg.hdr.sender = task_handle; msg.hdr.my_ref = 0; msg.hdr.your_ref = 0; msg.hdr.action_code = Wimp_MAppControl; msg.data.app_control.version = 1; msg.data.app_control.flags = Wimp_MAppControl_ImmediateAction; msg.data.app_control.reason = Wimp_MAppControl_Configure; ChkError(wimp_send_message(Wimp_EUserMessage, &msg, handle, -1, NULL)); } break; case MainLogOut: { browser_data * current; /* Close all open browser windows */ while (last_browser) { /* Only close ancestor browsers */ current = last_browser; while (current && current->ancestor) current = current->previous; if (current) handle_close_browser(0, NULL, NULL, current); } /* Close the OpenURL dialogue, in case it's open... */ openurl_close(0, 0); #ifndef REMOTE_HOTLIST /* Make sure the hotlist window is closed */ show_error_ret(hotlist_close()); #endif /* Make sure the Choices are closed too */ show_error_ret(choices_close()); /* Finally, log the user out and bring back the */ /* log in prompt. */ show_error_ret(multiuser_logout()); ChkError(multiuser_login()); } break; } } /*************************************************/ /* menus_document_opened_over() */ /* */ /* When the document menu is opened, this sees */ /* if the pointer was over a specific token. */ /* If so, it records this information for */ /* future use (see menus_show_document). This */ /* function returns that token address, or NULL */ /* if the menu isn't open / no token could be */ /* determined. */ /* */ /* Returns: Pointer to the token the pointer */ /* was over when the main menu was */ /* opened, or NULL if the menu is no */ /* longer open / no token could be */ /* determined when it was opened. */ /*************************************************/ HStream * menus_document_opened_over(void) { return document_menu_opened_over; } /*************************************************/ /* menus_document_over_browser() */ /* */ /* Companion function to */ /* menus_document_opened_over, so see that for */ /* details. */ /* */ /* Returns: Pointer to the browser_data */ /* struct representing the browser */ /* the main menu was opened from, if */ /* any (NULL if not). */ /*************************************************/ browser_data * menus_document_over_browser(void) { return document_menu_browser; } /*************************************************/ /* menus_help_from_help_string() */ /* */ /* Visit a URL encoded in the selected menu */ /* item's Interactive Help string. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_help_from_help_string(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; char help[Limits_URL]; /* Find the browser_data structure for the browser (ancestor) window */ if (toolbox_get_client_handle(0,idb->ancestor_id,(void *) &b)) b = NULL; if (!is_known_browser(b)) b = NULL; else b = utils_ancestor(b); if ( menu_get_entry_help_message(0, idb->self_id, idb->self_component, help, sizeof(help), NULL) ) return 0; if (b) ChkError(fetchpage_new(b, help, 1, 0)); else ChkError(windows_create_browser(help, NULL, NULL, NULL, 0)); return 1; } /*************************************************/ /* menus_help_release_notes() */ /* */ /* Visit a URL encoded in the selected menu */ /* item's Interactive Help string, appended by */ /* a filename based on the browser version. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_help_release_notes(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; char * p; char help[Limits_URL]; /* Find the browser_data structure for the browser (ancestor) window */ if (toolbox_get_client_handle(0,idb->ancestor_id,(void *) &b)) b = NULL; if (!is_known_browser(b)) b = NULL; else b = utils_ancestor(b); /* Get the Help string */ if ( menu_get_entry_help_message(0, idb->self_id, idb->self_component, help, sizeof(help), NULL) ) return 0; /* Append the version */ *tokens = '\0'; lookup_token("Version",1,0); if (strlen(tokens) + strlen(help) + sizeof(".html") > sizeof(help)) return 0; /* Convert spaces to underscores and dots to commas */ p = tokens; while (*p) { if (*p == ' ') *p = '_'; if (*p == '.') *p = ','; p++; } /* Append '.html' */ strcat(tokens, ".html"); strcat(help, tokens); /* Fetch the page */ if (b) ChkError(fetchpage_new(b, help, 1, 0)); else ChkError(windows_create_browser(help, NULL, NULL, NULL, 0)); return 1; } /*************************************************/ /* menus_help_about_page() */ /* */ /* Go to the 'about:' page. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int menus_help_about_page(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; /* Find the browser_data structure for the browser (ancestor) window */ if (toolbox_get_client_handle(0,idb->ancestor_id,(void *) &b)) b = NULL; if (!is_known_browser(b)) b = NULL; else b = utils_ancestor(b); if (b) ChkError(fetchpage_new(b, AboutMethod, 1, 0)); else ChkError(windows_create_browser(AboutMethod, NULL, NULL, NULL, 0)); return 1; } /*************************************************/ /* menus_help_miscellaneous() */ /* */ /* Go to a page looked up from Controls under */ /* the name 'JumpToxx' where 'xx' is a 2 digit */ /* hex number obtained from the given parameter. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* in which to fetch the item, or */ /* NULL for a new window; */ /* */ /* Number of token to look for (see */ /* above). */ /*************************************************/ void menus_help_miscellaneous(browser_data * b, int which) { char name[9]; char * url; /* Sanity check */ if (which < 0 || which > 0x7f) return; /* Build the Choices token name */ sprintf(name, "JumpTo%02x", which); /* Read it - exit if not found */ url = lookup_control(name, 1, NULL); if (!strcmp(url, "!")) return; /* Fetch the URL */ if (b) ChkError(fetchpage_new(b, url, 1, 0)); else ChkError(windows_create_browser(url, NULL, NULL, NULL, 0)); return; }