/* 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 : PrintStyle.c */ /* */ /* Purpose: Change print style options with the */ /* PrintStyle dialogue. */ /* */ /* This source is fairly closely tied to */ /* Print.c, as the Print Style dialogue */ /* is typically opened from the Print */ /* dialogue. */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 24-Aug-97: Created. */ /***************************************************/ #include <stdlib.h> #include <string.h> #include "swis.h" #include "wimp.h" #include "wimplib.h" #include "event.h" #include "toolbox.h" #include "printdbox.h" #include "window.h" #include "svcprint.h" #include "Global.h" #include "Utils.h" #include "Browser.h" #include "Menus.h" #include "Printing.h" #include "PrintStyle.h" /* Local structures and supporting definitions */ #define Background_Show_Type_None 0 #define Background_Show_Type_Tables 1 #define Background_Show_Type_All 2 /* Holds info on the Print Style dialogue's contents; small enough */ /* to hold as a static, as the code to dynamically allocate it */ /* would occupy more room than the structure itself. */ typedef struct printstyle_contents { unsigned int underline_links :1; unsigned int use_source_cols :1; unsigned int show_foreground :1; unsigned int show_background :1; unsigned int background_show_type :2; /* 0 = none, 1 = in tables, 2 = all */ unsigned int black_no_background :1; unsigned int always_use_black :1; } printstyle_contents; /* Local statics */ static printstyle_contents contents; /* Remember the old dialogue contents so the Cancel button can work, and */ /* other functions can inquire about the state of the contents without */ /* needing this end to start calling toolbox routines to find out. */ static ObjectId window_id = 0; /* Remember the ID in case it needs closing 'out of the blue'. */ static ObjectId ancestor_id = 0; /* Remember then ancestor ID in case the ancestor closes. */ static int defaults_set = 0; /* Static function prototypes */ static _kernel_oserror * printstyle_read_contents (ObjectId dialogue, printstyle_contents * contents); static _kernel_oserror * printstyle_set_contents (ObjectId dialogue, printstyle_contents * contents); static int printstyle_cancel (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int printstyle_option_group_one (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); /*************************************************/ /* printstyle_read_contents() */ /* */ /* Reads the contents of the Print Style */ /* dialogue into a printstyle_contents struct. */ /* */ /* Parameters: Object ID of the dialogue; */ /* */ /* Pointer to the structure to write */ /* to. */ /*************************************************/ static _kernel_oserror * printstyle_read_contents(ObjectId dialogue, printstyle_contents * contents) { int state; /* Read the four basic display options */ RetError(optionbutton_get_state(0, dialogue, PSUnderlineLinks, &state)); contents->underline_links = !!state; RetError(optionbutton_get_state(0, dialogue, PSUseDocumentColours, &state)); contents->use_source_cols = !!state; RetError(optionbutton_get_state(0, dialogue, PSShowForegroundImages, &state)); contents->show_foreground = !!state; RetError(optionbutton_get_state(0, dialogue, PSShowBackgroundImages, &state)); contents->show_background = !!state; /* Read the background show type */ RetError(radiobutton_get_state(0, dialogue, PSAllBackgrounds, NULL, &state)); switch (state) { default: case PSNoBackgrounds: contents->background_show_type = Background_Show_Type_None; break; case PSTablesOnly: contents->background_show_type = Background_Show_Type_Tables; break; case PSAllBackgrounds: contents->background_show_type = Background_Show_Type_All; break; } /* Finally, read the 'print text in black' options */ RetError(optionbutton_get_state(0, dialogue, PSBlackIfNoBackground, &state)); contents->black_no_background = !!state; RetError(optionbutton_get_state(0, dialogue, PSAlwaysUseBlack, &state)); contents->always_use_black = !!state; return NULL; } /*************************************************/ /* printstyle_set_contents() */ /* */ /* Sets the contents of the Print Style dialogue */ /* from a printstyle_contents structure. */ /* */ /* Parameters: Object ID of the dialogue; */ /* */ /* Pointer to the structure to read */ /* from. */ /*************************************************/ static _kernel_oserror * printstyle_set_contents(ObjectId dialogue, printstyle_contents * contents) { /* Set the four basic display options */ RetError(optionbutton_set_state(0, dialogue, PSUnderlineLinks, contents->underline_links)); RetError(optionbutton_set_state(0, dialogue, PSUseDocumentColours, contents->use_source_cols)); RetError(optionbutton_set_state(0, dialogue, PSShowForegroundImages, contents->show_foreground)); RetError(optionbutton_set_state(0, dialogue, PSShowBackgroundImages, contents->show_background)); /* Ensure the browser (if any) is up to date with this */ printstyle_option_group_one(0, NULL, NULL, NULL); /* Set the background show type */ switch (contents->background_show_type) { default: case Background_Show_Type_None: RetError(radiobutton_set_state(0, dialogue, PSNoBackgrounds, 1)); break; case Background_Show_Type_Tables: RetError(radiobutton_set_state(0, dialogue, PSTablesOnly, 1)); break; case Background_Show_Type_All: RetError(radiobutton_set_state(0, dialogue, PSAllBackgrounds, 1)); } /* Finally, set the 'print text in black' options */ RetError(optionbutton_set_state(0, dialogue, PSBlackIfNoBackground, contents->black_no_background)); return optionbutton_set_state(0, dialogue, PSAlwaysUseBlack, contents->always_use_black); } /*************************************************/ /* printstyle_set_defaults() */ /* */ /* Fills in the local printstyle_contents */ /* structure with the default values to put in */ /* a Print Style dialogue, if they have not */ /* already been filled in. */ /* */ /* If the dialogue is open, the contents are */ /* updated. */ /* */ /* Returns: 1 if the structure was filled in, */ /* else 0. */ /*************************************************/ int printstyle_set_defaults(void) { if (!defaults_set) { /* Read the defaults from the Choices file */ if (!strcmp(lookup_choice("PrintBack:tables", 0, 0),"none")) contents.background_show_type = Background_Show_Type_None; else if (!strcmp(lookup_choice("PrintBack:tables", 0, 0),"all")) contents.background_show_type = Background_Show_Type_All; else contents.background_show_type = Background_Show_Type_Tables; if (!strcmp(lookup_choice("PrintBlack:bg", 0, 0), "always")) contents.always_use_black = 1, contents.black_no_background = 0; else if (!strcmp(lookup_choice("PrintBlack:bg", 0, 0), "never")) contents.always_use_black = 0, contents.black_no_background = 0; else contents.always_use_black = 0, contents.black_no_background = 1; defaults_set = 1; if (window_id) printstyle_set_contents(window_id, &contents); return 1; } return 0; } /*************************************************/ /* printstyle_to_be_shown() */ /* */ /* Called when the EPSToBeShown event is */ /* generated, typically when the Print Style */ /* dialogue is about to be shown. Registers */ /* event handlers for the dialogue, reads and */ /* sets options in it, etc. */ /* */ /* Parameters are as standard for a Toolbox */ /* event hander, though only the self_id and */ /* ancestor_id fields of the ID block are of */ /* interest. */ /*************************************************/ int printstyle_to_be_shown(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * ancestor = NULL; /* If the stored dialogue ID is non-zero on entry, the dialogue */ /* was reopened without closing - so get rid of the various */ /* event handlers before we reregister them. */ if (window_id) printstyle_close(0, 0); /* Right, record the ID as given in the ID block */ window_id = idb->self_id; /* Sigh. Blimmin' Toolbox. The Setup button in the Print */ /* dialogue, when used to open Print Style, does not */ /* transmit the ancestor ID information - aargh! */ /* */ /* This appears to be because the underlying window ID */ /* is given as this object's parent, rather than the */ /* print dialogue, and it doesn't have an ancestor (bug, */ /* I'd say). Maybe because it's an alternative window, */ /* rather than a standard print dialogue? In any case, */ /* we must assume that the setup window did come from */ /* the print dialogue (and not, say, the choices) if */ /* there's no ancestor window, and ask the print */ /* routines what window it was for. */ ancestor_id = idb->ancestor_id; if (ancestor_id) { ChkError(toolbox_get_ancestor(0, ancestor_id, &ancestor_id, NULL)); } else { print_return_dialogue_info(NULL, NULL, &ancestor_id, &ancestor); } /* Attach event handlers - OK and Cancel functions */ ChkError(event_register_toolbox_handler(idb->self_id, EPSOK, printstyle_ok, NULL)); ChkError(event_register_toolbox_handler(idb->self_id, EPSCancel, printstyle_cancel, NULL)); /* If defaults have never been set before, set them now */ printstyle_set_defaults(); /* Set up the basic display options to match the ancestor browser, */ /* if there is one. Do this before registering handlers for the */ /* basic display options. */ if (ancestor) { contents.underline_links = ancestor->underline_links; contents.use_source_cols = ancestor->use_source_cols; contents.show_foreground = ancestor->show_foreground; contents.show_background = ancestor->show_background; ChkError(printstyle_set_contents(idb->self_id, &contents)); } /* Changing basic display type options (so that the browser window */ /* can be updated to reflect the new settings) */ ChkError(event_register_toolbox_handler(idb->self_id, EPSOG1, printstyle_option_group_one, NULL)); /* Finished */ return 1; } /*************************************************/ /* printstyle_ok() */ /* */ /* Handles clicks on the 'OK' (or 'Use', etc.) */ /* button in the Print Style dialogue. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler (though none are actually */ /* used). */ /*************************************************/ int printstyle_ok(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { if (!window_id) return 0; /* As with the Print dialogue, because this routine takes no */ /* direct action, other functions are called independently */ /* and must act on the 'contents' printstyle_contents struct */ /* - we can't use a local one here to allow Adjust-clicks. */ ChkError(printstyle_read_contents(window_id, &contents)); ChkError(printstyle_close(0, 0)); /* No other actual direct action to take; that's done by the Print dialogue */ return 1; } /*************************************************/ /* printstyle_cancel() */ /* */ /* Handles clicks on the 'Cancel' button in the */ /* Print Style dialogue. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int printstyle_cancel(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { WimpGetPointerInfoBlock info; /* Restore the old contents */ ChkError(printstyle_set_contents(window_id, &contents)); /* If Select was pressed, the dialogue should close. */ /* (No button => Escape was pressed). */ ChkError(wimp_get_pointer_info(&info)); if ((info.button_state & Wimp_MouseButtonSelect) || !info.button_state) { ChkError(printstyle_close(0, 0)); } return 1; } /*************************************************/ /* printstyle_close() */ /* */ /* If the Print Style dialogue is opened, this */ /* will close it, deregistering any associated */ /* event handlers. */ /* */ /* Parameters: An object ID, or 0. If not zero, */ /* the ID must match the ancestor */ /* recorded when the dialogue was */ /* opened or no action is taken; */ /* */ /* 0 to close the dialogue, 1 to do */ /* everything except that. */ /*************************************************/ _kernel_oserror * printstyle_close(ObjectId ancestor, int do_not_close) { _kernel_oserror * e = NULL; if (ancestor && ancestor != ancestor_id) return NULL; if (window_id) { /* Deregister associated event handlers */ e = event_deregister_toolbox_handlers_for_object(window_id); if (e) goto printstyle_close_exit; /* Restore the old contents */ e = printstyle_set_contents(window_id, &contents); if (e) goto printstyle_close_exit; /* Close the dialogue */ if (!do_not_close) { /* Restore input focus to the Print dialogue, */ /* if the Print Style dialogue still has it. */ utils_restore_caret(window_id); /* Now hide the Print Style dialogue */ e = toolbox_hide_object(0, window_id); } } printstyle_close_exit: window_id = ancestor_id = 0; return e; } /*************************************************/ /* printstyle_option_group_one() */ /* */ /* Handles clicks on the group of four option */ /* buttons controlling basic page display. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler (though none are used!). */ /*************************************************/ static int printstyle_option_group_one(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; int ul, dc, sf, sb; /* What browser is the Print dialogue for, if any? */ print_return_dialogue_info(NULL, NULL, NULL, &b); if (b) { /* Read the option states */ ChkError(optionbutton_get_state(0, window_id, PSUnderlineLinks, &ul)); ChkError(optionbutton_get_state(0, window_id, PSUseDocumentColours, &dc)); ChkError(optionbutton_get_state(0, window_id, PSShowForegroundImages, &sf)); ChkError(optionbutton_get_state(0, window_id, PSShowBackgroundImages, &sb)); /* Update the browser to reflect the changes */ ChkError(browser_set_look(b, window_id, ul, dc, sf, sb)); } return 1; } /*************************************************/ /* printstyle_set_look() */ /* */ /* If the Print Style dialogue is open for the */ /* given browser, update option group one with */ /* the values specified. */ /* */ /* If the object changing the look is not the */ /* Print Style window itself, the changes are */ /* stored inside the local printstyle_contents */ /* struct; Cancel will thus not restore them. */ /* This is because it is assumed that if another */ /* object sets the look (e.g. via. the */ /* browser_set_look function), this is meant to */ /* be a change controlled by that object, and it */ /* shouldn't be cancelled if the Print or Print */ /* Style dialogues go. */ /* */ /* Parameters: Object ID of the object that is */ /* changing the look of the browser, */ /* e.g. a menu or even the Print */ /* Style dialogue itself, or 0 to */ /* have the same effect as the Print */ /* Style dialogue object ID (see */ /* comments above); */ /* */ /* Object ID of the browser that the */ /* Print Style dialogue should be */ /* open for; */ /* */ /* 1 to underline links, 0 not to, */ /* -1 to not change this state; */ /* */ /* 1 to use document colours, 0 to */ /* use defaults, -1 to not change */ /* this state; */ /* */ /* 1 to show images, 0 not to (any */ /* pending image fetches are started */ /* up again if 1 is given), or -1 to */ /* not change this state; */ /* */ /* 1 to display plain backgrounds, 0 */ /* to allow background images (and */ /* here too, any pending image */ /* fetches for background images are */ /* restarted if 0 is given), or -1 */ /* to not change this state. */ /*************************************************/ _kernel_oserror * printstyle_set_look(ObjectId source, ObjectId browser, int underline_links, int use_source_cols, int show_foreground, int show_background) { int state; if (ancestor_id == browser) { /* Not much to say here - just go through each option in turn */ if (underline_links >= 0) { /* Get the option state */ RetError(optionbutton_get_state(0, window_id, PSUnderlineLinks, &state)); /* If the requested state is different, set the new state */ if (state != underline_links) RetError(optionbutton_set_state(0, window_id, PSUnderlineLinks, underline_links)); /* If we've been given a source ID and it isn't the Print Style */ /* dialogue itself, set the new value so Cancel won't destroy it. */ if (source && source != window_id) contents.underline_links = underline_links; } if (use_source_cols >= 0) { RetError(optionbutton_get_state(0, window_id, PSUseDocumentColours, &state)); if (state != use_source_cols) RetError(optionbutton_set_state(0, window_id, PSUseDocumentColours, use_source_cols)); if (source && source != window_id) contents.use_source_cols = use_source_cols; } if (show_foreground >= 0) { RetError(optionbutton_get_state(0, window_id, PSShowForegroundImages, &state)); if (state != show_foreground) RetError(optionbutton_set_state(0, window_id, PSShowForegroundImages, show_foreground)); if (source && source != window_id) contents.show_foreground = show_foreground; } if (show_background >= 0) { RetError(optionbutton_get_state(0, window_id, PSShowBackgroundImages, &state)); if (state == show_background) RetError(optionbutton_set_state(0, window_id, PSShowBackgroundImages, show_background)); if (source && source != window_id) contents.show_background = show_background; } } return NULL; } /*************************************************/ /* printstyle_show_none() */ /* */ /* Ask if no backgrounds should be plotted. */ /* */ /* Returns: 1 if the Print Style dialogue */ /* specified no backgrounds, else */ /* 0. */ /*************************************************/ int printstyle_show_none(void) { return (contents.background_show_type == Background_Show_Type_None); } /*************************************************/ /* printstyle_show_in_tables_only() */ /* */ /* Ask if backgrounds should be plotted in */ /* tables only. */ /* */ /* Returns: 1 if the Print Style dialogue */ /* specified backgrounds in tables */ /* only, else 0. */ /*************************************************/ int printstyle_show_in_tables_only(void) { return (contents.background_show_type == Background_Show_Type_Tables); } /*************************************************/ /* printstyle_show_all() */ /* */ /* Ask if all backgrounds should be plotted. */ /* */ /* Returns: 1 if the Print Style dialogue */ /* specified all backgrounds, else */ /* 0. */ /*************************************************/ int printstyle_show_all(void) { return (contents.background_show_type == Background_Show_Type_All); } /*************************************************/ /* printstyle_black_no_background() */ /* */ /* Ask if all body text should be plotted in */ /* black. */ /* */ /* Returns: 1 if the Print Style dialogue */ /* specified black body text else 0. */ /*************************************************/ int printstyle_black_no_background(void) { return contents.black_no_background; return 0; } /*************************************************/ /* printstyle_always_use_black() */ /* */ /* Ask if all table text should be plotted in */ /* black. */ /* */ /* Returns: 1 if the Print Style dialogue */ /* specified black table text, else */ /* 0. */ /*************************************************/ int printstyle_always_use_black(void) { return contents.always_use_black; return 0; } /*************************************************/ /* printstyle_return_dialogue_info() */ /* */ /* Returns information on the Print Style */ /* dialogue, and its ancestor. */ /* */ /* Parameters: Pointer to an ObjectId, in which */ /* the ID of the dialogue is placed; */ /* */ /* Pointer to an ObjectId, in which */ /* the ID of the ancestor window is */ /* placed. */ /* */ /* Returns: See parameters list, and note */ /* that the returned values will be */ /* 0, and 0 if the Print Style */ /* dialogue is closed. */ /* */ /* Assumes: Either pointer may be NULL. */ /*************************************************/ void printstyle_return_dialogue_info(ObjectId * window, ObjectId * ancestor) { if (window) *window = window_id; if (ancestor) *ancestor = ancestor_id; }