InterruptibleCmd.C 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: InterruptibleCmd.C /main/3 1995/11/06 16:00:32 rswiston $ */
  24. /*
  25. *+SNOTICE
  26. *
  27. * RESTRICTED CONFIDENTIAL INFORMATION:
  28. *
  29. * The information in this document is subject to special
  30. * restrictions in a confidential disclosure agreement bertween
  31. * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
  32. * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
  33. * Sun's specific written approval. This documment and all copies
  34. * and derivative works thereof must be returned or destroyed at
  35. * Sun's request.
  36. *
  37. * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
  38. *
  39. *+ENOTICE
  40. */
  41. ///////////////////////////////////////////////////////////////////////////////
  42. //////////////////////////////////////////////////////////////////////////////
  43. // This example code is from the book:
  44. //
  45. // Object-Oriented Programming with C++ and OSF/Motif
  46. // by
  47. // Douglas Young
  48. // Prentice Hall, 1992
  49. // ISBN 0-13-630252-1
  50. //
  51. // Copyright 1991 by Prentice Hall
  52. // All Rights Reserved
  53. //
  54. // Permission to use, copy, modify, and distribute this software for
  55. // any purpose except publication and without fee is hereby granted, provided
  56. // that the above copyright notice appear in all copies of the software.
  57. ///////////////////////////////////////////////////////////////////////////////
  58. //////////////////////////////////////////////////////////////////////////////
  59. ///////////////////////////////////////////////////////////////
  60. // InterruptibleCmd.C: Abstract class that supports lengthy,
  61. // user-interruptible activities
  62. //////////////////////////////////////////////////////////////
  63. #include "InterruptibleCmd.h"
  64. #include "WorkingDialogManager.h"
  65. #include "Application.h"
  66. #include <Xm/Xm.h>
  67. #include <Xm/MessageB.h>
  68. #include <assert.h>
  69. #if !defined(__linux__) && !defined(CSRG_BASED)
  70. extern void forceUpdate( Widget );
  71. #endif
  72. InterruptibleCmd::InterruptibleCmd ( char *name, char *label, int active ) :
  73. NoUndoCmd ( name, label, active )
  74. {
  75. _wpId = 0; // There is no work procedure yet
  76. _callback = NULL; // Callbacks are specified in execute()
  77. _clientData = NULL;
  78. _done = FALSE;
  79. }
  80. InterruptibleCmd::~InterruptibleCmd()
  81. {
  82. // Clean up by removing all callbacks
  83. if ( _wpId)
  84. XtRemoveWorkProc ( _wpId );
  85. }
  86. void InterruptibleCmd::execute ( TaskDoneCallback callback, void *clientData )
  87. {
  88. _callback = callback;
  89. _clientData = clientData;
  90. execute();
  91. }
  92. void InterruptibleCmd::execute()
  93. {
  94. char *name_str;
  95. char *label_str;
  96. name_str = (char *) name();
  97. label_str = (char *) getLabel();
  98. _done = FALSE; // Initialize flag
  99. // Call the Cmd execute function to handle the Undo, and other
  100. // general mechanisms supported by Cmd. Execute calls doit()
  101. Cmd::execute();
  102. // If the task was completed in a single call,
  103. // don't bother to set up a work procedure. Just
  104. // give derived classes a chance to cleanup and
  105. // call the application's callback function
  106. if ( _done )
  107. {
  108. cleanup();
  109. if ( _callback )
  110. ( *_callback )( this, FALSE, _clientData );
  111. }
  112. // If the task is not done, post a WorkingDialog and
  113. // install a work procedure to continue the task
  114. // as soon as possible.
  115. if ( !_done )
  116. {
  117. theWorkingDialogManager->post (label_str,
  118. "Fetching" ,
  119. (void *) this,
  120. NULL,
  121. &InterruptibleCmd::interruptCallback );
  122. _wpId = XtAppAddWorkProc ( theApplication->appContext(),
  123. &InterruptibleCmd::workProcCallback,
  124. (XtPointer) this );
  125. }
  126. }
  127. Boolean InterruptibleCmd::workProcCallback ( XtPointer clientData )
  128. {
  129. InterruptibleCmd *obj = (InterruptibleCmd *) clientData;
  130. // The work procedure just returns the value returned by the
  131. // workProc member function.
  132. return ( obj->workProc() );
  133. }
  134. Boolean InterruptibleCmd::workProc()
  135. {
  136. doit();
  137. // If the task has been completed, hide the dialog,
  138. // give the derived class a chance to clean up, and notify
  139. // the application that instantiated this object.
  140. if ( _done )
  141. {
  142. theWorkingDialogManager->unpost();
  143. cleanup();
  144. if ( _callback )
  145. ( *_callback )( this, FALSE, _clientData );
  146. }
  147. return _done;
  148. }
  149. void InterruptibleCmd::cleanup()
  150. {
  151. // Empty
  152. }
  153. void InterruptibleCmd::interruptCallback ( void * clientData )
  154. {
  155. InterruptibleCmd *obj = ( InterruptibleCmd * ) clientData;
  156. // Just set the _interrupt flag to TRUE. The workProc()
  157. // function will notice the next time it is called
  158. obj->interrupt();
  159. }
  160. void InterruptibleCmd::interrupt()
  161. {
  162. // Remove the work procedure
  163. XtRemoveWorkProc ( _wpId );
  164. // Remove the working dialog and give derived
  165. // classes a chance to clean up
  166. theWorkingDialogManager->unpost();
  167. cleanup();
  168. // Notify the application that the task was interrupted
  169. if ( _callback )
  170. ( *_callback )( this, TRUE, _clientData);
  171. }
  172. void InterruptibleCmd::updateMessage ( char * msg )
  173. {
  174. theWorkingDialogManager->updateMessage ( msg );
  175. }