Log Message:
-----------
GRANT wizard

Added Files:
-----------
    pgadmin3/src/include:
        ctlSecurityPanel.h (r1.1)
        dlgClasses.h (r1.1)
        frmGrantWizard.h (r1.1)
    pgadmin3/src/ui:
        ctlSecurityPanel.cpp (r1.1)
        dlgClasses.cpp (r1.1)
        frmGrantWizard.cpp (r1.1)

--- /dev/null
+++ src/include/frmGrantWizard.h
@@ -0,0 +1,54 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id: frmGrantWizard.h,v 1.1 2004/06/06 19:42:00 andreas Exp $
+// Copyright (C) 2002 - 2004, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// frmGrantWizard.h - Grant Wizard Dialogue
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef FRMGRANTWIZARD_H
+#define FRMGRANTWIZARD_H
+
+// wxWindows headers
+#include <wx/wx.h>
+
+
+// App headers
+#include "pgAdmin3.h"
+#include "frmMain.h"
+#include "dlgClasses.h"
+
+
+class ctlSecurityPanel;
+
+
+class frmGrantWizard : public ExecutionDialog
+{
+public:
+    frmGrantWizard(frmMain *form, pgObject *_object);
+    ~frmGrantWizard();
+
+    void Go();
+    wxString GetSql();
+    wxString GetHelpPage() const;
+    
+private:
+
+    void OnPageSelect(wxNotebookEvent& event);
+    void OnCheckAll(wxCommandEvent &event);
+    void OnUncheckAll(wxCommandEvent &event);
+
+    void AddObjects(pgCollection *collection);
+
+    wxArrayPtrVoid objectArray;
+    ctlSQLBox *sqlPane;
+    wxNotebook *nbNotebook;
+    ctlSecurityPanel *securityPage;
+
+    DECLARE_EVENT_TABLE()
+};
+
+#endif
--- /dev/null
+++ src/include/dlgClasses.h
@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id: dlgClasses.h,v 1.1 2004/06/06 19:42:00 andreas Exp $
+// Copyright (C) 2002 - 2004, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// dlgClasses.h - Some dialogue base classes 
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef DLGCLASSES_H
+#define DLGCLASSES_H
+
+#include <wx/wx.h>
+
+
+#define btnOK                   CTRL_BUTTON("btnOK")
+#define btnCancel               CTRL_BUTTON("btnCancel")
+
+
+
+class frmMain;
+
+class DialogWithHelp : public wxDialog
+{
+public:
+    DialogWithHelp(frmMain *frame);
+
+protected:
+    frmMain *mainForm;
+    void OnHelp(wxCommandEvent& ev);
+
+
+private:
+    virtual wxString GetHelpPage() const = 0;
+    DECLARE_EVENT_TABLE();
+};
+
+class ExecutionDialog : public DialogWithHelp
+{
+public:
+    ExecutionDialog(frmMain *frame, pgObject *_object);
+    virtual wxString GetSql()=0;
+
+    void OnOK(wxCommandEvent& ev);
+    void OnCancel(wxCommandEvent& ev);
+    void OnClose(wxCloseEvent& event);
+
+    void Abort();
+
+protected:
+    pgObject *object;
+    pgQueryThread *thread;
+    wxTextCtrl *txtMessages;
+
+private:
+    DECLARE_EVENT_TABLE();
+};
+#endif
--- /dev/null
+++ src/include/ctlSecurityPanel.h
@@ -0,0 +1,75 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id: ctlSecurityPanel.h,v 1.1 2004/06/06 19:42:00 andreas Exp $
+// Copyright (C) 2002 - 2004, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// ctlSecurityPanel.h - Panel with security information
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+#ifndef CTL_SECPANEL_H
+#define CTL_SECPANEL_H
+
+#include <wx/wx.h>
+#include <wx/notebook.h>
+
+enum
+{
+    CTL_PROPSQL=250,
+    CTL_MSG,
+    CTL_LBPRIV,
+    CTL_STATICGROUP,
+    CTL_CBGROUP,
+    CTL_ADDPRIV,
+    CTL_DELPRIV,
+    CTL_ALLPRIV,
+    CTL_ALLPRIVGRANT,
+    CTL_PRIVCB          // base for all privilege checkboxes, must be last
+};
+
+
+class pgConn;
+
+class ctlSecurityPanel : public wxPanel
+{
+
+public:
+
+    ctlSecurityPanel(wxNotebook *nb, const wxString &privList, char *privChars, 
wxImageList *imgList);
+    ~ctlSecurityPanel();
+
+    ctlListView *lbPrivileges;
+    wxComboBox *cbGroups;
+    wxStaticText *stGroup;
+    void SetConnection(pgConn *conn) { connection=conn; }
+    wxString GetGrant(const wxString &allPattern, const wxString &grantObject, 
wxArrayString *currentAcl=0);
+protected:
+    wxNotebook *nbNotebook;
+    pgConn *connection;
+
+    wxButton *btnAddPriv, *btnDelPriv;
+    int privilegeCount;
+    char *privilegeChars;
+    wxCheckBox **privCheckboxes;
+    wxCheckBox *allPrivileges, *allPrivilegesGrant;
+
+    void OnPrivSelChange(wxListEvent &ev);
+    void OnAddPriv(wxCommandEvent& ev);
+    void OnDelPriv(wxCommandEvent& ev);
+    void OnPrivCheck(wxCommandEvent& ev);
+    void OnPrivCheckAll(wxCommandEvent& ev);
+    void OnPrivCheckAllGrant(wxCommandEvent& ev);
+
+    void CheckGrantOpt(int index);
+    bool GrantAllowed() const;
+
+
+    DECLARE_EVENT_TABLE();
+};
+
+
+
+#endif
\ No newline at end of file
--- /dev/null
+++ src/ui/frmGrantWizard.cpp
@@ -0,0 +1,236 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id: frmGrantWizard.cpp,v 1.1 2004/06/06 19:42:00 andreas Exp $
+// Copyright (C) 2002 - 2004, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// frmGrantWizard.cpp - Grant Wizard dialogue
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+
+
+// App headers
+#include "pgAdmin3.h"
+#include "frmGrantWizard.h"
+#include "sysLogger.h"
+#include "pgFunction.h"
+#include "ctlSecurityPanel.h"
+
+// Icons
+#include "images/index.xpm"
+
+
+#define chkList     CTRL_CHECKLISTBOX("chkList")
+
+
+
+BEGIN_EVENT_TABLE(frmGrantWizard, ExecutionDialog)
+    EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"),  frmGrantWizard::OnPageSelect) 
+    EVT_BUTTON(XRCID("btnChkAll"), frmGrantWizard::OnCheckAll)
+    EVT_BUTTON(XRCID("btnUnchkAll"), frmGrantWizard::OnUncheckAll)
+END_EVENT_TABLE()
+
+
+frmGrantWizard::frmGrantWizard(frmMain *form, pgObject *obj) : ExecutionDialog(form, 
obj)
+{
+    wxLogInfo(wxT("Creating a grant wizard dialogue for %s %s"), 
object->GetTypeName().c_str(), object->GetFullName().c_str());
+
+    nbNotebook = 0;
+
+    wxWindowBase::SetFont(settings->GetSystemFont());
+    wxXmlResource::Get()->LoadDialog(this, form, wxT("frmGrantWizard"));
+    SetTitle(wxString::Format(_("Privileges for %s %s"), 
object->GetTypeName().c_str(), object->GetFullIdentifier().c_str()));
+
+    // Icon
+    SetIcon(wxIcon(index_xpm));
+    nbNotebook = CTRL_NOTEBOOK("nbNotebook");
+    sqlPane = 0;
+
+    CenterOnParent();
+}
+
+
+frmGrantWizard::~frmGrantWizard()
+{
+    wxLogInfo(wxT("Destroying a grant wizard dialogue"));
+    Abort();
+}
+
+
+wxString frmGrantWizard::GetHelpPage() const
+{
+    wxString page=wxT("sql-grant");
+
+    return page;
+}
+
+
+
+void frmGrantWizard::OnUncheckAll(wxCommandEvent& event)
+{
+    int i;
+    for (i=0 ; i < chkList->GetCount() ; i++)
+        chkList->Check(i, false);
+}
+
+
+
+void frmGrantWizard::OnCheckAll(wxCommandEvent& event)
+{
+    int i;
+    for (i=0 ; i < chkList->GetCount() ; i++)
+        chkList->Check(i, true);
+}
+
+
+void frmGrantWizard::OnPageSelect(wxNotebookEvent& event)
+{
+    if (nbNotebook && sqlPane && event.GetSelection() == 
(int)nbNotebook->GetPageCount()-2)
+    {
+        sqlPane->SetReadOnly(false);
+        sqlPane->SetText(GetSql());
+        sqlPane->SetReadOnly(true);
+    }
+}
+
+
+void frmGrantWizard::AddObjects(pgCollection *collection)
+{
+    bool traverseKids = (!collection->IsCollection() || collection->GetType() == 
PG_SCHEMAS);
+
+    if (!traverseKids)
+    {
+        if (!collection->IsCollectionForType(PG_TABLE) &&
+            !collection->IsCollectionForType(PG_FUNCTION) &&
+            !collection->IsCollectionForType(PG_TRIGGERFUNCTION) &&
+            !collection->IsCollectionForType(PG_VIEW) &&
+            !collection->IsCollectionForType(PG_SEQUENCE))
+            return;
+    }
+    wxCookieType cookie;
+    wxTreeItemId item=mainForm->GetBrowser()->GetFirstChild(collection->GetId(), 
cookie);
+
+    while (item)
+    {
+        pgObject *obj=(pgObject*)mainForm->GetBrowser()->GetItemData(item);
+        if (obj)
+        {
+            if (traverseKids)
+                AddObjects((pgCollection*)obj);
+            else
+            {
+                objectArray.Add(obj);
+                chkList->Append(obj->GetTypeName() + wxT(" ") + 
obj->GetFullIdentifier());
+            }
+        }
+        item=mainForm->GetBrowser()->GetNextChild(collection->GetId(), cookie);
+    }
+
+}
+
+void frmGrantWizard::Go()
+{
+    chkList->SetFocus();
+
+    wxString privList = wxT("INSERT,SELECT,UPDATE,DELETE,RULE,REFERENCES,TRIGGER");
+    char *privChar="arwdRxt";
+    switch (object->GetType())
+    {
+        case PG_DATABASE:
+        case PG_SCHEMAS:
+        case PG_SCHEMA:
+            privList.Append(wxT(",EXECUTE"));
+            privChar = "arwdRxtX";
+            break;
+        case PG_FUNCTIONS:
+        case PG_TRIGGERFUNCTIONS:
+            privList = wxT(",EXECUTE");
+            privChar = "X";
+            break;
+        default:
+            break;
+    }
+
+
+    securityPage = new ctlSecurityPanel(nbNotebook, privList, privChar, 
mainForm->GetImageList());
+    securityPage->SetConnection(object->GetConnection());
+
+    sqlPane = new ctlSQLBox(nbNotebook, CTL_PROPSQL, wxDefaultPosition, 
wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH2);
+    nbNotebook->AddPage(sqlPane, wxT("SQL"));
+
+    txtMessages = new wxTextCtrl(nbNotebook, CTL_MSG, wxEmptyString, 
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL);
+    nbNotebook->AddPage(txtMessages, _("Messages"));
+
+    AddObjects((pgCollection*)object);
+
+
+    if (securityPage->cbGroups)
+    {
+        pgSet *set=object->GetConnection()->ExecuteSet(wxT("SELECT groname FROM 
pg_group ORDER BY groname"));
+
+        if (set)
+        {
+            while (!set->Eof())
+            {
+                securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0));
+                set->MoveNext();
+            }
+            delete set;
+        }
+
+        if (settings->GetShowUsersForPrivileges())
+        {
+            set=object->GetConnection()->ExecuteSet(wxT("SELECT usename FROM pg_user 
ORDER BY usename"));
+
+            if (set)
+            {
+                securityPage->stGroup->SetLabel(_("Group/User"));
+
+                while (!set->Eof())
+                {
+                    securityPage->cbGroups->Append(set->GetVal(0));
+                    set->MoveNext();
+                }
+                delete set;
+            }
+        }
+    }
+
+    Show(true);
+}
+
+
+wxString frmGrantWizard::GetSql()
+{
+    wxString sql;
+
+    int i;
+    for (i=0 ; i < chkList->GetCount() ; i++)
+    {
+        if (chkList->IsChecked(i))
+        {
+            wxString tmp;
+
+            pgObject *obj=(pgObject*)objectArray.Item(i);
+
+            if (obj->GetType() == PG_FUNCTION || obj->GetType() == PG_TRIGGERFUNCTION)
+            {
+                tmp = securityPage->GetGrant(wxT("X"), wxT("FUNCTION ") 
+                    + obj->GetQuotedFullIdentifier() + wxT("(")
+                    + ((pgFunction*)obj)->GetArgTypes() + wxT(")"));
+            }
+            else
+                tmp = securityPage->GetGrant(wxT("arwdRxt"), 
obj->GetTypeName().Upper() + wxT(" ") + obj->GetQuotedFullIdentifier());
+
+            if (!tmp.IsEmpty())
+                sql.Append(tmp);
+        }
+    }
+    return sql;
+}
\ No newline at end of file
--- /dev/null
+++ src/ui/dlgClasses.cpp
@@ -0,0 +1,168 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id: dlgClasses.cpp,v 1.1 2004/06/06 19:42:00 andreas Exp $
+// Copyright (C) 2002 - 2004, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// dlgClasses.cpp - Some dialogue base classes 
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+
+
+// App headers
+#include "pgAdmin3.h"
+#include "frmMain.h"
+#include "dlgClasses.h"
+#include "pgConn.h"
+
+#include "menu.h"
+
+
+BEGIN_EVENT_TABLE(DialogWithHelp, wxDialog)
+    EVT_MENU(MNU_HELP,                  DialogWithHelp::OnHelp)
+    EVT_BUTTON(XRCID("btnHelp"),        DialogWithHelp::OnHelp)
+END_EVENT_TABLE();
+
+
+DialogWithHelp::DialogWithHelp(frmMain *frame) : wxDialog()
+{
+    mainForm = frame;
+
+    wxAcceleratorEntry entries[2];
+    entries[0].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP);
+// this is for GTK because Meta (usually Numlock) is interpreted like Alt
+// there are too many controls to reset m_Meta in all of them
+    entries[1].Set(wxACCEL_ALT, WXK_F1, MNU_HELP);
+    wxAcceleratorTable accel(2, entries);
+
+    SetAcceleratorTable(accel);
+}
+
+
+void DialogWithHelp::OnHelp(wxCommandEvent& ev)
+{
+    wxString page=GetHelpPage();
+
+    if (!page.IsEmpty())
+        DisplaySqlHelp(this, page);
+}
+
+
+
+////////////////////////////////////////////////////////////////77
+
+
+BEGIN_EVENT_TABLE(ExecutionDialog, DialogWithHelp)
+    EVT_BUTTON (XRCID("btnOK"),         ExecutionDialog::OnOK)
+    EVT_BUTTON (XRCID("btnCancel"),     ExecutionDialog::OnCancel)
+    EVT_CLOSE(                          ExecutionDialog::OnClose)
+END_EVENT_TABLE()
+
+
+ExecutionDialog::ExecutionDialog(frmMain *frame, pgObject *_object) : 
DialogWithHelp(frame)
+{
+    thread=0;
+    object = _object;
+    txtMessages = 0;
+}
+
+
+void ExecutionDialog::OnClose(wxCloseEvent& event)
+{
+    Abort();
+    Destroy();
+}
+
+
+void ExecutionDialog::OnCancel(wxCommandEvent& ev)
+{
+    if (thread)
+    {
+        btnCancel->Disable();
+        Abort();
+        btnCancel->Enable();
+        btnOK->Enable();
+    }
+    else
+    {
+        Destroy();
+    }
+}
+
+
+void ExecutionDialog::Abort()
+{
+    if (thread)
+    {
+        if (thread->IsRunning())
+            thread->Delete();
+        delete thread;
+        thread=0;
+    }
+}
+
+
+void ExecutionDialog::OnOK(wxCommandEvent& ev)
+{
+    if (!thread)
+    {
+        wxString sql=GetSql();
+        if (sql.IsEmpty())
+            return;
+
+        btnOK->Disable();
+
+        thread=new pgQueryThread(object->GetConnection(), sql);
+        if (thread->Create() != wxTHREAD_NO_ERROR)
+        {
+            Abort();
+            return;
+        }
+
+        wxLongLong startTime=wxGetLocalTimeMillis();
+        thread->Run();
+
+        while (thread && thread->IsRunning())
+        {
+            wxUsleep(10);
+            // here could be the animation
+            if (txtMessages)
+                txtMessages->AppendText(thread->GetMessagesAndClear());
+            wxYield();
+        }
+
+        if (thread)
+        {
+            if (txtMessages)
+                txtMessages->AppendText(thread->GetMessagesAndClear());
+
+            if (thread->DataSet() != NULL)
+                wxLogDebug(wxString::Format(_("%d rows."), 
thread->DataSet()->NumRows()));
+
+            if (txtMessages)
+                txtMessages->AppendText(_("Total query runtime: ") 
+                    + (wxGetLocalTimeMillis()-startTime).ToString() + wxT(" ms."));
+
+                btnOK->SetLabel(_("Done"));
+            btnCancel->Disable();
+        }
+        else
+            if (txtMessages)
+                txtMessages->AppendText(_("\nCancelled.\n"));
+
+        btnOK->Enable();
+    }
+    else
+    {
+        Abort();
+        Destroy();
+    }
+}
+
+
--- /dev/null
+++ src/ui/ctlSecurityPanel.cpp
@@ -0,0 +1,356 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id: ctlSecurityPanel.cpp,v 1.1 2004/06/06 19:42:00 andreas Exp $
+// Copyright (C) 2002 - 2004, The pgAdmin Development Team
+// This software is released under the Artistic Licence
+//
+// ctlSecurityPanel.cpp - Panel with security information
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+// wxWindows headers
+#include <wx/wx.h>
+#include <wx/settings.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "sysLogger.h"
+#include "ctlSecurityPanel.h"
+#include "pgConn.h"
+#include "pgObject.h"
+
+
+
+BEGIN_EVENT_TABLE(ctlSecurityPanel, wxPanel)
+    EVT_LIST_ITEM_SELECTED(CTL_LBPRIV,  ctlSecurityPanel::OnPrivSelChange)
+    EVT_BUTTON(CTL_ADDPRIV,             ctlSecurityPanel::OnAddPriv)
+    EVT_BUTTON(CTL_DELPRIV,             ctlSecurityPanel::OnDelPriv)
+    EVT_CHECKBOX(CTL_ALLPRIV,           ctlSecurityPanel::OnPrivCheckAll)
+    EVT_CHECKBOX(CTL_ALLPRIVGRANT,      ctlSecurityPanel::OnPrivCheckAllGrant)
+    EVT_CHECKBOX(CTL_PRIVCB,            ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+2,          ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+4,          ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+6,          ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+8,          ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+10,         ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+12,         ctlSecurityPanel::OnPrivCheck)
+    EVT_CHECKBOX(CTL_PRIVCB+14,         ctlSecurityPanel::OnPrivCheck)
+END_EVENT_TABLE();
+
+
+
+
+
+ctlSecurityPanel::ctlSecurityPanel(wxNotebook *nb, const wxString &privList, char 
*privChars, wxImageList *imgList)
+: wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize)
+{
+    nbNotebook = nb;
+    nbNotebook->AddPage(this, _("Security"));
+
+    connection = 0;
+    privilegeChars=privChars;
+    allPrivileges=0;
+
+    privCheckboxes=0;
+
+    wxStringTokenizer privileges(privList, wxT(","));
+    privilegeCount=privileges.CountTokens();
+
+
+    if (privilegeCount)
+    {
+        bool needAll=(privilegeCount > 1);
+        privCheckboxes = new wxCheckBox*[privilegeCount*2];
+        int i=0;
+
+        long chkFlags=0;
+        int width, height;
+        GetClientSize(&width, &height);
+
+        wxPoint zeroPos=ConvertDialogToPixels(wxPoint(5, 5));
+        wxSize chkSize=ConvertDialogToPixels(wxSize(65,12));
+        wxSize btnSize=ConvertDialogToPixels(wxSize(50,15));
+        wxSize spcSize=ConvertDialogToPixels(wxSize(2, 2));
+
+        {
+            int y = height 
+                - spcSize.GetHeight()
+                - zeroPos.y * 2
+                - chkSize.GetHeight() * (4 + privilegeCount + (needAll ? 0 : 1));
+
+            lbPrivileges = new ctlListView(this, CTL_LBPRIV, 
+                zeroPos, 
+                wxSize(width - zeroPos.x * 2, y - zeroPos.y - spcSize.GetHeight()), 
wxSUNKEN_BORDER|wxLC_REPORT);
+
+            lbPrivileges->CreateColumns(imgList, _("User/Group"), _("Privileges"), 
-1);
+
+            btnAddPriv = new wxButton(this, CTL_ADDPRIV, _("Add/Change"), 
+                wxPoint(zeroPos.x, y), btnSize);
+            btnDelPriv = new wxButton(this, CTL_DELPRIV, _("Remove"), 
+                wxPoint(zeroPos.x * 2 + btnSize.GetWidth(), y), btnSize);
+            y += zeroPos.y + btnSize.GetHeight();
+
+            new wxStaticBox(this, -1, _("Privileges"), 
+                wxPoint(zeroPos.x, y), 
+                wxSize(width - zeroPos.x*2, btnSize.GetHeight() + chkSize.GetHeight() 
* (2 + privilegeCount-(needAll?0:1))));
+            y += zeroPos.y + spcSize.GetHeight();
+
+            stGroup = new wxStaticText(this, CTL_STATICGROUP, _("Group"), 
wxPoint(zeroPos.x * 2, y+3), chkSize);
+            cbGroups = new wxComboBox(this, CTL_CBGROUP, wxT(""), 
+                wxPoint(zeroPos.x * 3 + chkSize.GetWidth(), y), 
+                wxSize(width - zeroPos.x * 4 - chkSize.GetWidth() - 
spcSize.GetWidth(), chkSize.GetHeight()));
+            y += btnSize.GetHeight();
+            cbGroups->Append(wxT("public"));
+            cbGroups->SetSelection(0);
+
+
+            if (needAll)
+            {
+                allPrivileges = new wxCheckBox(this, CTL_ALLPRIV, wxT("ALL"), 
+                    wxPoint(zeroPos.x * 2, y), 
+                    chkSize);
+                allPrivilegesGrant = new wxCheckBox(this, CTL_ALLPRIVGRANT, wxT("WITH 
GRANT OPTION"), 
+                    wxPoint(zeroPos.x * 3 + chkSize.GetWidth(), y), 
+                    wxSize(width - zeroPos.x * 4 - chkSize.GetWidth() - 
spcSize.GetWidth(), chkSize.GetHeight()));
+                y += chkSize.GetHeight();
+                allPrivilegesGrant->Disable();
+            }
+
+            while (privileges.HasMoreTokens())
+            {
+                wxString priv=privileges.GetNextToken();
+                wxCheckBox *cb;
+                cb=new wxCheckBox(this, CTL_PRIVCB+i, priv, 
+                    wxPoint(zeroPos.x * 2, y), 
+                    chkSize);
+                privCheckboxes[i++] = cb;
+                cb=new wxCheckBox(this, CTL_PRIVCB+i, wxT("WITH GRANT OPTION"), 
+                    wxPoint(zeroPos.x * 3 + chkSize.GetWidth(), y), 
+                    wxSize(width - zeroPos.x * 4 - chkSize.GetWidth() - 
spcSize.GetWidth(), chkSize.GetHeight()));
+                cb->Disable();
+                privCheckboxes[i++] = cb;
+
+                y += chkSize.GetHeight();
+            }
+        }
+
+    }
+}
+
+
+ctlSecurityPanel::~ctlSecurityPanel()
+{
+    if (privCheckboxes)
+        delete[] privCheckboxes;
+}
+
+
+
+
+wxString ctlSecurityPanel::GetGrant(const wxString &allPattern, const wxString 
&grantObject, wxArrayString *currentAcl)
+{
+    wxArrayString tmpAcl;
+    if (currentAcl)
+        tmpAcl = *currentAcl;
+
+    wxString sql;
+    int cnt=lbPrivileges->GetItemCount();
+    int pos;
+    unsigned int i;
+
+    for (pos=0 ; pos < cnt ; pos++)
+    {
+        wxString name=lbPrivileges->GetText(pos);
+        wxString value=lbPrivileges->GetText(pos, 1);
+
+        int nameLen=name.Length();
+
+        bool privWasAssigned=false;
+        bool privPartiallyAssigned=false;
+        for (i=0 ; i < tmpAcl.GetCount() ; i++)
+        {
+            if (tmpAcl.Item(i).Left(nameLen) == name)
+            {
+                privPartiallyAssigned=true;
+                if (tmpAcl.Item(i).Mid(nameLen+1) == value)
+                    privWasAssigned=true;
+                tmpAcl.RemoveAt(i);
+                break;
+            }
+        }
+
+        if (name.Left(6).IsSameAs(wxT("group "), false))
+            name = wxT("GROUP ") + qtIdent(name.Mid(6));
+        else
+            name=qtIdent(name);
+
+        if (!privWasAssigned)
+        {
+            if (privPartiallyAssigned)
+                sql += pgObject::GetPrivileges(allPattern, wxT(""), grantObject, 
name);
+            sql += pgObject::GetPrivileges(allPattern, value, grantObject, name);
+        }
+    }
+
+    for (i=0 ; i < tmpAcl.GetCount() ; i++)
+    {
+        wxString name=tmpAcl.Item(i).BeforeLast('=');
+
+        if (name.Left(6).IsSameAs(wxT("group "), false))
+            name = wxT("GROUP ") + qtIdent(name.Mid(6));
+        else
+            name=qtIdent(name);
+        sql += pgObject::GetPrivileges(allPattern, wxT(""), grantObject, name);
+    }
+    return sql;
+}
+
+
+void ctlSecurityPanel::OnPrivCheckAll(wxCommandEvent& ev)
+{
+    bool all=allPrivileges->GetValue();
+    int i;
+    for (i=0 ; i < privilegeCount ; i++)
+    {
+        if (all)
+        {
+            privCheckboxes[i*2]->SetValue(true);
+            privCheckboxes[i*2]->Disable();
+            privCheckboxes[i*2+1]->Disable();
+            allPrivilegesGrant->Enable(GrantAllowed());
+        }
+        else
+        {
+            allPrivilegesGrant->Disable();
+            allPrivilegesGrant->SetValue(false);
+            privCheckboxes[i*2]->Enable();
+            CheckGrantOpt(i);
+        }
+    }
+}
+
+
+
+void ctlSecurityPanel::OnPrivCheckAllGrant(wxCommandEvent& ev)
+{
+    bool grant=allPrivilegesGrant->GetValue();
+    int i;
+    for (i=0 ; i < privilegeCount ; i++)
+        privCheckboxes[i*2+1]->SetValue(grant);
+}
+
+
+void ctlSecurityPanel::OnPrivCheck(wxCommandEvent& ev)
+{
+    int id=(ev.GetId()-CTL_PRIVCB) /2;
+    CheckGrantOpt(id);
+}
+
+
+void ctlSecurityPanel::CheckGrantOpt(int id)
+{
+    bool canGrant=(GrantAllowed() && privCheckboxes[id*2]->GetValue());
+    if (canGrant)
+        privCheckboxes[id*2+1]->Enable();
+    else
+    {
+        privCheckboxes[id*2+1]->SetValue(false);
+        privCheckboxes[id*2+1]->Disable();
+    }
+}
+
+
+void ctlSecurityPanel::OnDelPriv(wxCommandEvent &ev)
+{
+    lbPrivileges->DeleteCurrentItem();
+}
+
+
+void ctlSecurityPanel::OnAddPriv(wxCommandEvent &ev)
+{
+    wxString name=cbGroups->GetValue();
+
+    long pos=lbPrivileges->FindItem(-1, name);
+    if (pos < 0)
+    {
+        pos = lbPrivileges->GetItemCount();
+        int icon=PGICON_USER;
+
+        if (name.Left(6).IsSameAs(wxT("group "), false))
+            icon = PGICON_GROUP;
+        else if (name.IsSameAs(wxT("public"), false))
+            icon = PGICON_PUBLIC;
+
+        lbPrivileges->InsertItem(pos, name, icon);
+    }
+    wxString value;
+    int i;
+    for (i=0 ; i < privilegeCount ; i++)
+    {
+        if (privCheckboxes[i*2]->GetValue())
+        {
+            value += privilegeChars[i];
+            if (privCheckboxes[i*2+1]->GetValue())
+                value += '*';
+        }
+    }
+    lbPrivileges->SetItem(pos, 1, value);
+}
+
+
+void ctlSecurityPanel::OnPrivSelChange(wxListEvent &ev)
+{
+    if (!cbGroups)
+        return;
+    if (allPrivileges)
+    {
+        allPrivileges->SetValue(false);
+        allPrivilegesGrant->SetValue(false);
+        allPrivilegesGrant->Disable();
+    }
+    long pos=lbPrivileges->GetSelection();
+    if (pos >= 0)
+    {
+        wxString name=lbPrivileges->GetText(pos);
+        wxString value=lbPrivileges->GetText(pos, 1);
+
+        pos=cbGroups->FindString(name);
+        if (pos < 0)
+        {
+            cbGroups->Append(name);
+            pos=cbGroups->GetCount()-1;
+        }
+        cbGroups->SetSelection(pos);
+
+        int i;
+        for (i=0 ; i < privilegeCount ; i++)
+        {
+            privCheckboxes[i*2]->Enable();
+            int index=value.Find(privilegeChars[i]);
+            if (index >= 0)
+            {
+                privCheckboxes[i*2]->SetValue(true);
+                privCheckboxes[i*2+1]->SetValue(value.Mid(index+1, 1) == wxT("*"));
+            }
+            else
+                privCheckboxes[i*2]->SetValue(false);
+            CheckGrantOpt(i);
+        }
+    }
+}
+
+
+
+bool ctlSecurityPanel::GrantAllowed() const
+{
+    if (!connection->BackendMinimumVersion(7, 4))
+        return false;
+
+    wxString user=cbGroups->GetValue();
+    if (user.Left(6).IsSameAs(wxT("group "), false) || user.IsSameAs(wxT("public"), 
false))
+        return false;
+
+    return true;
+}
---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faqs/FAQ.html

Reply via email to