Merge branch 'cde-fixups-1' of ssh://git.code.sf.net/p/cdesktopenv/code into cde...
[oweals/cde.git] / cde / programs / dtprintinfo / objects / BaseObj.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 libraries 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: BaseObj.C /main/4 1998/08/03 16:30:23 mgreess $ */
24 /*                                                                      *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                *
29  */
30
31 #include "BaseObj.h"
32
33 #include <string.h>
34 #include <stdlib.h>
35
36 const char *ACTION_NOT_FOUND = "ActionNotFound";
37
38 BaseObj::BaseObj(BaseObj *parent,
39                  const char *name)
40 {
41    _name = STRDUP(name);
42    _displayName = NULL;
43    _details = NULL;
44    _parent = parent;
45    _init_children = false;
46    _init_attributes = false;
47    _children = NULL;
48    _numChildren = 0;
49    _numActions = 0;
50    _numAttributes = 0;
51    _actions = NULL;
52    _attributes = NULL;
53    _lastActionName = NULL;
54    _lastActionOutput = NULL;
55    _lastActionStatus = 0;
56    AddToParent();
57    BaseObj *p = _parent;
58    while (p)
59     {
60       p->NotifyCreate(this);
61       p = p->_parent;
62     }
63 }
64
65 BaseObj::~BaseObj()
66 {
67    int i;
68
69    DeleteChildren();
70    DeleteFromParent();
71
72    BaseObj *parent = _parent;
73    while (parent)
74     {
75       parent->NotifyDelete(this);
76       parent = parent->_parent;
77     }
78
79    for (i = 0; i < _numAttributes; i++)
80     {
81       delete _attributes[i]->ReferenceName;
82       delete _attributes[i]->Value;
83       delete _attributes[i]->DisplayName;
84       delete _attributes[i]->DisplayValue;
85       delete _attributes[i]->DefaultValue;
86       delete _attributes[i]->DisplayDefaultValue;
87       delete _attributes[i]->Help;
88       delete _attributes[i]->ContextualHelp;
89       delete _attributes[i]->Listing;
90       delete _attributes[i]->Dependancies;
91       delete _attributes[i];
92     }
93    delete []_attributes;
94    for (i = 0; i < _numActions; i++)
95     {
96       delete _actions[i]->ReferenceName;
97       delete _actions[i]->DisplayName;
98       delete _actions[i]->Nmemonic;
99       delete _actions[i]->AcceleratorText;
100       delete _actions[i]->Accelerator;
101       delete _actions[i]->Help;
102       delete _actions[i]->ContextualHelp;
103       delete _actions[i]->Dependancies;
104       delete _actions[i];
105     }
106    delete []_actions;
107    delete []_children;
108    free(_lastActionName);
109    delete [] _lastActionOutput;
110    free(_details);
111    free(_displayName);
112    free(_name);
113 }
114
115 char *BaseObj::DisplayName()
116 {
117    if (!_displayName)
118     {
119       InitDisplayName();
120       if (!_displayName)
121          _displayName = STRDUP(_name);
122     }
123    return _displayName; 
124 }
125
126 void BaseObj::ReadAttributes()
127 {
128    if (_init_attributes == false)
129     {
130       LoadAttributes(_numAttributes, _attributes);
131       _init_attributes = true;
132     }
133 }
134
135 char *BaseObj::Details()
136 {
137    if (!_details)
138     {
139       InitDetails();
140       if (!_details)
141          _details = STRDUP("");
142     }
143    return _details; 
144 }
145
146 void BaseObj::UpdateDetails()
147 {
148    free(_details);
149    _details = NULL;
150    (void) Details();
151 }
152
153 void BaseObj::UpdateChildren()
154 {
155    DeleteChildren();
156    InitChildren();
157    _init_children = true;
158 }
159
160 BaseObj **BaseObj::Children()
161 {
162    if (_init_children == false)
163     {
164       InitChildren();
165       _init_children = true;
166     }
167    return _children; 
168 }
169
170 int BaseObj::NumChildren()
171 {
172    if (_init_children == false)
173     {
174       InitChildren();
175       _init_children = true;
176     }
177    return _numChildren; 
178 }
179
180 void BaseObj::DeleteAction(const char *name)
181 {
182    Action *action;
183
184    if (!HasAction(name, &action))
185       return;
186
187    Action **new_actions;
188    int i, index;
189
190    index = 0;
191    new_actions = new Action*[_numActions - 1];
192    for (i = 0; i < _numActions; i++)
193       if (_actions[i] != action)
194          new_actions[index++] = _actions[i];
195    delete action->ReferenceName;
196    delete action->DisplayName;
197    delete action->Nmemonic;
198    delete action->AcceleratorText;
199    delete action->Accelerator;
200    delete action->Help;
201    delete action->ContextualHelp;
202    delete action->Dependancies;
203    delete action;
204
205    delete []_actions;
206    _actions = new_actions;
207
208    _numActions--;
209 }
210
211 void BaseObj::DeleteAttribute(const char *name)
212 {
213    Attribute *attribute;
214
215    if (!HasAttribute(name, &attribute))
216       return;
217
218    Attribute **new_attributes;
219    int i, index;
220
221    index = 0;
222    new_attributes = new Attribute*[_numAttributes - 1];
223    for (i = 0; i < _numAttributes; i++)
224       if (_attributes[i] != attribute)
225          new_attributes[index++] = _attributes[i];
226    delete attribute->ReferenceName;
227    delete attribute->Value;
228    delete attribute->DisplayName;
229    delete attribute->DisplayValue;
230    delete attribute->DefaultValue;
231    delete attribute->DisplayDefaultValue;
232    delete attribute->Help;
233    delete attribute->ContextualHelp;
234    delete attribute->Listing;
235    delete attribute->Dependancies;
236    delete attribute;
237
238    delete []_attributes;
239    _attributes = new_attributes;
240
241    _numAttributes--;
242 }
243
244 void BaseObj::AddAttribute(const char *ReferenceName,
245                            const char *DisplayName,
246                            const char *Help,
247                            const char *ContextualHelp,
248                            Characteristics Mask,
249                            ValueList ValueListType,
250                            const char *Listing,
251                            const char *Dependancies,
252                            const char *DefaultValue,
253                            const char *DisplayDefaultValue)
254 {
255    Attribute **new_attributes;
256    int i;
257
258    new_attributes = new Attribute*[_numAttributes + 1];
259    for (i = 0; i < _numAttributes; i++)
260       new_attributes[i] = _attributes[i];
261
262    delete []_attributes;
263    _attributes = new_attributes;
264    Attribute *attribute = new Attribute;
265    attribute->ReferenceName = STRDUP(ReferenceName);
266    attribute->Value = NULL;
267    attribute->DisplayName = STRDUP(DisplayName);
268    attribute->DisplayValue = NULL;
269    attribute->DefaultValue = STRDUP(DefaultValue);
270    attribute->DisplayDefaultValue = STRDUP(DisplayDefaultValue);
271    attribute->Mask = Mask;
272    attribute->Help = STRDUP(Help);
273    attribute->ContextualHelp = STRDUP(ContextualHelp);
274    attribute->Listing = STRDUP(Listing);
275    attribute->ValueListType = ValueListType;
276    attribute->Dependancies = STRDUP(Dependancies);
277    _attributes[_numAttributes] = attribute;
278
279    _numAttributes++;
280 }
281
282 void BaseObj::AddAction(ActionHandler Handler, 
283                         const char *ReferenceName,
284                         const char *DisplayName,
285                         const char *Nmemonic,
286                         const char *Help, 
287                         const char *ContextualHelp,
288                         boolean InputRequired,
289                         const char *AcceleratorText,
290                         const char *Accelerator,
291                         const char *Dependancies)
292 {
293    Action **new_actions;
294    int i;
295
296    new_actions = new Action*[_numActions + 1];
297    for (i = 0; i < _numActions; i++)
298       new_actions[i] = _actions[i];
299
300    delete []_actions;
301    _actions = new_actions;
302    Action *action = new Action;
303    action->Handler = Handler;
304    action->ReferenceName = STRDUP(ReferenceName);
305    action->DisplayName = STRDUP(DisplayName);
306    action->Nmemonic = STRDUP(Nmemonic);
307    action->AcceleratorText = STRDUP(AcceleratorText);
308    action->Accelerator = STRDUP(Accelerator);
309    action->InputRequired = InputRequired;
310    action->Help = STRDUP(Help);
311    action->ContextualHelp = STRDUP(ContextualHelp);
312    action->Dependancies = STRDUP(Dependancies);
313    _actions[_numActions] = action;
314
315    _numActions++;
316 }
317
318 void BaseObj::AddToParent()
319 {
320    if (!_parent)
321       return;
322
323    BaseObj **new_children;
324    int i;
325
326    new_children = new BaseObj*[_parent->_numChildren + 1];
327    for (i = 0; i < _parent->_numChildren; i++)
328       new_children[i] = _parent->_children[i];
329
330    delete []_parent->_children;
331    _parent->_children = new_children;
332    _parent->_children[_parent->_numChildren] = this;
333
334    _parent->_numChildren++;
335 }
336
337 void BaseObj::DeleteFromParent()
338 {
339    if (!_parent)
340       return;
341
342    BaseObj **new_children;
343    int i, index;
344
345    index = 0;
346    new_children = new BaseObj*[_parent->_numChildren - 1];
347    for (i = 0; i < _parent->_numChildren; i++)
348       if (_parent->_children[i] != this)
349          new_children[index++] = _parent->_children[i];
350
351    delete []_parent->_children;
352    _parent->_children = new_children;
353
354    _parent->_numChildren--;
355 }
356
357 int BaseObj::NumSiblings()
358 {
359    if (_parent)
360       return _parent->_numChildren;
361    else
362       return 0;
363 }
364
365 BaseObj ** BaseObj::Siblings()
366 {
367    if (_parent)
368       return _parent->_children;
369    else
370       return NULL;
371 }
372
373 boolean BaseObj::HasAction(const char *actionName,
374                            Action **action)
375 {
376    int i;
377
378    for (i = 0; i < _numActions; i++)
379       if (!strcmp(_actions[i]->ReferenceName, actionName))
380         {
381           *action = _actions[i];
382           return true;
383         }
384    return false;
385 }
386
387 boolean BaseObj::HasAction(Action *action)
388 {
389    Action *dummy;
390
391    if (action)
392       return HasAction(action->ReferenceName, &dummy);
393    else
394       return false;
395 }
396
397 boolean BaseObj::HasAction(const char *actionName)
398 {
399    Action *dummy;
400
401    return HasAction(actionName, &dummy);
402 }
403
404 boolean BaseObj::SendAction(Action *action,
405                             BaseObj *requestor)
406 {
407    boolean status;
408
409    delete [] _lastActionOutput;
410    free(_lastActionName);
411    _lastActionOutput = NULL;
412    _lastActionName = strdup(action->ReferenceName);
413    if ((status = HasAction(action)) == true)
414       _lastActionStatus = (*action->Handler)(this, &_lastActionOutput,
415                                              requestor);
416    else
417     {
418       _lastActionStatus = -1;
419       int len = strlen("'%s' is not an action of %s") +
420                 strlen(ObjectClassName()) + strlen(action->ReferenceName) + 1;
421       _lastActionOutput = new char [len];
422       sprintf(_lastActionOutput, "'%s' is not an action of %s", 
423               ObjectClassName(), action->ReferenceName);
424     }
425    return status;
426 }
427
428 boolean BaseObj::SendAction(const char *actionName,
429                             BaseObj *requestor)
430 {
431    Action *action;
432
433    (void) HasAction(actionName, &action);
434    return SendAction(action, requestor);
435 }
436
437 char * BaseObj::AttributeValue(char *referenceName)
438 {
439    Attribute *dummy;
440
441    ReadAttributes();
442    if (HasAttribute(referenceName, &dummy))
443       return dummy->Value;
444    else
445       return NULL;
446 }
447
448 boolean BaseObj::HasAttribute(const char *attributeName,
449                               Attribute **attribute)
450 {
451    int i;
452
453    for (i = 0; i < _numAttributes; i++)
454       if (!strcmp(_attributes[i]->ReferenceName, attributeName))
455         {
456           *attribute = _attributes[i];
457           return true;
458         }
459    return false;
460 }
461
462 boolean BaseObj::HasAttribute(Attribute *attribute)
463 {
464    Attribute *dummy;
465
466    return HasAttribute(attribute->ReferenceName, &dummy);
467 }
468
469 boolean BaseObj::HasAttribute(const char *attributeName)
470 {
471    Attribute *dummy;
472
473    return HasAttribute(attributeName, &dummy);
474 }
475
476 void BaseObj::DeleteChildren()
477 {
478    if (_numChildren)
479     {
480       BaseObj **kids = new BaseObj*[_numChildren];
481       int i, n = _numChildren;
482       // Save children first before deleting a child since the destructor
483       // updates the _children variable
484       for (i = 0; i < n; i++)
485          kids[i] = _children[i];
486       for (i = 0; i < n; i++)
487          delete kids[i];
488       delete []kids;
489     }
490 }
491
492 // Dump object
493 void BaseObj::Dump(boolean verbose, int level)
494 {
495    int i, j;
496
497    for (i = 0; i < level; i++) printf("   ");
498    printf("%s : %s\n", Name(), ObjectClassName());
499    if (verbose)
500     {
501       for (i = -1; i <= level; i++) printf("   ");
502       printf("Display Name = '%s'\n", _displayName);
503       for (i = -1; i <= level; i++) printf("   ");
504       printf("Details = '%s'\n", _details);
505       for (i = -1; i <= level; i++) printf("   ");
506       printf("Number Actions = %d\n", _numActions);
507       for (j = 0; j < _numActions; j++)
508        {
509          for (i = -2; i <= level; i++) printf("   ");
510          printf("Action.%s = '%s'\n", _actions[j]->ReferenceName,
511                 _actions[j]->DisplayName);
512        }
513       for (i = -1; i <= level; i++) printf("   ");
514       printf("Number Attributes = %d\n", _numAttributes);
515       for (j = 0; j < _numAttributes; j++)
516        {
517          for (i = -2; i <= level; i++) printf("   ");
518          printf("Attribute.%s = '%s'\n", _attributes[j]->ReferenceName,
519                 _attributes[j]->DisplayValue);
520        }
521       for (i = -1; i <= level; i++) printf("   ");
522       printf("Number Children = %d\n", _numChildren);
523     }
524 }
525
526 // Dump object hierarchy
527 void BaseObj::DumpHierarchy(boolean verbose, int level)
528 {
529    int i;
530
531    Dump(verbose, level);
532    for (i = 0; i < _numChildren; i++)
533       _children[i]->DumpHierarchy(verbose, level + 1);
534 }
535
536 void BaseObj::Error(const char *message) 
537 {
538    // Log Error
539    printf("%s: (%s) %s\n", ObjectClassName(), Name(), message);
540 }
541
542 int BaseObj::RunCommand(const char *command, 
543                         char **std_out,
544                         char **std_err)
545 {
546    int status;
547
548    Invoke *_thread = new Invoke(command, std_out, std_err);
549
550    status = _thread->status;
551    delete _thread;
552
553    return status;
554 }