Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtmail / MotifApp / Cmd.C
1 /* $TOG: Cmd.C /main/4 1998/07/24 16:04:37 mgreess $ */
2 /*
3  *+SNOTICE
4  *
5  *      RESTRICTED CONFIDENTIAL INFORMATION:
6  *      
7  *      The information in this document is subject to special
8  *      restrictions in a confidential disclosure agreement bertween
9  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
10  *      document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
11  *      Sun's specific written approval.  This documment and all copies
12  *      and derivative works thereof must be returned or destroyed at
13  *      Sun's request.
14  *
15  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
16  *
17  *+ENOTICE
18  */
19 ///////////////////////////////////////////////////////////////////////////////
20 //////////////////////////////////////////////////////////////////////////////
21 //         This example code is from the book:
22 //
23 //           Object-Oriented Programming with C++ and OSF/Motif
24 //         by
25 //           Douglas Young
26 //           Prentice Hall, 1992
27 //           ISBN 0-13-630252-1 
28 //
29 //         Copyright 1991 by Prentice Hall
30 //         All Rights Reserved
31 //
32 //  Permission to use, copy, modify, and distribute this software for 
33 //  any purpose except publication and without fee is hereby granted, provided 
34 //  that the above copyright notice appear in all copies of the software.
35 ///////////////////////////////////////////////////////////////////////////////
36 //////////////////////////////////////////////////////////////////////////////
37
38
39 ///////////////////////////////////////////////////////
40 // Cmd.C
41 ///////////////////////////////////////////////////////
42 #include <stdlib.h>
43 #include "Cmd.h"
44 #include "CmdList.h"
45 #include "CmdInterface.h"
46
47 extern Cmd *theUndoCmd;  // External object that reverses the 
48 // most recent Cmd when executed
49
50 Cmd *Cmd::_lastCmd = NULL;  // Pointer to most recent Cmd
51
52 Cmd::Cmd ( char *name, char *label, int active )
53 {
54     // Initialize all data members
55     
56     _name              = name;  
57     _active            = active;  
58     _numInterfaces     = 0;    
59     _ci                = NULL;
60     _activationList    = NULL;
61     _deactivationList  = NULL;
62     _hasUndo           = TRUE;
63
64     if (label) {
65         _label         = strdup(label);
66     } else {
67         _label         = strdup(name);
68     }
69 }
70
71 Cmd::~Cmd()
72 {
73     delete _activationList;     
74     delete _deactivationList;   
75     free (_label);
76     if (_ci)
77         delete [] _ci;
78 }
79
80 void Cmd::registerInterface ( CmdInterface *ci )
81 {
82     // Make a new list, large enough for the new object
83     
84     CmdInterface **newList = new CmdInterface*[_numInterfaces + 1];
85     
86     // Copy the contents of the previous list to
87     // the new list
88     
89     for( int i = 0; i < _numInterfaces; i++)
90         newList[i] = _ci[i];
91     
92     // Free the old list
93     
94     if (_ci)
95         delete []_ci;
96     
97     // Install the new list
98     
99     _ci =  newList;
100     
101     // Add the object to the list and update the list size.
102     
103     _ci[_numInterfaces] = ci;
104     
105     _numInterfaces++;
106     
107     if ( ci )
108         if ( _active )
109             ci->activate();
110         else
111             ci->deactivate();      
112 }
113
114 void Cmd::activate()
115 {
116     // Activate the associated interfaces
117     
118     for ( int i = 0; i < _numInterfaces; i++ )
119         _ci[i]->activate ();
120     
121     // Save the current value of active before setting the new state
122     
123     _previouslyActive = _active;
124     _active = TRUE;
125 }
126
127 void Cmd::deactivate()
128 {
129     // Deactivate the associated interfaces
130     
131     for ( int i = 0; i < _numInterfaces; i++ )
132         _ci[i]->deactivate ();
133     
134     // Save the current value of active before setting the new state
135     
136     _previouslyActive = _active;
137     _active = FALSE;
138 }
139
140 void Cmd::revert()
141 {
142     // Activate or deactivate, as necessary, 
143     // to return to the previous state
144     
145     if ( _previouslyActive )
146         activate();
147     else
148         deactivate();
149 }
150
151 #ifdef DEAD_WOOD
152 void Cmd::addToActivationList ( Cmd *cmd )
153 {
154     if ( !_activationList )
155         _activationList = new CmdList();
156     
157     _activationList->add ( cmd );
158 }
159
160 void Cmd::addToDeactivationList ( Cmd *cmd )
161 {
162     if ( !_deactivationList )
163         _deactivationList = new CmdList();
164     
165     _deactivationList->add ( cmd );
166 }
167 #endif /* DEAD_WOOD */
168
169 void Cmd::execute()
170 {
171     int i;      
172     
173     // If a command is inactive, it cannot be executed
174     
175     if ( !_active )
176         return;
177     
178
179     // Activate or deactivate the global theUndoCmd, 
180     // and remember the last command, as needed
181     
182     if ( _hasUndo )
183     {
184         Cmd::_lastCmd = this;
185         theUndoCmd->activate();
186     }
187     else  
188     {      
189         Cmd::_lastCmd = NULL;
190         theUndoCmd->deactivate();
191     }
192     
193     // Process the commands that depend on this one
194     
195     if ( _activationList )    
196         for ( i = 0; i < _activationList->size(); i++ )
197             (*_activationList)[i]->activate();
198     
199     if ( _deactivationList )    
200         for ( i = 0; i < _deactivationList->size(); i++ )
201             (*_deactivationList)[i]->deactivate();
202
203
204     // Call the derived class's doit member function to 
205     // perform the action represented by this object
206     
207     doit();
208     
209 }
210
211 void Cmd::undo()
212 {
213     int i;
214     
215     // Call the derived class's undoit() member function.
216     
217     undoit();
218     
219     // The system only supports one level of undo, and this is it,
220     // so deactivate the undo facility.
221     
222     theUndoCmd->deactivate();
223     
224     // Reverse the effects of the execute() member function by 
225     // reverting all dependent objects to their previous state
226     
227     if ( _activationList )        
228         for ( i = 0; i < _activationList->size(); i++ )
229             (*_activationList)[i]->revert();
230     
231     if ( _deactivationList )    
232         for ( i = 0; i < _deactivationList->size(); i++ )
233             (*_deactivationList)[i]->revert();
234 }
235
236 #ifndef CAN_INLINE_VIRTUALS
237 const char *const
238 Cmd::className(void)
239 {
240     return "Cmd";
241 }
242 #endif /* ! CAN_INLINE_VIRTUALS */