Oops..
Missed to attach the patch.
Regards,
Ashesh
On Tue, Dec 2, 2008 at 1:32 PM, Ashesh Vashi
<[EMAIL PROTECTED]>wrote:
> Hi Dave Page,
>
> Please find the updated patch.
>
> Wow - that's a whole lot more code than I was expecting (and explains
> why it took somewhat longer than I planned). What I meant, was that I
> just wanted a replacement dialogue for the existing one. What you've
>
> done is reimplement the join handling, in what I think is a *much*
> nicer way :-)
>
> Thanks
>
>
> The only issues I've seen while testing (on Windows), are:
>
> - The Join label doesn't update on the diagram if you change the join
> type unless you click on the drawing canvas afterwards.
>
> Done
> Only issue, I can see with the combobox within the Grid, is until you loose
> the focus
> (by either pressing return or moving to other cell), the value is not
> getting updated
> for that particular join
>
>
> - Selecting a join should select the corresponding row in the list.
>
> In fact, I implemented this feature on double click.
> Now onwards,
> * For single left click, row will be selected, but the "joins panel" will
> be activate.
> * For double left click, "Joins panel" will be selected and the
> corresponding row in
> the list too.
>
>
> - You are missing updates to include/images/module.mk and
> include/gqb/module.mk. The images should also be added to the VC++
> project file.
>
> Done
>
> Thanks & Regards,
> Ashesh Vashi
>
--
With Regards,
Ashesh Vashi
Software Engineer
EnterpriseDB
(www.enterprisedb.com)
Index: include/images/module.mk
===================================================================
--- include/images/module.mk (revision 7506)
+++ include/images/module.mk (working copy)
@@ -92,6 +92,8 @@
$(srcdir)/include/images/forward.xpm \
$(srcdir)/include/images/function.xpm \
$(srcdir)/include/images/functions.xpm \
+ $(srcdir)/include/images/gqbAdd.xpm \
+ $(srcdir)/include/images/gqbRemove.xpm \
$(srcdir)/include/images/group.xpm \
$(srcdir)/include/images/groups.xpm \
$(srcdir)/include/images/help.xpm \
Index: include/gqb/module.mk
===================================================================
--- include/gqb/module.mk (revision 7506)
+++ include/gqb/module.mk (working copy)
@@ -22,6 +22,7 @@
$(srcdir)/include/gqb/gqbGridOrderTable.h \
$(srcdir)/include/gqb/gqbGridProjTable.h \
$(srcdir)/include/gqb/gqbGridRestTable.h \
+ $(srcdir)/include/gqb/gqbGridJoinTable.h \
$(srcdir)/include/gqb/gqbModel.h \
$(srcdir)/include/gqb/gqbObject.h \
$(srcdir)/include/gqb/gqbObjectCollection.h \
Index: include/gqb/gqbViewPanels.h
===================================================================
--- include/gqb/gqbViewPanels.h (revision 7506)
+++ include/gqb/gqbViewPanels.h (working copy)
@@ -15,9 +15,11 @@
#include <wx/minifram.h>
// App headers
+#include "gqb/gqbViewController.h"
#include "gqb/gqbGridProjTable.h"
#include "gqb/gqbGridRestTable.h"
#include "gqb/gqbGridOrderTable.h"
+#include "gqb/gqbGridJoinTable.h"
enum gridButtons
{
@@ -28,6 +30,9 @@
GQB_COLS_ADD_BUTTON_ID,
GQB_COLS_DROP_BUTTON_ID,
+ GQB_JOIN_COLS_ADD_BUTTON_ID,
+ GQB_JOIN_COLS_DELETE_BUTTON_ID,
+
GQB_ORDER_DROP_BUTTON_ID,
GQB_ORDER_DROP_ALL_BUTTON_ID,
GQB_ORDER_ADD_ALL_BUTTON_ID,
@@ -77,7 +82,9 @@
gqbColsTree(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style);
wxTreeItemId& createRoot(wxString &Name);
wxTreeItemId& getRootNode(){return rootNode;}
- void refreshTree(gqbModel *model);
+ void refreshTree(gqbModel *model, gqbQueryObject *doNotInclude=NULL);
+ virtual void DeleteAllItems();
+ ~gqbColsTree() { DeleteAllItems(); }
private:
wxTreeItemId rootNode;
@@ -93,7 +100,7 @@
{
public:
gqbColsPopUp(wxWindow* parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size);
- void refreshTree(gqbModel *_model);
+ virtual void refreshTree(gqbModel *_model);
void OnPopUpOKClick(wxCommandEvent& event);
void OnPopUpTreeClick(wxTreeEvent& event);
void OnPopUpTreeDoubleClick(wxTreeEvent& event);
@@ -102,7 +109,7 @@
void setUsedCell(wxGrid* grid, int row, int col){usedGrid=grid; _row=row; _col=col;};
void focus();
-private:
+protected:
int _row,_col;
wxGrid *usedGrid;
gqbColsTree *colsTree;
@@ -112,14 +119,40 @@
};
+class gqbJoinsPanel;
+
+class gqbJoinsPopUp: public gqbColsPopUp
+{
+public:
+ gqbJoinsPopUp(
+ gqbJoinsPanel* parent, wxWindowID id, wxString title, wxPoint pos,
+ const wxSize size, gqbQueryJoin* _join, bool isSource,
+ gqbGridJoinTable* _gmodel);
+ void OnPopUpOKClick(wxCommandEvent& event);
+ void OnPopUpTreeClick(wxTreeEvent& event);
+ void OnPopUpTreeDoubleClick(wxTreeEvent& event);
+
+ // This should be called through OnPopUpOKClick & OnPopUpTreeDoubleClick
+ void updateJoin();
+
+ virtual void refreshTree(gqbModel* _model);
+
+private:
+ gqbQueryJoin *join; // Not owned, shouldn't be deletedat this class
+ gqbQueryObject *selectedTbl; //Not owned, shouldn't be deletedat this class
+ gqbColumn *selectedCol; //Not owned, shouldn't be deletedat this class
+ bool isSource;
+ gqbGridJoinTable *gModel; //Not owned, shouldn't be deletedat this class
+};
+
//
// Criterias Panel
//
-class wxRestrictionGrid: public wxGrid
+class gqbCustomGrid: public wxGrid
{
public:
- wxRestrictionGrid(wxWindow* parent, wxWindowID id);
+ gqbCustomGrid(wxWindow* parent, wxWindowID id);
void ComboBoxEvent(wxGridEvent& event);
void RevertSel();
@@ -150,6 +183,31 @@
};
+class gqbJoinsPanel: public wxPanel
+{
+public:
+ gqbJoinsPanel(wxWindow* parent, gqbModel *_model, gqbGridJoinTable *_gmodel, gqbController *_controller);
+ void OnCellLeftClick(wxGridEvent& ev);
+ void refreshTree(gqbModel *_model);
+ void OnButtonAdd(wxCommandEvent&);
+ void OnButtonDrop(wxCommandEvent&);
+ void SetGridColsSize();
+ void updateView(gqbQueryObject *tbl);
+ void updatedJoinType(gqbQueryJoin *join);
+
+private:
+ wxBitmapButton *buttonAdd, *buttonDrop;
+ wxBitmap addBitmap, dropBitmap;
+ void showColsPopUp(int row, int col, wxPoint pos);
+ wxGrid *joinsGrid;
+ gqbModel *model; // Not owned shouldn't be deleted at this class
+ gqbJoinsPopUp *joinsPopUp; // It will be automatically deleted
+ gqbGridJoinTable *gModel; // Not owned shouldn't be deleted at this class
+ gqbController *controller; // Not owned shouldn't be deleted at this class
+ DECLARE_EVENT_TABLE()
+
+};
+
//
// Order by Panel
//
Index: include/gqb/gqbViewController.h
===================================================================
--- include/gqb/gqbViewController.h (revision 7506)
+++ include/gqb/gqbViewController.h (working copy)
@@ -27,6 +27,7 @@
#include "gqb/gqbGridProjTable.h"
#include "gqb/gqbGridRestTable.h"
#include "gqb/gqbGridOrderTable.h"
+#include "gqb/gqbGridJoinTable.h"
#include "gqb/gqbBrowser.h"
class gqbView;
@@ -52,6 +53,15 @@
DECLARE_EVENT_TABLE()
};
+// This enum is useful to select particular page from the tabs
+enum tabsIndex
+{
+ ti_colsGridPanel = 0,
+ ti_criteriaPanel,
+ ti_orderPanel,
+ ti_joinsPanel
+};
+
class gqbController: public wxObject
{
public:
@@ -109,8 +119,11 @@
wxPanel* getColsGridPanel(){ return (wxPanel*)projectionPanel; };
wxPanel* getCriteriaPanel(){ return (wxPanel*)criteriaPanel; };
wxPanel* getOrderPanel(){ return (wxPanel*)orderPanel; };
+ wxPanel* getJoinsPanel() { return joinsPanel; }
void newTableAdded(gqbQueryObject *item);
bool clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest);
+ void updateTable(gqbQueryObject *table);
+ void updateJoin(gqbQueryJoin *join);
// Functions for all gqb extra Panels (projection, criteria..)
void emptyPanelsData();
@@ -124,9 +137,10 @@
// if change the way objects were draw changes too.
gqbIteratorBase *iterator; //include here for reuse of iterator, should be
// delete when class destroy
- wxPanel *projectionPanel, *criteriaPanel, *orderPanel;
+ wxPanel *projectionPanel, *criteriaPanel, *orderPanel, *joinsPanel;
gqbGridProjTable *gridTable; // Data model for the columns grid internals
gqbGridRestTable *restrictionsGridTable; // Data model for restricions grid internals
+ gqbGridJoinTable *joinsGridTable; // Data model for joins grid internals
gqbGridOrderTable *orderByLGridTable, *orderByRGridTable; // Data model for order by grid internals
wxSize canvasSize;
@@ -144,7 +158,6 @@
wxMenu *m_rightJoins, *m_rightTables;
void OnMenuJoinDelete(wxCommandEvent& event);
void OnMenuTableDelete(wxCommandEvent& event);
- void OnMenuJoinSetType(wxCommandEvent& event);
void OnMenuTableSetAlias(wxCommandEvent& event);
wxArrayString joinTypeChoices;
DECLARE_EVENT_TABLE()
Index: include/gqb/gqbArrayCollection.h
===================================================================
--- include/gqb/gqbArrayCollection.h (revision 7506)
+++ include/gqb/gqbArrayCollection.h (working copy)
@@ -59,6 +59,7 @@
void insertAtIndex(gqbObject *item, int index);
void deleteAll();
void removeAll();
+ gqbObject *& operator[](size_t index) { return gqbArray[index]; }
private:
gqbObjsArray gqbArray;
Index: pgAdmin3.vcproj
===================================================================
--- pgAdmin3.vcproj (revision 7506)
+++ pgAdmin3.vcproj (working copy)
@@ -1286,6 +1286,14 @@
>
</File>
<File
+ RelativePath=".\include\images\gqbAdd.xpm"
+ >
+ </File>
+ <File
+ RelativePath=".\include\images\gqbRemove.xpm"
+ >
+ </File>
+ <File
RelativePath=".\include\images\group.xpm"
>
</File>
@@ -2414,6 +2422,10 @@
>
</File>
<File
+ RelativePath=".\include\gqb\gqbGridJoinTable.h"
+ >
+ </File>
+ <File
RelativePath=".\include\gqb\gqbGridProjTable.h"
>
</File>
@@ -3587,6 +3599,10 @@
>
</File>
<File
+ RelativePath=".\gqb\gqbGridJoinTable.cpp"
+ >
+ </File>
+ <File
RelativePath=".\gqb\gqbGridProjTable.cpp"
>
</File>
Index: gqb/gqbView.cpp
===================================================================
--- gqb/gqbView.cpp (revision 7506)
+++ gqb/gqbView.cpp (working copy)
@@ -45,7 +45,6 @@
EVT_ERASE_BACKGROUND(gqbView::onEraseBackGround) //This erase flicker create by wxStaticText when erasing background but this is not needed
EVT_KEY_DOWN(gqbView::OnKeyDown)
EVT_MENU(GQB_RMJ_DELETE, gqbView::OnMenuJoinDelete)
-EVT_MENU(GQB_RMJ_SETTYPE, gqbView::OnMenuJoinSetType)
EVT_MENU(GQB_RMT_DELETE, gqbView::OnMenuTableDelete)
EVT_MENU(GQB_RMT_SETALIAS, gqbView::OnMenuTableSetAlias)
END_EVENT_TABLE()
@@ -95,6 +94,10 @@
this->restrictionsGridTable = new gqbGridRestTable(model->getRestrictions());
this->criteriaPanel = new gqbCriteriaPanel(controller->getTabs(),model,restrictionsGridTable);
+ // Create Joins Panel
+ this->joinsGridTable = new gqbGridJoinTable(this->model);
+ this->joinsPanel = new gqbJoinsPanel(controller->getTabs(), model, joinsGridTable, controller);
+
// Create Order by Panel
this->orderByLGridTable = new gqbGridOrderTable(1,model->getOrdByAvailColumns(),model->getOrdByAvailParents(),NULL);
this->orderByRGridTable = new gqbGridOrderTable(2,model->getOrdByColumns(), model->getOrdByParents(),model->getOrdByKind());
@@ -162,7 +165,6 @@
if(!m_rightJoins)
{
m_rightJoins = new wxMenu;
- m_rightJoins->Append(GQB_RMJ_SETTYPE, _("&Set Join Type"));
m_rightJoins->Append(GQB_RMJ_DELETE, _("&Delete Join"));
}
cTempSelected=NULL;
@@ -177,6 +179,7 @@
{
if(jTempSelected)
{
+ this->joinsGridTable->removeJoin(joinSelected);
controller->removeJoin(jTempSelected);
jTempSelected=NULL;
this->Refresh();
@@ -184,46 +187,6 @@
}
-void gqbView::OnMenuJoinSetType(wxCommandEvent& WXUNUSED(event))
-{
-// Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign
-// as his parent the main container of the view, and void the bug
- if(jTempSelected)
- {
- wxSingleChoiceDialog dialog(controller->getDialogParent(),
- _("Select the kind of Join"),
- _("Please select a type of Join for relation, e.g. = "),
- joinTypeChoices,
- NULL,
- wxOK | wxCANCEL| wxCENTRE);
- dialog.SetSelection(0);
- if (dialog.ShowModal() == wxID_OK)
- {
- if(dialog.GetStringSelection().Contains(wxT(" = ")))
- {
- jTempSelected->setKindofJoin(_equally);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" > ")))
- {
- jTempSelected->setKindofJoin(_greater);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" < ")))
- {
- jTempSelected->setKindofJoin(_lesser);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" >= ")))
- {
- jTempSelected->setKindofJoin(_equgreater);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" <= ")))
- {
- jTempSelected->setKindofJoin(_equlesser);
- }
- }
- }
-}
-
-
void gqbView::OnMenuTableDelete(wxCommandEvent& WXUNUSED(event))
{
if(cTempSelected)
@@ -246,8 +209,12 @@
_("Please enter an alias for the table."),
wxT(""),
wxOK | wxCANCEL| wxCENTRE);
+ dialog.SetValue(cTempSelected->getAlias());
if (dialog.ShowModal() == wxID_OK)
+ {
cTempSelected->setAlias(dialog.GetValue());
+ joinsPanel->Refresh();
+ }
cTempSelected=NULL;
this->Refresh();
}
@@ -277,42 +244,19 @@
_("Please enter an alias for the table."),
wxT(""),
wxOK | wxCANCEL| wxCENTRE);
+ dialog.SetValue(t->getAlias());
if (dialog.ShowModal() == wxID_OK)
+ {
t->setAlias(dialog.GetValue());
+ joinsPanel->Refresh();
+ }
}
else if(anySelected->getType()==GQB_JOIN)
{
gqbQueryJoin *j = (gqbQueryJoin *) anySelected;
- wxSingleChoiceDialog dialog(controller->getDialogParent(),
- _("Select the kind of join"),
- _("Please select a type of join between the relations."),
- joinTypeChoices,
- NULL,
- wxOK | wxCANCEL| wxCENTRE);
- dialog.SetSelection(0);
- if (dialog.ShowModal() == wxID_OK)
- {
- if(dialog.GetStringSelection().Contains(wxT(" = ")))
- {
- j->setKindofJoin(_equally);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" > ")))
- {
- j->setKindofJoin(_greater);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" < ")))
- {
- j->setKindofJoin(_lesser);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" >= ")))
- {
- j->setKindofJoin(_equgreater);
- }
- else if(dialog.GetStringSelection().Contains(wxT(" <= ")))
- {
- j->setKindofJoin(_equlesser);
- }
- }
+
+ controller->getTabs()->ChangeSelection(ti_joinsPanel);
+ this->joinsGridTable->selectJoin(j);
}
}
this->Refresh();
@@ -454,6 +398,9 @@
if(mode==pt_normal)
{
changeTOpressed=false;
+ anySelected=controller->getModelSelected(pos, collectionSelected, joinSelected, false);
+ if (anySelected && anySelected->getType() == GQB_JOIN)
+ this->joinsGridTable->selectJoin((gqbQueryJoin *)anySelected);
}
// Pointer is used to add joins
else if(mode==pt_join)
@@ -490,6 +437,7 @@
// GQB-TODO: Allow other type of joins
gqbQueryJoin *qj=controller->addJoin(joinSource,joinSCol,joinDest,joinDCol,_equally);
graphBehavior->calcAnchorPoint(qj);
+ this->joinsGridTable->AppendJoin(qj);
}
// Let the temporary join line to be draw again [Don't destroy anything because all object where own by other objects this are just pointers]
joinSource=NULL;
@@ -546,6 +494,7 @@
{
if(collectionSelected)
{
+ this->joinsGridTable->removeJoins(collectionSelected);
controller->removeTableFromModel(collectionSelected,gridTable,orderByLGridTable,orderByRGridTable);
collectionSelected=NULL;
this->Refresh();
@@ -553,6 +502,7 @@
if(joinSelected)
{
+ this->joinsGridTable->removeJoin(joinSelected);
controller->removeJoin(joinSelected);
joinSelected=NULL;
this->Refresh();
@@ -641,6 +591,7 @@
void gqbView::emptyPanelsData()
{
gridTable->emptyTableData();
+ this->joinsGridTable->emptyTableData();
}
@@ -656,3 +607,39 @@
orderByLGridTable->GetView()->ProcessTableMessage( msg );
}
}
+
+void gqbView::updateTable(gqbQueryObject *queryTable)
+{
+ if (queryTable->getHaveJoins())
+ {
+ gqbIteratorBase *j=queryTable->createJoinsIterator();
+ while (j->HasNext())
+ {
+ gqbQueryJoin *tmp= (gqbQueryJoin *)j->Next();
+ graphBehavior->calcAnchorPoint(tmp);
+ }
+ delete j;
+ }
+
+ // Update position of anchor points of Joins that come from others tables
+ if (queryTable->getHaveRegJoins())
+ {
+ gqbIteratorBase *r=queryTable->createRegJoinsIterator();
+ while (r->HasNext())
+ {
+ gqbQueryJoin *tmp= (gqbQueryJoin *)r->Next();
+ graphBehavior->calcAnchorPoint(tmp);
+ }
+ delete r;
+ }
+ this->Refresh();
+}
+
+void gqbView::updateJoin(gqbQueryJoin *join)
+{
+ if (join)
+ {
+ graphBehavior->calcAnchorPoint(join);
+ this->Refresh();
+ }
+}
Index: gqb/gqbViewPanels.cpp
===================================================================
--- gqb/gqbViewPanels.cpp (revision 7506)
+++ gqb/gqbViewPanels.cpp (working copy)
@@ -25,6 +25,7 @@
#include "gqb/gqbGridProjTable.h"
#include "gqb/gqbGridRestTable.h"
#include "gqb/gqbGridOrderTable.h"
+#include "gqb/gqbGridJoinTable.h"
// Images
#include "images/gqbUp.xpm"
@@ -41,7 +42,13 @@
#include "images/table-sm.xpm"
#include "images/column-sm.xpm"
#include "images/view-sm.xpm"
+#include "images/gqbAdd.xpm"
+#include "images/gqbRemove.xpm"
+// Get available ID for Criteria & Joins Panel
+long CRITERIA_PANEL_RESTRICTION_GRID_ID = ::wxNewId();
+long JOINS_PANEL_GRID_ID = ::wxNewId();
+
//
// View Columns Grid Panel Class.
//
@@ -383,10 +390,50 @@
}
-void gqbColsTree::refreshTree(gqbModel * model)
+// Override the DeleteAllItems virtual function
+// Needs to set null as item-data, otherwise they will delete
+// the gqbQueryObject(s) and gqbColumn(s), while deleting these
+// items
+void gqbColsTree::DeleteAllItems()
{
+ wxTreeItemId tableId;
+ wxTreeItemIdValue tableCookie;
+ wxTreeItemId rootId = this->GetRootItem();
+
+ if ( this->GetChildrenCount(rootId, false) != 0 )
+ {
+ wxTreeItemId lastTableId = this->GetLastChild(rootId);
+ tableId = this->GetFirstChild(rootId, tableCookie);
+ while ( true )
+ {
+ this->SetItemData(tableId, NULL);
+ wxTreeItemIdValue colCookie;
+ wxTreeItemId colId = this->GetFirstChild(tableId, colCookie);
+ wxTreeItemId lastColId = this->GetLastChild(tableId);
+ if ( this->GetChildrenCount(tableId, false) != 0 )
+ {
+ while ( true )
+ {
+ this->SetItemData(colId, NULL);
+ if ( colId != lastColId )
+ colId = this->GetNextSibling(colId);
+ else
+ break;
+ }
+ }
+ if ( lastTableId != tableId )
+ tableId = this->GetNextSibling(tableId);
+ else
+ break;
+ }
+ }
+ wxTreeCtrl::DeleteAllItems();
+}
+
+void gqbColsTree::refreshTree(gqbModel * model, gqbQueryObject *doNotInclude)
+{
// This remove and delete data inside tree's node
- this->DeleteAllItems();
+ this->DeleteAllItems();
wxString a=_("Select column");
createRoot(a);
this->Expand(rootNode);
@@ -396,26 +443,29 @@
while(iterator->HasNext())
{
gqbQueryObject *tmpTable= (gqbQueryObject *)iterator->Next();
+
+ if (doNotInclude && tmpTable == doNotInclude)
+ continue;
- int iconIndex;
- if (tmpTable->parent->getType() == GQB_TABLE)
- iconIndex = 1;
- else // Must be a view
- iconIndex = 3;
+ int iconIndex;
+ if (tmpTable->parent->getType() == GQB_TABLE)
+ iconIndex = 1;
+ else // Must be a view
+ iconIndex = 3;
if(tmpTable->getAlias().length()>0)
{
- parent=this->AppendItem(rootNode, tmpTable->getAlias() , iconIndex, iconIndex, NULL);
+ parent=this->AppendItem(rootNode, tmpTable->getAlias() , iconIndex, iconIndex, tmpTable);
}
else
{
- parent=this->AppendItem(rootNode, tmpTable->getName() , iconIndex, iconIndex, NULL);
+ parent=this->AppendItem(rootNode, tmpTable->getName() , iconIndex, iconIndex, tmpTable);
}
gqbIteratorBase *colsIterator = tmpTable->parent->createColumnsIterator();
while(colsIterator->HasNext())
{
gqbColumn *tmpColumn= (gqbColumn *)colsIterator->Next();
- this->AppendItem(parent, tmpColumn->getName() , 2, 2,NULL);
+ this->AppendItem(parent, tmpColumn->getName() , 2, 2, tmpColumn);
}
delete colsIterator;
}
@@ -546,13 +596,11 @@
gModel=gridModel;
colsPopUp=NULL;
- // GQB-TODO: add real ID not 321
- // wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP,wxT(""));
- this->restrictionsGrid = new wxRestrictionGrid(this, 321);
+ this->restrictionsGrid = new gqbCustomGrid(this, CRITERIA_PANEL_RESTRICTION_GRID_ID);
restrictionsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells);
this->restrictionsGrid->SetSelectionMode(wxGrid::wxGridSelectRows);
- this->Connect(321, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbCriteriaPanel::OnCellLeftClick);
+ this->Connect(CRITERIA_PANEL_RESTRICTION_GRID_ID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbCriteriaPanel::OnCellLeftClick);
// GQB-TODO: in a future implement OnMouseWheel
addBitmap= wxBitmap(gqbAddRest_xpm);
@@ -633,7 +681,7 @@
void gqbCriteriaPanel::OnCellLeftClick(wxGridEvent& event)
{
wxObject *object = event.GetEventObject();
- wxRestrictionGrid *grid = wxDynamicCast( object, wxRestrictionGrid );
+ gqbCustomGrid *grid = wxDynamicCast( object, gqbCustomGrid );
// Only show editor y case of column 1
if(event.GetCol()==1)
@@ -718,7 +766,7 @@
//
// View Selection Criteria Panel Class's Grid.
//
-wxRestrictionGrid::wxRestrictionGrid(wxWindow* parent, wxWindowID id):
+gqbCustomGrid::gqbCustomGrid(wxWindow* parent, wxWindowID id):
wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_BESTWRAP,wxT("")),
m_selTemp(NULL)
{
@@ -737,7 +785,7 @@
}
-void wxRestrictionGrid::RevertSel()
+void gqbCustomGrid::RevertSel()
{
if (m_selTemp)
{
@@ -748,7 +796,7 @@
}
-void wxRestrictionGrid::ComboBoxEvent(wxGridEvent& event)
+void gqbCustomGrid::ComboBoxEvent(wxGridEvent& event)
{
// This forces the cell to go into edit mode directly
@@ -772,7 +820,7 @@
}
// hack to prevent selection from being lost when click combobox
- if (event.GetCol() == 0 && this->IsInSelection(event.GetRow(), event.GetCol()))
+ if (this->IsInSelection(event.GetRow(), event.GetCol()))
{
this->m_selTemp = this->m_selection;
this->m_selection = NULL;
@@ -1266,3 +1314,310 @@
}
event.Skip();
}
+
+// Popup window for gqbJoinsPanel
+//
+gqbJoinsPopUp::gqbJoinsPopUp(
+ gqbJoinsPanel* parent, wxWindowID id, wxString title,
+ wxPoint pos, const wxSize size, gqbQueryJoin *_join,
+ bool isSource, gqbGridJoinTable* _gmodel)
+:gqbColsPopUp(parent, id, title, pos, size)
+{
+ this->editTree->SetEditable(false);
+
+ // Handles different events for Ok button, single mouse click, double mouse click
+ this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbJoinsPopUp::OnPopUpOKClick);
+ this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbJoinsPopUp::OnPopUpTreeDoubleClick);
+ this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbJoinsPopUp::OnPopUpTreeClick);
+
+ this->selectedTbl = NULL;
+ this->selectedCol = NULL;
+ this->join = _join;
+ this->isSource = isSource;
+ this->gModel = _gmodel;
+}
+
+void gqbJoinsPopUp::refreshTree(gqbModel *_model)
+{
+ model=_model;
+ if(colsTree && _model)
+ {
+ // Do not include already included Table
+ // For self join, other entity for the same table should be used with alias
+ if ( join )
+ colsTree->refreshTree(model, isSource ? join->getDestQTable() : join->getSourceQTable());
+ else
+ colsTree->refreshTree(model);
+ }
+}
+
+// single mouse click on tree
+void gqbJoinsPopUp::OnPopUpTreeClick(wxTreeEvent& event)
+{
+ if( colsTree )
+ {
+ wxTreeItemId itemId = event.GetItem();
+ wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId);
+
+ if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem()!=itemId))
+ {
+ selectedCol = (gqbColumn *)colsTree->GetItemData(itemId);
+ selectedTbl = (gqbQueryObject *)colsTree->GetItemData(itemIdParent);
+ this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId)));
+ }
+ else
+ {
+ selectedCol = NULL;
+ selectedTbl = NULL;
+ }
+ }
+}
+
+
+void gqbJoinsPopUp::OnPopUpOKClick(wxCommandEvent& event)
+{
+ if( colsTree && selectedCol && selectedTbl )
+ {
+ // This should update the selected Join with the new values.
+ updateJoin();
+ }
+
+ this->MakeModal(false);
+ this->Hide();
+ this->GetParent()->Refresh();
+ this->join = NULL;
+ this->selectedCol = NULL;
+ this->selectedTbl = NULL;
+}
+
+
+// Update the view fo this query table, involved in
+// the whole operation
+void gqbJoinsPanel::updateView(gqbQueryObject *table)
+{
+ if (table)
+ controller->getView()->updateTable(table);
+}
+
+void gqbJoinsPopUp::updateJoin()
+{
+ if ((isSource ? join->getSCol() : join->getDCol()) != selectedCol)
+ {
+ // Create a new join with the existing data
+ // Replace it in the gqbJoinTable with the existing one
+ // Unregister the join, if exists
+ gqbQueryObject *srcTbl = ( isSource ? selectedTbl : join->getSourceQTable() );
+ gqbQueryObject *destTbl = ( isSource ? join->getDestQTable() : selectedTbl );
+ gqbColumn *srcCol = ( isSource ? selectedCol : join->getSCol() );
+ gqbColumn *destCol = ( isSource ? join->getDCol() : selectedCol );
+ type_Join joinType = join->getKindofJoin();
+
+ gqbQueryJoin *newJoin = NULL;
+ if( srcTbl && destTbl )
+ {
+ newJoin = srcTbl->addJoin(srcTbl, destTbl, srcCol, destCol, joinType);
+ ((gqbJoinsPanel *)GetParent())->updateView(newJoin->getSourceQTable());
+ }
+ else
+ newJoin = new gqbQueryJoin(srcTbl, destTbl, srcCol, destCol, joinType);
+
+ gModel->ReplaceJoin(join, newJoin);
+
+ if (join->getSourceQTable() && join->getDestQTable())
+ {
+ // This will remove the join object too
+ gqbQueryObject* srcObj = join->getSourceQTable();
+ srcObj->removeJoin(join, true);
+ }
+ else
+ {
+ delete join;
+ }
+ join = newJoin;
+ }
+}
+
+
+void gqbJoinsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent& event)
+{
+ if(colsTree)
+ {
+ wxTreeItemId itemId = event.GetItem();
+ wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId);
+ if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem()!=itemId))
+ {
+ selectedCol = (gqbColumn *)colsTree->GetItemData(itemId);
+ selectedTbl = (gqbQueryObject *)colsTree->GetItemData(itemIdParent);
+
+ updateJoin();
+
+ this->MakeModal(false);
+ this->Hide();
+ this->GetParent()->Refresh();
+ this->join = NULL;
+ this->selectedCol = NULL;
+ this->selectedTbl = NULL;
+ }
+ }
+}
+
+//
+// View Selection Joins Panel Class.
+//
+
+BEGIN_EVENT_TABLE(gqbJoinsPanel, wxPanel)
+EVT_BUTTON(GQB_JOIN_COLS_ADD_BUTTON_ID, gqbJoinsPanel::OnButtonAdd)
+EVT_BUTTON(GQB_JOIN_COLS_DELETE_BUTTON_ID, gqbJoinsPanel::OnButtonDrop)
+END_EVENT_TABLE()
+
+gqbJoinsPanel::gqbJoinsPanel(wxWindow* parent, gqbModel *_model, gqbGridJoinTable* _gmodel, gqbController *_controller):
+wxPanel(parent, wxID_ANY)
+{
+ model=_model;
+ gModel=_gmodel;
+ controller=_controller;
+ joinsPopUp=NULL;
+
+ this->joinsGrid = new gqbCustomGrid(this, JOINS_PANEL_GRID_ID);
+ joinsGrid->CreateGrid(0, 5, wxGrid::wxGridSelectRows);
+ joinsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells);
+ this->joinsGrid->SetSelectionMode(wxGrid::wxGridSelectRows);
+
+ this->Connect(JOINS_PANEL_GRID_ID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbJoinsPanel::OnCellLeftClick);
+ // GQB-TODO: in a future implement OnMouseWheel
+
+ addBitmap= wxBitmap(gqbAdd_xpm);
+ dropBitmap= wxBitmap(gqbRemove_xpm);
+ buttonAdd= new wxBitmapButton( this, GQB_JOIN_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add"));
+ buttonDrop= new wxBitmapButton( this, GQB_JOIN_COLS_DELETE_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove"));
+
+ wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );
+ horizontalSizer->Add(joinsGrid,
+ 1, // make vertically stretchable
+ wxEXPAND | // make horizontally stretchable
+ wxALL, // and make border all around
+ 3 ); // set border width to 10
+
+ wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL );
+
+ buttonsSizer->Add(
+ this->buttonAdd,
+ 0, // make horizontally unstretchable
+ wxALL, // make border all around (implicit top alignment)
+ 10 ); // set border width to 10
+
+ buttonsSizer->Add(
+ this->buttonDrop,
+ 0, // make horizontally unstretchable
+ wxALL, // make border all around (implicit top alignment)
+ 10 ); // set border width to 10
+
+ horizontalSizer->Add(
+ buttonsSizer,
+ 0, // make vertically unstretchable
+ wxALIGN_CENTER ); // no border and centre horizontally
+
+ this->SetSizer(horizontalSizer);
+}
+
+
+void gqbJoinsPanel::showColsPopUp(int row, int col, wxPoint pos)
+{
+ if( joinsPopUp )
+ {
+ joinsPopUp->Destroy();
+ joinsPopUp = NULL;
+ }
+ joinsPopUp = new gqbJoinsPopUp(this,-1,wxT("Select Column"),wxDefaultPosition,wxDefaultSize, this->gModel->GetJoin(row), ( col == 0 ? true : false ), this->gModel);
+
+ refreshTree(model);
+
+ // Set initial Value
+ joinsPopUp->setEditText(joinsGrid->GetCellValue(row,col));
+
+ // Set Position for Pop Up Tree
+ // Position of wxNotebook
+ wxPoint p=this->GetParent()->GetPosition();
+ p.x+=pos.x;
+ p.y+=pos.y;
+ wxPoint p2=this->GetPosition();
+
+ // Position of panel inside wxNotebook
+ p.x+=p2.x;
+ p.y+=p2.y+40;
+ joinsPopUp->SetPosition(p);
+ joinsPopUp->Show();
+ joinsPopUp->MakeModal(true);
+ joinsPopUp->focus();
+ joinsPopUp->setUsedCell(joinsGrid,row,col);
+}
+
+
+void gqbJoinsPanel::refreshTree(gqbModel *_model)
+{
+ model=_model;
+ if(joinsPopUp && model)
+ joinsPopUp->refreshTree(model);
+}
+
+
+void gqbJoinsPanel::OnCellLeftClick(wxGridEvent& event)
+{
+ wxObject *object = event.GetEventObject();
+ gqbCustomGrid *grid = wxDynamicCast( object, gqbCustomGrid );
+
+ // Only show editor y case of column 1
+ if(event.GetCol()==1)
+ {
+ grid->ComboBoxEvent(event);
+ } else if(event.GetCol()==0 || event.GetCol()==2)
+ {
+ // Allow mini browser frame to be visible to user
+ wxRect cellSize=grid->CellToRect(event.GetRow(), event.GetCol());
+ wxPoint p = event.GetPosition();
+ joinsGrid->CalcUnscrolledPosition(p.x,p.y,&p.x,&p.y);
+
+ // Number 17 is button's width at cellRender function [nButtonWidth]
+ if((grid->GetRowLabelSize()+cellSize.GetRight())-(p.x) <= 17 )
+ {
+ p = event.GetPosition();
+ showColsPopUp(event.GetRow(), event.GetCol(),p);
+ }
+ }
+ event.Skip();
+}
+
+
+void gqbJoinsPanel::OnButtonAdd(wxCommandEvent&)
+{
+ this->gModel->AppendJoin( NULL );
+}
+
+
+void gqbJoinsPanel::OnButtonDrop(wxCommandEvent&)
+{
+ if(joinsGrid->GetGridCursorRow()>=0)
+ {
+ gqbQueryObject *updateTbl = gModel->DeleteRow(joinsGrid->GetGridCursorRow());
+ if (updateTbl)
+ controller->getView()->updateTable(updateTbl);
+ }
+ joinsGrid->Refresh();
+}
+
+
+void gqbJoinsPanel::SetGridColsSize()
+{
+ // After sizers determine the width of Grid then calculate the % space for each column about 33% each one
+ int size=(int)((joinsGrid->GetSize().GetWidth() - joinsGrid->GetRowLabelSize())*0.3);
+ joinsGrid->SetColSize(0,size);
+ joinsGrid->SetColSize(1,size);
+ joinsGrid->SetColSize(2,size);
+}
+
+void gqbJoinsPanel::updatedJoinType(gqbQueryJoin *join)
+{
+ controller->getView()->updateJoin(join);
+}
+
+
Index: gqb/module.mk
===================================================================
--- gqb/module.mk (revision 7506)
+++ gqb/module.mk (working copy)
@@ -20,6 +20,7 @@
$(srcdir)/gqb/gqbGridOrderTable.cpp \
$(srcdir)/gqb/gqbGridProjTable.cpp \
$(srcdir)/gqb/gqbGridRestTable.cpp \
+ $(srcdir)/gqb/gqbGridJoinTable.cpp \
$(srcdir)/gqb/gqbModel.cpp \
$(srcdir)/gqb/gqbObject.cpp \
$(srcdir)/gqb/gqbObjectCollection.cpp \
Index: gqb/gqbQueryObjs.cpp
===================================================================
--- gqb/gqbQueryObjs.cpp (revision 7506)
+++ gqb/gqbQueryObjs.cpp (working copy)
@@ -23,6 +23,8 @@
#include "gqb/gqbObjectCollection.h"
#include "gqb/gqbViewPanels.h"
+const wxString wxEmptyStr = wxEmptyString;
+
//
// Collections of Tables inside a Query, data structured used for query storage & later generation of SQL sentence
//
@@ -348,6 +350,8 @@
const wxString& gqbQueryJoin::getSourceTable()
{
+ if (!owner)
+ return wxEmptyStr;
gqbTable *s=(gqbTable*)&sCol->getOwner();
return s->getName();
}
@@ -355,6 +359,8 @@
const wxString& gqbQueryJoin::getDestTable()
{
+ if (!destination)
+ return wxEmptyStr;
gqbTable *d=(gqbTable*)&dCol->getOwner();
return d->getName();
}
@@ -362,12 +368,16 @@
const wxString& gqbQueryJoin::getSourceCol()
{
+ if (!sCol)
+ return wxEmptyStr;
return sCol->getName();
}
const wxString& gqbQueryJoin::getDestCol()
{
+ if (!dCol)
+ return wxEmptyStr;
return dCol->getName();
}
Index: gqb/gqbController.cpp
===================================================================
--- gqb/gqbController.cpp (revision 7506)
+++ gqb/gqbController.cpp (working copy)
@@ -54,9 +54,10 @@
view->SetScrollbars( 10, 10, 127, 80 );
gqbContainer->SplitVertically(browserPanel,view);
- tabs->AddPage(view->getColsGridPanel(), _("Columns"));
- tabs->AddPage(view->getCriteriaPanel(), _("Criteria"));
- tabs->AddPage(view->getOrderPanel(), _("Ordering"));
+ tabs->InsertPage(ti_colsGridPanel, view->getColsGridPanel(), _("Columns"));
+ tabs->InsertPage(ti_criteriaPanel, view->getCriteriaPanel(), _("Criteria"));
+ tabs->InsertPage(ti_orderPanel, view->getOrderPanel(), _("Ordering"));
+ tabs->InsertPage(ti_joinsPanel, view->getJoinsPanel(), _("Joins"));
gqbMainContainer->SplitHorizontally(gqbContainer,tabs);
// Fix Sash resize bug
@@ -536,6 +537,7 @@
((gqbGridPanel *)view->getColsGridPanel())->SetGridColsSize();
((gqbCriteriaPanel *)view->getCriteriaPanel())->SetGridColsSize();
((gqbOrderPanel *)view->getOrderPanel())->SetGridColsSize();
+ ((gqbJoinsPanel *)view->getJoinsPanel())->SetGridColsSize();
}
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers