home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / p / popups / Docs / ExampleSrc / c / _SaveAs < prev    next >
Encoding:
Text File  |  1993-05-25  |  8.6 KB  |  269 lines

  1. /*  File:     _SaveAs.c
  2.  *  Purpose:  Supplies functionality for a PopUp
  3.  *  Author:   © Copyright 1993 Jason Williams
  4.  *            All rights reserved
  5.  */
  6.  
  7. #include "DeskLib:WimpSWIs.h"
  8.  
  9. #include "DeskLib:Error.h"
  10. #include "DeskLib:DragASpr.h"
  11. #include "DeskLib:Icon.h"
  12. #include "DeskLib:Kbd.h"
  13. #include "DeskLib:KeyCodes.h"
  14. #include "DeskLib:StringCR.h"
  15. #include "DeskLib:SWI.h"
  16. #include "DeskLib:Template.h"
  17.  
  18. #include "Server.h"
  19.  
  20. #include <string.h>
  21.  
  22.  
  23. typedef struct
  24. {
  25.   char iconname[12];
  26.   char filename[196];
  27. } saveas_data;
  28.  
  29. #define SAVEFLAG_OKCLICK 0x01
  30. #define SAVEFLAG_SHIFT   0x02
  31. typedef struct
  32. {
  33.   int  flagword;
  34.   int  reserved;
  35.   char filename[212];
  36. } saveas_return;
  37.  
  38.  
  39. /*  First of all, we define a handler_info structure for our PopUp handler
  40.  *  which describes it to the manager. This is referenced externally
  41.  *  by the server to find the procedure to call with events for any PopUp
  42.  *  of this type, etc.
  43.  *  (We also prototype the handler function so we can reference it here)
  44.  */
  45.  
  46. static int Handler_SaveAs(int, ctrl_block *, void *, event_pollblock *);
  47.  
  48. handler_info HandlerInfo_SaveAs =
  49. {
  50.   "SaveAs",                                  /* PopUp type/name string       */
  51.   0x00000001,                                /* Flag word                    */
  52.   Handler_SaveAs,                            /* Handler procedure            */
  53.   0                                          /* Instantiation workspace size */
  54. };
  55.  
  56.  
  57.   /*  Used to remember if SHIFT was held down when you started the save drag.
  58.    *  NOTE that only one drag can ever be in effect, so it is safe to use
  59.    *  a static variable to hold this information in.
  60.    */
  61. static BOOL shiftdown = FALSE;
  62.  
  63. static void ReturnState(event_pollblock *event,
  64.                         window_handle window, BOOL okclicked)
  65. /* Handles click of OK or press of return key in SaveAs window */
  66. {
  67.   saveas_return *state = (saveas_return *) event;
  68.   char temp[260];
  69.   int i = 0;
  70.  
  71.   state->flagword = okclicked;          /* Return OK-Click/File-Drag state   */
  72.   if (!okclicked && shiftdown)
  73.     state->flagword |= SAVEFLAG_SHIFT;  /* Shift state only returned if drag */
  74.  
  75.   Icon_GetText(window, 2, temp);
  76.  
  77.   /* Find the end of the string, and convert spaces into hard-spaces */
  78.   temp[259] = 0;
  79.   while (temp[i])
  80.   {
  81.     if (temp[i] == ' ') temp[i] = '\xA0';      
  82.     i++;
  83.   }
  84.  
  85.   while (i > 0 && temp[i] != '.') i--;               /* Try to find leafname */
  86.   if (temp[i] == '.') i++;                           /* Advance past '.'     */
  87.  
  88.   if (okclicked)
  89.   {
  90.     if (i <= 0)       /* No '.' in filename, so assume it's invalid pathname */
  91.     {
  92.       Wimp_CreateMenu((menu_block *) -1, 0, 0);             /* Kill our menu */
  93.       ReportMessage(reportflag_OKONLY, "OK", "",
  94.                   "To save, drag the file icon to a directory display window");
  95.       i = -9;
  96.     }
  97.     else
  98.     {
  99.       temp[211] = 0;
  100.       strcpy(state->filename, temp);        /* Return full pathname (if any) */
  101.     }
  102.   }
  103.   else
  104.     strcpy(state->filename, &temp[i]);      /* return leafname only (if any) */
  105.   
  106.   if (i > -9)                                        /* If no error, then... */
  107.     SendState(state, sizeof(saveas_return));         /* Return data to user  */
  108.  
  109.   Wimp_CreateMenu((menu_block *) -1, 0, 0);          /* Kill menu and window */
  110.   Wimp_DeleteWindow(window);
  111.   KillMe();                   /* Inform server that we have closed ourselves */
  112. }
  113.  
  114.  
  115. #define SWI_Wimp_SpriteOp            (0x000600c0+41)
  116.  
  117.  
  118. /*  The Handler_ function referenced in the above info struct will handle all
  119.  *  calls from the server during normal operation...
  120.  */
  121.  
  122. static BOOL Handler_SaveAs(int reasoncode, ctrl_block *ctrl,
  123.                            void *privateworkspace, event_pollblock *event)
  124. {
  125.   switch(reasoncode)
  126.   {
  127.     case REASON_OPEN:
  128.       {
  129.         window_handle windowhandle;
  130.         window_block *window;
  131.         saveas_data *info;
  132.  
  133.         /*  Find the template. NOTE that if you provide a STATIC popup, you
  134.          *  MUST support multiple instantiations, so MUST use Template_Clone()
  135.          *  Also note that if bringing up a MENU LEAF window, we must clone
  136.          *  our template data into the RMA so the WIMP does not crash! ;-(
  137.           */
  138.  
  139.         if ((ctrl->appflags & APPFLAGS_ISLEAF) == 0)
  140.           window = Template_Find("SaveAs");
  141.           /* (The close icon is there already) */
  142.         else
  143.         {
  144.           window = Template_RMAFind("SaveAs");
  145.           window->flags.data.closeicon = FALSE;
  146.           /* (Remove the close icon. NOTE that this is a COPY of the window
  147.            * so does not permanently remove the icon)
  148.            */
  149.         }
  150.  
  151.         if (window == NULL) break;
  152.  
  153.         info = (saveas_data *) (((int)event) + POPUP_DATA_OFFSET);
  154.  
  155.         /* Attempt to 'fix' the file icon (icon 3) to work under RISC OS 2 */
  156.         {
  157.           icon_block *i;
  158.  
  159.           i = (icon_block *) (((int) window) + sizeof(window_block));
  160.  
  161.           /* Icon is not indirected, not text, is sprite */
  162.           i[3].flags.value &= ~(icon_TEXT | icon_INDIRECTED);
  163.           i[3].flags.value |= icon_SPRITE;
  164.  
  165.           /* Check if the requested sprite exists - else use file_xxx */
  166.           if (SWI(3,0, SWI_Wimp_SpriteOp, 24, 0, (int)info->iconname))
  167.             strcpy(i[3].data.spritename, "file_xxx");
  168.           else
  169.             strcpycr(i[3].data.spritename, info->iconname); 
  170.         }
  171.  
  172.         /*  Create the window, and fill in it's icons with the data given
  173.          *  to us in the pollblock. (DATA_BASE is defined above)
  174.          */
  175.         Wimp_CreateWindow(window, &windowhandle);
  176.  
  177.         SetIconText(windowhandle, 2, info->filename);      /* Set fname text */
  178.  
  179.         ctrl->pollmask.value = ~( (1 << event_CLOSE)    |
  180.                                   (1 << event_CLICK)    |
  181.                                   (1 << event_USERDRAG) |
  182.                                   (1 << event_KEY) );
  183.         ctrl->basewindow = windowhandle;     /* Let server know windowhandle */
  184.       }
  185.       return(TRUE);
  186.  
  187.  
  188.     case REASON_CLOSE:                           /* Quietly close our window */
  189.       Wimp_DeleteWindow(ctrl->basewindow);              /* Kill window       */
  190.       return(TRUE);
  191.  
  192.  
  193.     case REASON_EVENT:                                /* Handle a WIMP Event */
  194.       switch(event->type)
  195.       {
  196.         case event_CLOSE:
  197.           if (event->data.openblock.window == ctrl->basewindow)
  198.           {
  199.             /*  *ONLY* if this is our window, we kill the current menu, kill
  200.              *  our window, and return TRUE to indicate that we have processed
  201.              *  the event (so no other handlers should get it)
  202.              */
  203.             Wimp_CreateMenu((menu_block *) -1, 0, 0);
  204.             Wimp_DeleteWindow(ctrl->basewindow);
  205.             KillMe();         /* Inform server that we have closed ourselves */
  206.             return(TRUE);
  207.           }
  208.           break;
  209.  
  210.         case event_CLICK:
  211.           if (event->data.mouse.window == ctrl->basewindow)
  212.           {
  213.             switch(event->data.mouse.icon)
  214.             {
  215.               case 0:  /* 'OK' button clicked */
  216.                 ReturnState(event, ctrl->basewindow, TRUE);
  217.                 break;
  218.  
  219.               case 3:  /* File icon dragged */
  220.                 /* Under RISC OS 3, just do this for DRAG events, but under
  221.                  * RISC OS 2 I seem to have to do it on normal click events
  222.                  * in order to get anything out of it at all!
  223.                  */
  224.                 if (event->data.mouse.button.data.dragadjust ||
  225.                     event->data.mouse.button.data.dragselect ||
  226.                     (wimpversion < 300 &&
  227.                       (event->data.mouse.button.data.adjust  ||
  228.                        event->data.mouse.button.data.select) ))
  229.                 {
  230.                   Icon_StartSolidDrag(ctrl->basewindow, 3);
  231.                   shiftdown = Kbd_KeyDown(inkey_SHIFT);
  232.                   ImDragging();   /* Tell server that I own the current drag */ 
  233.                 }
  234.                 break;
  235.             }
  236.             return(TRUE);
  237.           }
  238.           break;
  239.  
  240.         case event_KEY:
  241.           if (event->data.key.caret.window == ctrl->basewindow)
  242.           {
  243.             switch(event->data.key.code)
  244.             {
  245.               case keycode_RETURN:
  246.                 ReturnState(event, ctrl->basewindow, TRUE);
  247.                 return(TRUE);
  248.             }
  249.           }
  250.           break;
  251.  
  252.         case event_USERDRAG:
  253.           /* This can only come to us when we started the drag */
  254.           {
  255.             mouse_block ptr;
  256.  
  257.             Wimp_GetPointerInfo(&ptr);
  258.             if (ptr.window != ctrl->basewindow) /* Ignore drop in own window */
  259.               ReturnState(event, ctrl->basewindow, FALSE);
  260.           }
  261.           break;
  262.       }
  263.       break;
  264.   }
  265.  
  266.   return(FALSE);          /* If we didn't handle this call, we MUST return 0 */
  267. }
  268.  
  269.