Merge branch 'linux1'
[oweals/cde.git] / cde / programs / dtmail / MotifApp / InterruptibleCmd.C
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 librararies 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
61 ///////////////////////////////////////////////////////////////
62 // InterruptibleCmd.C: Abstract class that supports lengthy,
63 //                     user-interruptible activities
64 //////////////////////////////////////////////////////////////
65 #include "InterruptibleCmd.h"
66 #include "WorkingDialogManager.h"
67 #include "Application.h"
68 #include <Xm/Xm.h>
69 #include <Xm/MessageB.h>
70 #include <assert.h>
71
72 #if !defined(linux)
73 extern forceUpdate( Widget );
74 #endif
75
76 InterruptibleCmd::InterruptibleCmd ( char *name, char *label, int active ) :
77                         NoUndoCmd ( name, label, active )
78 {
79     _wpId        = NULL;   // There is no work procedure yet
80     _callback    = NULL;           // Callbacks are specified in execute()
81     _clientData  = NULL;
82     _done        = FALSE; 
83 }
84
85 InterruptibleCmd::~InterruptibleCmd()
86 {
87     // Clean up by removing all callbacks
88     
89     if ( _wpId)    
90         XtRemoveWorkProc ( _wpId );
91 }
92
93 void InterruptibleCmd::execute ( TaskDoneCallback callback, void *clientData )
94 {
95     _callback   = callback;
96     _clientData = clientData;
97     execute();
98 }
99
100 void InterruptibleCmd::execute()
101 {
102     char *name_str;
103     char *label_str;
104     
105     name_str = (char *) name();
106     label_str = (char *) getLabel();
107
108     _done  = FALSE;  // Initialize flag
109     
110     // Call the Cmd execute function to handle the Undo, and other
111     // general mechanisms supported by Cmd. Execute calls doit()
112     
113     Cmd::execute();  
114     
115     // If the task was completed in a single call,
116     // don't bother to set up a work procedure. Just
117     // give derived classes a chance to cleanup and
118     // call the application's callback function
119     
120     if ( _done )
121     {
122         cleanup();
123         
124         if ( _callback )
125             ( *_callback )( this, FALSE, _clientData );
126     }
127     
128     // If the task is not done, post a WorkingDialog and 
129     // install a work procedure to continue the task 
130     // as soon as possible.
131     
132     if ( !_done )
133     {
134         theWorkingDialogManager->post (label_str,
135                                        "Fetching" , 
136                                        (void *) this,
137                                        NULL, 
138                                        &InterruptibleCmd::interruptCallback );
139         
140         _wpId = XtAppAddWorkProc ( theApplication->appContext(), 
141                                   &InterruptibleCmd::workProcCallback,
142                                   (XtPointer) this );
143     }
144 }
145
146 Boolean InterruptibleCmd::workProcCallback ( XtPointer clientData )
147 {
148     InterruptibleCmd *obj = (InterruptibleCmd *) clientData;
149     
150     // The work procedure just returns the value returned by the
151     // workProc member function.
152     
153     return ( obj->workProc() );
154 }
155
156 Boolean InterruptibleCmd::workProc()
157 {
158     doit();
159     
160     // If the task has been completed, hide the dialog,
161     // give the derived class a chance to clean up, and notify
162     // the application that instantiated this object.
163     
164     if ( _done )
165     {
166         theWorkingDialogManager->unpost();
167         cleanup();
168         
169         if ( _callback )
170             ( *_callback )( this, FALSE, _clientData );
171     }
172     
173     return _done;
174 }
175
176 void InterruptibleCmd::cleanup()
177 {
178     // Empty
179 }
180
181 void InterruptibleCmd::interruptCallback ( void * clientData )
182 {
183     InterruptibleCmd *obj = ( InterruptibleCmd * ) clientData;
184     
185     // Just set the _interrupt flag to TRUE. The workProc() 
186     // function will notice the next time it is called
187     
188     obj->interrupt();
189 }
190
191 void InterruptibleCmd::interrupt()
192 {
193     // Remove the work procedure
194     
195     XtRemoveWorkProc ( _wpId );
196     
197     // Remove the working dialog and give derived 
198     // classes a chance to clean up 
199     
200     theWorkingDialogManager->unpost();
201     cleanup();
202     
203     // Notify the application that the task was interrupted
204     
205     if ( _callback )
206         ( *_callback )( this, TRUE, _clientData);
207 }
208
209 void InterruptibleCmd::updateMessage ( char * msg )
210 {
211     theWorkingDialogManager->updateMessage ( msg );   
212 }