home *** CD-ROM | disk | FTP | other *** search
- /* File: _SaveAs.c
- * Purpose: Supplies functionality for a PopUp
- * Author: © Copyright 1993 Jason Williams
- * All rights reserved
- */
-
- #include "DeskLib:WimpSWIs.h"
-
- #include "DeskLib:Error.h"
- #include "DeskLib:DragASpr.h"
- #include "DeskLib:Icon.h"
- #include "DeskLib:Kbd.h"
- #include "DeskLib:KeyCodes.h"
- #include "DeskLib:StringCR.h"
- #include "DeskLib:SWI.h"
- #include "DeskLib:Template.h"
-
- #include "Server.h"
-
- #include <string.h>
-
-
- typedef struct
- {
- char iconname[12];
- char filename[196];
- } saveas_data;
-
- #define SAVEFLAG_OKCLICK 0x01
- #define SAVEFLAG_SHIFT 0x02
- typedef struct
- {
- int flagword;
- int reserved;
- char filename[212];
- } saveas_return;
-
-
- /* First of all, we define a handler_info structure for our PopUp handler
- * which describes it to the manager. This is referenced externally
- * by the server to find the procedure to call with events for any PopUp
- * of this type, etc.
- * (We also prototype the handler function so we can reference it here)
- */
-
- static int Handler_SaveAs(int, ctrl_block *, void *, event_pollblock *);
-
- handler_info HandlerInfo_SaveAs =
- {
- "SaveAs", /* PopUp type/name string */
- 0x00000001, /* Flag word */
- Handler_SaveAs, /* Handler procedure */
- 0 /* Instantiation workspace size */
- };
-
-
- /* Used to remember if SHIFT was held down when you started the save drag.
- * NOTE that only one drag can ever be in effect, so it is safe to use
- * a static variable to hold this information in.
- */
- static BOOL shiftdown = FALSE;
-
- static void ReturnState(event_pollblock *event,
- window_handle window, BOOL okclicked)
- /* Handles click of OK or press of return key in SaveAs window */
- {
- saveas_return *state = (saveas_return *) event;
- char temp[260];
- int i = 0;
-
- state->flagword = okclicked; /* Return OK-Click/File-Drag state */
- if (!okclicked && shiftdown)
- state->flagword |= SAVEFLAG_SHIFT; /* Shift state only returned if drag */
-
- Icon_GetText(window, 2, temp);
-
- /* Find the end of the string, and convert spaces into hard-spaces */
- temp[259] = 0;
- while (temp[i])
- {
- if (temp[i] == ' ') temp[i] = '\xA0';
- i++;
- }
-
- while (i > 0 && temp[i] != '.') i--; /* Try to find leafname */
- if (temp[i] == '.') i++; /* Advance past '.' */
-
- if (okclicked)
- {
- if (i <= 0) /* No '.' in filename, so assume it's invalid pathname */
- {
- Wimp_CreateMenu((menu_block *) -1, 0, 0); /* Kill our menu */
- ReportMessage(reportflag_OKONLY, "OK", "",
- "To save, drag the file icon to a directory display window");
- i = -9;
- }
- else
- {
- temp[211] = 0;
- strcpy(state->filename, temp); /* Return full pathname (if any) */
- }
- }
- else
- strcpy(state->filename, &temp[i]); /* return leafname only (if any) */
-
- if (i > -9) /* If no error, then... */
- SendState(state, sizeof(saveas_return)); /* Return data to user */
-
- Wimp_CreateMenu((menu_block *) -1, 0, 0); /* Kill menu and window */
- Wimp_DeleteWindow(window);
- KillMe(); /* Inform server that we have closed ourselves */
- }
-
-
- #define SWI_Wimp_SpriteOp (0x000600c0+41)
-
-
- /* The Handler_ function referenced in the above info struct will handle all
- * calls from the server during normal operation...
- */
-
- static BOOL Handler_SaveAs(int reasoncode, ctrl_block *ctrl,
- void *privateworkspace, event_pollblock *event)
- {
- switch(reasoncode)
- {
- case REASON_OPEN:
- {
- window_handle windowhandle;
- window_block *window;
- saveas_data *info;
-
- /* Find the template. NOTE that if you provide a STATIC popup, you
- * MUST support multiple instantiations, so MUST use Template_Clone()
- * Also note that if bringing up a MENU LEAF window, we must clone
- * our template data into the RMA so the WIMP does not crash! ;-(
- */
-
- if ((ctrl->appflags & APPFLAGS_ISLEAF) == 0)
- window = Template_Find("SaveAs");
- /* (The close icon is there already) */
- else
- {
- window = Template_RMAFind("SaveAs");
- window->flags.data.closeicon = FALSE;
- /* (Remove the close icon. NOTE that this is a COPY of the window
- * so does not permanently remove the icon)
- */
- }
-
- if (window == NULL) break;
-
- info = (saveas_data *) (((int)event) + POPUP_DATA_OFFSET);
-
- /* Attempt to 'fix' the file icon (icon 3) to work under RISC OS 2 */
- {
- icon_block *i;
-
- i = (icon_block *) (((int) window) + sizeof(window_block));
-
- /* Icon is not indirected, not text, is sprite */
- i[3].flags.value &= ~(icon_TEXT | icon_INDIRECTED);
- i[3].flags.value |= icon_SPRITE;
-
- /* Check if the requested sprite exists - else use file_xxx */
- if (SWI(3,0, SWI_Wimp_SpriteOp, 24, 0, (int)info->iconname))
- strcpy(i[3].data.spritename, "file_xxx");
- else
- strcpycr(i[3].data.spritename, info->iconname);
- }
-
- /* Create the window, and fill in it's icons with the data given
- * to us in the pollblock. (DATA_BASE is defined above)
- */
- Wimp_CreateWindow(window, &windowhandle);
-
- SetIconText(windowhandle, 2, info->filename); /* Set fname text */
-
- ctrl->pollmask.value = ~( (1 << event_CLOSE) |
- (1 << event_CLICK) |
- (1 << event_USERDRAG) |
- (1 << event_KEY) );
- ctrl->basewindow = windowhandle; /* Let server know windowhandle */
- }
- return(TRUE);
-
-
- case REASON_CLOSE: /* Quietly close our window */
- Wimp_DeleteWindow(ctrl->basewindow); /* Kill window */
- return(TRUE);
-
-
- case REASON_EVENT: /* Handle a WIMP Event */
- switch(event->type)
- {
- case event_CLOSE:
- if (event->data.openblock.window == ctrl->basewindow)
- {
- /* *ONLY* if this is our window, we kill the current menu, kill
- * our window, and return TRUE to indicate that we have processed
- * the event (so no other handlers should get it)
- */
- Wimp_CreateMenu((menu_block *) -1, 0, 0);
- Wimp_DeleteWindow(ctrl->basewindow);
- KillMe(); /* Inform server that we have closed ourselves */
- return(TRUE);
- }
- break;
-
- case event_CLICK:
- if (event->data.mouse.window == ctrl->basewindow)
- {
- switch(event->data.mouse.icon)
- {
- case 0: /* 'OK' button clicked */
- ReturnState(event, ctrl->basewindow, TRUE);
- break;
-
- case 3: /* File icon dragged */
- /* Under RISC OS 3, just do this for DRAG events, but under
- * RISC OS 2 I seem to have to do it on normal click events
- * in order to get anything out of it at all!
- */
- if (event->data.mouse.button.data.dragadjust ||
- event->data.mouse.button.data.dragselect ||
- (wimpversion < 300 &&
- (event->data.mouse.button.data.adjust ||
- event->data.mouse.button.data.select) ))
- {
- Icon_StartSolidDrag(ctrl->basewindow, 3);
- shiftdown = Kbd_KeyDown(inkey_SHIFT);
- ImDragging(); /* Tell server that I own the current drag */
- }
- break;
- }
- return(TRUE);
- }
- break;
-
- case event_KEY:
- if (event->data.key.caret.window == ctrl->basewindow)
- {
- switch(event->data.key.code)
- {
- case keycode_RETURN:
- ReturnState(event, ctrl->basewindow, TRUE);
- return(TRUE);
- }
- }
- break;
-
- case event_USERDRAG:
- /* This can only come to us when we started the drag */
- {
- mouse_block ptr;
-
- Wimp_GetPointerInfo(&ptr);
- if (ptr.window != ctrl->basewindow) /* Ignore drop in own window */
- ReturnState(event, ctrl->basewindow, FALSE);
- }
- break;
- }
- break;
- }
-
- return(FALSE); /* If we didn't handle this call, we MUST return 0 */
- }
-
-