////////////////////////////////////////////////////////////////////////// // // 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 #include #include #include #include #include // 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); }