mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
594 lines
17 KiB
C++
594 lines
17 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// dlgAggregate.cpp - Aggregate properties dialog
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
|
|
// App headers
|
|
#include "pgAdmin3.h"
|
|
#include "utils/misc.h"
|
|
#include "utils/pgDefs.h"
|
|
|
|
#include "dlg/dlgAggregate.h"
|
|
#include "schema/pgSchema.h"
|
|
#include "schema/pgAggregate.h"
|
|
#include "schema/pgDatatype.h"
|
|
#include "ctl/ctlSeclabelPanel.h"
|
|
#include "frm/frmMain.h"
|
|
#include "schema/pgUser.h"
|
|
#include "schema/pgGroup.h"
|
|
|
|
#include "images/aggregate.pngc"
|
|
|
|
// pointer to controls
|
|
#define cbInputType CTRL_COMBOBOX2("cbInputType")
|
|
#define lstInputTypes CTRL_LISTCTRL("lstInputTypes")
|
|
#define cbStateType CTRL_COMBOBOX2("cbStateType")
|
|
#define cbStateFunc CTRL_COMBOBOX("cbStateFunc")
|
|
#define cbFinalFunc CTRL_COMBOBOX("cbFinalFunc")
|
|
#define cbSortOp CTRL_COMBOBOX("cbSortOp")
|
|
#define txtInitial CTRL_TEXT("txtInitial")
|
|
#define btnAddType CTRL_BUTTON("btnAddType")
|
|
#define btnRemoveType CTRL_BUTTON("btnRemoveType")
|
|
|
|
dlgProperty *pgAggregateFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
|
{
|
|
return new dlgAggregate(this, frame, (pgAggregate *)node, (pgSchema *)parent);
|
|
}
|
|
|
|
BEGIN_EVENT_TABLE(dlgAggregate, dlgTypeProperty)
|
|
EVT_TEXT(XRCID("cbInputType"), dlgAggregate::OnChangeTypeBase)
|
|
EVT_TEXT(XRCID("cbStateType"), dlgAggregate::OnChangeTypeState)
|
|
EVT_COMBOBOX(XRCID("cbStateType"), dlgAggregate::OnChangeType)
|
|
EVT_COMBOBOX(XRCID("cbStateFunc"), dlgProperty::OnChange)
|
|
EVT_COMBOBOX(XRCID("cbSortOp"), dlgProperty::OnChange)
|
|
EVT_TEXT(XRCID("cbStateFunc"), dlgProperty::OnChange)
|
|
EVT_BUTTON(XRCID("btnAddType"), dlgAggregate::OnAddInputType)
|
|
EVT_BUTTON(XRCID("btnRemoveType"), dlgAggregate::OnRemoveInputType)
|
|
EVT_LIST_ITEM_SELECTED(XRCID("lstInputTypes"), dlgAggregate::OnSelectInputType)
|
|
EVT_BUTTON(CTL_ADDPRIV, dlgAggregate::OnAddPriv)
|
|
EVT_BUTTON(CTL_DELPRIV, dlgAggregate::OnDelPriv)
|
|
#ifdef __WXMAC__
|
|
EVT_SIZE( dlgAggregate::OnChangeSize)
|
|
#endif
|
|
END_EVENT_TABLE();
|
|
|
|
dlgAggregate::dlgAggregate(pgaFactory *f, frmMain *frame, pgAggregate *agg, pgSchema *sch)
|
|
: dlgTypeProperty(f, frame, wxT("dlgAggregate"))
|
|
{
|
|
schema = sch;
|
|
aggregate = agg;
|
|
seclabelPage = new ctlSeclabelPanel(nbNotebook);
|
|
|
|
/* Aggregate Privileges */
|
|
securityChanged = false;
|
|
if (agg)
|
|
connection = agg->GetConnection();
|
|
securityPage = new ctlSecurityPanel(nbNotebook, wxT("EXECUTE"), "X", frame->GetImageList());
|
|
if (connection && (!agg || agg->CanCreate()))
|
|
{
|
|
// Fetch Groups Information
|
|
pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname"));
|
|
|
|
if (setGrp)
|
|
{
|
|
while (!setGrp->Eof())
|
|
{
|
|
groups.Add(setGrp->GetVal(0));
|
|
setGrp->MoveNext();
|
|
}
|
|
delete setGrp;
|
|
}
|
|
|
|
if (agg)
|
|
{
|
|
wxString strAcl = agg->GetAcl();
|
|
if (!strAcl.IsEmpty())
|
|
{
|
|
wxArrayString aclArray;
|
|
strAcl = strAcl.Mid(1, strAcl.Length() - 2);
|
|
getArrayFromCommaSeparatedList(strAcl, aclArray);
|
|
wxString roleName;
|
|
for (unsigned int index = 0; index < aclArray.Count(); index++)
|
|
{
|
|
wxString strCurrAcl = aclArray[index];
|
|
|
|
/*
|
|
* In rare case, we can have ',' (comma) in the user name.
|
|
* But, we need to handle them also
|
|
*/
|
|
if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND)
|
|
{
|
|
// Check it is start of the ACL
|
|
if (strCurrAcl[0U] == (wxChar)'"')
|
|
roleName = strCurrAcl + wxT(",");
|
|
continue;
|
|
}
|
|
else
|
|
strCurrAcl = roleName + strCurrAcl;
|
|
|
|
if (strCurrAcl[0U] == (wxChar)'"')
|
|
strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1);
|
|
roleName = strCurrAcl.BeforeLast('=');
|
|
|
|
wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/');
|
|
|
|
int icon = userFactory.GetIconId();
|
|
|
|
if (roleName.Left(6).IsSameAs(wxT("group "), false))
|
|
{
|
|
icon = groupFactory.GetIconId();
|
|
roleName = wxT("group ") + qtStrip(roleName.Mid(6));
|
|
}
|
|
else if (roleName.IsEmpty())
|
|
{
|
|
icon = PGICON_PUBLIC;
|
|
roleName = wxT("public");
|
|
}
|
|
else
|
|
{
|
|
roleName = qtStrip(roleName);
|
|
for (unsigned int index = 0; index < groups.Count(); index++)
|
|
if (roleName == groups[index])
|
|
{
|
|
roleName = wxT("group ") + roleName;
|
|
icon = groupFactory.GetIconId();
|
|
break;
|
|
}
|
|
}
|
|
|
|
securityPage->lbPrivileges->AppendItem(icon, roleName, value);
|
|
currentAcl.Add(roleName + wxT("=") + value);
|
|
|
|
// Reset roleName
|
|
roleName.Empty();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
securityPage->Disable();
|
|
}
|
|
|
|
pgObject *dlgAggregate::GetObject()
|
|
{
|
|
return aggregate;
|
|
}
|
|
|
|
int dlgAggregate::Go(bool modal)
|
|
{
|
|
if (!connection->BackendMinimumVersion(8, 0))
|
|
cbOwner->Disable();
|
|
|
|
if (!connection->BackendMinimumVersion(8, 1))
|
|
cbSortOp->Disable();
|
|
|
|
if (connection->BackendMinimumVersion(9, 1))
|
|
{
|
|
seclabelPage->SetConnection(connection);
|
|
seclabelPage->SetObject(aggregate);
|
|
this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgAggregate::OnChange));
|
|
}
|
|
else
|
|
seclabelPage->Disable();
|
|
|
|
lstInputTypes->InsertColumn(0, _("Input types"), wxLIST_FORMAT_LEFT, lstInputTypes->GetSize().x - 10);
|
|
|
|
if (aggregate)
|
|
{
|
|
// edit mode
|
|
txtName->Enable(connection->BackendMinimumVersion(7, 4));
|
|
cbSchema->Enable(connection->BackendMinimumVersion(8, 1));
|
|
|
|
for (unsigned int x = 0; x < aggregate->GetInputTypesArray().Count(); x++ )
|
|
{
|
|
lstInputTypes->InsertItem(x, aggregate->GetInputTypesArray().Item(x));
|
|
AddType(wxT(" "), 0, aggregate->GetInputTypesArray().Item(x));
|
|
}
|
|
|
|
cbStateType->Append(aggregate->GetStateType());
|
|
cbStateType->SetSelection(0);
|
|
|
|
cbStateFunc->Append(aggregate->GetStateFunction());
|
|
cbStateFunc->SetSelection(0);
|
|
cbFinalFunc->Append(aggregate->GetFinalFunction());
|
|
cbFinalFunc->SetSelection(0);
|
|
|
|
cbSortOp->Append(aggregate->GetSortOp());
|
|
cbSortOp->SetSelection(0);
|
|
|
|
txtInitial->SetValue(aggregate->GetInitialCondition());
|
|
|
|
cbInputType->Disable();
|
|
btnAddType->Disable();
|
|
btnRemoveType->Disable();
|
|
cbStateFunc->Disable();
|
|
cbStateType->Disable();
|
|
cbFinalFunc->Disable();
|
|
cbSortOp->Disable();
|
|
txtInitial->Disable();
|
|
}
|
|
else
|
|
{
|
|
// create mode
|
|
AddType(wxT(" "), PGOID_TYPE_ANY, wxT("\"any\""));
|
|
cbInputType->Append(wxT("ANY"));
|
|
|
|
FillDatatype(cbInputType, cbStateType, false);
|
|
btnRemoveType->Disable();
|
|
}
|
|
|
|
securityPage->SetConnection(connection);
|
|
|
|
if (securityPage->cbGroups)
|
|
{
|
|
// Fetch Groups Information
|
|
for ( unsigned int index = 0; index < groups.Count();)
|
|
securityPage->cbGroups->Append(wxT("group ") + groups[index++]);
|
|
|
|
// Fetch Users Information
|
|
if (settings->GetShowUsersForPrivileges())
|
|
{
|
|
securityPage->stGroup->SetLabel(_("Group/User"));
|
|
dlgProperty::AddUsers(securityPage->cbGroups);
|
|
}
|
|
}
|
|
securityPage->lbPrivileges->GetParent()->Layout();
|
|
|
|
return dlgProperty::Go(modal);
|
|
}
|
|
|
|
pgObject *dlgAggregate::CreateObject(pgCollection *collection)
|
|
{
|
|
pgObject *obj = aggregateFactory.CreateObjects(collection, 0,
|
|
wxT("\n AND proname=") + qtDbString(GetName()) +
|
|
wxT("\n AND pronamespace=") + schema->GetOidStr());
|
|
|
|
return obj;
|
|
}
|
|
|
|
#ifdef __WXMAC__
|
|
void dlgAggregate::OnChangeSize(wxSizeEvent &ev)
|
|
{
|
|
lstInputTypes->SetSize(wxDefaultCoord, wxDefaultCoord,
|
|
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
|
|
securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord,
|
|
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550);
|
|
if (GetAutoLayout())
|
|
{
|
|
Layout();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void dlgAggregate::CheckChange()
|
|
{
|
|
bool enable = true;
|
|
if (aggregate)
|
|
{
|
|
enable = GetName() != aggregate->GetName()
|
|
|| cbSchema->GetValue() != aggregate->GetSchema()->GetName()
|
|
|| txtComment->GetValue() != aggregate->GetComment()
|
|
|| cbOwner->GetValue() != aggregate->GetOwner();
|
|
if (seclabelPage && connection->BackendMinimumVersion(9, 1))
|
|
enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty());
|
|
}
|
|
else
|
|
{
|
|
// For pre 8.2 servers, we can only have one input type.
|
|
if (!connection->BackendMinimumVersion(8, 2))
|
|
{
|
|
if (lstInputTypes->GetItemCount() >= 1)
|
|
btnAddType->Disable();
|
|
else
|
|
btnAddType->Enable();
|
|
}
|
|
|
|
// Multi parameter aggregates cannot have sort ops.
|
|
if (connection->BackendMinimumVersion(8, 2))
|
|
{
|
|
if (lstInputTypes->GetItemCount() > 1)
|
|
{
|
|
cbSortOp->SetValue(wxEmptyString);
|
|
cbSortOp->Disable();
|
|
}
|
|
else
|
|
cbSortOp->Enable();
|
|
}
|
|
|
|
wxString name = GetName();
|
|
CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
|
|
CheckValid(enable, cbStateType->GetGuessedSelection() >= 0, _("Please select state datatype."));
|
|
CheckValid(enable, cbStateFunc->GetCurrentSelection() >= 0, _("Please specify state function."));
|
|
}
|
|
EnableOK(enable || securityChanged);
|
|
}
|
|
|
|
void dlgAggregate::OnChangeTypeBase(wxCommandEvent &ev)
|
|
{
|
|
cbInputType->GuessSelection(ev);
|
|
OnChangeType(ev);
|
|
}
|
|
|
|
void dlgAggregate::OnChangeTypeState(wxCommandEvent &ev)
|
|
{
|
|
cbStateType->GuessSelection(ev);
|
|
OnChangeType(ev);
|
|
}
|
|
|
|
void dlgAggregate::OnChangeType(wxCommandEvent &ev)
|
|
{
|
|
cbStateFunc->Clear();
|
|
cbFinalFunc->Clear();
|
|
cbSortOp->Clear();
|
|
|
|
pgSet *set;
|
|
wxString qry;
|
|
|
|
// Get the possible state functions. They must return the state type, and take
|
|
// input_types + 1 parameters, the first of which is of the state type.
|
|
// If there are no input_types specified, assume "ANY" for a count(*) style aggregate.
|
|
if (lstInputTypes->GetItemCount() > 0 && cbStateType->GetGuessedSelection() >= 0)
|
|
{
|
|
set = connection->ExecuteSet(
|
|
wxT("SELECT proname, nspname, prorettype\n")
|
|
wxT(" FROM pg_proc p\n")
|
|
wxT(" JOIN pg_type t ON t.oid=p.prorettype\n")
|
|
wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n")
|
|
wxT(" WHERE prorettype = ") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) +
|
|
wxT("\n AND prokind <> 'a'")
|
|
wxT("\n AND proargtypes = '") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + wxT(" ") + GetInputTypesOidList() + wxT("'"));
|
|
|
|
if (set)
|
|
{
|
|
while (!set->Eof())
|
|
{
|
|
cbStateFunc->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")),
|
|
database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname"))));
|
|
|
|
set->MoveNext();
|
|
}
|
|
delete set;
|
|
}
|
|
|
|
// Get the possible final_func options. This may be nothing, or a
|
|
// function taking an argument of state_type
|
|
cbFinalFunc->Append(wxT(" "));
|
|
|
|
set = connection->ExecuteSet(
|
|
wxT("SELECT proname, nspname, prorettype\n")
|
|
wxT(" FROM pg_proc p\n")
|
|
wxT(" JOIN pg_type t ON t.oid=p.prorettype\n")
|
|
wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n")
|
|
wxT(" WHERE proisagg = FALSE")
|
|
wxT("\n AND proargtypes = '") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + wxT("'"));
|
|
|
|
if (set)
|
|
{
|
|
while (!set->Eof())
|
|
{
|
|
cbFinalFunc->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")),
|
|
database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname"))));
|
|
|
|
set->MoveNext();
|
|
}
|
|
delete set;
|
|
}
|
|
|
|
// Get the sort operators. This is only valid for a single arguement operator.
|
|
cbSortOp->Append(wxT(" "), wxEmptyString);
|
|
|
|
set = connection->ExecuteSet(
|
|
wxT("SELECT oprname, nspname\n")
|
|
wxT(" FROM pg_operator op\n")
|
|
wxT(" JOIN pg_namespace nsp on nsp.oid=oprnamespace\n")
|
|
wxT(" WHERE oprleft = ") + NumToStr(GetInputTypeOid(0)) + wxT("\n")
|
|
wxT(" AND oprright = ") + NumToStr(GetInputTypeOid(0)) + wxT("\n"));
|
|
|
|
if (set)
|
|
{
|
|
while (!set->Eof())
|
|
{
|
|
wxString key = database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("oprname")));
|
|
wxString txt = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("oprname"));
|
|
cbSortOp->Append(txt, key);
|
|
set->MoveNext();
|
|
}
|
|
delete set;
|
|
}
|
|
}
|
|
|
|
CheckChange();
|
|
}
|
|
|
|
wxString dlgAggregate::GetSql()
|
|
{
|
|
wxString sql, name;
|
|
|
|
if (aggregate)
|
|
{
|
|
// edit mode
|
|
name = schema->GetQuotedPrefix() + qtIdent(GetName()) + wxT("(") + GetInputTypesList() + wxT(")");
|
|
|
|
AppendNameChange(sql, wxT("AGGREGATE ") + aggregate->GetQuotedFullName());
|
|
AppendOwnerChange(sql, wxT("AGGREGATE ") + name);
|
|
AppendSchemaChange(sql, wxT("AGGREGATE ") + name);
|
|
}
|
|
else
|
|
{
|
|
// create mode
|
|
name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName());
|
|
|
|
if (connection->BackendMinimumVersion(8, 2))
|
|
{
|
|
sql = wxT("CREATE AGGREGATE ") + name
|
|
+ wxT("(") + GetInputTypesList() + wxT(") (\n");
|
|
}
|
|
else
|
|
{
|
|
sql = wxT("CREATE AGGREGATE ") + name
|
|
+ wxT("(\n BASETYPE=") + GetInputTypesList() + wxT(",\n");
|
|
}
|
|
|
|
sql += wxT(" SFUNC=") + cbStateFunc->GetStringKey()
|
|
+ wxT(",\n STYPE=") + GetQuotedTypename(cbStateType->GetGuessedSelection() + 1); // skip "any" type
|
|
|
|
if (cbFinalFunc->GetCurrentSelection() > 0)
|
|
{
|
|
sql += wxT(",\n FINALFUNC=")
|
|
+ cbFinalFunc->GetStringKey();
|
|
}
|
|
wxString initial = txtInitial->GetValue().Strip(wxString::both);
|
|
if (!initial.IsEmpty())
|
|
{
|
|
if (initial == wxT("''")) // Empty string
|
|
sql += wxT(",\n INITCOND=''");
|
|
else if (initial == wxT("\\'\\'")) // Pair of quotes
|
|
sql += wxT(",\n INITCOND=''''''");
|
|
else
|
|
sql += wxT(",\n INITCOND=") + qtDbString(initial);
|
|
}
|
|
|
|
if (!cbSortOp->GetValue().IsEmpty())
|
|
{
|
|
wxString opr = cbSortOp->GetStringKey();
|
|
if (!opr.IsEmpty())
|
|
sql += wxT(",\n SORTOP=") + opr;
|
|
}
|
|
|
|
sql += wxT("\n);\n");
|
|
|
|
AppendOwnerNew(sql, wxT("AGGREGATE ") + name + wxT("(") + GetInputTypesList() + wxT(")"));
|
|
}
|
|
|
|
AppendComment(sql, wxT("AGGREGATE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())
|
|
+ wxT("(") + GetInputTypesList() + wxT(")"), aggregate);
|
|
|
|
sql += securityPage->GetGrant(wxT("X"),
|
|
wxT("FUNCTION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + wxT("(") + GetInputTypesList() + wxT(")"),
|
|
¤tAcl);
|
|
|
|
if (seclabelPage && connection->BackendMinimumVersion(9, 1))
|
|
sql += seclabelPage->GetSqlForSecLabels(wxT("AGGREGATE"),
|
|
qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())
|
|
+ wxT("(") + GetInputTypesList() + wxT(")"));
|
|
|
|
return sql;
|
|
}
|
|
|
|
// Return the list of input types
|
|
wxString dlgAggregate::GetInputTypesList()
|
|
{
|
|
wxString types;
|
|
|
|
for (int i = 0; i < lstInputTypes->GetItemCount(); i++)
|
|
{
|
|
if (i > 0)
|
|
types += wxT(", ");
|
|
|
|
if (lstInputTypes->GetItemText(i) == wxT("ANY") || lstInputTypes->GetItemText(i) == wxT("*"))
|
|
return wxT("*");
|
|
else
|
|
types += qtTypeIdent(lstInputTypes->GetItemText(i));
|
|
}
|
|
return types;
|
|
}
|
|
|
|
void dlgAggregate::OnAddInputType(wxCommandEvent &ev)
|
|
{
|
|
if (cbInputType->GetValue() != wxEmptyString)
|
|
{
|
|
if (cbInputType->GetValue() == wxT("ANY") && lstInputTypes->GetItemCount() > 0)
|
|
{
|
|
wxLogError(_("The ANY pseudo-datatype cannot be used in multi parameter aggregates."));
|
|
return;
|
|
}
|
|
|
|
wxListItem itm;
|
|
itm.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT);
|
|
|
|
itm.SetData(StrToLong(GetTypeOid(cbInputType->GetGuessedSelection())));
|
|
itm.SetText(cbInputType->GetValue());
|
|
|
|
lstInputTypes->InsertItem(itm);
|
|
|
|
if (cbInputType->GetValue() == wxT("ANY"))
|
|
btnAddType->Disable();
|
|
|
|
OnChangeType(ev);
|
|
}
|
|
}
|
|
|
|
void dlgAggregate::OnRemoveInputType(wxCommandEvent &ev)
|
|
{
|
|
long pos = lstInputTypes->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);;
|
|
if (pos >= 0)
|
|
{
|
|
lstInputTypes->DeleteItem(pos);
|
|
|
|
OnChangeType(ev);
|
|
btnRemoveType->Disable();
|
|
|
|
// Re-enable the Add button, in case it was disabled because
|
|
// ANY was specified.
|
|
btnAddType->Enable();
|
|
}
|
|
}
|
|
|
|
void dlgAggregate::OnSelectInputType(wxListEvent &ev)
|
|
{
|
|
if (!aggregate)
|
|
btnRemoveType->Enable();
|
|
}
|
|
|
|
// Returnt the datatype OID for the given parameter number
|
|
long dlgAggregate::GetInputTypeOid(int param)
|
|
{
|
|
wxListItem itm;
|
|
itm.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT);
|
|
itm.SetId(param);
|
|
|
|
lstInputTypes->GetItem(itm);
|
|
|
|
return itm.GetData();
|
|
}
|
|
|
|
// Return the list of datatype OIDs
|
|
wxString dlgAggregate::GetInputTypesOidList()
|
|
{
|
|
wxString types;
|
|
|
|
for (int i = 0; i < lstInputTypes->GetItemCount(); i++)
|
|
{
|
|
if (i > 0)
|
|
types += wxT(" ");
|
|
|
|
types += NumToStr(GetInputTypeOid(i));
|
|
}
|
|
return types;
|
|
}
|
|
|
|
void dlgAggregate::OnChange(wxCommandEvent &event)
|
|
{
|
|
CheckChange();
|
|
}
|
|
|
|
void dlgAggregate::OnAddPriv(wxCommandEvent &ev)
|
|
{
|
|
securityChanged = true;
|
|
CheckChange();
|
|
}
|
|
|
|
void dlgAggregate::OnDelPriv(wxCommandEvent &ev)
|
|
{
|
|
securityChanged = true;
|
|
CheckChange();
|
|
}
|