/* Copyright 1998 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 : SetPBoxes.c */ /* */ /* Purpose: Functions relating to the Set Post_In */ /* / Post_Out dialogue box. */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 19-Mar-98: 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 "svcprint.h" #include "Global.h" #include "Utils.h" #include "Multiuser.h" #include "Save.h" #include "SetPBoxes.h" /* This doesn't do much unless in a multiuser build... */ #ifndef SINGLE_USER /* Local statics */ static ObjectId dbox = NULL_ObjectId; /* Static function prototypes */ static int setpboxes_ok (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int setpboxes_cancel (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); /*************************************************/ /* setpboxes_check_boxes() */ /* */ /* Find out whether !Post_In and !Post_Out, set */ /* in choices.post_in and choices.post_out, are */ /* at least readable as directories or image */ /* files. */ /* */ /* Parameters: Pointer to an int, in which 1 is */ /* written if Post_In is readable as */ /* a directory or image file, else 0 */ /* is written; */ /* */ /* Similarly, pointer to an int for */ /* Post_Out. */ /* */ /* Assumes: Either int pointer may be NULL. */ /*************************************************/ void setpboxes_check_boxes(int * in, int * out) { int attr; int in_ok = 0; int out_ok = 0; /* Which can't we find - Post_In, Post_Out or both? */ _swix(OS_File, _INR(0,1) | _OUT(0), 17, /* Read catalogue info for named object */ choices.post_in, &attr); if (attr == 2 || attr == 3) in_ok = 1; /* 2 = dir, 3 = image file (so could be dir) */ _swix(OS_File, _INR(0,1) | _OUT(0), 17, /* Read catalogue info for named object */ choices.post_out, &attr); if (attr == 2 || attr == 3) out_ok = 1; /* 2 = dir, 3 = image file (so could be dir) */ /* Return the values */ if (in) *in = in_ok; if (out) *out = out_ok; return; } /*************************************************/ /* setpboxes_show_dialogue() */ /* */ /* Create, fill in and show the SetPBoxes */ /* dialogue box. */ /*************************************************/ _kernel_oserror * setpboxes_show_dialogue(void) { char help_panel[Limits_Help]; int in_ok = 0; int out_ok = 0; setpboxes_check_boxes(&in_ok, &out_ok); /* Show the 'question mark' icon bar icon */ show_error_ret(multiuser_set_iconbar_variant("q")); /* Create the dialogue box */ RetError(toolbox_create_object(0, "SetPBoxes", &dbox)); /* Fill in the main writable. First compile the text. */ StrNCpy0(help_panel, lookup_token("SPB1:The browser cannot find \"", 0, 0)); /* We either have only Post_In, only Post_Out or neither. If */ /* we have both, assume someone called by accident or in a */ /* panic, so treat as if none could be found. */ if (in_ok && !out_ok) { /* No Post_Out */ if ( strlen(help_panel) + sizeof("!Post_Out") < sizeof(help_panel) ) strcat(help_panel, "!Post_Out"); } else if (!in_ok && out_ok) { /* No Post_In */ if ( strlen(help_panel) + sizeof("!Post_In") < sizeof(help_panel) ) strcat(help_panel, "!Post_In"); } else { /* Neither or both (treat latter as neither, see above) */ if ( strlen(help_panel) + sizeof("!Post_In") < sizeof(help_panel) ) strcat(help_panel, "!Post_In"); if ( strlen(help_panel) + strlen(lookup_token("SPB2:\" or \"",0,0)) + 1 < sizeof(help_panel) ) strcat(help_panel, tokens); if ( strlen(help_panel) + sizeof("!Post_Out") < sizeof(help_panel) ) strcat(help_panel, "!Post_Out"); } if ( strlen(help_panel) + strlen(lookup_token("SPB3:\". To set the locations of either, drag them to the writable icons below or type in their filenames directly. Then click on 'Set'.", 0, 0)) + 1 < sizeof(help_panel) ) strcat(help_panel, tokens); /* Now put it into the icon */ button_set_value(0, dbox, SetPBoxes_Prompt, help_panel); /* Fill in the writables. Errors on setting are ignored, but */ /* errors on reading are not, so these gadgets must be present */ /* (write errors are ignored in case the path happens to be */ /* too long for the buffer, say, which isn't necessarily fatal */ /* if the path is going to be reset anyway). */ writablefield_set_value(0, dbox, SetPBoxes_InWrit, choices.post_in); writablefield_set_value(0, dbox, SetPBoxes_OutWrit, choices.post_out); /* Event handlers */ RetError(event_register_toolbox_handler(dbox, ESetPBoxes_OK, setpboxes_ok, NULL)); RetError(event_register_toolbox_handler(dbox, ESetPBoxes_Cancel, setpboxes_cancel, NULL)); /* Open the dialogue */ return toolbox_show_object(0, dbox, Toolbox_ShowObject_Centre, NULL, NULL_ObjectId, NULL_ComponentId); } /*************************************************/ /* setpboxes_check_message() */ /* */ /* Check to see if a Wimp_MDataLoad is for the */ /* writables in the Set Post_In / Post_Out */ /* dialogue box or not. If so, deal with it. */ /* */ /* Parameters: Pointer to a WimpMessage block */ /* containing a Wimp_MDataLoad. */ /* */ /* Returns: 1 if the message was of interest, */ /* else 0. */ /*************************************************/ int setpboxes_check_message(WimpMessage * m) { int window; int icon_in [2]; int icon_out [2]; const char * name = m->data.data_load.leaf_name; if (dbox == NULL_ObjectId) return 0; /* Check the window handle */ if ( window_get_wimp_handle(0, dbox, &window) ) return 0; if (window != m->data.data_load.destination_window) return 0; /* We swallow the message either way now, but still need to */ /* check which icon it was dropped over. */ if ( gadget_get_icon_list(0, dbox, SetPBoxes_InWrit, icon_in, sizeof(icon_in), NULL) ) return 1; if ( gadget_get_icon_list(0, dbox, SetPBoxes_OutWrit, icon_out, sizeof(icon_out), NULL) ) return 1; /* Deal with a drop on the Post_In writable */ if (icon_in[0] == m->data.data_load.destination_icon) { const char * d = strrchr(name, '.'); const char * f = strstr(name, ".!Post_In"); if (d == f) { show_error_ret(writablefield_set_value(0, dbox, SetPBoxes_InWrit, (char *) name)); } } /* Deal with a drop on the Post_Out writable */ else if (icon_out[0] == m->data.data_load.destination_icon) { const char * d = strrchr(name, '.'); const char * f = strstr(name, ".!Post_Out"); if (d == f) { show_error_ret(writablefield_set_value(0, dbox, SetPBoxes_OutWrit, (char *) name)); } } /* Exit, saying we dealt with the message */ return 1; } /*************************************************/ /* setpboxes_ok() */ /* */ /* Handle ESetPBoxes_OK events, usually from a */ /* click on the 'OK' / 'Set' button in the */ /* Set Post_In / Post_Out dialogue box. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int setpboxes_ok(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { char path[Limits_Multi_Pathname]; int in_ok = 0; int out_ok = 0; /* Read Post_In */ *path = 0; show_error_ret(writablefield_get_value(0, idb->self_id, SetPBoxes_InWrit, path, sizeof(path), NULL)); /* Allocate memory for this in choices.post_in */ free(choices.post_in); choices.post_in = malloc(strlen(path) + 1); if (choices.post_in) strcpy(choices.post_in, path); /* Read Post_Out */ *path = 0; show_error_ret(writablefield_get_value(0, idb->self_id, SetPBoxes_OutWrit, path, sizeof(path), NULL)); /* Allocate memory for this in choices.post_in */ free(choices.post_out); choices.post_out = malloc(strlen(path) + 1); if (choices.post_out) strcpy(choices.post_out, path); /* If either allocation failed, complain and shut down */ if ( !choices.post_in || !choices.post_out ) { show_error(make_no_memory_error(33)); /* Just in case someone changes the behaviour above to not exit, */ /* we should return cleanly here */ return 1; } /* If we have an invalid post_in or post_out, complain and */ /* leave the dialogue box up. */ if ( *choices.post_in && *choices.post_out ) setpboxes_check_boxes(&in_ok, &out_ok); if (!in_ok || !out_ok) { erb.errnum = Utils_Error_Custom_Message; StrNCpy0(erb.errmess, lookup_token("NoPBoxSet:You must set a valid location for both !Post_In and !Post_Out.", 0, 0)); show_error_ret(&erb); return 1; } /* Post_In / Post_Out OK, so get rid of the dialogue box */ event_deregister_toolbox_handlers_for_object(idb->self_id); toolbox_delete_object(0, idb->self_id); /* Save the settings */ show_error_ret(save_save_choices(NULL)); /* Show the log in prompt */ show_error(multiuser_login()); return 1; } /*************************************************/ /* setpboxes_cancel() */ /* */ /* Handle ESetPBoxes_Cancel events, usually from */ /* a click on the 'Cancel' / 'Exit' button in */ /* the Set Post_In / Post_Out dialogue box. */ /* */ /* NB This will quit the browser through calling */ /* exit(EXIT_SUCCESS)! */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int setpboxes_cancel(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { /* Tidy up, in case someone later wants this code to keep */ /* the browser alive rather than shutting it down. */ event_deregister_toolbox_handlers_for_object(idb->self_id); toolbox_delete_object(0, idb->self_id); /* Quit */ exit(EXIT_SUCCESS); /* Keep compiler happy */ return 1; } #endif