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