efcc174dbee9f35567d62a644aec00bce2d30ea2
[oweals/cde.git] / cde / programs / dtprintinfo / libUI / BaseUI.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: BaseUI.C /main/10 1998/07/24 16:14: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 "BaseUI.h"
32
33 #ifdef NO_REGCOMP
34 #include <ctype.h>
35 #if defined(SVR4) || defined(SYSV)
36 #include <libgen.h>
37 #endif
38 #else
39 #include <regex.h>
40 #endif
41
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #ifdef hpux
46   #include <time.h>
47 #elif defined(USL) || defined(__uxp__) || defined(__osf__) || defined(linux)
48   #include <sys/time.h>
49 #else
50   #include <sys/select.h>
51 #endif /* hpux */
52 #ifdef _AIX
53 #include <strings.h>            /* need to get bzero defined */
54 #endif /* _AIX */
55
56 #if defined(aix) || defined(USL) || defined(__uxp__)
57 extern "C"
58 {
59 extern int strcasecmp(const char *,  const char *);
60 }
61 #endif
62
63 #define IsContainer(p) (p->UIClass() == CONTAINER)
64
65 #ifdef DEBUG
66 #define PrintObject() if (trace_calls) fprintf(stderr, " %s\n", _name);
67 #else
68 #define PrintObject()
69 #endif
70
71 int BaseUI::_UniqueID = 1;
72
73 BaseUI::BaseUI(BaseUI *parent,
74                const char *name,
75                const char *category)
76 {
77    EnterFunction("BaseUI::BaseUI");
78    _id = _UniqueID++;
79    _name = STRDUP(name);
80    PrintObject();
81
82    _category = STRDUP(category);
83    if (parent)
84     {
85       _viewStyle = parent->_viewStyle;
86       _iconStyle = parent->_iconStyle;
87       _visible = parent->_visible;
88       _active = parent->_active;
89     }
90    else
91     {
92       _viewStyle = GRID;
93       _iconStyle = LARGE_ICON;
94       _visible = true;
95       _active = true;
96     }
97    _update_message = NULL;
98    _selected = false;
99    _parent = parent;
100    _children = NULL;
101    _numChildren = 0;
102    _allChildren = NULL;
103    _numAllChildren = 0;
104    _has_been_opened = false;
105    _opened = false;
106    AddToParent();
107    AddToParentContainer();
108    BaseUI *p = _parent;
109    while (p && !IsContainer(p))
110     {
111       p->NotifyCreate(this);
112       p = p->_parent;
113     }
114    if (p && IsContainer(p))
115       p->NotifyCreate(this);
116
117    LeaveFunction("BaseUI::BaseUI");
118    PrintObject();
119 }
120
121 BaseUI::~BaseUI()
122 {
123    EnterFunction("BaseUI::~BaseUI()");
124    PrintObject();
125
126    BaseUI *p = _parent;
127
128    DeleteChildren();
129    DeleteFromParent();
130    DeleteFromParentContainer();
131
132    while (p)
133     {
134       if (IsContainer(p))
135        {
136          if (p->UISubClass() == ICON_LIST ||
137              p->UISubClass() == SCROLLED_ICON_LIST)
138             break;
139          if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
140             break;
141        }
142       p->NotifyDelete(this);
143       p = p->_parent;
144     }
145    if (p && IsContainer(p))
146       p->NotifyDelete(this);
147
148    delete(_update_message);
149    delete []_children;
150    delete []_allChildren;
151
152    LeaveFunction("BaseUI::~BaseUI()");
153    PrintObject();
154
155    free(_category);
156    free(_name);
157 }
158
159 void BaseUI::ContextualHelp()
160 {
161    DoContextualHelp();
162 }
163
164 void BaseUI::Refresh()
165 {
166    DoRefresh();
167 }
168
169 void BaseUI::ToFront()
170 {
171    DoToFront();
172 }
173
174 void BaseUI::Parent(BaseUI *new_parent)
175 {
176    if (SetParent(new_parent))
177     {
178       // need to write this 
179       ;
180     }
181 }
182
183 void BaseUI::Open(boolean flag)
184 {
185    if (SetOpen(flag))
186     {
187       _has_been_opened = true;
188       _opened = flag;
189       BaseUI *p = _parent;
190       while (p && !IsContainer(p))
191        {
192          p->NotifyOpen(this);
193          p = p->_parent;
194        }
195       if (p && IsContainer(p))
196          p->NotifyOpen(this);
197     }
198 }
199
200 void BaseUI::AddToParent()
201 {
202    if (!_parent)
203       return;
204
205    BaseUI **new_children;
206    int i;
207
208    new_children = new BaseUI*[_parent->_numChildren + 1];
209    for (i = 0; i < _parent->_numChildren; i++)
210       new_children[i] = _parent->_children[i];
211
212    delete []_parent->_children;
213    _parent->_children = new_children;
214    _parent->_children[_parent->_numChildren] = this;
215
216    _parent->_numChildren++;
217 }
218
219 void BaseUI::DeleteFromParent()
220 {
221    if (!_parent)
222       return;
223
224    BaseUI **new_children;
225    int i, index;
226
227    index = 0;
228    new_children = new BaseUI*[_parent->_numChildren - 1];
229    for (i = 0; i < _parent->_numChildren; i++)
230       if (_parent->_children[i] != this)
231          new_children[index++] = _parent->_children[i];
232
233    delete []_parent->_children;
234    _parent->_children = new_children;
235
236    _parent->_numChildren--;
237 }
238
239 void BaseUI::DeleteChildren()
240 {
241    EnterFunction("BaseUI::DeleteChildren()");
242    PrintObject();
243
244    if (_numChildren)
245     {
246       BaseUI **kids = new BaseUI*[_numChildren];
247       int i, j, n = _numChildren;
248       // Save children first before deleting a child since the destructor
249       // updates the _children variable
250       for (i = 0; i < n; i++)
251          kids[i] = _children[i];
252       for (i = 0; i < n; i++)
253        {
254          for (j = 0; j < _numChildren; j++)
255            if (_children[j] == kids[i])
256             {
257               delete kids[i];
258               break;
259             }
260        }
261       delete []kids;
262     }
263    LeaveFunction("BaseUI::DeleteChildren()");
264    PrintObject();
265 }
266
267 BaseUI * BaseUI::ContainerParent()
268 {
269    BaseUI *parent = this;
270
271    while (parent && !IsContainer(parent))
272       parent = parent->_parent;
273       
274    return parent;
275 }
276
277 void BaseUI::AddToParentContainer()
278 {
279    BaseUI *parent;
280
281    if (!(parent = ContainerParent()))
282       return;
283
284    BaseUI **new_children;
285    int i;
286
287    new_children = new BaseUI*[parent->_numAllChildren + 1];
288    for (i = 0; i < parent->_numAllChildren; i++)
289       new_children[i] = parent->_allChildren[i];
290
291    delete []parent->_allChildren;
292    parent->_allChildren = new_children;
293    parent->_allChildren[parent->_numAllChildren] = this;
294
295    parent->_numAllChildren++;
296 }
297
298 void BaseUI::DeleteFromParentContainer()
299 {
300    BaseUI *parent;
301
302    if (!(parent = ContainerParent()))
303       return;
304
305    BaseUI **new_children;
306    int i, index;
307
308    index = 0;
309    new_children = new BaseUI*[parent->_numAllChildren - 1];
310    for (i = 0; i < parent->_numAllChildren; i++)
311       if (parent->_allChildren[i] != this)
312          new_children[index++] = parent->_allChildren[i];
313
314    delete []parent->_allChildren;
315    parent->_allChildren = new_children;
316
317    parent->_numAllChildren--;
318 }
319
320 boolean BaseUI::HandleHelpRequest()
321 {
322    BaseUI *parent = _parent;
323    while (parent && parent->HandleHelpRequest() == false)
324       parent = parent->_parent;
325    return true;
326 }
327
328 void BaseUI::SetVisible(boolean flag)
329 {
330    if (SetVisiblity(flag))
331     {
332       _visible = flag;
333       BaseUI *p = _parent;
334       while (p)
335        {
336          if (IsContainer(p))
337           {
338             if (p->UISubClass() == ICON_LIST ||
339                 p->UISubClass() == SCROLLED_ICON_LIST)
340                break;
341             if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
342                break;
343           }
344          p->NotifyVisiblity(this);
345          p = p->_parent;
346        }
347       if (p && IsContainer(p))
348          p->NotifyVisiblity(this);
349     }
350 }
351
352 // Set visiblity, calls derived function SetVisiblity
353 void BaseUI::Visible(boolean flag)
354 {
355    if (UIClass() != CONTAINER &&
356        UIClass() != MAIN_WINDOW &&
357        UIClass() != DIALOG &&
358        UIClass() != APPLICATION)
359     {
360       int i;
361       SetVisible(flag);
362       for (i = 0; i < _numChildren; i++)
363          if (!IsContainer(_children[i]))
364             _children[i]->Visible(flag);
365     }
366    else
367       SetVisible(flag);
368 }
369
370 // Set sensitivity, calls derived function SetActivity
371 void BaseUI::Active(boolean flag)
372 {
373    if (UIClass() != CONTAINER)
374     {
375       int i;
376       if (flag == true)
377        {
378         if (SetActivity(flag))
379             _active = flag;
380          for (i = 0; i < _numChildren; i++)
381             if (!IsContainer(_children[i]))
382                _children[i]->Active(flag);
383        }
384       else
385        {
386          for (i = 0; i < _numChildren; i++)
387             if (!IsContainer(_children[i]))
388                _children[i]->Active(flag);
389         if (SetActivity(flag))
390             _active = flag;
391        }
392     }
393    else if (SetActivity(flag))
394       _active = flag;
395 }
396
397 // Set view, calls derived function SetIcon
398 void BaseUI::ContainerView(ViewStyle viewStyle)
399 {
400    if (UIClass() == CONTAINER)
401     {
402       int i;
403       for (i = 0; i < _numAllChildren; i++)
404          if (!IsContainer(_allChildren[i]))
405             _allChildren[i]->ContainerView(viewStyle);
406     }
407    _viewStyle = viewStyle;
408 }
409
410 // Set view, calls derived function SetIcon
411 void BaseUI::IconView(IconStyle iconStyle)
412 {
413    if (UIClass() == CONTAINER)
414     {
415       int i;
416       for (i = 0; i < _numAllChildren; i++)
417          if (IsContainer(_allChildren[i]))
418           {
419             if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
420                _allChildren[i]->IconView(iconStyle);
421           }
422          else
423             _allChildren[i]->IconView(iconStyle);
424     }
425    if (SetIcon(iconStyle))
426       _iconStyle = iconStyle;
427 }
428
429 // Set selected status, calls derived function SetSelected
430 void BaseUI::Selected(boolean flag)
431 {
432    if (SetSelected(flag))
433     {
434       _selected = flag;
435       BaseUI *p = _parent;
436       while (p)
437        {
438          if (IsContainer(p))
439           {
440             if (p->UISubClass() == ICON_LIST ||
441                 p->UISubClass() == SCROLLED_ICON_LIST)
442                break;
443             if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
444                break;
445           }
446          p->NotifySelected(this);
447          p = p->_parent;
448        }
449       if (p && IsContainer(p))
450          p->NotifySelected(this);
451     }
452 }
453
454 // Set name, calls derived function SetCategory
455 void BaseUI::Category(char *category)
456 {
457    if (SetCategory(category))
458     {
459       free(_category);
460       _category = STRDUP(category);
461     }
462 }
463
464 // Set name, calls derived function SetName
465 void BaseUI::Name(char *name)
466 {
467    if (SetName(name))
468     {
469       free(_name);
470       _name = STRDUP(name);
471     }
472 }
473
474 // Select/UnSelected all immediate children
475 void BaseUI::SelectAll(boolean select_status)
476 {
477    int i;
478
479    for (i = 0; i < _numChildren; i++)
480     {
481       _children[i]->Selected(select_status);
482       if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
483          _children[i]->SelectAll(select_status);
484     }
485
486 }
487
488 // Select/UnSelected all children, and their children, etc...
489 void BaseUI::SelectAllDescendants(boolean select_status)
490 {
491    int i;
492
493    if (UIClass() == CONTAINER)
494       for (i = 0; i < _numChildren; i++)
495          _children[i]->Selected(select_status);
496    else
497       for (i = 0; i < _numChildren; i++)
498        {
499          _children[i]->Selected(select_status);
500          if (!IsContainer(_children[i]))
501             _children[i]->SelectAllDescendants(select_status);
502        }
503 }
504
505 // Open/Close all children, and their children, etc...
506 void BaseUI::OpenAllDescendants(boolean opened)
507 {
508    int i;
509
510    if (UIClass() == CONTAINER)
511       for (i = 0; i < _numChildren; i++)
512          _children[i]->Open(opened);
513    else
514     {
515       if (opened)
516          for (i = 0; i < _numChildren; i++)
517           {
518             _children[i]->Open(opened);
519             if (!IsContainer(_children[i]))
520                _children[i]->OpenAllDescendants(opened);
521           }
522       else
523          for (i = 0; i < _numChildren; i++)
524           {
525             if (!IsContainer(_children[i]))
526                _children[i]->OpenAllDescendants(opened);
527             _children[i]->Open(opened);
528           }
529     }
530 }
531
532 void BaseUI::Selection(int *n_items,
533                        BaseUI ***items)
534 {
535    if (UIClass() != CONTAINER)
536     {
537       if (items)
538          *items = NULL;
539       *n_items = 0;
540       return;
541     }
542
543    boolean isScrolledList;
544    if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
545       isScrolledList = true;
546    else
547       isScrolledList = false;
548
549    int i;
550    *n_items = 0;
551    for (i = 0; i < _numAllChildren; i++)
552       if (!IsContainer(_allChildren[i]) && _allChildren[i]->Selected())
553          (*n_items)++;
554       else if (IsContainer(_allChildren[i]) && isScrolledList)
555        {
556          int tmp;
557          _allChildren[i]->Selection(&tmp);
558          (*n_items) += tmp;
559        }
560
561    if (!items)
562       return;
563
564    if (*n_items == 0)
565       *items = NULL;
566    else
567     {
568       BaseUI **list = new BaseUI*[*n_items];
569       *n_items = 0;
570       for (i = 0; i < _numAllChildren; i++)
571          if (!IsContainer(_allChildren[i]) && _allChildren[i]->Selected())
572             list[(*n_items)++] = _allChildren[i];
573          else if (IsContainer(_allChildren[i]) && isScrolledList)
574           {
575             int tmp;
576             BaseUI **tmp1;
577             _allChildren[i]->Selection(&tmp, &tmp1);
578             int j, k = *n_items + tmp;
579             for (j = *n_items; j < k; j++)
580                list[(*n_items)++] = tmp1[j];
581             delete []tmp1;
582           }
583
584       *items = list;
585     }
586 }
587
588 int BaseUI::NumContainerChildren()
589 {
590    BaseUI *container = ContainerParent();
591
592    if (container)
593       return container->_numAllChildren;
594    else
595       return 0;
596 }
597
598 BaseUI ** BaseUI::ContainerChildren()
599 {
600    BaseUI *container = ContainerParent();
601
602    if (container)
603       return container->_allChildren;
604    else
605       return NULL;
606 }
607
608 int BaseUI::NumSiblings()
609 {
610    if (_parent)
611       return _parent->_numChildren;
612    else
613       return 0;
614 }
615
616 BaseUI ** BaseUI::Siblings()
617 {
618    if (_parent)
619       return _parent->_children;
620    else
621       return NULL;
622 }
623
624 void BaseUI::_Find(void *pattern, int depth, int *n_matches,
625                    BaseUI ***matches, SelectProc select_proc,
626                    boolean regular_expression, boolean case_sensitive,
627                    boolean find_by_name, int cur_depth)
628 {
629    if (depth != 0 && cur_depth == depth)
630       return;
631
632    BaseUI **children = _children;
633    int n_children = _numChildren;
634    int i;
635    for (i = 0; i < n_children; i++)
636     {
637       int tmp = 0;
638       BaseUI **tmp1 = NULL;
639       children[i]->_Find(pattern, depth, &tmp, &tmp1, select_proc,
640                              regular_expression, case_sensitive,
641                              find_by_name, cur_depth + 1);
642       if (tmp)
643        {
644          int j;
645          if (*n_matches == 0)
646             *matches = (BaseUI **)malloc(sizeof(BaseUI **) * tmp);
647          else
648             *matches = (BaseUI **)realloc(*matches, sizeof(BaseUI **) *
649                                           (*n_matches + tmp));
650          for (j = 0; j < tmp; j++)
651             (*matches)[(*n_matches)++] = tmp1[j];
652          free(tmp1);
653          tmp = 0;
654        }
655       char *value;
656       int is_match;
657       if (find_by_name)
658          value = children[i]->_name;
659       else
660          value = children[i]->_category;
661       if (value)
662        {
663          if (case_sensitive)
664           {
665             if (regular_expression)
666 #ifdef NO_REGCOMP
667                is_match = (int)regex((char *)pattern, value);
668 #else
669                is_match = !regexec((regex_t *)pattern, value, (size_t)0,NULL,0);
670 #endif
671             else
672                is_match = !strcmp(value, (char *)pattern);
673           }
674          else
675           {
676             if (regular_expression)
677 #ifdef NO_REGCOMP
678                is_match = (int)regex((char *)pattern, value);
679 #else
680                is_match = !regexec((regex_t *)pattern, value, (size_t)0,NULL,0);
681 #endif
682             else 
683                is_match = !strcasecmp(value, (char *)pattern);
684           }
685         }
686        else
687           is_match = 0;
688
689       if (is_match && select_proc)
690          is_match = (*select_proc)(children[i]);
691       if (is_match)
692        {
693          if (*n_matches == 0)
694             *matches = (BaseUI **)malloc(sizeof(BaseUI **));
695          else
696             *matches = (BaseUI **)realloc(*matches, sizeof(BaseUI **) *
697                                           (*n_matches + 1));
698          (*matches)[(*n_matches)++] = children[i];
699        }
700     }
701 }
702
703 BaseUI *BaseUI::_FindBy(char *pattern, int depth, int *n_matches,
704                         BaseUI ***matches, SelectProc select_proc,
705                         boolean regular_expression, boolean case_sensitive, 
706                         boolean find_by_name)
707 {
708    void *reg_expr = pattern;
709 #ifdef NO_REGCOMP
710    if (regular_expression)
711     {
712       if (case_sensitive == false)
713        {
714          char *new_pattern = new char[(strlen(pattern) * 4) + 1];
715          int i = 0;
716          char *s;
717          for (s = pattern; *s; s++)
718           {
719              if (isalpha((int)*s))
720               {
721                 new_pattern[i++] = '[';
722                 new_pattern[i++] = *s;
723                 if (islower(*s))
724                    new_pattern[i++] = (char)toupper((int)*s);
725                 else
726                    new_pattern[i++] = (char)tolower((int)*s);
727                 new_pattern[i++] = ']';
728               }
729              else
730                 new_pattern[i++] = *s;
731           }
732          new_pattern[i] = '\0';
733          reg_expr = regcmp(new_pattern, (char *)NULL);
734          delete new_pattern;
735        }
736       else
737          reg_expr = regcmp(pattern, (char *)NULL);
738     }
739 #else
740    regex_t re;
741    if (regular_expression)
742     {
743       int compile_flags;
744       if (case_sensitive)
745          compile_flags = REG_NOSUB;
746       else
747          compile_flags = REG_ICASE|REG_NOSUB;
748       if (regcomp(&re, pattern, compile_flags) != 0)
749          reg_expr = NULL;
750       else
751          reg_expr = &re;
752     }
753 #endif
754    if (!reg_expr)
755     {
756       if (n_matches)
757          *n_matches = 0;
758       if (matches)
759          matches = NULL;
760       return NULL;
761     }
762    BaseUI **_matches = NULL;
763    int _n_matches = 0;
764    _Find(reg_expr, depth, &_n_matches, &_matches, select_proc,
765          regular_expression, case_sensitive, find_by_name, 0);
766   
767 #ifndef NO_REGCOMP
768    if (regular_expression)
769       regfree(&re);
770 #endif
771    if (n_matches)
772       *n_matches = _n_matches;
773    if (matches)
774     {
775       *matches = _matches;
776       if (_n_matches)
777          return _matches[0];
778       else
779          return NULL;
780     }
781    else if (_n_matches)
782     {
783       BaseUI *a_match = _matches[0];
784       free(_matches);
785       return a_match;
786     }
787    return NULL;
788 }
789
790 BaseUI *BaseUI::FindByName(char *pattern, int depth, int *n_matches,
791                            BaseUI ***matches, SelectProc select_proc,
792                            boolean regular_expression, boolean case_sensitive)
793 {
794    return _FindBy(pattern, depth, n_matches, matches, select_proc,
795                   regular_expression, case_sensitive, true);
796 }
797
798 BaseUI *BaseUI::FindByCategory(char *pattern, int depth, int *n_matches,
799                                BaseUI ***matches, SelectProc select_proc,
800                                boolean regular_expression,
801                                boolean case_sensitive)
802 {
803    return _FindBy(pattern, depth, n_matches, matches, select_proc,
804                   regular_expression, case_sensitive, false);
805 }
806
807 void BaseUI::OrderByName(boolean /*flag*/)
808 {
809 }
810
811 void BaseUI::GroupByCategory(boolean /*flag*/)
812 {
813 }
814
815 // Calls derived class's SetOrder function
816 void BaseUI::Order(int new_position)
817 {
818   if (!_parent || new_position < 0 || new_position > _parent->_numChildren)
819      return;
820
821   int current_position = Order();
822   if (new_position == current_position)
823     return;
824
825   BaseUI **children = _parent->_children;
826   int i;
827   if (current_position < new_position)
828      for (i = current_position; i < new_position; i++)
829         children[i] = children[i + 1];
830   else
831      for (i = current_position; i > new_position; i--)
832         children[i] = children[i - 1];
833   children[new_position] = this;
834   (void) SetOrder(new_position);
835 }
836
837 int BaseUI::Order()
838 {
839    int i = 0;
840    if (_parent)
841     {
842       for (i = 0; i < _parent->_numChildren; i++)
843          if (_parent->_children[i] == this)
844             break;
845     }
846    return i;
847 }
848
849 boolean BaseUI::IsVisible()
850 {
851    return DoIsVisible();
852 }
853
854 void BaseUI::MakeVisible()
855 {
856    if (_visible == false)
857       return;
858    BaseUI *parent = Parent();
859    if (parent)
860      parent->MakeVisible();
861    if (_visible && parent)
862       DoMakeVisible();
863 }
864
865 void BaseUI::BeginUpdate()
866 {
867    _update = false;
868    DoBeginUpdate();
869 }
870
871 void BaseUI::EndUpdate()
872 {
873    _update = true;
874    DoEndUpdate();
875 }
876
877 void BaseUI::UpdateMessage(const char *message)
878 {
879    free(_update_message);
880    _update_message = STRDUP(message);
881    DoUpdateMessage(_update_message);
882 }
883
884 boolean BaseUI::ObjectExists(int unique_id)
885 {
886    int i;
887    boolean found = false;
888    for (i = 0; i < _numChildren; i++)
889     {
890       BaseUI *child = _children[i];
891       if (unique_id == _children[i]->_id)
892        {
893          found = true;
894          break;
895        }
896       else if (found = _children[i]->ObjectExists(unique_id))
897          break;
898     }
899    return found;
900 }
901
902 #define PrintBoolean(flag) flag ? "True" : "False"
903
904 // Dump object to stdout
905 void BaseUI::Dump(boolean verbose, int level)
906 {
907    int i;
908
909    for (i = 0; i < level; i++)
910       printf("   ");
911    printf("%s : %s\n", _name, UIClassName());
912    if (verbose)
913     {
914       for (i = -1; i <= level; i++) printf("   ");
915       printf("Category : %s\n", _category ? _category : "");
916       for (i = -1; i <= level; i++) printf("   ");
917       printf("HasBeenOpened : %s\n", PrintBoolean(_has_been_opened));
918       for (i = -1; i <= level; i++) printf("   ");
919       printf("Opened : %s\n", PrintBoolean(_opened));
920       for (i = -1; i <= level; i++) printf("   ");
921       printf("Visible : %s\n", PrintBoolean(_visible));
922       for (i = -1; i <= level; i++) printf("   ");
923       printf("Active : %s\n", PrintBoolean(_active));
924       for (i = -1; i <= level; i++) printf("   ");
925       printf("Selected : %s\n", PrintBoolean(_selected));
926       for (i = -1; i <= level; i++) printf("   ");
927       switch (_viewStyle)
928       {
929       case AS_PLACED: printf("ViewStyle : AS_PLACED\n"); break;
930       case GRID: printf("ViewStyle : GRID\n"); break;
931       case BROWSER: printf("ViewStyle : BROWSER\n"); break;
932       case TREE: printf("ViewStyle : TREE\n"); break;
933       case PROPERTIES: printf("ViewStyle : PROPERTIES\n"); break;
934       }
935       for (i = -1; i <= level; i++) printf("   ");
936       switch (_iconStyle)
937       {
938       case NAME_ONLY: printf("IconStyle : NAME_ONLY\n"); break;
939       case LARGE_ICON: printf("IconStyle : LARGE_ICON\n"); break;
940       case SMALL_ICON: printf("IconStyle : SMALL_ICON\n"); break;
941       case DETAILS: printf("IconStyle : DETAILS\n"); break;
942       }
943       for (i = -1; i <= level; i++) printf("   ");
944       printf("Number Children = %d\n",  _numChildren);
945     }
946 }
947
948 // Dump object hierarchy to stdout
949 void BaseUI::DumpHierarchy(boolean verbose, int level)
950 {
951    Dump(verbose, level);
952
953    int i;
954    for (i = 0; i < _numChildren; i++)
955       _children[i]->DumpHierarchy(verbose, level + 1);
956 }
957
958 void BaseUI::AddTimeOut(TimeOutCallback timeoutCB, void *data, long interval)
959 {
960    if (timeoutCB)
961     {
962       if (data)
963          SetAddTimeOut(timeoutCB, data, interval);
964       else
965          SetAddTimeOut(timeoutCB, this, interval);
966     }
967 }
968
969 int BaseUI::MicroSleep(long usecs)
970 {
971    struct timeval timeoutVal;
972    timeoutVal.tv_sec = usecs / 1000000;
973    timeoutVal.tv_usec = usecs & 1000000;
974
975    fd_set rdmask;
976    fd_set wrmask;
977    fd_set exmask;
978    FD_ZERO(&rdmask);
979    FD_ZERO(&wrmask);
980    FD_ZERO(&exmask);
981
982    return select(0,&rdmask,&wrmask,&exmask,&timeoutVal);
983 }
984
985 // DEBUG STUFF
986
987 #ifdef DEBUG
988
989 int BaseUI::indent = 0;
990 boolean BaseUI::trace_calls = false;
991
992 static char * make_header_buffer(int indent)
993 {
994    static char header_buffer[1024];
995    static char *leading_chars="1234567890abcdefghijklmnop";
996    int indx;
997    char c;
998
999    header_buffer[0] = '\0';
1000
1001    for (indx = 0 ; indx < indent; indx++)
1002     {
1003       c = leading_chars[indx];
1004       header_buffer[2*indx] = leading_chars[indx];
1005       header_buffer[2*indx +1] = ' ';
1006     }
1007
1008    header_buffer[2*indx] = '\0';
1009
1010    return(header_buffer);
1011 }
1012
1013 void BaseUI::EnterFunction(char *FunctionName)
1014 {
1015    char *format_buffer = new char[1024];
1016    char *header_buffer;
1017
1018    if (trace_calls)
1019     {
1020       header_buffer = make_header_buffer(indent);
1021       sprintf(format_buffer,"%s>: %%s  %d ",header_buffer,indent);
1022       fprintf(stderr,format_buffer,FunctionName);
1023       indent++;
1024     }
1025    delete [] format_buffer;
1026 }
1027
1028 void BaseUI::LeaveFunction(char *FunctionName)
1029 {
1030    char *format_buffer = new char[1024];
1031    char *header_buffer;
1032
1033    if (trace_calls)
1034     {
1035       indent--;
1036       header_buffer = make_header_buffer(indent);
1037       sprintf(format_buffer,"%s<: %%s  %d ",header_buffer,indent);
1038       fprintf(stderr,format_buffer,FunctionName);
1039     }
1040    delete [] format_buffer;
1041 }
1042 #endif // DEBUG