2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: BaseUI.C /main/10 1998/07/24 16:14:23 mgreess $ */
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. *
35 #if defined(SVR4) || defined(SYSV)
50 #include <sys/select.h>
53 #include <strings.h> /* need to get bzero defined */
59 extern int strcasecmp(const char *, const char *);
63 #define IsContainer(p) (p->UIClass() == CONTAINER)
66 #define PrintObject() if (trace_calls) fprintf(stderr, " %s\n", _name);
71 int BaseUI::_UniqueID = 1;
73 BaseUI::BaseUI(BaseUI *parent,
77 EnterFunction("BaseUI::BaseUI");
82 _category = STRDUP(category);
85 _viewStyle = parent->_viewStyle;
86 _iconStyle = parent->_iconStyle;
87 _visible = parent->_visible;
88 _active = parent->_active;
93 _iconStyle = LARGE_ICON;
97 _update_message = NULL;
104 _has_been_opened = false;
107 AddToParentContainer();
109 while (p && !IsContainer(p))
111 p->NotifyCreate(this);
114 if (p && IsContainer(p))
115 p->NotifyCreate(this);
117 LeaveFunction("BaseUI::BaseUI");
123 EnterFunction("BaseUI::~BaseUI()");
130 DeleteFromParentContainer();
136 if (p->UISubClass() == ICON_LIST ||
137 p->UISubClass() == SCROLLED_ICON_LIST)
139 if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
142 p->NotifyDelete(this);
145 if (p && IsContainer(p))
146 p->NotifyDelete(this);
148 delete(_update_message);
150 delete []_allChildren;
152 LeaveFunction("BaseUI::~BaseUI()");
159 void BaseUI::ContextualHelp()
164 void BaseUI::Refresh()
169 void BaseUI::ToFront()
174 void BaseUI::Parent(BaseUI *new_parent)
176 if (SetParent(new_parent))
178 // need to write this
183 void BaseUI::Open(boolean flag)
187 _has_been_opened = true;
190 while (p && !IsContainer(p))
195 if (p && IsContainer(p))
200 void BaseUI::AddToParent()
205 BaseUI **new_children;
208 new_children = new BaseUI*[_parent->_numChildren + 1];
209 for (i = 0; i < _parent->_numChildren; i++)
210 new_children[i] = _parent->_children[i];
212 delete []_parent->_children;
213 _parent->_children = new_children;
214 _parent->_children[_parent->_numChildren] = this;
216 _parent->_numChildren++;
219 void BaseUI::DeleteFromParent()
224 BaseUI **new_children;
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];
233 delete []_parent->_children;
234 _parent->_children = new_children;
236 _parent->_numChildren--;
239 void BaseUI::DeleteChildren()
241 EnterFunction("BaseUI::DeleteChildren()");
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++)
254 for (j = 0; j < _numChildren; j++)
255 if (_children[j] == kids[i])
263 LeaveFunction("BaseUI::DeleteChildren()");
267 BaseUI * BaseUI::ContainerParent()
269 BaseUI *parent = this;
271 while (parent && !IsContainer(parent))
272 parent = parent->_parent;
277 void BaseUI::AddToParentContainer()
281 if (!(parent = ContainerParent()))
284 BaseUI **new_children;
287 new_children = new BaseUI*[parent->_numAllChildren + 1];
288 for (i = 0; i < parent->_numAllChildren; i++)
289 new_children[i] = parent->_allChildren[i];
291 delete []parent->_allChildren;
292 parent->_allChildren = new_children;
293 parent->_allChildren[parent->_numAllChildren] = this;
295 parent->_numAllChildren++;
298 void BaseUI::DeleteFromParentContainer()
302 if (!(parent = ContainerParent()))
305 BaseUI **new_children;
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];
314 delete []parent->_allChildren;
315 parent->_allChildren = new_children;
317 parent->_numAllChildren--;
320 boolean BaseUI::HandleHelpRequest()
322 BaseUI *parent = _parent;
323 while (parent && parent->HandleHelpRequest() == false)
324 parent = parent->_parent;
328 void BaseUI::SetVisible(boolean flag)
330 if (SetVisiblity(flag))
338 if (p->UISubClass() == ICON_LIST ||
339 p->UISubClass() == SCROLLED_ICON_LIST)
341 if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
344 p->NotifyVisiblity(this);
347 if (p && IsContainer(p))
348 p->NotifyVisiblity(this);
352 // Set visiblity, calls derived function SetVisiblity
353 void BaseUI::Visible(boolean flag)
355 if (UIClass() != CONTAINER &&
356 UIClass() != MAIN_WINDOW &&
357 UIClass() != DIALOG &&
358 UIClass() != APPLICATION)
362 for (i = 0; i < _numChildren; i++)
363 if (!IsContainer(_children[i]))
364 _children[i]->Visible(flag);
370 // Set sensitivity, calls derived function SetActivity
371 void BaseUI::Active(boolean flag)
373 if (UIClass() != CONTAINER)
378 if (SetActivity(flag))
380 for (i = 0; i < _numChildren; i++)
381 if (!IsContainer(_children[i]))
382 _children[i]->Active(flag);
386 for (i = 0; i < _numChildren; i++)
387 if (!IsContainer(_children[i]))
388 _children[i]->Active(flag);
389 if (SetActivity(flag))
393 else if (SetActivity(flag))
397 // Set view, calls derived function SetIcon
398 void BaseUI::ContainerView(ViewStyle viewStyle)
400 if (UIClass() == CONTAINER)
403 for (i = 0; i < _numAllChildren; i++)
404 if (!IsContainer(_allChildren[i]))
405 _allChildren[i]->ContainerView(viewStyle);
407 _viewStyle = viewStyle;
410 // Set view, calls derived function SetIcon
411 void BaseUI::IconView(IconStyle iconStyle)
413 if (UIClass() == CONTAINER)
416 for (i = 0; i < _numAllChildren; i++)
417 if (IsContainer(_allChildren[i]))
419 if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
420 _allChildren[i]->IconView(iconStyle);
423 _allChildren[i]->IconView(iconStyle);
425 if (SetIcon(iconStyle))
426 _iconStyle = iconStyle;
429 // Set selected status, calls derived function SetSelected
430 void BaseUI::Selected(boolean flag)
432 if (SetSelected(flag))
440 if (p->UISubClass() == ICON_LIST ||
441 p->UISubClass() == SCROLLED_ICON_LIST)
443 if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
446 p->NotifySelected(this);
449 if (p && IsContainer(p))
450 p->NotifySelected(this);
454 // Set name, calls derived function SetCategory
455 void BaseUI::Category(char *category)
457 if (SetCategory(category))
460 _category = STRDUP(category);
464 // Set name, calls derived function SetName
465 void BaseUI::Name(char *name)
470 _name = STRDUP(name);
474 // Select/UnSelected all immediate children
475 void BaseUI::SelectAll(boolean select_status)
479 for (i = 0; i < _numChildren; i++)
481 _children[i]->Selected(select_status);
482 if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
483 _children[i]->SelectAll(select_status);
488 // Select/UnSelected all children, and their children, etc...
489 void BaseUI::SelectAllDescendants(boolean select_status)
493 if (UIClass() == CONTAINER)
494 for (i = 0; i < _numChildren; i++)
495 _children[i]->Selected(select_status);
497 for (i = 0; i < _numChildren; i++)
499 _children[i]->Selected(select_status);
500 if (!IsContainer(_children[i]))
501 _children[i]->SelectAllDescendants(select_status);
505 // Open/Close all children, and their children, etc...
506 void BaseUI::OpenAllDescendants(boolean opened)
510 if (UIClass() == CONTAINER)
511 for (i = 0; i < _numChildren; i++)
512 _children[i]->Open(opened);
516 for (i = 0; i < _numChildren; i++)
518 _children[i]->Open(opened);
519 if (!IsContainer(_children[i]))
520 _children[i]->OpenAllDescendants(opened);
523 for (i = 0; i < _numChildren; i++)
525 if (!IsContainer(_children[i]))
526 _children[i]->OpenAllDescendants(opened);
527 _children[i]->Open(opened);
532 void BaseUI::Selection(int *n_items,
535 if (UIClass() != CONTAINER)
543 boolean isScrolledList;
544 if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
545 isScrolledList = true;
547 isScrolledList = false;
551 for (i = 0; i < _numAllChildren; i++)
552 if (!IsContainer(_allChildren[i]) && _allChildren[i]->Selected())
554 else if (IsContainer(_allChildren[i]) && isScrolledList)
557 _allChildren[i]->Selection(&tmp);
568 BaseUI **list = new BaseUI*[*n_items];
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)
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];
588 int BaseUI::NumContainerChildren()
590 BaseUI *container = ContainerParent();
593 return container->_numAllChildren;
598 BaseUI ** BaseUI::ContainerChildren()
600 BaseUI *container = ContainerParent();
603 return container->_allChildren;
608 int BaseUI::NumSiblings()
611 return _parent->_numChildren;
616 BaseUI ** BaseUI::Siblings()
619 return _parent->_children;
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)
629 if (depth != 0 && cur_depth == depth)
632 BaseUI **children = _children;
633 int n_children = _numChildren;
635 for (i = 0; i < n_children; i++)
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);
646 *matches = (BaseUI **)malloc(sizeof(BaseUI **) * tmp);
648 *matches = (BaseUI **)realloc(*matches, sizeof(BaseUI **) *
650 for (j = 0; j < tmp; j++)
651 (*matches)[(*n_matches)++] = tmp1[j];
658 value = children[i]->_name;
660 value = children[i]->_category;
665 if (regular_expression)
667 is_match = (int)regex((char *)pattern, value);
669 is_match = !regexec((regex_t *)pattern, value, (size_t)0,NULL,0);
672 is_match = !strcmp(value, (char *)pattern);
676 if (regular_expression)
678 is_match = (int)regex((char *)pattern, value);
680 is_match = !regexec((regex_t *)pattern, value, (size_t)0,NULL,0);
683 is_match = !strcasecmp(value, (char *)pattern);
689 if (is_match && select_proc)
690 is_match = (*select_proc)(children[i]);
694 *matches = (BaseUI **)malloc(sizeof(BaseUI **));
696 *matches = (BaseUI **)realloc(*matches, sizeof(BaseUI **) *
698 (*matches)[(*n_matches)++] = children[i];
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)
708 void *reg_expr = pattern;
710 if (regular_expression)
712 if (case_sensitive == false)
714 char *new_pattern = new char[(strlen(pattern) * 4) + 1];
717 for (s = pattern; *s; s++)
719 if (isalpha((int)*s))
721 new_pattern[i++] = '[';
722 new_pattern[i++] = *s;
724 new_pattern[i++] = (char)toupper((int)*s);
726 new_pattern[i++] = (char)tolower((int)*s);
727 new_pattern[i++] = ']';
730 new_pattern[i++] = *s;
732 new_pattern[i] = '\0';
733 reg_expr = regcmp(new_pattern, (char *)NULL);
737 reg_expr = regcmp(pattern, (char *)NULL);
741 if (regular_expression)
745 compile_flags = REG_NOSUB;
747 compile_flags = REG_ICASE|REG_NOSUB;
748 if (regcomp(&re, pattern, compile_flags) != 0)
762 BaseUI **_matches = NULL;
764 _Find(reg_expr, depth, &_n_matches, &_matches, select_proc,
765 regular_expression, case_sensitive, find_by_name, 0);
768 if (regular_expression)
772 *n_matches = _n_matches;
783 BaseUI *a_match = _matches[0];
790 BaseUI *BaseUI::FindByName(char *pattern, int depth, int *n_matches,
791 BaseUI ***matches, SelectProc select_proc,
792 boolean regular_expression, boolean case_sensitive)
794 return _FindBy(pattern, depth, n_matches, matches, select_proc,
795 regular_expression, case_sensitive, true);
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)
803 return _FindBy(pattern, depth, n_matches, matches, select_proc,
804 regular_expression, case_sensitive, false);
807 void BaseUI::OrderByName(boolean /*flag*/)
811 void BaseUI::GroupByCategory(boolean /*flag*/)
815 // Calls derived class's SetOrder function
816 void BaseUI::Order(int new_position)
818 if (!_parent || new_position < 0 || new_position > _parent->_numChildren)
821 int current_position = Order();
822 if (new_position == current_position)
825 BaseUI **children = _parent->_children;
827 if (current_position < new_position)
828 for (i = current_position; i < new_position; i++)
829 children[i] = children[i + 1];
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);
842 for (i = 0; i < _parent->_numChildren; i++)
843 if (_parent->_children[i] == this)
849 boolean BaseUI::IsVisible()
851 return DoIsVisible();
854 void BaseUI::MakeVisible()
856 if (_visible == false)
858 BaseUI *parent = Parent();
860 parent->MakeVisible();
861 if (_visible && parent)
865 void BaseUI::BeginUpdate()
871 void BaseUI::EndUpdate()
877 void BaseUI::UpdateMessage(const char *message)
879 free(_update_message);
880 _update_message = STRDUP(message);
881 DoUpdateMessage(_update_message);
884 boolean BaseUI::ObjectExists(int unique_id)
887 boolean found = false;
888 for (i = 0; i < _numChildren; i++)
890 BaseUI *child = _children[i];
891 if (unique_id == _children[i]->_id)
896 else if (found = _children[i]->ObjectExists(unique_id))
902 #define PrintBoolean(flag) flag ? "True" : "False"
904 // Dump object to stdout
905 void BaseUI::Dump(boolean verbose, int level)
909 for (i = 0; i < level; i++)
911 printf("%s : %s\n", _name, UIClassName());
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(" ");
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;
935 for (i = -1; i <= level; i++) printf(" ");
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;
943 for (i = -1; i <= level; i++) printf(" ");
944 printf("Number Children = %d\n", _numChildren);
948 // Dump object hierarchy to stdout
949 void BaseUI::DumpHierarchy(boolean verbose, int level)
951 Dump(verbose, level);
954 for (i = 0; i < _numChildren; i++)
955 _children[i]->DumpHierarchy(verbose, level + 1);
958 void BaseUI::AddTimeOut(TimeOutCallback timeoutCB, void *data, long interval)
963 SetAddTimeOut(timeoutCB, data, interval);
965 SetAddTimeOut(timeoutCB, this, interval);
969 int BaseUI::MicroSleep(long usecs)
971 struct timeval timeoutVal;
972 timeoutVal.tv_sec = usecs / 1000000;
973 timeoutVal.tv_usec = usecs & 1000000;
982 return select(0,&rdmask,&wrmask,&exmask,&timeoutVal);
989 int BaseUI::indent = 0;
990 boolean BaseUI::trace_calls = false;
992 static char * make_header_buffer(int indent)
994 static char header_buffer[1024];
995 static char *leading_chars="1234567890abcdefghijklmnop";
999 header_buffer[0] = '\0';
1001 for (indx = 0 ; indx < indent; indx++)
1003 c = leading_chars[indx];
1004 header_buffer[2*indx] = leading_chars[indx];
1005 header_buffer[2*indx +1] = ' ';
1008 header_buffer[2*indx] = '\0';
1010 return(header_buffer);
1013 void BaseUI::EnterFunction(char *FunctionName)
1015 char *format_buffer = new char[1024];
1016 char *header_buffer;
1020 header_buffer = make_header_buffer(indent);
1021 sprintf(format_buffer,"%s>: %%s %d ",header_buffer,indent);
1022 fprintf(stderr,format_buffer,FunctionName);
1025 delete [] format_buffer;
1028 void BaseUI::LeaveFunction(char *FunctionName)
1030 char *format_buffer = new char[1024];
1031 char *header_buffer;
1036 header_buffer = make_header_buffer(indent);
1037 sprintf(format_buffer,"%s<: %%s %d ",header_buffer,indent);
1038 fprintf(stderr,format_buffer,FunctionName);
1040 delete [] format_buffer;