home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / devtools / gik2 / ewyio2eu.d2x / EWYQAEH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-04  |  142.8 KB  |  2,947 lines

  1. /*
  2. GIK/2 1.0.1 EWYQAEH.C 5621-432 (C) COPYRIGHT IBM CORP 1991, 1993.  ALL RIGHTS RESERVED.  LICENSED MATERIALS - PROPERTY OF IBM.
  3. */
  4. /**********************************************************************/
  5. /*                                                                    */
  6. /*                         MODULE PROLOGUE                            */
  7. /*                                                                    */
  8. /* COMPONENT NAME:   PERSONNEL DATABASE EXAMPLE                       */
  9. /*                                                                    */
  10. /* MODULE NAME:      EWYQAEH.C                                        */
  11. /*                                                                    */
  12. /* DESCRIPTIVE NAME: Graphics Interface Kit/2 -                       */
  13. /*                   Personnel Database Example                       */
  14. /*                                                                    */
  15. /* PURPOSE:          Event functions                                  */
  16. /*                                                                    */
  17. /* COPYRIGHT:        (C) 1991, 1993 IBM Corporation                   */
  18. /*                                                                    */
  19. /* DISCLAIMER OF WARRANTIES.  The following [enclosed] code is        */
  20. /* sample code created by IBM Corporation. This sample code is not    */
  21. /* part of any standard or IBM product and is provided to you solely  */
  22. /* for the purpose of assisting you in the development of your        */
  23. /* applications.  The code is provided "AS IS", without               */
  24. /* warranty of any kind.  IBM shall not be liable for any damages     */
  25. /* arising out of your use of the sample code, even if they have been */
  26. /* advised of the possibility of such damages.                        */
  27. /*                                                                    */
  28. /**********************************************************************/
  29.  
  30. /*--------------------------------------------------------------------*/
  31. /* INCLUDE RELATED DEFINES                                            */
  32. /*--------------------------------------------------------------------*/
  33.  
  34. #define  INCL_DOS                      /* OS/2 definitions            */
  35. #define  INCL_PM                       /* PM definitions              */
  36.  
  37. /*--------------------------------------------------------------------*/
  38. /* HEADER FILES                                                       */
  39. /*--------------------------------------------------------------------*/
  40.  
  41. #include <os2.h>                       /* OS/2 header file            */
  42. #include <string.h>                    /* C library header            */
  43. #include <ewyga.h>                     /* GIK/2 header file           */
  44. #include "EWYQADF.H"                   /* Generated header file       */
  45. #include "EWYQA.H"                     /* Example header file         */
  46.  
  47. /*--------------------------------------------------------------------*/
  48. /* CONSTANTS                                                          */
  49. /*--------------------------------------------------------------------*/
  50. /* $$N                                                                */
  51. #define  STR_REMOVE_EMPLOYEES           \
  52. "Employees that are not selected will be removed.\
  53. Do you want to continue?"
  54. #define  STR_PLACE_ADDED_EMPLOYEE       \
  55. "You can only place the new employee on a manager"
  56. #define  STR_PLACE_MOVED_EMPLOYEE       \
  57. "You can only place the employee on a manager"
  58. #define  STR_PLACE_1_MOVED_DEP_MANAGER  \
  59. "You can only place employees that do not report \
  60. to a manager on a manager"
  61. #define  STR_PLACE_N_MOVED_DEP_MANAGER  \
  62. "You can only place an employee that does not \
  63. report to a manager on a manager"
  64.  
  65. /*--------------------------------------------------------------------*/
  66. /* MACROS                                                             */
  67. /*--------------------------------------------------------------------*/
  68.  
  69. #define  MSG_EMPLOYEE_NOT_ATTACHED(str) \
  70.          GsMessageBox(dhnd, str, "", MB_OK|MB_WARNING, NULL)
  71. /* $$F */
  72. /*--------------------------------------------------------------------*/
  73. /* LOCAL FUNCTION PROTOTYPES                                          */
  74. /*--------------------------------------------------------------------*/
  75.  
  76. SHORT GSENTRY EvActionDone(DHND,SHORT,EVS_ACTION_DONE *);
  77.  
  78. SHORT GSENTRY EvClear(DHND,SHORT,VOID *);
  79. SHORT GSENTRY EvClick(DHND,SHORT,EVS_CLICK *);
  80. SHORT GSENTRY EvEndAdd(DHND,SHORT,EVS_END_ADD *);
  81. SHORT GSENTRY EvEndMove(DHND,SHORT,EVS_END_MOVE *);
  82. SHORT GSENTRY EvInit(DHND,SHORT,EVS_INIT *);
  83. SHORT GSENTRY EvMenu(DHND,SHORT,EVS_MENU *);
  84. SHORT GSENTRY EvNew(DHND,SHORT,VOID *);
  85. SHORT GSENTRY EvStartAdd(DHND,SHORT,EVS_START_ADD *);
  86. SHORT GSENTRY EvStartMove(DHND,SHORT,EVS_START_MOVE *);
  87. SHORT GSENTRY EvDragOver(DHND,SHORT,EVS_DRAG_OVER *);
  88. SHORT GSENTRY EvDrop(DHND,SHORT,EVS_DROP *);
  89. SHORT GSENTRY EvEndDrag(DHND,SHORT,EVS_END_DRAG *);
  90. SHORT GSENTRY EvStartDrag(DHND,SHORT,EVS_START_DRAG *);
  91.  
  92. /*--------------------------------------------------------------------*/
  93. /* Auxiliary functions (local).                                       */
  94. /*--------------------------------------------------------------------*/
  95.  
  96. static VOID PerformLayout(DHND);
  97. SHORT AllSubtreeEmployeeAf(DHND);
  98. static VOID PutAllSubtreeSymAf(DHND,SHND,BOOL);
  99. static VOID RemoveEmployee(DHND,SHND);
  100. static VOID RemoveGenManager(DHND);
  101. SHORT ManagerAfOff(DHND,SHND);
  102. static VOID DeleteLink(DHND,SHND);
  103. static VOID RemoveManager(DHND,SHND);
  104. SHORT SetGenManager(DHND);
  105. SHORT EmployeeForGenManager(DHND,SHND);
  106. SHORT AttachMoveEmployeeToManager(DHND,SHND);
  107. SHORT AttachEmployeeToManager(DHND,SHND,SHND);
  108. SHORT AllVisibleEmployeesMoved(DHND);
  109. SHORT NotSelectedDepManager(DHND,SHND);
  110. SHORT VisibleEmployee(DHND);
  111. SHORT DeleteAllNewLinks(DHND);
  112. static VOID ShowMsgAfterMovingEmployees(DHND);
  113. SHORT SymDragged(DHND,DRAGINFO *);
  114. SHORT AllVisibleEmployeesDragged(DHND,DRAGINFO *);
  115. static VOID UpdateEmployeeData(DHND,DRAGINFO *,SHND);
  116. static VOID GetTargetNode(DHND,DRAGINFO *,SHND,SHND *);
  117. SHORT DropEmployeeForGenManager(DHND);
  118. SHORT AttachDrop1EmployeeToManager(DHND,POINTL);
  119. SHORT AttachDropNEmployeeToManager(DHND);
  120. static VOID PutAllLinkToPreManagerAf(DHND);
  121. static VOID PutLinkToPreManagerAf(DHND,SHND);
  122.  
  123. /**********************************************************************/
  124. /* EvActionDone                                                       */
  125. /*                                                                    */
  126. /* Parameters:                                                        */
  127. /*    DHND                     dhnd  (I): Diagram handle.             */
  128. /*    SHORT                    ev_id (I): Identifies the event.       */
  129. /*    EVS_ACTION_DONE          *pEvs (I): Pointer to instance of event*/
  130. /*                                        data type.                  */
  131. /*     SHORT  action_type (I):     Type of action                     */
  132. /*                                 It is one of the following:        */
  133. /*                                   GE_*                             */
  134. /*                                   GI_*                             */
  135. /*                                   GS_ACTION_HANDLER                */
  136. /*     USHORT menu_id (I):         Identifier of the menu item in the */
  137. /*                                 menu bar. It is 0 for Implicit     */
  138. /*                                 Actions and when a symbol is added */
  139. /*                                 from the Symbol Palette.           */
  140. /*     SHORT  action_rc (I):       Return code of the Explicit Action,*/
  141. /*                                 Implicit Action or User Action that*/
  142. /*                                 takes place before the event is    */
  143. /*                                 triggered.                         */
  144. /*                                                                    */
  145. /*                                                                    */
  146. /* Returns:                                                           */
  147. /*   GS_YES       The default processing continues.                   */
  148. /*                                                                    */
  149. /* Description:                                                       */
  150. /*    The function handles the event EV_ACTION_DONE.                  */
  151. /*    - Performs a layout algorithm.                                  */
  152. /**********************************************************************/
  153.  
  154. SHORT GSENTRY EvActionDone(DHND dhnd,SHORT ev_id,EVS_ACTION_DONE *pEvs)
  155. {
  156.   SHORT            action_num;         /* number of pending actions   */
  157.   GSS_ACTION       action[GS_ACTION_num];/* action data               */
  158.   SHORT            cnt;                /* action count                */
  159.   BOOL             drag;               /* indicates whether GI_DRAG is
  160.                                           being processed             */
  161.  
  162.   /*------------------------------------------------------------------*/
  163.   /* Handle the actions.                                              */
  164.   /*------------------------------------------------------------------*/
  165.  
  166.   switch (pEvs->action_type)
  167.   {
  168.     case  GE_ADD_SYM :
  169.     case  GI_MOVE_BP_SYM :
  170.  
  171.       /*--------------------------------------------------------------*/
  172.       /* Perform a layout algorithm.                                  */
  173.       /*--------------------------------------------------------------*/
  174.  
  175.       PerformLayout(dhnd);
  176.       break;
  177.     case  GE_CLEAR :
  178.  
  179.       /*--------------------------------------------------------------*/
  180.       /* If at least one symbol representing an employee in the       */
  181.       /* company is visible, perform a layout algorithm.              */
  182.       /*--------------------------------------------------------------*/
  183.  
  184.       if (VisibleEmployee(dhnd) == GS_YES)
  185.       {
  186.         PerformLayout(dhnd);
  187.       }
  188.       break;
  189.     case  GE_OPEN :
  190.  
  191.       /*--------------------------------------------------------------*/
  192.       /* Determine the general manager.                               */
  193.       /*--------------------------------------------------------------*/
  194.  
  195.       SetGenManager(dhnd);
  196.       break;
  197.     case  GI_DRAG :
  198.  
  199.       /*--------------------------------------------------------------*/
  200.       /* If the drag operation has been stopped, restore the previous */
  201.       /* position of the symbols. Otherwise, perform a layout         */
  202.       /* algorithm.                                                   */
  203.       /*--------------------------------------------------------------*/
  204.  
  205.       if (pEvs->action_rc != GS_OK)
  206.       {
  207.         GsTriggerGenericAction(dhnd, GE_UNDO, NULL);
  208.       }
  209.       else
  210.       {
  211.         PerformLayout(dhnd);
  212.       }
  213.  
  214.       /*--------------------------------------------------------------*/
  215.       /* Determine the general manager.                               */
  216.       /*--------------------------------------------------------------*/
  217.  
  218.       SetGenManager(dhnd);
  219.       break;
  220.     case  GI_DROP :
  221.  
  222.       /*--------------------------------------------------------------*/
  223.       /* If the target window of the direct manipulation operation is */
  224.       /* not the same as its source window, perform a layout          */
  225.       /* algorithm.                                                   */
  226.       /*--------------------------------------------------------------*/
  227.  
  228.       GsGetAction(dhnd, NULL, &action_num);
  229.       GsGetAction(dhnd, action, &action_num);
  230.       for (drag = FALSE, cnt = action_num; (!drag) && (cnt >= 0); cnt--)
  231.       {
  232.         drag = (action[cnt].action_type == GI_DRAG);
  233.       }
  234.       if (!drag)
  235.       {
  236.         PerformLayout(dhnd);
  237.       }
  238.       break;
  239.   }
  240.   return  GS_YES;
  241. }
  242.  
  243. /**********************************************************************/
  244. /* PerformLayout                                                      */
  245. /*                                                                    */
  246. /* Parameters:                                                        */
  247. /*   DHND             dhnd     (I): Diagram handle                    */
  248. /*                                                                    */
  249. /* Returns:                                                           */
  250. /*   VOID                                                             */
  251. /*                                                                    */
  252. /* Description:                                                       */
  253. /*   The function performs a layout algorithm.                        */
  254. /**********************************************************************/
  255.  
  256. static VOID PerformLayout(DHND dhnd)
  257. {
  258.   SHORT            action_num;         /* number of pending actions   */
  259.  
  260.   /*------------------------------------------------------------------*/
  261.   /* If not more than one action is pending, a layout algorithm is    */
  262.   /* performed.                                                       */
  263.   /*------------------------------------------------------------------*/
  264.  
  265.   GsGetAction(dhnd, NULL, &action_num);
  266.   if (action_num <= 1)
  267.   {
  268.     GsTriggerGenericAction(dhnd, GE_LAYOUT, NULL);
  269.   }
  270. }
  271.  
  272. /**********************************************************************/
  273. /* EvClear                                                            */
  274. /*                                                                    */
  275. /* Parameters:                                                        */
  276. /*    DHND                     dhnd  (I): Diagram handle.             */
  277. /*    SHORT                    ev_id (I): Identifies the event.       */
  278. /*    VOID                     *pEvs (I): Pointer to instance of event*/
  279. /*                                        data type.                  */
  280. /*                                                                    */
  281. /* Returns:                                                           */
  282. /*   GS_NO        Any changes made to symbols remain and the action   */
  283. /*                stops.                                              */
  284. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  285. /*                stops.                                              */
  286. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  287. /*                checkpoint are undone and the action stops.         */
  288. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  289. /*                checkpoint are undone and the action stops.         */
  290. /*   GS_YES       The default processing continues.                   */
  291. /*                                                                    */
  292. /* Description:                                                       */
  293. /*    The function handles the event EV_CLEAR.                        */
  294. /*    - Checks whether a subtree with more than one employee is to be */
  295. /*      deleted.                                                      */
  296. /*    - All selected node symbols and their children are marked for   */
  297. /*      deletion.                                                     */
  298. /**********************************************************************/
  299.  
  300. SHORT GSENTRY EvClear(DHND dhnd,SHORT ev_id,VOID *pEvs)
  301. {
  302.   SHND             employee_shnd;      /* handle of employee          */
  303.   USHORT           button;             /* push-button clicked on      */
  304.  
  305.   /*------------------------------------------------------------------*/
  306.   /* If a subtree with symbols that are not selected is to be deleted,*/
  307.   /* a message is displayed to inform the end user.                   */
  308.   /*------------------------------------------------------------------*/
  309.  
  310.   if (AllSubtreeEmployeeAf(dhnd) == GS_NO)
  311.   {
  312.     GsMessageBox(dhnd, STR_REMOVE_EMPLOYEES, "", MB_YESNO|MB_WARNING,
  313.        &button);
  314.     if (button != MBID_YES)
  315.     {
  316.       return  GS_NO;
  317.     }
  318.   }
  319.  
  320.   /*------------------------------------------------------------------*/
  321.   /* Mark symbols for deletion. All selected symbols representing     */
  322.   /* employees have the action flag already set.                      */
  323.   /*------------------------------------------------------------------*/
  324.  
  325.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  326.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  327.   {
  328.     PutAllSubtreeSymAf(dhnd, employee_shnd, FALSE);
  329.     RemoveEmployee(dhnd, employee_shnd);
  330.   }
  331.  
  332.   /*------------------------------------------------------------------*/
  333.   /* If all employees are to be deleted, also the general manager has */
  334.   /* to be removed from the company.                                  */
  335.   /*------------------------------------------------------------------*/
  336.  
  337.   RemoveGenManager(dhnd);
  338.   return  GS_YES;
  339. }
  340.  
  341. /**********************************************************************/
  342. /* AllSubtreeEmployeeAf                                               */
  343. /*                                                                    */
  344. /* Parameters:                                                        */
  345. /*   DHND             dhnd     (I): Diagram handle                    */
  346. /*                                                                    */
  347. /* Returns:                                                           */
  348. /*   GS_NO                                                            */
  349. /*   GS_YES                                                           */
  350. /*                                                                    */
  351. /* Description:                                                       */
  352. /*   The function checks for all symbols representing employees the   */
  353. /*   following:                                                       */
  354. /*   - The symbol has its action flag set.                            */
  355. /*   - The employee is a manager to whom employees are reporting.     */
  356. /*   - All symbols representing employees reporting to the manager    */
  357. /*     have their action flag set.                                    */
  358. /**********************************************************************/
  359.  
  360. SHORT AllSubtreeEmployeeAf(DHND dhnd)
  361. {
  362.   SHND             employee_shnd;      /* handle of employee          */
  363.   EMPLOYEE         employee;           /* employee object data        */
  364.   SHORT            af;                 /* state of the action flag    */
  365.   SHORT            cnt;                /* symbol count                */
  366.  
  367.   /*------------------------------------------------------------------*/
  368.   /* Loop over all symbols having their action flag set.              */
  369.   /*------------------------------------------------------------------*/
  370.  
  371.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  372.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  373.   {
  374.  
  375.     /*----------------------------------------------------------------*/
  376.     /* Retrieve the employee data.                                    */
  377.     /*----------------------------------------------------------------*/
  378.  
  379.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  380.        (employee));
  381.  
  382.     /*----------------------------------------------------------------*/
  383.     /* Loop over all employees reporting to the current employee.     */
  384.     /*----------------------------------------------------------------*/
  385.  
  386.     for (cnt = 0; cnt < employee.employee_num; cnt++)
  387.     {
  388.  
  389.       /*--------------------------------------------------------------*/
  390.       /* See whether the symbol representing an employee has its      */
  391.       /* action flag set.                                             */
  392.       /*--------------------------------------------------------------*/
  393.  
  394.       GsGetSymAf(dhnd, employee.employee_shnd[cnt], &af);
  395.       if (af == GS_OFF)
  396.       {
  397.         GsEndSymCollection(dhnd);
  398.         return  GS_NO;
  399.       }
  400.     }
  401.   }
  402.   return  GS_YES;
  403. }
  404.  
  405. /**********************************************************************/
  406. /* PutAllSubtreeSymAf                                                 */
  407. /*                                                                    */
  408. /* Parameters:                                                        */
  409. /*   DHND             dhnd      (I): Diagram handle                   */
  410. /*   SHND             root_shnd (I): Handle of the root symbol of a   */
  411. /*                                   subtree                          */
  412. /*   BOOL             child     (I): Indicates a recursive call       */
  413. /*                                                                    */
  414. /* Returns:                                                           */
  415. /*   VOID                                                             */
  416. /*                                                                    */
  417. /* Description:                                                       */
  418. /*   The function recursively sets the action flag of all symbols of  */
  419. /*   a subtree.                                                       */
  420. /**********************************************************************/
  421.  
  422. static VOID PutAllSubtreeSymAf(DHND dhnd,SHND root_shnd,BOOL child)
  423. {
  424.   SHND             link_shnd;          /* handle of link symbol       */
  425.   EMPLOYEE         employee;           /* employee object data        */
  426.   SHORT            cnt;                /* symbol count                */
  427.  
  428.   /*------------------------------------------------------------------*/
  429.   /* Set the action flag of the symbol.                               */
  430.   /*------------------------------------------------------------------*/
  431.  
  432.   GsPutSymAf(dhnd, root_shnd, GS_ON);
  433.  
  434.   /*------------------------------------------------------------------*/
  435.   /* Set the action flag of the link between symbol and its parent    */
  436.   /* symbol.                                                          */
  437.   /*------------------------------------------------------------------*/
  438.  
  439.   if (child)
  440.   {
  441.     GsGetFirstAttachedSym(dhnd, GS_TARGET_ATTACHED_LINK, root_shnd,
  442.        &link_shnd, NULL);
  443.     GsPutSymAf(dhnd, link_shnd, GS_ON);
  444.   }
  445.  
  446.   /*------------------------------------------------------------------*/
  447.   /* Retrieve the data of the employee represented by the root symbol.*/
  448.   /*------------------------------------------------------------------*/
  449.  
  450.   GsGetSymObjectData(dhnd, root_shnd, (PVOID)&employee, sizeof(employee)
  451.      );
  452.  
  453.   /*------------------------------------------------------------------*/
  454.   /* Set the action flag of all symbols of all subtrees that have the */
  455.   /* root symbol as parent.                                           */
  456.   /*------------------------------------------------------------------*/
  457.  
  458.   for (cnt = 0; cnt < employee.employee_num; cnt++)
  459.   {
  460.     PutAllSubtreeSymAf(dhnd, employee.employee_shnd[cnt], TRUE);
  461.   }
  462. }
  463.  
  464. /**********************************************************************/
  465. /* RemoveEmployee                                                     */
  466. /*                                                                    */
  467. /* Parameters:                                                        */
  468. /*   DHND             dhnd          (I): Diagram handle               */
  469. /*   SHND             employee_shnd (I): handle of employee           */
  470. /*                                                                    */
  471. /* Returns:                                                           */
  472. /*   VOID                                                             */
  473. /*                                                                    */
  474. /* Description:                                                       */
  475. /*   The function removes an employee from its manager.               */
  476. /**********************************************************************/
  477.  
  478. static VOID RemoveEmployee(DHND dhnd,SHND employee_shnd)
  479. {
  480.   EMPLOYEE         employee;           /* employee object data        */
  481.   EMPLOYEE         manager;            /* manager object data         */
  482.   SHORT            i;                  /* array index                 */
  483.  
  484.   /*------------------------------------------------------------------*/
  485.   /* See whether the employee reports to a manager.                   */
  486.   /*------------------------------------------------------------------*/
  487.  
  488.   GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  489.      (employee));
  490.   if (employee.manager_shnd != GS_INVALID_SHND)
  491.   {                                    /* the employee reports to a
  492.                                           manager                     */
  493.  
  494.     /*----------------------------------------------------------------*/
  495.     /* Retrieve the manager object data.                              */
  496.     /*----------------------------------------------------------------*/
  497.  
  498.     GsGetSymObjectData(dhnd, employee.manager_shnd, (PVOID)&manager,
  499.        sizeof(manager));
  500.  
  501.     /*----------------------------------------------------------------*/
  502.     /* Retrieve the index of the employee to be removed in the array  */
  503.     /* of employee handles.                                           */
  504.     /*----------------------------------------------------------------*/
  505.  
  506.     i = 0;
  507.     while ((manager.employee_shnd[i] != employee_shnd) && (i <
  508.        EMPLOYEE_MAX))
  509.     {
  510.       i++;
  511.     }
  512.  
  513.     /*----------------------------------------------------------------*/
  514.     /* See whether the index was found.                               */
  515.     /*----------------------------------------------------------------*/
  516.  
  517.     if (i < EMPLOYEE_MAX)
  518.     {                                  /* correct index               */
  519.  
  520.       /*--------------------------------------------------------------*/
  521.       /* Reduce the number of employees reporting to the manager.     */
  522.       /*--------------------------------------------------------------*/
  523.  
  524.       manager.employee_num--;
  525.  
  526.       /*--------------------------------------------------------------*/
  527.       /* Remove the handle of the employee from the array.            */
  528.       /*--------------------------------------------------------------*/
  529.  
  530.       memcpy(&manager.employee_shnd[i], &manager.employee_shnd[i+1],
  531.          (manager.employee_num-i)*sizeof(SHND));
  532.  
  533.       /*--------------------------------------------------------------*/
  534.       /* Store the manager object data.                               */
  535.       /*--------------------------------------------------------------*/
  536.  
  537.       GsPutSymObjectData(dhnd, employee.manager_shnd, (PVOID)&manager,
  538.          sizeof(manager));
  539.     }
  540.   }
  541. }
  542.  
  543. /**********************************************************************/
  544. /* RemoveGenManager                                                   */
  545. /*                                                                    */
  546. /* Parameters:                                                        */
  547. /*   DHND             dhnd          (I): Diagram handle               */
  548. /*                                                                    */
  549. /* Returns:                                                           */
  550. /*   VOID                                                             */
  551. /*                                                                    */
  552. /* Description:                                                       */
  553. /*   The function removes the general manager from the company.       */
  554. /**********************************************************************/
  555.  
  556. static VOID RemoveGenManager(DHND dhnd)
  557. {
  558.   SHND             gen_manager_shnd;   /* handle of general manager   */
  559.   SHORT            af;                 /* state of the action flag    */
  560.   LONG             long_value;         /* long value of the diagram   */
  561.  
  562.   /*------------------------------------------------------------------*/
  563.   /* Retrieve the handle of the symbol representing the general       */
  564.   /* manager.                                                         */
  565.   /*------------------------------------------------------------------*/
  566.  
  567.   GsGetDiagLong(dhnd, &long_value);
  568.   gen_manager_shnd = LOUSHORT(long_value);
  569.  
  570.   /*------------------------------------------------------------------*/
  571.   /* See whether the general manager is to be removed. This means that*/
  572.   /* all employees are removed.                                       */
  573.   /*------------------------------------------------------------------*/
  574.  
  575.   GsGetSymAf(dhnd, gen_manager_shnd, &af);
  576.   if (af == GS_ON)
  577.   {                                    /* the general manager is to be
  578.                                           removed                     */
  579.  
  580.     /*----------------------------------------------------------------*/
  581.     /* Store the handle of the symbol representing the general        */
  582.     /* manager. As there will be no employee in the company, the value*/
  583.     /* being stored is GS_INVALID_SHND.                               */
  584.     /*----------------------------------------------------------------*/
  585.  
  586.     GsPutDiagLong(dhnd, (LONG)GS_INVALID_SHND);
  587.   }
  588. }
  589.  
  590. /**********************************************************************/
  591. /* EvClick                                                            */
  592. /*                                                                    */
  593. /* Parameters:                                                        */
  594. /*    DHND                     dhnd  (I): Diagram handle.             */
  595. /*    SHORT                    ev_id (I): Identifies the event.       */
  596. /*    EVS_CLICK                *pEvs (I): Pointer to instance of event*/
  597. /*                                        data type.                  */
  598. /*     SHND   shnd (I):            Handle of the symbol               */
  599. /*     SHORT  part_ref (I):        Reference number of the symbol part*/
  600. /*     USHORT button (I):          indicator of the pressed mouse     */
  601. /*                                 button                             */
  602. /*                                   GS_MB1                           */
  603. /*                                   GS_MB2                           */
  604. /*                                                                    */
  605. /* Returns:                                                           */
  606. /*   GS_NO        Any changes made to symbols remain and the action   */
  607. /*                stops.                                              */
  608. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  609. /*                stops.                                              */
  610. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  611. /*                checkpoint are undone and the action stops.         */
  612. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  613. /*                checkpoint are undone and the action stops.         */
  614. /*   GS_YES       The default processing continues.                   */
  615. /*                                                                    */
  616. /* Description:                                                       */
  617. /*    The function handles the event EV_CLICK.                        */
  618. /*    - Flips the visibility state of the symbol part indicating the  */
  619. /*      sex of the employee.                                          */
  620. /**********************************************************************/
  621.  
  622. SHORT GSENTRY EvClick(DHND dhnd,SHORT ev_id,EVS_CLICK *pEvs)
  623. {
  624.   SHORT            visible;
  625.  
  626.   /*------------------------------------------------------------------*/
  627.   /* See whether a woman is shown.                                    */
  628.   /*------------------------------------------------------------------*/
  629.  
  630.   GsGetPartVisibility(dhnd, pEvs->shnd, PERSON_WOMAN, &visible);
  631.   if (visible == GS_ON)
  632.   {                                    /* a woman is shown            */
  633.  
  634.     /*----------------------------------------------------------------*/
  635.     /* Show a man.                                                    */
  636.     /*----------------------------------------------------------------*/
  637.  
  638.     GsPutPartVisibility(dhnd, pEvs->shnd, PERSON_WOMAN, GS_OFF);
  639.     GsPutPartVisibility(dhnd, pEvs->shnd, PERSON_MAN, GS_ON);
  640.   }
  641.   else
  642.   {                                    /* a man is shown              */
  643.  
  644.     /*----------------------------------------------------------------*/
  645.     /* Show a woman.                                                  */
  646.     /*----------------------------------------------------------------*/
  647.  
  648.     GsPutPartVisibility(dhnd, pEvs->shnd, PERSON_WOMAN, GS_ON);
  649.     GsPutPartVisibility(dhnd, pEvs->shnd, PERSON_MAN, GS_OFF);
  650.   }
  651.   return  GS_YES;
  652. }
  653.  
  654. /**********************************************************************/
  655. /* EvEndAdd                                                           */
  656. /*                                                                    */
  657. /* Parameters:                                                        */
  658. /*    DHND                     dhnd  (I): Diagram handle.             */
  659. /*    SHORT                    ev_id (I): Identifies the event.       */
  660. /*    EVS_END_ADD              *pEvs (I): Pointer to instance of event*/
  661. /*                                        data type.                  */
  662. /*     SHND   shnd (I):            Handle of the symbol               */
  663. /*     POINTL mouse_pos (I):       Position of the mouse pointer      */
  664. /*                                                                    */
  665. /* Returns:                                                           */
  666. /*   GS_NO        Any changes made to symbols remain and the action   */
  667. /*                stops.                                              */
  668. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  669. /*                stops.                                              */
  670. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  671. /*                checkpoint are undone and the action stops.         */
  672. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  673. /*                checkpoint are undone and the action stops.         */
  674. /*   GS_YES       The default processing continues.                   */
  675. /*                                                                    */
  676. /* Description:                                                       */
  677. /*    The function handles the event EV_END_ADD.                      */
  678. /*    - The employee-manager relationship for the new employee is     */
  679. /*      determined.                                                   */
  680. /*    - The data of the new employee are initialized.                 */
  681. /**********************************************************************/
  682.  
  683. SHORT GSENTRY EvEndAdd(DHND dhnd,SHORT ev_id,EVS_END_ADD *pEvs)
  684. {
  685.   EMPLOYEE         employee;           /* employee object data        */
  686.   SHORT            rc;                 /* return code                 */
  687.  
  688.   /*------------------------------------------------------------------*/
  689.   /* Initialize the employee data.                                    */
  690.   /*------------------------------------------------------------------*/
  691.  
  692.   memset(&employee, 0, sizeof(employee));
  693.   GsPutSymObjectData(dhnd, pEvs->shnd, (PVOID)&employee, sizeof(employee
  694.      ));
  695.  
  696.   /*------------------------------------------------------------------*/
  697.   /* If the new employee will not become general manager, it is to be */
  698.   /* attached to a manager.                                           */
  699.   /*------------------------------------------------------------------*/
  700.  
  701.   if (EmployeeForGenManager(dhnd, pEvs->shnd) == GS_NO)
  702.   {                                    /* the employee is not general
  703.                                           manager                     */
  704.     rc = AttachMoveEmployeeToManager(dhnd, pEvs->shnd);
  705.     switch (rc)
  706.     {
  707.       case  GS_YES :
  708.         break;
  709.       case  GS_REJECT :
  710.         MSG_EMPLOYEE_NOT_ATTACHED(STR_PLACE_ADDED_EMPLOYEE);
  711.         return (rc);
  712.       default  :
  713.         return  GS_RESTORE;
  714.     }
  715.   }
  716.   return  GS_YES;
  717. }
  718.  
  719. /**********************************************************************/
  720. /* SetGenManager                                                      */
  721. /*                                                                    */
  722. /* Parameters:                                                        */
  723. /*   DHND             dhnd          (I): Diagram handle               */
  724. /*                                                                    */
  725. /* Returns:                                                           */
  726. /*   GS_NO                                                            */
  727. /*   GS_YES                                                           */
  728. /*                                                                    */
  729. /* Description:                                                       */
  730. /*   The function retrieves the general manager of a company and      */
  731. /*   stores this information.                                         */
  732. /**********************************************************************/
  733.  
  734. SHORT SetGenManager(DHND dhnd)
  735. {
  736.   SHND             gen_manager_shnd;   /* handle of general manager   */
  737.   SHND             employee_shnd;      /* handle of employee          */
  738.   LONG             long_value;         /* long value of the diagram   */
  739.   EMPLOYEE         employee;           /* employee object data        */
  740.  
  741.   /*------------------------------------------------------------------*/
  742.   /* Retrieve the handle of the symbol representing the general       */
  743.   /* manager.                                                         */
  744.   /*------------------------------------------------------------------*/
  745.  
  746.   GsGetDiagLong(dhnd, &long_value);
  747.   gen_manager_shnd = LOUSHORT(long_value);
  748.  
  749.   /*------------------------------------------------------------------*/
  750.   /* See whether a general manager exists.                            */
  751.   /*------------------------------------------------------------------*/
  752.  
  753.   if (gen_manager_shnd == GS_INVALID_SHND)
  754.   {                                    /* no general manager exists   */
  755.  
  756.     /*----------------------------------------------------------------*/
  757.     /* See whether an employee exists.                                */
  758.     /*----------------------------------------------------------------*/
  759.  
  760.     if (GsGetFirstSym(dhnd, GS_NODE, GS_ANY_SYM, GS_UPPER_FIRST,
  761.        &employee_shnd) == GS_OK)
  762.     {                                  /* an employee exists          */
  763.       while (employee_shnd != GS_INVALID_SHND)
  764.       {
  765.  
  766.         /*------------------------------------------------------------*/
  767.         /* Retrieve the employee object data.                         */
  768.         /*------------------------------------------------------------*/
  769.  
  770.         GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  771.            (employee));
  772.  
  773.         /*------------------------------------------------------------*/
  774.         /* See whether the employee is the general manager.           */
  775.         /*------------------------------------------------------------*/
  776.  
  777.         if (employee.manager_shnd == GS_INVALID_SHND)
  778.         {                              /* he is the general manager   */
  779.           break;
  780.         }
  781.         else
  782.         {                              /* he is not the general
  783.                                           manager                     */
  784.           employee_shnd = employee.manager_shnd;
  785.         }
  786.       }
  787.  
  788.       /*--------------------------------------------------------------*/
  789.       /* The employee is stored as general manager.                   */
  790.       /*--------------------------------------------------------------*/
  791.  
  792.       EmployeeForGenManager(dhnd, employee_shnd);
  793.     }
  794.   }
  795.   return  GS_YES;
  796. }
  797.  
  798. /**********************************************************************/
  799. /* EmployeeForGenManager                                              */
  800. /*                                                                    */
  801. /* Parameters:                                                        */
  802. /*   DHND             dhnd          (I): Diagram handle               */
  803. /*   SHND             employee_shnd (I): handle of employee           */
  804. /*                                                                    */
  805. /* Returns:                                                           */
  806. /*   GS_NO                                                            */
  807. /*   GS_YES                                                           */
  808. /*                                                                    */
  809. /* Description:                                                       */
  810. /*   The function checks whether this is the first employee added     */
  811. /*   to the company.                                                  */
  812. /**********************************************************************/
  813.  
  814. SHORT EmployeeForGenManager(DHND dhnd,SHND employee_shnd)
  815. {
  816.   SHND             gen_manager_shnd;   /* handle of general manager   */
  817.   EMPLOYEE         employee;           /* employee object data        */
  818.   LONG             long_value;         /* long value of the diagram   */
  819.  
  820.   /*------------------------------------------------------------------*/
  821.   /* Retrieve the handle of the symbol representing the general       */
  822.   /* manager.                                                         */
  823.   /*------------------------------------------------------------------*/
  824.  
  825.   GsGetDiagLong(dhnd, &long_value);
  826.   gen_manager_shnd = LOUSHORT(long_value);
  827.  
  828.   /*------------------------------------------------------------------*/
  829.   /* See whether a general manager exists.                            */
  830.   /*------------------------------------------------------------------*/
  831.  
  832.   if (gen_manager_shnd == GS_INVALID_SHND)
  833.   {                                    /* no general manager exists   */
  834.  
  835.     /*----------------------------------------------------------------*/
  836.     /* Retrieve the employee object data.                             */
  837.     /*----------------------------------------------------------------*/
  838.  
  839.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  840.        (employee));
  841.  
  842.     /*----------------------------------------------------------------*/
  843.     /* The employee is stored as general manager.                     */
  844.     /*----------------------------------------------------------------*/
  845.  
  846.     GsPutDiagLong(dhnd, (LONG)employee_shnd);
  847.  
  848.     /*----------------------------------------------------------------*/
  849.     /* Store the information about the manager in the employee data.  */
  850.     /*----------------------------------------------------------------*/
  851.  
  852.     employee.manager_shnd = GS_INVALID_SHND;
  853.     employee.pre_manager_shnd = GS_INVALID_SHND;
  854.     GsPutSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  855.        (employee));
  856.     return  GS_YES;
  857.   }
  858.   return  GS_NO;
  859. }
  860.  
  861. /**********************************************************************/
  862. /* AttachMoveEmployeeToManager                                        */
  863. /*                                                                    */
  864. /* Parameters:                                                        */
  865. /*   DHND             dhnd          (I): Diagram handle               */
  866. /*   SHND             employee_shnd (I): handle of employee           */
  867. /*                                                                    */
  868. /* Returns:                                                           */
  869. /*   GS_NO            the attachment is not done                      */
  870. /*   GS_REJECT        the attachment is not accepted                  */
  871. /*   GS_YES           the attachment is done                          */
  872. /*                                                                    */
  873. /* Description:                                                       */
  874. /*   The function adds an employee to a manager.                      */
  875. /**********************************************************************/
  876.  
  877. SHORT AttachMoveEmployeeToManager(DHND dhnd,SHND employee_shnd)
  878. {
  879.   SHND             manager_shnd;       /* handle of manager           */
  880.  
  881.   /*------------------------------------------------------------------*/
  882.   /* Determine the manager of the employee.                           */
  883.   /*------------------------------------------------------------------*/
  884.  
  885.   if (GsGetFirstOverlappedSym(dhnd, GS_NODE, GS_UPPER_FIRST,
  886.      employee_shnd, 0, &manager_shnd, NULL) == GSE_COLLECTION_EMPTY)
  887.   {
  888.     return  GS_REJECT;
  889.   }
  890.  
  891.   /*------------------------------------------------------------------*/
  892.   /* Define the employee-manager relationship.                        */
  893.   /*------------------------------------------------------------------*/
  894.  
  895.   return  AttachEmployeeToManager(dhnd, employee_shnd, manager_shnd);
  896. }
  897.  
  898. /**********************************************************************/
  899. /* AttachEmployeeToManager                                            */
  900. /*                                                                    */
  901. /* Parameters:                                                        */
  902. /*   DHND             dhnd          (I): Diagram handle               */
  903. /*   SHND             employee_shnd (I): handle of employee           */
  904. /*   SHND             manager_shnd  (I): handle of manager            */
  905. /*                                                                    */
  906. /* Returns:                                                           */
  907. /*   GS_NO            the attachment is not done                      */
  908. /*   GS_YES           the attachment is done                          */
  909. /*                                                                    */
  910. /* Description:                                                       */
  911. /*   The function adds an employee to a manager.                      */
  912. /**********************************************************************/
  913.  
  914. SHORT AttachEmployeeToManager(DHND dhnd,SHND employee_shnd,SHND
  915.                                manager_shnd)
  916. {
  917.   SHND             link_shnd;          /* handle of link symbol       */
  918.   EMPLOYEE         employee;           /* employee object data        */
  919.   EMPLOYEE         manager;            /* manager object data         */
  920.  
  921.   /*------------------------------------------------------------------*/
  922.   /* Check the symbol handles.                                        */
  923.   /*------------------------------------------------------------------*/
  924.  
  925.   if ((employee_shnd == GS_INVALID_SHND) || /*                        */
  926.      (manager_shnd == GS_INVALID_SHND))
  927.   {                                    /* invalid symbol handles      */
  928.     return  GS_NO;
  929.   }
  930.  
  931.   /*------------------------------------------------------------------*/
  932.   /* Retrieve the employee object data.                               */
  933.   /*------------------------------------------------------------------*/
  934.  
  935.   GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  936.      (employee));
  937.  
  938.   /*------------------------------------------------------------------*/
  939.   /* A new employee cannot report to a manager whose number of        */
  940.   /* employees reporting to him is already maximal.                   */
  941.   /*------------------------------------------------------------------*/
  942.  
  943.   GsGetSymObjectData(dhnd, manager_shnd, (PVOID)&manager, sizeof(manager
  944.      ));
  945.   if (manager.employee_num >= EMPLOYEE_MAX)
  946.   {                                    /* too many employees          */
  947.     return  GS_NO;
  948.   }
  949.  
  950.   /*------------------------------------------------------------------*/
  951.   /* Store the information about the new employee in the manager data.*/
  952.   /*------------------------------------------------------------------*/
  953.  
  954.   manager.employee_shnd[manager.employee_num] = employee_shnd;
  955.   manager.employee_num++;
  956.   GsPutSymObjectData(dhnd, manager_shnd, (PVOID)&manager, sizeof(manager
  957.      ));
  958.  
  959.   /*------------------------------------------------------------------*/
  960.   /* Create a link from the manager to the new employee.              */
  961.   /*------------------------------------------------------------------*/
  962.  
  963.   GsAddSym(dhnd, &link_shnd, LINK_PERSONS, LINK_FORM);
  964.   GsPutSymTerminal(dhnd, link_shnd, GS_SOURCE, manager_shnd);
  965.   GsPutSymTerminal(dhnd, link_shnd, GS_TARGET, employee_shnd);
  966.  
  967.   /*------------------------------------------------------------------*/
  968.   /* Store the information about the manager in the employee data.    */
  969.   /*------------------------------------------------------------------*/
  970.  
  971.   employee.manager_shnd = manager_shnd;
  972.   employee.pre_manager_shnd = manager_shnd;
  973.   GsPutSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  974.      (employee));
  975.   return  GS_YES;
  976. }
  977.  
  978. /**********************************************************************/
  979. /* EvEndMove                                                          */
  980. /*                                                                    */
  981. /* Parameters:                                                        */
  982. /*    DHND                     dhnd  (I): Diagram handle.             */
  983. /*    SHORT                    ev_id (I): Identifies the event.       */
  984. /*    EVS_END_MOVE             *pEvs (I): Pointer to instance of event*/
  985. /*                                        data type.                  */
  986. /*     POINTL mouse_pos (I):       Position of the mouse pointer      */
  987. /*                                                                    */
  988. /* Returns:                                                           */
  989. /*   GS_NO        Any changes made to symbols remain and the action   */
  990. /*                stops.                                              */
  991. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  992. /*                stops.                                              */
  993. /*   GS_REJECT    The attempt to end the action is rejected and the   */
  994. /*                graphics editor retries the action processing.      */
  995. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  996. /*                checkpoint are undone and the action stops.         */
  997. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  998. /*                checkpoint are undone and the action stops.         */
  999. /*   GS_YES       The default processing continues.                   */
  1000. /*                                                                    */
  1001. /* Description:                                                       */
  1002. /*    The function handles the event EV_END_MOVE.                     */
  1003. /*    - The employee-manager relationship for the employees being     */
  1004. /*      moved is determined.                                          */
  1005. /**********************************************************************/
  1006.  
  1007. SHORT GSENTRY EvEndMove(DHND dhnd,SHORT ev_id,EVS_END_MOVE *pEvs)
  1008. {
  1009.   SHND             employee_shnd;      /* handle of employee          */
  1010.   EMPLOYEE         employee;           /* employee object data        */
  1011.   SHORT            rc;                 /* return code                 */
  1012.  
  1013.   /*------------------------------------------------------------------*/
  1014.   /* If all visible symbols representing employees have been moved,   */
  1015.   /* the employee-manager relationship for all employees will not be  */
  1016.   /* changed.                                                         */
  1017.   /*------------------------------------------------------------------*/
  1018.  
  1019.   if (AllVisibleEmployeesMoved(dhnd) == GS_YES)
  1020.   {
  1021.     return  GS_RESTORE;
  1022.   }
  1023.  
  1024.   /*------------------------------------------------------------------*/
  1025.   /* Loop over all symbols representing employees being moved.        */
  1026.   /*------------------------------------------------------------------*/
  1027.  
  1028.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  1029.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  1030.   {
  1031.  
  1032.     /*----------------------------------------------------------------*/
  1033.     /* Retrieve the employee object data.                             */
  1034.     /*----------------------------------------------------------------*/
  1035.  
  1036.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  1037.        (employee));
  1038.  
  1039.     /*----------------------------------------------------------------*/
  1040.     /* If the employee does not report to a manager, attach him to a  */
  1041.     /* manager.                                                       */
  1042.     /*----------------------------------------------------------------*/
  1043.  
  1044.     if (employee.manager_shnd == GS_INVALID_SHND)
  1045.     {
  1046.       rc = AttachMoveEmployeeToManager(dhnd, employee_shnd);
  1047.       switch (rc)
  1048.       {
  1049.         case  GS_YES :
  1050.           break;
  1051.         case  GS_REJECT :
  1052.           DeleteAllNewLinks(dhnd);
  1053.           MSG_EMPLOYEE_NOT_ATTACHED(STR_PLACE_N_MOVED_DEP_MANAGER);
  1054.           GsEndSymCollection(dhnd);
  1055.           return (rc);
  1056.         default  :
  1057.           GsEndSymCollection(dhnd);
  1058.           return  GS_RESTORE;
  1059.       }
  1060.     }
  1061.   }
  1062.   return  GS_YES;
  1063. }
  1064.  
  1065. /**********************************************************************/
  1066. /* AllVisibleEmployeesMoved                                           */
  1067. /*                                                                    */
  1068. /* Parameters:                                                        */
  1069. /*   DHND             dhnd          (I): Diagram handle               */
  1070. /*                                                                    */
  1071. /* Returns:                                                           */
  1072. /*   GS_NO                                                            */
  1073. /*   GS_YES                                                           */
  1074. /*                                                                    */
  1075. /* Description:                                                       */
  1076. /*   The function checks whether all visible employees are moved.     */
  1077. /**********************************************************************/
  1078.  
  1079. SHORT AllVisibleEmployeesMoved(DHND dhnd)
  1080. {
  1081.   SHND             employee_shnd;      /* handle of employee          */
  1082.   SHORT            af;                 /* state of the action flag    */
  1083.   SHORT            shown;              /* visibility of a symbol      */
  1084.  
  1085.   /*------------------------------------------------------------------*/
  1086.   /* Loop over all symbols representing employees.                    */
  1087.   /*------------------------------------------------------------------*/
  1088.  
  1089.   GsCollectSym(dhnd, GS_NODE, GS_ANY_SYM, GS_UPPER_FIRST);
  1090.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  1091.   {
  1092.  
  1093.     /*----------------------------------------------------------------*/
  1094.     /* See whether the symbol is visible.                             */
  1095.     /*----------------------------------------------------------------*/
  1096.  
  1097.     GsGetSymVisibility(dhnd, employee_shnd, &shown);
  1098.     if (shown == GS_ON)
  1099.     {
  1100.  
  1101.       /*--------------------------------------------------------------*/
  1102.       /* See whether the symbol has its action flag reset and is      */
  1103.       /* therefore not moved.                                         */
  1104.       /*--------------------------------------------------------------*/
  1105.  
  1106.       GsGetSymAf(dhnd, employee_shnd, &af);
  1107.       if (af == GS_OFF)
  1108.       {
  1109.         GsEndSymCollection(dhnd);
  1110.         return  GS_NO;
  1111.       }
  1112.     }
  1113.   }
  1114.   return  GS_YES;
  1115. }
  1116.  
  1117. /**********************************************************************/
  1118. /* DeleteAllNewLinks                                                  */
  1119. /*                                                                    */
  1120. /* Parameters:                                                        */
  1121. /*   DHND             dhnd          (I): Diagram handle               */
  1122. /*                                                                    */
  1123. /* Returns:                                                           */
  1124. /*   GS_NO                                                            */
  1125. /*   GS_YES                                                           */
  1126. /*                                                                    */
  1127. /* Description:                                                       */
  1128. /*   The function deletes all links connecting employees being moved  */
  1129. /*   with their new manager.                                          */
  1130. /**********************************************************************/
  1131.  
  1132. SHORT DeleteAllNewLinks(DHND dhnd)
  1133. {
  1134.   SHND             employee_shnd;      /* handle of employee          */
  1135.  
  1136.   /*------------------------------------------------------------------*/
  1137.   /* Loop over all symbols representing employees that have their     */
  1138.   /* action flag set.                                                 */
  1139.   /*------------------------------------------------------------------*/
  1140.  
  1141.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  1142.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  1143.   {
  1144.  
  1145.     /*----------------------------------------------------------------*/
  1146.     /* See whether every symbol representing a manager to which the   */
  1147.     /* employee is reporting has its action flag reset.               */
  1148.     /*----------------------------------------------------------------*/
  1149.  
  1150.     if (ManagerAfOff(dhnd, employee_shnd) == GS_YES)
  1151.     {                                  /* all action flags are reset  */
  1152.  
  1153.       /*--------------------------------------------------------------*/
  1154.       /* Remove the employee from its manager.                        */
  1155.       /*--------------------------------------------------------------*/
  1156.  
  1157.       RemoveEmployee(dhnd, employee_shnd);
  1158.  
  1159.       /*--------------------------------------------------------------*/
  1160.       /* Delete the link between the employee and its manager.        */
  1161.       /*--------------------------------------------------------------*/
  1162.  
  1163.       DeleteLink(dhnd, employee_shnd);
  1164.  
  1165.       /*--------------------------------------------------------------*/
  1166.       /* Remove the manager from the employee.                        */
  1167.       /*--------------------------------------------------------------*/
  1168.  
  1169.       RemoveManager(dhnd, employee_shnd);
  1170.     }
  1171.   }
  1172.   return  GS_YES;
  1173. }
  1174.  
  1175. /**********************************************************************/
  1176. /* ShowMsgAfterMovingEmployees                                        */
  1177. /*                                                                    */
  1178. /* Parameters:                                                        */
  1179. /*   DHND             dhnd          (I): Diagram handle               */
  1180. /*                                                                    */
  1181. /* Returns:                                                           */
  1182. /*   VOID                                                             */
  1183. /*                                                                    */
  1184. /* Description:                                                       */
  1185. /*   The function displays a message box that informs the end user    */
  1186. /*   after having moved employees that could not be attached to a     */
  1187. /*   manager.                                                         */
  1188. /**********************************************************************/
  1189.  
  1190. static VOID ShowMsgAfterMovingEmployees(DHND dhnd)
  1191. {
  1192.   SHND             employee_shnd;      /* handle of employee          */
  1193.   EMPLOYEE         employee;           /* employee object data        */
  1194.   SHORT            moved_employee_num; /* number of moved employees   */
  1195.   SHORT            moved_dep_manager_num;/* number of moved department
  1196.                                           managers                    */
  1197.  
  1198.   /*------------------------------------------------------------------*/
  1199.   /* Loop over all moved symbols representing employees.              */
  1200.   /*------------------------------------------------------------------*/
  1201.  
  1202.   moved_employee_num = 0;
  1203.   moved_dep_manager_num = 0;
  1204.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  1205.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  1206.   {
  1207.     moved_employee_num++;
  1208.  
  1209.     /*----------------------------------------------------------------*/
  1210.     /* Retrieve the employee object data.                             */
  1211.     /*----------------------------------------------------------------*/
  1212.  
  1213.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  1214.        (employee));
  1215.  
  1216.     /*----------------------------------------------------------------*/
  1217.     /* See whether the employee is a department manager.              */
  1218.     /*----------------------------------------------------------------*/
  1219.  
  1220.     if (employee.manager_shnd == GS_INVALID_SHND)
  1221.     {
  1222.       if (employee.employee_num)
  1223.       {
  1224.         moved_dep_manager_num++;
  1225.       }
  1226.       if (moved_dep_manager_num > 2)
  1227.       {
  1228.         GsEndSymCollection(dhnd);
  1229.         break;
  1230.       }
  1231.     }
  1232.   }
  1233.  
  1234.   /*------------------------------------------------------------------*/
  1235.   /* Display the appropriate message.                                 */
  1236.   /*------------------------------------------------------------------*/
  1237.  
  1238.   if (moved_employee_num == 1)
  1239.   {
  1240.     MSG_EMPLOYEE_NOT_ATTACHED(STR_PLACE_MOVED_EMPLOYEE);
  1241.   }
  1242.   else
  1243.   {
  1244.     if (moved_dep_manager_num == 1)
  1245.     {
  1246.       MSG_EMPLOYEE_NOT_ATTACHED(STR_PLACE_1_MOVED_DEP_MANAGER);
  1247.     }
  1248.     else
  1249.     {
  1250.       MSG_EMPLOYEE_NOT_ATTACHED(STR_PLACE_N_MOVED_DEP_MANAGER);
  1251.     }
  1252.   }
  1253. }
  1254.  
  1255. /**********************************************************************/
  1256. /* EvInit                                                             */
  1257. /*                                                                    */
  1258. /* Parameters:                                                        */
  1259. /*    DHND                     dhnd  (I): Diagram handle.             */
  1260. /*    SHORT                    ev_id (I): Identifies the event.       */
  1261. /*    EVS_INIT                 *pEvs (I): Pointer to instance of event*/
  1262. /*                                        data type.                  */
  1263. /*     VOID *pInit_data (I):       Pointer passed from the customizing*/
  1264. /*                                 code to the parameter pInit_data of*/
  1265. /*                                 the GIK/2 function GsInitWin       */
  1266. /*     HAB  hab (I):               Handle to anchor block             */
  1267. /*     HWND hwnd_client (I):       Handle to client window            */
  1268. /*     HWND hwnd_frame (I):        Handle to frame window             */
  1269. /*                                                                    */
  1270. /* Returns:                                                           */
  1271. /*   GS_NO        The window is closed.                               */
  1272. /*   GS_YES       The initialization of the GIK/2 window continues.   */
  1273. /*                                                                    */
  1274. /* Description:                                                       */
  1275. /*    The function handles the event EV_INIT.                         */
  1276. /**********************************************************************/
  1277.  
  1278. SHORT GSENTRY EvInit(DHND dhnd,SHORT ev_id,EVS_INIT *pEvs)
  1279. {
  1280.   ULONG            cst;                /* diagram constraints         */
  1281.  
  1282.   /*------------------------------------------------------------------*/
  1283.   /* Store the handle of the symbol representing the general manager. */
  1284.   /* As there is no employee in the company, the value being stored is*/
  1285.   /* GS_INVALID_SHND.                                                 */
  1286.   /*------------------------------------------------------------------*/
  1287.  
  1288.   GsPutDiagLong(dhnd, (LONG)GS_INVALID_SHND);
  1289.  
  1290.   /*------------------------------------------------------------------*/
  1291.   /* The direct manipulation operation has to be a Move only.         */
  1292.   /*------------------------------------------------------------------*/
  1293.  
  1294.   GsGetDiagConstraint(dhnd, &cst);
  1295.   cst &= ~(GS_CST_DIAG_DRAG_COPY|GS_CST_DIAG_DRAG_LINK);
  1296.   GsPutDiagConstraint(dhnd, cst);
  1297.   return  GS_YES;
  1298. }
  1299.  
  1300. /**********************************************************************/
  1301. /* EvMenu                                                             */
  1302. /*                                                                    */
  1303. /* Parameters:                                                        */
  1304. /*    DHND                     dhnd  (I): Diagram handle.             */
  1305. /*    SHORT                    ev_id (I): Identifies the event.       */
  1306. /*    EVS_MENU                 *pEvs (I): Pointer to instance of event*/
  1307. /*                                        data type.                  */
  1308. /*     SHORT  win_id (I):          Identification of the window       */
  1309. /*                                 It is one of the following:        */
  1310. /*                                   GS_WIN_MAIN                      */
  1311. /*                                   GS_WIN_OV                        */
  1312. /*     USHORT menu_id (I):         Identifier of the menu bar choice  */
  1313. /*                                                                    */
  1314. /* Returns:                                                           */
  1315. /*   GS_NO        Any changes made to symbols remain and the action   */
  1316. /*                stops.                                              */
  1317. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  1318. /*                stops.                                              */
  1319. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  1320. /*                checkpoint are undone and the action stops.         */
  1321. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  1322. /*                checkpoint are undone and the action stops.         */
  1323. /*   GS_YES       The default processing continues.                   */
  1324. /*                                                                    */
  1325. /* Description:                                                       */
  1326. /*    The function handles the event EV_MENU.                         */
  1327. /*    - Enables or disables choices of the 'Department' pull-down.    */
  1328. /*    - Enables or disables pull-down choices for adding an employee. */
  1329. /**********************************************************************/
  1330.  
  1331. SHORT GSENTRY EvMenu(DHND dhnd,SHORT ev_id,EVS_MENU *pEvs)
  1332. {
  1333.   LONG             long_value;         /* long value of the diagram   */
  1334.   SHND             gen_manager_shnd;   /* handle of general manager   */
  1335.   SHND             shnd;               /* symbol handle               */
  1336.   SHORT            shown;              /* visibility of a symbol      */
  1337.   SHORT            state;              /* state of the menu item      */
  1338.   SHORT            rc;                 /* return code                 */
  1339.   SHORT            action_num;         /* number of pending actions   */
  1340.  
  1341.   /*------------------------------------------------------------------*/
  1342.   /* Retrieve the handle of the symbol representing the general       */
  1343.   /* manager.                                                         */
  1344.   /*------------------------------------------------------------------*/
  1345.  
  1346.   GsGetDiagLong(dhnd, &long_value);
  1347.   gen_manager_shnd = LOUSHORT(long_value);
  1348.  
  1349.   /*------------------------------------------------------------------*/
  1350.   /* If the symbol representing the general manager is visible, the   */
  1351.   /* 'Company' menu item is disabled. Otherwise it is enabled.        */
  1352.   /*------------------------------------------------------------------*/
  1353.  
  1354.   if (gen_manager_shnd == GS_INVALID_SHND)
  1355.   {                                    /* no general manager exists   */
  1356.     state = GS_OFF;
  1357.   }
  1358.   else
  1359.   {
  1360.     GsGetSymVisibility(dhnd, gen_manager_shnd, &shown);
  1361.     if (shown == GS_ON)
  1362.     {                                  /* the symbol is visible       */
  1363.       state = GS_OFF;
  1364.     }
  1365.     else
  1366.     {                                  /* the symbol is invisible     */
  1367.       state = GS_ON;
  1368.     }
  1369.   }
  1370.   GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_COMPANY, state);
  1371.  
  1372.   /*------------------------------------------------------------------*/
  1373.   /* If at least one selected symbol is selected, the 'Development'   */
  1374.   /* menu item is to enable. Otherwise it is to disable.              */
  1375.   /*------------------------------------------------------------------*/
  1376.  
  1377.   state = GS_OFF;
  1378.   GsCollectSym(dhnd, GS_NODE, GS_SYM_SELECTED, GS_UPPER_FIRST);
  1379.   while (GsGetCollectedSym(dhnd, &shnd) == GS_OK)
  1380.   {
  1381.  
  1382.     /*----------------------------------------------------------------*/
  1383.     /* See whether the symbol is visible.                             */
  1384.     /*----------------------------------------------------------------*/
  1385.  
  1386.     GsGetSymVisibility(dhnd, shnd, &shown);
  1387.     if (shown == GS_ON)
  1388.     {
  1389.       state = GS_ON;
  1390.       GsEndSymCollection(dhnd);
  1391.       break;
  1392.     }
  1393.   }
  1394.  
  1395.   /*------------------------------------------------------------------*/
  1396.   /* If at least one department manager is not selected, the 'Branch' */
  1397.   /* menu item is to enable. Otherwise it is to disable.              */
  1398.   /*------------------------------------------------------------------*/
  1399.  
  1400.   if (state == GS_ON)
  1401.   {
  1402.     if (NotSelectedDepManager(dhnd, gen_manager_shnd) == GS_NO)
  1403.       state = GS_OFF;
  1404.   }
  1405.   GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_BRANCH, state);
  1406.  
  1407.   /*------------------------------------------------------------------*/
  1408.   /* If actions are pending, some action cannot be processed.         */
  1409.   /*------------------------------------------------------------------*/
  1410.  
  1411.   GsGetAction(dhnd, NULL, &action_num);
  1412.   if (action_num > 1)
  1413.   {
  1414.     state = GS_OFF;
  1415.   }
  1416.   else
  1417.   {
  1418.     state = GS_ON;
  1419.   }
  1420.   if (state == GS_OFF)
  1421.   {
  1422.     GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_CLEAR, state);
  1423.     GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_SELECT_ALL, state);
  1424.     GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_DESELECT, state);
  1425.     GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_COLOR, state);
  1426.     GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_SET_FONT, state);
  1427.     GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, AID_RESET_FONT, state);
  1428.   }
  1429.  
  1430.   /*------------------------------------------------------------------*/
  1431.   /* If actions are pending and if no symbol representing an employee */
  1432.   /* in the company is visible, some action cannot be processed.      */
  1433.   /*------------------------------------------------------------------*/
  1434.  
  1435.   if (state == GS_ON)
  1436.   {
  1437.     rc = VisibleEmployee(dhnd);
  1438.     if (rc == GS_NO)
  1439.     {
  1440.       state = GS_OFF;
  1441.     }
  1442.   }
  1443.   GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, MID_NODE, state);
  1444.   if (state == GS_ON)
  1445.   {
  1446.     if (rc == GS_REJECT)
  1447.     {
  1448.       state = GS_OFF;
  1449.     }
  1450.   }
  1451.   GsPutMenuItemEnabled(dhnd, GS_WIN_MAIN, MID_LAY, state);
  1452.   return  GS_YES;
  1453. }
  1454.  
  1455. /**********************************************************************/
  1456. /* NotSelectedDepManager                                              */
  1457. /*                                                                    */
  1458. /* Parameters:                                                        */
  1459. /*   DHND             dhnd           (I): Diagram handle              */
  1460. /*   SHND             employee_shnd  (I): handle of employee          */
  1461. /*                                                                    */
  1462. /* Returns:                                                           */
  1463. /*   GS_NO                                                            */
  1464. /*   GS_YES                                                           */
  1465. /*                                                                    */
  1466. /* Description:                                                       */
  1467. /*   The function retrieves the handle of a department manager        */
  1468. /*   of which the symbol that is representing him is not selected.    */
  1469. /**********************************************************************/
  1470.  
  1471. SHORT NotSelectedDepManager(DHND dhnd,SHND employee_shnd)
  1472. {
  1473.   SHORT            shown;              /* visibility of a symbol      */
  1474.   SHORT            selection;          /* selection state of a symbol */
  1475.   EMPLOYEE         employee;           /* employee object data        */
  1476.   SHORT            cnt;                /* symbol count                */
  1477.  
  1478.   /*------------------------------------------------------------------*/
  1479.   /* See whether the symbol is visible.                               */
  1480.   /*------------------------------------------------------------------*/
  1481.  
  1482.   GsGetSymVisibility(dhnd, employee_shnd, &shown);
  1483.   if (shown == GS_ON)
  1484.   {                                    /* it is visible               */
  1485.  
  1486.     /*----------------------------------------------------------------*/
  1487.     /* See whether the symbol is selected.                            */
  1488.     /*----------------------------------------------------------------*/
  1489.  
  1490.     GsGetSymSelection(dhnd, employee_shnd, &selection);
  1491.     if (selection == GS_OFF)
  1492.     {                                  /* it is not selected          */
  1493.       return  GS_YES;
  1494.     }
  1495.     else
  1496.     {                                  /* it is selected              */
  1497.       return  GS_NO;
  1498.     }
  1499.   }
  1500.   else
  1501.   {                                    /* it is invisible             */
  1502.  
  1503.     /*----------------------------------------------------------------*/
  1504.     /* Retrieve the employee object data.                             */
  1505.     /*----------------------------------------------------------------*/
  1506.  
  1507.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  1508.        (employee));
  1509.  
  1510.     /*----------------------------------------------------------------*/
  1511.     /* Loop over all employees reporting to the current employee.     */
  1512.     /*----------------------------------------------------------------*/
  1513.  
  1514.     for (cnt = 0; cnt < employee.employee_num; cnt++)
  1515.     {
  1516.       if (NotSelectedDepManager(dhnd, employee.employee_shnd[cnt]) ==
  1517.          GS_YES)
  1518.         return  GS_YES;
  1519.     }
  1520.   }
  1521.   return  GS_NO;
  1522. }
  1523.  
  1524. /**********************************************************************/
  1525. /* VisibleEmployee                                                    */
  1526. /*                                                                    */
  1527. /* Parameters:                                                        */
  1528. /*   DHND             dhnd           (I): Diagram handle              */
  1529. /*                                                                    */
  1530. /* Returns:                                                           */
  1531. /*   GS_NO                                                            */
  1532. /*   GS_REJECT                                                        */
  1533. /*   GS_YES                                                           */
  1534. /*                                                                    */
  1535. /* Description:                                                       */
  1536. /*   The function checks whether at leastone symbol representing an   */
  1537. /*   employee is visible.                                             */
  1538. /**********************************************************************/
  1539.  
  1540. SHORT VisibleEmployee(DHND dhnd)
  1541. {
  1542.   SHND             gen_manager_shnd;   /* handle of general manager   */
  1543.   SHND             employee_shnd;      /* handle of employee          */
  1544.   SHORT            shown;              /* visibility of a symbol      */
  1545.   LONG             long_value;         /* long value of the diagram   */
  1546.  
  1547.   /*------------------------------------------------------------------*/
  1548.   /* Retrieve the handle of the symbol representing the general       */
  1549.   /* manager.                                                         */
  1550.   /*------------------------------------------------------------------*/
  1551.  
  1552.   GsGetDiagLong(dhnd, &long_value);
  1553.   gen_manager_shnd = LOUSHORT(long_value);
  1554.  
  1555.   /*------------------------------------------------------------------*/
  1556.   /* If no general manager exists, symbols cannot be visible.         */
  1557.   /*------------------------------------------------------------------*/
  1558.  
  1559.   if (gen_manager_shnd == GS_INVALID_SHND)
  1560.   {
  1561.     return  GS_REJECT;
  1562.   }
  1563.  
  1564.   /*------------------------------------------------------------------*/
  1565.   /* Loop over all symbols representing employees.                    */
  1566.   /*------------------------------------------------------------------*/
  1567.  
  1568.   GsCollectSym(dhnd, GS_NODE, GS_ANY_SYM, GS_UPPER_FIRST);
  1569.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  1570.   {
  1571.  
  1572.     /*----------------------------------------------------------------*/
  1573.     /* See whether the symbol is visible.                             */
  1574.     /*----------------------------------------------------------------*/
  1575.  
  1576.     GsGetSymVisibility(dhnd, employee_shnd, &shown);
  1577.     if (shown == GS_ON)
  1578.     {
  1579.       GsEndSymCollection(dhnd);
  1580.       return  GS_YES;
  1581.     }
  1582.   }
  1583.   return  GS_NO;
  1584. }
  1585.  
  1586. /**********************************************************************/
  1587. /* EvNew                                                              */
  1588. /*                                                                    */
  1589. /* Parameters:                                                        */
  1590. /*    DHND                     dhnd  (I): Diagram handle.             */
  1591. /*    SHORT                    ev_id (I): Identifies the event.       */
  1592. /*    VOID                     *pEvs (I): Pointer to instance of event*/
  1593. /*                                        data type.                  */
  1594. /*                                                                    */
  1595. /* Returns:                                                           */
  1596. /*   GS_NO        Any changes made to symbols remain and the action   */
  1597. /*                stops.                                              */
  1598. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  1599. /*                stops.                                              */
  1600. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  1601. /*                checkpoint are undone and the action stops.         */
  1602. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  1603. /*                checkpoint are undone and the action stops.         */
  1604. /*   GS_YES       The default processing continues.                   */
  1605. /*                                                                    */
  1606. /* Description:                                                       */
  1607. /*    The function handles the event EV_NEW.                          */
  1608. /**********************************************************************/
  1609.  
  1610. SHORT GSENTRY EvNew(DHND dhnd,SHORT ev_id,VOID *pEvs)
  1611. {
  1612.  
  1613.   /*------------------------------------------------------------------*/
  1614.   /* Store the handle of the symbol representing the general manager. */
  1615.   /* As there is no employee in the company, the value being stored is*/
  1616.   /* GS_INVALID_SHND.                                                 */
  1617.   /*------------------------------------------------------------------*/
  1618.  
  1619.   GsPutDiagLong(dhnd, (LONG)GS_INVALID_SHND);
  1620.   return  GS_YES;
  1621. }
  1622.  
  1623. /**********************************************************************/
  1624. /* EvStartAdd                                                         */
  1625. /*                                                                    */
  1626. /* Parameters:                                                        */
  1627. /*    DHND                     dhnd  (I): Diagram handle.             */
  1628. /*    SHORT                    ev_id (I): Identifies the event.       */
  1629. /*    EVS_START_ADD            *pEvs (I): Pointer to instance of event*/
  1630. /*                                        data type.                  */
  1631. /*     SHND  shnd (I):             Handle of the symbol               */
  1632. /*     SHORT sym_class (I):        Class of the symbol. It is one of  */
  1633. /*                                 the following:                     */
  1634. /*                                   GS_NODE                          */
  1635. /*                                   GS_LINK                          */
  1636. /*     SHORT sym_type (I):         Type of the symbol                 */
  1637. /*     SHORT sym_form (I):         Form of the symbol                 */
  1638. /*     SHORT palette (I):          Palette indicator                  */
  1639. /*                                 It specifies whether a symbol is   */
  1640. /*                                 being added from the Symbol        */
  1641. /*                                 Palette. It is one of the          */
  1642. /*                                 following:                         */
  1643. /*                                   GS_NO                            */
  1644. /*                                   GS_YES                           */
  1645. /*                                                                    */
  1646. /* Returns:                                                           */
  1647. /*   GS_END       The action is ended in the same way the end user    */
  1648. /*                would end the action.                               */
  1649. /*   GS_NO        Any changes made to symbols remain and the action   */
  1650. /*                stops.                                              */
  1651. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  1652. /*                stops.                                              */
  1653. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  1654. /*                checkpoint are undone and the action stops.         */
  1655. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  1656. /*                checkpoint are undone and the action stops.         */
  1657. /*   GS_YES       The default processing continues.                   */
  1658. /*                                                                    */
  1659. /* Description:                                                       */
  1660. /*    The function handles the event EV_START_ADD.                    */
  1661. /*    - Checks whether symbols are visible so that the new symbol can */
  1662. /*      be attached to one of them.                                   */
  1663. /**********************************************************************/
  1664.  
  1665. SHORT GSENTRY EvStartAdd(DHND dhnd,SHORT ev_id,EVS_START_ADD *pEvs)
  1666. {
  1667.   SHORT            action_num;         /* number of pending actions   */
  1668.  
  1669.   /*------------------------------------------------------------------*/
  1670.   /* If actions are pending, adding of symbols is not allowed.        */
  1671.   /*------------------------------------------------------------------*/
  1672.  
  1673.   GsGetAction(dhnd, NULL, &action_num);
  1674.   if (action_num > 1)
  1675.   {
  1676.     return  GS_RESTORE;
  1677.   }
  1678.  
  1679.   /*------------------------------------------------------------------*/
  1680.   /* If no symbol representing an employee in the company is visible, */
  1681.   /* adding of symbols is not allowed.                                */
  1682.   /*------------------------------------------------------------------*/
  1683.  
  1684.   if (VisibleEmployee(dhnd) == GS_NO)
  1685.   {
  1686.     return  GS_RESTORE;
  1687.   }
  1688.   return  GS_YES;
  1689. }
  1690.  
  1691. /**********************************************************************/
  1692. /* EvStartMove                                                        */
  1693. /*                                                                    */
  1694. /* Parameters:                                                        */
  1695. /*    DHND                     dhnd  (I): Diagram handle.             */
  1696. /*    SHORT                    ev_id (I): Identifies the event.       */
  1697. /*    EVS_START_MOVE           *pEvs (I): Pointer to instance of event*/
  1698. /*                                        data type.                  */
  1699. /*     SHND   shnd (I):            Handle of the symbol               */
  1700. /*     SHORT  bp_ref (I):          Reference number of the new bend   */
  1701. /*                                 This member is GS_INVALID_BP if the*/
  1702. /*                                 end user clicks on a node symbol   */
  1703. /*                                 instead of a bend point.           */
  1704. /*     POINTL mouse_pos (I):       Position of the mouse pointer      */
  1705. /*                                                                    */
  1706. /* Returns:                                                           */
  1707. /*   GS_NO        Any changes made to symbols remain and the action   */
  1708. /*                stops.                                              */
  1709. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  1710. /*                stops.                                              */
  1711. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  1712. /*                checkpoint are undone and the action stops.         */
  1713. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  1714. /*                checkpoint are undone and the action stops.         */
  1715. /*   GS_YES       The default processing continues.                   */
  1716. /*                                                                    */
  1717. /* Description:                                                       */
  1718. /*    The function handles the event EV_START_MOVE.                   */
  1719. /*    - Node symbols that are to maove and their children are marked  */
  1720. /*      for movement.                                                 */
  1721. /**********************************************************************/
  1722.  
  1723. SHORT GSENTRY EvStartMove(DHND dhnd,SHORT ev_id,EVS_START_MOVE *pEvs)
  1724. {
  1725.   SHND             employee_shnd;      /* handle of employee          */
  1726.  
  1727.   /*------------------------------------------------------------------*/
  1728.   /* Loop over all symbols representing employees that have their     */
  1729.   /* action flag set.                                                 */
  1730.   /*------------------------------------------------------------------*/
  1731.  
  1732.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  1733.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  1734.   {
  1735.  
  1736.     /*----------------------------------------------------------------*/
  1737.     /* Mark symbols for movement.                                     */
  1738.     /*----------------------------------------------------------------*/
  1739.  
  1740.     PutAllSubtreeSymAf(dhnd, employee_shnd, FALSE);
  1741.  
  1742.     /*----------------------------------------------------------------*/
  1743.     /* See whether every symbol representing a manager to which the   */
  1744.     /* employee is reporting has its action flag reset.               */
  1745.     /*----------------------------------------------------------------*/
  1746.  
  1747.     if (ManagerAfOff(dhnd, employee_shnd) == GS_YES)
  1748.     {                                  /* all action flags are reset  */
  1749.  
  1750.       /*--------------------------------------------------------------*/
  1751.       /* Remove the employee from its manager.                        */
  1752.       /*--------------------------------------------------------------*/
  1753.  
  1754.       RemoveEmployee(dhnd, employee_shnd);
  1755.  
  1756.       /*--------------------------------------------------------------*/
  1757.       /* Delete the link between the employee and its manager.        */
  1758.       /*--------------------------------------------------------------*/
  1759.  
  1760.       DeleteLink(dhnd, employee_shnd);
  1761.  
  1762.       /*--------------------------------------------------------------*/
  1763.       /* Remove the manager from the employee.                        */
  1764.       /*--------------------------------------------------------------*/
  1765.  
  1766.       RemoveManager(dhnd, employee_shnd);
  1767.     }
  1768.   }
  1769.   return  GS_YES;
  1770. }
  1771.  
  1772. /**********************************************************************/
  1773. /* ManagerAfOff                                                       */
  1774. /*                                                                    */
  1775. /* Parameters:                                                        */
  1776. /*   DHND             dhnd          (I): Diagram handle               */
  1777. /*   SHND             employee_shnd (I): handle of employee           */
  1778. /*                                                                    */
  1779. /* Returns:                                                           */
  1780. /*   GS_NO                                                            */
  1781. /*   GS_YES                                                           */
  1782. /*                                                                    */
  1783. /* Description:                                                       */
  1784. /*   The function checks whether the symbol representing the manager  */
  1785. /*   of a given employee has its action flag reset.                   */
  1786. /**********************************************************************/
  1787.  
  1788. SHORT ManagerAfOff(DHND dhnd,SHND employee_shnd)
  1789. {
  1790.   EMPLOYEE         employee;           /* employee object data        */
  1791.   SHORT            af;                 /* state of the action flag    */
  1792.  
  1793.   /*------------------------------------------------------------------*/
  1794.   /* Retrieve the employee data.                                      */
  1795.   /*------------------------------------------------------------------*/
  1796.  
  1797.   GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  1798.      (employee));
  1799.  
  1800.   /*------------------------------------------------------------------*/
  1801.   /* See whether the employee is reporting to a manager.              */
  1802.   /*------------------------------------------------------------------*/
  1803.  
  1804.   if (employee.manager_shnd != GS_INVALID_SHND)
  1805.   {                                    /* the employee reports to a
  1806.                                           manager                     */
  1807.  
  1808.     /*----------------------------------------------------------------*/
  1809.     /* See whether the symbol representing the manager to which the   */
  1810.     /* employee is reporting has its action flag set.                 */
  1811.     /*----------------------------------------------------------------*/
  1812.  
  1813.     GsGetSymAf(dhnd, employee.manager_shnd, &af);
  1814.     if (af == GS_ON)
  1815.     {
  1816.       return  GS_NO;
  1817.     }
  1818.   }
  1819.   return  GS_YES;
  1820. }
  1821.  
  1822. /**********************************************************************/
  1823. /* DeleteLink                                                         */
  1824. /*                                                                    */
  1825. /* Parameters:                                                        */
  1826. /*   DHND             dhnd          (I): Diagram handle               */
  1827. /*   SHND             employee_shnd (I): handle of employee           */
  1828. /*                                                                    */
  1829. /* Returns:                                                           */
  1830. /*   VOID                                                             */
  1831. /*                                                                    */
  1832. /* Description:                                                       */
  1833. /*   The function removes the link between an employee and its        */
  1834. /*   manager.                                                         */
  1835. /**********************************************************************/
  1836.  
  1837. static VOID DeleteLink(DHND dhnd,SHND employee_shnd)
  1838. {
  1839.   SHND             link_shnd;          /* handle of link symbol       */
  1840.  
  1841.   /*------------------------------------------------------------------*/
  1842.   /* Retrieve the handle of the link between employee and its manager.*/
  1843.   /*------------------------------------------------------------------*/
  1844.  
  1845.   GsGetFirstAttachedSym(dhnd, GS_TARGET_ATTACHED_LINK, employee_shnd,
  1846.      &link_shnd, NULL);
  1847.  
  1848.   /*------------------------------------------------------------------*/
  1849.   /* Delete the link.                                                 */
  1850.   /*------------------------------------------------------------------*/
  1851.  
  1852.   if (link_shnd != GS_INVALID_SHND)
  1853.   {
  1854.     GsDeleteSym(dhnd, link_shnd);
  1855.   }
  1856. }
  1857.  
  1858. /**********************************************************************/
  1859. /* RemoveManager                                                      */
  1860. /*                                                                    */
  1861. /* Parameters:                                                        */
  1862. /*   DHND             dhnd          (I): Diagram handle               */
  1863. /*   SHND             employee_shnd (I): handle of employee           */
  1864. /*                                                                    */
  1865. /* Returns:                                                           */
  1866. /*   VOID                                                             */
  1867. /*                                                                    */
  1868. /* Description:                                                       */
  1869. /*   The function removes the manager from an employee.               */
  1870. /**********************************************************************/
  1871.  
  1872. static VOID RemoveManager(DHND dhnd,SHND employee_shnd)
  1873. {
  1874.   EMPLOYEE         employee;           /* employee object data        */
  1875.  
  1876.   /*------------------------------------------------------------------*/
  1877.   /* Retrieve the employee object data.                               */
  1878.   /*------------------------------------------------------------------*/
  1879.  
  1880.   GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  1881.      (employee));
  1882.  
  1883.   /*------------------------------------------------------------------*/
  1884.   /* See whether the employee is reporting to a manager.              */
  1885.   /*------------------------------------------------------------------*/
  1886.  
  1887.   if (employee.manager_shnd != GS_INVALID_SHND)
  1888.   {                                    /* the employee reports to a
  1889.                                           manager                     */
  1890.  
  1891.     /*----------------------------------------------------------------*/
  1892.     /* Store the information that the manager is removed.             */
  1893.     /*----------------------------------------------------------------*/
  1894.  
  1895.     employee.manager_shnd = GS_INVALID_SHND;
  1896.  
  1897.     /*----------------------------------------------------------------*/
  1898.     /* Store the employee object data.                                */
  1899.     /*----------------------------------------------------------------*/
  1900.  
  1901.     GsPutSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  1902.        (employee));
  1903.   }
  1904. }
  1905.  
  1906. /**********************************************************************/
  1907. /* EvDragOver                                                         */
  1908. /*                                                                    */
  1909. /* Parameters:                                                        */
  1910. /*    DHND                     dhnd  (I): Diagram handle.             */
  1911. /*    SHORT                    ev_id (I): Identifies the event.       */
  1912. /*    EVS_DRAG_OVER            *pEvs (I): Pointer to instance of event*/
  1913. /*                                        data type.                  */
  1914. /*     DRAGINFO  *pDrag_info (I):  Pointer to data type describing    */
  1915. /*                                 the direct manipulation operation  */
  1916. /*     POINTL    mouse_pos (I):    Position of the mouse pointer      */
  1917. /*     DRAGIMAGE *pDrag_image (I): Pointer to an array of DRAGIMAGE   */
  1918. /*                                 data types                         */
  1919. /*                                 The array describes the image to   */
  1920. /*                                 be displayed for the dragged items.*/
  1921. /*                                 It is NULL if no GIK/2 objects are */
  1922. /*                                 being dragged.                     */
  1923. /*     SHORT     num (I/O):        Number of items dragged            */
  1924. /*     HPOINTER  hptr (I/O):       Handle of the mouse pointer        */
  1925. /*     MRESULT   mresult (I/O):    Return code for the message        */
  1926. /*                                                                    */
  1927. /* Returns:                                                           */
  1928. /*   GS_NO        Any changes made to symbols remain and the action   */
  1929. /*                stops.                                              */
  1930. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  1931. /*                stops.                                              */
  1932. /*   GS_REJECT    The attempt to end the action is rejected and the   */
  1933. /*                graphics editor retries the action processing.      */
  1934. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  1935. /*                checkpoint are undone and the action stops.         */
  1936. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  1937. /*                checkpoint are undone and the action stops.         */
  1938. /*   GS_YES       The default processing continues.                   */
  1939. /*                                                                    */
  1940. /* Description:                                                       */
  1941. /*    The function handles the event EV_DRAG_OVER.                    */
  1942. /*    - Checks whether all items being dragged are symbols.           */
  1943. /*    - Checks whether symbols exists to which the dragged symbols    */
  1944. /*      are allowed to be attached.                                   */
  1945. /**********************************************************************/
  1946.  
  1947. SHORT GSENTRY EvDragOver(DHND dhnd,SHORT ev_id,EVS_DRAG_OVER *pEvs)
  1948. {
  1949.   SHORT            action_num;         /* number of pending actions   */
  1950.   SHORT            action_max_num;     /* maximum number of pending
  1951.                                           actions that is allowed     */
  1952.   SHND             employee_shnd;      /* handle of employee          */
  1953.   RECTL            area;               /* hit area                    */
  1954.   DRAGITEM         *pDrag_item;        /* pointer to data of a dragged
  1955.                                           object                      */
  1956.   SHORT            rc;                 /* return code                 */
  1957.   HWND             hwnd;               /* window handle               */
  1958.   BOOL             is_source;          /* indicates whether the window
  1959.                                           being dragged over is the
  1960.                                           source window of the direct
  1961.                                           manipulation operation      */
  1962.  
  1963.   /*------------------------------------------------------------------*/
  1964.   /* See whether the window being dragged over is the source window of*/
  1965.   /* the of the direct manipulation operation.                        */
  1966.   /*------------------------------------------------------------------*/
  1967.  
  1968.   GsGetHwnd(dhnd, GS_WIN_MAIN, 0, FID_CLIENT, &hwnd);
  1969.   is_source = (hwnd == pEvs->pDrag_info->hwndSource);
  1970.  
  1971.   /*------------------------------------------------------------------*/
  1972.   /* If actions are pending, symbols cannot be dropped.               */
  1973.   /*------------------------------------------------------------------*/
  1974.  
  1975.   GsGetAction(dhnd, NULL, &action_num);
  1976.   if (is_source)
  1977.   {
  1978.     action_max_num = 2;
  1979.   }
  1980.   else
  1981.   {
  1982.     action_max_num = 1;
  1983.   }
  1984.   if (action_num > action_max_num)
  1985.   {
  1986.     pEvs->mresult = MRFROMSHORT(DOR_NEVERDROP);
  1987.     return  GS_YES;
  1988.   }
  1989.  
  1990.   /*------------------------------------------------------------------*/
  1991.   /* If items being dragged are not symbols, a drop is not allowed.   */
  1992.   /*------------------------------------------------------------------*/
  1993.  
  1994.   if (SymDragged(dhnd, pEvs->pDrag_info) == GS_NO)
  1995.   {
  1996.     pEvs->mresult = MRFROMSHORT(DOR_NEVERDROP);
  1997.     return  GS_YES;
  1998.   }
  1999.  
  2000.   /*------------------------------------------------------------------*/
  2001.   /* If all visible symbols representing employees are being dragged, */
  2002.   /* adding of symbols is not allowed.                                */
  2003.   /*------------------------------------------------------------------*/
  2004.  
  2005.   rc = AllVisibleEmployeesDragged(dhnd, pEvs->pDrag_info);
  2006.   switch (rc)
  2007.   {
  2008.     case  GS_YES :                     /* all visible symbol are being
  2009.                                           dragged                     */
  2010.       pEvs->mresult = MRFROMSHORT(DOR_NEVERDROP);
  2011.       break;
  2012.     case  GS_REJECT :                  /* no symbol exists            */
  2013.       if (is_source)
  2014.       {
  2015.         pEvs->mresult = MRFROMSHORT(DOR_NEVERDROP);
  2016.       }
  2017.       break;
  2018.     default  :                         /* some visible symbols are not
  2019.                                           being dragged               */
  2020.  
  2021.       /*--------------------------------------------------------------*/
  2022.       /* Determine the area to be used for a hit detection.           */
  2023.       /*--------------------------------------------------------------*/
  2024.  
  2025.       area.xLeft = pEvs->mouse_pos.x-GS_HALF_HIT_WIDTH;
  2026.       area.yBottom = pEvs->mouse_pos.y-GS_HALF_HIT_HEIGHT;
  2027.       area.xRight = pEvs->mouse_pos.x+GS_HALF_HIT_WIDTH;
  2028.       area.yTop = pEvs->mouse_pos.y+GS_HALF_HIT_HEIGHT;
  2029.  
  2030.       /*--------------------------------------------------------------*/
  2031.       /* See whether the mouse pointer is on a symbol representing an */
  2032.       /* employee.                                                    */
  2033.       /*--------------------------------------------------------------*/
  2034.  
  2035.       if (GsGetFirstHitSym(dhnd, GS_NODE, GS_UPPER_FIRST, &area,
  2036.          &employee_shnd, NULL, NULL, NULL) != GS_OK)
  2037.       {                                /* the pointer is not on a
  2038.                                           symbol                      */
  2039.         pEvs->mresult = MRFROMSHORT(DOR_NODROP);
  2040.       }
  2041.       else
  2042.       {                                /* the pointer is on a symbol  */
  2043.  
  2044.         /*------------------------------------------------------------*/
  2045.         /* See whether the mouse pointer is on a symbol representing  */
  2046.         /* an employee currently being dragged.                       */
  2047.         /*------------------------------------------------------------*/
  2048.  
  2049.         GsGetDragItem(dhnd, employee_shnd, &pDrag_item);
  2050.         if (pDrag_item)
  2051.         {                              /* the symbol the mouse pointer
  2052.                                           is on is being dragged      */
  2053.           pEvs->mresult = MRFROMSHORT(DOR_NODROP);
  2054.         }
  2055.       }
  2056.       break;
  2057.   }
  2058.   return  GS_YES;
  2059. }
  2060.  
  2061. /**********************************************************************/
  2062. /* SymDragged                                                         */
  2063. /*                                                                    */
  2064. /* Parameters:                                                        */
  2065. /*   DHND             dhnd        (I): Diagram handle                 */
  2066. /*   DRAGINFO         *pDrag_info (I): Drag info                      */
  2067. /*                                                                    */
  2068. /* Returns:                                                           */
  2069. /*   GS_NO                                                            */
  2070. /*   GS_YES                                                           */
  2071. /*                                                                    */
  2072. /* Description:                                                       */
  2073. /*   The function checks whether all items being dragged are symbols. */
  2074. /**********************************************************************/
  2075.  
  2076. SHORT SymDragged(DHND dhnd,DRAGINFO *pDrag_info)
  2077. {
  2078.   SHORT            num;                /* number items being dragged  */
  2079.   SHORT            sym_id;             /* symbol index                */
  2080.   DRAGITEM         *pDrag_item;        /* pointer to data of a dragged
  2081.                                           object                      */
  2082.  
  2083.   /*------------------------------------------------------------------*/
  2084.   /* Retrieve the number of items being dragged.                      */
  2085.   /*------------------------------------------------------------------*/
  2086.  
  2087.   num = DrgQueryDragitemCount(pDrag_info);
  2088.  
  2089.   /*------------------------------------------------------------------*/
  2090.   /* Loop over all items being dragged.                               */
  2091.   /*------------------------------------------------------------------*/
  2092.  
  2093.   for (sym_id = 0; sym_id < num; sym_id++)
  2094.   {
  2095.  
  2096.     /*----------------------------------------------------------------*/
  2097.     /* Get the item info.                                             */
  2098.     /*----------------------------------------------------------------*/
  2099.  
  2100.     pDrag_item = DrgQueryDragitemPtr(pDrag_info, (ULONG)sym_id);
  2101.  
  2102.     /*----------------------------------------------------------------*/
  2103.     /* See whether the item is a symbol.                              */
  2104.     /*----------------------------------------------------------------*/
  2105.  
  2106.     if (!DrgVerifyType(pDrag_item, GS_DRT_SYM))
  2107.     {                                  /* it is not a symbol          */
  2108.       return  GS_NO;
  2109.     }
  2110.   }
  2111.   return  GS_YES;
  2112. }
  2113.  
  2114. /**********************************************************************/
  2115. /* AllVisibleEmployeesDragged                                         */
  2116. /*                                                                    */
  2117. /* Parameters:                                                        */
  2118. /*   DHND             dhnd        (I): Diagram handle                 */
  2119. /*   DRAGINFO         *pDrag_info (I): Drag info                      */
  2120. /*                                                                    */
  2121. /* Returns:                                                           */
  2122. /*   GS_NO                                                            */
  2123. /*   GS_REJECT                                                        */
  2124. /*   GS_YES                                                           */
  2125. /*                                                                    */
  2126. /* Description:                                                       */
  2127. /*   The function checks whether all visible employees are dragged.   */
  2128. /**********************************************************************/
  2129.  
  2130. SHORT AllVisibleEmployeesDragged(DHND dhnd,DRAGINFO *pDrag_info)
  2131. {
  2132.   SHND             gen_manager_shnd;   /* handle of general manager   */
  2133.   SHND             employee_shnd;      /* handle of employee          */
  2134.   LONG             long_value;         /* long value of the diagram   */
  2135.   SHORT            shown;              /* visibility of a symbol      */
  2136.   DRAGITEM         *pDrag_item;        /* pointer to data of a dragged
  2137.                                           object                      */
  2138.  
  2139.   /*------------------------------------------------------------------*/
  2140.   /* Retrieve the handle of the symbol representing the general       */
  2141.   /* manager.                                                         */
  2142.   /*------------------------------------------------------------------*/
  2143.  
  2144.   GsGetDiagLong(dhnd, &long_value);
  2145.   gen_manager_shnd = LOUSHORT(long_value);
  2146.  
  2147.   /*------------------------------------------------------------------*/
  2148.   /* See whether a general manager exists.                            */
  2149.   /*------------------------------------------------------------------*/
  2150.  
  2151.   if (gen_manager_shnd == GS_INVALID_SHND)
  2152.   {
  2153.     return  GS_REJECT;
  2154.   }
  2155.  
  2156.   /*------------------------------------------------------------------*/
  2157.   /* Loop over all symbols representing employees.                    */
  2158.   /*------------------------------------------------------------------*/
  2159.  
  2160.   GsCollectSym(dhnd, GS_NODE, GS_ANY_SYM, GS_UPPER_FIRST);
  2161.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  2162.   {
  2163.  
  2164.     /*----------------------------------------------------------------*/
  2165.     /* See whether the symbol is visible.                             */
  2166.     /*----------------------------------------------------------------*/
  2167.  
  2168.     GsGetSymVisibility(dhnd, employee_shnd, &shown);
  2169.     if (shown == GS_ON)
  2170.     {                                  /* the symbol is visible       */
  2171.  
  2172.       /*--------------------------------------------------------------*/
  2173.       /* See whether the symbol represents an employee currently being*/
  2174.       /* dragged.                                                     */
  2175.       /*--------------------------------------------------------------*/
  2176.  
  2177.       GsGetDragItem(dhnd, employee_shnd, &pDrag_item);
  2178.       if (!pDrag_item)
  2179.       {                                /* the symbol is not being
  2180.                                           dragged                     */
  2181.         GsEndSymCollection(dhnd);
  2182.         return  GS_NO;
  2183.       }
  2184.     }
  2185.   }
  2186.   return  GS_YES;
  2187. }
  2188.  
  2189. /**********************************************************************/
  2190. /* EvDrop                                                             */
  2191. /*                                                                    */
  2192. /* Parameters:                                                        */
  2193. /*    DHND                     dhnd  (I): Diagram handle.             */
  2194. /*    SHORT                    ev_id (I): Identifies the event.       */
  2195. /*    EVS_DROP                 *pEvs (I): Pointer to instance of event*/
  2196. /*                                        data type.                  */
  2197. /*     DRAGINFO  *pDrag_info (I):  Pointer to data type describing    */
  2198. /*                                 the direct manipulation operation  */
  2199. /*     POINTL mouse_pos (I):       Position of the mouse pointer      */
  2200. /*                                                                    */
  2201. /* Returns:                                                           */
  2202. /*   GS_NO        Any changes made to symbols remain and the action   */
  2203. /*                stops.                                              */
  2204. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  2205. /*                stops.                                              */
  2206. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  2207. /*                checkpoint are undone and the action stops.         */
  2208. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  2209. /*                checkpoint are undone and the action stops.         */
  2210. /*   GS_YES       The default processing continues.                   */
  2211. /*                                                                    */
  2212. /* Description:                                                       */
  2213. /*    The function handles the event EV_DROP.                         */
  2214. /*    - The employee-manager relationship for the employees being     */
  2215. /*      dropped is determined.                                        */
  2216. /**********************************************************************/
  2217.  
  2218. SHORT GSENTRY EvDrop(DHND dhnd,SHORT ev_id,EVS_DROP *pEvs)
  2219. {
  2220.   SHND             employee_shnd;      /* handle of employee          */
  2221.   SHND             shnd;               /* symbol handle               */
  2222.   SHORT            rc;                 /* return code                 */
  2223.   HWND             hwnd;               /* window handle               */
  2224.  
  2225.   /*------------------------------------------------------------------*/
  2226.   /* Update the object data of all dropped symbols representing       */
  2227.   /* employees.                                                       */
  2228.   /*------------------------------------------------------------------*/
  2229.  
  2230.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  2231.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  2232.   {
  2233.     UpdateEmployeeData(dhnd, pEvs->pDrag_info, employee_shnd);
  2234.   }
  2235.  
  2236.   /*------------------------------------------------------------------*/
  2237.   /* If the company has no general manager and only one employee has  */
  2238.   /* been dropped that does not report to a manager, it becomes       */
  2239.   /* general manager.                                                 */
  2240.   /*------------------------------------------------------------------*/
  2241.  
  2242.   rc = DropEmployeeForGenManager(dhnd);
  2243.   switch (rc)
  2244.   {
  2245.     case  GS_NO :
  2246.       return  GS_RESTORE;
  2247.  
  2248.     case  GS_REJECT :
  2249.  
  2250.       /*--------------------------------------------------------------*/
  2251.       /* Adds the dropped employee the mouse pointer is on to the     */
  2252.       /* manager the mouse pointer is on.                             */
  2253.       /*--------------------------------------------------------------*/
  2254.  
  2255.       if (AttachDrop1EmployeeToManager(dhnd, pEvs->mouse_pos) != GS_YES)
  2256.       {
  2257.         return  GS_RESTORE;
  2258.       }
  2259.  
  2260.       /*--------------------------------------------------------------*/
  2261.       /* Adds all dropped employees that do not report to a manager to*/
  2262.       /* a manager.                                                   */
  2263.       /*--------------------------------------------------------------*/
  2264.  
  2265.       if (AttachDropNEmployeeToManager(dhnd) != GS_YES)
  2266.       {
  2267.         return  GS_RESTORE;
  2268.       }
  2269.       break;
  2270.   }
  2271.  
  2272.   /*------------------------------------------------------------------*/
  2273.   /* Do not allow performing a layout algorithm if the target window  */
  2274.   /* of the direct manipulation operation is the same as the source   */
  2275.   /* window.                                                          */
  2276.   /*------------------------------------------------------------------*/
  2277.  
  2278.   GsGetHwnd(dhnd, GS_WIN_MAIN, 0, FID_CLIENT, &hwnd);
  2279.   if (hwnd == pEvs->pDrag_info->hwndSource)
  2280.   {
  2281.  
  2282.     /*----------------------------------------------------------------*/
  2283.     /* The function marks all links between employees and their       */
  2284.     /* manager.                                                       */
  2285.     /*----------------------------------------------------------------*/
  2286.  
  2287.     PutAllLinkToPreManagerAf(dhnd);
  2288.  
  2289.     /*----------------------------------------------------------------*/
  2290.     /* Set the visibility state of all new symbols.                   */
  2291.     /*----------------------------------------------------------------*/
  2292.  
  2293.     GsCollectSym(dhnd, GS_ANY_CLASS, GS_SYM_AF, GS_UPPER_FIRST);
  2294.     while (GsGetCollectedSym(dhnd, &shnd) == GS_OK)
  2295.     {
  2296.       GsPutSymVisibility(dhnd, shnd, GS_OFF);
  2297.       GsPutSymFlag(dhnd, shnd, SF_INVISIBLE, SF_INVISIBLE);
  2298.     }
  2299.   }
  2300.   return  GS_YES;
  2301. }
  2302.  
  2303. /**********************************************************************/
  2304. /* UpdateEmployeeData                                                 */
  2305. /*                                                                    */
  2306. /* Parameters:                                                        */
  2307. /*   DHND             dhnd          (I): Diagram handle               */
  2308. /*   DRAGINFO         *pDrag_info   (I): Drag info                    */
  2309. /*   SHND             employee_shnd (I): handle of employee           */
  2310. /*                                                                    */
  2311. /* Returns:                                                           */
  2312. /*   VOID                                                             */
  2313. /*                                                                    */
  2314. /* Description:                                                       */
  2315. /*   The function updates the object data of an employee.             */
  2316. /**********************************************************************/
  2317.  
  2318. static VOID UpdateEmployeeData(DHND dhnd,DRAGINFO *pDrag_info,SHND
  2319.                                 employee_shnd)
  2320. {
  2321.   EMPLOYEE         employee;           /* employee object data        */
  2322.   SHORT            cnt;                /* symbol count                */
  2323.  
  2324.   /*------------------------------------------------------------------*/
  2325.   /* Retrieve the employee data.                                      */
  2326.   /*------------------------------------------------------------------*/
  2327.  
  2328.   GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  2329.      (employee));
  2330.  
  2331.   /*------------------------------------------------------------------*/
  2332.   /* Update the handle of the symbol representing the manager.        */
  2333.   /*------------------------------------------------------------------*/
  2334.  
  2335.   if (employee.manager_shnd != GS_INVALID_SHND)
  2336.   {                                    /* the employee reports to a
  2337.                                           manager                     */
  2338.     GetTargetNode(dhnd, pDrag_info, employee.manager_shnd,
  2339.        &employee.manager_shnd);
  2340.   }
  2341.   employee.pre_manager_shnd = employee.manager_shnd;
  2342.  
  2343.   /*------------------------------------------------------------------*/
  2344.   /* Update the handles of all symbols representing employees         */
  2345.   /* reporting to the current employee.                               */
  2346.   /*------------------------------------------------------------------*/
  2347.  
  2348.   for (cnt = 0; cnt < employee.employee_num; cnt++)
  2349.   {
  2350.     GetTargetNode(dhnd, pDrag_info, employee.employee_shnd[cnt],
  2351.        &employee.employee_shnd[cnt]);
  2352.   }
  2353.  
  2354.   /*------------------------------------------------------------------*/
  2355.   /* Store the employee object data.                                  */
  2356.   /*------------------------------------------------------------------*/
  2357.  
  2358.   GsPutSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  2359.      (employee));
  2360. }
  2361.  
  2362. /**********************************************************************/
  2363. /* GetTargetNode                                                      */
  2364. /*                                                                    */
  2365. /* Parameters:                                                        */
  2366. /*   DHND             dhnd          (I): Diagram handle               */
  2367. /*   DRAGINFO         *pDrag_info   (I): Drag info                    */
  2368. /*   SHND             source_shnd   (I): source symbol handle         */
  2369. /*   SHND             *pTarget_shnd (I): target symbol handle         */
  2370. /*                                                                    */
  2371. /* Returns:                                                           */
  2372. /*   VOID                                                             */
  2373. /*                                                                    */
  2374. /* Description:                                                       */
  2375. /*   The function retrieves the symbol handle in the target window    */
  2376. /*   of a node symbol having been dropped.                            */
  2377. /**********************************************************************/
  2378.  
  2379. static VOID GetTargetNode(DHND dhnd,DRAGINFO *pDrag_info,SHND
  2380.                            source_shnd,SHND *pTarget_shnd)
  2381. {
  2382.   SHORT            num;                /* number items being dragged  */
  2383.   SHORT            sym_id;             /* symbol index                */
  2384.   DRAGITEM         *pDrag_sym;         /* pointer to data of the
  2385.                                           dropped symbol              */
  2386.   DRAGITEM         *pDrag_item;        /* pointer to data of a dragged
  2387.                                           object                      */
  2388.   SHND             shnd;               /* symbol handle               */
  2389.  
  2390.   /*------------------------------------------------------------------*/
  2391.   /* Initial value for the handle.                                    */
  2392.   /*------------------------------------------------------------------*/
  2393.  
  2394.   *pTarget_shnd = GS_INVALID_SHND;
  2395.  
  2396.   /*------------------------------------------------------------------*/
  2397.   /* Retrieve the number of items having been dragged.                */
  2398.   /*------------------------------------------------------------------*/
  2399.  
  2400.   num = DrgQueryDragitemCount(pDrag_info);
  2401.  
  2402.   /*------------------------------------------------------------------*/
  2403.   /* Loop over all items having been dragged.                         */
  2404.   /*------------------------------------------------------------------*/
  2405.  
  2406.   pDrag_sym = NULL;
  2407.   for (sym_id = 0; sym_id < num; sym_id++)
  2408.   {
  2409.  
  2410.     /*----------------------------------------------------------------*/
  2411.     /* Get the item info.                                             */
  2412.     /*----------------------------------------------------------------*/
  2413.  
  2414.     pDrag_item = DrgQueryDragitemPtr(pDrag_info, (ULONG)sym_id);
  2415.  
  2416.     /*----------------------------------------------------------------*/
  2417.     /* See whether the item is a symbol.                              */
  2418.     /*----------------------------------------------------------------*/
  2419.  
  2420.     if (DrgVerifyType(pDrag_item, GS_DRT_SYM))
  2421.     {                                  /* it is a symbol              */
  2422.  
  2423.       /*--------------------------------------------------------------*/
  2424.       /* Check the symbol handle.                                     */
  2425.       /*--------------------------------------------------------------*/
  2426.  
  2427.       if ((SHND)(LOUSHORT(pDrag_item->ulItemID)) == source_shnd)
  2428.       {
  2429.         pDrag_sym = pDrag_item;
  2430.         break;
  2431.       }
  2432.     }
  2433.   }
  2434.  
  2435.   /*------------------------------------------------------------------*/
  2436.   /* See whether the symbol has been dragged.                         */
  2437.   /*------------------------------------------------------------------*/
  2438.  
  2439.   if (pDrag_sym)
  2440.   {                                    /* the symbol has been dragged */
  2441.  
  2442.     /*----------------------------------------------------------------*/
  2443.     /* Loop over all dropped node symbols.                            */
  2444.     /*----------------------------------------------------------------*/
  2445.  
  2446.     GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  2447.     while (GsGetCollectedSym(dhnd, &shnd) == GS_OK)
  2448.     {
  2449.  
  2450.       /*--------------------------------------------------------------*/
  2451.       /* Compare the pointers to the data used for dragged items.     */
  2452.       /*--------------------------------------------------------------*/
  2453.  
  2454.       GsGetDragItem(dhnd, shnd, &pDrag_item);
  2455.       if (pDrag_item == pDrag_sym)
  2456.       {                                /* symbol is found             */
  2457.         *pTarget_shnd = shnd;
  2458.         GsEndSymCollection(dhnd);
  2459.         break;
  2460.       }
  2461.     }
  2462.   }
  2463. }
  2464.  
  2465. /**********************************************************************/
  2466. /* DropEmployeeForGenManager                                          */
  2467. /*                                                                    */
  2468. /* Parameters:                                                        */
  2469. /*   DHND             dhnd          (I): Diagram handle               */
  2470. /*                                                                    */
  2471. /* Returns:                                                           */
  2472. /*   GS_NO                                                            */
  2473. /*   GS_REJECT                                                        */
  2474. /*   GS_YES                                                           */
  2475. /*                                                                    */
  2476. /* Description:                                                       */
  2477. /*   The function checks whether the dropped employees are the first  */
  2478. /*   having been added to the company. One of them becomes general    */
  2479. /*   manager.                                                         */
  2480. /**********************************************************************/
  2481.  
  2482. SHORT DropEmployeeForGenManager(DHND dhnd)
  2483. {
  2484.   SHND             gen_manager_shnd;   /* handle of general manager   */
  2485.   SHND             employee_shnd;      /* handle of employee          */
  2486.   EMPLOYEE         employee;           /* employee object data        */
  2487.   LONG             long_value;         /* long value of the diagram   */
  2488.   SHORT            employee_num;       /* number of employees not
  2489.                                           reporting to a manager      */
  2490.  
  2491.   /*------------------------------------------------------------------*/
  2492.   /* Retrieve the handle of the symbol representing the general       */
  2493.   /* manager.                                                         */
  2494.   /*------------------------------------------------------------------*/
  2495.  
  2496.   GsGetDiagLong(dhnd, &long_value);
  2497.   gen_manager_shnd = LOUSHORT(long_value);
  2498.  
  2499.   /*------------------------------------------------------------------*/
  2500.   /* See whether a general manager exists.                            */
  2501.   /*------------------------------------------------------------------*/
  2502.  
  2503.   if (gen_manager_shnd != GS_INVALID_SHND)
  2504.   {                                    /* a general manager exists    */
  2505.     return  GS_REJECT;
  2506.   }
  2507.   else
  2508.   {                                    /* no general manager exists   */
  2509.  
  2510.     /*----------------------------------------------------------------*/
  2511.     /* Loop over all dropped symbols representing employees.          */
  2512.     /*----------------------------------------------------------------*/
  2513.  
  2514.     employee_num = 0;
  2515.     GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  2516.     while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  2517.     {
  2518.  
  2519.       /*--------------------------------------------------------------*/
  2520.       /* Retrieve the employee object data.                           */
  2521.       /*--------------------------------------------------------------*/
  2522.  
  2523.       GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  2524.          (employee));
  2525.  
  2526.       /*--------------------------------------------------------------*/
  2527.       /* Retrieve the handle of the symbol representing the first     */
  2528.       /* employee that does not report to a manager.                  */
  2529.       /*--------------------------------------------------------------*/
  2530.  
  2531.       if (employee.manager_shnd == GS_INVALID_SHND)
  2532.       {
  2533.         employee_num++;
  2534.         if (gen_manager_shnd == GS_INVALID_SHND)
  2535.         {
  2536.           gen_manager_shnd = employee_shnd;
  2537.         }
  2538.       }
  2539.     }
  2540.  
  2541.     /*----------------------------------------------------------------*/
  2542.     /* If there is only one employee that does not report to a        */
  2543.     /* manager, it is stored as general manager.                      */
  2544.     /*----------------------------------------------------------------*/
  2545.  
  2546.     if (employee_num == 1)
  2547.     {
  2548.       GsPutDiagLong(dhnd, (LONG)gen_manager_shnd);
  2549.       return  GS_YES;
  2550.     }
  2551.   }
  2552.   return  GS_NO;
  2553. }
  2554.  
  2555. /**********************************************************************/
  2556. /* AttachDrop1EmployeeToManager                                       */
  2557. /*                                                                    */
  2558. /* Parameters:                                                        */
  2559. /*   DHND             dhnd      (I): Diagram handle                   */
  2560. /*   POINTL           mouse_pos (I): Position of the mouse pointer    */
  2561. /*                                                                    */
  2562. /* Returns:                                                           */
  2563. /*   GS_NO            the attachment is not done                      */
  2564. /*   GS_YES           the attachment is done                          */
  2565. /*                                                                    */
  2566. /* Description:                                                       */
  2567. /*   The function adds the dropped employee the mouse pointer is on   */
  2568. /*   to a manager the mouse pointer is on.                            */
  2569. /**********************************************************************/
  2570.  
  2571. SHORT AttachDrop1EmployeeToManager(DHND dhnd,POINTL mouse_pos)
  2572. {
  2573.   SHND             employee_shnd;      /* handle of employee          */
  2574.   SHND             manager_shnd;       /* handle of manager           */
  2575.   SHND             shnd;               /* symbol handle               */
  2576.   RECTL            area;               /* hit area                    */
  2577.   SHORT            af;                 /* state of the action flag    */
  2578.  
  2579.   /*------------------------------------------------------------------*/
  2580.   /* Determine the area to be used for a hit detection.               */
  2581.   /*------------------------------------------------------------------*/
  2582.  
  2583.   area.xLeft = mouse_pos.x-GS_HALF_HIT_WIDTH;
  2584.   area.yBottom = mouse_pos.y-GS_HALF_HIT_HEIGHT;
  2585.   area.xRight = mouse_pos.x+GS_HALF_HIT_WIDTH;
  2586.   area.yTop = mouse_pos.y+GS_HALF_HIT_HEIGHT;
  2587.  
  2588.   /*------------------------------------------------------------------*/
  2589.   /* Retrieve the handles of the two symbols the mouse pointer is on. */
  2590.   /*------------------------------------------------------------------*/
  2591.  
  2592.   employee_shnd = GS_INVALID_SHND;
  2593.   manager_shnd = GS_INVALID_SHND;
  2594.   GsCollectHitSym(dhnd, GS_NODE, GS_UPPER_FIRST, &area);
  2595.   while (GsGetCollectedHitSym(dhnd, &shnd, NULL, NULL, NULL) == GS_OK)
  2596.   {
  2597.  
  2598.     /*----------------------------------------------------------------*/
  2599.     /* See whether it is a symbol having been dropped.                */
  2600.     /*----------------------------------------------------------------*/
  2601.  
  2602.     GsGetSymAf(dhnd, shnd, &af);
  2603.     if (af == GS_ON)
  2604.     {                                  /* the symbol has been dropped */
  2605.       employee_shnd = shnd;
  2606.     }
  2607.     else
  2608.     {                                  /* the symbol has not been
  2609.                                           dropped                     */
  2610.       manager_shnd = shnd;
  2611.     }
  2612.  
  2613.     /*----------------------------------------------------------------*/
  2614.     /* See whether the handles of the two symbols the mouse pointer is*/
  2615.     /* on have been retrieved.                                        */
  2616.     /*----------------------------------------------------------------*/
  2617.  
  2618.     if ((employee_shnd != GS_INVALID_SHND) && /*                      */
  2619.        (manager_shnd != GS_INVALID_SHND))
  2620.     {
  2621.       GsEndHitSymCollection(dhnd);
  2622.       break;
  2623.     }
  2624.   }
  2625.  
  2626.   /*------------------------------------------------------------------*/
  2627.   /* Define the employee-manager relationship.                        */
  2628.   /*------------------------------------------------------------------*/
  2629.  
  2630.   return  AttachEmployeeToManager(dhnd, employee_shnd, manager_shnd);
  2631. }
  2632.  
  2633. /**********************************************************************/
  2634. /* AttachDropNEmployeeToManager                                       */
  2635. /*                                                                    */
  2636. /* Parameters:                                                        */
  2637. /*   DHND             dhnd      (I): Diagram handle                   */
  2638. /*                                                                    */
  2639. /* Returns:                                                           */
  2640. /*   GS_NO            the attachment is not done                      */
  2641. /*   GS_REJECT        the attachment is not done                      */
  2642. /*   GS_YES           the attachment is done                          */
  2643. /*                                                                    */
  2644. /* Description:                                                       */
  2645. /*   The function adds all dropped employee that do not report to     */
  2646. /*   a manager to a manager.                                          */
  2647. /**********************************************************************/
  2648.  
  2649. SHORT AttachDropNEmployeeToManager(DHND dhnd)
  2650. {
  2651.   SHND             employee_shnd;      /* handle of employee          */
  2652.   EMPLOYEE         employee;           /* employee object data        */
  2653.   SHORT            rc;                 /* return code                 */
  2654.  
  2655.   /*------------------------------------------------------------------*/
  2656.   /* Loop over all dropped symbols representing employees.            */
  2657.   /*------------------------------------------------------------------*/
  2658.  
  2659.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  2660.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  2661.   {
  2662.  
  2663.     /*----------------------------------------------------------------*/
  2664.     /* Retrieve the employee object data.                             */
  2665.     /*----------------------------------------------------------------*/
  2666.  
  2667.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  2668.        (employee));
  2669.  
  2670.     /*----------------------------------------------------------------*/
  2671.     /* See whether the employee reports to a manager.                 */
  2672.     /*----------------------------------------------------------------*/
  2673.  
  2674.     if (employee.manager_shnd == GS_INVALID_SHND)
  2675.     {                                  /* it does not report to a
  2676.                                           manager                     */
  2677.       if ((rc = AttachMoveEmployeeToManager(dhnd, employee_shnd)) !=
  2678.          GS_YES)
  2679.       {
  2680.         GsEndSymCollection(dhnd);
  2681.         return (rc);
  2682.       }
  2683.     }
  2684.   }
  2685.   return  GS_YES;
  2686. }
  2687.  
  2688. /**********************************************************************/
  2689. /* EvEndDrag                                                          */
  2690. /*                                                                    */
  2691. /* Parameters:                                                        */
  2692. /*    DHND                     dhnd  (I): Diagram handle.             */
  2693. /*    SHORT                    ev_id (I): Identifies the event.       */
  2694. /*    EVS_END_DRAG             *pEvs (I): Pointer to instance of event*/
  2695. /*                                        data type.                  */
  2696. /*     DRAGINFO  *pDrag_info (I):  Pointer to data type describing    */
  2697. /*                                 the direct manipulation operation  */
  2698. /*     HWND      hwnd_target (I):  Handle of the target window        */
  2699. /*                                                                    */
  2700. /* Returns:                                                           */
  2701. /*   GS_NO        Any changes made to symbols remain and the action   */
  2702. /*                stops.                                              */
  2703. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  2704. /*                stops.                                              */
  2705. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  2706. /*                checkpoint are undone and the action stops.         */
  2707. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  2708. /*                checkpoint are undone and the action stops.         */
  2709. /*   GS_YES       The default processing continues.                   */
  2710. /*                                                                    */
  2711. /* Description:                                                       */
  2712. /*    The function handles the event EV_END_DRAG.                     */
  2713. /**********************************************************************/
  2714.  
  2715. SHORT GSENTRY EvEndDrag(DHND dhnd,SHORT ev_id,EVS_END_DRAG *pEvs)
  2716. {
  2717.   SHND             shnd;               /* symbol handle               */
  2718.   ULONG            sym_flags;          /* symbol flags                */
  2719.   HWND             hwnd;               /* window handle               */
  2720.  
  2721.   /*------------------------------------------------------------------*/
  2722.   /* The function marks all links between employees and their previous*/
  2723.   /* manager.                                                         */
  2724.   /*------------------------------------------------------------------*/
  2725.  
  2726.   PutAllLinkToPreManagerAf(dhnd);
  2727.  
  2728.   /*------------------------------------------------------------------*/
  2729.   /* Set the visibility state of all new symbols if the target window */
  2730.   /* of the direct manipulation operation is the same as the source   */
  2731.   /* window.                                                          */
  2732.   /*------------------------------------------------------------------*/
  2733.  
  2734.   GsGetHwnd(dhnd, GS_WIN_MAIN, 0, FID_CLIENT, &hwnd);
  2735.   if (hwnd == pEvs->hwnd_target)
  2736.   {
  2737.  
  2738.     /*----------------------------------------------------------------*/
  2739.     /* Loop over all symbols.                                         */
  2740.     /*----------------------------------------------------------------*/
  2741.  
  2742.     GsCollectSym(dhnd, GS_ANY_CLASS, GS_ANY_SYM, GS_UPPER_FIRST);
  2743.     while (GsGetCollectedSym(dhnd, &shnd) == GS_OK)
  2744.     {
  2745.  
  2746.       /*--------------------------------------------------------------*/
  2747.       /* See whether the symbol is new.                               */
  2748.       /*--------------------------------------------------------------*/
  2749.  
  2750.       GsGetSymFlag(dhnd, shnd, &sym_flags);
  2751.       if (sym_flags&SF_INVISIBLE)
  2752.       {
  2753.         GsPutSymVisibility(dhnd, shnd, GS_ON);
  2754.         GsPutSymFlag(dhnd, shnd, ~SF_INVISIBLE, SF_INVISIBLE);
  2755.       }
  2756.     }
  2757.   }
  2758.   return  GS_YES;
  2759. }
  2760.  
  2761. /**********************************************************************/
  2762. /* PutAllLinkToPreManagerAf                                           */
  2763. /*                                                                    */
  2764. /* Parameters:                                                        */
  2765. /*   DHND             dhnd          (I): Diagram handle               */
  2766. /*                                                                    */
  2767. /* Returns:                                                           */
  2768. /*   VOID                                                             */
  2769. /*                                                                    */
  2770. /* Description:                                                       */
  2771. /*   The function sets the action flag of all links between employees */
  2772. /*   and their previous manager.                                      */
  2773. /**********************************************************************/
  2774.  
  2775. static VOID PutAllLinkToPreManagerAf(DHND dhnd)
  2776. {
  2777.   SHND             employee_shnd;      /* handle of employee          */
  2778.   EMPLOYEE         employee;           /* employee object data        */
  2779.  
  2780.   /*------------------------------------------------------------------*/
  2781.   /* Loop over all symbols representing employees having been dragged.*/
  2782.   /*------------------------------------------------------------------*/
  2783.  
  2784.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  2785.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  2786.   {
  2787.  
  2788.     /*----------------------------------------------------------------*/
  2789.     /* Retrieve the employee object data.                             */
  2790.     /*----------------------------------------------------------------*/
  2791.  
  2792.     GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  2793.        (employee));
  2794.  
  2795.     /*----------------------------------------------------------------*/
  2796.     /* If the employee does not report to a manager, delete the link  */
  2797.     /* between the employee and its previous manager.                 */
  2798.     /*----------------------------------------------------------------*/
  2799.  
  2800.     if (employee.manager_shnd == GS_INVALID_SHND)
  2801.     {
  2802.       PutLinkToPreManagerAf(dhnd, employee_shnd);
  2803.     }
  2804.   }
  2805. }
  2806.  
  2807. /**********************************************************************/
  2808. /* PutLinkToPreManagerAf                                              */
  2809. /*                                                                    */
  2810. /* Parameters:                                                        */
  2811. /*   DHND             dhnd          (I): Diagram handle               */
  2812. /*   SHND             employee_shnd (I): handle of employee           */
  2813. /*                                                                    */
  2814. /* Returns:                                                           */
  2815. /*   VOID                                                             */
  2816. /*                                                                    */
  2817. /* Description:                                                       */
  2818. /*   The function sets the action flag of the link between an employee*/
  2819. /*   and its previous manager.                                        */
  2820. /**********************************************************************/
  2821.  
  2822. static VOID PutLinkToPreManagerAf(DHND dhnd,SHND employee_shnd)
  2823. {
  2824.   EMPLOYEE         employee;           /* employee object data        */
  2825.   SHND             link_shnd;          /* handle of link symbol       */
  2826.  
  2827.   /*------------------------------------------------------------------*/
  2828.   /* Retrieve the employee object data.                               */
  2829.   /*------------------------------------------------------------------*/
  2830.  
  2831.   GsGetSymObjectData(dhnd, employee_shnd, (PVOID)&employee, sizeof
  2832.      (employee));
  2833.  
  2834.   /*------------------------------------------------------------------*/
  2835.   /* See whether the employee is reporting to a manager.              */
  2836.   /*------------------------------------------------------------------*/
  2837.  
  2838.   if (employee.pre_manager_shnd != GS_INVALID_SHND)
  2839.   {                                    /* the employee reports to a
  2840.                                           manager                     */
  2841.  
  2842.     /*----------------------------------------------------------------*/
  2843.     /* Retrieve the handle of the link.                               */
  2844.     /*----------------------------------------------------------------*/
  2845.  
  2846.     GsGetFirstAttachedSym(dhnd, GS_TARGET_ATTACHED_LINK, employee_shnd,
  2847.        &link_shnd, NULL);
  2848.  
  2849.     /*----------------------------------------------------------------*/
  2850.     /* Mark the link.                                                 */
  2851.     /*----------------------------------------------------------------*/
  2852.  
  2853.     if (link_shnd != GS_INVALID_SHND)
  2854.     {
  2855.       GsPutSymAf(dhnd, link_shnd, GS_ON);
  2856.     }
  2857.   }
  2858. }
  2859.  
  2860. /**********************************************************************/
  2861. /* EvStartDrag                                                        */
  2862. /*                                                                    */
  2863. /* Parameters:                                                        */
  2864. /*    DHND                     dhnd  (I): Diagram handle.             */
  2865. /*    SHORT                    ev_id (I): Identifies the event.       */
  2866. /*    EVS_START_DRAG           *pEvs (I): Pointer to instance of event*/
  2867. /*                                        data type.                  */
  2868. /*     SHND   shnd (I):            Handle of the symbol               */
  2869. /*     POINTL mouse_pos (I):       Position of the mouse pointer      */
  2870. /*                                                                    */
  2871. /* Returns:                                                           */
  2872. /*   GS_NO        Any changes made to symbols remain and the action   */
  2873. /*                stops.                                              */
  2874. /*   GS_NO_1      Any changes made to symbols remain and the action   */
  2875. /*                stops.                                              */
  2876. /*   GS_RESTORE   Any changes made to symbols since the last undo     */
  2877. /*                checkpoint are undone and the action stops.         */
  2878. /*   GS_RESTORE_1 Any changes made to symbols since the last undo     */
  2879. /*                checkpoint are undone and the action stops.         */
  2880. /*   GS_YES       The default processing continues.                   */
  2881. /*                                                                    */
  2882. /* Description:                                                       */
  2883. /*    The function handles the event EV_START_DRAG.                   */
  2884. /*    - Link symbol are not allowed to be dragged.                    */
  2885. /**********************************************************************/
  2886.  
  2887. SHORT GSENTRY EvStartDrag(DHND dhnd,SHORT ev_id,EVS_START_DRAG *pEvs)
  2888. {
  2889.   SHORT            sym_class;          /* class of the symbol         */
  2890.   SHND             employee_shnd;      /* handle of employee          */
  2891.  
  2892.   /*------------------------------------------------------------------*/
  2893.   /* If the symbol the mouse pointer is on a link, drag and drop is   */
  2894.   /* not started.                                                     */
  2895.   /*------------------------------------------------------------------*/
  2896.  
  2897.   GsGetSymClass(dhnd, pEvs->shnd, &sym_class);
  2898.   if (sym_class == GS_LINK)
  2899.   {
  2900.     return  GS_RESTORE;
  2901.   }
  2902.  
  2903.   /*------------------------------------------------------------------*/
  2904.   /* Clear the undo stack. This is necessary to restore the current   */
  2905.   /* situation if the drag operation will be stopped by the end user. */
  2906.   /*------------------------------------------------------------------*/
  2907.  
  2908.   GsResetUndo(dhnd);
  2909.  
  2910.   /*------------------------------------------------------------------*/
  2911.   /* Mark symbols for dragging. All selected symbols representing     */
  2912.   /* employees have the action flag already set.                      */
  2913.   /*------------------------------------------------------------------*/
  2914.  
  2915.   GsCollectSym(dhnd, GS_NODE, GS_SYM_AF, GS_UPPER_FIRST);
  2916.   while (GsGetCollectedSym(dhnd, &employee_shnd) == GS_OK)
  2917.   {
  2918.  
  2919.     /*----------------------------------------------------------------*/
  2920.     /* Mark all symbols of the subtree having the current node as root*/
  2921.     /* for dragging.                                                  */
  2922.     /*----------------------------------------------------------------*/
  2923.  
  2924.     PutAllSubtreeSymAf(dhnd, employee_shnd, FALSE);
  2925.  
  2926.     /*----------------------------------------------------------------*/
  2927.     /* Remove the employee from its manager.                          */
  2928.     /*----------------------------------------------------------------*/
  2929.  
  2930.     RemoveEmployee(dhnd, employee_shnd);
  2931.  
  2932.     /*----------------------------------------------------------------*/
  2933.     /* Remove the manager from the employee.                          */
  2934.     /*----------------------------------------------------------------*/
  2935.  
  2936.     RemoveManager(dhnd, employee_shnd);
  2937.   }
  2938.  
  2939.   /*------------------------------------------------------------------*/
  2940.   /* If all employees are to be deleted, also the general manager has */
  2941.   /* to be removed from the company.                                  */
  2942.   /*------------------------------------------------------------------*/
  2943.  
  2944.   RemoveGenManager(dhnd);
  2945.   return  GS_YES;
  2946. }
  2947.