Files
l7/LBoundGrid.h

335 lines
12 KiB
C
Raw Normal View History

2018-04-25 20:43:41 +02:00
/*
* File: LBoundGrid.h
2022-11-19 16:05:44 +01:00
* Author: Saleem Edah-Tally - nmset@yandex.com
2018-04-25 20:43:41 +02:00
* License : LGPL version 2.1
2022-11-19 16:05:44 +01:00
* Copyright Saleem Edah-Tally, M. D. - © 2014
2018-04-25 20:43:41 +02:00
*
* Created on 9 juin 2014, 16:40
*/
#ifndef LBOUNDGRID_H
Added classes to manage simple tabular data of known structure using a popup containing a wxGrid object. BasePicker : Abstract class adding a popup to wxPickerBase styled with a wxTextCtrl. BaseGridPicker : Abstract class adding a wxGrid in the popup. JsonGridPickerCtrl : UI control storing the tabular data in a JSON array. LBoundJsonGridPicker : connect JsonGridPicker to database. LGridJsonCellEditor : use LBoundJsonGridPicker in other wxGrid objects. LGridJsonCellRenderer : render cell JSON data. XmlGridPickerCtrl : UI control storing the tabular data in as XML document. LBoundXmlGridPicker : connect XmlGridPicker to database. LGridXmlCellEditor : grid editor for LBoundXmlGridPicker. LGridXmlCellRenderer : grid renderer for LBoundXmlGridPicker. JsonHelper and XmlHelper : for applications to quickly get intent value from database data.. The structure of managed tabular data : Column 1 : Intent - this is what we want to store/edit. This can be telephone numbers, email addresses, instant messaging addresses... any single line piece of information that can exist many times for one entity (person, company...). Column 2 : Type - A short description of the intent : 'Home, Work, Mobile, Fax, Other...'. It is displayed in a non editable wxComboBox. Column 3 : Preferred - One line of data can be selected as the preferred one. It is not mandatory, but it must be a single choice. Column 4 : Notes - single line notes. Adjust sql scripts and L7.dox. Applied ANSI formatting style to all files. Other changes : Work around a nasty misbehavior. Grid columns edited by a translated combobox expect full string data as cell values. LResultSet::BEData() will report these mapped strings, instead of database real data. LBoundComboBox::IsDirty() will always be true even if the editor is unchanged once created. Simplest workaround : disconnect m_BoundComboBox if unchanged. LGridTextEditor::ProvideFormEditor() : set the form editor's value explicitely.; wxTextCtrl does not interpret data it receives LBoundControl::SetNull must be void. LBoundGrid : Unbind:: instructions should limit to the widget's id, like Bind:: LConnection::GetReturnedKeys should return NULL. LConnection::SetData should return void. Notes : wxJSON must be configured with the same prefix as wxWidgets, here /usr/local/{wxWidgets,wxWidgets-Release}.
2019-12-22 16:35:16 +01:00
#define LBOUNDGRID_H
2018-04-25 20:43:41 +02:00
#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);
Added classes to manage simple tabular data of known structure using a popup containing a wxGrid object. BasePicker : Abstract class adding a popup to wxPickerBase styled with a wxTextCtrl. BaseGridPicker : Abstract class adding a wxGrid in the popup. JsonGridPickerCtrl : UI control storing the tabular data in a JSON array. LBoundJsonGridPicker : connect JsonGridPicker to database. LGridJsonCellEditor : use LBoundJsonGridPicker in other wxGrid objects. LGridJsonCellRenderer : render cell JSON data. XmlGridPickerCtrl : UI control storing the tabular data in as XML document. LBoundXmlGridPicker : connect XmlGridPicker to database. LGridXmlCellEditor : grid editor for LBoundXmlGridPicker. LGridXmlCellRenderer : grid renderer for LBoundXmlGridPicker. JsonHelper and XmlHelper : for applications to quickly get intent value from database data.. The structure of managed tabular data : Column 1 : Intent - this is what we want to store/edit. This can be telephone numbers, email addresses, instant messaging addresses... any single line piece of information that can exist many times for one entity (person, company...). Column 2 : Type - A short description of the intent : 'Home, Work, Mobile, Fax, Other...'. It is displayed in a non editable wxComboBox. Column 3 : Preferred - One line of data can be selected as the preferred one. It is not mandatory, but it must be a single choice. Column 4 : Notes - single line notes. Adjust sql scripts and L7.dox. Applied ANSI formatting style to all files. Other changes : Work around a nasty misbehavior. Grid columns edited by a translated combobox expect full string data as cell values. LResultSet::BEData() will report these mapped strings, instead of database real data. LBoundComboBox::IsDirty() will always be true even if the editor is unchanged once created. Simplest workaround : disconnect m_BoundComboBox if unchanged. LGridTextEditor::ProvideFormEditor() : set the form editor's value explicitely.; wxTextCtrl does not interpret data it receives LBoundControl::SetNull must be void. LBoundGrid : Unbind:: instructions should limit to the widget's id, like Bind:: LConnection::GetReturnedKeys should return NULL. LConnection::SetData should return void. Notes : wxJSON must be configured with the same prefix as wxWidgets, here /usr/local/{wxWidgets,wxWidgets-Release}.
2019-12-22 16:35:16 +01:00
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);
2018-04-25 20:43:41 +02:00
/**
*
* @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:
};
Added classes to manage simple tabular data of known structure using a popup containing a wxGrid object. BasePicker : Abstract class adding a popup to wxPickerBase styled with a wxTextCtrl. BaseGridPicker : Abstract class adding a wxGrid in the popup. JsonGridPickerCtrl : UI control storing the tabular data in a JSON array. LBoundJsonGridPicker : connect JsonGridPicker to database. LGridJsonCellEditor : use LBoundJsonGridPicker in other wxGrid objects. LGridJsonCellRenderer : render cell JSON data. XmlGridPickerCtrl : UI control storing the tabular data in as XML document. LBoundXmlGridPicker : connect XmlGridPicker to database. LGridXmlCellEditor : grid editor for LBoundXmlGridPicker. LGridXmlCellRenderer : grid renderer for LBoundXmlGridPicker. JsonHelper and XmlHelper : for applications to quickly get intent value from database data.. The structure of managed tabular data : Column 1 : Intent - this is what we want to store/edit. This can be telephone numbers, email addresses, instant messaging addresses... any single line piece of information that can exist many times for one entity (person, company...). Column 2 : Type - A short description of the intent : 'Home, Work, Mobile, Fax, Other...'. It is displayed in a non editable wxComboBox. Column 3 : Preferred - One line of data can be selected as the preferred one. It is not mandatory, but it must be a single choice. Column 4 : Notes - single line notes. Adjust sql scripts and L7.dox. Applied ANSI formatting style to all files. Other changes : Work around a nasty misbehavior. Grid columns edited by a translated combobox expect full string data as cell values. LResultSet::BEData() will report these mapped strings, instead of database real data. LBoundComboBox::IsDirty() will always be true even if the editor is unchanged once created. Simplest workaround : disconnect m_BoundComboBox if unchanged. LGridTextEditor::ProvideFormEditor() : set the form editor's value explicitely.; wxTextCtrl does not interpret data it receives LBoundControl::SetNull must be void. LBoundGrid : Unbind:: instructions should limit to the widget's id, like Bind:: LConnection::GetReturnedKeys should return NULL. LConnection::SetData should return void. Notes : wxJSON must be configured with the same prefix as wxWidgets, here /usr/local/{wxWidgets,wxWidgets-Release}.
2019-12-22 16:35:16 +01:00
#endif /* LBOUNDGRID_H */
2018-04-25 20:43:41 +02:00