pgadmin3/gqb/gqbViewPanels.cpp
2020-07-07 22:19:12 +05:00

1648 lines
50 KiB
C++

//////////////////////////////////////////////////////////////////////////
//
// pgAdmin III - PostgreSQL Tools
//
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
// gqbViewPanels.cpp - All panels used by GQB
//
//////////////////////////////////////////////////////////////////////////
// App headers
#include "pgAdmin3.h"
// wxWindows headers
#include <wx/wx.h>
#include <wx/minifram.h>
#include <wx/generic/gridctrl.h>
#include <wx/notebook.h>
#include <wx/imaglist.h>
#include <wx/listctrl.h>
// App headers
#include "gqb/gqbViewPanels.h"
#include "gqb/gqbGridProjTable.h"
#include "gqb/gqbGridRestTable.h"
#include "gqb/gqbGridOrderTable.h"
#include "gqb/gqbGridJoinTable.h"
// Images
#include "images/gqbUp.pngc"
#include "images/gqbUpTop.pngc"
#include "images/gqbDown.pngc"
#include "images/gqbDownBottom.pngc"
#include "images/gqbOrderAddAll.pngc"
#include "images/gqbOrderRemoveAll.pngc"
#include "images/gqbOrderRemove.pngc"
#include "images/gqbOrderAdd.pngc"
#include "images/gqbAddRest.pngc"
#include "images/gqbRemoveRest.pngc"
#include "images/tables.pngc"
#include "images/table-sm.pngc"
#include "images/column-sm.pngc"
#include "images/view-sm.pngc"
#include "images/gqbAdd.pngc"
#include "images/gqbRemove.pngc"
// 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.
//
BEGIN_EVENT_TABLE(gqbGridPanel, wxPanel)
EVT_GRID_SELECT_CELL(gqbGridPanel::OnGridSelectCell)
EVT_GRID_RANGE_SELECT(gqbGridPanel::OnGridRangeSelected)
EVT_BUTTON(GQB_COLS_UP_BUTTON_ID, gqbGridPanel::OnButtonUp)
EVT_BUTTON(GQB_COLS_UP_TOP_BUTTON_ID, gqbGridPanel::OnButtonUpTop)
EVT_BUTTON(GQB_COLS_DOWN_BUTTON_ID, gqbGridPanel::OnButtonDown)
EVT_BUTTON(GQB_COLS_DOWN_BOTTOM_BUTTON_ID, gqbGridPanel::OnButtonDownBottom)
END_EVENT_TABLE()
gqbGridPanel::gqbGridPanel(wxWindow *parent, wxWindowID id = wxID_ANY, gqbGridProjTable *gridModel = NULL):
wxPanel(parent, -1)
{
gModel = gridModel;
allowSelCells = true;
selTop = -1;
selBottom = -1;
upBitmap = *gqbUp_png_bmp;
upTopBitmap = *gqbUpTop_png_bmp;
downBitmap = *gqbDown_png_bmp;
downBottomBitmap = *gqbDownBottom_png_bmp;
buttonUp = new wxBitmapButton( this, GQB_COLS_UP_BUTTON_ID, upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Up") );
buttonUp->SetToolTip(_("Move the selected column up"));
buttonUpTop = new wxBitmapButton( this, GQB_COLS_UP_TOP_BUTTON_ID, upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Top") );
buttonUpTop->SetToolTip(_("Move the selected column to the top"));
buttonDown = new wxBitmapButton( this, GQB_COLS_DOWN_BUTTON_ID, downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Down") );
buttonDown->SetToolTip(_("Move the selected column down"));
buttonDownBottom = new wxBitmapButton( this, GQB_COLS_DOWN_BOTTOM_BUTTON_ID, downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Bottom") );
buttonDownBottom->SetToolTip(_("Move the selected column to the bottom"));
this->colsGrid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT(""));
colsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells);
// Adjust the default row height to be more compact
wxFont font = colsGrid->GetLabelFont();
int nWidth = 0;
int nHeight = 18;
colsGrid->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);
colsGrid->SetColLabelSize(nHeight + 6);
colsGrid->SetRowLabelSize(35);
#ifdef __WXGTK__
colsGrid->SetDefaultRowSize(nHeight + 8, TRUE);
#else
colsGrid->SetDefaultRowSize(nHeight + 4, TRUE);
#endif
wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );
horizontalSizer->Add(colsGrid,
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->buttonUpTop,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer->Add(
this->buttonUp,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer->Add(
this->buttonDown,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer->Add(
this->buttonDownBottom,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
horizontalSizer->Add(
buttonsSizer,
0, // make vertically unstretchable
wxALIGN_CENTER ); // no border and centre horizontally
this->SetSizer(horizontalSizer);
}
gqbGridPanel::~gqbGridPanel()
{
if (buttonUp)
delete buttonUp;
if(buttonDown)
delete buttonDown;
if(buttonUpTop)
delete buttonUpTop;
if(buttonDownBottom)
delete buttonDownBottom;
}
void gqbGridPanel::SetGridColsSize()
{
// After sizers determine the width of Grid then calculate the % space for each column about 33% each one
int size = (int)((colsGrid->GetSize().GetWidth() - colsGrid->GetRowLabelSize()) * 0.30);
colsGrid->SetColSize(0, size);
colsGrid->SetColSize(1, size);
colsGrid->SetColSize(2, size);
}
void gqbGridPanel::OnGridSelectCell( wxGridEvent &ev )
{
if(allowSelCells)
{
if ( ev.Selecting() )
{
selTop = ev.GetRow();
selBottom = -1;
}
else
{
selTop = -1;
selBottom = -1;
}
}
ev.Skip();
}
void gqbGridPanel::OnGridRangeSelected( wxGridRangeSelectEvent &ev )
{
if(allowSelCells)
{
if ( ev.Selecting() )
{
selTop = ev.GetTopRow();
selBottom = ev.GetBottomRow();
}
else
{
selTop = -1;
selBottom = -1;
}
}
ev.Skip();
}
void gqbGridPanel::OnButtonUp(wxCommandEvent &)
{
// A single row is selected
allowSelCells = false;
if((selTop >= 0 && selBottom == -1) || (selTop == selBottom))
{
--selTop;
gModel->changesPositions(selTop, selTop + 1);
if(selTop < 0)
{
selTop = 0;
}
colsGrid->SelectBlock(selTop, 0, selTop, 1, false);
colsGrid->SetGridCursor(selTop, 0);
selBottom = -1;
}
else
{
// A range of rows is selected
if (selTop >= 0 && selBottom >= 0)
{
int newTop = selTop - 1;
gModel->changesRangeOnePos(selTop, selBottom, newTop);
if(selTop > 0) // recalculate new selection area & avoid bad selection area
{
selTop--;
selBottom--;
}
colsGrid->SelectBlock(selTop, 0, selBottom, 1, false);
colsGrid->SetGridCursor(selTop, 0);
}
}
allowSelCells = true;
}
void gqbGridPanel::OnButtonUpTop(wxCommandEvent &)
{
allowSelCells = false;
// A Single Row is selected
if((selTop >= 0 && selBottom == -1) || (selTop == selBottom))
{
selBottom = selTop - 1;
selTop = 0;
gModel->changesRangeOnePos(selTop, selBottom, 1);
colsGrid->SelectBlock(0, 0, 0, 1, false);
colsGrid->SetGridCursor(0, 0);
// Put variables in correct values now.
selTop = 0;
selBottom = -1;
}
// A range of rows is selected
else
{
int newTop = 0;
if (selTop >= 0 && selBottom >= 0)
{
// Move all range only one pos the require times to get the top
for(int i = selTop; i > 0; i--)
{
newTop = selTop - 1;
gModel->changesRangeOnePos(selTop, selBottom, newTop);
// Recalculate new selection area & avoid bad selection area
if(selTop > 0)
{
selTop--;
selBottom--;
}
colsGrid->SelectBlock(selTop, 0, selBottom, 1, false);
colsGrid->SetGridCursor(selTop, 0);
}
}
}
allowSelCells = true;
}
void gqbGridPanel::OnButtonDown(wxCommandEvent &)
{
allowSelCells = false;
// A single row is selected
if((selTop >= 0 && selBottom == -1) || (selTop == selBottom))
{
++selTop;
gModel->changesPositions(selTop, selTop - 1);
// Adjust selection when selected item it's last item.
if(selTop == gModel->GetNumberRows())
{
selTop--;
}
colsGrid->SelectBlock(selTop, 0, selTop, 1, false);
colsGrid->SetGridCursor(selTop, 0);
selBottom = -1;
}
// A range of rows is selected
else
{
if (selTop >= 0 && selBottom >= 0)
{
int newTop = selTop + 1;
gModel->changesRangeOnePos(selTop, selBottom, newTop);
// Recalculate new selection area & avoid bad selection area
if(selBottom < gModel->GetNumberRows() - 1)
{
selTop++;
selBottom++;
}
colsGrid->SelectBlock(selTop, 0, selBottom, 1, false);
colsGrid->SetGridCursor(selTop, 0);
}
}
allowSelCells = true;
}
void gqbGridPanel::OnButtonDownBottom(wxCommandEvent &)
{
allowSelCells = false;
// A Single Row is selected
if((selTop >= 0 && selBottom == -1) || (selTop == selBottom))
{
selBottom = gModel->GetNumberRows() - 1;
selTop = selTop + 1;
int newBottom = gModel->GetNumberRows() - 1;
gModel->changesRangeOnePos(selTop, selBottom, selTop - 1);
colsGrid->SelectBlock(newBottom, 0, newBottom, 1, false);
colsGrid->SetGridCursor(newBottom, 0);
// Put variables in correct values now.
selTop = newBottom;
selBottom = -1;
}
// A range of rows is selected
else
{
int newTop = 0, size = gModel->GetNumberRows();
if (selTop >= 0 && selBottom >= 0)
{
for(int i = selBottom; i < size; i++)
{
newTop = selTop + 1;
gModel->changesRangeOnePos(selTop, selBottom, newTop);
// Recalculate new selection area & avoid bad selection area
if(selBottom < gModel->GetNumberRows() - 1)
{
selTop++;
selBottom++;
}
colsGrid->SelectBlock(selTop, 0, selBottom, 1, false);
colsGrid->SetGridCursor(selTop, 0);
}
}
}
allowSelCells = true;
}
//
// Tree with Columns & tables inside a query model
//
gqbColsTree::gqbColsTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
: wxTreeCtrl(parent, id, pos, size, style)
{
wxImageList *imageList = new wxImageList(16, 16);
imageList->Add(*tables_png_ico);
imageList->Add(*table_sm_png_ico);
imageList->Add(*column_sm_png_ico);
imageList->Add(*view_sm_png_ico);
this->AssignImageList(imageList);
wxString a = _("Select column");
createRoot(a);
this->Expand(rootNode);
}
// Create root node
wxTreeItemId &gqbColsTree::createRoot(wxString &Name)
{
rootNode = this->AddRoot(Name, 0, 0);
return rootNode;
}
// 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();
wxString a = _("Select column");
createRoot(a);
this->Expand(rootNode);
wxTreeItemId parent;
gqbIteratorBase *iterator = model->createQueryIterator();
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;
if(tmpTable->getAlias().length() > 0)
{
parent = this->AppendItem(rootNode, tmpTable->getAlias() , iconIndex, iconIndex, tmpTable);
}
else
{
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, tmpColumn);
}
delete colsIterator;
}
delete iterator;
if (rootNode)
{
this->SortChildren(rootNode);
this->Expand(rootNode);
}
}
//
// Popup Window for gqbColsTree
//
gqbColsPopUp::gqbColsPopUp(wxWindow *parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size):
wxDialog(parent, id, title, pos, size, wxRESIZE_BORDER | wxCAPTION)
{
this->SetSize(wxSize(243, 165));
wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);
editTree = new wxTextCtrl(this, QR_TREE, wxT(""), wxPoint(5, 5), wxSize(193, 22));
editTree->AcceptsFocus();
editTree->SetFocus();
editTree->SetEditable(true);
hSizer->Add(editTree, 1, wxEXPAND | wxRIGHT, 3);
buttonTree = new wxButton(this, QR_TREE_OK, _("OK") , wxPoint(199, 5), wxDefaultSize, wxBU_EXACTFIT);
this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbColsPopUp::OnPopUpOKClick);
hSizer->Add(buttonTree);
vSizer->Add(hSizer, 0, wxEXPAND | wxALL, 3);
colsTree = new gqbColsTree(this, QR_TREE, wxPoint(5, 31), wxSize(224, 104), wxTR_HAS_BUTTONS | wxSIMPLE_BORDER | wxTR_SINGLE);
this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeDoubleClick);
this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeClick);
vSizer->Add(colsTree, 1, wxEXPAND | wxALL, 3);
SetSizer(vSizer);
}
void gqbColsPopUp::refreshTree(gqbModel *_model)
{
model = _model;
if(colsTree && _model)
{
colsTree->refreshTree(model);
}
}
void gqbColsPopUp::OnPopUpOKClick(wxCommandEvent &event)
{
this->usedGrid->SetCellValue(_row, _col, this->getEditText());
//this->MakeModal(false);
this->Hide();
this->GetParent()->Refresh();
}
void gqbColsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent &event)
{
if(colsTree)
{
wxTreeItemId itemId = event.GetItem();
wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId);
if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId))
{
this->usedGrid->SetCellValue(_row, _col, this->getEditText());
if(this->usedGrid->GetCellValue(_row, _col).length() <= 0)
{
this->usedGrid->SetCellValue(_row, _col, _("Set value"));
}
//this->MakeModal(false);
this->Hide();
this->GetParent()->Refresh();
}
}
}
void gqbColsPopUp::OnPopUpTreeClick(wxTreeEvent &event)
{
if(colsTree)
{
wxTreeItemId itemId = event.GetItem();
wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId);
if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId))
{
this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId)));
}
}
}
void gqbColsPopUp::setEditText(wxString text)
{
this->editTree->SetValue(text);
}
void gqbColsPopUp::focus()
{
this->editTree->SetFocus();
this->editTree->SetSelection(-1, -1);
}
//
// View Selection Criteria Panel Class.
//
BEGIN_EVENT_TABLE(gqbCriteriaPanel, wxPanel)
EVT_BUTTON(GQB_COLS_ADD_BUTTON_ID, gqbCriteriaPanel::OnButtonAdd)
EVT_BUTTON(GQB_COLS_DROP_BUTTON_ID, gqbCriteriaPanel::OnButtonDrop)
END_EVENT_TABLE()
gqbCriteriaPanel::gqbCriteriaPanel(wxWindow *parent, gqbModel *_model, gqbGridRestTable *gridModel):
wxPanel(parent, -1)
{
model = _model;
gModel = gridModel;
colsPopUp = NULL;
this->restrictionsGrid = new gqbCustomGrid(this, CRITERIA_PANEL_RESTRICTION_GRID_ID);
restrictionsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells);
this->restrictionsGrid->SetSelectionMode(wxGrid::wxGridSelectRows);
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 = *gqbAddRest_png_bmp;
dropBitmap = *gqbRemoveRest_png_bmp;
buttonAdd = new wxBitmapButton( this, GQB_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add"));
buttonAdd->SetToolTip(_("Add a new criteria line"));
buttonDrop = new wxBitmapButton( this, GQB_COLS_DROP_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove"));
buttonDrop->SetToolTip(_("Remove the selected criteria line"));
wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );
horizontalSizer->Add(restrictionsGrid,
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 gqbCriteriaPanel::showColsPopUp(int row, int col, wxPoint pos)
{
if(!colsPopUp)
{
colsPopUp = new gqbColsPopUp(this, -1, wxT("Set Value"), wxDefaultPosition, wxDefaultSize);
}
refreshTree(model);
// Set initial Value
colsPopUp->setEditText(restrictionsGrid->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;
colsPopUp->SetPosition(p);
//colsPopUp->Show();
//colsPopUp->MakeModal(true);
colsPopUp->ShowModal();
colsPopUp->focus();
colsPopUp->setUsedCell(restrictionsGrid, row, col);
}
void gqbCriteriaPanel::refreshTree(gqbModel *_model)
{
// GQB-TODO: Do this through controller...
model = _model;
if(colsPopUp && model)
colsPopUp->refreshTree(model);
}
void gqbCriteriaPanel::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();
restrictionsGrid->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);
}
} //GQB-TODO 1,2 can be integrate with 3
else if(event.GetCol() == 3)
{
// Change connector of the Restriction between AND/OR
wxRect cellSize = restrictionsGrid->CellToRect(event.GetRow(), event.GetCol());
wxPoint p = event.GetPosition();
restrictionsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y);
// Number 17 is button's width at cellRender function [nButtonWidth]
if((restrictionsGrid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 )
{
p = event.GetPosition();
if( gModel->GetValue(event.GetRow(), 3).Contains(wxT("AND")) )
{
gModel->SetValue(event.GetRow(), 3, wxT("OR"));
}
else
{
gModel->SetValue(event.GetRow(), 3, wxT("AND"));
}
restrictionsGrid->Refresh();
}
}
event.Skip();
}
void gqbCriteriaPanel::OnButtonAdd(wxCommandEvent &)
{
// GQB-TODO: use controller one
gqbQueryRestriction *r = new gqbQueryRestriction();
gModel->AppendItem(r);
int row = model->getRestrictions()->restrictionsCount() - 1;
wxString strChoices[16] = {wxT("="), wxT("!="), wxT("<"), wxT("<="), wxT(">"), wxT(">="), wxT("BETWEEN"), wxT("LIKE"), wxT("NOT LIKE"), wxT("ILIKE"), wxT("NOT ILIKE"), wxT("IN"), wxT("NOT IN"), wxT("NOT BETWEEN"), wxT("IS NULL"), wxT("IS NOT NULL")};
restrictionsGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer);
restrictionsGrid->SetCellRenderer(row, 0, new wxGridCellButtonRenderer);
restrictionsGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoices), strChoices));
restrictionsGrid->SetCellRenderer(row, 2, new wxGridCellButtonRenderer);
restrictionsGrid->SetCellRenderer(row, 3, new wxGridCellButtonRenderer);
restrictionsGrid->SetReadOnly(row, 3, true);
}
void gqbCriteriaPanel::OnButtonDrop(wxCommandEvent &)
{
if(restrictionsGrid->GetGridCursorRow() >= 0)
gModel->DeleteRows(restrictionsGrid->GetGridCursorRow(), 1);
restrictionsGrid->Refresh();
}
void gqbCriteriaPanel::SetGridColsSize()
{
// After sizers determine the width of Grid then calculate the % space for each column about 33% each one
int size = (int)((restrictionsGrid->GetSize().GetWidth() - restrictionsGrid->GetRowLabelSize()) * 0.225);
restrictionsGrid->SetColSize(0, size);
restrictionsGrid->SetColSize(1, size);
restrictionsGrid->SetColSize(2, size);
restrictionsGrid->SetColSize(3, size);
}
//
// View Selection Criteria Panel Class's Grid.
//
gqbCustomGrid::gqbCustomGrid(wxWindow *parent, wxWindowID id):
wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP, wxT("")),
m_selTemp(NULL)
{
// Adjust the default row height to be more compact
wxFont font = GetLabelFont();
int nWidth = 0;
int nHeight = 18;
GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);
SetColLabelSize(nHeight + 6);
SetRowLabelSize(35);
#ifdef __WXGTK__
SetDefaultRowSize(nHeight + 8, TRUE);
#else
SetDefaultRowSize(nHeight + 4, TRUE);
#endif
}
void gqbCustomGrid::RevertSel()
{
if (m_selTemp)
{
wxASSERT(m_selection == NULL);
m_selection = m_selTemp;
m_selTemp = NULL;
}
}
void gqbCustomGrid::ComboBoxEvent(wxGridEvent &event)
{
// This forces the cell to go into edit mode directly
this->m_waitForSlowClick = TRUE;
int row = event.GetRow();
int col = event.GetCol();
this->SetGridCursor(row, col);
// Store the click co-ordinates in the editor if possible
// if an editor has created a ClientData area, we presume it's
// a wxPoint and we store the click co-ordinates
wxGridCellEditor *pEditor = this->GetCellEditor(event.GetRow(), event.GetCol());
wxPoint *pClickPoint = (wxPoint *)pEditor->GetClientData();
if (pClickPoint)
{
*pClickPoint = this->ClientToScreen(event.GetPosition());
#ifndef __WINDOWS__
EnableCellEditControl(true);
#endif
}
// hack to prevent selection from being lost when click combobox
if (this->IsInSelection(event.GetRow(), event.GetCol()))
{
this->m_selTemp = this->m_selection;
this->m_selection = NULL;
}
pEditor->DecRef();
}
//
//
// Order by Panel
//
//
BEGIN_EVENT_TABLE(gqbOrderPanel, wxPanel)
EVT_BUTTON(GQB_ORDER_DROP_BUTTON_ID, gqbOrderPanel::OnButtonRemove)
EVT_BUTTON(GQB_ORDER_DROP_ALL_BUTTON_ID, gqbOrderPanel::OnButtonRemoveAll)
EVT_BUTTON(GQB_ORDER_ADD_BUTTON_ID, gqbOrderPanel::OnButtonAdd)
EVT_BUTTON(GQB_ORDER_ADD_ALL_BUTTON_ID, gqbOrderPanel::OnButtonAddAll)
EVT_GRID_SELECT_CELL(gqbOrderPanel::OnGridSelectCell)
EVT_GRID_RANGE_SELECT(gqbOrderPanel::OnGridRangeSelected)
EVT_BUTTON(GQB_ORDER_UP_BUTTON_ID, gqbOrderPanel::OnButtonUp)
EVT_BUTTON(GQB_ORDER_UP_TOP_BUTTON_ID, gqbOrderPanel::OnButtonUpTop)
EVT_BUTTON(GQB_ORDER_DOWN_BUTTON_ID, gqbOrderPanel::OnButtonDown)
EVT_BUTTON(GQB_ORDER_DOWN_BOTTOM_BUTTON_ID, gqbOrderPanel::OnButtonDownBottom)
END_EVENT_TABLE()
gqbOrderPanel::gqbOrderPanel(wxWindow *parent, gqbGridOrderTable *gridTableLeft, gqbGridOrderTable *gridTableRight):
wxPanel(parent, -1)
{
// GQB-TODO: change bitmap buttons
selLeft = -1;
selRightTop = -1;
selRightBottom = -1;
tableLeft = gridTableLeft;
tableRight = gridTableRight;
allowSelCells = true;
addBitmap = *gqbOrderAdd_png_bmp;
addAllBitmap = *gqbOrderAddAll_png_bmp;
removeBitmap = *gqbOrderRemove_png_bmp;
removeAllBitmap = *gqbOrderRemoveAll_png_bmp;
buttonAdd = new wxBitmapButton( this, GQB_ORDER_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") );
buttonAdd->SetToolTip(_("Add the selected column"));
buttonAddAll = new wxBitmapButton( this, GQB_ORDER_ADD_ALL_BUTTON_ID, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") );
buttonAddAll->SetToolTip(_("Add all columns"));
buttonRemove = new wxBitmapButton( this, GQB_ORDER_DROP_BUTTON_ID, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") );
buttonRemove->SetToolTip(_("Remove the selected column"));
buttonRemoveAll = new wxBitmapButton( this, GQB_ORDER_DROP_ALL_BUTTON_ID, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") );
buttonRemoveAll->SetToolTip(_("Remove all columns"));
upBitmap = *gqbUp_png_bmp;
upTopBitmap = *gqbUpTop_png_bmp;
downBitmap = *gqbDown_png_bmp;
downBottomBitmap = *gqbDownBottom_png_bmp;
buttonUp = new wxBitmapButton( this, GQB_ORDER_UP_BUTTON_ID, upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Up") );
buttonUp->SetToolTip(_("Move the selected column up"));
buttonDown = new wxBitmapButton( this, GQB_ORDER_DOWN_BUTTON_ID, downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Down") );
buttonDown->SetToolTip(_("Move the selected column down"));
buttonUpTop = new wxBitmapButton( this, GQB_ORDER_UP_TOP_BUTTON_ID, upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Top") );
buttonUpTop->SetToolTip(_("Move the selected column to the top"));
buttonDownBottom = new wxBitmapButton( this, GQB_ORDER_DOWN_BOTTOM_BUTTON_ID, downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Bottom") );
buttonDownBottom->SetToolTip(_("Move the selected column to the bottom"));
availableColumns = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("Available Columns"));
availableColumns->SetTable(gridTableLeft);
availableColumns->EnableEditing(false);
// Adjust the default row height to be more compact
wxFont font = availableColumns->GetLabelFont();
int nWidth = 0;
int nHeight = 18;
availableColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);
availableColumns->SetColLabelSize(nHeight + 6);
availableColumns->SetRowLabelSize(35);
#ifdef __WXGTK__
availableColumns->SetDefaultRowSize(nHeight + 8, TRUE);
#else
availableColumns->SetDefaultRowSize(nHeight + 4, TRUE);
#endif
wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL );
horizontalSizer->Add(availableColumns,
1, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
wxALL, // and make border all around
3 ); // set border width to 10
wxBoxSizer *buttonsSizer1 = new wxBoxSizer( wxVERTICAL );
buttonsSizer1->Add(
this->buttonAdd,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer1->Add(
this->buttonAddAll,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer1->Add(
this->buttonRemove,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer1->Add(
this->buttonRemoveAll,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
horizontalSizer->Add(
buttonsSizer1,
0, // make vertically unstretchable
wxALIGN_CENTER ); // no border and centre horizontally
// GQB-TODO: change 333 for a new and better one.
usedColumns = new wxGrid(this, 333, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("Columns Order"));
usedColumns->SetTable(gridTableRight);
usedColumns->EnableEditing(false);
// Adjust the default row height to be more compact
font = usedColumns->GetLabelFont();
nWidth = 0;
nHeight = 18;
usedColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font);
usedColumns->SetColLabelSize(nHeight + 6);
usedColumns->SetRowLabelSize(35);
#ifdef __WXGTK__
usedColumns->SetDefaultRowSize(nHeight + 8, TRUE);
#else
usedColumns->SetDefaultRowSize(nHeight + 4, TRUE);
#endif
this->Connect(333, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbOrderPanel::OnCellLeftClick);
horizontalSizer->Add(usedColumns,
1, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
wxALL, // and make border all around
3 ); // set border width to 10
wxBoxSizer *buttonsSizer2 = new wxBoxSizer( wxVERTICAL );
buttonsSizer2->Add(
this->buttonUpTop,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer2->Add(
this->buttonUp,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer2->Add(
this->buttonDown,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
buttonsSizer2->Add(
this->buttonDownBottom,
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
3 ); // set border width to 10
horizontalSizer->Add(
buttonsSizer2,
0, // make vertically unstretchable
wxALIGN_CENTER ); // no border and centre horizontally
this->SetSizer(horizontalSizer);
}
void gqbOrderPanel::OnButtonRemove(wxCommandEvent &)
{
if(usedColumns->GetNumberRows() > 0)
{
if(selRightTop != -1)
{
gqbColumn *col = (gqbColumn *) tableRight->getObjectAt(selRightTop, 0);
gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(selRightTop, 1);
tableLeft->AppendItem(col, colParent, 'N');
tableRight->removeRowAt(selRightTop);
}
}
}
void gqbOrderPanel::OnButtonRemoveAll(wxCommandEvent &)
{
if(usedColumns->GetNumberRows() > 0)
{
for(int i = usedColumns->GetNumberRows() - 1; i >= 0; i--)
{
gqbColumn *col = (gqbColumn *) tableRight->getObjectAt(i, 0);
gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(i, 1);
tableLeft->AppendItem(col, colParent, 'N');
tableRight->removeRowAt(i);
}
}
}
void gqbOrderPanel::OnButtonAdd(wxCommandEvent &)
{
if(availableColumns->GetNumberRows() > 0)
{
if(selLeft != -1)
{
gqbColumn *col = (gqbColumn *) tableLeft->getObjectAt(selLeft, 0);
gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(selLeft, 1);
tableRight->AppendItem(col, colParent, 'A');
usedColumns->SetCellRenderer((usedColumns->GetNumberRows() - 1), 1, new wxGridCellButtonRenderer);
tableLeft->removeRowAt(selLeft);
}
}
}
void gqbOrderPanel::OnButtonAddAll(wxCommandEvent &)
{
if(availableColumns->GetNumberRows() > 0)
{
for(int i = availableColumns->GetNumberRows() - 1; i >= 0; i--)
{
gqbColumn *col = (gqbColumn *) tableLeft->getObjectAt(i, 0);
gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(i, 1);
tableRight->AppendItem(col, colParent, 'A');
usedColumns->SetCellRenderer((usedColumns->GetNumberRows() - 1), 1, new wxGridCellButtonRenderer);
tableLeft->removeRowAt(i);
}
}
}
void gqbOrderPanel::OnGridSelectCell( wxGridEvent &ev )
{
if(allowSelCells)
{
if ( ev.Selecting() )
{
wxObject *object = ev.GetEventObject();
wxGrid *grid = wxDynamicCast( object, wxGrid );
if(grid->GetNumberCols() == 1) // Left Grid
{
selLeft = ev.GetRow();
}
else
{
// Right Grid
selRightTop = ev.GetRow();
selRightBottom = -1;
}
}
else
{
selRightTop = -1; // GQB-TODO: this is correct??
selRightBottom = -1;
selLeft = -1;
}
}
ev.Skip();
}
void gqbOrderPanel::OnGridRangeSelected( wxGridRangeSelectEvent &ev )
{
if(allowSelCells)
{
if ( ev.Selecting() )
{
selRightTop = ev.GetTopRow();
selRightBottom = ev.GetBottomRow();
}
else
{
selRightTop = -1;
selRightBottom = -1;
}
}
ev.Skip();
}
void gqbOrderPanel::OnButtonUp(wxCommandEvent &)
{
// A single row is selected
allowSelCells = false;
if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom))
{
--selRightTop;
tableRight->changesPositions(selRightTop, selRightTop + 1);
if(selRightTop < 0)
{
selRightTop = 0;
}
usedColumns->SelectBlock(selRightTop, 0, selRightTop, 1, false);
usedColumns->SetGridCursor(selRightTop, 0);
selRightBottom = -1;
}
else
{
// A range of rows is selected
if (selRightTop >= 0 && selRightBottom >= 0)
{
int newTop = selRightTop - 1;
tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop);
if(selRightTop > 0) // Recalculate new selection area & avoid bad selection area
{
selRightTop--;
selRightBottom--;
}
usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false);
usedColumns->SetGridCursor(selRightTop, 0);
}
}
allowSelCells = true;
}
void gqbOrderPanel::OnButtonUpTop(wxCommandEvent &)
{
allowSelCells = false;
// A Single Row is selected
if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom))
{
selRightBottom = selRightTop - 1;
selRightTop = 0;
tableRight->changesRangeOnePos(selRightTop, selRightBottom, 1);
usedColumns->SelectBlock(0, 0, 0, 1, false);
usedColumns->SetGridCursor(0, 0);
// Put variables in correct values now.
selRightTop = 0;
selRightBottom = -1;
}
// A range of rows is selected
else
{
int newTop = 0;
if (selRightTop >= 0 && selRightBottom >= 0)
{
// Move all range only one pos the require times to get the top
for(int i = selRightTop; i > 0; i--)
{
newTop = selRightTop - 1;
tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop);
// Recalculate new selection area & avoid bad selection area
if(selRightTop > 0)
{
selRightTop--;
selRightBottom--;
}
usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false);
usedColumns->SetGridCursor(selRightTop, 0);
}
}
}
allowSelCells = true;
}
void gqbOrderPanel::OnButtonDown(wxCommandEvent &)
{
allowSelCells = false;
// A single row is selected
if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom))
{
++selRightTop;
tableRight->changesPositions(selRightTop, selRightTop - 1);
// Adjust selection when selected item it's last item.
if(selRightTop == tableRight->GetNumberRows())
{
selRightTop--;
}
usedColumns->SelectBlock(selRightTop, 0, selRightTop, 1, false);
usedColumns->SetGridCursor(selRightTop, 0);
selRightBottom = -1;
}
// A range of rows is selected
else
{
if (selRightTop >= 0 && selRightBottom >= 0)
{
int newTop = selRightTop + 1;
tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop);
// Recalculate new selection area & avoid bad selection area
if(selRightBottom < tableRight->GetNumberRows() - 1)
{
selRightTop++;
selRightBottom++;
}
usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false);
usedColumns->SetGridCursor(selRightTop, 0);
}
}
allowSelCells = true;
}
void gqbOrderPanel::OnButtonDownBottom(wxCommandEvent &)
{
allowSelCells = false;
// A Single Row is selected
if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom))
{
selRightBottom = tableRight->GetNumberRows() - 1;
selRightTop = selRightTop + 1;
int newBottom = tableRight->GetNumberRows() - 1;
tableRight->changesRangeOnePos(selRightTop, selRightBottom, selRightTop - 1);
usedColumns->SelectBlock(newBottom, 0, newBottom, 1, false);
usedColumns->SetGridCursor(newBottom, 0);
// Put variables in correct values now.
selRightTop = newBottom;
selRightBottom = -1;
}
// A range of rows is selected
else
{
int newTop = 0, size = tableRight->GetNumberRows();
if (selRightTop >= 0 && selRightBottom >= 0)
{
for(int i = selRightBottom; i < size; i++)
{
newTop = selRightTop + 1;
tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop);
// Recalculate new selection area & avoid bad selection area
if(selRightBottom < tableRight->GetNumberRows() - 1)
{
selRightTop++;
selRightBottom++;
}
usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false);
usedColumns->SetGridCursor(selRightTop, 0);
}
}
}
allowSelCells = true;
}
void gqbOrderPanel::SetGridColsSize()
{
// After sizers determine the width of Grid then calculate the % space for each column
int size = (int)((availableColumns->GetSize().GetWidth() - availableColumns->GetRowLabelSize()) * 0.90);
availableColumns->SetColSize(0, size);
size = (int)((usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize()) * 0.65);
int size2 = (int)((usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize()) * 0.25);
usedColumns->SetColSize(0, size);
usedColumns->SetColSize(1, size2);
}
void gqbOrderPanel::OnCellLeftClick(wxGridEvent &event)
{
// Only show editor y case of column 1
if(event.GetCol() == 1)
{
// Change kind of order of the columns between ASC and DESC
wxRect cellSize = usedColumns->CellToRect(event.GetRow(), event.GetCol());
wxPoint p = event.GetPosition();
usedColumns->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y);
// Number 17 is button's width at cellRender function [nButtonWidth]
if((usedColumns->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 )
{
p = event.GetPosition();
if( tableRight->GetValue(event.GetRow(), 1).Contains(wxT("ASC")) )
{
tableRight->SetValue(event.GetRow(), 1, wxT("DESC"));
}
else
{
tableRight->SetValue(event.GetRow(), 1, wxT("ASC"));
}
usedColumns->Refresh();
}
}
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 = *gqbAdd_png_bmp;
dropBitmap = *gqbRemove_png_bmp;
buttonAdd = new wxBitmapButton( this, GQB_JOIN_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add"));
buttonAdd->SetToolTip(_("Add a new join"));
buttonDrop = new wxBitmapButton( this, GQB_JOIN_COLS_DELETE_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove"));
buttonDrop->SetToolTip(_("Remove the selected join"));
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->ShowModal();
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::selectJoin(gqbQueryJoin *join)
{
joinsGrid->RevertSel();
gModel->selectJoin(join);
}