Merge branch 'linux1'
[oweals/cde.git] / cde / programs / dtmail / MotifApp / Cmd.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 /* $TOG: Cmd.C /main/4 1998/07/24 16:04:37 mgreess $ */
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 // Cmd.C
63 ///////////////////////////////////////////////////////
64 #include <stdlib.h>
65 #include "Cmd.h"
66 #include "CmdList.h"
67 #include "CmdInterface.h"
68
69 extern Cmd *theUndoCmd;  // External object that reverses the 
70 // most recent Cmd when executed
71
72 Cmd *Cmd::_lastCmd = NULL;  // Pointer to most recent Cmd
73
74 Cmd::Cmd ( char *name, char *label, int active )
75 {
76     // Initialize all data members
77     
78     _name              = name;  
79     _active            = active;  
80     _numInterfaces     = 0;    
81     _ci                = NULL;
82     _activationList    = NULL;
83     _deactivationList  = NULL;
84     _hasUndo           = TRUE;
85
86     if (label) {
87         _label         = strdup(label);
88     } else {
89         _label         = strdup(name);
90     }
91 }
92
93 Cmd::~Cmd()
94 {
95     delete _activationList;     
96     delete _deactivationList;   
97     free (_label);
98     if (_ci)
99         delete [] _ci;
100 }
101
102 void Cmd::registerInterface ( CmdInterface *ci )
103 {
104     // Make a new list, large enough for the new object
105     
106     CmdInterface **newList = new CmdInterface*[_numInterfaces + 1];
107     
108     // Copy the contents of the previous list to
109     // the new list
110     
111     for( int i = 0; i < _numInterfaces; i++)
112         newList[i] = _ci[i];
113     
114     // Free the old list
115     
116     if (_ci)
117         delete []_ci;
118     
119     // Install the new list
120     
121     _ci =  newList;
122     
123     // Add the object to the list and update the list size.
124     
125     _ci[_numInterfaces] = ci;
126     
127     _numInterfaces++;
128     
129     if ( ci )
130         if ( _active )
131             ci->activate();
132         else
133             ci->deactivate();      
134 }
135
136 void Cmd::activate()
137 {
138     // Activate the associated interfaces
139     
140     for ( int i = 0; i < _numInterfaces; i++ )
141         _ci[i]->activate ();
142     
143     // Save the current value of active before setting the new state
144     
145     _previouslyActive = _active;
146     _active = TRUE;
147 }
148
149 void Cmd::deactivate()
150 {
151     // Deactivate the associated interfaces
152     
153     for ( int i = 0; i < _numInterfaces; i++ )
154         _ci[i]->deactivate ();
155     
156     // Save the current value of active before setting the new state
157     
158     _previouslyActive = _active;
159     _active = FALSE;
160 }
161
162 void Cmd::revert()
163 {
164     // Activate or deactivate, as necessary, 
165     // to return to the previous state
166     
167     if ( _previouslyActive )
168         activate();
169     else
170         deactivate();
171 }
172
173 #ifdef DEAD_WOOD
174 void Cmd::addToActivationList ( Cmd *cmd )
175 {
176     if ( !_activationList )
177         _activationList = new CmdList();
178     
179     _activationList->add ( cmd );
180 }
181
182 void Cmd::addToDeactivationList ( Cmd *cmd )
183 {
184     if ( !_deactivationList )
185         _deactivationList = new CmdList();
186     
187     _deactivationList->add ( cmd );
188 }
189 #endif /* DEAD_WOOD */
190
191 void Cmd::execute()
192 {
193     int i;      
194     
195     // If a command is inactive, it cannot be executed
196     
197     if ( !_active )
198         return;
199     
200
201     // Activate or deactivate the global theUndoCmd, 
202     // and remember the last command, as needed
203     
204     if ( _hasUndo )
205     {
206         Cmd::_lastCmd = this;
207         theUndoCmd->activate();
208     }
209     else  
210     {      
211         Cmd::_lastCmd = NULL;
212         theUndoCmd->deactivate();
213     }
214     
215     // Process the commands that depend on this one
216     
217     if ( _activationList )    
218         for ( i = 0; i < _activationList->size(); i++ )
219             (*_activationList)[i]->activate();
220     
221     if ( _deactivationList )    
222         for ( i = 0; i < _deactivationList->size(); i++ )
223             (*_deactivationList)[i]->deactivate();
224
225
226     // Call the derived class's doit member function to 
227     // perform the action represented by this object
228     
229     doit();
230     
231 }
232
233 void Cmd::undo()
234 {
235     int i;
236     
237     // Call the derived class's undoit() member function.
238     
239     undoit();
240     
241     // The system only supports one level of undo, and this is it,
242     // so deactivate the undo facility.
243     
244     theUndoCmd->deactivate();
245     
246     // Reverse the effects of the execute() member function by 
247     // reverting all dependent objects to their previous state
248     
249     if ( _activationList )        
250         for ( i = 0; i < _activationList->size(); i++ )
251             (*_activationList)[i]->revert();
252     
253     if ( _deactivationList )    
254         for ( i = 0; i < _deactivationList->size(); i++ )
255             (*_deactivationList)[i]->revert();
256 }
257
258 #ifndef CAN_INLINE_VIRTUALS
259 const char *const
260 Cmd::className(void)
261 {
262     return "Cmd";
263 }
264 #endif /* ! CAN_INLINE_VIRTUALS */