335 lines
12 KiB
C++
335 lines
12 KiB
C++
/*
|
|
* File: LBoundGrid.h
|
|
* Author: Saleem Edah-Tally - nmset@yandex.com
|
|
* License : LGPL version 2.1
|
|
* Copyright Saleem Edah-Tally, M. D. - © 2014
|
|
*
|
|
* Created on 9 juin 2014, 16:40
|
|
*/
|
|
|
|
#ifndef LBOUNDGRID_H
|
|
#define LBOUNDGRID_H
|
|
|
|
#include <wx/grid.h>
|
|
#include "LResultSet.h"
|
|
#include "LGridColEditor.h"
|
|
|
|
class LBoundGridFormEvent;
|
|
|
|
/**
|
|
* Displays and edits database tables with custom renderers and editors.
|
|
* A custom menu controls data editing.
|
|
* Can edit a row in form view; application can add widgets on the form dialog.
|
|
* Display on phones or tablets with high DPI is optimized.
|
|
*/
|
|
class LBoundGrid : public wxGrid
|
|
{
|
|
public:
|
|
/**
|
|
* The constructor forces selection mode to wxGridSelectRows,
|
|
* this is a requirement, don't change it in your code.
|
|
*
|
|
* @param parent
|
|
* @param id
|
|
*/
|
|
LBoundGrid(wxWindow* parent, wxWindowID id = wxID_ANY);
|
|
/**
|
|
* Deletes the menu, the form client sizer and calls ClearGrid().
|
|
*/
|
|
virtual ~LBoundGrid();
|
|
|
|
void SetResultSet(LResultSet * newResultSet);
|
|
|
|
LResultSet* GetResultSet() const
|
|
{
|
|
return m_rs;
|
|
}
|
|
/**
|
|
* Is destructive. All rows and columns are deleted. Column editors get destroyed.
|
|
*/
|
|
void ClearGrid();
|
|
/**
|
|
* Deletes all rows, preserves columns, fills the underlying wxStringTable with raw database data.
|
|
*/
|
|
void FillGrid();
|
|
/**
|
|
* The specified column will be edited with LGridCheckEditor and rendered with LGridCheckRenderer.
|
|
* @param newColName database table column name
|
|
* @param newLabel grid header label
|
|
* @param width column width
|
|
* @param readOnly if true, editing is not allowed
|
|
* @param isDualstate edit/render as dual or tristate
|
|
* @param newNullLabel if the underlying check box is tristate with undetermined state, the cell displays this value
|
|
*/
|
|
void CreateCheckBoxColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
bool readOnly = false,
|
|
bool isDualstate = false,
|
|
wxString newNullLabel = _T("?"));
|
|
/**
|
|
* The specified column will be edited with LGridComboEditor and rendered with LGridComboRenderer.
|
|
* @param newColName database table column name
|
|
* @param newLabel grid header label
|
|
* @param width column width
|
|
* @param readOnly if true, editing is not allowed
|
|
*/
|
|
void CreateComboBoxColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
bool readOnly = false);
|
|
/**
|
|
* The specified column will be edited with LGridDateEditor and rendered with LGridDateRenderer.
|
|
* @param newColName database table column name
|
|
* @param newLabel grid header label
|
|
* @param width column width
|
|
* @param readOnly if true, editing is not allowed
|
|
*/
|
|
void CreateDateColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
bool readOnly = false);
|
|
/**
|
|
* The specified column will be edited with LGridTextEditor and rendered with LGridTextRenderer.
|
|
* @param newColName database table column name
|
|
* @param newLabel grid header label
|
|
* @param width column width
|
|
* @param newMultiline use a single or multiline text editor
|
|
* @param readOnly if true, editing is not allowed
|
|
*/
|
|
void CreateTextColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
bool newMultiline = false,
|
|
bool readOnly = false);
|
|
/**
|
|
* The specified column will be edited with LGridSpinEditor and rendered with LGridSpinRenderer.
|
|
* @param newColName database table column name
|
|
* @param newLabel grid header label
|
|
* @param width column width
|
|
* @param newMin minimal value of the editor
|
|
* @param newMax maximal value of the editor
|
|
* @param newInitial initial value of the editor
|
|
* @param readOnly if true, editing is not allowed
|
|
*/
|
|
void CreateSpinColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
int newMin = 0,
|
|
int newMax = 100,
|
|
int newInitial = 0,
|
|
bool readOnly = false);
|
|
void CreateJsonGridColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
const wxString& intentLabel,
|
|
const wxArrayString& types,
|
|
wxSize popupSize = wxDefaultSize,
|
|
bool readOnly = false);
|
|
void CreateXmlGridColumn(const wxString& newColName,
|
|
const wxString& newLabel,
|
|
unsigned int width,
|
|
const wxString& intentLabel,
|
|
const wxArrayString& types,
|
|
wxSize popupSize = wxDefaultSize,
|
|
bool readOnly = false);
|
|
/**
|
|
*
|
|
* @param col the grid column index
|
|
* @return the database table column name if above Create???Column has been called on that column, wxEmpyString otherwise.
|
|
*/
|
|
const wxString GetColName(const unsigned int col);
|
|
/**
|
|
*
|
|
* @param colName database table column name
|
|
* @return the grid column index of the first column defined with above Create???Column and whose
|
|
* columnName property equals colName. If no column is found, -1 is returned.
|
|
*/
|
|
int GetColIndex(const wxString& colName);
|
|
/**
|
|
* Has to call BeginEdit on the cell at row and col. This creates the editor if necessary,
|
|
* which in turn registers it in the underlying resultset.
|
|
* @param row
|
|
* @param col
|
|
* @param keepRegistered if true, does not unregister the editor in the underlying resultset
|
|
* @return The editor typed as LBoundControl* if found, NULL otherwise.
|
|
*/
|
|
LBoundControl* GetBoundControl(const unsigned int row,
|
|
const unsigned int col,
|
|
bool keepRegistered = true);
|
|
/**
|
|
* Has to call BeginEdit on the cell at row and colName. This creates the editor if necessary,
|
|
* which in turn registers it in the underlying resultset.
|
|
* @param row
|
|
* @param colName database table column name
|
|
* @param keepRegistered if true, does not unregister the editor in the underlying resultset
|
|
* @return The editor typed as LBoundControl* if found, NULL otherwise.
|
|
*/
|
|
LBoundControl* GetBoundControl(const unsigned int row,
|
|
const wxString& colName,
|
|
bool keepRegistered = true);
|
|
/**
|
|
*
|
|
* @param row
|
|
* @param col
|
|
* @return the cell editor at row and col as LGridColEditor* .
|
|
*/
|
|
LGridColEditor * GetColEditor(const unsigned int row, const unsigned int col) const;
|
|
/**
|
|
*
|
|
* @param col grid column index
|
|
* @return the form editor if in form view, NULL otherwise.
|
|
*/
|
|
wxControl* GetFormEditor(const unsigned int col) const;
|
|
/**
|
|
*
|
|
* @param colName database table column name
|
|
* @return the form editor if in form view, NULL otherwise.
|
|
*/
|
|
wxControl* GetFormEditor(const wxString& colName);
|
|
/**
|
|
* Calls BeginEdit on the cell at row and colName. This creates the editor if necessary,
|
|
* which in turn registers it in the underlying resultset.
|
|
* @param row
|
|
* @param col
|
|
* @param keepRegistered if true, does not unregister the editor in the underlying resultset
|
|
* @return
|
|
*/
|
|
bool InitEditor(const unsigned int row,
|
|
const unsigned int col,
|
|
bool keepRegistered = true);
|
|
void InitAllEditors(const unsigned int row, bool keepRegistered = true);
|
|
|
|
/**
|
|
* An application can register a single form event handler here.
|
|
* @param newEVH
|
|
*/
|
|
void SetGridFormEventHandler(LBoundGridFormEvent * newEVH)
|
|
{
|
|
m_gridFormEVH = newEVH;
|
|
}
|
|
|
|
LBoundGridFormEvent* GetGridFormEventHandler()
|
|
{
|
|
return m_gridFormEVH;
|
|
}
|
|
|
|
void AddMenuSeparator();
|
|
void AddMenuItem(wxMenuItem * newItem);
|
|
void AddSubMenu(wxMenu * newSubMenu, const wxString &label);
|
|
void RemoveMenuItem(const wxString& newItemLabelText);
|
|
void RemoveAllExternalMenuItems();
|
|
void EnableMenuItem(int id, bool enable = true);
|
|
|
|
wxMenu* GetMenu() const
|
|
{
|
|
return m_menu;
|
|
}
|
|
// Overrides to optimize display on phones and tablets with high DPI.
|
|
void SetDefaultRowSize(int height, bool resizeExistingRows = false);
|
|
void SetColMinimalAcceptableWidth(int width);
|
|
void SetColMinimalWidth(int col, int width);
|
|
void SetColSize(int col, int width);
|
|
void SetDefaultColSize(int width, bool resizeExistingCols = false);
|
|
void SetRowLabelSize(int width);
|
|
void SetRowMinimalAcceptableHeight(int height);
|
|
void SetRowMinimalHeight(int row, int height);
|
|
void SetRowSize(int row, int height);
|
|
private:
|
|
|
|
enum mnuIDs
|
|
{
|
|
ID_MNU_SAVE = -50000, ID_MNU_DELETE, ID_MNU_CANCEL, ID_MNU_REFRESH, ID_MNU_FORMVIEW
|
|
};
|
|
wxWeakRef<LResultSet> m_rs;
|
|
/**
|
|
* For phones and tablets with high DPI.
|
|
*/
|
|
wxDouble m_scaleFactor;
|
|
/**
|
|
* All database table date is stored as string.
|
|
*/
|
|
wxGridStringTable * m_stringTable;
|
|
wxMenu * m_menu;
|
|
/**
|
|
* This wxBoxSizer is created on the wxDialog when the grid is in form view,
|
|
* and is passed to the application via an instance of LBoundGridFormEvent if set.
|
|
*/
|
|
wxBoxSizer * m_formClientSizer;
|
|
/**
|
|
* Client application can set a single instance of LBoundGridFormEvent to receive
|
|
* events in form view.
|
|
*/
|
|
LBoundGridFormEvent * m_gridFormEVH;
|
|
/**
|
|
* Only one single line must be selected.
|
|
* @param evt
|
|
*/
|
|
void ForceSingleLineRange(wxGridRangeSelectEvent& evt);
|
|
/**
|
|
* Synchronizes the grid and the resultset row positions.
|
|
* @param evt
|
|
*/
|
|
void CellSelected(wxGridEvent& evt);
|
|
/**
|
|
* Called in constructor.
|
|
*/
|
|
void CreateMenu();
|
|
/**
|
|
* On right click.
|
|
* @param evt
|
|
*/
|
|
void ShowMenu(wxGridEvent& evt);
|
|
/**
|
|
* Saves, cancels edits or deletes current row, or shows form view.
|
|
* @param evt
|
|
*/
|
|
void MenuAction(wxCommandEvent& evt);
|
|
/**
|
|
* Helper function to Save() and Delete(). Concerns the column declared as primary key.
|
|
* @param row
|
|
* @return
|
|
*/
|
|
bool InitPKEditor(const int row);
|
|
/**
|
|
* Edits the current row in a wxDialog.
|
|
*/
|
|
void ShowFormView();
|
|
/**
|
|
* Unregisters all controls in the resultset and set them back to null.
|
|
*/
|
|
void RestoreEditorControls();
|
|
/**
|
|
* Calls Reset() on the LGridColEditor at col, i.e., deletes the editor control.
|
|
* @param col grid column index
|
|
*/
|
|
void ResetColEditor(const int col);
|
|
|
|
};
|
|
|
|
class LBoundGridFormEvent
|
|
{
|
|
public:
|
|
LBoundGridFormEvent();
|
|
virtual ~LBoundGridFormEvent();
|
|
/**
|
|
*
|
|
* @param origin
|
|
* @param clientSizer a wxBoxSizer at the bottom of the form window.
|
|
*/
|
|
virtual void BeforeFormShown(const LBoundGrid * origin, wxBoxSizer * clientSizer);
|
|
/**
|
|
*
|
|
* @param origin
|
|
* @param clientSizer a wxBoxSizer at the bottom of the form window.
|
|
*/
|
|
virtual void AfterFormHidden(const LBoundGrid * origin, wxBoxSizer * clientSizer);
|
|
virtual void AfterFormDestroyed(const LBoundGrid * origin);
|
|
|
|
private:
|
|
|
|
};
|
|
|
|
#endif /* LBOUNDGRID_H */
|
|
|