1041 lines
24 KiB
C
1041 lines
24 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $TOG: BaseUI.C /main/10 1998/07/24 16:14:23 mgreess $ */
|
|
/* *
|
|
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
|
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
|
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
|
* (c) Copyright 1993, 1994 Novell, Inc. *
|
|
*/
|
|
|
|
#include "BaseUI.h"
|
|
|
|
#ifdef NO_REGCOMP
|
|
#include <ctype.h>
|
|
#if defined(SVR4) || defined(SYSV)
|
|
#include <libgen.h>
|
|
#endif
|
|
#else
|
|
#include <regex.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#if defined(__linux__)
|
|
#include <sys/time.h>
|
|
#else
|
|
#include <sys/select.h>
|
|
#endif /* linux */
|
|
#ifdef _AIX
|
|
#include <strings.h> /* need to get bzero defined */
|
|
#endif /* _AIX */
|
|
|
|
#if defined(aix)
|
|
extern "C"
|
|
{
|
|
extern int strcasecmp(const char *, const char *);
|
|
}
|
|
#endif
|
|
|
|
#define IsContainer(p) (p->UIClass() == CONTAINER)
|
|
|
|
#ifdef DEBUG
|
|
#define PrintObject() if (trace_calls) fprintf(stderr, " %s\n", _name);
|
|
#else
|
|
#define PrintObject()
|
|
#endif
|
|
|
|
int BaseUI::_UniqueID = 1;
|
|
|
|
BaseUI::BaseUI(BaseUI *parent,
|
|
const char *name,
|
|
const char *category)
|
|
{
|
|
EnterFunction("BaseUI::BaseUI");
|
|
_id = _UniqueID++;
|
|
_name = STRDUP(name);
|
|
PrintObject();
|
|
|
|
_category = STRDUP(category);
|
|
if (parent)
|
|
{
|
|
_viewStyle = parent->_viewStyle;
|
|
_iconStyle = parent->_iconStyle;
|
|
_visible = parent->_visible;
|
|
_active = parent->_active;
|
|
}
|
|
else
|
|
{
|
|
_viewStyle = GRID;
|
|
_iconStyle = LARGE_ICON;
|
|
_visible = true;
|
|
_active = true;
|
|
}
|
|
_update_message = NULL;
|
|
_selected = false;
|
|
_parent = parent;
|
|
_children = NULL;
|
|
_numChildren = 0;
|
|
_allChildren = NULL;
|
|
_numAllChildren = 0;
|
|
_has_been_opened = false;
|
|
_opened = false;
|
|
AddToParent();
|
|
AddToParentContainer();
|
|
BaseUI *p = _parent;
|
|
while (p && !IsContainer(p))
|
|
{
|
|
p->NotifyCreate(this);
|
|
p = p->_parent;
|
|
}
|
|
if (p && IsContainer(p))
|
|
p->NotifyCreate(this);
|
|
|
|
LeaveFunction("BaseUI::BaseUI");
|
|
PrintObject();
|
|
}
|
|
|
|
BaseUI::~BaseUI()
|
|
{
|
|
EnterFunction("BaseUI::~BaseUI()");
|
|
PrintObject();
|
|
|
|
BaseUI *p = _parent;
|
|
|
|
DeleteChildren();
|
|
DeleteFromParent();
|
|
DeleteFromParentContainer();
|
|
|
|
while (p)
|
|
{
|
|
if (IsContainer(p))
|
|
{
|
|
if (p->UISubClass() == ICON_LIST ||
|
|
p->UISubClass() == SCROLLED_ICON_LIST)
|
|
break;
|
|
if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
|
|
break;
|
|
}
|
|
p->NotifyDelete(this);
|
|
p = p->_parent;
|
|
}
|
|
if (p && IsContainer(p))
|
|
p->NotifyDelete(this);
|
|
|
|
delete(_update_message);
|
|
delete []_children;
|
|
delete []_allChildren;
|
|
|
|
LeaveFunction("BaseUI::~BaseUI()");
|
|
PrintObject();
|
|
|
|
free(_category);
|
|
free(_name);
|
|
}
|
|
|
|
void BaseUI::ContextualHelp()
|
|
{
|
|
DoContextualHelp();
|
|
}
|
|
|
|
void BaseUI::Refresh()
|
|
{
|
|
DoRefresh();
|
|
}
|
|
|
|
void BaseUI::ToFront()
|
|
{
|
|
DoToFront();
|
|
}
|
|
|
|
void BaseUI::Parent(BaseUI *new_parent)
|
|
{
|
|
if (SetParent(new_parent))
|
|
{
|
|
// need to write this
|
|
;
|
|
}
|
|
}
|
|
|
|
void BaseUI::Open(boolean flag)
|
|
{
|
|
if (SetOpen(flag))
|
|
{
|
|
_has_been_opened = true;
|
|
_opened = flag;
|
|
BaseUI *p = _parent;
|
|
while (p && !IsContainer(p))
|
|
{
|
|
p->NotifyOpen(this);
|
|
p = p->_parent;
|
|
}
|
|
if (p && IsContainer(p))
|
|
p->NotifyOpen(this);
|
|
}
|
|
}
|
|
|
|
void BaseUI::AddToParent()
|
|
{
|
|
if (!_parent)
|
|
return;
|
|
|
|
BaseUI **new_children;
|
|
int i;
|
|
|
|
new_children = new BaseUI*[_parent->_numChildren + 1];
|
|
for (i = 0; i < _parent->_numChildren; i++)
|
|
new_children[i] = _parent->_children[i];
|
|
|
|
delete []_parent->_children;
|
|
_parent->_children = new_children;
|
|
_parent->_children[_parent->_numChildren] = this;
|
|
|
|
_parent->_numChildren++;
|
|
}
|
|
|
|
void BaseUI::DeleteFromParent()
|
|
{
|
|
if (!_parent)
|
|
return;
|
|
|
|
BaseUI **new_children;
|
|
int i, index;
|
|
|
|
index = 0;
|
|
new_children = new BaseUI*[_parent->_numChildren - 1];
|
|
for (i = 0; i < _parent->_numChildren; i++)
|
|
if (_parent->_children[i] != this)
|
|
new_children[index++] = _parent->_children[i];
|
|
|
|
delete []_parent->_children;
|
|
_parent->_children = new_children;
|
|
|
|
_parent->_numChildren--;
|
|
}
|
|
|
|
void BaseUI::DeleteChildren()
|
|
{
|
|
EnterFunction("BaseUI::DeleteChildren()");
|
|
PrintObject();
|
|
|
|
if (_numChildren)
|
|
{
|
|
BaseUI **kids = new BaseUI*[_numChildren];
|
|
int i, j, n = _numChildren;
|
|
// Save children first before deleting a child since the destructor
|
|
// updates the _children variable
|
|
for (i = 0; i < n; i++)
|
|
kids[i] = _children[i];
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
for (j = 0; j < _numChildren; j++)
|
|
if (_children[j] == kids[i])
|
|
{
|
|
delete kids[i];
|
|
break;
|
|
}
|
|
}
|
|
delete []kids;
|
|
}
|
|
LeaveFunction("BaseUI::DeleteChildren()");
|
|
PrintObject();
|
|
}
|
|
|
|
BaseUI * BaseUI::ContainerParent()
|
|
{
|
|
BaseUI *parent = this;
|
|
|
|
while (parent && !IsContainer(parent))
|
|
parent = parent->_parent;
|
|
|
|
return parent;
|
|
}
|
|
|
|
void BaseUI::AddToParentContainer()
|
|
{
|
|
BaseUI *parent;
|
|
|
|
if (!(parent = ContainerParent()))
|
|
return;
|
|
|
|
BaseUI **new_children;
|
|
int i;
|
|
|
|
new_children = new BaseUI*[parent->_numAllChildren + 1];
|
|
for (i = 0; i < parent->_numAllChildren; i++)
|
|
new_children[i] = parent->_allChildren[i];
|
|
|
|
delete []parent->_allChildren;
|
|
parent->_allChildren = new_children;
|
|
parent->_allChildren[parent->_numAllChildren] = this;
|
|
|
|
parent->_numAllChildren++;
|
|
}
|
|
|
|
void BaseUI::DeleteFromParentContainer()
|
|
{
|
|
BaseUI *parent;
|
|
|
|
if (!(parent = ContainerParent()))
|
|
return;
|
|
|
|
BaseUI **new_children;
|
|
int i, index;
|
|
|
|
index = 0;
|
|
new_children = new BaseUI*[parent->_numAllChildren - 1];
|
|
for (i = 0; i < parent->_numAllChildren; i++)
|
|
if (parent->_allChildren[i] != this)
|
|
new_children[index++] = parent->_allChildren[i];
|
|
|
|
delete []parent->_allChildren;
|
|
parent->_allChildren = new_children;
|
|
|
|
parent->_numAllChildren--;
|
|
}
|
|
|
|
boolean BaseUI::HandleHelpRequest()
|
|
{
|
|
BaseUI *parent = _parent;
|
|
while (parent && parent->HandleHelpRequest() == false)
|
|
parent = parent->_parent;
|
|
return true;
|
|
}
|
|
|
|
void BaseUI::SetVisible(boolean flag)
|
|
{
|
|
if (SetVisiblity(flag))
|
|
{
|
|
_visible = flag;
|
|
BaseUI *p = _parent;
|
|
while (p)
|
|
{
|
|
if (IsContainer(p))
|
|
{
|
|
if (p->UISubClass() == ICON_LIST ||
|
|
p->UISubClass() == SCROLLED_ICON_LIST)
|
|
break;
|
|
if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
|
|
break;
|
|
}
|
|
p->NotifyVisiblity(this);
|
|
p = p->_parent;
|
|
}
|
|
if (p && IsContainer(p))
|
|
p->NotifyVisiblity(this);
|
|
}
|
|
}
|
|
|
|
// Set visiblity, calls derived function SetVisiblity
|
|
void BaseUI::Visible(boolean flag)
|
|
{
|
|
if (UIClass() != CONTAINER &&
|
|
UIClass() != MAIN_WINDOW &&
|
|
UIClass() != DIALOG &&
|
|
UIClass() != APPLICATION)
|
|
{
|
|
int i;
|
|
SetVisible(flag);
|
|
for (i = 0; i < _numChildren; i++)
|
|
if (!IsContainer(_children[i]))
|
|
_children[i]->Visible(flag);
|
|
}
|
|
else
|
|
SetVisible(flag);
|
|
}
|
|
|
|
// Set sensitivity, calls derived function SetActivity
|
|
void BaseUI::Active(boolean flag)
|
|
{
|
|
if (UIClass() != CONTAINER)
|
|
{
|
|
int i;
|
|
if (flag == true)
|
|
{
|
|
if (SetActivity(flag))
|
|
_active = flag;
|
|
for (i = 0; i < _numChildren; i++)
|
|
if (!IsContainer(_children[i]))
|
|
_children[i]->Active(flag);
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < _numChildren; i++)
|
|
if (!IsContainer(_children[i]))
|
|
_children[i]->Active(flag);
|
|
if (SetActivity(flag))
|
|
_active = flag;
|
|
}
|
|
}
|
|
else if (SetActivity(flag))
|
|
_active = flag;
|
|
}
|
|
|
|
// Set view, calls derived function SetIcon
|
|
void BaseUI::ContainerView(ViewStyle viewStyle)
|
|
{
|
|
if (UIClass() == CONTAINER)
|
|
{
|
|
int i;
|
|
for (i = 0; i < _numAllChildren; i++)
|
|
if (!IsContainer(_allChildren[i]))
|
|
_allChildren[i]->ContainerView(viewStyle);
|
|
}
|
|
_viewStyle = viewStyle;
|
|
}
|
|
|
|
// Set view, calls derived function SetIcon
|
|
void BaseUI::IconView(IconStyle iconStyle)
|
|
{
|
|
if (UIClass() == CONTAINER)
|
|
{
|
|
int i;
|
|
for (i = 0; i < _numAllChildren; i++)
|
|
if (IsContainer(_allChildren[i]))
|
|
{
|
|
if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
|
|
_allChildren[i]->IconView(iconStyle);
|
|
}
|
|
else
|
|
_allChildren[i]->IconView(iconStyle);
|
|
}
|
|
if (SetIcon(iconStyle))
|
|
_iconStyle = iconStyle;
|
|
}
|
|
|
|
// Set selected status, calls derived function SetSelected
|
|
void BaseUI::Selected(boolean flag)
|
|
{
|
|
if (SetSelected(flag))
|
|
{
|
|
_selected = flag;
|
|
BaseUI *p = _parent;
|
|
while (p)
|
|
{
|
|
if (IsContainer(p))
|
|
{
|
|
if (p->UISubClass() == ICON_LIST ||
|
|
p->UISubClass() == SCROLLED_ICON_LIST)
|
|
break;
|
|
if (!IsContainer(p->_parent) && p->_parent->UIClass() != ICON)
|
|
break;
|
|
}
|
|
p->NotifySelected(this);
|
|
p = p->_parent;
|
|
}
|
|
if (p && IsContainer(p))
|
|
p->NotifySelected(this);
|
|
}
|
|
}
|
|
|
|
// Set name, calls derived function SetCategory
|
|
void BaseUI::Category(char *category)
|
|
{
|
|
if (SetCategory(category))
|
|
{
|
|
free(_category);
|
|
_category = STRDUP(category);
|
|
}
|
|
}
|
|
|
|
// Set name, calls derived function SetName
|
|
void BaseUI::Name(char *name)
|
|
{
|
|
if (SetName(name))
|
|
{
|
|
free(_name);
|
|
_name = STRDUP(name);
|
|
}
|
|
}
|
|
|
|
// Select/UnSelected all immediate children
|
|
void BaseUI::SelectAll(boolean select_status)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < _numChildren; i++)
|
|
{
|
|
_children[i]->Selected(select_status);
|
|
if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
|
|
_children[i]->SelectAll(select_status);
|
|
}
|
|
|
|
}
|
|
|
|
// Select/UnSelected all children, and their children, etc...
|
|
void BaseUI::SelectAllDescendants(boolean select_status)
|
|
{
|
|
int i;
|
|
|
|
if (UIClass() == CONTAINER)
|
|
for (i = 0; i < _numChildren; i++)
|
|
_children[i]->Selected(select_status);
|
|
else
|
|
for (i = 0; i < _numChildren; i++)
|
|
{
|
|
_children[i]->Selected(select_status);
|
|
if (!IsContainer(_children[i]))
|
|
_children[i]->SelectAllDescendants(select_status);
|
|
}
|
|
}
|
|
|
|
// Open/Close all children, and their children, etc...
|
|
void BaseUI::OpenAllDescendants(boolean opened)
|
|
{
|
|
int i;
|
|
|
|
if (UIClass() == CONTAINER)
|
|
for (i = 0; i < _numChildren; i++)
|
|
_children[i]->Open(opened);
|
|
else
|
|
{
|
|
if (opened)
|
|
for (i = 0; i < _numChildren; i++)
|
|
{
|
|
_children[i]->Open(opened);
|
|
if (!IsContainer(_children[i]))
|
|
_children[i]->OpenAllDescendants(opened);
|
|
}
|
|
else
|
|
for (i = 0; i < _numChildren; i++)
|
|
{
|
|
if (!IsContainer(_children[i]))
|
|
_children[i]->OpenAllDescendants(opened);
|
|
_children[i]->Open(opened);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BaseUI::Selection(int *n_items,
|
|
BaseUI ***items)
|
|
{
|
|
if (UIClass() != CONTAINER)
|
|
{
|
|
if (items)
|
|
*items = NULL;
|
|
*n_items = 0;
|
|
return;
|
|
}
|
|
|
|
boolean isScrolledList;
|
|
if (UISubClass() == SCROLLED_ICON_LIST || UISubClass() == ICON_LIST)
|
|
isScrolledList = true;
|
|
else
|
|
isScrolledList = false;
|
|
|
|
int i;
|
|
*n_items = 0;
|
|
for (i = 0; i < _numAllChildren; i++)
|
|
if (!IsContainer(_allChildren[i]) && _allChildren[i]->Selected())
|
|
(*n_items)++;
|
|
else if (IsContainer(_allChildren[i]) && isScrolledList)
|
|
{
|
|
int tmp;
|
|
_allChildren[i]->Selection(&tmp);
|
|
(*n_items) += tmp;
|
|
}
|
|
|
|
if (!items)
|
|
return;
|
|
|
|
if (*n_items == 0)
|
|
*items = NULL;
|
|
else
|
|
{
|
|
BaseUI **list = new BaseUI*[*n_items];
|
|
*n_items = 0;
|
|
for (i = 0; i < _numAllChildren; i++)
|
|
if (!IsContainer(_allChildren[i]) && _allChildren[i]->Selected())
|
|
list[(*n_items)++] = _allChildren[i];
|
|
else if (IsContainer(_allChildren[i]) && isScrolledList)
|
|
{
|
|
int tmp;
|
|
BaseUI **tmp1;
|
|
_allChildren[i]->Selection(&tmp, &tmp1);
|
|
int j, k = *n_items + tmp;
|
|
for (j = *n_items; j < k; j++)
|
|
list[(*n_items)++] = tmp1[j];
|
|
delete []tmp1;
|
|
}
|
|
|
|
*items = list;
|
|
}
|
|
}
|
|
|
|
int BaseUI::NumContainerChildren()
|
|
{
|
|
BaseUI *container = ContainerParent();
|
|
|
|
if (container)
|
|
return container->_numAllChildren;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
BaseUI ** BaseUI::ContainerChildren()
|
|
{
|
|
BaseUI *container = ContainerParent();
|
|
|
|
if (container)
|
|
return container->_allChildren;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
int BaseUI::NumSiblings()
|
|
{
|
|
if (_parent)
|
|
return _parent->_numChildren;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
BaseUI ** BaseUI::Siblings()
|
|
{
|
|
if (_parent)
|
|
return _parent->_children;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
void BaseUI::_Find(void *pattern, int depth, int *n_matches,
|
|
BaseUI ***matches, SelectProc select_proc,
|
|
boolean regular_expression, boolean case_sensitive,
|
|
boolean find_by_name, int cur_depth)
|
|
{
|
|
if (depth != 0 && cur_depth == depth)
|
|
return;
|
|
|
|
BaseUI **children = _children;
|
|
int n_children = _numChildren;
|
|
int i;
|
|
for (i = 0; i < n_children; i++)
|
|
{
|
|
int tmp = 0;
|
|
BaseUI **tmp1 = NULL;
|
|
children[i]->_Find(pattern, depth, &tmp, &tmp1, select_proc,
|
|
regular_expression, case_sensitive,
|
|
find_by_name, cur_depth + 1);
|
|
if (tmp)
|
|
{
|
|
int j;
|
|
if (*n_matches == 0)
|
|
*matches = (BaseUI **)malloc(sizeof(BaseUI **) * tmp);
|
|
else
|
|
*matches = (BaseUI **)realloc(*matches, sizeof(BaseUI **) *
|
|
(*n_matches + tmp));
|
|
for (j = 0; j < tmp; j++)
|
|
(*matches)[(*n_matches)++] = tmp1[j];
|
|
free(tmp1);
|
|
tmp = 0;
|
|
}
|
|
char *value;
|
|
int is_match;
|
|
if (find_by_name)
|
|
value = children[i]->_name;
|
|
else
|
|
value = children[i]->_category;
|
|
if (value)
|
|
{
|
|
if (case_sensitive)
|
|
{
|
|
if (regular_expression)
|
|
#ifdef NO_REGCOMP
|
|
is_match = (int)regex((char *)pattern, value);
|
|
#else
|
|
is_match = !regexec((regex_t *)pattern, value, (size_t)0,NULL,0);
|
|
#endif
|
|
else
|
|
is_match = !strcmp(value, (char *)pattern);
|
|
}
|
|
else
|
|
{
|
|
if (regular_expression)
|
|
#ifdef NO_REGCOMP
|
|
is_match = (int)regex((char *)pattern, value);
|
|
#else
|
|
is_match = !regexec((regex_t *)pattern, value, (size_t)0,NULL,0);
|
|
#endif
|
|
else
|
|
is_match = !strcasecmp(value, (char *)pattern);
|
|
}
|
|
}
|
|
else
|
|
is_match = 0;
|
|
|
|
if (is_match && select_proc)
|
|
is_match = (*select_proc)(children[i]);
|
|
if (is_match)
|
|
{
|
|
if (*n_matches == 0)
|
|
*matches = (BaseUI **)malloc(sizeof(BaseUI **));
|
|
else
|
|
*matches = (BaseUI **)realloc(*matches, sizeof(BaseUI **) *
|
|
(*n_matches + 1));
|
|
(*matches)[(*n_matches)++] = children[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
BaseUI *BaseUI::_FindBy(char *pattern, int depth, int *n_matches,
|
|
BaseUI ***matches, SelectProc select_proc,
|
|
boolean regular_expression, boolean case_sensitive,
|
|
boolean find_by_name)
|
|
{
|
|
void *reg_expr = pattern;
|
|
#ifdef NO_REGCOMP
|
|
if (regular_expression)
|
|
{
|
|
if (case_sensitive == false)
|
|
{
|
|
char *new_pattern = new char[(strlen(pattern) * 4) + 1];
|
|
int i = 0;
|
|
char *s;
|
|
for (s = pattern; *s; s++)
|
|
{
|
|
if (isalpha((int)*s))
|
|
{
|
|
new_pattern[i++] = '[';
|
|
new_pattern[i++] = *s;
|
|
if (islower(*s))
|
|
new_pattern[i++] = (char)toupper((int)*s);
|
|
else
|
|
new_pattern[i++] = (char)tolower((int)*s);
|
|
new_pattern[i++] = ']';
|
|
}
|
|
else
|
|
new_pattern[i++] = *s;
|
|
}
|
|
new_pattern[i] = '\0';
|
|
reg_expr = regcmp(new_pattern, (char *)NULL);
|
|
delete new_pattern;
|
|
}
|
|
else
|
|
reg_expr = regcmp(pattern, (char *)NULL);
|
|
}
|
|
#else
|
|
regex_t re;
|
|
if (regular_expression)
|
|
{
|
|
int compile_flags;
|
|
if (case_sensitive)
|
|
compile_flags = REG_NOSUB;
|
|
else
|
|
compile_flags = REG_ICASE|REG_NOSUB;
|
|
if (regcomp(&re, pattern, compile_flags) != 0)
|
|
reg_expr = NULL;
|
|
else
|
|
reg_expr = &re;
|
|
}
|
|
#endif
|
|
if (!reg_expr)
|
|
{
|
|
if (n_matches)
|
|
*n_matches = 0;
|
|
if (matches)
|
|
matches = NULL;
|
|
return NULL;
|
|
}
|
|
BaseUI **_matches = NULL;
|
|
int _n_matches = 0;
|
|
_Find(reg_expr, depth, &_n_matches, &_matches, select_proc,
|
|
regular_expression, case_sensitive, find_by_name, 0);
|
|
|
|
#ifndef NO_REGCOMP
|
|
if (regular_expression)
|
|
regfree(&re);
|
|
#endif
|
|
if (n_matches)
|
|
*n_matches = _n_matches;
|
|
if (matches)
|
|
{
|
|
*matches = _matches;
|
|
if (_n_matches)
|
|
return _matches[0];
|
|
else
|
|
return NULL;
|
|
}
|
|
else if (_n_matches)
|
|
{
|
|
BaseUI *a_match = _matches[0];
|
|
free(_matches);
|
|
return a_match;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BaseUI *BaseUI::FindByName(char *pattern, int depth, int *n_matches,
|
|
BaseUI ***matches, SelectProc select_proc,
|
|
boolean regular_expression, boolean case_sensitive)
|
|
{
|
|
return _FindBy(pattern, depth, n_matches, matches, select_proc,
|
|
regular_expression, case_sensitive, true);
|
|
}
|
|
|
|
BaseUI *BaseUI::FindByCategory(char *pattern, int depth, int *n_matches,
|
|
BaseUI ***matches, SelectProc select_proc,
|
|
boolean regular_expression,
|
|
boolean case_sensitive)
|
|
{
|
|
return _FindBy(pattern, depth, n_matches, matches, select_proc,
|
|
regular_expression, case_sensitive, false);
|
|
}
|
|
|
|
void BaseUI::OrderByName(boolean /*flag*/)
|
|
{
|
|
}
|
|
|
|
void BaseUI::GroupByCategory(boolean /*flag*/)
|
|
{
|
|
}
|
|
|
|
// Calls derived class's SetOrder function
|
|
void BaseUI::Order(int new_position)
|
|
{
|
|
if (!_parent || new_position < 0 || new_position > _parent->_numChildren)
|
|
return;
|
|
|
|
int current_position = Order();
|
|
if (new_position == current_position)
|
|
return;
|
|
|
|
BaseUI **children = _parent->_children;
|
|
int i;
|
|
if (current_position < new_position)
|
|
for (i = current_position; i < new_position; i++)
|
|
children[i] = children[i + 1];
|
|
else
|
|
for (i = current_position; i > new_position; i--)
|
|
children[i] = children[i - 1];
|
|
children[new_position] = this;
|
|
(void) SetOrder(new_position);
|
|
}
|
|
|
|
int BaseUI::Order()
|
|
{
|
|
int i = 0;
|
|
if (_parent)
|
|
{
|
|
for (i = 0; i < _parent->_numChildren; i++)
|
|
if (_parent->_children[i] == this)
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
boolean BaseUI::IsVisible()
|
|
{
|
|
return DoIsVisible();
|
|
}
|
|
|
|
void BaseUI::MakeVisible()
|
|
{
|
|
if (_visible == false)
|
|
return;
|
|
BaseUI *parent = Parent();
|
|
if (parent)
|
|
parent->MakeVisible();
|
|
if (_visible && parent)
|
|
DoMakeVisible();
|
|
}
|
|
|
|
void BaseUI::BeginUpdate()
|
|
{
|
|
_update = false;
|
|
DoBeginUpdate();
|
|
}
|
|
|
|
void BaseUI::EndUpdate()
|
|
{
|
|
_update = true;
|
|
DoEndUpdate();
|
|
}
|
|
|
|
void BaseUI::UpdateMessage(const char *message)
|
|
{
|
|
free(_update_message);
|
|
_update_message = STRDUP(message);
|
|
DoUpdateMessage(_update_message);
|
|
}
|
|
|
|
boolean BaseUI::ObjectExists(int unique_id)
|
|
{
|
|
int i;
|
|
boolean found = false;
|
|
for (i = 0; i < _numChildren; i++)
|
|
{
|
|
BaseUI *child = _children[i];
|
|
if (unique_id == _children[i]->_id)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
else if (found = _children[i]->ObjectExists(unique_id))
|
|
break;
|
|
}
|
|
return found;
|
|
}
|
|
|
|
#define PrintBoolean(flag) flag ? "True" : "False"
|
|
|
|
// Dump object to stdout
|
|
void BaseUI::Dump(boolean verbose, int level)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < level; i++)
|
|
printf(" ");
|
|
printf("%s : %s\n", _name, UIClassName());
|
|
if (verbose)
|
|
{
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("Category : %s\n", _category ? _category : "");
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("HasBeenOpened : %s\n", PrintBoolean(_has_been_opened));
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("Opened : %s\n", PrintBoolean(_opened));
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("Visible : %s\n", PrintBoolean(_visible));
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("Active : %s\n", PrintBoolean(_active));
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("Selected : %s\n", PrintBoolean(_selected));
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
switch (_viewStyle)
|
|
{
|
|
case AS_PLACED: printf("ViewStyle : AS_PLACED\n"); break;
|
|
case GRID: printf("ViewStyle : GRID\n"); break;
|
|
case BROWSER: printf("ViewStyle : BROWSER\n"); break;
|
|
case TREE: printf("ViewStyle : TREE\n"); break;
|
|
case PROPERTIES: printf("ViewStyle : PROPERTIES\n"); break;
|
|
}
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
switch (_iconStyle)
|
|
{
|
|
case NAME_ONLY: printf("IconStyle : NAME_ONLY\n"); break;
|
|
case LARGE_ICON: printf("IconStyle : LARGE_ICON\n"); break;
|
|
case SMALL_ICON: printf("IconStyle : SMALL_ICON\n"); break;
|
|
case DETAILS: printf("IconStyle : DETAILS\n"); break;
|
|
}
|
|
for (i = -1; i <= level; i++) printf(" ");
|
|
printf("Number Children = %d\n", _numChildren);
|
|
}
|
|
}
|
|
|
|
// Dump object hierarchy to stdout
|
|
void BaseUI::DumpHierarchy(boolean verbose, int level)
|
|
{
|
|
Dump(verbose, level);
|
|
|
|
int i;
|
|
for (i = 0; i < _numChildren; i++)
|
|
_children[i]->DumpHierarchy(verbose, level + 1);
|
|
}
|
|
|
|
void BaseUI::AddTimeOut(TimeOutCallback timeoutCB, void *data, long interval)
|
|
{
|
|
if (timeoutCB)
|
|
{
|
|
if (data)
|
|
SetAddTimeOut(timeoutCB, data, interval);
|
|
else
|
|
SetAddTimeOut(timeoutCB, this, interval);
|
|
}
|
|
}
|
|
|
|
int BaseUI::MicroSleep(long usecs)
|
|
{
|
|
struct timeval timeoutVal;
|
|
timeoutVal.tv_sec = usecs / 1000000;
|
|
timeoutVal.tv_usec = usecs & 1000000;
|
|
|
|
fd_set rdmask;
|
|
fd_set wrmask;
|
|
fd_set exmask;
|
|
FD_ZERO(&rdmask);
|
|
FD_ZERO(&wrmask);
|
|
FD_ZERO(&exmask);
|
|
|
|
return select(0,&rdmask,&wrmask,&exmask,&timeoutVal);
|
|
}
|
|
|
|
// DEBUG STUFF
|
|
|
|
#ifdef DEBUG
|
|
|
|
int BaseUI::indent = 0;
|
|
boolean BaseUI::trace_calls = false;
|
|
|
|
static char * make_header_buffer(int indent)
|
|
{
|
|
static char header_buffer[1024];
|
|
static char *leading_chars="1234567890abcdefghijklmnop";
|
|
int indx;
|
|
char c;
|
|
|
|
header_buffer[0] = '\0';
|
|
|
|
for (indx = 0 ; indx < indent; indx++)
|
|
{
|
|
c = leading_chars[indx];
|
|
header_buffer[2*indx] = leading_chars[indx];
|
|
header_buffer[2*indx +1] = ' ';
|
|
}
|
|
|
|
header_buffer[2*indx] = '\0';
|
|
|
|
return(header_buffer);
|
|
}
|
|
|
|
void BaseUI::EnterFunction(char *FunctionName)
|
|
{
|
|
char *format_buffer = new char[1024];
|
|
char *header_buffer;
|
|
|
|
if (trace_calls)
|
|
{
|
|
header_buffer = make_header_buffer(indent);
|
|
sprintf(format_buffer,"%s>: %%s %d ",header_buffer,indent);
|
|
fprintf(stderr,format_buffer,FunctionName);
|
|
indent++;
|
|
}
|
|
delete [] format_buffer;
|
|
}
|
|
|
|
void BaseUI::LeaveFunction(char *FunctionName)
|
|
{
|
|
char *format_buffer = new char[1024];
|
|
char *header_buffer;
|
|
|
|
if (trace_calls)
|
|
{
|
|
indent--;
|
|
header_buffer = make_header_buffer(indent);
|
|
sprintf(format_buffer,"%s<: %%s %d ",header_buffer,indent);
|
|
fprintf(stderr,format_buffer,FunctionName);
|
|
}
|
|
delete [] format_buffer;
|
|
}
|
|
#endif // DEBUG
|