/* 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 : SaveObject.c */ /* */ /* Purpose: Handle the Save Object dialogue */ /* (actual object saving is done in */ /* Save.c). */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 03-Sep-97: Created. */ /* */ /* 05-Sep-97: Split so bulk became the */ /* SaveFile source, and the */ /* small fetch saving stayed */ /* in here. */ /***************************************************/ #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 "gadgets.h" #include "svcprint.h" #include "Global.h" #include "Utils.h" #include "Browser.h" #include "Fetch.h" /* (For ISLINK macro) */ #include "Protocols.h" #include "Save.h" #include "SaveFile.h" #include "Windows.h" #include "SaveObject.h" /* Static function prototypes */ static int saveobject_drag_ended (int eventcode, ToolboxEvent * event, IdBlock * idb, browser_data * handle); static int saveobject_ok (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); static int saveobject_cancel (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle); /*************************************************/ /* saveobject_open_for() */ /* */ /* Creates and opens a Save Object dialogue for */ /* a given browser, opening near the pointer. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* which is the ancestor of the */ /* dialogue. */ /*************************************************/ _kernel_oserror * saveobject_open_for(browser_data * b) { ObjectId id; /* Create and show the object */ RetError(toolbox_create_object(0, "SaveObject", &id)); /* Remember the ID */ b->save_dbox = id; /* Show it - everything else is done when the ToBeShown */ /* event comes in. */ RetError(toolbox_show_object(0, id, Toolbox_ShowObject_Centre, NULL, b->self_id, -1)); return NULL; } /*************************************************/ /* saveobject_to_be_shown() */ /* */ /* Fills in the Save Object dialogue prior to */ /* being shown. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ int saveobject_to_be_shown(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { char text[Limits_OS_Pathname]; browser_data * b; /* Process the writable icon text */ ChkError(windows_process_component_text(idb->self_id, SaveObjectWrit, text, sizeof(text), 0, 1)); /* Where did we come from? */ ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); #ifndef TRACE if (!is_known_browser(b)) return 0; #else if (!is_known_browser(b)) { erb.errnum = 0; sprintf(erb.errmess, "Save dialogue origin of object is suspect; given browser %p is unknown, in saveobject_to_be_shown", b); show_error_ret(&erb); return 0; } #endif ChkError(savefile_set_leafname_from_url(idb->self_id, SaveObjectWrit, browser_fetch_url(b))); /* Set the draggable sprite */ ChkError(savefile_set_filetype(idb->self_id, SaveObjectDrag, b->save_type, 1)); /* Install required event handlers */ ChkError(event_register_toolbox_handler(idb->self_id, Draggable_DragEnded, (ToolboxEventHandler *) saveobject_drag_ended, b)); ChkError(event_register_toolbox_handler(idb->self_id, ESaveObjectOK, saveobject_ok, b)); ChkError(event_register_toolbox_handler(idb->self_id, ESaveObjectCancel, saveobject_cancel, b)); return 1; } /*************************************************/ /* saveobject_drag_ended() */ /* */ /* Handle Draggable_DragEnded events from the */ /* Save Object dialogue draggable sprite gadget. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int saveobject_drag_ended(int eventcode, ToolboxEvent * event, IdBlock * idb, browser_data * handle) { DraggableDragEndedEvent * drag = (DraggableDragEndedEvent *) event; WimpGetPointerInfoBlock info; int window_handle; char path[Limits_OS_Pathname]; char * leaf; /* If the user dragged back to the save dialogue, do nothing */ ChkError(window_get_wimp_handle(0, idb->self_id, &window_handle)); if (window_handle == drag->window_handle) return 1; /* Get the pathname from the Save Object dialogue. */ ChkError(writablefield_get_value(0, idb->self_id, SaveObjectWrit, path, sizeof(path), NULL)); path[sizeof(path) - 1] = 0; /* Point to the leafname component */ leaf = strrchr(path, '.'); if (!leaf) leaf = path; else leaf ++; /* Send out the DataSave message */ info.x = drag->x; info.y = drag->y; info.window_handle = drag->window_handle; info.icon_handle = drag->icon_handle; ChkError(protocols_atats_send_data_save(handle, NULL, leaf, save_object_size(handle), handle->save_type, protocols_saving_object, &info)); return 1; } /*************************************************/ /* saveobject_ok() */ /* */ /* Handles clicks on the 'OK' button in the */ /* Save Object dialogue. */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int saveobject_ok(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { char path[Limits_OS_Pathname]; char * leaf; browser_data * b; /* Get the pathname from the Save Object dialogue. */ ChkError(writablefield_get_value(0, idb->self_id, SaveObjectWrit, path, sizeof(path), NULL)); path[sizeof(path) - 1] = 0; /* Is this fully specified? */ leaf = strrchr(path, '.'); if (!leaf) { StrNCpy0(erb.errmess, lookup_token("GivePath:To save, drag the file icon to a directory viewer", 0, 0)); erb.errnum = Utils_Error_Custom_Message; ChkError(&erb); } /* Where did we come from? */ ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); if (!is_known_browser(b)) return 0; /* First, hide the Save Object dialogue */ ChkError(saveobject_close(b)); /* Set the paths etc. and allow the fetch to continue */ ChkError(save_save_object(path, b)); return 1; } /*************************************************/ /* saveobject_cancel() */ /* */ /* Handles clicks on the 'Cancel' button in the */ /* Save Object dialogue */ /* */ /* Parameters are as standard for a Toolbox */ /* event handler. */ /*************************************************/ static int saveobject_cancel(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle) { browser_data * b; /* We don't do anything sophisticated, like */ /* restoring previous options here, as the */ /* dialogue is too simple for it to be */ /* worthwhile. */ ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b)); /* If we were fetching, stop the fetch */ if (b && is_known_browser(b) && b->save_link) fetch_stop(b, 0); /* Close the dialogue */ ChkError(saveobject_close(b)); return 1; } /*************************************************/ /* saveobject_close() */ /* */ /* If the Save Object dialogue is opened, this */ /* will close it, deregistering any associated */ /* event handlers. The dialogue is deleted. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* relevant to the dialogue. */ /*************************************************/ _kernel_oserror * saveobject_close(browser_data * b) { _kernel_oserror * e; int required; if (!b->save_dbox) return NULL; /* Record whatever pathname is in the dialogue for use in */ /* future dialogues. */ RetError(writablefield_get_value(0, b->save_dbox, SaveObjectWrit, NULL, 0, &required)); /* Get rid of any event handlers */ RetError(event_deregister_toolbox_handlers_for_object(b->save_dbox)); /* Delete the dialogue */ e = toolbox_delete_object(0, b->save_dbox); b->save_dbox = 0; return e; }