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